reg.c 64.1 KB
Newer Older
1
2
3
4
/*
 * Copyright 2002-2005, Instant802 Networks, Inc.
 * Copyright 2005-2006, Devicescape Software, Inc.
 * Copyright 2007	Johannes Berg <johannes@sipsolutions.net>
5
 * Copyright 2008-2011	Luis R. Rodriguez <mcgrof@qca.qualcomm.com>
6
 *
7
8
9
10
11
12
13
14
15
16
17
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
19
 */

20

21
22
/**
 * DOC: Wireless regulatory infrastructure
23
24
25
26
27
28
 *
 * The usual implementation is for a driver to read a device EEPROM to
 * determine which regulatory domain it should be operating under, then
 * looking up the allowable channels in a driver-local table and finally
 * registering those channels in the wiphy structure.
 *
29
30
31
32
33
34
35
36
37
38
39
40
41
42
 * Another set of compliance enforcement is for drivers to use their
 * own compliance limits which can be stored on the EEPROM. The host
 * driver or firmware may ensure these are used.
 *
 * In addition to all this we provide an extra layer of regulatory
 * conformance. For drivers which do not have any regulatory
 * information CRDA provides the complete regulatory solution.
 * For others it provides a community effort on further restrictions
 * to enhance compliance.
 *
 * Note: When number of rules --> infinity we will not be able to
 * index on alpha2 any more, instead we'll probably have to
 * rely on some SHA1 checksum of the regdomain for example.
 *
43
 */
44
45
46

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

47
#include <linux/kernel.h>
48
#include <linux/export.h>
49
#include <linux/slab.h>
50
#include <linux/list.h>
51
#include <linux/ctype.h>
52
53
#include <linux/nl80211.h>
#include <linux/platform_device.h>
54
#include <linux/moduleparam.h>
55
#include <net/cfg80211.h>
56
#include "core.h"
57
#include "reg.h"
58
#include "regdb.h"
59
#include "nl80211.h"
60

