History

nl80211: support beacon report scanning

Beacon report radio measurement requires reporting observed BSSs on the channels specified in the beacon request. If the measurement mode is set to passive or active, it requires actually performing a scan (passive or active, accordingly), and reporting the time that the scan was started and the time each beacon/probe was received (both in terms of TSF of the BSS of the requesting AP). If the request mode is table, this information is optional. In addition, the radio measurement request specifies the channel dwell time for the measurement. In order to use scan for beacon report when the mode is active or passive, add a parameter to scan request that specifies the channel dwell time, and add scan start time and beacon received time to scan results information. Supporting beacon report is required for Multi Band Operation (MBO).

Avraham Stern committed 10 years ago

Commit 1d762501 parent f1724b023 files · +279 −52Browse files

Unified · Split

23 files
  1. drivers/net/wireless/ath/ath6kl/cfg80211.c +14 −3
  2. drivers/net/wireless/ath/wil6210/cfg80211.c +5 −1
  3. drivers/net/wireless/ath/wil6210/main.c +10 −2
  4. drivers/net/wireless/ath/wil6210/p2p.c +5 −1
  5. drivers/net/wireless/ath/wil6210/wmi.c +5 −3
  6. drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +5 −1
  7. drivers/net/wireless/intersil/orinoco/scan.c +10 −2
  8. drivers/net/wireless/marvell/libertas/cfg.c +8 −3
  9. drivers/net/wireless/marvell/mwifiex/cmdevt.c +10 −2
  10. drivers/net/wireless/marvell/mwifiex/main.c +5 −1
  11. drivers/net/wireless/marvell/mwifiex/scan.c +10 −2
  12. drivers/net/wireless/rndis_wlan.c +8 −2
  13. drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c +8 −3
  14. drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +10 −2
  15. drivers/staging/wlan-ng/cfg80211.c +4 −1
  16. include/net/cfg80211.h +35 −5
  17. include/uapi/linux/nl80211.h +42 −0
  18. net/mac80211/scan.c +7 −2
  19. net/wireless/core.c +2 −2
  20. net/wireless/core.h +12 −0
  21. net/wireless/nl80211.c +27 −0
  22. net/wireless/scan.c +12 −6
  23. net/wireless/trace.h +25 −8
