Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 77db0a3c authored by Eran Harary's avatar Eran Harary Committed by Emmanuel Grumbach
Browse files

iwlwifi: mvm: new NVM format in family 8000



Support the changes below:
- Fields and sections structure were changed.
- the NVM file built from DWord instead of Words.
- sections header format was changed.

Signed-off-by: default avatarEran Harary <eran.harary@intel.com>
Reviewed-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
parent 7303dd7f
Loading
Loading
Loading
Loading
+6 −0
Original line number Original line Diff line number Diff line
@@ -728,6 +728,12 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
			if (tlv_len != sizeof(u32))
			if (tlv_len != sizeof(u32))
				goto invalid_tlv_len;
				goto invalid_tlv_len;
			drv->fw.phy_config = le32_to_cpup((__le32 *)tlv_data);
			drv->fw.phy_config = le32_to_cpup((__le32 *)tlv_data);
			drv->fw.valid_tx_ant = (drv->fw.phy_config &
						FW_PHY_CFG_TX_CHAIN) >>
						FW_PHY_CFG_TX_CHAIN_POS;
			drv->fw.valid_rx_ant = (drv->fw.phy_config &
						FW_PHY_CFG_RX_CHAIN) >>
						FW_PHY_CFG_RX_CHAIN_POS;
			break;
			break;
		 case IWL_UCODE_TLV_SECURE_SEC_RT:
		 case IWL_UCODE_TLV_SECURE_SEC_RT:
			iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_REGULAR,
			iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_REGULAR,
+14 −0
Original line number Original line Diff line number Diff line
@@ -70,6 +70,20 @@
#define DRV_COPYRIGHT	"Copyright(c) 2003- 2014 Intel Corporation"
#define DRV_COPYRIGHT	"Copyright(c) 2003- 2014 Intel Corporation"
#define DRV_AUTHOR     "<ilw@linux.intel.com>"
#define DRV_AUTHOR     "<ilw@linux.intel.com>"


/* radio config bits (actual values from NVM definition) */
#define NVM_RF_CFG_DASH_MSK(x)   (x & 0x3)         /* bits 0-1   */
#define NVM_RF_CFG_STEP_MSK(x)   ((x >> 2)  & 0x3) /* bits 2-3   */
#define NVM_RF_CFG_TYPE_MSK(x)   ((x >> 4)  & 0x3) /* bits 4-5   */
#define NVM_RF_CFG_PNUM_MSK(x)   ((x >> 6)  & 0x3) /* bits 6-7   */
#define NVM_RF_CFG_TX_ANT_MSK(x) ((x >> 8)  & 0xF) /* bits 8-11  */
#define NVM_RF_CFG_RX_ANT_MSK(x) ((x >> 12) & 0xF) /* bits 12-15 */

#define NVM_RF_CFG_FLAVOR_MSK_FAMILY_8000(x)   (x & 0xF)
#define NVM_RF_CFG_DASH_MSK_FAMILY_8000(x)   ((x >> 4) & 0xF)
#define NVM_RF_CFG_STEP_MSK_FAMILY_8000(x)   ((x >> 8) & 0xF)
#define NVM_RF_CFG_TYPE_MSK_FAMILY_8000(x)   ((x >> 12) & 0xFFF)
#define NVM_RF_CFG_TX_ANT_MSK_FAMILY_8000(x) ((x >> 24) & 0xF)
#define NVM_RF_CFG_RX_ANT_MSK_FAMILY_8000(x) ((x >> 28) & 0xF)


