aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/ath5k/pcu.c58
1 files changed, 34 insertions, 24 deletions
diff --git a/drivers/net/wireless/ath5k/pcu.c b/drivers/net/wireless/ath5k/pcu.c
index 79879f2d426c..ad7ea36502bd 100644
--- a/drivers/net/wireless/ath5k/pcu.c
+++ b/drivers/net/wireless/ath5k/pcu.c
@@ -1013,6 +1013,23 @@ int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry)
1013 AR5K_KEYTABLE_VALID; 1013 AR5K_KEYTABLE_VALID;
1014} 1014}
1015 1015
1016static
1017int ath5k_keycache_type(const struct ieee80211_key_conf *key)
1018{
1019 switch (key->alg) {
1020 case ALG_TKIP:
1021 return AR5K_KEYTABLE_TYPE_TKIP;
1022 case ALG_CCMP:
1023 return AR5K_KEYTABLE_TYPE_CCM;
1024 case ALG_WEP:
1025 if (key->keylen == LEN_WEP40)
1026 return AR5K_KEYTABLE_TYPE_40;
1027 else if (key->keylen == LEN_WEP104)
1028 return AR5K_KEYTABLE_TYPE_104;
1029 }
1030 return -EINVAL;
1031}
1032
1016/* 1033/*
1017 * Set a key entry on the table 1034 * Set a key entry on the table
1018 */ 1035 */
@@ -1027,6 +1044,7 @@ int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
1027 u32 keytype; 1044 u32 keytype;
1028 u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET; 1045 u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET;
1029 bool is_tkip; 1046 bool is_tkip;
1047 const u8 *key_ptr;
1030 1048
1031 ATH5K_TRACE(ah->ah_sc); 1049 ATH5K_TRACE(ah->ah_sc);
1032 1050
@@ -1042,33 +1060,25 @@ int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
1042 (is_tkip && micentry > AR5K_KEYTABLE_SIZE)) 1060 (is_tkip && micentry > AR5K_KEYTABLE_SIZE))
1043 return -EOPNOTSUPP; 1061 return -EOPNOTSUPP;
1044 1062
1045 switch (keylen) { 1063 if (unlikely(keylen > 16))
1046 /* WEP 40-bit = 40-bit entered key + 24 bit IV = 64-bit */ 1064 return -EOPNOTSUPP;
1047 case 40 / 8:
1048 memcpy(&key_v[0], key->key, 5);
1049 keytype = AR5K_KEYTABLE_TYPE_40;
1050 break;
1051 1065
1052 /* WEP 104-bit = 104-bit entered key + 24-bit IV = 128-bit */ 1066 keytype = ath5k_keycache_type(key);
1053 case 104 / 8: 1067 if (keytype < 0)
1054 memcpy(&key_v[0], &key->key[0], 6); 1068 return keytype;
1055 memcpy(&key_v[2], &key->key[6], 6);
1056 memcpy(&key_v[4], &key->key[12], 1);
1057 keytype = AR5K_KEYTABLE_TYPE_104;
1058 break;
1059 /* WEP/TKIP 128-bit = 128-bit entered key + 24 bit IV = 152-bit */
1060 case 128 / 8:
1061 memcpy(&key_v[0], &key->key[0], 6);
1062 memcpy(&key_v[2], &key->key[6], 6);
1063 memcpy(&key_v[4], &key->key[12], 4);
1064 keytype = is_tkip ?
1065 AR5K_KEYTABLE_TYPE_TKIP :
1066 AR5K_KEYTABLE_TYPE_128;
1067 break;
1068 1069
1069 default: 1070 /*
1070 return -EINVAL; /* shouldn't happen */ 1071 * each key block is 6 bytes wide, written as pairs of
1072 * alternating 32 and 16 bit le values.
1073 */
1074 key_ptr = key->key;
1075 for (i = 0; keylen >= 6; keylen -= 6) {
1076 memcpy(&key_v[i], key_ptr, 6);
1077 i += 2;
1078 key_ptr += 6;
1071 } 1079 }
1080 if (keylen)
1081 memcpy(&key_v[i], key_ptr, keylen);
1072 1082
1073 /* intentionally corrupt key until mic is installed */ 1083 /* intentionally corrupt key until mic is installed */
1074 if (is_tkip) { 1084 if (is_tkip) {