Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[safe/jmp/linux-2.6] / drivers / net / tg3.c
index 65ff286..7195bde 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com)
  * Copyright (C) 2001, 2002, 2003 Jeff Garzik (jgarzik@pobox.com)
  * Copyright (C) 2004 Sun Microsystems Inc.
- * Copyright (C) 2005-2009 Broadcom Corporation.
+ * Copyright (C) 2005-2010 Broadcom Corporation.
  *
  * Firmware is:
  *     Derived from proprietary unpublished source code,
@@ -68,8 +68,8 @@
 
 #define DRV_MODULE_NAME                "tg3"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "3.101"
-#define DRV_MODULE_RELDATE     "August 28, 2009"
+#define DRV_MODULE_VERSION     "3.106"
+#define DRV_MODULE_RELDATE     "January 12, 2010"
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
 #define TG3_DEF_RX_RING_PENDING                200
 #define TG3_RX_JUMBO_RING_SIZE         256
 #define TG3_DEF_RX_JUMBO_RING_PENDING  100
+#define TG3_RSS_INDIR_TBL_SIZE 128
 
 /* Do not place this n-ring entries value into the tp struct itself,
  * we really want to expose these constants to GCC so that modulo et
  * replace things like '% foo' with '& (foo - 1)'.
  */
 #define TG3_RX_RCB_RING_SIZE(tp)       \
-       ((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ?  512 : 1024)
+       (((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) && \
+         !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) ? 1024 : 512)
 
 #define TG3_TX_RING_SIZE               512
 #define TG3_DEF_TX_RING_PENDING                (TG3_TX_RING_SIZE - 1)
 #define TG3_RX_STD_MAP_SZ              TG3_RX_DMA_TO_MAP_SZ(TG3_RX_STD_DMA_SZ)
 #define TG3_RX_JMB_MAP_SZ              TG3_RX_DMA_TO_MAP_SZ(TG3_RX_JMB_DMA_SZ)
 
+#define TG3_RX_STD_BUFF_RING_SIZE \
+       (sizeof(struct ring_info) * TG3_RX_RING_SIZE)
+
+#define TG3_RX_JMB_BUFF_RING_SIZE \
+       (sizeof(struct ring_info) * TG3_RX_JUMBO_RING_SIZE)
+
 /* minimum number of free TX descriptors required to wake up TX process */
 #define TG3_TX_WAKEUP_THRESH(tnapi)            ((tnapi)->tx_pending / 4)
 
@@ -160,12 +168,13 @@ MODULE_FIRMWARE(FIRMWARE_TG3);
 MODULE_FIRMWARE(FIRMWARE_TG3TSO);
 MODULE_FIRMWARE(FIRMWARE_TG3TSO5);
 
+#define TG3_RSS_MIN_NUM_MSIX_VECS      2
 
 static int tg3_debug = -1;     /* -1 == use TG3_DEF_MSG_ENABLE as value */
 module_param(tg3_debug, int, 0);
 MODULE_PARM_DESC(tg3_debug, "Tigon3 bitmapped debugging message enable value");
 
-static struct pci_device_id tg3_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(tg3_pci_tbl) = {
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5700)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5701)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5702)},
@@ -232,6 +241,15 @@ static struct pci_device_id tg3_pci_tbl[] = {
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57760)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57790)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57788)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5717)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5718)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5724)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57781)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57785)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57761)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57765)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57791)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57795)},
        {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)},
        {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX)},
        {PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000)},
@@ -393,7 +411,7 @@ static void tg3_write_indirect_mbox(struct tg3 *tp, u32 off, u32 val)
                                       TG3_64BIT_REG_LOW, val);
                return;
        }
-       if (off == (MAILBOX_RCV_STD_PROD_IDX + TG3_64BIT_REG_LOW)) {
+       if (off == TG3_RX_STD_PROD_IDX_REG) {
                pci_write_config_dword(tp->pdev, TG3PCI_STD_RING_PROD_IDX +
                                       TG3_64BIT_REG_LOW, val);
                return;
@@ -613,25 +631,33 @@ static void tg3_ape_unlock(struct tg3 *tp, int locknum)
 
 static void tg3_disable_ints(struct tg3 *tp)
 {
+       int i;
+
        tw32(TG3PCI_MISC_HOST_CTRL,
             (tp->misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT));
-       tw32_mailbox_f(tp->napi[0].int_mbox, 0x00000001);
+       for (i = 0; i < tp->irq_max; i++)
+               tw32_mailbox_f(tp->napi[i].int_mbox, 0x00000001);
 }
 
 static void tg3_enable_ints(struct tg3 *tp)
 {
-       u32 coal_now;
-       struct tg3_napi *tnapi = &tp->napi[0];
+       int i;
+       u32 coal_now = 0;
+
        tp->irq_sync = 0;
        wmb();
 
        tw32(TG3PCI_MISC_HOST_CTRL,
             (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT));
-       tw32_mailbox_f(tnapi->int_mbox, tnapi->last_tag << 24);
-       if (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI)
+
+       for (i = 0; i < tp->irq_cnt; i++) {
+               struct tg3_napi *tnapi = &tp->napi[i];
                tw32_mailbox_f(tnapi->int_mbox, tnapi->last_tag << 24);
+               if (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI)
+                       tw32_mailbox_f(tnapi->int_mbox, tnapi->last_tag << 24);
 
-       coal_now = HOSTCC_MODE_NOW;
+               coal_now |= tnapi->coal_now;
+       }
 
        /* Force an initial interrupt */
        if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) &&
@@ -657,7 +683,7 @@ static inline unsigned int tg3_has_work(struct tg3_napi *tnapi)
        }
        /* check for RX/TX work to do */
        if (sblk->idx[0].tx_consumer != tnapi->tx_cons ||
-           sblk->idx[0].rx_producer != tnapi->rx_rcb_ptr)
+           *(tnapi->rx_rcb_prod_idx) != tnapi->rx_rcb_ptr)
                work_exists = 1;
 
        return work_exists;
@@ -682,38 +708,56 @@ static void tg3_int_reenable(struct tg3_napi *tnapi)
        if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) &&
            tg3_has_work(tnapi))
                tw32(HOSTCC_MODE, tp->coalesce_mode |
-                    (HOSTCC_MODE_ENABLE | HOSTCC_MODE_NOW));
+                    HOSTCC_MODE_ENABLE | tnapi->coal_now);
+}
+
+static void tg3_napi_disable(struct tg3 *tp)
+{
+       int i;
+
+       for (i = tp->irq_cnt - 1; i >= 0; i--)
+               napi_disable(&tp->napi[i].napi);
+}
+
+static void tg3_napi_enable(struct tg3 *tp)
+{
+       int i;
+
+       for (i = 0; i < tp->irq_cnt; i++)
+               napi_enable(&tp->napi[i].napi);
 }
 
 static inline void tg3_netif_stop(struct tg3 *tp)
 {
        tp->dev->trans_start = jiffies; /* prevent tx timeout */
-       napi_disable(&tp->napi[0].napi);
+       tg3_napi_disable(tp);
        netif_tx_disable(tp->dev);
 }
 
 static inline void tg3_netif_start(struct tg3 *tp)
 {
-       struct tg3_napi *tnapi = &tp->napi[0];
-       netif_wake_queue(tp->dev);
-       /* NOTE: unconditional netif_wake_queue is only appropriate
-        * so long as all callers are assured to have free tx slots
-        * (such as after tg3_init_hw)
+       /* NOTE: unconditional netif_tx_wake_all_queues is only
+        * appropriate so long as all callers are assured to
+        * have free tx slots (such as after tg3_init_hw)
         */
-       napi_enable(&tnapi->napi);
-       tnapi->hw_status->status |= SD_STATUS_UPDATED;
+       netif_tx_wake_all_queues(tp->dev);
+
+       tg3_napi_enable(tp);
+       tp->napi[0].hw_status->status |= SD_STATUS_UPDATED;
        tg3_enable_ints(tp);
 }
 
 static void tg3_switch_clocks(struct tg3 *tp)
 {
-       u32 clock_ctrl = tr32(TG3PCI_CLOCK_CTRL);
+       u32 clock_ctrl;
        u32 orig_clock_ctrl;
 
        if ((tp->tg3_flags & TG3_FLAG_CPMU_PRESENT) ||
            (tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
                return;
 
+       clock_ctrl = tr32(TG3PCI_CLOCK_CTRL);
+
        orig_clock_ctrl = clock_ctrl;
        clock_ctrl &= (CLOCK_CTRL_FORCE_CLKRUN |
                       CLOCK_CTRL_CLKRUN_OENABLE |
@@ -753,7 +797,7 @@ static int tg3_readphy(struct tg3 *tp, int reg, u32 *val)
 
        *val = 0x0;
 
-       frame_val  = ((PHY_ADDR << MI_COM_PHY_ADDR_SHIFT) &
+       frame_val  = ((tp->phy_addr << MI_COM_PHY_ADDR_SHIFT) &
                      MI_COM_PHY_ADDR_MASK);
        frame_val |= ((reg << MI_COM_REG_ADDR_SHIFT) &
                      MI_COM_REG_ADDR_MASK);
@@ -804,7 +848,7 @@ static int tg3_writephy(struct tg3 *tp, int reg, u32 val)
                udelay(80);
        }
 
-       frame_val  = ((PHY_ADDR << MI_COM_PHY_ADDR_SHIFT) &
+       frame_val  = ((tp->phy_addr << MI_COM_PHY_ADDR_SHIFT) &
                      MI_COM_PHY_ADDR_MASK);
        frame_val |= ((reg << MI_COM_REG_ADDR_SHIFT) &
                      MI_COM_REG_ADDR_MASK);
@@ -873,11 +917,12 @@ static int tg3_mdio_read(struct mii_bus *bp, int mii_id, int reg)
        struct tg3 *tp = bp->priv;
        u32 val;
 
-       if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED)
-               return -EAGAIN;
+       spin_lock_bh(&tp->lock);
 
        if (tg3_readphy(tp, reg, &val))
-               return -EIO;
+               val = -EIO;
+
+       spin_unlock_bh(&tp->lock);
 
        return val;
 }
@@ -885,14 +930,16 @@ static int tg3_mdio_read(struct mii_bus *bp, int mii_id, int reg)
 static int tg3_mdio_write(struct mii_bus *bp, int mii_id, int reg, u16 val)
 {
        struct tg3 *tp = bp->priv;
+       u32 ret = 0;
 
-       if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED)
-               return -EAGAIN;
+       spin_lock_bh(&tp->lock);
 
        if (tg3_writephy(tp, reg, val))
-               return -EIO;
+               ret = -EIO;
 
-       return 0;
+       spin_unlock_bh(&tp->lock);
+
+       return ret;
 }
 
 static int tg3_mdio_reset(struct mii_bus *bp)
@@ -905,9 +952,10 @@ static void tg3_mdio_config_5785(struct tg3 *tp)
        u32 val;
        struct phy_device *phydev;
 
-       phydev = tp->mdio_bus->phy_map[PHY_ADDR];
+       phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
        switch (phydev->drv->phy_id & phydev->drv->phy_id_mask) {
        case TG3_PHY_ID_BCM50610:
+       case TG3_PHY_ID_BCM50610M:
                val = MAC_PHYCFG2_50610_LED_MODES;
                break;
        case TG3_PHY_ID_BCMAC131:
@@ -982,30 +1030,34 @@ static void tg3_mdio_config_5785(struct tg3 *tp)
 
 static void tg3_mdio_start(struct tg3 *tp)
 {
-       if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) {
-               mutex_lock(&tp->mdio_bus->mdio_lock);
-               tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_PAUSED;
-               mutex_unlock(&tp->mdio_bus->mdio_lock);
-       }
-
        tp->mi_mode &= ~MAC_MI_MODE_AUTO_POLL;
        tw32_f(MAC_MI_MODE, tp->mi_mode);
        udelay(80);
 
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) {
+               u32 funcnum, is_serdes;
+
+               funcnum = tr32(TG3_CPMU_STATUS) & TG3_CPMU_STATUS_PCIE_FUNC;
+               if (funcnum)
+                       tp->phy_addr = 2;
+               else
+                       tp->phy_addr = 1;
+
+               if (tp->pci_chip_rev_id != CHIPREV_ID_5717_A0)
+                       is_serdes = tr32(SG_DIG_STATUS) & SG_DIG_IS_SERDES;
+               else
+                       is_serdes = tr32(TG3_CPMU_PHY_STRAP) &
+                                   TG3_CPMU_PHY_STRAP_IS_SERDES;
+               if (is_serdes)
+                       tp->phy_addr += 7;
+       } else
+               tp->phy_addr = TG3_PHY_MII_ADDR;
+
        if ((tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) &&
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
                tg3_mdio_config_5785(tp);
 }
 
-static void tg3_mdio_stop(struct tg3 *tp)
-{
-       if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) {
-               mutex_lock(&tp->mdio_bus->mdio_lock);
-               tp->tg3_flags3 |= TG3_FLG3_MDIOBUS_PAUSED;
-               mutex_unlock(&tp->mdio_bus->mdio_lock);
-       }
-}
-
 static int tg3_mdio_init(struct tg3 *tp)
 {
        int i;
@@ -1030,7 +1082,7 @@ static int tg3_mdio_init(struct tg3 *tp)
        tp->mdio_bus->read     = &tg3_mdio_read;
        tp->mdio_bus->write    = &tg3_mdio_write;
        tp->mdio_bus->reset    = &tg3_mdio_reset;
-       tp->mdio_bus->phy_mask = ~(1 << PHY_ADDR);
+       tp->mdio_bus->phy_mask = ~(1 << TG3_PHY_MII_ADDR);
        tp->mdio_bus->irq      = &tp->mdio_irq[0];
 
        for (i = 0; i < PHY_MAX_ADDR; i++)
@@ -1052,7 +1104,7 @@ static int tg3_mdio_init(struct tg3 *tp)
                return i;
        }
 
-       phydev = tp->mdio_bus->phy_map[PHY_ADDR];
+       phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
 
        if (!phydev || !phydev->drv) {
                printk(KERN_WARNING "%s: No PHY devices\n", tp->dev->name);
@@ -1064,8 +1116,14 @@ static int tg3_mdio_init(struct tg3 *tp)
        switch (phydev->drv->phy_id & phydev->drv->phy_id_mask) {
        case TG3_PHY_ID_BCM57780:
                phydev->interface = PHY_INTERFACE_MODE_GMII;
+               phydev->dev_flags |= PHY_BRCM_AUTO_PWRDWN_ENABLE;
                break;
        case TG3_PHY_ID_BCM50610:
+       case TG3_PHY_ID_BCM50610M:
+               phydev->dev_flags |= PHY_BRCM_CLEAR_RGMII_MODE |
+                                    PHY_BRCM_RX_REFCLK_UNUSED |
+                                    PHY_BRCM_DIS_TXCRXC_NOENRGY |
+                                    PHY_BRCM_AUTO_PWRDWN_ENABLE;
                if (tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE)
                        phydev->dev_flags |= PHY_BRCM_STD_IBND_DISABLE;
                if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_RX_EN)
@@ -1079,6 +1137,7 @@ static int tg3_mdio_init(struct tg3 *tp)
        case TG3_PHY_ID_RTL8201E:
        case TG3_PHY_ID_BCMAC131:
                phydev->interface = PHY_INTERFACE_MODE_MII;
+               phydev->dev_flags |= PHY_BRCM_AUTO_PWRDWN_ENABLE;
                tp->tg3_flags3 |= TG3_FLG3_PHY_IS_FET;
                break;
        }
@@ -1097,7 +1156,6 @@ static void tg3_mdio_fini(struct tg3 *tp)
                tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_INITED;
                mdiobus_unregister(tp->mdio_bus);
                mdiobus_free(tp->mdio_bus);
-               tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_PAUSED;
        }
 }
 
@@ -1280,7 +1338,7 @@ static void tg3_setup_flow_control(struct tg3 *tp, u32 lcladv, u32 rmtadv)
        u32 old_tx_mode = tp->tx_mode;
 
        if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)
-               autoneg = tp->mdio_bus->phy_map[PHY_ADDR]->autoneg;
+               autoneg = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]->autoneg;
        else
                autoneg = tp->link_config.autoneg;
 
@@ -1317,9 +1375,9 @@ static void tg3_adjust_link(struct net_device *dev)
        u8 oldflowctrl, linkmesg = 0;
        u32 mac_mode, lcl_adv, rmt_adv;
        struct tg3 *tp = netdev_priv(dev);
-       struct phy_device *phydev = tp->mdio_bus->phy_map[PHY_ADDR];
+       struct phy_device *phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
 
-       spin_lock(&tp->lock);
+       spin_lock_bh(&tp->lock);
 
        mac_mode = tp->mac_mode & ~(MAC_MODE_PORT_MODE_MASK |
                                    MAC_MODE_HALF_DUPLEX);
@@ -1332,8 +1390,11 @@ static void tg3_adjust_link(struct net_device *dev)
 
                if (phydev->speed == SPEED_100 || phydev->speed == SPEED_10)
                        mac_mode |= MAC_MODE_PORT_MODE_MII;
-               else
+               else if (phydev->speed == SPEED_1000 ||
+                        GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785)
                        mac_mode |= MAC_MODE_PORT_MODE_GMII;
+               else
+                       mac_mode |= MAC_MODE_PORT_MODE_MII;
 
                if (phydev->duplex == DUPLEX_HALF)
                        mac_mode |= MAC_MODE_HALF_DUPLEX;
@@ -1387,7 +1448,7 @@ static void tg3_adjust_link(struct net_device *dev)
        tp->link_config.active_speed = phydev->speed;
        tp->link_config.active_duplex = phydev->duplex;
 
-       spin_unlock(&tp->lock);
+       spin_unlock_bh(&tp->lock);
 
        if (linkmesg)
                tg3_link_report(tp);
@@ -1403,7 +1464,7 @@ static int tg3_phy_init(struct tg3 *tp)
        /* Bring the PHY back to a known state. */
        tg3_bmcr_reset(tp);
 
-       phydev = tp->mdio_bus->phy_map[PHY_ADDR];
+       phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
 
        /* Attach the MAC to the PHY. */
        phydev = phy_connect(tp->dev, dev_name(&phydev->dev), tg3_adjust_link,
@@ -1430,7 +1491,7 @@ static int tg3_phy_init(struct tg3 *tp)
                                      SUPPORTED_Asym_Pause);
                break;
        default:
-               phy_disconnect(tp->mdio_bus->phy_map[PHY_ADDR]);
+               phy_disconnect(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]);
                return -EINVAL;
        }
 
@@ -1448,7 +1509,7 @@ static void tg3_phy_start(struct tg3 *tp)
        if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
                return;
 
-       phydev = tp->mdio_bus->phy_map[PHY_ADDR];
+       phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
 
        if (tp->link_config.phy_is_low_power) {
                tp->link_config.phy_is_low_power = 0;
@@ -1468,13 +1529,13 @@ static void tg3_phy_stop(struct tg3 *tp)
        if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
                return;
 
-       phy_stop(tp->mdio_bus->phy_map[PHY_ADDR]);
+       phy_stop(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]);
 }
 
 static void tg3_phy_fini(struct tg3 *tp)
 {
        if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) {
-               phy_disconnect(tp->mdio_bus->phy_map[PHY_ADDR]);
+               phy_disconnect(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]);
                tp->tg3_flags3 &= ~TG3_FLG3_PHY_CONNECTED;
        }
 }
@@ -1509,7 +1570,9 @@ static void tg3_phy_toggle_apd(struct tg3 *tp, bool enable)
 {
        u32 reg;
 
-       if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+       if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
+               (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 &&
+            (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)))
                return;
 
        if (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) {
@@ -1884,6 +1947,10 @@ static int tg3_phy_reset(struct tg3 *tp)
                }
        }
 
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 &&
+           (tp->tg3_flags2 & TG3_FLG2_MII_SERDES))
+               return 0;
+
        tg3_phy_apply_otp(tp);
 
        if (tp->tg3_flags3 & TG3_FLG3_PHY_ENABLE_APD)
@@ -1964,11 +2031,14 @@ static void tg3_frob_aux_power(struct tg3 *tp)
 {
        struct tg3 *tp_peer = tp;
 
-       if ((tp->tg3_flags2 & TG3_FLG2_IS_NIC) == 0)
+       /* The GPIOs do something completely different on 57765. */
+       if ((tp->tg3_flags2 & TG3_FLG2_IS_NIC) == 0 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
                return;
 
-       if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) ||
-           (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714)) {
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) {
                struct net_device *dev_peer;
 
                dev_peer = pci_get_drvdata(tp->pdev_peer);
@@ -2117,6 +2187,26 @@ static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power)
                tw32_f(GRC_MISC_CFG, val | GRC_MISC_CFG_EPHY_IDDQ);
                udelay(40);
                return;
