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.c138
1 files changed, 83 insertions, 55 deletions
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index fb274db77e3c..489b6ad200d4 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -196,7 +196,8 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
196 ieee802_11_parse_elems(elements, skb->len - baselen, &elems); 196 ieee802_11_parse_elems(elements, skb->len - baselen, &elems);
197 197
198 if (elems.ds_params && elems.ds_params_len == 1) 198 if (elems.ds_params && elems.ds_params_len == 1)
199 freq = ieee80211_channel_to_frequency(elems.ds_params[0]); 199 freq = ieee80211_channel_to_frequency(elems.ds_params[0],
200 rx_status->band);
200 else 201 else
201 freq = rx_status->freq; 202 freq = rx_status->freq;
202 203
@@ -211,6 +212,14 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
211 if (bss) 212 if (bss)
212 ieee80211_rx_bss_put(sdata->local, bss); 213 ieee80211_rx_bss_put(sdata->local, bss);
213 214
215 /* If we are on-operating-channel, and this packet is for the
216 * current channel, pass the pkt on up the stack so that
217 * the rest of the stack can make use of it.
218 */
219 if (ieee80211_cfg_on_oper_channel(sdata->local)
220 && (channel == sdata->local->oper_channel))
221 return RX_CONTINUE;
222
214 dev_kfree_skb(skb); 223 dev_kfree_skb(skb);
215 return RX_QUEUED; 224 return RX_QUEUED;
216} 225}
@@ -249,10 +258,12 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
249 return true; 258 return true;
250} 259}
251 260
252static bool __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted, 261static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted,
253 bool was_hw_scan) 262 bool was_hw_scan)
254{ 263{
255 struct ieee80211_local *local = hw_to_local(hw); 264 struct ieee80211_local *local = hw_to_local(hw);
265 bool on_oper_chan;
266 bool enable_beacons = false;
256 267
257 lockdep_assert_held(&local->mtx); 268 lockdep_assert_held(&local->mtx);
258 269
@@ -266,12 +277,12 @@ static bool __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted,
266 aborted = true; 277 aborted = true;
267 278
268 if (WARN_ON(!local->scan_req)) 279 if (WARN_ON(!local->scan_req))
269 return false; 280 return;
270 281
271 if (was_hw_scan && !aborted && ieee80211_prep_hw_scan(local)) { 282 if (was_hw_scan && !aborted && ieee80211_prep_hw_scan(local)) {
272 int rc = drv_hw_scan(local, local->scan_sdata, local->hw_scan_req); 283 int rc = drv_hw_scan(local, local->scan_sdata, local->hw_scan_req);
273 if (rc == 0) 284 if (rc == 0)
274 return false; 285 return;
275 } 286 }
276 287
277 kfree(local->hw_scan_req); 288 kfree(local->hw_scan_req);
@@ -285,24 +296,28 @@ static bool __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted,
285 local->scanning = 0; 296 local->scanning = 0;
286 local->scan_channel = NULL; 297 local->scan_channel = NULL;
287 298
288 return true; 299 on_oper_chan = ieee80211_cfg_on_oper_channel(local);
289}
290 300
291static void __ieee80211_scan_completed_finish(struct ieee80211_hw *hw, 301 if (was_hw_scan || !on_oper_chan)
292 bool was_hw_scan) 302 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
293{ 303 else
294 struct ieee80211_local *local = hw_to_local(hw); 304 /* Set power back to normal operating levels. */
305 ieee80211_hw_config(local, 0);
295 306
296 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
297 if (!was_hw_scan) { 307 if (!was_hw_scan) {
308 bool on_oper_chan2;
298 ieee80211_configure_filter(local); 309 ieee80211_configure_filter(local);
299 drv_sw_scan_complete(local); 310 drv_sw_scan_complete(local);
300 ieee80211_offchannel_return(local, true); 311 on_oper_chan2 = ieee80211_cfg_on_oper_channel(local);
312 /* We should always be on-channel at this point. */
313 WARN_ON(!on_oper_chan2);
314 if (on_oper_chan2 && (on_oper_chan != on_oper_chan2))
315 enable_beacons = true;
316
317 ieee80211_offchannel_return(local, enable_beacons, true);
301 } 318 }
302 319
303 mutex_lock(&local->mtx);
304 ieee80211_recalc_idle(local); 320 ieee80211_recalc_idle(local);
305 mutex_unlock(&local->mtx);
306 321
307 ieee80211_mlme_notify_scan_completed(local); 322 ieee80211_mlme_notify_scan_completed(local);
308 ieee80211_ibss_notify_scan_completed(local); 323 ieee80211_ibss_notify_scan_completed(local);
@@ -340,16 +355,21 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
340 */ 355 */
341 drv_sw_scan_start(local); 356 drv_sw_scan_start(local);
342 357
343 ieee80211_offchannel_stop_beaconing(local);
344
345 local->leave_oper_channel_time = 0; 358 local->leave_oper_channel_time = 0;
346 local->next_scan_state = SCAN_DECISION; 359 local->next_scan_state = SCAN_DECISION;
347 local->scan_channel_idx = 0; 360 local->scan_channel_idx = 0;
348 361
349 drv_flush(local, false); 362 /* We always want to use off-channel PS, even if we
363 * are not really leaving oper-channel. Don't
364 * tell the AP though, as long as we are on-channel.
365 */
366 ieee80211_offchannel_enable_all_ps(local, false);
350 367
351 ieee80211_configure_filter(local); 368 ieee80211_configure_filter(local);
352 369
370 /* We need to set power level at maximum rate for scanning. */
371 ieee80211_hw_config(local, 0);
372
353 ieee80211_queue_delayed_work(&local->hw, 373 ieee80211_queue_delayed_work(&local->hw,
354 &local->scan_work, 374 &local->scan_work,
355 IEEE80211_CHANNEL_TIME); 375 IEEE80211_CHANNEL_TIME);
@@ -486,7 +506,20 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local,
486 } 506 }
487 mutex_unlock(&local->iflist_mtx); 507 mutex_unlock(&local->iflist_mtx);
488 508
489 if (local->scan_channel) { 509 next_chan = local->scan_req->channels[local->scan_channel_idx];
510
511 if (ieee80211_cfg_on_oper_channel(local)) {
512 /* We're currently on operating channel. */
513 if (next_chan == local->oper_channel)
514 /* We don't need to move off of operating channel. */
515 local->next_scan_state = SCAN_SET_CHANNEL;
516 else
517 /*
518 * We do need to leave operating channel, as next
519 * scan is somewhere else.
520 */
521 local->next_scan_state = SCAN_LEAVE_OPER_CHANNEL;
522 } else {
490 /* 523 /*
491 * we're currently scanning a different channel, let's 524 * we're currently scanning a different channel, let's
492 * see if we can scan another channel without interfering 525 * see if we can scan another channel without interfering
@@ -502,7 +535,6 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local,
502 * 535 *
503 * Otherwise switch back to the operating channel. 536 * Otherwise switch back to the operating channel.
504 */ 537 */
505 next_chan = local->scan_req->channels[local->scan_channel_idx];
506 538
507 bad_latency = time_after(jiffies + 539 bad_latency = time_after(jiffies +
508 ieee80211_scan_get_channel_time(next_chan), 540 ieee80211_scan_get_channel_time(next_chan),
@@ -520,12 +552,6 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local,
520 local->next_scan_state = SCAN_ENTER_OPER_CHANNEL; 552 local->next_scan_state = SCAN_ENTER_OPER_CHANNEL;
521 else 553 else
522 local->next_scan_state = SCAN_SET_CHANNEL; 554 local->next_scan_state = SCAN_SET_CHANNEL;
523 } else {
524 /*
525 * we're on the operating channel currently, let's
526 * leave that channel now to scan another one
527 */
528 local->next_scan_state = SCAN_LEAVE_OPER_CHANNEL;
529 } 555 }
530 556
531 *next_delay = 0; 557 *next_delay = 0;
@@ -534,9 +560,10 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local,
534static void ieee80211_scan_state_leave_oper_channel(struct ieee80211_local *local, 560static void ieee80211_scan_state_leave_oper_channel(struct ieee80211_local *local,
535 unsigned long *next_delay) 561 unsigned long *next_delay)
536{ 562{
537 ieee80211_offchannel_stop_station(local); 563 /* PS will already be in off-channel mode,
538 564 * we do that once at the beginning of scanning.
539 __set_bit(SCAN_OFF_CHANNEL, &local->scanning); 565 */
566 ieee80211_offchannel_stop_vifs(local, false);
540 567
541 /* 568 /*
542 * What if the nullfunc frames didn't arrive? 569 * What if the nullfunc frames didn't arrive?
@@ -559,15 +586,15 @@ static void ieee80211_scan_state_enter_oper_channel(struct ieee80211_local *loca
559{ 586{
560 /* switch back to the operating channel */ 587 /* switch back to the operating channel */
561 local->scan_channel = NULL; 588 local->scan_channel = NULL;
562 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); 589 if (!ieee80211_cfg_on_oper_channel(local))
590 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
563 591
564 /* 592 /*
565 * Only re-enable station mode interface now; beaconing will be 593 * Re-enable vifs and beaconing. Leave PS
566 * re-enabled once the full scan has been completed. 594 * in off-channel state..will put that back
595 * on-channel at the end of scanning.
567 */ 596 */
568 ieee80211_offchannel_return(local, false); 597 ieee80211_offchannel_return(local, true, false);
569
570 __clear_bit(SCAN_OFF_CHANNEL, &local->scanning);
571 598
572 *next_delay = HZ / 5; 599 *next_delay = HZ / 5;
573 local->next_scan_state = SCAN_DECISION; 600 local->next_scan_state = SCAN_DECISION;
@@ -583,8 +610,11 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local,
583 chan = local->scan_req->channels[local->scan_channel_idx]; 610 chan = local->scan_req->channels[local->scan_channel_idx];
584 611
585 local->scan_channel = chan; 612 local->scan_channel = chan;
586 if (ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL)) 613
587 skip = 1; 614 /* Only call hw-config if we really need to change channels. */
615 if (chan != local->hw.conf.channel)
616 if (ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL))
617 skip = 1;
588 618
589 /* advance state machine to next channel/band */ 619 /* advance state machine to next channel/band */
590 local->scan_channel_idx++; 620 local->scan_channel_idx++;
@@ -642,12 +672,14 @@ void ieee80211_scan_work(struct work_struct *work)
642{ 672{
643 struct ieee80211_local *local = 673 struct ieee80211_local *local =
644 container_of(work, struct ieee80211_local, scan_work.work); 674 container_of(work, struct ieee80211_local, scan_work.work);
645 struct ieee80211_sub_if_data *sdata = local->scan_sdata; 675 struct ieee80211_sub_if_data *sdata;
646 unsigned long next_delay = 0; 676 unsigned long next_delay = 0;
647 bool aborted, hw_scan, finish; 677 bool aborted, hw_scan;
648 678
649 mutex_lock(&local->mtx); 679 mutex_lock(&local->mtx);
650 680
681 sdata = local->scan_sdata;
682
651 if (test_and_clear_bit(SCAN_COMPLETED, &local->scanning)) { 683 if (test_and_clear_bit(SCAN_COMPLETED, &local->scanning)) {
652 aborted = test_and_clear_bit(SCAN_ABORTED, &local->scanning); 684 aborted = test_and_clear_bit(SCAN_ABORTED, &local->scanning);
653 goto out_complete; 685 goto out_complete;
@@ -711,17 +743,11 @@ void ieee80211_scan_work(struct work_struct *work)
711 } while (next_delay == 0); 743 } while (next_delay == 0);
712 744
713 ieee80211_queue_delayed_work(&local->hw, &local->scan_work, next_delay); 745 ieee80211_queue_delayed_work(&local->hw, &local->scan_work, next_delay);
714 mutex_unlock(&local->mtx); 746 goto out;
715 return;
716 747
717out_complete: 748out_complete:
718 hw_scan = test_bit(SCAN_HW_SCANNING, &local->scanning); 749 hw_scan = test_bit(SCAN_HW_SCANNING, &local->scanning);
719 finish = __ieee80211_scan_completed(&local->hw, aborted, hw_scan); 750 __ieee80211_scan_completed(&local->hw, aborted, hw_scan);
720 mutex_unlock(&local->mtx);
721 if (finish)
722 __ieee80211_scan_completed_finish(&local->hw, hw_scan);
723 return;
724
725out: 751out:
726 mutex_unlock(&local->mtx); 752 mutex_unlock(&local->mtx);
727} 753}
@@ -791,7 +817,6 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
791void ieee80211_scan_cancel(struct ieee80211_local *local) 817void ieee80211_scan_cancel(struct ieee80211_local *local)
792{ 818{
793 bool abortscan; 819 bool abortscan;
794 bool finish = false;
795 820
796 /* 821 /*
797 * We are only canceling software scan, or deferred scan that was not 822 * We are only canceling software scan, or deferred scan that was not
@@ -811,14 +836,17 @@ void ieee80211_scan_cancel(struct ieee80211_local *local)
811 836
812 mutex_lock(&local->mtx); 837 mutex_lock(&local->mtx);
813 abortscan = local->scan_req && !test_bit(SCAN_HW_SCANNING, &local->scanning); 838 abortscan = local->scan_req && !test_bit(SCAN_HW_SCANNING, &local->scanning);
814 if (abortscan)
815 finish = __ieee80211_scan_completed(&local->hw, true, false);
816 mutex_unlock(&local->mtx);
817
818 if (abortscan) { 839 if (abortscan) {
819 /* The scan is canceled, but stop work from being pending */ 840 /*
820 cancel_delayed_work_sync(&local->scan_work); 841 * The scan is canceled, but stop work from being pending.
842 *
843 * If the work is currently running, it must be blocked on
844 * the mutex, but we'll set scan_sdata = NULL and it'll
845 * simply exit once it acquires the mutex.
846 */
847 cancel_delayed_work(&local->scan_work);
848 /* and clean up */
849 __ieee80211_scan_completed(&local->hw, true, false);
821 } 850 }
822 if (finish) 851 mutex_unlock(&local->mtx);
823 __ieee80211_scan_completed_finish(&local->hw, false);
824} 852}