diff options
author | David S. Miller <davem@davemloft.net> | 2008-12-06 01:23:34 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-12-06 01:23:34 -0500 |
commit | 098401a600b6344771900fe164c5eafb668ce99c (patch) | |
tree | c03077ee357cf6191bcd9f44ead4e6e4ce8f0495 /drivers/net/wireless/ath5k | |
parent | cb7b48f671f9c7582993a6c0ff6e989078048561 (diff) | |
parent | c112d0c5b89037dd618083b5fdf4bb36b0c51d77 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'drivers/net/wireless/ath5k')
-rw-r--r-- | drivers/net/wireless/ath5k/ath5k.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/attach.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/pcu.c | 95 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/reg.h | 1 |
4 files changed, 60 insertions, 43 deletions
diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h index 5ee2dd1814c2..13df1191b070 100644 --- a/drivers/net/wireless/ath5k/ath5k.h +++ b/drivers/net/wireless/ath5k/ath5k.h | |||
@@ -1052,6 +1052,7 @@ struct ath5k_hw { | |||
1052 | bool ah_calibration; | 1052 | bool ah_calibration; |
1053 | bool ah_running; | 1053 | bool ah_running; |
1054 | bool ah_single_chip; | 1054 | bool ah_single_chip; |
1055 | bool ah_combined_mic; | ||
1055 | enum ath5k_rfgain ah_rf_gain; | 1056 | enum ath5k_rfgain ah_rf_gain; |
1056 | 1057 | ||
1057 | u32 ah_mac_srev; | 1058 | u32 ah_mac_srev; |
diff --git a/drivers/net/wireless/ath5k/attach.c b/drivers/net/wireless/ath5k/attach.c index 49d82d79d3fc..dea378f76731 100644 --- a/drivers/net/wireless/ath5k/attach.c +++ b/drivers/net/wireless/ath5k/attach.c | |||
@@ -317,6 +317,12 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version) | |||
317 | goto err_free; | 317 | goto err_free; |
318 | } | 318 | } |
319 | 319 | ||
320 | if (srev >= AR5K_SREV_AR2414) { | ||
321 | ah->ah_combined_mic = true; | ||
322 | AR5K_REG_ENABLE_BITS(ah, AR5K_MISC_MODE, | ||
323 | AR5K_MISC_MODE_COMBINED_MIC); | ||
324 | } | ||
325 | |||
320 | /* MAC address is cleared until add_interface */ | 326 | /* MAC address is cleared until add_interface */ |
321 | ath5k_hw_set_lladdr(ah, mac); | 327 | ath5k_hw_set_lladdr(ah, mac); |
322 | 328 | ||
diff --git a/drivers/net/wireless/ath5k/pcu.c b/drivers/net/wireless/ath5k/pcu.c index d7f0c1017bda..dabe42219e2a 100644 --- a/drivers/net/wireless/ath5k/pcu.c +++ b/drivers/net/wireless/ath5k/pcu.c | |||
@@ -267,24 +267,23 @@ void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac) | |||
267 | * @mac: The card's mac address | 267 | * @mac: The card's mac address |
268 | * | 268 | * |
269 | * Set station id on hw using the provided mac address | 269 | * Set station id on hw using the provided mac address |
270 | * | ||
271 | * NOTE: This is only called during attach, don't call it | ||
272 | * on reset because it overwrites all AR5K_STA_ID1 settings. | ||
273 | * We have set_opmode (above) for reset. | ||
274 | */ | 270 | */ |
275 | int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac) | 271 | int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac) |
276 | { | 272 | { |
277 | u32 low_id, high_id; | 273 | u32 low_id, high_id; |
274 | u32 pcu_reg; | ||
278 | 275 | ||
279 | ATH5K_TRACE(ah->ah_sc); | 276 | ATH5K_TRACE(ah->ah_sc); |
280 | /* Set new station ID */ | 277 | /* Set new station ID */ |
281 | memcpy(ah->ah_sta_id, mac, ETH_ALEN); | 278 | memcpy(ah->ah_sta_id, mac, ETH_ALEN); |
282 | 279 | ||
280 | pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000; | ||
281 | |||
283 | low_id = AR5K_LOW_ID(mac); | 282 | low_id = AR5K_LOW_ID(mac); |
284 | high_id = AR5K_HIGH_ID(mac); | 283 | high_id = AR5K_HIGH_ID(mac); |
285 | 284 | ||
286 | ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0); | 285 | ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0); |
287 | ath5k_hw_reg_write(ah, high_id, AR5K_STA_ID1); | 286 | ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1); |
288 | 287 | ||
289 | return 0; | 288 | return 0; |
290 | } | 289 | } |
@@ -1014,6 +1013,23 @@ int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry) | |||
1014 | AR5K_KEYTABLE_VALID; | 1013 | AR5K_KEYTABLE_VALID; |
1015 | } | 1014 | } |
1016 | 1015 | ||
1016 | static | ||
1017 | int 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 | |||
1017 | /* | 1033 | /* |
1018 | * Set a key entry on the table | 1034 | * Set a key entry on the table |
1019 | */ | 1035 | */ |
@@ -1028,6 +1044,7 @@ int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, | |||
1028 | u32 keytype; | 1044 | u32 keytype; |
1029 | u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET; | 1045 | u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET; |
1030 | bool is_tkip; | 1046 | bool is_tkip; |
1047 | const u8 *key_ptr; | ||
1031 | 1048 | ||
1032 | ATH5K_TRACE(ah->ah_sc); | 1049 | ATH5K_TRACE(ah->ah_sc); |
1033 | 1050 | ||
@@ -1043,33 +1060,25 @@ int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, | |||
1043 | (is_tkip && micentry > AR5K_KEYTABLE_SIZE)) | 1060 | (is_tkip && micentry > AR5K_KEYTABLE_SIZE)) |
1044 | return -EOPNOTSUPP; | 1061 | return -EOPNOTSUPP; |
1045 | 1062 | ||
1046 | switch (keylen) { | 1063 | if (unlikely(keylen > 16)) |
1047 | /* WEP 40-bit = 40-bit entered key + 24 bit IV = 64-bit */ | 1064 | return -EOPNOTSUPP; |
1048 | case 40 / 8: | ||
1049 | memcpy(&key_v[0], key->key, 5); | ||
1050 | keytype = AR5K_KEYTABLE_TYPE_40; | ||
1051 | break; | ||
1052 | 1065 | ||
1053 | /* WEP 104-bit = 104-bit entered key + 24-bit IV = 128-bit */ | 1066 | keytype = ath5k_keycache_type(key); |
1054 | case 104 / 8: | 1067 | if (keytype < 0) |
1055 | memcpy(&key_v[0], &key->key[0], 6); | 1068 | return keytype; |
1056 | memcpy(&key_v[2], &key->key[6], 6); | ||
1057 | memcpy(&key_v[4], &key->key[12], 1); | ||
1058 | keytype = AR5K_KEYTABLE_TYPE_104; | ||
1059 | break; | ||
1060 | /* WEP/TKIP 128-bit = 128-bit entered key + 24 bit IV = 152-bit */ | ||
1061 | case 128 / 8: | ||
1062 | memcpy(&key_v[0], &key->key[0], 6); | ||
1063 | memcpy(&key_v[2], &key->key[6], 6); | ||
1064 | memcpy(&key_v[4], &key->key[12], 4); | ||
1065 | keytype = is_tkip ? | ||
1066 | AR5K_KEYTABLE_TYPE_TKIP : | ||
1067 | AR5K_KEYTABLE_TYPE_128; | ||
1068 | break; | ||
1069 | 1069 | ||
1070 | default: | 1070 | /* |
1071 | 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; | ||
1072 | } | 1079 | } |
1080 | if (keylen) | ||
1081 | memcpy(&key_v[i], key_ptr, keylen); | ||
1073 | 1082 | ||
1074 | /* intentionally corrupt key until mic is installed */ | 1083 | /* intentionally corrupt key until mic is installed */ |
1075 | if (is_tkip) { | 1084 | if (is_tkip) { |
@@ -1087,20 +1096,20 @@ int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, | |||
1087 | /* Install rx/tx MIC */ | 1096 | /* Install rx/tx MIC */ |
1088 | rxmic = (__le32 *) &key->key[16]; | 1097 | rxmic = (__le32 *) &key->key[16]; |
1089 | txmic = (__le32 *) &key->key[24]; | 1098 | txmic = (__le32 *) &key->key[24]; |
1090 | #if 0 | 1099 | |
1091 | /* MISC_MODE register & 0x04 - for mac srev >= griffin */ | 1100 | if (ah->ah_combined_mic) { |
1092 | key_v[0] = rxmic[0]; | 1101 | key_v[0] = rxmic[0]; |
1093 | key_v[1] = (txmic[0] >> 16) & 0xffff; | 1102 | key_v[1] = (txmic[0] >> 16) & 0xffff; |
1094 | key_v[2] = rxmic[1]; | 1103 | key_v[2] = rxmic[1]; |
1095 | key_v[3] = txmic[0] & 0xffff; | 1104 | key_v[3] = txmic[0] & 0xffff; |
1096 | key_v[4] = txmic[1]; | 1105 | key_v[4] = txmic[1]; |
1097 | #else | 1106 | } else { |
1098 | key_v[0] = rxmic[0]; | 1107 | key_v[0] = rxmic[0]; |
1099 | key_v[1] = 0; | 1108 | key_v[1] = 0; |
1100 | key_v[2] = rxmic[1]; | 1109 | key_v[2] = rxmic[1]; |
1101 | key_v[3] = 0; | 1110 | key_v[3] = 0; |
1102 | key_v[4] = 0; | 1111 | key_v[4] = 0; |
1103 | #endif | 1112 | } |
1104 | for (i = 0; i < ARRAY_SIZE(key_v); i++) | 1113 | for (i = 0; i < ARRAY_SIZE(key_v); i++) |
1105 | ath5k_hw_reg_write(ah, le32_to_cpu(key_v[i]), | 1114 | ath5k_hw_reg_write(ah, le32_to_cpu(key_v[i]), |
1106 | AR5K_KEYTABLE_OFF(micentry, i)); | 1115 | AR5K_KEYTABLE_OFF(micentry, i)); |
diff --git a/drivers/net/wireless/ath5k/reg.h b/drivers/net/wireless/ath5k/reg.h index 69755fc2f9be..91aaeaf88199 100644 --- a/drivers/net/wireless/ath5k/reg.h +++ b/drivers/net/wireless/ath5k/reg.h | |||
@@ -1729,6 +1729,7 @@ | |||
1729 | #define AR5K_MISC_MODE 0x8120 /* Register Address */ | 1729 | #define AR5K_MISC_MODE 0x8120 /* Register Address */ |
1730 | #define AR5K_MISC_MODE_FBSSID_MATCH 0x00000001 /* Force BSSID match */ | 1730 | #define AR5K_MISC_MODE_FBSSID_MATCH 0x00000001 /* Force BSSID match */ |
1731 | #define AR5K_MISC_MODE_ACKSIFS_MEM 0x00000002 /* ACK SIFS memory (?) */ | 1731 | #define AR5K_MISC_MODE_ACKSIFS_MEM 0x00000002 /* ACK SIFS memory (?) */ |
1732 | #define AR5K_MISC_MODE_COMBINED_MIC 0x00000004 /* use rx/tx MIC key */ | ||
1732 | /* more bits */ | 1733 | /* more bits */ |
1733 | 1734 | ||
1734 | /* | 1735 | /* |