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

Commit 8ba2d7a1 authored by Eran Harary's avatar Eran Harary Committed by Emmanuel Grumbach
Browse files

iwlwifi: mvm: take the MAC address from HW registers



For some configurations, the driver should get the MAC
address from the hardware registers and not from the
regular locations. Since the parsing of the MAC address
is the same regardless of its source, continue the regular
code path (parsing) after we read the registers.

Signed-off-by: default avatarEran Harary <eran.harary@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
parent 5711cac4
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -244,6 +244,7 @@ enum iwl_ucode_tlv_flag {
 * @IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF: ucode supports disabling dummy notif.
 * @IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF: ucode supports disabling dummy notif.
 * @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time
 * @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time
 *	longer than the passive one, which is essential for fragmented scan.
 *	longer than the passive one, which is essential for fragmented scan.
 * @IWL_UCODE_TLV_API_WIFI_MCC_UPDATE: ucode supports MCC updates with source.
 * IWL_UCODE_TLV_API_HDC_PHASE_0: ucode supports finer configuration of LTR
 * IWL_UCODE_TLV_API_HDC_PHASE_0: ucode supports finer configuration of LTR
 * @IWL_UCODE_TLV_API_BASIC_DWELL: use only basic dwell time in scan command,
 * @IWL_UCODE_TLV_API_BASIC_DWELL: use only basic dwell time in scan command,
 *	regardless of the band or the number of the probes. FW will calculate
 *	regardless of the band or the number of the probes. FW will calculate
@@ -261,6 +262,7 @@ enum iwl_ucode_tlv_api {
	IWL_UCODE_TLV_API_DISABLE_STA_TX	= BIT(5),
	IWL_UCODE_TLV_API_DISABLE_STA_TX	= BIT(5),
	IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF	= BIT(7),
	IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF	= BIT(7),
	IWL_UCODE_TLV_API_FRAGMENTED_SCAN	= BIT(8),
	IWL_UCODE_TLV_API_FRAGMENTED_SCAN	= BIT(8),
	IWL_UCODE_TLV_API_WIFI_MCC_UPDATE	= BIT(9),
	IWL_UCODE_TLV_API_HDC_PHASE_0		= BIT(10),
	IWL_UCODE_TLV_API_HDC_PHASE_0		= BIT(10),
	IWL_UCODE_TLV_API_BASIC_DWELL		= BIT(13),
	IWL_UCODE_TLV_API_BASIC_DWELL		= BIT(13),
	IWL_UCODE_TLV_API_SCD_CFG		= BIT(15),
	IWL_UCODE_TLV_API_SCD_CFG		= BIT(15),
+16 −45
Original line number Original line Diff line number Diff line
@@ -542,7 +542,8 @@ static void iwl_set_hw_address_family_8000(struct device *dev,
					   const struct iwl_cfg *cfg,
					   const struct iwl_cfg *cfg,
					   struct iwl_nvm_data *data,
					   struct iwl_nvm_data *data,
					   const __le16 *mac_override,
					   const __le16 *mac_override,
					   const __le16 *nvm_hw)
					   const __le16 *nvm_hw,
					   u32 mac_addr0, u32 mac_addr1)
{
{
	const u8 *hw_addr;
	const u8 *hw_addr;


@@ -566,48 +567,17 @@ static void iwl_set_hw_address_family_8000(struct device *dev,
	}
	}


	if (nvm_hw) {
	if (nvm_hw) {
		/* read the MAC address from OTP */
		/* read the MAC address from HW resisters */
		if (!dev_is_pci(dev) || (data->nvm_version < 0xE08)) {
		hw_addr = (const u8 *)&mac_addr0;
			/* read the mac address from the WFPM location */
			hw_addr = (const u8 *)(nvm_hw +
					       HW_ADDR0_WFPM_FAMILY_8000);
		data->hw_addr[0] = hw_addr[3];
		data->hw_addr[0] = hw_addr[3];
		data->hw_addr[1] = hw_addr[2];
		data->hw_addr[1] = hw_addr[2];
		data->hw_addr[2] = hw_addr[1];
		data->hw_addr[2] = hw_addr[1];
		data->hw_addr[3] = hw_addr[0];
		data->hw_addr[3] = hw_addr[0];


			hw_addr = (const u8 *)(nvm_hw +
		hw_addr = (const u8 *)&mac_addr1;
					       HW_ADDR1_WFPM_FAMILY_8000);
		data->hw_addr[4] = hw_addr[1];
		data->hw_addr[4] = hw_addr[1];
		data->hw_addr[5] = hw_addr[0];
		data->hw_addr[5] = hw_addr[0];
		} else if ((data->nvm_version >= 0xE08) &&
			   (data->nvm_version < 0xE0B)) {
			/* read "reverse order"  from the PCIe location */
			hw_addr = (const u8 *)(nvm_hw +
					       HW_ADDR0_PCIE_FAMILY_8000);
			data->hw_addr[5] = hw_addr[2];
			data->hw_addr[4] = hw_addr[1];
			data->hw_addr[3] = hw_addr[0];

			hw_addr = (const u8 *)(nvm_hw +
					       HW_ADDR1_PCIE_FAMILY_8000);
			data->hw_addr[2] = hw_addr[3];
			data->hw_addr[1] = hw_addr[2];
			data->hw_addr[0] = hw_addr[1];
		} else {
			/* read from the PCIe location */
			hw_addr = (const u8 *)(nvm_hw +
					       HW_ADDR0_PCIE_FAMILY_8000);
			data->hw_addr[5] = hw_addr[0];
			data->hw_addr[4] = hw_addr[1];
			data->hw_addr[3] = hw_addr[2];


			hw_addr = (const u8 *)(nvm_hw +
					       HW_ADDR1_PCIE_FAMILY_8000);
			data->hw_addr[2] = hw_addr[1];
			data->hw_addr[1] = hw_addr[2];
			data->hw_addr[0] = hw_addr[3];
		}
		if (!is_valid_ether_addr(data->hw_addr))
		if (!is_valid_ether_addr(data->hw_addr))
			IWL_ERR_DEV(dev,
			IWL_ERR_DEV(dev,
				    "mac address from hw section is not valid\n");
				    "mac address from hw section is not valid\n");
@@ -624,7 +594,8 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
		   const __le16 *nvm_calib, const __le16 *regulatory,
		   const __le16 *nvm_calib, const __le16 *regulatory,
		   const __le16 *mac_override, const __le16 *phy_sku,
		   const __le16 *mac_override, const __le16 *phy_sku,
		   u8 tx_chains, u8 rx_chains,
		   u8 tx_chains, u8 rx_chains,
		   bool lar_fw_supported, bool is_family_8000_a_step)
		   bool lar_fw_supported, bool is_family_8000_a_step,
		   u32 mac_addr0, u32 mac_addr1)
{
{
	struct iwl_nvm_data *data;
	struct iwl_nvm_data *data;
	u32 sku;
	u32 sku;
@@ -692,7 +663,7 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,


		/* MAC address in family 8000 */
		/* MAC address in family 8000 */
		iwl_set_hw_address_family_8000(dev, cfg, data, mac_override,
		iwl_set_hw_address_family_8000(dev, cfg, data, mac_override,
					       nvm_hw);
					       nvm_hw, mac_addr0, mac_addr1);


		iwl_init_sbands(dev, cfg, data, regulatory,
		iwl_init_sbands(dev, cfg, data, regulatory,
				tx_chains, rx_chains,
				tx_chains, rx_chains,
+2 −1
Original line number Original line Diff line number Diff line
@@ -79,7 +79,8 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
		   const __le16 *nvm_calib, const __le16 *regulatory,
		   const __le16 *nvm_calib, const __le16 *regulatory,
		   const __le16 *mac_override, const __le16 *phy_sku,
		   const __le16 *mac_override, const __le16 *phy_sku,
		   u8 tx_chains, u8 rx_chains,
		   u8 tx_chains, u8 rx_chains,
		   bool lar_fw_supported, bool is_family_8000_a_step);
		   bool lar_fw_supported, bool is_family_8000_a_step,
		   u32 mac_addr0, u32 mac_addr1);


/**
/**
 * iwl_parse_mcc_info - parse MCC (mobile country code) info coming from FW
 * iwl_parse_mcc_info - parse MCC (mobile country code) info coming from FW
+8 −0
Original line number Original line Diff line number Diff line
@@ -371,6 +371,14 @@ enum secure_load_status_reg {


#define DBGC_IN_SAMPLE			(0xa03c00)
#define DBGC_IN_SAMPLE			(0xa03c00)


/* enable the ID buf for read */
#define WFPM_PS_CTL_CLR			0xA0300C
#define WFMP_MAC_ADDR_0			0xA03080
#define WFMP_MAC_ADDR_1			0xA03084
#define LMPM_PMG_EN			0xA01CEC
#define RADIO_REG_SYS_MANUAL_DFT_0	0xAD4078
#define RFIC_REG_RD			0xAD0470

/* FW chicken bits */
/* FW chicken bits */
#define LMPM_CHICK			0xA01FF8
#define LMPM_CHICK			0xA01FF8
enum {
enum {
+86 −64
Original line number Original line Diff line number Diff line
@@ -1478,6 +1478,92 @@ struct iwl_sf_cfg_cmd {
	__le32 full_on_timeouts[SF_NUM_SCENARIO][SF_NUM_TIMEOUT_TYPES];
	__le32 full_on_timeouts[SF_NUM_SCENARIO][SF_NUM_TIMEOUT_TYPES];
} __packed; /* SF_CFG_API_S_VER_2 */
} __packed; /* SF_CFG_API_S_VER_2 */


/***********************************
 * Location Aware Regulatory (LAR) API - MCC updates
 ***********************************/

/**
 * struct iwl_mcc_update_cmd - Request the device to update geographic
 * regulatory profile according to the given MCC (Mobile Country Code).
 * The MCC is two letter-code, ascii upper case[A-Z] or '00' for world domain.
 * 'ZZ' MCC will be used to switch to NVM default profile; in this case, the
 * MCC in the cmd response will be the relevant MCC in the NVM.
 * @mcc: given mobile country code
 * @source_id: the source from where we got the MCC, see iwl_mcc_source
 * @reserved: reserved for alignment
 */
struct iwl_mcc_update_cmd {
	__le16 mcc;
	u8 source_id;
	u8 reserved;
} __packed; /* LAR_UPDATE_MCC_CMD_API_S */

/**
 * iwl_mcc_update_resp - response to MCC_UPDATE_CMD.
 * Contains the new channel control profile map, if changed, and the new MCC
 * (mobile country code).
 * The new MCC may be different than what was requested in MCC_UPDATE_CMD.
 * @status: 0 for success, 1 no change in channel profile, 2 invalid input.
 * @mcc: the new applied MCC
 * @cap: capabilities for all channels which matches the MCC
 * @source_id: the MCC source, see iwl_mcc_source
 * @n_channels: number of channels in @channels_data (may be 14, 39, 50 or 51
 *		channels, depending on platform)
 * @channels: channel control data map, DWORD for each channel. Only the first
 *	16bits are used.
 */
struct iwl_mcc_update_resp {
	__le32 status;
	__le16 mcc;
	u8 cap;
	u8 source_id;
	__le32 n_channels;
	__le32 channels[0];
} __packed; /* LAR_UPDATE_MCC_CMD_RESP_S */

/**
 * struct iwl_mcc_chub_notif - chub notifies of mcc change
 * (MCC_CHUB_UPDATE_CMD = 0xc9)
 * The Chub (Communication Hub, CommsHUB) is a HW component that connects to
 * the cellular and connectivity cores that gets updates of the mcc, and
 * notifies the ucode directly of any mcc change.
 * The ucode requests the driver to request the device to update geographic
 * regulatory  profile according to the given MCC (Mobile Country Code).
 * The MCC is two letter-code, ascii upper case[A-Z] or '00' for world domain.
 * 'ZZ' MCC will be used to switch to NVM default profile; in this case, the
 * MCC in the cmd response will be the relevant MCC in the NVM.
 * @mcc: given mobile country code
 * @source_id: identity of the change originator, see iwl_mcc_source
 * @reserved1: reserved for alignment
 */
struct iwl_mcc_chub_notif {
	u16 mcc;
	u8 source_id;
	u8 reserved1;
} __packed; /* LAR_MCC_NOTIFY_S */

enum iwl_mcc_update_status {
	MCC_RESP_NEW_CHAN_PROFILE,
	MCC_RESP_SAME_CHAN_PROFILE,
	MCC_RESP_INVALID,
	MCC_RESP_NVM_DISABLED,
	MCC_RESP_ILLEGAL,
	MCC_RESP_LOW_PRIORITY,
};

enum iwl_mcc_source {
	MCC_SOURCE_OLD_FW = 0,
	MCC_SOURCE_ME = 1,
	MCC_SOURCE_BIOS = 2,
	MCC_SOURCE_3G_LTE_HOST = 3,
	MCC_SOURCE_3G_LTE_DEVICE = 4,
	MCC_SOURCE_WIFI = 5,
	MCC_SOURCE_RESERVED = 6,
	MCC_SOURCE_DEFAULT = 7,
	MCC_SOURCE_UNINITIALIZED = 8,
	MCC_SOURCE_GET_CURRENT = 0x10
};

/* DTS measurements */
/* DTS measurements */


enum iwl_dts_measurement_flags {
enum iwl_dts_measurement_flags {
@@ -1679,68 +1765,4 @@ struct iwl_shared_mem_cfg {
	__le32 page_buff_size;
	__le32 page_buff_size;
} __packed; /* SHARED_MEM_ALLOC_API_S_VER_1 */
} __packed; /* SHARED_MEM_ALLOC_API_S_VER_1 */


/***********************************
 * Location Aware Regulatory (LAR) API - MCC updates
 ***********************************/

/**
 * struct iwl_mcc_update_cmd - Request the device to update geographic
 * regulatory profile according to the given MCC (Mobile Country Code).
 * The MCC is two letter-code, ascii upper case[A-Z] or '00' for world domain.
 * 'ZZ' MCC will be used to switch to NVM default profile; in this case, the
 * MCC in the cmd response will be the relevant MCC in the NVM.
 * @mcc: given mobile country code
 * @reserved: reserved for alignment
 */
struct iwl_mcc_update_cmd {
	__le16 mcc;
	__le16 reserved;
} __packed; /* LAR_UPDATE_MCC_CMD_API_S */

/**
 * iwl_mcc_update_resp - response to MCC_UPDATE_CMD.
 * Contains the new channel control profile map, if changed, and the new MCC
 * (mobile country code).
 * The new MCC may be different than what was requested in MCC_UPDATE_CMD.
 * @status: 0 for success, 1 no change in channel profile, 2 invalid input.
 * @mcc: the new applied MCC
 * @n_channels: number of channels in @channels_data (may be 14, 39, 50 or 51
 *		channels, depending on platform)
 * @channels: channel control data map, DWORD for each channel. Only the first
 *	16bits are used.
 */
struct iwl_mcc_update_resp {
	__le32 status;
	__le16 mcc;
	__le16 reserved;
	__le32 n_channels;
	__le32 channels[0];
} __packed; /* LAR_UPDATE_MCC_CMD_RESP_S */

/**
 * struct iwl_mcc_chub_notif - chub notifies of mcc change
 * (MCC_CHUB_UPDATE_CMD = 0xc9)
 * The Chub (Communication Hub, CommsHUB) is a HW component that connects to
 * the cellular and connectivity cores that gets updates of the mcc, and
 * notifies the ucode directly of any mcc change.
 * The ucode requests the driver to request the device to update geographic
 * regulatory  profile according to the given MCC (Mobile Country Code).
 * The MCC is two letter-code, ascii upper case[A-Z] or '00' for world domain.
 * 'ZZ' MCC will be used to switch to NVM default profile; in this case, the
 * MCC in the cmd response will be the relevant MCC in the NVM.
 * @mcc: given mobile country code
 * @reserved: reserved for alignment
 */
struct iwl_mcc_chub_notif {
	u16 mcc;
	u16 reserved1;
} __packed; /* LAR_MCC_NOTIFY_S */

enum iwl_mcc_update_status {
	MCC_RESP_NEW_CHAN_PROFILE,
	MCC_RESP_SAME_CHAN_PROFILE,
	MCC_RESP_INVALID,
	MCC_RESP_NVM_DISABLED,
};

#endif /* __fw_api_h__ */
#endif /* __fw_api_h__ */
Loading