diff options
Diffstat (limited to 'drivers/net/wireless/intel')
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/fw/notif-wait.c | 10 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/fw/pnvm.c | 4 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/iwl-config.h | 1 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c | 7 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 1 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/rfi.c | 6 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 17 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c | 31 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c | 3 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 30 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 3 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c | 35 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 7 | 
15 files changed, 103 insertions, 56 deletions
| diff --git a/drivers/net/wireless/intel/iwlwifi/fw/notif-wait.c b/drivers/net/wireless/intel/iwlwifi/fw/notif-wait.c index 3dbc6f3f92cc..231d2517f398 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/notif-wait.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/notif-wait.c @@ -1,6 +1,6 @@  // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause  /* - * Copyright (C) 2005-2014 Intel Corporation + * Copyright (C) 2005-2014, 2021 Intel Corporation   * Copyright (C) 2015-2017 Intel Deutschland GmbH   */  #include <linux/sched.h> @@ -26,7 +26,7 @@ bool iwl_notification_wait(struct iwl_notif_wait_data *notif_wait,  	if (!list_empty(¬if_wait->notif_waits)) {  		struct iwl_notification_wait *w; -		spin_lock(¬if_wait->notif_wait_lock); +		spin_lock_bh(¬if_wait->notif_wait_lock);  		list_for_each_entry(w, ¬if_wait->notif_waits, list) {  			int i;  			bool found = false; @@ -59,7 +59,7 @@ bool iwl_notification_wait(struct iwl_notif_wait_data *notif_wait,  				triggered = true;  			}  		} -		spin_unlock(¬if_wait->notif_wait_lock); +		spin_unlock_bh(¬if_wait->notif_wait_lock);  	}  	return triggered; @@ -70,10 +70,10 @@ void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait)  {  	struct iwl_notification_wait *wait_entry; -	spin_lock(¬if_wait->notif_wait_lock); +	spin_lock_bh(¬if_wait->notif_wait_lock);  	list_for_each_entry(wait_entry, ¬if_wait->notif_waits, list)  		wait_entry->aborted = true; -	spin_unlock(¬if_wait->notif_wait_lock); +	spin_unlock_bh(¬if_wait->notif_wait_lock);  	wake_up_all(¬if_wait->notif_waitq);  } diff --git a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c index fd070ca5e517..40f2109a097f 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c @@ -271,12 +271,12 @@ static int iwl_pnvm_get_from_efi(struct iwl_trans *trans,  	err = efivar_entry_get(pnvm_efivar, NULL, &package_size, package);  	if (err) {  		IWL_DEBUG_FW(trans, -			     "PNVM UEFI variable not found %d (len %zd)\n", +			     "PNVM UEFI variable not found %d (len %lu)\n",  			     err, package_size);  		goto out;  	} -	IWL_DEBUG_FW(trans, "Read PNVM fro UEFI with size %zd\n", package_size); +	IWL_DEBUG_FW(trans, "Read PNVM fro UEFI with size %lu\n", package_size);  	*data = kmemdup(package->data, *len, GFP_KERNEL);  	if (!*data) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index 75f99ff7f908..c4f5da76f1c0 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -414,6 +414,7 @@ struct iwl_cfg {  #define IWL_CFG_MAC_TYPE_QNJ		0x36  #define IWL_CFG_MAC_TYPE_SO		0x37  #define IWL_CFG_MAC_TYPE_SNJ		0x42 +#define IWL_CFG_MAC_TYPE_SOF		0x43  #define IWL_CFG_MAC_TYPE_MA		0x44  #define IWL_CFG_RF_TYPE_TH		0x105 diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c index af684f80b0cc..c5a1e84dc1ab 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c @@ -232,7 +232,7 @@ enum iwl_reg_capa_flags_v2 {  	REG_CAPA_V2_MCS_9_ALLOWED	= BIT(6),  	REG_CAPA_V2_WEATHER_DISABLED	= BIT(7),  	REG_CAPA_V2_40MHZ_ALLOWED	= BIT(8), -	REG_CAPA_V2_11AX_DISABLED	= BIT(13), +	REG_CAPA_V2_11AX_DISABLED	= BIT(10),  };  /* diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h index 868da7e79a45..e6d2e0994317 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h @@ -205,6 +205,8 @@ static inline void iwl_op_mode_time_point(struct iwl_op_mode *op_mode,  					  enum iwl_fw_ini_time_point tp_id,  					  union iwl_dbg_tlv_tp_data *tp_data)  { +	if (!op_mode || !op_mode->ops || !op_mode->ops->time_point) +		return;  	op_mode->ops->time_point(op_mode, tp_id, tp_data);  } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c index 130760572262..34ddef97b099 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c @@ -1786,10 +1786,13 @@ static ssize_t iwl_dbgfs_rfi_freq_table_write(struct iwl_mvm *mvm, char *buf,  		return -EINVAL;  	/* value zero triggers re-sending the default table to the device */ -	if (!op_id) +	if (!op_id) { +		mutex_lock(&mvm->mutex);  		ret = iwl_rfi_send_config_cmd(mvm, NULL); -	else +		mutex_unlock(&mvm->mutex); +	} else {  		ret = -EOPNOTSUPP; /* in the future a new table will be added */ +	}  	return ret ?: count;  } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 15e2773ce7e7..5ee64f7f3c85 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -1083,6 +1083,7 @@ static const struct dmi_system_id dmi_ppag_approved_list[] = {  			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTek COMPUTER INC."),  		},  	}, +	{}  };  static int iwl_mvm_ppag_init(struct iwl_mvm *mvm) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rfi.c b/drivers/net/wireless/intel/iwlwifi/mvm/rfi.c index 873919048143..0b818067067c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rfi.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rfi.c @@ -1,6 +1,6 @@  // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause  /* - * Copyright (C) 2020 Intel Corporation + * Copyright (C) 2020 - 2021 Intel Corporation   */  #include "mvm.h" @@ -66,6 +66,8 @@ int iwl_rfi_send_config_cmd(struct iwl_mvm *mvm, struct iwl_rfi_lut_entry *rfi_t  	if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_RFIM_SUPPORT))  		return -EOPNOTSUPP; +	lockdep_assert_held(&mvm->mutex); +  	/* in case no table is passed, use the default one */  	if (!rfi_table) {  		memcpy(cmd.table, iwl_rfi_table, sizeof(cmd.table)); @@ -75,9 +77,7 @@ int iwl_rfi_send_config_cmd(struct iwl_mvm *mvm, struct iwl_rfi_lut_entry *rfi_t  		cmd.oem = 1;  	} -	mutex_lock(&mvm->mutex);  	ret = iwl_mvm_send_cmd(mvm, &hcmd); -	mutex_unlock(&mvm->mutex);  	if (ret)  		IWL_ERR(mvm, "Failed to send RFI config cmd %d\n", ret); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index c21736f80c29..af5a6dd81c41 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -272,10 +272,10 @@ static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm,  	rx_status->chain_signal[2] = S8_MIN;  } -static int iwl_mvm_rx_mgmt_crypto(struct ieee80211_sta *sta, -				  struct ieee80211_hdr *hdr, -				  struct iwl_rx_mpdu_desc *desc, -				  u32 status) +static int iwl_mvm_rx_mgmt_prot(struct ieee80211_sta *sta, +				struct ieee80211_hdr *hdr, +				struct iwl_rx_mpdu_desc *desc, +				u32 status)  {  	struct iwl_mvm_sta *mvmsta;  	struct iwl_mvm_vif *mvmvif; @@ -285,6 +285,9 @@ static int iwl_mvm_rx_mgmt_crypto(struct ieee80211_sta *sta,  	u32 len = le16_to_cpu(desc->mpdu_len);  	const u8 *frame = (void *)hdr; +	if ((status & IWL_RX_MPDU_STATUS_SEC_MASK) == IWL_RX_MPDU_STATUS_SEC_NONE) +		return 0; +  	/*  	 * For non-beacon, we don't really care. But beacons may  	 * be filtered out, and we thus need the firmware's replay @@ -356,6 +359,10 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_sta *sta,  	    IWL_RX_MPDU_STATUS_SEC_UNKNOWN && !mvm->monitor_on)  		return -1; +	if (unlikely(ieee80211_is_mgmt(hdr->frame_control) && +		     !ieee80211_has_protected(hdr->frame_control))) +		return iwl_mvm_rx_mgmt_prot(sta, hdr, desc, status); +  	if (!ieee80211_has_protected(hdr->frame_control) ||  	    (status & IWL_RX_MPDU_STATUS_SEC_MASK) ==  	    IWL_RX_MPDU_STATUS_SEC_NONE) @@ -411,7 +418,7 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_sta *sta,  		stats->flag |= RX_FLAG_DECRYPTED;  		return 0;  	case RX_MPDU_RES_STATUS_SEC_CMAC_GMAC_ENC: -		return iwl_mvm_rx_mgmt_crypto(sta, hdr, desc, status); +		break;  	default:  		/*  		 * Sometimes we can get frames that were not decrypted diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c index 8fba190e84cf..cecc32e7dbe8 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c @@ -1,6 +1,6 @@  // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause  /* - * Copyright (C) 2018-2020 Intel Corporation + * Copyright (C) 2018-2021 Intel Corporation   */  #include "iwl-trans.h"  #include "iwl-fh.h" @@ -75,15 +75,6 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,  				 const struct fw_img *fw)  {  	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); -	u32 ltr_val = CSR_LTR_LONG_VAL_AD_NO_SNOOP_REQ | -		      u32_encode_bits(CSR_LTR_LONG_VAL_AD_SCALE_USEC, -				      CSR_LTR_LONG_VAL_AD_NO_SNOOP_SCALE) | -		      u32_encode_bits(250, -				      CSR_LTR_LONG_VAL_AD_NO_SNOOP_VAL) | -		      CSR_LTR_LONG_VAL_AD_SNOOP_REQ | -		      u32_encode_bits(CSR_LTR_LONG_VAL_AD_SCALE_USEC, -				      CSR_LTR_LONG_VAL_AD_SNOOP_SCALE) | -		      u32_encode_bits(250, CSR_LTR_LONG_VAL_AD_SNOOP_VAL);  	struct iwl_context_info_gen3 *ctxt_info_gen3;  	struct iwl_prph_scratch *prph_scratch;  	struct iwl_prph_scratch_ctrl_cfg *prph_sc_ctrl; @@ -217,26 +208,6 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,  	iwl_set_bit(trans, CSR_CTXT_INFO_BOOT_CTRL,  		    CSR_AUTO_FUNC_BOOT_ENA); -	/* -	 * To workaround hardware latency issues during the boot process, -	 * initialize the LTR to ~250 usec (see ltr_val above). -	 * The firmware initializes this again later (to a smaller value). -	 */ -	if ((trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_AX210 || -	     trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000) && -	    !trans->trans_cfg->integrated) { -		iwl_write32(trans, CSR_LTR_LONG_VAL_AD, ltr_val); -	} else if (trans->trans_cfg->integrated && -		   trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000) { -		iwl_write_prph(trans, HPM_MAC_LTR_CSR, HPM_MAC_LRT_ENABLE_ALL); -		iwl_write_prph(trans, HPM_UMAC_LTR, ltr_val); -	} - -	if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) -		iwl_write_umac_prph(trans, UREG_CPU_INIT_RUN, 1); -	else -		iwl_set_bit(trans, CSR_GP_CNTRL, CSR_AUTO_FUNC_INIT); -  	return 0;  err_free_ctxt_info: diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c index d1bb273d6b6d..74ce31fdf45e 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c @@ -1,7 +1,7 @@  // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause  /*   * Copyright (C) 2017 Intel Deutschland GmbH - * Copyright (C) 2018-2020 Intel Corporation + * Copyright (C) 2018-2021 Intel Corporation   */  #include "iwl-trans.h"  #include "iwl-fh.h" @@ -240,7 +240,6 @@ int iwl_pcie_ctxt_info_init(struct iwl_trans *trans,  	/* kick FW self load */  	iwl_write64(trans, CSR_CTXT_INFO_BA, trans_pcie->ctxt_info_dma_addr); -	iwl_write_prph(trans, UREG_CPU_INIT_RUN, 1);  	/* Context info will be released upon alive or failure to get one */ diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index 314fec4a89ad..558a0b2ef0fc 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -592,6 +592,7 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {  	IWL_DEV_INFO(0x4DF0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0, NULL),  	IWL_DEV_INFO(0x4DF0, 0x2074, iwl_ax201_cfg_qu_hr, NULL),  	IWL_DEV_INFO(0x4DF0, 0x4070, iwl_ax201_cfg_qu_hr, NULL), +	IWL_DEV_INFO(0x4DF0, 0x6074, iwl_ax201_cfg_qu_hr, NULL),  	/* So with HR */  	IWL_DEV_INFO(0x2725, 0x0090, iwlax211_2ax_cfg_so_gf_a0, NULL), @@ -1040,7 +1041,31 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {  		      IWL_CFG_MAC_TYPE_SO, IWL_CFG_ANY,  		      IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY,  		      IWL_CFG_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, -		      iwl_cfg_so_a0_hr_a0, iwl_ax201_name) +		      iwl_cfg_so_a0_hr_a0, iwl_ax201_name), + +/* So-F with Hr */ +	_IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, +		      IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, +		      IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, +		      IWL_CFG_NO_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, +		      iwl_cfg_so_a0_hr_a0, iwl_ax203_name), +	_IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, +		      IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, +		      IWL_CFG_RF_TYPE_HR1, IWL_CFG_ANY, +		      IWL_CFG_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, +		      iwl_cfg_so_a0_hr_a0, iwl_ax101_name), +	_IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, +		      IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, +		      IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, +		      IWL_CFG_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, +		      iwl_cfg_so_a0_hr_a0, iwl_ax201_name), + +/* So-F with Gf */ +	_IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, +		      IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, +		      IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY, +		      IWL_CFG_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, +		      iwlax211_2ax_cfg_so_gf_a0, iwl_ax211_name),  #endif /* CONFIG_IWLMVM */  }; @@ -1106,6 +1131,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  		}  	} +#if IS_ENABLED(CONFIG_IWLMVM) +  	/*  	 * Workaround for problematic SnJ device: sometimes when  	 * certain RF modules are connected to SnJ, the device ID @@ -1116,7 +1143,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  	if (CSR_HW_REV_TYPE(iwl_trans->hw_rev) == IWL_CFG_MAC_TYPE_SNJ)  		iwl_trans->trans_cfg = &iwl_so_trans_cfg; -#if IS_ENABLED(CONFIG_IWLMVM)  	/*  	 * special-case 7265D, it has the same PCI IDs.  	 * diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c index 42426e25cac6..2bec97133119 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -1129,6 +1129,8 @@ static int _iwl_pcie_rx_init(struct iwl_trans *trans)  		iwl_pcie_rx_init_rxb_lists(rxq); +		spin_unlock_bh(&rxq->lock); +  		if (!rxq->napi.poll) {  			int (*poll)(struct napi_struct *, int) = iwl_pcie_napi_poll; @@ -1149,7 +1151,6 @@ static int _iwl_pcie_rx_init(struct iwl_trans *trans)  			napi_enable(&rxq->napi);  		} -		spin_unlock_bh(&rxq->lock);  	}  	/* move the pool to the default queue and allocator ownerships */ diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c index 497ef3405da3..94ffc1ae484d 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c @@ -266,6 +266,34 @@ void iwl_trans_pcie_gen2_fw_alive(struct iwl_trans *trans, u32 scd_addr)  	mutex_unlock(&trans_pcie->mutex);  } +static void iwl_pcie_set_ltr(struct iwl_trans *trans) +{ +	u32 ltr_val = CSR_LTR_LONG_VAL_AD_NO_SNOOP_REQ | +		      u32_encode_bits(CSR_LTR_LONG_VAL_AD_SCALE_USEC, +				      CSR_LTR_LONG_VAL_AD_NO_SNOOP_SCALE) | +		      u32_encode_bits(250, +				      CSR_LTR_LONG_VAL_AD_NO_SNOOP_VAL) | +		      CSR_LTR_LONG_VAL_AD_SNOOP_REQ | +		      u32_encode_bits(CSR_LTR_LONG_VAL_AD_SCALE_USEC, +				      CSR_LTR_LONG_VAL_AD_SNOOP_SCALE) | +		      u32_encode_bits(250, CSR_LTR_LONG_VAL_AD_SNOOP_VAL); + +	/* +	 * To workaround hardware latency issues during the boot process, +	 * initialize the LTR to ~250 usec (see ltr_val above). +	 * The firmware initializes this again later (to a smaller value). +	 */ +	if ((trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_AX210 || +	     trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000) && +	    !trans->trans_cfg->integrated) { +		iwl_write32(trans, CSR_LTR_LONG_VAL_AD, ltr_val); +	} else if (trans->trans_cfg->integrated && +		   trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000) { +		iwl_write_prph(trans, HPM_MAC_LTR_CSR, HPM_MAC_LRT_ENABLE_ALL); +		iwl_write_prph(trans, HPM_UMAC_LTR, ltr_val); +	} +} +  int iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans,  				 const struct fw_img *fw, bool run_in_rfkill)  { @@ -332,6 +360,13 @@ int iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans,  	if (ret)  		goto out; +	iwl_pcie_set_ltr(trans); + +	if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) +		iwl_write_umac_prph(trans, UREG_CPU_INIT_RUN, 1); +	else +		iwl_write_prph(trans, UREG_CPU_INIT_RUN, 1); +  	/* re-check RF-Kill state since we may have missed the interrupt */  	hw_rfkill = iwl_pcie_check_hw_rf_kill(trans);  	if (hw_rfkill && !run_in_rfkill) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c index 381e8f90b6f2..7ae32491b5da 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c @@ -928,6 +928,7 @@ int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,  	u32 cmd_pos;  	const u8 *cmddata[IWL_MAX_CMD_TBS_PER_TFD];  	u16 cmdlen[IWL_MAX_CMD_TBS_PER_TFD]; +	unsigned long flags;  	if (WARN(!trans->wide_cmd_header &&  		 group_id > IWL_ALWAYS_LONG_GROUP, @@ -1011,10 +1012,10 @@ int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,  		goto free_dup_buf;  	} -	spin_lock_bh(&txq->lock); +	spin_lock_irqsave(&txq->lock, flags);  	if (iwl_txq_space(trans, txq) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) { -		spin_unlock_bh(&txq->lock); +		spin_unlock_irqrestore(&txq->lock, flags);  		IWL_ERR(trans, "No space in command queue\n");  		iwl_op_mode_cmd_queue_full(trans->op_mode); @@ -1174,7 +1175,7 @@ int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,   unlock_reg:  	spin_unlock(&trans_pcie->reg_lock);   out: -	spin_unlock_bh(&txq->lock); +	spin_unlock_irqrestore(&txq->lock, flags);   free_dup_buf:  	if (idx < 0)  		kfree(dup_buf); |