+       } else if (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) {
+               u32 phytest;
+               if (!tg3_readphy(tp, MII_TG3_FET_TEST, &phytest)) {
+                       u32 phy;
+
+                       tg3_writephy(tp, MII_ADVERTISE, 0);
+                       tg3_writephy(tp, MII_BMCR,
+                                    BMCR_ANENABLE | BMCR_ANRESTART);
+
+                       tg3_writephy(tp, MII_TG3_FET_TEST,
+                                    phytest | MII_TG3_FET_SHADOW_EN);
+                       if (!tg3_readphy(tp, MII_TG3_FET_SHDW_AUXMODE4, &phy)) {
+                               phy |= MII_TG3_FET_SHDW_AUXMODE4_SBPD;
+                               tg3_writephy(tp,
+                                            MII_TG3_FET_SHDW_AUXMODE4,
+                                            phy);
+                       }
+                       tg3_writephy(tp, MII_TG3_FET_TEST, phytest);
+               }
+               return;
        } else if (do_low_power) {
                tg3_writephy(tp, MII_TG3_EXT_CTRL,
                             MII_TG3_EXT_CTRL_FORCE_LED_OFF);
@@ -2186,7 +2276,7 @@ static void tg3_nvram_unlock(struct tg3 *tp)
 static void tg3_enable_nvram_access(struct tg3 *tp)
 {
        if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
-           !(tp->tg3_flags2 & TG3_FLG2_PROTECTED_NVRAM)) {
+           !(tp->tg3_flags3 & TG3_FLG3_PROTECTED_NVRAM)) {
                u32 nvaccess = tr32(NVRAM_ACCESS);
 
                tw32(NVRAM_ACCESS, nvaccess | ACCESS_ENABLE);
@@ -2197,7 +2287,7 @@ static void tg3_enable_nvram_access(struct tg3 *tp)
 static void tg3_disable_nvram_access(struct tg3 *tp)
 {
        if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
-           !(tp->tg3_flags2 & TG3_FLG2_PROTECTED_NVRAM)) {
+           !(tp->tg3_flags3 & TG3_FLG3_PROTECTED_NVRAM)) {
                u32 nvaccess = tr32(NVRAM_ACCESS);
 
                tw32(NVRAM_ACCESS, nvaccess & ~ACCESS_ENABLE);
@@ -2442,7 +2532,7 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
                        struct phy_device *phydev;
                        u32 phyid, advertising;
 
-                       phydev = tp->mdio_bus->phy_map[PHY_ADDR];
+                       phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
 
                        tp->link_config.phy_is_low_power = 1;
 
@@ -3211,15 +3301,6 @@ relink:
                        pci_write_config_word(tp->pdev,
                                              tp->pcie_cap + PCI_EXP_LNKCTL,
                                              newlnkctl);
-       } else if (tp->tg3_flags3 & TG3_FLG3_TOGGLE_10_100_L1PLLPD) {
-               u32 newreg, oldreg = tr32(TG3_PCIE_LNKCTL);
-               if (tp->link_config.active_speed == SPEED_100 ||
-                   tp->link_config.active_speed == SPEED_10)
-                       newreg = oldreg & ~TG3_PCIE_LNKCTL_L1_PLL_PD_EN;
-               else
-                       newreg = oldreg | TG3_PCIE_LNKCTL_L1_PLL_PD_EN;
-               if (newreg != oldreg)
-                       tw32(TG3_PCIE_LNKCTL, newreg);
        }
 
        if (current_link_up != netif_carrier_ok(tp->dev)) {
@@ -4285,9 +4366,16 @@ static void tg3_tx(struct tg3_napi *tnapi)
        struct tg3 *tp = tnapi->tp;
        u32 hw_idx = tnapi->hw_status->idx[0].tx_consumer;
        u32 sw_idx = tnapi->tx_cons;
+       struct netdev_queue *txq;
+       int index = tnapi - tp->napi;
+
+       if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)
+               index--;
+
+       txq = netdev_get_tx_queue(tp->dev, index);
 
        while (sw_idx != hw_idx) {
-               struct tx_ring_info *ri = &tnapi->tx_buffers[sw_idx];
+               struct ring_info *ri = &tnapi->tx_buffers[sw_idx];
                struct sk_buff *skb = ri->skb;
                int i, tx_bug = 0;
 
@@ -4296,7 +4384,10 @@ static void tg3_tx(struct tg3_napi *tnapi)
                        return;
                }
 
-               skb_dma_unmap(&tp->pdev->dev, skb, DMA_TO_DEVICE);
+               pci_unmap_single(tp->pdev,
+                                pci_unmap_addr(ri, mapping),
+                                skb_headlen(skb),
+                                PCI_DMA_TODEVICE);
 
                ri->skb = NULL;
 
@@ -4306,6 +4397,11 @@ static void tg3_tx(struct tg3_napi *tnapi)
                        ri = &tnapi->tx_buffers[sw_idx];
                        if (unlikely(ri->skb != NULL || sw_idx == hw_idx))
                                tx_bug = 1;
+
+                       pci_unmap_page(tp->pdev,
+                                      pci_unmap_addr(ri, mapping),
+                                      skb_shinfo(skb)->frags[i].size,
+                                      PCI_DMA_TODEVICE);
                        sw_idx = NEXT_TX(sw_idx);
                }
 
@@ -4326,16 +4422,27 @@ static void tg3_tx(struct tg3_napi *tnapi)
         */
        smp_mb();
 
-       if (unlikely(netif_queue_stopped(tp->dev) &&
+       if (unlikely(netif_tx_queue_stopped(txq) &&
                     (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi)))) {
-               netif_tx_lock(tp->dev);
-               if (netif_queue_stopped(tp->dev) &&
+               __netif_tx_lock(txq, smp_processor_id());
+               if (netif_tx_queue_stopped(txq) &&
                    (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi)))
-                       netif_wake_queue(tp->dev);
-               netif_tx_unlock(tp->dev);
+                       netif_tx_wake_queue(txq);
+               __netif_tx_unlock(txq);
        }
 }
 
+static void tg3_rx_skb_free(struct tg3 *tp, struct ring_info *ri, u32 map_sz)
+{
+       if (!ri->skb)
+               return;
+
+       pci_unmap_single(tp->pdev, pci_unmap_addr(ri, mapping),
+                        map_sz, PCI_DMA_FROMDEVICE);
+       dev_kfree_skb_any(ri->skb);
+       ri->skb = NULL;
+}
+
 /* Returns size of skb allocated or < 0 on error.
  *
  * We only need to fill in the address because the other members
@@ -4347,16 +4454,14 @@ static void tg3_tx(struct tg3_napi *tnapi)
  * buffers the cpu only reads the last cacheline of the RX descriptor
  * (to fetch the error flags, vlan tag, checksum, and opaque cookie).
  */
-static int tg3_alloc_rx_skb(struct tg3_napi *tnapi, u32 opaque_key,
-                           int src_idx, u32 dest_idx_unmasked)
+static int tg3_alloc_rx_skb(struct tg3 *tp, struct tg3_rx_prodring_set *tpr,
+                           u32 opaque_key, u32 dest_idx_unmasked)
 {
-       struct tg3 *tp = tnapi->tp;
        struct tg3_rx_buffer_desc *desc;
        struct ring_info *map, *src_map;
        struct sk_buff *skb;
        dma_addr_t mapping;
        int skb_size, dest_idx;
-       struct tg3_rx_prodring_set *tpr = &tp->prodring[0];
 
        src_map = NULL;
        switch (opaque_key) {
@@ -4364,8 +4469,6 @@ static int tg3_alloc_rx_skb(struct tg3_napi *tnapi, u32 opaque_key,
                dest_idx = dest_idx_unmasked % TG3_RX_RING_SIZE;
                desc = &tpr->rx_std[dest_idx];
                map = &tpr->rx_std_buffers[dest_idx];
-               if (src_idx >= 0)
-                       src_map = &tpr->rx_std_buffers[src_idx];
                skb_size = tp->rx_pkt_map_sz;
                break;
 
@@ -4373,8 +4476,6 @@ static int tg3_alloc_rx_skb(struct tg3_napi *tnapi, u32 opaque_key,
                dest_idx = dest_idx_unmasked % TG3_RX_JUMBO_RING_SIZE;
                desc = &tpr->rx_jmb[dest_idx].std;
                map = &tpr->rx_jmb_buffers[dest_idx];
-               if (src_idx >= 0)
-                       src_map = &tpr->rx_jmb_buffers[src_idx];
                skb_size = TG3_RX_JMB_MAP_SZ;
                break;
 
@@ -4396,13 +4497,14 @@ static int tg3_alloc_rx_skb(struct tg3_napi *tnapi, u32 opaque_key,
 
        mapping = pci_map_single(tp->pdev, skb->data, skb_size,
                                 PCI_DMA_FROMDEVICE);
+       if (pci_dma_mapping_error(tp->pdev, mapping)) {
+               dev_kfree_skb(skb);
+               return -EIO;
+       }
 
        map->skb = skb;
        pci_unmap_addr_set(map, mapping, mapping);
 
-       if (src_map != NULL)
-               src_map->skb = NULL;
-
        desc->addr_hi = ((u64)mapping >> 32);
        desc->addr_lo = ((u64)mapping & 0xffffffff);
 
@@ -4413,30 +4515,32 @@ static int tg3_alloc_rx_skb(struct tg3_napi *tnapi, u32 opaque_key,
  * members of the RX descriptor are invariant.  See notes above
  * tg3_alloc_rx_skb for full details.
  */
-static void tg3_recycle_rx(struct tg3_napi *tnapi, u32 opaque_key,
-                          int src_idx, u32 dest_idx_unmasked)
+static void tg3_recycle_rx(struct tg3_napi *tnapi,
+                          struct tg3_rx_prodring_set *dpr,
+                          u32 opaque_key, int src_idx,
+                          u32 dest_idx_unmasked)
 {
        struct tg3 *tp = tnapi->tp;
        struct tg3_rx_buffer_desc *src_desc, *dest_desc;
        struct ring_info *src_map, *dest_map;
        int dest_idx;
-       struct tg3_rx_prodring_set *tpr = &tp->prodring[0];
+       struct tg3_rx_prodring_set *spr = &tp->prodring[0];
 
        switch (opaque_key) {
        case RXD_OPAQUE_RING_STD:
                dest_idx = dest_idx_unmasked % TG3_RX_RING_SIZE;
-               dest_desc = &tpr->rx_std[dest_idx];
-               dest_map = &tpr->rx_std_buffers[dest_idx];
-               src_desc = &tpr->rx_std[src_idx];
-               src_map = &tpr->rx_std_buffers[src_idx];
+               dest_desc = &dpr->rx_std[dest_idx];
+               dest_map = &dpr->rx_std_buffers[dest_idx];
+               src_desc = &spr->rx_std[src_idx];
+               src_map = &spr->rx_std_buffers[src_idx];
                break;
 
        case RXD_OPAQUE_RING_JUMBO:
                dest_idx = dest_idx_unmasked % TG3_RX_JUMBO_RING_SIZE;
-               dest_desc = &tpr->rx_jmb[dest_idx].std;
-               dest_map = &tpr->rx_jmb_buffers[dest_idx];
-               src_desc = &tpr->rx_jmb[src_idx].std;
-               src_map = &tpr->rx_jmb_buffers[src_idx];
+               dest_desc = &dpr->rx_jmb[dest_idx].std;
+               dest_map = &dpr->rx_jmb_buffers[dest_idx];
+               src_desc = &spr->rx_jmb[src_idx].std;
+               src_map = &spr->rx_jmb_buffers[src_idx];
                break;
 
        default:
@@ -4448,7 +4552,6 @@ static void tg3_recycle_rx(struct tg3_napi *tnapi, u32 opaque_key,
                           pci_unmap_addr(src_map, mapping));
        dest_desc->addr_hi = src_desc->addr_hi;
        dest_desc->addr_lo = src_desc->addr_lo;
-
        src_map->skb = NULL;
 }
 
@@ -4480,12 +4583,13 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
 {
        struct tg3 *tp = tnapi->tp;
        u32 work_mask, rx_std_posted = 0;
+       u32 std_prod_idx, jmb_prod_idx;
        u32 sw_idx = tnapi->rx_rcb_ptr;
        u16 hw_idx;
        int received;
-       struct tg3_rx_prodring_set *tpr = &tp->prodring[0];
+       struct tg3_rx_prodring_set *tpr = tnapi->prodring;
 
-       hw_idx = tnapi->hw_status->idx[0].rx_producer;
+       hw_idx = *(tnapi->rx_rcb_prod_idx);
        /*
         * We need to order the read of hw_idx and the read of
         * the opaque cookie.
@@ -4493,7 +4597,10 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
        rmb();
        work_mask = 0;
        received = 0;
+       std_prod_idx = tpr->rx_std_prod_idx;
+       jmb_prod_idx = tpr->rx_jmb_prod_idx;
        while (sw_idx != hw_idx && budget > 0) {
+               struct ring_info *ri;
                struct tg3_rx_buffer_desc *desc = &tnapi->rx_rcb[sw_idx];
                unsigned int len;
                struct sk_buff *skb;
@@ -4503,16 +4610,16 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
                desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK;
                opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK;
                if (opaque_key == RXD_OPAQUE_RING_STD) {
-                       struct ring_info *ri = &tpr->rx_std_buffers[desc_idx];
+                       ri = &tp->prodring[0].rx_std_buffers[desc_idx];
                        dma_addr = pci_unmap_addr(ri, mapping);
                        skb = ri->skb;
-                       post_ptr = &tpr->rx_std_ptr;
+                       post_ptr = &std_prod_idx;
                        rx_std_posted++;
                } else if (opaque_key == RXD_OPAQUE_RING_JUMBO) {
-                       struct ring_info *ri = &tpr->rx_jmb_buffers[desc_idx];
+                       ri = &tp->prodring[0].rx_jmb_buffers[desc_idx];
                        dma_addr = pci_unmap_addr(ri, mapping);
                        skb = ri->skb;
-                       post_ptr = &tpr->rx_jmb_ptr;
+                       post_ptr = &jmb_prod_idx;
                } else
                        goto next_pkt_nopost;
 
@@ -4521,7 +4628,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
                if ((desc->err_vlan & RXD_ERR_MASK) != 0 &&
                    (desc->err_vlan != RXD_ERR_ODD_NIBBLE_RCVD_MII)) {
                drop_it:
-                       tg3_recycle_rx(tnapi, opaque_key,
+                       tg3_recycle_rx(tnapi, tpr, opaque_key,
                                       desc_idx, *post_ptr);
                drop_it_no_recycle:
                        /* Other statistics kept track of by card. */
@@ -4532,20 +4639,21 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
                len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) -
                      ETH_FCS_LEN;
 
-               if (len > RX_COPY_THRESHOLD
-                       && tp->rx_offset == NET_IP_ALIGN
-                       /* rx_offset will likely not equal NET_IP_ALIGN
-                        * if this is a 5701 card running in PCI-X mode
-                        * [see tg3_get_invariants()]
-                        */
-               ) {
+               if (len > RX_COPY_THRESHOLD &&
+                   tp->rx_offset == NET_IP_ALIGN) {
+                   /* rx_offset will likely not equal NET_IP_ALIGN
+                    * if this is a 5701 card running in PCI-X mode
+                    * [see tg3_get_invariants()]
+                    */
                        int skb_size;
 
-                       skb_size = tg3_alloc_rx_skb(tnapi, opaque_key,
-                                                   desc_idx, *post_ptr);
+                       skb_size = tg3_alloc_rx_skb(tp, tpr, opaque_key,
+                                                   *post_ptr);
                        if (skb_size < 0)
                                goto drop_it;
 
+                       ri->skb = NULL;
+
                        pci_unmap_single(tp->pdev, dma_addr, skb_size,
                                         PCI_DMA_FROMDEVICE);
 
@@ -4553,7 +4661,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
                } else {
                        struct sk_buff *copy_skb;
 
-                       tg3_recycle_rx(tnapi, opaque_key,
+                       tg3_recycle_rx(tnapi, tpr, opaque_key,
                                       desc_idx, *post_ptr);
 
                        copy_skb = netdev_alloc_skb(tp->dev,
@@ -4603,10 +4711,9 @@ next_pkt:
                (*post_ptr)++;
 
                if (unlikely(rx_std_posted >= tp->rx_std_max_post)) {
-                       u32 idx = *post_ptr % TG3_RX_RING_SIZE;
-
-                       tw32_rx_mbox(MAILBOX_RCV_STD_PROD_IDX +
-                                    TG3_64BIT_REG_LOW, idx);
+                       tpr->rx_std_prod_idx = std_prod_idx % TG3_RX_RING_SIZE;
+                       tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG,
+                                    tpr->rx_std_prod_idx);
                        work_mask &= ~RXD_OPAQUE_RING_STD;
                        rx_std_posted = 0;
                }
@@ -4616,7 +4723,7 @@ next_pkt_nopost:
 
                /* Refresh hw_idx to see if there is new work */
                if (sw_idx == hw_idx) {
-                       hw_idx = tnapi->hw_status->idx[0].rx_producer;
+                       hw_idx = *(tnapi->rx_rcb_prod_idx);
                        rmb();
                }
        }
@@ -4626,33 +4733,45 @@ next_pkt_nopost:
        tw32_rx_mbox(tnapi->consmbox, sw_idx);
 
        /* Refill RX ring(s). */
-       if (work_mask & RXD_OPAQUE_RING_STD) {
-               sw_idx = tpr->rx_std_ptr % TG3_RX_RING_SIZE;
-               tw32_rx_mbox(MAILBOX_RCV_STD_PROD_IDX + TG3_64BIT_REG_LOW,
-                            sw_idx);
-       }
-       if (work_mask & RXD_OPAQUE_RING_JUMBO) {
-               sw_idx = tpr->rx_jmb_ptr % TG3_RX_JUMBO_RING_SIZE;
-               tw32_rx_mbox(MAILBOX_RCV_JUMBO_PROD_IDX + TG3_64BIT_REG_LOW,
-                            sw_idx);
+       if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS) || tnapi == &tp->napi[1]) {
+               if (work_mask & RXD_OPAQUE_RING_STD) {
+                       tpr->rx_std_prod_idx = std_prod_idx % TG3_RX_RING_SIZE;
+                       tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG,
+                                    tpr->rx_std_prod_idx);
+               }
+               if (work_mask & RXD_OPAQUE_RING_JUMBO) {
+                       tpr->rx_jmb_prod_idx = jmb_prod_idx %
+                                              TG3_RX_JUMBO_RING_SIZE;
+                       tw32_rx_mbox(TG3_RX_JMB_PROD_IDX_REG,
+                                    tpr->rx_jmb_prod_idx);
+               }
+               mmiowb();
+       } else if (work_mask) {
+               /* rx_std_buffers[] and rx_jmb_buffers[] entries must be
+                * updated before the producer indices can be updated.
+                */
+               smp_wmb();
+
+               tpr->rx_std_prod_idx = std_prod_idx % TG3_RX_RING_SIZE;
+               tpr->rx_jmb_prod_idx = jmb_prod_idx % TG3_RX_JUMBO_RING_SIZE;
+
+               napi_schedule(&tp->napi[1].napi);
        }
-       mmiowb();
 
        return received;
 }
 
-static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
+static void tg3_poll_link(struct tg3 *tp)
 {
-       struct tg3 *tp = tnapi->tp;
-       struct tg3_hw_status *sblk = tnapi->hw_status;
-
        /* handle link change and other phy events */
        if (!(tp->tg3_flags &
              (TG3_FLAG_USE_LINKCHG_REG |
               TG3_FLAG_POLL_SERDES))) {
+               struct tg3_hw_status *sblk = tp->napi[0].hw_status;
+
                if (sblk->status & SD_STATUS_LINK_CHG) {
                        sblk->status = SD_STATUS_UPDATED |
-                               (sblk->status & ~SD_STATUS_LINK_CHG);
+                                      (sblk->status & ~SD_STATUS_LINK_CHG);
                        spin_lock(&tp->lock);
                        if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
                                tw32_f(MAC_STATUS,
@@ -4666,6 +4785,98 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
                        spin_unlock(&tp->lock);
                }
        }
+}
+
+static void tg3_rx_prodring_xfer(struct tg3 *tp,
+                                struct tg3_rx_prodring_set *dpr,
+                                struct tg3_rx_prodring_set *spr)
+{
+       u32 si, di, cpycnt, src_prod_idx;
+       int i;
+
+       while (1) {
+               src_prod_idx = spr->rx_std_prod_idx;
+
+               /* Make sure updates to the rx_std_buffers[] entries and the
+                * standard producer index are seen in the correct order.
+                */
+               smp_rmb();
+
+               if (spr->rx_std_cons_idx == src_prod_idx)
+                       break;
+
+               if (spr->rx_std_cons_idx < src_prod_idx)
+                       cpycnt = src_prod_idx - spr->rx_std_cons_idx;
+               else
+                       cpycnt = TG3_RX_RING_SIZE - spr->rx_std_cons_idx;
+
+               cpycnt = min(cpycnt, TG3_RX_RING_SIZE - dpr->rx_std_prod_idx);
+
+               si = spr->rx_std_cons_idx;
+               di = dpr->rx_std_prod_idx;
+
+               memcpy(&dpr->rx_std_buffers[di],
+                      &spr->rx_std_buffers[si],
+                      cpycnt * sizeof(struct ring_info));
+
+               for (i = 0; i < cpycnt; i++, di++, si++) {
+                       struct tg3_rx_buffer_desc *sbd, *dbd;
+                       sbd = &spr->rx_std[si];
+                       dbd = &dpr->rx_std[di];
+                       dbd->addr_hi = sbd->addr_hi;
+                       dbd->addr_lo = sbd->addr_lo;
+               }
+
+               spr->rx_std_cons_idx = (spr->rx_std_cons_idx + cpycnt) %
+                                      TG3_RX_RING_SIZE;
+               dpr->rx_std_prod_idx = (dpr->rx_std_prod_idx + cpycnt) %
+                                      TG3_RX_RING_SIZE;
+       }
+
+       while (1) {
+               src_prod_idx = spr->rx_jmb_prod_idx;
+
+               /* Make sure updates to the rx_jmb_buffers[] entries and
+                * the jumbo producer index are seen in the correct order.
+                */
+               smp_rmb();
+
+               if (spr->rx_jmb_cons_idx == src_prod_idx)
+                       break;
+
+               if (spr->rx_jmb_cons_idx < src_prod_idx)
+                       cpycnt = src_prod_idx - spr->rx_jmb_cons_idx;
+               else
+                       cpycnt = TG3_RX_JUMBO_RING_SIZE - spr->rx_jmb_cons_idx;
+
+               cpycnt = min(cpycnt,
+                            TG3_RX_JUMBO_RING_SIZE - dpr->rx_jmb_prod_idx);
+
+               si = spr->rx_jmb_cons_idx;
+               di = dpr->rx_jmb_prod_idx;
+
+               memcpy(&dpr->rx_jmb_buffers[di],
+                      &spr->rx_jmb_buffers[si],
+                      cpycnt * sizeof(struct ring_info));
+
+               for (i = 0; i < cpycnt; i++, di++, si++) {
+                       struct tg3_rx_buffer_desc *sbd, *dbd;
+                       sbd = &spr->rx_jmb[si].std;
+                       dbd = &dpr->rx_jmb[di].std;
+                       dbd->addr_hi = sbd->addr_hi;
+                       dbd->addr_lo = sbd->addr_lo;
+               }
+
+               spr->rx_jmb_cons_idx = (spr->rx_jmb_cons_idx + cpycnt) %
+                                      TG3_RX_JUMBO_RING_SIZE;
+               dpr->rx_jmb_prod_idx = (dpr->rx_jmb_prod_idx + cpycnt) %
+                                      TG3_RX_JUMBO_RING_SIZE;
+       }
+}
+
+static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
+{
+       struct tg3 *tp = tnapi->tp;
 
        /* run TX completion thread */
        if (tnapi->hw_status->idx[0].tx_consumer != tnapi->tx_cons) {
@@ -4678,9 +4889,77 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
         * All RX "locking" is done by ensuring outside
         * code synchronizes with tg3->napi.poll()
         */
-       if (sblk->idx[0].rx_producer != tnapi->rx_rcb_ptr)
+       if (*(tnapi->rx_rcb_prod_idx) != tnapi->rx_rcb_ptr)
                work_done += tg3_rx(tnapi, budget - work_done);
 
+       if ((tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS) && tnapi == &tp->napi[1]) {
+               int i;
+               u32 std_prod_idx = tp->prodring[0].rx_std_prod_idx;
+               u32 jmb_prod_idx = tp->prodring[0].rx_jmb_prod_idx;
+
+               for (i = 2; i < tp->irq_cnt; i++)
+                       tg3_rx_prodring_xfer(tp, tnapi->prodring,
+                                            tp->napi[i].prodring);
+
+               wmb();
+
+               if (std_prod_idx != tp->prodring[0].rx_std_prod_idx) {
+                       u32 mbox = TG3_RX_STD_PROD_IDX_REG;
+                       tw32_rx_mbox(mbox, tp->prodring[0].rx_std_prod_idx);
+               }
+
+               if (jmb_prod_idx != tp->prodring[0].rx_jmb_prod_idx) {
+                       u32 mbox = TG3_RX_JMB_PROD_IDX_REG;
+                       tw32_rx_mbox(mbox, tp->prodring[0].rx_jmb_prod_idx);
+               }
+
+               mmiowb();
+       }
+
+       return work_done;
+}
+
+static int tg3_poll_msix(struct napi_struct *napi, int budget)
+{
+       struct tg3_napi *tnapi = container_of(napi, struct tg3_napi, napi);
+       struct tg3 *tp = tnapi->tp;
+       int work_done = 0;
+       struct tg3_hw_status *sblk = tnapi->hw_status;
+
+       while (1) {
+               work_done = tg3_poll_work(tnapi, work_done, budget);
+
+               if (unlikely(tp->tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING))
+                       goto tx_recovery;
+
+               if (unlikely(work_done >= budget))
+                       break;
+
+               /* tp->last_tag is used in tg3_restart_ints() below
+                * to tell the hw how much work has been processed,
+                * so we must read it before checking for more work.
+                */
+               tnapi->last_tag = sblk->status_tag;
+               tnapi->last_irq_tag = tnapi->last_tag;
+               rmb();
+
+               /* check for RX/TX work to do */
+               if (sblk->idx[0].tx_consumer == tnapi->tx_cons &&
+                   *(tnapi->rx_rcb_prod_idx) == tnapi->rx_rcb_ptr) {
+                       napi_complete(napi);
+                       /* Reenable interrupts. */
+                       tw32_mailbox(tnapi->int_mbox, tnapi->last_tag << 24);
+                       mmiowb();
+                       break;
+               }
+       }
+
+       return work_done;
+
+tx_recovery:
+       /* work_done is guaranteed to be less than budget. */
+       napi_complete(napi);
+       schedule_work(&tp->reset_task);
        return work_done;
 }
 
@@ -4692,6 +4971,8 @@ static int tg3_poll(struct napi_struct *napi, int budget)
        struct tg3_hw_status *sblk = tnapi->hw_status;
 
        while (1) {
+               tg3_poll_link(tp);
+
                work_done = tg3_poll_work(tnapi, work_done, budget);
 
                if (unlikely(tp->tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING))
@@ -4729,12 +5010,15 @@ tx_recovery:
 
 static void tg3_irq_quiesce(struct tg3 *tp)
 {
+       int i;
+
        BUG_ON(tp->irq_sync);
 
        tp->irq_sync = 1;
        smp_mb();
 
-       synchronize_irq(tp->pdev->irq);
+       for (i = 0; i < tp->irq_cnt; i++)
+               synchronize_irq(tp->napi[i].irq_vec);
 }
 
 static inline int tg3_irq_sync(struct tg3 *tp)
@@ -4768,7 +5052,8 @@ static irqreturn_t tg3_msi_1shot(int irq, void *dev_id)
        struct tg3 *tp = tnapi->tp;
 
        prefetch(tnapi->hw_status);
-       prefetch(&tnapi->rx_rcb[tnapi->rx_rcb_ptr]);
+       if (tnapi->rx_rcb)
+               prefetch(&tnapi->rx_rcb[tnapi->rx_rcb_ptr]);
 
        if (likely(!tg3_irq_sync(tp)))
                napi_schedule(&tnapi->napi);
@@ -4786,7 +5071,8 @@ static irqreturn_t tg3_msi(int irq, void *dev_id)
        struct tg3 *tp = tnapi->tp;
 
        prefetch(tnapi->hw_status);
-       prefetch(&tnapi->rx_rcb[tnapi->rx_rcb_ptr]);
+       if (tnapi->rx_rcb)
+               prefetch(&tnapi->rx_rcb[tnapi->rx_rcb_ptr]);
        /*
         * Writing any value to intr-mbox-0 clears PCI INTA# and
         * chip-internal interrupt pending events.
@@ -4937,7 +5223,7 @@ static int tg3_restart_hw(struct tg3 *tp, int reset_phy)
                tg3_full_unlock(tp);
                del_timer_sync(&tp->timer);
                tp->irq_sync = 0;
-               napi_enable(&tp->napi[0].napi);
+               tg3_napi_enable(tp);
                dev_close(tp->dev);
                tg3_full_lock(tp, 0);
        }
@@ -4947,9 +5233,11 @@ static int tg3_restart_hw(struct tg3 *tp, int reset_phy)
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void tg3_poll_controller(struct net_device *dev)
 {
+       int i;
        struct tg3 *tp = netdev_priv(dev);
 
-       tg3_interrupt(tp->pdev->irq, dev);
+       for (i = 0; i < tp->irq_cnt; i++)
+               tg3_interrupt(tp->napi[i].irq_vec, dev);
 }
 #endif
 
@@ -5047,11 +5335,11 @@ static inline int tg3_40bit_overflow_test(struct tg3 *tp, dma_addr_t mapping,
 static void tg3_set_txd(struct tg3_napi *, int, dma_addr_t, int, u32, u32);
 
 /* Workaround 4GB and 40-bit hardware DMA bugs. */
-static int tigon3_dma_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb,
-                                      u32 last_plus_one, u32 *start,
-                                      u32 base_flags, u32 mss)
+static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi,
+                                      struct sk_buff *skb, u32 last_plus_one,
+                                      u32 *start, u32 base_flags, u32 mss)
 {
-       struct tg3_napi *tnapi = &tp->napi[0];
+       struct tg3 *tp = tnapi->tp;
        struct sk_buff *new_skb;
        dma_addr_t new_addr = 0;
        u32 entry = *start;
@@ -5072,16 +5360,21 @@ static int tigon3_dma_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb,
        } else {
                /* New SKB is guaranteed to be linear. */
                entry = *start;
-               ret = skb_dma_map(&tp->pdev->dev, new_skb, DMA_TO_DEVICE);
-               new_addr = skb_shinfo(new_skb)->dma_head;
+               new_addr = pci_map_single(tp->pdev, new_skb->data, new_skb->len,
+                                         PCI_DMA_TODEVICE);
+               /* Make sure the mapping succeeded */
+               if (pci_dma_mapping_error(tp->pdev, new_addr)) {
+                       ret = -1;
+                       dev_kfree_skb(new_skb);
+                       new_skb = NULL;
 
                /* Make sure new skb does not cross any 4G boundaries.
                 * Drop the packet if it does.
                 */
-               if (ret || tg3_4g_overflow_test(new_addr, new_skb->len)) {
-                       if (!ret)
-                               skb_dma_unmap(&tp->pdev->dev, new_skb,
-                                             DMA_TO_DEVICE);
+               } else if ((tp->tg3_flags3 & TG3_FLG3_4G_DMA_BNDRY_BUG) &&
+                           tg3_4g_overflow_test(new_addr, new_skb->len)) {
+                       pci_unmap_single(tp->pdev, new_addr, new_skb->len,
+                                        PCI_DMA_TODEVICE);
                        ret = -1;
                        dev_kfree_skb(new_skb);
                        new_skb = NULL;
@@ -5095,15 +5388,28 @@ static int tigon3_dma_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb,
        /* Now clean up the sw ring entries. */
        i = 0;
        while (entry != last_plus_one) {
+               int len;
+
                if (i == 0)
-                       tnapi->tx_buffers[entry].skb = new_skb;
+                       len = skb_headlen(skb);
                else
+                       len = skb_shinfo(skb)->frags[i-1].size;
+
+               pci_unmap_single(tp->pdev,
+                                pci_unmap_addr(&tnapi->tx_buffers[entry],
+                                               mapping),
+                                len, PCI_DMA_TODEVICE);
+               if (i == 0) {
+                       tnapi->tx_buffers[entry].skb = new_skb;
+                       pci_unmap_addr_set(&tnapi->tx_buffers[entry], mapping,
+                                          new_addr);
+               } else {
                        tnapi->tx_buffers[entry].skb = NULL;
+               }
                entry = NEXT_TX(entry);
                i++;
        }
 
-       skb_dma_unmap(&tp->pdev->dev, skb, DMA_TO_DEVICE);
        dev_kfree_skb(skb);
 
        return ret;
@@ -5133,18 +5439,23 @@ static void tg3_set_txd(struct tg3_napi *tnapi, int entry,
 }
 
 /* hard_start_xmit for devices that don't have any bugs and
- * support TG3_FLG2_HW_TSO_2 only.
+ * support TG3_FLG2_HW_TSO_2 and TG3_FLG2_HW_TSO_3 only.
  */
 static netdev_tx_t tg3_start_xmit(struct sk_buff *skb,
                                  struct net_device *dev)
 {
        struct tg3 *tp = netdev_priv(dev);
        u32 len, entry, base_flags, mss;
-       struct skb_shared_info *sp;
        dma_addr_t mapping;
-       struct tg3_napi *tnapi = &tp->napi[0];
+       struct tg3_napi *tnapi;
+       struct netdev_queue *txq;
+       unsigned int i, last;
 
-       len = skb_headlen(skb);
+
+       txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb));
+       tnapi = &tp->napi[skb_get_queue_mapping(skb)];
+       if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)
+               tnapi++;
 
        /* We are running in BH disabled context with netif_tx_lock
         * and TX reclaim runs via tp->napi.poll inside of a software
@@ -5152,8 +5463,8 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb,
         * no IRQ context deadlocks to worry about either.  Rejoice!
         */
        if (unlikely(tg3_tx_avail(tnapi) <= (skb_shinfo(skb)->nr_frags + 1))) {
-               if (!netif_queue_stopped(dev)) {
-                       netif_stop_queue(dev);
+               if (!netif_tx_queue_stopped(txq)) {
+                       netif_tx_stop_queue(txq);
 
                        /* This is a hard error, log it. */
                        printk(KERN_ERR PFX "%s: BUG! Tx Ring full when "
@@ -5167,6 +5478,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb,
        mss = 0;
        if ((mss = skb_shinfo(skb)->gso_size) != 0) {
                int tcp_opt_len, ip_tcp_len;
+               u32 hdrlen;
 
                if (skb_header_cloned(skb) &&
                    pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) {
@@ -5175,7 +5487,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb,
                }
 
                if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
-                       mss |= (skb_headlen(skb) - ETH_HLEN) << 9;
+                       hdrlen = skb_headlen(skb) - ETH_HLEN;
                else {
                        struct iphdr *iph = ip_hdr(skb);
 
@@ -5184,9 +5496,17 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb,
 
                        iph->check = 0;
                        iph->tot_len = htons(mss + ip_tcp_len + tcp_opt_len);
-                       mss |= (ip_tcp_len + tcp_opt_len) << 9;
+                       hdrlen = ip_tcp_len + tcp_opt_len;
                }
 
+               if (tp->tg3_flags2 & TG3_FLG2_HW_TSO_3) {
+                       mss |= (hdrlen & 0xc) << 12;
+                       if (hdrlen & 0x10)
+                               base_flags |= 0x00000010;
+                       base_flags |= (hdrlen & 0x3e0) << 5;
+               } else
+                       mss |= hdrlen << 9;
+
                base_flags |= (TXD_FLAG_CPU_PRE_DMA |
                               TXD_FLAG_CPU_POST_DMA);
 
@@ -5201,16 +5521,21 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb,
                               (vlan_tx_tag_get(skb) << 16));
 #endif
 
-       if (skb_dma_map(&tp->pdev->dev, skb, DMA_TO_DEVICE)) {
+       len = skb_headlen(skb);
+
+       /* Queue skb data, a.k.a. the main skb fragment. */
+       mapping = pci_map_single(tp->pdev, skb->data, len, PCI_DMA_TODEVICE);
+       if (pci_dma_mapping_error(tp->pdev, mapping)) {
                dev_kfree_skb(skb);
                goto out_unlock;
        }
 
-       sp = skb_shinfo(skb);
-
-       mapping = sp->dma_head;
-
        tnapi->tx_buffers[entry].skb = skb;
+       pci_unmap_addr_set(&tnapi->tx_buffers[entry], mapping, mapping);
+
+       if ((tp->tg3_flags3 & TG3_FLG3_USE_JUMBO_BDFLAG) &&
+           !mss && skb->len > ETH_DATA_LEN)
+               base_flags |= TXD_FLAG_JMB_PKT;
 
        tg3_set_txd(tnapi, entry, mapping, len, base_flags,
                    (skb_shinfo(skb)->nr_frags == 0) | (mss << 1));
@@ -5219,15 +5544,21 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb,
 
        /* Now loop through additional data fragments, and queue them. */
        if (skb_shinfo(skb)->nr_frags > 0) {
-               unsigned int i, last;
-
                last = skb_shinfo(skb)->nr_frags - 1;
                for (i = 0; i <= last; i++) {
                        skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
                        len = frag->size;
-                       mapping = sp->dma_maps[i];
+                       mapping = pci_map_page(tp->pdev,
+                                              frag->page,
+                                              frag->page_offset,
+                                              len, PCI_DMA_TODEVICE);
+                       if (pci_dma_mapping_error(tp->pdev, mapping))
+                               goto dma_error;
+
                        tnapi->tx_buffers[entry].skb = NULL;
+                       pci_unmap_addr_set(&tnapi->tx_buffers[entry], mapping,
+                                          mapping);
 
                        tg3_set_txd(tnapi, entry, mapping, len,
                                    base_flags, (i == last) | (mss << 1));
@@ -5241,15 +5572,36 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb,
 
        tnapi->tx_prod = entry;
        if (unlikely(tg3_tx_avail(tnapi) <= (MAX_SKB_FRAGS + 1))) {
-               netif_stop_queue(dev);
+               netif_tx_stop_queue(txq);
                if (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi))
-                       netif_wake_queue(tp->dev);
+                       netif_tx_wake_queue(txq);
        }
 
 out_unlock:
        mmiowb();
 
        return NETDEV_TX_OK;
+
+dma_error:
+       last = i;
+       entry = tnapi->tx_prod;
+       tnapi->tx_buffers[entry].skb = NULL;
+       pci_unmap_single(tp->pdev,
+                        pci_unmap_addr(&tnapi->tx_buffers[entry], mapping),
+                        skb_headlen(skb),
+                        PCI_DMA_TODEVICE);
+       for (i = 0; i <= last; i++) {
+               skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+               entry = NEXT_TX(entry);
+
+               pci_unmap_page(tp->pdev,
+                              pci_unmap_addr(&tnapi->tx_buffers[entry],
+                                             mapping),
+                              frag->size, PCI_DMA_TODEVICE);
+       }
+
+       dev_kfree_skb(skb);
+       return NETDEV_TX_OK;
 }
 
 static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *,
@@ -5297,12 +5649,17 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
 {
        struct tg3 *tp = netdev_priv(dev);
        u32 len, entry, base_flags, mss;
-       struct skb_shared_info *sp;
        int would_hit_hwbug;
        dma_addr_t mapping;
-       struct tg3_napi *tnapi = &tp->napi[0];
+       struct tg3_napi *tnapi;
+       struct netdev_queue *txq;
+       unsigned int i, last;
 
-       len = skb_headlen(skb);
+
+       txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb));
+       tnapi = &tp->napi[skb_get_queue_mapping(skb)];
+       if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)
+               tnapi++;
 
        /* We are running in BH disabled context with netif_tx_lock
         * and TX reclaim runs via tp->napi.poll inside of a software
@@ -5310,8 +5667,8 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
         * no IRQ context deadlocks to worry about either.  Rejoice!
         */
        if (unlikely(tg3_tx_avail(tnapi) <= (skb_shinfo(skb)->nr_frags + 1))) {
-               if (!netif_queue_stopped(dev)) {
-                       netif_stop_queue(dev);
+               if (!netif_tx_queue_stopped(txq)) {
+                       netif_tx_stop_queue(txq);
 
                        /* This is a hard error, log it. */
                        printk(KERN_ERR PFX "%s: BUG! Tx Ring full when "
@@ -5324,10 +5681,10 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
        base_flags = 0;
        if (skb->ip_summed == CHECKSUM_PARTIAL)
                base_flags |= TXD_FLAG_TCPUDP_CSUM;
-       mss = 0;
+
        if ((mss = skb_shinfo(skb)->gso_size) != 0) {
                struct iphdr *iph;
-               int tcp_opt_len, ip_tcp_len, hdr_len;
+               u32 tcp_opt_len, ip_tcp_len, hdr_len;
 
                if (skb_header_cloned(skb) &&
                    pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) {
@@ -5358,8 +5715,15 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
                                                                 IPPROTO_TCP,
                                                                 0);
 
-               if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO) ||
-                   (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)) {
+               if (tp->tg3_flags2 & TG3_FLG2_HW_TSO_3) {
+                       mss |= (hdr_len & 0xc) << 12;
+                       if (hdr_len & 0x10)
+                               base_flags |= 0x00000010;
+                       base_flags |= (hdr_len & 0x3e0) << 5;
+               } else if (tp->tg3_flags2 & TG3_FLG2_HW_TSO_2)
+                       mss |= hdr_len << 9;
+               else if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_1) ||
+                        GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
                        if (tcp_opt_len || iph->ihl > 5) {
                                int tsflags;
 
@@ -5381,22 +5745,35 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
                               (vlan_tx_tag_get(skb) << 16));
 #endif
 
-       if (skb_dma_map(&tp->pdev->dev, skb, DMA_TO_DEVICE)) {
+       if ((tp->tg3_flags3 & TG3_FLG3_USE_JUMBO_BDFLAG) &&
+           !mss && skb->len > ETH_DATA_LEN)
+               base_flags |= TXD_FLAG_JMB_PKT;
+
+       len = skb_headlen(skb);
+
+       mapping = pci_map_single(tp->pdev, skb->data, len, PCI_DMA_TODEVICE);
+       if (pci_dma_mapping_error(tp->pdev, mapping)) {
                dev_kfree_skb(skb);
                goto out_unlock;
        }
 
-       sp = skb_shinfo(skb);
-
-       mapping = sp->dma_head;
-
        tnapi->tx_buffers[entry].skb = skb;
+       pci_unmap_addr_set(&tnapi->tx_buffers[entry], mapping, mapping);
 
        would_hit_hwbug = 0;
 
-       if (tp->tg3_flags3 & TG3_FLG3_5701_DMA_BUG)
+       if ((tp->tg3_flags3 & TG3_FLG3_SHORT_DMA_BUG) && len <= 8)
                would_hit_hwbug = 1;
-       else if (tg3_4g_overflow_test(mapping, len))
+
+       if ((tp->tg3_flags3 & TG3_FLG3_4G_DMA_BNDRY_BUG) &&
+           tg3_4g_overflow_test(mapping, len))
+               would_hit_hwbug = 1;
+
+       if ((tp->tg3_flags3 & TG3_FLG3_40BIT_DMA_LIMIT_BUG) &&
+           tg3_40bit_overflow_test(tp, mapping, len))
+               would_hit_hwbug = 1;
+
+       if (tp->tg3_flags3 & TG3_FLG3_5701_DMA_BUG)
                would_hit_hwbug = 1;
 
        tg3_set_txd(tnapi, entry, mapping, len, base_flags,
@@ -5406,21 +5783,32 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
 
        /* Now loop through additional data fragments, and queue them. */
        if (skb_shinfo(skb)->nr_frags > 0) {
-               unsigned int i, last;
-
                last = skb_shinfo(skb)->nr_frags - 1;
                for (i = 0; i <= last; i++) {
                        skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
                        len = frag->size;
-                       mapping = sp->dma_maps[i];
+                       mapping = pci_map_page(tp->pdev,
+                                              frag->page,
+                                              frag->page_offset,
+                                              len, PCI_DMA_TODEVICE);
 
                        tnapi->tx_buffers[entry].skb = NULL;
+                       pci_unmap_addr_set(&tnapi->tx_buffers[entry], mapping,
+                                          mapping);
+                       if (pci_dma_mapping_error(tp->pdev, mapping))
+                               goto dma_error;
 
-                       if (tg3_4g_overflow_test(mapping, len))
+                       if ((tp->tg3_flags3 & TG3_FLG3_SHORT_DMA_BUG) &&
+                           len <= 8)
                                would_hit_hwbug = 1;
 
-                       if (tg3_40bit_overflow_test(tp, mapping, len))
+                       if ((tp->tg3_flags3 & TG3_FLG3_4G_DMA_BNDRY_BUG) &&
+                           tg3_4g_overflow_test(mapping, len))
+                               would_hit_hwbug = 1;
+
+                       if ((tp->tg3_flags3 & TG3_FLG3_40BIT_DMA_LIMIT_BUG) &&
+                           tg3_40bit_overflow_test(tp, mapping, len))
                                would_hit_hwbug = 1;
 
                        if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
@@ -5444,7 +5832,7 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
                /* If the workaround fails due to memory/mapping
                 * failure, silently drop this packet.
                 */
-               if (tigon3_dma_hwbug_workaround(tp, skb, last_plus_one,
+               if (tigon3_dma_hwbug_workaround(tnapi, skb, last_plus_one,
                                                &start, base_flags, mss))
                        goto out_unlock;
 
@@ -5452,19 +5840,40 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
        }
 
        /* Packets are ready, update Tx producer idx local and on card. */
-       tw32_tx_mbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW, entry);
+       tw32_tx_mbox(tnapi->prodmbox, entry);
 
        tnapi->tx_prod = entry;
        if (unlikely(tg3_tx_avail(tnapi) <= (MAX_SKB_FRAGS + 1))) {
-               netif_stop_queue(dev);
+               netif_tx_stop_queue(txq);
                if (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi))
-                       netif_wake_queue(tp->dev);
+                       netif_tx_wake_queue(txq);
        }
 
 out_unlock:
        mmiowb();
 
        return NETDEV_TX_OK;
+
+dma_error:
+       last = i;
+       entry = tnapi->tx_prod;
+       tnapi->tx_buffers[entry].skb = NULL;
+       pci_unmap_single(tp->pdev,
+                        pci_unmap_addr(&tnapi->tx_buffers[entry], mapping),
+                        skb_headlen(skb),
+                        PCI_DMA_TODEVICE);
+       for (i = 0; i <= last; i++) {
+               skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+               entry = NEXT_TX(entry);
+
+               pci_unmap_page(tp->pdev,
+                              pci_unmap_addr(&tnapi->tx_buffers[entry],
+                                             mapping),
+                              frag->size, PCI_DMA_TODEVICE);
+       }
+
+       dev_kfree_skb(skb);
+       return NETDEV_TX_OK;
 }
 
 static inline void tg3_set_mtu(struct net_device *dev, struct tg3 *tp,
@@ -5529,36 +5938,33 @@ static void tg3_rx_prodring_free(struct tg3 *tp,
                                 struct tg3_rx_prodring_set *tpr)
 {
        int i;
-       struct ring_info *rxp;
-
-       for (i = 0; i < TG3_RX_RING_SIZE; i++) {
-               rxp = &tpr->rx_std_buffers[i];
 
-               if (rxp->skb == NULL)
-                       continue;
+       if (tpr != &tp->prodring[0]) {
+               for (i = tpr->rx_std_cons_idx; i != tpr->rx_std_prod_idx;
+                    i = (i + 1) % TG3_RX_RING_SIZE)
+                       tg3_rx_skb_free(tp, &tpr->rx_std_buffers[i],
+                                       tp->rx_pkt_map_sz);
+
+               if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
+                       for (i = tpr->rx_jmb_cons_idx;
+                            i != tpr->rx_jmb_prod_idx;
+                            i = (i + 1) % TG3_RX_JUMBO_RING_SIZE) {
+                               tg3_rx_skb_free(tp, &tpr->rx_jmb_buffers[i],
+                                               TG3_RX_JMB_MAP_SZ);
+                       }
+               }
 
-               pci_unmap_single(tp->pdev,
-                                pci_unmap_addr(rxp, mapping),
-                                tp->rx_pkt_map_sz,
-                                PCI_DMA_FROMDEVICE);
-               dev_kfree_skb_any(rxp->skb);
-               rxp->skb = NULL;
+               return;
        }
 
-       if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
-               for (i = 0; i < TG3_RX_JUMBO_RING_SIZE; i++) {
-                       rxp = &tpr->rx_jmb_buffers[i];
-
-                       if (rxp->skb == NULL)
-                               continue;
+       for (i = 0; i < TG3_RX_RING_SIZE; i++)
+               tg3_rx_skb_free(tp, &tpr->rx_std_buffers[i],
+                               tp->rx_pkt_map_sz);
 
-                       pci_unmap_single(tp->pdev,
-                                        pci_unmap_addr(rxp, mapping),
-                                        TG3_RX_JMB_MAP_SZ,
-                                        PCI_DMA_FROMDEVICE);
-                       dev_kfree_skb_any(rxp->skb);
-                       rxp->skb = NULL;
-               }
+       if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
+               for (i = 0; i < TG3_RX_JUMBO_RING_SIZE; i++)
+                       tg3_rx_skb_free(tp, &tpr->rx_jmb_buffers[i],
+                                       TG3_RX_JMB_MAP_SZ);
        }
 }
 
@@ -5573,7 +5979,19 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp,
                                 struct tg3_rx_prodring_set *tpr)
 {
        u32 i, rx_pkt_dma_sz;
-       struct tg3_napi *tnapi = &tp->napi[0];
+
+       tpr->rx_std_cons_idx = 0;
+       tpr->rx_std_prod_idx = 0;
+       tpr->rx_jmb_cons_idx = 0;
+       tpr->rx_jmb_prod_idx = 0;
+
+       if (tpr != &tp->prodring[0]) {
+               memset(&tpr->rx_std_buffers[0], 0, TG3_RX_STD_BUFF_RING_SIZE);
+               if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE)
+                       memset(&tpr->rx_jmb_buffers[0], 0,
+                              TG3_RX_JMB_BUFF_RING_SIZE);
+               goto done;
+       }
 
        /* Zero out all descriptors. */
        memset(tpr->rx_std, 0, TG3_RX_RING_BYTES);
@@ -5600,7 +6018,7 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp,
 
        /* Now allocate fresh SKBs for each rx ring. */
        for (i = 0; i < tp->rx_pending; i++) {
-               if (tg3_alloc_rx_skb(tnapi, RXD_OPAQUE_RING_STD, -1, i) < 0) {
+               if (tg3_alloc_rx_skb(tp, tpr, RXD_OPAQUE_RING_STD, i) < 0) {
                        printk(KERN_WARNING PFX
                               "%s: Using a smaller RX standard ring, "
                               "only %d out of %d buffers were allocated "
@@ -5631,8 +6049,8 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp,
                }
 
                for (i = 0; i < tp->rx_jumbo_pending; i++) {
-                       if (tg3_alloc_rx_skb(tnapi, RXD_OPAQUE_RING_JUMBO,
-                                            -1, i) < 0) {
+                       if (tg3_alloc_rx_skb(tp, tpr, RXD_OPAQUE_RING_JUMBO,
+                                            i) < 0) {
                                printk(KERN_WARNING PFX
                                       "%s: Using a smaller RX jumbo ring, "
                                       "only %d out of %d buffers were "
@@ -5676,8 +6094,7 @@ static void tg3_rx_prodring_fini(struct tg3 *tp,
 static int tg3_rx_prodring_init(struct tg3 *tp,
                                struct tg3_rx_prodring_set *tpr)
 {
-       tpr->rx_std_buffers = kzalloc(sizeof(struct ring_info) *
-                                     TG3_RX_RING_SIZE, GFP_KERNEL);
+       tpr->rx_std_buffers = kzalloc(TG3_RX_STD_BUFF_RING_SIZE, GFP_KERNEL);
        if (!tpr->rx_std_buffers)
                return -ENOMEM;
 
@@ -5687,8 +6104,7 @@ static int tg3_rx_prodring_init(struct tg3 *tp,
                goto err_out;
 
        if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
-               tpr->rx_jmb_buffers = kzalloc(sizeof(struct ring_info) *
-                                             TG3_RX_JUMBO_RING_SIZE,
+               tpr->rx_jmb_buffers = kzalloc(TG3_RX_JMB_BUFF_RING_SIZE,
                                              GFP_KERNEL);
                if (!tpr->rx_jmb_buffers)
                        goto err_out;
@@ -5716,31 +6132,50 @@ err_out:
  */
 static void tg3_free_rings(struct tg3 *tp)
 {
-       struct tg3_napi *tnapi = &tp->napi[0];
-       int i;
-
-       for (i = 0; i < TG3_TX_RING_SIZE; ) {
-               struct tx_ring_info *txp;
-               struct sk_buff *skb;
+       int i, j;
 
-               txp = &tnapi->tx_buffers[i];
-               skb = txp->skb;
+       for (j = 0; j < tp->irq_cnt; j++) {
+               struct tg3_napi *tnapi = &tp->napi[j];
 
-               if (skb == NULL) {
-                       i++;
+               if (!tnapi->tx_buffers)
                        continue;
-               }
 
-               skb_dma_unmap(&tp->pdev->dev, skb, DMA_TO_DEVICE);
+               for (i = 0; i < TG3_TX_RING_SIZE; ) {
+                       struct ring_info *txp;
+                       struct sk_buff *skb;
+                       unsigned int k;
 
-               txp->skb = NULL;
+                       txp = &tnapi->tx_buffers[i];
+                       skb = txp->skb;
 
-               i += skb_shinfo(skb)->nr_frags + 1;
+                       if (skb == NULL) {
+                               i++;
+                               continue;
+                       }
 
-               dev_kfree_skb_any(skb);
-       }
+                       pci_unmap_single(tp->pdev,
+                                        pci_unmap_addr(txp, mapping),
+                                        skb_headlen(skb),
+                                        PCI_DMA_TODEVICE);
+                       txp->skb = NULL;
 
-       tg3_rx_prodring_free(tp, &tp->prodring[0]);
+                       i++;
+
+                       for (k = 0; k < skb_shinfo(skb)->nr_frags; k++) {
+                               txp = &tnapi->tx_buffers[i & (TG3_TX_RING_SIZE - 1)];
+                               pci_unmap_page(tp->pdev,
+                                              pci_unmap_addr(txp, mapping),
+                                              skb_shinfo(skb)->frags[k].size,
+                                              PCI_DMA_TODEVICE);
+                               i++;
+                       }
+
+                       dev_kfree_skb_any(skb);
+               }
+
+               if (tp->irq_cnt == 1 || j != tp->irq_cnt - 1)
+                       tg3_rx_prodring_free(tp, &tp->prodring[j]);
+       }
 }
 
 /* Initialize tx/rx rings for packet processing.
@@ -5752,18 +6187,35 @@ static void tg3_free_rings(struct tg3 *tp)
  */
 static int tg3_init_rings(struct tg3 *tp)
 {
-       struct tg3_napi *tnapi = &tp->napi[0];
+       int i;
 
        /* Free up all the SKBs. */
        tg3_free_rings(tp);
 
-       /* Zero out all descriptors. */
-       memset(tnapi->tx_ring, 0, TG3_TX_RING_BYTES);
+       for (i = 0; i < tp->irq_cnt; i++) {
+               struct tg3_napi *tnapi = &tp->napi[i];
+
+               tnapi->last_tag = 0;
+               tnapi->last_irq_tag = 0;
+               tnapi->hw_status->status = 0;
+               tnapi->hw_status->status_tag = 0;
+               memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE);
+
+               tnapi->tx_prod = 0;
+               tnapi->tx_cons = 0;
+               if (tnapi->tx_ring)
+                       memset(tnapi->tx_ring, 0, TG3_TX_RING_BYTES);
 
-       tnapi->rx_rcb_ptr = 0;
-       memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));
+               tnapi->rx_rcb_ptr = 0;
+               if (tnapi->rx_rcb)
+                       memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));
 
-       return tg3_rx_prodring_alloc(tp, &tp->prodring[0]);
+               if ((tp->irq_cnt == 1 || i != tp->irq_cnt - 1) &&
+                       tg3_rx_prodring_alloc(tp, &tp->prodring[i]))
+                       return -ENOMEM;
+       }
+
+       return 0;
 }
 
 /*
@@ -5772,32 +6224,43 @@ static int tg3_init_rings(struct tg3 *tp)
  */
 static void tg3_free_consistent(struct tg3 *tp)
 {
-       struct tg3_napi *tnapi = &tp->napi[0];
+       int i;
 
-       kfree(tnapi->tx_buffers);
-       tnapi->tx_buffers = NULL;
-       if (tnapi->tx_ring) {
-               pci_free_consistent(tp->pdev, TG3_TX_RING_BYTES,
-                       tnapi->tx_ring, tnapi->tx_desc_mapping);
-               tnapi->tx_ring = NULL;
-       }
-       if (tnapi->rx_rcb) {
-               pci_free_consistent(tp->pdev, TG3_RX_RCB_RING_BYTES(tp),
-                                   tnapi->rx_rcb, tnapi->rx_rcb_mapping);
-               tnapi->rx_rcb = NULL;
-       }
-       if (tnapi->hw_status) {
-               pci_free_consistent(tp->pdev, TG3_HW_STATUS_SIZE,
-                                   tnapi->hw_status,
-                                   tnapi->status_mapping);
-               tnapi->hw_status = NULL;
+       for (i = 0; i < tp->irq_cnt; i++) {
+               struct tg3_napi *tnapi = &tp->napi[i];
+
+               if (tnapi->tx_ring) {
+                       pci_free_consistent(tp->pdev, TG3_TX_RING_BYTES,
+                               tnapi->tx_ring, tnapi->tx_desc_mapping);
+                       tnapi->tx_ring = NULL;
+               }
+
+               kfree(tnapi->tx_buffers);
+               tnapi->tx_buffers = NULL;
+
+               if (tnapi->rx_rcb) {
+                       pci_free_consistent(tp->pdev, TG3_RX_RCB_RING_BYTES(tp),
+                                           tnapi->rx_rcb,
+                                           tnapi->rx_rcb_mapping);
+                       tnapi->rx_rcb = NULL;
+               }
+
+               if (tnapi->hw_status) {
+                       pci_free_consistent(tp->pdev, TG3_HW_STATUS_SIZE,
+                                           tnapi->hw_status,
+                                           tnapi->status_mapping);
+                       tnapi->hw_status = NULL;
+               }
        }
+
        if (tp->hw_stats) {
                pci_free_consistent(tp->pdev, sizeof(struct tg3_hw_stats),
                                    tp->hw_stats, tp->stats_mapping);
                tp->hw_stats = NULL;
        }
-       tg3_rx_prodring_fini(tp, &tp->prodring[0]);
+
+       for (i = 0; i < (tp->irq_cnt == 1 ? 1 : tp->irq_cnt - 1); i++)
+               tg3_rx_prodring_fini(tp, &tp->prodring[i]);
 }
 
 /*
@@ -5806,44 +6269,93 @@ static void tg3_free_consistent(struct tg3 *tp)
  */
 static int tg3_alloc_consistent(struct tg3 *tp)
 {
-       struct tg3_napi *tnapi = &tp->napi[0];
+       int i;
 
-       if (tg3_rx_prodring_init(tp, &tp->prodring[0]))
-               return -ENOMEM;
+       for (i = 0; i < (tp->irq_cnt == 1 ? 1 : tp->irq_cnt - 1); i++) {
+               if (tg3_rx_prodring_init(tp, &tp->prodring[i]))
+                       goto err_out;
+       }
 
-       tnapi->tx_buffers = kzalloc(sizeof(struct tx_ring_info) *
-                                   TG3_TX_RING_SIZE, GFP_KERNEL);
-       if (!tnapi->tx_buffers)
+       tp->hw_stats = pci_alloc_consistent(tp->pdev,
+                                           sizeof(struct tg3_hw_stats),
+                                           &tp->stats_mapping);
+       if (!tp->hw_stats)
                goto err_out;
 
-       tnapi->tx_ring = pci_alloc_consistent(tp->pdev, TG3_TX_RING_BYTES,
-                                             &tnapi->tx_desc_mapping);
-       if (!tnapi->tx_ring)
-               goto err_out;
+       memset(tp->hw_stats, 0, sizeof(struct tg3_hw_stats));
 
-       tnapi->hw_status = pci_alloc_consistent(tp->pdev,
-                                               TG3_HW_STATUS_SIZE,
-                                               &tnapi->status_mapping);
-       if (!tnapi->hw_status)
-               goto err_out;
+       for (i = 0; i < tp->irq_cnt; i++) {
+               struct tg3_napi *tnapi = &tp->napi[i];
+               struct tg3_hw_status *sblk;
 
-       memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE);
+               tnapi->hw_status = pci_alloc_consistent(tp->pdev,
+                                                       TG3_HW_STATUS_SIZE,
+                                                       &tnapi->status_mapping);
+               if (!tnapi->hw_status)
+                       goto err_out;
 
-       tnapi->rx_rcb = pci_alloc_consistent(tp->pdev,
-                                            TG3_RX_RCB_RING_BYTES(tp),
-                                            &tnapi->rx_rcb_mapping);
-       if (!tnapi->rx_rcb)
-               goto err_out;
+               memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE);
+               sblk = tnapi->hw_status;
 
-       memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));
+               /* If multivector TSS is enabled, vector 0 does not handle
+                * tx interrupts.  Don't allocate any resources for it.
+                */
+               if ((!i && !(tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)) ||
+                   (i && (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS))) {
+                       tnapi->tx_buffers = kzalloc(sizeof(struct ring_info) *
+                                                   TG3_TX_RING_SIZE,
+                                                   GFP_KERNEL);
+                       if (!tnapi->tx_buffers)
+                               goto err_out;
 
-       tp->hw_stats = pci_alloc_consistent(tp->pdev,
-                                           sizeof(struct tg3_hw_stats),
-                                           &tp->stats_mapping);
-       if (!tp->hw_stats)
-               goto err_out;
+                       tnapi->tx_ring = pci_alloc_consistent(tp->pdev,
+                                                             TG3_TX_RING_BYTES,
+                                                      &tnapi->tx_desc_mapping);
+                       if (!tnapi->tx_ring)
+                               goto err_out;
+               }
 
-       memset(tp->hw_stats, 0, sizeof(struct tg3_hw_stats));
+               /*
+                * When RSS is enabled, the status block format changes
+                * slightly.  The "rx_jumbo_consumer", "reserved",
+                * and "rx_mini_consumer" members get mapped to the
+                * other three rx return ring producer indexes.
+                */
+               switch (i) {
+               default:
+                       tnapi->rx_rcb_prod_idx = &sblk->idx[0].rx_producer;
+                       break;
+               case 2:
+                       tnapi->rx_rcb_prod_idx = &sblk->rx_jumbo_consumer;
+                       break;
+               case 3:
+                       tnapi->rx_rcb_prod_idx = &sblk->reserved;
+                       break;
+               case 4:
+                       tnapi->rx_rcb_prod_idx = &sblk->rx_mini_consumer;
+                       break;
+               }
+
+               if (tp->irq_cnt == 1)
+                       tnapi->prodring = &tp->prodring[0];
+               else if (i)
+                       tnapi->prodring = &tp->prodring[i - 1];
+
+               /*
+                * If multivector RSS is enabled, vector 0 does not handle
+                * rx or tx interrupts.  Don't allocate any resources for it.
+                */
+               if (!i && (tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS))
+                       continue;
+
+               tnapi->rx_rcb = pci_alloc_consistent(tp->pdev,
+                                                    TG3_RX_RCB_RING_BYTES(tp),
+                                                    &tnapi->rx_rcb_mapping);
+               if (!tnapi->rx_rcb)
+                       goto err_out;
+
+               memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));
+       }
 
        return 0;
 
@@ -5904,7 +6416,6 @@ static int tg3_stop_block(struct tg3 *tp, unsigned long ofs, u32 enable_bit, int
 static int tg3_abort_hw(struct tg3 *tp, int silent)
 {
        int i, err;
-       struct tg3_napi *tnapi = &tp->napi[0];
 
        tg3_disable_ints(tp);
 
@@ -5956,8 +6467,11 @@ static int tg3_abort_hw(struct tg3 *tp, int silent)
        err |= tg3_stop_block(tp, BUFMGR_MODE, BUFMGR_MODE_ENABLE, silent);
        err |= tg3_stop_block(tp, MEMARB_MODE, MEMARB_MODE_ENABLE, silent);
 
-       if (tnapi->hw_status)
-               memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE);
+       for (i = 0; i < tp->irq_cnt; i++) {
+               struct tg3_napi *tnapi = &tp->napi[i];
+               if (tnapi->hw_status)
+                       memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE);
+       }
        if (tp->hw_stats)
                memset(tp->hw_stats, 0, sizeof(struct tg3_hw_stats));
 
@@ -6244,12 +6758,10 @@ static int tg3_chip_reset(struct tg3 *tp)
 {
        u32 val;
        void (*write_op)(struct tg3 *, u32, u32);
-       int err;
+       int i, err;
 
        tg3_nvram_lock(tp);
 
-       tg3_mdio_stop(tp);
-
        tg3_ape_lock(tp, TG3_APE_LOCK_GRC);
 
        /* No matching tg3_nvram_unlock() after this because
@@ -6284,14 +6796,19 @@ static int tg3_chip_reset(struct tg3 *tp)
         * sharing or irqpoll.
         */
        tp->tg3_flags |= TG3_FLAG_CHIP_RESETTING;
-       if (tp->napi[0].hw_status) {
-               tp->napi[0].hw_status->status = 0;
-               tp->napi[0].hw_status->status_tag = 0;
+       for (i = 0; i < tp->irq_cnt; i++) {
+               struct tg3_napi *tnapi = &tp->napi[i];
+               if (tnapi->hw_status) {
+                       tnapi->hw_status->status = 0;
+                       tnapi->hw_status->status_tag = 0;
+               }
+               tnapi->last_tag = 0;
+               tnapi->last_irq_tag = 0;
        }
-       tp->napi[0].last_tag = 0;
-       tp->napi[0].last_irq_tag = 0;
        smp_mb();
-       synchronize_irq(tp->pdev->irq);
+
+       for (i = 0; i < tp->irq_cnt; i++)
+               synchronize_irq(tp->napi[i].irq_vec);
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) {
                val = tr32(TG3_PCIE_LNKCTL) & ~TG3_PCIE_LNKCTL_L1_PLL_PD_EN;
@@ -6446,8 +6963,35 @@ static int tg3_chip_reset(struct tg3 *tp)
 
        tg3_mdio_start(tp);
 
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) {
+               u8 phy_addr;
+
+               phy_addr = tp->phy_addr;
+               tp->phy_addr = TG3_PHY_PCIE_ADDR;
+
+               tg3_writephy(tp, TG3_PCIEPHY_BLOCK_ADDR,
+                            TG3_PCIEPHY_TXB_BLK << TG3_PCIEPHY_BLOCK_SHIFT);
+               val = TG3_PCIEPHY_TX0CTRL1_TXOCM | TG3_PCIEPHY_TX0CTRL1_RDCTL |
+                     TG3_PCIEPHY_TX0CTRL1_TXCMV | TG3_PCIEPHY_TX0CTRL1_TKSEL |
+                     TG3_PCIEPHY_TX0CTRL1_NB_EN;
+               tg3_writephy(tp, TG3_PCIEPHY_TX0CTRL1, val);
+               udelay(10);
+
+               tg3_writephy(tp, TG3_PCIEPHY_BLOCK_ADDR,
+                            TG3_PCIEPHY_XGXS_BLK1 << TG3_PCIEPHY_BLOCK_SHIFT);
+               val = TG3_PCIEPHY_PWRMGMT4_LOWPWR_EN |
+                     TG3_PCIEPHY_PWRMGMT4_L1PLLPD_EN;
+               tg3_writephy(tp, TG3_PCIEPHY_PWRMGMT4, val);
+               udelay(10);
+
+               tp->phy_addr = phy_addr;
+       }
+
        if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) &&
-           tp->pci_chip_rev_id != CHIPREV_ID_5750_A0) {
+           tp->pci_chip_rev_id != CHIPREV_ID_5750_A0 &&
+           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785 &&
+           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 &&
+           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57765) {
                val = tr32(0x7c00);
 
                tw32(0x7c00, val | (1 << 25));
@@ -6797,24 +7341,191 @@ static void tg3_set_bdinfo(struct tg3 *tp, u32 bdinfo_addr,
 static void __tg3_set_rx_mode(struct net_device *);
 static void __tg3_set_coalesce(struct tg3 *tp, struct ethtool_coalesce *ec)
 {
-       tw32(HOSTCC_RXCOL_TICKS, ec->rx_coalesce_usecs);
-       tw32(HOSTCC_TXCOL_TICKS, ec->tx_coalesce_usecs);
-       tw32(HOSTCC_RXMAX_FRAMES, ec->rx_max_coalesced_frames);
-       tw32(HOSTCC_TXMAX_FRAMES, ec->tx_max_coalesced_frames);
-       if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
-               tw32(HOSTCC_RXCOAL_TICK_INT, ec->rx_coalesce_usecs_irq);
-               tw32(HOSTCC_TXCOAL_TICK_INT, ec->tx_coalesce_usecs_irq);
+       int i;
+
+       if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)) {
+               tw32(HOSTCC_TXCOL_TICKS, ec->tx_coalesce_usecs);
+               tw32(HOSTCC_TXMAX_FRAMES, ec->tx_max_coalesced_frames);
+               tw32(HOSTCC_TXCOAL_MAXF_INT, ec->tx_max_coalesced_frames_irq);
+       } else {
+               tw32(HOSTCC_TXCOL_TICKS, 0);
+               tw32(HOSTCC_TXMAX_FRAMES, 0);
+               tw32(HOSTCC_TXCOAL_MAXF_INT, 0);
        }
-       tw32(HOSTCC_RXCOAL_MAXF_INT, ec->rx_max_coalesced_frames_irq);
-       tw32(HOSTCC_TXCOAL_MAXF_INT, ec->tx_max_coalesced_frames_irq);
+
+       if (!(tp->tg3_flags2 & TG3_FLG2_USING_MSIX)) {
+               tw32(HOSTCC_RXCOL_TICKS, ec->rx_coalesce_usecs);
+               tw32(HOSTCC_RXMAX_FRAMES, ec->rx_max_coalesced_frames);
+               tw32(HOSTCC_RXCOAL_MAXF_INT, ec->rx_max_coalesced_frames_irq);
+       } else {
+               tw32(HOSTCC_RXCOL_TICKS, 0);
+               tw32(HOSTCC_RXMAX_FRAMES, 0);
+               tw32(HOSTCC_RXCOAL_MAXF_INT, 0);
+       }
+
        if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
                u32 val = ec->stats_block_coalesce_usecs;
 
+               tw32(HOSTCC_RXCOAL_TICK_INT, ec->rx_coalesce_usecs_irq);
+               tw32(HOSTCC_TXCOAL_TICK_INT, ec->tx_coalesce_usecs_irq);
+
                if (!netif_carrier_ok(tp->dev))
                        val = 0;
 
                tw32(HOSTCC_STAT_COAL_TICKS, val);
        }
+
+       for (i = 0; i < tp->irq_cnt - 1; i++) {
+               u32 reg;
+
+               reg = HOSTCC_RXCOL_TICKS_VEC1 + i * 0x18;
+               tw32(reg, ec->rx_coalesce_usecs);
+               reg = HOSTCC_RXMAX_FRAMES_VEC1 + i * 0x18;
+               tw32(reg, ec->rx_max_coalesced_frames);
+               reg = HOSTCC_RXCOAL_MAXF_INT_VEC1 + i * 0x18;
+               tw32(reg, ec->rx_max_coalesced_frames_irq);
+
+               if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS) {
+                       reg = HOSTCC_TXCOL_TICKS_VEC1 + i * 0x18;
+                       tw32(reg, ec->tx_coalesce_usecs);
+                       reg = HOSTCC_TXMAX_FRAMES_VEC1 + i * 0x18;
+                       tw32(reg, ec->tx_max_coalesced_frames);
+                       reg = HOSTCC_TXCOAL_MAXF_INT_VEC1 + i * 0x18;
+                       tw32(reg, ec->tx_max_coalesced_frames_irq);
+               }
+       }
+
+       for (; i < tp->irq_max - 1; i++) {
+               tw32(HOSTCC_RXCOL_TICKS_VEC1 + i * 0x18, 0);
+               tw32(HOSTCC_RXMAX_FRAMES_VEC1 + i * 0x18, 0);
+               tw32(HOSTCC_RXCOAL_MAXF_INT_VEC1 + i * 0x18, 0);
+
+               if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS) {
+                       tw32(HOSTCC_TXCOL_TICKS_VEC1 + i * 0x18, 0);
+                       tw32(HOSTCC_TXMAX_FRAMES_VEC1 + i * 0x18, 0);
+                       tw32(HOSTCC_TXCOAL_MAXF_INT_VEC1 + i * 0x18, 0);
+               }
+       }
+}
+
+/* tp->lock is held. */
+static void tg3_rings_reset(struct tg3 *tp)
+{
+       int i;
+       u32 stblk, txrcb, rxrcb, limit;
+       struct tg3_napi *tnapi = &tp->napi[0];
+
+       /* Disable all transmit rings but the first. */
+       if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+               limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 16;
+       else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
+               limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 2;
+       else
+               limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE;
+
+       for (txrcb = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE;
+            txrcb < limit; txrcb += TG3_BDINFO_SIZE)
+               tg3_write_mem(tp, txrcb + TG3_BDINFO_MAXLEN_FLAGS,
+                             BDINFO_FLAGS_DISABLED);
+
+
+       /* Disable all receive return rings but the first. */
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
+               limit = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE * 17;
+       else if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+               limit = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE * 16;
+       else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
+                GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
+               limit = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE * 4;
+       else
+               limit = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE;
+
+       for (rxrcb = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE;
+            rxrcb < limit; rxrcb += TG3_BDINFO_SIZE)
+               tg3_write_mem(tp, rxrcb + TG3_BDINFO_MAXLEN_FLAGS,
+                             BDINFO_FLAGS_DISABLED);
+
+       /* Disable interrupts */
+       tw32_mailbox_f(tp->napi[0].int_mbox, 1);
+
+       /* Zero mailbox registers. */
+       if (tp->tg3_flags & TG3_FLAG_SUPPORT_MSIX) {
+               for (i = 1; i < TG3_IRQ_MAX_VECS; i++) {
+                       tp->napi[i].tx_prod = 0;
+                       tp->napi[i].tx_cons = 0;
+                       if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)
+                               tw32_mailbox(tp->napi[i].prodmbox, 0);
+                       tw32_rx_mbox(tp->napi[i].consmbox, 0);
+                       tw32_mailbox_f(tp->napi[i].int_mbox, 1);
+               }
+               if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS))
+                       tw32_mailbox(tp->napi[0].prodmbox, 0);
+       } else {
+               tp->napi[0].tx_prod = 0;
+               tp->napi[0].tx_cons = 0;
+               tw32_mailbox(tp->napi[0].prodmbox, 0);
+               tw32_rx_mbox(tp->napi[0].consmbox, 0);
+       }
+
+       /* Make sure the NIC-based send BD rings are disabled. */
+       if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
+               u32 mbox = MAILBOX_SNDNIC_PROD_IDX_0 + TG3_64BIT_REG_LOW;
+               for (i = 0; i < 16; i++)
+                       tw32_tx_mbox(mbox + i * 8, 0);
+       }
+
+       txrcb = NIC_SRAM_SEND_RCB;
+       rxrcb = NIC_SRAM_RCV_RET_RCB;
+
+       /* Clear status block in ram. */
+       memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE);
+
+       /* Set status block DMA address */
+       tw32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH,
+            ((u64) tnapi->status_mapping >> 32));
+       tw32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_LOW,
+            ((u64) tnapi->status_mapping & 0xffffffff));
+
+       if (tnapi->tx_ring) {
+               tg3_set_bdinfo(tp, txrcb, tnapi->tx_desc_mapping,
+                              (TG3_TX_RING_SIZE <<
+                               BDINFO_FLAGS_MAXLEN_SHIFT),
+                              NIC_SRAM_TX_BUFFER_DESC);
+               txrcb += TG3_BDINFO_SIZE;
+       }
+
+       if (tnapi->rx_rcb) {
+               tg3_set_bdinfo(tp, rxrcb, tnapi->rx_rcb_mapping,
+                              (TG3_RX_RCB_RING_SIZE(tp) <<
+                               BDINFO_FLAGS_MAXLEN_SHIFT), 0);
+               rxrcb += TG3_BDINFO_SIZE;
+       }
+
+       stblk = HOSTCC_STATBLCK_RING1;
+
+       for (i = 1, tnapi++; i < tp->irq_cnt; i++, tnapi++) {
+               u64 mapping = (u64)tnapi->status_mapping;
+               tw32(stblk + TG3_64BIT_REG_HIGH, mapping >> 32);
+               tw32(stblk + TG3_64BIT_REG_LOW, mapping & 0xffffffff);
+
+               /* Clear status block in ram. */
+               memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE);
+
+               if (tnapi->tx_ring) {
+                       tg3_set_bdinfo(tp, txrcb, tnapi->tx_desc_mapping,
+                                      (TG3_TX_RING_SIZE <<
+                                       BDINFO_FLAGS_MAXLEN_SHIFT),
+                                      NIC_SRAM_TX_BUFFER_DESC);
+                       txrcb += TG3_BDINFO_SIZE;
+               }
+
+               tg3_set_bdinfo(tp, rxrcb, tnapi->rx_rcb_mapping,
+                              (TG3_RX_RCB_RING_SIZE(tp) <<
+                               BDINFO_FLAGS_MAXLEN_SHIFT), 0);
+
+               stblk += 8;
+               rxrcb += TG3_BDINFO_SIZE;
+       }
 }
 
 /* tp->lock is held. */
@@ -6875,15 +7586,23 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                tw32(TG3_PCIE_EIDLE_DELAY, val | TG3_PCIE_EIDLE_DELAY_13_CLKS);
 
                tw32(TG3_CORR_ERR_STAT, TG3_CORR_ERR_STAT_CLEAR);
+
+               val = tr32(TG3_PCIE_LNKCTL) & ~TG3_PCIE_LNKCTL_L1_PLL_PD_EN;
+               tw32(TG3_PCIE_LNKCTL, val | TG3_PCIE_LNKCTL_L1_PLL_PD_DIS);
        }
 
-       if (tp->tg3_flags3 & TG3_FLG3_TOGGLE_10_100_L1PLLPD) {
-               val = tr32(TG3_PCIE_LNKCTL);
-               if (tp->tg3_flags3 & TG3_FLG3_CLKREQ_BUG)
-                       val |= TG3_PCIE_LNKCTL_L1_PLL_PD_DIS;
-               else
-                       val &= ~TG3_PCIE_LNKCTL_L1_PLL_PD_DIS;
-               tw32(TG3_PCIE_LNKCTL, val);
+       if (tp->tg3_flags3 & TG3_FLG3_L1PLLPD_EN) {
+               u32 grc_mode = tr32(GRC_MODE);
+
+               /* Access the lower 1K of PL PCIE block registers. */
+               val = grc_mode & ~GRC_MODE_PCIE_PORT_MASK;
+               tw32(GRC_MODE, val | GRC_MODE_PCIE_PL_SEL);
+
+               val = tr32(TG3_PCIE_TLDLPL_PORT + TG3_PCIE_PL_LO_PHYCTL1);
+               tw32(TG3_PCIE_TLDLPL_PORT + TG3_PCIE_PL_LO_PHYCTL1,
+                    val | TG3_PCIE_PL_LO_PHYCTL1_L1PLLPD_EN);
+
+               tw32(GRC_MODE, grc_mode);
        }
 
        /* This works around an issue with Athlon chipsets on
@@ -6930,8 +7649,13 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        if (err)
                return err;
 
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5784 &&
-           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5761) {
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) {
+               val = tr32(TG3PCI_DMA_RW_CTRL) &
+                     ~DMA_RWCTRL_DIS_CACHE_ALIGNMENT;
+               tw32(TG3PCI_DMA_RW_CTRL, val | tp->dma_rwctrl);
+       } else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5784 &&
+                  GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5761) {
                /* This value is determined during the probe time DMA
                 * engine test, tg3_test_dma.
                 */
@@ -7054,8 +7778,9 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
             ((u64) tpr->rx_std_mapping >> 32));
        tw32(RCVDBDI_STD_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW,
             ((u64) tpr->rx_std_mapping & 0xffffffff));
-       tw32(RCVDBDI_STD_BD + TG3_BDINFO_NIC_ADDR,
-            NIC_SRAM_RX_BUFFER_DESC);
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717)
+               tw32(RCVDBDI_STD_BD + TG3_BDINFO_NIC_ADDR,
+                    NIC_SRAM_RX_BUFFER_DESC);
 
        /* Disable the mini ring */
        if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
@@ -7078,69 +7803,39 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                        tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS,
                             (RX_JUMBO_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT) |
                             BDINFO_FLAGS_USE_EXT_RECV);
-                       tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_NIC_ADDR,
-                            NIC_SRAM_RX_JUMBO_BUFFER_DESC);
+                       if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717)
+                               tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_NIC_ADDR,
+                                    NIC_SRAM_RX_JUMBO_BUFFER_DESC);
                } else {
                        tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS,
                             BDINFO_FLAGS_DISABLED);
                }
 