/**
/**
 * DOC: Driver system flows - drv component
 * DOC: Driver system flows - drv component
+3 −2
Original line number Original line Diff line number Diff line
@@ -81,16 +81,17 @@ struct iwl_nvm_data {
	bool sku_cap_band_24GHz_enable;
	bool sku_cap_band_24GHz_enable;
	bool sku_cap_band_52GHz_enable;
	bool sku_cap_band_52GHz_enable;
	bool sku_cap_11n_enable;
	bool sku_cap_11n_enable;
	bool sku_cap_11ac_enable;
	bool sku_cap_amt_enable;
	bool sku_cap_amt_enable;
	bool sku_cap_ipan_enable;
	bool sku_cap_ipan_enable;


	u8 radio_cfg_type;
	u16 radio_cfg_type;
	u8 radio_cfg_step;
	u8 radio_cfg_step;
	u8 radio_cfg_dash;
	u8 radio_cfg_dash;
	u8 radio_cfg_pnum;
	u8 radio_cfg_pnum;
	u8 valid_tx_ant, valid_rx_ant;
	u8 valid_tx_ant, valid_rx_ant;


	u16 nvm_version;
	u32 nvm_version;
	s8 max_tx_pwr_half_dbm;
	s8 max_tx_pwr_half_dbm;


	struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
	struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
+4 −4
Original line number Original line Diff line number Diff line
@@ -288,6 +288,8 @@ struct iwl_fw {


	struct iwl_tlv_calib_ctrl default_calib[IWL_UCODE_TYPE_MAX];
	struct iwl_tlv_calib_ctrl default_calib[IWL_UCODE_TYPE_MAX];
	u32 phy_config;
	u32 phy_config;
	u8 valid_tx_ant;
	u8 valid_rx_ant;


	bool mvm_fw;
	bool mvm_fw;


@@ -296,14 +298,12 @@ struct iwl_fw {


static inline u8 iwl_fw_valid_tx_ant(const struct iwl_fw *fw)
static inline u8 iwl_fw_valid_tx_ant(const struct iwl_fw *fw)
{
{
	return (fw->phy_config & FW_PHY_CFG_TX_CHAIN) >>
	return fw->valid_tx_ant;
		FW_PHY_CFG_TX_CHAIN_POS;
}
}


static inline u8 iwl_fw_valid_rx_ant(const struct iwl_fw *fw)
static inline u8 iwl_fw_valid_rx_ant(const struct iwl_fw *fw)
{
{
	return (fw->phy_config & FW_PHY_CFG_RX_CHAIN) >>
	return fw->valid_rx_ant;
		FW_PHY_CFG_RX_CHAIN_POS;
}
}


#endif  /* __iwl_fw_h__ */
#endif  /* __iwl_fw_h__ */
+190 −49
Original line number Original line Diff line number Diff line
@@ -84,6 +84,27 @@ enum wkp_nvm_offsets {
	XTAL_CALIB = 0x316 - NVM_CALIB_SECTION
	XTAL_CALIB = 0x316 - NVM_CALIB_SECTION
};
};


enum family_8000_nvm_offsets {
	/* NVM HW-Section offset (in words) definitions */
	HW_ADDR0_FAMILY_8000 = 0x12,
	HW_ADDR1_FAMILY_8000 = 0x16,
	MAC_ADDRESS_OVERRIDE_FAMILY_8000 = 1,

	/* NVM SW-Section offset (in words) definitions */
	NVM_SW_SECTION_FAMILY_8000 = 0x1C0,
	NVM_VERSION_FAMILY_8000 = 0,
	RADIO_CFG_FAMILY_8000 = 2,
	SKU_FAMILY_8000 = 4,
	N_HW_ADDRS_FAMILY_8000 = 5,

	/* NVM REGULATORY -Section offset (in words) definitions */
	NVM_CHANNELS_FAMILY_8000 = 0,

	/* NVM calibration section offset (in words) definitions */
	NVM_CALIB_SECTION_FAMILY_8000 = 0x2B8,
	XTAL_CALIB_FAMILY_8000 = 0x316 - NVM_CALIB_SECTION_FAMILY_8000
};

