diff options
Diffstat (limited to 'drivers/net/bnx2.c')
-rw-r--r-- | drivers/net/bnx2.c | 52 |
1 files changed, 32 insertions, 20 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index bbfbdafb4ae5..d68accea380b 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -2633,15 +2633,11 @@ bnx2_has_work(struct bnx2 *bp) | |||
2633 | return 0; | 2633 | return 0; |
2634 | } | 2634 | } |
2635 | 2635 | ||
2636 | static int | 2636 | static int bnx2_poll_work(struct bnx2 *bp, int work_done, int budget) |
2637 | bnx2_poll(struct napi_struct *napi, int budget) | ||
2638 | { | 2637 | { |
2639 | struct bnx2 *bp = container_of(napi, struct bnx2, napi); | ||
2640 | struct net_device *dev = bp->dev; | ||
2641 | struct status_block *sblk = bp->status_blk; | 2638 | struct status_block *sblk = bp->status_blk; |
2642 | u32 status_attn_bits = sblk->status_attn_bits; | 2639 | u32 status_attn_bits = sblk->status_attn_bits; |
2643 | u32 status_attn_bits_ack = sblk->status_attn_bits_ack; | 2640 | u32 status_attn_bits_ack = sblk->status_attn_bits_ack; |
2644 | int work_done = 0; | ||
2645 | 2641 | ||
2646 | if ((status_attn_bits & STATUS_ATTN_EVENTS) != | 2642 | if ((status_attn_bits & STATUS_ATTN_EVENTS) != |
2647 | (status_attn_bits_ack & STATUS_ATTN_EVENTS)) { | 2643 | (status_attn_bits_ack & STATUS_ATTN_EVENTS)) { |
@@ -2660,27 +2656,43 @@ bnx2_poll(struct napi_struct *napi, int budget) | |||
2660 | bnx2_tx_int(bp); | 2656 | bnx2_tx_int(bp); |
2661 | 2657 | ||
2662 | if (bp->status_blk->status_rx_quick_consumer_index0 != bp->hw_rx_cons) | 2658 | if (bp->status_blk->status_rx_quick_consumer_index0 != bp->hw_rx_cons) |
2663 | work_done = bnx2_rx_int(bp, budget); | 2659 | work_done += bnx2_rx_int(bp, budget - work_done); |
2664 | 2660 | ||
2665 | bp->last_status_idx = bp->status_blk->status_idx; | 2661 | return work_done; |
2666 | rmb(); | 2662 | } |
2663 | |||
2664 | static int bnx2_poll(struct napi_struct *napi, int budget) | ||
2665 | { | ||
2666 | struct bnx2 *bp = container_of(napi, struct bnx2, napi); | ||
2667 | int work_done = 0; | ||
2668 | |||
2669 | while (1) { | ||
2670 | work_done = bnx2_poll_work(bp, work_done, budget); | ||
2667 | 2671 | ||
2668 | if (!bnx2_has_work(bp)) { | 2672 | if (unlikely(work_done >= budget)) |
2669 | netif_rx_complete(dev, napi); | 2673 | break; |
2670 | if (likely(bp->flags & USING_MSI_FLAG)) { | 2674 | |
2675 | if (likely(!bnx2_has_work(bp))) { | ||
2676 | bp->last_status_idx = bp->status_blk->status_idx; | ||
2677 | rmb(); | ||
2678 | |||
2679 | netif_rx_complete(bp->dev, napi); | ||
2680 | if (likely(bp->flags & USING_MSI_FLAG)) { | ||
2681 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, | ||
2682 | BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | | ||
2683 | bp->last_status_idx); | ||
2684 | return 0; | ||
2685 | } | ||
2671 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, | 2686 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, |
2672 | BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | | 2687 | BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | |
2688 | BNX2_PCICFG_INT_ACK_CMD_MASK_INT | | ||
2673 | bp->last_status_idx); | 2689 | bp->last_status_idx); |
2674 | return 0; | ||
2675 | } | ||
2676 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, | ||
2677 | BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | | ||
2678 | BNX2_PCICFG_INT_ACK_CMD_MASK_INT | | ||
2679 | bp->last_status_idx); | ||
2680 | 2690 | ||
2681 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, | 2691 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, |
2682 | BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | | 2692 | BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | |
2683 | bp->last_status_idx); | 2693 | bp->last_status_idx); |
2694 | break; | ||
2695 | } | ||
2684 | } | 2696 | } |
2685 | 2697 | ||
2686 | return work_done; | 2698 | return work_done; |