diff options
author | Felix Fietkau <nbd@openwrt.org> | 2010-01-14 20:33:40 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-01-15 17:02:08 -0500 |
commit | 0005baf4a31efe6de6f922f73ccbd3762a110062 (patch) | |
tree | a5eb0a5e336c17be79c3a3ca1ac823064155ed84 /drivers/net/wireless/ath/ath9k/hw.c | |
parent | 145b6d1a56f224d15c61aa7ecfda9a1171b47b6a (diff) |
ath9k: cleanup slot time and ack/cts timeout handling
Previously ath9k left the initialization of slot timing and ACK/CTS
timeout to the mode specific initvals. This does not handle short vs
long slot in 2.4 GHz and uses a rather strange value for the 2.4 GHz
ACK timeout (64 usec).
This patch uses the proper ath9k_hw functions for setting slot time and
timeouts and also implements the switch between short and long slot
time in 2.4 GHz
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/hw.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.c | 103 |
1 files changed, 32 insertions, 71 deletions
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 2311fe7a0bf2..e1fd4cc9fae2 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -52,28 +52,6 @@ module_exit(ath9k_exit); | |||
52 | /* Helper Functions */ | 52 | /* Helper Functions */ |
53 | /********************/ | 53 | /********************/ |
54 | 54 | ||
55 | static u32 ath9k_hw_mac_usec(struct ath_hw *ah, u32 clks) | ||
56 | { | ||
57 | struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; | ||
58 | |||
59 | if (!ah->curchan) /* should really check for CCK instead */ | ||
60 | return clks / ATH9K_CLOCK_RATE_CCK; | ||
61 | if (conf->channel->band == IEEE80211_BAND_2GHZ) | ||
62 | return clks / ATH9K_CLOCK_RATE_2GHZ_OFDM; | ||
63 | |||
64 | return clks / ATH9K_CLOCK_RATE_5GHZ_OFDM; | ||
65 | } | ||
66 | |||
67 | static u32 ath9k_hw_mac_to_usec(struct ath_hw *ah, u32 clks) | ||
68 | { | ||
69 | struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; | ||
70 | |||
71 | if (conf_is_ht40(conf)) | ||
72 | return ath9k_hw_mac_usec(ah, clks) / 2; | ||
73 | else | ||
74 | return ath9k_hw_mac_usec(ah, clks); | ||
75 | } | ||
76 | |||
77 | static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs) | 55 | static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs) |
78 | { | 56 | { |
79 | struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; | 57 | struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; |
@@ -413,8 +391,6 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah) | |||
413 | ah->beacon_interval = 100; | 391 | ah->beacon_interval = 100; |
414 | ah->enable_32kHz_clock = DONT_USE_32KHZ; | 392 | ah->enable_32kHz_clock = DONT_USE_32KHZ; |
415 | ah->slottime = (u32) -1; | 393 | ah->slottime = (u32) -1; |
416 | ah->acktimeout = (u32) -1; | ||
417 | ah->ctstimeout = (u32) -1; | ||
418 | ah->globaltxtimeout = (u32) -1; | 394 | ah->globaltxtimeout = (u32) -1; |
419 | ah->power_mode = ATH9K_PM_UNDEFINED; | 395 | ah->power_mode = ATH9K_PM_UNDEFINED; |
420 | } | 396 | } |
@@ -1180,34 +1156,25 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, | |||
1180 | } | 1156 | } |
1181 | } | 1157 | } |
1182 | 1158 | ||
1183 | static bool ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us) | 1159 | static void ath9k_hw_setslottime(struct ath_hw *ah, u32 us) |
1184 | { | 1160 | { |
1185 | if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) { | 1161 | u32 val = ath9k_hw_mac_to_clks(ah, us); |
1186 | ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, | 1162 | val = min(val, (u32) 0xFFFF); |
1187 | "bad ack timeout %u\n", us); | 1163 | REG_WRITE(ah, AR_D_GBL_IFS_SLOT, val); |
1188 | ah->acktimeout = (u32) -1; | ||
1189 | return false; | ||
1190 | } else { | ||
1191 | REG_RMW_FIELD(ah, AR_TIME_OUT, | ||
1192 | AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us)); | ||
1193 | ah->acktimeout = us; | ||
1194 | return true; | ||
1195 | } | ||
1196 | } | 1164 | } |
1197 | 1165 | ||
1198 | static bool ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us) | 1166 | static void ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us) |
1199 | { | 1167 | { |
1200 | if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) { | 1168 | u32 val = ath9k_hw_mac_to_clks(ah, us); |
1201 | ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, | 1169 | val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_ACK)); |
1202 | "bad cts timeout %u\n", us); | 1170 | REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_ACK, val); |
1203 | ah->ctstimeout = (u32) -1; | 1171 | } |
1204 | return false; | 1172 | |
1205 | } else { | 1173 | static void ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us) |
1206 | REG_RMW_FIELD(ah, AR_TIME_OUT, | 1174 | { |
1207 | AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us)); | 1175 | u32 val = ath9k_hw_mac_to_clks(ah, us); |
1208 | ah->ctstimeout = us; | 1176 | val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_CTS)); |
1209 | return true; | 1177 | REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_CTS, val); |
1210 | } | ||
1211 | } | 1178 | } |
1212 | 1179 | ||
1213 | static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu) | 1180 | static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu) |
@@ -1224,23 +1191,32 @@ static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu) | |||
1224 | } | 1191 | } |
1225 | } | 1192 | } |
1226 | 1193 | ||
1227 | static void ath9k_hw_init_user_settings(struct ath_hw *ah) | 1194 | void ath9k_hw_init_global_settings(struct ath_hw *ah) |
1228 | { | 1195 | { |
1196 | struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; | ||
1197 | int acktimeout; | ||
1198 | int sifstime; | ||
1199 | |||
1229 | ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, "ah->misc_mode 0x%x\n", | 1200 | ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, "ah->misc_mode 0x%x\n", |
1230 | ah->misc_mode); | 1201 | ah->misc_mode); |
1231 | 1202 | ||
1232 | if (ah->misc_mode != 0) | 1203 | if (ah->misc_mode != 0) |
1233 | REG_WRITE(ah, AR_PCU_MISC, | 1204 | REG_WRITE(ah, AR_PCU_MISC, |
1234 | REG_READ(ah, AR_PCU_MISC) | ah->misc_mode); | 1205 | REG_READ(ah, AR_PCU_MISC) | ah->misc_mode); |
1235 | if (ah->slottime != (u32) -1) | 1206 | |
1236 | ath9k_hw_setslottime(ah, ah->slottime); | 1207 | if (conf->channel && conf->channel->band == IEEE80211_BAND_5GHZ) |
1237 | if (ah->acktimeout != (u32) -1) | 1208 | sifstime = 16; |
1238 | ath9k_hw_set_ack_timeout(ah, ah->acktimeout); | 1209 | else |
1239 | if (ah->ctstimeout != (u32) -1) | 1210 | sifstime = 10; |
1240 | ath9k_hw_set_cts_timeout(ah, ah->ctstimeout); | 1211 | |
1212 | acktimeout = ah->slottime + sifstime; | ||
1213 | ath9k_hw_setslottime(ah, ah->slottime); | ||
1214 | ath9k_hw_set_ack_timeout(ah, acktimeout); | ||
1215 | ath9k_hw_set_cts_timeout(ah, acktimeout); | ||
1241 | if (ah->globaltxtimeout != (u32) -1) | 1216 | if (ah->globaltxtimeout != (u32) -1) |
1242 | ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout); | 1217 | ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout); |
1243 | } | 1218 | } |
1219 | EXPORT_SYMBOL(ath9k_hw_init_global_settings); | ||
1244 | 1220 | ||
1245 | void ath9k_hw_deinit(struct ath_hw *ah) | 1221 | void ath9k_hw_deinit(struct ath_hw *ah) |
1246 | { | 1222 | { |
@@ -2061,7 +2037,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
2061 | if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) | 2037 | if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) |
2062 | ath9k_enable_rfkill(ah); | 2038 | ath9k_enable_rfkill(ah); |
2063 | 2039 | ||
2064 | ath9k_hw_init_user_settings(ah); | 2040 | ath9k_hw_init_global_settings(ah); |
2065 | 2041 | ||
2066 | if (AR_SREV_9287_12_OR_LATER(ah)) { | 2042 | if (AR_SREV_9287_12_OR_LATER(ah)) { |
2067 | REG_WRITE(ah, AR_D_GBL_IFS_SIFS, | 2043 | REG_WRITE(ah, AR_D_GBL_IFS_SIFS, |
@@ -3658,21 +3634,6 @@ u64 ath9k_hw_extend_tsf(struct ath_hw *ah, u32 rstamp) | |||
3658 | } | 3634 | } |
3659 | EXPORT_SYMBOL(ath9k_hw_extend_tsf); | 3635 | EXPORT_SYMBOL(ath9k_hw_extend_tsf); |
3660 | 3636 | ||
3661 | bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us) | ||
3662 | { | ||
3663 | if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) { | ||
3664 | ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, | ||
3665 | "bad slot time %u\n", us); | ||
3666 | ah->slottime = (u32) -1; | ||
3667 | return false; | ||
3668 | } else { | ||
3669 | REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us)); | ||
3670 | ah->slottime = us; | ||
3671 | return true; | ||
3672 | } | ||
3673 | } | ||
3674 | EXPORT_SYMBOL(ath9k_hw_setslottime); | ||
3675 | |||
3676 | void ath9k_hw_set11nmac2040(struct ath_hw *ah) | 3637 | void ath9k_hw_set11nmac2040(struct ath_hw *ah) |
3677 | { | 3638 | { |
3678 | struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; | 3639 | struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; |