All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] wifi: nl80211: Add support to specify channel width for scan
@ 2023-03-01  9:02 Xinyue Ling
  2023-03-01  9:02 ` [PATCH 1/4] nl80211: Add 4/8/16 MHz BSS control channel width definitions Xinyue Ling
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Xinyue Ling @ 2023-03-01  9:02 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless

nl80211_trigger_scan() processes scan request netlink attributes,
defined in enum nl80211_attrs, and fills struct
cfg80211_scan_request *request.

Currently there is no logic to fill this member:
	enum nl80211_bss_scan_width scan_width;

We have a requirement to fill this member for drone use cases, in
which drone controller needs to scan and connect to drone in 5 MHz
or 10 MHz channel width (may support other channel widths lower
than 20 MHz later).

Unfortunately there is not an existing attribute in enum
nl80211_attrs that has enum nl80211_bss_scan_width semantics. The
only attribute which has those semantics is NL80211_BSS_CHAN_WIDTH
in enum nl80211_bss, and of course we can't mix attributes from
different enums in a netlink command, at least not at the same
nesting level.

enum nl80211_attrs does define another attribute,
NL80211_ATTR_CHANNEL_WIDTH, but it has enum nl80211_chan_width
semantics.

In order to support the requirement to fill the scan_width with
an enum nl80211_bss_scan_width value we seem to have two options:
1) Use NL80211_ATTR_CHANNEL_WIDTH and convert from enum
nl80211_chan_width semantics to enum nl80211_bss_scan_width semantics
when filling struct cfg80211_scan_request *request.
2) Introduce a new NL80211_ATTR_SCAN_CHANNEL_WIDTH attribute to
enum nl80211_attrs that has enum nl80211_bss_scan_width semantics.

The following series of patches is the implementations of above two
options. In order to make them a series, a revert patch is included,
which can be ignored. Please review and decide which option is more
reasonable and acceptable.

Xinyue Ling (4):
  nl80211: Add 4/8/16 MHz BSS control channel width definitions
  wifi: nl80211: Add support to specify channel width for scan (option
    1)
  Revert "wifi: nl80211: Add support to specify channel width for scan
    (option 1)"
  wifi: nl80211: Add support to specify channel width for scan (option
    2)

 include/net/cfg80211.h       |  6 ++++++
 include/uapi/linux/nl80211.h | 34 ++++++++++++++++++++++++++++++++--
 net/wireless/nl80211.c       | 14 ++++++++++++++
 3 files changed, 52 insertions(+), 2 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/4] nl80211: Add 4/8/16 MHz BSS control channel width definitions
  2023-03-01  9:02 [PATCH 0/4] wifi: nl80211: Add support to specify channel width for scan Xinyue Ling
@ 2023-03-01  9:02 ` Xinyue Ling
  2023-03-01  9:02 ` [PATCH 2/4] wifi: nl80211: Add support to specify channel width for scan (option 1) Xinyue Ling
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Xinyue Ling @ 2023-03-01  9:02 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless

Add definitions in enum nl80211_bss_scan_width to support
4/8/16 MHz BSS control channel width defined in IEEE Std
802.11ah-2016.

Signed-off-by: Xinyue Ling <quic_xinyling@quicinc.com>
---
 include/uapi/linux/nl80211.h | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 8ecb0fbee721..3f15ac05f581 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -4903,6 +4903,9 @@ enum nl80211_chan_width {
  * @NL80211_BSS_CHAN_WIDTH_5: control channel is 5 MHz wide
  * @NL80211_BSS_CHAN_WIDTH_1: control channel is 1 MHz wide
  * @NL80211_BSS_CHAN_WIDTH_2: control channel is 2 MHz wide
+ * @NL80211_BSS_CHAN_WIDTH_4: control channel is 4 MHz wide
+ * @NL80211_BSS_CHAN_WIDTH_8: control channel is 8 MHz wide
+ * @NL80211_BSS_CHAN_WIDTH_16: control channel is 16 MHz wide
  */
 enum nl80211_bss_scan_width {
 	NL80211_BSS_CHAN_WIDTH_20,
@@ -4910,6 +4913,9 @@ enum nl80211_bss_scan_width {
 	NL80211_BSS_CHAN_WIDTH_5,
 	NL80211_BSS_CHAN_WIDTH_1,
 	NL80211_BSS_CHAN_WIDTH_2,
+	NL80211_BSS_CHAN_WIDTH_4,
+	NL80211_BSS_CHAN_WIDTH_8,
+	NL80211_BSS_CHAN_WIDTH_16,
 };
 
 /**
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/4] wifi: nl80211: Add support to specify channel width for scan (option 1)
  2023-03-01  9:02 [PATCH 0/4] wifi: nl80211: Add support to specify channel width for scan Xinyue Ling
  2023-03-01  9:02 ` [PATCH 1/4] nl80211: Add 4/8/16 MHz BSS control channel width definitions Xinyue Ling