-               val = RX_STD_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT;
+               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
+                       val = (RX_STD_MAX_SIZE_5705 << BDINFO_FLAGS_MAXLEN_SHIFT) |
+                             (RX_STD_MAX_SIZE << 2);
+               else
+                       val = RX_STD_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT;
        } else
                val = RX_STD_MAX_SIZE_5705 << BDINFO_FLAGS_MAXLEN_SHIFT;
 
        tw32(RCVDBDI_STD_BD + TG3_BDINFO_MAXLEN_FLAGS, val);
 
-       /* There is only one send ring on 5705/5750, no need to explicitly
-        * disable the others.
-        */
-       if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
-               /* Clear out send RCB ring in SRAM. */
-               for (i = NIC_SRAM_SEND_RCB; i < NIC_SRAM_RCV_RET_RCB; i += TG3_BDINFO_SIZE)
-                       tg3_write_mem(tp, i + TG3_BDINFO_MAXLEN_FLAGS,
-                                     BDINFO_FLAGS_DISABLED);
-       }
-
-       tp->napi[0].tx_prod = 0;
-       tp->napi[0].tx_cons = 0;
-       tw32_tx_mbox(MAILBOX_SNDNIC_PROD_IDX_0 + TG3_64BIT_REG_LOW, 0);
+       tpr->rx_std_prod_idx = tp->rx_pending;
+       tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG, tpr->rx_std_prod_idx);
 
