tg3: cleanup pci device table vars
[linux-2.6.git] / drivers / net / tg3.c
index 7c2c81a..73eacbd 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-2010 Broadcom Corporation.
+ * Copyright (C) 2005-2011 Broadcom Corporation.
  *
  * Firmware is:
  *     Derived from proprietary unpublished source code,
@@ -32,6 +32,7 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/ethtool.h>
+#include <linux/mdio.h>
 #include <linux/mii.h>
 #include <linux/phy.h>
 #include <linux/brcmphy.h>
 #define BAR_0  0
 #define BAR_2  2
 
-#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
-#define TG3_VLAN_TAG_USED 1
-#else
-#define TG3_VLAN_TAG_USED 0
-#endif
-
 #include "tg3.h"
 
 #define DRV_MODULE_NAME                "tg3"
 #define TG3_MAJ_NUM                    3
-#define TG3_MIN_NUM                    112
+#define TG3_MIN_NUM                    117
 #define DRV_MODULE_VERSION     \
        __stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM)
-#define DRV_MODULE_RELDATE     "July 11, 2010"
+#define DRV_MODULE_RELDATE     "January 25, 2011"
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
  * You can't change the ring sizes, but you can change where you place
  * them in the NIC onboard memory.
  */
-#define TG3_RX_RING_SIZE               512
+#define TG3_RX_STD_RING_SIZE(tp) \
+       ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || \
+         GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) ? \
+        RX_STD_MAX_SIZE_5717 : 512)
 #define TG3_DEF_RX_RING_PENDING                200
-#define TG3_RX_JUMBO_RING_SIZE         256
+#define TG3_RX_JMB_RING_SIZE(tp) \
+       ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || \
+         GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) ? \
+        1024 : 256)
 #define TG3_DEF_RX_JUMBO_RING_PENDING  100
 #define TG3_RSS_INDIR_TBL_SIZE         128
 
  * hw multiply/modulo instructions.  Another solution would be to
  * replace things like '% foo' with '& (foo - 1)'.
  */
-#define TG3_RX_RCB_RING_SIZE(tp)       \
-       (((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_RING_BYTES      (sizeof(struct tg3_rx_buffer_desc) * \
-                                TG3_RX_RING_SIZE)
-#define TG3_RX_JUMBO_RING_BYTES        (sizeof(struct tg3_ext_rx_buffer_desc) * \
-                                TG3_RX_JUMBO_RING_SIZE)
-#define TG3_RX_RCB_RING_BYTES(tp) (sizeof(struct tg3_rx_buffer_desc) * \
-                                TG3_RX_RCB_RING_SIZE(tp))
+#define TG3_RX_STD_RING_BYTES(tp) \
+       (sizeof(struct tg3_rx_buffer_desc) * TG3_RX_STD_RING_SIZE(tp))
+#define TG3_RX_JMB_RING_BYTES(tp) \
+       (sizeof(struct tg3_ext_rx_buffer_desc) * TG3_RX_JMB_RING_SIZE(tp))
+#define TG3_RX_RCB_RING_BYTES(tp) \
+       (sizeof(struct tg3_rx_buffer_desc) * (tp->rx_ret_ring_mask + 1))
 #define TG3_TX_RING_BYTES      (sizeof(struct tg3_tx_buffer_desc) * \
                                 TG3_TX_RING_SIZE)
 #define NEXT_TX(N)             (((N) + 1) & (TG3_TX_RING_SIZE - 1))
 
-#define TG3_RX_DMA_ALIGN               16
-#define TG3_RX_HEADROOM                        ALIGN(VLAN_HLEN, TG3_RX_DMA_ALIGN)
-
 #define TG3_DMA_BYTE_ENAB              64
 
 #define TG3_RX_STD_DMA_SZ              1536
 #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_STD_BUFF_RING_SIZE(tp) \
+       (sizeof(struct ring_info) * TG3_RX_STD_RING_SIZE(tp))
 
-#define TG3_RX_JMB_BUFF_RING_SIZE \
-       (sizeof(struct ring_info) * TG3_RX_JUMBO_RING_SIZE)
+#define TG3_RX_JMB_BUFF_RING_SIZE(tp) \
+       (sizeof(struct ring_info) * TG3_RX_JMB_RING_SIZE(tp))
 
 /* Due to a hardware bug, the 5701 can only DMA to memory addresses
  * that are at least dword aligned when used in PCIX mode.  The driver
@@ -221,12 +216,9 @@ static DEFINE_PCI_DEVICE_TABLE(tg3_pci_tbl) = {
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5901_2)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5704S_2)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705F)},
-       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5720)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5721)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5722)},
-       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5750)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5751)},
-       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5750M)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5751M)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5751F)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5752)},
@@ -267,7 +259,6 @@ static DEFINE_PCI_DEVICE_TABLE(tg3_pci_tbl) = {
        {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)},
@@ -755,42 +746,6 @@ static void tg3_int_reenable(struct tg3_napi *tnapi)
                     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 */
-       tg3_napi_disable(tp);
-       netif_tx_disable(tp->dev);
-}
-
-static inline void tg3_netif_start(struct tg3 *tp)
-{
-       /* 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)
-        */
-       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;
@@ -882,7 +837,7 @@ static int tg3_writephy(struct tg3 *tp, int reg, u32 val)
        unsigned int loops;
        int ret;
 
-       if ((tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) &&
+       if ((tp->phy_flags & TG3_PHYFLG_IS_FET) &&
            (reg == MII_TG3_CTRL || reg == MII_TG3_AUX_CTRL))
                return 0;
 
@@ -1178,7 +1133,7 @@ static int tg3_mdio_init(struct tg3 *tp)
        case 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;
+               tp->phy_flags |= TG3_PHYFLG_IS_FET;
                break;
        }
 
@@ -1199,6 +1154,52 @@ static void tg3_mdio_fini(struct tg3 *tp)
        }
 }
 
+static int tg3_phy_cl45_write(struct tg3 *tp, u32 devad, u32 addr, u32 val)
+{
+       int err;
+
+       err = tg3_writephy(tp, MII_TG3_MMD_CTRL, devad);
+       if (err)
+               goto done;
+
+       err = tg3_writephy(tp, MII_TG3_MMD_ADDRESS, addr);
+       if (err)
+               goto done;
+
+       err = tg3_writephy(tp, MII_TG3_MMD_CTRL,
+                          MII_TG3_MMD_CTRL_DATA_NOINC | devad);
+       if (err)
+               goto done;
+
+       err = tg3_writephy(tp, MII_TG3_MMD_ADDRESS, val);
+
+done:
+       return err;
+}
+
+static int tg3_phy_cl45_read(struct tg3 *tp, u32 devad, u32 addr, u32 *val)
+{
+       int err;
+
+       err = tg3_writephy(tp, MII_TG3_MMD_CTRL, devad);
+       if (err)
+               goto done;
+
+       err = tg3_writephy(tp, MII_TG3_MMD_ADDRESS, addr);
+       if (err)
+               goto done;
+
+       err = tg3_writephy(tp, MII_TG3_MMD_CTRL,
+                          MII_TG3_MMD_CTRL_DATA_NOINC | devad);
+       if (err)
+               goto done;
+
+       err = tg3_readphy(tp, MII_TG3_MMD_ADDRESS, val);
+
+done:
+       return err;
+}
+
 /* tp->lock is held. */
 static inline void tg3_generate_fw_event(struct tg3 *tp)
 {
@@ -1271,7 +1272,7 @@ static void tg3_ump_link_report(struct tg3 *tp)
        tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 4, val);
 
        val = 0;
-       if (!(tp->tg3_flags2 & TG3_FLG2_MII_SERDES)) {
+       if (!(tp->phy_flags & TG3_PHYFLG_MII_SERDES)) {
                if (!tg3_readphy(tp, MII_CTRL1000, &reg))
                        val = reg << 16;
                if (!tg3_readphy(tp, MII_STAT1000, &reg))
@@ -1379,7 +1380,7 @@ static void tg3_setup_flow_control(struct tg3 *tp, u32 lcladv, u32 rmtadv)
 
        if (autoneg == AUTONEG_ENABLE &&
            (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG)) {
-               if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)
+               if (tp->phy_flags & TG3_PHYFLG_ANY_SERDES)
                        flowctrl = tg3_resolve_flowctrl_1000X(lcladv, rmtadv);
                else
                        flowctrl = mii_resolve_flowctrl_fdx(lcladv, rmtadv);
@@ -1493,7 +1494,7 @@ static int tg3_phy_init(struct tg3 *tp)
 {
        struct phy_device *phydev;
 
-       if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED)
+       if (tp->phy_flags & TG3_PHYFLG_IS_CONNECTED)
                return 0;
 
        /* Bring the PHY back to a known state. */
@@ -1513,7 +1514,7 @@ static int tg3_phy_init(struct tg3 *tp)
        switch (phydev->interface) {
        case PHY_INTERFACE_MODE_GMII:
        case PHY_INTERFACE_MODE_RGMII:
-               if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) {
+               if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) {
                        phydev->supported &= (PHY_GBIT_FEATURES |
                                              SUPPORTED_Pause |
                                              SUPPORTED_Asym_Pause);
@@ -1530,7 +1531,7 @@ static int tg3_phy_init(struct tg3 *tp)
                return -EINVAL;
        }
 
-       tp->tg3_flags3 |= TG3_FLG3_PHY_CONNECTED;
+       tp->phy_flags |= TG3_PHYFLG_IS_CONNECTED;
 
        phydev->advertising = phydev->supported;
 
@@ -1541,13 +1542,13 @@ static void tg3_phy_start(struct tg3 *tp)
 {
        struct phy_device *phydev;
 
-       if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
+       if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED))
                return;
 
        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;
+       if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) {
+               tp->phy_flags &= ~TG3_PHYFLG_IS_LOW_POWER;
                phydev->speed = tp->link_config.orig_speed;
                phydev->duplex = tp->link_config.orig_duplex;
                phydev->autoneg = tp->link_config.orig_autoneg;
@@ -1561,7 +1562,7 @@ static void tg3_phy_start(struct tg3 *tp)
 
 static void tg3_phy_stop(struct tg3 *tp)
 {
-       if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
+       if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED))
                return;
 
        phy_stop(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]);
@@ -1569,16 +1570,32 @@ static void tg3_phy_stop(struct tg3 *tp)
 
 static void tg3_phy_fini(struct tg3 *tp)
 {
-       if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) {
+       if (tp->phy_flags & TG3_PHYFLG_IS_CONNECTED) {
                phy_disconnect(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]);
-               tp->tg3_flags3 &= ~TG3_FLG3_PHY_CONNECTED;
+               tp->phy_flags &= ~TG3_PHYFLG_IS_CONNECTED;
        }
 }
 
-static void tg3_phydsp_write(struct tg3 *tp, u32 reg, u32 val)
+static int tg3_phydsp_read(struct tg3 *tp, u32 reg, u32 *val)
 {
-       tg3_writephy(tp, MII_TG3_DSP_ADDRESS, reg);
-       tg3_writephy(tp, MII_TG3_DSP_RW_PORT, val);
+       int err;
+
+       err = tg3_writephy(tp, MII_TG3_DSP_ADDRESS, reg);
+       if (!err)
+               err = tg3_readphy(tp, MII_TG3_DSP_RW_PORT, val);
+
+       return err;
+}
+
+static int tg3_phydsp_write(struct tg3 *tp, u32 reg, u32 val)
+{
+       int err;
+
+       err = tg3_writephy(tp, MII_TG3_DSP_ADDRESS, reg);
+       if (!err)
+               err = tg3_writephy(tp, MII_TG3_DSP_RW_PORT, val);
+
+       return err;
 }
 
 static void tg3_phy_fet_toggle_apd(struct tg3 *tp, bool enable)
@@ -1608,10 +1625,10 @@ static void tg3_phy_toggle_apd(struct tg3 *tp, bool enable)
        if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
            ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
              GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) &&
-            (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)))
+            (tp->phy_flags & TG3_PHYFLG_MII_SERDES)))
                return;
 
-       if (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) {
+       if (tp->phy_flags & TG3_PHYFLG_IS_FET) {
                tg3_phy_fet_toggle_apd(tp, enable);
                return;
        }
@@ -1642,10 +1659,10 @@ static void tg3_phy_toggle_automdix(struct tg3 *tp, int enable)
        u32 phy;
 
        if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
-           (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES))
+           (tp->phy_flags & TG3_PHYFLG_ANY_SERDES))
                return;
 
-       if (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) {
+       if (tp->phy_flags & TG3_PHYFLG_IS_FET) {
                u32 ephy;
 
                if (!tg3_readphy(tp, MII_TG3_FET_TEST, &ephy)) {
@@ -1681,7 +1698,7 @@ static void tg3_phy_set_wirespeed(struct tg3 *tp)
 {
        u32 val;
 
-       if (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED)
+       if (tp->phy_flags & TG3_PHYFLG_NO_ETH_WIRE_SPEED)
                return;
 
        if (!tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x7007) &&
@@ -1733,6 +1750,63 @@ static void tg3_phy_apply_otp(struct tg3 *tp)
        tg3_writephy(tp, MII_TG3_AUX_CTRL, phy);
 }
 
+static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up)
+{
+       u32 val;
+
+       if (!(tp->phy_flags & TG3_PHYFLG_EEE_CAP))
+               return;
+
+       tp->setlpicnt = 0;
+
+       if (tp->link_config.autoneg == AUTONEG_ENABLE &&
+           current_link_up == 1 &&
+           tp->link_config.active_duplex == DUPLEX_FULL &&
+           (tp->link_config.active_speed == SPEED_100 ||
+            tp->link_config.active_speed == SPEED_1000)) {
+               u32 eeectl;
+
+               if (tp->link_config.active_speed == SPEED_1000)
+                       eeectl = TG3_CPMU_EEE_CTRL_EXIT_16_5_US;
+               else
+                       eeectl = TG3_CPMU_EEE_CTRL_EXIT_36_US;
+
+               tw32(TG3_CPMU_EEE_CTRL, eeectl);
+
+               tg3_phy_cl45_read(tp, MDIO_MMD_AN,
+                                 TG3_CL45_D7_EEERES_STAT, &val);
+
+               switch (val) {
+               case TG3_CL45_D7_EEERES_STAT_LP_1000T:
+                       switch (GET_ASIC_REV(tp->pci_chip_rev_id)) {
+                       case ASIC_REV_5717:
+                       case ASIC_REV_5719:
+                       case ASIC_REV_57765:
+                               /* Enable SM_DSP clock and tx 6dB coding. */
+                               val = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
+                                     MII_TG3_AUXCTL_ACTL_SMDSP_ENA |
+                                     MII_TG3_AUXCTL_ACTL_TX_6DB;
+                               tg3_writephy(tp, MII_TG3_AUX_CTRL, val);
+
+                               tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, 0x0000);
+
+                               /* Turn off SM_DSP clock. */
+                               val = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
+                                     MII_TG3_AUXCTL_ACTL_TX_6DB;
+                               tg3_writephy(tp, MII_TG3_AUX_CTRL, val);
+                       }
+                       /* Fallthrough */
+               case TG3_CL45_D7_EEERES_STAT_LP_100TX:
+                       tp->setlpicnt = 2;
+               }
+       }
+
+       if (!tp->setlpicnt) {
+               val = tr32(TG3_CPMU_EEE_MODE);
+               tw32(TG3_CPMU_EEE_MODE, val & ~TG3_CPMU_EEEMD_LPI_ENABLE);
+       }
+}
+
 static int tg3_wait_macro_done(struct tg3 *tp)
 {
        int limit = 100;
@@ -1740,7 +1814,7 @@ static int tg3_wait_macro_done(struct tg3 *tp)
        while (limit--) {
                u32 tmp32;
 
-               if (!tg3_readphy(tp, 0x16, &tmp32)) {
+               if (!tg3_readphy(tp, MII_TG3_DSP_CONTROL, &tmp32)) {
                        if ((tmp32 & 0x1000) == 0)
                                break;
                }
@@ -1766,13 +1840,13 @@ static int tg3_phy_write_and_check_testpat(struct tg3 *tp, int *resetp)
 
                tg3_writephy(tp, MII_TG3_DSP_ADDRESS,
                             (chan * 0x2000) | 0x0200);
-               tg3_writephy(tp, 0x16, 0x0002);
+               tg3_writephy(tp, MII_TG3_DSP_CONTROL, 0x0002);
 
                for (i = 0; i < 6; i++)
                        tg3_writephy(tp, MII_TG3_DSP_RW_PORT,
                                     test_pat[chan][i]);
 
-               tg3_writephy(tp, 0x16, 0x0202);
+               tg3_writephy(tp, MII_TG3_DSP_CONTROL, 0x0202);
                if (tg3_wait_macro_done(tp)) {
                        *resetp = 1;
                        return -EBUSY;
@@ -1780,13 +1854,13 @@ static int tg3_phy_write_and_check_testpat(struct tg3 *tp, int *resetp)
 
                tg3_writephy(tp, MII_TG3_DSP_ADDRESS,
                             (chan * 0x2000) | 0x0200);
-               tg3_writephy(tp, 0x16, 0x0082);
+               tg3_writephy(tp, MII_TG3_DSP_CONTROL, 0x0082);
                if (tg3_wait_macro_done(tp)) {
                        *resetp = 1;
                        return -EBUSY;
                }
 
-               tg3_writephy(tp, 0x16, 0x0802);
+               tg3_writephy(tp, MII_TG3_DSP_CONTROL, 0x0802);
                if (tg3_wait_macro_done(tp)) {
                        *resetp = 1;
                        return -EBUSY;
@@ -1826,10 +1900,10 @@ static int tg3_phy_reset_chanpat(struct tg3 *tp)
 
                tg3_writephy(tp, MII_TG3_DSP_ADDRESS,
                             (chan * 0x2000) | 0x0200);
-               tg3_writephy(tp, 0x16, 0x0002);
+               tg3_writephy(tp, MII_TG3_DSP_CONTROL, 0x0002);
                for (i = 0; i < 6; i++)
                        tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x000);
-               tg3_writephy(tp, 0x16, 0x0202);
+               tg3_writephy(tp, MII_TG3_DSP_CONTROL, 0x0202);
                if (tg3_wait_macro_done(tp))
                        return -EBUSY;
        }
@@ -1875,8 +1949,7 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp)
                tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00);
 
                /* Block the PHY control access.  */
-               tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8005);
-               tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x0800);
+               tg3_phydsp_write(tp, 0x8005, 0x0800);
 
                err = tg3_phy_write_and_check_testpat(tp, &do_phy_reset);
                if (!err)
@@ -1887,11 +1960,10 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp)
        if (err)
                return err;
 
-       tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8005);
-       tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x0000);
+       tg3_phydsp_write(tp, 0x8005, 0x0000);
 
        tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8200);
-       tg3_writephy(tp, 0x16, 0x0000);
+       tg3_writephy(tp, MII_TG3_DSP_CONTROL, 0x0000);
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
@@ -1917,19 +1989,16 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp)
  */
 static int tg3_phy_reset(struct tg3 *tp)
 {
-       u32 cpmuctrl;
-       u32 phy_status;
+       u32 val, cpmuctrl;
        int err;
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
-               u32 val;
-
                val = tr32(GRC_MISC_CFG);
                tw32_f(GRC_MISC_CFG, val & ~GRC_MISC_CFG_EPHY_IDDQ);
                udelay(40);
        }
