diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/main.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 1247 |
1 files changed, 785 insertions, 462 deletions
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 43d2be9867fc..cbf5d2a1bb26 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -16,6 +16,7 @@ | |||
16 | 16 | ||
17 | #include <linux/nl80211.h> | 17 | #include <linux/nl80211.h> |
18 | #include "ath9k.h" | 18 | #include "ath9k.h" |
19 | #include "btcoex.h" | ||
19 | 20 | ||
20 | static char *dev_info = "ath9k"; | 21 | static char *dev_info = "ath9k"; |
21 | 22 | ||
@@ -28,6 +29,10 @@ static int modparam_nohwcrypt; | |||
28 | module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444); | 29 | module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444); |
29 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption"); | 30 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption"); |
30 | 31 | ||
32 | static unsigned int ath9k_debug = ATH_DBG_DEFAULT; | ||
33 | module_param_named(debug, ath9k_debug, uint, 0); | ||
34 | MODULE_PARM_DESC(debug, "Debugging mask"); | ||
35 | |||
31 | /* We use the hw_value as an index into our private channel structure */ | 36 | /* We use the hw_value as an index into our private channel structure */ |
32 | 37 | ||
33 | #define CHAN2G(_freq, _idx) { \ | 38 | #define CHAN2G(_freq, _idx) { \ |
@@ -224,8 +229,9 @@ static void ath_setup_rates(struct ath_softc *sc, enum ieee80211_band band) | |||
224 | } | 229 | } |
225 | sband->n_bitrates++; | 230 | sband->n_bitrates++; |
226 | 231 | ||
227 | DPRINTF(sc, ATH_DBG_CONFIG, "Rate: %2dMbps, ratecode: %2d\n", | 232 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG, |
228 | rate[i].bitrate / 10, rate[i].hw_value); | 233 | "Rate: %2dMbps, ratecode: %2d\n", |
234 | rate[i].bitrate / 10, rate[i].hw_value); | ||
229 | } | 235 | } |
230 | } | 236 | } |
231 | 237 | ||
@@ -242,6 +248,51 @@ static struct ath9k_channel *ath_get_curchannel(struct ath_softc *sc, | |||
242 | return channel; | 248 | return channel; |
243 | } | 249 | } |
244 | 250 | ||
251 | static bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode) | ||
252 | { | ||
253 | unsigned long flags; | ||
254 | bool ret; | ||
255 | |||
256 | spin_lock_irqsave(&sc->sc_pm_lock, flags); | ||
257 | ret = ath9k_hw_setpower(sc->sc_ah, mode); | ||
258 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | ||
259 | |||
260 | return ret; | ||
261 | } | ||
262 | |||
263 | void ath9k_ps_wakeup(struct ath_softc *sc) | ||
264 | { | ||
265 | unsigned long flags; | ||
266 | |||
267 | spin_lock_irqsave(&sc->sc_pm_lock, flags); | ||
268 | if (++sc->ps_usecount != 1) | ||
269 | goto unlock; | ||
270 | |||
271 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); | ||
272 | |||
273 | unlock: | ||
274 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | ||
275 | } | ||
276 | |||
277 | void ath9k_ps_restore(struct ath_softc *sc) | ||
278 | { | ||
279 | unsigned long flags; | ||
280 | |||
281 | spin_lock_irqsave(&sc->sc_pm_lock, flags); | ||
282 | if (--sc->ps_usecount != 0) | ||
283 | goto unlock; | ||
284 | |||
285 | if (sc->ps_enabled && | ||
286 | !(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON | | ||
287 | SC_OP_WAIT_FOR_CAB | | ||
288 | SC_OP_WAIT_FOR_PSPOLL_DATA | | ||
289 | SC_OP_WAIT_FOR_TX_ACK))) | ||
290 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP); | ||
291 | |||
292 | unlock: | ||
293 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | ||
294 | } | ||
295 | |||
245 | /* | 296 | /* |
246 | * Set/change channels. If the channel is really being changed, it's done | 297 | * Set/change channels. If the channel is really being changed, it's done |
247 | * by reseting the chip. To accomplish this we must first cleanup any pending | 298 | * by reseting the chip. To accomplish this we must first cleanup any pending |
@@ -251,6 +302,8 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
251 | struct ath9k_channel *hchan) | 302 | struct ath9k_channel *hchan) |
252 | { | 303 | { |
253 | struct ath_hw *ah = sc->sc_ah; | 304 | struct ath_hw *ah = sc->sc_ah; |
305 | struct ath_common *common = ath9k_hw_common(ah); | ||
306 | struct ieee80211_conf *conf = &common->hw->conf; | ||
254 | bool fastcc = true, stopped; | 307 | bool fastcc = true, stopped; |
255 | struct ieee80211_channel *channel = hw->conf.channel; | 308 | struct ieee80211_channel *channel = hw->conf.channel; |
256 | int r; | 309 | int r; |
@@ -280,19 +333,19 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
280 | if (!stopped || (sc->sc_flags & SC_OP_FULL_RESET)) | 333 | if (!stopped || (sc->sc_flags & SC_OP_FULL_RESET)) |
281 | fastcc = false; | 334 | fastcc = false; |
282 | 335 | ||
283 | DPRINTF(sc, ATH_DBG_CONFIG, | 336 | ath_print(common, ATH_DBG_CONFIG, |
284 | "(%u MHz) -> (%u MHz), chanwidth: %d\n", | 337 | "(%u MHz) -> (%u MHz), conf_is_ht40: %d\n", |
285 | sc->sc_ah->curchan->channel, | 338 | sc->sc_ah->curchan->channel, |
286 | channel->center_freq, sc->tx_chan_width); | 339 | channel->center_freq, conf_is_ht40(conf)); |
287 | 340 | ||
288 | spin_lock_bh(&sc->sc_resetlock); | 341 | spin_lock_bh(&sc->sc_resetlock); |
289 | 342 | ||
290 | r = ath9k_hw_reset(ah, hchan, fastcc); | 343 | r = ath9k_hw_reset(ah, hchan, fastcc); |
291 | if (r) { | 344 | if (r) { |
292 | DPRINTF(sc, ATH_DBG_FATAL, | 345 | ath_print(common, ATH_DBG_FATAL, |
293 | "Unable to reset channel (%u Mhz) " | 346 | "Unable to reset channel (%u Mhz) " |
294 | "reset status %d\n", | 347 | "reset status %d\n", |
295 | channel->center_freq, r); | 348 | channel->center_freq, r); |
296 | spin_unlock_bh(&sc->sc_resetlock); | 349 | spin_unlock_bh(&sc->sc_resetlock); |
297 | goto ps_restore; | 350 | goto ps_restore; |
298 | } | 351 | } |
@@ -301,8 +354,8 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
301 | sc->sc_flags &= ~SC_OP_FULL_RESET; | 354 | sc->sc_flags &= ~SC_OP_FULL_RESET; |
302 | 355 | ||
303 | if (ath_startrecv(sc) != 0) { | 356 | if (ath_startrecv(sc) != 0) { |
304 | DPRINTF(sc, ATH_DBG_FATAL, | 357 | ath_print(common, ATH_DBG_FATAL, |
305 | "Unable to restart recv logic\n"); | 358 | "Unable to restart recv logic\n"); |
306 | r = -EIO; | 359 | r = -EIO; |
307 | goto ps_restore; | 360 | goto ps_restore; |
308 | } | 361 | } |
@@ -327,6 +380,7 @@ static void ath_ani_calibrate(unsigned long data) | |||
327 | { | 380 | { |
328 | struct ath_softc *sc = (struct ath_softc *)data; | 381 | struct ath_softc *sc = (struct ath_softc *)data; |
329 | struct ath_hw *ah = sc->sc_ah; | 382 | struct ath_hw *ah = sc->sc_ah; |
383 | struct ath_common *common = ath9k_hw_common(ah); | ||
330 | bool longcal = false; | 384 | bool longcal = false; |
331 | bool shortcal = false; | 385 | bool shortcal = false; |
332 | bool aniflag = false; | 386 | bool aniflag = false; |
@@ -351,33 +405,34 @@ static void ath_ani_calibrate(unsigned long data) | |||
351 | ath9k_ps_wakeup(sc); | 405 | ath9k_ps_wakeup(sc); |
352 | 406 | ||
353 | /* Long calibration runs independently of short calibration. */ | 407 | /* Long calibration runs independently of short calibration. */ |
354 | if ((timestamp - sc->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) { | 408 | if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) { |
355 | longcal = true; | 409 | longcal = true; |
356 | DPRINTF(sc, ATH_DBG_ANI, "longcal @%lu\n", jiffies); | 410 | ath_print(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies); |
357 | sc->ani.longcal_timer = timestamp; | 411 | common->ani.longcal_timer = timestamp; |
358 | } | 412 | } |
359 | 413 | ||
360 | /* Short calibration applies only while caldone is false */ | 414 | /* Short calibration applies only while caldone is false */ |
361 | if (!sc->ani.caldone) { | 415 | if (!common->ani.caldone) { |
362 | if ((timestamp - sc->ani.shortcal_timer) >= short_cal_interval) { | 416 | if ((timestamp - common->ani.shortcal_timer) >= short_cal_interval) { |
363 | shortcal = true; | 417 | shortcal = true; |
364 | DPRINTF(sc, ATH_DBG_ANI, "shortcal @%lu\n", jiffies); | 418 | ath_print(common, ATH_DBG_ANI, |
365 | sc->ani.shortcal_timer = timestamp; | 419 | "shortcal @%lu\n", jiffies); |
366 | sc->ani.resetcal_timer = timestamp; | 420 | common->ani.shortcal_timer = timestamp; |
421 | common->ani.resetcal_timer = timestamp; | ||
367 | } | 422 | } |
368 | } else { | 423 | } else { |
369 | if ((timestamp - sc->ani.resetcal_timer) >= | 424 | if ((timestamp - common->ani.resetcal_timer) >= |
370 | ATH_RESTART_CALINTERVAL) { | 425 | ATH_RESTART_CALINTERVAL) { |
371 | sc->ani.caldone = ath9k_hw_reset_calvalid(ah); | 426 | common->ani.caldone = ath9k_hw_reset_calvalid(ah); |
372 | if (sc->ani.caldone) | 427 | if (common->ani.caldone) |
373 | sc->ani.resetcal_timer = timestamp; | 428 | common->ani.resetcal_timer = timestamp; |
374 | } | 429 | } |
375 | } | 430 | } |
376 | 431 | ||
377 | /* Verify whether we must check ANI */ | 432 | /* Verify whether we must check ANI */ |
378 | if ((timestamp - sc->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) { | 433 | if ((timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) { |
379 | aniflag = true; | 434 | aniflag = true; |
380 | sc->ani.checkani_timer = timestamp; | 435 | common->ani.checkani_timer = timestamp; |
381 | } | 436 | } |
382 | 437 | ||
383 | /* Skip all processing if there's nothing to do. */ | 438 | /* Skip all processing if there's nothing to do. */ |
@@ -388,16 +443,21 @@ static void ath_ani_calibrate(unsigned long data) | |||
388 | 443 | ||
389 | /* Perform calibration if necessary */ | 444 | /* Perform calibration if necessary */ |
390 | if (longcal || shortcal) { | 445 | if (longcal || shortcal) { |
391 | sc->ani.caldone = ath9k_hw_calibrate(ah, ah->curchan, | 446 | common->ani.caldone = |
392 | sc->rx_chainmask, longcal); | 447 | ath9k_hw_calibrate(ah, |
448 | ah->curchan, | ||
449 | common->rx_chainmask, | ||
450 | longcal); | ||
393 | 451 | ||
394 | if (longcal) | 452 | if (longcal) |
395 | sc->ani.noise_floor = ath9k_hw_getchan_noise(ah, | 453 | common->ani.noise_floor = ath9k_hw_getchan_noise(ah, |
396 | ah->curchan); | 454 | ah->curchan); |
397 | 455 | ||
398 | DPRINTF(sc, ATH_DBG_ANI," calibrate chan %u/%x nf: %d\n", | 456 | ath_print(common, ATH_DBG_ANI, |
399 | ah->curchan->channel, ah->curchan->channelFlags, | 457 | " calibrate chan %u/%x nf: %d\n", |
400 | sc->ani.noise_floor); | 458 | ah->curchan->channel, |
459 | ah->curchan->channelFlags, | ||
460 | common->ani.noise_floor); | ||
401 | } | 461 | } |
402 | } | 462 | } |
403 | 463 | ||
@@ -413,21 +473,21 @@ set_timer: | |||
413 | cal_interval = ATH_LONG_CALINTERVAL; | 473 | cal_interval = ATH_LONG_CALINTERVAL; |
414 | if (sc->sc_ah->config.enable_ani) | 474 | if (sc->sc_ah->config.enable_ani) |
415 | cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL); | 475 | cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL); |
416 | if (!sc->ani.caldone) | 476 | if (!common->ani.caldone) |
417 | cal_interval = min(cal_interval, (u32)short_cal_interval); | 477 | cal_interval = min(cal_interval, (u32)short_cal_interval); |
418 | 478 | ||
419 | mod_timer(&sc->ani.timer, jiffies + msecs_to_jiffies(cal_interval)); | 479 | mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval)); |
420 | } | 480 | } |
421 | 481 | ||
422 | static void ath_start_ani(struct ath_softc *sc) | 482 | static void ath_start_ani(struct ath_common *common) |
423 | { | 483 | { |
424 | unsigned long timestamp = jiffies_to_msecs(jiffies); | 484 | unsigned long timestamp = jiffies_to_msecs(jiffies); |
425 | 485 | ||
426 | sc->ani.longcal_timer = timestamp; | 486 | common->ani.longcal_timer = timestamp; |
427 | sc->ani.shortcal_timer = timestamp; | 487 | common->ani.shortcal_timer = timestamp; |
428 | sc->ani.checkani_timer = timestamp; | 488 | common->ani.checkani_timer = timestamp; |
429 | 489 | ||
430 | mod_timer(&sc->ani.timer, | 490 | mod_timer(&common->ani.timer, |
431 | jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); | 491 | jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); |
432 | } | 492 | } |
433 | 493 | ||
@@ -439,17 +499,22 @@ static void ath_start_ani(struct ath_softc *sc) | |||
439 | */ | 499 | */ |
440 | void ath_update_chainmask(struct ath_softc *sc, int is_ht) | 500 | void ath_update_chainmask(struct ath_softc *sc, int is_ht) |
441 | { | 501 | { |
502 | struct ath_hw *ah = sc->sc_ah; | ||
503 | struct ath_common *common = ath9k_hw_common(ah); | ||
504 | |||
442 | if ((sc->sc_flags & SC_OP_SCANNING) || is_ht || | 505 | if ((sc->sc_flags & SC_OP_SCANNING) || is_ht || |
443 | (sc->btcoex_info.btcoex_scheme != ATH_BTCOEX_CFG_NONE)) { | 506 | (ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE)) { |
444 | sc->tx_chainmask = sc->sc_ah->caps.tx_chainmask; | 507 | common->tx_chainmask = ah->caps.tx_chainmask; |
445 | sc->rx_chainmask = sc->sc_ah->caps.rx_chainmask; | 508 | common->rx_chainmask = ah->caps.rx_chainmask; |
446 | } else { | 509 | } else { |
447 | sc->tx_chainmask = 1; | 510 | common->tx_chainmask = 1; |
448 | sc->rx_chainmask = 1; | 511 | common->rx_chainmask = 1; |
449 | } | 512 | } |
450 | 513 | ||
451 | DPRINTF(sc, ATH_DBG_CONFIG, "tx chmask: %d, rx chmask: %d\n", | 514 | ath_print(common, ATH_DBG_CONFIG, |
452 | sc->tx_chainmask, sc->rx_chainmask); | 515 | "tx chmask: %d, rx chmask: %d\n", |
516 | common->tx_chainmask, | ||
517 | common->rx_chainmask); | ||
453 | } | 518 | } |
454 | 519 | ||
455 | static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta) | 520 | static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta) |
@@ -478,6 +543,9 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) | |||
478 | static void ath9k_tasklet(unsigned long data) | 543 | static void ath9k_tasklet(unsigned long data) |
479 | { | 544 | { |
480 | struct ath_softc *sc = (struct ath_softc *)data; | 545 | struct ath_softc *sc = (struct ath_softc *)data; |
546 | struct ath_hw *ah = sc->sc_ah; | ||
547 | struct ath_common *common = ath9k_hw_common(ah); | ||
548 | |||
481 | u32 status = sc->intrstatus; | 549 | u32 status = sc->intrstatus; |
482 | 550 | ||
483 | ath9k_ps_wakeup(sc); | 551 | ath9k_ps_wakeup(sc); |
@@ -502,16 +570,17 @@ static void ath9k_tasklet(unsigned long data) | |||
502 | * TSF sync does not look correct; remain awake to sync with | 570 | * TSF sync does not look correct; remain awake to sync with |
503 | * the next Beacon. | 571 | * the next Beacon. |
504 | */ | 572 | */ |
505 | DPRINTF(sc, ATH_DBG_PS, "TSFOOR - Sync with next Beacon\n"); | 573 | ath_print(common, ATH_DBG_PS, |
574 | "TSFOOR - Sync with next Beacon\n"); | ||
506 | sc->sc_flags |= SC_OP_WAIT_FOR_BEACON | SC_OP_BEACON_SYNC; | 575 | sc->sc_flags |= SC_OP_WAIT_FOR_BEACON | SC_OP_BEACON_SYNC; |
507 | } | 576 | } |
508 | 577 | ||
509 | if (sc->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE) | 578 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) |
510 | if (status & ATH9K_INT_GENTIMER) | 579 | if (status & ATH9K_INT_GENTIMER) |
511 | ath_gen_timer_isr(sc->sc_ah); | 580 | ath_gen_timer_isr(sc->sc_ah); |
512 | 581 | ||
513 | /* re-enable hardware interrupt */ | 582 | /* re-enable hardware interrupt */ |
514 | ath9k_hw_set_interrupts(sc->sc_ah, sc->imask); | 583 | ath9k_hw_set_interrupts(ah, sc->imask); |
515 | ath9k_ps_restore(sc); | 584 | ath9k_ps_restore(sc); |
516 | } | 585 | } |
517 | 586 | ||
@@ -602,7 +671,7 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
602 | if (status & ATH9K_INT_TIM_TIMER) { | 671 | if (status & ATH9K_INT_TIM_TIMER) { |
603 | /* Clear RxAbort bit so that we can | 672 | /* Clear RxAbort bit so that we can |
604 | * receive frames */ | 673 | * receive frames */ |
605 | ath9k_hw_setpower(ah, ATH9K_PM_AWAKE); | 674 | ath9k_setpower(sc, ATH9K_PM_AWAKE); |
606 | ath9k_hw_setrxabort(sc->sc_ah, 0); | 675 | ath9k_hw_setrxabort(sc->sc_ah, 0); |
607 | sc->sc_flags |= SC_OP_WAIT_FOR_BEACON; | 676 | sc->sc_flags |= SC_OP_WAIT_FOR_BEACON; |
608 | } | 677 | } |
@@ -664,10 +733,11 @@ static u32 ath_get_extchanmode(struct ath_softc *sc, | |||
664 | return chanmode; | 733 | return chanmode; |
665 | } | 734 | } |
666 | 735 | ||
667 | static int ath_setkey_tkip(struct ath_softc *sc, u16 keyix, const u8 *key, | 736 | static int ath_setkey_tkip(struct ath_common *common, u16 keyix, const u8 *key, |
668 | struct ath9k_keyval *hk, const u8 *addr, | 737 | struct ath9k_keyval *hk, const u8 *addr, |
669 | bool authenticator) | 738 | bool authenticator) |
670 | { | 739 | { |
740 | struct ath_hw *ah = common->ah; | ||
671 | const u8 *key_rxmic; | 741 | const u8 *key_rxmic; |
672 | const u8 *key_txmic; | 742 | const u8 *key_txmic; |
673 | 743 | ||
@@ -687,42 +757,42 @@ static int ath_setkey_tkip(struct ath_softc *sc, u16 keyix, const u8 *key, | |||
687 | memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); | 757 | memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); |
688 | memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic)); | 758 | memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic)); |
689 | } | 759 | } |
690 | return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, addr); | 760 | return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr); |
691 | } | 761 | } |
692 | if (!sc->splitmic) { | 762 | if (!common->splitmic) { |
693 | /* TX and RX keys share the same key cache entry. */ | 763 | /* TX and RX keys share the same key cache entry. */ |
694 | memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); | 764 | memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); |
695 | memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic)); | 765 | memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic)); |
696 | return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, addr); | 766 | return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr); |
697 | } | 767 | } |
698 | 768 | ||
699 | /* Separate key cache entries for TX and RX */ | 769 | /* Separate key cache entries for TX and RX */ |
700 | 770 | ||
701 | /* TX key goes at first index, RX key at +32. */ | 771 | /* TX key goes at first index, RX key at +32. */ |
702 | memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic)); | 772 | memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic)); |
703 | if (!ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, NULL)) { | 773 | if (!ath9k_hw_set_keycache_entry(ah, keyix, hk, NULL)) { |
704 | /* TX MIC entry failed. No need to proceed further */ | 774 | /* TX MIC entry failed. No need to proceed further */ |
705 | DPRINTF(sc, ATH_DBG_FATAL, | 775 | ath_print(common, ATH_DBG_FATAL, |
706 | "Setting TX MIC Key Failed\n"); | 776 | "Setting TX MIC Key Failed\n"); |
707 | return 0; | 777 | return 0; |
708 | } | 778 | } |
709 | 779 | ||
710 | memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); | 780 | memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); |
711 | /* XXX delete tx key on failure? */ | 781 | /* XXX delete tx key on failure? */ |
712 | return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix + 32, hk, addr); | 782 | return ath9k_hw_set_keycache_entry(ah, keyix + 32, hk, addr); |
713 | } | 783 | } |
714 | 784 | ||
715 | static int ath_reserve_key_cache_slot_tkip(struct ath_softc *sc) | 785 | static int ath_reserve_key_cache_slot_tkip(struct ath_common *common) |
716 | { | 786 | { |
717 | int i; | 787 | int i; |
718 | 788 | ||
719 | for (i = IEEE80211_WEP_NKID; i < sc->keymax / 2; i++) { | 789 | for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) { |
720 | if (test_bit(i, sc->keymap) || | 790 | if (test_bit(i, common->keymap) || |
721 | test_bit(i + 64, sc->keymap)) | 791 | test_bit(i + 64, common->keymap)) |
722 | continue; /* At least one part of TKIP key allocated */ | 792 | continue; /* At least one part of TKIP key allocated */ |
723 | if (sc->splitmic && | 793 | if (common->splitmic && |
724 | (test_bit(i + 32, sc->keymap) || | 794 | (test_bit(i + 32, common->keymap) || |
725 | test_bit(i + 64 + 32, sc->keymap))) | 795 | test_bit(i + 64 + 32, common->keymap))) |
726 | continue; /* At least one part of TKIP key allocated */ | 796 | continue; /* At least one part of TKIP key allocated */ |
727 | 797 | ||
728 | /* Found a free slot for a TKIP key */ | 798 | /* Found a free slot for a TKIP key */ |
@@ -731,60 +801,60 @@ static int ath_reserve_key_cache_slot_tkip(struct ath_softc *sc) | |||
731 | return -1; | 801 | return -1; |
732 | } | 802 | } |
733 | 803 | ||
734 | static int ath_reserve_key_cache_slot(struct ath_softc *sc) | 804 | static int ath_reserve_key_cache_slot(struct ath_common *common) |
735 | { | 805 | { |
736 | int i; | 806 | int i; |
737 | 807 | ||
738 | /* First, try to find slots that would not be available for TKIP. */ | 808 | /* First, try to find slots that would not be available for TKIP. */ |
739 | if (sc->splitmic) { | 809 | if (common->splitmic) { |
740 | for (i = IEEE80211_WEP_NKID; i < sc->keymax / 4; i++) { | 810 | for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) { |
741 | if (!test_bit(i, sc->keymap) && | 811 | if (!test_bit(i, common->keymap) && |
742 | (test_bit(i + 32, sc->keymap) || | 812 | (test_bit(i + 32, common->keymap) || |
743 | test_bit(i + 64, sc->keymap) || | 813 | test_bit(i + 64, common->keymap) || |
744 | test_bit(i + 64 + 32, sc->keymap))) | 814 | test_bit(i + 64 + 32, common->keymap))) |
745 | return i; | 815 | return i; |
746 | if (!test_bit(i + 32, sc->keymap) && | 816 | if (!test_bit(i + 32, common->keymap) && |
747 | (test_bit(i, sc->keymap) || | 817 | (test_bit(i, common->keymap) || |
748 | test_bit(i + 64, sc->keymap) || | 818 | test_bit(i + 64, common->keymap) || |
749 | test_bit(i + 64 + 32, sc->keymap))) | 819 | test_bit(i + 64 + 32, common->keymap))) |
750 | return i + 32; | 820 | return i + 32; |
751 | if (!test_bit(i + 64, sc->keymap) && | 821 | if (!test_bit(i + 64, common->keymap) && |
752 | (test_bit(i , sc->keymap) || | 822 | (test_bit(i , common->keymap) || |
753 | test_bit(i + 32, sc->keymap) || | 823 | test_bit(i + 32, common->keymap) || |
754 | test_bit(i + 64 + 32, sc->keymap))) | 824 | test_bit(i + 64 + 32, common->keymap))) |
755 | return i + 64; | 825 | return i + 64; |
756 | if (!test_bit(i + 64 + 32, sc->keymap) && | 826 | if (!test_bit(i + 64 + 32, common->keymap) && |
757 | (test_bit(i, sc->keymap) || | 827 | (test_bit(i, common->keymap) || |
758 | test_bit(i + 32, sc->keymap) || | 828 | test_bit(i + 32, common->keymap) || |
759 | test_bit(i + 64, sc->keymap))) | 829 | test_bit(i + 64, common->keymap))) |
760 | return i + 64 + 32; | 830 | return i + 64 + 32; |
761 | } | 831 | } |
762 | } else { | 832 | } else { |
763 | for (i = IEEE80211_WEP_NKID; i < sc->keymax / 2; i++) { | 833 | for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) { |
764 | if (!test_bit(i, sc->keymap) && | 834 | if (!test_bit(i, common->keymap) && |
765 | test_bit(i + 64, sc->keymap)) | 835 | test_bit(i + 64, common->keymap)) |
766 | return i; | 836 | return i; |
767 | if (test_bit(i, sc->keymap) && | 837 | if (test_bit(i, common->keymap) && |
768 | !test_bit(i + 64, sc->keymap)) | 838 | !test_bit(i + 64, common->keymap)) |
769 | return i + 64; | 839 | return i + 64; |
770 | } | 840 | } |
771 | } | 841 | } |
772 | 842 | ||
773 | /* No partially used TKIP slots, pick any available slot */ | 843 | /* No partially used TKIP slots, pick any available slot */ |
774 | for (i = IEEE80211_WEP_NKID; i < sc->keymax; i++) { | 844 | for (i = IEEE80211_WEP_NKID; i < common->keymax; i++) { |
775 | /* Do not allow slots that could be needed for TKIP group keys | 845 | /* Do not allow slots that could be needed for TKIP group keys |
776 | * to be used. This limitation could be removed if we know that | 846 | * to be used. This limitation could be removed if we know that |
777 | * TKIP will not be used. */ | 847 | * TKIP will not be used. */ |
778 | if (i >= 64 && i < 64 + IEEE80211_WEP_NKID) | 848 | if (i >= 64 && i < 64 + IEEE80211_WEP_NKID) |
779 | continue; | 849 | continue; |
780 | if (sc->splitmic) { | 850 | if (common->splitmic) { |
781 | if (i >= 32 && i < 32 + IEEE80211_WEP_NKID) | 851 | if (i >= 32 && i < 32 + IEEE80211_WEP_NKID) |
782 | continue; | 852 | continue; |
783 | if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID) | 853 | if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID) |
784 | continue; | 854 | continue; |
785 | } | 855 | } |
786 | 856 | ||
787 | if (!test_bit(i, sc->keymap)) | 857 | if (!test_bit(i, common->keymap)) |
788 | return i; /* Found a free slot for a key */ | 858 | return i; /* Found a free slot for a key */ |
789 | } | 859 | } |
790 | 860 | ||
@@ -792,11 +862,12 @@ static int ath_reserve_key_cache_slot(struct ath_softc *sc) | |||
792 | return -1; | 862 | return -1; |
793 | } | 863 | } |
794 | 864 | ||
795 | static int ath_key_config(struct ath_softc *sc, | 865 | static int ath_key_config(struct ath_common *common, |
796 | struct ieee80211_vif *vif, | 866 | struct ieee80211_vif *vif, |
797 | struct ieee80211_sta *sta, | 867 | struct ieee80211_sta *sta, |
798 | struct ieee80211_key_conf *key) | 868 | struct ieee80211_key_conf *key) |
799 | { | 869 | { |
870 | struct ath_hw *ah = common->ah; | ||
800 | struct ath9k_keyval hk; | 871 | struct ath9k_keyval hk; |
801 | const u8 *mac = NULL; | 872 | const u8 *mac = NULL; |
802 | int ret = 0; | 873 | int ret = 0; |
@@ -842,54 +913,57 @@ static int ath_key_config(struct ath_softc *sc, | |||
842 | mac = sta->addr; | 913 | mac = sta->addr; |
843 | 914 | ||
844 | if (key->alg == ALG_TKIP) | 915 | if (key->alg == ALG_TKIP) |
845 | idx = ath_reserve_key_cache_slot_tkip(sc); | 916 | idx = ath_reserve_key_cache_slot_tkip(common); |
846 | else | 917 | else |
847 | idx = ath_reserve_key_cache_slot(sc); | 918 | idx = ath_reserve_key_cache_slot(common); |
848 | if (idx < 0) | 919 | if (idx < 0) |
849 | return -ENOSPC; /* no free key cache entries */ | 920 | return -ENOSPC; /* no free key cache entries */ |
850 | } | 921 | } |
851 | 922 | ||
852 | if (key->alg == ALG_TKIP) | 923 | if (key->alg == ALG_TKIP) |
853 | ret = ath_setkey_tkip(sc, idx, key->key, &hk, mac, | 924 | ret = ath_setkey_tkip(common, idx, key->key, &hk, mac, |
854 | vif->type == NL80211_IFTYPE_AP); | 925 | vif->type == NL80211_IFTYPE_AP); |
855 | else | 926 | else |
856 | ret = ath9k_hw_set_keycache_entry(sc->sc_ah, idx, &hk, mac); | 927 | ret = ath9k_hw_set_keycache_entry(ah, idx, &hk, mac); |
857 | 928 | ||
858 | if (!ret) | 929 | if (!ret) |
859 | return -EIO; | 930 | return -EIO; |
860 | 931 | ||
861 | set_bit(idx, sc->keymap); | 932 | set_bit(idx, common->keymap); |
862 | if (key->alg == ALG_TKIP) { | 933 | if (key->alg == ALG_TKIP) { |
863 | set_bit(idx + 64, sc->keymap); | 934 | set_bit(idx + 64, common->keymap); |
864 | if (sc->splitmic) { | 935 | if (common->splitmic) { |
865 | set_bit(idx + 32, sc->keymap); | 936 | set_bit(idx + 32, common->keymap); |
866 | set_bit(idx + 64 + 32, sc->keymap); | 937 | set_bit(idx + 64 + 32, common->keymap); |
867 | } | 938 | } |
868 | } | 939 | } |
869 | 940 | ||
870 | return idx; | 941 | return idx; |
871 | } | 942 | } |
872 | 943 | ||
873 | static void ath_key_delete(struct ath_softc *sc, struct ieee80211_key_conf *key) | 944 | static void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key) |
874 | { | 945 | { |
875 | ath9k_hw_keyreset(sc->sc_ah, key->hw_key_idx); | 946 | struct ath_hw *ah = common->ah; |
947 | |||
948 | ath9k_hw_keyreset(ah, key->hw_key_idx); | ||
876 | if (key->hw_key_idx < IEEE80211_WEP_NKID) | 949 | if (key->hw_key_idx < IEEE80211_WEP_NKID) |
877 | return; | 950 | return; |
878 | 951 | ||
879 | clear_bit(key->hw_key_idx, sc->keymap); | 952 | clear_bit(key->hw_key_idx, common->keymap); |
880 | if (key->alg != ALG_TKIP) | 953 | if (key->alg != ALG_TKIP) |
881 | return; | 954 | return; |
882 | 955 | ||
883 | clear_bit(key->hw_key_idx + 64, sc->keymap); | 956 | clear_bit(key->hw_key_idx + 64, common->keymap); |
884 | if (sc->splitmic) { | 957 | if (common->splitmic) { |
885 | clear_bit(key->hw_key_idx + 32, sc->keymap); | 958 | clear_bit(key->hw_key_idx + 32, common->keymap); |
886 | clear_bit(key->hw_key_idx + 64 + 32, sc->keymap); | 959 | clear_bit(key->hw_key_idx + 64 + 32, common->keymap); |
887 | } | 960 | } |
888 | } | 961 | } |
889 | 962 | ||
890 | static void setup_ht_cap(struct ath_softc *sc, | 963 | static void setup_ht_cap(struct ath_softc *sc, |
891 | struct ieee80211_sta_ht_cap *ht_info) | 964 | struct ieee80211_sta_ht_cap *ht_info) |
892 | { | 965 | { |
966 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
893 | u8 tx_streams, rx_streams; | 967 | u8 tx_streams, rx_streams; |
894 | 968 | ||
895 | ht_info->ht_supported = true; | 969 | ht_info->ht_supported = true; |
@@ -903,12 +977,15 @@ static void setup_ht_cap(struct ath_softc *sc, | |||
903 | 977 | ||
904 | /* set up supported mcs set */ | 978 | /* set up supported mcs set */ |
905 | memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); | 979 | memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); |
906 | tx_streams = !(sc->tx_chainmask & (sc->tx_chainmask - 1)) ? 1 : 2; | 980 | tx_streams = !(common->tx_chainmask & (common->tx_chainmask - 1)) ? |
907 | rx_streams = !(sc->rx_chainmask & (sc->rx_chainmask - 1)) ? 1 : 2; | 981 | 1 : 2; |
982 | rx_streams = !(common->rx_chainmask & (common->rx_chainmask - 1)) ? | ||
983 | 1 : 2; | ||
908 | 984 | ||
909 | if (tx_streams != rx_streams) { | 985 | if (tx_streams != rx_streams) { |
910 | DPRINTF(sc, ATH_DBG_CONFIG, "TX streams %d, RX streams: %d\n", | 986 | ath_print(common, ATH_DBG_CONFIG, |
911 | tx_streams, rx_streams); | 987 | "TX streams %d, RX streams: %d\n", |
988 | tx_streams, rx_streams); | ||
912 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; | 989 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; |
913 | ht_info->mcs.tx_params |= ((tx_streams - 1) << | 990 | ht_info->mcs.tx_params |= ((tx_streams - 1) << |
914 | IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); | 991 | IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); |
@@ -925,14 +1002,17 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, | |||
925 | struct ieee80211_vif *vif, | 1002 | struct ieee80211_vif *vif, |
926 | struct ieee80211_bss_conf *bss_conf) | 1003 | struct ieee80211_bss_conf *bss_conf) |
927 | { | 1004 | { |
1005 | struct ath_hw *ah = sc->sc_ah; | ||
1006 | struct ath_common *common = ath9k_hw_common(ah); | ||
928 | 1007 | ||
929 | if (bss_conf->assoc) { | 1008 | if (bss_conf->assoc) { |
930 | DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info ASSOC %d, bssid: %pM\n", | 1009 | ath_print(common, ATH_DBG_CONFIG, |
931 | bss_conf->aid, sc->curbssid); | 1010 | "Bss Info ASSOC %d, bssid: %pM\n", |
1011 | bss_conf->aid, common->curbssid); | ||
932 | 1012 | ||
933 | /* New association, store aid */ | 1013 | /* New association, store aid */ |
934 | sc->curaid = bss_conf->aid; | 1014 | common->curaid = bss_conf->aid; |
935 | ath9k_hw_write_associd(sc); | 1015 | ath9k_hw_write_associd(ah); |
936 | 1016 | ||
937 | /* | 1017 | /* |
938 | * Request a re-configuration of Beacon related timers | 1018 | * Request a re-configuration of Beacon related timers |
@@ -947,12 +1027,12 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, | |||
947 | /* Reset rssi stats */ | 1027 | /* Reset rssi stats */ |
948 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; | 1028 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; |
949 | 1029 | ||
950 | ath_start_ani(sc); | 1030 | ath_start_ani(common); |
951 | } else { | 1031 | } else { |
952 | DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info DISASSOC\n"); | 1032 | ath_print(common, ATH_DBG_CONFIG, "Bss Info DISASSOC\n"); |
953 | sc->curaid = 0; | 1033 | common->curaid = 0; |
954 | /* Stop ANI */ | 1034 | /* Stop ANI */ |
955 | del_timer_sync(&sc->ani.timer); | 1035 | del_timer_sync(&common->ani.timer); |
956 | } | 1036 | } |
957 | } | 1037 | } |
958 | 1038 | ||
@@ -1042,8 +1122,8 @@ static int ath_register_led(struct ath_softc *sc, struct ath_led *led, | |||
1042 | 1122 | ||
1043 | ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->led_cdev); | 1123 | ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->led_cdev); |
1044 | if (ret) | 1124 | if (ret) |
1045 | DPRINTF(sc, ATH_DBG_FATAL, | 1125 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, |
1046 | "Failed to register led:%s", led->name); | 1126 | "Failed to register led:%s", led->name); |
1047 | else | 1127 | else |
1048 | led->registered = 1; | 1128 | led->registered = 1; |
1049 | return ret; | 1129 | return ret; |
@@ -1124,10 +1204,11 @@ fail: | |||
1124 | ath_deinit_leds(sc); | 1204 | ath_deinit_leds(sc); |
1125 | } | 1205 | } |
1126 | 1206 | ||
1127 | void ath_radio_enable(struct ath_softc *sc) | 1207 | void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) |
1128 | { | 1208 | { |
1129 | struct ath_hw *ah = sc->sc_ah; | 1209 | struct ath_hw *ah = sc->sc_ah; |
1130 | struct ieee80211_channel *channel = sc->hw->conf.channel; | 1210 | struct ath_common *common = ath9k_hw_common(ah); |
1211 | struct ieee80211_channel *channel = hw->conf.channel; | ||
1131 | int r; | 1212 | int r; |
1132 | 1213 | ||
1133 | ath9k_ps_wakeup(sc); | 1214 | ath9k_ps_wakeup(sc); |
@@ -1139,17 +1220,17 @@ void ath_radio_enable(struct ath_softc *sc) | |||
1139 | spin_lock_bh(&sc->sc_resetlock); | 1220 | spin_lock_bh(&sc->sc_resetlock); |
1140 | r = ath9k_hw_reset(ah, ah->curchan, false); | 1221 | r = ath9k_hw_reset(ah, ah->curchan, false); |
1141 | if (r) { | 1222 | if (r) { |
1142 | DPRINTF(sc, ATH_DBG_FATAL, | 1223 | ath_print(common, ATH_DBG_FATAL, |
1143 | "Unable to reset channel %u (%uMhz) ", | 1224 | "Unable to reset channel %u (%uMhz) ", |
1144 | "reset status %d\n", | 1225 | "reset status %d\n", |
1145 | channel->center_freq, r); | 1226 | channel->center_freq, r); |
1146 | } | 1227 | } |
1147 | spin_unlock_bh(&sc->sc_resetlock); | 1228 | spin_unlock_bh(&sc->sc_resetlock); |
1148 | 1229 | ||
1149 | ath_update_txpow(sc); | 1230 | ath_update_txpow(sc); |
1150 | if (ath_startrecv(sc) != 0) { | 1231 | if (ath_startrecv(sc) != 0) { |
1151 | DPRINTF(sc, ATH_DBG_FATAL, | 1232 | ath_print(common, ATH_DBG_FATAL, |
1152 | "Unable to restart recv logic\n"); | 1233 | "Unable to restart recv logic\n"); |
1153 | return; | 1234 | return; |
1154 | } | 1235 | } |
1155 | 1236 | ||
@@ -1164,18 +1245,18 @@ void ath_radio_enable(struct ath_softc *sc) | |||
1164 | AR_GPIO_OUTPUT_MUX_AS_OUTPUT); | 1245 | AR_GPIO_OUTPUT_MUX_AS_OUTPUT); |
1165 | ath9k_hw_set_gpio(ah, ah->led_pin, 0); | 1246 | ath9k_hw_set_gpio(ah, ah->led_pin, 0); |
1166 | 1247 | ||
1167 | ieee80211_wake_queues(sc->hw); | 1248 | ieee80211_wake_queues(hw); |
1168 | ath9k_ps_restore(sc); | 1249 | ath9k_ps_restore(sc); |
1169 | } | 1250 | } |
1170 | 1251 | ||
1171 | void ath_radio_disable(struct ath_softc *sc) | 1252 | void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) |
1172 | { | 1253 | { |
1173 | struct ath_hw *ah = sc->sc_ah; | 1254 | struct ath_hw *ah = sc->sc_ah; |
1174 | struct ieee80211_channel *channel = sc->hw->conf.channel; | 1255 | struct ieee80211_channel *channel = hw->conf.channel; |
1175 | int r; | 1256 | int r; |
1176 | 1257 | ||
1177 | ath9k_ps_wakeup(sc); | 1258 | ath9k_ps_wakeup(sc); |
1178 | ieee80211_stop_queues(sc->hw); | 1259 | ieee80211_stop_queues(hw); |
1179 | 1260 | ||
1180 | /* Disable LED */ | 1261 | /* Disable LED */ |
1181 | ath9k_hw_set_gpio(ah, ah->led_pin, 1); | 1262 | ath9k_hw_set_gpio(ah, ah->led_pin, 1); |
@@ -1189,22 +1270,22 @@ void ath_radio_disable(struct ath_softc *sc) | |||
1189 | ath_flushrecv(sc); /* flush recv queue */ | 1270 | ath_flushrecv(sc); /* flush recv queue */ |
1190 | 1271 | ||
1191 | if (!ah->curchan) | 1272 | if (!ah->curchan) |
1192 | ah->curchan = ath_get_curchannel(sc, sc->hw); | 1273 | ah->curchan = ath_get_curchannel(sc, hw); |
1193 | 1274 | ||
1194 | spin_lock_bh(&sc->sc_resetlock); | 1275 | spin_lock_bh(&sc->sc_resetlock); |
1195 | r = ath9k_hw_reset(ah, ah->curchan, false); | 1276 | r = ath9k_hw_reset(ah, ah->curchan, false); |
1196 | if (r) { | 1277 | if (r) { |
1197 | DPRINTF(sc, ATH_DBG_FATAL, | 1278 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, |
1198 | "Unable to reset channel %u (%uMhz) " | 1279 | "Unable to reset channel %u (%uMhz) " |
1199 | "reset status %d\n", | 1280 | "reset status %d\n", |
1200 | channel->center_freq, r); | 1281 | channel->center_freq, r); |
1201 | } | 1282 | } |
1202 | spin_unlock_bh(&sc->sc_resetlock); | 1283 | spin_unlock_bh(&sc->sc_resetlock); |
1203 | 1284 | ||
1204 | ath9k_hw_phy_disable(ah); | 1285 | ath9k_hw_phy_disable(ah); |
1205 | ath9k_hw_configpcipowersave(ah, 1, 1); | 1286 | ath9k_hw_configpcipowersave(ah, 1, 1); |
1206 | ath9k_ps_restore(sc); | 1287 | ath9k_ps_restore(sc); |
1207 | ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP); | 1288 | ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); |
1208 | } | 1289 | } |
1209 | 1290 | ||
1210 | /*******************/ | 1291 | /*******************/ |
@@ -1236,23 +1317,26 @@ static void ath_start_rfkill_poll(struct ath_softc *sc) | |||
1236 | wiphy_rfkill_start_polling(sc->hw->wiphy); | 1317 | wiphy_rfkill_start_polling(sc->hw->wiphy); |
1237 | } | 1318 | } |
1238 | 1319 | ||
1239 | void ath_cleanup(struct ath_softc *sc) | 1320 | static void ath9k_uninit_hw(struct ath_softc *sc) |
1240 | { | 1321 | { |
1241 | ath_detach(sc); | 1322 | struct ath_hw *ah = sc->sc_ah; |
1242 | free_irq(sc->irq, sc); | 1323 | |
1243 | ath_bus_cleanup(sc); | 1324 | BUG_ON(!ah); |
1244 | kfree(sc->sec_wiphy); | 1325 | |
1245 | ieee80211_free_hw(sc->hw); | 1326 | ath9k_exit_debug(ah); |
1327 | ath9k_hw_detach(ah); | ||
1328 | sc->sc_ah = NULL; | ||
1246 | } | 1329 | } |
1247 | 1330 | ||
1248 | void ath_detach(struct ath_softc *sc) | 1331 | static void ath_clean_core(struct ath_softc *sc) |
1249 | { | 1332 | { |
1250 | struct ieee80211_hw *hw = sc->hw; | 1333 | struct ieee80211_hw *hw = sc->hw; |
1334 | struct ath_hw *ah = sc->sc_ah; | ||
1251 | int i = 0; | 1335 | int i = 0; |
1252 | 1336 | ||
1253 | ath9k_ps_wakeup(sc); | 1337 | ath9k_ps_wakeup(sc); |
1254 | 1338 | ||
1255 | DPRINTF(sc, ATH_DBG_CONFIG, "Detach ATH hw\n"); | 1339 | dev_dbg(sc->dev, "Detach ATH hw\n"); |
1256 | 1340 | ||
1257 | ath_deinit_leds(sc); | 1341 | ath_deinit_leds(sc); |
1258 | wiphy_rfkill_stop_polling(sc->hw->wiphy); | 1342 | wiphy_rfkill_stop_polling(sc->hw->wiphy); |
@@ -1273,20 +1357,36 @@ void ath_detach(struct ath_softc *sc) | |||
1273 | tasklet_kill(&sc->bcon_tasklet); | 1357 | tasklet_kill(&sc->bcon_tasklet); |
1274 | 1358 | ||
1275 | if (!(sc->sc_flags & SC_OP_INVALID)) | 1359 | if (!(sc->sc_flags & SC_OP_INVALID)) |
1276 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); | 1360 | ath9k_setpower(sc, ATH9K_PM_AWAKE); |
1277 | 1361 | ||
1278 | /* cleanup tx queues */ | 1362 | /* cleanup tx queues */ |
1279 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | 1363 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) |
1280 | if (ATH_TXQ_SETUP(sc, i)) | 1364 | if (ATH_TXQ_SETUP(sc, i)) |
1281 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); | 1365 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); |
1282 | 1366 | ||
1283 | if ((sc->btcoex_info.no_stomp_timer) && | 1367 | if ((sc->btcoex.no_stomp_timer) && |
1284 | sc->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE) | 1368 | ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) |
1285 | ath_gen_timer_free(sc->sc_ah, sc->btcoex_info.no_stomp_timer); | 1369 | ath_gen_timer_free(ah, sc->btcoex.no_stomp_timer); |
1370 | } | ||
1286 | 1371 | ||
1287 | ath9k_hw_detach(sc->sc_ah); | 1372 | void ath_detach(struct ath_softc *sc) |
1288 | sc->sc_ah = NULL; | 1373 | { |
1289 | ath9k_exit_debug(sc); | 1374 | ath_clean_core(sc); |
1375 | ath9k_uninit_hw(sc); | ||
1376 | } | ||
1377 | |||
1378 | void ath_cleanup(struct ath_softc *sc) | ||
1379 | { | ||
1380 | struct ath_hw *ah = sc->sc_ah; | ||
1381 | struct ath_common *common = ath9k_hw_common(ah); | ||
1382 | |||
1383 | ath_clean_core(sc); | ||
1384 | free_irq(sc->irq, sc); | ||
1385 | ath_bus_cleanup(common); | ||
1386 | kfree(sc->sec_wiphy); | ||
1387 | ieee80211_free_hw(sc->hw); | ||
1388 | |||
1389 | ath9k_uninit_hw(sc); | ||
1290 | } | 1390 | } |
1291 | 1391 | ||
1292 | static int ath9k_reg_notifier(struct wiphy *wiphy, | 1392 | static int ath9k_reg_notifier(struct wiphy *wiphy, |
@@ -1295,29 +1395,245 @@ static int ath9k_reg_notifier(struct wiphy *wiphy, | |||
1295 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); | 1395 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); |
1296 | struct ath_wiphy *aphy = hw->priv; | 1396 | struct ath_wiphy *aphy = hw->priv; |
1297 | struct ath_softc *sc = aphy->sc; | 1397 | struct ath_softc *sc = aphy->sc; |
1298 | struct ath_regulatory *reg = &sc->common.regulatory; | 1398 | struct ath_regulatory *reg = ath9k_hw_regulatory(sc->sc_ah); |
1299 | 1399 | ||
1300 | return ath_reg_notifier_apply(wiphy, request, reg); | 1400 | return ath_reg_notifier_apply(wiphy, request, reg); |
1301 | } | 1401 | } |
1302 | 1402 | ||
1303 | /* | 1403 | /* |
1404 | * Detects if there is any priority bt traffic | ||
1405 | */ | ||
1406 | static void ath_detect_bt_priority(struct ath_softc *sc) | ||
1407 | { | ||
1408 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
1409 | struct ath_hw *ah = sc->sc_ah; | ||
1410 | |||
1411 | if (ath9k_hw_gpio_get(sc->sc_ah, ah->btcoex_hw.btpriority_gpio)) | ||
1412 | btcoex->bt_priority_cnt++; | ||
1413 | |||
1414 | if (time_after(jiffies, btcoex->bt_priority_time + | ||
1415 | msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) { | ||
1416 | if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) { | ||
1417 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX, | ||
1418 | "BT priority traffic detected"); | ||
1419 | sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED; | ||
1420 | } else { | ||
1421 | sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED; | ||
1422 | } | ||
1423 | |||
1424 | btcoex->bt_priority_cnt = 0; | ||
1425 | btcoex->bt_priority_time = jiffies; | ||
1426 | } | ||
1427 | } | ||
1428 | |||
1429 | /* | ||
1430 | * Configures appropriate weight based on stomp type. | ||
1431 | */ | ||
1432 | static void ath9k_btcoex_bt_stomp(struct ath_softc *sc, | ||
1433 | enum ath_stomp_type stomp_type) | ||
1434 | { | ||
1435 | struct ath_hw *ah = sc->sc_ah; | ||
1436 | |||
1437 | switch (stomp_type) { | ||
1438 | case ATH_BTCOEX_STOMP_ALL: | ||
1439 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||
1440 | AR_STOMP_ALL_WLAN_WGHT); | ||
1441 | break; | ||
1442 | case ATH_BTCOEX_STOMP_LOW: | ||
1443 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||
1444 | AR_STOMP_LOW_WLAN_WGHT); | ||
1445 | break; | ||
1446 | case ATH_BTCOEX_STOMP_NONE: | ||
1447 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||
1448 | AR_STOMP_NONE_WLAN_WGHT); | ||
1449 | break; | ||
1450 | default: | ||
1451 | ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, | ||
1452 | "Invalid Stomptype\n"); | ||
1453 | break; | ||
1454 | } | ||
1455 | |||
1456 | ath9k_hw_btcoex_enable(ah); | ||
1457 | } | ||
1458 | |||
1459 | static void ath9k_gen_timer_start(struct ath_hw *ah, | ||
1460 | struct ath_gen_timer *timer, | ||
1461 | u32 timer_next, | ||
1462 | u32 timer_period) | ||
1463 | { | ||
1464 | struct ath_common *common = ath9k_hw_common(ah); | ||
1465 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
1466 | |||
1467 | ath9k_hw_gen_timer_start(ah, timer, timer_next, timer_period); | ||
1468 | |||
1469 | if ((sc->imask & ATH9K_INT_GENTIMER) == 0) { | ||
1470 | ath9k_hw_set_interrupts(ah, 0); | ||
1471 | sc->imask |= ATH9K_INT_GENTIMER; | ||
1472 | ath9k_hw_set_interrupts(ah, sc->imask); | ||
1473 | } | ||
1474 | } | ||
1475 | |||
1476 | static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer) | ||
1477 | { | ||
1478 | struct ath_common *common = ath9k_hw_common(ah); | ||
1479 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
1480 | struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers; | ||
1481 | |||
1482 | ath9k_hw_gen_timer_stop(ah, timer); | ||
1483 | |||
1484 | /* if no timer is enabled, turn off interrupt mask */ | ||
1485 | if (timer_table->timer_mask.val == 0) { | ||
1486 | ath9k_hw_set_interrupts(ah, 0); | ||
1487 | sc->imask &= ~ATH9K_INT_GENTIMER; | ||
1488 | ath9k_hw_set_interrupts(ah, sc->imask); | ||
1489 | } | ||
1490 | } | ||
1491 | |||
1492 | /* | ||
1493 | * This is the master bt coex timer which runs for every | ||
1494 | * 45ms, bt traffic will be given priority during 55% of this | ||
1495 | * period while wlan gets remaining 45% | ||
1496 | */ | ||
1497 | static void ath_btcoex_period_timer(unsigned long data) | ||
1498 | { | ||
1499 | struct ath_softc *sc = (struct ath_softc *) data; | ||
1500 | struct ath_hw *ah = sc->sc_ah; | ||
1501 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
1502 | |||
1503 | ath_detect_bt_priority(sc); | ||
1504 | |||
1505 | spin_lock_bh(&btcoex->btcoex_lock); | ||
1506 | |||
1507 | ath9k_btcoex_bt_stomp(sc, btcoex->bt_stomp_type); | ||
1508 | |||
1509 | spin_unlock_bh(&btcoex->btcoex_lock); | ||
1510 | |||
1511 | if (btcoex->btcoex_period != btcoex->btcoex_no_stomp) { | ||
1512 | if (btcoex->hw_timer_enabled) | ||
1513 | ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer); | ||
1514 | |||
1515 | ath9k_gen_timer_start(ah, | ||
1516 | btcoex->no_stomp_timer, | ||
1517 | (ath9k_hw_gettsf32(ah) + | ||
1518 | btcoex->btcoex_no_stomp), | ||
1519 | btcoex->btcoex_no_stomp * 10); | ||
1520 | btcoex->hw_timer_enabled = true; | ||
1521 | } | ||
1522 | |||
1523 | mod_timer(&btcoex->period_timer, jiffies + | ||
1524 | msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD)); | ||
1525 | } | ||
1526 | |||
1527 | /* | ||
1528 | * Generic tsf based hw timer which configures weight | ||
1529 | * registers to time slice between wlan and bt traffic | ||
1530 | */ | ||
1531 | static void ath_btcoex_no_stomp_timer(void *arg) | ||
1532 | { | ||
1533 | struct ath_softc *sc = (struct ath_softc *)arg; | ||
1534 | struct ath_hw *ah = sc->sc_ah; | ||
1535 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
1536 | |||
1537 | ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, | ||
1538 | "no stomp timer running \n"); | ||
1539 | |||
1540 | spin_lock_bh(&btcoex->btcoex_lock); | ||
1541 | |||
1542 | if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW) | ||
1543 | ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_NONE); | ||
1544 | else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) | ||
1545 | ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_LOW); | ||
1546 | |||
1547 | spin_unlock_bh(&btcoex->btcoex_lock); | ||
1548 | } | ||
1549 | |||
1550 | static int ath_init_btcoex_timer(struct ath_softc *sc) | ||
1551 | { | ||
1552 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
1553 | |||
1554 | btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000; | ||
1555 | btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * | ||
1556 | btcoex->btcoex_period / 100; | ||
1557 | |||
1558 | setup_timer(&btcoex->period_timer, ath_btcoex_period_timer, | ||
1559 | (unsigned long) sc); | ||
1560 | |||
1561 | spin_lock_init(&btcoex->btcoex_lock); | ||
1562 | |||
1563 | btcoex->no_stomp_timer = ath_gen_timer_alloc(sc->sc_ah, | ||
1564 | ath_btcoex_no_stomp_timer, | ||
1565 | ath_btcoex_no_stomp_timer, | ||
1566 | (void *) sc, AR_FIRST_NDP_TIMER); | ||
1567 | |||
1568 | if (!btcoex->no_stomp_timer) | ||
1569 | return -ENOMEM; | ||
1570 | |||
1571 | return 0; | ||
1572 | } | ||
1573 | |||
1574 | /* | ||
1575 | * Read and write, they both share the same lock. We do this to serialize | ||
1576 | * reads and writes on Atheros 802.11n PCI devices only. This is required | ||
1577 | * as the FIFO on these devices can only accept sanely 2 requests. After | ||
1578 | * that the device goes bananas. Serializing the reads/writes prevents this | ||
1579 | * from happening. | ||
1580 | */ | ||
1581 | |||
1582 | static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset) | ||
1583 | { | ||
1584 | struct ath_hw *ah = (struct ath_hw *) hw_priv; | ||
1585 | struct ath_common *common = ath9k_hw_common(ah); | ||
1586 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
1587 | |||
1588 | if (ah->config.serialize_regmode == SER_REG_MODE_ON) { | ||
1589 | unsigned long flags; | ||
1590 | spin_lock_irqsave(&sc->sc_serial_rw, flags); | ||
1591 | iowrite32(val, sc->mem + reg_offset); | ||
1592 | spin_unlock_irqrestore(&sc->sc_serial_rw, flags); | ||
1593 | } else | ||
1594 | iowrite32(val, sc->mem + reg_offset); | ||
1595 | } | ||
1596 | |||
1597 | static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset) | ||
1598 | { | ||
1599 | struct ath_hw *ah = (struct ath_hw *) hw_priv; | ||
1600 | struct ath_common *common = ath9k_hw_common(ah); | ||
1601 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
1602 | u32 val; | ||
1603 | |||
1604 | if (ah->config.serialize_regmode == SER_REG_MODE_ON) { | ||
1605 | unsigned long flags; | ||
1606 | spin_lock_irqsave(&sc->sc_serial_rw, flags); | ||
1607 | val = ioread32(sc->mem + reg_offset); | ||
1608 | spin_unlock_irqrestore(&sc->sc_serial_rw, flags); | ||
1609 | } else | ||
1610 | val = ioread32(sc->mem + reg_offset); | ||
1611 | return val; | ||
1612 | } | ||
1613 | |||
1614 | static const struct ath_ops ath9k_common_ops = { | ||
1615 | .read = ath9k_ioread32, | ||
1616 | .write = ath9k_iowrite32, | ||
1617 | }; | ||
1618 | |||
1619 | /* | ||
1304 | * Initialize and fill ath_softc, ath_sofct is the | 1620 | * Initialize and fill ath_softc, ath_sofct is the |
1305 | * "Software Carrier" struct. Historically it has existed | 1621 | * "Software Carrier" struct. Historically it has existed |
1306 | * to allow the separation between hardware specific | 1622 | * to allow the separation between hardware specific |
1307 | * variables (now in ath_hw) and driver specific variables. | 1623 | * variables (now in ath_hw) and driver specific variables. |
1308 | */ | 1624 | */ |
1309 | static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid) | 1625 | static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, |
1626 | const struct ath_bus_ops *bus_ops) | ||
1310 | { | 1627 | { |
1311 | struct ath_hw *ah = NULL; | 1628 | struct ath_hw *ah = NULL; |
1629 | struct ath_common *common; | ||
1312 | int r = 0, i; | 1630 | int r = 0, i; |
1313 | int csz = 0; | 1631 | int csz = 0; |
1632 | int qnum; | ||
1314 | 1633 | ||
1315 | /* XXX: hardware will not be ready until ath_open() being called */ | 1634 | /* XXX: hardware will not be ready until ath_open() being called */ |
1316 | sc->sc_flags |= SC_OP_INVALID; | 1635 | sc->sc_flags |= SC_OP_INVALID; |
1317 | 1636 | ||
1318 | if (ath9k_init_debug(sc) < 0) | ||
1319 | printk(KERN_ERR "Unable to create debugfs files\n"); | ||
1320 | |||
1321 | spin_lock_init(&sc->wiphy_lock); | 1637 | spin_lock_init(&sc->wiphy_lock); |
1322 | spin_lock_init(&sc->sc_resetlock); | 1638 | spin_lock_init(&sc->sc_resetlock); |
1323 | spin_lock_init(&sc->sc_serial_rw); | 1639 | spin_lock_init(&sc->sc_serial_rw); |
@@ -1328,47 +1644,58 @@ static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid) | |||
1328 | tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet, | 1644 | tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet, |
1329 | (unsigned long)sc); | 1645 | (unsigned long)sc); |
1330 | 1646 | ||
1331 | /* | ||
1332 | * Cache line size is used to size and align various | ||
1333 | * structures used to communicate with the hardware. | ||
1334 | */ | ||
1335 | ath_read_cachesize(sc, &csz); | ||
1336 | /* XXX assert csz is non-zero */ | ||
1337 | sc->common.cachelsz = csz << 2; /* convert to bytes */ | ||
1338 | |||
1339 | ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL); | 1647 | ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL); |
1340 | if (!ah) { | 1648 | if (!ah) |
1341 | r = -ENOMEM; | 1649 | return -ENOMEM; |
1342 | goto bad_no_ah; | ||
1343 | } | ||
1344 | 1650 | ||
1345 | ah->ah_sc = sc; | ||
1346 | ah->hw_version.devid = devid; | 1651 | ah->hw_version.devid = devid; |
1347 | ah->hw_version.subsysid = subsysid; | 1652 | ah->hw_version.subsysid = subsysid; |
1348 | sc->sc_ah = ah; | 1653 | sc->sc_ah = ah; |
1349 | 1654 | ||
1655 | common = ath9k_hw_common(ah); | ||
1656 | common->ops = &ath9k_common_ops; | ||
1657 | common->bus_ops = bus_ops; | ||
1658 | common->ah = ah; | ||
1659 | common->hw = sc->hw; | ||
1660 | common->priv = sc; | ||
1661 | common->debug_mask = ath9k_debug; | ||
1662 | |||
1663 | /* | ||
1664 | * Cache line size is used to size and align various | ||
1665 | * structures used to communicate with the hardware. | ||
1666 | */ | ||
1667 | ath_read_cachesize(common, &csz); | ||
1668 | /* XXX assert csz is non-zero */ | ||
1669 | common->cachelsz = csz << 2; /* convert to bytes */ | ||
1670 | |||
1350 | r = ath9k_hw_init(ah); | 1671 | r = ath9k_hw_init(ah); |
1351 | if (r) { | 1672 | if (r) { |
1352 | DPRINTF(sc, ATH_DBG_FATAL, | 1673 | ath_print(common, ATH_DBG_FATAL, |
1353 | "Unable to initialize hardware; " | 1674 | "Unable to initialize hardware; " |
1354 | "initialization status: %d\n", r); | 1675 | "initialization status: %d\n", r); |
1355 | goto bad; | 1676 | goto bad_free_hw; |
1677 | } | ||
1678 | |||
1679 | if (ath9k_init_debug(ah) < 0) { | ||
1680 | ath_print(common, ATH_DBG_FATAL, | ||
1681 | "Unable to create debugfs files\n"); | ||
1682 | goto bad_free_hw; | ||
1356 | } | 1683 | } |
1357 | 1684 | ||
1358 | /* Get the hardware key cache size. */ | 1685 | /* Get the hardware key cache size. */ |
1359 | sc->keymax = ah->caps.keycache_size; | 1686 | common->keymax = ah->caps.keycache_size; |
1360 | if (sc->keymax > ATH_KEYMAX) { | 1687 | if (common->keymax > ATH_KEYMAX) { |
1361 | DPRINTF(sc, ATH_DBG_ANY, | 1688 | ath_print(common, ATH_DBG_ANY, |
1362 | "Warning, using only %u entries in %u key cache\n", | 1689 | "Warning, using only %u entries in %u key cache\n", |
1363 | ATH_KEYMAX, sc->keymax); | 1690 | ATH_KEYMAX, common->keymax); |
1364 | sc->keymax = ATH_KEYMAX; | 1691 | common->keymax = ATH_KEYMAX; |
1365 | } | 1692 | } |
1366 | 1693 | ||
1367 | /* | 1694 | /* |
1368 | * Reset the key cache since some parts do not | 1695 | * Reset the key cache since some parts do not |
1369 | * reset the contents on initial power up. | 1696 | * reset the contents on initial power up. |
1370 | */ | 1697 | */ |
1371 | for (i = 0; i < sc->keymax; i++) | 1698 | for (i = 0; i < common->keymax; i++) |
1372 | ath9k_hw_keyreset(ah, (u16) i); | 1699 | ath9k_hw_keyreset(ah, (u16) i); |
1373 | 1700 | ||
1374 | /* default to MONITOR mode */ | 1701 | /* default to MONITOR mode */ |
@@ -1386,17 +1713,17 @@ static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid) | |||
1386 | * priority. Note that the hal handles reseting | 1713 | * priority. Note that the hal handles reseting |
1387 | * these queues at the needed time. | 1714 | * these queues at the needed time. |
1388 | */ | 1715 | */ |
1389 | sc->beacon.beaconq = ath_beaconq_setup(ah); | 1716 | sc->beacon.beaconq = ath9k_hw_beaconq_setup(ah); |
1390 | if (sc->beacon.beaconq == -1) { | 1717 | if (sc->beacon.beaconq == -1) { |
1391 | DPRINTF(sc, ATH_DBG_FATAL, | 1718 | ath_print(common, ATH_DBG_FATAL, |
1392 | "Unable to setup a beacon xmit queue\n"); | 1719 | "Unable to setup a beacon xmit queue\n"); |
1393 | r = -EIO; | 1720 | r = -EIO; |
1394 | goto bad2; | 1721 | goto bad2; |
1395 | } | 1722 | } |
1396 | sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0); | 1723 | sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0); |
1397 | if (sc->beacon.cabq == NULL) { | 1724 | if (sc->beacon.cabq == NULL) { |
1398 | DPRINTF(sc, ATH_DBG_FATAL, | 1725 | ath_print(common, ATH_DBG_FATAL, |
1399 | "Unable to setup CAB xmit queue\n"); | 1726 | "Unable to setup CAB xmit queue\n"); |
1400 | r = -EIO; | 1727 | r = -EIO; |
1401 | goto bad2; | 1728 | goto bad2; |
1402 | } | 1729 | } |
@@ -1410,27 +1737,27 @@ static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid) | |||
1410 | /* Setup data queues */ | 1737 | /* Setup data queues */ |
1411 | /* NB: ensure BK queue is the lowest priority h/w queue */ | 1738 | /* NB: ensure BK queue is the lowest priority h/w queue */ |
1412 | if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) { | 1739 | if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) { |
1413 | DPRINTF(sc, ATH_DBG_FATAL, | 1740 | ath_print(common, ATH_DBG_FATAL, |
1414 | "Unable to setup xmit queue for BK traffic\n"); | 1741 | "Unable to setup xmit queue for BK traffic\n"); |
1415 | r = -EIO; | 1742 | r = -EIO; |
1416 | goto bad2; | 1743 | goto bad2; |
1417 | } | 1744 | } |
1418 | 1745 | ||
1419 | if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) { | 1746 | if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) { |
1420 | DPRINTF(sc, ATH_DBG_FATAL, | 1747 | ath_print(common, ATH_DBG_FATAL, |
1421 | "Unable to setup xmit queue for BE traffic\n"); | 1748 | "Unable to setup xmit queue for BE traffic\n"); |
1422 | r = -EIO; | 1749 | r = -EIO; |
1423 | goto bad2; | 1750 | goto bad2; |
1424 | } | 1751 | } |
1425 | if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) { | 1752 | if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) { |
1426 | DPRINTF(sc, ATH_DBG_FATAL, | 1753 | ath_print(common, ATH_DBG_FATAL, |
1427 | "Unable to setup xmit queue for VI traffic\n"); | 1754 | "Unable to setup xmit queue for VI traffic\n"); |
1428 | r = -EIO; | 1755 | r = -EIO; |
1429 | goto bad2; | 1756 | goto bad2; |
1430 | } | 1757 | } |
1431 | if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) { | 1758 | if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) { |
1432 | DPRINTF(sc, ATH_DBG_FATAL, | 1759 | ath_print(common, ATH_DBG_FATAL, |
1433 | "Unable to setup xmit queue for VO traffic\n"); | 1760 | "Unable to setup xmit queue for VO traffic\n"); |
1434 | r = -EIO; | 1761 | r = -EIO; |
1435 | goto bad2; | 1762 | goto bad2; |
1436 | } | 1763 | } |
@@ -1438,8 +1765,8 @@ static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid) | |||
1438 | /* Initializes the noise floor to a reasonable default value. | 1765 | /* Initializes the noise floor to a reasonable default value. |
1439 | * Later on this will be updated during ANI processing. */ | 1766 | * Later on this will be updated during ANI processing. */ |
1440 | 1767 | ||
1441 | sc->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR; | 1768 | common->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR; |
1442 | setup_timer(&sc->ani.timer, ath_ani_calibrate, (unsigned long)sc); | 1769 | setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); |
1443 | 1770 | ||
1444 | if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER, | 1771 | if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER, |
1445 | ATH9K_CIPHER_TKIP, NULL)) { | 1772 | ATH9K_CIPHER_TKIP, NULL)) { |
@@ -1465,7 +1792,7 @@ static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid) | |||
1465 | ATH9K_CIPHER_MIC, NULL) | 1792 | ATH9K_CIPHER_MIC, NULL) |
1466 | && ath9k_hw_getcapability(ah, ATH9K_CAP_TKIP_SPLIT, | 1793 | && ath9k_hw_getcapability(ah, ATH9K_CAP_TKIP_SPLIT, |
1467 | 0, NULL)) | 1794 | 0, NULL)) |
1468 | sc->splitmic = 1; | 1795 | common->splitmic = 1; |
1469 | 1796 | ||
1470 | /* turn on mcast key search if possible */ | 1797 | /* turn on mcast key search if possible */ |
1471 | if (!ath9k_hw_getcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL)) | 1798 | if (!ath9k_hw_getcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL)) |
@@ -1480,14 +1807,14 @@ static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid) | |||
1480 | sc->sc_flags |= SC_OP_RXAGGR; | 1807 | sc->sc_flags |= SC_OP_RXAGGR; |
1481 | } | 1808 | } |
1482 | 1809 | ||
1483 | sc->tx_chainmask = ah->caps.tx_chainmask; | 1810 | common->tx_chainmask = ah->caps.tx_chainmask; |
1484 | sc->rx_chainmask = ah->caps.rx_chainmask; | 1811 | common->rx_chainmask = ah->caps.rx_chainmask; |
1485 | 1812 | ||
1486 | ath9k_hw_setcapability(ah, ATH9K_CAP_DIVERSITY, 1, true, NULL); | 1813 | ath9k_hw_setcapability(ah, ATH9K_CAP_DIVERSITY, 1, true, NULL); |
1487 | sc->rx.defant = ath9k_hw_getdefantenna(ah); | 1814 | sc->rx.defant = ath9k_hw_getdefantenna(ah); |
1488 | 1815 | ||
1489 | if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) | 1816 | if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) |
1490 | memcpy(sc->bssidmask, ath_bcast_mac, ETH_ALEN); | 1817 | memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); |
1491 | 1818 | ||
1492 | sc->beacon.slottime = ATH9K_SLOT_TIME_9; /* default to short slot time */ | 1819 | sc->beacon.slottime = ATH9K_SLOT_TIME_9; /* default to short slot time */ |
1493 | 1820 | ||
@@ -1515,10 +1842,24 @@ static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid) | |||
1515 | ARRAY_SIZE(ath9k_5ghz_chantable); | 1842 | ARRAY_SIZE(ath9k_5ghz_chantable); |
1516 | } | 1843 | } |
1517 | 1844 | ||
1518 | if (sc->btcoex_info.btcoex_scheme != ATH_BTCOEX_CFG_NONE) { | 1845 | switch (ah->btcoex_hw.scheme) { |
1519 | r = ath9k_hw_btcoex_init(ah); | 1846 | case ATH_BTCOEX_CFG_NONE: |
1847 | break; | ||
1848 | case ATH_BTCOEX_CFG_2WIRE: | ||
1849 | ath9k_hw_btcoex_init_2wire(ah); | ||
1850 | break; | ||
1851 | case ATH_BTCOEX_CFG_3WIRE: | ||
1852 | ath9k_hw_btcoex_init_3wire(ah); | ||
1853 | r = ath_init_btcoex_timer(sc); | ||
1520 | if (r) | 1854 | if (r) |
1521 | goto bad2; | 1855 | goto bad2; |
1856 | qnum = ath_tx_get_qnum(sc, ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE); | ||
1857 | ath9k_hw_init_btcoex_hw(ah, qnum); | ||
1858 | sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; | ||
1859 | break; | ||
1860 | default: | ||
1861 | WARN_ON(1); | ||
1862 | break; | ||
1522 | } | 1863 | } |
1523 | 1864 | ||
1524 | return 0; | 1865 | return 0; |
@@ -1527,12 +1868,9 @@ bad2: | |||
1527 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | 1868 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) |
1528 | if (ATH_TXQ_SETUP(sc, i)) | 1869 | if (ATH_TXQ_SETUP(sc, i)) |
1529 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); | 1870 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); |
1530 | bad: | ||
1531 | ath9k_hw_detach(ah); | ||
1532 | sc->sc_ah = NULL; | ||
1533 | bad_no_ah: | ||
1534 | ath9k_exit_debug(sc); | ||
1535 | 1871 | ||
1872 | bad_free_hw: | ||
1873 | ath9k_uninit_hw(sc); | ||
1536 | return r; | 1874 | return r; |
1537 | } | 1875 | } |
1538 | 1876 | ||
@@ -1555,7 +1893,7 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
1555 | BIT(NL80211_IFTYPE_ADHOC) | | 1893 | BIT(NL80211_IFTYPE_ADHOC) | |
1556 | BIT(NL80211_IFTYPE_MESH_POINT); | 1894 | BIT(NL80211_IFTYPE_MESH_POINT); |
1557 | 1895 | ||
1558 | hw->wiphy->ps_default = false; | 1896 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; |
1559 | 1897 | ||
1560 | hw->queues = 4; | 1898 | hw->queues = 4; |
1561 | hw->max_rates = 4; | 1899 | hw->max_rates = 4; |
@@ -1576,34 +1914,40 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
1576 | } | 1914 | } |
1577 | 1915 | ||
1578 | /* Device driver core initialization */ | 1916 | /* Device driver core initialization */ |
1579 | int ath_init_device(u16 devid, struct ath_softc *sc, u16 subsysid) | 1917 | int ath_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, |
1918 | const struct ath_bus_ops *bus_ops) | ||
1580 | { | 1919 | { |
1581 | struct ieee80211_hw *hw = sc->hw; | 1920 | struct ieee80211_hw *hw = sc->hw; |
1921 | struct ath_common *common; | ||
1922 | struct ath_hw *ah; | ||
1582 | int error = 0, i; | 1923 | int error = 0, i; |
1583 | struct ath_regulatory *reg; | 1924 | struct ath_regulatory *reg; |
1584 | 1925 | ||
1585 | DPRINTF(sc, ATH_DBG_CONFIG, "Attach ATH hw\n"); | 1926 | dev_dbg(sc->dev, "Attach ATH hw\n"); |
1586 | 1927 | ||
1587 | error = ath_init_softc(devid, sc, subsysid); | 1928 | error = ath_init_softc(devid, sc, subsysid, bus_ops); |
1588 | if (error != 0) | 1929 | if (error != 0) |
1589 | return error; | 1930 | return error; |
1590 | 1931 | ||
1932 | ah = sc->sc_ah; | ||
1933 | common = ath9k_hw_common(ah); | ||
1934 | |||
1591 | /* get mac address from hardware and set in mac80211 */ | 1935 | /* get mac address from hardware and set in mac80211 */ |
1592 | 1936 | ||
1593 | SET_IEEE80211_PERM_ADDR(hw, sc->sc_ah->macaddr); | 1937 | SET_IEEE80211_PERM_ADDR(hw, common->macaddr); |
1594 | 1938 | ||
1595 | ath_set_hw_capab(sc, hw); | 1939 | ath_set_hw_capab(sc, hw); |
1596 | 1940 | ||
1597 | error = ath_regd_init(&sc->common.regulatory, sc->hw->wiphy, | 1941 | error = ath_regd_init(&common->regulatory, sc->hw->wiphy, |
1598 | ath9k_reg_notifier); | 1942 | ath9k_reg_notifier); |
1599 | if (error) | 1943 | if (error) |
1600 | return error; | 1944 | return error; |
1601 | 1945 | ||
1602 | reg = &sc->common.regulatory; | 1946 | reg = &common->regulatory; |
1603 | 1947 | ||
1604 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { | 1948 | if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) { |
1605 | setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); | 1949 | setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); |
1606 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) | 1950 | if (test_bit(ATH9K_MODE_11A, ah->caps.wireless_modes)) |
1607 | setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); | 1951 | setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); |
1608 | } | 1952 | } |
1609 | 1953 | ||
@@ -1641,9 +1985,7 @@ error_attach: | |||
1641 | if (ATH_TXQ_SETUP(sc, i)) | 1985 | if (ATH_TXQ_SETUP(sc, i)) |
1642 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); | 1986 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); |
1643 | 1987 | ||
1644 | ath9k_hw_detach(sc->sc_ah); | 1988 | ath9k_uninit_hw(sc); |
1645 | sc->sc_ah = NULL; | ||
1646 | ath9k_exit_debug(sc); | ||
1647 | 1989 | ||
1648 | return error; | 1990 | return error; |
1649 | } | 1991 | } |
@@ -1651,6 +1993,7 @@ error_attach: | |||
1651 | int ath_reset(struct ath_softc *sc, bool retry_tx) | 1993 | int ath_reset(struct ath_softc *sc, bool retry_tx) |
1652 | { | 1994 | { |
1653 | struct ath_hw *ah = sc->sc_ah; | 1995 | struct ath_hw *ah = sc->sc_ah; |
1996 | struct ath_common *common = ath9k_hw_common(ah); | ||
1654 | struct ieee80211_hw *hw = sc->hw; | 1997 | struct ieee80211_hw *hw = sc->hw; |
1655 | int r; | 1998 | int r; |
1656 | 1999 | ||
@@ -1662,12 +2005,13 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
1662 | spin_lock_bh(&sc->sc_resetlock); | 2005 | spin_lock_bh(&sc->sc_resetlock); |
1663 | r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false); | 2006 | r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false); |
1664 | if (r) | 2007 | if (r) |
1665 | DPRINTF(sc, ATH_DBG_FATAL, | 2008 | ath_print(common, ATH_DBG_FATAL, |
1666 | "Unable to reset hardware; reset status %d\n", r); | 2009 | "Unable to reset hardware; reset status %d\n", r); |
1667 | spin_unlock_bh(&sc->sc_resetlock); | 2010 | spin_unlock_bh(&sc->sc_resetlock); |
1668 | 2011 | ||
1669 | if (ath_startrecv(sc) != 0) | 2012 | if (ath_startrecv(sc) != 0) |
1670 | DPRINTF(sc, ATH_DBG_FATAL, "Unable to start recv logic\n"); | 2013 | ath_print(common, ATH_DBG_FATAL, |
2014 | "Unable to start recv logic\n"); | ||
1671 | 2015 | ||
1672 | /* | 2016 | /* |
1673 | * We may be doing a reset in response to a request | 2017 | * We may be doing a reset in response to a request |
@@ -1710,19 +2054,20 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | |||
1710 | ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc)) | 2054 | ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc)) |
1711 | #define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0) | 2055 | #define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0) |
1712 | #define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096) | 2056 | #define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096) |
1713 | 2057 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | |
1714 | struct ath_desc *ds; | 2058 | struct ath_desc *ds; |
1715 | struct ath_buf *bf; | 2059 | struct ath_buf *bf; |
1716 | int i, bsize, error; | 2060 | int i, bsize, error; |
1717 | 2061 | ||
1718 | DPRINTF(sc, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n", | 2062 | ath_print(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n", |
1719 | name, nbuf, ndesc); | 2063 | name, nbuf, ndesc); |
1720 | 2064 | ||
1721 | INIT_LIST_HEAD(head); | 2065 | INIT_LIST_HEAD(head); |
1722 | /* ath_desc must be a multiple of DWORDs */ | 2066 | /* ath_desc must be a multiple of DWORDs */ |
1723 | if ((sizeof(struct ath_desc) % 4) != 0) { | 2067 | if ((sizeof(struct ath_desc) % 4) != 0) { |
1724 | DPRINTF(sc, ATH_DBG_FATAL, "ath_desc not DWORD aligned\n"); | 2068 | ath_print(common, ATH_DBG_FATAL, |
1725 | ASSERT((sizeof(struct ath_desc) % 4) == 0); | 2069 | "ath_desc not DWORD aligned\n"); |
2070 | BUG_ON((sizeof(struct ath_desc) % 4) != 0); | ||
1726 | error = -ENOMEM; | 2071 | error = -ENOMEM; |
1727 | goto fail; | 2072 | goto fail; |
1728 | } | 2073 | } |
@@ -1755,9 +2100,9 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | |||
1755 | goto fail; | 2100 | goto fail; |
1756 | } | 2101 | } |
1757 | ds = dd->dd_desc; | 2102 | ds = dd->dd_desc; |
1758 | DPRINTF(sc, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n", | 2103 | ath_print(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n", |
1759 | name, ds, (u32) dd->dd_desc_len, | 2104 | name, ds, (u32) dd->dd_desc_len, |
1760 | ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len); | 2105 | ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len); |
1761 | 2106 | ||
1762 | /* allocate buffers */ | 2107 | /* allocate buffers */ |
1763 | bsize = sizeof(struct ath_buf) * nbuf; | 2108 | bsize = sizeof(struct ath_buf) * nbuf; |
@@ -1780,7 +2125,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | |||
1780 | * descriptor fetch. | 2125 | * descriptor fetch. |
1781 | */ | 2126 | */ |
1782 | while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) { | 2127 | while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) { |
1783 | ASSERT((caddr_t) bf->bf_desc < | 2128 | BUG_ON((caddr_t) bf->bf_desc >= |
1784 | ((caddr_t) dd->dd_desc + | 2129 | ((caddr_t) dd->dd_desc + |
1785 | dd->dd_desc_len)); | 2130 | dd->dd_desc_len)); |
1786 | 2131 | ||
@@ -1884,31 +2229,50 @@ void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
1884 | ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM; | 2229 | ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM; |
1885 | } | 2230 | } |
1886 | 2231 | ||
1887 | sc->tx_chan_width = ATH9K_HT_MACMODE_20; | 2232 | if (conf_is_ht(conf)) |
1888 | |||
1889 | if (conf_is_ht(conf)) { | ||
1890 | if (conf_is_ht40(conf)) | ||
1891 | sc->tx_chan_width = ATH9K_HT_MACMODE_2040; | ||
1892 | |||
1893 | ichan->chanmode = ath_get_extchanmode(sc, chan, | 2233 | ichan->chanmode = ath_get_extchanmode(sc, chan, |
1894 | conf->channel_type); | 2234 | conf->channel_type); |
1895 | } | ||
1896 | } | 2235 | } |
1897 | 2236 | ||
1898 | /**********************/ | 2237 | /**********************/ |
1899 | /* mac80211 callbacks */ | 2238 | /* mac80211 callbacks */ |
1900 | /**********************/ | 2239 | /**********************/ |
1901 | 2240 | ||
2241 | /* | ||
2242 | * (Re)start btcoex timers | ||
2243 | */ | ||
2244 | static void ath9k_btcoex_timer_resume(struct ath_softc *sc) | ||
2245 | { | ||
2246 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
2247 | struct ath_hw *ah = sc->sc_ah; | ||
2248 | |||
2249 | ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, | ||
2250 | "Starting btcoex timers"); | ||
2251 | |||
2252 | /* make sure duty cycle timer is also stopped when resuming */ | ||
2253 | if (btcoex->hw_timer_enabled) | ||
2254 | ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer); | ||
2255 | |||
2256 | btcoex->bt_priority_cnt = 0; | ||
2257 | btcoex->bt_priority_time = jiffies; | ||
2258 | sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED; | ||
2259 | |||
2260 | mod_timer(&btcoex->period_timer, jiffies); | ||
2261 | } | ||
2262 | |||
1902 | static int ath9k_start(struct ieee80211_hw *hw) | 2263 | static int ath9k_start(struct ieee80211_hw *hw) |
1903 | { | 2264 | { |
1904 | struct ath_wiphy *aphy = hw->priv; | 2265 | struct ath_wiphy *aphy = hw->priv; |
1905 | struct ath_softc *sc = aphy->sc; | 2266 | struct ath_softc *sc = aphy->sc; |
2267 | struct ath_hw *ah = sc->sc_ah; | ||
2268 | struct ath_common *common = ath9k_hw_common(ah); | ||
1906 | struct ieee80211_channel *curchan = hw->conf.channel; | 2269 | struct ieee80211_channel *curchan = hw->conf.channel; |
1907 | struct ath9k_channel *init_channel; | 2270 | struct ath9k_channel *init_channel; |
1908 | int r; | 2271 | int r; |
1909 | 2272 | ||
1910 | DPRINTF(sc, ATH_DBG_CONFIG, "Starting driver with " | 2273 | ath_print(common, ATH_DBG_CONFIG, |
1911 | "initial channel: %d MHz\n", curchan->center_freq); | 2274 | "Starting driver with initial channel: %d MHz\n", |
2275 | curchan->center_freq); | ||
1912 | 2276 | ||
1913 | mutex_lock(&sc->mutex); | 2277 | mutex_lock(&sc->mutex); |
1914 | 2278 | ||
@@ -1940,7 +2304,7 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1940 | init_channel = ath_get_curchannel(sc, hw); | 2304 | init_channel = ath_get_curchannel(sc, hw); |
1941 | 2305 | ||
1942 | /* Reset SERDES registers */ | 2306 | /* Reset SERDES registers */ |
1943 | ath9k_hw_configpcipowersave(sc->sc_ah, 0, 0); | 2307 | ath9k_hw_configpcipowersave(ah, 0, 0); |
1944 | 2308 | ||
1945 | /* | 2309 | /* |
1946 | * The basic interface to setting the hardware in a good | 2310 | * The basic interface to setting the hardware in a good |
@@ -1950,12 +2314,12 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1950 | * and then setup of the interrupt mask. | 2314 | * and then setup of the interrupt mask. |
1951 | */ | 2315 | */ |
1952 | spin_lock_bh(&sc->sc_resetlock); | 2316 | spin_lock_bh(&sc->sc_resetlock); |
1953 | r = ath9k_hw_reset(sc->sc_ah, init_channel, false); | 2317 | r = ath9k_hw_reset(ah, init_channel, false); |
1954 | if (r) { | 2318 | if (r) { |
1955 | DPRINTF(sc, ATH_DBG_FATAL, | 2319 | ath_print(common, ATH_DBG_FATAL, |
1956 | "Unable to reset hardware; reset status %d " | 2320 | "Unable to reset hardware; reset status %d " |
1957 | "(freq %u MHz)\n", r, | 2321 | "(freq %u MHz)\n", r, |
1958 | curchan->center_freq); | 2322 | curchan->center_freq); |
1959 | spin_unlock_bh(&sc->sc_resetlock); | 2323 | spin_unlock_bh(&sc->sc_resetlock); |
1960 | goto mutex_unlock; | 2324 | goto mutex_unlock; |
1961 | } | 2325 | } |
@@ -1975,7 +2339,8 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1975 | * here except setup the interrupt mask. | 2339 | * here except setup the interrupt mask. |
1976 | */ | 2340 | */ |
1977 | if (ath_startrecv(sc) != 0) { | 2341 | if (ath_startrecv(sc) != 0) { |
1978 | DPRINTF(sc, ATH_DBG_FATAL, "Unable to start recv logic\n"); | 2342 | ath_print(common, ATH_DBG_FATAL, |
2343 | "Unable to start recv logic\n"); | ||
1979 | r = -EIO; | 2344 | r = -EIO; |
1980 | goto mutex_unlock; | 2345 | goto mutex_unlock; |
1981 | } | 2346 | } |
@@ -1985,10 +2350,10 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1985 | | ATH9K_INT_RXEOL | ATH9K_INT_RXORN | 2350 | | ATH9K_INT_RXEOL | ATH9K_INT_RXORN |
1986 | | ATH9K_INT_FATAL | ATH9K_INT_GLOBAL; | 2351 | | ATH9K_INT_FATAL | ATH9K_INT_GLOBAL; |
1987 | 2352 | ||
1988 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_GTT) | 2353 | if (ah->caps.hw_caps & ATH9K_HW_CAP_GTT) |
1989 | sc->imask |= ATH9K_INT_GTT; | 2354 | sc->imask |= ATH9K_INT_GTT; |
1990 | 2355 | ||
1991 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) | 2356 | if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) |
1992 | sc->imask |= ATH9K_INT_CST; | 2357 | sc->imask |= ATH9K_INT_CST; |
1993 | 2358 | ||
1994 | ath_cache_conf_rate(sc, &hw->conf); | 2359 | ath_cache_conf_rate(sc, &hw->conf); |
@@ -1997,21 +2362,22 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1997 | 2362 | ||
1998 | /* Disable BMISS interrupt when we're not associated */ | 2363 | /* Disable BMISS interrupt when we're not associated */ |
1999 | sc->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); | 2364 | sc->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); |
2000 | ath9k_hw_set_interrupts(sc->sc_ah, sc->imask); | 2365 | ath9k_hw_set_interrupts(ah, sc->imask); |
2001 | 2366 | ||
2002 | ieee80211_wake_queues(hw); | 2367 | ieee80211_wake_queues(hw); |
2003 | 2368 | ||
2004 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); | 2369 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); |
2005 | 2370 | ||
2006 | if ((sc->btcoex_info.btcoex_scheme != ATH_BTCOEX_CFG_NONE) && | 2371 | if ((ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) && |
2007 | !(sc->sc_flags & SC_OP_BTCOEX_ENABLED)) { | 2372 | !ah->btcoex_hw.enabled) { |
2008 | ath_btcoex_set_weight(&sc->btcoex_info, AR_BT_COEX_WGHT, | 2373 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, |
2009 | AR_STOMP_LOW_WLAN_WGHT); | 2374 | AR_STOMP_LOW_WLAN_WGHT); |
2010 | ath9k_hw_btcoex_enable(sc->sc_ah); | 2375 | ath9k_hw_btcoex_enable(ah); |
2011 | 2376 | ||
2012 | ath_pcie_aspm_disable(sc); | 2377 | if (common->bus_ops->bt_coex_prep) |
2013 | if (sc->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE) | 2378 | common->bus_ops->bt_coex_prep(common); |
2014 | ath_btcoex_timer_resume(sc, &sc->btcoex_info); | 2379 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) |
2380 | ath9k_btcoex_timer_resume(sc); | ||
2015 | } | 2381 | } |
2016 | 2382 | ||
2017 | mutex_unlock: | 2383 | mutex_unlock: |
@@ -2026,12 +2392,14 @@ static int ath9k_tx(struct ieee80211_hw *hw, | |||
2026 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 2392 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
2027 | struct ath_wiphy *aphy = hw->priv; | 2393 | struct ath_wiphy *aphy = hw->priv; |
2028 | struct ath_softc *sc = aphy->sc; | 2394 | struct ath_softc *sc = aphy->sc; |
2395 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
2029 | struct ath_tx_control txctl; | 2396 | struct ath_tx_control txctl; |
2030 | int hdrlen, padsize; | 2397 | int hdrlen, padsize; |
2031 | 2398 | ||
2032 | if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) { | 2399 | if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) { |
2033 | printk(KERN_DEBUG "ath9k: %s: TX in unexpected wiphy state " | 2400 | ath_print(common, ATH_DBG_XMIT, |
2034 | "%d\n", wiphy_name(hw->wiphy), aphy->state); | 2401 | "ath9k: %s: TX in unexpected wiphy state " |
2402 | "%d\n", wiphy_name(hw->wiphy), aphy->state); | ||
2035 | goto exit; | 2403 | goto exit; |
2036 | } | 2404 | } |
2037 | 2405 | ||
@@ -2044,8 +2412,8 @@ static int ath9k_tx(struct ieee80211_hw *hw, | |||
2044 | if (ieee80211_is_data(hdr->frame_control) && | 2412 | if (ieee80211_is_data(hdr->frame_control) && |
2045 | !ieee80211_is_nullfunc(hdr->frame_control) && | 2413 | !ieee80211_is_nullfunc(hdr->frame_control) && |
2046 | !ieee80211_has_pm(hdr->frame_control)) { | 2414 | !ieee80211_has_pm(hdr->frame_control)) { |
2047 | DPRINTF(sc, ATH_DBG_PS, "Add PM=1 for a TX frame " | 2415 | ath_print(common, ATH_DBG_PS, "Add PM=1 for a TX frame " |
2048 | "while in PS mode\n"); | 2416 | "while in PS mode\n"); |
2049 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); | 2417 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); |
2050 | } | 2418 | } |
2051 | } | 2419 | } |
@@ -2060,11 +2428,12 @@ static int ath9k_tx(struct ieee80211_hw *hw, | |||
2060 | ath9k_ps_wakeup(sc); | 2428 | ath9k_ps_wakeup(sc); |
2061 | ath9k_hw_setrxabort(sc->sc_ah, 0); | 2429 | ath9k_hw_setrxabort(sc->sc_ah, 0); |
2062 | if (ieee80211_is_pspoll(hdr->frame_control)) { | 2430 | if (ieee80211_is_pspoll(hdr->frame_control)) { |
2063 | DPRINTF(sc, ATH_DBG_PS, "Sending PS-Poll to pick a " | 2431 | ath_print(common, ATH_DBG_PS, |
2064 | "buffered frame\n"); | 2432 | "Sending PS-Poll to pick a buffered frame\n"); |
2065 | sc->sc_flags |= SC_OP_WAIT_FOR_PSPOLL_DATA; | 2433 | sc->sc_flags |= SC_OP_WAIT_FOR_PSPOLL_DATA; |
2066 | } else { | 2434 | } else { |
2067 | DPRINTF(sc, ATH_DBG_PS, "Wake up to complete TX\n"); | 2435 | ath_print(common, ATH_DBG_PS, |
2436 | "Wake up to complete TX\n"); | ||
2068 | sc->sc_flags |= SC_OP_WAIT_FOR_TX_ACK; | 2437 | sc->sc_flags |= SC_OP_WAIT_FOR_TX_ACK; |
2069 | } | 2438 | } |
2070 | /* | 2439 | /* |
@@ -2106,10 +2475,10 @@ static int ath9k_tx(struct ieee80211_hw *hw, | |||
2106 | if (!txctl.txq) | 2475 | if (!txctl.txq) |
2107 | goto exit; | 2476 | goto exit; |
2108 | 2477 | ||
2109 | DPRINTF(sc, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb); | 2478 | ath_print(common, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb); |
2110 | 2479 | ||
2111 | if (ath_tx_start(hw, skb, &txctl) != 0) { | 2480 | if (ath_tx_start(hw, skb, &txctl) != 0) { |
2112 | DPRINTF(sc, ATH_DBG_XMIT, "TX failed\n"); | 2481 | ath_print(common, ATH_DBG_XMIT, "TX failed\n"); |
2113 | goto exit; | 2482 | goto exit; |
2114 | } | 2483 | } |
2115 | 2484 | ||
@@ -2119,10 +2488,28 @@ exit: | |||
2119 | return 0; | 2488 | return 0; |
2120 | } | 2489 | } |
2121 | 2490 | ||
2491 | /* | ||
2492 | * Pause btcoex timer and bt duty cycle timer | ||
2493 | */ | ||
2494 | static void ath9k_btcoex_timer_pause(struct ath_softc *sc) | ||
2495 | { | ||
2496 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
2497 | struct ath_hw *ah = sc->sc_ah; | ||
2498 | |||
2499 | del_timer_sync(&btcoex->period_timer); | ||
2500 | |||
2501 | if (btcoex->hw_timer_enabled) | ||
2502 | ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer); | ||
2503 | |||
2504 | btcoex->hw_timer_enabled = false; | ||
2505 | } | ||
2506 | |||
2122 | static void ath9k_stop(struct ieee80211_hw *hw) | 2507 | static void ath9k_stop(struct ieee80211_hw *hw) |
2123 | { | 2508 | { |
2124 | struct ath_wiphy *aphy = hw->priv; | 2509 | struct ath_wiphy *aphy = hw->priv; |
2125 | struct ath_softc *sc = aphy->sc; | 2510 | struct ath_softc *sc = aphy->sc; |
2511 | struct ath_hw *ah = sc->sc_ah; | ||
2512 | struct ath_common *common = ath9k_hw_common(ah); | ||
2126 | 2513 | ||
2127 | mutex_lock(&sc->mutex); | 2514 | mutex_lock(&sc->mutex); |
2128 | 2515 | ||
@@ -2137,7 +2524,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
2137 | } | 2524 | } |
2138 | 2525 | ||
2139 | if (sc->sc_flags & SC_OP_INVALID) { | 2526 | if (sc->sc_flags & SC_OP_INVALID) { |
2140 | DPRINTF(sc, ATH_DBG_ANY, "Device not present\n"); | 2527 | ath_print(common, ATH_DBG_ANY, "Device not present\n"); |
2141 | mutex_unlock(&sc->mutex); | 2528 | mutex_unlock(&sc->mutex); |
2142 | return; | 2529 | return; |
2143 | } | 2530 | } |
@@ -2147,33 +2534,33 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
2147 | return; /* another wiphy still in use */ | 2534 | return; /* another wiphy still in use */ |
2148 | } | 2535 | } |
2149 | 2536 | ||
2150 | if (sc->sc_flags & SC_OP_BTCOEX_ENABLED) { | 2537 | if (ah->btcoex_hw.enabled) { |
2151 | ath9k_hw_btcoex_disable(sc->sc_ah); | 2538 | ath9k_hw_btcoex_disable(ah); |
2152 | if (sc->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE) | 2539 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) |
2153 | ath_btcoex_timer_pause(sc, &sc->btcoex_info); | 2540 | ath9k_btcoex_timer_pause(sc); |
2154 | } | 2541 | } |
2155 | 2542 | ||
2156 | /* make sure h/w will not generate any interrupt | 2543 | /* make sure h/w will not generate any interrupt |
2157 | * before setting the invalid flag. */ | 2544 | * before setting the invalid flag. */ |
2158 | ath9k_hw_set_interrupts(sc->sc_ah, 0); | 2545 | ath9k_hw_set_interrupts(ah, 0); |
2159 | 2546 | ||
2160 | if (!(sc->sc_flags & SC_OP_INVALID)) { | 2547 | if (!(sc->sc_flags & SC_OP_INVALID)) { |
2161 | ath_drain_all_txq(sc, false); | 2548 | ath_drain_all_txq(sc, false); |
2162 | ath_stoprecv(sc); | 2549 | ath_stoprecv(sc); |
2163 | ath9k_hw_phy_disable(sc->sc_ah); | 2550 | ath9k_hw_phy_disable(ah); |
2164 | } else | 2551 | } else |
2165 | sc->rx.rxlink = NULL; | 2552 | sc->rx.rxlink = NULL; |
2166 | 2553 | ||
2167 | /* disable HAL and put h/w to sleep */ | 2554 | /* disable HAL and put h/w to sleep */ |
2168 | ath9k_hw_disable(sc->sc_ah); | 2555 | ath9k_hw_disable(ah); |
2169 | ath9k_hw_configpcipowersave(sc->sc_ah, 1, 1); | 2556 | ath9k_hw_configpcipowersave(ah, 1, 1); |
2170 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP); | 2557 | ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); |
2171 | 2558 | ||
2172 | sc->sc_flags |= SC_OP_INVALID; | 2559 | sc->sc_flags |= SC_OP_INVALID; |
2173 | 2560 | ||
2174 | mutex_unlock(&sc->mutex); | 2561 | mutex_unlock(&sc->mutex); |
2175 | 2562 | ||
2176 | DPRINTF(sc, ATH_DBG_CONFIG, "Driver halt\n"); | 2563 | ath_print(common, ATH_DBG_CONFIG, "Driver halt\n"); |
2177 | } | 2564 | } |
2178 | 2565 | ||
2179 | static int ath9k_add_interface(struct ieee80211_hw *hw, | 2566 | static int ath9k_add_interface(struct ieee80211_hw *hw, |
@@ -2181,6 +2568,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
2181 | { | 2568 | { |
2182 | struct ath_wiphy *aphy = hw->priv; | 2569 | struct ath_wiphy *aphy = hw->priv; |
2183 | struct ath_softc *sc = aphy->sc; | 2570 | struct ath_softc *sc = aphy->sc; |
2571 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
2184 | struct ath_vif *avp = (void *)conf->vif->drv_priv; | 2572 | struct ath_vif *avp = (void *)conf->vif->drv_priv; |
2185 | enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED; | 2573 | enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED; |
2186 | int ret = 0; | 2574 | int ret = 0; |
@@ -2207,13 +2595,14 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
2207 | ic_opmode = conf->type; | 2595 | ic_opmode = conf->type; |
2208 | break; | 2596 | break; |
2209 | default: | 2597 | default: |
2210 | DPRINTF(sc, ATH_DBG_FATAL, | 2598 | ath_print(common, ATH_DBG_FATAL, |
2211 | "Interface type %d not yet supported\n", conf->type); | 2599 | "Interface type %d not yet supported\n", conf->type); |
2212 | ret = -EOPNOTSUPP; | 2600 | ret = -EOPNOTSUPP; |
2213 | goto out; | 2601 | goto out; |
2214 | } | 2602 | } |
2215 | 2603 | ||
2216 | DPRINTF(sc, ATH_DBG_CONFIG, "Attach a VIF of type: %d\n", ic_opmode); | 2604 | ath_print(common, ATH_DBG_CONFIG, |
2605 | "Attach a VIF of type: %d\n", ic_opmode); | ||
2217 | 2606 | ||
2218 | /* Set the VIF opmode */ | 2607 | /* Set the VIF opmode */ |
2219 | avp->av_opmode = ic_opmode; | 2608 | avp->av_opmode = ic_opmode; |
@@ -2251,7 +2640,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
2251 | if (conf->type == NL80211_IFTYPE_AP || | 2640 | if (conf->type == NL80211_IFTYPE_AP || |
2252 | conf->type == NL80211_IFTYPE_ADHOC || | 2641 | conf->type == NL80211_IFTYPE_ADHOC || |
2253 | conf->type == NL80211_IFTYPE_MONITOR) | 2642 | conf->type == NL80211_IFTYPE_MONITOR) |
2254 | ath_start_ani(sc); | 2643 | ath_start_ani(common); |
2255 | 2644 | ||
2256 | out: | 2645 | out: |
2257 | mutex_unlock(&sc->mutex); | 2646 | mutex_unlock(&sc->mutex); |
@@ -2263,15 +2652,16 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, | |||
2263 | { | 2652 | { |
2264 | struct ath_wiphy *aphy = hw->priv; | 2653 | struct ath_wiphy *aphy = hw->priv; |
2265 | struct ath_softc *sc = aphy->sc; | 2654 | struct ath_softc *sc = aphy->sc; |
2655 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
2266 | struct ath_vif *avp = (void *)conf->vif->drv_priv; | 2656 | struct ath_vif *avp = (void *)conf->vif->drv_priv; |
2267 | int i; | 2657 | int i; |
2268 | 2658 | ||
2269 | DPRINTF(sc, ATH_DBG_CONFIG, "Detach Interface\n"); | 2659 | ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n"); |
2270 | 2660 | ||
2271 | mutex_lock(&sc->mutex); | 2661 | mutex_lock(&sc->mutex); |
2272 | 2662 | ||
2273 | /* Stop ANI */ | 2663 | /* Stop ANI */ |
2274 | del_timer_sync(&sc->ani.timer); | 2664 | del_timer_sync(&common->ani.timer); |
2275 | 2665 | ||
2276 | /* Reclaim beacon resources */ | 2666 | /* Reclaim beacon resources */ |
2277 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || | 2667 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || |
@@ -2301,27 +2691,43 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
2301 | { | 2691 | { |
2302 | struct ath_wiphy *aphy = hw->priv; | 2692 | struct ath_wiphy *aphy = hw->priv; |
2303 | struct ath_softc *sc = aphy->sc; | 2693 | struct ath_softc *sc = aphy->sc; |
2694 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
2304 | struct ieee80211_conf *conf = &hw->conf; | 2695 | struct ieee80211_conf *conf = &hw->conf; |
2305 | struct ath_hw *ah = sc->sc_ah; | 2696 | struct ath_hw *ah = sc->sc_ah; |
2306 | bool all_wiphys_idle = false, disable_radio = false; | 2697 | bool disable_radio; |
2307 | 2698 | ||
2308 | mutex_lock(&sc->mutex); | 2699 | mutex_lock(&sc->mutex); |
2309 | 2700 | ||
2310 | /* Leave this as the first check */ | 2701 | /* |
2702 | * Leave this as the first check because we need to turn on the | ||
2703 | * radio if it was disabled before prior to processing the rest | ||
2704 | * of the changes. Likewise we must only disable the radio towards | ||
2705 | * the end. | ||
2706 | */ | ||
2311 | if (changed & IEEE80211_CONF_CHANGE_IDLE) { | 2707 | if (changed & IEEE80211_CONF_CHANGE_IDLE) { |
2708 | bool enable_radio; | ||
2709 | bool all_wiphys_idle; | ||
2710 | bool idle = !!(conf->flags & IEEE80211_CONF_IDLE); | ||
2312 | 2711 | ||
2313 | spin_lock_bh(&sc->wiphy_lock); | 2712 | spin_lock_bh(&sc->wiphy_lock); |
2314 | all_wiphys_idle = ath9k_all_wiphys_idle(sc); | 2713 | all_wiphys_idle = ath9k_all_wiphys_idle(sc); |
2714 | ath9k_set_wiphy_idle(aphy, idle); | ||
2715 | |||
2716 | if (!idle && all_wiphys_idle) | ||
2717 | enable_radio = true; | ||
2718 | |||
2719 | /* | ||
2720 | * After we unlock here its possible another wiphy | ||
2721 | * can be re-renabled so to account for that we will | ||
2722 | * only disable the radio toward the end of this routine | ||
2723 | * if by then all wiphys are still idle. | ||
2724 | */ | ||
2315 | spin_unlock_bh(&sc->wiphy_lock); | 2725 | spin_unlock_bh(&sc->wiphy_lock); |
2316 | 2726 | ||
2317 | if (conf->flags & IEEE80211_CONF_IDLE){ | 2727 | if (enable_radio) { |
2318 | if (all_wiphys_idle) | 2728 | ath_radio_enable(sc, hw); |
2319 | disable_radio = true; | 2729 | ath_print(common, ATH_DBG_CONFIG, |
2320 | } | 2730 | "not-idle: enabling radio\n"); |
2321 | else if (all_wiphys_idle) { | ||
2322 | ath_radio_enable(sc); | ||
2323 | DPRINTF(sc, ATH_DBG_CONFIG, | ||
2324 | "not-idle: enabling radio\n"); | ||
2325 | } | 2731 | } |
2326 | } | 2732 | } |
2327 | 2733 | ||
@@ -2339,7 +2745,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
2339 | sc->ps_enabled = true; | 2745 | sc->ps_enabled = true; |
2340 | } else { | 2746 | } else { |
2341 | sc->ps_enabled = false; | 2747 | sc->ps_enabled = false; |
2342 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); | 2748 | ath9k_setpower(sc, ATH9K_PM_AWAKE); |
2343 | if (!(ah->caps.hw_caps & | 2749 | if (!(ah->caps.hw_caps & |
2344 | ATH9K_HW_CAP_AUTOSLEEP)) { | 2750 | ATH9K_HW_CAP_AUTOSLEEP)) { |
2345 | ath9k_hw_setrxabort(sc->sc_ah, 0); | 2751 | ath9k_hw_setrxabort(sc->sc_ah, 0); |
@@ -2374,8 +2780,8 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
2374 | goto skip_chan_change; | 2780 | goto skip_chan_change; |
2375 | } | 2781 | } |
2376 | 2782 | ||
2377 | DPRINTF(sc, ATH_DBG_CONFIG, "Set channel: %d MHz\n", | 2783 | ath_print(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n", |
2378 | curchan->center_freq); | 2784 | curchan->center_freq); |
2379 | 2785 | ||
2380 | /* XXX: remove me eventualy */ | 2786 | /* XXX: remove me eventualy */ |
2381 | ath9k_update_ichannel(sc, hw, &sc->sc_ah->channels[pos]); | 2787 | ath9k_update_ichannel(sc, hw, &sc->sc_ah->channels[pos]); |
@@ -2383,7 +2789,8 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
2383 | ath_update_chainmask(sc, conf_is_ht(conf)); | 2789 | ath_update_chainmask(sc, conf_is_ht(conf)); |
2384 | 2790 | ||
2385 | if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) { | 2791 | if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) { |
2386 | DPRINTF(sc, ATH_DBG_FATAL, "Unable to set channel\n"); | 2792 | ath_print(common, ATH_DBG_FATAL, |
2793 | "Unable to set channel\n"); | ||
2387 | mutex_unlock(&sc->mutex); | 2794 | mutex_unlock(&sc->mutex); |
2388 | return -EINVAL; | 2795 | return -EINVAL; |
2389 | } | 2796 | } |
@@ -2393,9 +2800,13 @@ skip_chan_change: | |||
2393 | if (changed & IEEE80211_CONF_CHANGE_POWER) | 2800 | if (changed & IEEE80211_CONF_CHANGE_POWER) |
2394 | sc->config.txpowlimit = 2 * conf->power_level; | 2801 | sc->config.txpowlimit = 2 * conf->power_level; |
2395 | 2802 | ||
2803 | spin_lock_bh(&sc->wiphy_lock); | ||
2804 | disable_radio = ath9k_all_wiphys_idle(sc); | ||
2805 | spin_unlock_bh(&sc->wiphy_lock); | ||
2806 | |||
2396 | if (disable_radio) { | 2807 | if (disable_radio) { |
2397 | DPRINTF(sc, ATH_DBG_CONFIG, "idle: disabling radio\n"); | 2808 | ath_print(common, ATH_DBG_CONFIG, "idle: disabling radio\n"); |
2398 | ath_radio_disable(sc); | 2809 | ath_radio_disable(sc, hw); |
2399 | } | 2810 | } |
2400 | 2811 | ||
2401 | mutex_unlock(&sc->mutex); | 2812 | mutex_unlock(&sc->mutex); |
@@ -2431,7 +2842,8 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw, | |||
2431 | ath9k_hw_setrxfilter(sc->sc_ah, rfilt); | 2842 | ath9k_hw_setrxfilter(sc->sc_ah, rfilt); |
2432 | ath9k_ps_restore(sc); | 2843 | ath9k_ps_restore(sc); |
2433 | 2844 | ||
2434 | DPRINTF(sc, ATH_DBG_CONFIG, "Set HW RX filter: 0x%x\n", rfilt); | 2845 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG, |
2846 | "Set HW RX filter: 0x%x\n", rfilt); | ||
2435 | } | 2847 | } |
2436 | 2848 | ||
2437 | static void ath9k_sta_notify(struct ieee80211_hw *hw, | 2849 | static void ath9k_sta_notify(struct ieee80211_hw *hw, |
@@ -2459,6 +2871,7 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue, | |||
2459 | { | 2871 | { |
2460 | struct ath_wiphy *aphy = hw->priv; | 2872 | struct ath_wiphy *aphy = hw->priv; |
2461 | struct ath_softc *sc = aphy->sc; | 2873 | struct ath_softc *sc = aphy->sc; |
2874 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
2462 | struct ath9k_tx_queue_info qi; | 2875 | struct ath9k_tx_queue_info qi; |
2463 | int ret = 0, qnum; | 2876 | int ret = 0, qnum; |
2464 | 2877 | ||
@@ -2475,15 +2888,15 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue, | |||
2475 | qi.tqi_burstTime = params->txop; | 2888 | qi.tqi_burstTime = params->txop; |
2476 | qnum = ath_get_hal_qnum(queue, sc); | 2889 | qnum = ath_get_hal_qnum(queue, sc); |
2477 | 2890 | ||
2478 | DPRINTF(sc, ATH_DBG_CONFIG, | 2891 | ath_print(common, ATH_DBG_CONFIG, |
2479 | "Configure tx [queue/halq] [%d/%d], " | 2892 | "Configure tx [queue/halq] [%d/%d], " |
2480 | "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", | 2893 | "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", |
2481 | queue, qnum, params->aifs, params->cw_min, | 2894 | queue, qnum, params->aifs, params->cw_min, |
2482 | params->cw_max, params->txop); | 2895 | params->cw_max, params->txop); |
2483 | 2896 | ||
2484 | ret = ath_txq_update(sc, qnum, &qi); | 2897 | ret = ath_txq_update(sc, qnum, &qi); |
2485 | if (ret) | 2898 | if (ret) |
2486 | DPRINTF(sc, ATH_DBG_FATAL, "TXQ Update failed\n"); | 2899 | ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n"); |
2487 | 2900 | ||
2488 | mutex_unlock(&sc->mutex); | 2901 | mutex_unlock(&sc->mutex); |
2489 | 2902 | ||
@@ -2498,6 +2911,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw, | |||
2498 | { | 2911 | { |
2499 | struct ath_wiphy *aphy = hw->priv; | 2912 | struct ath_wiphy *aphy = hw->priv; |
2500 | struct ath_softc *sc = aphy->sc; | 2913 | struct ath_softc *sc = aphy->sc; |
2914 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
2501 | int ret = 0; | 2915 | int ret = 0; |
2502 | 2916 | ||
2503 | if (modparam_nohwcrypt) | 2917 | if (modparam_nohwcrypt) |
@@ -2505,11 +2919,11 @@ static int ath9k_set_key(struct ieee80211_hw *hw, | |||
2505 | 2919 | ||
2506 | mutex_lock(&sc->mutex); | 2920 | mutex_lock(&sc->mutex); |
2507 | ath9k_ps_wakeup(sc); | 2921 | ath9k_ps_wakeup(sc); |
2508 | DPRINTF(sc, ATH_DBG_CONFIG, "Set HW Key\n"); | 2922 | ath_print(common, ATH_DBG_CONFIG, "Set HW Key\n"); |
2509 | 2923 | ||
2510 | switch (cmd) { | 2924 | switch (cmd) { |
2511 | case SET_KEY: | 2925 | case SET_KEY: |
2512 | ret = ath_key_config(sc, vif, sta, key); | 2926 | ret = ath_key_config(common, vif, sta, key); |
2513 | if (ret >= 0) { | 2927 | if (ret >= 0) { |
2514 | key->hw_key_idx = ret; | 2928 | key->hw_key_idx = ret; |
2515 | /* push IV and Michael MIC generation to stack */ | 2929 | /* push IV and Michael MIC generation to stack */ |
@@ -2522,7 +2936,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw, | |||
2522 | } | 2936 | } |
2523 | break; | 2937 | break; |
2524 | case DISABLE_KEY: | 2938 | case DISABLE_KEY: |
2525 | ath_key_delete(sc, key); | 2939 | ath_key_delete(common, key); |
2526 | break; | 2940 | break; |
2527 | default: | 2941 | default: |
2528 | ret = -EINVAL; | 2942 | ret = -EINVAL; |
@@ -2542,94 +2956,67 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
2542 | struct ath_wiphy *aphy = hw->priv; | 2956 | struct ath_wiphy *aphy = hw->priv; |
2543 | struct ath_softc *sc = aphy->sc; | 2957 | struct ath_softc *sc = aphy->sc; |
2544 | struct ath_hw *ah = sc->sc_ah; | 2958 | struct ath_hw *ah = sc->sc_ah; |
2959 | struct ath_common *common = ath9k_hw_common(ah); | ||
2545 | struct ath_vif *avp = (void *)vif->drv_priv; | 2960 | struct ath_vif *avp = (void *)vif->drv_priv; |
2546 | u32 rfilt = 0; | 2961 | int error; |
2547 | int error, i; | ||
2548 | 2962 | ||
2549 | mutex_lock(&sc->mutex); | 2963 | mutex_lock(&sc->mutex); |
2550 | 2964 | ||
2551 | /* | 2965 | if (changed & BSS_CHANGED_BSSID) { |
2552 | * TODO: Need to decide which hw opmode to use for | 2966 | /* Set BSSID */ |
2553 | * multi-interface cases | 2967 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); |
2554 | * XXX: This belongs into add_interface! | 2968 | memcpy(avp->bssid, bss_conf->bssid, ETH_ALEN); |
2555 | */ | 2969 | common->curaid = 0; |
2556 | if (vif->type == NL80211_IFTYPE_AP && | 2970 | ath9k_hw_write_associd(ah); |
2557 | ah->opmode != NL80211_IFTYPE_AP) { | ||
2558 | ah->opmode = NL80211_IFTYPE_STATION; | ||
2559 | ath9k_hw_setopmode(ah); | ||
2560 | memcpy(sc->curbssid, sc->sc_ah->macaddr, ETH_ALEN); | ||
2561 | sc->curaid = 0; | ||
2562 | ath9k_hw_write_associd(sc); | ||
2563 | /* Request full reset to get hw opmode changed properly */ | ||
2564 | sc->sc_flags |= SC_OP_FULL_RESET; | ||
2565 | } | ||
2566 | |||
2567 | if ((changed & BSS_CHANGED_BSSID) && | ||
2568 | !is_zero_ether_addr(bss_conf->bssid)) { | ||
2569 | switch (vif->type) { | ||
2570 | case NL80211_IFTYPE_STATION: | ||
2571 | case NL80211_IFTYPE_ADHOC: | ||
2572 | case NL80211_IFTYPE_MESH_POINT: | ||
2573 | /* Set BSSID */ | ||
2574 | memcpy(sc->curbssid, bss_conf->bssid, ETH_ALEN); | ||
2575 | memcpy(avp->bssid, bss_conf->bssid, ETH_ALEN); | ||
2576 | sc->curaid = 0; | ||
2577 | ath9k_hw_write_associd(sc); | ||
2578 | |||
2579 | /* Set aggregation protection mode parameters */ | ||
2580 | sc->config.ath_aggr_prot = 0; | ||
2581 | |||
2582 | DPRINTF(sc, ATH_DBG_CONFIG, | ||
2583 | "RX filter 0x%x bssid %pM aid 0x%x\n", | ||
2584 | rfilt, sc->curbssid, sc->curaid); | ||
2585 | |||
2586 | /* need to reconfigure the beacon */ | ||
2587 | sc->sc_flags &= ~SC_OP_BEACONS ; | ||
2588 | 2971 | ||
2589 | break; | 2972 | /* Set aggregation protection mode parameters */ |
2590 | default: | 2973 | sc->config.ath_aggr_prot = 0; |
2591 | break; | 2974 | |
2592 | } | 2975 | /* Only legacy IBSS for now */ |
2976 | if (vif->type == NL80211_IFTYPE_ADHOC) | ||
2977 | ath_update_chainmask(sc, 0); | ||
2978 | |||
2979 | ath_print(common, ATH_DBG_CONFIG, | ||
2980 | "BSSID: %pM aid: 0x%x\n", | ||
2981 | common->curbssid, common->curaid); | ||
2982 | |||
2983 | /* need to reconfigure the beacon */ | ||
2984 | sc->sc_flags &= ~SC_OP_BEACONS ; | ||
2593 | } | 2985 | } |
2594 | 2986 | ||
2595 | if ((vif->type == NL80211_IFTYPE_ADHOC) || | 2987 | /* Enable transmission of beacons (AP, IBSS, MESH) */ |
2596 | (vif->type == NL80211_IFTYPE_AP) || | 2988 | if ((changed & BSS_CHANGED_BEACON) || |
2597 | (vif->type == NL80211_IFTYPE_MESH_POINT)) { | 2989 | ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon)) { |
2598 | if ((changed & BSS_CHANGED_BEACON) || | 2990 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); |
2599 | (changed & BSS_CHANGED_BEACON_ENABLED && | 2991 | error = ath_beacon_alloc(aphy, vif); |
2600 | bss_conf->enable_beacon)) { | 2992 | if (!error) |
2601 | /* | 2993 | ath_beacon_config(sc, vif); |
2602 | * Allocate and setup the beacon frame. | 2994 | } |
2603 | * | ||
2604 | * Stop any previous beacon DMA. This may be | ||
2605 | * necessary, for example, when an ibss merge | ||
2606 | * causes reconfiguration; we may be called | ||
2607 | * with beacon transmission active. | ||
2608 | */ | ||
2609 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | ||
2610 | 2995 | ||
2996 | /* Disable transmission of beacons */ | ||
2997 | if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon) | ||
2998 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | ||
2999 | |||
3000 | if (changed & BSS_CHANGED_BEACON_INT) { | ||
3001 | sc->beacon_interval = bss_conf->beacon_int; | ||
3002 | /* | ||
3003 | * In case of AP mode, the HW TSF has to be reset | ||
3004 | * when the beacon interval changes. | ||
3005 | */ | ||
3006 | if (vif->type == NL80211_IFTYPE_AP) { | ||
3007 | sc->sc_flags |= SC_OP_TSF_RESET; | ||
3008 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | ||
2611 | error = ath_beacon_alloc(aphy, vif); | 3009 | error = ath_beacon_alloc(aphy, vif); |
2612 | if (!error) | 3010 | if (!error) |
2613 | ath_beacon_config(sc, vif); | 3011 | ath_beacon_config(sc, vif); |
3012 | } else { | ||
3013 | ath_beacon_config(sc, vif); | ||
2614 | } | 3014 | } |
2615 | } | 3015 | } |
2616 | 3016 | ||
2617 | /* Check for WLAN_CAPABILITY_PRIVACY ? */ | ||
2618 | if ((avp->av_opmode != NL80211_IFTYPE_STATION)) { | ||
2619 | for (i = 0; i < IEEE80211_WEP_NKID; i++) | ||
2620 | if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i)) | ||
2621 | ath9k_hw_keysetmac(sc->sc_ah, | ||
2622 | (u16)i, | ||
2623 | sc->curbssid); | ||
2624 | } | ||
2625 | |||
2626 | /* Only legacy IBSS for now */ | ||
2627 | if (vif->type == NL80211_IFTYPE_ADHOC) | ||
2628 | ath_update_chainmask(sc, 0); | ||
2629 | |||
2630 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { | 3017 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { |
2631 | DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n", | 3018 | ath_print(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n", |
2632 | bss_conf->use_short_preamble); | 3019 | bss_conf->use_short_preamble); |
2633 | if (bss_conf->use_short_preamble) | 3020 | if (bss_conf->use_short_preamble) |
2634 | sc->sc_flags |= SC_OP_PREAMBLE_SHORT; | 3021 | sc->sc_flags |= SC_OP_PREAMBLE_SHORT; |
2635 | else | 3022 | else |
@@ -2637,8 +3024,8 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
2637 | } | 3024 | } |
2638 | 3025 | ||
2639 | if (changed & BSS_CHANGED_ERP_CTS_PROT) { | 3026 | if (changed & BSS_CHANGED_ERP_CTS_PROT) { |
2640 | DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n", | 3027 | ath_print(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n", |
2641 | bss_conf->use_cts_prot); | 3028 | bss_conf->use_cts_prot); |
2642 | if (bss_conf->use_cts_prot && | 3029 | if (bss_conf->use_cts_prot && |
2643 | hw->conf.channel->band != IEEE80211_BAND_5GHZ) | 3030 | hw->conf.channel->band != IEEE80211_BAND_5GHZ) |
2644 | sc->sc_flags |= SC_OP_PROTECT_ENABLE; | 3031 | sc->sc_flags |= SC_OP_PROTECT_ENABLE; |
@@ -2647,23 +3034,11 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
2647 | } | 3034 | } |
2648 | 3035 | ||
2649 | if (changed & BSS_CHANGED_ASSOC) { | 3036 | if (changed & BSS_CHANGED_ASSOC) { |
2650 | DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", | 3037 | ath_print(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", |
2651 | bss_conf->assoc); | 3038 | bss_conf->assoc); |
2652 | ath9k_bss_assoc_info(sc, vif, bss_conf); | 3039 | ath9k_bss_assoc_info(sc, vif, bss_conf); |
2653 | } | 3040 | } |
2654 | 3041 | ||
2655 | /* | ||
2656 | * The HW TSF has to be reset when the beacon interval changes. | ||
2657 | * We set the flag here, and ath_beacon_config_ap() would take this | ||
2658 | * into account when it gets called through the subsequent | ||
2659 | * config_interface() call - with IFCC_BEACON in the changed field. | ||
2660 | */ | ||
2661 | |||
2662 | if (changed & BSS_CHANGED_BEACON_INT) { | ||
2663 | sc->sc_flags |= SC_OP_TSF_RESET; | ||
2664 | sc->beacon_interval = bss_conf->beacon_int; | ||
2665 | } | ||
2666 | |||
2667 | mutex_unlock(&sc->mutex); | 3042 | mutex_unlock(&sc->mutex); |
2668 | } | 3043 | } |
2669 | 3044 | ||
@@ -2696,11 +3071,16 @@ static void ath9k_reset_tsf(struct ieee80211_hw *hw) | |||
2696 | struct ath_softc *sc = aphy->sc; | 3071 | struct ath_softc *sc = aphy->sc; |
2697 | 3072 | ||
2698 | mutex_lock(&sc->mutex); | 3073 | mutex_lock(&sc->mutex); |
3074 | |||
3075 | ath9k_ps_wakeup(sc); | ||
2699 | ath9k_hw_reset_tsf(sc->sc_ah); | 3076 | ath9k_hw_reset_tsf(sc->sc_ah); |
3077 | ath9k_ps_restore(sc); | ||
3078 | |||
2700 | mutex_unlock(&sc->mutex); | 3079 | mutex_unlock(&sc->mutex); |
2701 | } | 3080 | } |
2702 | 3081 | ||
2703 | static int ath9k_ampdu_action(struct ieee80211_hw *hw, | 3082 | static int ath9k_ampdu_action(struct ieee80211_hw *hw, |
3083 | struct ieee80211_vif *vif, | ||
2704 | enum ieee80211_ampdu_mlme_action action, | 3084 | enum ieee80211_ampdu_mlme_action action, |
2705 | struct ieee80211_sta *sta, | 3085 | struct ieee80211_sta *sta, |
2706 | u16 tid, u16 *ssn) | 3086 | u16 tid, u16 *ssn) |
@@ -2718,17 +3098,18 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, | |||
2718 | break; | 3098 | break; |
2719 | case IEEE80211_AMPDU_TX_START: | 3099 | case IEEE80211_AMPDU_TX_START: |
2720 | ath_tx_aggr_start(sc, sta, tid, ssn); | 3100 | ath_tx_aggr_start(sc, sta, tid, ssn); |
2721 | ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid); | 3101 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
2722 | break; | 3102 | break; |
2723 | case IEEE80211_AMPDU_TX_STOP: | 3103 | case IEEE80211_AMPDU_TX_STOP: |
2724 | ath_tx_aggr_stop(sc, sta, tid); | 3104 | ath_tx_aggr_stop(sc, sta, tid); |
2725 | ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid); | 3105 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
2726 | break; | 3106 | break; |
2727 | case IEEE80211_AMPDU_TX_OPERATIONAL: | 3107 | case IEEE80211_AMPDU_TX_OPERATIONAL: |
2728 | ath_tx_aggr_resume(sc, sta, tid); | 3108 | ath_tx_aggr_resume(sc, sta, tid); |
2729 | break; | 3109 | break; |
2730 | default: | 3110 | default: |
2731 | DPRINTF(sc, ATH_DBG_FATAL, "Unknown AMPDU action\n"); | 3111 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, |
3112 | "Unknown AMPDU action\n"); | ||
2732 | } | 3113 | } |
2733 | 3114 | ||
2734 | return ret; | 3115 | return ret; |
@@ -2796,64 +3177,6 @@ struct ieee80211_ops ath9k_ops = { | |||
2796 | .rfkill_poll = ath9k_rfkill_poll_state, | 3177 | .rfkill_poll = ath9k_rfkill_poll_state, |
2797 | }; | 3178 | }; |
2798 | 3179 | ||
2799 | static struct { | ||
2800 | u32 version; | ||
2801 | const char * name; | ||
2802 | } ath_mac_bb_names[] = { | ||
2803 | { AR_SREV_VERSION_5416_PCI, "5416" }, | ||
2804 | { AR_SREV_VERSION_5416_PCIE, "5418" }, | ||
2805 | { AR_SREV_VERSION_9100, "9100" }, | ||
2806 | { AR_SREV_VERSION_9160, "9160" }, | ||
2807 | { AR_SREV_VERSION_9280, "9280" }, | ||
2808 | { AR_SREV_VERSION_9285, "9285" }, | ||
2809 | { AR_SREV_VERSION_9287, "9287" } | ||
2810 | }; | ||
2811 | |||
2812 | static struct { | ||
2813 | u16 version; | ||
2814 | const char * name; | ||
2815 | } ath_rf_names[] = { | ||
2816 | { 0, "5133" }, | ||
2817 | { AR_RAD5133_SREV_MAJOR, "5133" }, | ||
2818 | { AR_RAD5122_SREV_MAJOR, "5122" }, | ||
2819 | { AR_RAD2133_SREV_MAJOR, "2133" }, | ||
2820 | { AR_RAD2122_SREV_MAJOR, "2122" } | ||
2821 | }; | ||
2822 | |||
2823 | /* | ||
2824 | * Return the MAC/BB name. "????" is returned if the MAC/BB is unknown. | ||
2825 | */ | ||
2826 | const char * | ||
2827 | ath_mac_bb_name(u32 mac_bb_version) | ||
2828 | { | ||
2829 | int i; | ||
2830 | |||
2831 | for (i=0; i<ARRAY_SIZE(ath_mac_bb_names); i++) { | ||
2832 | if (ath_mac_bb_names[i].version == mac_bb_version) { | ||
2833 | return ath_mac_bb_names[i].name; | ||
2834 | } | ||
2835 | } | ||
2836 | |||
2837 | return "????"; | ||
2838 | } | ||
2839 | |||
2840 | /* | ||
2841 | * Return the RF name. "????" is returned if the RF is unknown. | ||
2842 | */ | ||
2843 | const char * | ||
2844 | ath_rf_name(u16 rf_version) | ||
2845 | { | ||
2846 | int i; | ||
2847 | |||
2848 | for (i=0; i<ARRAY_SIZE(ath_rf_names); i++) { | ||
2849 | if (ath_rf_names[i].version == rf_version) { | ||
2850 | return ath_rf_names[i].name; | ||
2851 | } | ||
2852 | } | ||
2853 | |||
2854 | return "????"; | ||
2855 | } | ||
2856 | |||
2857 | static int __init ath9k_init(void) | 3180 | static int __init ath9k_init(void) |
2858 | { | 3181 | { |
2859 | int error; | 3182 | int error; |