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