aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/mac80211.h3
-rw-r--r--net/mac80211/ieee80211_i.h6
-rw-r--r--net/mac80211/scan.c34
3 files changed, 34 insertions, 9 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index dcc8c2bf986e..8f97548b6d80 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -2268,7 +2268,8 @@ void ieee80211_wake_queues(struct ieee80211_hw *hw);
2268 * 2268 *
2269 * When hardware scan offload is used (i.e. the hw_scan() callback is 2269 * When hardware scan offload is used (i.e. the hw_scan() callback is
2270 * assigned) this function needs to be called by the driver to notify 2270 * assigned) this function needs to be called by the driver to notify
2271 * mac80211 that the scan finished. 2271 * mac80211 that the scan finished. This function can be called from
2272 * any context, including hardirq context.
2272 * 2273 *
2273 * @hw: the hardware that finished the scan 2274 * @hw: the hardware that finished the scan
2274 * @aborted: set to true if scan was aborted 2275 * @aborted: set to true if scan was aborted
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 9e225f01497b..31713320258c 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -596,11 +596,17 @@ enum queue_stop_reason {
596 * determine if we are on the operating channel or not 596 * determine if we are on the operating channel or not
597 * @SCAN_OFF_CHANNEL: We're off our operating channel for scanning, 597 * @SCAN_OFF_CHANNEL: We're off our operating channel for scanning,
598 * gets only set in conjunction with SCAN_SW_SCANNING 598 * gets only set in conjunction with SCAN_SW_SCANNING
599 * @SCAN_COMPLETED: Set for our scan work function when the driver reported
600 * that the scan completed.
601 * @SCAN_ABORTED: Set for our scan work function when the driver reported
602 * a scan complete for an aborted scan.
599 */ 603 */
600enum { 604enum {
601 SCAN_SW_SCANNING, 605 SCAN_SW_SCANNING,
602 SCAN_HW_SCANNING, 606 SCAN_HW_SCANNING,
603 SCAN_OFF_CHANNEL, 607 SCAN_OFF_CHANNEL,
608 SCAN_COMPLETED,
609 SCAN_ABORTED,
604}; 610};
605 611
606/** 612/**
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 31f233f7f51a..d60389ba9b95 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -248,13 +248,11 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
248 return true; 248 return true;
249} 249}
250 250
251void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) 251static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
252{ 252{
253 struct ieee80211_local *local = hw_to_local(hw); 253 struct ieee80211_local *local = hw_to_local(hw);
254 bool was_hw_scan; 254 bool was_hw_scan;
255 255
256 trace_api_scan_completed(local, aborted);
257
258 mutex_lock(&local->mtx); 256 mutex_lock(&local->mtx);
259 257
260 /* 258 /*
@@ -312,6 +310,18 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
312 ieee80211_mesh_notify_scan_completed(local); 310 ieee80211_mesh_notify_scan_completed(local);
313 ieee80211_queue_work(&local->hw, &local->work_work); 311 ieee80211_queue_work(&local->hw, &local->work_work);
314} 312}
313
314void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
315{
316 struct ieee80211_local *local = hw_to_local(hw);
317
318 trace_api_scan_completed(local, aborted);
319
320 set_bit(SCAN_COMPLETED, &local->scanning);
321 if (aborted)
322 set_bit(SCAN_ABORTED, &local->scanning);
323 ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0);
324}
315EXPORT_SYMBOL(ieee80211_scan_completed); 325EXPORT_SYMBOL(ieee80211_scan_completed);
316 326
317static int ieee80211_start_sw_scan(struct ieee80211_local *local) 327static int ieee80211_start_sw_scan(struct ieee80211_local *local)
@@ -449,7 +459,7 @@ static int ieee80211_scan_state_decision(struct ieee80211_local *local,
449 459
450 /* if no more bands/channels left, complete scan and advance to the idle state */ 460 /* if no more bands/channels left, complete scan and advance to the idle state */
451 if (local->scan_channel_idx >= local->scan_req->n_channels) { 461 if (local->scan_channel_idx >= local->scan_req->n_channels) {
452 ieee80211_scan_completed(&local->hw, false); 462 __ieee80211_scan_completed(&local->hw, false);
453 return 1; 463 return 1;
454 } 464 }
455 465
@@ -641,6 +651,14 @@ void ieee80211_scan_work(struct work_struct *work)
641 struct ieee80211_sub_if_data *sdata = local->scan_sdata; 651 struct ieee80211_sub_if_data *sdata = local->scan_sdata;
642 unsigned long next_delay = 0; 652 unsigned long next_delay = 0;
643 653
654 if (test_and_clear_bit(SCAN_COMPLETED, &local->scanning)) {
655 bool aborted;
656
657 aborted = test_and_clear_bit(SCAN_ABORTED, &local->scanning);
658 __ieee80211_scan_completed(&local->hw, aborted);
659 return;
660 }
661
644 mutex_lock(&local->mtx); 662 mutex_lock(&local->mtx);
645 if (!sdata || !local->scan_req) { 663 if (!sdata || !local->scan_req) {
646 mutex_unlock(&local->mtx); 664 mutex_unlock(&local->mtx);
@@ -651,7 +669,7 @@ void ieee80211_scan_work(struct work_struct *work)
651 int rc = drv_hw_scan(local, sdata, local->hw_scan_req); 669 int rc = drv_hw_scan(local, sdata, local->hw_scan_req);
652 mutex_unlock(&local->mtx); 670 mutex_unlock(&local->mtx);
653 if (rc) 671 if (rc)
654 ieee80211_scan_completed(&local->hw, true); 672 __ieee80211_scan_completed(&local->hw, true);
655 return; 673 return;
656 } 674 }
657 675
@@ -666,7 +684,7 @@ void ieee80211_scan_work(struct work_struct *work)
666 mutex_unlock(&local->mtx); 684 mutex_unlock(&local->mtx);
667 685
668 if (rc) 686 if (rc)
669 ieee80211_scan_completed(&local->hw, true); 687 __ieee80211_scan_completed(&local->hw, true);
670 return; 688 return;
671 } 689 }
672 690
@@ -676,7 +694,7 @@ void ieee80211_scan_work(struct work_struct *work)
676 * Avoid re-scheduling when the sdata is going away. 694 * Avoid re-scheduling when the sdata is going away.
677 */ 695 */
678 if (!ieee80211_sdata_running(sdata)) { 696 if (!ieee80211_sdata_running(sdata)) {
679 ieee80211_scan_completed(&local->hw, true); 697 __ieee80211_scan_completed(&local->hw, true);
680 return; 698 return;
681 } 699 }
682 700
@@ -783,5 +801,5 @@ void ieee80211_scan_cancel(struct ieee80211_local *local)
783 mutex_unlock(&local->mtx); 801 mutex_unlock(&local->mtx);
784 802
785 if (abortscan) 803 if (abortscan)
786 ieee80211_scan_completed(&local->hw, true); 804 __ieee80211_scan_completed(&local->hw, true);
787} 805}