[BNX2]: Fix driver software flag namespace.
[linux-2.6.git] / drivers / net / bnx2.c
index 4fc9d16..5605d41 100644 (file)
@@ -1,6 +1,6 @@
 /* bnx2.c: Broadcom NX2 network driver.
  *
- * Copyright (c) 2004-2007 Broadcom Corporation
+ * Copyright (c) 2004-2008 Broadcom Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -56,8 +56,8 @@
 
 #define DRV_MODULE_NAME                "bnx2"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "1.7.0"
-#define DRV_MODULE_RELDATE     "December 11, 2007"
+#define DRV_MODULE_VERSION     "1.7.2"
+#define DRV_MODULE_RELDATE     "January 21, 2008"
 
 #define RUN_AT(x) (jiffies + (x))
 
@@ -580,7 +580,7 @@ bnx2_alloc_mem(struct bnx2 *bp)
 
        /* Combine status and statistics blocks into one allocation. */
        status_blk_size = L1_CACHE_ALIGN(sizeof(struct status_block));
-       if (bp->flags & MSIX_CAP_FLAG)
+       if (bp->flags & BNX2_FLAG_MSIX_CAP)
                status_blk_size = L1_CACHE_ALIGN(BNX2_MAX_MSIX_HW_VEC *
                                                 BNX2_SBLK_MSIX_ALIGN_SIZE);
        bp->status_stats_size = status_blk_size +
@@ -594,11 +594,11 @@ bnx2_alloc_mem(struct bnx2 *bp)
        memset(bp->status_blk, 0, bp->status_stats_size);
 
        bp->bnx2_napi[0].status_blk = bp->status_blk;
-       if (bp->flags & MSIX_CAP_FLAG) {
+       if (bp->flags & BNX2_FLAG_MSIX_CAP) {
                for (i = 1; i < BNX2_MAX_MSIX_VEC; i++) {
                        struct bnx2_napi *bnapi = &bp->bnx2_napi[i];
 
-                       bnapi->status_blk = (void *)
+                       bnapi->status_blk_msix = (void *)
                                ((unsigned long) bp->status_blk +
                                 BNX2_SBLK_MSIX_ALIGN_SIZE * i);
                        bnapi->int_num = i << 24;
@@ -1186,6 +1186,19 @@ bnx2_disable_forced_2g5(struct bnx2 *bp)
        bnx2_write_phy(bp, bp->mii_bmcr, bmcr);
 }
 
+static void
+bnx2_5706s_force_link_dn(struct bnx2 *bp, int start)
+{
+       u32 val;
+
+       bnx2_write_phy(bp, MII_BNX2_DSP_ADDRESS, MII_EXPAND_SERDES_CTL);
+       bnx2_read_phy(bp, MII_BNX2_DSP_RW_PORT, &val);
+       if (start)
+               bnx2_write_phy(bp, MII_BNX2_DSP_RW_PORT, val & 0xff0f);
+       else
+               bnx2_write_phy(bp, MII_BNX2_DSP_RW_PORT, val | 0xc0);
+}
+
 static int
 bnx2_set_link(struct bnx2 *bp)
 {
@@ -1211,6 +1224,10 @@ bnx2_set_link(struct bnx2 *bp)
            (CHIP_NUM(bp) == CHIP_NUM_5706)) {
                u32 val;
 
+               if (bp->phy_flags & PHY_FORCED_DOWN_FLAG) {
+                       bnx2_5706s_force_link_dn(bp, 0);
+                       bp->phy_flags &= ~PHY_FORCED_DOWN_FLAG;
+               }
                val = REG_RD(bp, BNX2_EMAC_STATUS);
                if (val & BNX2_EMAC_STATUS_LINK)
                        bmsr |= BMSR_LSTATUS;
@@ -1239,7 +1256,15 @@ bnx2_set_link(struct bnx2 *bp)
                    (bp->autoneg & AUTONEG_SPEED))
                        bnx2_disable_forced_2g5(bp);
 
-               bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG;
+               if (bp->phy_flags & PHY_PARALLEL_DETECT_FLAG) {
+                       u32 bmcr;
+
+                       bnx2_read_phy(bp, bp->mii_bmcr, &bmcr);
+                       bmcr |= BMCR_ANENABLE;
+                       bnx2_write_phy(bp, bp->mii_bmcr, bmcr);
+
+                       bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG;
+               }
                bp->link_up = 0;
        }
 
@@ -2388,10 +2413,11 @@ bnx2_get_hw_tx_cons(struct bnx2_napi *bnapi)
        return cons;
 }
 
