diff options
Diffstat (limited to 'drivers/net/sfc/nic.c')
-rw-r--r-- | drivers/net/sfc/nic.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c index db44224ed2ca..b06f8e348307 100644 --- a/drivers/net/sfc/nic.c +++ b/drivers/net/sfc/nic.c | |||
@@ -623,10 +623,6 @@ void efx_nic_remove_rx(struct efx_rx_queue *rx_queue) | |||
623 | * | 623 | * |
624 | * This writes the EVQ_RPTR_REG register for the specified channel's | 624 | * This writes the EVQ_RPTR_REG register for the specified channel's |
625 | * event queue. | 625 | * event queue. |
626 | * | ||
627 | * Note that EVQ_RPTR_REG contains the index of the "last read" event, | ||
628 | * whereas channel->eventq_read_ptr contains the index of the "next to | ||
629 | * read" event. | ||
630 | */ | 626 | */ |
631 | void efx_nic_eventq_read_ack(struct efx_channel *channel) | 627 | void efx_nic_eventq_read_ack(struct efx_channel *channel) |
632 | { | 628 | { |
@@ -1384,6 +1380,15 @@ static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id) | |||
1384 | efx->last_irq_cpu = raw_smp_processor_id(); | 1380 | efx->last_irq_cpu = raw_smp_processor_id(); |
1385 | EFX_TRACE(efx, "IRQ %d on CPU %d status " EFX_DWORD_FMT "\n", | 1381 | EFX_TRACE(efx, "IRQ %d on CPU %d status " EFX_DWORD_FMT "\n", |
1386 | irq, raw_smp_processor_id(), EFX_DWORD_VAL(reg)); | 1382 | irq, raw_smp_processor_id(), EFX_DWORD_VAL(reg)); |
1383 | } else if (EFX_WORKAROUND_15783(efx)) { | ||
1384 | /* We can't return IRQ_HANDLED more than once on seeing ISR0=0 | ||
1385 | * because this might be a shared interrupt, but we do need to | ||
1386 | * check the channel every time and preemptively rearm it if | ||
1387 | * it's idle. */ | ||
1388 | efx_for_each_channel(channel, efx) { | ||
1389 | if (!channel->work_pending) | ||
1390 | efx_nic_eventq_read_ack(channel); | ||
1391 | } | ||
1387 | } | 1392 | } |
1388 | 1393 | ||
1389 | return result; | 1394 | return result; |