/* SKU Capabilities (actual values from NVM definition) */
/* SKU Capabilities (actual values from NVM definition) */
enum nvm_sku_bits {
enum nvm_sku_bits {
	NVM_SKU_CAP_BAND_24GHZ	= BIT(0),
	NVM_SKU_CAP_BAND_24GHZ	= BIT(0),
@@ -92,14 +113,6 @@ enum nvm_sku_bits {
	NVM_SKU_CAP_11AC_ENABLE	= BIT(3),
	NVM_SKU_CAP_11AC_ENABLE	= BIT(3),
};
};


/* radio config bits (actual values from NVM definition) */
#define NVM_RF_CFG_DASH_MSK(x)   (x & 0x3)         /* bits 0-1   */
#define NVM_RF_CFG_STEP_MSK(x)   ((x >> 2)  & 0x3) /* bits 2-3   */
#define NVM_RF_CFG_TYPE_MSK(x)   ((x >> 4)  & 0x3) /* bits 4-5   */
#define NVM_RF_CFG_PNUM_MSK(x)   ((x >> 6)  & 0x3) /* bits 6-7   */
#define NVM_RF_CFG_TX_ANT_MSK(x) ((x >> 8)  & 0xF) /* bits 8-11  */
#define NVM_RF_CFG_RX_ANT_MSK(x) ((x >> 12) & 0xF) /* bits 12-15 */

/*
/*
 * These are the channel numbers in the order that they are stored in the NVM
 * These are the channel numbers in the order that they are stored in the NVM
 */
 */
@@ -112,7 +125,17 @@ static const u8 iwl_nvm_channels[] = {
	149, 153, 157, 161, 165
	149, 153, 157, 161, 165
};
};


static const u8 iwl_nvm_channels_family_8000[] = {
	/* 2.4 GHz */
	1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
	/* 5 GHz */
	36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92,
	96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144,
	149, 153, 157, 161, 165, 169, 173, 177, 181
};