-       err  = tg3_readphy(tp, MII_BMSR, &phy_status);
-       err |= tg3_readphy(tp, MII_BMSR, &phy_status);
+       err  = tg3_readphy(tp, MII_BMSR, &val);
+       err |= tg3_readphy(tp, MII_BMSR, &val);
        if (err != 0)
                return -EBUSY;
 
@@ -1961,18 +2030,14 @@ static int tg3_phy_reset(struct tg3 *tp)
                return err;
 
        if (cpmuctrl & CPMU_CTRL_GPHY_10MB_RXONLY) {
-               u32 phy;
-
-               phy = MII_TG3_DSP_EXP8_AEDW | MII_TG3_DSP_EXP8_REJ2MHz;
-               tg3_phydsp_write(tp, MII_TG3_DSP_EXP8, phy);
+               val = MII_TG3_DSP_EXP8_AEDW | MII_TG3_DSP_EXP8_REJ2MHz;
+               tg3_phydsp_write(tp, MII_TG3_DSP_EXP8, val);
 
                tw32(TG3_CPMU_CTRL, cpmuctrl);
        }
 
        if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5784_AX ||
            GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5761_AX) {
-               u32 val;
-
                val = tr32(TG3_CPMU_LSPD_1000MB_CLK);
                if ((val & CPMU_LSPD_1000MB_MACCLK_MASK) ==
                    CPMU_LSPD_1000MB_MACCLK_12_5) {
@@ -1984,42 +2049,37 @@ static int tg3_phy_reset(struct tg3 *tp)
 
        if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
             GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) &&
-           (tp->tg3_flags2 & TG3_FLG2_MII_SERDES))
+           (tp->phy_flags & TG3_PHYFLG_MII_SERDES))
                return 0;
 
        tg3_phy_apply_otp(tp);
 
-       if (tp->tg3_flags3 & TG3_FLG3_PHY_ENABLE_APD)
+       if (tp->phy_flags & TG3_PHYFLG_ENABLE_APD)
                tg3_phy_toggle_apd(tp, true);
        else
                tg3_phy_toggle_apd(tp, false);
 
 out:
-       if (tp->tg3_flags2 & TG3_FLG2_PHY_ADC_BUG) {
+       if (tp->phy_flags & TG3_PHYFLG_ADC_BUG) {
                tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00);
-               tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x201f);
-               tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x2aaa);
-               tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x000a);
-               tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x0323);
+               tg3_phydsp_write(tp, 0x201f, 0x2aaa);
+               tg3_phydsp_write(tp, 0x000a, 0x0323);
                tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400);
        }
-       if (tp->tg3_flags2 & TG3_FLG2_PHY_5704_A0_BUG) {
-               tg3_writephy(tp, 0x1c, 0x8d68);
-               tg3_writephy(tp, 0x1c, 0x8d68);
+       if (tp->phy_flags & TG3_PHYFLG_5704_A0_BUG) {
+               tg3_writephy(tp, MII_TG3_MISC_SHDW, 0x8d68);
+               tg3_writephy(tp, MII_TG3_MISC_SHDW, 0x8d68);
        }
-       if (tp->tg3_flags2 & TG3_FLG2_PHY_BER_BUG) {
+       if (tp->phy_flags & TG3_PHYFLG_BER_BUG) {
                tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00);
-               tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x000a);
-               tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x310b);
-               tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x201f);
-               tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x9506);
-               tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x401f);
-               tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x14e2);
+               tg3_phydsp_write(tp, 0x000a, 0x310b);
+               tg3_phydsp_write(tp, 0x201f, 0x9506);
+               tg3_phydsp_write(tp, 0x401f, 0x14e2);
                tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400);
-       } else if (tp->tg3_flags2 & TG3_FLG2_PHY_JITTER_BUG) {
+       } else if (tp->phy_flags & TG3_PHYFLG_JITTER_BUG) {
                tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00);
                tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x000a);
-               if (tp->tg3_flags2 & TG3_FLG2_PHY_ADJUST_TRIM) {
+               if (tp->phy_flags & TG3_PHYFLG_ADJUST_TRIM) {
                        tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x110b);
                        tg3_writephy(tp, MII_TG3_TEST1,
                                     MII_TG3_TEST1_TRIM_EN | 0x4);
@@ -2033,23 +2093,19 @@ out:
                /* Cannot do read-modify-write on 5401 */
                tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4c20);
        } else if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
-               u32 phy_reg;
-
                /* Set bit 14 with read-modify-write to preserve other bits */
                if (!tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0007) &&
-                   !tg3_readphy(tp, MII_TG3_AUX_CTRL, &phy_reg))
-                       tg3_writephy(tp, MII_TG3_AUX_CTRL, phy_reg | 0x4000);
+                   !tg3_readphy(tp, MII_TG3_AUX_CTRL, &val))
+                       tg3_writephy(tp, MII_TG3_AUX_CTRL, val | 0x4000);
        }
 
        /* Set phy register 0x10 bit 0 to high fifo elasticity to support
         * jumbo frames transmission.
         */
        if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
-               u32 phy_reg;
-
-               if (!tg3_readphy(tp, MII_TG3_EXT_CTRL, &phy_reg))
+               if (!tg3_readphy(tp, MII_TG3_EXT_CTRL, &val))
                        tg3_writephy(tp, MII_TG3_EXT_CTRL,
-                                    phy_reg | MII_TG3_EXT_CTRL_FIFO_ELASTIC);
+                                    val | MII_TG3_EXT_CTRL_FIFO_ELASTIC);
        }
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
@@ -2204,7 +2260,7 @@ static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power)
 {
        u32 val;
 
-       if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) {
+       if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) {
                if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
                        u32 sg_dig_ctrl = tr32(SG_DIG_CTRL);
                        u32 serdes_cfg = tr32(MAC_SERDES_CFG);
@@ -2223,7 +2279,7 @@ 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) {
+       } else if (tp->phy_flags & TG3_PHYFLG_IS_FET) {
                u32 phytest;
                if (!tg3_readphy(tp, MII_TG3_FET_TEST, &phytest)) {
                        u32 phy;
@@ -2260,7 +2316,7 @@ static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power)
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
            (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 &&
-            (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)))
+            (tp->phy_flags & TG3_PHYFLG_MII_SERDES)))
                return;
 
        if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5784_AX ||
@@ -2506,39 +2562,35 @@ static void __tg3_set_mac_addr(struct tg3 *tp, int skip_mac_1)
        tw32(MAC_TX_BACKOFF_SEED, addr_high);
 }
 
-static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
+static void tg3_enable_register_access(struct tg3 *tp)
 {
-       u32 misc_host_ctrl;
-       bool device_should_wake, do_low_power;
-
-       /* Make sure register accesses (indirect or otherwise)
-        * will function correctly.
+       /*
+        * Make sure register accesses (indirect or otherwise) will function
+        * correctly.
         */
        pci_write_config_dword(tp->pdev,
-                              TG3PCI_MISC_HOST_CTRL,
-                              tp->misc_host_ctrl);
+                              TG3PCI_MISC_HOST_CTRL, tp->misc_host_ctrl);
+}
 
-       switch (state) {
-       case PCI_D0:
-               pci_enable_wake(tp->pdev, state, false);
-               pci_set_power_state(tp->pdev, PCI_D0);
+static int tg3_power_up(struct tg3 *tp)
+{
+       tg3_enable_register_access(tp);
 
-               /* Switch out of Vaux if it is a NIC */
-               if (tp->tg3_flags2 & TG3_FLG2_IS_NIC)
-                       tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl, 100);
+       pci_set_power_state(tp->pdev, PCI_D0);
 
-               return 0;
+       /* Switch out of Vaux if it is a NIC */
+       if (tp->tg3_flags2 & TG3_FLG2_IS_NIC)
+               tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl, 100);
 
-       case PCI_D1:
-       case PCI_D2:
-       case PCI_D3hot:
-               break;
+       return 0;
+}
 
-       default:
-               netdev_err(tp->dev, "Invalid power state (D%d) requested\n",
-                          state);
-               return -EINVAL;
-       }
+static int tg3_power_down_prepare(struct tg3 *tp)
+{
+       u32 misc_host_ctrl;
+       bool device_should_wake, do_low_power;
+
+       tg3_enable_register_access(tp);
 
        /* Restore the CLKREQ setting. */
        if (tp->tg3_flags3 & TG3_FLG3_CLKREQ_BUG) {
@@ -2557,20 +2609,19 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
        tw32(TG3PCI_MISC_HOST_CTRL,
             misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT);
 
-       device_should_wake = pci_pme_capable(tp->pdev, state) &&
-                            device_may_wakeup(&tp->pdev->dev) &&
+       device_should_wake = device_may_wakeup(&tp->pdev->dev) &&
                             (tp->tg3_flags & TG3_FLAG_WOL_ENABLE);
 
        if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
                do_low_power = false;
-               if ((tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) &&
-                   !tp->link_config.phy_is_low_power) {
+               if ((tp->phy_flags & TG3_PHYFLG_IS_CONNECTED) &&
+                   !(tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)) {
                        struct phy_device *phydev;
                        u32 phyid, advertising;
 
                        phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
 
-                       tp->link_config.phy_is_low_power = 1;
+                       tp->phy_flags |= TG3_PHYFLG_IS_LOW_POWER;
 
                        tp->link_config.orig_speed = phydev->speed;
                        tp->link_config.orig_duplex = phydev->duplex;
@@ -2609,14 +2660,14 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
        } else {
                do_low_power = true;
 
-               if (tp->link_config.phy_is_low_power == 0) {
-                       tp->link_config.phy_is_low_power = 1;
+               if (!(tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)) {
+                       tp->phy_flags |= TG3_PHYFLG_IS_LOW_POWER;
                        tp->link_config.orig_speed = tp->link_config.speed;
                        tp->link_config.orig_duplex = tp->link_config.duplex;
                        tp->link_config.orig_autoneg = tp->link_config.autoneg;
                }
 
-               if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)) {
+               if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES)) {
                        tp->link_config.speed = SPEED_10;
                        tp->link_config.duplex = DUPLEX_HALF;
                        tp->link_config.autoneg = AUTONEG_ENABLE;
@@ -2649,13 +2700,13 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
        if (device_should_wake) {
                u32 mac_mode;
 
-               if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) {
+               if (!(tp->phy_flags & TG3_PHYFLG_PHY_SERDES)) {
                        if (do_low_power) {
                                tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x5a);
                                udelay(40);
                        }
 
-                       if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)
+                       if (tp->phy_flags & TG3_PHYFLG_MII_SERDES)
                                mac_mode = MAC_MODE_PORT_MODE_GMII;
                        else
                                mac_mode = MAC_MODE_PORT_MODE_MII;
@@ -2685,12 +2736,10 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
                     (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)))
                        mac_mode |= MAC_MODE_KEEP_FRAME_IN_WOL;
 
-               if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
-                       mac_mode |= tp->mac_mode &
-                                   (MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN);
-                       if (mac_mode & MAC_MODE_APE_TX_EN)
-                               mac_mode |= MAC_MODE_TDE_ENABLE;
-               }
+               if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
+                       mac_mode |= MAC_MODE_APE_TX_EN |
+                                   MAC_MODE_APE_RX_EN |
+                                   MAC_MODE_TDE_ENABLE;
 
                tw32_f(MAC_MODE, mac_mode);
                udelay(100);
@@ -2780,13 +2829,15 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
 
        tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN);
 
-       if (device_should_wake)
-               pci_enable_wake(tp->pdev, state, true);
+       return 0;
+}
 
-       /* Finally, set the new power state. */
-       pci_set_power_state(tp->pdev, state);
+static void tg3_power_down(struct tg3 *tp)
+{
+       tg3_power_down_prepare(tp);
 
-       return 0;
+       pci_wake_from_d3(tp->pdev, tp->tg3_flags & TG3_FLAG_WOL_ENABLE);
+       pci_set_power_state(tp->pdev, PCI_D3hot);
 }
 
 static void tg3_aux_stat_to_speed_duplex(struct tg3 *tp, u32 val, u16 *speed, u8 *duplex)
@@ -2823,7 +2874,7 @@ static void tg3_aux_stat_to_speed_duplex(struct tg3 *tp, u32 val, u16 *speed, u8
                break;
 
        default:
-               if (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) {
+               if (tp->phy_flags & TG3_PHYFLG_IS_FET) {
                        *speed = (val & MII_TG3_AUX_STAT_100) ? SPEED_100 :
                                 SPEED_10;
                        *duplex = (val & MII_TG3_AUX_STAT_FULL) ? DUPLEX_FULL :
@@ -2841,7 +2892,7 @@ static void tg3_phy_copper_begin(struct tg3 *tp)
        u32 new_adv;
        int i;
 
-       if (tp->link_config.phy_is_low_power) {
+       if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) {
                /* Entering low power mode.  Disable gigabit and
                 * 100baseT advertisements.
                 */
@@ -2854,7 +2905,7 @@ static void tg3_phy_copper_begin(struct tg3 *tp)
 
                tg3_writephy(tp, MII_ADVERTISE, new_adv);
        } else if (tp->link_config.speed == SPEED_INVALID) {
-               if (tp->tg3_flags & TG3_FLAG_10_100_ONLY)
+               if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY)
                        tp->link_config.advertising &=
                                ~(ADVERTISED_1000baseT_Half |
                                  ADVERTISED_1000baseT_Full);
@@ -2880,7 +2931,7 @@ static void tg3_phy_copper_begin(struct tg3 *tp)
                                new_adv |= MII_TG3_CTRL_ADV_1000_HALF;
                        if (tp->link_config.advertising & ADVERTISED_1000baseT_Full)
                                new_adv |= MII_TG3_CTRL_ADV_1000_FULL;
-                       if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY) &&
+                       if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY) &&
                            (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
                             tp->pci_chip_rev_id == CHIPREV_ID_5701_B0))
                                new_adv |= (MII_TG3_CTRL_AS_MASTER |
@@ -2925,6 +2976,51 @@ static void tg3_phy_copper_begin(struct tg3 *tp)
                tg3_writephy(tp, MII_TG3_CTRL, new_adv);
        }
 
+       if (tp->phy_flags & TG3_PHYFLG_EEE_CAP) {
+               u32 val;
+
+               tw32(TG3_CPMU_EEE_MODE,
+                    tr32(TG3_CPMU_EEE_MODE) & ~TG3_CPMU_EEEMD_LPI_ENABLE);
+
+               /* Enable SM_DSP clock and tx 6dB coding. */
+               val = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
+                     MII_TG3_AUXCTL_ACTL_SMDSP_ENA |
+                     MII_TG3_AUXCTL_ACTL_TX_6DB;
+               tg3_writephy(tp, MII_TG3_AUX_CTRL, val);
+
+               switch (GET_ASIC_REV(tp->pci_chip_rev_id)) {
+               case ASIC_REV_5717:
+               case ASIC_REV_57765:
+                       if (!tg3_phydsp_read(tp, MII_TG3_DSP_CH34TP2, &val))
+                               tg3_phydsp_write(tp, MII_TG3_DSP_CH34TP2, val |
+                                                MII_TG3_DSP_CH34TP2_HIBW01);
+                       /* Fall through */
+               case ASIC_REV_5719:
+                       val = MII_TG3_DSP_TAP26_ALNOKO |
+                             MII_TG3_DSP_TAP26_RMRXSTO |
+                             MII_TG3_DSP_TAP26_OPCSINPT;
+                       tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, val);
+               }
+
+               val = 0;
+               if (tp->link_config.autoneg == AUTONEG_ENABLE) {
+                       /* Advertise 100-BaseTX EEE ability */
+                       if (tp->link_config.advertising &
+                           ADVERTISED_100baseT_Full)
+                               val |= MDIO_AN_EEE_ADV_100TX;
+                       /* Advertise 1000-BaseT EEE ability */
+                       if (tp->link_config.advertising &
+                           ADVERTISED_1000baseT_Full)
+                               val |= MDIO_AN_EEE_ADV_1000T;
+               }
+               tg3_phy_cl45_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val);
+
+               /* Turn off SM_DSP clock. */
+               val = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
+                     MII_TG3_AUXCTL_ACTL_TX_6DB;
+               tg3_writephy(tp, MII_TG3_AUX_CTRL, val);
+       }
+
        if (tp->link_config.autoneg == AUTONEG_DISABLE &&
            tp->link_config.speed != SPEED_INVALID) {
                u32 bmcr, orig_bmcr;
@@ -2982,20 +3078,11 @@ static int tg3_init_5401phy_dsp(struct tg3 *tp)
        /* Set Extended packet length bit */
        err  = tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4c20);
 
-       err |= tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x0012);
-       err |= tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x1804);
-
-       err |= tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x0013);
-       err |= tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x1204);
-
-       err |= tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8006);
-       err |= tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x0132);
-
-       err |= tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8006);
-       err |= tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x0232);
-
-       err |= tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x201f);
-       err |= tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x0a20);
+       err |= tg3_phydsp_write(tp, 0x0012, 0x1804);
+       err |= tg3_phydsp_write(tp, 0x0013, 0x1204);
+       err |= tg3_phydsp_write(tp, 0x8006, 0x0132);
+       err |= tg3_phydsp_write(tp, 0x8006, 0x0232);
+       err |= tg3_phydsp_write(tp, 0x201f, 0x0a20);
 
        udelay(40);
 
@@ -3020,7 +3107,7 @@ static int tg3_copper_is_advertising_all(struct tg3 *tp, u32 mask)
 
        if ((adv_reg & all_mask) != all_mask)
                return 0;
