be2net: fix spurious interrupt handling in intx mode

Occasionally we may see an interrupt without an event in the eq.
In intx, we currently see the event queue and return IRQ_NONE causing
a the irq to be disabled ("no one cared".) Instead, read the CEV_ISR
reg to check the existence of the interrupt.

Signed-off-by: Sathya Perla <sathyap@serverengines.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Sathya Perla 2009-07-01 01:06:07 +00:00 committed by David S. Miller
parent 7d3cabbcc8
commit c001c213b1
2 changed files with 13 additions and 7 deletions

View File

@ -55,6 +55,10 @@
#define MEMBAR_CTRL_INT_CTRL_PFUNC_MASK 0x7 /* bits 26 - 28 */
#define MEMBAR_CTRL_INT_CTRL_PFUNC_SHIFT 26
/********* ISR0 Register offset **********/
#define CEV_ISR0_OFFSET 0xC18
#define CEV_ISR_SIZE 4
/********* Event Q door bell *************/
#define DB_EQ_OFFSET DB_CQ_OFFSET
#define DB_EQ_RING_ID_MASK 0x1FF /* bits 0 - 8 */

View File

@ -1274,15 +1274,17 @@ static irqreturn_t be_intx(int irq, void *dev)
{
struct be_adapter *adapter = dev;
struct be_ctrl_info *ctrl = &adapter->ctrl;
int rx, tx;
int isr;
tx = event_handle(ctrl, &adapter->tx_eq);
rx = event_handle(ctrl, &adapter->rx_eq);
isr = ioread32(ctrl->csr + CEV_ISR0_OFFSET +
ctrl->pci_func * CEV_ISR_SIZE);
if (!isr)
return IRQ_NONE;
if (rx || tx)
return IRQ_HANDLED;
else
return IRQ_NONE;
event_handle(ctrl, &adapter->tx_eq);
event_handle(ctrl, &adapter->rx_eq);
return IRQ_HANDLED;
}
static irqreturn_t be_msix_rx(int irq, void *dev)