diff mbox series

[06/16] iwlwifi: pcie: recognize NICs with hw_rev 0x364 correctly

Message ID 20190118190004.22270-7-luca@coelho.fi (mailing list archive)
State Accepted
Delegated to: Luca Coelho
Headers show
Series iwlwifi: updates intended for v4.21 2019-01-18 | expand

Commit Message

Luca Coelho Jan. 18, 2019, 6:59 p.m. UTC
From: Luca Coelho <luciano.coelho@intel.com>

Some devices with PCI ID 0x2723, which is supposed to be 22260, are
actually not.  So we need to differentiate them by checking the hw_rev
and change the cfg accordingly.

Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

Comments

kernel test robot Jan. 21, 2019, 8:46 p.m. UTC | #1
Hi Luca,

I love your patch! Yet something to improve:

[auto build test ERROR on wireless-drivers-next/master]
[also build test ERROR on v5.0-rc2 next-20190116]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Luca-Coelho/iwlwifi-updates-intended-for-v4-21-2019-01-18/20190122-010757
base:   https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git master
config: i386-allmodconfig (attached as .config)
compiler: gcc-8 (Debian 8.2.0-14) 8.2.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

   drivers/net/wireless/intel/iwlwifi/pcie/trans.c: In function 'iwl_trans_pcie_alloc':
