forked from Minki/linux
sfc: Extend the legacy interrupt workarounds
Siena has two problems with legacy interrupts: 1. There is no synchronisation between the ISR read completion, and the interrupt deassert message. 2. A downstream read at the "wrong" moment can return 0, and suppress generating the next interrupt. Falcon should suffer from both of these, and it appears it does. Enable EFX_WORKAROUND_15783 on Falcon as well. Also, when we see queues == 0, ensure we always schedule or rearm every event queue. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
b7b40eeb0f
commit
41b7e4c326
@ -1356,33 +1356,28 @@ static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id)
|
||||
}
|
||||
result = IRQ_HANDLED;
|
||||
|
||||
} else if (EFX_WORKAROUND_15783(efx) &&
|
||||
efx->irq_zero_count++ == 0) {
|
||||
} else if (EFX_WORKAROUND_15783(efx)) {
|
||||
efx_qword_t *event;
|
||||
|
||||
/* Ensure we rearm all event queues */
|
||||
/* We can't return IRQ_HANDLED more than once on seeing ISR=0
|
||||
* because this might be a shared interrupt. */
|
||||
if (efx->irq_zero_count++ == 0)
|
||||
result = IRQ_HANDLED;
|
||||
|
||||
/* Ensure we schedule or rearm all event queues */
|
||||
efx_for_each_channel(channel, efx) {
|
||||
event = efx_event(channel, channel->eventq_read_ptr);
|
||||
if (efx_event_present(event))
|
||||
efx_schedule_channel(channel);
|
||||
else
|
||||
efx_nic_eventq_read_ack(channel);
|
||||
}
|
||||
|
||||
result = IRQ_HANDLED;
|
||||
}
|
||||
|
||||
if (result == IRQ_HANDLED) {
|
||||
efx->last_irq_cpu = raw_smp_processor_id();
|
||||
EFX_TRACE(efx, "IRQ %d on CPU %d status " EFX_DWORD_FMT "\n",
|
||||
irq, raw_smp_processor_id(), EFX_DWORD_VAL(reg));
|
||||
} else if (EFX_WORKAROUND_15783(efx)) {
|
||||
/* We can't return IRQ_HANDLED more than once on seeing ISR0=0
|
||||
* because this might be a shared interrupt, but we do need to
|
||||
* check the channel every time and preemptively rearm it if
|
||||
* it's idle. */
|
||||
efx_for_each_channel(channel, efx) {
|
||||
if (!channel->work_pending)
|
||||
efx_nic_eventq_read_ack(channel);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -37,7 +37,7 @@
|
||||
/* Truncated IPv4 packets can confuse the TX packet parser */
|
||||
#define EFX_WORKAROUND_15592 EFX_WORKAROUND_FALCON_AB
|
||||
/* Legacy ISR read can return zero once */
|
||||
#define EFX_WORKAROUND_15783 EFX_WORKAROUND_SIENA
|
||||
#define EFX_WORKAROUND_15783 EFX_WORKAROUND_ALWAYS
|
||||
/* Legacy interrupt storm when interrupt fifo fills */
|
||||
#define EFX_WORKAROUND_17213 EFX_WORKAROUND_SIENA
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user