diff options
author | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2014-04-13 09:03:11 -0400 |
---|---|---|
committer | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2014-05-07 15:54:32 -0400 |
commit | 83f7a85f1134c6e914453f5747435415a23d516b (patch) | |
tree | bd233a654083e8734e6fd629f00bdde2aba7c57a /drivers/net | |
parent | bd5e4744a6ca64299b57a2682c720d00a475a734 (diff) |
iwlwifi: pcie: disable interrupts upon PCIe alloc
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.
Cc: <stable@vger.kernel.org> [3.14]
Reported-and-tested-by: Alexander Monakov <amonakov@gmail.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/iwlwifi/pcie/trans.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index dcfd6d866d09..2365553f1ef7 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c | |||
@@ -1749,6 +1749,10 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | |||
1749 | * PCI Tx retries from interfering with C3 CPU state */ | 1749 | * PCI Tx retries from interfering with C3 CPU state */ |
1750 | pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); | 1750 | pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); |
1751 | 1751 | ||
1752 | trans->dev = &pdev->dev; | ||
1753 | trans_pcie->pci_dev = pdev; | ||
1754 | iwl_disable_interrupts(trans); | ||
1755 | |||
1752 | err = pci_enable_msi(pdev); | 1756 | err = pci_enable_msi(pdev); |
1753 | if (err) { | 1757 | if (err) { |
1754 | dev_err(&pdev->dev, "pci_enable_msi failed(0X%x)\n", err); | 1758 | dev_err(&pdev->dev, "pci_enable_msi failed(0X%x)\n", err); |
@@ -1760,8 +1764,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | |||
1760 | } | 1764 | } |
1761 | } | 1765 | } |
1762 | 1766 | ||
1763 | trans->dev = &pdev->dev; | ||
1764 | trans_pcie->pci_dev = pdev; | ||
1765 | trans->hw_rev = iwl_read32(trans, CSR_HW_REV); | 1767 | trans->hw_rev = iwl_read32(trans, CSR_HW_REV); |
1766 | trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; | 1768 | trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; |
1767 | snprintf(trans->hw_id_str, sizeof(trans->hw_id_str), | 1769 | snprintf(trans->hw_id_str, sizeof(trans->hw_id_str), |
@@ -1787,8 +1789,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | |||
1787 | goto out_pci_disable_msi; | 1789 | goto out_pci_disable_msi; |
1788 | } | 1790 | } |
1789 | 1791 | ||
1790 | trans_pcie->inta_mask = CSR_INI_SET_MASK; | ||
1791 | |||
1792 | if (iwl_pcie_alloc_ict(trans)) | 1792 | if (iwl_pcie_alloc_ict(trans)) |
1793 | goto out_free_cmd_pool; | 1793 | goto out_free_cmd_pool; |
1794 | 1794 | ||
@@ -1800,6 +1800,8 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | |||
1800 | goto out_free_ict; | 1800 | goto out_free_ict; |
1801 | } | 1801 | } |
1802 | 1802 | ||
1803 | trans_pcie->inta_mask = CSR_INI_SET_MASK; | ||
1804 | |||
1803 | return trans; | 1805 | return trans; |
1804 | 1806 | ||
1805 | out_free_ict: | 1807 | out_free_ict: |