-       val = MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW;
-       tw32_mailbox(val, 0);
-
-       tg3_set_bdinfo(tp, NIC_SRAM_SEND_RCB,
-                      tp->napi[0].tx_desc_mapping,
-                      (TG3_TX_RING_SIZE <<
-                       BDINFO_FLAGS_MAXLEN_SHIFT),
-                      NIC_SRAM_TX_BUFFER_DESC);
+       tpr->rx_jmb_prod_idx = (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) ?
+                         tp->rx_jumbo_pending : 0;
+       tw32_rx_mbox(TG3_RX_JMB_PROD_IDX_REG, tpr->rx_jmb_prod_idx);
 
-       /* There is only one receive return ring on 5705/5750, no need
-        * to explicitly disable the others.
-        */
-       if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
-               for (i = NIC_SRAM_RCV_RET_RCB; i < NIC_SRAM_STATS_BLK;
-                    i += TG3_BDINFO_SIZE) {
-                       tg3_write_mem(tp, i + TG3_BDINFO_MAXLEN_FLAGS,
-                                     BDINFO_FLAGS_DISABLED);
-               }
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) {
+               tw32(STD_REPLENISH_LWM, 32);
+               tw32(JMB_REPLENISH_LWM, 16);
        }
 
-       tw32_rx_mbox(tp->napi[0].consmbox, 0);
-
-       tg3_set_bdinfo(tp, NIC_SRAM_RCV_RET_RCB,
-                      tp->napi[0].rx_rcb_mapping,
-                      (TG3_RX_RCB_RING_SIZE(tp) <<
-                       BDINFO_FLAGS_MAXLEN_SHIFT),
-                      0);
-
-       tpr->rx_std_ptr = tp->rx_pending;
-       tw32_rx_mbox(MAILBOX_RCV_STD_PROD_IDX + TG3_64BIT_REG_LOW,
-                    tpr->rx_std_ptr);
-
-       tpr->rx_jmb_ptr = (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) ?
-                         tp->rx_jumbo_pending : 0;
-       tw32_rx_mbox(MAILBOX_RCV_JUMBO_PROD_IDX + TG3_64BIT_REG_LOW,
-                    tpr->rx_jmb_ptr);
+       tg3_rings_reset(tp);
 
        /* Initialize MAC address and backoff seed. */
        __tg3_set_mac_addr(tp, 0);
