Linux Audio

Check our new training course

Loading...
v3.1
  1/*
  2 * Copyright (c) 2008-2009 Atheros Communications Inc.
  3 *
  4 * Permission to use, copy, modify, and/or distribute this software for any
  5 * purpose with or without fee is hereby granted, provided that the above
  6 * copyright notice and this permission notice appear in all copies.
  7 *
  8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 15 */
 16
 
 
 17#include <linux/kernel.h>
 
 18#include <net/cfg80211.h>
 19#include <net/mac80211.h>
 20#include "regd.h"
 21#include "regd_common.h"
 22
 
 
 23/*
 24 * This is a set of common rules used by our world regulatory domains.
 25 * We have 12 world regulatory domains. To save space we consolidate
 26 * the regulatory domains in 5 structures by frequency and change
 27 * the flags on our reg_notifier() on a case by case basis.
 28 */
 29
 30/* Only these channels all allow active scan on all world regulatory domains */
 31#define ATH9K_2GHZ_CH01_11	REG_RULE(2412-10, 2462+10, 40, 0, 20, 0)
 32
 33/* We enable active scan on these a case by case basis by regulatory domain */
 34#define ATH9K_2GHZ_CH12_13	REG_RULE(2467-10, 2472+10, 40, 0, 20,\
 35					NL80211_RRF_PASSIVE_SCAN)
 36#define ATH9K_2GHZ_CH14		REG_RULE(2484-10, 2484+10, 40, 0, 20,\
 37				NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM)
 38
 39/* We allow IBSS on these on a case by case basis by regulatory domain */
 40#define ATH9K_5GHZ_5150_5350	REG_RULE(5150-10, 5350+10, 40, 0, 30,\
 41				NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
 42#define ATH9K_5GHZ_5470_5850	REG_RULE(5470-10, 5850+10, 40, 0, 30,\
 43				NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
 44#define ATH9K_5GHZ_5725_5850	REG_RULE(5725-10, 5850+10, 40, 0, 30,\
 45				NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
 46
 47#define ATH9K_2GHZ_ALL		ATH9K_2GHZ_CH01_11, \
 48				ATH9K_2GHZ_CH12_13, \
 49				ATH9K_2GHZ_CH14
 50
 51#define ATH9K_5GHZ_ALL		ATH9K_5GHZ_5150_5350, \
 52				ATH9K_5GHZ_5470_5850
 53
 54/* This one skips what we call "mid band" */
 55#define ATH9K_5GHZ_NO_MIDBAND	ATH9K_5GHZ_5150_5350, \
 56				ATH9K_5GHZ_5725_5850
 57
 58/* Can be used for:
 59 * 0x60, 0x61, 0x62 */
 60static const struct ieee80211_regdomain ath_world_regdom_60_61_62 = {
 61	.n_reg_rules = 5,
 62	.alpha2 =  "99",
 63	.reg_rules = {
 64		ATH9K_2GHZ_ALL,
 65		ATH9K_5GHZ_ALL,
 66	}
 67};
 68
 69/* Can be used by 0x63 and 0x65 */
 70static const struct ieee80211_regdomain ath_world_regdom_63_65 = {
 71	.n_reg_rules = 4,
 72	.alpha2 =  "99",
 73	.reg_rules = {
 74		ATH9K_2GHZ_CH01_11,
 75		ATH9K_2GHZ_CH12_13,
 76		ATH9K_5GHZ_NO_MIDBAND,
 77	}
 78};
 79
 80/* Can be used by 0x64 only */
 81static const struct ieee80211_regdomain ath_world_regdom_64 = {
 82	.n_reg_rules = 3,
 83	.alpha2 =  "99",
 84	.reg_rules = {
 85		ATH9K_2GHZ_CH01_11,
 86		ATH9K_5GHZ_NO_MIDBAND,
 87	}
 88};
 89
 90/* Can be used by 0x66 and 0x69 */
 91static const struct ieee80211_regdomain ath_world_regdom_66_69 = {
 92	.n_reg_rules = 3,
 93	.alpha2 =  "99",
 94	.reg_rules = {
 95		ATH9K_2GHZ_CH01_11,
 96		ATH9K_5GHZ_ALL,
 97	}
 98};
 99
