i40e: Re-enable interrupt on ICR0
authorAnjali Singhai Jain <anjali.singhai@intel.com>
Wed, 18 Dec 2013 13:45:49 +0000 (13:45 +0000)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Thu, 9 Jan 2014 09:17:14 +0000 (01:17 -0800)
The hardware can occasionally give an interrupt on the misc
queue for which there is no driver work to do.  In that case
the driver was not re-enabling interrupts even though they
were auto masked by hardware.  This left interrupts disabled
on this queue.

Re-enable the interrupt whenever leaving this function.

Signed-off-by: Anjali Singhai Jain <anjali.singhai@intel.com>
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Tested-by: Kavindya Deegala <kavindya.s.deegala@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/i40e/i40e_main.c

index f736c44704125364ca544f53ebb0c5e2637f0ee7..38ec66feead1c328249ab45188bb5d407f666c59 100644 (file)
@@ -2758,16 +2758,16 @@ static irqreturn_t i40e_intr(int irq, void *data)
 {
        struct i40e_pf *pf = (struct i40e_pf *)data;
        struct i40e_hw *hw = &pf->hw;
+       irqreturn_t ret = IRQ_NONE;
        u32 icr0, icr0_remaining;
        u32 val, ena_mask;
 
        icr0 = rd32(hw, I40E_PFINT_ICR0);
+       ena_mask = rd32(hw, I40E_PFINT_ICR0_ENA);
 
        /* if sharing a legacy IRQ, we might get called w/o an intr pending */
        if ((icr0 & I40E_PFINT_ICR0_INTEVENT_MASK) == 0)
-               return IRQ_NONE;
-
-       ena_mask = rd32(hw, I40E_PFINT_ICR0_ENA);
+               goto enable_intr;
 
        /* if interrupt but no bits showing, must be SWINT */
        if (((icr0 & ~I40E_PFINT_ICR0_INTEVENT_MASK) == 0) ||
@@ -2843,7 +2843,9 @@ static irqreturn_t i40e_intr(int irq, void *data)
                }
                ena_mask &= ~icr0_remaining;
        }
+       ret = IRQ_HANDLED;
 
+enable_intr:
        /* re-enable interrupt causes */
        wr32(hw, I40E_PFINT_ICR0_ENA, ena_mask);
        if (!test_bit(__I40E_DOWN, &pf->state)) {
@@ -2851,7 +2853,7 @@ static irqreturn_t i40e_intr(int irq, void *data)
                i40e_irq_dynamic_enable_icr0(pf);
        }
 
-       return IRQ_HANDLED;
+       return ret;
 }
 
 /**