diff options
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/pcie/drv.c')
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 107 | 
1 files changed, 95 insertions, 12 deletions
| diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index ffaf973dae94..d94bd8d732e9 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -1,6 +1,6 @@  // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause  /* - * Copyright (C) 2005-2014, 2018-2020 Intel Corporation + * Copyright (C) 2005-2014, 2018-2021 Intel Corporation   * Copyright (C) 2013-2015 Intel Mobile Communications GmbH   * Copyright (C) 2016-2017 Intel Deutschland GmbH   */ @@ -17,10 +17,20 @@  #include "iwl-prph.h"  #include "internal.h" +#define TRANS_CFG_MARKER BIT(0) +#define _IS_A(cfg, _struct) __builtin_types_compatible_p(typeof(cfg),	\ +							 struct _struct) +extern int _invalid_type; +#define _TRANS_CFG_MARKER(cfg)						\ +	(__builtin_choose_expr(_IS_A(cfg, iwl_cfg_trans_params),	\ +			       TRANS_CFG_MARKER,			\ +	 __builtin_choose_expr(_IS_A(cfg, iwl_cfg), 0, _invalid_type))) +#define _ASSIGN_CFG(cfg) (_TRANS_CFG_MARKER(cfg) + (kernel_ulong_t)&(cfg)) +  #define IWL_PCI_DEVICE(dev, subdev, cfg) \  	.vendor = PCI_VENDOR_ID_INTEL,  .device = (dev), \  	.subvendor = PCI_ANY_ID, .subdevice = (subdev), \ -	.driver_data = (kernel_ulong_t)&(cfg) +	.driver_data = _ASSIGN_CFG(cfg)  /* Hardware specific file defines the PCI IDs table for that hardware module */  static const struct pci_device_id iwl_hw_card_ids[] = { @@ -490,6 +500,8 @@ static const struct pci_device_id iwl_hw_card_ids[] = {  	{IWL_PCI_DEVICE(0x2729, PCI_ANY_ID, iwl_ma_trans_cfg)},  	{IWL_PCI_DEVICE(0x7E40, PCI_ANY_ID, iwl_ma_trans_cfg)}, +/* Bz devices */ +	{IWL_PCI_DEVICE(0x2727, PCI_ANY_ID, iwl_bz_trans_cfg)},  #endif /* CONFIG_IWLMVM */  	{0} @@ -592,6 +604,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), @@ -606,6 +619,8 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {  	IWL_DEV_INFO(0x2725, 0x4020, iwlax210_2ax_cfg_ty_gf_a0, NULL),  	IWL_DEV_INFO(0x2725, 0x6020, iwlax210_2ax_cfg_ty_gf_a0, NULL),  	IWL_DEV_INFO(0x2725, 0x6024, iwlax210_2ax_cfg_ty_gf_a0, NULL), +	IWL_DEV_INFO(0x2725, 0x1673, iwlax210_2ax_cfg_ty_gf_a0, iwl_ax210_killer_1675w_name), +	IWL_DEV_INFO(0x2725, 0x1674, iwlax210_2ax_cfg_ty_gf_a0, iwl_ax210_killer_1675x_name),  	IWL_DEV_INFO(0x7A70, 0x0090, iwlax211_2ax_cfg_so_gf_a0_long, NULL),  	IWL_DEV_INFO(0x7A70, 0x0098, iwlax211_2ax_cfg_so_gf_a0_long, NULL),  	IWL_DEV_INFO(0x7A70, 0x00B0, iwlax411_2ax_cfg_so_gf4_a0_long, NULL), @@ -1013,12 +1028,12 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {  		      IWL_CFG_MAC_TYPE_MA, IWL_CFG_ANY,  		      IWL_CFG_RF_TYPE_MR, IWL_CFG_ANY,  		      IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, -		      iwl_cfg_ma_a0_mr_a0, iwl_ma_name), +		      iwl_cfg_ma_a0_mr_a0, iwl_ax221_name),  	_IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,  		      IWL_CFG_MAC_TYPE_SNJ, IWL_CFG_ANY,  		      IWL_CFG_RF_TYPE_MR, IWL_CFG_ANY,  		      IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, -		      iwl_cfg_snj_a0_mr_a0, iwl_ma_name), +		      iwl_cfg_snj_a0_mr_a0, iwl_ax221_name),  /* So with Hr */  	_IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, @@ -1040,7 +1055,60 @@ 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), + +/* Bz */ +	_IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, +		      IWL_CFG_MAC_TYPE_BZ, IWL_CFG_ANY, +		      IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, +		      IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, +		      iwl_cfg_bz_a0_hr_b0, iwl_ax201_name), +	_IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, +		      IWL_CFG_MAC_TYPE_BZ, IWL_CFG_ANY, +		      IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY, +		      IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, +		      iwl_cfg_bz_a0_gf_a0, iwl_ax211_name), +	_IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, +		      IWL_CFG_MAC_TYPE_BZ, IWL_CFG_ANY, +		      IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY, +		      IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_CDB, +		      iwl_cfg_bz_a0_gf4_a0, iwl_ax211_name), +	_IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, +		      IWL_CFG_MAC_TYPE_BZ, IWL_CFG_ANY, +		      IWL_CFG_RF_TYPE_MR, IWL_CFG_ANY, +		      IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, +		      iwl_cfg_bz_a0_mr_a0, iwl_ax211_name), + +/* So with GF */ +	_IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, +		      IWL_CFG_MAC_TYPE_SO, 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 */  }; @@ -1050,19 +1118,22 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {  static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  { -	const struct iwl_cfg_trans_params *trans = -		(struct iwl_cfg_trans_params *)(ent->driver_data); +	const struct iwl_cfg_trans_params *trans;  	const struct iwl_cfg *cfg_7265d __maybe_unused = NULL;  	struct iwl_trans *iwl_trans;  	struct iwl_trans_pcie *trans_pcie;  	int i, ret; +	const struct iwl_cfg *cfg; + +	trans = (void *)(ent->driver_data & ~TRANS_CFG_MARKER); +  	/*  	 * This is needed for backwards compatibility with the old  	 * tables, so we don't need to change all the config structs  	 * at the same time.  The cfg is used to compare with the old  	 * full cfg structs.  	 */ -	const struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); +	cfg = (void *)(ent->driver_data & ~TRANS_CFG_MARKER);  	/* make sure trans is the first element in iwl_cfg */  	BUILD_BUG_ON(offsetof(struct iwl_cfg, trans)); @@ -1140,7 +1211,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  			iwl_trans->cfg = &iwlax210_2ax_cfg_ty_gf_a0;  		} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) ==  			   CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_JF)) { -			iwl_trans->cfg = &iwlax210_2ax_cfg_so_jf_a0; +			iwl_trans->cfg = &iwlax210_2ax_cfg_so_jf_b0;  		} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) ==  			   CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_GF)) {  			iwl_trans->cfg = &iwlax211_2ax_cfg_so_gf_a0; @@ -1177,11 +1248,19 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  #endif  	/* -	 * If we didn't set the cfg yet, assume the trans is actually -	 * a full cfg from the old tables. +	 * If we didn't set the cfg yet, the PCI ID table entry should have +	 * been a full config - if yes, use it, otherwise fail.  	 */ -	if (!iwl_trans->cfg) +	if (!iwl_trans->cfg) { +		if (ent->driver_data & TRANS_CFG_MARKER) { +			pr_err("No config found for PCI dev %04x/%04x, rev=0x%x, rfid=0x%x\n", +			       pdev->device, pdev->subsystem_device, +			       iwl_trans->hw_rev, iwl_trans->hw_rf_id); +			ret = -EINVAL; +			goto out_free_trans; +		}  		iwl_trans->cfg = cfg; +	}  	/* if we don't have a name yet, copy name from the old cfg */  	if (!iwl_trans->name) @@ -1197,6 +1276,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  		trans_pcie->num_rx_bufs = RX_QUEUE_SIZE;  	} +	ret = iwl_trans_init(iwl_trans); +	if (ret) +		goto out_free_trans; +  	pci_set_drvdata(pdev, iwl_trans);  	iwl_trans->drv = iwl_drv_start(iwl_trans); | 