100/* Can be used by 0x67, 0x68, 0x6A and 0x6C */
101static const struct ieee80211_regdomain ath_world_regdom_67_68_6A_6C = {
102	.n_reg_rules = 4,
103	.alpha2 =  "99",
104	.reg_rules = {
105		ATH9K_2GHZ_CH01_11,
106		ATH9K_2GHZ_CH12_13,
107		ATH9K_5GHZ_ALL,
108	}
109};
110
111static inline bool is_wwr_sku(u16 regd)
112{
113	return ((regd & COUNTRY_ERD_FLAG) != COUNTRY_ERD_FLAG) &&
114		(((regd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) ||
115		(regd == WORLD));
116}
117
118static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg)
119{
120	return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG;
121}
122
123bool ath_is_world_regd(struct ath_regulatory *reg)
124{
125	return is_wwr_sku(ath_regd_get_eepromRD(reg));
126}
127EXPORT_SYMBOL(ath_is_world_regd);
128
129static const struct ieee80211_regdomain *ath_default_world_regdomain(void)
130{
131	/* this is the most restrictive */
132	return &ath_world_regdom_64;
133}
134
135static const struct
136ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg)
137{
138	switch (reg->regpair->regDmnEnum) {
139	case 0x60:
140	case 0x61:
141	case 0x62:
142		return &ath_world_regdom_60_61_62;
143	case 0x63:
144	case 0x65:
145		return &ath_world_regdom_63_65;
146	case 0x64:
147		return &ath_world_regdom_64;
148	case 0x66:
149	case 0x69:
150		return &ath_world_regdom_66_69;
151	case 0x67:
152	case 0x68:
153	case 0x6A:
154	case 0x6C:
155		return &ath_world_regdom_67_68_6A_6C;
156	default:
157		WARN_ON(1);
158		return ath_default_world_regdomain();
159	}
160}
161
162bool ath_is_49ghz_allowed(u16 regdomain)
163{
164	/* possibly more */
165	return regdomain == MKK9_MKKC;
166}
167EXPORT_SYMBOL(ath_is_49ghz_allowed);
168
169/* Frequency is one where radar detection is required */
170static bool ath_is_radar_freq(u16 center_freq)
171{
172	return (center_freq >= 5260 && center_freq <= 5700);
173}
174
175/*
176 * N.B: These exception rules do not apply radar freqs.
177 *
178 * - We enable adhoc (or beaconing) if allowed by 11d
179 * - We enable active scan if the channel is allowed by 11d
180 * - If no country IE has been processed and a we determine we have
181 *   received a beacon on a channel we can enable active scan and
182 *   adhoc (or beaconing).
183 */
184static void
185ath_reg_apply_beaconing_flags(struct wiphy *wiphy,
186			      enum nl80211_reg_initiator initiator)
187{
188	enum ieee80211_band band;
189	struct ieee80211_supported_band *sband;
190	const struct ieee80211_reg_rule *reg_rule;
191	struct ieee80211_channel *ch;
192	unsigned int i;
193	u32 bandwidth = 0;
194	int r;
195
196	for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
197
198		if (!wiphy->bands[band])
199			continue;
200
201		sband = wiphy->bands[band];
202
203		for (i = 0; i < sband->n_channels; i++) {
204
205			ch = &sband->channels[i];
206
207			if (ath_is_radar_freq(ch->center_freq) ||
208			    (ch->flags & IEEE80211_CHAN_RADAR))
209				continue;
210
211			if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
212				r = freq_reg_info(wiphy,
213						  ch->center_freq,
214						  bandwidth,
215						  &reg_rule);
216				if (r)
217					continue;
218				/*
219				 * If 11d had a rule for this channel ensure
220				 * we enable adhoc/beaconing if it allows us to
221				 * use it. Note that we would have disabled it
222				 * by applying our static world regdomain by
223				 * default during init, prior to calling our
224				 * regulatory_hint().
225				 */
226				if (!(reg_rule->flags &
227				    NL80211_RRF_NO_IBSS))
228					ch->flags &=
229					  ~IEEE80211_CHAN_NO_IBSS;
230				if (!(reg_rule->flags &
231				    NL80211_RRF_PASSIVE_SCAN))
232					ch->flags &=
233					  ~IEEE80211_CHAN_PASSIVE_SCAN;
234			} else {
235				if (ch->beacon_found)
236					ch->flags &= ~(IEEE80211_CHAN_NO_IBSS |
237					  IEEE80211_CHAN_PASSIVE_SCAN);
238			}
239		}
240	}
241
242}
243
244/* Allows active scan scan on Ch 12 and 13 */
245static void
246ath_reg_apply_active_scan_flags(struct wiphy *wiphy,
247				enum nl80211_reg_initiator initiator)
248{
249	struct ieee80211_supported_band *sband;
250	struct ieee80211_channel *ch;
251	const struct ieee80211_reg_rule *reg_rule;
252	u32 bandwidth = 0;
253	int r;
254
255	sband = wiphy->bands[IEEE80211_BAND_2GHZ];
 
 
256
257	/*
258	 * If no country IE has been received always enable active scan
259	 * on these channels. This is only done for specific regulatory SKUs
260	 */
261	if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {
262		ch = &sband->channels[11]; /* CH 12 */
263		if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
264			ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
265		ch = &sband->channels[12]; /* CH 13 */
266		if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
267			ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
268		return;
269	}
270
271	/*
272	 * If a country IE has been received check its rule for this
273	 * channel first before enabling active scan. The passive scan
274	 * would have been enforced by the initial processing of our
275	 * custom regulatory domain.
276	 */
277
278	ch = &sband->channels[11]; /* CH 12 */
279	r = freq_reg_info(wiphy, ch->center_freq, bandwidth, &reg_rule);
280	if (!r) {
281		if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
282			if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
283				ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
284	}
285
286	ch = &sband->channels[12]; /* CH 13 */
287	r = freq_reg_info(wiphy, ch->center_freq, bandwidth, &reg_rule);
288	if (!r) {
289		if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
290			if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
291				ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
292	}
293}
294
295/* Always apply Radar/DFS rules on freq range 5260 MHz - 5700 MHz */
296static void ath_reg_apply_radar_flags(struct wiphy *wiphy)
297{
298	struct ieee80211_supported_band *sband;
299	struct ieee80211_channel *ch;
300	unsigned int i;
301
302	if (!wiphy->bands[IEEE80211_BAND_5GHZ])
303		return;
304
305	sband = wiphy->bands[IEEE80211_BAND_5GHZ];
306
307	for (i = 0; i < sband->n_channels; i++) {
308		ch = &sband->channels[i];
309		if (!ath_is_radar_freq(ch->center_freq))
310			continue;
311		/* We always enable radar detection/DFS on this
312		 * frequency range. Additionally we also apply on
313		 * this frequency range:
314		 * - If STA mode does not yet have DFS supports disable
315		 *   active scanning
316		 * - If adhoc mode does not support DFS yet then
317		 *   disable adhoc in the frequency.
318		 * - If AP mode does not yet support radar detection/DFS
319		 *   do not allow AP mode
320		 */
321		if (!(ch->flags & IEEE80211_CHAN_DISABLED))
322			ch->flags |= IEEE80211_CHAN_RADAR |
323				     IEEE80211_CHAN_NO_IBSS |
324				     IEEE80211_CHAN_PASSIVE_SCAN;
325	}
326}
327
328static void ath_reg_apply_world_flags(struct wiphy *wiphy,
329				      enum nl80211_reg_initiator initiator,
330				      struct ath_regulatory *reg)
331{
332	switch (reg->regpair->regDmnEnum) {
333	case 0x60:
334	case 0x63:
335	case 0x66:
336	case 0x67:
337	case 0x6C:
338		ath_reg_apply_beaconing_flags(wiphy, initiator);
339		break;
340	case 0x68:
341		ath_reg_apply_beaconing_flags(wiphy, initiator);
342		ath_reg_apply_active_scan_flags(wiphy, initiator);
343		break;
344	}
345}
346
 
 
 
 
 
 
 
 
 
 
 
 
347int ath_reg_notifier_apply(struct wiphy *wiphy,
348			   struct regulatory_request *request,
349			   struct ath_regulatory *reg)
350{
 
 
 
 
351	/* We always apply this */
352	ath_reg_apply_radar_flags(wiphy);
353
354	/*
355	 * This would happen when we have sent a custom regulatory request
356	 * a world regulatory domain and the scheduler hasn't yet processed
357	 * any pending requests in the queue.
358	 */
359	if (!request)
360		return 0;
361
362	switch (request->initiator) {
363	case NL80211_REGDOM_SET_BY_DRIVER:
364	case NL80211_REGDOM_SET_BY_CORE:
 
 
 
 
 
 
 
 
 
 
 
365	case NL80211_REGDOM_SET_BY_USER:
366		break;
367	case NL80211_REGDOM_SET_BY_COUNTRY_IE:
368		if (ath_is_world_regd(reg))
369			ath_reg_apply_world_flags(wiphy, request->initiator,
370						  reg);
 
 
 
 
 
 
 
 
 
 
 
 
 
371		break;
372	}
373
374	return 0;
375}
376EXPORT_SYMBOL(ath_reg_notifier_apply);
377
378static bool ath_regd_is_eeprom_valid(struct ath_regulatory *reg)
379{
380	u16 rd = ath_regd_get_eepromRD(reg);
381	int i;
382
383	if (rd & COUNTRY_ERD_FLAG) {
384		/* EEPROM value is a country code */
385		u16 cc = rd & ~COUNTRY_ERD_FLAG;
386		printk(KERN_DEBUG
387		       "ath: EEPROM indicates we should expect "
388			"a country code\n");
389		for (i = 0; i < ARRAY_SIZE(allCountries); i++)
390			if (allCountries[i].countryCode == cc)
391				return true;
392	} else {
393		/* EEPROM value is a regpair value */
394		if (rd != CTRY_DEFAULT)
395			printk(KERN_DEBUG "ath: EEPROM indicates we "
396			       "should expect a direct regpair map\n");
397		for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++)
398			if (regDomainPairs[i].regDmnEnum == rd)
399				return true;
400	}
401	printk(KERN_DEBUG
402		 "ath: invalid regulatory domain/country code 0x%x\n", rd);
403	return false;
404}
405
406/* EEPROM country code to regpair mapping */
407static struct country_code_to_enum_rd*
408ath_regd_find_country(u16 countryCode)
409{
410	int i;
411
412	for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
413		if (allCountries[i].countryCode == countryCode)
414			return &allCountries[i];
415	}
416	return NULL;
417}
418
419/* EEPROM rd code to regpair mapping */
420static struct country_code_to_enum_rd*
421ath_regd_find_country_by_rd(int regdmn)
422{
423	int i;
424
425	for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
426		if (allCountries[i].regDmnEnum == regdmn)
427			return &allCountries[i];
428	}
429	return NULL;
430}
431
432/* Returns the map of the EEPROM set RD to a country code */
433static u16 ath_regd_get_default_country(u16 rd)
434{
435	if (rd & COUNTRY_ERD_FLAG) {
436		struct country_code_to_enum_rd *country = NULL;
437		u16 cc = rd & ~COUNTRY_ERD_FLAG;
438
439		country = ath_regd_find_country(cc);
440		if (country != NULL)
441			return cc;
442	}
443
444	return CTRY_DEFAULT;
445}
446
447static struct reg_dmn_pair_mapping*
448ath_get_regpair(int regdmn)
449{
450	int i;
451
452	if (regdmn == NO_ENUMRD)
453		return NULL;
454	for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) {
455		if (regDomainPairs[i].regDmnEnum == regdmn)
456			return &regDomainPairs[i];
457	}
458	return NULL;
459}
460
461static int
462ath_regd_init_wiphy(struct ath_regulatory *reg,
463		    struct wiphy *wiphy,
464		    int (*reg_notifier)(struct wiphy *wiphy,
465					struct regulatory_request *request))
466{
467	const struct ieee80211_regdomain *regd;
468
469	wiphy->reg_notifier = reg_notifier;
470	wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
471
472	if (ath_is_world_regd(reg)) {
473		/*
474		 * Anything applied here (prior to wiphy registration) gets
475		 * saved on the wiphy orig_* parameters
476		 */
477		regd = ath_world_regdomain(reg);
478		wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
479	} else {
480		/*
481		 * This gets applied in the case of the absence of CRDA,
482		 * it's our own custom world regulatory domain, similar to
483		 * cfg80211's but we enable passive scanning.
484		 */
485		regd = ath_default_world_regdomain();
486	}
487	wiphy_apply_custom_regulatory(wiphy, regd);
488	ath_reg_apply_radar_flags(wiphy);
489	ath_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg);
490	return 0;
491}
492
493/*
494 * Some users have reported their EEPROM programmed with
495 * 0x8000 set, this is not a supported regulatory domain
496 * but since we have more than one user with it we need
497 * a solution for them. We default to 0x64, which is the
498 * default Atheros world regulatory domain.
499 */
500static void ath_regd_sanitize(struct ath_regulatory *reg)
501{
502	if (reg->current_rd != COUNTRY_ERD_FLAG)
503		return;
504	printk(KERN_DEBUG "ath: EEPROM regdomain sanitized\n");
505	reg->current_rd = 0x64;
506}
507
508int
509ath_regd_init(struct ath_regulatory *reg,
510	      struct wiphy *wiphy,
511	      int (*reg_notifier)(struct wiphy *wiphy,
512				  struct regulatory_request *request))
513{
514	struct country_code_to_enum_rd *country = NULL;
515	u16 regdmn;
516
517	if (!reg)
518		return -EINVAL;
519
520	ath_regd_sanitize(reg);
521
522	printk(KERN_DEBUG "ath: EEPROM regdomain: 0x%0x\n", reg->current_rd);
523
524	if (!ath_regd_is_eeprom_valid(reg)) {
525		printk(KERN_ERR "ath: Invalid EEPROM contents\n");
526		return -EINVAL;
527	}
528
529	regdmn = ath_regd_get_eepromRD(reg);
530	reg->country_code = ath_regd_get_default_country(regdmn);
531
532	if (reg->country_code == CTRY_DEFAULT &&
533	    regdmn == CTRY_DEFAULT) {
534		printk(KERN_DEBUG "ath: EEPROM indicates default "
535		       "country code should be used\n");
536		reg->country_code = CTRY_UNITED_STATES;
537	}
538
539	if (reg->country_code == CTRY_DEFAULT) {
540		country = NULL;
541	} else {
542		printk(KERN_DEBUG "ath: doing EEPROM country->regdmn "
543		       "map search\n");
544		country = ath_regd_find_country(reg->country_code);
545		if (country == NULL) {
546			printk(KERN_DEBUG
547				"ath: no valid country maps found for "
548				"country code: 0x%0x\n",
549				reg->country_code);
550			return -EINVAL;
551		} else {
552			regdmn = country->regDmnEnum;
553			printk(KERN_DEBUG "ath: country maps to "
554			       "regdmn code: 0x%0x\n",
555			       regdmn);
556		}
557	}
558
559	reg->regpair = ath_get_regpair(regdmn);
560
561	if (!reg->regpair) {
562		printk(KERN_DEBUG "ath: "
563			"No regulatory domain pair found, cannot continue\n");
564		return -EINVAL;
565	}
566
567	if (!country)
568		country = ath_regd_find_country_by_rd(regdmn);
569
570	if (country) {
571		reg->alpha2[0] = country->isoName[0];
572		reg->alpha2[1] = country->isoName[1];
573	} else {
574		reg->alpha2[0] = '0';
575		reg->alpha2[1] = '0';
576	}
577
578	printk(KERN_DEBUG "ath: Country alpha2 being used: %c%c\n",
579		reg->alpha2[0], reg->alpha2[1]);
580	printk(KERN_DEBUG "ath: Regpair used: 0x%0x\n",
581		reg->regpair->regDmnEnum);
582
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
583	ath_regd_init_wiphy(reg, wiphy, reg_notifier);
 
584	return 0;
585}
586EXPORT_SYMBOL(ath_regd_init);
587
588u32 ath_regd_get_band_ctl(struct ath_regulatory *reg,
589			  enum ieee80211_band band)
590{
591	if (!reg->regpair ||
592	    (reg->country_code == CTRY_DEFAULT &&
593	     is_wwr_sku(ath_regd_get_eepromRD(reg)))) {
594		return SD_NO_CTL;
595	}
596
597	switch (band) {
598	case IEEE80211_BAND_2GHZ:
599		return reg->regpair->reg_2ghz_ctl;
600	case IEEE80211_BAND_5GHZ:
601		return reg->regpair->reg_5ghz_ctl;
602	default:
603		return NO_CTL;
604	}
605}
606EXPORT_SYMBOL(ath_regd_get_band_ctl);
v3.5.6
  1/*
  2 * Copyright (c) 2008-2009 Atheros Communications Inc.
  3 *
  4 * Permission to use, copy, modify, and/or distribute this software for any
  5 * purpose with or without fee is hereby granted, provided that the above
  6 * copyright notice and this permission notice appear in all copies.
  7 *
  8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 15 */
 16
 17#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 18
 19#include <linux/kernel.h>
 20#include <linux/export.h>
 21#include <net/cfg80211.h>
 22#include <net/mac80211.h>
 23#include "regd.h"
 24#include "regd_common.h"
 25
 26static int __ath_regd_init(struct ath_regulatory *reg);
 27
 28/*
 29 * This is a set of common rules used by our world regulatory domains.
 30 * We have 12 world regulatory domains. To save space we consolidate
 31 * the regulatory domains in 5 structures by frequency and change
 32 * the flags on our reg_notifier() on a case by case basis.
 33 */
 34
 35/* Only these channels all allow active scan on all world regulatory domains */
 36#define ATH9K_2GHZ_CH01_11	REG_RULE(2412-10, 2462+10, 40, 0, 20, 0)
 37
 38/* We enable active scan on these a case by case basis by regulatory domain */
 39#define ATH9K_2GHZ_CH12_13	REG_RULE(2467-10, 2472+10, 40, 0, 20,\
 40					NL80211_RRF_PASSIVE_SCAN)
 41#define ATH9K_2GHZ_CH14		REG_RULE(2484-10, 2484+10, 40, 0, 20,\
 42				NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM)
 43
 44/* We allow IBSS on these on a case by case basis by regulatory domain */
 45#define ATH9K_5GHZ_5150_5350	REG_RULE(5150-10, 5350+10, 40, 0, 30,\
 46				NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
 47#define ATH9K_5GHZ_5470_5850	REG_RULE(5470-10, 5850+10, 40, 0, 30,\
 48				NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
 49#define ATH9K_5GHZ_5725_5850	REG_RULE(5725-10, 5850+10, 40, 0, 30,\
 50				NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
 51
 52#define ATH9K_2GHZ_ALL		ATH9K_2GHZ_CH01_11, \
 53				ATH9K_2GHZ_CH12_13, \
 54				ATH9K_2GHZ_CH14
 55
 56#define ATH9K_5GHZ_ALL		ATH9K_5GHZ_5150_5350, \
 57				ATH9K_5GHZ_5470_5850
 58
 59/* This one skips what we call "mid band" */
 60#define ATH9K_5GHZ_NO_MIDBAND	ATH9K_5GHZ_5150_5350, \
 61				ATH9K_5GHZ_5725_5850
 62
 63/* Can be used for:
 64 * 0x60, 0x61, 0x62 */
 65static const struct ieee80211_regdomain ath_world_regdom_60_61_62 = {
 66	.n_reg_rules = 5,
 67	.alpha2 =  "99",
 68	.reg_rules = {
 69		ATH9K_2GHZ_ALL,
 70		ATH9K_5GHZ_ALL,
 71	}
 72};
 73
 74/* Can be used by 0x63 and 0x65 */
 75static const struct ieee80211_regdomain ath_world_regdom_63_65 = {
 76	.n_reg_rules = 4,
 77	.alpha2 =  "99",
 78	.reg_rules = {
 79		ATH9K_2GHZ_CH01_11,
 80		ATH9K_2GHZ_CH12_13,
 81		ATH9K_5GHZ_NO_MIDBAND,
 82	}
 83};
 84
 85/* Can be used by 0x64 only */
 86static const struct ieee80211_regdomain ath_world_regdom_64 = {
 87	.n_reg_rules = 3,
 88	.alpha2 =  "99",
 89	.reg_rules = {
 90		ATH9K_2GHZ_CH01_11,
 91		ATH9K_5GHZ_NO_MIDBAND,
 92	}
 93};
 94
 95/* Can be used by 0x66 and 0x69 */
 96static const struct ieee80211_regdomain ath_world_regdom_66_69 = {
 97	.n_reg_rules = 3,
 98	.alpha2 =  "99",
 99	.reg_rules = {
100		ATH9K_2GHZ_CH01_11,
101		ATH9K_5GHZ_ALL,
102	}
103};
104
105/* Can be used by 0x67, 0x68, 0x6A and 0x6C */
106static const struct ieee80211_regdomain ath_world_regdom_67_68_6A_6C = {
107	.n_reg_rules = 4,
108	.alpha2 =  "99",
109	.reg_rules = {
110		ATH9K_2GHZ_CH01_11,
111		ATH9K_2GHZ_CH12_13,
112		ATH9K_5GHZ_ALL,
113	}
114};
115
116static inline bool is_wwr_sku(u16 regd)
117{
118	return ((regd & COUNTRY_ERD_FLAG) != COUNTRY_ERD_FLAG) &&
119		(((regd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) ||
120		(regd == WORLD));
121}
122
123static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg)
124{
125	return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG;
126}
127
128bool ath_is_world_regd(struct ath_regulatory *reg)
129{
130	return is_wwr_sku(ath_regd_get_eepromRD(reg));
131}
132EXPORT_SYMBOL(ath_is_world_regd);
133
134static const struct ieee80211_regdomain *ath_default_world_regdomain(void)
135{
136	/* this is the most restrictive */
137	return &ath_world_regdom_64;
138}
139
140static const struct
141ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg)
142{
143	switch (reg->regpair->regDmnEnum) {
144	case 0x60:
145	case 0x61:
146	case 0x62:
147		return &ath_world_regdom_60_61_62;
148	case 0x63:
149	case 0x65:
150		return &ath_world_regdom_63_65;
151	case 0x64:
152		return &ath_world_regdom_64;
153	case 0x66:
154	case 0x69:
155		return &ath_world_regdom_66_69;
156	case 0x67:
157	case 0x68:
158	case 0x6A:
159	case 0x6C:
160		return &ath_world_regdom_67_68_6A_6C;
161	default:
162		WARN_ON(1);
163		return ath_default_world_regdomain();
164	}
165}
166
167bool ath_is_49ghz_allowed(u16 regdomain)
168{
169	/* possibly more */
170	return regdomain == MKK9_MKKC;
171}
172EXPORT_SYMBOL(ath_is_49ghz_allowed);
173
174/* Frequency is one where radar detection is required */
175static bool ath_is_radar_freq(u16 center_freq)
176{
177	return (center_freq >= 5260 && center_freq <= 5700);
178}
179
180/*
181 * N.B: These exception rules do not apply radar freqs.
182 *
183 * - We enable adhoc (or beaconing) if allowed by 11d
184 * - We enable active scan if the channel is allowed by 11d
185 * - If no country IE has been processed and a we determine we have
186 *   received a beacon on a channel we can enable active scan and
187 *   adhoc (or beaconing).
188 */
189static void
190ath_reg_apply_beaconing_flags(struct wiphy *wiphy,
191			      enum nl80211_reg_initiator initiator)
192{
193	enum ieee80211_band band;
194	struct ieee80211_supported_band *sband;
195	const struct ieee80211_reg_rule *reg_rule;
196	struct ieee80211_channel *ch;
197	unsigned int i;
198	u32 bandwidth = 0;
199	int r;
200
201	for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
202
203		if (!wiphy->bands[band])
204			continue;
205
206		sband = wiphy->bands[band];
207
208		for (i = 0; i < sband->n_channels; i++) {
209
210			ch = &sband->channels[i];
211
212			if (ath_is_radar_freq(ch->center_freq) ||
213			    (ch->flags & IEEE80211_CHAN_RADAR))
214				continue;
215
216			if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
217				r = freq_reg_info(wiphy,
218						  ch->center_freq,
219						  bandwidth,
220						  &reg_rule);
221				if (r)
222					continue;
223				/*
224				 * If 11d had a rule for this channel ensure
225				 * we enable adhoc/beaconing if it allows us to
226				 * use it. Note that we would have disabled it
227				 * by applying our static world regdomain by
228				 * default during init, prior to calling our
229				 * regulatory_hint().
230				 */
231				if (!(reg_rule->flags &
232				    NL80211_RRF_NO_IBSS))
233					ch->flags &=
234					  ~IEEE80211_CHAN_NO_IBSS;
235				if (!(reg_rule->flags &
236				    NL80211_RRF_PASSIVE_SCAN))
237					ch->flags &=
238					  ~IEEE80211_CHAN_PASSIVE_SCAN;
239			} else {
240				if (ch->beacon_found)
241					ch->flags &= ~(IEEE80211_CHAN_NO_IBSS |
242					  IEEE80211_CHAN_PASSIVE_SCAN);
243			}
244		}
245	}
246
247}
248
249/* Allows active scan scan on Ch 12 and 13 */
250static void
251ath_reg_apply_active_scan_flags(struct wiphy *wiphy,
252				enum nl80211_reg_initiator initiator)
253{
254	struct ieee80211_supported_band *sband;
255	struct ieee80211_channel *ch;
256	const struct ieee80211_reg_rule *reg_rule;
257	u32 bandwidth = 0;
258	int r;
259
260	sband = wiphy->bands[IEEE80211_BAND_2GHZ];
261	if (!sband)
262		return;
263
264	/*
265	 * If no country IE has been received always enable active scan
266	 * on these channels. This is only done for specific regulatory SKUs
267	 */
268	if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {
269		ch = &sband->channels[11]; /* CH 12 */
270		if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
271			ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
272		ch = &sband->channels[12]; /* CH 13 */
273		if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
274			ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
275		return;
276	}
277
278	/*
279	 * If a country IE has been received check its rule for this
280	 * channel first before enabling active scan. The passive scan
281	 * would have been enforced by the initial processing of our
282	 * custom regulatory domain.
283	 */
284
285	ch = &sband->channels[11]; /* CH 12 */
286	r = freq_reg_info(wiphy, ch->center_freq, bandwidth, &reg_rule);
287	if (!r) {
288		if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
289			if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
290				ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
291	}
292
293	ch = &sband->channels[12]; /* CH 13 */
294	r = freq_reg_info(wiphy, ch->center_freq, bandwidth, &reg_rule);
295	if (!r) {
296		if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
297			if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
298				ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
299	}
300}
301
302/* Always apply Radar/DFS rules on freq range 5260 MHz - 5700 MHz */
303static void ath_reg_apply_radar_flags(struct wiphy *wiphy)
304{
305	struct ieee80211_supported_band *sband;
306	struct ieee80211_channel *ch;
307	unsigned int i;
308
309	if (!wiphy->bands[IEEE80211_BAND_5GHZ])
310		return;
311
312	sband = wiphy->bands[IEEE80211_BAND_5GHZ];
313
314	for (i = 0; i < sband->n_channels; i++) {
315		ch = &sband->channels[i];
316		if (!ath_is_radar_freq(ch->center_freq))
317			continue;
318		/* We always enable radar detection/DFS on this
319		 * frequency range. Additionally we also apply on
320		 * this frequency range:
321		 * - If STA mode does not yet have DFS supports disable
322		 *   active scanning
323		 * - If adhoc mode does not support DFS yet then
324		 *   disable adhoc in the frequency.
325		 * - If AP mode does not yet support radar detection/DFS
326		 *   do not allow AP mode
327		 */
328		if (!(ch->flags & IEEE80211_CHAN_DISABLED))
329			ch->flags |= IEEE80211_CHAN_RADAR |
330				     IEEE80211_CHAN_NO_IBSS |
331				     IEEE80211_CHAN_PASSIVE_SCAN;
332	}
333}
334
335static void ath_reg_apply_world_flags(struct wiphy *wiphy,
336				      enum nl80211_reg_initiator initiator,
337				      struct ath_regulatory *reg)
338{
339	switch (reg->regpair->regDmnEnum) {
340	case 0x60:
341	case 0x63:
342	case 0x66:
343	case 0x67:
344	case 0x6C:
345		ath_reg_apply_beaconing_flags(wiphy, initiator);
346		break;
347	case 0x68:
348		ath_reg_apply_beaconing_flags(wiphy, initiator);
349		ath_reg_apply_active_scan_flags(wiphy, initiator);
350		break;
351	}
352}
353
354static u16 ath_regd_find_country_by_name(char *alpha2)
355{
356	unsigned int i;
357
358	for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
359		if (!memcmp(allCountries[i].isoName, alpha2, 2))
360			return allCountries[i].countryCode;
361	}
362
363	return -1;
364}
365
366int ath_reg_notifier_apply(struct wiphy *wiphy,
367			   struct regulatory_request *request,
368			   struct ath_regulatory *reg)
369{
370	struct ath_common *common = container_of(reg, struct ath_common,
371						 regulatory);
372	u16 country_code;
373
374	/* We always apply this */
375	ath_reg_apply_radar_flags(wiphy);
376
377	/*
378	 * This would happen when we have sent a custom regulatory request
379	 * a world regulatory domain and the scheduler hasn't yet processed
380	 * any pending requests in the queue.
381	 */
382	if (!request)
383		return 0;
384
385	switch (request->initiator) {
 
386	case NL80211_REGDOM_SET_BY_CORE:
387		/*
388		 * If common->reg_world_copy is world roaming it means we *were*
389		 * world roaming... so we now have to restore that data.
390		 */
391		if (!ath_is_world_regd(&common->reg_world_copy))
392			break;
393
394		memcpy(reg, &common->reg_world_copy,
395		       sizeof(struct ath_regulatory));
396		break;
397	case NL80211_REGDOM_SET_BY_DRIVER:
398	case NL80211_REGDOM_SET_BY_USER:
399		break;
400	case NL80211_REGDOM_SET_BY_COUNTRY_IE:
401		if (!ath_is_world_regd(reg))
402			break;
403
404		country_code = ath_regd_find_country_by_name(request->alpha2);
405		if (country_code == (u16) -1)
406			break;
407
408		reg->current_rd = COUNTRY_ERD_FLAG;
409		reg->current_rd |= country_code;
410
411		printk(KERN_DEBUG "ath: regdomain 0x%0x updated by CountryIE\n",
412			reg->current_rd);
413		__ath_regd_init(reg);
414
415		ath_reg_apply_world_flags(wiphy, request->initiator, reg);
416
417		break;
418	}
419
420	return 0;
421}
422EXPORT_SYMBOL(ath_reg_notifier_apply);
423
424static bool ath_regd_is_eeprom_valid(struct ath_regulatory *reg)
425{
426	u16 rd = ath_regd_get_eepromRD(reg);
427	int i;
428
429	if (rd & COUNTRY_ERD_FLAG) {
430		/* EEPROM value is a country code */
431		u16 cc = rd & ~COUNTRY_ERD_FLAG;
432		printk(KERN_DEBUG
433		       "ath: EEPROM indicates we should expect "
434			"a country code\n");
435		for (i = 0; i < ARRAY_SIZE(allCountries); i++)
436			if (allCountries[i].countryCode == cc)
437				return true;
438	} else {
439		/* EEPROM value is a regpair value */
440		if (rd != CTRY_DEFAULT)
441			printk(KERN_DEBUG "ath: EEPROM indicates we "
442			       "should expect a direct regpair map\n");
443		for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++)
444			if (regDomainPairs[i].regDmnEnum == rd)
445				return true;
446	}
447	printk(KERN_DEBUG
448		 "ath: invalid regulatory domain/country code 0x%x\n", rd);
449	return false;
450}
451
452/* EEPROM country code to regpair mapping */
453static struct country_code_to_enum_rd*
454ath_regd_find_country(u16 countryCode)
455{
456	int i;
457
458	for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
459		if (allCountries[i].countryCode == countryCode)
460			return &allCountries[i];
461	}
462	return NULL;
463}
464
465/* EEPROM rd code to regpair mapping */
466static struct country_code_to_enum_rd*
467ath_regd_find_country_by_rd(int regdmn)
468{
469	int i;
470
471	for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
472		if (allCountries[i].regDmnEnum == regdmn)
473			return &allCountries[i];
474	}
475	return NULL;
476}
477
478/* Returns the map of the EEPROM set RD to a country code */
479static u16 ath_regd_get_default_country(u16 rd)
480{
481	if (rd & COUNTRY_ERD_FLAG) {
482		struct country_code_to_enum_rd *country = NULL;
483		u16 cc = rd & ~COUNTRY_ERD_FLAG;
484
485		country = ath_regd_find_country(cc);
486		if (country != NULL)
487			return cc;
488	}
489
490	return CTRY_DEFAULT;
491}
492
493static struct reg_dmn_pair_mapping*
494ath_get_regpair(int regdmn)
495{
496	int i;
497
498	if (regdmn == NO_ENUMRD)
499		return NULL;
500	for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) {
501		if (regDomainPairs[i].regDmnEnum == regdmn)
502			return &regDomainPairs[i];
503	}
504	return NULL;
505}
506
507static int
508ath_regd_init_wiphy(struct ath_regulatory *reg,
509		    struct wiphy *wiphy,
510		    int (*reg_notifier)(struct wiphy *wiphy,
511					struct regulatory_request *request))
512{
513	const struct ieee80211_regdomain *regd;
514
515	wiphy->reg_notifier = reg_notifier;
516	wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
517
518	if (ath_is_world_regd(reg)) {
519		/*
520		 * Anything applied here (prior to wiphy registration) gets
521		 * saved on the wiphy orig_* parameters
522		 */
523		regd = ath_world_regdomain(reg);
524		wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
525	} else {
526		/*
527		 * This gets applied in the case of the absence of CRDA,
528		 * it's our own custom world regulatory domain, similar to
529		 * cfg80211's but we enable passive scanning.
530		 */
531		regd = ath_default_world_regdomain();
532	}
533	wiphy_apply_custom_regulatory(wiphy, regd);
534	ath_reg_apply_radar_flags(wiphy);
535	ath_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg);
536	return 0;
537}
538
539/*
540 * Some users have reported their EEPROM programmed with
541 * 0x8000 set, this is not a supported regulatory domain
542 * but since we have more than one user with it we need
543 * a solution for them. We default to 0x64, which is the
544 * default Atheros world regulatory domain.
545 */
546static void ath_regd_sanitize(struct ath_regulatory *reg)
547{
548	if (reg->current_rd != COUNTRY_ERD_FLAG)
549		return;
550	printk(KERN_DEBUG "ath: EEPROM regdomain sanitized\n");
551	reg->current_rd = 0x64;
552}
553
554static int __ath_regd_init(struct ath_regulatory *reg)
 
 
 
 
555{
556	struct country_code_to_enum_rd *country = NULL;
557	u16 regdmn;
558
559	if (!reg)
560		return -EINVAL;
561
562	ath_regd_sanitize(reg);
563
564	printk(KERN_DEBUG "ath: EEPROM regdomain: 0x%0x\n", reg->current_rd);
565
566	if (!ath_regd_is_eeprom_valid(reg)) {
567		pr_err("Invalid EEPROM contents\n");
568		return -EINVAL;
569	}
570
571	regdmn = ath_regd_get_eepromRD(reg);
572	reg->country_code = ath_regd_get_default_country(regdmn);
573
574	if (reg->country_code == CTRY_DEFAULT &&
575	    regdmn == CTRY_DEFAULT) {
576		printk(KERN_DEBUG "ath: EEPROM indicates default "
577		       "country code should be used\n");
578		reg->country_code = CTRY_UNITED_STATES;
579	}
580
581	if (reg->country_code == CTRY_DEFAULT) {
582		country = NULL;
583	} else {
584		printk(KERN_DEBUG "ath: doing EEPROM country->regdmn "
585		       "map search\n");
586		country = ath_regd_find_country(reg->country_code);
587		if (country == NULL) {
588			printk(KERN_DEBUG
589				"ath: no valid country maps found for "
590				"country code: 0x%0x\n",
591				reg->country_code);
592			return -EINVAL;
593		} else {
594			regdmn = country->regDmnEnum;
595			printk(KERN_DEBUG "ath: country maps to "
596			       "regdmn code: 0x%0x\n",
597			       regdmn);
598		}
599	}
600
601	reg->regpair = ath_get_regpair(regdmn);
602
603	if (!reg->regpair) {
604		printk(KERN_DEBUG "ath: "
605			"No regulatory domain pair found, cannot continue\n");
606		return -EINVAL;
607	}
608
609	if (!country)
610		country = ath_regd_find_country_by_rd(regdmn);
611
612	if (country) {
613		reg->alpha2[0] = country->isoName[0];
614		reg->alpha2[1] = country->isoName[1];
615	} else {
616		reg->alpha2[0] = '0';
617		reg->alpha2[1] = '0';
618	}
619
620	printk(KERN_DEBUG "ath: Country alpha2 being used: %c%c\n",
621		reg->alpha2[0], reg->alpha2[1]);
622	printk(KERN_DEBUG "ath: Regpair used: 0x%0x\n",
623		reg->regpair->regDmnEnum);
624
625	return 0;
626}
627
628int
629ath_regd_init(struct ath_regulatory *reg,
630	      struct wiphy *wiphy,
631	      int (*reg_notifier)(struct wiphy *wiphy,
632				  struct regulatory_request *request))
633{
634	struct ath_common *common = container_of(reg, struct ath_common,
635						 regulatory);
636	int r;
637
638	r = __ath_regd_init(reg);
639	if (r)
640		return r;
641
642	if (ath_is_world_regd(reg))
643		memcpy(&common->reg_world_copy, reg,
644		       sizeof(struct ath_regulatory));
645
646	ath_regd_init_wiphy(reg, wiphy, reg_notifier);
647
648	return 0;
649}
650EXPORT_SYMBOL(ath_regd_init);
651
652u32 ath_regd_get_band_ctl(struct ath_regulatory *reg,
653			  enum ieee80211_band band)
654{
655	if (!reg->regpair ||
656	    (reg->country_code == CTRY_DEFAULT &&
657	     is_wwr_sku(ath_regd_get_eepromRD(reg)))) {
658		return SD_NO_CTL;
659	}
660
661	switch (band) {
662	case IEEE80211_BAND_2GHZ:
663		return reg->regpair->reg_2ghz_ctl;
664	case IEEE80211_BAND_5GHZ:
665		return reg->regpair->reg_5ghz_ctl;
666	default:
667		return NO_CTL;
668	}
669}
670EXPORT_SYMBOL(ath_regd_get_band_ctl);