From cee7479c049bc86848d233587a5cc22c9507a240 Mon Sep 17 00:00:00 2001 From: Andy Gospodarek Date: Wed, 11 Feb 2009 17:46:01 -0500 Subject: [PATCH] bnx2: fixup problems with netpoll implementation RHBZ 484667 --- drivers/net/bnx2.c | 74 ++++++++++++++++++++++++++++++--------------------- drivers/net/bnx2.h | 1 + 2 files changed, 44 insertions(+), 31 deletions(-) diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 22580ab..bae139c 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -472,19 +472,13 @@ bnx2_disable_int_sync(struct bnx2 *bp) static void bnx2_napi_disable(struct bnx2 *bp) { - int i; - - for (i = 0; i < bp->irq_nvecs; i++) - netif_poll_disable(bp->bnx2_napi[i].dummy_netdev); + netif_poll_disable(bp->dev); } static void bnx2_napi_enable(struct bnx2 *bp) { - int i; - - for (i = 0; i < bp->irq_nvecs; i++) - netif_poll_enable(bp->bnx2_napi[i].dummy_netdev); + netif_poll_enable(bp->dev); } static void @@ -3173,10 +3167,7 @@ static int bnx2_poll_msix(struct net_device *dev, int *budget) /* status idx must be read before checking for more work. */ rmb(); if (likely(!bnx2_has_fast_work(bnapi))) { - - REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, bnapi->int_num | - BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | - bnapi->last_status_idx); + bnapi->complete = 1; return 0; } } @@ -3195,30 +3186,18 @@ static int bnx2_poll(struct net_device *dev, int *budget) work_done = bnx2_poll_work(bp, bnapi, work_done, *budget); - if (unlikely(work_done >= *budget)) - break; - /* bnapi->last_status_idx is used below to tell the hw how * much work has been processed, so we must read it before * checking for more work. */ bnapi->last_status_idx = sblk->status_idx; + + if (unlikely(work_done >= *budget)) + break; + rmb(); if (likely(!bnx2_has_work(bnapi))) { - if (likely(bp->flags & BNX2_FLAG_USING_MSI_OR_MSIX)) { - REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, - BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | - bnapi->last_status_idx); - return 0; - } - REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, - BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | - BNX2_PCICFG_INT_ACK_CMD_MASK_INT | - bnapi->last_status_idx); - - REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, - BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | - bnapi->last_status_idx); + bnapi->complete = 1; return 0; } } @@ -3235,16 +3214,49 @@ static int bnx2_poll_all(struct net_device *dev, int *budget) for (i = 0; i < bp->irq_nvecs; i++) { struct bnx2_napi *bnapi = &bp->bnx2_napi[i]; struct net_device *poll_dev = bnapi->dummy_netdev; + int local_budget = min(*budget,dev->quota); if (poll_dev && poll_dev->poll) { - int new_resched = poll_dev->poll(poll_dev, budget); - resched |= new_resched; + resched |= poll_dev->poll(poll_dev, &local_budget); + } + *budget -= local_budget; + if (*budget < 0) { + budget = 0; + resched = 1; } } if (!resched) netif_rx_complete(dev); + for (i = 0; i < bp->irq_nvecs; i++) { + struct bnx2_napi *bnapi = &bp->bnx2_napi[i]; + + if (bnapi->complete) { + if (likely(bp->flags & BNX2_FLAG_USING_MSI_OR_MSIX)) { + if (i == 0) + REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, + BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | + bnapi->last_status_idx); + else + REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, + bnapi->int_num | + BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | + bnapi->last_status_idx); + } else { + REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, + BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | + BNX2_PCICFG_INT_ACK_CMD_MASK_INT | + bnapi->last_status_idx); + + REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, + BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | + bnapi->last_status_idx); + } + bnapi->complete = 0; + } + } + return resched; } diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index ed63f2b..2abb48d 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -6642,6 +6642,7 @@ struct bnx2_napi { u16 *hw_rx_cons_ptr; u32 last_status_idx; u32 int_num; + u32 complete; struct bnx2_rx_ring_info rx_ring; struct bnx2_tx_ring_info tx_ring; -- 1.5.2.1