aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath5k
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-12-06 01:23:34 -0500
committerDavid S. Miller <davem@davemloft.net>2008-12-06 01:23:34 -0500
commit098401a600b6344771900fe164c5eafb668ce99c (patch)
treec03077ee357cf6191bcd9f44ead4e6e4ce8f0495 /drivers/net/wireless/ath5k
parentcb7b48f671f9c7582993a6c0ff6e989078048561 (diff)
parentc112d0c5b89037dd618083b5fdf4bb36b0c51d77 (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.h1
-rw-r--r--drivers/net/wireless/ath5k/attach.c6
-rw-r--r--drivers/net/wireless/ath5k/pcu.c95
-rw-r--r--drivers/net/wireless/ath5k/reg.h1
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 */
275int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac) 271int 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
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
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/*