diff options
Diffstat (limited to 'drivers/net/bnx2.c')
-rw-r--r-- | drivers/net/bnx2.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 439f4827addc..a806a8edec87 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -2547,6 +2547,7 @@ bnx2_interrupt(int irq, void *dev_instance) | |||
2547 | { | 2547 | { |
2548 | struct net_device *dev = dev_instance; | 2548 | struct net_device *dev = dev_instance; |
2549 | struct bnx2 *bp = netdev_priv(dev); | 2549 | struct bnx2 *bp = netdev_priv(dev); |
2550 | struct status_block *sblk = bp->status_blk; | ||
2550 | 2551 | ||
2551 | /* When using INTx, it is possible for the interrupt to arrive | 2552 | /* When using INTx, it is possible for the interrupt to arrive |
2552 | * at the CPU before the status block posted prior to the | 2553 | * at the CPU before the status block posted prior to the |
@@ -2554,7 +2555,7 @@ bnx2_interrupt(int irq, void *dev_instance) | |||
2554 | * When using MSI, the MSI message will always complete after | 2555 | * When using MSI, the MSI message will always complete after |
2555 | * the status block write. | 2556 | * the status block write. |
2556 | */ | 2557 | */ |
2557 | if ((bp->status_blk->status_idx == bp->last_status_idx) && | 2558 | if ((sblk->status_idx == bp->last_status_idx) && |
2558 | (REG_RD(bp, BNX2_PCICFG_MISC_STATUS) & | 2559 | (REG_RD(bp, BNX2_PCICFG_MISC_STATUS) & |
2559 | BNX2_PCICFG_MISC_STATUS_INTA_VALUE)) | 2560 | BNX2_PCICFG_MISC_STATUS_INTA_VALUE)) |
2560 | return IRQ_NONE; | 2561 | return IRQ_NONE; |
@@ -2563,11 +2564,19 @@ bnx2_interrupt(int irq, void *dev_instance) | |||
2563 | BNX2_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM | | 2564 | BNX2_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM | |
2564 | BNX2_PCICFG_INT_ACK_CMD_MASK_INT); | 2565 | BNX2_PCICFG_INT_ACK_CMD_MASK_INT); |
2565 | 2566 | ||
2567 | /* Read back to deassert IRQ immediately to avoid too many | ||
2568 | * spurious interrupts. | ||
2569 | */ | ||
2570 | REG_RD(bp, BNX2_PCICFG_INT_ACK_CMD); | ||
2571 | |||
2566 | /* Return here if interrupt is shared and is disabled. */ | 2572 | /* Return here if interrupt is shared and is disabled. */ |
2567 | if (unlikely(atomic_read(&bp->intr_sem) != 0)) | 2573 | if (unlikely(atomic_read(&bp->intr_sem) != 0)) |
2568 | return IRQ_HANDLED; | 2574 | return IRQ_HANDLED; |
2569 | 2575 | ||
2570 | netif_rx_schedule(dev); | 2576 | if (netif_rx_schedule_prep(dev)) { |
2577 | bp->last_status_idx = sblk->status_idx; | ||
2578 | __netif_rx_schedule(dev); | ||
2579 | } | ||
2571 | 2580 | ||
2572 | return IRQ_HANDLED; | 2581 | return IRQ_HANDLED; |
2573 | } | 2582 | } |