diff options
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c')
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 137 | 
1 files changed, 62 insertions, 75 deletions
| diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c index 3014beef4873..c3a5d8ccc95e 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c @@ -77,7 +77,7 @@  #include "iwl-csr.h"  /* NVM offsets (in words) definitions */ -enum wkp_nvm_offsets { +enum nvm_offsets {  	/* NVM HW-Section offset (in words) definitions */  	SUBSYSTEM_ID = 0x0A,  	HW_ADDR = 0x15, @@ -92,7 +92,10 @@ enum wkp_nvm_offsets {  	/* NVM calibration section offset (in words) definitions */  	NVM_CALIB_SECTION = 0x2B8, -	XTAL_CALIB = 0x316 - NVM_CALIB_SECTION +	XTAL_CALIB = 0x316 - NVM_CALIB_SECTION, + +	/* NVM REGULATORY -Section offset (in words) definitions */ +	NVM_CHANNELS_SDP = 0,  };  enum ext_nvm_offsets { @@ -206,8 +209,36 @@ enum iwl_nvm_channel_flags {  	NVM_CHANNEL_DC_HIGH		= BIT(12),  }; +static inline void iwl_nvm_print_channel_flags(struct device *dev, u32 level, +					       int chan, u16 flags) +{  #define CHECK_AND_PRINT_I(x)	\ -	((ch_flags & NVM_CHANNEL_##x) ? # x " " : "") +	((flags & NVM_CHANNEL_##x) ? " " #x : "") + +	if (!(flags & NVM_CHANNEL_VALID)) { +		IWL_DEBUG_DEV(dev, level, "Ch. %d: 0x%x: No traffic\n", +			      chan, flags); +		return; +	} + +	/* Note: already can print up to 101 characters, 110 is the limit! */ +	IWL_DEBUG_DEV(dev, level, +		      "Ch. %d: 0x%x:%s%s%s%s%s%s%s%s%s%s%s%s\n", +		      chan, flags, +		      CHECK_AND_PRINT_I(VALID), +		      CHECK_AND_PRINT_I(IBSS), +		      CHECK_AND_PRINT_I(ACTIVE), +		      CHECK_AND_PRINT_I(RADAR), +		      CHECK_AND_PRINT_I(INDOOR_ONLY), +		      CHECK_AND_PRINT_I(GO_CONCURRENT), +		      CHECK_AND_PRINT_I(UNIFORM), +		      CHECK_AND_PRINT_I(20MHZ), +		      CHECK_AND_PRINT_I(40MHZ), +		      CHECK_AND_PRINT_I(80MHZ), +		      CHECK_AND_PRINT_I(160MHZ), +		      CHECK_AND_PRINT_I(DC_HIGH)); +#undef CHECK_AND_PRINT_I +}  static u32 iwl_get_channel_flags(u8 ch_num, int ch_idx, bool is_5ghz,  				 u16 nvm_flags, const struct iwl_cfg *cfg) @@ -215,7 +246,7 @@ static u32 iwl_get_channel_flags(u8 ch_num, int ch_idx, bool is_5ghz,  	u32 flags = IEEE80211_CHAN_NO_HT40;  	u32 last_5ghz_ht = LAST_5GHZ_HT; -	if (cfg->ext_nvm) +	if (cfg->nvm_type == IWL_NVM_EXT)  		last_5ghz_ht = LAST_5GHZ_HT_FAMILY_8000;  	if (!is_5ghz && (nvm_flags & NVM_CHANNEL_40MHZ)) { @@ -268,7 +299,7 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,  	int num_of_ch, num_2ghz_channels;  	const u8 *nvm_chan; -	if (!cfg->ext_nvm) { +	if (cfg->nvm_type != IWL_NVM_EXT) {  		num_of_ch = IWL_NUM_CHANNELS;  		nvm_chan = &iwl_nvm_channels[0];  		num_2ghz_channels = NUM_2GHZ_CHANNELS; @@ -302,12 +333,8 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,  			 * supported, hence we still want to add them to  			 * the list of supported channels to cfg80211.  			 */ -			IWL_DEBUG_EEPROM(dev, -					 "Ch. %d Flags %x [%sGHz] - No traffic\n", -					 nvm_chan[ch_idx], -					 ch_flags, -					 (ch_idx >= num_2ghz_channels) ? -					 "5.2" : "2.4"); +			iwl_nvm_print_channel_flags(dev, IWL_DL_EEPROM, +						    nvm_chan[ch_idx], ch_flags);  			continue;  		} @@ -337,27 +364,10 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,  		else  			channel->flags = 0; -		IWL_DEBUG_EEPROM(dev, -				 "Ch. %d [%sGHz] flags 0x%x %s%s%s%s%s%s%s%s%s%s%s%s(%ddBm): Ad-Hoc %ssupported\n", -				 channel->hw_value, -				 is_5ghz ? "5.2" : "2.4", -				 ch_flags, -				 CHECK_AND_PRINT_I(VALID), -				 CHECK_AND_PRINT_I(IBSS), -				 CHECK_AND_PRINT_I(ACTIVE), -				 CHECK_AND_PRINT_I(RADAR), -				 CHECK_AND_PRINT_I(INDOOR_ONLY), -				 CHECK_AND_PRINT_I(GO_CONCURRENT), -				 CHECK_AND_PRINT_I(UNIFORM), -				 CHECK_AND_PRINT_I(20MHZ), -				 CHECK_AND_PRINT_I(40MHZ), -				 CHECK_AND_PRINT_I(80MHZ), -				 CHECK_AND_PRINT_I(160MHZ), -				 CHECK_AND_PRINT_I(DC_HIGH), -				 channel->max_power, -				 ((ch_flags & NVM_CHANNEL_IBSS) && -				  !(ch_flags & NVM_CHANNEL_RADAR)) -					? "" : "not "); +		iwl_nvm_print_channel_flags(dev, IWL_DL_EEPROM, +					    channel->hw_value, ch_flags); +		IWL_DEBUG_EEPROM(dev, "Ch. %d: %ddBm\n", +				 channel->hw_value, channel->max_power);  	}  	return n_channels; @@ -484,7 +494,7 @@ IWL_EXPORT_SYMBOL(iwl_init_sbands);  static int iwl_get_sku(const struct iwl_cfg *cfg, const __le16 *nvm_sw,  		       const __le16 *phy_sku)  { -	if (!cfg->ext_nvm) +	if (cfg->nvm_type != IWL_NVM_EXT)  		return le16_to_cpup(nvm_sw + SKU);  	return le32_to_cpup((__le32 *)(phy_sku + SKU_FAMILY_8000)); @@ -492,7 +502,7 @@ static int iwl_get_sku(const struct iwl_cfg *cfg, const __le16 *nvm_sw,  static int iwl_get_nvm_version(const struct iwl_cfg *cfg, const __le16 *nvm_sw)  { -	if (!cfg->ext_nvm) +	if (cfg->nvm_type != IWL_NVM_EXT)  		return le16_to_cpup(nvm_sw + NVM_VERSION);  	else  		return le32_to_cpup((__le32 *)(nvm_sw + @@ -502,7 +512,7 @@ static int iwl_get_nvm_version(const struct iwl_cfg *cfg, const __le16 *nvm_sw)  static int iwl_get_radio_cfg(const struct iwl_cfg *cfg, const __le16 *nvm_sw,  			     const __le16 *phy_sku)  { -	if (!cfg->ext_nvm) +	if (cfg->nvm_type != IWL_NVM_EXT)  		return le16_to_cpup(nvm_sw + RADIO_CFG);  	return le32_to_cpup((__le32 *)(phy_sku + RADIO_CFG_FAMILY_EXT_NVM)); @@ -513,7 +523,7 @@ static int iwl_get_n_hw_addrs(const struct iwl_cfg *cfg, const __le16 *nvm_sw)  {  	int n_hw_addr; -	if (!cfg->ext_nvm) +	if (cfg->nvm_type != IWL_NVM_EXT)  		return le16_to_cpup(nvm_sw + N_HW_ADDRS);  	n_hw_addr = le32_to_cpup((__le32 *)(nvm_sw + N_HW_ADDRS_FAMILY_8000)); @@ -525,7 +535,7 @@ static void iwl_set_radio_cfg(const struct iwl_cfg *cfg,  			      struct iwl_nvm_data *data,  			      u32 radio_cfg)  { -	if (!cfg->ext_nvm) { +	if (cfg->nvm_type != IWL_NVM_EXT) {  		data->radio_cfg_type = NVM_RF_CFG_TYPE_MSK(radio_cfg);  		data->radio_cfg_step = NVM_RF_CFG_STEP_MSK(radio_cfg);  		data->radio_cfg_dash = NVM_RF_CFG_DASH_MSK(radio_cfg); @@ -634,7 +644,7 @@ static int iwl_set_hw_address(struct iwl_trans *trans,  {  	if (cfg->mac_addr_from_csr) {  		iwl_set_hw_address_from_csr(trans, data); -	} else if (!cfg->ext_nvm) { +	} else if (cfg->nvm_type != IWL_NVM_EXT) {  		const u8 *hw_addr = (const u8 *)(nvm_hw + HW_ADDR);  		/* The byte order is little endian 16 bit, meaning 214365 */ @@ -706,7 +716,7 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,  	u16 lar_config;  	const __le16 *ch_section; -	if (!cfg->ext_nvm) +	if (cfg->nvm_type != IWL_NVM_EXT)  		data = kzalloc(sizeof(*data) +  			       sizeof(struct ieee80211_channel) *  			       IWL_NUM_CHANNELS, @@ -740,7 +750,7 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,  	data->n_hw_addrs = iwl_get_n_hw_addrs(cfg, nvm_sw); -	if (!cfg->ext_nvm) { +	if (cfg->nvm_type != IWL_NVM_EXT) {  		/* Checking for required sections */  		if (!nvm_calib) {  			IWL_ERR(trans, @@ -748,11 +758,15 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,  			kfree(data);  			return NULL;  		} + +		ch_section = cfg->nvm_type == IWL_NVM_SDP ? +			     ®ulatory[NVM_CHANNELS_SDP] : +			     &nvm_sw[NVM_CHANNELS]; +  		/* in family 8000 Xtal calibration values moved to OTP */  		data->xtal_calib[0] = *(nvm_calib + XTAL_CALIB);  		data->xtal_calib[1] = *(nvm_calib + XTAL_CALIB + 1);  		lar_enabled = true; -		ch_section = &nvm_sw[NVM_CHANNELS];  	} else {  		u16 lar_offset = data->nvm_version < 0xE39 ?  				 NVM_LAR_OFFSET_OLD : @@ -786,7 +800,7 @@ static u32 iwl_nvm_get_regdom_bw_flags(const u8 *nvm_chan,  	u32 flags = NL80211_RRF_NO_HT40;  	u32 last_5ghz_ht = LAST_5GHZ_HT; -	if (cfg->ext_nvm) +	if (cfg->nvm_type == IWL_NVM_EXT)  		last_5ghz_ht = LAST_5GHZ_HT_FAMILY_8000;  	if (ch_idx < NUM_2GHZ_CHANNELS && @@ -834,7 +848,7 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,  	int ch_idx;  	u16 ch_flags;  	u32 reg_rule_flags, prev_reg_rule_flags = 0; -	const u8 *nvm_chan = cfg->ext_nvm ? +	const u8 *nvm_chan = cfg->nvm_type == IWL_NVM_EXT ?  			     iwl_ext_nvm_channels : iwl_nvm_channels;  	struct ieee80211_regdomain *regd;  	int size_of_regd; @@ -843,7 +857,7 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,  	int center_freq, prev_center_freq = 0;  	int valid_rules = 0;  	bool new_rule; -	int max_num_ch = cfg->ext_nvm ? +	int max_num_ch = cfg->nvm_type == IWL_NVM_EXT ?  			 IWL_NUM_CHANNELS_EXT : IWL_NUM_CHANNELS;  	if (WARN_ON_ONCE(num_of_ch > NL80211_MAX_SUPP_REG_RULES)) @@ -873,12 +887,8 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,  		new_rule = false;  		if (!(ch_flags & NVM_CHANNEL_VALID)) { -			IWL_DEBUG_DEV(dev, IWL_DL_LAR, -				      "Ch. %d Flags %x [%sGHz] - No traffic\n", -				      nvm_chan[ch_idx], -				      ch_flags, -				      (ch_idx >= NUM_2GHZ_CHANNELS) ? -				      "5.2" : "2.4"); +			iwl_nvm_print_channel_flags(dev, IWL_DL_LAR, +						    nvm_chan[ch_idx], ch_flags);  			continue;  		} @@ -914,31 +924,8 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,  		prev_center_freq = center_freq;  		prev_reg_rule_flags = reg_rule_flags; -		IWL_DEBUG_DEV(dev, IWL_DL_LAR, -			      "Ch. %d [%sGHz] %s%s%s%s%s%s%s%s%s%s%s%s(0x%02x)\n", -			      center_freq, -			      band == NL80211_BAND_5GHZ ? "5.2" : "2.4", -			      CHECK_AND_PRINT_I(VALID), -			      CHECK_AND_PRINT_I(IBSS), -			      CHECK_AND_PRINT_I(ACTIVE), -			      CHECK_AND_PRINT_I(RADAR), -			      CHECK_AND_PRINT_I(INDOOR_ONLY), -			      CHECK_AND_PRINT_I(GO_CONCURRENT), -			      CHECK_AND_PRINT_I(UNIFORM), -			      CHECK_AND_PRINT_I(20MHZ), -			      CHECK_AND_PRINT_I(40MHZ), -			      CHECK_AND_PRINT_I(80MHZ), -			      CHECK_AND_PRINT_I(160MHZ), -			      CHECK_AND_PRINT_I(DC_HIGH), -			      ch_flags); -		IWL_DEBUG_DEV(dev, IWL_DL_LAR, -			      "Ch. %d [%sGHz] reg_flags 0x%x: %s\n", -			      center_freq, -			      band == NL80211_BAND_5GHZ ? "5.2" : "2.4", -			      reg_rule_flags, -			      ((ch_flags & NVM_CHANNEL_ACTIVE) && -			       !(ch_flags & NVM_CHANNEL_RADAR)) -					 ? "Ad-Hoc" : ""); +		iwl_nvm_print_channel_flags(dev, IWL_DL_LAR, +					    nvm_chan[ch_idx], ch_flags);  	}  	regd->n_reg_rules = valid_rules; |