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

Commit 9f32e017 authored by Eran Harary's avatar Eran Harary Committed by Emmanuel Grumbach
Browse files

iwlwifi: mvm: select the MAC address according to priority



For family 8000 products, the driver should take the MAC
address from the mac_override section and only if this
section is empty it should take it from the HW section.

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 26481bf4
Loading
Loading
Loading
Loading
+38 −8
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/export.h>
#include <linux/etherdevice.h>
#include "iwl-drv.h"
#include "iwl-modparams.h"
#include "iwl-nvm-parse.h"
@@ -450,13 +451,27 @@ 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];
	const u8 *hw_addr = (const u8 *)(nvm_sec + HW_ADDR);

	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];
}

static void iwl_set_hw_address_family_8000(const struct iwl_cfg *cfg,
					   struct iwl_nvm_data *data,
					   const __le16 *mac_override,
					   const __le16 *nvm_hw)
{
	const u8 *hw_addr;

	if (mac_override) {
		hw_addr = (const u8 *)(mac_override +
				 MAC_ADDRESS_OVERRIDE_FAMILY_8000);

		/* The byte order is little endian 16 bit, meaning 214365 */
		data->hw_addr[0] = hw_addr[1];
@@ -465,6 +480,21 @@ static void iwl_set_hw_address(const struct iwl_cfg *cfg,
		data->hw_addr[3] = hw_addr[2];
		data->hw_addr[4] = hw_addr[5];
		data->hw_addr[5] = hw_addr[4];

		if (is_valid_ether_addr(hw_addr))
			return;
	}

	/* take the MAC address from the OTP */
	hw_addr = (const u8 *)(nvm_hw + HW_ADDR0_FAMILY_8000);
	data->hw_addr[0] = hw_addr[3];
	data->hw_addr[1] = hw_addr[2];
	data->hw_addr[2] = hw_addr[1];
	data->hw_addr[3] = hw_addr[0];

	hw_addr = (const u8 *)(nvm_hw + HW_ADDR1_FAMILY_8000);
	data->hw_addr[4] = hw_addr[1];
	data->hw_addr[5] = hw_addr[0];
}

struct iwl_nvm_data *
@@ -526,7 +556,7 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
				rx_chains);
	} else {
		/* MAC address in family 8000 */
		iwl_set_hw_address(cfg, data, mac_override);
		iwl_set_hw_address_family_8000(cfg, data, mac_override, nvm_hw);

		iwl_init_sbands(dev, cfg, data, regulatory,
				sku & NVM_SKU_CAP_11AC_ENABLE, tx_chains,
+8 −1
Original line number Diff line number Diff line
@@ -238,13 +238,20 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)
			return NULL;
		}
	} else {
		/* SW and REGULATORY sections are mandatory */
		if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW].data ||
		    !mvm->nvm_sections[NVM_SECTION_TYPE_MAC_OVERRIDE].data ||
		    !mvm->nvm_sections[NVM_SECTION_TYPE_REGULATORY].data) {
			IWL_ERR(mvm,
				"Can't parse empty family 8000 NVM sections\n");
			return NULL;
		}
		/* MAC_OVERRIDE or at least HW section must exist */
		if (!mvm->cfg->nvm_hw_section_num &&
		    !mvm->nvm_sections[NVM_SECTION_TYPE_MAC_OVERRIDE].data) {
			IWL_ERR(mvm,
				"Can't parse mac_address, empty sections\n");
			return NULL;
		}
	}

	if (WARN_ON(!mvm->cfg))