1 /* $OpenBSD: if_ral_cardbus.c,v 1.22 2015/11/24 17:11:39 mpi 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 35 #include <machine/bus.h> 36 #include <machine/intr.h> 37 38 #include <net/if.h> 39 #include <net/if_media.h> 40 41 #include <netinet/in.h> 42 #include <netinet/if_ether.h> 43 44 #include <net80211/ieee80211_var.h> 45 #include <net80211/ieee80211_amrr.h> 46 #include <net80211/ieee80211_radiotap.h> 47 48 #include <dev/ic/rt2560var.h> 49 #include <dev/ic/rt2661var.h> 50 #include <dev/ic/rt2860var.h> 51 52 #include <dev/pci/pcireg.h> 53 #include <dev/pci/pcivar.h> 54 #include <dev/pci/pcidevs.h> 55 56 #include <dev/cardbus/cardbusvar.h> 57 58 static struct ral_opns { 59 int (*attach)(void *, int); 60 int (*detach)(void *); 61 void (*suspend)(void *); 62 void (*resume)(void *); 63 int (*intr)(void *); 64 65 } ral_rt2560_opns = { 66 rt2560_attach, 67 rt2560_detach, 68 rt2560_suspend, 69 rt2560_wakeup, 70 rt2560_intr 71 72 }, ral_rt2661_opns = { 73 rt2661_attach, 74 rt2661_detach, 75 rt2661_suspend, 76 rt2661_wakeup, 77 rt2661_intr 78 79 }, ral_rt2860_opns = { 80 rt2860_attach, 81 rt2860_detach, 82 rt2860_suspend, 83 rt2860_wakeup, 84 rt2860_intr 85 }; 86 87 struct ral_cardbus_softc { 88 union { 89 struct rt2560_softc sc_rt2560; 90 struct rt2661_softc sc_rt2661; 91 struct rt2860_softc sc_rt2860; 92 } u; 93 #define sc_sc u.sc_rt2560 94 95 /* cardbus specific goo */ 96 struct ral_opns *sc_opns; 97 cardbus_devfunc_t sc_ct; 98 pcitag_t sc_tag; 99 void *sc_ih; 100 bus_size_t sc_mapsize; 101 pcireg_t sc_bar_val; 102 int sc_intrline; 103 pci_chipset_tag_t sc_pc; 104 }; 105 106 int ral_cardbus_match(struct device *, void *, void *); 107 void ral_cardbus_attach(struct device *, struct device *, void *); 108 int ral_cardbus_detach(struct device *, int); 109 int ral_cardbus_activate(struct device *, int); 110 111 struct cfattach ral_cardbus_ca = { 112 sizeof (struct ral_cardbus_softc), ral_cardbus_match, 113 ral_cardbus_attach, ral_cardbus_detach, 114 ral_cardbus_activate 115 }; 116 117 static const struct pci_matchid ral_cardbus_devices[] = { 118 { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT2560 }, 119 { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT2561 }, 120 { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT2561S }, 121 { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT2661 }, 122 { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT2860 }, 123 { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT2890 }, 124 { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT2760 }, 125 { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT2790 }, 126 { PCI_VENDOR_AWT, PCI_PRODUCT_AWT_RT2890 }, 127 { PCI_VENDOR_EDIMAX, PCI_PRODUCT_EDIMAX_RT2860_1 }, 128 { PCI_VENDOR_EDIMAX, PCI_PRODUCT_EDIMAX_RT2860_2 }, 129 { PCI_VENDOR_EDIMAX, PCI_PRODUCT_EDIMAX_RT2860_3 }, 130 { PCI_VENDOR_EDIMAX, PCI_PRODUCT_EDIMAX_RT2860_4 }, 131 { PCI_VENDOR_EDIMAX, PCI_PRODUCT_EDIMAX_RT2860_5 }, 132 { PCI_VENDOR_EDIMAX, PCI_PRODUCT_EDIMAX_RT2860_6 }, 133 { PCI_VENDOR_EDIMAX, PCI_PRODUCT_EDIMAX_RT2860_7 }, 134 { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT3062 }, 135 { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT3090 }, 136 { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT3091 }, 137 { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT3092 }, 138 { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT3562 }, 139 { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT3592 }, 140 { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT3593 } 141 }; 142 143 int ral_cardbus_enable(struct rt2560_softc *); 144 void ral_cardbus_disable(struct rt2560_softc *); 145 void ral_cardbus_setup(struct ral_cardbus_softc *); 146 void ral_cardbus_wakeup(struct ral_cardbus_softc *); 147 148 int 149 ral_cardbus_match(struct device *parent, void *match, void *aux) 150 { 151 return (cardbus_matchbyid((struct cardbus_attach_args *)aux, 152 ral_cardbus_devices, nitems(ral_cardbus_devices))); 153 } 154 155 void 156 ral_cardbus_attach(struct device *parent, struct device *self, void *aux) 157 { 158 struct ral_cardbus_softc *csc = (struct ral_cardbus_softc *)self; 159 struct rt2560_softc *sc = &csc->sc_sc; 160 struct cardbus_attach_args *ca = aux; 161 cardbus_devfunc_t ct = ca->ca_ct; 162 bus_addr_t base; 163 int error; 164 165 if (PCI_VENDOR(ca->ca_id) == PCI_VENDOR_RALINK) { 166 switch (PCI_PRODUCT(ca->ca_id)) { 167 case PCI_PRODUCT_RALINK_RT2560: 168 csc->sc_opns = &ral_rt2560_opns; 169 break; 170 case PCI_PRODUCT_RALINK_RT2561: 171 case PCI_PRODUCT_RALINK_RT2561S: 172 case PCI_PRODUCT_RALINK_RT2661: 173 csc->sc_opns = &ral_rt2661_opns; 174 break; 175 default: 176 csc->sc_opns = &ral_rt2860_opns; 177 break; 178 } 179 } else { 180 /* all other vendors are RT2860 only */ 181 csc->sc_opns = &ral_rt2860_opns; 182 } 183 sc->sc_dmat = ca->ca_dmat; 184 csc->sc_ct = ct; 185 csc->sc_tag = ca->ca_tag; 186 csc->sc_intrline = ca->ca_intrline; 187 csc->sc_pc = ca->ca_pc; 188 189 /* power management hooks */ 190 sc->sc_enable = ral_cardbus_enable; 191 sc->sc_disable = ral_cardbus_disable; 192 193 /* map control/status registers */ 194 error = Cardbus_mapreg_map(ct, CARDBUS_BASE0_REG, 195 PCI_MAPREG_TYPE_MEM, 0, &sc->sc_st, &sc->sc_sh, &base, 196 &csc->sc_mapsize); 197 if (error != 0) { 198 printf(": can't map mem space\n"); 199 return; 200 } 201 202 csc->sc_bar_val = base | PCI_MAPREG_TYPE_MEM; 203 204 /* set up the PCI configuration registers */ 205 ral_cardbus_setup(csc); 206 207 printf(": irq %d", csc->sc_intrline); 208 209 (*csc->sc_opns->attach)(sc, PCI_PRODUCT(ca->ca_id)); 210 211 Cardbus_function_disable(ct); 212 } 213 214 int 215 ral_cardbus_detach(struct device *self, int flags) 216 { 217 struct ral_cardbus_softc *csc = (struct ral_cardbus_softc *)self; 218 struct rt2560_softc *sc = &csc->sc_sc; 219 cardbus_devfunc_t ct = csc->sc_ct; 220 cardbus_chipset_tag_t cc = ct->ct_cc; 221 cardbus_function_tag_t cf = ct->ct_cf; 222 int error; 223 224 error = (*csc->sc_opns->detach)(sc); 225 if (error != 0) 226 return error; 227 228 /* unhook the interrupt handler */ 229 if (csc->sc_ih != NULL) { 230 cardbus_intr_disestablish(cc, cf, csc->sc_ih); 231 csc->sc_ih = NULL; 232 } 233 234 /* release bus space and close window */ 235 Cardbus_mapreg_unmap(ct, CARDBUS_BASE0_REG, sc->sc_st, sc->sc_sh, 236 csc->sc_mapsize); 237 238 return 0; 239 } 240 241 int 242 ral_cardbus_activate(struct device *self, int act) 243 { 244 struct ral_cardbus_softc *csc = (struct ral_cardbus_softc *)self; 245 struct rt2560_softc *sc = &csc->sc_sc; 246 247 switch (act) { 248 case DVACT_SUSPEND: 249 (*csc->sc_opns->suspend)(sc); 250 break; 251 case DVACT_WAKEUP: 252 ral_cardbus_wakeup(csc); 253 break; 254 } 255 256 return 0; 257 } 258 259 int 260 ral_cardbus_enable(struct rt2560_softc *sc) 261 { 262 struct ral_cardbus_softc *csc = (struct ral_cardbus_softc *)sc; 263 cardbus_devfunc_t ct = csc->sc_ct; 264 cardbus_chipset_tag_t cc = ct->ct_cc; 265 cardbus_function_tag_t cf = ct->ct_cf; 266 267 /* power on the socket */ 268 Cardbus_function_enable(ct); 269 270 /* setup the PCI configuration registers */ 271 ral_cardbus_setup(csc); 272 273 /* map and establish the interrupt handler */ 274 csc->sc_ih = cardbus_intr_establish(cc, cf, csc->sc_intrline, IPL_NET, 275 csc->sc_opns->intr, sc, sc->sc_dev.dv_xname); 276 if (csc->sc_ih == NULL) { 277 printf("%s: could not establish interrupt at %d\n", 278 sc->sc_dev.dv_xname, csc->sc_intrline); 279 Cardbus_function_disable(ct); 280 return 1; 281 } 282 283 return 0; 284 } 285 286 void 287 ral_cardbus_disable(struct rt2560_softc *sc) 288 { 289 struct ral_cardbus_softc *csc = (struct ral_cardbus_softc *)sc; 290 cardbus_devfunc_t ct = csc->sc_ct; 291 cardbus_chipset_tag_t cc = ct->ct_cc; 292 cardbus_function_tag_t cf = ct->ct_cf; 293 294 /* unhook the interrupt handler */ 295 cardbus_intr_disestablish(cc, cf, csc->sc_ih); 296 csc->sc_ih = NULL; 297 298 /* power down the socket */ 299 Cardbus_function_disable(ct); 300 } 301 302 void 303 ral_cardbus_setup(struct ral_cardbus_softc *csc) 304 { 305 cardbus_devfunc_t ct = csc->sc_ct; 306 cardbus_chipset_tag_t cc = ct->ct_cc; 307 pci_chipset_tag_t pc = csc->sc_pc; 308 cardbus_function_tag_t cf = ct->ct_cf; 309 pcireg_t reg; 310 311 /* program the BAR */ 312 pci_conf_write(pc, csc->sc_tag, CARDBUS_BASE0_REG, 313 csc->sc_bar_val); 314 315 /* make sure the right access type is on the cardbus bridge */ 316 (*cf->cardbus_ctrl)(cc, CARDBUS_MEM_ENABLE); 317 (*cf->cardbus_ctrl)(cc, CARDBUS_BM_ENABLE); 318 319 /* enable the appropriate bits in the PCI CSR */ 320 reg = pci_conf_read(pc, csc->sc_tag, 321 PCI_COMMAND_STATUS_REG); 322 reg |= PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_MEM_ENABLE; 323 pci_conf_write(pc, csc->sc_tag, PCI_COMMAND_STATUS_REG, 324 reg); 325 } 326 327 void 328 ral_cardbus_wakeup(struct ral_cardbus_softc *csc) 329 { 330 struct rt2560_softc *sc = &csc->sc_sc; 331 int s; 332 333 s = splnet(); 334 (*csc->sc_opns->resume)(sc); 335 splx(s); 336 } 337