[BNX2]: Restructure IRQ datastructures.
[safe/jmp/linux-2.6] / drivers / net / bnx2.c
index ae081c8..83cdbde 100644 (file)
@@ -56,8 +56,8 @@
 
 #define DRV_MODULE_NAME                "bnx2"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "1.6.9"
-#define DRV_MODULE_RELDATE     "December 8, 2007"
+#define DRV_MODULE_VERSION     "1.7.0"
+#define DRV_MODULE_RELDATE     "December 11, 2007"
 
 #define RUN_AT(x) (jiffies + (x))
 
@@ -2323,17 +2323,25 @@ bnx2_phy_int(struct bnx2 *bp)
 
 }
 
+static inline u16
+bnx2_get_hw_tx_cons(struct bnx2 *bp)
+{
+       u16 cons;
+
+       cons = bp->status_blk->status_tx_quick_consumer_index0;
+
+       if (unlikely((cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT))
+               cons++;
+       return cons;
+}
+
 static void
 bnx2_tx_int(struct bnx2 *bp)
 {
-       struct status_block *sblk = bp->status_blk;
        u16 hw_cons, sw_cons, sw_ring_cons;
        int tx_free_bd = 0;
 
-       hw_cons = bp->hw_tx_cons = sblk->status_tx_quick_consumer_index0;
-       if ((hw_cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT) {
-               hw_cons++;
-       }
+       hw_cons = bnx2_get_hw_tx_cons(bp);
        sw_cons = bp->tx_cons;
 
        while (sw_cons != hw_cons) {
@@ -2385,14 +2393,10 @@ bnx2_tx_int(struct bnx2 *bp)
 
                dev_kfree_skb(skb);
 
-               hw_cons = bp->hw_tx_cons =
-                       sblk->status_tx_quick_consumer_index0;
-
-               if ((hw_cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT) {
-                       hw_cons++;
-               }
+               hw_cons = bnx2_get_hw_tx_cons(bp);
        }
 
+       bp->hw_tx_cons = hw_cons;
        bp->tx_cons = sw_cons;
        /* Need to make the tx_cons update visible to bnx2_start_xmit()
         * before checking for netif_queue_stopped().  Without the
@@ -2822,7 +2826,7 @@ bnx2_has_work(struct bnx2 *bp)
        struct status_block *sblk = bp->status_blk;
 
        if ((bnx2_get_hw_rx_cons(bp) != bp->rx_cons) ||
-           (sblk->status_tx_quick_consumer_index0 != bp->hw_tx_cons))
+           (bnx2_get_hw_tx_cons(bp) != bp->hw_tx_cons))
                return 1;
 
        if ((sblk->status_attn_bits & STATUS_ATTN_EVENTS) !=
@@ -2851,7 +2855,7 @@ static int bnx2_poll_work(struct bnx2 *bp, int work_done, int budget)
                REG_RD(bp, BNX2_HC_COMMAND);
        }
 
-       if (sblk->status_tx_quick_consumer_index0 != bp->hw_tx_cons)
+       if (bnx2_get_hw_tx_cons(bp) != bp->hw_tx_cons)
                bnx2_tx_int(bp);
 
        if (bnx2_get_hw_rx_cons(bp) != bp->rx_cons)
@@ -4917,7 +4921,7 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
        REG_RD(bp, BNX2_HC_COMMAND);
 
        udelay(5);
-       rx_start_idx = bp->status_blk->status_rx_quick_consumer_index0;
+       rx_start_idx = bnx2_get_hw_rx_cons(bp);
 
        num_pkts = 0;
 
@@ -4947,11 +4951,10 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
        pci_unmap_single(bp->pdev, map, pkt_size, PCI_DMA_TODEVICE);
        dev_kfree_skb(skb);
 
-       if (bp->status_blk->status_tx_quick_consumer_index0 != bp->tx_prod) {
+       if (bnx2_get_hw_tx_cons(bp) != bp->tx_prod)
                goto loopback_test_done;
-       }
 
-       rx_idx = bp->status_blk->status_rx_quick_consumer_index0;
+       rx_idx = bnx2_get_hw_rx_cons(bp);
        if (rx_idx != rx_start_idx + num_pkts) {
                goto loopback_test_done;
        }
@@ -5231,18 +5234,15 @@ static int
 bnx2_request_irq(struct bnx2 *bp)
 {
        struct net_device *dev = bp->dev;
-       int rc = 0;
-
-       if (bp->flags & USING_MSI_FLAG) {
-               irq_handler_t   fn = bnx2_msi;
-
-               if (bp->flags & ONE_SHOT_MSI_FLAG)
-                       fn = bnx2_msi_1shot;
+       unsigned long flags;
+       struct bnx2_irq *irq = &bp->irq_tbl[0];
+       int rc;
 
-               rc = request_irq(bp->pdev->irq, fn, 0, dev->name, dev);
-       } else
-               rc = request_irq(bp->pdev->irq, bnx2_interrupt,
-                                IRQF_SHARED, dev->name, dev);
+       if (bp->flags & USING_MSI_FLAG)
+               flags = 0;
+       else
+               flags = IRQF_SHARED;
+       rc = request_irq(irq->vector, irq->handler, flags, dev->name, dev);
        return rc;
 }
 
@@ -5251,12 +5251,31 @@ bnx2_free_irq(struct bnx2 *bp)
 {
        struct net_device *dev = bp->dev;
 
+       free_irq(bp->irq_tbl[0].vector, dev);
        if (bp->flags & USING_MSI_FLAG) {
-               free_irq(bp->pdev->irq, dev);
                pci_disable_msi(bp->pdev);
                bp->flags &= ~(USING_MSI_FLAG | ONE_SHOT_MSI_FLAG);
-       } else
-               free_irq(bp->pdev->irq, dev);
+       }
+}
+
+static void
+bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi)
+{
+       bp->irq_tbl[0].handler = bnx2_interrupt;
+       strcpy(bp->irq_tbl[0].name, bp->dev->name);
+
+       if ((bp->flags & MSI_CAP_FLAG) && !dis_msi) {
+               if (pci_enable_msi(bp->pdev) == 0) {
+                       bp->flags |= USING_MSI_FLAG;
+                       if (CHIP_NUM(bp) == CHIP_NUM_5709) {
+                               bp->flags |= ONE_SHOT_MSI_FLAG;
+                               bp->irq_tbl[0].handler = bnx2_msi_1shot;
+                       } else
+                               bp->irq_tbl[0].handler = bnx2_msi;
+               }
+       }
+
+       bp->irq_tbl[0].vector = bp->pdev->irq;
 }
 
 /* Called with rtnl_lock */
@@ -5275,15 +5294,8 @@ bnx2_open(struct net_device *dev)
        if (rc)
                return rc;
 
+       bnx2_setup_int_mode(bp, disable_msi);
        napi_enable(&bp->napi);
-
-       if ((bp->flags & MSI_CAP_FLAG) && !disable_msi) {
-               if (pci_enable_msi(bp->pdev) == 0) {
-                       bp->flags |= USING_MSI_FLAG;
-                       if (CHIP_NUM(bp) == CHIP_NUM_5709)
-                               bp->flags |= ONE_SHOT_MSI_FLAG;
-               }
-       }
        rc = bnx2_request_irq(bp);
 
        if (rc) {
@@ -5322,6 +5334,8 @@ bnx2_open(struct net_device *dev)
                        bnx2_disable_int(bp);
                        bnx2_free_irq(bp);
 
+                       bnx2_setup_int_mode(bp, 1);
+
                        rc = bnx2_init_nic(bp);
 
                        if (!rc)