aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDaniel Drake <dsd@gentoo.org>2006-07-18 16:33:27 -0400
committerJohn W. Linville <linville@tuxdriver.com>2006-07-27 16:17:28 -0400
commit5acd0c4153be25269d7cb9a4b09fd6db571c5cc1 (patch)
treeb970a1b9469617597ab1594ca269bc81b020a881 /net
parentd8e2be90d301a0381e9b2528fe2835cf2992bca3 (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')
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_assoc.c21
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_io.c14
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_module.c78
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_priv.h8
4 files changed, 96 insertions, 25 deletions
diff --git a/net/ieee80211/softmac/ieee80211softmac_assoc.c b/net/ieee80211/softmac/ieee80211softmac_assoc.c
index 44215ce64d4e..589f6d2c548a 100644
--- a/net/ieee80211/softmac/ieee80211softmac_assoc.c
+++ b/net/ieee80211/softmac/ieee80211softmac_assoc.c
@@ -96,7 +96,7 @@ ieee80211softmac_disassoc(struct ieee80211softmac_device *mac)
96 mac->associated = 0; 96 mac->associated = 0;
97 mac->associnfo.bssvalid = 0; 97 mac->associnfo.bssvalid = 0;
98 mac->associnfo.associating = 0; 98 mac->associnfo.associating = 0;
99 ieee80211softmac_init_txrates(mac); 99 ieee80211softmac_init_bss(mac);
100 ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_DISASSOCIATED, NULL); 100 ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_DISASSOCIATED, NULL);
101 spin_unlock_irqrestore(&mac->lock, flags); 101 spin_unlock_irqrestore(&mac->lock, flags);
102} 102}
@@ -334,11 +334,19 @@ ieee80211softmac_associated(struct ieee80211softmac_device *mac,
334 struct ieee80211_assoc_response * resp, 334 struct ieee80211_assoc_response * resp,
335 struct ieee80211softmac_network *net) 335 struct ieee80211softmac_network *net)
336{ 336{
337 u16 cap = le16_to_cpu(resp->capability);
338 u8 erp_value = net->erp_value;
339
337 mac->associnfo.associating = 0; 340 mac->associnfo.associating = 0;
338 mac->associnfo.supported_rates = net->supported_rates; 341 mac->bssinfo.supported_rates = net->supported_rates;
339 ieee80211softmac_recalc_txrates(mac); 342 ieee80211softmac_recalc_txrates(mac);
340 343
341 mac->associated = 1; 344 mac->associated = 1;
345
346 mac->associnfo.short_preamble_available =
347 (cap & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0;
348 ieee80211softmac_process_erp(mac, erp_value);
349
342 if (mac->set_bssid_filter) 350 if (mac->set_bssid_filter)
343 mac->set_bssid_filter(mac->dev, net->bssid); 351 mac->set_bssid_filter(mac->dev, net->bssid);
344 memcpy(mac->ieee->bssid, net->bssid, ETH_ALEN); 352 memcpy(mac->ieee->bssid, net->bssid, ETH_ALEN);
@@ -351,9 +359,9 @@ ieee80211softmac_associated(struct ieee80211softmac_device *mac,
351int 359int
352ieee80211softmac_handle_assoc_response(struct net_device * dev, 360ieee80211softmac_handle_assoc_response(struct net_device * dev,
353 struct ieee80211_assoc_response * resp, 361 struct ieee80211_assoc_response * resp,
354 struct ieee80211_network * _ieee80211_network_do_not_use) 362 struct ieee80211_network * _ieee80211_network)
355{ 363{
356 /* NOTE: the network parameter has to be ignored by 364 /* NOTE: the network parameter has to be mostly ignored by
357 * this code because it is the ieee80211's pointer 365 * this code because it is the ieee80211's pointer
358 * to the struct, not ours (we made a copy) 366 * to the struct, not ours (we made a copy)
359 */ 367 */
@@ -385,6 +393,11 @@ ieee80211softmac_handle_assoc_response(struct net_device * dev,
385 /* now that we know it was for us, we can cancel the timeout */ 393 /* now that we know it was for us, we can cancel the timeout */
386 cancel_delayed_work(&mac->associnfo.timeout); 394 cancel_delayed_work(&mac->associnfo.timeout);
387 395
396 /* if the association response included an ERP IE, update our saved
397 * copy */
398 if (_ieee80211_network->flags & NETWORK_HAS_ERP_VALUE)
399 network->erp_value = _ieee80211_network->erp_value;
400
388 switch (status) { 401 switch (status) {
389 case 0: 402 case 0:
390 dprintk(KERN_INFO PFX "associated!\n"); 403 dprintk(KERN_INFO PFX "associated!\n");
diff --git a/net/ieee80211/softmac/ieee80211softmac_io.c b/net/ieee80211/softmac/ieee80211softmac_io.c
index 6ae5a1dc7956..82bfddbf33a2 100644
--- a/net/ieee80211/softmac/ieee80211softmac_io.c
+++ b/net/ieee80211/softmac/ieee80211softmac_io.c
@@ -467,3 +467,17 @@ ieee80211softmac_send_mgt_frame(struct ieee80211softmac_device *mac,
467 kfree(pkt); 467 kfree(pkt);
468 return 0; 468 return 0;
469} 469}
470
471/* Beacon handling */
472int ieee80211softmac_handle_beacon(struct net_device *dev,
473 struct ieee80211_beacon *beacon,
474 struct ieee80211_network *network)
475{
476 struct ieee80211softmac_device *mac = ieee80211_priv(dev);
477
478 if (mac->associated && memcmp(network->bssid, mac->associnfo.bssid, ETH_ALEN) == 0)
479 ieee80211softmac_process_erp(mac, network->erp_value);
480
481 return 0;
482}
483
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
213void 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
212void ieee80211softmac_recalc_txrates(struct ieee80211softmac_device *mac) 241void 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
235void ieee80211softmac_init_txrates(struct ieee80211softmac_device *mac) 260void 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}
287EXPORT_SYMBOL_GPL(ieee80211softmac_start); 326EXPORT_SYMBOL_GPL(ieee80211softmac_start);
288 327
@@ -335,7 +374,6 @@ u8 ieee80211softmac_lower_rate_delta(struct ieee80211softmac_device *mac, u8 rat
335static void ieee80211softmac_add_txrates_badness(struct ieee80211softmac_device *mac, 374static 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);
358printk("Bitrate raised to %u\n", default_rate); 394printk("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
378void ieee80211softmac_fragment_lost(struct net_device *dev, 412void 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}
diff --git a/net/ieee80211/softmac/ieee80211softmac_priv.h b/net/ieee80211/softmac/ieee80211softmac_priv.h
index fa1f8e3acfc0..0642e090b8a7 100644
--- a/net/ieee80211/softmac/ieee80211softmac_priv.h
+++ b/net/ieee80211/softmac/ieee80211softmac_priv.h
@@ -116,9 +116,11 @@ ieee80211softmac_get_network_by_essid(struct ieee80211softmac_device *mac,
116 struct ieee80211softmac_essid *essid); 116 struct ieee80211softmac_essid *essid);
117 117
118/* Rates related */ 118/* Rates related */
119void ieee80211softmac_process_erp(struct ieee80211softmac_device *mac,
120 u8 erp_value);
119int ieee80211softmac_ratesinfo_rate_supported(struct ieee80211softmac_ratesinfo *ri, u8 rate); 121int ieee80211softmac_ratesinfo_rate_supported(struct ieee80211softmac_ratesinfo *ri, u8 rate);
120u8 ieee80211softmac_lower_rate_delta(struct ieee80211softmac_device *mac, u8 rate, int delta); 122u8 ieee80211softmac_lower_rate_delta(struct ieee80211softmac_device *mac, u8 rate, int delta);
121void ieee80211softmac_init_txrates(struct ieee80211softmac_device *mac); 123void ieee80211softmac_init_bss(struct ieee80211softmac_device *mac);
122void ieee80211softmac_recalc_txrates(struct ieee80211softmac_device *mac); 124void ieee80211softmac_recalc_txrates(struct ieee80211softmac_device *mac);
123static inline u8 lower_rate(struct ieee80211softmac_device *mac, u8 rate) { 125static inline u8 lower_rate(struct ieee80211softmac_device *mac, u8 rate) {
124 return ieee80211softmac_lower_rate_delta(mac, rate, 1); 126 return ieee80211softmac_lower_rate_delta(mac, rate, 1);
@@ -133,6 +135,9 @@ static inline u8 get_fallback_rate(struct ieee80211softmac_device *mac, u8 rate)
133/*** prototypes from _io.c */ 135/*** prototypes from _io.c */
134int ieee80211softmac_send_mgt_frame(struct ieee80211softmac_device *mac, 136int ieee80211softmac_send_mgt_frame(struct ieee80211softmac_device *mac,
135 void* ptrarg, u32 type, u32 arg); 137 void* ptrarg, u32 type, u32 arg);
138int ieee80211softmac_handle_beacon(struct net_device *dev,
139 struct ieee80211_beacon *beacon,
140 struct ieee80211_network *network);
136 141
137/*** prototypes from _auth.c */ 142/*** prototypes from _auth.c */
138/* do these have to go into the public header? */ 143/* do these have to go into the public header? */
@@ -189,6 +194,7 @@ struct ieee80211softmac_network {
189 authenticated:1, 194 authenticated:1,
190 auth_desynced_once:1; 195 auth_desynced_once:1;
191 196
197 u8 erp_value; /* Saved ERP value */
192 u16 capabilities; /* Capabilities bitfield */ 198 u16 capabilities; /* Capabilities bitfield */
193 u8 challenge_len; /* Auth Challenge length */ 199 u8 challenge_len; /* Auth Challenge length */
194 char *challenge; /* Challenge Text */ 200 char *challenge; /* Challenge Text */