aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/scan.c')
-rw-r--r--net/mac80211/scan.c230
1 files changed, 58 insertions, 172 deletions
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index f934c9620b73..9afe2f9885dc 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -12,7 +12,6 @@
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13 */ 13 */
14 14
15#include <linux/wireless.h>
16#include <linux/if_arp.h> 15#include <linux/if_arp.h>
17#include <linux/rtnetlink.h> 16#include <linux/rtnetlink.h>
18#include <net/mac80211.h> 17#include <net/mac80211.h>
@@ -29,16 +28,19 @@ struct ieee80211_bss *
29ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq, 28ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq,
30 u8 *ssid, u8 ssid_len) 29 u8 *ssid, u8 ssid_len)
31{ 30{
32 return (void *)cfg80211_get_bss(local->hw.wiphy, 31 struct cfg80211_bss *cbss;
33 ieee80211_get_channel(local->hw.wiphy, 32
34 freq), 33 cbss = cfg80211_get_bss(local->hw.wiphy,
35 bssid, ssid, ssid_len, 34 ieee80211_get_channel(local->hw.wiphy, freq),
36 0, 0); 35 bssid, ssid, ssid_len, 0, 0);
36 if (!cbss)
37 return NULL;
38 return (void *)cbss->priv;
37} 39}
38 40
39static void ieee80211_rx_bss_free(struct cfg80211_bss *cbss) 41static void ieee80211_rx_bss_free(struct cfg80211_bss *cbss)
40{ 42{
41 struct ieee80211_bss *bss = (void *)cbss; 43 struct ieee80211_bss *bss = (void *)cbss->priv;
42 44
43 kfree(bss_mesh_id(bss)); 45 kfree(bss_mesh_id(bss));
44 kfree(bss_mesh_cfg(bss)); 46 kfree(bss_mesh_cfg(bss));
@@ -47,7 +49,26 @@ static void ieee80211_rx_bss_free(struct cfg80211_bss *cbss)
47void ieee80211_rx_bss_put(struct ieee80211_local *local, 49void ieee80211_rx_bss_put(struct ieee80211_local *local,
48 struct ieee80211_bss *bss) 50 struct ieee80211_bss *bss)
49{ 51{
50 cfg80211_put_bss((struct cfg80211_bss *)bss); 52 if (!bss)
53 return;
54 cfg80211_put_bss(container_of((void *)bss, struct cfg80211_bss, priv));
55}
56
57static bool is_uapsd_supported(struct ieee802_11_elems *elems)
58{
59 u8 qos_info;
60
61 if (elems->wmm_info && elems->wmm_info_len == 7
62 && elems->wmm_info[5] == 1)
63 qos_info = elems->wmm_info[6];
64 else if (elems->wmm_param && elems->wmm_param_len == 24
65 && elems->wmm_param[5] == 1)
66 qos_info = elems->wmm_param[6];
67 else
68 /* no valid wmm information or parameter element found */
69 return false;
70
71 return qos_info & IEEE80211_WMM_IE_AP_QOSINFO_UAPSD;
51} 72}
52 73
53struct ieee80211_bss * 74struct ieee80211_bss *
@@ -59,6 +80,7 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
59 struct ieee80211_channel *channel, 80 struct ieee80211_channel *channel,
60 bool beacon) 81 bool beacon)
61{ 82{
83 struct cfg80211_bss *cbss;
62 struct ieee80211_bss *bss; 84 struct ieee80211_bss *bss;
63 int clen; 85 int clen;
64 s32 signal = 0; 86 s32 signal = 0;
@@ -68,13 +90,14 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
68 else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) 90 else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)
69 signal = (rx_status->signal * 100) / local->hw.max_signal; 91 signal = (rx_status->signal * 100) / local->hw.max_signal;
70 92
71 bss = (void *)cfg80211_inform_bss_frame(local->hw.wiphy, channel, 93 cbss = cfg80211_inform_bss_frame(local->hw.wiphy, channel,
72 mgmt, len, signal, GFP_ATOMIC); 94 mgmt, len, signal, GFP_ATOMIC);
73 95
74 if (!bss) 96 if (!cbss)
75 return NULL; 97 return NULL;
76 98
77 bss->cbss.free_priv = ieee80211_rx_bss_free; 99 cbss->free_priv = ieee80211_rx_bss_free;
100 bss = (void *)cbss->priv;
78 101
79 /* save the ERP value so that it is available at association time */ 102 /* save the ERP value so that it is available at association time */
80 if (elems->erp_info && elems->erp_info_len >= 1) { 103 if (elems->erp_info && elems->erp_info_len >= 1) {
@@ -111,6 +134,7 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
111 } 134 }
112 135
113 bss->wmm_used = elems->wmm_param || elems->wmm_info; 136 bss->wmm_used = elems->wmm_param || elems->wmm_info;
137 bss->uapsd_supported = is_uapsd_supported(elems);
114 138
115 if (!beacon) 139 if (!beacon)
116 bss->last_probe_resp = jiffies; 140 bss->last_probe_resp = jiffies;
@@ -147,7 +171,7 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
147 presp = ieee80211_is_probe_resp(fc); 171 presp = ieee80211_is_probe_resp(fc);
148 if (presp) { 172 if (presp) {
149 /* ignore ProbeResp to foreign address */ 173 /* ignore ProbeResp to foreign address */
150 if (memcmp(mgmt->da, sdata->dev->dev_addr, ETH_ALEN)) 174 if (memcmp(mgmt->da, sdata->vif.addr, ETH_ALEN))
151 return RX_DROP_MONITOR; 175 return RX_DROP_MONITOR;
152 176
153 presp = true; 177 presp = true;
@@ -220,82 +244,9 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
220 return true; 244 return true;
221} 245}
222 246
223/*
224 * inform AP that we will go to sleep so that it will buffer the frames
225 * while we scan
226 */
227static void ieee80211_scan_ps_enable(struct ieee80211_sub_if_data *sdata)
228{
229 struct ieee80211_local *local = sdata->local;
230
231 local->scan_ps_enabled = false;
232
233 /* FIXME: what to do when local->pspolling is true? */
234
235 del_timer_sync(&local->dynamic_ps_timer);
236 cancel_work_sync(&local->dynamic_ps_enable_work);
237
238 if (local->hw.conf.flags & IEEE80211_CONF_PS) {
239 local->scan_ps_enabled = true;
240 local->hw.conf.flags &= ~IEEE80211_CONF_PS;
241 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
242 }
243
244 if (!(local->scan_ps_enabled) ||
245 !(local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK))
246 /*
247 * If power save was enabled, no need to send a nullfunc
248 * frame because AP knows that we are sleeping. But if the
249 * hardware is creating the nullfunc frame for power save
250 * status (ie. IEEE80211_HW_PS_NULLFUNC_STACK is not
251 * enabled) and power save was enabled, the firmware just
252 * sent a null frame with power save disabled. So we need
253 * to send a new nullfunc frame to inform the AP that we
254 * are again sleeping.
255 */
256 ieee80211_send_nullfunc(local, sdata, 1);
257}
258
259/* inform AP that we are awake again, unless power save is enabled */
260static void ieee80211_scan_ps_disable(struct ieee80211_sub_if_data *sdata)
261{
262 struct ieee80211_local *local = sdata->local;
263
264 if (!local->ps_sdata)
265 ieee80211_send_nullfunc(local, sdata, 0);
266 else if (local->scan_ps_enabled) {
267 /*
268 * In !IEEE80211_HW_PS_NULLFUNC_STACK case the hardware
269 * will send a nullfunc frame with the powersave bit set
270 * even though the AP already knows that we are sleeping.
271 * This could be avoided by sending a null frame with power
272 * save bit disabled before enabling the power save, but
273 * this doesn't gain anything.
274 *
275 * When IEEE80211_HW_PS_NULLFUNC_STACK is enabled, no need
276 * to send a nullfunc frame because AP already knows that
277 * we are sleeping, let's just enable power save mode in
278 * hardware.
279 */
280 local->hw.conf.flags |= IEEE80211_CONF_PS;
281 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
282 } else if (local->hw.conf.dynamic_ps_timeout > 0) {
283 /*
284 * If IEEE80211_CONF_PS was not set and the dynamic_ps_timer
285 * had been running before leaving the operating channel,
286 * restart the timer now and send a nullfunc frame to inform
287 * the AP that we are awake.
288 */
289 ieee80211_send_nullfunc(local, sdata, 0);
290 mod_timer(&local->dynamic_ps_timer, jiffies +
291 msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));
292 }
293}
294
295void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) 247void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
296{ 248{
297 struct ieee80211_local *local = hw_to_local(hw); 249 struct ieee80211_local *local = hw_to_local(hw);
298 struct ieee80211_sub_if_data *sdata;
299 bool was_hw_scan; 250 bool was_hw_scan;
300 251
301 mutex_lock(&local->scan_mtx); 252 mutex_lock(&local->scan_mtx);
@@ -344,41 +295,19 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
344 295
345 drv_sw_scan_complete(local); 296 drv_sw_scan_complete(local);
346 297
347 mutex_lock(&local->iflist_mtx); 298 ieee80211_offchannel_return(local, true);
348 list_for_each_entry(sdata, &local->interfaces, list) {
349 if (!netif_running(sdata->dev))
350 continue;
351
352 /* Tell AP we're back */
353 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
354 if (sdata->u.mgd.associated) {
355 ieee80211_scan_ps_disable(sdata);
356 netif_tx_wake_all_queues(sdata->dev);
357 }
358 } else
359 netif_tx_wake_all_queues(sdata->dev);
360
361 /* re-enable beaconing */
362 if (sdata->vif.type == NL80211_IFTYPE_AP ||
363 sdata->vif.type == NL80211_IFTYPE_ADHOC ||
364 sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
365 ieee80211_bss_info_change_notify(
366 sdata, BSS_CHANGED_BEACON_ENABLED);
367 }
368 mutex_unlock(&local->iflist_mtx);
369 299
370 done: 300 done:
371 ieee80211_recalc_idle(local); 301 ieee80211_recalc_idle(local);
372 ieee80211_mlme_notify_scan_completed(local); 302 ieee80211_mlme_notify_scan_completed(local);
373 ieee80211_ibss_notify_scan_completed(local); 303 ieee80211_ibss_notify_scan_completed(local);
374 ieee80211_mesh_notify_scan_completed(local); 304 ieee80211_mesh_notify_scan_completed(local);
305 ieee80211_queue_work(&local->hw, &local->work_work);
375} 306}
376EXPORT_SYMBOL(ieee80211_scan_completed); 307EXPORT_SYMBOL(ieee80211_scan_completed);
377 308
378static int ieee80211_start_sw_scan(struct ieee80211_local *local) 309static int ieee80211_start_sw_scan(struct ieee80211_local *local)
379{ 310{
380 struct ieee80211_sub_if_data *sdata;
381
382 /* 311 /*
383 * Hardware/driver doesn't support hw_scan, so use software 312 * Hardware/driver doesn't support hw_scan, so use software
384 * scanning instead. First send a nullfunc frame with power save 313 * scanning instead. First send a nullfunc frame with power save
@@ -394,33 +323,15 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
394 */ 323 */
395 drv_sw_scan_start(local); 324 drv_sw_scan_start(local);
396 325
397 mutex_lock(&local->iflist_mtx); 326 ieee80211_offchannel_stop_beaconing(local);
398 list_for_each_entry(sdata, &local->interfaces, list) {
399 if (!netif_running(sdata->dev))
400 continue;
401
402 /* disable beaconing */
403 if (sdata->vif.type == NL80211_IFTYPE_AP ||
404 sdata->vif.type == NL80211_IFTYPE_ADHOC ||
405 sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
406 ieee80211_bss_info_change_notify(
407 sdata, BSS_CHANGED_BEACON_ENABLED);
408
409 /*
410 * only handle non-STA interfaces here, STA interfaces
411 * are handled in the scan state machine
412 */
413 if (sdata->vif.type != NL80211_IFTYPE_STATION)
414 netif_tx_stop_all_queues(sdata->dev);
415 }
416 mutex_unlock(&local->iflist_mtx);
417 327
418 local->next_scan_state = SCAN_DECISION; 328 local->next_scan_state = SCAN_DECISION;
419 local->scan_channel_idx = 0; 329 local->scan_channel_idx = 0;
420 330
331 drv_flush(local, false);
332
421 ieee80211_configure_filter(local); 333 ieee80211_configure_filter(local);
422 334
423 /* TODO: start scan as soon as all nullfunc frames are ACKed */
424 ieee80211_queue_delayed_work(&local->hw, 335 ieee80211_queue_delayed_work(&local->hw,
425 &local->scan_work, 336 &local->scan_work,
426 IEEE80211_CHANNEL_TIME); 337 IEEE80211_CHANNEL_TIME);
@@ -433,7 +344,6 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
433 struct cfg80211_scan_request *req) 344 struct cfg80211_scan_request *req)
434{ 345{
435 struct ieee80211_local *local = sdata->local; 346 struct ieee80211_local *local = sdata->local;
436 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
437 int rc; 347 int rc;
438 348
439 if (local->scan_req) 349 if (local->scan_req)
@@ -463,11 +373,8 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
463 local->scan_req = req; 373 local->scan_req = req;
464 local->scan_sdata = sdata; 374 local->scan_sdata = sdata;
465 375
466 if (req != local->int_scan_req && 376 if (!list_empty(&local->work_list)) {
467 sdata->vif.type == NL80211_IFTYPE_STATION && 377 /* wait for the work to finish/time out */
468 !list_empty(&ifmgd->work_list)) {
469 /* actually wait for the work it's doing to finish/time out */
470 set_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request);
471 return 0; 378 return 0;
472 } 379 }
473 380
@@ -526,7 +433,7 @@ static int ieee80211_scan_state_decision(struct ieee80211_local *local,
526 /* check if at least one STA interface is associated */ 433 /* check if at least one STA interface is associated */
527 mutex_lock(&local->iflist_mtx); 434 mutex_lock(&local->iflist_mtx);
528 list_for_each_entry(sdata, &local->interfaces, list) { 435 list_for_each_entry(sdata, &local->interfaces, list) {
529 if (!netif_running(sdata->dev)) 436 if (!ieee80211_sdata_running(sdata))
530 continue; 437 continue;
531 438
532 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 439 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
@@ -564,56 +471,35 @@ static int ieee80211_scan_state_decision(struct ieee80211_local *local,
564static void ieee80211_scan_state_leave_oper_channel(struct ieee80211_local *local, 471static void ieee80211_scan_state_leave_oper_channel(struct ieee80211_local *local,
565 unsigned long *next_delay) 472 unsigned long *next_delay)
566{ 473{
567 struct ieee80211_sub_if_data *sdata; 474 ieee80211_offchannel_stop_station(local);
475
476 __set_bit(SCAN_OFF_CHANNEL, &local->scanning);
568 477
569 /* 478 /*
570 * notify the AP about us leaving the channel and stop all STA interfaces 479 * What if the nullfunc frames didn't arrive?
571 */ 480 */
572 mutex_lock(&local->iflist_mtx); 481 drv_flush(local, false);
573 list_for_each_entry(sdata, &local->interfaces, list) { 482 if (local->ops->flush)
574 if (!netif_running(sdata->dev)) 483 *next_delay = 0;
575 continue; 484 else
576 485 *next_delay = HZ / 10;
577 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
578 netif_tx_stop_all_queues(sdata->dev);
579 if (sdata->u.mgd.associated)
580 ieee80211_scan_ps_enable(sdata);
581 }
582 }
583 mutex_unlock(&local->iflist_mtx);
584
585 __set_bit(SCAN_OFF_CHANNEL, &local->scanning);
586 486
587 /* advance to the next channel to be scanned */ 487 /* advance to the next channel to be scanned */
588 *next_delay = HZ / 10;
589 local->next_scan_state = SCAN_SET_CHANNEL; 488 local->next_scan_state = SCAN_SET_CHANNEL;
590} 489}
591 490
592static void ieee80211_scan_state_enter_oper_channel(struct ieee80211_local *local, 491static void ieee80211_scan_state_enter_oper_channel(struct ieee80211_local *local,
593 unsigned long *next_delay) 492 unsigned long *next_delay)
594{ 493{
595 struct ieee80211_sub_if_data *sdata = local->scan_sdata;
596
597 /* switch back to the operating channel */ 494 /* switch back to the operating channel */
598 local->scan_channel = NULL; 495 local->scan_channel = NULL;
599 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); 496 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
600 497
601 /* 498 /*
602 * notify the AP about us being back and restart all STA interfaces 499 * Only re-enable station mode interface now; beaconing will be
500 * re-enabled once the full scan has been completed.
603 */ 501 */
604 mutex_lock(&local->iflist_mtx); 502 ieee80211_offchannel_return(local, false);
605 list_for_each_entry(sdata, &local->interfaces, list) {
606 if (!netif_running(sdata->dev))
607 continue;
608
609 /* Tell AP we're back */
610 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
611 if (sdata->u.mgd.associated)
612 ieee80211_scan_ps_disable(sdata);
613 netif_tx_wake_all_queues(sdata->dev);
614 }
615 }
616 mutex_unlock(&local->iflist_mtx);
617 503
618 __clear_bit(SCAN_OFF_CHANNEL, &local->scanning); 504 __clear_bit(SCAN_OFF_CHANNEL, &local->scanning);
619 505
@@ -727,7 +613,7 @@ void ieee80211_scan_work(struct work_struct *work)
727 /* 613 /*
728 * Avoid re-scheduling when the sdata is going away. 614 * Avoid re-scheduling when the sdata is going away.
729 */ 615 */
730 if (!netif_running(sdata->dev)) { 616 if (!ieee80211_sdata_running(sdata)) {
731 ieee80211_scan_completed(&local->hw, true); 617 ieee80211_scan_completed(&local->hw, true);
732 return; 618 return;
733 } 619 }