aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.c17
-rw-r--r--drivers/net/wireless/ath/wil6210/cfg80211.c6
-rw-r--r--drivers/net/wireless/ath/wil6210/main.c12
-rw-r--r--drivers/net/wireless/ath/wil6210/p2p.c6
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.c8
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c6
-rw-r--r--drivers/net/wireless/intersil/orinoco/scan.c12
-rw-r--r--drivers/net/wireless/marvell/libertas/cfg.c11
-rw-r--r--drivers/net/wireless/marvell/mwifiex/cmdevt.c12
-rw-r--r--drivers/net/wireless/marvell/mwifiex/main.c6
-rw-r--r--drivers/net/wireless/marvell/mwifiex/scan.c12
-rw-r--r--drivers/net/wireless/rndis_wlan.c10
-rw-r--r--drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c11
-rw-r--r--drivers/staging/wilc1000/wilc_wfi_cfgoperations.c12
-rw-r--r--drivers/staging/wlan-ng/cfg80211.c5
-rw-r--r--include/net/cfg80211.h40
-rw-r--r--include/uapi/linux/nl80211.h42
-rw-r--r--net/mac80211/scan.c9
-rw-r--r--net/wireless/core.c4
-rw-r--r--net/wireless/core.h12
-rw-r--r--net/wireless/nl80211.c27
-rw-r--r--net/wireless/scan.c18
-rw-r--r--net/wireless/trace.h33
23 files changed, 279 insertions, 52 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 4e11ba06f089..ef5b40ef6d67 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -859,7 +859,11 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason,
859 struct ath6kl *ar = vif->ar; 859 struct ath6kl *ar = vif->ar;
860 860
861 if (vif->scan_req) { 861 if (vif->scan_req) {
862 cfg80211_scan_done(vif->scan_req, true); 862 struct cfg80211_scan_info info = {
863 .aborted = true,
864 };
865
866 cfg80211_scan_done(vif->scan_req, &info);
863 vif->scan_req = NULL; 867 vif->scan_req = NULL;
864 } 868 }
865 869
@@ -1069,6 +1073,9 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy,
1069void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted) 1073void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted)
1070{ 1074{
1071 struct ath6kl *ar = vif->ar; 1075 struct ath6kl *ar = vif->ar;
1076 struct cfg80211_scan_info info = {
1077 .aborted = aborted,
1078 };
1072 int i; 1079 int i;
1073 1080
1074 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: status%s\n", __func__, 1081 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: status%s\n", __func__,
@@ -1089,7 +1096,7 @@ void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted)
1089 } 1096 }
1090 1097
1091out: 1098out:
1092 cfg80211_scan_done(vif->scan_req, aborted); 1099 cfg80211_scan_done(vif->scan_req, &info);
1093 vif->scan_req = NULL; 1100 vif->scan_req = NULL;
1094} 1101}
1095 1102
@@ -3614,7 +3621,11 @@ void ath6kl_cfg80211_vif_stop(struct ath6kl_vif *vif, bool wmi_ready)
3614 } 3621 }
3615 3622
3616 if (vif->scan_req) { 3623 if (vif->scan_req) {
3617 cfg80211_scan_done(vif->scan_req, true); 3624 struct cfg80211_scan_info info = {
3625 .aborted = true,
3626 };
3627
3628 cfg80211_scan_done(vif->scan_req, &info);
3618 vif->scan_req = NULL; 3629 vif->scan_req = NULL;
3619 } 3630 }
3620 3631
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index 62bf9331bd7f..f0e1175fb76a 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -1369,7 +1369,11 @@ static void wil_cfg80211_stop_p2p_device(struct wiphy *wiphy,
1369 mutex_lock(&wil->mutex); 1369 mutex_lock(&wil->mutex);
1370 started = wil_p2p_stop_discovery(wil); 1370 started = wil_p2p_stop_discovery(wil);
1371 if (started && wil->scan_request) { 1371 if (started && wil->scan_request) {
1372 cfg80211_scan_done(wil->scan_request, 1); 1372 struct cfg80211_scan_info info = {
1373 .aborted = true,
1374 };
1375
1376 cfg80211_scan_done(wil->scan_request, &info);
1373 wil->scan_request = NULL; 1377 wil->scan_request = NULL;
1374 wil->radio_wdev = wil->wdev; 1378 wil->radio_wdev = wil->wdev;
1375 } 1379 }
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index 8e31d755bbee..4bc92e54984a 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -850,10 +850,14 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
850 mutex_unlock(&wil->wmi_mutex); 850 mutex_unlock(&wil->wmi_mutex);
851 851
852 if (wil->scan_request) { 852 if (wil->scan_request) {
853 struct cfg80211_scan_info info = {
854 .aborted = true,
855 };
856
853 wil_dbg_misc(wil, "Abort scan_request 0x%p\n", 857 wil_dbg_misc(wil, "Abort scan_request 0x%p\n",
854 wil->scan_request); 858 wil->scan_request);
855 del_timer_sync(&wil->scan_timer); 859 del_timer_sync(&wil->scan_timer);
856 cfg80211_scan_done(wil->scan_request, true); 860 cfg80211_scan_done(wil->scan_request, &info);
857 wil->scan_request = NULL; 861 wil->scan_request = NULL;
858 } 862 }
859 863
@@ -1049,10 +1053,14 @@ int __wil_down(struct wil6210_priv *wil)
1049 (void)wil_p2p_stop_discovery(wil); 1053 (void)wil_p2p_stop_discovery(wil);
1050 1054
1051 if (wil->scan_request) { 1055 if (wil->scan_request) {
1056 struct cfg80211_scan_info info = {
1057 .aborted = true,
1058 };
1059
1052 wil_dbg_misc(wil, "Abort scan_request 0x%p\n", 1060 wil_dbg_misc(wil, "Abort scan_request 0x%p\n",
1053 wil->scan_request); 1061 wil->scan_request);
1054 del_timer_sync(&wil->scan_timer); 1062 del_timer_sync(&wil->scan_timer);
1055 cfg80211_scan_done(wil->scan_request, true); 1063 cfg80211_scan_done(wil->scan_request, &info);
1056 wil->scan_request = NULL; 1064 wil->scan_request = NULL;
1057 } 1065 }
1058 1066
diff --git a/drivers/net/wireless/ath/wil6210/p2p.c b/drivers/net/wireless/ath/wil6210/p2p.c
index 213b8259638c..e0f8aa0ebfac 100644
--- a/drivers/net/wireless/ath/wil6210/p2p.c
+++ b/drivers/net/wireless/ath/wil6210/p2p.c
@@ -252,8 +252,12 @@ void wil_p2p_search_expired(struct work_struct *work)
252 mutex_unlock(&wil->mutex); 252 mutex_unlock(&wil->mutex);
253 253
254 if (started) { 254 if (started) {
255 struct cfg80211_scan_info info = {
256 .aborted = false,
257 };
258
255 mutex_lock(&wil->p2p_wdev_mutex); 259 mutex_lock(&wil->p2p_wdev_mutex);
256 cfg80211_scan_done(wil->scan_request, 0); 260 cfg80211_scan_done(wil->scan_request, &info);
257 wil->scan_request = NULL; 261 wil->scan_request = NULL;
258 wil->radio_wdev = wil->wdev; 262 wil->radio_wdev = wil->wdev;
259 mutex_unlock(&wil->p2p_wdev_mutex); 263 mutex_unlock(&wil->p2p_wdev_mutex);
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index b80c5d850e1e..4d92541913c0 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -426,15 +426,17 @@ static void wmi_evt_scan_complete(struct wil6210_priv *wil, int id,
426{ 426{
427 if (wil->scan_request) { 427 if (wil->scan_request) {
428 struct wmi_scan_complete_event *data = d; 428 struct wmi_scan_complete_event *data = d;
429 bool aborted = (data->status != WMI_SCAN_SUCCESS); 429 struct cfg80211_scan_info info = {
430 .aborted = (data->status != WMI_SCAN_SUCCESS),
431 };
430 432
431 wil_dbg_wmi(wil, "SCAN_COMPLETE(0x%08x)\n", data->status); 433 wil_dbg_wmi(wil, "SCAN_COMPLETE(0x%08x)\n", data->status);
432 wil_dbg_misc(wil, "Complete scan_request 0x%p aborted %d\n", 434 wil_dbg_misc(wil, "Complete scan_request 0x%p aborted %d\n",
433 wil->scan_request, aborted); 435 wil->scan_request, info.aborted);
434 436
435 del_timer_sync(&wil->scan_timer); 437 del_timer_sync(&wil->scan_timer);
436 mutex_lock(&wil->p2p_wdev_mutex); 438 mutex_lock(&wil->p2p_wdev_mutex);
437 cfg80211_scan_done(wil->scan_request, aborted); 439 cfg80211_scan_done(wil->scan_request, &info);
438 wil->radio_wdev = wil->wdev; 440 wil->radio_wdev = wil->wdev;
439 mutex_unlock(&wil->p2p_wdev_mutex); 441 mutex_unlock(&wil->p2p_wdev_mutex);
440 wil->scan_request = NULL; 442 wil->scan_request = NULL;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 264bd638a3d9..afe2b202040a 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -775,9 +775,13 @@ s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
775 if (!aborted) 775 if (!aborted)
776 cfg80211_sched_scan_results(cfg_to_wiphy(cfg)); 776 cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
777 } else if (scan_request) { 777 } else if (scan_request) {
778 struct cfg80211_scan_info info = {
779 .aborted = aborted,
780 };
781
778 brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n", 782 brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
779 aborted ? "Aborted" : "Done"); 783 aborted ? "Aborted" : "Done");
780 cfg80211_scan_done(scan_request, aborted); 784 cfg80211_scan_done(scan_request, &info);
781 } 785 }
782 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) 786 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
783 brcmf_dbg(SCAN, "Scan complete, probably P2P scan\n"); 787 brcmf_dbg(SCAN, "Scan complete, probably P2P scan\n");
diff --git a/drivers/net/wireless/intersil/orinoco/scan.c b/drivers/net/wireless/intersil/orinoco/scan.c
index d0ceb06c72d0..6d1d084854fb 100644
--- a/drivers/net/wireless/intersil/orinoco/scan.c
+++ b/drivers/net/wireless/intersil/orinoco/scan.c
@@ -237,7 +237,11 @@ void orinoco_add_hostscan_results(struct orinoco_private *priv,
237 237
238 scan_abort: 238 scan_abort:
239 if (priv->scan_request) { 239 if (priv->scan_request) {
240 cfg80211_scan_done(priv->scan_request, abort); 240 struct cfg80211_scan_info info = {
241 .aborted = abort,
242 };
243
244 cfg80211_scan_done(priv->scan_request, &info);
241 priv->scan_request = NULL; 245 priv->scan_request = NULL;
242 } 246 }
243} 247}
@@ -245,7 +249,11 @@ void orinoco_add_hostscan_results(struct orinoco_private *priv,
245void orinoco_scan_done(struct orinoco_private *priv, bool abort) 249void orinoco_scan_done(struct orinoco_private *priv, bool abort)
246{ 250{
247 if (priv->scan_request) { 251 if (priv->scan_request) {
248 cfg80211_scan_done(priv->scan_request, abort); 252 struct cfg80211_scan_info info = {
253 .aborted = abort,
254 };
255
256 cfg80211_scan_done(priv->scan_request, &info);
249 priv->scan_request = NULL; 257 priv->scan_request = NULL;
250 } 258 }
251} 259}
diff --git a/drivers/net/wireless/marvell/libertas/cfg.c b/drivers/net/wireless/marvell/libertas/cfg.c
index 776b44bfd93a..ea4802446618 100644
--- a/drivers/net/wireless/marvell/libertas/cfg.c
+++ b/drivers/net/wireless/marvell/libertas/cfg.c
@@ -796,10 +796,15 @@ void lbs_scan_done(struct lbs_private *priv)
796{ 796{
797 WARN_ON(!priv->scan_req); 797 WARN_ON(!priv->scan_req);
798 798
799 if (priv->internal_scan) 799 if (priv->internal_scan) {
800 kfree(priv->scan_req); 800 kfree(priv->scan_req);
801 else 801 } else {
802 cfg80211_scan_done(priv->scan_req, false); 802 struct cfg80211_scan_info info = {
803 .aborted = false,
804 };
805
806 cfg80211_scan_done(priv->scan_req, &info);
807 }
803 808
804 priv->scan_req = NULL; 809 priv->scan_req = NULL;
805} 810}
diff --git a/drivers/net/wireless/marvell/mwifiex/cmdevt.c b/drivers/net/wireless/marvell/mwifiex/cmdevt.c
index 6bc2011d8609..e7a21443647e 100644
--- a/drivers/net/wireless/marvell/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/marvell/mwifiex/cmdevt.c
@@ -1057,8 +1057,12 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
1057 if (!priv) 1057 if (!priv)
1058 continue; 1058 continue;
1059 if (priv->scan_request) { 1059 if (priv->scan_request) {
1060 struct cfg80211_scan_info info = {
1061 .aborted = true,
1062 };
1063
1060 mwifiex_dbg(adapter, WARN, "info: aborting scan\n"); 1064 mwifiex_dbg(adapter, WARN, "info: aborting scan\n");
1061 cfg80211_scan_done(priv->scan_request, 1); 1065 cfg80211_scan_done(priv->scan_request, &info);
1062 priv->scan_request = NULL; 1066 priv->scan_request = NULL;
1063 } 1067 }
1064 } 1068 }
@@ -1112,8 +1116,12 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter)
1112 if (!priv) 1116 if (!priv)
1113 continue; 1117 continue;
1114 if (priv->scan_request) { 1118 if (priv->scan_request) {
1119 struct cfg80211_scan_info info = {
1120 .aborted = true,
1121 };
1122
1115 mwifiex_dbg(adapter, WARN, "info: aborting scan\n"); 1123 mwifiex_dbg(adapter, WARN, "info: aborting scan\n");
1116 cfg80211_scan_done(priv->scan_request, 1); 1124 cfg80211_scan_done(priv->scan_request, &info);
1117 priv->scan_request = NULL; 1125 priv->scan_request = NULL;
1118 } 1126 }
1119 } 1127 }
diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c
index 0e280f879b58..db4925db39aa 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.c
+++ b/drivers/net/wireless/marvell/mwifiex/main.c
@@ -697,9 +697,13 @@ mwifiex_close(struct net_device *dev)
697 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 697 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
698 698
699 if (priv->scan_request) { 699 if (priv->scan_request) {
700 struct cfg80211_scan_info info = {
701 .aborted = true,
702 };
703
700 mwifiex_dbg(priv->adapter, INFO, 704 mwifiex_dbg(priv->adapter, INFO,
701 "aborting scan on ndo_stop\n"); 705 "aborting scan on ndo_stop\n");
702 cfg80211_scan_done(priv->scan_request, 1); 706 cfg80211_scan_done(priv->scan_request, &info);
703 priv->scan_request = NULL; 707 priv->scan_request = NULL;
704 priv->scan_aborting = true; 708 priv->scan_aborting = true;
705 } 709 }
diff --git a/drivers/net/wireless/marvell/mwifiex/scan.c b/drivers/net/wireless/marvell/mwifiex/scan.c
index bc5e52cebce1..fdd749110fcb 100644
--- a/drivers/net/wireless/marvell/mwifiex/scan.c
+++ b/drivers/net/wireless/marvell/mwifiex/scan.c
@@ -1956,9 +1956,13 @@ static void mwifiex_check_next_scan_command(struct mwifiex_private *priv)
1956 mwifiex_complete_scan(priv); 1956 mwifiex_complete_scan(priv);
1957 1957
1958 if (priv->scan_request) { 1958 if (priv->scan_request) {
1959 struct cfg80211_scan_info info = {
1960 .aborted = false,
1961 };
1962
1959 mwifiex_dbg(adapter, INFO, 1963 mwifiex_dbg(adapter, INFO,
1960 "info: notifying scan done\n"); 1964 "info: notifying scan done\n");
1961 cfg80211_scan_done(priv->scan_request, 0); 1965 cfg80211_scan_done(priv->scan_request, &info);
1962 priv->scan_request = NULL; 1966 priv->scan_request = NULL;
1963 } else { 1967 } else {
1964 priv->scan_aborting = false; 1968 priv->scan_aborting = false;
@@ -1977,9 +1981,13 @@ static void mwifiex_check_next_scan_command(struct mwifiex_private *priv)
1977 1981
1978 if (!adapter->active_scan_triggered) { 1982 if (!adapter->active_scan_triggered) {
1979 if (priv->scan_request) { 1983 if (priv->scan_request) {
1984 struct cfg80211_scan_info info = {
1985 .aborted = true,
1986 };
1987
1980 mwifiex_dbg(adapter, INFO, 1988 mwifiex_dbg(adapter, INFO,
1981 "info: aborting scan\n"); 1989 "info: aborting scan\n");
1982 cfg80211_scan_done(priv->scan_request, 1); 1990 cfg80211_scan_done(priv->scan_request, &info);
1983 priv->scan_request = NULL; 1991 priv->scan_request = NULL;
1984 } else { 1992 } else {
1985 priv->scan_aborting = false; 1993 priv->scan_aborting = false;
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 569918c485b4..603c90470225 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -2134,6 +2134,7 @@ static void rndis_get_scan_results(struct work_struct *work)
2134 struct rndis_wlan_private *priv = 2134 struct rndis_wlan_private *priv =
2135 container_of(work, struct rndis_wlan_private, scan_work.work); 2135 container_of(work, struct rndis_wlan_private, scan_work.work);
2136 struct usbnet *usbdev = priv->usbdev; 2136 struct usbnet *usbdev = priv->usbdev;
2137 struct cfg80211_scan_info info = {};
2137 int ret; 2138 int ret;
2138 2139
2139 netdev_dbg(usbdev->net, "get_scan_results\n"); 2140 netdev_dbg(usbdev->net, "get_scan_results\n");
@@ -2143,7 +2144,8 @@ static void rndis_get_scan_results(struct work_struct *work)
2143 2144
2144 ret = rndis_check_bssid_list(usbdev, NULL, NULL); 2145 ret = rndis_check_bssid_list(usbdev, NULL, NULL);
2145 2146
2146 cfg80211_scan_done(priv->scan_request, ret < 0); 2147 info.aborted = ret < 0;
2148 cfg80211_scan_done(priv->scan_request, &info);
2147 2149
2148 priv->scan_request = NULL; 2150 priv->scan_request = NULL;
2149} 2151}
@@ -3574,7 +3576,11 @@ static int rndis_wlan_stop(struct usbnet *usbdev)
3574 flush_workqueue(priv->workqueue); 3576 flush_workqueue(priv->workqueue);
3575 3577
3576 if (priv->scan_request) { 3578 if (priv->scan_request) {
3577 cfg80211_scan_done(priv->scan_request, true); 3579 struct cfg80211_scan_info info = {
3580 .aborted = true,
3581 };
3582
3583 cfg80211_scan_done(priv->scan_request, &info);
3578 priv->scan_request = NULL; 3584 priv->scan_request = NULL;
3579 } 3585 }
3580 3586
diff --git a/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c
index 0da559d929bc..d0ba3778990e 100644
--- a/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c
+++ b/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c
@@ -1256,10 +1256,15 @@ void rtw_cfg80211_indicate_scan_done(struct rtw_wdev_priv *pwdev_priv,
1256 DBG_8723A("%s with scan req\n", __func__); 1256 DBG_8723A("%s with scan req\n", __func__);
1257 1257
1258 if (pwdev_priv->scan_request->wiphy != 1258 if (pwdev_priv->scan_request->wiphy !=
1259 pwdev_priv->rtw_wdev->wiphy) 1259 pwdev_priv->rtw_wdev->wiphy) {
1260 DBG_8723A("error wiphy compare\n"); 1260 DBG_8723A("error wiphy compare\n");
1261 else 1261 } else {
1262 cfg80211_scan_done(pwdev_priv->scan_request, aborted); 1262 struct cfg80211_scan_info info = {
1263 .aborted = aborted,
1264 };
1265
1266 cfg80211_scan_done(pwdev_priv->scan_request, &info);
1267 }
1263 1268
1264 pwdev_priv->scan_request = NULL; 1269 pwdev_priv->scan_request = NULL;
1265 } else { 1270 } else {
diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
index 51aff4ff7d7c..a0d8e22e575b 100644
--- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
+++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
@@ -454,7 +454,11 @@ static void CfgScanResult(enum scan_event scan_event,
454 mutex_lock(&priv->scan_req_lock); 454 mutex_lock(&priv->scan_req_lock);
455 455
456 if (priv->pstrScanReq) { 456 if (priv->pstrScanReq) {
457 cfg80211_scan_done(priv->pstrScanReq, false); 457 struct cfg80211_scan_info info = {
458 .aborted = false,
459 };
460
461 cfg80211_scan_done(priv->pstrScanReq, &info);
458 priv->u32RcvdChCount = 0; 462 priv->u32RcvdChCount = 0;
459 priv->bCfgScanning = false; 463 priv->bCfgScanning = false;
460 priv->pstrScanReq = NULL; 464 priv->pstrScanReq = NULL;
@@ -464,10 +468,14 @@ static void CfgScanResult(enum scan_event scan_event,
464 mutex_lock(&priv->scan_req_lock); 468 mutex_lock(&priv->scan_req_lock);
465 469
466 if (priv->pstrScanReq) { 470 if (priv->pstrScanReq) {
471 struct cfg80211_scan_info info = {
472 .aborted = false,
473 };
474
467 update_scan_time(); 475 update_scan_time();
468 refresh_scan(priv, 1, false); 476 refresh_scan(priv, 1, false);
469 477
470 cfg80211_scan_done(priv->pstrScanReq, false); 478 cfg80211_scan_done(priv->pstrScanReq, &info);
471 priv->bCfgScanning = false; 479 priv->bCfgScanning = false;
472 priv->pstrScanReq = NULL; 480 priv->pstrScanReq = NULL;
473 } 481 }
diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c
index a6e6fb9f42e1..f46dfe6b24e8 100644
--- a/drivers/staging/wlan-ng/cfg80211.c
+++ b/drivers/staging/wlan-ng/cfg80211.c
@@ -338,6 +338,8 @@ static int prism2_scan(struct wiphy *wiphy,
338 struct p80211msg_dot11req_scan msg1; 338 struct p80211msg_dot11req_scan msg1;
339 struct p80211msg_dot11req_scan_results msg2; 339 struct p80211msg_dot11req_scan_results msg2;
340 struct cfg80211_bss *bss; 340 struct cfg80211_bss *bss;
341 struct cfg80211_scan_info info = {};
342
341 int result; 343 int result;
342 int err = 0; 344 int err = 0;
343 int numbss = 0; 345 int numbss = 0;
@@ -440,7 +442,8 @@ static int prism2_scan(struct wiphy *wiphy,
440 err = prism2_result2err(msg2.resultcode.data); 442 err = prism2_result2err(msg2.resultcode.data);
441 443
442exit: 444exit:
443 cfg80211_scan_done(request, err ? 1 : 0); 445 info.aborted = !!(err);
446 cfg80211_scan_done(request, &info);
444 priv->scan_request = NULL; 447 priv->scan_request = NULL;
445 return err; 448 return err;
446} 449}
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index fa4f0f793817..e2658e392a1f 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1424,6 +1424,21 @@ struct cfg80211_ssid {
1424}; 1424};
1425 1425
1426/** 1426/**
1427 * struct cfg80211_scan_info - information about completed scan
1428 * @scan_start_tsf: scan start time in terms of the TSF of the BSS that the
1429 * wireless device that requested the scan is connected to. If this
1430 * information is not available, this field is left zero.
1431 * @tsf_bssid: the BSSID according to which %scan_start_tsf is set.
1432 * @aborted: set to true if the scan was aborted for any reason,
1433 * userspace will be notified of that
1434 */
1435struct cfg80211_scan_info {
1436 u64 scan_start_tsf;
1437 u8 tsf_bssid[ETH_ALEN] __aligned(2);
1438 bool aborted;
1439};
1440
1441/**
1427 * struct cfg80211_scan_request - scan request description 1442 * struct cfg80211_scan_request - scan request description
1428 * 1443 *
1429 * @ssids: SSIDs to scan for (active scan only) 1444 * @ssids: SSIDs to scan for (active scan only)
@@ -1433,12 +1448,17 @@ struct cfg80211_ssid {
1433 * @scan_width: channel width for scanning 1448 * @scan_width: channel width for scanning
1434 * @ie: optional information element(s) to add into Probe Request or %NULL 1449 * @ie: optional information element(s) to add into Probe Request or %NULL
1435 * @ie_len: length of ie in octets 1450 * @ie_len: length of ie in octets
1451 * @duration: how long to listen on each channel, in TUs. If
1452 * %duration_mandatory is not set, this is the maximum dwell time and
1453 * the actual dwell time may be shorter.
1454 * @duration_mandatory: if set, the scan duration must be as specified by the
1455 * %duration field.
1436 * @flags: bit field of flags controlling operation 1456 * @flags: bit field of flags controlling operation
1437 * @rates: bitmap of rates to advertise for each band 1457 * @rates: bitmap of rates to advertise for each band
1438 * @wiphy: the wiphy this was for 1458 * @wiphy: the wiphy this was for
1439 * @scan_start: time (in jiffies) when the scan started 1459 * @scan_start: time (in jiffies) when the scan started
1440 * @wdev: the wireless device to scan for 1460 * @wdev: the wireless device to scan for
1441 * @aborted: (internal) scan request was notified as aborted 1461 * @info: (internal) information about completed scan
1442 * @notified: (internal) scan request was notified as done or aborted 1462 * @notified: (internal) scan request was notified as done or aborted
1443 * @no_cck: used to send probe requests at non CCK rate in 2GHz band 1463 * @no_cck: used to send probe requests at non CCK rate in 2GHz band
1444 * @mac_addr: MAC address used with randomisation 1464 * @mac_addr: MAC address used with randomisation
@@ -1454,6 +1474,8 @@ struct cfg80211_scan_request {
1454 enum nl80211_bss_scan_width scan_width; 1474 enum nl80211_bss_scan_width scan_width;
1455 const u8 *ie; 1475 const u8 *ie;
1456 size_t ie_len; 1476 size_t ie_len;
1477 u16 duration;
1478 bool duration_mandatory;
1457 u32 flags; 1479 u32 flags;
1458 1480
1459 u32 rates[NUM_NL80211_BANDS]; 1481 u32 rates[NUM_NL80211_BANDS];
@@ -1467,7 +1489,8 @@ struct cfg80211_scan_request {
1467 /* internal */ 1489 /* internal */
1468 struct wiphy *wiphy; 1490 struct wiphy *wiphy;
1469 unsigned long scan_start; 1491 unsigned long scan_start;
1470 bool aborted, notified; 1492 struct cfg80211_scan_info info;
1493 bool notified;
1471 bool no_cck; 1494 bool no_cck;
1472 1495
1473 /* keep last */ 1496 /* keep last */
@@ -1600,12 +1623,19 @@ enum cfg80211_signal_type {
1600 * buffered on the device) and be accurate to about 10ms. 1623 * buffered on the device) and be accurate to about 10ms.
1601 * If the frame isn't buffered, just passing the return value of 1624 * If the frame isn't buffered, just passing the return value of
1602 * ktime_get_boot_ns() is likely appropriate. 1625 * ktime_get_boot_ns() is likely appropriate.
1626 * @parent_tsf: the time at the start of reception of the first octet of the
1627 * timestamp field of the frame. The time is the TSF of the BSS specified
1628 * by %parent_bssid.
1629 * @parent_bssid: the BSS according to which %parent_tsf is set. This is set to
1630 * the BSS that requested the scan in which the beacon/probe was received.
1603 */ 1631 */
1604struct cfg80211_inform_bss { 1632struct cfg80211_inform_bss {
1605 struct ieee80211_channel *chan; 1633 struct ieee80211_channel *chan;
1606 enum nl80211_bss_scan_width scan_width; 1634 enum nl80211_bss_scan_width scan_width;
1607 s32 signal; 1635 s32 signal;
1608 u64 boottime_ns; 1636 u64 boottime_ns;
1637 u64 parent_tsf;
1638 u8 parent_bssid[ETH_ALEN] __aligned(2);
1609}; 1639};
1610 1640
1611/** 1641/**
@@ -4067,10 +4097,10 @@ const char *reg_initiator_name(enum nl80211_reg_initiator initiator);
4067 * cfg80211_scan_done - notify that scan finished 4097 * cfg80211_scan_done - notify that scan finished
4068 * 4098 *
4069 * @request: the corresponding scan request 4099 * @request: the corresponding scan request
4070 * @aborted: set to true if the scan was aborted for any reason, 4100 * @info: information about the completed scan
4071 * userspace will be notified of that
4072 */ 4101 */
4073void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted); 4102void cfg80211_scan_done(struct cfg80211_scan_request *request,
4103 struct cfg80211_scan_info *info);
4074 4104
4075/** 4105/**
4076 * cfg80211_sched_scan_results - notify that new scan results are available 4106 * cfg80211_sched_scan_results - notify that new scan results are available
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 1d7da7888dcf..b39ccab45333 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1848,6 +1848,22 @@ enum nl80211_commands {
1848 * to turn that feature off set an invalid mac address 1848 * to turn that feature off set an invalid mac address
1849 * (e.g. FF:FF:FF:FF:FF:FF) 1849 * (e.g. FF:FF:FF:FF:FF:FF)
1850 * 1850 *
1851 * @NL80211_ATTR_SCAN_START_TIME_TSF: The time at which the scan was actually
1852 * started (u64). The time is the TSF of the BSS the interface that
1853 * requested the scan is connected to (if available, otherwise this
1854 * attribute must not be included).
1855 * @NL80211_ATTR_SCAN_START_TIME_TSF_BSSID: The BSS according to which
1856 * %NL80211_ATTR_SCAN_START_TIME_TSF is set.
1857 * @NL80211_ATTR_MEASUREMENT_DURATION: measurement duration in TUs (u16). If
1858 * %NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY is not set, this is the
1859 * maximum measurement duration allowed. This attribute is used with
1860 * measurement requests. It can also be used with %NL80211_CMD_TRIGGER_SCAN
1861 * if the scan is used for beacon report radio measurement.
1862 * @NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY: flag attribute that indicates
1863 * that the duration specified with %NL80211_ATTR_MEASUREMENT_DURATION is
1864 * mandatory. If this flag is not set, the duration is the maximum duration
1865 * and the actual measurement duration may be shorter.
1866 *
1851 * @NUM_NL80211_ATTR: total number of nl80211_attrs available 1867 * @NUM_NL80211_ATTR: total number of nl80211_attrs available
1852 * @NL80211_ATTR_MAX: highest attribute number currently defined 1868 * @NL80211_ATTR_MAX: highest attribute number currently defined
1853 * @__NL80211_ATTR_AFTER_LAST: internal use 1869 * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2235,6 +2251,11 @@ enum nl80211_attrs {
2235 NL80211_ATTR_MU_MIMO_GROUP_DATA, 2251 NL80211_ATTR_MU_MIMO_GROUP_DATA,
2236 NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR, 2252 NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR,
2237 2253
2254 NL80211_ATTR_SCAN_START_TIME_TSF,
2255 NL80211_ATTR_SCAN_START_TIME_TSF_BSSID,
2256 NL80211_ATTR_MEASUREMENT_DURATION,
2257 NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY,
2258
2238 /* add attributes here, update the policy in nl80211.c */ 2259 /* add attributes here, update the policy in nl80211.c */
2239 2260
2240 __NL80211_ATTR_AFTER_LAST, 2261 __NL80211_ATTR_AFTER_LAST,
@@ -3496,6 +3517,12 @@ enum nl80211_bss_scan_width {
3496 * was last updated by a received frame. The value is expected to be 3517 * was last updated by a received frame. The value is expected to be
3497 * accurate to about 10ms. (u64, nanoseconds) 3518 * accurate to about 10ms. (u64, nanoseconds)
3498 * @NL80211_BSS_PAD: attribute used for padding for 64-bit alignment 3519 * @NL80211_BSS_PAD: attribute used for padding for 64-bit alignment
3520 * @NL80211_BSS_PARENT_TSF: the time at the start of reception of the first
3521 * octet of the timestamp field of the last beacon/probe received for
3522 * this BSS. The time is the TSF of the BSS specified by
3523 * @NL80211_BSS_PARENT_BSSID. (u64).
3524 * @NL80211_BSS_PARENT_BSSID: the BSS according to which @NL80211_BSS_PARENT_TSF
3525 * is set.
3499 * @__NL80211_BSS_AFTER_LAST: internal 3526 * @__NL80211_BSS_AFTER_LAST: internal
3500 * @NL80211_BSS_MAX: highest BSS attribute 3527 * @NL80211_BSS_MAX: highest BSS attribute
3501 */ 3528 */
@@ -3517,6 +3544,8 @@ enum nl80211_bss {
3517 NL80211_BSS_PRESP_DATA, 3544 NL80211_BSS_PRESP_DATA,
3518 NL80211_BSS_LAST_SEEN_BOOTTIME, 3545 NL80211_BSS_LAST_SEEN_BOOTTIME,
3519 NL80211_BSS_PAD, 3546 NL80211_BSS_PAD,
3547 NL80211_BSS_PARENT_TSF,
3548 NL80211_BSS_PARENT_BSSID,
3520 3549
3521 /* keep last */ 3550 /* keep last */
3522 __NL80211_BSS_AFTER_LAST, 3551 __NL80211_BSS_AFTER_LAST,
@@ -4507,6 +4536,16 @@ enum nl80211_feature_flags {
4507 * %NL80211_ATTR_MU_MIMO_GROUP_DATA attribute, 4536 * %NL80211_ATTR_MU_MIMO_GROUP_DATA attribute,
4508 * or can be configured to follow a station by configuring the 4537 * or can be configured to follow a station by configuring the
4509 * %NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR attribute. 4538 * %NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR attribute.
4539 * @NL80211_EXT_FEATURE_SCAN_START_TIME: This driver includes the actual
4540 * time the scan started in scan results event. The time is the TSF of
4541 * the BSS that the interface that requested the scan is connected to
4542 * (if available).
4543 * @NL80211_EXT_FEATURE_BSS_PARENT_TSF: Per BSS, this driver reports the
4544 * time the last beacon/probe was received. The time is the TSF of the
4545 * BSS that the interface that requested the scan is connected to
4546 * (if available).
4547 * @NL80211_EXT_FEATURE_SET_SCAN_DWELL: This driver supports configuration of
4548 * channel dwell time.
4510 * 4549 *
4511 * @NUM_NL80211_EXT_FEATURES: number of extended features. 4550 * @NUM_NL80211_EXT_FEATURES: number of extended features.
4512 * @MAX_NL80211_EXT_FEATURES: highest extended feature index. 4551 * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
@@ -4515,6 +4554,9 @@ enum nl80211_ext_feature_index {
4515 NL80211_EXT_FEATURE_VHT_IBSS, 4554 NL80211_EXT_FEATURE_VHT_IBSS,
4516 NL80211_EXT_FEATURE_RRM, 4555 NL80211_EXT_FEATURE_RRM,
4517 NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER, 4556 NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER,
4557 NL80211_EXT_FEATURE_SCAN_START_TIME,
4558 NL80211_EXT_FEATURE_BSS_PARENT_TSF,
4559 NL80211_EXT_FEATURE_SET_SCAN_DWELL,
4518 4560
4519 /* add new features before the definition below */ 4561 /* add new features before the definition below */
4520 NUM_NL80211_EXT_FEATURES, 4562 NUM_NL80211_EXT_FEATURES,
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index f9648ef9e31f..4ec1c52a1549 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -353,8 +353,13 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
353 scan_req = rcu_dereference_protected(local->scan_req, 353 scan_req = rcu_dereference_protected(local->scan_req,
354 lockdep_is_held(&local->mtx)); 354 lockdep_is_held(&local->mtx));
355 355
356 if (scan_req != local->int_scan_req) 356 if (scan_req != local->int_scan_req) {
357 cfg80211_scan_done(scan_req, aborted); 357 struct cfg80211_scan_info info = {
358 .aborted = aborted,
359 };
360
361 cfg80211_scan_done(scan_req, &info);
362 }
358 RCU_INIT_POINTER(local->scan_req, NULL); 363 RCU_INIT_POINTER(local->scan_req, NULL);
359 364
360 scan_sdata = rcu_dereference_protected(local->scan_sdata, 365 scan_sdata = rcu_dereference_protected(local->scan_sdata,
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 39d9abd309ea..7645e97362c0 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -220,7 +220,7 @@ void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev,
220 220
221 if (rdev->scan_req && rdev->scan_req->wdev == wdev) { 221 if (rdev->scan_req && rdev->scan_req->wdev == wdev) {
222 if (WARN_ON(!rdev->scan_req->notified)) 222 if (WARN_ON(!rdev->scan_req->notified))
223 rdev->scan_req->aborted = true; 223 rdev->scan_req->info.aborted = true;
224 ___cfg80211_scan_done(rdev, false); 224 ___cfg80211_scan_done(rdev, false);
225 } 225 }
226} 226}
@@ -1087,7 +1087,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
1087 cfg80211_update_iface_num(rdev, wdev->iftype, -1); 1087 cfg80211_update_iface_num(rdev, wdev->iftype, -1);
1088 if (rdev->scan_req && rdev->scan_req->wdev == wdev) { 1088 if (rdev->scan_req && rdev->scan_req->wdev == wdev) {
1089 if (WARN_ON(!rdev->scan_req->notified)) 1089 if (WARN_ON(!rdev->scan_req->notified))
1090 rdev->scan_req->aborted = true; 1090 rdev->scan_req->info.aborted = true;
1091 ___cfg80211_scan_done(rdev, false); 1091 ___cfg80211_scan_done(rdev, false);
1092 } 1092 }
1093 1093
diff --git a/net/wireless/core.h b/net/wireless/core.h
index a4d547f99f8d..eee91443924d 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -141,6 +141,18 @@ struct cfg80211_internal_bss {
141 unsigned long refcount; 141 unsigned long refcount;
142 atomic_t hold; 142 atomic_t hold;
143 143
144 /* time at the start of the reception of the first octet of the
145 * timestamp field of the last beacon/probe received for this BSS.
146 * The time is the TSF of the BSS specified by %parent_bssid.
147 */
148 u64 parent_tsf;
149
150 /* the BSS according to which %parent_tsf is set. This is set to
151 * the BSS that the interface that requested the scan was connected to
152 * when the beacon/probe was received.
153 */
154 u8 parent_bssid[ETH_ALEN] __aligned(2);
155
144 /* must be last because of priv member */ 156 /* must be last because of priv member */
145 struct cfg80211_bss pub; 157 struct cfg80211_bss pub;
146}; 158};
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 447026f8cc76..c53b5462ed00 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -6223,6 +6223,19 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
6223 } 6223 }
6224 } 6224 }
6225 6225
6226 if (info->attrs[NL80211_ATTR_MEASUREMENT_DURATION]) {
6227 if (!wiphy_ext_feature_isset(wiphy,
6228 NL80211_EXT_FEATURE_SET_SCAN_DWELL)) {
6229 err = -EOPNOTSUPP;
6230 goto out_free;
6231 }
6232
6233 request->duration =
6234 nla_get_u16(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION]);
6235 request->duration_mandatory =
6236 nla_get_flag(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY]);
6237 }
6238
6226 if (info->attrs[NL80211_ATTR_SCAN_FLAGS]) { 6239 if (info->attrs[NL80211_ATTR_SCAN_FLAGS]) {
6227 request->flags = nla_get_u32( 6240 request->flags = nla_get_u32(
6228 info->attrs[NL80211_ATTR_SCAN_FLAGS]); 6241 info->attrs[NL80211_ATTR_SCAN_FLAGS]);
@@ -7056,6 +7069,13 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
7056 jiffies_to_msecs(jiffies - intbss->ts))) 7069 jiffies_to_msecs(jiffies - intbss->ts)))
7057 goto nla_put_failure; 7070 goto nla_put_failure;
7058 7071
7072 if (intbss->parent_tsf &&
7073 (nla_put_u64_64bit(msg, NL80211_BSS_PARENT_TSF,
7074 intbss->parent_tsf, NL80211_BSS_PAD) ||
7075 nla_put(msg, NL80211_BSS_PARENT_BSSID, ETH_ALEN,
7076 intbss->parent_bssid)))
7077 goto nla_put_failure;
7078
7059 if (intbss->ts_boottime && 7079 if (intbss->ts_boottime &&
7060 nla_put_u64_64bit(msg, NL80211_BSS_LAST_SEEN_BOOTTIME, 7080 nla_put_u64_64bit(msg, NL80211_BSS_LAST_SEEN_BOOTTIME,
7061 intbss->ts_boottime, NL80211_BSS_PAD)) 7081 intbss->ts_boottime, NL80211_BSS_PAD))
@@ -11829,6 +11849,13 @@ static int nl80211_add_scan_req(struct sk_buff *msg,
11829 nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags)) 11849 nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags))
11830 goto nla_put_failure; 11850 goto nla_put_failure;
11831 11851
11852 if (req->info.scan_start_tsf &&
11853 (nla_put_u64_64bit(msg, NL80211_ATTR_SCAN_START_TIME_TSF,
11854 req->info.scan_start_tsf, NL80211_BSS_PAD) ||
11855 nla_put(msg, NL80211_ATTR_SCAN_START_TIME_TSF_BSSID, ETH_ALEN,
11856 req->info.tsf_bssid)))
11857 goto nla_put_failure;
11858
11832 return 0; 11859 return 0;
11833 nla_put_failure: 11860 nla_put_failure:
11834 return -ENOBUFS; 11861 return -ENOBUFS;
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index ef2955c89a00..0358e12be54b 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * Copyright 2008 Johannes Berg <johannes@sipsolutions.net> 4 * Copyright 2008 Johannes Berg <johannes@sipsolutions.net>
5 * Copyright 2013-2014 Intel Mobile Communications GmbH 5 * Copyright 2013-2014 Intel Mobile Communications GmbH
6 * Copyright 2016 Intel Deutschland GmbH
6 */ 7 */
7#include <linux/kernel.h> 8#include <linux/kernel.h>
8#include <linux/slab.h> 9#include <linux/slab.h>
@@ -194,7 +195,7 @@ void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev,
194 if (wdev->netdev) 195 if (wdev->netdev)
195 cfg80211_sme_scan_done(wdev->netdev); 196 cfg80211_sme_scan_done(wdev->netdev);
196 197
197 if (!request->aborted && 198 if (!request->info.aborted &&
198 request->flags & NL80211_SCAN_FLAG_FLUSH) { 199 request->flags & NL80211_SCAN_FLAG_FLUSH) {
199 /* flush entries from previous scans */ 200 /* flush entries from previous scans */
200 spin_lock_bh(&rdev->bss_lock); 201 spin_lock_bh(&rdev->bss_lock);
@@ -202,10 +203,10 @@ void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev,
202 spin_unlock_bh(&rdev->bss_lock); 203 spin_unlock_bh(&rdev->bss_lock);
203 } 204 }
204 205
205 msg = nl80211_build_scan_msg(rdev, wdev, request->aborted); 206 msg = nl80211_build_scan_msg(rdev, wdev, request->info.aborted);
206 207
207#ifdef CONFIG_CFG80211_WEXT 208#ifdef CONFIG_CFG80211_WEXT
208 if (wdev->netdev && !request->aborted) { 209 if (wdev->netdev && !request->info.aborted) {
209 memset(&wrqu, 0, sizeof(wrqu)); 210 memset(&wrqu, 0, sizeof(wrqu));
210 211
211 wireless_send_event(wdev->netdev, SIOCGIWSCAN, &wrqu, NULL); 212 wireless_send_event(wdev->netdev, SIOCGIWSCAN, &wrqu, NULL);
@@ -236,12 +237,13 @@ void __cfg80211_scan_done(struct work_struct *wk)
236 rtnl_unlock(); 237 rtnl_unlock();
237} 238}
238 239
239void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted) 240void cfg80211_scan_done(struct cfg80211_scan_request *request,
241 struct cfg80211_scan_info *info)
240{ 242{
241 trace_cfg80211_scan_done(request, aborted); 243 trace_cfg80211_scan_done(request, info);
242 WARN_ON(request != wiphy_to_rdev(request->wiphy)->scan_req); 244 WARN_ON(request != wiphy_to_rdev(request->wiphy)->scan_req);
243 245
244 request->aborted = aborted; 246 request->info = *info;
245 request->notified = true; 247 request->notified = true;
246 queue_work(cfg80211_wq, &wiphy_to_rdev(request->wiphy)->scan_done_wk); 248 queue_work(cfg80211_wq, &wiphy_to_rdev(request->wiphy)->scan_done_wk);
247} 249}
@@ -843,6 +845,8 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev,
843 found->pub.capability = tmp->pub.capability; 845 found->pub.capability = tmp->pub.capability;
844 found->ts = tmp->ts; 846 found->ts = tmp->ts;
845 found->ts_boottime = tmp->ts_boottime; 847 found->ts_boottime = tmp->ts_boottime;
848 found->parent_tsf = tmp->parent_tsf;
849 ether_addr_copy(found->parent_bssid, tmp->parent_bssid);
846 } else { 850 } else {
847 struct cfg80211_internal_bss *new; 851 struct cfg80211_internal_bss *new;
848 struct cfg80211_internal_bss *hidden; 852 struct cfg80211_internal_bss *hidden;
@@ -1086,6 +1090,8 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
1086 tmp.pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int); 1090 tmp.pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int);
1087 tmp.pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info); 1091 tmp.pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
1088 tmp.ts_boottime = data->boottime_ns; 1092 tmp.ts_boottime = data->boottime_ns;
1093 tmp.parent_tsf = data->parent_tsf;
1094 ether_addr_copy(tmp.parent_bssid, data->parent_bssid);
1089 1095
1090 signal_valid = abs(data->chan->center_freq - channel->center_freq) <= 1096 signal_valid = abs(data->chan->center_freq - channel->center_freq) <=
1091 wiphy->max_adj_channel_rssi_comp; 1097 wiphy->max_adj_channel_rssi_comp;
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 3c1091ae6c36..72b5255cefe2 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -2642,8 +2642,9 @@ TRACE_EVENT(cfg80211_tdls_oper_request,
2642 ); 2642 );
2643 2643
2644TRACE_EVENT(cfg80211_scan_done, 2644TRACE_EVENT(cfg80211_scan_done,
2645 TP_PROTO(struct cfg80211_scan_request *request, bool aborted), 2645 TP_PROTO(struct cfg80211_scan_request *request,
2646 TP_ARGS(request, aborted), 2646 struct cfg80211_scan_info *info),
2647 TP_ARGS(request, info),
2647 TP_STRUCT__entry( 2648 TP_STRUCT__entry(
2648 __field(u32, n_channels) 2649 __field(u32, n_channels)
2649 __dynamic_array(u8, ie, request ? request->ie_len : 0) 2650 __dynamic_array(u8, ie, request ? request->ie_len : 0)
@@ -2652,6 +2653,8 @@ TRACE_EVENT(cfg80211_scan_done,
2652 MAC_ENTRY(wiphy_mac) 2653 MAC_ENTRY(wiphy_mac)
2653 __field(bool, no_cck) 2654 __field(bool, no_cck)
2654 __field(bool, aborted) 2655 __field(bool, aborted)
2656 __field(u64, scan_start_tsf)
2657 MAC_ENTRY(tsf_bssid)
2655 ), 2658 ),
2656 TP_fast_assign( 2659 TP_fast_assign(
2657 if (request) { 2660 if (request) {
@@ -2666,9 +2669,16 @@ TRACE_EVENT(cfg80211_scan_done,
2666 request->wiphy->perm_addr); 2669 request->wiphy->perm_addr);
2667 __entry->no_cck = request->no_cck; 2670 __entry->no_cck = request->no_cck;
2668 } 2671 }
2669 __entry->aborted = aborted; 2672 if (info) {
2673 __entry->aborted = info->aborted;
2674 __entry->scan_start_tsf = info->scan_start_tsf;
2675 MAC_ASSIGN(tsf_bssid, info->tsf_bssid);
2676 }
2670 ), 2677 ),
2671 TP_printk("aborted: %s", BOOL_TO_STR(__entry->aborted)) 2678 TP_printk("aborted: %s, scan start (TSF): %llu, tsf_bssid: " MAC_PR_FMT,
2679 BOOL_TO_STR(__entry->aborted),
2680 (unsigned long long)__entry->scan_start_tsf,
2681 MAC_PR_ARG(tsf_bssid))
2672); 2682);
2673 2683
2674DEFINE_EVENT(wiphy_only_evt, cfg80211_sched_scan_results, 2684DEFINE_EVENT(wiphy_only_evt, cfg80211_sched_scan_results,
@@ -2721,6 +2731,8 @@ TRACE_EVENT(cfg80211_inform_bss_frame,
2721 __dynamic_array(u8, mgmt, len) 2731 __dynamic_array(u8, mgmt, len)
2722 __field(s32, signal) 2732 __field(s32, signal)
2723 __field(u64, ts_boottime) 2733 __field(u64, ts_boottime)
2734 __field(u64, parent_tsf)
2735 MAC_ENTRY(parent_bssid)
2724 ), 2736 ),
2725 TP_fast_assign( 2737 TP_fast_assign(
2726 WIPHY_ASSIGN; 2738 WIPHY_ASSIGN;
@@ -2730,10 +2742,15 @@ TRACE_EVENT(cfg80211_inform_bss_frame,
2730 memcpy(__get_dynamic_array(mgmt), mgmt, len); 2742 memcpy(__get_dynamic_array(mgmt), mgmt, len);
2731 __entry->signal = data->signal; 2743 __entry->signal = data->signal;
2732 __entry->ts_boottime = data->boottime_ns; 2744 __entry->ts_boottime = data->boottime_ns;
2733 ), 2745 __entry->parent_tsf = data->parent_tsf;
2734 TP_printk(WIPHY_PR_FMT ", " CHAN_PR_FMT "(scan_width: %d) signal: %d, tsb:%llu", 2746 MAC_ASSIGN(parent_bssid, data->parent_bssid);
2735 WIPHY_PR_ARG, CHAN_PR_ARG, __entry->scan_width, 2747 ),
2736 __entry->signal, (unsigned long long)__entry->ts_boottime) 2748 TP_printk(WIPHY_PR_FMT ", " CHAN_PR_FMT
2749 "(scan_width: %d) signal: %d, tsb:%llu, detect_tsf:%llu, tsf_bssid: "
2750 MAC_PR_FMT, WIPHY_PR_ARG, CHAN_PR_ARG, __entry->scan_width,
2751 __entry->signal, (unsigned long long)__entry->ts_boottime,
2752 (unsigned long long)__entry->parent_tsf,
2753 MAC_PR_ARG(parent_bssid))
2737); 2754);
2738 2755
2739DECLARE_EVENT_CLASS(cfg80211_bss_evt, 2756DECLARE_EVENT_CLASS(cfg80211_bss_evt,