Skip to content

Commit c8cb5b8

Browse files
tmussaijmberg-intel
authored andcommitted
nl80211/cfg80211: support 6 GHz scanning
Support 6 GHz scanning, by * a new scan flag to scan for colocated BSSes advertised by (and found) APs on 2.4 & 5 GHz * doing the necessary reduced neighbor report parsing for this, to find them * adding the ability to split the scan request in case the device by itself cannot support this. Also add some necessary bits in mac80211 to not break with these changes. Signed-off-by: Tova Mussai <[email protected]> Signed-off-by: Johannes Berg <[email protected]> Link: https://lore.kernel.org/r/20200918113313.232917c93af9.Ida22f0212f9122f47094d81659e879a50434a6a2@changeid Signed-off-by: Johannes Berg <[email protected]>
1 parent dba0491 commit c8cb5b8

File tree

7 files changed

+552
-17
lines changed

7 files changed

+552
-17
lines changed

include/net/cfg80211.h

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2095,6 +2095,27 @@ struct cfg80211_scan_info {
20952095
bool aborted;
20962096
};
20972097

2098+
/**
2099+
* struct cfg80211_scan_6ghz_params - relevant for 6 GHz only
2100+
*
2101+
* @short_bssid: short ssid to scan for
2102+
* @bssid: bssid to scan for
2103+
* @channel_idx: idx of the channel in the channel array in the scan request
2104+
* which the above info relvant to
2105+
* @unsolicited_probe: the AP transmits unsolicited probe response every 20 TU
2106+
* @short_ssid_valid: short_ssid is valid and can be used
2107+
* @psc_no_listen: when set, and the channel is a PSC channel, no need to wait
2108+
* 20 TUs before starting to send probe requests.
2109+
*/
2110+
struct cfg80211_scan_6ghz_params {
2111+
u32 short_ssid;
2112+
u32 channel_idx;
2113+
u8 bssid[ETH_ALEN];
2114+
bool unsolicited_probe;
2115+
bool short_ssid_valid;
2116+
bool psc_no_listen;
2117+
};
2118+
20982119
/**
20992120
* struct cfg80211_scan_request - scan request description
21002121
*
@@ -2122,6 +2143,10 @@ struct cfg80211_scan_info {
21222143
* @mac_addr_mask: MAC address mask used with randomisation, bits that
21232144
* are 0 in the mask should be randomised, bits that are 1 should
21242145
* be taken from the @mac_addr
2146+
* @scan_6ghz: relevant for split scan request only,
2147+
* true if this is the second scan request
2148+
* @n_6ghz_params: number of 6 GHz params
2149+
* @scan_6ghz_params: 6 GHz params
21252150
* @bssid: BSSID to scan for (most commonly, the wildcard BSSID)
21262151
*/
21272152
struct cfg80211_scan_request {
@@ -2149,6 +2174,9 @@ struct cfg80211_scan_request {
21492174
struct cfg80211_scan_info info;
21502175
bool notified;
21512176
bool no_cck;
2177+
bool scan_6ghz;
2178+
u32 n_6ghz_params;
2179+
struct cfg80211_scan_6ghz_params *scan_6ghz_params;
21522180

21532181
/* keep last */
21542182
struct ieee80211_channel *channels[];
@@ -4217,6 +4245,8 @@ struct cfg80211_ops {
42174245
/**
42184246
* enum wiphy_flags - wiphy capability flags
42194247
*
4248+
* @WIPHY_FLAG_SPLIT_SCAN_6GHZ: if set to true, the scan request will be split
4249+
* into two, first for legacy bands and second for UHB.
42204250
* @WIPHY_FLAG_NETNS_OK: if not set, do not allow changing the netns of this
42214251
* wiphy at all
42224252
* @WIPHY_FLAG_PS_ON_BY_DEFAULT: if set to true, powersave will be enabled
@@ -4260,7 +4290,7 @@ struct cfg80211_ops {
42604290
enum wiphy_flags {
42614291
WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK = BIT(0),
42624292
/* use hole at 1 */
4263-
/* use hole at 2 */
4293+
WIPHY_FLAG_SPLIT_SCAN_6GHZ = BIT(2),
42644294
WIPHY_FLAG_NETNS_OK = BIT(3),
42654295
WIPHY_FLAG_PS_ON_BY_DEFAULT = BIT(4),
42664296
WIPHY_FLAG_4ADDR_AP = BIT(5),

include/uapi/linux/nl80211.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6059,6 +6059,8 @@ enum nl80211_timeout_reason {
60596059
* @NL80211_SCAN_FLAG_FREQ_KHZ: report scan results with
60606060
* %NL80211_ATTR_SCAN_FREQ_KHZ. This also means
60616061
* %NL80211_ATTR_SCAN_FREQUENCIES will not be included.
6062+
* @NL80211_SCAN_FLAG_COLOCATED_6GHZ: scan for colocated APs reported by
6063+
* 2.4/5 GHz APs
60626064
*/
60636065
enum nl80211_scan_flags {
60646066
NL80211_SCAN_FLAG_LOW_PRIORITY = 1<<0,
@@ -6075,6 +6077,7 @@ enum nl80211_scan_flags {
60756077
NL80211_SCAN_FLAG_RANDOM_SN = 1<<11,
60766078
NL80211_SCAN_FLAG_MIN_PREQ_CONTENT = 1<<12,
60776079
NL80211_SCAN_FLAG_FREQ_KHZ = 1<<13,
6080+
NL80211_SCAN_FLAG_COLOCATED_6GHZ = 1<<14,
60786081
};
60796082

60806083
/**

net/mac80211/scan.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* Copyright 2007, Michael Wu <[email protected]>
1010
* Copyright 2013-2015 Intel Mobile Communications GmbH
1111
* Copyright 2016-2017 Intel Deutschland GmbH
12-
* Copyright (C) 2018-2019 Intel Corporation
12+
* Copyright (C) 2018-2020 Intel Corporation
1313
*/
1414

1515
#include <linux/if_arp.h>
@@ -712,6 +712,10 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
712712
req->duration_mandatory;
713713

714714
local->hw_scan_band = 0;
715+
local->hw_scan_req->req.n_6ghz_params = req->n_6ghz_params;
716+
local->hw_scan_req->req.scan_6ghz_params =
717+
req->scan_6ghz_params;
718+
local->hw_scan_req->req.scan_6ghz = req->scan_6ghz;
715719

716720
/*
717721
* After allocating local->hw_scan_req, we must
@@ -1124,7 +1128,8 @@ int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
11241128
int max_n;
11251129

11261130
for (band = 0; band < NUM_NL80211_BANDS; band++) {
1127-
if (!local->hw.wiphy->bands[band])
1131+
if (!local->hw.wiphy->bands[band] ||
1132+
band == NL80211_BAND_6GHZ)
11281133
continue;
11291134

11301135
max_n = local->hw.wiphy->bands[band]->n_channels;

net/wireless/core.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,9 @@ void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev,
236236
rdev->opencount--;
237237

238238
if (rdev->scan_req && rdev->scan_req->wdev == wdev) {
239-
if (WARN_ON(!rdev->scan_req->notified))
239+
if (WARN_ON(!rdev->scan_req->notified &&
240+
(!rdev->int_scan_req ||
241+
!rdev->int_scan_req->notified)))
240242
rdev->scan_req->info.aborted = true;
241243
___cfg80211_scan_done(rdev, false);
242244
}
@@ -1336,7 +1338,9 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
13361338
case NETDEV_DOWN:
13371339
cfg80211_update_iface_num(rdev, wdev->iftype, -1);
13381340
if (rdev->scan_req && rdev->scan_req->wdev == wdev) {
1339-
if (WARN_ON(!rdev->scan_req->notified))
1341+
if (WARN_ON(!rdev->scan_req->notified &&
1342+
(!rdev->int_scan_req ||
1343+
!rdev->int_scan_req->notified)))
13401344
rdev->scan_req->info.aborted = true;
13411345
___cfg80211_scan_done(rdev, false);
13421346
}

net/wireless/core.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Wireless configuration interface internals.
44
*
55
* Copyright 2006-2010 Johannes Berg <[email protected]>
6-
* Copyright (C) 2018-2019 Intel Corporation
6+
* Copyright (C) 2018-2020 Intel Corporation
77
*/
88
#ifndef __NET_WIRELESS_CORE_H
99
#define __NET_WIRELESS_CORE_H
@@ -72,6 +72,7 @@ struct cfg80211_registered_device {
7272
u32 bss_generation;
7373
u32 bss_entries;
7474
struct cfg80211_scan_request *scan_req; /* protected by RTNL */
75+
struct cfg80211_scan_request *int_scan_req;
7576
struct sk_buff *scan_msg;
7677
struct list_head sched_scan_req_list;
7778
time64_t suspend_at;
@@ -457,6 +458,8 @@ void cfg80211_process_wdev_events(struct wireless_dev *wdev);
457458
bool cfg80211_does_bw_fit_range(const struct ieee80211_freq_range *freq_range,
458459
u32 center_freq_khz, u32 bw_khz);
459460

461+
int cfg80211_scan(struct cfg80211_registered_device *rdev);
462+
460463
extern struct work_struct cfg80211_disconnect_work;
461464

462465
/**

net/wireless/nl80211.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8236,7 +8236,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
82368236
request->scan_start = jiffies;
82378237

82388238
rdev->scan_req = request;
8239-
err = rdev_scan(rdev, request);
8239+
err = cfg80211_scan(rdev);
82408240

82418241
if (err)
82428242
goto out_free;
@@ -15518,6 +15518,7 @@ static int nl80211_add_scan_req(struct sk_buff *msg,
1551815518
struct cfg80211_scan_request *req = rdev->scan_req;
1551915519
struct nlattr *nest;
1552015520
int i;
15521+
struct cfg80211_scan_info *info;
1552115522

1552215523
if (WARN_ON(!req))
1552315524
return 0;
@@ -15561,11 +15562,13 @@ static int nl80211_add_scan_req(struct sk_buff *msg,
1556115562
nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags))
1556215563
goto nla_put_failure;
1556315564

15564-
if (req->info.scan_start_tsf &&
15565+
info = rdev->int_scan_req ? &rdev->int_scan_req->info :
15566+
&rdev->scan_req->info;
15567+
if (info->scan_start_tsf &&
1556515568
(nla_put_u64_64bit(msg, NL80211_ATTR_SCAN_START_TIME_TSF,
15566-
req->info.scan_start_tsf, NL80211_BSS_PAD) ||
15569+
info->scan_start_tsf, NL80211_BSS_PAD) ||
1556715570
nla_put(msg, NL80211_ATTR_SCAN_START_TIME_TSF_BSSID, ETH_ALEN,
15568-
req->info.tsf_bssid)))
15571+
info->tsf_bssid)))
1556915572
goto nla_put_failure;
1557015573

1557115574
return 0;

0 commit comments

Comments
 (0)