diff options
79 files changed, 2854 insertions, 1836 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 | /* |
diff --git a/drivers/net/wireless/ath9k/Kconfig b/drivers/net/wireless/ath9k/Kconfig index 80a692430413..c43bd321f97f 100644 --- a/drivers/net/wireless/ath9k/Kconfig +++ b/drivers/net/wireless/ath9k/Kconfig | |||
@@ -9,3 +9,14 @@ config ATH9K | |||
9 | Atheros IEEE 802.11n AR5008 and AR9001 family of chipsets. | 9 | Atheros IEEE 802.11n AR5008 and AR9001 family of chipsets. |
10 | 10 | ||
11 | If you choose to build a module, it'll be called ath9k. | 11 | If you choose to build a module, it'll be called ath9k. |
12 | |||
13 | config ATH9K_DEBUG | ||
14 | bool "Atheros ath9k debugging" | ||
15 | depends on ATH9K | ||
16 | ---help--- | ||
17 | Say Y, if you need ath9k to display debug messages. | ||
18 | Pass the debug mask as a module parameter: | ||
19 | |||
20 | modprobe ath9k debug=0x00002000 | ||
21 | |||
22 | Look in ath9k/core.h for possible debug masks | ||
diff --git a/drivers/net/wireless/ath9k/Makefile b/drivers/net/wireless/ath9k/Makefile index c741e8d34748..1209d14613ac 100644 --- a/drivers/net/wireless/ath9k/Makefile +++ b/drivers/net/wireless/ath9k/Makefile | |||
@@ -11,4 +11,6 @@ ath9k-y += hw.o \ | |||
11 | xmit.o \ | 11 | xmit.o \ |
12 | rc.o | 12 | rc.o |
13 | 13 | ||
14 | ath9k-$(CONFIG_ATH9K_DEBUG) += debug.o | ||
15 | |||
14 | obj-$(CONFIG_ATH9K) += ath9k.o | 16 | obj-$(CONFIG_ATH9K) += ath9k.o |
diff --git a/drivers/net/wireless/ath9k/ani.c b/drivers/net/wireless/ath9k/ani.c index ada12e9aa7f9..251e2d9a7a4a 100644 --- a/drivers/net/wireless/ath9k/ani.c +++ b/drivers/net/wireless/ath9k/ani.c | |||
@@ -53,8 +53,8 @@ static bool ath9k_hw_ani_control(struct ath_hal *ah, | |||
53 | 53 | ||
54 | if (level >= ARRAY_SIZE(ahp->ah_totalSizeDesired)) { | 54 | if (level >= ARRAY_SIZE(ahp->ah_totalSizeDesired)) { |
55 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, | 55 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, |
56 | "%s: level out of range (%u > %u)\n", | 56 | "level out of range (%u > %u)\n", |
57 | __func__, level, | 57 | level, |
58 | (unsigned)ARRAY_SIZE(ahp->ah_totalSizeDesired)); | 58 | (unsigned)ARRAY_SIZE(ahp->ah_totalSizeDesired)); |
59 | return false; | 59 | return false; |
60 | } | 60 | } |
@@ -158,8 +158,8 @@ static bool ath9k_hw_ani_control(struct ath_hal *ah, | |||
158 | 158 | ||
159 | if (level >= ARRAY_SIZE(firstep)) { | 159 | if (level >= ARRAY_SIZE(firstep)) { |
160 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, | 160 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, |
161 | "%s: level out of range (%u > %u)\n", | 161 | "level out of range (%u > %u)\n", |
162 | __func__, level, | 162 | level, |
163 | (unsigned) ARRAY_SIZE(firstep)); | 163 | (unsigned) ARRAY_SIZE(firstep)); |
164 | return false; | 164 | return false; |
165 | } | 165 | } |
@@ -180,8 +180,8 @@ static bool ath9k_hw_ani_control(struct ath_hal *ah, | |||
180 | 180 | ||
181 | if (level >= ARRAY_SIZE(cycpwrThr1)) { | 181 | if (level >= ARRAY_SIZE(cycpwrThr1)) { |
182 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, | 182 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, |
183 | "%s: level out of range (%u > %u)\n", | 183 | "level out of range (%u > %u)\n", |
184 | __func__, level, | 184 | level, |
185 | (unsigned) | 185 | (unsigned) |
186 | ARRAY_SIZE(cycpwrThr1)); | 186 | ARRAY_SIZE(cycpwrThr1)); |
187 | return false; | 187 | return false; |
@@ -200,11 +200,11 @@ static bool ath9k_hw_ani_control(struct ath_hal *ah, | |||
200 | break; | 200 | break; |
201 | default: | 201 | default: |
202 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, | 202 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, |
203 | "%s: invalid cmd %u\n", __func__, cmd); | 203 | "invalid cmd %u\n", cmd); |
204 | return false; | 204 | return false; |
205 | } | 205 | } |
206 | 206 | ||
207 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, "%s: ANI parameters:\n", __func__); | 207 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, "ANI parameters:\n"); |
208 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, | 208 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, |
209 | "noiseImmunityLevel=%d, spurImmunityLevel=%d, " | 209 | "noiseImmunityLevel=%d, spurImmunityLevel=%d, " |
210 | "ofdmWeakSigDetectOff=%d\n", | 210 | "ofdmWeakSigDetectOff=%d\n", |
@@ -262,8 +262,8 @@ static void ath9k_ani_restart(struct ath_hal *ah) | |||
262 | AR_PHY_COUNTMAX - aniState->cckTrigHigh; | 262 | AR_PHY_COUNTMAX - aniState->cckTrigHigh; |
263 | } | 263 | } |
264 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, | 264 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, |
265 | "%s: Writing ofdmbase=%u cckbase=%u\n", | 265 | "Writing ofdmbase=%u cckbase=%u\n", |
266 | __func__, aniState->ofdmPhyErrBase, | 266 | aniState->ofdmPhyErrBase, |
267 | aniState->cckPhyErrBase); | 267 | aniState->cckPhyErrBase); |
268 | REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase); | 268 | REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase); |
269 | REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase); | 269 | REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase); |
@@ -303,7 +303,7 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hal *ah) | |||
303 | } | 303 | } |
304 | } | 304 | } |
305 | 305 | ||
306 | if (ah->ah_opmode == ATH9K_M_HOSTAP) { | 306 | if (ah->ah_opmode == NL80211_IFTYPE_AP) { |
307 | if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) { | 307 | if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) { |
308 | ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, | 308 | ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, |
309 | aniState->firstepLevel + 1); | 309 | aniState->firstepLevel + 1); |
@@ -368,7 +368,7 @@ static void ath9k_hw_ani_cck_err_trigger(struct ath_hal *ah) | |||
368 | return; | 368 | return; |
369 | } | 369 | } |
370 | } | 370 | } |
371 | if (ah->ah_opmode == ATH9K_M_HOSTAP) { | 371 | if (ah->ah_opmode == NL80211_IFTYPE_AP) { |
372 | if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) { | 372 | if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) { |
373 | ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, | 373 | ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, |
374 | aniState->firstepLevel + 1); | 374 | aniState->firstepLevel + 1); |
@@ -398,7 +398,7 @@ static void ath9k_hw_ani_lower_immunity(struct ath_hal *ah) | |||
398 | 398 | ||
399 | aniState = ahp->ah_curani; | 399 | aniState = ahp->ah_curani; |
400 | 400 | ||
401 | if (ah->ah_opmode == ATH9K_M_HOSTAP) { | 401 | if (ah->ah_opmode == NL80211_IFTYPE_AP) { |
402 | if (aniState->firstepLevel > 0) { | 402 | if (aniState->firstepLevel > 0) { |
403 | if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, | 403 | if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, |
404 | aniState->firstepLevel - 1)) | 404 | aniState->firstepLevel - 1)) |
@@ -487,11 +487,10 @@ void ath9k_ani_reset(struct ath_hal *ah) | |||
487 | aniState = &ahp->ah_ani[index]; | 487 | aniState = &ahp->ah_ani[index]; |
488 | ahp->ah_curani = aniState; | 488 | ahp->ah_curani = aniState; |
489 | 489 | ||
490 | if (DO_ANI(ah) && ah->ah_opmode != ATH9K_M_STA | 490 | if (DO_ANI(ah) && ah->ah_opmode != NL80211_IFTYPE_STATION |
491 | && ah->ah_opmode != ATH9K_M_IBSS) { | 491 | && ah->ah_opmode != NL80211_IFTYPE_ADHOC) { |
492 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, | 492 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, |
493 | "%s: Reset ANI state opmode %u\n", __func__, | 493 | "Reset ANI state opmode %u\n", ah->ah_opmode); |
494 | ah->ah_opmode); | ||
495 | ahp->ah_stats.ast_ani_reset++; | 494 | ahp->ah_stats.ast_ani_reset++; |
496 | 495 | ||
497 | ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0); | 496 | ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0); |
@@ -505,7 +504,7 @@ void ath9k_ani_reset(struct ath_hal *ah) | |||
505 | ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) | | 504 | ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) | |
506 | ATH9K_RX_FILTER_PHYERR); | 505 | ATH9K_RX_FILTER_PHYERR); |
507 | 506 | ||
508 | if (ah->ah_opmode == ATH9K_M_HOSTAP) { | 507 | if (ah->ah_opmode == NL80211_IFTYPE_AP) { |
509 | ahp->ah_curani->ofdmTrigHigh = | 508 | ahp->ah_curani->ofdmTrigHigh = |
510 | ah->ah_config.ofdm_trig_high; | 509 | ah->ah_config.ofdm_trig_high; |
511 | ahp->ah_curani->ofdmTrigLow = | 510 | ahp->ah_curani->ofdmTrigLow = |
@@ -581,9 +580,9 @@ void ath9k_hw_ani_monitor(struct ath_hal *ah, | |||
581 | phyCnt2 < aniState->cckPhyErrBase) { | 580 | phyCnt2 < aniState->cckPhyErrBase) { |
582 | if (phyCnt1 < aniState->ofdmPhyErrBase) { | 581 | if (phyCnt1 < aniState->ofdmPhyErrBase) { |
583 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, | 582 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, |
584 | "%s: phyCnt1 0x%x, resetting " | 583 | "phyCnt1 0x%x, resetting " |
585 | "counter value to 0x%x\n", | 584 | "counter value to 0x%x\n", |
586 | __func__, phyCnt1, | 585 | phyCnt1, |
587 | aniState->ofdmPhyErrBase); | 586 | aniState->ofdmPhyErrBase); |
588 | REG_WRITE(ah, AR_PHY_ERR_1, | 587 | REG_WRITE(ah, AR_PHY_ERR_1, |
589 | aniState->ofdmPhyErrBase); | 588 | aniState->ofdmPhyErrBase); |
@@ -592,9 +591,9 @@ void ath9k_hw_ani_monitor(struct ath_hal *ah, | |||
592 | } | 591 | } |
593 | if (phyCnt2 < aniState->cckPhyErrBase) { | 592 | if (phyCnt2 < aniState->cckPhyErrBase) { |
594 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, | 593 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, |
595 | "%s: phyCnt2 0x%x, resetting " | 594 | "phyCnt2 0x%x, resetting " |
596 | "counter value to 0x%x\n", | 595 | "counter value to 0x%x\n", |
597 | __func__, phyCnt2, | 596 | phyCnt2, |
598 | aniState->cckPhyErrBase); | 597 | aniState->cckPhyErrBase); |
599 | REG_WRITE(ah, AR_PHY_ERR_2, | 598 | REG_WRITE(ah, AR_PHY_ERR_2, |
600 | aniState->cckPhyErrBase); | 599 | aniState->cckPhyErrBase); |
@@ -692,8 +691,7 @@ u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hal *ah, | |||
692 | 691 | ||
693 | if (cycles == 0 || cycles > cc) { | 692 | if (cycles == 0 || cycles > cc) { |
694 | DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, | 693 | DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, |
695 | "%s: cycle counter wrap. ExtBusy = 0\n", | 694 | "cycle counter wrap. ExtBusy = 0\n"); |
696 | __func__); | ||
697 | good = 0; | 695 | good = 0; |
698 | } else { | 696 | } else { |
699 | u32 cc_d = cc - cycles; | 697 | u32 cc_d = cc - cycles; |
diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h index 5b9bc545e964..9520aa0898e3 100644 --- a/drivers/net/wireless/ath9k/ath9k.h +++ b/drivers/net/wireless/ath9k/ath9k.h | |||
@@ -647,13 +647,6 @@ enum ath9k_ant_setting { | |||
647 | ATH9K_ANT_FIXED_B | 647 | ATH9K_ANT_FIXED_B |
648 | }; | 648 | }; |
649 | 649 | ||
650 | enum ath9k_opmode { | ||
651 | ATH9K_M_STA = 1, | ||
652 | ATH9K_M_IBSS = 0, | ||
653 | ATH9K_M_HOSTAP = 6, | ||
654 | ATH9K_M_MONITOR = 8 | ||
655 | }; | ||
656 | |||
657 | #define ATH9K_SLOT_TIME_6 6 | 650 | #define ATH9K_SLOT_TIME_6 6 |
658 | #define ATH9K_SLOT_TIME_9 9 | 651 | #define ATH9K_SLOT_TIME_9 9 |
659 | #define ATH9K_SLOT_TIME_20 20 | 652 | #define ATH9K_SLOT_TIME_20 20 |
@@ -780,7 +773,8 @@ struct ath_hal { | |||
780 | 773 | ||
781 | void __iomem *ah_sh; | 774 | void __iomem *ah_sh; |
782 | struct ath_softc *ah_sc; | 775 | struct ath_softc *ah_sc; |
783 | enum ath9k_opmode ah_opmode; | 776 | |
777 | enum nl80211_iftype ah_opmode; | ||
784 | struct ath9k_ops_config ah_config; | 778 | struct ath9k_ops_config ah_config; |
785 | struct ath9k_hw_capabilities ah_caps; | 779 | struct ath9k_hw_capabilities ah_caps; |
786 | 780 | ||
@@ -1009,7 +1003,6 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints); | |||
1009 | 1003 | ||
1010 | /* MAC (PCU/QCU) */ | 1004 | /* MAC (PCU/QCU) */ |
1011 | 1005 | ||
1012 | void ath9k_hw_dmaRegDump(struct ath_hal *ah); | ||
1013 | u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q); | 1006 | u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q); |
1014 | bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q, u32 txdp); | 1007 | bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q, u32 txdp); |
1015 | bool ath9k_hw_txstart(struct ath_hal *ah, u32 q); | 1008 | bool ath9k_hw_txstart(struct ath_hal *ah, u32 q); |
diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c index e80d9b9b61a0..507299bf0136 100644 --- a/drivers/net/wireless/ath9k/beacon.c +++ b/drivers/net/wireless/ath9k/beacon.c | |||
@@ -27,7 +27,7 @@ static int ath_beaconq_config(struct ath_softc *sc) | |||
27 | struct ath9k_tx_queue_info qi; | 27 | struct ath9k_tx_queue_info qi; |
28 | 28 | ||
29 | ath9k_hw_get_txq_props(ah, sc->sc_bhalq, &qi); | 29 | ath9k_hw_get_txq_props(ah, sc->sc_bhalq, &qi); |
30 | if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) { | 30 | if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) { |
31 | /* Always burst out beacon and CAB traffic. */ | 31 | /* Always burst out beacon and CAB traffic. */ |
32 | qi.tqi_aifs = 1; | 32 | qi.tqi_aifs = 1; |
33 | qi.tqi_cwmin = 0; | 33 | qi.tqi_cwmin = 0; |
@@ -41,8 +41,7 @@ static int ath_beaconq_config(struct ath_softc *sc) | |||
41 | 41 | ||
42 | if (!ath9k_hw_set_txq_props(ah, sc->sc_bhalq, &qi)) { | 42 | if (!ath9k_hw_set_txq_props(ah, sc->sc_bhalq, &qi)) { |
43 | DPRINTF(sc, ATH_DBG_FATAL, | 43 | DPRINTF(sc, ATH_DBG_FATAL, |
44 | "%s: unable to update h/w beacon queue parameters\n", | 44 | "unable to update h/w beacon queue parameters\n"); |
45 | __func__); | ||
46 | return 0; | 45 | return 0; |
47 | } else { | 46 | } else { |
48 | ath9k_hw_resettxqueue(ah, sc->sc_bhalq); /* push to h/w */ | 47 | ath9k_hw_resettxqueue(ah, sc->sc_bhalq); /* push to h/w */ |
@@ -53,8 +52,8 @@ static int ath_beaconq_config(struct ath_softc *sc) | |||
53 | static void ath_bstuck_process(struct ath_softc *sc) | 52 | static void ath_bstuck_process(struct ath_softc *sc) |
54 | { | 53 | { |
55 | DPRINTF(sc, ATH_DBG_BEACON, | 54 | DPRINTF(sc, ATH_DBG_BEACON, |
56 | "%s: stuck beacon; resetting (bmiss count %u)\n", | 55 | "stuck beacon; resetting (bmiss count %u)\n", |
57 | __func__, sc->sc_bmisscount); | 56 | sc->sc_bmisscount); |
58 | ath_reset(sc, false); | 57 | ath_reset(sc, false); |
59 | } | 58 | } |
60 | 59 | ||
@@ -76,15 +75,14 @@ static void ath_beacon_setup(struct ath_softc *sc, | |||
76 | int ctsrate = 0; | 75 | int ctsrate = 0; |
77 | int ctsduration = 0; | 76 | int ctsduration = 0; |
78 | 77 | ||
79 | DPRINTF(sc, ATH_DBG_BEACON, "%s: m %p len %u\n", | 78 | DPRINTF(sc, ATH_DBG_BEACON, "m %p len %u\n", skb, skb->len); |
80 | __func__, skb, skb->len); | ||
81 | 79 | ||
82 | /* setup descriptors */ | 80 | /* setup descriptors */ |
83 | ds = bf->bf_desc; | 81 | ds = bf->bf_desc; |
84 | 82 | ||
85 | flags = ATH9K_TXDESC_NOACK; | 83 | flags = ATH9K_TXDESC_NOACK; |
86 | 84 | ||
87 | if (sc->sc_ah->ah_opmode == ATH9K_M_IBSS && | 85 | if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC && |
88 | (ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) { | 86 | (ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) { |
89 | ds->ds_link = bf->bf_daddr; /* self-linked */ | 87 | ds->ds_link = bf->bf_daddr; /* self-linked */ |
90 | flags |= ATH9K_TXDESC_VEOL; | 88 | flags |= ATH9K_TXDESC_VEOL; |
@@ -158,8 +156,8 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) | |||
158 | cabq = sc->sc_cabq; | 156 | cabq = sc->sc_cabq; |
159 | 157 | ||
160 | if (avp->av_bcbuf == NULL) { | 158 | if (avp->av_bcbuf == NULL) { |
161 | DPRINTF(sc, ATH_DBG_BEACON, "%s: avp=%p av_bcbuf=%p\n", | 159 | DPRINTF(sc, ATH_DBG_BEACON, "avp=%p av_bcbuf=%p\n", |
162 | __func__, avp, avp->av_bcbuf); | 160 | avp, avp->av_bcbuf); |
163 | return NULL; | 161 | return NULL; |
164 | } | 162 | } |
165 | 163 | ||
@@ -192,6 +190,13 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) | |||
192 | pci_map_single(sc->pdev, skb->data, | 190 | pci_map_single(sc->pdev, skb->data, |
193 | skb->len, | 191 | skb->len, |
194 | PCI_DMA_TODEVICE); | 192 | PCI_DMA_TODEVICE); |
193 | if (unlikely(pci_dma_mapping_error(sc->pdev, bf->bf_buf_addr))) { | ||
194 | dev_kfree_skb_any(skb); | ||
195 | bf->bf_mpdu = NULL; | ||
196 | DPRINTF(sc, ATH_DBG_CONFIG, | ||
197 | "pci_dma_mapping_error() on beaconing\n"); | ||
198 | return NULL; | ||
199 | } | ||
195 | 200 | ||
196 | skb = ieee80211_get_buffered_bc(sc->hw, vif); | 201 | skb = ieee80211_get_buffered_bc(sc->hw, vif); |
197 | 202 | ||
@@ -216,7 +221,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) | |||
216 | if (sc->sc_nvaps > 1) { | 221 | if (sc->sc_nvaps > 1) { |
217 | ath_tx_draintxq(sc, cabq, false); | 222 | ath_tx_draintxq(sc, cabq, false); |
218 | DPRINTF(sc, ATH_DBG_BEACON, | 223 | DPRINTF(sc, ATH_DBG_BEACON, |
219 | "%s: flush previous cabq traffic\n", __func__); | 224 | "flush previous cabq traffic\n"); |
220 | } | 225 | } |
221 | } | 226 | } |
222 | 227 | ||
@@ -253,8 +258,8 @@ static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id) | |||
253 | avp = (void *)vif->drv_priv; | 258 | avp = (void *)vif->drv_priv; |
254 | 259 | ||
255 | if (avp->av_bcbuf == NULL) { | 260 | if (avp->av_bcbuf == NULL) { |
256 | DPRINTF(sc, ATH_DBG_BEACON, "%s: avp=%p av_bcbuf=%p\n", | 261 | DPRINTF(sc, ATH_DBG_BEACON, "avp=%p av_bcbuf=%p\n", |
257 | __func__, avp, avp != NULL ? avp->av_bcbuf : NULL); | 262 | avp, avp != NULL ? avp->av_bcbuf : NULL); |
258 | return; | 263 | return; |
259 | } | 264 | } |
260 | bf = avp->av_bcbuf; | 265 | bf = avp->av_bcbuf; |
@@ -266,7 +271,7 @@ static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id) | |||
266 | /* NB: caller is known to have already stopped tx dma */ | 271 | /* NB: caller is known to have already stopped tx dma */ |
267 | ath9k_hw_puttxbuf(ah, sc->sc_bhalq, bf->bf_daddr); | 272 | ath9k_hw_puttxbuf(ah, sc->sc_bhalq, bf->bf_daddr); |
268 | ath9k_hw_txstart(ah, sc->sc_bhalq); | 273 | ath9k_hw_txstart(ah, sc->sc_bhalq); |
269 | DPRINTF(sc, ATH_DBG_BEACON, "%s: TXDP%u = %llx (%p)\n", __func__, | 274 | DPRINTF(sc, ATH_DBG_BEACON, "TXDP%u = %llx (%p)\n", |
270 | sc->sc_bhalq, ito64(bf->bf_daddr), bf->bf_desc); | 275 | sc->sc_bhalq, ito64(bf->bf_daddr), bf->bf_desc); |
271 | } | 276 | } |
272 | 277 | ||
@@ -304,7 +309,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) | |||
304 | struct ath_buf, list); | 309 | struct ath_buf, list); |
305 | list_del(&avp->av_bcbuf->list); | 310 | list_del(&avp->av_bcbuf->list); |
306 | 311 | ||
307 | if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP || | 312 | if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP || |
308 | !(sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) { | 313 | !(sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) { |
309 | int slot; | 314 | int slot; |
310 | /* | 315 | /* |
@@ -351,8 +356,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) | |||
351 | */ | 356 | */ |
352 | skb = ieee80211_beacon_get(sc->hw, vif); | 357 | skb = ieee80211_beacon_get(sc->hw, vif); |
353 | if (skb == NULL) { | 358 | if (skb == NULL) { |
354 | DPRINTF(sc, ATH_DBG_BEACON, "%s: cannot get skb\n", | 359 | DPRINTF(sc, ATH_DBG_BEACON, "cannot get skb\n"); |
355 | __func__); | ||
356 | return -ENOMEM; | 360 | return -ENOMEM; |
357 | } | 361 | } |
358 | 362 | ||
@@ -388,19 +392,25 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) | |||
388 | val = cpu_to_le64(tsfadjust << 10); /* TU->TSF */ | 392 | val = cpu_to_le64(tsfadjust << 10); /* TU->TSF */ |
389 | 393 | ||
390 | DPRINTF(sc, ATH_DBG_BEACON, | 394 | DPRINTF(sc, ATH_DBG_BEACON, |
391 | "%s: %s beacons, bslot %d intval %u tsfadjust %llu\n", | 395 | "stagger beacons, bslot %d intval %u tsfadjust %llu\n", |
392 | __func__, "stagger", | ||
393 | avp->av_bslot, intval, (unsigned long long)tsfadjust); | 396 | avp->av_bslot, intval, (unsigned long long)tsfadjust); |
394 | 397 | ||
395 | hdr = (struct ieee80211_hdr *)skb->data; | 398 | hdr = (struct ieee80211_hdr *)skb->data; |
396 | memcpy(&hdr[1], &val, sizeof(val)); | 399 | memcpy(&hdr[1], &val, sizeof(val)); |
397 | } | 400 | } |
398 | 401 | ||
402 | bf->bf_mpdu = skb; | ||
399 | bf->bf_buf_addr = bf->bf_dmacontext = | 403 | bf->bf_buf_addr = bf->bf_dmacontext = |
400 | pci_map_single(sc->pdev, skb->data, | 404 | pci_map_single(sc->pdev, skb->data, |
401 | skb->len, | 405 | skb->len, |
402 | PCI_DMA_TODEVICE); | 406 | PCI_DMA_TODEVICE); |
403 | bf->bf_mpdu = skb; | 407 | if (unlikely(pci_dma_mapping_error(sc->pdev, bf->bf_buf_addr))) { |
408 | dev_kfree_skb_any(skb); | ||
409 | bf->bf_mpdu = NULL; | ||
410 | DPRINTF(sc, ATH_DBG_CONFIG, | ||
411 | "pci_dma_mapping_error() on beacon alloc\n"); | ||
412 | return -ENOMEM; | ||
413 | } | ||
404 | 414 | ||
405 | return 0; | 415 | return 0; |
406 | } | 416 | } |
@@ -468,40 +478,38 @@ void ath9k_beacon_tasklet(unsigned long data) | |||
468 | if (sc->sc_bmisscount < BSTUCK_THRESH) { | 478 | if (sc->sc_bmisscount < BSTUCK_THRESH) { |
469 | if (sc->sc_flags & SC_OP_NO_RESET) { | 479 | if (sc->sc_flags & SC_OP_NO_RESET) { |
470 | DPRINTF(sc, ATH_DBG_BEACON, | 480 | DPRINTF(sc, ATH_DBG_BEACON, |
471 | "%s: missed %u consecutive beacons\n", | 481 | "missed %u consecutive beacons\n", |
472 | __func__, sc->sc_bmisscount); | 482 | sc->sc_bmisscount); |
473 | if (show_cycles) { | 483 | if (show_cycles) { |
474 | /* | 484 | /* |
475 | * Display cycle counter stats from HW | 485 | * Display cycle counter stats from HW |
476 | * to aide in debug of stickiness. | 486 | * to aide in debug of stickiness. |
477 | */ | 487 | */ |
478 | DPRINTF(sc, ATH_DBG_BEACON, | 488 | DPRINTF(sc, ATH_DBG_BEACON, |
479 | "%s: busy times: rx_clear=%d, " | 489 | "busy times: rx_clear=%d, " |
480 | "rx_frame=%d, tx_frame=%d\n", | 490 | "rx_frame=%d, tx_frame=%d\n", |
481 | __func__, rx_clear, rx_frame, | 491 | rx_clear, rx_frame, |
482 | tx_frame); | 492 | tx_frame); |
483 | } else { | 493 | } else { |
484 | DPRINTF(sc, ATH_DBG_BEACON, | 494 | DPRINTF(sc, ATH_DBG_BEACON, |
485 | "%s: unable to obtain " | 495 | "unable to obtain " |
486 | "busy times\n", __func__); | 496 | "busy times\n"); |
487 | } | 497 | } |
488 | } else { | 498 | } else { |
489 | DPRINTF(sc, ATH_DBG_BEACON, | 499 | DPRINTF(sc, ATH_DBG_BEACON, |
490 | "%s: missed %u consecutive beacons\n", | 500 | "missed %u consecutive beacons\n", |
491 | __func__, sc->sc_bmisscount); | 501 | sc->sc_bmisscount); |
492 | } | 502 | } |
493 | } else if (sc->sc_bmisscount >= BSTUCK_THRESH) { | 503 | } else if (sc->sc_bmisscount >= BSTUCK_THRESH) { |
494 | if (sc->sc_flags & SC_OP_NO_RESET) { | 504 | if (sc->sc_flags & SC_OP_NO_RESET) { |
495 | if (sc->sc_bmisscount == BSTUCK_THRESH) { | 505 | if (sc->sc_bmisscount == BSTUCK_THRESH) { |
496 | DPRINTF(sc, ATH_DBG_BEACON, | 506 | DPRINTF(sc, ATH_DBG_BEACON, |
497 | "%s: beacon is officially " | 507 | "beacon is officially " |
498 | "stuck\n", __func__); | 508 | "stuck\n"); |
499 | ath9k_hw_dmaRegDump(ah); | ||
500 | } | 509 | } |
501 | } else { | 510 | } else { |
502 | DPRINTF(sc, ATH_DBG_BEACON, | 511 | DPRINTF(sc, ATH_DBG_BEACON, |
503 | "%s: beacon is officially stuck\n", | 512 | "beacon is officially stuck\n"); |
504 | __func__); | ||
505 | ath_bstuck_process(sc); | 513 | ath_bstuck_process(sc); |
506 | } | 514 | } |
507 | } | 515 | } |
@@ -511,12 +519,12 @@ void ath9k_beacon_tasklet(unsigned long data) | |||
511 | if (sc->sc_bmisscount != 0) { | 519 | if (sc->sc_bmisscount != 0) { |
512 | if (sc->sc_flags & SC_OP_NO_RESET) { | 520 | if (sc->sc_flags & SC_OP_NO_RESET) { |
513 | DPRINTF(sc, ATH_DBG_BEACON, | 521 | DPRINTF(sc, ATH_DBG_BEACON, |
514 | "%s: resume beacon xmit after %u misses\n", | 522 | "resume beacon xmit after %u misses\n", |
515 | __func__, sc->sc_bmisscount); | 523 | sc->sc_bmisscount); |
516 | } else { | 524 | } else { |
517 | DPRINTF(sc, ATH_DBG_BEACON, | 525 | DPRINTF(sc, ATH_DBG_BEACON, |
518 | "%s: resume beacon xmit after %u misses\n", | 526 | "resume beacon xmit after %u misses\n", |
519 | __func__, sc->sc_bmisscount); | 527 | sc->sc_bmisscount); |
520 | } | 528 | } |
521 | sc->sc_bmisscount = 0; | 529 | sc->sc_bmisscount = 0; |
522 | } | 530 | } |
@@ -536,8 +544,8 @@ void ath9k_beacon_tasklet(unsigned long data) | |||
536 | if_id = sc->sc_bslot[(slot + 1) % ATH_BCBUF]; | 544 | if_id = sc->sc_bslot[(slot + 1) % ATH_BCBUF]; |
537 | 545 | ||
538 | DPRINTF(sc, ATH_DBG_BEACON, | 546 | DPRINTF(sc, ATH_DBG_BEACON, |
539 | "%s: slot %d [tsf %llu tsftu %u intval %u] if_id %d\n", | 547 | "slot %d [tsf %llu tsftu %u intval %u] if_id %d\n", |
540 | __func__, slot, (unsigned long long)tsf, tsftu, | 548 | slot, (unsigned long long)tsf, tsftu, |
541 | intval, if_id); | 549 | intval, if_id); |
542 | 550 | ||
543 | bfaddr = 0; | 551 | bfaddr = 0; |
@@ -580,8 +588,7 @@ void ath9k_beacon_tasklet(unsigned long data) | |||
580 | */ | 588 | */ |
581 | if (!ath9k_hw_stoptxdma(ah, sc->sc_bhalq)) { | 589 | if (!ath9k_hw_stoptxdma(ah, sc->sc_bhalq)) { |
582 | DPRINTF(sc, ATH_DBG_FATAL, | 590 | DPRINTF(sc, ATH_DBG_FATAL, |
583 | "%s: beacon queue %u did not stop?\n", | 591 | "beacon queue %u did not stop?\n", sc->sc_bhalq); |
584 | __func__, sc->sc_bhalq); | ||
585 | /* NB: the HAL still stops DMA, so proceed */ | 592 | /* NB: the HAL still stops DMA, so proceed */ |
586 | } | 593 | } |
587 | 594 | ||
@@ -614,16 +621,16 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) | |||
614 | struct ath_hal *ah = sc->sc_ah; | 621 | struct ath_hal *ah = sc->sc_ah; |
615 | struct ath_beacon_config conf; | 622 | struct ath_beacon_config conf; |
616 | struct ath_vap *avp; | 623 | struct ath_vap *avp; |
617 | enum ath9k_opmode av_opmode; | 624 | enum nl80211_iftype opmode; |
618 | u32 nexttbtt, intval; | 625 | u32 nexttbtt, intval; |
619 | 626 | ||
620 | if (if_id != ATH_IF_ID_ANY) { | 627 | if (if_id != ATH_IF_ID_ANY) { |
621 | vif = sc->sc_vaps[if_id]; | 628 | vif = sc->sc_vaps[if_id]; |
622 | ASSERT(vif); | 629 | ASSERT(vif); |
623 | avp = (void *)vif->drv_priv; | 630 | avp = (void *)vif->drv_priv; |
624 | av_opmode = avp->av_opmode; | 631 | opmode = avp->av_opmode; |
625 | } else { | 632 | } else { |
626 | av_opmode = sc->sc_ah->ah_opmode; | 633 | opmode = sc->sc_ah->ah_opmode; |
627 | } | 634 | } |
628 | 635 | ||
629 | memset(&conf, 0, sizeof(struct ath_beacon_config)); | 636 | memset(&conf, 0, sizeof(struct ath_beacon_config)); |
@@ -639,7 +646,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) | |||
639 | nexttbtt = TSF_TO_TU(sc->bc_tstamp >> 32, sc->bc_tstamp); | 646 | nexttbtt = TSF_TO_TU(sc->bc_tstamp >> 32, sc->bc_tstamp); |
640 | 647 | ||
641 | /* XXX conditionalize multi-bss support? */ | 648 | /* XXX conditionalize multi-bss support? */ |
642 | if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) { | 649 | if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) { |
643 | /* | 650 | /* |
644 | * For multi-bss ap support beacons are either staggered | 651 | * For multi-bss ap support beacons are either staggered |
645 | * evenly over N slots or burst together. For the former | 652 | * evenly over N slots or burst together. For the former |
@@ -658,11 +665,11 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) | |||
658 | else if (intval) /* NB: can be 0 for monitor mode */ | 665 | else if (intval) /* NB: can be 0 for monitor mode */ |
659 | nexttbtt = roundup(nexttbtt, intval); | 666 | nexttbtt = roundup(nexttbtt, intval); |
660 | 667 | ||
661 | DPRINTF(sc, ATH_DBG_BEACON, "%s: nexttbtt %u intval %u (%u)\n", | 668 | DPRINTF(sc, ATH_DBG_BEACON, "nexttbtt %u intval %u (%u)\n", |
662 | __func__, nexttbtt, intval, conf.beacon_interval); | 669 | nexttbtt, intval, conf.beacon_interval); |
663 | 670 | ||
664 | /* Check for ATH9K_M_HOSTAP and sc_nostabeacons for WDS client */ | 671 | /* Check for NL80211_IFTYPE_AP and sc_nostabeacons for WDS client */ |
665 | if (sc->sc_ah->ah_opmode == ATH9K_M_STA) { | 672 | if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION) { |
666 | struct ath9k_beacon_state bs; | 673 | struct ath9k_beacon_state bs; |
667 | u64 tsf; | 674 | u64 tsf; |
668 | u32 tsftu; | 675 | u32 tsftu; |
@@ -746,7 +753,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) | |||
746 | bs.bs_sleepduration = bs.bs_dtimperiod; | 753 | bs.bs_sleepduration = bs.bs_dtimperiod; |
747 | 754 | ||
748 | DPRINTF(sc, ATH_DBG_BEACON, | 755 | DPRINTF(sc, ATH_DBG_BEACON, |
749 | "%s: tsf %llu " | 756 | "tsf %llu " |
750 | "tsf:tu %u " | 757 | "tsf:tu %u " |
751 | "intval %u " | 758 | "intval %u " |
752 | "nexttbtt %u " | 759 | "nexttbtt %u " |
@@ -758,7 +765,6 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) | |||
758 | "maxdur %u " | 765 | "maxdur %u " |
759 | "next %u " | 766 | "next %u " |
760 | "timoffset %u\n", | 767 | "timoffset %u\n", |
761 | __func__, | ||
762 | (unsigned long long)tsf, tsftu, | 768 | (unsigned long long)tsf, tsftu, |
763 | bs.bs_intval, | 769 | bs.bs_intval, |
764 | bs.bs_nexttbtt, | 770 | bs.bs_nexttbtt, |
@@ -782,7 +788,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) | |||
782 | ath9k_hw_set_interrupts(ah, 0); | 788 | ath9k_hw_set_interrupts(ah, 0); |
783 | if (nexttbtt == intval) | 789 | if (nexttbtt == intval) |
784 | intval |= ATH9K_BEACON_RESET_TSF; | 790 | intval |= ATH9K_BEACON_RESET_TSF; |
785 | if (sc->sc_ah->ah_opmode == ATH9K_M_IBSS) { | 791 | if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC) { |
786 | /* | 792 | /* |
787 | * Pull nexttbtt forward to reflect the current | 793 | * Pull nexttbtt forward to reflect the current |
788 | * TSF | 794 | * TSF |
@@ -798,8 +804,8 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) | |||
798 | } | 804 | } |
799 | #undef FUDGE | 805 | #undef FUDGE |
800 | DPRINTF(sc, ATH_DBG_BEACON, | 806 | DPRINTF(sc, ATH_DBG_BEACON, |
801 | "%s: IBSS nexttbtt %u intval %u (%u)\n", | 807 | "IBSS nexttbtt %u intval %u (%u)\n", |
802 | __func__, nexttbtt, | 808 | nexttbtt, |
803 | intval & ~ATH9K_BEACON_RESET_TSF, | 809 | intval & ~ATH9K_BEACON_RESET_TSF, |
804 | conf.beacon_interval); | 810 | conf.beacon_interval); |
805 | 811 | ||
@@ -814,7 +820,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) | |||
814 | if (!(ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) | 820 | if (!(ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) |
815 | sc->sc_imask |= ATH9K_INT_SWBA; | 821 | sc->sc_imask |= ATH9K_INT_SWBA; |
816 | ath_beaconq_config(sc); | 822 | ath_beaconq_config(sc); |
817 | } else if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) { | 823 | } else if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) { |
818 | /* | 824 | /* |
819 | * In AP mode we enable the beacon timers and | 825 | * In AP mode we enable the beacon timers and |
820 | * SWBA interrupts to prepare beacon frames. | 826 | * SWBA interrupts to prepare beacon frames. |
@@ -830,7 +836,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) | |||
830 | * When using a self-linked beacon descriptor in | 836 | * When using a self-linked beacon descriptor in |
831 | * ibss mode load it once here. | 837 | * ibss mode load it once here. |
832 | */ | 838 | */ |
833 | if (sc->sc_ah->ah_opmode == ATH9K_M_IBSS && | 839 | if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC && |
834 | (ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) | 840 | (ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) |
835 | ath_beacon_start_adhoc(sc, 0); | 841 | ath_beacon_start_adhoc(sc, 0); |
836 | } | 842 | } |
diff --git a/drivers/net/wireless/ath9k/calib.c b/drivers/net/wireless/ath9k/calib.c index 0e214f746a96..51c8a3ce4e60 100644 --- a/drivers/net/wireless/ath9k/calib.c +++ b/drivers/net/wireless/ath9k/calib.c | |||
@@ -31,11 +31,11 @@ static const int16_t NOISE_FLOOR[] = { -96, -93, -98, -96, -93, -96 }; | |||
31 | static bool ath9k_hw_nf_in_range(struct ath_hal *ah, s16 nf) | 31 | static bool ath9k_hw_nf_in_range(struct ath_hal *ah, s16 nf) |
32 | { | 32 | { |
33 | if (nf > ATH9K_NF_TOO_LOW) { | 33 | if (nf > ATH9K_NF_TOO_LOW) { |
34 | DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL, | 34 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, |
35 | "%s: noise floor value detected (%d) is " | 35 | "noise floor value detected (%d) is " |
36 | "lower than what we think is a " | 36 | "lower than what we think is a " |
37 | "reasonable value (%d)\n", | 37 | "reasonable value (%d)\n", |
38 | __func__, nf, ATH9K_NF_TOO_LOW); | 38 | nf, ATH9K_NF_TOO_LOW); |
39 | return false; | 39 | return false; |
40 | } | 40 | } |
41 | return true; | 41 | return true; |
@@ -116,7 +116,7 @@ static void ath9k_hw_do_getnf(struct ath_hal *ah, | |||
116 | 116 | ||
117 | if (nf & 0x100) | 117 | if (nf & 0x100) |
118 | nf = 0 - ((nf ^ 0x1ff) + 1); | 118 | nf = 0 - ((nf ^ 0x1ff) + 1); |
119 | DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL, | 119 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, |
120 | "NF calibrated [ctl] [chain 1] is %d\n", nf); | 120 | "NF calibrated [ctl] [chain 1] is %d\n", nf); |
121 | nfarray[1] = nf; | 121 | nfarray[1] = nf; |
122 | 122 | ||
@@ -125,7 +125,7 @@ static void ath9k_hw_do_getnf(struct ath_hal *ah, | |||
125 | AR_PHY_CH2_MINCCA_PWR); | 125 | AR_PHY_CH2_MINCCA_PWR); |
126 | if (nf & 0x100) | 126 | if (nf & 0x100) |
127 | nf = 0 - ((nf ^ 0x1ff) + 1); | 127 | nf = 0 - ((nf ^ 0x1ff) + 1); |
128 | DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL, | 128 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, |
129 | "NF calibrated [ctl] [chain 2] is %d\n", nf); | 129 | "NF calibrated [ctl] [chain 2] is %d\n", nf); |
130 | nfarray[2] = nf; | 130 | nfarray[2] = nf; |
131 | } | 131 | } |
@@ -139,7 +139,7 @@ static void ath9k_hw_do_getnf(struct ath_hal *ah, | |||
139 | 139 | ||
140 | if (nf & 0x100) | 140 | if (nf & 0x100) |
141 | nf = 0 - ((nf ^ 0x1ff) + 1); | 141 | nf = 0 - ((nf ^ 0x1ff) + 1); |
142 | DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL, | 142 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, |
143 | "NF calibrated [ext] [chain 0] is %d\n", nf); | 143 | "NF calibrated [ext] [chain 0] is %d\n", nf); |
144 | nfarray[3] = nf; | 144 | nfarray[3] = nf; |
145 | 145 | ||
@@ -161,7 +161,7 @@ static void ath9k_hw_do_getnf(struct ath_hal *ah, | |||
161 | AR_PHY_CH2_EXT_MINCCA_PWR); | 161 | AR_PHY_CH2_EXT_MINCCA_PWR); |
162 | if (nf & 0x100) | 162 | if (nf & 0x100) |
163 | nf = 0 - ((nf ^ 0x1ff) + 1); | 163 | nf = 0 - ((nf ^ 0x1ff) + 1); |
164 | DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL, | 164 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, |
165 | "NF calibrated [ext] [chain 2] is %d\n", nf); | 165 | "NF calibrated [ext] [chain 2] is %d\n", nf); |
166 | nfarray[5] = nf; | 166 | nfarray[5] = nf; |
167 | } | 167 | } |
@@ -187,8 +187,7 @@ static bool getNoiseFloorThresh(struct ath_hal *ah, | |||
187 | break; | 187 | break; |
188 | default: | 188 | default: |
189 | DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, | 189 | DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, |
190 | "%s: invalid channel flags 0x%x\n", __func__, | 190 | "invalid channel flags 0x%x\n", chan->channelFlags); |
191 | chan->channelFlags); | ||
192 | return false; | 191 | return false; |
193 | } | 192 | } |
194 | 193 | ||
@@ -206,24 +205,22 @@ static void ath9k_hw_setup_calibration(struct ath_hal *ah, | |||
206 | case IQ_MISMATCH_CAL: | 205 | case IQ_MISMATCH_CAL: |
207 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ); | 206 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ); |
208 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 207 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, |
209 | "%s: starting IQ Mismatch Calibration\n", | 208 | "starting IQ Mismatch Calibration\n"); |
210 | __func__); | ||
211 | break; | 209 | break; |
212 | case ADC_GAIN_CAL: | 210 | case ADC_GAIN_CAL: |
213 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN); | 211 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN); |
214 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 212 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, |
215 | "%s: starting ADC Gain Calibration\n", __func__); | 213 | "starting ADC Gain Calibration\n"); |
216 | break; | 214 | break; |
217 | case ADC_DC_CAL: | 215 | case ADC_DC_CAL: |
218 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER); | 216 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER); |
219 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 217 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, |
220 | "%s: starting ADC DC Calibration\n", __func__); | 218 | "starting ADC DC Calibration\n"); |
221 | break; | 219 | break; |
222 | case ADC_DC_INIT_CAL: | 220 | case ADC_DC_INIT_CAL: |
223 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT); | 221 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT); |
224 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 222 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, |
225 | "%s: starting Init ADC DC Calibration\n", | 223 | "starting Init ADC DC Calibration\n"); |
226 | __func__); | ||
227 | break; | 224 | break; |
228 | } | 225 | } |
229 | 226 | ||
@@ -594,16 +591,16 @@ void ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan, | |||
594 | 591 | ||
595 | if (ichan == NULL) { | 592 | if (ichan == NULL) { |
596 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 593 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, |
597 | "%s: invalid channel %u/0x%x; no mapping\n", | 594 | "invalid channel %u/0x%x; no mapping\n", |
598 | __func__, chan->channel, chan->channelFlags); | 595 | chan->channel, chan->channelFlags); |
599 | return; | 596 | return; |
600 | } | 597 | } |
601 | 598 | ||
602 | 599 | ||
603 | if (currCal->calState != CAL_DONE) { | 600 | if (currCal->calState != CAL_DONE) { |
604 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 601 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, |
605 | "%s: Calibration state incorrect, %d\n", | 602 | "Calibration state incorrect, %d\n", |
606 | __func__, currCal->calState); | 603 | currCal->calState); |
607 | return; | 604 | return; |
608 | } | 605 | } |
609 | 606 | ||
@@ -612,8 +609,8 @@ void ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan, | |||
612 | return; | 609 | return; |
613 | 610 | ||
614 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 611 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, |
615 | "%s: Resetting Cal %d state for channel %u/0x%x\n", | 612 | "Resetting Cal %d state for channel %u/0x%x\n", |
616 | __func__, currCal->calData->calType, chan->channel, | 613 | currCal->calData->calType, chan->channel, |
617 | chan->channelFlags); | 614 | chan->channelFlags); |
618 | 615 | ||
619 | ichan->CalValid &= ~currCal->calData->calType; | 616 | ichan->CalValid &= ~currCal->calData->calType; |
@@ -705,8 +702,7 @@ int16_t ath9k_hw_getnf(struct ath_hal *ah, | |||
705 | chan->channelFlags &= (~CHANNEL_CW_INT); | 702 | chan->channelFlags &= (~CHANNEL_CW_INT); |
706 | if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) { | 703 | if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) { |
707 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 704 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, |
708 | "%s: NF did not complete in calibration window\n", | 705 | "NF did not complete in calibration window\n"); |
709 | __func__); | ||
710 | nf = 0; | 706 | nf = 0; |
711 | chan->rawNoiseFloor = nf; | 707 | chan->rawNoiseFloor = nf; |
712 | return chan->rawNoiseFloor; | 708 | return chan->rawNoiseFloor; |
@@ -716,8 +712,8 @@ int16_t ath9k_hw_getnf(struct ath_hal *ah, | |||
716 | if (getNoiseFloorThresh(ah, chan, &nfThresh) | 712 | if (getNoiseFloorThresh(ah, chan, &nfThresh) |
717 | && nf > nfThresh) { | 713 | && nf > nfThresh) { |
718 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 714 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, |
719 | "%s: noise floor failed detected; " | 715 | "noise floor failed detected; " |
720 | "detected %d, threshold %d\n", __func__, | 716 | "detected %d, threshold %d\n", |
721 | nf, nfThresh); | 717 | nf, nfThresh); |
722 | chan->channelFlags |= CHANNEL_CW_INT; | 718 | chan->channelFlags |= CHANNEL_CW_INT; |
723 | } | 719 | } |
@@ -759,9 +755,9 @@ s16 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan) | |||
759 | 755 | ||
760 | ichan = ath9k_regd_check_channel(ah, chan); | 756 | ichan = ath9k_regd_check_channel(ah, chan); |
761 | if (ichan == NULL) { | 757 | if (ichan == NULL) { |
762 | DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL, | 758 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, |
763 | "%s: invalid channel %u/0x%x; no mapping\n", | 759 | "invalid channel %u/0x%x; no mapping\n", |
764 | __func__, chan->channel, chan->channelFlags); | 760 | chan->channel, chan->channelFlags); |
765 | return ATH_DEFAULT_NOISE_FLOOR; | 761 | return ATH_DEFAULT_NOISE_FLOOR; |
766 | } | 762 | } |
767 | if (ichan->rawNoiseFloor == 0) { | 763 | if (ichan->rawNoiseFloor == 0) { |
@@ -788,8 +784,8 @@ bool ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan, | |||
788 | 784 | ||
789 | if (ichan == NULL) { | 785 | if (ichan == NULL) { |
790 | DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, | 786 | DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, |
791 | "%s: invalid channel %u/0x%x; no mapping\n", | 787 | "invalid channel %u/0x%x; no mapping\n", |
792 | __func__, chan->channel, chan->channelFlags); | 788 | chan->channel, chan->channelFlags); |
793 | return false; | 789 | return false; |
794 | } | 790 | } |
795 | 791 | ||
@@ -834,8 +830,8 @@ bool ath9k_hw_init_cal(struct ath_hal *ah, | |||
834 | 830 | ||
835 | if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) { | 831 | if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) { |
836 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 832 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, |
837 | "%s: offset calibration failed to complete in 1ms; " | 833 | "offset calibration failed to complete in 1ms; " |
838 | "noisy environment?\n", __func__); | 834 | "noisy environment?\n"); |
839 | return false; | 835 | return false; |
840 | } | 836 | } |
841 | 837 | ||
@@ -850,22 +846,19 @@ bool ath9k_hw_init_cal(struct ath_hal *ah, | |||
850 | INIT_CAL(&ahp->ah_adcGainCalData); | 846 | INIT_CAL(&ahp->ah_adcGainCalData); |
851 | INSERT_CAL(ahp, &ahp->ah_adcGainCalData); | 847 | INSERT_CAL(ahp, &ahp->ah_adcGainCalData); |
852 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 848 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, |
853 | "%s: enabling ADC Gain Calibration.\n", | 849 | "enabling ADC Gain Calibration.\n"); |
854 | __func__); | ||
855 | } | 850 | } |
856 | if (ath9k_hw_iscal_supported(ah, chan, ADC_DC_CAL)) { | 851 | if (ath9k_hw_iscal_supported(ah, chan, ADC_DC_CAL)) { |
857 | INIT_CAL(&ahp->ah_adcDcCalData); | 852 | INIT_CAL(&ahp->ah_adcDcCalData); |
858 | INSERT_CAL(ahp, &ahp->ah_adcDcCalData); | 853 | INSERT_CAL(ahp, &ahp->ah_adcDcCalData); |
859 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 854 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, |
860 | "%s: enabling ADC DC Calibration.\n", | 855 | "enabling ADC DC Calibration.\n"); |
861 | __func__); | ||
862 | } | 856 | } |
863 | if (ath9k_hw_iscal_supported(ah, chan, IQ_MISMATCH_CAL)) { | 857 | if (ath9k_hw_iscal_supported(ah, chan, IQ_MISMATCH_CAL)) { |
864 | INIT_CAL(&ahp->ah_iqCalData); | 858 | INIT_CAL(&ahp->ah_iqCalData); |
865 | INSERT_CAL(ahp, &ahp->ah_iqCalData); | 859 | INSERT_CAL(ahp, &ahp->ah_iqCalData); |
866 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 860 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, |
867 | "%s: enabling IQ Calibration.\n", | 861 | "enabling IQ Calibration.\n"); |
868 | __func__); | ||
869 | } | 862 | } |
870 | 863 | ||
871 | ahp->ah_cal_list_curr = ahp->ah_cal_list; | 864 | ahp->ah_cal_list_curr = ahp->ah_cal_list; |
diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index f0c54377dfe6..a500d1770534 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h | |||
@@ -17,27 +17,8 @@ | |||
17 | #ifndef CORE_H | 17 | #ifndef CORE_H |
18 | #define CORE_H | 18 | #define CORE_H |
19 | 19 | ||
20 | #include <linux/version.h> | ||
21 | #include <linux/autoconf.h> | ||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/spinlock.h> | ||
25 | #include <linux/errno.h> | ||
26 | #include <linux/skbuff.h> | ||
27 | #include <linux/netdevice.h> | ||
28 | #include <linux/etherdevice.h> | 20 | #include <linux/etherdevice.h> |
29 | #include <linux/ip.h> | ||
30 | #include <linux/tcp.h> | ||
31 | #include <linux/in.h> | ||
32 | #include <linux/delay.h> | ||
33 | #include <linux/wait.h> | ||
34 | #include <linux/pci.h> | 21 | #include <linux/pci.h> |
35 | #include <linux/interrupt.h> | ||
36 | #include <linux/sched.h> | ||
37 | #include <linux/list.h> | ||
38 | #include <asm/byteorder.h> | ||
39 | #include <linux/scatterlist.h> | ||
40 | #include <asm/page.h> | ||
41 | #include <net/mac80211.h> | 22 | #include <net/mac80211.h> |
42 | #include <linux/leds.h> | 23 | #include <linux/leds.h> |
43 | #include <linux/rfkill.h> | 24 | #include <linux/rfkill.h> |
@@ -84,52 +65,64 @@ struct ath_node; | |||
84 | 65 | ||
85 | static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; | 66 | static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; |
86 | 67 | ||
87 | /*************/ | ||
88 | /* Debugging */ | ||
89 | /*************/ | ||
90 | |||
91 | enum ATH_DEBUG { | 68 | enum ATH_DEBUG { |
92 | ATH_DBG_RESET = 0x00000001, | 69 | ATH_DBG_RESET = 0x00000001, |
93 | ATH_DBG_PHY_IO = 0x00000002, | 70 | ATH_DBG_REG_IO = 0x00000002, |
94 | ATH_DBG_REG_IO = 0x00000004, | 71 | ATH_DBG_QUEUE = 0x00000004, |
95 | ATH_DBG_QUEUE = 0x00000008, | 72 | ATH_DBG_EEPROM = 0x00000008, |
96 | ATH_DBG_EEPROM = 0x00000010, | 73 | ATH_DBG_CALIBRATE = 0x00000010, |
97 | ATH_DBG_NF_CAL = 0x00000020, | 74 | ATH_DBG_CHANNEL = 0x00000020, |
98 | ATH_DBG_CALIBRATE = 0x00000040, | 75 | ATH_DBG_INTERRUPT = 0x00000040, |
99 | ATH_DBG_CHANNEL = 0x00000080, | 76 | ATH_DBG_REGULATORY = 0x00000080, |
100 | ATH_DBG_INTERRUPT = 0x00000100, | 77 | ATH_DBG_ANI = 0x00000100, |
101 | ATH_DBG_REGULATORY = 0x00000200, | 78 | ATH_DBG_POWER_MGMT = 0x00000200, |
102 | ATH_DBG_ANI = 0x00000400, | 79 | ATH_DBG_XMIT = 0x00000400, |
103 | ATH_DBG_POWER_MGMT = 0x00000800, | 80 | ATH_DBG_BEACON = 0x00001000, |
104 | ATH_DBG_XMIT = 0x00001000, | 81 | ATH_DBG_CONFIG = 0x00002000, |
105 | ATH_DBG_BEACON = 0x00002000, | 82 | ATH_DBG_KEYCACHE = 0x00004000, |
106 | ATH_DBG_RATE = 0x00004000, | 83 | ATH_DBG_FATAL = 0x00008000, |
107 | ATH_DBG_CONFIG = 0x00008000, | ||
108 | ATH_DBG_KEYCACHE = 0x00010000, | ||
109 | ATH_DBG_AGGR = 0x00020000, | ||
110 | ATH_DBG_FATAL = 0x00040000, | ||
111 | ATH_DBG_ANY = 0xffffffff | 84 | ATH_DBG_ANY = 0xffffffff |
112 | }; | 85 | }; |
113 | 86 | ||
114 | #define DBG_DEFAULT (ATH_DBG_FATAL) | 87 | #define DBG_DEFAULT (ATH_DBG_FATAL) |
115 | 88 | ||
116 | #define DPRINTF(sc, _m, _fmt, ...) do { \ | 89 | #ifdef CONFIG_ATH9K_DEBUG |
117 | if (sc->sc_debug & (_m)) \ | 90 | |
118 | printk(_fmt , ##__VA_ARGS__); \ | 91 | struct ath9k_debug { |
119 | } while (0) | 92 | int debug_mask; |
93 | struct dentry *debugfs_root; | ||
94 | struct dentry *debugfs_phy; | ||
95 | struct dentry *debugfs_dma; | ||
96 | }; | ||
97 | |||
98 | void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...); | ||
99 | int ath9k_init_debug(struct ath_softc *sc); | ||
100 | void ath9k_exit_debug(struct ath_softc *sc); | ||
101 | |||
102 | #else | ||
103 | |||
104 | static inline void DPRINTF(struct ath_softc *sc, int dbg_mask, | ||
105 | const char *fmt, ...) | ||
106 | { | ||
107 | } | ||
120 | 108 | ||
121 | /***************************/ | 109 | static inline int ath9k_init_debug(struct ath_softc *sc) |
122 | /* Load-time Configuration */ | 110 | { |
123 | /***************************/ | 111 | return 0; |
112 | } | ||
113 | |||
114 | static inline void ath9k_exit_debug(struct ath_softc *sc) | ||
115 | { | ||
116 | } | ||
117 | |||
118 | #endif /* CONFIG_ATH9K_DEBUG */ | ||
124 | 119 | ||
125 | /* Per-instance load-time (note: NOT run-time) configurations | ||
126 | * for Atheros Device */ | ||
127 | struct ath_config { | 120 | struct ath_config { |
128 | u32 ath_aggr_prot; | 121 | u32 ath_aggr_prot; |
129 | u16 txpowlimit; | 122 | u16 txpowlimit; |
130 | u16 txpowlimit_override; | 123 | u16 txpowlimit_override; |
131 | u8 cabqReadytime; /* Cabq Readytime % */ | 124 | u8 cabqReadytime; |
132 | u8 swBeaconProcess; /* Process received beacons in SW (vs HW) */ | 125 | u8 swBeaconProcess; |
133 | }; | 126 | }; |
134 | 127 | ||
135 | /*************************/ | 128 | /*************************/ |
@@ -160,14 +153,13 @@ enum buffer_type { | |||
160 | }; | 153 | }; |
161 | 154 | ||
162 | struct ath_buf_state { | 155 | struct ath_buf_state { |
163 | int bfs_nframes; /* # frames in aggregate */ | 156 | int bfs_nframes; /* # frames in aggregate */ |
164 | u16 bfs_al; /* length of aggregate */ | 157 | u16 bfs_al; /* length of aggregate */ |
165 | u16 bfs_frmlen; /* length of frame */ | 158 | u16 bfs_frmlen; /* length of frame */ |
166 | int bfs_seqno; /* sequence number */ | 159 | int bfs_seqno; /* sequence number */ |
167 | int bfs_tidno; /* tid of this frame */ | 160 | int bfs_tidno; /* tid of this frame */ |
168 | int bfs_retries; /* current retries */ | 161 | int bfs_retries; /* current retries */ |
169 | u32 bf_type; /* BUF_* (enum buffer_type) */ | 162 | u32 bf_type; /* BUF_* (enum buffer_type) */ |
170 | /* key type use to encrypt this frame */ | ||
171 | u32 bfs_keyix; | 163 | u32 bfs_keyix; |
172 | enum ath9k_key_type bfs_keytype; | 164 | enum ath9k_key_type bfs_keytype; |
173 | }; | 165 | }; |
@@ -213,13 +205,6 @@ struct ath_buf { | |||
213 | dma_addr_t bf_dmacontext; | 205 | dma_addr_t bf_dmacontext; |
214 | }; | 206 | }; |
215 | 207 | ||
216 | /* | ||
217 | * reset the rx buffer. | ||
218 | * any new fields added to the athbuf and require | ||
219 | * reset need to be added to this macro. | ||
220 | * currently bf_status is the only one requires that | ||
221 | * requires reset. | ||
222 | */ | ||
223 | #define ATH_RXBUF_RESET(_bf) ((_bf)->bf_status = 0) | 208 | #define ATH_RXBUF_RESET(_bf) ((_bf)->bf_status = 0) |
224 | 209 | ||
225 | /* hw processing complete, desc processed by hal */ | 210 | /* hw processing complete, desc processed by hal */ |
@@ -263,11 +248,8 @@ void ath_rx_cleanup(struct ath_softc *sc); | |||
263 | int ath_rx_tasklet(struct ath_softc *sc, int flush); | 248 | int ath_rx_tasklet(struct ath_softc *sc, int flush); |
264 | 249 | ||
265 | #define ATH_TXBUF 512 | 250 | #define ATH_TXBUF 512 |
266 | /* max number of transmit attempts (tries) */ | ||
267 | #define ATH_TXMAXTRY 13 | 251 | #define ATH_TXMAXTRY 13 |
268 | /* max number of 11n transmit attempts (tries) */ | ||
269 | #define ATH_11N_TXMAXTRY 10 | 252 | #define ATH_11N_TXMAXTRY 10 |
270 | /* max number of tries for management and control frames */ | ||
271 | #define ATH_MGT_TXMAXTRY 4 | 253 | #define ATH_MGT_TXMAXTRY 4 |
272 | #define WME_BA_BMP_SIZE 64 | 254 | #define WME_BA_BMP_SIZE 64 |
273 | #define WME_MAX_BA WME_BA_BMP_SIZE | 255 | #define WME_MAX_BA WME_BA_BMP_SIZE |
@@ -279,22 +261,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush); | |||
279 | WME_AC_VO) | 261 | WME_AC_VO) |
280 | 262 | ||
281 | 263 | ||
282 | /* Wireless Multimedia Extension Defines */ | 264 | #define WME_AC_BE 0 |
283 | #define WME_AC_BE 0 /* best effort */ | 265 | #define WME_AC_BK 1 |
284 | #define WME_AC_BK 1 /* background */ | 266 | #define WME_AC_VI 2 |
285 | #define WME_AC_VI 2 /* video */ | 267 | #define WME_AC_VO 3 |
286 | #define WME_AC_VO 3 /* voice */ | 268 | #define WME_NUM_AC 4 |
287 | #define WME_NUM_AC 4 | ||
288 | 269 | ||
289 | /* | ||
290 | * Data transmit queue state. One of these exists for each | ||
291 | * hardware transmit queue. Packets sent to us from above | ||
292 | * are assigned to queues based on their priority. Not all | ||
293 | * devices support a complete set of hardware transmit queues. | ||
294 | * For those devices the array sc_ac2q will map multiple | ||
295 | * priorities to fewer hardware queues (typically all to one | ||
296 | * hardware queue). | ||
297 | */ | ||
298 | struct ath_txq { | 270 | struct ath_txq { |
299 | u32 axq_qnum; /* hardware q number */ | 271 | u32 axq_qnum; /* hardware q number */ |
300 | u32 *axq_link; /* link ptr in last TX desc */ | 272 | u32 *axq_link; /* link ptr in last TX desc */ |
@@ -372,14 +344,15 @@ struct ath_xmit_status { | |||
372 | #define ATH_TX_BAR 0x04 | 344 | #define ATH_TX_BAR 0x04 |
373 | }; | 345 | }; |
374 | 346 | ||
347 | /* All RSSI values are noise floor adjusted */ | ||
375 | struct ath_tx_stat { | 348 | struct ath_tx_stat { |
376 | int rssi; /* RSSI (noise floor ajusted) */ | 349 | int rssi; |
377 | int rssictl[ATH_MAX_ANTENNA]; /* RSSI (noise floor ajusted) */ | 350 | int rssictl[ATH_MAX_ANTENNA]; |
378 | int rssiextn[ATH_MAX_ANTENNA]; /* RSSI (noise floor ajusted) */ | 351 | int rssiextn[ATH_MAX_ANTENNA]; |
379 | int rateieee; /* data rate xmitted (IEEE rate code) */ | 352 | int rateieee; |
380 | int rateKbps; /* data rate xmitted (Kbps) */ | 353 | int rateKbps; |
381 | int ratecode; /* phy rate code */ | 354 | int ratecode; |
382 | int flags; /* validity flags */ | 355 | int flags; |
383 | /* if any of ctl,extn chain rssis are valid */ | 356 | /* if any of ctl,extn chain rssis are valid */ |
384 | #define ATH_TX_CHAIN_RSSI_VALID 0x01 | 357 | #define ATH_TX_CHAIN_RSSI_VALID 0x01 |
385 | /* if extn chain rssis are valid */ | 358 | /* if extn chain rssis are valid */ |
@@ -415,7 +388,7 @@ void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb); | |||
415 | /**********************/ | 388 | /**********************/ |
416 | 389 | ||
417 | #define ADDBA_EXCHANGE_ATTEMPTS 10 | 390 | #define ADDBA_EXCHANGE_ATTEMPTS 10 |
418 | #define ATH_AGGR_DELIM_SZ 4 /* delimiter size */ | 391 | #define ATH_AGGR_DELIM_SZ 4 |
419 | #define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */ | 392 | #define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */ |
420 | /* number of delimiters for encryption padding */ | 393 | /* number of delimiters for encryption padding */ |
421 | #define ATH_AGGR_ENCRYPTDELIM 10 | 394 | #define ATH_AGGR_ENCRYPTDELIM 10 |
@@ -466,10 +439,9 @@ struct aggr_rifs_param { | |||
466 | 439 | ||
467 | /* Per-node aggregation state */ | 440 | /* Per-node aggregation state */ |
468 | struct ath_node_aggr { | 441 | struct ath_node_aggr { |
469 | struct ath_atx tx; /* node transmit state */ | 442 | struct ath_atx tx; |
470 | }; | 443 | }; |
471 | 444 | ||
472 | /* driver-specific node state */ | ||
473 | struct ath_node { | 445 | struct ath_node { |
474 | struct ath_softc *an_sc; | 446 | struct ath_softc *an_sc; |
475 | struct ath_node_aggr an_aggr; | 447 | struct ath_node_aggr an_aggr; |
@@ -500,12 +472,11 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid | |||
500 | #define ATH_SET_VAP_BSSID_MASK(bssid_mask) \ | 472 | #define ATH_SET_VAP_BSSID_MASK(bssid_mask) \ |
501 | ((bssid_mask)[0] &= ~(((ATH_BCBUF-1)<<2)|0x02)) | 473 | ((bssid_mask)[0] &= ~(((ATH_BCBUF-1)<<2)|0x02)) |
502 | 474 | ||
503 | /* driver-specific vap state */ | ||
504 | struct ath_vap { | 475 | struct ath_vap { |
505 | int av_bslot; /* beacon slot index */ | 476 | int av_bslot; |
506 | enum ath9k_opmode av_opmode; /* VAP operational mode */ | 477 | enum nl80211_iftype av_opmode; |
507 | struct ath_buf *av_bcbuf; /* beacon buffer */ | 478 | struct ath_buf *av_bcbuf; |
508 | struct ath_tx_control av_btxctl; /* txctl information for beacon */ | 479 | struct ath_tx_control av_btxctl; |
509 | }; | 480 | }; |
510 | 481 | ||
511 | /*******************/ | 482 | /*******************/ |
@@ -518,12 +489,11 @@ struct ath_vap { | |||
518 | * number of beacon intervals, the game's up. | 489 | * number of beacon intervals, the game's up. |
519 | */ | 490 | */ |
520 | #define BSTUCK_THRESH (9 * ATH_BCBUF) | 491 | #define BSTUCK_THRESH (9 * ATH_BCBUF) |
521 | #define ATH_BCBUF 4 /* number of beacon buffers */ | 492 | #define ATH_BCBUF 4 |
522 | #define ATH_DEFAULT_BINTVAL 100 /* default beacon interval in TU */ | 493 | #define ATH_DEFAULT_BINTVAL 100 /* TU */ |
523 | #define ATH_DEFAULT_BMISS_LIMIT 10 | 494 | #define ATH_DEFAULT_BMISS_LIMIT 10 |
524 | #define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024) | 495 | #define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024) |
525 | 496 | ||
526 | /* beacon configuration */ | ||
527 | struct ath_beacon_config { | 497 | struct ath_beacon_config { |
528 | u16 beacon_interval; | 498 | u16 beacon_interval; |
529 | u16 listen_interval; | 499 | u16 listen_interval; |
@@ -661,7 +631,9 @@ struct ath_softc { | |||
661 | u8 sc_myaddr[ETH_ALEN]; | 631 | u8 sc_myaddr[ETH_ALEN]; |
662 | u8 sc_bssidmask[ETH_ALEN]; | 632 | u8 sc_bssidmask[ETH_ALEN]; |
663 | 633 | ||
664 | int sc_debug; | 634 | #ifdef CONFIG_ATH9K_DEBUG |
635 | struct ath9k_debug sc_debug; | ||
636 | #endif | ||
665 | u32 sc_intrstatus; | 637 | u32 sc_intrstatus; |
666 | u32 sc_flags; /* SC_OP_* */ | 638 | u32 sc_flags; /* SC_OP_* */ |
667 | unsigned int rx_filter; | 639 | unsigned int rx_filter; |
@@ -674,18 +646,18 @@ struct ath_softc { | |||
674 | u8 sc_tx_chainmask; | 646 | u8 sc_tx_chainmask; |
675 | u8 sc_rx_chainmask; | 647 | u8 sc_rx_chainmask; |
676 | enum ath9k_int sc_imask; | 648 | enum ath9k_int sc_imask; |
677 | enum wireless_mode sc_curmode; /* current phy mode */ | 649 | enum wireless_mode sc_curmode; |
678 | enum PROT_MODE sc_protmode; | 650 | enum PROT_MODE sc_protmode; |
679 | 651 | ||
680 | u8 sc_nbcnvaps; /* # of vaps sending beacons */ | 652 | u8 sc_nbcnvaps; |
681 | u16 sc_nvaps; /* # of active virtual ap's */ | 653 | u16 sc_nvaps; |
682 | struct ieee80211_vif *sc_vaps[ATH_BCBUF]; | 654 | struct ieee80211_vif *sc_vaps[ATH_BCBUF]; |
683 | 655 | ||
684 | u8 sc_mcastantenna; | 656 | u8 sc_mcastantenna; |
685 | u8 sc_defant; /* current default antenna */ | 657 | u8 sc_defant; |
686 | u8 sc_rxotherant; /* rx's on non-default antenna */ | 658 | u8 sc_rxotherant; |
687 | 659 | ||
688 | struct ath9k_node_stats sc_halstats; /* station-mode rssi stats */ | 660 | struct ath9k_node_stats sc_halstats; |
689 | enum ath9k_ht_extprotspacing sc_ht_extprotspacing; | 661 | enum ath9k_ht_extprotspacing sc_ht_extprotspacing; |
690 | enum ath9k_ht_macmode tx_chan_width; | 662 | enum ath9k_ht_macmode tx_chan_width; |
691 | 663 | ||
@@ -699,22 +671,22 @@ struct ath_softc { | |||
699 | } sc_updateslot; /* slot time update fsm */ | 671 | } sc_updateslot; /* slot time update fsm */ |
700 | 672 | ||
701 | /* Crypto */ | 673 | /* Crypto */ |
702 | u32 sc_keymax; /* size of key cache */ | 674 | u32 sc_keymax; |
703 | DECLARE_BITMAP(sc_keymap, ATH_KEYMAX); /* key use bit map */ | 675 | DECLARE_BITMAP(sc_keymap, ATH_KEYMAX); |
704 | u8 sc_splitmic; /* split TKIP MIC keys */ | 676 | u8 sc_splitmic; /* split TKIP MIC keys */ |
705 | 677 | ||
706 | /* RX */ | 678 | /* RX */ |
707 | struct list_head sc_rxbuf; | 679 | struct list_head sc_rxbuf; |
708 | struct ath_descdma sc_rxdma; | 680 | struct ath_descdma sc_rxdma; |
709 | int sc_rxbufsize; /* rx size based on mtu */ | 681 | int sc_rxbufsize; |
710 | u32 *sc_rxlink; /* link ptr in last RX desc */ | 682 | u32 *sc_rxlink; |
711 | 683 | ||
712 | /* TX */ | 684 | /* TX */ |
713 | struct list_head sc_txbuf; | 685 | struct list_head sc_txbuf; |
714 | struct ath_txq sc_txq[ATH9K_NUM_TX_QUEUES]; | 686 | struct ath_txq sc_txq[ATH9K_NUM_TX_QUEUES]; |
715 | struct ath_descdma sc_txdma; | 687 | struct ath_descdma sc_txdma; |
716 | u32 sc_txqsetup; | 688 | u32 sc_txqsetup; |
717 | int sc_haltype2q[ATH9K_WME_AC_VO+1]; /* HAL WME AC -> h/w qnum */ | 689 | int sc_haltype2q[ATH9K_WME_AC_VO+1]; |
718 | u16 seq_no; /* TX sequence number */ | 690 | u16 seq_no; /* TX sequence number */ |
719 | 691 | ||
720 | /* Beacon */ | 692 | /* Beacon */ |
@@ -724,13 +696,13 @@ struct ath_softc { | |||
724 | struct list_head sc_bbuf; | 696 | struct list_head sc_bbuf; |
725 | u32 sc_bhalq; | 697 | u32 sc_bhalq; |
726 | u32 sc_bmisscount; | 698 | u32 sc_bmisscount; |
727 | u32 ast_be_xmit; /* beacons transmitted */ | 699 | u32 ast_be_xmit; |
728 | u64 bc_tstamp; | 700 | u64 bc_tstamp; |
729 | 701 | ||
730 | /* Rate */ | 702 | /* Rate */ |
731 | struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX]; | 703 | struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX]; |
732 | struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX]; | 704 | struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX]; |
733 | u8 sc_protrix; /* protection rate index */ | 705 | u8 sc_protrix; |
734 | 706 | ||
735 | /* Channel, Band */ | 707 | /* Channel, Band */ |
736 | struct ieee80211_channel channels[IEEE80211_NUM_BANDS][ATH_CHAN_MAX]; | 708 | struct ieee80211_channel channels[IEEE80211_NUM_BANDS][ATH_CHAN_MAX]; |
diff --git a/drivers/net/wireless/ath9k/debug.c b/drivers/net/wireless/ath9k/debug.c new file mode 100644 index 000000000000..da52812c3a94 --- /dev/null +++ b/drivers/net/wireless/ath9k/debug.c | |||
@@ -0,0 +1,160 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "core.h" | ||
18 | #include "reg.h" | ||
19 | #include "hw.h" | ||
20 | |||
21 | static unsigned int ath9k_debug = DBG_DEFAULT; | ||
22 | module_param_named(debug, ath9k_debug, uint, 0); | ||
23 | |||
24 | void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...) | ||
25 | { | ||
26 | if (!sc) | ||
27 | return; | ||
28 | |||
29 | if (sc->sc_debug.debug_mask & dbg_mask) { | ||
30 | va_list args; | ||
31 | |||
32 | va_start(args, fmt); | ||
33 | printk(KERN_DEBUG "ath9k: "); | ||
34 | vprintk(fmt, args); | ||
35 | va_end(args); | ||
36 | } | ||
37 | } | ||
38 | |||
39 | static int ath9k_debugfs_open(struct inode *inode, struct file *file) | ||
40 | { | ||
41 | file->private_data = inode->i_private; | ||
42 | return 0; | ||
43 | } | ||
44 | |||
45 | static ssize_t read_file_dma(struct file *file, char __user *user_buf, | ||
46 | size_t count, loff_t *ppos) | ||
47 | { | ||
48 | struct ath_softc *sc = file->private_data; | ||
49 | struct ath_hal *ah = sc->sc_ah; | ||
50 | char buf[1024]; | ||
51 | unsigned int len = 0; | ||
52 | u32 val[ATH9K_NUM_DMA_DEBUG_REGS]; | ||
53 | int i, qcuOffset = 0, dcuOffset = 0; | ||
54 | u32 *qcuBase = &val[0], *dcuBase = &val[4]; | ||
55 | |||
56 | REG_WRITE(ah, AR_MACMISC, | ||
57 | ((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) | | ||
58 | (AR_MACMISC_MISC_OBS_BUS_1 << | ||
59 | AR_MACMISC_MISC_OBS_BUS_MSB_S))); | ||
60 | |||
61 | len += snprintf(buf + len, sizeof(buf) - len, | ||
62 | "Raw DMA Debug values:\n"); | ||
63 | |||
64 | for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) { | ||
65 | if (i % 4 == 0) | ||
66 | len += snprintf(buf + len, sizeof(buf) - len, "\n"); | ||
67 | |||
68 | val[i] = REG_READ(ah, AR_DMADBG_0 + (i * sizeof(u32))); | ||
69 | len += snprintf(buf + len, sizeof(buf) - len, "%d: %08x ", | ||
70 | i, val[i]); | ||
71 | } | ||
72 | |||
73 | len += snprintf(buf + len, sizeof(buf) - len, "\n\n"); | ||
74 | len += snprintf(buf + len, sizeof(buf) - len, | ||
75 | "Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n"); | ||
76 | |||
77 | for (i = 0; i < ATH9K_NUM_QUEUES; i++, qcuOffset += 4, dcuOffset += 5) { | ||
78 | if (i == 8) { | ||
79 | qcuOffset = 0; | ||
80 | qcuBase++; | ||
81 | } | ||
82 | |||
83 | if (i == 6) { | ||
84 | dcuOffset = 0; | ||
85 | dcuBase++; | ||
86 | } | ||
87 | |||
88 | len += snprintf(buf + len, sizeof(buf) - len, | ||
89 | "%2d %2x %1x %2x %2x\n", | ||
90 | i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset, | ||
91 | (*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset + 3), | ||
92 | val[2] & (0x7 << (i * 3)) >> (i * 3), | ||
93 | (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset); | ||
94 | } | ||
95 | |||
96 | len += snprintf(buf + len, sizeof(buf) - len, "\n"); | ||
97 | |||
98 | len += snprintf(buf + len, sizeof(buf) - len, | ||
99 | "qcu_stitch state: %2x qcu_fetch state: %2x\n", | ||
100 | (val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22); | ||
101 | len += snprintf(buf + len, sizeof(buf) - len, | ||
102 | "qcu_complete state: %2x dcu_complete state: %2x\n", | ||
103 | (val[3] & 0x1c000000) >> 26, (val[6] & 0x3)); | ||
104 | len += snprintf(buf + len, sizeof(buf) - len, | ||
105 | "dcu_arb state: %2x dcu_fp state: %2x\n", | ||
106 | (val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27); | ||
107 | len += snprintf(buf + len, sizeof(buf) - len, | ||
108 | "chan_idle_dur: %3d chan_idle_dur_valid: %1d\n", | ||
109 | (val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10); | ||
110 | len += snprintf(buf + len, sizeof(buf) - len, | ||
111 | "txfifo_valid_0: %1d txfifo_valid_1: %1d\n", | ||
112 | (val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12); | ||
113 | len += snprintf(buf + len, sizeof(buf) - len, | ||
114 | "txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n", | ||
115 | (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17); | ||
116 | |||
117 | len += snprintf(buf + len, sizeof(buf) - len, "pcu observe: 0x%x \n", | ||
118 | REG_READ(ah, AR_OBS_BUS_1)); | ||
119 | len += snprintf(buf + len, sizeof(buf) - len, | ||
120 | "AR_CR: 0x%x \n", REG_READ(ah, AR_CR)); | ||
121 | |||
122 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
123 | } | ||
124 | |||
125 | static const struct file_operations fops_dma = { | ||
126 | .read = read_file_dma, | ||
127 | .open = ath9k_debugfs_open, | ||
128 | .owner = THIS_MODULE | ||
129 | }; | ||
130 | |||
131 | int ath9k_init_debug(struct ath_softc *sc) | ||
132 | { | ||
133 | sc->sc_debug.debug_mask = ath9k_debug; | ||
134 | |||
135 | sc->sc_debug.debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); | ||
136 | if (!sc->sc_debug.debugfs_root) | ||
137 | goto err; | ||
138 | |||
139 | sc->sc_debug.debugfs_phy = debugfs_create_dir(wiphy_name(sc->hw->wiphy), | ||
140 | sc->sc_debug.debugfs_root); | ||
141 | if (!sc->sc_debug.debugfs_phy) | ||
142 | goto err; | ||
143 | |||
144 | sc->sc_debug.debugfs_dma = debugfs_create_file("dma", S_IRUGO, | ||
145 | sc->sc_debug.debugfs_phy, sc, &fops_dma); | ||
146 | if (!sc->sc_debug.debugfs_dma) | ||
147 | goto err; | ||
148 | |||
149 | return 0; | ||
150 | err: | ||
151 | ath9k_exit_debug(sc); | ||
152 | return -ENOMEM; | ||
153 | } | ||
154 | |||
155 | void ath9k_exit_debug(struct ath_softc *sc) | ||
156 | { | ||
157 | debugfs_remove(sc->sc_debug.debugfs_dma); | ||
158 | debugfs_remove(sc->sc_debug.debugfs_phy); | ||
159 | debugfs_remove(sc->sc_debug.debugfs_root); | ||
160 | } | ||
diff --git a/drivers/net/wireless/ath9k/eeprom.c b/drivers/net/wireless/ath9k/eeprom.c index 466dbce2c5f7..e180c9043df6 100644 --- a/drivers/net/wireless/ath9k/eeprom.c +++ b/drivers/net/wireless/ath9k/eeprom.c | |||
@@ -116,7 +116,7 @@ static int ath9k_hw_flash_map(struct ath_hal *ah) | |||
116 | 116 | ||
117 | if (!ahp->ah_cal_mem) { | 117 | if (!ahp->ah_cal_mem) { |
118 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | 118 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, |
119 | "%s: cannot remap eeprom region \n", __func__); | 119 | "cannot remap eeprom region \n"); |
120 | return -EIO; | 120 | return -EIO; |
121 | } | 121 | } |
122 | 122 | ||
@@ -149,7 +149,7 @@ static bool ath9k_hw_fill_eeprom(struct ath_hal *ah) | |||
149 | 149 | ||
150 | if (!ath9k_hw_use_flash(ah)) { | 150 | if (!ath9k_hw_use_flash(ah)) { |
151 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | 151 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, |
152 | "%s: Reading from EEPROM, not flash\n", __func__); | 152 | "Reading from EEPROM, not flash\n"); |
153 | ar5416_eep_start_loc = 256; | 153 | ar5416_eep_start_loc = 256; |
154 | } | 154 | } |
155 | 155 | ||
@@ -162,8 +162,7 @@ static bool ath9k_hw_fill_eeprom(struct ath_hal *ah) | |||
162 | if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc, | 162 | if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc, |
163 | eep_data)) { | 163 | eep_data)) { |
164 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | 164 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, |
165 | "%s: Unable to read eeprom region \n", | 165 | "Unable to read eeprom region \n"); |
166 | __func__); | ||
167 | return false; | 166 | return false; |
168 | } | 167 | } |
169 | eep_data++; | 168 | eep_data++; |
@@ -185,12 +184,11 @@ static int ath9k_hw_check_eeprom(struct ath_hal *ah) | |||
185 | if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, | 184 | if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, |
186 | &magic)) { | 185 | &magic)) { |
187 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | 186 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, |
188 | "%s: Reading Magic # failed\n", __func__); | 187 | "Reading Magic # failed\n"); |
189 | return false; | 188 | return false; |
190 | } | 189 | } |
191 | 190 | ||
192 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "%s: Read Magic = 0x%04X\n", | 191 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "Read Magic = 0x%04X\n", magic); |
193 | __func__, magic); | ||
194 | 192 | ||
195 | if (magic != AR5416_EEPROM_MAGIC) { | 193 | if (magic != AR5416_EEPROM_MAGIC) { |
196 | magic2 = swab16(magic); | 194 | magic2 = swab16(magic); |
@@ -1205,11 +1203,11 @@ bool ath9k_hw_set_power_cal_table(struct ath_hal *ah, | |||
1205 | ((pdadcValues[4 * j + 3] & 0xFF) << 24); | 1203 | ((pdadcValues[4 * j + 3] & 0xFF) << 24); |
1206 | REG_WRITE(ah, regOffset, reg32); | 1204 | REG_WRITE(ah, regOffset, reg32); |
1207 | 1205 | ||
1208 | DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO, | 1206 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, |
1209 | "PDADC (%d,%4x): %4.4x %8.8x\n", | 1207 | "PDADC (%d,%4x): %4.4x %8.8x\n", |
1210 | i, regChainOffset, regOffset, | 1208 | i, regChainOffset, regOffset, |
1211 | reg32); | 1209 | reg32); |
1212 | DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO, | 1210 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, |
1213 | "PDADC: Chain %d | PDADC %3d Value %3d | " | 1211 | "PDADC: Chain %d | PDADC %3d Value %3d | " |
1214 | "PDADC %3d Value %3d | PDADC %3d Value %3d | " | 1212 | "PDADC %3d Value %3d | PDADC %3d Value %3d | " |
1215 | "PDADC %3d Value %3d |\n", | 1213 | "PDADC %3d Value %3d |\n", |
diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c index 6eef10477896..668865dce533 100644 --- a/drivers/net/wireless/ath9k/hw.c +++ b/drivers/net/wireless/ath9k/hw.c | |||
@@ -104,9 +104,10 @@ bool ath9k_hw_wait(struct ath_hal *ah, u32 reg, u32 mask, u32 val) | |||
104 | 104 | ||
105 | udelay(AH_TIME_QUANTUM); | 105 | udelay(AH_TIME_QUANTUM); |
106 | } | 106 | } |
107 | DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO, | 107 | |
108 | "%s: timeout on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n", | 108 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, |
109 | __func__, reg, REG_READ(ah, reg), mask, val); | 109 | "timeout on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n", |
110 | reg, REG_READ(ah, reg), mask, val); | ||
110 | 111 | ||
111 | return false; | 112 | return false; |
112 | } | 113 | } |
@@ -188,8 +189,8 @@ u16 ath9k_hw_computetxtime(struct ath_hal *ah, | |||
188 | } | 189 | } |
189 | break; | 190 | break; |
190 | default: | 191 | default: |
191 | DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO, | 192 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, |
192 | "%s: unknown phy %u (rate ix %u)\n", __func__, | 193 | "Unknown phy %u (rate ix %u)\n", |
193 | rates->info[rateix].phy, rateix); | 194 | rates->info[rateix].phy, rateix); |
194 | txTime = 0; | 195 | txTime = 0; |
195 | break; | 196 | break; |
@@ -355,9 +356,9 @@ static bool ath9k_hw_chip_test(struct ath_hal *ah) | |||
355 | rdData = REG_READ(ah, addr); | 356 | rdData = REG_READ(ah, addr); |
356 | if (rdData != wrData) { | 357 | if (rdData != wrData) { |
357 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, | 358 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, |
358 | "%s: address test failed " | 359 | "address test failed " |
359 | "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n", | 360 | "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n", |
360 | __func__, addr, wrData, rdData); | 361 | addr, wrData, rdData); |
361 | return false; | 362 | return false; |
362 | } | 363 | } |
363 | } | 364 | } |
@@ -367,9 +368,9 @@ static bool ath9k_hw_chip_test(struct ath_hal *ah) | |||
367 | rdData = REG_READ(ah, addr); | 368 | rdData = REG_READ(ah, addr); |
368 | if (wrData != rdData) { | 369 | if (wrData != rdData) { |
369 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, | 370 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, |
370 | "%s: address test failed " | 371 | "address test failed " |
371 | "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n", | 372 | "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n", |
372 | __func__, addr, wrData, rdData); | 373 | addr, wrData, rdData); |
373 | return false; | 374 | return false; |
374 | } | 375 | } |
375 | } | 376 | } |
@@ -449,8 +450,7 @@ static struct ath_hal_5416 *ath9k_hw_newstate(u16 devid, | |||
449 | ahp = kzalloc(sizeof(struct ath_hal_5416), GFP_KERNEL); | 450 | ahp = kzalloc(sizeof(struct ath_hal_5416), GFP_KERNEL); |
450 | if (ahp == NULL) { | 451 | if (ahp == NULL) { |
451 | DPRINTF(sc, ATH_DBG_FATAL, | 452 | DPRINTF(sc, ATH_DBG_FATAL, |
452 | "%s: cannot allocate memory for state block\n", | 453 | "Cannot allocate memory for state block\n"); |
453 | __func__); | ||
454 | *status = -ENOMEM; | 454 | *status = -ENOMEM; |
455 | return NULL; | 455 | return NULL; |
456 | } | 456 | } |
@@ -497,8 +497,7 @@ static int ath9k_hw_rfattach(struct ath_hal *ah) | |||
497 | rfStatus = ath9k_hw_init_rf(ah, &ecode); | 497 | rfStatus = ath9k_hw_init_rf(ah, &ecode); |
498 | if (!rfStatus) { | 498 | if (!rfStatus) { |
499 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, | 499 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, |
500 | "%s: RF setup failed, status %u\n", __func__, | 500 | "RF setup failed, status %u\n", ecode); |
501 | ecode); | ||
502 | return ecode; | 501 | return ecode; |
503 | } | 502 | } |
504 | 503 | ||
@@ -523,9 +522,9 @@ static int ath9k_hw_rf_claim(struct ath_hal *ah) | |||
523 | break; | 522 | break; |
524 | default: | 523 | default: |
525 | DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, | 524 | DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, |
526 | "%s: 5G Radio Chip Rev 0x%02X is not " | 525 | "5G Radio Chip Rev 0x%02X is not " |
527 | "supported by this driver\n", | 526 | "supported by this driver\n", |
528 | __func__, ah->ah_analog5GhzRev); | 527 | ah->ah_analog5GhzRev); |
529 | return -EOPNOTSUPP; | 528 | return -EOPNOTSUPP; |
530 | } | 529 | } |
531 | 530 | ||
@@ -550,7 +549,7 @@ static int ath9k_hw_init_macaddr(struct ath_hal *ah) | |||
550 | } | 549 | } |
551 | if (sum == 0 || sum == 0xffff * 3) { | 550 | if (sum == 0 || sum == 0xffff * 3) { |
552 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | 551 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, |
553 | "%s: mac address read failed: %pM\n", __func__, | 552 | "mac address read failed: %pM\n", |
554 | ahp->ah_macaddr); | 553 | ahp->ah_macaddr); |
555 | return -EADDRNOTAVAIL; | 554 | return -EADDRNOTAVAIL; |
556 | } | 555 | } |
@@ -612,7 +611,7 @@ static int ath9k_hw_post_attach(struct ath_hal *ah) | |||
612 | 611 | ||
613 | if (!ath9k_hw_chip_test(ah)) { | 612 | if (!ath9k_hw_chip_test(ah)) { |
614 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, | 613 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, |
615 | "%s: hardware self-test failed\n", __func__); | 614 | "hardware self-test failed\n"); |
616 | return -ENODEV; | 615 | return -ENODEV; |
617 | } | 616 | } |
618 | 617 | ||
@@ -658,15 +657,13 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, | |||
658 | ahp->ah_intrMitigation = true; | 657 | ahp->ah_intrMitigation = true; |
659 | 658 | ||
660 | if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) { | 659 | if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) { |
661 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: couldn't reset chip\n", | 660 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, "Couldn't reset chip\n"); |
662 | __func__); | ||
663 | ecode = -EIO; | 661 | ecode = -EIO; |
664 | goto bad; | 662 | goto bad; |
665 | } | 663 | } |
666 | 664 | ||
667 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) { | 665 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) { |
668 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: couldn't wakeup chip\n", | 666 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, "Couldn't wakeup chip\n"); |
669 | __func__); | ||
670 | ecode = -EIO; | 667 | ecode = -EIO; |
671 | goto bad; | 668 | goto bad; |
672 | } | 669 | } |
@@ -682,17 +679,16 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, | |||
682 | } | 679 | } |
683 | 680 | ||
684 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, | 681 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, |
685 | "%s: serialize_regmode is %d\n", | 682 | "serialize_regmode is %d\n", |
686 | __func__, ah->ah_config.serialize_regmode); | 683 | ah->ah_config.serialize_regmode); |
687 | 684 | ||
688 | if ((ah->ah_macVersion != AR_SREV_VERSION_5416_PCI) && | 685 | if ((ah->ah_macVersion != AR_SREV_VERSION_5416_PCI) && |
689 | (ah->ah_macVersion != AR_SREV_VERSION_5416_PCIE) && | 686 | (ah->ah_macVersion != AR_SREV_VERSION_5416_PCIE) && |
690 | (ah->ah_macVersion != AR_SREV_VERSION_9160) && | 687 | (ah->ah_macVersion != AR_SREV_VERSION_9160) && |
691 | (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah))) { | 688 | (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah))) { |
692 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, | 689 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, |
693 | "%s: Mac Chip Rev 0x%02x.%x is not supported by " | 690 | "Mac Chip Rev 0x%02x.%x is not supported by " |
694 | "this driver\n", __func__, | 691 | "this driver\n", ah->ah_macVersion, ah->ah_macRev); |
695 | ah->ah_macVersion, ah->ah_macRev); | ||
696 | ecode = -EOPNOTSUPP; | 692 | ecode = -EOPNOTSUPP; |
697 | goto bad; | 693 | goto bad; |
698 | } | 694 | } |
@@ -737,7 +733,7 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, | |||
737 | } | 733 | } |
738 | 734 | ||
739 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, | 735 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, |
740 | "%s: This Mac Chip Rev 0x%02x.%x is \n", __func__, | 736 | "This Mac Chip Rev 0x%02x.%x is \n", |
741 | ah->ah_macVersion, ah->ah_macRev); | 737 | ah->ah_macVersion, ah->ah_macRev); |
742 | 738 | ||
743 | if (AR_SREV_9280_20_OR_LATER(ah)) { | 739 | if (AR_SREV_9280_20_OR_LATER(ah)) { |
@@ -874,7 +870,7 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, | |||
874 | #endif | 870 | #endif |
875 | if (!ath9k_hw_fill_cap_info(ah)) { | 871 | if (!ath9k_hw_fill_cap_info(ah)) { |
876 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, | 872 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, |
877 | "%s:failed ath9k_hw_fill_cap_info\n", __func__); | 873 | "failed ath9k_hw_fill_cap_info\n"); |
878 | ecode = -EINVAL; | 874 | ecode = -EINVAL; |
879 | goto bad; | 875 | goto bad; |
880 | } | 876 | } |
@@ -882,8 +878,7 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, | |||
882 | ecode = ath9k_hw_init_macaddr(ah); | 878 | ecode = ath9k_hw_init_macaddr(ah); |
883 | if (ecode != 0) { | 879 | if (ecode != 0) { |
884 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, | 880 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, |
885 | "%s: failed initializing mac address\n", | 881 | "failed initializing mac address\n"); |
886 | __func__); | ||
887 | goto bad; | 882 | goto bad; |
888 | } | 883 | } |
889 | 884 | ||
@@ -1045,7 +1040,8 @@ static void ath9k_hw_init_chain_masks(struct ath_hal *ah) | |||
1045 | REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001); | 1040 | REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001); |
1046 | } | 1041 | } |
1047 | 1042 | ||
1048 | static void ath9k_hw_init_interrupt_masks(struct ath_hal *ah, enum ath9k_opmode opmode) | 1043 | static void ath9k_hw_init_interrupt_masks(struct ath_hal *ah, |
1044 | enum nl80211_iftype opmode) | ||
1049 | { | 1045 | { |
1050 | struct ath_hal_5416 *ahp = AH5416(ah); | 1046 | struct ath_hal_5416 *ahp = AH5416(ah); |
1051 | 1047 | ||
@@ -1062,7 +1058,7 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hal *ah, enum ath9k_opmode | |||
1062 | 1058 | ||
1063 | ahp->ah_maskReg |= AR_IMR_TXOK; | 1059 | ahp->ah_maskReg |= AR_IMR_TXOK; |
1064 | 1060 | ||
1065 | if (opmode == ATH9K_M_HOSTAP) | 1061 | if (opmode == NL80211_IFTYPE_AP) |
1066 | ahp->ah_maskReg |= AR_IMR_MIB; | 1062 | ahp->ah_maskReg |= AR_IMR_MIB; |
1067 | 1063 | ||
1068 | REG_WRITE(ah, AR_IMR, ahp->ah_maskReg); | 1064 | REG_WRITE(ah, AR_IMR, ahp->ah_maskReg); |
@@ -1080,8 +1076,7 @@ static bool ath9k_hw_set_ack_timeout(struct ath_hal *ah, u32 us) | |||
1080 | struct ath_hal_5416 *ahp = AH5416(ah); | 1076 | struct ath_hal_5416 *ahp = AH5416(ah); |
1081 | 1077 | ||
1082 | if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) { | 1078 | if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) { |
1083 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad ack timeout %u\n", | 1079 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad ack timeout %u\n", us); |
1084 | __func__, us); | ||
1085 | ahp->ah_acktimeout = (u32) -1; | 1080 | ahp->ah_acktimeout = (u32) -1; |
1086 | return false; | 1081 | return false; |
1087 | } else { | 1082 | } else { |
@@ -1097,8 +1092,7 @@ static bool ath9k_hw_set_cts_timeout(struct ath_hal *ah, u32 us) | |||
1097 | struct ath_hal_5416 *ahp = AH5416(ah); | 1092 | struct ath_hal_5416 *ahp = AH5416(ah); |
1098 | 1093 | ||
1099 | if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) { | 1094 | if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) { |
1100 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad cts timeout %u\n", | 1095 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad cts timeout %u\n", us); |
1101 | __func__, us); | ||
1102 | ahp->ah_ctstimeout = (u32) -1; | 1096 | ahp->ah_ctstimeout = (u32) -1; |
1103 | return false; | 1097 | return false; |
1104 | } else { | 1098 | } else { |
@@ -1115,7 +1109,7 @@ static bool ath9k_hw_set_global_txtimeout(struct ath_hal *ah, u32 tu) | |||
1115 | 1109 | ||
1116 | if (tu > 0xFFFF) { | 1110 | if (tu > 0xFFFF) { |
1117 | DPRINTF(ah->ah_sc, ATH_DBG_XMIT, | 1111 | DPRINTF(ah->ah_sc, ATH_DBG_XMIT, |
1118 | "%s: bad global tx timeout %u\n", __func__, tu); | 1112 | "bad global tx timeout %u\n", tu); |
1119 | ahp->ah_globaltxtimeout = (u32) -1; | 1113 | ahp->ah_globaltxtimeout = (u32) -1; |
1120 | return false; | 1114 | return false; |
1121 | } else { | 1115 | } else { |
@@ -1129,8 +1123,8 @@ static void ath9k_hw_init_user_settings(struct ath_hal *ah) | |||
1129 | { | 1123 | { |
1130 | struct ath_hal_5416 *ahp = AH5416(ah); | 1124 | struct ath_hal_5416 *ahp = AH5416(ah); |
1131 | 1125 | ||
1132 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, "--AP %s ahp->ah_miscMode 0x%x\n", | 1126 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, "ahp->ah_miscMode 0x%x\n", |
1133 | __func__, ahp->ah_miscMode); | 1127 | ahp->ah_miscMode); |
1134 | 1128 | ||
1135 | if (ahp->ah_miscMode != 0) | 1129 | if (ahp->ah_miscMode != 0) |
1136 | REG_WRITE(ah, AR_PCU_MISC, | 1130 | REG_WRITE(ah, AR_PCU_MISC, |
@@ -1176,7 +1170,7 @@ struct ath_hal *ath9k_hw_attach(u16 devid, struct ath_softc *sc, | |||
1176 | break; | 1170 | break; |
1177 | default: | 1171 | default: |
1178 | DPRINTF(ah->ah_sc, ATH_DBG_ANY, | 1172 | DPRINTF(ah->ah_sc, ATH_DBG_ANY, |
1179 | "devid=0x%x not supported.\n", devid); | 1173 | "devid=0x%x not supported.\n", devid); |
1180 | ah = NULL; | 1174 | ah = NULL; |
1181 | *error = -ENXIO; | 1175 | *error = -ENXIO; |
1182 | break; | 1176 | break; |
@@ -1355,13 +1349,13 @@ static int ath9k_hw_process_ini(struct ath_hal *ah, | |||
1355 | (u32) ah->ah_powerLimit)); | 1349 | (u32) ah->ah_powerLimit)); |
1356 | if (status != 0) { | 1350 | if (status != 0) { |
1357 | DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, | 1351 | DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, |
1358 | "%s: error init'ing transmit power\n", __func__); | 1352 | "error init'ing transmit power\n"); |
1359 | return -EIO; | 1353 | return -EIO; |
1360 | } | 1354 | } |
1361 | 1355 | ||
1362 | if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) { | 1356 | if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) { |
1363 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, | 1357 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, |
1364 | "%s: ar5416SetRfRegs failed\n", __func__); | 1358 | "ar5416SetRfRegs failed\n"); |
1365 | return -EIO; | 1359 | return -EIO; |
1366 | } | 1360 | } |
1367 | 1361 | ||
@@ -1430,18 +1424,18 @@ static void ath9k_hw_set_operating_mode(struct ath_hal *ah, int opmode) | |||
1430 | val = REG_READ(ah, AR_STA_ID1); | 1424 | val = REG_READ(ah, AR_STA_ID1); |
1431 | val &= ~(AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC); | 1425 | val &= ~(AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC); |
1432 | switch (opmode) { | 1426 | switch (opmode) { |
1433 | case ATH9K_M_HOSTAP: | 1427 | case NL80211_IFTYPE_AP: |
1434 | REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_STA_AP | 1428 | REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_STA_AP |
1435 | | AR_STA_ID1_KSRCH_MODE); | 1429 | | AR_STA_ID1_KSRCH_MODE); |
1436 | REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); | 1430 | REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); |
1437 | break; | 1431 | break; |
1438 | case ATH9K_M_IBSS: | 1432 | case NL80211_IFTYPE_ADHOC: |
1439 | REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC | 1433 | REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC |
1440 | | AR_STA_ID1_KSRCH_MODE); | 1434 | | AR_STA_ID1_KSRCH_MODE); |
1441 | REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); | 1435 | REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); |
1442 | break; | 1436 | break; |
1443 | case ATH9K_M_STA: | 1437 | case NL80211_IFTYPE_STATION: |
1444 | case ATH9K_M_MONITOR: | 1438 | case NL80211_IFTYPE_MONITOR: |
1445 | REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE); | 1439 | REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE); |
1446 | break; | 1440 | break; |
1447 | } | 1441 | } |
@@ -1533,8 +1527,7 @@ static bool ath9k_hw_set_reset(struct ath_hal *ah, int type) | |||
1533 | REG_WRITE(ah, (u16) (AR_RTC_RC), 0); | 1527 | REG_WRITE(ah, (u16) (AR_RTC_RC), 0); |
1534 | if (!ath9k_hw_wait(ah, (u16) (AR_RTC_RC), AR_RTC_RC_M, 0)) { | 1528 | if (!ath9k_hw_wait(ah, (u16) (AR_RTC_RC), AR_RTC_RC_M, 0)) { |
1535 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, | 1529 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, |
1536 | "%s: RTC stuck in MAC reset\n", | 1530 | "RTC stuck in MAC reset\n"); |
1537 | __func__); | ||
1538 | return false; | 1531 | return false; |
1539 | } | 1532 | } |
1540 | 1533 | ||
@@ -1561,8 +1554,7 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hal *ah) | |||
1561 | AR_RTC_STATUS, | 1554 | AR_RTC_STATUS, |
1562 | AR_RTC_STATUS_M, | 1555 | AR_RTC_STATUS_M, |
1563 | AR_RTC_STATUS_ON)) { | 1556 | AR_RTC_STATUS_ON)) { |
1564 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: RTC not waking up\n", | 1557 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, "RTC not waking up\n"); |
1565 | __func__); | ||
1566 | return false; | 1558 | return false; |
1567 | } | 1559 | } |
1568 | 1560 | ||
@@ -1641,9 +1633,8 @@ static struct ath9k_channel *ath9k_hw_check_chan(struct ath_hal *ah, | |||
1641 | { | 1633 | { |
1642 | if (!(IS_CHAN_2GHZ(chan) ^ IS_CHAN_5GHZ(chan))) { | 1634 | if (!(IS_CHAN_2GHZ(chan) ^ IS_CHAN_5GHZ(chan))) { |
1643 | DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, | 1635 | DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, |
1644 | "%s: invalid channel %u/0x%x; not marked as " | 1636 | "invalid channel %u/0x%x; not marked as " |
1645 | "2GHz or 5GHz\n", __func__, chan->channel, | 1637 | "2GHz or 5GHz\n", chan->channel, chan->channelFlags); |
1646 | chan->channelFlags); | ||
1647 | return NULL; | 1638 | return NULL; |
1648 | } | 1639 | } |
1649 | 1640 | ||
@@ -1652,9 +1643,9 @@ static struct ath9k_channel *ath9k_hw_check_chan(struct ath_hal *ah, | |||
1652 | !IS_CHAN_HT20(chan) && | 1643 | !IS_CHAN_HT20(chan) && |
1653 | !IS_CHAN_HT40(chan)) { | 1644 | !IS_CHAN_HT40(chan)) { |
1654 | DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, | 1645 | DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, |
1655 | "%s: invalid channel %u/0x%x; not marked as " | 1646 | "invalid channel %u/0x%x; not marked as " |
1656 | "OFDM or CCK or HT20 or HT40PLUS or HT40MINUS\n", | 1647 | "OFDM or CCK or HT20 or HT40PLUS or HT40MINUS\n", |
1657 | __func__, chan->channel, chan->channelFlags); | 1648 | chan->channel, chan->channelFlags); |
1658 | return NULL; | 1649 | return NULL; |
1659 | } | 1650 | } |
1660 | 1651 | ||
@@ -1670,8 +1661,7 @@ static bool ath9k_hw_channel_change(struct ath_hal *ah, | |||
1670 | for (qnum = 0; qnum < AR_NUM_QCU; qnum++) { | 1661 | for (qnum = 0; qnum < AR_NUM_QCU; qnum++) { |
1671 | if (ath9k_hw_numtxpending(ah, qnum)) { | 1662 | if (ath9k_hw_numtxpending(ah, qnum)) { |
1672 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, | 1663 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, |
1673 | "%s: Transmit frames pending on queue %d\n", | 1664 | "Transmit frames pending on queue %d\n", qnum); |
1674 | __func__, qnum); | ||
1675 | return false; | 1665 | return false; |
1676 | } | 1666 | } |
1677 | } | 1667 | } |
@@ -1679,8 +1669,8 @@ static bool ath9k_hw_channel_change(struct ath_hal *ah, | |||
1679 | REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN); | 1669 | REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN); |
1680 | if (!ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN, | 1670 | if (!ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN, |
1681 | AR_PHY_RFBUS_GRANT_EN)) { | 1671 | AR_PHY_RFBUS_GRANT_EN)) { |
1682 | DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO, | 1672 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, |
1683 | "%s: Could not kill baseband RX\n", __func__); | 1673 | "Could not kill baseband RX\n"); |
1684 | return false; | 1674 | return false; |
1685 | } | 1675 | } |
1686 | 1676 | ||
@@ -1689,13 +1679,13 @@ static bool ath9k_hw_channel_change(struct ath_hal *ah, | |||
1689 | if (AR_SREV_9280_10_OR_LATER(ah)) { | 1679 | if (AR_SREV_9280_10_OR_LATER(ah)) { |
1690 | if (!(ath9k_hw_ar9280_set_channel(ah, chan))) { | 1680 | if (!(ath9k_hw_ar9280_set_channel(ah, chan))) { |
1691 | DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, | 1681 | DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, |
1692 | "%s: failed to set channel\n", __func__); | 1682 | "failed to set channel\n"); |
1693 | return false; | 1683 | return false; |
1694 | } | 1684 | } |
1695 | } else { | 1685 | } else { |
1696 | if (!(ath9k_hw_set_channel(ah, chan))) { | 1686 | if (!(ath9k_hw_set_channel(ah, chan))) { |
1697 | DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, | 1687 | DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, |
1698 | "%s: failed to set channel\n", __func__); | 1688 | "failed to set channel\n"); |
1699 | return false; | 1689 | return false; |
1700 | } | 1690 | } |
1701 | } | 1691 | } |
@@ -1707,7 +1697,7 @@ static bool ath9k_hw_channel_change(struct ath_hal *ah, | |||
1707 | min((u32) MAX_RATE_POWER, | 1697 | min((u32) MAX_RATE_POWER, |
1708 | (u32) ah->ah_powerLimit)) != 0) { | 1698 | (u32) ah->ah_powerLimit)) != 0) { |
1709 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | 1699 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, |
1710 | "%s: error init'ing transmit power\n", __func__); | 1700 | "error init'ing transmit power\n"); |
1711 | return false; | 1701 | return false; |
1712 | } | 1702 | } |
1713 | 1703 | ||
@@ -2211,8 +2201,8 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan, | |||
2211 | 2201 | ||
2212 | if (ath9k_hw_check_chan(ah, chan) == NULL) { | 2202 | if (ath9k_hw_check_chan(ah, chan) == NULL) { |
2213 | DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, | 2203 | DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, |
2214 | "%s: invalid channel %u/0x%x; no mapping\n", | 2204 | "invalid channel %u/0x%x; no mapping\n", |
2215 | __func__, chan->channel, chan->channelFlags); | 2205 | chan->channel, chan->channelFlags); |
2216 | ecode = -EINVAL; | 2206 | ecode = -EINVAL; |
2217 | goto bad; | 2207 | goto bad; |
2218 | } | 2208 | } |
@@ -2254,8 +2244,7 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan, | |||
2254 | ath9k_hw_mark_phy_inactive(ah); | 2244 | ath9k_hw_mark_phy_inactive(ah); |
2255 | 2245 | ||
2256 | if (!ath9k_hw_chip_reset(ah, chan)) { | 2246 | if (!ath9k_hw_chip_reset(ah, chan)) { |
2257 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: chip reset failed\n", | 2247 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, "chip reset failed\n"); |
2258 | __func__); | ||
2259 | ecode = -EINVAL; | 2248 | ecode = -EINVAL; |
2260 | goto bad; | 2249 | goto bad; |
2261 | } | 2250 | } |
@@ -2289,7 +2278,7 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan, | |||
2289 | 2278 | ||
2290 | if (!ath9k_hw_eeprom_set_board_values(ah, chan)) { | 2279 | if (!ath9k_hw_eeprom_set_board_values(ah, chan)) { |
2291 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | 2280 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, |
2292 | "%s: error setting board options\n", __func__); | 2281 | "error setting board options\n"); |
2293 | ecode = -EIO; | 2282 | ecode = -EIO; |
2294 | goto bad; | 2283 | goto bad; |
2295 | } | 2284 | } |
@@ -2379,15 +2368,13 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan, | |||
2379 | mask = REG_READ(ah, AR_CFG); | 2368 | mask = REG_READ(ah, AR_CFG); |
2380 | if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) { | 2369 | if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) { |
2381 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, | 2370 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, |
2382 | "%s CFG Byte Swap Set 0x%x\n", __func__, | 2371 | "CFG Byte Swap Set 0x%x\n", mask); |
2383 | mask); | ||
2384 | } else { | 2372 | } else { |
2385 | mask = | 2373 | mask = |
2386 | INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB; | 2374 | INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB; |
2387 | REG_WRITE(ah, AR_CFG, mask); | 2375 | REG_WRITE(ah, AR_CFG, mask); |
2388 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, | 2376 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, |
2389 | "%s Setting CFG 0x%x\n", __func__, | 2377 | "Setting CFG 0x%x\n", REG_READ(ah, AR_CFG)); |
2390 | REG_READ(ah, AR_CFG)); | ||
2391 | } | 2378 | } |
2392 | } else { | 2379 | } else { |
2393 | #ifdef __BIG_ENDIAN | 2380 | #ifdef __BIG_ENDIAN |
@@ -2412,7 +2399,7 @@ bool ath9k_hw_keyreset(struct ath_hal *ah, u16 entry) | |||
2412 | 2399 | ||
2413 | if (entry >= ah->ah_caps.keycache_size) { | 2400 | if (entry >= ah->ah_caps.keycache_size) { |
2414 | DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE, | 2401 | DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE, |
2415 | "%s: entry %u out of range\n", __func__, entry); | 2402 | "entry %u out of range\n", entry); |
2416 | return false; | 2403 | return false; |
2417 | } | 2404 | } |
2418 | 2405 | ||
@@ -2449,7 +2436,7 @@ bool ath9k_hw_keysetmac(struct ath_hal *ah, u16 entry, const u8 *mac) | |||
2449 | 2436 | ||
2450 | if (entry >= ah->ah_caps.keycache_size) { | 2437 | if (entry >= ah->ah_caps.keycache_size) { |
2451 | DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE, | 2438 | DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE, |
2452 | "%s: entry %u out of range\n", __func__, entry); | 2439 | "entry %u out of range\n", entry); |
2453 | return false; | 2440 | return false; |
2454 | } | 2441 | } |
2455 | 2442 | ||
@@ -2485,7 +2472,7 @@ bool ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry, | |||
2485 | 2472 | ||
2486 | if (entry >= pCap->keycache_size) { | 2473 | if (entry >= pCap->keycache_size) { |
2487 | DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE, | 2474 | DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE, |
2488 | "%s: entry %u out of range\n", __func__, entry); | 2475 | "entry %u out of range\n", entry); |
2489 | return false; | 2476 | return false; |
2490 | } | 2477 | } |
2491 | 2478 | ||
@@ -2496,8 +2483,7 @@ bool ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry, | |||
2496 | case ATH9K_CIPHER_AES_CCM: | 2483 | case ATH9K_CIPHER_AES_CCM: |
2497 | if (!(pCap->hw_caps & ATH9K_HW_CAP_CIPHER_AESCCM)) { | 2484 | if (!(pCap->hw_caps & ATH9K_HW_CAP_CIPHER_AESCCM)) { |
2498 | DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE, | 2485 | DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE, |
2499 | "%s: AES-CCM not supported by " | 2486 | "AES-CCM not supported by mac rev 0x%x\n", |
2500 | "mac rev 0x%x\n", __func__, | ||
2501 | ah->ah_macRev); | 2487 | ah->ah_macRev); |
2502 | return false; | 2488 | return false; |
2503 | } | 2489 | } |
@@ -2508,16 +2494,14 @@ bool ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry, | |||
2508 | if (ATH9K_IS_MIC_ENABLED(ah) | 2494 | if (ATH9K_IS_MIC_ENABLED(ah) |
2509 | && entry + 64 >= pCap->keycache_size) { | 2495 | && entry + 64 >= pCap->keycache_size) { |
2510 | DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE, | 2496 | DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE, |
2511 | "%s: entry %u inappropriate for TKIP\n", | 2497 | "entry %u inappropriate for TKIP\n", entry); |
2512 | __func__, entry); | ||
2513 | return false; | 2498 | return false; |
2514 | } | 2499 | } |
2515 | break; | 2500 | break; |
2516 | case ATH9K_CIPHER_WEP: | 2501 | case ATH9K_CIPHER_WEP: |
2517 | if (k->kv_len < LEN_WEP40) { | 2502 | if (k->kv_len < LEN_WEP40) { |
2518 | DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE, | 2503 | DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE, |
2519 | "%s: WEP key length %u too small\n", | 2504 | "WEP key length %u too small\n", k->kv_len); |
2520 | __func__, k->kv_len); | ||
2521 | return false; | 2505 | return false; |
2522 | } | 2506 | } |
2523 | if (k->kv_len <= LEN_WEP40) | 2507 | if (k->kv_len <= LEN_WEP40) |
@@ -2532,8 +2516,7 @@ bool ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry, | |||
2532 | break; | 2516 | break; |
2533 | default: | 2517 | default: |
2534 | DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE, | 2518 | DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE, |
2535 | "%s: cipher %u not supported\n", __func__, | 2519 | "cipher %u not supported\n", k->kv_type); |
2536 | k->kv_type); | ||
2537 | return false; | 2520 | return false; |
2538 | } | 2521 | } |
2539 | 2522 | ||
@@ -2682,8 +2665,7 @@ static bool ath9k_hw_set_power_awake(struct ath_hal *ah, | |||
2682 | } | 2665 | } |
2683 | if (i == 0) { | 2666 | if (i == 0) { |
2684 | DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, | 2667 | DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, |
2685 | "%s: Failed to wakeup in %uus\n", | 2668 | "Failed to wakeup in %uus\n", POWER_UP_TIME / 20); |
2686 | __func__, POWER_UP_TIME / 20); | ||
2687 | return false; | 2669 | return false; |
2688 | } | 2670 | } |
2689 | } | 2671 | } |
@@ -2705,7 +2687,7 @@ bool ath9k_hw_setpower(struct ath_hal *ah, | |||
2705 | }; | 2687 | }; |
2706 | int status = true, setChip = true; | 2688 | int status = true, setChip = true; |
2707 | 2689 | ||
2708 | DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, "%s: %s -> %s (%s)\n", __func__, | 2690 | DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, "%s -> %s (%s)\n", |
2709 | modes[ahp->ah_powerMode], modes[mode], | 2691 | modes[ahp->ah_powerMode], modes[mode], |
2710 | setChip ? "set chip " : ""); | 2692 | setChip ? "set chip " : ""); |
2711 | 2693 | ||
@@ -2722,7 +2704,7 @@ bool ath9k_hw_setpower(struct ath_hal *ah, | |||
2722 | break; | 2704 | break; |
2723 | default: | 2705 | default: |
2724 | DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, | 2706 | DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, |
2725 | "%s: unknown power mode %u\n", __func__, mode); | 2707 | "Unknown power mode %u\n", mode); |
2726 | return false; | 2708 | return false; |
2727 | } | 2709 | } |
2728 | ahp->ah_powerMode = mode; | 2710 | ahp->ah_powerMode = mode; |
@@ -2899,8 +2881,7 @@ bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked) | |||
2899 | 2881 | ||
2900 | if (isr & AR_ISR_RXORN) { | 2882 | if (isr & AR_ISR_RXORN) { |
2901 | DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, | 2883 | DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, |
2902 | "%s: receive FIFO overrun interrupt\n", | 2884 | "receive FIFO overrun interrupt\n"); |
2903 | __func__); | ||
2904 | } | 2885 | } |
2905 | 2886 | ||
2906 | if (!AR_SREV_9100(ah)) { | 2887 | if (!AR_SREV_9100(ah)) { |
@@ -2926,27 +2907,23 @@ bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked) | |||
2926 | if (fatal_int) { | 2907 | if (fatal_int) { |
2927 | if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) { | 2908 | if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) { |
2928 | DPRINTF(ah->ah_sc, ATH_DBG_ANY, | 2909 | DPRINTF(ah->ah_sc, ATH_DBG_ANY, |
2929 | "%s: received PCI FATAL interrupt\n", | 2910 | "received PCI FATAL interrupt\n"); |
2930 | __func__); | ||
2931 | } | 2911 | } |
2932 | if (sync_cause & AR_INTR_SYNC_HOST1_PERR) { | 2912 | if (sync_cause & AR_INTR_SYNC_HOST1_PERR) { |
2933 | DPRINTF(ah->ah_sc, ATH_DBG_ANY, | 2913 | DPRINTF(ah->ah_sc, ATH_DBG_ANY, |
2934 | "%s: received PCI PERR interrupt\n", | 2914 | "received PCI PERR interrupt\n"); |
2935 | __func__); | ||
2936 | } | 2915 | } |
2937 | } | 2916 | } |
2938 | if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) { | 2917 | if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) { |
2939 | DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, | 2918 | DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, |
2940 | "%s: AR_INTR_SYNC_RADM_CPL_TIMEOUT\n", | 2919 | "AR_INTR_SYNC_RADM_CPL_TIMEOUT\n"); |
2941 | __func__); | ||
2942 | REG_WRITE(ah, AR_RC, AR_RC_HOSTIF); | 2920 | REG_WRITE(ah, AR_RC, AR_RC_HOSTIF); |
2943 | REG_WRITE(ah, AR_RC, 0); | 2921 | REG_WRITE(ah, AR_RC, 0); |
2944 | *masked |= ATH9K_INT_FATAL; | 2922 | *masked |= ATH9K_INT_FATAL; |
2945 | } | 2923 | } |
2946 | if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) { | 2924 | if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) { |
2947 | DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, | 2925 | DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, |
2948 | "%s: AR_INTR_SYNC_LOCAL_TIMEOUT\n", | 2926 | "AR_INTR_SYNC_LOCAL_TIMEOUT\n"); |
2949 | __func__); | ||
2950 | } | 2927 | } |
2951 | 2928 | ||
2952 | REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause); | 2929 | REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause); |
@@ -2968,12 +2945,10 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints) | |||
2968 | u32 mask, mask2; | 2945 | u32 mask, mask2; |
2969 | struct ath9k_hw_capabilities *pCap = &ah->ah_caps; | 2946 | struct ath9k_hw_capabilities *pCap = &ah->ah_caps; |
2970 | 2947 | ||
2971 | DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: 0x%x => 0x%x\n", __func__, | 2948 | DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints); |
2972 | omask, ints); | ||
2973 | 2949 | ||
2974 | if (omask & ATH9K_INT_GLOBAL) { | 2950 | if (omask & ATH9K_INT_GLOBAL) { |
2975 | DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: disable IER\n", | 2951 | DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "disable IER\n"); |
2976 | __func__); | ||
2977 | REG_WRITE(ah, AR_IER, AR_IER_DISABLE); | 2952 | REG_WRITE(ah, AR_IER, AR_IER_DISABLE); |
2978 | (void) REG_READ(ah, AR_IER); | 2953 | (void) REG_READ(ah, AR_IER); |
2979 | if (!AR_SREV_9100(ah)) { | 2954 | if (!AR_SREV_9100(ah)) { |
@@ -3028,8 +3003,7 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints) | |||
3028 | mask2 |= AR_IMR_S2_CST; | 3003 | mask2 |= AR_IMR_S2_CST; |
3029 | } | 3004 | } |
3030 | 3005 | ||
3031 | DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: new IMR 0x%x\n", __func__, | 3006 | DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask); |
3032 | mask); | ||
3033 | REG_WRITE(ah, AR_IMR, mask); | 3007 | REG_WRITE(ah, AR_IMR, mask); |
3034 | mask = REG_READ(ah, AR_IMR_S2) & ~(AR_IMR_S2_TIM | | 3008 | mask = REG_READ(ah, AR_IMR_S2) & ~(AR_IMR_S2_TIM | |
3035 | AR_IMR_S2_DTIM | | 3009 | AR_IMR_S2_DTIM | |
@@ -3049,8 +3023,7 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints) | |||
3049 | } | 3023 | } |
3050 | 3024 | ||
3051 | if (ints & ATH9K_INT_GLOBAL) { | 3025 | if (ints & ATH9K_INT_GLOBAL) { |
3052 | DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: enable IER\n", | 3026 | DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "enable IER\n"); |
3053 | __func__); | ||
3054 | REG_WRITE(ah, AR_IER, AR_IER_ENABLE); | 3027 | REG_WRITE(ah, AR_IER, AR_IER_ENABLE); |
3055 | if (!AR_SREV_9100(ah)) { | 3028 | if (!AR_SREV_9100(ah)) { |
3056 | REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, | 3029 | REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, |
@@ -3082,14 +3055,14 @@ void ath9k_hw_beaconinit(struct ath_hal *ah, u32 next_beacon, u32 beacon_period) | |||
3082 | ahp->ah_beaconInterval = beacon_period; | 3055 | ahp->ah_beaconInterval = beacon_period; |
3083 | 3056 | ||
3084 | switch (ah->ah_opmode) { | 3057 | switch (ah->ah_opmode) { |
3085 | case ATH9K_M_STA: | 3058 | case NL80211_IFTYPE_STATION: |
3086 | case ATH9K_M_MONITOR: | 3059 | case NL80211_IFTYPE_MONITOR: |
3087 | REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon)); | 3060 | REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon)); |
3088 | REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff); | 3061 | REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff); |
3089 | REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff); | 3062 | REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff); |
3090 | flags |= AR_TBTT_TIMER_EN; | 3063 | flags |= AR_TBTT_TIMER_EN; |
3091 | break; | 3064 | break; |
3092 | case ATH9K_M_IBSS: | 3065 | case NL80211_IFTYPE_ADHOC: |
3093 | REG_SET_BIT(ah, AR_TXCFG, | 3066 | REG_SET_BIT(ah, AR_TXCFG, |
3094 | AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY); | 3067 | AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY); |
3095 | REG_WRITE(ah, AR_NEXT_NDP_TIMER, | 3068 | REG_WRITE(ah, AR_NEXT_NDP_TIMER, |
@@ -3097,7 +3070,7 @@ void ath9k_hw_beaconinit(struct ath_hal *ah, u32 next_beacon, u32 beacon_period) | |||
3097 | (ahp->ah_atimWindow ? ahp-> | 3070 | (ahp->ah_atimWindow ? ahp-> |
3098 | ah_atimWindow : 1))); | 3071 | ah_atimWindow : 1))); |
3099 | flags |= AR_NDP_TIMER_EN; | 3072 | flags |= AR_NDP_TIMER_EN; |
3100 | case ATH9K_M_HOSTAP: | 3073 | case NL80211_IFTYPE_AP: |
3101 | REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon)); | 3074 | REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon)); |
3102 | REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, | 3075 | REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, |
3103 | TU_TO_USEC(next_beacon - | 3076 | TU_TO_USEC(next_beacon - |
@@ -3110,6 +3083,12 @@ void ath9k_hw_beaconinit(struct ath_hal *ah, u32 next_beacon, u32 beacon_period) | |||
3110 | flags |= | 3083 | flags |= |
3111 | AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN; | 3084 | AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN; |
3112 | break; | 3085 | break; |
3086 | default: | ||
3087 | DPRINTF(ah->ah_sc, ATH_DBG_BEACON, | ||
3088 | "%s: unsupported opmode: %d\n", | ||
3089 | __func__, ah->ah_opmode); | ||
3090 | return; | ||
3091 | break; | ||
3113 | } | 3092 | } |
3114 | 3093 | ||
3115 | REG_WRITE(ah, AR_BEACON_PERIOD, TU_TO_USEC(beacon_period)); | 3094 | REG_WRITE(ah, AR_BEACON_PERIOD, TU_TO_USEC(beacon_period)); |
@@ -3156,14 +3135,10 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah, | |||
3156 | else | 3135 | else |
3157 | nextTbtt = bs->bs_nexttbtt; | 3136 | nextTbtt = bs->bs_nexttbtt; |
3158 | 3137 | ||
3159 | DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: next DTIM %d\n", __func__, | 3138 | DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "next DTIM %d\n", bs->bs_nextdtim); |
3160 | bs->bs_nextdtim); | 3139 | DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "next beacon %d\n", nextTbtt); |
3161 | DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: next beacon %d\n", __func__, | 3140 | DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "beacon period %d\n", beaconintval); |
3162 | nextTbtt); | 3141 | DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "DTIM period %d\n", dtimperiod); |
3163 | DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: beacon period %d\n", __func__, | ||
3164 | beaconintval); | ||
3165 | DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: DTIM period %d\n", __func__, | ||
3166 | dtimperiod); | ||
3167 | 3142 | ||
3168 | REG_WRITE(ah, AR_NEXT_DTIM, | 3143 | REG_WRITE(ah, AR_NEXT_DTIM, |
3169 | TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP)); | 3144 | TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP)); |
@@ -3209,15 +3184,14 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah) | |||
3209 | 3184 | ||
3210 | capField = ath9k_hw_get_eeprom(ah, EEP_OP_CAP); | 3185 | capField = ath9k_hw_get_eeprom(ah, EEP_OP_CAP); |
3211 | 3186 | ||
3212 | if (ah->ah_opmode != ATH9K_M_HOSTAP && | 3187 | if (ah->ah_opmode != NL80211_IFTYPE_AP && |
3213 | ah->ah_subvendorid == AR_SUBVENDOR_ID_NEW_A) { | 3188 | ah->ah_subvendorid == AR_SUBVENDOR_ID_NEW_A) { |
3214 | if (ah->ah_currentRD == 0x64 || ah->ah_currentRD == 0x65) | 3189 | if (ah->ah_currentRD == 0x64 || ah->ah_currentRD == 0x65) |
3215 | ah->ah_currentRD += 5; | 3190 | ah->ah_currentRD += 5; |
3216 | else if (ah->ah_currentRD == 0x41) | 3191 | else if (ah->ah_currentRD == 0x41) |
3217 | ah->ah_currentRD = 0x43; | 3192 | ah->ah_currentRD = 0x43; |
3218 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | 3193 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, |
3219 | "%s: regdomain mapped to 0x%x\n", __func__, | 3194 | "regdomain mapped to 0x%x\n", ah->ah_currentRD); |
3220 | ah->ah_currentRD); | ||
3221 | } | 3195 | } |
3222 | 3196 | ||
3223 | eeval = ath9k_hw_get_eeprom(ah, EEP_OP_MODE); | 3197 | eeval = ath9k_hw_get_eeprom(ah, EEP_OP_MODE); |
@@ -3823,8 +3797,7 @@ void ath9k_hw_reset_tsf(struct ath_hal *ah) | |||
3823 | count++; | 3797 | count++; |
3824 | if (count > 10) { | 3798 | if (count > 10) { |
3825 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, | 3799 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, |
3826 | "%s: AR_SLP32_TSF_WRITE_STATUS limit exceeded\n", | 3800 | "AR_SLP32_TSF_WRITE_STATUS limit exceeded\n"); |
3827 | __func__); | ||
3828 | break; | 3801 | break; |
3829 | } | 3802 | } |
3830 | udelay(10); | 3803 | udelay(10); |
@@ -3849,8 +3822,7 @@ bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us) | |||
3849 | struct ath_hal_5416 *ahp = AH5416(ah); | 3822 | struct ath_hal_5416 *ahp = AH5416(ah); |
3850 | 3823 | ||
3851 | if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) { | 3824 | if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) { |
3852 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad slot time %u\n", | 3825 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad slot time %u\n", us); |
3853 | __func__, us); | ||
3854 | ahp->ah_slottime = (u32) -1; | 3826 | ahp->ah_slottime = (u32) -1; |
3855 | return false; | 3827 | return false; |
3856 | } else { | 3828 | } else { |
diff --git a/drivers/net/wireless/ath9k/mac.c b/drivers/net/wireless/ath9k/mac.c index 36955e0b1849..a4e98986dbcd 100644 --- a/drivers/net/wireless/ath9k/mac.c +++ b/drivers/net/wireless/ath9k/mac.c | |||
@@ -25,10 +25,10 @@ static void ath9k_hw_set_txq_interrupts(struct ath_hal *ah, | |||
25 | struct ath_hal_5416 *ahp = AH5416(ah); | 25 | struct ath_hal_5416 *ahp = AH5416(ah); |
26 | 26 | ||
27 | DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, | 27 | DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, |
28 | "%s: tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n", | 28 | "tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n", |
29 | __func__, ahp->ah_txOkInterruptMask, | 29 | ahp->ah_txOkInterruptMask, ahp->ah_txErrInterruptMask, |
30 | ahp->ah_txErrInterruptMask, ahp->ah_txDescInterruptMask, | 30 | ahp->ah_txDescInterruptMask, ahp->ah_txEolInterruptMask, |
31 | ahp->ah_txEolInterruptMask, ahp->ah_txUrnInterruptMask); | 31 | ahp->ah_txUrnInterruptMask); |
32 | 32 | ||
33 | REG_WRITE(ah, AR_IMR_S0, | 33 | REG_WRITE(ah, AR_IMR_S0, |
34 | SM(ahp->ah_txOkInterruptMask, AR_IMR_S0_QCU_TXOK) | 34 | SM(ahp->ah_txOkInterruptMask, AR_IMR_S0_QCU_TXOK) |
@@ -40,78 +40,6 @@ static void ath9k_hw_set_txq_interrupts(struct ath_hal *ah, | |||
40 | AR_IMR_S2_QCU_TXURN, ahp->ah_txUrnInterruptMask); | 40 | AR_IMR_S2_QCU_TXURN, ahp->ah_txUrnInterruptMask); |
41 | } | 41 | } |
42 | 42 | ||
43 | void ath9k_hw_dmaRegDump(struct ath_hal *ah) | ||
44 | { | ||
45 | u32 val[ATH9K_NUM_DMA_DEBUG_REGS]; | ||
46 | int qcuOffset = 0, dcuOffset = 0; | ||
47 | u32 *qcuBase = &val[0], *dcuBase = &val[4]; | ||
48 | int i; | ||
49 | |||
50 | REG_WRITE(ah, AR_MACMISC, | ||
51 | ((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) | | ||
52 | (AR_MACMISC_MISC_OBS_BUS_1 << | ||
53 | AR_MACMISC_MISC_OBS_BUS_MSB_S))); | ||
54 | |||
55 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "Raw DMA Debug values:\n"); | ||
56 | |||
57 | for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) { | ||
58 | if (i % 4 == 0) | ||
59 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n"); | ||
60 | |||
61 | val[i] = REG_READ(ah, AR_DMADBG_0 + (i * sizeof(u32))); | ||
62 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "%d: %08x ", i, val[i]); | ||
63 | } | ||
64 | |||
65 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n\n"); | ||
66 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, | ||
67 | "Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n"); | ||
68 | |||
69 | for (i = 0; i < ATH9K_NUM_QUEUES; | ||
70 | i++, qcuOffset += 4, dcuOffset += 5) { | ||
71 | if (i == 8) { | ||
72 | qcuOffset = 0; | ||
73 | qcuBase++; | ||
74 | } | ||
75 | |||
76 | if (i == 6) { | ||
77 | dcuOffset = 0; | ||
78 | dcuBase++; | ||
79 | } | ||
80 | |||
81 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, | ||
82 | "%2d %2x %1x %2x %2x\n", | ||
83 | i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset, | ||
84 | (*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset + 3), | ||
85 | val[2] & (0x7 << (i * 3)) >> (i * 3), | ||
86 | (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset); | ||
87 | } | ||
88 | |||
89 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n"); | ||
90 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, | ||
91 | "qcu_stitch state: %2x qcu_fetch state: %2x\n", | ||
92 | (val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22); | ||
93 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, | ||
94 | "qcu_complete state: %2x dcu_complete state: %2x\n", | ||
95 | (val[3] & 0x1c000000) >> 26, (val[6] & 0x3)); | ||
96 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, | ||
97 | "dcu_arb state: %2x dcu_fp state: %2x\n", | ||
98 | (val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27); | ||
99 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, | ||
100 | "chan_idle_dur: %3d chan_idle_dur_valid: %1d\n", | ||
101 | (val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10); | ||
102 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, | ||
103 | "txfifo_valid_0: %1d txfifo_valid_1: %1d\n", | ||
104 | (val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12); | ||
105 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, | ||
106 | "txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n", | ||
107 | (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17); | ||
108 | |||
109 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "pcu observe 0x%x \n", | ||
110 | REG_READ(ah, AR_OBS_BUS_1)); | ||
111 | DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, | ||
112 | "AR_CR 0x%x \n", REG_READ(ah, AR_CR)); | ||
113 | } | ||
114 | |||
115 | u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q) | 43 | u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q) |
116 | { | 44 | { |
117 | return REG_READ(ah, AR_QTXDP(q)); | 45 | return REG_READ(ah, AR_QTXDP(q)); |
@@ -126,7 +54,7 @@ bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q, u32 txdp) | |||
126 | 54 | ||
127 | bool ath9k_hw_txstart(struct ath_hal *ah, u32 q) | 55 | bool ath9k_hw_txstart(struct ath_hal *ah, u32 q) |
128 | { | 56 | { |
129 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q); | 57 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %u\n", q); |
130 | 58 | ||
131 | REG_WRITE(ah, AR_Q_TXE, 1 << q); | 59 | REG_WRITE(ah, AR_Q_TXE, 1 << q); |
132 | 60 | ||
@@ -207,9 +135,8 @@ bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q) | |||
207 | break; | 135 | break; |
208 | 136 | ||
209 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, | 137 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, |
210 | "%s: TSF have moved while trying to set " | 138 | "TSF have moved while trying to set " |
211 | "quiet time TSF: 0x%08x\n", | 139 | "quiet time TSF: 0x%08x\n", tsfLow); |
212 | __func__, tsfLow); | ||
213 | } | 140 | } |
214 | 141 | ||
215 | REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH); | 142 | REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH); |
@@ -222,9 +149,8 @@ bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q) | |||
222 | while (ath9k_hw_numtxpending(ah, q)) { | 149 | while (ath9k_hw_numtxpending(ah, q)) { |
223 | if ((--wait) == 0) { | 150 | if ((--wait) == 0) { |
224 | DPRINTF(ah->ah_sc, ATH_DBG_XMIT, | 151 | DPRINTF(ah->ah_sc, ATH_DBG_XMIT, |
225 | "%s: Failed to stop Tx DMA in 100 " | 152 | "Failed to stop Tx DMA in 100 " |
226 | "msec after killing last frame\n", | 153 | "msec after killing last frame\n"); |
227 | __func__); | ||
228 | break; | 154 | break; |
229 | } | 155 | } |
230 | udelay(100); | 156 | udelay(100); |
@@ -523,19 +449,17 @@ bool ath9k_hw_set_txq_props(struct ath_hal *ah, int q, | |||
523 | struct ath9k_tx_queue_info *qi; | 449 | struct ath9k_tx_queue_info *qi; |
524 | 450 | ||
525 | if (q >= pCap->total_queues) { | 451 | if (q >= pCap->total_queues) { |
526 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n", | 452 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q); |
527 | __func__, q); | ||
528 | return false; | 453 | return false; |
529 | } | 454 | } |
530 | 455 | ||
531 | qi = &ahp->ah_txq[q]; | 456 | qi = &ahp->ah_txq[q]; |
532 | if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { | 457 | if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { |
533 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n", | 458 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n"); |
534 | __func__); | ||
535 | return false; | 459 | return false; |
536 | } | 460 | } |
537 | 461 | ||
538 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %p\n", __func__, qi); | 462 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %p\n", qi); |
539 | 463 | ||
540 | qi->tqi_ver = qinfo->tqi_ver; | 464 | qi->tqi_ver = qinfo->tqi_ver; |
541 | qi->tqi_subtype = qinfo->tqi_subtype; | 465 | qi->tqi_subtype = qinfo->tqi_subtype; |
@@ -593,15 +517,13 @@ bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q, | |||
593 | struct ath9k_tx_queue_info *qi; | 517 | struct ath9k_tx_queue_info *qi; |
594 | 518 | ||
595 | if (q >= pCap->total_queues) { | 519 | if (q >= pCap->total_queues) { |
596 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n", | 520 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q); |
597 | __func__, q); | ||
598 | return false; | 521 | return false; |
599 | } | 522 | } |
600 | 523 | ||
601 | qi = &ahp->ah_txq[q]; | 524 | qi = &ahp->ah_txq[q]; |
602 | if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { | 525 | if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { |
603 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n", | 526 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n"); |
604 | __func__); | ||
605 | return false; | 527 | return false; |
606 | } | 528 | } |
607 | 529 | ||
@@ -651,22 +573,21 @@ int ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type, | |||
651 | break; | 573 | break; |
652 | if (q == pCap->total_queues) { | 574 | if (q == pCap->total_queues) { |
653 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, | 575 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, |
654 | "%s: no available tx queue\n", __func__); | 576 | "no available tx queue\n"); |
655 | return -1; | 577 | return -1; |
656 | } | 578 | } |
657 | break; | 579 | break; |
658 | default: | 580 | default: |
659 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: bad tx queue type %u\n", | 581 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "bad tx queue type %u\n", type); |
660 | __func__, type); | ||
661 | return -1; | 582 | return -1; |
662 | } | 583 | } |
663 | 584 | ||
664 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q); | 585 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %u\n", q); |
665 | 586 | ||
666 | qi = &ahp->ah_txq[q]; | 587 | qi = &ahp->ah_txq[q]; |
667 | if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) { | 588 | if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) { |
668 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, | 589 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, |
669 | "%s: tx queue %u already active\n", __func__, q); | 590 | "tx queue %u already active\n", q); |
670 | return -1; | 591 | return -1; |
671 | } | 592 | } |
672 | memset(qi, 0, sizeof(struct ath9k_tx_queue_info)); | 593 | memset(qi, 0, sizeof(struct ath9k_tx_queue_info)); |
@@ -697,19 +618,16 @@ bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q) | |||
697 | struct ath9k_tx_queue_info *qi; | 618 | struct ath9k_tx_queue_info *qi; |
698 | 619 | ||
699 | if (q >= pCap->total_queues) { | 620 | if (q >= pCap->total_queues) { |
700 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n", | 621 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q); |
701 | __func__, q); | ||
702 | return false; | 622 | return false; |
703 | } | 623 | } |
704 | qi = &ahp->ah_txq[q]; | 624 | qi = &ahp->ah_txq[q]; |
705 | if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { | 625 | if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { |
706 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n", | 626 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue %u\n", q); |
707 | __func__, q); | ||
708 | return false; | 627 | return false; |
709 | } | 628 | } |
710 | 629 | ||
711 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: release queue %u\n", | 630 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "release queue %u\n", q); |
712 | __func__, q); | ||
713 | 631 | ||
714 | qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE; | 632 | qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE; |
715 | ahp->ah_txOkInterruptMask &= ~(1 << q); | 633 | ahp->ah_txOkInterruptMask &= ~(1 << q); |
@@ -731,19 +649,17 @@ bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q) | |||
731 | u32 cwMin, chanCwMin, value; | 649 | u32 cwMin, chanCwMin, value; |
732 | 650 | ||
733 | if (q >= pCap->total_queues) { | 651 | if (q >= pCap->total_queues) { |
734 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n", | 652 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q); |
735 | __func__, q); | ||
736 | return false; | 653 | return false; |
737 | } | 654 | } |
738 | 655 | ||
739 | qi = &ahp->ah_txq[q]; | 656 | qi = &ahp->ah_txq[q]; |
740 | if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { | 657 | if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { |
741 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n", | 658 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue %u\n", q); |
742 | __func__, q); | ||
743 | return true; | 659 | return true; |
744 | } | 660 | } |
745 | 661 | ||
746 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: reset queue %u\n", __func__, q); | 662 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "reset queue %u\n", q); |
747 | 663 | ||
748 | if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) { | 664 | if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) { |
749 | if (chan && IS_CHAN_B(chan)) | 665 | if (chan && IS_CHAN_B(chan)) |
@@ -976,8 +892,7 @@ bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set) | |||
976 | 892 | ||
977 | reg = REG_READ(ah, AR_OBS_BUS_1); | 893 | reg = REG_READ(ah, AR_OBS_BUS_1); |
978 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | 894 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, |
979 | "%s: rx failed to go idle in 10 ms RXSM=0x%x\n", | 895 | "rx failed to go idle in 10 ms RXSM=0x%x\n", reg); |
980 | __func__, reg); | ||
981 | 896 | ||
982 | return false; | 897 | return false; |
983 | } | 898 | } |
@@ -1022,9 +937,8 @@ bool ath9k_hw_stopdmarecv(struct ath_hal *ah) | |||
1022 | 937 | ||
1023 | if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0)) { | 938 | if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0)) { |
1024 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, | 939 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, |
1025 | "%s: dma failed to stop in 10ms\n" | 940 | "dma failed to stop in 10ms\n" |
1026 | "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n", | 941 | "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n", |
1027 | __func__, | ||
1028 | REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW)); | 942 | REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW)); |
1029 | return false; | 943 | return false; |
1030 | } else { | 944 | } else { |
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 437e38a3c6d7..26c47577e183 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/nl80211.h> | 17 | #include <linux/nl80211.h> |
18 | #include "core.h" | 18 | #include "core.h" |
19 | #include "reg.h" | 19 | #include "reg.h" |
20 | #include "hw.h" | ||
20 | 21 | ||
21 | #define ATH_PCI_VERSION "0.1" | 22 | #define ATH_PCI_VERSION "0.1" |
22 | 23 | ||
@@ -175,8 +176,8 @@ static void ath_setup_rates(struct ath_softc *sc, enum ieee80211_band band) | |||
175 | rate[i].bitrate = rate_table->info[i].ratekbps / 100; | 176 | rate[i].bitrate = rate_table->info[i].ratekbps / 100; |
176 | rate[i].hw_value = rate_table->info[i].ratecode; | 177 | rate[i].hw_value = rate_table->info[i].ratecode; |
177 | sband->n_bitrates++; | 178 | sband->n_bitrates++; |
178 | DPRINTF(sc, ATH_DBG_CONFIG, "%s: Rate: %2dMbps, ratecode: %2d\n", | 179 | DPRINTF(sc, ATH_DBG_CONFIG, "Rate: %2dMbps, ratecode: %2d\n", |
179 | __func__, rate[i].bitrate / 10, rate[i].hw_value); | 180 | rate[i].bitrate / 10, rate[i].hw_value); |
180 | } | 181 | } |
181 | } | 182 | } |
182 | 183 | ||
@@ -198,9 +199,9 @@ static int ath_setup_channels(struct ath_softc *sc) | |||
198 | &nregclass, CTRY_DEFAULT, false, 1)) { | 199 | &nregclass, CTRY_DEFAULT, false, 1)) { |
199 | u32 rd = ah->ah_currentRD; | 200 | u32 rd = ah->ah_currentRD; |
200 | DPRINTF(sc, ATH_DBG_FATAL, | 201 | DPRINTF(sc, ATH_DBG_FATAL, |
201 | "%s: unable to collect channel list; " | 202 | "Unable to collect channel list; " |
202 | "regdomain likely %u country code %u\n", | 203 | "regdomain likely %u country code %u\n", |
203 | __func__, rd, CTRY_DEFAULT); | 204 | rd, CTRY_DEFAULT); |
204 | return -EINVAL; | 205 | return -EINVAL; |
205 | } | 206 | } |
206 | 207 | ||
@@ -223,9 +224,9 @@ static int ath_setup_channels(struct ath_softc *sc) | |||
223 | 224 | ||
224 | band_2ghz->n_channels = ++a; | 225 | band_2ghz->n_channels = ++a; |
225 | 226 | ||
226 | DPRINTF(sc, ATH_DBG_CONFIG, "%s: 2MHz channel: %d, " | 227 | DPRINTF(sc, ATH_DBG_CONFIG, "2MHz channel: %d, " |
227 | "channelFlags: 0x%x\n", | 228 | "channelFlags: 0x%x\n", |
228 | __func__, c->channel, c->channelFlags); | 229 | c->channel, c->channelFlags); |
229 | } else if (IS_CHAN_5GHZ(c)) { | 230 | } else if (IS_CHAN_5GHZ(c)) { |
230 | chan_5ghz[b].band = IEEE80211_BAND_5GHZ; | 231 | chan_5ghz[b].band = IEEE80211_BAND_5GHZ; |
231 | chan_5ghz[b].center_freq = c->channel; | 232 | chan_5ghz[b].center_freq = c->channel; |
@@ -238,9 +239,9 @@ static int ath_setup_channels(struct ath_softc *sc) | |||
238 | 239 | ||
239 | band_5ghz->n_channels = ++b; | 240 | band_5ghz->n_channels = ++b; |
240 | 241 | ||
241 | DPRINTF(sc, ATH_DBG_CONFIG, "%s: 5MHz channel: %d, " | 242 | DPRINTF(sc, ATH_DBG_CONFIG, "5MHz channel: %d, " |
242 | "channelFlags: 0x%x\n", | 243 | "channelFlags: 0x%x\n", |
243 | __func__, c->channel, c->channelFlags); | 244 | c->channel, c->channelFlags); |
244 | } | 245 | } |
245 | } | 246 | } |
246 | 247 | ||
@@ -274,9 +275,9 @@ static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan) | |||
274 | * hardware at the new frequency, and then re-enable | 275 | * hardware at the new frequency, and then re-enable |
275 | * the relevant bits of the h/w. | 276 | * the relevant bits of the h/w. |
276 | */ | 277 | */ |
277 | ath9k_hw_set_interrupts(ah, 0); /* disable interrupts */ | 278 | ath9k_hw_set_interrupts(ah, 0); |
278 | ath_draintxq(sc, false); /* clear pending tx frames */ | 279 | ath_draintxq(sc, false); |
279 | stopped = ath_stoprecv(sc); /* turn off frame recv */ | 280 | stopped = ath_stoprecv(sc); |
280 | 281 | ||
281 | /* XXX: do not flush receive queue here. We don't want | 282 | /* XXX: do not flush receive queue here. We don't want |
282 | * to flush data frames already in queue because of | 283 | * to flush data frames already in queue because of |
@@ -286,8 +287,7 @@ static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan) | |||
286 | fastcc = false; | 287 | fastcc = false; |
287 | 288 | ||
288 | DPRINTF(sc, ATH_DBG_CONFIG, | 289 | DPRINTF(sc, ATH_DBG_CONFIG, |
289 | "%s: (%u MHz) -> (%u MHz), cflags:%x, chanwidth: %d\n", | 290 | "(%u MHz) -> (%u MHz), cflags:%x, chanwidth: %d\n", |
290 | __func__, | ||
291 | sc->sc_ah->ah_curchan->channel, | 291 | sc->sc_ah->ah_curchan->channel, |
292 | hchan->channel, hchan->channelFlags, sc->tx_chan_width); | 292 | hchan->channel, hchan->channelFlags, sc->tx_chan_width); |
293 | 293 | ||
@@ -296,8 +296,8 @@ static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan) | |||
296 | sc->sc_tx_chainmask, sc->sc_rx_chainmask, | 296 | sc->sc_tx_chainmask, sc->sc_rx_chainmask, |
297 | sc->sc_ht_extprotspacing, fastcc, &status)) { | 297 | sc->sc_ht_extprotspacing, fastcc, &status)) { |
298 | DPRINTF(sc, ATH_DBG_FATAL, | 298 | DPRINTF(sc, ATH_DBG_FATAL, |
299 | "%s: unable to reset channel %u (%uMhz) " | 299 | "Unable to reset channel %u (%uMhz) " |
300 | "flags 0x%x hal status %u\n", __func__, | 300 | "flags 0x%x hal status %u\n", |
301 | ath9k_hw_mhz2ieee(ah, hchan->channel, | 301 | ath9k_hw_mhz2ieee(ah, hchan->channel, |
302 | hchan->channelFlags), | 302 | hchan->channelFlags), |
303 | hchan->channel, hchan->channelFlags, status); | 303 | hchan->channel, hchan->channelFlags, status); |
@@ -311,7 +311,7 @@ static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan) | |||
311 | 311 | ||
312 | if (ath_startrecv(sc) != 0) { | 312 | if (ath_startrecv(sc) != 0) { |
313 | DPRINTF(sc, ATH_DBG_FATAL, | 313 | DPRINTF(sc, ATH_DBG_FATAL, |
314 | "%s: unable to restart recv logic\n", __func__); | 314 | "Unable to restart recv logic\n"); |
315 | return -EIO; | 315 | return -EIO; |
316 | } | 316 | } |
317 | 317 | ||
@@ -352,8 +352,7 @@ static void ath_ani_calibrate(unsigned long data) | |||
352 | /* Long calibration runs independently of short calibration. */ | 352 | /* Long calibration runs independently of short calibration. */ |
353 | if ((timestamp - sc->sc_ani.sc_longcal_timer) >= ATH_LONG_CALINTERVAL) { | 353 | if ((timestamp - sc->sc_ani.sc_longcal_timer) >= ATH_LONG_CALINTERVAL) { |
354 | longcal = true; | 354 | longcal = true; |
355 | DPRINTF(sc, ATH_DBG_ANI, "%s: longcal @%lu\n", | 355 | DPRINTF(sc, ATH_DBG_ANI, "longcal @%lu\n", jiffies); |
356 | __func__, jiffies); | ||
357 | sc->sc_ani.sc_longcal_timer = timestamp; | 356 | sc->sc_ani.sc_longcal_timer = timestamp; |
358 | } | 357 | } |
359 | 358 | ||
@@ -362,8 +361,7 @@ static void ath_ani_calibrate(unsigned long data) | |||
362 | if ((timestamp - sc->sc_ani.sc_shortcal_timer) >= | 361 | if ((timestamp - sc->sc_ani.sc_shortcal_timer) >= |
363 | ATH_SHORT_CALINTERVAL) { | 362 | ATH_SHORT_CALINTERVAL) { |
364 | shortcal = true; | 363 | shortcal = true; |
365 | DPRINTF(sc, ATH_DBG_ANI, "%s: shortcal @%lu\n", | 364 | DPRINTF(sc, ATH_DBG_ANI, "shortcal @%lu\n", jiffies); |
366 | __func__, jiffies); | ||
367 | sc->sc_ani.sc_shortcal_timer = timestamp; | 365 | sc->sc_ani.sc_shortcal_timer = timestamp; |
368 | sc->sc_ani.sc_resetcal_timer = timestamp; | 366 | sc->sc_ani.sc_resetcal_timer = timestamp; |
369 | } | 367 | } |
@@ -404,15 +402,13 @@ static void ath_ani_calibrate(unsigned long data) | |||
404 | ah->ah_curchan); | 402 | ah->ah_curchan); |
405 | 403 | ||
406 | DPRINTF(sc, ATH_DBG_ANI, | 404 | DPRINTF(sc, ATH_DBG_ANI, |
407 | "%s: calibrate chan %u/%x nf: %d\n", | 405 | "calibrate chan %u/%x nf: %d\n", |
408 | __func__, | ||
409 | ah->ah_curchan->channel, | 406 | ah->ah_curchan->channel, |
410 | ah->ah_curchan->channelFlags, | 407 | ah->ah_curchan->channelFlags, |
411 | sc->sc_ani.sc_noise_floor); | 408 | sc->sc_ani.sc_noise_floor); |
412 | } else { | 409 | } else { |
413 | DPRINTF(sc, ATH_DBG_ANY, | 410 | DPRINTF(sc, ATH_DBG_ANY, |
414 | "%s: calibrate chan %u/%x failed\n", | 411 | "calibrate chan %u/%x failed\n", |
415 | __func__, | ||
416 | ah->ah_curchan->channel, | 412 | ah->ah_curchan->channel, |
417 | ah->ah_curchan->channelFlags); | 413 | ah->ah_curchan->channelFlags); |
418 | } | 414 | } |
@@ -425,8 +421,9 @@ static void ath_ani_calibrate(unsigned long data) | |||
425 | * The interval must be the shortest necessary to satisfy ANI, | 421 | * The interval must be the shortest necessary to satisfy ANI, |
426 | * short calibration and long calibration. | 422 | * short calibration and long calibration. |
427 | */ | 423 | */ |
428 | 424 | cal_interval = ATH_LONG_CALINTERVAL; | |
429 | cal_interval = ATH_ANI_POLLINTERVAL; | 425 | if (sc->sc_ah->ah_config.enable_ani) |
426 | cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL); | ||
430 | if (!sc->sc_ani.sc_caldone) | 427 | if (!sc->sc_ani.sc_caldone) |
431 | cal_interval = min(cal_interval, (u32)ATH_SHORT_CALINTERVAL); | 428 | cal_interval = min(cal_interval, (u32)ATH_SHORT_CALINTERVAL); |
432 | 429 | ||
@@ -449,8 +446,8 @@ static void ath_update_chainmask(struct ath_softc *sc, int is_ht) | |||
449 | sc->sc_rx_chainmask = 1; | 446 | sc->sc_rx_chainmask = 1; |
450 | } | 447 | } |
451 | 448 | ||
452 | DPRINTF(sc, ATH_DBG_CONFIG, "%s: tx chmask: %d, rx chmask: %d\n", | 449 | DPRINTF(sc, ATH_DBG_CONFIG, "tx chmask: %d, rx chmask: %d\n", |
453 | __func__, sc->sc_tx_chainmask, sc->sc_rx_chainmask); | 450 | sc->sc_tx_chainmask, sc->sc_rx_chainmask); |
454 | } | 451 | } |
455 | 452 | ||
456 | static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta) | 453 | static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta) |
@@ -622,35 +619,35 @@ static int ath_get_channel(struct ath_softc *sc, | |||
622 | return -1; | 619 | return -1; |
623 | } | 620 | } |
624 | 621 | ||
622 | /* ext_chan_offset: (-1, 0, 1) (below, none, above) */ | ||
623 | |||
625 | static u32 ath_get_extchanmode(struct ath_softc *sc, | 624 | static u32 ath_get_extchanmode(struct ath_softc *sc, |
626 | struct ieee80211_channel *chan, | 625 | struct ieee80211_channel *chan, |
627 | struct ieee80211_bss_conf *bss_conf) | 626 | int ext_chan_offset, |
627 | enum ath9k_ht_macmode tx_chan_width) | ||
628 | { | 628 | { |
629 | u32 chanmode = 0; | 629 | u32 chanmode = 0; |
630 | u8 ext_chan_offset = bss_conf->ht.secondary_channel_offset; | ||
631 | enum ath9k_ht_macmode tx_chan_width = (bss_conf->ht.width_40_ok) ? | ||
632 | ATH9K_HT_MACMODE_2040 : ATH9K_HT_MACMODE_20; | ||
633 | 630 | ||
634 | switch (chan->band) { | 631 | switch (chan->band) { |
635 | case IEEE80211_BAND_2GHZ: | 632 | case IEEE80211_BAND_2GHZ: |
636 | if ((ext_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_NONE) && | 633 | if ((ext_chan_offset == 0) && |
637 | (tx_chan_width == ATH9K_HT_MACMODE_20)) | 634 | (tx_chan_width == ATH9K_HT_MACMODE_20)) |
638 | chanmode = CHANNEL_G_HT20; | 635 | chanmode = CHANNEL_G_HT20; |
639 | if ((ext_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE) && | 636 | if ((ext_chan_offset == 1) && |
640 | (tx_chan_width == ATH9K_HT_MACMODE_2040)) | 637 | (tx_chan_width == ATH9K_HT_MACMODE_2040)) |
641 | chanmode = CHANNEL_G_HT40PLUS; | 638 | chanmode = CHANNEL_G_HT40PLUS; |
642 | if ((ext_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_BELOW) && | 639 | if ((ext_chan_offset == -1) && |
643 | (tx_chan_width == ATH9K_HT_MACMODE_2040)) | 640 | (tx_chan_width == ATH9K_HT_MACMODE_2040)) |
644 | chanmode = CHANNEL_G_HT40MINUS; | 641 | chanmode = CHANNEL_G_HT40MINUS; |
645 | break; | 642 | break; |
646 | case IEEE80211_BAND_5GHZ: | 643 | case IEEE80211_BAND_5GHZ: |
647 | if ((ext_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_NONE) && | 644 | if ((ext_chan_offset == 0) && |
648 | (tx_chan_width == ATH9K_HT_MACMODE_20)) | 645 | (tx_chan_width == ATH9K_HT_MACMODE_20)) |
649 | chanmode = CHANNEL_A_HT20; | 646 | chanmode = CHANNEL_A_HT20; |
650 | if ((ext_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE) && | 647 | if ((ext_chan_offset == 1) && |
651 | (tx_chan_width == ATH9K_HT_MACMODE_2040)) | 648 | (tx_chan_width == ATH9K_HT_MACMODE_2040)) |
652 | chanmode = CHANNEL_A_HT40PLUS; | 649 | chanmode = CHANNEL_A_HT40PLUS; |
653 | if ((ext_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_BELOW) && | 650 | if ((ext_chan_offset == -1) && |
654 | (tx_chan_width == ATH9K_HT_MACMODE_2040)) | 651 | (tx_chan_width == ATH9K_HT_MACMODE_2040)) |
655 | chanmode = CHANNEL_A_HT40MINUS; | 652 | chanmode = CHANNEL_A_HT40MINUS; |
656 | break; | 653 | break; |
@@ -712,7 +709,7 @@ static int ath_setkey_tkip(struct ath_softc *sc, | |||
712 | if (!ath_keyset(sc, key->keyidx, hk, NULL)) { | 709 | if (!ath_keyset(sc, key->keyidx, hk, NULL)) { |
713 | /* Txmic entry failed. No need to proceed further */ | 710 | /* Txmic entry failed. No need to proceed further */ |
714 | DPRINTF(sc, ATH_DBG_KEYCACHE, | 711 | DPRINTF(sc, ATH_DBG_KEYCACHE, |
715 | "%s Setting TX MIC Key Failed\n", __func__); | 712 | "Setting TX MIC Key Failed\n"); |
716 | return 0; | 713 | return 0; |
717 | } | 714 | } |
718 | 715 | ||
@@ -758,13 +755,17 @@ static int ath_key_config(struct ath_softc *sc, | |||
758 | 755 | ||
759 | /* | 756 | /* |
760 | * Strategy: | 757 | * Strategy: |
761 | * For _M_STA mc tx, we will not setup a key at all since we never | 758 | * For STA mc tx, we will not setup a key at |
762 | * tx mc. | 759 | * all since we never tx mc. |
763 | * _M_STA mc rx, we will use the keyID. | 760 | * |
764 | * for _M_IBSS mc tx, we will use the keyID, and no macaddr. | 761 | * For STA mc rx, we will use the keyID. |
765 | * for _M_IBSS mc rx, we will alloc a slot and plumb the mac of the | 762 | * |
766 | * peer node. BUT we will plumb a cleartext key so that we can do | 763 | * For ADHOC mc tx, we will use the keyID, and no macaddr. |
767 | * perSta default key table lookup in software. | 764 | * |
765 | * For ADHOC mc rx, we will alloc a slot and plumb the mac of | ||
766 | * the peer node. | ||
767 | * BUT we will plumb a cleartext key so that we can do | ||
768 | * per-Sta default key table lookup in software. | ||
768 | */ | 769 | */ |
769 | if (is_broadcast_ether_addr(addr)) { | 770 | if (is_broadcast_ether_addr(addr)) { |
770 | switch (opmode) { | 771 | switch (opmode) { |
@@ -836,11 +837,22 @@ static void ath9k_ht_conf(struct ath_softc *sc, | |||
836 | ath9k_hw_set11nmac2040(sc->sc_ah, sc->tx_chan_width); | 837 | ath9k_hw_set11nmac2040(sc->sc_ah, sc->tx_chan_width); |
837 | 838 | ||
838 | DPRINTF(sc, ATH_DBG_CONFIG, | 839 | DPRINTF(sc, ATH_DBG_CONFIG, |
839 | "%s: BSS Changed HT, chanwidth: %d\n", | 840 | "BSS Changed HT, chanwidth: %d\n", sc->tx_chan_width); |
840 | __func__, sc->tx_chan_width); | ||
841 | } | 841 | } |
842 | } | 842 | } |
843 | 843 | ||
844 | static inline int ath_sec_offset(u8 ext_offset) | ||
845 | { | ||
846 | if (ext_offset == IEEE80211_HT_PARAM_CHA_SEC_NONE) | ||
847 | return 0; | ||
848 | else if (ext_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE) | ||
849 | return 1; | ||
850 | else if (ext_offset == IEEE80211_HT_PARAM_CHA_SEC_BELOW) | ||
851 | return -1; | ||
852 | |||
853 | return 0; | ||
854 | } | ||
855 | |||
844 | static void ath9k_bss_assoc_info(struct ath_softc *sc, | 856 | static void ath9k_bss_assoc_info(struct ath_softc *sc, |
845 | struct ieee80211_vif *vif, | 857 | struct ieee80211_vif *vif, |
846 | struct ieee80211_bss_conf *bss_conf) | 858 | struct ieee80211_bss_conf *bss_conf) |
@@ -851,12 +863,10 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, | |||
851 | int pos; | 863 | int pos; |
852 | 864 | ||
853 | if (bss_conf->assoc) { | 865 | if (bss_conf->assoc) { |
854 | DPRINTF(sc, ATH_DBG_CONFIG, "%s: Bss Info ASSOC %d\n", | 866 | DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info ASSOC %d\n", bss_conf->aid); |
855 | __func__, | ||
856 | bss_conf->aid); | ||
857 | 867 | ||
858 | /* New association, store aid */ | 868 | /* New association, store aid */ |
859 | if (avp->av_opmode == ATH9K_M_STA) { | 869 | if (avp->av_opmode == NL80211_IFTYPE_STATION) { |
860 | sc->sc_curaid = bss_conf->aid; | 870 | sc->sc_curaid = bss_conf->aid; |
861 | ath9k_hw_write_associd(sc->sc_ah, sc->sc_curbssid, | 871 | ath9k_hw_write_associd(sc->sc_ah, sc->sc_curbssid, |
862 | sc->sc_curaid); | 872 | sc->sc_curaid); |
@@ -876,29 +886,25 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, | |||
876 | ath_update_chainmask(sc, hw->conf.ht.enabled); | 886 | ath_update_chainmask(sc, hw->conf.ht.enabled); |
877 | 887 | ||
878 | DPRINTF(sc, ATH_DBG_CONFIG, | 888 | DPRINTF(sc, ATH_DBG_CONFIG, |
879 | "%s: bssid %pM aid 0x%x\n", | 889 | "bssid %pM aid 0x%x\n", |
880 | __func__, | ||
881 | sc->sc_curbssid, sc->sc_curaid); | 890 | sc->sc_curbssid, sc->sc_curaid); |
882 | 891 | ||
883 | DPRINTF(sc, ATH_DBG_CONFIG, "%s: Set channel: %d MHz\n", | ||
884 | __func__, | ||
885 | curchan->center_freq); | ||
886 | |||
887 | pos = ath_get_channel(sc, curchan); | 892 | pos = ath_get_channel(sc, curchan); |
888 | if (pos == -1) { | 893 | if (pos == -1) { |
889 | DPRINTF(sc, ATH_DBG_FATAL, | 894 | DPRINTF(sc, ATH_DBG_FATAL, |
890 | "%s: Invalid channel\n", __func__); | 895 | "Invalid channel: %d\n", curchan->center_freq); |
891 | return; | 896 | return; |
892 | } | 897 | } |
893 | 898 | ||
894 | if (hw->conf.ht.enabled) { | 899 | if (hw->conf.ht.enabled) { |
895 | sc->sc_ah->ah_channels[pos].chanmode = | 900 | int offset = |
896 | ath_get_extchanmode(sc, curchan, bss_conf); | 901 | ath_sec_offset(bss_conf->ht.secondary_channel_offset); |
902 | sc->tx_chan_width = (bss_conf->ht.width_40_ok) ? | ||
903 | ATH9K_HT_MACMODE_2040 : ATH9K_HT_MACMODE_20; | ||
897 | 904 | ||
898 | if (bss_conf->ht.width_40_ok) | 905 | sc->sc_ah->ah_channels[pos].chanmode = |
899 | sc->tx_chan_width = ATH9K_HT_MACMODE_2040; | 906 | ath_get_extchanmode(sc, curchan, |
900 | else | 907 | offset, sc->tx_chan_width); |
901 | sc->tx_chan_width = ATH9K_HT_MACMODE_20; | ||
902 | } else { | 908 | } else { |
903 | sc->sc_ah->ah_channels[pos].chanmode = | 909 | sc->sc_ah->ah_channels[pos].chanmode = |
904 | (curchan->band == IEEE80211_BAND_2GHZ) ? | 910 | (curchan->band == IEEE80211_BAND_2GHZ) ? |
@@ -907,14 +913,15 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, | |||
907 | 913 | ||
908 | /* set h/w channel */ | 914 | /* set h/w channel */ |
909 | if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0) | 915 | if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0) |
910 | DPRINTF(sc, ATH_DBG_FATAL, | 916 | DPRINTF(sc, ATH_DBG_FATAL, "Unable to set channel: %d\n", |
911 | "%s: Unable to set channel\n", __func__); | 917 | curchan->center_freq); |
918 | |||
912 | /* Start ANI */ | 919 | /* Start ANI */ |
913 | mod_timer(&sc->sc_ani.timer, | 920 | mod_timer(&sc->sc_ani.timer, |
914 | jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); | 921 | jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); |
915 | 922 | ||
916 | } else { | 923 | } else { |
917 | DPRINTF(sc, ATH_DBG_CONFIG, "%s: Bss Info DISSOC\n", __func__); | 924 | DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info DISSOC\n"); |
918 | sc->sc_curaid = 0; | 925 | sc->sc_curaid = 0; |
919 | } | 926 | } |
920 | } | 927 | } |
@@ -1053,8 +1060,8 @@ static void ath_radio_enable(struct ath_softc *sc) | |||
1053 | sc->sc_ht_extprotspacing, | 1060 | sc->sc_ht_extprotspacing, |
1054 | false, &status)) { | 1061 | false, &status)) { |
1055 | DPRINTF(sc, ATH_DBG_FATAL, | 1062 | DPRINTF(sc, ATH_DBG_FATAL, |
1056 | "%s: unable to reset channel %u (%uMhz) " | 1063 | "Unable to reset channel %u (%uMhz) " |
1057 | "flags 0x%x hal status %u\n", __func__, | 1064 | "flags 0x%x hal status %u\n", |
1058 | ath9k_hw_mhz2ieee(ah, | 1065 | ath9k_hw_mhz2ieee(ah, |
1059 | ah->ah_curchan->channel, | 1066 | ah->ah_curchan->channel, |
1060 | ah->ah_curchan->channelFlags), | 1067 | ah->ah_curchan->channelFlags), |
@@ -1066,7 +1073,7 @@ static void ath_radio_enable(struct ath_softc *sc) | |||
1066 | ath_update_txpow(sc); | 1073 | ath_update_txpow(sc); |
1067 | if (ath_startrecv(sc) != 0) { | 1074 | if (ath_startrecv(sc) != 0) { |
1068 | DPRINTF(sc, ATH_DBG_FATAL, | 1075 | DPRINTF(sc, ATH_DBG_FATAL, |
1069 | "%s: unable to restart recv logic\n", __func__); | 1076 | "Unable to restart recv logic\n"); |
1070 | return; | 1077 | return; |
1071 | } | 1078 | } |
1072 | 1079 | ||
@@ -1111,8 +1118,8 @@ static void ath_radio_disable(struct ath_softc *sc) | |||
1111 | sc->sc_ht_extprotspacing, | 1118 | sc->sc_ht_extprotspacing, |
1112 | false, &status)) { | 1119 | false, &status)) { |
1113 | DPRINTF(sc, ATH_DBG_FATAL, | 1120 | DPRINTF(sc, ATH_DBG_FATAL, |
1114 | "%s: unable to reset channel %u (%uMhz) " | 1121 | "Unable to reset channel %u (%uMhz) " |
1115 | "flags 0x%x hal status %u\n", __func__, | 1122 | "flags 0x%x hal status %u\n", |
1116 | ath9k_hw_mhz2ieee(ah, | 1123 | ath9k_hw_mhz2ieee(ah, |
1117 | ah->ah_curchan->channel, | 1124 | ah->ah_curchan->channel, |
1118 | ah->ah_curchan->channelFlags), | 1125 | ah->ah_curchan->channelFlags), |
@@ -1192,7 +1199,7 @@ static int ath_sw_toggle_radio(void *data, enum rfkill_state state) | |||
1192 | sc->sc_flags &= ~SC_OP_RFKILL_SW_BLOCKED; | 1199 | sc->sc_flags &= ~SC_OP_RFKILL_SW_BLOCKED; |
1193 | if (sc->sc_flags & SC_OP_RFKILL_HW_BLOCKED) { | 1200 | if (sc->sc_flags & SC_OP_RFKILL_HW_BLOCKED) { |
1194 | DPRINTF(sc, ATH_DBG_FATAL, "Can't turn on the" | 1201 | DPRINTF(sc, ATH_DBG_FATAL, "Can't turn on the" |
1195 | "radio as it is disabled by h/w \n"); | 1202 | "radio as it is disabled by h/w\n"); |
1196 | return -EPERM; | 1203 | return -EPERM; |
1197 | } | 1204 | } |
1198 | ath_radio_enable(sc); | 1205 | ath_radio_enable(sc); |
@@ -1272,7 +1279,7 @@ static void ath_detach(struct ath_softc *sc) | |||
1272 | struct ieee80211_hw *hw = sc->hw; | 1279 | struct ieee80211_hw *hw = sc->hw; |
1273 | int i = 0; | 1280 | int i = 0; |
1274 | 1281 | ||
1275 | DPRINTF(sc, ATH_DBG_CONFIG, "%s: Detach ATH hw\n", __func__); | 1282 | DPRINTF(sc, ATH_DBG_CONFIG, "Detach ATH hw\n"); |
1276 | 1283 | ||
1277 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | 1284 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) |
1278 | ath_deinit_rfkill(sc); | 1285 | ath_deinit_rfkill(sc); |
@@ -1298,6 +1305,7 @@ static void ath_detach(struct ath_softc *sc) | |||
1298 | ath_tx_cleanupq(sc, &sc->sc_txq[i]); | 1305 | ath_tx_cleanupq(sc, &sc->sc_txq[i]); |
1299 | 1306 | ||
1300 | ath9k_hw_detach(sc->sc_ah); | 1307 | ath9k_hw_detach(sc->sc_ah); |
1308 | ath9k_exit_debug(sc); | ||
1301 | } | 1309 | } |
1302 | 1310 | ||
1303 | static int ath_init(u16 devid, struct ath_softc *sc) | 1311 | static int ath_init(u16 devid, struct ath_softc *sc) |
@@ -1309,7 +1317,9 @@ static int ath_init(u16 devid, struct ath_softc *sc) | |||
1309 | 1317 | ||
1310 | /* XXX: hardware will not be ready until ath_open() being called */ | 1318 | /* XXX: hardware will not be ready until ath_open() being called */ |
1311 | sc->sc_flags |= SC_OP_INVALID; | 1319 | sc->sc_flags |= SC_OP_INVALID; |
1312 | sc->sc_debug = DBG_DEFAULT; | 1320 | |
1321 | if (ath9k_init_debug(sc) < 0) | ||
1322 | printk(KERN_ERR "Unable to create debugfs files\n"); | ||
1313 | 1323 | ||
1314 | spin_lock_init(&sc->sc_resetlock); | 1324 | spin_lock_init(&sc->sc_resetlock); |
1315 | tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); | 1325 | tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); |
@@ -1327,8 +1337,7 @@ static int ath_init(u16 devid, struct ath_softc *sc) | |||
1327 | ah = ath9k_hw_attach(devid, sc, sc->mem, &status); | 1337 | ah = ath9k_hw_attach(devid, sc, sc->mem, &status); |
1328 | if (ah == NULL) { | 1338 | if (ah == NULL) { |
1329 | DPRINTF(sc, ATH_DBG_FATAL, | 1339 | DPRINTF(sc, ATH_DBG_FATAL, |
1330 | "%s: unable to attach hardware; HAL status %u\n", | 1340 | "Unable to attach hardware; HAL status %u\n", status); |
1331 | __func__, status); | ||
1332 | error = -ENXIO; | 1341 | error = -ENXIO; |
1333 | goto bad; | 1342 | goto bad; |
1334 | } | 1343 | } |
@@ -1338,8 +1347,8 @@ static int ath_init(u16 devid, struct ath_softc *sc) | |||
1338 | sc->sc_keymax = ah->ah_caps.keycache_size; | 1347 | sc->sc_keymax = ah->ah_caps.keycache_size; |
1339 | if (sc->sc_keymax > ATH_KEYMAX) { | 1348 | if (sc->sc_keymax > ATH_KEYMAX) { |
1340 | DPRINTF(sc, ATH_DBG_KEYCACHE, | 1349 | DPRINTF(sc, ATH_DBG_KEYCACHE, |
1341 | "%s: Warning, using only %u entries in %u key cache\n", | 1350 | "Warning, using only %u entries in %u key cache\n", |
1342 | __func__, ATH_KEYMAX, sc->sc_keymax); | 1351 | ATH_KEYMAX, sc->sc_keymax); |
1343 | sc->sc_keymax = ATH_KEYMAX; | 1352 | sc->sc_keymax = ATH_KEYMAX; |
1344 | } | 1353 | } |
1345 | 1354 | ||
@@ -1369,7 +1378,8 @@ static int ath_init(u16 devid, struct ath_softc *sc) | |||
1369 | goto bad; | 1378 | goto bad; |
1370 | 1379 | ||
1371 | /* default to MONITOR mode */ | 1380 | /* default to MONITOR mode */ |
1372 | sc->sc_ah->ah_opmode = ATH9K_M_MONITOR; | 1381 | sc->sc_ah->ah_opmode = NL80211_IFTYPE_MONITOR; |
1382 | |||
1373 | 1383 | ||
1374 | /* Setup rate tables */ | 1384 | /* Setup rate tables */ |
1375 | 1385 | ||
@@ -1386,14 +1396,14 @@ static int ath_init(u16 devid, struct ath_softc *sc) | |||
1386 | sc->sc_bhalq = ath_beaconq_setup(ah); | 1396 | sc->sc_bhalq = ath_beaconq_setup(ah); |
1387 | if (sc->sc_bhalq == -1) { | 1397 | if (sc->sc_bhalq == -1) { |
1388 | DPRINTF(sc, ATH_DBG_FATAL, | 1398 | DPRINTF(sc, ATH_DBG_FATAL, |
1389 | "%s: unable to setup a beacon xmit queue\n", __func__); | 1399 | "Unable to setup a beacon xmit queue\n"); |
1390 | error = -EIO; | 1400 | error = -EIO; |
1391 | goto bad2; | 1401 | goto bad2; |
1392 | } | 1402 | } |
1393 | sc->sc_cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0); | 1403 | sc->sc_cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0); |
1394 | if (sc->sc_cabq == NULL) { | 1404 | if (sc->sc_cabq == NULL) { |
1395 | DPRINTF(sc, ATH_DBG_FATAL, | 1405 | DPRINTF(sc, ATH_DBG_FATAL, |
1396 | "%s: unable to setup CAB xmit queue\n", __func__); | 1406 | "Unable to setup CAB xmit queue\n"); |
1397 | error = -EIO; | 1407 | error = -EIO; |
1398 | goto bad2; | 1408 | goto bad2; |
1399 | } | 1409 | } |
@@ -1408,30 +1418,26 @@ static int ath_init(u16 devid, struct ath_softc *sc) | |||
1408 | /* NB: ensure BK queue is the lowest priority h/w queue */ | 1418 | /* NB: ensure BK queue is the lowest priority h/w queue */ |
1409 | if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) { | 1419 | if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) { |
1410 | DPRINTF(sc, ATH_DBG_FATAL, | 1420 | DPRINTF(sc, ATH_DBG_FATAL, |
1411 | "%s: unable to setup xmit queue for BK traffic\n", | 1421 | "Unable to setup xmit queue for BK traffic\n"); |
1412 | __func__); | ||
1413 | error = -EIO; | 1422 | error = -EIO; |
1414 | goto bad2; | 1423 | goto bad2; |
1415 | } | 1424 | } |
1416 | 1425 | ||
1417 | if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) { | 1426 | if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) { |
1418 | DPRINTF(sc, ATH_DBG_FATAL, | 1427 | DPRINTF(sc, ATH_DBG_FATAL, |
1419 | "%s: unable to setup xmit queue for BE traffic\n", | 1428 | "Unable to setup xmit queue for BE traffic\n"); |
1420 | __func__); | ||
1421 | error = -EIO; | 1429 | error = -EIO; |
1422 | goto bad2; | 1430 | goto bad2; |
1423 | } | 1431 | } |
1424 | if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) { | 1432 | if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) { |
1425 | DPRINTF(sc, ATH_DBG_FATAL, | 1433 | DPRINTF(sc, ATH_DBG_FATAL, |
1426 | "%s: unable to setup xmit queue for VI traffic\n", | 1434 | "Unable to setup xmit queue for VI traffic\n"); |
1427 | __func__); | ||
1428 | error = -EIO; | 1435 | error = -EIO; |
1429 | goto bad2; | 1436 | goto bad2; |
1430 | } | 1437 | } |
1431 | if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) { | 1438 | if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) { |
1432 | DPRINTF(sc, ATH_DBG_FATAL, | 1439 | DPRINTF(sc, ATH_DBG_FATAL, |
1433 | "%s: unable to setup xmit queue for VO traffic\n", | 1440 | "Unable to setup xmit queue for VO traffic\n"); |
1434 | __func__); | ||
1435 | error = -EIO; | 1441 | error = -EIO; |
1436 | goto bad2; | 1442 | goto bad2; |
1437 | } | 1443 | } |
@@ -1543,7 +1549,7 @@ static int ath_attach(u16 devid, struct ath_softc *sc) | |||
1543 | struct ieee80211_hw *hw = sc->hw; | 1549 | struct ieee80211_hw *hw = sc->hw; |
1544 | int error = 0; | 1550 | int error = 0; |
1545 | 1551 | ||
1546 | DPRINTF(sc, ATH_DBG_CONFIG, "%s: Attach ATH hw\n", __func__); | 1552 | DPRINTF(sc, ATH_DBG_CONFIG, "Attach ATH hw\n"); |
1547 | 1553 | ||
1548 | error = ath_init(devid, sc); | 1554 | error = ath_init(devid, sc); |
1549 | if (error != 0) | 1555 | if (error != 0) |
@@ -1574,8 +1580,7 @@ static int ath_attach(u16 devid, struct ath_softc *sc) | |||
1574 | error = ath_rate_control_register(); | 1580 | error = ath_rate_control_register(); |
1575 | if (error != 0) { | 1581 | if (error != 0) { |
1576 | DPRINTF(sc, ATH_DBG_FATAL, | 1582 | DPRINTF(sc, ATH_DBG_FATAL, |
1577 | "%s: Unable to register rate control " | 1583 | "Unable to register rate control algorithm: %d\n", error); |
1578 | "algorithm:%d\n", __func__, error); | ||
1579 | ath_rate_control_unregister(); | 1584 | ath_rate_control_unregister(); |
1580 | goto bad; | 1585 | goto bad; |
1581 | } | 1586 | } |
@@ -1643,15 +1648,13 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
1643 | sc->sc_tx_chainmask, sc->sc_rx_chainmask, | 1648 | sc->sc_tx_chainmask, sc->sc_rx_chainmask, |
1644 | sc->sc_ht_extprotspacing, false, &status)) { | 1649 | sc->sc_ht_extprotspacing, false, &status)) { |
1645 | DPRINTF(sc, ATH_DBG_FATAL, | 1650 | DPRINTF(sc, ATH_DBG_FATAL, |
1646 | "%s: unable to reset hardware; hal status %u\n", | 1651 | "Unable to reset hardware; hal status %u\n", status); |
1647 | __func__, status); | ||
1648 | error = -EIO; | 1652 | error = -EIO; |
1649 | } | 1653 | } |
1650 | spin_unlock_bh(&sc->sc_resetlock); | 1654 | spin_unlock_bh(&sc->sc_resetlock); |
1651 | 1655 | ||
1652 | if (ath_startrecv(sc) != 0) | 1656 | if (ath_startrecv(sc) != 0) |
1653 | DPRINTF(sc, ATH_DBG_FATAL, | 1657 | DPRINTF(sc, ATH_DBG_FATAL, "Unable to start recv logic\n"); |
1654 | "%s: unable to start recv logic\n", __func__); | ||
1655 | 1658 | ||
1656 | /* | 1659 | /* |
1657 | * We may be doing a reset in response to a request | 1660 | * We may be doing a reset in response to a request |
@@ -1699,13 +1702,12 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | |||
1699 | struct ath_buf *bf; | 1702 | struct ath_buf *bf; |
1700 | int i, bsize, error; | 1703 | int i, bsize, error; |
1701 | 1704 | ||
1702 | DPRINTF(sc, ATH_DBG_CONFIG, "%s: %s DMA: %u buffers %u desc/buf\n", | 1705 | DPRINTF(sc, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n", |
1703 | __func__, name, nbuf, ndesc); | 1706 | name, nbuf, ndesc); |
1704 | 1707 | ||
1705 | /* ath_desc must be a multiple of DWORDs */ | 1708 | /* ath_desc must be a multiple of DWORDs */ |
1706 | if ((sizeof(struct ath_desc) % 4) != 0) { | 1709 | if ((sizeof(struct ath_desc) % 4) != 0) { |
1707 | DPRINTF(sc, ATH_DBG_FATAL, "%s: ath_desc not DWORD aligned\n", | 1710 | DPRINTF(sc, ATH_DBG_FATAL, "ath_desc not DWORD aligned\n"); |
1708 | __func__); | ||
1709 | ASSERT((sizeof(struct ath_desc) % 4) == 0); | 1711 | ASSERT((sizeof(struct ath_desc) % 4) == 0); |
1710 | error = -ENOMEM; | 1712 | error = -ENOMEM; |
1711 | goto fail; | 1713 | goto fail; |
@@ -1741,8 +1743,8 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | |||
1741 | goto fail; | 1743 | goto fail; |
1742 | } | 1744 | } |
1743 | ds = dd->dd_desc; | 1745 | ds = dd->dd_desc; |
1744 | DPRINTF(sc, ATH_DBG_CONFIG, "%s: %s DMA map: %p (%u) -> %llx (%u)\n", | 1746 | DPRINTF(sc, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n", |
1745 | __func__, dd->dd_name, ds, (u32) dd->dd_desc_len, | 1747 | dd->dd_name, ds, (u32) dd->dd_desc_len, |
1746 | ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len); | 1748 | ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len); |
1747 | 1749 | ||
1748 | /* allocate buffers */ | 1750 | /* allocate buffers */ |
@@ -1864,14 +1866,14 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1864 | struct ath9k_channel *init_channel; | 1866 | struct ath9k_channel *init_channel; |
1865 | int error = 0, pos, status; | 1867 | int error = 0, pos, status; |
1866 | 1868 | ||
1867 | DPRINTF(sc, ATH_DBG_CONFIG, "%s: Starting driver with " | 1869 | DPRINTF(sc, ATH_DBG_CONFIG, "Starting driver with " |
1868 | "initial channel: %d MHz\n", __func__, curchan->center_freq); | 1870 | "initial channel: %d MHz\n", curchan->center_freq); |
1869 | 1871 | ||
1870 | /* setup initial channel */ | 1872 | /* setup initial channel */ |
1871 | 1873 | ||
1872 | pos = ath_get_channel(sc, curchan); | 1874 | pos = ath_get_channel(sc, curchan); |
1873 | if (pos == -1) { | 1875 | if (pos == -1) { |
1874 | DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid channel\n", __func__); | 1876 | DPRINTF(sc, ATH_DBG_FATAL, "Invalid channel: %d\n", curchan->center_freq); |
1875 | error = -EINVAL; | 1877 | error = -EINVAL; |
1876 | goto error; | 1878 | goto error; |
1877 | } | 1879 | } |
@@ -1897,8 +1899,8 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1897 | sc->sc_tx_chainmask, sc->sc_rx_chainmask, | 1899 | sc->sc_tx_chainmask, sc->sc_rx_chainmask, |
1898 | sc->sc_ht_extprotspacing, false, &status)) { | 1900 | sc->sc_ht_extprotspacing, false, &status)) { |
1899 | DPRINTF(sc, ATH_DBG_FATAL, | 1901 | DPRINTF(sc, ATH_DBG_FATAL, |
1900 | "%s: unable to reset hardware; hal status %u " | 1902 | "Unable to reset hardware; hal status %u " |
1901 | "(freq %u flags 0x%x)\n", __func__, status, | 1903 | "(freq %u flags 0x%x)\n", status, |
1902 | init_channel->channel, init_channel->channelFlags); | 1904 | init_channel->channel, init_channel->channelFlags); |
1903 | error = -EIO; | 1905 | error = -EIO; |
1904 | spin_unlock_bh(&sc->sc_resetlock); | 1906 | spin_unlock_bh(&sc->sc_resetlock); |
@@ -1921,7 +1923,7 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1921 | */ | 1923 | */ |
1922 | if (ath_startrecv(sc) != 0) { | 1924 | if (ath_startrecv(sc) != 0) { |
1923 | DPRINTF(sc, ATH_DBG_FATAL, | 1925 | DPRINTF(sc, ATH_DBG_FATAL, |
1924 | "%s: unable to start recv logic\n", __func__); | 1926 | "Unable to start recv logic\n"); |
1925 | error = -EIO; | 1927 | error = -EIO; |
1926 | goto error; | 1928 | goto error; |
1927 | } | 1929 | } |
@@ -1942,8 +1944,8 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1942 | * Note we only do this (at the moment) for station mode. | 1944 | * Note we only do this (at the moment) for station mode. |
1943 | */ | 1945 | */ |
1944 | if (ath9k_hw_phycounters(sc->sc_ah) && | 1946 | if (ath9k_hw_phycounters(sc->sc_ah) && |
1945 | ((sc->sc_ah->ah_opmode == ATH9K_M_STA) || | 1947 | ((sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION) || |
1946 | (sc->sc_ah->ah_opmode == ATH9K_M_IBSS))) | 1948 | (sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC))) |
1947 | sc->sc_imask |= ATH9K_INT_MIB; | 1949 | sc->sc_imask |= ATH9K_INT_MIB; |
1948 | /* | 1950 | /* |
1949 | * Some hardware processes the TIM IE and fires an | 1951 | * Some hardware processes the TIM IE and fires an |
@@ -1952,7 +1954,7 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1952 | * enable the TIM interrupt when operating as station. | 1954 | * enable the TIM interrupt when operating as station. |
1953 | */ | 1955 | */ |
1954 | if ((sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_ENHANCEDPM) && | 1956 | if ((sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_ENHANCEDPM) && |
1955 | (sc->sc_ah->ah_opmode == ATH9K_M_STA) && | 1957 | (sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION) && |
1956 | !sc->sc_config.swBeaconProcess) | 1958 | !sc->sc_config.swBeaconProcess) |
1957 | sc->sc_imask |= ATH9K_INT_TIM; | 1959 | sc->sc_imask |= ATH9K_INT_TIM; |
1958 | 1960 | ||
@@ -2013,12 +2015,10 @@ static int ath9k_tx(struct ieee80211_hw *hw, | |||
2013 | if (!txctl.txq) | 2015 | if (!txctl.txq) |
2014 | goto exit; | 2016 | goto exit; |
2015 | 2017 | ||
2016 | DPRINTF(sc, ATH_DBG_XMIT, "%s: transmitting packet, skb: %p\n", | 2018 | DPRINTF(sc, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb); |
2017 | __func__, | ||
2018 | skb); | ||
2019 | 2019 | ||
2020 | if (ath_tx_start(sc, skb, &txctl) != 0) { | 2020 | if (ath_tx_start(sc, skb, &txctl) != 0) { |
2021 | DPRINTF(sc, ATH_DBG_XMIT, "%s: TX failed\n", __func__); | 2021 | DPRINTF(sc, ATH_DBG_XMIT, "TX failed\n"); |
2022 | goto exit; | 2022 | goto exit; |
2023 | } | 2023 | } |
2024 | 2024 | ||
@@ -2033,11 +2033,11 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
2033 | struct ath_softc *sc = hw->priv; | 2033 | struct ath_softc *sc = hw->priv; |
2034 | 2034 | ||
2035 | if (sc->sc_flags & SC_OP_INVALID) { | 2035 | if (sc->sc_flags & SC_OP_INVALID) { |
2036 | DPRINTF(sc, ATH_DBG_ANY, "%s: Device not present\n", __func__); | 2036 | DPRINTF(sc, ATH_DBG_ANY, "Device not present\n"); |
2037 | return; | 2037 | return; |
2038 | } | 2038 | } |
2039 | 2039 | ||
2040 | DPRINTF(sc, ATH_DBG_CONFIG, "%s: Cleaning up\n", __func__); | 2040 | DPRINTF(sc, ATH_DBG_CONFIG, "Cleaning up\n"); |
2041 | 2041 | ||
2042 | ieee80211_stop_queues(sc->hw); | 2042 | ieee80211_stop_queues(sc->hw); |
2043 | 2043 | ||
@@ -2062,7 +2062,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
2062 | 2062 | ||
2063 | sc->sc_flags |= SC_OP_INVALID; | 2063 | sc->sc_flags |= SC_OP_INVALID; |
2064 | 2064 | ||
2065 | DPRINTF(sc, ATH_DBG_CONFIG, "%s: Driver halt\n", __func__); | 2065 | DPRINTF(sc, ATH_DBG_CONFIG, "Driver halt\n"); |
2066 | } | 2066 | } |
2067 | 2067 | ||
2068 | static int ath9k_add_interface(struct ieee80211_hw *hw, | 2068 | static int ath9k_add_interface(struct ieee80211_hw *hw, |
@@ -2070,7 +2070,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
2070 | { | 2070 | { |
2071 | struct ath_softc *sc = hw->priv; | 2071 | struct ath_softc *sc = hw->priv; |
2072 | struct ath_vap *avp = (void *)conf->vif->drv_priv; | 2072 | struct ath_vap *avp = (void *)conf->vif->drv_priv; |
2073 | int ic_opmode = 0; | 2073 | enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED; |
2074 | 2074 | ||
2075 | /* Support only vap for now */ | 2075 | /* Support only vap for now */ |
2076 | 2076 | ||
@@ -2079,30 +2079,27 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
2079 | 2079 | ||
2080 | switch (conf->type) { | 2080 | switch (conf->type) { |
2081 | case NL80211_IFTYPE_STATION: | 2081 | case NL80211_IFTYPE_STATION: |
2082 | ic_opmode = ATH9K_M_STA; | 2082 | ic_opmode = NL80211_IFTYPE_STATION; |
2083 | break; | 2083 | break; |
2084 | case NL80211_IFTYPE_ADHOC: | 2084 | case NL80211_IFTYPE_ADHOC: |
2085 | ic_opmode = ATH9K_M_IBSS; | 2085 | ic_opmode = NL80211_IFTYPE_ADHOC; |
2086 | break; | 2086 | break; |
2087 | case NL80211_IFTYPE_AP: | 2087 | case NL80211_IFTYPE_AP: |
2088 | ic_opmode = ATH9K_M_HOSTAP; | 2088 | ic_opmode = NL80211_IFTYPE_AP; |
2089 | break; | 2089 | break; |
2090 | default: | 2090 | default: |
2091 | DPRINTF(sc, ATH_DBG_FATAL, | 2091 | DPRINTF(sc, ATH_DBG_FATAL, |
2092 | "%s: Interface type %d not yet supported\n", | 2092 | "Interface type %d not yet supported\n", conf->type); |
2093 | __func__, conf->type); | ||
2094 | return -EOPNOTSUPP; | 2093 | return -EOPNOTSUPP; |
2095 | } | 2094 | } |
2096 | 2095 | ||
2097 | DPRINTF(sc, ATH_DBG_CONFIG, "%s: Attach a VAP of type: %d\n", | 2096 | DPRINTF(sc, ATH_DBG_CONFIG, "Attach a VAP of type: %d\n", ic_opmode); |
2098 | __func__, | ||
2099 | ic_opmode); | ||
2100 | 2097 | ||
2101 | /* Set the VAP opmode */ | 2098 | /* Set the VAP opmode */ |
2102 | avp->av_opmode = ic_opmode; | 2099 | avp->av_opmode = ic_opmode; |
2103 | avp->av_bslot = -1; | 2100 | avp->av_bslot = -1; |
2104 | 2101 | ||
2105 | if (ic_opmode == ATH9K_M_HOSTAP) | 2102 | if (ic_opmode == NL80211_IFTYPE_AP) |
2106 | ath9k_hw_set_tsfadjust(sc->sc_ah, 1); | 2103 | ath9k_hw_set_tsfadjust(sc->sc_ah, 1); |
2107 | 2104 | ||
2108 | sc->sc_vaps[0] = conf->vif; | 2105 | sc->sc_vaps[0] = conf->vif; |
@@ -2127,7 +2124,7 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, | |||
2127 | struct ath_softc *sc = hw->priv; | 2124 | struct ath_softc *sc = hw->priv; |
2128 | struct ath_vap *avp = (void *)conf->vif->drv_priv; | 2125 | struct ath_vap *avp = (void *)conf->vif->drv_priv; |
2129 | 2126 | ||
2130 | DPRINTF(sc, ATH_DBG_CONFIG, "%s: Detach VAP\n", __func__); | 2127 | DPRINTF(sc, ATH_DBG_CONFIG, "Detach Interface\n"); |
2131 | 2128 | ||
2132 | #ifdef CONFIG_SLOW_ANT_DIV | 2129 | #ifdef CONFIG_SLOW_ANT_DIV |
2133 | ath_slow_ant_div_stop(&sc->sc_antdiv); | 2130 | ath_slow_ant_div_stop(&sc->sc_antdiv); |
@@ -2136,8 +2133,8 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, | |||
2136 | del_timer_sync(&sc->sc_ani.timer); | 2133 | del_timer_sync(&sc->sc_ani.timer); |
2137 | 2134 | ||
2138 | /* Reclaim beacon resources */ | 2135 | /* Reclaim beacon resources */ |
2139 | if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP || | 2136 | if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP || |
2140 | sc->sc_ah->ah_opmode == ATH9K_M_IBSS) { | 2137 | sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC) { |
2141 | ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq); | 2138 | ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq); |
2142 | ath_beacon_return(sc, avp); | 2139 | ath_beacon_return(sc, avp); |
2143 | } | 2140 | } |
@@ -2157,12 +2154,13 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
2157 | struct ieee80211_channel *curchan = hw->conf.channel; | 2154 | struct ieee80211_channel *curchan = hw->conf.channel; |
2158 | int pos; | 2155 | int pos; |
2159 | 2156 | ||
2160 | DPRINTF(sc, ATH_DBG_CONFIG, "%s: Set channel: %d MHz\n", | 2157 | DPRINTF(sc, ATH_DBG_CONFIG, "Set channel: %d MHz\n", |
2161 | __func__, curchan->center_freq); | 2158 | curchan->center_freq); |
2162 | 2159 | ||
2163 | pos = ath_get_channel(sc, curchan); | 2160 | pos = ath_get_channel(sc, curchan); |
2164 | if (pos == -1) { | 2161 | if (pos == -1) { |
2165 | DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid channel\n", __func__); | 2162 | DPRINTF(sc, ATH_DBG_FATAL, "Invalid channel: %d\n", |
2163 | curchan->center_freq); | ||
2166 | return -EINVAL; | 2164 | return -EINVAL; |
2167 | } | 2165 | } |
2168 | 2166 | ||
@@ -2171,9 +2169,21 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
2171 | (curchan->band == IEEE80211_BAND_2GHZ) ? | 2169 | (curchan->band == IEEE80211_BAND_2GHZ) ? |
2172 | CHANNEL_G : CHANNEL_A; | 2170 | CHANNEL_G : CHANNEL_A; |
2173 | 2171 | ||
2174 | if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0) | 2172 | if ((sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) && |
2175 | DPRINTF(sc, ATH_DBG_FATAL, | 2173 | (conf->ht.enabled)) { |
2176 | "%s: Unable to set channel\n", __func__); | 2174 | sc->tx_chan_width = (!!conf->ht.sec_chan_offset) ? |
2175 | ATH9K_HT_MACMODE_2040 : ATH9K_HT_MACMODE_20; | ||
2176 | |||
2177 | sc->sc_ah->ah_channels[pos].chanmode = | ||
2178 | ath_get_extchanmode(sc, curchan, | ||
2179 | conf->ht.sec_chan_offset, | ||
2180 | sc->tx_chan_width); | ||
2181 | } | ||
2182 | |||
2183 | if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0) { | ||
2184 | DPRINTF(sc, ATH_DBG_FATAL, "Unable to set channel\n"); | ||
2185 | return -EINVAL; | ||
2186 | } | ||
2177 | } | 2187 | } |
2178 | 2188 | ||
2179 | if (changed & IEEE80211_CONF_CHANGE_HT) | 2189 | if (changed & IEEE80211_CONF_CHANGE_HT) |
@@ -2198,8 +2208,8 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, | |||
2198 | /* TODO: Need to decide which hw opmode to use for multi-interface | 2208 | /* TODO: Need to decide which hw opmode to use for multi-interface |
2199 | * cases */ | 2209 | * cases */ |
2200 | if (vif->type == NL80211_IFTYPE_AP && | 2210 | if (vif->type == NL80211_IFTYPE_AP && |
2201 | ah->ah_opmode != ATH9K_M_HOSTAP) { | 2211 | ah->ah_opmode != NL80211_IFTYPE_AP) { |
2202 | ah->ah_opmode = ATH9K_M_HOSTAP; | 2212 | ah->ah_opmode = NL80211_IFTYPE_STATION; |
2203 | ath9k_hw_setopmode(ah); | 2213 | ath9k_hw_setopmode(ah); |
2204 | ath9k_hw_write_associd(ah, sc->sc_myaddr, 0); | 2214 | ath9k_hw_write_associd(ah, sc->sc_myaddr, 0); |
2205 | /* Request full reset to get hw opmode changed properly */ | 2215 | /* Request full reset to get hw opmode changed properly */ |
@@ -2221,9 +2231,8 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, | |||
2221 | sc->sc_config.ath_aggr_prot = 0; | 2231 | sc->sc_config.ath_aggr_prot = 0; |
2222 | 2232 | ||
2223 | DPRINTF(sc, ATH_DBG_CONFIG, | 2233 | DPRINTF(sc, ATH_DBG_CONFIG, |
2224 | "%s: RX filter 0x%x bssid %pM aid 0x%x\n", | 2234 | "RX filter 0x%x bssid %pM aid 0x%x\n", |
2225 | __func__, rfilt, | 2235 | rfilt, sc->sc_curbssid, sc->sc_curaid); |
2226 | sc->sc_curbssid, sc->sc_curaid); | ||
2227 | 2236 | ||
2228 | /* need to reconfigure the beacon */ | 2237 | /* need to reconfigure the beacon */ |
2229 | sc->sc_flags &= ~SC_OP_BEACONS ; | 2238 | sc->sc_flags &= ~SC_OP_BEACONS ; |
@@ -2255,7 +2264,7 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, | |||
2255 | } | 2264 | } |
2256 | 2265 | ||
2257 | /* Check for WLAN_CAPABILITY_PRIVACY ? */ | 2266 | /* Check for WLAN_CAPABILITY_PRIVACY ? */ |
2258 | if ((avp->av_opmode != ATH9K_M_STA)) { | 2267 | if ((avp->av_opmode != NL80211_IFTYPE_STATION)) { |
2259 | for (i = 0; i < IEEE80211_WEP_NKID; i++) | 2268 | for (i = 0; i < IEEE80211_WEP_NKID; i++) |
2260 | if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i)) | 2269 | if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i)) |
2261 | ath9k_hw_keysetmac(sc->sc_ah, | 2270 | ath9k_hw_keysetmac(sc->sc_ah, |
@@ -2300,8 +2309,7 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw, | |||
2300 | ath9k_hw_write_associd(sc->sc_ah, ath_bcast_mac, 0); | 2309 | ath9k_hw_write_associd(sc->sc_ah, ath_bcast_mac, 0); |
2301 | } | 2310 | } |
2302 | 2311 | ||
2303 | DPRINTF(sc, ATH_DBG_CONFIG, "%s: Set HW RX filter: 0x%x\n", | 2312 | DPRINTF(sc, ATH_DBG_CONFIG, "Set HW RX filter: 0x%x\n", sc->rx_filter); |
2304 | __func__, sc->rx_filter); | ||
2305 | } | 2313 | } |
2306 | 2314 | ||
2307 | static void ath9k_sta_notify(struct ieee80211_hw *hw, | 2315 | static void ath9k_sta_notify(struct ieee80211_hw *hw, |
@@ -2341,20 +2349,14 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, | |||
2341 | qnum = ath_get_hal_qnum(queue, sc); | 2349 | qnum = ath_get_hal_qnum(queue, sc); |
2342 | 2350 | ||
2343 | DPRINTF(sc, ATH_DBG_CONFIG, | 2351 | DPRINTF(sc, ATH_DBG_CONFIG, |
2344 | "%s: Configure tx [queue/halq] [%d/%d], " | 2352 | "Configure tx [queue/halq] [%d/%d], " |
2345 | "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", | 2353 | "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", |
2346 | __func__, | 2354 | queue, qnum, params->aifs, params->cw_min, |
2347 | queue, | 2355 | params->cw_max, params->txop); |
2348 | qnum, | ||
2349 | params->aifs, | ||
2350 | params->cw_min, | ||
2351 | params->cw_max, | ||
2352 | params->txop); | ||
2353 | 2356 | ||
2354 | ret = ath_txq_update(sc, qnum, &qi); | 2357 | ret = ath_txq_update(sc, qnum, &qi); |
2355 | if (ret) | 2358 | if (ret) |
2356 | DPRINTF(sc, ATH_DBG_FATAL, | 2359 | DPRINTF(sc, ATH_DBG_FATAL, "TXQ Update failed\n"); |
2357 | "%s: TXQ Update failed\n", __func__); | ||
2358 | 2360 | ||
2359 | return ret; | 2361 | return ret; |
2360 | } | 2362 | } |
@@ -2368,7 +2370,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw, | |||
2368 | struct ath_softc *sc = hw->priv; | 2370 | struct ath_softc *sc = hw->priv; |
2369 | int ret = 0; | 2371 | int ret = 0; |
2370 | 2372 | ||
2371 | DPRINTF(sc, ATH_DBG_KEYCACHE, " %s: Set HW Key\n", __func__); | 2373 | DPRINTF(sc, ATH_DBG_KEYCACHE, "Set HW Key\n"); |
2372 | 2374 | ||
2373 | switch (cmd) { | 2375 | switch (cmd) { |
2374 | case SET_KEY: | 2376 | case SET_KEY: |
@@ -2401,8 +2403,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
2401 | struct ath_softc *sc = hw->priv; | 2403 | struct ath_softc *sc = hw->priv; |
2402 | 2404 | ||
2403 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { | 2405 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { |
2404 | DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed PREAMBLE %d\n", | 2406 | DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n", |
2405 | __func__, | ||
2406 | bss_conf->use_short_preamble); | 2407 | bss_conf->use_short_preamble); |
2407 | if (bss_conf->use_short_preamble) | 2408 | if (bss_conf->use_short_preamble) |
2408 | sc->sc_flags |= SC_OP_PREAMBLE_SHORT; | 2409 | sc->sc_flags |= SC_OP_PREAMBLE_SHORT; |
@@ -2411,8 +2412,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
2411 | } | 2412 | } |
2412 | 2413 | ||
2413 | if (changed & BSS_CHANGED_ERP_CTS_PROT) { | 2414 | if (changed & BSS_CHANGED_ERP_CTS_PROT) { |
2414 | DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed CTS PROT %d\n", | 2415 | DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n", |
2415 | __func__, | ||
2416 | bss_conf->use_cts_prot); | 2416 | bss_conf->use_cts_prot); |
2417 | if (bss_conf->use_cts_prot && | 2417 | if (bss_conf->use_cts_prot && |
2418 | hw->conf.channel->band != IEEE80211_BAND_5GHZ) | 2418 | hw->conf.channel->band != IEEE80211_BAND_5GHZ) |
@@ -2425,8 +2425,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
2425 | ath9k_ht_conf(sc, bss_conf); | 2425 | ath9k_ht_conf(sc, bss_conf); |
2426 | 2426 | ||
2427 | if (changed & BSS_CHANGED_ASSOC) { | 2427 | if (changed & BSS_CHANGED_ASSOC) { |
2428 | DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed ASSOC %d\n", | 2428 | DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", |
2429 | __func__, | ||
2430 | bss_conf->assoc); | 2429 | bss_conf->assoc); |
2431 | ath9k_bss_assoc_info(sc, vif, bss_conf); | 2430 | ath9k_bss_assoc_info(sc, vif, bss_conf); |
2432 | } | 2431 | } |
@@ -2470,8 +2469,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, | |||
2470 | ret = ath_tx_aggr_start(sc, sta, tid, ssn); | 2469 | ret = ath_tx_aggr_start(sc, sta, tid, ssn); |
2471 | if (ret < 0) | 2470 | if (ret < 0) |
2472 | DPRINTF(sc, ATH_DBG_FATAL, | 2471 | DPRINTF(sc, ATH_DBG_FATAL, |
2473 | "%s: Unable to start TX aggregation\n", | 2472 | "Unable to start TX aggregation\n"); |
2474 | __func__); | ||
2475 | else | 2473 | else |
2476 | ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid); | 2474 | ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid); |
2477 | break; | 2475 | break; |
@@ -2479,8 +2477,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, | |||
2479 | ret = ath_tx_aggr_stop(sc, sta, tid); | 2477 | ret = ath_tx_aggr_stop(sc, sta, tid); |
2480 | if (ret < 0) | 2478 | if (ret < 0) |
2481 | DPRINTF(sc, ATH_DBG_FATAL, | 2479 | DPRINTF(sc, ATH_DBG_FATAL, |
2482 | "%s: Unable to stop TX aggregation\n", | 2480 | "Unable to stop TX aggregation\n"); |
2483 | __func__); | ||
2484 | 2481 | ||
2485 | ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid); | 2482 | ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid); |
2486 | break; | 2483 | break; |
@@ -2488,8 +2485,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, | |||
2488 | ath_tx_aggr_resume(sc, sta, tid); | 2485 | ath_tx_aggr_resume(sc, sta, tid); |
2489 | break; | 2486 | break; |
2490 | default: | 2487 | default: |
2491 | DPRINTF(sc, ATH_DBG_FATAL, | 2488 | DPRINTF(sc, ATH_DBG_FATAL, "Unknown AMPDU action\n"); |
2492 | "%s: Unknown AMPDU action\n", __func__); | ||
2493 | } | 2489 | } |
2494 | 2490 | ||
2495 | return ret; | 2491 | return ret; |
@@ -2545,7 +2541,6 @@ static struct { | |||
2545 | /* | 2541 | /* |
2546 | * Return the MAC/BB name. "????" is returned if the MAC/BB is unknown. | 2542 | * Return the MAC/BB name. "????" is returned if the MAC/BB is unknown. |
2547 | */ | 2543 | */ |
2548 | |||
2549 | static const char * | 2544 | static const char * |
2550 | ath_mac_bb_name(u32 mac_bb_version) | 2545 | ath_mac_bb_name(u32 mac_bb_version) |
2551 | { | 2546 | { |
@@ -2563,7 +2558,6 @@ ath_mac_bb_name(u32 mac_bb_version) | |||
2563 | /* | 2558 | /* |
2564 | * Return the RF name. "????" is returned if the RF is unknown. | 2559 | * Return the RF name. "????" is returned if the RF is unknown. |
2565 | */ | 2560 | */ |
2566 | |||
2567 | static const char * | 2561 | static const char * |
2568 | ath_rf_name(u16 rf_version) | 2562 | ath_rf_name(u16 rf_version) |
2569 | { | 2563 | { |
@@ -2602,7 +2596,7 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2602 | 2596 | ||
2603 | if (ret) { | 2597 | if (ret) { |
2604 | printk(KERN_ERR "ath9k: 32-bit DMA consistent " | 2598 | printk(KERN_ERR "ath9k: 32-bit DMA consistent " |
2605 | "DMA enable faled\n"); | 2599 | "DMA enable failed\n"); |
2606 | goto bad; | 2600 | goto bad; |
2607 | } | 2601 | } |
2608 | 2602 | ||
@@ -2812,6 +2806,6 @@ module_init(init_ath_pci); | |||
2812 | static void __exit exit_ath_pci(void) | 2806 | static void __exit exit_ath_pci(void) |
2813 | { | 2807 | { |
2814 | pci_unregister_driver(&ath_pci_driver); | 2808 | pci_unregister_driver(&ath_pci_driver); |
2815 | printk(KERN_INFO "%s: driver unloaded\n", dev_info); | 2809 | printk(KERN_INFO "%s: Driver unloaded\n", dev_info); |
2816 | } | 2810 | } |
2817 | module_exit(exit_ath_pci); | 2811 | module_exit(exit_ath_pci); |
diff --git a/drivers/net/wireless/ath9k/phy.c b/drivers/net/wireless/ath9k/phy.c index 4f1c8bf8342b..766982a8196e 100644 --- a/drivers/net/wireless/ath9k/phy.c +++ b/drivers/net/wireless/ath9k/phy.c | |||
@@ -52,8 +52,7 @@ ath9k_hw_set_channel(struct ath_hal *ah, struct ath9k_channel *chan) | |||
52 | bModeSynth = 1; | 52 | bModeSynth = 1; |
53 | } else { | 53 | } else { |
54 | DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, | 54 | DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, |
55 | "%s: invalid channel %u MHz\n", __func__, | 55 | "Invalid channel %u MHz\n", freq); |
56 | freq); | ||
57 | return false; | 56 | return false; |
58 | } | 57 | } |
59 | 58 | ||
@@ -86,7 +85,7 @@ ath9k_hw_set_channel(struct ath_hal *ah, struct ath9k_channel *chan) | |||
86 | aModeRefSel = ath9k_hw_reverse_bits(1, 2); | 85 | aModeRefSel = ath9k_hw_reverse_bits(1, 2); |
87 | } else { | 86 | } else { |
88 | DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, | 87 | DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, |
89 | "%s: invalid channel %u MHz\n", __func__, freq); | 88 | "Invalid channel %u MHz\n", freq); |
90 | return false; | 89 | return false; |
91 | } | 90 | } |
92 | 91 | ||
@@ -348,8 +347,7 @@ bool ath9k_hw_init_rf(struct ath_hal *ah, int *status) | |||
348 | || ahp->ah_analogBank6TPCData == NULL | 347 | || ahp->ah_analogBank6TPCData == NULL |
349 | || ahp->ah_analogBank7Data == NULL) { | 348 | || ahp->ah_analogBank7Data == NULL) { |
350 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | 349 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, |
351 | "%s: cannot allocate RF banks\n", | 350 | "Cannot allocate RF banks\n"); |
352 | __func__); | ||
353 | *status = -ENOMEM; | 351 | *status = -ENOMEM; |
354 | return false; | 352 | return false; |
355 | } | 353 | } |
@@ -360,8 +358,7 @@ bool ath9k_hw_init_rf(struct ath_hal *ah, int *status) | |||
360 | ahp->ah_iniAddac.ia_columns), GFP_KERNEL); | 358 | ahp->ah_iniAddac.ia_columns), GFP_KERNEL); |
361 | if (ahp->ah_addac5416_21 == NULL) { | 359 | if (ahp->ah_addac5416_21 == NULL) { |
362 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | 360 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, |
363 | "%s: cannot allocate ah_addac5416_21\n", | 361 | "Cannot allocate ah_addac5416_21\n"); |
364 | __func__); | ||
365 | *status = -ENOMEM; | 362 | *status = -ENOMEM; |
366 | return false; | 363 | return false; |
367 | } | 364 | } |
@@ -371,8 +368,7 @@ bool ath9k_hw_init_rf(struct ath_hal *ah, int *status) | |||
371 | ahp->ah_iniBank6.ia_rows), GFP_KERNEL); | 368 | ahp->ah_iniBank6.ia_rows), GFP_KERNEL); |
372 | if (ahp->ah_bank6Temp == NULL) { | 369 | if (ahp->ah_bank6Temp == NULL) { |
373 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | 370 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, |
374 | "%s: cannot allocate ah_bank6Temp\n", | 371 | "Cannot allocate ah_bank6Temp\n"); |
375 | __func__); | ||
376 | *status = -ENOMEM; | 372 | *status = -ENOMEM; |
377 | return false; | 373 | return false; |
378 | } | 374 | } |
diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c index 93dfea897ff2..76acd2b75fcd 100644 --- a/drivers/net/wireless/ath9k/rc.c +++ b/drivers/net/wireless/ath9k/rc.c | |||
@@ -1304,6 +1304,38 @@ static void ath_rc_tx_status(struct ath_softc *sc, | |||
1304 | xretries, long_retry); | 1304 | xretries, long_retry); |
1305 | } | 1305 | } |
1306 | 1306 | ||
1307 | static struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc, | ||
1308 | enum ieee80211_band band, | ||
1309 | bool is_ht, bool is_cw_40) | ||
1310 | { | ||
1311 | int mode = 0; | ||
1312 | |||
1313 | switch(band) { | ||
1314 | case IEEE80211_BAND_2GHZ: | ||
1315 | mode = ATH9K_MODE_11G; | ||
1316 | if (is_ht) | ||
1317 | mode = ATH9K_MODE_11NG_HT20; | ||
1318 | if (is_cw_40) | ||
1319 | mode = ATH9K_MODE_11NG_HT40PLUS; | ||
1320 | break; | ||
1321 | case IEEE80211_BAND_5GHZ: | ||
1322 | mode = ATH9K_MODE_11A; | ||
1323 | if (is_ht) | ||
1324 | mode = ATH9K_MODE_11NA_HT20; | ||
1325 | if (is_cw_40) | ||
1326 | mode = ATH9K_MODE_11NA_HT40PLUS; | ||
1327 | break; | ||
1328 | default: | ||
1329 | DPRINTF(sc, ATH_DBG_CONFIG, "Invalid band\n"); | ||
1330 | return NULL; | ||
1331 | } | ||
1332 | |||
1333 | BUG_ON(mode >= ATH9K_MODE_MAX); | ||
1334 | |||
1335 | DPRINTF(sc, ATH_DBG_CONFIG, "Choosing rate table for mode: %d\n", mode); | ||
1336 | return sc->hw_rate_table[mode]; | ||
1337 | } | ||
1338 | |||
1307 | static void ath_rc_init(struct ath_softc *sc, | 1339 | static void ath_rc_init(struct ath_softc *sc, |
1308 | struct ath_rate_priv *ath_rc_priv, | 1340 | struct ath_rate_priv *ath_rc_priv, |
1309 | struct ieee80211_supported_band *sband, | 1341 | struct ieee80211_supported_band *sband, |
@@ -1314,16 +1346,25 @@ static void ath_rc_init(struct ath_softc *sc, | |||
1314 | u8 *ht_mcs = (u8 *)&ath_rc_priv->neg_ht_rates; | 1346 | u8 *ht_mcs = (u8 *)&ath_rc_priv->neg_ht_rates; |
1315 | u8 i, j, k, hi = 0, hthi = 0; | 1347 | u8 i, j, k, hi = 0, hthi = 0; |
1316 | 1348 | ||
1317 | rate_table = sc->hw_rate_table[sc->sc_curmode]; | 1349 | /* FIXME: Adhoc */ |
1350 | if ((sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION) || | ||
1351 | (sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC)) { | ||
1352 | bool is_cw_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40; | ||
1353 | rate_table = ath_choose_rate_table(sc, sband->band, | ||
1354 | sta->ht_cap.ht_supported, | ||
1355 | is_cw_40); | ||
1356 | } else if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) { | ||
1357 | /* sc_curmode would be set on init through config() */ | ||
1358 | rate_table = sc->hw_rate_table[sc->sc_curmode]; | ||
1359 | } | ||
1318 | 1360 | ||
1319 | if (sta->ht_cap.ht_supported) { | 1361 | if (!rate_table) { |
1320 | if (sband->band == IEEE80211_BAND_2GHZ) | 1362 | DPRINTF(sc, ATH_DBG_FATAL, "Rate table not initialized\n"); |
1321 | rate_table = sc->hw_rate_table[ATH9K_MODE_11NG_HT20]; | 1363 | return; |
1322 | else | 1364 | } |
1323 | rate_table = sc->hw_rate_table[ATH9K_MODE_11NA_HT20]; | ||
1324 | 1365 | ||
1366 | if (sta->ht_cap.ht_supported) { | ||
1325 | ath_rc_priv->ht_cap = (WLAN_RC_HT_FLAG | WLAN_RC_DS_FLAG); | 1367 | ath_rc_priv->ht_cap = (WLAN_RC_HT_FLAG | WLAN_RC_DS_FLAG); |
1326 | |||
1327 | if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) | 1368 | if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) |
1328 | ath_rc_priv->ht_cap |= WLAN_RC_40_FLAG; | 1369 | ath_rc_priv->ht_cap |= WLAN_RC_40_FLAG; |
1329 | } | 1370 | } |
@@ -1531,8 +1572,7 @@ static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp | |||
1531 | rate_priv = kzalloc(sizeof(struct ath_rate_priv), gfp); | 1572 | rate_priv = kzalloc(sizeof(struct ath_rate_priv), gfp); |
1532 | if (!rate_priv) { | 1573 | if (!rate_priv) { |
1533 | DPRINTF(sc, ATH_DBG_FATAL, | 1574 | DPRINTF(sc, ATH_DBG_FATAL, |
1534 | "%s: Unable to allocate private rc structure\n", | 1575 | "Unable to allocate private rc structure\n"); |
1535 | __func__); | ||
1536 | return NULL; | 1576 | return NULL; |
1537 | } | 1577 | } |
1538 | 1578 | ||
diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index e49e32356e92..7a455468823b 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c | |||
@@ -105,8 +105,7 @@ static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len) | |||
105 | skb_reserve(skb, sc->sc_cachelsz - off); | 105 | skb_reserve(skb, sc->sc_cachelsz - off); |
106 | } else { | 106 | } else { |
107 | DPRINTF(sc, ATH_DBG_FATAL, | 107 | DPRINTF(sc, ATH_DBG_FATAL, |
108 | "%s: skbuff alloc of size %u failed\n", | 108 | "skbuff alloc of size %u failed\n", len); |
109 | __func__, len); | ||
110 | return NULL; | 109 | return NULL; |
111 | } | 110 | } |
112 | 111 | ||
@@ -166,7 +165,7 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds, | |||
166 | * discard the frame. Enable this if you want to see | 165 | * discard the frame. Enable this if you want to see |
167 | * error frames in Monitor mode. | 166 | * error frames in Monitor mode. |
168 | */ | 167 | */ |
169 | if (sc->sc_ah->ah_opmode != ATH9K_M_MONITOR) | 168 | if (sc->sc_ah->ah_opmode != NL80211_IFTYPE_MONITOR) |
170 | goto rx_next; | 169 | goto rx_next; |
171 | } else if (ds->ds_rxstat.rs_status != 0) { | 170 | } else if (ds->ds_rxstat.rs_status != 0) { |
172 | if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC) | 171 | if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC) |
@@ -192,7 +191,7 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds, | |||
192 | * decryption and MIC failures. For monitor mode, | 191 | * decryption and MIC failures. For monitor mode, |
193 | * we also ignore the CRC error. | 192 | * we also ignore the CRC error. |
194 | */ | 193 | */ |
195 | if (sc->sc_ah->ah_opmode == ATH9K_M_MONITOR) { | 194 | if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_MONITOR) { |
196 | if (ds->ds_rxstat.rs_status & | 195 | if (ds->ds_rxstat.rs_status & |
197 | ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC | | 196 | ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC | |
198 | ATH9K_RXERR_CRC)) | 197 | ATH9K_RXERR_CRC)) |
@@ -263,11 +262,7 @@ static void ath_opmode_init(struct ath_softc *sc) | |||
263 | 262 | ||
264 | /* calculate and install multicast filter */ | 263 | /* calculate and install multicast filter */ |
265 | mfilt[0] = mfilt[1] = ~0; | 264 | mfilt[0] = mfilt[1] = ~0; |
266 | |||
267 | ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]); | 265 | ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]); |
268 | DPRINTF(sc, ATH_DBG_CONFIG , | ||
269 | "%s: RX filter 0x%x, MC filter %08x:%08x\n", | ||
270 | __func__, rfilt, mfilt[0], mfilt[1]); | ||
271 | } | 266 | } |
272 | 267 | ||
273 | int ath_rx_init(struct ath_softc *sc, int nbufs) | 268 | int ath_rx_init(struct ath_softc *sc, int nbufs) |
@@ -285,8 +280,8 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) | |||
285 | min(sc->sc_cachelsz, | 280 | min(sc->sc_cachelsz, |
286 | (u16)64)); | 281 | (u16)64)); |
287 | 282 | ||
288 | DPRINTF(sc, ATH_DBG_CONFIG, "%s: cachelsz %u rxbufsize %u\n", | 283 | DPRINTF(sc, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n", |
289 | __func__, sc->sc_cachelsz, sc->sc_rxbufsize); | 284 | sc->sc_cachelsz, sc->sc_rxbufsize); |
290 | 285 | ||
291 | /* Initialize rx descriptors */ | 286 | /* Initialize rx descriptors */ |
292 | 287 | ||
@@ -294,8 +289,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) | |||
294 | "rx", nbufs, 1); | 289 | "rx", nbufs, 1); |
295 | if (error != 0) { | 290 | if (error != 0) { |
296 | DPRINTF(sc, ATH_DBG_FATAL, | 291 | DPRINTF(sc, ATH_DBG_FATAL, |
297 | "%s: failed to allocate rx descriptors: %d\n", | 292 | "failed to allocate rx descriptors: %d\n", error); |
298 | __func__, error); | ||
299 | break; | 293 | break; |
300 | } | 294 | } |
301 | 295 | ||
@@ -310,6 +304,15 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) | |||
310 | bf->bf_buf_addr = pci_map_single(sc->pdev, skb->data, | 304 | bf->bf_buf_addr = pci_map_single(sc->pdev, skb->data, |
311 | sc->sc_rxbufsize, | 305 | sc->sc_rxbufsize, |
312 | PCI_DMA_FROMDEVICE); | 306 | PCI_DMA_FROMDEVICE); |
307 | if (unlikely(pci_dma_mapping_error(sc->pdev, | ||
308 | bf->bf_buf_addr))) { | ||
309 | dev_kfree_skb_any(skb); | ||
310 | bf->bf_mpdu = NULL; | ||
311 | DPRINTF(sc, ATH_DBG_CONFIG, | ||
312 | "pci_dma_mapping_error() on RX init\n"); | ||
313 | error = -ENOMEM; | ||
314 | break; | ||
315 | } | ||
313 | bf->bf_dmacontext = bf->bf_buf_addr; | 316 | bf->bf_dmacontext = bf->bf_buf_addr; |
314 | } | 317 | } |
315 | sc->sc_rxlink = NULL; | 318 | sc->sc_rxlink = NULL; |
@@ -367,25 +370,25 @@ u32 ath_calcrxfilter(struct ath_softc *sc) | |||
367 | | ATH9K_RX_FILTER_MCAST; | 370 | | ATH9K_RX_FILTER_MCAST; |
368 | 371 | ||
369 | /* If not a STA, enable processing of Probe Requests */ | 372 | /* If not a STA, enable processing of Probe Requests */ |
370 | if (sc->sc_ah->ah_opmode != ATH9K_M_STA) | 373 | if (sc->sc_ah->ah_opmode != NL80211_IFTYPE_STATION) |
371 | rfilt |= ATH9K_RX_FILTER_PROBEREQ; | 374 | rfilt |= ATH9K_RX_FILTER_PROBEREQ; |
372 | 375 | ||
373 | /* Can't set HOSTAP into promiscous mode */ | 376 | /* Can't set HOSTAP into promiscous mode */ |
374 | if (((sc->sc_ah->ah_opmode != ATH9K_M_HOSTAP) && | 377 | if (((sc->sc_ah->ah_opmode != NL80211_IFTYPE_AP) && |
375 | (sc->rx_filter & FIF_PROMISC_IN_BSS)) || | 378 | (sc->rx_filter & FIF_PROMISC_IN_BSS)) || |
376 | (sc->sc_ah->ah_opmode == ATH9K_M_MONITOR)) { | 379 | (sc->sc_ah->ah_opmode == NL80211_IFTYPE_MONITOR)) { |
377 | rfilt |= ATH9K_RX_FILTER_PROM; | 380 | rfilt |= ATH9K_RX_FILTER_PROM; |
378 | /* ??? To prevent from sending ACK */ | 381 | /* ??? To prevent from sending ACK */ |
379 | rfilt &= ~ATH9K_RX_FILTER_UCAST; | 382 | rfilt &= ~ATH9K_RX_FILTER_UCAST; |
380 | } | 383 | } |
381 | 384 | ||
382 | if (sc->sc_ah->ah_opmode == ATH9K_M_STA || | 385 | if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION || |
383 | sc->sc_ah->ah_opmode == ATH9K_M_IBSS) | 386 | sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC) |
384 | rfilt |= ATH9K_RX_FILTER_BEACON; | 387 | rfilt |= ATH9K_RX_FILTER_BEACON; |
385 | 388 | ||
386 | /* If in HOSTAP mode, want to enable reception of PSPOLL frames | 389 | /* If in HOSTAP mode, want to enable reception of PSPOLL frames |
387 | & beacon frames */ | 390 | & beacon frames */ |
388 | if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) | 391 | if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) |
389 | rfilt |= (ATH9K_RX_FILTER_BEACON | ATH9K_RX_FILTER_PSPOLL); | 392 | rfilt |= (ATH9K_RX_FILTER_BEACON | ATH9K_RX_FILTER_PSPOLL); |
390 | 393 | ||
391 | return rfilt; | 394 | return rfilt; |
@@ -595,6 +598,14 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) | |||
595 | bf->bf_buf_addr = pci_map_single(sc->pdev, requeue_skb->data, | 598 | bf->bf_buf_addr = pci_map_single(sc->pdev, requeue_skb->data, |
596 | sc->sc_rxbufsize, | 599 | sc->sc_rxbufsize, |
597 | PCI_DMA_FROMDEVICE); | 600 | PCI_DMA_FROMDEVICE); |
601 | if (unlikely(pci_dma_mapping_error(sc->pdev, | ||
602 | bf->bf_buf_addr))) { | ||
603 | dev_kfree_skb_any(requeue_skb); | ||
604 | bf->bf_mpdu = NULL; | ||
605 | DPRINTF(sc, ATH_DBG_CONFIG, | ||
606 | "pci_dma_mapping_error() on RX\n"); | ||
607 | break; | ||
608 | } | ||
598 | bf->bf_dmacontext = bf->bf_buf_addr; | 609 | bf->bf_dmacontext = bf->bf_buf_addr; |
599 | 610 | ||
600 | /* | 611 | /* |
diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c index 62e28887ccd3..64043e99facf 100644 --- a/drivers/net/wireless/ath9k/regd.c +++ b/drivers/net/wireless/ath9k/regd.c | |||
@@ -42,7 +42,7 @@ ath9k_regd_sort(void *a, u32 n, u32 size, ath_hal_cmp_t *cmp) | |||
42 | u8 *u = t - size; | 42 | u8 *u = t - size; |
43 | if (cmp(u, t) <= 0) | 43 | if (cmp(u, t) <= 0) |
44 | break; | 44 | break; |
45 | swap(u, t, size); | 45 | swap_array(u, t, size); |
46 | } | 46 | } |
47 | } | 47 | } |
48 | 48 | ||
@@ -78,8 +78,7 @@ static bool ath9k_regd_is_eeprom_valid(struct ath_hal *ah) | |||
78 | return true; | 78 | return true; |
79 | } | 79 | } |
80 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | 80 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, |
81 | "%s: invalid regulatory domain/country code 0x%x\n", | 81 | "invalid regulatory domain/country code 0x%x\n", rd); |
82 | __func__, rd); | ||
83 | return false; | 82 | return false; |
84 | } | 83 | } |
85 | 84 | ||
@@ -107,13 +106,12 @@ static bool ath9k_regd_is_ccode_valid(struct ath_hal *ah, | |||
107 | return true; | 106 | return true; |
108 | 107 | ||
109 | rd = ath9k_regd_get_eepromRD(ah); | 108 | rd = ath9k_regd_get_eepromRD(ah); |
110 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "%s: EEPROM regdomain 0x%x\n", | 109 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "EEPROM regdomain 0x%x\n", rd); |
111 | __func__, rd); | ||
112 | 110 | ||
113 | if (rd & COUNTRY_ERD_FLAG) { | 111 | if (rd & COUNTRY_ERD_FLAG) { |
114 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | 112 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, |
115 | "%s: EEPROM setting is country code %u\n", | 113 | "EEPROM setting is country code %u\n", |
116 | __func__, rd & ~COUNTRY_ERD_FLAG); | 114 | rd & ~COUNTRY_ERD_FLAG); |
117 | return cc == (rd & ~COUNTRY_ERD_FLAG); | 115 | return cc == (rd & ~COUNTRY_ERD_FLAG); |
118 | } | 116 | } |
119 | 117 | ||
@@ -290,8 +288,7 @@ ath9k_regd_get_wmode_regdomain(struct ath_hal *ah, int regDmn, | |||
290 | } | 288 | } |
291 | if (!found) { | 289 | if (!found) { |
292 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | 290 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, |
293 | "%s: Failed to find reg domain pair %u\n", | 291 | "Failed to find reg domain pair %u\n", regDmn); |
294 | __func__, regDmn); | ||
295 | return false; | 292 | return false; |
296 | } | 293 | } |
297 | if (!(channelFlag & CHANNEL_2GHZ)) { | 294 | if (!(channelFlag & CHANNEL_2GHZ)) { |
@@ -307,8 +304,7 @@ ath9k_regd_get_wmode_regdomain(struct ath_hal *ah, int regDmn, | |||
307 | found = ath9k_regd_is_valid_reg_domain(regDmn, rd); | 304 | found = ath9k_regd_is_valid_reg_domain(regDmn, rd); |
308 | if (!found) { | 305 | if (!found) { |
309 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | 306 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, |
310 | "%s: Failed to find unitary reg domain %u\n", | 307 | "Failed to find unitary reg domain %u\n", regDmn); |
311 | __func__, regDmn); | ||
312 | return false; | 308 | return false; |
313 | } else { | 309 | } else { |
314 | rd->pscan &= regPair->pscanMask; | 310 | rd->pscan &= regPair->pscanMask; |
@@ -430,30 +426,27 @@ ath9k_regd_add_channel(struct ath_hal *ah, | |||
430 | 426 | ||
431 | if (!(c_lo <= c && c <= c_hi)) { | 427 | if (!(c_lo <= c && c <= c_hi)) { |
432 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | 428 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, |
433 | "%s: c %u out of range [%u..%u]\n", | 429 | "c %u out of range [%u..%u]\n", |
434 | __func__, c, c_lo, c_hi); | 430 | c, c_lo, c_hi); |
435 | return false; | 431 | return false; |
436 | } | 432 | } |
437 | if ((fband->channelBW == CHANNEL_HALF_BW) && | 433 | if ((fband->channelBW == CHANNEL_HALF_BW) && |
438 | !(ah->ah_caps.hw_caps & ATH9K_HW_CAP_CHAN_HALFRATE)) { | 434 | !(ah->ah_caps.hw_caps & ATH9K_HW_CAP_CHAN_HALFRATE)) { |
439 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | 435 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, |
440 | "%s: Skipping %u half rate channel\n", | 436 | "Skipping %u half rate channel\n", c); |
441 | __func__, c); | ||
442 | return false; | 437 | return false; |
443 | } | 438 | } |
444 | 439 | ||
445 | if ((fband->channelBW == CHANNEL_QUARTER_BW) && | 440 | if ((fband->channelBW == CHANNEL_QUARTER_BW) && |
446 | !(ah->ah_caps.hw_caps & ATH9K_HW_CAP_CHAN_QUARTERRATE)) { | 441 | !(ah->ah_caps.hw_caps & ATH9K_HW_CAP_CHAN_QUARTERRATE)) { |
447 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | 442 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, |
448 | "%s: Skipping %u quarter rate channel\n", | 443 | "Skipping %u quarter rate channel\n", c); |
449 | __func__, c); | ||
450 | return false; | 444 | return false; |
451 | } | 445 | } |
452 | 446 | ||
453 | if (((c + fband->channelSep) / 2) > (maxChan + HALF_MAXCHANBW)) { | 447 | if (((c + fband->channelSep) / 2) > (maxChan + HALF_MAXCHANBW)) { |
454 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | 448 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, |
455 | "%s: c %u > maxChan %u\n", | 449 | "c %u > maxChan %u\n", c, maxChan); |
456 | __func__, c, maxChan); | ||
457 | return false; | 450 | return false; |
458 | } | 451 | } |
459 | 452 | ||
@@ -463,7 +456,7 @@ ath9k_regd_add_channel(struct ath_hal *ah, | |||
463 | return false; | 456 | return false; |
464 | } | 457 | } |
465 | 458 | ||
466 | if ((rd->flags & NO_HOSTAP) && (ah->ah_opmode == ATH9K_M_HOSTAP)) { | 459 | if ((rd->flags & NO_HOSTAP) && (ah->ah_opmode == NL80211_IFTYPE_AP)) { |
467 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | 460 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, |
468 | "Skipping HOSTAP channel\n"); | 461 | "Skipping HOSTAP channel\n"); |
469 | return false; | 462 | return false; |
@@ -606,8 +599,7 @@ static bool ath9k_regd_japan_check(struct ath_hal *ah, | |||
606 | } | 599 | } |
607 | 600 | ||
608 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | 601 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, |
609 | "%s: Skipping %d freq band\n", | 602 | "Skipping %d freq band\n", j_bandcheck[i].freqbandbit); |
610 | __func__, j_bandcheck[i].freqbandbit); | ||
611 | 603 | ||
612 | return skipband; | 604 | return skipband; |
613 | } | 605 | } |
@@ -632,20 +624,19 @@ ath9k_regd_init_channels(struct ath_hal *ah, | |||
632 | unsigned long *modes_avail; | 624 | unsigned long *modes_avail; |
633 | DECLARE_BITMAP(modes_allowed, ATH9K_MODE_MAX); | 625 | DECLARE_BITMAP(modes_allowed, ATH9K_MODE_MAX); |
634 | 626 | ||
635 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "%s: cc %u %s %s\n", | 627 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "cc %u %s %s\n", cc, |
636 | __func__, cc, | ||
637 | enableOutdoor ? "Enable outdoor" : "", | 628 | enableOutdoor ? "Enable outdoor" : "", |
638 | enableExtendedChannels ? "Enable ecm" : ""); | 629 | enableExtendedChannels ? "Enable ecm" : ""); |
639 | 630 | ||
640 | if (!ath9k_regd_is_ccode_valid(ah, cc)) { | 631 | if (!ath9k_regd_is_ccode_valid(ah, cc)) { |
641 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | 632 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, |
642 | "%s: invalid country code %d\n", __func__, cc); | 633 | "Invalid country code %d\n", cc); |
643 | return false; | 634 | return false; |
644 | } | 635 | } |
645 | 636 | ||
646 | if (!ath9k_regd_is_eeprom_valid(ah)) { | 637 | if (!ath9k_regd_is_eeprom_valid(ah)) { |
647 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | 638 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, |
648 | "%s: invalid EEPROM contents\n", __func__); | 639 | "Invalid EEPROM contents\n"); |
649 | return false; | 640 | return false; |
650 | } | 641 | } |
651 | 642 | ||
@@ -693,9 +684,9 @@ ath9k_regd_init_channels(struct ath_hal *ah, | |||
693 | ~CHANNEL_2GHZ, | 684 | ~CHANNEL_2GHZ, |
694 | &rd5GHz)) { | 685 | &rd5GHz)) { |
695 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | 686 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, |
696 | "%s: couldn't find unitary " | 687 | "Couldn't find unitary " |
697 | "5GHz reg domain for country %u\n", | 688 | "5GHz reg domain for country %u\n", |
698 | __func__, ah->ah_countryCode); | 689 | ah->ah_countryCode); |
699 | return false; | 690 | return false; |
700 | } | 691 | } |
701 | if (!ath9k_regd_get_wmode_regdomain(ah, | 692 | if (!ath9k_regd_get_wmode_regdomain(ah, |
@@ -703,9 +694,9 @@ ath9k_regd_init_channels(struct ath_hal *ah, | |||
703 | CHANNEL_2GHZ, | 694 | CHANNEL_2GHZ, |
704 | &rd2GHz)) { | 695 | &rd2GHz)) { |
705 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | 696 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, |
706 | "%s: couldn't find unitary 2GHz " | 697 | "Couldn't find unitary 2GHz " |
707 | "reg domain for country %u\n", | 698 | "reg domain for country %u\n", |
708 | __func__, ah->ah_countryCode); | 699 | ah->ah_countryCode); |
709 | return false; | 700 | return false; |
710 | } | 701 | } |
711 | 702 | ||
@@ -717,9 +708,9 @@ ath9k_regd_init_channels(struct ath_hal *ah, | |||
717 | ~CHANNEL_2GHZ, | 708 | ~CHANNEL_2GHZ, |
718 | &rd5GHz)) { | 709 | &rd5GHz)) { |
719 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | 710 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, |
720 | "%s: couldn't find unitary 5GHz " | 711 | "Couldn't find unitary 5GHz " |
721 | "reg domain for country %u\n", | 712 | "reg domain for country %u\n", |
722 | __func__, ah->ah_countryCode); | 713 | ah->ah_countryCode); |
723 | return false; | 714 | return false; |
724 | } | 715 | } |
725 | } | 716 | } |
@@ -749,15 +740,14 @@ ath9k_regd_init_channels(struct ath_hal *ah, | |||
749 | 740 | ||
750 | if (!test_bit(cm->mode, modes_avail)) { | 741 | if (!test_bit(cm->mode, modes_avail)) { |
751 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | 742 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, |
752 | "%s: !avail mode %d flags 0x%x\n", | 743 | "!avail mode %d flags 0x%x\n", |
753 | __func__, cm->mode, cm->flags); | 744 | cm->mode, cm->flags); |
754 | continue; | 745 | continue; |
755 | } | 746 | } |
756 | if (!ath9k_get_channel_edges(ah, cm->flags, &c_lo, &c_hi)) { | 747 | if (!ath9k_get_channel_edges(ah, cm->flags, &c_lo, &c_hi)) { |
757 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | 748 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, |
758 | "%s: channels 0x%x not supported " | 749 | "channels 0x%x not supported " |
759 | "by hardware\n", | 750 | "by hardware\n", cm->flags); |
760 | __func__, cm->flags); | ||
761 | continue; | 751 | continue; |
762 | } | 752 | } |
763 | 753 | ||
@@ -788,8 +778,7 @@ ath9k_regd_init_channels(struct ath_hal *ah, | |||
788 | break; | 778 | break; |
789 | default: | 779 | default: |
790 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | 780 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, |
791 | "%s: Unknown HAL mode 0x%x\n", __func__, | 781 | "Unknown HAL mode 0x%x\n", cm->mode); |
792 | cm->mode); | ||
793 | continue; | 782 | continue; |
794 | } | 783 | } |
795 | 784 | ||
@@ -841,9 +830,8 @@ ath9k_regd_init_channels(struct ath_hal *ah, | |||
841 | if (next >= maxchans) { | 830 | if (next >= maxchans) { |
842 | DPRINTF(ah->ah_sc, | 831 | DPRINTF(ah->ah_sc, |
843 | ATH_DBG_REGULATORY, | 832 | ATH_DBG_REGULATORY, |
844 | "%s: too many channels " | 833 | "too many channels " |
845 | "for channel table\n", | 834 | "for channel table\n"); |
846 | __func__); | ||
847 | goto done; | 835 | goto done; |
848 | } | 836 | } |
849 | if (ath9k_regd_add_channel(ah, | 837 | if (ath9k_regd_add_channel(ah, |
@@ -869,9 +857,8 @@ done: | |||
869 | 857 | ||
870 | if (next > ARRAY_SIZE(ah->ah_channels)) { | 858 | if (next > ARRAY_SIZE(ah->ah_channels)) { |
871 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | 859 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, |
872 | "%s: too many channels %u; truncating to %u\n", | 860 | "too many channels %u; truncating to %u\n", |
873 | __func__, next, | 861 | next, (int) ARRAY_SIZE(ah->ah_channels)); |
874 | (int) ARRAY_SIZE(ah->ah_channels)); | ||
875 | next = ARRAY_SIZE(ah->ah_channels); | 862 | next = ARRAY_SIZE(ah->ah_channels); |
876 | } | 863 | } |
877 | #ifdef ATH_NF_PER_CHAN | 864 | #ifdef ATH_NF_PER_CHAN |
@@ -919,7 +906,7 @@ ath9k_regd_check_channel(struct ath_hal *ah, | |||
919 | int n, lim; | 906 | int n, lim; |
920 | 907 | ||
921 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | 908 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, |
922 | "%s: channel %u/0x%x (0x%x) requested\n", __func__, | 909 | "channel %u/0x%x (0x%x) requested\n", |
923 | c->channel, c->channelFlags, flags); | 910 | c->channel, c->channelFlags, flags); |
924 | 911 | ||
925 | cc = ah->ah_curchan; | 912 | cc = ah->ah_curchan; |
@@ -950,15 +937,15 @@ ath9k_regd_check_channel(struct ath_hal *ah, | |||
950 | d = flags - (cc->channelFlags & CHAN_FLAGS); | 937 | d = flags - (cc->channelFlags & CHAN_FLAGS); |
951 | } | 938 | } |
952 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | 939 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, |
953 | "%s: channel %u/0x%x d %d\n", __func__, | 940 | "channel %u/0x%x d %d\n", |
954 | cc->channel, cc->channelFlags, d); | 941 | cc->channel, cc->channelFlags, d); |
955 | if (d > 0) { | 942 | if (d > 0) { |
956 | base = cc + 1; | 943 | base = cc + 1; |
957 | lim--; | 944 | lim--; |
958 | } | 945 | } |
959 | } | 946 | } |
960 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "%s: no match for %u/0x%x\n", | 947 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "no match for %u/0x%x\n", |
961 | __func__, c->channel, c->channelFlags); | 948 | c->channel, c->channelFlags); |
962 | return NULL; | 949 | return NULL; |
963 | } | 950 | } |
964 | 951 | ||
diff --git a/drivers/net/wireless/ath9k/regd.h b/drivers/net/wireless/ath9k/regd.h index 0ecd344fbd98..512d990aa7ea 100644 --- a/drivers/net/wireless/ath9k/regd.h +++ b/drivers/net/wireless/ath9k/regd.h | |||
@@ -125,7 +125,7 @@ | |||
125 | 125 | ||
126 | #define CHAN_FLAGS (CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER) | 126 | #define CHAN_FLAGS (CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER) |
127 | 127 | ||
128 | #define swap(_a, _b, _size) { \ | 128 | #define swap_array(_a, _b, _size) { \ |
129 | u8 *s = _b; \ | 129 | u8 *s = _b; \ |
130 | int i = _size; \ | 130 | int i = _size; \ |
131 | do { \ | 131 | do { \ |
diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index 413fbdd38ab6..9de27c681b86 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c | |||
@@ -83,18 +83,16 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, | |||
83 | txq->axq_linkbuf = list_entry(txq->axq_q.prev, struct ath_buf, list); | 83 | txq->axq_linkbuf = list_entry(txq->axq_q.prev, struct ath_buf, list); |
84 | 84 | ||
85 | DPRINTF(sc, ATH_DBG_QUEUE, | 85 | DPRINTF(sc, ATH_DBG_QUEUE, |
86 | "%s: txq depth = %d\n", __func__, txq->axq_depth); | 86 | "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth); |
87 | 87 | ||
88 | if (txq->axq_link == NULL) { | 88 | if (txq->axq_link == NULL) { |
89 | ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr); | 89 | ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr); |
90 | DPRINTF(sc, ATH_DBG_XMIT, | 90 | DPRINTF(sc, ATH_DBG_XMIT, |
91 | "%s: TXDP[%u] = %llx (%p)\n", | 91 | "TXDP[%u] = %llx (%p)\n", |
92 | __func__, txq->axq_qnum, | 92 | txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc); |
93 | ito64(bf->bf_daddr), bf->bf_desc); | ||
94 | } else { | 93 | } else { |
95 | *txq->axq_link = bf->bf_daddr; | 94 | *txq->axq_link = bf->bf_daddr; |
96 | DPRINTF(sc, ATH_DBG_XMIT, "%s: link[%u] (%p)=%llx (%p)\n", | 95 | DPRINTF(sc, ATH_DBG_XMIT, "link[%u] (%p)=%llx (%p)\n", |
97 | __func__, | ||
98 | txq->axq_qnum, txq->axq_link, | 96 | txq->axq_qnum, txq->axq_link, |
99 | ito64(bf->bf_daddr), bf->bf_desc); | 97 | ito64(bf->bf_daddr), bf->bf_desc); |
100 | } | 98 | } |
@@ -109,8 +107,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
109 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 107 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
110 | struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | 108 | struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info); |
111 | 109 | ||
112 | DPRINTF(sc, ATH_DBG_XMIT, | 110 | DPRINTF(sc, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); |
113 | "%s: TX complete: skb: %p\n", __func__, skb); | ||
114 | 111 | ||
115 | if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK || | 112 | if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK || |
116 | tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) { | 113 | tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) { |
@@ -763,7 +760,8 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc, | |||
763 | * when perform internal reset in this routine. | 760 | * when perform internal reset in this routine. |
764 | * Only enable reset in STA mode for now. | 761 | * Only enable reset in STA mode for now. |
765 | */ | 762 | */ |
766 | if (sc->sc_ah->ah_opmode == ATH9K_M_STA) | 763 | if (sc->sc_ah->ah_opmode == |
764 | NL80211_IFTYPE_STATION) | ||
767 | needreset = 1; | 765 | needreset = 1; |
768 | } | 766 | } |
769 | } else { | 767 | } else { |
@@ -983,8 +981,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
983 | int txok, nbad = 0; | 981 | int txok, nbad = 0; |
984 | int status; | 982 | int status; |
985 | 983 | ||
986 | DPRINTF(sc, ATH_DBG_QUEUE, | 984 | DPRINTF(sc, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n", |
987 | "%s: tx queue %d (%x), link %p\n", __func__, | ||
988 | txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum), | 985 | txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum), |
989 | txq->axq_link); | 986 | txq->axq_link); |
990 | 987 | ||
@@ -1116,9 +1113,9 @@ static void ath_tx_stopdma(struct ath_softc *sc, struct ath_txq *txq) | |||
1116 | struct ath_hal *ah = sc->sc_ah; | 1113 | struct ath_hal *ah = sc->sc_ah; |
1117 | 1114 | ||
1118 | (void) ath9k_hw_stoptxdma(ah, txq->axq_qnum); | 1115 | (void) ath9k_hw_stoptxdma(ah, txq->axq_qnum); |
1119 | DPRINTF(sc, ATH_DBG_XMIT, "%s: tx queue [%u] %x, link %p\n", | 1116 | DPRINTF(sc, ATH_DBG_XMIT, "tx queue [%u] %x, link %p\n", |
1120 | __func__, txq->axq_qnum, | 1117 | txq->axq_qnum, ath9k_hw_gettxbuf(ah, txq->axq_qnum), |
1121 | ath9k_hw_gettxbuf(ah, txq->axq_qnum), txq->axq_link); | 1118 | txq->axq_link); |
1122 | } | 1119 | } |
1123 | 1120 | ||
1124 | /* Drain only the data queues */ | 1121 | /* Drain only the data queues */ |
@@ -1142,8 +1139,7 @@ static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx) | |||
1142 | 1139 | ||
1143 | if (npend) { | 1140 | if (npend) { |
1144 | /* TxDMA not stopped, reset the hal */ | 1141 | /* TxDMA not stopped, reset the hal */ |
1145 | DPRINTF(sc, ATH_DBG_XMIT, | 1142 | DPRINTF(sc, ATH_DBG_XMIT, "Unable to stop TxDMA. Reset HAL!\n"); |
1146 | "%s: Unable to stop TxDMA. Reset HAL!\n", __func__); | ||
1147 | 1143 | ||
1148 | spin_lock_bh(&sc->sc_resetlock); | 1144 | spin_lock_bh(&sc->sc_resetlock); |
1149 | if (!ath9k_hw_reset(ah, | 1145 | if (!ath9k_hw_reset(ah, |
@@ -1153,8 +1149,7 @@ static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx) | |||
1153 | sc->sc_ht_extprotspacing, true, &status)) { | 1149 | sc->sc_ht_extprotspacing, true, &status)) { |
1154 | 1150 | ||
1155 | DPRINTF(sc, ATH_DBG_FATAL, | 1151 | DPRINTF(sc, ATH_DBG_FATAL, |
1156 | "%s: unable to reset hardware; hal status %u\n", | 1152 | "Unable to reset hardware; hal status %u\n", |
1157 | __func__, | ||
1158 | status); | 1153 | status); |
1159 | } | 1154 | } |
1160 | spin_unlock_bh(&sc->sc_resetlock); | 1155 | spin_unlock_bh(&sc->sc_resetlock); |
@@ -1194,7 +1189,6 @@ static void ath_tx_addto_baw(struct ath_softc *sc, | |||
1194 | * Function to send an A-MPDU | 1189 | * Function to send an A-MPDU |
1195 | * NB: must be called with txq lock held | 1190 | * NB: must be called with txq lock held |
1196 | */ | 1191 | */ |
1197 | |||
1198 | static int ath_tx_send_ampdu(struct ath_softc *sc, | 1192 | static int ath_tx_send_ampdu(struct ath_softc *sc, |
1199 | struct ath_atx_tid *tid, | 1193 | struct ath_atx_tid *tid, |
1200 | struct list_head *bf_head, | 1194 | struct list_head *bf_head, |
@@ -1242,7 +1236,6 @@ static int ath_tx_send_ampdu(struct ath_softc *sc, | |||
1242 | * looks up the rate | 1236 | * looks up the rate |
1243 | * returns aggr limit based on lowest of the rates | 1237 | * returns aggr limit based on lowest of the rates |
1244 | */ | 1238 | */ |
1245 | |||
1246 | static u32 ath_lookup_rate(struct ath_softc *sc, | 1239 | static u32 ath_lookup_rate(struct ath_softc *sc, |
1247 | struct ath_buf *bf, | 1240 | struct ath_buf *bf, |
1248 | struct ath_atx_tid *tid) | 1241 | struct ath_atx_tid *tid) |
@@ -1310,7 +1303,6 @@ static u32 ath_lookup_rate(struct ath_softc *sc, | |||
1310 | * meet the minimum required mpdudensity. | 1303 | * meet the minimum required mpdudensity. |
1311 | * caller should make sure that the rate is HT rate . | 1304 | * caller should make sure that the rate is HT rate . |
1312 | */ | 1305 | */ |
1313 | |||
1314 | static int ath_compute_num_delims(struct ath_softc *sc, | 1306 | static int ath_compute_num_delims(struct ath_softc *sc, |
1315 | struct ath_atx_tid *tid, | 1307 | struct ath_atx_tid *tid, |
1316 | struct ath_buf *bf, | 1308 | struct ath_buf *bf, |
@@ -1382,7 +1374,6 @@ static int ath_compute_num_delims(struct ath_softc *sc, | |||
1382 | * For aggregation from software buffer queue. | 1374 | * For aggregation from software buffer queue. |
1383 | * NB: must be called with txq lock held | 1375 | * NB: must be called with txq lock held |
1384 | */ | 1376 | */ |
1385 | |||
1386 | static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, | 1377 | static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, |
1387 | struct ath_atx_tid *tid, | 1378 | struct ath_atx_tid *tid, |
1388 | struct list_head *bf_q, | 1379 | struct list_head *bf_q, |
@@ -1505,7 +1496,6 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, | |||
1505 | * process pending frames possibly doing a-mpdu aggregation | 1496 | * process pending frames possibly doing a-mpdu aggregation |
1506 | * NB: must be called with txq lock held | 1497 | * NB: must be called with txq lock held |
1507 | */ | 1498 | */ |
1508 | |||
1509 | static void ath_tx_sched_aggr(struct ath_softc *sc, | 1499 | static void ath_tx_sched_aggr(struct ath_softc *sc, |
1510 | struct ath_txq *txq, struct ath_atx_tid *tid) | 1500 | struct ath_txq *txq, struct ath_atx_tid *tid) |
1511 | { | 1501 | { |
@@ -1635,7 +1625,6 @@ static void ath_tid_drain(struct ath_softc *sc, | |||
1635 | * Drain all pending buffers | 1625 | * Drain all pending buffers |
1636 | * NB: must be called with txq lock held | 1626 | * NB: must be called with txq lock held |
1637 | */ | 1627 | */ |
1638 | |||
1639 | static void ath_txq_drain_pending_buffers(struct ath_softc *sc, | 1628 | static void ath_txq_drain_pending_buffers(struct ath_softc *sc, |
1640 | struct ath_txq *txq) | 1629 | struct ath_txq *txq) |
1641 | { | 1630 | { |
@@ -1653,7 +1642,7 @@ static void ath_txq_drain_pending_buffers(struct ath_softc *sc, | |||
1653 | } | 1642 | } |
1654 | } | 1643 | } |
1655 | 1644 | ||
1656 | static void ath_tx_setup_buffer(struct ath_softc *sc, struct ath_buf *bf, | 1645 | static int ath_tx_setup_buffer(struct ath_softc *sc, struct ath_buf *bf, |
1657 | struct sk_buff *skb, | 1646 | struct sk_buff *skb, |
1658 | struct ath_tx_control *txctl) | 1647 | struct ath_tx_control *txctl) |
1659 | { | 1648 | { |
@@ -1663,7 +1652,9 @@ static void ath_tx_setup_buffer(struct ath_softc *sc, struct ath_buf *bf, | |||
1663 | int hdrlen; | 1652 | int hdrlen; |
1664 | __le16 fc; | 1653 | __le16 fc; |
1665 | 1654 | ||
1666 | tx_info_priv = kzalloc(sizeof(*tx_info_priv), GFP_KERNEL); | 1655 | tx_info_priv = kzalloc(sizeof(*tx_info_priv), GFP_ATOMIC); |
1656 | if (unlikely(!tx_info_priv)) | ||
1657 | return -ENOMEM; | ||
1667 | tx_info->rate_driver_data[0] = tx_info_priv; | 1658 | tx_info->rate_driver_data[0] = tx_info_priv; |
1668 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 1659 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); |
1669 | fc = hdr->frame_control; | 1660 | fc = hdr->frame_control; |
@@ -1712,9 +1703,18 @@ static void ath_tx_setup_buffer(struct ath_softc *sc, struct ath_buf *bf, | |||
1712 | /* DMA setup */ | 1703 | /* DMA setup */ |
1713 | 1704 | ||
1714 | bf->bf_mpdu = skb; | 1705 | bf->bf_mpdu = skb; |
1706 | |||
1715 | bf->bf_dmacontext = pci_map_single(sc->pdev, skb->data, | 1707 | bf->bf_dmacontext = pci_map_single(sc->pdev, skb->data, |
1716 | skb->len, PCI_DMA_TODEVICE); | 1708 | skb->len, PCI_DMA_TODEVICE); |
1709 | if (unlikely(pci_dma_mapping_error(sc->pdev, bf->bf_dmacontext))) { | ||
1710 | bf->bf_mpdu = NULL; | ||
1711 | DPRINTF(sc, ATH_DBG_CONFIG, | ||
1712 | "pci_dma_mapping_error() on TX\n"); | ||
1713 | return -ENOMEM; | ||
1714 | } | ||
1715 | |||
1717 | bf->bf_buf_addr = bf->bf_dmacontext; | 1716 | bf->bf_buf_addr = bf->bf_dmacontext; |
1717 | return 0; | ||
1718 | } | 1718 | } |
1719 | 1719 | ||
1720 | /* FIXME: tx power */ | 1720 | /* FIXME: tx power */ |
@@ -1786,21 +1786,46 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, | |||
1786 | spin_unlock_bh(&txctl->txq->axq_lock); | 1786 | spin_unlock_bh(&txctl->txq->axq_lock); |
1787 | } | 1787 | } |
1788 | 1788 | ||
1789 | /* Upon failure caller should free skb */ | ||
1789 | int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb, | 1790 | int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb, |
1790 | struct ath_tx_control *txctl) | 1791 | struct ath_tx_control *txctl) |
1791 | { | 1792 | { |
1792 | struct ath_buf *bf; | 1793 | struct ath_buf *bf; |
1794 | int r; | ||
1793 | 1795 | ||
1794 | /* Check if a tx buffer is available */ | 1796 | /* Check if a tx buffer is available */ |
1795 | 1797 | ||
1796 | bf = ath_tx_get_buffer(sc); | 1798 | bf = ath_tx_get_buffer(sc); |
1797 | if (!bf) { | 1799 | if (!bf) { |
1798 | DPRINTF(sc, ATH_DBG_XMIT, "%s: TX buffers are full\n", | 1800 | DPRINTF(sc, ATH_DBG_XMIT, "TX buffers are full\n"); |
1799 | __func__); | ||
1800 | return -1; | 1801 | return -1; |
1801 | } | 1802 | } |
1802 | 1803 | ||
1803 | ath_tx_setup_buffer(sc, bf, skb, txctl); | 1804 | r = ath_tx_setup_buffer(sc, bf, skb, txctl); |
1805 | if (unlikely(r)) { | ||
1806 | struct ath_txq *txq = txctl->txq; | ||
1807 | |||
1808 | DPRINTF(sc, ATH_DBG_FATAL, "TX mem alloc failure\n"); | ||
1809 | |||
1810 | /* upon ath_tx_processq() this TX queue will be resumed, we | ||
1811 | * guarantee this will happen by knowing beforehand that | ||
1812 | * we will at least have to run TX completionon one buffer | ||
1813 | * on the queue */ | ||
1814 | spin_lock_bh(&txq->axq_lock); | ||
1815 | if (ath_txq_depth(sc, txq->axq_qnum) > 1) { | ||
1816 | ieee80211_stop_queue(sc->hw, | ||
1817 | skb_get_queue_mapping(skb)); | ||
1818 | txq->stopped = 1; | ||
1819 | } | ||
1820 | spin_unlock_bh(&txq->axq_lock); | ||
1821 | |||
1822 | spin_lock_bh(&sc->sc_txbuflock); | ||
1823 | list_add_tail(&bf->list, &sc->sc_txbuf); | ||
1824 | spin_unlock_bh(&sc->sc_txbuflock); | ||
1825 | |||
1826 | return r; | ||
1827 | } | ||
1828 | |||
1804 | ath_tx_start_dma(sc, bf, txctl); | 1829 | ath_tx_start_dma(sc, bf, txctl); |
1805 | 1830 | ||
1806 | return 0; | 1831 | return 0; |
@@ -1820,8 +1845,8 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) | |||
1820 | "tx", nbufs, 1); | 1845 | "tx", nbufs, 1); |
1821 | if (error != 0) { | 1846 | if (error != 0) { |
1822 | DPRINTF(sc, ATH_DBG_FATAL, | 1847 | DPRINTF(sc, ATH_DBG_FATAL, |
1823 | "%s: failed to allocate tx descriptors: %d\n", | 1848 | "Failed to allocate tx descriptors: %d\n", |
1824 | __func__, error); | 1849 | error); |
1825 | break; | 1850 | break; |
1826 | } | 1851 | } |
1827 | 1852 | ||
@@ -1830,9 +1855,8 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) | |||
1830 | "beacon", ATH_BCBUF, 1); | 1855 | "beacon", ATH_BCBUF, 1); |
1831 | if (error != 0) { | 1856 | if (error != 0) { |
1832 | DPRINTF(sc, ATH_DBG_FATAL, | 1857 | DPRINTF(sc, ATH_DBG_FATAL, |
1833 | "%s: failed to allocate " | 1858 | "Failed to allocate beacon descriptors: %d\n", |
1834 | "beacon descripotrs: %d\n", | 1859 | error); |
1835 | __func__, error); | ||
1836 | break; | 1860 | break; |
1837 | } | 1861 | } |
1838 | 1862 | ||
@@ -1904,8 +1928,8 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) | |||
1904 | } | 1928 | } |
1905 | if (qnum >= ARRAY_SIZE(sc->sc_txq)) { | 1929 | if (qnum >= ARRAY_SIZE(sc->sc_txq)) { |
1906 | DPRINTF(sc, ATH_DBG_FATAL, | 1930 | DPRINTF(sc, ATH_DBG_FATAL, |
1907 | "%s: hal qnum %u out of range, max %u!\n", | 1931 | "qnum %u out of range, max %u!\n", |
1908 | __func__, qnum, (unsigned int)ARRAY_SIZE(sc->sc_txq)); | 1932 | qnum, (unsigned int)ARRAY_SIZE(sc->sc_txq)); |
1909 | ath9k_hw_releasetxqueue(ah, qnum); | 1933 | ath9k_hw_releasetxqueue(ah, qnum); |
1910 | return NULL; | 1934 | return NULL; |
1911 | } | 1935 | } |
@@ -1950,8 +1974,8 @@ int ath_tx_setup(struct ath_softc *sc, int haltype) | |||
1950 | 1974 | ||
1951 | if (haltype >= ARRAY_SIZE(sc->sc_haltype2q)) { | 1975 | if (haltype >= ARRAY_SIZE(sc->sc_haltype2q)) { |
1952 | DPRINTF(sc, ATH_DBG_FATAL, | 1976 | DPRINTF(sc, ATH_DBG_FATAL, |
1953 | "%s: HAL AC %u out of range, max %zu!\n", | 1977 | "HAL AC %u out of range, max %zu!\n", |
1954 | __func__, haltype, ARRAY_SIZE(sc->sc_haltype2q)); | 1978 | haltype, ARRAY_SIZE(sc->sc_haltype2q)); |
1955 | return 0; | 1979 | return 0; |
1956 | } | 1980 | } |
1957 | txq = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, haltype); | 1981 | txq = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, haltype); |
@@ -1970,8 +1994,7 @@ int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype) | |||
1970 | case ATH9K_TX_QUEUE_DATA: | 1994 | case ATH9K_TX_QUEUE_DATA: |
1971 | if (haltype >= ARRAY_SIZE(sc->sc_haltype2q)) { | 1995 | if (haltype >= ARRAY_SIZE(sc->sc_haltype2q)) { |
1972 | DPRINTF(sc, ATH_DBG_FATAL, | 1996 | DPRINTF(sc, ATH_DBG_FATAL, |
1973 | "%s: HAL AC %u out of range, max %zu!\n", | 1997 | "HAL AC %u out of range, max %zu!\n", |
1974 | __func__, | ||
1975 | haltype, ARRAY_SIZE(sc->sc_haltype2q)); | 1998 | haltype, ARRAY_SIZE(sc->sc_haltype2q)); |
1976 | return -1; | 1999 | return -1; |
1977 | } | 2000 | } |
@@ -2004,8 +2027,8 @@ struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb) | |||
2004 | /* Try to avoid running out of descriptors */ | 2027 | /* Try to avoid running out of descriptors */ |
2005 | if (txq->axq_depth >= (ATH_TXBUF - 20)) { | 2028 | if (txq->axq_depth >= (ATH_TXBUF - 20)) { |
2006 | DPRINTF(sc, ATH_DBG_FATAL, | 2029 | DPRINTF(sc, ATH_DBG_FATAL, |
2007 | "%s: TX queue: %d is full, depth: %d\n", | 2030 | "TX queue: %d is full, depth: %d\n", |
2008 | __func__, qnum, txq->axq_depth); | 2031 | qnum, txq->axq_depth); |
2009 | ieee80211_stop_queue(sc->hw, skb_get_queue_mapping(skb)); | 2032 | ieee80211_stop_queue(sc->hw, skb_get_queue_mapping(skb)); |
2010 | txq->stopped = 1; | 2033 | txq->stopped = 1; |
2011 | spin_unlock_bh(&txq->axq_lock); | 2034 | spin_unlock_bh(&txq->axq_lock); |
@@ -2047,8 +2070,7 @@ int ath_txq_update(struct ath_softc *sc, int qnum, | |||
2047 | 2070 | ||
2048 | if (!ath9k_hw_set_txq_props(ah, qnum, &qi)) { | 2071 | if (!ath9k_hw_set_txq_props(ah, qnum, &qi)) { |
2049 | DPRINTF(sc, ATH_DBG_FATAL, | 2072 | DPRINTF(sc, ATH_DBG_FATAL, |
2050 | "%s: unable to update hardware queue %u!\n", | 2073 | "Unable to update hardware queue %u!\n", qnum); |
2051 | __func__, qnum); | ||
2052 | error = -EIO; | 2074 | error = -EIO; |
2053 | } else { | 2075 | } else { |
2054 | ath9k_hw_resettxqueue(ah, qnum); /* push to h/w */ | 2076 | ath9k_hw_resettxqueue(ah, qnum); /* push to h/w */ |
@@ -2167,7 +2189,7 @@ void ath_draintxq(struct ath_softc *sc, bool retry_tx) | |||
2167 | * we go to INIT state */ | 2189 | * we go to INIT state */ |
2168 | if (!(sc->sc_flags & SC_OP_INVALID)) { | 2190 | if (!(sc->sc_flags & SC_OP_INVALID)) { |
2169 | (void) ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq); | 2191 | (void) ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq); |
2170 | DPRINTF(sc, ATH_DBG_XMIT, "%s: beacon queue %x\n", __func__, | 2192 | DPRINTF(sc, ATH_DBG_XMIT, "beacon queue %x\n", |
2171 | ath9k_hw_gettxbuf(sc->sc_ah, sc->sc_bhalq)); | 2193 | ath9k_hw_gettxbuf(sc->sc_ah, sc->sc_bhalq)); |
2172 | } | 2194 | } |
2173 | 2195 | ||
@@ -2267,8 +2289,6 @@ void ath_tx_aggr_teardown(struct ath_softc *sc, struct ath_node *an, u8 tid) | |||
2267 | struct list_head bf_head; | 2289 | struct list_head bf_head; |
2268 | INIT_LIST_HEAD(&bf_head); | 2290 | INIT_LIST_HEAD(&bf_head); |
2269 | 2291 | ||
2270 | DPRINTF(sc, ATH_DBG_AGGR, "%s: teardown TX aggregation\n", __func__); | ||
2271 | |||
2272 | if (txtid->state & AGGR_CLEANUP) /* cleanup is in progress */ | 2292 | if (txtid->state & AGGR_CLEANUP) /* cleanup is in progress */ |
2273 | return; | 2293 | return; |
2274 | 2294 | ||
@@ -2501,8 +2521,7 @@ void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb) | |||
2501 | if (hdrlen & 3) { | 2521 | if (hdrlen & 3) { |
2502 | padsize = hdrlen % 4; | 2522 | padsize = hdrlen % 4; |
2503 | if (skb_headroom(skb) < padsize) { | 2523 | if (skb_headroom(skb) < padsize) { |
2504 | DPRINTF(sc, ATH_DBG_XMIT, "%s: TX CABQ padding " | 2524 | DPRINTF(sc, ATH_DBG_XMIT, "TX CABQ padding failed\n"); |
2505 | "failed\n", __func__); | ||
2506 | dev_kfree_skb_any(skb); | 2525 | dev_kfree_skb_any(skb); |
2507 | return; | 2526 | return; |
2508 | } | 2527 | } |
@@ -2512,12 +2531,10 @@ void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb) | |||
2512 | 2531 | ||
2513 | txctl.txq = sc->sc_cabq; | 2532 | txctl.txq = sc->sc_cabq; |
2514 | 2533 | ||
2515 | DPRINTF(sc, ATH_DBG_XMIT, "%s: transmitting CABQ packet, skb: %p\n", | 2534 | DPRINTF(sc, ATH_DBG_XMIT, "transmitting CABQ packet, skb: %p\n", skb); |
2516 | __func__, | ||
2517 | skb); | ||
2518 | 2535 | ||
2519 | if (ath_tx_start(sc, skb, &txctl) != 0) { | 2536 | if (ath_tx_start(sc, skb, &txctl) != 0) { |
2520 | DPRINTF(sc, ATH_DBG_XMIT, "%s: TX failed\n", __func__); | 2537 | DPRINTF(sc, ATH_DBG_XMIT, "CABQ TX failed\n"); |
2521 | goto exit; | 2538 | goto exit; |
2522 | } | 2539 | } |
2523 | 2540 | ||
diff --git a/drivers/net/wireless/hostap/Kconfig b/drivers/net/wireless/hostap/Kconfig index 87bbd4db4bad..932d207bce23 100644 --- a/drivers/net/wireless/hostap/Kconfig +++ b/drivers/net/wireless/hostap/Kconfig | |||
@@ -2,6 +2,13 @@ config HOSTAP | |||
2 | tristate "IEEE 802.11 for Host AP (Prism2/2.5/3 and WEP/TKIP/CCMP)" | 2 | tristate "IEEE 802.11 for Host AP (Prism2/2.5/3 and WEP/TKIP/CCMP)" |
3 | depends on WLAN_80211 | 3 | depends on WLAN_80211 |
4 | select WIRELESS_EXT | 4 | select WIRELESS_EXT |
5 | select CRYPTO | ||
6 | select CRYPTO_ARC4 | ||
7 | select CRYPTO_ECB | ||
8 | select CRYPTO_AES | ||
9 | select CRYPTO_MICHAEL_MIC | ||
10 | select CRYPTO_ECB | ||
11 | select CRC32 | ||
5 | select LIB80211 | 12 | select LIB80211 |
6 | select LIB80211_CRYPT_WEP | 13 | select LIB80211_CRYPT_WEP |
7 | select LIB80211_CRYPT_TKIP | 14 | select LIB80211_CRYPT_TKIP |
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index d2a2b7586d08..48fa6df3a774 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c | |||
@@ -7797,15 +7797,6 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv, | |||
7797 | memmove(rxb->skb->data + sizeof(struct ipw_rt_hdr), | 7797 | memmove(rxb->skb->data + sizeof(struct ipw_rt_hdr), |
7798 | rxb->skb->data + IPW_RX_FRAME_SIZE, len); | 7798 | rxb->skb->data + IPW_RX_FRAME_SIZE, len); |
7799 | 7799 | ||
7800 | /* Zero the radiotap static buffer ... We only need to zero the bytes NOT | ||
7801 | * part of our real header, saves a little time. | ||
7802 | * | ||
7803 | * No longer necessary since we fill in all our data. Purge before merging | ||
7804 | * patch officially. | ||
7805 | * memset(rxb->skb->data + sizeof(struct ipw_rt_hdr), 0, | ||
7806 | * IEEE80211_RADIOTAP_HDRLEN - sizeof(struct ipw_rt_hdr)); | ||
7807 | */ | ||
7808 | |||
7809 | ipw_rt = (struct ipw_rt_hdr *)rxb->skb->data; | 7800 | ipw_rt = (struct ipw_rt_hdr *)rxb->skb->data; |
7810 | 7801 | ||
7811 | ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION; | 7802 | ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION; |
@@ -8013,15 +8004,6 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv, | |||
8013 | 8004 | ||
8014 | memcpy(ipw_rt->payload, hdr, len); | 8005 | memcpy(ipw_rt->payload, hdr, len); |
8015 | 8006 | ||
8016 | /* Zero the radiotap static buffer ... We only need to zero the bytes | ||
8017 | * NOT part of our real header, saves a little time. | ||
8018 | * | ||
8019 | * No longer necessary since we fill in all our data. Purge before | ||
8020 | * merging patch officially. | ||
8021 | * memset(rxb->skb->data + sizeof(struct ipw_rt_hdr), 0, | ||
8022 | * IEEE80211_RADIOTAP_HDRLEN - sizeof(struct ipw_rt_hdr)); | ||
8023 | */ | ||
8024 | |||
8025 | ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION; | 8007 | ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION; |
8026 | ipw_rt->rt_hdr.it_pad = 0; /* always good to zero */ | 8008 | ipw_rt->rt_hdr.it_pad = 0; /* always good to zero */ |
8027 | ipw_rt->rt_hdr.it_len = cpu_to_le16(sizeof(*ipw_rt)); /* total header+data */ | 8009 | ipw_rt->rt_hdr.it_len = cpu_to_le16(sizeof(*ipw_rt)); /* total header+data */ |
@@ -10409,9 +10391,9 @@ static void ipw_handle_promiscuous_tx(struct ipw_priv *priv, | |||
10409 | } else | 10391 | } else |
10410 | len = src->len; | 10392 | len = src->len; |
10411 | 10393 | ||
10412 | dst = alloc_skb( | 10394 | dst = alloc_skb(len + sizeof(*rt_hdr), GFP_ATOMIC); |
10413 | len + IEEE80211_RADIOTAP_HDRLEN, GFP_ATOMIC); | 10395 | if (!dst) |
10414 | if (!dst) continue; | 10396 | continue; |
10415 | 10397 | ||
10416 | rt_hdr = (void *)skb_put(dst, sizeof(*rt_hdr)); | 10398 | rt_hdr = (void *)skb_put(dst, sizeof(*rt_hdr)); |
10417 | 10399 | ||
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 8b45b30e6d5c..0be9e6b66aa0 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile | |||
@@ -8,7 +8,7 @@ iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o | |||
8 | iwlcore-$(CONFIG_IWLAGN_SPECTRUM_MEASUREMENT) += iwl-spectrum.o | 8 | iwlcore-$(CONFIG_IWLAGN_SPECTRUM_MEASUREMENT) += iwl-spectrum.o |
9 | 9 | ||
10 | obj-$(CONFIG_IWLAGN) += iwlagn.o | 10 | obj-$(CONFIG_IWLAGN) += iwlagn.o |
11 | iwlagn-objs := iwl-agn.o iwl-agn-rs.o | 11 | iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-hcmd-check.o |
12 | 12 | ||
13 | iwlagn-$(CONFIG_IWL4965) += iwl-4965.o | 13 | iwlagn-$(CONFIG_IWL4965) += iwl-4965.o |
14 | iwlagn-$(CONFIG_IWL5000) += iwl-5000.o | 14 | iwlagn-$(CONFIG_IWL5000) += iwl-5000.o |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-commands.h b/drivers/net/wireless/iwlwifi/iwl-3945-commands.h index 8772d9d7d6e7..daf99ea88e90 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945-commands.h | |||
@@ -69,6 +69,12 @@ | |||
69 | #ifndef __iwl_3945_commands_h__ | 69 | #ifndef __iwl_3945_commands_h__ |
70 | #define __iwl_3945_commands_h__ | 70 | #define __iwl_3945_commands_h__ |
71 | 71 | ||
72 | /* uCode version contains 4 values: Major/Minor/API/Serial */ | ||
73 | #define IWL_UCODE_MAJOR(ver) (((ver) & 0xFF000000) >> 24) | ||
74 | #define IWL_UCODE_MINOR(ver) (((ver) & 0x00FF0000) >> 16) | ||
75 | #define IWL_UCODE_API(ver) (((ver) & 0x0000FF00) >> 8) | ||
76 | #define IWL_UCODE_SERIAL(ver) ((ver) & 0x000000FF) | ||
77 | |||
72 | enum { | 78 | enum { |
73 | REPLY_ALIVE = 0x1, | 79 | REPLY_ALIVE = 0x1, |
74 | REPLY_ERROR = 0x2, | 80 | REPLY_ERROR = 0x2, |
@@ -220,7 +226,7 @@ struct iwl3945_power_per_rate { | |||
220 | * | 226 | * |
221 | *****************************************************************************/ | 227 | *****************************************************************************/ |
222 | 228 | ||
223 | #define UCODE_VALID_OK __constant_cpu_to_le32(0x1) | 229 | #define UCODE_VALID_OK cpu_to_le32(0x1) |
224 | #define INITIALIZE_SUBTYPE (9) | 230 | #define INITIALIZE_SUBTYPE (9) |
225 | 231 | ||
226 | /* | 232 | /* |
@@ -322,42 +328,42 @@ enum { | |||
322 | 328 | ||
323 | /* rx_config flags */ | 329 | /* rx_config flags */ |
324 | /* band & modulation selection */ | 330 | /* band & modulation selection */ |
325 | #define RXON_FLG_BAND_24G_MSK __constant_cpu_to_le32(1 << 0) | 331 | #define RXON_FLG_BAND_24G_MSK cpu_to_le32(1 << 0) |
326 | #define RXON_FLG_CCK_MSK __constant_cpu_to_le32(1 << 1) | 332 | #define RXON_FLG_CCK_MSK cpu_to_le32(1 << 1) |
327 | /* auto detection enable */ | 333 | /* auto detection enable */ |
328 | #define RXON_FLG_AUTO_DETECT_MSK __constant_cpu_to_le32(1 << 2) | 334 | #define RXON_FLG_AUTO_DETECT_MSK cpu_to_le32(1 << 2) |
329 | /* TGg protection when tx */ | 335 | /* TGg protection when tx */ |
330 | #define RXON_FLG_TGG_PROTECT_MSK __constant_cpu_to_le32(1 << 3) | 336 | #define RXON_FLG_TGG_PROTECT_MSK cpu_to_le32(1 << 3) |
331 | /* cck short slot & preamble */ | 337 | /* cck short slot & preamble */ |
332 | #define RXON_FLG_SHORT_SLOT_MSK __constant_cpu_to_le32(1 << 4) | 338 | #define RXON_FLG_SHORT_SLOT_MSK cpu_to_le32(1 << 4) |
333 | #define RXON_FLG_SHORT_PREAMBLE_MSK __constant_cpu_to_le32(1 << 5) | 339 | #define RXON_FLG_SHORT_PREAMBLE_MSK cpu_to_le32(1 << 5) |
334 | /* antenna selection */ | 340 | /* antenna selection */ |
335 | #define RXON_FLG_DIS_DIV_MSK __constant_cpu_to_le32(1 << 7) | 341 | #define RXON_FLG_DIS_DIV_MSK cpu_to_le32(1 << 7) |
336 | #define RXON_FLG_ANT_SEL_MSK __constant_cpu_to_le32(0x0f00) | 342 | #define RXON_FLG_ANT_SEL_MSK cpu_to_le32(0x0f00) |
337 | #define RXON_FLG_ANT_A_MSK __constant_cpu_to_le32(1 << 8) | 343 | #define RXON_FLG_ANT_A_MSK cpu_to_le32(1 << 8) |
338 | #define RXON_FLG_ANT_B_MSK __constant_cpu_to_le32(1 << 9) | 344 | #define RXON_FLG_ANT_B_MSK cpu_to_le32(1 << 9) |
339 | /* radar detection enable */ | 345 | /* radar detection enable */ |
340 | #define RXON_FLG_RADAR_DETECT_MSK __constant_cpu_to_le32(1 << 12) | 346 | #define RXON_FLG_RADAR_DETECT_MSK cpu_to_le32(1 << 12) |
341 | #define RXON_FLG_TGJ_NARROW_BAND_MSK __constant_cpu_to_le32(1 << 13) | 347 | #define RXON_FLG_TGJ_NARROW_BAND_MSK cpu_to_le32(1 << 13) |
342 | /* rx response to host with 8-byte TSF | 348 | /* rx response to host with 8-byte TSF |
343 | * (according to ON_AIR deassertion) */ | 349 | * (according to ON_AIR deassertion) */ |
344 | #define RXON_FLG_TSF2HOST_MSK __constant_cpu_to_le32(1 << 15) | 350 | #define RXON_FLG_TSF2HOST_MSK cpu_to_le32(1 << 15) |
345 | 351 | ||
346 | /* rx_config filter flags */ | 352 | /* rx_config filter flags */ |
347 | /* accept all data frames */ | 353 | /* accept all data frames */ |
348 | #define RXON_FILTER_PROMISC_MSK __constant_cpu_to_le32(1 << 0) | 354 | #define RXON_FILTER_PROMISC_MSK cpu_to_le32(1 << 0) |
349 | /* pass control & management to host */ | 355 | /* pass control & management to host */ |
350 | #define RXON_FILTER_CTL2HOST_MSK __constant_cpu_to_le32(1 << 1) | 356 | #define RXON_FILTER_CTL2HOST_MSK cpu_to_le32(1 << 1) |
351 | /* accept multi-cast */ | 357 | /* accept multi-cast */ |
352 | #define RXON_FILTER_ACCEPT_GRP_MSK __constant_cpu_to_le32(1 << 2) | 358 | #define RXON_FILTER_ACCEPT_GRP_MSK cpu_to_le32(1 << 2) |
353 | /* don't decrypt uni-cast frames */ | 359 | /* don't decrypt uni-cast frames */ |
354 | #define RXON_FILTER_DIS_DECRYPT_MSK __constant_cpu_to_le32(1 << 3) | 360 | #define RXON_FILTER_DIS_DECRYPT_MSK cpu_to_le32(1 << 3) |
355 | /* don't decrypt multi-cast frames */ | 361 | /* don't decrypt multi-cast frames */ |
356 | #define RXON_FILTER_DIS_GRP_DECRYPT_MSK __constant_cpu_to_le32(1 << 4) | 362 | #define RXON_FILTER_DIS_GRP_DECRYPT_MSK cpu_to_le32(1 << 4) |
357 | /* STA is associated */ | 363 | /* STA is associated */ |
358 | #define RXON_FILTER_ASSOC_MSK __constant_cpu_to_le32(1 << 5) | 364 | #define RXON_FILTER_ASSOC_MSK cpu_to_le32(1 << 5) |
359 | /* transfer to host non bssid beacons in associated state */ | 365 | /* transfer to host non bssid beacons in associated state */ |
360 | #define RXON_FILTER_BCON_AWARE_MSK __constant_cpu_to_le32(1 << 6) | 366 | #define RXON_FILTER_BCON_AWARE_MSK cpu_to_le32(1 << 6) |
361 | 367 | ||
362 | /** | 368 | /** |
363 | * REPLY_RXON = 0x10 (command, has simple generic response) | 369 | * REPLY_RXON = 0x10 (command, has simple generic response) |
@@ -471,9 +477,9 @@ struct iwl3945_ac_qos { | |||
471 | } __attribute__ ((packed)); | 477 | } __attribute__ ((packed)); |
472 | 478 | ||
473 | /* QoS flags defines */ | 479 | /* QoS flags defines */ |
474 | #define QOS_PARAM_FLG_UPDATE_EDCA_MSK __constant_cpu_to_le32(0x01) | 480 | #define QOS_PARAM_FLG_UPDATE_EDCA_MSK cpu_to_le32(0x01) |
475 | #define QOS_PARAM_FLG_TGN_MSK __constant_cpu_to_le32(0x02) | 481 | #define QOS_PARAM_FLG_TGN_MSK cpu_to_le32(0x02) |
476 | #define QOS_PARAM_FLG_TXOP_TYPE_MSK __constant_cpu_to_le32(0x10) | 482 | #define QOS_PARAM_FLG_TXOP_TYPE_MSK cpu_to_le32(0x10) |
477 | 483 | ||
478 | /* Number of Access Categories (AC) (EDCA), queues 0..3 */ | 484 | /* Number of Access Categories (AC) (EDCA), queues 0..3 */ |
479 | #define AC_NUM 4 | 485 | #define AC_NUM 4 |
@@ -508,27 +514,27 @@ struct iwl3945_qosparam_cmd { | |||
508 | #define IWL_STATION_COUNT 32 /* MAX(3945,4965)*/ | 514 | #define IWL_STATION_COUNT 32 /* MAX(3945,4965)*/ |
509 | #define IWL_INVALID_STATION 255 | 515 | #define IWL_INVALID_STATION 255 |
510 | 516 | ||
511 | #define STA_FLG_TX_RATE_MSK __constant_cpu_to_le32(1 << 2); | 517 | #define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2); |
512 | #define STA_FLG_PWR_SAVE_MSK __constant_cpu_to_le32(1 << 8); | 518 | #define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8); |
513 | 519 | ||
514 | /* Use in mode field. 1: modify existing entry, 0: add new station entry */ | 520 | /* Use in mode field. 1: modify existing entry, 0: add new station entry */ |
515 | #define STA_CONTROL_MODIFY_MSK 0x01 | 521 | #define STA_CONTROL_MODIFY_MSK 0x01 |
516 | 522 | ||
517 | /* key flags __le16*/ | 523 | /* key flags __le16*/ |
518 | #define STA_KEY_FLG_ENCRYPT_MSK __constant_cpu_to_le16(0x0007) | 524 | #define STA_KEY_FLG_ENCRYPT_MSK cpu_to_le16(0x0007) |
519 | #define STA_KEY_FLG_NO_ENC __constant_cpu_to_le16(0x0000) | 525 | #define STA_KEY_FLG_NO_ENC cpu_to_le16(0x0000) |
520 | #define STA_KEY_FLG_WEP __constant_cpu_to_le16(0x0001) | 526 | #define STA_KEY_FLG_WEP cpu_to_le16(0x0001) |
521 | #define STA_KEY_FLG_CCMP __constant_cpu_to_le16(0x0002) | 527 | #define STA_KEY_FLG_CCMP cpu_to_le16(0x0002) |
522 | #define STA_KEY_FLG_TKIP __constant_cpu_to_le16(0x0003) | 528 | #define STA_KEY_FLG_TKIP cpu_to_le16(0x0003) |
523 | 529 | ||
524 | #define STA_KEY_FLG_KEYID_POS 8 | 530 | #define STA_KEY_FLG_KEYID_POS 8 |
525 | #define STA_KEY_FLG_INVALID __constant_cpu_to_le16(0x0800) | 531 | #define STA_KEY_FLG_INVALID cpu_to_le16(0x0800) |
526 | /* wep key is either from global key (0) or from station info array (1) */ | 532 | /* wep key is either from global key (0) or from station info array (1) */ |
527 | #define STA_KEY_FLG_WEP_KEY_MAP_MSK __constant_cpu_to_le16(0x0008) | 533 | #define STA_KEY_FLG_WEP_KEY_MAP_MSK cpu_to_le16(0x0008) |
528 | 534 | ||
529 | /* wep key in STA: 5-bytes (0) or 13-bytes (1) */ | 535 | /* wep key in STA: 5-bytes (0) or 13-bytes (1) */ |
530 | #define STA_KEY_FLG_KEY_SIZE_MSK __constant_cpu_to_le16(0x1000) | 536 | #define STA_KEY_FLG_KEY_SIZE_MSK cpu_to_le16(0x1000) |
531 | #define STA_KEY_MULTICAST_MSK __constant_cpu_to_le16(0x4000) | 537 | #define STA_KEY_MULTICAST_MSK cpu_to_le16(0x4000) |
532 | 538 | ||
533 | /* Flags indicate whether to modify vs. don't change various station params */ | 539 | /* Flags indicate whether to modify vs. don't change various station params */ |
534 | #define STA_MODIFY_KEY_MASK 0x01 | 540 | #define STA_MODIFY_KEY_MASK 0x01 |
@@ -666,14 +672,14 @@ struct iwl3945_rx_frame_hdr { | |||
666 | u8 payload[0]; | 672 | u8 payload[0]; |
667 | } __attribute__ ((packed)); | 673 | } __attribute__ ((packed)); |
668 | 674 | ||
669 | #define RX_RES_STATUS_NO_CRC32_ERROR __constant_cpu_to_le32(1 << 0) | 675 | #define RX_RES_STATUS_NO_CRC32_ERROR cpu_to_le32(1 << 0) |
670 | #define RX_RES_STATUS_NO_RXE_OVERFLOW __constant_cpu_to_le32(1 << 1) | 676 | #define RX_RES_STATUS_NO_RXE_OVERFLOW cpu_to_le32(1 << 1) |
671 | 677 | ||
672 | #define RX_RES_PHY_FLAGS_BAND_24_MSK __constant_cpu_to_le16(1 << 0) | 678 | #define RX_RES_PHY_FLAGS_BAND_24_MSK cpu_to_le16(1 << 0) |
673 | #define RX_RES_PHY_FLAGS_MOD_CCK_MSK __constant_cpu_to_le16(1 << 1) | 679 | #define RX_RES_PHY_FLAGS_MOD_CCK_MSK cpu_to_le16(1 << 1) |
674 | #define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK __constant_cpu_to_le16(1 << 2) | 680 | #define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK cpu_to_le16(1 << 2) |
675 | #define RX_RES_PHY_FLAGS_NARROW_BAND_MSK __constant_cpu_to_le16(1 << 3) | 681 | #define RX_RES_PHY_FLAGS_NARROW_BAND_MSK cpu_to_le16(1 << 3) |
676 | #define RX_RES_PHY_FLAGS_ANTENNA_MSK __constant_cpu_to_le16(0xf0) | 682 | #define RX_RES_PHY_FLAGS_ANTENNA_MSK cpu_to_le16(0xf0) |
677 | 683 | ||
678 | #define RX_RES_STATUS_SEC_TYPE_MSK (0x7 << 8) | 684 | #define RX_RES_STATUS_SEC_TYPE_MSK (0x7 << 8) |
679 | #define RX_RES_STATUS_SEC_TYPE_NONE (0x0 << 8) | 685 | #define RX_RES_STATUS_SEC_TYPE_NONE (0x0 << 8) |
@@ -733,57 +739,57 @@ struct iwl3945_rx_frame { | |||
733 | 739 | ||
734 | /* 1: Use Request-To-Send protocol before this frame. | 740 | /* 1: Use Request-To-Send protocol before this frame. |
735 | * Mutually exclusive vs. TX_CMD_FLG_CTS_MSK. */ | 741 | * Mutually exclusive vs. TX_CMD_FLG_CTS_MSK. */ |
736 | #define TX_CMD_FLG_RTS_MSK __constant_cpu_to_le32(1 << 1) | 742 | #define TX_CMD_FLG_RTS_MSK cpu_to_le32(1 << 1) |
737 | 743 | ||
738 | /* 1: Transmit Clear-To-Send to self before this frame. | 744 | /* 1: Transmit Clear-To-Send to self before this frame. |
739 | * Driver should set this for AUTH/DEAUTH/ASSOC-REQ/REASSOC mgmnt frames. | 745 | * Driver should set this for AUTH/DEAUTH/ASSOC-REQ/REASSOC mgmnt frames. |
740 | * Mutually exclusive vs. TX_CMD_FLG_RTS_MSK. */ | 746 | * Mutually exclusive vs. TX_CMD_FLG_RTS_MSK. */ |
741 | #define TX_CMD_FLG_CTS_MSK __constant_cpu_to_le32(1 << 2) | 747 | #define TX_CMD_FLG_CTS_MSK cpu_to_le32(1 << 2) |
742 | 748 | ||
743 | /* 1: Expect ACK from receiving station | 749 | /* 1: Expect ACK from receiving station |
744 | * 0: Don't expect ACK (MAC header's duration field s/b 0) | 750 | * 0: Don't expect ACK (MAC header's duration field s/b 0) |
745 | * Set this for unicast frames, but not broadcast/multicast. */ | 751 | * Set this for unicast frames, but not broadcast/multicast. */ |
746 | #define TX_CMD_FLG_ACK_MSK __constant_cpu_to_le32(1 << 3) | 752 | #define TX_CMD_FLG_ACK_MSK cpu_to_le32(1 << 3) |
747 | 753 | ||
748 | /* 1: Use rate scale table (see REPLY_TX_LINK_QUALITY_CMD). | 754 | /* 1: Use rate scale table (see REPLY_TX_LINK_QUALITY_CMD). |
749 | * Tx command's initial_rate_index indicates first rate to try; | 755 | * Tx command's initial_rate_index indicates first rate to try; |
750 | * uCode walks through table for additional Tx attempts. | 756 | * uCode walks through table for additional Tx attempts. |
751 | * 0: Use Tx rate/MCS from Tx command's rate_n_flags field. | 757 | * 0: Use Tx rate/MCS from Tx command's rate_n_flags field. |
752 | * This rate will be used for all Tx attempts; it will not be scaled. */ | 758 | * This rate will be used for all Tx attempts; it will not be scaled. */ |
753 | #define TX_CMD_FLG_STA_RATE_MSK __constant_cpu_to_le32(1 << 4) | 759 | #define TX_CMD_FLG_STA_RATE_MSK cpu_to_le32(1 << 4) |
754 | 760 | ||
755 | /* 1: Expect immediate block-ack. | 761 | /* 1: Expect immediate block-ack. |
756 | * Set when Txing a block-ack request frame. Also set TX_CMD_FLG_ACK_MSK. */ | 762 | * Set when Txing a block-ack request frame. Also set TX_CMD_FLG_ACK_MSK. */ |
757 | #define TX_CMD_FLG_IMM_BA_RSP_MASK __constant_cpu_to_le32(1 << 6) | 763 | #define TX_CMD_FLG_IMM_BA_RSP_MASK cpu_to_le32(1 << 6) |
758 | 764 | ||
759 | /* 1: Frame requires full Tx-Op protection. | 765 | /* 1: Frame requires full Tx-Op protection. |
760 | * Set this if either RTS or CTS Tx Flag gets set. */ | 766 | * Set this if either RTS or CTS Tx Flag gets set. */ |
761 | #define TX_CMD_FLG_FULL_TXOP_PROT_MSK __constant_cpu_to_le32(1 << 7) | 767 | #define TX_CMD_FLG_FULL_TXOP_PROT_MSK cpu_to_le32(1 << 7) |
762 | 768 | ||
763 | /* Tx antenna selection field; used only for 3945, reserved (0) for 4965. | 769 | /* Tx antenna selection field; used only for 3945, reserved (0) for 4965. |
764 | * Set field to "0" to allow 3945 uCode to select antenna (normal usage). */ | 770 | * Set field to "0" to allow 3945 uCode to select antenna (normal usage). */ |
765 | #define TX_CMD_FLG_ANT_SEL_MSK __constant_cpu_to_le32(0xf00) | 771 | #define TX_CMD_FLG_ANT_SEL_MSK cpu_to_le32(0xf00) |
766 | #define TX_CMD_FLG_ANT_A_MSK __constant_cpu_to_le32(1 << 8) | 772 | #define TX_CMD_FLG_ANT_A_MSK cpu_to_le32(1 << 8) |
767 | #define TX_CMD_FLG_ANT_B_MSK __constant_cpu_to_le32(1 << 9) | 773 | #define TX_CMD_FLG_ANT_B_MSK cpu_to_le32(1 << 9) |
768 | 774 | ||
769 | /* 1: Ignore Bluetooth priority for this frame. | 775 | /* 1: Ignore Bluetooth priority for this frame. |
770 | * 0: Delay Tx until Bluetooth device is done (normal usage). */ | 776 | * 0: Delay Tx until Bluetooth device is done (normal usage). */ |
771 | #define TX_CMD_FLG_BT_DIS_MSK __constant_cpu_to_le32(1 << 12) | 777 | #define TX_CMD_FLG_BT_DIS_MSK cpu_to_le32(1 << 12) |
772 | 778 | ||
773 | /* 1: uCode overrides sequence control field in MAC header. | 779 | /* 1: uCode overrides sequence control field in MAC header. |
774 | * 0: Driver provides sequence control field in MAC header. | 780 | * 0: Driver provides sequence control field in MAC header. |
775 | * Set this for management frames, non-QOS data frames, non-unicast frames, | 781 | * Set this for management frames, non-QOS data frames, non-unicast frames, |
776 | * and also in Tx command embedded in REPLY_SCAN_CMD for active scans. */ | 782 | * and also in Tx command embedded in REPLY_SCAN_CMD for active scans. */ |
777 | #define TX_CMD_FLG_SEQ_CTL_MSK __constant_cpu_to_le32(1 << 13) | 783 | #define TX_CMD_FLG_SEQ_CTL_MSK cpu_to_le32(1 << 13) |
778 | 784 | ||
779 | /* 1: This frame is non-last MPDU; more fragments are coming. | 785 | /* 1: This frame is non-last MPDU; more fragments are coming. |
780 | * 0: Last fragment, or not using fragmentation. */ | 786 | * 0: Last fragment, or not using fragmentation. */ |
781 | #define TX_CMD_FLG_MORE_FRAG_MSK __constant_cpu_to_le32(1 << 14) | 787 | #define TX_CMD_FLG_MORE_FRAG_MSK cpu_to_le32(1 << 14) |
782 | 788 | ||
783 | /* 1: uCode calculates and inserts Timestamp Function (TSF) in outgoing frame. | 789 | /* 1: uCode calculates and inserts Timestamp Function (TSF) in outgoing frame. |
784 | * 0: No TSF required in outgoing frame. | 790 | * 0: No TSF required in outgoing frame. |
785 | * Set this for transmitting beacons and probe responses. */ | 791 | * Set this for transmitting beacons and probe responses. */ |
786 | #define TX_CMD_FLG_TSF_MSK __constant_cpu_to_le32(1 << 16) | 792 | #define TX_CMD_FLG_TSF_MSK cpu_to_le32(1 << 16) |
787 | 793 | ||
788 | /* 1: Driver inserted 2 bytes pad after the MAC header, for (required) dword | 794 | /* 1: Driver inserted 2 bytes pad after the MAC header, for (required) dword |
789 | * alignment of frame's payload data field. | 795 | * alignment of frame's payload data field. |
@@ -791,10 +797,10 @@ struct iwl3945_rx_frame { | |||
791 | * Set this for MAC headers with 26 or 30 bytes, i.e. those with QOS or ADDR4 | 797 | * Set this for MAC headers with 26 or 30 bytes, i.e. those with QOS or ADDR4 |
792 | * field (but not both). Driver must align frame data (i.e. data following | 798 | * field (but not both). Driver must align frame data (i.e. data following |
793 | * MAC header) to DWORD boundary. */ | 799 | * MAC header) to DWORD boundary. */ |
794 | #define TX_CMD_FLG_MH_PAD_MSK __constant_cpu_to_le32(1 << 20) | 800 | #define TX_CMD_FLG_MH_PAD_MSK cpu_to_le32(1 << 20) |
795 | 801 | ||
796 | /* HCCA-AP - disable duration overwriting. */ | 802 | /* HCCA-AP - disable duration overwriting. */ |
797 | #define TX_CMD_FLG_DUR_MSK __constant_cpu_to_le32(1 << 25) | 803 | #define TX_CMD_FLG_DUR_MSK cpu_to_le32(1 << 25) |
798 | 804 | ||
799 | /* | 805 | /* |
800 | * TX command security control | 806 | * TX command security control |
@@ -1158,9 +1164,9 @@ struct iwl3945_spectrum_notification { | |||
1158 | */ | 1164 | */ |
1159 | #define IWL_POWER_VEC_SIZE 5 | 1165 | #define IWL_POWER_VEC_SIZE 5 |
1160 | 1166 | ||
1161 | #define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK __constant_cpu_to_le32(1 << 0) | 1167 | #define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK cpu_to_le32(1 << 0) |
1162 | #define IWL_POWER_SLEEP_OVER_DTIM_MSK __constant_cpu_to_le32(1 << 2) | 1168 | #define IWL_POWER_SLEEP_OVER_DTIM_MSK cpu_to_le32(1 << 2) |
1163 | #define IWL_POWER_PCI_PM_MSK __constant_cpu_to_le32(1 << 3) | 1169 | #define IWL_POWER_PCI_PM_MSK cpu_to_le32(1 << 3) |
1164 | struct iwl3945_powertable_cmd { | 1170 | struct iwl3945_powertable_cmd { |
1165 | __le32 flags; | 1171 | __le32 flags; |
1166 | __le32 rx_data_timeout; | 1172 | __le32 rx_data_timeout; |
@@ -1278,8 +1284,8 @@ struct iwl3945_ssid_ie { | |||
1278 | } __attribute__ ((packed)); | 1284 | } __attribute__ ((packed)); |
1279 | 1285 | ||
1280 | #define PROBE_OPTION_MAX 0x4 | 1286 | #define PROBE_OPTION_MAX 0x4 |
1281 | #define TX_CMD_LIFE_TIME_INFINITE __constant_cpu_to_le32(0xFFFFFFFF) | 1287 | #define TX_CMD_LIFE_TIME_INFINITE cpu_to_le32(0xFFFFFFFF) |
1282 | #define IWL_GOOD_CRC_TH __constant_cpu_to_le16(1) | 1288 | #define IWL_GOOD_CRC_TH cpu_to_le16(1) |
1283 | #define IWL_MAX_SCAN_SIZE 1024 | 1289 | #define IWL_MAX_SCAN_SIZE 1024 |
1284 | 1290 | ||
1285 | /* | 1291 | /* |
@@ -1379,7 +1385,7 @@ struct iwl3945_scan_cmd { | |||
1379 | } __attribute__ ((packed)); | 1385 | } __attribute__ ((packed)); |
1380 | 1386 | ||
1381 | /* Can abort will notify by complete notification with abort status. */ | 1387 | /* Can abort will notify by complete notification with abort status. */ |
1382 | #define CAN_ABORT_STATUS __constant_cpu_to_le32(0x1) | 1388 | #define CAN_ABORT_STATUS cpu_to_le32(0x1) |
1383 | /* complete notification statuses */ | 1389 | /* complete notification statuses */ |
1384 | #define ABORT_STATUS 0x2 | 1390 | #define ABORT_STATUS 0x2 |
1385 | 1391 | ||
@@ -1572,8 +1578,8 @@ struct statistics_general { | |||
1572 | * STATISTICS_NOTIFICATIONs after received beacons (see below). This flag | 1578 | * STATISTICS_NOTIFICATIONs after received beacons (see below). This flag |
1573 | * does not affect the response to the REPLY_STATISTICS_CMD 0x9c itself. | 1579 | * does not affect the response to the REPLY_STATISTICS_CMD 0x9c itself. |
1574 | */ | 1580 | */ |
1575 | #define IWL_STATS_CONF_CLEAR_STATS __constant_cpu_to_le32(0x1) /* see above */ | 1581 | #define IWL_STATS_CONF_CLEAR_STATS cpu_to_le32(0x1) /* see above */ |
1576 | #define IWL_STATS_CONF_DISABLE_NOTIF __constant_cpu_to_le32(0x2)/* see above */ | 1582 | #define IWL_STATS_CONF_DISABLE_NOTIF cpu_to_le32(0x2)/* see above */ |
1577 | struct iwl3945_statistics_cmd { | 1583 | struct iwl3945_statistics_cmd { |
1578 | __le32 configuration_flags; /* IWL_STATS_CONF_* */ | 1584 | __le32 configuration_flags; /* IWL_STATS_CONF_* */ |
1579 | } __attribute__ ((packed)); | 1585 | } __attribute__ ((packed)); |
@@ -1593,8 +1599,8 @@ struct iwl3945_statistics_cmd { | |||
1593 | * appropriately so that each notification contains statistics for only the | 1599 | * appropriately so that each notification contains statistics for only the |
1594 | * one channel that has just been scanned. | 1600 | * one channel that has just been scanned. |
1595 | */ | 1601 | */ |
1596 | #define STATISTICS_REPLY_FLG_BAND_24G_MSK __constant_cpu_to_le32(0x2) | 1602 | #define STATISTICS_REPLY_FLG_BAND_24G_MSK cpu_to_le32(0x2) |
1597 | #define STATISTICS_REPLY_FLG_FAT_MODE_MSK __constant_cpu_to_le32(0x8) | 1603 | #define STATISTICS_REPLY_FLG_FAT_MODE_MSK cpu_to_le32(0x8) |
1598 | struct iwl3945_notif_statistics { | 1604 | struct iwl3945_notif_statistics { |
1599 | __le32 flag; | 1605 | __le32 flag; |
1600 | struct statistics_rx rx; | 1606 | struct statistics_rx rx; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-core.h b/drivers/net/wireless/iwlwifi/iwl-3945-core.h index bc12f97ba0b1..edac6c6a9110 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945-core.h | |||
@@ -71,9 +71,33 @@ | |||
71 | #define IWL_SKU_G 0x1 | 71 | #define IWL_SKU_G 0x1 |
72 | #define IWL_SKU_A 0x2 | 72 | #define IWL_SKU_A 0x2 |
73 | 73 | ||
74 | /** | ||
75 | * struct iwl_3945_cfg | ||
76 | * @fw_name_pre: Firmware filename prefix. The api version and extension | ||
77 | * (.ucode) will be added to filename before loading from disk. The | ||
78 | * filename is constructed as fw_name_pre<api>.ucode. | ||
79 | * @ucode_api_max: Highest version of uCode API supported by driver. | ||
80 | * @ucode_api_min: Lowest version of uCode API supported by driver. | ||
81 | * | ||
82 | * We enable the driver to be backward compatible wrt API version. The | ||
83 | * driver specifies which APIs it supports (with @ucode_api_max being the | ||
84 | * highest and @ucode_api_min the lowest). Firmware will only be loaded if | ||
85 | * it has a supported API version. The firmware's API version will be | ||
86 | * stored in @iwl_priv, enabling the driver to make runtime changes based | ||
87 | * on firmware version used. | ||
88 | * | ||
89 | * For example, | ||
90 | * if (IWL_UCODE_API(priv->ucode_ver) >= 2) { | ||
91 | * Driver interacts with Firmware API version >= 2. | ||
92 | * } else { | ||
93 | * Driver interacts with Firmware API version 1. | ||
94 | * } | ||
95 | */ | ||
74 | struct iwl_3945_cfg { | 96 | struct iwl_3945_cfg { |
75 | const char *name; | 97 | const char *name; |
76 | const char *fw_name; | 98 | const char *fw_name_pre; |
99 | const unsigned int ucode_api_max; | ||
100 | const unsigned int ucode_api_min; | ||
77 | unsigned int sku; | 101 | unsigned int sku; |
78 | }; | 102 | }; |
79 | 103 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c index bfeef701b1fd..b03dd06ceabf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c | |||
@@ -63,6 +63,9 @@ struct iwl3945_rs_sta { | |||
63 | u8 ibss_sta_added; | 63 | u8 ibss_sta_added; |
64 | struct timer_list rate_scale_flush; | 64 | struct timer_list rate_scale_flush; |
65 | struct iwl3945_rate_scale_data win[IWL_RATE_COUNT]; | 65 | struct iwl3945_rate_scale_data win[IWL_RATE_COUNT]; |
66 | #ifdef CONFIG_MAC80211_DEBUGFS | ||
67 | struct dentry *rs_sta_dbgfs_stats_table_file; | ||
68 | #endif | ||
66 | 69 | ||
67 | /* used to be in sta_info */ | 70 | /* used to be in sta_info */ |
68 | int last_txrate_idx; | 71 | int last_txrate_idx; |
@@ -114,9 +117,11 @@ static struct iwl3945_tpt_entry iwl3945_tpt_table_g[] = { | |||
114 | }; | 117 | }; |
115 | 118 | ||
116 | #define IWL_RATE_MAX_WINDOW 62 | 119 | #define IWL_RATE_MAX_WINDOW 62 |
117 | #define IWL_RATE_FLUSH (3*HZ/10) | 120 | #define IWL_RATE_FLUSH (3*HZ) |
118 | #define IWL_RATE_WIN_FLUSH (HZ/2) | 121 | #define IWL_RATE_WIN_FLUSH (HZ/2) |
119 | #define IWL_RATE_HIGH_TH 11520 | 122 | #define IWL_RATE_HIGH_TH 11520 |
123 | #define IWL_SUCCESS_UP_TH 8960 | ||
124 | #define IWL_SUCCESS_DOWN_TH 10880 | ||
120 | #define IWL_RATE_MIN_FAILURE_TH 8 | 125 | #define IWL_RATE_MIN_FAILURE_TH 8 |
121 | #define IWL_RATE_MIN_SUCCESS_TH 8 | 126 | #define IWL_RATE_MIN_SUCCESS_TH 8 |
122 | #define IWL_RATE_DECREASE_TH 1920 | 127 | #define IWL_RATE_DECREASE_TH 1920 |
@@ -203,6 +208,7 @@ static int iwl3945_rate_scale_flush_windows(struct iwl3945_rs_sta *rs_sta) | |||
203 | 208 | ||
204 | #define IWL_RATE_FLUSH_MAX 5000 /* msec */ | 209 | #define IWL_RATE_FLUSH_MAX 5000 /* msec */ |
205 | #define IWL_RATE_FLUSH_MIN 50 /* msec */ | 210 | #define IWL_RATE_FLUSH_MIN 50 /* msec */ |
211 | #define IWL_AVERAGE_PACKETS 1500 | ||
206 | 212 | ||
207 | static void iwl3945_bg_rate_scale_flush(unsigned long data) | 213 | static void iwl3945_bg_rate_scale_flush(unsigned long data) |
208 | { | 214 | { |
@@ -217,8 +223,6 @@ static void iwl3945_bg_rate_scale_flush(unsigned long data) | |||
217 | 223 | ||
218 | spin_lock_irqsave(&rs_sta->lock, flags); | 224 | spin_lock_irqsave(&rs_sta->lock, flags); |
219 | 225 | ||
220 | rs_sta->flush_pending = 0; | ||
221 | |||
222 | /* Number of packets Rx'd since last time this timer ran */ | 226 | /* Number of packets Rx'd since last time this timer ran */ |
223 | packet_count = (rs_sta->tx_packets - rs_sta->last_tx_packets) + 1; | 227 | packet_count = (rs_sta->tx_packets - rs_sta->last_tx_packets) + 1; |
224 | 228 | ||
@@ -227,7 +231,6 @@ static void iwl3945_bg_rate_scale_flush(unsigned long data) | |||
227 | if (unflushed) { | 231 | if (unflushed) { |
228 | duration = | 232 | duration = |
229 | jiffies_to_msecs(jiffies - rs_sta->last_partial_flush); | 233 | jiffies_to_msecs(jiffies - rs_sta->last_partial_flush); |
230 | /* duration = jiffies_to_msecs(rs_sta->flush_time); */ | ||
231 | 234 | ||
232 | IWL_DEBUG_RATE("Tx'd %d packets in %dms\n", | 235 | IWL_DEBUG_RATE("Tx'd %d packets in %dms\n", |
233 | packet_count, duration); | 236 | packet_count, duration); |
@@ -239,9 +242,11 @@ static void iwl3945_bg_rate_scale_flush(unsigned long data) | |||
239 | pps = 0; | 242 | pps = 0; |
240 | 243 | ||
241 | if (pps) { | 244 | if (pps) { |
242 | duration = IWL_RATE_FLUSH_MAX / pps; | 245 | duration = (IWL_AVERAGE_PACKETS * 1000) / pps; |
243 | if (duration < IWL_RATE_FLUSH_MIN) | 246 | if (duration < IWL_RATE_FLUSH_MIN) |
244 | duration = IWL_RATE_FLUSH_MIN; | 247 | duration = IWL_RATE_FLUSH_MIN; |
248 | else if (duration > IWL_RATE_FLUSH_MAX) | ||
249 | duration = IWL_RATE_FLUSH_MAX; | ||
245 | } else | 250 | } else |
246 | duration = IWL_RATE_FLUSH_MAX; | 251 | duration = IWL_RATE_FLUSH_MAX; |
247 | 252 | ||
@@ -254,8 +259,10 @@ static void iwl3945_bg_rate_scale_flush(unsigned long data) | |||
254 | rs_sta->flush_time); | 259 | rs_sta->flush_time); |
255 | 260 | ||
256 | rs_sta->last_partial_flush = jiffies; | 261 | rs_sta->last_partial_flush = jiffies; |
262 | } else { | ||
263 | rs_sta->flush_time = IWL_RATE_FLUSH; | ||
264 | rs_sta->flush_pending = 0; | ||
257 | } | 265 | } |
258 | |||
259 | /* If there weren't any unflushed entries, we don't schedule the timer | 266 | /* If there weren't any unflushed entries, we don't schedule the timer |
260 | * to run again */ | 267 | * to run again */ |
261 | 268 | ||
@@ -275,17 +282,18 @@ static void iwl3945_bg_rate_scale_flush(unsigned long data) | |||
275 | */ | 282 | */ |
276 | static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta, | 283 | static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta, |
277 | struct iwl3945_rate_scale_data *window, | 284 | struct iwl3945_rate_scale_data *window, |
278 | int success, int retries) | 285 | int success, int retries, int index) |
279 | { | 286 | { |
280 | unsigned long flags; | 287 | unsigned long flags; |
288 | s32 fail_count; | ||
281 | 289 | ||
282 | if (!retries) { | 290 | if (!retries) { |
283 | IWL_DEBUG_RATE("leave: retries == 0 -- should be at least 1\n"); | 291 | IWL_DEBUG_RATE("leave: retries == 0 -- should be at least 1\n"); |
284 | return; | 292 | return; |
285 | } | 293 | } |
286 | 294 | ||
295 | spin_lock_irqsave(&rs_sta->lock, flags); | ||
287 | while (retries--) { | 296 | while (retries--) { |
288 | spin_lock_irqsave(&rs_sta->lock, flags); | ||
289 | 297 | ||
290 | /* If we have filled up the window then subtract one from the | 298 | /* If we have filled up the window then subtract one from the |
291 | * success counter if the high-bit is counting toward | 299 | * success counter if the high-bit is counting toward |
@@ -313,8 +321,18 @@ static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta, | |||
313 | /* Tag this window as having been updated */ | 321 | /* Tag this window as having been updated */ |
314 | window->stamp = jiffies; | 322 | window->stamp = jiffies; |
315 | 323 | ||
316 | spin_unlock_irqrestore(&rs_sta->lock, flags); | ||
317 | } | 324 | } |
325 | |||
326 | fail_count = window->counter - window->success_counter; | ||
327 | if ((fail_count >= IWL_RATE_MIN_FAILURE_TH) || | ||
328 | (window->success_counter >= IWL_RATE_MIN_SUCCESS_TH)) | ||
329 | window->average_tpt = ((window->success_ratio * | ||
330 | rs_sta->expected_tpt[index] + 64) / 128); | ||
331 | else | ||
332 | window->average_tpt = IWL_INV_TPT; | ||
333 | |||
334 | spin_unlock_irqrestore(&rs_sta->lock, flags); | ||
335 | |||
318 | } | 336 | } |
319 | 337 | ||
320 | static void rs_rate_init(void *priv, struct ieee80211_supported_band *sband, | 338 | static void rs_rate_init(void *priv, struct ieee80211_supported_band *sband, |
@@ -426,19 +444,16 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband | |||
426 | struct ieee80211_sta *sta, void *priv_sta, | 444 | struct ieee80211_sta *sta, void *priv_sta, |
427 | struct sk_buff *skb) | 445 | struct sk_buff *skb) |
428 | { | 446 | { |
429 | u8 retries = 0, current_count; | 447 | s8 retries = 0, current_count; |
430 | int scale_rate_index, first_index, last_index; | 448 | int scale_rate_index, first_index, last_index; |
431 | unsigned long flags; | 449 | unsigned long flags; |
432 | struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_rate; | 450 | struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_rate; |
433 | struct iwl3945_rs_sta *rs_sta = priv_sta; | 451 | struct iwl3945_rs_sta *rs_sta = priv_sta; |
434 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 452 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
435 | int i; | ||
436 | 453 | ||
437 | IWL_DEBUG_RATE("enter\n"); | 454 | IWL_DEBUG_RATE("enter\n"); |
438 | 455 | ||
439 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) | 456 | retries = info->status.rates[0].count; |
440 | retries += info->status.rates[i].count; | ||
441 | retries--; | ||
442 | 457 | ||
443 | first_index = sband->bitrates[info->status.rates[0].idx].hw_value; | 458 | first_index = sband->bitrates[info->status.rates[0].idx].hw_value; |
444 | if ((first_index < 0) || (first_index >= IWL_RATE_COUNT)) { | 459 | if ((first_index < 0) || (first_index >= IWL_RATE_COUNT)) { |
@@ -466,9 +481,9 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband | |||
466 | * at which the frame was finally transmitted (or failed if no | 481 | * at which the frame was finally transmitted (or failed if no |
467 | * ACK) | 482 | * ACK) |
468 | */ | 483 | */ |
469 | while (retries > 0) { | 484 | while (retries > 1) { |
470 | if (retries < priv->retry_rate) { | 485 | if ((retries - 1) < priv->retry_rate) { |
471 | current_count = retries; | 486 | current_count = (retries - 1); |
472 | last_index = scale_rate_index; | 487 | last_index = scale_rate_index; |
473 | } else { | 488 | } else { |
474 | current_count = priv->retry_rate; | 489 | current_count = priv->retry_rate; |
@@ -480,15 +495,13 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband | |||
480 | * as was used for it (per current_count) */ | 495 | * as was used for it (per current_count) */ |
481 | iwl3945_collect_tx_data(rs_sta, | 496 | iwl3945_collect_tx_data(rs_sta, |
482 | &rs_sta->win[scale_rate_index], | 497 | &rs_sta->win[scale_rate_index], |
483 | 0, current_count); | 498 | 0, current_count, scale_rate_index); |
484 | IWL_DEBUG_RATE("Update rate %d for %d retries.\n", | 499 | IWL_DEBUG_RATE("Update rate %d for %d retries.\n", |
485 | scale_rate_index, current_count); | 500 | scale_rate_index, current_count); |
486 | 501 | ||
487 | retries -= current_count; | 502 | retries -= current_count; |
488 | 503 | ||
489 | if (retries) | 504 | scale_rate_index = last_index; |
490 | scale_rate_index = | ||
491 | iwl3945_rs_next_rate(priv, scale_rate_index); | ||
492 | } | 505 | } |
493 | 506 | ||
494 | 507 | ||
@@ -499,7 +512,7 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband | |||
499 | "success" : "failure"); | 512 | "success" : "failure"); |
500 | iwl3945_collect_tx_data(rs_sta, | 513 | iwl3945_collect_tx_data(rs_sta, |
501 | &rs_sta->win[last_index], | 514 | &rs_sta->win[last_index], |
502 | info->flags & IEEE80211_TX_STAT_ACK, 1); | 515 | info->flags & IEEE80211_TX_STAT_ACK, 1, last_index); |
503 | 516 | ||
504 | /* We updated the rate scale window -- if its been more than | 517 | /* We updated the rate scale window -- if its been more than |
505 | * flush_time since the last run, schedule the flush | 518 | * flush_time since the last run, schedule the flush |
@@ -507,9 +520,10 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband | |||
507 | spin_lock_irqsave(&rs_sta->lock, flags); | 520 | spin_lock_irqsave(&rs_sta->lock, flags); |
508 | 521 | ||
509 | if (!rs_sta->flush_pending && | 522 | if (!rs_sta->flush_pending && |
510 | time_after(jiffies, rs_sta->last_partial_flush + | 523 | time_after(jiffies, rs_sta->last_flush + |
511 | rs_sta->flush_time)) { | 524 | rs_sta->flush_time)) { |
512 | 525 | ||
526 | rs_sta->last_partial_flush = jiffies; | ||
513 | rs_sta->flush_pending = 1; | 527 | rs_sta->flush_pending = 1; |
514 | mod_timer(&rs_sta->rate_scale_flush, | 528 | mod_timer(&rs_sta->rate_scale_flush, |
515 | jiffies + rs_sta->flush_time); | 529 | jiffies + rs_sta->flush_time); |
@@ -657,8 +671,13 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, | |||
657 | 671 | ||
658 | spin_lock_irqsave(&rs_sta->lock, flags); | 672 | spin_lock_irqsave(&rs_sta->lock, flags); |
659 | 673 | ||
674 | /* for recent assoc, choose best rate regarding | ||
675 | * to rssi value | ||
676 | */ | ||
660 | if (rs_sta->start_rate != IWL_RATE_INVALID) { | 677 | if (rs_sta->start_rate != IWL_RATE_INVALID) { |
661 | index = rs_sta->start_rate; | 678 | if (rs_sta->start_rate < index && |
679 | (rate_mask & (1 << rs_sta->start_rate))) | ||
680 | index = rs_sta->start_rate; | ||
662 | rs_sta->start_rate = IWL_RATE_INVALID; | 681 | rs_sta->start_rate = IWL_RATE_INVALID; |
663 | } | 682 | } |
664 | 683 | ||
@@ -668,7 +687,6 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, | |||
668 | 687 | ||
669 | if (((fail_count <= IWL_RATE_MIN_FAILURE_TH) && | 688 | if (((fail_count <= IWL_RATE_MIN_FAILURE_TH) && |
670 | (window->success_counter < IWL_RATE_MIN_SUCCESS_TH))) { | 689 | (window->success_counter < IWL_RATE_MIN_SUCCESS_TH))) { |
671 | window->average_tpt = IWL_INV_TPT; | ||
672 | spin_unlock_irqrestore(&rs_sta->lock, flags); | 690 | spin_unlock_irqrestore(&rs_sta->lock, flags); |
673 | 691 | ||
674 | IWL_DEBUG_RATE("Invalid average_tpt on rate %d: " | 692 | IWL_DEBUG_RATE("Invalid average_tpt on rate %d: " |
@@ -682,8 +700,6 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, | |||
682 | 700 | ||
683 | } | 701 | } |
684 | 702 | ||
685 | window->average_tpt = ((window->success_ratio * | ||
686 | rs_sta->expected_tpt[index] + 64) / 128); | ||
687 | current_tpt = window->average_tpt; | 703 | current_tpt = window->average_tpt; |
688 | 704 | ||
689 | high_low = iwl3945_get_adjacent_rate(rs_sta, index, rate_mask, | 705 | high_low = iwl3945_get_adjacent_rate(rs_sta, index, rate_mask, |
@@ -731,13 +747,15 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, | |||
731 | } | 747 | } |
732 | } | 748 | } |
733 | 749 | ||
734 | if ((window->success_ratio > IWL_RATE_HIGH_TH) || | 750 | if (scale_action == -1) { |
735 | (current_tpt > window->average_tpt)) { | 751 | if (window->success_ratio > IWL_SUCCESS_DOWN_TH) |
736 | IWL_DEBUG_RATE("No action -- success_ratio [%d] > HIGH_TH or " | 752 | scale_action = 0; |
737 | "current_tpt [%d] > average_tpt [%d]\n", | 753 | } else if (scale_action == 1) { |
738 | window->success_ratio, | 754 | if (window->success_ratio < IWL_SUCCESS_UP_TH) { |
739 | current_tpt, window->average_tpt); | 755 | IWL_DEBUG_RATE("No action -- success_ratio [%d] < " |
740 | scale_action = 0; | 756 | "SUCCESS UP\n", window->success_ratio); |
757 | scale_action = 0; | ||
758 | } | ||
741 | } | 759 | } |
742 | 760 | ||
743 | switch (scale_action) { | 761 | switch (scale_action) { |
@@ -772,6 +790,60 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, | |||
772 | IWL_DEBUG_RATE("leave: %d\n", index); | 790 | IWL_DEBUG_RATE("leave: %d\n", index); |
773 | } | 791 | } |
774 | 792 | ||
793 | #ifdef CONFIG_MAC80211_DEBUGFS | ||
794 | static int iwl3945_open_file_generic(struct inode *inode, struct file *file) | ||
795 | { | ||
796 | file->private_data = inode->i_private; | ||
797 | return 0; | ||
798 | } | ||
799 | |||
800 | static ssize_t iwl3945_sta_dbgfs_stats_table_read(struct file *file, | ||
801 | char __user *user_buf, | ||
802 | size_t count, loff_t *ppos) | ||
803 | { | ||
804 | char buff[1024]; | ||
805 | int desc = 0; | ||
806 | int j; | ||
807 | struct iwl3945_rs_sta *lq_sta = file->private_data; | ||
808 | |||
809 | desc += sprintf(buff + desc, "tx packets=%d last rate index=%d\n" | ||
810 | "rate=0x%X flush time %d\n", | ||
811 | lq_sta->tx_packets, | ||
812 | lq_sta->last_txrate_idx, | ||
813 | lq_sta->start_rate, jiffies_to_msecs(lq_sta->flush_time)); | ||
814 | for (j = 0; j < IWL_RATE_COUNT; j++) { | ||
815 | desc += sprintf(buff+desc, | ||
816 | "counter=%d success=%d %%=%d\n", | ||
817 | lq_sta->win[j].counter, | ||
818 | lq_sta->win[j].success_counter, | ||
819 | lq_sta->win[j].success_ratio); | ||
820 | } | ||
821 | return simple_read_from_buffer(user_buf, count, ppos, buff, desc); | ||
822 | } | ||
823 | |||
824 | static const struct file_operations rs_sta_dbgfs_stats_table_ops = { | ||
825 | .read = iwl3945_sta_dbgfs_stats_table_read, | ||
826 | .open = iwl3945_open_file_generic, | ||
827 | }; | ||
828 | |||
829 | static void iwl3945_add_debugfs(void *priv, void *priv_sta, | ||
830 | struct dentry *dir) | ||
831 | { | ||
832 | struct iwl3945_rs_sta *lq_sta = priv_sta; | ||
833 | |||
834 | lq_sta->rs_sta_dbgfs_stats_table_file = | ||
835 | debugfs_create_file("rate_stats_table", 0600, dir, | ||
836 | lq_sta, &rs_sta_dbgfs_stats_table_ops); | ||
837 | |||
838 | } | ||
839 | |||
840 | static void iwl3945_remove_debugfs(void *priv, void *priv_sta) | ||
841 | { | ||
842 | struct iwl3945_rs_sta *lq_sta = priv_sta; | ||
843 | debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file); | ||
844 | } | ||
845 | #endif | ||
846 | |||
775 | static struct rate_control_ops rs_ops = { | 847 | static struct rate_control_ops rs_ops = { |
776 | .module = NULL, | 848 | .module = NULL, |
777 | .name = RS_NAME, | 849 | .name = RS_NAME, |
@@ -782,6 +854,11 @@ static struct rate_control_ops rs_ops = { | |||
782 | .free = rs_free, | 854 | .free = rs_free, |
783 | .alloc_sta = rs_alloc_sta, | 855 | .alloc_sta = rs_alloc_sta, |
784 | .free_sta = rs_free_sta, | 856 | .free_sta = rs_free_sta, |
857 | #ifdef CONFIG_MAC80211_DEBUGFS | ||
858 | .add_sta_debugfs = iwl3945_add_debugfs, | ||
859 | .remove_sta_debugfs = iwl3945_remove_debugfs, | ||
860 | #endif | ||
861 | |||
785 | }; | 862 | }; |
786 | 863 | ||
787 | void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) | 864 | void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index af77ea70d737..4e6b7154c223 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -337,7 +337,7 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv, | |||
337 | struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; | 337 | struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; |
338 | u32 status = le32_to_cpu(tx_resp->status); | 338 | u32 status = le32_to_cpu(tx_resp->status); |
339 | int rate_idx; | 339 | int rate_idx; |
340 | int fail, i; | 340 | int fail; |
341 | 341 | ||
342 | if ((index >= txq->q.n_bd) || (iwl3945_x2_queue_used(&txq->q, index) == 0)) { | 342 | if ((index >= txq->q.n_bd) || (iwl3945_x2_queue_used(&txq->q, index) == 0)) { |
343 | IWL_ERROR("Read index for DMA queue txq_id (%d) index %d " | 343 | IWL_ERROR("Read index for DMA queue txq_id (%d) index %d " |
@@ -356,27 +356,9 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv, | |||
356 | rate_idx -= IWL_FIRST_OFDM_RATE; | 356 | rate_idx -= IWL_FIRST_OFDM_RATE; |
357 | 357 | ||
358 | fail = tx_resp->failure_frame; | 358 | fail = tx_resp->failure_frame; |
359 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { | ||
360 | int next = iwl3945_rs_next_rate(priv, rate_idx); | ||
361 | 359 | ||
362 | info->status.rates[i].idx = rate_idx; | 360 | info->status.rates[0].idx = rate_idx; |
363 | 361 | info->status.rates[0].count = fail + 1; /* add final attempt */ | |
364 | /* | ||
365 | * Put remaining into the last count as best approximation | ||
366 | * of saying exactly what the hardware would have done... | ||
367 | */ | ||
368 | if ((rate_idx == next) || (i == IEEE80211_TX_MAX_RATES - 1)) { | ||
369 | info->status.rates[i].count = fail; | ||
370 | break; | ||
371 | } | ||
372 | |||
373 | info->status.rates[i].count = priv->retry_rate; | ||
374 | fail -= priv->retry_rate; | ||
375 | rate_idx = next; | ||
376 | if (fail <= 0) | ||
377 | break; | ||
378 | } | ||
379 | info->status.rates[i].count++; /* add final attempt */ | ||
380 | 362 | ||
381 | /* tx_status->rts_retry_count = tx_resp->failure_rts; */ | 363 | /* tx_status->rts_retry_count = tx_resp->failure_rts; */ |
382 | info->flags |= ((status & TX_STATUS_MSK) == TX_STATUS_SUCCESS) ? | 364 | info->flags |= ((status & TX_STATUS_MSK) == TX_STATUS_SUCCESS) ? |
@@ -809,12 +791,19 @@ int iwl3945_hw_txq_free_tfd(struct iwl3945_priv *priv, struct iwl3945_tx_queue * | |||
809 | 791 | ||
810 | u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *addr) | 792 | u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *addr) |
811 | { | 793 | { |
812 | int i; | 794 | int i, start = IWL_AP_ID; |
813 | int ret = IWL_INVALID_STATION; | 795 | int ret = IWL_INVALID_STATION; |
814 | unsigned long flags; | 796 | unsigned long flags; |
815 | 797 | ||
798 | if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) || | ||
799 | (priv->iw_mode == NL80211_IFTYPE_AP)) | ||
800 | start = IWL_STA_ID; | ||
801 | |||
802 | if (is_broadcast_ether_addr(addr)) | ||
803 | return priv->hw_setting.bcast_sta_id; | ||
804 | |||
816 | spin_lock_irqsave(&priv->sta_lock, flags); | 805 | spin_lock_irqsave(&priv->sta_lock, flags); |
817 | for (i = IWL_STA_ID; i < priv->hw_setting.max_stations; i++) | 806 | for (i = start; i < priv->hw_setting.max_stations; i++) |
818 | if ((priv->stations[i].used) && | 807 | if ((priv->stations[i].used) && |
819 | (!compare_ether_addr | 808 | (!compare_ether_addr |
820 | (priv->stations[i].sta.sta.addr, addr))) { | 809 | (priv->stations[i].sta.sta.addr, addr))) { |
@@ -2519,13 +2508,17 @@ void iwl3945_hw_cancel_deferred_work(struct iwl3945_priv *priv) | |||
2519 | 2508 | ||
2520 | static struct iwl_3945_cfg iwl3945_bg_cfg = { | 2509 | static struct iwl_3945_cfg iwl3945_bg_cfg = { |
2521 | .name = "3945BG", | 2510 | .name = "3945BG", |
2522 | .fw_name = "iwlwifi-3945" IWL3945_UCODE_API ".ucode", | 2511 | .fw_name_pre = IWL3945_FW_PRE, |
2512 | .ucode_api_max = IWL3945_UCODE_API_MAX, | ||
2513 | .ucode_api_min = IWL3945_UCODE_API_MIN, | ||
2523 | .sku = IWL_SKU_G, | 2514 | .sku = IWL_SKU_G, |
2524 | }; | 2515 | }; |
2525 | 2516 | ||
2526 | static struct iwl_3945_cfg iwl3945_abg_cfg = { | 2517 | static struct iwl_3945_cfg iwl3945_abg_cfg = { |
2527 | .name = "3945ABG", | 2518 | .name = "3945ABG", |
2528 | .fw_name = "iwlwifi-3945" IWL3945_UCODE_API ".ucode", | 2519 | .fw_name_pre = IWL3945_FW_PRE, |
2520 | .ucode_api_max = IWL3945_UCODE_API_MAX, | ||
2521 | .ucode_api_min = IWL3945_UCODE_API_MIN, | ||
2529 | .sku = IWL_SKU_A|IWL_SKU_G, | 2522 | .sku = IWL_SKU_A|IWL_SKU_G, |
2530 | }; | 2523 | }; |
2531 | 2524 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index 2a924c10ff93..5c2c15e65a63 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h | |||
@@ -50,11 +50,15 @@ extern struct pci_device_id iwl3945_hw_card_ids[]; | |||
50 | #include "iwl-3945-debug.h" | 50 | #include "iwl-3945-debug.h" |
51 | #include "iwl-3945-led.h" | 51 | #include "iwl-3945-led.h" |
52 | 52 | ||
53 | /* Change firmware file name, using "-" and incrementing number, | 53 | /* Highest firmware API version supported */ |
54 | * *only* when uCode interface or architecture changes so that it | 54 | #define IWL3945_UCODE_API_MAX 2 |
55 | * is not compatible with earlier drivers. | 55 | |
56 | * This number will also appear in << 8 position of 1st dword of uCode file */ | 56 | /* Lowest firmware API version supported */ |
57 | #define IWL3945_UCODE_API "-1" | 57 | #define IWL3945_UCODE_API_MIN 1 |
58 | |||
59 | #define IWL3945_FW_PRE "iwlwifi-3945-" | ||
60 | #define _IWL3945_MODULE_FIRMWARE(api) IWL3945_FW_PRE #api ".ucode" | ||
61 | #define IWL3945_MODULE_FIRMWARE(api) _IWL3945_MODULE_FIRMWARE(api) | ||
58 | 62 | ||
59 | /* Default noise level to report when noise measurement is not available. | 63 | /* Default noise level to report when noise measurement is not available. |
60 | * This may be because we're: | 64 | * This may be because we're: |
@@ -505,7 +509,7 @@ struct fw_desc { | |||
505 | 509 | ||
506 | /* uCode file layout */ | 510 | /* uCode file layout */ |
507 | struct iwl3945_ucode { | 511 | struct iwl3945_ucode { |
508 | __le32 ver; /* major/minor/subminor */ | 512 | __le32 ver; /* major/minor/API/serial */ |
509 | __le32 inst_size; /* bytes of runtime instructions */ | 513 | __le32 inst_size; /* bytes of runtime instructions */ |
510 | __le32 data_size; /* bytes of runtime data */ | 514 | __le32 data_size; /* bytes of runtime data */ |
511 | __le32 init_size; /* bytes of initialization instructions */ | 515 | __le32 init_size; /* bytes of initialization instructions */ |
@@ -762,6 +766,8 @@ struct iwl3945_priv { | |||
762 | void __iomem *hw_base; | 766 | void __iomem *hw_base; |
763 | 767 | ||
764 | /* uCode images, save to reload in case of failure */ | 768 | /* uCode images, save to reload in case of failure */ |
769 | u32 ucode_ver; /* ucode version, copy of | ||
770 | iwl3945_ucode.ver */ | ||
765 | struct fw_desc ucode_code; /* runtime inst */ | 771 | struct fw_desc ucode_code; /* runtime inst */ |
766 | struct fw_desc ucode_data; /* runtime data original */ | 772 | struct fw_desc ucode_data; /* runtime data original */ |
767 | struct fw_desc ucode_data_backup; /* runtime data save/restore */ | 773 | struct fw_desc ucode_data_backup; /* runtime data save/restore */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index ab0b40531989..87c7bb0d5044 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -48,12 +48,15 @@ | |||
48 | static int iwl4965_send_tx_power(struct iwl_priv *priv); | 48 | static int iwl4965_send_tx_power(struct iwl_priv *priv); |
49 | static int iwl4965_hw_get_temperature(const struct iwl_priv *priv); | 49 | static int iwl4965_hw_get_temperature(const struct iwl_priv *priv); |
50 | 50 | ||
51 | /* Change firmware file name, using "-" and incrementing number, | 51 | /* Highest firmware API version supported */ |
52 | * *only* when uCode interface or architecture changes so that it | 52 | #define IWL4965_UCODE_API_MAX 2 |
53 | * is not compatible with earlier drivers. | 53 | |
54 | * This number will also appear in << 8 position of 1st dword of uCode file */ | 54 | /* Lowest firmware API version supported */ |
55 | #define IWL4965_UCODE_API "-2" | 55 | #define IWL4965_UCODE_API_MIN 2 |
56 | #define IWL4965_MODULE_FIRMWARE "iwlwifi-4965" IWL4965_UCODE_API ".ucode" | 56 | |
57 | #define IWL4965_FW_PRE "iwlwifi-4965-" | ||
58 | #define _IWL4965_MODULE_FIRMWARE(api) IWL4965_FW_PRE #api ".ucode" | ||
59 | #define IWL4965_MODULE_FIRMWARE(api) _IWL4965_MODULE_FIRMWARE(api) | ||
57 | 60 | ||
58 | 61 | ||
59 | /* module parameters */ | 62 | /* module parameters */ |
@@ -523,7 +526,7 @@ static void iwl4965_chain_noise_reset(struct iwl_priv *priv) | |||
523 | struct iwl_calib_diff_gain_cmd cmd; | 526 | struct iwl_calib_diff_gain_cmd cmd; |
524 | 527 | ||
525 | memset(&cmd, 0, sizeof(cmd)); | 528 | memset(&cmd, 0, sizeof(cmd)); |
526 | cmd.opCode = IWL_PHY_CALIBRATE_DIFF_GAIN_CMD; | 529 | cmd.hdr.op_code = IWL_PHY_CALIBRATE_DIFF_GAIN_CMD; |
527 | cmd.diff_gain_a = 0; | 530 | cmd.diff_gain_a = 0; |
528 | cmd.diff_gain_b = 0; | 531 | cmd.diff_gain_b = 0; |
529 | cmd.diff_gain_c = 0; | 532 | cmd.diff_gain_c = 0; |
@@ -574,7 +577,7 @@ static void iwl4965_gain_computation(struct iwl_priv *priv, | |||
574 | data->radio_write = 1; | 577 | data->radio_write = 1; |
575 | 578 | ||
576 | memset(&cmd, 0, sizeof(cmd)); | 579 | memset(&cmd, 0, sizeof(cmd)); |
577 | cmd.opCode = IWL_PHY_CALIBRATE_DIFF_GAIN_CMD; | 580 | cmd.hdr.op_code = IWL_PHY_CALIBRATE_DIFF_GAIN_CMD; |
578 | cmd.diff_gain_a = data->delta_gain_code[0]; | 581 | cmd.diff_gain_a = data->delta_gain_code[0]; |
579 | cmd.diff_gain_b = data->delta_gain_code[1]; | 582 | cmd.diff_gain_b = data->delta_gain_code[1]; |
580 | cmd.diff_gain_c = data->delta_gain_code[2]; | 583 | cmd.diff_gain_c = data->delta_gain_code[2]; |
@@ -816,6 +819,7 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv) | |||
816 | } | 819 | } |
817 | 820 | ||
818 | priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; | 821 | priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; |
822 | priv->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM; | ||
819 | priv->hw_params.scd_bc_tbls_size = | 823 | priv->hw_params.scd_bc_tbls_size = |
820 | IWL49_NUM_QUEUES * sizeof(struct iwl4965_scd_bc_tbl); | 824 | IWL49_NUM_QUEUES * sizeof(struct iwl4965_scd_bc_tbl); |
821 | priv->hw_params.max_stations = IWL4965_STATION_COUNT; | 825 | priv->hw_params.max_stations = IWL4965_STATION_COUNT; |
@@ -2335,7 +2339,9 @@ static struct iwl_ops iwl4965_ops = { | |||
2335 | 2339 | ||
2336 | struct iwl_cfg iwl4965_agn_cfg = { | 2340 | struct iwl_cfg iwl4965_agn_cfg = { |
2337 | .name = "4965AGN", | 2341 | .name = "4965AGN", |
2338 | .fw_name = IWL4965_MODULE_FIRMWARE, | 2342 | .fw_name_pre = IWL4965_FW_PRE, |
2343 | .ucode_api_max = IWL4965_UCODE_API_MAX, | ||
2344 | .ucode_api_min = IWL4965_UCODE_API_MIN, | ||
2339 | .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, | 2345 | .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, |
2340 | .eeprom_size = IWL4965_EEPROM_IMG_SIZE, | 2346 | .eeprom_size = IWL4965_EEPROM_IMG_SIZE, |
2341 | .eeprom_ver = EEPROM_4965_EEPROM_VERSION, | 2347 | .eeprom_ver = EEPROM_4965_EEPROM_VERSION, |
@@ -2345,7 +2351,7 @@ struct iwl_cfg iwl4965_agn_cfg = { | |||
2345 | }; | 2351 | }; |
2346 | 2352 | ||
2347 | /* Module firmware */ | 2353 | /* Module firmware */ |
2348 | MODULE_FIRMWARE(IWL4965_MODULE_FIRMWARE); | 2354 | MODULE_FIRMWARE(IWL4965_MODULE_FIRMWARE(IWL4965_UCODE_API_MAX)); |
2349 | 2355 | ||
2350 | module_param_named(antenna, iwl4965_mod_params.antenna, int, 0444); | 2356 | module_param_named(antenna, iwl4965_mod_params.antenna, int, 0444); |
2351 | MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])"); | 2357 | MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])"); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index a738886b434f..438e4bd0a9a8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -44,9 +44,21 @@ | |||
44 | #include "iwl-helpers.h" | 44 | #include "iwl-helpers.h" |
45 | #include "iwl-5000-hw.h" | 45 | #include "iwl-5000-hw.h" |
46 | 46 | ||
47 | #define IWL5000_UCODE_API "-1" | 47 | /* Highest firmware API version supported */ |
48 | #define IWL5000_UCODE_API_MAX 1 | ||
49 | #define IWL5150_UCODE_API_MAX 1 | ||
48 | 50 | ||
49 | #define IWL5000_MODULE_FIRMWARE "iwlwifi-5000" IWL5000_UCODE_API ".ucode" | 51 | /* Lowest firmware API version supported */ |
52 | #define IWL5000_UCODE_API_MIN 1 | ||
53 | #define IWL5150_UCODE_API_MIN 1 | ||
54 | |||
55 | #define IWL5000_FW_PRE "iwlwifi-5000-" | ||
56 | #define _IWL5000_MODULE_FIRMWARE(api) IWL5000_FW_PRE #api ".ucode" | ||
57 | #define IWL5000_MODULE_FIRMWARE(api) _IWL5000_MODULE_FIRMWARE(api) | ||
58 | |||
59 | #define IWL5150_FW_PRE "iwlwifi-5150-" | ||
60 | #define _IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE #api ".ucode" | ||
61 | #define IWL5150_MODULE_FIRMWARE(api) _IWL5150_MODULE_FIRMWARE(api) | ||
50 | 62 | ||
51 | static const u16 iwl5000_default_queue_to_tx_fifo[] = { | 63 | static const u16 iwl5000_default_queue_to_tx_fifo[] = { |
52 | IWL_TX_FIFO_AC3, | 64 | IWL_TX_FIFO_AC3, |
@@ -338,9 +350,13 @@ static void iwl5000_gain_computation(struct iwl_priv *priv, | |||
338 | 350 | ||
339 | if (!data->radio_write) { | 351 | if (!data->radio_write) { |
340 | struct iwl_calib_chain_noise_gain_cmd cmd; | 352 | struct iwl_calib_chain_noise_gain_cmd cmd; |
353 | |||
341 | memset(&cmd, 0, sizeof(cmd)); | 354 | memset(&cmd, 0, sizeof(cmd)); |
342 | 355 | ||
343 | cmd.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD; | 356 | cmd.hdr.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD; |
357 | cmd.hdr.first_group = 0; | ||
358 | cmd.hdr.groups_num = 1; | ||
359 | cmd.hdr.data_valid = 1; | ||
344 | cmd.delta_gain_1 = data->delta_gain_code[1]; | 360 | cmd.delta_gain_1 = data->delta_gain_code[1]; |
345 | cmd.delta_gain_2 = data->delta_gain_code[2]; | 361 | cmd.delta_gain_2 = data->delta_gain_code[2]; |
346 | iwl_send_cmd_pdu_async(priv, REPLY_PHY_CALIBRATION_CMD, | 362 | iwl_send_cmd_pdu_async(priv, REPLY_PHY_CALIBRATION_CMD, |
@@ -362,14 +378,19 @@ static void iwl5000_gain_computation(struct iwl_priv *priv, | |||
362 | static void iwl5000_chain_noise_reset(struct iwl_priv *priv) | 378 | static void iwl5000_chain_noise_reset(struct iwl_priv *priv) |
363 | { | 379 | { |
364 | struct iwl_chain_noise_data *data = &priv->chain_noise_data; | 380 | struct iwl_chain_noise_data *data = &priv->chain_noise_data; |
381 | int ret; | ||
365 | 382 | ||
366 | if ((data->state == IWL_CHAIN_NOISE_ALIVE) && iwl_is_associated(priv)) { | 383 | if ((data->state == IWL_CHAIN_NOISE_ALIVE) && iwl_is_associated(priv)) { |
367 | struct iwl_calib_chain_noise_reset_cmd cmd; | 384 | struct iwl_calib_chain_noise_reset_cmd cmd; |
368 | |||
369 | memset(&cmd, 0, sizeof(cmd)); | 385 | memset(&cmd, 0, sizeof(cmd)); |
370 | cmd.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD; | 386 | |
371 | if (iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, | 387 | cmd.hdr.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD; |
372 | sizeof(cmd), &cmd)) | 388 | cmd.hdr.first_group = 0; |
389 | cmd.hdr.groups_num = 1; | ||
390 | cmd.hdr.data_valid = 1; | ||
391 | ret = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, | ||
392 | sizeof(cmd), &cmd); | ||
393 | if (ret) | ||
373 | IWL_ERROR("Could not send REPLY_PHY_CALIBRATION_CMD\n"); | 394 | IWL_ERROR("Could not send REPLY_PHY_CALIBRATION_CMD\n"); |
374 | data->state = IWL_CHAIN_NOISE_ACCUMULATE; | 395 | data->state = IWL_CHAIN_NOISE_ACCUMULATE; |
375 | IWL_DEBUG_CALIB("Run chain_noise_calibrate\n"); | 396 | IWL_DEBUG_CALIB("Run chain_noise_calibrate\n"); |
@@ -415,22 +436,33 @@ static const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv, | |||
415 | return &priv->eeprom[address]; | 436 | return &priv->eeprom[address]; |
416 | } | 437 | } |
417 | 438 | ||
439 | static s32 iwl5150_get_ct_threshold(struct iwl_priv *priv) | ||
440 | { | ||
441 | const s32 volt2temp_coef = -5; | ||
442 | u16 *temp_calib = (u16 *)iwl_eeprom_query_addr(priv, | ||
443 | EEPROM_5000_TEMPERATURE); | ||
444 | /* offset = temperate - voltage / coef */ | ||
445 | s32 offset = temp_calib[0] - temp_calib[1] / volt2temp_coef; | ||
446 | s32 threshold = (s32)CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD) - offset; | ||
447 | return threshold * volt2temp_coef; | ||
448 | } | ||
449 | |||
418 | /* | 450 | /* |
419 | * Calibration | 451 | * Calibration |
420 | */ | 452 | */ |
421 | static int iwl5000_set_Xtal_calib(struct iwl_priv *priv) | 453 | static int iwl5000_set_Xtal_calib(struct iwl_priv *priv) |
422 | { | 454 | { |
423 | u8 data[sizeof(struct iwl_calib_hdr) + | 455 | struct iwl_calib_xtal_freq_cmd cmd; |
424 | sizeof(struct iwl_cal_xtal_freq)]; | ||
425 | struct iwl_calib_cmd *cmd = (struct iwl_calib_cmd *)data; | ||
426 | struct iwl_cal_xtal_freq *xtal = (struct iwl_cal_xtal_freq *)cmd->data; | ||
427 | u16 *xtal_calib = (u16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_XTAL); | 456 | u16 *xtal_calib = (u16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_XTAL); |
428 | 457 | ||
429 | cmd->hdr.op_code = IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD; | 458 | cmd.hdr.op_code = IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD; |
430 | xtal->cap_pin1 = (u8)xtal_calib[0]; | 459 | cmd.hdr.first_group = 0; |
431 | xtal->cap_pin2 = (u8)xtal_calib[1]; | 460 | cmd.hdr.groups_num = 1; |
461 | cmd.hdr.data_valid = 1; | ||
462 | cmd.cap_pin1 = (u8)xtal_calib[0]; | ||
463 | cmd.cap_pin2 = (u8)xtal_calib[1]; | ||
432 | return iwl_calib_set(&priv->calib_results[IWL_CALIB_XTAL], | 464 | return iwl_calib_set(&priv->calib_results[IWL_CALIB_XTAL], |
433 | data, sizeof(data)); | 465 | (u8 *)&cmd, sizeof(cmd)); |
434 | } | 466 | } |
435 | 467 | ||
436 | static int iwl5000_send_calib_cfg(struct iwl_priv *priv) | 468 | static int iwl5000_send_calib_cfg(struct iwl_priv *priv) |
@@ -466,6 +498,9 @@ static void iwl5000_rx_calib_result(struct iwl_priv *priv, | |||
466 | * uCode. iwl_send_calib_results sends them in a row according to their | 498 | * uCode. iwl_send_calib_results sends them in a row according to their |
467 | * index. We sort them here */ | 499 | * index. We sort them here */ |
468 | switch (hdr->op_code) { | 500 | switch (hdr->op_code) { |
501 | case IWL_PHY_CALIBRATE_DC_CMD: | ||
502 | index = IWL_CALIB_DC; | ||
503 | break; | ||
469 | case IWL_PHY_CALIBRATE_LO_CMD: | 504 | case IWL_PHY_CALIBRATE_LO_CMD: |
470 | index = IWL_CALIB_LO; | 505 | index = IWL_CALIB_LO; |
471 | break; | 506 | break; |
@@ -802,6 +837,7 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) | |||
802 | } | 837 | } |
803 | 838 | ||
804 | priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; | 839 | priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; |
840 | priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; | ||
805 | priv->hw_params.scd_bc_tbls_size = | 841 | priv->hw_params.scd_bc_tbls_size = |
806 | IWL50_NUM_QUEUES * sizeof(struct iwl5000_scd_bc_tbl); | 842 | IWL50_NUM_QUEUES * sizeof(struct iwl5000_scd_bc_tbl); |
807 | priv->hw_params.max_stations = IWL5000_STATION_COUNT; | 843 | priv->hw_params.max_stations = IWL5000_STATION_COUNT; |
@@ -845,7 +881,7 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) | |||
845 | case CSR_HW_REV_TYPE_5150: | 881 | case CSR_HW_REV_TYPE_5150: |
846 | /* 5150 wants in Kelvin */ | 882 | /* 5150 wants in Kelvin */ |
847 | priv->hw_params.ct_kill_threshold = | 883 | priv->hw_params.ct_kill_threshold = |
848 | CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD); | 884 | iwl5150_get_ct_threshold(priv); |
849 | break; | 885 | break; |
850 | } | 886 | } |
851 | 887 | ||
@@ -862,7 +898,12 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) | |||
862 | BIT(IWL_CALIB_BASE_BAND); | 898 | BIT(IWL_CALIB_BASE_BAND); |
863 | break; | 899 | break; |
864 | case CSR_HW_REV_TYPE_5150: | 900 | case CSR_HW_REV_TYPE_5150: |
865 | priv->hw_params.calib_init_cfg = 0; | 901 | priv->hw_params.calib_init_cfg = |
902 | BIT(IWL_CALIB_DC) | | ||
903 | BIT(IWL_CALIB_LO) | | ||
904 | BIT(IWL_CALIB_TX_IQ) | | ||
905 | BIT(IWL_CALIB_BASE_BAND); | ||
906 | |||
866 | break; | 907 | break; |
867 | } | 908 | } |
868 | 909 | ||
@@ -1501,7 +1542,9 @@ static struct iwl_mod_params iwl50_mod_params = { | |||
1501 | 1542 | ||
1502 | struct iwl_cfg iwl5300_agn_cfg = { | 1543 | struct iwl_cfg iwl5300_agn_cfg = { |
1503 | .name = "5300AGN", | 1544 | .name = "5300AGN", |
1504 | .fw_name = IWL5000_MODULE_FIRMWARE, | 1545 | .fw_name_pre = IWL5000_FW_PRE, |
1546 | .ucode_api_max = IWL5000_UCODE_API_MAX, | ||
1547 | .ucode_api_min = IWL5000_UCODE_API_MIN, | ||
1505 | .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, | 1548 | .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, |
1506 | .ops = &iwl5000_ops, | 1549 | .ops = &iwl5000_ops, |
1507 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, | 1550 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, |
@@ -1512,7 +1555,9 @@ struct iwl_cfg iwl5300_agn_cfg = { | |||
1512 | 1555 | ||
1513 | struct iwl_cfg iwl5100_bg_cfg = { | 1556 | struct iwl_cfg iwl5100_bg_cfg = { |
1514 | .name = "5100BG", | 1557 | .name = "5100BG", |
1515 | .fw_name = IWL5000_MODULE_FIRMWARE, | 1558 | .fw_name_pre = IWL5000_FW_PRE, |
1559 | .ucode_api_max = IWL5000_UCODE_API_MAX, | ||
1560 | .ucode_api_min = IWL5000_UCODE_API_MIN, | ||
1516 | .sku = IWL_SKU_G, | 1561 | .sku = IWL_SKU_G, |
1517 | .ops = &iwl5000_ops, | 1562 | .ops = &iwl5000_ops, |
1518 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, | 1563 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, |
@@ -1523,7 +1568,9 @@ struct iwl_cfg iwl5100_bg_cfg = { | |||
1523 | 1568 | ||
1524 | struct iwl_cfg iwl5100_abg_cfg = { | 1569 | struct iwl_cfg iwl5100_abg_cfg = { |
1525 | .name = "5100ABG", | 1570 | .name = "5100ABG", |
1526 | .fw_name = IWL5000_MODULE_FIRMWARE, | 1571 | .fw_name_pre = IWL5000_FW_PRE, |
1572 | .ucode_api_max = IWL5000_UCODE_API_MAX, | ||
1573 | .ucode_api_min = IWL5000_UCODE_API_MIN, | ||
1527 | .sku = IWL_SKU_A|IWL_SKU_G, | 1574 | .sku = IWL_SKU_A|IWL_SKU_G, |
1528 | .ops = &iwl5000_ops, | 1575 | .ops = &iwl5000_ops, |
1529 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, | 1576 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, |
@@ -1534,7 +1581,9 @@ struct iwl_cfg iwl5100_abg_cfg = { | |||
1534 | 1581 | ||
1535 | struct iwl_cfg iwl5100_agn_cfg = { | 1582 | struct iwl_cfg iwl5100_agn_cfg = { |
1536 | .name = "5100AGN", | 1583 | .name = "5100AGN", |
1537 | .fw_name = IWL5000_MODULE_FIRMWARE, | 1584 | .fw_name_pre = IWL5000_FW_PRE, |
1585 | .ucode_api_max = IWL5000_UCODE_API_MAX, | ||
1586 | .ucode_api_min = IWL5000_UCODE_API_MIN, | ||
1538 | .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, | 1587 | .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, |
1539 | .ops = &iwl5000_ops, | 1588 | .ops = &iwl5000_ops, |
1540 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, | 1589 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, |
@@ -1545,7 +1594,22 @@ struct iwl_cfg iwl5100_agn_cfg = { | |||
1545 | 1594 | ||
1546 | struct iwl_cfg iwl5350_agn_cfg = { | 1595 | struct iwl_cfg iwl5350_agn_cfg = { |
1547 | .name = "5350AGN", | 1596 | .name = "5350AGN", |
1548 | .fw_name = IWL5000_MODULE_FIRMWARE, | 1597 | .fw_name_pre = IWL5000_FW_PRE, |
1598 | .ucode_api_max = IWL5000_UCODE_API_MAX, | ||
1599 | .ucode_api_min = IWL5000_UCODE_API_MIN, | ||
1600 | .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, | ||
1601 | .ops = &iwl5000_ops, | ||
1602 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, | ||
1603 | .eeprom_ver = EEPROM_5050_EEPROM_VERSION, | ||
1604 | .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, | ||
1605 | .mod_params = &iwl50_mod_params, | ||
1606 | }; | ||
1607 | |||
1608 | struct iwl_cfg iwl5150_agn_cfg = { | ||
1609 | .name = "5150AGN", | ||
1610 | .fw_name_pre = IWL5150_FW_PRE, | ||
1611 | .ucode_api_max = IWL5150_UCODE_API_MAX, | ||
1612 | .ucode_api_min = IWL5150_UCODE_API_MIN, | ||
1549 | .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, | 1613 | .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, |
1550 | .ops = &iwl5000_ops, | 1614 | .ops = &iwl5000_ops, |
1551 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, | 1615 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, |
@@ -1554,7 +1618,8 @@ struct iwl_cfg iwl5350_agn_cfg = { | |||
1554 | .mod_params = &iwl50_mod_params, | 1618 | .mod_params = &iwl50_mod_params, |
1555 | }; | 1619 | }; |
1556 | 1620 | ||
1557 | MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE); | 1621 | MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); |
1622 | MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_MAX)); | ||
1558 | 1623 | ||
1559 | module_param_named(disable50, iwl50_mod_params.disable, int, 0444); | 1624 | module_param_named(disable50, iwl50_mod_params.disable, int, 0444); |
1560 | MODULE_PARM_DESC(disable50, | 1625 | MODULE_PARM_DESC(disable50, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd-check.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd-check.c new file mode 100644 index 000000000000..c50494a74f67 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd-check.c | |||
@@ -0,0 +1,108 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * GPL LICENSE SUMMARY | ||
4 | * | ||
5 | * Copyright(c) 2008 Intel Corporation. All rights reserved. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of version 2 of the GNU General Public License as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | ||
19 | * USA | ||
20 | * | ||
21 | * The full GNU General Public License is included in this distribution | ||
22 | * in the file called LICENSE.GPL. | ||
23 | * | ||
24 | * Contact Information: | ||
25 | * Tomas Winkler <tomas.winkler@intel.com> | ||
26 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
27 | *****************************************************************************/ | ||
28 | |||
29 | #include <linux/kernel.h> | ||
30 | #include <net/mac80211.h> | ||
31 | #include "iwl-dev.h" | ||
32 | #include "iwl-debug.h" | ||
33 | #include "iwl-commands.h" | ||
34 | |||
35 | |||
36 | /** | ||
37 | * iwl_check_rxon_cmd - validate RXON structure is valid | ||
38 | * | ||
39 | * NOTE: This is really only useful during development and can eventually | ||
40 | * be #ifdef'd out once the driver is stable and folks aren't actively | ||
41 | * making changes | ||
42 | */ | ||
43 | int iwl_agn_check_rxon_cmd(struct iwl_rxon_cmd *rxon) | ||
44 | { | ||
45 | int error = 0; | ||
46 | int counter = 1; | ||
47 | |||
48 | if (rxon->flags & RXON_FLG_BAND_24G_MSK) { | ||
49 | error |= le32_to_cpu(rxon->flags & | ||
50 | (RXON_FLG_TGJ_NARROW_BAND_MSK | | ||
51 | RXON_FLG_RADAR_DETECT_MSK)); | ||
52 | if (error) | ||
53 | IWL_WARNING("check 24G fields %d | %d\n", | ||
54 | counter++, error); | ||
55 | } else { | ||
56 | error |= (rxon->flags & RXON_FLG_SHORT_SLOT_MSK) ? | ||
57 | 0 : le32_to_cpu(RXON_FLG_SHORT_SLOT_MSK); | ||
58 | if (error) | ||
59 | IWL_WARNING("check 52 fields %d | %d\n", | ||
60 | counter++, error); | ||
61 | error |= le32_to_cpu(rxon->flags & RXON_FLG_CCK_MSK); | ||
62 | if (error) | ||
63 | IWL_WARNING("check 52 CCK %d | %d\n", | ||
64 | counter++, error); | ||
65 | } | ||
66 | error |= (rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1; | ||
67 | if (error) | ||
68 | IWL_WARNING("check mac addr %d | %d\n", counter++, error); | ||
69 | |||
70 | /* make sure basic rates 6Mbps and 1Mbps are supported */ | ||
71 | error |= (((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0) && | ||
72 | ((rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0)); | ||
73 | if (error) | ||
74 | IWL_WARNING("check basic rate %d | %d\n", counter++, error); | ||
75 | |||
76 | error |= (le16_to_cpu(rxon->assoc_id) > 2007); | ||
77 | if (error) | ||
78 | IWL_WARNING("check assoc id %d | %d\n", counter++, error); | ||
79 | |||
80 | error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) | ||
81 | == (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)); | ||
82 | if (error) | ||
83 | IWL_WARNING("check CCK and short slot %d | %d\n", | ||
84 | counter++, error); | ||
85 | |||
86 | error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) | ||
87 | == (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)); | ||
88 | if (error) | ||
89 | IWL_WARNING("check CCK & auto detect %d | %d\n", | ||
90 | counter++, error); | ||
91 | |||
92 | error |= ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK | | ||
93 | RXON_FLG_TGG_PROTECT_MSK)) == RXON_FLG_TGG_PROTECT_MSK); | ||
94 | if (error) | ||
95 | IWL_WARNING("check TGG and auto detect %d | %d\n", | ||
96 | counter++, error); | ||
97 | |||
98 | if (error) | ||
99 | IWL_WARNING("Tuning to channel %d\n", | ||
100 | le16_to_cpu(rxon->channel)); | ||
101 | |||
102 | if (error) { | ||
103 | IWL_ERROR("Not a valid iwl4965_rxon_assoc_cmd field values\n"); | ||
104 | return -1; | ||
105 | } | ||
106 | return 0; | ||
107 | } | ||
108 | |||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 7888250117dc..b3c263d2724f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -108,79 +108,6 @@ static void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt) | |||
108 | } | 108 | } |
109 | 109 | ||
110 | /** | 110 | /** |
111 | * iwl_check_rxon_cmd - validate RXON structure is valid | ||
112 | * | ||
113 | * NOTE: This is really only useful during development and can eventually | ||
114 | * be #ifdef'd out once the driver is stable and folks aren't actively | ||
115 | * making changes | ||
116 | */ | ||
117 | static int iwl_check_rxon_cmd(struct iwl_rxon_cmd *rxon) | ||
118 | { | ||
119 | int error = 0; | ||
120 | int counter = 1; | ||
121 | |||
122 | if (rxon->flags & RXON_FLG_BAND_24G_MSK) { | ||
123 | error |= le32_to_cpu(rxon->flags & | ||
124 | (RXON_FLG_TGJ_NARROW_BAND_MSK | | ||
125 | RXON_FLG_RADAR_DETECT_MSK)); | ||
126 | if (error) | ||
127 | IWL_WARNING("check 24G fields %d | %d\n", | ||
128 | counter++, error); | ||
129 | } else { | ||
130 | error |= (rxon->flags & RXON_FLG_SHORT_SLOT_MSK) ? | ||
131 | 0 : le32_to_cpu(RXON_FLG_SHORT_SLOT_MSK); | ||
132 | if (error) | ||
133 | IWL_WARNING("check 52 fields %d | %d\n", | ||
134 | counter++, error); | ||
135 | error |= le32_to_cpu(rxon->flags & RXON_FLG_CCK_MSK); | ||
136 | if (error) | ||
137 | IWL_WARNING("check 52 CCK %d | %d\n", | ||
138 | counter++, error); | ||
139 | } | ||
140 | error |= (rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1; | ||
141 | if (error) | ||
142 | IWL_WARNING("check mac addr %d | %d\n", counter++, error); | ||
143 | |||
144 | /* make sure basic rates 6Mbps and 1Mbps are supported */ | ||
145 | error |= (((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0) && | ||
146 | ((rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0)); | ||
147 | if (error) | ||
148 | IWL_WARNING("check basic rate %d | %d\n", counter++, error); | ||
149 | |||
150 | error |= (le16_to_cpu(rxon->assoc_id) > 2007); | ||
151 | if (error) | ||
152 | IWL_WARNING("check assoc id %d | %d\n", counter++, error); | ||
153 | |||
154 | error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) | ||
155 | == (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)); | ||
156 | if (error) | ||
157 | IWL_WARNING("check CCK and short slot %d | %d\n", | ||
158 | counter++, error); | ||
159 | |||
160 | error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) | ||
161 | == (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)); | ||
162 | if (error) | ||
163 | IWL_WARNING("check CCK & auto detect %d | %d\n", | ||
164 | counter++, error); | ||
165 | |||
166 | error |= ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK | | ||
167 | RXON_FLG_TGG_PROTECT_MSK)) == RXON_FLG_TGG_PROTECT_MSK); | ||
168 | if (error) | ||
169 | IWL_WARNING("check TGG and auto detect %d | %d\n", | ||
170 | counter++, error); | ||
171 | |||
172 | if (error) | ||
173 | IWL_WARNING("Tuning to channel %d\n", | ||
174 | le16_to_cpu(rxon->channel)); | ||
175 | |||
176 | if (error) { | ||
177 | IWL_ERROR("Not a valid iwl_rxon_assoc_cmd field values\n"); | ||
178 | return -1; | ||
179 | } | ||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | /** | ||
184 | * iwl_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed | 111 | * iwl_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed |
185 | * @priv: staging_rxon is compared to active_rxon | 112 | * @priv: staging_rxon is compared to active_rxon |
186 | * | 113 | * |
@@ -252,7 +179,7 @@ static int iwl_commit_rxon(struct iwl_priv *priv) | |||
252 | * 5000, but will not damage 4965 */ | 179 | * 5000, but will not damage 4965 */ |
253 | priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN; | 180 | priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN; |
254 | 181 | ||
255 | ret = iwl_check_rxon_cmd(&priv->staging_rxon); | 182 | ret = iwl_agn_check_rxon_cmd(&priv->staging_rxon); |
256 | if (ret) { | 183 | if (ret) { |
257 | IWL_ERROR("Invalid RXON configuration. Not committing.\n"); | 184 | IWL_ERROR("Invalid RXON configuration. Not committing.\n"); |
258 | return -EINVAL; | 185 | return -EINVAL; |
@@ -1328,13 +1255,6 @@ static void iwl_print_rx_config_cmd(struct iwl_priv *priv) | |||
1328 | } | 1255 | } |
1329 | #endif | 1256 | #endif |
1330 | 1257 | ||
1331 | static void iwl_enable_interrupts(struct iwl_priv *priv) | ||
1332 | { | ||
1333 | IWL_DEBUG_ISR("Enabling interrupts\n"); | ||
1334 | set_bit(STATUS_INT_ENABLED, &priv->status); | ||
1335 | iwl_write32(priv, CSR_INT_MASK, CSR_INI_SET_MASK); | ||
1336 | } | ||
1337 | |||
1338 | /* call this function to flush any scheduled tasklet */ | 1258 | /* call this function to flush any scheduled tasklet */ |
1339 | static inline void iwl_synchronize_irq(struct iwl_priv *priv) | 1259 | static inline void iwl_synchronize_irq(struct iwl_priv *priv) |
1340 | { | 1260 | { |
@@ -1343,21 +1263,6 @@ static inline void iwl_synchronize_irq(struct iwl_priv *priv) | |||
1343 | tasklet_kill(&priv->irq_tasklet); | 1263 | tasklet_kill(&priv->irq_tasklet); |
1344 | } | 1264 | } |
1345 | 1265 | ||
1346 | static inline void iwl_disable_interrupts(struct iwl_priv *priv) | ||
1347 | { | ||
1348 | clear_bit(STATUS_INT_ENABLED, &priv->status); | ||
1349 | |||
1350 | /* disable interrupts from uCode/NIC to host */ | ||
1351 | iwl_write32(priv, CSR_INT_MASK, 0x00000000); | ||
1352 | |||
1353 | /* acknowledge/clear/reset any interrupts still pending | ||
1354 | * from uCode or flow handler (Rx/Tx DMA) */ | ||
1355 | iwl_write32(priv, CSR_INT, 0xffffffff); | ||
1356 | iwl_write32(priv, CSR_FH_INT_STATUS, 0xffffffff); | ||
1357 | IWL_DEBUG_ISR("Disabled interrupts\n"); | ||
1358 | } | ||
1359 | |||
1360 | |||
1361 | /** | 1266 | /** |
1362 | * iwl_irq_handle_error - called for HW or SW error interrupt from card | 1267 | * iwl_irq_handle_error - called for HW or SW error interrupt from card |
1363 | */ | 1268 | */ |
@@ -1608,7 +1513,7 @@ static irqreturn_t iwl_isr(int irq, void *data) | |||
1608 | if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) { | 1513 | if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) { |
1609 | /* Hardware disappeared. It might have already raised | 1514 | /* Hardware disappeared. It might have already raised |
1610 | * an interrupt */ | 1515 | * an interrupt */ |
1611 | IWL_WARNING("HARDWARE GONE?? INTA == 0x%080x\n", inta); | 1516 | IWL_WARNING("HARDWARE GONE?? INTA == 0x%08x\n", inta); |
1612 | goto unplugged; | 1517 | goto unplugged; |
1613 | } | 1518 | } |
1614 | 1519 | ||
@@ -1665,24 +1570,40 @@ static void iwl_nic_start(struct iwl_priv *priv) | |||
1665 | static int iwl_read_ucode(struct iwl_priv *priv) | 1570 | static int iwl_read_ucode(struct iwl_priv *priv) |
1666 | { | 1571 | { |
1667 | struct iwl_ucode *ucode; | 1572 | struct iwl_ucode *ucode; |
1668 | int ret; | 1573 | int ret = -EINVAL, index; |
1669 | const struct firmware *ucode_raw; | 1574 | const struct firmware *ucode_raw; |
1670 | const char *name = priv->cfg->fw_name; | 1575 | const char *name_pre = priv->cfg->fw_name_pre; |
1576 | const unsigned int api_max = priv->cfg->ucode_api_max; | ||
1577 | const unsigned int api_min = priv->cfg->ucode_api_min; | ||
1578 | char buf[25]; | ||
1671 | u8 *src; | 1579 | u8 *src; |
1672 | size_t len; | 1580 | size_t len; |
1673 | u32 ver, inst_size, data_size, init_size, init_data_size, boot_size; | 1581 | u32 api_ver, inst_size, data_size, init_size, init_data_size, boot_size; |
1674 | 1582 | ||
1675 | /* Ask kernel firmware_class module to get the boot firmware off disk. | 1583 | /* Ask kernel firmware_class module to get the boot firmware off disk. |
1676 | * request_firmware() is synchronous, file is in memory on return. */ | 1584 | * request_firmware() is synchronous, file is in memory on return. */ |
1677 | ret = request_firmware(&ucode_raw, name, &priv->pci_dev->dev); | 1585 | for (index = api_max; index >= api_min; index--) { |
1678 | if (ret < 0) { | 1586 | sprintf(buf, "%s%d%s", name_pre, index, ".ucode"); |
1679 | IWL_ERROR("%s firmware file req failed: Reason %d\n", | 1587 | ret = request_firmware(&ucode_raw, buf, &priv->pci_dev->dev); |
1680 | name, ret); | 1588 | if (ret < 0) { |
1681 | goto error; | 1589 | IWL_ERROR("%s firmware file req failed: Reason %d\n", |
1590 | buf, ret); | ||
1591 | if (ret == -ENOENT) | ||
1592 | continue; | ||
1593 | else | ||
1594 | goto error; | ||
1595 | } else { | ||
1596 | if (index < api_max) | ||
1597 | IWL_ERROR("Loaded firmware %s, which is deprecated. Please use API v%u instead.\n", | ||
1598 | buf, api_max); | ||
1599 | IWL_DEBUG_INFO("Got firmware '%s' file (%zd bytes) from disk\n", | ||
1600 | buf, ucode_raw->size); | ||
1601 | break; | ||
1602 | } | ||
1682 | } | 1603 | } |
1683 | 1604 | ||
1684 | IWL_DEBUG_INFO("Got firmware '%s' file (%zd bytes) from disk\n", | 1605 | if (ret < 0) |
1685 | name, ucode_raw->size); | 1606 | goto error; |
1686 | 1607 | ||
1687 | /* Make sure that we got at least our header! */ | 1608 | /* Make sure that we got at least our header! */ |
1688 | if (ucode_raw->size < sizeof(*ucode)) { | 1609 | if (ucode_raw->size < sizeof(*ucode)) { |
@@ -1694,14 +1615,40 @@ static int iwl_read_ucode(struct iwl_priv *priv) | |||
1694 | /* Data from ucode file: header followed by uCode images */ | 1615 | /* Data from ucode file: header followed by uCode images */ |
1695 | ucode = (void *)ucode_raw->data; | 1616 | ucode = (void *)ucode_raw->data; |
1696 | 1617 | ||
1697 | ver = le32_to_cpu(ucode->ver); | 1618 | priv->ucode_ver = le32_to_cpu(ucode->ver); |
1619 | api_ver = IWL_UCODE_API(priv->ucode_ver); | ||
1698 | inst_size = le32_to_cpu(ucode->inst_size); | 1620 | inst_size = le32_to_cpu(ucode->inst_size); |
1699 | data_size = le32_to_cpu(ucode->data_size); | 1621 | data_size = le32_to_cpu(ucode->data_size); |
1700 | init_size = le32_to_cpu(ucode->init_size); | 1622 | init_size = le32_to_cpu(ucode->init_size); |
1701 | init_data_size = le32_to_cpu(ucode->init_data_size); | 1623 | init_data_size = le32_to_cpu(ucode->init_data_size); |
1702 | boot_size = le32_to_cpu(ucode->boot_size); | 1624 | boot_size = le32_to_cpu(ucode->boot_size); |
1703 | 1625 | ||
1704 | IWL_DEBUG_INFO("f/w package hdr ucode version = 0x%x\n", ver); | 1626 | /* api_ver should match the api version forming part of the |
1627 | * firmware filename ... but we don't check for that and only rely | ||
1628 | * on the API version read from firware header from here on forward */ | ||
1629 | |||
1630 | if (api_ver < api_min || api_ver > api_max) { | ||
1631 | IWL_ERROR("Driver unable to support your firmware API. " | ||
1632 | "Driver supports v%u, firmware is v%u.\n", | ||
1633 | api_max, api_ver); | ||
1634 | priv->ucode_ver = 0; | ||
1635 | ret = -EINVAL; | ||
1636 | goto err_release; | ||
1637 | } | ||
1638 | if (api_ver != api_max) | ||
1639 | IWL_ERROR("Firmware has old API version. Expected v%u, " | ||
1640 | "got v%u. New firmware can be obtained " | ||
1641 | "from http://www.intellinuxwireless.org.\n", | ||
1642 | api_max, api_ver); | ||
1643 | |||
1644 | printk(KERN_INFO DRV_NAME " loaded firmware version %u.%u.%u.%u\n", | ||
1645 | IWL_UCODE_MAJOR(priv->ucode_ver), | ||
1646 | IWL_UCODE_MINOR(priv->ucode_ver), | ||
1647 | IWL_UCODE_API(priv->ucode_ver), | ||
1648 | IWL_UCODE_SERIAL(priv->ucode_ver)); | ||
1649 | |||
1650 | IWL_DEBUG_INFO("f/w package hdr ucode version raw = 0x%x\n", | ||
1651 | priv->ucode_ver); | ||
1705 | IWL_DEBUG_INFO("f/w package hdr runtime inst size = %u\n", | 1652 | IWL_DEBUG_INFO("f/w package hdr runtime inst size = %u\n", |
1706 | inst_size); | 1653 | inst_size); |
1707 | IWL_DEBUG_INFO("f/w package hdr runtime data size = %u\n", | 1654 | IWL_DEBUG_INFO("f/w package hdr runtime data size = %u\n", |
@@ -3675,68 +3622,6 @@ static ssize_t show_power_level(struct device *d, | |||
3675 | static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level, | 3622 | static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level, |
3676 | store_power_level); | 3623 | store_power_level); |
3677 | 3624 | ||
3678 | static ssize_t show_channels(struct device *d, | ||
3679 | struct device_attribute *attr, char *buf) | ||
3680 | { | ||
3681 | |||
3682 | struct iwl_priv *priv = dev_get_drvdata(d); | ||
3683 | struct ieee80211_channel *channels = NULL; | ||
3684 | const struct ieee80211_supported_band *supp_band = NULL; | ||
3685 | int len = 0, i; | ||
3686 | int count = 0; | ||
3687 | |||
3688 | if (!test_bit(STATUS_GEO_CONFIGURED, &priv->status)) | ||
3689 | return -EAGAIN; | ||
3690 | |||
3691 | supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_2GHZ); | ||
3692 | channels = supp_band->channels; | ||
3693 | count = supp_band->n_channels; | ||
3694 | |||
3695 | len += sprintf(&buf[len], | ||
3696 | "Displaying %d channels in 2.4GHz band " | ||
3697 | "(802.11bg):\n", count); | ||
3698 | |||
3699 | for (i = 0; i < count; i++) | ||
3700 | len += sprintf(&buf[len], "%d: %ddBm: BSS%s%s, %s.\n", | ||
3701 | ieee80211_frequency_to_channel( | ||
3702 | channels[i].center_freq), | ||
3703 | channels[i].max_power, | ||
3704 | channels[i].flags & IEEE80211_CHAN_RADAR ? | ||
3705 | " (IEEE 802.11h required)" : "", | ||
3706 | (!(channels[i].flags & IEEE80211_CHAN_NO_IBSS) | ||
3707 | || (channels[i].flags & | ||
3708 | IEEE80211_CHAN_RADAR)) ? "" : | ||
3709 | ", IBSS", | ||
3710 | channels[i].flags & | ||
3711 | IEEE80211_CHAN_PASSIVE_SCAN ? | ||
3712 | "passive only" : "active/passive"); | ||
3713 | |||
3714 | supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_5GHZ); | ||
3715 | channels = supp_band->channels; | ||
3716 | count = supp_band->n_channels; | ||
3717 | |||
3718 | len += sprintf(&buf[len], "Displaying %d channels in 5.2GHz band " | ||
3719 | "(802.11a):\n", count); | ||
3720 | |||
3721 | for (i = 0; i < count; i++) | ||
3722 | len += sprintf(&buf[len], "%d: %ddBm: BSS%s%s, %s.\n", | ||
3723 | ieee80211_frequency_to_channel( | ||
3724 | channels[i].center_freq), | ||
3725 | channels[i].max_power, | ||
3726 | channels[i].flags & IEEE80211_CHAN_RADAR ? | ||
3727 | " (IEEE 802.11h required)" : "", | ||
3728 | ((channels[i].flags & IEEE80211_CHAN_NO_IBSS) | ||
3729 | || (channels[i].flags & | ||
3730 | IEEE80211_CHAN_RADAR)) ? "" : | ||
3731 | ", IBSS", | ||
3732 | channels[i].flags & | ||
3733 | IEEE80211_CHAN_PASSIVE_SCAN ? | ||
3734 | "passive only" : "active/passive"); | ||
3735 | |||
3736 | return len; | ||
3737 | } | ||
3738 | |||
3739 | static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL); | ||
3740 | 3625 | ||
3741 | static ssize_t show_statistics(struct device *d, | 3626 | static ssize_t show_statistics(struct device *d, |
3742 | struct device_attribute *attr, char *buf) | 3627 | struct device_attribute *attr, char *buf) |
@@ -3836,7 +3721,6 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv) | |||
3836 | } | 3721 | } |
3837 | 3722 | ||
3838 | static struct attribute *iwl_sysfs_entries[] = { | 3723 | static struct attribute *iwl_sysfs_entries[] = { |
3839 | &dev_attr_channels.attr, | ||
3840 | &dev_attr_flags.attr, | 3724 | &dev_attr_flags.attr, |
3841 | &dev_attr_filter_flags.attr, | 3725 | &dev_attr_filter_flags.attr, |
3842 | &dev_attr_power_level.attr, | 3726 | &dev_attr_power_level.attr, |
@@ -4210,7 +4094,11 @@ static struct pci_device_id iwl_hw_card_ids[] = { | |||
4210 | {IWL_PCI_DEVICE(0x423A, 0x1001, iwl5350_agn_cfg)}, | 4094 | {IWL_PCI_DEVICE(0x423A, 0x1001, iwl5350_agn_cfg)}, |
4211 | {IWL_PCI_DEVICE(0x423A, 0x1021, iwl5350_agn_cfg)}, | 4095 | {IWL_PCI_DEVICE(0x423A, 0x1021, iwl5350_agn_cfg)}, |
4212 | {IWL_PCI_DEVICE(0x423B, 0x1011, iwl5350_agn_cfg)}, | 4096 | {IWL_PCI_DEVICE(0x423B, 0x1011, iwl5350_agn_cfg)}, |
4097 | /* 5150 Wifi/WiMax */ | ||
4098 | {IWL_PCI_DEVICE(0x423C, PCI_ANY_ID, iwl5150_agn_cfg)}, | ||
4099 | {IWL_PCI_DEVICE(0x423D, PCI_ANY_ID, iwl5150_agn_cfg)}, | ||
4213 | #endif /* CONFIG_IWL5000 */ | 4100 | #endif /* CONFIG_IWL5000 */ |
4101 | |||
4214 | {0} | 4102 | {0} |
4215 | }; | 4103 | }; |
4216 | MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); | 4104 | MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 1fe83d45443a..528bcab49d13 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h | |||
@@ -69,6 +69,12 @@ | |||
69 | #ifndef __iwl_commands_h__ | 69 | #ifndef __iwl_commands_h__ |
70 | #define __iwl_commands_h__ | 70 | #define __iwl_commands_h__ |
71 | 71 | ||
72 | /* uCode version contains 4 values: Major/Minor/API/Serial */ | ||
73 | #define IWL_UCODE_MAJOR(ver) (((ver) & 0xFF000000) >> 24) | ||
74 | #define IWL_UCODE_MINOR(ver) (((ver) & 0x00FF0000) >> 16) | ||
75 | #define IWL_UCODE_API(ver) (((ver) & 0x0000FF00) >> 8) | ||
76 | #define IWL_UCODE_SERIAL(ver) ((ver) & 0x000000FF) | ||
77 | |||
72 | enum { | 78 | enum { |
73 | REPLY_ALIVE = 0x1, | 79 | REPLY_ALIVE = 0x1, |
74 | REPLY_ERROR = 0x2, | 80 | REPLY_ERROR = 0x2, |
@@ -172,8 +178,8 @@ enum { | |||
172 | #define QUEUE_TO_SEQ(q) (((q) & 0x1f) << 8) | 178 | #define QUEUE_TO_SEQ(q) (((q) & 0x1f) << 8) |
173 | #define SEQ_TO_INDEX(s) ((s) & 0xff) | 179 | #define SEQ_TO_INDEX(s) ((s) & 0xff) |
174 | #define INDEX_TO_SEQ(i) ((i) & 0xff) | 180 | #define INDEX_TO_SEQ(i) ((i) & 0xff) |
175 | #define SEQ_HUGE_FRAME __constant_cpu_to_le16(0x4000) | 181 | #define SEQ_HUGE_FRAME cpu_to_le16(0x4000) |
176 | #define SEQ_RX_FRAME __constant_cpu_to_le16(0x8000) | 182 | #define SEQ_RX_FRAME cpu_to_le16(0x8000) |
177 | 183 | ||
178 | /** | 184 | /** |
179 | * struct iwl_cmd_header | 185 | * struct iwl_cmd_header |
@@ -368,7 +374,7 @@ struct iwl5000_tx_power_dbm_cmd { | |||
368 | * | 374 | * |
369 | *****************************************************************************/ | 375 | *****************************************************************************/ |
370 | 376 | ||
371 | #define UCODE_VALID_OK __constant_cpu_to_le32(0x1) | 377 | #define UCODE_VALID_OK cpu_to_le32(0x1) |
372 | #define INITIALIZE_SUBTYPE (9) | 378 | #define INITIALIZE_SUBTYPE (9) |
373 | 379 | ||
374 | /* | 380 | /* |
@@ -517,75 +523,75 @@ enum { | |||
517 | }; | 523 | }; |
518 | 524 | ||
519 | 525 | ||
520 | #define RXON_RX_CHAIN_DRIVER_FORCE_MSK __constant_cpu_to_le16(0x1 << 0) | 526 | #define RXON_RX_CHAIN_DRIVER_FORCE_MSK cpu_to_le16(0x1 << 0) |
521 | #define RXON_RX_CHAIN_VALID_MSK __constant_cpu_to_le16(0x7 << 1) | 527 | #define RXON_RX_CHAIN_VALID_MSK cpu_to_le16(0x7 << 1) |
522 | #define RXON_RX_CHAIN_VALID_POS (1) | 528 | #define RXON_RX_CHAIN_VALID_POS (1) |
523 | #define RXON_RX_CHAIN_FORCE_SEL_MSK __constant_cpu_to_le16(0x7 << 4) | 529 | #define RXON_RX_CHAIN_FORCE_SEL_MSK cpu_to_le16(0x7 << 4) |
524 | #define RXON_RX_CHAIN_FORCE_SEL_POS (4) | 530 | #define RXON_RX_CHAIN_FORCE_SEL_POS (4) |
525 | #define RXON_RX_CHAIN_FORCE_MIMO_SEL_MSK __constant_cpu_to_le16(0x7 << 7) | 531 | #define RXON_RX_CHAIN_FORCE_MIMO_SEL_MSK cpu_to_le16(0x7 << 7) |
526 | #define RXON_RX_CHAIN_FORCE_MIMO_SEL_POS (7) | 532 | #define RXON_RX_CHAIN_FORCE_MIMO_SEL_POS (7) |
527 | #define RXON_RX_CHAIN_CNT_MSK __constant_cpu_to_le16(0x3 << 10) | 533 | #define RXON_RX_CHAIN_CNT_MSK cpu_to_le16(0x3 << 10) |
528 | #define RXON_RX_CHAIN_CNT_POS (10) | 534 | #define RXON_RX_CHAIN_CNT_POS (10) |
529 | #define RXON_RX_CHAIN_MIMO_CNT_MSK __constant_cpu_to_le16(0x3 << 12) | 535 | #define RXON_RX_CHAIN_MIMO_CNT_MSK cpu_to_le16(0x3 << 12) |
530 | #define RXON_RX_CHAIN_MIMO_CNT_POS (12) | 536 | #define RXON_RX_CHAIN_MIMO_CNT_POS (12) |
531 | #define RXON_RX_CHAIN_MIMO_FORCE_MSK __constant_cpu_to_le16(0x1 << 14) | 537 | #define RXON_RX_CHAIN_MIMO_FORCE_MSK cpu_to_le16(0x1 << 14) |
532 | #define RXON_RX_CHAIN_MIMO_FORCE_POS (14) | 538 | #define RXON_RX_CHAIN_MIMO_FORCE_POS (14) |
533 | 539 | ||
534 | /* rx_config flags */ | 540 | /* rx_config flags */ |
535 | /* band & modulation selection */ | 541 | /* band & modulation selection */ |
536 | #define RXON_FLG_BAND_24G_MSK __constant_cpu_to_le32(1 << 0) | 542 | #define RXON_FLG_BAND_24G_MSK cpu_to_le32(1 << 0) |
537 | #define RXON_FLG_CCK_MSK __constant_cpu_to_le32(1 << 1) | 543 | #define RXON_FLG_CCK_MSK cpu_to_le32(1 << 1) |
538 | /* auto detection enable */ | 544 | /* auto detection enable */ |
539 | #define RXON_FLG_AUTO_DETECT_MSK __constant_cpu_to_le32(1 << 2) | 545 | #define RXON_FLG_AUTO_DETECT_MSK cpu_to_le32(1 << 2) |
540 | /* TGg protection when tx */ | 546 | /* TGg protection when tx */ |
541 | #define RXON_FLG_TGG_PROTECT_MSK __constant_cpu_to_le32(1 << 3) | 547 | #define RXON_FLG_TGG_PROTECT_MSK cpu_to_le32(1 << 3) |
542 | /* cck short slot & preamble */ | 548 | /* cck short slot & preamble */ |
543 | #define RXON_FLG_SHORT_SLOT_MSK __constant_cpu_to_le32(1 << 4) | 549 | #define RXON_FLG_SHORT_SLOT_MSK cpu_to_le32(1 << 4) |
544 | #define RXON_FLG_SHORT_PREAMBLE_MSK __constant_cpu_to_le32(1 << 5) | 550 | #define RXON_FLG_SHORT_PREAMBLE_MSK cpu_to_le32(1 << 5) |
545 | /* antenna selection */ | 551 | /* antenna selection */ |
546 | #define RXON_FLG_DIS_DIV_MSK __constant_cpu_to_le32(1 << 7) | 552 | #define RXON_FLG_DIS_DIV_MSK cpu_to_le32(1 << 7) |
547 | #define RXON_FLG_ANT_SEL_MSK __constant_cpu_to_le32(0x0f00) | 553 | #define RXON_FLG_ANT_SEL_MSK cpu_to_le32(0x0f00) |
548 | #define RXON_FLG_ANT_A_MSK __constant_cpu_to_le32(1 << 8) | 554 | #define RXON_FLG_ANT_A_MSK cpu_to_le32(1 << 8) |
549 | #define RXON_FLG_ANT_B_MSK __constant_cpu_to_le32(1 << 9) | 555 | #define RXON_FLG_ANT_B_MSK cpu_to_le32(1 << 9) |
550 | /* radar detection enable */ | 556 | /* radar detection enable */ |
551 | #define RXON_FLG_RADAR_DETECT_MSK __constant_cpu_to_le32(1 << 12) | 557 | #define RXON_FLG_RADAR_DETECT_MSK cpu_to_le32(1 << 12) |
552 | #define RXON_FLG_TGJ_NARROW_BAND_MSK __constant_cpu_to_le32(1 << 13) | 558 | #define RXON_FLG_TGJ_NARROW_BAND_MSK cpu_to_le32(1 << 13) |
553 | /* rx response to host with 8-byte TSF | 559 | /* rx response to host with 8-byte TSF |
554 | * (according to ON_AIR deassertion) */ | 560 | * (according to ON_AIR deassertion) */ |
555 | #define RXON_FLG_TSF2HOST_MSK __constant_cpu_to_le32(1 << 15) | 561 | #define RXON_FLG_TSF2HOST_MSK cpu_to_le32(1 << 15) |
556 | 562 | ||
557 | 563 | ||
558 | /* HT flags */ | 564 | /* HT flags */ |
559 | #define RXON_FLG_CTRL_CHANNEL_LOC_POS (22) | 565 | #define RXON_FLG_CTRL_CHANNEL_LOC_POS (22) |
560 | #define RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK __constant_cpu_to_le32(0x1 << 22) | 566 | #define RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK cpu_to_le32(0x1 << 22) |
561 | 567 | ||
562 | #define RXON_FLG_HT_OPERATING_MODE_POS (23) | 568 | #define RXON_FLG_HT_OPERATING_MODE_POS (23) |
563 | 569 | ||
564 | #define RXON_FLG_HT_PROT_MSK __constant_cpu_to_le32(0x1 << 23) | 570 | #define RXON_FLG_HT_PROT_MSK cpu_to_le32(0x1 << 23) |
565 | #define RXON_FLG_FAT_PROT_MSK __constant_cpu_to_le32(0x2 << 23) | 571 | #define RXON_FLG_FAT_PROT_MSK cpu_to_le32(0x2 << 23) |
566 | 572 | ||
567 | #define RXON_FLG_CHANNEL_MODE_POS (25) | 573 | #define RXON_FLG_CHANNEL_MODE_POS (25) |
568 | #define RXON_FLG_CHANNEL_MODE_MSK __constant_cpu_to_le32(0x3 << 25) | 574 | #define RXON_FLG_CHANNEL_MODE_MSK cpu_to_le32(0x3 << 25) |
569 | #define RXON_FLG_CHANNEL_MODE_PURE_40_MSK __constant_cpu_to_le32(0x1 << 25) | 575 | #define RXON_FLG_CHANNEL_MODE_PURE_40_MSK cpu_to_le32(0x1 << 25) |
570 | #define RXON_FLG_CHANNEL_MODE_MIXED_MSK __constant_cpu_to_le32(0x2 << 25) | 576 | #define RXON_FLG_CHANNEL_MODE_MIXED_MSK cpu_to_le32(0x2 << 25) |
571 | /* CTS to self (if spec allows) flag */ | 577 | /* CTS to self (if spec allows) flag */ |
572 | #define RXON_FLG_SELF_CTS_EN __constant_cpu_to_le32(0x1<<30) | 578 | #define RXON_FLG_SELF_CTS_EN cpu_to_le32(0x1<<30) |
573 | 579 | ||
574 | /* rx_config filter flags */ | 580 | /* rx_config filter flags */ |
575 | /* accept all data frames */ | 581 | /* accept all data frames */ |
576 | #define RXON_FILTER_PROMISC_MSK __constant_cpu_to_le32(1 << 0) | 582 | #define RXON_FILTER_PROMISC_MSK cpu_to_le32(1 << 0) |
577 | /* pass control & management to host */ | 583 | /* pass control & management to host */ |
578 | #define RXON_FILTER_CTL2HOST_MSK __constant_cpu_to_le32(1 << 1) | 584 | #define RXON_FILTER_CTL2HOST_MSK cpu_to_le32(1 << 1) |
579 | /* accept multi-cast */ | 585 | /* accept multi-cast */ |
580 | #define RXON_FILTER_ACCEPT_GRP_MSK __constant_cpu_to_le32(1 << 2) | 586 | #define RXON_FILTER_ACCEPT_GRP_MSK cpu_to_le32(1 << 2) |
581 | /* don't decrypt uni-cast frames */ | 587 | /* don't decrypt uni-cast frames */ |
582 | #define RXON_FILTER_DIS_DECRYPT_MSK __constant_cpu_to_le32(1 << 3) | 588 | #define RXON_FILTER_DIS_DECRYPT_MSK cpu_to_le32(1 << 3) |
583 | /* don't decrypt multi-cast frames */ | 589 | /* don't decrypt multi-cast frames */ |
584 | #define RXON_FILTER_DIS_GRP_DECRYPT_MSK __constant_cpu_to_le32(1 << 4) | 590 | #define RXON_FILTER_DIS_GRP_DECRYPT_MSK cpu_to_le32(1 << 4) |
585 | /* STA is associated */ | 591 | /* STA is associated */ |
586 | #define RXON_FILTER_ASSOC_MSK __constant_cpu_to_le32(1 << 5) | 592 | #define RXON_FILTER_ASSOC_MSK cpu_to_le32(1 << 5) |
587 | /* transfer to host non bssid beacons in associated state */ | 593 | /* transfer to host non bssid beacons in associated state */ |
588 | #define RXON_FILTER_BCON_AWARE_MSK __constant_cpu_to_le32(1 << 6) | 594 | #define RXON_FILTER_BCON_AWARE_MSK cpu_to_le32(1 << 6) |
589 | 595 | ||
590 | /** | 596 | /** |
591 | * REPLY_RXON = 0x10 (command, has simple generic response) | 597 | * REPLY_RXON = 0x10 (command, has simple generic response) |
@@ -745,9 +751,9 @@ struct iwl_ac_qos { | |||
745 | } __attribute__ ((packed)); | 751 | } __attribute__ ((packed)); |
746 | 752 | ||
747 | /* QoS flags defines */ | 753 | /* QoS flags defines */ |
748 | #define QOS_PARAM_FLG_UPDATE_EDCA_MSK __constant_cpu_to_le32(0x01) | 754 | #define QOS_PARAM_FLG_UPDATE_EDCA_MSK cpu_to_le32(0x01) |
749 | #define QOS_PARAM_FLG_TGN_MSK __constant_cpu_to_le32(0x02) | 755 | #define QOS_PARAM_FLG_TGN_MSK cpu_to_le32(0x02) |
750 | #define QOS_PARAM_FLG_TXOP_TYPE_MSK __constant_cpu_to_le32(0x10) | 756 | #define QOS_PARAM_FLG_TXOP_TYPE_MSK cpu_to_le32(0x10) |
751 | 757 | ||
752 | /* Number of Access Categories (AC) (EDCA), queues 0..3 */ | 758 | /* Number of Access Categories (AC) (EDCA), queues 0..3 */ |
753 | #define AC_NUM 4 | 759 | #define AC_NUM 4 |
@@ -784,34 +790,34 @@ struct iwl_qosparam_cmd { | |||
784 | #define IWL_STATION_COUNT 32 /* MAX(3945,4965)*/ | 790 | #define IWL_STATION_COUNT 32 /* MAX(3945,4965)*/ |
785 | #define IWL_INVALID_STATION 255 | 791 | #define IWL_INVALID_STATION 255 |
786 | 792 | ||
787 | #define STA_FLG_PWR_SAVE_MSK __constant_cpu_to_le32(1 << 8); | 793 | #define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8); |
788 | #define STA_FLG_RTS_MIMO_PROT_MSK __constant_cpu_to_le32(1 << 17) | 794 | #define STA_FLG_RTS_MIMO_PROT_MSK cpu_to_le32(1 << 17) |
789 | #define STA_FLG_AGG_MPDU_8US_MSK __constant_cpu_to_le32(1 << 18) | 795 | #define STA_FLG_AGG_MPDU_8US_MSK cpu_to_le32(1 << 18) |
790 | #define STA_FLG_MAX_AGG_SIZE_POS (19) | 796 | #define STA_FLG_MAX_AGG_SIZE_POS (19) |
791 | #define STA_FLG_MAX_AGG_SIZE_MSK __constant_cpu_to_le32(3 << 19) | 797 | #define STA_FLG_MAX_AGG_SIZE_MSK cpu_to_le32(3 << 19) |
792 | #define STA_FLG_FAT_EN_MSK __constant_cpu_to_le32(1 << 21) | 798 | #define STA_FLG_FAT_EN_MSK cpu_to_le32(1 << 21) |
793 | #define STA_FLG_MIMO_DIS_MSK __constant_cpu_to_le32(1 << 22) | 799 | #define STA_FLG_MIMO_DIS_MSK cpu_to_le32(1 << 22) |
794 | #define STA_FLG_AGG_MPDU_DENSITY_POS (23) | 800 | #define STA_FLG_AGG_MPDU_DENSITY_POS (23) |
795 | #define STA_FLG_AGG_MPDU_DENSITY_MSK __constant_cpu_to_le32(7 << 23) | 801 | #define STA_FLG_AGG_MPDU_DENSITY_MSK cpu_to_le32(7 << 23) |
796 | 802 | ||
797 | /* Use in mode field. 1: modify existing entry, 0: add new station entry */ | 803 | /* Use in mode field. 1: modify existing entry, 0: add new station entry */ |
798 | #define STA_CONTROL_MODIFY_MSK 0x01 | 804 | #define STA_CONTROL_MODIFY_MSK 0x01 |
799 | 805 | ||
800 | /* key flags __le16*/ | 806 | /* key flags __le16*/ |
801 | #define STA_KEY_FLG_ENCRYPT_MSK __constant_cpu_to_le16(0x0007) | 807 | #define STA_KEY_FLG_ENCRYPT_MSK cpu_to_le16(0x0007) |
802 | #define STA_KEY_FLG_NO_ENC __constant_cpu_to_le16(0x0000) | 808 | #define STA_KEY_FLG_NO_ENC cpu_to_le16(0x0000) |
803 | #define STA_KEY_FLG_WEP __constant_cpu_to_le16(0x0001) | 809 | #define STA_KEY_FLG_WEP cpu_to_le16(0x0001) |
804 | #define STA_KEY_FLG_CCMP __constant_cpu_to_le16(0x0002) | 810 | #define STA_KEY_FLG_CCMP cpu_to_le16(0x0002) |
805 | #define STA_KEY_FLG_TKIP __constant_cpu_to_le16(0x0003) | 811 | #define STA_KEY_FLG_TKIP cpu_to_le16(0x0003) |
806 | 812 | ||
807 | #define STA_KEY_FLG_KEYID_POS 8 | 813 | #define STA_KEY_FLG_KEYID_POS 8 |
808 | #define STA_KEY_FLG_INVALID __constant_cpu_to_le16(0x0800) | 814 | #define STA_KEY_FLG_INVALID cpu_to_le16(0x0800) |
809 | /* wep key is either from global key (0) or from station info array (1) */ | 815 | /* wep key is either from global key (0) or from station info array (1) */ |
810 | #define STA_KEY_FLG_MAP_KEY_MSK __constant_cpu_to_le16(0x0008) | 816 | #define STA_KEY_FLG_MAP_KEY_MSK cpu_to_le16(0x0008) |
811 | 817 | ||
812 | /* wep key in STA: 5-bytes (0) or 13-bytes (1) */ | 818 | /* wep key in STA: 5-bytes (0) or 13-bytes (1) */ |
813 | #define STA_KEY_FLG_KEY_SIZE_MSK __constant_cpu_to_le16(0x1000) | 819 | #define STA_KEY_FLG_KEY_SIZE_MSK cpu_to_le16(0x1000) |
814 | #define STA_KEY_MULTICAST_MSK __constant_cpu_to_le16(0x4000) | 820 | #define STA_KEY_MULTICAST_MSK cpu_to_le16(0x4000) |
815 | #define STA_KEY_MAX_NUM 8 | 821 | #define STA_KEY_MAX_NUM 8 |
816 | 822 | ||
817 | /* Flags indicate whether to modify vs. don't change various station params */ | 823 | /* Flags indicate whether to modify vs. don't change various station params */ |
@@ -1036,14 +1042,14 @@ struct iwl4965_rx_frame_hdr { | |||
1036 | u8 payload[0]; | 1042 | u8 payload[0]; |
1037 | } __attribute__ ((packed)); | 1043 | } __attribute__ ((packed)); |
1038 | 1044 | ||
1039 | #define RX_RES_STATUS_NO_CRC32_ERROR __constant_cpu_to_le32(1 << 0) | 1045 | #define RX_RES_STATUS_NO_CRC32_ERROR cpu_to_le32(1 << 0) |
1040 | #define RX_RES_STATUS_NO_RXE_OVERFLOW __constant_cpu_to_le32(1 << 1) | 1046 | #define RX_RES_STATUS_NO_RXE_OVERFLOW cpu_to_le32(1 << 1) |
1041 | 1047 | ||
1042 | #define RX_RES_PHY_FLAGS_BAND_24_MSK __constant_cpu_to_le16(1 << 0) | 1048 | #define RX_RES_PHY_FLAGS_BAND_24_MSK cpu_to_le16(1 << 0) |
1043 | #define RX_RES_PHY_FLAGS_MOD_CCK_MSK __constant_cpu_to_le16(1 << 1) | 1049 | #define RX_RES_PHY_FLAGS_MOD_CCK_MSK cpu_to_le16(1 << 1) |
1044 | #define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK __constant_cpu_to_le16(1 << 2) | 1050 | #define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK cpu_to_le16(1 << 2) |
1045 | #define RX_RES_PHY_FLAGS_NARROW_BAND_MSK __constant_cpu_to_le16(1 << 3) | 1051 | #define RX_RES_PHY_FLAGS_NARROW_BAND_MSK cpu_to_le16(1 << 3) |
1046 | #define RX_RES_PHY_FLAGS_ANTENNA_MSK __constant_cpu_to_le16(0xf0) | 1052 | #define RX_RES_PHY_FLAGS_ANTENNA_MSK cpu_to_le16(0xf0) |
1047 | 1053 | ||
1048 | #define RX_RES_STATUS_SEC_TYPE_MSK (0x7 << 8) | 1054 | #define RX_RES_STATUS_SEC_TYPE_MSK (0x7 << 8) |
1049 | #define RX_RES_STATUS_SEC_TYPE_NONE (0x0 << 8) | 1055 | #define RX_RES_STATUS_SEC_TYPE_NONE (0x0 << 8) |
@@ -1174,21 +1180,21 @@ struct iwl4965_rx_mpdu_res_start { | |||
1174 | /* 1: Use RTS/CTS protocol or CTS-to-self if spec allows it | 1180 | /* 1: Use RTS/CTS protocol or CTS-to-self if spec allows it |
1175 | * before this frame. if CTS-to-self required check | 1181 | * before this frame. if CTS-to-self required check |
1176 | * RXON_FLG_SELF_CTS_EN status. */ | 1182 | * RXON_FLG_SELF_CTS_EN status. */ |
1177 | #define TX_CMD_FLG_RTS_CTS_MSK __constant_cpu_to_le32(1 << 0) | 1183 | #define TX_CMD_FLG_RTS_CTS_MSK cpu_to_le32(1 << 0) |
1178 | 1184 | ||
1179 | /* 1: Use Request-To-Send protocol before this frame. | 1185 | /* 1: Use Request-To-Send protocol before this frame. |
1180 | * Mutually exclusive vs. TX_CMD_FLG_CTS_MSK. */ | 1186 | * Mutually exclusive vs. TX_CMD_FLG_CTS_MSK. */ |
1181 | #define TX_CMD_FLG_RTS_MSK __constant_cpu_to_le32(1 << 1) | 1187 | #define TX_CMD_FLG_RTS_MSK cpu_to_le32(1 << 1) |
1182 | 1188 | ||
1183 | /* 1: Transmit Clear-To-Send to self before this frame. | 1189 | /* 1: Transmit Clear-To-Send to self before this frame. |
1184 | * Driver should set this for AUTH/DEAUTH/ASSOC-REQ/REASSOC mgmnt frames. | 1190 | * Driver should set this for AUTH/DEAUTH/ASSOC-REQ/REASSOC mgmnt frames. |
1185 | * Mutually exclusive vs. TX_CMD_FLG_RTS_MSK. */ | 1191 | * Mutually exclusive vs. TX_CMD_FLG_RTS_MSK. */ |
1186 | #define TX_CMD_FLG_CTS_MSK __constant_cpu_to_le32(1 << 2) | 1192 | #define TX_CMD_FLG_CTS_MSK cpu_to_le32(1 << 2) |
1187 | 1193 | ||
1188 | /* 1: Expect ACK from receiving station | 1194 | /* 1: Expect ACK from receiving station |
1189 | * 0: Don't expect ACK (MAC header's duration field s/b 0) | 1195 | * 0: Don't expect ACK (MAC header's duration field s/b 0) |
1190 | * Set this for unicast frames, but not broadcast/multicast. */ | 1196 | * Set this for unicast frames, but not broadcast/multicast. */ |
1191 | #define TX_CMD_FLG_ACK_MSK __constant_cpu_to_le32(1 << 3) | 1197 | #define TX_CMD_FLG_ACK_MSK cpu_to_le32(1 << 3) |
1192 | 1198 | ||
1193 | /* For 4965: | 1199 | /* For 4965: |
1194 | * 1: Use rate scale table (see REPLY_TX_LINK_QUALITY_CMD). | 1200 | * 1: Use rate scale table (see REPLY_TX_LINK_QUALITY_CMD). |
@@ -1196,40 +1202,40 @@ struct iwl4965_rx_mpdu_res_start { | |||
1196 | * uCode walks through table for additional Tx attempts. | 1202 | * uCode walks through table for additional Tx attempts. |
1197 | * 0: Use Tx rate/MCS from Tx command's rate_n_flags field. | 1203 | * 0: Use Tx rate/MCS from Tx command's rate_n_flags field. |
1198 | * This rate will be used for all Tx attempts; it will not be scaled. */ | 1204 | * This rate will be used for all Tx attempts; it will not be scaled. */ |
1199 | #define TX_CMD_FLG_STA_RATE_MSK __constant_cpu_to_le32(1 << 4) | 1205 | #define TX_CMD_FLG_STA_RATE_MSK cpu_to_le32(1 << 4) |
1200 | 1206 | ||
1201 | /* 1: Expect immediate block-ack. | 1207 | /* 1: Expect immediate block-ack. |
1202 | * Set when Txing a block-ack request frame. Also set TX_CMD_FLG_ACK_MSK. */ | 1208 | * Set when Txing a block-ack request frame. Also set TX_CMD_FLG_ACK_MSK. */ |
1203 | #define TX_CMD_FLG_IMM_BA_RSP_MASK __constant_cpu_to_le32(1 << 6) | 1209 | #define TX_CMD_FLG_IMM_BA_RSP_MASK cpu_to_le32(1 << 6) |
1204 | 1210 | ||
1205 | /* 1: Frame requires full Tx-Op protection. | 1211 | /* 1: Frame requires full Tx-Op protection. |
1206 | * Set this if either RTS or CTS Tx Flag gets set. */ | 1212 | * Set this if either RTS or CTS Tx Flag gets set. */ |
1207 | #define TX_CMD_FLG_FULL_TXOP_PROT_MSK __constant_cpu_to_le32(1 << 7) | 1213 | #define TX_CMD_FLG_FULL_TXOP_PROT_MSK cpu_to_le32(1 << 7) |
1208 | 1214 | ||
1209 | /* Tx antenna selection field; used only for 3945, reserved (0) for 4965. | 1215 | /* Tx antenna selection field; used only for 3945, reserved (0) for 4965. |
1210 | * Set field to "0" to allow 3945 uCode to select antenna (normal usage). */ | 1216 | * Set field to "0" to allow 3945 uCode to select antenna (normal usage). */ |
1211 | #define TX_CMD_FLG_ANT_SEL_MSK __constant_cpu_to_le32(0xf00) | 1217 | #define TX_CMD_FLG_ANT_SEL_MSK cpu_to_le32(0xf00) |
1212 | #define TX_CMD_FLG_ANT_A_MSK __constant_cpu_to_le32(1 << 8) | 1218 | #define TX_CMD_FLG_ANT_A_MSK cpu_to_le32(1 << 8) |
1213 | #define TX_CMD_FLG_ANT_B_MSK __constant_cpu_to_le32(1 << 9) | 1219 | #define TX_CMD_FLG_ANT_B_MSK cpu_to_le32(1 << 9) |
1214 | 1220 | ||
1215 | /* 1: Ignore Bluetooth priority for this frame. | 1221 | /* 1: Ignore Bluetooth priority for this frame. |
1216 | * 0: Delay Tx until Bluetooth device is done (normal usage). */ | 1222 | * 0: Delay Tx until Bluetooth device is done (normal usage). */ |
1217 | #define TX_CMD_FLG_BT_DIS_MSK __constant_cpu_to_le32(1 << 12) | 1223 | #define TX_CMD_FLG_BT_DIS_MSK cpu_to_le32(1 << 12) |
1218 | 1224 | ||
1219 | /* 1: uCode overrides sequence control field in MAC header. | 1225 | /* 1: uCode overrides sequence control field in MAC header. |
1220 | * 0: Driver provides sequence control field in MAC header. | 1226 | * 0: Driver provides sequence control field in MAC header. |
1221 | * Set this for management frames, non-QOS data frames, non-unicast frames, | 1227 | * Set this for management frames, non-QOS data frames, non-unicast frames, |
1222 | * and also in Tx command embedded in REPLY_SCAN_CMD for active scans. */ | 1228 | * and also in Tx command embedded in REPLY_SCAN_CMD for active scans. */ |
1223 | #define TX_CMD_FLG_SEQ_CTL_MSK __constant_cpu_to_le32(1 << 13) | 1229 | #define TX_CMD_FLG_SEQ_CTL_MSK cpu_to_le32(1 << 13) |
1224 | 1230 | ||
1225 | /* 1: This frame is non-last MPDU; more fragments are coming. | 1231 | /* 1: This frame is non-last MPDU; more fragments are coming. |
1226 | * 0: Last fragment, or not using fragmentation. */ | 1232 | * 0: Last fragment, or not using fragmentation. */ |
1227 | #define TX_CMD_FLG_MORE_FRAG_MSK __constant_cpu_to_le32(1 << 14) | 1233 | #define TX_CMD_FLG_MORE_FRAG_MSK cpu_to_le32(1 << 14) |
1228 | 1234 | ||
1229 | /* 1: uCode calculates and inserts Timestamp Function (TSF) in outgoing frame. | 1235 | /* 1: uCode calculates and inserts Timestamp Function (TSF) in outgoing frame. |
1230 | * 0: No TSF required in outgoing frame. | 1236 | * 0: No TSF required in outgoing frame. |
1231 | * Set this for transmitting beacons and probe responses. */ | 1237 | * Set this for transmitting beacons and probe responses. */ |
1232 | #define TX_CMD_FLG_TSF_MSK __constant_cpu_to_le32(1 << 16) | 1238 | #define TX_CMD_FLG_TSF_MSK cpu_to_le32(1 << 16) |
1233 | 1239 | ||
1234 | /* 1: Driver inserted 2 bytes pad after the MAC header, for (required) dword | 1240 | /* 1: Driver inserted 2 bytes pad after the MAC header, for (required) dword |
1235 | * alignment of frame's payload data field. | 1241 | * alignment of frame's payload data field. |
@@ -1237,14 +1243,14 @@ struct iwl4965_rx_mpdu_res_start { | |||
1237 | * Set this for MAC headers with 26 or 30 bytes, i.e. those with QOS or ADDR4 | 1243 | * Set this for MAC headers with 26 or 30 bytes, i.e. those with QOS or ADDR4 |
1238 | * field (but not both). Driver must align frame data (i.e. data following | 1244 | * field (but not both). Driver must align frame data (i.e. data following |
1239 | * MAC header) to DWORD boundary. */ | 1245 | * MAC header) to DWORD boundary. */ |
1240 | #define TX_CMD_FLG_MH_PAD_MSK __constant_cpu_to_le32(1 << 20) | 1246 | #define TX_CMD_FLG_MH_PAD_MSK cpu_to_le32(1 << 20) |
1241 | 1247 | ||
1242 | /* accelerate aggregation support | 1248 | /* accelerate aggregation support |
1243 | * 0 - no CCMP encryption; 1 - CCMP encryption */ | 1249 | * 0 - no CCMP encryption; 1 - CCMP encryption */ |
1244 | #define TX_CMD_FLG_AGG_CCMP_MSK __constant_cpu_to_le32(1 << 22) | 1250 | #define TX_CMD_FLG_AGG_CCMP_MSK cpu_to_le32(1 << 22) |
1245 | 1251 | ||
1246 | /* HCCA-AP - disable duration overwriting. */ | 1252 | /* HCCA-AP - disable duration overwriting. */ |
1247 | #define TX_CMD_FLG_DUR_MSK __constant_cpu_to_le32(1 << 25) | 1253 | #define TX_CMD_FLG_DUR_MSK cpu_to_le32(1 << 25) |
1248 | 1254 | ||
1249 | 1255 | ||
1250 | /* | 1256 | /* |
@@ -2076,10 +2082,10 @@ struct iwl4965_spectrum_notification { | |||
2076 | */ | 2082 | */ |
2077 | #define IWL_POWER_VEC_SIZE 5 | 2083 | #define IWL_POWER_VEC_SIZE 5 |
2078 | 2084 | ||
2079 | #define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK __constant_cpu_to_le16(1 << 0) | 2085 | #define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK cpu_to_le16(1 << 0) |
2080 | #define IWL_POWER_SLEEP_OVER_DTIM_MSK __constant_cpu_to_le16(1 << 2) | 2086 | #define IWL_POWER_SLEEP_OVER_DTIM_MSK cpu_to_le16(1 << 2) |
2081 | #define IWL_POWER_PCI_PM_MSK __constant_cpu_to_le16(1 << 3) | 2087 | #define IWL_POWER_PCI_PM_MSK cpu_to_le16(1 << 3) |
2082 | #define IWL_POWER_FAST_PD __constant_cpu_to_le16(1 << 4) | 2088 | #define IWL_POWER_FAST_PD cpu_to_le16(1 << 4) |
2083 | 2089 | ||
2084 | struct iwl_powertable_cmd { | 2090 | struct iwl_powertable_cmd { |
2085 | __le16 flags; | 2091 | __le16 flags; |
@@ -2153,8 +2159,8 @@ struct iwl_ct_kill_config { | |||
2153 | * | 2159 | * |
2154 | *****************************************************************************/ | 2160 | *****************************************************************************/ |
2155 | 2161 | ||
2156 | #define SCAN_CHANNEL_TYPE_PASSIVE __constant_cpu_to_le32(0) | 2162 | #define SCAN_CHANNEL_TYPE_PASSIVE cpu_to_le32(0) |
2157 | #define SCAN_CHANNEL_TYPE_ACTIVE __constant_cpu_to_le32(1) | 2163 | #define SCAN_CHANNEL_TYPE_ACTIVE cpu_to_le32(1) |
2158 | 2164 | ||
2159 | /** | 2165 | /** |
2160 | * struct iwl_scan_channel - entry in REPLY_SCAN_CMD channel table | 2166 | * struct iwl_scan_channel - entry in REPLY_SCAN_CMD channel table |
@@ -2205,8 +2211,8 @@ struct iwl_ssid_ie { | |||
2205 | } __attribute__ ((packed)); | 2211 | } __attribute__ ((packed)); |
2206 | 2212 | ||
2207 | #define PROBE_OPTION_MAX 0x14 | 2213 | #define PROBE_OPTION_MAX 0x14 |
2208 | #define TX_CMD_LIFE_TIME_INFINITE __constant_cpu_to_le32(0xFFFFFFFF) | 2214 | #define TX_CMD_LIFE_TIME_INFINITE cpu_to_le32(0xFFFFFFFF) |
2209 | #define IWL_GOOD_CRC_TH __constant_cpu_to_le16(1) | 2215 | #define IWL_GOOD_CRC_TH cpu_to_le16(1) |
2210 | #define IWL_MAX_SCAN_SIZE 1024 | 2216 | #define IWL_MAX_SCAN_SIZE 1024 |
2211 | 2217 | ||
2212 | /* | 2218 | /* |
@@ -2306,7 +2312,7 @@ struct iwl_scan_cmd { | |||
2306 | } __attribute__ ((packed)); | 2312 | } __attribute__ ((packed)); |
2307 | 2313 | ||
2308 | /* Can abort will notify by complete notification with abort status. */ | 2314 | /* Can abort will notify by complete notification with abort status. */ |
2309 | #define CAN_ABORT_STATUS __constant_cpu_to_le32(0x1) | 2315 | #define CAN_ABORT_STATUS cpu_to_le32(0x1) |
2310 | /* complete notification statuses */ | 2316 | /* complete notification statuses */ |
2311 | #define ABORT_STATUS 0x2 | 2317 | #define ABORT_STATUS 0x2 |
2312 | 2318 | ||
@@ -2568,8 +2574,8 @@ struct statistics_general { | |||
2568 | * STATISTICS_NOTIFICATIONs after received beacons (see below). This flag | 2574 | * STATISTICS_NOTIFICATIONs after received beacons (see below). This flag |
2569 | * does not affect the response to the REPLY_STATISTICS_CMD 0x9c itself. | 2575 | * does not affect the response to the REPLY_STATISTICS_CMD 0x9c itself. |
2570 | */ | 2576 | */ |
2571 | #define IWL_STATS_CONF_CLEAR_STATS __constant_cpu_to_le32(0x1) /* see above */ | 2577 | #define IWL_STATS_CONF_CLEAR_STATS cpu_to_le32(0x1) /* see above */ |
2572 | #define IWL_STATS_CONF_DISABLE_NOTIF __constant_cpu_to_le32(0x2)/* see above */ | 2578 | #define IWL_STATS_CONF_DISABLE_NOTIF cpu_to_le32(0x2)/* see above */ |
2573 | struct iwl_statistics_cmd { | 2579 | struct iwl_statistics_cmd { |
2574 | __le32 configuration_flags; /* IWL_STATS_CONF_* */ | 2580 | __le32 configuration_flags; /* IWL_STATS_CONF_* */ |
2575 | } __attribute__ ((packed)); | 2581 | } __attribute__ ((packed)); |
@@ -2589,8 +2595,8 @@ struct iwl_statistics_cmd { | |||
2589 | * appropriately so that each notification contains statistics for only the | 2595 | * appropriately so that each notification contains statistics for only the |
2590 | * one channel that has just been scanned. | 2596 | * one channel that has just been scanned. |
2591 | */ | 2597 | */ |
2592 | #define STATISTICS_REPLY_FLG_BAND_24G_MSK __constant_cpu_to_le32(0x2) | 2598 | #define STATISTICS_REPLY_FLG_BAND_24G_MSK cpu_to_le32(0x2) |
2593 | #define STATISTICS_REPLY_FLG_FAT_MODE_MSK __constant_cpu_to_le32(0x8) | 2599 | #define STATISTICS_REPLY_FLG_FAT_MODE_MSK cpu_to_le32(0x8) |
2594 | struct iwl_notif_statistics { | 2600 | struct iwl_notif_statistics { |
2595 | __le32 flag; | 2601 | __le32 flag; |
2596 | struct statistics_rx rx; | 2602 | struct statistics_rx rx; |
@@ -2806,8 +2812,8 @@ struct iwl4965_missed_beacon_notif { | |||
2806 | #define HD_OFDM_ENERGY_TH_IN_INDEX (10) | 2812 | #define HD_OFDM_ENERGY_TH_IN_INDEX (10) |
2807 | 2813 | ||
2808 | /* Control field in struct iwl_sensitivity_cmd */ | 2814 | /* Control field in struct iwl_sensitivity_cmd */ |
2809 | #define SENSITIVITY_CMD_CONTROL_DEFAULT_TABLE __constant_cpu_to_le16(0) | 2815 | #define SENSITIVITY_CMD_CONTROL_DEFAULT_TABLE cpu_to_le16(0) |
2810 | #define SENSITIVITY_CMD_CONTROL_WORK_TABLE __constant_cpu_to_le16(1) | 2816 | #define SENSITIVITY_CMD_CONTROL_WORK_TABLE cpu_to_le16(1) |
2811 | 2817 | ||
2812 | /** | 2818 | /** |
2813 | * struct iwl_sensitivity_cmd | 2819 | * struct iwl_sensitivity_cmd |
@@ -2896,12 +2902,7 @@ enum { | |||
2896 | }; | 2902 | }; |
2897 | 2903 | ||
2898 | 2904 | ||
2899 | struct iwl_cal_xtal_freq { | 2905 | #define IWL_CALIB_INIT_CFG_ALL cpu_to_le32(0xffffffff) |
2900 | u8 cap_pin1; | ||
2901 | u8 cap_pin2; | ||
2902 | } __attribute__ ((packed)); | ||
2903 | |||
2904 | #define IWL_CALIB_INIT_CFG_ALL __constant_cpu_to_le32(0xffffffff) | ||
2905 | 2906 | ||
2906 | struct iwl_calib_cfg_elmnt_s { | 2907 | struct iwl_calib_cfg_elmnt_s { |
2907 | __le32 is_enable; | 2908 | __le32 is_enable; |
@@ -2935,31 +2936,34 @@ struct iwl_calib_cmd { | |||
2935 | u8 data[0]; | 2936 | u8 data[0]; |
2936 | } __attribute__ ((packed)); | 2937 | } __attribute__ ((packed)); |
2937 | 2938 | ||
2938 | /* "Differential Gain" opcode used in REPLY_PHY_CALIBRATION_CMD. */ | 2939 | /* IWL_PHY_CALIBRATE_DIFF_GAIN_CMD (7) */ |
2939 | |||
2940 | struct iwl_calib_diff_gain_cmd { | 2940 | struct iwl_calib_diff_gain_cmd { |
2941 | u8 opCode; /* IWL_PHY_CALIBRATE_DIFF_GAIN_CMD (7) */ | 2941 | struct iwl_calib_hdr hdr; |
2942 | u8 flags; /* not used */ | ||
2943 | __le16 reserved; | ||
2944 | s8 diff_gain_a; /* see above */ | 2942 | s8 diff_gain_a; /* see above */ |
2945 | s8 diff_gain_b; | 2943 | s8 diff_gain_b; |
2946 | s8 diff_gain_c; | 2944 | s8 diff_gain_c; |
2947 | u8 reserved1; | 2945 | u8 reserved1; |
2948 | } __attribute__ ((packed)); | 2946 | } __attribute__ ((packed)); |
2949 | 2947 | ||
2950 | struct iwl_calib_chain_noise_reset_cmd { | 2948 | struct iwl_calib_xtal_freq_cmd { |
2951 | u8 op_code; /* IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD */ | 2949 | struct iwl_calib_hdr hdr; |
2952 | u8 flags; /* not used */ | 2950 | u8 cap_pin1; |
2953 | __le16 reserved; | 2951 | u8 cap_pin2; |
2952 | u8 pad[2]; | ||
2954 | } __attribute__ ((packed)); | 2953 | } __attribute__ ((packed)); |
2955 | 2954 | ||
2955 | /* IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD */ | ||
2956 | struct iwl_calib_chain_noise_reset_cmd { | ||
2957 | struct iwl_calib_hdr hdr; | ||
2958 | u8 data[0]; | ||
2959 | }; | ||
2960 | |||
2961 | /* IWL_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD */ | ||
2956 | struct iwl_calib_chain_noise_gain_cmd { | 2962 | struct iwl_calib_chain_noise_gain_cmd { |
2957 | u8 op_code; /* IWL_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD */ | 2963 | struct iwl_calib_hdr hdr; |
2958 | u8 flags; /* not used */ | ||
2959 | __le16 reserved; | ||
2960 | u8 delta_gain_1; | 2964 | u8 delta_gain_1; |
2961 | u8 delta_gain_2; | 2965 | u8 delta_gain_2; |
2962 | __le16 reserved1; | 2966 | u8 pad[2]; |
2963 | } __attribute__ ((packed)); | 2967 | } __attribute__ ((packed)); |
2964 | 2968 | ||
2965 | /****************************************************************************** | 2969 | /****************************************************************************** |
@@ -3066,4 +3070,6 @@ struct iwl_rx_packet { | |||
3066 | 3070 | ||
3067 | #define IWL_RX_FRAME_SIZE (4 + sizeof(struct iwl4965_rx_frame)) | 3071 | #define IWL_RX_FRAME_SIZE (4 + sizeof(struct iwl4965_rx_frame)) |
3068 | 3072 | ||
3073 | int iwl_agn_check_rxon_cmd(struct iwl_rxon_cmd *rxon); | ||
3074 | |||
3069 | #endif /* __iwl_commands_h__ */ | 3075 | #endif /* __iwl_commands_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 6aa332bebc5f..1b021ca74e25 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -808,7 +808,6 @@ int iwl_setup_mac(struct iwl_priv *priv) | |||
808 | IEEE80211_HW_NOISE_DBM | | 808 | IEEE80211_HW_NOISE_DBM | |
809 | IEEE80211_HW_AMPDU_AGGREGATION; | 809 | IEEE80211_HW_AMPDU_AGGREGATION; |
810 | hw->wiphy->interface_modes = | 810 | hw->wiphy->interface_modes = |
811 | BIT(NL80211_IFTYPE_AP) | | ||
812 | BIT(NL80211_IFTYPE_STATION) | | 811 | BIT(NL80211_IFTYPE_STATION) | |
813 | BIT(NL80211_IFTYPE_ADHOC); | 812 | BIT(NL80211_IFTYPE_ADHOC); |
814 | 813 | ||
@@ -962,6 +961,30 @@ void iwl_uninit_drv(struct iwl_priv *priv) | |||
962 | } | 961 | } |
963 | EXPORT_SYMBOL(iwl_uninit_drv); | 962 | EXPORT_SYMBOL(iwl_uninit_drv); |
964 | 963 | ||
964 | |||
965 | void iwl_disable_interrupts(struct iwl_priv *priv) | ||
966 | { | ||
967 | clear_bit(STATUS_INT_ENABLED, &priv->status); | ||
968 | |||
969 | /* disable interrupts from uCode/NIC to host */ | ||
970 | iwl_write32(priv, CSR_INT_MASK, 0x00000000); | ||
971 | |||
972 | /* acknowledge/clear/reset any interrupts still pending | ||
973 | * from uCode or flow handler (Rx/Tx DMA) */ | ||
974 | iwl_write32(priv, CSR_INT, 0xffffffff); | ||
975 | iwl_write32(priv, CSR_FH_INT_STATUS, 0xffffffff); | ||
976 | IWL_DEBUG_ISR("Disabled interrupts\n"); | ||
977 | } | ||
978 | EXPORT_SYMBOL(iwl_disable_interrupts); | ||
979 | |||
980 | void iwl_enable_interrupts(struct iwl_priv *priv) | ||
981 | { | ||
982 | IWL_DEBUG_ISR("Enabling interrupts\n"); | ||
983 | set_bit(STATUS_INT_ENABLED, &priv->status); | ||
984 | iwl_write32(priv, CSR_INT_MASK, CSR_INI_SET_MASK); | ||
985 | } | ||
986 | EXPORT_SYMBOL(iwl_enable_interrupts); | ||
987 | |||
965 | int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags) | 988 | int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags) |
966 | { | 989 | { |
967 | u32 stat_flags = 0; | 990 | u32 stat_flags = 0; |
@@ -1337,6 +1360,7 @@ void iwl_rf_kill_ct_config(struct iwl_priv *priv) | |||
1337 | } | 1360 | } |
1338 | EXPORT_SYMBOL(iwl_rf_kill_ct_config); | 1361 | EXPORT_SYMBOL(iwl_rf_kill_ct_config); |
1339 | 1362 | ||
1363 | |||
1340 | /* | 1364 | /* |
1341 | * CARD_STATE_CMD | 1365 | * CARD_STATE_CMD |
1342 | * | 1366 | * |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 82bf263b6f5a..81ddca077175 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -164,9 +164,39 @@ struct iwl_mod_params { | |||
164 | int restart_fw; /* def: 1 = restart firmware */ | 164 | int restart_fw; /* def: 1 = restart firmware */ |
165 | }; | 165 | }; |
166 | 166 | ||
167 | /** | ||
168 | * struct iwl_cfg | ||
169 | * @fw_name_pre: Firmware filename prefix. The api version and extension | ||
170 | * (.ucode) will be added to filename before loading from disk. The | ||
171 | * filename is constructed as fw_name_pre<api>.ucode. | ||
172 | * @ucode_api_max: Highest version of uCode API supported by driver. | ||
173 | * @ucode_api_min: Lowest version of uCode API supported by driver. | ||
174 | * | ||
175 | * We enable the driver to be backward compatible wrt API version. The | ||
176 | * driver specifies which APIs it supports (with @ucode_api_max being the | ||
177 | * highest and @ucode_api_min the lowest). Firmware will only be loaded if | ||
178 | * it has a supported API version. The firmware's API version will be | ||
179 | * stored in @iwl_priv, enabling the driver to make runtime changes based | ||
180 | * on firmware version used. | ||
181 | * | ||
182 | * For example, | ||
183 | * if (IWL_UCODE_API(priv->ucode_ver) >= 2) { | ||
184 | * Driver interacts with Firmware API version >= 2. | ||
185 | * } else { | ||
186 | * Driver interacts with Firmware API version 1. | ||
187 | * } | ||
188 | * | ||
189 | * The ideal usage of this infrastructure is to treat a new ucode API | ||
190 | * release as a new hardware revision. That is, through utilizing the | ||
191 | * iwl_hcmd_utils_ops etc. we accommodate different command structures | ||
192 | * and flows between hardware versions (4965/5000) as well as their API | ||
193 | * versions. | ||
194 | */ | ||
167 | struct iwl_cfg { | 195 | struct iwl_cfg { |
168 | const char *name; | 196 | const char *name; |
169 | const char *fw_name; | 197 | const char *fw_name_pre; |
198 | const unsigned int ucode_api_max; | ||
199 | const unsigned int ucode_api_min; | ||
170 | unsigned int sku; | 200 | unsigned int sku; |
171 | int eeprom_size; | 201 | int eeprom_size; |
172 | u16 eeprom_ver; | 202 | u16 eeprom_ver; |
@@ -313,6 +343,12 @@ int iwl_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len, | |||
313 | int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd); | 343 | int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd); |
314 | 344 | ||
315 | /***************************************************** | 345 | /***************************************************** |
346 | * PCI * | ||
347 | *****************************************************/ | ||
348 | void iwl_disable_interrupts(struct iwl_priv *priv); | ||
349 | void iwl_enable_interrupts(struct iwl_priv *priv); | ||
350 | |||
351 | /***************************************************** | ||
316 | * Error Handling Debugging | 352 | * Error Handling Debugging |
317 | ******************************************************/ | 353 | ******************************************************/ |
318 | void iwl_dump_nic_error_log(struct iwl_priv *priv); | 354 | void iwl_dump_nic_error_log(struct iwl_priv *priv); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 0e79a6ab4c81..a115dc64f6a6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h | |||
@@ -60,6 +60,7 @@ struct iwl_debugfs { | |||
60 | struct dentry *file_rx_statistics; | 60 | struct dentry *file_rx_statistics; |
61 | struct dentry *file_tx_statistics; | 61 | struct dentry *file_tx_statistics; |
62 | struct dentry *file_log_event; | 62 | struct dentry *file_log_event; |
63 | struct dentry *file_channels; | ||
63 | } dbgfs_data_files; | 64 | } dbgfs_data_files; |
64 | struct dir_rf_files { | 65 | struct dir_rf_files { |
65 | struct dentry *file_disable_sensitivity; | 66 | struct dentry *file_disable_sensitivity; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index c3df5aa8df91..370b66c444b3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c | |||
@@ -348,12 +348,86 @@ static ssize_t iwl_dbgfs_log_event_write(struct file *file, | |||
348 | return count; | 348 | return count; |
349 | } | 349 | } |
350 | 350 | ||
351 | |||
352 | |||
353 | static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf, | ||
354 | size_t count, loff_t *ppos) | ||
355 | { | ||
356 | struct iwl_priv *priv = (struct iwl_priv *)file->private_data; | ||
357 | struct ieee80211_channel *channels = NULL; | ||
358 | const struct ieee80211_supported_band *supp_band = NULL; | ||
359 | int pos = 0, i, bufsz = PAGE_SIZE; | ||
360 | char *buf; | ||
361 | ssize_t ret; | ||
362 | |||
363 | if (!test_bit(STATUS_GEO_CONFIGURED, &priv->status)) | ||
364 | return -EAGAIN; | ||
365 | |||
366 | buf = kzalloc(bufsz, GFP_KERNEL); | ||
367 | if (!buf) { | ||
368 | IWL_ERROR("Can not allocate Buffer\n"); | ||
369 | return -ENOMEM; | ||
370 | } | ||
371 | |||
372 | supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_2GHZ); | ||
373 | channels = supp_band->channels; | ||
374 | |||
375 | pos += scnprintf(buf + pos, bufsz - pos, | ||
376 | "Displaying %d channels in 2.4GHz band 802.11bg):\n", | ||
377 | supp_band->n_channels); | ||
378 | |||
379 | for (i = 0; i < supp_band->n_channels; i++) | ||
380 | pos += scnprintf(buf + pos, bufsz - pos, | ||
381 | "%d: %ddBm: BSS%s%s, %s.\n", | ||
382 | ieee80211_frequency_to_channel( | ||
383 | channels[i].center_freq), | ||
384 | channels[i].max_power, | ||
385 | channels[i].flags & IEEE80211_CHAN_RADAR ? | ||
386 | " (IEEE 802.11h required)" : "", | ||
387 | (!(channels[i].flags & IEEE80211_CHAN_NO_IBSS) | ||
388 | || (channels[i].flags & | ||
389 | IEEE80211_CHAN_RADAR)) ? "" : | ||
390 | ", IBSS", | ||
391 | channels[i].flags & | ||
392 | IEEE80211_CHAN_PASSIVE_SCAN ? | ||
393 | "passive only" : "active/passive"); | ||
394 | |||
395 | supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_5GHZ); | ||
396 | channels = supp_band->channels; | ||
397 | |||
398 | pos += scnprintf(buf + pos, bufsz - pos, | ||
399 | "Displaying %d channels in 5.2GHz band (802.11a)\n", | ||
400 | supp_band->n_channels); | ||
401 | |||
402 | for (i = 0; i < supp_band->n_channels; i++) | ||
403 | pos += scnprintf(buf + pos, bufsz - pos, | ||
404 | "%d: %ddBm: BSS%s%s, %s.\n", | ||
405 | ieee80211_frequency_to_channel( | ||
406 | channels[i].center_freq), | ||
407 | channels[i].max_power, | ||
408 | channels[i].flags & IEEE80211_CHAN_RADAR ? | ||
409 | " (IEEE 802.11h required)" : "", | ||
410 | ((channels[i].flags & IEEE80211_CHAN_NO_IBSS) | ||
411 | || (channels[i].flags & | ||
412 | IEEE80211_CHAN_RADAR)) ? "" : | ||
413 | ", IBSS", | ||
414 | channels[i].flags & | ||
415 | IEEE80211_CHAN_PASSIVE_SCAN ? | ||
416 | "passive only" : "active/passive"); | ||
417 | |||
418 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
419 | kfree(buf); | ||
420 | return ret; | ||
421 | } | ||
422 | |||
423 | |||
351 | DEBUGFS_READ_WRITE_FILE_OPS(sram); | 424 | DEBUGFS_READ_WRITE_FILE_OPS(sram); |
352 | DEBUGFS_WRITE_FILE_OPS(log_event); | 425 | DEBUGFS_WRITE_FILE_OPS(log_event); |
353 | DEBUGFS_READ_FILE_OPS(eeprom); | 426 | DEBUGFS_READ_FILE_OPS(eeprom); |
354 | DEBUGFS_READ_FILE_OPS(stations); | 427 | DEBUGFS_READ_FILE_OPS(stations); |
355 | DEBUGFS_READ_FILE_OPS(rx_statistics); | 428 | DEBUGFS_READ_FILE_OPS(rx_statistics); |
356 | DEBUGFS_READ_FILE_OPS(tx_statistics); | 429 | DEBUGFS_READ_FILE_OPS(tx_statistics); |
430 | DEBUGFS_READ_FILE_OPS(channels); | ||
357 | 431 | ||
358 | /* | 432 | /* |
359 | * Create the debugfs files and directories | 433 | * Create the debugfs files and directories |
@@ -387,6 +461,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) | |||
387 | DEBUGFS_ADD_FILE(stations, data); | 461 | DEBUGFS_ADD_FILE(stations, data); |
388 | DEBUGFS_ADD_FILE(rx_statistics, data); | 462 | DEBUGFS_ADD_FILE(rx_statistics, data); |
389 | DEBUGFS_ADD_FILE(tx_statistics, data); | 463 | DEBUGFS_ADD_FILE(tx_statistics, data); |
464 | DEBUGFS_ADD_FILE(channels, data); | ||
390 | DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal); | 465 | DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal); |
391 | DEBUGFS_ADD_BOOL(disable_chain_noise, rf, | 466 | DEBUGFS_ADD_BOOL(disable_chain_noise, rf, |
392 | &priv->disable_chain_noise_cal); | 467 | &priv->disable_chain_noise_cal); |
@@ -415,6 +490,7 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv) | |||
415 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sram); | 490 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sram); |
416 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_log_event); | 491 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_log_event); |
417 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations); | 492 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations); |
493 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_channels); | ||
418 | DEBUGFS_REMOVE(priv->dbgfs->dir_data); | 494 | DEBUGFS_REMOVE(priv->dbgfs->dir_data); |
419 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity); | 495 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity); |
420 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise); | 496 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 4da988e0eae0..a19fbb5eaae4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -54,6 +54,7 @@ extern struct iwl_cfg iwl5100_agn_cfg; | |||
54 | extern struct iwl_cfg iwl5350_agn_cfg; | 54 | extern struct iwl_cfg iwl5350_agn_cfg; |
55 | extern struct iwl_cfg iwl5100_bg_cfg; | 55 | extern struct iwl_cfg iwl5100_bg_cfg; |
56 | extern struct iwl_cfg iwl5100_abg_cfg; | 56 | extern struct iwl_cfg iwl5100_abg_cfg; |
57 | extern struct iwl_cfg iwl5150_agn_cfg; | ||
57 | 58 | ||
58 | /* CT-KILL constants */ | 59 | /* CT-KILL constants */ |
59 | #define CT_KILL_THRESHOLD 110 /* in Celsius */ | 60 | #define CT_KILL_THRESHOLD 110 /* in Celsius */ |
@@ -461,7 +462,7 @@ struct fw_desc { | |||
461 | 462 | ||
462 | /* uCode file layout */ | 463 | /* uCode file layout */ |
463 | struct iwl_ucode { | 464 | struct iwl_ucode { |
464 | __le32 ver; /* major/minor/subminor */ | 465 | __le32 ver; /* major/minor/API/serial */ |
465 | __le32 inst_size; /* bytes of runtime instructions */ | 466 | __le32 inst_size; /* bytes of runtime instructions */ |
466 | __le32 data_size; /* bytes of runtime data */ | 467 | __le32 data_size; /* bytes of runtime data */ |
467 | __le32 init_size; /* bytes of initialization instructions */ | 468 | __le32 init_size; /* bytes of initialization instructions */ |
@@ -507,6 +508,7 @@ struct iwl_sensitivity_ranges { | |||
507 | /** | 508 | /** |
508 | * struct iwl_hw_params | 509 | * struct iwl_hw_params |
509 | * @max_txq_num: Max # Tx queues supported | 510 | * @max_txq_num: Max # Tx queues supported |
511 | * @dma_chnl_num: Number of Tx DMA/FIFO channels | ||
510 | * @scd_bc_tbls_size: size of scheduler byte count tables | 512 | * @scd_bc_tbls_size: size of scheduler byte count tables |
511 | * @tx/rx_chains_num: Number of TX/RX chains | 513 | * @tx/rx_chains_num: Number of TX/RX chains |
512 | * @valid_tx/rx_ant: usable antennas | 514 | * @valid_tx/rx_ant: usable antennas |
@@ -524,7 +526,8 @@ struct iwl_sensitivity_ranges { | |||
524 | * @struct iwl_sensitivity_ranges: range of sensitivity values | 526 | * @struct iwl_sensitivity_ranges: range of sensitivity values |
525 | */ | 527 | */ |
526 | struct iwl_hw_params { | 528 | struct iwl_hw_params { |
527 | u16 max_txq_num; | 529 | u8 max_txq_num; |
530 | u8 dma_chnl_num; | ||
528 | u16 scd_bc_tbls_size; | 531 | u16 scd_bc_tbls_size; |
529 | u8 tx_chains_num; | 532 | u8 tx_chains_num; |
530 | u8 rx_chains_num; | 533 | u8 rx_chains_num; |
@@ -692,6 +695,7 @@ struct statistics_general_data { | |||
692 | */ | 695 | */ |
693 | enum iwl_calib { | 696 | enum iwl_calib { |
694 | IWL_CALIB_XTAL, | 697 | IWL_CALIB_XTAL, |
698 | IWL_CALIB_DC, | ||
695 | IWL_CALIB_LO, | 699 | IWL_CALIB_LO, |
696 | IWL_CALIB_TX_IQ, | 700 | IWL_CALIB_TX_IQ, |
697 | IWL_CALIB_TX_IQ_PERD, | 701 | IWL_CALIB_TX_IQ_PERD, |
@@ -839,6 +843,8 @@ struct iwl_priv { | |||
839 | u8 rev_id; | 843 | u8 rev_id; |
840 | 844 | ||
841 | /* uCode images, save to reload in case of failure */ | 845 | /* uCode images, save to reload in case of failure */ |
846 | u32 ucode_ver; /* version of ucode, copy of | ||
847 | iwl_ucode.ver */ | ||
842 | struct fw_desc ucode_code; /* runtime inst */ | 848 | struct fw_desc ucode_code; /* runtime inst */ |
843 | struct fw_desc ucode_data; /* runtime data original */ | 849 | struct fw_desc ucode_data; /* runtime data original */ |
844 | struct fw_desc ucode_data_backup; /* runtime data save/restore */ | 850 | struct fw_desc ucode_data_backup; /* runtime data save/restore */ |
@@ -1084,9 +1090,4 @@ static inline int is_channel_ibss(const struct iwl_channel_info *ch) | |||
1084 | return ((ch->flags & EEPROM_CHANNEL_IBSS)) ? 1 : 0; | 1090 | return ((ch->flags & EEPROM_CHANNEL_IBSS)) ? 1 : 0; |
1085 | } | 1091 | } |
1086 | 1092 | ||
1087 | extern const struct iwl_channel_info *iwl_get_channel_info( | ||
1088 | const struct iwl_priv *priv, enum ieee80211_band band, u16 channel); | ||
1089 | |||
1090 | /* Requires full declaration of iwl_priv before including */ | ||
1091 | |||
1092 | #endif /* __iwl_dev_h__ */ | 1093 | #endif /* __iwl_dev_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index 997f23c8db2e..8f6b05fa2330 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h | |||
@@ -147,6 +147,7 @@ struct iwl_eeprom_channel { | |||
147 | /*5000 calibrations */ | 147 | /*5000 calibrations */ |
148 | #define EEPROM_5000_CALIB_ALL (INDIRECT_ADDRESS | INDIRECT_CALIBRATION) | 148 | #define EEPROM_5000_CALIB_ALL (INDIRECT_ADDRESS | INDIRECT_CALIBRATION) |
149 | #define EEPROM_5000_XTAL ((2*0x128) | EEPROM_5000_CALIB_ALL) | 149 | #define EEPROM_5000_XTAL ((2*0x128) | EEPROM_5000_CALIB_ALL) |
150 | #define EEPROM_5000_TEMPERATURE ((2*0x12A) | EEPROM_5000_CALIB_ALL) | ||
150 | 151 | ||
151 | /* 5000 links */ | 152 | /* 5000 links */ |
152 | #define EEPROM_5000_LINK_HOST (2*0x64) | 153 | #define EEPROM_5000_LINK_HOST (2*0x64) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index e045dfeaa1fe..18d6cf67d9b7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -611,7 +611,7 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv) | |||
611 | */ | 611 | */ |
612 | void iwl_txq_ctx_stop(struct iwl_priv *priv) | 612 | void iwl_txq_ctx_stop(struct iwl_priv *priv) |
613 | { | 613 | { |
614 | int txq_id; | 614 | int ch; |
615 | unsigned long flags; | 615 | unsigned long flags; |
616 | 616 | ||
617 | /* Turn off all Tx DMA fifos */ | 617 | /* Turn off all Tx DMA fifos */ |
@@ -624,12 +624,11 @@ void iwl_txq_ctx_stop(struct iwl_priv *priv) | |||
624 | priv->cfg->ops->lib->txq_set_sched(priv, 0); | 624 | priv->cfg->ops->lib->txq_set_sched(priv, 0); |
625 | 625 | ||
626 | /* Stop each Tx DMA channel, and wait for it to be idle */ | 626 | /* Stop each Tx DMA channel, and wait for it to be idle */ |
627 | for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { | 627 | for (ch = 0; ch < priv->hw_params.dma_chnl_num; ch++) { |
628 | iwl_write_direct32(priv, | 628 | iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0); |
629 | FH_TCSR_CHNL_TX_CONFIG_REG(txq_id), 0x0); | ||
630 | iwl_poll_direct_bit(priv, FH_TSSR_TX_STATUS_REG, | 629 | iwl_poll_direct_bit(priv, FH_TSSR_TX_STATUS_REG, |
631 | FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE | 630 | FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), |
632 | (txq_id), 200); | 631 | 200); |
633 | } | 632 | } |
634 | iwl_release_nic_access(priv); | 633 | iwl_release_nic_access(priv); |
635 | spin_unlock_irqrestore(&priv->lock, flags); | 634 | spin_unlock_irqrestore(&priv->lock, flags); |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 69fda64c6503..1a411c2d83e6 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -4311,35 +4311,6 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv) | |||
4311 | /* Safely ignore these bits for debug checks below */ | 4311 | /* Safely ignore these bits for debug checks below */ |
4312 | inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE); | 4312 | inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE); |
4313 | 4313 | ||
4314 | /* HW RF KILL switch toggled (4965 only) */ | ||
4315 | if (inta & CSR_INT_BIT_RF_KILL) { | ||
4316 | int hw_rf_kill = 0; | ||
4317 | if (!(iwl3945_read32(priv, CSR_GP_CNTRL) & | ||
4318 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) | ||
4319 | hw_rf_kill = 1; | ||
4320 | |||
4321 | IWL_DEBUG(IWL_DL_INFO | IWL_DL_RF_KILL | IWL_DL_ISR, | ||
4322 | "RF_KILL bit toggled to %s.\n", | ||
4323 | hw_rf_kill ? "disable radio" : "enable radio"); | ||
4324 | |||
4325 | /* Queue restart only if RF_KILL switch was set to "kill" | ||
4326 | * when we loaded driver, and is now set to "enable". | ||
4327 | * After we're Alive, RF_KILL gets handled by | ||
4328 | * iwl3945_rx_card_state_notif() */ | ||
4329 | if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status)) { | ||
4330 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | ||
4331 | queue_work(priv->workqueue, &priv->restart); | ||
4332 | } | ||
4333 | |||
4334 | handled |= CSR_INT_BIT_RF_KILL; | ||
4335 | } | ||
4336 | |||
4337 | /* Chip got too hot and stopped itself (4965 only) */ | ||
4338 | if (inta & CSR_INT_BIT_CT_KILL) { | ||
4339 | IWL_ERROR("Microcode CT kill error detected.\n"); | ||
4340 | handled |= CSR_INT_BIT_CT_KILL; | ||
4341 | } | ||
4342 | |||
4343 | /* Error detected by uCode */ | 4314 | /* Error detected by uCode */ |
4344 | if (inta & CSR_INT_BIT_SW_ERR) { | 4315 | if (inta & CSR_INT_BIT_SW_ERR) { |
4345 | IWL_ERROR("Microcode SW error detected. Restarting 0x%X.\n", | 4316 | IWL_ERROR("Microcode SW error detected. Restarting 0x%X.\n", |
@@ -4440,7 +4411,7 @@ static irqreturn_t iwl3945_isr(int irq, void *data) | |||
4440 | 4411 | ||
4441 | if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) { | 4412 | if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) { |
4442 | /* Hardware disappeared */ | 4413 | /* Hardware disappeared */ |
4443 | IWL_WARNING("HARDWARE GONE?? INTA == 0x%080x\n", inta); | 4414 | IWL_WARNING("HARDWARE GONE?? INTA == 0x%08x\n", inta); |
4444 | goto unplugged; | 4415 | goto unplugged; |
4445 | } | 4416 | } |
4446 | 4417 | ||
@@ -4814,17 +4785,33 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, | |||
4814 | continue; | 4785 | continue; |
4815 | } | 4786 | } |
4816 | 4787 | ||
4788 | scan_ch->active_dwell = cpu_to_le16(active_dwell); | ||
4789 | scan_ch->passive_dwell = cpu_to_le16(passive_dwell); | ||
4790 | /* If passive , set up for auto-switch | ||
4791 | * and use long active_dwell time. | ||
4792 | */ | ||
4817 | if (!is_active || is_channel_passive(ch_info) || | 4793 | if (!is_active || is_channel_passive(ch_info) || |
4818 | (channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN)) | 4794 | (channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN)) { |
4819 | scan_ch->type = 0; /* passive */ | 4795 | scan_ch->type = 0; /* passive */ |
4820 | else | 4796 | if (IWL_UCODE_API(priv->ucode_ver) == 1) |
4797 | scan_ch->active_dwell = cpu_to_le16(passive_dwell - 1); | ||
4798 | } else { | ||
4821 | scan_ch->type = 1; /* active */ | 4799 | scan_ch->type = 1; /* active */ |
4800 | } | ||
4822 | 4801 | ||
4823 | if ((scan_ch->type & 1) && n_probes) | 4802 | /* Set direct probe bits. These may be used both for active |
4824 | scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes); | 4803 | * scan channels (probes gets sent right away), |
4825 | 4804 | * or for passive channels (probes get se sent only after | |
4826 | scan_ch->active_dwell = cpu_to_le16(active_dwell); | 4805 | * hearing clear Rx packet).*/ |
4827 | scan_ch->passive_dwell = cpu_to_le16(passive_dwell); | 4806 | if (IWL_UCODE_API(priv->ucode_ver) >= 2) { |
4807 | if (n_probes) | ||
4808 | scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes); | ||
4809 | } else { | ||
4810 | /* uCode v1 does not allow setting direct probe bits on | ||
4811 | * passive channel. */ | ||
4812 | if ((scan_ch->type & 1) && n_probes) | ||
4813 | scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes); | ||
4814 | } | ||
4828 | 4815 | ||
4829 | /* Set txpower levels to defaults */ | 4816 | /* Set txpower levels to defaults */ |
4830 | scan_ch->tpc.dsp_atten = 110; | 4817 | scan_ch->tpc.dsp_atten = 110; |
@@ -5325,25 +5312,41 @@ static void iwl3945_nic_start(struct iwl3945_priv *priv) | |||
5325 | static int iwl3945_read_ucode(struct iwl3945_priv *priv) | 5312 | static int iwl3945_read_ucode(struct iwl3945_priv *priv) |
5326 | { | 5313 | { |
5327 | struct iwl3945_ucode *ucode; | 5314 | struct iwl3945_ucode *ucode; |
5328 | int ret = 0; | 5315 | int ret = -EINVAL, index; |
5329 | const struct firmware *ucode_raw; | 5316 | const struct firmware *ucode_raw; |
5330 | /* firmware file name contains uCode/driver compatibility version */ | 5317 | /* firmware file name contains uCode/driver compatibility version */ |
5331 | const char *name = priv->cfg->fw_name; | 5318 | const char *name_pre = priv->cfg->fw_name_pre; |
5319 | const unsigned int api_max = priv->cfg->ucode_api_max; | ||
5320 | const unsigned int api_min = priv->cfg->ucode_api_min; | ||
5321 | char buf[25]; | ||
5332 | u8 *src; | 5322 | u8 *src; |
5333 | size_t len; | 5323 | size_t len; |
5334 | u32 ver, inst_size, data_size, init_size, init_data_size, boot_size; | 5324 | u32 api_ver, inst_size, data_size, init_size, init_data_size, boot_size; |
5335 | 5325 | ||
5336 | /* Ask kernel firmware_class module to get the boot firmware off disk. | 5326 | /* Ask kernel firmware_class module to get the boot firmware off disk. |
5337 | * request_firmware() is synchronous, file is in memory on return. */ | 5327 | * request_firmware() is synchronous, file is in memory on return. */ |
5338 | ret = request_firmware(&ucode_raw, name, &priv->pci_dev->dev); | 5328 | for (index = api_max; index >= api_min; index--) { |
5339 | if (ret < 0) { | 5329 | sprintf(buf, "%s%u%s", name_pre, index, ".ucode"); |
5340 | IWL_ERROR("%s firmware file req failed: Reason %d\n", | 5330 | ret = request_firmware(&ucode_raw, buf, &priv->pci_dev->dev); |
5341 | name, ret); | 5331 | if (ret < 0) { |
5342 | goto error; | 5332 | IWL_ERROR("%s firmware file req failed: Reason %d\n", |
5333 | buf, ret); | ||
5334 | if (ret == -ENOENT) | ||
5335 | continue; | ||
5336 | else | ||
5337 | goto error; | ||
5338 | } else { | ||
5339 | if (index < api_max) | ||
5340 | IWL_ERROR("Loaded firmware %s, which is deprecated. Please use API v%u instead.\n", | ||
5341 | buf, api_max); | ||
5342 | IWL_DEBUG_INFO("Got firmware '%s' file (%zd bytes) from disk\n", | ||
5343 | buf, ucode_raw->size); | ||
5344 | break; | ||
5345 | } | ||
5343 | } | 5346 | } |
5344 | 5347 | ||
5345 | IWL_DEBUG_INFO("Got firmware '%s' file (%zd bytes) from disk\n", | 5348 | if (ret < 0) |
5346 | name, ucode_raw->size); | 5349 | goto error; |
5347 | 5350 | ||
5348 | /* Make sure that we got at least our header! */ | 5351 | /* Make sure that we got at least our header! */ |
5349 | if (ucode_raw->size < sizeof(*ucode)) { | 5352 | if (ucode_raw->size < sizeof(*ucode)) { |
@@ -5355,20 +5358,46 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv) | |||
5355 | /* Data from ucode file: header followed by uCode images */ | 5358 | /* Data from ucode file: header followed by uCode images */ |
5356 | ucode = (void *)ucode_raw->data; | 5359 | ucode = (void *)ucode_raw->data; |
5357 | 5360 | ||
5358 | ver = le32_to_cpu(ucode->ver); | 5361 | priv->ucode_ver = le32_to_cpu(ucode->ver); |
5362 | api_ver = IWL_UCODE_API(priv->ucode_ver); | ||
5359 | inst_size = le32_to_cpu(ucode->inst_size); | 5363 | inst_size = le32_to_cpu(ucode->inst_size); |
5360 | data_size = le32_to_cpu(ucode->data_size); | 5364 | data_size = le32_to_cpu(ucode->data_size); |
5361 | init_size = le32_to_cpu(ucode->init_size); | 5365 | init_size = le32_to_cpu(ucode->init_size); |
5362 | init_data_size = le32_to_cpu(ucode->init_data_size); | 5366 | init_data_size = le32_to_cpu(ucode->init_data_size); |
5363 | boot_size = le32_to_cpu(ucode->boot_size); | 5367 | boot_size = le32_to_cpu(ucode->boot_size); |
5364 | 5368 | ||
5365 | IWL_DEBUG_INFO("f/w package hdr ucode version = 0x%x\n", ver); | 5369 | /* api_ver should match the api version forming part of the |
5370 | * firmware filename ... but we don't check for that and only rely | ||
5371 | * on the API version read from firware header from here on forward */ | ||
5372 | |||
5373 | if (api_ver < api_min || api_ver > api_max) { | ||
5374 | IWL_ERROR("Driver unable to support your firmware API. " | ||
5375 | "Driver supports v%u, firmware is v%u.\n", | ||
5376 | api_max, api_ver); | ||
5377 | priv->ucode_ver = 0; | ||
5378 | ret = -EINVAL; | ||
5379 | goto err_release; | ||
5380 | } | ||
5381 | if (api_ver != api_max) | ||
5382 | IWL_ERROR("Firmware has old API version. Expected %u, " | ||
5383 | "got %u. New firmware can be obtained " | ||
5384 | "from http://www.intellinuxwireless.org.\n", | ||
5385 | api_max, api_ver); | ||
5386 | |||
5387 | printk(KERN_INFO DRV_NAME " loaded firmware version %u.%u.%u.%u\n", | ||
5388 | IWL_UCODE_MAJOR(priv->ucode_ver), | ||
5389 | IWL_UCODE_MINOR(priv->ucode_ver), | ||
5390 | IWL_UCODE_API(priv->ucode_ver), | ||
5391 | IWL_UCODE_SERIAL(priv->ucode_ver)); | ||
5392 | IWL_DEBUG_INFO("f/w package hdr ucode version raw = 0x%x\n", | ||
5393 | priv->ucode_ver); | ||
5366 | IWL_DEBUG_INFO("f/w package hdr runtime inst size = %u\n", inst_size); | 5394 | IWL_DEBUG_INFO("f/w package hdr runtime inst size = %u\n", inst_size); |
5367 | IWL_DEBUG_INFO("f/w package hdr runtime data size = %u\n", data_size); | 5395 | IWL_DEBUG_INFO("f/w package hdr runtime data size = %u\n", data_size); |
5368 | IWL_DEBUG_INFO("f/w package hdr init inst size = %u\n", init_size); | 5396 | IWL_DEBUG_INFO("f/w package hdr init inst size = %u\n", init_size); |
5369 | IWL_DEBUG_INFO("f/w package hdr init data size = %u\n", init_data_size); | 5397 | IWL_DEBUG_INFO("f/w package hdr init data size = %u\n", init_data_size); |
5370 | IWL_DEBUG_INFO("f/w package hdr boot inst size = %u\n", boot_size); | 5398 | IWL_DEBUG_INFO("f/w package hdr boot inst size = %u\n", boot_size); |
5371 | 5399 | ||
5400 | |||
5372 | /* Verify size of file vs. image size info in file's header */ | 5401 | /* Verify size of file vs. image size info in file's header */ |
5373 | if (ucode_raw->size < sizeof(*ucode) + | 5402 | if (ucode_raw->size < sizeof(*ucode) + |
5374 | inst_size + data_size + init_size + | 5403 | inst_size + data_size + init_size + |
@@ -7843,7 +7872,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
7843 | IEEE80211_HW_NOISE_DBM; | 7872 | IEEE80211_HW_NOISE_DBM; |
7844 | 7873 | ||
7845 | hw->wiphy->interface_modes = | 7874 | hw->wiphy->interface_modes = |
7846 | BIT(NL80211_IFTYPE_AP) | | ||
7847 | BIT(NL80211_IFTYPE_STATION) | | 7875 | BIT(NL80211_IFTYPE_STATION) | |
7848 | BIT(NL80211_IFTYPE_ADHOC); | 7876 | BIT(NL80211_IFTYPE_ADHOC); |
7849 | 7877 | ||
@@ -8328,7 +8356,7 @@ static void __exit iwl3945_exit(void) | |||
8328 | iwl3945_rate_control_unregister(); | 8356 | iwl3945_rate_control_unregister(); |
8329 | } | 8357 | } |
8330 | 8358 | ||
8331 | MODULE_FIRMWARE("iwlwifi-3945" IWL3945_UCODE_API ".ucode"); | 8359 | MODULE_FIRMWARE(IWL3945_MODULE_FIRMWARE(IWL3945_UCODE_API_MAX)); |
8332 | 8360 | ||
8333 | module_param_named(antenna, iwl3945_param_antenna, int, 0444); | 8361 | module_param_named(antenna, iwl3945_param_antenna, int, 0444); |
8334 | MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])"); | 8362 | MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])"); |
diff --git a/drivers/net/wireless/libertas/radiotap.h b/drivers/net/wireless/libertas/radiotap.h index 5d118f40cfbc..f8eb9097ff0a 100644 --- a/drivers/net/wireless/libertas/radiotap.h +++ b/drivers/net/wireless/libertas/radiotap.h | |||
@@ -6,9 +6,6 @@ struct tx_radiotap_hdr { | |||
6 | u8 txpower; | 6 | u8 txpower; |
7 | u8 rts_retries; | 7 | u8 rts_retries; |
8 | u8 data_retries; | 8 | u8 data_retries; |
9 | #if 0 | ||
10 | u8 pad[IEEE80211_RADIOTAP_HDRLEN - 12]; | ||
11 | #endif | ||
12 | } __attribute__ ((packed)); | 9 | } __attribute__ ((packed)); |
13 | 10 | ||
14 | #define TX_RADIOTAP_PRESENT ( \ | 11 | #define TX_RADIOTAP_PRESENT ( \ |
diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h index 491ab96c7b67..d2dbb9e15d97 100644 --- a/drivers/net/wireless/p54/p54.h +++ b/drivers/net/wireless/p54/p54.h | |||
@@ -85,7 +85,6 @@ struct p54_common { | |||
85 | struct mutex conf_mutex; | 85 | struct mutex conf_mutex; |
86 | u8 mac_addr[ETH_ALEN]; | 86 | u8 mac_addr[ETH_ALEN]; |
87 | u8 bssid[ETH_ALEN]; | 87 | u8 bssid[ETH_ALEN]; |
88 | u16 mac_mode; | ||
89 | struct pda_iq_autocal_entry *iq_autocal; | 88 | struct pda_iq_autocal_entry *iq_autocal; |
90 | unsigned int iq_autocal_len; | 89 | unsigned int iq_autocal_len; |
91 | struct pda_channel_output_limit *output_limit; | 90 | struct pda_channel_output_limit *output_limit; |
@@ -95,7 +94,6 @@ struct p54_common { | |||
95 | bool use_short_slot; | 94 | bool use_short_slot; |
96 | u16 rxhw; | 95 | u16 rxhw; |
97 | u8 version; | 96 | u8 version; |
98 | u8 rx_antenna; | ||
99 | unsigned int tx_hdr_len; | 97 | unsigned int tx_hdr_len; |
100 | unsigned int fw_var; | 98 | unsigned int fw_var; |
101 | unsigned int fw_interface; | 99 | unsigned int fw_interface; |
@@ -115,6 +113,8 @@ struct p54_common { | |||
115 | int noise; | 113 | int noise; |
116 | void *eeprom; | 114 | void *eeprom; |
117 | struct completion eeprom_comp; | 115 | struct completion eeprom_comp; |
116 | u8 privacy_caps; | ||
117 | u8 rx_keycache_size; | ||
118 | }; | 118 | }; |
119 | 119 | ||
120 | int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb); | 120 | int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb); |
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index 602392628e4e..89968a5bff84 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c | |||
@@ -25,6 +25,9 @@ | |||
25 | #include "p54.h" | 25 | #include "p54.h" |
26 | #include "p54common.h" | 26 | #include "p54common.h" |
27 | 27 | ||
28 | static int modparam_nohwcrypt; | ||
29 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); | ||
30 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); | ||
28 | MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>"); | 31 | MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>"); |
29 | MODULE_DESCRIPTION("Softmac Prism54 common code"); | 32 | MODULE_DESCRIPTION("Softmac Prism54 common code"); |
30 | MODULE_LICENSE("GPL"); | 33 | MODULE_LICENSE("GPL"); |
@@ -155,21 +158,21 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) | |||
155 | priv->fw_interface = be32_to_cpup((__be32 *) | 158 | priv->fw_interface = be32_to_cpup((__be32 *) |
156 | bootrec->data); | 159 | bootrec->data); |
157 | switch (priv->fw_interface) { | 160 | switch (priv->fw_interface) { |
158 | case FW_FMAC: | ||
159 | printk(KERN_INFO "p54: FreeMAC firmware\n"); | ||
160 | break; | ||
161 | case FW_LM20: | ||
162 | printk(KERN_INFO "p54: LM20 firmware\n"); | ||
163 | break; | ||
164 | case FW_LM86: | 161 | case FW_LM86: |
165 | printk(KERN_INFO "p54: LM86 firmware\n"); | 162 | case FW_LM20: |
166 | break; | 163 | case FW_LM87: { |
167 | case FW_LM87: | 164 | char *iftype = (char *)bootrec->data; |
168 | printk(KERN_INFO "p54: LM87 firmware\n"); | 165 | printk(KERN_INFO "%s: p54 detected a LM%c%c " |
166 | "firmware\n", | ||
167 | wiphy_name(dev->wiphy), | ||
168 | iftype[2], iftype[3]); | ||
169 | break; | 169 | break; |
170 | } | ||
171 | case FW_FMAC: | ||
170 | default: | 172 | default: |
171 | printk(KERN_INFO "p54: unknown firmware\n"); | 173 | printk(KERN_ERR "%s: unsupported firmware\n", |
172 | break; | 174 | wiphy_name(dev->wiphy)); |
175 | return -ENODEV; | ||
173 | } | 176 | } |
174 | break; | 177 | break; |
175 | case BR_CODE_COMPONENT_VERSION: | 178 | case BR_CODE_COMPONENT_VERSION: |
@@ -185,6 +188,8 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) | |||
185 | priv->rx_end = le32_to_cpu(desc->rx_end) - 0x3500; | 188 | priv->rx_end = le32_to_cpu(desc->rx_end) - 0x3500; |
186 | priv->headroom = desc->headroom; | 189 | priv->headroom = desc->headroom; |
187 | priv->tailroom = desc->tailroom; | 190 | priv->tailroom = desc->tailroom; |
191 | priv->privacy_caps = desc->privacy_caps; | ||
192 | priv->rx_keycache_size = desc->rx_keycache_size; | ||
188 | if (le32_to_cpu(bootrec->len) == 11) | 193 | if (le32_to_cpu(bootrec->len) == 11) |
189 | priv->rx_mtu = le16_to_cpu(desc->rx_mtu); | 194 | priv->rx_mtu = le16_to_cpu(desc->rx_mtu); |
190 | else | 195 | else |
@@ -211,13 +216,15 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) | |||
211 | } | 216 | } |
212 | 217 | ||
213 | if (fw_version) | 218 | if (fw_version) |
214 | printk(KERN_INFO "p54: FW rev %s - Softmac protocol %x.%x\n", | 219 | printk(KERN_INFO "%s: FW rev %s - Softmac protocol %x.%x\n", |
215 | fw_version, priv->fw_var >> 8, priv->fw_var & 0xff); | 220 | wiphy_name(dev->wiphy), fw_version, |
221 | priv->fw_var >> 8, priv->fw_var & 0xff); | ||
216 | 222 | ||
217 | if (priv->fw_var < 0x500) | 223 | if (priv->fw_var < 0x500) |
218 | printk(KERN_INFO "p54: you are using an obsolete firmware. " | 224 | printk(KERN_INFO "%s: you are using an obsolete firmware. " |
219 | "visit http://wireless.kernel.org/en/users/Drivers/p54 " | 225 | "visit http://wireless.kernel.org/en/users/Drivers/p54 " |
220 | "and grab one for \"kernel >= 2.6.28\"!\n"); | 226 | "and grab one for \"kernel >= 2.6.28\"!\n", |
227 | wiphy_name(dev->wiphy)); | ||
221 | 228 | ||
222 | if (priv->fw_var >= 0x300) { | 229 | if (priv->fw_var >= 0x300) { |
223 | /* Firmware supports QoS, use it! */ | 230 | /* Firmware supports QoS, use it! */ |
@@ -228,6 +235,16 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) | |||
228 | dev->queues = 4; | 235 | dev->queues = 4; |
229 | } | 236 | } |
230 | 237 | ||
238 | if (!modparam_nohwcrypt) | ||
239 | printk(KERN_INFO "%s: cryptographic accelerator " | ||
240 | "WEP:%s, TKIP:%s, CCMP:%s\n", | ||
241 | wiphy_name(dev->wiphy), | ||
242 | (priv->privacy_caps & BR_DESC_PRIV_CAP_WEP) ? "YES" : | ||
243 | "no", (priv->privacy_caps & (BR_DESC_PRIV_CAP_TKIP | | ||
244 | BR_DESC_PRIV_CAP_MICHAEL)) ? "YES" : "no", | ||
245 | (priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP) ? | ||
246 | "YES" : "no"); | ||
247 | |||
231 | return 0; | 248 | return 0; |
232 | } | 249 | } |
233 | EXPORT_SYMBOL_GPL(p54_parse_firmware); | 250 | EXPORT_SYMBOL_GPL(p54_parse_firmware); |
@@ -384,8 +401,9 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) | |||
384 | err = p54_convert_rev1(dev, curve_data); | 401 | err = p54_convert_rev1(dev, curve_data); |
385 | break; | 402 | break; |
386 | default: | 403 | default: |
387 | printk(KERN_ERR "p54: unknown curve data " | 404 | printk(KERN_ERR "%s: unknown curve data " |
388 | "revision %d\n", | 405 | "revision %d\n", |
406 | wiphy_name(dev->wiphy), | ||
389 | curve_data->cal_method_rev); | 407 | curve_data->cal_method_rev); |
390 | err = -ENODEV; | 408 | err = -ENODEV; |
391 | break; | 409 | break; |
@@ -445,7 +463,8 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) | |||
445 | case PDR_PER_CHANNEL_BASEBAND_REGISTERS: | 463 | case PDR_PER_CHANNEL_BASEBAND_REGISTERS: |
446 | break; | 464 | break; |
447 | default: | 465 | default: |
448 | printk(KERN_INFO "p54: unknown eeprom code : 0x%x\n", | 466 | printk(KERN_INFO "%s: unknown eeprom code : 0x%x\n", |
467 | wiphy_name(dev->wiphy), | ||
449 | le16_to_cpu(entry->code)); | 468 | le16_to_cpu(entry->code)); |
450 | break; | 469 | break; |
451 | } | 470 | } |
@@ -455,7 +474,8 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) | |||
455 | 474 | ||
456 | if (!synth || !priv->iq_autocal || !priv->output_limit || | 475 | if (!synth || !priv->iq_autocal || !priv->output_limit || |
457 | !priv->curve_data) { | 476 | !priv->curve_data) { |
458 | printk(KERN_ERR "p54: not all required entries found in eeprom!\n"); | 477 | printk(KERN_ERR "%s: not all required entries found in eeprom!\n", |
478 | wiphy_name(dev->wiphy)); | ||
459 | err = -EINVAL; | 479 | err = -EINVAL; |
460 | goto err; | 480 | goto err; |
461 | } | 481 | } |
@@ -500,7 +520,8 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) | |||
500 | priv->curve_data = NULL; | 520 | priv->curve_data = NULL; |
501 | } | 521 | } |
502 | 522 | ||
503 | printk(KERN_ERR "p54: eeprom parse failed!\n"); | 523 | printk(KERN_ERR "%s: eeprom parse failed!\n", |
524 | wiphy_name(dev->wiphy)); | ||
504 | return err; | 525 | return err; |
505 | } | 526 | } |
506 | 527 | ||
@@ -526,6 +547,12 @@ static int p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
526 | return 0; | 547 | return 0; |
527 | } | 548 | } |
528 | 549 | ||
550 | if (hdr->decrypt_status == P54_DECRYPT_OK) | ||
551 | rx_status.flag |= RX_FLAG_DECRYPTED; | ||
552 | if ((hdr->decrypt_status == P54_DECRYPT_FAIL_MICHAEL) || | ||
553 | (hdr->decrypt_status == P54_DECRYPT_FAIL_TKIP)) | ||
554 | rx_status.flag |= RX_FLAG_MMIC_ERROR; | ||
555 | |||
529 | rx_status.signal = p54_rssi_to_dbm(dev, hdr->rssi); | 556 | rx_status.signal = p54_rssi_to_dbm(dev, hdr->rssi); |
530 | rx_status.noise = priv->noise; | 557 | rx_status.noise = priv->noise; |
531 | /* XX correct? */ | 558 | /* XX correct? */ |
@@ -652,6 +679,10 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
652 | __skb_unlink(entry, &priv->tx_queue); | 679 | __skb_unlink(entry, &priv->tx_queue); |
653 | spin_unlock_irqrestore(&priv->tx_queue.lock, flags); | 680 | spin_unlock_irqrestore(&priv->tx_queue.lock, flags); |
654 | 681 | ||
682 | entry_hdr = (struct p54_hdr *) entry->data; | ||
683 | entry_data = (struct p54_tx_data *) entry_hdr->data; | ||
684 | priv->tx_stats[entry_data->hw_queue].len--; | ||
685 | |||
655 | if (unlikely(entry == priv->cached_beacon)) { | 686 | if (unlikely(entry == priv->cached_beacon)) { |
656 | kfree_skb(entry); | 687 | kfree_skb(entry); |
657 | priv->cached_beacon = NULL; | 688 | priv->cached_beacon = NULL; |
@@ -668,8 +699,6 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
668 | BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, | 699 | BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, |
669 | status.ampdu_ack_len) != 23); | 700 | status.ampdu_ack_len) != 23); |
670 | 701 | ||
671 | entry_hdr = (struct p54_hdr *) entry->data; | ||
672 | entry_data = (struct p54_tx_data *) entry_hdr->data; | ||
673 | if (entry_hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_ALIGN)) | 702 | if (entry_hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_ALIGN)) |
674 | pad = entry_data->align[0]; | 703 | pad = entry_data->align[0]; |
675 | 704 | ||
@@ -687,7 +716,6 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
687 | } | 716 | } |
688 | } | 717 | } |
689 | 718 | ||
690 | priv->tx_stats[entry_data->hw_queue].len--; | ||
691 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && | 719 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && |
692 | (!payload->status)) | 720 | (!payload->status)) |
693 | info->flags |= IEEE80211_TX_STAT_ACK; | 721 | info->flags |= IEEE80211_TX_STAT_ACK; |
@@ -717,7 +745,13 @@ static void p54_rx_eeprom_readback(struct ieee80211_hw *dev, | |||
717 | if (!priv->eeprom) | 745 | if (!priv->eeprom) |
718 | return ; | 746 | return ; |
719 | 747 | ||
720 | memcpy(priv->eeprom, eeprom->data, le16_to_cpu(eeprom->len)); | 748 | if (priv->fw_var >= 0x509) { |
749 | memcpy(priv->eeprom, eeprom->v2.data, | ||
750 | le16_to_cpu(eeprom->v2.len)); | ||
751 | } else { | ||
752 | memcpy(priv->eeprom, eeprom->v1.data, | ||
753 | le16_to_cpu(eeprom->v1.len)); | ||
754 | } | ||
721 | 755 | ||
722 | complete(&priv->eeprom_comp); | 756 | complete(&priv->eeprom_comp); |
723 | } | 757 | } |
@@ -918,12 +952,18 @@ int p54_read_eeprom(struct ieee80211_hw *dev) | |||
918 | struct p54_hdr *hdr = NULL; | 952 | struct p54_hdr *hdr = NULL; |
919 | struct p54_eeprom_lm86 *eeprom_hdr; | 953 | struct p54_eeprom_lm86 *eeprom_hdr; |
920 | struct sk_buff *skb; | 954 | struct sk_buff *skb; |
921 | size_t eeprom_size = 0x2020, offset = 0, blocksize; | 955 | size_t eeprom_size = 0x2020, offset = 0, blocksize, maxblocksize; |
922 | int ret = -ENOMEM; | 956 | int ret = -ENOMEM; |
923 | void *eeprom = NULL; | 957 | void *eeprom = NULL; |
924 | 958 | ||
925 | skb = p54_alloc_skb(dev, 0x8000, sizeof(*hdr) + sizeof(*eeprom_hdr) + | 959 | maxblocksize = EEPROM_READBACK_LEN; |
926 | EEPROM_READBACK_LEN, | 960 | if (priv->fw_var >= 0x509) |
961 | maxblocksize -= 0xc; | ||
962 | else | ||
963 | maxblocksize -= 0x4; | ||
964 | |||
965 | skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL, sizeof(*hdr) + | ||
966 | sizeof(*eeprom_hdr) + maxblocksize, | ||
927 | P54_CONTROL_TYPE_EEPROM_READBACK, GFP_KERNEL); | 967 | P54_CONTROL_TYPE_EEPROM_READBACK, GFP_KERNEL); |
928 | if (!skb) | 968 | if (!skb) |
929 | goto free; | 969 | goto free; |
@@ -935,12 +975,19 @@ int p54_read_eeprom(struct ieee80211_hw *dev) | |||
935 | goto free; | 975 | goto free; |
936 | 976 | ||
937 | eeprom_hdr = (struct p54_eeprom_lm86 *) skb_put(skb, | 977 | eeprom_hdr = (struct p54_eeprom_lm86 *) skb_put(skb, |
938 | sizeof(*eeprom_hdr) + EEPROM_READBACK_LEN); | 978 | sizeof(*eeprom_hdr) + maxblocksize); |
939 | 979 | ||
940 | while (eeprom_size) { | 980 | while (eeprom_size) { |
941 | blocksize = min(eeprom_size, (size_t)EEPROM_READBACK_LEN); | 981 | blocksize = min(eeprom_size, maxblocksize); |
942 | eeprom_hdr->offset = cpu_to_le16(offset); | 982 | if (priv->fw_var < 0x509) { |
943 | eeprom_hdr->len = cpu_to_le16(blocksize); | 983 | eeprom_hdr->v1.offset = cpu_to_le16(offset); |
984 | eeprom_hdr->v1.len = cpu_to_le16(blocksize); | ||
985 | } else { | ||
986 | eeprom_hdr->v2.offset = cpu_to_le32(offset); | ||
987 | eeprom_hdr->v2.len = cpu_to_le16(blocksize); | ||
988 | eeprom_hdr->v2.magic2 = 0xf; | ||
989 | memcpy(eeprom_hdr->v2.magic, (const char *)"LOCK", 4); | ||
990 | } | ||
944 | priv->tx(dev, skb, 0); | 991 | priv->tx(dev, skb, 0); |
945 | 992 | ||
946 | if (!wait_for_completion_interruptible_timeout(&priv->eeprom_comp, HZ)) { | 993 | if (!wait_for_completion_interruptible_timeout(&priv->eeprom_comp, HZ)) { |
@@ -1004,6 +1051,38 @@ static int p54_sta_unlock(struct ieee80211_hw *dev, u8 *addr) | |||
1004 | return 0; | 1051 | return 0; |
1005 | } | 1052 | } |
1006 | 1053 | ||
1054 | static void p54_sta_notify_ps(struct ieee80211_hw *dev, | ||
1055 | enum sta_notify_ps_cmd notify_cmd, | ||
1056 | struct ieee80211_sta *sta) | ||
1057 | { | ||
1058 | switch (notify_cmd) { | ||
1059 | case STA_NOTIFY_AWAKE: | ||
1060 | p54_sta_unlock(dev, sta->addr); | ||
1061 | break; | ||
1062 | default: | ||
1063 | break; | ||
1064 | } | ||
1065 | } | ||
1066 | |||
1067 | static void p54_sta_notify(struct ieee80211_hw *dev, struct ieee80211_vif *vif, | ||
1068 | enum sta_notify_cmd notify_cmd, | ||
1069 | struct ieee80211_sta *sta) | ||
1070 | { | ||
1071 | switch (notify_cmd) { | ||
1072 | case STA_NOTIFY_ADD: | ||
1073 | case STA_NOTIFY_REMOVE: | ||
1074 | /* | ||
1075 | * Notify the firmware that we don't want or we don't | ||
1076 | * need to buffer frames for this station anymore. | ||
1077 | */ | ||
1078 | |||
1079 | p54_sta_unlock(dev, sta->addr); | ||
1080 | break; | ||
1081 | default: | ||
1082 | break; | ||
1083 | } | ||
1084 | } | ||
1085 | |||
1007 | static int p54_tx_cancel(struct ieee80211_hw *dev, struct sk_buff *entry) | 1086 | static int p54_tx_cancel(struct ieee80211_hw *dev, struct sk_buff *entry) |
1008 | { | 1087 | { |
1009 | struct p54_common *priv = dev->priv; | 1088 | struct p54_common *priv = dev->priv; |
@@ -1069,11 +1148,25 @@ static int p54_tx_fill(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
1069 | if (info->control.sta) | 1148 | if (info->control.sta) |
1070 | *aid = info->control.sta->aid; | 1149 | *aid = info->control.sta->aid; |
1071 | else | 1150 | else |
1072 | *flags = P54_HDR_FLAG_DATA_OUT_NOCANCEL; | 1151 | *flags |= P54_HDR_FLAG_DATA_OUT_NOCANCEL; |
1073 | } | 1152 | } |
1074 | return ret; | 1153 | return ret; |
1075 | } | 1154 | } |
1076 | 1155 | ||
1156 | static u8 p54_convert_algo(enum ieee80211_key_alg alg) | ||
1157 | { | ||
1158 | switch (alg) { | ||
1159 | case ALG_WEP: | ||
1160 | return P54_CRYPTO_WEP; | ||
1161 | case ALG_TKIP: | ||
1162 | return P54_CRYPTO_TKIPMICHAEL; | ||
1163 | case ALG_CCMP: | ||
1164 | return P54_CRYPTO_AESCCMP; | ||
1165 | default: | ||
1166 | return 0; | ||
1167 | } | ||
1168 | } | ||
1169 | |||
1077 | static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | 1170 | static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb) |
1078 | { | 1171 | { |
1079 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1172 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
@@ -1082,9 +1175,9 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
1082 | struct p54_hdr *hdr; | 1175 | struct p54_hdr *hdr; |
1083 | struct p54_tx_data *txhdr; | 1176 | struct p54_tx_data *txhdr; |
1084 | size_t padding, len, tim_len = 0; | 1177 | size_t padding, len, tim_len = 0; |
1085 | int i, j, ridx; | 1178 | int i, j, ridx, ret; |
1086 | u16 hdr_flags = 0, aid = 0; | 1179 | u16 hdr_flags = 0, aid = 0; |
1087 | u8 rate, queue; | 1180 | u8 rate, queue, crypt_offset = 0; |
1088 | u8 cts_rate = 0x20; | 1181 | u8 cts_rate = 0x20; |
1089 | u8 rc_flags; | 1182 | u8 rc_flags; |
1090 | u8 calculated_tries[4]; | 1183 | u8 calculated_tries[4]; |
@@ -1092,28 +1185,30 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
1092 | 1185 | ||
1093 | queue = skb_get_queue_mapping(skb); | 1186 | queue = skb_get_queue_mapping(skb); |
1094 | 1187 | ||
1095 | if (p54_tx_fill(dev, skb, info, &queue, &tim_len, &hdr_flags, &aid)) { | 1188 | ret = p54_tx_fill(dev, skb, info, &queue, &tim_len, &hdr_flags, &aid); |
1096 | current_queue = &priv->tx_stats[queue]; | 1189 | current_queue = &priv->tx_stats[queue]; |
1097 | if (unlikely(current_queue->len > current_queue->limit)) | 1190 | if (unlikely((current_queue->len > current_queue->limit) && ret)) |
1098 | return NETDEV_TX_BUSY; | 1191 | return NETDEV_TX_BUSY; |
1099 | current_queue->len++; | 1192 | current_queue->len++; |
1100 | current_queue->count++; | 1193 | current_queue->count++; |
1101 | if (current_queue->len == current_queue->limit) | 1194 | if ((current_queue->len == current_queue->limit) && ret) |
1102 | ieee80211_stop_queue(dev, skb_get_queue_mapping(skb)); | 1195 | ieee80211_stop_queue(dev, skb_get_queue_mapping(skb)); |
1103 | } | ||
1104 | 1196 | ||
1105 | padding = (unsigned long)(skb->data - (sizeof(*hdr) + sizeof(*txhdr))) & 3; | 1197 | padding = (unsigned long)(skb->data - (sizeof(*hdr) + sizeof(*txhdr))) & 3; |
1106 | len = skb->len; | 1198 | len = skb->len; |
1107 | 1199 | ||
1108 | if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) { | 1200 | if (info->control.hw_key) { |
1109 | if (info->control.sta) | 1201 | crypt_offset = ieee80211_get_hdrlen_from_skb(skb); |
1110 | if (p54_sta_unlock(dev, info->control.sta->addr)) { | 1202 | if (info->control.hw_key->alg == ALG_TKIP) { |
1111 | if (current_queue) { | 1203 | u8 *iv = (u8 *)(skb->data + crypt_offset); |
1112 | current_queue->len--; | 1204 | /* |
1113 | current_queue->count--; | 1205 | * The firmware excepts that the IV has to have |
1114 | } | 1206 | * this special format |
1115 | return NETDEV_TX_BUSY; | 1207 | */ |
1116 | } | 1208 | iv[1] = iv[0]; |
1209 | iv[0] = iv[2]; | ||
1210 | iv[2] = 0; | ||
1211 | } | ||
1117 | } | 1212 | } |
1118 | 1213 | ||
1119 | txhdr = (struct p54_tx_data *) skb_push(skb, sizeof(*txhdr) + padding); | 1214 | txhdr = (struct p54_tx_data *) skb_push(skb, sizeof(*txhdr) + padding); |
@@ -1121,7 +1216,6 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
1121 | 1216 | ||
1122 | if (padding) | 1217 | if (padding) |
1123 | hdr_flags |= P54_HDR_FLAG_DATA_ALIGN; | 1218 | hdr_flags |= P54_HDR_FLAG_DATA_ALIGN; |
1124 | hdr->len = cpu_to_le16(len); | ||
1125 | hdr->type = cpu_to_le16(aid); | 1219 | hdr->type = cpu_to_le16(aid); |
1126 | hdr->rts_tries = info->control.rates[0].count; | 1220 | hdr->rts_tries = info->control.rates[0].count; |
1127 | 1221 | ||
@@ -1196,10 +1290,27 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
1196 | /* TODO: enable bursting */ | 1290 | /* TODO: enable bursting */ |
1197 | hdr->flags = cpu_to_le16(hdr_flags); | 1291 | hdr->flags = cpu_to_le16(hdr_flags); |
1198 | hdr->tries = ridx; | 1292 | hdr->tries = ridx; |
1199 | txhdr->crypt_offset = 0; | ||
1200 | txhdr->rts_rate_idx = 0; | 1293 | txhdr->rts_rate_idx = 0; |
1201 | txhdr->key_type = 0; | 1294 | if (info->control.hw_key) { |
1202 | txhdr->key_len = 0; | 1295 | crypt_offset += info->control.hw_key->iv_len; |
1296 | txhdr->key_type = p54_convert_algo(info->control.hw_key->alg); | ||
1297 | txhdr->key_len = min((u8)16, info->control.hw_key->keylen); | ||
1298 | memcpy(txhdr->key, info->control.hw_key->key, txhdr->key_len); | ||
1299 | if (info->control.hw_key->alg == ALG_TKIP) { | ||
1300 | if (unlikely(skb_tailroom(skb) < 12)) | ||
1301 | goto err; | ||
1302 | /* reserve space for the MIC key */ | ||
1303 | len += 8; | ||
1304 | memcpy(skb_put(skb, 8), &(info->control.hw_key->key | ||
1305 | [NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY]), 8); | ||
1306 | } | ||
1307 | /* reserve some space for ICV */ | ||
1308 | len += info->control.hw_key->icv_len; | ||
1309 | } else { | ||
1310 | txhdr->key_type = 0; | ||
1311 | txhdr->key_len = 0; | ||
1312 | } | ||
1313 | txhdr->crypt_offset = crypt_offset; | ||
1203 | txhdr->hw_queue = queue; | 1314 | txhdr->hw_queue = queue; |
1204 | if (current_queue) | 1315 | if (current_queue) |
1205 | txhdr->backlog = current_queue->len; | 1316 | txhdr->backlog = current_queue->len; |
@@ -1213,24 +1324,28 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
1213 | if (padding) | 1324 | if (padding) |
1214 | txhdr->align[0] = padding; | 1325 | txhdr->align[0] = padding; |
1215 | 1326 | ||
1327 | hdr->len = cpu_to_le16(len); | ||
1216 | /* modifies skb->cb and with it info, so must be last! */ | 1328 | /* modifies skb->cb and with it info, so must be last! */ |
1217 | if (unlikely(p54_assign_address(dev, skb, hdr, skb->len + tim_len))) { | 1329 | if (unlikely(p54_assign_address(dev, skb, hdr, skb->len + tim_len))) |
1218 | skb_pull(skb, sizeof(*hdr) + sizeof(*txhdr) + padding); | 1330 | goto err; |
1219 | if (current_queue) { | ||
1220 | current_queue->len--; | ||
1221 | current_queue->count--; | ||
1222 | } | ||
1223 | return NETDEV_TX_BUSY; | ||
1224 | } | ||
1225 | priv->tx(dev, skb, 0); | 1331 | priv->tx(dev, skb, 0); |
1226 | return 0; | 1332 | return 0; |
1333 | |||
1334 | err: | ||
1335 | skb_pull(skb, sizeof(*hdr) + sizeof(*txhdr) + padding); | ||
1336 | if (current_queue) { | ||
1337 | current_queue->len--; | ||
1338 | current_queue->count--; | ||
1339 | } | ||
1340 | return NETDEV_TX_BUSY; | ||
1227 | } | 1341 | } |
1228 | 1342 | ||
1229 | static int p54_setup_mac(struct ieee80211_hw *dev, u16 mode, const u8 *bssid) | 1343 | static int p54_setup_mac(struct ieee80211_hw *dev) |
1230 | { | 1344 | { |
1231 | struct p54_common *priv = dev->priv; | 1345 | struct p54_common *priv = dev->priv; |
1232 | struct sk_buff *skb; | 1346 | struct sk_buff *skb; |
1233 | struct p54_setup_mac *setup; | 1347 | struct p54_setup_mac *setup; |
1348 | u16 mode; | ||
1234 | 1349 | ||
1235 | skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*setup) + | 1350 | skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*setup) + |
1236 | sizeof(struct p54_hdr), P54_CONTROL_TYPE_SETUP, | 1351 | sizeof(struct p54_hdr), P54_CONTROL_TYPE_SETUP, |
@@ -1239,14 +1354,31 @@ static int p54_setup_mac(struct ieee80211_hw *dev, u16 mode, const u8 *bssid) | |||
1239 | return -ENOMEM; | 1354 | return -ENOMEM; |
1240 | 1355 | ||
1241 | setup = (struct p54_setup_mac *) skb_put(skb, sizeof(*setup)); | 1356 | setup = (struct p54_setup_mac *) skb_put(skb, sizeof(*setup)); |
1242 | priv->mac_mode = mode; | 1357 | if (dev->conf.radio_enabled) { |
1358 | switch (priv->mode) { | ||
1359 | case NL80211_IFTYPE_STATION: | ||
1360 | mode = P54_FILTER_TYPE_STATION; | ||
1361 | break; | ||
1362 | case NL80211_IFTYPE_AP: | ||
1363 | mode = P54_FILTER_TYPE_AP; | ||
1364 | break; | ||
1365 | case NL80211_IFTYPE_ADHOC: | ||
1366 | case NL80211_IFTYPE_MESH_POINT: | ||
1367 | mode = P54_FILTER_TYPE_IBSS; | ||
1368 | break; | ||
1369 | default: | ||
1370 | mode = P54_FILTER_TYPE_NONE; | ||
1371 | break; | ||
1372 | } | ||
1373 | if (priv->filter_flags & FIF_PROMISC_IN_BSS) | ||
1374 | mode |= P54_FILTER_TYPE_TRANSPARENT; | ||
1375 | } else | ||
1376 | mode = P54_FILTER_TYPE_RX_DISABLED; | ||
1377 | |||
1243 | setup->mac_mode = cpu_to_le16(mode); | 1378 | setup->mac_mode = cpu_to_le16(mode); |
1244 | memcpy(setup->mac_addr, priv->mac_addr, ETH_ALEN); | 1379 | memcpy(setup->mac_addr, priv->mac_addr, ETH_ALEN); |
1245 | if (!bssid) | 1380 | memcpy(setup->bssid, priv->bssid, ETH_ALEN); |
1246 | memset(setup->bssid, ~0, ETH_ALEN); | 1381 | setup->rx_antenna = 2; /* automatic */ |
1247 | else | ||
1248 | memcpy(setup->bssid, bssid, ETH_ALEN); | ||
1249 | setup->rx_antenna = priv->rx_antenna; | ||
1250 | setup->rx_align = 0; | 1382 | setup->rx_align = 0; |
1251 | if (priv->fw_var < 0x500) { | 1383 | if (priv->fw_var < 0x500) { |
1252 | setup->v1.basic_rate_mask = cpu_to_le32(priv->basic_rate_mask); | 1384 | setup->v1.basic_rate_mask = cpu_to_le32(priv->basic_rate_mask); |
@@ -1275,7 +1407,8 @@ static int p54_setup_mac(struct ieee80211_hw *dev, u16 mode, const u8 *bssid) | |||
1275 | return 0; | 1407 | return 0; |
1276 | } | 1408 | } |
1277 | 1409 | ||
1278 | static int p54_set_freq(struct ieee80211_hw *dev, u16 frequency) | 1410 | static int p54_scan(struct ieee80211_hw *dev, u16 mode, u16 dwell, |
1411 | u16 frequency) | ||
1279 | { | 1412 | { |
1280 | struct p54_common *priv = dev->priv; | 1413 | struct p54_common *priv = dev->priv; |
1281 | struct sk_buff *skb; | 1414 | struct sk_buff *skb; |
@@ -1292,8 +1425,8 @@ static int p54_set_freq(struct ieee80211_hw *dev, u16 frequency) | |||
1292 | 1425 | ||
1293 | chan = (struct p54_scan *) skb_put(skb, sizeof(*chan)); | 1426 | chan = (struct p54_scan *) skb_put(skb, sizeof(*chan)); |
1294 | memset(chan->padding1, 0, sizeof(chan->padding1)); | 1427 | memset(chan->padding1, 0, sizeof(chan->padding1)); |
1295 | chan->mode = cpu_to_le16(P54_SCAN_EXIT); | 1428 | chan->mode = cpu_to_le16(mode); |
1296 | chan->dwell = cpu_to_le16(0x0); | 1429 | chan->dwell = cpu_to_le16(dwell); |
1297 | 1430 | ||
1298 | for (i = 0; i < priv->iq_autocal_len; i++) { | 1431 | for (i = 0; i < priv->iq_autocal_len; i++) { |
1299 | if (priv->iq_autocal[i].freq != freq) | 1432 | if (priv->iq_autocal[i].freq != freq) |
@@ -1446,28 +1579,23 @@ static int p54_beacon_tim(struct sk_buff *skb) | |||
1446 | struct ieee80211_mgmt *mgmt = (void *)skb->data; | 1579 | struct ieee80211_mgmt *mgmt = (void *)skb->data; |
1447 | u8 *pos, *end; | 1580 | u8 *pos, *end; |
1448 | 1581 | ||
1449 | if (skb->len <= sizeof(mgmt)) { | 1582 | if (skb->len <= sizeof(mgmt)) |
1450 | printk(KERN_ERR "p54: beacon is too short!\n"); | ||
1451 | return -EINVAL; | 1583 | return -EINVAL; |
1452 | } | ||
1453 | 1584 | ||
1454 | pos = (u8 *)mgmt->u.beacon.variable; | 1585 | pos = (u8 *)mgmt->u.beacon.variable; |
1455 | end = skb->data + skb->len; | 1586 | end = skb->data + skb->len; |
1456 | while (pos < end) { | 1587 | while (pos < end) { |
1457 | if (pos + 2 + pos[1] > end) { | 1588 | if (pos + 2 + pos[1] > end) |
1458 | printk(KERN_ERR "p54: parsing beacon failed\n"); | ||
1459 | return -EINVAL; | 1589 | return -EINVAL; |
1460 | } | ||
1461 | 1590 | ||
1462 | if (pos[0] == WLAN_EID_TIM) { | 1591 | if (pos[0] == WLAN_EID_TIM) { |
1463 | u8 dtim_len = pos[1]; | 1592 | u8 dtim_len = pos[1]; |
1464 | u8 dtim_period = pos[3]; | 1593 | u8 dtim_period = pos[3]; |
1465 | u8 *next = pos + 2 + dtim_len; | 1594 | u8 *next = pos + 2 + dtim_len; |
1466 | 1595 | ||
1467 | if (dtim_len < 3) { | 1596 | if (dtim_len < 3) |
1468 | printk(KERN_ERR "p54: invalid dtim len!\n"); | ||
1469 | return -EINVAL; | 1597 | return -EINVAL; |
1470 | } | 1598 | |
1471 | memmove(pos, next, end - next); | 1599 | memmove(pos, next, end - next); |
1472 | 1600 | ||
1473 | if (dtim_len > 3) | 1601 | if (dtim_len > 3) |
@@ -1536,10 +1664,14 @@ static int p54_start(struct ieee80211_hw *dev) | |||
1536 | err = p54_init_stats(dev); | 1664 | err = p54_init_stats(dev); |
1537 | if (err) | 1665 | if (err) |
1538 | goto out; | 1666 | goto out; |
1539 | err = p54_setup_mac(dev, P54_FILTER_TYPE_NONE, NULL); | 1667 | |
1540 | if (err) | 1668 | memset(priv->bssid, ~0, ETH_ALEN); |
1541 | goto out; | ||
1542 | priv->mode = NL80211_IFTYPE_MONITOR; | 1669 | priv->mode = NL80211_IFTYPE_MONITOR; |
1670 | err = p54_setup_mac(dev); | ||
1671 | if (err) { | ||
1672 | priv->mode = NL80211_IFTYPE_UNSPECIFIED; | ||
1673 | goto out; | ||
1674 | } | ||
1543 | 1675 | ||
1544 | out: | 1676 | out: |
1545 | mutex_unlock(&priv->conf_mutex); | 1677 | mutex_unlock(&priv->conf_mutex); |
@@ -1592,27 +1724,8 @@ static int p54_add_interface(struct ieee80211_hw *dev, | |||
1592 | } | 1724 | } |
1593 | 1725 | ||
1594 | memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN); | 1726 | memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN); |
1595 | 1727 | p54_setup_mac(dev); | |
1596 | p54_setup_mac(dev, P54_FILTER_TYPE_NONE, NULL); | ||
1597 | |||
1598 | switch (conf->type) { | ||
1599 | case NL80211_IFTYPE_STATION: | ||
1600 | p54_setup_mac(dev, P54_FILTER_TYPE_STATION, NULL); | ||
1601 | break; | ||
1602 | case NL80211_IFTYPE_AP: | ||
1603 | p54_setup_mac(dev, P54_FILTER_TYPE_AP, priv->mac_addr); | ||
1604 | break; | ||
1605 | case NL80211_IFTYPE_ADHOC: | ||
1606 | case NL80211_IFTYPE_MESH_POINT: | ||
1607 | p54_setup_mac(dev, P54_FILTER_TYPE_IBSS, NULL); | ||
1608 | break; | ||
1609 | default: | ||
1610 | BUG(); /* impossible */ | ||
1611 | break; | ||
1612 | } | ||
1613 | |||
1614 | p54_set_leds(dev, 1, 0, 0); | 1728 | p54_set_leds(dev, 1, 0, 0); |
1615 | |||
1616 | mutex_unlock(&priv->conf_mutex); | 1729 | mutex_unlock(&priv->conf_mutex); |
1617 | return 0; | 1730 | return 0; |
1618 | } | 1731 | } |
@@ -1625,9 +1738,10 @@ static void p54_remove_interface(struct ieee80211_hw *dev, | |||
1625 | mutex_lock(&priv->conf_mutex); | 1738 | mutex_lock(&priv->conf_mutex); |
1626 | if (priv->cached_beacon) | 1739 | if (priv->cached_beacon) |
1627 | p54_tx_cancel(dev, priv->cached_beacon); | 1740 | p54_tx_cancel(dev, priv->cached_beacon); |
1628 | p54_setup_mac(dev, P54_FILTER_TYPE_NONE, NULL); | ||
1629 | priv->mode = NL80211_IFTYPE_MONITOR; | 1741 | priv->mode = NL80211_IFTYPE_MONITOR; |
1630 | memset(priv->mac_addr, 0, ETH_ALEN); | 1742 | memset(priv->mac_addr, 0, ETH_ALEN); |
1743 | memset(priv->bssid, 0, ETH_ALEN); | ||
1744 | p54_setup_mac(dev); | ||
1631 | mutex_unlock(&priv->conf_mutex); | 1745 | mutex_unlock(&priv->conf_mutex); |
1632 | } | 1746 | } |
1633 | 1747 | ||
@@ -1638,11 +1752,21 @@ static int p54_config(struct ieee80211_hw *dev, u32 changed) | |||
1638 | struct ieee80211_conf *conf = &dev->conf; | 1752 | struct ieee80211_conf *conf = &dev->conf; |
1639 | 1753 | ||
1640 | mutex_lock(&priv->conf_mutex); | 1754 | mutex_lock(&priv->conf_mutex); |
1641 | priv->rx_antenna = 2; /* automatic */ | 1755 | if (changed & IEEE80211_CONF_CHANGE_POWER) |
1642 | priv->output_power = conf->power_level << 2; | 1756 | priv->output_power = conf->power_level << 2; |
1643 | ret = p54_set_freq(dev, conf->channel->center_freq); | 1757 | if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) { |
1644 | if (!ret) | 1758 | ret = p54_setup_mac(dev); |
1645 | ret = p54_set_edcf(dev); | 1759 | if (ret) |
1760 | goto out; | ||
1761 | } | ||
1762 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { | ||
1763 | ret = p54_scan(dev, P54_SCAN_EXIT, 0, | ||
1764 | conf->channel->center_freq); | ||
1765 | if (ret) | ||
1766 | goto out; | ||
1767 | } | ||
1768 | |||
1769 | out: | ||
1646 | mutex_unlock(&priv->conf_mutex); | 1770 | mutex_unlock(&priv->conf_mutex); |
1647 | return ret; | 1771 | return ret; |
1648 | } | 1772 | } |
@@ -1655,36 +1779,31 @@ static int p54_config_interface(struct ieee80211_hw *dev, | |||
1655 | int ret = 0; | 1779 | int ret = 0; |
1656 | 1780 | ||
1657 | mutex_lock(&priv->conf_mutex); | 1781 | mutex_lock(&priv->conf_mutex); |
1658 | switch (priv->mode) { | 1782 | if (conf->changed & IEEE80211_IFCC_BSSID) { |
1659 | case NL80211_IFTYPE_STATION: | 1783 | memcpy(priv->bssid, conf->bssid, ETH_ALEN); |
1660 | ret = p54_setup_mac(dev, P54_FILTER_TYPE_STATION, conf->bssid); | 1784 | ret = p54_setup_mac(dev); |
1661 | if (ret) | 1785 | if (ret) |
1662 | goto out; | 1786 | goto out; |
1663 | ret = p54_set_leds(dev, 1, | 1787 | } |
1664 | !is_multicast_ether_addr(conf->bssid), 0); | 1788 | |
1789 | if (conf->changed & IEEE80211_IFCC_BEACON) { | ||
1790 | ret = p54_scan(dev, P54_SCAN_EXIT, 0, | ||
1791 | dev->conf.channel->center_freq); | ||
1665 | if (ret) | 1792 | if (ret) |
1666 | goto out; | 1793 | goto out; |
1667 | memcpy(priv->bssid, conf->bssid, ETH_ALEN); | 1794 | ret = p54_setup_mac(dev); |
1668 | break; | ||
1669 | case NL80211_IFTYPE_AP: | ||
1670 | case NL80211_IFTYPE_ADHOC: | ||
1671 | case NL80211_IFTYPE_MESH_POINT: | ||
1672 | memcpy(priv->bssid, conf->bssid, ETH_ALEN); | ||
1673 | ret = p54_set_freq(dev, dev->conf.channel->center_freq); | ||
1674 | if (ret) | 1795 | if (ret) |
1675 | goto out; | 1796 | goto out; |
1676 | ret = p54_setup_mac(dev, priv->mac_mode, priv->bssid); | 1797 | ret = p54_beacon_update(dev, vif); |
1798 | if (ret) | ||
1799 | goto out; | ||
1800 | ret = p54_set_edcf(dev); | ||
1677 | if (ret) | 1801 | if (ret) |
1678 | goto out; | 1802 | goto out; |
1679 | if (conf->changed & IEEE80211_IFCC_BEACON) { | ||
1680 | ret = p54_beacon_update(dev, vif); | ||
1681 | if (ret) | ||
1682 | goto out; | ||
1683 | ret = p54_set_edcf(dev); | ||
1684 | if (ret) | ||
1685 | goto out; | ||
1686 | } | ||
1687 | } | 1803 | } |
1804 | |||
1805 | ret = p54_set_leds(dev, 1, !is_multicast_ether_addr(priv->bssid), 0); | ||
1806 | |||
1688 | out: | 1807 | out: |
1689 | mutex_unlock(&priv->conf_mutex); | 1808 | mutex_unlock(&priv->conf_mutex); |
1690 | return ret; | 1809 | return ret; |
@@ -1697,25 +1816,14 @@ static void p54_configure_filter(struct ieee80211_hw *dev, | |||
1697 | { | 1816 | { |
1698 | struct p54_common *priv = dev->priv; | 1817 | struct p54_common *priv = dev->priv; |
1699 | 1818 | ||
1700 | *total_flags &= FIF_BCN_PRBRESP_PROMISC | | 1819 | *total_flags &= FIF_PROMISC_IN_BSS | |
1701 | FIF_PROMISC_IN_BSS | | 1820 | (*total_flags & FIF_PROMISC_IN_BSS) ? |
1702 | FIF_FCSFAIL; | 1821 | FIF_FCSFAIL : 0; |
1703 | 1822 | ||
1704 | priv->filter_flags = *total_flags; | 1823 | priv->filter_flags = *total_flags; |
1705 | 1824 | ||
1706 | if (changed_flags & FIF_BCN_PRBRESP_PROMISC) { | 1825 | if (changed_flags & FIF_PROMISC_IN_BSS) |
1707 | if (*total_flags & FIF_BCN_PRBRESP_PROMISC) | 1826 | p54_setup_mac(dev); |
1708 | p54_setup_mac(dev, priv->mac_mode, NULL); | ||
1709 | else | ||
1710 | p54_setup_mac(dev, priv->mac_mode, priv->bssid); | ||
1711 | } | ||
1712 | |||
1713 | if (changed_flags & FIF_PROMISC_IN_BSS) { | ||
1714 | if (*total_flags & FIF_PROMISC_IN_BSS) | ||
1715 | p54_setup_mac(dev, priv->mac_mode | 0x8, NULL); | ||
1716 | else | ||
1717 | p54_setup_mac(dev, priv->mac_mode & ~0x8, priv->bssid); | ||
1718 | } | ||
1719 | } | 1827 | } |
1720 | 1828 | ||
1721 | static int p54_conf_tx(struct ieee80211_hw *dev, u16 queue, | 1829 | static int p54_conf_tx(struct ieee80211_hw *dev, u16 queue, |
@@ -1812,21 +1920,106 @@ static void p54_bss_info_changed(struct ieee80211_hw *dev, | |||
1812 | priv->basic_rate_mask = (info->basic_rates << 4); | 1920 | priv->basic_rate_mask = (info->basic_rates << 4); |
1813 | else | 1921 | else |
1814 | priv->basic_rate_mask = info->basic_rates; | 1922 | priv->basic_rate_mask = info->basic_rates; |
1815 | p54_setup_mac(dev, priv->mac_mode, priv->bssid); | 1923 | p54_setup_mac(dev); |
1816 | if (priv->fw_var >= 0x500) | 1924 | if (priv->fw_var >= 0x500) |
1817 | p54_set_freq(dev, dev->conf.channel->center_freq); | 1925 | p54_scan(dev, P54_SCAN_EXIT, 0, |
1926 | dev->conf.channel->center_freq); | ||
1818 | } | 1927 | } |
1819 | if (changed & BSS_CHANGED_ASSOC) { | 1928 | if (changed & BSS_CHANGED_ASSOC) { |
1820 | if (info->assoc) { | 1929 | if (info->assoc) { |
1821 | priv->aid = info->aid; | 1930 | priv->aid = info->aid; |
1822 | priv->wakeup_timer = info->beacon_int * | 1931 | priv->wakeup_timer = info->beacon_int * |
1823 | info->dtim_period * 5; | 1932 | info->dtim_period * 5; |
1824 | p54_setup_mac(dev, priv->mac_mode, priv->bssid); | 1933 | p54_setup_mac(dev); |
1825 | } | 1934 | } |
1826 | } | 1935 | } |
1827 | 1936 | ||
1828 | } | 1937 | } |
1829 | 1938 | ||
1939 | static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd, | ||
1940 | const u8 *local_address, const u8 *address, | ||
1941 | struct ieee80211_key_conf *key) | ||
1942 | { | ||
1943 | struct p54_common *priv = dev->priv; | ||
1944 | struct sk_buff *skb; | ||
1945 | struct p54_keycache *rxkey; | ||
1946 | u8 algo = 0; | ||
1947 | |||
1948 | if (modparam_nohwcrypt) | ||
1949 | return -EOPNOTSUPP; | ||
1950 | |||
1951 | if (cmd == DISABLE_KEY) | ||
1952 | algo = 0; | ||
1953 | else { | ||
1954 | switch (key->alg) { | ||
1955 | case ALG_TKIP: | ||
1956 | if (!(priv->privacy_caps & (BR_DESC_PRIV_CAP_MICHAEL | | ||
1957 | BR_DESC_PRIV_CAP_TKIP))) | ||
1958 | return -EOPNOTSUPP; | ||
1959 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; | ||
1960 | algo = P54_CRYPTO_TKIPMICHAEL; | ||
1961 | break; | ||
1962 | case ALG_WEP: | ||
1963 | if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_WEP)) | ||
1964 | return -EOPNOTSUPP; | ||
1965 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; | ||
1966 | algo = P54_CRYPTO_WEP; | ||
1967 | break; | ||
1968 | case ALG_CCMP: | ||
1969 | if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP)) | ||
1970 | return -EOPNOTSUPP; | ||
1971 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; | ||
1972 | algo = P54_CRYPTO_AESCCMP; | ||
1973 | break; | ||
1974 | default: | ||
1975 | return -EINVAL; | ||
1976 | } | ||
1977 | } | ||
1978 | |||
1979 | if (key->keyidx > priv->rx_keycache_size) { | ||
1980 | /* | ||
1981 | * The device supports the choosen algorithm, but the firmware | ||
1982 | * does not provide enough key slots to store all of them. | ||
1983 | * So, incoming frames have to be decoded by the mac80211 stack, | ||
1984 | * but we can still offload encryption for outgoing frames. | ||
1985 | */ | ||
1986 | |||
1987 | return 0; | ||
1988 | } | ||
1989 | |||
1990 | mutex_lock(&priv->conf_mutex); | ||
1991 | skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*rxkey) + | ||
1992 | sizeof(struct p54_hdr), P54_CONTROL_TYPE_RX_KEYCACHE, | ||
1993 | GFP_ATOMIC); | ||
1994 | if (!skb) { | ||
1995 | mutex_unlock(&priv->conf_mutex); | ||
1996 | return -ENOMEM; | ||
1997 | } | ||
1998 | |||
1999 | /* TODO: some devices have 4 more free slots for rx keys */ | ||
2000 | rxkey = (struct p54_keycache *)skb_put(skb, sizeof(*rxkey)); | ||
2001 | rxkey->entry = key->keyidx; | ||
2002 | rxkey->key_id = key->keyidx; | ||
2003 | rxkey->key_type = algo; | ||
2004 | if (address) | ||
2005 | memcpy(rxkey->mac, address, ETH_ALEN); | ||
2006 | else | ||
2007 | memset(rxkey->mac, ~0, ETH_ALEN); | ||
2008 | if (key->alg != ALG_TKIP) { | ||
2009 | rxkey->key_len = min((u8)16, key->keylen); | ||
2010 | memcpy(rxkey->key, key->key, rxkey->key_len); | ||
2011 | } else { | ||
2012 | rxkey->key_len = 24; | ||
2013 | memcpy(rxkey->key, key->key, 16); | ||
2014 | memcpy(&(rxkey->key[16]), &(key->key | ||
2015 | [NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY]), 8); | ||
2016 | } | ||
2017 | |||
2018 | priv->tx(dev, skb, 1); | ||
2019 | mutex_unlock(&priv->conf_mutex); | ||
2020 | return 0; | ||
2021 | } | ||
2022 | |||
1830 | static const struct ieee80211_ops p54_ops = { | 2023 | static const struct ieee80211_ops p54_ops = { |
1831 | .tx = p54_tx, | 2024 | .tx = p54_tx, |
1832 | .start = p54_start, | 2025 | .start = p54_start, |
@@ -1834,6 +2027,9 @@ static const struct ieee80211_ops p54_ops = { | |||
1834 | .add_interface = p54_add_interface, | 2027 | .add_interface = p54_add_interface, |
1835 | .remove_interface = p54_remove_interface, | 2028 | .remove_interface = p54_remove_interface, |
1836 | .set_tim = p54_set_tim, | 2029 | .set_tim = p54_set_tim, |
2030 | .sta_notify_ps = p54_sta_notify_ps, | ||
2031 | .sta_notify = p54_sta_notify, | ||
2032 | .set_key = p54_set_key, | ||
1837 | .config = p54_config, | 2033 | .config = p54_config, |
1838 | .config_interface = p54_config_interface, | 2034 | .config_interface = p54_config_interface, |
1839 | .bss_info_changed = p54_bss_info_changed, | 2035 | .bss_info_changed = p54_bss_info_changed, |
diff --git a/drivers/net/wireless/p54/p54common.h b/drivers/net/wireless/p54/p54common.h index 3419f16be938..5a68fdae7730 100644 --- a/drivers/net/wireless/p54/p54common.h +++ b/drivers/net/wireless/p54/p54common.h | |||
@@ -246,9 +246,21 @@ struct memrecord { | |||
246 | }; | 246 | }; |
247 | 247 | ||
248 | struct p54_eeprom_lm86 { | 248 | struct p54_eeprom_lm86 { |
249 | __le16 offset; | 249 | union { |
250 | __le16 len; | 250 | struct { |
251 | u8 data[0]; | 251 | __le16 offset; |
252 | __le16 len; | ||
253 | u8 data[0]; | ||
254 | } v1; | ||
255 | struct { | ||
256 | __le32 offset; | ||
257 | __le16 len; | ||
258 | u8 magic2; | ||
259 | u8 pad; | ||
260 | u8 magic[4]; | ||
261 | u8 data[0]; | ||
262 | } v2; | ||
263 | } __attribute__ ((packed)); | ||
252 | } __attribute__ ((packed)); | 264 | } __attribute__ ((packed)); |
253 | 265 | ||
254 | enum p54_rx_decrypt_status { | 266 | enum p54_rx_decrypt_status { |
@@ -302,7 +314,7 @@ enum p54_frame_sent_status { | |||
302 | P54_TX_OK = 0, | 314 | P54_TX_OK = 0, |
303 | P54_TX_FAILED, | 315 | P54_TX_FAILED, |
304 | P54_TX_PSM, | 316 | P54_TX_PSM, |
305 | P54_TX_PSM_CANCELLED | 317 | P54_TX_PSM_CANCELLED = 4 |
306 | }; | 318 | }; |
307 | 319 | ||
308 | struct p54_frame_sent { | 320 | struct p54_frame_sent { |
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 21ba526a45bf..2dd3cd41d0fe 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c | |||
@@ -244,13 +244,13 @@ static void p54u_tx_3887(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
244 | usb_submit_urb(data_urb, GFP_ATOMIC); | 244 | usb_submit_urb(data_urb, GFP_ATOMIC); |
245 | } | 245 | } |
246 | 246 | ||
247 | static __le32 p54u_lm87_chksum(const u32 *data, size_t length) | 247 | static __le32 p54u_lm87_chksum(const __le32 *data, size_t length) |
248 | { | 248 | { |
249 | u32 chk = 0; | 249 | u32 chk = 0; |
250 | 250 | ||
251 | length >>= 2; | 251 | length >>= 2; |
252 | while (length--) { | 252 | while (length--) { |
253 | chk ^= *data++; | 253 | chk ^= le32_to_cpu(*data++); |
254 | chk = (chk >> 5) ^ (chk << 3); | 254 | chk = (chk >> 5) ^ (chk << 3); |
255 | } | 255 | } |
256 | 256 | ||
@@ -270,7 +270,7 @@ static void p54u_tx_lm87(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
270 | if (!data_urb) | 270 | if (!data_urb) |
271 | return; | 271 | return; |
272 | 272 | ||
273 | checksum = p54u_lm87_chksum((u32 *)skb->data, skb->len); | 273 | checksum = p54u_lm87_chksum((__le32 *)skb->data, skb->len); |
274 | hdr = (struct lm87_tx_hdr *)skb_push(skb, sizeof(*hdr)); | 274 | hdr = (struct lm87_tx_hdr *)skb_push(skb, sizeof(*hdr)); |
275 | hdr->chksum = checksum; | 275 | hdr->chksum = checksum; |
276 | hdr->device_addr = addr; | 276 | hdr->device_addr = addr; |
@@ -405,7 +405,8 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev) | |||
405 | 405 | ||
406 | tmp = buf = kmalloc(P54U_FW_BLOCK, GFP_KERNEL); | 406 | tmp = buf = kmalloc(P54U_FW_BLOCK, GFP_KERNEL); |
407 | if (!buf) { | 407 | if (!buf) { |
408 | printk(KERN_ERR "p54usb: cannot allocate firmware upload buffer!\n"); | 408 | dev_err(&priv->udev->dev, "(p54usb) cannot allocate firmware" |
409 | "upload buffer!\n"); | ||
409 | err = -ENOMEM; | 410 | err = -ENOMEM; |
410 | goto err_bufalloc; | 411 | goto err_bufalloc; |
411 | } | 412 | } |
@@ -413,13 +414,14 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev) | |||
413 | memcpy(buf, start_string, 4); | 414 | memcpy(buf, start_string, 4); |
414 | err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 4); | 415 | err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 4); |
415 | if (err) { | 416 | if (err) { |
416 | printk(KERN_ERR "p54usb: reset failed! (%d)\n", err); | 417 | dev_err(&priv->udev->dev, "(p54usb) reset failed! (%d)\n", err); |
417 | goto err_reset; | 418 | goto err_reset; |
418 | } | 419 | } |
419 | 420 | ||
420 | err = request_firmware(&fw_entry, "isl3887usb", &priv->udev->dev); | 421 | err = request_firmware(&fw_entry, "isl3887usb", &priv->udev->dev); |
421 | if (err) { | 422 | if (err) { |
422 | printk(KERN_ERR "p54usb: cannot find firmware (isl3887usb)\n"); | 423 | dev_err(&priv->udev->dev, "p54usb: cannot find firmware " |
424 | "(isl3887usb)\n"); | ||
423 | err = request_firmware(&fw_entry, "isl3887usb_bare", | 425 | err = request_firmware(&fw_entry, "isl3887usb_bare", |
424 | &priv->udev->dev); | 426 | &priv->udev->dev); |
425 | if (err) | 427 | if (err) |
@@ -474,7 +476,8 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev) | |||
474 | 476 | ||
475 | err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, block_size); | 477 | err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, block_size); |
476 | if (err) { | 478 | if (err) { |
477 | printk(KERN_ERR "p54usb: firmware upload failed!\n"); | 479 | dev_err(&priv->udev->dev, "(p54usb) firmware " |
480 | "upload failed!\n"); | ||
478 | goto err_upload_failed; | 481 | goto err_upload_failed; |
479 | } | 482 | } |
480 | 483 | ||
@@ -485,10 +488,9 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev) | |||
485 | *((__le32 *)buf) = cpu_to_le32(~crc32_le(~0, fw_entry->data, fw_entry->size)); | 488 | *((__le32 *)buf) = cpu_to_le32(~crc32_le(~0, fw_entry->data, fw_entry->size)); |
486 | err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, sizeof(u32)); | 489 | err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, sizeof(u32)); |
487 | if (err) { | 490 | if (err) { |
488 | printk(KERN_ERR "p54usb: firmware upload failed!\n"); | 491 | dev_err(&priv->udev->dev, "(p54usb) firmware upload failed!\n"); |
489 | goto err_upload_failed; | 492 | goto err_upload_failed; |
490 | } | 493 | } |
491 | |||
492 | timeout = jiffies + msecs_to_jiffies(1000); | 494 | timeout = jiffies + msecs_to_jiffies(1000); |
493 | while (!(err = usb_bulk_msg(priv->udev, | 495 | while (!(err = usb_bulk_msg(priv->udev, |
494 | usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), buf, 128, &alen, 1000))) { | 496 | usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), buf, 128, &alen, 1000))) { |
@@ -496,25 +498,27 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev) | |||
496 | break; | 498 | break; |
497 | 499 | ||
498 | if (alen > 5 && !memcmp(buf, "ERROR", 5)) { | 500 | if (alen > 5 && !memcmp(buf, "ERROR", 5)) { |
499 | printk(KERN_INFO "p54usb: firmware upload failed!\n"); | ||
500 | err = -EINVAL; | 501 | err = -EINVAL; |
501 | break; | 502 | break; |
502 | } | 503 | } |
503 | 504 | ||
504 | if (time_after(jiffies, timeout)) { | 505 | if (time_after(jiffies, timeout)) { |
505 | printk(KERN_ERR "p54usb: firmware boot timed out!\n"); | 506 | dev_err(&priv->udev->dev, "(p54usb) firmware boot " |
507 | "timed out!\n"); | ||
506 | err = -ETIMEDOUT; | 508 | err = -ETIMEDOUT; |
507 | break; | 509 | break; |
508 | } | 510 | } |
509 | } | 511 | } |
510 | if (err) | 512 | if (err) { |
513 | dev_err(&priv->udev->dev, "(p54usb) firmware upload failed!\n"); | ||
511 | goto err_upload_failed; | 514 | goto err_upload_failed; |
515 | } | ||
512 | 516 | ||
513 | buf[0] = 'g'; | 517 | buf[0] = 'g'; |
514 | buf[1] = '\r'; | 518 | buf[1] = '\r'; |
515 | err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 2); | 519 | err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 2); |
516 | if (err) { | 520 | if (err) { |
517 | printk(KERN_ERR "p54usb: firmware boot failed!\n"); | 521 | dev_err(&priv->udev->dev, "(p54usb) firmware boot failed!\n"); |
518 | goto err_upload_failed; | 522 | goto err_upload_failed; |
519 | } | 523 | } |
520 | 524 | ||
@@ -554,13 +558,15 @@ static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev) | |||
554 | 558 | ||
555 | buf = kmalloc(512, GFP_KERNEL); | 559 | buf = kmalloc(512, GFP_KERNEL); |
556 | if (!buf) { | 560 | if (!buf) { |
557 | printk(KERN_ERR "p54usb: firmware buffer alloc failed!\n"); | 561 | dev_err(&priv->udev->dev, "(p54usb) firmware buffer " |
562 | "alloc failed!\n"); | ||
558 | return -ENOMEM; | 563 | return -ENOMEM; |
559 | } | 564 | } |
560 | 565 | ||
561 | err = request_firmware(&fw_entry, "isl3886usb", &priv->udev->dev); | 566 | err = request_firmware(&fw_entry, "isl3886usb", &priv->udev->dev); |
562 | if (err) { | 567 | if (err) { |
563 | printk(KERN_ERR "p54usb: cannot find firmware (isl3886usb)\n"); | 568 | dev_err(&priv->udev->dev, "(p54usb) cannot find firmware " |
569 | "(isl3886usb)\n"); | ||
564 | err = request_firmware(&fw_entry, "isl3890usb", | 570 | err = request_firmware(&fw_entry, "isl3890usb", |
565 | &priv->udev->dev); | 571 | &priv->udev->dev); |
566 | if (err) { | 572 | if (err) { |
@@ -685,8 +691,8 @@ static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev) | |||
685 | 691 | ||
686 | err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, block_len); | 692 | err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, block_len); |
687 | if (err) { | 693 | if (err) { |
688 | printk(KERN_ERR "p54usb: firmware block upload " | 694 | dev_err(&priv->udev->dev, "(p54usb) firmware block " |
689 | "failed\n"); | 695 | "upload failed\n"); |
690 | goto fail; | 696 | goto fail; |
691 | } | 697 | } |
692 | 698 | ||
@@ -719,8 +725,8 @@ static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev) | |||
719 | 0x002C | (unsigned long)&devreg->direct_mem_win); | 725 | 0x002C | (unsigned long)&devreg->direct_mem_win); |
720 | if (!(reg & cpu_to_le32(ISL38XX_DMA_STATUS_DONE)) || | 726 | if (!(reg & cpu_to_le32(ISL38XX_DMA_STATUS_DONE)) || |
721 | !(reg & cpu_to_le32(ISL38XX_DMA_STATUS_READY))) { | 727 | !(reg & cpu_to_le32(ISL38XX_DMA_STATUS_READY))) { |
722 | printk(KERN_ERR "p54usb: firmware DMA transfer " | 728 | dev_err(&priv->udev->dev, "(p54usb) firmware DMA " |
723 | "failed\n"); | 729 | "transfer failed\n"); |
724 | goto fail; | 730 | goto fail; |
725 | } | 731 | } |
726 | 732 | ||
@@ -825,8 +831,9 @@ static int __devinit p54u_probe(struct usb_interface *intf, | |||
825 | unsigned int i, recognized_pipes; | 831 | unsigned int i, recognized_pipes; |
826 | 832 | ||
827 | dev = p54_init_common(sizeof(*priv)); | 833 | dev = p54_init_common(sizeof(*priv)); |
834 | |||
828 | if (!dev) { | 835 | if (!dev) { |
829 | printk(KERN_ERR "p54usb: ieee80211 alloc failed\n"); | 836 | dev_err(&udev->dev, "(p54usb) ieee80211 alloc failed\n"); |
830 | return -ENOMEM; | 837 | return -ENOMEM; |
831 | } | 838 | } |
832 | 839 | ||
@@ -887,7 +894,7 @@ static int __devinit p54u_probe(struct usb_interface *intf, | |||
887 | 894 | ||
888 | err = ieee80211_register_hw(dev); | 895 | err = ieee80211_register_hw(dev); |
889 | if (err) { | 896 | if (err) { |
890 | printk(KERN_ERR "p54usb: Cannot register netdevice\n"); | 897 | dev_err(&udev->dev, "(p54usb) Cannot register netdevice\n"); |
891 | goto err_free_dev; | 898 | goto err_free_dev; |
892 | } | 899 | } |
893 | 900 | ||
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index 95511ac22470..178b313293b4 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig | |||
@@ -57,6 +57,7 @@ config RT2500USB | |||
57 | tristate "Ralink rt2500 (USB) support" | 57 | tristate "Ralink rt2500 (USB) support" |
58 | depends on USB | 58 | depends on USB |
59 | select RT2X00_LIB_USB | 59 | select RT2X00_LIB_USB |
60 | select RT2X00_LIB_CRYPTO | ||
60 | ---help--- | 61 | ---help--- |
61 | This adds support for rt2500 wireless chipset family. | 62 | This adds support for rt2500 wireless chipset family. |
62 | Supported chips: RT2571 & RT2572. | 63 | Supported chips: RT2571 & RT2572. |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 0447e93306ad..30028e2422fc 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -36,6 +36,13 @@ | |||
36 | #include "rt2500usb.h" | 36 | #include "rt2500usb.h" |
37 | 37 | ||
38 | /* | 38 | /* |
39 | * Allow hardware encryption to be disabled. | ||
40 | */ | ||
41 | static int modparam_nohwcrypt = 1; | ||
42 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); | ||
43 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); | ||
44 | |||
45 | /* | ||
39 | * Register access. | 46 | * Register access. |
40 | * All access to the CSR registers will go through the methods | 47 | * All access to the CSR registers will go through the methods |
41 | * rt2500usb_register_read and rt2500usb_register_write. | 48 | * rt2500usb_register_read and rt2500usb_register_write. |
@@ -323,6 +330,82 @@ static void rt2500usb_init_led(struct rt2x00_dev *rt2x00dev, | |||
323 | /* | 330 | /* |
324 | * Configuration handlers. | 331 | * Configuration handlers. |
325 | */ | 332 | */ |
333 | |||
334 | /* | ||
335 | * rt2500usb does not differentiate between shared and pairwise | ||
336 | * keys, so we should use the same function for both key types. | ||
337 | */ | ||
338 | static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev, | ||
339 | struct rt2x00lib_crypto *crypto, | ||
340 | struct ieee80211_key_conf *key) | ||
341 | { | ||
342 | int timeout; | ||
343 | u32 mask; | ||
344 | u16 reg; | ||
345 | |||
346 | if (crypto->cmd == SET_KEY) { | ||
347 | /* | ||
348 | * Pairwise key will always be entry 0, but this | ||
349 | * could collide with a shared key on the same | ||
350 | * position... | ||
351 | */ | ||
352 | mask = TXRX_CSR0_KEY_ID.bit_mask; | ||
353 | |||
354 | rt2500usb_register_read(rt2x00dev, TXRX_CSR0, ®); | ||
355 | reg &= mask; | ||
356 | |||
357 | if (reg && reg == mask) | ||
358 | return -ENOSPC; | ||
359 | |||
360 | reg = rt2x00_get_field16(reg, TXRX_CSR0_KEY_ID); | ||
361 | |||
362 | key->hw_key_idx += reg ? ffz(reg) : 0; | ||
363 | |||
364 | /* | ||
365 | * The encryption key doesn't fit within the CSR cache, | ||
366 | * this means we should allocate it seperately and use | ||
367 | * rt2x00usb_vendor_request() to send the key to the hardware. | ||
368 | */ | ||
369 | reg = KEY_ENTRY(key->hw_key_idx); | ||
370 | timeout = REGISTER_TIMEOUT32(sizeof(crypto->key)); | ||
371 | rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE, | ||
372 | USB_VENDOR_REQUEST_OUT, reg, | ||
373 | crypto->key, | ||
374 | sizeof(crypto->key), | ||
375 | timeout); | ||
376 | |||
377 | /* | ||
378 | * The driver does not support the IV/EIV generation | ||
379 | * in hardware. However it doesn't support the IV/EIV | ||
380 | * inside the ieee80211 frame either, but requires it | ||
381 | * to be provided seperately for the descriptor. | ||
382 | * rt2x00lib will cut the IV/EIV data out of all frames | ||
383 | * given to us by mac80211, but we must tell mac80211 | ||
384 | * to generate the IV/EIV data. | ||
385 | */ | ||
386 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; | ||
387 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; | ||
388 | } | ||
389 | |||
390 | /* | ||
391 | * TXRX_CSR0_KEY_ID contains only single-bit fields to indicate | ||
392 | * a particular key is valid. | ||
393 | */ | ||
394 | rt2500usb_register_read(rt2x00dev, TXRX_CSR0, ®); | ||
395 | rt2x00_set_field16(®, TXRX_CSR0_ALGORITHM, crypto->cipher); | ||
396 | rt2x00_set_field16(®, TXRX_CSR0_IV_OFFSET, IEEE80211_HEADER); | ||
397 | |||
398 | mask = rt2x00_get_field16(reg, TXRX_CSR0_KEY_ID); | ||
399 | if (crypto->cmd == SET_KEY) | ||
400 | mask |= 1 << key->hw_key_idx; | ||
401 | else if (crypto->cmd == DISABLE_KEY) | ||
402 | mask &= ~(1 << key->hw_key_idx); | ||
403 | rt2x00_set_field16(®, TXRX_CSR0_KEY_ID, mask); | ||
404 | rt2500usb_register_write(rt2x00dev, TXRX_CSR0, reg); | ||
405 | |||
406 | return 0; | ||
407 | } | ||
408 | |||
326 | static void rt2500usb_config_filter(struct rt2x00_dev *rt2x00dev, | 409 | static void rt2500usb_config_filter(struct rt2x00_dev *rt2x00dev, |
327 | const unsigned int filter_flags) | 410 | const unsigned int filter_flags) |
328 | { | 411 | { |
@@ -844,7 +927,7 @@ static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev) | |||
844 | 927 | ||
845 | rt2500usb_register_read(rt2x00dev, TXRX_CSR0, ®); | 928 | rt2500usb_register_read(rt2x00dev, TXRX_CSR0, ®); |
846 | rt2x00_set_field16(®, TXRX_CSR0_IV_OFFSET, IEEE80211_HEADER); | 929 | rt2x00_set_field16(®, TXRX_CSR0_IV_OFFSET, IEEE80211_HEADER); |
847 | rt2x00_set_field16(®, TXRX_CSR0_KEY_ID, 0xff); | 930 | rt2x00_set_field16(®, TXRX_CSR0_KEY_ID, 0); |
848 | rt2500usb_register_write(rt2x00dev, TXRX_CSR0, reg); | 931 | rt2500usb_register_write(rt2x00dev, TXRX_CSR0, reg); |
849 | 932 | ||
850 | rt2500usb_register_read(rt2x00dev, MAC_CSR18, ®); | 933 | rt2500usb_register_read(rt2x00dev, MAC_CSR18, ®); |
@@ -1066,7 +1149,7 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1066 | * Start writing the descriptor words. | 1149 | * Start writing the descriptor words. |
1067 | */ | 1150 | */ |
1068 | rt2x00_desc_read(txd, 1, &word); | 1151 | rt2x00_desc_read(txd, 1, &word); |
1069 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); | 1152 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, txdesc->iv_offset); |
1070 | rt2x00_set_field32(&word, TXD_W1_AIFS, txdesc->aifs); | 1153 | rt2x00_set_field32(&word, TXD_W1_AIFS, txdesc->aifs); |
1071 | rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); | 1154 | rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); |
1072 | rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); | 1155 | rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); |
@@ -1079,6 +1162,11 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1079 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, txdesc->length_high); | 1162 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, txdesc->length_high); |
1080 | rt2x00_desc_write(txd, 2, word); | 1163 | rt2x00_desc_write(txd, 2, word); |
1081 | 1164 | ||
1165 | if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags)) { | ||
1166 | _rt2x00_desc_write(txd, 3, skbdesc->iv[0]); | ||
1167 | _rt2x00_desc_write(txd, 4, skbdesc->iv[1]); | ||
1168 | } | ||
1169 | |||
1082 | rt2x00_desc_read(txd, 0, &word); | 1170 | rt2x00_desc_read(txd, 0, &word); |
1083 | rt2x00_set_field32(&word, TXD_W0_RETRY_LIMIT, txdesc->retry_limit); | 1171 | rt2x00_set_field32(&word, TXD_W0_RETRY_LIMIT, txdesc->retry_limit); |
1084 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, | 1172 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, |
@@ -1093,7 +1181,8 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1093 | test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)); | 1181 | test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)); |
1094 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); | 1182 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1095 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skb->len); | 1183 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skb->len); |
1096 | rt2x00_set_field32(&word, TXD_W0_CIPHER, CIPHER_NONE); | 1184 | rt2x00_set_field32(&word, TXD_W0_CIPHER, txdesc->cipher); |
1185 | rt2x00_set_field32(&word, TXD_W0_KEY_ID, txdesc->key_idx); | ||
1097 | rt2x00_desc_write(txd, 0, word); | 1186 | rt2x00_desc_write(txd, 0, word); |
1098 | } | 1187 | } |
1099 | 1188 | ||
@@ -1204,6 +1293,7 @@ static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1204 | static void rt2500usb_fill_rxdone(struct queue_entry *entry, | 1293 | static void rt2500usb_fill_rxdone(struct queue_entry *entry, |
1205 | struct rxdone_entry_desc *rxdesc) | 1294 | struct rxdone_entry_desc *rxdesc) |
1206 | { | 1295 | { |
1296 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
1207 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; | 1297 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; |
1208 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | 1298 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
1209 | __le32 *rxd = | 1299 | __le32 *rxd = |
@@ -1231,6 +1321,33 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry, | |||
1231 | if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) | 1321 | if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) |
1232 | rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC; | 1322 | rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC; |
1233 | 1323 | ||
1324 | if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) { | ||
1325 | rxdesc->cipher = rt2x00_get_field32(word0, RXD_W0_CIPHER); | ||
1326 | if (rt2x00_get_field32(word0, RXD_W0_CIPHER_ERROR)) | ||
1327 | rxdesc->cipher_status = RX_CRYPTO_FAIL_KEY; | ||
1328 | } | ||
1329 | |||
1330 | if (rxdesc->cipher != CIPHER_NONE) { | ||
1331 | _rt2x00_desc_read(rxd, 2, &rxdesc->iv[0]); | ||
1332 | _rt2x00_desc_read(rxd, 3, &rxdesc->iv[1]); | ||
1333 | rxdesc->dev_flags |= RXDONE_CRYPTO_IV; | ||
1334 | |||
1335 | /* ICV is located at the end of frame */ | ||
1336 | |||
1337 | /* | ||
1338 | * Hardware has stripped IV/EIV data from 802.11 frame during | ||
1339 | * decryption. It has provided the data seperately but rt2x00lib | ||
1340 | * should decide if it should be reinserted. | ||
1341 | */ | ||
1342 | rxdesc->flags |= RX_FLAG_IV_STRIPPED; | ||
1343 | if (rxdesc->cipher != CIPHER_TKIP) | ||
1344 | rxdesc->flags |= RX_FLAG_MMIC_STRIPPED; | ||
1345 | if (rxdesc->cipher_status == RX_CRYPTO_SUCCESS) | ||
1346 | rxdesc->flags |= RX_FLAG_DECRYPTED; | ||
1347 | else if (rxdesc->cipher_status == RX_CRYPTO_FAIL_MIC) | ||
1348 | rxdesc->flags |= RX_FLAG_MMIC_ERROR; | ||
1349 | } | ||
1350 | |||
1234 | /* | 1351 | /* |
1235 | * Obtain the status about this packet. | 1352 | * Obtain the status about this packet. |
1236 | * When frame was received with an OFDM bitrate, | 1353 | * When frame was received with an OFDM bitrate, |
@@ -1238,8 +1355,8 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry, | |||
1238 | * a CCK bitrate the signal is the rate in 100kbit/s. | 1355 | * a CCK bitrate the signal is the rate in 100kbit/s. |
1239 | */ | 1356 | */ |
1240 | rxdesc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); | 1357 | rxdesc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); |
1241 | rxdesc->rssi = rt2x00_get_field32(word1, RXD_W1_RSSI) - | 1358 | rxdesc->rssi = |
1242 | entry->queue->rt2x00dev->rssi_offset; | 1359 | rt2x00_get_field32(word1, RXD_W1_RSSI) - rt2x00dev->rssi_offset; |
1243 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | 1360 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); |
1244 | 1361 | ||
1245 | if (rt2x00_get_field32(word0, RXD_W0_OFDM)) | 1362 | if (rt2x00_get_field32(word0, RXD_W0_OFDM)) |
@@ -1727,6 +1844,10 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1727 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); | 1844 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); |
1728 | __set_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags); | 1845 | __set_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags); |
1729 | __set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags); | 1846 | __set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags); |
1847 | if (!modparam_nohwcrypt) { | ||
1848 | __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); | ||
1849 | __set_bit(CONFIG_CRYPTO_COPY_IV, &rt2x00dev->flags); | ||
1850 | } | ||
1730 | __set_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags); | 1851 | __set_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags); |
1731 | 1852 | ||
1732 | /* | 1853 | /* |
@@ -1746,6 +1867,7 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = { | |||
1746 | .config = rt2x00mac_config, | 1867 | .config = rt2x00mac_config, |
1747 | .config_interface = rt2x00mac_config_interface, | 1868 | .config_interface = rt2x00mac_config_interface, |
1748 | .configure_filter = rt2x00mac_configure_filter, | 1869 | .configure_filter = rt2x00mac_configure_filter, |
1870 | .set_key = rt2x00mac_set_key, | ||
1749 | .get_stats = rt2x00mac_get_stats, | 1871 | .get_stats = rt2x00mac_get_stats, |
1750 | .bss_info_changed = rt2x00mac_bss_info_changed, | 1872 | .bss_info_changed = rt2x00mac_bss_info_changed, |
1751 | .conf_tx = rt2x00mac_conf_tx, | 1873 | .conf_tx = rt2x00mac_conf_tx, |
@@ -1767,6 +1889,8 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { | |||
1767 | .get_tx_data_len = rt2500usb_get_tx_data_len, | 1889 | .get_tx_data_len = rt2500usb_get_tx_data_len, |
1768 | .kick_tx_queue = rt2500usb_kick_tx_queue, | 1890 | .kick_tx_queue = rt2500usb_kick_tx_queue, |
1769 | .fill_rxdone = rt2500usb_fill_rxdone, | 1891 | .fill_rxdone = rt2500usb_fill_rxdone, |
1892 | .config_shared_key = rt2500usb_config_key, | ||
1893 | .config_pairwise_key = rt2500usb_config_key, | ||
1770 | .config_filter = rt2500usb_config_filter, | 1894 | .config_filter = rt2500usb_config_filter, |
1771 | .config_intf = rt2500usb_config_intf, | 1895 | .config_intf = rt2500usb_config_intf, |
1772 | .config_erp = rt2500usb_config_erp, | 1896 | .config_erp = rt2500usb_config_erp, |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h index dbb5d689e23d..4347dfdabcd4 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.h +++ b/drivers/net/wireless/rt2x00/rt2500usb.h | |||
@@ -447,6 +447,9 @@ | |||
447 | #define SEC_CSR30 0x04bc | 447 | #define SEC_CSR30 0x04bc |
448 | #define SEC_CSR31 0x04be | 448 | #define SEC_CSR31 0x04be |
449 | 449 | ||
450 | #define KEY_ENTRY(__idx) \ | ||
451 | ( SEC_CSR0 + ((__idx) * 16) ) | ||
452 | |||
450 | /* | 453 | /* |
451 | * PHY control registers. | 454 | * PHY control registers. |
452 | */ | 455 | */ |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 780ba7365810..39ecf3b82ca1 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -44,7 +44,7 @@ | |||
44 | /* | 44 | /* |
45 | * Module information. | 45 | * Module information. |
46 | */ | 46 | */ |
47 | #define DRV_VERSION "2.2.2" | 47 | #define DRV_VERSION "2.2.3" |
48 | #define DRV_PROJECT "http://rt2x00.serialmonkey.com" | 48 | #define DRV_PROJECT "http://rt2x00.serialmonkey.com" |
49 | 49 | ||
50 | /* | 50 | /* |
@@ -653,6 +653,7 @@ enum rt2x00_flags { | |||
653 | CONFIG_EXTERNAL_LNA_BG, | 653 | CONFIG_EXTERNAL_LNA_BG, |
654 | CONFIG_DOUBLE_ANTENNA, | 654 | CONFIG_DOUBLE_ANTENNA, |
655 | CONFIG_DISABLE_LINK_TUNING, | 655 | CONFIG_DISABLE_LINK_TUNING, |
656 | CONFIG_CRYPTO_COPY_IV, | ||
656 | }; | 657 | }; |
657 | 658 | ||
658 | /* | 659 | /* |
@@ -803,6 +804,12 @@ struct rt2x00_dev { | |||
803 | u16 tx_power; | 804 | u16 tx_power; |
804 | 805 | ||
805 | /* | 806 | /* |
807 | * Current retry values. | ||
808 | */ | ||
809 | u8 short_retry; | ||
810 | u8 long_retry; | ||
811 | |||
812 | /* | ||
806 | * Rssi <-> Dbm offset | 813 | * Rssi <-> Dbm offset |
807 | */ | 814 | */ |
808 | u8 rssi_offset; | 815 | u8 rssi_offset; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index 7c62ce125b94..e66fb316cd61 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c | |||
@@ -108,33 +108,34 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, | |||
108 | rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp); | 108 | rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp); |
109 | } | 109 | } |
110 | 110 | ||
111 | static inline | ||
112 | enum antenna rt2x00lib_config_antenna_check(enum antenna current_ant, | ||
113 | enum antenna default_ant) | ||
114 | { | ||
115 | if (current_ant != ANTENNA_SW_DIVERSITY) | ||
116 | return current_ant; | ||
117 | return (default_ant != ANTENNA_SW_DIVERSITY) ? default_ant : ANTENNA_B; | ||
118 | } | ||
119 | |||
111 | void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | 120 | void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, |
112 | struct antenna_setup *ant) | 121 | struct antenna_setup *ant) |
113 | { | 122 | { |
123 | struct antenna_setup *def = &rt2x00dev->default_ant; | ||
124 | struct antenna_setup *active = &rt2x00dev->link.ant.active; | ||
125 | |||
114 | /* | 126 | /* |
115 | * Failsafe: Make sure we are not sending the | 127 | * Failsafe: Make sure we are not sending the |
116 | * ANTENNA_SW_DIVERSITY state to the driver. | 128 | * ANTENNA_SW_DIVERSITY state to the driver. |
117 | * If that happes fallback to hardware default, | 129 | * If that happes fallback to hardware default, |
118 | * or our own default. | 130 | * or our own default. |
131 | * The calls to rt2x00lib_config_antenna_check() | ||
132 | * might have caused that we restore back to the already | ||
133 | * active setting. If that has happened we can quit. | ||
119 | */ | 134 | */ |
120 | if (ant->rx == ANTENNA_SW_DIVERSITY) { | 135 | ant->rx = rt2x00lib_config_antenna_check(ant->rx, def->rx); |
121 | if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY) | 136 | ant->tx = rt2x00lib_config_antenna_check(ant->tx, def->tx); |
122 | ant->rx = ANTENNA_B; | ||
123 | else | ||
124 | ant->rx = rt2x00dev->default_ant.rx; | ||
125 | } | ||
126 | if (ant->tx == ANTENNA_SW_DIVERSITY) { | ||
127 | if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY) | ||
128 | ant->tx = ANTENNA_B; | ||
129 | else | ||
130 | ant->tx = rt2x00dev->default_ant.tx; | ||
131 | } | ||
132 | 137 | ||
133 | /* | 138 | if (ant->rx == active->rx && ant->tx == active->tx) |
134 | * Only reconfigure when something has changed. | ||
135 | */ | ||
136 | if (ant->rx == rt2x00dev->link.ant.active.rx && | ||
137 | ant->tx == rt2x00dev->link.ant.active.tx) | ||
138 | return; | 139 | return; |
139 | 140 | ||
140 | /* | 141 | /* |
@@ -154,7 +155,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
154 | rt2x00lib_reset_link_tuner(rt2x00dev); | 155 | rt2x00lib_reset_link_tuner(rt2x00dev); |
155 | rt2x00_reset_link_ant_rssi(&rt2x00dev->link); | 156 | rt2x00_reset_link_ant_rssi(&rt2x00dev->link); |
156 | 157 | ||
157 | memcpy(&rt2x00dev->link.ant.active, ant, sizeof(*ant)); | 158 | memcpy(active, ant, sizeof(*ant)); |
158 | 159 | ||
159 | if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) | 160 | if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) |
160 | rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK); | 161 | rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK); |
@@ -194,6 +195,8 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, | |||
194 | 195 | ||
195 | rt2x00dev->curr_band = conf->channel->band; | 196 | rt2x00dev->curr_band = conf->channel->band; |
196 | rt2x00dev->tx_power = conf->power_level; | 197 | rt2x00dev->tx_power = conf->power_level; |
198 | rt2x00dev->short_retry = conf->short_frame_max_tx_count; | ||
199 | rt2x00dev->long_retry = conf->long_frame_max_tx_count; | ||
197 | 200 | ||
198 | rt2x00dev->rx_status.band = conf->channel->band; | 201 | rt2x00dev->rx_status.band = conf->channel->band; |
199 | rt2x00dev->rx_status.freq = conf->channel->center_freq; | 202 | rt2x00dev->rx_status.freq = conf->channel->center_freq; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c index 5a858e5106c4..37ad0d2fb64c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00crypto.c +++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c | |||
@@ -46,6 +46,29 @@ enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key) | |||
46 | } | 46 | } |
47 | } | 47 | } |
48 | 48 | ||
49 | void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry, | ||
50 | struct txentry_desc *txdesc) | ||
51 | { | ||
52 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); | ||
53 | struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; | ||
54 | |||
55 | __set_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags); | ||
56 | |||
57 | txdesc->cipher = rt2x00crypto_key_to_cipher(hw_key); | ||
58 | |||
59 | if (hw_key->flags & IEEE80211_KEY_FLAG_PAIRWISE) | ||
60 | __set_bit(ENTRY_TXD_ENCRYPT_PAIRWISE, &txdesc->flags); | ||
61 | |||
62 | txdesc->key_idx = hw_key->hw_key_idx; | ||
63 | txdesc->iv_offset = ieee80211_get_hdrlen_from_skb(entry->skb); | ||
64 | |||
65 | if (!(hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) | ||
66 | __set_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags); | ||
67 | |||
68 | if (!(hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) | ||
69 | __set_bit(ENTRY_TXD_ENCRYPT_MMIC, &txdesc->flags); | ||
70 | } | ||
71 | |||
49 | unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx_info) | 72 | unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx_info) |
50 | { | 73 | { |
51 | struct ieee80211_key_conf *key = tx_info->control.hw_key; | 74 | struct ieee80211_key_conf *key = tx_info->control.hw_key; |
@@ -69,6 +92,18 @@ unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx_info) | |||
69 | return overhead; | 92 | return overhead; |
70 | } | 93 | } |
71 | 94 | ||
95 | void rt2x00crypto_tx_copy_iv(struct sk_buff *skb, unsigned int iv_len) | ||
96 | { | ||
97 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | ||
98 | unsigned int header_length = ieee80211_get_hdrlen_from_skb(skb); | ||
99 | |||
100 | if (unlikely(!iv_len)) | ||
101 | return; | ||
102 | |||
103 | /* Copy IV/EIV data */ | ||
104 | memcpy(skbdesc->iv, skb->data + header_length, iv_len); | ||
105 | } | ||
106 | |||
72 | void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, unsigned int iv_len) | 107 | void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, unsigned int iv_len) |
73 | { | 108 | { |
74 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 109 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
@@ -78,10 +113,7 @@ void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, unsigned int iv_len) | |||
78 | return; | 113 | return; |
79 | 114 | ||
80 | /* Copy IV/EIV data */ | 115 | /* Copy IV/EIV data */ |
81 | if (iv_len >= 4) | 116 | memcpy(skbdesc->iv, skb->data + header_length, iv_len); |
82 | memcpy(&skbdesc->iv, skb->data + header_length, 4); | ||
83 | if (iv_len >= 8) | ||
84 | memcpy(&skbdesc->eiv, skb->data + header_length + 4, 4); | ||
85 | 117 | ||
86 | /* Move ieee80211 header */ | 118 | /* Move ieee80211 header */ |
87 | memmove(skb->data + iv_len, skb->data, header_length); | 119 | memmove(skb->data + iv_len, skb->data, header_length); |
@@ -98,7 +130,7 @@ void rt2x00crypto_tx_insert_iv(struct sk_buff *skb) | |||
98 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 130 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
99 | unsigned int header_length = ieee80211_get_hdrlen_from_skb(skb); | 131 | unsigned int header_length = ieee80211_get_hdrlen_from_skb(skb); |
100 | const unsigned int iv_len = | 132 | const unsigned int iv_len = |
101 | ((!!(skbdesc->iv)) * 4) + ((!!(skbdesc->eiv)) * 4); | 133 | ((!!(skbdesc->iv[0])) * 4) + ((!!(skbdesc->iv[1])) * 4); |
102 | 134 | ||
103 | if (!(skbdesc->flags & FRAME_DESC_IV_STRIPPED)) | 135 | if (!(skbdesc->flags & FRAME_DESC_IV_STRIPPED)) |
104 | return; | 136 | return; |
@@ -109,10 +141,7 @@ void rt2x00crypto_tx_insert_iv(struct sk_buff *skb) | |||
109 | memmove(skb->data, skb->data + iv_len, header_length); | 141 | memmove(skb->data, skb->data + iv_len, header_length); |
110 | 142 | ||
111 | /* Copy IV/EIV data */ | 143 | /* Copy IV/EIV data */ |
112 | if (iv_len >= 4) | 144 | memcpy(skb->data + header_length, skbdesc->iv, iv_len); |
113 | memcpy(skb->data + header_length, &skbdesc->iv, 4); | ||
114 | if (iv_len >= 8) | ||
115 | memcpy(skb->data + header_length + 4, &skbdesc->eiv, 4); | ||
116 | 145 | ||
117 | /* IV/EIV data has returned into the frame */ | 146 | /* IV/EIV data has returned into the frame */ |
118 | skbdesc->flags &= ~FRAME_DESC_IV_STRIPPED; | 147 | skbdesc->flags &= ~FRAME_DESC_IV_STRIPPED; |
@@ -172,17 +201,9 @@ void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, unsigned int align, | |||
172 | header_length); | 201 | header_length); |
173 | transfer += header_length; | 202 | transfer += header_length; |
174 | 203 | ||
175 | /* Copy IV data */ | 204 | /* Copy IV/EIV data */ |
176 | if (iv_len >= 4) { | 205 | memcpy(skb->data + transfer, rxdesc->iv, iv_len); |
177 | memcpy(skb->data + transfer, &rxdesc->iv, 4); | 206 | transfer += iv_len; |
178 | transfer += 4; | ||
179 | } | ||
180 | |||
181 | /* Copy EIV data */ | ||
182 | if (iv_len >= 8) { | ||
183 | memcpy(skb->data + transfer, &rxdesc->eiv, 4); | ||
184 | transfer += 4; | ||
185 | } | ||
186 | 207 | ||
187 | /* Move payload */ | 208 | /* Move payload */ |
188 | if (align) { | 209 | if (align) { |
@@ -198,16 +219,14 @@ void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, unsigned int align, | |||
198 | */ | 219 | */ |
199 | transfer += payload_len; | 220 | transfer += payload_len; |
200 | 221 | ||
201 | /* Copy ICV data */ | 222 | /* |
202 | if (icv_len >= 4) { | 223 | * Copy ICV data |
203 | memcpy(skb->data + transfer, &rxdesc->icv, 4); | 224 | * AES appends 8 bytes, we can't fill the upper |
204 | /* | 225 | * 4 bytes, but mac80211 doesn't care about what |
205 | * AES appends 8 bytes, we can't fill the upper | 226 | * we provide here anyway and strips it immediately. |
206 | * 4 bytes, but mac80211 doesn't care about what | 227 | */ |
207 | * we provide here anyway and strips it immediately. | 228 | memcpy(skb->data + transfer, &rxdesc->icv, 4); |
208 | */ | 229 | transfer += icv_len; |
209 | transfer += icv_len; | ||
210 | } | ||
211 | 230 | ||
212 | /* IV/EIV/ICV has been inserted into frame */ | 231 | /* IV/EIV/ICV has been inserted into frame */ |
213 | rxdesc->size = transfer; | 232 | rxdesc->size = transfer; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 7fc1d766062b..6d92542fcf0d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -636,7 +636,8 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, | |||
636 | * provided seperately (through hardware descriptor) | 636 | * provided seperately (through hardware descriptor) |
637 | * in which case we should reinsert the data into the frame. | 637 | * in which case we should reinsert the data into the frame. |
638 | */ | 638 | */ |
639 | if ((rxdesc.flags & RX_FLAG_IV_STRIPPED)) { | 639 | if ((rxdesc.dev_flags & RXDONE_CRYPTO_IV) && |
640 | (rxdesc.flags & RX_FLAG_IV_STRIPPED)) { | ||
640 | rt2x00crypto_rx_insert_iv(entry->skb, align, | 641 | rt2x00crypto_rx_insert_iv(entry->skb, align, |
641 | header_length, &rxdesc); | 642 | header_length, &rxdesc); |
642 | } else if (align) { | 643 | } else if (align) { |
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index 93997333d46d..03024327767b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h | |||
@@ -218,7 +218,10 @@ static inline void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev, | |||
218 | */ | 218 | */ |
219 | #ifdef CONFIG_RT2X00_LIB_CRYPTO | 219 | #ifdef CONFIG_RT2X00_LIB_CRYPTO |
220 | enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key); | 220 | enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key); |
221 | void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry, | ||
222 | struct txentry_desc *txdesc); | ||
221 | unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx_info); | 223 | unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx_info); |
224 | void rt2x00crypto_tx_copy_iv(struct sk_buff *skb, unsigned int iv_len); | ||
222 | void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, unsigned int iv_len); | 225 | void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, unsigned int iv_len); |
223 | void rt2x00crypto_tx_insert_iv(struct sk_buff *skb); | 226 | void rt2x00crypto_tx_insert_iv(struct sk_buff *skb); |
224 | void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, unsigned int align, | 227 | void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, unsigned int align, |
@@ -230,11 +233,21 @@ static inline enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf * | |||
230 | return CIPHER_NONE; | 233 | return CIPHER_NONE; |
231 | } | 234 | } |
232 | 235 | ||
236 | static inline void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry, | ||
237 | struct txentry_desc *txdesc) | ||
238 | { | ||
239 | } | ||
240 | |||
233 | static inline unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx_info) | 241 | static inline unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx_info) |
234 | { | 242 | { |
235 | return 0; | 243 | return 0; |
236 | } | 244 | } |
237 | 245 | ||
246 | static inline void rt2x00crypto_tx_copy_iv(struct sk_buff *skb, | ||
247 | unsigned int iv_len) | ||
248 | { | ||
249 | } | ||
250 | |||
238 | static inline void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, | 251 | static inline void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, |
239 | unsigned int iv_len) | 252 | unsigned int iv_len) |
240 | { | 253 | { |
@@ -250,7 +263,7 @@ static inline void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, | |||
250 | struct rxdone_entry_desc *rxdesc) | 263 | struct rxdone_entry_desc *rxdesc) |
251 | { | 264 | { |
252 | } | 265 | } |
253 | #endif | 266 | #endif /* CONFIG_RT2X00_LIB_CRYPTO */ |
254 | 267 | ||
255 | /* | 268 | /* |
256 | * RFkill handlers. | 269 | * RFkill handlers. |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 4c0395729066..38edee5fe168 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -79,10 +79,8 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, | |||
79 | * RTS/CTS frame should use the length of the frame plus any | 79 | * RTS/CTS frame should use the length of the frame plus any |
80 | * encryption overhead that will be added by the hardware. | 80 | * encryption overhead that will be added by the hardware. |
81 | */ | 81 | */ |
82 | #ifdef CONFIG_RT2X00_LIB_CRYPTO | ||
83 | if (!frag_skb->do_not_encrypt) | 82 | if (!frag_skb->do_not_encrypt) |
84 | data_length += rt2x00crypto_tx_overhead(tx_info); | 83 | data_length += rt2x00crypto_tx_overhead(tx_info); |
85 | #endif /* CONFIG_RT2X00_LIB_CRYPTO */ | ||
86 | 84 | ||
87 | if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) | 85 | if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) |
88 | ieee80211_ctstoself_get(rt2x00dev->hw, tx_info->control.vif, | 86 | ieee80211_ctstoself_get(rt2x00dev->hw, tx_info->control.vif, |
@@ -489,6 +487,7 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
489 | struct ieee80211_key_conf *key) | 487 | struct ieee80211_key_conf *key) |
490 | { | 488 | { |
491 | struct rt2x00_dev *rt2x00dev = hw->priv; | 489 | struct rt2x00_dev *rt2x00dev = hw->priv; |
490 | struct ieee80211_sta *sta; | ||
492 | int (*set_key) (struct rt2x00_dev *rt2x00dev, | 491 | int (*set_key) (struct rt2x00_dev *rt2x00dev, |
493 | struct rt2x00lib_crypto *crypto, | 492 | struct rt2x00lib_crypto *crypto, |
494 | struct ieee80211_key_conf *key); | 493 | struct ieee80211_key_conf *key); |
@@ -539,6 +538,17 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
539 | memcpy(&crypto.key, &key->key[0], key->keylen); | 538 | memcpy(&crypto.key, &key->key[0], key->keylen); |
540 | 539 | ||
541 | /* | 540 | /* |
541 | * Discover the Association ID from mac80211. | ||
542 | * Some drivers need this information when updating the | ||
543 | * hardware key (either adding or removing). | ||
544 | */ | ||
545 | rcu_read_lock(); | ||
546 | sta = ieee80211_find_sta(hw, address); | ||
547 | if (sta) | ||
548 | crypto.aid = sta->aid; | ||
549 | rcu_read_unlock(); | ||
550 | |||
551 | /* | ||
542 | * Each BSS has a maximum of 4 shared keys. | 552 | * Each BSS has a maximum of 4 shared keys. |
543 | * Shared key index values: | 553 | * Shared key index values: |
544 | * 0) BSS0 key0 | 554 | * 0) BSS0 key0 |
@@ -636,7 +646,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, | |||
636 | * When the erp information has changed, we should perform | 646 | * When the erp information has changed, we should perform |
637 | * additional configuration steps. For all other changes we are done. | 647 | * additional configuration steps. For all other changes we are done. |
638 | */ | 648 | */ |
639 | if (changes & (BSS_CHANGED_ERP_PREAMBLE | BSS_CHANGED_ERP_CTS_PROT)) { | 649 | if (changes & ~(BSS_CHANGED_ASSOC | BSS_CHANGED_HT)) { |
640 | if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags)) | 650 | if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags)) |
641 | rt2x00lib_config_erp(rt2x00dev, intf, bss_conf); | 651 | rt2x00lib_config_erp(rt2x00dev, intf, bss_conf); |
642 | else | 652 | else |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index b8de9d2750e4..eaec6bd93ed5 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -55,14 +55,12 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev, | |||
55 | /* | 55 | /* |
56 | * For IV/EIV/ICV assembly we must make sure there is | 56 | * For IV/EIV/ICV assembly we must make sure there is |
57 | * at least 8 bytes bytes available in headroom for IV/EIV | 57 | * at least 8 bytes bytes available in headroom for IV/EIV |
58 | * and 4 bytes for ICV data as tailroon. | 58 | * and 8 bytes for ICV data as tailroon. |
59 | */ | 59 | */ |
60 | #ifdef CONFIG_RT2X00_LIB_CRYPTO | ||
61 | if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) { | 60 | if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) { |
62 | head_size += 8; | 61 | head_size += 8; |
63 | tail_size += 4; | 62 | tail_size += 8; |
64 | } | 63 | } |
65 | #endif /* CONFIG_RT2X00_LIB_CRYPTO */ | ||
66 | 64 | ||
67 | /* | 65 | /* |
68 | * Allocate skbuffer. | 66 | * Allocate skbuffer. |
@@ -174,7 +172,7 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | |||
174 | txdesc->cw_max = entry->queue->cw_max; | 172 | txdesc->cw_max = entry->queue->cw_max; |
175 | txdesc->aifs = entry->queue->aifs; | 173 | txdesc->aifs = entry->queue->aifs; |
176 | 174 | ||
177 | /* Data length + CRC + IV/EIV/ICV/MMIC (when using encryption) */ | 175 | /* Data length + CRC */ |
178 | data_length = entry->skb->len + 4; | 176 | data_length = entry->skb->len + 4; |
179 | 177 | ||
180 | /* | 178 | /* |
@@ -183,34 +181,17 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | |||
183 | if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) | 181 | if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) |
184 | __set_bit(ENTRY_TXD_ACK, &txdesc->flags); | 182 | __set_bit(ENTRY_TXD_ACK, &txdesc->flags); |
185 | 183 | ||
186 | #ifdef CONFIG_RT2X00_LIB_CRYPTO | ||
187 | if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) && | 184 | if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) && |
188 | !entry->skb->do_not_encrypt) { | 185 | !entry->skb->do_not_encrypt) { |
189 | struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; | 186 | /* Apply crypto specific descriptor information */ |
190 | 187 | rt2x00crypto_create_tx_descriptor(entry, txdesc); | |
191 | __set_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags); | ||
192 | |||
193 | txdesc->cipher = rt2x00crypto_key_to_cipher(hw_key); | ||
194 | |||
195 | if (hw_key->flags & IEEE80211_KEY_FLAG_PAIRWISE) | ||
196 | __set_bit(ENTRY_TXD_ENCRYPT_PAIRWISE, &txdesc->flags); | ||
197 | |||
198 | txdesc->key_idx = hw_key->hw_key_idx; | ||
199 | txdesc->iv_offset = ieee80211_get_hdrlen_from_skb(entry->skb); | ||
200 | 188 | ||
201 | /* | 189 | /* |
202 | * Extend frame length to include all encryption overhead | 190 | * Extend frame length to include all encryption overhead |
203 | * that will be added by the hardware. | 191 | * that will be added by the hardware. |
204 | */ | 192 | */ |
205 | data_length += rt2x00crypto_tx_overhead(tx_info); | 193 | data_length += rt2x00crypto_tx_overhead(tx_info); |
206 | |||
207 | if (!(hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) | ||
208 | __set_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags); | ||
209 | |||
210 | if (!(hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) | ||
211 | __set_bit(ENTRY_TXD_ENCRYPT_MMIC, &txdesc->flags); | ||
212 | } | 194 | } |
213 | #endif /* CONFIG_RT2X00_LIB_CRYPTO */ | ||
214 | 195 | ||
215 | /* | 196 | /* |
216 | * Check if this is a RTS/CTS frame | 197 | * Check if this is a RTS/CTS frame |
@@ -231,14 +212,7 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | |||
231 | * Determine retry information. | 212 | * Determine retry information. |
232 | */ | 213 | */ |
233 | txdesc->retry_limit = tx_info->control.rates[0].count - 1; | 214 | txdesc->retry_limit = tx_info->control.rates[0].count - 1; |
234 | /* | 215 | if (txdesc->retry_limit >= rt2x00dev->long_retry) |
235 | * XXX: If at this point we knew whether the HW is going to use | ||
236 | * the RETRY_MODE bit or the retry_limit (currently all | ||
237 | * use the RETRY_MODE bit) we could do something like b43 | ||
238 | * does, set the RETRY_MODE bit when the RC algorithm is | ||
239 | * requesting more than the long retry limit. | ||
240 | */ | ||
241 | if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) | ||
242 | __set_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags); | 216 | __set_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags); |
243 | 217 | ||
244 | /* | 218 | /* |
@@ -427,8 +401,12 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) | |||
427 | * the frame so we can provide it to the driver seperately. | 401 | * the frame so we can provide it to the driver seperately. |
428 | */ | 402 | */ |
429 | if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) && | 403 | if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) && |
430 | !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) | 404 | !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) { |
431 | rt2x00crypto_tx_remove_iv(skb, iv_len); | 405 | if (test_bit(CONFIG_CRYPTO_COPY_IV, &queue->rt2x00dev->flags)) |
406 | rt2x00crypto_tx_copy_iv(skb, iv_len); | ||
407 | else | ||
408 | rt2x00crypto_tx_remove_iv(skb, iv_len); | ||
409 | } | ||
432 | 410 | ||
433 | /* | 411 | /* |
434 | * It could be possible that the queue was corrupted and this | 412 | * It could be possible that the queue was corrupted and this |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 2e99ab53ec65..282937153408 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h | |||
@@ -109,8 +109,7 @@ enum skb_frame_desc_flags { | |||
109 | * @desc: Pointer to descriptor part of the frame. | 109 | * @desc: Pointer to descriptor part of the frame. |
110 | * Note that this pointer could point to something outside | 110 | * Note that this pointer could point to something outside |
111 | * of the scope of the skb->data pointer. | 111 | * of the scope of the skb->data pointer. |
112 | * @iv: IV data used during encryption/decryption. | 112 | * @iv: IV/EIV data used during encryption/decryption. |
113 | * @eiv: EIV data used during encryption/decryption. | ||
114 | * @skb_dma: (PCI-only) the DMA address associated with the sk buffer. | 113 | * @skb_dma: (PCI-only) the DMA address associated with the sk buffer. |
115 | * @entry: The entry to which this sk buffer belongs. | 114 | * @entry: The entry to which this sk buffer belongs. |
116 | */ | 115 | */ |
@@ -123,8 +122,7 @@ struct skb_frame_desc { | |||
123 | 122 | ||
124 | void *desc; | 123 | void *desc; |
125 | 124 | ||
126 | __le32 iv; | 125 | __le32 iv[2]; |
127 | __le32 eiv; | ||
128 | 126 | ||
129 | dma_addr_t skb_dma; | 127 | dma_addr_t skb_dma; |
130 | 128 | ||
@@ -148,11 +146,15 @@ static inline struct skb_frame_desc* get_skb_frame_desc(struct sk_buff *skb) | |||
148 | * @RXDONE_SIGNAL_PLCP: Signal field contains the plcp value. | 146 | * @RXDONE_SIGNAL_PLCP: Signal field contains the plcp value. |
149 | * @RXDONE_SIGNAL_BITRATE: Signal field contains the bitrate value. | 147 | * @RXDONE_SIGNAL_BITRATE: Signal field contains the bitrate value. |
150 | * @RXDONE_MY_BSS: Does this frame originate from device's BSS. | 148 | * @RXDONE_MY_BSS: Does this frame originate from device's BSS. |
149 | * @RXDONE_CRYPTO_IV: Driver provided IV/EIV data. | ||
150 | * @RXDONE_CRYPTO_ICV: Driver provided ICV data. | ||
151 | */ | 151 | */ |
152 | enum rxdone_entry_desc_flags { | 152 | enum rxdone_entry_desc_flags { |
153 | RXDONE_SIGNAL_PLCP = 1 << 0, | 153 | RXDONE_SIGNAL_PLCP = 1 << 0, |
154 | RXDONE_SIGNAL_BITRATE = 1 << 1, | 154 | RXDONE_SIGNAL_BITRATE = 1 << 1, |
155 | RXDONE_MY_BSS = 1 << 2, | 155 | RXDONE_MY_BSS = 1 << 2, |
156 | RXDONE_CRYPTO_IV = 1 << 3, | ||
157 | RXDONE_CRYPTO_ICV = 1 << 4, | ||
156 | }; | 158 | }; |
157 | 159 | ||
158 | /** | 160 | /** |
@@ -168,8 +170,7 @@ enum rxdone_entry_desc_flags { | |||
168 | * @dev_flags: Ralink receive flags (See &enum rxdone_entry_desc_flags). | 170 | * @dev_flags: Ralink receive flags (See &enum rxdone_entry_desc_flags). |
169 | * @cipher: Cipher type used during decryption. | 171 | * @cipher: Cipher type used during decryption. |
170 | * @cipher_status: Decryption status. | 172 | * @cipher_status: Decryption status. |
171 | * @iv: IV data used during decryption. | 173 | * @iv: IV/EIV data used during decryption. |
172 | * @eiv: EIV data used during decryption. | ||
173 | * @icv: ICV data used during decryption. | 174 | * @icv: ICV data used during decryption. |
174 | */ | 175 | */ |
175 | struct rxdone_entry_desc { | 176 | struct rxdone_entry_desc { |
@@ -182,8 +183,7 @@ struct rxdone_entry_desc { | |||
182 | u8 cipher; | 183 | u8 cipher; |
183 | u8 cipher_status; | 184 | u8 cipher_status; |
184 | 185 | ||
185 | __le32 iv; | 186 | __le32 iv[2]; |
186 | __le32 eiv; | ||
187 | __le32 icv; | 187 | __le32 icv; |
188 | }; | 188 | }; |
189 | 189 | ||
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index d54443c25fe3..987e89009f74 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -1778,8 +1778,8 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1778 | rt2x00_desc_write(txd, 2, word); | 1778 | rt2x00_desc_write(txd, 2, word); |
1779 | 1779 | ||
1780 | if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags)) { | 1780 | if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags)) { |
1781 | _rt2x00_desc_write(txd, 3, skbdesc->iv); | 1781 | _rt2x00_desc_write(txd, 3, skbdesc->iv[0]); |
1782 | _rt2x00_desc_write(txd, 4, skbdesc->eiv); | 1782 | _rt2x00_desc_write(txd, 4, skbdesc->iv[1]); |
1783 | } | 1783 | } |
1784 | 1784 | ||
1785 | rt2x00_desc_read(txd, 5, &word); | 1785 | rt2x00_desc_read(txd, 5, &word); |
@@ -1949,9 +1949,12 @@ static void rt61pci_fill_rxdone(struct queue_entry *entry, | |||
1949 | } | 1949 | } |
1950 | 1950 | ||
1951 | if (rxdesc->cipher != CIPHER_NONE) { | 1951 | if (rxdesc->cipher != CIPHER_NONE) { |
1952 | _rt2x00_desc_read(entry_priv->desc, 2, &rxdesc->iv); | 1952 | _rt2x00_desc_read(entry_priv->desc, 2, &rxdesc->iv[0]); |
1953 | _rt2x00_desc_read(entry_priv->desc, 3, &rxdesc->eiv); | 1953 | _rt2x00_desc_read(entry_priv->desc, 3, &rxdesc->iv[1]); |
1954 | rxdesc->dev_flags |= RXDONE_CRYPTO_IV; | ||
1955 | |||
1954 | _rt2x00_desc_read(entry_priv->desc, 4, &rxdesc->icv); | 1956 | _rt2x00_desc_read(entry_priv->desc, 4, &rxdesc->icv); |
1957 | rxdesc->dev_flags |= RXDONE_CRYPTO_ICV; | ||
1955 | 1958 | ||
1956 | /* | 1959 | /* |
1957 | * Hardware has stripped IV/EIV data from 802.11 frame during | 1960 | * Hardware has stripped IV/EIV data from 802.11 frame during |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 37a782dc8080..d638a8a59370 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -1428,8 +1428,8 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1428 | rt2x00_desc_write(txd, 2, word); | 1428 | rt2x00_desc_write(txd, 2, word); |
1429 | 1429 | ||
1430 | if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags)) { | 1430 | if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags)) { |
1431 | _rt2x00_desc_write(txd, 3, skbdesc->iv); | 1431 | _rt2x00_desc_write(txd, 3, skbdesc->iv[0]); |
1432 | _rt2x00_desc_write(txd, 4, skbdesc->eiv); | 1432 | _rt2x00_desc_write(txd, 4, skbdesc->iv[1]); |
1433 | } | 1433 | } |
1434 | 1434 | ||
1435 | rt2x00_desc_read(txd, 5, &word); | 1435 | rt2x00_desc_read(txd, 5, &word); |
@@ -1618,9 +1618,12 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry, | |||
1618 | } | 1618 | } |
1619 | 1619 | ||
1620 | if (rxdesc->cipher != CIPHER_NONE) { | 1620 | if (rxdesc->cipher != CIPHER_NONE) { |
1621 | _rt2x00_desc_read(rxd, 2, &rxdesc->iv); | 1621 | _rt2x00_desc_read(rxd, 2, &rxdesc->iv[0]); |
1622 | _rt2x00_desc_read(rxd, 3, &rxdesc->eiv); | 1622 | _rt2x00_desc_read(rxd, 3, &rxdesc->iv[1]); |
1623 | rxdesc->dev_flags |= RXDONE_CRYPTO_IV; | ||
1624 | |||
1623 | _rt2x00_desc_read(rxd, 4, &rxdesc->icv); | 1625 | _rt2x00_desc_read(rxd, 4, &rxdesc->icv); |
1626 | rxdesc->dev_flags |= RXDONE_CRYPTO_ICV; | ||
1624 | 1627 | ||
1625 | /* | 1628 | /* |
1626 | * Hardware has stripped IV/EIV data from 802.11 frame during | 1629 | * Hardware has stripped IV/EIV data from 802.11 frame during |
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index 69ea5222f163..dbf52e8bbd7a 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c | |||
@@ -238,7 +238,7 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
238 | hdr->flags = cpu_to_le32(flags); | 238 | hdr->flags = cpu_to_le32(flags); |
239 | hdr->len = 0; | 239 | hdr->len = 0; |
240 | hdr->rts_duration = rts_dur; | 240 | hdr->rts_duration = rts_dur; |
241 | hdr->retry = cpu_to_le32(info->control.rates[0].count << 8); | 241 | hdr->retry = cpu_to_le32((info->control.rates[0].count - 1) << 8); |
242 | buf = hdr; | 242 | buf = hdr; |
243 | 243 | ||
244 | ep = 2; | 244 | ep = 2; |
@@ -256,7 +256,7 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
256 | memset(hdr, 0, sizeof(*hdr)); | 256 | memset(hdr, 0, sizeof(*hdr)); |
257 | hdr->flags = cpu_to_le32(flags); | 257 | hdr->flags = cpu_to_le32(flags); |
258 | hdr->rts_duration = rts_dur; | 258 | hdr->rts_duration = rts_dur; |
259 | hdr->retry = cpu_to_le32(info->control.rates[0].count << 8); | 259 | hdr->retry = cpu_to_le32((info->control.rates[0].count - 1) << 8); |
260 | hdr->tx_duration = | 260 | hdr->tx_duration = |
261 | ieee80211_generic_frame_duration(dev, priv->vif, | 261 | ieee80211_generic_frame_duration(dev, priv->vif, |
262 | skb->len, txrate); | 262 | skb->len, txrate); |
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index e08c8bcfb78d..04d4516f9c71 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h | |||
@@ -3,7 +3,26 @@ | |||
3 | /* | 3 | /* |
4 | * 802.11 netlink interface public header | 4 | * 802.11 netlink interface public header |
5 | * | 5 | * |
6 | * Copyright 2006, 2007 Johannes Berg <johannes@sipsolutions.net> | 6 | * Copyright 2006, 2007, 2008 Johannes Berg <johannes@sipsolutions.net> |
7 | * Copyright 2008 Michael Wu <flamingice@sourmilk.net> | ||
8 | * Copyright 2008 Luis Carlos Cobo <luisca@cozybit.com> | ||
9 | * Copyright 2008 Michael Buesch <mb@bu3sch.de> | ||
10 | * Copyright 2008 Luis R. Rodriguez <lrodriguez@atheros.com> | ||
11 | * Copyright 2008 Jouni Malinen <jouni.malinen@atheros.com> | ||
12 | * Copyright 2008 Colin McCabe <colin@cozybit.com> | ||
13 | * | ||
14 | * Permission to use, copy, modify, and/or distribute this software for any | ||
15 | * purpose with or without fee is hereby granted, provided that the above | ||
16 | * copyright notice and this permission notice appear in all copies. | ||
17 | * | ||
18 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
19 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
20 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
21 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
22 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
23 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
24 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
25 | * | ||
7 | */ | 26 | */ |
8 | 27 | ||
9 | /** | 28 | /** |
@@ -26,8 +45,9 @@ | |||
26 | * @NL80211_CMD_GET_WIPHY: request information about a wiphy or dump request | 45 | * @NL80211_CMD_GET_WIPHY: request information about a wiphy or dump request |
27 | * to get a list of all present wiphys. | 46 | * to get a list of all present wiphys. |
28 | * @NL80211_CMD_SET_WIPHY: set wiphy parameters, needs %NL80211_ATTR_WIPHY or | 47 | * @NL80211_CMD_SET_WIPHY: set wiphy parameters, needs %NL80211_ATTR_WIPHY or |
29 | * %NL80211_ATTR_IFINDEX; can be used to set %NL80211_ATTR_WIPHY_NAME | 48 | * %NL80211_ATTR_IFINDEX; can be used to set %NL80211_ATTR_WIPHY_NAME, |
30 | * and/or %NL80211_ATTR_WIPHY_TXQ_PARAMS. | 49 | * %NL80211_ATTR_WIPHY_TXQ_PARAMS, %NL80211_ATTR_WIPHY_FREQ, and/or |
50 | * %NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET. | ||
31 | * @NL80211_CMD_NEW_WIPHY: Newly created wiphy, response to get request | 51 | * @NL80211_CMD_NEW_WIPHY: Newly created wiphy, response to get request |
32 | * or rename notification. Has attributes %NL80211_ATTR_WIPHY and | 52 | * or rename notification. Has attributes %NL80211_ATTR_WIPHY and |
33 | * %NL80211_ATTR_WIPHY_NAME. | 53 | * %NL80211_ATTR_WIPHY_NAME. |
@@ -180,6 +200,14 @@ enum nl80211_commands { | |||
180 | * /sys/class/ieee80211/<phyname>/index | 200 | * /sys/class/ieee80211/<phyname>/index |
181 | * @NL80211_ATTR_WIPHY_NAME: wiphy name (used for renaming) | 201 | * @NL80211_ATTR_WIPHY_NAME: wiphy name (used for renaming) |
182 | * @NL80211_ATTR_WIPHY_TXQ_PARAMS: a nested array of TX queue parameters | 202 | * @NL80211_ATTR_WIPHY_TXQ_PARAMS: a nested array of TX queue parameters |
203 | * @NL80211_ATTR_WIPHY_FREQ: frequency of the selected channel in MHz | ||
204 | * @NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET: included with NL80211_ATTR_WIPHY_FREQ | ||
205 | * if HT20 or HT40 are allowed (i.e., 802.11n disabled if not included): | ||
206 | * NL80211_SEC_CHAN_NO_HT = HT not allowed (i.e., same as not including | ||
207 | * this attribute) | ||
208 | * NL80211_SEC_CHAN_DISABLED = HT20 only | ||
209 | * NL80211_SEC_CHAN_BELOW = secondary channel is below the primary channel | ||
210 | * NL80211_SEC_CHAN_ABOVE = secondary channel is above the primary channel | ||
183 | * | 211 | * |
184 | * @NL80211_ATTR_IFINDEX: network interface index of the device to operate on | 212 | * @NL80211_ATTR_IFINDEX: network interface index of the device to operate on |
185 | * @NL80211_ATTR_IFNAME: network interface name | 213 | * @NL80211_ATTR_IFNAME: network interface name |
@@ -315,6 +343,8 @@ enum nl80211_attrs { | |||
315 | NL80211_ATTR_BSS_BASIC_RATES, | 343 | NL80211_ATTR_BSS_BASIC_RATES, |
316 | 344 | ||
317 | NL80211_ATTR_WIPHY_TXQ_PARAMS, | 345 | NL80211_ATTR_WIPHY_TXQ_PARAMS, |
346 | NL80211_ATTR_WIPHY_FREQ, | ||
347 | NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET, | ||
318 | 348 | ||
319 | /* add attributes here, update the policy in nl80211.c */ | 349 | /* add attributes here, update the policy in nl80211.c */ |
320 | 350 | ||
@@ -329,6 +359,8 @@ enum nl80211_attrs { | |||
329 | #define NL80211_ATTR_HT_CAPABILITY NL80211_ATTR_HT_CAPABILITY | 359 | #define NL80211_ATTR_HT_CAPABILITY NL80211_ATTR_HT_CAPABILITY |
330 | #define NL80211_ATTR_BSS_BASIC_RATES NL80211_ATTR_BSS_BASIC_RATES | 360 | #define NL80211_ATTR_BSS_BASIC_RATES NL80211_ATTR_BSS_BASIC_RATES |
331 | #define NL80211_ATTR_WIPHY_TXQ_PARAMS NL80211_ATTR_WIPHY_TXQ_PARAMS | 361 | #define NL80211_ATTR_WIPHY_TXQ_PARAMS NL80211_ATTR_WIPHY_TXQ_PARAMS |
362 | #define NL80211_ATTR_WIPHY_FREQ NL80211_ATTR_WIPHY_FREQ | ||
363 | #define NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET | ||
332 | 364 | ||
333 | #define NL80211_MAX_SUPP_RATES 32 | 365 | #define NL80211_MAX_SUPP_RATES 32 |
334 | #define NL80211_MAX_SUPP_REG_RULES 32 | 366 | #define NL80211_MAX_SUPP_REG_RULES 32 |
@@ -742,4 +774,10 @@ enum nl80211_txq_q { | |||
742 | NL80211_TXQ_Q_BK | 774 | NL80211_TXQ_Q_BK |
743 | }; | 775 | }; |
744 | 776 | ||
777 | enum nl80211_sec_chan_offset { | ||
778 | NL80211_SEC_CHAN_NO_HT /* No HT */, | ||
779 | NL80211_SEC_CHAN_DISABLED /* HT20 only */, | ||
780 | NL80211_SEC_CHAN_BELOW /* HT40- */, | ||
781 | NL80211_SEC_CHAN_ABOVE /* HT40+ */ | ||
782 | }; | ||
745 | #endif /* __LINUX_NL80211_H */ | 783 | #endif /* __LINUX_NL80211_H */ |
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 1d57835d73f2..a0c0bf19496c 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -5,6 +5,8 @@ | |||
5 | #include <linux/skbuff.h> | 5 | #include <linux/skbuff.h> |
6 | #include <linux/nl80211.h> | 6 | #include <linux/nl80211.h> |
7 | #include <net/genetlink.h> | 7 | #include <net/genetlink.h> |
8 | /* remove once we remove the wext stuff */ | ||
9 | #include <net/iw_handler.h> | ||
8 | 10 | ||
9 | /* | 11 | /* |
10 | * 802.11 configuration in-kernel interface | 12 | * 802.11 configuration in-kernel interface |
@@ -392,6 +394,9 @@ struct ieee80211_txq_params { | |||
392 | /* from net/wireless.h */ | 394 | /* from net/wireless.h */ |
393 | struct wiphy; | 395 | struct wiphy; |
394 | 396 | ||
397 | /* from net/ieee80211.h */ | ||
398 | struct ieee80211_channel; | ||
399 | |||
395 | /** | 400 | /** |
396 | * struct cfg80211_ops - backend description for wireless configuration | 401 | * struct cfg80211_ops - backend description for wireless configuration |
397 | * | 402 | * |
@@ -450,6 +455,8 @@ struct wiphy; | |||
450 | * @change_bss: Modify parameters for a given BSS. | 455 | * @change_bss: Modify parameters for a given BSS. |
451 | * | 456 | * |
452 | * @set_txq_params: Set TX queue parameters | 457 | * @set_txq_params: Set TX queue parameters |
458 | * | ||
459 | * @set_channel: Set channel | ||
453 | */ | 460 | */ |
454 | struct cfg80211_ops { | 461 | struct cfg80211_ops { |
455 | int (*add_virtual_intf)(struct wiphy *wiphy, char *name, | 462 | int (*add_virtual_intf)(struct wiphy *wiphy, char *name, |
@@ -513,6 +520,19 @@ struct cfg80211_ops { | |||
513 | 520 | ||
514 | int (*set_txq_params)(struct wiphy *wiphy, | 521 | int (*set_txq_params)(struct wiphy *wiphy, |
515 | struct ieee80211_txq_params *params); | 522 | struct ieee80211_txq_params *params); |
523 | |||
524 | int (*set_channel)(struct wiphy *wiphy, | ||
525 | struct ieee80211_channel *chan, | ||
526 | enum nl80211_sec_chan_offset); | ||
516 | }; | 527 | }; |
517 | 528 | ||
529 | /* temporary wext handlers */ | ||
530 | int cfg80211_wext_giwname(struct net_device *dev, | ||
531 | struct iw_request_info *info, | ||
532 | char *name, char *extra); | ||
533 | int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info, | ||
534 | u32 *mode, char *extra); | ||
535 | int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info, | ||
536 | u32 *mode, char *extra); | ||
537 | |||
518 | #endif /* __NET_CFG80211_H */ | 538 | #endif /* __NET_CFG80211_H */ |
diff --git a/include/net/ieee80211_radiotap.h b/include/net/ieee80211_radiotap.h index d364fd594ea4..384698cb773a 100644 --- a/include/net/ieee80211_radiotap.h +++ b/include/net/ieee80211_radiotap.h | |||
@@ -1,7 +1,4 @@ | |||
1 | /* $FreeBSD: src/sys/net80211/ieee80211_radiotap.h,v 1.5 2005/01/22 20:12:05 sam Exp $ */ | 1 | /* |
2 | /* $NetBSD: ieee80211_radiotap.h,v 1.11 2005/06/22 06:16:02 dyoung Exp $ */ | ||
3 | |||
4 | /*- | ||
5 | * Copyright (c) 2003, 2004 David Young. All rights reserved. | 2 | * Copyright (c) 2003, 2004 David Young. All rights reserved. |
6 | * | 3 | * |
7 | * Redistribution and use in source and binary forms, with or without | 4 | * Redistribution and use in source and binary forms, with or without |
@@ -42,8 +39,6 @@ | |||
42 | #include <linux/kernel.h> | 39 | #include <linux/kernel.h> |
43 | #include <asm/unaligned.h> | 40 | #include <asm/unaligned.h> |
44 | 41 | ||
45 | /* Radiotap header version (from official NetBSD feed) */ | ||
46 | #define IEEE80211RADIOTAP_VERSION "1.5" | ||
47 | /* Base version of the radiotap packet header data */ | 42 | /* Base version of the radiotap packet header data */ |
48 | #define PKTHDR_RADIOTAP_VERSION 0 | 43 | #define PKTHDR_RADIOTAP_VERSION 0 |
49 | 44 | ||
@@ -62,12 +57,8 @@ | |||
62 | * readers. | 57 | * readers. |
63 | */ | 58 | */ |
64 | 59 | ||
65 | /* XXX tcpdump/libpcap do not tolerate variable-length headers, | 60 | /* |
66 | * yet, so we pad every radiotap header to 64 bytes. Ugh. | 61 | * The radio capture header precedes the 802.11 header. |
67 | */ | ||
68 | #define IEEE80211_RADIOTAP_HDRLEN 64 | ||
69 | |||
70 | /* The radio capture header precedes the 802.11 header. | ||
71 | * All data in the header is little endian on all platforms. | 62 | * All data in the header is little endian on all platforms. |
72 | */ | 63 | */ |
73 | struct ieee80211_radiotap_header { | 64 | struct ieee80211_radiotap_header { |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 6a1d4ea18186..e84c922a1b16 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -323,6 +323,7 @@ struct ieee80211_tx_rate { | |||
323 | * @flags: transmit info flags, defined above | 323 | * @flags: transmit info flags, defined above |
324 | * @band: the band to transmit on (use for checking for races) | 324 | * @band: the band to transmit on (use for checking for races) |
325 | * @antenna_sel_tx: antenna to use, 0 for automatic diversity | 325 | * @antenna_sel_tx: antenna to use, 0 for automatic diversity |
326 | * @pad: padding, ignore | ||
326 | * @control: union for control data | 327 | * @control: union for control data |
327 | * @status: union for status data | 328 | * @status: union for status data |
328 | * @driver_data: array of driver_data pointers | 329 | * @driver_data: array of driver_data pointers |
@@ -507,6 +508,9 @@ static inline int __deprecated __IEEE80211_CONF_SHORT_SLOT_TIME(void) | |||
507 | 508 | ||
508 | struct ieee80211_ht_conf { | 509 | struct ieee80211_ht_conf { |
509 | bool enabled; | 510 | bool enabled; |
511 | int sec_chan_offset; /* 0 = HT40 disabled; -1 = HT40 enabled, secondary | ||
512 | * channel below primary; 1 = HT40 enabled, | ||
513 | * secondary channel above primary */ | ||
510 | }; | 514 | }; |
511 | 515 | ||
512 | /** | 516 | /** |
@@ -779,6 +783,19 @@ enum sta_notify_cmd { | |||
779 | }; | 783 | }; |
780 | 784 | ||
781 | /** | 785 | /** |
786 | * enum sta_notify_ps_cmd - sta power save notify command | ||
787 | * | ||
788 | * Used with the sta_notify_ps() callback in &struct ieee80211_ops to | ||
789 | * notify the driver if a station made a power state transition. | ||
790 | * | ||
791 | * @STA_NOTIFY_SLEEP: a station is now sleeping | ||
792 | * @STA_NOTIFY_AWAKE: a sleeping station woke up | ||
793 | */ | ||
794 | enum sta_notify_ps_cmd { | ||
795 | STA_NOTIFY_SLEEP, STA_NOTIFY_AWAKE, | ||
796 | }; | ||
797 | |||
798 | /** | ||
782 | * enum ieee80211_tkip_key_type - get tkip key | 799 | * enum ieee80211_tkip_key_type - get tkip key |
783 | * | 800 | * |
784 | * Used by drivers which need to get a tkip key for skb. Some drivers need a | 801 | * Used by drivers which need to get a tkip key for skb. Some drivers need a |
@@ -1248,6 +1265,9 @@ enum ieee80211_ampdu_mlme_action { | |||
1248 | * @sta_notify: Notifies low level driver about addition or removal | 1265 | * @sta_notify: Notifies low level driver about addition or removal |
1249 | * of associated station or AP. | 1266 | * of associated station or AP. |
1250 | * | 1267 | * |
1268 | * @sta_ps_notify: Notifies low level driver about the power state transition | ||
1269 | * of a associated station. Must be atomic. | ||
1270 | * | ||
1251 | * @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max), | 1271 | * @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max), |
1252 | * bursting) for a hardware TX queue. | 1272 | * bursting) for a hardware TX queue. |
1253 | * | 1273 | * |
@@ -1314,6 +1334,8 @@ struct ieee80211_ops { | |||
1314 | int (*set_frag_threshold)(struct ieee80211_hw *hw, u32 value); | 1334 | int (*set_frag_threshold)(struct ieee80211_hw *hw, u32 value); |
1315 | void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 1335 | void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
1316 | enum sta_notify_cmd, struct ieee80211_sta *sta); | 1336 | enum sta_notify_cmd, struct ieee80211_sta *sta); |
1337 | void (*sta_notify_ps)(struct ieee80211_hw *hw, | ||
1338 | enum sta_notify_ps_cmd, struct ieee80211_sta *sta); | ||
1317 | int (*conf_tx)(struct ieee80211_hw *hw, u16 queue, | 1339 | int (*conf_tx)(struct ieee80211_hw *hw, u16 queue, |
1318 | const struct ieee80211_tx_queue_params *params); | 1340 | const struct ieee80211_tx_queue_params *params); |
1319 | int (*get_tx_stats)(struct ieee80211_hw *hw, | 1341 | int (*get_tx_stats)(struct ieee80211_hw *hw, |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 16423f94801b..7a7a6c176dc5 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -1095,6 +1095,18 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy, | |||
1095 | return 0; | 1095 | return 0; |
1096 | } | 1096 | } |
1097 | 1097 | ||
1098 | static int ieee80211_set_channel(struct wiphy *wiphy, | ||
1099 | struct ieee80211_channel *chan, | ||
1100 | enum nl80211_sec_chan_offset sec_chan_offset) | ||
1101 | { | ||
1102 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
1103 | |||
1104 | local->oper_channel = chan; | ||
1105 | local->oper_sec_chan_offset = sec_chan_offset; | ||
1106 | |||
1107 | return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | ||
1108 | } | ||
1109 | |||
1098 | struct cfg80211_ops mac80211_config_ops = { | 1110 | struct cfg80211_ops mac80211_config_ops = { |
1099 | .add_virtual_intf = ieee80211_add_iface, | 1111 | .add_virtual_intf = ieee80211_add_iface, |
1100 | .del_virtual_intf = ieee80211_del_iface, | 1112 | .del_virtual_intf = ieee80211_del_iface, |
@@ -1122,4 +1134,5 @@ struct cfg80211_ops mac80211_config_ops = { | |||
1122 | #endif | 1134 | #endif |
1123 | .change_bss = ieee80211_change_bss, | 1135 | .change_bss = ieee80211_change_bss, |
1124 | .set_txq_params = ieee80211_set_txq_params, | 1136 | .set_txq_params = ieee80211_set_txq_params, |
1137 | .set_channel = ieee80211_set_channel, | ||
1125 | }; | 1138 | }; |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 155a20410017..527205f8c1a1 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -626,6 +626,7 @@ struct ieee80211_local { | |||
626 | struct delayed_work scan_work; | 626 | struct delayed_work scan_work; |
627 | struct ieee80211_sub_if_data *scan_sdata; | 627 | struct ieee80211_sub_if_data *scan_sdata; |
628 | struct ieee80211_channel *oper_channel, *scan_channel; | 628 | struct ieee80211_channel *oper_channel, *scan_channel; |
629 | enum nl80211_sec_chan_offset oper_sec_chan_offset; | ||
629 | u8 scan_ssid[IEEE80211_MAX_SSID_LEN]; | 630 | u8 scan_ssid[IEEE80211_MAX_SSID_LEN]; |
630 | size_t scan_ssid_len; | 631 | size_t scan_ssid_len; |
631 | struct list_head bss_list; | 632 | struct list_head bss_list; |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 46082125f3e1..5abbc3f07dd6 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -435,7 +435,11 @@ static int ieee80211_stop(struct net_device *dev) | |||
435 | break; | 435 | break; |
436 | case NL80211_IFTYPE_STATION: | 436 | case NL80211_IFTYPE_STATION: |
437 | case NL80211_IFTYPE_ADHOC: | 437 | case NL80211_IFTYPE_ADHOC: |
438 | sdata->u.sta.state = IEEE80211_STA_MLME_DISABLED; | 438 | /* Announce that we are leaving the network. */ |
439 | if (sdata->u.sta.state != IEEE80211_STA_MLME_DISABLED) | ||
440 | ieee80211_sta_deauthenticate(sdata, | ||
441 | WLAN_REASON_DEAUTH_LEAVING); | ||
442 | |||
439 | memset(sdata->u.sta.bssid, 0, ETH_ALEN); | 443 | memset(sdata->u.sta.bssid, 0, ETH_ALEN); |
440 | del_timer_sync(&sdata->u.sta.timer); | 444 | del_timer_sync(&sdata->u.sta.timer); |
441 | /* | 445 | /* |
@@ -694,6 +698,10 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, | |||
694 | if (type == sdata->vif.type) | 698 | if (type == sdata->vif.type) |
695 | return 0; | 699 | return 0; |
696 | 700 | ||
701 | /* Setting ad-hoc mode on non-IBSS channel is not supported. */ | ||
702 | if (sdata->local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS) | ||
703 | return -EOPNOTSUPP; | ||
704 | |||
697 | /* | 705 | /* |
698 | * We could, here, on changes between IBSS/STA/MESH modes, | 706 | * We could, here, on changes between IBSS/STA/MESH modes, |
699 | * invoke an MLME function instead that disassociates etc. | 707 | * invoke an MLME function instead that disassociates etc. |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index cec9b6d3e1ce..29c3ecf7e914 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -195,20 +195,42 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | |||
195 | struct ieee80211_channel *chan; | 195 | struct ieee80211_channel *chan; |
196 | int ret = 0; | 196 | int ret = 0; |
197 | int power; | 197 | int power; |
198 | enum nl80211_sec_chan_offset sec_chan_offset; | ||
198 | 199 | ||
199 | might_sleep(); | 200 | might_sleep(); |
200 | 201 | ||
201 | if (local->sw_scanning) | 202 | if (local->sw_scanning) { |
202 | chan = local->scan_channel; | 203 | chan = local->scan_channel; |
203 | else | 204 | sec_chan_offset = NL80211_SEC_CHAN_NO_HT; |
205 | } else { | ||
204 | chan = local->oper_channel; | 206 | chan = local->oper_channel; |
207 | sec_chan_offset = local->oper_sec_chan_offset; | ||
208 | } | ||
205 | 209 | ||
206 | if (chan != local->hw.conf.channel) { | 210 | if (chan != local->hw.conf.channel || |
211 | sec_chan_offset != local->hw.conf.ht.sec_chan_offset) { | ||
207 | local->hw.conf.channel = chan; | 212 | local->hw.conf.channel = chan; |
213 | switch (sec_chan_offset) { | ||
214 | case NL80211_SEC_CHAN_NO_HT: | ||
215 | local->hw.conf.ht.enabled = false; | ||
216 | local->hw.conf.ht.sec_chan_offset = 0; | ||
217 | break; | ||
218 | case NL80211_SEC_CHAN_DISABLED: | ||
219 | local->hw.conf.ht.enabled = true; | ||
220 | local->hw.conf.ht.sec_chan_offset = 0; | ||
221 | break; | ||
222 | case NL80211_SEC_CHAN_BELOW: | ||
223 | local->hw.conf.ht.enabled = true; | ||
224 | local->hw.conf.ht.sec_chan_offset = -1; | ||
225 | break; | ||
226 | case NL80211_SEC_CHAN_ABOVE: | ||
227 | local->hw.conf.ht.enabled = true; | ||
228 | local->hw.conf.ht.sec_chan_offset = 1; | ||
229 | break; | ||
230 | } | ||
208 | changed |= IEEE80211_CONF_CHANGE_CHANNEL; | 231 | changed |= IEEE80211_CONF_CHANGE_CHANNEL; |
209 | } | 232 | } |
210 | 233 | ||
211 | |||
212 | if (!local->hw.conf.power_level) | 234 | if (!local->hw.conf.power_level) |
213 | power = chan->max_power; | 235 | power = chan->max_power; |
214 | else | 236 | else |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 7600ac9b87fe..87b2ac85d911 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -855,16 +855,26 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
855 | if (self_disconnected || reason == WLAN_REASON_DISASSOC_STA_HAS_LEFT) | 855 | if (self_disconnected || reason == WLAN_REASON_DISASSOC_STA_HAS_LEFT) |
856 | ifsta->state = IEEE80211_STA_MLME_DISABLED; | 856 | ifsta->state = IEEE80211_STA_MLME_DISABLED; |
857 | 857 | ||
858 | sta_info_unlink(&sta); | ||
859 | |||
860 | rcu_read_unlock(); | 858 | rcu_read_unlock(); |
861 | 859 | ||
862 | sta_info_destroy(sta); | ||
863 | |||
864 | local->hw.conf.ht.enabled = false; | 860 | local->hw.conf.ht.enabled = false; |
865 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_HT); | 861 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_HT); |
866 | 862 | ||
867 | ieee80211_bss_info_change_notify(sdata, changed); | 863 | ieee80211_bss_info_change_notify(sdata, changed); |
864 | |||
865 | rcu_read_lock(); | ||
866 | |||
867 | sta = sta_info_get(local, ifsta->bssid); | ||
868 | if (!sta) { | ||
869 | rcu_read_unlock(); | ||
870 | return; | ||
871 | } | ||
872 | |||
873 | sta_info_unlink(&sta); | ||
874 | |||
875 | rcu_read_unlock(); | ||
876 | |||
877 | sta_info_destroy(sta); | ||
868 | } | 878 | } |
869 | 879 | ||
870 | static int ieee80211_sta_wep_configured(struct ieee80211_sub_if_data *sdata) | 880 | static int ieee80211_sta_wep_configured(struct ieee80211_sub_if_data *sdata) |
@@ -2002,7 +2012,7 @@ static int ieee80211_sta_match_ssid(struct ieee80211_if_sta *ifsta, | |||
2002 | } | 2012 | } |
2003 | } | 2013 | } |
2004 | 2014 | ||
2005 | if (hidden_ssid && ifsta->ssid_len == ssid_len) | 2015 | if (hidden_ssid && (ifsta->ssid_len == ssid_len || ssid_len == 0)) |
2006 | return 1; | 2016 | return 1; |
2007 | 2017 | ||
2008 | if (ssid_len == 1 && ssid[0] == ' ') | 2018 | if (ssid_len == 1 && ssid[0] == ' ') |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 648a1d0e6c82..14be095b8528 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -654,9 +654,13 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
654 | static void ap_sta_ps_start(struct sta_info *sta) | 654 | static void ap_sta_ps_start(struct sta_info *sta) |
655 | { | 655 | { |
656 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 656 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
657 | struct ieee80211_local *local = sdata->local; | ||
657 | 658 | ||
658 | atomic_inc(&sdata->bss->num_sta_ps); | 659 | atomic_inc(&sdata->bss->num_sta_ps); |
659 | set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL); | 660 | set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL); |
661 | if (local->ops->sta_notify_ps) | ||
662 | local->ops->sta_notify_ps(local_to_hw(local), STA_NOTIFY_SLEEP, | ||
663 | &sta->sta); | ||
660 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 664 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
661 | printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n", | 665 | printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n", |
662 | sdata->dev->name, sta->sta.addr, sta->sta.aid); | 666 | sdata->dev->name, sta->sta.addr, sta->sta.aid); |
@@ -673,6 +677,9 @@ static int ap_sta_ps_end(struct sta_info *sta) | |||
673 | atomic_dec(&sdata->bss->num_sta_ps); | 677 | atomic_dec(&sdata->bss->num_sta_ps); |
674 | 678 | ||
675 | clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL); | 679 | clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL); |
680 | if (local->ops->sta_notify_ps) | ||
681 | local->ops->sta_notify_ps(local_to_hw(local), STA_NOTIFY_AWAKE, | ||
682 | &sta->sta); | ||
676 | 683 | ||
677 | if (!skb_queue_empty(&sta->ps_tx_buf)) | 684 | if (!skb_queue_empty(&sta->ps_tx_buf)) |
678 | sta_info_clear_tim_bit(sta); | 685 | sta_info_clear_tim_bit(sta); |
@@ -741,17 +748,29 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | |||
741 | sta->last_qual = rx->status->qual; | 748 | sta->last_qual = rx->status->qual; |
742 | sta->last_noise = rx->status->noise; | 749 | sta->last_noise = rx->status->noise; |
743 | 750 | ||
751 | /* | ||
752 | * Change STA power saving mode only at the end of a frame | ||
753 | * exchange sequence. | ||
754 | */ | ||
744 | if (!ieee80211_has_morefrags(hdr->frame_control) && | 755 | if (!ieee80211_has_morefrags(hdr->frame_control) && |
745 | (rx->sdata->vif.type == NL80211_IFTYPE_AP || | 756 | (rx->sdata->vif.type == NL80211_IFTYPE_AP || |
746 | rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) { | 757 | rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) { |
747 | /* Change STA power saving mode only in the end of a frame | 758 | if (test_sta_flags(sta, WLAN_STA_PS)) { |
748 | * exchange sequence */ | 759 | /* |
749 | if (test_sta_flags(sta, WLAN_STA_PS) && | 760 | * Ignore doze->wake transitions that are |
750 | !ieee80211_has_pm(hdr->frame_control)) | 761 | * indicated by non-data frames, the standard |
751 | rx->sent_ps_buffered += ap_sta_ps_end(sta); | 762 | * is unclear here, but for example going to |
752 | else if (!test_sta_flags(sta, WLAN_STA_PS) && | 763 | * PS mode and then scanning would cause a |
753 | ieee80211_has_pm(hdr->frame_control)) | 764 | * doze->wake transition for the probe request, |
754 | ap_sta_ps_start(sta); | 765 | * and that is clearly undesirable. |
766 | */ | ||
767 | if (ieee80211_is_data(hdr->frame_control) && | ||
768 | !ieee80211_has_pm(hdr->frame_control)) | ||
769 | rx->sent_ps_buffered += ap_sta_ps_end(sta); | ||
770 | } else { | ||
771 | if (ieee80211_has_pm(hdr->frame_control)) | ||
772 | ap_sta_ps_start(sta); | ||
773 | } | ||
755 | } | 774 | } |
756 | 775 | ||
757 | /* Drop data::nullfunc frames silently, since they are used only to | 776 | /* Drop data::nullfunc frames silently, since they are used only to |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 0d81b2cfd1a6..d7761e95e4cf 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1779,8 +1779,7 @@ void ieee80211_tx_pending(unsigned long data) | |||
1779 | 1779 | ||
1780 | /* functions for drivers to get certain frames */ | 1780 | /* functions for drivers to get certain frames */ |
1781 | 1781 | ||
1782 | static void ieee80211_beacon_add_tim(struct ieee80211_local *local, | 1782 | static void ieee80211_beacon_add_tim(struct ieee80211_if_ap *bss, |
1783 | struct ieee80211_if_ap *bss, | ||
1784 | struct sk_buff *skb, | 1783 | struct sk_buff *skb, |
1785 | struct beacon_data *beacon) | 1784 | struct beacon_data *beacon) |
1786 | { | 1785 | { |
@@ -1848,7 +1847,6 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1848 | struct ieee80211_local *local = hw_to_local(hw); | 1847 | struct ieee80211_local *local = hw_to_local(hw); |
1849 | struct sk_buff *skb = NULL; | 1848 | struct sk_buff *skb = NULL; |
1850 | struct ieee80211_tx_info *info; | 1849 | struct ieee80211_tx_info *info; |
1851 | struct net_device *bdev; | ||
1852 | struct ieee80211_sub_if_data *sdata = NULL; | 1850 | struct ieee80211_sub_if_data *sdata = NULL; |
1853 | struct ieee80211_if_ap *ap = NULL; | 1851 | struct ieee80211_if_ap *ap = NULL; |
1854 | struct ieee80211_if_sta *ifsta = NULL; | 1852 | struct ieee80211_if_sta *ifsta = NULL; |
@@ -1861,7 +1859,6 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1861 | rcu_read_lock(); | 1859 | rcu_read_lock(); |
1862 | 1860 | ||
1863 | sdata = vif_to_sdata(vif); | 1861 | sdata = vif_to_sdata(vif); |
1864 | bdev = sdata->dev; | ||
1865 | 1862 | ||
1866 | if (sdata->vif.type == NL80211_IFTYPE_AP) { | 1863 | if (sdata->vif.type == NL80211_IFTYPE_AP) { |
1867 | ap = &sdata->u.ap; | 1864 | ap = &sdata->u.ap; |
@@ -1889,12 +1886,12 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1889 | * of the tim bitmap in mac80211 and the driver. | 1886 | * of the tim bitmap in mac80211 and the driver. |
1890 | */ | 1887 | */ |
1891 | if (local->tim_in_locked_section) { | 1888 | if (local->tim_in_locked_section) { |
1892 | ieee80211_beacon_add_tim(local, ap, skb, beacon); | 1889 | ieee80211_beacon_add_tim(ap, skb, beacon); |
1893 | } else { | 1890 | } else { |
1894 | unsigned long flags; | 1891 | unsigned long flags; |
1895 | 1892 | ||
1896 | spin_lock_irqsave(&local->sta_lock, flags); | 1893 | spin_lock_irqsave(&local->sta_lock, flags); |
1897 | ieee80211_beacon_add_tim(local, ap, skb, beacon); | 1894 | ieee80211_beacon_add_tim(ap, skb, beacon); |
1898 | spin_unlock_irqrestore(&local->sta_lock, flags); | 1895 | spin_unlock_irqrestore(&local->sta_lock, flags); |
1899 | } | 1896 | } |
1900 | 1897 | ||
@@ -2016,14 +2013,12 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, | |||
2016 | struct sk_buff *skb = NULL; | 2013 | struct sk_buff *skb = NULL; |
2017 | struct sta_info *sta; | 2014 | struct sta_info *sta; |
2018 | struct ieee80211_tx_data tx; | 2015 | struct ieee80211_tx_data tx; |
2019 | struct net_device *bdev; | ||
2020 | struct ieee80211_sub_if_data *sdata; | 2016 | struct ieee80211_sub_if_data *sdata; |
2021 | struct ieee80211_if_ap *bss = NULL; | 2017 | struct ieee80211_if_ap *bss = NULL; |
2022 | struct beacon_data *beacon; | 2018 | struct beacon_data *beacon; |
2023 | struct ieee80211_tx_info *info; | 2019 | struct ieee80211_tx_info *info; |
2024 | 2020 | ||
2025 | sdata = vif_to_sdata(vif); | 2021 | sdata = vif_to_sdata(vif); |
2026 | bdev = sdata->dev; | ||
2027 | bss = &sdata->u.ap; | 2022 | bss = &sdata->u.ap; |
2028 | 2023 | ||
2029 | if (!bss) | 2024 | if (!bss) |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 0f841317c7e9..505d68f344ce 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -641,6 +641,7 @@ int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freqMHz) | |||
641 | chan->flags & IEEE80211_CHAN_NO_IBSS) | 641 | chan->flags & IEEE80211_CHAN_NO_IBSS) |
642 | return ret; | 642 | return ret; |
643 | local->oper_channel = chan; | 643 | local->oper_channel = chan; |
644 | local->oper_sec_chan_offset = NL80211_SEC_CHAN_NO_HT; | ||
644 | 645 | ||
645 | if (local->sw_scanning || local->hw_scanning) | 646 | if (local->sw_scanning || local->hw_scanning) |
646 | ret = 0; | 647 | ret = 0; |
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index b3ce28d35611..4e1fdcfacb0c 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c | |||
@@ -135,48 +135,6 @@ static int ieee80211_ioctl_siwgenie(struct net_device *dev, | |||
135 | return -EOPNOTSUPP; | 135 | return -EOPNOTSUPP; |
136 | } | 136 | } |
137 | 137 | ||
138 | static int ieee80211_ioctl_giwname(struct net_device *dev, | ||
139 | struct iw_request_info *info, | ||
140 | char *name, char *extra) | ||
141 | { | ||
142 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
143 | struct ieee80211_supported_band *sband; | ||
144 | u8 is_ht = 0, is_a = 0, is_b = 0, is_g = 0; | ||
145 | |||
146 | |||
147 | sband = local->hw.wiphy->bands[IEEE80211_BAND_5GHZ]; | ||
148 | if (sband) { | ||
149 | is_a = 1; | ||
150 | is_ht |= sband->ht_cap.ht_supported; | ||
151 | } | ||
152 | |||
153 | sband = local->hw.wiphy->bands[IEEE80211_BAND_2GHZ]; | ||
154 | if (sband) { | ||
155 | int i; | ||
156 | /* Check for mandatory rates */ | ||
157 | for (i = 0; i < sband->n_bitrates; i++) { | ||
158 | if (sband->bitrates[i].bitrate == 10) | ||
159 | is_b = 1; | ||
160 | if (sband->bitrates[i].bitrate == 60) | ||
161 | is_g = 1; | ||
162 | } | ||
163 | is_ht |= sband->ht_cap.ht_supported; | ||
164 | } | ||
165 | |||
166 | strcpy(name, "IEEE 802.11"); | ||
167 | if (is_a) | ||
168 | strcat(name, "a"); | ||
169 | if (is_b) | ||
170 | strcat(name, "b"); | ||
171 | if (is_g) | ||
172 | strcat(name, "g"); | ||
173 | if (is_ht) | ||
174 | strcat(name, "n"); | ||
175 | |||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | |||
180 | static int ieee80211_ioctl_giwrange(struct net_device *dev, | 138 | static int ieee80211_ioctl_giwrange(struct net_device *dev, |
181 | struct iw_request_info *info, | 139 | struct iw_request_info *info, |
182 | struct iw_point *data, char *extra) | 140 | struct iw_point *data, char *extra) |
@@ -266,78 +224,6 @@ static int ieee80211_ioctl_giwrange(struct net_device *dev, | |||
266 | } | 224 | } |
267 | 225 | ||
268 | 226 | ||
269 | static int ieee80211_ioctl_siwmode(struct net_device *dev, | ||
270 | struct iw_request_info *info, | ||
271 | __u32 *mode, char *extra) | ||
272 | { | ||
273 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
274 | struct ieee80211_local *local = sdata->local; | ||
275 | int type; | ||
276 | |||
277 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | ||
278 | return -EOPNOTSUPP; | ||
279 | |||
280 | switch (*mode) { | ||
281 | case IW_MODE_INFRA: | ||
282 | type = NL80211_IFTYPE_STATION; | ||
283 | break; | ||
284 | case IW_MODE_ADHOC: | ||
285 | /* Setting ad-hoc mode on non ibss channel is not | ||
286 | * supported. | ||
287 | */ | ||
288 | if (local->oper_channel && | ||
289 | (local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS)) | ||
290 | return -EOPNOTSUPP; | ||
291 | |||
292 | type = NL80211_IFTYPE_ADHOC; | ||
293 | break; | ||
294 | case IW_MODE_REPEAT: | ||
295 | type = NL80211_IFTYPE_WDS; | ||
296 | break; | ||
297 | case IW_MODE_MONITOR: | ||
298 | type = NL80211_IFTYPE_MONITOR; | ||
299 | break; | ||
300 | default: | ||
301 | return -EINVAL; | ||
302 | } | ||
303 | |||
304 | return ieee80211_if_change_type(sdata, type); | ||
305 | } | ||
306 | |||
307 | |||
308 | static int ieee80211_ioctl_giwmode(struct net_device *dev, | ||
309 | struct iw_request_info *info, | ||
310 | __u32 *mode, char *extra) | ||
311 | { | ||
312 | struct ieee80211_sub_if_data *sdata; | ||
313 | |||
314 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
315 | switch (sdata->vif.type) { | ||
316 | case NL80211_IFTYPE_AP: | ||
317 | *mode = IW_MODE_MASTER; | ||
318 | break; | ||
319 | case NL80211_IFTYPE_STATION: | ||
320 | *mode = IW_MODE_INFRA; | ||
321 | break; | ||
322 | case NL80211_IFTYPE_ADHOC: | ||
323 | *mode = IW_MODE_ADHOC; | ||
324 | break; | ||
325 | case NL80211_IFTYPE_MONITOR: | ||
326 | *mode = IW_MODE_MONITOR; | ||
327 | break; | ||
328 | case NL80211_IFTYPE_WDS: | ||
329 | *mode = IW_MODE_REPEAT; | ||
330 | break; | ||
331 | case NL80211_IFTYPE_AP_VLAN: | ||
332 | *mode = IW_MODE_SECOND; /* FIXME */ | ||
333 | break; | ||
334 | default: | ||
335 | *mode = IW_MODE_AUTO; | ||
336 | break; | ||
337 | } | ||
338 | return 0; | ||
339 | } | ||
340 | |||
341 | static int ieee80211_ioctl_siwfreq(struct net_device *dev, | 227 | static int ieee80211_ioctl_siwfreq(struct net_device *dev, |
342 | struct iw_request_info *info, | 228 | struct iw_request_info *info, |
343 | struct iw_freq *freq, char *extra) | 229 | struct iw_freq *freq, char *extra) |
@@ -1146,13 +1032,13 @@ static int ieee80211_ioctl_siwencodeext(struct net_device *dev, | |||
1146 | static const iw_handler ieee80211_handler[] = | 1032 | static const iw_handler ieee80211_handler[] = |
1147 | { | 1033 | { |
1148 | (iw_handler) NULL, /* SIOCSIWCOMMIT */ | 1034 | (iw_handler) NULL, /* SIOCSIWCOMMIT */ |
1149 | (iw_handler) ieee80211_ioctl_giwname, /* SIOCGIWNAME */ | 1035 | (iw_handler) cfg80211_wext_giwname, /* SIOCGIWNAME */ |
1150 | (iw_handler) NULL, /* SIOCSIWNWID */ | 1036 | (iw_handler) NULL, /* SIOCSIWNWID */ |
1151 | (iw_handler) NULL, /* SIOCGIWNWID */ | 1037 | (iw_handler) NULL, /* SIOCGIWNWID */ |
1152 | (iw_handler) ieee80211_ioctl_siwfreq, /* SIOCSIWFREQ */ | 1038 | (iw_handler) ieee80211_ioctl_siwfreq, /* SIOCSIWFREQ */ |
1153 | (iw_handler) ieee80211_ioctl_giwfreq, /* SIOCGIWFREQ */ | 1039 | (iw_handler) ieee80211_ioctl_giwfreq, /* SIOCGIWFREQ */ |
1154 | (iw_handler) ieee80211_ioctl_siwmode, /* SIOCSIWMODE */ | 1040 | (iw_handler) cfg80211_wext_siwmode, /* SIOCSIWMODE */ |
1155 | (iw_handler) ieee80211_ioctl_giwmode, /* SIOCGIWMODE */ | 1041 | (iw_handler) cfg80211_wext_giwmode, /* SIOCGIWMODE */ |
1156 | (iw_handler) NULL, /* SIOCSIWSENS */ | 1042 | (iw_handler) NULL, /* SIOCSIWSENS */ |
1157 | (iw_handler) NULL, /* SIOCGIWSENS */ | 1043 | (iw_handler) NULL, /* SIOCGIWSENS */ |
1158 | (iw_handler) NULL /* not used */, /* SIOCSIWRANGE */ | 1044 | (iw_handler) NULL /* not used */, /* SIOCSIWRANGE */ |
diff --git a/net/wireless/Makefile b/net/wireless/Makefile index cc547edb111f..9bc412c83430 100644 --- a/net/wireless/Makefile +++ b/net/wireless/Makefile | |||
@@ -6,4 +6,5 @@ obj-$(CONFIG_LIB80211_CRYPT_CCMP) += lib80211_crypt_ccmp.o | |||
6 | obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o | 6 | obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o |
7 | 7 | ||
8 | cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o | 8 | cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o |
9 | cfg80211-$(CONFIG_WIRELESS_EXT) += wext-compat.o | ||
9 | cfg80211-$(CONFIG_NL80211) += nl80211.o | 10 | cfg80211-$(CONFIG_NL80211) += nl80211.o |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index c9141e3df9ba..9caee6022e3f 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -59,6 +59,8 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = { | |||
59 | [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING, | 59 | [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING, |
60 | .len = BUS_ID_SIZE-1 }, | 60 | .len = BUS_ID_SIZE-1 }, |
61 | [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED }, | 61 | [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED }, |
62 | [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 }, | ||
63 | [NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET] = { .type = NLA_U32 }, | ||
62 | 64 | ||
63 | [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 }, | 65 | [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 }, |
64 | [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 }, | 66 | [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 }, |
@@ -359,6 +361,61 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
359 | } | 361 | } |
360 | } | 362 | } |
361 | 363 | ||
364 | if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { | ||
365 | enum nl80211_sec_chan_offset sec_chan_offset = | ||
366 | NL80211_SEC_CHAN_NO_HT; | ||
367 | struct ieee80211_channel *chan; | ||
368 | u32 freq, sec_freq; | ||
369 | |||
370 | if (!rdev->ops->set_channel) { | ||
371 | result = -EOPNOTSUPP; | ||
372 | goto bad_res; | ||
373 | } | ||
374 | |||
375 | if (info->attrs[NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET]) { | ||
376 | sec_chan_offset = nla_get_u32( | ||
377 | info->attrs[ | ||
378 | NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET]); | ||
379 | if (sec_chan_offset != NL80211_SEC_CHAN_NO_HT && | ||
380 | sec_chan_offset != NL80211_SEC_CHAN_DISABLED && | ||
381 | sec_chan_offset != NL80211_SEC_CHAN_BELOW && | ||
382 | sec_chan_offset != NL80211_SEC_CHAN_ABOVE) { | ||
383 | result = -EINVAL; | ||
384 | goto bad_res; | ||
385 | } | ||
386 | } | ||
387 | |||
388 | freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]); | ||
389 | chan = ieee80211_get_channel(&rdev->wiphy, freq); | ||
390 | if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) { | ||
391 | /* Primary channel not allowed */ | ||
392 | result = -EINVAL; | ||
393 | goto bad_res; | ||
394 | } | ||
395 | if (sec_chan_offset == NL80211_SEC_CHAN_BELOW) | ||
396 | sec_freq = freq - 20; | ||
397 | else if (sec_chan_offset == NL80211_SEC_CHAN_ABOVE) | ||
398 | sec_freq = freq + 20; | ||
399 | else | ||
400 | sec_freq = 0; | ||
401 | |||
402 | if (sec_freq) { | ||
403 | struct ieee80211_channel *schan; | ||
404 | schan = ieee80211_get_channel(&rdev->wiphy, sec_freq); | ||
405 | if (!schan || schan->flags & IEEE80211_CHAN_DISABLED) { | ||
406 | /* Secondary channel not allowed */ | ||
407 | result = -EINVAL; | ||
408 | goto bad_res; | ||
409 | } | ||
410 | } | ||
411 | |||
412 | result = rdev->ops->set_channel(&rdev->wiphy, chan, | ||
413 | sec_chan_offset); | ||
414 | if (result) | ||
415 | goto bad_res; | ||
416 | } | ||
417 | |||
418 | |||
362 | bad_res: | 419 | bad_res: |
363 | cfg80211_put_dev(rdev); | 420 | cfg80211_put_dev(rdev); |
364 | return result; | 421 | return result; |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 0990059f7e48..4f877535e666 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -989,6 +989,9 @@ void regulatory_hint_11d(struct wiphy *wiphy, | |||
989 | u32 checksum = 0; | 989 | u32 checksum = 0; |
990 | enum environment_cap env = ENVIRON_ANY; | 990 | enum environment_cap env = ENVIRON_ANY; |
991 | 991 | ||
992 | if (!last_request) | ||
993 | return; | ||
994 | |||
992 | mutex_lock(&cfg80211_drv_mutex); | 995 | mutex_lock(&cfg80211_drv_mutex); |
993 | 996 | ||
994 | /* IE len must be evenly divisible by 2 */ | 997 | /* IE len must be evenly divisible by 2 */ |
@@ -1330,7 +1333,7 @@ int set_regdom(const struct ieee80211_regdomain *rd) | |||
1330 | /* Caller must hold cfg80211_drv_mutex */ | 1333 | /* Caller must hold cfg80211_drv_mutex */ |
1331 | void reg_device_remove(struct wiphy *wiphy) | 1334 | void reg_device_remove(struct wiphy *wiphy) |
1332 | { | 1335 | { |
1333 | if (!last_request->wiphy) | 1336 | if (!last_request || !last_request->wiphy) |
1334 | return; | 1337 | return; |
1335 | if (last_request->wiphy != wiphy) | 1338 | if (last_request->wiphy != wiphy) |
1336 | return; | 1339 | return; |
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c new file mode 100644 index 000000000000..58e489fd4aed --- /dev/null +++ b/net/wireless/wext-compat.c | |||
@@ -0,0 +1,139 @@ | |||
1 | /* | ||
2 | * cfg80211 - wext compat code | ||
3 | * | ||
4 | * This is temporary code until all wireless functionality is migrated | ||
5 | * into cfg80211, when that happens all the exports here go away and | ||
6 | * we directly assign the wireless handlers of wireless interfaces. | ||
7 | * | ||
8 | * Copyright 2008 Johannes Berg <johannes@sipsolutions.net> | ||
9 | */ | ||
10 | |||
11 | #include <linux/wireless.h> | ||
12 | #include <linux/nl80211.h> | ||
13 | #include <net/iw_handler.h> | ||
14 | #include <net/wireless.h> | ||
15 | #include <net/cfg80211.h> | ||
16 | #include "core.h" | ||
17 | |||
18 | int cfg80211_wext_giwname(struct net_device *dev, | ||
19 | struct iw_request_info *info, | ||
20 | char *name, char *extra) | ||
21 | { | ||
22 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
23 | struct ieee80211_supported_band *sband; | ||
24 | bool is_ht = false, is_a = false, is_b = false, is_g = false; | ||
25 | |||
26 | if (!wdev) | ||
27 | return -EOPNOTSUPP; | ||
28 | |||
29 | sband = wdev->wiphy->bands[IEEE80211_BAND_5GHZ]; | ||
30 | if (sband) { | ||
31 | is_a = true; | ||
32 | is_ht |= sband->ht_cap.ht_supported; | ||
33 | } | ||
34 | |||
35 | sband = wdev->wiphy->bands[IEEE80211_BAND_2GHZ]; | ||
36 | if (sband) { | ||
37 | int i; | ||
38 | /* Check for mandatory rates */ | ||
39 | for (i = 0; i < sband->n_bitrates; i++) { | ||
40 | if (sband->bitrates[i].bitrate == 10) | ||
41 | is_b = true; | ||
42 | if (sband->bitrates[i].bitrate == 60) | ||
43 | is_g = true; | ||
44 | } | ||
45 | is_ht |= sband->ht_cap.ht_supported; | ||
46 | } | ||
47 | |||
48 | strcpy(name, "IEEE 802.11"); | ||
49 | if (is_a) | ||
50 | strcat(name, "a"); | ||
51 | if (is_b) | ||
52 | strcat(name, "b"); | ||
53 | if (is_g) | ||
54 | strcat(name, "g"); | ||
55 | if (is_ht) | ||
56 | strcat(name, "n"); | ||
57 | |||
58 | return 0; | ||
59 | } | ||
60 | EXPORT_SYMBOL(cfg80211_wext_giwname); | ||
61 | |||
62 | int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info, | ||
63 | u32 *mode, char *extra) | ||
64 | { | ||
65 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
66 | struct cfg80211_registered_device *rdev; | ||
67 | struct vif_params vifparams; | ||
68 | enum nl80211_iftype type; | ||
69 | |||
70 | if (!wdev) | ||
71 | return -EOPNOTSUPP; | ||
72 | |||
73 | rdev = wiphy_to_dev(wdev->wiphy); | ||
74 | |||
75 | if (!rdev->ops->change_virtual_intf) | ||
76 | return -EOPNOTSUPP; | ||
77 | |||
78 | /* don't support changing VLANs, you just re-create them */ | ||
79 | if (wdev->iftype == NL80211_IFTYPE_AP_VLAN) | ||
80 | return -EOPNOTSUPP; | ||
81 | |||
82 | switch (*mode) { | ||
83 | case IW_MODE_INFRA: | ||
84 | type = NL80211_IFTYPE_STATION; | ||
85 | break; | ||
86 | case IW_MODE_ADHOC: | ||
87 | type = NL80211_IFTYPE_ADHOC; | ||
88 | break; | ||
89 | case IW_MODE_REPEAT: | ||
90 | type = NL80211_IFTYPE_WDS; | ||
91 | break; | ||
92 | case IW_MODE_MONITOR: | ||
93 | type = NL80211_IFTYPE_MONITOR; | ||
94 | break; | ||
95 | default: | ||
96 | return -EINVAL; | ||
97 | } | ||
98 | |||
99 | memset(&vifparams, 0, sizeof(vifparams)); | ||
100 | |||
101 | return rdev->ops->change_virtual_intf(wdev->wiphy, dev->ifindex, type, | ||
102 | NULL, &vifparams); | ||
103 | } | ||
104 | EXPORT_SYMBOL(cfg80211_wext_siwmode); | ||
105 | |||
106 | int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info, | ||
107 | u32 *mode, char *extra) | ||
108 | { | ||
109 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
110 | |||
111 | if (!wdev) | ||
112 | return -EOPNOTSUPP; | ||
113 | |||
114 | switch (wdev->iftype) { | ||
115 | case NL80211_IFTYPE_AP: | ||
116 | *mode = IW_MODE_MASTER; | ||
117 | break; | ||
118 | case NL80211_IFTYPE_STATION: | ||
119 | *mode = IW_MODE_INFRA; | ||
120 | break; | ||
121 | case NL80211_IFTYPE_ADHOC: | ||
122 | *mode = IW_MODE_ADHOC; | ||
123 | break; | ||
124 | case NL80211_IFTYPE_MONITOR: | ||
125 | *mode = IW_MODE_MONITOR; | ||
126 | break; | ||
127 | case NL80211_IFTYPE_WDS: | ||
128 | *mode = IW_MODE_REPEAT; | ||
129 | break; | ||
130 | case NL80211_IFTYPE_AP_VLAN: | ||
131 | *mode = IW_MODE_SECOND; /* FIXME */ | ||
132 | break; | ||
133 | default: | ||
134 | *mode = IW_MODE_AUTO; | ||
135 | break; | ||
136 | } | ||
137 | return 0; | ||
138 | } | ||
139 | EXPORT_SYMBOL(cfg80211_wext_giwmode); | ||