aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c14
-rw-r--r--drivers/net/wireless/ath/ath9k/channel.c5
-rw-r--r--drivers/net/wireless/atmel/at76c50x-usb.c5
-rw-r--r--drivers/net/wireless/intel/iwlegacy/common.c6
-rw-r--r--drivers/net/wireless/intel/iwlwifi/dvm/scan.c6
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/scan.c37
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c11
-rw-r--r--drivers/net/wireless/st/cw1200/scan.c6
-rw-r--r--drivers/net/wireless/ti/wl1251/event.c6
-rw-r--r--drivers/net/wireless/ti/wl1251/main.c6
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c11
-rw-r--r--drivers/net/wireless/ti/wlcore/scan.c5
-rw-r--r--include/net/mac80211.h5
-rw-r--r--net/mac80211/ieee80211_i.h1
-rw-r--r--net/mac80211/scan.c42
15 files changed, 131 insertions, 35 deletions
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index d4b7a168f7c0..ebc12c521fe0 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3858,12 +3858,16 @@ void __ath10k_scan_finish(struct ath10k *ar)
3858 break; 3858 break;
3859 case ATH10K_SCAN_RUNNING: 3859 case ATH10K_SCAN_RUNNING:
3860 case ATH10K_SCAN_ABORTING: 3860 case ATH10K_SCAN_ABORTING:
3861 if (!ar->scan.is_roc) 3861 if (!ar->scan.is_roc) {
3862 ieee80211_scan_completed(ar->hw, 3862 struct cfg80211_scan_info info = {
3863 (ar->scan.state == 3863 .aborted = (ar->scan.state ==
3864 ATH10K_SCAN_ABORTING)); 3864 ATH10K_SCAN_ABORTING),
3865 else if (ar->scan.roc_notify) 3865 };
3866
3867 ieee80211_scan_completed(ar->hw, &info);
3868 } else if (ar->scan.roc_notify) {
3866 ieee80211_remain_on_channel_expired(ar->hw); 3869 ieee80211_remain_on_channel_expired(ar->hw);
3870 }
3867 /* fall through */ 3871 /* fall through */
3868 case ATH10K_SCAN_STARTING: 3872 case ATH10K_SCAN_STARTING:
3869 ar->scan.state = ATH10K_SCAN_IDLE; 3873 ar->scan.state = ATH10K_SCAN_IDLE;
diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c
index e56bafcf5864..57e26a640477 100644
--- a/drivers/net/wireless/ath/ath9k/channel.c
+++ b/drivers/net/wireless/ath/ath9k/channel.c
@@ -960,6 +960,9 @@ void ath_roc_complete(struct ath_softc *sc, enum ath_roc_complete_reason reason)
960void ath_scan_complete(struct ath_softc *sc, bool abort) 960void ath_scan_complete(struct ath_softc *sc, bool abort)
961{ 961{
962 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 962 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
963 struct cfg80211_scan_info info = {
964 .aborted = abort,
965 };
963 966
964 if (abort) 967 if (abort)
965 ath_dbg(common, CHAN_CTX, "HW scan aborted\n"); 968 ath_dbg(common, CHAN_CTX, "HW scan aborted\n");
@@ -969,7 +972,7 @@ void ath_scan_complete(struct ath_softc *sc, bool abort)
969 sc->offchannel.scan_req = NULL; 972 sc->offchannel.scan_req = NULL;
970 sc->offchannel.scan_vif = NULL; 973 sc->offchannel.scan_vif = NULL;
971 sc->offchannel.state = ATH_OFFCHANNEL_IDLE; 974 sc->offchannel.state = ATH_OFFCHANNEL_IDLE;
972 ieee80211_scan_completed(sc->hw, abort); 975 ieee80211_scan_completed(sc->hw, &info);
973 clear_bit(ATH_OP_SCANNING, &common->op_flags); 976 clear_bit(ATH_OP_SCANNING, &common->op_flags);
974 spin_lock_bh(&sc->chan_lock); 977 spin_lock_bh(&sc->chan_lock);
975 if (test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags)) 978 if (test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags))
diff --git a/drivers/net/wireless/atmel/at76c50x-usb.c b/drivers/net/wireless/atmel/at76c50x-usb.c
index 7c108047fb46..0e180677c7fc 100644
--- a/drivers/net/wireless/atmel/at76c50x-usb.c
+++ b/drivers/net/wireless/atmel/at76c50x-usb.c
@@ -1922,6 +1922,9 @@ static void at76_dwork_hw_scan(struct work_struct *work)
1922{ 1922{
1923 struct at76_priv *priv = container_of(work, struct at76_priv, 1923 struct at76_priv *priv = container_of(work, struct at76_priv,
1924 dwork_hw_scan.work); 1924 dwork_hw_scan.work);
1925 struct cfg80211_scan_info info = {
1926 .aborted = false,
1927 };
1925 int ret; 1928 int ret;
1926 1929
1927 if (priv->device_unplugged) 1930 if (priv->device_unplugged)
@@ -1948,7 +1951,7 @@ static void at76_dwork_hw_scan(struct work_struct *work)
1948 1951
1949 mutex_unlock(&priv->mtx); 1952 mutex_unlock(&priv->mtx);
1950 1953
1951 ieee80211_scan_completed(priv->hw, false); 1954 ieee80211_scan_completed(priv->hw, &info);
1952 1955
1953 ieee80211_wake_queues(priv->hw); 1956 ieee80211_wake_queues(priv->hw);
1954} 1957}
diff --git a/drivers/net/wireless/intel/iwlegacy/common.c b/drivers/net/wireless/intel/iwlegacy/common.c
index eb24b9241bb2..140b6ea8f7cc 100644
--- a/drivers/net/wireless/intel/iwlegacy/common.c
+++ b/drivers/net/wireless/intel/iwlegacy/common.c
@@ -1305,10 +1305,14 @@ il_send_scan_abort(struct il_priv *il)
1305static void 1305static void
1306il_complete_scan(struct il_priv *il, bool aborted) 1306il_complete_scan(struct il_priv *il, bool aborted)
1307{ 1307{
1308 struct cfg80211_scan_info info = {
1309 .aborted = aborted,
1310 };
1311
1308 /* check if scan was requested from mac80211 */ 1312 /* check if scan was requested from mac80211 */
1309 if (il->scan_request) { 1313 if (il->scan_request) {
1310 D_SCAN("Complete scan in mac80211\n"); 1314 D_SCAN("Complete scan in mac80211\n");
1311 ieee80211_scan_completed(il->hw, aborted); 1315 ieee80211_scan_completed(il->hw, &info);
1312 } 1316 }
1313 1317
1314 il->scan_vif = NULL; 1318 il->scan_vif = NULL;
diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/scan.c b/drivers/net/wireless/intel/iwlwifi/dvm/scan.c
index d01766f16175..17e6a32384d3 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/scan.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/scan.c
@@ -94,10 +94,14 @@ static int iwl_send_scan_abort(struct iwl_priv *priv)
94 94
95static void iwl_complete_scan(struct iwl_priv *priv, bool aborted) 95static void iwl_complete_scan(struct iwl_priv *priv, bool aborted)
96{ 96{
97 struct cfg80211_scan_info info = {
98 .aborted = aborted,
99 };
100
97 /* check if scan was requested from mac80211 */ 101 /* check if scan was requested from mac80211 */
98 if (priv->scan_request) { 102 if (priv->scan_request) {
99 IWL_DEBUG_SCAN(priv, "Complete scan in mac80211\n"); 103 IWL_DEBUG_SCAN(priv, "Complete scan in mac80211\n");
100 ieee80211_scan_completed(priv->hw, aborted); 104 ieee80211_scan_completed(priv->hw, &info);
101 } 105 }
102 106
103 priv->scan_type = IWL_SCAN_NORMAL; 107 priv->scan_type = IWL_SCAN_NORMAL;
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
index e78fc567ff7d..1cac10c5d818 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
@@ -391,13 +391,16 @@ void iwl_mvm_rx_lmac_scan_complete_notif(struct iwl_mvm *mvm,
391 ieee80211_sched_scan_stopped(mvm->hw); 391 ieee80211_sched_scan_stopped(mvm->hw);
392 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED; 392 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
393 } else if (mvm->scan_status & IWL_MVM_SCAN_REGULAR) { 393 } else if (mvm->scan_status & IWL_MVM_SCAN_REGULAR) {
394 struct cfg80211_scan_info info = {
395 .aborted = aborted,
396 };
397
394 IWL_DEBUG_SCAN(mvm, "Regular scan %s, EBS status %s (FW)\n", 398 IWL_DEBUG_SCAN(mvm, "Regular scan %s, EBS status %s (FW)\n",
395 aborted ? "aborted" : "completed", 399 aborted ? "aborted" : "completed",
396 iwl_mvm_ebs_status_str(scan_notif->ebs_status)); 400 iwl_mvm_ebs_status_str(scan_notif->ebs_status));
397 401
398 mvm->scan_status &= ~IWL_MVM_SCAN_REGULAR; 402 mvm->scan_status &= ~IWL_MVM_SCAN_REGULAR;
399 ieee80211_scan_completed(mvm->hw, 403 ieee80211_scan_completed(mvm->hw, &info);
400 scan_notif->status == IWL_SCAN_OFFLOAD_ABORTED);
401 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); 404 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
402 del_timer(&mvm->scan_timer); 405 del_timer(&mvm->scan_timer);
403 } else { 406 } else {
@@ -1430,7 +1433,11 @@ void iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm,
1430 1433
1431 /* if the scan is already stopping, we don't need to notify mac80211 */ 1434 /* if the scan is already stopping, we don't need to notify mac80211 */
1432 if (mvm->scan_uid_status[uid] == IWL_MVM_SCAN_REGULAR) { 1435 if (mvm->scan_uid_status[uid] == IWL_MVM_SCAN_REGULAR) {
1433 ieee80211_scan_completed(mvm->hw, aborted); 1436 struct cfg80211_scan_info info = {
1437 .aborted = aborted,
1438 };
1439
1440 ieee80211_scan_completed(mvm->hw, &info);
1434 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); 1441 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
1435 del_timer(&mvm->scan_timer); 1442 del_timer(&mvm->scan_timer);
1436 } else if (mvm->scan_uid_status[uid] == IWL_MVM_SCAN_SCHED) { 1443 } else if (mvm->scan_uid_status[uid] == IWL_MVM_SCAN_SCHED) {
@@ -1564,7 +1571,11 @@ void iwl_mvm_report_scan_aborted(struct iwl_mvm *mvm)
1564 1571
1565 uid = iwl_mvm_scan_uid_by_status(mvm, IWL_MVM_SCAN_REGULAR); 1572 uid = iwl_mvm_scan_uid_by_status(mvm, IWL_MVM_SCAN_REGULAR);
1566 if (uid >= 0) { 1573 if (uid >= 0) {
1567 ieee80211_scan_completed(mvm->hw, true); 1574 struct cfg80211_scan_info info = {
1575 .aborted = true,
1576 };
1577
1578 ieee80211_scan_completed(mvm->hw, &info);
1568 mvm->scan_uid_status[uid] = 0; 1579 mvm->scan_uid_status[uid] = 0;
1569 } 1580 }
1570 uid = iwl_mvm_scan_uid_by_status(mvm, IWL_MVM_SCAN_SCHED); 1581 uid = iwl_mvm_scan_uid_by_status(mvm, IWL_MVM_SCAN_SCHED);
@@ -1585,8 +1596,13 @@ void iwl_mvm_report_scan_aborted(struct iwl_mvm *mvm)
1585 mvm->scan_uid_status[i] = 0; 1596 mvm->scan_uid_status[i] = 0;
1586 } 1597 }
1587 } else { 1598 } else {
1588 if (mvm->scan_status & IWL_MVM_SCAN_REGULAR) 1599 if (mvm->scan_status & IWL_MVM_SCAN_REGULAR) {
1589 ieee80211_scan_completed(mvm->hw, true); 1600 struct cfg80211_scan_info info = {
1601 .aborted = true,
1602 };
1603
1604 ieee80211_scan_completed(mvm->hw, &info);
1605 }
1590 1606
1591 /* Sched scan will be restarted by mac80211 in 1607 /* Sched scan will be restarted by mac80211 in
1592 * restart_hw, so do not report if FW is about to be 1608 * restart_hw, so do not report if FW is about to be
@@ -1629,8 +1645,13 @@ out:
1629 */ 1645 */
1630 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); 1646 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
1631 del_timer(&mvm->scan_timer); 1647 del_timer(&mvm->scan_timer);
1632 if (notify) 1648 if (notify) {
1633 ieee80211_scan_completed(mvm->hw, true); 1649 struct cfg80211_scan_info info = {
1650 .aborted = true,
1651 };
1652
1653 ieee80211_scan_completed(mvm->hw, &info);
1654 }
1634 } else if (notify) { 1655 } else if (notify) {
1635 ieee80211_sched_scan_stopped(mvm->hw); 1656 ieee80211_sched_scan_stopped(mvm->hw);
1636 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED; 1657 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 337794f9506e..8c35ac838fce 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -1941,8 +1941,12 @@ static void hw_scan_work(struct work_struct *work)
1941 1941
1942 mutex_lock(&hwsim->mutex); 1942 mutex_lock(&hwsim->mutex);
1943 if (hwsim->scan_chan_idx >= req->n_channels) { 1943 if (hwsim->scan_chan_idx >= req->n_channels) {
1944 struct cfg80211_scan_info info = {
1945 .aborted = false,
1946 };
1947
1944 wiphy_debug(hwsim->hw->wiphy, "hw scan complete\n"); 1948 wiphy_debug(hwsim->hw->wiphy, "hw scan complete\n");
1945 ieee80211_scan_completed(hwsim->hw, false); 1949 ieee80211_scan_completed(hwsim->hw, &info);
1946 hwsim->hw_scan_request = NULL; 1950 hwsim->hw_scan_request = NULL;
1947 hwsim->hw_scan_vif = NULL; 1951 hwsim->hw_scan_vif = NULL;
1948 hwsim->tmp_chan = NULL; 1952 hwsim->tmp_chan = NULL;
@@ -2027,13 +2031,16 @@ static void mac80211_hwsim_cancel_hw_scan(struct ieee80211_hw *hw,
2027 struct ieee80211_vif *vif) 2031 struct ieee80211_vif *vif)
2028{ 2032{
2029 struct mac80211_hwsim_data *hwsim = hw->priv; 2033 struct mac80211_hwsim_data *hwsim = hw->priv;
2034 struct cfg80211_scan_info info = {
2035 .aborted = true,
2036 };
2030 2037
2031 wiphy_debug(hw->wiphy, "hwsim cancel_hw_scan\n"); 2038 wiphy_debug(hw->wiphy, "hwsim cancel_hw_scan\n");
2032 2039
2033 cancel_delayed_work_sync(&hwsim->hw_scan); 2040 cancel_delayed_work_sync(&hwsim->hw_scan);
2034 2041
2035 mutex_lock(&hwsim->mutex); 2042 mutex_lock(&hwsim->mutex);
2036 ieee80211_scan_completed(hwsim->hw, true); 2043 ieee80211_scan_completed(hwsim->hw, &info);
2037 hwsim->tmp_chan = NULL; 2044 hwsim->tmp_chan = NULL;
2038 hwsim->hw_scan_request = NULL; 2045 hwsim->hw_scan_request = NULL;
2039 hwsim->hw_scan_vif = NULL; 2046 hwsim->hw_scan_vif = NULL;
diff --git a/drivers/net/wireless/st/cw1200/scan.c b/drivers/net/wireless/st/cw1200/scan.c
index 983788156bb0..0a0ff7e31f5b 100644
--- a/drivers/net/wireless/st/cw1200/scan.c
+++ b/drivers/net/wireless/st/cw1200/scan.c
@@ -167,6 +167,10 @@ void cw1200_scan_work(struct work_struct *work)
167 } 167 }
168 168
169 if (!priv->scan.req || (priv->scan.curr == priv->scan.end)) { 169 if (!priv->scan.req || (priv->scan.curr == priv->scan.end)) {
170 struct cfg80211_scan_info info = {
171 .aborted = priv->scan.status ? 1 : 0,
172 };
173
170 if (priv->scan.output_power != priv->output_power) 174 if (priv->scan.output_power != priv->output_power)
171 wsm_set_output_power(priv, priv->output_power * 10); 175 wsm_set_output_power(priv, priv->output_power * 10);
172 if (priv->join_status == CW1200_JOIN_STATUS_STA && 176 if (priv->join_status == CW1200_JOIN_STATUS_STA &&
@@ -188,7 +192,7 @@ void cw1200_scan_work(struct work_struct *work)
188 cw1200_scan_restart_delayed(priv); 192 cw1200_scan_restart_delayed(priv);
189 wsm_unlock_tx(priv); 193 wsm_unlock_tx(priv);
190 mutex_unlock(&priv->conf_mutex); 194 mutex_unlock(&priv->conf_mutex);
191 ieee80211_scan_completed(priv->hw, priv->scan.status ? 1 : 0); 195 ieee80211_scan_completed(priv->hw, &info);
192 up(&priv->scan.lock); 196 up(&priv->scan.lock);
193 return; 197 return;
194 } else { 198 } else {
diff --git a/drivers/net/wireless/ti/wl1251/event.c b/drivers/net/wireless/ti/wl1251/event.c
index c98630394a1a..d0593bc1f1a9 100644
--- a/drivers/net/wireless/ti/wl1251/event.c
+++ b/drivers/net/wireless/ti/wl1251/event.c
@@ -36,7 +36,11 @@ static int wl1251_event_scan_complete(struct wl1251 *wl,
36 mbox->scheduled_scan_channels); 36 mbox->scheduled_scan_channels);
37 37
38 if (wl->scanning) { 38 if (wl->scanning) {
39 ieee80211_scan_completed(wl->hw, false); 39 struct cfg80211_scan_info info = {
40 .aborted = false,
41 };
42
43 ieee80211_scan_completed(wl->hw, &info);
40 wl1251_debug(DEBUG_MAC80211, "mac80211 hw scan completed"); 44 wl1251_debug(DEBUG_MAC80211, "mac80211 hw scan completed");
41 wl->scanning = false; 45 wl->scanning = false;
42 if (wl->hw->conf.flags & IEEE80211_CONF_IDLE) 46 if (wl->hw->conf.flags & IEEE80211_CONF_IDLE)
diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c
index 56384a4e2a35..bbf7604889b7 100644
--- a/drivers/net/wireless/ti/wl1251/main.c
+++ b/drivers/net/wireless/ti/wl1251/main.c
@@ -448,7 +448,11 @@ static void wl1251_op_stop(struct ieee80211_hw *hw)
448 WARN_ON(wl->state != WL1251_STATE_ON); 448 WARN_ON(wl->state != WL1251_STATE_ON);
449 449
450 if (wl->scanning) { 450 if (wl->scanning) {
451 ieee80211_scan_completed(wl->hw, true); 451 struct cfg80211_scan_info info = {
452 .aborted = true,
453 };
454
455 ieee80211_scan_completed(wl->hw, &info);
452 wl->scanning = false; 456 wl->scanning = false;
453 } 457 }
454 458
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 10fd24c28ece..69267d592504 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -2615,6 +2615,10 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
2615 2615
2616 if (wl->scan.state != WL1271_SCAN_STATE_IDLE && 2616 if (wl->scan.state != WL1271_SCAN_STATE_IDLE &&
2617 wl->scan_wlvif == wlvif) { 2617 wl->scan_wlvif == wlvif) {
2618 struct cfg80211_scan_info info = {
2619 .aborted = true,
2620 };
2621
2618 /* 2622 /*
2619 * Rearm the tx watchdog just before idling scan. This 2623 * Rearm the tx watchdog just before idling scan. This
2620 * prevents just-finished scans from triggering the watchdog 2624 * prevents just-finished scans from triggering the watchdog
@@ -2625,7 +2629,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
2625 memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); 2629 memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch));
2626 wl->scan_wlvif = NULL; 2630 wl->scan_wlvif = NULL;
2627 wl->scan.req = NULL; 2631 wl->scan.req = NULL;
2628 ieee80211_scan_completed(wl->hw, true); 2632 ieee80211_scan_completed(wl->hw, &info);
2629 } 2633 }
2630 2634
2631 if (wl->sched_vif == wlvif) 2635 if (wl->sched_vif == wlvif)
@@ -3649,6 +3653,9 @@ static void wl1271_op_cancel_hw_scan(struct ieee80211_hw *hw,
3649{ 3653{
3650 struct wl1271 *wl = hw->priv; 3654 struct wl1271 *wl = hw->priv;
3651 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 3655 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
3656 struct cfg80211_scan_info info = {
3657 .aborted = true,
3658 };
3652 int ret; 3659 int ret;
3653 3660
3654 wl1271_debug(DEBUG_MAC80211, "mac80211 cancel hw scan"); 3661 wl1271_debug(DEBUG_MAC80211, "mac80211 cancel hw scan");
@@ -3681,7 +3688,7 @@ static void wl1271_op_cancel_hw_scan(struct ieee80211_hw *hw,
3681 memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); 3688 memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch));
3682 wl->scan_wlvif = NULL; 3689 wl->scan_wlvif = NULL;
3683 wl->scan.req = NULL; 3690 wl->scan.req = NULL;
3684 ieee80211_scan_completed(wl->hw, true); 3691 ieee80211_scan_completed(wl->hw, &info);
3685 3692
3686out_sleep: 3693out_sleep:
3687 wl1271_ps_elp_sleep(wl); 3694 wl1271_ps_elp_sleep(wl);
diff --git a/drivers/net/wireless/ti/wlcore/scan.c b/drivers/net/wireless/ti/wlcore/scan.c
index 23343643207a..5612f5916b4e 100644
--- a/drivers/net/wireless/ti/wlcore/scan.c
+++ b/drivers/net/wireless/ti/wlcore/scan.c
@@ -36,6 +36,9 @@ void wl1271_scan_complete_work(struct work_struct *work)
36 struct delayed_work *dwork; 36 struct delayed_work *dwork;
37 struct wl1271 *wl; 37 struct wl1271 *wl;
38 struct wl12xx_vif *wlvif; 38 struct wl12xx_vif *wlvif;
39 struct cfg80211_scan_info info = {
40 .aborted = false,
41 };
39 int ret; 42 int ret;
40 43
41 dwork = to_delayed_work(work); 44 dwork = to_delayed_work(work);
@@ -82,7 +85,7 @@ void wl1271_scan_complete_work(struct work_struct *work)
82 85
83 wlcore_cmd_regdomain_config_locked(wl); 86 wlcore_cmd_regdomain_config_locked(wl);
84 87
85 ieee80211_scan_completed(wl->hw, false); 88 ieee80211_scan_completed(wl->hw, &info);
86 89
87out: 90out:
88 mutex_unlock(&wl->mutex); 91 mutex_unlock(&wl->mutex);
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index a52009ffc19f..b4faadbb4e01 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -4697,9 +4697,10 @@ void ieee80211_wake_queues(struct ieee80211_hw *hw);
4697 * any context, including hardirq context. 4697 * any context, including hardirq context.
4698 * 4698 *
4699 * @hw: the hardware that finished the scan 4699 * @hw: the hardware that finished the scan
4700 * @aborted: set to true if scan was aborted 4700 * @info: information about the completed scan
4701 */ 4701 */
4702void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted); 4702void ieee80211_scan_completed(struct ieee80211_hw *hw,
4703 struct cfg80211_scan_info *info);
4703 4704
4704/** 4705/**
4705 * ieee80211_sched_scan_results - got results from scheduled scan 4706 * ieee80211_sched_scan_results - got results from scheduled scan
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 54edfb6fc1d1..f56d342c31b8 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1250,6 +1250,7 @@ struct ieee80211_local {
1250 int scan_channel_idx; 1250 int scan_channel_idx;
1251 int scan_ies_len; 1251 int scan_ies_len;
1252 int hw_scan_ies_bufsize; 1252 int hw_scan_ies_bufsize;
1253 struct cfg80211_scan_info scan_info;
1253 1254
1254 struct work_struct sched_scan_stopped_work; 1255 struct work_struct sched_scan_stopped_work;
1255 struct ieee80211_sub_if_data __rcu *sched_scan_sdata; 1256 struct ieee80211_sub_if_data __rcu *sched_scan_sdata;
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 4ec1c52a1549..8d4a9cd8a39a 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -7,6 +7,7 @@
7 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> 7 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
8 * Copyright 2007, Michael Wu <flamingice@sourmilk.net> 8 * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
9 * Copyright 2013-2015 Intel Mobile Communications GmbH 9 * Copyright 2013-2015 Intel Mobile Communications GmbH
10 * Copyright 2016 Intel Deutschland GmbH
10 * 11 *
11 * This program is free software; you can redistribute it and/or modify 12 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as 13 * it under the terms of the GNU General Public License version 2 as
@@ -70,6 +71,7 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
70 .boottime_ns = rx_status->boottime_ns, 71 .boottime_ns = rx_status->boottime_ns,
71 }; 72 };
72 bool signal_valid; 73 bool signal_valid;
74 struct ieee80211_sub_if_data *scan_sdata;
73 75
74 if (ieee80211_hw_check(&local->hw, SIGNAL_DBM)) 76 if (ieee80211_hw_check(&local->hw, SIGNAL_DBM))
75 bss_meta.signal = rx_status->signal * 100; 77 bss_meta.signal = rx_status->signal * 100;
@@ -83,6 +85,20 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
83 bss_meta.scan_width = NL80211_BSS_CHAN_WIDTH_10; 85 bss_meta.scan_width = NL80211_BSS_CHAN_WIDTH_10;
84 86
85 bss_meta.chan = channel; 87 bss_meta.chan = channel;
88
89 rcu_read_lock();
90 scan_sdata = rcu_dereference(local->scan_sdata);
91 if (scan_sdata && scan_sdata->vif.type == NL80211_IFTYPE_STATION &&
92 scan_sdata->vif.bss_conf.assoc &&
93 ieee80211_have_rx_timestamp(rx_status)) {
94 bss_meta.parent_tsf =
95 ieee80211_calculate_rx_timestamp(local, rx_status,
96 len + FCS_LEN, 24);
97 ether_addr_copy(bss_meta.parent_bssid,
98 scan_sdata->vif.bss_conf.bssid);
99 }
100 rcu_read_unlock();
101
86 cbss = cfg80211_inform_bss_frame_data(local->hw.wiphy, &bss_meta, 102 cbss = cfg80211_inform_bss_frame_data(local->hw.wiphy, &bss_meta,
87 mgmt, len, GFP_ATOMIC); 103 mgmt, len, GFP_ATOMIC);
88 if (!cbss) 104 if (!cbss)
@@ -345,6 +361,11 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
345 361
346 if (rc == 0) 362 if (rc == 0)
347 return; 363 return;
364
365 /* HW scan failed and is going to be reported as done, so clear
366 * old scan info.
367 */
368 memset(&local->scan_info, 0, sizeof(local->scan_info));
348 } 369 }
349 370
350 kfree(local->hw_scan_req); 371 kfree(local->hw_scan_req);
@@ -354,11 +375,8 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
354 lockdep_is_held(&local->mtx)); 375 lockdep_is_held(&local->mtx));
355 376
356 if (scan_req != local->int_scan_req) { 377 if (scan_req != local->int_scan_req) {
357 struct cfg80211_scan_info info = { 378 local->scan_info.aborted = aborted;
358 .aborted = aborted, 379 cfg80211_scan_done(scan_req, &local->scan_info);
359 };
360
361 cfg80211_scan_done(scan_req, &info);
362 } 380 }
363 RCU_INIT_POINTER(local->scan_req, NULL); 381 RCU_INIT_POINTER(local->scan_req, NULL);
364 382
@@ -396,15 +414,19 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
396 ieee80211_start_next_roc(local); 414 ieee80211_start_next_roc(local);
397} 415}
398 416
399void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) 417void ieee80211_scan_completed(struct ieee80211_hw *hw,
418 struct cfg80211_scan_info *info)
400{ 419{
401 struct ieee80211_local *local = hw_to_local(hw); 420 struct ieee80211_local *local = hw_to_local(hw);
402 421
403 trace_api_scan_completed(local, aborted); 422 trace_api_scan_completed(local, info);
404 423
405 set_bit(SCAN_COMPLETED, &local->scanning); 424 set_bit(SCAN_COMPLETED, &local->scanning);
406 if (aborted) 425 if (info->aborted)
407 set_bit(SCAN_ABORTED, &local->scanning); 426 set_bit(SCAN_ABORTED, &local->scanning);
427
428 memcpy(&local->scan_info, info, sizeof(*info));
429
408 ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0); 430 ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0);
409} 431}
410EXPORT_SYMBOL(ieee80211_scan_completed); 432EXPORT_SYMBOL(ieee80211_scan_completed);
@@ -571,6 +593,9 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
571 local->hw_scan_req->req.ie = ies; 593 local->hw_scan_req->req.ie = ies;
572 local->hw_scan_req->req.flags = req->flags; 594 local->hw_scan_req->req.flags = req->flags;
573 eth_broadcast_addr(local->hw_scan_req->req.bssid); 595 eth_broadcast_addr(local->hw_scan_req->req.bssid);
596 local->hw_scan_req->req.duration = req->duration;
597 local->hw_scan_req->req.duration_mandatory =
598 req->duration_mandatory;
574 599
575 local->hw_scan_band = 0; 600 local->hw_scan_band = 0;
576 601
@@ -1078,6 +1103,7 @@ void ieee80211_scan_cancel(struct ieee80211_local *local)
1078 */ 1103 */
1079 cancel_delayed_work(&local->scan_work); 1104 cancel_delayed_work(&local->scan_work);
1080 /* and clean up */ 1105 /* and clean up */
1106 memset(&local->scan_info, 0, sizeof(local->scan_info));
1081 __ieee80211_scan_completed(&local->hw, true); 1107 __ieee80211_scan_completed(&local->hw, true);
1082out: 1108out:
1083 mutex_unlock(&local->mtx); 1109 mutex_unlock(&local->mtx);