-       if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) {
+       if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) {
                u32 tg3_ctrl;
 
                all_mask = 0;
@@ -3074,7 +3161,7 @@ static int tg3_adv_1000T_flowctrl_ok(struct tg3 *tp, u32 *lcladv, u32 *rmtadv)
 static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
 {
        int current_link_up;
-       u32 bmsr, dummy;
+       u32 bmsr, val;
        u32 lcl_adv, rmt_adv;
        u16 current_speed;
        u8 current_duplex;
@@ -3148,18 +3235,18 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
                   tp->pci_chip_rev_id == CHIPREV_ID_5701_B0) {
                /* 5701 {A0,B0} CRC bug workaround */
                tg3_writephy(tp, 0x15, 0x0a75);
-               tg3_writephy(tp, 0x1c, 0x8c68);
-               tg3_writephy(tp, 0x1c, 0x8d68);
-               tg3_writephy(tp, 0x1c, 0x8c68);
+               tg3_writephy(tp, MII_TG3_MISC_SHDW, 0x8c68);
+               tg3_writephy(tp, MII_TG3_MISC_SHDW, 0x8d68);
+               tg3_writephy(tp, MII_TG3_MISC_SHDW, 0x8c68);
        }
 
        /* Clear pending interrupts... */
-       tg3_readphy(tp, MII_TG3_ISTAT, &dummy);
-       tg3_readphy(tp, MII_TG3_ISTAT, &dummy);
+       tg3_readphy(tp, MII_TG3_ISTAT, &val);
+       tg3_readphy(tp, MII_TG3_ISTAT, &val);
 
-       if (tp->tg3_flags & TG3_FLAG_USE_MI_INTERRUPT)
+       if (tp->phy_flags & TG3_PHYFLG_USE_MI_INTERRUPT)
                tg3_writephy(tp, MII_TG3_IMASK, ~MII_TG3_INT_LINKCHG);
-       else if (!(tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET))
+       else if (!(tp->phy_flags & TG3_PHYFLG_IS_FET))
                tg3_writephy(tp, MII_TG3_IMASK, ~0);
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
@@ -3175,9 +3262,7 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
        current_speed = SPEED_INVALID;
        current_duplex = DUPLEX_INVALID;
 
-       if (tp->tg3_flags2 & TG3_FLG2_CAPACITIVE_COUPLING) {
-               u32 val;
-
+       if (tp->phy_flags & TG3_PHYFLG_CAPACITIVE_COUPLING) {
                tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4007);
                tg3_readphy(tp, MII_TG3_AUX_CTRL, &val);
                if (!(val & (1 << 10))) {
@@ -3251,14 +3336,12 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
        }
 
 relink:
-       if (current_link_up == 0 || tp->link_config.phy_is_low_power) {
-               u32 tmp;
-
+       if (current_link_up == 0 || (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)) {
                tg3_phy_copper_begin(tp);
 
-               tg3_readphy(tp, MII_BMSR, &tmp);
-               if (!tg3_readphy(tp, MII_BMSR, &tmp) &&
-                   (tmp & BMSR_LSTATUS))
+               tg3_readphy(tp, MII_BMSR, &bmsr);
+               if (!tg3_readphy(tp, MII_BMSR, &bmsr) &&
+                   (bmsr & BMSR_LSTATUS))
                        current_link_up = 1;
        }
 
@@ -3269,7 +3352,7 @@ relink:
                        tp->mac_mode |= MAC_MODE_PORT_MODE_MII;
                else
                        tp->mac_mode |= MAC_MODE_PORT_MODE_GMII;
-       } else if (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET)
+       } else if (tp->phy_flags & TG3_PHYFLG_IS_FET)
                tp->mac_mode |= MAC_MODE_PORT_MODE_MII;
        else
                tp->mac_mode |= MAC_MODE_PORT_MODE_GMII;
@@ -3299,6 +3382,8 @@ relink:
        tw32_f(MAC_MODE, tp->mac_mode);
        udelay(40);
 
+       tg3_phy_eee_adjust(tp, current_link_up);
+
        if (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) {
                /* Polled via timer. */
                tw32_f(MAC_EVENT, 0);
@@ -3820,7 +3905,7 @@ static int tg3_setup_fiber_hw_autoneg(struct tg3 *tp, u32 mac_status)
                expected_sg_dig_ctrl |= SG_DIG_ASYM_PAUSE;
 
        if (sg_dig_ctrl != expected_sg_dig_ctrl) {
-               if ((tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT) &&
+               if ((tp->phy_flags & TG3_PHYFLG_PARALLEL_DETECT) &&
                    tp->serdes_counter &&
                    ((mac_status & (MAC_STATUS_PCS_SYNCED |
                                    MAC_STATUS_RCVD_CFG)) ==
@@ -3837,7 +3922,7 @@ restart_autoneg:
                tw32_f(SG_DIG_CTRL, expected_sg_dig_ctrl);
 
                tp->serdes_counter = SERDES_AN_TIMEOUT_5704S;
-               tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT;
+               tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT;
        } else if (mac_status & (MAC_STATUS_PCS_SYNCED |
                                 MAC_STATUS_SIGNAL_DET)) {
                sg_dig_status = tr32(SG_DIG_STATUS);
@@ -3860,7 +3945,7 @@ restart_autoneg:
                        tg3_setup_flow_control(tp, local_adv, remote_adv);
                        current_link_up = 1;
                        tp->serdes_counter = 0;
-                       tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT;
+                       tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT;
                } else if (!(sg_dig_status & SG_DIG_AUTONEG_COMPLETE)) {
                        if (tp->serdes_counter)
                                tp->serdes_counter--;
@@ -3887,8 +3972,8 @@ restart_autoneg:
                                    !(mac_status & MAC_STATUS_RCVD_CFG)) {
                                        tg3_setup_flow_control(tp, 0, 0);
                                        current_link_up = 1;
-                                       tp->tg3_flags2 |=
-                                               TG3_FLG2_PARALLEL_DETECT;
+                                       tp->phy_flags |=
+                                               TG3_PHYFLG_PARALLEL_DETECT;
                                        tp->serdes_counter =
                                                SERDES_PARALLEL_DET_TIMEOUT;
                                } else
@@ -3897,7 +3982,7 @@ restart_autoneg:
                }
        } else {
                tp->serdes_counter = SERDES_AN_TIMEOUT_5704S;
-               tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT;
+               tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT;
        }
 
 out:
@@ -4114,7 +4199,7 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset)
        err |= tg3_readphy(tp, MII_BMCR, &bmcr);
 
        if ((tp->link_config.autoneg == AUTONEG_ENABLE) && !force_reset &&
-           (tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT)) {
+           (tp->phy_flags & TG3_PHYFLG_PARALLEL_DETECT)) {
                /* do nothing, just check for link up at the end */
        } else if (tp->link_config.autoneg == AUTONEG_ENABLE) {
                u32 adv, new_adv;
@@ -4139,7 +4224,7 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset)
 
                        tw32_f(MAC_EVENT, MAC_EVENT_LNKSTATE_CHANGED);
                        tp->serdes_counter = SERDES_AN_TIMEOUT_5714S;
-                       tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT;
+                       tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT;
 
                        return err;
                }
@@ -4184,7 +4269,7 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset)
                                else
                                        bmsr &= ~BMSR_LSTATUS;
                        }
-                       tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT;
+                       tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT;
                }
        }
 
@@ -4239,7 +4324,7 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset)
                        netif_carrier_on(tp->dev);
                else {
                        netif_carrier_off(tp->dev);
-                       tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT;
+                       tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT;
                }
                tg3_link_report(tp);
        }
@@ -4263,13 +4348,14 @@ static void tg3_serdes_parallel_detect(struct tg3 *tp)
                        u32 phy1, phy2;
 
                        /* Select shadow register 0x1f */
-                       tg3_writephy(tp, 0x1c, 0x7c00);
-                       tg3_readphy(tp, 0x1c, &phy1);
+                       tg3_writephy(tp, MII_TG3_MISC_SHDW, 0x7c00);
+                       tg3_readphy(tp, MII_TG3_MISC_SHDW, &phy1);
 
                        /* Select expansion interrupt status register */
-                       tg3_writephy(tp, 0x17, 0x0f01);
-                       tg3_readphy(tp, 0x15, &phy2);
-                       tg3_readphy(tp, 0x15, &phy2);
+                       tg3_writephy(tp, MII_TG3_DSP_ADDRESS,
+                                        MII_TG3_DSP_EXP1_INT_STAT);
+                       tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &phy2);
+                       tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &phy2);
 
                        if ((phy1 & 0x10) && !(phy2 & 0x20)) {
                                /* We have signal detect and not receiving
@@ -4280,17 +4366,18 @@ static void tg3_serdes_parallel_detect(struct tg3 *tp)
                                bmcr &= ~BMCR_ANENABLE;
                                bmcr |= BMCR_SPEED1000 | BMCR_FULLDPLX;
                                tg3_writephy(tp, MII_BMCR, bmcr);
-                               tp->tg3_flags2 |= TG3_FLG2_PARALLEL_DETECT;
+                               tp->phy_flags |= TG3_PHYFLG_PARALLEL_DETECT;
                        }
                }
        } else if (netif_carrier_ok(tp->dev) &&
                   (tp->link_config.autoneg == AUTONEG_ENABLE) &&
-                  (tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT)) {
+                  (tp->phy_flags & TG3_PHYFLG_PARALLEL_DETECT)) {
                u32 phy2;
 
                /* Select expansion interrupt status register */
-               tg3_writephy(tp, 0x17, 0x0f01);
-               tg3_readphy(tp, 0x15, &phy2);
+               tg3_writephy(tp, MII_TG3_DSP_ADDRESS,
+                                MII_TG3_DSP_EXP1_INT_STAT);
+               tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &phy2);
                if (phy2 & 0x20) {
                        u32 bmcr;
 
@@ -4298,7 +4385,7 @@ static void tg3_serdes_parallel_detect(struct tg3 *tp)
                        tg3_readphy(tp, MII_BMCR, &bmcr);
                        tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANENABLE);
 
-                       tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT;
+                       tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT;
 
                }
        }
@@ -4308,9 +4395,9 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset)
 {
        int err;
 
-       if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)
+       if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES)
                err = tg3_setup_fiber_phy(tp, force_reset);
-       else if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)
+       else if (tp->phy_flags & TG3_PHYFLG_MII_SERDES)
                err = tg3_setup_fiber_mii_phy(tp, force_reset);
        else
                err = tg3_setup_copper_phy(tp, force_reset);
@@ -4365,6 +4452,11 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset)
        return err;
 }
 
+static inline int tg3_irq_sync(struct tg3 *tp)
+{
+       return tp->irq_sync;
+}
+
 /* This is called whenever we suspect that the system chipset is re-
  * ordering the sequence of MMIO to the tx send mailbox. The symptom
  * is bogus tx completions. We try to recover by setting the
@@ -4389,7 +4481,8 @@ static void tg3_tx_recover(struct tg3 *tp)
 
 static inline u32 tg3_tx_avail(struct tg3_napi *tnapi)
 {
-       smp_mb();
+       /* Tell compiler to fetch tx indices from memory. */
+       barrier();
        return tnapi->tx_pending -
               ((tnapi->tx_prod - tnapi->tx_cons) & (TG3_TX_RING_SIZE - 1));
 }
@@ -4495,22 +4588,21 @@ static int tg3_alloc_rx_skb(struct tg3 *tp, struct tg3_rx_prodring_set *tpr,
                            u32 opaque_key, u32 dest_idx_unmasked)
 {
        struct tg3_rx_buffer_desc *desc;
-       struct ring_info *map, *src_map;
+       struct ring_info *map;
        struct sk_buff *skb;
        dma_addr_t mapping;
        int skb_size, dest_idx;
 
-       src_map = NULL;
        switch (opaque_key) {
        case RXD_OPAQUE_RING_STD:
-               dest_idx = dest_idx_unmasked % TG3_RX_RING_SIZE;
+               dest_idx = dest_idx_unmasked & tp->rx_std_ring_mask;
                desc = &tpr->rx_std[dest_idx];
                map = &tpr->rx_std_buffers[dest_idx];
                skb_size = tp->rx_pkt_map_sz;
                break;
 
        case RXD_OPAQUE_RING_JUMBO:
-               dest_idx = dest_idx_unmasked % TG3_RX_JUMBO_RING_SIZE;
+               dest_idx = dest_idx_unmasked & tp->rx_jmb_ring_mask;
                desc = &tpr->rx_jmb[dest_idx].std;
                map = &tpr->rx_jmb_buffers[dest_idx];
                skb_size = TG3_RX_JMB_MAP_SZ;
@@ -4560,12 +4652,12 @@ static void tg3_recycle_rx(struct tg3_napi *tnapi,
        struct tg3 *tp = tnapi->tp;
        struct tg3_rx_buffer_desc *src_desc, *dest_desc;
        struct ring_info *src_map, *dest_map;
-       struct tg3_rx_prodring_set *spr = &tp->prodring[0];
+       struct tg3_rx_prodring_set *spr = &tp->napi[0].prodring;
        int dest_idx;
 
        switch (opaque_key) {
        case RXD_OPAQUE_RING_STD:
-               dest_idx = dest_idx_unmasked % TG3_RX_RING_SIZE;
+               dest_idx = dest_idx_unmasked & tp->rx_std_ring_mask;
                dest_desc = &dpr->rx_std[dest_idx];
                dest_map = &dpr->rx_std_buffers[dest_idx];
                src_desc = &spr->rx_std[src_idx];
@@ -4573,7 +4665,7 @@ static void tg3_recycle_rx(struct tg3_napi *tnapi,
                break;
 
        case RXD_OPAQUE_RING_JUMBO:
-               dest_idx = dest_idx_unmasked % TG3_RX_JUMBO_RING_SIZE;
+               dest_idx = dest_idx_unmasked & tp->rx_jmb_ring_mask;
                dest_desc = &dpr->rx_jmb[dest_idx].std;
                dest_map = &dpr->rx_jmb_buffers[dest_idx];
                src_desc = &spr->rx_jmb[src_idx].std;
@@ -4630,7 +4722,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
        u32 sw_idx = tnapi->rx_rcb_ptr;
        u16 hw_idx;
        int received;
-       struct tg3_rx_prodring_set *tpr = tnapi->prodring;
+       struct tg3_rx_prodring_set *tpr = &tnapi->prodring;
 
        hw_idx = *(tnapi->rx_rcb_prod_idx);
        /*
@@ -4649,19 +4741,17 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
                struct sk_buff *skb;
                dma_addr_t dma_addr;
                u32 opaque_key, desc_idx, *post_ptr;
-               bool hw_vlan __maybe_unused = false;
-               u16 vtag __maybe_unused = 0;
 
                desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK;
                opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK;
                if (opaque_key == RXD_OPAQUE_RING_STD) {
-                       ri = &tp->prodring[0].rx_std_buffers[desc_idx];
+                       ri = &tp->napi[0].prodring.rx_std_buffers[desc_idx];
                        dma_addr = dma_unmap_addr(ri, mapping);
                        skb = ri->skb;
                        post_ptr = &std_prod_idx;
                        rx_std_posted++;
                } else if (opaque_key == RXD_OPAQUE_RING_JUMBO) {
-                       ri = &tp->prodring[0].rx_jmb_buffers[desc_idx];
+                       ri = &tp->napi[0].prodring.rx_jmb_buffers[desc_idx];
                        dma_addr = dma_unmap_addr(ri, mapping);
                        skb = ri->skb;
                        post_ptr = &jmb_prod_idx;
@@ -4677,7 +4767,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
                                       desc_idx, *post_ptr);
                drop_it_no_recycle:
                        /* Other statistics kept track of by card. */
-                       tp->net_stats.rx_dropped++;
+                       tp->rx_dropped++;
                        goto next_pkt;
                }
 
@@ -4709,12 +4799,12 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
                        tg3_recycle_rx(tnapi, tpr, opaque_key,
                                       desc_idx, *post_ptr);
 
-                       copy_skb = netdev_alloc_skb(tp->dev, len + VLAN_HLEN +
+                       copy_skb = netdev_alloc_skb(tp->dev, len +
                                                    TG3_RAW_IP_ALIGN);
                        if (copy_skb == NULL)
                                goto drop_it_no_recycle;
 
-                       skb_reserve(copy_skb, TG3_RAW_IP_ALIGN + VLAN_HLEN);
+                       skb_reserve(copy_skb, TG3_RAW_IP_ALIGN);
                        skb_put(copy_skb, len);
                        pci_dma_sync_single_for_cpu(tp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE);
                        skb_copy_from_linear_data(skb, copy_skb->data, len);
@@ -4730,41 +4820,22 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
                      >> RXD_TCPCSUM_SHIFT) == 0xffff))
                        skb->ip_summed = CHECKSUM_UNNECESSARY;
                else
-                       skb->ip_summed = CHECKSUM_NONE;
+                       skb_checksum_none_assert(skb);
 
                skb->protocol = eth_type_trans(skb, tp->dev);
 
                if (len > (tp->dev->mtu + ETH_HLEN) &&
                    skb->protocol != htons(ETH_P_8021Q)) {
                        dev_kfree_skb(skb);
-                       goto next_pkt;
+                       goto drop_it_no_recycle;
                }
 
                if (desc->type_flags & RXD_FLAG_VLAN &&
-                   !(tp->rx_mode & RX_MODE_KEEP_VLAN_TAG)) {
-                       vtag = desc->err_vlan & RXD_VLAN_MASK;
-#if TG3_VLAN_TAG_USED
-                       if (tp->vlgrp)
-                               hw_vlan = true;
-                       else
-#endif
-                       {
-                               struct vlan_ethhdr *ve = (struct vlan_ethhdr *)
-                                                   __skb_push(skb, VLAN_HLEN);
-
-                               memmove(ve, skb->data + VLAN_HLEN,
-                                       ETH_ALEN * 2);
-                               ve->h_vlan_proto = htons(ETH_P_8021Q);
-                               ve->h_vlan_TCI = htons(vtag);
-                       }
-               }
+                   !(tp->rx_mode & RX_MODE_KEEP_VLAN_TAG))
+                       __vlan_hwaccel_put_tag(skb,
+                                              desc->err_vlan & RXD_VLAN_MASK);
 
-#if TG3_VLAN_TAG_USED
-               if (hw_vlan)
-                       vlan_gro_receive(&tnapi->napi, tp->vlgrp, vtag, skb);
-               else
-#endif
-                       napi_gro_receive(&tnapi->napi, skb);
+               napi_gro_receive(&tnapi->napi, skb);
 
                received++;
                budget--;
@@ -4773,7 +4844,8 @@ next_pkt:
                (*post_ptr)++;
 
                if (unlikely(rx_std_posted >= tp->rx_std_max_post)) {
-                       tpr->rx_std_prod_idx = std_prod_idx % TG3_RX_RING_SIZE;
+                       tpr->rx_std_prod_idx = std_prod_idx &
+                                              tp->rx_std_ring_mask;
                        tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG,
                                     tpr->rx_std_prod_idx);
                        work_mask &= ~RXD_OPAQUE_RING_STD;
@@ -4781,7 +4853,7 @@ next_pkt:
                }
 next_pkt_nopost:
                sw_idx++;
