diff options
Diffstat (limited to 'drivers/net/wireless/intel')
| -rw-r--r-- | drivers/net/wireless/intel/ipw2x00/ipw2100.c | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/ipw2x00/ipw2200.h | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlegacy/common.c | 15 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlegacy/common.h | 12 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/fw/acpi.c | 96 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/fw/init.c | 4 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 28 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/iwl-drv.h | 3 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 10 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 12 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c | 34 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 6 | 
13 files changed, 153 insertions, 73 deletions
diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2100.c b/drivers/net/wireless/intel/ipw2x00/ipw2100.c index b6636002c7d2..fe75941c584d 100644 --- a/drivers/net/wireless/intel/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/intel/ipw2x00/ipw2100.c @@ -2518,7 +2518,7 @@ static void isr_rx_monitor(struct ipw2100_priv *priv, int i,  	 * to build this manually element by element, we can write it much  	 * more efficiently than we can parse it. ORDER MATTERS HERE */  	struct ipw_rt_hdr { -		struct ieee80211_radiotap_header rt_hdr; +		struct ieee80211_radiotap_header_fixed rt_hdr;  		s8 rt_dbmsignal; /* signal in dbM, kluged to signed */  	} *ipw_rt; diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.h b/drivers/net/wireless/intel/ipw2x00/ipw2200.h index 8ebf09121e17..226286cb7eb8 100644 --- a/drivers/net/wireless/intel/ipw2x00/ipw2200.h +++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.h @@ -1143,7 +1143,7 @@ struct ipw_prom_priv {   * structure is provided regardless of any bits unset.   */  struct ipw_rt_hdr { -	struct ieee80211_radiotap_header rt_hdr; +	struct ieee80211_radiotap_header_fixed rt_hdr;  	u64 rt_tsf;      /* TSF */	/* XXX */  	u8 rt_flags;	/* radiotap packet flags */  	u8 rt_rate;	/* rate in 500kb/s */ diff --git a/drivers/net/wireless/intel/iwlegacy/common.c b/drivers/net/wireless/intel/iwlegacy/common.c index 9d33a66a49b5..958dd4f9bc69 100644 --- a/drivers/net/wireless/intel/iwlegacy/common.c +++ b/drivers/net/wireless/intel/iwlegacy/common.c @@ -3122,6 +3122,7 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd)  	struct il_cmd_meta *out_meta;  	dma_addr_t phys_addr;  	unsigned long flags; +	u8 *out_payload;  	u32 idx;  	u16 fix_size; @@ -3157,6 +3158,16 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd)  	out_cmd = txq->cmd[idx];  	out_meta = &txq->meta[idx]; +	/* The payload is in the same place in regular and huge +	 * command buffers, but we need to let the compiler know when +	 * we're using a larger payload buffer to avoid "field- +	 * spanning write" warnings at run-time for huge commands. +	 */ +	if (cmd->flags & CMD_SIZE_HUGE) +		out_payload = ((struct il_device_cmd_huge *)out_cmd)->cmd.payload; +	else +		out_payload = out_cmd->cmd.payload; +  	if (WARN_ON(out_meta->flags & CMD_MAPPED)) {  		spin_unlock_irqrestore(&il->hcmd_lock, flags);  		return -ENOSPC; @@ -3170,7 +3181,7 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd)  		out_meta->callback = cmd->callback;  	out_cmd->hdr.cmd = cmd->id; -	memcpy(&out_cmd->cmd.payload, cmd->data, cmd->len); +	memcpy(out_payload, cmd->data, cmd->len);  	/* At this point, the out_cmd now has all of the incoming cmd  	 * information */ @@ -4962,6 +4973,8 @@ il_pci_resume(struct device *device)  	 */  	pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); +	_il_wr(il, CSR_INT, 0xffffffff); +	_il_wr(il, CSR_FH_INT_STATUS, 0xffffffff);  	il_enable_interrupts(il);  	if (!(_il_rd(il, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) diff --git a/drivers/net/wireless/intel/iwlegacy/common.h b/drivers/net/wireless/intel/iwlegacy/common.h index 2147781b5fff..725c2a88ddb7 100644 --- a/drivers/net/wireless/intel/iwlegacy/common.h +++ b/drivers/net/wireless/intel/iwlegacy/common.h @@ -560,6 +560,18 @@ struct il_device_cmd {  #define TFD_MAX_PAYLOAD_SIZE (sizeof(struct il_device_cmd)) +/** + * struct il_device_cmd_huge + * + * For use when sending huge commands. + */ +struct il_device_cmd_huge { +	struct il_cmd_header hdr;	/* uCode API */ +	union { +		u8 payload[IL_MAX_CMD_SIZE - sizeof(struct il_cmd_header)]; +	} __packed cmd; +} __packed; +  struct il_host_cmd {  	const void *data;  	unsigned long reply_page; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c index a7cea0a55b35..0bc32291815e 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c @@ -429,38 +429,28 @@ out_free:  	return ret;  } -static int iwl_acpi_sar_set_profile(union acpi_object *table, -				    struct iwl_sar_profile *profile, -				    bool enabled, u8 num_chains, -				    u8 num_sub_bands) +static int +iwl_acpi_parse_chains_table(union acpi_object *table, +			    struct iwl_sar_profile_chain *chains, +			    u8 num_chains, u8 num_sub_bands)  { -	int i, j, idx = 0; - -	/* -	 * The table from ACPI is flat, but we store it in a -	 * structured array. -	 */ -	for (i = 0; i < BIOS_SAR_MAX_CHAINS_PER_PROFILE; i++) { -		for (j = 0; j < BIOS_SAR_MAX_SUB_BANDS_NUM; j++) { +	for (u8 chain = 0; chain < num_chains; chain++) { +		for (u8 subband = 0; subband < BIOS_SAR_MAX_SUB_BANDS_NUM; +		     subband++) {  			/* if we don't have the values, use the default */ -			if (i >= num_chains || j >= num_sub_bands) { -				profile->chains[i].subbands[j] = 0; +			if (subband >= num_sub_bands) { +				chains[chain].subbands[subband] = 0; +			} else if (table->type != ACPI_TYPE_INTEGER || +				   table->integer.value > U8_MAX) { +				return -EINVAL;  			} else { -				if (table[idx].type != ACPI_TYPE_INTEGER || -				    table[idx].integer.value > U8_MAX) -					return -EINVAL; - -				profile->chains[i].subbands[j] = -					table[idx].integer.value; - -				idx++; +				chains[chain].subbands[subband] = +					table->integer.value; +				table++;  			}  		}  	} -	/* Only if all values were valid can the profile be enabled */ -	profile->enabled = enabled; -  	return 0;  } @@ -543,9 +533,11 @@ read_table:  	/* The profile from WRDS is officially profile 1, but goes  	 * into sar_profiles[0] (because we don't have a profile 0).  	 */ -	ret = iwl_acpi_sar_set_profile(table, &fwrt->sar_profiles[0], -				       flags & IWL_SAR_ENABLE_MSK, -				       num_chains, num_sub_bands); +	ret = iwl_acpi_parse_chains_table(table, fwrt->sar_profiles[0].chains, +					  num_chains, num_sub_bands); +	if (!ret && flags & IWL_SAR_ENABLE_MSK) +		fwrt->sar_profiles[0].enabled = true; +  out_free:  	kfree(data);  	return ret; @@ -557,7 +549,7 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt)  	bool enabled;  	int i, n_profiles, tbl_rev, pos;  	int ret = 0; -	u8 num_chains, num_sub_bands; +	u8 num_sub_bands;  	data = iwl_acpi_get_object(fwrt->dev, ACPI_EWRD_METHOD);  	if (IS_ERR(data)) @@ -573,7 +565,6 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt)  			goto out_free;  		} -		num_chains = ACPI_SAR_NUM_CHAINS_REV2;  		num_sub_bands = ACPI_SAR_NUM_SUB_BANDS_REV2;  		goto read_table; @@ -589,7 +580,6 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt)  			goto out_free;  		} -		num_chains = ACPI_SAR_NUM_CHAINS_REV1;  		num_sub_bands = ACPI_SAR_NUM_SUB_BANDS_REV1;  		goto read_table; @@ -605,7 +595,6 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt)  			goto out_free;  		} -		num_chains = ACPI_SAR_NUM_CHAINS_REV0;  		num_sub_bands = ACPI_SAR_NUM_SUB_BANDS_REV0;  		goto read_table; @@ -637,23 +626,54 @@ read_table:  	/* the tables start at element 3 */  	pos = 3; +	BUILD_BUG_ON(ACPI_SAR_NUM_CHAINS_REV0 != ACPI_SAR_NUM_CHAINS_REV1); +	BUILD_BUG_ON(ACPI_SAR_NUM_CHAINS_REV2 != 2 * ACPI_SAR_NUM_CHAINS_REV0); + +	/* parse non-cdb chains for all profiles */  	for (i = 0; i < n_profiles; i++) {  		union acpi_object *table = &wifi_pkg->package.elements[pos]; +  		/* The EWRD profiles officially go from 2 to 4, but we  		 * save them in sar_profiles[1-3] (because we don't  		 * have profile 0).  So in the array we start from 1.  		 */ -		ret = iwl_acpi_sar_set_profile(table, -					       &fwrt->sar_profiles[i + 1], -					       enabled, num_chains, -					       num_sub_bands); +		ret = iwl_acpi_parse_chains_table(table, +						  fwrt->sar_profiles[i + 1].chains, +						  ACPI_SAR_NUM_CHAINS_REV0, +						  num_sub_bands); +		if (ret < 0) +			goto out_free; + +		/* go to the next table */ +		pos += ACPI_SAR_NUM_CHAINS_REV0 * num_sub_bands; +	} + +	/* non-cdb table revisions */ +	if (tbl_rev < 2) +		goto set_enabled; + +	/* parse cdb chains for all profiles */ +	for (i = 0; i < n_profiles; i++) { +		struct iwl_sar_profile_chain *chains; +		union acpi_object *table; + +		table = &wifi_pkg->package.elements[pos]; +		chains = &fwrt->sar_profiles[i + 1].chains[ACPI_SAR_NUM_CHAINS_REV0]; +		ret = iwl_acpi_parse_chains_table(table, +						  chains, +						  ACPI_SAR_NUM_CHAINS_REV0, +						  num_sub_bands);  		if (ret < 0) -			break; +			goto out_free;  		/* go to the next table */ -		pos += num_chains * num_sub_bands; +		pos += ACPI_SAR_NUM_CHAINS_REV0 * num_sub_bands;  	} +set_enabled: +	for (i = 0; i < n_profiles; i++) +		fwrt->sar_profiles[i + 1].enabled = enabled; +  out_free:  	kfree(data);  	return ret; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/init.c b/drivers/net/wireless/intel/iwlwifi/fw/init.c index d8b083be5b6b..de87e0e3e072 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/init.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/init.c @@ -39,10 +39,12 @@ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,  }  IWL_EXPORT_SYMBOL(iwl_fw_runtime_init); +/* Assumes the appropriate lock is held by the caller */  void iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt)  {  	iwl_fw_suspend_timestamp(fwrt); -	iwl_dbg_tlv_time_point(fwrt, IWL_FW_INI_TIME_POINT_HOST_D3_START, NULL); +	iwl_dbg_tlv_time_point_sync(fwrt, IWL_FW_INI_TIME_POINT_HOST_D3_START, +				    NULL);  }  IWL_EXPORT_SYMBOL(iwl_fw_runtime_suspend); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index 2abfc986701f..c620911a1193 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c @@ -1413,25 +1413,35 @@ _iwl_op_mode_start(struct iwl_drv *drv, struct iwlwifi_opmode_table *op)  	const struct iwl_op_mode_ops *ops = op->ops;  	struct dentry *dbgfs_dir = NULL;  	struct iwl_op_mode *op_mode = NULL; +	int retry, max_retry = !!iwlwifi_mod_params.fw_restart * IWL_MAX_INIT_RETRY;  	/* also protects start/stop from racing against each other */  	lockdep_assert_held(&iwlwifi_opmode_table_mtx); +	for (retry = 0; retry <= max_retry; retry++) { +  #ifdef CONFIG_IWLWIFI_DEBUGFS -	drv->dbgfs_op_mode = debugfs_create_dir(op->name, -						drv->dbgfs_drv); -	dbgfs_dir = drv->dbgfs_op_mode; +		drv->dbgfs_op_mode = debugfs_create_dir(op->name, +							drv->dbgfs_drv); +		dbgfs_dir = drv->dbgfs_op_mode;  #endif -	op_mode = ops->start(drv->trans, drv->trans->cfg, -			     &drv->fw, dbgfs_dir); -	if (op_mode) -		return op_mode; +		op_mode = ops->start(drv->trans, drv->trans->cfg, +				     &drv->fw, dbgfs_dir); + +		if (op_mode) +			return op_mode; + +		if (test_bit(STATUS_TRANS_DEAD, &drv->trans->status)) +			break; + +		IWL_ERR(drv, "retry init count %d\n", retry);  #ifdef CONFIG_IWLWIFI_DEBUGFS -	debugfs_remove_recursive(drv->dbgfs_op_mode); -	drv->dbgfs_op_mode = NULL; +		debugfs_remove_recursive(drv->dbgfs_op_mode); +		drv->dbgfs_op_mode = NULL;  #endif +	}  	return NULL;  } diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.h b/drivers/net/wireless/intel/iwlwifi/iwl-drv.h index 1549ff429549..6a1d31892417 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.h @@ -98,6 +98,9 @@ void iwl_drv_stop(struct iwl_drv *drv);  #define VISIBLE_IF_IWLWIFI_KUNIT static  #endif +/* max retry for init flow */ +#define IWL_MAX_INIT_RETRY 2 +  #define FW_NAME_PRE_BUFSIZE	64  struct iwl_trans;  const char *iwl_drv_get_fwname_pre(struct iwl_trans *trans, char *buf); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 49a6aff42376..244ca8cab9d1 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -1398,7 +1398,9 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)  	iwl_mvm_pause_tcm(mvm, true); +	mutex_lock(&mvm->mutex);  	iwl_fw_runtime_suspend(&mvm->fwrt); +	mutex_unlock(&mvm->mutex);  	return __iwl_mvm_suspend(hw, wowlan, false);  } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 08546e673cf5..f30b0fc8eca9 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -1307,8 +1307,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), @@ -1316,7 +1316,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), },  	}; @@ -1336,7 +1335,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; @@ -1347,11 +1346,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, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index a327893c6dce..80b9a115245f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -1293,12 +1293,14 @@ int iwl_mvm_mac_start(struct ieee80211_hw *hw)  {  	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);  	int ret; +	int retry, max_retry = 0;  	mutex_lock(&mvm->mutex);  	/* we are starting the mac not in error flow, and restart is enabled */  	if (!test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status) &&  	    iwlwifi_mod_params.fw_restart) { +		max_retry = IWL_MAX_INIT_RETRY;  		/*  		 * This will prevent mac80211 recovery flows to trigger during  		 * init failures @@ -1306,7 +1308,13 @@ int iwl_mvm_mac_start(struct ieee80211_hw *hw)  		set_bit(IWL_MVM_STATUS_STARTING, &mvm->status);  	} -	ret = __iwl_mvm_mac_start(mvm); +	for (retry = 0; retry <= max_retry; retry++) { +		ret = __iwl_mvm_mac_start(mvm); +		if (!ret) +			break; + +		IWL_ERR(mvm, "mac start retry %d\n", retry); +	}  	clear_bit(IWL_MVM_STATUS_STARTING, &mvm->status);  	mutex_unlock(&mvm->mutex); @@ -1970,7 +1978,6 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,  		mvm->p2p_device_vif = NULL;  	} -	iwl_mvm_unset_link_mapping(mvm, vif, &vif->bss_conf);  	iwl_mvm_mac_ctxt_remove(mvm, vif);  	RCU_INIT_POINTER(mvm->vif_id_to_mac[mvmvif->id], NULL); @@ -1979,6 +1986,7 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,  		mvm->monitor_on = false;  out: +	iwl_mvm_unset_link_mapping(mvm, vif, &vif->bss_conf);  	if (vif->type == NL80211_IFTYPE_AP ||  	    vif->type == NL80211_IFTYPE_ADHOC) {  		iwl_mvm_dealloc_int_sta(mvm, &mvmvif->deflink.mcast_sta); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c index f2378e0fb2fb..e252f0dcea20 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c @@ -41,8 +41,6 @@ static int iwl_mvm_mld_mac_add_interface(struct ieee80211_hw *hw,  	/* reset deflink MLO parameters */  	mvmvif->deflink.fw_link_id = IWL_MVM_FW_LINK_ID_INVALID;  	mvmvif->deflink.active = 0; -	/* the first link always points to the default one */ -	mvmvif->link[0] = &mvmvif->deflink;  	ret = iwl_mvm_mld_mac_ctxt_add(mvm, vif);  	if (ret) @@ -60,9 +58,19 @@ static int iwl_mvm_mld_mac_add_interface(struct ieee80211_hw *hw,  				     IEEE80211_VIF_SUPPORTS_CQM_RSSI;  	} -	ret = iwl_mvm_add_link(mvm, vif, &vif->bss_conf); -	if (ret) -		goto out_free_bf; +	/* We want link[0] to point to the default link, unless we have MLO and +	 * in this case this will be modified later by .change_vif_links() +	 * If we are in the restart flow with an MLD connection, we will wait +	 * to .change_vif_links() to setup the links. +	 */ +	if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) || +	    !ieee80211_vif_is_mld(vif)) { +		mvmvif->link[0] = &mvmvif->deflink; + +		ret = iwl_mvm_add_link(mvm, vif, &vif->bss_conf); +		if (ret) +			goto out_free_bf; +	}  	/* Save a pointer to p2p device vif, so it can later be used to  	 * update the p2p device MAC when a GO is started/stopped @@ -350,11 +358,6 @@ __iwl_mvm_mld_assign_vif_chanctx(struct iwl_mvm *mvm,  		rcu_read_unlock();  	} -	if (vif->type == NL80211_IFTYPE_STATION) -		iwl_mvm_send_ap_tx_power_constraint_cmd(mvm, vif, -							link_conf, -							false); -  	/* then activate */  	ret = iwl_mvm_link_changed(mvm, vif, link_conf,  				   LINK_CONTEXT_MODIFY_ACTIVE | @@ -363,6 +366,11 @@ __iwl_mvm_mld_assign_vif_chanctx(struct iwl_mvm *mvm,  	if (ret)  		goto out; +	if (vif->type == NL80211_IFTYPE_STATION) +		iwl_mvm_send_ap_tx_power_constraint_cmd(mvm, vif, +							link_conf, +							false); +  	/*  	 * Power state must be updated before quotas,  	 * otherwise fw will complain. @@ -1194,7 +1202,11 @@ iwl_mvm_mld_change_vif_links(struct ieee80211_hw *hw,  	mutex_lock(&mvm->mutex); -	if (old_links == 0) { +	/* If we're in RESTART flow, the default link wasn't added in +         * drv_add_interface(), and link[0] doesn't point to it. +	 */ +	if (old_links == 0 && !test_bit(IWL_MVM_STATUS_IN_HW_RESTART, +					&mvm->status)) {  		err = iwl_mvm_disable_link(mvm, vif, &vif->bss_conf);  		if (err)  			goto out_err; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c index 3ce9150213a7..ddcbd80a49fb 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c @@ -1774,7 +1774,7 @@ iwl_mvm_umac_scan_cfg_channels_v7_6g(struct iwl_mvm *mvm,  			&cp->channel_config[ch_cnt];  		u32 s_ssid_bitmap = 0, bssid_bitmap = 0, flags = 0; -		u8 j, k, n_s_ssids = 0, n_bssids = 0; +		u8 k, n_s_ssids = 0, n_bssids = 0;  		u8 max_s_ssids, max_bssids;  		bool force_passive = false, found = false, allow_passive = true,  		     unsolicited_probe_on_chan = false, psc_no_listen = false; @@ -1799,7 +1799,7 @@ iwl_mvm_umac_scan_cfg_channels_v7_6g(struct iwl_mvm *mvm,  		cfg->v5.iter_count = 1;  		cfg->v5.iter_interval = 0; -		for (j = 0; j < params->n_6ghz_params; j++) { +		for (u32 j = 0; j < params->n_6ghz_params; j++) {  			s8 tmp_psd_20;  			if (!(scan_6ghz_params[j].channel_idx == i)) @@ -1873,7 +1873,7 @@ iwl_mvm_umac_scan_cfg_channels_v7_6g(struct iwl_mvm *mvm,  		 * SSID.  		 * TODO: improve this logic  		 */ -		for (j = 0; j < params->n_6ghz_params; j++) { +		for (u32 j = 0; j < params->n_6ghz_params; j++) {  			if (!(scan_6ghz_params[j].channel_idx == i))  				continue;  | 
