diff options
author | Sujith <Sujith.Manoharan@atheros.com> | 2010-01-08 00:06:07 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-01-12 14:02:05 -0500 |
commit | 285f2ddae03ca207877262f5a9dbd9cddd8b3913 (patch) | |
tree | 7b26606956f4d6f4c1f564718769501b34d3f640 /drivers/net/wireless/ath/ath9k | |
parent | 1b04b9308ebc7f6accb319cf51c9b8ec29f79707 (diff) |
ath9k: Cleanup init/deinit routines
The device initialization and termination functions
were messy and convoluted. Introduce helper functions
to clarify init_softc() and simplify things in general.
Signed-off-by: Sujith <Sujith.Manoharan@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ahb.c | 20 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ath9k.h | 7 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/init.c | 515 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/pci.c | 57 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/virtual.c | 2 |
7 files changed, 309 insertions, 298 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index 329e6bc137ab..f24b1f4c3e29 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c | |||
@@ -121,16 +121,16 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
121 | sc->mem = mem; | 121 | sc->mem = mem; |
122 | sc->irq = irq; | 122 | sc->irq = irq; |
123 | 123 | ||
124 | ret = ath_init_device(AR5416_AR9100_DEVID, sc, 0x0, &ath_ahb_bus_ops); | 124 | ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc); |
125 | if (ret) { | 125 | if (ret) { |
126 | dev_err(&pdev->dev, "failed to initialize device\n"); | 126 | dev_err(&pdev->dev, "request_irq failed\n"); |
127 | goto err_free_hw; | 127 | goto err_free_hw; |
128 | } | 128 | } |
129 | 129 | ||
130 | ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc); | 130 | ret = ath9k_init_device(AR5416_AR9100_DEVID, sc, 0x0, &ath_ahb_bus_ops); |
131 | if (ret) { | 131 | if (ret) { |
132 | dev_err(&pdev->dev, "request_irq failed\n"); | 132 | dev_err(&pdev->dev, "failed to initialize device\n"); |
133 | goto err_detach; | 133 | goto err_irq; |
134 | } | 134 | } |
135 | 135 | ||
136 | ah = sc->sc_ah; | 136 | ah = sc->sc_ah; |
@@ -143,8 +143,8 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
143 | 143 | ||
144 | return 0; | 144 | return 0; |
145 | 145 | ||
146 | err_detach: | 146 | err_irq: |
147 | ath_detach(sc); | 147 | free_irq(irq, sc); |
148 | err_free_hw: | 148 | err_free_hw: |
149 | ieee80211_free_hw(hw); | 149 | ieee80211_free_hw(hw); |
150 | platform_set_drvdata(pdev, NULL); | 150 | platform_set_drvdata(pdev, NULL); |
@@ -161,8 +161,12 @@ static int ath_ahb_remove(struct platform_device *pdev) | |||
161 | if (hw) { | 161 | if (hw) { |
162 | struct ath_wiphy *aphy = hw->priv; | 162 | struct ath_wiphy *aphy = hw->priv; |
163 | struct ath_softc *sc = aphy->sc; | 163 | struct ath_softc *sc = aphy->sc; |
164 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
164 | 165 | ||
165 | ath_cleanup(sc); | 166 | ath9k_deinit_device(sc); |
167 | free_irq(sc->irq, sc); | ||
168 | ieee80211_free_hw(sc->hw); | ||
169 | ath_bus_cleanup(common); | ||
166 | platform_set_drvdata(pdev, NULL); | 170 | platform_set_drvdata(pdev, NULL); |
167 | } | 171 | } |
168 | 172 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index f4645a45ef3c..bf3d4c4bfa52 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -544,13 +544,12 @@ extern struct ieee80211_ops ath9k_ops; | |||
544 | extern int modparam_nohwcrypt; | 544 | extern int modparam_nohwcrypt; |
545 | 545 | ||
546 | irqreturn_t ath_isr(int irq, void *dev); | 546 | irqreturn_t ath_isr(int irq, void *dev); |
547 | void ath_cleanup(struct ath_softc *sc); | 547 | int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, |
548 | int ath_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, | ||
549 | const struct ath_bus_ops *bus_ops); | 548 | const struct ath_bus_ops *bus_ops); |
550 | void ath_detach(struct ath_softc *sc); | 549 | void ath9k_deinit_device(struct ath_softc *sc); |
551 | const char *ath_mac_bb_name(u32 mac_bb_version); | 550 | const char *ath_mac_bb_name(u32 mac_bb_version); |
552 | const char *ath_rf_name(u16 rf_version); | 551 | const char *ath_rf_name(u16 rf_version); |
553 | void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw); | 552 | void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw); |
554 | void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw, | 553 | void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw, |
555 | struct ath9k_channel *ichan); | 554 | struct ath9k_channel *ichan); |
556 | void ath_update_chainmask(struct ath_softc *sc, int is_ht); | 555 | void ath_update_chainmask(struct ath_softc *sc, int is_ht); |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 9474f9f6d400..2311fe7a0bf2 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -1242,7 +1242,7 @@ static void ath9k_hw_init_user_settings(struct ath_hw *ah) | |||
1242 | ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout); | 1242 | ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout); |
1243 | } | 1243 | } |
1244 | 1244 | ||
1245 | void ath9k_hw_detach(struct ath_hw *ah) | 1245 | void ath9k_hw_deinit(struct ath_hw *ah) |
1246 | { | 1246 | { |
1247 | struct ath_common *common = ath9k_hw_common(ah); | 1247 | struct ath_common *common = ath9k_hw_common(ah); |
1248 | 1248 | ||
@@ -1260,7 +1260,7 @@ free_hw: | |||
1260 | kfree(ah); | 1260 | kfree(ah); |
1261 | ah = NULL; | 1261 | ah = NULL; |
1262 | } | 1262 | } |
1263 | EXPORT_SYMBOL(ath9k_hw_detach); | 1263 | EXPORT_SYMBOL(ath9k_hw_deinit); |
1264 | 1264 | ||
1265 | /*******/ | 1265 | /*******/ |
1266 | /* INI */ | 1266 | /* INI */ |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 8849450dc591..3f0f055ea39b 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -616,7 +616,7 @@ static inline struct ath_regulatory *ath9k_hw_regulatory(struct ath_hw *ah) | |||
616 | 616 | ||
617 | /* Initialization, Detach, Reset */ | 617 | /* Initialization, Detach, Reset */ |
618 | const char *ath9k_hw_probe(u16 vendorid, u16 devid); | 618 | const char *ath9k_hw_probe(u16 vendorid, u16 devid); |
619 | void ath9k_hw_detach(struct ath_hw *ah); | 619 | void ath9k_hw_deinit(struct ath_hw *ah); |
620 | int ath9k_hw_init(struct ath_hw *ah); | 620 | int ath9k_hw_init(struct ath_hw *ah); |
621 | int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | 621 | int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, |
622 | bool bChannelChange); | 622 | bool bChannelChange); |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 2bea0892918e..16d1efb4b8b2 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -128,7 +128,7 @@ static struct ieee80211_rate ath9k_legacy_rates[] = { | |||
128 | RATE(540, 0x0c, 0), | 128 | RATE(540, 0x0c, 0), |
129 | }; | 129 | }; |
130 | 130 | ||
131 | static void ath9k_uninit_hw(struct ath_softc *sc); | 131 | static void ath9k_deinit_softc(struct ath_softc *sc); |
132 | 132 | ||
133 | /* | 133 | /* |
134 | * Read and write, they both share the same lock. We do this to serialize | 134 | * Read and write, they both share the same lock. We do this to serialize |
@@ -333,67 +333,13 @@ fail: | |||
333 | #undef DS2PHYS | 333 | #undef DS2PHYS |
334 | } | 334 | } |
335 | 335 | ||
336 | static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, | 336 | static void ath9k_init_crypto(struct ath_softc *sc) |
337 | const struct ath_bus_ops *bus_ops) | ||
338 | { | 337 | { |
339 | struct ath_hw *ah = NULL; | 338 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
340 | struct ath_common *common; | 339 | int i = 0; |
341 | int r = 0, i; | ||
342 | int csz = 0; | ||
343 | int qnum; | ||
344 | |||
345 | /* XXX: hardware will not be ready until ath_open() being called */ | ||
346 | sc->sc_flags |= SC_OP_INVALID; | ||
347 | |||
348 | spin_lock_init(&sc->wiphy_lock); | ||
349 | spin_lock_init(&sc->sc_resetlock); | ||
350 | spin_lock_init(&sc->sc_serial_rw); | ||
351 | spin_lock_init(&sc->sc_pm_lock); | ||
352 | mutex_init(&sc->mutex); | ||
353 | tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); | ||
354 | tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet, | ||
355 | (unsigned long)sc); | ||
356 | |||
357 | ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL); | ||
358 | if (!ah) | ||
359 | return -ENOMEM; | ||
360 | |||
361 | ah->hw_version.devid = devid; | ||
362 | ah->hw_version.subsysid = subsysid; | ||
363 | sc->sc_ah = ah; | ||
364 | |||
365 | common = ath9k_hw_common(ah); | ||
366 | common->ops = &ath9k_common_ops; | ||
367 | common->bus_ops = bus_ops; | ||
368 | common->ah = ah; | ||
369 | common->hw = sc->hw; | ||
370 | common->priv = sc; | ||
371 | common->debug_mask = ath9k_debug; | ||
372 | |||
373 | /* | ||
374 | * Cache line size is used to size and align various | ||
375 | * structures used to communicate with the hardware. | ||
376 | */ | ||
377 | ath_read_cachesize(common, &csz); | ||
378 | /* XXX assert csz is non-zero */ | ||
379 | common->cachelsz = csz << 2; /* convert to bytes */ | ||
380 | |||
381 | r = ath9k_hw_init(ah); | ||
382 | if (r) { | ||
383 | ath_print(common, ATH_DBG_FATAL, | ||
384 | "Unable to initialize hardware; " | ||
385 | "initialization status: %d\n", r); | ||
386 | goto bad_free_hw; | ||
387 | } | ||
388 | |||
389 | if (ath9k_init_debug(ah) < 0) { | ||
390 | ath_print(common, ATH_DBG_FATAL, | ||
391 | "Unable to create debugfs files\n"); | ||
392 | goto bad_free_hw; | ||
393 | } | ||
394 | 340 | ||
395 | /* Get the hardware key cache size. */ | 341 | /* Get the hardware key cache size. */ |
396 | common->keymax = ah->caps.keycache_size; | 342 | common->keymax = sc->sc_ah->caps.keycache_size; |
397 | if (common->keymax > ATH_KEYMAX) { | 343 | if (common->keymax > ATH_KEYMAX) { |
398 | ath_print(common, ATH_DBG_ANY, | 344 | ath_print(common, ATH_DBG_ANY, |
399 | "Warning, using only %u entries in %u key cache\n", | 345 | "Warning, using only %u entries in %u key cache\n", |
@@ -406,185 +352,273 @@ static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, | |||
406 | * reset the contents on initial power up. | 352 | * reset the contents on initial power up. |
407 | */ | 353 | */ |
408 | for (i = 0; i < common->keymax; i++) | 354 | for (i = 0; i < common->keymax; i++) |
409 | ath9k_hw_keyreset(ah, (u16) i); | 355 | ath9k_hw_keyreset(sc->sc_ah, (u16) i); |
410 | 356 | ||
411 | /* default to MONITOR mode */ | 357 | if (ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_CIPHER, |
412 | sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR; | 358 | ATH9K_CIPHER_TKIP, NULL)) { |
359 | /* | ||
360 | * Whether we should enable h/w TKIP MIC. | ||
361 | * XXX: if we don't support WME TKIP MIC, then we wouldn't | ||
362 | * report WMM capable, so it's always safe to turn on | ||
363 | * TKIP MIC in this case. | ||
364 | */ | ||
365 | ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_TKIP_MIC, 0, 1, NULL); | ||
366 | } | ||
413 | 367 | ||
414 | /* | 368 | /* |
415 | * Allocate hardware transmit queues: one queue for | 369 | * Check whether the separate key cache entries |
416 | * beacon frames and one data queue for each QoS | 370 | * are required to handle both tx+rx MIC keys. |
417 | * priority. Note that the hal handles reseting | 371 | * With split mic keys the number of stations is limited |
418 | * these queues at the needed time. | 372 | * to 27 otherwise 59. |
419 | */ | 373 | */ |
420 | sc->beacon.beaconq = ath9k_hw_beaconq_setup(ah); | 374 | if (ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_CIPHER, |
375 | ATH9K_CIPHER_TKIP, NULL) | ||
376 | && ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_CIPHER, | ||
377 | ATH9K_CIPHER_MIC, NULL) | ||
378 | && ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_TKIP_SPLIT, | ||
379 | 0, NULL)) | ||
380 | common->splitmic = 1; | ||
381 | |||
382 | /* turn on mcast key search if possible */ | ||
383 | if (!ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL)) | ||
384 | (void)ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_MCAST_KEYSRCH, | ||
385 | 1, 1, NULL); | ||
386 | |||
387 | } | ||
388 | |||
389 | static int ath9k_init_btcoex(struct ath_softc *sc) | ||
390 | { | ||
391 | int r, qnum; | ||
392 | |||
393 | switch (sc->sc_ah->btcoex_hw.scheme) { | ||
394 | case ATH_BTCOEX_CFG_NONE: | ||
395 | break; | ||
396 | case ATH_BTCOEX_CFG_2WIRE: | ||
397 | ath9k_hw_btcoex_init_2wire(sc->sc_ah); | ||
398 | break; | ||
399 | case ATH_BTCOEX_CFG_3WIRE: | ||
400 | ath9k_hw_btcoex_init_3wire(sc->sc_ah); | ||
401 | r = ath_init_btcoex_timer(sc); | ||
402 | if (r) | ||
403 | return -1; | ||
404 | qnum = ath_tx_get_qnum(sc, ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE); | ||
405 | ath9k_hw_init_btcoex_hw(sc->sc_ah, qnum); | ||
406 | sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; | ||
407 | break; | ||
408 | default: | ||
409 | WARN_ON(1); | ||
410 | break; | ||
411 | } | ||
412 | |||
413 | return 0; | ||
414 | } | ||
415 | |||
416 | static int ath9k_init_queues(struct ath_softc *sc) | ||
417 | { | ||
418 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
419 | int i = 0; | ||
420 | |||
421 | for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++) | ||
422 | sc->tx.hwq_map[i] = -1; | ||
423 | |||
424 | sc->beacon.beaconq = ath9k_hw_beaconq_setup(sc->sc_ah); | ||
421 | if (sc->beacon.beaconq == -1) { | 425 | if (sc->beacon.beaconq == -1) { |
422 | ath_print(common, ATH_DBG_FATAL, | 426 | ath_print(common, ATH_DBG_FATAL, |
423 | "Unable to setup a beacon xmit queue\n"); | 427 | "Unable to setup a beacon xmit queue\n"); |
424 | r = -EIO; | 428 | goto err; |
425 | goto bad2; | ||
426 | } | 429 | } |
430 | |||
427 | sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0); | 431 | sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0); |
428 | if (sc->beacon.cabq == NULL) { | 432 | if (sc->beacon.cabq == NULL) { |
429 | ath_print(common, ATH_DBG_FATAL, | 433 | ath_print(common, ATH_DBG_FATAL, |
430 | "Unable to setup CAB xmit queue\n"); | 434 | "Unable to setup CAB xmit queue\n"); |
431 | r = -EIO; | 435 | goto err; |
432 | goto bad2; | ||
433 | } | 436 | } |
434 | 437 | ||
435 | sc->config.cabqReadytime = ATH_CABQ_READY_TIME; | 438 | sc->config.cabqReadytime = ATH_CABQ_READY_TIME; |
436 | ath_cabq_update(sc); | 439 | ath_cabq_update(sc); |
437 | 440 | ||
438 | for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++) | ||
439 | sc->tx.hwq_map[i] = -1; | ||
440 | |||
441 | /* Setup data queues */ | ||
442 | /* NB: ensure BK queue is the lowest priority h/w queue */ | ||
443 | if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) { | 441 | if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) { |
444 | ath_print(common, ATH_DBG_FATAL, | 442 | ath_print(common, ATH_DBG_FATAL, |
445 | "Unable to setup xmit queue for BK traffic\n"); | 443 | "Unable to setup xmit queue for BK traffic\n"); |
446 | r = -EIO; | 444 | goto err; |
447 | goto bad2; | ||
448 | } | 445 | } |
449 | 446 | ||
450 | if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) { | 447 | if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) { |
451 | ath_print(common, ATH_DBG_FATAL, | 448 | ath_print(common, ATH_DBG_FATAL, |
452 | "Unable to setup xmit queue for BE traffic\n"); | 449 | "Unable to setup xmit queue for BE traffic\n"); |
453 | r = -EIO; | 450 | goto err; |
454 | goto bad2; | ||
455 | } | 451 | } |
456 | if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) { | 452 | if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) { |
457 | ath_print(common, ATH_DBG_FATAL, | 453 | ath_print(common, ATH_DBG_FATAL, |
458 | "Unable to setup xmit queue for VI traffic\n"); | 454 | "Unable to setup xmit queue for VI traffic\n"); |
459 | r = -EIO; | 455 | goto err; |
460 | goto bad2; | ||
461 | } | 456 | } |
462 | if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) { | 457 | if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) { |
463 | ath_print(common, ATH_DBG_FATAL, | 458 | ath_print(common, ATH_DBG_FATAL, |
464 | "Unable to setup xmit queue for VO traffic\n"); | 459 | "Unable to setup xmit queue for VO traffic\n"); |
465 | r = -EIO; | 460 | goto err; |
466 | goto bad2; | ||
467 | } | 461 | } |
468 | 462 | ||
469 | /* Initializes the noise floor to a reasonable default value. | 463 | return 0; |
470 | * Later on this will be updated during ANI processing. */ | ||
471 | 464 | ||
472 | common->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR; | 465 | err: |
473 | setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); | 466 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) |
467 | if (ATH_TXQ_SETUP(sc, i)) | ||
468 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); | ||
474 | 469 | ||
475 | if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER, | 470 | return -EIO; |
476 | ATH9K_CIPHER_TKIP, NULL)) { | 471 | } |
477 | /* | 472 | |
478 | * Whether we should enable h/w TKIP MIC. | 473 | static void ath9k_init_channels_rates(struct ath_softc *sc) |
479 | * XXX: if we don't support WME TKIP MIC, then we wouldn't | 474 | { |
480 | * report WMM capable, so it's always safe to turn on | 475 | if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) { |
481 | * TKIP MIC in this case. | 476 | sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable; |
482 | */ | 477 | sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; |
483 | ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_TKIP_MIC, | 478 | sc->sbands[IEEE80211_BAND_2GHZ].n_channels = |
484 | 0, 1, NULL); | 479 | ARRAY_SIZE(ath9k_2ghz_chantable); |
480 | sc->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates; | ||
481 | sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates = | ||
482 | ARRAY_SIZE(ath9k_legacy_rates); | ||
485 | } | 483 | } |
486 | 484 | ||
487 | /* | 485 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) { |
488 | * Check whether the separate key cache entries | 486 | sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable; |
489 | * are required to handle both tx+rx MIC keys. | 487 | sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; |
490 | * With split mic keys the number of stations is limited | 488 | sc->sbands[IEEE80211_BAND_5GHZ].n_channels = |
491 | * to 27 otherwise 59. | 489 | ARRAY_SIZE(ath9k_5ghz_chantable); |
492 | */ | 490 | sc->sbands[IEEE80211_BAND_5GHZ].bitrates = |
493 | if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER, | 491 | ath9k_legacy_rates + 4; |
494 | ATH9K_CIPHER_TKIP, NULL) | 492 | sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates = |
495 | && ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER, | 493 | ARRAY_SIZE(ath9k_legacy_rates) - 4; |
496 | ATH9K_CIPHER_MIC, NULL) | 494 | } |
497 | && ath9k_hw_getcapability(ah, ATH9K_CAP_TKIP_SPLIT, | 495 | } |
498 | 0, NULL)) | ||
499 | common->splitmic = 1; | ||
500 | 496 | ||
501 | /* turn on mcast key search if possible */ | 497 | static void ath9k_init_misc(struct ath_softc *sc) |
502 | if (!ath9k_hw_getcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL)) | 498 | { |
503 | (void)ath9k_hw_setcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 1, | 499 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
504 | 1, NULL); | 500 | int i = 0; |
501 | |||
502 | common->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR; | ||
503 | setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); | ||
505 | 504 | ||
506 | sc->config.txpowlimit = ATH_TXPOWER_MAX; | 505 | sc->config.txpowlimit = ATH_TXPOWER_MAX; |
507 | 506 | ||
508 | /* 11n Capabilities */ | 507 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { |
509 | if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) { | ||
510 | sc->sc_flags |= SC_OP_TXAGGR; | 508 | sc->sc_flags |= SC_OP_TXAGGR; |
511 | sc->sc_flags |= SC_OP_RXAGGR; | 509 | sc->sc_flags |= SC_OP_RXAGGR; |
512 | } | 510 | } |
513 | 511 | ||
514 | common->tx_chainmask = ah->caps.tx_chainmask; | 512 | common->tx_chainmask = sc->sc_ah->caps.tx_chainmask; |
515 | common->rx_chainmask = ah->caps.rx_chainmask; | 513 | common->rx_chainmask = sc->sc_ah->caps.rx_chainmask; |
516 | 514 | ||
517 | ath9k_hw_setcapability(ah, ATH9K_CAP_DIVERSITY, 1, true, NULL); | 515 | ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_DIVERSITY, 1, true, NULL); |
518 | sc->rx.defant = ath9k_hw_getdefantenna(ah); | 516 | sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah); |
519 | 517 | ||
520 | if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) | 518 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) |
521 | memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); | 519 | memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); |
522 | 520 | ||
523 | sc->beacon.slottime = ATH9K_SLOT_TIME_9; /* default to short slot time */ | 521 | sc->beacon.slottime = ATH9K_SLOT_TIME_9; |
524 | 522 | ||
525 | /* initialize beacon slots */ | ||
526 | for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) { | 523 | for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) { |
527 | sc->beacon.bslot[i] = NULL; | 524 | sc->beacon.bslot[i] = NULL; |
528 | sc->beacon.bslot_aphy[i] = NULL; | 525 | sc->beacon.bslot_aphy[i] = NULL; |
529 | } | 526 | } |
527 | } | ||
530 | 528 | ||
531 | /* setup channels and rates */ | 529 | static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, |
530 | const struct ath_bus_ops *bus_ops) | ||
531 | { | ||
532 | struct ath_hw *ah = NULL; | ||
533 | struct ath_common *common; | ||
534 | int ret = 0, i; | ||
535 | int csz = 0; | ||
532 | 536 | ||
533 | if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) { | 537 | sc->sc_flags |= SC_OP_INVALID; |
534 | sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable; | ||
535 | sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; | ||
536 | sc->sbands[IEEE80211_BAND_2GHZ].n_channels = | ||
537 | ARRAY_SIZE(ath9k_2ghz_chantable); | ||
538 | sc->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates; | ||
539 | sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates = | ||
540 | ARRAY_SIZE(ath9k_legacy_rates); | ||
541 | } | ||
542 | 538 | ||
543 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) { | 539 | ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL); |
544 | sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable; | 540 | if (!ah) |
545 | sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; | 541 | return -ENOMEM; |
546 | sc->sbands[IEEE80211_BAND_5GHZ].n_channels = | 542 | |
547 | ARRAY_SIZE(ath9k_5ghz_chantable); | 543 | ah->hw_version.devid = devid; |
548 | sc->sbands[IEEE80211_BAND_5GHZ].bitrates = | 544 | ah->hw_version.subsysid = subsysid; |
549 | ath9k_legacy_rates + 4; | 545 | sc->sc_ah = ah; |
550 | sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates = | 546 | |
551 | ARRAY_SIZE(ath9k_legacy_rates) - 4; | 547 | common = ath9k_hw_common(ah); |
548 | common->ops = &ath9k_common_ops; | ||
549 | common->bus_ops = bus_ops; | ||
550 | common->ah = ah; | ||
551 | common->hw = sc->hw; | ||
552 | common->priv = sc; | ||
553 | common->debug_mask = ath9k_debug; | ||
554 | |||
555 | spin_lock_init(&sc->wiphy_lock); | ||
556 | spin_lock_init(&sc->sc_resetlock); | ||
557 | spin_lock_init(&sc->sc_serial_rw); | ||
558 | spin_lock_init(&sc->sc_pm_lock); | ||
559 | mutex_init(&sc->mutex); | ||
560 | tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); | ||
561 | tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet, | ||
562 | (unsigned long)sc); | ||
563 | |||
564 | /* | ||
565 | * Cache line size is used to size and align various | ||
566 | * structures used to communicate with the hardware. | ||
567 | */ | ||
568 | ath_read_cachesize(common, &csz); | ||
569 | common->cachelsz = csz << 2; /* convert to bytes */ | ||
570 | |||
571 | ret = ath9k_hw_init(ah); | ||
572 | if (ret) { | ||
573 | ath_print(common, ATH_DBG_FATAL, | ||
574 | "Unable to initialize hardware; " | ||
575 | "initialization status: %d\n", ret); | ||
576 | goto err_hw; | ||
552 | } | 577 | } |
553 | 578 | ||
554 | switch (ah->btcoex_hw.scheme) { | 579 | ret = ath9k_init_debug(ah); |
555 | case ATH_BTCOEX_CFG_NONE: | 580 | if (ret) { |
556 | break; | 581 | ath_print(common, ATH_DBG_FATAL, |
557 | case ATH_BTCOEX_CFG_2WIRE: | 582 | "Unable to create debugfs files\n"); |
558 | ath9k_hw_btcoex_init_2wire(ah); | 583 | goto err_debug; |
559 | break; | ||
560 | case ATH_BTCOEX_CFG_3WIRE: | ||
561 | ath9k_hw_btcoex_init_3wire(ah); | ||
562 | r = ath_init_btcoex_timer(sc); | ||
563 | if (r) | ||
564 | goto bad2; | ||
565 | qnum = ath_tx_get_qnum(sc, ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE); | ||
566 | ath9k_hw_init_btcoex_hw(ah, qnum); | ||
567 | sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; | ||
568 | break; | ||
569 | default: | ||
570 | WARN_ON(1); | ||
571 | break; | ||
572 | } | 584 | } |
573 | 585 | ||
586 | ret = ath9k_init_queues(sc); | ||
587 | if (ret) | ||
588 | goto err_queues; | ||
589 | |||
590 | ret = ath9k_init_btcoex(sc); | ||
591 | if (ret) | ||
592 | goto err_btcoex; | ||
593 | |||
594 | ath9k_init_crypto(sc); | ||
595 | ath9k_init_channels_rates(sc); | ||
596 | ath9k_init_misc(sc); | ||
597 | |||
574 | return 0; | 598 | return 0; |
575 | bad2: | 599 | |
576 | /* cleanup tx queues */ | 600 | err_btcoex: |
577 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | 601 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) |
578 | if (ATH_TXQ_SETUP(sc, i)) | 602 | if (ATH_TXQ_SETUP(sc, i)) |
579 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); | 603 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); |
604 | err_queues: | ||
605 | ath9k_exit_debug(ah); | ||
606 | err_debug: | ||
607 | ath9k_hw_deinit(ah); | ||
608 | err_hw: | ||
609 | tasklet_kill(&sc->intr_tq); | ||
610 | tasklet_kill(&sc->bcon_tasklet); | ||
580 | 611 | ||
581 | bad_free_hw: | 612 | kfree(ah); |
582 | ath9k_uninit_hw(sc); | 613 | sc->sc_ah = NULL; |
583 | return r; | 614 | |
615 | return ret; | ||
584 | } | 616 | } |
585 | 617 | ||
586 | void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | 618 | void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) |
587 | { | 619 | { |
620 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
621 | |||
588 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | 622 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | |
589 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 623 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
590 | IEEE80211_HW_SIGNAL_DBM | | 624 | IEEE80211_HW_SIGNAL_DBM | |
@@ -621,85 +655,85 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
621 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) | 655 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) |
622 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | 656 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = |
623 | &sc->sbands[IEEE80211_BAND_5GHZ]; | 657 | &sc->sbands[IEEE80211_BAND_5GHZ]; |
658 | |||
659 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { | ||
660 | if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) | ||
661 | setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); | ||
662 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) | ||
663 | setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); | ||
664 | } | ||
665 | |||
666 | SET_IEEE80211_PERM_ADDR(hw, common->macaddr); | ||
624 | } | 667 | } |
625 | 668 | ||
626 | /* Device driver core initialization */ | 669 | int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, |
627 | int ath_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, | ||
628 | const struct ath_bus_ops *bus_ops) | 670 | const struct ath_bus_ops *bus_ops) |
629 | { | 671 | { |
630 | struct ieee80211_hw *hw = sc->hw; | 672 | struct ieee80211_hw *hw = sc->hw; |
631 | struct ath_common *common; | 673 | struct ath_common *common; |
632 | struct ath_hw *ah; | 674 | struct ath_hw *ah; |
633 | int error = 0, i; | 675 | int error = 0; |
634 | struct ath_regulatory *reg; | 676 | struct ath_regulatory *reg; |
635 | 677 | ||
636 | dev_dbg(sc->dev, "Attach ATH hw\n"); | 678 | /* Bring up device */ |
637 | 679 | error = ath9k_init_softc(devid, sc, subsysid, bus_ops); | |
638 | error = ath_init_softc(devid, sc, subsysid, bus_ops); | ||
639 | if (error != 0) | 680 | if (error != 0) |
640 | return error; | 681 | goto error_init; |
641 | 682 | ||
642 | ah = sc->sc_ah; | 683 | ah = sc->sc_ah; |
643 | common = ath9k_hw_common(ah); | 684 | common = ath9k_hw_common(ah); |
685 | ath9k_set_hw_capab(sc, hw); | ||
644 | 686 | ||
645 | /* get mac address from hardware and set in mac80211 */ | 687 | /* Initialize regulatory */ |
646 | |||
647 | SET_IEEE80211_PERM_ADDR(hw, common->macaddr); | ||
648 | |||
649 | ath_set_hw_capab(sc, hw); | ||
650 | |||
651 | error = ath_regd_init(&common->regulatory, sc->hw->wiphy, | 688 | error = ath_regd_init(&common->regulatory, sc->hw->wiphy, |
652 | ath9k_reg_notifier); | 689 | ath9k_reg_notifier); |
653 | if (error) | 690 | if (error) |
654 | return error; | 691 | goto error_regd; |
655 | 692 | ||
656 | reg = &common->regulatory; | 693 | reg = &common->regulatory; |
657 | 694 | ||
658 | if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) { | 695 | /* Setup TX DMA */ |
659 | if (test_bit(ATH9K_MODE_11G, ah->caps.wireless_modes)) | ||
660 | setup_ht_cap(sc, | ||
661 | &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); | ||
662 | if (test_bit(ATH9K_MODE_11A, ah->caps.wireless_modes)) | ||
663 | setup_ht_cap(sc, | ||
664 | &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); | ||
665 | } | ||
666 | |||
667 | /* initialize tx/rx engine */ | ||
668 | error = ath_tx_init(sc, ATH_TXBUF); | 696 | error = ath_tx_init(sc, ATH_TXBUF); |
669 | if (error != 0) | 697 | if (error != 0) |
670 | goto error_attach; | 698 | goto error_tx; |
671 | 699 | ||
700 | /* Setup RX DMA */ | ||
672 | error = ath_rx_init(sc, ATH_RXBUF); | 701 | error = ath_rx_init(sc, ATH_RXBUF); |
673 | if (error != 0) | 702 | if (error != 0) |
674 | goto error_attach; | 703 | goto error_rx; |
675 | |||
676 | INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work); | ||
677 | INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work); | ||
678 | sc->wiphy_scheduler_int = msecs_to_jiffies(500); | ||
679 | 704 | ||
705 | /* Register with mac80211 */ | ||
680 | error = ieee80211_register_hw(hw); | 706 | error = ieee80211_register_hw(hw); |
707 | if (error) | ||
708 | goto error_register; | ||
681 | 709 | ||
710 | /* Handle world regulatory */ | ||
682 | if (!ath_is_world_regd(reg)) { | 711 | if (!ath_is_world_regd(reg)) { |
683 | error = regulatory_hint(hw->wiphy, reg->alpha2); | 712 | error = regulatory_hint(hw->wiphy, reg->alpha2); |
684 | if (error) | 713 | if (error) |
685 | goto error_attach; | 714 | goto error_world; |
686 | } | 715 | } |
687 | 716 | ||
688 | /* Initialize LED control */ | 717 | INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work); |
689 | ath_init_leds(sc); | 718 | INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work); |
719 | sc->wiphy_scheduler_int = msecs_to_jiffies(500); | ||
690 | 720 | ||
721 | ath_init_leds(sc); | ||
691 | ath_start_rfkill_poll(sc); | 722 | ath_start_rfkill_poll(sc); |
692 | 723 | ||
693 | return 0; | 724 | return 0; |
694 | 725 | ||
695 | error_attach: | 726 | error_world: |
696 | /* cleanup tx queues */ | 727 | ieee80211_unregister_hw(hw); |
697 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | 728 | error_register: |
698 | if (ATH_TXQ_SETUP(sc, i)) | 729 | ath_rx_cleanup(sc); |
699 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); | 730 | error_rx: |
700 | 731 | ath_tx_cleanup(sc); | |
701 | ath9k_uninit_hw(sc); | 732 | error_tx: |
702 | 733 | /* Nothing */ | |
734 | error_regd: | ||
735 | ath9k_deinit_softc(sc); | ||
736 | error_init: | ||
703 | return error; | 737 | return error; |
704 | } | 738 | } |
705 | 739 | ||
@@ -707,29 +741,34 @@ error_attach: | |||
707 | /* De-Initialization */ | 741 | /* De-Initialization */ |
708 | /*****************************/ | 742 | /*****************************/ |
709 | 743 | ||
710 | static void ath9k_uninit_hw(struct ath_softc *sc) | 744 | static void ath9k_deinit_softc(struct ath_softc *sc) |
711 | { | 745 | { |
712 | struct ath_hw *ah = sc->sc_ah; | 746 | int i = 0; |
713 | 747 | ||
714 | BUG_ON(!ah); | 748 | if ((sc->btcoex.no_stomp_timer) && |
749 | sc->sc_ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) | ||
750 | ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer); | ||
715 | 751 | ||
716 | ath9k_exit_debug(ah); | 752 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) |
717 | ath9k_hw_detach(ah); | 753 | if (ATH_TXQ_SETUP(sc, i)) |
718 | sc->sc_ah = NULL; | 754 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); |
755 | |||
756 | ath9k_exit_debug(sc->sc_ah); | ||
757 | ath9k_hw_deinit(sc->sc_ah); | ||
758 | |||
759 | tasklet_kill(&sc->intr_tq); | ||
760 | tasklet_kill(&sc->bcon_tasklet); | ||
719 | } | 761 | } |
720 | 762 | ||
721 | static void ath_clean_core(struct ath_softc *sc) | 763 | void ath9k_deinit_device(struct ath_softc *sc) |
722 | { | 764 | { |
723 | struct ieee80211_hw *hw = sc->hw; | 765 | struct ieee80211_hw *hw = sc->hw; |
724 | struct ath_hw *ah = sc->sc_ah; | ||
725 | int i = 0; | 766 | int i = 0; |
726 | 767 | ||
727 | ath9k_ps_wakeup(sc); | 768 | ath9k_ps_wakeup(sc); |
728 | 769 | ||
729 | dev_dbg(sc->dev, "Detach ATH hw\n"); | ||
730 | |||
731 | ath_deinit_leds(sc); | ||
732 | wiphy_rfkill_stop_polling(sc->hw->wiphy); | 770 | wiphy_rfkill_stop_polling(sc->hw->wiphy); |
771 | ath_deinit_leds(sc); | ||
733 | 772 | ||
734 | for (i = 0; i < sc->num_sec_wiphy; i++) { | 773 | for (i = 0; i < sc->num_sec_wiphy; i++) { |
735 | struct ath_wiphy *aphy = sc->sec_wiphy[i]; | 774 | struct ath_wiphy *aphy = sc->sec_wiphy[i]; |
@@ -739,24 +778,12 @@ static void ath_clean_core(struct ath_softc *sc) | |||
739 | ieee80211_unregister_hw(aphy->hw); | 778 | ieee80211_unregister_hw(aphy->hw); |
740 | ieee80211_free_hw(aphy->hw); | 779 | ieee80211_free_hw(aphy->hw); |
741 | } | 780 | } |
781 | kfree(sc->sec_wiphy); | ||
782 | |||
742 | ieee80211_unregister_hw(hw); | 783 | ieee80211_unregister_hw(hw); |
743 | ath_rx_cleanup(sc); | 784 | ath_rx_cleanup(sc); |
744 | ath_tx_cleanup(sc); | 785 | ath_tx_cleanup(sc); |
745 | 786 | ath9k_deinit_softc(sc); | |
746 | tasklet_kill(&sc->intr_tq); | ||
747 | tasklet_kill(&sc->bcon_tasklet); | ||
748 | |||
749 | if (!(sc->sc_flags & SC_OP_INVALID)) | ||
750 | ath9k_setpower(sc, ATH9K_PM_AWAKE); | ||
751 | |||
752 | /* cleanup tx queues */ | ||
753 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | ||
754 | if (ATH_TXQ_SETUP(sc, i)) | ||
755 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); | ||
756 | |||
757 | if ((sc->btcoex.no_stomp_timer) && | ||
758 | ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) | ||
759 | ath_gen_timer_free(ah, sc->btcoex.no_stomp_timer); | ||
760 | } | 787 | } |
761 | 788 | ||
762 | void ath_descdma_cleanup(struct ath_softc *sc, | 789 | void ath_descdma_cleanup(struct ath_softc *sc, |
@@ -771,26 +798,6 @@ void ath_descdma_cleanup(struct ath_softc *sc, | |||
771 | memset(dd, 0, sizeof(*dd)); | 798 | memset(dd, 0, sizeof(*dd)); |
772 | } | 799 | } |
773 | 800 | ||
774 | void ath_detach(struct ath_softc *sc) | ||
775 | { | ||
776 | ath_clean_core(sc); | ||
777 | ath9k_uninit_hw(sc); | ||
778 | } | ||
779 | |||
780 | void ath_cleanup(struct ath_softc *sc) | ||
781 | { | ||
782 | struct ath_hw *ah = sc->sc_ah; | ||
783 | struct ath_common *common = ath9k_hw_common(ah); | ||
784 | |||
785 | ath_clean_core(sc); | ||
786 | free_irq(sc->irq, sc); | ||
787 | ath_bus_cleanup(common); | ||
788 | kfree(sc->sec_wiphy); | ||
789 | ieee80211_free_hw(sc->hw); | ||
790 | |||
791 | ath9k_uninit_hw(sc); | ||
792 | } | ||
793 | |||
794 | /************************/ | 801 | /************************/ |
795 | /* Module Hooks */ | 802 | /* Module Hooks */ |
796 | /************************/ | 803 | /************************/ |
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index f7af5ea54753..95b9a07597ef 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c | |||
@@ -113,25 +113,22 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
113 | u16 subsysid; | 113 | u16 subsysid; |
114 | u32 val; | 114 | u32 val; |
115 | int ret = 0; | 115 | int ret = 0; |
116 | struct ath_hw *ah; | ||
117 | char hw_name[64]; | 116 | char hw_name[64]; |
118 | 117 | ||
119 | if (pci_enable_device(pdev)) | 118 | if (pci_enable_device(pdev)) |
120 | return -EIO; | 119 | return -EIO; |
121 | 120 | ||
122 | ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | 121 | ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); |
123 | |||
124 | if (ret) { | 122 | if (ret) { |
125 | printk(KERN_ERR "ath9k: 32-bit DMA not available\n"); | 123 | printk(KERN_ERR "ath9k: 32-bit DMA not available\n"); |
126 | goto bad; | 124 | goto err_dma; |
127 | } | 125 | } |
128 | 126 | ||
129 | ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); | 127 | ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); |
130 | |||
131 | if (ret) { | 128 | if (ret) { |
132 | printk(KERN_ERR "ath9k: 32-bit DMA consistent " | 129 | printk(KERN_ERR "ath9k: 32-bit DMA consistent " |
133 | "DMA enable failed\n"); | 130 | "DMA enable failed\n"); |
134 | goto bad; | 131 | goto err_dma; |
135 | } | 132 | } |
136 | 133 | ||
137 | /* | 134 | /* |
@@ -171,22 +168,22 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
171 | if (ret) { | 168 | if (ret) { |
172 | dev_err(&pdev->dev, "PCI memory region reserve error\n"); | 169 | dev_err(&pdev->dev, "PCI memory region reserve error\n"); |
173 | ret = -ENODEV; | 170 | ret = -ENODEV; |
174 | goto bad; | 171 | goto err_region; |
175 | } | 172 | } |
176 | 173 | ||
177 | mem = pci_iomap(pdev, 0, 0); | 174 | mem = pci_iomap(pdev, 0, 0); |
178 | if (!mem) { | 175 | if (!mem) { |
179 | printk(KERN_ERR "PCI memory map error\n") ; | 176 | printk(KERN_ERR "PCI memory map error\n") ; |
180 | ret = -EIO; | 177 | ret = -EIO; |
181 | goto bad1; | 178 | goto err_iomap; |
182 | } | 179 | } |
183 | 180 | ||
184 | hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) + | 181 | hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) + |
185 | sizeof(struct ath_softc), &ath9k_ops); | 182 | sizeof(struct ath_softc), &ath9k_ops); |
186 | if (!hw) { | 183 | if (!hw) { |
187 | dev_err(&pdev->dev, "no memory for ieee80211_hw\n"); | 184 | dev_err(&pdev->dev, "No memory for ieee80211_hw\n"); |
188 | ret = -ENOMEM; | 185 | ret = -ENOMEM; |
189 | goto bad2; | 186 | goto err_alloc_hw; |
190 | } | 187 | } |
191 | 188 | ||
192 | SET_IEEE80211_DEV(hw, &pdev->dev); | 189 | SET_IEEE80211_DEV(hw, &pdev->dev); |
@@ -201,25 +198,22 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
201 | sc->dev = &pdev->dev; | 198 | sc->dev = &pdev->dev; |
202 | sc->mem = mem; | 199 | sc->mem = mem; |
203 | 200 | ||
204 | pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsysid); | ||
205 | ret = ath_init_device(id->device, sc, subsysid, &ath_pci_bus_ops); | ||
206 | if (ret) { | ||
207 | dev_err(&pdev->dev, "failed to initialize device\n"); | ||
208 | goto bad3; | ||
209 | } | ||
210 | |||
211 | /* setup interrupt service routine */ | ||
212 | |||
213 | ret = request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath9k", sc); | 201 | ret = request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath9k", sc); |
214 | if (ret) { | 202 | if (ret) { |
215 | dev_err(&pdev->dev, "request_irq failed\n"); | 203 | dev_err(&pdev->dev, "request_irq failed\n"); |
216 | goto bad4; | 204 | goto err_irq; |
217 | } | 205 | } |
218 | 206 | ||
219 | sc->irq = pdev->irq; | 207 | sc->irq = pdev->irq; |
220 | 208 | ||
221 | ah = sc->sc_ah; | 209 | pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsysid); |
222 | ath9k_hw_name(ah, hw_name, sizeof(hw_name)); | 210 | ret = ath9k_init_device(id->device, sc, subsysid, &ath_pci_bus_ops); |
211 | if (ret) { | ||
212 | dev_err(&pdev->dev, "Failed to initialize device\n"); | ||
213 | goto err_init; | ||
214 | } | ||
215 | |||
216 | ath9k_hw_name(sc->sc_ah, hw_name, sizeof(hw_name)); | ||
223 | printk(KERN_INFO | 217 | printk(KERN_INFO |
224 | "%s: %s mem=0x%lx, irq=%d\n", | 218 | "%s: %s mem=0x%lx, irq=%d\n", |
225 | wiphy_name(hw->wiphy), | 219 | wiphy_name(hw->wiphy), |
@@ -227,15 +221,18 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
227 | (unsigned long)mem, pdev->irq); | 221 | (unsigned long)mem, pdev->irq); |
228 | 222 | ||
229 | return 0; | 223 | return 0; |
230 | bad4: | 224 | |
231 | ath_detach(sc); | 225 | err_init: |
232 | bad3: | 226 | free_irq(sc->irq, sc); |
227 | err_irq: | ||
233 | ieee80211_free_hw(hw); | 228 | ieee80211_free_hw(hw); |
234 | bad2: | 229 | err_alloc_hw: |
235 | pci_iounmap(pdev, mem); | 230 | pci_iounmap(pdev, mem); |
236 | bad1: | 231 | err_iomap: |
237 | pci_release_region(pdev, 0); | 232 | pci_release_region(pdev, 0); |
238 | bad: | 233 | err_region: |
234 | /* Nothing */ | ||
235 | err_dma: | ||
239 | pci_disable_device(pdev); | 236 | pci_disable_device(pdev); |
240 | return ret; | 237 | return ret; |
241 | } | 238 | } |
@@ -245,8 +242,12 @@ static void ath_pci_remove(struct pci_dev *pdev) | |||
245 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | 242 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); |
246 | struct ath_wiphy *aphy = hw->priv; | 243 | struct ath_wiphy *aphy = hw->priv; |
247 | struct ath_softc *sc = aphy->sc; | 244 | struct ath_softc *sc = aphy->sc; |
245 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
248 | 246 | ||
249 | ath_cleanup(sc); | 247 | ath9k_deinit_device(sc); |
248 | free_irq(sc->irq, sc); | ||
249 | ieee80211_free_hw(sc->hw); | ||
250 | ath_bus_cleanup(common); | ||
250 | } | 251 | } |
251 | 252 | ||
252 | #ifdef CONFIG_PM | 253 | #ifdef CONFIG_PM |
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c index cd26caaf44e7..a43fbf84dab9 100644 --- a/drivers/net/wireless/ath/ath9k/virtual.c +++ b/drivers/net/wireless/ath/ath9k/virtual.c | |||
@@ -152,7 +152,7 @@ int ath9k_wiphy_add(struct ath_softc *sc) | |||
152 | 152 | ||
153 | SET_IEEE80211_PERM_ADDR(hw, addr); | 153 | SET_IEEE80211_PERM_ADDR(hw, addr); |
154 | 154 | ||
155 | ath_set_hw_capab(sc, hw); | 155 | ath9k_set_hw_capab(sc, hw); |
156 | 156 | ||
157 | error = ieee80211_register_hw(hw); | 157 | error = ieee80211_register_hw(hw); |
158 | 158 | ||