-               sw_idx &= (TG3_RX_RCB_RING_SIZE(tp) - 1);
+               sw_idx &= tp->rx_ret_ring_mask;
 
                /* Refresh hw_idx to see if there is new work */
                if (sw_idx == hw_idx) {
@@ -4797,13 +4869,14 @@ next_pkt_nopost:
        /* Refill RX ring(s). */
        if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS)) {
                if (work_mask & RXD_OPAQUE_RING_STD) {
-                       tpr->rx_std_prod_idx = std_prod_idx % TG3_RX_RING_SIZE;
+                       tpr->rx_std_prod_idx = std_prod_idx &
+                                              tp->rx_std_ring_mask;
                        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;
+                       tpr->rx_jmb_prod_idx = jmb_prod_idx &
+                                              tp->rx_jmb_ring_mask;
                        tw32_rx_mbox(TG3_RX_JMB_PROD_IDX_REG,
                                     tpr->rx_jmb_prod_idx);
                }
@@ -4814,8 +4887,8 @@ next_pkt_nopost:
                 */
                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;
+               tpr->rx_std_prod_idx = std_prod_idx & tp->rx_std_ring_mask;
+               tpr->rx_jmb_prod_idx = jmb_prod_idx & tp->rx_jmb_ring_mask;
 
                if (tnapi != &tp->napi[1])
                        napi_schedule(&tp->napi[1].napi);
@@ -4871,9 +4944,11 @@ static int tg3_rx_prodring_xfer(struct tg3 *tp,
                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 = tp->rx_std_ring_mask + 1 -
+                                spr->rx_std_cons_idx;
 
-               cpycnt = min(cpycnt, TG3_RX_RING_SIZE - dpr->rx_std_prod_idx);
+               cpycnt = min(cpycnt,
+                            tp->rx_std_ring_mask + 1 - dpr->rx_std_prod_idx);
 
                si = spr->rx_std_cons_idx;
                di = dpr->rx_std_prod_idx;
@@ -4907,10 +4982,10 @@ static int tg3_rx_prodring_xfer(struct tg3 *tp,
                        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;
+               spr->rx_std_cons_idx = (spr->rx_std_cons_idx + cpycnt) &
+                                      tp->rx_std_ring_mask;
+               dpr->rx_std_prod_idx = (dpr->rx_std_prod_idx + cpycnt) &
+                                      tp->rx_std_ring_mask;
        }
 
        while (1) {
@@ -4927,10 +5002,11 @@ static int tg3_rx_prodring_xfer(struct tg3 *tp,
                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 = tp->rx_jmb_ring_mask + 1 -
+                                spr->rx_jmb_cons_idx;
 
                cpycnt = min(cpycnt,
-                            TG3_RX_JUMBO_RING_SIZE - dpr->rx_jmb_prod_idx);
+                            tp->rx_jmb_ring_mask + 1 - dpr->rx_jmb_prod_idx);
 
                si = spr->rx_jmb_cons_idx;
                di = dpr->rx_jmb_prod_idx;
@@ -4964,10 +5040,10 @@ static int tg3_rx_prodring_xfer(struct tg3 *tp,
                        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;
+               spr->rx_jmb_cons_idx = (spr->rx_jmb_cons_idx + cpycnt) &
+                                      tp->rx_jmb_ring_mask;
+               dpr->rx_jmb_prod_idx = (dpr->rx_jmb_prod_idx + cpycnt) &
+                                      tp->rx_jmb_ring_mask;
        }
 
        return err;
@@ -4992,14 +5068,14 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
                work_done += tg3_rx(tnapi, budget - work_done);
 
        if ((tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS) && tnapi == &tp->napi[1]) {
-               struct tg3_rx_prodring_set *dpr = &tp->prodring[0];
+               struct tg3_rx_prodring_set *dpr = &tp->napi[0].prodring;
                int i, err = 0;
                u32 std_prod_idx = dpr->rx_std_prod_idx;
                u32 jmb_prod_idx = dpr->rx_jmb_prod_idx;
 
                for (i = 1; i < tp->irq_cnt; i++)
                        err |= tg3_rx_prodring_xfer(tp, dpr,
-                                                   tp->napi[i].prodring);
+                                                   &tp->napi[i].prodring);
 
                wmb();
 
@@ -5109,6 +5185,59 @@ tx_recovery:
        return work_done;
 }
 
+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 void tg3_napi_init(struct tg3 *tp)
+{
+       int i;
+
+       netif_napi_add(tp->dev, &tp->napi[0].napi, tg3_poll, 64);
+       for (i = 1; i < tp->irq_cnt; i++)
+               netif_napi_add(tp->dev, &tp->napi[i].napi, tg3_poll_msix, 64);
+}
+
+static void tg3_napi_fini(struct tg3 *tp)
+{
+       int i;
+
+       for (i = 0; i < tp->irq_cnt; i++)
+               netif_napi_del(&tp->napi[i].napi);
+}
+
+static inline void tg3_netif_stop(struct tg3 *tp)
+{
+       tp->dev->trans_start = jiffies; /* prevent tx timeout */
+       tg3_napi_disable(tp);
+       netif_tx_disable(tp->dev);
+}
+
+static inline void tg3_netif_start(struct tg3 *tp)
+{
+       /* 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)
+        */
+       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_irq_quiesce(struct tg3 *tp)
 {
        int i;
@@ -5122,11 +5251,6 @@ static void tg3_irq_quiesce(struct tg3 *tp)
                synchronize_irq(tp->napi[i].irq_vec);
 }
 
-static inline int tg3_irq_sync(struct tg3 *tp)
-{
-       return tp->irq_sync;
-}
-
 /* Fully shutdown all tg3 driver activity elsewhere in the system.
  * If irq_sync is non-zero, then the IRQ handler must be synchronized
  * with as well.  Most of the time, this is not necessary except when
@@ -5415,8 +5539,7 @@ static inline int tg3_4g_overflow_test(dma_addr_t mapping, int len)
 {
        u32 base = (u32) mapping & 0xffffffff;
 
-       return ((base > 0xffffdcc0) &&
-               (base + len + 8 < base));
+       return (base > 0xffffdcc0) && (base + len + 8 < base);
 }
 
 /* Test for DMA addresses > 40-bit */
@@ -5425,7 +5548,7 @@ static inline int tg3_40bit_overflow_test(struct tg3 *tp, dma_addr_t mapping,
 {
 #if defined(CONFIG_HIGHMEM) && (BITS_PER_LONG == 64)
        if (tp->tg3_flags & TG3_FLAG_40BIT_DMA_BUG)
-               return (((u64) mapping + len) > DMA_BIT_MASK(40));
+               return ((u64) mapping + len) > DMA_BIT_MASK(40);
        return 0;
 #else
        return 0;
@@ -5585,9 +5708,9 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb,
                        goto out_unlock;
                }
 
-               if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
+               if (skb_is_gso_v6(skb)) {
                        hdrlen = skb_headlen(skb) - ETH_HLEN;
-               else {
+               } else {
                        struct iphdr *iph = ip_hdr(skb);
 
                        tcp_opt_len = tcp_optlen(skb);
@@ -5615,11 +5738,9 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb,
                base_flags |= TXD_FLAG_TCPUDP_CSUM;
        }
 
-#if TG3_VLAN_TAG_USED
-       if (tp->vlgrp != NULL && vlan_tx_tag_present(skb))
+       if (vlan_tx_tag_present(skb))
                base_flags |= (TXD_FLAG_VLAN |
                               (vlan_tx_tag_get(skb) << 16));
-#endif
 
        len = skb_headlen(skb);
 
@@ -5634,7 +5755,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb,
        dma_unmap_addr_set(&tnapi->tx_buffers[entry], mapping, mapping);
 
        if ((tp->tg3_flags3 & TG3_FLG3_USE_JUMBO_BDFLAG) &&
-           !mss && skb->len > ETH_DATA_LEN)
+           !mss && skb->len > VLAN_ETH_FRAME_LEN)
                base_flags |= TXD_FLAG_JMB_PKT;
 
        tg3_set_txd(tnapi, entry, mapping, len, base_flags,
@@ -5673,6 +5794,13 @@ 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_tx_stop_queue(txq);
+
+               /* netif_tx_stop_queue() must be done before checking
+                * checking tx index in tg3_tx_avail() below, because in
+                * tg3_tx(), we update tx index before checking for
+                * netif_tx_queue_stopped().
+                */
+               smp_mb();
                if (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi))
                        netif_tx_wake_queue(txq);
        }
@@ -5718,6 +5846,13 @@ static int tg3_tso_bug(struct tg3 *tp, struct sk_buff *skb)
        /* Estimate the number of fragments in the worst case */
        if (unlikely(tg3_tx_avail(&tp->napi[0]) <= frag_cnt_est)) {
                netif_stop_queue(tp->dev);
+
+               /* netif_tx_stop_queue() must be done before checking
+                * checking tx index in tg3_tx_avail() below, because in
+                * tg3_tx(), we update tx index before checking for
+                * netif_tx_queue_stopped().
+                */
+               smp_mb();
                if (tg3_tx_avail(&tp->napi[0]) <= frag_cnt_est)
                        return NETDEV_TX_BUSY;
 
@@ -5795,7 +5930,7 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
                iph = ip_hdr(skb);
                tcp_opt_len = tcp_optlen(skb);
 
-               if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) {
+               if (skb_is_gso_v6(skb)) {
                        hdr_len = skb_headlen(skb) - ETH_HLEN;
                } else {
                        u32 ip_tcp_len;
@@ -5847,14 +5982,13 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
                        }
                }
        }
-#if TG3_VLAN_TAG_USED
-       if (tp->vlgrp != NULL && vlan_tx_tag_present(skb))
+
+       if (vlan_tx_tag_present(skb))
                base_flags |= (TXD_FLAG_VLAN |
                               (vlan_tx_tag_get(skb) << 16));
-#endif
 
        if ((tp->tg3_flags3 & TG3_FLG3_USE_JUMBO_BDFLAG) &&
-           !mss && skb->len > ETH_DATA_LEN)
+           !mss && skb->len > VLAN_ETH_FRAME_LEN)
                base_flags |= TXD_FLAG_JMB_PKT;
 
        len = skb_headlen(skb);
@@ -5953,6 +6087,13 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
        tnapi->tx_prod = entry;
        if (unlikely(tg3_tx_avail(tnapi) <= (MAX_SKB_FRAGS + 1))) {
                netif_tx_stop_queue(txq);
+
+               /* netif_tx_stop_queue() must be done before checking
+                * checking tx index in tg3_tx_avail() below, because in
+                * tg3_tx(), we update tx index before checking for
+                * netif_tx_queue_stopped().
+                */
+               smp_mb();
                if (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi))
                        netif_tx_wake_queue(txq);
        }
@@ -6047,16 +6188,16 @@ static void tg3_rx_prodring_free(struct tg3 *tp,
 {
        int i;
 
-       if (tpr != &tp->prodring[0]) {
+       if (tpr != &tp->napi[0].prodring) {
                for (i = tpr->rx_std_cons_idx; i != tpr->rx_std_prod_idx;
-                    i = (i + 1) % TG3_RX_RING_SIZE)
+                    i = (i + 1) & tp->rx_std_ring_mask)
                        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) {
+                            i = (i + 1) & tp->rx_jmb_ring_mask) {
                                tg3_rx_skb_free(tp, &tpr->rx_jmb_buffers[i],
                                                TG3_RX_JMB_MAP_SZ);
                        }
@@ -6065,12 +6206,13 @@ static void tg3_rx_prodring_free(struct tg3 *tp,
                return;
        }
 
-       for (i = 0; i < TG3_RX_RING_SIZE; i++)
+       for (i = 0; i <= tp->rx_std_ring_mask; i++)
                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 = 0; i < TG3_RX_JUMBO_RING_SIZE; i++)
+       if ((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) &&
+           !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
+               for (i = 0; i <= tp->rx_jmb_ring_mask; i++)
                        tg3_rx_skb_free(tp, &tpr->rx_jmb_buffers[i],
                                        TG3_RX_JMB_MAP_SZ);
        }
@@ -6093,16 +6235,17 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp,
        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)
+       if (tpr != &tp->napi[0].prodring) {
+               memset(&tpr->rx_std_buffers[0], 0,
+                      TG3_RX_STD_BUFF_RING_SIZE(tp));
+               if (tpr->rx_jmb_buffers)
                        memset(&tpr->rx_jmb_buffers[0], 0,
-                              TG3_RX_JMB_BUFF_RING_SIZE);
+                              TG3_RX_JMB_BUFF_RING_SIZE(tp));
                goto done;
        }
 
        /* Zero out all descriptors. */
-       memset(tpr->rx_std, 0, TG3_RX_RING_BYTES);
+       memset(tpr->rx_std, 0, TG3_RX_STD_RING_BYTES(tp));
 
        rx_pkt_dma_sz = TG3_RX_STD_DMA_SZ;
        if ((tp->tg3_flags2 & TG3_FLG2_5780_CLASS) &&
@@ -6114,7 +6257,7 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp,
         * stuff once.  This works because the card does not
         * write into the rx buffer posting rings.
         */
-       for (i = 0; i < TG3_RX_RING_SIZE; i++) {
+       for (i = 0; i <= tp->rx_std_ring_mask; i++) {
                struct tg3_rx_buffer_desc *rxd;
 
                rxd = &tpr->rx_std[i];
@@ -6138,15 +6281,16 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp,
                }
        }
 
-       if (!(tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE))
+       if (!(tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) ||
+           (tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
                goto done;
 
-       memset(tpr->rx_jmb, 0, TG3_RX_JUMBO_RING_BYTES);
+       memset(tpr->rx_jmb, 0, TG3_RX_JMB_RING_BYTES(tp));
 
        if (!(tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE))
                goto done;
 
-       for (i = 0; i < TG3_RX_JUMBO_RING_SIZE; i++) {
+       for (i = 0; i <= tp->rx_jmb_ring_mask; i++) {
                struct tg3_rx_buffer_desc *rxd;
 
                rxd = &tpr->rx_jmb[i].std;
@@ -6186,13 +6330,13 @@ static void tg3_rx_prodring_fini(struct tg3 *tp,
        kfree(tpr->rx_jmb_buffers);
        tpr->rx_jmb_buffers = NULL;
        if (tpr->rx_std) {
-               pci_free_consistent(tp->pdev, TG3_RX_RING_BYTES,
-                                   tpr->rx_std, tpr->rx_std_mapping);
+               dma_free_coherent(&tp->pdev->dev, TG3_RX_STD_RING_BYTES(tp),
+                                 tpr->rx_std, tpr->rx_std_mapping);
                tpr->rx_std = NULL;
        }
        if (tpr->rx_jmb) {
-               pci_free_consistent(tp->pdev, TG3_RX_JUMBO_RING_BYTES,
-                                   tpr->rx_jmb, tpr->rx_jmb_mapping);
+               dma_free_coherent(&tp->pdev->dev, TG3_RX_JMB_RING_BYTES(tp),
+                                 tpr->rx_jmb, tpr->rx_jmb_mapping);
                tpr->rx_jmb = NULL;
        }
 }
@@ -6200,24 +6344,29 @@ 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(TG3_RX_STD_BUFF_RING_SIZE, GFP_KERNEL);
+       tpr->rx_std_buffers = kzalloc(TG3_RX_STD_BUFF_RING_SIZE(tp),
+                                     GFP_KERNEL);
        if (!tpr->rx_std_buffers)
                return -ENOMEM;
 
-       tpr->rx_std = pci_alloc_consistent(tp->pdev, TG3_RX_RING_BYTES,
-                                          &tpr->rx_std_mapping);
+       tpr->rx_std = dma_alloc_coherent(&tp->pdev->dev,
+                                        TG3_RX_STD_RING_BYTES(tp),
+                                        &tpr->rx_std_mapping,
+                                        GFP_KERNEL);
        if (!tpr->rx_std)
                goto err_out;
 
-       if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
-               tpr->rx_jmb_buffers = kzalloc(TG3_RX_JMB_BUFF_RING_SIZE,
+       if ((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) &&
+           !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
+               tpr->rx_jmb_buffers = kzalloc(TG3_RX_JMB_BUFF_RING_SIZE(tp),
                                              GFP_KERNEL);
                if (!tpr->rx_jmb_buffers)
                        goto err_out;
 
-               tpr->rx_jmb = pci_alloc_consistent(tp->pdev,
-                                                  TG3_RX_JUMBO_RING_BYTES,
-                                                  &tpr->rx_jmb_mapping);
+               tpr->rx_jmb = dma_alloc_coherent(&tp->pdev->dev,
+                                                TG3_RX_JMB_RING_BYTES(tp),
+                                                &tpr->rx_jmb_mapping,
+                                                GFP_KERNEL);
                if (!tpr->rx_jmb)
                        goto err_out;
        }
@@ -6243,7 +6392,7 @@ static void tg3_free_rings(struct tg3 *tp)
        for (j = 0; j < tp->irq_cnt; j++) {
                struct tg3_napi *tnapi = &tp->napi[j];
 
-               tg3_rx_prodring_free(tp, &tp->prodring[j]);
+               tg3_rx_prodring_free(tp, &tnapi->prodring);
 
                if (!tnapi->tx_buffers)
                        continue;
@@ -6315,7 +6464,7 @@ static int tg3_init_rings(struct tg3 *tp)
                if (tnapi->rx_rcb)
                        memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));
 
-               if (tg3_rx_prodring_alloc(tp, &tp->prodring[i])) {
+               if (tg3_rx_prodring_alloc(tp, &tnapi->prodring)) {
                        tg3_free_rings(tp);
                        return -ENOMEM;
                }
@@ -6336,7 +6485,7 @@ static void tg3_free_consistent(struct tg3 *tp)
                struct tg3_napi *tnapi = &tp->napi[i];
 
                if (tnapi->tx_ring) {
-                       pci_free_consistent(tp->pdev, TG3_TX_RING_BYTES,
+                       dma_free_coherent(&tp->pdev->dev, TG3_TX_RING_BYTES,
                                tnapi->tx_ring, tnapi->tx_desc_mapping);
                        tnapi->tx_ring = NULL;
                }
@@ -6345,28 +6494,28 @@ static void tg3_free_consistent(struct tg3 *tp)
                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);
+                       dma_free_coherent(&tp->pdev->dev,
+                                         TG3_RX_RCB_RING_BYTES(tp),
+                                         tnapi->rx_rcb,
+                                         tnapi->rx_rcb_mapping);
                        tnapi->rx_rcb = NULL;
                }
 
+               tg3_rx_prodring_fini(tp, &tnapi->prodring);
+
                if (tnapi->hw_status) {
-                       pci_free_consistent(tp->pdev, TG3_HW_STATUS_SIZE,
-                                           tnapi->hw_status,
-                                           tnapi->status_mapping);
+                       dma_free_coherent(&tp->pdev->dev, 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);
+               dma_free_coherent(&tp->pdev->dev, sizeof(struct tg3_hw_stats),
+                                 tp->hw_stats, tp->stats_mapping);
                tp->hw_stats = NULL;
        }
-
-       for (i = 0; i < tp->irq_cnt; i++)
-               tg3_rx_prodring_fini(tp, &tp->prodring[i]);
 }
 
 /*
@@ -6377,14 +6526,10 @@ static int tg3_alloc_consistent(struct tg3 *tp)
 {
        int i;
 
-       for (i = 0; i < tp->irq_cnt; i++) {
-               if (tg3_rx_prodring_init(tp, &tp->prodring[i]))
-                       goto err_out;
-       }
-
-       tp->hw_stats = pci_alloc_consistent(tp->pdev,
-                                           sizeof(struct tg3_hw_stats),
-                                           &tp->stats_mapping);
+       tp->hw_stats = dma_alloc_coherent(&tp->pdev->dev,
+                                         sizeof(struct tg3_hw_stats),
+                                         &tp->stats_mapping,
+                                         GFP_KERNEL);
        if (!tp->hw_stats)
                goto err_out;
 
@@ -6394,15 +6539,19 @@ static int tg3_alloc_consistent(struct tg3 *tp)
                struct tg3_napi *tnapi = &tp->napi[i];
                struct tg3_hw_status *sblk;
 
-               tnapi->hw_status = pci_alloc_consistent(tp->pdev,
-                                                       TG3_HW_STATUS_SIZE,
-                                                       &tnapi->status_mapping);
+               tnapi->hw_status = dma_alloc_coherent(&tp->pdev->dev,
+                                                     TG3_HW_STATUS_SIZE,
+                                                     &tnapi->status_mapping,
+                                                     GFP_KERNEL);
                if (!tnapi->hw_status)
                        goto err_out;
 
                memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE);
                sblk = tnapi->hw_status;
 
+               if (tg3_rx_prodring_init(tp, &tnapi->prodring))
+                       goto err_out;
+
                /* If multivector TSS is enabled, vector 0 does not handle
                 * tx interrupts.  Don't allocate any resources for it.
                 */
@@ -6414,9 +6563,10 @@ static int tg3_alloc_consistent(struct tg3 *tp)
                        if (!tnapi->tx_buffers)
                                goto err_out;
 
-                       tnapi->tx_ring = pci_alloc_consistent(tp->pdev,
-                                                             TG3_TX_RING_BYTES,
-                                                      &tnapi->tx_desc_mapping);
+                       tnapi->tx_ring = dma_alloc_coherent(&tp->pdev->dev,
+                                                           TG3_TX_RING_BYTES,
+                                                       &tnapi->tx_desc_mapping,
+                                                           GFP_KERNEL);
                        if (!tnapi->tx_ring)
                                goto err_out;
                }
@@ -6442,8 +6592,6 @@ static int tg3_alloc_consistent(struct tg3 *tp)
                        break;
                }
 
-               tnapi->prodring = &tp->prodring[i];
-
                /*
                 * If multivector RSS is enabled, vector 0 does not handle
                 * rx or tx interrupts.  Don't allocate any resources for it.
@@ -6451,9 +6599,10 @@ static int tg3_alloc_consistent(struct tg3 *tp)
                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);
+               tnapi->rx_rcb = dma_alloc_coherent(&tp->pdev->dev,
+                                                  TG3_RX_RCB_RING_BYTES(tp),
+                                                  &tnapi->rx_rcb_mapping,
+                                                  GFP_KERNEL);
                if (!tnapi->rx_rcb)
                        goto err_out;
 
@@ -6586,6 +6735,10 @@ static void tg3_ape_send_event(struct tg3 *tp, u32 event)
        int i;
        u32 apedata;
 
+       /* NCSI does not support APE events */
+       if (tp->tg3_flags3 & TG3_FLG3_APE_HAS_NCSI)
+               return;
+
        apedata = tg3_ape_read32(tp, TG3_APE_SEG_SIG);
        if (apedata != APE_SEG_SIG_MAGIC)
                return;
@@ -6637,6 +6790,8 @@ static void tg3_ape_driver_state_change(struct tg3 *tp, int kind)
                        APE_HOST_DRIVER_ID_MAGIC(TG3_MAJ_NUM, TG3_MIN_NUM));
                tg3_ape_write32(tp, TG3_APE_HOST_BEHAVIOR,
                                APE_HOST_BEHAV_NO_PHYLOCK);
+               tg3_ape_write32(tp, TG3_APE_HOST_DRVR_STATE,
+                                   TG3_APE_HOST_DRVR_STATE_START);
 
                event = APE_EVENT_STATUS_STATE_START;
                break;
@@ -6648,6 +6803,16 @@ static void tg3_ape_driver_state_change(struct tg3 *tp, int kind)
                 */
                tg3_ape_write32(tp, TG3_APE_HOST_SEG_SIG, 0x0);
 
+               if (device_may_wakeup(&tp->pdev->dev) &&
+                   (tp->tg3_flags & TG3_FLAG_WOL_ENABLE)) {
+                       tg3_ape_write32(tp, TG3_APE_HOST_WOL_SPEED,
+                                           TG3_APE_HOST_WOL_SPEED_AUTO);
+                       apedata = TG3_APE_HOST_DRVR_STATE_WOL;
+               } else
+                       apedata = TG3_APE_HOST_DRVR_STATE_UNLOAD;
+
+               tg3_ape_write32(tp, TG3_APE_HOST_DRVR_STATE, apedata);
+
                event = APE_EVENT_STATUS_STATE_UNLOAD;
                break;
        case RESET_KIND_SUSPEND:
@@ -6821,7 +6986,7 @@ static void tg3_restore_pci_state(struct tg3 *tp)
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785) {
                if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)
