iwlwifi: pcie: don't service an interrupt that was masked
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Tue, 21 May 2019 12:10:38 +0000 (15:10 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 31 Jul 2019 05:28:37 +0000 (07:28 +0200)
commit 3b57a10ca14c619707398dc58fe5ece18c95b20b upstream.

Sometimes the register status can include interrupts that
were masked. We can, for example, get the RF-Kill bit set
in the interrupt status register although this interrupt
was masked. Then if we get the ALIVE interrupt (for example)
that was not masked, we need to *not* service the RF-Kill
interrupt.
Fix this in the MSI-X interrupt handler.

Cc: stable@vger.kernel.org
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/wireless/intel/iwlwifi/pcie/rx.c

index 953e0254a94c187c26e1ab47909953e508015c1a..8d3ef30904caa51b2b97aabe6f76483fdfbec71e 100644 (file)
@@ -1956,10 +1956,18 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id)
                return IRQ_NONE;
        }
 
-       if (iwl_have_debug_level(IWL_DL_ISR))
-               IWL_DEBUG_ISR(trans, "ISR inta_fh 0x%08x, enabled 0x%08x\n",
-                             inta_fh,
+       if (iwl_have_debug_level(IWL_DL_ISR)) {
+               IWL_DEBUG_ISR(trans,
+                             "ISR inta_fh 0x%08x, enabled (sw) 0x%08x (hw) 0x%08x\n",
+                             inta_fh, trans_pcie->fh_mask,
                              iwl_read32(trans, CSR_MSIX_FH_INT_MASK_AD));
+               if (inta_fh & ~trans_pcie->fh_mask)
+                       IWL_DEBUG_ISR(trans,
+                                     "We got a masked interrupt (0x%08x)\n",
+                                     inta_fh & ~trans_pcie->fh_mask);
+       }
+
+       inta_fh &= trans_pcie->fh_mask;
 
        if ((trans_pcie->shared_vec_mask & IWL_SHARED_IRQ_NON_RX) &&
            inta_fh & MSIX_FH_INT_CAUSES_Q0) {
@@ -1998,11 +2006,18 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id)
        }
 
        /* After checking FH register check HW register */
-       if (iwl_have_debug_level(IWL_DL_ISR))
+       if (iwl_have_debug_level(IWL_DL_ISR)) {
                IWL_DEBUG_ISR(trans,
-                             "ISR inta_hw 0x%08x, enabled 0x%08x\n",
-                             inta_hw,
+                             "ISR inta_hw 0x%08x, enabled (sw) 0x%08x (hw) 0x%08x\n",
+                             inta_hw, trans_pcie->hw_mask,
                              iwl_read32(trans, CSR_MSIX_HW_INT_MASK_AD));
+               if (inta_hw & ~trans_pcie->hw_mask)
+                       IWL_DEBUG_ISR(trans,
+                                     "We got a masked interrupt 0x%08x\n",
+                                     inta_hw & ~trans_pcie->hw_mask);
+       }
+
+       inta_hw &= trans_pcie->hw_mask;
 
        /* Alive notification via Rx interrupt will do the real work */
        if (inta_hw & MSIX_HW_INT_CAUSES_REG_ALIVE) {