diff options
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, | |||
| 1069 | void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted) | 1073 | void 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 | ||
| 1091 | out: | 1098 | out: |
| 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, | |||
| 245 | void orinoco_scan_done(struct orinoco_private *priv, bool abort) | 249 | void 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 | ||
| 442 | exit: | 444 | exit: |
| 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 | */ | ||
| 1435 | struct 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 | */ |
| 1604 | struct cfg80211_inform_bss { | 1632 | struct 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 | */ |
| 4073 | void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted); | 4102 | void 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 | ||
| 239 | void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted) | 240 | void 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 | ||
| 2644 | TRACE_EVENT(cfg80211_scan_done, | 2644 | TRACE_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 | ||
| 2674 | DEFINE_EVENT(wiphy_only_evt, cfg80211_sched_scan_results, | 2684 | DEFINE_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 | ||
| 2739 | DECLARE_EVENT_CLASS(cfg80211_bss_evt, | 2756 | DECLARE_EVENT_CLASS(cfg80211_bss_evt, |