61
#ifdef CONFIG_CFG80211_REG_DEBUG
62
63
#define REG_DBG_PRINT(format, args...)			\
	printk(KERN_DEBUG pr_fmt(format), ##args)
64
#else
65
#define REG_DBG_PRINT(args...)
66
67
#endif

68
69
70
71
72
73
74
enum reg_request_treatment {
	REG_REQ_OK,
	REG_REQ_IGNORE,
	REG_REQ_INTERSECT,
	REG_REQ_ALREADY_SET,
};

75
76
77
78
79
80
81
82
83
static struct regulatory_request core_request_world = {
	.initiator = NL80211_REGDOM_SET_BY_CORE,
	.alpha2[0] = '0',
	.alpha2[1] = '0',
	.intersect = false,
	.processed = true,
	.country_ie_env = ENVIRON_ANY,
};

84
/* Receipt of information from last regulatory request */
85
static struct regulatory_request *last_request = &core_request_world;
86

87
88
/* To trigger userspace events */
static struct platform_device *reg_pdev;
89

90
91
92
93
static struct device_type reg_device_type = {
	.uevent = reg_device_uevent,
};

94
95
/*
 * Central wireless core regulatory domains, we only need two,
96
 * the current one and a world regulatory domain in case we have no
97
98
 * information to give us an alpha2
 */
99
const struct ieee80211_regdomain *cfg80211_regdomain;
100

101
102
103
104
105
/*
 * Protects static reg.c components:
 *     - cfg80211_world_regdom
 *     - cfg80211_regdom
 *     - last_request
106
 *     - reg_num_devs_support_basehint
107
 */
108
static DEFINE_MUTEX(reg_mutex);
109

110
111
112
113
114
115
/*
 * Number of devices that registered to the core
 * that support cellular base station regulatory hints
 */
static int reg_num_devs_support_basehint;

116
117
118
119
static inline void assert_reg_lock(void)
{
	lockdep_assert_held(&reg_mutex);
}
120

121
/* Used to queue up regulatory hints */
122
123
124
static LIST_HEAD(reg_requests_list);
static spinlock_t reg_requests_lock;

125
126
127
128
129
130
131
132
133
134
135
136
/* Used to queue up beacon hints for review */
static LIST_HEAD(reg_pending_beacons);
static spinlock_t reg_pending_beacons_lock;

/* Used to keep track of processed beacon hints */
static LIST_HEAD(reg_beacon_list);

struct reg_beacon {
	struct list_head list;
	struct ieee80211_channel chan;
};

137
138
139
static void reg_todo(struct work_struct *work);
static DECLARE_WORK(reg_work, reg_todo);

140
141
142
static void reg_timeout_work(struct work_struct *work);
static DECLARE_DELAYED_WORK(reg_timeout, reg_timeout_work);

143
144
/* We keep a static world regulatory domain in case of the absence of CRDA */
static const struct ieee80211_regdomain world_regdom = {
145
	.n_reg_rules = 6,
146
147
	.alpha2 =  "00",
	.reg_rules = {
148
149
		/* IEEE 802.11b/g, channels 1..11 */
		REG_RULE(2412-10, 2462+10, 40, 6, 20, 0),
150
151
		/* IEEE 802.11b/g, channels 12..13. */
		REG_RULE(2467-10, 2472+10, 40, 6, 20,
152
153
			NL80211_RRF_PASSIVE_SCAN |
			NL80211_RRF_NO_IBSS),
154
155
156
157
158
159
160
		/* IEEE 802.11 channel 14 - Only JP enables
		 * this and for 802.11b only */
		REG_RULE(2484-10, 2484+10, 20, 6, 20,
			NL80211_RRF_PASSIVE_SCAN |
			NL80211_RRF_NO_IBSS |
			NL80211_RRF_NO_OFDM),
		/* IEEE 802.11a, channel 36..48 */
161
		REG_RULE(5180-10, 5240+10, 40, 6, 20,
162
163
                        NL80211_RRF_PASSIVE_SCAN |
                        NL80211_RRF_NO_IBSS),
164
165
166
167

		/* NB: 5260 MHz - 5700 MHz requies DFS */

		/* IEEE 802.11a, channel 149..165 */
168
		REG_RULE(5745-10, 5825+10, 40, 6, 20,
169
170
			NL80211_RRF_PASSIVE_SCAN |
			NL80211_RRF_NO_IBSS),
171
172
173

		/* IEEE 802.11ad (60gHz), channels 1..3 */
		REG_RULE(56160+2160*1-1080, 56160+2160*3+1080, 2160, 0, 0, 0),
174
175
176
	}
};

177
178
static const struct ieee80211_regdomain *cfg80211_world_regdom =
	&world_regdom;
179

180
static char *ieee80211_regdom = "00";
181
static char user_alpha2[2];
182

183
184
185
module_param(ieee80211_regdom, charp, 0444);
MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code");

186
static void reset_regdomains(bool full_reset)
187
{
188
189
190
191
192
193
194
195
196
197
	/* avoid freeing static information or freeing something twice */
	if (cfg80211_regdomain == cfg80211_world_regdom)
		cfg80211_regdomain = NULL;
	if (cfg80211_world_regdom == &world_regdom)
		cfg80211_world_regdom = NULL;
	if (cfg80211_regdomain == &world_regdom)
		cfg80211_regdomain = NULL;

	kfree(cfg80211_regdomain);
	kfree(cfg80211_world_regdom);
198

199
	cfg80211_world_regdom = &world_regdom;
200
	cfg80211_regdomain = NULL;
201
202
203
204
205
206
207

	if (!full_reset)
		return;

	if (last_request != &core_request_world)
		kfree(last_request);
	last_request = &core_request_world;
208
209
}

210
211
212
213
/*
 * Dynamic world regulatory domain requested by the wireless
 * core upon initialization
 */
214
static void update_world_regdomain(const struct ieee80211_regdomain *rd)
215
{
216
	BUG_ON(!last_request);
217

218
	reset_regdomains(false);
219
220
221
222
223

	cfg80211_world_regdom = rd;
	cfg80211_regdomain = rd;
}

224
bool is_world_regdom(const char *alpha2)
225
226
227
{
	if (!alpha2)
		return false;
Johannes Berg's avatar
Johannes Berg committed
228
	return alpha2[0] == '0' && alpha2[1] == '0';
229
}
230

231
static bool is_alpha2_set(const char *alpha2)
232
233
234
{
	if (!alpha2)
		return false;
Johannes Berg's avatar
Johannes Berg committed
235
	return alpha2[0] && alpha2[1];
236
}
237

238
static bool is_unknown_alpha2(const char *alpha2)
239
240
241
{
	if (!alpha2)
		return false;
242
243
244
245
	/*
	 * Special case where regulatory domain was built by driver
	 * but a specific alpha2 cannot be determined
	 */
Johannes Berg's avatar
Johannes Berg committed
246
	return alpha2[0] == '9' && alpha2[1] == '9';
247
}
248

249
250
251
252
static bool is_intersected_alpha2(const char *alpha2)
{
	if (!alpha2)
		return false;
253
254
	/*
	 * Special case where regulatory domain is the
255
	 * result of an intersection between two regulatory domain
256
257
	 * structures
	 */
Johannes Berg's avatar
Johannes Berg committed
258
	return alpha2[0] == '9' && alpha2[1] == '8';
259
260
}

261
static bool is_an_alpha2(const char *alpha2)
262
263
264
{
	if (!alpha2)
		return false;
Johannes Berg's avatar
Johannes Berg committed
265
	return isalpha(alpha2[0]) && isalpha(alpha2[1]);
266
}
267

268
static bool alpha2_equal(const char *alpha2_x, const char *alpha2_y)
269
270
271
{
	if (!alpha2_x || !alpha2_y)
		return false;
Johannes Berg's avatar
Johannes Berg committed
272
	return alpha2_x[0] == alpha2_y[0] && alpha2_x[1] == alpha2_y[1];
273
274
}

275
static bool regdom_changes(const char *alpha2)
276
{
277
278
	assert_cfg80211_lock();

279
280
	if (!cfg80211_regdomain)
		return true;
Johannes Berg's avatar
Johannes Berg committed
281
	return !alpha2_equal(cfg80211_regdomain->alpha2, alpha2);
282
283
}

284
285
286
287
288
289
290
291
292
293
294
/*
 * The NL80211_REGDOM_SET_BY_USER regdom alpha2 is cached, this lets
 * you know if a valid regulatory hint with NL80211_REGDOM_SET_BY_USER
 * has ever been issued.
 */
static bool is_user_regdom_saved(void)
{
	if (user_alpha2[0] == '9' && user_alpha2[1] == '7')
		return false;

	/* This would indicate a mistake on the design */
Johannes Berg's avatar
Johannes Berg committed
295
	if (WARN(!is_world_regdom(user_alpha2) && !is_an_alpha2(user_alpha2),
296
		 "Unexpected user alpha2: %c%c\n",
Johannes Berg's avatar
Johannes Berg committed
297
		 user_alpha2[0], user_alpha2[1]))
298
299
300
301
302
		return false;

	return true;
}

303
304
static const struct ieee80211_regdomain *
reg_copy_regd(const struct ieee80211_regdomain *src_regd)
305
306
{
	struct ieee80211_regdomain *regd;
307
	int size_of_regd;
308
309
	unsigned int i;

310
311
312
	size_of_regd =
		sizeof(struct ieee80211_regdomain) +
		src_regd->n_reg_rules * sizeof(struct ieee80211_reg_rule);
313
314
315

	regd = kzalloc(size_of_regd, GFP_KERNEL);
	if (!regd)
316
		return ERR_PTR(-ENOMEM);
317
318
319
320
321

	memcpy(regd, src_regd, sizeof(struct ieee80211_regdomain));

	for (i = 0; i < src_regd->n_reg_rules; i++)
		memcpy(&regd->reg_rules[i], &src_regd->reg_rules[i],
322
		       sizeof(struct ieee80211_reg_rule));
323

324
	return regd;
325
326
327
328
329
330
331
332
333
}

#ifdef CONFIG_CFG80211_INTERNAL_REGDB
struct reg_regdb_search_request {
	char alpha2[2];
	struct list_head list;
};

static LIST_HEAD(reg_regdb_search_list);
334
static DEFINE_MUTEX(reg_regdb_search_mutex);
335
336
337
338

static void reg_regdb_search(struct work_struct *work)
{
	struct reg_regdb_search_request *request;
339
340
	const struct ieee80211_regdomain *curdom, *regdom = NULL;
	int i;
341
342

	mutex_lock(&cfg80211_mutex);
343

344
	mutex_lock(&reg_regdb_search_mutex);
345
346
347
348
349
350
	while (!list_empty(&reg_regdb_search_list)) {
		request = list_first_entry(&reg_regdb_search_list,
					   struct reg_regdb_search_request,
					   list);
		list_del(&request->list);

Johannes Berg's avatar
Johannes Berg committed
351
		for (i = 0; i < reg_regdb_size; i++) {
352
353
			curdom = reg_regdb[i];

Johannes Berg's avatar
Johannes Berg committed
354
			if (alpha2_equal(request->alpha2, curdom->alpha2)) {
355
				regdom = reg_copy_regd(curdom);
356
357
358
359
360
361
				break;
			}
		}

		kfree(request);
	}
362
	mutex_unlock(&reg_regdb_search_mutex);
363

364
	if (!IS_ERR_OR_NULL(regdom))
365
366
367
		set_regdom(regdom);

	mutex_unlock(&cfg80211_mutex);
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
}

static DECLARE_WORK(reg_regdb_work, reg_regdb_search);

static void reg_regdb_query(const char *alpha2)
{
	struct reg_regdb_search_request *request;

	if (!alpha2)
		return;

	request = kzalloc(sizeof(struct reg_regdb_search_request), GFP_KERNEL);
	if (!request)
		return;

	memcpy(request->alpha2, alpha2, 2);

385
	mutex_lock(&reg_regdb_search_mutex);
386
	list_add_tail(&request->list, &reg_regdb_search_list);
387
	mutex_unlock(&reg_regdb_search_mutex);
388
389
390

	schedule_work(&reg_regdb_work);
}
391
392
393
394
395
396
397

/* Feel free to add any other sanity checks here */
static void reg_regdb_size_check(void)
{
	/* We should ideally BUILD_BUG_ON() but then random builds would fail */
	WARN_ONCE(!reg_regdb_size, "db.txt is empty, you should update it...");
}
398
#else
399
static inline void reg_regdb_size_check(void) {}
400
401
402
static inline void reg_regdb_query(const char *alpha2) {}
#endif /* CONFIG_CFG80211_INTERNAL_REGDB */

403
404
/*
 * This lets us keep regulatory code which is updated on a regulatory
405
406
 * basis in userspace. Country information is filled in by
 * reg_device_uevent
407
 */
408
409
410
static int call_crda(const char *alpha2)
{
	if (!is_world_regdom((char *) alpha2))
411
		pr_info("Calling CRDA for country: %c%c\n",
412
413
			alpha2[0], alpha2[1]);
	else
414
		pr_info("Calling CRDA to update world regulatory domain\n");
415

416
417
418
	/* query internal regulatory database (if it exists) */
	reg_regdb_query(alpha2);

419
	return kobject_uevent(&reg_pdev->dev.kobj, KOBJ_CHANGE);
420
421
422
}

/* Used by nl80211 before kmalloc'ing our regulatory domain */
423
bool reg_is_valid_request(const char *alpha2)
424
{
425
426
	assert_cfg80211_lock();

427
428
429
430
	if (!last_request)
		return false;

	return alpha2_equal(last_request->alpha2, alpha2);
431
}
432

433
/* Sanity check on a regulatory rule */
434
static bool is_valid_reg_rule(const struct ieee80211_reg_rule *rule)
435
{
436
	const struct ieee80211_freq_range *freq_range = &rule->freq_range;
437
438
	u32 freq_diff;

439
	if (freq_range->start_freq_khz <= 0 || freq_range->end_freq_khz <= 0)
440
441
442
443
444
445
446
		return false;

	if (freq_range->start_freq_khz > freq_range->end_freq_khz)
		return false;

	freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz;

447
	if (freq_range->end_freq_khz <= freq_range->start_freq_khz ||
Johannes Berg's avatar
Johannes Berg committed
448
	    freq_range->max_bandwidth_khz > freq_diff)
449
450
451
452
453
		return false;

	return true;
}

454
static bool is_valid_rd(const struct ieee80211_regdomain *rd)
455
{
456
	const struct ieee80211_reg_rule *reg_rule = NULL;
457
	unsigned int i;
458

459
460
	if (!rd->n_reg_rules)
		return false;
461

462
463
464
	if (WARN_ON(rd->n_reg_rules > NL80211_MAX_SUPP_REG_RULES))
		return false;

465
466
467
468
469
470
471
	for (i = 0; i < rd->n_reg_rules; i++) {
		reg_rule = &rd->reg_rules[i];
		if (!is_valid_reg_rule(reg_rule))
			return false;
	}

	return true;
472
473
}

474
475
476
static bool reg_does_bw_fit(const struct ieee80211_freq_range *freq_range,
			    u32 center_freq_khz,
			    u32 bw_khz)
477
{
478
479
480
481
482
483
484
485
486
487
	u32 start_freq_khz, end_freq_khz;

	start_freq_khz = center_freq_khz - (bw_khz/2);
	end_freq_khz = center_freq_khz + (bw_khz/2);

	if (start_freq_khz >= freq_range->start_freq_khz &&
	    end_freq_khz <= freq_range->end_freq_khz)
		return true;

	return false;
488
}
489

490
491
492
493
494
495
496
/**
 * freq_in_rule_band - tells us if a frequency is in a frequency band
 * @freq_range: frequency rule we want to query
 * @freq_khz: frequency we are inquiring about
 *
 * This lets us know if a specific frequency rule is or is not relevant to
 * a specific frequency's band. Bands are device specific and artificial
497
498
499
500
501
 * definitions (the "2.4 GHz band", the "5 GHz band" and the "60GHz band"),
 * however it is safe for now to assume that a frequency rule should not be
 * part of a frequency's band if the start freq or end freq are off by more
 * than 2 GHz for the 2.4 and 5 GHz bands, and by more than 10 GHz for the
 * 60 GHz band.
502
503
504
505
 * This resolution can be lowered and should be considered as we add
 * regulatory rule support for other "bands".
 **/
static bool freq_in_rule_band(const struct ieee80211_freq_range *freq_range,
Johannes Berg's avatar
Johannes Berg committed
506
			      u32 freq_khz)
507
508
{
#define ONE_GHZ_IN_KHZ	1000000
509
510
511
512
513
514
515
516
	/*
	 * From 802.11ad: directional multi-gigabit (DMG):
	 * Pertaining to operation in a frequency band containing a channel
	 * with the Channel starting frequency above 45 GHz.
	 */
	u32 limit = freq_khz > 45 * ONE_GHZ_IN_KHZ ?
			10 * ONE_GHZ_IN_KHZ : 2 * ONE_GHZ_IN_KHZ;
	if (abs(freq_khz - freq_range->start_freq_khz) <= limit)
517
		return true;
518
	if (abs(freq_khz - freq_range->end_freq_khz) <= limit)
519
520
521
522
523
		return true;
	return false;
#undef ONE_GHZ_IN_KHZ
}

524
525
526
527
/*
 * Helper for regdom_intersect(), this does the real
 * mathematical intersection fun
 */
Johannes Berg's avatar
Johannes Berg committed
528
529
530
static int reg_rules_intersect(const struct ieee80211_reg_rule *rule1,
			       const struct ieee80211_reg_rule *rule2,
			       struct ieee80211_reg_rule *intersected_rule)
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
{
	const struct ieee80211_freq_range *freq_range1, *freq_range2;
	struct ieee80211_freq_range *freq_range;
	const struct ieee80211_power_rule *power_rule1, *power_rule2;
	struct ieee80211_power_rule *power_rule;
	u32 freq_diff;

	freq_range1 = &rule1->freq_range;
	freq_range2 = &rule2->freq_range;
	freq_range = &intersected_rule->freq_range;

	power_rule1 = &rule1->power_rule;
	power_rule2 = &rule2->power_rule;
	power_rule = &intersected_rule->power_rule;

	freq_range->start_freq_khz = max(freq_range1->start_freq_khz,
Johannes Berg's avatar
Johannes Berg committed
547
					 freq_range2->start_freq_khz);
548
	freq_range->end_freq_khz = min(freq_range1->end_freq_khz,
Johannes Berg's avatar
Johannes Berg committed
549
				       freq_range2->end_freq_khz);
550
	freq_range->max_bandwidth_khz = min(freq_range1->max_bandwidth_khz,
Johannes Berg's avatar
Johannes Berg committed
551
					    freq_range2->max_bandwidth_khz);
552
553
554
555
556
557
558
559
560
561

	freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz;
	if (freq_range->max_bandwidth_khz > freq_diff)
		freq_range->max_bandwidth_khz = freq_diff;

	power_rule->max_eirp = min(power_rule1->max_eirp,
		power_rule2->max_eirp);
	power_rule->max_antenna_gain = min(power_rule1->max_antenna_gain,
		power_rule2->max_antenna_gain);

Johannes Berg's avatar
Johannes Berg committed
562
	intersected_rule->flags = rule1->flags | rule2->flags;
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582

	if (!is_valid_reg_rule(intersected_rule))
		return -EINVAL;

	return 0;
}

/**
 * regdom_intersect - do the intersection between two regulatory domains
 * @rd1: first regulatory domain
 * @rd2: second regulatory domain
 *
 * Use this function to get the intersection between two regulatory domains.
 * Once completed we will mark the alpha2 for the rd as intersected, "98",
 * as no one single alpha2 can represent this regulatory domain.
 *
 * Returns a pointer to the regulatory domain structure which will hold the
 * resulting intersection of rules between rd1 and rd2. We will
 * kzalloc() this structure for you.
 */
Johannes Berg's avatar
Johannes Berg committed
583
584
585
static struct ieee80211_regdomain *
regdom_intersect(const struct ieee80211_regdomain *rd1,
		 const struct ieee80211_regdomain *rd2)
586
587
588
589
590
591
592
593
{
	int r, size_of_regd;
	unsigned int x, y;
	unsigned int num_rules = 0, rule_idx = 0;
	const struct ieee80211_reg_rule *rule1, *rule2;
	struct ieee80211_reg_rule *intersected_rule;
	struct ieee80211_regdomain *rd;
	/* This is just a dummy holder to help us count */
594
	struct ieee80211_reg_rule dummy_rule;
595
596
597
598

	if (!rd1 || !rd2)
		return NULL;

599
600
	/*
	 * First we get a count of the rules we'll need, then we actually
601
602
603
	 * build them. This is to so we can malloc() and free() a
	 * regdomain once. The reason we use reg_rules_intersect() here
	 * is it will return -EINVAL if the rule computed makes no sense.
604
605
	 * All rules that do check out OK are valid.
	 */
606
607
608
609
610

	for (x = 0; x < rd1->n_reg_rules; x++) {
		rule1 = &rd1->reg_rules[x];
		for (y = 0; y < rd2->n_reg_rules; y++) {
			rule2 = &rd2->reg_rules[y];
611
			if (!reg_rules_intersect(rule1, rule2, &dummy_rule))
612
613
614
615
616
617
618
619
				num_rules++;
		}
	}

	if (!num_rules)
		return NULL;

	size_of_regd = sizeof(struct ieee80211_regdomain) +
620
		       num_rules * sizeof(struct ieee80211_reg_rule);
621
622
623
624
625

	rd = kzalloc(size_of_regd, GFP_KERNEL);
	if (!rd)
		return NULL;

626
	for (x = 0; x < rd1->n_reg_rules && rule_idx < num_rules; x++) {
627
		rule1 = &rd1->reg_rules[x];
628
		for (y = 0; y < rd2->n_reg_rules && rule_idx < num_rules; y++) {
629
			rule2 = &rd2->reg_rules[y];
630
631
			/*
			 * This time around instead of using the stack lets
632
			 * write to the target rule directly saving ourselves
633
634
			 * a memcpy()
			 */
635
			intersected_rule = &rd->reg_rules[rule_idx];
Johannes Berg's avatar
Johannes Berg committed
636
			r = reg_rules_intersect(rule1, rule2, intersected_rule);
637
638
639
640
			/*
			 * No need to memset here the intersected rule here as
			 * we're not using the stack anymore
			 */
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
			if (r)
				continue;
			rule_idx++;
		}
	}

	if (rule_idx != num_rules) {
		kfree(rd);
		return NULL;
	}

	rd->n_reg_rules = num_rules;
	rd->alpha2[0] = '9';
	rd->alpha2[1] = '8';

	return rd;
}

659
660
661
662
/*
 * XXX: add support for the rest of enum nl80211_reg_rule_flags, we may
 * want to just have the channel structure use these
 */
663
664
665
666
667
668
669
670
671
static u32 map_regdom_flags(u32 rd_flags)
{
	u32 channel_flags = 0;
	if (rd_flags & NL80211_RRF_PASSIVE_SCAN)
		channel_flags |= IEEE80211_CHAN_PASSIVE_SCAN;
	if (rd_flags & NL80211_RRF_NO_IBSS)
		channel_flags |= IEEE80211_CHAN_NO_IBSS;
	if (rd_flags & NL80211_RRF_DFS)
		channel_flags |= IEEE80211_CHAN_RADAR;
672
673
	if (rd_flags & NL80211_RRF_NO_OFDM)
		channel_flags |= IEEE80211_CHAN_NO_OFDM;
674
675
676
	return channel_flags;
}

677
678
static int freq_reg_info_regd(struct wiphy *wiphy,
			      u32 center_freq,
679
			      u32 desired_bw_khz,
680
681
			      const struct ieee80211_reg_rule **reg_rule,
			      const struct ieee80211_regdomain *custom_regd)
682
683
{
	int i;
684
	bool band_rule_found = false;
685
	const struct ieee80211_regdomain *regd;
686
687
688
689
	bool bw_fits = false;

	if (!desired_bw_khz)
		desired_bw_khz = MHZ_TO_KHZ(20);
690

691
	regd = custom_regd ? custom_regd : cfg80211_regdomain;
692

693
694
695
696
	/*
	 * Follow the driver's regulatory domain, if present, unless a country
	 * IE has been processed or a user wants to help complaince further
	 */
697
698
	if (!custom_regd &&
	    last_request->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE &&
699
	    last_request->initiator != NL80211_REGDOM_SET_BY_USER &&
700
701
702
703
	    wiphy->regd)
		regd = wiphy->regd;

	if (!regd)
704
705
		return -EINVAL;

706
	for (i = 0; i < regd->n_reg_rules; i++) {
707
708
709
		const struct ieee80211_reg_rule *rr;
		const struct ieee80211_freq_range *fr = NULL;

710
		rr = &regd->reg_rules[i];
711
		fr = &rr->freq_range;
712

713
714
		/*
		 * We only need to know if one frequency rule was
715
		 * was in center_freq's band, that's enough, so lets
716
717
		 * not overwrite it once found
		 */
718
719
720
		if (!band_rule_found)
			band_rule_found = freq_in_rule_band(fr, center_freq);

Johannes Berg's avatar
Johannes Berg committed
721
		bw_fits = reg_does_bw_fit(fr, center_freq, desired_bw_khz);
722

723
		if (band_rule_found && bw_fits) {
724
			*reg_rule = rr;
725
			return 0;
726
727
728
		}
	}

729
730
731
	if (!band_rule_found)
		return -ERANGE;

732
	return -EINVAL;
733
734
}

Johannes Berg's avatar
Johannes Berg committed
735
int freq_reg_info(struct wiphy *wiphy, u32 center_freq, u32 desired_bw_khz,
736
		  const struct ieee80211_reg_rule **reg_rule)
737
{
738
	assert_cfg80211_lock();
Johannes Berg's avatar
Johannes Berg committed
739
740
741

	return freq_reg_info_regd(wiphy, center_freq, desired_bw_khz,
				  reg_rule, NULL);
742
}
743
EXPORT_SYMBOL(freq_reg_info);
744

745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
#ifdef CONFIG_CFG80211_REG_DEBUG
static const char *reg_initiator_name(enum nl80211_reg_initiator initiator)
{
	switch (initiator) {
	case NL80211_REGDOM_SET_BY_CORE:
		return "Set by core";
	case NL80211_REGDOM_SET_BY_USER:
		return "Set by user";
	case NL80211_REGDOM_SET_BY_DRIVER:
		return "Set by driver";
	case NL80211_REGDOM_SET_BY_COUNTRY_IE:
		return "Set by country IE";
	default:
		WARN_ON(1);
		return "Set by bug";
	}
}
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778

static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan,
				    u32 desired_bw_khz,
				    const struct ieee80211_reg_rule *reg_rule)
{
	const struct ieee80211_power_rule *power_rule;
	const struct ieee80211_freq_range *freq_range;
	char max_antenna_gain[32];

	power_rule = &reg_rule->power_rule;
	freq_range = &reg_rule->freq_range;

	if (!power_rule->max_antenna_gain)
		snprintf(max_antenna_gain, 32, "N/A");
	else
		snprintf(max_antenna_gain, 32, "%d", power_rule->max_antenna_gain);

Johannes Berg's avatar
Johannes Berg committed
779
780
	REG_DBG_PRINT("Updating information on frequency %d MHz for a %d MHz width channel with regulatory rule:\n",
		      chan->center_freq, KHZ_TO_MHZ(desired_bw_khz));
781

782
	REG_DBG_PRINT("%d KHz - %d KHz @ %d KHz), (%s mBi, %d mBm)\n",
Johannes Berg's avatar
Johannes Berg committed
783
784
		      freq_range->start_freq_khz, freq_range->end_freq_khz,
		      freq_range->max_bandwidth_khz, max_antenna_gain,
785
786
787
788
789
790
791
792
793
		      power_rule->max_eirp);
}
#else
static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan,
				    u32 desired_bw_khz,
				    const struct ieee80211_reg_rule *reg_rule)
{
	return;
}
794
795
#endif

