diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/init.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/init.c | 345 |
1 files changed, 204 insertions, 141 deletions
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 243c1775f343..45c585a337e9 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2011 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
@@ -15,6 +15,7 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/ath9k_platform.h> | ||
18 | 19 | ||
19 | #include "ath9k.h" | 20 | #include "ath9k.h" |
20 | 21 | ||
@@ -29,17 +30,23 @@ static unsigned int ath9k_debug = ATH_DBG_DEFAULT; | |||
29 | module_param_named(debug, ath9k_debug, uint, 0); | 30 | module_param_named(debug, ath9k_debug, uint, 0); |
30 | MODULE_PARM_DESC(debug, "Debugging mask"); | 31 | MODULE_PARM_DESC(debug, "Debugging mask"); |
31 | 32 | ||
32 | int modparam_nohwcrypt; | 33 | int ath9k_modparam_nohwcrypt; |
33 | module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444); | 34 | module_param_named(nohwcrypt, ath9k_modparam_nohwcrypt, int, 0444); |
34 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption"); | 35 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption"); |
35 | 36 | ||
36 | int led_blink = 1; | 37 | int led_blink; |
37 | module_param_named(blink, led_blink, int, 0444); | 38 | module_param_named(blink, led_blink, int, 0444); |
38 | MODULE_PARM_DESC(blink, "Enable LED blink on activity"); | 39 | MODULE_PARM_DESC(blink, "Enable LED blink on activity"); |
39 | 40 | ||
41 | static int ath9k_btcoex_enable; | ||
42 | module_param_named(btcoex_enable, ath9k_btcoex_enable, int, 0444); | ||
43 | MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence"); | ||
44 | |||
45 | bool is_ath9k_unloaded; | ||
40 | /* We use the hw_value as an index into our private channel structure */ | 46 | /* We use the hw_value as an index into our private channel structure */ |
41 | 47 | ||
42 | #define CHAN2G(_freq, _idx) { \ | 48 | #define CHAN2G(_freq, _idx) { \ |
49 | .band = IEEE80211_BAND_2GHZ, \ | ||
43 | .center_freq = (_freq), \ | 50 | .center_freq = (_freq), \ |
44 | .hw_value = (_idx), \ | 51 | .hw_value = (_idx), \ |
45 | .max_power = 20, \ | 52 | .max_power = 20, \ |
@@ -56,7 +63,7 @@ MODULE_PARM_DESC(blink, "Enable LED blink on activity"); | |||
56 | * on 5 MHz steps, we support the channels which we know | 63 | * on 5 MHz steps, we support the channels which we know |
57 | * we have calibration data for all cards though to make | 64 | * we have calibration data for all cards though to make |
58 | * this static */ | 65 | * this static */ |
59 | static struct ieee80211_channel ath9k_2ghz_chantable[] = { | 66 | static const struct ieee80211_channel ath9k_2ghz_chantable[] = { |
60 | CHAN2G(2412, 0), /* Channel 1 */ | 67 | CHAN2G(2412, 0), /* Channel 1 */ |
61 | CHAN2G(2417, 1), /* Channel 2 */ | 68 | CHAN2G(2417, 1), /* Channel 2 */ |
62 | CHAN2G(2422, 2), /* Channel 3 */ | 69 | CHAN2G(2422, 2), /* Channel 3 */ |
@@ -77,7 +84,7 @@ static struct ieee80211_channel ath9k_2ghz_chantable[] = { | |||
77 | * on 5 MHz steps, we support the channels which we know | 84 | * on 5 MHz steps, we support the channels which we know |
78 | * we have calibration data for all cards though to make | 85 | * we have calibration data for all cards though to make |
79 | * this static */ | 86 | * this static */ |
80 | static struct ieee80211_channel ath9k_5ghz_chantable[] = { | 87 | static const struct ieee80211_channel ath9k_5ghz_chantable[] = { |
81 | /* _We_ call this UNII 1 */ | 88 | /* _We_ call this UNII 1 */ |
82 | CHAN5G(5180, 14), /* Channel 36 */ | 89 | CHAN5G(5180, 14), /* Channel 36 */ |
83 | CHAN5G(5200, 15), /* Channel 40 */ | 90 | CHAN5G(5200, 15), /* Channel 40 */ |
@@ -134,6 +141,21 @@ static struct ieee80211_rate ath9k_legacy_rates[] = { | |||
134 | RATE(540, 0x0c, 0), | 141 | RATE(540, 0x0c, 0), |
135 | }; | 142 | }; |
136 | 143 | ||
144 | #ifdef CONFIG_MAC80211_LEDS | ||
145 | static const struct ieee80211_tpt_blink ath9k_tpt_blink[] = { | ||
146 | { .throughput = 0 * 1024, .blink_time = 334 }, | ||
147 | { .throughput = 1 * 1024, .blink_time = 260 }, | ||
148 | { .throughput = 5 * 1024, .blink_time = 220 }, | ||
149 | { .throughput = 10 * 1024, .blink_time = 190 }, | ||
150 | { .throughput = 20 * 1024, .blink_time = 170 }, | ||
151 | { .throughput = 50 * 1024, .blink_time = 150 }, | ||
152 | { .throughput = 70 * 1024, .blink_time = 130 }, | ||
153 | { .throughput = 100 * 1024, .blink_time = 110 }, | ||
154 | { .throughput = 200 * 1024, .blink_time = 80 }, | ||
155 | { .throughput = 300 * 1024, .blink_time = 50 }, | ||
156 | }; | ||
157 | #endif | ||
158 | |||
137 | static void ath9k_deinit_softc(struct ath_softc *sc); | 159 | static void ath9k_deinit_softc(struct ath_softc *sc); |
138 | 160 | ||
139 | /* | 161 | /* |
@@ -174,10 +196,27 @@ static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset) | |||
174 | return val; | 196 | return val; |
175 | } | 197 | } |
176 | 198 | ||
177 | static const struct ath_ops ath9k_common_ops = { | 199 | static unsigned int ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr) |
178 | .read = ath9k_ioread32, | 200 | { |
179 | .write = ath9k_iowrite32, | 201 | struct ath_hw *ah = (struct ath_hw *) hw_priv; |
180 | }; | 202 | struct ath_common *common = ath9k_hw_common(ah); |
203 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
204 | unsigned long uninitialized_var(flags); | ||
205 | u32 val; | ||
206 | |||
207 | if (ah->config.serialize_regmode == SER_REG_MODE_ON) | ||
208 | spin_lock_irqsave(&sc->sc_serial_rw, flags); | ||
209 | |||
210 | val = ioread32(sc->mem + reg_offset); | ||
211 | val &= ~clr; | ||
212 | val |= set; | ||
213 | iowrite32(val, sc->mem + reg_offset); | ||
214 | |||
215 | if (ah->config.serialize_regmode == SER_REG_MODE_ON) | ||
216 | spin_unlock_irqrestore(&sc->sc_serial_rw, flags); | ||
217 | |||
218 | return val; | ||
219 | } | ||
181 | 220 | ||
182 | /**************************/ | 221 | /**************************/ |
183 | /* Initialization */ | 222 | /* Initialization */ |
@@ -206,12 +245,14 @@ static void setup_ht_cap(struct ath_softc *sc, | |||
206 | ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; | 245 | ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; |
207 | ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8; | 246 | ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8; |
208 | 247 | ||
209 | if (AR_SREV_9300_20_OR_LATER(ah)) | 248 | if (AR_SREV_9485(ah)) |
249 | max_streams = 1; | ||
250 | else if (AR_SREV_9300_20_OR_LATER(ah)) | ||
210 | max_streams = 3; | 251 | max_streams = 3; |
211 | else | 252 | else |
212 | max_streams = 2; | 253 | max_streams = 2; |
213 | 254 | ||
214 | if (AR_SREV_9280_10_OR_LATER(ah)) { | 255 | if (AR_SREV_9280_20_OR_LATER(ah)) { |
215 | if (max_streams >= 2) | 256 | if (max_streams >= 2) |
216 | ht_info->cap |= IEEE80211_HT_CAP_TX_STBC; | 257 | ht_info->cap |= IEEE80211_HT_CAP_TX_STBC; |
217 | ht_info->cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT); | 258 | ht_info->cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT); |
@@ -222,9 +263,9 @@ static void setup_ht_cap(struct ath_softc *sc, | |||
222 | tx_streams = ath9k_cmn_count_streams(common->tx_chainmask, max_streams); | 263 | tx_streams = ath9k_cmn_count_streams(common->tx_chainmask, max_streams); |
223 | rx_streams = ath9k_cmn_count_streams(common->rx_chainmask, max_streams); | 264 | rx_streams = ath9k_cmn_count_streams(common->rx_chainmask, max_streams); |
224 | 265 | ||
225 | ath_print(common, ATH_DBG_CONFIG, | 266 | ath_dbg(common, ATH_DBG_CONFIG, |
226 | "TX streams %d, RX streams: %d\n", | 267 | "TX streams %d, RX streams: %d\n", |
227 | tx_streams, rx_streams); | 268 | tx_streams, rx_streams); |
228 | 269 | ||
229 | if (tx_streams != rx_streams) { | 270 | if (tx_streams != rx_streams) { |
230 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; | 271 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; |
@@ -242,8 +283,7 @@ static int ath9k_reg_notifier(struct wiphy *wiphy, | |||
242 | struct regulatory_request *request) | 283 | struct regulatory_request *request) |
243 | { | 284 | { |
244 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); | 285 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); |
245 | struct ath_wiphy *aphy = hw->priv; | 286 | struct ath_softc *sc = hw->priv; |
246 | struct ath_softc *sc = aphy->sc; | ||
247 | struct ath_regulatory *reg = ath9k_hw_regulatory(sc->sc_ah); | 287 | struct ath_regulatory *reg = ath9k_hw_regulatory(sc->sc_ah); |
248 | 288 | ||
249 | return ath_reg_notifier_apply(wiphy, request, reg); | 289 | return ath_reg_notifier_apply(wiphy, request, reg); |
@@ -267,8 +307,8 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | |||
267 | struct ath_buf *bf; | 307 | struct ath_buf *bf; |
268 | int i, bsize, error, desc_len; | 308 | int i, bsize, error, desc_len; |
269 | 309 | ||
270 | ath_print(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n", | 310 | ath_dbg(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n", |
271 | name, nbuf, ndesc); | 311 | name, nbuf, ndesc); |
272 | 312 | ||
273 | INIT_LIST_HEAD(head); | 313 | INIT_LIST_HEAD(head); |
274 | 314 | ||
@@ -279,8 +319,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | |||
279 | 319 | ||
280 | /* ath_desc must be a multiple of DWORDs */ | 320 | /* ath_desc must be a multiple of DWORDs */ |
281 | if ((desc_len % 4) != 0) { | 321 | if ((desc_len % 4) != 0) { |
282 | ath_print(common, ATH_DBG_FATAL, | 322 | ath_err(common, "ath_desc not DWORD aligned\n"); |
283 | "ath_desc not DWORD aligned\n"); | ||
284 | BUG_ON((desc_len % 4) != 0); | 323 | BUG_ON((desc_len % 4) != 0); |
285 | error = -ENOMEM; | 324 | error = -ENOMEM; |
286 | goto fail; | 325 | goto fail; |
@@ -314,9 +353,9 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | |||
314 | goto fail; | 353 | goto fail; |
315 | } | 354 | } |
316 | ds = (u8 *) dd->dd_desc; | 355 | ds = (u8 *) dd->dd_desc; |
317 | ath_print(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n", | 356 | ath_dbg(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n", |
318 | name, ds, (u32) dd->dd_desc_len, | 357 | name, ds, (u32) dd->dd_desc_len, |
319 | ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len); | 358 | ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len); |
320 | 359 | ||
321 | /* allocate buffers */ | 360 | /* allocate buffers */ |
322 | bsize = sizeof(struct ath_buf) * nbuf; | 361 | bsize = sizeof(struct ath_buf) * nbuf; |
@@ -362,26 +401,20 @@ fail: | |||
362 | #undef DS2PHYS | 401 | #undef DS2PHYS |
363 | } | 402 | } |
364 | 403 | ||
365 | static void ath9k_init_crypto(struct ath_softc *sc) | 404 | void ath9k_init_crypto(struct ath_softc *sc) |
366 | { | 405 | { |
367 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 406 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
368 | int i = 0; | 407 | int i = 0; |
369 | 408 | ||
370 | /* Get the hardware key cache size. */ | 409 | /* Get the hardware key cache size. */ |
371 | common->keymax = sc->sc_ah->caps.keycache_size; | 410 | common->keymax = AR_KEYTABLE_SIZE; |
372 | if (common->keymax > ATH_KEYMAX) { | ||
373 | ath_print(common, ATH_DBG_ANY, | ||
374 | "Warning, using only %u entries in %u key cache\n", | ||
375 | ATH_KEYMAX, common->keymax); | ||
376 | common->keymax = ATH_KEYMAX; | ||
377 | } | ||
378 | 411 | ||
379 | /* | 412 | /* |
380 | * Reset the key cache since some parts do not | 413 | * Reset the key cache since some parts do not |
381 | * reset the contents on initial power up. | 414 | * reset the contents on initial power up. |
382 | */ | 415 | */ |
383 | for (i = 0; i < common->keymax; i++) | 416 | for (i = 0; i < common->keymax; i++) |
384 | ath9k_hw_keyreset(sc->sc_ah, (u16) i); | 417 | ath_hw_keyreset(common, (u16) i); |
385 | 418 | ||
386 | /* | 419 | /* |
387 | * Check whether the separate key cache entries | 420 | * Check whether the separate key cache entries |
@@ -389,13 +422,14 @@ static void ath9k_init_crypto(struct ath_softc *sc) | |||
389 | * With split mic keys the number of stations is limited | 422 | * With split mic keys the number of stations is limited |
390 | * to 27 otherwise 59. | 423 | * to 27 otherwise 59. |
391 | */ | 424 | */ |
392 | if (!(sc->sc_ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA)) | 425 | if (sc->sc_ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) |
393 | common->splitmic = 1; | 426 | common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED; |
394 | } | 427 | } |
395 | 428 | ||
396 | static int ath9k_init_btcoex(struct ath_softc *sc) | 429 | static int ath9k_init_btcoex(struct ath_softc *sc) |
397 | { | 430 | { |
398 | int r, qnum; | 431 | struct ath_txq *txq; |
432 | int r; | ||
399 | 433 | ||
400 | switch (sc->sc_ah->btcoex_hw.scheme) { | 434 | switch (sc->sc_ah->btcoex_hw.scheme) { |
401 | case ATH_BTCOEX_CFG_NONE: | 435 | case ATH_BTCOEX_CFG_NONE: |
@@ -408,8 +442,8 @@ static int ath9k_init_btcoex(struct ath_softc *sc) | |||
408 | r = ath_init_btcoex_timer(sc); | 442 | r = ath_init_btcoex_timer(sc); |
409 | if (r) | 443 | if (r) |
410 | return -1; | 444 | return -1; |
411 | qnum = sc->tx.hwq_map[WME_AC_BE]; | 445 | txq = sc->tx.txq_map[WME_AC_BE]; |
412 | ath9k_hw_init_btcoex_hw(sc->sc_ah, qnum); | 446 | ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum); |
413 | sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; | 447 | sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; |
414 | break; | 448 | break; |
415 | default: | 449 | default: |
@@ -422,65 +456,36 @@ static int ath9k_init_btcoex(struct ath_softc *sc) | |||
422 | 456 | ||
423 | static int ath9k_init_queues(struct ath_softc *sc) | 457 | static int ath9k_init_queues(struct ath_softc *sc) |
424 | { | 458 | { |
425 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
426 | int i = 0; | 459 | int i = 0; |
427 | 460 | ||
428 | for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++) | ||
429 | sc->tx.hwq_map[i] = -1; | ||
430 | |||
431 | sc->beacon.beaconq = ath9k_hw_beaconq_setup(sc->sc_ah); | 461 | sc->beacon.beaconq = ath9k_hw_beaconq_setup(sc->sc_ah); |
432 | if (sc->beacon.beaconq == -1) { | ||
433 | ath_print(common, ATH_DBG_FATAL, | ||
434 | "Unable to setup a beacon xmit queue\n"); | ||
435 | goto err; | ||
436 | } | ||
437 | |||
438 | sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0); | 462 | sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0); |
439 | if (sc->beacon.cabq == NULL) { | ||
440 | ath_print(common, ATH_DBG_FATAL, | ||
441 | "Unable to setup CAB xmit queue\n"); | ||
442 | goto err; | ||
443 | } | ||
444 | 463 | ||
445 | sc->config.cabqReadytime = ATH_CABQ_READY_TIME; | 464 | sc->config.cabqReadytime = ATH_CABQ_READY_TIME; |
446 | ath_cabq_update(sc); | 465 | ath_cabq_update(sc); |
447 | 466 | ||
448 | if (!ath_tx_setup(sc, WME_AC_BK)) { | 467 | for (i = 0; i < WME_NUM_AC; i++) { |
449 | ath_print(common, ATH_DBG_FATAL, | 468 | sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i); |
450 | "Unable to setup xmit queue for BK traffic\n"); | 469 | sc->tx.txq_map[i]->mac80211_qnum = i; |
451 | goto err; | ||
452 | } | ||
453 | |||
454 | if (!ath_tx_setup(sc, WME_AC_BE)) { | ||
455 | ath_print(common, ATH_DBG_FATAL, | ||
456 | "Unable to setup xmit queue for BE traffic\n"); | ||
457 | goto err; | ||
458 | } | ||
459 | if (!ath_tx_setup(sc, WME_AC_VI)) { | ||
460 | ath_print(common, ATH_DBG_FATAL, | ||
461 | "Unable to setup xmit queue for VI traffic\n"); | ||
462 | goto err; | ||
463 | } | ||
464 | if (!ath_tx_setup(sc, WME_AC_VO)) { | ||
465 | ath_print(common, ATH_DBG_FATAL, | ||
466 | "Unable to setup xmit queue for VO traffic\n"); | ||
467 | goto err; | ||
468 | } | 470 | } |
469 | |||
470 | return 0; | 471 | return 0; |
471 | |||
472 | err: | ||
473 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | ||
474 | if (ATH_TXQ_SETUP(sc, i)) | ||
475 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); | ||
476 | |||
477 | return -EIO; | ||
478 | } | 472 | } |
479 | 473 | ||
480 | static void ath9k_init_channels_rates(struct ath_softc *sc) | 474 | static int ath9k_init_channels_rates(struct ath_softc *sc) |
481 | { | 475 | { |
482 | if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) { | 476 | void *channels; |
483 | sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable; | 477 | |
478 | BUILD_BUG_ON(ARRAY_SIZE(ath9k_2ghz_chantable) + | ||
479 | ARRAY_SIZE(ath9k_5ghz_chantable) != | ||
480 | ATH9K_NUM_CHANNELS); | ||
481 | |||
482 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) { | ||
483 | channels = kmemdup(ath9k_2ghz_chantable, | ||
484 | sizeof(ath9k_2ghz_chantable), GFP_KERNEL); | ||
485 | if (!channels) | ||
486 | return -ENOMEM; | ||
487 | |||
488 | sc->sbands[IEEE80211_BAND_2GHZ].channels = channels; | ||
484 | sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; | 489 | sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; |
485 | sc->sbands[IEEE80211_BAND_2GHZ].n_channels = | 490 | sc->sbands[IEEE80211_BAND_2GHZ].n_channels = |
486 | ARRAY_SIZE(ath9k_2ghz_chantable); | 491 | ARRAY_SIZE(ath9k_2ghz_chantable); |
@@ -489,8 +494,16 @@ static void ath9k_init_channels_rates(struct ath_softc *sc) | |||
489 | ARRAY_SIZE(ath9k_legacy_rates); | 494 | ARRAY_SIZE(ath9k_legacy_rates); |
490 | } | 495 | } |
491 | 496 | ||
492 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) { | 497 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) { |
493 | sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable; | 498 | channels = kmemdup(ath9k_5ghz_chantable, |
499 | sizeof(ath9k_5ghz_chantable), GFP_KERNEL); | ||
500 | if (!channels) { | ||
501 | if (sc->sbands[IEEE80211_BAND_2GHZ].channels) | ||
502 | kfree(sc->sbands[IEEE80211_BAND_2GHZ].channels); | ||
503 | return -ENOMEM; | ||
504 | } | ||
505 | |||
506 | sc->sbands[IEEE80211_BAND_5GHZ].channels = channels; | ||
494 | sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; | 507 | sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; |
495 | sc->sbands[IEEE80211_BAND_5GHZ].n_channels = | 508 | sc->sbands[IEEE80211_BAND_5GHZ].n_channels = |
496 | ARRAY_SIZE(ath9k_5ghz_chantable); | 509 | ARRAY_SIZE(ath9k_5ghz_chantable); |
@@ -499,6 +512,7 @@ static void ath9k_init_channels_rates(struct ath_softc *sc) | |||
499 | sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates = | 512 | sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates = |
500 | ARRAY_SIZE(ath9k_legacy_rates) - 4; | 513 | ARRAY_SIZE(ath9k_legacy_rates) - 4; |
501 | } | 514 | } |
515 | return 0; | ||
502 | } | 516 | } |
503 | 517 | ||
504 | static void ath9k_init_misc(struct ath_softc *sc) | 518 | static void ath9k_init_misc(struct ath_softc *sc) |
@@ -506,7 +520,6 @@ static void ath9k_init_misc(struct ath_softc *sc) | |||
506 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 520 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
507 | int i = 0; | 521 | int i = 0; |
508 | 522 | ||
509 | common->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR; | ||
510 | setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); | 523 | setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); |
511 | 524 | ||
512 | sc->config.txpowlimit = ATH_TXPOWER_MAX; | 525 | sc->config.txpowlimit = ATH_TXPOWER_MAX; |
@@ -522,20 +535,21 @@ static void ath9k_init_misc(struct ath_softc *sc) | |||
522 | ath9k_hw_set_diversity(sc->sc_ah, true); | 535 | ath9k_hw_set_diversity(sc->sc_ah, true); |
523 | sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah); | 536 | sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah); |
524 | 537 | ||
525 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) | 538 | memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); |
526 | memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); | ||
527 | 539 | ||
528 | sc->beacon.slottime = ATH9K_SLOT_TIME_9; | 540 | sc->beacon.slottime = ATH9K_SLOT_TIME_9; |
529 | 541 | ||
530 | for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) { | 542 | for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) |
531 | sc->beacon.bslot[i] = NULL; | 543 | sc->beacon.bslot[i] = NULL; |
532 | sc->beacon.bslot_aphy[i] = NULL; | 544 | |
533 | } | 545 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) |
546 | sc->ant_comb.count = ATH_ANT_DIV_COMB_INIT_COUNT; | ||
534 | } | 547 | } |
535 | 548 | ||
536 | static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, | 549 | static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, |
537 | const struct ath_bus_ops *bus_ops) | 550 | const struct ath_bus_ops *bus_ops) |
538 | { | 551 | { |
552 | struct ath9k_platform_data *pdata = sc->dev->platform_data; | ||
539 | struct ath_hw *ah = NULL; | 553 | struct ath_hw *ah = NULL; |
540 | struct ath_common *common; | 554 | struct ath_common *common; |
541 | int ret = 0, i; | 555 | int ret = 0, i; |
@@ -545,23 +559,41 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, | |||
545 | if (!ah) | 559 | if (!ah) |
546 | return -ENOMEM; | 560 | return -ENOMEM; |
547 | 561 | ||
562 | ah->hw = sc->hw; | ||
548 | ah->hw_version.devid = devid; | 563 | ah->hw_version.devid = devid; |
549 | ah->hw_version.subsysid = subsysid; | 564 | ah->hw_version.subsysid = subsysid; |
565 | ah->reg_ops.read = ath9k_ioread32; | ||
566 | ah->reg_ops.write = ath9k_iowrite32; | ||
567 | ah->reg_ops.rmw = ath9k_reg_rmw; | ||
550 | sc->sc_ah = ah; | 568 | sc->sc_ah = ah; |
551 | 569 | ||
570 | if (!pdata) { | ||
571 | ah->ah_flags |= AH_USE_EEPROM; | ||
572 | sc->sc_ah->led_pin = -1; | ||
573 | } else { | ||
574 | sc->sc_ah->gpio_mask = pdata->gpio_mask; | ||
575 | sc->sc_ah->gpio_val = pdata->gpio_val; | ||
576 | sc->sc_ah->led_pin = pdata->led_pin; | ||
577 | ah->is_clk_25mhz = pdata->is_clk_25mhz; | ||
578 | } | ||
579 | |||
552 | common = ath9k_hw_common(ah); | 580 | common = ath9k_hw_common(ah); |
553 | common->ops = &ath9k_common_ops; | 581 | common->ops = &ah->reg_ops; |
554 | common->bus_ops = bus_ops; | 582 | common->bus_ops = bus_ops; |
555 | common->ah = ah; | 583 | common->ah = ah; |
556 | common->hw = sc->hw; | 584 | common->hw = sc->hw; |
557 | common->priv = sc; | 585 | common->priv = sc; |
558 | common->debug_mask = ath9k_debug; | 586 | common->debug_mask = ath9k_debug; |
587 | common->btcoex_enabled = ath9k_btcoex_enable == 1; | ||
588 | spin_lock_init(&common->cc_lock); | ||
559 | 589 | ||
560 | spin_lock_init(&sc->wiphy_lock); | ||
561 | spin_lock_init(&sc->sc_resetlock); | ||
562 | spin_lock_init(&sc->sc_serial_rw); | 590 | spin_lock_init(&sc->sc_serial_rw); |
563 | spin_lock_init(&sc->sc_pm_lock); | 591 | spin_lock_init(&sc->sc_pm_lock); |
564 | mutex_init(&sc->mutex); | 592 | mutex_init(&sc->mutex); |
593 | #ifdef CONFIG_ATH9K_DEBUGFS | ||
594 | spin_lock_init(&sc->nodes_lock); | ||
595 | INIT_LIST_HEAD(&sc->nodes); | ||
596 | #endif | ||
565 | tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); | 597 | tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); |
566 | tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet, | 598 | tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet, |
567 | (unsigned long)sc); | 599 | (unsigned long)sc); |
@@ -578,12 +610,8 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, | |||
578 | if (ret) | 610 | if (ret) |
579 | goto err_hw; | 611 | goto err_hw; |
580 | 612 | ||
581 | ret = ath9k_init_debug(ah); | 613 | if (pdata && pdata->macaddr) |
582 | if (ret) { | 614 | memcpy(common->macaddr, pdata->macaddr, ETH_ALEN); |
583 | ath_print(common, ATH_DBG_FATAL, | ||
584 | "Unable to create debugfs files\n"); | ||
585 | goto err_debug; | ||
586 | } | ||
587 | 615 | ||
588 | ret = ath9k_init_queues(sc); | 616 | ret = ath9k_init_queues(sc); |
589 | if (ret) | 617 | if (ret) |
@@ -593,8 +621,11 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, | |||
593 | if (ret) | 621 | if (ret) |
594 | goto err_btcoex; | 622 | goto err_btcoex; |
595 | 623 | ||
624 | ret = ath9k_init_channels_rates(sc); | ||
625 | if (ret) | ||
626 | goto err_btcoex; | ||
627 | |||
596 | ath9k_init_crypto(sc); | 628 | ath9k_init_crypto(sc); |
597 | ath9k_init_channels_rates(sc); | ||
598 | ath9k_init_misc(sc); | 629 | ath9k_init_misc(sc); |
599 | 630 | ||
600 | return 0; | 631 | return 0; |
@@ -604,12 +635,8 @@ err_btcoex: | |||
604 | if (ATH_TXQ_SETUP(sc, i)) | 635 | if (ATH_TXQ_SETUP(sc, i)) |
605 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); | 636 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); |
606 | err_queues: | 637 | err_queues: |
607 | ath9k_exit_debug(ah); | ||
608 | err_debug: | ||
609 | ath9k_hw_deinit(ah); | 638 | ath9k_hw_deinit(ah); |
610 | err_hw: | 639 | err_hw: |
611 | tasklet_kill(&sc->intr_tq); | ||
612 | tasklet_kill(&sc->bcon_tasklet); | ||
613 | 640 | ||
614 | kfree(ah); | 641 | kfree(ah); |
615 | sc->sc_ah = NULL; | 642 | sc->sc_ah = NULL; |
@@ -617,6 +644,37 @@ err_hw: | |||
617 | return ret; | 644 | return ret; |
618 | } | 645 | } |
619 | 646 | ||
647 | static void ath9k_init_band_txpower(struct ath_softc *sc, int band) | ||
648 | { | ||
649 | struct ieee80211_supported_band *sband; | ||
650 | struct ieee80211_channel *chan; | ||
651 | struct ath_hw *ah = sc->sc_ah; | ||
652 | struct ath_regulatory *reg = ath9k_hw_regulatory(ah); | ||
653 | int i; | ||
654 | |||
655 | sband = &sc->sbands[band]; | ||
656 | for (i = 0; i < sband->n_channels; i++) { | ||
657 | chan = &sband->channels[i]; | ||
658 | ah->curchan = &ah->channels[chan->hw_value]; | ||
659 | ath9k_cmn_update_ichannel(ah->curchan, chan, NL80211_CHAN_HT20); | ||
660 | ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, true); | ||
661 | chan->max_power = reg->max_power_level / 2; | ||
662 | } | ||
663 | } | ||
664 | |||
665 | static void ath9k_init_txpower_limits(struct ath_softc *sc) | ||
666 | { | ||
667 | struct ath_hw *ah = sc->sc_ah; | ||
668 | struct ath9k_channel *curchan = ah->curchan; | ||
669 | |||
670 | if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) | ||
671 | ath9k_init_band_txpower(sc, IEEE80211_BAND_2GHZ); | ||
672 | if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) | ||
673 | ath9k_init_band_txpower(sc, IEEE80211_BAND_5GHZ); | ||
674 | |||
675 | ah->curchan = curchan; | ||
676 | } | ||
677 | |||
620 | void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | 678 | void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) |
621 | { | 679 | { |
622 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 680 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
@@ -632,16 +690,22 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
632 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) | 690 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) |
633 | hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; | 691 | hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; |
634 | 692 | ||
635 | if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || modparam_nohwcrypt) | 693 | if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || ath9k_modparam_nohwcrypt) |
636 | hw->flags |= IEEE80211_HW_MFP_CAPABLE; | 694 | hw->flags |= IEEE80211_HW_MFP_CAPABLE; |
637 | 695 | ||
638 | hw->wiphy->interface_modes = | 696 | hw->wiphy->interface_modes = |
697 | BIT(NL80211_IFTYPE_P2P_GO) | | ||
698 | BIT(NL80211_IFTYPE_P2P_CLIENT) | | ||
639 | BIT(NL80211_IFTYPE_AP) | | 699 | BIT(NL80211_IFTYPE_AP) | |
700 | BIT(NL80211_IFTYPE_WDS) | | ||
640 | BIT(NL80211_IFTYPE_STATION) | | 701 | BIT(NL80211_IFTYPE_STATION) | |
641 | BIT(NL80211_IFTYPE_ADHOC) | | 702 | BIT(NL80211_IFTYPE_ADHOC) | |
642 | BIT(NL80211_IFTYPE_MESH_POINT); | 703 | BIT(NL80211_IFTYPE_MESH_POINT); |
643 | 704 | ||
644 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | 705 | if (AR_SREV_5416(sc->sc_ah)) |
706 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
707 | |||
708 | hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; | ||
645 | 709 | ||
646 | hw->queues = 4; | 710 | hw->queues = 4; |
647 | hw->max_rates = 4; | 711 | hw->max_rates = 4; |
@@ -651,19 +715,21 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
651 | hw->sta_data_size = sizeof(struct ath_node); | 715 | hw->sta_data_size = sizeof(struct ath_node); |
652 | hw->vif_data_size = sizeof(struct ath_vif); | 716 | hw->vif_data_size = sizeof(struct ath_vif); |
653 | 717 | ||
718 | #ifdef CONFIG_ATH9K_RATE_CONTROL | ||
654 | hw->rate_control_algorithm = "ath9k_rate_control"; | 719 | hw->rate_control_algorithm = "ath9k_rate_control"; |
720 | #endif | ||
655 | 721 | ||
656 | if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) | 722 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) |
657 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = | 723 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = |
658 | &sc->sbands[IEEE80211_BAND_2GHZ]; | 724 | &sc->sbands[IEEE80211_BAND_2GHZ]; |
659 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) | 725 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) |
660 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | 726 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = |
661 | &sc->sbands[IEEE80211_BAND_5GHZ]; | 727 | &sc->sbands[IEEE80211_BAND_5GHZ]; |
662 | 728 | ||
663 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { | 729 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { |
664 | if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) | 730 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) |
665 | setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); | 731 | setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); |
666 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) | 732 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) |
667 | setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); | 733 | setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); |
668 | } | 734 | } |
669 | 735 | ||
@@ -706,11 +772,26 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, | |||
706 | if (error != 0) | 772 | if (error != 0) |
707 | goto error_rx; | 773 | goto error_rx; |
708 | 774 | ||
775 | ath9k_init_txpower_limits(sc); | ||
776 | |||
777 | #ifdef CONFIG_MAC80211_LEDS | ||
778 | /* must be initialized before ieee80211_register_hw */ | ||
779 | sc->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(sc->hw, | ||
780 | IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_tpt_blink, | ||
781 | ARRAY_SIZE(ath9k_tpt_blink)); | ||
782 | #endif | ||
783 | |||
709 | /* Register with mac80211 */ | 784 | /* Register with mac80211 */ |
710 | error = ieee80211_register_hw(hw); | 785 | error = ieee80211_register_hw(hw); |
711 | if (error) | 786 | if (error) |
712 | goto error_register; | 787 | goto error_register; |
713 | 788 | ||
789 | error = ath9k_init_debug(ah); | ||
790 | if (error) { | ||
791 | ath_err(common, "Unable to create debugfs files\n"); | ||
792 | goto error_world; | ||
793 | } | ||
794 | |||
714 | /* Handle world regulatory */ | 795 | /* Handle world regulatory */ |
715 | if (!ath_is_world_regd(reg)) { | 796 | if (!ath_is_world_regd(reg)) { |
716 | error = regulatory_hint(hw->wiphy, reg->alpha2); | 797 | error = regulatory_hint(hw->wiphy, reg->alpha2); |
@@ -720,9 +801,8 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, | |||
720 | 801 | ||
721 | INIT_WORK(&sc->hw_check_work, ath_hw_check); | 802 | INIT_WORK(&sc->hw_check_work, ath_hw_check); |
722 | INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); | 803 | INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); |
723 | INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work); | 804 | INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); |
724 | INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work); | 805 | sc->last_rssi = ATH_RSSI_DUMMY_MARKER; |
725 | sc->wiphy_scheduler_int = msecs_to_jiffies(500); | ||
726 | 806 | ||
727 | ath_init_leds(sc); | 807 | ath_init_leds(sc); |
728 | ath_start_rfkill_poll(sc); | 808 | ath_start_rfkill_poll(sc); |
@@ -751,6 +831,12 @@ static void ath9k_deinit_softc(struct ath_softc *sc) | |||
751 | { | 831 | { |
752 | int i = 0; | 832 | int i = 0; |
753 | 833 | ||
834 | if (sc->sbands[IEEE80211_BAND_2GHZ].channels) | ||
835 | kfree(sc->sbands[IEEE80211_BAND_2GHZ].channels); | ||
836 | |||
837 | if (sc->sbands[IEEE80211_BAND_5GHZ].channels) | ||
838 | kfree(sc->sbands[IEEE80211_BAND_5GHZ].channels); | ||
839 | |||
754 | if ((sc->btcoex.no_stomp_timer) && | 840 | if ((sc->btcoex.no_stomp_timer) && |
755 | sc->sc_ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) | 841 | sc->sc_ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) |
756 | ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer); | 842 | ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer); |
@@ -759,12 +845,8 @@ static void ath9k_deinit_softc(struct ath_softc *sc) | |||
759 | if (ATH_TXQ_SETUP(sc, i)) | 845 | if (ATH_TXQ_SETUP(sc, i)) |
760 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); | 846 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); |
761 | 847 | ||
762 | ath9k_exit_debug(sc->sc_ah); | ||
763 | ath9k_hw_deinit(sc->sc_ah); | 848 | ath9k_hw_deinit(sc->sc_ah); |
764 | 849 | ||
765 | tasklet_kill(&sc->intr_tq); | ||
766 | tasklet_kill(&sc->bcon_tasklet); | ||
767 | |||
768 | kfree(sc->sc_ah); | 850 | kfree(sc->sc_ah); |
769 | sc->sc_ah = NULL; | 851 | sc->sc_ah = NULL; |
770 | } | 852 | } |
@@ -772,27 +854,18 @@ static void ath9k_deinit_softc(struct ath_softc *sc) | |||
772 | void ath9k_deinit_device(struct ath_softc *sc) | 854 | void ath9k_deinit_device(struct ath_softc *sc) |
773 | { | 855 | { |
774 | struct ieee80211_hw *hw = sc->hw; | 856 | struct ieee80211_hw *hw = sc->hw; |
775 | int i = 0; | ||
776 | 857 | ||
777 | ath9k_ps_wakeup(sc); | 858 | ath9k_ps_wakeup(sc); |
778 | 859 | ||
779 | wiphy_rfkill_stop_polling(sc->hw->wiphy); | 860 | wiphy_rfkill_stop_polling(sc->hw->wiphy); |
780 | ath_deinit_leds(sc); | 861 | ath_deinit_leds(sc); |
781 | 862 | ||
782 | for (i = 0; i < sc->num_sec_wiphy; i++) { | 863 | ath9k_ps_restore(sc); |
783 | struct ath_wiphy *aphy = sc->sec_wiphy[i]; | ||
784 | if (aphy == NULL) | ||
785 | continue; | ||
786 | sc->sec_wiphy[i] = NULL; | ||
787 | ieee80211_unregister_hw(aphy->hw); | ||
788 | ieee80211_free_hw(aphy->hw); | ||
789 | } | ||
790 | 864 | ||
791 | ieee80211_unregister_hw(hw); | 865 | ieee80211_unregister_hw(hw); |
792 | ath_rx_cleanup(sc); | 866 | ath_rx_cleanup(sc); |
793 | ath_tx_cleanup(sc); | 867 | ath_tx_cleanup(sc); |
794 | ath9k_deinit_softc(sc); | 868 | ath9k_deinit_softc(sc); |
795 | kfree(sc->sec_wiphy); | ||
796 | } | 869 | } |
797 | 870 | ||
798 | void ath_descdma_cleanup(struct ath_softc *sc, | 871 | void ath_descdma_cleanup(struct ath_softc *sc, |
@@ -825,20 +898,12 @@ static int __init ath9k_init(void) | |||
825 | goto err_out; | 898 | goto err_out; |
826 | } | 899 | } |
827 | 900 | ||
828 | error = ath9k_debug_create_root(); | ||
829 | if (error) { | ||
830 | printk(KERN_ERR | ||
831 | "ath9k: Unable to create debugfs root: %d\n", | ||
832 | error); | ||
833 | goto err_rate_unregister; | ||
834 | } | ||
835 | |||
836 | error = ath_pci_init(); | 901 | error = ath_pci_init(); |
837 | if (error < 0) { | 902 | if (error < 0) { |
838 | printk(KERN_ERR | 903 | printk(KERN_ERR |
839 | "ath9k: No PCI devices found, driver not installed.\n"); | 904 | "ath9k: No PCI devices found, driver not installed.\n"); |
840 | error = -ENODEV; | 905 | error = -ENODEV; |
841 | goto err_remove_root; | 906 | goto err_rate_unregister; |
842 | } | 907 | } |
843 | 908 | ||
844 | error = ath_ahb_init(); | 909 | error = ath_ahb_init(); |
@@ -852,8 +917,6 @@ static int __init ath9k_init(void) | |||
852 | err_pci_exit: | 917 | err_pci_exit: |
853 | ath_pci_exit(); | 918 | ath_pci_exit(); |
854 | 919 | ||
855 | err_remove_root: | ||
856 | ath9k_debug_remove_root(); | ||
857 | err_rate_unregister: | 920 | err_rate_unregister: |
858 | ath_rate_control_unregister(); | 921 | ath_rate_control_unregister(); |
859 | err_out: | 922 | err_out: |
@@ -863,9 +926,9 @@ module_init(ath9k_init); | |||
863 | 926 | ||
864 | static void __exit ath9k_exit(void) | 927 | static void __exit ath9k_exit(void) |
865 | { | 928 | { |
929 | is_ath9k_unloaded = true; | ||
866 | ath_ahb_exit(); | 930 | ath_ahb_exit(); |
867 | ath_pci_exit(); | 931 | ath_pci_exit(); |
868 | ath9k_debug_remove_root(); | ||
869 | ath_rate_control_unregister(); | 932 | ath_rate_control_unregister(); |
870 | printk(KERN_INFO "%s: Driver unloaded\n", dev_info); | 933 | printk(KERN_INFO "%s: Driver unloaded\n", dev_info); |
871 | } | 934 | } |