1 From b25413fed3d43e1ed3340df4d928971bb8639f66 Mon Sep 17 00:00:00 2001
2 From: Aloka Dixit <quic_alokad@quicinc.com>
3 Date: Mon, 30 Jan 2023 16:12:24 -0800
4 Subject: [PATCH] wifi: cfg80211: move puncturing bitmap validation from
7 - Move ieee80211_valid_disable_subchannel_bitmap() from mlme.c to
8 chan.c, rename it as cfg80211_valid_disable_subchannel_bitmap()
10 - Modify the prototype to include struct cfg80211_chan_def instead
11 of only bandwidth to support a check which returns false if the
12 primary channel is punctured.
14 Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com>
15 Link: https://lore.kernel.org/r/20230131001227.25014-2-quic_alokad@quicinc.com
16 Signed-off-by: Johannes Berg <johannes.berg@intel.com>
18 include/net/cfg80211.h | 12 +++++++
19 net/mac80211/mlme.c | 73 ++++--------------------------------------
20 net/wireless/chan.c | 69 +++++++++++++++++++++++++++++++++++++++
21 3 files changed, 87 insertions(+), 67 deletions(-)
23 --- a/include/net/cfg80211.h
24 +++ b/include/net/cfg80211.h
25 @@ -8951,4 +8951,16 @@ static inline int cfg80211_color_change_
30 + * cfg80211_valid_disable_subchannel_bitmap - validate puncturing bitmap
31 + * @bitmap: bitmap to be validated
32 + * @chandef: channel definition
34 + * Validate the puncturing bitmap.
36 + * Return: %true if the bitmap is valid. %false otherwise.
38 +bool cfg80211_valid_disable_subchannel_bitmap(u16 *bitmap,
39 + const struct cfg80211_chan_def *chandef);
41 #endif /* __NET_CFG80211_H */
42 --- a/net/mac80211/mlme.c
43 +++ b/net/mac80211/mlme.c
44 @@ -88,67 +88,6 @@ MODULE_PARM_DESC(probe_wait_ms,
46 #define IEEE80211_SIGNAL_AVE_MIN_COUNT 4
48 -struct ieee80211_per_bw_puncturing_values {
50 - const u16 *valid_values;
53 -static const u16 puncturing_values_80mhz[] = {
57 -static const u16 puncturing_values_160mhz[] = {
58 - 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1, 0xc0, 0x30, 0xc, 0x3
61 -static const u16 puncturing_values_320mhz[] = {
62 - 0xc000, 0x3000, 0xc00, 0x300, 0xc0, 0x30, 0xc, 0x3, 0xf000, 0xf00,
63 - 0xf0, 0xf, 0xfc00, 0xf300, 0xf0c0, 0xf030, 0xf00c, 0xf003, 0xc00f,
64 - 0x300f, 0xc0f, 0x30f, 0xcf, 0x3f
67 -#define IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(_bw) \
69 - .len = ARRAY_SIZE(puncturing_values_ ## _bw ## mhz), \
70 - .valid_values = puncturing_values_ ## _bw ## mhz \
73 -static const struct ieee80211_per_bw_puncturing_values per_bw_puncturing[] = {
74 - IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(80),
75 - IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(160),
76 - IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(320)
79 -static bool ieee80211_valid_disable_subchannel_bitmap(u16 *bitmap,
80 - enum nl80211_chan_width bw)
85 - case NL80211_CHAN_WIDTH_80:
88 - case NL80211_CHAN_WIDTH_160:
91 - case NL80211_CHAN_WIDTH_320:
102 - for (i = 0; i < per_bw_puncturing[idx].len; i++)
103 - if (per_bw_puncturing[idx].valid_values[i] == *bitmap)
110 * Extract from the given disabled subchannel bitmap (raw format
111 * from the EHT Operation Element) the bits for the subchannel
112 @@ -206,8 +145,8 @@ ieee80211_handle_puncturing_bitmap(struc
113 ieee80211_extract_dis_subch_bmap(eht_oper, chandef,
116 - if (ieee80211_valid_disable_subchannel_bitmap(&bitmap,
118 + if (cfg80211_valid_disable_subchannel_bitmap(&bitmap,
121 link->u.mgd.conn_flags |=
122 ieee80211_chandef_downgrade(chandef);
123 @@ -5584,8 +5523,8 @@ static bool ieee80211_config_puncturing(
124 extracted == link->conf->eht_puncturing)
127 - if (!ieee80211_valid_disable_subchannel_bitmap(&bitmap,
128 - link->conf->chandef.width)) {
129 + if (!cfg80211_valid_disable_subchannel_bitmap(&bitmap,
130 + &link->conf->chandef)) {
132 "Got an invalid disable subchannel bitmap from AP %pM: bitmap = 0x%x, bw = 0x%x. disconnect\n",
134 @@ -7072,8 +7011,8 @@ ieee80211_setup_assoc_link(struct ieee80
137 bitmap = get_unaligned_le16(disable_subchannel_bitmap);
138 - if (ieee80211_valid_disable_subchannel_bitmap(&bitmap,
139 - link->conf->chandef.width))
140 + if (cfg80211_valid_disable_subchannel_bitmap(&bitmap,
141 + &link->conf->chandef))
142 ieee80211_handle_puncturing_bitmap(link,
145 --- a/net/wireless/chan.c
146 +++ b/net/wireless/chan.c
147 @@ -1505,3 +1505,72 @@ struct cfg80211_chan_def *wdev_chandef(s
150 EXPORT_SYMBOL(wdev_chandef);
152 +struct cfg80211_per_bw_puncturing_values {
154 + const u16 *valid_values;
157 +static const u16 puncturing_values_80mhz[] = {
161 +static const u16 puncturing_values_160mhz[] = {
162 + 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1, 0xc0, 0x30, 0xc, 0x3
165 +static const u16 puncturing_values_320mhz[] = {
166 + 0xc000, 0x3000, 0xc00, 0x300, 0xc0, 0x30, 0xc, 0x3, 0xf000, 0xf00,
167 + 0xf0, 0xf, 0xfc00, 0xf300, 0xf0c0, 0xf030, 0xf00c, 0xf003, 0xc00f,
168 + 0x300f, 0xc0f, 0x30f, 0xcf, 0x3f
171 +#define CFG80211_PER_BW_VALID_PUNCTURING_VALUES(_bw) \
173 + .len = ARRAY_SIZE(puncturing_values_ ## _bw ## mhz), \
174 + .valid_values = puncturing_values_ ## _bw ## mhz \
177 +static const struct cfg80211_per_bw_puncturing_values per_bw_puncturing[] = {
178 + CFG80211_PER_BW_VALID_PUNCTURING_VALUES(80),
179 + CFG80211_PER_BW_VALID_PUNCTURING_VALUES(160),
180 + CFG80211_PER_BW_VALID_PUNCTURING_VALUES(320)
183 +bool cfg80211_valid_disable_subchannel_bitmap(u16 *bitmap,
184 + const struct cfg80211_chan_def *chandef)
186 + u32 idx, i, start_freq;
188 + switch (chandef->width) {
189 + case NL80211_CHAN_WIDTH_80:
191 + start_freq = chandef->center_freq1 - 40;
193 + case NL80211_CHAN_WIDTH_160:
195 + start_freq = chandef->center_freq1 - 80;
197 + case NL80211_CHAN_WIDTH_320:
199 + start_freq = chandef->center_freq1 - 160;
209 + /* check if primary channel is punctured */
210 + if (*bitmap & (u16)BIT((chandef->chan->center_freq - start_freq) / 20))
213 + for (i = 0; i < per_bw_puncturing[idx].len; i++)
214 + if (per_bw_puncturing[idx].valid_values[i] == *bitmap)
219 +EXPORT_SYMBOL(cfg80211_valid_disable_subchannel_bitmap);