From: Emmanuel Grumbach Date: Sun, 13 Apr 2014 13:03:11 +0000 (+0300) Subject: iwlwifi: pcie: disable interrupts upon PCIe alloc X-Git-Tag: v3.14.6~71 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=83134b6448d894e1842bbd765a87a456b5c67a1e;p=thirdparty%2Fkernel%2Fstable.git iwlwifi: pcie: disable interrupts upon PCIe alloc commit 83f7a85f1134c6e914453f5747435415a23d516b upstream. In case RFKILL is in KILL position, the NIC will issue an interrupt straight away. This interrupt won't be sent because it is masked in the hardware. But if our interrupt service routine is called for another reason (SHARED_IRQ), then we'll look at the interrupt cause and service it. This can cause bad things if we are not ready yet. Explicitly clean the interrupt cause register to make sure we won't service anything before we are ready to. Reported-and-tested-by: Alexander Monakov Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index f9507807b4865..8d42fd9b08110 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -1563,6 +1563,10 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, * PCI Tx retries from interfering with C3 CPU state */ pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); + trans->dev = &pdev->dev; + trans_pcie->pci_dev = pdev; + iwl_disable_interrupts(trans); + err = pci_enable_msi(pdev); if (err) { dev_err(&pdev->dev, "pci_enable_msi failed(0X%x)\n", err); @@ -1574,8 +1578,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, } } - trans->dev = &pdev->dev; - trans_pcie->pci_dev = pdev; trans->hw_rev = iwl_read32(trans, CSR_HW_REV); trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; snprintf(trans->hw_id_str, sizeof(trans->hw_id_str), @@ -1601,8 +1603,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, goto out_pci_disable_msi; } - trans_pcie->inta_mask = CSR_INI_SET_MASK; - if (iwl_pcie_alloc_ict(trans)) goto out_free_cmd_pool; @@ -1614,6 +1614,8 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, goto out_free_ict; } + trans_pcie->inta_mask = CSR_INI_SET_MASK; + return trans; out_free_ict: