summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/sfc/nic.c
diff options
context:
space:
mode:
authorAlexandre Rames <arames@solarflare.com>2013-03-21 16:41:43 +0000
committerBen Hutchings <bhutchings@solarflare.com>2013-06-24 19:58:25 +0100
commitb28405b0f25c91b52350fd558c219f08e5033eaf (patch)
treeaaf3d37c96a0a789ae23dd4f751cd9c57f24a1c8 /drivers/net/ethernet/sfc/nic.c
parent37173488400704f1a05656616cd12baa9e03173b (diff)
sfc: Fix EEH with legacy interrupts.
PCI legacy interrupts are level-triggered, and we cannot mask them up on an isolated device. Instead, disable the IRQ at the controller until we have recovered. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Diffstat (limited to 'drivers/net/ethernet/sfc/nic.c')
-rw-r--r--drivers/net/ethernet/sfc/nic.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c
index b0503cd8c2a0..39432d3d1fe9 100644
--- a/drivers/net/ethernet/sfc/nic.c
+++ b/drivers/net/ethernet/sfc/nic.c
@@ -1579,6 +1579,16 @@ static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id)
efx_readd(efx, &reg, FR_BZ_INT_ISR0);
queues = EFX_EXTRACT_DWORD(reg, 0, 31);
+ /* Legacy interrupts are disabled too late by the EEH kernel
+ * code. Disable them earlier.
+ * If an EEH error occurred, the read will have returned all ones.
+ */
+ if (EFX_DWORD_IS_ALL_ONES(reg) && efx_try_recovery(efx) &&
+ !efx->eeh_disabled_legacy_irq) {
+ disable_irq_nosync(efx->legacy_irq);
+ efx->eeh_disabled_legacy_irq = true;
+ }
+
/* Handle non-event-queue sources */
if (queues & (1U << efx->irq_level)) {
syserr = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_FATAL_INT);