-static void
-bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi)
+static int
+bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
 {
        u16 hw_cons, sw_cons, sw_ring_cons;
+       int tx_pkt = 0;
 
        hw_cons = bnx2_get_hw_tx_cons(bnapi);
        sw_cons = bnapi->tx_cons;
@@ -2442,6 +2468,9 @@ bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi)
                sw_cons = NEXT_TX_BD(sw_cons);
 
                dev_kfree_skb(skb);
+               tx_pkt++;
+               if (tx_pkt == budget)
+                       break;
 
                hw_cons = bnx2_get_hw_tx_cons(bnapi);
        }
@@ -2463,6 +2492,7 @@ bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi)
                        netif_wake_queue(bp->dev);
                netif_tx_unlock(bp->dev);
        }
+       return tx_pkt;
 }
 
 static void
@@ -2752,7 +2782,7 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
                }
 
 #ifdef BCM_VLAN
-               if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) && (bp->vlgrp != 0)) {
+               if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) && bp->vlgrp) {
                        vlan_hwaccel_receive_skb(skb, bp->vlgrp,
                                rx_hdr->l2_fhdr_vlan_tag);
                }
@@ -2875,14 +2905,30 @@ bnx2_interrupt(int irq, void *dev_instance)
        return IRQ_HANDLED;
 }
 
+static irqreturn_t
+bnx2_tx_msix(int irq, void *dev_instance)
+{
+       struct net_device *dev = dev_instance;
+       struct bnx2 *bp = netdev_priv(dev);
+       struct bnx2_napi *bnapi = &bp->bnx2_napi[BNX2_TX_VEC];
+
+       prefetch(bnapi->status_blk_msix);
+
+       /* Return here if interrupt is disabled. */
+       if (unlikely(atomic_read(&bp->intr_sem) != 0))
+               return IRQ_HANDLED;
+
+       netif_rx_schedule(dev, &bnapi->napi);
+       return IRQ_HANDLED;
+}
+
 #define STATUS_ATTN_EVENTS     (STATUS_ATTN_BITS_LINK_STATE | \
                                 STATUS_ATTN_BITS_TIMER_ABORT)
 
 static inline int
 bnx2_has_work(struct bnx2_napi *bnapi)
 {
-       struct bnx2 *bp = bnapi->bp;
-       struct status_block *sblk = bp->status_blk;
+       struct status_block *sblk = bnapi->status_blk;
 
        if ((bnx2_get_hw_rx_cons(bnapi) != bnapi->rx_cons) ||
            (bnx2_get_hw_tx_cons(bnapi) != bnapi->hw_tx_cons))
@@ -2895,6 +2941,29 @@ bnx2_has_work(struct bnx2_napi *bnapi)
        return 0;
 }
 
