diff options
author | Lukáš Turek <8an@praha12.net> | 2009-12-21 16:50:51 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-01-12 13:50:08 -0500 |
commit | 6e08d228b6d8e93d7b25b3573c6da7da179c2ae1 (patch) | |
tree | b489861f90b416a48f7f46fa4adb23972a5148c3 | |
parent | 3578e6ebb305e6bf7519f6e86741772892f4d51a (diff) |
ath5k: Implement mac80211 callback set_coverage_class
The callback sets slot time as specified in IEEE 802.11-2007 section
17.3.8.6 (for 20MHz channels only for now) and raises ACK and CTS
timeouts accordingly. The values are persistent, they are restored after
device reset.
Signed-off-by: Lukas Turek <8an@praha12.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/ath/ath5k/ath5k.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/base.c | 22 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/pcu.c | 57 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/reset.c | 4 |
4 files changed, 85 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index ae311d2dcc16..66bcb506a112 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h | |||
@@ -1063,6 +1063,7 @@ struct ath5k_hw { | |||
1063 | u32 ah_cw_min; | 1063 | u32 ah_cw_min; |
1064 | u32 ah_cw_max; | 1064 | u32 ah_cw_max; |
1065 | u32 ah_limit_tx_retries; | 1065 | u32 ah_limit_tx_retries; |
1066 | u8 ah_coverage_class; | ||
1066 | 1067 | ||
1067 | /* Antenna Control */ | 1068 | /* Antenna Control */ |
1068 | u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX]; | 1069 | u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX]; |
@@ -1200,6 +1201,7 @@ extern bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah); | |||
1200 | 1201 | ||
1201 | /* Protocol Control Unit Functions */ | 1202 | /* Protocol Control Unit Functions */ |
1202 | extern int ath5k_hw_set_opmode(struct ath5k_hw *ah); | 1203 | extern int ath5k_hw_set_opmode(struct ath5k_hw *ah); |
1204 | extern void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class); | ||
1203 | /* BSSID Functions */ | 1205 | /* BSSID Functions */ |
1204 | extern int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac); | 1206 | extern int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac); |
1205 | extern void ath5k_hw_set_associd(struct ath5k_hw *ah); | 1207 | extern void ath5k_hw_set_associd(struct ath5k_hw *ah); |
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index fdfaf0f618f1..b5015376d4ba 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -254,6 +254,8 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw, | |||
254 | u32 changes); | 254 | u32 changes); |
255 | static void ath5k_sw_scan_start(struct ieee80211_hw *hw); | 255 | static void ath5k_sw_scan_start(struct ieee80211_hw *hw); |
256 | static void ath5k_sw_scan_complete(struct ieee80211_hw *hw); | 256 | static void ath5k_sw_scan_complete(struct ieee80211_hw *hw); |
257 | static void ath5k_set_coverage_class(struct ieee80211_hw *hw, | ||
258 | u8 coverage_class); | ||
257 | 259 | ||
258 | static const struct ieee80211_ops ath5k_hw_ops = { | 260 | static const struct ieee80211_ops ath5k_hw_ops = { |
259 | .tx = ath5k_tx, | 261 | .tx = ath5k_tx, |
@@ -274,6 +276,7 @@ static const struct ieee80211_ops ath5k_hw_ops = { | |||
274 | .bss_info_changed = ath5k_bss_info_changed, | 276 | .bss_info_changed = ath5k_bss_info_changed, |
275 | .sw_scan_start = ath5k_sw_scan_start, | 277 | .sw_scan_start = ath5k_sw_scan_start, |
276 | .sw_scan_complete = ath5k_sw_scan_complete, | 278 | .sw_scan_complete = ath5k_sw_scan_complete, |
279 | .set_coverage_class = ath5k_set_coverage_class, | ||
277 | }; | 280 | }; |
278 | 281 | ||
279 | /* | 282 | /* |
@@ -3262,3 +3265,22 @@ static void ath5k_sw_scan_complete(struct ieee80211_hw *hw) | |||
3262 | ath5k_hw_set_ledstate(sc->ah, sc->assoc ? | 3265 | ath5k_hw_set_ledstate(sc->ah, sc->assoc ? |
3263 | AR5K_LED_ASSOC : AR5K_LED_INIT); | 3266 | AR5K_LED_ASSOC : AR5K_LED_INIT); |
3264 | } | 3267 | } |
3268 | |||
3269 | /** | ||
3270 | * ath5k_set_coverage_class - Set IEEE 802.11 coverage class | ||
3271 | * | ||
3272 | * @hw: struct ieee80211_hw pointer | ||
3273 | * @coverage_class: IEEE 802.11 coverage class number | ||
3274 | * | ||
3275 | * Mac80211 callback. Sets slot time, ACK timeout and CTS timeout for given | ||
3276 | * coverage class. The values are persistent, they are restored after device | ||
3277 | * reset. | ||
3278 | */ | ||
3279 | static void ath5k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) | ||
3280 | { | ||
3281 | struct ath5k_softc *sc = hw->priv; | ||
3282 | |||
3283 | mutex_lock(&sc->lock); | ||
3284 | ath5k_hw_set_coverage_class(sc->ah, coverage_class); | ||
3285 | mutex_unlock(&sc->lock); | ||
3286 | } | ||
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index b601ff9865fd..aefe84f9c04b 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c | |||
@@ -286,6 +286,42 @@ unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah) | |||
286 | } | 286 | } |
287 | 287 | ||
288 | /** | 288 | /** |
289 | * ath5k_hw_get_default_slottime - Get the default slot time for current mode | ||
290 | * | ||
291 | * @ah: The &struct ath5k_hw | ||
292 | */ | ||
293 | unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah) | ||
294 | { | ||
295 | struct ieee80211_channel *channel = ah->ah_current_channel; | ||
296 | |||
297 | if (channel->hw_value & CHANNEL_TURBO) | ||
298 | return 6; /* both turbo modes */ | ||
299 | |||
300 | if (channel->hw_value & CHANNEL_CCK) | ||
301 | return 20; /* 802.11b */ | ||
302 | |||
303 | return 9; /* 802.11 a/g */ | ||
304 | } | ||
305 | |||
306 | /** | ||
307 | * ath5k_hw_get_default_sifs - Get the default SIFS for current mode | ||
308 | * | ||
309 | * @ah: The &struct ath5k_hw | ||
310 | */ | ||
311 | unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah) | ||
312 | { | ||
313 | struct ieee80211_channel *channel = ah->ah_current_channel; | ||
314 | |||
315 | if (channel->hw_value & CHANNEL_TURBO) | ||
316 | return 8; /* both turbo modes */ | ||
317 | |||
318 | if (channel->hw_value & CHANNEL_5GHZ) | ||
319 | return 16; /* 802.11a */ | ||
320 | |||
321 | return 10; /* 802.11 b/g */ | ||
322 | } | ||
323 | |||
324 | /** | ||
289 | * ath5k_hw_set_lladdr - Set station id | 325 | * ath5k_hw_set_lladdr - Set station id |
290 | * | 326 | * |
291 | * @ah: The &struct ath5k_hw | 327 | * @ah: The &struct ath5k_hw |
@@ -1094,3 +1130,24 @@ int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac) | |||
1094 | return 0; | 1130 | return 0; |
1095 | } | 1131 | } |
1096 | 1132 | ||
1133 | /** | ||
1134 | * ath5k_hw_set_coverage_class - Set IEEE 802.11 coverage class | ||
1135 | * | ||
1136 | * @ah: The &struct ath5k_hw | ||
1137 | * @coverage_class: IEEE 802.11 coverage class number | ||
1138 | * | ||
1139 | * Sets slot time, ACK timeout and CTS timeout for given coverage class. | ||
1140 | */ | ||
1141 | void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class) | ||
1142 | { | ||
1143 | /* As defined by IEEE 802.11-2007 17.3.8.6 */ | ||
1144 | int slot_time = ath5k_hw_get_default_slottime(ah) + 3 * coverage_class; | ||
1145 | int ack_timeout = ath5k_hw_get_default_sifs(ah) + slot_time; | ||
1146 | int cts_timeout = ack_timeout; | ||
1147 | |||
1148 | ath5k_hw_set_slot_time(ah, slot_time); | ||
1149 | ath5k_hw_set_ack_timeout(ah, ack_timeout); | ||
1150 | ath5k_hw_set_cts_timeout(ah, cts_timeout); | ||
1151 | |||
1152 | ah->ah_coverage_class = coverage_class; | ||
1153 | } | ||
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index 299b33a03979..6690923fd78c 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c | |||
@@ -1316,6 +1316,10 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
1316 | /* Restore antenna mode */ | 1316 | /* Restore antenna mode */ |
1317 | ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode); | 1317 | ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode); |
1318 | 1318 | ||
1319 | /* Restore slot time and ACK timeouts */ | ||
1320 | if (ah->ah_coverage_class > 0) | ||
1321 | ath5k_hw_set_coverage_class(ah, ah->ah_coverage_class); | ||
1322 | |||
1319 | /* | 1323 | /* |
1320 | * Configure QCUs/DCUs | 1324 | * Configure QCUs/DCUs |
1321 | */ | 1325 | */ |