-                       pcie_set_readrq(tp->pdev, 4096);
+                       pcie_set_readrq(tp->pdev, tp->pcie_readrq);
                else {
                        pci_write_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE,
                                              tp->pci_cacheline_sz);
@@ -7015,7 +7180,7 @@ static int tg3_chip_reset(struct tg3 *tp)
                                      tp->pcie_cap + PCI_EXP_DEVCTL,
                                      val16);
 
-               pcie_set_readrq(tp->pdev, 4096);
+               pcie_set_readrq(tp->pdev, tp->pcie_readrq);
 
                /* Clear error status */
                pci_write_config_word(tp->pdev,
@@ -7056,19 +7221,21 @@ static int tg3_chip_reset(struct tg3 *tp)
                tw32(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl);
        }
 
-       if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) {
-               tp->mac_mode = MAC_MODE_PORT_MODE_TBI;
-               tw32_f(MAC_MODE, tp->mac_mode);
-       } else if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) {
-               tp->mac_mode = MAC_MODE_PORT_MODE_GMII;
-               tw32_f(MAC_MODE, tp->mac_mode);
-       } else if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
-               tp->mac_mode &= (MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN);
-               if (tp->mac_mode & MAC_MODE_APE_TX_EN)
-                       tp->mac_mode |= MAC_MODE_TDE_ENABLE;
-               tw32_f(MAC_MODE, tp->mac_mode);
+       if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
+               tp->mac_mode = MAC_MODE_APE_TX_EN |
+                              MAC_MODE_APE_RX_EN |
+                              MAC_MODE_TDE_ENABLE;
+
+       if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) {
+               tp->mac_mode |= MAC_MODE_PORT_MODE_TBI;
+               val = tp->mac_mode;
+       } else if (tp->phy_flags & TG3_PHYFLG_MII_SERDES) {
+               tp->mac_mode |= MAC_MODE_PORT_MODE_GMII;
+               val = tp->mac_mode;
        } else
-               tw32_f(MAC_MODE, 0);
+               val = 0;
+
+       tw32_f(MAC_MODE, val);
        udelay(40);
 
        tg3_ape_unlock(tp, TG3_APE_LOCK_GRC);
@@ -7505,6 +7672,9 @@ static void tg3_rings_reset(struct tg3 *tp)
        /* 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_5717 ||
+                GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
+               limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 4;
        else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
                limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 2;
        else
@@ -7538,7 +7708,7 @@ static void tg3_rings_reset(struct tg3 *tp)
 
        /* Zero mailbox registers. */
        if (tp->tg3_flags & TG3_FLAG_SUPPORT_MSIX) {
-               for (i = 1; i < TG3_IRQ_MAX_VECS; i++) {
+               for (i = 1; i < tp->irq_max; i++) {
                        tp->napi[i].tx_prod = 0;
                        tp->napi[i].tx_cons = 0;
                        if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)
@@ -7584,8 +7754,8 @@ static void tg3_rings_reset(struct tg3 *tp)
 
        if (tnapi->rx_rcb) {
                tg3_set_bdinfo(tp, rxrcb, tnapi->rx_rcb_mapping,
-                              (TG3_RX_RCB_RING_SIZE(tp) <<
-                               BDINFO_FLAGS_MAXLEN_SHIFT), 0);
+                              (tp->rx_ret_ring_mask + 1) <<
+                               BDINFO_FLAGS_MAXLEN_SHIFT, 0);
                rxrcb += TG3_BDINFO_SIZE;
        }
 
@@ -7608,7 +7778,7 @@ static void tg3_rings_reset(struct tg3 *tp)
                }
 
                tg3_set_bdinfo(tp, rxrcb, tnapi->rx_rcb_mapping,
-                              (TG3_RX_RCB_RING_SIZE(tp) <<
+                              ((tp->rx_ret_ring_mask + 1) <<
                                BDINFO_FLAGS_MAXLEN_SHIFT), 0);
 
                stblk += 8;
@@ -7621,7 +7791,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 {
        u32 val, rdmac_mode;
        int i, err, limit;
-       struct tg3_rx_prodring_set *tpr = &tp->prodring[0];
+       struct tg3_rx_prodring_set *tpr = &tp->napi[0].prodring;
 
        tg3_disable_ints(tp);
 
@@ -7632,6 +7802,37 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        if (tp->tg3_flags & TG3_FLAG_INIT_COMPLETE)
                tg3_abort_hw(tp, 1);
 
+       /* Enable MAC control of LPI */
+       if (tp->phy_flags & TG3_PHYFLG_EEE_CAP) {
+               tw32_f(TG3_CPMU_EEE_LNKIDL_CTRL,
+                      TG3_CPMU_EEE_LNKIDL_PCIE_NL0 |
+                      TG3_CPMU_EEE_LNKIDL_UART_IDL);
+
+               tw32_f(TG3_CPMU_EEE_CTRL,
+                      TG3_CPMU_EEE_CTRL_EXIT_20_1_US);
+
+               val = TG3_CPMU_EEEMD_ERLY_L1_XIT_DET |
+                     TG3_CPMU_EEEMD_LPI_IN_TX |
+                     TG3_CPMU_EEEMD_LPI_IN_RX |
+                     TG3_CPMU_EEEMD_EEE_ENABLE;
+
+               if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717)
+                       val |= TG3_CPMU_EEEMD_SND_IDX_DET_EN;
+
+               if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
+                       val |= TG3_CPMU_EEEMD_APE_TX_DET_EN;
+
+               tw32_f(TG3_CPMU_EEE_MODE, val);
+
+               tw32_f(TG3_CPMU_EEE_DBTMR1,
+                      TG3_CPMU_DBTMR1_PCIEXIT_2047US |
+                      TG3_CPMU_DBTMR1_LNKIDLE_2047US);
+
+               tw32_f(TG3_CPMU_EEE_DBTMR2,
+                      TG3_CPMU_DBTMR2_APE_TX_2047US |
+                      TG3_CPMU_DBTMR2_TXIDXEQ_2047US);
+       }
+
        if (reset_phy)
                tg3_phy_reset(tp);
 
@@ -7691,18 +7892,21 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                tw32(GRC_MODE, grc_mode);
        }
 
-       if (tp->pci_chip_rev_id == CHIPREV_ID_57765_A0) {
-               u32 grc_mode = tr32(GRC_MODE);
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) {
+               if (tp->pci_chip_rev_id == CHIPREV_ID_57765_A0) {
+                       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);
+                       /* 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_PHYCTL5);
-               tw32(TG3_PCIE_TLDLPL_PORT + TG3_PCIE_PL_LO_PHYCTL5,
-                    val | TG3_PCIE_PL_LO_PHYCTL5_DIS_L2CLKREQ);
+                       val = tr32(TG3_PCIE_TLDLPL_PORT +
+                                  TG3_PCIE_PL_LO_PHYCTL5);
+                       tw32(TG3_PCIE_TLDLPL_PORT + TG3_PCIE_PL_LO_PHYCTL5,
+                            val | TG3_PCIE_PL_LO_PHYCTL5_DIS_L2CLKREQ);
 
-               tw32(GRC_MODE, grc_mode);
+                       tw32(GRC_MODE, grc_mode);
+               }
 
                val = tr32(TG3_CPMU_LSPD_10MB_CLK);
                val &= ~CPMU_LSPD_10MB_MACCLK_MASK;
@@ -7835,7 +8039,10 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        tw32(BUFMGR_DMA_HIGH_WATER,
             tp->bufmgr_config.dma_high_water);
 
-       tw32(BUFMGR_MODE, BUFMGR_MODE_ENABLE | BUFMGR_MODE_ATTN_ENABLE);
+       val = BUFMGR_MODE_ENABLE | BUFMGR_MODE_ATTN_ENABLE;
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
+               val |= BUFMGR_MODE_NO_TX_UNDERRUN;
+       tw32(BUFMGR_MODE, val);
        for (i = 0; i < 2000; i++) {
                if (tr32(BUFMGR_MODE) & BUFMGR_MODE_ENABLE)
                        break;
@@ -7896,8 +8103,9 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        /* Program the jumbo buffer descriptor ring control
         * blocks on those devices that have them.
         */
-       if ((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) &&
-           !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
+           ((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) &&
+           !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS))) {
                /* Setup replenish threshold. */
                tw32(RCVBDI_JUMBO_THRESH, tp->rx_jumbo_pending / 8);
 
@@ -7918,10 +8126,14 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                             BDINFO_FLAGS_DISABLED);
                }
 
-               if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)
-                       val = (RX_STD_MAX_SIZE_5705 << BDINFO_FLAGS_MAXLEN_SHIFT) |
-                             (TG3_RX_STD_DMA_SZ << 2);
-               else
+               if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) {
+                       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
+                               val = RX_STD_MAX_SIZE_5705;
+                       else
+                               val = RX_STD_MAX_SIZE_5717;
+                       val <<= BDINFO_FLAGS_MAXLEN_SHIFT;
+                       val |= (TG3_RX_STD_DMA_SZ << 2);
+               } else
                        val = TG3_RX_STD_DMA_SZ << BDINFO_FLAGS_MAXLEN_SHIFT;
        } else
                val = RX_STD_MAX_SIZE_5705 << BDINFO_FLAGS_MAXLEN_SHIFT;
@@ -7970,8 +8182,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                      RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB |
                      RDMAC_MODE_LNGREAD_ENAB);
 
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
                rdmac_mode |= RDMAC_MODE_MULT_DMA_RD_DIS;
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
@@ -8005,6 +8216,31 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
                rdmac_mode |= RDMAC_MODE_IPV6_LSO_EN;
 
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
+           (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) {
+               val = tr32(TG3_RDMA_RSRVCTRL_REG);
+               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) {
+                       val &= ~(TG3_RDMA_RSRVCTRL_TXMRGN_MASK |
+                                TG3_RDMA_RSRVCTRL_FIFO_LWM_MASK |
+                                TG3_RDMA_RSRVCTRL_FIFO_HWM_MASK);
+                       val |= TG3_RDMA_RSRVCTRL_TXMRGN_320B |
+                              TG3_RDMA_RSRVCTRL_FIFO_LWM_1_5K |
+                              TG3_RDMA_RSRVCTRL_FIFO_HWM_1_5K;
+               }
+               tw32(TG3_RDMA_RSRVCTRL_REG,
+                    val | TG3_RDMA_RSRVCTRL_FIFO_OFLW_FIX);
+       }
+
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) {
+               val = tr32(TG3_LSO_RD_DMA_CRPTEN_CTRL);
+               tw32(TG3_LSO_RD_DMA_CRPTEN_CTRL, val |
+                    TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_BD_4K |
+                    TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_LSO_4K);
+       }
+
        /* Receive/send statistics. */
        if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) {
                val = tr32(RCVLPC_STATS_ENABLE);
@@ -8063,21 +8299,21 @@ 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);
 
-       if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) {
-               tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT;
+       if (tp->phy_flags & TG3_PHYFLG_MII_SERDES) {
+               tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT;
                /* reset to prevent losing 1st rx packet intermittently */
                tw32_f(MAC_RX_MODE, RX_MODE_RESET);
                udelay(10);
        }
 
        if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
-               tp->mac_mode &= MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN;
+               tp->mac_mode = MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN;
        else
                tp->mac_mode = 0;
        tp->mac_mode |= MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE |
                MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | MAC_MODE_FHDE_ENABLE;
        if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
-           !(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) &&
+           !(tp->phy_flags & TG3_PHYFLG_PHY_SERDES) &&
            GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700)
                tp->mac_mode |= MAC_MODE_LINK_POLARITY;
        tw32_f(MAC_MODE, tp->mac_mode | MAC_MODE_RXSTAT_CLEAR | MAC_MODE_TXSTAT_CLEAR);
@@ -8114,7 +8350,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
        udelay(100);
 
-       if (tp->tg3_flags2 & TG3_FLG2_USING_MSIX) {
+       if ((tp->tg3_flags2 & TG3_FLG2_USING_MSIX) &&
+               tp->irq_cnt > 1) {
                val = tr32(MSGINT_MODE);
                val |= MSGINT_MODE_MULTIVEC_EN | MSGINT_MODE_ENABLE;
                tw32(MSGINT_MODE, val);
@@ -8187,7 +8424,11 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 
        tw32(SNDBDC_MODE, SNDBDC_MODE_ENABLE | SNDBDC_MODE_ATTN_ENABLE);
        tw32(RCVBDI_MODE, RCVBDI_MODE_ENABLE | RCVBDI_MODE_RCB_ATTN_ENAB);
-       tw32(RCVDBDI_MODE, RCVDBDI_MODE_ENABLE | RCVDBDI_MODE_INV_RING_SZ);
+       val = RCVDBDI_MODE_ENABLE | RCVDBDI_MODE_INV_RING_SZ;
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
+               val |= RCVDBDI_MODE_LRG_RING_SZ;
+       tw32(RCVDBDI_MODE, val);
        tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE);
        if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
                tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE | 0x8);
@@ -8262,16 +8503,16 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        tw32(MAC_LED_CTRL, tp->led_ctrl);
 
        tw32(MAC_MI_STAT, MAC_MI_STAT_LNKSTAT_ATTN_ENAB);
-       if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) {
+       if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) {
                tw32_f(MAC_RX_MODE, RX_MODE_RESET);
                udelay(10);
        }
        tw32_f(MAC_RX_MODE, tp->rx_mode);
        udelay(10);
 
-       if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) {
+       if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) {
                if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) &&
-                       !(tp->tg3_flags2 & TG3_FLG2_SERDES_PREEMPHASIS)) {
+                       !(tp->phy_flags & TG3_PHYFLG_SERDES_PREEMPHASIS)) {
                        /* Set drive transmission level to 1.2V  */
                        /* only if the signal pre-emphasis bit is not set  */
                        val = tr32(MAC_SERDES_CFG);
@@ -8293,12 +8534,12 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        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)) {
+           (tp->phy_flags & TG3_PHYFLG_PHY_SERDES)) {
                /* Use hardware link auto-negotiation */
                tp->tg3_flags2 |= TG3_FLG2_HW_AUTONEG;
        }
 
-       if ((tp->tg3_flags2 & TG3_FLG2_MII_SERDES) &&
+       if ((tp->phy_flags & TG3_PHYFLG_MII_SERDES) &&
            (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714)) {
                u32 tmp;
 
@@ -8310,8 +8551,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        }
 
        if (!(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)) {
-               if (tp->link_config.phy_is_low_power) {
-                       tp->link_config.phy_is_low_power = 0;
+               if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) {
+                       tp->phy_flags &= ~TG3_PHYFLG_IS_LOW_POWER;
                        tp->link_config.speed = tp->link_config.orig_speed;
                        tp->link_config.duplex = tp->link_config.orig_duplex;
                        tp->link_config.autoneg = tp->link_config.orig_autoneg;
@@ -8321,15 +8562,15 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                if (err)
                        return err;
 
-               if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) &&
-                   !(tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET)) {
+               if (!(tp->phy_flags & TG3_PHYFLG_PHY_SERDES) &&
+                   !(tp->phy_flags & TG3_PHYFLG_IS_FET)) {
                        u32 tmp;
 
                        /* Clear CRC stats. */
                        if (!tg3_readphy(tp, MII_TG3_TEST1, &tmp)) {
                                tg3_writephy(tp, MII_TG3_TEST1,
                                             tmp | MII_TG3_TEST1_CRC_EN);
-                               tg3_readphy(tp, 0x14, &tmp);
+                               tg3_readphy(tp, MII_TG3_RXR_COUNTERS, &tmp);
                        }
                }
        }
@@ -8490,6 +8731,12 @@ static void tg3_timer(unsigned long __opaque)
                if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)
                        tg3_periodic_fetch_stats(tp);
 