+static int bnx2_tx_poll(struct napi_struct *napi, int budget)
+{
+       struct bnx2_napi *bnapi = container_of(napi, struct bnx2_napi, napi);
+       struct bnx2 *bp = bnapi->bp;
+       int work_done = 0;
+       struct status_block_msix *sblk = bnapi->status_blk_msix;
+
+       do {
+               work_done += bnx2_tx_int(bp, bnapi, budget - work_done);
+               if (unlikely(work_done >= budget))
+                       return work_done;
+
+               bnapi->last_status_idx = sblk->status_idx;
+               rmb();
+       } while (bnx2_get_hw_tx_cons(bnapi) != bnapi->hw_tx_cons);
+
+       netif_rx_complete(bp->dev, napi);
+       REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, bnapi->int_num |
+              BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
+              bnapi->last_status_idx);
+       return work_done;
+}
+
 static int bnx2_poll_work(struct bnx2 *bp, struct bnx2_napi *bnapi,
                          int work_done, int budget)
 {
@@ -2916,7 +2985,7 @@ static int bnx2_poll_work(struct bnx2 *bp, struct bnx2_napi *bnapi,
        }
 
        if (bnx2_get_hw_tx_cons(bnapi) != bnapi->hw_tx_cons)
-               bnx2_tx_int(bp, bnapi);
+               bnx2_tx_int(bp, bnapi, 0);
 
        if (bnx2_get_hw_rx_cons(bnapi) != bnapi->rx_cons)
                work_done += bnx2_rx_int(bp, bnapi, budget - work_done);
@@ -2945,7 +3014,7 @@ static int bnx2_poll(struct napi_struct *napi, int budget)
                rmb();
                if (likely(!bnx2_has_work(bnapi))) {
                        netif_rx_complete(bp->dev, napi);
-                       if (likely(bp->flags & USING_MSI_OR_MSIX_FLAG)) {
+                       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);
@@ -2982,10 +3051,10 @@ bnx2_set_rx_mode(struct net_device *dev)
                                  BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG);
        sort_mode = 1 | BNX2_RPM_SORT_USER0_BC_EN;
 #ifdef BCM_VLAN
-       if (!bp->vlgrp && !(bp->flags & ASF_ENABLE_FLAG))
+       if (!bp->vlgrp && !(bp->flags & BNX2_FLAG_ASF_ENABLE))
                rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG;
 #else
-       if (!(bp->flags & ASF_ENABLE_FLAG))
+       if (!(bp->flags & BNX2_FLAG_ASF_ENABLE))
                rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG;
 #endif
        if (dev->flags & IFF_PROMISC) {
@@ -3423,7 +3492,7 @@ bnx2_set_power_state(struct bnx2 *bp, pci_power_t state)
                        wol_msg = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL;
                }
 
-               if (!(bp->flags & NO_WOL_FLAG))
+               if (!(bp->flags & BNX2_FLAG_NO_WOL))
                        bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT3 | wol_msg, 0);
 
                pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
@@ -4214,7 +4283,7 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
                rc = bnx2_alloc_bad_rbuf(bp);
        }
 
-       if (bp->flags & USING_MSIX_FLAG)
+       if (bp->flags & BNX2_FLAG_USING_MSIX)
                bnx2_setup_msix_tbl(bp);
 
        return rc;
@@ -4240,11 +4309,11 @@ bnx2_init_chip(struct bnx2 *bp)
 
        val |= (0x2 << 20) | (1 << 11);
 
-       if ((bp->flags & PCIX_FLAG) && (bp->bus_speed_mhz == 133))
+       if ((bp->flags & BNX2_FLAG_PCIX) && (bp->bus_speed_mhz == 133))
                val |= (1 << 23);
 
        if ((CHIP_NUM(bp) == CHIP_NUM_5706) &&
-           (CHIP_ID(bp) != CHIP_ID_5706_A0) && !(bp->flags & PCIX_FLAG))
+           (CHIP_ID(bp) != CHIP_ID_5706_A0) && !(bp->flags & BNX2_FLAG_PCIX))
                val |= BNX2_DMA_CONFIG_CNTL_PING_PONG_DMA;
 
        REG_WR(bp, BNX2_DMA_CONFIG, val);
@@ -4255,7 +4324,7 @@ bnx2_init_chip(struct bnx2 *bp)
                REG_WR(bp, BNX2_TDMA_CONFIG, val);
        }
 