@@ -7196,7 +7891,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
                rdmac_mode |= RDMAC_MODE_IPV4_LSO_EN;
 
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
+       if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_3) ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
                rdmac_mode |= RDMAC_MODE_IPV6_LSO_EN;
 
@@ -7229,12 +7925,6 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 
        __tg3_set_coalesce(tp, &tp->coal);
 
-       /* set status block DMA address */
-       tw32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH,
-            ((u64) tp->napi[0].status_mapping >> 32));
-       tw32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_LOW,
-            ((u64) tp->napi[0].status_mapping & 0xffffffff));
-
        if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
                /* Status/statistics block address.  See tg3_timer,
                 * the tg3_periodic_fetch_stats call there, and
@@ -7245,7 +7935,16 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                tw32(HOSTCC_STATS_BLK_HOST_ADDR + TG3_64BIT_REG_LOW,
                     ((u64) tp->stats_mapping & 0xffffffff));
                tw32(HOSTCC_STATS_BLK_NIC_ADDR, NIC_SRAM_STATS_BLK);
+
                tw32(HOSTCC_STATUS_BLK_NIC_ADDR, NIC_SRAM_STATUS_BLK);
+
+               /* Clear statistics and status block memory areas */
+               for (i = NIC_SRAM_STATS_BLK;
+                    i < NIC_SRAM_STATUS_BLK + TG3_HW_STATUS_SIZE;
+                    i += sizeof(u32)) {
+                       tg3_write_mem(tp, i, 0);
+                       udelay(40);
+               }
        }
 
        tw32(HOSTCC_MODE, HOSTCC_MODE_ENABLE | tp->coalesce_mode);
