1
2
3
4
5
6
7
8
9
10
11
12#include <linux/export.h>
13#include <net/cfg80211.h>
14#include "core.h"
15#include "rdev-ops.h"
16
17static bool cfg80211_valid_60g_freq(u32 freq)
18{
19 return freq >= 58320 && freq <= 70200;
20}
21
22void cfg80211_chandef_create(struct cfg80211_chan_def *chandef,
23 struct ieee80211_channel *chan,
24 enum nl80211_channel_type chan_type)
25{
26 if (WARN_ON(!chan))
27 return;
28
29 chandef->chan = chan;
30 chandef->freq1_offset = chan->freq_offset;
31 chandef->center_freq2 = 0;
32 chandef->edmg.bw_config = 0;
33 chandef->edmg.channels = 0;
34
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;
44 case NL80211_CHAN_HT40PLUS:
45 chandef->width = NL80211_CHAN_WIDTH_40;
46 chandef->center_freq1 = chan->center_freq + 10;
47 break;
48 case NL80211_CHAN_HT40MINUS:
49 chandef->width = NL80211_CHAN_WIDTH_40;
50 chandef->center_freq1 = chan->center_freq - 10;
51 break;
52 default:
53 WARN_ON(1);
54 }
55}
56EXPORT_SYMBOL(cfg80211_chandef_create);
57
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
82
83
84
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
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
143bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef)
144{
145 u32 control_freq;
146
147 if (!chandef->chan)
148 return false;
149
150 if (chandef->freq1_offset >= 1000)
151 return false;
152
153 control_freq = chandef->chan->center_freq;
154
155 switch (chandef->width) {
156 case NL80211_CHAN_WIDTH_5:
157 case NL80211_CHAN_WIDTH_10:
158 case NL80211_CHAN_WIDTH_20:
159 case NL80211_CHAN_WIDTH_20_NOHT:
160 if (ieee80211_chandef_to_khz(chandef) !=
161 ieee80211_channel_to_khz(chandef->chan))
162 return false;
163 if (chandef->center_freq2)
164 return false;
165 break;
166 case NL80211_CHAN_WIDTH_40:
167 if (chandef->center_freq1 != control_freq + 10 &&
168 chandef->center_freq1 != control_freq - 10)
169 return false;
170 if (chandef->center_freq2)
171 return false;
172 break;
173 case NL80211_CHAN_WIDTH_80P80:
174 if (chandef->center_freq1 != control_freq + 30 &&
175 chandef->center_freq1 != control_freq + 10 &&
176 chandef->center_freq1 != control_freq - 10 &&
177 chandef->center_freq1 != control_freq - 30)
178 return false;
179 if (!chandef->center_freq2)
180 return false;
181
182 if (chandef->center_freq1 - chandef->center_freq2 == 80 ||
183 chandef->center_freq2 - chandef->center_freq1 == 80)
184 return false;
185 break;
186 case NL80211_CHAN_WIDTH_80:
187 if (chandef->center_freq1 != control_freq + 30 &&
188 chandef->center_freq1 != control_freq + 10 &&
189 chandef->center_freq1 != control_freq - 10 &&
190 chandef->center_freq1 != control_freq - 30)
191 return false;
192 if (chandef->center_freq2)
193 return false;
194 break;
195 case NL80211_CHAN_WIDTH_160:
196 if (chandef->center_freq1 != control_freq + 70 &&
197 chandef->center_freq1 != control_freq + 50 &&
198 chandef->center_freq1 != control_freq + 30 &&
199 chandef->center_freq1 != control_freq + 10 &&
200 chandef->center_freq1 != control_freq - 10 &&
201 chandef->center_freq1 != control_freq - 30 &&
202 chandef->center_freq1 != control_freq - 50 &&
203 chandef->center_freq1 != control_freq - 70)
204 return false;
205 if (chandef->center_freq2)
206 return false;
207 break;
208 default:
209 return false;
210 }
211
212
213 if (chandef->center_freq1 == 2484 &&
214 chandef->width != NL80211_CHAN_WIDTH_20_NOHT)
215 return false;
216
217 if (cfg80211_chandef_is_edmg(chandef) &&
218 !cfg80211_edmg_chandef_valid(chandef))
219 return false;
220
221 return true;
222}
223EXPORT_SYMBOL(cfg80211_chandef_valid);
224
225static void chandef_primary_freqs(const struct cfg80211_chan_def *c,
226 u32 *pri40, u32 *pri80)
227{
228 int tmp;
229
230 switch (c->width) {
231 case NL80211_CHAN_WIDTH_40:
232 *pri40 = c->center_freq1;
233 *pri80 = 0;
234 break;
235 case NL80211_CHAN_WIDTH_80:
236 case NL80211_CHAN_WIDTH_80P80:
237 *pri80 = c->center_freq1;
238
239 tmp = (30 + c->chan->center_freq - c->center_freq1)/20;
240
241 tmp /= 2;
242
243 *pri40 = c->center_freq1 - 20 + 40 * tmp;
244 break;
245 case NL80211_CHAN_WIDTH_160:
246
247 tmp = (70 + c->chan->center_freq - c->center_freq1)/20;
248
249 tmp /= 2;
250
251 *pri40 = c->center_freq1 - 60 + 40 * tmp;
252
253 tmp /= 2;
254 *pri80 = c->center_freq1 - 40 + 80 * tmp;
255 break;
256 default:
257 WARN_ON_ONCE(1);
258 }
259}
260
261static int cfg80211_chandef_get_width(const struct cfg80211_chan_def *c)
262{
263 int width;
264
265 switch (c->width) {
266 case NL80211_CHAN_WIDTH_5:
267 width = 5;
268 break;
269 case NL80211_CHAN_WIDTH_10:
270 width = 10;
271 break;
272 case NL80211_CHAN_WIDTH_20:
273 case NL80211_CHAN_WIDTH_20_NOHT:
274 width = 20;
275 break;
276 case NL80211_CHAN_WIDTH_40:
277 width = 40;
278 break;
279 case NL80211_CHAN_WIDTH_80P80:
280 case NL80211_CHAN_WIDTH_80:
281 width = 80;
282 break;
283 case NL80211_CHAN_WIDTH_160:
284 width = 160;
285 break;
286 default:
287 WARN_ON_ONCE(1);
288 return -1;
289 }
290 return width;
291}
292
293const struct cfg80211_chan_def *
294cfg80211_chandef_compatible(const struct cfg80211_chan_def *c1,
295 const struct cfg80211_chan_def *c2)
296{
297 u32 c1_pri40, c1_pri80, c2_pri40, c2_pri80;
298
299
300 if (cfg80211_chandef_identical(c1, c2))
301 return c1;
302
303
304 if (c1->chan != c2->chan)
305 return NULL;
306
307
308
309
310
311 if (c1->width == c2->width)
312 return NULL;
313
314
315
316
317
318 if (c1->width == NL80211_CHAN_WIDTH_5 ||
319 c1->width == NL80211_CHAN_WIDTH_10 ||
320 c2->width == NL80211_CHAN_WIDTH_5 ||
321 c2->width == NL80211_CHAN_WIDTH_10)
322 return NULL;
323
324 if (c1->width == NL80211_CHAN_WIDTH_20_NOHT ||
325 c1->width == NL80211_CHAN_WIDTH_20)
326 return c2;
327
328 if (c2->width == NL80211_CHAN_WIDTH_20_NOHT ||
329 c2->width == NL80211_CHAN_WIDTH_20)
330 return c1;
331
332 chandef_primary_freqs(c1, &c1_pri40, &c1_pri80);
333 chandef_primary_freqs(c2, &c2_pri40, &c2_pri80);
334
335 if (c1_pri40 != c2_pri40)
336 return NULL;
337
338 WARN_ON(!c1_pri80 && !c2_pri80);
339 if (c1_pri80 && c2_pri80 && c1_pri80 != c2_pri80)
340 return NULL;
341
342 if (c1->width > c2->width)
343 return c1;
344 return c2;
345}
346EXPORT_SYMBOL(cfg80211_chandef_compatible);
347
348static void cfg80211_set_chans_dfs_state(struct wiphy *wiphy, u32 center_freq,
349 u32 bandwidth,
350 enum nl80211_dfs_state dfs_state)
351{
352 struct ieee80211_channel *c;
353 u32 freq;
354
355 for (freq = center_freq - bandwidth/2 + 10;
356 freq <= center_freq + bandwidth/2 - 10;
357 freq += 20) {
358 c = ieee80211_get_channel(wiphy, freq);
359 if (!c || !(c->flags & IEEE80211_CHAN_RADAR))
360 continue;
361
362 c->dfs_state = dfs_state;
363 c->dfs_state_entered = jiffies;
364 }
365}
366
367void cfg80211_set_dfs_state(struct wiphy *wiphy,
368 const struct cfg80211_chan_def *chandef,
369 enum nl80211_dfs_state dfs_state)
370{
371 int width;
372
373 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
374 return;
375
376 width = cfg80211_chandef_get_width(chandef);
377 if (width < 0)
378 return;
379
380 cfg80211_set_chans_dfs_state(wiphy, chandef->center_freq1,
381 width, dfs_state);
382
383 if (!chandef->center_freq2)
384 return;
385 cfg80211_set_chans_dfs_state(wiphy, chandef->center_freq2,
386 width, dfs_state);
387}
388
389static u32 cfg80211_get_start_freq(u32 center_freq,
390 u32 bandwidth)
391{
392 u32 start_freq;
393
394 bandwidth = MHZ_TO_KHZ(bandwidth);
395 if (bandwidth <= MHZ_TO_KHZ(20))
396 start_freq = center_freq;
397 else
398 start_freq = center_freq - bandwidth / 2 + MHZ_TO_KHZ(10);
399
400 return start_freq;
401}
402
403static u32 cfg80211_get_end_freq(u32 center_freq,
404 u32 bandwidth)
405{
406 u32 end_freq;
407
408 bandwidth = MHZ_TO_KHZ(bandwidth);
409 if (bandwidth <= MHZ_TO_KHZ(20))
410 end_freq = center_freq;
411 else
412 end_freq = center_freq + bandwidth / 2 - MHZ_TO_KHZ(10);
413
414 return end_freq;
415}
416
417static int cfg80211_get_chans_dfs_required(struct wiphy *wiphy,
418 u32 center_freq,
419 u32 bandwidth)
420{
421 struct ieee80211_channel *c;
422 u32 freq, start_freq, end_freq;
423
424 start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
425 end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
426
427 for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
428 c = ieee80211_get_channel_khz(wiphy, freq);
429 if (!c)
430 return -EINVAL;
431
432 if (c->flags & IEEE80211_CHAN_RADAR)
433 return 1;
434 }
435 return 0;
436}
437
438
439int cfg80211_chandef_dfs_required(struct wiphy *wiphy,
440 const struct cfg80211_chan_def *chandef,
441 enum nl80211_iftype iftype)
442{
443 int width;
444 int ret;
445
446 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
447 return -EINVAL;
448
449 switch (iftype) {
450 case NL80211_IFTYPE_ADHOC:
451 case NL80211_IFTYPE_AP:
452 case NL80211_IFTYPE_P2P_GO:
453 case NL80211_IFTYPE_MESH_POINT:
454 width = cfg80211_chandef_get_width(chandef);
455 if (width < 0)
456 return -EINVAL;
457
458 ret = cfg80211_get_chans_dfs_required(wiphy,
459 ieee80211_chandef_to_khz(chandef),
460 width);
461 if (ret < 0)
462 return ret;
463 else if (ret > 0)
464 return BIT(chandef->width);
465
466 if (!chandef->center_freq2)
467 return 0;
468
469 ret = cfg80211_get_chans_dfs_required(wiphy,
470 MHZ_TO_KHZ(chandef->center_freq2),
471 width);
472 if (ret < 0)
473 return ret;
474 else if (ret > 0)
475 return BIT(chandef->width);
476
477 break;
478 case NL80211_IFTYPE_STATION:
479 case NL80211_IFTYPE_OCB:
480 case NL80211_IFTYPE_P2P_CLIENT:
481 case NL80211_IFTYPE_MONITOR:
482 case NL80211_IFTYPE_AP_VLAN:
483 case NL80211_IFTYPE_WDS:
484 case NL80211_IFTYPE_P2P_DEVICE:
485 case NL80211_IFTYPE_NAN:
486 break;
487 case NL80211_IFTYPE_UNSPECIFIED:
488 case NUM_NL80211_IFTYPES:
489 WARN_ON(1);
490 }
491
492 return 0;
493}
494EXPORT_SYMBOL(cfg80211_chandef_dfs_required);
495
496static int cfg80211_get_chans_dfs_usable(struct wiphy *wiphy,
497 u32 center_freq,
498 u32 bandwidth)
499{
500 struct ieee80211_channel *c;
501 u32 freq, start_freq, end_freq;
502 int count = 0;
503
504 start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
505 end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
506
507
508
509
510
511
512
513 for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
514 c = ieee80211_get_channel_khz(wiphy, freq);
515 if (!c)
516 return -EINVAL;
517
518 if (c->flags & IEEE80211_CHAN_DISABLED)
519 return -EINVAL;
520
521 if (c->flags & IEEE80211_CHAN_RADAR) {
522 if (c->dfs_state == NL80211_DFS_UNAVAILABLE)
523 return -EINVAL;
524
525 if (c->dfs_state == NL80211_DFS_USABLE)
526 count++;
527 }
528 }
529
530 return count;
531}
532
533bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy,
534 const struct cfg80211_chan_def *chandef)
535{
536 int width;
537 int r1, r2 = 0;
538
539 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
540 return false;
541
542 width = cfg80211_chandef_get_width(chandef);
543 if (width < 0)
544 return false;
545
546 r1 = cfg80211_get_chans_dfs_usable(wiphy,
547 MHZ_TO_KHZ(chandef->center_freq1),
548 width);
549
550 if (r1 < 0)
551 return false;
552
553 switch (chandef->width) {
554 case NL80211_CHAN_WIDTH_80P80:
555 WARN_ON(!chandef->center_freq2);
556 r2 = cfg80211_get_chans_dfs_usable(wiphy,
557 MHZ_TO_KHZ(chandef->center_freq2),
558 width);
559 if (r2 < 0)
560 return false;
561 break;
562 default:
563 WARN_ON(chandef->center_freq2);
564 break;
565 }
566
567 return (r1 + r2 > 0);
568}
569
570
571
572
573
574bool cfg80211_is_sub_chan(struct cfg80211_chan_def *chandef,
575 struct ieee80211_channel *chan)
576{
577 int width;
578 u32 freq;
579
580 if (chandef->chan->center_freq == chan->center_freq)
581 return true;
582
583 width = cfg80211_chandef_get_width(chandef);
584 if (width <= 20)
585 return false;
586
587 for (freq = chandef->center_freq1 - width / 2 + 10;
588 freq <= chandef->center_freq1 + width / 2 - 10; freq += 20) {
589 if (chan->center_freq == freq)
590 return true;
591 }
592
593 if (!chandef->center_freq2)
594 return false;
595
596 for (freq = chandef->center_freq2 - width / 2 + 10;
597 freq <= chandef->center_freq2 + width / 2 - 10; freq += 20) {
598 if (chan->center_freq == freq)
599 return true;
600 }
601
602 return false;
603}
604
605bool cfg80211_beaconing_iface_active(struct wireless_dev *wdev)
606{
607 bool active = false;
608
609 ASSERT_WDEV_LOCK(wdev);
610
611 if (!wdev->chandef.chan)
612 return false;
613
614 switch (wdev->iftype) {
615 case NL80211_IFTYPE_AP:
616 case NL80211_IFTYPE_P2P_GO:
617 active = wdev->beacon_interval != 0;
618 break;
619 case NL80211_IFTYPE_ADHOC:
620 active = wdev->ssid_len != 0;
621 break;
622 case NL80211_IFTYPE_MESH_POINT:
623 active = wdev->mesh_id_len != 0;
624 break;
625 case NL80211_IFTYPE_STATION:
626 case NL80211_IFTYPE_OCB:
627 case NL80211_IFTYPE_P2P_CLIENT:
628 case NL80211_IFTYPE_MONITOR:
629 case NL80211_IFTYPE_AP_VLAN:
630 case NL80211_IFTYPE_WDS:
631 case NL80211_IFTYPE_P2P_DEVICE:
632
633 case NL80211_IFTYPE_NAN:
634 break;
635 case NL80211_IFTYPE_UNSPECIFIED:
636 case NUM_NL80211_IFTYPES:
637 WARN_ON(1);
638 }
639
640 return active;
641}
642
643static bool cfg80211_is_wiphy_oper_chan(struct wiphy *wiphy,
644 struct ieee80211_channel *chan)
645{
646 struct wireless_dev *wdev;
647
648 list_for_each_entry(wdev, &wiphy->wdev_list, list) {
649 wdev_lock(wdev);
650 if (!cfg80211_beaconing_iface_active(wdev)) {
651 wdev_unlock(wdev);
652 continue;
653 }
654
655 if (cfg80211_is_sub_chan(&wdev->chandef, chan)) {
656 wdev_unlock(wdev);
657 return true;
658 }
659 wdev_unlock(wdev);
660 }
661
662 return false;
663}
664
665bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy,
666 struct ieee80211_channel *chan)
667{
668 struct cfg80211_registered_device *rdev;
669
670 ASSERT_RTNL();
671
672 if (!(chan->flags & IEEE80211_CHAN_RADAR))
673 return false;
674
675 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
676 if (!reg_dfs_domain_same(wiphy, &rdev->wiphy))
677 continue;
678
679 if (cfg80211_is_wiphy_oper_chan(&rdev->wiphy, chan))
680 return true;
681 }
682
683 return false;
684}
685
686static bool cfg80211_get_chans_dfs_available(struct wiphy *wiphy,
687 u32 center_freq,
688 u32 bandwidth)
689{
690 struct ieee80211_channel *c;
691 u32 freq, start_freq, end_freq;
692 bool dfs_offload;
693
694 dfs_offload = wiphy_ext_feature_isset(wiphy,
695 NL80211_EXT_FEATURE_DFS_OFFLOAD);
696
697 start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
698 end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
699
700
701
702
703
704
705 for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
706 c = ieee80211_get_channel_khz(wiphy, freq);
707 if (!c)
708 return false;
709
710 if (c->flags & IEEE80211_CHAN_DISABLED)
711 return false;
712
713 if ((c->flags & IEEE80211_CHAN_RADAR) &&
714 (c->dfs_state != NL80211_DFS_AVAILABLE) &&
715 !(c->dfs_state == NL80211_DFS_USABLE && dfs_offload))
716 return false;
717 }
718
719 return true;
720}
721
722static bool cfg80211_chandef_dfs_available(struct wiphy *wiphy,
723 const struct cfg80211_chan_def *chandef)
724{
725 int width;
726 int r;
727
728 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
729 return false;
730
731 width = cfg80211_chandef_get_width(chandef);
732 if (width < 0)
733 return false;
734
735 r = cfg80211_get_chans_dfs_available(wiphy,
736 MHZ_TO_KHZ(chandef->center_freq1),
737 width);
738
739
740 if (!r)
741 return r;
742
743 switch (chandef->width) {
744 case NL80211_CHAN_WIDTH_80P80:
745 WARN_ON(!chandef->center_freq2);
746 r = cfg80211_get_chans_dfs_available(wiphy,
747 MHZ_TO_KHZ(chandef->center_freq2),
748 width);
749 break;
750 default:
751 WARN_ON(chandef->center_freq2);
752 break;
753 }
754
755 return r;
756}
757
758static unsigned int cfg80211_get_chans_dfs_cac_time(struct wiphy *wiphy,
759 u32 center_freq,
760 u32 bandwidth)
761{
762 struct ieee80211_channel *c;
763 u32 start_freq, end_freq, freq;
764 unsigned int dfs_cac_ms = 0;
765
766 start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
767 end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
768
769 for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
770 c = ieee80211_get_channel_khz(wiphy, freq);
771 if (!c)
772 return 0;
773
774 if (c->flags & IEEE80211_CHAN_DISABLED)
775 return 0;
776
777 if (!(c->flags & IEEE80211_CHAN_RADAR))
778 continue;
779
780 if (c->dfs_cac_ms > dfs_cac_ms)
781 dfs_cac_ms = c->dfs_cac_ms;
782 }
783
784 return dfs_cac_ms;
785}
786
787unsigned int
788cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
789 const struct cfg80211_chan_def *chandef)
790{
791 int width;
792 unsigned int t1 = 0, t2 = 0;
793
794 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
795 return 0;
796
797 width = cfg80211_chandef_get_width(chandef);
798 if (width < 0)
799 return 0;
800
801 t1 = cfg80211_get_chans_dfs_cac_time(wiphy,
802 MHZ_TO_KHZ(chandef->center_freq1),
803 width);
804
805 if (!chandef->center_freq2)
806 return t1;
807
808 t2 = cfg80211_get_chans_dfs_cac_time(wiphy,
809 MHZ_TO_KHZ(chandef->center_freq2),
810 width);
811
812 return max(t1, t2);
813}
814
815static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
816 u32 center_freq, u32 bandwidth,
817 u32 prohibited_flags)
818{
819 struct ieee80211_channel *c;
820 u32 freq, start_freq, end_freq;
821
822 start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
823 end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
824
825 for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
826 c = ieee80211_get_channel_khz(wiphy, freq);
827 if (!c || c->flags & prohibited_flags)
828 return false;
829 }
830
831 return true;
832}
833
834
835static bool cfg80211_edmg_usable(struct wiphy *wiphy, u8 edmg_channels,
836 enum ieee80211_edmg_bw_config edmg_bw_config,
837 int primary_channel,
838 struct ieee80211_edmg *edmg_cap)
839{
840 struct ieee80211_channel *chan;
841 int i, freq;
842 int channels_counter = 0;
843
844 if (!edmg_channels && !edmg_bw_config)
845 return true;
846
847 if ((!edmg_channels && edmg_bw_config) ||
848 (edmg_channels && !edmg_bw_config))
849 return false;
850
851 if (!(edmg_channels & BIT(primary_channel - 1)))
852 return false;
853
854
855 for (i = 0; i < 6; i++) {
856 if (!(edmg_channels & BIT(i)))
857 continue;
858
859 if (!(edmg_cap->channels & BIT(i)))
860 return false;
861
862 channels_counter++;
863
864 freq = ieee80211_channel_to_frequency(i + 1,
865 NL80211_BAND_60GHZ);
866 chan = ieee80211_get_channel(wiphy, freq);
867 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
868 return false;
869 }
870
871
872 if (channels_counter > 4)
873 return false;
874
875
876
877
878 if ((edmg_bw_config % 4) > (edmg_cap->bw_config % 4))
879 return false;
880
881 if (edmg_bw_config > edmg_cap->bw_config)
882 return false;
883
884 return true;
885}
886
887bool cfg80211_chandef_usable(struct wiphy *wiphy,
888 const struct cfg80211_chan_def *chandef,
889 u32 prohibited_flags)
890{
891 struct ieee80211_sta_ht_cap *ht_cap;
892 struct ieee80211_sta_vht_cap *vht_cap;
893 struct ieee80211_edmg *edmg_cap;
894 u32 width, control_freq, cap;
895
896 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
897 return false;
898
899 ht_cap = &wiphy->bands[chandef->chan->band]->ht_cap;
900 vht_cap = &wiphy->bands[chandef->chan->band]->vht_cap;
901 edmg_cap = &wiphy->bands[chandef->chan->band]->edmg_cap;
902
903 if (edmg_cap->channels &&
904 !cfg80211_edmg_usable(wiphy,
905 chandef->edmg.channels,
906 chandef->edmg.bw_config,
907 chandef->chan->hw_value,
908 edmg_cap))
909 return false;
910
911 control_freq = chandef->chan->center_freq;
912
913 switch (chandef->width) {
914 case NL80211_CHAN_WIDTH_5:
915 width = 5;
916 break;
917 case NL80211_CHAN_WIDTH_10:
918 prohibited_flags |= IEEE80211_CHAN_NO_10MHZ;
919 width = 10;
920 break;
921 case NL80211_CHAN_WIDTH_20:
922 if (!ht_cap->ht_supported &&
923 chandef->chan->band != NL80211_BAND_6GHZ)
924 return false;
925
926 case NL80211_CHAN_WIDTH_20_NOHT:
927 prohibited_flags |= IEEE80211_CHAN_NO_20MHZ;
928 width = 20;
929 break;
930 case NL80211_CHAN_WIDTH_40:
931 width = 40;
932 if (chandef->chan->band == NL80211_BAND_6GHZ)
933 break;
934 if (!ht_cap->ht_supported)
935 return false;
936 if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ||
937 ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT)
938 return false;
939 if (chandef->center_freq1 < control_freq &&
940 chandef->chan->flags & IEEE80211_CHAN_NO_HT40MINUS)
941 return false;
942 if (chandef->center_freq1 > control_freq &&
943 chandef->chan->flags & IEEE80211_CHAN_NO_HT40PLUS)
944 return false;
945 break;
946 case NL80211_CHAN_WIDTH_80P80:
947 cap = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
948 if (chandef->chan->band != NL80211_BAND_6GHZ &&
949 cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
950 return false;
951
952 case NL80211_CHAN_WIDTH_80:
953 prohibited_flags |= IEEE80211_CHAN_NO_80MHZ;
954 width = 80;
955 if (chandef->chan->band == NL80211_BAND_6GHZ)
956 break;
957 if (!vht_cap->vht_supported)
958 return false;
959 break;
960 case NL80211_CHAN_WIDTH_160:
961 prohibited_flags |= IEEE80211_CHAN_NO_160MHZ;
962 width = 160;
963 if (chandef->chan->band == NL80211_BAND_6GHZ)
964 break;
965 if (!vht_cap->vht_supported)
966 return false;
967 cap = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
968 if (cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ &&
969 cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
970 return false;
971 break;
972 default:
973 WARN_ON_ONCE(1);
974 return false;
975 }
976
977
978
979
980
981
982
983
984
985
986
987
988 if (width > 20)
989 prohibited_flags |= IEEE80211_CHAN_NO_OFDM;
990
991
992 if (width < 20)
993 prohibited_flags |= IEEE80211_CHAN_NO_OFDM;
994
995
996 if (!cfg80211_secondary_chans_ok(wiphy,
997 ieee80211_chandef_to_khz(chandef),
998 width, prohibited_flags))
999 return false;
1000
1001 if (!chandef->center_freq2)
1002 return true;
1003 return cfg80211_secondary_chans_ok(wiphy,
1004 MHZ_TO_KHZ(chandef->center_freq2),
1005 width, prohibited_flags);
1006}
1007EXPORT_SYMBOL(cfg80211_chandef_usable);
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018static bool cfg80211_ir_permissive_chan(struct wiphy *wiphy,
1019 enum nl80211_iftype iftype,
1020 struct ieee80211_channel *chan)
1021{
1022 struct wireless_dev *wdev;
1023 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
1024
1025 ASSERT_RTNL();
1026
1027 if (!IS_ENABLED(CONFIG_CFG80211_REG_RELAX_NO_IR) ||
1028 !(wiphy->regulatory_flags & REGULATORY_ENABLE_RELAX_NO_IR))
1029 return false;
1030
1031
1032 if (iftype != NL80211_IFTYPE_P2P_GO &&
1033 iftype != NL80211_IFTYPE_STATION &&
1034 iftype != NL80211_IFTYPE_P2P_CLIENT)
1035 return false;
1036
1037 if (regulatory_indoor_allowed() &&
1038 (chan->flags & IEEE80211_CHAN_INDOOR_ONLY))
1039 return true;
1040
1041 if (!(chan->flags & IEEE80211_CHAN_IR_CONCURRENT))
1042 return false;
1043
1044
1045
1046
1047
1048
1049
1050
1051 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
1052 struct ieee80211_channel *other_chan = NULL;
1053 int r1, r2;
1054
1055 wdev_lock(wdev);
1056 if (wdev->iftype == NL80211_IFTYPE_STATION &&
1057 wdev->current_bss)
1058 other_chan = wdev->current_bss->pub.channel;
1059
1060
1061
1062
1063
1064
1065
1066
1067 if (iftype == NL80211_IFTYPE_P2P_GO &&
1068 wdev->iftype == NL80211_IFTYPE_P2P_GO &&
1069 wdev->beacon_interval &&
1070 !(chan->flags & IEEE80211_CHAN_INDOOR_ONLY))
1071 other_chan = wdev->chandef.chan;
1072 wdev_unlock(wdev);
1073
1074 if (!other_chan)
1075 continue;
1076
1077 if (chan == other_chan)
1078 return true;
1079
1080 if (chan->band != NL80211_BAND_5GHZ &&
1081 chan->band != NL80211_BAND_6GHZ)
1082 continue;
1083
1084 r1 = cfg80211_get_unii(chan->center_freq);
1085 r2 = cfg80211_get_unii(other_chan->center_freq);
1086
1087 if (r1 != -EINVAL && r1 == r2) {
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100 if (chan->center_freq == 5825 &&
1101 other_chan->center_freq != 5825)
1102 continue;
1103 return true;
1104 }
1105 }
1106
1107 return false;
1108}
1109
1110static bool _cfg80211_reg_can_beacon(struct wiphy *wiphy,
1111 struct cfg80211_chan_def *chandef,
1112 enum nl80211_iftype iftype,
1113 bool check_no_ir)
1114{
1115 bool res;
1116 u32 prohibited_flags = IEEE80211_CHAN_DISABLED |
1117 IEEE80211_CHAN_RADAR;
1118
1119 trace_cfg80211_reg_can_beacon(wiphy, chandef, iftype, check_no_ir);
1120
1121 if (check_no_ir)
1122 prohibited_flags |= IEEE80211_CHAN_NO_IR;
1123
1124 if (cfg80211_chandef_dfs_required(wiphy, chandef, iftype) > 0 &&
1125 cfg80211_chandef_dfs_available(wiphy, chandef)) {
1126
1127 prohibited_flags = IEEE80211_CHAN_DISABLED;
1128 }
1129
1130 res = cfg80211_chandef_usable(wiphy, chandef, prohibited_flags);
1131
1132 trace_cfg80211_return_bool(res);
1133 return res;
1134}
1135
1136bool cfg80211_reg_can_beacon(struct wiphy *wiphy,
1137 struct cfg80211_chan_def *chandef,
1138 enum nl80211_iftype iftype)
1139{
1140 return _cfg80211_reg_can_beacon(wiphy, chandef, iftype, true);
1141}
1142EXPORT_SYMBOL(cfg80211_reg_can_beacon);
1143
1144bool cfg80211_reg_can_beacon_relax(struct wiphy *wiphy,
1145 struct cfg80211_chan_def *chandef,
1146 enum nl80211_iftype iftype)
1147{
1148 bool check_no_ir;
1149
1150 ASSERT_RTNL();
1151
1152
1153
1154
1155
1156
1157
1158 check_no_ir = !cfg80211_ir_permissive_chan(wiphy, iftype,
1159 chandef->chan);
1160
1161 return _cfg80211_reg_can_beacon(wiphy, chandef, iftype, check_no_ir);
1162}
1163EXPORT_SYMBOL(cfg80211_reg_can_beacon_relax);
1164
1165int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
1166 struct cfg80211_chan_def *chandef)
1167{
1168 if (!rdev->ops->set_monitor_channel)
1169 return -EOPNOTSUPP;
1170 if (!cfg80211_has_monitors_only(rdev))
1171 return -EBUSY;
1172
1173 return rdev_set_monitor_channel(rdev, chandef);
1174}
1175
1176void
1177cfg80211_get_chan_state(struct wireless_dev *wdev,
1178 struct ieee80211_channel **chan,
1179 enum cfg80211_chan_mode *chanmode,
1180 u8 *radar_detect)
1181{
1182 int ret;
1183
1184 *chan = NULL;
1185 *chanmode = CHAN_MODE_UNDEFINED;
1186
1187 ASSERT_WDEV_LOCK(wdev);
1188
1189 if (wdev->netdev && !netif_running(wdev->netdev))
1190 return;
1191
1192 switch (wdev->iftype) {
1193 case NL80211_IFTYPE_ADHOC:
1194 if (wdev->current_bss) {
1195 *chan = wdev->current_bss->pub.channel;
1196 *chanmode = (wdev->ibss_fixed &&
1197 !wdev->ibss_dfs_possible)
1198 ? CHAN_MODE_SHARED
1199 : CHAN_MODE_EXCLUSIVE;
1200
1201
1202
1203 if (wdev->ibss_dfs_possible)
1204 *radar_detect |= BIT(wdev->chandef.width);
1205 return;
1206 }
1207 break;
1208 case NL80211_IFTYPE_STATION:
1209 case NL80211_IFTYPE_P2P_CLIENT:
1210 if (wdev->current_bss) {
1211 *chan = wdev->current_bss->pub.channel;
1212 *chanmode = CHAN_MODE_SHARED;
1213 return;
1214 }
1215 break;
1216 case NL80211_IFTYPE_AP:
1217 case NL80211_IFTYPE_P2P_GO:
1218 if (wdev->cac_started) {
1219 *chan = wdev->chandef.chan;
1220 *chanmode = CHAN_MODE_SHARED;
1221 *radar_detect |= BIT(wdev->chandef.width);
1222 } else if (wdev->beacon_interval) {
1223 *chan = wdev->chandef.chan;
1224 *chanmode = CHAN_MODE_SHARED;
1225
1226 ret = cfg80211_chandef_dfs_required(wdev->wiphy,
1227 &wdev->chandef,
1228 wdev->iftype);
1229 WARN_ON(ret < 0);
1230 if (ret > 0)
1231 *radar_detect |= BIT(wdev->chandef.width);
1232 }
1233 return;
1234 case NL80211_IFTYPE_MESH_POINT:
1235 if (wdev->mesh_id_len) {
1236 *chan = wdev->chandef.chan;
1237 *chanmode = CHAN_MODE_SHARED;
1238
1239 ret = cfg80211_chandef_dfs_required(wdev->wiphy,
1240 &wdev->chandef,
1241 wdev->iftype);
1242 WARN_ON(ret < 0);
1243 if (ret > 0)
1244 *radar_detect |= BIT(wdev->chandef.width);
1245 }
1246 return;
1247 case NL80211_IFTYPE_OCB:
1248 if (wdev->chandef.chan) {
1249 *chan = wdev->chandef.chan;
1250 *chanmode = CHAN_MODE_SHARED;
1251 return;
1252 }
1253 break;
1254 case NL80211_IFTYPE_MONITOR:
1255 case NL80211_IFTYPE_AP_VLAN:
1256 case NL80211_IFTYPE_WDS:
1257 case NL80211_IFTYPE_P2P_DEVICE:
1258 case NL80211_IFTYPE_NAN:
1259
1260 return;
1261 case NL80211_IFTYPE_UNSPECIFIED:
1262 case NUM_NL80211_IFTYPES:
1263 WARN_ON(1);
1264 }
1265}
1266