]> Git Repo - linux.git/blame - net/wireless/chan.c
Linux 6.14-rc3
[linux.git] / net / wireless / chan.c
CommitLineData
b2441318 1// SPDX-License-Identifier: GPL-2.0
59bbb6f7
JB
2/*
3 * This file contains helper code to handle channel
4 * settings and keeping track of what is possible at
5 * any point in time.
6 *
7 * Copyright 2009 Johannes Berg <[email protected]>
2740f0cf 8 * Copyright 2013-2014 Intel Mobile Communications GmbH
b82730bf 9 * Copyright 2018-2024 Intel Corporation
59bbb6f7
JB
10 */
11
54858ee5 12#include <linux/export.h>
35799944 13#include <linux/bitfield.h>
59bbb6f7
JB
14#include <net/cfg80211.h>
15#include "core.h"
e35e4d28 16#include "rdev-ops.h"
59bbb6f7 17
2a38075c
AAL
18static bool cfg80211_valid_60g_freq(u32 freq)
19{
20 return freq >= 58320 && freq <= 70200;
21}
22
3d9d1d66
JB
23void cfg80211_chandef_create(struct cfg80211_chan_def *chandef,
24 struct ieee80211_channel *chan,
25 enum nl80211_channel_type chan_type)
9236d838 26{
3d9d1d66
JB
27 if (WARN_ON(!chan))
28 return;
9236d838 29
b82730bf
JB
30 *chandef = (struct cfg80211_chan_def) {
31 .chan = chan,
32 .freq1_offset = chan->freq_offset,
33 };
4ee3e063 34
3d9d1d66
JB
35 switch (chan_type) {
36 case NL80211_CHAN_NO_HT:
37 chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
38 chandef->center_freq1 = chan->center_freq;
39 break;
40 case NL80211_CHAN_HT20:
41 chandef->width = NL80211_CHAN_WIDTH_20;
42 chandef->center_freq1 = chan->center_freq;
43 break;
9236d838 44 case NL80211_CHAN_HT40PLUS:
3d9d1d66
JB
45 chandef->width = NL80211_CHAN_WIDTH_40;
46 chandef->center_freq1 = chan->center_freq + 10;
09a02fdb 47 break;
9236d838 48 case NL80211_CHAN_HT40MINUS:
3d9d1d66
JB
49 chandef->width = NL80211_CHAN_WIDTH_40;
50 chandef->center_freq1 = chan->center_freq - 10;
09a02fdb 51 break;
9236d838 52 default:
3d9d1d66
JB
53 WARN_ON(1);
54 }
55}
56EXPORT_SYMBOL(cfg80211_chandef_create);
57
9add0535
KK
58static int cfg80211_chandef_get_width(const struct cfg80211_chan_def *c)
59{
60 return nl80211_chan_width_to_mhz(c->width);
61}
62
63static u32 cfg80211_get_start_freq(const struct cfg80211_chan_def *chandef,
64 u32 cf)
65{
66 u32 start_freq, center_freq, bandwidth;
67
68 center_freq = MHZ_TO_KHZ((cf == 1) ?
69 chandef->center_freq1 : chandef->center_freq2);
70 bandwidth = MHZ_TO_KHZ(cfg80211_chandef_get_width(chandef));
71
72 if (bandwidth <= MHZ_TO_KHZ(20))
73 start_freq = center_freq;
74 else
75 start_freq = center_freq - bandwidth / 2 + MHZ_TO_KHZ(10);
76
77 return start_freq;
78}
79
80static u32 cfg80211_get_end_freq(const struct cfg80211_chan_def *chandef,
81 u32 cf)
82{
83 u32 end_freq, center_freq, bandwidth;
84
85 center_freq = MHZ_TO_KHZ((cf == 1) ?
86 chandef->center_freq1 : chandef->center_freq2);
87 bandwidth = MHZ_TO_KHZ(cfg80211_chandef_get_width(chandef));
88
89 if (bandwidth <= MHZ_TO_KHZ(20))
90 end_freq = center_freq;
91 else
92 end_freq = center_freq + bandwidth / 2 - MHZ_TO_KHZ(10);
93
94 return end_freq;
95}
96
97#define for_each_subchan(chandef, freq, cf) \
98 for (u32 punctured = chandef->punctured, \
99 cf = 1, freq = cfg80211_get_start_freq(chandef, cf); \
100 freq <= cfg80211_get_end_freq(chandef, cf); \
101 freq += MHZ_TO_KHZ(20), \
102 ((cf == 1 && chandef->center_freq2 != 0 && \
103 freq > cfg80211_get_end_freq(chandef, cf)) ? \
104 (cf++, freq = cfg80211_get_start_freq(chandef, cf), \
105 punctured = 0) : (punctured >>= 1))) \
106 if (!(punctured & 1))
107
719036ae
JB
108struct cfg80211_per_bw_puncturing_values {
109 u8 len;
110 const u16 *valid_values;
111};
112
113static const u16 puncturing_values_80mhz[] = {
114 0x8, 0x4, 0x2, 0x1
115};
116
117static const u16 puncturing_values_160mhz[] = {
118 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1, 0xc0, 0x30, 0xc, 0x3
119};
120
121static const u16 puncturing_values_320mhz[] = {
122 0xc000, 0x3000, 0xc00, 0x300, 0xc0, 0x30, 0xc, 0x3, 0xf000, 0xf00,
123 0xf0, 0xf, 0xfc00, 0xf300, 0xf0c0, 0xf030, 0xf00c, 0xf003, 0xc00f,
124 0x300f, 0xc0f, 0x30f, 0xcf, 0x3f
125};
126
127#define CFG80211_PER_BW_VALID_PUNCTURING_VALUES(_bw) \
128 { \
129 .len = ARRAY_SIZE(puncturing_values_ ## _bw ## mhz), \
130 .valid_values = puncturing_values_ ## _bw ## mhz \
131 }
132
133static const struct cfg80211_per_bw_puncturing_values per_bw_puncturing[] = {
134 CFG80211_PER_BW_VALID_PUNCTURING_VALUES(80),
135 CFG80211_PER_BW_VALID_PUNCTURING_VALUES(160),
136 CFG80211_PER_BW_VALID_PUNCTURING_VALUES(320)
137};
138
b82730bf 139static bool valid_puncturing_bitmap(const struct cfg80211_chan_def *chandef)
719036ae 140{
b82730bf 141 u32 idx, i, start_freq, primary_center = chandef->chan->center_freq;
719036ae
JB
142
143 switch (chandef->width) {
144 case NL80211_CHAN_WIDTH_80:
145 idx = 0;
146 start_freq = chandef->center_freq1 - 40;
147 break;
148 case NL80211_CHAN_WIDTH_160:
149 idx = 1;
150 start_freq = chandef->center_freq1 - 80;
151 break;
152 case NL80211_CHAN_WIDTH_320:
153 idx = 2;
154 start_freq = chandef->center_freq1 - 160;
155 break;
156 default:
b82730bf 157 return chandef->punctured == 0;
719036ae
JB
158 }
159
b82730bf 160 if (!chandef->punctured)
719036ae
JB
161 return true;
162
163 /* check if primary channel is punctured */
b82730bf 164 if (chandef->punctured & (u16)BIT((primary_center - start_freq) / 20))
719036ae
JB
165 return false;
166
b82730bf
JB
167 for (i = 0; i < per_bw_puncturing[idx].len; i++) {
168 if (per_bw_puncturing[idx].valid_values[i] == chandef->punctured)
719036ae 169 return true;
b82730bf 170 }
719036ae
JB
171
172 return false;
173}
719036ae 174
2a38075c
AAL
175static bool cfg80211_edmg_chandef_valid(const struct cfg80211_chan_def *chandef)
176{
177 int max_contiguous = 0;
178 int num_of_enabled = 0;
179 int contiguous = 0;
180 int i;
181
182 if (!chandef->edmg.channels || !chandef->edmg.bw_config)
183 return false;
184
185 if (!cfg80211_valid_60g_freq(chandef->chan->center_freq))
186 return false;
187
188 for (i = 0; i < 6; i++) {
189 if (chandef->edmg.channels & BIT(i)) {
190 contiguous++;
191 num_of_enabled++;
192 } else {
193 contiguous = 0;
194 }
195
196 max_contiguous = max(contiguous, max_contiguous);
197 }
198 /* basic verification of edmg configuration according to
199 * IEEE P802.11ay/D4.0 section 9.4.2.251
200 */
201 /* check bw_config against contiguous edmg channels */
202 switch (chandef->edmg.bw_config) {
203 case IEEE80211_EDMG_BW_CONFIG_4:
204 case IEEE80211_EDMG_BW_CONFIG_8:
205 case IEEE80211_EDMG_BW_CONFIG_12:
206 if (max_contiguous < 1)
207 return false;
208 break;
209 case IEEE80211_EDMG_BW_CONFIG_5:
210 case IEEE80211_EDMG_BW_CONFIG_9:
211 case IEEE80211_EDMG_BW_CONFIG_13:
212 if (max_contiguous < 2)
213 return false;
214 break;
215 case IEEE80211_EDMG_BW_CONFIG_6:
216 case IEEE80211_EDMG_BW_CONFIG_10:
217 case IEEE80211_EDMG_BW_CONFIG_14:
218 if (max_contiguous < 3)
219 return false;
220 break;
221 case IEEE80211_EDMG_BW_CONFIG_7:
222 case IEEE80211_EDMG_BW_CONFIG_11:
223 case IEEE80211_EDMG_BW_CONFIG_15:
224 if (max_contiguous < 4)
225 return false;
226 break;
227
228 default:
229 return false;
230 }
231
232 /* check bw_config against aggregated (non contiguous) edmg channels */
233 switch (chandef->edmg.bw_config) {
234 case IEEE80211_EDMG_BW_CONFIG_4:
235 case IEEE80211_EDMG_BW_CONFIG_5:
236 case IEEE80211_EDMG_BW_CONFIG_6:
237 case IEEE80211_EDMG_BW_CONFIG_7:
238 break;
239 case IEEE80211_EDMG_BW_CONFIG_8:
240 case IEEE80211_EDMG_BW_CONFIG_9:
241 case IEEE80211_EDMG_BW_CONFIG_10:
242 case IEEE80211_EDMG_BW_CONFIG_11:
243 if (num_of_enabled < 2)
244 return false;
245 break;
246 case IEEE80211_EDMG_BW_CONFIG_12:
247 case IEEE80211_EDMG_BW_CONFIG_13:
248 case IEEE80211_EDMG_BW_CONFIG_14:
249 case IEEE80211_EDMG_BW_CONFIG_15:
250 if (num_of_enabled < 4 || max_contiguous < 2)
251 return false;
252 break;
253 default:
254 return false;
255 }
256
257 return true;
258}
259
10fa22b6 260int nl80211_chan_width_to_mhz(enum nl80211_chan_width chan_width)
11b34737
TP
261{
262 int mhz;
263
264 switch (chan_width) {
265 case NL80211_CHAN_WIDTH_1:
266 mhz = 1;
267 break;
268 case NL80211_CHAN_WIDTH_2:
269 mhz = 2;
270 break;
271 case NL80211_CHAN_WIDTH_4:
272 mhz = 4;
273 break;
274 case NL80211_CHAN_WIDTH_8:
275 mhz = 8;
276 break;
277 case NL80211_CHAN_WIDTH_16:
278 mhz = 16;
279 break;
280 case NL80211_CHAN_WIDTH_5:
281 mhz = 5;
282 break;
283 case NL80211_CHAN_WIDTH_10:
284 mhz = 10;
285 break;
286 case NL80211_CHAN_WIDTH_20:
287 case NL80211_CHAN_WIDTH_20_NOHT:
288 mhz = 20;
289 break;
290 case NL80211_CHAN_WIDTH_40:
291 mhz = 40;
292 break;
293 case NL80211_CHAN_WIDTH_80P80:
294 case NL80211_CHAN_WIDTH_80:
295 mhz = 80;
296 break;
297 case NL80211_CHAN_WIDTH_160:
298 mhz = 160;
299 break;
3743bec6
JD
300 case NL80211_CHAN_WIDTH_320:
301 mhz = 320;
302 break;
11b34737
TP
303 default:
304 WARN_ON_ONCE(1);
305 return -1;
306 }
307 return mhz;
308}
10fa22b6 309EXPORT_SYMBOL(nl80211_chan_width_to_mhz);
11b34737 310
91b193d5
BB
311static bool cfg80211_valid_center_freq(u32 center,
312 enum nl80211_chan_width width)
313{
314 int bw;
315 int step;
316
317 /* We only do strict verification on 6 GHz */
318 if (center < 5955 || center > 7115)
319 return true;
320
321 bw = nl80211_chan_width_to_mhz(width);
322 if (bw < 0)
323 return false;
324
325 /* Validate that the channels bw is entirely within the 6 GHz band */
326 if (center - bw / 2 < 5945 || center + bw / 2 > 7125)
327 return false;
328
329 /* With 320 MHz the permitted channels overlap */
330 if (bw == 320)
331 step = 160;
332 else
333 step = bw;
334
335 /*
336 * Valid channels are packed from lowest frequency towards higher ones.
4b482281 337 * So test that the lower frequency aligns with one of these steps.
91b193d5
BB
338 */
339 return (center - bw / 2 - 5945) % step == 0;
340}
341
9f5e8f6e 342bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef)
3d9d1d66 343{
11b34737
TP
344 u32 control_freq, oper_freq;
345 int oper_width, control_width;
3d9d1d66
JB
346
347 if (!chandef->chan)
348 return false;
349
be689f68
JB
350 if (chandef->freq1_offset >= 1000)
351 return false;
352
3d9d1d66
JB
353 control_freq = chandef->chan->center_freq;
354
355 switch (chandef->width) {
2f301ab2
SW
356 case NL80211_CHAN_WIDTH_5:
357 case NL80211_CHAN_WIDTH_10:
3d9d1d66
JB
358 case NL80211_CHAN_WIDTH_20:
359 case NL80211_CHAN_WIDTH_20_NOHT:
934f4c7d
TP
360 if (ieee80211_chandef_to_khz(chandef) !=
361 ieee80211_channel_to_khz(chandef->chan))
3d9d1d66
JB
362 return false;
363 if (chandef->center_freq2)
364 return false;
365 break;
c1cd35c6 366 case NL80211_CHAN_WIDTH_1:
11b34737
TP
367 case NL80211_CHAN_WIDTH_2:
368 case NL80211_CHAN_WIDTH_4:
369 case NL80211_CHAN_WIDTH_8:
370 case NL80211_CHAN_WIDTH_16:
c1cd35c6
TP
371 if (chandef->chan->band != NL80211_BAND_S1GHZ)
372 return false;
373
11b34737
TP
374 control_freq = ieee80211_channel_to_khz(chandef->chan);
375 oper_freq = ieee80211_chandef_to_khz(chandef);
376 control_width = nl80211_chan_width_to_mhz(
377 ieee80211_s1g_channel_width(
378 chandef->chan));
379 oper_width = cfg80211_chandef_get_width(chandef);
380
381 if (oper_width < 0 || control_width < 0)
382 return false;
383 if (chandef->center_freq2)
384 return false;
385
386 if (control_freq + MHZ_TO_KHZ(control_width) / 2 >
387 oper_freq + MHZ_TO_KHZ(oper_width) / 2)
388 return false;
389
390 if (control_freq - MHZ_TO_KHZ(control_width) / 2 <
391 oper_freq - MHZ_TO_KHZ(oper_width) / 2)
392 return false;
393 break;
3d9d1d66 394 case NL80211_CHAN_WIDTH_80P80:
3d9d1d66
JB
395 if (!chandef->center_freq2)
396 return false;
9cab3151
JB
397 /* adjacent is not allowed -- that's a 160 MHz channel */
398 if (chandef->center_freq1 - chandef->center_freq2 == 80 ||
399 chandef->center_freq2 - chandef->center_freq1 == 80)
400 return false;
3d9d1d66 401 break;
3bb1ccc4 402 default:
3d9d1d66
JB
403 if (chandef->center_freq2)
404 return false;
405 break;
3bb1ccc4
JB
406 }
407
408 switch (chandef->width) {
409 case NL80211_CHAN_WIDTH_5:
410 case NL80211_CHAN_WIDTH_10:
411 case NL80211_CHAN_WIDTH_20:
412 case NL80211_CHAN_WIDTH_20_NOHT:
413 case NL80211_CHAN_WIDTH_1:
414 case NL80211_CHAN_WIDTH_2:
415 case NL80211_CHAN_WIDTH_4:
416 case NL80211_CHAN_WIDTH_8:
417 case NL80211_CHAN_WIDTH_16:
418 /* all checked above */
3d9d1d66 419 break;
3743bec6
JD
420 case NL80211_CHAN_WIDTH_320:
421 if (chandef->center_freq1 == control_freq + 150 ||
422 chandef->center_freq1 == control_freq + 130 ||
423 chandef->center_freq1 == control_freq + 110 ||
424 chandef->center_freq1 == control_freq + 90 ||
425 chandef->center_freq1 == control_freq - 90 ||
426 chandef->center_freq1 == control_freq - 110 ||
427 chandef->center_freq1 == control_freq - 130 ||
428 chandef->center_freq1 == control_freq - 150)
429 break;
430 fallthrough;
3bb1ccc4
JB
431 case NL80211_CHAN_WIDTH_160:
432 if (chandef->center_freq1 == control_freq + 70 ||
433 chandef->center_freq1 == control_freq + 50 ||
434 chandef->center_freq1 == control_freq - 50 ||
435 chandef->center_freq1 == control_freq - 70)
436 break;
437 fallthrough;
438 case NL80211_CHAN_WIDTH_80P80:
439 case NL80211_CHAN_WIDTH_80:
440 if (chandef->center_freq1 == control_freq + 30 ||
441 chandef->center_freq1 == control_freq - 30)
442 break;
443 fallthrough;
444 case NL80211_CHAN_WIDTH_40:
445 if (chandef->center_freq1 == control_freq + 10 ||
446 chandef->center_freq1 == control_freq - 10)
447 break;
448 fallthrough;
3d9d1d66
JB
449 default:
450 return false;
451 }
452
91b193d5
BB
453 if (!cfg80211_valid_center_freq(chandef->center_freq1, chandef->width))
454 return false;
455
456 if (chandef->width == NL80211_CHAN_WIDTH_80P80 &&
457 !cfg80211_valid_center_freq(chandef->center_freq2, chandef->width))
458 return false;
459
ec649fed
MH
460 /* channel 14 is only for IEEE 802.11b */
461 if (chandef->center_freq1 == 2484 &&
462 chandef->width != NL80211_CHAN_WIDTH_20_NOHT)
463 return false;
464
2a38075c
AAL
465 if (cfg80211_chandef_is_edmg(chandef) &&
466 !cfg80211_edmg_chandef_valid(chandef))
467 return false;
468
b82730bf 469 return valid_puncturing_bitmap(chandef);
3d9d1d66 470}
9f5e8f6e 471EXPORT_SYMBOL(cfg80211_chandef_valid);
3d9d1d66 472
b82730bf
JB
473int cfg80211_chandef_primary(const struct cfg80211_chan_def *c,
474 enum nl80211_chan_width primary_chan_width,
475 u16 *punctured)
3d9d1d66 476{
8f251a0a
JB
477 int pri_width = nl80211_chan_width_to_mhz(primary_chan_width);
478 int width = cfg80211_chandef_get_width(c);
479 u32 control = c->chan->center_freq;
480 u32 center = c->center_freq1;
b82730bf 481 u16 _punct = 0;
3d9d1d66 482
8f251a0a
JB
483 if (WARN_ON_ONCE(pri_width < 0 || width < 0))
484 return -1;
485
486 /* not intended to be called this way, can't determine */
487 if (WARN_ON_ONCE(pri_width > width))
488 return -1;
489
b82730bf
JB
490 if (!punctured)
491 punctured = &_punct;
492
493 *punctured = c->punctured;
494
8f251a0a 495 while (width > pri_width) {
b82730bf
JB
496 unsigned int bits_to_drop = width / 20 / 2;
497
498 if (control > center) {
8f251a0a 499 center += width / 4;
b82730bf
JB
500 *punctured >>= bits_to_drop;
501 } else {
8f251a0a 502 center -= width / 4;
b82730bf
JB
503 *punctured &= (1 << bits_to_drop) - 1;
504 }
8f251a0a 505 width /= 2;
3d9d1d66 506 }
8f251a0a
JB
507
508 return center;
3d9d1d66 509}
b82730bf 510EXPORT_SYMBOL(cfg80211_chandef_primary);
3d9d1d66 511
8f251a0a
JB
512static const struct cfg80211_chan_def *
513check_chandef_primary_compat(const struct cfg80211_chan_def *c1,
514 const struct cfg80211_chan_def *c2,
515 enum nl80211_chan_width primary_chan_width)
3d9d1d66 516{
b82730bf
JB
517 u16 punct_c1 = 0, punct_c2 = 0;
518
8f251a0a 519 /* check primary is compatible -> error if not */
b82730bf
JB
520 if (cfg80211_chandef_primary(c1, primary_chan_width, &punct_c1) !=
521 cfg80211_chandef_primary(c2, primary_chan_width, &punct_c2))
522 return ERR_PTR(-EINVAL);
523
524 if (punct_c1 != punct_c2)
8f251a0a
JB
525 return ERR_PTR(-EINVAL);
526
527 /* assumes c1 is smaller width, if that was just checked -> done */
528 if (c1->width == primary_chan_width)
529 return c2;
530
531 /* otherwise continue checking the next width */
532 return NULL;
533}
534
535static const struct cfg80211_chan_def *
536_cfg80211_chandef_compatible(const struct cfg80211_chan_def *c1,
537 const struct cfg80211_chan_def *c2)
538{
539 const struct cfg80211_chan_def *ret;
3d9d1d66
JB
540
541 /* If they are identical, return */
542 if (cfg80211_chandef_identical(c1, c2))
8f251a0a 543 return c2;
3d9d1d66
JB
544
545 /* otherwise, must have same control channel */
546 if (c1->chan != c2->chan)
547 return NULL;
548
549 /*
550 * If they have the same width, but aren't identical,
551 * then they can't be compatible.
552 */
553 if (c1->width == c2->width)
554 return NULL;
555
2f301ab2 556 /*
b9d908dc 557 * can't be compatible if one of them is 5/10 MHz or S1G
2f301ab2
SW
558 * but they don't have the same width.
559 */
b9d908dc
JB
560#define NARROW_OR_S1G(width) ((width) == NL80211_CHAN_WIDTH_5 || \
561 (width) == NL80211_CHAN_WIDTH_10 || \
562 (width) == NL80211_CHAN_WIDTH_1 || \
563 (width) == NL80211_CHAN_WIDTH_2 || \
564 (width) == NL80211_CHAN_WIDTH_4 || \
565 (width) == NL80211_CHAN_WIDTH_8 || \
566 (width) == NL80211_CHAN_WIDTH_16)
567
568 if (NARROW_OR_S1G(c1->width) || NARROW_OR_S1G(c2->width))
2f301ab2
SW
569 return NULL;
570
8f251a0a
JB
571 /*
572 * Make sure that c1 is always the narrower one, so that later
573 * we either return NULL or c2 and don't have to check both
574 * directions.
575 */
576 if (c1->width > c2->width)
577 swap(c1, c2);
578
579 /*
580 * No further checks needed if the "narrower" one is only 20 MHz.
581 * Here "narrower" includes being a 20 MHz non-HT channel vs. a
582 * 20 MHz HT (or later) one.
583 */
584 if (c1->width <= NL80211_CHAN_WIDTH_20)
3d9d1d66
JB
585 return c2;
586
8f251a0a
JB
587 ret = check_chandef_primary_compat(c1, c2, NL80211_CHAN_WIDTH_40);
588 if (ret)
589 return ret;
3d9d1d66 590
8f251a0a
JB
591 ret = check_chandef_primary_compat(c1, c2, NL80211_CHAN_WIDTH_80);
592 if (ret)
593 return ret;
3d9d1d66 594
8f251a0a
JB
595 /*
596 * If c1 is 80+80, then c2 is 160 or higher, but that cannot
597 * match. If c2 was also 80+80 it was already either accepted
598 * or rejected above (identical or not, respectively.)
599 */
600 if (c1->width == NL80211_CHAN_WIDTH_80P80)
3d9d1d66
JB
601 return NULL;
602
8f251a0a
JB
603 ret = check_chandef_primary_compat(c1, c2, NL80211_CHAN_WIDTH_160);
604 if (ret)
605 return ret;
3743bec6 606
8f251a0a
JB
607 /*
608 * Getting here would mean they're both wider than 160, have the
609 * same primary 160, but are not identical - this cannot happen
610 * since they must be 320 (no wider chandefs exist, at least yet.)
611 */
612 WARN_ON_ONCE(1);
3743bec6 613
8f251a0a
JB
614 return NULL;
615}
3743bec6 616
8f251a0a
JB
617const struct cfg80211_chan_def *
618cfg80211_chandef_compatible(const struct cfg80211_chan_def *c1,
619 const struct cfg80211_chan_def *c2)
620{
621 const struct cfg80211_chan_def *ret;
3743bec6 622
8f251a0a
JB
623 ret = _cfg80211_chandef_compatible(c1, c2);
624 if (IS_ERR(ret))
3d9d1d66 625 return NULL;
8f251a0a 626 return ret;
3d9d1d66
JB
627}
628EXPORT_SYMBOL(cfg80211_chandef_compatible);
629
04f39047
SW
630void cfg80211_set_dfs_state(struct wiphy *wiphy,
631 const struct cfg80211_chan_def *chandef,
632 enum nl80211_dfs_state dfs_state)
633{
9add0535 634 struct ieee80211_channel *c;
04f39047
SW
635 int width;
636
637 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
638 return;
639
640 width = cfg80211_chandef_get_width(chandef);
641 if (width < 0)
642 return;
643
9add0535
KK
644 for_each_subchan(chandef, freq, cf) {
645 c = ieee80211_get_channel_khz(wiphy, freq);
646 if (!c || !(c->flags & IEEE80211_CHAN_RADAR))
647 continue;
40d1ba63 648
9add0535
KK
649 c->dfs_state = dfs_state;
650 c->dfs_state_entered = jiffies;
651 }
40d1ba63
JD
652}
653
41a313d8
AO
654static bool
655cfg80211_dfs_permissive_check_wdev(struct cfg80211_registered_device *rdev,
656 enum nl80211_iftype iftype,
657 struct wireless_dev *wdev,
658 struct ieee80211_channel *chan)
659{
660 unsigned int link_id;
661
662 for_each_valid_link(wdev, link_id) {
663 struct ieee80211_channel *other_chan = NULL;
664 struct cfg80211_chan_def chandef = {};
665 int ret;
666
667 /* In order to avoid daisy chaining only allow BSS STA */
668 if (wdev->iftype != NL80211_IFTYPE_STATION ||
669 !wdev->links[link_id].client.current_bss)
670 continue;
671
672 other_chan =
673 wdev->links[link_id].client.current_bss->pub.channel;
674
675 if (!other_chan)
676 continue;
677
678 if (chan == other_chan)
679 return true;
680
681 /* continue if we can't get the channel */
682 ret = rdev_get_channel(rdev, wdev, link_id, &chandef);
683 if (ret)
684 continue;
685
686 if (cfg80211_is_sub_chan(&chandef, chan, false))
687 return true;
688 }
689
690 return false;
691}
692
693/*
694 * Check if P2P GO is allowed to operate on a DFS channel
695 */
696static bool cfg80211_dfs_permissive_chan(struct wiphy *wiphy,
697 enum nl80211_iftype iftype,
698 struct ieee80211_channel *chan)
699{
700 struct wireless_dev *wdev;
701 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
702
703 lockdep_assert_held(&rdev->wiphy.mtx);
704
705 if (!wiphy_ext_feature_isset(&rdev->wiphy,
706 NL80211_EXT_FEATURE_DFS_CONCURRENT) ||
707 !(chan->flags & IEEE80211_CHAN_DFS_CONCURRENT))
708 return false;
709
710 /* only valid for P2P GO */
711 if (iftype != NL80211_IFTYPE_P2P_GO)
712 return false;
713
714 /*
715 * Allow only if there's a concurrent BSS
716 */
717 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
718 bool ret = cfg80211_dfs_permissive_check_wdev(rdev, iftype,
719 wdev, chan);
720 if (ret)
721 return ret;
722 }
723
724 return false;
725}
726
04f39047 727static int cfg80211_get_chans_dfs_required(struct wiphy *wiphy,
9add0535
KK
728 const struct cfg80211_chan_def *chandef,
729 enum nl80211_iftype iftype)
04f39047
SW
730{
731 struct ieee80211_channel *c;
04f39047 732
9add0535 733 for_each_subchan(chandef, freq, cf) {
934f4c7d 734 c = ieee80211_get_channel_khz(wiphy, freq);
04f39047
SW
735 if (!c)
736 return -EINVAL;
737
41a313d8
AO
738 if (c->flags & IEEE80211_CHAN_RADAR &&
739 !cfg80211_dfs_permissive_chan(wiphy, iftype, c))
04f39047
SW
740 return 1;
741 }
41a313d8 742
04f39047
SW
743 return 0;
744}
745
746
747int cfg80211_chandef_dfs_required(struct wiphy *wiphy,
2beb6dab
LC
748 const struct cfg80211_chan_def *chandef,
749 enum nl80211_iftype iftype)
04f39047
SW
750{
751 int width;
2beb6dab 752 int ret;
04f39047
SW
753
754 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
755 return -EINVAL;
756
2beb6dab
LC
757 switch (iftype) {
758 case NL80211_IFTYPE_ADHOC:
759 case NL80211_IFTYPE_AP:
760 case NL80211_IFTYPE_P2P_GO:
761 case NL80211_IFTYPE_MESH_POINT:
762 width = cfg80211_chandef_get_width(chandef);
763 if (width < 0)
764 return -EINVAL;
04f39047 765
9add0535 766 ret = cfg80211_get_chans_dfs_required(wiphy, chandef, iftype);
04f39047 767
9add0535 768 return (ret > 0) ? BIT(chandef->width) : ret;
2beb6dab
LC
769 break;
770 case NL80211_IFTYPE_STATION:
6e0bd6c3 771 case NL80211_IFTYPE_OCB:
2beb6dab
LC
772 case NL80211_IFTYPE_P2P_CLIENT:
773 case NL80211_IFTYPE_MONITOR:
774 case NL80211_IFTYPE_AP_VLAN:
2beb6dab 775 case NL80211_IFTYPE_P2P_DEVICE:
cb3b7d87 776 case NL80211_IFTYPE_NAN:
2beb6dab 777 break;
e7e0517c 778 case NL80211_IFTYPE_WDS:
00ec75fc 779 case NL80211_IFTYPE_UNSPECIFIED:
2beb6dab
LC
780 case NUM_NL80211_IFTYPES:
781 WARN_ON(1);
782 }
783
784 return 0;
04f39047 785}
774f0734 786EXPORT_SYMBOL(cfg80211_chandef_dfs_required);
04f39047 787
9add0535
KK
788bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy,
789 const struct cfg80211_chan_def *chandef)
fe7c3a1f
JD
790{
791 struct ieee80211_channel *c;
9add0535 792 int width, count = 0;
fe7c3a1f 793
9add0535
KK
794 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
795 return false;
796
797 width = cfg80211_chandef_get_width(chandef);
798 if (width < 0)
799 return false;
fe7c3a1f
JD
800
801 /*
802 * Check entire range of channels for the bandwidth.
803 * Check all channels are DFS channels (DFS_USABLE or
804 * DFS_AVAILABLE). Return number of usable channels
805 * (require CAC). Allow DFS and non-DFS channel mix.
806 */
9add0535 807 for_each_subchan(chandef, freq, cf) {
934f4c7d 808 c = ieee80211_get_channel_khz(wiphy, freq);
fe7c3a1f 809 if (!c)
9add0535 810 return false;
fe7c3a1f
JD
811
812 if (c->flags & IEEE80211_CHAN_DISABLED)
9add0535 813 return false;
fe7c3a1f
JD
814
815 if (c->flags & IEEE80211_CHAN_RADAR) {
816 if (c->dfs_state == NL80211_DFS_UNAVAILABLE)
9add0535 817 return false;
fe7c3a1f
JD
818
819 if (c->dfs_state == NL80211_DFS_USABLE)
820 count++;
821 }
822 }
823
9add0535 824 return count > 0;
fe7c3a1f 825}
30ca8b0c 826EXPORT_SYMBOL(cfg80211_chandef_dfs_usable);
fe7c3a1f 827
b35a51c7
VT
828/*
829 * Checks if center frequency of chan falls with in the bandwidth
830 * range of chandef.
831 */
832bool cfg80211_is_sub_chan(struct cfg80211_chan_def *chandef,
7b0a0e3c
JB
833 struct ieee80211_channel *chan,
834 bool primary_only)
b35a51c7
VT
835{
836 int width;
a67a4893 837 u32 freq;
b35a51c7 838
7b0a0e3c
JB
839 if (!chandef->chan)
840 return false;
841
b35a51c7
VT
842 if (chandef->chan->center_freq == chan->center_freq)
843 return true;
844
7b0a0e3c
JB
845 if (primary_only)
846 return false;
847
b35a51c7
VT
848 width = cfg80211_chandef_get_width(chandef);
849 if (width <= 20)
850 return false;
851
b35a51c7
VT
852 for (freq = chandef->center_freq1 - width / 2 + 10;
853 freq <= chandef->center_freq1 + width / 2 - 10; freq += 20) {
854 if (chan->center_freq == freq)
855 return true;
856 }
857
858 if (!chandef->center_freq2)
859 return false;
860
861 for (freq = chandef->center_freq2 - width / 2 + 10;
862 freq <= chandef->center_freq2 + width / 2 - 10; freq += 20) {
863 if (chan->center_freq == freq)
864 return true;
865 }
866
867 return false;
868}
869
870bool cfg80211_beaconing_iface_active(struct wireless_dev *wdev)
871{
7b0a0e3c 872 unsigned int link;
b35a51c7 873
076fc877 874 lockdep_assert_wiphy(wdev->wiphy);
b35a51c7 875
b35a51c7
VT
876 switch (wdev->iftype) {
877 case NL80211_IFTYPE_AP:
878 case NL80211_IFTYPE_P2P_GO:
7b0a0e3c
JB
879 for_each_valid_link(wdev, link) {
880 if (wdev->links[link].ap.beacon_interval)
881 return true;
882 }
b35a51c7
VT
883 break;
884 case NL80211_IFTYPE_ADHOC:
7b0a0e3c
JB
885 if (wdev->u.ibss.ssid_len)
886 return true;
b35a51c7
VT
887 break;
888 case NL80211_IFTYPE_MESH_POINT:
7b0a0e3c
JB
889 if (wdev->u.mesh.id_len)
890 return true;
b35a51c7
VT
891 break;
892 case NL80211_IFTYPE_STATION:
893 case NL80211_IFTYPE_OCB:
894 case NL80211_IFTYPE_P2P_CLIENT:
895 case NL80211_IFTYPE_MONITOR:
896 case NL80211_IFTYPE_AP_VLAN:
b35a51c7
VT
897 case NL80211_IFTYPE_P2P_DEVICE:
898 /* Can NAN type be considered as beaconing interface? */
899 case NL80211_IFTYPE_NAN:
900 break;
901 case NL80211_IFTYPE_UNSPECIFIED:
e7e0517c 902 case NL80211_IFTYPE_WDS:
b35a51c7
VT
903 case NUM_NL80211_IFTYPES:
904 WARN_ON(1);
905 }
906
7b0a0e3c
JB
907 return false;
908}
909
910bool cfg80211_wdev_on_sub_chan(struct wireless_dev *wdev,
911 struct ieee80211_channel *chan,
912 bool primary_only)
913{
914 unsigned int link;
915
916 switch (wdev->iftype) {
917 case NL80211_IFTYPE_AP:
918 case NL80211_IFTYPE_P2P_GO:
919 for_each_valid_link(wdev, link) {
920 if (cfg80211_is_sub_chan(&wdev->links[link].ap.chandef,
921 chan, primary_only))
922 return true;
923 }
924 break;
925 case NL80211_IFTYPE_ADHOC:
926 return cfg80211_is_sub_chan(&wdev->u.ibss.chandef, chan,
927 primary_only);
928 case NL80211_IFTYPE_MESH_POINT:
929 return cfg80211_is_sub_chan(&wdev->u.mesh.chandef, chan,
930 primary_only);
931 default:
932 break;
933 }
934
935 return false;
b35a51c7
VT
936}
937
89766727
VT
938static bool cfg80211_is_wiphy_oper_chan(struct wiphy *wiphy,
939 struct ieee80211_channel *chan)
b35a51c7
VT
940{
941 struct wireless_dev *wdev;
942
076fc877
JB
943 lockdep_assert_wiphy(wiphy);
944
b35a51c7 945 list_for_each_entry(wdev, &wiphy->wdev_list, list) {
076fc877 946 if (!cfg80211_beaconing_iface_active(wdev))
b35a51c7 947 continue;
b35a51c7 948
076fc877 949 if (cfg80211_wdev_on_sub_chan(wdev, chan, false))
b35a51c7 950 return true;
b35a51c7
VT
951 }
952
953 return false;
954}
fe7c3a1f 955
84158164
LB
956static bool
957cfg80211_offchan_chain_is_active(struct cfg80211_registered_device *rdev,
958 struct ieee80211_channel *channel)
959{
a95bfb87 960 if (!rdev->background_radar_wdev)
84158164
LB
961 return false;
962
a95bfb87 963 if (!cfg80211_chandef_valid(&rdev->background_radar_chandef))
84158164
LB
964 return false;
965
7b0a0e3c
JB
966 return cfg80211_is_sub_chan(&rdev->background_radar_chandef, channel,
967 false);
84158164
LB
968}
969
89766727
VT
970bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy,
971 struct ieee80211_channel *chan)
972{
973 struct cfg80211_registered_device *rdev;
974
975 ASSERT_RTNL();
976
977 if (!(chan->flags & IEEE80211_CHAN_RADAR))
978 return false;
979
7483a214 980 for_each_rdev(rdev) {
fa8809a5
JB
981 bool found;
982
89766727
VT
983 if (!reg_dfs_domain_same(wiphy, &rdev->wiphy))
984 continue;
985
f42d22d3
JB
986 guard(wiphy)(&rdev->wiphy);
987
fa8809a5
JB
988 found = cfg80211_is_wiphy_oper_chan(&rdev->wiphy, chan) ||
989 cfg80211_offchan_chain_is_active(rdev, chan);
84158164 990
fa8809a5 991 if (found)
84158164 992 return true;
89766727
VT
993 }
994
995 return false;
996}
997
9add0535
KK
998static bool cfg80211_chandef_dfs_available(struct wiphy *wiphy,
999 const struct cfg80211_chan_def *chandef)
3d9d1d66
JB
1000{
1001 struct ieee80211_channel *c;
9add0535 1002 int width;
2c390e44
DL
1003 bool dfs_offload;
1004
9add0535
KK
1005 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
1006 return false;
1007
1008 width = cfg80211_chandef_get_width(chandef);
1009 if (width < 0)
1010 return false;
1011
2c390e44
DL
1012 dfs_offload = wiphy_ext_feature_isset(wiphy,
1013 NL80211_EXT_FEATURE_DFS_OFFLOAD);
2f301ab2 1014
6bc54fbc
JD
1015 /*
1016 * Check entire range of channels for the bandwidth.
1017 * If any channel in between is disabled or has not
1018 * had gone through CAC return false
1019 */
9add0535 1020 for_each_subchan(chandef, freq, cf) {
934f4c7d 1021 c = ieee80211_get_channel_khz(wiphy, freq);
04f39047
SW
1022 if (!c)
1023 return false;
1024
6bc54fbc
JD
1025 if (c->flags & IEEE80211_CHAN_DISABLED)
1026 return false;
1027
2c390e44
DL
1028 if ((c->flags & IEEE80211_CHAN_RADAR) &&
1029 (c->dfs_state != NL80211_DFS_AVAILABLE) &&
1030 !(c->dfs_state == NL80211_DFS_USABLE && dfs_offload))
04f39047 1031 return false;
6bc54fbc
JD
1032 }
1033
1034 return true;
1035}
1036
9add0535
KK
1037unsigned int
1038cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
1039 const struct cfg80211_chan_def *chandef)
6bc54fbc 1040{
9add0535 1041 struct ieee80211_channel *c;
6bc54fbc 1042 int width;
9add0535 1043 unsigned int t1 = 0, t2 = 0;
6bc54fbc
JD
1044
1045 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
9add0535 1046 return 0;
6bc54fbc
JD
1047
1048 width = cfg80211_chandef_get_width(chandef);
1049 if (width < 0)
9add0535 1050 return 0;
31559f35 1051
9add0535 1052 for_each_subchan(chandef, freq, cf) {
934f4c7d 1053 c = ieee80211_get_channel_khz(wiphy, freq);
9add0535
KK
1054 if (!c || (c->flags & IEEE80211_CHAN_DISABLED)) {
1055 if (cf == 1)
1056 t1 = INT_MAX;
1057 else
1058 t2 = INT_MAX;
1059 continue;
1060 }
31559f35
JD
1061
1062 if (!(c->flags & IEEE80211_CHAN_RADAR))
1063 continue;
1064
9add0535
KK
1065 if (cf == 1 && c->dfs_cac_ms > t1)
1066 t1 = c->dfs_cac_ms;
31559f35 1067
9add0535
KK
1068 if (cf == 2 && c->dfs_cac_ms > t2)
1069 t2 = c->dfs_cac_ms;
1070 }
31559f35 1071
9add0535 1072 if (t1 == INT_MAX && t2 == INT_MAX)
31559f35
JD
1073 return 0;
1074
9add0535
KK
1075 if (t1 == INT_MAX)
1076 return t2;
31559f35 1077
9add0535 1078 if (t2 == INT_MAX)
31559f35
JD
1079 return t1;
1080
31559f35
JD
1081 return max(t1, t2);
1082}
30ca8b0c 1083EXPORT_SYMBOL(cfg80211_chandef_dfs_cac_time);
6bc54fbc 1084
2a38075c
AAL
1085/* check if the operating channels are valid and supported */
1086static bool cfg80211_edmg_usable(struct wiphy *wiphy, u8 edmg_channels,
1087 enum ieee80211_edmg_bw_config edmg_bw_config,
1088 int primary_channel,
1089 struct ieee80211_edmg *edmg_cap)
1090{
1091 struct ieee80211_channel *chan;
1092 int i, freq;
1093 int channels_counter = 0;
1094
1095 if (!edmg_channels && !edmg_bw_config)
1096 return true;
1097
1098 if ((!edmg_channels && edmg_bw_config) ||
1099 (edmg_channels && !edmg_bw_config))
1100 return false;
1101
1102 if (!(edmg_channels & BIT(primary_channel - 1)))
1103 return false;
1104
1105 /* 60GHz channels 1..6 */
1106 for (i = 0; i < 6; i++) {
1107 if (!(edmg_channels & BIT(i)))
1108 continue;
1109
1110 if (!(edmg_cap->channels & BIT(i)))
1111 return false;
1112
1113 channels_counter++;
1114
1115 freq = ieee80211_channel_to_frequency(i + 1,
1116 NL80211_BAND_60GHZ);
1117 chan = ieee80211_get_channel(wiphy, freq);
1118 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
1119 return false;
1120 }
1121
1122 /* IEEE802.11 allows max 4 channels */
1123 if (channels_counter > 4)
1124 return false;
1125
1126 /* check bw_config is a subset of what driver supports
1127 * (see IEEE P802.11ay/D4.0 section 9.4.2.251, Table 13)
1128 */
1129 if ((edmg_bw_config % 4) > (edmg_cap->bw_config % 4))
1130 return false;
1131
1132 if (edmg_bw_config > edmg_cap->bw_config)
1133 return false;
1134
1135 return true;
1136}
1137
a110a3b7
JB
1138bool _cfg80211_chandef_usable(struct wiphy *wiphy,
1139 const struct cfg80211_chan_def *chandef,
ca41bfe3
JB
1140 u32 prohibited_flags,
1141 u32 permitting_flags)
3d9d1d66 1142{
9f5e8f6e
JB
1143 struct ieee80211_sta_ht_cap *ht_cap;
1144 struct ieee80211_sta_vht_cap *vht_cap;
2a38075c 1145 struct ieee80211_edmg *edmg_cap;
08f6f147 1146 u32 width, control_freq, cap;
3743bec6
JD
1147 bool ext_nss_cap, support_80_80 = false, support_320 = false;
1148 const struct ieee80211_sband_iftype_data *iftd;
1149 struct ieee80211_supported_band *sband;
9add0535 1150 struct ieee80211_channel *c;
3743bec6 1151 int i;
3d9d1d66 1152
9f5e8f6e
JB
1153 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
1154 return false;
3d9d1d66 1155
9f5e8f6e
JB
1156 ht_cap = &wiphy->bands[chandef->chan->band]->ht_cap;
1157 vht_cap = &wiphy->bands[chandef->chan->band]->vht_cap;
2a38075c 1158 edmg_cap = &wiphy->bands[chandef->chan->band]->edmg_cap;
e6ed929b
WG
1159 ext_nss_cap = __le16_to_cpu(vht_cap->vht_mcs.tx_highest) &
1160 IEEE80211_VHT_EXT_NSS_BW_CAPABLE;
2a38075c
AAL
1161
1162 if (edmg_cap->channels &&
1163 !cfg80211_edmg_usable(wiphy,
1164 chandef->edmg.channels,
1165 chandef->edmg.bw_config,
1166 chandef->chan->hw_value,
1167 edmg_cap))
1168 return false;
3d9d1d66 1169
9f5e8f6e 1170 control_freq = chandef->chan->center_freq;
9236d838 1171
3d9d1d66 1172 switch (chandef->width) {
df78a0c0
TP
1173 case NL80211_CHAN_WIDTH_1:
1174 width = 1;
1175 break;
1176 case NL80211_CHAN_WIDTH_2:
1177 width = 2;
1178 break;
1179 case NL80211_CHAN_WIDTH_4:
1180 width = 4;
1181 break;
1182 case NL80211_CHAN_WIDTH_8:
1183 width = 8;
1184 break;
1185 case NL80211_CHAN_WIDTH_16:
1186 width = 16;
1187 break;
2f301ab2
SW
1188 case NL80211_CHAN_WIDTH_5:
1189 width = 5;
1190 break;
1191 case NL80211_CHAN_WIDTH_10:
ea077c1c 1192 prohibited_flags |= IEEE80211_CHAN_NO_10MHZ;
2f301ab2
SW
1193 width = 10;
1194 break;
3d9d1d66 1195 case NL80211_CHAN_WIDTH_20:
ba8f6a03
JB
1196 if (!ht_cap->ht_supported &&
1197 chandef->chan->band != NL80211_BAND_6GHZ)
9f5e8f6e 1198 return false;
df561f66 1199 fallthrough;
9f5e8f6e 1200 case NL80211_CHAN_WIDTH_20_NOHT:
ea077c1c 1201 prohibited_flags |= IEEE80211_CHAN_NO_20MHZ;
3d9d1d66
JB
1202 width = 20;
1203 break;
1204 case NL80211_CHAN_WIDTH_40:
1205 width = 40;
ba8f6a03
JB
1206 if (chandef->chan->band == NL80211_BAND_6GHZ)
1207 break;
9f5e8f6e
JB
1208 if (!ht_cap->ht_supported)
1209 return false;
1210 if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ||
1211 ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT)
1212 return false;
1213 if (chandef->center_freq1 < control_freq &&
1214 chandef->chan->flags & IEEE80211_CHAN_NO_HT40MINUS)
1215 return false;
1216 if (chandef->center_freq1 > control_freq &&
1217 chandef->chan->flags & IEEE80211_CHAN_NO_HT40PLUS)
1218 return false;
3d9d1d66 1219 break;
3d9d1d66 1220 case NL80211_CHAN_WIDTH_80P80:
35799944
SB
1221 cap = vht_cap->cap;
1222 support_80_80 =
1223 (cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ) ||
1224 (cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ &&
1225 cap & IEEE80211_VHT_CAP_EXT_NSS_BW_MASK) ||
e6ed929b
WG
1226 (ext_nss_cap &&
1227 u32_get_bits(cap, IEEE80211_VHT_CAP_EXT_NSS_BW_MASK) > 1);
35799944 1228 if (chandef->chan->band != NL80211_BAND_6GHZ && !support_80_80)
9f5e8f6e 1229 return false;
df561f66 1230 fallthrough;
9f5e8f6e 1231 case NL80211_CHAN_WIDTH_80:
c7a6ee27 1232 prohibited_flags |= IEEE80211_CHAN_NO_80MHZ;
3d9d1d66 1233 width = 80;
ba8f6a03
JB
1234 if (chandef->chan->band == NL80211_BAND_6GHZ)
1235 break;
1236 if (!vht_cap->vht_supported)
1237 return false;
3d9d1d66
JB
1238 break;
1239 case NL80211_CHAN_WIDTH_160:
ba8f6a03
JB
1240 prohibited_flags |= IEEE80211_CHAN_NO_160MHZ;
1241 width = 160;
1242 if (chandef->chan->band == NL80211_BAND_6GHZ)
1243 break;
9f5e8f6e
JB
1244 if (!vht_cap->vht_supported)
1245 return false;
08f6f147
JM
1246 cap = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
1247 if (cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ &&
35799944 1248 cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ &&
e6ed929b
WG
1249 !(ext_nss_cap &&
1250 (vht_cap->cap & IEEE80211_VHT_CAP_EXT_NSS_BW_MASK)))
9f5e8f6e 1251 return false;
3d9d1d66 1252 break;
3743bec6
JD
1253 case NL80211_CHAN_WIDTH_320:
1254 prohibited_flags |= IEEE80211_CHAN_NO_320MHZ;
1255 width = 320;
1256
1257 if (chandef->chan->band != NL80211_BAND_6GHZ)
1258 return false;
1259
1260 sband = wiphy->bands[NL80211_BAND_6GHZ];
1261 if (!sband)
1262 return false;
1263
e8c18412 1264 for_each_sband_iftype_data(sband, i, iftd) {
3743bec6
JD
1265 if (!iftd->eht_cap.has_eht)
1266 continue;
1267
1268 if (iftd->eht_cap.eht_cap_elem.phy_cap_info[0] &
1269 IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ) {
1270 support_320 = true;
1271 break;
1272 }
1273 }
1274
1275 if (!support_320)
1276 return false;
1277 break;
3d9d1d66
JB
1278 default:
1279 WARN_ON_ONCE(1);
9236d838 1280 return false;
4ee3e063 1281 }
3d9d1d66 1282
c7a6ee27
JB
1283 /*
1284 * TODO: What if there are only certain 80/160/80+80 MHz channels
1285 * allowed by the driver, or only certain combinations?
1286 * For 40 MHz the driver can set the NO_HT40 flags, but for
1287 * 80/160 MHz and in particular 80+80 MHz this isn't really
1288 * feasible and we only have NO_80MHZ/NO_160MHZ so far but
1289 * no way to cover 80+80 MHz or more complex restrictions.
1290 * Note that such restrictions also need to be advertised to
1291 * userspace, for example for P2P channel selection.
1292 */
9f5e8f6e 1293
a6662dba
JB
1294 if (width > 20)
1295 prohibited_flags |= IEEE80211_CHAN_NO_OFDM;
1296
2f301ab2
SW
1297 /* 5 and 10 MHz are only defined for the OFDM PHY */
1298 if (width < 20)
1299 prohibited_flags |= IEEE80211_CHAN_NO_OFDM;
1300
9add0535
KK
1301 for_each_subchan(chandef, freq, cf) {
1302 c = ieee80211_get_channel_khz(wiphy, freq);
1303 if (!c)
1304 return false;
1305 if (c->flags & permitting_flags)
1306 continue;
1307 if (c->flags & prohibited_flags)
1308 return false;
1309 }
2f301ab2 1310
9add0535 1311 return true;
a110a3b7
JB
1312}
1313
1314bool cfg80211_chandef_usable(struct wiphy *wiphy,
1315 const struct cfg80211_chan_def *chandef,
1316 u32 prohibited_flags)
1317{
ca41bfe3 1318 return _cfg80211_chandef_usable(wiphy, chandef, prohibited_flags, 0);
9f5e8f6e
JB
1319}
1320EXPORT_SYMBOL(cfg80211_chandef_usable);
1321
7b0a0e3c
JB
1322static bool cfg80211_ir_permissive_check_wdev(enum nl80211_iftype iftype,
1323 struct wireless_dev *wdev,
1324 struct ieee80211_channel *chan)
1325{
1326 struct ieee80211_channel *other_chan = NULL;
1327 unsigned int link_id;
1328 int r1, r2;
1329
1330 for_each_valid_link(wdev, link_id) {
1331 if (wdev->iftype == NL80211_IFTYPE_STATION &&
1332 wdev->links[link_id].client.current_bss)
1333 other_chan = wdev->links[link_id].client.current_bss->pub.channel;
1334
1335 /*
1336 * If a GO already operates on the same GO_CONCURRENT channel,
1337 * this one (maybe the same one) can beacon as well. We allow
1338 * the operation even if the station we relied on with
1339 * GO_CONCURRENT is disconnected now. But then we must make sure
1340 * we're not outdoor on an indoor-only channel.
1341 */
1342 if (iftype == NL80211_IFTYPE_P2P_GO &&
1343 wdev->iftype == NL80211_IFTYPE_P2P_GO &&
1344 wdev->links[link_id].ap.beacon_interval &&
1345 !(chan->flags & IEEE80211_CHAN_INDOOR_ONLY))
1346 other_chan = wdev->links[link_id].ap.chandef.chan;
1347
1348 if (!other_chan)
1349 continue;
1350
1351 if (chan == other_chan)
1352 return true;
1353
1354 if (chan->band != NL80211_BAND_5GHZ &&
1355 chan->band != NL80211_BAND_6GHZ)
1356 continue;
1357
1358 r1 = cfg80211_get_unii(chan->center_freq);
1359 r2 = cfg80211_get_unii(other_chan->center_freq);
1360
1361 if (r1 != -EINVAL && r1 == r2) {
1362 /*
1363 * At some locations channels 149-165 are considered a
1364 * bundle, but at other locations, e.g., Indonesia,
1365 * channels 149-161 are considered a bundle while
1366 * channel 165 is left out and considered to be in a
1367 * different bundle. Thus, in case that there is a
1368 * station interface connected to an AP on channel 165,
1369 * it is assumed that channels 149-161 are allowed for
1370 * GO operations. However, having a station interface
1371 * connected to an AP on channels 149-161, does not
1372 * allow GO operation on channel 165.
1373 */
1374 if (chan->center_freq == 5825 &&
1375 other_chan->center_freq != 5825)
1376 continue;
1377 return true;
1378 }
1379 }
1380
1381 return false;
1382}
1383
174e0cd2 1384/*
06f207fc
AN
1385 * Check if the channel can be used under permissive conditions mandated by
1386 * some regulatory bodies, i.e., the channel is marked with
1387 * IEEE80211_CHAN_IR_CONCURRENT and there is an additional station interface
174e0cd2
IP
1388 * associated to an AP on the same channel or on the same UNII band
1389 * (assuming that the AP is an authorized master).
06f207fc 1390 * In addition allow operation on a channel on which indoor operation is
c8866e55 1391 * allowed, iff we are currently operating in an indoor environment.
174e0cd2 1392 */
06f207fc
AN
1393static bool cfg80211_ir_permissive_chan(struct wiphy *wiphy,
1394 enum nl80211_iftype iftype,
174e0cd2
IP
1395 struct ieee80211_channel *chan)
1396{
be69c24a 1397 struct wireless_dev *wdev;
06f207fc 1398 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
174e0cd2 1399
a05829a7 1400 lockdep_assert_held(&rdev->wiphy.mtx);
174e0cd2 1401
97f2645f 1402 if (!IS_ENABLED(CONFIG_CFG80211_REG_RELAX_NO_IR) ||
c8866e55
IP
1403 !(wiphy->regulatory_flags & REGULATORY_ENABLE_RELAX_NO_IR))
1404 return false;
1405
06f207fc
AN
1406 /* only valid for GO and TDLS off-channel (station/p2p-CL) */
1407 if (iftype != NL80211_IFTYPE_P2P_GO &&
1408 iftype != NL80211_IFTYPE_STATION &&
1409 iftype != NL80211_IFTYPE_P2P_CLIENT)
1410 return false;
1411
c8866e55
IP
1412 if (regulatory_indoor_allowed() &&
1413 (chan->flags & IEEE80211_CHAN_INDOOR_ONLY))
1414 return true;
1415
06f207fc 1416 if (!(chan->flags & IEEE80211_CHAN_IR_CONCURRENT))
174e0cd2
IP
1417 return false;
1418
1419 /*
1420 * Generally, it is possible to rely on another device/driver to allow
06f207fc 1421 * the IR concurrent relaxation, however, since the device can further
174e0cd2
IP
1422 * enforce the relaxation (by doing a similar verifications as this),
1423 * and thus fail the GO instantiation, consider only the interfaces of
1424 * the current registered device.
1425 */
53873f13 1426 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
7b0a0e3c 1427 bool ret;
174e0cd2 1428
7b0a0e3c 1429 ret = cfg80211_ir_permissive_check_wdev(iftype, wdev, chan);
7b0a0e3c
JB
1430 if (ret)
1431 return ret;
174e0cd2
IP
1432 }
1433
1434 return false;
1435}
1436
923b352f
AN
1437static bool _cfg80211_reg_can_beacon(struct wiphy *wiphy,
1438 struct cfg80211_chan_def *chandef,
1439 enum nl80211_iftype iftype,
c1d8bd8d
JB
1440 u32 prohibited_flags,
1441 u32 permitting_flags)
9f5e8f6e 1442{
c1d8bd8d 1443 bool res, check_radar;
41a313d8 1444 int dfs_required;
9f5e8f6e 1445
c1d8bd8d
JB
1446 trace_cfg80211_reg_can_beacon(wiphy, chandef, iftype,
1447 prohibited_flags,
1448 permitting_flags);
174e0cd2 1449
c1d8bd8d
JB
1450 if (!_cfg80211_chandef_usable(wiphy, chandef,
1451 IEEE80211_CHAN_DISABLED, 0))
1452 return false;
3d9d1d66 1453
41a313d8 1454 dfs_required = cfg80211_chandef_dfs_required(wiphy, chandef, iftype);
c1d8bd8d 1455 check_radar = dfs_required != 0;
41a313d8
AO
1456
1457 if (dfs_required > 0 &&
6bc54fbc
JD
1458 cfg80211_chandef_dfs_available(wiphy, chandef)) {
1459 /* We can skip IEEE80211_CHAN_NO_IR if chandef dfs available */
c1d8bd8d
JB
1460 prohibited_flags &= ~IEEE80211_CHAN_NO_IR;
1461 check_radar = false;
6bc54fbc
JD
1462 }
1463
c1d8bd8d
JB
1464 if (check_radar &&
1465 !_cfg80211_chandef_usable(wiphy, chandef,
1466 IEEE80211_CHAN_RADAR, 0))
1467 return false;
1468
1469 res = _cfg80211_chandef_usable(wiphy, chandef,
1470 prohibited_flags,
1471 permitting_flags);
3d9d1d66
JB
1472
1473 trace_cfg80211_return_bool(res);
1474 return res;
9236d838 1475}
923b352f 1476
9fd171a7
JB
1477bool cfg80211_reg_check_beaconing(struct wiphy *wiphy,
1478 struct cfg80211_chan_def *chandef,
1479 struct cfg80211_beaconing_check_config *cfg)
923b352f 1480{
a05829a7 1481 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
c1d8bd8d 1482 u32 permitting_flags = 0;
9fd171a7 1483 bool check_no_ir = true;
923b352f
AN
1484
1485 /*
1486 * Under certain conditions suggested by some regulatory bodies a
1487 * GO/STA can IR on channels marked with IEEE80211_NO_IR. Set this flag
1488 * only if such relaxations are not enabled and the conditions are not
1489 * met.
1490 */
9fd171a7
JB
1491 if (cfg->relax) {
1492 lockdep_assert_held(&rdev->wiphy.mtx);
1493 check_no_ir = !cfg80211_ir_permissive_chan(wiphy, cfg->iftype,
1494 chandef->chan);
1495 }
923b352f 1496
c1d8bd8d
JB
1497 if (cfg->reg_power == IEEE80211_REG_VLP_AP)
1498 permitting_flags |= IEEE80211_CHAN_ALLOW_6GHZ_VLP_AP;
1499
9fd171a7 1500 return _cfg80211_reg_can_beacon(wiphy, chandef, cfg->iftype,
c1d8bd8d
JB
1501 check_no_ir ? IEEE80211_CHAN_NO_IR : 0,
1502 permitting_flags);
923b352f 1503}
9fd171a7 1504EXPORT_SYMBOL(cfg80211_reg_check_beaconing);
923b352f 1505
e8c9bd5b 1506int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
9c4f8309 1507 struct net_device *dev,
683b6d3b 1508 struct cfg80211_chan_def *chandef)
9588bbd5 1509{
e8c9bd5b 1510 if (!rdev->ops->set_monitor_channel)
9588bbd5 1511 return -EOPNOTSUPP;
4f03c1ed
MK
1512 if (!cfg80211_has_monitors_only(rdev))
1513 return -EBUSY;
9588bbd5 1514
9c4f8309 1515 return rdev_set_monitor_channel(rdev, dev, chandef);
59bbb6f7 1516}
26ab9a0c 1517
be989891
JB
1518bool cfg80211_any_usable_channels(struct wiphy *wiphy,
1519 unsigned long sband_mask,
1520 u32 prohibited_flags)
1521{
1522 int idx;
1523
1524 prohibited_flags |= IEEE80211_CHAN_DISABLED;
1525
1526 for_each_set_bit(idx, &sband_mask, NUM_NL80211_BANDS) {
1527 struct ieee80211_supported_band *sband = wiphy->bands[idx];
1528 int chanidx;
1529
1530 if (!sband)
1531 continue;
1532
1533 for (chanidx = 0; chanidx < sband->n_channels; chanidx++) {
1534 struct ieee80211_channel *chan;
1535
1536 chan = &sband->channels[chanidx];
1537
1538 if (chan->flags & prohibited_flags)
1539 continue;
1540
1541 return true;
1542 }
1543 }
1544
1545 return false;
1546}
1547EXPORT_SYMBOL(cfg80211_any_usable_channels);
7b0a0e3c
JB
1548
1549struct cfg80211_chan_def *wdev_chandef(struct wireless_dev *wdev,
1550 unsigned int link_id)
1551{
076fc877
JB
1552 lockdep_assert_wiphy(wdev->wiphy);
1553
1554 WARN_ON(wdev->valid_links && !(wdev->valid_links & BIT(link_id)));
1555 WARN_ON(!wdev->valid_links && link_id > 0);
7b0a0e3c
JB
1556
1557 switch (wdev->iftype) {
1558 case NL80211_IFTYPE_MESH_POINT:
1559 return &wdev->u.mesh.chandef;
1560 case NL80211_IFTYPE_ADHOC:
1561 return &wdev->u.ibss.chandef;
1562 case NL80211_IFTYPE_OCB:
1563 return &wdev->u.ocb.chandef;
1564 case NL80211_IFTYPE_AP:
1565 case NL80211_IFTYPE_P2P_GO:
1566 return &wdev->links[link_id].ap.chandef;
1567 default:
1568 return NULL;
1569 }
1570}
1571EXPORT_SYMBOL(wdev_chandef);
This page took 1.029915 seconds and 4 git commands to generate.