796
797
798
799
800
801
802
803
804
/*
 * Note that right now we assume the desired channel bandwidth
 * is always 20 MHz for each individual channel (HT40 uses 20 MHz
 * per channel, the primary and the extension channel). To support
 * smaller custom bandwidths such as 5 MHz or 10 MHz we'll need a
 * new ieee80211_channel.target_bw and re run the regulatory check
 * on the wiphy with the target_bw specified. Then we can simply use
 * that below for the desired_bw_khz below.
 */
805
806
807
static void handle_channel(struct wiphy *wiphy,
			   enum nl80211_reg_initiator initiator,
			   enum ieee80211_band band,
808
			   unsigned int chan_idx)
809
810
{
	int r;
811
812
	u32 flags, bw_flags = 0;
	u32 desired_bw_khz = MHZ_TO_KHZ(20);
813
814
	const struct ieee80211_reg_rule *reg_rule = NULL;
	const struct ieee80211_power_rule *power_rule = NULL;
815
	const struct ieee80211_freq_range *freq_range = NULL;
816
817
	struct ieee80211_supported_band *sband;
	struct ieee80211_channel *chan;
818
	struct wiphy *request_wiphy = NULL;
819

820
821
	assert_cfg80211_lock();

822
823
	request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx);

824
825
826
827
828
	sband = wiphy->bands[band];
	BUG_ON(chan_idx >= sband->n_channels);
	chan = &sband->channels[chan_idx];

	flags = chan->orig_flags;
