aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/main.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c82
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