diff options
author | Daniel Drake <dsd@gentoo.org> | 2006-07-18 16:33:27 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2006-07-27 16:17:28 -0400 |
commit | 5acd0c4153be25269d7cb9a4b09fd6db571c5cc1 (patch) | |
tree | b970a1b9469617597ab1594ca269bc81b020a881 /net/ieee80211/softmac/ieee80211softmac_module.c | |
parent | d8e2be90d301a0381e9b2528fe2835cf2992bca3 (diff) |
[PATCH] softmac: ERP handling and driver-level notifications
This patch implements ERP handling in softmac so that the drivers can support
protection and preambles properly.
I added a new struct, ieee80211softmac_bss_info, which is used for
BSS-dependent variables like these.
A new hook has been added (bssinfo_change), which allows the drivers to be
notified when anything in bssinfo changes.
I modified the txrates_change API to match the bssinfo_change API. The
existing one is a little messy and the usefulness of providing the old rates
is questionable (and can be implemented at driver level if really necessary).
No drivers are using this API (yet), so this should be safe.
Signed-off-by: Daniel Drake <dsd@gentoo.org>
Acked-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/ieee80211/softmac/ieee80211softmac_module.c')
-rw-r--r-- | net/ieee80211/softmac/ieee80211softmac_module.c | 78 |
1 files changed, 58 insertions, 20 deletions
diff --git a/net/ieee80211/softmac/ieee80211softmac_module.c b/net/ieee80211/softmac/ieee80211softmac_module.c index 4b2e57d12418..c275646b2269 100644 --- a/net/ieee80211/softmac/ieee80211softmac_module.c +++ b/net/ieee80211/softmac/ieee80211softmac_module.c | |||
@@ -44,6 +44,7 @@ struct net_device *alloc_ieee80211softmac(int sizeof_priv) | |||
44 | softmac->ieee->handle_assoc_response = ieee80211softmac_handle_assoc_response; | 44 | softmac->ieee->handle_assoc_response = ieee80211softmac_handle_assoc_response; |
45 | softmac->ieee->handle_reassoc_request = ieee80211softmac_handle_reassoc_req; | 45 | softmac->ieee->handle_reassoc_request = ieee80211softmac_handle_reassoc_req; |
46 | softmac->ieee->handle_disassoc = ieee80211softmac_handle_disassoc; | 46 | softmac->ieee->handle_disassoc = ieee80211softmac_handle_disassoc; |
47 | softmac->ieee->handle_beacon = ieee80211softmac_handle_beacon; | ||
47 | softmac->scaninfo = NULL; | 48 | softmac->scaninfo = NULL; |
48 | 49 | ||
49 | softmac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT; | 50 | softmac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT; |
@@ -209,35 +210,59 @@ static u8 highest_supported_rate(struct ieee80211softmac_device *mac, | |||
209 | return user_rate; | 210 | return user_rate; |
210 | } | 211 | } |
211 | 212 | ||
213 | void ieee80211softmac_process_erp(struct ieee80211softmac_device *mac, | ||
214 | u8 erp_value) | ||
215 | { | ||
216 | int use_protection; | ||
217 | int short_preamble; | ||
218 | u32 changes = 0; | ||
219 | |||
220 | /* Barker preamble mode */ | ||
221 | short_preamble = ((erp_value & WLAN_ERP_BARKER_PREAMBLE) == 0 | ||
222 | && mac->associnfo.short_preamble_available) ? 1 : 0; | ||
223 | |||
224 | /* Protection needed? */ | ||
225 | use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0; | ||
226 | |||
227 | if (mac->bssinfo.short_preamble != short_preamble) { | ||
228 | changes |= IEEE80211SOFTMAC_BSSINFOCHG_SHORT_PREAMBLE; | ||
229 | mac->bssinfo.short_preamble = short_preamble; | ||
230 | } | ||
231 | |||
232 | if (mac->bssinfo.use_protection != use_protection) { | ||
233 | changes |= IEEE80211SOFTMAC_BSSINFOCHG_PROTECTION; | ||
234 | mac->bssinfo.use_protection = use_protection; | ||
235 | } | ||
236 | |||
237 | if (mac->bssinfo_change && changes) | ||
238 | mac->bssinfo_change(mac->dev, changes); | ||
239 | } | ||
240 | |||
212 | void ieee80211softmac_recalc_txrates(struct ieee80211softmac_device *mac) | 241 | void ieee80211softmac_recalc_txrates(struct ieee80211softmac_device *mac) |
213 | { | 242 | { |
214 | struct ieee80211softmac_txrates *txrates = &mac->txrates; | 243 | struct ieee80211softmac_txrates *txrates = &mac->txrates; |
215 | struct ieee80211softmac_txrates oldrates; | ||
216 | u32 change = 0; | 244 | u32 change = 0; |
217 | 245 | ||
218 | if (mac->txrates_change) | ||
219 | oldrates = mac->txrates; | ||
220 | |||
221 | change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT; | 246 | change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT; |
222 | txrates->default_rate = highest_supported_rate(mac, &mac->associnfo.supported_rates, 0); | 247 | txrates->default_rate = highest_supported_rate(mac, &mac->bssinfo.supported_rates, 0); |
223 | 248 | ||
224 | change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK; | 249 | change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK; |
225 | txrates->default_fallback = lower_rate(mac, txrates->default_rate); | 250 | txrates->default_fallback = lower_rate(mac, txrates->default_rate); |
226 | 251 | ||
227 | change |= IEEE80211SOFTMAC_TXRATECHG_MCAST; | 252 | change |= IEEE80211SOFTMAC_TXRATECHG_MCAST; |
228 | txrates->mcast_rate = highest_supported_rate(mac, &mac->associnfo.supported_rates, 1); | 253 | txrates->mcast_rate = highest_supported_rate(mac, &mac->bssinfo.supported_rates, 1); |
229 | 254 | ||
230 | if (mac->txrates_change) | 255 | if (mac->txrates_change) |
231 | mac->txrates_change(mac->dev, change, &oldrates); | 256 | mac->txrates_change(mac->dev, change); |
232 | 257 | ||
233 | } | 258 | } |
234 | 259 | ||
235 | void ieee80211softmac_init_txrates(struct ieee80211softmac_device *mac) | 260 | void ieee80211softmac_init_bss(struct ieee80211softmac_device *mac) |
236 | { | 261 | { |
237 | struct ieee80211_device *ieee = mac->ieee; | 262 | struct ieee80211_device *ieee = mac->ieee; |
238 | u32 change = 0; | 263 | u32 change = 0; |
239 | struct ieee80211softmac_txrates *txrates = &mac->txrates; | 264 | struct ieee80211softmac_txrates *txrates = &mac->txrates; |
240 | struct ieee80211softmac_txrates oldrates; | 265 | struct ieee80211softmac_bss_info *bssinfo = &mac->bssinfo; |
241 | 266 | ||
242 | /* TODO: We need some kind of state machine to lower the default rates | 267 | /* TODO: We need some kind of state machine to lower the default rates |
243 | * if we loose too many packets. | 268 | * if we loose too many packets. |
@@ -245,8 +270,6 @@ void ieee80211softmac_init_txrates(struct ieee80211softmac_device *mac) | |||
245 | /* Change the default txrate to the highest possible value. | 270 | /* Change the default txrate to the highest possible value. |
246 | * The txrate machine will lower it, if it is too high. | 271 | * The txrate machine will lower it, if it is too high. |
247 | */ | 272 | */ |
248 | if (mac->txrates_change) | ||
249 | oldrates = mac->txrates; | ||
250 | /* FIXME: We don't correctly handle backing down to lower | 273 | /* FIXME: We don't correctly handle backing down to lower |
251 | rates, so 801.11g devices start off at 11M for now. People | 274 | rates, so 801.11g devices start off at 11M for now. People |
252 | can manually change it if they really need to, but 11M is | 275 | can manually change it if they really need to, but 11M is |
@@ -272,7 +295,23 @@ void ieee80211softmac_init_txrates(struct ieee80211softmac_device *mac) | |||
272 | change |= IEEE80211SOFTMAC_TXRATECHG_MGT_MCAST; | 295 | change |= IEEE80211SOFTMAC_TXRATECHG_MGT_MCAST; |
273 | 296 | ||
274 | if (mac->txrates_change) | 297 | if (mac->txrates_change) |
275 | mac->txrates_change(mac->dev, change, &oldrates); | 298 | mac->txrates_change(mac->dev, change); |
299 | |||
300 | change = 0; | ||
301 | |||
302 | bssinfo->supported_rates.count = 0; | ||
303 | memset(bssinfo->supported_rates.rates, 0, | ||
304 | sizeof(bssinfo->supported_rates.rates)); | ||
305 | change |= IEEE80211SOFTMAC_BSSINFOCHG_RATES; | ||
306 | |||
307 | bssinfo->short_preamble = 0; | ||
308 | change |= IEEE80211SOFTMAC_BSSINFOCHG_SHORT_PREAMBLE; | ||
309 | |||
310 | bssinfo->use_protection = 0; | ||
311 | change |= IEEE80211SOFTMAC_BSSINFOCHG_PROTECTION; | ||
312 | |||
313 | if (mac->bssinfo_change) | ||
314 | mac->bssinfo_change(mac->dev, change); | ||
276 | 315 | ||
277 | mac->running = 1; | 316 | mac->running = 1; |
278 | } | 317 | } |
@@ -282,7 +321,7 @@ void ieee80211softmac_start(struct net_device *dev) | |||
282 | struct ieee80211softmac_device *mac = ieee80211_priv(dev); | 321 | struct ieee80211softmac_device *mac = ieee80211_priv(dev); |
283 | 322 | ||
284 | ieee80211softmac_start_check_rates(mac); | 323 | ieee80211softmac_start_check_rates(mac); |
285 | ieee80211softmac_init_txrates(mac); | 324 | ieee80211softmac_init_bss(mac); |
286 | } | 325 | } |
287 | EXPORT_SYMBOL_GPL(ieee80211softmac_start); | 326 | EXPORT_SYMBOL_GPL(ieee80211softmac_start); |
288 | 327 | ||
@@ -335,7 +374,6 @@ u8 ieee80211softmac_lower_rate_delta(struct ieee80211softmac_device *mac, u8 rat | |||
335 | static void ieee80211softmac_add_txrates_badness(struct ieee80211softmac_device *mac, | 374 | static void ieee80211softmac_add_txrates_badness(struct ieee80211softmac_device *mac, |
336 | int amount) | 375 | int amount) |
337 | { | 376 | { |
338 | struct ieee80211softmac_txrates oldrates; | ||
339 | u8 default_rate = mac->txrates.default_rate; | 377 | u8 default_rate = mac->txrates.default_rate; |
340 | u8 default_fallback = mac->txrates.default_fallback; | 378 | u8 default_fallback = mac->txrates.default_fallback; |
341 | u32 changes = 0; | 379 | u32 changes = 0; |
@@ -348,8 +386,6 @@ printk("badness %d\n", mac->txrate_badness); | |||
348 | mac->txrate_badness += amount; | 386 | mac->txrate_badness += amount; |
349 | if (mac->txrate_badness <= -1000) { | 387 | if (mac->txrate_badness <= -1000) { |
350 | /* Very small badness. Try a faster bitrate. */ | 388 | /* Very small badness. Try a faster bitrate. */ |
351 | if (mac->txrates_change) | ||
352 | memcpy(&oldrates, &mac->txrates, sizeof(oldrates)); | ||
353 | default_rate = raise_rate(mac, default_rate); | 389 | default_rate = raise_rate(mac, default_rate); |
354 | changes |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT; | 390 | changes |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT; |
355 | default_fallback = get_fallback_rate(mac, default_rate); | 391 | default_fallback = get_fallback_rate(mac, default_rate); |
@@ -358,8 +394,6 @@ printk("badness %d\n", mac->txrate_badness); | |||
358 | printk("Bitrate raised to %u\n", default_rate); | 394 | printk("Bitrate raised to %u\n", default_rate); |
359 | } else if (mac->txrate_badness >= 10000) { | 395 | } else if (mac->txrate_badness >= 10000) { |
360 | /* Very high badness. Try a slower bitrate. */ | 396 | /* Very high badness. Try a slower bitrate. */ |
361 | if (mac->txrates_change) | ||
362 | memcpy(&oldrates, &mac->txrates, sizeof(oldrates)); | ||
363 | default_rate = lower_rate(mac, default_rate); | 397 | default_rate = lower_rate(mac, default_rate); |
364 | changes |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT; | 398 | changes |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT; |
365 | default_fallback = get_fallback_rate(mac, default_rate); | 399 | default_fallback = get_fallback_rate(mac, default_rate); |
@@ -372,7 +406,7 @@ printk("Bitrate lowered to %u\n", default_rate); | |||
372 | mac->txrates.default_fallback = default_fallback; | 406 | mac->txrates.default_fallback = default_fallback; |
373 | 407 | ||
374 | if (changes && mac->txrates_change) | 408 | if (changes && mac->txrates_change) |
375 | mac->txrates_change(mac->dev, changes, &oldrates); | 409 | mac->txrates_change(mac->dev, changes); |
376 | } | 410 | } |
377 | 411 | ||
378 | void ieee80211softmac_fragment_lost(struct net_device *dev, | 412 | void ieee80211softmac_fragment_lost(struct net_device *dev, |
@@ -416,7 +450,11 @@ ieee80211softmac_create_network(struct ieee80211softmac_device *mac, | |||
416 | memcpy(&softnet->supported_rates.rates[softnet->supported_rates.count], net->rates_ex, net->rates_ex_len); | 450 | memcpy(&softnet->supported_rates.rates[softnet->supported_rates.count], net->rates_ex, net->rates_ex_len); |
417 | softnet->supported_rates.count += net->rates_ex_len; | 451 | softnet->supported_rates.count += net->rates_ex_len; |
418 | sort(softnet->supported_rates.rates, softnet->supported_rates.count, sizeof(softnet->supported_rates.rates[0]), rate_cmp, NULL); | 452 | sort(softnet->supported_rates.rates, softnet->supported_rates.count, sizeof(softnet->supported_rates.rates[0]), rate_cmp, NULL); |
419 | 453 | ||
454 | /* we save the ERP value because it is needed at association time, and | ||
455 | * many AP's do not include an ERP IE in the association response. */ | ||
456 | softnet->erp_value = net->erp_value; | ||
457 | |||
420 | softnet->capabilities = net->capability; | 458 | softnet->capabilities = net->capability; |
421 | return softnet; | 459 | return softnet; |
422 | } | 460 | } |