aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2008-06-19 19:41:57 -0400
committerDavid S. Miller <davem@davemloft.net>2008-06-19 19:41:57 -0400
commitf0ea2e63859cf234b7017a2d7bba2a5a1db3bf25 (patch)
tree6b5e2e18ce331d0467a729cbde0e5680c6d447b3 /drivers/net
parent43e80b89b65cbc62b5e0fde09b47c9fc572a8b11 (diff)
bnx2: Use one handler for all MSI-X vectors.
Use the same MSI-X handler to schedule NAPI. Change the dev_instance void pointer to the bnx2_napi struct instead so we can have the proper context for each MSI-X vector. Add a new bnx2_poll_msix() that is optimized for handling MSI-X NAPI polling of rx/tx work only. Remove the old bnx2_tx_poll() that is no longer needed. Each MSI-X vector handles 1 tx and 1 rx ring. The first vector handles link events as well. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: Benjamin Li <benli@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/bnx2.c99
1 files changed, 40 insertions, 59 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 3872e51b3c85..0a297f77a276 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -2996,9 +2996,9 @@ next_rx:
2996static irqreturn_t 2996static irqreturn_t
2997bnx2_msi(int irq, void *dev_instance) 2997bnx2_msi(int irq, void *dev_instance)
2998{ 2998{
2999 struct net_device *dev = dev_instance; 2999 struct bnx2_napi *bnapi = dev_instance;
3000 struct bnx2 *bp = netdev_priv(dev); 3000 struct bnx2 *bp = bnapi->bp;
3001 struct bnx2_napi *bnapi = &bp->bnx2_napi[0]; 3001 struct net_device *dev = bp->dev;
3002 3002
3003 prefetch(bnapi->status_blk.msi); 3003 prefetch(bnapi->status_blk.msi);
3004 REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, 3004 REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
@@ -3017,9 +3017,9 @@ bnx2_msi(int irq, void *dev_instance)
3017static irqreturn_t 3017static irqreturn_t
3018bnx2_msi_1shot(int irq, void *dev_instance) 3018bnx2_msi_1shot(int irq, void *dev_instance)
3019{ 3019{
3020 struct net_device *dev = dev_instance; 3020 struct bnx2_napi *bnapi = dev_instance;
3021 struct bnx2 *bp = netdev_priv(dev); 3021 struct bnx2 *bp = bnapi->bp;
3022 struct bnx2_napi *bnapi = &bp->bnx2_napi[0]; 3022 struct net_device *dev = bp->dev;
3023 3023
3024 prefetch(bnapi->status_blk.msi); 3024 prefetch(bnapi->status_blk.msi);
3025 3025
@@ -3035,9 +3035,9 @@ bnx2_msi_1shot(int irq, void *dev_instance)
3035static irqreturn_t 3035static irqreturn_t
3036bnx2_interrupt(int irq, void *dev_instance) 3036bnx2_interrupt(int irq, void *dev_instance)
3037{ 3037{
3038 struct net_device *dev = dev_instance; 3038 struct bnx2_napi *bnapi = dev_instance;
3039 struct bnx2 *bp = netdev_priv(dev); 3039 struct bnx2 *bp = bnapi->bp;
3040 struct bnx2_napi *bnapi = &bp->bnx2_napi[0]; 3040 struct net_device *dev = bp->dev;
3041 struct status_block *sblk = bnapi->status_blk.msi; 3041 struct status_block *sblk = bnapi->status_blk.msi;
3042 3042
3043 /* When using INTx, it is possible for the interrupt to arrive 3043 /* When using INTx, it is possible for the interrupt to arrive
@@ -3072,23 +3072,6 @@ bnx2_interrupt(int irq, void *dev_instance)
3072 return IRQ_HANDLED; 3072 return IRQ_HANDLED;
3073} 3073}
3074 3074
3075static irqreturn_t
3076bnx2_tx_msix(int irq, void *dev_instance)
3077{
3078 struct net_device *dev = dev_instance;
3079 struct bnx2 *bp = netdev_priv(dev);
3080 struct bnx2_napi *bnapi = &bp->bnx2_napi[BNX2_TX_VEC];
3081
3082 prefetch(bnapi->status_blk.msix);
3083
3084 /* Return here if interrupt is disabled. */
3085 if (unlikely(atomic_read(&bp->intr_sem) != 0))
3086 return IRQ_HANDLED;
3087
3088 netif_rx_schedule(dev, &bnapi->napi);
3089 return IRQ_HANDLED;
3090}
3091
3092static inline int 3075static inline int
3093bnx2_has_fast_work(struct bnx2_napi *bnapi) 3076bnx2_has_fast_work(struct bnx2_napi *bnapi)
3094{ 3077{
@@ -3119,30 +3102,6 @@ bnx2_has_work(struct bnx2_napi *bnapi)
3119 return 0; 3102 return 0;
3120} 3103}
3121 3104
3122static int bnx2_tx_poll(struct napi_struct *napi, int budget)
3123{
3124 struct bnx2_napi *bnapi = container_of(napi, struct bnx2_napi, napi);
3125 struct bnx2 *bp = bnapi->bp;
3126 struct bnx2_tx_ring_info *txr = &bnapi->tx_ring;
3127 int work_done = 0;
3128 struct status_block_msix *sblk = bnapi->status_blk.msix;
3129
3130 do {
3131 work_done += bnx2_tx_int(bp, bnapi, budget - work_done);
3132 if (unlikely(work_done >= budget))
3133 return work_done;
3134
3135 bnapi->last_status_idx = sblk->status_idx;
3136 rmb();
3137 } while (bnx2_get_hw_tx_cons(bnapi) != txr->hw_tx_cons);
3138
3139 netif_rx_complete(bp->dev, napi);
3140 REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, bnapi->int_num |
3141 BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
3142 bnapi->last_status_idx);
3143 return work_done;
3144}
3145
3146static void bnx2_poll_link(struct bnx2 *bp, struct bnx2_napi *bnapi) 3105static void bnx2_poll_link(struct bnx2 *bp, struct bnx2_napi *bnapi)
3147{ 3106{
3148 struct status_block *sblk = bnapi->status_blk.msi; 3107 struct status_block *sblk = bnapi->status_blk.msi;
@@ -3178,6 +3137,33 @@ static int bnx2_poll_work(struct bnx2 *bp, struct bnx2_napi *bnapi,
3178 return work_done; 3137 return work_done;
3179} 3138}
3180 3139
3140static int bnx2_poll_msix(struct napi_struct *napi, int budget)
3141{
3142 struct bnx2_napi *bnapi = container_of(napi, struct bnx2_napi, napi);
3143 struct bnx2 *bp = bnapi->bp;
3144 int work_done = 0;
3145 struct status_block_msix *sblk = bnapi->status_blk.msix;
3146
3147 while (1) {
3148 work_done = bnx2_poll_work(bp, bnapi, work_done, budget);
3149 if (unlikely(work_done >= budget))
3150 break;
3151
3152 bnapi->last_status_idx = sblk->status_idx;
3153 /* status idx must be read before checking for more work. */
3154 rmb();
3155 if (likely(!bnx2_has_fast_work(bnapi))) {
3156
3157 netif_rx_complete(bp->dev, napi);
3158 REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, bnapi->int_num |
3159 BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
3160 bnapi->last_status_idx);
3161 break;
3162 }
3163 }
3164 return work_done;
3165}
3166
3181static int bnx2_poll(struct napi_struct *napi, int budget) 3167static int bnx2_poll(struct napi_struct *napi, int budget)
3182{ 3168{
3183 struct bnx2_napi *bnapi = container_of(napi, struct bnx2_napi, napi); 3169 struct bnx2_napi *bnapi = container_of(napi, struct bnx2_napi, napi);
@@ -5636,7 +5622,6 @@ bnx2_restart_timer:
5636static int 5622static int
5637bnx2_request_irq(struct bnx2 *bp) 5623bnx2_request_irq(struct bnx2 *bp)
5638{ 5624{
5639 struct net_device *dev = bp->dev;
5640 unsigned long flags; 5625 unsigned long flags;
5641 struct bnx2_irq *irq; 5626 struct bnx2_irq *irq;
5642 int rc = 0, i; 5627 int rc = 0, i;
@@ -5649,7 +5634,7 @@ bnx2_request_irq(struct bnx2 *bp)
5649 for (i = 0; i < bp->irq_nvecs; i++) { 5634 for (i = 0; i < bp->irq_nvecs; i++) {
5650 irq = &bp->irq_tbl[i]; 5635 irq = &bp->irq_tbl[i];
5651 rc = request_irq(irq->vector, irq->handler, flags, irq->name, 5636 rc = request_irq(irq->vector, irq->handler, flags, irq->name,
5652 dev); 5637 &bp->bnx2_napi[i]);
5653 if (rc) 5638 if (rc)
5654 break; 5639 break;
5655 irq->requested = 1; 5640 irq->requested = 1;
@@ -5660,14 +5645,13 @@ bnx2_request_irq(struct bnx2 *bp)
5660static void 5645static void
5661bnx2_free_irq(struct bnx2 *bp) 5646bnx2_free_irq(struct bnx2 *bp)
5662{ 5647{
5663 struct net_device *dev = bp->dev;
5664 struct bnx2_irq *irq; 5648 struct bnx2_irq *irq;
5665 int i; 5649 int i;
5666 5650
5667 for (i = 0; i < bp->irq_nvecs; i++) { 5651 for (i = 0; i < bp->irq_nvecs; i++) {
5668 irq = &bp->irq_tbl[i]; 5652 irq = &bp->irq_tbl[i];
5669 if (irq->requested) 5653 if (irq->requested)
5670 free_irq(irq->vector, dev); 5654 free_irq(irq->vector, &bp->bnx2_napi[i]);
5671 irq->requested = 0; 5655 irq->requested = 0;
5672 } 5656 }
5673 if (bp->flags & BNX2_FLAG_USING_MSI) 5657 if (bp->flags & BNX2_FLAG_USING_MSI)
@@ -5694,10 +5678,7 @@ bnx2_enable_msix(struct bnx2 *bp)
5694 msix_ent[i].vector = 0; 5678 msix_ent[i].vector = 0;
5695 5679
5696 strcpy(bp->irq_tbl[i].name, bp->dev->name); 5680 strcpy(bp->irq_tbl[i].name, bp->dev->name);
5697 if (i == 0) 5681 bp->irq_tbl[i].handler = bnx2_msi_1shot;
5698 bp->irq_tbl[i].handler = bnx2_msi_1shot;
5699 else
5700 bp->irq_tbl[i].handler = bnx2_tx_msix;
5701 } 5682 }
5702 5683
5703 rc = pci_enable_msix(bp->pdev, msix_ent, BNX2_MAX_MSIX_VEC); 5684 rc = pci_enable_msix(bp->pdev, msix_ent, BNX2_MAX_MSIX_VEC);
@@ -7567,7 +7548,7 @@ bnx2_init_napi(struct bnx2 *bp)
7567 if (i == 0) 7548 if (i == 0)
7568 poll = bnx2_poll; 7549 poll = bnx2_poll;
7569 else 7550 else
7570 poll = bnx2_tx_poll; 7551 poll = bnx2_poll_msix;
7571 7552
7572 netif_napi_add(bp->dev, &bp->bnx2_napi[i].napi, poll, 64); 7553 netif_napi_add(bp->dev, &bp->bnx2_napi[i].napi, poll, 64);
7573 bnapi->bp = bp; 7554 bnapi->bp = bp;