diff options
Diffstat (limited to 'sys/contrib/dev/iwlwifi/mvm/fw.c')
| -rw-r--r-- | sys/contrib/dev/iwlwifi/mvm/fw.c | 308 | 
1 files changed, 140 insertions, 168 deletions
| diff --git a/sys/contrib/dev/iwlwifi/mvm/fw.c b/sys/contrib/dev/iwlwifi/mvm/fw.c index 08c4898c8f1a..d931c6eaf12f 100644 --- a/sys/contrib/dev/iwlwifi/mvm/fw.c +++ b/sys/contrib/dev/iwlwifi/mvm/fw.c @@ -1,6 +1,6 @@  // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause  /* - * Copyright (C) 2012-2014, 2018-2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2025 Intel Corporation   * Copyright (C) 2013-2015 Intel Mobile Communications GmbH   * Copyright (C) 2016-2017 Intel Deutschland GmbH   */ @@ -29,8 +29,8 @@  #define MVM_UCODE_CALIB_TIMEOUT	(2 * HZ)  struct iwl_mvm_alive_data { +	__le32 sku_id[3];  	bool valid; -	u32 scd_base_addr;  };  static int iwl_send_tx_ant_cfg(struct iwl_mvm *mvm, u8 valid_tx_ant) @@ -57,13 +57,13 @@ static int iwl_send_rss_cfg_cmd(struct iwl_mvm *mvm)  			     BIT(IWL_RSS_HASH_TYPE_IPV6_PAYLOAD),  	}; -	if (mvm->trans->num_rx_queues == 1) +	if (mvm->trans->info.num_rxqs == 1)  		return 0;  	/* Do not direct RSS traffic to Q 0 which is our fallback queue */  	for (i = 0; i < ARRAY_SIZE(cmd.indirection_table); i++)  		cmd.indirection_table[i] = -			1 + (i % (mvm->trans->num_rx_queues - 1)); +			1 + (i % (mvm->trans->info.num_rxqs - 1));  	netdev_rss_key_fill(cmd.secret_key, sizeof(cmd.secret_key));  	return iwl_mvm_send_cmd_pdu(mvm, RSS_CONFIG_CMD, 0, sizeof(cmd), &cmd); @@ -114,13 +114,29 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,  	u32 i; -	if (version == 6) { +	if (version >= 6) {  		struct iwl_alive_ntf_v6 *palive;  		if (pkt_len < sizeof(*palive))  			return false;  		palive = (void *)pkt->data; + +		umac = &palive->umac_data; +		lmac1 = &palive->lmac_data[0]; +		lmac2 = &palive->lmac_data[1]; +		status = le16_to_cpu(palive->status); + +		BUILD_BUG_ON(sizeof(palive->sku_id.data) != +			     sizeof(alive_data->sku_id)); +		memcpy(alive_data->sku_id, palive->sku_id.data, +		       sizeof(palive->sku_id.data)); + +		IWL_DEBUG_FW(mvm, "Got sku_id: 0x0%x 0x0%x 0x0%x\n", +			     le32_to_cpu(alive_data->sku_id[0]), +			     le32_to_cpu(alive_data->sku_id[1]), +			     le32_to_cpu(alive_data->sku_id[2])); +  		mvm->trans->dbg.imr_data.imr_enable =  			le32_to_cpu(palive->imr.enabled);  		mvm->trans->dbg.imr_data.imr_size = @@ -157,39 +173,17 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,  				}  			}  		} -	} -	if (version >= 5) { -		struct iwl_alive_ntf_v5 *palive; +		if (version >= 8) { +			const struct iwl_alive_ntf *palive_v8 = +				(void *)pkt->data; -		if (pkt_len < sizeof(*palive)) -			return false; - -		palive = (void *)pkt->data; -		umac = &palive->umac_data; -		lmac1 = &palive->lmac_data[0]; -		lmac2 = &palive->lmac_data[1]; -		status = le16_to_cpu(palive->status); +			if (pkt_len < sizeof(*palive_v8)) +				return false; -		mvm->trans->sku_id[0] = le32_to_cpu(palive->sku_id.data[0]); -		mvm->trans->sku_id[1] = le32_to_cpu(palive->sku_id.data[1]); -		mvm->trans->sku_id[2] = le32_to_cpu(palive->sku_id.data[2]); - -		IWL_DEBUG_FW(mvm, "Got sku_id: 0x0%x 0x0%x 0x0%x\n", -			     mvm->trans->sku_id[0], -			     mvm->trans->sku_id[1], -			     mvm->trans->sku_id[2]); -	} else if (iwl_rx_packet_payload_len(pkt) == sizeof(struct iwl_alive_ntf_v4)) { -		struct iwl_alive_ntf_v4 *palive; - -		if (pkt_len < sizeof(*palive)) -			return false; - -		palive = (void *)pkt->data; -		umac = &palive->umac_data; -		lmac1 = &palive->lmac_data[0]; -		lmac2 = &palive->lmac_data[1]; -		status = le16_to_cpu(palive->status); +			IWL_DEBUG_FW(mvm, "platform id: 0x%llx\n", +				     palive_v8->platform_id); +		}  	} else if (iwl_rx_packet_payload_len(pkt) ==  		   sizeof(struct iwl_alive_ntf_v3)) {  		struct iwl_alive_ntf_v3 *palive3; @@ -221,7 +215,7 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,  	if (umac_error_table) {  		if (umac_error_table >= -		    mvm->trans->cfg->min_umac_error_event_table) { +		    mvm->trans->mac_cfg->base->min_umac_error_event_table) {  			iwl_fw_umac_set_alive_err_table(mvm->trans,  							umac_error_table);  		} else { @@ -233,7 +227,6 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,  		}  	} -	alive_data->scd_base_addr = le32_to_cpu(lmac1->dbg_ptrs.scd_base_ptr);  	alive_data->valid = status == IWL_ALIVE_STATUS_OK;  	IWL_DEBUG_FW(mvm, @@ -282,7 +275,7 @@ static void iwl_mvm_print_pd_notification(struct iwl_mvm *mvm)  	IWL_ERR(mvm, #reg_name ": 0x%x\n", iwl_read_umac_prph(trans, reg_name))  	struct iwl_trans *trans = mvm->trans; -	enum iwl_device_family device_family = trans->trans_cfg->device_family; +	enum iwl_device_family device_family = trans->mac_cfg->device_family;  	if (device_family < IWL_DEVICE_FAMILY_8000)  		return; @@ -304,7 +297,6 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,  {  	struct iwl_notification_wait alive_wait;  	struct iwl_mvm_alive_data alive_data = {}; -	const struct fw_img *fw;  	int ret;  	enum iwl_ucode_type old_type = mvm->fwrt.cur_fw_img;  	static const u16 alive_cmd[] = { UCODE_ALIVE_NTFY }; @@ -317,11 +309,7 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,  	    iwl_fw_dbg_conf_usniffer(mvm->fw, FW_DBG_START_FROM_ALIVE) &&  	    !(fw_has_capa(&mvm->fw->ucode_capa,  			  IWL_UCODE_TLV_CAPA_USNIFFER_UNIFIED))) -		fw = iwl_get_ucode_image(mvm->fw, IWL_UCODE_REGULAR_USNIFFER); -	else -		fw = iwl_get_ucode_image(mvm->fw, ucode_type); -	if (WARN_ON(!fw)) -		return -EINVAL; +		ucode_type = IWL_UCODE_REGULAR_USNIFFER;  	iwl_fw_set_current_image(&mvm->fwrt, ucode_type);  	clear_bit(IWL_MVM_STATUS_FIRMWARE_RUNNING, &mvm->status); @@ -334,7 +322,8 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,  	 * For the unified firmware case, the ucode_type is not  	 * INIT, but we still need to run it.  	 */ -	ret = iwl_trans_start_fw(mvm->trans, fw, run_in_rfkill); +	ret = iwl_trans_start_fw(mvm->trans, mvm->fw, ucode_type, +				 run_in_rfkill);  	if (ret) {  		iwl_fw_set_current_image(&mvm->fwrt, old_type);  		iwl_remove_notification(&mvm->notif_wait, &alive_wait); @@ -348,7 +337,7 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,  	ret = iwl_wait_notification(&mvm->notif_wait, &alive_wait,  				    MVM_UCODE_ALIVE_TIMEOUT); -	if (mvm->trans->trans_cfg->device_family == +	if (mvm->trans->mac_cfg->device_family ==  	    IWL_DEVICE_FAMILY_AX210) {  		/* print these registers regardless of alive fail/success */  		IWL_INFO(mvm, "WFPM_UMAC_PD_NOTIFICATION: 0x%x\n", @@ -365,14 +354,14 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,  		struct iwl_trans *trans = mvm->trans;  		/* SecBoot info */ -		if (trans->trans_cfg->device_family >= +		if (trans->mac_cfg->device_family >=  					IWL_DEVICE_FAMILY_22000) {  			IWL_ERR(mvm,  				"SecBoot CPU1 Status: 0x%x, CPU2 Status: 0x%x\n",  				iwl_read_umac_prph(trans, UMAG_SB_CPU_1_STATUS),  				iwl_read_umac_prph(trans,  						   UMAG_SB_CPU_2_STATUS)); -		} else if (trans->trans_cfg->device_family >= +		} else if (trans->mac_cfg->device_family >=  			   IWL_DEVICE_FAMILY_8000) {  			IWL_ERR(mvm,  				"SecBoot CPU1 Status: 0x%x, CPU2 Status: 0x%x\n", @@ -383,7 +372,7 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,  		iwl_mvm_print_pd_notification(mvm);  		/* LMAC/UMAC PC info */ -		if (trans->trans_cfg->device_family >= +		if (trans->mac_cfg->device_family >=  					IWL_DEVICE_FAMILY_22000) {  			pc_data = trans->dbg.pc_data;  			for (count = 0; count < trans->dbg.num_pc; @@ -391,7 +380,7 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,  				IWL_ERR(mvm, "%s: 0x%x\n",  					pc_data->pc_name,  					pc_data->pc_address); -		} else if (trans->trans_cfg->device_family >= +		} else if (trans->mac_cfg->device_family >=  					IWL_DEVICE_FAMILY_9000) {  			IWL_ERR(mvm, "UMAC PC: 0x%x\n",  				iwl_read_umac_prph(trans, @@ -422,16 +411,16 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,  	/* if reached this point, Alive notification was received */  	iwl_mei_alive_notif(true); +	iwl_trans_fw_alive(mvm->trans); +  	ret = iwl_pnvm_load(mvm->trans, &mvm->notif_wait, -			    &mvm->fw->ucode_capa); +			    mvm->fw, alive_data.sku_id);  	if (ret) {  		IWL_ERR(mvm, "Timeout waiting for PNVM load!\n");  		iwl_fw_set_current_image(&mvm->fwrt, old_type);  		return ret;  	} -	iwl_trans_fw_alive(mvm->trans, alive_data.scd_base_addr); -  	/*  	 * Note: all the queues are enabled as part of the interface  	 * initialization, but in firmware restart scenarios they @@ -473,7 +462,7 @@ static void iwl_mvm_phy_filter_init(struct iwl_mvm *mvm,  				    struct iwl_phy_specific_cfg *phy_filters)  {  #ifdef CONFIG_ACPI -	*phy_filters = mvm->phy_filters; +	*phy_filters = mvm->fwrt.phy_filters;  #endif /* CONFIG_ACPI */  } @@ -490,7 +479,7 @@ static void iwl_mvm_uats_init(struct iwl_mvm *mvm)  		.dataflags[0] = IWL_HCMD_DFL_NOCOPY,  	}; -	if (mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210) { +	if (mvm->trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_AX210) {  		IWL_DEBUG_RADIO(mvm, "UATS feature is not supported\n");  		return;  	} @@ -504,11 +493,10 @@ static void iwl_mvm_uats_init(struct iwl_mvm *mvm)  		return;  	} -	ret = iwl_uefi_get_uats_table(mvm->trans, &mvm->fwrt); -	if (ret < 0) { -		IWL_DEBUG_FW(mvm, "failed to read UATS table (%d)\n", ret); +	iwl_uefi_get_uats_table(mvm->trans, &mvm->fwrt); + +	if (!mvm->fwrt.uats_valid)  		return; -	}  	ret = iwl_mvm_send_cmd(mvm, &cmd);  	if (ret < 0) @@ -578,7 +566,7 @@ static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm)  	/* set flags extra PHY configuration flags from the device's cfg */  	phy_cfg_cmd.phy_cfg |= -		cpu_to_le32(mvm->trans->trans_cfg->extra_phy_cfg_flags); +		cpu_to_le32(mvm->trans->mac_cfg->extra_phy_cfg_flags);  	phy_cfg_cmd.calib_control.event_trigger =  		mvm->fw->default_calib[ucode_type].event_trigger; @@ -617,7 +605,7 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm)  	mvm->rfkill_safe_init_done = false; -	if (mvm->trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_AX210) { +	if (mvm->trans->mac_cfg->device_family == IWL_DEVICE_FAMILY_AX210) {  		sb_cfg = iwl_read_umac_prph(mvm->trans, SB_MODIFY_CFG_FLAG);  		/* if needed, we'll reset this on our way out later */  		mvm->fw_product_reset = sb_cfg == SB_CFG_RESIDES_IN_ROM; @@ -642,7 +630,8 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm)  		/* if we needed reset then fail here, but notify and remove */  		if (mvm->fw_product_reset) {  			iwl_mei_alive_notif(false); -			iwl_trans_pcie_remove(mvm->trans, true); +			iwl_trans_pcie_reset(mvm->trans, +					     IWL_RESET_MODE_RESCAN);  		}  		goto error; @@ -650,11 +639,6 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm)  	iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_POINT_AFTER_ALIVE,  			       NULL); -	if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) -		mvm->trans->step_urm = !!(iwl_read_umac_prph(mvm->trans, -							     CNVI_PMU_STEP_FLOW) & -						CNVI_PMU_STEP_FLOW_FORCE_URM); -  	/* Send init config command to mark that we are sending NVM access  	 * commands  	 */ @@ -755,7 +739,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm)  		goto remove_notif;  	} -	if (mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_8000) { +	if (mvm->trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_8000) {  		ret = iwl_mvm_send_bt_init_conf(mvm);  		if (ret)  			goto remove_notif; @@ -863,7 +847,10 @@ static int iwl_mvm_config_ltr(struct iwl_mvm *mvm)  int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b)  {  	u32 cmd_id = REDUCE_TX_POWER_CMD; -	struct iwl_dev_tx_power_cmd cmd = { +	struct iwl_dev_tx_power_cmd_v3_v8 cmd = { +		.common.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_CHAINS), +	}; +	struct iwl_dev_tx_power_cmd cmd_v9_v10 = {  		.common.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_CHAINS),  	};  	__le16 *per_chain; @@ -871,18 +858,23 @@ int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b)  	u16 len = 0;  	u32 n_subbands;  	u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd_id, 3); +	void *cmd_data = &cmd; -	if (cmd_ver >= 7) { -		len = sizeof(cmd.v7); +	if (cmd_ver == 10) { +		len = sizeof(cmd_v9_v10.v10);  		n_subbands = IWL_NUM_SUB_BANDS_V2; -		per_chain = cmd.v7.per_chain[0][0]; -		cmd.v7.flags = cpu_to_le32(mvm->fwrt.reduced_power_flags); -		if (cmd_ver == 8) -			len = sizeof(cmd.v8); -	} else if (cmd_ver == 6) { -		len = sizeof(cmd.v6); +		per_chain = &cmd_v9_v10.v10.per_chain[0][0][0]; +		cmd_v9_v10.v10.flags = +			cpu_to_le32(mvm->fwrt.reduced_power_flags); +	} else if (cmd_ver == 9) { +		len = sizeof(cmd_v9_v10.v9); +		n_subbands = IWL_NUM_SUB_BANDS_V1; +		per_chain = &cmd_v9_v10.v9.per_chain[0][0]; +	} else if (cmd_ver == 8) { +		len = sizeof(cmd.v8);  		n_subbands = IWL_NUM_SUB_BANDS_V2; -		per_chain = cmd.v6.per_chain[0][0]; +		per_chain = cmd.v8.per_chain[0][0]; +		cmd.v8.flags = cpu_to_le32(mvm->fwrt.reduced_power_flags);  	} else if (fw_has_api(&mvm->fw->ucode_capa,  			      IWL_UCODE_TLV_API_REDUCE_TX_POWER)) {  		len = sizeof(cmd.v5); @@ -899,9 +891,14 @@ int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b)  		per_chain = cmd.v3.per_chain[0][0];  	} -	/* all structs have the same common part, add it */ +	/* all structs have the same common part, add its length */  	len += sizeof(cmd.common); +	if (cmd_ver < 9) +		len += sizeof(cmd.per_band); +	else +		cmd_data = &cmd_v9_v10; +  	ret = iwl_sar_fill_profile(&mvm->fwrt, per_chain,  				   IWL_NUM_CHAIN_TABLES,  				   n_subbands, prof_a, prof_b); @@ -913,7 +910,7 @@ int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b)  	iwl_mei_set_power_limit(per_chain);  	IWL_DEBUG_RADIO(mvm, "Sending REDUCE_TX_POWER_CMD per chain\n"); -	return iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0, len, &cmd); +	return iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0, len, cmd_data);  }  int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm) @@ -1074,36 +1071,24 @@ static int iwl_mvm_ppag_init(struct iwl_mvm *mvm)  	return iwl_mvm_ppag_send_cmd(mvm);  } -static bool iwl_mvm_add_to_tas_block_list(__le32 *list, __le32 *le_size, unsigned int mcc) -{ -	int i; -	u32 size = le32_to_cpu(*le_size); - -	/* Verify that there is room for another country */ -	if (size >= IWL_WTAS_BLACK_LIST_MAX) -		return false; - -	for (i = 0; i < size; i++) { -		if (list[i] == cpu_to_le32(mcc)) -			return true; -	} - -	list[size++] = cpu_to_le32(mcc); -	*le_size = cpu_to_le32(size); -	return true; -} -  static void iwl_mvm_tas_init(struct iwl_mvm *mvm)  {  	u32 cmd_id = WIDE_ID(REGULATORY_AND_NVM_GROUP, TAS_CONFIG); -	int ret; +	int fw_ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd_id, +					   IWL_FW_CMD_VER_UNKNOWN); +	struct iwl_tas_selection_data selection_data = {}; +	struct iwl_tas_config_cmd_v2_v4 cmd_v2_v4 = {}; +	struct iwl_tas_config_cmd cmd_v5 = {};  	struct iwl_tas_data data = {}; -	struct iwl_tas_config_cmd cmd = {}; -	int cmd_size, fw_ver; +	void *cmd_data = &cmd_v2_v4; +	int cmd_size; +	int ret;  	BUILD_BUG_ON(ARRAY_SIZE(data.block_list_array) !=  		     IWL_WTAS_BLACK_LIST_MAX); -	BUILD_BUG_ON(ARRAY_SIZE(cmd.common.block_list_array) != +	BUILD_BUG_ON(ARRAY_SIZE(cmd_v2_v4.common.block_list_array) != +		     IWL_WTAS_BLACK_LIST_MAX); +	BUILD_BUG_ON(ARRAY_SIZE(cmd_v5.block_list_array) !=  		     IWL_WTAS_BLACK_LIST_MAX);  	if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_TAS_CFG)) { @@ -1119,17 +1104,17 @@ static void iwl_mvm_tas_init(struct iwl_mvm *mvm)  		return;  	} -	if (ret == 0) +	if (ret == 0 && fw_ver < 5)  		return;  	if (!iwl_is_tas_approved()) {  		IWL_DEBUG_RADIO(mvm,  				"System vendor '%s' is not in the approved list, disabling TAS in US and Canada.\n",  				dmi_get_system_info(DMI_SYS_VENDOR) ?: "<unknown>"); -		if ((!iwl_mvm_add_to_tas_block_list(data.block_list_array, +		if ((!iwl_add_mcc_to_tas_block_list(data.block_list_array,  						    &data.block_list_size,  						    IWL_MCC_US)) || -		    (!iwl_mvm_add_to_tas_block_list(data.block_list_array, +		    (!iwl_add_mcc_to_tas_block_list(data.block_list_array,  						    &data.block_list_size,  						    IWL_MCC_CANADA))) {  			IWL_DEBUG_RADIO(mvm, @@ -1142,63 +1127,53 @@ static void iwl_mvm_tas_init(struct iwl_mvm *mvm)  				dmi_get_system_info(DMI_SYS_VENDOR) ?: "<unknown>");  	} -	fw_ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd_id, -				       IWL_FW_CMD_VER_UNKNOWN); - -	memcpy(&cmd.common, &data, sizeof(struct iwl_tas_config_cmd_common)); - -	/* Set v3 or v4 specific parts. will be trunctated for fw_ver < 3 */ -	if (fw_ver == 4) { -		cmd.v4.override_tas_iec = data.override_tas_iec; -		cmd.v4.enable_tas_iec = data.enable_tas_iec; -		cmd.v4.usa_tas_uhb_allowed = data.usa_tas_uhb_allowed; +	if (fw_ver < 5) { +		selection_data = iwl_parse_tas_selection(data.tas_selection, +							 data.table_revision); +		cmd_v2_v4.common.block_list_size = +			cpu_to_le32(data.block_list_size); +		for (u8 i = 0; i < data.block_list_size; i++) +			cmd_v2_v4.common.block_list_array[i] = +				cpu_to_le32(data.block_list_array[i]); +	} + +	if (fw_ver == 5) { +		cmd_size = sizeof(cmd_v5); +		cmd_data = &cmd_v5; +		cmd_v5.block_list_size = cpu_to_le16(data.block_list_size); +		for (u16 i = 0; i < data.block_list_size; i++) +			cmd_v5.block_list_array[i] = +				cpu_to_le16(data.block_list_array[i]); +		cmd_v5.tas_config_info.table_source = data.table_source; +		cmd_v5.tas_config_info.table_revision = data.table_revision; +		cmd_v5.tas_config_info.value = cpu_to_le32(data.tas_selection); +	} else if (fw_ver == 4) { +		cmd_size = sizeof(cmd_v2_v4.common) + sizeof(cmd_v2_v4.v4); +		cmd_v2_v4.v4.override_tas_iec = selection_data.override_tas_iec; +		cmd_v2_v4.v4.enable_tas_iec = selection_data.enable_tas_iec; +		cmd_v2_v4.v4.usa_tas_uhb_allowed = +			selection_data.usa_tas_uhb_allowed; +		if (fw_has_capa(&mvm->fw->ucode_capa, +				IWL_UCODE_TLV_CAPA_UHB_CANADA_TAS_SUPPORT) && +		    selection_data.canada_tas_uhb_allowed) +			cmd_v2_v4.v4.uhb_allowed_flags = TAS_UHB_ALLOWED_CANADA; +	} else if (fw_ver == 3) { +		cmd_size = sizeof(cmd_v2_v4.common) + sizeof(cmd_v2_v4.v3); +		cmd_v2_v4.v3.override_tas_iec = +			cpu_to_le16(selection_data.override_tas_iec); +		cmd_v2_v4.v3.enable_tas_iec = +			cpu_to_le16(selection_data.enable_tas_iec); +	} else if (fw_ver == 2) { +		cmd_size = sizeof(cmd_v2_v4.common);  	} else { -		cmd.v3.override_tas_iec = cpu_to_le16(data.override_tas_iec); -		cmd.v3.enable_tas_iec = cpu_to_le16(data.enable_tas_iec); +		return;  	} -	cmd_size = sizeof(struct iwl_tas_config_cmd_common); -	if (fw_ver >= 3) -		/* v4 is the same size as v3 */ -		cmd_size += sizeof(struct iwl_tas_config_cmd_v3); - -	ret = iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0, cmd_size, &cmd); +	ret = iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0, cmd_size, cmd_data);  	if (ret < 0)  		IWL_DEBUG_RADIO(mvm, "failed to send TAS_CONFIG (%d)\n", ret);  } -static bool iwl_mvm_eval_dsm_rfi(struct iwl_mvm *mvm) -{ -	u32 value = 0; -	/* default behaviour is disabled */ -	bool bios_enable_rfi = false; -	int ret = iwl_bios_get_dsm(&mvm->fwrt, DSM_FUNC_RFI_CONFIG, &value); - - -	if (ret < 0) { -		IWL_DEBUG_RADIO(mvm, "Failed to get DSM RFI, ret=%d\n", ret); -		return bios_enable_rfi; -	} - -	value &= DSM_VALUE_RFI_DISABLE; -	/* RFI BIOS CONFIG value can be 0 or 3 only. -	 * i.e 0 means DDR and DLVR enabled. 3 means DDR and DLVR disabled. -	 * 1 and 2 are invalid BIOS configurations, So, it's not possible to -	 * disable ddr/dlvr separately. -	 */ -	if (!value) { -		IWL_DEBUG_RADIO(mvm, "DSM RFI is evaluated to enable\n"); -		bios_enable_rfi = true; -	} else if (value == DSM_VALUE_RFI_DISABLE) { -		IWL_DEBUG_RADIO(mvm, "DSM RFI is evaluated to disable\n"); -	} else { -		IWL_DEBUG_RADIO(mvm, -				"DSM RFI got invalid value, value=%d\n", value); -	} - -	return bios_enable_rfi; -} -  static void iwl_mvm_lari_cfg(struct iwl_mvm *mvm)  {  	struct iwl_lari_config_change_cmd cmd; @@ -1272,7 +1247,7 @@ void iwl_mvm_get_bios_tables(struct iwl_mvm *mvm)  		}  	} -	iwl_acpi_get_phy_filters(&mvm->fwrt, &mvm->phy_filters); +	iwl_acpi_get_phy_filters(&mvm->fwrt);  	if (iwl_bios_get_eckv(&mvm->fwrt, &mvm->ext_clock_valid))  		IWL_DEBUG_RADIO(mvm, "ECKV table doesn't exist in BIOS\n"); @@ -1288,8 +1263,8 @@ static void iwl_mvm_disconnect_iterator(void *data, u8 *mac,  void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags)  {  	u32 error_log_size = mvm->fw->ucode_capa.error_log_size; +	u32 status = 0;  	int ret; -	u32 resp;  	struct iwl_fw_error_recovery_cmd recovery_cmd = {  		.flags = cpu_to_le32(flags), @@ -1297,7 +1272,6 @@ void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags)  	};  	struct iwl_host_cmd host_cmd = {  		.id = WIDE_ID(SYSTEM_GROUP, FW_ERROR_RECOVERY_CMD), -		.flags = CMD_WANT_SKB,  		.data = {&recovery_cmd, },  		.len = {sizeof(recovery_cmd), },  	}; @@ -1317,7 +1291,7 @@ void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags)  		recovery_cmd.buf_size = cpu_to_le32(error_log_size);  	} -	ret = iwl_mvm_send_cmd(mvm, &host_cmd); +	ret = iwl_mvm_send_cmd_status(mvm, &host_cmd, &status);  	kfree(mvm->error_recovery_buf);  	mvm->error_recovery_buf = NULL; @@ -1328,11 +1302,10 @@ void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags)  	/* skb respond is only relevant in ERROR_RECOVERY_UPDATE_DB */  	if (flags & ERROR_RECOVERY_UPDATE_DB) { -		resp = le32_to_cpu(*(__le32 *)host_cmd.resp_pkt->data); -		if (resp) { +		if (status) {  			IWL_ERR(mvm,  				"Failed to send recovery cmd blob was invalid %d\n", -				resp); +				status);  			ieee80211_iterate_interfaces(mvm->hw, 0,  						     iwl_mvm_disconnect_iterator, @@ -1384,6 +1357,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)  	int ret, i;  	struct ieee80211_supported_band *sband = NULL; +	lockdep_assert_wiphy(mvm->hw->wiphy);  	lockdep_assert_held(&mvm->mutex);  	ret = iwl_trans_start_hw(mvm->trans); @@ -1464,10 +1438,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)  		RCU_INIT_POINTER(mvm->fw_id_to_link_sta[i], NULL);  	} -	for (i = 0; i < IWL_MVM_FW_MAX_LINK_ID + 1; i++) -		RCU_INIT_POINTER(mvm->link_id_to_link_conf[i], NULL); - -	mvm->tdls_cs.peer.sta_id = IWL_MVM_INVALID_STA; +	mvm->tdls_cs.peer.sta_id = IWL_INVALID_STA;  	/* reset quota debouncing buffer - 0xff will yield invalid data */  	memset(&mvm->last_quota_cmd, 0xff, sizeof(mvm->last_quota_cmd)); @@ -1586,7 +1557,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)  	iwl_mvm_uats_init(mvm);  	if (iwl_rfi_supported(mvm)) { -		if (iwl_mvm_eval_dsm_rfi(mvm)) +		if (iwl_rfi_is_enabled_in_bios(&mvm->fwrt))  			iwl_rfi_send_config_cmd(mvm, NULL);  	} @@ -1603,6 +1574,7 @@ int iwl_mvm_load_d3_fw(struct iwl_mvm *mvm)  {  	int ret, i; +	lockdep_assert_wiphy(mvm->hw->wiphy);  	lockdep_assert_held(&mvm->mutex);  	ret = iwl_trans_start_hw(mvm->trans); | 