#define IWL_NUM_CHANNELS	ARRAY_SIZE(iwl_nvm_channels)
#define IWL_NUM_CHANNELS	ARRAY_SIZE(iwl_nvm_channels)
#define IWL_NUM_CHANNELS_FAMILY_8000	ARRAY_SIZE(iwl_nvm_channels_family_8000)
#define NUM_2GHZ_CHANNELS	14
#define NUM_2GHZ_CHANNELS	14
#define FIRST_2GHZ_HT_MINUS	5
#define FIRST_2GHZ_HT_MINUS	5
#define LAST_2GHZ_HT_PLUS	9
#define LAST_2GHZ_HT_PLUS	9
@@ -179,13 +202,23 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
	struct ieee80211_channel *channel;
	struct ieee80211_channel *channel;
	u16 ch_flags;
	u16 ch_flags;
	bool is_5ghz;
	bool is_5ghz;
	int num_of_ch;
	const u8 *nvm_chan;

	if (cfg->device_family != IWL_DEVICE_FAMILY_8000) {
		num_of_ch = IWL_NUM_CHANNELS;
		nvm_chan = &iwl_nvm_channels[0];
	} else {
		num_of_ch = IWL_NUM_CHANNELS_FAMILY_8000;
		nvm_chan = &iwl_nvm_channels_family_8000[0];
	}


	for (ch_idx = 0; ch_idx < IWL_NUM_CHANNELS; ch_idx++) {
	for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) {
		ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx);
		ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx);
		if (!(ch_flags & NVM_CHANNEL_VALID)) {
		if (!(ch_flags & NVM_CHANNEL_VALID)) {
			IWL_DEBUG_EEPROM(dev,
			IWL_DEBUG_EEPROM(dev,
					 "Ch. %d Flags %x [%sGHz] - No traffic\n",
					 "Ch. %d Flags %x [%sGHz] - No traffic\n",
					 iwl_nvm_channels[ch_idx],
					 nvm_chan[ch_idx],
					 ch_flags,
					 ch_flags,
					 (ch_idx >= NUM_2GHZ_CHANNELS) ?
					 (ch_idx >= NUM_2GHZ_CHANNELS) ?
					 "5.2" : "2.4");
					 "5.2" : "2.4");
@@ -195,7 +228,7 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
		channel = &data->channels[n_channels];
		channel = &data->channels[n_channels];
		n_channels++;
		n_channels++;


		channel->hw_value = iwl_nvm_channels[ch_idx];
		channel->hw_value = nvm_chan[ch_idx];
		channel->band = (ch_idx < NUM_2GHZ_CHANNELS) ?
		channel->band = (ch_idx < NUM_2GHZ_CHANNELS) ?
				IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
				IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
		channel->center_freq =
		channel->center_freq =
@@ -206,11 +239,11 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
		channel->flags = IEEE80211_CHAN_NO_HT40;
		channel->flags = IEEE80211_CHAN_NO_HT40;
		if (ch_idx < NUM_2GHZ_CHANNELS &&
		if (ch_idx < NUM_2GHZ_CHANNELS &&
		    (ch_flags & NVM_CHANNEL_40MHZ)) {
		    (ch_flags & NVM_CHANNEL_40MHZ)) {
			if (iwl_nvm_channels[ch_idx] <= LAST_2GHZ_HT_PLUS)
			if (nvm_chan[ch_idx] <= LAST_2GHZ_HT_PLUS)
				channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
				channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
			if (iwl_nvm_channels[ch_idx] >= FIRST_2GHZ_HT_MINUS)
			if (nvm_chan[ch_idx] >= FIRST_2GHZ_HT_MINUS)
				channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
				channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
		} else if (iwl_nvm_channels[ch_idx] <= LAST_5GHZ_HT &&
		} else if (nvm_chan[ch_idx] <= LAST_5GHZ_HT &&
			   (ch_flags & NVM_CHANNEL_40MHZ)) {
			   (ch_flags & NVM_CHANNEL_40MHZ)) {
			if ((ch_idx - NUM_2GHZ_CHANNELS) % 2 == 0)
			if ((ch_idx - NUM_2GHZ_CHANNELS) % 2 == 0)
				channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
				channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
@@ -302,14 +335,23 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
}
}


static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
			    struct iwl_nvm_data *data, const __le16 *nvm_sw,
			    struct iwl_nvm_data *data,
			    bool enable_vht, u8 tx_chains, u8 rx_chains)
			    const __le16 *ch_section, bool enable_vht,
			    u8 tx_chains, u8 rx_chains)
{
{
	int n_channels = iwl_init_channel_map(dev, cfg, data,
	int n_channels;
			&nvm_sw[NVM_CHANNELS]);
	int n_used = 0;
	int n_used = 0;
	struct ieee80211_supported_band *sband;
	struct ieee80211_supported_band *sband;


	if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
		n_channels = iwl_init_channel_map(
				dev, cfg, data,
				&ch_section[NVM_CHANNELS]);
	else
		n_channels = iwl_init_channel_map(
				dev, cfg, data,
				&ch_section[NVM_CHANNELS_FAMILY_8000]);

	sband = &data->bands[IEEE80211_BAND_2GHZ];
	sband = &data->bands[IEEE80211_BAND_2GHZ];
	sband->band = IEEE80211_BAND_2GHZ;
	sband->band = IEEE80211_BAND_2GHZ;
	sband->bitrates = &iwl_cfg80211_rates[RATES_24_OFFS];
	sband->bitrates = &iwl_cfg80211_rates[RATES_24_OFFS];
@@ -335,35 +377,122 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
			    n_used, n_channels);
			    n_used, n_channels);
}
}


static int iwl_get_sku(const struct iwl_cfg *cfg,
		       const __le16 *nvm_sw)
{
	if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
		return le16_to_cpup(nvm_sw + SKU);
	else
		return le32_to_cpup((__le32 *)(nvm_sw + SKU_FAMILY_8000));
}

static int iwl_get_nvm_version(const struct iwl_cfg *cfg,
			       const __le16 *nvm_sw)
{
	if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
		return le16_to_cpup(nvm_sw + NVM_VERSION);
	else
		return le32_to_cpup((__le32 *)(nvm_sw +
					       NVM_VERSION_FAMILY_8000));
}

static int iwl_get_radio_cfg(const struct iwl_cfg *cfg,
			     const __le16 *nvm_sw)
{
	if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
		return le16_to_cpup(nvm_sw + RADIO_CFG);
	else
		return le32_to_cpup((__le32 *)(nvm_sw + RADIO_CFG_FAMILY_8000));
}