829

Johannes Berg's avatar
Johannes Berg committed
830
831
	r = freq_reg_info(wiphy, MHZ_TO_KHZ(chan->center_freq),
			  desired_bw_khz, &reg_rule);
832
833
834
	if (r) {
		/*
		 * We will disable all channels that do not match our
Lucas De Marchi's avatar
Lucas De Marchi committed
835
		 * received regulatory rule unless the hint is coming
836
837
838
839
840
841
842
843
844
845
846
		 * from a Country IE and the Country IE had no information
		 * about a band. The IEEE 802.11 spec allows for an AP
		 * to send only a subset of the regulatory rules allowed,
		 * so an AP in the US that only supports 2.4 GHz may only send
		 * a country IE with information for the 2.4 GHz band
		 * while 5 GHz is still supported.
		 */
		if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE &&
		    r == -ERANGE)
			return;

847
		REG_DBG_PRINT("Disabling freq %d MHz\n", chan->center_freq);
848
		chan->flags = IEEE80211_CHAN_DISABLED;
849
		return;
850
	}
851

852
853
	chan_reg_rule_print_dbg(chan, desired_bw_khz, reg_rule);

854
	power_rule = &reg_rule->power_rule;
855
856
857
858
	freq_range = &reg_rule->freq_range;

	if (freq_range->max_bandwidth_khz < MHZ_TO_KHZ(40))
		bw_flags = IEEE80211_CHAN_NO_HT40;