+               if (tp->setlpicnt && !--tp->setlpicnt) {
+                       u32 val = tr32(TG3_CPMU_EEE_MODE);
+                       tw32(TG3_CPMU_EEE_MODE,
+                            val | TG3_CPMU_EEEMD_LPI_ENABLE);
+               }
+
                if (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) {
                        u32 mac_stat;
                        int phy_event;
@@ -8497,7 +8744,7 @@ static void tg3_timer(unsigned long __opaque)
                        mac_stat = tr32(MAC_STATUS);
 
                        phy_event = 0;
-                       if (tp->tg3_flags & TG3_FLAG_USE_MI_INTERRUPT) {
+                       if (tp->phy_flags & TG3_PHYFLG_USE_MI_INTERRUPT) {
                                if (mac_stat & MAC_STATUS_MI_INTERRUPT)
                                        phy_event = 1;
                        } else if (mac_stat & MAC_STATUS_LNKSTATE_CHANGED)
@@ -8529,7 +8776,7 @@ static void tg3_timer(unsigned long __opaque)
                                }
                                tg3_setup_phy(tp, 0);
                        }
-               } else if ((tp->tg3_flags2 & TG3_FLG2_MII_SERDES) &&
+               } else if ((tp->phy_flags & TG3_PHYFLG_MII_SERDES) &&
                           (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
                        tg3_serdes_parallel_detect(tp);
                }
@@ -8806,14 +9053,18 @@ static bool tg3_enable_msix(struct tg3 *tp)
        for (i = 0; i < tp->irq_max; i++)
                tp->napi[i].irq_vec = msix_ent[i].vector;
 
-       tp->dev->real_num_tx_queues = 1;
+       netif_set_real_num_tx_queues(tp->dev, 1);
+       rc = tp->irq_cnt > 1 ? tp->irq_cnt - 1 : 1;
+       if (netif_set_real_num_rx_queues(tp->dev, rc)) {
+               pci_disable_msix(tp->pdev);
+               return false;
+       }
+
        if (tp->irq_cnt > 1) {
                tp->tg3_flags3 |= TG3_FLG3_ENABLE_RSS;
-
-               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
-                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) {
+               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) {
                        tp->tg3_flags3 |= TG3_FLG3_ENABLE_TSS;
-                       tp->dev->real_num_tx_queues = tp->irq_cnt - 1;
+                       netif_set_real_num_tx_queues(tp->dev, tp->irq_cnt - 1);
                }
        }
 
@@ -8840,7 +9091,8 @@ static void tg3_ints_init(struct tg3 *tp)
 
        if (tp->tg3_flags2 & TG3_FLG2_USING_MSI_OR_MSIX) {
                u32 msi_mode = tr32(MSGINT_MODE);
-               if (tp->tg3_flags2 & TG3_FLG2_USING_MSIX)
+               if ((tp->tg3_flags2 & TG3_FLG2_USING_MSIX) &&
+                   tp->irq_cnt > 1)
                        msi_mode |= MSGINT_MODE_MULTIVEC_EN;
                tw32(MSGINT_MODE, msi_mode | MSGINT_MODE_ENABLE);
        }
@@ -8848,7 +9100,8 @@ 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;
+               netif_set_real_num_tx_queues(tp->dev, 1);
+               netif_set_real_num_rx_queues(tp->dev, 1);
        }
 }
 
@@ -8883,7 +9136,7 @@ static int tg3_open(struct net_device *dev)
 
        netif_carrier_off(tp->dev);
 
-       err = tg3_set_power_state(tp, PCI_D0);
+       err = tg3_power_up(tp);
        if (err)
                return err;
 
@@ -8907,6 +9160,8 @@ static int tg3_open(struct net_device *dev)
        if (err)
                goto err_out1;
 
+       tg3_napi_init(tp);
+
        tg3_napi_enable(tp);
 
        for (i = 0; i < tp->irq_cnt; i++) {
@@ -8994,6 +9249,7 @@ err_out3:
 
 err_out2:
        tg3_napi_disable(tp);
+       tg3_napi_fini(tp);
        tg3_free_consistent(tp);
 
 err_out1:
@@ -9041,9 +9297,11 @@ static int tg3_close(struct net_device *dev)
        memcpy(&tp->estats_prev, tg3_get_estats(tp),
               sizeof(tp->estats_prev));
 
+       tg3_napi_fini(tp);
+
        tg3_free_consistent(tp);
 
-       tg3_set_power_state(tp, PCI_D3hot);
+       tg3_power_down(tp);
 
        netif_carrier_off(tp->dev);
 
@@ -9059,7 +9317,7 @@ static u64 calc_crc_errors(struct tg3 *tp)
 {
        struct tg3_hw_stats *hw_stats = tp->hw_stats;
 
-       if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) &&
+       if (!(tp->phy_flags & TG3_PHYFLG_PHY_SERDES) &&
            (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
             GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)) {
                u32 val;
@@ -9068,7 +9326,7 @@ static u64 calc_crc_errors(struct tg3 *tp)
                if (!tg3_readphy(tp, MII_TG3_TEST1, &val)) {
                        tg3_writephy(tp, MII_TG3_TEST1,
                                     val | MII_TG3_TEST1_CRC_EN);
-                       tg3_readphy(tp, 0x14, &val);
+                       tg3_readphy(tp, MII_TG3_RXR_COUNTERS, &val);
                } else
                        val = 0;
                spin_unlock_bh(&tp->lock);
@@ -9230,6 +9488,8 @@ static struct rtnl_link_stats64 *tg3_get_stats64(struct net_device *dev,
        stats->rx_missed_errors = old_stats->rx_missed_errors +
                get_stat64(&hw_stats->rx_discards);
 
+       stats->rx_dropped = tp->rx_dropped;
+
        return stats;
 }
 
@@ -9274,17 +9534,10 @@ static void __tg3_set_rx_mode(struct net_device *dev)
        rx_mode = tp->rx_mode & ~(RX_MODE_PROMISC |
                                  RX_MODE_KEEP_VLAN_TAG);
 
+#if !defined(CONFIG_VLAN_8021Q) && !defined(CONFIG_VLAN_8021Q_MODULE)
        /* When ASF is in use, we always keep the RX_MODE_KEEP_VLAN_TAG
         * flag clear.
         */
-#if TG3_VLAN_TAG_USED
-       if (!tp->vlgrp &&
-           !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF))
-               rx_mode |= RX_MODE_KEEP_VLAN_TAG;
-#else
-       /* By definition, VLAN is disabled always in this
-        * case.
-        */
        if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF))
                rx_mode |= RX_MODE_KEEP_VLAN_TAG;
 #endif
@@ -9358,7 +9611,7 @@ static void tg3_get_regs(struct net_device *dev,
 
        memset(p, 0, TG3_REGDUMP_LEN);
 
-       if (tp->link_config.phy_is_low_power)
+       if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)
                return;
 
        tg3_full_lock(tp, 0);
@@ -9437,7 +9690,7 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
        if (tp->tg3_flags3 & TG3_FLG3_NO_NVRAM)
                return -EINVAL;
 
-       if (tp->link_config.phy_is_low_power)
+       if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)
                return -EAGAIN;
 
        offset = eeprom->offset;
@@ -9499,7 +9752,7 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
        u8 *buf;
        __be32 start, end;
 
-       if (tp->link_config.phy_is_low_power)
+       if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)
                return -EAGAIN;
 
        if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) ||
@@ -9556,7 +9809,7 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 
        if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
                struct phy_device *phydev;
-               if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
+               if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED))
                        return -EAGAIN;
                phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
                return phy_ethtool_gset(phydev, cmd);
@@ -9564,11 +9817,11 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 
        cmd->supported = (SUPPORTED_Autoneg);
 
-       if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY))
+       if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY))
                cmd->supported |= (SUPPORTED_1000baseT_Half |
                                   SUPPORTED_1000baseT_Full);
 
-       if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)) {
+       if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES)) {
                cmd->supported |= (SUPPORTED_100baseT_Half |
                                  SUPPORTED_100baseT_Full |
                                  SUPPORTED_10baseT_Half |
@@ -9584,6 +9837,9 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
        if (netif_running(dev)) {
                cmd->speed = tp->link_config.active_speed;
                cmd->duplex = tp->link_config.active_duplex;
+       } else {
+               cmd->speed = SPEED_INVALID;
+               cmd->duplex = DUPLEX_INVALID;
        }
        cmd->phy_address = tp->phy_addr;
        cmd->transceiver = XCVR_INTERNAL;
@@ -9599,7 +9855,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 
        if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
                struct phy_device *phydev;
-               if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
+               if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED))
                        return -EAGAIN;
                phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
                return phy_ethtool_sset(phydev, cmd);
@@ -9619,11 +9875,11 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                           ADVERTISED_Pause |
                           ADVERTISED_Asym_Pause;
 
-               if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY))
+               if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY))
                        mask |= ADVERTISED_1000baseT_Half |
                                ADVERTISED_1000baseT_Full;
 
-               if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES))
+               if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES))
                        mask |= ADVERTISED_100baseT_Half |
                                ADVERTISED_100baseT_Full |
                                ADVERTISED_10baseT_Half |
@@ -9644,7 +9900,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 
                cmd->advertising &= mask;
        } else {
-               if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) {
+               if (tp->phy_flags & TG3_PHYFLG_ANY_SERDES) {
                        if (cmd->speed != SPEED_1000)
                                return -EINVAL;
 
@@ -9720,16 +9976,16 @@ static int tg3_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
            !((tp->tg3_flags & TG3_FLAG_WOL_CAP) && device_can_wakeup(dp)))
                return -EINVAL;
 
+       device_set_wakeup_enable(dp, wol->wolopts & WAKE_MAGIC);
+
        spin_lock_bh(&tp->lock);
-       if (wol->wolopts & WAKE_MAGIC) {
+       if (device_may_wakeup(dp))
                tp->tg3_flags |= TG3_FLAG_WOL_ENABLE;
-               device_set_wakeup_enable(dp, true);
-       } else {
+       else
                tp->tg3_flags &= ~TG3_FLAG_WOL_ENABLE;
-               device_set_wakeup_enable(dp, false);
-       }
        spin_unlock_bh(&tp->lock);
 
+
        return 0;
 }
 
@@ -9780,11 +10036,11 @@ static int tg3_nway_reset(struct net_device *dev)
        if (!netif_running(dev))
                return -EAGAIN;
 
-       if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)
+       if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES)
                return -EINVAL;
 
        if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
-               if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
+               if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED))
                        return -EAGAIN;
                r = phy_start_aneg(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]);
        } else {
@@ -9795,7 +10051,7 @@ static int tg3_nway_reset(struct net_device *dev)
                tg3_readphy(tp, MII_BMCR, &bmcr);
                if (!tg3_readphy(tp, MII_BMCR, &bmcr) &&
                    ((bmcr & BMCR_ANENABLE) ||
-                    (tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT))) {
+                    (tp->phy_flags & TG3_PHYFLG_PARALLEL_DETECT))) {
                        tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANRESTART |
                                                   BMCR_ANENABLE);
                        r = 0;
@@ -9810,10 +10066,10 @@ static void tg3_get_ringparam(struct net_device *dev, struct ethtool_ringparam *
 {
        struct tg3 *tp = netdev_priv(dev);
 
-       ering->rx_max_pending = TG3_RX_RING_SIZE - 1;
+       ering->rx_max_pending = tp->rx_std_ring_mask;
        ering->rx_mini_max_pending = 0;
        if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE)
-               ering->rx_jumbo_max_pending = TG3_RX_JUMBO_RING_SIZE - 1;
+               ering->rx_jumbo_max_pending = tp->rx_jmb_ring_mask;
        else
                ering->rx_jumbo_max_pending = 0;
 
@@ -9834,8 +10090,8 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e
        struct tg3 *tp = netdev_priv(dev);
        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) ||
+       if ((ering->rx_pending > tp->rx_std_ring_mask) ||
+           (ering->rx_jumbo_pending > tp->rx_jmb_ring_mask) ||
            (ering->tx_pending > TG3_TX_RING_SIZE - 1) ||
            (ering->tx_pending <= MAX_SKB_FRAGS) ||
            ((tp->tg3_flags2 & TG3_FLG2_TSO_BUG) &&
@@ -9857,7 +10113,7 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e
                tp->rx_pending = 63;
        tp->rx_jumbo_pending = ering->rx_jumbo_pending;
 
-       for (i = 0; i < TG3_IRQ_MAX_VECS; i++)
+       for (i = 0; i < tp->irq_max; i++)
                tp->napi[i].tx_pending = ering->tx_pending;
 
        if (netif_running(dev)) {
@@ -9905,8 +10161,7 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam
 
                if (!(phydev->supported & SUPPORTED_Pause) ||
                    (!(phydev->supported & SUPPORTED_Asym_Pause) &&
-                    ((epause->rx_pause && !epause->tx_pause) ||
-                     (!epause->rx_pause && epause->tx_pause))))
+                    (epause->rx_pause != epause->tx_pause)))
                        return -EINVAL;
 
                tp->link_config.flowctrl = 0;
@@ -9930,7 +10185,7 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam
                else
                        tp->tg3_flags &= ~TG3_FLAG_PAUSE_AUTONEG;
 
-               if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) {
+               if (tp->phy_flags & TG3_PHYFLG_IS_CONNECTED) {
                        u32 oldadv = phydev->advertising &
                                     (ADVERTISED_Pause | ADVERTISED_Asym_Pause);
                        if (oldadv != newadv) {
@@ -10232,16 +10487,53 @@ static int tg3_test_nvram(struct tg3 *tp)
                goto out;
        }
 
+       err = -EIO;
+
        /* Bootstrap checksum at offset 0x10 */
        csum = calc_crc((unsigned char *) buf, 0x10);
-       if (csum != be32_to_cpu(buf[0x10/4]))
+       if (csum != le32_to_cpu(buf[0x10/4]))
                goto out;
 
        /* Manufacturing block starts at offset 0x74, checksum at 0xfc */
        csum = calc_crc((unsigned char *) &buf[0x74/4], 0x88);
-       if (csum != be32_to_cpu(buf[0xfc/4]))
+       if (csum != le32_to_cpu(buf[0xfc/4]))
                goto out;
 
+       for (i = 0; i < TG3_NVM_VPD_LEN; i += 4) {
+               /* 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, TG3_NVM_VPD_OFF + i, &buf[i/4]))
+                       goto out;
+       }
+
+       i = pci_vpd_find_tag((u8 *)buf, 0, TG3_NVM_VPD_LEN,
+                            PCI_VPD_LRDT_RO_DATA);
+       if (i > 0) {
+               j = pci_vpd_lrdt_size(&((u8 *)buf)[i]);
+               if (j < 0)
+                       goto out;
+
+               if (i + PCI_VPD_LRDT_TAG_SIZE + j > TG3_NVM_VPD_LEN)
+                       goto out;
+
+               i += PCI_VPD_LRDT_TAG_SIZE;
+               j = pci_vpd_find_info_keyword((u8 *)buf, i, j,
+                                             PCI_VPD_RO_KEYWORD_CHKSUM);
+               if (j > 0) {
+                       u8 csum8 = 0;
+
+                       j += PCI_VPD_INFO_FLD_HDR_SIZE;
+
+                       for (i = 0; i <= j; i++)
+                               csum8 += ((u8 *)buf)[i];
+
+                       if (csum8)
+                               goto out;
+               }
+       }
+
        err = 0;
 
 out:
@@ -10259,7 +10551,7 @@ static int tg3_test_link(struct tg3 *tp)
        if (!netif_running(tp->dev))
                return -ENODEV;
 
-       if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)
+       if (tp->phy_flags & TG3_PHYFLG_ANY_SERDES)
                max = TG3_SERDES_TIMEOUT_SEC;
        else
                max = TG3_COPPER_TIMEOUT_SEC;
@@ -10598,12 +10890,13 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
        int num_pkts, tx_len, rx_len, i, err;
        struct tg3_rx_buffer_desc *desc;
        struct tg3_napi *tnapi, *rnapi;
-       struct tg3_rx_prodring_set *tpr = &tp->prodring[0];
+       struct tg3_rx_prodring_set *tpr = &tp->napi[0].prodring;
 
        tnapi = &tp->napi[0];
        rnapi = &tp->napi[0];
        if (tp->irq_cnt > 1) {
-               rnapi = &tp->napi[1];
+               if (tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS)
+                       rnapi = &tp->napi[1];
                if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)
                        tnapi = &tp->napi[1];
        }
@@ -10612,16 +10905,19 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
        if (loopback_mode == TG3_MAC_LOOPBACK) {
                /* HW errata - mac loopback fails in some cases on 5780.
                 * Normal traffic and PHY loopback are not affected by
-                * errata.
+                * errata.  Also, the MAC loopback test is deprecated for
+                * all newer ASIC revisions.
                 */
-               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)
+               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 ||
+                   (tp->tg3_flags & TG3_FLAG_CPMU_PRESENT))
                        return 0;
 
-               mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) |
-                          MAC_MODE_PORT_INT_LPBACK;
+               mac_mode = tp->mac_mode &
+                          ~(MAC_MODE_PORT_MODE_MASK | MAC_MODE_HALF_DUPLEX);
+               mac_mode |= MAC_MODE_PORT_INT_LPBACK;
                if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
                        mac_mode |= MAC_MODE_LINK_POLARITY;
-               if (tp->tg3_flags & TG3_FLAG_10_100_ONLY)
+               if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY)
                        mac_mode |= MAC_MODE_PORT_MODE_MII;
                else
                        mac_mode |= MAC_MODE_PORT_MODE_GMII;
