diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/main.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 255 |
1 files changed, 17 insertions, 238 deletions
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index abfa0493236f..b8b76dd2c11e 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -520,6 +520,12 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
520 | !(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA))) | 520 | !(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA))) |
521 | goto chip_reset; | 521 | goto chip_reset; |
522 | 522 | ||
523 | if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) && | ||
524 | (status & ATH9K_INT_BB_WATCHDOG)) { | ||
525 | ar9003_hw_bb_watchdog_dbg_info(ah); | ||
526 | goto chip_reset; | ||
527 | } | ||
528 | |||
523 | if (status & ATH9K_INT_SWBA) | 529 | if (status & ATH9K_INT_SWBA) |
524 | tasklet_schedule(&sc->bcon_tasklet); | 530 | tasklet_schedule(&sc->bcon_tasklet); |
525 | 531 | ||
@@ -615,234 +621,6 @@ static u32 ath_get_extchanmode(struct ath_softc *sc, | |||
615 | return chanmode; | 621 | return chanmode; |
616 | } | 622 | } |
617 | 623 | ||
618 | static int ath_setkey_tkip(struct ath_common *common, u16 keyix, const u8 *key, | ||
619 | struct ath9k_keyval *hk, const u8 *addr, | ||
620 | bool authenticator) | ||
621 | { | ||
622 | struct ath_hw *ah = common->ah; | ||
623 | const u8 *key_rxmic; | ||
624 | const u8 *key_txmic; | ||
625 | |||
626 | key_txmic = key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY; | ||
627 | key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY; | ||
628 | |||
629 | if (addr == NULL) { | ||
630 | /* | ||
631 | * Group key installation - only two key cache entries are used | ||
632 | * regardless of splitmic capability since group key is only | ||
633 | * used either for TX or RX. | ||
634 | */ | ||
635 | if (authenticator) { | ||
636 | memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic)); | ||
637 | memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_mic)); | ||
638 | } else { | ||
639 | memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); | ||
640 | memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic)); | ||
641 | } | ||
642 | return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr); | ||
643 | } | ||
644 | if (!common->splitmic) { | ||
645 | /* TX and RX keys share the same key cache entry. */ | ||
646 | memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); | ||
647 | memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic)); | ||
648 | return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr); | ||
649 | } | ||
650 | |||
651 | /* Separate key cache entries for TX and RX */ | ||
652 | |||
653 | /* TX key goes at first index, RX key at +32. */ | ||
654 | memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic)); | ||
655 | if (!ath9k_hw_set_keycache_entry(ah, keyix, hk, NULL)) { | ||
656 | /* TX MIC entry failed. No need to proceed further */ | ||
657 | ath_print(common, ATH_DBG_FATAL, | ||
658 | "Setting TX MIC Key Failed\n"); | ||
659 | return 0; | ||
660 | } | ||
661 | |||
662 | memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); | ||
663 | /* XXX delete tx key on failure? */ | ||
664 | return ath9k_hw_set_keycache_entry(ah, keyix + 32, hk, addr); | ||
665 | } | ||
666 | |||
667 | static int ath_reserve_key_cache_slot_tkip(struct ath_common *common) | ||
668 | { | ||
669 | int i; | ||
670 | |||
671 | for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) { | ||
672 | if (test_bit(i, common->keymap) || | ||
673 | test_bit(i + 64, common->keymap)) | ||
674 | continue; /* At least one part of TKIP key allocated */ | ||
675 | if (common->splitmic && | ||
676 | (test_bit(i + 32, common->keymap) || | ||
677 | test_bit(i + 64 + 32, common->keymap))) | ||
678 | continue; /* At least one part of TKIP key allocated */ | ||
679 | |||
680 | /* Found a free slot for a TKIP key */ | ||
681 | return i; | ||
682 | } | ||
683 | return -1; | ||
684 | } | ||
685 | |||
686 | static int ath_reserve_key_cache_slot(struct ath_common *common) | ||
687 | { | ||
688 | int i; | ||
689 | |||
690 | /* First, try to find slots that would not be available for TKIP. */ | ||
691 | if (common->splitmic) { | ||
692 | for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) { | ||
693 | if (!test_bit(i, common->keymap) && | ||
694 | (test_bit(i + 32, common->keymap) || | ||
695 | test_bit(i + 64, common->keymap) || | ||
696 | test_bit(i + 64 + 32, common->keymap))) | ||
697 | return i; | ||
698 | if (!test_bit(i + 32, common->keymap) && | ||
699 | (test_bit(i, common->keymap) || | ||
700 | test_bit(i + 64, common->keymap) || | ||
701 | test_bit(i + 64 + 32, common->keymap))) | ||
702 | return i + 32; | ||
703 | if (!test_bit(i + 64, common->keymap) && | ||
704 | (test_bit(i , common->keymap) || | ||
705 | test_bit(i + 32, common->keymap) || | ||
706 | test_bit(i + 64 + 32, common->keymap))) | ||
707 | return i + 64; | ||
708 | if (!test_bit(i + 64 + 32, common->keymap) && | ||
709 | (test_bit(i, common->keymap) || | ||
710 | test_bit(i + 32, common->keymap) || | ||
711 | test_bit(i + 64, common->keymap))) | ||
712 | return i + 64 + 32; | ||
713 | } | ||
714 | } else { | ||
715 | for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) { | ||
716 | if (!test_bit(i, common->keymap) && | ||
717 | test_bit(i + 64, common->keymap)) | ||
718 | return i; | ||
719 | if (test_bit(i, common->keymap) && | ||
720 | !test_bit(i + 64, common->keymap)) | ||
721 | return i + 64; | ||
722 | } | ||
723 | } | ||
724 | |||
725 | /* No partially used TKIP slots, pick any available slot */ | ||
726 | for (i = IEEE80211_WEP_NKID; i < common->keymax; i++) { | ||
727 | /* Do not allow slots that could be needed for TKIP group keys | ||
728 | * to be used. This limitation could be removed if we know that | ||
729 | * TKIP will not be used. */ | ||
730 | if (i >= 64 && i < 64 + IEEE80211_WEP_NKID) | ||
731 | continue; | ||
732 | if (common->splitmic) { | ||
733 | if (i >= 32 && i < 32 + IEEE80211_WEP_NKID) | ||
734 | continue; | ||
735 | if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID) | ||
736 | continue; | ||
737 | } | ||
738 | |||
739 | if (!test_bit(i, common->keymap)) | ||
740 | return i; /* Found a free slot for a key */ | ||
741 | } | ||
742 | |||
743 | /* No free slot found */ | ||
744 | return -1; | ||
745 | } | ||
746 | |||
747 | static int ath_key_config(struct ath_common *common, | ||
748 | struct ieee80211_vif *vif, | ||
749 | struct ieee80211_sta *sta, | ||
750 | struct ieee80211_key_conf *key) | ||
751 | { | ||
752 | struct ath_hw *ah = common->ah; | ||
753 | struct ath9k_keyval hk; | ||
754 | const u8 *mac = NULL; | ||
755 | int ret = 0; | ||
756 | int idx; | ||
757 | |||
758 | memset(&hk, 0, sizeof(hk)); | ||
759 | |||
760 | switch (key->alg) { | ||
761 | case ALG_WEP: | ||
762 | hk.kv_type = ATH9K_CIPHER_WEP; | ||
763 | break; | ||
764 | case ALG_TKIP: | ||
765 | hk.kv_type = ATH9K_CIPHER_TKIP; | ||
766 | break; | ||
767 | case ALG_CCMP: | ||
768 | hk.kv_type = ATH9K_CIPHER_AES_CCM; | ||
769 | break; | ||
770 | default: | ||
771 | return -EOPNOTSUPP; | ||
772 | } | ||
773 | |||
774 | hk.kv_len = key->keylen; | ||
775 | memcpy(hk.kv_val, key->key, key->keylen); | ||
776 | |||
777 | if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { | ||
778 | /* For now, use the default keys for broadcast keys. This may | ||
779 | * need to change with virtual interfaces. */ | ||
780 | idx = key->keyidx; | ||
781 | } else if (key->keyidx) { | ||
782 | if (WARN_ON(!sta)) | ||
783 | return -EOPNOTSUPP; | ||
784 | mac = sta->addr; | ||
785 | |||
786 | if (vif->type != NL80211_IFTYPE_AP) { | ||
787 | /* Only keyidx 0 should be used with unicast key, but | ||
788 | * allow this for client mode for now. */ | ||
789 | idx = key->keyidx; | ||
790 | } else | ||
791 | return -EIO; | ||
792 | } else { | ||
793 | if (WARN_ON(!sta)) | ||
794 | return -EOPNOTSUPP; | ||
795 | mac = sta->addr; | ||
796 | |||
797 | if (key->alg == ALG_TKIP) | ||
798 | idx = ath_reserve_key_cache_slot_tkip(common); | ||
799 | else | ||
800 | idx = ath_reserve_key_cache_slot(common); | ||
801 | if (idx < 0) | ||
802 | return -ENOSPC; /* no free key cache entries */ | ||
803 | } | ||
804 | |||
805 | if (key->alg == ALG_TKIP) | ||
806 | ret = ath_setkey_tkip(common, idx, key->key, &hk, mac, | ||
807 | vif->type == NL80211_IFTYPE_AP); | ||
808 | else | ||
809 | ret = ath9k_hw_set_keycache_entry(ah, idx, &hk, mac); | ||
810 | |||
811 | if (!ret) | ||
812 | return -EIO; | ||
813 | |||
814 | set_bit(idx, common->keymap); | ||
815 | if (key->alg == ALG_TKIP) { | ||
816 | set_bit(idx + 64, common->keymap); | ||
817 | if (common->splitmic) { | ||
818 | set_bit(idx + 32, common->keymap); | ||
819 | set_bit(idx + 64 + 32, common->keymap); | ||
820 | } | ||
821 | } | ||
822 | |||
823 | return idx; | ||
824 | } | ||
825 | |||
826 | static void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key) | ||
827 | { | ||
828 | struct ath_hw *ah = common->ah; | ||
829 | |||
830 | ath9k_hw_keyreset(ah, key->hw_key_idx); | ||
831 | if (key->hw_key_idx < IEEE80211_WEP_NKID) | ||
832 | return; | ||
833 | |||
834 | clear_bit(key->hw_key_idx, common->keymap); | ||
835 | if (key->alg != ALG_TKIP) | ||
836 | return; | ||
837 | |||
838 | clear_bit(key->hw_key_idx + 64, common->keymap); | ||
839 | if (common->splitmic) { | ||
840 | ath9k_hw_keyreset(ah, key->hw_key_idx + 32); | ||
841 | clear_bit(key->hw_key_idx + 32, common->keymap); | ||
842 | clear_bit(key->hw_key_idx + 64 + 32, common->keymap); | ||
843 | } | ||
844 | } | ||
845 | |||
846 | static void ath9k_bss_assoc_info(struct ath_softc *sc, | 624 | static void ath9k_bss_assoc_info(struct ath_softc *sc, |
847 | struct ieee80211_vif *vif, | 625 | struct ieee80211_vif *vif, |
848 | struct ieee80211_bss_conf *bss_conf) | 626 | struct ieee80211_bss_conf *bss_conf) |
@@ -1195,7 +973,9 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1195 | ATH9K_INT_GLOBAL; | 973 | ATH9K_INT_GLOBAL; |
1196 | 974 | ||
1197 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | 975 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) |
1198 | ah->imask |= ATH9K_INT_RXHP | ATH9K_INT_RXLP; | 976 | ah->imask |= ATH9K_INT_RXHP | |
977 | ATH9K_INT_RXLP | | ||
978 | ATH9K_INT_BB_WATCHDOG; | ||
1199 | else | 979 | else |
1200 | ah->imask |= ATH9K_INT_RX; | 980 | ah->imask |= ATH9K_INT_RX; |
1201 | 981 | ||
@@ -1245,6 +1025,7 @@ static int ath9k_tx(struct ieee80211_hw *hw, | |||
1245 | struct ath_tx_control txctl; | 1025 | struct ath_tx_control txctl; |
1246 | int padpos, padsize; | 1026 | int padpos, padsize; |
1247 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 1027 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
1028 | int qnum; | ||
1248 | 1029 | ||
1249 | if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) { | 1030 | if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) { |
1250 | ath_print(common, ATH_DBG_XMIT, | 1031 | ath_print(common, ATH_DBG_XMIT, |
@@ -1274,7 +1055,8 @@ static int ath9k_tx(struct ieee80211_hw *hw, | |||
1274 | * completed and if needed, also for RX of buffered frames. | 1055 | * completed and if needed, also for RX of buffered frames. |
1275 | */ | 1056 | */ |
1276 | ath9k_ps_wakeup(sc); | 1057 | ath9k_ps_wakeup(sc); |
1277 | ath9k_hw_setrxabort(sc->sc_ah, 0); | 1058 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) |
1059 | ath9k_hw_setrxabort(sc->sc_ah, 0); | ||
1278 | if (ieee80211_is_pspoll(hdr->frame_control)) { | 1060 | if (ieee80211_is_pspoll(hdr->frame_control)) { |
1279 | ath_print(common, ATH_DBG_PS, | 1061 | ath_print(common, ATH_DBG_PS, |
1280 | "Sending PS-Poll to pick a buffered frame\n"); | 1062 | "Sending PS-Poll to pick a buffered frame\n"); |
@@ -1316,11 +1098,8 @@ static int ath9k_tx(struct ieee80211_hw *hw, | |||
1316 | memmove(skb->data, skb->data + padsize, padpos); | 1098 | memmove(skb->data, skb->data + padsize, padpos); |
1317 | } | 1099 | } |
1318 | 1100 | ||
1319 | /* Check if a tx queue is available */ | 1101 | qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc); |
1320 | 1102 | txctl.txq = &sc->tx.txq[qnum]; | |
1321 | txctl.txq = ath_test_get_txq(sc, skb); | ||
1322 | if (!txctl.txq) | ||
1323 | goto exit; | ||
1324 | 1103 | ||
1325 | ath_print(common, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb); | 1104 | ath_print(common, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb); |
1326 | 1105 | ||
@@ -1538,8 +1317,8 @@ void ath9k_enable_ps(struct ath_softc *sc) | |||
1538 | ah->imask |= ATH9K_INT_TIM_TIMER; | 1317 | ah->imask |= ATH9K_INT_TIM_TIMER; |
1539 | ath9k_hw_set_interrupts(ah, ah->imask); | 1318 | ath9k_hw_set_interrupts(ah, ah->imask); |
1540 | } | 1319 | } |
1320 | ath9k_hw_setrxabort(ah, 1); | ||
1541 | } | 1321 | } |
1542 | ath9k_hw_setrxabort(ah, 1); | ||
1543 | } | 1322 | } |
1544 | 1323 | ||
1545 | static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | 1324 | static int ath9k_config(struct ieee80211_hw *hw, u32 changed) |
@@ -1804,7 +1583,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw, | |||
1804 | 1583 | ||
1805 | switch (cmd) { | 1584 | switch (cmd) { |
1806 | case SET_KEY: | 1585 | case SET_KEY: |
1807 | ret = ath_key_config(common, vif, sta, key); | 1586 | ret = ath9k_cmn_key_config(common, vif, sta, key); |
1808 | if (ret >= 0) { | 1587 | if (ret >= 0) { |
1809 | key->hw_key_idx = ret; | 1588 | key->hw_key_idx = ret; |
1810 | /* push IV and Michael MIC generation to stack */ | 1589 | /* push IV and Michael MIC generation to stack */ |
@@ -1817,7 +1596,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw, | |||
1817 | } | 1596 | } |
1818 | break; | 1597 | break; |
1819 | case DISABLE_KEY: | 1598 | case DISABLE_KEY: |
1820 | ath_key_delete(common, key); | 1599 | ath9k_cmn_key_delete(common, key); |
1821 | break; | 1600 | break; |
1822 | default: | 1601 | default: |
1823 | ret = -EINVAL; | 1602 | ret = -EINVAL; |