drivers/net/wireless/ath/ath6kl/cfg80211.c+14−3
@@ -859,7 +859,11 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason, · 858 unmodified lines
859859 struct ath6kl *ar = vif->ar;
860860
861861 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);
863867 vif->scan_req = NULL;
864868 }
865869
@@ -1069,6 +1073,9 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, · 203 unmodified lines
10691073 void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted)
10701074 {
10711075 struct ath6kl *ar = vif->ar;
1076+ struct cfg80211_scan_info info = {
1077+ .aborted = aborted,
1078+ };
10721079 int i;
10731080
10741081 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) · 14 unmodified lines
10891096 }
10901097
10911098 out:
1092− cfg80211_scan_done(vif->scan_req, aborted);
1099+ cfg80211_scan_done(vif->scan_req, &info);
10931100 vif->scan_req = NULL;
10941101 }
10951102
@@ -3614,7 +3621,11 @@ void ath6kl_cfg80211_vif_stop(struct ath6kl_vif *vif, bool wmi_ready) · 2518 unmodified lines
36143621 }
36153622
36163623 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);
36183629 vif->scan_req = NULL;
36193630 }
36203631
drivers/net/wireless/ath/wil6210/cfg80211.c+5−1
@@ -1369,7 +1369,11 @@ static void wil_cfg80211_stop_p2p_device(struct wiphy *wiphy, · 1368 unmodified lines
13691369 mutex_lock(&wil->mutex);
13701370 started = wil_p2p_stop_discovery(wil);
13711371 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);
13731377 wil->scan_request = NULL;
13741378 wil->radio_wdev = wil->wdev;
13751379 }
drivers/net/wireless/ath/wil6210/main.c+10−2
@@ -850,10 +850,14 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) · 849 unmodified lines
850850 mutex_unlock(&wil->wmi_mutex);
851851
852852 if (wil->scan_request) {
853+ struct cfg80211_scan_info info = {
854+ .aborted = true,
855+ };
856+
853857 wil_dbg_misc(wil, "Abort scan_request 0x%p\n",
854858 wil->scan_request);
855859 del_timer_sync(&wil->scan_timer);
856− cfg80211_scan_done(wil->scan_request, true);
860+ cfg80211_scan_done(wil->scan_request, &info);
857861 wil->scan_request = NULL;
858862 }
859863
@@ -1049,10 +1053,14 @@ int __wil_down(struct wil6210_priv *wil) · 189 unmodified lines
10491053 (void)wil_p2p_stop_discovery(wil);
10501054
10511055 if (wil->scan_request) {
1056+ struct cfg80211_scan_info info = {
1057+ .aborted = true,
1058+ };
1059+
10521060 wil_dbg_misc(wil, "Abort scan_request 0x%p\n",
10531061 wil->scan_request);
10541062 del_timer_sync(&wil->scan_timer);
1055− cfg80211_scan_done(wil->scan_request, true);
1063+ cfg80211_scan_done(wil->scan_request, &info);
10561064 wil->scan_request = NULL;
10571065 }
10581066
drivers/net/wireless/ath/wil6210/p2p.c+5−1
@@ -252,8 +252,12 @@ void wil_p2p_search_expired(struct work_struct *work) · 251 unmodified lines
252252 mutex_unlock(&wil->mutex);
253253
254254 if (started) {
255+ struct cfg80211_scan_info info = {
256+ .aborted = false,
257+ };
258+
255259 mutex_lock(&wil->p2p_wdev_mutex);
256− cfg80211_scan_done(wil->scan_request, 0);
260+ cfg80211_scan_done(wil->scan_request, &info);
257261 wil->scan_request = NULL;
258262 wil->radio_wdev = wil->wdev;
259263 mutex_unlock(&wil->p2p_wdev_mutex);
drivers/net/wireless/ath/wil6210/wmi.c+5−3
@@ -426,15 +426,17 @@ static void wmi_evt_scan_complete(struct wil6210_priv *wil, int id, · 425 unmodified lines
426426 {
427427 if (wil->scan_request) {
428428 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+ };
430432
431433 wil_dbg_wmi(wil, "SCAN_COMPLETE(0x%08x)\n", data->status);
432434 wil_dbg_misc(wil, "Complete scan_request 0x%p aborted %d\n",
433− wil->scan_request, aborted);
435+ wil->scan_request, info.aborted);
434436
435437 del_timer_sync(&wil->scan_timer);
436438 mutex_lock(&wil->p2p_wdev_mutex);
437− cfg80211_scan_done(wil->scan_request, aborted);
439+ cfg80211_scan_done(wil->scan_request, &info);
438440 wil->radio_wdev = wil->wdev;
439441 mutex_unlock(&wil->p2p_wdev_mutex);
440442 wil->scan_request = NULL;
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c+5−1
@@ -775,9 +775,13 @@ s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg, · 774 unmodified lines
775775 if (!aborted)
776776 cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
777777 } else if (scan_request) {
778+ struct cfg80211_scan_info info = {
779+ .aborted = aborted,
780+ };
781+
778782 brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
779783 aborted ? "Aborted" : "Done");
780− cfg80211_scan_done(scan_request, aborted);
784+ cfg80211_scan_done(scan_request, &info);
781785 }
782786 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
783787 brcmf_dbg(SCAN, "Scan complete, probably P2P scan\n");
drivers/net/wireless/intersil/orinoco/scan.c+10−2
@@ -237,7 +237,11 @@ void orinoco_add_hostscan_results(struct orinoco_private *priv, · 236 unmodified lines
237237
238238 scan_abort:
239239 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);
241245 priv->scan_request = NULL;
242246 }
243247 }
@@ -245,7 +249,11 @@ void orinoco_add_hostscan_results(struct orinoco_private *priv, · 1 unmodified line
245249 void orinoco_scan_done(struct orinoco_private *priv, bool abort)
246250 {
247251 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);
249257 priv->scan_request = NULL;
250258 }
251259 }
drivers/net/wireless/marvell/libertas/cfg.c+8−3
@@ -796,10 +796,15 @@ void lbs_scan_done(struct lbs_private *priv) · 795 unmodified lines
796796 {
797797 WARN_ON(!priv->scan_req);
798798
799− if (priv->internal_scan)
799+ if (priv->internal_scan) {
800800 kfree(priv->scan_req);
801− else
802− cfg80211_scan_done(priv->scan_req, false);
801+ } else {
802+ struct cfg80211_scan_info info = {
803+ .aborted = false,
804+ };
805+
806+ cfg80211_scan_done(priv->scan_req, &info);
807+ }
803808
804809 priv->scan_req = NULL;
805810 }
drivers/net/wireless/marvell/mwifiex/cmdevt.c+10−2
@@ -1057,8 +1057,12 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) · 1056 unmodified lines
10571057 if (!priv)
10581058 continue;
10591059 if (priv->scan_request) {
1060+ struct cfg80211_scan_info info = {
1061+ .aborted = true,
1062+ };
1063+
10601064 mwifiex_dbg(adapter, WARN, "info: aborting scan\n");
1061− cfg80211_scan_done(priv->scan_request, 1);
1065+ cfg80211_scan_done(priv->scan_request, &info);
10621066 priv->scan_request = NULL;
10631067 }
10641068 }
@@ -1112,8 +1116,12 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter) · 47 unmodified lines
11121116 if (!priv)
11131117 continue;
11141118 if (priv->scan_request) {
1119+ struct cfg80211_scan_info info = {
1120+ .aborted = true,
1121+ };
1122+
11151123 mwifiex_dbg(adapter, WARN, "info: aborting scan\n");
1116− cfg80211_scan_done(priv->scan_request, 1);
1124+ cfg80211_scan_done(priv->scan_request, &info);
11171125 priv->scan_request = NULL;
11181126 }
11191127 }
drivers/net/wireless/marvell/mwifiex/main.c+5−1
@@ -697,9 +697,13 @@ mwifiex_close(struct net_device *dev) · 696 unmodified lines
697697 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
698698
699699 if (priv->scan_request) {
700+ struct cfg80211_scan_info info = {
701+ .aborted = true,
702+ };
703+
700704 mwifiex_dbg(priv->adapter, INFO,
701705 "aborting scan on ndo_stop\n");
702− cfg80211_scan_done(priv->scan_request, 1);
706+ cfg80211_scan_done(priv->scan_request, &info);
703707 priv->scan_request = NULL;
704708 priv->scan_aborting = true;
705709 }
drivers/net/wireless/marvell/mwifiex/scan.c+10−2
@@ -1956,9 +1956,13 @@ static void mwifiex_check_next_scan_command(struct mwifiex_private *priv) · 1955 unmodified lines
19561956 mwifiex_complete_scan(priv);
19571957
19581958 if (priv->scan_request) {
1959+ struct cfg80211_scan_info info = {
1960+ .aborted = false,
1961+ };
1962+
19591963 mwifiex_dbg(adapter, INFO,
19601964 "info: notifying scan done\n");
1961− cfg80211_scan_done(priv->scan_request, 0);
1965+ cfg80211_scan_done(priv->scan_request, &info);
19621966 priv->scan_request = NULL;
19631967 } else {
19641968 priv->scan_aborting = false;
@@ -1977,9 +1981,13 @@ static void mwifiex_check_next_scan_command(struct mwifiex_private *priv) · 12 unmodified lines
19771981
19781982 if (!adapter->active_scan_triggered) {
19791983 if (priv->scan_request) {
1984+ struct cfg80211_scan_info info = {
1985+ .aborted = true,
1986+ };
1987+
19801988 mwifiex_dbg(adapter, INFO,
19811989 "info: aborting scan\n");
1982− cfg80211_scan_done(priv->scan_request, 1);
1990+ cfg80211_scan_done(priv->scan_request, &info);
19831991 priv->scan_request = NULL;
19841992 } else {
19851993 priv->scan_aborting = false;
drivers/net/wireless/rndis_wlan.c+8−2
@@ -2134,6 +2134,7 @@ static void rndis_get_scan_results(struct work_struct *work) · 2133 unmodified lines
21342134 struct rndis_wlan_private *priv =
21352135 container_of(work, struct rndis_wlan_private, scan_work.work);
21362136 struct usbnet *usbdev = priv->usbdev;
2137+ struct cfg80211_scan_info info = {};
21372138 int ret;
21382139
21392140 netdev_dbg(usbdev->net, "get_scan_results\n");
@@ -2143,7 +2144,8 @@ static void rndis_get_scan_results(struct work_struct *work) · 3 unmodified lines
21432144
21442145 ret = rndis_check_bssid_list(usbdev, NULL, NULL);
21452146
2146− cfg80211_scan_done(priv->scan_request, ret < 0);
2147+ info.aborted = ret < 0;
2148+ cfg80211_scan_done(priv->scan_request, &info);
21472149
21482150 priv->scan_request = NULL;
21492151 }
@@ -3574,7 +3576,11 @@ static int rndis_wlan_stop(struct usbnet *usbdev) · 1424 unmodified lines
35743576 flush_workqueue(priv->workqueue);
35753577
35763578 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);
35783584 priv->scan_request = NULL;
35793585 }
35803586
drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c+8−3
@@ -1256,10 +1256,15 @@ void rtw_cfg80211_indicate_scan_done(struct rtw_wdev_priv *pwdev_priv, · 1255 unmodified lines
12561256 DBG_8723A("%s with scan req\n", __func__);
12571257
12581258 if (pwdev_priv->scan_request->wiphy !=
1259− pwdev_priv->rtw_wdev->wiphy)
1259+ pwdev_priv->rtw_wdev->wiphy) {
12601260 DBG_8723A("error wiphy compare\n");
1261− else
1262− cfg80211_scan_done(pwdev_priv->scan_request, aborted);
1261+ } else {
1262+ struct cfg80211_scan_info info = {
1263+ .aborted = aborted,
1264+ };
1265+
1266+ cfg80211_scan_done(pwdev_priv->scan_request, &info);
1267+ }
12631268
12641269 pwdev_priv->scan_request = NULL;
12651270 } else {
drivers/staging/wilc1000/wilc_wfi_cfgoperations.c+10−2
@@ -454,7 +454,11 @@ static void CfgScanResult(enum scan_event scan_event, · 453 unmodified lines
454454 mutex_lock(&priv->scan_req_lock);
455455
456456 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);
458462 priv->u32RcvdChCount = 0;
459463 priv->bCfgScanning = false;
460464 priv->pstrScanReq = NULL;
@@ -464,10 +468,14 @@ static void CfgScanResult(enum scan_event scan_event, · 3 unmodified lines
464468 mutex_lock(&priv->scan_req_lock);
465469
466470 if (priv->pstrScanReq) {
471+ struct cfg80211_scan_info info = {
472+ .aborted = false,
473+ };
474+
467475 update_scan_time();
468476 refresh_scan(priv, 1, false);
469477
470− cfg80211_scan_done(priv->pstrScanReq, false);
478+ cfg80211_scan_done(priv->pstrScanReq, &info);
471479 priv->bCfgScanning = false;
472480 priv->pstrScanReq = NULL;
473481 }
drivers/staging/wlan-ng/cfg80211.c+4−1
@@ -338,6 +338,8 @@ static int prism2_scan(struct wiphy *wiphy, · 337 unmodified lines
338338 struct p80211msg_dot11req_scan msg1;
339339 struct p80211msg_dot11req_scan_results msg2;
340340 struct cfg80211_bss *bss;
341+ struct cfg80211_scan_info info = {};
342+
341343 int result;
342344 int err = 0;
343345 int numbss = 0;
@@ -440,7 +442,8 @@ static int prism2_scan(struct wiphy *wiphy, · 96 unmodified lines
440442 err = prism2_result2err(msg2.resultcode.data);
441443
442444 exit:
443− cfg80211_scan_done(request, err ? 1 : 0);
445+ info.aborted = !!(err);
446+ cfg80211_scan_done(request, &info);
444447 priv->scan_request = NULL;
445448 return err;
446449 }
include/net/cfg80211.h+35−5
@@ -1423,6 +1423,21 @@ struct cfg80211_ssid { · 1422 unmodified lines
14231423 u8 ssid_len;
14241424 };
14251425
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+
14261441 /**
14271442 * struct cfg80211_scan_request - scan request description
14281443 *
@@ -1433,12 +1448,17 @@ struct cfg80211_ssid { · 4 unmodified lines
14331448 * @scan_width: channel width for scanning
14341449 * @ie: optional information element(s) to add into Probe Request or %NULL
14351450 * @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.
14361456 * @flags: bit field of flags controlling operation
14371457 * @rates: bitmap of rates to advertise for each band
14381458 * @wiphy: the wiphy this was for
14391459 * @scan_start: time (in jiffies) when the scan started
14401460 * @wdev: the wireless device to scan for
1441− * @aborted: (internal) scan request was notified as aborted
1461+ * @info: (internal) information about completed scan
14421462 * @notified: (internal) scan request was notified as done or aborted
14431463 * @no_cck: used to send probe requests at non CCK rate in 2GHz band
14441464 * @mac_addr: MAC address used with randomisation
@@ -1454,6 +1474,8 @@ struct cfg80211_scan_request { · 9 unmodified lines
14541474 enum nl80211_bss_scan_width scan_width;
14551475 const u8 *ie;
14561476 size_t ie_len;
1477+ u16 duration;
1478+ bool duration_mandatory;
14571479 u32 flags;
14581480
14591481 u32 rates[NUM_NL80211_BANDS];
@@ -1467,7 +1489,8 @@ struct cfg80211_scan_request { · 7 unmodified lines
14671489 /* internal */
14681490 struct wiphy *wiphy;
14691491 unsigned long scan_start;
1470− bool aborted, notified;
1492+ struct cfg80211_scan_info info;
1493+ bool notified;
14711494 bool no_cck;
14721495
14731496 /* keep last */
@@ -1600,12 +1623,19 @@ enum cfg80211_signal_type { · 126 unmodified lines
16001623 * buffered on the device) and be accurate to about 10ms.
16011624 * If the frame isn't buffered, just passing the return value of
16021625 * 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.
16031631 */
16041632 struct cfg80211_inform_bss {
16051633 struct ieee80211_channel *chan;
16061634 enum nl80211_bss_scan_width scan_width;
16071635 s32 signal;
16081636 u64 boottime_ns;
1637+ u64 parent_tsf;
1638+ u8 parent_bssid[ETH_ALEN] __aligned(2);
16091639 };
16101640
16111641 /**
@@ -4067,10 +4097,10 @@ const char *reg_initiator_name(enum nl80211_reg_initiator initiator); · 2455 unmodified lines
40674097 * cfg80211_scan_done - notify that scan finished
40684098 *
40694099 * @request: the corresponding scan request
4070− * @aborted: set to true if the scan was aborted for any reason,
4071− * userspace will be notified of that
4100+ * @info: information about the completed scan
40724101 */
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);
40744104
40754105 /**
40764106 * cfg80211_sched_scan_results - notify that new scan results are available
include/uapi/linux/nl80211.h+42−0
@@ -1848,6 +1848,22 @@ enum nl80211_commands { · 1847 unmodified lines
18481848 * to turn that feature off set an invalid mac address
18491849 * (e.g. FF:FF:FF:FF:FF:FF)
18501850 *
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+ *
18511867 * @NUM_NL80211_ATTR: total number of nl80211_attrs available
18521868 * @NL80211_ATTR_MAX: highest attribute number currently defined
18531869 * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2235,6 +2251,11 @@ enum nl80211_attrs { · 381 unmodified lines
22352251 NL80211_ATTR_MU_MIMO_GROUP_DATA,
22362252 NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR,
22372253
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+
22382259 /* add attributes here, update the policy in nl80211.c */
22392260
22402261 __NL80211_ATTR_AFTER_LAST,
@@ -3496,6 +3517,12 @@ enum nl80211_bss_scan_width { · 1255 unmodified lines
34963517 * was last updated by a received frame. The value is expected to be
34973518 * accurate to about 10ms. (u64, nanoseconds)
34983519 * @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.
34993526 * @__NL80211_BSS_AFTER_LAST: internal
35003527 * @NL80211_BSS_MAX: highest BSS attribute
35013528 */
@@ -3517,6 +3544,8 @@ enum nl80211_bss { · 15 unmodified lines
35173544 NL80211_BSS_PRESP_DATA,
35183545 NL80211_BSS_LAST_SEEN_BOOTTIME,
35193546 NL80211_BSS_PAD,
3547+ NL80211_BSS_PARENT_TSF,
3548+ NL80211_BSS_PARENT_BSSID,
35203549
35213550 /* keep last */
35223551 __NL80211_BSS_AFTER_LAST,
@@ -4507,6 +4536,16 @@ enum nl80211_feature_flags { · 984 unmodified lines
45074536 * %NL80211_ATTR_MU_MIMO_GROUP_DATA attribute,
45084537 * or can be configured to follow a station by configuring the
45094538 * %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.
45104549 *
45114550 * @NUM_NL80211_EXT_FEATURES: number of extended features.
45124551 * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
@@ -4515,6 +4554,9 @@ enum nl80211_ext_feature_index { · 2 unmodified lines
45154554 NL80211_EXT_FEATURE_VHT_IBSS,
45164555 NL80211_EXT_FEATURE_RRM,
45174556 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,
45184560
45194561 /* add new features before the definition below */
45204562 NUM_NL80211_EXT_FEATURES,
net/mac80211/scan.c+7−2
@@ -353,8 +353,13 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) · 352 unmodified lines
353353 scan_req = rcu_dereference_protected(local->scan_req,
354354 lockdep_is_held(&local->mtx));
355355
356− if (scan_req != local->int_scan_req)
357− cfg80211_scan_done(scan_req, aborted);
356+ if (scan_req != local->int_scan_req) {
357+ struct cfg80211_scan_info info = {
358+ .aborted = aborted,
359+ };
360+
361+ cfg80211_scan_done(scan_req, &info);
362+ }
358363 RCU_INIT_POINTER(local->scan_req, NULL);
359364
360365 scan_sdata = rcu_dereference_protected(local->scan_sdata,
net/wireless/core.c+2−2
@@ -220,7 +220,7 @@ void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev, · 219 unmodified lines
220220
221221 if (rdev->scan_req && rdev->scan_req->wdev == wdev) {
222222 if (WARN_ON(!rdev->scan_req->notified))
223− rdev->scan_req->aborted = true;
223+ rdev->scan_req->info.aborted = true;
224224 ___cfg80211_scan_done(rdev, false);
225225 }
226226 }
@@ -1087,7 +1087,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, · 860 unmodified lines
10871087 cfg80211_update_iface_num(rdev, wdev->iftype, -1);
10881088 if (rdev->scan_req && rdev->scan_req->wdev == wdev) {
10891089 if (WARN_ON(!rdev->scan_req->notified))
1090− rdev->scan_req->aborted = true;
1090+ rdev->scan_req->info.aborted = true;
10911091 ___cfg80211_scan_done(rdev, false);
10921092 }
10931093
net/wireless/core.h+12−0
@@ -141,6 +141,18 @@ struct cfg80211_internal_bss { · 140 unmodified lines
141141 unsigned long refcount;
142142 atomic_t hold;
143143
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+
144156 /* must be last because of priv member */
145157 struct cfg80211_bss pub;
146158 };
net/wireless/nl80211.c+27−0
@@ -6223,6 +6223,19 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) · 6222 unmodified lines
62236223 }
62246224 }
62256225
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+
62266239 if (info->attrs[NL80211_ATTR_SCAN_FLAGS]) {
62276240 request->flags = nla_get_u32(
62286241 info->attrs[NL80211_ATTR_SCAN_FLAGS]);
@@ -7056,6 +7069,13 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb, · 827 unmodified lines
70567069 jiffies_to_msecs(jiffies - intbss->ts)))
70577070 goto nla_put_failure;
70587071
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+
70597079 if (intbss->ts_boottime &&
70607080 nla_put_u64_64bit(msg, NL80211_BSS_LAST_SEEN_BOOTTIME,
70617081 intbss->ts_boottime, NL80211_BSS_PAD))
@@ -11829,6 +11849,13 @@ static int nl80211_add_scan_req(struct sk_buff *msg, · 4767 unmodified lines
1182911849 nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags))
1183011850 goto nla_put_failure;
1183111851
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+
1183211859 return 0;
1183311860 nla_put_failure:
1183411861 return -ENOBUFS;
net/wireless/scan.c+12−6
@@ -3,6 +3,7 @@ · 2 unmodified lines
33 *
44 * Copyright 2008 Johannes Berg <johannes@sipsolutions.net>
55 * Copyright 2013-2014 Intel Mobile Communications GmbH
6+ * Copyright 2016 Intel Deutschland GmbH
67 */
78 #include <linux/kernel.h>
89 #include <linux/slab.h>
@@ -194,7 +195,7 @@ void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, · 185 unmodified lines
194195 if (wdev->netdev)
195196 cfg80211_sme_scan_done(wdev->netdev);
196197
197− if (!request->aborted &&
198+ if (!request->info.aborted &&
198199 request->flags & NL80211_SCAN_FLAG_FLUSH) {
199200 /* flush entries from previous scans */
200201 spin_lock_bh(&rdev->bss_lock);
@@ -202,10 +203,10 @@ void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, · 1 unmodified line
202203 spin_unlock_bh(&rdev->bss_lock);
203204 }
204205
205− msg = nl80211_build_scan_msg(rdev, wdev, request->aborted);
206+ msg = nl80211_build_scan_msg(rdev, wdev, request->info.aborted);
206207
207208 #ifdef CONFIG_CFG80211_WEXT
208− if (wdev->netdev && !request->aborted) {
209+ if (wdev->netdev && !request->info.aborted) {
209210 memset(&wrqu, 0, sizeof(wrqu));
210211
211212 wireless_send_event(wdev->netdev, SIOCGIWSCAN, &wrqu, NULL);
@@ -236,12 +237,13 @@ void __cfg80211_scan_done(struct work_struct *wk) · 24 unmodified lines
236237 rtnl_unlock();
237238 }
238239
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)
240242 {
241− trace_cfg80211_scan_done(request, aborted);
243+ trace_cfg80211_scan_done(request, info);
242244 WARN_ON(request != wiphy_to_rdev(request->wiphy)->scan_req);
243245
244− request->aborted = aborted;
246+ request->info = *info;
245247 request->notified = true;
246248 queue_work(cfg80211_wq, &wiphy_to_rdev(request->wiphy)->scan_done_wk);
247249 }
@@ -843,6 +845,8 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev, · 595 unmodified lines
843845 found->pub.capability = tmp->pub.capability;
844846 found->ts = tmp->ts;
845847 found->ts_boottime = tmp->ts_boottime;
848+ found->parent_tsf = tmp->parent_tsf;
849+ ether_addr_copy(found->parent_bssid, tmp->parent_bssid);
846850 } else {
847851 struct cfg80211_internal_bss *new;
848852 struct cfg80211_internal_bss *hidden;
@@ -1086,6 +1090,8 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy, · 237 unmodified lines
10861090 tmp.pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int);
10871091 tmp.pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
10881092 tmp.ts_boottime = data->boottime_ns;
1093+ tmp.parent_tsf = data->parent_tsf;
1094+ ether_addr_copy(tmp.parent_bssid, data->parent_bssid);
10891095
10901096 signal_valid = abs(data->chan->center_freq - channel->center_freq) <=
10911097 wiphy->max_adj_channel_rssi_comp;
net/wireless/trace.h+25−8
@@ -2642,8 +2642,9 @@ TRACE_EVENT(cfg80211_tdls_oper_request, · 2641 unmodified lines
26422642 );
26432643
26442644 TRACE_EVENT(cfg80211_scan_done,
2645− TP_PROTO(struct cfg80211_scan_request *request, bool aborted),
2646− TP_ARGS(request, aborted),
2645+ TP_PROTO(struct cfg80211_scan_request *request,
2646+ struct cfg80211_scan_info *info),
2647+ TP_ARGS(request, info),
26472648 TP_STRUCT__entry(
26482649 __field(u32, n_channels)
26492650 __dynamic_array(u8, ie, request ? request->ie_len : 0)
@@ -2652,6 +2653,8 @@ TRACE_EVENT(cfg80211_scan_done, · 2 unmodified lines
26522653 MAC_ENTRY(wiphy_mac)
26532654 __field(bool, no_cck)
26542655 __field(bool, aborted)
2656+ __field(u64, scan_start_tsf)
2657+ MAC_ENTRY(tsf_bssid)
26552658 ),
26562659 TP_fast_assign(
26572660 if (request) {
@@ -2666,9 +2669,16 @@ TRACE_EVENT(cfg80211_scan_done, · 8 unmodified lines
26662669 request->wiphy->perm_addr);
26672670 __entry->no_cck = request->no_cck;
26682671 }
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+ }
26702677 ),
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))
26722682 );
26732683
26742684 DEFINE_EVENT(wiphy_only_evt, cfg80211_sched_scan_results,
@@ -2721,6 +2731,8 @@ TRACE_EVENT(cfg80211_inform_bss_frame, · 46 unmodified lines
27212731 __dynamic_array(u8, mgmt, len)
27222732 __field(s32, signal)
27232733 __field(u64, ts_boottime)
2734+ __field(u64, parent_tsf)
2735+ MAC_ENTRY(parent_bssid)
27242736 ),
27252737 TP_fast_assign(
27262738 WIPHY_ASSIGN;
@@ -2730,10 +2742,15 @@ TRACE_EVENT(cfg80211_inform_bss_frame, · 3 unmodified lines
27302742 memcpy(__get_dynamic_array(mgmt), mgmt, len);
27312743 __entry->signal = data->signal;
27322744 __entry->ts_boottime = data->boottime_ns;
2733− ),
2734− TP_printk(WIPHY_PR_FMT ", " CHAN_PR_FMT "(scan_width: %d) signal: %d, tsb:%llu",
2735− WIPHY_PR_ARG, CHAN_PR_ARG, __entry->scan_width,
2736− __entry->signal, (unsigned long long)__entry->ts_boottime)
2745+ __entry->parent_tsf = data->parent_tsf;
2746+ MAC_ASSIGN(parent_bssid, data->parent_bssid);
2747+ ),
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))
27372754 );
27382755
27392756 DECLARE_EVENT_CLASS(cfg80211_bss_evt,

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t