wifi: mac80211: use cfg80211_chandef_primary_freq()
[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 392
8f251a0a
JB
393int cfg80211_chandef_primary_freq(const struct cfg80211_chan_def *c,
394 enum nl80211_chan_width primary_chan_width)
3d9d1d66 395{
8f251a0a
JB
396 int pri_width = nl80211_chan_width_to_mhz(primary_chan_width);
397 int width = cfg80211_chandef_get_width(c);
398 u32 control = c->chan->center_freq;
399 u32 center = c->center_freq1;
3d9d1d66 400
8f251a0a
JB
401 if (WARN_ON_ONCE(pri_width < 0 || width < 0))
402 return -1;
403
404 /* not intended to be called this way, can't determine */
405 if (WARN_ON_ONCE(pri_width > width))
406 return -1;
407
408 while (width > pri_width) {
409 if (control > center)
410 center += width / 4;
411 else
412 center -= width / 4;
413 width /= 2;
3d9d1d66 414 }
8f251a0a
JB
415
416 return center;
3d9d1d66 417}
8f251a0a 418EXPORT_SYMBOL(cfg80211_chandef_primary_freq);
3d9d1d66 419
8f251a0a
JB
420static const struct cfg80211_chan_def *
421check_chandef_primary_compat(const struct cfg80211_chan_def *c1,
422 const struct cfg80211_chan_def *c2,
423 enum nl80211_chan_width primary_chan_width)
3d9d1d66 424{
8f251a0a
JB
425 /* check primary is compatible -> error if not */
426 if (cfg80211_chandef_primary_freq(c1, primary_chan_width) !=
427 cfg80211_chandef_primary_freq(c2, primary_chan_width))
428 return ERR_PTR(-EINVAL);
429
430 /* assumes c1 is smaller width, if that was just checked -> done */
431 if (c1->width == primary_chan_width)
432 return c2;
433
434 /* otherwise continue checking the next width */
435 return NULL;
436}
437
438static const struct cfg80211_chan_def *
439_cfg80211_chandef_compatible(const struct cfg80211_chan_def *c1,
440 const struct cfg80211_chan_def *c2)
441{
442 const struct cfg80211_chan_def *ret;
3d9d1d66
JB
443
444 /* If they are identical, return */
445 if (cfg80211_chandef_identical(c1, c2))
8f251a0a 446 return c2;
3d9d1d66
JB
447
448 /* otherwise, must have same control channel */
449 if (c1->chan != c2->chan)
450 return NULL;
451
452 /*
453 * If they have the same width, but aren't identical,
454 * then they can't be compatible.
455 */
456 if (c1->width == c2->width)
457 return NULL;
458
2f301ab2 459 /*
b9d908dc 460 * can't be compatible if one of them is 5/10 MHz or S1G
2f301ab2
SW
461 * but they don't have the same width.
462 */
b9d908dc
JB
463#define NARROW_OR_S1G(width) ((width) == NL80211_CHAN_WIDTH_5 || \
464 (width) == NL80211_CHAN_WIDTH_10 || \
465 (width) == NL80211_CHAN_WIDTH_1 || \
466 (width) == NL80211_CHAN_WIDTH_2 || \
467 (width) == NL80211_CHAN_WIDTH_4 || \
468 (width) == NL80211_CHAN_WIDTH_8 || \
469 (width) == NL80211_CHAN_WIDTH_16)
470
471 if (NARROW_OR_S1G(c1->width) || NARROW_OR_S1G(c2->width))
2f301ab2
SW
472 return NULL;
473
8f251a0a
JB
474 /*
475 * Make sure that c1 is always the narrower one, so that later
476 * we either return NULL or c2 and don't have to check both
477 * directions.
478 */
479 if (c1->width > c2->width)
480 swap(c1, c2);
481
482 /*
483 * No further checks needed if the "narrower" one is only 20 MHz.
484 * Here "narrower" includes being a 20 MHz non-HT channel vs. a
485 * 20 MHz HT (or later) one.
486 */
487 if (c1->width <= NL80211_CHAN_WIDTH_20)
3d9d1d66
JB
488 return c2;
489
8f251a0a
JB
490 ret = check_chandef_primary_compat(c1, c2, NL80211_CHAN_WIDTH_40);
491 if (ret)
492 return ret;
3d9d1d66 493
8f251a0a
JB
494 ret = check_chandef_primary_compat(c1, c2, NL80211_CHAN_WIDTH_80);
495 if (ret)
496 return ret;
3d9d1d66 497
8f251a0a
JB
498 /*
499 * If c1 is 80+80, then c2 is 160 or higher, but that cannot
500 * match. If c2 was also 80+80 it was already either accepted
501 * or rejected above (identical or not, respectively.)
502 */
503 if (c1->width == NL80211_CHAN_WIDTH_80P80)
3d9d1d66
JB
504 return NULL;
505
8f251a0a
JB
506 ret = check_chandef_primary_compat(c1, c2, NL80211_CHAN_WIDTH_160);
507 if (ret)
508 return ret;
3743bec6 509
8f251a0a
JB
510 /*
511 * Getting here would mean they're both wider than 160, have the
512 * same primary 160, but are not identical - this cannot happen
513 * since they must be 320 (no wider chandefs exist, at least yet.)
514 */
515 WARN_ON_ONCE(1);
3743bec6 516
8f251a0a
JB
517 return NULL;
518}
3743bec6 519
8f251a0a
JB
520const struct cfg80211_chan_def *
521cfg80211_chandef_compatible(const struct cfg80211_chan_def *c1,
522 const struct cfg80211_chan_def *c2)
523{
524 const struct cfg80211_chan_def *ret;
3743bec6 525
8f251a0a
JB
526 ret = _cfg80211_chandef_compatible(c1, c2);
527 if (IS_ERR(ret))
3d9d1d66 528 return NULL;
8f251a0a 529 return ret;
3d9d1d66
JB
530}
531EXPORT_SYMBOL(cfg80211_chandef_compatible);
532
04f39047
SW
533static void cfg80211_set_chans_dfs_state(struct wiphy *wiphy, u32 center_freq,
534 u32 bandwidth,
535 enum nl80211_dfs_state dfs_state)
536{
537 struct ieee80211_channel *c;
538 u32 freq;
539
540 for (freq = center_freq - bandwidth/2 + 10;
541 freq <= center_freq + bandwidth/2 - 10;
542 freq += 20) {
543 c = ieee80211_get_channel(wiphy, freq);
544 if (!c || !(c->flags & IEEE80211_CHAN_RADAR))
545 continue;
546
547 c->dfs_state = dfs_state;
548 c->dfs_state_entered = jiffies;
549 }
550}
551
552void cfg80211_set_dfs_state(struct wiphy *wiphy,
553 const struct cfg80211_chan_def *chandef,
554 enum nl80211_dfs_state dfs_state)
555{
556 int width;
557
558 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
559 return;
560
561 width = cfg80211_chandef_get_width(chandef);
562 if (width < 0)
563 return;
564
565 cfg80211_set_chans_dfs_state(wiphy, chandef->center_freq1,
566 width, dfs_state);
567
568 if (!chandef->center_freq2)
569 return;
570 cfg80211_set_chans_dfs_state(wiphy, chandef->center_freq2,
571 width, dfs_state);
572}
573
40d1ba63
JD
574static u32 cfg80211_get_start_freq(u32 center_freq,
575 u32 bandwidth)
576{
577 u32 start_freq;
578
934f4c7d
TP
579 bandwidth = MHZ_TO_KHZ(bandwidth);
580 if (bandwidth <= MHZ_TO_KHZ(20))
40d1ba63
JD
581 start_freq = center_freq;
582 else
934f4c7d 583 start_freq = center_freq - bandwidth / 2 + MHZ_TO_KHZ(10);
40d1ba63
JD
584
585 return start_freq;
586}
587
588static u32 cfg80211_get_end_freq(u32 center_freq,
589 u32 bandwidth)
590{
591 u32 end_freq;
592
934f4c7d
TP
593 bandwidth = MHZ_TO_KHZ(bandwidth);
594 if (bandwidth <= MHZ_TO_KHZ(20))
40d1ba63
JD
595 end_freq = center_freq;
596 else
934f4c7d 597 end_freq = center_freq + bandwidth / 2 - MHZ_TO_KHZ(10);
40d1ba63
JD
598
599 return end_freq;
600}
601
41a313d8
AO
602static bool
603cfg80211_dfs_permissive_check_wdev(struct cfg80211_registered_device *rdev,
604 enum nl80211_iftype iftype,
605 struct wireless_dev *wdev,
606 struct ieee80211_channel *chan)
607{
608 unsigned int link_id;
609
610 for_each_valid_link(wdev, link_id) {
611 struct ieee80211_channel *other_chan = NULL;
612 struct cfg80211_chan_def chandef = {};
613 int ret;
614
615 /* In order to avoid daisy chaining only allow BSS STA */
616 if (wdev->iftype != NL80211_IFTYPE_STATION ||
617 !wdev->links[link_id].client.current_bss)
618 continue;
619
620 other_chan =
621 wdev->links[link_id].client.current_bss->pub.channel;
622
623 if (!other_chan)
624 continue;
625
626 if (chan == other_chan)
627 return true;
628
629 /* continue if we can't get the channel */
630 ret = rdev_get_channel(rdev, wdev, link_id, &chandef);
631 if (ret)
632 continue;
633
634 if (cfg80211_is_sub_chan(&chandef, chan, false))
635 return true;
636 }
637
638 return false;
639}
640
641/*
642 * Check if P2P GO is allowed to operate on a DFS channel
643 */
644static bool cfg80211_dfs_permissive_chan(struct wiphy *wiphy,
645 enum nl80211_iftype iftype,
646 struct ieee80211_channel *chan)
647{
648 struct wireless_dev *wdev;
649 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
650
651 lockdep_assert_held(&rdev->wiphy.mtx);
652
653 if (!wiphy_ext_feature_isset(&rdev->wiphy,
654 NL80211_EXT_FEATURE_DFS_CONCURRENT) ||
655 !(chan->flags & IEEE80211_CHAN_DFS_CONCURRENT))
656 return false;
657
658 /* only valid for P2P GO */
659 if (iftype != NL80211_IFTYPE_P2P_GO)
660 return false;
661
662 /*
663 * Allow only if there's a concurrent BSS
664 */
665 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
666 bool ret = cfg80211_dfs_permissive_check_wdev(rdev, iftype,
667 wdev, chan);
668 if (ret)
669 return ret;
670 }
671
672 return false;
673}
674
04f39047
SW
675static int cfg80211_get_chans_dfs_required(struct wiphy *wiphy,
676 u32 center_freq,
41a313d8
AO
677 u32 bandwidth,
678 enum nl80211_iftype iftype)
04f39047
SW
679{
680 struct ieee80211_channel *c;
2f301ab2
SW
681 u32 freq, start_freq, end_freq;
682
40d1ba63
JD
683 start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
684 end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
04f39047 685
934f4c7d
TP
686 for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
687 c = ieee80211_get_channel_khz(wiphy, freq);
04f39047
SW
688 if (!c)
689 return -EINVAL;
690
41a313d8
AO
691 if (c->flags & IEEE80211_CHAN_RADAR &&
692 !cfg80211_dfs_permissive_chan(wiphy, iftype, c))
04f39047
SW
693 return 1;
694 }
41a313d8 695
04f39047
SW
696 return 0;
697}
698
699
700int cfg80211_chandef_dfs_required(struct wiphy *wiphy,
2beb6dab
LC
701 const struct cfg80211_chan_def *chandef,
702 enum nl80211_iftype iftype)
04f39047
SW
703{
704 int width;
2beb6dab 705 int ret;
04f39047
SW
706
707 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
708 return -EINVAL;
709
2beb6dab
LC
710 switch (iftype) {
711 case NL80211_IFTYPE_ADHOC:
712 case NL80211_IFTYPE_AP:
713 case NL80211_IFTYPE_P2P_GO:
714 case NL80211_IFTYPE_MESH_POINT:
715 width = cfg80211_chandef_get_width(chandef);
716 if (width < 0)
717 return -EINVAL;
04f39047 718
2beb6dab 719 ret = cfg80211_get_chans_dfs_required(wiphy,
934f4c7d 720 ieee80211_chandef_to_khz(chandef),
41a313d8 721 width, iftype);
2beb6dab
LC
722 if (ret < 0)
723 return ret;
724 else if (ret > 0)
725 return BIT(chandef->width);
04f39047 726
2beb6dab
LC
727 if (!chandef->center_freq2)
728 return 0;
729
730 ret = cfg80211_get_chans_dfs_required(wiphy,
934f4c7d 731 MHZ_TO_KHZ(chandef->center_freq2),
41a313d8 732 width, iftype);
2beb6dab
LC
733 if (ret < 0)
734 return ret;
735 else if (ret > 0)
736 return BIT(chandef->width);
04f39047 737
2beb6dab
LC
738 break;
739 case NL80211_IFTYPE_STATION:
6e0bd6c3 740 case NL80211_IFTYPE_OCB:
2beb6dab
LC
741 case NL80211_IFTYPE_P2P_CLIENT:
742 case NL80211_IFTYPE_MONITOR:
743 case NL80211_IFTYPE_AP_VLAN:
2beb6dab 744 case NL80211_IFTYPE_P2P_DEVICE:
cb3b7d87 745 case NL80211_IFTYPE_NAN:
2beb6dab 746 break;
e7e0517c 747 case NL80211_IFTYPE_WDS:
00ec75fc 748 case NL80211_IFTYPE_UNSPECIFIED:
2beb6dab
LC
749 case NUM_NL80211_IFTYPES:
750 WARN_ON(1);
751 }
752
753 return 0;
04f39047 754}
774f0734 755EXPORT_SYMBOL(cfg80211_chandef_dfs_required);
04f39047 756
fe7c3a1f
JD
757static int cfg80211_get_chans_dfs_usable(struct wiphy *wiphy,
758 u32 center_freq,
759 u32 bandwidth)
760{
761 struct ieee80211_channel *c;
762 u32 freq, start_freq, end_freq;
763 int count = 0;
764
765 start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
766 end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
767
768 /*
769 * Check entire range of channels for the bandwidth.
770 * Check all channels are DFS channels (DFS_USABLE or
771 * DFS_AVAILABLE). Return number of usable channels
772 * (require CAC). Allow DFS and non-DFS channel mix.
773 */
934f4c7d
TP
774 for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
775 c = ieee80211_get_channel_khz(wiphy, freq);
fe7c3a1f
JD
776 if (!c)
777 return -EINVAL;
778
779 if (c->flags & IEEE80211_CHAN_DISABLED)
780 return -EINVAL;
781
782 if (c->flags & IEEE80211_CHAN_RADAR) {
783 if (c->dfs_state == NL80211_DFS_UNAVAILABLE)
784 return -EINVAL;
785
786 if (c->dfs_state == NL80211_DFS_USABLE)
787 count++;
788 }
789 }
790
791 return count;
792}
793
794bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy,
795 const struct cfg80211_chan_def *chandef)
796{
797 int width;
798 int r1, r2 = 0;
799
800 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
801 return false;
802
803 width = cfg80211_chandef_get_width(chandef);
804 if (width < 0)
805 return false;
806
934f4c7d
TP
807 r1 = cfg80211_get_chans_dfs_usable(wiphy,
808 MHZ_TO_KHZ(chandef->center_freq1),
809 width);
fe7c3a1f
JD
810
811 if (r1 < 0)
812 return false;
813
814 switch (chandef->width) {
815 case NL80211_CHAN_WIDTH_80P80:
816 WARN_ON(!chandef->center_freq2);
817 r2 = cfg80211_get_chans_dfs_usable(wiphy,
934f4c7d
TP
818 MHZ_TO_KHZ(chandef->center_freq2),
819 width);
fe7c3a1f
JD
820 if (r2 < 0)
821 return false;
822 break;
823 default:
824 WARN_ON(chandef->center_freq2);
825 break;
826 }
827
828 return (r1 + r2 > 0);
829}
30ca8b0c 830EXPORT_SYMBOL(cfg80211_chandef_dfs_usable);
fe7c3a1f 831
b35a51c7
VT
832/*
833 * Checks if center frequency of chan falls with in the bandwidth
834 * range of chandef.
835 */
836bool cfg80211_is_sub_chan(struct cfg80211_chan_def *chandef,
7b0a0e3c
JB
837 struct ieee80211_channel *chan,
838 bool primary_only)
b35a51c7
VT
839{
840 int width;
a67a4893 841 u32 freq;
b35a51c7 842
7b0a0e3c
JB
843 if (!chandef->chan)
844 return false;
845
b35a51c7
VT
846 if (chandef->chan->center_freq == chan->center_freq)
847 return true;
848
7b0a0e3c
JB
849 if (primary_only)
850 return false;
851
b35a51c7
VT
852 width = cfg80211_chandef_get_width(chandef);
853 if (width <= 20)
854 return false;
855
b35a51c7
VT
856 for (freq = chandef->center_freq1 - width / 2 + 10;
857 freq <= chandef->center_freq1 + width / 2 - 10; freq += 20) {
858 if (chan->center_freq == freq)
859 return true;
860 }
861
862 if (!chandef->center_freq2)
863 return false;
864
865 for (freq = chandef->center_freq2 - width / 2 + 10;
866 freq <= chandef->center_freq2 + width / 2 - 10; freq += 20) {
867 if (chan->center_freq == freq)
868 return true;
869 }
870
871 return false;
872}
873
874bool cfg80211_beaconing_iface_active(struct wireless_dev *wdev)
875{
7b0a0e3c 876 unsigned int link;
b35a51c7 877
076fc877 878 lockdep_assert_wiphy(wdev->wiphy);
b35a51c7 879
b35a51c7
VT
880 switch (wdev->iftype) {
881 case NL80211_IFTYPE_AP:
882 case NL80211_IFTYPE_P2P_GO:
7b0a0e3c
JB
883 for_each_valid_link(wdev, link) {
884 if (wdev->links[link].ap.beacon_interval)
885 return true;
886 }
b35a51c7
VT
887 break;
888 case NL80211_IFTYPE_ADHOC:
7b0a0e3c
JB
889 if (wdev->u.ibss.ssid_len)
890 return true;
b35a51c7
VT
891 break;
892 case NL80211_IFTYPE_MESH_POINT:
7b0a0e3c
JB
893 if (wdev->u.mesh.id_len)
894 return true;
b35a51c7
VT
895 break;
896 case NL80211_IFTYPE_STATION:
897 case NL80211_IFTYPE_OCB:
898 case NL80211_IFTYPE_P2P_CLIENT:
899 case NL80211_IFTYPE_MONITOR:
900 case NL80211_IFTYPE_AP_VLAN:
b35a51c7
VT
901 case NL80211_IFTYPE_P2P_DEVICE:
902 /* Can NAN type be considered as beaconing interface? */
903 case NL80211_IFTYPE_NAN:
904 break;
905 case NL80211_IFTYPE_UNSPECIFIED:
e7e0517c 906 case NL80211_IFTYPE_WDS:
b35a51c7
VT
907 case NUM_NL80211_IFTYPES:
908 WARN_ON(1);
909 }
910
7b0a0e3c
JB
911 return false;
912}
913
914bool cfg80211_wdev_on_sub_chan(struct wireless_dev *wdev,
915 struct ieee80211_channel *chan,
916 bool primary_only)
917{
918 unsigned int link;
919
920 switch (wdev->iftype) {
921 case NL80211_IFTYPE_AP:
922 case NL80211_IFTYPE_P2P_GO:
923 for_each_valid_link(wdev, link) {
924 if (cfg80211_is_sub_chan(&wdev->links[link].ap.chandef,
925 chan, primary_only))
926 return true;
927 }
928 break;
929 case NL80211_IFTYPE_ADHOC:
930 return cfg80211_is_sub_chan(&wdev->u.ibss.chandef, chan,
931 primary_only);
932 case NL80211_IFTYPE_MESH_POINT:
933 return cfg80211_is_sub_chan(&wdev->u.mesh.chandef, chan,
934 primary_only);
935 default:
936 break;
937 }
938
939 return false;
b35a51c7
VT
940}
941
89766727
VT
942static bool cfg80211_is_wiphy_oper_chan(struct wiphy *wiphy,
943 struct ieee80211_channel *chan)
b35a51c7
VT
944{
945 struct wireless_dev *wdev;
946
076fc877
JB
947 lockdep_assert_wiphy(wiphy);
948
b35a51c7 949 list_for_each_entry(wdev, &wiphy->wdev_list, list) {
076fc877 950 if (!cfg80211_beaconing_iface_active(wdev))
b35a51c7 951 continue;
b35a51c7 952
076fc877 953 if (cfg80211_wdev_on_sub_chan(wdev, chan, false))
b35a51c7 954 return true;
b35a51c7
VT
955 }
956
957 return false;
958}
fe7c3a1f 959
84158164
LB
960static bool
961cfg80211_offchan_chain_is_active(struct cfg80211_registered_device *rdev,
962 struct ieee80211_channel *channel)
963{
a95bfb87 964 if (!rdev->background_radar_wdev)
84158164
LB
965 return false;
966
a95bfb87 967 if (!cfg80211_chandef_valid(&rdev->background_radar_chandef))
84158164
LB
968 return false;
969
7b0a0e3c
JB
970 return cfg80211_is_sub_chan(&rdev->background_radar_chandef, channel,
971 false);
84158164
LB
972}
973
89766727
VT
974bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy,
975 struct ieee80211_channel *chan)
976{
977 struct cfg80211_registered_device *rdev;
978
979 ASSERT_RTNL();
980
981 if (!(chan->flags & IEEE80211_CHAN_RADAR))
982 return false;
983
7483a214 984 for_each_rdev(rdev) {
fa8809a5
JB
985 bool found;
986
89766727
VT
987 if (!reg_dfs_domain_same(wiphy, &rdev->wiphy))
988 continue;
989
fa8809a5
JB
990 wiphy_lock(&rdev->wiphy);
991 found = cfg80211_is_wiphy_oper_chan(&rdev->wiphy, chan) ||
992 cfg80211_offchan_chain_is_active(rdev, chan);
993 wiphy_unlock(&rdev->wiphy);
84158164 994
fa8809a5 995 if (found)
84158164 996 return true;
89766727
VT
997 }
998
999 return false;
1000}
1001
6bc54fbc
JD
1002static bool cfg80211_get_chans_dfs_available(struct wiphy *wiphy,
1003 u32 center_freq,
1004 u32 bandwidth)
3d9d1d66
JB
1005{
1006 struct ieee80211_channel *c;
2f301ab2 1007 u32 freq, start_freq, end_freq;
2c390e44
DL
1008 bool dfs_offload;
1009
1010 dfs_offload = wiphy_ext_feature_isset(wiphy,
1011 NL80211_EXT_FEATURE_DFS_OFFLOAD);
2f301ab2 1012
40d1ba63
JD
1013 start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
1014 end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
3d9d1d66 1015
6bc54fbc
JD
1016 /*
1017 * Check entire range of channels for the bandwidth.
1018 * If any channel in between is disabled or has not
1019 * had gone through CAC return false
1020 */
934f4c7d
TP
1021 for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
1022 c = ieee80211_get_channel_khz(wiphy, freq);
04f39047
SW
1023 if (!c)
1024 return false;
1025
6bc54fbc
JD
1026 if (c->flags & IEEE80211_CHAN_DISABLED)
1027 return false;
1028
2c390e44
DL
1029 if ((c->flags & IEEE80211_CHAN_RADAR) &&
1030 (c->dfs_state != NL80211_DFS_AVAILABLE) &&
1031 !(c->dfs_state == NL80211_DFS_USABLE && dfs_offload))
04f39047 1032 return false;
6bc54fbc
JD
1033 }
1034
1035 return true;
1036}
1037
1038static bool cfg80211_chandef_dfs_available(struct wiphy *wiphy,
1039 const struct cfg80211_chan_def *chandef)
1040{
1041 int width;
1042 int r;
1043
1044 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
1045 return false;
1046
1047 width = cfg80211_chandef_get_width(chandef);
1048 if (width < 0)
1049 return false;
1050
934f4c7d
TP
1051 r = cfg80211_get_chans_dfs_available(wiphy,
1052 MHZ_TO_KHZ(chandef->center_freq1),
6bc54fbc
JD
1053 width);
1054
1055 /* If any of channels unavailable for cf1 just return */
1056 if (!r)
1057 return r;
1058
1059 switch (chandef->width) {
1060 case NL80211_CHAN_WIDTH_80P80:
1061 WARN_ON(!chandef->center_freq2);
1062 r = cfg80211_get_chans_dfs_available(wiphy,
934f4c7d
TP
1063 MHZ_TO_KHZ(chandef->center_freq2),
1064 width);
680682d4 1065 break;
6bc54fbc
JD
1066 default:
1067 WARN_ON(chandef->center_freq2);
1068 break;
1069 }
1070
1071 return r;
1072}
1073
31559f35
JD
1074static unsigned int cfg80211_get_chans_dfs_cac_time(struct wiphy *wiphy,
1075 u32 center_freq,
1076 u32 bandwidth)
1077{
1078 struct ieee80211_channel *c;
1079 u32 start_freq, end_freq, freq;
1080 unsigned int dfs_cac_ms = 0;
1081
1082 start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
1083 end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
1084
934f4c7d
TP
1085 for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
1086 c = ieee80211_get_channel_khz(wiphy, freq);
31559f35
JD
1087 if (!c)
1088 return 0;
1089
1090 if (c->flags & IEEE80211_CHAN_DISABLED)
1091 return 0;
1092
1093 if (!(c->flags & IEEE80211_CHAN_RADAR))
1094 continue;
1095
1096 if (c->dfs_cac_ms > dfs_cac_ms)
1097 dfs_cac_ms = c->dfs_cac_ms;
1098 }
1099
1100 return dfs_cac_ms;
1101}
1102
1103unsigned int
1104cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
1105 const struct cfg80211_chan_def *chandef)
1106{
1107 int width;
1108 unsigned int t1 = 0, t2 = 0;
1109
1110 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
1111 return 0;
1112
1113 width = cfg80211_chandef_get_width(chandef);
1114 if (width < 0)
1115 return 0;
1116
1117 t1 = cfg80211_get_chans_dfs_cac_time(wiphy,
934f4c7d 1118 MHZ_TO_KHZ(chandef->center_freq1),
31559f35
JD
1119 width);
1120
1121 if (!chandef->center_freq2)
1122 return t1;
1123
1124 t2 = cfg80211_get_chans_dfs_cac_time(wiphy,
934f4c7d 1125 MHZ_TO_KHZ(chandef->center_freq2),
31559f35
JD
1126 width);
1127
1128 return max(t1, t2);
1129}
30ca8b0c 1130EXPORT_SYMBOL(cfg80211_chandef_dfs_cac_time);
6bc54fbc
JD
1131
1132static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
1133 u32 center_freq, u32 bandwidth,
1134 u32 prohibited_flags)
1135{
1136 struct ieee80211_channel *c;
1137 u32 freq, start_freq, end_freq;
04f39047 1138
6bc54fbc
JD
1139 start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
1140 end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
1141
934f4c7d
TP
1142 for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
1143 c = ieee80211_get_channel_khz(wiphy, freq);
6bc54fbc 1144 if (!c || c->flags & prohibited_flags)
3d9d1d66 1145 return false;
9236d838
LR
1146 }
1147
3d9d1d66
JB
1148 return true;
1149}
1150
2a38075c
AAL
1151/* check if the operating channels are valid and supported */
1152static bool cfg80211_edmg_usable(struct wiphy *wiphy, u8 edmg_channels,
1153 enum ieee80211_edmg_bw_config edmg_bw_config,
1154 int primary_channel,
1155 struct ieee80211_edmg *edmg_cap)
1156{
1157 struct ieee80211_channel *chan;
1158 int i, freq;
1159 int channels_counter = 0;
1160
1161 if (!edmg_channels && !edmg_bw_config)
1162 return true;
1163
1164 if ((!edmg_channels && edmg_bw_config) ||
1165 (edmg_channels && !edmg_bw_config))
1166 return false;
1167
1168 if (!(edmg_channels & BIT(primary_channel - 1)))
1169 return false;
1170
1171 /* 60GHz channels 1..6 */
1172 for (i = 0; i < 6; i++) {
1173 if (!(edmg_channels & BIT(i)))
1174 continue;
1175
1176 if (!(edmg_cap->channels & BIT(i)))
1177 return false;
1178
1179 channels_counter++;
1180
1181 freq = ieee80211_channel_to_frequency(i + 1,
1182 NL80211_BAND_60GHZ);
1183 chan = ieee80211_get_channel(wiphy, freq);
1184 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
1185 return false;
1186 }
1187
1188 /* IEEE802.11 allows max 4 channels */
1189 if (channels_counter > 4)
1190 return false;
1191
1192 /* check bw_config is a subset of what driver supports
1193 * (see IEEE P802.11ay/D4.0 section 9.4.2.251, Table 13)
1194 */
1195 if ((edmg_bw_config % 4) > (edmg_cap->bw_config % 4))
1196 return false;
1197
1198 if (edmg_bw_config > edmg_cap->bw_config)
1199 return false;
1200
1201 return true;
1202}
1203
9f5e8f6e
JB
1204bool cfg80211_chandef_usable(struct wiphy *wiphy,
1205 const struct cfg80211_chan_def *chandef,
1206 u32 prohibited_flags)
3d9d1d66 1207{
9f5e8f6e
JB
1208 struct ieee80211_sta_ht_cap *ht_cap;
1209 struct ieee80211_sta_vht_cap *vht_cap;
2a38075c 1210 struct ieee80211_edmg *edmg_cap;
08f6f147 1211 u32 width, control_freq, cap;
3743bec6
JD
1212 bool ext_nss_cap, support_80_80 = false, support_320 = false;
1213 const struct ieee80211_sband_iftype_data *iftd;
1214 struct ieee80211_supported_band *sband;
1215 int i;
3d9d1d66 1216
9f5e8f6e
JB
1217 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
1218 return false;
3d9d1d66 1219
9f5e8f6e
JB
1220 ht_cap = &wiphy->bands[chandef->chan->band]->ht_cap;
1221 vht_cap = &wiphy->bands[chandef->chan->band]->vht_cap;
2a38075c 1222 edmg_cap = &wiphy->bands[chandef->chan->band]->edmg_cap;
e6ed929b
WG
1223 ext_nss_cap = __le16_to_cpu(vht_cap->vht_mcs.tx_highest) &
1224 IEEE80211_VHT_EXT_NSS_BW_CAPABLE;
2a38075c
AAL
1225
1226 if (edmg_cap->channels &&
1227 !cfg80211_edmg_usable(wiphy,
1228 chandef->edmg.channels,
1229 chandef->edmg.bw_config,
1230 chandef->chan->hw_value,
1231 edmg_cap))
1232 return false;
3d9d1d66 1233
9f5e8f6e 1234 control_freq = chandef->chan->center_freq;
9236d838 1235
3d9d1d66 1236 switch (chandef->width) {
df78a0c0
TP
1237 case NL80211_CHAN_WIDTH_1:
1238 width = 1;
1239 break;
1240 case NL80211_CHAN_WIDTH_2:
1241 width = 2;
1242 break;
1243 case NL80211_CHAN_WIDTH_4:
1244 width = 4;
1245 break;
1246 case NL80211_CHAN_WIDTH_8:
1247 width = 8;
1248 break;
1249 case NL80211_CHAN_WIDTH_16:
1250 width = 16;
1251 break;
2f301ab2
SW
1252 case NL80211_CHAN_WIDTH_5:
1253 width = 5;
1254 break;
1255 case NL80211_CHAN_WIDTH_10:
ea077c1c 1256 prohibited_flags |= IEEE80211_CHAN_NO_10MHZ;
2f301ab2
SW
1257 width = 10;
1258 break;
3d9d1d66 1259 case NL80211_CHAN_WIDTH_20:
ba8f6a03
JB
1260 if (!ht_cap->ht_supported &&
1261 chandef->chan->band != NL80211_BAND_6GHZ)
9f5e8f6e 1262 return false;
df561f66 1263 fallthrough;
9f5e8f6e 1264 case NL80211_CHAN_WIDTH_20_NOHT:
ea077c1c 1265 prohibited_flags |= IEEE80211_CHAN_NO_20MHZ;
3d9d1d66
JB
1266 width = 20;
1267 break;
1268 case NL80211_CHAN_WIDTH_40:
1269 width = 40;
ba8f6a03
JB
1270 if (chandef->chan->band == NL80211_BAND_6GHZ)
1271 break;
9f5e8f6e
JB
1272 if (!ht_cap->ht_supported)
1273 return false;
1274 if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ||
1275 ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT)
1276 return false;
1277 if (chandef->center_freq1 < control_freq &&
1278 chandef->chan->flags & IEEE80211_CHAN_NO_HT40MINUS)
1279 return false;
1280 if (chandef->center_freq1 > control_freq &&
1281 chandef->chan->flags & IEEE80211_CHAN_NO_HT40PLUS)
1282 return false;
3d9d1d66 1283 break;
3d9d1d66 1284 case NL80211_CHAN_WIDTH_80P80:
35799944
SB
1285 cap = vht_cap->cap;
1286 support_80_80 =
1287 (cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ) ||
1288 (cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ &&
1289 cap & IEEE80211_VHT_CAP_EXT_NSS_BW_MASK) ||
e6ed929b
WG
1290 (ext_nss_cap &&
1291 u32_get_bits(cap, IEEE80211_VHT_CAP_EXT_NSS_BW_MASK) > 1);
35799944 1292 if (chandef->chan->band != NL80211_BAND_6GHZ && !support_80_80)
9f5e8f6e 1293 return false;
df561f66 1294 fallthrough;
9f5e8f6e 1295 case NL80211_CHAN_WIDTH_80:
c7a6ee27 1296 prohibited_flags |= IEEE80211_CHAN_NO_80MHZ;
3d9d1d66 1297 width = 80;
ba8f6a03
JB
1298 if (chandef->chan->band == NL80211_BAND_6GHZ)
1299 break;
1300 if (!vht_cap->vht_supported)
1301 return false;
3d9d1d66
JB
1302 break;
1303 case NL80211_CHAN_WIDTH_160:
ba8f6a03
JB
1304 prohibited_flags |= IEEE80211_CHAN_NO_160MHZ;
1305 width = 160;
1306 if (chandef->chan->band == NL80211_BAND_6GHZ)
1307 break;
9f5e8f6e
JB
1308 if (!vht_cap->vht_supported)
1309 return false;
08f6f147
JM
1310 cap = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
1311 if (cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ &&
35799944 1312 cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ &&
e6ed929b
WG
1313 !(ext_nss_cap &&
1314 (vht_cap->cap & IEEE80211_VHT_CAP_EXT_NSS_BW_MASK)))
9f5e8f6e 1315 return false;
3d9d1d66 1316 break;
3743bec6
JD
1317 case NL80211_CHAN_WIDTH_320:
1318 prohibited_flags |= IEEE80211_CHAN_NO_320MHZ;
1319 width = 320;
1320
1321 if (chandef->chan->band != NL80211_BAND_6GHZ)
1322 return false;
1323
1324 sband = wiphy->bands[NL80211_BAND_6GHZ];
1325 if (!sband)
1326 return false;
1327
e8c18412 1328 for_each_sband_iftype_data(sband, i, iftd) {
3743bec6
JD
1329 if (!iftd->eht_cap.has_eht)
1330 continue;
1331
1332 if (iftd->eht_cap.eht_cap_elem.phy_cap_info[0] &
1333 IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ) {
1334 support_320 = true;
1335 break;
1336 }
1337 }
1338
1339 if (!support_320)
1340 return false;
1341 break;
3d9d1d66
JB
1342 default:
1343 WARN_ON_ONCE(1);
9236d838 1344 return false;
4ee3e063 1345 }
3d9d1d66 1346
c7a6ee27
JB
1347 /*
1348 * TODO: What if there are only certain 80/160/80+80 MHz channels
1349 * allowed by the driver, or only certain combinations?
1350 * For 40 MHz the driver can set the NO_HT40 flags, but for
1351 * 80/160 MHz and in particular 80+80 MHz this isn't really
1352 * feasible and we only have NO_80MHZ/NO_160MHZ so far but
1353 * no way to cover 80+80 MHz or more complex restrictions.
1354 * Note that such restrictions also need to be advertised to
1355 * userspace, for example for P2P channel selection.
1356 */
9f5e8f6e 1357
a6662dba
JB
1358 if (width > 20)
1359 prohibited_flags |= IEEE80211_CHAN_NO_OFDM;
1360
2f301ab2
SW
1361 /* 5 and 10 MHz are only defined for the OFDM PHY */
1362 if (width < 20)
1363 prohibited_flags |= IEEE80211_CHAN_NO_OFDM;
1364
1365
934f4c7d
TP
1366 if (!cfg80211_secondary_chans_ok(wiphy,
1367 ieee80211_chandef_to_khz(chandef),
9f5e8f6e
JB
1368 width, prohibited_flags))
1369 return false;
1370
1371 if (!chandef->center_freq2)
1372 return true;
934f4c7d
TP
1373 return cfg80211_secondary_chans_ok(wiphy,
1374 MHZ_TO_KHZ(chandef->center_freq2),
9f5e8f6e
JB
1375 width, prohibited_flags);
1376}
1377EXPORT_SYMBOL(cfg80211_chandef_usable);
1378
7b0a0e3c
JB
1379static bool cfg80211_ir_permissive_check_wdev(enum nl80211_iftype iftype,
1380 struct wireless_dev *wdev,
1381 struct ieee80211_channel *chan)
1382{
1383 struct ieee80211_channel *other_chan = NULL;
1384 unsigned int link_id;
1385 int r1, r2;
1386
1387 for_each_valid_link(wdev, link_id) {
1388 if (wdev->iftype == NL80211_IFTYPE_STATION &&
1389 wdev->links[link_id].client.current_bss)
1390 other_chan = wdev->links[link_id].client.current_bss->pub.channel;
1391
1392 /*
1393 * If a GO already operates on the same GO_CONCURRENT channel,
1394 * this one (maybe the same one) can beacon as well. We allow
1395 * the operation even if the station we relied on with
1396 * GO_CONCURRENT is disconnected now. But then we must make sure
1397 * we're not outdoor on an indoor-only channel.
1398 */
1399 if (iftype == NL80211_IFTYPE_P2P_GO &&
1400 wdev->iftype == NL80211_IFTYPE_P2P_GO &&
1401 wdev->links[link_id].ap.beacon_interval &&
1402 !(chan->flags & IEEE80211_CHAN_INDOOR_ONLY))
1403 other_chan = wdev->links[link_id].ap.chandef.chan;
1404
1405 if (!other_chan)
1406 continue;
1407
1408 if (chan == other_chan)
1409 return true;
1410
1411 if (chan->band != NL80211_BAND_5GHZ &&
1412 chan->band != NL80211_BAND_6GHZ)
1413 continue;
1414
1415 r1 = cfg80211_get_unii(chan->center_freq);
1416 r2 = cfg80211_get_unii(other_chan->center_freq);
1417
1418 if (r1 != -EINVAL && r1 == r2) {
1419 /*
1420 * At some locations channels 149-165 are considered a
1421 * bundle, but at other locations, e.g., Indonesia,
1422 * channels 149-161 are considered a bundle while
1423 * channel 165 is left out and considered to be in a
1424 * different bundle. Thus, in case that there is a
1425 * station interface connected to an AP on channel 165,
1426 * it is assumed that channels 149-161 are allowed for
1427 * GO operations. However, having a station interface
1428 * connected to an AP on channels 149-161, does not
1429 * allow GO operation on channel 165.
1430 */
1431 if (chan->center_freq == 5825 &&
1432 other_chan->center_freq != 5825)
1433 continue;
1434 return true;
1435 }
1436 }
1437
1438 return false;
1439}
1440
174e0cd2 1441/*
06f207fc
AN
1442 * Check if the channel can be used under permissive conditions mandated by
1443 * some regulatory bodies, i.e., the channel is marked with
1444 * IEEE80211_CHAN_IR_CONCURRENT and there is an additional station interface
174e0cd2
IP
1445 * associated to an AP on the same channel or on the same UNII band
1446 * (assuming that the AP is an authorized master).
06f207fc 1447 * In addition allow operation on a channel on which indoor operation is
c8866e55 1448 * allowed, iff we are currently operating in an indoor environment.
174e0cd2 1449 */
06f207fc
AN
1450static bool cfg80211_ir_permissive_chan(struct wiphy *wiphy,
1451 enum nl80211_iftype iftype,
174e0cd2
IP
1452 struct ieee80211_channel *chan)
1453{
be69c24a 1454 struct wireless_dev *wdev;
06f207fc 1455 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
174e0cd2 1456
a05829a7 1457 lockdep_assert_held(&rdev->wiphy.mtx);
174e0cd2 1458
97f2645f 1459 if (!IS_ENABLED(CONFIG_CFG80211_REG_RELAX_NO_IR) ||
c8866e55
IP
1460 !(wiphy->regulatory_flags & REGULATORY_ENABLE_RELAX_NO_IR))
1461 return false;
1462
06f207fc
AN
1463 /* only valid for GO and TDLS off-channel (station/p2p-CL) */
1464 if (iftype != NL80211_IFTYPE_P2P_GO &&
1465 iftype != NL80211_IFTYPE_STATION &&
1466 iftype != NL80211_IFTYPE_P2P_CLIENT)
1467 return false;
1468
c8866e55
IP
1469 if (regulatory_indoor_allowed() &&
1470 (chan->flags & IEEE80211_CHAN_INDOOR_ONLY))
1471 return true;
1472
06f207fc 1473 if (!(chan->flags & IEEE80211_CHAN_IR_CONCURRENT))
174e0cd2
IP
1474 return false;
1475
1476 /*
1477 * Generally, it is possible to rely on another device/driver to allow
06f207fc 1478 * the IR concurrent relaxation, however, since the device can further
174e0cd2
IP
1479 * enforce the relaxation (by doing a similar verifications as this),
1480 * and thus fail the GO instantiation, consider only the interfaces of
1481 * the current registered device.
1482 */
53873f13 1483 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
7b0a0e3c 1484 bool ret;
174e0cd2 1485
7b0a0e3c 1486 ret = cfg80211_ir_permissive_check_wdev(iftype, wdev, chan);
7b0a0e3c
JB
1487 if (ret)
1488 return ret;
174e0cd2
IP
1489 }
1490
1491 return false;
1492}
1493
923b352f
AN
1494static bool _cfg80211_reg_can_beacon(struct wiphy *wiphy,
1495 struct cfg80211_chan_def *chandef,
1496 enum nl80211_iftype iftype,
1497 bool check_no_ir)
9f5e8f6e
JB
1498{
1499 bool res;
41a313d8
AO
1500 u32 prohibited_flags = IEEE80211_CHAN_DISABLED;
1501 int dfs_required;
9f5e8f6e 1502
923b352f 1503 trace_cfg80211_reg_can_beacon(wiphy, chandef, iftype, check_no_ir);
174e0cd2 1504
923b352f 1505 if (check_no_ir)
174e0cd2 1506 prohibited_flags |= IEEE80211_CHAN_NO_IR;
3d9d1d66 1507
41a313d8
AO
1508 dfs_required = cfg80211_chandef_dfs_required(wiphy, chandef, iftype);
1509 if (dfs_required != 0)
1510 prohibited_flags |= IEEE80211_CHAN_RADAR;
1511
1512 if (dfs_required > 0 &&
6bc54fbc
JD
1513 cfg80211_chandef_dfs_available(wiphy, chandef)) {
1514 /* We can skip IEEE80211_CHAN_NO_IR if chandef dfs available */
1515 prohibited_flags = IEEE80211_CHAN_DISABLED;
1516 }
1517
1518 res = cfg80211_chandef_usable(wiphy, chandef, prohibited_flags);
3d9d1d66
JB
1519
1520 trace_cfg80211_return_bool(res);
1521 return res;
9236d838 1522}
923b352f
AN
1523
1524bool cfg80211_reg_can_beacon(struct wiphy *wiphy,
1525 struct cfg80211_chan_def *chandef,
1526 enum nl80211_iftype iftype)
1527{
1528 return _cfg80211_reg_can_beacon(wiphy, chandef, iftype, true);
1529}
683b6d3b 1530EXPORT_SYMBOL(cfg80211_reg_can_beacon);
9236d838 1531
923b352f
AN
1532bool cfg80211_reg_can_beacon_relax(struct wiphy *wiphy,
1533 struct cfg80211_chan_def *chandef,
1534 enum nl80211_iftype iftype)
1535{
a05829a7 1536 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
923b352f
AN
1537 bool check_no_ir;
1538
a05829a7 1539 lockdep_assert_held(&rdev->wiphy.mtx);
923b352f
AN
1540
1541 /*
1542 * Under certain conditions suggested by some regulatory bodies a
1543 * GO/STA can IR on channels marked with IEEE80211_NO_IR. Set this flag
1544 * only if such relaxations are not enabled and the conditions are not
1545 * met.
1546 */
1547 check_no_ir = !cfg80211_ir_permissive_chan(wiphy, iftype,
1548 chandef->chan);
1549
1550 return _cfg80211_reg_can_beacon(wiphy, chandef, iftype, check_no_ir);
1551}
1552EXPORT_SYMBOL(cfg80211_reg_can_beacon_relax);
1553
e8c9bd5b 1554int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
683b6d3b 1555 struct cfg80211_chan_def *chandef)
9588bbd5 1556{
e8c9bd5b 1557 if (!rdev->ops->set_monitor_channel)
9588bbd5 1558 return -EOPNOTSUPP;
4f03c1ed
MK
1559 if (!cfg80211_has_monitors_only(rdev))
1560 return -EBUSY;
9588bbd5 1561
683b6d3b 1562 return rdev_set_monitor_channel(rdev, chandef);
59bbb6f7 1563}
26ab9a0c 1564
be989891
JB
1565bool cfg80211_any_usable_channels(struct wiphy *wiphy,
1566 unsigned long sband_mask,
1567 u32 prohibited_flags)
1568{
1569 int idx;
1570
1571 prohibited_flags |= IEEE80211_CHAN_DISABLED;
1572
1573 for_each_set_bit(idx, &sband_mask, NUM_NL80211_BANDS) {
1574 struct ieee80211_supported_band *sband = wiphy->bands[idx];
1575 int chanidx;
1576
1577 if (!sband)
1578 continue;
1579
1580 for (chanidx = 0; chanidx < sband->n_channels; chanidx++) {
1581 struct ieee80211_channel *chan;
1582
1583 chan = &sband->channels[chanidx];
1584
1585 if (chan->flags & prohibited_flags)
1586 continue;
1587
1588 return true;
1589 }
1590 }
1591
1592 return false;
1593}
1594EXPORT_SYMBOL(cfg80211_any_usable_channels);
7b0a0e3c
JB
1595
1596struct cfg80211_chan_def *wdev_chandef(struct wireless_dev *wdev,
1597 unsigned int link_id)
1598{
076fc877
JB
1599 lockdep_assert_wiphy(wdev->wiphy);
1600
1601 WARN_ON(wdev->valid_links && !(wdev->valid_links & BIT(link_id)));
1602 WARN_ON(!wdev->valid_links && link_id > 0);
7b0a0e3c
JB
1603
1604 switch (wdev->iftype) {
1605 case NL80211_IFTYPE_MESH_POINT:
1606 return &wdev->u.mesh.chandef;
1607 case NL80211_IFTYPE_ADHOC:
1608 return &wdev->u.ibss.chandef;
1609 case NL80211_IFTYPE_OCB:
1610 return &wdev->u.ocb.chandef;
1611 case NL80211_IFTYPE_AP:
1612 case NL80211_IFTYPE_P2P_GO:
1613 return &wdev->links[link_id].ap.chandef;
1614 default:
1615 return NULL;
1616 }
1617}
1618EXPORT_SYMBOL(wdev_chandef);