blob: 75fe1bb4a0d0ab98881fd35718c8adeb9de2794a [file] [log] [blame]
developerebaa5512023-04-19 18:23:21 +08001From 63bd8cc91635ad129587df0227be49074538b36e Mon Sep 17 00:00:00 2001
2From: Aloka Dixit <quic_alokad@quicinc.com>
3Date: Mon, 30 Jan 2023 16:12:25 -0800
4Subject: [PATCH 6/9] wifi: nl80211: validate and configure puncturing bitmap
5
6- New feature flag, NL80211_EXT_FEATURE_PUNCT, to advertise
7 driver support for preamble puncturing in AP mode.
8- New attribute, NL80211_ATTR_PUNCT_BITMAP, to receive a puncturing
9 bitmap from the userspace during AP bring up (NL80211_CMD_START_AP)
10 and channel switch (NL80211_CMD_CHANNEL_SWITCH) operations. Each bit
11 corresponds to a 20 MHz channel in the operating bandwidth, lowest
12 bit for the lowest channel. Bit set to 1 indicates that the channel
13 is punctured. Higher 16 bits are reserved.
14- New members added to structures cfg80211_ap_settings and
15 cfg80211_csa_settings to propagate the bitmap to the driver after
16 validation.
17
18Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com>
19Signed-off-by: Muna Sinada <quic_msinada@quicinc.com>
20Link: https://lore.kernel.org/r/20230131001227.25014-3-quic_alokad@quicinc.com
21[move validation against 0xffff into policy]
22Signed-off-by: Johannes Berg <johannes.berg@intel.com>
23---
24 include/net/cfg80211.h | 8 ++++++++
25 include/uapi/linux/nl80211.h | 11 +++++++++++
26 net/wireless/nl80211.c | 32 ++++++++++++++++++++++++++++++++
27 3 files changed, 51 insertions(+)
28
29diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
30index d532612..9c65eda 100644
31--- a/include/net/cfg80211.h
32+++ b/include/net/cfg80211.h
33@@ -1327,6 +1327,9 @@ struct cfg80211_unsol_bcast_probe_resp {
34 * @fils_discovery: FILS discovery transmission parameters
35 * @unsol_bcast_probe_resp: Unsolicited broadcast probe response parameters
36 * @mbssid_config: AP settings for multiple bssid
37+ * @punct_bitmap: Preamble puncturing bitmap. Each bit represents
38+ * a 20 MHz channel, lowest bit corresponding to the lowest channel.
39+ * Bit set to 1 indicates that the channel is punctured.
40 */
41 struct cfg80211_ap_settings {
42 struct cfg80211_chan_def chandef;
43@@ -1361,6 +1364,7 @@ struct cfg80211_ap_settings {
44 struct cfg80211_fils_discovery fils_discovery;
45 struct cfg80211_unsol_bcast_probe_resp unsol_bcast_probe_resp;
46 struct cfg80211_mbssid_config mbssid_config;
47+ u16 punct_bitmap;
48 };
49
50 /**
51@@ -1378,6 +1382,9 @@ struct cfg80211_ap_settings {
52 * @radar_required: whether radar detection is required on the new channel
53 * @block_tx: whether transmissions should be blocked while changing
54 * @count: number of beacons until switch
55+ * @punct_bitmap: Preamble puncturing bitmap. Each bit represents
56+ * a 20 MHz channel, lowest bit corresponding to the lowest channel.
57+ * Bit set to 1 indicates that the channel is punctured.
58 */
59 struct cfg80211_csa_settings {
60 struct cfg80211_chan_def chandef;
61@@ -1390,6 +1397,7 @@ struct cfg80211_csa_settings {
62 bool radar_required;
63 bool block_tx;
64 u8 count;
65+ u16 punct_bitmap;
66 };
67
68 /**
69diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
70index c14a91b..173aef8 100644
71--- a/include/uapi/linux/nl80211.h
72+++ b/include/uapi/linux/nl80211.h
73@@ -2751,6 +2751,12 @@ enum nl80211_commands {
74 * the incoming frame RX timestamp.
75 * @NL80211_ATTR_TD_BITMAP: Transition Disable bitmap, for subsequent
76 * (re)associations.
77+ *
78+ * @NL80211_ATTR_PUNCT_BITMAP: (u32) Preamble puncturing bitmap, lowest
79+ * bit corresponds to the lowest 20 MHz channel. Each bit set to 1
80+ * indicates that the sub-channel is punctured. Higher 16 bits are
81+ * reserved.
82+ *
83 * @NUM_NL80211_ATTR: total number of nl80211_attrs available
84 * @NL80211_ATTR_MAX: highest attribute number currently defined
85 * @__NL80211_ATTR_AFTER_LAST: internal use
86@@ -3280,6 +3286,8 @@ enum nl80211_attrs {
87 NL80211_ATTR_RX_HW_TIMESTAMP,
88 NL80211_ATTR_TD_BITMAP,
89
90+ NL80211_ATTR_PUNCT_BITMAP,
91+
92 /* add attributes here, update the policy in nl80211.c */
93
94 __NL80211_ATTR_AFTER_LAST,
95@@ -6294,6 +6302,8 @@ enum nl80211_feature_flags {
96 * might apply, e.g. no scans in progress, no offchannel operations
97 * in progress, and no active connections.
98 *
99+ * @NL80211_EXT_FEATURE_PUNCT: Driver supports preamble puncturing in AP mode.
100+ *
101 * @NUM_NL80211_EXT_FEATURES: number of extended features.
102 * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
103 */
104@@ -6362,6 +6372,7 @@ enum nl80211_ext_feature_index {
105 NL80211_EXT_FEATURE_FILS_CRYPTO_OFFLOAD,
106 NL80211_EXT_FEATURE_RADAR_BACKGROUND,
107 NL80211_EXT_FEATURE_POWERED_ADDR_CHANGE,
108+ NL80211_EXT_FEATURE_PUNCT,
109
110 /* add new features before the definition below */
111 NUM_NL80211_EXT_FEATURES,
112diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
113index 6a97e52..4cc095d 100644
114--- a/net/wireless/nl80211.c
115+++ b/net/wireless/nl80211.c
116@@ -799,6 +799,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
117 [NL80211_ATTR_MLD_ADDR] = NLA_POLICY_EXACT_LEN(ETH_ALEN),
118 [NL80211_ATTR_MLO_SUPPORT] = { .type = NLA_FLAG },
119 [NL80211_ATTR_MAX_NUM_AKM_SUITES] = { .type = NLA_REJECT },
120+ [NL80211_ATTR_PUNCT_BITMAP] = NLA_POLICY_RANGE(NLA_U8, 0, 0xffff),
121 };
122
123 /* policy for the key attributes */
124@@ -3167,6 +3168,21 @@ static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev)
125 wdev->iftype == NL80211_IFTYPE_P2P_GO;
126 }
127
128+static int nl80211_parse_punct_bitmap(struct cfg80211_registered_device *rdev,
129+ struct genl_info *info,
130+ const struct cfg80211_chan_def *chandef,
131+ u16 *punct_bitmap)
132+{
133+ if (!wiphy_ext_feature_isset(&rdev->wiphy, NL80211_EXT_FEATURE_PUNCT))
134+ return -EINVAL;
135+
136+ *punct_bitmap = nla_get_u32(info->attrs[NL80211_ATTR_PUNCT_BITMAP]);
137+ if (!cfg80211_valid_disable_subchannel_bitmap(punct_bitmap, chandef))
138+ return -EINVAL;
139+
140+ return 0;
141+}
142+
143 int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
144 struct genl_info *info,
145 struct cfg80211_chan_def *chandef)
146@@ -5912,6 +5928,14 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
147 goto out;
148 }
149
150+ if (info->attrs[NL80211_ATTR_PUNCT_BITMAP]) {
151+ err = nl80211_parse_punct_bitmap(rdev, info,
152+ &params->chandef,
153+ &params->punct_bitmap);
154+ if (err)
155+ goto out;
156+ }
157+
158 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &params->chandef,
159 wdev->iftype)) {
160 err = -EINVAL;
161@@ -10050,6 +10074,14 @@ skip_beacons:
162 if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX])
163 params.block_tx = true;
164
165+ if (info->attrs[NL80211_ATTR_PUNCT_BITMAP]) {
166+ err = nl80211_parse_punct_bitmap(rdev, info,
167+ &params.chandef,
168+ &params.punct_bitmap);
169+ if (err)
170+ goto free;
171+ }
172+
173 wdev_lock(wdev);
174 err = rdev_channel_switch(rdev, dev, &params);
175 wdev_unlock(wdev);
176--
1772.39.2
178