aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2010-05-25 13:42:46 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-06-03 14:10:44 -0400
commit1f03baad4d0516f4bd3a4728d71ff00b01be930d (patch)
treeafecbf71bc230a3a2d0f2fa2d4bcf7b94bf278d5
parenteed8e22f0133e8278b1f8079fcb452f1f9692f9d (diff)
ath9k: use the key handling code from ath9k_common instead of duplicating it
Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c232
1 files changed, 2 insertions, 230 deletions
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index d6e8be0999bc..120708d51d45 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -621,234 +621,6 @@ static u32 ath_get_extchanmode(struct ath_softc *sc,
621 return chanmode; 621 return chanmode;
622} 622}
623 623
624static int ath_setkey_tkip(struct ath_common *common, u16 keyix, const u8 *key,
625 struct ath9k_keyval *hk, const u8 *addr,
626 bool authenticator)
627{
628 struct ath_hw *ah = common->ah;
629 const u8 *key_rxmic;
630 const u8 *key_txmic;
631
632 key_txmic = key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY;
633 key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
634
635 if (addr == NULL) {
636 /*
637 * Group key installation - only two key cache entries are used
638 * regardless of splitmic capability since group key is only
639 * used either for TX or RX.
640 */
641 if (authenticator) {
642 memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
643 memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_mic));
644 } else {
645 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
646 memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic));
647 }
648 return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr);
649 }
650 if (!common->splitmic) {
651 /* TX and RX keys share the same key cache entry. */
652 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
653 memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic));
654 return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr);
655 }
656
657 /* Separate key cache entries for TX and RX */
658
659 /* TX key goes at first index, RX key at +32. */
660 memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
661 if (!ath9k_hw_set_keycache_entry(ah, keyix, hk, NULL)) {
662 /* TX MIC entry failed. No need to proceed further */
663 ath_print(common, ATH_DBG_FATAL,
664 "Setting TX MIC Key Failed\n");
665 return 0;
666 }
667
668 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
669 /* XXX delete tx key on failure? */
670 return ath9k_hw_set_keycache_entry(ah, keyix + 32, hk, addr);
671}
672
673static int ath_reserve_key_cache_slot_tkip(struct ath_common *common)
674{
675 int i;
676
677 for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) {
678 if (test_bit(i, common->keymap) ||
679 test_bit(i + 64, common->keymap))
680 continue; /* At least one part of TKIP key allocated */
681 if (common->splitmic &&
682 (test_bit(i + 32, common->keymap) ||
683 test_bit(i + 64 + 32, common->keymap)))
684 continue; /* At least one part of TKIP key allocated */
685
686 /* Found a free slot for a TKIP key */
687 return i;
688 }
689 return -1;
690}
691
692static int ath_reserve_key_cache_slot(struct ath_common *common)
693{
694 int i;
695
696 /* First, try to find slots that would not be available for TKIP. */
697 if (common->splitmic) {
698 for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) {
699 if (!test_bit(i, common->keymap) &&
700 (test_bit(i + 32, common->keymap) ||
701 test_bit(i + 64, common->keymap) ||
702 test_bit(i + 64 + 32, common->keymap)))
703 return i;
704 if (!test_bit(i + 32, common->keymap) &&
705 (test_bit(i, common->keymap) ||
706 test_bit(i + 64, common->keymap) ||
707 test_bit(i + 64 + 32, common->keymap)))
708 return i + 32;
709 if (!test_bit(i + 64, common->keymap) &&
710 (test_bit(i , common->keymap) ||
711 test_bit(i + 32, common->keymap) ||
712 test_bit(i + 64 + 32, common->keymap)))
713 return i + 64;
714 if (!test_bit(i + 64 + 32, common->keymap) &&
715 (test_bit(i, common->keymap) ||
716 test_bit(i + 32, common->keymap) ||
717 test_bit(i + 64, common->keymap)))
718 return i + 64 + 32;
719 }
720 } else {
721 for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) {
722 if (!test_bit(i, common->keymap) &&
723 test_bit(i + 64, common->keymap))
724 return i;
725 if (test_bit(i, common->keymap) &&
726 !test_bit(i + 64, common->keymap))
727 return i + 64;
728 }
729 }
730
731 /* No partially used TKIP slots, pick any available slot */
732 for (i = IEEE80211_WEP_NKID; i < common->keymax; i++) {
733 /* Do not allow slots that could be needed for TKIP group keys
734 * to be used. This limitation could be removed if we know that
735 * TKIP will not be used. */
736 if (i >= 64 && i < 64 + IEEE80211_WEP_NKID)
737 continue;
738 if (common->splitmic) {
739 if (i >= 32 && i < 32 + IEEE80211_WEP_NKID)
740 continue;
741 if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID)
742 continue;
743 }
744
745 if (!test_bit(i, common->keymap))
746 return i; /* Found a free slot for a key */
747 }
748
749 /* No free slot found */
750 return -1;
751}
752
753static int ath_key_config(struct ath_common *common,
754 struct ieee80211_vif *vif,
755 struct ieee80211_sta *sta,
756 struct ieee80211_key_conf *key)
757{
758 struct ath_hw *ah = common->ah;
759 struct ath9k_keyval hk;
760 const u8 *mac = NULL;
761 int ret = 0;
762 int idx;
763
764 memset(&hk, 0, sizeof(hk));
765
766 switch (key->alg) {
767 case ALG_WEP:
768 hk.kv_type = ATH9K_CIPHER_WEP;
769 break;
770 case ALG_TKIP:
771 hk.kv_type = ATH9K_CIPHER_TKIP;
772 break;
773 case ALG_CCMP:
774 hk.kv_type = ATH9K_CIPHER_AES_CCM;
775 break;
776 default:
777 return -EOPNOTSUPP;
778 }
779
780 hk.kv_len = key->keylen;
781 memcpy(hk.kv_val, key->key, key->keylen);
782
783 if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
784 /* For now, use the default keys for broadcast keys. This may
785 * need to change with virtual interfaces. */
786 idx = key->keyidx;
787 } else if (key->keyidx) {
788 if (WARN_ON(!sta))
789 return -EOPNOTSUPP;
790 mac = sta->addr;
791
792 if (vif->type != NL80211_IFTYPE_AP) {
793 /* Only keyidx 0 should be used with unicast key, but
794 * allow this for client mode for now. */
795 idx = key->keyidx;
796 } else
797 return -EIO;
798 } else {
799 if (WARN_ON(!sta))
800 return -EOPNOTSUPP;
801 mac = sta->addr;
802
803 if (key->alg == ALG_TKIP)
804 idx = ath_reserve_key_cache_slot_tkip(common);
805 else
806 idx = ath_reserve_key_cache_slot(common);
807 if (idx < 0)
808 return -ENOSPC; /* no free key cache entries */
809 }
810
811 if (key->alg == ALG_TKIP)
812 ret = ath_setkey_tkip(common, idx, key->key, &hk, mac,
813 vif->type == NL80211_IFTYPE_AP);
814 else
815 ret = ath9k_hw_set_keycache_entry(ah, idx, &hk, mac);
816
817 if (!ret)
818 return -EIO;
819
820 set_bit(idx, common->keymap);
821 if (key->alg == ALG_TKIP) {
822 set_bit(idx + 64, common->keymap);
823 if (common->splitmic) {
824 set_bit(idx + 32, common->keymap);
825 set_bit(idx + 64 + 32, common->keymap);
826 }
827 }
828
829 return idx;
830}
831
832static void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key)
833{
834 struct ath_hw *ah = common->ah;
835
836 ath9k_hw_keyreset(ah, key->hw_key_idx);
837 if (key->hw_key_idx < IEEE80211_WEP_NKID)
838 return;
839
840 clear_bit(key->hw_key_idx, common->keymap);
841 if (key->alg != ALG_TKIP)
842 return;
843
844 clear_bit(key->hw_key_idx + 64, common->keymap);
845 if (common->splitmic) {
846 ath9k_hw_keyreset(ah, key->hw_key_idx + 32);
847 clear_bit(key->hw_key_idx + 32, common->keymap);
848 clear_bit(key->hw_key_idx + 64 + 32, common->keymap);
849 }
850}
851
852static void ath9k_bss_assoc_info(struct ath_softc *sc, 624static void ath9k_bss_assoc_info(struct ath_softc *sc,
853 struct ieee80211_vif *vif, 625 struct ieee80211_vif *vif,
854 struct ieee80211_bss_conf *bss_conf) 626 struct ieee80211_bss_conf *bss_conf)
@@ -1813,7 +1585,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
1813 1585
1814 switch (cmd) { 1586 switch (cmd) {
1815 case SET_KEY: 1587 case SET_KEY:
1816 ret = ath_key_config(common, vif, sta, key); 1588 ret = ath9k_cmn_key_config(common, vif, sta, key);
1817 if (ret >= 0) { 1589 if (ret >= 0) {
1818 key->hw_key_idx = ret; 1590 key->hw_key_idx = ret;
1819 /* push IV and Michael MIC generation to stack */ 1591 /* push IV and Michael MIC generation to stack */
@@ -1826,7 +1598,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
1826 } 1598 }
1827 break; 1599 break;
1828 case DISABLE_KEY: 1600 case DISABLE_KEY:
1829 ath_key_delete(common, key); 1601 ath9k_cmn_key_delete(common, key);
1830 break; 1602 break;
1831 default: 1603 default:
1832 ret = -EINVAL; 1604 ret = -EINVAL;