|
@@ -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;
|