blob: 2a7cd079ca5108921a4b5059c011defb9f32d0da [file] [log] [blame]
developerebaa5512023-04-19 18:23:21 +08001From 40e52a97b1bc7b280198cb63e11663d784bd48c8 Mon Sep 17 00:00:00 2001
2From: Aloka Dixit <quic_alokad@quicinc.com>
3Date: Mon, 30 Jan 2023 16:12:24 -0800
4Subject: [PATCH 5/9] wifi: cfg80211: move puncturing bitmap validation from
5 mac80211
6
7- Move ieee80211_valid_disable_subchannel_bitmap() from mlme.c to
8 chan.c, rename it as cfg80211_valid_disable_subchannel_bitmap()
9 and export it.
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.
13
14Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com>
15Link: https://lore.kernel.org/r/20230131001227.25014-2-quic_alokad@quicinc.com
16Signed-off-by: Johannes Berg <johannes.berg@intel.com>
17---
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(-)
22
23diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
24index 9420086..d532612 100644
25--- a/include/net/cfg80211.h
26+++ b/include/net/cfg80211.h
27@@ -8948,4 +8948,16 @@ static inline int cfg80211_color_change_notify(struct net_device *dev)
28 0, 0);
29 }
30
31+/**
32+ * cfg80211_valid_disable_subchannel_bitmap - validate puncturing bitmap
33+ * @bitmap: bitmap to be validated
34+ * @chandef: channel definition
35+ *
36+ * Validate the puncturing bitmap.
37+ *
38+ * Return: %true if the bitmap is valid. %false otherwise.
39+ */
40+bool cfg80211_valid_disable_subchannel_bitmap(u16 *bitmap,
41+ const struct cfg80211_chan_def *chandef);
42+
43 #endif /* __NET_CFG80211_H */
44diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
45index 8c69fd6..2716ae0 100644
46--- a/net/mac80211/mlme.c
47+++ b/net/mac80211/mlme.c
48@@ -88,67 +88,6 @@ MODULE_PARM_DESC(probe_wait_ms,
49 */
50 #define IEEE80211_SIGNAL_AVE_MIN_COUNT 4
51
52-struct ieee80211_per_bw_puncturing_values {
53- u8 len;
54- const u16 *valid_values;
55-};
56-
57-static const u16 puncturing_values_80mhz[] = {
58- 0x8, 0x4, 0x2, 0x1
59-};
60-
61-static const u16 puncturing_values_160mhz[] = {
62- 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1, 0xc0, 0x30, 0xc, 0x3
63-};
64-
65-static const u16 puncturing_values_320mhz[] = {
66- 0xc000, 0x3000, 0xc00, 0x300, 0xc0, 0x30, 0xc, 0x3, 0xf000, 0xf00,
67- 0xf0, 0xf, 0xfc00, 0xf300, 0xf0c0, 0xf030, 0xf00c, 0xf003, 0xc00f,
68- 0x300f, 0xc0f, 0x30f, 0xcf, 0x3f
69-};
70-
71-#define IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(_bw) \
72- { \
73- .len = ARRAY_SIZE(puncturing_values_ ## _bw ## mhz), \
74- .valid_values = puncturing_values_ ## _bw ## mhz \
75- }
76-
77-static const struct ieee80211_per_bw_puncturing_values per_bw_puncturing[] = {
78- IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(80),
79- IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(160),
80- IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(320)
81-};
82-
83-static bool ieee80211_valid_disable_subchannel_bitmap(u16 *bitmap,
84- enum nl80211_chan_width bw)
85-{
86- u32 idx, i;
87-
88- switch (bw) {
89- case NL80211_CHAN_WIDTH_80:
90- idx = 0;
91- break;
92- case NL80211_CHAN_WIDTH_160:
93- idx = 1;
94- break;
95- case NL80211_CHAN_WIDTH_320:
96- idx = 2;
97- break;
98- default:
99- *bitmap = 0;
100- break;
101- }
102-
103- if (!*bitmap)
104- return true;
105-
106- for (i = 0; i < per_bw_puncturing[idx].len; i++)
107- if (per_bw_puncturing[idx].valid_values[i] == *bitmap)
108- return true;
109-
110- return false;
111-}
112-
113 /*
114 * Extract from the given disabled subchannel bitmap (raw format
115 * from the EHT Operation Element) the bits for the subchannel
116@@ -206,8 +145,8 @@ ieee80211_handle_puncturing_bitmap(struct ieee80211_link_data *link,
117 ieee80211_extract_dis_subch_bmap(eht_oper, chandef,
118 bitmap);
119
120- if (ieee80211_valid_disable_subchannel_bitmap(&bitmap,
121- chandef->width))
122+ if (cfg80211_valid_disable_subchannel_bitmap(&bitmap,
123+ chandef))
124 break;
125 link->u.mgd.conn_flags |=
126 ieee80211_chandef_downgrade(chandef);
127@@ -5584,8 +5523,8 @@ static bool ieee80211_config_puncturing(struct ieee80211_link_data *link,
128 extracted == link->conf->eht_puncturing)
129 return true;
130
131- if (!ieee80211_valid_disable_subchannel_bitmap(&bitmap,
132- link->conf->chandef.width)) {
133+ if (!cfg80211_valid_disable_subchannel_bitmap(&bitmap,
134+ &link->conf->chandef)) {
135 link_info(link,
136 "Got an invalid disable subchannel bitmap from AP %pM: bitmap = 0x%x, bw = 0x%x. disconnect\n",
137 link->u.mgd.bssid,
138@@ -7072,8 +7011,8 @@ ieee80211_setup_assoc_link(struct ieee80211_sub_if_data *sdata,
139 u16 bitmap;
140
141 bitmap = get_unaligned_le16(disable_subchannel_bitmap);
142- if (ieee80211_valid_disable_subchannel_bitmap(&bitmap,
143- link->conf->chandef.width))
144+ if (cfg80211_valid_disable_subchannel_bitmap(&bitmap,
145+ &link->conf->chandef))
146 ieee80211_handle_puncturing_bitmap(link,
147 eht_oper,
148 bitmap,
149diff --git a/net/wireless/chan.c b/net/wireless/chan.c
150index 29b5c2f..d5ed976 100644
151--- a/net/wireless/chan.c
152+++ b/net/wireless/chan.c
153@@ -1460,3 +1460,72 @@ struct cfg80211_chan_def *wdev_chandef(struct wireless_dev *wdev,
154 }
155 }
156 EXPORT_SYMBOL(wdev_chandef);
157+
158+struct cfg80211_per_bw_puncturing_values {
159+ u8 len;
160+ const u16 *valid_values;
161+};
162+
163+static const u16 puncturing_values_80mhz[] = {
164+ 0x8, 0x4, 0x2, 0x1
165+};
166+
167+static const u16 puncturing_values_160mhz[] = {
168+ 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1, 0xc0, 0x30, 0xc, 0x3
169+};
170+
171+static const u16 puncturing_values_320mhz[] = {
172+ 0xc000, 0x3000, 0xc00, 0x300, 0xc0, 0x30, 0xc, 0x3, 0xf000, 0xf00,
173+ 0xf0, 0xf, 0xfc00, 0xf300, 0xf0c0, 0xf030, 0xf00c, 0xf003, 0xc00f,
174+ 0x300f, 0xc0f, 0x30f, 0xcf, 0x3f
175+};
176+
177+#define CFG80211_PER_BW_VALID_PUNCTURING_VALUES(_bw) \
178+ { \
179+ .len = ARRAY_SIZE(puncturing_values_ ## _bw ## mhz), \
180+ .valid_values = puncturing_values_ ## _bw ## mhz \
181+ }
182+
183+static const struct cfg80211_per_bw_puncturing_values per_bw_puncturing[] = {
184+ CFG80211_PER_BW_VALID_PUNCTURING_VALUES(80),
185+ CFG80211_PER_BW_VALID_PUNCTURING_VALUES(160),
186+ CFG80211_PER_BW_VALID_PUNCTURING_VALUES(320)
187+};
188+
189+bool cfg80211_valid_disable_subchannel_bitmap(u16 *bitmap,
190+ const struct cfg80211_chan_def *chandef)
191+{
192+ u32 idx, i, start_freq;
193+
194+ switch (chandef->width) {
195+ case NL80211_CHAN_WIDTH_80:
196+ idx = 0;
197+ start_freq = chandef->center_freq1 - 40;
198+ break;
199+ case NL80211_CHAN_WIDTH_160:
200+ idx = 1;
201+ start_freq = chandef->center_freq1 - 80;
202+ break;
203+ case NL80211_CHAN_WIDTH_320:
204+ idx = 2;
205+ start_freq = chandef->center_freq1 - 160;
206+ break;
207+ default:
208+ *bitmap = 0;
209+ break;
210+ }
211+
212+ if (!*bitmap)
213+ return true;
214+
215+ /* check if primary channel is punctured */
216+ if (*bitmap & (u16)BIT((chandef->chan->center_freq - start_freq) / 20))
217+ return false;
218+
219+ for (i = 0; i < per_bw_puncturing[idx].len; i++)
220+ if (per_bw_puncturing[idx].valid_values[i] == *bitmap)
221+ return true;
222+
223+ return false;
224+}
225+EXPORT_SYMBOL(cfg80211_valid_disable_subchannel_bitmap);
226--
2272.39.2
228