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.c806
1 files changed, 278 insertions, 528 deletions
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 7a0754c92df4..f180db0de66c 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
@@ -56,20 +67,12 @@ static struct platform_device *reg_pdev;
56const struct ieee80211_regdomain *cfg80211_regdomain; 67const struct ieee80211_regdomain *cfg80211_regdomain;
57 68
58/* 69/*
59 * We use this as a place for the rd structure built from the
60 * last parsed country IE to rest until CRDA gets back to us with
61 * what it thinks should apply for the same country
62 */
63static const struct ieee80211_regdomain *country_ie_regdomain;
64
65/*
66 * Protects static reg.c components: 70 * Protects static reg.c components:
67 * - cfg80211_world_regdom 71 * - cfg80211_world_regdom
68 * - cfg80211_regdom 72 * - cfg80211_regdom
69 * - country_ie_regdomain
70 * - last_request 73 * - last_request
71 */ 74 */
72DEFINE_MUTEX(reg_mutex); 75static DEFINE_MUTEX(reg_mutex);
73#define assert_reg_lock() WARN_ON(!mutex_is_locked(&reg_mutex)) 76#define assert_reg_lock() WARN_ON(!mutex_is_locked(&reg_mutex))
74 77
75/* Used to queue up regulatory hints */ 78/* Used to queue up regulatory hints */
@@ -124,82 +127,11 @@ static const struct ieee80211_regdomain *cfg80211_world_regdom =
124 &world_regdom; 127 &world_regdom;
125 128
126static char *ieee80211_regdom = "00"; 129static char *ieee80211_regdom = "00";
130static char user_alpha2[2];
127 131
128module_param(ieee80211_regdom, charp, 0444); 132module_param(ieee80211_regdom, charp, 0444);
129MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code"); 133MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code");
130 134
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..48 */
145 REG_RULE(5180-10, 5240+10, 40, 6, 17, 0),
146 /* IEEE 802.11a, channels 48..64 */
147 REG_RULE(5260-10, 5320+10, 40, 6, 20, NL80211_RRF_DFS),
148 /* IEEE 802.11a, channels 100..124 */
149 REG_RULE(5500-10, 5590+10, 40, 6, 20, NL80211_RRF_DFS),
150 /* IEEE 802.11a, channels 132..144 */
151 REG_RULE(5660-10, 5700+10, 40, 6, 20, NL80211_RRF_DFS),
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 = 6,
159 .alpha2 = "JP",
160 .reg_rules = {
161 /* IEEE 802.11b/g, channels 1..11 */
162 REG_RULE(2412-10, 2462+10, 40, 6, 20, 0),
163 /* IEEE 802.11b/g, channels 12..13 */
164 REG_RULE(2467-10, 2472+10, 20, 6, 20, 0),
165 /* IEEE 802.11b/g, channel 14 */
166 REG_RULE(2484-10, 2484+10, 20, 6, 20, NL80211_RRF_NO_OFDM),
167 /* IEEE 802.11a, channels 36..48 */
168 REG_RULE(5180-10, 5240+10, 40, 6, 20, 0),
169 /* IEEE 802.11a, channels 52..64 */
170 REG_RULE(5260-10, 5320+10, 40, 6, 20, NL80211_RRF_DFS),
171 /* IEEE 802.11a, channels 100..144 */
172 REG_RULE(5500-10, 5700+10, 40, 6, 23, NL80211_RRF_DFS),
173 }
174};
175
176static const struct ieee80211_regdomain *static_regdom(char *alpha2)
177{
178 if (alpha2[0] == 'U' && alpha2[1] == 'S')
179 return &us_regdom;
180 if (alpha2[0] == 'J' && alpha2[1] == 'P')
181 return &jp_regdom;
182 /* Use world roaming rules for "EU", since it was a pseudo
183 domain anyway... */
184 if (alpha2[0] == 'E' && alpha2[1] == 'U')
185 return &world_regdom;
186 /* Default, world roaming rules */
187 return &world_regdom;
188}
189
190static bool is_old_static_regdom(const struct ieee80211_regdomain *rd)
191{
192 if (rd == &us_regdom || rd == &jp_regdom || rd == &world_regdom)
193 return true;
194 return false;
195}
196#else
197static inline bool is_old_static_regdom(const struct ieee80211_regdomain *rd)
198{
199 return false;
200}
201#endif
202
203static void reset_regdomains(void) 135static void reset_regdomains(void)
204{ 136{
205 /* avoid freeing static information or freeing something twice */ 137 /* avoid freeing static information or freeing something twice */
@@ -209,8 +141,6 @@ static void reset_regdomains(void)
209 cfg80211_world_regdom = NULL; 141 cfg80211_world_regdom = NULL;
210 if (cfg80211_regdomain == &world_regdom) 142 if (cfg80211_regdomain == &world_regdom)
211 cfg80211_regdomain = NULL; 143 cfg80211_regdomain = NULL;
212 if (is_old_static_regdom(cfg80211_regdomain))
213 cfg80211_regdomain = NULL;
214 144
215 kfree(cfg80211_regdomain); 145 kfree(cfg80211_regdomain);
216 kfree(cfg80211_world_regdom); 146 kfree(cfg80211_world_regdom);
@@ -316,24 +246,116 @@ static bool regdom_changes(const char *alpha2)
316 return true; 246 return true;
317} 247}
318 248
319/** 249/*
320 * country_ie_integrity_changes - tells us if the country IE has changed 250 * The NL80211_REGDOM_SET_BY_USER regdom alpha2 is cached, this lets
321 * @checksum: checksum of country IE of fields we are interested in 251 * you know if a valid regulatory hint with NL80211_REGDOM_SET_BY_USER
322 * 252 * has ever been issued.
323 * If the country IE has not changed you can ignore it safely. This is
324 * useful to determine if two devices are seeing two different country IEs
325 * even on the same alpha2. Note that this will return false if no IE has
326 * been set on the wireless core yet.
327 */ 253 */
328static bool country_ie_integrity_changes(u32 checksum) 254static bool is_user_regdom_saved(void)
329{ 255{
330 /* If no IE has been set then the checksum doesn't change */ 256 if (user_alpha2[0] == '9' && user_alpha2[1] == '7')
331 if (unlikely(!last_request->country_ie_checksum))
332 return false; 257 return false;
333 if (unlikely(last_request->country_ie_checksum != checksum)) 258
334 return true; 259 /* This would indicate a mistake on the design */
335 return false; 260 if (WARN((!is_world_regdom(user_alpha2) &&
261 !is_an_alpha2(user_alpha2)),
262 "Unexpected user alpha2: %c%c\n",
263 user_alpha2[0],
264 user_alpha2[1]))
265 return false;
266
267 return true;
268}
269
270static int reg_copy_regd(const struct ieee80211_regdomain **dst_regd,
271 const struct ieee80211_regdomain *src_regd)
272{
273 struct ieee80211_regdomain *regd;
274 int size_of_regd = 0;
275 unsigned int i;
276
277 size_of_regd = sizeof(struct ieee80211_regdomain) +
278 ((src_regd->n_reg_rules + 1) * sizeof(struct ieee80211_reg_rule));
279
280 regd = kzalloc(size_of_regd, GFP_KERNEL);
281 if (!regd)
282 return -ENOMEM;
283
284 memcpy(regd, src_regd, sizeof(struct ieee80211_regdomain));
285
286 for (i = 0; i < src_regd->n_reg_rules; i++)
287 memcpy(&regd->reg_rules[i], &src_regd->reg_rules[i],
288 sizeof(struct ieee80211_reg_rule));
289
290 *dst_regd = regd;
291 return 0;
292}
293
294#ifdef CONFIG_CFG80211_INTERNAL_REGDB
295struct reg_regdb_search_request {
296 char alpha2[2];
297 struct list_head list;
298};
299
300static LIST_HEAD(reg_regdb_search_list);
301static DEFINE_MUTEX(reg_regdb_search_mutex);
302
303static void reg_regdb_search(struct work_struct *work)
304{
305 struct reg_regdb_search_request *request;
306 const struct ieee80211_regdomain *curdom, *regdom;
307 int i, r;
308
309 mutex_lock(&reg_regdb_search_mutex);
310 while (!list_empty(&reg_regdb_search_list)) {
311 request = list_first_entry(&reg_regdb_search_list,
312 struct reg_regdb_search_request,
313 list);
314 list_del(&request->list);
315
316 for (i=0; i<reg_regdb_size; i++) {
317 curdom = reg_regdb[i];
318
319 if (!memcmp(request->alpha2, curdom->alpha2, 2)) {
320 r = reg_copy_regd(&regdom, curdom);
321 if (r)
322 break;
323 mutex_lock(&cfg80211_mutex);
324 set_regdom(regdom);
325 mutex_unlock(&cfg80211_mutex);
326 break;
327 }
328 }
329
330 kfree(request);
331 }
332 mutex_unlock(&reg_regdb_search_mutex);
333}
334
335static DECLARE_WORK(reg_regdb_work, reg_regdb_search);
336
337static void reg_regdb_query(const char *alpha2)
338{
339 struct reg_regdb_search_request *request;
340
341 if (!alpha2)
342 return;
343
344 request = kzalloc(sizeof(struct reg_regdb_search_request), GFP_KERNEL);
345 if (!request)
346 return;
347
348 memcpy(request->alpha2, alpha2, 2);
349
350 mutex_lock(&reg_regdb_search_mutex);
351 list_add_tail(&request->list, &reg_regdb_search_list);
352 mutex_unlock(&reg_regdb_search_mutex);
353
354 schedule_work(&reg_regdb_work);
336} 355}
356#else
357static inline void reg_regdb_query(const char *alpha2) {}
358#endif /* CONFIG_CFG80211_INTERNAL_REGDB */
337 359
338/* 360/*
339 * This lets us keep regulatory code which is updated on a regulatory 361 * This lets us keep regulatory code which is updated on a regulatory
@@ -354,6 +376,9 @@ static int call_crda(const char *alpha2)
354 printk(KERN_INFO "cfg80211: Calling CRDA to update world " 376 printk(KERN_INFO "cfg80211: Calling CRDA to update world "
355 "regulatory domain\n"); 377 "regulatory domain\n");
356 378
379 /* query internal regulatory database (if it exists) */
380 reg_regdb_query(alpha2);
381
357 country_env[8] = alpha2[0]; 382 country_env[8] = alpha2[0];
358 country_env[9] = alpha2[1]; 383 country_env[9] = alpha2[1];
359 384
@@ -454,215 +479,6 @@ static bool freq_in_rule_band(const struct ieee80211_freq_range *freq_range,
454} 479}
455 480
456/* 481/*
457 * Converts a country IE to a regulatory domain. A regulatory domain
458 * structure has a lot of information which the IE doesn't yet have,
459 * so for the other values we use upper max values as we will intersect
460 * with our userspace regulatory agent to get lower bounds.
461 */
462static struct ieee80211_regdomain *country_ie_2_rd(
463 u8 *country_ie,
464 u8 country_ie_len,
465 u32 *checksum)
466{
467 struct ieee80211_regdomain *rd = NULL;
468 unsigned int i = 0;
469 char alpha2[2];
470 u32 flags = 0;
471 u32 num_rules = 0, size_of_regd = 0;
472 u8 *triplets_start = NULL;
473 u8 len_at_triplet = 0;
474 /* the last channel we have registered in a subband (triplet) */
475 int last_sub_max_channel = 0;
476
477 *checksum = 0xDEADBEEF;
478
479 /* Country IE requirements */
480 BUG_ON(country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN ||
481 country_ie_len & 0x01);
482
483 alpha2[0] = country_ie[0];
484 alpha2[1] = country_ie[1];
485
486 /*
487 * Third octet can be:
488 * 'I' - Indoor
489 * 'O' - Outdoor
490 *
491 * anything else we assume is no restrictions
492 */
493 if (country_ie[2] == 'I')
494 flags = NL80211_RRF_NO_OUTDOOR;
495 else if (country_ie[2] == 'O')
496 flags = NL80211_RRF_NO_INDOOR;
497
498 country_ie += 3;
499 country_ie_len -= 3;
500
501 triplets_start = country_ie;
502 len_at_triplet = country_ie_len;
503
504 *checksum ^= ((flags ^ alpha2[0] ^ alpha2[1]) << 8);
505
506 /*
507 * We need to build a reg rule for each triplet, but first we must
508 * calculate the number of reg rules we will need. We will need one
509 * for each channel subband
510 */
511 while (country_ie_len >= 3) {
512 int end_channel = 0;
513 struct ieee80211_country_ie_triplet *triplet =
514 (struct ieee80211_country_ie_triplet *) country_ie;
515 int cur_sub_max_channel = 0, cur_channel = 0;
516
517 if (triplet->ext.reg_extension_id >=
518 IEEE80211_COUNTRY_EXTENSION_ID) {
519 country_ie += 3;
520 country_ie_len -= 3;
521 continue;
522 }
523
524 /* 2 GHz */
525 if (triplet->chans.first_channel <= 14)
526 end_channel = triplet->chans.first_channel +
527 triplet->chans.num_channels;
528 else
529 /*
530 * 5 GHz -- For example in country IEs if the first
531 * channel given is 36 and the number of channels is 4
532 * then the individual channel numbers defined for the
533 * 5 GHz PHY by these parameters are: 36, 40, 44, and 48
534 * and not 36, 37, 38, 39.
535 *
536 * See: http://tinyurl.com/11d-clarification
537 */
538 end_channel = triplet->chans.first_channel +
539 (4 * (triplet->chans.num_channels - 1));
540
541 cur_channel = triplet->chans.first_channel;
542 cur_sub_max_channel = end_channel;
543
544 /* Basic sanity check */
545 if (cur_sub_max_channel < cur_channel)
546 return NULL;
547
548 /*
549 * Do not allow overlapping channels. Also channels
550 * passed in each subband must be monotonically
551 * increasing
552 */
553 if (last_sub_max_channel) {
554 if (cur_channel <= last_sub_max_channel)
555 return NULL;
556 if (cur_sub_max_channel <= last_sub_max_channel)
557 return NULL;
558 }
559
560 /*
561 * When dot11RegulatoryClassesRequired is supported
562 * we can throw ext triplets as part of this soup,
563 * for now we don't care when those change as we
564 * don't support them
565 */
566 *checksum ^= ((cur_channel ^ cur_sub_max_channel) << 8) |
567 ((cur_sub_max_channel ^ cur_sub_max_channel) << 16) |
568 ((triplet->chans.max_power ^ cur_sub_max_channel) << 24);
569
570 last_sub_max_channel = cur_sub_max_channel;
571
572 country_ie += 3;
573 country_ie_len -= 3;
574 num_rules++;
575
576 /*
577 * Note: this is not a IEEE requirement but
578 * simply a memory requirement
579 */
580 if (num_rules > NL80211_MAX_SUPP_REG_RULES)
581 return NULL;
582 }
583
584 country_ie = triplets_start;
585 country_ie_len = len_at_triplet;
586
587 size_of_regd = sizeof(struct ieee80211_regdomain) +
588 (num_rules * sizeof(struct ieee80211_reg_rule));
589
590 rd = kzalloc(size_of_regd, GFP_KERNEL);
591 if (!rd)
592 return NULL;
593
594 rd->n_reg_rules = num_rules;
595 rd->alpha2[0] = alpha2[0];
596 rd->alpha2[1] = alpha2[1];
597
598 /* This time around we fill in the rd */
599 while (country_ie_len >= 3) {
600 int end_channel = 0;
601 struct ieee80211_country_ie_triplet *triplet =
602 (struct ieee80211_country_ie_triplet *) country_ie;
603 struct ieee80211_reg_rule *reg_rule = NULL;
604 struct ieee80211_freq_range *freq_range = NULL;
605 struct ieee80211_power_rule *power_rule = NULL;
606
607 /*
608 * Must parse if dot11RegulatoryClassesRequired is true,
609 * we don't support this yet
610 */
611 if (triplet->ext.reg_extension_id >=
612 IEEE80211_COUNTRY_EXTENSION_ID) {
613 country_ie += 3;
614 country_ie_len -= 3;
615 continue;
616 }
617
618 reg_rule = &rd->reg_rules[i];
619 freq_range = &reg_rule->freq_range;
620 power_rule = &reg_rule->power_rule;
621
622 reg_rule->flags = flags;
623
624 /* 2 GHz */
625 if (triplet->chans.first_channel <= 14)
626 end_channel = triplet->chans.first_channel +
627 triplet->chans.num_channels;
628 else
629 end_channel = triplet->chans.first_channel +
630 (4 * (triplet->chans.num_channels - 1));
631
632 /*
633 * The +10 is since the regulatory domain expects
634 * the actual band edge, not the center of freq for
635 * its start and end freqs, assuming 20 MHz bandwidth on
636 * the channels passed
637 */
638 freq_range->start_freq_khz =
639 MHZ_TO_KHZ(ieee80211_channel_to_frequency(
640 triplet->chans.first_channel) - 10);
641 freq_range->end_freq_khz =
642 MHZ_TO_KHZ(ieee80211_channel_to_frequency(
643 end_channel) + 10);
644
645 /*
646 * These are large arbitrary values we use to intersect later.
647 * Increment this if we ever support >= 40 MHz channels
648 * in IEEE 802.11
649 */
650 freq_range->max_bandwidth_khz = MHZ_TO_KHZ(40);
651 power_rule->max_antenna_gain = DBI_TO_MBI(100);
652 power_rule->max_eirp = DBM_TO_MBM(100);
653
654 country_ie += 3;
655 country_ie_len -= 3;
656 i++;
657
658 BUG_ON(i > NL80211_MAX_SUPP_REG_RULES);
659 }
660
661 return rd;
662}
663
664
665/*
666 * Helper for regdom_intersect(), this does the real 482 * Helper for regdom_intersect(), this does the real
667 * mathematical intersection fun 483 * mathematical intersection fun
668 */ 484 */
@@ -883,7 +699,6 @@ static int freq_reg_info_regd(struct wiphy *wiphy,
883 699
884 return -EINVAL; 700 return -EINVAL;
885} 701}
886EXPORT_SYMBOL(freq_reg_info);
887 702
888int freq_reg_info(struct wiphy *wiphy, 703int freq_reg_info(struct wiphy *wiphy,
889 u32 center_freq, 704 u32 center_freq,
@@ -897,6 +712,7 @@ int freq_reg_info(struct wiphy *wiphy,
897 reg_rule, 712 reg_rule,
898 NULL); 713 NULL);
899} 714}
715EXPORT_SYMBOL(freq_reg_info);
900 716
901/* 717/*
902 * Note that right now we assume the desired channel bandwidth 718 * Note that right now we assume the desired channel bandwidth
@@ -935,45 +751,8 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
935 desired_bw_khz, 751 desired_bw_khz,
936 &reg_rule); 752 &reg_rule);
937 753
938 if (r) { 754 if (r)
939 /*
940 * This means no regulatory rule was found in the country IE
941 * with a frequency range on the center_freq's band, since
942 * IEEE-802.11 allows for a country IE to have a subset of the
943 * regulatory information provided in a country we ignore
944 * disabling the channel unless at least one reg rule was
945 * found on the center_freq's band. For details see this
946 * clarification:
947 *
948 * http://tinyurl.com/11d-clarification
949 */
950 if (r == -ERANGE &&
951 last_request->initiator ==
952 NL80211_REGDOM_SET_BY_COUNTRY_IE) {
953#ifdef CONFIG_CFG80211_REG_DEBUG
954 printk(KERN_DEBUG "cfg80211: Leaving channel %d MHz "
955 "intact on %s - no rule found in band on "
956 "Country IE\n",
957 chan->center_freq, wiphy_name(wiphy));
958#endif
959 } else {
960 /*
961 * In this case we know the country IE has at least one reg rule
962 * for the band so we respect its band definitions
963 */
964#ifdef CONFIG_CFG80211_REG_DEBUG
965 if (last_request->initiator ==
966 NL80211_REGDOM_SET_BY_COUNTRY_IE)
967 printk(KERN_DEBUG "cfg80211: Disabling "
968 "channel %d MHz on %s due to "
969 "Country IE\n",
970 chan->center_freq, wiphy_name(wiphy));
971#endif
972 flags |= IEEE80211_CHAN_DISABLED;
973 chan->flags = flags;
974 }
975 return; 755 return;
976 }
977 756
978 power_rule = &reg_rule->power_rule; 757 power_rule = &reg_rule->power_rule;
979 freq_range = &reg_rule->freq_range; 758 freq_range = &reg_rule->freq_range;
@@ -1342,30 +1121,6 @@ void wiphy_apply_custom_regulatory(struct wiphy *wiphy,
1342} 1121}
1343EXPORT_SYMBOL(wiphy_apply_custom_regulatory); 1122EXPORT_SYMBOL(wiphy_apply_custom_regulatory);
1344 1123
1345static int reg_copy_regd(const struct ieee80211_regdomain **dst_regd,
1346 const struct ieee80211_regdomain *src_regd)
1347{
1348 struct ieee80211_regdomain *regd;
1349 int size_of_regd = 0;
1350 unsigned int i;
1351
1352 size_of_regd = sizeof(struct ieee80211_regdomain) +
1353 ((src_regd->n_reg_rules + 1) * sizeof(struct ieee80211_reg_rule));
1354
1355 regd = kzalloc(size_of_regd, GFP_KERNEL);
1356 if (!regd)
1357 return -ENOMEM;
1358
1359 memcpy(regd, src_regd, sizeof(struct ieee80211_regdomain));
1360
1361 for (i = 0; i < src_regd->n_reg_rules; i++)
1362 memcpy(&regd->reg_rules[i], &src_regd->reg_rules[i],
1363 sizeof(struct ieee80211_reg_rule));
1364
1365 *dst_regd = regd;
1366 return 0;
1367}
1368
1369/* 1124/*
1370 * Return value which can be used by ignore_request() to indicate 1125 * Return value which can be used by ignore_request() to indicate
1371 * it has been determined we should intersect two regulatory domains 1126 * it has been determined we should intersect two regulatory domains
@@ -1387,7 +1142,7 @@ static int ignore_request(struct wiphy *wiphy,
1387 1142
1388 switch (pending_request->initiator) { 1143 switch (pending_request->initiator) {
1389 case NL80211_REGDOM_SET_BY_CORE: 1144 case NL80211_REGDOM_SET_BY_CORE:
1390 return -EINVAL; 1145 return 0;
1391 case NL80211_REGDOM_SET_BY_COUNTRY_IE: 1146 case NL80211_REGDOM_SET_BY_COUNTRY_IE:
1392 1147
1393 last_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx); 1148 last_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx);
@@ -1418,8 +1173,6 @@ static int ignore_request(struct wiphy *wiphy,
1418 return REG_INTERSECT; 1173 return REG_INTERSECT;
1419 case NL80211_REGDOM_SET_BY_DRIVER: 1174 case NL80211_REGDOM_SET_BY_DRIVER:
1420 if (last_request->initiator == NL80211_REGDOM_SET_BY_CORE) { 1175 if (last_request->initiator == NL80211_REGDOM_SET_BY_CORE) {
1421 if (is_old_static_regdom(cfg80211_regdomain))
1422 return 0;
1423 if (regdom_changes(pending_request->alpha2)) 1176 if (regdom_changes(pending_request->alpha2))
1424 return 0; 1177 return 0;
1425 return -EALREADY; 1178 return -EALREADY;
@@ -1456,8 +1209,7 @@ static int ignore_request(struct wiphy *wiphy,
1456 return -EAGAIN; 1209 return -EAGAIN;
1457 } 1210 }
1458 1211
1459 if (!is_old_static_regdom(cfg80211_regdomain) && 1212 if (!regdom_changes(pending_request->alpha2))
1460 !regdom_changes(pending_request->alpha2))
1461 return -EALREADY; 1213 return -EALREADY;
1462 1214
1463 return 0; 1215 return 0;
@@ -1529,6 +1281,11 @@ new_request:
1529 1281
1530 pending_request = NULL; 1282 pending_request = NULL;
1531 1283
1284 if (last_request->initiator == NL80211_REGDOM_SET_BY_USER) {
1285 user_alpha2[0] = last_request->alpha2[0];
1286 user_alpha2[1] = last_request->alpha2[1];
1287 }
1288
1532 /* When r == REG_INTERSECT we do need to call CRDA */ 1289 /* When r == REG_INTERSECT we do need to call CRDA */
1533 if (r < 0) { 1290 if (r < 0) {
1534 /* 1291 /*
@@ -1549,6 +1306,7 @@ static void reg_process_hint(struct regulatory_request *reg_request)
1549{ 1306{
1550 int r = 0; 1307 int r = 0;
1551 struct wiphy *wiphy = NULL; 1308 struct wiphy *wiphy = NULL;
1309 enum nl80211_reg_initiator initiator = reg_request->initiator;
1552 1310
1553 BUG_ON(!reg_request->alpha2); 1311 BUG_ON(!reg_request->alpha2);
1554 1312
@@ -1568,7 +1326,7 @@ static void reg_process_hint(struct regulatory_request *reg_request)
1568 /* This is required so that the orig_* parameters are saved */ 1326 /* This is required so that the orig_* parameters are saved */
1569 if (r == -EALREADY && wiphy && 1327 if (r == -EALREADY && wiphy &&
1570 wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY) 1328 wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY)
1571 wiphy_update_regulatory(wiphy, reg_request->initiator); 1329 wiphy_update_regulatory(wiphy, initiator);
1572out: 1330out:
1573 mutex_unlock(&reg_mutex); 1331 mutex_unlock(&reg_mutex);
1574 mutex_unlock(&cfg80211_mutex); 1332 mutex_unlock(&cfg80211_mutex);
@@ -1648,12 +1406,16 @@ static void queue_regulatory_request(struct regulatory_request *request)
1648 schedule_work(&reg_work); 1406 schedule_work(&reg_work);
1649} 1407}
1650 1408
1651/* Core regulatory hint -- happens once during cfg80211_init() */ 1409/*
1410 * Core regulatory hint -- happens during cfg80211_init()
1411 * and when we restore regulatory settings.
1412 */
1652static int regulatory_hint_core(const char *alpha2) 1413static int regulatory_hint_core(const char *alpha2)
1653{ 1414{
1654 struct regulatory_request *request; 1415 struct regulatory_request *request;
1655 1416
1656 BUG_ON(last_request); 1417 kfree(last_request);
1418 last_request = NULL;
1657 1419
1658 request = kzalloc(sizeof(struct regulatory_request), 1420 request = kzalloc(sizeof(struct regulatory_request),
1659 GFP_KERNEL); 1421 GFP_KERNEL);
@@ -1664,14 +1426,12 @@ static int regulatory_hint_core(const char *alpha2)
1664 request->alpha2[1] = alpha2[1]; 1426 request->alpha2[1] = alpha2[1];
1665 request->initiator = NL80211_REGDOM_SET_BY_CORE; 1427 request->initiator = NL80211_REGDOM_SET_BY_CORE;
1666 1428
1667 queue_regulatory_request(request);
1668
1669 /* 1429 /*
1670 * This ensures last_request is populated once modules 1430 * This ensures last_request is populated once modules
1671 * come swinging in and calling regulatory hints and 1431 * come swinging in and calling regulatory hints and
1672 * wiphy_apply_custom_regulatory(). 1432 * wiphy_apply_custom_regulatory().
1673 */ 1433 */
1674 flush_scheduled_work(); 1434 reg_process_hint(request);
1675 1435
1676 return 0; 1436 return 0;
1677} 1437}
@@ -1724,46 +1484,16 @@ int regulatory_hint(struct wiphy *wiphy, const char *alpha2)
1724} 1484}
1725EXPORT_SYMBOL(regulatory_hint); 1485EXPORT_SYMBOL(regulatory_hint);
1726 1486
1727/* Caller must hold reg_mutex */
1728static bool reg_same_country_ie_hint(struct wiphy *wiphy,
1729 u32 country_ie_checksum)
1730{
1731 struct wiphy *request_wiphy;
1732
1733 assert_reg_lock();
1734
1735 if (unlikely(last_request->initiator !=
1736 NL80211_REGDOM_SET_BY_COUNTRY_IE))
1737 return false;
1738
1739 request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx);
1740
1741 if (!request_wiphy)
1742 return false;
1743
1744 if (likely(request_wiphy != wiphy))
1745 return !country_ie_integrity_changes(country_ie_checksum);
1746 /*
1747 * We should not have let these through at this point, they
1748 * should have been picked up earlier by the first alpha2 check
1749 * on the device
1750 */
1751 if (WARN_ON(!country_ie_integrity_changes(country_ie_checksum)))
1752 return true;
1753 return false;
1754}
1755
1756/* 1487/*
1757 * We hold wdev_lock() here so we cannot hold cfg80211_mutex() and 1488 * We hold wdev_lock() here so we cannot hold cfg80211_mutex() and
1758 * therefore cannot iterate over the rdev list here. 1489 * therefore cannot iterate over the rdev list here.
1759 */ 1490 */
1760void regulatory_hint_11d(struct wiphy *wiphy, 1491void regulatory_hint_11d(struct wiphy *wiphy,
1761 u8 *country_ie, 1492 enum ieee80211_band band,
1762 u8 country_ie_len) 1493 u8 *country_ie,
1494 u8 country_ie_len)
1763{ 1495{
1764 struct ieee80211_regdomain *rd = NULL;
1765 char alpha2[2]; 1496 char alpha2[2];
1766 u32 checksum = 0;
1767 enum environment_cap env = ENVIRON_ANY; 1497 enum environment_cap env = ENVIRON_ANY;
1768 struct regulatory_request *request; 1498 struct regulatory_request *request;
1769 1499
@@ -1779,14 +1509,6 @@ void regulatory_hint_11d(struct wiphy *wiphy,
1779 if (country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN) 1509 if (country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN)
1780 goto out; 1510 goto out;
1781 1511
1782 /*
1783 * Pending country IE processing, this can happen after we
1784 * call CRDA and wait for a response if a beacon was received before
1785 * we were able to process the last regulatory_hint_11d() call
1786 */
1787 if (country_ie_regdomain)
1788 goto out;
1789
1790 alpha2[0] = country_ie[0]; 1512 alpha2[0] = country_ie[0];
1791 alpha2[1] = country_ie[1]; 1513 alpha2[1] = country_ie[1];
1792 1514
@@ -1805,37 +1527,14 @@ void regulatory_hint_11d(struct wiphy *wiphy,
1805 wiphy_idx_valid(last_request->wiphy_idx))) 1527 wiphy_idx_valid(last_request->wiphy_idx)))
1806 goto out; 1528 goto out;
1807 1529
1808 rd = country_ie_2_rd(country_ie, country_ie_len, &checksum);
1809 if (!rd)
1810 goto out;
1811
1812 /*
1813 * This will not happen right now but we leave it here for the
1814 * the future when we want to add suspend/resume support and having
1815 * the user move to another country after doing so, or having the user
1816 * move to another AP. Right now we just trust the first AP.
1817 *
1818 * If we hit this before we add this support we want to be informed of
1819 * it as it would indicate a mistake in the current design
1820 */
1821 if (WARN_ON(reg_same_country_ie_hint(wiphy, checksum)))
1822 goto free_rd_out;
1823
1824 request = kzalloc(sizeof(struct regulatory_request), GFP_KERNEL); 1530 request = kzalloc(sizeof(struct regulatory_request), GFP_KERNEL);
1825 if (!request) 1531 if (!request)
1826 goto free_rd_out; 1532 goto out;
1827
1828 /*
1829 * We keep this around for when CRDA comes back with a response so
1830 * we can intersect with that
1831 */
1832 country_ie_regdomain = rd;
1833 1533
1834 request->wiphy_idx = get_wiphy_idx(wiphy); 1534 request->wiphy_idx = get_wiphy_idx(wiphy);
1835 request->alpha2[0] = rd->alpha2[0]; 1535 request->alpha2[0] = alpha2[0];
1836 request->alpha2[1] = rd->alpha2[1]; 1536 request->alpha2[1] = alpha2[1];
1837 request->initiator = NL80211_REGDOM_SET_BY_COUNTRY_IE; 1537 request->initiator = NL80211_REGDOM_SET_BY_COUNTRY_IE;
1838 request->country_ie_checksum = checksum;
1839 request->country_ie_env = env; 1538 request->country_ie_env = env;
1840 1539
1841 mutex_unlock(&reg_mutex); 1540 mutex_unlock(&reg_mutex);
@@ -1844,12 +1543,127 @@ void regulatory_hint_11d(struct wiphy *wiphy,
1844 1543
1845 return; 1544 return;
1846 1545
1847free_rd_out:
1848 kfree(rd);
1849out: 1546out:
1850 mutex_unlock(&reg_mutex); 1547 mutex_unlock(&reg_mutex);
1851} 1548}
1852 1549
1550static void restore_alpha2(char *alpha2, bool reset_user)
1551{
1552 /* indicates there is no alpha2 to consider for restoration */
1553 alpha2[0] = '9';
1554 alpha2[1] = '7';
1555
1556 /* The user setting has precedence over the module parameter */
1557 if (is_user_regdom_saved()) {
1558 /* Unless we're asked to ignore it and reset it */
1559 if (reset_user) {
1560 REG_DBG_PRINT("cfg80211: Restoring regulatory settings "
1561 "including user preference\n");
1562 user_alpha2[0] = '9';
1563 user_alpha2[1] = '7';
1564
1565 /*
1566 * If we're ignoring user settings, we still need to
1567 * check the module parameter to ensure we put things
1568 * back as they were for a full restore.
1569 */
1570 if (!is_world_regdom(ieee80211_regdom)) {
1571 REG_DBG_PRINT("cfg80211: Keeping preference on "
1572 "module parameter ieee80211_regdom: %c%c\n",
1573 ieee80211_regdom[0],
1574 ieee80211_regdom[1]);
1575 alpha2[0] = ieee80211_regdom[0];
1576 alpha2[1] = ieee80211_regdom[1];
1577 }
1578 } else {
1579 REG_DBG_PRINT("cfg80211: Restoring regulatory settings "
1580 "while preserving user preference for: %c%c\n",
1581 user_alpha2[0],
1582 user_alpha2[1]);
1583 alpha2[0] = user_alpha2[0];
1584 alpha2[1] = user_alpha2[1];
1585 }
1586 } else if (!is_world_regdom(ieee80211_regdom)) {
1587 REG_DBG_PRINT("cfg80211: Keeping preference on "
1588 "module parameter ieee80211_regdom: %c%c\n",
1589 ieee80211_regdom[0],
1590 ieee80211_regdom[1]);
1591 alpha2[0] = ieee80211_regdom[0];
1592 alpha2[1] = ieee80211_regdom[1];
1593 } else
1594 REG_DBG_PRINT("cfg80211: Restoring regulatory settings\n");
1595}
1596
1597/*
1598 * Restoring regulatory settings involves ingoring any
1599 * possibly stale country IE information and user regulatory
1600 * settings if so desired, this includes any beacon hints
1601 * learned as we could have traveled outside to another country
1602 * after disconnection. To restore regulatory settings we do
1603 * exactly what we did at bootup:
1604 *
1605 * - send a core regulatory hint
1606 * - send a user regulatory hint if applicable
1607 *
1608 * Device drivers that send a regulatory hint for a specific country
1609 * keep their own regulatory domain on wiphy->regd so that does does
1610 * not need to be remembered.
1611 */
1612static void restore_regulatory_settings(bool reset_user)
1613{
1614 char alpha2[2];
1615 struct reg_beacon *reg_beacon, *btmp;
1616
1617 mutex_lock(&cfg80211_mutex);
1618 mutex_lock(&reg_mutex);
1619
1620 reset_regdomains();
1621 restore_alpha2(alpha2, reset_user);
1622
1623 /* Clear beacon hints */
1624 spin_lock_bh(&reg_pending_beacons_lock);
1625 if (!list_empty(&reg_pending_beacons)) {
1626 list_for_each_entry_safe(reg_beacon, btmp,
1627 &reg_pending_beacons, list) {
1628 list_del(&reg_beacon->list);
1629 kfree(reg_beacon);
1630 }
1631 }
1632 spin_unlock_bh(&reg_pending_beacons_lock);
1633
1634 if (!list_empty(&reg_beacon_list)) {
1635 list_for_each_entry_safe(reg_beacon, btmp,
1636 &reg_beacon_list, list) {
1637 list_del(&reg_beacon->list);
1638 kfree(reg_beacon);
1639 }
1640 }
1641
1642 /* First restore to the basic regulatory settings */
1643 cfg80211_regdomain = cfg80211_world_regdom;
1644
1645 mutex_unlock(&reg_mutex);
1646 mutex_unlock(&cfg80211_mutex);
1647
1648 regulatory_hint_core(cfg80211_regdomain->alpha2);
1649
1650 /*
1651 * This restores the ieee80211_regdom module parameter
1652 * preference or the last user requested regulatory
1653 * settings, user regulatory settings takes precedence.
1654 */
1655 if (is_an_alpha2(alpha2))
1656 regulatory_hint_user(user_alpha2);
1657}
1658
1659
1660void regulatory_hint_disconnect(void)
1661{
1662 REG_DBG_PRINT("cfg80211: All devices are disconnected, going to "
1663 "restore regulatory settings\n");
1664 restore_regulatory_settings(false);
1665}
1666
1853static bool freq_is_chan_12_13_14(u16 freq) 1667static bool freq_is_chan_12_13_14(u16 freq)
1854{ 1668{
1855 if (freq == ieee80211_channel_to_frequency(12) || 1669 if (freq == ieee80211_channel_to_frequency(12) ||
@@ -1875,13 +1689,12 @@ int regulatory_hint_found_beacon(struct wiphy *wiphy,
1875 if (!reg_beacon) 1689 if (!reg_beacon)
1876 return -ENOMEM; 1690 return -ENOMEM;
1877 1691
1878#ifdef CONFIG_CFG80211_REG_DEBUG 1692 REG_DBG_PRINT("cfg80211: Found new beacon on "
1879 printk(KERN_DEBUG "cfg80211: Found new beacon on " 1693 "frequency: %d MHz (Ch %d) on %s\n",
1880 "frequency: %d MHz (Ch %d) on %s\n", 1694 beacon_chan->center_freq,
1881 beacon_chan->center_freq, 1695 ieee80211_frequency_to_channel(beacon_chan->center_freq),
1882 ieee80211_frequency_to_channel(beacon_chan->center_freq), 1696 wiphy_name(wiphy));
1883 wiphy_name(wiphy)); 1697
1884#endif
1885 memcpy(&reg_beacon->chan, beacon_chan, 1698 memcpy(&reg_beacon->chan, beacon_chan,
1886 sizeof(struct ieee80211_channel)); 1699 sizeof(struct ieee80211_channel));
1887 1700
@@ -1953,10 +1766,10 @@ static void print_regdomain(const struct ieee80211_regdomain *rd)
1953 rdev->country_ie_alpha2[1]); 1766 rdev->country_ie_alpha2[1]);
1954 } else 1767 } else
1955 printk(KERN_INFO "cfg80211: Current regulatory " 1768 printk(KERN_INFO "cfg80211: Current regulatory "
1956 "domain intersected: \n"); 1769 "domain intersected:\n");
1957 } else 1770 } else
1958 printk(KERN_INFO "cfg80211: Current regulatory " 1771 printk(KERN_INFO "cfg80211: Current regulatory "
1959 "domain intersected: \n"); 1772 "domain intersected:\n");
1960 } else if (is_world_regdom(rd->alpha2)) 1773 } else if (is_world_regdom(rd->alpha2))
1961 printk(KERN_INFO "cfg80211: World regulatory " 1774 printk(KERN_INFO "cfg80211: World regulatory "
1962 "domain updated:\n"); 1775 "domain updated:\n");
@@ -1980,33 +1793,6 @@ static void print_regdomain_info(const struct ieee80211_regdomain *rd)
1980 print_rd_rules(rd); 1793 print_rd_rules(rd);
1981} 1794}
1982 1795
1983#ifdef CONFIG_CFG80211_REG_DEBUG
1984static void reg_country_ie_process_debug(
1985 const struct ieee80211_regdomain *rd,
1986 const struct ieee80211_regdomain *country_ie_regdomain,
1987 const struct ieee80211_regdomain *intersected_rd)
1988{
1989 printk(KERN_DEBUG "cfg80211: Received country IE:\n");
1990 print_regdomain_info(country_ie_regdomain);
1991 printk(KERN_DEBUG "cfg80211: CRDA thinks this should applied:\n");
1992 print_regdomain_info(rd);
1993 if (intersected_rd) {
1994 printk(KERN_DEBUG "cfg80211: We intersect both of these "
1995 "and get:\n");
1996 print_regdomain_info(intersected_rd);
1997 return;
1998 }
1999 printk(KERN_DEBUG "cfg80211: Intersection between both failed\n");
2000}
2001#else
2002static inline void reg_country_ie_process_debug(
2003 const struct ieee80211_regdomain *rd,
2004 const struct ieee80211_regdomain *country_ie_regdomain,
2005 const struct ieee80211_regdomain *intersected_rd)
2006{
2007}
2008#endif
2009
2010/* Takes ownership of rd only if it doesn't fail */ 1796/* Takes ownership of rd only if it doesn't fail */
2011static int __set_regdom(const struct ieee80211_regdomain *rd) 1797static int __set_regdom(const struct ieee80211_regdomain *rd)
2012{ 1798{
@@ -2039,8 +1825,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
2039 * If someone else asked us to change the rd lets only bother 1825 * If someone else asked us to change the rd lets only bother
2040 * checking if the alpha2 changes if CRDA was already called 1826 * checking if the alpha2 changes if CRDA was already called
2041 */ 1827 */
2042 if (!is_old_static_regdom(cfg80211_regdomain) && 1828 if (!regdom_changes(rd->alpha2))
2043 !regdom_changes(rd->alpha2))
2044 return -EINVAL; 1829 return -EINVAL;
2045 } 1830 }
2046 1831
@@ -2119,34 +1904,6 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
2119 return 0; 1904 return 0;
2120 } 1905 }
2121 1906
2122 /*
2123 * Country IE requests are handled a bit differently, we intersect
2124 * the country IE rd with what CRDA believes that country should have
2125 */
2126
2127 /*
2128 * Userspace could have sent two replies with only
2129 * one kernel request. By the second reply we would have
2130 * already processed and consumed the country_ie_regdomain.
2131 */
2132 if (!country_ie_regdomain)
2133 return -EALREADY;
2134 BUG_ON(rd == country_ie_regdomain);
2135
2136 /*
2137 * Intersect what CRDA returned and our what we
2138 * had built from the Country IE received
2139 */
2140
2141 intersected_rd = regdom_intersect(rd, country_ie_regdomain);
2142
2143 reg_country_ie_process_debug(rd,
2144 country_ie_regdomain,
2145 intersected_rd);
2146
2147 kfree(country_ie_regdomain);
2148 country_ie_regdomain = NULL;
2149
2150 if (!intersected_rd) 1907 if (!intersected_rd)
2151 return -EINVAL; 1908 return -EINVAL;
2152 1909
@@ -2228,7 +1985,7 @@ out:
2228 mutex_unlock(&reg_mutex); 1985 mutex_unlock(&reg_mutex);
2229} 1986}
2230 1987
2231int regulatory_init(void) 1988int __init regulatory_init(void)
2232{ 1989{
2233 int err = 0; 1990 int err = 0;
2234 1991
@@ -2239,15 +1996,11 @@ int regulatory_init(void)
2239 spin_lock_init(&reg_requests_lock); 1996 spin_lock_init(&reg_requests_lock);
2240 spin_lock_init(&reg_pending_beacons_lock); 1997 spin_lock_init(&reg_pending_beacons_lock);
2241 1998
2242#ifdef CONFIG_WIRELESS_OLD_REGULATORY
2243 cfg80211_regdomain = static_regdom(ieee80211_regdom);
2244
2245 printk(KERN_INFO "cfg80211: Using static regulatory domain info\n");
2246 print_regdomain_info(cfg80211_regdomain);
2247#else
2248 cfg80211_regdomain = cfg80211_world_regdom; 1999 cfg80211_regdomain = cfg80211_world_regdom;
2249 2000
2250#endif 2001 user_alpha2[0] = '9';
2002 user_alpha2[1] = '7';
2003
2251 /* We always try to get an update for the static regdomain */ 2004 /* We always try to get an update for the static regdomain */
2252 err = regulatory_hint_core(cfg80211_regdomain->alpha2); 2005 err = regulatory_hint_core(cfg80211_regdomain->alpha2);
2253 if (err) { 2006 if (err) {
@@ -2278,7 +2031,7 @@ int regulatory_init(void)
2278 return 0; 2031 return 0;
2279} 2032}
2280 2033
2281void regulatory_exit(void) 2034void /* __init_or_exit */ regulatory_exit(void)
2282{ 2035{
2283 struct regulatory_request *reg_request, *tmp; 2036 struct regulatory_request *reg_request, *tmp;
2284 struct reg_beacon *reg_beacon, *btmp; 2037 struct reg_beacon *reg_beacon, *btmp;
@@ -2290,9 +2043,6 @@ void regulatory_exit(void)
2290 2043
2291 reset_regdomains(); 2044 reset_regdomains();
2292 2045
2293 kfree(country_ie_regdomain);
2294 country_ie_regdomain = NULL;
2295
2296 kfree(last_request); 2046 kfree(last_request);
2297 2047
2298 platform_device_unregister(reg_pdev); 2048 platform_device_unregister(reg_pdev);