@@ -7255,15 +7954,6 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
                tw32(RCVLSC_MODE, RCVLSC_MODE_ENABLE | RCVLSC_MODE_ATTN_ENABLE);
 
-       /* Clear statistics/status block in chip, and status block in ram. */
-       for (i = NIC_SRAM_STATS_BLK;
-            i < NIC_SRAM_STATUS_BLK + TG3_HW_STATUS_SIZE;
-            i += sizeof(u32)) {
-               tg3_write_mem(tp, i, 0);
-               udelay(40);
-       }
-       memset(tp->napi[0].hw_status, 0, TG3_HW_STATUS_SIZE);
-
        if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) {
                tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT;
                /* reset to prevent losing 1st rx packet intermittently */
@@ -7315,7 +8005,11 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
        udelay(100);
 
-       tw32_mailbox_f(tp->napi[0].int_mbox, 0);
+       if (tp->tg3_flags2 & TG3_FLG2_USING_MSIX) {
+               val = tr32(MSGINT_MODE);
+               val |= MSGINT_MODE_MULTIVEC_EN | MSGINT_MODE_ENABLE;
+               tw32(MSGINT_MODE, val);
+       }
 
        if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
                tw32_f(DMAC_MODE, DMAC_MODE_ENABLE);
@@ -7347,6 +8041,9 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
                val |= WDMAC_MODE_STATUS_TAG_FIX;
 
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
+               val |= WDMAC_MODE_BURST_ALL_DATA;
+
        tw32_f(WDMAC_MODE, val);
        udelay(40);
 
@@ -7385,7 +8082,10 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE);
        if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
                tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE | 0x8);
-       tw32(SNDBDI_MODE, SNDBDI_MODE_ENABLE | SNDBDI_MODE_ATTN_ENABLE);
+       val = SNDBDI_MODE_ENABLE | SNDBDI_MODE_ATTN_ENABLE;
+       if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)
+               val |= SNDBDI_MODE_MULTI_TXQ_EN;
+       tw32(SNDBDI_MODE, val);
        tw32(SNDBDS_MODE, SNDBDS_MODE_ENABLE | SNDBDS_MODE_ATTN_ENABLE);
 
        if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0) {
@@ -7404,10 +8104,46 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        tw32_f(MAC_TX_MODE, tp->tx_mode);
        udelay(100);
 
+       if (tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS) {
+               u32 reg = MAC_RSS_INDIR_TBL_0;
+               u8 *ent = (u8 *)&val;
+
+               /* Setup the indirection table */
+               for (i = 0; i < TG3_RSS_INDIR_TBL_SIZE; i++) {
+                       int idx = i % sizeof(val);
+
+                       ent[idx] = i % (tp->irq_cnt - 1);
+                       if (idx == sizeof(val) - 1) {
+                               tw32(reg, val);
+                               reg += 4;
+                       }
+               }
+
+               /* Setup the "secret" hash key. */
+               tw32(MAC_RSS_HASH_KEY_0, 0x5f865437);
+               tw32(MAC_RSS_HASH_KEY_1, 0xe4ac62cc);
+               tw32(MAC_RSS_HASH_KEY_2, 0x50103a45);
+               tw32(MAC_RSS_HASH_KEY_3, 0x36621985);
+               tw32(MAC_RSS_HASH_KEY_4, 0xbf14c0e8);
+               tw32(MAC_RSS_HASH_KEY_5, 0x1bc27a1e);
+               tw32(MAC_RSS_HASH_KEY_6, 0x84f4b556);
+               tw32(MAC_RSS_HASH_KEY_7, 0x094ea6fe);
+               tw32(MAC_RSS_HASH_KEY_8, 0x7dda01e7);
+               tw32(MAC_RSS_HASH_KEY_9, 0xc04d7481);
+       }
+
        tp->rx_mode = RX_MODE_ENABLE;
        if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
                tp->rx_mode |= RX_MODE_IPV6_CSUM_ENABLE;
 
+       if (tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS)
+               tp->rx_mode |= RX_MODE_RSS_ENABLE |
+                              RX_MODE_RSS_ITBL_HASH_BITS_7 |
+                              RX_MODE_RSS_IPV6_HASH_EN |
+                              RX_MODE_RSS_TCP_IPV6_HASH_EN |
+                              RX_MODE_RSS_IPV4_HASH_EN |
+                              RX_MODE_RSS_TCP_IPV4_HASH_EN;
+
        tw32_f(MAC_RX_MODE, tp->rx_mode);
        udelay(10);
 
@@ -7438,7 +8174,11 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        /* Prevent chip from dropping frames when flow control
         * is enabled.
         */
-       tw32_f(MAC_LOW_WMARK_MAX_RX_FRAME, 2);
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
+               val = 1;
+       else
+               val = 2;
+       tw32_f(MAC_LOW_WMARK_MAX_RX_FRAME, val);
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 &&
            (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) {
@@ -7622,7 +8362,7 @@ static void tg3_timer(unsigned long __opaque)
                             tp->grc_local_ctrl | GRC_LCLCTRL_SETINT);
                } else {
                        tw32(HOSTCC_MODE, tp->coalesce_mode |
-                            (HOSTCC_MODE_ENABLE | HOSTCC_MODE_NOW));
+                            HOSTCC_MODE_ENABLE | HOSTCC_MODE_NOW);
                }
 
                if (!(tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) {
@@ -7723,13 +8463,22 @@ restart_timer:
        add_timer(&tp->timer);
 }
 
-static int tg3_request_irq(struct tg3 *tp)
+static int tg3_request_irq(struct tg3 *tp, int irq_num)
 {
        irq_handler_t fn;
        unsigned long flags;
-       char *name = tp->dev->name;
+       char *name;
+       struct tg3_napi *tnapi = &tp->napi[irq_num];
 
-       if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
+       if (tp->irq_cnt == 1)
+               name = tp->dev->name;
+       else {
+               name = &tnapi->irq_lbl[0];
+               snprintf(name, IFNAMSIZ, "%s-%d", tp->dev->name, irq_num);
+               name[IFNAMSIZ-1] = 0;
+       }
+
+       if (tp->tg3_flags2 & TG3_FLG2_USING_MSI_OR_MSIX) {
                fn = tg3_msi;
                if (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI)
                        fn = tg3_msi_1shot;
@@ -7740,7 +8489,8 @@ static int tg3_request_irq(struct tg3 *tp)
                        fn = tg3_interrupt_tagged;
                flags = IRQF_SHARED | IRQF_SAMPLE_RANDOM;
        }
-       return request_irq(tp->pdev->irq, fn, flags, name, &tp->napi[0]);
+
+       return request_irq(tnapi->irq_vec, fn, flags, name, tnapi);
 }
 
 static int tg3_test_interrupt(struct tg3 *tp)
@@ -7748,15 +8498,27 @@ static int tg3_test_interrupt(struct tg3 *tp)
        struct tg3_napi *tnapi = &tp->napi[0];
        struct net_device *dev = tp->dev;
        int err, i, intr_ok = 0;
+       u32 val;
 
        if (!netif_running(dev))
                return -ENODEV;
 
        tg3_disable_ints(tp);
 
-       free_irq(tp->pdev->irq, tnapi);
+       free_irq(tnapi->irq_vec, tnapi);
 
-       err = request_irq(tp->pdev->irq, tg3_test_isr,
+       /*
+        * Turn off MSI one shot mode.  Otherwise this test has no
+        * observable way to know whether the interrupt was delivered.
+        */
+       if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) &&
+           (tp->tg3_flags2 & TG3_FLG2_USING_MSI)) {
+               val = tr32(MSGINT_MODE) | MSGINT_MODE_ONE_SHOT_DISABLE;
+               tw32(MSGINT_MODE, val);
+       }
+
+       err = request_irq(tnapi->irq_vec, tg3_test_isr,
                          IRQF_SHARED | IRQF_SAMPLE_RANDOM, dev->name, tnapi);
        if (err)
                return err;
@@ -7765,7 +8527,7 @@ static int tg3_test_interrupt(struct tg3 *tp)
        tg3_enable_ints(tp);
 
        tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE |
-              HOSTCC_MODE_NOW);
+              tnapi->coal_now);
 
        for (i = 0; i < 5; i++) {
                u32 int_mbox, misc_host_ctrl;
@@ -7784,15 +8546,23 @@ static int tg3_test_interrupt(struct tg3 *tp)
 
        tg3_disable_ints(tp);
 
-       free_irq(tp->pdev->irq, tnapi);
+       free_irq(tnapi->irq_vec, tnapi);
 
-       err = tg3_request_irq(tp);
+       err = tg3_request_irq(tp, 0);
 
        if (err)
                return err;
 
-       if (intr_ok)
+       if (intr_ok) {
+               /* Reenable MSI one shot mode. */
+               if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+                    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) &&
+                   (tp->tg3_flags2 & TG3_FLG2_USING_MSI)) {
+                       val = tr32(MSGINT_MODE) & ~MSGINT_MODE_ONE_SHOT_DISABLE;
+                       tw32(MSGINT_MODE, val);
+               }
                return 0;
+       }
 
        return -EIO;
 }
@@ -7832,13 +8602,13 @@ static int tg3_test_msi(struct tg3 *tp)
               "the PCI maintainer and include system chipset information.\n",
                       tp->dev->name);
 
-       free_irq(tp->pdev->irq, &tp->napi[0]);
+       free_irq(tp->napi[0].irq_vec, &tp->napi[0]);
 
        pci_disable_msi(tp->pdev);
 
        tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
 
-       err = tg3_request_irq(tp);
+       err = tg3_request_irq(tp, 0);
        if (err)
                return err;
 
@@ -7853,7 +8623,7 @@ static int tg3_test_msi(struct tg3 *tp)
        tg3_full_unlock(tp);
 
        if (err)
-               free_irq(tp->pdev->irq, &tp->napi[0]);
+               free_irq(tp->napi[0].irq_vec, &tp->napi[0]);
 
        return err;
 }
@@ -7889,37 +8659,99 @@ static int tg3_request_firmware(struct tg3 *tp)
        return 0;
 }
 
+static bool tg3_enable_msix(struct tg3 *tp)
+{
+       int i, rc, cpus = num_online_cpus();
+       struct msix_entry msix_ent[tp->irq_max];
+
+       if (cpus == 1)
+               /* Just fallback to the simpler MSI mode. */
+               return false;
+
+       /*
+        * We want as many rx rings enabled as there are cpus.
+        * The first MSIX vector only deals with link interrupts, etc,
+        * so we add one to the number of vectors we are requesting.
+        */
+       tp->irq_cnt = min_t(unsigned, cpus + 1, tp->irq_max);
+
+       for (i = 0; i < tp->irq_max; i++) {
+               msix_ent[i].entry  = i;
+               msix_ent[i].vector = 0;
+       }
+
+       rc = pci_enable_msix(tp->pdev, msix_ent, tp->irq_cnt);
+       if (rc != 0) {
+               if (rc < TG3_RSS_MIN_NUM_MSIX_VECS)
+                       return false;
+               if (pci_enable_msix(tp->pdev, msix_ent, rc))
+                       return false;
+               printk(KERN_NOTICE
+                      "%s: Requested %d MSI-X vectors, received %d\n",
+                      tp->dev->name, tp->irq_cnt, rc);
+               tp->irq_cnt = rc;
+       }
+
+       tp->tg3_flags3 |= TG3_FLG3_ENABLE_RSS;
+
+       for (i = 0; i < tp->irq_max; i++)
+               tp->napi[i].irq_vec = msix_ent[i].vector;
+
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) {
+               tp->tg3_flags3 |= TG3_FLG3_ENABLE_TSS;
+               tp->dev->real_num_tx_queues = tp->irq_cnt - 1;
+       } else
+               tp->dev->real_num_tx_queues = 1;
+
+       return true;
+}
+
 static void tg3_ints_init(struct tg3 *tp)
 {
-       if (tp->tg3_flags & TG3_FLAG_SUPPORT_MSI) {
+       if ((tp->tg3_flags & TG3_FLAG_SUPPORT_MSI_OR_MSIX) &&
+           !(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)) {
                /* All MSI supporting chips should support tagged
                 * status.  Assert that this is the case.
                 */
-               if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)) {
-                       printk(KERN_WARNING PFX "%s: MSI without TAGGED? "
-                              "Not using MSI.\n", tp->dev->name);
-               } else if (pci_enable_msi(tp->pdev) == 0) {
-                       u32 msi_mode;
+               printk(KERN_WARNING PFX "%s: MSI without TAGGED? "
+                      "Not using MSI.\n", tp->dev->name);
+               goto defcfg;
+       }
 
-                       msi_mode = tr32(MSGINT_MODE);
-                       tw32(MSGINT_MODE, msi_mode | MSGINT_MODE_ENABLE);
-                       tp->tg3_flags2 |= TG3_FLG2_USING_MSI;
-               }
+       if ((tp->tg3_flags & TG3_FLAG_SUPPORT_MSIX) && tg3_enable_msix(tp))
+               tp->tg3_flags2 |= TG3_FLG2_USING_MSIX;
+       else if ((tp->tg3_flags & TG3_FLAG_SUPPORT_MSI) &&
+                pci_enable_msi(tp->pdev) == 0)
+               tp->tg3_flags2 |= TG3_FLG2_USING_MSI;
+
+       if (tp->tg3_flags2 & TG3_FLG2_USING_MSI_OR_MSIX) {
+               u32 msi_mode = tr32(MSGINT_MODE);
+               if (tp->tg3_flags2 & TG3_FLG2_USING_MSIX)
+                       msi_mode |= MSGINT_MODE_MULTIVEC_EN;
+               tw32(MSGINT_MODE, msi_mode | MSGINT_MODE_ENABLE);
+       }
+defcfg:
+       if (!(tp->tg3_flags2 & TG3_FLG2_USING_MSIX)) {
+               tp->irq_cnt = 1;
+               tp->napi[0].irq_vec = tp->pdev->irq;
+               tp->dev->real_num_tx_queues = 1;
        }
 }
 
 static void tg3_ints_fini(struct tg3 *tp)
 {
-               if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
-                       pci_disable_msi(tp->pdev);
-                       tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
-               }
+       if (tp->tg3_flags2 & TG3_FLG2_USING_MSIX)
+               pci_disable_msix(tp->pdev);
+       else if (tp->tg3_flags2 & TG3_FLG2_USING_MSI)
+               pci_disable_msi(tp->pdev);
+       tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI_OR_MSIX;
+       tp->tg3_flags3 &= ~TG3_FLG3_ENABLE_RSS;
 }
 
 static int tg3_open(struct net_device *dev)
 {
        struct tg3 *tp = netdev_priv(dev);
-       int err;
+       int i, err;
 
        if (tp->fw_needed) {
                err = tg3_request_firmware(tp);
@@ -7950,21 +8782,33 @@ static int tg3_open(struct net_device *dev)
 
        tg3_full_unlock(tp);
 
+       /*
+        * Setup interrupts first so we know how
+        * many NAPI resources to allocate
+        */
+       tg3_ints_init(tp);
+
        /* The placement of this call is tied
         * to the setup and use of Host TX descriptors.
         */
        err = tg3_alloc_consistent(tp);
        if (err)
-               return err;
-
-       tg3_ints_init(tp);
+               goto err_out1;
 
-       napi_enable(&tp->napi[0].napi);
+       tg3_napi_enable(tp);
 
-       err = tg3_request_irq(tp);
+       for (i = 0; i < tp->irq_cnt; i++) {
+               struct tg3_napi *tnapi = &tp->napi[i];
+               err = tg3_request_irq(tp, i);
+               if (err) {
+                       for (i--; i >= 0; i--)
+                               free_irq(tnapi->irq_vec, tnapi);
+                       break;
+               }
+       }
 
        if (err)
-               goto err_out1;
+               goto err_out2;
 
        tg3_full_lock(tp, 0);
 
@@ -7993,7 +8837,7 @@ static int tg3_open(struct net_device *dev)
        tg3_full_unlock(tp);
 
        if (err)
-               goto err_out2;
+               goto err_out3;
 
        if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
                err = tg3_test_msi(tp);
@@ -8004,16 +8848,17 @@ static int tg3_open(struct net_device *dev)
                        tg3_free_rings(tp);
                        tg3_full_unlock(tp);
 
-                       goto err_out1;
+                       goto err_out2;
                }
 
-               if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
-                       if (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI) {
-                               u32 val = tr32(PCIE_TRANSACTION_CFG);
+               if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 &&
+                   GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57765 &&
+                   (tp->tg3_flags2 & TG3_FLG2_USING_MSI) &&
+                   (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI)) {
+                       u32 val = tr32(PCIE_TRANSACTION_CFG);
 
-                               tw32(PCIE_TRANSACTION_CFG,
-                                    val | PCIE_TRANS_CFG_1SHOT_MSI);
-                       }
+                       tw32(PCIE_TRANSACTION_CFG,
+                            val | PCIE_TRANS_CFG_1SHOT_MSI);
                }
        }
 