-       if (bp->flags & PCIX_FLAG) {
+       if (bp->flags & BNX2_FLAG_PCIX) {
                u16 val16;
 
                pci_read_config_word(bp->pdev, bp->pcix_cap + PCI_X_CMD,
@@ -4369,7 +4438,7 @@ bnx2_init_chip(struct bnx2 *bp)
                      BNX2_HC_CONFIG_COLLECT_STATS;
        }
 
-       if (bp->flags & USING_MSIX_FLAG) {
+       if (bp->flags & BNX2_FLAG_USING_MSIX) {
                REG_WR(bp, BNX2_HC_MSIX_BIT_VECTOR,
                       BNX2_HC_MSIX_BIT_VECTOR_VAL);
 
@@ -4387,7 +4456,7 @@ bnx2_init_chip(struct bnx2 *bp)
                val |= BNX2_HC_CONFIG_SB_ADDR_INC_128B;
        }
 
-       if (bp->flags & ONE_SHOT_MSI_FLAG)
+       if (bp->flags & BNX2_FLAG_ONE_SHOT_MSI)
                val |= BNX2_HC_CONFIG_ONE_SHOT;
 
        REG_WR(bp, BNX2_HC_CONFIG, val);
@@ -4474,7 +4543,7 @@ bnx2_init_tx_ring(struct bnx2 *bp)
        struct bnx2_napi *bnapi;
 
        bp->tx_vec = 0;
-       if (bp->flags & USING_MSIX_FLAG) {
+       if (bp->flags & BNX2_FLAG_USING_MSIX) {
                cid = TX_TSS_CID;
                bp->tx_vec = BNX2_TX_VEC;
                REG_WR(bp, BNX2_TSCH_TSS_CFG, BNX2_TX_INT_NUM |
@@ -4624,7 +4693,7 @@ bnx2_set_rx_ring_size(struct bnx2 *bp, u32 size)
        bp->rx_pg_ring_size = 0;
        bp->rx_max_pg_ring = 0;
        bp->rx_max_pg_ring_idx = 0;
-       if (rx_space > PAGE_SIZE) {
+       if ((rx_space > PAGE_SIZE) && !(bp->flags & BNX2_FLAG_JUMBO_BROKEN)) {
                int pages = PAGE_ALIGN(bp->dev->mtu - 40) >> PAGE_SHIFT;
 
                jumbo_size = size * pages;
@@ -5006,7 +5075,7 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
        struct bnx2_napi *bnapi = &bp->bnx2_napi[0], *tx_napi;
 
        tx_napi = bnapi;
-       if (bp->flags & USING_MSIX_FLAG)
+       if (bp->flags & BNX2_FLAG_USING_MSIX)
                tx_napi = &bp->bnx2_napi[BNX2_TX_VEC];
 
        if (loopback_mode == BNX2_MAC_LOOPBACK) {
@@ -5232,13 +5301,51 @@ bnx2_test_intr(struct bnx2 *bp)
        return -ENODEV;
 }
 
+static int
+bnx2_5706_serdes_has_link(struct bnx2 *bp)
+{
+       u32 mode_ctl, an_dbg, exp;
+
+       bnx2_write_phy(bp, MII_BNX2_MISC_SHADOW, MISC_SHDW_MODE_CTL);
+       bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &mode_ctl);
+
+       if (!(mode_ctl & MISC_SHDW_MODE_CTL_SIG_DET))
+               return 0;
+
+       bnx2_write_phy(bp, MII_BNX2_MISC_SHADOW, MISC_SHDW_AN_DBG);
+       bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &an_dbg);
+       bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &an_dbg);
+
+       if (an_dbg & MISC_SHDW_AN_DBG_NOSYNC)
+               return 0;
+
+       bnx2_write_phy(bp, MII_BNX2_DSP_ADDRESS, MII_EXPAND_REG1);
+       bnx2_read_phy(bp, MII_BNX2_DSP_RW_PORT, &exp);
+       bnx2_read_phy(bp, MII_BNX2_DSP_RW_PORT, &exp);
+
+       if (exp & MII_EXPAND_REG1_RUDI_C)       /* receiving CONFIG */
+               return 0;
+
+       return 1;
+}
+
 static void
 bnx2_5706_serdes_timer(struct bnx2 *bp)
 {
+       int check_link = 1;
+
        spin_lock(&bp->phy_lock);
-       if (bp->serdes_an_pending)
+       if (bp->phy_flags & PHY_FORCED_DOWN_FLAG) {
+               bnx2_5706s_force_link_dn(bp, 0);
+               bp->phy_flags &= ~PHY_FORCED_DOWN_FLAG;
+               spin_unlock(&bp->phy_lock);
+               return;
+       }
+
+       if (bp->serdes_an_pending) {
                bp->serdes_an_pending--;
-       else if ((bp->link_up == 0) && (bp->autoneg & AUTONEG_SPEED)) {
+               check_link = 0;
+       } else if ((bp->link_up == 0) && (bp->autoneg & AUTONEG_SPEED)) {
                u32 bmcr;
 
                bp->current_interval = bp->timer_interval;
@@ -5246,19 +5353,7 @@ bnx2_5706_serdes_timer(struct bnx2 *bp)
                bnx2_read_phy(bp, bp->mii_bmcr, &bmcr);
 
                if (bmcr & BMCR_ANENABLE) {
-                       u32 phy1, phy2;
-
-                       bnx2_write_phy(bp, 0x1c, 0x7c00);
-                       bnx2_read_phy(bp, 0x1c, &phy1);
-
-                       bnx2_write_phy(bp, 0x17, 0x0f01);
-                       bnx2_read_phy(bp, 0x15, &phy2);
-                       bnx2_write_phy(bp, 0x17, 0x0f01);
-                       bnx2_read_phy(bp, 0x15, &phy2);
-
-                       if ((phy1 & 0x10) &&    /* SIGNAL DETECT */
-                               !(phy2 & 0x20)) {       /* no CONFIG */
-
+                       if (bnx2_5706_serdes_has_link(bp)) {
                                bmcr &= ~BMCR_ANENABLE;
                                bmcr |= BMCR_SPEED1000 | BMCR_FULLDPLX;
                                bnx2_write_phy(bp, bp->mii_bmcr, bmcr);
@@ -5270,6 +5365,7 @@ bnx2_5706_serdes_timer(struct bnx2 *bp)
                 (bp->phy_flags & PHY_PARALLEL_DETECT_FLAG)) {
                u32 phy2;
 
+               check_link = 0;
                bnx2_write_phy(bp, 0x17, 0x0f01);
                bnx2_read_phy(bp, 0x15, &phy2);
                if (phy2 & 0x20) {
@@ -5284,6 +5380,18 @@ bnx2_5706_serdes_timer(struct bnx2 *bp)
        } else
                bp->current_interval = bp->timer_interval;
 
+       if (bp->link_up && (bp->autoneg & AUTONEG_SPEED) && check_link) {
+               u32 val;
+
+               bnx2_write_phy(bp, MII_BNX2_MISC_SHADOW, MISC_SHDW_AN_DBG);
+               bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &val);
+               bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &val);
+
+               if (val & MISC_SHDW_AN_DBG_NOSYNC) {
+                       bnx2_5706s_force_link_dn(bp, 1);
+                       bp->phy_flags |= PHY_FORCED_DOWN_FLAG;
+               }
+       }
        spin_unlock(&bp->phy_lock);
 }
 
@@ -5359,7 +5467,7 @@ bnx2_request_irq(struct bnx2 *bp)
        struct bnx2_irq *irq;
        int rc = 0, i;
 
-       if (bp->flags & USING_MSI_OR_MSIX_FLAG)
+       if (bp->flags & BNX2_FLAG_USING_MSI_OR_MSIX)
                flags = 0;
        else
                flags = IRQF_SHARED;
@@ -5388,21 +5496,46 @@ bnx2_free_irq(struct bnx2 *bp)
                        free_irq(irq->vector, dev);
                irq->requested = 0;
        }
-       if (bp->flags & USING_MSI_FLAG)
+       if (bp->flags & BNX2_FLAG_USING_MSI)
                pci_disable_msi(bp->pdev);
-       else if (bp->flags & USING_MSIX_FLAG)
+       else if (bp->flags & BNX2_FLAG_USING_MSIX)
                pci_disable_msix(bp->pdev);
 
-       bp->flags &= ~(USING_MSI_OR_MSIX_FLAG | ONE_SHOT_MSI_FLAG);
+       bp->flags &= ~(BNX2_FLAG_USING_MSI_OR_MSIX | BNX2_FLAG_ONE_SHOT_MSI);
 }
 
 static void
 bnx2_enable_msix(struct bnx2 *bp)
 {
+       int i, rc;
+       struct msix_entry msix_ent[BNX2_MAX_MSIX_VEC];
+
        bnx2_setup_msix_tbl(bp);
        REG_WR(bp, BNX2_PCI_MSIX_CONTROL, BNX2_MAX_MSIX_HW_VEC - 1);
        REG_WR(bp, BNX2_PCI_MSIX_TBL_OFF_BIR, BNX2_PCI_GRC_WINDOW2_BASE);
        REG_WR(bp, BNX2_PCI_MSIX_PBA_OFF_BIT, BNX2_PCI_GRC_WINDOW3_BASE);
+
+       for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) {
+               msix_ent[i].entry = i;
+               msix_ent[i].vector = 0;
+       }
+
+       rc = pci_enable_msix(bp->pdev, msix_ent, BNX2_MAX_MSIX_VEC);
+       if (rc != 0)
+               return;
+
+       bp->irq_tbl[BNX2_BASE_VEC].handler = bnx2_msi_1shot;
+       bp->irq_tbl[BNX2_TX_VEC].handler = bnx2_tx_msix;
+
+       strcpy(bp->irq_tbl[BNX2_BASE_VEC].name, bp->dev->name);
+       strcat(bp->irq_tbl[BNX2_BASE_VEC].name, "-base");
+       strcpy(bp->irq_tbl[BNX2_TX_VEC].name, bp->dev->name);
+       strcat(bp->irq_tbl[BNX2_TX_VEC].name, "-tx");
+
+       bp->irq_nvecs = BNX2_MAX_MSIX_VEC;
+       bp->flags |= BNX2_FLAG_USING_MSIX | BNX2_FLAG_ONE_SHOT_MSI;
+       for (i = 0; i < BNX2_MAX_MSIX_VEC; i++)
+               bp->irq_tbl[i].vector = msix_ent[i].vector;
 }
 
 static void
@@ -5413,15 +5546,15 @@ bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi)
        bp->irq_nvecs = 1;
        bp->irq_tbl[0].vector = bp->pdev->irq;
 
-       if ((bp->flags & MSIX_CAP_FLAG) && !dis_msi)
+       if ((bp->flags & BNX2_FLAG_MSIX_CAP) && !dis_msi)
                bnx2_enable_msix(bp);
 
-       if ((bp->flags & MSI_CAP_FLAG) && !dis_msi &&
-           !(bp->flags & USING_MSIX_FLAG)) {
+       if ((bp->flags & BNX2_FLAG_MSI_CAP) && !dis_msi &&
+           !(bp->flags & BNX2_FLAG_USING_MSIX)) {
                if (pci_enable_msi(bp->pdev) == 0) {
-                       bp->flags |= USING_MSI_FLAG;
+                       bp->flags |= BNX2_FLAG_USING_MSI;
                        if (CHIP_NUM(bp) == CHIP_NUM_5709) {
-                               bp->flags |= ONE_SHOT_MSI_FLAG;
+                               bp->flags |= BNX2_FLAG_ONE_SHOT_MSI;
                                bp->irq_tbl[0].handler = bnx2_msi_1shot;
                        } else
                                bp->irq_tbl[0].handler = bnx2_msi;
@@ -5473,7 +5606,7 @@ bnx2_open(struct net_device *dev)
 
        bnx2_enable_int(bp);
 
-       if (bp->flags & USING_MSI_FLAG) {
+       if (bp->flags & BNX2_FLAG_USING_MSI) {
                /* Test MSI to make sure it is working
                 * If MSI test fails, go back to INTx mode
                 */
@@ -5504,9 +5637,10 @@ bnx2_open(struct net_device *dev)
                        bnx2_enable_int(bp);
                }
        }
-       if (bp->flags & USING_MSI_FLAG) {
+       if (bp->flags & BNX2_FLAG_USING_MSI)
                printk(KERN_INFO PFX "%s: using MSI\n", dev->name);
-       }
+       else if (bp->flags & BNX2_FLAG_USING_MSIX)
+               printk(KERN_INFO PFX "%s: using MSIX\n", dev->name);
 
        netif_start_queue(dev);
 
@@ -5570,7 +5704,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
        u32 len, vlan_tag_flags, last_frag, mss;
        u16 prod, ring_prod;
        int i;
-       struct bnx2_napi *bnapi = &bp->bnx2_napi[0];
+       struct bnx2_napi *bnapi = &bp->bnx2_napi[bp->tx_vec];
 
        if (unlikely(bnx2_tx_avail(bp, bnapi) <
            (skb_shinfo(skb)->nr_frags + 1))) {
@@ -5589,7 +5723,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
                vlan_tag_flags |= TX_BD_FLAGS_TCP_UDP_CKSUM;
        }
 
-       if (bp->vlgrp != 0 && vlan_tx_tag_present(skb)) {
+       if (bp->vlgrp && vlan_tx_tag_present(skb)) {
                vlan_tag_flags |=
                        (TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16));
        }
@@ -5714,7 +5848,7 @@ bnx2_close(struct net_device *dev)
        bnx2_disable_int_sync(bp);
        bnx2_napi_disable(bp);
        del_timer_sync(&bp->timer);
-       if (bp->flags & NO_WOL_FLAG)
+       if (bp->flags & BNX2_FLAG_NO_WOL)
                reset_code = BNX2_DRV_MSG_CODE_UNLOAD_LNK_DN;
        else if (bp->wol)
                reset_code = BNX2_DRV_MSG_CODE_SUSPEND_WOL;
@@ -6037,7 +6171,7 @@ bnx2_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
        struct bnx2 *bp = netdev_priv(dev);
 
-       if (bp->flags & NO_WOL_FLAG) {
+       if (bp->flags & BNX2_FLAG_NO_WOL) {
                wol->supported = 0;
                wol->wolopts = 0;
        }
@@ -6060,7 +6194,7 @@ bnx2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
                return -EINVAL;
 
        if (wol->wolopts & WAKE_MAGIC) {
-               if (bp->flags & NO_WOL_FLAG)
+               if (bp->flags & BNX2_FLAG_NO_WOL)
                        return -EINVAL;
 
                bp->wol = 1;
@@ -6832,7 +6966,7 @@ bnx2_get_pci_speed(struct bnx2 *bp)
        if (reg & BNX2_PCICFG_MISC_STATUS_PCIX_DET) {
                u32 clkreg;
 
-               bp->flags |= PCIX_FLAG;
+               bp->flags |= BNX2_FLAG_PCIX;
 
                clkreg = REG_RD(bp, BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS);
 
@@ -6871,7 +7005,7 @@ bnx2_get_pci_speed(struct bnx2 *bp)
        }
 
        if (reg & BNX2_PCICFG_MISC_STATUS_32BIT_DET)
-               bp->flags |= PCI_32BIT_FLAG;
+               bp->flags |= BNX2_FLAG_PCI_32BIT;
 
 }
 
@@ -6959,7 +7093,9 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
                        rc = -EIO;
                        goto err_out_unmap;
                }
-               bp->flags |= PCIE_FLAG;
+               bp->flags |= BNX2_FLAG_PCIE;
+               if (CHIP_REV(bp) == CHIP_REV_Ax)
+                       bp->flags |= BNX2_FLAG_JUMBO_BROKEN;
        } else {
                bp->pcix_cap = pci_find_capability(pdev, PCI_CAP_ID_PCIX);
                if (bp->pcix_cap == 0) {
@@ -6972,12 +7108,12 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
 
        if (CHIP_NUM(bp) == CHIP_NUM_5709 && CHIP_REV(bp) != CHIP_REV_Ax) {
                if (pci_find_capability(pdev, PCI_CAP_ID_MSIX))
-                       bp->flags |= MSIX_CAP_FLAG;
+                       bp->flags |= BNX2_FLAG_MSIX_CAP;
        }
 
        if (CHIP_ID(bp) != CHIP_ID_5706_A0 && CHIP_ID(bp) != CHIP_ID_5706_A1) {
                if (pci_find_capability(pdev, PCI_CAP_ID_MSI))
-                       bp->flags |= MSI_CAP_FLAG;
+                       bp->flags |= BNX2_FLAG_MSI_CAP;
        }
 
        /* 5708 cannot support DMA addresses > 40-bit.  */
@@ -7000,7 +7136,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
                goto err_out_unmap;
        }
 
-       if (!(bp->flags & PCIE_FLAG))
+       if (!(bp->flags & BNX2_FLAG_PCIE))
                bnx2_get_pci_speed(bp);
 
        /* 5706A0 may falsely detect SERR and PERR. */
@@ -7010,7 +7146,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
                REG_WR(bp, PCI_COMMAND, reg);
        }
        else if ((CHIP_ID(bp) == CHIP_ID_5706_A1) &&
-               !(bp->flags & PCIX_FLAG)) {
+               !(bp->flags & BNX2_FLAG_PCIX)) {
 
                dev_err(&pdev->dev,
                        "5706 A1 can only be used in a PCIX bus, aborting.\n");
@@ -7060,7 +7196,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
                bp->wol = 1;
 
        if (reg & BNX2_PORT_FEATURE_ASF_ENABLED) {
-               bp->flags |= ASF_ENABLE_FLAG;
+               bp->flags |= BNX2_FLAG_ASF_ENABLE;
 
                for (i = 0; i < 30; i++) {
                        reg = REG_RD_IND(bp, bp->shmem_base +
@@ -7132,7 +7268,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
                reg = REG_RD_IND(bp, bp->shmem_base +
                                     BNX2_SHARED_HW_CFG_CONFIG);
                if (!(reg & BNX2_SHARED_HW_CFG_GIG_LINK_ON_VAUX)) {
-                       bp->flags |= NO_WOL_FLAG;
+                       bp->flags |= BNX2_FLAG_NO_WOL;
                        bp->wol = 0;
                }
                if (CHIP_NUM(bp) != CHIP_NUM_5706) {
@@ -7153,7 +7289,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
        if ((CHIP_ID(bp) == CHIP_ID_5708_A0) ||
            (CHIP_ID(bp) == CHIP_ID_5708_B0) ||
            (CHIP_ID(bp) == CHIP_ID_5708_B1)) {
-               bp->flags |= NO_WOL_FLAG;
+               bp->flags |= BNX2_FLAG_NO_WOL;
                bp->wol = 0;
        }
 
@@ -7227,13 +7363,13 @@ bnx2_bus_string(struct bnx2 *bp, char *str)
 {
        char *s = str;
 
-       if (bp->flags & PCIE_FLAG) {
+       if (bp->flags & BNX2_FLAG_PCIE) {
                s += sprintf(s, "PCI Express");
        } else {
                s += sprintf(s, "PCI");
-               if (bp->flags & PCIX_FLAG)
+               if (bp->flags & BNX2_FLAG_PCIX)
                        s += sprintf(s, "-X");
-               if (bp->flags & PCI_32BIT_FLAG)
+               if (bp->flags & BNX2_FLAG_PCI_32BIT)
                        s += sprintf(s, " 32-bit");
                else
                        s += sprintf(s, " 64-bit");
@@ -7242,7 +7378,7 @@ bnx2_bus_string(struct bnx2 *bp, char *str)
        return str;
 }
 
-static int __devinit
+static void __devinit
 bnx2_init_napi(struct bnx2 *bp)
 {
        int i;
@@ -7253,6 +7389,8 @@ bnx2_init_napi(struct bnx2 *bp)
                bnapi->bp = bp;
        }
        netif_napi_add(bp->dev, &bp->bnx2_napi[0].napi, bnx2_poll, 64);
+       netif_napi_add(bp->dev, &bp->bnx2_napi[BNX2_TX_VEC].napi, bnx2_tx_poll,
+                      64);
 }
 
 static int __devinit
@@ -7381,7 +7519,7 @@ bnx2_suspend(struct pci_dev *pdev, pm_message_t state)
        bnx2_netif_stop(bp);
        netif_device_detach(dev);
        del_timer_sync(&bp->timer);
-       if (bp->flags & NO_WOL_FLAG)
+       if (bp->flags & BNX2_FLAG_NO_WOL)
                reset_code = BNX2_DRV_MSG_CODE_UNLOAD_LNK_DN;
        else if (bp->wol)
                reset_code = BNX2_DRV_MSG_CODE_SUSPEND_WOL;