| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | /******************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2012-01-07 20:46:42 -06:00
										 |  |  |  * Copyright(c) 2009-2012  Realtek Corporation. | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or modify it | 
					
						
							|  |  |  |  * under the terms of version 2 of the GNU General Public License as | 
					
						
							|  |  |  |  * published by the Free Software Foundation. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, but WITHOUT | 
					
						
							|  |  |  |  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 
					
						
							|  |  |  |  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for | 
					
						
							|  |  |  |  * more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License along with | 
					
						
							|  |  |  |  * this program; if not, write to the Free Software Foundation, Inc., | 
					
						
							|  |  |  |  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The full GNU General Public License is included in this distribution in the | 
					
						
							|  |  |  |  * file called LICENSE. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Contact Information: | 
					
						
							|  |  |  |  * wlanfae <wlanfae@realtek.com> | 
					
						
							|  |  |  |  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | 
					
						
							|  |  |  |  * Hsinchu 300, Taiwan. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Larry Finger <Larry.Finger@lwfinger.net> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *****************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "wifi.h"
 | 
					
						
							|  |  |  | #include "regd.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct country_code_to_enum_rd allCountries[] = { | 
					
						
							|  |  |  | 	{COUNTRY_CODE_FCC, "US"}, | 
					
						
							|  |  |  | 	{COUNTRY_CODE_IC, "US"}, | 
					
						
							|  |  |  | 	{COUNTRY_CODE_ETSI, "EC"}, | 
					
						
							|  |  |  | 	{COUNTRY_CODE_SPAIN, "EC"}, | 
					
						
							|  |  |  | 	{COUNTRY_CODE_FRANCE, "EC"}, | 
					
						
							|  |  |  | 	{COUNTRY_CODE_MKK, "JP"}, | 
					
						
							|  |  |  | 	{COUNTRY_CODE_MKK1, "JP"}, | 
					
						
							|  |  |  | 	{COUNTRY_CODE_ISRAEL, "EC"}, | 
					
						
							|  |  |  | 	{COUNTRY_CODE_TELEC, "JP"}, | 
					
						
							|  |  |  | 	{COUNTRY_CODE_MIC, "JP"}, | 
					
						
							|  |  |  | 	{COUNTRY_CODE_GLOBAL_DOMAIN, "JP"}, | 
					
						
							|  |  |  | 	{COUNTRY_CODE_WORLD_WIDE_13, "EC"}, | 
					
						
							|  |  |  | 	{COUNTRY_CODE_TELEC_NETGEAR, "EC"}, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  *Only these channels all allow active | 
					
						
							|  |  |  |  *scan on all world regulatory domains | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #define RTL819x_2GHZ_CH01_11	\
 | 
					
						
							|  |  |  | 	REG_RULE(2412-10, 2462+10, 40, 0, 20, 0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  *We enable active scan on these a case | 
					
						
							|  |  |  |  *by case basis by regulatory domain | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #define RTL819x_2GHZ_CH12_13	\
 | 
					
						
							|  |  |  | 	REG_RULE(2467-10, 2472+10, 40, 0, 20,\ | 
					
						
							| 
									
										
										
										
											2013-10-21 19:22:25 +02:00
										 |  |  | 		 NL80211_RRF_NO_IR) | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define RTL819x_2GHZ_CH14	\
 | 
					
						
							|  |  |  | 	REG_RULE(2484-10, 2484+10, 40, 0, 20, \ | 
					
						
							| 
									
										
										
										
											2013-10-21 19:22:25 +02:00
										 |  |  | 		 NL80211_RRF_NO_IR | NL80211_RRF_NO_OFDM) | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-25 12:53:24 -05:00
										 |  |  | /* 5G chan 36 - chan 64*/ | 
					
						
							|  |  |  | #define RTL819x_5GHZ_5150_5350	\
 | 
					
						
							|  |  |  | 	REG_RULE(5150-10, 5350+10, 40, 0, 30, \ | 
					
						
							| 
									
										
										
										
											2013-10-21 19:22:25 +02:00
										 |  |  | 		 NL80211_RRF_NO_IR) | 
					
						
							| 
									
										
										
										
											2011-04-25 12:53:24 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* 5G chan 100 - chan 165*/ | 
					
						
							|  |  |  | #define RTL819x_5GHZ_5470_5850	\
 | 
					
						
							|  |  |  | 	REG_RULE(5470-10, 5850+10, 40, 0, 30, \ | 
					
						
							| 
									
										
										
										
											2013-10-21 19:22:25 +02:00
										 |  |  | 		 NL80211_RRF_NO_IR) | 
					
						
							| 
									
										
										
										
											2011-04-25 12:53:24 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* 5G chan 149 - chan 165*/ | 
					
						
							|  |  |  | #define RTL819x_5GHZ_5725_5850	\
 | 
					
						
							|  |  |  | 	REG_RULE(5725-10, 5850+10, 40, 0, 30, \ | 
					
						
							| 
									
										
										
										
											2013-10-21 19:22:25 +02:00
										 |  |  | 		 NL80211_RRF_NO_IR) | 
					
						
							| 
									
										
										
										
											2011-04-25 12:53:24 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define RTL819x_5GHZ_ALL	\
 | 
					
						
							|  |  |  | 	(RTL819x_5GHZ_5150_5350, RTL819x_5GHZ_5470_5850) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | static const struct ieee80211_regdomain rtl_regdom_11 = { | 
					
						
							|  |  |  | 	.n_reg_rules = 1, | 
					
						
							|  |  |  | 	.alpha2 = "99", | 
					
						
							|  |  |  | 	.reg_rules = { | 
					
						
							|  |  |  | 		      RTL819x_2GHZ_CH01_11, | 
					
						
							| 
									
										
										
										
											2011-04-25 12:53:24 -05:00
										 |  |  | 		      } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const struct ieee80211_regdomain rtl_regdom_12_13 = { | 
					
						
							|  |  |  | 	.n_reg_rules = 2, | 
					
						
							|  |  |  | 	.alpha2 = "99", | 
					
						
							|  |  |  | 	.reg_rules = { | 
					
						
							|  |  |  | 		      RTL819x_2GHZ_CH01_11, | 
					
						
							|  |  |  | 			  RTL819x_2GHZ_CH12_13, | 
					
						
							|  |  |  | 		      } | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-25 12:53:24 -05:00
										 |  |  | static const struct ieee80211_regdomain rtl_regdom_no_midband = { | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | 	.n_reg_rules = 3, | 
					
						
							|  |  |  | 	.alpha2 = "99", | 
					
						
							|  |  |  | 	.reg_rules = { | 
					
						
							|  |  |  | 		      RTL819x_2GHZ_CH01_11, | 
					
						
							| 
									
										
										
										
											2011-04-25 12:53:24 -05:00
										 |  |  | 			  RTL819x_5GHZ_5150_5350, | 
					
						
							|  |  |  | 			  RTL819x_5GHZ_5725_5850, | 
					
						
							|  |  |  | 		      } | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-25 12:53:24 -05:00
										 |  |  | static const struct ieee80211_regdomain rtl_regdom_60_64 = { | 
					
						
							|  |  |  | 	.n_reg_rules = 3, | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | 	.alpha2 = "99", | 
					
						
							|  |  |  | 	.reg_rules = { | 
					
						
							|  |  |  | 		      RTL819x_2GHZ_CH01_11, | 
					
						
							| 
									
										
										
										
											2011-04-25 12:53:24 -05:00
										 |  |  | 			  RTL819x_2GHZ_CH12_13, | 
					
						
							|  |  |  | 			  RTL819x_5GHZ_5725_5850, | 
					
						
							|  |  |  | 		      } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const struct ieee80211_regdomain rtl_regdom_14_60_64 = { | 
					
						
							|  |  |  | 	.n_reg_rules = 4, | 
					
						
							|  |  |  | 	.alpha2 = "99", | 
					
						
							|  |  |  | 	.reg_rules = { | 
					
						
							|  |  |  | 		      RTL819x_2GHZ_CH01_11, | 
					
						
							|  |  |  | 			  RTL819x_2GHZ_CH12_13, | 
					
						
							|  |  |  | 			  RTL819x_2GHZ_CH14, | 
					
						
							|  |  |  | 			  RTL819x_5GHZ_5725_5850, | 
					
						
							|  |  |  | 		      } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const struct ieee80211_regdomain rtl_regdom_14 = { | 
					
						
							|  |  |  | 	.n_reg_rules = 3, | 
					
						
							|  |  |  | 	.alpha2 = "99", | 
					
						
							|  |  |  | 	.reg_rules = { | 
					
						
							|  |  |  | 		      RTL819x_2GHZ_CH01_11, | 
					
						
							|  |  |  | 			  RTL819x_2GHZ_CH12_13, | 
					
						
							|  |  |  | 			  RTL819x_2GHZ_CH14, | 
					
						
							|  |  |  | 		      } | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static bool _rtl_is_radar_freq(u16 center_freq) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return (center_freq >= 5260 && center_freq <= 5700); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void _rtl_reg_apply_beaconing_flags(struct wiphy *wiphy, | 
					
						
							|  |  |  | 					   enum nl80211_reg_initiator initiator) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	enum ieee80211_band band; | 
					
						
							|  |  |  | 	struct ieee80211_supported_band *sband; | 
					
						
							|  |  |  | 	const struct ieee80211_reg_rule *reg_rule; | 
					
						
							|  |  |  | 	struct ieee80211_channel *ch; | 
					
						
							|  |  |  | 	unsigned int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (!wiphy->bands[band]) | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		sband = wiphy->bands[band]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for (i = 0; i < sband->n_channels; i++) { | 
					
						
							|  |  |  | 			ch = &sband->channels[i]; | 
					
						
							|  |  |  | 			if (_rtl_is_radar_freq(ch->center_freq) || | 
					
						
							|  |  |  | 			    (ch->flags & IEEE80211_CHAN_RADAR)) | 
					
						
							|  |  |  | 				continue; | 
					
						
							|  |  |  | 			if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { | 
					
						
							| 
									
										
										
										
											2013-10-29 19:34:26 +01:00
										 |  |  | 				reg_rule = freq_reg_info(wiphy, | 
					
						
							|  |  |  | 							 MHZ_TO_KHZ(ch->center_freq)); | 
					
						
							| 
									
										
										
										
											2012-12-06 15:57:14 +01:00
										 |  |  | 				if (IS_ERR(reg_rule)) | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | 					continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/*
 | 
					
						
							|  |  |  | 				 *If 11d had a rule for this channel ensure | 
					
						
							|  |  |  | 				 *we enable adhoc/beaconing if it allows us to | 
					
						
							|  |  |  | 				 *use it. Note that we would have disabled it | 
					
						
							|  |  |  | 				 *by applying our static world regdomain by | 
					
						
							|  |  |  | 				 *default during init, prior to calling our | 
					
						
							|  |  |  | 				 *regulatory_hint(). | 
					
						
							|  |  |  | 				 */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-21 19:22:25 +02:00
										 |  |  | 				if (!(reg_rule->flags & NL80211_RRF_NO_IR)) | 
					
						
							|  |  |  | 					ch->flags &= ~IEEE80211_CHAN_NO_IR; | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | 			} else { | 
					
						
							|  |  |  | 				if (ch->beacon_found) | 
					
						
							| 
									
										
										
										
											2013-10-21 19:22:25 +02:00
										 |  |  | 					ch->flags &= ~IEEE80211_CHAN_NO_IR; | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Allows active scan scan on Ch 12 and 13 */ | 
					
						
							|  |  |  | static void _rtl_reg_apply_active_scan_flags(struct wiphy *wiphy, | 
					
						
							|  |  |  | 					     enum nl80211_reg_initiator | 
					
						
							|  |  |  | 					     initiator) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ieee80211_supported_band *sband; | 
					
						
							|  |  |  | 	struct ieee80211_channel *ch; | 
					
						
							|  |  |  | 	const struct ieee80211_reg_rule *reg_rule; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-25 12:53:24 -05:00
										 |  |  | 	if (!wiphy->bands[IEEE80211_BAND_2GHZ]) | 
					
						
							|  |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | 	sband = wiphy->bands[IEEE80211_BAND_2GHZ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 *If no country IE has been received always enable active scan | 
					
						
							|  |  |  | 	 *on these channels. This is only done for specific regulatory SKUs | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) { | 
					
						
							|  |  |  | 		ch = &sband->channels[11];	/* CH 12 */ | 
					
						
							| 
									
										
										
										
											2013-10-21 19:22:25 +02:00
										 |  |  | 		if (ch->flags & IEEE80211_CHAN_NO_IR) | 
					
						
							|  |  |  | 			ch->flags &= ~IEEE80211_CHAN_NO_IR; | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | 		ch = &sband->channels[12];	/* CH 13 */ | 
					
						
							| 
									
										
										
										
											2013-10-21 19:22:25 +02:00
										 |  |  | 		if (ch->flags & IEEE80211_CHAN_NO_IR) | 
					
						
							|  |  |  | 			ch->flags &= ~IEEE80211_CHAN_NO_IR; | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							| 
									
										
										
										
											2011-03-30 22:57:33 -03:00
										 |  |  | 	 *If a country IE has been received check its rule for this | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | 	 *channel first before enabling active scan. The passive scan | 
					
						
							|  |  |  | 	 *would have been enforced by the initial processing of our | 
					
						
							|  |  |  | 	 *custom regulatory domain. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ch = &sband->channels[11];	/* CH 12 */ | 
					
						
							| 
									
										
										
										
											2013-10-29 19:34:26 +01:00
										 |  |  | 	reg_rule = freq_reg_info(wiphy, MHZ_TO_KHZ(ch->center_freq)); | 
					
						
							| 
									
										
										
										
											2012-12-06 15:57:14 +01:00
										 |  |  | 	if (!IS_ERR(reg_rule)) { | 
					
						
							| 
									
										
										
										
											2013-10-21 19:22:25 +02:00
										 |  |  | 		if (!(reg_rule->flags & NL80211_RRF_NO_IR)) | 
					
						
							|  |  |  | 			if (ch->flags & IEEE80211_CHAN_NO_IR) | 
					
						
							|  |  |  | 				ch->flags &= ~IEEE80211_CHAN_NO_IR; | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ch = &sband->channels[12];	/* CH 13 */ | 
					
						
							| 
									
										
										
										
											2013-10-29 19:34:26 +01:00
										 |  |  | 	reg_rule = freq_reg_info(wiphy, MHZ_TO_KHZ(ch->center_freq)); | 
					
						
							| 
									
										
										
										
											2012-12-06 15:57:14 +01:00
										 |  |  | 	if (!IS_ERR(reg_rule)) { | 
					
						
							| 
									
										
										
										
											2013-10-21 19:22:25 +02:00
										 |  |  | 		if (!(reg_rule->flags & NL80211_RRF_NO_IR)) | 
					
						
							|  |  |  | 			if (ch->flags & IEEE80211_CHAN_NO_IR) | 
					
						
							|  |  |  | 				ch->flags &= ~IEEE80211_CHAN_NO_IR; | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  *Always apply Radar/DFS rules on | 
					
						
							|  |  |  |  *freq range 5260 MHz - 5700 MHz | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static void _rtl_reg_apply_radar_flags(struct wiphy *wiphy) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ieee80211_supported_band *sband; | 
					
						
							|  |  |  | 	struct ieee80211_channel *ch; | 
					
						
							|  |  |  | 	unsigned int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!wiphy->bands[IEEE80211_BAND_5GHZ]) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sband = wiphy->bands[IEEE80211_BAND_5GHZ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < sband->n_channels; i++) { | 
					
						
							|  |  |  | 		ch = &sband->channels[i]; | 
					
						
							|  |  |  | 		if (!_rtl_is_radar_freq(ch->center_freq)) | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/*
 | 
					
						
							|  |  |  | 		 *We always enable radar detection/DFS on this | 
					
						
							|  |  |  | 		 *frequency range. Additionally we also apply on | 
					
						
							|  |  |  | 		 *this frequency range: | 
					
						
							|  |  |  | 		 *- If STA mode does not yet have DFS supports disable | 
					
						
							|  |  |  | 		 * active scanning | 
					
						
							|  |  |  | 		 *- If adhoc mode does not support DFS yet then disable | 
					
						
							|  |  |  | 		 * adhoc in the frequency. | 
					
						
							|  |  |  | 		 *- If AP mode does not yet support radar detection/DFS | 
					
						
							|  |  |  | 		 *do not allow AP mode | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		if (!(ch->flags & IEEE80211_CHAN_DISABLED)) | 
					
						
							|  |  |  | 			ch->flags |= IEEE80211_CHAN_RADAR | | 
					
						
							| 
									
										
										
										
											2013-10-21 19:22:25 +02:00
										 |  |  | 				     IEEE80211_CHAN_NO_IR; | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void _rtl_reg_apply_world_flags(struct wiphy *wiphy, | 
					
						
							|  |  |  | 				       enum nl80211_reg_initiator initiator, | 
					
						
							|  |  |  | 				       struct rtl_regulatory *reg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	_rtl_reg_apply_beaconing_flags(wiphy, initiator); | 
					
						
							|  |  |  | 	_rtl_reg_apply_active_scan_flags(wiphy, initiator); | 
					
						
							|  |  |  | 	return; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-11 18:39:36 +00:00
										 |  |  | static void _rtl_reg_notifier_apply(struct wiphy *wiphy, | 
					
						
							|  |  |  | 				    struct regulatory_request *request, | 
					
						
							|  |  |  | 				    struct rtl_regulatory *reg) | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | { | 
					
						
							|  |  |  | 	/* We always apply this */ | 
					
						
							|  |  |  | 	_rtl_reg_apply_radar_flags(wiphy); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (request->initiator) { | 
					
						
							|  |  |  | 	case NL80211_REGDOM_SET_BY_DRIVER: | 
					
						
							|  |  |  | 	case NL80211_REGDOM_SET_BY_CORE: | 
					
						
							|  |  |  | 	case NL80211_REGDOM_SET_BY_USER: | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case NL80211_REGDOM_SET_BY_COUNTRY_IE: | 
					
						
							|  |  |  | 		_rtl_reg_apply_world_flags(wiphy, request->initiator, reg); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const struct ieee80211_regdomain *_rtl_regdomain_select( | 
					
						
							|  |  |  | 					       struct rtl_regulatory *reg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	switch (reg->country_code) { | 
					
						
							|  |  |  | 	case COUNTRY_CODE_FCC: | 
					
						
							| 
									
										
										
										
											2011-04-25 12:53:24 -05:00
										 |  |  | 		return &rtl_regdom_no_midband; | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | 	case COUNTRY_CODE_IC: | 
					
						
							|  |  |  | 		return &rtl_regdom_11; | 
					
						
							|  |  |  | 	case COUNTRY_CODE_ETSI: | 
					
						
							| 
									
										
										
										
											2011-04-25 12:53:24 -05:00
										 |  |  | 	case COUNTRY_CODE_TELEC_NETGEAR: | 
					
						
							|  |  |  | 		return &rtl_regdom_60_64; | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | 	case COUNTRY_CODE_SPAIN: | 
					
						
							|  |  |  | 	case COUNTRY_CODE_FRANCE: | 
					
						
							|  |  |  | 	case COUNTRY_CODE_ISRAEL: | 
					
						
							| 
									
										
										
										
											2011-04-25 12:53:24 -05:00
										 |  |  | 	case COUNTRY_CODE_WORLD_WIDE_13: | 
					
						
							|  |  |  | 		return &rtl_regdom_12_13; | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | 	case COUNTRY_CODE_MKK: | 
					
						
							|  |  |  | 	case COUNTRY_CODE_MKK1: | 
					
						
							|  |  |  | 	case COUNTRY_CODE_TELEC: | 
					
						
							|  |  |  | 	case COUNTRY_CODE_MIC: | 
					
						
							| 
									
										
										
										
											2011-04-25 12:53:24 -05:00
										 |  |  | 		return &rtl_regdom_14_60_64; | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | 	case COUNTRY_CODE_GLOBAL_DOMAIN: | 
					
						
							| 
									
										
										
										
											2011-04-25 12:53:24 -05:00
										 |  |  | 		return &rtl_regdom_14; | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | 	default: | 
					
						
							| 
									
										
										
										
											2011-04-25 12:53:24 -05:00
										 |  |  | 		return &rtl_regdom_no_midband; | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int _rtl_regd_init_wiphy(struct rtl_regulatory *reg, | 
					
						
							|  |  |  | 				struct wiphy *wiphy, | 
					
						
							| 
									
										
										
										
											2013-01-11 18:39:36 +00:00
										 |  |  | 				void (*reg_notifier) (struct wiphy *wiphy, | 
					
						
							|  |  |  | 						      struct regulatory_request * | 
					
						
							|  |  |  | 						      request)) | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | { | 
					
						
							|  |  |  | 	const struct ieee80211_regdomain *regd; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	wiphy->reg_notifier = reg_notifier; | 
					
						
							| 
									
										
										
										
											2011-04-25 12:53:24 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-11 22:15:29 +01:00
										 |  |  | 	wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; | 
					
						
							|  |  |  | 	wiphy->regulatory_flags &= ~REGULATORY_STRICT_REG; | 
					
						
							|  |  |  | 	wiphy->regulatory_flags &= ~REGULATORY_DISABLE_BEACON_HINTS; | 
					
						
							| 
									
										
										
										
											2011-04-25 12:53:24 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | 	regd = _rtl_regdomain_select(reg); | 
					
						
							|  |  |  | 	wiphy_apply_custom_regulatory(wiphy, regd); | 
					
						
							|  |  |  | 	_rtl_reg_apply_radar_flags(wiphy); | 
					
						
							|  |  |  | 	_rtl_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct country_code_to_enum_rd *_rtl_regd_find_country(u16 countrycode) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < ARRAY_SIZE(allCountries); i++) { | 
					
						
							|  |  |  | 		if (allCountries[i].countrycode == countrycode) | 
					
						
							|  |  |  | 			return &allCountries[i]; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int rtl_regd_init(struct ieee80211_hw *hw, | 
					
						
							| 
									
										
										
										
											2013-01-11 18:39:36 +00:00
										 |  |  | 		  void (*reg_notifier) (struct wiphy *wiphy, | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | 				       struct regulatory_request *request)) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct rtl_priv *rtlpriv = rtl_priv(hw); | 
					
						
							|  |  |  | 	struct wiphy *wiphy = hw->wiphy; | 
					
						
							|  |  |  | 	struct country_code_to_enum_rd *country = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (wiphy == NULL || &rtlpriv->regd == NULL) | 
					
						
							|  |  |  | 		return -EINVAL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-25 12:53:24 -05:00
										 |  |  | 	/* init country_code from efuse channel plan */ | 
					
						
							|  |  |  | 	rtlpriv->regd.country_code = rtlpriv->efuse.channel_plan; | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE, | 
					
						
							| 
									
										
										
										
											2012-01-04 19:40:41 -08:00
										 |  |  | 		 "rtl: EEPROM regdomain: 0x%0x\n", rtlpriv->regd.country_code); | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (rtlpriv->regd.country_code >= COUNTRY_CODE_MAX) { | 
					
						
							|  |  |  | 		RT_TRACE(rtlpriv, COMP_REGD, DBG_DMESG, | 
					
						
							| 
									
										
										
										
											2012-01-04 19:40:41 -08:00
										 |  |  | 			 "rtl: EEPROM indicates invalid contry code, world wide 13 should be used\n"); | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		rtlpriv->regd.country_code = COUNTRY_CODE_WORLD_WIDE_13; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	country = _rtl_regd_find_country(rtlpriv->regd.country_code); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (country) { | 
					
						
							| 
									
										
										
										
											2011-04-25 12:53:24 -05:00
										 |  |  | 		rtlpriv->regd.alpha2[0] = country->iso_name[0]; | 
					
						
							|  |  |  | 		rtlpriv->regd.alpha2[1] = country->iso_name[1]; | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		rtlpriv->regd.alpha2[0] = '0'; | 
					
						
							|  |  |  | 		rtlpriv->regd.alpha2[1] = '0'; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE, | 
					
						
							| 
									
										
										
										
											2012-01-04 19:40:41 -08:00
										 |  |  | 		 "rtl: Country alpha2 being used: %c%c\n", | 
					
						
							|  |  |  | 		 rtlpriv->regd.alpha2[0], rtlpriv->regd.alpha2[1]); | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	_rtl_regd_init_wiphy(&rtlpriv->regd, wiphy, reg_notifier); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-11 18:39:36 +00:00
										 |  |  | void rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); | 
					
						
							|  |  |  | 	struct rtl_priv *rtlpriv = rtl_priv(hw); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-04 19:40:41 -08:00
										 |  |  | 	RT_TRACE(rtlpriv, COMP_REGD, DBG_LOUD, "\n"); | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-11 18:39:36 +00:00
										 |  |  | 	_rtl_reg_notifier_apply(wiphy, request, &rtlpriv->regd); | 
					
						
							| 
									
										
										
										
											2010-12-08 11:12:31 -06:00
										 |  |  | } |