@@ -10629,7 +10925,7 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
        } else if (loopback_mode == TG3_PHY_LOOPBACK) {
                u32 val;
 
-               if (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) {
+               if (tp->phy_flags & TG3_PHYFLG_IS_FET) {
                        tg3_phy_fet_toggle_apd(tp, false);
                        val = BMCR_LOOPBACK | BMCR_FULLDPLX | BMCR_SPEED100;
                } else
@@ -10640,8 +10936,9 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
                tg3_writephy(tp, MII_BMCR, val);
                udelay(40);
 
-               mac_mode = tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK;
-               if (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) {
+               mac_mode = tp->mac_mode &
+                          ~(MAC_MODE_PORT_MODE_MASK | MAC_MODE_HALF_DUPLEX);
+               if (tp->phy_flags & TG3_PHYFLG_IS_FET) {
                        tg3_writephy(tp, MII_TG3_FET_PTEST,
                                     MII_TG3_FET_PTEST_FRC_TX_LINK |
                                     MII_TG3_FET_PTEST_FRC_TX_LOCK);
@@ -10653,7 +10950,7 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
                        mac_mode |= MAC_MODE_PORT_MODE_GMII;
 
                /* reset to prevent losing 1st rx packet intermittently */
-               if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) {
+               if (tp->phy_flags & TG3_PHYFLG_MII_SERDES) {
                        tw32_f(MAC_RX_MODE, RX_MODE_RESET);
                        udelay(10);
                        tw32_f(MAC_RX_MODE, tp->rx_mode);
@@ -10668,6 +10965,13 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
                                     MII_TG3_EXT_CTRL_LNK3_LED_MODE);
                }
                tw32(MAC_MODE, mac_mode);
+
+               /* Wait for link */
+               for (i = 0; i < 100; i++) {
+                       if (tr32(MAC_TX_STATUS) & TX_STATUS_LINK_UP)
+                               break;
+                       mdelay(1);
+               }
        } else {
                return -EINVAL;
        }
@@ -10774,17 +11078,22 @@ out:
 static int tg3_test_loopback(struct tg3 *tp)
 {
        int err = 0;
-       u32 cpmuctrl = 0;
+       u32 eee_cap, cpmuctrl = 0;
 
        if (!netif_running(tp->dev))
                return TG3_LOOPBACK_FAILED;
 
+       eee_cap = tp->phy_flags & TG3_PHYFLG_EEE_CAP;
+       tp->phy_flags &= ~TG3_PHYFLG_EEE_CAP;
+
        err = tg3_reset_hw(tp, 1);
-       if (err)
-               return TG3_LOOPBACK_FAILED;
+       if (err) {
+               err = TG3_LOOPBACK_FAILED;
+               goto done;
+       }
 
        /* Turn off gphy autopowerdown. */
-       if (tp->tg3_flags3 & TG3_FLG3_PHY_ENABLE_APD)
+       if (tp->phy_flags & TG3_PHYFLG_ENABLE_APD)
                tg3_phy_toggle_apd(tp, false);
 
        if (tp->tg3_flags & TG3_FLAG_CPMU_PRESENT) {
@@ -10801,8 +11110,10 @@ static int tg3_test_loopback(struct tg3 *tp)
                        udelay(10);
                }
 
-               if (status != CPMU_MUTEX_GNT_DRIVER)
-                       return TG3_LOOPBACK_FAILED;
+               if (status != CPMU_MUTEX_GNT_DRIVER) {
+                       err = TG3_LOOPBACK_FAILED;
+                       goto done;
+               }
 
                /* Turn off link-based power management. */
                cpmuctrl = tr32(TG3_CPMU_CTRL);
@@ -10821,16 +11132,19 @@ static int tg3_test_loopback(struct tg3 *tp)
                tw32(TG3_CPMU_MUTEX_GNT, CPMU_MUTEX_GNT_DRIVER);
        }
 
-       if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) &&
+       if (!(tp->phy_flags & TG3_PHYFLG_PHY_SERDES) &&
            !(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)) {
                if (tg3_run_loopback(tp, TG3_PHY_LOOPBACK))
                        err |= TG3_PHY_LOOPBACK_FAILED;
        }
 
        /* Re-enable gphy autopowerdown. */
-       if (tp->tg3_flags3 & TG3_FLG3_PHY_ENABLE_APD)
+       if (tp->phy_flags & TG3_PHYFLG_ENABLE_APD)
                tg3_phy_toggle_apd(tp, true);
 
+done:
+       tp->phy_flags |= eee_cap;
+
        return err;
 }
 
@@ -10839,8 +11153,8 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
 {
        struct tg3 *tp = netdev_priv(dev);
 
-       if (tp->link_config.phy_is_low_power)
-               tg3_set_power_state(tp, PCI_D0);
+       if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)
+               tg3_power_up(tp);
 
        memset(data, 0, sizeof(u64) * TG3_NUM_TEST);
 
@@ -10871,7 +11185,7 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
                if (!err)
                        tg3_nvram_unlock(tp);
 
-               if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)
+               if (tp->phy_flags & TG3_PHYFLG_MII_SERDES)
                        tg3_phy_reset(tp);
 
                if (tg3_test_registers(tp) != 0) {
@@ -10907,8 +11221,8 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
                if (irq_sync && !err2)
                        tg3_phy_start(tp);
        }
-       if (tp->link_config.phy_is_low_power)
-               tg3_set_power_state(tp, PCI_D3hot);
+       if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)
+               tg3_power_down(tp);
 
 }
 
@@ -10920,7 +11234,7 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 
        if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
                struct phy_device *phydev;
-               if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
+               if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED))
                        return -EAGAIN;
                phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
                return phy_mii_ioctl(phydev, ifr, cmd);
@@ -10934,10 +11248,12 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
        case SIOCGMIIREG: {
                u32 mii_regval;
 
-               if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)
+               if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES)
                        break;                  /* We have no PHY */
 
-               if (tp->link_config.phy_is_low_power)
+               if ((tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) ||
+                   ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) &&
+                    !netif_running(dev)))
                        return -EAGAIN;
 
                spin_lock_bh(&tp->lock);
@@ -10950,10 +11266,12 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
        }
 
        case SIOCSMIIREG:
-               if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)
+               if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES)
                        break;                  /* We have no PHY */
 
-               if (tp->link_config.phy_is_low_power)
+               if ((tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) ||
+                   ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) &&
+                    !netif_running(dev)))
                        return -EAGAIN;
 
                spin_lock_bh(&tp->lock);
@@ -10969,31 +11287,6 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
        return -EOPNOTSUPP;
 }
 
-#if TG3_VLAN_TAG_USED
-static void tg3_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
-{
-       struct tg3 *tp = netdev_priv(dev);
-
-       if (!netif_running(dev)) {
-               tp->vlgrp = grp;
-               return;
-       }
-
-       tg3_netif_stop(tp);
-
-       tg3_full_lock(tp, 0);
-
-       tp->vlgrp = grp;
-
-       /* Update RX_MODE_KEEP_VLAN_TAG bit in RX_MODE register. */
-       __tg3_set_rx_mode(dev);
-
-       tg3_netif_start(tp);
-
-       tg3_full_unlock(tp);
-}
-#endif
-
 static int tg3_get_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
 {
        struct tg3 *tp = netdev_priv(dev);
@@ -12081,9 +12374,9 @@ 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_5705_PLUS))
-                               tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES;
+                               tp->phy_flags |= TG3_PHYFLG_PHY_SERDES;
                        else
-                               tp->tg3_flags2 |= TG3_FLG2_MII_SERDES;
+                               tp->phy_flags |= TG3_PHYFLG_MII_SERDES;
                }
 
                if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS)
@@ -12167,7 +12460,7 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
                        (tp->tg3_flags2 & TG3_FLG2_5750_PLUS))
                        tp->tg3_flags3 |= TG3_FLG3_ENABLE_APE;
 
-               if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES &&
+               if (tp->phy_flags & TG3_PHYFLG_ANY_SERDES &&
                    !(nic_cfg & NIC_SRAM_DATA_CFG_FIBER_WOL))
                        tp->tg3_flags &= ~TG3_FLAG_WOL_CAP;
 
@@ -12176,17 +12469,18 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
                        tp->tg3_flags |= TG3_FLAG_WOL_ENABLE;
 
                if (cfg2 & (1 << 17))
-                       tp->tg3_flags2 |= TG3_FLG2_CAPACITIVE_COUPLING;
+                       tp->phy_flags |= TG3_PHYFLG_CAPACITIVE_COUPLING;
 
                /* serdes signal pre-emphasis in register 0x590 set by */
                /* bootcode if bit 18 is set */
                if (cfg2 & (1 << 18))
-                       tp->tg3_flags2 |= TG3_FLG2_SERDES_PREEMPHASIS;
+                       tp->phy_flags |= TG3_PHYFLG_SERDES_PREEMPHASIS;
 
-               if (((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
-                     GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX)) &&
+               if (((tp->tg3_flags3 & TG3_FLG3_5717_PLUS) ||
+                   ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
+                     GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX))) &&
                    (cfg2 & NIC_SRAM_DATA_CFG_2_APD_EN))
-                       tp->tg3_flags3 |= TG3_FLG3_PHY_ENABLE_APD;
+                       tp->phy_flags |= TG3_PHYFLG_ENABLE_APD;
 
                if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) &&
                    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785 &&
@@ -12206,9 +12500,11 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
                        tp->tg3_flags3 |= TG3_FLG3_RGMII_EXT_IBND_TX_EN;
        }
 done:
-       device_init_wakeup(&tp->pdev->dev, tp->tg3_flags & TG3_FLAG_WOL_CAP);
-       device_set_wakeup_enable(&tp->pdev->dev,
+       if (tp->tg3_flags & TG3_FLAG_WOL_CAP)
+               device_set_wakeup_enable(&tp->pdev->dev,
                                 tp->tg3_flags & TG3_FLAG_WOL_ENABLE);
+       else
+               device_set_wakeup_capable(&tp->pdev->dev, false);
 }
 
 static int __devinit tg3_issue_otp_command(struct tg3 *tp, u32 cmd)
@@ -12295,9 +12591,9 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
        if (!err && TG3_KNOWN_PHY_ID(hw_phy_id_masked)) {
                tp->phy_id = hw_phy_id;
                if (hw_phy_id_masked == TG3_PHY_ID_BCM8002)
-                       tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES;
+                       tp->phy_flags |= TG3_PHYFLG_PHY_SERDES;
                else
-                       tp->tg3_flags2 &= ~TG3_FLG2_PHY_SERDES;
+                       tp->phy_flags &= ~TG3_PHYFLG_PHY_SERDES;
        } else {
                if (tp->phy_id != TG3_PHY_ID_INVALID) {
                        /* Do nothing, phy ID already set up in
@@ -12316,11 +12612,18 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
                        tp->phy_id = p->phy_id;
                        if (!tp->phy_id ||
                            tp->phy_id == TG3_PHY_ID_BCM8002)
-                               tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES;
+                               tp->phy_flags |= TG3_PHYFLG_PHY_SERDES;
                }
        }
 
-       if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) &&
+       if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES) &&
+           ((tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 &&
+             tp->pci_chip_rev_id != CHIPREV_ID_5717_A0) ||
+            (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 &&
+             tp->pci_chip_rev_id != CHIPREV_ID_57765_A0)))
+               tp->phy_flags |= TG3_PHYFLG_EEE_CAP;
+
+       if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES) &&
            !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) &&
            !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
                u32 bmsr, adv_reg, tg3_ctrl, mask;
@@ -12338,7 +12641,7 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
                           ADVERTISE_100HALF | ADVERTISE_100FULL |
                           ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
                tg3_ctrl = 0;
-               if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) {
+               if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) {
                        tg3_ctrl = (MII_TG3_CTRL_ADV_1000_HALF |
                                    MII_TG3_CTRL_ADV_1000_FULL);
                        if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
@@ -12353,7 +12656,7 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
                if (!tg3_copper_is_advertising_all(tp, mask)) {
                        tg3_writephy(tp, MII_ADVERTISE, adv_reg);
 
-                       if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY))
+                       if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY))
                                tg3_writephy(tp, MII_TG3_CTRL, tg3_ctrl);
 
                        tg3_writephy(tp, MII_BMCR,
@@ -12362,7 +12665,7 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
                tg3_phy_set_wirespeed(tp);
 
                tg3_writephy(tp, MII_ADVERTISE, adv_reg);
-               if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY))
+               if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY))
                        tg3_writephy(tp, MII_TG3_CTRL, tg3_ctrl);
        }
 
@@ -12375,13 +12678,13 @@ skip_phy_reset:
                err = tg3_init_5401phy_dsp(tp);
        }
 
-       if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)
+       if (tp->phy_flags & TG3_PHYFLG_ANY_SERDES)
                tp->link_config.advertising =
                        (ADVERTISED_1000baseT_Half |
                         ADVERTISED_1000baseT_Full |
                         ADVERTISED_Autoneg |
                         ADVERTISED_FIBRE);
-       if (tp->tg3_flags & TG3_FLAG_10_100_ONLY)
+       if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY)
                tp->link_config.advertising &=
                        ~(ADVERTISED_1000baseT_Half |
                          ADVERTISED_1000baseT_Full);
@@ -12391,14 +12694,18 @@ skip_phy_reset:
 
 static void __devinit tg3_read_vpd(struct tg3 *tp)
 {
-       u8 vpd_data[TG3_NVM_VPD_LEN];
+       u8 *vpd_data;
        unsigned int block_end, rosize, len;
        int j, i = 0;
        u32 magic;
 
        if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) ||
            tg3_nvram_read(tp, 0x0, &magic))
-               goto out_not_found;
+               goto out_no_vpd;
+
+       vpd_data = kmalloc(TG3_NVM_VPD_LEN, GFP_KERNEL);
+       if (!vpd_data)
+               goto out_no_vpd;
 
        if (magic == TG3_EEPROM_MAGIC) {
                for (i = 0; i < TG3_NVM_VPD_LEN; i += 4) {
@@ -12421,7 +12728,7 @@ static void __devinit tg3_read_vpd(struct tg3 *tp)
                        cnt = pci_read_vpd(tp->pdev, pos,
                                           TG3_NVM_VPD_LEN - pos,
                                           &vpd_data[pos]);
-                       if (cnt == -ETIMEDOUT || -EINTR)
+                       if (cnt == -ETIMEDOUT || cnt == -EINTR)
                                cnt = 0;
                        else if (cnt < 0)
                                goto out_not_found;
@@ -12482,43 +12789,51 @@ partno:
 
        memcpy(tp->board_part_number, &vpd_data[i], len);
 
-       return;
-
 out_not_found:
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+       kfree(vpd_data);
+       if (tp->board_part_number[0])
+               return;
+
+out_no_vpd:
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) {
+               if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717)
+                       strcpy(tp->board_part_number, "BCM5717");
+               else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718)
+                       strcpy(tp->board_part_number, "BCM5718");
+               else
+                       goto nomatch;
+       } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) {
+               if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57780)
+                       strcpy(tp->board_part_number, "BCM57780");
+               else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57760)
+                       strcpy(tp->board_part_number, "BCM57760");
+               else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57790)
+                       strcpy(tp->board_part_number, "BCM57790");
+               else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57788)
+                       strcpy(tp->board_part_number, "BCM57788");
+               else
+                       goto nomatch;
+       } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) {
+               if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57761)
+                       strcpy(tp->board_part_number, "BCM57761");
+               else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57765)
+                       strcpy(tp->board_part_number, "BCM57765");
+               else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57781)
+                       strcpy(tp->board_part_number, "BCM57781");
+               else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57785)
+                       strcpy(tp->board_part_number, "BCM57785");
+               else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57791)
+                       strcpy(tp->board_part_number, "BCM57791");
+               else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57795)
+                       strcpy(tp->board_part_number, "BCM57795");
+               else
+                       goto nomatch;
+       } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
                strcpy(tp->board_part_number, "BCM95906");
-       else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 &&
-                tp->pdev->device == TG3PCI_DEVICE_TIGON3_57780)
-               strcpy(tp->board_part_number, "BCM57780");
-       else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 &&
-                tp->pdev->device == TG3PCI_DEVICE_TIGON3_57760)
-               strcpy(tp->board_part_number, "BCM57760");
-       else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 &&
-                tp->pdev->device == TG3PCI_DEVICE_TIGON3_57790)
-               strcpy(tp->board_part_number, "BCM57790");
-       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 &&
-                tp->pdev->device == TG3PCI_DEVICE_TIGON3_57761)
-               strcpy(tp->board_part_number, "BCM57761");
-       else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 &&
-                tp->pdev->device == TG3PCI_DEVICE_TIGON3_57765)
-               strcpy(tp->board_part_number, "BCM57765");
-       else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 &&
-                tp->pdev->device == TG3PCI_DEVICE_TIGON3_57781)
-               strcpy(tp->board_part_number, "BCM57781");
-       else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 &&
-                tp->pdev->device == TG3PCI_DEVICE_TIGON3_57785)
-               strcpy(tp->board_part_number, "BCM57785");
-       else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 &&
-                tp->pdev->device == TG3PCI_DEVICE_TIGON3_57791)
-               strcpy(tp->board_part_number, "BCM57791");
-       else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 &&
-                tp->pdev->device == TG3PCI_DEVICE_TIGON3_57795)
-               strcpy(tp->board_part_number, "BCM57795");
-       else
+       } else {
+nomatch:
                strcpy(tp->board_part_number, "none");
+       }
 }
 
 static int __devinit tg3_fw_img_is_valid(struct tg3 *tp, u32 offset)
@@ -12627,6 +12942,9 @@ static void __devinit tg3_read_sb_ver(struct tg3 *tp, u32 val)
        case TG3_EEPROM_SB_REVISION_5:
                offset = TG3_EEPROM_SB_F1R5_EDH_OFF;
                break;
+       case TG3_EEPROM_SB_REVISION_6:
+               offset = TG3_EEPROM_SB_F1R6_EDH_OFF;
+               break;
        default:
                return;
        }
@@ -12710,6 +13028,7 @@ static void __devinit tg3_read_dash_ver(struct tg3 *tp)
 {
        int vlen;
        u32 apedata;
+       char *fwtype;
 
        if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) ||
            !(tp->tg3_flags  & TG3_FLAG_ENABLE_ASF))
@@ -12725,9 +13044,17 @@ static void __devinit tg3_read_dash_ver(struct tg3 *tp)
 
        apedata = tg3_ape_read32(tp, TG3_APE_FW_VERSION);
 
+       if (tg3_ape_read32(tp, TG3_APE_FW_FEATURES) & TG3_APE_FW_FEATURE_NCSI) {
+               tp->tg3_flags3 |= TG3_FLG3_APE_HAS_NCSI;
+               fwtype = "NCSI";
+       } else {
+               fwtype = "DASH";
+       }
+
        vlen = strlen(tp->fw_ver);
 
-       snprintf(&tp->fw_ver[vlen], TG3_VER_SIZE - vlen, " DASH v%d.%d.%d.%d",
+       snprintf(&tp->fw_ver[vlen], TG3_VER_SIZE - vlen, " %s v%d.%d.%d.%d",
+                fwtype,
                 (apedata & APE_FW_VERSION_MAJMSK) >> APE_FW_VERSION_MAJSFT,
                 (apedata & APE_FW_VERSION_MINMSK) >> APE_FW_VERSION_MINSFT,
                 (apedata & APE_FW_VERSION_REVMSK) >> APE_FW_VERSION_REVSFT,
@@ -12773,22 +13100,30 @@ static struct pci_dev * __devinit tg3_find_peer(struct tg3 *);
 
 static void inline vlan_features_add(struct net_device *dev, unsigned long flags)
 {
-#if TG3_VLAN_TAG_USED
        dev->vlan_features |= flags;
-#endif
 }
 
+static inline u32 tg3_rx_ret_ring_size(struct tg3 *tp)
+{
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
+               return 4096;
+       else if ((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) &&
+                !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
+               return 1024;
+       else
+               return 512;
+}
+
+static DEFINE_PCI_DEVICE_TABLE(tg3_write_reorder_chipsets) = {
+       { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C) },
+       { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE) },
+       { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8385_0) },
+       { },
+};
+
 static int __devinit tg3_get_invariants(struct tg3 *tp)
 {
-       static struct pci_device_id write_reorder_chipsets[] = {
-               { PCI_DEVICE(PCI_VENDOR_ID_AMD,
-                            PCI_DEVICE_ID_AMD_FE_GATE_700C) },
-               { PCI_DEVICE(PCI_VENDOR_ID_AMD,
-                            PCI_DEVICE_ID_AMD_8131_BRIDGE) },
-               { PCI_DEVICE(PCI_VENDOR_ID_VIA,
-                            PCI_DEVICE_ID_VIA_8385_0) },
-               { },
-       };
        u32 misc_ctrl_reg;
        u32 pci_state_reg, grc_misc_cfg;
        u32 val;
@@ -12822,7 +13157,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 
                if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717 ||
                    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 ||
-                   tp->pdev->device == TG3PCI_DEVICE_TIGON3_5724 ||
                    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719)
                        pci_read_config_dword(tp->pdev,
                                              TG3PCI_GEN2_PRODID_ASICREV,
@@ -13023,7 +13357,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        }
 
        /* Determine TSO capabilities */
-       if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
+               ; /* Do nothing. HW bug. */
+       else if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)
                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)