859

860
	if (last_request->initiator == NL80211_REGDOM_SET_BY_DRIVER &&
861
	    request_wiphy && request_wiphy == wiphy &&
862
	    request_wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY) {
863
		/*
Lucas De Marchi's avatar
Lucas De Marchi committed
864
		 * This guarantees the driver's requested regulatory domain
865
		 * will always be used as a base for further regulatory
866
867
		 * settings
		 */
868
		chan->flags = chan->orig_flags =
869
			map_regdom_flags(reg_rule->flags) | bw_flags;
870
871
		chan->max_antenna_gain = chan->orig_mag =
			(int) MBI_TO_DBI(power_rule->max_antenna_gain);
872
		chan->max_reg_power = chan->max_power = chan->orig_mpwr =
873
874
875
876
			(int) MBM_TO_DBM(power_rule->max_eirp);
		return;
	}

877
	chan->beacon_found = false;
878
	chan->flags = flags | bw_flags | map_regdom_flags(reg_rule->flags);
Johannes Berg's avatar
Johannes Berg committed
879
880
881
	chan->max_antenna_gain =
		min_t(int, chan->orig_mag,
		      MBI_TO_DBI(power_rule->max_antenna_gain));
882
	chan->max_reg_power = (int) MBM_TO_DBM(power_rule->max_eirp);
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
	if (chan->orig_mpwr) {
		/*
		 * Devices that have their own custom regulatory domain
		 * but also use WIPHY_FLAG_STRICT_REGULATORY will follow the
		 * passed country IE power settings.
		 */
		if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE &&
		    wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY &&
		    wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY)
			chan->max_power = chan->max_reg_power;
		else
			chan->max_power = min(chan->orig_mpwr,
					      chan->max_reg_power);
	} else
		chan->max_power = chan->max_reg_power;