@ 2023-03-01  9:02 ` Xinyue Ling
  2023-03-01  9:02 ` [PATCH 3/4] Revert "wifi: nl80211: Add support to specify channel width for scan (option 1)" Xinyue Ling
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Xinyue Ling @ 2023-03-01  9:02 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless

Add support to parse NL80211_ATTR_CHANNEL_WIDTH attribute
and convert it from enum nl80211_chan_width semantics to
enum nl80211_bss_scan_width semantics for nl80211_commands
NL80211_CMD_TRIGGER_SCAN and NL80211_CMD_START_SCHED_SCAN.
Also add a new scan_width_set flag in the scan request sent
to the driver to indicate whether the scan channel width is
passed from the userspace.

If channel width lower than 20 MHz is specified, it will be
converted from enum nl80211_chan_width value to the
corresponding enum nl80211_bss_scan_width value and it is
expected that only BSSs using this channel width can be
found. If 20 MHz or higher channel width is specified, it
is expected that all the BSSs using 20 MHz or higher channel
width can be found as their management frames can be
received on the primary 20 MHz channel. If this attribute is
not passed from the userspace, the scan channel width will
be decided by the driver.

One example for such use case is connection between drone
and drone controller, userspace may need to specify the
scan channel width, which needs to be passed to the driver
to trigger the scan on this specified channel width.