@@ -8027,17 +8872,22 @@ static int tg3_open(struct net_device *dev)
 
        tg3_full_unlock(tp);
 
-       netif_start_queue(dev);
+       netif_tx_start_all_queues(dev);
 
        return 0;
 
+err_out3:
+       for (i = tp->irq_cnt - 1; i >= 0; i--) {
+               struct tg3_napi *tnapi = &tp->napi[i];
+               free_irq(tnapi->irq_vec, tnapi);
+       }
+
 err_out2:
-       free_irq(tp->pdev->irq, &tp->napi[0]);
+       tg3_napi_disable(tp);
+       tg3_free_consistent(tp);
 
 err_out1:
-       napi_disable(&tp->napi[0].napi);
        tg3_ints_fini(tp);
-       tg3_free_consistent(tp);
        return err;
 }
 
@@ -8276,15 +9126,18 @@ static struct tg3_ethtool_stats *tg3_get_estats(struct tg3 *);
 
 static int tg3_close(struct net_device *dev)
 {
+       int i;
        struct tg3 *tp = netdev_priv(dev);
 
-       napi_disable(&tp->napi[0].napi);
+       tg3_napi_disable(tp);
        cancel_work_sync(&tp->reset_task);
 
-       netif_stop_queue(dev);
+       netif_tx_stop_all_queues(dev);
 
        del_timer_sync(&tp->timer);
 
+       tg3_phy_stop(tp);
+
        tg3_full_lock(tp, 1);
 #if 0
        tg3_dump_state(tp);
@@ -8298,7 +9151,10 @@ static int tg3_close(struct net_device *dev)
 
        tg3_full_unlock(tp);
 
-       free_irq(tp->pdev->irq, &tp->napi[0]);
+       for (i = tp->irq_cnt - 1; i >= 0; i--) {
+               struct tg3_napi *tnapi = &tp->napi[i];
+               free_irq(tnapi->irq_vec, tnapi);
+       }
 
        tg3_ints_fini(tp);
 
@@ -8837,9 +9693,11 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
        struct tg3 *tp = netdev_priv(dev);
 
        if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+               struct phy_device *phydev;
                if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
                        return -EAGAIN;
-               return phy_ethtool_gset(tp->mdio_bus->phy_map[PHY_ADDR], cmd);
+               phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
+               return phy_ethtool_gset(phydev, cmd);
        }
 
        cmd->supported = (SUPPORTED_Autoneg);
@@ -8865,7 +9723,7 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                cmd->speed = tp->link_config.active_speed;
                cmd->duplex = tp->link_config.active_duplex;
        }
-       cmd->phy_address = PHY_ADDR;
+       cmd->phy_address = tp->phy_addr;
        cmd->transceiver = XCVR_INTERNAL;
        cmd->autoneg = tp->link_config.autoneg;
        cmd->maxtxpkt = 0;
@@ -8878,9 +9736,11 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
        struct tg3 *tp = netdev_priv(dev);
 
        if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+               struct phy_device *phydev;
                if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
                        return -EAGAIN;
-               return phy_ethtool_sset(tp->mdio_bus->phy_map[PHY_ADDR], cmd);
+               phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
+               return phy_ethtool_sset(phydev, cmd);
        }
 
        if (cmd->autoneg != AUTONEG_ENABLE &&
@@ -9033,10 +9893,12 @@ static int tg3_set_tso(struct net_device *dev, u32 value)
                return 0;
        }
        if ((dev->features & NETIF_F_IPV6_CSUM) &&
-           (tp->tg3_flags2 & TG3_FLG2_HW_TSO_2)) {
+           ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) ||
+            (tp->tg3_flags2 & TG3_FLG2_HW_TSO_3))) {
                if (value) {
                        dev->features |= NETIF_F_TSO6;
-                       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
+                       if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_3) ||
+                           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
                            (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
                             GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX) ||
                            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
@@ -9062,7 +9924,7 @@ static int tg3_nway_reset(struct net_device *dev)
        if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
                if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
                        return -EAGAIN;
-               r = phy_start_aneg(tp->mdio_bus->phy_map[PHY_ADDR]);
+               r = phy_start_aneg(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]);
        } else {
                u32 bmcr;
 
@@ -9108,7 +9970,7 @@ static void tg3_get_ringparam(struct net_device *dev, struct ethtool_ringparam *
 static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
 {
        struct tg3 *tp = netdev_priv(dev);
-       int irq_sync = 0, err = 0;
+       int i, irq_sync = 0, err = 0;
 
        if ((ering->rx_pending > TG3_RX_RING_SIZE - 1) ||
            (ering->rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) ||
@@ -9132,7 +9994,9 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e
            tp->rx_pending > 63)
                tp->rx_pending = 63;
        tp->rx_jumbo_pending = ering->rx_jumbo_pending;
-       tp->napi[0].tx_pending = ering->tx_pending;
+
+       for (i = 0; i < TG3_IRQ_MAX_VECS; i++)
+               tp->napi[i].tx_pending = ering->tx_pending;
 
        if (netif_running(dev)) {
                tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
@@ -9179,7 +10043,7 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam
                        u32 newadv;
                        struct phy_device *phydev;
 
-                       phydev = tp->mdio_bus->phy_map[PHY_ADDR];
+                       phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
 
                        if (epause->rx_pause) {
                                if (epause->tx_pause)
@@ -9811,12 +10675,27 @@ static int tg3_test_memory(struct tg3 *tp)
                { 0x00008000, 0x01000},
                { 0x00010000, 0x01000},
                { 0xffffffff, 0x00000}
+       }, mem_tbl_5717[] = {
+               { 0x00000200, 0x00008},
+               { 0x00010000, 0x0a000},
+               { 0x00020000, 0x13c00},
+               { 0xffffffff, 0x00000}
+       }, mem_tbl_57765[] = {
+               { 0x00000200, 0x00008},
+               { 0x00004000, 0x00800},
+               { 0x00006000, 0x09800},
+               { 0x00010000, 0x0a000},
+               { 0xffffffff, 0x00000}
        };
        struct mem_entry *mem_tbl;
        int err = 0;
        int i;
 
-       if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
+               mem_tbl = mem_tbl_5717;
+       else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
+               mem_tbl = mem_tbl_57765;
+       else if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
                mem_tbl = mem_tbl_5755;
        else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
                mem_tbl = mem_tbl_5906;
@@ -9840,7 +10719,7 @@ static int tg3_test_memory(struct tg3 *tp)
 static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
 {
        u32 mac_mode, rx_start_idx, rx_idx, tx_idx, opaque_key;
-       u32 desc_idx;
+       u32 desc_idx, coal_now;
        struct sk_buff *skb, *rx_skb;
        u8 *tx_data;
        dma_addr_t map;
@@ -9849,8 +10728,14 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
        struct tg3_napi *tnapi, *rnapi;
        struct tg3_rx_prodring_set *tpr = &tp->prodring[0];
 
-       tnapi = &tp->napi[0];
-       rnapi = &tp->napi[0];
+       if (tp->irq_cnt > 1) {
+               tnapi = &tp->napi[1];
+               rnapi = &tp->napi[1];
+       } else {
+               tnapi = &tp->napi[0];
+               rnapi = &tp->napi[0];
+       }
+       coal_now = tnapi->coal_now | rnapi->coal_now;
 
        if (loopback_mode == TG3_MAC_LOOPBACK) {
                /* HW errata - mac loopback fails in some cases on 5780.
@@ -9927,9 +10812,13 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
                tx_data[i] = (u8) (i & 0xff);
 
        map = pci_map_single(tp->pdev, skb->data, tx_len, PCI_DMA_TODEVICE);
+       if (pci_dma_mapping_error(tp->pdev, map)) {
+               dev_kfree_skb(skb);
+               return -EIO;
+       }
 
        tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE |
-            HOSTCC_MODE_NOW);
+              rnapi->coal_now);
 
        udelay(10);
 
@@ -9947,10 +10836,10 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
 
        udelay(10);
 
-       /* 250 usec to allow enough time on some 10/100 Mbps devices.  */
-       for (i = 0; i < 25; i++) {
+       /* 350 usec to allow enough time on some 10/100 Mbps devices.  */
+       for (i = 0; i < 35; i++) {
                tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE |
-                      HOSTCC_MODE_NOW);
+                      coal_now);
 
                udelay(10);
 
@@ -10153,14 +11042,16 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
        int err;
 
        if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+               struct phy_device *phydev;
                if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
                        return -EAGAIN;
-               return phy_mii_ioctl(tp->mdio_bus->phy_map[PHY_ADDR], data, cmd);
+               phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
+               return phy_mii_ioctl(phydev, data, cmd);
        }
 
        switch(cmd) {
        case SIOCGMIIPHY:
-               data->phy_id = PHY_ADDR;
+               data->phy_id = tp->phy_addr;
 
                /* fallthru */
        case SIOCGMIIREG: {
@@ -10185,9 +11076,6 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
                if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)
                        break;                  /* We have no PHY */
 
-               if (!capable(CAP_NET_ADMIN))
-                       return -EPERM;
-
                if (tp->link_config.phy_is_low_power)
                        return -EAGAIN;
 
@@ -10443,6 +11331,33 @@ static void __devinit tg3_get_nvram_info(struct tg3 *tp)
        }
 }
 
+static void __devinit tg3_nvram_get_pagesize(struct tg3 *tp, u32 nvmcfg1)
+{
+       switch (nvmcfg1 & NVRAM_CFG1_5752PAGE_SIZE_MASK) {
+       case FLASH_5752PAGE_SIZE_256:
+               tp->nvram_pagesize = 256;
+               break;
+       case FLASH_5752PAGE_SIZE_512:
+               tp->nvram_pagesize = 512;
+               break;
+       case FLASH_5752PAGE_SIZE_1K:
+               tp->nvram_pagesize = 1024;
+               break;
+       case FLASH_5752PAGE_SIZE_2K:
+               tp->nvram_pagesize = 2048;
+               break;
+       case FLASH_5752PAGE_SIZE_4K:
+               tp->nvram_pagesize = 4096;
+               break;
+       case FLASH_5752PAGE_SIZE_264:
+               tp->nvram_pagesize = 264;
+               break;
+       case FLASH_5752PAGE_SIZE_528:
+               tp->nvram_pagesize = 528;
+               break;
+       }
+}
+
 static void __devinit tg3_get_5752_nvram_info(struct tg3 *tp)
 {
        u32 nvcfg1;
@@ -10451,7 +11366,7 @@ static void __devinit tg3_get_5752_nvram_info(struct tg3 *tp)
 
        /* NVRAM protection for TPM */
        if (nvcfg1 & (1 << 27))
-               tp->tg3_flags2 |= TG3_FLG2_PROTECTED_NVRAM;
+               tp->tg3_flags3 |= TG3_FLG3_PROTECTED_NVRAM;
 
        switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
        case FLASH_5752VENDOR_ATMEL_EEPROM_64KHZ:
@@ -10474,26 +11389,7 @@ static void __devinit tg3_get_5752_nvram_info(struct tg3 *tp)
        }
 
        if (tp->tg3_flags2 & TG3_FLG2_FLASH) {
-               switch (nvcfg1 & NVRAM_CFG1_5752PAGE_SIZE_MASK) {
-               case FLASH_5752PAGE_SIZE_256:
-                       tp->nvram_pagesize = 256;
-                       break;
-               case FLASH_5752PAGE_SIZE_512:
-                       tp->nvram_pagesize = 512;
-                       break;
-               case FLASH_5752PAGE_SIZE_1K:
-                       tp->nvram_pagesize = 1024;
-                       break;
-               case FLASH_5752PAGE_SIZE_2K:
-                       tp->nvram_pagesize = 2048;
-                       break;
-               case FLASH_5752PAGE_SIZE_4K:
-                       tp->nvram_pagesize = 4096;
-                       break;
-               case FLASH_5752PAGE_SIZE_264:
-                       tp->nvram_pagesize = 264;
-                       break;
-               }
+               tg3_nvram_get_pagesize(tp, nvcfg1);
        } else {
                /* For eeprom, set pagesize to maximum eeprom size */
                tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
@@ -10511,7 +11407,7 @@ static void __devinit tg3_get_5755_nvram_info(struct tg3 *tp)
 
        /* NVRAM protection for TPM */
        if (nvcfg1 & (1 << 27)) {
-               tp->tg3_flags2 |= TG3_FLG2_PROTECTED_NVRAM;
+               tp->tg3_flags3 |= TG3_FLG3_PROTECTED_NVRAM;
                protect = 1;
        }
 
@@ -10605,7 +11501,7 @@ static void __devinit tg3_get_5761_nvram_info(struct tg3 *tp)
 
        /* NVRAM protection for TPM */
        if (nvcfg1 & (1 << 27)) {
-               tp->tg3_flags2 |= TG3_FLG2_PROTECTED_NVRAM;
+               tp->tg3_flags3 |= TG3_FLG3_PROTECTED_NVRAM;
                protect = 1;
        }
 
@@ -10746,34 +11642,84 @@ static void __devinit tg3_get_57780_nvram_info(struct tg3 *tp)
                return;
        }
 
-       switch (nvcfg1 & NVRAM_CFG1_5752PAGE_SIZE_MASK) {
-       case FLASH_5752PAGE_SIZE_256:
-               tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
-               tp->nvram_pagesize = 256;
-               break;
-       case FLASH_5752PAGE_SIZE_512:
-               tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
-               tp->nvram_pagesize = 512;
-               break;
-       case FLASH_5752PAGE_SIZE_1K:
-               tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
-               tp->nvram_pagesize = 1024;
-               break;
-       case FLASH_5752PAGE_SIZE_2K:
-               tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
-               tp->nvram_pagesize = 2048;
-               break;
-       case FLASH_5752PAGE_SIZE_4K:
+       tg3_nvram_get_pagesize(tp, nvcfg1);
+       if (tp->nvram_pagesize != 264 && tp->nvram_pagesize != 528)
                tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
-               tp->nvram_pagesize = 4096;
-               break;
-       case FLASH_5752PAGE_SIZE_264:
-               tp->nvram_pagesize = 264;
+}
+
+
+static void __devinit tg3_get_5717_nvram_info(struct tg3 *tp)
+{
+       u32 nvcfg1;
+
+       nvcfg1 = tr32(NVRAM_CFG1);
+
+       switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
+       case FLASH_5717VENDOR_ATMEL_EEPROM:
+       case FLASH_5717VENDOR_MICRO_EEPROM:
+               tp->nvram_jedecnum = JEDEC_ATMEL;
+               tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+               tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
+
+               nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
+               tw32(NVRAM_CFG1, nvcfg1);
+               return;
+       case FLASH_5717VENDOR_ATMEL_MDB011D:
+       case FLASH_5717VENDOR_ATMEL_ADB011B:
+       case FLASH_5717VENDOR_ATMEL_ADB011D:
+       case FLASH_5717VENDOR_ATMEL_MDB021D:
+       case FLASH_5717VENDOR_ATMEL_ADB021B:
+       case FLASH_5717VENDOR_ATMEL_ADB021D:
+       case FLASH_5717VENDOR_ATMEL_45USPT:
+               tp->nvram_jedecnum = JEDEC_ATMEL;
+               tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+               tp->tg3_flags2 |= TG3_FLG2_FLASH;
+
+               switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
+               case FLASH_5717VENDOR_ATMEL_MDB021D:
+               case FLASH_5717VENDOR_ATMEL_ADB021B:
+               case FLASH_5717VENDOR_ATMEL_ADB021D:
+                       tp->nvram_size = TG3_NVRAM_SIZE_256KB;
+                       break;
+               default:
+                       tp->nvram_size = TG3_NVRAM_SIZE_128KB;
+                       break;
+               }
                break;
-       case FLASH_5752PAGE_SIZE_528:
-               tp->nvram_pagesize = 528;
+       case FLASH_5717VENDOR_ST_M_M25PE10:
+       case FLASH_5717VENDOR_ST_A_M25PE10:
+       case FLASH_5717VENDOR_ST_M_M45PE10:
+       case FLASH_5717VENDOR_ST_A_M45PE10:
+       case FLASH_5717VENDOR_ST_M_M25PE20:
+       case FLASH_5717VENDOR_ST_A_M25PE20:
+       case FLASH_5717VENDOR_ST_M_M45PE20:
+       case FLASH_5717VENDOR_ST_A_M45PE20:
+       case FLASH_5717VENDOR_ST_25USPT:
+       case FLASH_5717VENDOR_ST_45USPT:
+               tp->nvram_jedecnum = JEDEC_ST;
+               tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+               tp->tg3_flags2 |= TG3_FLG2_FLASH;
+
+               switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
+               case FLASH_5717VENDOR_ST_M_M25PE20:
+               case FLASH_5717VENDOR_ST_A_M25PE20:
+               case FLASH_5717VENDOR_ST_M_M45PE20:
+               case FLASH_5717VENDOR_ST_A_M45PE20:
+                       tp->nvram_size = TG3_NVRAM_SIZE_256KB;
+                       break;
+               default:
+                       tp->nvram_size = TG3_NVRAM_SIZE_128KB;
+                       break;
+               }
                break;
+       default:
+               tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM;
+               return;
        }
+
+       tg3_nvram_get_pagesize(tp, nvcfg1);
+       if (tp->nvram_pagesize != 264 && tp->nvram_pagesize != 528)
+               tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
 }
 
 /* Chips other than 5700/5701 use the NVRAM for fetching info. */
@@ -10816,8 +11762,11 @@ static void __devinit tg3_nvram_init(struct tg3 *tp)
                        tg3_get_5761_nvram_info(tp);
                else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
                        tg3_get_5906_nvram_info(tp);
-               else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
+               else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
+                        GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
                        tg3_get_57780_nvram_info(tp);
+               else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
+                       tg3_get_5717_nvram_info(tp);
                else
                        tg3_get_nvram_info(tp);
 
@@ -11055,7 +12004,7 @@ static int tg3_nvram_write_block(struct tg3 *tp, u32 offset, u32 len, u8 *buf)
 
                tg3_enable_nvram_access(tp);
                if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
-                   !(tp->tg3_flags2 & TG3_FLG2_PROTECTED_NVRAM))
+                   !(tp->tg3_flags3 & TG3_FLG3_PROTECTED_NVRAM))
                        tw32(NVRAM_WRITE1, 0x406);
 
                grc_mode = tr32(GRC_MODE);
