diff options
Diffstat (limited to 'net/mac80211/scan.c')
-rw-r--r-- | net/mac80211/scan.c | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index c4cdbde24fd3..13d23299e696 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -336,6 +336,10 @@ EXPORT_SYMBOL(ieee80211_scan_completed); | |||
336 | 336 | ||
337 | static int ieee80211_start_sw_scan(struct ieee80211_local *local) | 337 | static int ieee80211_start_sw_scan(struct ieee80211_local *local) |
338 | { | 338 | { |
339 | /* Software scan is not supported in multi-channel cases */ | ||
340 | if (local->use_chanctx) | ||
341 | return -EOPNOTSUPP; | ||
342 | |||
339 | /* | 343 | /* |
340 | * Hardware/driver doesn't support hw_scan, so use software | 344 | * Hardware/driver doesn't support hw_scan, so use software |
341 | * scanning instead. First send a nullfunc frame with power save | 345 | * scanning instead. First send a nullfunc frame with power save |
@@ -417,7 +421,7 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local, | |||
417 | local->scan_req->ie, local->scan_req->ie_len, | 421 | local->scan_req->ie, local->scan_req->ie_len, |
418 | local->scan_req->rates[band], false, | 422 | local->scan_req->rates[band], false, |
419 | local->scan_req->no_cck, | 423 | local->scan_req->no_cck, |
420 | local->hw.conf.channel); | 424 | local->hw.conf.channel, true); |
421 | 425 | ||
422 | /* | 426 | /* |
423 | * After sending probe requests, wait for probe responses | 427 | * After sending probe requests, wait for probe responses |
@@ -462,6 +466,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, | |||
462 | sizeof(*local->hw_scan_req) + | 466 | sizeof(*local->hw_scan_req) + |
463 | req->n_channels * sizeof(req->channels[0]); | 467 | req->n_channels * sizeof(req->channels[0]); |
464 | local->hw_scan_req->ie = ies; | 468 | local->hw_scan_req->ie = ies; |
469 | local->hw_scan_req->flags = req->flags; | ||
465 | 470 | ||
466 | local->hw_scan_band = 0; | 471 | local->hw_scan_band = 0; |
467 | 472 | ||
@@ -480,7 +485,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, | |||
480 | if (local->ops->hw_scan) { | 485 | if (local->ops->hw_scan) { |
481 | __set_bit(SCAN_HW_SCANNING, &local->scanning); | 486 | __set_bit(SCAN_HW_SCANNING, &local->scanning); |
482 | } else if ((req->n_channels == 1) && | 487 | } else if ((req->n_channels == 1) && |
483 | (req->channels[0] == local->oper_channel)) { | 488 | (req->channels[0] == local->_oper_channel)) { |
484 | /* | 489 | /* |
485 | * If we are scanning only on the operating channel | 490 | * If we are scanning only on the operating channel |
486 | * then we do not need to stop normal activities | 491 | * then we do not need to stop normal activities |
@@ -562,6 +567,7 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local, | |||
562 | unsigned long min_beacon_int = 0; | 567 | unsigned long min_beacon_int = 0; |
563 | struct ieee80211_sub_if_data *sdata; | 568 | struct ieee80211_sub_if_data *sdata; |
564 | struct ieee80211_channel *next_chan; | 569 | struct ieee80211_channel *next_chan; |
570 | enum mac80211_scan_state next_scan_state; | ||
565 | 571 | ||
566 | /* | 572 | /* |
567 | * check if at least one STA interface is associated, | 573 | * check if at least one STA interface is associated, |
@@ -620,10 +626,18 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local, | |||
620 | usecs_to_jiffies(min_beacon_int * 1024) * | 626 | usecs_to_jiffies(min_beacon_int * 1024) * |
621 | local->hw.conf.listen_interval); | 627 | local->hw.conf.listen_interval); |
622 | 628 | ||
623 | if (associated && (!tx_empty || bad_latency || listen_int_exceeded)) | 629 | if (associated && !tx_empty) { |
624 | local->next_scan_state = SCAN_SUSPEND; | 630 | if (local->scan_req->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) |
625 | else | 631 | next_scan_state = SCAN_ABORT; |
626 | local->next_scan_state = SCAN_SET_CHANNEL; | 632 | else |
633 | next_scan_state = SCAN_SUSPEND; | ||
634 | } else if (associated && (bad_latency || listen_int_exceeded)) { | ||
635 | next_scan_state = SCAN_SUSPEND; | ||
636 | } else { | ||
637 | next_scan_state = SCAN_SET_CHANNEL; | ||
638 | } | ||
639 | |||
640 | local->next_scan_state = next_scan_state; | ||
627 | 641 | ||
628 | *next_delay = 0; | 642 | *next_delay = 0; |
629 | } | 643 | } |
@@ -794,6 +808,9 @@ void ieee80211_scan_work(struct work_struct *work) | |||
794 | case SCAN_RESUME: | 808 | case SCAN_RESUME: |
795 | ieee80211_scan_state_resume(local, &next_delay); | 809 | ieee80211_scan_state_resume(local, &next_delay); |
796 | break; | 810 | break; |
811 | case SCAN_ABORT: | ||
812 | aborted = true; | ||
813 | goto out_complete; | ||
797 | } | 814 | } |
798 | } while (next_delay == 0); | 815 | } while (next_delay == 0); |
799 | 816 | ||