898
899
}

Johannes Berg's avatar
Johannes Berg committed
900
static void handle_band(struct wiphy *wiphy, enum ieee80211_band band,
901
			enum nl80211_reg_initiator initiator)
902
{
903
904
905
906
907
	unsigned int i;
	struct ieee80211_supported_band *sband;

	BUG_ON(!wiphy->bands[band]);
	sband = wiphy->bands[band];
908
909

	for (i = 0; i < sband->n_channels; i++)
910
		handle_channel(wiphy, initiator, band, i);
911
912
}

913
914
915
916
static bool reg_request_cell_base(struct regulatory_request *request)
{
	if (request->initiator != NL80211_REGDOM_SET_BY_USER)
		return false;
Johannes Berg's avatar
Johannes Berg committed
917
	return request->user_reg_hint_type == NL80211_USER_REG_HINT_CELL_BASE;
918
919
920
921
}

bool reg_last_request_cell_base(void)
{
922
	bool val;
Johannes Berg's avatar
Johannes Berg committed
923

924
925
926
	assert_cfg80211_lock();

	mutex_lock(&reg_mutex);
927
	val = reg_request_cell_base(last_request);
928
	mutex_unlock(&reg_mutex);
Johannes Berg's avatar
Johannes Berg committed
929

930
	return val;
931
932
933
934
}