Signed-off-by: Xinyue Ling <quic_xinyling@quicinc.com>
---
 include/net/cfg80211.h       |  6 +++++
 include/uapi/linux/nl80211.h | 19 ++++++++++++++-
 net/wireless/nl80211.c       | 47 +++++++++++++++++++++++++++++++++++-
 3 files changed, 70 insertions(+), 2 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 54a77d906b2d..bbf566190a87 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2400,6 +2400,8 @@ struct cfg80211_scan_6ghz_params {
  * @channels: channels to scan on.
  * @n_channels: total number of channels to scan
  * @scan_width: channel width for scanning
+ * @scan_width_set: channel width for scanning is specified from the
+ *	userspace
  * @ie: optional information element(s) to add into Probe Request or %NULL
  * @ie_len: length of ie in octets
  * @duration: how long to listen on each channel, in TUs. If
@@ -2430,6 +2432,7 @@ struct cfg80211_scan_request {
 	int n_ssids;
 	u32 n_channels;
 	enum nl80211_bss_scan_width scan_width;
+	bool scan_width_set;
 	const u8 *ie;
 	size_t ie_len;
 	u16 duration;
@@ -2525,6 +2528,8 @@ struct cfg80211_bss_select_adjust {
  * @n_ssids: number of SSIDs
  * @n_channels: total number of channels to scan
  * @scan_width: channel width for scanning
+ * @scan_width_set: channel width for scanning is specified from the
+ *	userspace
  * @ie: optional information element(s) to add into Probe Request or %NULL
  * @ie_len: length of ie in octets
  * @flags: bit field of flags controlling operation
@@ -2573,6 +2578,7 @@ struct cfg80211_sched_scan_request {
 	int n_ssids;
 	u32 n_channels;
 	enum nl80211_bss_scan_width scan_width;
+	bool scan_width_set;
 	const u8 *ie;
 	size_t ie_len;
 	u32 flags;
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 3f15ac05f581..03b60d987a1b 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -501,7 +501,13 @@
  *	%NL80211_ATTR_TX_NO_CCK_RATE is used to decide whether to send the
  *	probe requests at CCK rate or not. %NL80211_ATTR_BSSID can be used to
  *	specify a BSSID to scan for; if not included, the wildcard BSSID will
- *	be used.
+ *	be used. %NL80211_ATTR_CHANNEL_WIDTH can be passed from the userspace
+ *	to specify the scan channel bandwidth; if channel bandwidth lower than
+ *	20 MHz is specified, it is expected that only BSSs using this channel
+ *	bandwidth can be found; if 20 MHz or higher channel bandwidth is
+ *	specified, it is expected that all the BSSs using 20 MHz or higher
+ *	channel bandwidth can be found; if not included, the scan channel
+ *	bandwidth will be decided by the driver.
  * @NL80211_CMD_NEW_SCAN_RESULTS: scan notification (as a reply to
  *	NL80211_CMD_GET_SCAN and on the "scan" multicast group)
  * @NL80211_CMD_SCAN_ABORTED: scan was aborted, for unspecified reasons,
@@ -530,6 +536,13 @@
  *	is supplied. If the device supports multiple concurrent scheduled
  *	scans, it will allow such when the caller provides the flag attribute
  *	%NL80211_ATTR_SCHED_SCAN_MULTI to indicate user-space support for it.
+ *	%NL80211_ATTR_CHANNEL_WIDTH can be passed from the userspace to specify
+ *	the scan channel width; if channel bandwidth lower than 20 MHz is
+ *	specified, it is expected that only BSSs using this channel bandwidth
+ *	can be found; if 20 MHz or higher channel bandwidth is specified, it is
+ *	expected that all the BSSs using 20 MHz or higher channel bandwidth can
+ *	be found; if not included, the scan channel bandwidth will be decided by
+ *	the driver.
  * @NL80211_CMD_STOP_SCHED_SCAN: stop a scheduled scan. Returns -ENOENT if
  *	scheduled scan is not running. The caller may assume that as soon
  *	as the call returns, it is safe to start a new scheduled scan again.
@@ -4875,6 +4888,8 @@ enum nl80211_key_mode {
  * @NL80211_CHAN_WIDTH_16: 16 MHz OFDM channel
  * @NL80211_CHAN_WIDTH_320: 320 MHz channel, the %NL80211_ATTR_CENTER_FREQ1
  *	attribute must be provided as well
+ * @NUM_NL80211_CHAN_WIDTH: number of values, avoid using this in userspace
+ *	since newer kernel versions may support more channel widths
  */
 enum nl80211_chan_width {
 	NL80211_CHAN_WIDTH_20_NOHT,
@@ -4891,6 +4906,8 @@ enum nl80211_chan_width {
 	NL80211_CHAN_WIDTH_8,
 	NL80211_CHAN_WIDTH_16,
 	NL80211_CHAN_WIDTH_320,
+
+	NUM_NL80211_CHAN_WIDTH
 };
 
 /**
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 64cf6110ce9d..2048a98c3273 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -478,7 +478,8 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
 						NL80211_EDMG_BW_CONFIG_MIN,
 						NL80211_EDMG_BW_CONFIG_MAX),
 
-	[NL80211_ATTR_CHANNEL_WIDTH] = { .type = NLA_U32 },
+	[NL80211_ATTR_CHANNEL_WIDTH] =
+		NLA_POLICY_MAX(NLA_U32, NUM_NL80211_CHAN_WIDTH),
 	[NL80211_ATTR_CENTER_FREQ1] = { .type = NLA_U32 },
 	[NL80211_ATTR_CENTER_FREQ1_OFFSET] = NLA_POLICY_RANGE(NLA_U32, 0, 999),
 	[NL80211_ATTR_CENTER_FREQ2] = { .type = NLA_U32 },
@@ -8924,6 +8925,34 @@ nl80211_check_scan_flags(struct wiphy *wiphy, struct wireless_dev *wdev,
 	return 0;
 }
 
+static enum nl80211_bss_scan_width
+chan_width_to_scan_width(enum nl80211_chan_width width)
+{
+	switch (width) {
+	case NL80211_CHAN_WIDTH_5:
+		return NL80211_BSS_CHAN_WIDTH_5;
+	case NL80211_CHAN_WIDTH_10:
+		return NL80211_BSS_CHAN_WIDTH_10;
+	case NL80211_CHAN_WIDTH_1:
+		return NL80211_BSS_CHAN_WIDTH_1;
+	case NL80211_CHAN_WIDTH_2:
+		return NL80211_BSS_CHAN_WIDTH_2;
+	case NL80211_CHAN_WIDTH_4:
+		return NL80211_BSS_CHAN_WIDTH_4;
+	case NL80211_CHAN_WIDTH_8:
+		return NL80211_BSS_CHAN_WIDTH_8;
+	case NL80211_CHAN_WIDTH_16:
+		return NL80211_BSS_CHAN_WIDTH_16;
+	default:
+		/* for the rest of channel bandwidth values (20 MHz or higher),
+		 * scan channel bandwidth can be set to NL80211_BSS_CHAN_WIDTH_20
+		 * as management frames of BSSs using 20 MHz or higher channel
+		 * can be received on the primary 20 MHz channel
+		 */
+		return NL80211_BSS_CHAN_WIDTH_20;
+	}
+}
+
 static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
 {
 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -9120,6 +9149,14 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
 			nla_get_flag(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY]);
 	}
 
+	if (info->attrs[NL80211_ATTR_CHANNEL_WIDTH]) {
+		enum nl80211_chan_width chan_width;
+
+		chan_width = nla_get_u32(info->attrs[NL80211_ATTR_CHANNEL_WIDTH]);
+		request->scan_width = chan_width_to_scan_width(chan_width);
+		request->scan_width_set = true;
+	}
+
 	err = nl80211_check_scan_flags(wiphy, wdev, request, info->attrs,
 				       false);
 	if (err)
@@ -9611,6 +9648,14 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
 		       request->ie_len);
 	}
 
+	if (attrs[NL80211_ATTR_CHANNEL_WIDTH]) {
+		enum nl80211_chan_width chan_width;
+
+		chan_width = nla_get_u32(attrs[NL80211_ATTR_CHANNEL_WIDTH]);
+		request->scan_width = chan_width_to_scan_width(chan_width);
+		request->scan_width_set = true;
+	}
+
 	err = nl80211_check_scan_flags(wiphy, wdev, request, attrs, true);
 	if (err)
 		goto out_free;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/4] Revert "wifi: nl80211: Add support to specify channel width for scan (option 1)"
  2023-03-01  9:02 [PATCH 0/4] wifi: nl80211: Add support to specify channel width for scan Xinyue Ling
  2023-03-01  9:02 ` [PATCH 1/4] nl80211: Add 4/8/16 MHz BSS control channel width definitions Xinyue Ling
  2023-03-01  9:02 ` [PATCH 2/4] wifi: nl80211: Add support to specify channel width for scan (option 1) Xinyue Ling