>> drivers/net/wireless/intel/iwlwifi/pcie/trans.c:3609:24: error: 'CSR_HW_REV_TYPE_QNJ_B0' undeclared (first use in this function); did you mean 'CSR_HW_REV_TYPE_QNJ'?
          trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0)) {
                           ^~~~~~~~~~~~~~~~~~~~~~
                           CSR_HW_REV_TYPE_QNJ
   drivers/net/wireless/intel/iwlwifi/pcie/trans.c:3609:24: note: each undeclared identifier is reported only once for each function it appears in

vim +3609 drivers/net/wireless/intel/iwlwifi/pcie/trans.c

  3416	
  3417	struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
  3418					       const struct pci_device_id *ent,
  3419					       const struct iwl_cfg *cfg)
  3420	{
  3421		struct iwl_trans_pcie *trans_pcie;
  3422		struct iwl_trans *trans;
  3423		int ret, addr_size;
  3424	
  3425		ret = pcim_enable_device(pdev);
  3426		if (ret)
  3427			return ERR_PTR(ret);
  3428	
  3429		if (cfg->gen2)
  3430			trans = iwl_trans_alloc(sizeof(struct iwl_trans_pcie),
  3431						&pdev->dev, cfg, &trans_ops_pcie_gen2);
  3432		else
  3433			trans = iwl_trans_alloc(sizeof(struct iwl_trans_pcie),
  3434						&pdev->dev, cfg, &trans_ops_pcie);
  3435		if (!trans)
  3436			return ERR_PTR(-ENOMEM);
  3437	
  3438		trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
  3439	
  3440		trans_pcie->trans = trans;
  3441		trans_pcie->opmode_down = true;
  3442		spin_lock_init(&trans_pcie->irq_lock);
  3443		spin_lock_init(&trans_pcie->reg_lock);
  3444		mutex_init(&trans_pcie->mutex);
  3445		init_waitqueue_head(&trans_pcie->ucode_write_waitq);
  3446		trans_pcie->tso_hdr_page = alloc_percpu(struct iwl_tso_hdr_page);
  3447		if (!trans_pcie->tso_hdr_page) {
  3448			ret = -ENOMEM;
  3449			goto out_no_pci;
  3450		}
  3451	
  3452	
  3453		if (!cfg->base_params->pcie_l1_allowed) {
  3454			/*
  3455			 * W/A - seems to solve weird behavior. We need to remove this
  3456			 * if we don't want to stay in L1 all the time. This wastes a
  3457			 * lot of power.
  3458			 */
  3459			pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S |
  3460					       PCIE_LINK_STATE_L1 |
  3461					       PCIE_LINK_STATE_CLKPM);
  3462		}
  3463	
  3464		trans_pcie->def_rx_queue = 0;
  3465	
  3466		if (cfg->use_tfh) {
  3467			addr_size = 64;
  3468			trans_pcie->max_tbs = IWL_TFH_NUM_TBS;
  3469			trans_pcie->tfd_size = sizeof(struct iwl_tfh_tfd);
  3470		} else {
  3471			addr_size = 36;
  3472			trans_pcie->max_tbs = IWL_NUM_OF_TBS;
  3473			trans_pcie->tfd_size = sizeof(struct iwl_tfd);
  3474		}
  3475		trans->max_skb_frags = IWL_PCIE_MAX_FRAGS(trans_pcie);
  3476	
  3477		pci_set_master(pdev);
  3478	
  3479		ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(addr_size));
  3480		if (!ret)
  3481			ret = pci_set_consistent_dma_mask(pdev,
  3482							  DMA_BIT_MASK(addr_size));
  3483		if (ret) {
  3484			ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
  3485			if (!ret)
  3486				ret = pci_set_consistent_dma_mask(pdev,
  3487								  DMA_BIT_MASK(32));
  3488			/* both attempts failed: */
  3489			if (ret) {
  3490				dev_err(&pdev->dev, "No suitable DMA available\n");
  3491				goto out_no_pci;
  3492			}
  3493		}
  3494	
  3495		ret = pcim_iomap_regions_request_all(pdev, BIT(0), DRV_NAME);
  3496		if (ret) {
  3497			dev_err(&pdev->dev, "pcim_iomap_regions_request_all failed\n");
  3498			goto out_no_pci;
  3499		}
  3500	
  3501		trans_pcie->hw_base = pcim_iomap_table(pdev)[0];
  3502		if (!trans_pcie->hw_base) {
  3503			dev_err(&pdev->dev, "pcim_iomap_table failed\n");
  3504			ret = -ENODEV;
  3505			goto out_no_pci;
  3506		}
  3507	
  3508		/* We disable the RETRY_TIMEOUT register (0x41) to keep
  3509		 * PCI Tx retries from interfering with C3 CPU state */
  3510		pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
  3511	
  3512		trans_pcie->pci_dev = pdev;
  3513		iwl_disable_interrupts(trans);
  3514	
  3515		trans->hw_rev = iwl_read32(trans, CSR_HW_REV);
  3516		if (trans->hw_rev == 0xffffffff) {
  3517			dev_err(&pdev->dev, "HW_REV=0xFFFFFFFF, PCI issues?\n");
  3518			ret = -EIO;
  3519			goto out_no_pci;
  3520		}
  3521	
  3522		/*
  3523		 * In the 8000 HW family the format of the 4 bytes of CSR_HW_REV have
  3524		 * changed, and now the revision step also includes bit 0-1 (no more
  3525		 * "dash" value). To keep hw_rev backwards compatible - we'll store it
  3526		 * in the old format.
  3527		 */
  3528		if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_8000) {
  3529			unsigned long flags;
  3530	
  3531			trans->hw_rev = (trans->hw_rev & 0xfff0) |
  3532					(CSR_HW_REV_STEP(trans->hw_rev << 2) << 2);
  3533	
  3534			ret = iwl_pcie_prepare_card_hw(trans);
  3535			if (ret) {
  3536				IWL_WARN(trans, "Exit HW not ready\n");
  3537				goto out_no_pci;
  3538			}
  3539	
  3540			/*
  3541			 * in-order to recognize C step driver should read chip version
  3542			 * id located at the AUX bus MISC address space.
  3543			 */
  3544			iwl_set_bit(trans, CSR_GP_CNTRL,
  3545				    BIT(trans->cfg->csr->flag_init_done));
  3546			udelay(2);
  3547	
  3548			ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
  3549					   BIT(trans->cfg->csr->flag_mac_clock_ready),
  3550					   BIT(trans->cfg->csr->flag_mac_clock_ready),
  3551					   25000);
  3552			if (ret < 0) {
  3553				IWL_DEBUG_INFO(trans, "Failed to wake up the nic\n");
  3554				goto out_no_pci;
  3555			}
  3556	
  3557			if (iwl_trans_grab_nic_access(trans, &flags)) {
  3558				u32 hw_step;
  3559	
  3560				hw_step = iwl_read_prph_no_grab(trans, WFPM_CTRL_REG);
  3561				hw_step |= ENABLE_WFPM;
  3562				iwl_write_prph_no_grab(trans, WFPM_CTRL_REG, hw_step);
  3563				hw_step = iwl_read_prph_no_grab(trans, AUX_MISC_REG);
  3564				hw_step = (hw_step >> HW_STEP_LOCATION_BITS) & 0xF;
  3565				if (hw_step == 0x3)
  3566					trans->hw_rev = (trans->hw_rev & 0xFFFFFFF3) |
  3567							(SILICON_C_STEP << 2);
  3568				iwl_trans_release_nic_access(trans, &flags);
  3569			}
  3570		}
  3571	
  3572		IWL_DEBUG_INFO(trans, "HW REV: 0x%0x\n", trans->hw_rev);
  3573	
  3574		/*
  3575		 * 9000-series integrated A-step has a problem with suspend/resume
  3576		 * and sometimes even causes the whole platform to get stuck. This
  3577		 * workaround makes the hardware not go into the problematic state.
  3578		 */
  3579		if (trans->cfg->integrated &&
  3580		    trans->cfg->device_family == IWL_DEVICE_FAMILY_9000 &&
  3581		    CSR_HW_REV_STEP(trans->hw_rev) == SILICON_A_STEP)
  3582			iwl_set_bit(trans, CSR_HOST_CHICKEN,
  3583				    CSR_HOST_CHICKEN_PM_IDLE_SRC_DIS_SB_PME);
  3584	
  3585	#if IS_ENABLED(CONFIG_IWLMVM)
  3586		trans->hw_rf_id = iwl_read32(trans, CSR_HW_RF_ID);
  3587	
  3588		if (cfg == &iwl22000_2ax_cfg_hr) {
  3589			if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
  3590			    CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR)) {
  3591				trans->cfg = &iwl22000_2ax_cfg_hr;
  3592			} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
  3593				   CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_JF)) {
  3594				trans->cfg = &iwl22000_2ax_cfg_jf;
  3595			} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
  3596				   CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HRCDB)) {
  3597				IWL_ERR(trans, "RF ID HRCDB is not supported\n");
  3598				ret = -EINVAL;
  3599				goto out_no_pci;
  3600			} else {
  3601				IWL_ERR(trans, "Unrecognized RF ID 0x%08x\n",
  3602					CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id));
  3603				ret = -EINVAL;
  3604				goto out_no_pci;
  3605			}
  3606		} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
  3607			   CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) &&
  3608			   (trans->cfg != &iwl22260_2ax_cfg ||
> 3609			    trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0)) {
  3610			u32 hw_status;
  3611	
  3612			hw_status = iwl_read_prph(trans, UMAG_GEN_HW_STATUS);
  3613			if (CSR_HW_RF_STEP(trans->hw_rf_id) == SILICON_B_STEP)
  3614				/*
  3615				* b step fw is the same for physical card and fpga
  3616				*/
  3617				trans->cfg = &iwl22000_2ax_cfg_qnj_hr_b0;
  3618			else if ((hw_status & UMAG_GEN_HW_IS_FPGA) &&
  3619				 CSR_HW_RF_STEP(trans->hw_rf_id) == SILICON_A_STEP) {
  3620				trans->cfg = &iwl22000_2ax_cfg_qnj_hr_a0_f0;
  3621			} else {
  3622				/*
  3623				* a step no FPGA
  3624				*/
  3625				trans->cfg = &iwl22000_2ac_cfg_hr;
  3626			}
  3627		}
  3628	#endif
  3629	
  3630		iwl_pcie_set_interrupt_capa(pdev, trans);
  3631		trans->hw_id = (pdev->device << 16) + pdev->subsystem_device;
  3632		snprintf(trans->hw_id_str, sizeof(trans->hw_id_str),
  3633			 "PCI ID: 0x%04X:0x%04X", pdev->device, pdev->subsystem_device);
  3634	
  3635		/* Initialize the wait queue for commands */
  3636		init_waitqueue_head(&trans_pcie->wait_command_queue);
  3637	
  3638		init_waitqueue_head(&trans_pcie->d0i3_waitq);
  3639	
  3640		if (trans_pcie->msix_enabled) {
  3641			ret = iwl_pcie_init_msix_handler(pdev, trans_pcie);
  3642			if (ret)
  3643				goto out_no_pci;
  3644		 } else {
  3645			ret = iwl_pcie_alloc_ict(trans);
  3646			if (ret)
  3647				goto out_no_pci;
  3648	
  3649			ret = devm_request_threaded_irq(&pdev->dev, pdev->irq,
  3650							iwl_pcie_isr,
  3651							iwl_pcie_irq_handler,
  3652							IRQF_SHARED, DRV_NAME, trans);
  3653			if (ret) {
  3654				IWL_ERR(trans, "Error allocating IRQ %d\n", pdev->irq);
  3655				goto out_free_ict;
  3656			}
  3657			trans_pcie->inta_mask = CSR_INI_SET_MASK;
  3658		 }
  3659	
  3660		trans_pcie->rba.alloc_wq = alloc_workqueue("rb_allocator",
  3661							   WQ_HIGHPRI | WQ_UNBOUND, 1);
  3662		INIT_WORK(&trans_pcie->rba.rx_alloc, iwl_pcie_rx_allocator_work);
  3663	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
diff mbox series

Patch

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index fc2f98f2d516..633444d2f930 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -3569,6 +3569,8 @@  struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
 		}
 	}
 
+	IWL_DEBUG_INFO(trans, "HW REV: 0x%0x\n", trans->hw_rev);
+
 	/*
 	 * 9000-series integrated A-step has a problem with suspend/resume
 	 * and sometimes even causes the whole platform to get stuck. This
@@ -3603,7 +3605,8 @@  struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
 		}
 	} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
 		   CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) &&
-		   trans->cfg != &iwl22260_2ax_cfg) {
+		   (trans->cfg != &iwl22260_2ax_cfg ||
+		    trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0)) {
 		u32 hw_status;
 
 		hw_status = iwl_read_prph(trans, UMAG_GEN_HW_STATUS);