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