diff options
author | Sathya Perla <sathyap@serverengines.com> | 2009-07-01 01:06:07 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-07-03 20:09:45 -0700 |
commit | c001c213b109c8baeeb6d012b422bf059b18368f (patch) | |
tree | eb9c551c9f84fe1a7fbaa8d15866200aa76e98f1 | |
parent | 7d3cabbcc86f7f69c47cb20c23ee84350ae6cfbb (diff) | |
download | op-kernel-dev-c001c213b109c8baeeb6d012b422bf059b18368f.zip op-kernel-dev-c001c213b109c8baeeb6d012b422bf059b18368f.tar.gz |
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>
-rw-r--r-- | drivers/net/benet/be_hw.h | 4 | ||||
-rw-r--r-- | drivers/net/benet/be_main.c | 16 |
2 files changed, 13 insertions, 7 deletions
diff --git a/drivers/net/benet/be_hw.h b/drivers/net/benet/be_hw.h index b02e805..29c33c7 100644 --- a/drivers/net/benet/be_hw.h +++ b/drivers/net/benet/be_hw.h @@ -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 */ diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 308eb09..c43f6a1 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -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) |