@@ -13074,7 +13410,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                tp->tg3_flags3 |= TG3_FLG3_40BIT_DMA_LIMIT_BUG;
        }
 
-       if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)
+       if ((tp->tg3_flags3 & TG3_FLG3_5717_PLUS) &&
+           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5719)
                tp->tg3_flags3 |= TG3_FLG3_USE_JUMBO_BDFLAG;
 
        if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
@@ -13091,7 +13428,11 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 
                tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS;
 
-               pcie_set_readrq(tp->pdev, 4096);
+               tp->pcie_readrq = 4096;
+               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
+                       tp->pcie_readrq = 2048;
+
+               pcie_set_readrq(tp->pdev, tp->pcie_readrq);
 
                pci_read_config_word(tp->pdev,
                                     tp->pcie_cap + PCI_EXP_LNKCTL,
@@ -13128,7 +13469,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
         * every mailbox register write to force the writes to be
         * posted to the chip in order.
         */
-       if (pci_dev_present(write_reorder_chipsets) &&
+       if (pci_dev_present(tg3_write_reorder_chipsets) &&
            !(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS))
                tp->tg3_flags |= TG3_FLAG_MBOX_WRITE_REORDER;
 
@@ -13278,7 +13619,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
            (tp->tg3_flags3 & TG3_FLG3_5717_PLUS))
                tp->tg3_flags |= TG3_FLAG_CPMU_PRESENT;
 
-       /* Set up tp->grc_local_ctrl before calling tg3_set_power_state().
+       /* Set up tp->grc_local_ctrl before calling tg_power_up().
         * GPIO1 driven high will bring 5700's external PHY out of reset.
         * It is also used as eeprom write protect on LOMs.
         */
@@ -13309,7 +13650,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        }
 
        /* Force the chip into D0. */
-       err = tg3_set_power_state(tp, PCI_D0);
+       err = tg3_power_up(tp);
        if (err) {
                dev_err(&tp->pdev->dev, "Transition to D0 failed\n");
                return err;
@@ -13333,25 +13674,25 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        }
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
-               tp->tg3_flags3 |= TG3_FLG3_PHY_IS_FET;
+               tp->phy_flags |= TG3_PHYFLG_IS_FET;
 
        /* A few boards don't want Ethernet@WireSpeed phy feature */
        if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) ||
            ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) &&
             (tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) &&
             (tp->pci_chip_rev_id != CHIPREV_ID_5705_A1)) ||
-           (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) ||
-           (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES))
-               tp->tg3_flags2 |= TG3_FLG2_NO_ETH_WIRE_SPEED;
+           (tp->phy_flags & TG3_PHYFLG_IS_FET) ||
+           (tp->phy_flags & TG3_PHYFLG_ANY_SERDES))
+               tp->phy_flags |= TG3_PHYFLG_NO_ETH_WIRE_SPEED;
 
        if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5703_AX ||
            GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5704_AX)
-               tp->tg3_flags2 |= TG3_FLG2_PHY_ADC_BUG;
+               tp->phy_flags |= TG3_PHYFLG_ADC_BUG;
        if (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0)
-               tp->tg3_flags2 |= TG3_FLG2_PHY_5704_A0_BUG;
+               tp->phy_flags |= TG3_PHYFLG_5704_A0_BUG;
 
        if ((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
-           !(tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) &&
+           !(tp->phy_flags & TG3_PHYFLG_IS_FET) &&
            GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785 &&
            GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57780 &&
            !(tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) {
@@ -13361,11 +13702,11 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) {
                        if (tp->pdev->device != PCI_DEVICE_ID_TIGON3_5756 &&
                            tp->pdev->device != PCI_DEVICE_ID_TIGON3_5722)
-                               tp->tg3_flags2 |= TG3_FLG2_PHY_JITTER_BUG;
+                               tp->phy_flags |= TG3_PHYFLG_JITTER_BUG;
                        if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5755M)
-                               tp->tg3_flags2 |= TG3_FLG2_PHY_ADJUST_TRIM;
+                               tp->phy_flags |= TG3_PHYFLG_ADJUST_TRIM;
                } else
-                       tp->tg3_flags2 |= TG3_FLG2_PHY_BER_BUG;
+                       tp->phy_flags |= TG3_PHYFLG_BER_BUG;
        }
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
@@ -13393,10 +13734,6 @@ static int __devinit tg3_get_invariants(struct tg3 *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)
-               return -ENOTSUPP;
-
        /* Initialize data/descriptor byte/word swapping. */
        val = tr32(GRC_MODE);
        val &= GRC_MODE_HOST_STACKUP;
@@ -13458,8 +13795,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 
        /* Preserve the APE MAC_MODE bits */
        if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
-               tp->mac_mode = tr32(MAC_MODE) |
-                              MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN;
+               tp->mac_mode = MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN;
        else
                tp->mac_mode = TG3_DEF_MAC_MODE;
 
@@ -13478,8 +13814,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
            tp->pdev->device == TG3PCI_DEVICE_TIGON3_57790 ||
            tp->pdev->device == TG3PCI_DEVICE_TIGON3_57791 ||
            tp->pdev->device == TG3PCI_DEVICE_TIGON3_57795 ||
-           (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET))
-               tp->tg3_flags |= TG3_FLAG_10_100_ONLY;
+           (tp->phy_flags & TG3_PHYFLG_IS_FET))
+               tp->phy_flags |= TG3_PHYFLG_10_100_ONLY;
 
        err = tg3_phy_probe(tp);
        if (err) {
@@ -13491,13 +13827,13 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        tg3_read_vpd(tp);
        tg3_read_fw_ver(tp);
 
-       if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) {
-               tp->tg3_flags &= ~TG3_FLAG_USE_MI_INTERRUPT;
+       if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) {
+               tp->phy_flags &= ~TG3_PHYFLG_USE_MI_INTERRUPT;
        } else {
                if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700)
-                       tp->tg3_flags |= TG3_FLAG_USE_MI_INTERRUPT;
+                       tp->phy_flags |= TG3_PHYFLG_USE_MI_INTERRUPT;
                else
-                       tp->tg3_flags &= ~TG3_FLAG_USE_MI_INTERRUPT;
+                       tp->phy_flags &= ~TG3_PHYFLG_USE_MI_INTERRUPT;
        }
 
        /* 5700 {AX,BX} chips have a broken status block link
@@ -13515,28 +13851,32 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
         */
        if (tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL &&
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 &&
-           !(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) {
-               tp->tg3_flags |= (TG3_FLAG_USE_MI_INTERRUPT |
-                                 TG3_FLAG_USE_LINKCHG_REG);
+           !(tp->phy_flags & TG3_PHYFLG_PHY_SERDES)) {
+               tp->phy_flags |= TG3_PHYFLG_USE_MI_INTERRUPT;
+               tp->tg3_flags |= TG3_FLAG_USE_LINKCHG_REG;
        }
 
        /* For all SERDES we poll the MAC status register. */
-       if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)
+       if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES)
                tp->tg3_flags |= TG3_FLAG_POLL_SERDES;
        else
                tp->tg3_flags &= ~TG3_FLAG_POLL_SERDES;
 
-       tp->rx_offset = NET_IP_ALIGN + TG3_RX_HEADROOM;
+       tp->rx_offset = NET_IP_ALIGN;
        tp->rx_copy_thresh = TG3_RX_COPY_THRESHOLD;
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 &&
            (tp->tg3_flags & TG3_FLAG_PCIX_MODE) != 0) {
-               tp->rx_offset -= NET_IP_ALIGN;
+               tp->rx_offset = 0;
 #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
                tp->rx_copy_thresh = ~(u16)0;
 #endif
        }
 
-       tp->rx_std_max_post = TG3_RX_RING_SIZE;
+       tp->rx_std_ring_mask = TG3_RX_STD_RING_SIZE(tp) - 1;
+       tp->rx_jmb_ring_mask = TG3_RX_JMB_RING_SIZE(tp) - 1;
+       tp->rx_ret_ring_mask = tg3_rx_ret_ring_size(tp) - 1;
+
+       tp->rx_std_max_post = tp->rx_std_ring_mask + 1;
 
        /* Increment the rx prod index on the rx std ring by at most
         * 8 for these chips to workaround hw errata.
@@ -13885,13 +14225,19 @@ static int __devinit tg3_do_test_dma(struct tg3 *tp, u32 *buf, dma_addr_t buf_dm
 
 #define TEST_BUFFER_SIZE       0x2000
 
+static DEFINE_PCI_DEVICE_TABLE(tg3_dma_wait_state_chipsets) = {
+       { PCI_DEVICE(PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_PCI15) },
+       { },
+};
+
 static int __devinit tg3_test_dma(struct tg3 *tp)
 {
        dma_addr_t buf_dma;
        u32 *buf, saved_dma_rwctrl;
        int ret = 0;
 
-       buf = pci_alloc_consistent(tp->pdev, TEST_BUFFER_SIZE, &buf_dma);
+       buf = dma_alloc_coherent(&tp->pdev->dev, TEST_BUFFER_SIZE,
+                                &buf_dma, GFP_KERNEL);
        if (!buf) {
                ret = -ENOMEM;
                goto out_nofree;
@@ -14053,17 +14399,12 @@ static int __devinit tg3_test_dma(struct tg3 *tp)
        }
        if ((tp->dma_rwctrl & DMA_RWCTRL_WRITE_BNDRY_MASK) !=
            DMA_RWCTRL_WRITE_BNDRY_16) {
-               static struct pci_device_id dma_wait_state_chipsets[] = {
-                       { PCI_DEVICE(PCI_VENDOR_ID_APPLE,
-                                    PCI_DEVICE_ID_APPLE_UNI_N_PCI15) },
-                       { },
-               };
 
                /* DMA test passed without adjusting DMA boundary,
                 * now look for chipsets that are known to expose the
                 * DMA bug without failing the test.
                 */
-               if (pci_dev_present(dma_wait_state_chipsets)) {
+               if (pci_dev_present(tg3_dma_wait_state_chipsets)) {
                        tp->dma_rwctrl &= ~DMA_RWCTRL_WRITE_BNDRY_MASK;
                        tp->dma_rwctrl |= DMA_RWCTRL_WRITE_BNDRY_16;
                } else {
@@ -14075,7 +14416,7 @@ static int __devinit tg3_test_dma(struct tg3 *tp)
        }
 
 out:
-       pci_free_consistent(tp->pdev, TEST_BUFFER_SIZE, buf, buf_dma);
+       dma_free_coherent(&tp->pdev->dev, TEST_BUFFER_SIZE, buf, buf_dma);
 out_nofree:
        return ret;
 }
@@ -14092,7 +14433,6 @@ static void __devinit tg3_init_link_config(struct tg3 *tp)
        tp->link_config.autoneg = AUTONEG_ENABLE;
        tp->link_config.active_speed = SPEED_INVALID;
        tp->link_config.active_duplex = DUPLEX_INVALID;
-       tp->link_config.phy_is_low_power = 0;
        tp->link_config.orig_speed = SPEED_INVALID;
        tp->link_config.orig_duplex = DUPLEX_INVALID;
        tp->link_config.orig_autoneg = AUTONEG_INVALID;
@@ -14290,9 +14630,6 @@ static const struct net_device_ops tg3_netdev_ops = {
        .ndo_do_ioctl           = tg3_ioctl,
        .ndo_tx_timeout         = tg3_tx_timeout,
        .ndo_change_mtu         = tg3_change_mtu,
-#if TG3_VLAN_TAG_USED
-       .ndo_vlan_rx_register   = tg3_vlan_rx_register,
-#endif
 #ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller    = tg3_poll_controller,
 #endif
@@ -14309,9 +14646,6 @@ static const struct net_device_ops tg3_netdev_ops_dma_bug = {
        .ndo_do_ioctl           = tg3_ioctl,
        .ndo_tx_timeout         = tg3_tx_timeout,
        .ndo_change_mtu         = tg3_change_mtu,
-#if TG3_VLAN_TAG_USED
-       .ndo_vlan_rx_register   = tg3_vlan_rx_register,
-#endif
 #ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller    = tg3_poll_controller,
 #endif
@@ -14361,9 +14695,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
 
        SET_NETDEV_DEV(dev, &pdev->dev);
 
-#if TG3_VLAN_TAG_USED
        dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-#endif
 
        tp = netdev_priv(dev);
        tp->pdev = pdev;
@@ -14426,7 +14758,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
        }
 
        if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) &&
-           tp->pci_chip_rev_id != CHIPREV_ID_5717_A0 &&
+           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 &&
            GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5719)
                dev->netdev_ops = &tg3_netdev_ops;
        else
@@ -14565,7 +14897,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
        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++) {
+       for (i = 0; i < tp->irq_max; i++) {
                struct tg3_napi *tnapi = &tp->napi[i];
 
                tnapi->tp = tp;
@@ -14580,13 +14912,10 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
                tnapi->consmbox = rcvmbx;
                tnapi->prodmbox = sndmbx;
 
-               if (i) {
+               if (i)
                        tnapi->coal_now = HOSTCC_MODE_COAL_VEC1_NOW << (i - 1);
-                       netif_napi_add(dev, &tnapi->napi, tg3_poll_msix, 64);
-               } else {
+               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;
@@ -14625,24 +14954,31 @@ 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->phy_flags & TG3_PHYFLG_IS_CONNECTED) {
                struct phy_device *phydev;
                phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
                netdev_info(dev,
                            "attached PHY driver [%s] (mii_bus:phy_addr=%s)\n",
                            phydev->drv->name, dev_name(&phydev->dev));
-       } else
+       } else {
+               char *ethtype;
+
+               if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY)
+                       ethtype = "10/100Base-TX";
+               else if (tp->phy_flags & TG3_PHYFLG_ANY_SERDES)
+                       ethtype = "1000Base-SX";
+               else
+                       ethtype = "10/100/1000Base-T";
+
                netdev_info(dev, "attached PHY is %s (%s Ethernet) "
-                           "(WireSpeed[%d])\n", tg3_phy_string(tp),
-                           ((tp->tg3_flags & TG3_FLAG_10_100_ONLY) ? "10/100Base-TX" :
-                            ((tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) ? "1000Base-SX" :
-                             "10/100/1000Base-T")),
-                           (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) == 0);
+                           "(WireSpeed[%d])\n", tg3_phy_string(tp), ethtype,
+                         (tp->phy_flags & TG3_PHYFLG_NO_ETH_WIRE_SPEED) == 0);
+       }
 
        netdev_info(dev, "RXcsums[%d] LinkChgREG[%d] MIirq[%d] ASF[%d] TSOcap[%d]\n",
                    (tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) != 0,
                    (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) != 0,
-                   (tp->tg3_flags & TG3_FLAG_USE_MI_INTERRUPT) != 0,
+                   (tp->phy_flags & TG3_PHYFLG_USE_MI_INTERRUPT) != 0,
                    (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0,
                    (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) != 0);
        netdev_info(dev, "dma_rwctrl[%08x] dma_mask[%d-bit]\n",
@@ -14686,7 +15022,7 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev)
                if (tp->fw)
                        release_firmware(tp->fw);
 
-               flush_scheduled_work();
+               cancel_work_sync(&tp->reset_task);
 
                if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
                        tg3_phy_fini(tp);
@@ -14709,23 +15045,18 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev)
        }
 }
 
-static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int tg3_suspend(struct device *device)
 {
+       struct pci_dev *pdev = to_pci_dev(device);
        struct net_device *dev = pci_get_drvdata(pdev);
        struct tg3 *tp = netdev_priv(dev);
-       pci_power_t target_state;
        int err;
 
-       /* PCI register 4 needs to be saved whether netif_running() or not.
-        * MSI address and data need to be saved if using MSI and
-        * netif_running().
-        */
-       pci_save_state(pdev);
-
        if (!netif_running(dev))
                return 0;
 
-       flush_scheduled_work();
+       flush_work_sync(&tp->reset_task);
        tg3_phy_stop(tp);
        tg3_netif_stop(tp);
 
@@ -14742,9 +15073,7 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
        tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
        tg3_full_unlock(tp);
 
-       target_state = pdev->pm_cap ? pci_target_state(pdev) : PCI_D3hot;
-
-       err = tg3_set_power_state(tp, target_state);
+       err = tg3_power_down_prepare(tp);
        if (err) {
                int err2;
 
@@ -14771,21 +15100,16 @@ out:
        return err;
 }
 
-static int tg3_resume(struct pci_dev *pdev)
+static int tg3_resume(struct device *device)
 {
+       struct pci_dev *pdev = to_pci_dev(device);
        struct net_device *dev = pci_get_drvdata(pdev);
        struct tg3 *tp = netdev_priv(dev);
        int err;
 
-       pci_restore_state(tp->pdev);
-
        if (!netif_running(dev))
                return 0;
 
-       err = tg3_set_power_state(tp, PCI_D0);
-       if (err)
-               return err;
-
        netif_device_attach(dev);
 
        tg3_full_lock(tp, 0);
@@ -14809,13 +15133,21 @@ out:
        return err;
 }
 
+static SIMPLE_DEV_PM_OPS(tg3_pm_ops, tg3_suspend, tg3_resume);
+#define TG3_PM_OPS (&tg3_pm_ops)
+
+#else
+
+#define TG3_PM_OPS NULL
+
+#endif /* CONFIG_PM_SLEEP */
+
 static struct pci_driver tg3_driver = {
        .name           = DRV_MODULE_NAME,
        .id_table       = tg3_pci_tbl,
        .probe          = tg3_init_one,
        .remove         = __devexit_p(tg3_remove_one),
-       .suspend        = tg3_suspend,
-       .resume         = tg3_resume
+       .driver.pm      = TG3_PM_OPS,
 };
 
 static int __init tg3_init(void)