aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/reg.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/reg.c')
-rw-r--r--net/wireless/reg.c732
1 files changed, 553 insertions, 179 deletions
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index f256dfffbf46..422da20d1e5b 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -33,6 +33,7 @@
33 * 33 *
34 */ 34 */
35#include <linux/kernel.h> 35#include <linux/kernel.h>
36#include <linux/slab.h>
36#include <linux/list.h> 37#include <linux/list.h>
37#include <linux/random.h> 38#include <linux/random.h>
38#include <linux/nl80211.h> 39#include <linux/nl80211.h>
@@ -40,8 +41,18 @@
40#include <net/cfg80211.h> 41#include <net/cfg80211.h>
41#include "core.h" 42#include "core.h"
42#include "reg.h" 43#include "reg.h"
44#include "regdb.h"
43#include "nl80211.h" 45#include "nl80211.h"
44 46
47#ifdef CONFIG_CFG80211_REG_DEBUG
48#define REG_DBG_PRINT(format, args...) \
49 do { \
50 printk(KERN_DEBUG format , ## args); \
51 } while (0)
52#else
53#define REG_DBG_PRINT(args...)
54#endif
55
45/* Receipt of information from last regulatory request */ 56/* Receipt of information from last regulatory request */
46static struct regulatory_request *last_request; 57static struct regulatory_request *last_request;
47 58
@@ -124,107 +135,11 @@ static const struct ieee80211_regdomain *cfg80211_world_regdom =
124 &world_regdom; 135 &world_regdom;
125 136
126static char *ieee80211_regdom = "00"; 137static char *ieee80211_regdom = "00";
138static char user_alpha2[2];
127 139
128module_param(ieee80211_regdom, charp, 0444); 140module_param(ieee80211_regdom, charp, 0444);
129MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code"); 141MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code");
130 142
131#ifdef CONFIG_WIRELESS_OLD_REGULATORY
132/*
133 * We assume 40 MHz bandwidth for the old regulatory work.
134 * We make emphasis we are using the exact same frequencies
135 * as before
136 */
137
138static const struct ieee80211_regdomain us_regdom = {
139 .n_reg_rules = 6,
140 .alpha2 = "US",
141 .reg_rules = {
142 /* IEEE 802.11b/g, channels 1..11 */
143 REG_RULE(2412-10, 2462+10, 40, 6, 27, 0),
144 /* IEEE 802.11a, channel 36 */
145 REG_RULE(5180-10, 5180+10, 40, 6, 23, 0),
146 /* IEEE 802.11a, channel 40 */
147 REG_RULE(5200-10, 5200+10, 40, 6, 23, 0),
148 /* IEEE 802.11a, channel 44 */
149 REG_RULE(5220-10, 5220+10, 40, 6, 23, 0),
150 /* IEEE 802.11a, channels 48..64 */
151 REG_RULE(5240-10, 5320+10, 40, 6, 23, 0),
152 /* IEEE 802.11a, channels 149..165, outdoor */
153 REG_RULE(5745-10, 5825+10, 40, 6, 30, 0),
154 }
155};
156
157static const struct ieee80211_regdomain jp_regdom = {
158 .n_reg_rules = 3,
159 .alpha2 = "JP",
160 .reg_rules = {
161 /* IEEE 802.11b/g, channels 1..14 */
162 REG_RULE(2412-10, 2484+10, 40, 6, 20, 0),
163 /* IEEE 802.11a, channels 34..48 */
164 REG_RULE(5170-10, 5240+10, 40, 6, 20,
165 NL80211_RRF_PASSIVE_SCAN),
166 /* IEEE 802.11a, channels 52..64 */
167 REG_RULE(5260-10, 5320+10, 40, 6, 20,
168 NL80211_RRF_NO_IBSS |
169 NL80211_RRF_DFS),
170 }
171};
172
173static const struct ieee80211_regdomain eu_regdom = {
174 .n_reg_rules = 6,
175 /*
176 * This alpha2 is bogus, we leave it here just for stupid
177 * backward compatibility
178 */
179 .alpha2 = "EU",
180 .reg_rules = {
181 /* IEEE 802.11b/g, channels 1..13 */
182 REG_RULE(2412-10, 2472+10, 40, 6, 20, 0),
183 /* IEEE 802.11a, channel 36 */
184 REG_RULE(5180-10, 5180+10, 40, 6, 23,
185 NL80211_RRF_PASSIVE_SCAN),
186 /* IEEE 802.11a, channel 40 */
187 REG_RULE(5200-10, 5200+10, 40, 6, 23,
188 NL80211_RRF_PASSIVE_SCAN),
189 /* IEEE 802.11a, channel 44 */
190 REG_RULE(5220-10, 5220+10, 40, 6, 23,
191 NL80211_RRF_PASSIVE_SCAN),
192 /* IEEE 802.11a, channels 48..64 */
193 REG_RULE(5240-10, 5320+10, 40, 6, 20,
194 NL80211_RRF_NO_IBSS |
195 NL80211_RRF_DFS),
196 /* IEEE 802.11a, channels 100..140 */
197 REG_RULE(5500-10, 5700+10, 40, 6, 30,
198 NL80211_RRF_NO_IBSS |
199 NL80211_RRF_DFS),
200 }
201};
202
203static const struct ieee80211_regdomain *static_regdom(char *alpha2)
204{
205 if (alpha2[0] == 'U' && alpha2[1] == 'S')
206 return &us_regdom;
207 if (alpha2[0] == 'J' && alpha2[1] == 'P')
208 return &jp_regdom;
209 if (alpha2[0] == 'E' && alpha2[1] == 'U')
210 return &eu_regdom;
211 /* Default, as per the old rules */
212 return &us_regdom;
213}
214
215static bool is_old_static_regdom(const struct ieee80211_regdomain *rd)
216{
217 if (rd == &us_regdom || rd == &jp_regdom || rd == &eu_regdom)
218 return true;
219 return false;
220}
221#else
222static inline bool is_old_static_regdom(const struct ieee80211_regdomain *rd)
223{
224 return false;
225}
226#endif
227
228static void reset_regdomains(void) 143static void reset_regdomains(void)
229{ 144{
230 /* avoid freeing static information or freeing something twice */ 145 /* avoid freeing static information or freeing something twice */
@@ -234,8 +149,6 @@ static void reset_regdomains(void)
234 cfg80211_world_regdom = NULL; 149 cfg80211_world_regdom = NULL;
235 if (cfg80211_regdomain == &world_regdom) 150 if (cfg80211_regdomain == &world_regdom)
236 cfg80211_regdomain = NULL; 151 cfg80211_regdomain = NULL;
237 if (is_old_static_regdom(cfg80211_regdomain))
238 cfg80211_regdomain = NULL;
239 152
240 kfree(cfg80211_regdomain); 153 kfree(cfg80211_regdomain);
241 kfree(cfg80211_world_regdom); 154 kfree(cfg80211_world_regdom);
@@ -341,6 +254,27 @@ static bool regdom_changes(const char *alpha2)
341 return true; 254 return true;
342} 255}
343 256
257/*
258 * The NL80211_REGDOM_SET_BY_USER regdom alpha2 is cached, this lets
259 * you know if a valid regulatory hint with NL80211_REGDOM_SET_BY_USER
260 * has ever been issued.
261 */
262static bool is_user_regdom_saved(void)
263{
264 if (user_alpha2[0] == '9' && user_alpha2[1] == '7')
265 return false;
266
267 /* This would indicate a mistake on the design */
268 if (WARN((!is_world_regdom(user_alpha2) &&
269 !is_an_alpha2(user_alpha2)),
270 "Unexpected user alpha2: %c%c\n",
271 user_alpha2[0],
272 user_alpha2[1]))
273 return false;
274
275 return true;
276}
277
344/** 278/**
345 * country_ie_integrity_changes - tells us if the country IE has changed 279 * country_ie_integrity_changes - tells us if the country IE has changed
346 * @checksum: checksum of country IE of fields we are interested in 280 * @checksum: checksum of country IE of fields we are interested in
@@ -360,6 +294,96 @@ static bool country_ie_integrity_changes(u32 checksum)
360 return false; 294 return false;
361} 295}
362 296
297static int reg_copy_regd(const struct ieee80211_regdomain **dst_regd,
298 const struct ieee80211_regdomain *src_regd)
299{
300 struct ieee80211_regdomain *regd;
301 int size_of_regd = 0;
302 unsigned int i;
303
304 size_of_regd = sizeof(struct ieee80211_regdomain) +
305 ((src_regd->n_reg_rules + 1) * sizeof(struct ieee80211_reg_rule));
306
307 regd = kzalloc(size_of_regd, GFP_KERNEL);
308 if (!regd)
309 return -ENOMEM;
310
311 memcpy(regd, src_regd, sizeof(struct ieee80211_regdomain));
312
313 for (i = 0; i < src_regd->n_reg_rules; i++)
314 memcpy(&regd->reg_rules[i], &src_regd->reg_rules[i],
315 sizeof(struct ieee80211_reg_rule));
316
317 *dst_regd = regd;
318 return 0;
319}
320
321#ifdef CONFIG_CFG80211_INTERNAL_REGDB
322struct reg_regdb_search_request {
323 char alpha2[2];
324 struct list_head list;
325};
326
327static LIST_HEAD(reg_regdb_search_list);
328static DEFINE_MUTEX(reg_regdb_search_mutex);
329
330static void reg_regdb_search(struct work_struct *work)
331{
332 struct reg_regdb_search_request *request;
333 const struct ieee80211_regdomain *curdom, *regdom;
334 int i, r;
335
336 mutex_lock(&reg_regdb_search_mutex);
337 while (!list_empty(&reg_regdb_search_list)) {
338 request = list_first_entry(&reg_regdb_search_list,
339 struct reg_regdb_search_request,
340 list);
341 list_del(&request->list);
342
343 for (i=0; i<reg_regdb_size; i++) {
344 curdom = reg_regdb[i];
345
346 if (!memcmp(request->alpha2, curdom->alpha2, 2)) {
347 r = reg_copy_regd(&regdom, curdom);
348 if (r)
349 break;
350 mutex_lock(&cfg80211_mutex);
351 set_regdom(regdom);
352 mutex_unlock(&cfg80211_mutex);
353 break;
354 }
355 }
356
357 kfree(request);
358 }
359 mutex_unlock(&reg_regdb_search_mutex);
360}
361
362static DECLARE_WORK(reg_regdb_work, reg_regdb_search);
363
364static void reg_regdb_query(const char *alpha2)
365{
366 struct reg_regdb_search_request *request;
367
368 if (!alpha2)
369 return;
370
371 request = kzalloc(sizeof(struct reg_regdb_search_request), GFP_KERNEL);
372 if (!request)
373 return;
374
375 memcpy(request->alpha2, alpha2, 2);
376
377 mutex_lock(&reg_regdb_search_mutex);
378 list_add_tail(&request->list, &reg_regdb_search_list);
379 mutex_unlock(&reg_regdb_search_mutex);
380
381 schedule_work(&reg_regdb_work);
382}
383#else
384static inline void reg_regdb_query(const char *alpha2) {}
385#endif /* CONFIG_CFG80211_INTERNAL_REGDB */
386
363/* 387/*
364 * This lets us keep regulatory code which is updated on a regulatory 388 * This lets us keep regulatory code which is updated on a regulatory
365 * basis in userspace. 389 * basis in userspace.
@@ -379,6 +403,9 @@ static int call_crda(const char *alpha2)
379 printk(KERN_INFO "cfg80211: Calling CRDA to update world " 403 printk(KERN_INFO "cfg80211: Calling CRDA to update world "
380 "regulatory domain\n"); 404 "regulatory domain\n");
381 405
406 /* query internal regulatory database (if it exists) */
407 reg_regdb_query(alpha2);
408
382 country_env[8] = alpha2[0]; 409 country_env[8] = alpha2[0];
383 country_env[9] = alpha2[1]; 410 country_env[9] = alpha2[1];
384 411
@@ -479,12 +506,212 @@ static bool freq_in_rule_band(const struct ieee80211_freq_range *freq_range,
479} 506}
480 507
481/* 508/*
509 * This is a work around for sanity checking ieee80211_channel_to_frequency()'s
510 * work. ieee80211_channel_to_frequency() can for example currently provide a
511 * 2 GHz channel when in fact a 5 GHz channel was desired. An example would be
512 * an AP providing channel 8 on a country IE triplet when it sent this on the
513 * 5 GHz band, that channel is designed to be channel 8 on 5 GHz, not a 2 GHz
514 * channel.
515 *
516 * This can be removed once ieee80211_channel_to_frequency() takes in a band.
517 */
518static bool chan_in_band(int chan, enum ieee80211_band band)
519{
520 int center_freq = ieee80211_channel_to_frequency(chan);
521
522 switch (band) {
523 case IEEE80211_BAND_2GHZ:
524 if (center_freq <= 2484)
525 return true;
526 return false;
527 case IEEE80211_BAND_5GHZ:
528 if (center_freq >= 5005)
529 return true;
530 return false;
531 default:
532 return false;
533 }
534}
535
536/*
537 * Some APs may send a country IE triplet for each channel they
538 * support and while this is completely overkill and silly we still
539 * need to support it. We avoid making a single rule for each channel
540 * though and to help us with this we use this helper to find the
541 * actual subband end channel. These type of country IE triplet
542 * scenerios are handled then, all yielding two regulaotry rules from
543 * parsing a country IE:
544 *
545 * [1]
546 * [2]
547 * [36]
548 * [40]
549 *
550 * [1]
551 * [2-4]
552 * [5-12]
553 * [36]
554 * [40-44]
555 *
556 * [1-4]
557 * [5-7]
558 * [36-44]
559 * [48-64]
560 *
561 * [36-36]
562 * [40-40]
563 * [44-44]
564 * [48-48]
565 * [52-52]
566 * [56-56]
567 * [60-60]
568 * [64-64]
569 * [100-100]
570 * [104-104]
571 * [108-108]
572 * [112-112]
573 * [116-116]
574 * [120-120]
575 * [124-124]
576 * [128-128]
577 * [132-132]
578 * [136-136]
579 * [140-140]
580 *
581 * Returns 0 if the IE has been found to be invalid in the middle
582 * somewhere.
583 */
584static int max_subband_chan(enum ieee80211_band band,
585 int orig_cur_chan,
586 int orig_end_channel,
587 s8 orig_max_power,
588 u8 **country_ie,
589 u8 *country_ie_len)
590{
591 u8 *triplets_start = *country_ie;
592 u8 len_at_triplet = *country_ie_len;
593 int end_subband_chan = orig_end_channel;
594
595 /*
596 * We'll deal with padding for the caller unless
597 * its not immediate and we don't process any channels
598 */
599 if (*country_ie_len == 1) {
600 *country_ie += 1;
601 *country_ie_len -= 1;
602 return orig_end_channel;
603 }
604
605 /* Move to the next triplet and then start search */
606 *country_ie += 3;
607 *country_ie_len -= 3;
608
609 if (!chan_in_band(orig_cur_chan, band))
610 return 0;
611
612 while (*country_ie_len >= 3) {
613 int end_channel = 0;
614 struct ieee80211_country_ie_triplet *triplet =
615 (struct ieee80211_country_ie_triplet *) *country_ie;
616 int cur_channel = 0, next_expected_chan;
617
618 /* means last triplet is completely unrelated to this one */
619 if (triplet->ext.reg_extension_id >=
620 IEEE80211_COUNTRY_EXTENSION_ID) {
621 *country_ie -= 3;
622 *country_ie_len += 3;
623 break;
624 }
625
626 if (triplet->chans.first_channel == 0) {
627 *country_ie += 1;
628 *country_ie_len -= 1;
629 if (*country_ie_len != 0)
630 return 0;
631 break;
632 }
633
634 if (triplet->chans.num_channels == 0)
635 return 0;
636
637 /* Monitonically increasing channel order */
638 if (triplet->chans.first_channel <= end_subband_chan)
639 return 0;
640
641 if (!chan_in_band(triplet->chans.first_channel, band))
642 return 0;
643
644 /* 2 GHz */
645 if (triplet->chans.first_channel <= 14) {
646 end_channel = triplet->chans.first_channel +
647 triplet->chans.num_channels - 1;
648 }
649 else {
650 end_channel = triplet->chans.first_channel +
651 (4 * (triplet->chans.num_channels - 1));
652 }
653
654 if (!chan_in_band(end_channel, band))
655 return 0;
656
657 if (orig_max_power != triplet->chans.max_power) {
658 *country_ie -= 3;
659 *country_ie_len += 3;
660 break;
661 }
662
663 cur_channel = triplet->chans.first_channel;
664
665 /* The key is finding the right next expected channel */
666 if (band == IEEE80211_BAND_2GHZ)
667 next_expected_chan = end_subband_chan + 1;
668 else
669 next_expected_chan = end_subband_chan + 4;
670
671 if (cur_channel != next_expected_chan) {
672 *country_ie -= 3;
673 *country_ie_len += 3;
674 break;
675 }
676
677 end_subband_chan = end_channel;
678
679 /* Move to the next one */
680 *country_ie += 3;
681 *country_ie_len -= 3;
682
683 /*
684 * Padding needs to be dealt with if we processed
685 * some channels.
686 */
687 if (*country_ie_len == 1) {
688 *country_ie += 1;
689 *country_ie_len -= 1;
690 break;
691 }
692
693 /* If seen, the IE is invalid */
694 if (*country_ie_len == 2)
695 return 0;
696 }
697
698 if (end_subband_chan == orig_end_channel) {
699 *country_ie = triplets_start;
700 *country_ie_len = len_at_triplet;
701 return orig_end_channel;
702 }
703
704 return end_subband_chan;
705}
706
707/*
482 * Converts a country IE to a regulatory domain. A regulatory domain 708 * Converts a country IE to a regulatory domain. A regulatory domain
483 * structure has a lot of information which the IE doesn't yet have, 709 * structure has a lot of information which the IE doesn't yet have,
484 * so for the other values we use upper max values as we will intersect 710 * so for the other values we use upper max values as we will intersect
485 * with our userspace regulatory agent to get lower bounds. 711 * with our userspace regulatory agent to get lower bounds.
486 */ 712 */
487static struct ieee80211_regdomain *country_ie_2_rd( 713static struct ieee80211_regdomain *country_ie_2_rd(
714 enum ieee80211_band band,
488 u8 *country_ie, 715 u8 *country_ie,
489 u8 country_ie_len, 716 u8 country_ie_len,
490 u32 *checksum) 717 u32 *checksum)
@@ -546,10 +773,29 @@ static struct ieee80211_regdomain *country_ie_2_rd(
546 continue; 773 continue;
547 } 774 }
548 775
776 /*
777 * APs can add padding to make length divisible
778 * by two, required by the spec.
779 */
780 if (triplet->chans.first_channel == 0) {
781 country_ie++;
782 country_ie_len--;
783 /* This is expected to be at the very end only */
784 if (country_ie_len != 0)
785 return NULL;
786 break;
787 }
788
789 if (triplet->chans.num_channels == 0)
790 return NULL;
791
792 if (!chan_in_band(triplet->chans.first_channel, band))
793 return NULL;
794
549 /* 2 GHz */ 795 /* 2 GHz */
550 if (triplet->chans.first_channel <= 14) 796 if (band == IEEE80211_BAND_2GHZ)
551 end_channel = triplet->chans.first_channel + 797 end_channel = triplet->chans.first_channel +
552 triplet->chans.num_channels; 798 triplet->chans.num_channels - 1;
553 else 799 else
554 /* 800 /*
555 * 5 GHz -- For example in country IEs if the first 801 * 5 GHz -- For example in country IEs if the first
@@ -564,6 +810,24 @@ static struct ieee80211_regdomain *country_ie_2_rd(
564 (4 * (triplet->chans.num_channels - 1)); 810 (4 * (triplet->chans.num_channels - 1));
565 811
566 cur_channel = triplet->chans.first_channel; 812 cur_channel = triplet->chans.first_channel;
813
814 /*
815 * Enhancement for APs that send a triplet for every channel
816 * or for whatever reason sends triplets with multiple channels
817 * separated when in fact they should be together.
818 */
819 end_channel = max_subband_chan(band,
820 cur_channel,
821 end_channel,
822 triplet->chans.max_power,
823 &country_ie,
824 &country_ie_len);
825 if (!end_channel)
826 return NULL;
827
828 if (!chan_in_band(end_channel, band))
829 return NULL;
830
567 cur_sub_max_channel = end_channel; 831 cur_sub_max_channel = end_channel;
568 832
569 /* Basic sanity check */ 833 /* Basic sanity check */
@@ -594,10 +858,13 @@ static struct ieee80211_regdomain *country_ie_2_rd(
594 858
595 last_sub_max_channel = cur_sub_max_channel; 859 last_sub_max_channel = cur_sub_max_channel;
596 860
597 country_ie += 3;
598 country_ie_len -= 3;
599 num_rules++; 861 num_rules++;
600 862
863 if (country_ie_len >= 3) {
864 country_ie += 3;
865 country_ie_len -= 3;
866 }
867
601 /* 868 /*
602 * Note: this is not a IEEE requirement but 869 * Note: this is not a IEEE requirement but
603 * simply a memory requirement 870 * simply a memory requirement
@@ -640,6 +907,12 @@ static struct ieee80211_regdomain *country_ie_2_rd(
640 continue; 907 continue;
641 } 908 }
642 909
910 if (triplet->chans.first_channel == 0) {
911 country_ie++;
912 country_ie_len--;
913 break;
914 }
915
643 reg_rule = &rd->reg_rules[i]; 916 reg_rule = &rd->reg_rules[i];
644 freq_range = &reg_rule->freq_range; 917 freq_range = &reg_rule->freq_range;
645 power_rule = &reg_rule->power_rule; 918 power_rule = &reg_rule->power_rule;
@@ -647,13 +920,20 @@ static struct ieee80211_regdomain *country_ie_2_rd(
647 reg_rule->flags = flags; 920 reg_rule->flags = flags;
648 921
649 /* 2 GHz */ 922 /* 2 GHz */
650 if (triplet->chans.first_channel <= 14) 923 if (band == IEEE80211_BAND_2GHZ)
651 end_channel = triplet->chans.first_channel + 924 end_channel = triplet->chans.first_channel +
652 triplet->chans.num_channels; 925 triplet->chans.num_channels -1;
653 else 926 else
654 end_channel = triplet->chans.first_channel + 927 end_channel = triplet->chans.first_channel +
655 (4 * (triplet->chans.num_channels - 1)); 928 (4 * (triplet->chans.num_channels - 1));
656 929
930 end_channel = max_subband_chan(band,
931 triplet->chans.first_channel,
932 end_channel,
933 triplet->chans.max_power,
934 &country_ie,
935 &country_ie_len);
936
657 /* 937 /*
658 * The +10 is since the regulatory domain expects 938 * The +10 is since the regulatory domain expects
659 * the actual band edge, not the center of freq for 939 * the actual band edge, not the center of freq for
@@ -674,12 +954,15 @@ static struct ieee80211_regdomain *country_ie_2_rd(
674 */ 954 */
675 freq_range->max_bandwidth_khz = MHZ_TO_KHZ(40); 955 freq_range->max_bandwidth_khz = MHZ_TO_KHZ(40);
676 power_rule->max_antenna_gain = DBI_TO_MBI(100); 956 power_rule->max_antenna_gain = DBI_TO_MBI(100);
677 power_rule->max_eirp = DBM_TO_MBM(100); 957 power_rule->max_eirp = DBM_TO_MBM(triplet->chans.max_power);
678 958
679 country_ie += 3;
680 country_ie_len -= 3;
681 i++; 959 i++;
682 960
961 if (country_ie_len >= 3) {
962 country_ie += 3;
963 country_ie_len -= 3;
964 }
965
683 BUG_ON(i > NL80211_MAX_SUPP_REG_RULES); 966 BUG_ON(i > NL80211_MAX_SUPP_REG_RULES);
684 } 967 }
685 968
@@ -975,25 +1258,21 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
975 if (r == -ERANGE && 1258 if (r == -ERANGE &&
976 last_request->initiator == 1259 last_request->initiator ==
977 NL80211_REGDOM_SET_BY_COUNTRY_IE) { 1260 NL80211_REGDOM_SET_BY_COUNTRY_IE) {
978#ifdef CONFIG_CFG80211_REG_DEBUG 1261 REG_DBG_PRINT("cfg80211: Leaving channel %d MHz "
979 printk(KERN_DEBUG "cfg80211: Leaving channel %d MHz "
980 "intact on %s - no rule found in band on " 1262 "intact on %s - no rule found in band on "
981 "Country IE\n", 1263 "Country IE\n",
982 chan->center_freq, wiphy_name(wiphy)); 1264 chan->center_freq, wiphy_name(wiphy));
983#endif
984 } else { 1265 } else {
985 /* 1266 /*
986 * In this case we know the country IE has at least one reg rule 1267 * In this case we know the country IE has at least one reg rule
987 * for the band so we respect its band definitions 1268 * for the band so we respect its band definitions
988 */ 1269 */
989#ifdef CONFIG_CFG80211_REG_DEBUG
990 if (last_request->initiator == 1270 if (last_request->initiator ==
991 NL80211_REGDOM_SET_BY_COUNTRY_IE) 1271 NL80211_REGDOM_SET_BY_COUNTRY_IE)
992 printk(KERN_DEBUG "cfg80211: Disabling " 1272 REG_DBG_PRINT("cfg80211: Disabling "
993 "channel %d MHz on %s due to " 1273 "channel %d MHz on %s due to "
994 "Country IE\n", 1274 "Country IE\n",
995 chan->center_freq, wiphy_name(wiphy)); 1275 chan->center_freq, wiphy_name(wiphy));
996#endif
997 flags |= IEEE80211_CHAN_DISABLED; 1276 flags |= IEEE80211_CHAN_DISABLED;
998 chan->flags = flags; 1277 chan->flags = flags;
999 } 1278 }
@@ -1008,7 +1287,7 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
1008 1287
1009 if (last_request->initiator == NL80211_REGDOM_SET_BY_DRIVER && 1288 if (last_request->initiator == NL80211_REGDOM_SET_BY_DRIVER &&
1010 request_wiphy && request_wiphy == wiphy && 1289 request_wiphy && request_wiphy == wiphy &&
1011 request_wiphy->strict_regulatory) { 1290 request_wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY) {
1012 /* 1291 /*
1013 * This gaurantees the driver's requested regulatory domain 1292 * This gaurantees the driver's requested regulatory domain
1014 * will always be used as a base for further regulatory 1293 * will always be used as a base for further regulatory
@@ -1051,13 +1330,13 @@ static bool ignore_reg_update(struct wiphy *wiphy,
1051 if (!last_request) 1330 if (!last_request)
1052 return true; 1331 return true;
1053 if (initiator == NL80211_REGDOM_SET_BY_CORE && 1332 if (initiator == NL80211_REGDOM_SET_BY_CORE &&
1054 wiphy->custom_regulatory) 1333 wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY)
1055 return true; 1334 return true;
1056 /* 1335 /*
1057 * wiphy->regd will be set once the device has its own 1336 * wiphy->regd will be set once the device has its own
1058 * desired regulatory domain set 1337 * desired regulatory domain set
1059 */ 1338 */
1060 if (wiphy->strict_regulatory && !wiphy->regd && 1339 if (wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY && !wiphy->regd &&
1061 !is_world_regdom(last_request->alpha2)) 1340 !is_world_regdom(last_request->alpha2))
1062 return true; 1341 return true;
1063 return false; 1342 return false;
@@ -1093,7 +1372,7 @@ static void handle_reg_beacon(struct wiphy *wiphy,
1093 1372
1094 chan->beacon_found = true; 1373 chan->beacon_found = true;
1095 1374
1096 if (wiphy->disable_beacon_hints) 1375 if (wiphy->flags & WIPHY_FLAG_DISABLE_BEACON_HINTS)
1097 return; 1376 return;
1098 1377
1099 chan_before.center_freq = chan->center_freq; 1378 chan_before.center_freq = chan->center_freq;
@@ -1164,7 +1443,7 @@ static bool reg_is_world_roaming(struct wiphy *wiphy)
1164 return true; 1443 return true;
1165 if (last_request && 1444 if (last_request &&
1166 last_request->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE && 1445 last_request->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE &&
1167 wiphy->custom_regulatory) 1446 wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY)
1168 return true; 1447 return true;
1169 return false; 1448 return false;
1170} 1449}
@@ -1367,30 +1646,6 @@ void wiphy_apply_custom_regulatory(struct wiphy *wiphy,
1367} 1646}
1368EXPORT_SYMBOL(wiphy_apply_custom_regulatory); 1647EXPORT_SYMBOL(wiphy_apply_custom_regulatory);
1369 1648
1370static int reg_copy_regd(const struct ieee80211_regdomain **dst_regd,
1371 const struct ieee80211_regdomain *src_regd)
1372{
1373 struct ieee80211_regdomain *regd;
1374 int size_of_regd = 0;
1375 unsigned int i;
1376
1377 size_of_regd = sizeof(struct ieee80211_regdomain) +
1378 ((src_regd->n_reg_rules + 1) * sizeof(struct ieee80211_reg_rule));
1379
1380 regd = kzalloc(size_of_regd, GFP_KERNEL);
1381 if (!regd)
1382 return -ENOMEM;
1383
1384 memcpy(regd, src_regd, sizeof(struct ieee80211_regdomain));
1385
1386 for (i = 0; i < src_regd->n_reg_rules; i++)
1387 memcpy(&regd->reg_rules[i], &src_regd->reg_rules[i],
1388 sizeof(struct ieee80211_reg_rule));
1389
1390 *dst_regd = regd;
1391 return 0;
1392}
1393
1394/* 1649/*
1395 * Return value which can be used by ignore_request() to indicate 1650 * Return value which can be used by ignore_request() to indicate
1396 * it has been determined we should intersect two regulatory domains 1651 * it has been determined we should intersect two regulatory domains
@@ -1412,7 +1667,7 @@ static int ignore_request(struct wiphy *wiphy,
1412 1667
1413 switch (pending_request->initiator) { 1668 switch (pending_request->initiator) {
1414 case NL80211_REGDOM_SET_BY_CORE: 1669 case NL80211_REGDOM_SET_BY_CORE:
1415 return -EINVAL; 1670 return 0;
1416 case NL80211_REGDOM_SET_BY_COUNTRY_IE: 1671 case NL80211_REGDOM_SET_BY_COUNTRY_IE:
1417 1672
1418 last_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx); 1673 last_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx);
@@ -1443,8 +1698,6 @@ static int ignore_request(struct wiphy *wiphy,
1443 return REG_INTERSECT; 1698 return REG_INTERSECT;
1444 case NL80211_REGDOM_SET_BY_DRIVER: 1699 case NL80211_REGDOM_SET_BY_DRIVER:
1445 if (last_request->initiator == NL80211_REGDOM_SET_BY_CORE) { 1700 if (last_request->initiator == NL80211_REGDOM_SET_BY_CORE) {
1446 if (is_old_static_regdom(cfg80211_regdomain))
1447 return 0;
1448 if (regdom_changes(pending_request->alpha2)) 1701 if (regdom_changes(pending_request->alpha2))
1449 return 0; 1702 return 0;
1450 return -EALREADY; 1703 return -EALREADY;
@@ -1481,8 +1734,7 @@ static int ignore_request(struct wiphy *wiphy,
1481 return -EAGAIN; 1734 return -EAGAIN;
1482 } 1735 }
1483 1736
1484 if (!is_old_static_regdom(cfg80211_regdomain) && 1737 if (!regdom_changes(pending_request->alpha2))
1485 !regdom_changes(pending_request->alpha2))
1486 return -EALREADY; 1738 return -EALREADY;
1487 1739
1488 return 0; 1740 return 0;
@@ -1554,6 +1806,11 @@ new_request:
1554 1806
1555 pending_request = NULL; 1807 pending_request = NULL;
1556 1808
1809 if (last_request->initiator == NL80211_REGDOM_SET_BY_USER) {
1810 user_alpha2[0] = last_request->alpha2[0];
1811 user_alpha2[1] = last_request->alpha2[1];
1812 }
1813
1557 /* When r == REG_INTERSECT we do need to call CRDA */ 1814 /* When r == REG_INTERSECT we do need to call CRDA */
1558 if (r < 0) { 1815 if (r < 0) {
1559 /* 1816 /*
@@ -1591,7 +1848,8 @@ static void reg_process_hint(struct regulatory_request *reg_request)
1591 1848
1592 r = __regulatory_hint(wiphy, reg_request); 1849 r = __regulatory_hint(wiphy, reg_request);
1593 /* This is required so that the orig_* parameters are saved */ 1850 /* This is required so that the orig_* parameters are saved */
1594 if (r == -EALREADY && wiphy && wiphy->strict_regulatory) 1851 if (r == -EALREADY && wiphy &&
1852 wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY)
1595 wiphy_update_regulatory(wiphy, reg_request->initiator); 1853 wiphy_update_regulatory(wiphy, reg_request->initiator);
1596out: 1854out:
1597 mutex_unlock(&reg_mutex); 1855 mutex_unlock(&reg_mutex);
@@ -1672,12 +1930,16 @@ static void queue_regulatory_request(struct regulatory_request *request)
1672 schedule_work(&reg_work); 1930 schedule_work(&reg_work);
1673} 1931}
1674 1932
1675/* Core regulatory hint -- happens once during cfg80211_init() */ 1933/*
1934 * Core regulatory hint -- happens during cfg80211_init()
1935 * and when we restore regulatory settings.
1936 */
1676static int regulatory_hint_core(const char *alpha2) 1937static int regulatory_hint_core(const char *alpha2)
1677{ 1938{
1678 struct regulatory_request *request; 1939 struct regulatory_request *request;
1679 1940
1680 BUG_ON(last_request); 1941 kfree(last_request);
1942 last_request = NULL;
1681 1943
1682 request = kzalloc(sizeof(struct regulatory_request), 1944 request = kzalloc(sizeof(struct regulatory_request),
1683 GFP_KERNEL); 1945 GFP_KERNEL);
@@ -1688,14 +1950,12 @@ static int regulatory_hint_core(const char *alpha2)
1688 request->alpha2[1] = alpha2[1]; 1950 request->alpha2[1] = alpha2[1];
1689 request->initiator = NL80211_REGDOM_SET_BY_CORE; 1951 request->initiator = NL80211_REGDOM_SET_BY_CORE;
1690 1952
1691 queue_regulatory_request(request);
1692
1693 /* 1953 /*
1694 * This ensures last_request is populated once modules 1954 * This ensures last_request is populated once modules
1695 * come swinging in and calling regulatory hints and 1955 * come swinging in and calling regulatory hints and
1696 * wiphy_apply_custom_regulatory(). 1956 * wiphy_apply_custom_regulatory().
1697 */ 1957 */
1698 flush_scheduled_work(); 1958 reg_process_hint(request);
1699 1959
1700 return 0; 1960 return 0;
1701} 1961}
@@ -1714,7 +1974,7 @@ int regulatory_hint_user(const char *alpha2)
1714 request->wiphy_idx = WIPHY_IDX_STALE; 1974 request->wiphy_idx = WIPHY_IDX_STALE;
1715 request->alpha2[0] = alpha2[0]; 1975 request->alpha2[0] = alpha2[0];
1716 request->alpha2[1] = alpha2[1]; 1976 request->alpha2[1] = alpha2[1];
1717 request->initiator = NL80211_REGDOM_SET_BY_USER, 1977 request->initiator = NL80211_REGDOM_SET_BY_USER;
1718 1978
1719 queue_regulatory_request(request); 1979 queue_regulatory_request(request);
1720 1980
@@ -1782,8 +2042,9 @@ static bool reg_same_country_ie_hint(struct wiphy *wiphy,
1782 * therefore cannot iterate over the rdev list here. 2042 * therefore cannot iterate over the rdev list here.
1783 */ 2043 */
1784void regulatory_hint_11d(struct wiphy *wiphy, 2044void regulatory_hint_11d(struct wiphy *wiphy,
1785 u8 *country_ie, 2045 enum ieee80211_band band,
1786 u8 country_ie_len) 2046 u8 *country_ie,
2047 u8 country_ie_len)
1787{ 2048{
1788 struct ieee80211_regdomain *rd = NULL; 2049 struct ieee80211_regdomain *rd = NULL;
1789 char alpha2[2]; 2050 char alpha2[2];
@@ -1829,9 +2090,11 @@ void regulatory_hint_11d(struct wiphy *wiphy,
1829 wiphy_idx_valid(last_request->wiphy_idx))) 2090 wiphy_idx_valid(last_request->wiphy_idx)))
1830 goto out; 2091 goto out;
1831 2092
1832 rd = country_ie_2_rd(country_ie, country_ie_len, &checksum); 2093 rd = country_ie_2_rd(band, country_ie, country_ie_len, &checksum);
1833 if (!rd) 2094 if (!rd) {
2095 REG_DBG_PRINT("cfg80211: Ignoring bogus country IE\n");
1834 goto out; 2096 goto out;
2097 }
1835 2098
1836 /* 2099 /*
1837 * This will not happen right now but we leave it here for the 2100 * This will not happen right now but we leave it here for the
@@ -1874,6 +2137,123 @@ out:
1874 mutex_unlock(&reg_mutex); 2137 mutex_unlock(&reg_mutex);
1875} 2138}
1876 2139
2140static void restore_alpha2(char *alpha2, bool reset_user)
2141{
2142 /* indicates there is no alpha2 to consider for restoration */
2143 alpha2[0] = '9';
2144 alpha2[1] = '7';
2145
2146 /* The user setting has precedence over the module parameter */
2147 if (is_user_regdom_saved()) {
2148 /* Unless we're asked to ignore it and reset it */
2149 if (reset_user) {
2150 REG_DBG_PRINT("cfg80211: Restoring regulatory settings "
2151 "including user preference\n");
2152 user_alpha2[0] = '9';
2153 user_alpha2[1] = '7';
2154
2155 /*
2156 * If we're ignoring user settings, we still need to
2157 * check the module parameter to ensure we put things
2158 * back as they were for a full restore.
2159 */
2160 if (!is_world_regdom(ieee80211_regdom)) {
2161 REG_DBG_PRINT("cfg80211: Keeping preference on "
2162 "module parameter ieee80211_regdom: %c%c\n",
2163 ieee80211_regdom[0],
2164 ieee80211_regdom[1]);
2165 alpha2[0] = ieee80211_regdom[0];
2166 alpha2[1] = ieee80211_regdom[1];
2167 }
2168 } else {
2169 REG_DBG_PRINT("cfg80211: Restoring regulatory settings "
2170 "while preserving user preference for: %c%c\n",
2171 user_alpha2[0],
2172 user_alpha2[1]);
2173 alpha2[0] = user_alpha2[0];
2174 alpha2[1] = user_alpha2[1];
2175 }
2176 } else if (!is_world_regdom(ieee80211_regdom)) {
2177 REG_DBG_PRINT("cfg80211: Keeping preference on "
2178 "module parameter ieee80211_regdom: %c%c\n",
2179 ieee80211_regdom[0],
2180 ieee80211_regdom[1]);
2181 alpha2[0] = ieee80211_regdom[0];
2182 alpha2[1] = ieee80211_regdom[1];
2183 } else
2184 REG_DBG_PRINT("cfg80211: Restoring regulatory settings\n");
2185}
2186
2187/*
2188 * Restoring regulatory settings involves ingoring any
2189 * possibly stale country IE information and user regulatory
2190 * settings if so desired, this includes any beacon hints
2191 * learned as we could have traveled outside to another country
2192 * after disconnection. To restore regulatory settings we do
2193 * exactly what we did at bootup:
2194 *
2195 * - send a core regulatory hint
2196 * - send a user regulatory hint if applicable
2197 *
2198 * Device drivers that send a regulatory hint for a specific country
2199 * keep their own regulatory domain on wiphy->regd so that does does
2200 * not need to be remembered.
2201 */
2202static void restore_regulatory_settings(bool reset_user)
2203{
2204 char alpha2[2];
2205 struct reg_beacon *reg_beacon, *btmp;
2206
2207 mutex_lock(&cfg80211_mutex);
2208 mutex_lock(&reg_mutex);
2209
2210 reset_regdomains();
2211 restore_alpha2(alpha2, reset_user);
2212
2213 /* Clear beacon hints */
2214 spin_lock_bh(&reg_pending_beacons_lock);
2215 if (!list_empty(&reg_pending_beacons)) {
2216 list_for_each_entry_safe(reg_beacon, btmp,
2217 &reg_pending_beacons, list) {
2218 list_del(&reg_beacon->list);
2219 kfree(reg_beacon);
2220 }
2221 }
2222 spin_unlock_bh(&reg_pending_beacons_lock);
2223
2224 if (!list_empty(&reg_beacon_list)) {
2225 list_for_each_entry_safe(reg_beacon, btmp,
2226 &reg_beacon_list, list) {
2227 list_del(&reg_beacon->list);
2228 kfree(reg_beacon);
2229 }
2230 }
2231
2232 /* First restore to the basic regulatory settings */
2233 cfg80211_regdomain = cfg80211_world_regdom;
2234
2235 mutex_unlock(&reg_mutex);
2236 mutex_unlock(&cfg80211_mutex);
2237
2238 regulatory_hint_core(cfg80211_regdomain->alpha2);
2239
2240 /*
2241 * This restores the ieee80211_regdom module parameter
2242 * preference or the last user requested regulatory
2243 * settings, user regulatory settings takes precedence.
2244 */
2245 if (is_an_alpha2(alpha2))
2246 regulatory_hint_user(user_alpha2);
2247}
2248
2249
2250void regulatory_hint_disconnect(void)
2251{
2252 REG_DBG_PRINT("cfg80211: All devices are disconnected, going to "
2253 "restore regulatory settings\n");
2254 restore_regulatory_settings(false);
2255}
2256
1877static bool freq_is_chan_12_13_14(u16 freq) 2257static bool freq_is_chan_12_13_14(u16 freq)
1878{ 2258{
1879 if (freq == ieee80211_channel_to_frequency(12) || 2259 if (freq == ieee80211_channel_to_frequency(12) ||
@@ -1899,13 +2279,12 @@ int regulatory_hint_found_beacon(struct wiphy *wiphy,
1899 if (!reg_beacon) 2279 if (!reg_beacon)
1900 return -ENOMEM; 2280 return -ENOMEM;
1901 2281
1902#ifdef CONFIG_CFG80211_REG_DEBUG 2282 REG_DBG_PRINT("cfg80211: Found new beacon on "
1903 printk(KERN_DEBUG "cfg80211: Found new beacon on " 2283 "frequency: %d MHz (Ch %d) on %s\n",
1904 "frequency: %d MHz (Ch %d) on %s\n", 2284 beacon_chan->center_freq,
1905 beacon_chan->center_freq, 2285 ieee80211_frequency_to_channel(beacon_chan->center_freq),
1906 ieee80211_frequency_to_channel(beacon_chan->center_freq), 2286 wiphy_name(wiphy));
1907 wiphy_name(wiphy)); 2287
1908#endif
1909 memcpy(&reg_beacon->chan, beacon_chan, 2288 memcpy(&reg_beacon->chan, beacon_chan,
1910 sizeof(struct ieee80211_channel)); 2289 sizeof(struct ieee80211_channel));
1911 2290
@@ -1930,7 +2309,7 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd)
1930 const struct ieee80211_freq_range *freq_range = NULL; 2309 const struct ieee80211_freq_range *freq_range = NULL;
1931 const struct ieee80211_power_rule *power_rule = NULL; 2310 const struct ieee80211_power_rule *power_rule = NULL;
1932 2311
1933 printk(KERN_INFO "\t(start_freq - end_freq @ bandwidth), " 2312 printk(KERN_INFO " (start_freq - end_freq @ bandwidth), "
1934 "(max_antenna_gain, max_eirp)\n"); 2313 "(max_antenna_gain, max_eirp)\n");
1935 2314
1936 for (i = 0; i < rd->n_reg_rules; i++) { 2315 for (i = 0; i < rd->n_reg_rules; i++) {
@@ -1943,7 +2322,7 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd)
1943 * in certain regions 2322 * in certain regions
1944 */ 2323 */
1945 if (power_rule->max_antenna_gain) 2324 if (power_rule->max_antenna_gain)
1946 printk(KERN_INFO "\t(%d KHz - %d KHz @ %d KHz), " 2325 printk(KERN_INFO " (%d KHz - %d KHz @ %d KHz), "
1947 "(%d mBi, %d mBm)\n", 2326 "(%d mBi, %d mBm)\n",
1948 freq_range->start_freq_khz, 2327 freq_range->start_freq_khz,
1949 freq_range->end_freq_khz, 2328 freq_range->end_freq_khz,
@@ -1951,7 +2330,7 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd)
1951 power_rule->max_antenna_gain, 2330 power_rule->max_antenna_gain,
1952 power_rule->max_eirp); 2331 power_rule->max_eirp);
1953 else 2332 else
1954 printk(KERN_INFO "\t(%d KHz - %d KHz @ %d KHz), " 2333 printk(KERN_INFO " (%d KHz - %d KHz @ %d KHz), "
1955 "(N/A, %d mBm)\n", 2334 "(N/A, %d mBm)\n",
1956 freq_range->start_freq_khz, 2335 freq_range->start_freq_khz,
1957 freq_range->end_freq_khz, 2336 freq_range->end_freq_khz,
@@ -2063,8 +2442,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
2063 * If someone else asked us to change the rd lets only bother 2442 * If someone else asked us to change the rd lets only bother
2064 * checking if the alpha2 changes if CRDA was already called 2443 * checking if the alpha2 changes if CRDA was already called
2065 */ 2444 */
2066 if (!is_old_static_regdom(cfg80211_regdomain) && 2445 if (!regdom_changes(rd->alpha2))
2067 !regdom_changes(rd->alpha2))
2068 return -EINVAL; 2446 return -EINVAL;
2069 } 2447 }
2070 2448
@@ -2263,15 +2641,11 @@ int regulatory_init(void)
2263 spin_lock_init(&reg_requests_lock); 2641 spin_lock_init(&reg_requests_lock);
2264 spin_lock_init(&reg_pending_beacons_lock); 2642 spin_lock_init(&reg_pending_beacons_lock);
2265 2643
2266#ifdef CONFIG_WIRELESS_OLD_REGULATORY
2267 cfg80211_regdomain = static_regdom(ieee80211_regdom);
2268
2269 printk(KERN_INFO "cfg80211: Using static regulatory domain info\n");
2270 print_regdomain_info(cfg80211_regdomain);
2271#else
2272 cfg80211_regdomain = cfg80211_world_regdom; 2644 cfg80211_regdomain = cfg80211_world_regdom;
2273 2645
2274#endif 2646 user_alpha2[0] = '9';
2647 user_alpha2[1] = '7';
2648
2275 /* We always try to get an update for the static regdomain */ 2649 /* We always try to get an update for the static regdomain */
2276 err = regulatory_hint_core(cfg80211_regdomain->alpha2); 2650 err = regulatory_hint_core(cfg80211_regdomain->alpha2);
2277 if (err) { 2651 if (err) {