treewide: Use fallthrough pseudo-keyword
[linux-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
ba8f6a03 9 * Copyright 2018-2020 Intel Corporation
59bbb6f7
JB
10 */
11
54858ee5 12#include <linux/export.h>
59bbb6f7
JB
13#include <net/cfg80211.h>
14#include "core.h"
e35e4d28 15#include "rdev-ops.h"
59bbb6f7 16
2a38075c
AAL
17static bool cfg80211_valid_60g_freq(u32 freq)
18{
19 return freq >= 58320 && freq <= 70200;
20}
21
3d9d1d66
JB
22void cfg80211_chandef_create(struct cfg80211_chan_def *chandef,
23 struct ieee80211_channel *chan,
24 enum nl80211_channel_type chan_type)
9236d838 25{
3d9d1d66
JB
26 if (WARN_ON(!chan))
27 return;
9236d838 28
3d9d1d66 29 chandef->chan = chan;
934f4c7d 30 chandef->freq1_offset = chan->freq_offset;
3d9d1d66 31 chandef->center_freq2 = 0;
2a38075c
AAL
32 chandef->edmg.bw_config = 0;
33 chandef->edmg.channels = 0;
4ee3e063 34
3d9d1d66
JB
35 switch (chan_type) {
36 case NL80211_CHAN_NO_HT:
37 chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
38 chandef->center_freq1 = chan->center_freq;
39 break;
40 case NL80211_CHAN_HT20:
41 chandef->width = NL80211_CHAN_WIDTH_20;
42 chandef->center_freq1 = chan->center_freq;
43 break;
9236d838 44 case NL80211_CHAN_HT40PLUS:
3d9d1d66
JB
45 chandef->width = NL80211_CHAN_WIDTH_40;
46 chandef->center_freq1 = chan->center_freq + 10;
09a02fdb 47 break;
9236d838 48 case NL80211_CHAN_HT40MINUS:
3d9d1d66
JB
49 chandef->width = NL80211_CHAN_WIDTH_40;
50 chandef->center_freq1 = chan->center_freq - 10;
09a02fdb 51 break;
9236d838 52 default:
3d9d1d66
JB
53 WARN_ON(1);
54 }
55}
56EXPORT_SYMBOL(cfg80211_chandef_create);
57
2a38075c
AAL
58static bool cfg80211_edmg_chandef_valid(const struct cfg80211_chan_def *chandef)
59{
60 int max_contiguous = 0;
61 int num_of_enabled = 0;
62 int contiguous = 0;
63 int i;
64
65 if (!chandef->edmg.channels || !chandef->edmg.bw_config)
66 return false;
67
68 if (!cfg80211_valid_60g_freq(chandef->chan->center_freq))
69 return false;
70
71 for (i = 0; i < 6; i++) {
72 if (chandef->edmg.channels & BIT(i)) {
73 contiguous++;
74 num_of_enabled++;
75 } else {
76 contiguous = 0;
77 }
78
79 max_contiguous = max(contiguous, max_contiguous);
80 }
81 /* basic verification of edmg configuration according to
82 * IEEE P802.11ay/D4.0 section 9.4.2.251
83 */
84 /* check bw_config against contiguous edmg channels */
85 switch (chandef->edmg.bw_config) {
86 case IEEE80211_EDMG_BW_CONFIG_4:
87 case IEEE80211_EDMG_BW_CONFIG_8:
88 case IEEE80211_EDMG_BW_CONFIG_12:
89 if (max_contiguous < 1)
90 return false;
91 break;
92 case IEEE80211_EDMG_BW_CONFIG_5:
93 case IEEE80211_EDMG_BW_CONFIG_9:
94 case IEEE80211_EDMG_BW_CONFIG_13:
95 if (max_contiguous < 2)
96 return false;
97 break;
98 case IEEE80211_EDMG_BW_CONFIG_6:
99 case IEEE80211_EDMG_BW_CONFIG_10:
100 case IEEE80211_EDMG_BW_CONFIG_14:
101 if (max_contiguous < 3)
102 return false;
103 break;
104 case IEEE80211_EDMG_BW_CONFIG_7:
105 case IEEE80211_EDMG_BW_CONFIG_11:
106 case IEEE80211_EDMG_BW_CONFIG_15:
107 if (max_contiguous < 4)
108 return false;
109 break;
110
111 default:
112 return false;
113 }
114
115 /* check bw_config against aggregated (non contiguous) edmg channels */
116 switch (chandef->edmg.bw_config) {
117 case IEEE80211_EDMG_BW_CONFIG_4:
118 case IEEE80211_EDMG_BW_CONFIG_5:
119 case IEEE80211_EDMG_BW_CONFIG_6:
120 case IEEE80211_EDMG_BW_CONFIG_7:
121 break;
122 case IEEE80211_EDMG_BW_CONFIG_8:
123 case IEEE80211_EDMG_BW_CONFIG_9:
124 case IEEE80211_EDMG_BW_CONFIG_10:
125 case IEEE80211_EDMG_BW_CONFIG_11:
126 if (num_of_enabled < 2)
127 return false;
128 break;
129 case IEEE80211_EDMG_BW_CONFIG_12:
130 case IEEE80211_EDMG_BW_CONFIG_13:
131 case IEEE80211_EDMG_BW_CONFIG_14:
132 case IEEE80211_EDMG_BW_CONFIG_15:
133 if (num_of_enabled < 4 || max_contiguous < 2)
134 return false;
135 break;
136 default:
137 return false;
138 }
139
140 return true;
141}
142
9f5e8f6e 143bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef)
3d9d1d66
JB
144{
145 u32 control_freq;
146
147 if (!chandef->chan)
148 return false;
149
be689f68
JB
150 if (chandef->freq1_offset >= 1000)
151 return false;
152
3d9d1d66
JB
153 control_freq = chandef->chan->center_freq;
154
155 switch (chandef->width) {
df78a0c0
TP
156 case NL80211_CHAN_WIDTH_1:
157 case NL80211_CHAN_WIDTH_2:
158 case NL80211_CHAN_WIDTH_4:
159 case NL80211_CHAN_WIDTH_8:
160 case NL80211_CHAN_WIDTH_16:
2f301ab2
SW
161 case NL80211_CHAN_WIDTH_5:
162 case NL80211_CHAN_WIDTH_10:
3d9d1d66
JB
163 case NL80211_CHAN_WIDTH_20:
164 case NL80211_CHAN_WIDTH_20_NOHT:
934f4c7d
TP
165 if (ieee80211_chandef_to_khz(chandef) !=
166 ieee80211_channel_to_khz(chandef->chan))
3d9d1d66
JB
167 return false;
168 if (chandef->center_freq2)
169 return false;
170 break;
171 case NL80211_CHAN_WIDTH_40:
172 if (chandef->center_freq1 != control_freq + 10 &&
173 chandef->center_freq1 != control_freq - 10)
174 return false;
175 if (chandef->center_freq2)
176 return false;
177 break;
178 case NL80211_CHAN_WIDTH_80P80:
179 if (chandef->center_freq1 != control_freq + 30 &&
180 chandef->center_freq1 != control_freq + 10 &&
181 chandef->center_freq1 != control_freq - 10 &&
182 chandef->center_freq1 != control_freq - 30)
183 return false;
184 if (!chandef->center_freq2)
185 return false;
9cab3151
JB
186 /* adjacent is not allowed -- that's a 160 MHz channel */
187 if (chandef->center_freq1 - chandef->center_freq2 == 80 ||
188 chandef->center_freq2 - chandef->center_freq1 == 80)
189 return false;
3d9d1d66
JB
190 break;
191 case NL80211_CHAN_WIDTH_80:
192 if (chandef->center_freq1 != control_freq + 30 &&
193 chandef->center_freq1 != control_freq + 10 &&
194 chandef->center_freq1 != control_freq - 10 &&
195 chandef->center_freq1 != control_freq - 30)
196 return false;
197 if (chandef->center_freq2)
198 return false;
199 break;
200 case NL80211_CHAN_WIDTH_160:
201 if (chandef->center_freq1 != control_freq + 70 &&
202 chandef->center_freq1 != control_freq + 50 &&
203 chandef->center_freq1 != control_freq + 30 &&
204 chandef->center_freq1 != control_freq + 10 &&
205 chandef->center_freq1 != control_freq - 10 &&
206 chandef->center_freq1 != control_freq - 30 &&
207 chandef->center_freq1 != control_freq - 50 &&
208 chandef->center_freq1 != control_freq - 70)
209 return false;
210 if (chandef->center_freq2)
211 return false;
212 break;
213 default:
214 return false;
215 }
216
ec649fed
MH
217 /* channel 14 is only for IEEE 802.11b */
218 if (chandef->center_freq1 == 2484 &&
219 chandef->width != NL80211_CHAN_WIDTH_20_NOHT)
220 return false;
221
2a38075c
AAL
222 if (cfg80211_chandef_is_edmg(chandef) &&
223 !cfg80211_edmg_chandef_valid(chandef))
224 return false;
225
3d9d1d66
JB
226 return true;
227}
9f5e8f6e 228EXPORT_SYMBOL(cfg80211_chandef_valid);
3d9d1d66
JB
229
230static void chandef_primary_freqs(const struct cfg80211_chan_def *c,
fc1f48ff 231 u32 *pri40, u32 *pri80)
3d9d1d66
JB
232{
233 int tmp;
234
235 switch (c->width) {
236 case NL80211_CHAN_WIDTH_40:
237 *pri40 = c->center_freq1;
238 *pri80 = 0;
239 break;
240 case NL80211_CHAN_WIDTH_80:
241 case NL80211_CHAN_WIDTH_80P80:
242 *pri80 = c->center_freq1;
243 /* n_P20 */
244 tmp = (30 + c->chan->center_freq - c->center_freq1)/20;
245 /* n_P40 */
246 tmp /= 2;
247 /* freq_P40 */
248 *pri40 = c->center_freq1 - 20 + 40 * tmp;
249 break;
250 case NL80211_CHAN_WIDTH_160:
251 /* n_P20 */
252 tmp = (70 + c->chan->center_freq - c->center_freq1)/20;
253 /* n_P40 */
254 tmp /= 2;
255 /* freq_P40 */
256 *pri40 = c->center_freq1 - 60 + 40 * tmp;
257 /* n_P80 */
258 tmp /= 2;
259 *pri80 = c->center_freq1 - 40 + 80 * tmp;
260 break;
261 default:
262 WARN_ON_ONCE(1);
263 }
264}
265
04f39047
SW
266static int cfg80211_chandef_get_width(const struct cfg80211_chan_def *c)
267{
268 int width;
269
270 switch (c->width) {
df78a0c0
TP
271 case NL80211_CHAN_WIDTH_1:
272 width = 1;
273 break;
274 case NL80211_CHAN_WIDTH_2:
275 width = 2;
276 break;
277 case NL80211_CHAN_WIDTH_4:
278 width = 4;
279 break;
280 case NL80211_CHAN_WIDTH_8:
281 width = 8;
282 break;
283 case NL80211_CHAN_WIDTH_16:
284 width = 16;
285 break;
2f301ab2
SW
286 case NL80211_CHAN_WIDTH_5:
287 width = 5;
288 break;
289 case NL80211_CHAN_WIDTH_10:
290 width = 10;
291 break;
04f39047
SW
292 case NL80211_CHAN_WIDTH_20:
293 case NL80211_CHAN_WIDTH_20_NOHT:
294 width = 20;
295 break;
296 case NL80211_CHAN_WIDTH_40:
297 width = 40;
298 break;
299 case NL80211_CHAN_WIDTH_80P80:
300 case NL80211_CHAN_WIDTH_80:
301 width = 80;
302 break;
303 case NL80211_CHAN_WIDTH_160:
304 width = 160;
305 break;
306 default:
307 WARN_ON_ONCE(1);
308 return -1;
309 }
310 return width;
311}
312
3d9d1d66
JB
313const struct cfg80211_chan_def *
314cfg80211_chandef_compatible(const struct cfg80211_chan_def *c1,
315 const struct cfg80211_chan_def *c2)
316{
317 u32 c1_pri40, c1_pri80, c2_pri40, c2_pri80;
318
319 /* If they are identical, return */
320 if (cfg80211_chandef_identical(c1, c2))
321 return c1;
322
323 /* otherwise, must have same control channel */
324 if (c1->chan != c2->chan)
325 return NULL;
326
327 /*
328 * If they have the same width, but aren't identical,
329 * then they can't be compatible.
330 */
331 if (c1->width == c2->width)
332 return NULL;
333
2f301ab2
SW
334 /*
335 * can't be compatible if one of them is 5 or 10 MHz,
336 * but they don't have the same width.
337 */
338 if (c1->width == NL80211_CHAN_WIDTH_5 ||
339 c1->width == NL80211_CHAN_WIDTH_10 ||
340 c2->width == NL80211_CHAN_WIDTH_5 ||
341 c2->width == NL80211_CHAN_WIDTH_10)
342 return NULL;
343
3d9d1d66
JB
344 if (c1->width == NL80211_CHAN_WIDTH_20_NOHT ||
345 c1->width == NL80211_CHAN_WIDTH_20)
346 return c2;
347
348 if (c2->width == NL80211_CHAN_WIDTH_20_NOHT ||
349 c2->width == NL80211_CHAN_WIDTH_20)
350 return c1;
351
352 chandef_primary_freqs(c1, &c1_pri40, &c1_pri80);
353 chandef_primary_freqs(c2, &c2_pri40, &c2_pri80);
354
355 if (c1_pri40 != c2_pri40)
356 return NULL;
357
358 WARN_ON(!c1_pri80 && !c2_pri80);
359 if (c1_pri80 && c2_pri80 && c1_pri80 != c2_pri80)
360 return NULL;
361
362 if (c1->width > c2->width)
363 return c1;
364 return c2;
365}
366EXPORT_SYMBOL(cfg80211_chandef_compatible);
367
04f39047
SW
368static void cfg80211_set_chans_dfs_state(struct wiphy *wiphy, u32 center_freq,
369 u32 bandwidth,
370 enum nl80211_dfs_state dfs_state)
371{
372 struct ieee80211_channel *c;
373 u32 freq;
374
375 for (freq = center_freq - bandwidth/2 + 10;
376 freq <= center_freq + bandwidth/2 - 10;
377 freq += 20) {
378 c = ieee80211_get_channel(wiphy, freq);
379 if (!c || !(c->flags & IEEE80211_CHAN_RADAR))
380 continue;
381
382 c->dfs_state = dfs_state;
383 c->dfs_state_entered = jiffies;
384 }
385}
386
387void cfg80211_set_dfs_state(struct wiphy *wiphy,
388 const struct cfg80211_chan_def *chandef,
389 enum nl80211_dfs_state dfs_state)
390{
391 int width;
392
393 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
394 return;
395
396 width = cfg80211_chandef_get_width(chandef);
397 if (width < 0)
398 return;
399
400 cfg80211_set_chans_dfs_state(wiphy, chandef->center_freq1,
401 width, dfs_state);
402
403 if (!chandef->center_freq2)
404 return;
405 cfg80211_set_chans_dfs_state(wiphy, chandef->center_freq2,
406 width, dfs_state);
407}
408
40d1ba63
JD
409static u32 cfg80211_get_start_freq(u32 center_freq,
410 u32 bandwidth)
411{
412 u32 start_freq;
413
934f4c7d
TP
414 bandwidth = MHZ_TO_KHZ(bandwidth);
415 if (bandwidth <= MHZ_TO_KHZ(20))
40d1ba63
JD
416 start_freq = center_freq;
417 else
934f4c7d 418 start_freq = center_freq - bandwidth / 2 + MHZ_TO_KHZ(10);
40d1ba63
JD
419
420 return start_freq;
421}
422
423static u32 cfg80211_get_end_freq(u32 center_freq,
424 u32 bandwidth)
425{
426 u32 end_freq;
427
934f4c7d
TP
428 bandwidth = MHZ_TO_KHZ(bandwidth);
429 if (bandwidth <= MHZ_TO_KHZ(20))
40d1ba63
JD
430 end_freq = center_freq;
431 else
934f4c7d 432 end_freq = center_freq + bandwidth / 2 - MHZ_TO_KHZ(10);
40d1ba63
JD
433
434 return end_freq;
435}
436
04f39047
SW
437static int cfg80211_get_chans_dfs_required(struct wiphy *wiphy,
438 u32 center_freq,
439 u32 bandwidth)
440{
441 struct ieee80211_channel *c;
2f301ab2
SW
442 u32 freq, start_freq, end_freq;
443
40d1ba63
JD
444 start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
445 end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
04f39047 446
934f4c7d
TP
447 for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
448 c = ieee80211_get_channel_khz(wiphy, freq);
04f39047
SW
449 if (!c)
450 return -EINVAL;
451
452 if (c->flags & IEEE80211_CHAN_RADAR)
453 return 1;
454 }
455 return 0;
456}
457
458
459int cfg80211_chandef_dfs_required(struct wiphy *wiphy,
2beb6dab
LC
460 const struct cfg80211_chan_def *chandef,
461 enum nl80211_iftype iftype)
04f39047
SW
462{
463 int width;
2beb6dab 464 int ret;
04f39047
SW
465
466 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
467 return -EINVAL;
468
2beb6dab
LC
469 switch (iftype) {
470 case NL80211_IFTYPE_ADHOC:
471 case NL80211_IFTYPE_AP:
472 case NL80211_IFTYPE_P2P_GO:
473 case NL80211_IFTYPE_MESH_POINT:
474 width = cfg80211_chandef_get_width(chandef);
475 if (width < 0)
476 return -EINVAL;
04f39047 477
2beb6dab 478 ret = cfg80211_get_chans_dfs_required(wiphy,
934f4c7d
TP
479 ieee80211_chandef_to_khz(chandef),
480 width);
2beb6dab
LC
481 if (ret < 0)
482 return ret;
483 else if (ret > 0)
484 return BIT(chandef->width);
04f39047 485
2beb6dab
LC
486 if (!chandef->center_freq2)
487 return 0;
488
489 ret = cfg80211_get_chans_dfs_required(wiphy,
934f4c7d
TP
490 MHZ_TO_KHZ(chandef->center_freq2),
491 width);
2beb6dab
LC
492 if (ret < 0)
493 return ret;
494 else if (ret > 0)
495 return BIT(chandef->width);
04f39047 496
2beb6dab
LC
497 break;
498 case NL80211_IFTYPE_STATION:
6e0bd6c3 499 case NL80211_IFTYPE_OCB:
2beb6dab
LC
500 case NL80211_IFTYPE_P2P_CLIENT:
501 case NL80211_IFTYPE_MONITOR:
502 case NL80211_IFTYPE_AP_VLAN:
503 case NL80211_IFTYPE_WDS:
504 case NL80211_IFTYPE_P2P_DEVICE:
cb3b7d87 505 case NL80211_IFTYPE_NAN:
2beb6dab 506 break;
00ec75fc 507 case NL80211_IFTYPE_UNSPECIFIED:
2beb6dab
LC
508 case NUM_NL80211_IFTYPES:
509 WARN_ON(1);
510 }
511
512 return 0;
04f39047 513}
774f0734 514EXPORT_SYMBOL(cfg80211_chandef_dfs_required);
04f39047 515
fe7c3a1f
JD
516static int cfg80211_get_chans_dfs_usable(struct wiphy *wiphy,
517 u32 center_freq,
518 u32 bandwidth)
519{
520 struct ieee80211_channel *c;
521 u32 freq, start_freq, end_freq;
522 int count = 0;
523
524 start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
525 end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
526
527 /*
528 * Check entire range of channels for the bandwidth.
529 * Check all channels are DFS channels (DFS_USABLE or
530 * DFS_AVAILABLE). Return number of usable channels
531 * (require CAC). Allow DFS and non-DFS channel mix.
532 */
934f4c7d
TP
533 for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
534 c = ieee80211_get_channel_khz(wiphy, freq);
fe7c3a1f
JD
535 if (!c)
536 return -EINVAL;
537
538 if (c->flags & IEEE80211_CHAN_DISABLED)
539 return -EINVAL;
540
541 if (c->flags & IEEE80211_CHAN_RADAR) {
542 if (c->dfs_state == NL80211_DFS_UNAVAILABLE)
543 return -EINVAL;
544
545 if (c->dfs_state == NL80211_DFS_USABLE)
546 count++;
547 }
548 }
549
550 return count;
551}
552
553bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy,
554 const struct cfg80211_chan_def *chandef)
555{
556 int width;
557 int r1, r2 = 0;
558
559 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
560 return false;
561
562 width = cfg80211_chandef_get_width(chandef);
563 if (width < 0)
564 return false;
565
934f4c7d
TP
566 r1 = cfg80211_get_chans_dfs_usable(wiphy,
567 MHZ_TO_KHZ(chandef->center_freq1),
568 width);
fe7c3a1f
JD
569
570 if (r1 < 0)
571 return false;
572
573 switch (chandef->width) {
574 case NL80211_CHAN_WIDTH_80P80:
575 WARN_ON(!chandef->center_freq2);
576 r2 = cfg80211_get_chans_dfs_usable(wiphy,
934f4c7d
TP
577 MHZ_TO_KHZ(chandef->center_freq2),
578 width);
fe7c3a1f
JD
579 if (r2 < 0)
580 return false;
581 break;
582 default:
583 WARN_ON(chandef->center_freq2);
584 break;
585 }
586
587 return (r1 + r2 > 0);
588}
589
b35a51c7
VT
590/*
591 * Checks if center frequency of chan falls with in the bandwidth
592 * range of chandef.
593 */
594bool cfg80211_is_sub_chan(struct cfg80211_chan_def *chandef,
595 struct ieee80211_channel *chan)
596{
597 int width;
a67a4893 598 u32 freq;
b35a51c7
VT
599
600 if (chandef->chan->center_freq == chan->center_freq)
601 return true;
602
603 width = cfg80211_chandef_get_width(chandef);
604 if (width <= 20)
605 return false;
606
b35a51c7
VT
607 for (freq = chandef->center_freq1 - width / 2 + 10;
608 freq <= chandef->center_freq1 + width / 2 - 10; freq += 20) {
609 if (chan->center_freq == freq)
610 return true;
611 }
612
613 if (!chandef->center_freq2)
614 return false;
615
616 for (freq = chandef->center_freq2 - width / 2 + 10;
617 freq <= chandef->center_freq2 + width / 2 - 10; freq += 20) {
618 if (chan->center_freq == freq)
619 return true;
620 }
621
622 return false;
623}
624
625bool cfg80211_beaconing_iface_active(struct wireless_dev *wdev)
626{
627 bool active = false;
628
629 ASSERT_WDEV_LOCK(wdev);
630
631 if (!wdev->chandef.chan)
632 return false;
633
634 switch (wdev->iftype) {
635 case NL80211_IFTYPE_AP:
636 case NL80211_IFTYPE_P2P_GO:
637 active = wdev->beacon_interval != 0;
638 break;
639 case NL80211_IFTYPE_ADHOC:
640 active = wdev->ssid_len != 0;
641 break;
642 case NL80211_IFTYPE_MESH_POINT:
643 active = wdev->mesh_id_len != 0;
644 break;
645 case NL80211_IFTYPE_STATION:
646 case NL80211_IFTYPE_OCB:
647 case NL80211_IFTYPE_P2P_CLIENT:
648 case NL80211_IFTYPE_MONITOR:
649 case NL80211_IFTYPE_AP_VLAN:
650 case NL80211_IFTYPE_WDS:
651 case NL80211_IFTYPE_P2P_DEVICE:
652 /* Can NAN type be considered as beaconing interface? */
653 case NL80211_IFTYPE_NAN:
654 break;
655 case NL80211_IFTYPE_UNSPECIFIED:
656 case NUM_NL80211_IFTYPES:
657 WARN_ON(1);
658 }
659
660 return active;
661}
662
89766727
VT
663static bool cfg80211_is_wiphy_oper_chan(struct wiphy *wiphy,
664 struct ieee80211_channel *chan)
b35a51c7
VT
665{
666 struct wireless_dev *wdev;
667
b35a51c7
VT
668 list_for_each_entry(wdev, &wiphy->wdev_list, list) {
669 wdev_lock(wdev);
670 if (!cfg80211_beaconing_iface_active(wdev)) {
671 wdev_unlock(wdev);
672 continue;
673 }
674
675 if (cfg80211_is_sub_chan(&wdev->chandef, chan)) {
676 wdev_unlock(wdev);
677 return true;
678 }
679 wdev_unlock(wdev);
680 }
681
682 return false;
683}
fe7c3a1f 684
89766727
VT
685bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy,
686 struct ieee80211_channel *chan)
687{
688 struct cfg80211_registered_device *rdev;
689
690 ASSERT_RTNL();
691
692 if (!(chan->flags & IEEE80211_CHAN_RADAR))
693 return false;
694
695 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
696 if (!reg_dfs_domain_same(wiphy, &rdev->wiphy))
697 continue;
698
699 if (cfg80211_is_wiphy_oper_chan(&rdev->wiphy, chan))
700 return true;
701 }
702
703 return false;
704}
705
6bc54fbc
JD
706static bool cfg80211_get_chans_dfs_available(struct wiphy *wiphy,
707 u32 center_freq,
708 u32 bandwidth)
3d9d1d66
JB
709{
710 struct ieee80211_channel *c;
2f301ab2 711 u32 freq, start_freq, end_freq;
2c390e44
DL
712 bool dfs_offload;
713
714 dfs_offload = wiphy_ext_feature_isset(wiphy,
715 NL80211_EXT_FEATURE_DFS_OFFLOAD);
2f301ab2 716
40d1ba63
JD
717 start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
718 end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
3d9d1d66 719
6bc54fbc
JD
720 /*
721 * Check entire range of channels for the bandwidth.
722 * If any channel in between is disabled or has not
723 * had gone through CAC return false
724 */
934f4c7d
TP
725 for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
726 c = ieee80211_get_channel_khz(wiphy, freq);
04f39047
SW
727 if (!c)
728 return false;
729
6bc54fbc
JD
730 if (c->flags & IEEE80211_CHAN_DISABLED)
731 return false;
732
2c390e44
DL
733 if ((c->flags & IEEE80211_CHAN_RADAR) &&
734 (c->dfs_state != NL80211_DFS_AVAILABLE) &&
735 !(c->dfs_state == NL80211_DFS_USABLE && dfs_offload))
04f39047 736 return false;
6bc54fbc
JD
737 }
738
739 return true;
740}
741
742static bool cfg80211_chandef_dfs_available(struct wiphy *wiphy,
743 const struct cfg80211_chan_def *chandef)
744{
745 int width;
746 int r;
747
748 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
749 return false;
750
751 width = cfg80211_chandef_get_width(chandef);
752 if (width < 0)
753 return false;
754
934f4c7d
TP
755 r = cfg80211_get_chans_dfs_available(wiphy,
756 MHZ_TO_KHZ(chandef->center_freq1),
6bc54fbc
JD
757 width);
758
759 /* If any of channels unavailable for cf1 just return */
760 if (!r)
761 return r;
762
763 switch (chandef->width) {
764 case NL80211_CHAN_WIDTH_80P80:
765 WARN_ON(!chandef->center_freq2);
766 r = cfg80211_get_chans_dfs_available(wiphy,
934f4c7d
TP
767 MHZ_TO_KHZ(chandef->center_freq2),
768 width);
680682d4 769 break;
6bc54fbc
JD
770 default:
771 WARN_ON(chandef->center_freq2);
772 break;
773 }
774
775 return r;
776}
777
31559f35
JD
778static unsigned int cfg80211_get_chans_dfs_cac_time(struct wiphy *wiphy,
779 u32 center_freq,
780 u32 bandwidth)
781{
782 struct ieee80211_channel *c;
783 u32 start_freq, end_freq, freq;
784 unsigned int dfs_cac_ms = 0;
785
786 start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
787 end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
788
934f4c7d
TP
789 for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
790 c = ieee80211_get_channel_khz(wiphy, freq);
31559f35
JD
791 if (!c)
792 return 0;
793
794 if (c->flags & IEEE80211_CHAN_DISABLED)
795 return 0;
796
797 if (!(c->flags & IEEE80211_CHAN_RADAR))
798 continue;
799
800 if (c->dfs_cac_ms > dfs_cac_ms)
801 dfs_cac_ms = c->dfs_cac_ms;
802 }
803
804 return dfs_cac_ms;
805}
806
807unsigned int
808cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
809 const struct cfg80211_chan_def *chandef)
810{
811 int width;
812 unsigned int t1 = 0, t2 = 0;
813
814 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
815 return 0;
816
817 width = cfg80211_chandef_get_width(chandef);
818 if (width < 0)
819 return 0;
820
821 t1 = cfg80211_get_chans_dfs_cac_time(wiphy,
934f4c7d 822 MHZ_TO_KHZ(chandef->center_freq1),
31559f35
JD
823 width);
824
825 if (!chandef->center_freq2)
826 return t1;
827
828 t2 = cfg80211_get_chans_dfs_cac_time(wiphy,
934f4c7d 829 MHZ_TO_KHZ(chandef->center_freq2),
31559f35
JD
830 width);
831
832 return max(t1, t2);
833}
6bc54fbc
JD
834
835static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
836 u32 center_freq, u32 bandwidth,
837 u32 prohibited_flags)
838{
839 struct ieee80211_channel *c;
840 u32 freq, start_freq, end_freq;
04f39047 841
6bc54fbc
JD
842 start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
843 end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
844
934f4c7d
TP
845 for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
846 c = ieee80211_get_channel_khz(wiphy, freq);
6bc54fbc 847 if (!c || c->flags & prohibited_flags)
3d9d1d66 848 return false;
9236d838
LR
849 }
850
3d9d1d66
JB
851 return true;
852}
853
2a38075c
AAL
854/* check if the operating channels are valid and supported */
855static bool cfg80211_edmg_usable(struct wiphy *wiphy, u8 edmg_channels,
856 enum ieee80211_edmg_bw_config edmg_bw_config,
857 int primary_channel,
858 struct ieee80211_edmg *edmg_cap)
859{
860 struct ieee80211_channel *chan;
861 int i, freq;
862 int channels_counter = 0;
863
864 if (!edmg_channels && !edmg_bw_config)
865 return true;
866
867 if ((!edmg_channels && edmg_bw_config) ||
868 (edmg_channels && !edmg_bw_config))
869 return false;
870
871 if (!(edmg_channels & BIT(primary_channel - 1)))
872 return false;
873
874 /* 60GHz channels 1..6 */
875 for (i = 0; i < 6; i++) {
876 if (!(edmg_channels & BIT(i)))
877 continue;
878
879 if (!(edmg_cap->channels & BIT(i)))
880 return false;
881
882 channels_counter++;
883
884 freq = ieee80211_channel_to_frequency(i + 1,
885 NL80211_BAND_60GHZ);
886 chan = ieee80211_get_channel(wiphy, freq);
887 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
888 return false;
889 }
890
891 /* IEEE802.11 allows max 4 channels */
892 if (channels_counter > 4)
893 return false;
894
895 /* check bw_config is a subset of what driver supports
896 * (see IEEE P802.11ay/D4.0 section 9.4.2.251, Table 13)
897 */
898 if ((edmg_bw_config % 4) > (edmg_cap->bw_config % 4))
899 return false;
900
901 if (edmg_bw_config > edmg_cap->bw_config)
902 return false;
903
904 return true;
905}
906
9f5e8f6e
JB
907bool cfg80211_chandef_usable(struct wiphy *wiphy,
908 const struct cfg80211_chan_def *chandef,
909 u32 prohibited_flags)
3d9d1d66 910{
9f5e8f6e
JB
911 struct ieee80211_sta_ht_cap *ht_cap;
912 struct ieee80211_sta_vht_cap *vht_cap;
2a38075c 913 struct ieee80211_edmg *edmg_cap;
08f6f147 914 u32 width, control_freq, cap;
3d9d1d66 915
9f5e8f6e
JB
916 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
917 return false;
3d9d1d66 918
9f5e8f6e
JB
919 ht_cap = &wiphy->bands[chandef->chan->band]->ht_cap;
920 vht_cap = &wiphy->bands[chandef->chan->band]->vht_cap;
2a38075c
AAL
921 edmg_cap = &wiphy->bands[chandef->chan->band]->edmg_cap;
922
923 if (edmg_cap->channels &&
924 !cfg80211_edmg_usable(wiphy,
925 chandef->edmg.channels,
926 chandef->edmg.bw_config,
927 chandef->chan->hw_value,
928 edmg_cap))
929 return false;
3d9d1d66 930
9f5e8f6e 931 control_freq = chandef->chan->center_freq;
9236d838 932
3d9d1d66 933 switch (chandef->width) {
df78a0c0
TP
934 case NL80211_CHAN_WIDTH_1:
935 width = 1;
936 break;
937 case NL80211_CHAN_WIDTH_2:
938 width = 2;
939 break;
940 case NL80211_CHAN_WIDTH_4:
941 width = 4;
942 break;
943 case NL80211_CHAN_WIDTH_8:
944 width = 8;
945 break;
946 case NL80211_CHAN_WIDTH_16:
947 width = 16;
948 break;
2f301ab2
SW
949 case NL80211_CHAN_WIDTH_5:
950 width = 5;
951 break;
952 case NL80211_CHAN_WIDTH_10:
ea077c1c 953 prohibited_flags |= IEEE80211_CHAN_NO_10MHZ;
2f301ab2
SW
954 width = 10;
955 break;
3d9d1d66 956 case NL80211_CHAN_WIDTH_20:
ba8f6a03
JB
957 if (!ht_cap->ht_supported &&
958 chandef->chan->band != NL80211_BAND_6GHZ)
9f5e8f6e 959 return false;
df561f66 960 fallthrough;
9f5e8f6e 961 case NL80211_CHAN_WIDTH_20_NOHT:
ea077c1c 962 prohibited_flags |= IEEE80211_CHAN_NO_20MHZ;
3d9d1d66
JB
963 width = 20;
964 break;
965 case NL80211_CHAN_WIDTH_40:
966 width = 40;
ba8f6a03
JB
967 if (chandef->chan->band == NL80211_BAND_6GHZ)
968 break;
9f5e8f6e
JB
969 if (!ht_cap->ht_supported)
970 return false;
971 if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ||
972 ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT)
973 return false;
974 if (chandef->center_freq1 < control_freq &&
975 chandef->chan->flags & IEEE80211_CHAN_NO_HT40MINUS)
976 return false;
977 if (chandef->center_freq1 > control_freq &&
978 chandef->chan->flags & IEEE80211_CHAN_NO_HT40PLUS)
979 return false;
3d9d1d66 980 break;
3d9d1d66 981 case NL80211_CHAN_WIDTH_80P80:
08f6f147 982 cap = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
ba8f6a03
JB
983 if (chandef->chan->band != NL80211_BAND_6GHZ &&
984 cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
9f5e8f6e 985 return false;
df561f66 986 fallthrough;
9f5e8f6e 987 case NL80211_CHAN_WIDTH_80:
c7a6ee27 988 prohibited_flags |= IEEE80211_CHAN_NO_80MHZ;
3d9d1d66 989 width = 80;
ba8f6a03
JB
990 if (chandef->chan->band == NL80211_BAND_6GHZ)
991 break;
992 if (!vht_cap->vht_supported)
993 return false;
3d9d1d66
JB
994 break;
995 case NL80211_CHAN_WIDTH_160:
ba8f6a03
JB
996 prohibited_flags |= IEEE80211_CHAN_NO_160MHZ;
997 width = 160;
998 if (chandef->chan->band == NL80211_BAND_6GHZ)
999 break;
9f5e8f6e
JB
1000 if (!vht_cap->vht_supported)
1001 return false;
08f6f147
JM
1002 cap = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
1003 if (cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ &&
1004 cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
9f5e8f6e 1005 return false;
3d9d1d66
JB
1006 break;
1007 default:
1008 WARN_ON_ONCE(1);
9236d838 1009 return false;
4ee3e063 1010 }
3d9d1d66 1011
c7a6ee27
JB
1012 /*
1013 * TODO: What if there are only certain 80/160/80+80 MHz channels
1014 * allowed by the driver, or only certain combinations?
1015 * For 40 MHz the driver can set the NO_HT40 flags, but for
1016 * 80/160 MHz and in particular 80+80 MHz this isn't really
1017 * feasible and we only have NO_80MHZ/NO_160MHZ so far but
1018 * no way to cover 80+80 MHz or more complex restrictions.
1019 * Note that such restrictions also need to be advertised to
1020 * userspace, for example for P2P channel selection.
1021 */
9f5e8f6e 1022
a6662dba
JB
1023 if (width > 20)
1024 prohibited_flags |= IEEE80211_CHAN_NO_OFDM;
1025
2f301ab2
SW
1026 /* 5 and 10 MHz are only defined for the OFDM PHY */
1027 if (width < 20)
1028 prohibited_flags |= IEEE80211_CHAN_NO_OFDM;
1029
1030
934f4c7d
TP
1031 if (!cfg80211_secondary_chans_ok(wiphy,
1032 ieee80211_chandef_to_khz(chandef),
9f5e8f6e
JB
1033 width, prohibited_flags))
1034 return false;
1035
1036 if (!chandef->center_freq2)
1037 return true;
934f4c7d
TP
1038 return cfg80211_secondary_chans_ok(wiphy,
1039 MHZ_TO_KHZ(chandef->center_freq2),
9f5e8f6e
JB
1040 width, prohibited_flags);
1041}
1042EXPORT_SYMBOL(cfg80211_chandef_usable);
1043
174e0cd2 1044/*
06f207fc
AN
1045 * Check if the channel can be used under permissive conditions mandated by
1046 * some regulatory bodies, i.e., the channel is marked with
1047 * IEEE80211_CHAN_IR_CONCURRENT and there is an additional station interface
174e0cd2
IP
1048 * associated to an AP on the same channel or on the same UNII band
1049 * (assuming that the AP is an authorized master).
06f207fc 1050 * In addition allow operation on a channel on which indoor operation is
c8866e55 1051 * allowed, iff we are currently operating in an indoor environment.
174e0cd2 1052 */
06f207fc
AN
1053static bool cfg80211_ir_permissive_chan(struct wiphy *wiphy,
1054 enum nl80211_iftype iftype,
174e0cd2
IP
1055 struct ieee80211_channel *chan)
1056{
be69c24a 1057 struct wireless_dev *wdev;
06f207fc 1058 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
174e0cd2
IP
1059
1060 ASSERT_RTNL();
1061
97f2645f 1062 if (!IS_ENABLED(CONFIG_CFG80211_REG_RELAX_NO_IR) ||
c8866e55
IP
1063 !(wiphy->regulatory_flags & REGULATORY_ENABLE_RELAX_NO_IR))
1064 return false;
1065
06f207fc
AN
1066 /* only valid for GO and TDLS off-channel (station/p2p-CL) */
1067 if (iftype != NL80211_IFTYPE_P2P_GO &&
1068 iftype != NL80211_IFTYPE_STATION &&
1069 iftype != NL80211_IFTYPE_P2P_CLIENT)
1070 return false;
1071
c8866e55
IP
1072 if (regulatory_indoor_allowed() &&
1073 (chan->flags & IEEE80211_CHAN_INDOOR_ONLY))
1074 return true;
1075
06f207fc 1076 if (!(chan->flags & IEEE80211_CHAN_IR_CONCURRENT))
174e0cd2
IP
1077 return false;
1078
1079 /*
1080 * Generally, it is possible to rely on another device/driver to allow
06f207fc 1081 * the IR concurrent relaxation, however, since the device can further
174e0cd2
IP
1082 * enforce the relaxation (by doing a similar verifications as this),
1083 * and thus fail the GO instantiation, consider only the interfaces of
1084 * the current registered device.
1085 */
53873f13 1086 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
174e0cd2
IP
1087 struct ieee80211_channel *other_chan = NULL;
1088 int r1, r2;
1089
be69c24a
AS
1090 wdev_lock(wdev);
1091 if (wdev->iftype == NL80211_IFTYPE_STATION &&
1092 wdev->current_bss)
1093 other_chan = wdev->current_bss->pub.channel;
1094
1095 /*
1096 * If a GO already operates on the same GO_CONCURRENT channel,
1097 * this one (maybe the same one) can beacon as well. We allow
1098 * the operation even if the station we relied on with
1099 * GO_CONCURRENT is disconnected now. But then we must make sure
1100 * we're not outdoor on an indoor-only channel.
1101 */
06f207fc
AN
1102 if (iftype == NL80211_IFTYPE_P2P_GO &&
1103 wdev->iftype == NL80211_IFTYPE_P2P_GO &&
be69c24a
AS
1104 wdev->beacon_interval &&
1105 !(chan->flags & IEEE80211_CHAN_INDOOR_ONLY))
1106 other_chan = wdev->chandef.chan;
1107 wdev_unlock(wdev);
174e0cd2
IP
1108
1109 if (!other_chan)
1110 continue;
1111
1112 if (chan == other_chan)
1113 return true;
1114
0816e6b1
AS
1115 if (chan->band != NL80211_BAND_5GHZ &&
1116 chan->band != NL80211_BAND_6GHZ)
174e0cd2
IP
1117 continue;
1118
1119 r1 = cfg80211_get_unii(chan->center_freq);
1120 r2 = cfg80211_get_unii(other_chan->center_freq);
1121
46d53724
IP
1122 if (r1 != -EINVAL && r1 == r2) {
1123 /*
1124 * At some locations channels 149-165 are considered a
1125 * bundle, but at other locations, e.g., Indonesia,
1126 * channels 149-161 are considered a bundle while
1127 * channel 165 is left out and considered to be in a
1128 * different bundle. Thus, in case that there is a
1129 * station interface connected to an AP on channel 165,
1130 * it is assumed that channels 149-161 are allowed for
1131 * GO operations. However, having a station interface
1132 * connected to an AP on channels 149-161, does not
1133 * allow GO operation on channel 165.
1134 */
1135 if (chan->center_freq == 5825 &&
1136 other_chan->center_freq != 5825)
1137 continue;
174e0cd2 1138 return true;
46d53724 1139 }
174e0cd2
IP
1140 }
1141
1142 return false;
1143}
1144
923b352f
AN
1145static bool _cfg80211_reg_can_beacon(struct wiphy *wiphy,
1146 struct cfg80211_chan_def *chandef,
1147 enum nl80211_iftype iftype,
1148 bool check_no_ir)
9f5e8f6e
JB
1149{
1150 bool res;
6bc54fbc 1151 u32 prohibited_flags = IEEE80211_CHAN_DISABLED |
6bc54fbc 1152 IEEE80211_CHAN_RADAR;
9f5e8f6e 1153
923b352f 1154 trace_cfg80211_reg_can_beacon(wiphy, chandef, iftype, check_no_ir);
174e0cd2 1155
923b352f 1156 if (check_no_ir)
174e0cd2 1157 prohibited_flags |= IEEE80211_CHAN_NO_IR;
3d9d1d66 1158
00ec75fc 1159 if (cfg80211_chandef_dfs_required(wiphy, chandef, iftype) > 0 &&
6bc54fbc
JD
1160 cfg80211_chandef_dfs_available(wiphy, chandef)) {
1161 /* We can skip IEEE80211_CHAN_NO_IR if chandef dfs available */
1162 prohibited_flags = IEEE80211_CHAN_DISABLED;
1163 }
1164
1165 res = cfg80211_chandef_usable(wiphy, chandef, prohibited_flags);
3d9d1d66
JB
1166
1167 trace_cfg80211_return_bool(res);
1168 return res;
9236d838 1169}
923b352f
AN
1170
1171bool cfg80211_reg_can_beacon(struct wiphy *wiphy,
1172 struct cfg80211_chan_def *chandef,
1173 enum nl80211_iftype iftype)
1174{
1175 return _cfg80211_reg_can_beacon(wiphy, chandef, iftype, true);
1176}
683b6d3b 1177EXPORT_SYMBOL(cfg80211_reg_can_beacon);
9236d838 1178
923b352f
AN
1179bool cfg80211_reg_can_beacon_relax(struct wiphy *wiphy,
1180 struct cfg80211_chan_def *chandef,
1181 enum nl80211_iftype iftype)
1182{
1183 bool check_no_ir;
1184
1185 ASSERT_RTNL();
1186
1187 /*
1188 * Under certain conditions suggested by some regulatory bodies a
1189 * GO/STA can IR on channels marked with IEEE80211_NO_IR. Set this flag
1190 * only if such relaxations are not enabled and the conditions are not
1191 * met.
1192 */
1193 check_no_ir = !cfg80211_ir_permissive_chan(wiphy, iftype,
1194 chandef->chan);
1195
1196 return _cfg80211_reg_can_beacon(wiphy, chandef, iftype, check_no_ir);
1197}
1198EXPORT_SYMBOL(cfg80211_reg_can_beacon_relax);
1199
e8c9bd5b 1200int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
683b6d3b 1201 struct cfg80211_chan_def *chandef)
9588bbd5 1202{
e8c9bd5b 1203 if (!rdev->ops->set_monitor_channel)
9588bbd5 1204 return -EOPNOTSUPP;
4f03c1ed
MK
1205 if (!cfg80211_has_monitors_only(rdev))
1206 return -EBUSY;
9588bbd5 1207
683b6d3b 1208 return rdev_set_monitor_channel(rdev, chandef);
59bbb6f7 1209}
26ab9a0c
MK
1210
1211void
8e95ea49 1212cfg80211_get_chan_state(struct wireless_dev *wdev,
26ab9a0c 1213 struct ieee80211_channel **chan,
9e0e2961
MK
1214 enum cfg80211_chan_mode *chanmode,
1215 u8 *radar_detect)
26ab9a0c 1216{
2beb6dab
LC
1217 int ret;
1218
26ab9a0c
MK
1219 *chan = NULL;
1220 *chanmode = CHAN_MODE_UNDEFINED;
1221
26ab9a0c
MK
1222 ASSERT_WDEV_LOCK(wdev);
1223
98104fde 1224 if (wdev->netdev && !netif_running(wdev->netdev))
26ab9a0c
MK
1225 return;
1226
1227 switch (wdev->iftype) {
1228 case NL80211_IFTYPE_ADHOC:
1229 if (wdev->current_bss) {
1230 *chan = wdev->current_bss->pub.channel;
5336fa88
SW
1231 *chanmode = (wdev->ibss_fixed &&
1232 !wdev->ibss_dfs_possible)
26ab9a0c
MK
1233 ? CHAN_MODE_SHARED
1234 : CHAN_MODE_EXCLUSIVE;
9e0e2961
MK
1235
1236 /* consider worst-case - IBSS can try to return to the
1237 * original user-specified channel as creator */
1238 if (wdev->ibss_dfs_possible)
1239 *radar_detect |= BIT(wdev->chandef.width);
26ab9a0c
MK
1240 return;
1241 }
0f0094b3 1242 break;
26ab9a0c
MK
1243 case NL80211_IFTYPE_STATION:
1244 case NL80211_IFTYPE_P2P_CLIENT:
1245 if (wdev->current_bss) {
1246 *chan = wdev->current_bss->pub.channel;
1247 *chanmode = CHAN_MODE_SHARED;
1248 return;
1249 }
1250 break;
1251 case NL80211_IFTYPE_AP:
1252 case NL80211_IFTYPE_P2P_GO:
04f39047 1253 if (wdev->cac_started) {
9e0e2961 1254 *chan = wdev->chandef.chan;
04f39047 1255 *chanmode = CHAN_MODE_SHARED;
9e0e2961 1256 *radar_detect |= BIT(wdev->chandef.width);
04f39047 1257 } else if (wdev->beacon_interval) {
9e0e2961 1258 *chan = wdev->chandef.chan;
f53594a0 1259 *chanmode = CHAN_MODE_SHARED;
9e0e2961 1260
2beb6dab
LC
1261 ret = cfg80211_chandef_dfs_required(wdev->wiphy,
1262 &wdev->chandef,
1263 wdev->iftype);
1264 WARN_ON(ret < 0);
1265 if (ret > 0)
9e0e2961 1266 *radar_detect |= BIT(wdev->chandef.width);
f53594a0
FF
1267 }
1268 return;
26ab9a0c 1269 case NL80211_IFTYPE_MESH_POINT:
f53594a0 1270 if (wdev->mesh_id_len) {
9e0e2961 1271 *chan = wdev->chandef.chan;
f53594a0 1272 *chanmode = CHAN_MODE_SHARED;
9e0e2961 1273
2beb6dab
LC
1274 ret = cfg80211_chandef_dfs_required(wdev->wiphy,
1275 &wdev->chandef,
1276 wdev->iftype);
1277 WARN_ON(ret < 0);
1278 if (ret > 0)
9e0e2961 1279 *radar_detect |= BIT(wdev->chandef.width);
f53594a0 1280 }
26ab9a0c 1281 return;
6e0bd6c3
RL
1282 case NL80211_IFTYPE_OCB:
1283 if (wdev->chandef.chan) {
1284 *chan = wdev->chandef.chan;
1285 *chanmode = CHAN_MODE_SHARED;
1286 return;
1287 }
1288 break;
26ab9a0c
MK
1289 case NL80211_IFTYPE_MONITOR:
1290 case NL80211_IFTYPE_AP_VLAN:
1291 case NL80211_IFTYPE_WDS:
98104fde 1292 case NL80211_IFTYPE_P2P_DEVICE:
cb3b7d87 1293 case NL80211_IFTYPE_NAN:
e7aceef4 1294 /* these interface types don't really have a channel */
98104fde 1295 return;
26ab9a0c
MK
1296 case NL80211_IFTYPE_UNSPECIFIED:
1297 case NUM_NL80211_IFTYPES:
1298 WARN_ON(1);
1299 }
26ab9a0c 1300}