#ifdef CONFIG_CFG80211_CERTIFICATION_ONUS
/* Core specific check */
935
936
static enum reg_request_treatment
reg_ignore_cell_hint(struct regulatory_request *pending_request)
937
938
{
	if (!reg_num_devs_support_basehint)
939
		return REG_REQ_IGNORE;
940

Johannes Berg's avatar
Johannes Berg committed
941
942
	if (reg_request_cell_base(last_request) &&
	    !regdom_changes(pending_request->alpha2))
943
		return REG_REQ_ALREADY_SET;
Johannes Berg's avatar
Johannes Berg committed
944

945
	return REG_REQ_OK;
946
947
948
949
950
}

/* Device specific check */
static bool reg_dev_ignore_cell_hint(struct wiphy *wiphy)
{
Johannes Berg's avatar
Johannes Berg committed
951
	return !(wiphy->features & NL80211_FEATURE_CELL_BASE_REG_HINTS);
952
953
954
955
}
#else
static int reg_ignore_cell_hint(struct regulatory_request *pending_request)
{
956
	return REG_REQ_IGNORE;
957
}
Johannes Berg's avatar
Johannes Berg committed
958
959

static bool reg_dev_ignore_cell_hint(struct wiphy *wiphy)
960
961
962
963
964
965
{
	return true;
}
#endif


