~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/wireless/chan.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php