@ 2023-03-01  9:02 ` Xinyue Ling
  2023-03-01  9:02 ` [PATCH 4/4] wifi: nl80211: Add support to specify channel width for scan (option 2) Xinyue Ling
  2023-03-07  9:20 ` [PATCH 0/4] wifi: nl80211: Add support to specify channel width for scan Johannes Berg
  4 siblings, 0 replies; 6+ messages in thread
From: Xinyue Ling @ 2023-03-01  9:02 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless

---
 include/net/cfg80211.h       |  6 -----
 include/uapi/linux/nl80211.h | 19 +--------------
 net/wireless/nl80211.c       | 47 +-----------------------------------
 3 files changed, 2 insertions(+), 70 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index bbf566190a87..54a77d906b2d 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2400,8 +2400,6 @@ struct cfg80211_scan_6ghz_params {
  * @channels: channels to scan on.
  * @n_channels: total number of channels to scan
  * @scan_width: channel width for scanning
- * @scan_width_set: channel width for scanning is specified from the
- *	userspace
  * @ie: optional information element(s) to add into Probe Request or %NULL
  * @ie_len: length of ie in octets
  * @duration: how long to listen on each channel, in TUs. If
@@ -2432,7 +2430,6 @@ struct cfg80211_scan_request {
 	int n_ssids;
 	u32 n_channels;
 	enum nl80211_bss_scan_width scan_width;
-	bool scan_width_set;
 	const u8 *ie;
 	size_t ie_len;
 	u16 duration;
@@ -2528,8 +2525,6 @@ struct cfg80211_bss_select_adjust {
  * @n_ssids: number of SSIDs
  * @n_channels: total number of channels to scan
  * @scan_width: channel width for scanning
- * @scan_width_set: channel width for scanning is specified from the
- *	userspace
  * @ie: optional information element(s) to add into Probe Request or %NULL
  * @ie_len: length of ie in octets
  * @flags: bit field of flags controlling operation
@@ -2578,7 +2573,6 @@ struct cfg80211_sched_scan_request {
 	int n_ssids;
 	u32 n_channels;
 	enum nl80211_bss_scan_width scan_width;
-	bool scan_width_set;
 	const u8 *ie;
 	size_t ie_len;
 	u32 flags;
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 03b60d987a1b..3f15ac05f581 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -501,13 +501,7 @@
  *	%NL80211_ATTR_TX_NO_CCK_RATE is used to decide whether to send the
  *	probe requests at CCK rate or not. %NL80211_ATTR_BSSID can be used to
  *	specify a BSSID to scan for; if not included, the wildcard BSSID will
- *	be used. %NL80211_ATTR_CHANNEL_WIDTH can be passed from the userspace
- *	to specify the scan channel bandwidth; if channel bandwidth lower than
- *	20 MHz is specified, it is expected that only BSSs using this channel
- *	bandwidth can be found; if 20 MHz or higher channel bandwidth is
- *	specified, it is expected that all the BSSs using 20 MHz or higher
- *	channel bandwidth can be found; if not included, the scan channel
- *	bandwidth will be decided by the driver.
+ *	be used.
  * @NL80211_CMD_NEW_SCAN_RESULTS: scan notification (as a reply to
  *	NL80211_CMD_GET_SCAN and on the "scan" multicast group)
  * @NL80211_CMD_SCAN_ABORTED: scan was aborted, for unspecified reasons,
@@ -536,13 +530,6 @@
  *	is supplied. If the device supports multiple concurrent scheduled
  *	scans, it will allow such when the caller provides the flag attribute
  *	%NL80211_ATTR_SCHED_SCAN_MULTI to indicate user-space support for it.
- *	%NL80211_ATTR_CHANNEL_WIDTH can be passed from the userspace to specify
- *	the scan channel width; if channel bandwidth lower than 20 MHz is
- *	specified, it is expected that only BSSs using this channel bandwidth
- *	can be found; if 20 MHz or higher channel bandwidth is specified, it is
- *	expected that all the BSSs using 20 MHz or higher channel bandwidth can
- *	be found; if not included, the scan channel bandwidth will be decided by
- *	the driver.
  * @NL80211_CMD_STOP_SCHED_SCAN: stop a scheduled scan. Returns -ENOENT if
  *	scheduled scan is not running. The caller may assume that as soon
  *	as the call returns, it is safe to start a new scheduled scan again.
@@ -4888,8 +4875,6 @@ enum nl80211_key_mode {
  * @NL80211_CHAN_WIDTH_16: 16 MHz OFDM channel
  * @NL80211_CHAN_WIDTH_320: 320 MHz channel, the %NL80211_ATTR_CENTER_FREQ1
  *	attribute must be provided as well
- * @NUM_NL80211_CHAN_WIDTH: number of values, avoid using this in userspace
- *	since newer kernel versions may support more channel widths
  */
 enum nl80211_chan_width {
 	NL80211_CHAN_WIDTH_20_NOHT,
@@ -4906,8 +4891,6 @@ enum nl80211_chan_width {
 	NL80211_CHAN_WIDTH_8,
 	NL80211_CHAN_WIDTH_16,
 	NL80211_CHAN_WIDTH_320,
-
-	NUM_NL80211_CHAN_WIDTH
 };
 
 /**
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 2048a98c3273..64cf6110ce9d 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -478,8 +478,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
 						NL80211_EDMG_BW_CONFIG_MIN,
 						NL80211_EDMG_BW_CONFIG_MAX),
 
-	[NL80211_ATTR_CHANNEL_WIDTH] =
-		NLA_POLICY_MAX(NLA_U32, NUM_NL80211_CHAN_WIDTH),
+	[NL80211_ATTR_CHANNEL_WIDTH] = { .type = NLA_U32 },
 	[NL80211_ATTR_CENTER_FREQ1] = { .type = NLA_U32 },
 	[NL80211_ATTR_CENTER_FREQ1_OFFSET] = NLA_POLICY_RANGE(NLA_U32, 0, 999),
 	[NL80211_ATTR_CENTER_FREQ2] = { .type = NLA_U32 },
@@ -8925,34 +8924,6 @@ nl80211_check_scan_flags(struct wiphy *wiphy, struct wireless_dev *wdev,
 	return 0;
 }
 
-static enum nl80211_bss_scan_width
-chan_width_to_scan_width(enum nl80211_chan_width width)
-{
-	switch (width) {
-	case NL80211_CHAN_WIDTH_5:
-		return NL80211_BSS_CHAN_WIDTH_5;
-	case NL80211_CHAN_WIDTH_10:
-		return NL80211_BSS_CHAN_WIDTH_10;
-	case NL80211_CHAN_WIDTH_1:
-		return NL80211_BSS_CHAN_WIDTH_1;
-	case NL80211_CHAN_WIDTH_2:
-		return NL80211_BSS_CHAN_WIDTH_2;
-	case NL80211_CHAN_WIDTH_4:
-		return NL80211_BSS_CHAN_WIDTH_4;
-	case NL80211_CHAN_WIDTH_8:
-		return NL80211_BSS_CHAN_WIDTH_8;
-	case NL80211_CHAN_WIDTH_16:
-		return NL80211_BSS_CHAN_WIDTH_16;
-	default:
-		/* for the rest of channel bandwidth values (20 MHz or higher),
-		 * scan channel bandwidth can be set to NL80211_BSS_CHAN_WIDTH_20
-		 * as management frames of BSSs using 20 MHz or higher channel
-		 * can be received on the primary 20 MHz channel
-		 */
-		return NL80211_BSS_CHAN_WIDTH_20;
-	}
-}
-
 static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
 {
 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -9149,14 +9120,6 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
 			nla_get_flag(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY]);
 	}
 
-	if (info->attrs[NL80211_ATTR_CHANNEL_WIDTH]) {
-		enum nl80211_chan_width chan_width;
-
-		chan_width = nla_get_u32(info->attrs[NL80211_ATTR_CHANNEL_WIDTH]);
-		request->scan_width = chan_width_to_scan_width(chan_width);
-		request->scan_width_set = true;
-	}
-
 	err = nl80211_check_scan_flags(wiphy, wdev, request, info->attrs,
 				       false);
 	if (err)
@@ -9648,14 +9611,6 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
 		       request->ie_len);
 	}
 
-	if (attrs[NL80211_ATTR_CHANNEL_WIDTH]) {
-		enum nl80211_chan_width chan_width;
-
-		chan_width = nla_get_u32(attrs[NL80211_ATTR_CHANNEL_WIDTH]);
-		request->scan_width = chan_width_to_scan_width(chan_width);
-		request->scan_width_set = true;
-	}
-
 	err = nl80211_check_scan_flags(wiphy, wdev, request, attrs, true);
 	if (err)
 		goto out_free;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/4] wifi: nl80211: Add support to specify channel width for scan (option 2)
  2023-03-01  9:02 [PATCH 0/4] wifi: nl80211: Add support to specify channel width for scan Xinyue Ling
                   ` (2 preceding siblings ...)
  2023-03-01  9:02 ` [PATCH 3/4] Revert "wifi: nl80211: Add support to specify channel width for scan (option 1)" Xinyue Ling
@ 2023-03-01  9:02 ` Xinyue Ling
  2023-03-07  9:20 ` [PATCH 0/4] wifi: nl80211: Add support to specify channel width for scan Johannes Berg
  4 siblings, 0 replies; 6+ messages in thread
From: Xinyue Ling @ 2023-03-01  9:02 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless

Introduce a new NL80211_ATTR_SCAN_CHANNEL_WIDTH attribute
with enum nl80211_bss_scan_width semantics and add support
to parse it for nl80211_commands NL80211_CMD_TRIGGER_SCAN
and NL80211_CMD_START_SCHED_SCAN. Also add a new
scan_width_set flag in the scan request sent to the driver
to indicate whether the scan channel width is passed from
the userspace.

If channel width lower than 20 MHz is specified, it is
expected that only BSSs using this channel width can be
found. If 20 MHz or higher channel width is specified, it
is expected that all the BSSs using 20 MHz or higher channel
width can be found as their management frames can be received
on the primary 20 MHz channel. If this attribute is not passed
from the userspace, the scan channel width will be decided by
the driver.

One example for such use case is connection between drone
and drone controller, userspace may need to specify the
scan channel width, which needs to be passed to the driver
to trigger the scan on this specified channel width.

Signed-off-by: Xinyue Ling <quic_xinyling@quicinc.com>
---
 include/net/cfg80211.h       |  6 ++++++
 include/uapi/linux/nl80211.h | 28 ++++++++++++++++++++++++++--
 net/wireless/nl80211.c       | 14 ++++++++++++++
 3 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 54a77d906b2d..bbf566190a87 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2400,6 +2400,8 @@ struct cfg80211_scan_6ghz_params {
  * @channels: channels to scan on.
  * @n_channels: total number of channels to scan
  * @scan_width: channel width for scanning
+ * @scan_width_set: channel width for scanning is specified from the
+ *	userspace
  * @ie: optional information element(s) to add into Probe Request or %NULL
  * @ie_len: length of ie in octets
  * @duration: how long to listen on each channel, in TUs. If
@@ -2430,6 +2432,7 @@ struct cfg80211_scan_request {
 	int n_ssids;
 	u32 n_channels;
 	enum nl80211_bss_scan_width scan_width;
+	bool scan_width_set;
 	const u8 *ie;
 	size_t ie_len;
 	u16 duration;
@@ -2525,6 +2528,8 @@ struct cfg80211_bss_select_adjust {
  * @n_ssids: number of SSIDs
  * @n_channels: total number of channels to scan
  * @scan_width: channel width for scanning
+ * @scan_width_set: channel width for scanning is specified from the
+ *	userspace
  * @ie: optional information element(s) to add into Probe Request or %NULL
  * @ie_len: length of ie in octets
  * @flags: bit field of flags controlling operation
@@ -2573,6 +2578,7 @@ struct cfg80211_sched_scan_request {
 	int n_ssids;
 	u32 n_channels;
 	enum nl80211_bss_scan_width scan_width;
+	bool scan_width_set;
 	const u8 *ie;
 	size_t ie_len;
 	u32 flags;
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 3f15ac05f581..6d78185bb728 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -501,7 +501,13 @@
  *	%NL80211_ATTR_TX_NO_CCK_RATE is used to decide whether to send the
  *	probe requests at CCK rate or not. %NL80211_ATTR_BSSID can be used to
  *	specify a BSSID to scan for; if not included, the wildcard BSSID will
- *	be used.
+ *	be used. %NL80211_ATTR_SCAN_CHANNEL_WIDTH can be passed from the
+ *	userspace to specify the scan channel width; if channel bandwidth lower
+ *	than 20 MHz is specified, it is expected that only BSSs using this channel
+ *	bandwidth can be found; if 20 MHz or higher channel bandwidth channel
+ *	bandwidth is specified, it is expected that all the BSSs using 20 MHz or
+ *	higher channel bandwidth can be found; if not included, the scan channel
+ *	bandwidth will be decided by the driver.
  * @NL80211_CMD_NEW_SCAN_RESULTS: scan notification (as a reply to
  *	NL80211_CMD_GET_SCAN and on the "scan" multicast group)
  * @NL80211_CMD_SCAN_ABORTED: scan was aborted, for unspecified reasons,
@@ -530,6 +536,13 @@
  *	is supplied. If the device supports multiple concurrent scheduled
  *	scans, it will allow such when the caller provides the flag attribute
  *	%NL80211_ATTR_SCHED_SCAN_MULTI to indicate user-space support for it.
+ *	%NL80211_ATTR_SCAN_CHANNEL_WIDTH can be passed from the userspace to
+ *	specify the scan channel width; if channel bandwidth lower than 20 MHz
+ *	is specified, it is expected that only BSSs using this channel bandwidth
+ *	can be found; if 20 MHz or higher channel bandwidth channel bandwidth is
+ *	specified, it is expected that all the BSSs using 20 MHz or higher channel
+ *	bandwidth can be found; if not included, the scan channel bandwidth will
+ *	be decided by the driver.
  * @NL80211_CMD_STOP_SCHED_SCAN: stop a scheduled scan. Returns -ENOENT if
  *	scheduled scan is not running. The caller may assume that as soon
  *	as the call returns, it is safe to start a new scheduled scan again.
@@ -2752,6 +2765,9 @@ enum nl80211_commands {
  *	the incoming frame RX timestamp.
  * @NL80211_ATTR_TD_BITMAP: Transition Disable bitmap, for subsequent
  *	(re)associations.
+ * @NL80211_ATTR_SCAN_CHANNEL_WIDTH: u32 attribute containing one of the
+ *	values of &enum nl80211_bss_scan_width, describing the scan channel
+ *	width. See the documentation of the enum for more information.
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3281,6 +3297,8 @@ enum nl80211_attrs {
 	NL80211_ATTR_RX_HW_TIMESTAMP,
 	NL80211_ATTR_TD_BITMAP,
 
+	NL80211_ATTR_SCAN_CHANNEL_WIDTH,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
@@ -4896,7 +4914,8 @@ enum nl80211_chan_width {
 /**
  * enum nl80211_bss_scan_width - control channel width for a BSS
  *
- * These values are used with the %NL80211_BSS_CHAN_WIDTH attribute.
+ * These values are used with the %NL80211_BSS_CHAN_WIDTH attribute
+ * and the %NL80211_ATTR_SCAN_CHANNEL_WIDTH attribute.
  *
  * @NL80211_BSS_CHAN_WIDTH_20: control channel is 20 MHz wide or compatible
  * @NL80211_BSS_CHAN_WIDTH_10: control channel is 10 MHz wide
@@ -4906,6 +4925,9 @@ enum nl80211_chan_width {
  * @NL80211_BSS_CHAN_WIDTH_4: control channel is 4 MHz wide
  * @NL80211_BSS_CHAN_WIDTH_8: control channel is 8 MHz wide
  * @NL80211_BSS_CHAN_WIDTH_16: control channel is 16 MHz wide
+ * @NUM_NL80211_BSS_CHAN_WIDTH: number of values, avoid using this in
+ *	userspace since newer kernel versions may support more channel
+ *	widths
  */
 enum nl80211_bss_scan_width {
 	NL80211_BSS_CHAN_WIDTH_20,
@@ -4916,6 +4938,8 @@ enum nl80211_bss_scan_width {
 	NL80211_BSS_CHAN_WIDTH_4,
 	NL80211_BSS_CHAN_WIDTH_8,
 	NL80211_BSS_CHAN_WIDTH_16,
+
+	NUM_NL80211_BSS_CHAN_WIDTH
 };
 
 /**
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 64cf6110ce9d..bcafeb0691d0 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -805,6 +805,8 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
 	[NL80211_ATTR_MLD_ADDR] = NLA_POLICY_EXACT_LEN(ETH_ALEN),
 	[NL80211_ATTR_MLO_SUPPORT] = { .type = NLA_FLAG },
 	[NL80211_ATTR_MAX_NUM_AKM_SUITES] = { .type = NLA_REJECT },
+	[NL80211_ATTR_SCAN_CHANNEL_WIDTH] =
+		NLA_POLICY_MAX(NLA_U32, NUM_NL80211_BSS_CHAN_WIDTH),
 };
 
 /* policy for the key attributes */
@@ -9120,6 +9122,12 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
 			nla_get_flag(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY]);
 	}
 
+	if (info->attrs[NL80211_ATTR_SCAN_CHANNEL_WIDTH]) {
+		request->scan_width =
+			nla_get_u32(info->attrs[NL80211_ATTR_SCAN_CHANNEL_WIDTH]);
+		request->scan_width_set = true;
+	}
+
 	err = nl80211_check_scan_flags(wiphy, wdev, request, info->attrs,
 				       false);
 	if (err)
@@ -9611,6 +9619,12 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
 		       request->ie_len);
 	}
 
+	if (attrs[NL80211_ATTR_SCAN_CHANNEL_WIDTH]) {
+		request->scan_width =
+			nla_get_u32(attrs[NL80211_ATTR_SCAN_CHANNEL_WIDTH]);
+		request->scan_width_set = true;
+	}
+
 	err = nl80211_check_scan_flags(wiphy, wdev, request, attrs, true);
 	if (err)
 		goto out_free;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/4] wifi: nl80211: Add support to specify channel width for scan
  2023-03-01  9:02 [PATCH 0/4] wifi: nl80211: Add support to specify channel width for scan Xinyue Ling
                   ` (3 preceding siblings ...)
  2023-03-01  9:02 ` [PATCH 4/4] wifi: nl80211: Add support to specify channel width for scan (option 2) Xinyue Ling
@ 2023-03-07  9:20 ` Johannes Berg
  4 siblings, 0 replies; 6+ messages in thread