966
967
static bool ignore_reg_update(struct wiphy *wiphy,
			      enum nl80211_reg_initiator initiator)
968
{
969
	if (!last_request) {
Johannes Berg's avatar
Johannes Berg committed
970
		REG_DBG_PRINT("Ignoring regulatory request %s since last_request is not set\n",
971
			      reg_initiator_name(initiator));
972
		return true;
973
974
	}

975
	if (initiator == NL80211_REGDOM_SET_BY_CORE &&
976
	    wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) {
Johannes Berg's avatar
Johannes Berg committed
977
		REG_DBG_PRINT("Ignoring regulatory request %s since the driver uses its own custom regulatory domain\n",
978
			      reg_initiator_name(initiator));
979
		return true;
980
981
	}

982
983
984
985
	/*
	 * wiphy->regd will be set once the device has its own
	 * desired regulatory domain set
	 */
986
	if (wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY && !wiphy->regd &&
987
	    initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE &&
988
	    !is_world_regdom(last_request->alpha2)) {
Johannes Berg's avatar
Johannes Berg committed
989
		REG_DBG_PRINT("Ignoring regulatory request %s since the driver requires its own regulatory domain to be set first\n",
990
			      reg_initiator_name(initiator));
991
		return true;
992
993
	}

994
995
996
	if (reg_request_cell_base(last_request))
		return reg_dev_ignore_cell_hint(wiphy);

997
998
999
	return false;
}

Johannes Berg's avatar
Johannes Berg committed
1000
static void handle_reg_beacon(struct wiphy *wiphy, unsigned int chan_idx,
1001
1002
1003
1004
			      struct reg_beacon *reg_beacon)
{
	struct ieee80211_supported_band *sband;
	struct ieee80211_channel *chan;
1005
1006
	bool channel_changed = false;
	struct ieee80211_channel chan_before;
1007
1008
1009
1010
1011
1012
1013
1014
1015

	assert_cfg80211_lock();

	sband = wiphy->bands[reg_beacon->chan.band];
	chan = &sband->channels[chan_idx];

	if (likely(chan->center_freq != reg_beacon->chan.center_freq))
		return;

1016
1017
1018
1019
1020
	if (chan->beacon_found)
		return;

	chan->beacon_found = true;

1021
	if (wiphy->flags & WIPHY_FLAG_DISABLE_BEACON_HINTS)
1022
1023
		return;

1024
1025
1026
	chan_before.center_freq = chan->center_freq;
	chan_before.flags = chan->flags;

1027
	if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) {
1028
		chan->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
1029
		channel_changed = true;
1030
1031
	}

1032
	if (chan->flags & IEEE80211_CHAN_NO_IBSS) {
1033
		chan->flags &= ~IEEE80211_CHAN_NO_IBSS;
1034
		channel_changed = true;
1035
1036
	}

1037
1038
	if (channel_changed)
		nl80211_send_beacon_hint_event(wiphy, &chan_before, chan);
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
}

/*
 * Called when a scan on a wiphy finds a beacon on
 * new channel
 */
static void wiphy_update_new_beacon(struct wiphy *wiphy,
				    struct reg_beacon *reg_beacon)
{
	unsigned int i;
	struct ieee80211_supported_band *sband;

	assert_cfg80211_lock();

	if (!wiphy->bands[reg_beacon->chan.band])
		return;

	sband = wiphy->bands[reg_beacon->chan.band];

	for (i = 0; i < sband->n_channels; i++)
		handle_reg_beacon(wiphy, i, reg_beacon);
}

/*
 * Called upon reg changes or a new wiphy is added
 */
static void wiphy_update_beacon_reg(struct wiphy *wiphy)
{
	unsigned int i;
	struct ieee80211_supported_band *sband;
	struct reg_beacon *reg_beacon;

	assert_cfg80211_lock();

	list_for_each_entry(reg_beacon, &reg_beacon_list, list) {
		if (!wiphy->bands[reg_beacon->chan.band])
			continue;
		sband = wiphy->bands[reg_beacon->chan.band];
		for (i = 0; i < sband->n_channels; i++)
			handle_reg_beacon(wiphy, i, reg_beacon);
	}
}

static bool reg_is_world_roaming(struct wiphy *wiphy)
{
	if (is_world_regdom(cfg80211_regdomain->alpha2) ||
	    (wiphy->regd && is_world_regdom(wiphy->regd->alpha2)))
		return true;
1087
1088
	if (last_request &&
	    last_request->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE &&
1089
	    wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY)
1090
1091
1092
1093
1094
1095
1096
		return true;
	return false;
}

/* Reap the advantages of previously found beacons */
static void reg_process_beacons(struct wiphy *wiphy)
{