#define N_HW_ADDRS_MASK_FAMILY_8000	0xF
static int iwl_get_n_hw_addrs(const struct iwl_cfg *cfg,
			      const __le16 *nvm_sw)
{
	if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
		return le16_to_cpup(nvm_sw + N_HW_ADDRS);
	else
		return le32_to_cpup((__le32 *)(nvm_sw + N_HW_ADDRS_FAMILY_8000))
		       & N_HW_ADDRS_MASK_FAMILY_8000;
}

static void iwl_set_radio_cfg(const struct iwl_cfg *cfg,
			      struct iwl_nvm_data *data,
			      u32 radio_cfg)
{
	if (cfg->device_family != IWL_DEVICE_FAMILY_8000) {
		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);
		data->radio_cfg_pnum = NVM_RF_CFG_PNUM_MSK(radio_cfg);
		data->valid_tx_ant = NVM_RF_CFG_TX_ANT_MSK(radio_cfg);
		data->valid_rx_ant = NVM_RF_CFG_RX_ANT_MSK(radio_cfg);
		return;
	}

	/* set the radio configuration for family 8000 */
	data->radio_cfg_type = NVM_RF_CFG_TYPE_MSK_FAMILY_8000(radio_cfg);
	data->radio_cfg_step = NVM_RF_CFG_STEP_MSK_FAMILY_8000(radio_cfg);
	data->radio_cfg_dash = NVM_RF_CFG_DASH_MSK_FAMILY_8000(radio_cfg);
	data->radio_cfg_pnum = NVM_RF_CFG_FLAVOR_MSK_FAMILY_8000(radio_cfg);
	data->valid_tx_ant = NVM_RF_CFG_TX_ANT_MSK_FAMILY_8000(radio_cfg);
	data->valid_rx_ant = NVM_RF_CFG_RX_ANT_MSK_FAMILY_8000(radio_cfg);
}

static void iwl_set_hw_address(const struct iwl_cfg *cfg,
			       struct iwl_nvm_data *data,
			       const __le16 *nvm_sec)
{
	u8 hw_addr[ETH_ALEN];

	if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
		memcpy(hw_addr, nvm_sec + HW_ADDR, ETH_ALEN);
	else
		memcpy(hw_addr, nvm_sec + MAC_ADDRESS_OVERRIDE_FAMILY_8000,
		       ETH_ALEN);

	/* The byte order is little endian 16 bit, meaning 214365 */
	data->hw_addr[0] = hw_addr[1];
	data->hw_addr[1] = hw_addr[0];
	data->hw_addr[2] = hw_addr[3];
	data->hw_addr[3] = hw_addr[2];
	data->hw_addr[4] = hw_addr[5];
	data->hw_addr[5] = hw_addr[4];
}

