1/*- 2 * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting 3 * Copyright (c) 2010-2011 Adrian Chadd, Xenion Pty Ltd 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer, 11 * without modification. 12 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 13 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 14 * redistribution must be conditioned upon including a substantially 15 * similar Disclaimer requirement for further binary redistribution. 16 * 17 * NO WARRANTY 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 21 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 23 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 26 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGES. 29 */ 30 31#include <sys/cdefs.h>
| 1/*- 2 * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting 3 * Copyright (c) 2010-2011 Adrian Chadd, Xenion Pty Ltd 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer, 11 * without modification. 12 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 13 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 14 * redistribution must be conditioned upon including a substantially 15 * similar Disclaimer requirement for further binary redistribution. 16 * 17 * NO WARRANTY 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 21 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 23 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 26 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGES. 29 */ 30 31#include <sys/cdefs.h>
|
32__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath_ahb.c 238433 2012-07-14 02:22:17Z adrian $");
| 32__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath_ahb.c 238709 2012-07-23 02:49:25Z adrian $");
|
33 34/* 35 * AHB bus front-end for the Atheros Wireless LAN controller driver. 36 */ 37 38#include "opt_ath.h" 39 40#include <sys/param.h> 41#include <sys/systm.h> 42#include <sys/module.h> 43#include <sys/kernel.h> 44#include <sys/lock.h> 45#include <sys/mutex.h> 46#include <sys/errno.h> 47 48#include <machine/bus.h> 49#include <machine/resource.h> 50#include <sys/bus.h> 51#include <sys/rman.h> 52 53#include <sys/socket.h> 54 55#include <net/if.h> 56#include <net/if_media.h> 57#include <net/if_arp.h> 58 59#include <net80211/ieee80211_var.h> 60 61#include <dev/ath/if_athvar.h> 62 63#include <mips/atheros/ar71xxreg.h> 64#include <mips/atheros/ar91xxreg.h> 65#include <mips/atheros/ar71xx_cpudef.h> 66 67/* 68 * bus glue. 69 */ 70 71/* number of 16 bit words */ 72#define ATH_EEPROM_DATA_SIZE 2048 73 74struct ath_ahb_softc { 75 struct ath_softc sc_sc; 76 struct resource *sc_sr; /* memory resource */ 77 struct resource *sc_irq; /* irq resource */ 78 struct resource *sc_eeprom; /* eeprom location */ 79 void *sc_ih; /* interrupt handler */ 80}; 81 82#define VENDOR_ATHEROS 0x168c 83#define AR9130_DEVID 0x000b 84 85static int 86ath_ahb_probe(device_t dev) 87{ 88 const char* devname; 89 90 /* Atheros / ar9130 */ 91 devname = ath_hal_probe(VENDOR_ATHEROS, AR9130_DEVID); 92 93 if (devname != NULL) { 94 device_set_desc(dev, devname); 95 return BUS_PROBE_DEFAULT; 96 } 97 return ENXIO; 98} 99 100static int 101ath_ahb_attach(device_t dev) 102{ 103 struct ath_ahb_softc *psc = device_get_softc(dev); 104 struct ath_softc *sc = &psc->sc_sc; 105 int error = ENXIO; 106 int rid; 107 long eepromaddr; 108 uint8_t *p; 109 110 sc->sc_dev = dev; 111 112 rid = 0; 113 psc->sc_sr = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); 114 if (psc->sc_sr == NULL) { 115 device_printf(dev, "cannot map register space\n"); 116 goto bad; 117 } 118 119 if (resource_long_value(device_get_name(dev), device_get_unit(dev), 120 "eepromaddr", &eepromaddr) != 0) { 121 device_printf(dev, "cannot fetch 'eepromaddr' from hints\n"); 122 goto bad0; 123 } 124 rid = 0; 125 device_printf(sc->sc_dev, "eeprom @ %p\n", (void *) eepromaddr); 126 psc->sc_eeprom = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, (uintptr_t) eepromaddr, 127 (uintptr_t) eepromaddr + (uintptr_t) ((ATH_EEPROM_DATA_SIZE * 2) - 1), 0, RF_ACTIVE); 128 if (psc->sc_eeprom == NULL) { 129 device_printf(dev, "cannot map eeprom space\n"); 130 goto bad0; 131 } 132 133 /* XXX uintptr_t is a bandaid for ia64; to be fixed */ 134 sc->sc_st = (HAL_BUS_TAG)(uintptr_t) rman_get_bustag(psc->sc_sr); 135 sc->sc_sh = (HAL_BUS_HANDLE) rman_get_bushandle(psc->sc_sr); 136 /* 137 * Mark device invalid so any interrupts (shared or otherwise) 138 * that arrive before the HAL is setup are discarded. 139 */ 140 sc->sc_invalid = 1; 141 142 /* Copy the EEPROM data out */ 143 sc->sc_eepromdata = malloc(ATH_EEPROM_DATA_SIZE * 2, M_TEMP, M_NOWAIT | M_ZERO); 144 if (sc->sc_eepromdata == NULL) { 145 device_printf(dev, "cannot allocate memory for eeprom data\n"); 146 goto bad1; 147 } 148 device_printf(sc->sc_dev, "eeprom data @ %p\n", (void *) rman_get_bushandle(psc->sc_eeprom)); 149 /* XXX why doesn't this work? -adrian */ 150#if 0 151 bus_space_read_multi_1( 152 rman_get_bustag(psc->sc_eeprom), 153 rman_get_bushandle(psc->sc_eeprom), 154 0, (u_int8_t *) sc->sc_eepromdata, ATH_EEPROM_DATA_SIZE * 2); 155#endif 156 p = (void *) rman_get_bushandle(psc->sc_eeprom); 157 memcpy(sc->sc_eepromdata, p, ATH_EEPROM_DATA_SIZE * 2); 158 159 /* 160 * Arrange interrupt line. 161 */ 162 rid = 0; 163 psc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_SHAREABLE|RF_ACTIVE); 164 if (psc->sc_irq == NULL) { 165 device_printf(dev, "could not map interrupt\n"); 166 goto bad1; 167 } 168 if (bus_setup_intr(dev, psc->sc_irq, 169 INTR_TYPE_NET | INTR_MPSAFE, 170 NULL, ath_intr, sc, &psc->sc_ih)) { 171 device_printf(dev, "could not establish interrupt\n"); 172 goto bad2; 173 } 174 175 /* 176 * Setup DMA descriptor area. 177 */ 178 if (bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */ 179 1, 0, /* alignment, bounds */ 180 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ 181 BUS_SPACE_MAXADDR, /* highaddr */ 182 NULL, NULL, /* filter, filterarg */ 183 0x3ffff, /* maxsize XXX */ 184 ATH_MAX_SCATTER, /* nsegments */ 185 0x3ffff, /* maxsegsize XXX */ 186 BUS_DMA_ALLOCNOW, /* flags */ 187 NULL, /* lockfunc */ 188 NULL, /* lockarg */ 189 &sc->sc_dmat)) { 190 device_printf(dev, "cannot allocate DMA tag\n"); 191 goto bad3; 192 } 193 194 ATH_LOCK_INIT(sc); 195 ATH_PCU_LOCK_INIT(sc); 196 ATH_RX_LOCK_INIT(sc);
| 33 34/* 35 * AHB bus front-end for the Atheros Wireless LAN controller driver. 36 */ 37 38#include "opt_ath.h" 39 40#include <sys/param.h> 41#include <sys/systm.h> 42#include <sys/module.h> 43#include <sys/kernel.h> 44#include <sys/lock.h> 45#include <sys/mutex.h> 46#include <sys/errno.h> 47 48#include <machine/bus.h> 49#include <machine/resource.h> 50#include <sys/bus.h> 51#include <sys/rman.h> 52 53#include <sys/socket.h> 54 55#include <net/if.h> 56#include <net/if_media.h> 57#include <net/if_arp.h> 58 59#include <net80211/ieee80211_var.h> 60 61#include <dev/ath/if_athvar.h> 62 63#include <mips/atheros/ar71xxreg.h> 64#include <mips/atheros/ar91xxreg.h> 65#include <mips/atheros/ar71xx_cpudef.h> 66 67/* 68 * bus glue. 69 */ 70 71/* number of 16 bit words */ 72#define ATH_EEPROM_DATA_SIZE 2048 73 74struct ath_ahb_softc { 75 struct ath_softc sc_sc; 76 struct resource *sc_sr; /* memory resource */ 77 struct resource *sc_irq; /* irq resource */ 78 struct resource *sc_eeprom; /* eeprom location */ 79 void *sc_ih; /* interrupt handler */ 80}; 81 82#define VENDOR_ATHEROS 0x168c 83#define AR9130_DEVID 0x000b 84 85static int 86ath_ahb_probe(device_t dev) 87{ 88 const char* devname; 89 90 /* Atheros / ar9130 */ 91 devname = ath_hal_probe(VENDOR_ATHEROS, AR9130_DEVID); 92 93 if (devname != NULL) { 94 device_set_desc(dev, devname); 95 return BUS_PROBE_DEFAULT; 96 } 97 return ENXIO; 98} 99 100static int 101ath_ahb_attach(device_t dev) 102{ 103 struct ath_ahb_softc *psc = device_get_softc(dev); 104 struct ath_softc *sc = &psc->sc_sc; 105 int error = ENXIO; 106 int rid; 107 long eepromaddr; 108 uint8_t *p; 109 110 sc->sc_dev = dev; 111 112 rid = 0; 113 psc->sc_sr = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); 114 if (psc->sc_sr == NULL) { 115 device_printf(dev, "cannot map register space\n"); 116 goto bad; 117 } 118 119 if (resource_long_value(device_get_name(dev), device_get_unit(dev), 120 "eepromaddr", &eepromaddr) != 0) { 121 device_printf(dev, "cannot fetch 'eepromaddr' from hints\n"); 122 goto bad0; 123 } 124 rid = 0; 125 device_printf(sc->sc_dev, "eeprom @ %p\n", (void *) eepromaddr); 126 psc->sc_eeprom = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, (uintptr_t) eepromaddr, 127 (uintptr_t) eepromaddr + (uintptr_t) ((ATH_EEPROM_DATA_SIZE * 2) - 1), 0, RF_ACTIVE); 128 if (psc->sc_eeprom == NULL) { 129 device_printf(dev, "cannot map eeprom space\n"); 130 goto bad0; 131 } 132 133 /* XXX uintptr_t is a bandaid for ia64; to be fixed */ 134 sc->sc_st = (HAL_BUS_TAG)(uintptr_t) rman_get_bustag(psc->sc_sr); 135 sc->sc_sh = (HAL_BUS_HANDLE) rman_get_bushandle(psc->sc_sr); 136 /* 137 * Mark device invalid so any interrupts (shared or otherwise) 138 * that arrive before the HAL is setup are discarded. 139 */ 140 sc->sc_invalid = 1; 141 142 /* Copy the EEPROM data out */ 143 sc->sc_eepromdata = malloc(ATH_EEPROM_DATA_SIZE * 2, M_TEMP, M_NOWAIT | M_ZERO); 144 if (sc->sc_eepromdata == NULL) { 145 device_printf(dev, "cannot allocate memory for eeprom data\n"); 146 goto bad1; 147 } 148 device_printf(sc->sc_dev, "eeprom data @ %p\n", (void *) rman_get_bushandle(psc->sc_eeprom)); 149 /* XXX why doesn't this work? -adrian */ 150#if 0 151 bus_space_read_multi_1( 152 rman_get_bustag(psc->sc_eeprom), 153 rman_get_bushandle(psc->sc_eeprom), 154 0, (u_int8_t *) sc->sc_eepromdata, ATH_EEPROM_DATA_SIZE * 2); 155#endif 156 p = (void *) rman_get_bushandle(psc->sc_eeprom); 157 memcpy(sc->sc_eepromdata, p, ATH_EEPROM_DATA_SIZE * 2); 158 159 /* 160 * Arrange interrupt line. 161 */ 162 rid = 0; 163 psc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_SHAREABLE|RF_ACTIVE); 164 if (psc->sc_irq == NULL) { 165 device_printf(dev, "could not map interrupt\n"); 166 goto bad1; 167 } 168 if (bus_setup_intr(dev, psc->sc_irq, 169 INTR_TYPE_NET | INTR_MPSAFE, 170 NULL, ath_intr, sc, &psc->sc_ih)) { 171 device_printf(dev, "could not establish interrupt\n"); 172 goto bad2; 173 } 174 175 /* 176 * Setup DMA descriptor area. 177 */ 178 if (bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */ 179 1, 0, /* alignment, bounds */ 180 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ 181 BUS_SPACE_MAXADDR, /* highaddr */ 182 NULL, NULL, /* filter, filterarg */ 183 0x3ffff, /* maxsize XXX */ 184 ATH_MAX_SCATTER, /* nsegments */ 185 0x3ffff, /* maxsegsize XXX */ 186 BUS_DMA_ALLOCNOW, /* flags */ 187 NULL, /* lockfunc */ 188 NULL, /* lockarg */ 189 &sc->sc_dmat)) { 190 device_printf(dev, "cannot allocate DMA tag\n"); 191 goto bad3; 192 } 193 194 ATH_LOCK_INIT(sc); 195 ATH_PCU_LOCK_INIT(sc); 196 ATH_RX_LOCK_INIT(sc);
|
| 197 ATH_TXSTATUS_LOCK_INIT(sc);
|
197 198 error = ath_attach(AR9130_DEVID, sc); 199 if (error == 0) /* success */ 200 return 0; 201
| 198 199 error = ath_attach(AR9130_DEVID, sc); 200 if (error == 0) /* success */ 201 return 0; 202
|
| 203 ATH_TXSTATUS_LOCK_DESTROY(sc);
|
202 ATH_RX_LOCK_DESTROY(sc); 203 ATH_PCU_LOCK_DESTROY(sc); 204 ATH_LOCK_DESTROY(sc); 205 bus_dma_tag_destroy(sc->sc_dmat); 206bad3: 207 bus_teardown_intr(dev, psc->sc_irq, psc->sc_ih); 208bad2: 209 bus_release_resource(dev, SYS_RES_IRQ, 0, psc->sc_irq); 210bad1: 211 bus_release_resource(dev, SYS_RES_MEMORY, 0, psc->sc_eeprom); 212bad0: 213 bus_release_resource(dev, SYS_RES_MEMORY, 0, psc->sc_sr); 214bad: 215 /* XXX?! */ 216 if (sc->sc_eepromdata) 217 free(sc->sc_eepromdata, M_TEMP); 218 return (error); 219} 220 221static int 222ath_ahb_detach(device_t dev) 223{ 224 struct ath_ahb_softc *psc = device_get_softc(dev); 225 struct ath_softc *sc = &psc->sc_sc; 226 227 /* check if device was removed */ 228 sc->sc_invalid = !bus_child_present(dev); 229 230 ath_detach(sc); 231 232 bus_generic_detach(dev); 233 bus_teardown_intr(dev, psc->sc_irq, psc->sc_ih); 234 bus_release_resource(dev, SYS_RES_IRQ, 0, psc->sc_irq); 235 236 bus_dma_tag_destroy(sc->sc_dmat); 237 bus_release_resource(dev, SYS_RES_MEMORY, 0, psc->sc_sr); 238 bus_release_resource(dev, SYS_RES_MEMORY, 0, psc->sc_eeprom); 239 /* XXX?! */ 240 if (sc->sc_eepromdata) 241 free(sc->sc_eepromdata, M_TEMP); 242
| 204 ATH_RX_LOCK_DESTROY(sc); 205 ATH_PCU_LOCK_DESTROY(sc); 206 ATH_LOCK_DESTROY(sc); 207 bus_dma_tag_destroy(sc->sc_dmat); 208bad3: 209 bus_teardown_intr(dev, psc->sc_irq, psc->sc_ih); 210bad2: 211 bus_release_resource(dev, SYS_RES_IRQ, 0, psc->sc_irq); 212bad1: 213 bus_release_resource(dev, SYS_RES_MEMORY, 0, psc->sc_eeprom); 214bad0: 215 bus_release_resource(dev, SYS_RES_MEMORY, 0, psc->sc_sr); 216bad: 217 /* XXX?! */ 218 if (sc->sc_eepromdata) 219 free(sc->sc_eepromdata, M_TEMP); 220 return (error); 221} 222 223static int 224ath_ahb_detach(device_t dev) 225{ 226 struct ath_ahb_softc *psc = device_get_softc(dev); 227 struct ath_softc *sc = &psc->sc_sc; 228 229 /* check if device was removed */ 230 sc->sc_invalid = !bus_child_present(dev); 231 232 ath_detach(sc); 233 234 bus_generic_detach(dev); 235 bus_teardown_intr(dev, psc->sc_irq, psc->sc_ih); 236 bus_release_resource(dev, SYS_RES_IRQ, 0, psc->sc_irq); 237 238 bus_dma_tag_destroy(sc->sc_dmat); 239 bus_release_resource(dev, SYS_RES_MEMORY, 0, psc->sc_sr); 240 bus_release_resource(dev, SYS_RES_MEMORY, 0, psc->sc_eeprom); 241 /* XXX?! */ 242 if (sc->sc_eepromdata) 243 free(sc->sc_eepromdata, M_TEMP); 244
|
| 245 ATH_TXSTATUS_LOCK_DESTROY(sc);
|
243 ATH_RX_LOCK_DESTROY(sc); 244 ATH_PCU_LOCK_DESTROY(sc); 245 ATH_LOCK_DESTROY(sc); 246 247 return (0); 248} 249 250static int 251ath_ahb_shutdown(device_t dev) 252{ 253 struct ath_ahb_softc *psc = device_get_softc(dev); 254 255 ath_shutdown(&psc->sc_sc); 256 return (0); 257} 258 259static int 260ath_ahb_suspend(device_t dev) 261{ 262 struct ath_ahb_softc *psc = device_get_softc(dev); 263 264 ath_suspend(&psc->sc_sc); 265 266 return (0); 267} 268 269static int 270ath_ahb_resume(device_t dev) 271{ 272 struct ath_ahb_softc *psc = device_get_softc(dev); 273 274 ath_resume(&psc->sc_sc); 275 276 return (0); 277} 278 279static device_method_t ath_ahb_methods[] = { 280 /* Device interface */ 281 DEVMETHOD(device_probe, ath_ahb_probe), 282 DEVMETHOD(device_attach, ath_ahb_attach), 283 DEVMETHOD(device_detach, ath_ahb_detach), 284 DEVMETHOD(device_shutdown, ath_ahb_shutdown), 285 DEVMETHOD(device_suspend, ath_ahb_suspend), 286 DEVMETHOD(device_resume, ath_ahb_resume), 287 288 { 0,0 } 289}; 290static driver_t ath_ahb_driver = { 291 "ath", 292 ath_ahb_methods, 293 sizeof (struct ath_ahb_softc) 294}; 295static devclass_t ath_devclass; 296DRIVER_MODULE(ath, nexus, ath_ahb_driver, ath_devclass, 0, 0); 297MODULE_VERSION(ath, 1); 298MODULE_DEPEND(ath, wlan, 1, 1, 1); /* 802.11 media layer */ 299MODULE_DEPEND(ath, if_ath, 1, 1, 1); /* if_ath driver */
| 246 ATH_RX_LOCK_DESTROY(sc); 247 ATH_PCU_LOCK_DESTROY(sc); 248 ATH_LOCK_DESTROY(sc); 249 250 return (0); 251} 252 253static int 254ath_ahb_shutdown(device_t dev) 255{ 256 struct ath_ahb_softc *psc = device_get_softc(dev); 257 258 ath_shutdown(&psc->sc_sc); 259 return (0); 260} 261 262static int 263ath_ahb_suspend(device_t dev) 264{ 265 struct ath_ahb_softc *psc = device_get_softc(dev); 266 267 ath_suspend(&psc->sc_sc); 268 269 return (0); 270} 271 272static int 273ath_ahb_resume(device_t dev) 274{ 275 struct ath_ahb_softc *psc = device_get_softc(dev); 276 277 ath_resume(&psc->sc_sc); 278 279 return (0); 280} 281 282static device_method_t ath_ahb_methods[] = { 283 /* Device interface */ 284 DEVMETHOD(device_probe, ath_ahb_probe), 285 DEVMETHOD(device_attach, ath_ahb_attach), 286 DEVMETHOD(device_detach, ath_ahb_detach), 287 DEVMETHOD(device_shutdown, ath_ahb_shutdown), 288 DEVMETHOD(device_suspend, ath_ahb_suspend), 289 DEVMETHOD(device_resume, ath_ahb_resume), 290 291 { 0,0 } 292}; 293static driver_t ath_ahb_driver = { 294 "ath", 295 ath_ahb_methods, 296 sizeof (struct ath_ahb_softc) 297}; 298static devclass_t ath_devclass; 299DRIVER_MODULE(ath, nexus, ath_ahb_driver, ath_devclass, 0, 0); 300MODULE_VERSION(ath, 1); 301MODULE_DEPEND(ath, wlan, 1, 1, 1); /* 802.11 media layer */ 302MODULE_DEPEND(ath, if_ath, 1, 1, 1); /* if_ath driver */
|