if_ral_cardbus.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. /* $OpenBSD: if_ral_cardbus.c,v 1.21 2013/12/06 21:03:02 deraadt Exp $ */
  2. /*-
  3. * Copyright (c) 2005-2010 Damien Bergamini <damien.bergamini@free.fr>
  4. *
  5. * Permission to use, copy, modify, and distribute this software for any
  6. * purpose with or without fee is hereby granted, provided that the above
  7. * copyright notice and this permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  10. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  12. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  14. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  15. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16. */
  17. /*
  18. * CardBus front-end for the Ralink RT2560/RT2561/RT2860/RT3090 driver.
  19. */
  20. #include "bpfilter.h"
  21. #include <sys/param.h>
  22. #include <sys/sockio.h>
  23. #include <sys/mbuf.h>
  24. #include <sys/kernel.h>
  25. #include <sys/socket.h>
  26. #include <sys/systm.h>
  27. #include <sys/malloc.h>
  28. #include <sys/timeout.h>
  29. #include <sys/device.h>
  30. #include <machine/bus.h>
  31. #include <machine/intr.h>
  32. #include <net/if.h>
  33. #include <net/if_dl.h>
  34. #include <net/if_media.h>
  35. #include <netinet/in.h>
  36. #include <netinet/if_ether.h>
  37. #include <net80211/ieee80211_var.h>
  38. #include <net80211/ieee80211_amrr.h>
  39. #include <net80211/ieee80211_radiotap.h>
  40. #include <dev/ic/rt2560var.h>
  41. #include <dev/ic/rt2661var.h>
  42. #include <dev/ic/rt2860var.h>
  43. #include <dev/pci/pcireg.h>
  44. #include <dev/pci/pcivar.h>
  45. #include <dev/pci/pcidevs.h>
  46. #include <dev/cardbus/cardbusvar.h>
  47. static struct ral_opns {
  48. int (*attach)(void *, int);
  49. int (*detach)(void *);
  50. void (*suspend)(void *);
  51. void (*resume)(void *);
  52. int (*intr)(void *);
  53. } ral_rt2560_opns = {
  54. rt2560_attach,
  55. rt2560_detach,
  56. rt2560_suspend,
  57. rt2560_wakeup,
  58. rt2560_intr
  59. }, ral_rt2661_opns = {
  60. rt2661_attach,
  61. rt2661_detach,
  62. rt2661_suspend,
  63. rt2661_wakeup,
  64. rt2661_intr
  65. }, ral_rt2860_opns = {
  66. rt2860_attach,
  67. rt2860_detach,
  68. rt2860_suspend,
  69. rt2860_wakeup,
  70. rt2860_intr
  71. };
  72. struct ral_cardbus_softc {
  73. union {
  74. struct rt2560_softc sc_rt2560;
  75. struct rt2661_softc sc_rt2661;
  76. struct rt2860_softc sc_rt2860;
  77. } u;
  78. #define sc_sc u.sc_rt2560
  79. /* cardbus specific goo */
  80. struct ral_opns *sc_opns;
  81. cardbus_devfunc_t sc_ct;
  82. pcitag_t sc_tag;
  83. void *sc_ih;
  84. bus_size_t sc_mapsize;
  85. pcireg_t sc_bar_val;
  86. int sc_intrline;
  87. pci_chipset_tag_t sc_pc;
  88. };
  89. int ral_cardbus_match(struct device *, void *, void *);
  90. void ral_cardbus_attach(struct device *, struct device *, void *);
  91. int ral_cardbus_detach(struct device *, int);
  92. int ral_cardbus_activate(struct device *, int);
  93. struct cfattach ral_cardbus_ca = {
  94. sizeof (struct ral_cardbus_softc), ral_cardbus_match,
  95. ral_cardbus_attach, ral_cardbus_detach,
  96. ral_cardbus_activate
  97. };
  98. static const struct pci_matchid ral_cardbus_devices[] = {
  99. { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT2560 },
  100. { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT2561 },
  101. { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT2561S },
  102. { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT2661 },
  103. { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT2860 },
  104. { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT2890 },
  105. { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT2760 },
  106. { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT2790 },
  107. { PCI_VENDOR_AWT, PCI_PRODUCT_AWT_RT2890 },
  108. { PCI_VENDOR_EDIMAX, PCI_PRODUCT_EDIMAX_RT2860_1 },
  109. { PCI_VENDOR_EDIMAX, PCI_PRODUCT_EDIMAX_RT2860_2 },
  110. { PCI_VENDOR_EDIMAX, PCI_PRODUCT_EDIMAX_RT2860_3 },
  111. { PCI_VENDOR_EDIMAX, PCI_PRODUCT_EDIMAX_RT2860_4 },
  112. { PCI_VENDOR_EDIMAX, PCI_PRODUCT_EDIMAX_RT2860_5 },
  113. { PCI_VENDOR_EDIMAX, PCI_PRODUCT_EDIMAX_RT2860_6 },
  114. { PCI_VENDOR_EDIMAX, PCI_PRODUCT_EDIMAX_RT2860_7 },
  115. { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT3062 },
  116. { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT3090 },
  117. { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT3091 },
  118. { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT3092 },
  119. { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT3562 },
  120. { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT3592 },
  121. { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT3593 }
  122. };
  123. int ral_cardbus_enable(struct rt2560_softc *);
  124. void ral_cardbus_disable(struct rt2560_softc *);
  125. void ral_cardbus_setup(struct ral_cardbus_softc *);
  126. void ral_cardbus_wakeup(struct ral_cardbus_softc *);
  127. int
  128. ral_cardbus_match(struct device *parent, void *match, void *aux)
  129. {
  130. return (cardbus_matchbyid((struct cardbus_attach_args *)aux,
  131. ral_cardbus_devices, nitems(ral_cardbus_devices)));
  132. }
  133. void
  134. ral_cardbus_attach(struct device *parent, struct device *self, void *aux)
  135. {
  136. struct ral_cardbus_softc *csc = (struct ral_cardbus_softc *)self;
  137. struct rt2560_softc *sc = &csc->sc_sc;
  138. struct cardbus_attach_args *ca = aux;
  139. cardbus_devfunc_t ct = ca->ca_ct;
  140. bus_addr_t base;
  141. int error;
  142. if (PCI_VENDOR(ca->ca_id) == PCI_VENDOR_RALINK) {
  143. switch (PCI_PRODUCT(ca->ca_id)) {
  144. case PCI_PRODUCT_RALINK_RT2560:
  145. csc->sc_opns = &ral_rt2560_opns;
  146. break;
  147. case PCI_PRODUCT_RALINK_RT2561:
  148. case PCI_PRODUCT_RALINK_RT2561S:
  149. case PCI_PRODUCT_RALINK_RT2661:
  150. csc->sc_opns = &ral_rt2661_opns;
  151. break;
  152. default:
  153. csc->sc_opns = &ral_rt2860_opns;
  154. break;
  155. }
  156. } else {
  157. /* all other vendors are RT2860 only */
  158. csc->sc_opns = &ral_rt2860_opns;
  159. }
  160. sc->sc_dmat = ca->ca_dmat;
  161. csc->sc_ct = ct;
  162. csc->sc_tag = ca->ca_tag;
  163. csc->sc_intrline = ca->ca_intrline;
  164. csc->sc_pc = ca->ca_pc;
  165. /* power management hooks */
  166. sc->sc_enable = ral_cardbus_enable;
  167. sc->sc_disable = ral_cardbus_disable;
  168. /* map control/status registers */
  169. error = Cardbus_mapreg_map(ct, CARDBUS_BASE0_REG,
  170. PCI_MAPREG_TYPE_MEM, 0, &sc->sc_st, &sc->sc_sh, &base,
  171. &csc->sc_mapsize);
  172. if (error != 0) {
  173. printf(": can't map mem space\n");
  174. return;
  175. }
  176. csc->sc_bar_val = base | PCI_MAPREG_TYPE_MEM;
  177. /* set up the PCI configuration registers */
  178. ral_cardbus_setup(csc);
  179. printf(": irq %d", csc->sc_intrline);
  180. (*csc->sc_opns->attach)(sc, PCI_PRODUCT(ca->ca_id));
  181. Cardbus_function_disable(ct);
  182. }
  183. int
  184. ral_cardbus_detach(struct device *self, int flags)
  185. {
  186. struct ral_cardbus_softc *csc = (struct ral_cardbus_softc *)self;
  187. struct rt2560_softc *sc = &csc->sc_sc;
  188. cardbus_devfunc_t ct = csc->sc_ct;
  189. cardbus_chipset_tag_t cc = ct->ct_cc;
  190. cardbus_function_tag_t cf = ct->ct_cf;
  191. int error;
  192. error = (*csc->sc_opns->detach)(sc);
  193. if (error != 0)
  194. return error;
  195. /* unhook the interrupt handler */
  196. if (csc->sc_ih != NULL) {
  197. cardbus_intr_disestablish(cc, cf, csc->sc_ih);
  198. csc->sc_ih = NULL;
  199. }
  200. /* release bus space and close window */
  201. Cardbus_mapreg_unmap(ct, CARDBUS_BASE0_REG, sc->sc_st, sc->sc_sh,
  202. csc->sc_mapsize);
  203. return 0;
  204. }
  205. int
  206. ral_cardbus_activate(struct device *self, int act)
  207. {
  208. struct ral_cardbus_softc *csc = (struct ral_cardbus_softc *)self;
  209. struct rt2560_softc *sc = &csc->sc_sc;
  210. switch (act) {
  211. case DVACT_SUSPEND:
  212. (*csc->sc_opns->suspend)(sc);
  213. break;
  214. case DVACT_WAKEUP:
  215. ral_cardbus_wakeup(csc);
  216. break;
  217. }
  218. return 0;
  219. }
  220. int
  221. ral_cardbus_enable(struct rt2560_softc *sc)
  222. {
  223. struct ral_cardbus_softc *csc = (struct ral_cardbus_softc *)sc;
  224. cardbus_devfunc_t ct = csc->sc_ct;
  225. cardbus_chipset_tag_t cc = ct->ct_cc;
  226. cardbus_function_tag_t cf = ct->ct_cf;
  227. /* power on the socket */
  228. Cardbus_function_enable(ct);
  229. /* setup the PCI configuration registers */
  230. ral_cardbus_setup(csc);
  231. /* map and establish the interrupt handler */
  232. csc->sc_ih = cardbus_intr_establish(cc, cf, csc->sc_intrline, IPL_NET,
  233. csc->sc_opns->intr, sc, sc->sc_dev.dv_xname);
  234. if (csc->sc_ih == NULL) {
  235. printf("%s: could not establish interrupt at %d\n",
  236. sc->sc_dev.dv_xname, csc->sc_intrline);
  237. Cardbus_function_disable(ct);
  238. return 1;
  239. }
  240. return 0;
  241. }
  242. void
  243. ral_cardbus_disable(struct rt2560_softc *sc)
  244. {
  245. struct ral_cardbus_softc *csc = (struct ral_cardbus_softc *)sc;
  246. cardbus_devfunc_t ct = csc->sc_ct;
  247. cardbus_chipset_tag_t cc = ct->ct_cc;
  248. cardbus_function_tag_t cf = ct->ct_cf;
  249. /* unhook the interrupt handler */
  250. cardbus_intr_disestablish(cc, cf, csc->sc_ih);
  251. csc->sc_ih = NULL;
  252. /* power down the socket */
  253. Cardbus_function_disable(ct);
  254. }
  255. void
  256. ral_cardbus_setup(struct ral_cardbus_softc *csc)
  257. {
  258. cardbus_devfunc_t ct = csc->sc_ct;
  259. cardbus_chipset_tag_t cc = ct->ct_cc;
  260. pci_chipset_tag_t pc = csc->sc_pc;
  261. cardbus_function_tag_t cf = ct->ct_cf;
  262. pcireg_t reg;
  263. /* program the BAR */
  264. pci_conf_write(pc, csc->sc_tag, CARDBUS_BASE0_REG,
  265. csc->sc_bar_val);
  266. /* make sure the right access type is on the cardbus bridge */
  267. (*cf->cardbus_ctrl)(cc, CARDBUS_MEM_ENABLE);
  268. (*cf->cardbus_ctrl)(cc, CARDBUS_BM_ENABLE);
  269. /* enable the appropriate bits in the PCI CSR */
  270. reg = pci_conf_read(pc, csc->sc_tag,
  271. PCI_COMMAND_STATUS_REG);
  272. reg |= PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_MEM_ENABLE;
  273. pci_conf_write(pc, csc->sc_tag, PCI_COMMAND_STATUS_REG,
  274. reg);
  275. }
  276. void
  277. ral_cardbus_wakeup(struct ral_cardbus_softc *csc)
  278. {
  279. struct rt2560_softc *sc = &csc->sc_sc;
  280. int s;
  281. s = splnet();
  282. (*csc->sc_opns->resume)(sc);
  283. splx(s);
  284. }