struct iwl_nvm_data *
struct iwl_nvm_data *
iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
		   const __le16 *nvm_hw, const __le16 *nvm_sw,
		   const __le16 *nvm_hw, const __le16 *nvm_sw,
		   const __le16 *nvm_calib, u8 tx_chains, u8 rx_chains)
		   const __le16 *nvm_calib, const __le16 *regulatory,
		   const __le16 *mac_override, u8 tx_chains, u8 rx_chains)
{
{
	struct iwl_nvm_data *data;
	struct iwl_nvm_data *data;
	u8 hw_addr[ETH_ALEN];
	u32 sku;
	u16 radio_cfg, sku;
	u32 radio_cfg;


	if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
		data = kzalloc(sizeof(*data) +
		data = kzalloc(sizeof(*data) +
		       sizeof(struct ieee80211_channel) * IWL_NUM_CHANNELS,
			       sizeof(struct ieee80211_channel) *
			       IWL_NUM_CHANNELS,
			       GFP_KERNEL);
	else
		data = kzalloc(sizeof(*data) +
			       sizeof(struct ieee80211_channel) *
			       IWL_NUM_CHANNELS_FAMILY_8000,
			       GFP_KERNEL);
			       GFP_KERNEL);
	if (!data)
	if (!data)
		return NULL;
		return NULL;


	data->nvm_version = le16_to_cpup(nvm_sw + NVM_VERSION);
	data->nvm_version = iwl_get_nvm_version(cfg, nvm_sw);


	radio_cfg = le16_to_cpup(nvm_sw + RADIO_CFG);
	radio_cfg = iwl_get_radio_cfg(cfg, nvm_sw);
	data->radio_cfg_type = NVM_RF_CFG_TYPE_MSK(radio_cfg);
	iwl_set_radio_cfg(cfg, data, radio_cfg);
	data->radio_cfg_step = NVM_RF_CFG_STEP_MSK(radio_cfg);
	data->radio_cfg_dash = NVM_RF_CFG_DASH_MSK(radio_cfg);
	data->radio_cfg_pnum = NVM_RF_CFG_PNUM_MSK(radio_cfg);
	data->valid_tx_ant = NVM_RF_CFG_TX_ANT_MSK(radio_cfg);
	data->valid_rx_ant = NVM_RF_CFG_RX_ANT_MSK(radio_cfg);


	sku = le16_to_cpup(nvm_sw + SKU);
	sku = iwl_get_sku(cfg, nvm_sw);
	data->sku_cap_band_24GHz_enable = sku & NVM_SKU_CAP_BAND_24GHZ;
	data->sku_cap_band_24GHz_enable = sku & NVM_SKU_CAP_BAND_24GHZ;
	data->sku_cap_band_52GHz_enable = sku & NVM_SKU_CAP_BAND_52GHZ;
	data->sku_cap_band_52GHz_enable = sku & NVM_SKU_CAP_BAND_52GHZ;
	data->sku_cap_11n_enable = sku & NVM_SKU_CAP_11N_ENABLE;
	data->sku_cap_11n_enable = sku & NVM_SKU_CAP_11N_ENABLE;
	data->sku_cap_11ac_enable = sku & NVM_SKU_CAP_11AC_ENABLE;
	if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_ALL)
	if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_ALL)
		data->sku_cap_11n_enable = false;
		data->sku_cap_11n_enable = false;


@@ -380,22 +509,34 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
		return NULL;
		return NULL;
	}
	}


	data->n_hw_addrs = le16_to_cpup(nvm_sw + N_HW_ADDRS);
	data->n_hw_addrs = iwl_get_n_hw_addrs(cfg, nvm_sw);


	if (cfg->device_family != IWL_DEVICE_FAMILY_8000) {
		/* Checking for required sections */
		if (!nvm_calib) {
			IWL_ERR_DEV(dev,
				    "Can't parse empty Calib NVM sections\n");
			return NULL;
		}
		/* in family 8000 Xtal calibration values moved to OTP */
		data->xtal_calib[0] = *(nvm_calib + XTAL_CALIB);
		data->xtal_calib[0] = *(nvm_calib + XTAL_CALIB);
		data->xtal_calib[1] = *(nvm_calib + XTAL_CALIB + 1);
		data->xtal_calib[1] = *(nvm_calib + XTAL_CALIB + 1);
	}


	/* The byte order is little endian 16 bit, meaning 214365 */
	if (cfg->device_family != IWL_DEVICE_FAMILY_8000) {
	memcpy(hw_addr, nvm_hw + HW_ADDR, ETH_ALEN);
		iwl_set_hw_address(cfg, data, nvm_hw);
	data->hw_addr[0] = hw_addr[1];
	data->hw_addr[1] = hw_addr[0];
	data->hw_addr[2] = hw_addr[3];
	data->hw_addr[3] = hw_addr[2];
	data->hw_addr[4] = hw_addr[5];
	data->hw_addr[5] = hw_addr[4];


	iwl_init_sbands(dev, cfg, data, nvm_sw, sku & NVM_SKU_CAP_11AC_ENABLE,
		iwl_init_sbands(dev, cfg, data, nvm_sw,
			tx_chains, rx_chains);
				sku & NVM_SKU_CAP_11AC_ENABLE, tx_chains,
				rx_chains);
	} else {
		/* MAC address in family 8000 */
		iwl_set_hw_address(cfg, data, mac_override);

		iwl_init_sbands(dev, cfg, data, regulatory,
				sku & NVM_SKU_CAP_11AC_ENABLE, tx_chains,
				rx_chains);
	}


	data->calib_version = 255;
	data->calib_version = 255;


Loading