From: Johannes Berg @ 2023-03-07  9:20 UTC (permalink / raw)
  To: Xinyue Ling; +Cc: linux-wireless

On Wed, 2023-03-01 at 17:02 +0800, Xinyue Ling wrote:
> nl80211_trigger_scan() processes scan request netlink attributes,
> defined in enum nl80211_attrs, and fills struct
> cfg80211_scan_request *request.
> 
> Currently there is no logic to fill this member:
> 	enum nl80211_bss_scan_width scan_width;

Right, noticed that too some time ago while working on MLO.

> We have a requirement to fill this member for drone use cases, in
> which drone controller needs to scan and connect to drone in 5 MHz
> or 10 MHz channel width (may support other channel widths lower
> than 20 MHz later).

:-(

> The following series of patches is the implementations of above two
> options. In order to make them a series, a revert patch is included,
> which can be ignored. Please review and decide which option is more
> reasonable and acceptable.

I'm not sure this matters so much right now ... either works. I suspect
a new attribute might be nicer (fsvo "nicer").

However, all this stuff is currently completely broken in mac80211. Are
you wanting to use it with mac80211? ieee80211_vif_get_shift() is fairly
much broken (deflink), and even if we don't expect to use MLO with
narrow channels, it's still a huge mess.

In fact, had I had enough time, I'd have removed all that code entirely
from mac80211 already, since it's clearly unreachable. There's nothing
that can ever select a narrow-band BSS since you can't actually scan
that way as you noticed too.


So ... for your use case:
 1) are you going to use mac80211?
 2) if not, which (upstream!) driver are you going to use?
 3) if yes, are you willing to dig through mac80211 and clean up all
    that narrow-band code:
     - to make sure it interacts well with MLO
       (even if it doesn't _support_ MLO),
     - to define it correctly wrt. what's supported such as
       HT/VHT/HE/EHT with narrow channels? How would that even work? I
       guess none of those - unless we're dealing with vendor
       extensions?
     - if we're dealing with vendor extensions here, anyone actually
       willing to commit to those and document them properly outside of
       just having a half-baked implementation?


So honestly, I'm not even going to look at these patches before I can
get some answers on this, because while it may work for your use case
right now, it's clearly a mess. For example, nothing prevents you even
from trying to create MLO out of a narrow-band and regular BSS, other
than that no AP would likely beacon that way ... Hopefully!! But I don't
think we should just hope that no AP does this and that wpa_s is smart
enough.

johannes

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2023-03-07  9:20 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-01  9:02 [PATCH 0/4] wifi: nl80211: Add support to specify channel width for scan Xinyue Ling
2023-03-01  9:02 ` [PATCH 1/4] nl80211: Add 4/8/16 MHz BSS control channel width definitions Xinyue Ling
2023-03-01  9:02 ` [PATCH 2/4] wifi: nl80211: Add support to specify channel width for scan (option 1) Xinyue Ling
2023-03-01  9:02 ` [PATCH 3/4] Revert "wifi: nl80211: Add support to specify channel width for scan (option 1)" Xinyue Ling
2023-03-01  9:02 ` [PATCH 4/4] wifi: nl80211: Add support to specify channel width for scan (option 2) Xinyue Ling
2023-03-07  9:20 ` [PATCH 0/4] wifi: nl80211: Add support to specify channel width for scan Johannes Berg

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.