diff options
author | John W. Linville <linville@tuxdriver.com> | 2010-04-23 14:43:45 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-04-23 14:43:45 -0400 |
commit | 3b51cc996e81d8a113416d8094fa4a88f8360a51 (patch) | |
tree | e75b98b228bb4e456c30673fcc4b56ffa1d09cf5 /drivers/net/wireless/ath/ath9k/main.c | |
parent | c68ed255265968c3948fa2678bf59d15c471b055 (diff) | |
parent | 672724403b42da1d276c6cf811e8e34d15efd964 (diff) |
Merge branch 'master' into for-davem
Conflicts:
drivers/net/wireless/ath/ath9k/phy.c
drivers/net/wireless/iwlwifi/iwl-6000.c
drivers/net/wireless/iwlwifi/iwl-debugfs.c
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/main.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 82 |
1 files changed, 69 insertions, 13 deletions
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index f7ef11407e27..aad370a7f95b 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -401,23 +401,41 @@ void ath9k_tasklet(unsigned long data) | |||
401 | struct ath_common *common = ath9k_hw_common(ah); | 401 | struct ath_common *common = ath9k_hw_common(ah); |
402 | 402 | ||
403 | u32 status = sc->intrstatus; | 403 | u32 status = sc->intrstatus; |
404 | u32 rxmask; | ||
404 | 405 | ||
405 | ath9k_ps_wakeup(sc); | 406 | ath9k_ps_wakeup(sc); |
406 | 407 | ||
407 | if (status & ATH9K_INT_FATAL) { | 408 | if ((status & ATH9K_INT_FATAL) || |
409 | !ath9k_hw_check_alive(ah)) { | ||
408 | ath_reset(sc, false); | 410 | ath_reset(sc, false); |
409 | ath9k_ps_restore(sc); | 411 | ath9k_ps_restore(sc); |
410 | return; | 412 | return; |
411 | } | 413 | } |
412 | 414 | ||
413 | if (status & (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN)) { | 415 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) |
416 | rxmask = (ATH9K_INT_RXHP | ATH9K_INT_RXLP | ATH9K_INT_RXEOL | | ||
417 | ATH9K_INT_RXORN); | ||
418 | else | ||
419 | rxmask = (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN); | ||
420 | |||
421 | if (status & rxmask) { | ||
414 | spin_lock_bh(&sc->rx.rxflushlock); | 422 | spin_lock_bh(&sc->rx.rxflushlock); |
415 | ath_rx_tasklet(sc, 0); | 423 | |
424 | /* Check for high priority Rx first */ | ||
425 | if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) && | ||
426 | (status & ATH9K_INT_RXHP)) | ||
427 | ath_rx_tasklet(sc, 0, true); | ||
428 | |||
429 | ath_rx_tasklet(sc, 0, false); | ||
416 | spin_unlock_bh(&sc->rx.rxflushlock); | 430 | spin_unlock_bh(&sc->rx.rxflushlock); |
417 | } | 431 | } |
418 | 432 | ||
419 | if (status & ATH9K_INT_TX) | 433 | if (status & ATH9K_INT_TX) { |
420 | ath_tx_tasklet(sc); | 434 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) |
435 | ath_tx_edma_tasklet(sc); | ||
436 | else | ||
437 | ath_tx_tasklet(sc); | ||
438 | } | ||
421 | 439 | ||
422 | if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) { | 440 | if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) { |
423 | /* | 441 | /* |
@@ -445,6 +463,8 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
445 | ATH9K_INT_RXORN | \ | 463 | ATH9K_INT_RXORN | \ |
446 | ATH9K_INT_RXEOL | \ | 464 | ATH9K_INT_RXEOL | \ |
447 | ATH9K_INT_RX | \ | 465 | ATH9K_INT_RX | \ |
466 | ATH9K_INT_RXLP | \ | ||
467 | ATH9K_INT_RXHP | \ | ||
448 | ATH9K_INT_TX | \ | 468 | ATH9K_INT_TX | \ |
449 | ATH9K_INT_BMISS | \ | 469 | ATH9K_INT_BMISS | \ |
450 | ATH9K_INT_CST | \ | 470 | ATH9K_INT_CST | \ |
@@ -496,7 +516,8 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
496 | * If a FATAL or RXORN interrupt is received, we have to reset the | 516 | * If a FATAL or RXORN interrupt is received, we have to reset the |
497 | * chip immediately. | 517 | * chip immediately. |
498 | */ | 518 | */ |
499 | if (status & (ATH9K_INT_FATAL | ATH9K_INT_RXORN)) | 519 | if ((status & ATH9K_INT_FATAL) || ((status & ATH9K_INT_RXORN) && |
520 | !(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA))) | ||
500 | goto chip_reset; | 521 | goto chip_reset; |
501 | 522 | ||
502 | if (status & ATH9K_INT_SWBA) | 523 | if (status & ATH9K_INT_SWBA) |
@@ -505,6 +526,13 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
505 | if (status & ATH9K_INT_TXURN) | 526 | if (status & ATH9K_INT_TXURN) |
506 | ath9k_hw_updatetxtriglevel(ah, true); | 527 | ath9k_hw_updatetxtriglevel(ah, true); |
507 | 528 | ||
529 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { | ||
530 | if (status & ATH9K_INT_RXEOL) { | ||
531 | ah->imask &= ~(ATH9K_INT_RXEOL | ATH9K_INT_RXORN); | ||
532 | ath9k_hw_set_interrupts(ah, ah->imask); | ||
533 | } | ||
534 | } | ||
535 | |||
508 | if (status & ATH9K_INT_MIB) { | 536 | if (status & ATH9K_INT_MIB) { |
509 | /* | 537 | /* |
510 | * Disable interrupts until we service the MIB | 538 | * Disable interrupts until we service the MIB |
@@ -724,6 +752,7 @@ static int ath_key_config(struct ath_common *common, | |||
724 | struct ath_hw *ah = common->ah; | 752 | struct ath_hw *ah = common->ah; |
725 | struct ath9k_keyval hk; | 753 | struct ath9k_keyval hk; |
726 | const u8 *mac = NULL; | 754 | const u8 *mac = NULL; |
755 | u8 gmac[ETH_ALEN]; | ||
727 | int ret = 0; | 756 | int ret = 0; |
728 | int idx; | 757 | int idx; |
729 | 758 | ||
@@ -747,9 +776,30 @@ static int ath_key_config(struct ath_common *common, | |||
747 | memcpy(hk.kv_val, key->key, key->keylen); | 776 | memcpy(hk.kv_val, key->key, key->keylen); |
748 | 777 | ||
749 | if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { | 778 | if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { |
750 | /* For now, use the default keys for broadcast keys. This may | 779 | |
751 | * need to change with virtual interfaces. */ | 780 | if (key->ap_addr) { |
752 | idx = key->keyidx; | 781 | /* |
782 | * Group keys on hardware that supports multicast frame | ||
783 | * key search use a mac that is the sender's address with | ||
784 | * the high bit set instead of the app-specified address. | ||
785 | */ | ||
786 | memcpy(gmac, key->ap_addr, ETH_ALEN); | ||
787 | gmac[0] |= 0x80; | ||
788 | mac = gmac; | ||
789 | |||
790 | if (key->alg == ALG_TKIP) | ||
791 | idx = ath_reserve_key_cache_slot_tkip(common); | ||
792 | else | ||
793 | idx = ath_reserve_key_cache_slot(common); | ||
794 | if (idx < 0) | ||
795 | mac = NULL; /* no free key cache entries */ | ||
796 | } | ||
797 | |||
798 | if (!mac) { | ||
799 | /* For now, use the default keys for broadcast keys. This may | ||
800 | * need to change with virtual interfaces. */ | ||
801 | idx = key->keyidx; | ||
802 | } | ||
753 | } else if (key->keyidx) { | 803 | } else if (key->keyidx) { |
754 | if (WARN_ON(!sta)) | 804 | if (WARN_ON(!sta)) |
755 | return -EOPNOTSUPP; | 805 | return -EOPNOTSUPP; |
@@ -1162,9 +1212,14 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1162 | } | 1212 | } |
1163 | 1213 | ||
1164 | /* Setup our intr mask. */ | 1214 | /* Setup our intr mask. */ |
1165 | ah->imask = ATH9K_INT_RX | ATH9K_INT_TX | 1215 | ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL | |
1166 | | ATH9K_INT_RXEOL | ATH9K_INT_RXORN | 1216 | ATH9K_INT_RXORN | ATH9K_INT_FATAL | |
1167 | | ATH9K_INT_FATAL | ATH9K_INT_GLOBAL; | 1217 | ATH9K_INT_GLOBAL; |
1218 | |||
1219 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | ||
1220 | ah->imask |= ATH9K_INT_RXHP | ATH9K_INT_RXLP; | ||
1221 | else | ||
1222 | ah->imask |= ATH9K_INT_RX; | ||
1168 | 1223 | ||
1169 | if (ah->caps.hw_caps & ATH9K_HW_CAP_GTT) | 1224 | if (ah->caps.hw_caps & ATH9K_HW_CAP_GTT) |
1170 | ah->imask |= ATH9K_INT_GTT; | 1225 | ah->imask |= ATH9K_INT_GTT; |
@@ -1436,7 +1491,8 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
1436 | if ((vif->type == NL80211_IFTYPE_STATION) || | 1491 | if ((vif->type == NL80211_IFTYPE_STATION) || |
1437 | (vif->type == NL80211_IFTYPE_ADHOC) || | 1492 | (vif->type == NL80211_IFTYPE_ADHOC) || |
1438 | (vif->type == NL80211_IFTYPE_MESH_POINT)) { | 1493 | (vif->type == NL80211_IFTYPE_MESH_POINT)) { |
1439 | ah->imask |= ATH9K_INT_MIB; | 1494 | if (ah->config.enable_ani) |
1495 | ah->imask |= ATH9K_INT_MIB; | ||
1440 | ah->imask |= ATH9K_INT_TSFOOR; | 1496 | ah->imask |= ATH9K_INT_TSFOOR; |
1441 | } | 1497 | } |
1442 | 1498 | ||