@@ -11228,7 +12177,8 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
 
                tp->phy_id = eeprom_phy_id;
                if (eeprom_phy_serdes) {
-                       if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)
+                       if ((tp->tg3_flags2 & TG3_FLG2_5780_CLASS) ||
+                           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
                                tp->tg3_flags2 |= TG3_FLG2_MII_SERDES;
                        else
                                tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES;
@@ -11539,7 +12489,7 @@ skip_phy_reset:
 
 static void __devinit tg3_read_partno(struct tg3 *tp)
 {
-       unsigned char vpd_data[256];   /* in little-endian format */
+       unsigned char vpd_data[TG3_NVM_VPD_LEN];   /* in little-endian format */
        unsigned int i;
        u32 magic;
 
@@ -11548,48 +12498,37 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
                goto out_not_found;
 
        if (magic == TG3_EEPROM_MAGIC) {
-               for (i = 0; i < 256; i += 4) {
+               for (i = 0; i < TG3_NVM_VPD_LEN; i += 4) {
                        u32 tmp;
 
                        /* The data is in little-endian format in NVRAM.
                         * Use the big-endian read routines to preserve
                         * the byte order as it exists in NVRAM.
                         */
-                       if (tg3_nvram_read_be32(tp, 0x100 + i, &tmp))
+                       if (tg3_nvram_read_be32(tp, TG3_NVM_VPD_OFF + i, &tmp))
                                goto out_not_found;
 
                        memcpy(&vpd_data[i], &tmp, sizeof(tmp));
                }
        } else {
-               int vpd_cap;
-
-               vpd_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_VPD);
-               for (i = 0; i < 256; i += 4) {
-                       u32 tmp, j = 0;
-                       __le32 v;
-                       u16 tmp16;
-
-                       pci_write_config_word(tp->pdev, vpd_cap + PCI_VPD_ADDR,
-                                             i);
-                       while (j++ < 100) {
-                               pci_read_config_word(tp->pdev, vpd_cap +
-                                                    PCI_VPD_ADDR, &tmp16);
-                               if (tmp16 & 0x8000)
-                                       break;
-                               msleep(1);
-                       }
-                       if (!(tmp16 & 0x8000))
+               ssize_t cnt;
+               unsigned int pos = 0, i = 0;
+
+               for (; pos < TG3_NVM_VPD_LEN && i < 3; i++, pos += cnt) {
+                       cnt = pci_read_vpd(tp->pdev, pos,
+                                          TG3_NVM_VPD_LEN - pos,
+                                          &vpd_data[pos]);
+                       if (cnt == -ETIMEDOUT || -EINTR)
+                               cnt = 0;
+                       else if (cnt < 0)
                                goto out_not_found;
-
-                       pci_read_config_dword(tp->pdev, vpd_cap + PCI_VPD_DATA,
-                                             &tmp);
-                       v = cpu_to_le32(tmp);
-                       memcpy(&vpd_data[i], &v, sizeof(v));
                }
+               if (pos != TG3_NVM_VPD_LEN)
+                       goto out_not_found;
        }
 
        /* Now parse and find the part number. */
-       for (i = 0; i < 254; ) {
+       for (i = 0; i < TG3_NVM_VPD_LEN - 2; ) {
                unsigned char val = vpd_data[i];
                unsigned int block_end;
 
@@ -11608,7 +12547,7 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
                              (vpd_data[i + 2] << 8)));
                i += 3;
 
-               if (block_end > 256)
+               if (block_end > TG3_NVM_VPD_LEN)
                        goto out_not_found;
 
                while (i < (block_end - 2)) {
@@ -11617,7 +12556,8 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
                                int partno_len = vpd_data[i + 2];
 
                                i += 3;
-                               if (partno_len > 24 || (partno_len + i) > 256)
+                               if (partno_len > TG3_BPN_SIZE ||
+                                   (partno_len + i) > TG3_NVM_VPD_LEN)
                                        goto out_not_found;
 
                                memcpy(tp->board_part_number,
@@ -11648,6 +12588,8 @@ out_not_found:
        else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 &&
                 tp->pdev->device == TG3PCI_DEVICE_TIGON3_57788)
                strcpy(tp->board_part_number, "BCM57788");
+       else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
+               strcpy(tp->board_part_number, "BCM57765");
        else
                strcpy(tp->board_part_number, "none");
 }
@@ -11931,8 +12873,25 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_USE_PROD_ID_REG) {
                u32 prod_id_asic_rev;
 
-               pci_read_config_dword(tp->pdev, TG3PCI_PRODID_ASICREV,
-                                     &prod_id_asic_rev);
+               if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717 ||
+                   tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 ||
+                   tp->pdev->device == TG3PCI_DEVICE_TIGON3_5724)
+                       pci_read_config_dword(tp->pdev,
+                                             TG3PCI_GEN2_PRODID_ASICREV,
+                                             &prod_id_asic_rev);
+               else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57781 ||
+                        tp->pdev->device == TG3PCI_DEVICE_TIGON3_57785 ||
+                        tp->pdev->device == TG3PCI_DEVICE_TIGON3_57761 ||
+                        tp->pdev->device == TG3PCI_DEVICE_TIGON3_57765 ||
+                        tp->pdev->device == TG3PCI_DEVICE_TIGON3_57791 ||
+                        tp->pdev->device == TG3PCI_DEVICE_TIGON3_57795)
+                       pci_read_config_dword(tp->pdev,
+                                             TG3PCI_GEN15_PRODID_ASICREV,
+                                             &prod_id_asic_rev);
+               else
+                       pci_read_config_dword(tp->pdev, TG3PCI_PRODID_ASICREV,
+                                             &prod_id_asic_rev);
+
                tp->pci_chip_rev_id = prod_id_asic_rev;
        }
 
@@ -12070,8 +13029,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL,
                               tp->misc_host_ctrl);
 
-       if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) ||
-           (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714))
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
                tp->pdev_peer = tg3_find_peer(tp);
 
        /* Intentionally exclude ASIC_REV_5906 */
@@ -12080,7 +13040,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
                tp->tg3_flags3 |= TG3_FLG3_5755_PLUS;
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 ||
@@ -12106,6 +13068,30 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                        tp->dev->features |= NETIF_F_IPV6_CSUM;
        }
 
+       /* Determine TSO capabilities */
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
+               tp->tg3_flags2 |= TG3_FLG2_HW_TSO_3;
+       else if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) ||
+                GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+               tp->tg3_flags2 |= TG3_FLG2_HW_TSO_2;
+       else if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) {
+               tp->tg3_flags2 |= TG3_FLG2_HW_TSO_1 | TG3_FLG2_TSO_BUG;
+               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 &&
+                   tp->pci_chip_rev_id >= CHIPREV_ID_5750_C2)
+                       tp->tg3_flags2 &= ~TG3_FLG2_TSO_BUG;
+       } else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 &&
+                  GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701 &&
+                  tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) {
+               tp->tg3_flags2 |= TG3_FLG2_TSO_BUG;
+               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)
+                       tp->fw_needed = FIRMWARE_TG3TSO5;
+               else
+                       tp->fw_needed = FIRMWARE_TG3TSO;
+       }
+
+       tp->irq_max = 1;
+
        if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) {
                tp->tg3_flags |= TG3_FLAG_SUPPORT_MSI;
                if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_AX ||
@@ -12117,19 +13103,31 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 
                if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) ||
                    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
-                       tp->tg3_flags2 |= TG3_FLG2_HW_TSO_2;
                        tp->tg3_flags2 |= TG3_FLG2_1SHOT_MSI;
-               } else {
-                       tp->tg3_flags2 |= TG3_FLG2_HW_TSO_1 | TG3_FLG2_TSO_BUG;
-                       if (GET_ASIC_REV(tp->pci_chip_rev_id) ==
-                               ASIC_REV_5750 &&
-                           tp->pci_chip_rev_id >= CHIPREV_ID_5750_C2)
-                               tp->tg3_flags2 &= ~TG3_FLG2_TSO_BUG;
                }
+
+               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) {
+                       tp->tg3_flags |= TG3_FLAG_SUPPORT_MSIX;
+                       tp->irq_max = TG3_IRQ_MAX_VECS;
+               }
+       }
+
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+               tp->tg3_flags3 |= TG3_FLG3_SHORT_DMA_BUG;
+       else if (!(tp->tg3_flags3 & TG3_FLG3_5755_PLUS)) {
+               tp->tg3_flags3 |= TG3_FLG3_4G_DMA_BNDRY_BUG;
+               tp->tg3_flags3 |= TG3_FLG3_40BIT_DMA_LIMIT_BUG;
        }
 
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
+               tp->tg3_flags3 |= TG3_FLG3_USE_JUMBO_BDFLAG;
+
        if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
-            (tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
+            (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) ||
+                (tp->tg3_flags3 & TG3_FLG3_USE_JUMBO_BDFLAG))
                tp->tg3_flags |= TG3_FLAG_JUMBO_CAPABLE;
 
        pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE,
@@ -12154,6 +13152,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                            tp->pci_chip_rev_id == CHIPREV_ID_57780_A0 ||
                            tp->pci_chip_rev_id == CHIPREV_ID_57780_A1)
                                tp->tg3_flags3 |= TG3_FLG3_CLKREQ_BUG;
+               } else if (tp->pci_chip_rev_id == CHIPREV_ID_5717_A0) {
+                       tp->tg3_flags3 |= TG3_FLG3_L1PLLPD_EN;
                }
        } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785) {
                tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS;
@@ -12263,7 +13263,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                tp->write32 = tg3_write_flush_reg32;
        }
 
-
        if ((tp->tg3_flags & TG3_FLAG_TXD_MBOX_HWBUG) ||
            (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER)) {
                tp->write32_tx_mbox = tg3_write32_tx_mbox;
@@ -12322,7 +13321,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
                tp->tg3_flags |= TG3_FLAG_CPMU_PRESENT;
 
        /* Set up tp->grc_local_ctrl before calling tg3_set_power_state().
@@ -12341,7 +13342,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE3;
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
                tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL;
 
        if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761 ||
@@ -12400,7 +13402,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        if ((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
            !(tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) &&
            GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785 &&
-           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57780) {
+           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57780 &&
+           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 &&
+           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57765) {
                if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
                    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
                    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
@@ -12435,15 +13439,15 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
                tp->tg3_flags3 |= TG3_FLG3_USE_PHYLIB;
 
-       if ((tp->pci_chip_rev_id == CHIPREV_ID_57780_A1 &&
-            tr32(RCVLPC_STATS_ENABLE) & RCVLPC_STATSENAB_ASF_FIX) ||
-           tp->pci_chip_rev_id == CHIPREV_ID_57780_A0)
-               tp->tg3_flags3 |= TG3_FLG3_TOGGLE_10_100_L1PLLPD;
-
        err = tg3_mdio_init(tp);
        if (err)
                return err;
 
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 &&
+           (tp->pci_chip_rev_id != CHIPREV_ID_5717_A0 ||
+                (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)))
+               return -ENOTSUPP;
+
        /* Initialize data/descriptor byte/word swapping. */
        val = tr32(GRC_MODE);
        val &= GRC_MODE_HOST_STACKUP;
@@ -12642,8 +13646,10 @@ static int __devinit tg3_get_device_address(struct tg3 *tp)
                        tw32_f(NVRAM_CMD, NVRAM_CMD_RESET);
                else
                        tg3_nvram_unlock(tp);
-       }
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+       } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) {
+               if (tr32(TG3_CPMU_STATUS) & TG3_CPMU_STATUS_PCIE_FUNC)
+                       mac_offset = 0xcc;
+       } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
                mac_offset = 0x10;
 
        /* First try to get it from MAC address mailbox. */
@@ -12727,6 +13733,12 @@ static u32 __devinit tg3_calc_dma_bndry(struct tg3 *tp, u32 val)
 #endif
 #endif
 
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) {
+               val = goal ? 0 : DMA_RWCTRL_DIS_CACHE_ALIGNMENT;
+               goto out;
+       }
+
        if (!goal)
                goto out;
 
@@ -12921,7 +13933,7 @@ static int __devinit tg3_test_dma(struct tg3 *tp)
 {
        dma_addr_t buf_dma;
        u32 *buf, saved_dma_rwctrl;
-       int ret;
+       int ret = 0;
 
        buf = pci_alloc_consistent(tp->pdev, TEST_BUFFER_SIZE, &buf_dma);
        if (!buf) {
@@ -12934,6 +13946,10 @@ static int __devinit tg3_test_dma(struct tg3 *tp)
 
        tp->dma_rwctrl = tg3_calc_dma_bndry(tp, tp->dma_rwctrl);
 
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
+               goto out;
+
        if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) {
                /* DMA read watermark not used on PCIE */
                tp->dma_rwctrl |= 0x00180000;
@@ -13006,7 +14022,6 @@ static int __devinit tg3_test_dma(struct tg3 *tp)
        tg3_switch_clocks(tp);
 #endif
 
-       ret = 0;
        if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 &&
            GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701)
                goto out;
@@ -13124,7 +14139,22 @@ static void __devinit tg3_init_link_config(struct tg3 *tp)
 
 static void __devinit tg3_init_bufmgr_config(struct tg3 *tp)
 {
-       if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) {
+               tp->bufmgr_config.mbuf_read_dma_low_water =
+                       DEFAULT_MB_RDMA_LOW_WATER_5705;
+               tp->bufmgr_config.mbuf_mac_rx_low_water =
+                       DEFAULT_MB_MACRX_LOW_WATER_57765;
+               tp->bufmgr_config.mbuf_high_water =
+                       DEFAULT_MB_HIGH_WATER_57765;
+
+               tp->bufmgr_config.mbuf_read_dma_low_water_jumbo =
+                       DEFAULT_MB_RDMA_LOW_WATER_5705;
+               tp->bufmgr_config.mbuf_mac_rx_low_water_jumbo =
+                       DEFAULT_MB_MACRX_LOW_WATER_JUMBO_57765;
+               tp->bufmgr_config.mbuf_high_water_jumbo =
+                       DEFAULT_MB_HIGH_WATER_JUMBO_57765;
+       } else if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
                tp->bufmgr_config.mbuf_read_dma_low_water =
                        DEFAULT_MB_RDMA_LOW_WATER_5705;
                tp->bufmgr_config.mbuf_mac_rx_low_water =
@@ -13184,6 +14214,9 @@ static char * __devinit tg3_phy_string(struct tg3 *tp)
        case PHY_ID_BCM5756:    return "5722/5756";
        case PHY_ID_BCM5906:    return "5906";
        case PHY_ID_BCM5761:    return "5761";
+       case PHY_ID_BCM5718C:   return "5718C";
+       case PHY_ID_BCM5718S:   return "5718S";
+       case PHY_ID_BCM57765:   return "57765";
        case PHY_ID_BCM8002:    return "8002/serdes";
        case 0:                 return "serdes";
        default:                return "unknown";
@@ -13329,7 +14362,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
        static int tg3_version_printed = 0;
        struct net_device *dev;
        struct tg3 *tp;
-       int err, pm_cap;
+       int i, err, pm_cap;
+       u32 sndmbx, rcvmbx, intmbx;
        char str[40];
        u64 dma_mask, persist_dma_mask;
 
@@ -13361,7 +14395,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
                goto err_out_free_res;
        }
 
-       dev = alloc_etherdev(sizeof(*tp));
+       dev = alloc_etherdev_mq(sizeof(*tp), TG3_IRQ_MAX_VECS);
        if (!dev) {
                printk(KERN_ERR PFX "Etherdev alloc failed, aborting.\n");
                err = -ENOMEM;
@@ -13424,12 +14458,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
        tp->rx_pending = TG3_DEF_RX_RING_PENDING;
        tp->rx_jumbo_pending = TG3_DEF_RX_JUMBO_RING_PENDING;
 
-       tp->napi[0].tp = tp;
-       tp->napi[0].int_mbox = MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW;
-       tp->napi[0].consmbox = MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW;
-       tp->napi[0].prodmbox = MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW;
-       tp->napi[0].tx_pending = TG3_DEF_TX_RING_PENDING;
-       netif_napi_add(dev, &tp->napi[0].napi, tg3_poll, 64);
        dev->ethtool_ops = &tg3_ethtool_ops;
        dev->watchdog_timeo = TG3_TX_TIMEOUT;
        dev->irq = pdev->irq;
@@ -13441,8 +14469,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
                goto err_out_iounmap;
        }
 
-       if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+       if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) &&
+           tp->pci_chip_rev_id != CHIPREV_ID_5717_A0)
                dev->netdev_ops = &tg3_netdev_ops;
        else
                dev->netdev_ops = &tg3_netdev_ops_dma_bug;
@@ -13489,37 +14517,32 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
 
        tg3_init_bufmgr_config(tp);
 
-       if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0)
-               tp->fw_needed = FIRMWARE_TG3;
-
-       if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) {
+       /* Selectively allow TSO based on operating conditions */
+       if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO) ||
+           (tp->fw_needed && !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)))
                tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
-       }
-       else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 ||
-           tp->pci_chip_rev_id == CHIPREV_ID_5705_A0 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906 ||
-           (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0) {
-               tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE;
-       } else {
-               tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE | TG3_FLG2_TSO_BUG;
-               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)
-                       tp->fw_needed = FIRMWARE_TG3TSO5;
-               else
-                       tp->fw_needed = FIRMWARE_TG3TSO;
+       else {
+               tp->tg3_flags2 &= ~(TG3_FLG2_TSO_CAPABLE | TG3_FLG2_TSO_BUG);
+               tp->fw_needed = NULL;
        }
 
+       if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0)
+               tp->fw_needed = FIRMWARE_TG3;
+
        /* TSO is on by default on chips that support hardware TSO.
         * Firmware TSO on older chips gives lower performance, so it
         * is off by default, but can be enabled using ethtool.
         */
-       if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) {
-               if (dev->features & NETIF_F_IP_CSUM)
-                       dev->features |= NETIF_F_TSO;
-               if ((dev->features & NETIF_F_IPV6_CSUM) &&
-                   (tp->tg3_flags2 & TG3_FLG2_HW_TSO_2))
+       if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO) &&
+           (dev->features & NETIF_F_IP_CSUM))
+               dev->features |= NETIF_F_TSO;
+
+       if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) ||
+           (tp->tg3_flags2 & TG3_FLG2_HW_TSO_3)) {
+               if (dev->features & NETIF_F_IPV6_CSUM)
                        dev->features |= NETIF_F_TSO6;
-               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
+               if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_3) ||
+                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
                    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
                     GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX) ||
                        GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
@@ -13527,7 +14550,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
                        dev->features |= NETIF_F_TSO_ECN;
        }
 
-
        if (tp->pci_chip_rev_id == CHIPREV_ID_5705_A1 &&
            !(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) &&
            !(tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH)) {
@@ -13539,7 +14561,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
        if (err) {
                printk(KERN_ERR PFX "Could not obtain valid ethernet address, "
                       "aborting.\n");
-               goto err_out_fw;
+               goto err_out_iounmap;
        }
 
        if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
@@ -13548,7 +14570,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
                        printk(KERN_ERR PFX "Cannot map APE registers, "
                               "aborting.\n");
                        err = -ENOMEM;
-                       goto err_out_fw;
+                       goto err_out_iounmap;
                }
 
                tg3_ape_lock_init(tp);
@@ -13578,6 +14600,53 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
        tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
        tp->link_config.flowctrl = FLOW_CTRL_TX | FLOW_CTRL_RX;
 
+       intmbx = MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW;
+       rcvmbx = MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW;
+       sndmbx = MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW;
+       for (i = 0; i < TG3_IRQ_MAX_VECS; i++) {
+               struct tg3_napi *tnapi = &tp->napi[i];
+
+               tnapi->tp = tp;
+               tnapi->tx_pending = TG3_DEF_TX_RING_PENDING;
+
+               tnapi->int_mbox = intmbx;
+               if (i < 4)
+                       intmbx += 0x8;
+               else
+                       intmbx += 0x4;
+
+               tnapi->consmbox = rcvmbx;
+               tnapi->prodmbox = sndmbx;
+
+               if (i) {
+                       tnapi->coal_now = HOSTCC_MODE_COAL_VEC1_NOW << (i - 1);
+                       netif_napi_add(dev, &tnapi->napi, tg3_poll_msix, 64);
+               } else {
+                       tnapi->coal_now = HOSTCC_MODE_NOW;
+                       netif_napi_add(dev, &tnapi->napi, tg3_poll, 64);
+               }
+
+               if (!(tp->tg3_flags & TG3_FLAG_SUPPORT_MSIX))
+                       break;
+
+               /*
+                * If we support MSIX, we'll be using RSS.  If we're using
+                * RSS, the first vector only handles link interrupts and the
+                * remaining vectors handle rx and tx interrupts.  Reuse the
+                * mailbox values for the next iteration.  The values we setup
+                * above are still useful for the single vectored mode.
+                */
+               if (!i)
+                       continue;
+
+               rcvmbx += 0x8;
+
+               if (sndmbx & 0x4)
+                       sndmbx -= 0x4;
+               else
+                       sndmbx += 0xc;
+       }
+
        tg3_init_coal(tp);
 
        pci_set_drvdata(pdev, dev);
@@ -13596,13 +14665,14 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
               tg3_bus_string(tp, str),
               dev->dev_addr);
 
-       if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED)
+       if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) {
+               struct phy_device *phydev;
+               phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
                printk(KERN_INFO
                       "%s: attached PHY driver [%s] (mii_bus:phy_addr=%s)\n",
-                      tp->dev->name,
-                      tp->mdio_bus->phy_map[PHY_ADDR]->drv->name,
-                      dev_name(&tp->mdio_bus->phy_map[PHY_ADDR]->dev));
-       else
+                      tp->dev->name, phydev->drv->name,
+                      dev_name(&phydev->dev));
+       } else
                printk(KERN_INFO
                       "%s: attached PHY is %s (%s Ethernet) (WireSpeed[%d])\n",
                       tp->dev->name, tg3_phy_string(tp),
@@ -13631,10 +14701,6 @@ err_out_apeunmap:
                tp->aperegs = NULL;
        }
 
-err_out_fw:
-       if (tp->fw)
-               release_firmware(tp->fw);
-
 err_out_iounmap:
        if (tp->regs) {
                iounmap(tp->regs);