nfsd4: fix null dereference creating nfsv4 callback client
[safe/jmp/linux-2.6] / drivers / net / tg3.c
index eb9f8f3..46a3f86 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-2007 Broadcom Corporation.
+ * Copyright (C) 2005-2009 Broadcom Corporation.
  *
  * Firmware is:
  *     Derived from proprietary unpublished source code,
@@ -40,6 +40,7 @@
 #include <linux/workqueue.h>
 #include <linux/prefetch.h>
 #include <linux/dma-mapping.h>
+#include <linux/firmware.h>
 
 #include <net/checksum.h>
 #include <net/ip.h>
 #include <asm/prom.h>
 #endif
 
+#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
 
-#define TG3_TSO_SUPPORT        1
-
 #include "tg3.h"
 
 #define DRV_MODULE_NAME                "tg3"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "3.94"
-#define DRV_MODULE_RELDATE     "August 14, 2008"
+#define DRV_MODULE_VERSION     "3.99"
+#define DRV_MODULE_RELDATE     "April 20, 2009"
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
 /* minimum number of free TX descriptors required to wake up TX process */
 #define TG3_TX_WAKEUP_THRESH(tp)               ((tp)->tx_pending / 4)
 
+#define TG3_RAW_IP_ALIGN 2
+
 /* number of ETHTOOL_GSTATS u64's */
 #define TG3_NUM_STATS          (sizeof(struct tg3_ethtool_stats)/sizeof(u64))
 
 #define TG3_NUM_TEST           6
 
+#define FIRMWARE_TG3           "tigon/tg3.bin"
+#define FIRMWARE_TG3TSO                "tigon/tg3_tso.bin"
+#define FIRMWARE_TG3TSO5       "tigon/tg3_tso5.bin"
+
 static char version[] __devinitdata =
        DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
 
@@ -141,6 +149,10 @@ MODULE_AUTHOR("David S. Miller (davem@redhat.com) and Jeff Garzik (jgarzik@pobox
 MODULE_DESCRIPTION("Broadcom Tigon3 ethernet driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_MODULE_VERSION);
+MODULE_FIRMWARE(FIRMWARE_TG3);
+MODULE_FIRMWARE(FIRMWARE_TG3TSO);
+MODULE_FIRMWARE(FIRMWARE_TG3TSO5);
+
 
 static int tg3_debug = -1;     /* -1 == use TG3_DEF_MSG_ENABLE as value */
 module_param(tg3_debug, int, 0);
@@ -205,7 +217,13 @@ static struct pci_device_id tg3_pci_tbl[] = {
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5723)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5761)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5761E)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5761S)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5761SE)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5785)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57780)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57760)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57790)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57720)},
        {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)},
        {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX)},
        {PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000)},
@@ -834,7 +852,7 @@ static int tg3_bmcr_reset(struct tg3 *tp)
                }
                udelay(10);
        }
-       if (limit <= 0)
+       if (limit < 0)
                return -EBUSY;
 
        return 0;
@@ -842,7 +860,7 @@ static int tg3_bmcr_reset(struct tg3 *tp)
 
 static int tg3_mdio_read(struct mii_bus *bp, int mii_id, int reg)
 {
-       struct tg3 *tp = (struct tg3 *)bp->priv;
+       struct tg3 *tp = bp->priv;
        u32 val;
 
        if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED)
@@ -856,7 +874,7 @@ static int tg3_mdio_read(struct mii_bus *bp, int mii_id, int reg)
 
 static int tg3_mdio_write(struct mii_bus *bp, int mii_id, int reg, u16 val)
 {
-       struct tg3 *tp = (struct tg3 *)bp->priv;
+       struct tg3 *tp = bp->priv;
 
        if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED)
                return -EAGAIN;
@@ -872,13 +890,48 @@ static int tg3_mdio_reset(struct mii_bus *bp)
        return 0;
 }
 
-static void tg3_mdio_config(struct tg3 *tp)
+static void tg3_mdio_config_5785(struct tg3 *tp)
 {
        u32 val;
+       struct phy_device *phydev;
+
+       phydev = tp->mdio_bus->phy_map[PHY_ADDR];
+       switch (phydev->drv->phy_id & phydev->drv->phy_id_mask) {
+       case TG3_PHY_ID_BCM50610:
+               val = MAC_PHYCFG2_50610_LED_MODES;
+               break;
+       case TG3_PHY_ID_BCMAC131:
+               val = MAC_PHYCFG2_AC131_LED_MODES;
+               break;
+       case TG3_PHY_ID_RTL8211C:
+               val = MAC_PHYCFG2_RTL8211C_LED_MODES;
+               break;
+       case TG3_PHY_ID_RTL8201E:
+               val = MAC_PHYCFG2_RTL8201E_LED_MODES;
+               break;
+       default:
+               return;
+       }
+
+       if (phydev->interface != PHY_INTERFACE_MODE_RGMII) {
+               tw32(MAC_PHYCFG2, val);
+
+               val = tr32(MAC_PHYCFG1);
+               val &= ~MAC_PHYCFG1_RGMII_INT;
+               tw32(MAC_PHYCFG1, val);
 
-       if (tp->mdio_bus->phy_map[PHY_ADDR]->interface !=
-           PHY_INTERFACE_MODE_RGMII)
                return;
+       }
+
+       if (!(tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE))
+               val |= MAC_PHYCFG2_EMODE_MASK_MASK |
+                      MAC_PHYCFG2_FMODE_MASK_MASK |
+                      MAC_PHYCFG2_GMODE_MASK_MASK |
+                      MAC_PHYCFG2_ACT_MASK_MASK   |
+                      MAC_PHYCFG2_QUAL_MASK_MASK |
+                      MAC_PHYCFG2_INBAND_ENABLE;
+
+       tw32(MAC_PHYCFG2, val);
 
        val = tr32(MAC_PHYCFG1) & ~(MAC_PHYCFG1_RGMII_EXT_RX_DEC |
                                    MAC_PHYCFG1_RGMII_SND_STAT_EN);
@@ -890,11 +943,6 @@ static void tg3_mdio_config(struct tg3 *tp)
        }
        tw32(MAC_PHYCFG1, val | MAC_PHYCFG1_RGMII_INT | MAC_PHYCFG1_TXC_DRV);
 
-       val = tr32(MAC_PHYCFG2) & ~(MAC_PHYCFG2_INBAND_ENABLE);
-       if (!(tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE))
-               val |= MAC_PHYCFG2_INBAND_ENABLE;
-       tw32(MAC_PHYCFG2, val);
-
        val = tr32(MAC_EXT_RGMII_MODE);
        val &= ~(MAC_RGMII_MODE_RX_INT_B |
                 MAC_RGMII_MODE_RX_QUALITY |
@@ -903,7 +951,7 @@ static void tg3_mdio_config(struct tg3 *tp)
                 MAC_RGMII_MODE_TX_ENABLE |
                 MAC_RGMII_MODE_TX_LOWPWR |
                 MAC_RGMII_MODE_TX_RESET);
-       if (tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE) {
+       if (!(tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE)) {
                if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_RX_EN)
                        val |= MAC_RGMII_MODE_RX_INT_B |
                               MAC_RGMII_MODE_RX_QUALITY |
@@ -929,8 +977,9 @@ static void tg3_mdio_start(struct tg3 *tp)
        tw32_f(MAC_MI_MODE, tp->mi_mode);
        udelay(80);
 
-       if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED)
-               tg3_mdio_config(tp);
+       if ((tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) &&
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
+               tg3_mdio_config_5785(tp);
 }
 
 static void tg3_mdio_stop(struct tg3 *tp)
@@ -984,29 +1033,44 @@ static int tg3_mdio_init(struct tg3 *tp)
        if (i) {
                printk(KERN_WARNING "%s: mdiobus_reg failed (0x%x)\n",
                        tp->dev->name, i);
+               mdiobus_free(tp->mdio_bus);
                return i;
        }
 
-       tp->tg3_flags3 |= TG3_FLG3_MDIOBUS_INITED;
-
        phydev = tp->mdio_bus->phy_map[PHY_ADDR];
 
-       switch (phydev->phy_id) {
+       if (!phydev || !phydev->drv) {
+               printk(KERN_WARNING "%s: No PHY devices\n", tp->dev->name);
+               mdiobus_unregister(tp->mdio_bus);
+               mdiobus_free(tp->mdio_bus);
+               return -ENODEV;
+       }
+
+       switch (phydev->drv->phy_id & phydev->drv->phy_id_mask) {
+       case TG3_PHY_ID_BCM57780:
+               phydev->interface = PHY_INTERFACE_MODE_GMII;
+               break;
        case TG3_PHY_ID_BCM50610:
-               phydev->interface = PHY_INTERFACE_MODE_RGMII;
                if (tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE)
                        phydev->dev_flags |= PHY_BRCM_STD_IBND_DISABLE;
                if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_RX_EN)
                        phydev->dev_flags |= PHY_BRCM_EXT_IBND_RX_ENABLE;
                if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_TX_EN)
                        phydev->dev_flags |= PHY_BRCM_EXT_IBND_TX_ENABLE;
+               /* fallthru */
+       case TG3_PHY_ID_RTL8211C:
+               phydev->interface = PHY_INTERFACE_MODE_RGMII;
                break;
+       case TG3_PHY_ID_RTL8201E:
        case TG3_PHY_ID_BCMAC131:
                phydev->interface = PHY_INTERFACE_MODE_MII;
                break;
        }
 
-       tg3_mdio_config(tp);
+       tp->tg3_flags3 |= TG3_FLG3_MDIOBUS_INITED;
+
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
+               tg3_mdio_config_5785(tp);
 
        return 0;
 }
@@ -1130,9 +1194,9 @@ static void tg3_link_report(struct tg3 *tp)
                printk(KERN_INFO PFX
                       "%s: Flow control is %s for TX and %s for RX.\n",
                       tp->dev->name,
-                      (tp->link_config.active_flowctrl & TG3_FLOW_CTRL_TX) ?
+                      (tp->link_config.active_flowctrl & FLOW_CTRL_TX) ?
                       "on" : "off",
-                      (tp->link_config.active_flowctrl & TG3_FLOW_CTRL_RX) ?
+                      (tp->link_config.active_flowctrl & FLOW_CTRL_RX) ?
                       "on" : "off");
                tg3_ump_link_report(tp);
        }
@@ -1142,11 +1206,11 @@ static u16 tg3_advert_flowctrl_1000T(u8 flow_ctrl)
 {
        u16 miireg;
 
-       if ((flow_ctrl & TG3_FLOW_CTRL_TX) && (flow_ctrl & TG3_FLOW_CTRL_RX))
+       if ((flow_ctrl & FLOW_CTRL_TX) && (flow_ctrl & FLOW_CTRL_RX))
                miireg = ADVERTISE_PAUSE_CAP;
-       else if (flow_ctrl & TG3_FLOW_CTRL_TX)
+       else if (flow_ctrl & FLOW_CTRL_TX)
                miireg = ADVERTISE_PAUSE_ASYM;
-       else if (flow_ctrl & TG3_FLOW_CTRL_RX)
+       else if (flow_ctrl & FLOW_CTRL_RX)
                miireg = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
        else
                miireg = 0;
@@ -1158,11 +1222,11 @@ static u16 tg3_advert_flowctrl_1000X(u8 flow_ctrl)
 {
        u16 miireg;
 
-       if ((flow_ctrl & TG3_FLOW_CTRL_TX) && (flow_ctrl & TG3_FLOW_CTRL_RX))
+       if ((flow_ctrl & FLOW_CTRL_TX) && (flow_ctrl & FLOW_CTRL_RX))
                miireg = ADVERTISE_1000XPAUSE;
-       else if (flow_ctrl & TG3_FLOW_CTRL_TX)
+       else if (flow_ctrl & FLOW_CTRL_TX)
                miireg = ADVERTISE_1000XPSE_ASYM;
-       else if (flow_ctrl & TG3_FLOW_CTRL_RX)
+       else if (flow_ctrl & FLOW_CTRL_RX)
                miireg = ADVERTISE_1000XPAUSE | ADVERTISE_1000XPSE_ASYM;
        else
                miireg = 0;
@@ -1170,28 +1234,6 @@ static u16 tg3_advert_flowctrl_1000X(u8 flow_ctrl)
        return miireg;
 }
 
-static u8 tg3_resolve_flowctrl_1000T(u16 lcladv, u16 rmtadv)
-{
-       u8 cap = 0;
-
-       if (lcladv & ADVERTISE_PAUSE_CAP) {
-               if (lcladv & ADVERTISE_PAUSE_ASYM) {
-                       if (rmtadv & LPA_PAUSE_CAP)
-                               cap = TG3_FLOW_CTRL_TX | TG3_FLOW_CTRL_RX;
-                       else if (rmtadv & LPA_PAUSE_ASYM)
-                               cap = TG3_FLOW_CTRL_RX;
-               } else {
-                       if (rmtadv & LPA_PAUSE_CAP)
-                               cap = TG3_FLOW_CTRL_TX | TG3_FLOW_CTRL_RX;
-               }
-       } else if (lcladv & ADVERTISE_PAUSE_ASYM) {
-               if ((rmtadv & LPA_PAUSE_CAP) && (rmtadv & LPA_PAUSE_ASYM))
-                       cap = TG3_FLOW_CTRL_TX;
-       }
-
-       return cap;
-}
-
 static u8 tg3_resolve_flowctrl_1000X(u16 lcladv, u16 rmtadv)
 {
        u8 cap = 0;
@@ -1199,16 +1241,16 @@ static u8 tg3_resolve_flowctrl_1000X(u16 lcladv, u16 rmtadv)
        if (lcladv & ADVERTISE_1000XPAUSE) {
                if (lcladv & ADVERTISE_1000XPSE_ASYM) {
                        if (rmtadv & LPA_1000XPAUSE)
-                               cap = TG3_FLOW_CTRL_TX | TG3_FLOW_CTRL_RX;
+                               cap = FLOW_CTRL_TX | FLOW_CTRL_RX;
                        else if (rmtadv & LPA_1000XPAUSE_ASYM)
-                               cap = TG3_FLOW_CTRL_RX;
+                               cap = FLOW_CTRL_RX;
                } else {
                        if (rmtadv & LPA_1000XPAUSE)
-                               cap = TG3_FLOW_CTRL_TX | TG3_FLOW_CTRL_RX;
+                               cap = FLOW_CTRL_TX | FLOW_CTRL_RX;
                }
        } else if (lcladv & ADVERTISE_1000XPSE_ASYM) {
                if ((rmtadv & LPA_1000XPAUSE) && (rmtadv & LPA_1000XPAUSE_ASYM))
-                       cap = TG3_FLOW_CTRL_TX;
+                       cap = FLOW_CTRL_TX;
        }
 
        return cap;
@@ -1231,13 +1273,13 @@ static void tg3_setup_flow_control(struct tg3 *tp, u32 lcladv, u32 rmtadv)
                if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)
                        flowctrl = tg3_resolve_flowctrl_1000X(lcladv, rmtadv);
                else
-                       flowctrl = tg3_resolve_flowctrl_1000T(lcladv, rmtadv);
+                       flowctrl = mii_resolve_flowctrl_fdx(lcladv, rmtadv);
        } else
                flowctrl = tp->link_config.flowctrl;
 
        tp->link_config.active_flowctrl = flowctrl;
 
-       if (flowctrl & TG3_FLOW_CTRL_RX)
+       if (flowctrl & FLOW_CTRL_RX)
                tp->rx_mode |= RX_MODE_FLOW_CTRL_ENABLE;
        else
                tp->rx_mode &= ~RX_MODE_FLOW_CTRL_ENABLE;
@@ -1245,7 +1287,7 @@ static void tg3_setup_flow_control(struct tg3 *tp, u32 lcladv, u32 rmtadv)
        if (old_rx_mode != tp->rx_mode)
                tw32_f(MAC_RX_MODE, tp->rx_mode);
 
-       if (flowctrl & TG3_FLOW_CTRL_TX)
+       if (flowctrl & FLOW_CTRL_TX)
                tp->tx_mode |= TX_MODE_FLOW_CTRL_ENABLE;
        else
                tp->tx_mode &= ~TX_MODE_FLOW_CTRL_ENABLE;
@@ -1299,6 +1341,15 @@ static void tg3_adjust_link(struct net_device *dev)
                udelay(40);
        }
 
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785) {
+               if (phydev->speed == SPEED_10)
+                       tw32(MAC_MI_STAT,
+                            MAC_MI_STAT_10MBPS_MODE |
+                            MAC_MI_STAT_LNKSTAT_ATTN_ENAB);
+               else
+                       tw32(MAC_MI_STAT, MAC_MI_STAT_LNKSTAT_ATTN_ENAB);
+       }
+
        if (phydev->speed == SPEED_1000 && phydev->duplex == DUPLEX_HALF)
                tw32(MAC_TX_LENGTHS,
                     ((2 << TX_LENGTHS_IPG_CRS_SHIFT) |
@@ -1339,25 +1390,37 @@ static int tg3_phy_init(struct tg3 *tp)
        phydev = tp->mdio_bus->phy_map[PHY_ADDR];
 
        /* Attach the MAC to the PHY. */
-       phydev = phy_connect(tp->dev, phydev->dev.bus_id, tg3_adjust_link,
+       phydev = phy_connect(tp->dev, dev_name(&phydev->dev), tg3_adjust_link,
                             phydev->dev_flags, phydev->interface);
        if (IS_ERR(phydev)) {
                printk(KERN_ERR "%s: Could not attach to PHY\n", tp->dev->name);
                return PTR_ERR(phydev);
        }
 
-       tp->tg3_flags3 |= TG3_FLG3_PHY_CONNECTED;
-
        /* Mask with MAC supported features. */
-       phydev->supported &= (PHY_GBIT_FEATURES |
-                             SUPPORTED_Pause |
-                             SUPPORTED_Asym_Pause);
+       switch (phydev->interface) {
+       case PHY_INTERFACE_MODE_GMII:
+       case PHY_INTERFACE_MODE_RGMII:
+               if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) {
+                       phydev->supported &= (PHY_GBIT_FEATURES |
+                                             SUPPORTED_Pause |
+                                             SUPPORTED_Asym_Pause);
+                       break;
+               }
+               /* fallthru */
+       case PHY_INTERFACE_MODE_MII:
+               phydev->supported &= (PHY_BASIC_FEATURES |
+                                     SUPPORTED_Pause |
+                                     SUPPORTED_Asym_Pause);
+               break;
+       default:
+               phy_disconnect(tp->mdio_bus->phy_map[PHY_ADDR]);
+               return -EINVAL;
+       }
 
-       phydev->advertising = phydev->supported;
+       tp->tg3_flags3 |= TG3_FLG3_PHY_CONNECTED;
 
-       printk(KERN_INFO
-              "%s: attached PHY driver [%s] (mii_bus:phy_addr=%s)\n",
-              tp->dev->name, phydev->drv->name, phydev->dev.bus_id);
+       phydev->advertising = phydev->supported;
 
        return 0;
 }
@@ -1406,6 +1469,35 @@ static void tg3_phydsp_write(struct tg3 *tp, u32 reg, u32 val)
        tg3_writephy(tp, MII_TG3_DSP_RW_PORT, val);
 }
 
+static void tg3_phy_toggle_apd(struct tg3 *tp, bool enable)
+{
+       u32 reg;
+
+       if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+               return;
+
+       reg = MII_TG3_MISC_SHDW_WREN |
+             MII_TG3_MISC_SHDW_SCR5_SEL |
+             MII_TG3_MISC_SHDW_SCR5_LPED |
+             MII_TG3_MISC_SHDW_SCR5_DLPTLM |
+             MII_TG3_MISC_SHDW_SCR5_SDTL |
+             MII_TG3_MISC_SHDW_SCR5_C125OE;
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5784 || !enable)
+               reg |= MII_TG3_MISC_SHDW_SCR5_DLLAPD;
+
+       tg3_writephy(tp, MII_TG3_MISC_SHDW, reg);
+
+
+       reg = MII_TG3_MISC_SHDW_WREN |
+             MII_TG3_MISC_SHDW_APD_SEL |
+             MII_TG3_MISC_SHDW_APD_WKTM_84MS;
+       if (enable)
+               reg |= MII_TG3_MISC_SHDW_APD_ENABLE;
+
+       tg3_writephy(tp, MII_TG3_MISC_SHDW, reg);
+}
+
 static void tg3_phy_toggle_automdix(struct tg3 *tp, int enable)
 {
        u32 phy;
@@ -1512,7 +1604,7 @@ static int tg3_wait_macro_done(struct tg3 *tp)
                                break;
                }
        }
-       if (limit <= 0)
+       if (limit < 0)
                return -EBUSY;
 
        return 0;
@@ -1737,7 +1829,8 @@ static int tg3_phy_reset(struct tg3 *tp)
                tw32(TG3_CPMU_CTRL, cpmuctrl);
        }
 
-       if (tp->tg3_flags3 & TG3_FLG3_5761_5784_AX_FIXES) {
+       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);
@@ -1747,16 +1840,15 @@ static int tg3_phy_reset(struct tg3 *tp)
                        udelay(40);
                        tw32_f(TG3_CPMU_LSPD_1000MB_CLK, val);
                }
-
-               /* Disable GPHY autopowerdown. */
-               tg3_writephy(tp, MII_TG3_MISC_SHDW,
-                            MII_TG3_MISC_SHDW_WREN |
-                            MII_TG3_MISC_SHDW_APD_SEL |
-                            MII_TG3_MISC_SHDW_APD_WKTM_84MS);
        }
 
        tg3_phy_apply_otp(tp);
 
+       if (tp->tg3_flags3 & TG3_FLG3_PHY_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) {
                tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00);
@@ -1858,7 +1950,8 @@ static void tg3_frob_aux_power(struct tg3 *tp)
                                     GRC_LCLCTRL_GPIO_OUTPUT0 |
                                     GRC_LCLCTRL_GPIO_OUTPUT1),
                                    100);
-               } else if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761) {
+               } else if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761 ||
+                          tp->pdev->device == TG3PCI_DEVICE_TIGON3_5761S) {
                        /* The 5761 non-e device swaps GPIO 0 and GPIO 2. */
                        u32 grc_local_ctrl = GRC_LCLCTRL_GPIO_OE0 |
                                             GRC_LCLCTRL_GPIO_OE1 |
@@ -1958,10 +2051,8 @@ static int tg3_setup_phy(struct tg3 *, int);
 
 static void tg3_write_sig_post_reset(struct tg3 *, int);
 static int tg3_halt_cpu(struct tg3 *, u32);
-static int tg3_nvram_lock(struct tg3 *);
-static void tg3_nvram_unlock(struct tg3 *);
 
-static void tg3_power_down_phy(struct tg3 *tp)
+static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power)
 {
        u32 val;
 
@@ -1984,10 +2075,15 @@ static void tg3_power_down_phy(struct tg3 *tp)
                tw32_f(GRC_MISC_CFG, val | GRC_MISC_CFG_EPHY_IDDQ);
                udelay(40);
                return;
-       } else if (!(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)) {
+       } else if (do_low_power) {
                tg3_writephy(tp, MII_TG3_EXT_CTRL,
                             MII_TG3_EXT_CTRL_FORCE_LED_OFF);
-               tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2);
+
+               tg3_writephy(tp, MII_TG3_AUX_CTRL,
+                            MII_TG3_AUXCTL_SHDWSEL_PWRCTL |
+                            MII_TG3_AUXCTL_PCTL_100TX_LPWR |
+                            MII_TG3_AUXCTL_PCTL_SPR_ISOLATE |
+                            MII_TG3_AUXCTL_PCTL_VREG_11V);
        }
 
        /* The PHY should not be powered down on some chips because
@@ -1999,7 +2095,8 @@ static void tg3_power_down_phy(struct tg3 *tp)
             (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)))
                return;
 
-       if (tp->tg3_flags3 & TG3_FLG3_5761_5784_AX_FIXES) {
+       if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5784_AX ||
+           GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5761_AX) {
                val = tr32(TG3_CPMU_LSPD_1000MB_CLK);
                val &= ~CPMU_LSPD_1000MB_MACCLK_MASK;
                val |= CPMU_LSPD_1000MB_MACCLK_12_5;
@@ -2009,9 +2106,242 @@ static void tg3_power_down_phy(struct tg3 *tp)
        tg3_writephy(tp, MII_BMCR, BMCR_PDOWN);
 }
 
+/* tp->lock is held. */
+static int tg3_nvram_lock(struct tg3 *tp)
+{
+       if (tp->tg3_flags & TG3_FLAG_NVRAM) {
+               int i;
+
+               if (tp->nvram_lock_cnt == 0) {
+                       tw32(NVRAM_SWARB, SWARB_REQ_SET1);
+                       for (i = 0; i < 8000; i++) {
+                               if (tr32(NVRAM_SWARB) & SWARB_GNT1)
+                                       break;
+                               udelay(20);
+                       }
+                       if (i == 8000) {
+                               tw32(NVRAM_SWARB, SWARB_REQ_CLR1);
+                               return -ENODEV;
+                       }
+               }
+               tp->nvram_lock_cnt++;
+       }
+       return 0;
+}
+
+/* tp->lock is held. */
+static void tg3_nvram_unlock(struct tg3 *tp)
+{
+       if (tp->tg3_flags & TG3_FLAG_NVRAM) {
+               if (tp->nvram_lock_cnt > 0)
+                       tp->nvram_lock_cnt--;
+               if (tp->nvram_lock_cnt == 0)
+                       tw32_f(NVRAM_SWARB, SWARB_REQ_CLR1);
+       }
+}
+
+/* tp->lock is held. */
+static void tg3_enable_nvram_access(struct tg3 *tp)
+{
+       if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
+           !(tp->tg3_flags2 & TG3_FLG2_PROTECTED_NVRAM)) {
+               u32 nvaccess = tr32(NVRAM_ACCESS);
+
+               tw32(NVRAM_ACCESS, nvaccess | ACCESS_ENABLE);
+       }
+}
+
+/* tp->lock is held. */
+static void tg3_disable_nvram_access(struct tg3 *tp)
+{
+       if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
+           !(tp->tg3_flags2 & TG3_FLG2_PROTECTED_NVRAM)) {
+               u32 nvaccess = tr32(NVRAM_ACCESS);
+
+               tw32(NVRAM_ACCESS, nvaccess & ~ACCESS_ENABLE);
+       }
+}
+
+static int tg3_nvram_read_using_eeprom(struct tg3 *tp,
+                                       u32 offset, u32 *val)
+{
+       u32 tmp;
+       int i;
+
+       if (offset > EEPROM_ADDR_ADDR_MASK || (offset % 4) != 0)
+               return -EINVAL;
+
+       tmp = tr32(GRC_EEPROM_ADDR) & ~(EEPROM_ADDR_ADDR_MASK |
+                                       EEPROM_ADDR_DEVID_MASK |
+                                       EEPROM_ADDR_READ);
+       tw32(GRC_EEPROM_ADDR,
+            tmp |
+            (0 << EEPROM_ADDR_DEVID_SHIFT) |
+            ((offset << EEPROM_ADDR_ADDR_SHIFT) &
+             EEPROM_ADDR_ADDR_MASK) |
+            EEPROM_ADDR_READ | EEPROM_ADDR_START);
+
+       for (i = 0; i < 1000; i++) {
+               tmp = tr32(GRC_EEPROM_ADDR);
+
+               if (tmp & EEPROM_ADDR_COMPLETE)
+                       break;
+               msleep(1);
+       }
+       if (!(tmp & EEPROM_ADDR_COMPLETE))
+               return -EBUSY;
+
+       tmp = tr32(GRC_EEPROM_DATA);
+
+       /*
+        * The data will always be opposite the native endian
+        * format.  Perform a blind byteswap to compensate.
+        */
+       *val = swab32(tmp);
+
+       return 0;
+}
+
+#define NVRAM_CMD_TIMEOUT 10000
+
+static int tg3_nvram_exec_cmd(struct tg3 *tp, u32 nvram_cmd)
+{
+       int i;
+
+       tw32(NVRAM_CMD, nvram_cmd);
+       for (i = 0; i < NVRAM_CMD_TIMEOUT; i++) {
+               udelay(10);
+               if (tr32(NVRAM_CMD) & NVRAM_CMD_DONE) {
+                       udelay(10);
+                       break;
+               }
+       }
+
+       if (i == NVRAM_CMD_TIMEOUT)
+               return -EBUSY;
+
+       return 0;
+}
+
+static u32 tg3_nvram_phys_addr(struct tg3 *tp, u32 addr)
+{
+       if ((tp->tg3_flags & TG3_FLAG_NVRAM) &&
+           (tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) &&
+           (tp->tg3_flags2 & TG3_FLG2_FLASH) &&
+          !(tp->tg3_flags3 & TG3_FLG3_NO_NVRAM_ADDR_TRANS) &&
+           (tp->nvram_jedecnum == JEDEC_ATMEL))
+
+               addr = ((addr / tp->nvram_pagesize) <<
+                       ATMEL_AT45DB0X1B_PAGE_POS) +
+                      (addr % tp->nvram_pagesize);
+
+       return addr;
+}
+
+static u32 tg3_nvram_logical_addr(struct tg3 *tp, u32 addr)
+{
+       if ((tp->tg3_flags & TG3_FLAG_NVRAM) &&
+           (tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) &&
+           (tp->tg3_flags2 & TG3_FLG2_FLASH) &&
+          !(tp->tg3_flags3 & TG3_FLG3_NO_NVRAM_ADDR_TRANS) &&
+           (tp->nvram_jedecnum == JEDEC_ATMEL))
+
+               addr = ((addr >> ATMEL_AT45DB0X1B_PAGE_POS) *
+                       tp->nvram_pagesize) +
+                      (addr & ((1 << ATMEL_AT45DB0X1B_PAGE_POS) - 1));
+
+       return addr;
+}
+
+/* NOTE: Data read in from NVRAM is byteswapped according to
+ * the byteswapping settings for all other register accesses.
+ * tg3 devices are BE devices, so on a BE machine, the data
+ * returned will be exactly as it is seen in NVRAM.  On a LE
+ * machine, the 32-bit value will be byteswapped.
+ */
+static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val)
+{
+       int ret;
+
+       if (!(tp->tg3_flags & TG3_FLAG_NVRAM))
+               return tg3_nvram_read_using_eeprom(tp, offset, val);
+
+       offset = tg3_nvram_phys_addr(tp, offset);
+
+       if (offset > NVRAM_ADDR_MSK)
+               return -EINVAL;
+
+       ret = tg3_nvram_lock(tp);
+       if (ret)
+               return ret;
+
+       tg3_enable_nvram_access(tp);
+
+       tw32(NVRAM_ADDR, offset);
+       ret = tg3_nvram_exec_cmd(tp, NVRAM_CMD_RD | NVRAM_CMD_GO |
+               NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_DONE);
+
+       if (ret == 0)
+               *val = tr32(NVRAM_RDDATA);
+
+       tg3_disable_nvram_access(tp);
+
+       tg3_nvram_unlock(tp);
+
+       return ret;
+}
+
+/* Ensures NVRAM data is in bytestream format. */
+static int tg3_nvram_read_be32(struct tg3 *tp, u32 offset, __be32 *val)
+{
+       u32 v;
+       int res = tg3_nvram_read(tp, offset, &v);
+       if (!res)
+               *val = cpu_to_be32(v);
+       return res;
+}
+
+/* tp->lock is held. */
+static void __tg3_set_mac_addr(struct tg3 *tp, int skip_mac_1)
+{
+       u32 addr_high, addr_low;
+       int i;
+
+       addr_high = ((tp->dev->dev_addr[0] << 8) |
+                    tp->dev->dev_addr[1]);
+       addr_low = ((tp->dev->dev_addr[2] << 24) |
+                   (tp->dev->dev_addr[3] << 16) |
+                   (tp->dev->dev_addr[4] <<  8) |
+                   (tp->dev->dev_addr[5] <<  0));
+       for (i = 0; i < 4; i++) {
+               if (i == 1 && skip_mac_1)
+                       continue;
+               tw32(MAC_ADDR_0_HIGH + (i * 8), addr_high);
+               tw32(MAC_ADDR_0_LOW + (i * 8), addr_low);
+       }
+
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
+               for (i = 0; i < 12; i++) {
+                       tw32(MAC_EXTADDR_0_HIGH + (i * 8), addr_high);
+                       tw32(MAC_EXTADDR_0_LOW + (i * 8), addr_low);
+               }
+       }
+
+       addr_high = (tp->dev->dev_addr[0] +
+                    tp->dev->dev_addr[1] +
+                    tp->dev->dev_addr[2] +
+                    tp->dev->dev_addr[3] +
+                    tp->dev->dev_addr[4] +
+                    tp->dev->dev_addr[5]) &
+               TX_BACKOFF_SEED_MASK;
+       tw32(MAC_TX_BACKOFF_SEED, addr_high);
+}
+
 static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
 {
        u32 misc_host_ctrl;
+       bool device_should_wake, do_low_power;
 
        /* Make sure register accesses (indirect or otherwise)
         * will function correctly.
@@ -2041,15 +2371,34 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
                        tp->dev->name, state);
                return -EINVAL;
        }
+
+       /* Restore the CLKREQ setting. */
+       if (tp->tg3_flags3 & TG3_FLG3_CLKREQ_BUG) {
+               u16 lnkctl;
+
+               pci_read_config_word(tp->pdev,
+                                    tp->pcie_cap + PCI_EXP_LNKCTL,
+                                    &lnkctl);
+               lnkctl |= PCI_EXP_LNKCTL_CLKREQ_EN;
+               pci_write_config_word(tp->pdev,
+                                     tp->pcie_cap + PCI_EXP_LNKCTL,
+                                     lnkctl);
+       }
+
        misc_host_ctrl = tr32(TG3PCI_MISC_HOST_CTRL);
        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) &&
+                            (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) {
                        struct phy_device *phydev;
-                       u32 advertising;
+                       u32 phyid, advertising;
 
                        phydev = tp->mdio_bus->phy_map[PHY_ADDR];
 
@@ -2066,7 +2415,7 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
                                      ADVERTISED_10baseT_Half;
 
                        if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
-                           (tp->tg3_flags & TG3_FLAG_WOL_ENABLE)) {
+                           device_should_wake) {
                                if (tp->tg3_flags & TG3_FLAG_WOL_SPEED_100MB)
                                        advertising |=
                                                ADVERTISED_100baseT_Half |
@@ -2079,8 +2428,19 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
                        phydev->advertising = advertising;
 
                        phy_start_aneg(phydev);
+
+                       phyid = phydev->drv->phy_id & phydev->drv->phy_id_mask;
+                       if (phyid != TG3_PHY_ID_BCMAC131) {
+                               phyid &= TG3_PHY_OUI_MASK;
+                               if (phyid == TG3_PHY_OUI_1 ||
+                                   phyid == TG3_PHY_OUI_2 ||
+                                   phyid == TG3_PHY_OUI_3)
+                                       do_low_power = true;
+                       }
                }
        } else {
+               do_low_power = true;
+
                if (tp->link_config.phy_is_low_power == 0) {
                        tp->link_config.phy_is_low_power = 1;
                        tp->link_config.orig_speed = tp->link_config.speed;
@@ -2118,11 +2478,11 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
                                                     WOL_DRV_WOL |
                                                     WOL_SET_MAGIC_PKT);
 
-       if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE) {
+       if (device_should_wake) {
                u32 mac_mode;
 
                if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) {
-                       if (!(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)) {
+                       if (do_low_power) {
                                tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x5a);
                                udelay(40);
                        }
@@ -2150,9 +2510,12 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
                if (!(tp->tg3_flags2 & TG3_FLG2_5750_PLUS))
                        tw32(MAC_LED_CTRL, tp->led_ctrl);
 
-               if (pci_pme_capable(tp->pdev, state) &&
-                    (tp->tg3_flags & TG3_FLAG_WOL_ENABLE))
-                       mac_mode |= MAC_MODE_MAGIC_PKT_ENABLE;
+               mac_mode |= MAC_MODE_MAGIC_PKT_ENABLE;
+               if (((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
+                   !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) &&
+                   ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
+                    (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 &
@@ -2224,10 +2587,9 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
                }
        }
 
-       if (!(tp->tg3_flags & TG3_FLAG_WOL_ENABLE) &&
-           !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) &&
-           !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE))
-               tg3_power_down_phy(tp);
+       if (!(device_should_wake) &&
+           !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF))
+               tg3_power_down_phy(tp, do_low_power);
 
        tg3_frob_aux_power(tp);
 
@@ -2250,7 +2612,7 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
 
        tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN);
 
-       if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE)
+       if (device_should_wake)
                pci_enable_wake(tp->pdev, state, true);
 
        /* Finally, set the new power state. */
@@ -2789,6 +3151,24 @@ relink:
                              NIC_SRAM_FIRMWARE_MBOX_MAGIC2);
        }
 
+       /* Prevent send BD corruption. */
+       if (tp->tg3_flags3 & TG3_FLG3_CLKREQ_BUG) {
+               u16 oldlnkctl, newlnkctl;
+
+               pci_read_config_word(tp->pdev,
+                                    tp->pcie_cap + PCI_EXP_LNKCTL,
+                                    &oldlnkctl);
+               if (tp->link_config.active_speed == SPEED_100 ||
+                   tp->link_config.active_speed == SPEED_10)
+                       newlnkctl = oldlnkctl & ~PCI_EXP_LNKCTL_CLKREQ_EN;
+               else
+                       newlnkctl = oldlnkctl | PCI_EXP_LNKCTL_CLKREQ_EN;
+               if (newlnkctl != oldlnkctl)
+                       pci_write_config_word(tp->pdev,
+                                             tp->pcie_cap + PCI_EXP_LNKCTL,
+                                             newlnkctl);
+       }
+
        if (current_link_up != netif_carrier_ok(tp->dev)) {
                if (current_link_up)
                        netif_carrier_on(tp->dev);
@@ -3765,8 +4145,7 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset)
                err = tg3_setup_copper_phy(tp, force_reset);
        }
 
-       if (tp->pci_chip_rev_id == CHIPREV_ID_5784_A0 ||
-           tp->pci_chip_rev_id == CHIPREV_ID_5784_A1) {
+       if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5784_AX) {
                u32 val, scale;
 
                val = tr32(TG3_CPMU_CLCK_STAT) & CPMU_CLCK_STAT_MAC_CLCK_MASK;
@@ -4019,7 +4398,7 @@ static void tg3_recycle_rx(struct tg3 *tp, u32 opaque_key,
 #if TG3_VLAN_TAG_USED
 static int tg3_vlan_rx(struct tg3 *tp, struct sk_buff *skb, u16 vlan_tag)
 {
-       return vlan_hwaccel_receive_skb(skb, tp->vlgrp, vlan_tag);
+       return vlan_gro_receive(&tp->napi, tp->vlgrp, vlan_tag, skb);
 }
 #endif
 
@@ -4100,12 +4479,15 @@ static int tg3_rx(struct tg3 *tp, int budget)
                        goto next_pkt;
                }
 
-               len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) - 4; /* omit crc */
+               len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) -
+                     ETH_FCS_LEN;
 
                if (len > RX_COPY_THRESHOLD
-                       && tp->rx_offset == 2
-                       /* rx_offset != 2 iff this is a 5701 card running
-                        * in PCI-X mode [see tg3_get_invariants()] */
+                       && tp->rx_offset == NET_IP_ALIGN
+                       /* rx_offset will likely not equal NET_IP_ALIGN
+                        * if this is a 5701 card running in PCI-X mode
+                        * [see tg3_get_invariants()]
+                        */
                ) {
                        int skb_size;
 
@@ -4125,11 +4507,12 @@ static int tg3_rx(struct tg3 *tp, int budget)
                        tg3_recycle_rx(tp, opaque_key,
                                       desc_idx, *post_ptr);
 
-                       copy_skb = netdev_alloc_skb(tp->dev, len + 2);
+                       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, 2);
+                       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);
@@ -4148,6 +4531,13 @@ static int tg3_rx(struct tg3 *tp, int budget)
                        skb->ip_summed = CHECKSUM_NONE;
 
                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;
+               }
+
 #if TG3_VLAN_TAG_USED
                if (tp->vlgrp != NULL &&
                    desc->type_flags & RXD_FLAG_VLAN) {
@@ -4155,9 +4545,8 @@ static int tg3_rx(struct tg3 *tp, int budget)
                                    desc->err_vlan & RXD_VLAN_MASK);
                } else
 #endif
-                       netif_receive_skb(skb);
+                       napi_gro_receive(&tp->napi, skb);
 
-               tp->dev->last_rx = jiffies;
                received++;
                budget--;
 
@@ -4266,12 +4655,13 @@ static int tg3_poll(struct napi_struct *napi, int budget)
                         * so we must read it before checking for more work.
                         */
                        tp->last_tag = sblk->status_tag;
+                       tp->last_irq_tag = tp->last_tag;
                        rmb();
                } else
                        sblk->status &= ~SD_STATUS_UPDATED;
 
                if (likely(!tg3_has_work(tp))) {
-                       netif_rx_complete(tp->dev, napi);
+                       napi_complete(napi);
                        tg3_restart_ints(tp);
                        break;
                }
@@ -4281,7 +4671,7 @@ static int tg3_poll(struct napi_struct *napi, int budget)
 
 tx_recovery:
        /* work_done is guaranteed to be less than budget. */
-       netif_rx_complete(tp->dev, napi);
+       napi_complete(napi);
        schedule_work(&tp->reset_task);
        return work_done;
 }
@@ -4330,7 +4720,7 @@ static irqreturn_t tg3_msi_1shot(int irq, void *dev_id)
        prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
 
        if (likely(!tg3_irq_sync(tp)))
-               netif_rx_schedule(dev, &tp->napi);
+               napi_schedule(&tp->napi);
 
        return IRQ_HANDLED;
 }
@@ -4355,7 +4745,7 @@ static irqreturn_t tg3_msi(int irq, void *dev_id)
         */
        tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
        if (likely(!tg3_irq_sync(tp)))
-               netif_rx_schedule(dev, &tp->napi);
+               napi_schedule(&tp->napi);
 
        return IRQ_RETVAL(1);
 }
@@ -4397,7 +4787,7 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id)
        sblk->status &= ~SD_STATUS_UPDATED;
        if (likely(tg3_has_work(tp))) {
                prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
-               netif_rx_schedule(dev, &tp->napi);
+               napi_schedule(&tp->napi);
        } else {
                /* No work, shared interrupt perhaps?  re-enable
                 * interrupts, and flush that PCI write
@@ -4421,7 +4811,7 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
         * Reading the PCI State register will confirm whether the
         * interrupt is ours and will flush the status block.
         */
-       if (unlikely(sblk->status_tag == tp->last_tag)) {
+       if (unlikely(sblk->status_tag == tp->last_irq_tag)) {
                if ((tp->tg3_flags & TG3_FLAG_CHIP_RESETTING) ||
                    (tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
                        handled = 0;
@@ -4441,18 +4831,22 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
         * excessive spurious interrupts can be worse in some cases.
         */
        tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
+
+       /*
+        * In a shared interrupt configuration, sometimes other devices'
+        * interrupts will scream.  We record the current status tag here
+        * so that the above check can report that the screaming interrupts
+        * are unhandled.  Eventually they will be silenced.
+        */
+       tp->last_irq_tag = sblk->status_tag;
+
        if (tg3_irq_sync(tp))
                goto out;
-       if (netif_rx_schedule_prep(dev, &tp->napi)) {
-               prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
-               /* Update last_tag to mark that this status has been
-                * seen. Because interrupt may be shared, we may be
-                * racing with tg3_poll(), so only update last_tag
-                * if tg3_poll() is not scheduled.
-                */
-               tp->last_tag = sblk->status_tag;
-               __netif_rx_schedule(dev, &tp->napi);
-       }
+
+       prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
+
+       napi_schedule(&tp->napi);
+
 out:
        return IRQ_RETVAL(handled);
 }
@@ -4592,7 +4986,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_40BIT_MASK);
+               return (((u64) mapping + len) > DMA_BIT_MASK(40));
        return 0;
 #else
        return 0;
@@ -4627,7 +5021,7 @@ static int tigon3_dma_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb,
                /* New SKB is guaranteed to be linear. */
                entry = *start;
                ret = skb_dma_map(&tp->pdev->dev, new_skb, DMA_TO_DEVICE);
-               new_addr = skb_shinfo(new_skb)->dma_maps[0];
+               new_addr = skb_shinfo(new_skb)->dma_head;
 
                /* Make sure new skb does not cross any 4G boundaries.
                 * Drop the packet if it does.
@@ -4761,7 +5155,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        sp = skb_shinfo(skb);
 
-       mapping = sp->dma_maps[0];
+       mapping = sp->dma_head;
 
        tp->tx_buffers[entry].skb = skb;
 
@@ -4779,7 +5173,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
                        len = frag->size;
-                       mapping = sp->dma_maps[i + 1];
+                       mapping = sp->dma_maps[i];
                        tp->tx_buffers[entry].skb = NULL;
 
                        tg3_set_txd(tp, entry, mapping, len,
@@ -4800,9 +5194,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
        }
 
 out_unlock:
-       mmiowb();
-
-       dev->trans_start = jiffies;
+       mmiowb();
 
        return NETDEV_TX_OK;
 }
@@ -4939,7 +5331,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
 
        sp = skb_shinfo(skb);
 
-       mapping = sp->dma_maps[0];
+       mapping = sp->dma_head;
 
        tp->tx_buffers[entry].skb = skb;
 
@@ -4964,7 +5356,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
                        skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
                        len = frag->size;
-                       mapping = sp->dma_maps[i + 1];
+                       mapping = sp->dma_maps[i];
 
                        tp->tx_buffers[entry].skb = NULL;
 
@@ -5013,9 +5405,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
        }
 
 out_unlock:
-       mmiowb();
-
-       dev->trans_start = jiffies;
+       mmiowb();
 
        return NETDEV_TX_OK;
 }
@@ -5441,62 +5831,6 @@ static int tg3_abort_hw(struct tg3 *tp, int silent)
        return err;
 }
 
-/* tp->lock is held. */
-static int tg3_nvram_lock(struct tg3 *tp)
-{
-       if (tp->tg3_flags & TG3_FLAG_NVRAM) {
-               int i;
-
-               if (tp->nvram_lock_cnt == 0) {
-                       tw32(NVRAM_SWARB, SWARB_REQ_SET1);
-                       for (i = 0; i < 8000; i++) {
-                               if (tr32(NVRAM_SWARB) & SWARB_GNT1)
-                                       break;
-                               udelay(20);
-                       }
-                       if (i == 8000) {
-                               tw32(NVRAM_SWARB, SWARB_REQ_CLR1);
-                               return -ENODEV;
-                       }
-               }
-               tp->nvram_lock_cnt++;
-       }
-       return 0;
-}
-
-/* tp->lock is held. */
-static void tg3_nvram_unlock(struct tg3 *tp)
-{
-       if (tp->tg3_flags & TG3_FLAG_NVRAM) {
-               if (tp->nvram_lock_cnt > 0)
-                       tp->nvram_lock_cnt--;
-               if (tp->nvram_lock_cnt == 0)
-                       tw32_f(NVRAM_SWARB, SWARB_REQ_CLR1);
-       }
-}
-
-/* tp->lock is held. */
-static void tg3_enable_nvram_access(struct tg3 *tp)
-{
-       if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
-           !(tp->tg3_flags2 & TG3_FLG2_PROTECTED_NVRAM)) {
-               u32 nvaccess = tr32(NVRAM_ACCESS);
-
-               tw32(NVRAM_ACCESS, nvaccess | ACCESS_ENABLE);
-       }
-}
-
-/* tp->lock is held. */
-static void tg3_disable_nvram_access(struct tg3 *tp)
-{
-       if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
-           !(tp->tg3_flags2 & TG3_FLG2_PROTECTED_NVRAM)) {
-               u32 nvaccess = tr32(NVRAM_ACCESS);
-
-               tw32(NVRAM_ACCESS, nvaccess & ~ACCESS_ENABLE);
-       }
-}
-
 static void tg3_ape_send_event(struct tg3 *tp, u32 event)
 {
        int i;
@@ -5557,6 +5891,13 @@ static void tg3_ape_driver_state_change(struct tg3 *tp, int kind)
                        event = APE_EVENT_STATUS_STATE_START;
                        break;
                case RESET_KIND_SHUTDOWN:
+                       /* With the interface we are currently using,
+                        * APE does not track driver state.  Wiping
+                        * out the HOST SEGMENT SIGNATURE forces
+                        * the APE to assume OS absent status.
+                        */
+                       tg3_ape_write32(tp, TG3_APE_HOST_SEG_SIG, 0x0);
+
                        event = APE_EVENT_STATUS_STATE_UNLOAD;
                        break;
                case RESET_KIND_SUSPEND:
@@ -5721,17 +6062,19 @@ static void tg3_restore_pci_state(struct tg3 *tp)
 
        pci_write_config_word(tp->pdev, PCI_COMMAND, tp->pci_cmd);
 
-       if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)
-               pcie_set_readrq(tp->pdev, 4096);
-       else {
-               pci_write_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE,
-                                     tp->pci_cacheline_sz);
-               pci_write_config_byte(tp->pdev, PCI_LATENCY_TIMER,
-                                     tp->pci_lat_timer);
+       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);
+               else {
+                       pci_write_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE,
+                                             tp->pci_cacheline_sz);
+                       pci_write_config_byte(tp->pdev, PCI_LATENCY_TIMER,
+                                             tp->pci_lat_timer);
+               }
        }
 
        /* Make sure PCI-X relaxed ordering bit is clear. */
-       if (tp->pcix_cap) {
+       if (tp->tg3_flags & TG3_FLAG_PCIX_MODE) {
                u16 pcix_cmd;
 
                pci_read_config_word(tp->pdev, tp->pcix_cap + PCI_X_CMD,
@@ -5788,11 +6131,7 @@ static int tg3_chip_reset(struct tg3 *tp)
        tg3_save_pci_state(tp);
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
+           (tp->tg3_flags3 & TG3_FLG3_5755_PLUS))
                tw32(GRC_FASTBOOT_PC, 0);
 
        /*
@@ -5817,6 +6156,7 @@ static int tg3_chip_reset(struct tg3 *tp)
                tp->hw_status->status_tag = 0;
        }
        tp->last_tag = 0;
+       tp->last_irq_tag = 0;
        smp_mb();
        synchronize_irq(tp->pdev->irq);
 
@@ -5871,7 +6211,7 @@ static int tg3_chip_reset(struct tg3 *tp)
 
        udelay(120);
 
-       if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) {
+       if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) && tp->pcie_cap) {
                if (tp->pci_chip_rev_id == CHIPREV_ID_5750_A0) {
                        int i;
                        u32 cfg_val;
@@ -5884,8 +6224,23 @@ static int tg3_chip_reset(struct tg3 *tp)
                        pci_write_config_dword(tp->pdev, 0xc4,
                                               cfg_val | (1 << 15));
                }
-               /* Set PCIE max payload size and clear error status.  */
-               pci_write_config_dword(tp->pdev, 0xd8, 0xf5000);
+
+               /* Set PCIE max payload size to 128 bytes and
+                * clear the "no snoop" and "relaxed ordering" bits.
+                */
+               pci_write_config_word(tp->pdev,
+                                     tp->pcie_cap + PCI_EXP_DEVCTL,
+                                     0);
+
+               pcie_set_readrq(tp->pdev, 4096);
+
+               /* Clear error status */
+               pci_write_config_word(tp->pdev,
+                                     tp->pcie_cap + PCI_EXP_DEVSTA,
+                                     PCI_EXP_DEVSTA_CED |
+                                     PCI_EXP_DEVSTA_NFED |
+                                     PCI_EXP_DEVSTA_FED |
+                                     PCI_EXP_DEVSTA_URD);
        }
 
        tg3_restore_pci_state(tp);
@@ -5996,6 +6351,8 @@ static int tg3_halt(struct tg3 *tp, int kind, int silent)
        tg3_abort_hw(tp, silent);
        err = tg3_chip_reset(tp);
 
+       __tg3_set_mac_addr(tp, 0);
+
        tg3_write_sig_legacy(tp, kind);
        tg3_write_sig_post_reset(tp, kind);
 
@@ -6005,130 +6362,6 @@ static int tg3_halt(struct tg3 *tp, int kind, int silent)
        return 0;
 }
 
-#define TG3_FW_RELEASE_MAJOR   0x0
-#define TG3_FW_RELASE_MINOR    0x0
-#define TG3_FW_RELEASE_FIX     0x0
-#define TG3_FW_START_ADDR      0x08000000
-#define TG3_FW_TEXT_ADDR       0x08000000
-#define TG3_FW_TEXT_LEN                0x9c0
-#define TG3_FW_RODATA_ADDR     0x080009c0
-#define TG3_FW_RODATA_LEN      0x60
-#define TG3_FW_DATA_ADDR       0x08000a40
-#define TG3_FW_DATA_LEN                0x20
-#define TG3_FW_SBSS_ADDR       0x08000a60
-#define TG3_FW_SBSS_LEN                0xc
-#define TG3_FW_BSS_ADDR                0x08000a70
-#define TG3_FW_BSS_LEN         0x10
-
-static const u32 tg3FwText[(TG3_FW_TEXT_LEN / sizeof(u32)) + 1] = {
-       0x00000000, 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c1d0800,
-       0x37bd3ffc, 0x03a0f021, 0x3c100800, 0x26100000, 0x0e000018, 0x00000000,
-       0x0000000d, 0x3c1d0800, 0x37bd3ffc, 0x03a0f021, 0x3c100800, 0x26100034,
-       0x0e00021c, 0x00000000, 0x0000000d, 0x00000000, 0x00000000, 0x00000000,
-       0x27bdffe0, 0x3c1cc000, 0xafbf0018, 0xaf80680c, 0x0e00004c, 0x241b2105,
-       0x97850000, 0x97870002, 0x9782002c, 0x9783002e, 0x3c040800, 0x248409c0,
-       0xafa00014, 0x00021400, 0x00621825, 0x00052c00, 0xafa30010, 0x8f860010,
-       0x00e52825, 0x0e000060, 0x24070102, 0x3c02ac00, 0x34420100, 0x3c03ac01,
-       0x34630100, 0xaf820490, 0x3c02ffff, 0xaf820494, 0xaf830498, 0xaf82049c,
-       0x24020001, 0xaf825ce0, 0x0e00003f, 0xaf825d00, 0x0e000140, 0x00000000,
-       0x8fbf0018, 0x03e00008, 0x27bd0020, 0x2402ffff, 0xaf825404, 0x8f835400,
-       0x34630400, 0xaf835400, 0xaf825404, 0x3c020800, 0x24420034, 0xaf82541c,
-       0x03e00008, 0xaf805400, 0x00000000, 0x00000000, 0x3c020800, 0x34423000,
-       0x3c030800, 0x34633000, 0x3c040800, 0x348437ff, 0x3c010800, 0xac220a64,
-       0x24020040, 0x3c010800, 0xac220a68, 0x3c010800, 0xac200a60, 0xac600000,
-       0x24630004, 0x0083102b, 0x5040fffd, 0xac600000, 0x03e00008, 0x00000000,
-       0x00804821, 0x8faa0010, 0x3c020800, 0x8c420a60, 0x3c040800, 0x8c840a68,
-       0x8fab0014, 0x24430001, 0x0044102b, 0x3c010800, 0xac230a60, 0x14400003,
-       0x00004021, 0x3c010800, 0xac200a60, 0x3c020800, 0x8c420a60, 0x3c030800,
-       0x8c630a64, 0x91240000, 0x00021140, 0x00431021, 0x00481021, 0x25080001,
-       0xa0440000, 0x29020008, 0x1440fff4, 0x25290001, 0x3c020800, 0x8c420a60,
-       0x3c030800, 0x8c630a64, 0x8f84680c, 0x00021140, 0x00431021, 0xac440008,
-       0xac45000c, 0xac460010, 0xac470014, 0xac4a0018, 0x03e00008, 0xac4b001c,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0,
-       0x02000008, 0x00000000, 0x0a0001e3, 0x3c0a0001, 0x0a0001e3, 0x3c0a0002,
-       0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000,
-       0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000,
-       0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000,
-       0x0a0001e3, 0x3c0a0007, 0x0a0001e3, 0x3c0a0008, 0x0a0001e3, 0x3c0a0009,
-       0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000, 0x0a0001e3, 0x3c0a000b,
-       0x0a0001e3, 0x3c0a000c, 0x0a0001e3, 0x3c0a000d, 0x0a0001e3, 0x00000000,
-       0x0a0001e3, 0x00000000, 0x0a0001e3, 0x3c0a000e, 0x0a0001e3, 0x00000000,
-       0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000,
-       0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000,
-       0x0a0001e3, 0x00000000, 0x0a0001e3, 0x3c0a0013, 0x0a0001e3, 0x3c0a0014,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0x27bdffe0, 0x00001821, 0x00001021, 0xafbf0018, 0xafb10014, 0xafb00010,
-       0x3c010800, 0x00220821, 0xac200a70, 0x3c010800, 0x00220821, 0xac200a74,
-       0x3c010800, 0x00220821, 0xac200a78, 0x24630001, 0x1860fff5, 0x2442000c,
-       0x24110001, 0x8f906810, 0x32020004, 0x14400005, 0x24040001, 0x3c020800,
-       0x8c420a78, 0x18400003, 0x00002021, 0x0e000182, 0x00000000, 0x32020001,
-       0x10400003, 0x00000000, 0x0e000169, 0x00000000, 0x0a000153, 0xaf915028,
-       0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x3c050800,
-       0x8ca50a70, 0x3c060800, 0x8cc60a80, 0x3c070800, 0x8ce70a78, 0x27bdffe0,
-       0x3c040800, 0x248409d0, 0xafbf0018, 0xafa00010, 0x0e000060, 0xafa00014,
-       0x0e00017b, 0x00002021, 0x8fbf0018, 0x03e00008, 0x27bd0020, 0x24020001,
-       0x8f836810, 0x00821004, 0x00021027, 0x00621824, 0x03e00008, 0xaf836810,
-       0x27bdffd8, 0xafbf0024, 0x1080002e, 0xafb00020, 0x8f825cec, 0xafa20018,
-       0x8f825cec, 0x3c100800, 0x26100a78, 0xafa2001c, 0x34028000, 0xaf825cec,
-       0x8e020000, 0x18400016, 0x00000000, 0x3c020800, 0x94420a74, 0x8fa3001c,
-       0x000221c0, 0xac830004, 0x8fa2001c, 0x3c010800, 0x0e000201, 0xac220a74,
-       0x10400005, 0x00000000, 0x8e020000, 0x24420001, 0x0a0001df, 0xae020000,
-       0x3c020800, 0x8c420a70, 0x00021c02, 0x000321c0, 0x0a0001c5, 0xafa2001c,
-       0x0e000201, 0x00000000, 0x1040001f, 0x00000000, 0x8e020000, 0x8fa3001c,
-       0x24420001, 0x3c010800, 0xac230a70, 0x3c010800, 0xac230a74, 0x0a0001df,
-       0xae020000, 0x3c100800, 0x26100a78, 0x8e020000, 0x18400028, 0x00000000,
-       0x0e000201, 0x00000000, 0x14400024, 0x00000000, 0x8e020000, 0x3c030800,
-       0x8c630a70, 0x2442ffff, 0xafa3001c, 0x18400006, 0xae020000, 0x00031402,
-       0x000221c0, 0x8c820004, 0x3c010800, 0xac220a70, 0x97a2001e, 0x2442ff00,
-       0x2c420300, 0x1440000b, 0x24024000, 0x3c040800, 0x248409dc, 0xafa00010,
-       0xafa00014, 0x8fa6001c, 0x24050008, 0x0e000060, 0x00003821, 0x0a0001df,
-       0x00000000, 0xaf825cf8, 0x3c020800, 0x8c420a40, 0x8fa3001c, 0x24420001,
-       0xaf835cf8, 0x3c010800, 0xac220a40, 0x8fbf0024, 0x8fb00020, 0x03e00008,
-       0x27bd0028, 0x27bdffe0, 0x3c040800, 0x248409e8, 0x00002821, 0x00003021,
-       0x00003821, 0xafbf0018, 0xafa00010, 0x0e000060, 0xafa00014, 0x8fbf0018,
-       0x03e00008, 0x27bd0020, 0x8f82680c, 0x8f85680c, 0x00021827, 0x0003182b,
-       0x00031823, 0x00431024, 0x00441021, 0x00a2282b, 0x10a00006, 0x00000000,
-       0x00401821, 0x8f82680c, 0x0043102b, 0x1440fffd, 0x00000000, 0x03e00008,
-       0x00000000, 0x3c040800, 0x8c840000, 0x3c030800, 0x8c630a40, 0x0064102b,
-       0x54400002, 0x00831023, 0x00641023, 0x2c420008, 0x03e00008, 0x38420001,
-       0x27bdffe0, 0x00802821, 0x3c040800, 0x24840a00, 0x00003021, 0x00003821,
-       0xafbf0018, 0xafa00010, 0x0e000060, 0xafa00014, 0x0a000216, 0x00000000,
-       0x8fbf0018, 0x03e00008, 0x27bd0020, 0x00000000, 0x27bdffe0, 0x3c1cc000,
-       0xafbf0018, 0x0e00004c, 0xaf80680c, 0x3c040800, 0x24840a10, 0x03802821,
-       0x00003021, 0x00003821, 0xafa00010, 0x0e000060, 0xafa00014, 0x2402ffff,
-       0xaf825404, 0x3c0200aa, 0x0e000234, 0xaf825434, 0x8fbf0018, 0x03e00008,
-       0x27bd0020, 0x00000000, 0x00000000, 0x00000000, 0x27bdffe8, 0xafb00010,
-       0x24100001, 0xafbf0014, 0x3c01c003, 0xac200000, 0x8f826810, 0x30422000,
-       0x10400003, 0x00000000, 0x0e000246, 0x00000000, 0x0a00023a, 0xaf905428,
-       0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x27bdfff8, 0x8f845d0c,
-       0x3c0200ff, 0x3c030800, 0x8c630a50, 0x3442fff8, 0x00821024, 0x1043001e,
-       0x3c0500ff, 0x34a5fff8, 0x3c06c003, 0x3c074000, 0x00851824, 0x8c620010,
-       0x3c010800, 0xac230a50, 0x30420008, 0x10400005, 0x00871025, 0x8cc20000,
-       0x24420001, 0xacc20000, 0x00871025, 0xaf825d0c, 0x8fa20000, 0x24420001,
-       0xafa20000, 0x8fa20000, 0x8fa20000, 0x24420001, 0xafa20000, 0x8fa20000,
-       0x8f845d0c, 0x3c030800, 0x8c630a50, 0x00851024, 0x1443ffe8, 0x00851824,
-       0x27bd0008, 0x03e00008, 0x00000000, 0x00000000, 0x00000000
-};
-
-static const u32 tg3FwRodata[(TG3_FW_RODATA_LEN / sizeof(u32)) + 1] = {
-       0x35373031, 0x726c7341, 0x00000000, 0x00000000, 0x53774576, 0x656e7430,
-       0x00000000, 0x726c7045, 0x76656e74, 0x31000000, 0x556e6b6e, 0x45766e74,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x66617461, 0x6c457272,
-       0x00000000, 0x00000000, 0x4d61696e, 0x43707542, 0x00000000, 0x00000000,
-       0x00000000
-};
-
-#if 0 /* All zeros, don't eat up space with it. */
-u32 tg3FwData[(TG3_FW_DATA_LEN / sizeof(u32)) + 1] = {
-       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000
-};
-#endif
-
 #define RX_CPU_SCRATCH_BASE    0x30000
 #define RX_CPU_SCRATCH_SIZE    0x04000
 #define TX_CPU_SCRATCH_BASE    0x34000
@@ -6183,15 +6416,9 @@ static int tg3_halt_cpu(struct tg3 *tp, u32 offset)
 }
 
 struct fw_info {
-       unsigned int text_base;
-       unsigned int text_len;
-       const u32 *text_data;
-       unsigned int rodata_base;
-       unsigned int rodata_len;
-       const u32 *rodata_data;
-       unsigned int data_base;
-       unsigned int data_len;
-       const u32 *data_data;
+       unsigned int fw_base;
+       unsigned int fw_len;
+       const __be32 *fw_data;
 };
 
 /* tp->lock is held. */
@@ -6228,24 +6455,11 @@ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_b
                write_op(tp, cpu_scratch_base + i, 0);
        tw32(cpu_base + CPU_STATE, 0xffffffff);
        tw32(cpu_base + CPU_MODE, tr32(cpu_base+CPU_MODE)|CPU_MODE_HALT);
-       for (i = 0; i < (info->text_len / sizeof(u32)); i++)
-               write_op(tp, (cpu_scratch_base +
-                             (info->text_base & 0xffff) +
-                             (i * sizeof(u32))),
-                        (info->text_data ?
-                         info->text_data[i] : 0));
-       for (i = 0; i < (info->rodata_len / sizeof(u32)); i++)
-               write_op(tp, (cpu_scratch_base +
-                             (info->rodata_base & 0xffff) +
-                             (i * sizeof(u32))),
-                        (info->rodata_data ?
-                         info->rodata_data[i] : 0));
-       for (i = 0; i < (info->data_len / sizeof(u32)); i++)
+       for (i = 0; i < (info->fw_len / sizeof(u32)); i++)
                write_op(tp, (cpu_scratch_base +
-                             (info->data_base & 0xffff) +
+                             (info->fw_base & 0xffff) +
                              (i * sizeof(u32))),
-                        (info->data_data ?
-                         info->data_data[i] : 0));
+                             be32_to_cpu(info->fw_data[i]));
 
        err = 0;
 
@@ -6257,17 +6471,20 @@ out:
 static int tg3_load_5701_a0_firmware_fix(struct tg3 *tp)
 {
        struct fw_info info;
+       const __be32 *fw_data;
        int err, i;
 
-       info.text_base = TG3_FW_TEXT_ADDR;
-       info.text_len = TG3_FW_TEXT_LEN;
-       info.text_data = &tg3FwText[0];
-       info.rodata_base = TG3_FW_RODATA_ADDR;
-       info.rodata_len = TG3_FW_RODATA_LEN;
-       info.rodata_data = &tg3FwRodata[0];
-       info.data_base = TG3_FW_DATA_ADDR;
-       info.data_len = TG3_FW_DATA_LEN;
-       info.data_data = NULL;
+       fw_data = (void *)tp->fw->data;
+
+       /* Firmware blob starts with version numbers, followed by
+          start address and length. We are setting complete length.
+          length = end_address_of_bss - start_address_of_text.
+          Remainder is the blob to be loaded contiguously
+          from start address. */
+
+       info.fw_base = be32_to_cpu(fw_data[1]);
+       info.fw_len = tp->fw->size - 12;
+       info.fw_data = &fw_data[3];
 
        err = tg3_load_firmware_cpu(tp, RX_CPU_BASE,
                                    RX_CPU_SCRATCH_BASE, RX_CPU_SCRATCH_SIZE,
@@ -6283,21 +6500,21 @@ static int tg3_load_5701_a0_firmware_fix(struct tg3 *tp)
 
        /* Now startup only the RX cpu. */
        tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff);
-       tw32_f(RX_CPU_BASE + CPU_PC,    TG3_FW_TEXT_ADDR);
+       tw32_f(RX_CPU_BASE + CPU_PC, info.fw_base);
 
        for (i = 0; i < 5; i++) {
-               if (tr32(RX_CPU_BASE + CPU_PC) == TG3_FW_TEXT_ADDR)
+               if (tr32(RX_CPU_BASE + CPU_PC) == info.fw_base)
                        break;
                tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff);
                tw32(RX_CPU_BASE + CPU_MODE,  CPU_MODE_HALT);
-               tw32_f(RX_CPU_BASE + CPU_PC,    TG3_FW_TEXT_ADDR);
+               tw32_f(RX_CPU_BASE + CPU_PC, info.fw_base);
                udelay(1000);
        }
        if (i >= 5) {
                printk(KERN_ERR PFX "tg3_load_firmware fails for %s "
                       "to set RX CPU PC, is %08x should be %08x\n",
                       tp->dev->name, tr32(RX_CPU_BASE + CPU_PC),
-                      TG3_FW_TEXT_ADDR);
+                      info.fw_base);
                return -ENODEV;
        }
        tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff);
@@ -6306,547 +6523,36 @@ static int tg3_load_5701_a0_firmware_fix(struct tg3 *tp)
        return 0;
 }
 
-
-#define TG3_TSO_FW_RELEASE_MAJOR       0x1
-#define TG3_TSO_FW_RELASE_MINOR                0x6
-#define TG3_TSO_FW_RELEASE_FIX         0x0
-#define TG3_TSO_FW_START_ADDR          0x08000000
-#define TG3_TSO_FW_TEXT_ADDR           0x08000000
-#define TG3_TSO_FW_TEXT_LEN            0x1aa0
-#define TG3_TSO_FW_RODATA_ADDR         0x08001aa0
-#define TG3_TSO_FW_RODATA_LEN          0x60
-#define TG3_TSO_FW_DATA_ADDR           0x08001b20
-#define TG3_TSO_FW_DATA_LEN            0x30
-#define TG3_TSO_FW_SBSS_ADDR           0x08001b50
-#define TG3_TSO_FW_SBSS_LEN            0x2c
-#define TG3_TSO_FW_BSS_ADDR            0x08001b80
-#define TG3_TSO_FW_BSS_LEN             0x894
-
-static const u32 tg3TsoFwText[(TG3_TSO_FW_TEXT_LEN / 4) + 1] = {
-       0x0e000003, 0x00000000, 0x08001b24, 0x00000000, 0x10000003, 0x00000000,
-       0x0000000d, 0x0000000d, 0x3c1d0800, 0x37bd4000, 0x03a0f021, 0x3c100800,
-       0x26100000, 0x0e000010, 0x00000000, 0x0000000d, 0x27bdffe0, 0x3c04fefe,
-       0xafbf0018, 0x0e0005d8, 0x34840002, 0x0e000668, 0x00000000, 0x3c030800,
-       0x90631b68, 0x24020002, 0x3c040800, 0x24841aac, 0x14620003, 0x24050001,
-       0x3c040800, 0x24841aa0, 0x24060006, 0x00003821, 0xafa00010, 0x0e00067c,
-       0xafa00014, 0x8f625c50, 0x34420001, 0xaf625c50, 0x8f625c90, 0x34420001,
-       0xaf625c90, 0x2402ffff, 0x0e000034, 0xaf625404, 0x8fbf0018, 0x03e00008,
-       0x27bd0020, 0x00000000, 0x00000000, 0x00000000, 0x27bdffe0, 0xafbf001c,
-       0xafb20018, 0xafb10014, 0x0e00005b, 0xafb00010, 0x24120002, 0x24110001,
-       0x8f706820, 0x32020100, 0x10400003, 0x00000000, 0x0e0000bb, 0x00000000,
-       0x8f706820, 0x32022000, 0x10400004, 0x32020001, 0x0e0001f0, 0x24040001,
-       0x32020001, 0x10400003, 0x00000000, 0x0e0000a3, 0x00000000, 0x3c020800,
-       0x90421b98, 0x14520003, 0x00000000, 0x0e0004c0, 0x00000000, 0x0a00003c,
-       0xaf715028, 0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008,
-       0x27bd0020, 0x27bdffe0, 0x3c040800, 0x24841ac0, 0x00002821, 0x00003021,
-       0x00003821, 0xafbf0018, 0xafa00010, 0x0e00067c, 0xafa00014, 0x3c040800,
-       0x248423d8, 0xa4800000, 0x3c010800, 0xa0201b98, 0x3c010800, 0xac201b9c,
-       0x3c010800, 0xac201ba0, 0x3c010800, 0xac201ba4, 0x3c010800, 0xac201bac,
-       0x3c010800, 0xac201bb8, 0x3c010800, 0xac201bbc, 0x8f624434, 0x3c010800,
-       0xac221b88, 0x8f624438, 0x3c010800, 0xac221b8c, 0x8f624410, 0xac80f7a8,
-       0x3c010800, 0xac201b84, 0x3c010800, 0xac2023e0, 0x3c010800, 0xac2023c8,
-       0x3c010800, 0xac2023cc, 0x3c010800, 0xac202400, 0x3c010800, 0xac221b90,
-       0x8f620068, 0x24030007, 0x00021702, 0x10430005, 0x00000000, 0x8f620068,
-       0x00021702, 0x14400004, 0x24020001, 0x3c010800, 0x0a000097, 0xac20240c,
-       0xac820034, 0x3c040800, 0x24841acc, 0x3c050800, 0x8ca5240c, 0x00003021,
-       0x00003821, 0xafa00010, 0x0e00067c, 0xafa00014, 0x8fbf0018, 0x03e00008,
-       0x27bd0020, 0x27bdffe0, 0x3c040800, 0x24841ad8, 0x00002821, 0x00003021,
-       0x00003821, 0xafbf0018, 0xafa00010, 0x0e00067c, 0xafa00014, 0x0e00005b,
-       0x00000000, 0x0e0000b4, 0x00002021, 0x8fbf0018, 0x03e00008, 0x27bd0020,
-       0x24020001, 0x8f636820, 0x00821004, 0x00021027, 0x00621824, 0x03e00008,
-       0xaf636820, 0x27bdffd0, 0xafbf002c, 0xafb60028, 0xafb50024, 0xafb40020,
-       0xafb3001c, 0xafb20018, 0xafb10014, 0xafb00010, 0x8f675c5c, 0x3c030800,
-       0x24631bbc, 0x8c620000, 0x14470005, 0x3c0200ff, 0x3c020800, 0x90421b98,
-       0x14400119, 0x3c0200ff, 0x3442fff8, 0x00e28824, 0xac670000, 0x00111902,
-       0x306300ff, 0x30e20003, 0x000211c0, 0x00622825, 0x00a04021, 0x00071602,
-       0x3c030800, 0x90631b98, 0x3044000f, 0x14600036, 0x00804821, 0x24020001,
-       0x3c010800, 0xa0221b98, 0x00051100, 0x00821025, 0x3c010800, 0xac201b9c,
-       0x3c010800, 0xac201ba0, 0x3c010800, 0xac201ba4, 0x3c010800, 0xac201bac,
-       0x3c010800, 0xac201bb8, 0x3c010800, 0xac201bb0, 0x3c010800, 0xac201bb4,
-       0x3c010800, 0xa42223d8, 0x9622000c, 0x30437fff, 0x3c010800, 0xa4222410,
-       0x30428000, 0x3c010800, 0xa4231bc6, 0x10400005, 0x24020001, 0x3c010800,
-       0xac2223f4, 0x0a000102, 0x2406003e, 0x24060036, 0x3c010800, 0xac2023f4,
-       0x9622000a, 0x3c030800, 0x94631bc6, 0x3c010800, 0xac2023f0, 0x3c010800,
-       0xac2023f8, 0x00021302, 0x00021080, 0x00c21021, 0x00621821, 0x3c010800,
-       0xa42223d0, 0x3c010800, 0x0a000115, 0xa4231b96, 0x9622000c, 0x3c010800,
-       0xa42223ec, 0x3c040800, 0x24841b9c, 0x8c820000, 0x00021100, 0x3c010800,
-       0x00220821, 0xac311bc8, 0x8c820000, 0x00021100, 0x3c010800, 0x00220821,
-       0xac271bcc, 0x8c820000, 0x25030001, 0x306601ff, 0x00021100, 0x3c010800,
-       0x00220821, 0xac261bd0, 0x8c820000, 0x00021100, 0x3c010800, 0x00220821,
-       0xac291bd4, 0x96230008, 0x3c020800, 0x8c421bac, 0x00432821, 0x3c010800,
-       0xac251bac, 0x9622000a, 0x30420004, 0x14400018, 0x00061100, 0x8f630c14,
-       0x3063000f, 0x2c620002, 0x1440000b, 0x3c02c000, 0x8f630c14, 0x3c020800,
-       0x8c421b40, 0x3063000f, 0x24420001, 0x3c010800, 0xac221b40, 0x2c620002,
-       0x1040fff7, 0x3c02c000, 0x00e21825, 0xaf635c5c, 0x8f625c50, 0x30420002,
-       0x10400014, 0x00000000, 0x0a000147, 0x00000000, 0x3c030800, 0x8c631b80,
-       0x3c040800, 0x94841b94, 0x01221025, 0x3c010800, 0xa42223da, 0x24020001,
-       0x3c010800, 0xac221bb8, 0x24630001, 0x0085202a, 0x3c010800, 0x10800003,
-       0xac231b80, 0x3c010800, 0xa4251b94, 0x3c060800, 0x24c61b9c, 0x8cc20000,
-       0x24420001, 0xacc20000, 0x28420080, 0x14400005, 0x00000000, 0x0e000656,
-       0x24040002, 0x0a0001e6, 0x00000000, 0x3c020800, 0x8c421bb8, 0x10400078,
-       0x24020001, 0x3c050800, 0x90a51b98, 0x14a20072, 0x00000000, 0x3c150800,
-       0x96b51b96, 0x3c040800, 0x8c841bac, 0x32a3ffff, 0x0083102a, 0x1440006c,
-       0x00000000, 0x14830003, 0x00000000, 0x3c010800, 0xac2523f0, 0x1060005c,
-       0x00009021, 0x24d60004, 0x0060a021, 0x24d30014, 0x8ec20000, 0x00028100,
-       0x3c110800, 0x02308821, 0x0e000625, 0x8e311bc8, 0x00402821, 0x10a00054,
-       0x00000000, 0x9628000a, 0x31020040, 0x10400005, 0x2407180c, 0x8e22000c,
-       0x2407188c, 0x00021400, 0xaca20018, 0x3c030800, 0x00701821, 0x8c631bd0,
-       0x3c020800, 0x00501021, 0x8c421bd4, 0x00031d00, 0x00021400, 0x00621825,
-       0xaca30014, 0x8ec30004, 0x96220008, 0x00432023, 0x3242ffff, 0x3083ffff,
-       0x00431021, 0x0282102a, 0x14400002, 0x02b23023, 0x00803021, 0x8e620000,
-       0x30c4ffff, 0x00441021, 0xae620000, 0x8e220000, 0xaca20000, 0x8e220004,
-       0x8e63fff4, 0x00431021, 0xaca20004, 0xa4a6000e, 0x8e62fff4, 0x00441021,
-       0xae62fff4, 0x96230008, 0x0043102a, 0x14400005, 0x02469021, 0x8e62fff0,
-       0xae60fff4, 0x24420001, 0xae62fff0, 0xaca00008, 0x3242ffff, 0x14540008,
-       0x24020305, 0x31020080, 0x54400001, 0x34e70010, 0x24020905, 0xa4a2000c,
-       0x0a0001cb, 0x34e70020, 0xa4a2000c, 0x3c020800, 0x8c4223f0, 0x10400003,
-       0x3c024b65, 0x0a0001d3, 0x34427654, 0x3c02b49a, 0x344289ab, 0xaca2001c,
-       0x30e2ffff, 0xaca20010, 0x0e0005a2, 0x00a02021, 0x3242ffff, 0x0054102b,
-       0x1440ffa9, 0x00000000, 0x24020002, 0x3c010800, 0x0a0001e6, 0xa0221b98,
-       0x8ec2083c, 0x24420001, 0x0a0001e6, 0xaec2083c, 0x0e0004c0, 0x00000000,
-       0x8fbf002c, 0x8fb60028, 0x8fb50024, 0x8fb40020, 0x8fb3001c, 0x8fb20018,
-       0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0030, 0x27bdffd0, 0xafbf0028,
-       0xafb30024, 0xafb20020, 0xafb1001c, 0xafb00018, 0x8f725c9c, 0x3c0200ff,
-       0x3442fff8, 0x3c070800, 0x24e71bb4, 0x02428824, 0x9623000e, 0x8ce20000,
-       0x00431021, 0xace20000, 0x8e220010, 0x30420020, 0x14400011, 0x00809821,
-       0x0e00063b, 0x02202021, 0x3c02c000, 0x02421825, 0xaf635c9c, 0x8f625c90,
-       0x30420002, 0x1040011e, 0x00000000, 0xaf635c9c, 0x8f625c90, 0x30420002,
-       0x10400119, 0x00000000, 0x0a00020d, 0x00000000, 0x8e240008, 0x8e230014,
-       0x00041402, 0x000231c0, 0x00031502, 0x304201ff, 0x2442ffff, 0x3042007f,
-       0x00031942, 0x30637800, 0x00021100, 0x24424000, 0x00624821, 0x9522000a,
-       0x3084ffff, 0x30420008, 0x104000b0, 0x000429c0, 0x3c020800, 0x8c422400,
-       0x14400024, 0x24c50008, 0x94c20014, 0x3c010800, 0xa42223d0, 0x8cc40010,
-       0x00041402, 0x3c010800, 0xa42223d2, 0x3c010800, 0xa42423d4, 0x94c2000e,
-       0x3083ffff, 0x00431023, 0x3c010800, 0xac222408, 0x94c2001a, 0x3c010800,
-       0xac262400, 0x3c010800, 0xac322404, 0x3c010800, 0xac2223fc, 0x3c02c000,
-       0x02421825, 0xaf635c9c, 0x8f625c90, 0x30420002, 0x104000e5, 0x00000000,
-       0xaf635c9c, 0x8f625c90, 0x30420002, 0x104000e0, 0x00000000, 0x0a000246,
-       0x00000000, 0x94c2000e, 0x3c030800, 0x946323d4, 0x00434023, 0x3103ffff,
-       0x2c620008, 0x1040001c, 0x00000000, 0x94c20014, 0x24420028, 0x00a22821,
-       0x00031042, 0x1840000b, 0x00002021, 0x24e60848, 0x00403821, 0x94a30000,
-       0x8cc20000, 0x24840001, 0x00431021, 0xacc20000, 0x0087102a, 0x1440fff9,
-       0x24a50002, 0x31020001, 0x1040001f, 0x3c024000, 0x3c040800, 0x248423fc,
-       0xa0a00001, 0x94a30000, 0x8c820000, 0x00431021, 0x0a000285, 0xac820000,
-       0x8f626800, 0x3c030010, 0x00431024, 0x10400009, 0x00000000, 0x94c2001a,
-       0x3c030800, 0x8c6323fc, 0x00431021, 0x3c010800, 0xac2223fc, 0x0a000286,
-       0x3c024000, 0x94c2001a, 0x94c4001c, 0x3c030800, 0x8c6323fc, 0x00441023,
-       0x00621821, 0x3c010800, 0xac2323fc, 0x3c024000, 0x02421825, 0xaf635c9c,
-       0x8f625c90, 0x30420002, 0x1440fffc, 0x00000000, 0x9522000a, 0x30420010,
-       0x1040009b, 0x00000000, 0x3c030800, 0x946323d4, 0x3c070800, 0x24e72400,
-       0x8ce40000, 0x8f626800, 0x24630030, 0x00832821, 0x3c030010, 0x00431024,
-       0x1440000a, 0x00000000, 0x94a20004, 0x3c040800, 0x8c842408, 0x3c030800,
-       0x8c6323fc, 0x00441023, 0x00621821, 0x3c010800, 0xac2323fc, 0x3c040800,
-       0x8c8423fc, 0x00041c02, 0x3082ffff, 0x00622021, 0x00041402, 0x00822021,
-       0x00041027, 0xa4a20006, 0x3c030800, 0x8c632404, 0x3c0200ff, 0x3442fff8,
-       0x00628824, 0x96220008, 0x24050001, 0x24034000, 0x000231c0, 0x00801021,
-       0xa4c2001a, 0xa4c0001c, 0xace00000, 0x3c010800, 0xac251b60, 0xaf635cb8,
-       0x8f625cb0, 0x30420002, 0x10400003, 0x00000000, 0x3c010800, 0xac201b60,
-       0x8e220008, 0xaf625cb8, 0x8f625cb0, 0x30420002, 0x10400003, 0x00000000,
-       0x3c010800, 0xac201b60, 0x3c020800, 0x8c421b60, 0x1040ffec, 0x00000000,
-       0x3c040800, 0x0e00063b, 0x8c842404, 0x0a00032a, 0x00000000, 0x3c030800,
-       0x90631b98, 0x24020002, 0x14620003, 0x3c034b65, 0x0a0002e1, 0x00008021,
-       0x8e22001c, 0x34637654, 0x10430002, 0x24100002, 0x24100001, 0x00c02021,
-       0x0e000350, 0x02003021, 0x24020003, 0x3c010800, 0xa0221b98, 0x24020002,
-       0x1202000a, 0x24020001, 0x3c030800, 0x8c6323f0, 0x10620006, 0x00000000,
-       0x3c020800, 0x944223d8, 0x00021400, 0x0a00031f, 0xae220014, 0x3c040800,
-       0x248423da, 0x94820000, 0x00021400, 0xae220014, 0x3c020800, 0x8c421bbc,
-       0x3c03c000, 0x3c010800, 0xa0201b98, 0x00431025, 0xaf625c5c, 0x8f625c50,
-       0x30420002, 0x10400009, 0x00000000, 0x2484f7e2, 0x8c820000, 0x00431025,
-       0xaf625c5c, 0x8f625c50, 0x30420002, 0x1440fffa, 0x00000000, 0x3c020800,
-       0x24421b84, 0x8c430000, 0x24630001, 0xac430000, 0x8f630c14, 0x3063000f,
-       0x2c620002, 0x1440000c, 0x3c024000, 0x8f630c14, 0x3c020800, 0x8c421b40,
-       0x3063000f, 0x24420001, 0x3c010800, 0xac221b40, 0x2c620002, 0x1040fff7,
-       0x00000000, 0x3c024000, 0x02421825, 0xaf635c9c, 0x8f625c90, 0x30420002,
-       0x1440fffc, 0x00000000, 0x12600003, 0x00000000, 0x0e0004c0, 0x00000000,
-       0x8fbf0028, 0x8fb30024, 0x8fb20020, 0x8fb1001c, 0x8fb00018, 0x03e00008,
-       0x27bd0030, 0x8f634450, 0x3c040800, 0x24841b88, 0x8c820000, 0x00031c02,
-       0x0043102b, 0x14400007, 0x3c038000, 0x8c840004, 0x8f624450, 0x00021c02,
-       0x0083102b, 0x1040fffc, 0x3c038000, 0xaf634444, 0x8f624444, 0x00431024,
-       0x1440fffd, 0x00000000, 0x8f624448, 0x03e00008, 0x3042ffff, 0x3c024000,
-       0x00822025, 0xaf645c38, 0x8f625c30, 0x30420002, 0x1440fffc, 0x00000000,
-       0x03e00008, 0x00000000, 0x27bdffe0, 0x00805821, 0x14c00011, 0x256e0008,
-       0x3c020800, 0x8c4223f4, 0x10400007, 0x24020016, 0x3c010800, 0xa42223d2,
-       0x2402002a, 0x3c010800, 0x0a000364, 0xa42223d4, 0x8d670010, 0x00071402,
-       0x3c010800, 0xa42223d2, 0x3c010800, 0xa42723d4, 0x3c040800, 0x948423d4,
-       0x3c030800, 0x946323d2, 0x95cf0006, 0x3c020800, 0x944223d0, 0x00832023,
-       0x01e2c023, 0x3065ffff, 0x24a20028, 0x01c24821, 0x3082ffff, 0x14c0001a,
-       0x01226021, 0x9582000c, 0x3042003f, 0x3c010800, 0xa42223d6, 0x95820004,
-       0x95830006, 0x3c010800, 0xac2023e4, 0x3c010800, 0xac2023e8, 0x00021400,
-       0x00431025, 0x3c010800, 0xac221bc0, 0x95220004, 0x3c010800, 0xa4221bc4,
-       0x95230002, 0x01e51023, 0x0043102a, 0x10400010, 0x24020001, 0x3c010800,
-       0x0a000398, 0xac2223f8, 0x3c030800, 0x8c6323e8, 0x3c020800, 0x94421bc4,
-       0x00431021, 0xa5220004, 0x3c020800, 0x94421bc0, 0xa5820004, 0x3c020800,
-       0x8c421bc0, 0xa5820006, 0x3c020800, 0x8c4223f0, 0x3c0d0800, 0x8dad23e4,
-       0x3c0a0800, 0x144000e5, 0x8d4a23e8, 0x3c020800, 0x94421bc4, 0x004a1821,
-       0x3063ffff, 0x0062182b, 0x24020002, 0x10c2000d, 0x01435023, 0x3c020800,
-       0x944223d6, 0x30420009, 0x10400008, 0x00000000, 0x9582000c, 0x3042fff6,
-       0xa582000c, 0x3c020800, 0x944223d6, 0x30420009, 0x01a26823, 0x3c020800,
-       0x8c4223f8, 0x1040004a, 0x01203821, 0x3c020800, 0x944223d2, 0x00004021,
-       0xa520000a, 0x01e21023, 0xa5220002, 0x3082ffff, 0x00021042, 0x18400008,
-       0x00003021, 0x00401821, 0x94e20000, 0x25080001, 0x00c23021, 0x0103102a,
-       0x1440fffb, 0x24e70002, 0x00061c02, 0x30c2ffff, 0x00623021, 0x00061402,
-       0x00c23021, 0x00c02821, 0x00061027, 0xa522000a, 0x00003021, 0x2527000c,
-       0x00004021, 0x94e20000, 0x25080001, 0x00c23021, 0x2d020004, 0x1440fffb,
-       0x24e70002, 0x95220002, 0x00004021, 0x91230009, 0x00442023, 0x01803821,
-       0x3082ffff, 0xa4e00010, 0x00621821, 0x00021042, 0x18400010, 0x00c33021,
-       0x00404821, 0x94e20000, 0x24e70002, 0x00c23021, 0x30e2007f, 0x14400006,
-       0x25080001, 0x8d630000, 0x3c02007f, 0x3442ff80, 0x00625824, 0x25670008,
-       0x0109102a, 0x1440fff3, 0x00000000, 0x30820001, 0x10400005, 0x00061c02,
-       0xa0e00001, 0x94e20000, 0x00c23021, 0x00061c02, 0x30c2ffff, 0x00623021,
-       0x00061402, 0x00c23021, 0x0a00047d, 0x30c6ffff, 0x24020002, 0x14c20081,
-       0x00000000, 0x3c020800, 0x8c42240c, 0x14400007, 0x00000000, 0x3c020800,
-       0x944223d2, 0x95230002, 0x01e21023, 0x10620077, 0x00000000, 0x3c020800,
-       0x944223d2, 0x01e21023, 0xa5220002, 0x3c020800, 0x8c42240c, 0x1040001a,
-       0x31e3ffff, 0x8dc70010, 0x3c020800, 0x94421b96, 0x00e04021, 0x00072c02,
-       0x00aa2021, 0x00431023, 0x00823823, 0x00072402, 0x30e2ffff, 0x00823821,
-       0x00071027, 0xa522000a, 0x3102ffff, 0x3c040800, 0x948423d4, 0x00453023,
-       0x00e02821, 0x00641823, 0x006d1821, 0x00c33021, 0x00061c02, 0x30c2ffff,
-       0x0a00047d, 0x00623021, 0x01203821, 0x00004021, 0x3082ffff, 0x00021042,
-       0x18400008, 0x00003021, 0x00401821, 0x94e20000, 0x25080001, 0x00c23021,
-       0x0103102a, 0x1440fffb, 0x24e70002, 0x00061c02, 0x30c2ffff, 0x00623021,
-       0x00061402, 0x00c23021, 0x00c02821, 0x00061027, 0xa522000a, 0x00003021,
-       0x2527000c, 0x00004021, 0x94e20000, 0x25080001, 0x00c23021, 0x2d020004,
-       0x1440fffb, 0x24e70002, 0x95220002, 0x00004021, 0x91230009, 0x00442023,
-       0x01803821, 0x3082ffff, 0xa4e00010, 0x3c040800, 0x948423d4, 0x00621821,
-       0x00c33021, 0x00061c02, 0x30c2ffff, 0x00623021, 0x00061c02, 0x3c020800,
-       0x944223d0, 0x00c34821, 0x00441023, 0x00021fc2, 0x00431021, 0x00021043,
-       0x18400010, 0x00003021, 0x00402021, 0x94e20000, 0x24e70002, 0x00c23021,
-       0x30e2007f, 0x14400006, 0x25080001, 0x8d630000, 0x3c02007f, 0x3442ff80,
-       0x00625824, 0x25670008, 0x0104102a, 0x1440fff3, 0x00000000, 0x3c020800,
-       0x944223ec, 0x00c23021, 0x3122ffff, 0x00c23021, 0x00061c02, 0x30c2ffff,
-       0x00623021, 0x00061402, 0x00c23021, 0x00c04021, 0x00061027, 0xa5820010,
-       0xadc00014, 0x0a00049d, 0xadc00000, 0x8dc70010, 0x00e04021, 0x11400007,
-       0x00072c02, 0x00aa3021, 0x00061402, 0x30c3ffff, 0x00433021, 0x00061402,
-       0x00c22821, 0x00051027, 0xa522000a, 0x3c030800, 0x946323d4, 0x3102ffff,
-       0x01e21021, 0x00433023, 0x00cd3021, 0x00061c02, 0x30c2ffff, 0x00623021,
-       0x00061402, 0x00c23021, 0x00c04021, 0x00061027, 0xa5820010, 0x3102ffff,
-       0x00051c00, 0x00431025, 0xadc20010, 0x3c020800, 0x8c4223f4, 0x10400005,
-       0x2de205eb, 0x14400002, 0x25e2fff2, 0x34028870, 0xa5c20034, 0x3c030800,
-       0x246323e8, 0x8c620000, 0x24420001, 0xac620000, 0x3c040800, 0x8c8423e4,
-       0x3c020800, 0x8c421bc0, 0x3303ffff, 0x00832021, 0x00431821, 0x0062102b,
-       0x3c010800, 0xac2423e4, 0x10400003, 0x2482ffff, 0x3c010800, 0xac2223e4,
-       0x3c010800, 0xac231bc0, 0x03e00008, 0x27bd0020, 0x27bdffb8, 0x3c050800,
-       0x24a51b96, 0xafbf0044, 0xafbe0040, 0xafb7003c, 0xafb60038, 0xafb50034,
-       0xafb40030, 0xafb3002c, 0xafb20028, 0xafb10024, 0xafb00020, 0x94a90000,
-       0x3c020800, 0x944223d0, 0x3c030800, 0x8c631bb0, 0x3c040800, 0x8c841bac,
-       0x01221023, 0x0064182a, 0xa7a9001e, 0x106000be, 0xa7a20016, 0x24be0022,
-       0x97b6001e, 0x24b3001a, 0x24b70016, 0x8fc20000, 0x14400008, 0x00000000,
-       0x8fc2fff8, 0x97a30016, 0x8fc4fff4, 0x00431021, 0x0082202a, 0x148000b0,
-       0x00000000, 0x97d50818, 0x32a2ffff, 0x104000a3, 0x00009021, 0x0040a021,
-       0x00008821, 0x0e000625, 0x00000000, 0x00403021, 0x14c00007, 0x00000000,
-       0x3c020800, 0x8c4223dc, 0x24420001, 0x3c010800, 0x0a000596, 0xac2223dc,
-       0x3c100800, 0x02118021, 0x8e101bc8, 0x9608000a, 0x31020040, 0x10400005,
-       0x2407180c, 0x8e02000c, 0x2407188c, 0x00021400, 0xacc20018, 0x31020080,
-       0x54400001, 0x34e70010, 0x3c020800, 0x00511021, 0x8c421bd0, 0x3c030800,
-       0x00711821, 0x8c631bd4, 0x00021500, 0x00031c00, 0x00431025, 0xacc20014,
-       0x96040008, 0x3242ffff, 0x00821021, 0x0282102a, 0x14400002, 0x02b22823,
-       0x00802821, 0x8e020000, 0x02459021, 0xacc20000, 0x8e020004, 0x00c02021,
-       0x26310010, 0xac820004, 0x30e2ffff, 0xac800008, 0xa485000e, 0xac820010,
-       0x24020305, 0x0e0005a2, 0xa482000c, 0x3242ffff, 0x0054102b, 0x1440ffc5,
-       0x3242ffff, 0x0a00058e, 0x00000000, 0x8e620000, 0x8e63fffc, 0x0043102a,
-       0x10400067, 0x00000000, 0x8e62fff0, 0x00028900, 0x3c100800, 0x02118021,
-       0x0e000625, 0x8e101bc8, 0x00403021, 0x14c00005, 0x00000000, 0x8e62082c,
-       0x24420001, 0x0a000596, 0xae62082c, 0x9608000a, 0x31020040, 0x10400005,
-       0x2407180c, 0x8e02000c, 0x2407188c, 0x00021400, 0xacc20018, 0x3c020800,
-       0x00511021, 0x8c421bd0, 0x3c030800, 0x00711821, 0x8c631bd4, 0x00021500,
-       0x00031c00, 0x00431025, 0xacc20014, 0x8e63fff4, 0x96020008, 0x00432023,
-       0x3242ffff, 0x3083ffff, 0x00431021, 0x02c2102a, 0x10400003, 0x00802821,
-       0x97a9001e, 0x01322823, 0x8e620000, 0x30a4ffff, 0x00441021, 0xae620000,
-       0xa4c5000e, 0x8e020000, 0xacc20000, 0x8e020004, 0x8e63fff4, 0x00431021,
-       0xacc20004, 0x8e63fff4, 0x96020008, 0x00641821, 0x0062102a, 0x14400006,
-       0x02459021, 0x8e62fff0, 0xae60fff4, 0x24420001, 0x0a000571, 0xae62fff0,
-       0xae63fff4, 0xacc00008, 0x3242ffff, 0x10560003, 0x31020004, 0x10400006,
-       0x24020305, 0x31020080, 0x54400001, 0x34e70010, 0x34e70020, 0x24020905,
-       0xa4c2000c, 0x8ee30000, 0x8ee20004, 0x14620007, 0x3c02b49a, 0x8ee20860,
-       0x54400001, 0x34e70400, 0x3c024b65, 0x0a000588, 0x34427654, 0x344289ab,
-       0xacc2001c, 0x30e2ffff, 0xacc20010, 0x0e0005a2, 0x00c02021, 0x3242ffff,
-       0x0056102b, 0x1440ff9b, 0x00000000, 0x8e620000, 0x8e63fffc, 0x0043102a,
-       0x1440ff48, 0x00000000, 0x8fbf0044, 0x8fbe0040, 0x8fb7003c, 0x8fb60038,
-       0x8fb50034, 0x8fb40030, 0x8fb3002c, 0x8fb20028, 0x8fb10024, 0x8fb00020,
-       0x03e00008, 0x27bd0048, 0x27bdffe8, 0xafbf0014, 0xafb00010, 0x8f624450,
-       0x8f634410, 0x0a0005b1, 0x00808021, 0x8f626820, 0x30422000, 0x10400003,
-       0x00000000, 0x0e0001f0, 0x00002021, 0x8f624450, 0x8f634410, 0x3042ffff,
-       0x0043102b, 0x1440fff5, 0x00000000, 0x8f630c14, 0x3063000f, 0x2c620002,
-       0x1440000b, 0x00000000, 0x8f630c14, 0x3c020800, 0x8c421b40, 0x3063000f,
-       0x24420001, 0x3c010800, 0xac221b40, 0x2c620002, 0x1040fff7, 0x00000000,
-       0xaf705c18, 0x8f625c10, 0x30420002, 0x10400009, 0x00000000, 0x8f626820,
-       0x30422000, 0x1040fff8, 0x00000000, 0x0e0001f0, 0x00002021, 0x0a0005c4,
-       0x00000000, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x00000000,
-       0x00000000, 0x00000000, 0x27bdffe8, 0x3c1bc000, 0xafbf0014, 0xafb00010,
-       0xaf60680c, 0x8f626804, 0x34420082, 0xaf626804, 0x8f634000, 0x24020b50,
-       0x3c010800, 0xac221b54, 0x24020b78, 0x3c010800, 0xac221b64, 0x34630002,
-       0xaf634000, 0x0e000605, 0x00808021, 0x3c010800, 0xa0221b68, 0x304200ff,
-       0x24030002, 0x14430005, 0x00000000, 0x3c020800, 0x8c421b54, 0x0a0005f8,
-       0xac5000c0, 0x3c020800, 0x8c421b54, 0xac5000bc, 0x8f624434, 0x8f634438,
-       0x8f644410, 0x3c010800, 0xac221b5c, 0x3c010800, 0xac231b6c, 0x3c010800,
-       0xac241b58, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c040800,
-       0x8c870000, 0x3c03aa55, 0x3463aa55, 0x3c06c003, 0xac830000, 0x8cc20000,
-       0x14430007, 0x24050002, 0x3c0355aa, 0x346355aa, 0xac830000, 0x8cc20000,
-       0x50430001, 0x24050001, 0x3c020800, 0xac470000, 0x03e00008, 0x00a01021,
-       0x27bdfff8, 0x18800009, 0x00002821, 0x8f63680c, 0x8f62680c, 0x1043fffe,
-       0x00000000, 0x24a50001, 0x00a4102a, 0x1440fff9, 0x00000000, 0x03e00008,
-       0x27bd0008, 0x8f634450, 0x3c020800, 0x8c421b5c, 0x00031c02, 0x0043102b,
-       0x14400008, 0x3c038000, 0x3c040800, 0x8c841b6c, 0x8f624450, 0x00021c02,
-       0x0083102b, 0x1040fffc, 0x3c038000, 0xaf634444, 0x8f624444, 0x00431024,
-       0x1440fffd, 0x00000000, 0x8f624448, 0x03e00008, 0x3042ffff, 0x3082ffff,
-       0x2442e000, 0x2c422001, 0x14400003, 0x3c024000, 0x0a000648, 0x2402ffff,
-       0x00822025, 0xaf645c38, 0x8f625c30, 0x30420002, 0x1440fffc, 0x00001021,
-       0x03e00008, 0x00000000, 0x8f624450, 0x3c030800, 0x8c631b58, 0x0a000651,
-       0x3042ffff, 0x8f624450, 0x3042ffff, 0x0043102b, 0x1440fffc, 0x00000000,
-       0x03e00008, 0x00000000, 0x27bdffe0, 0x00802821, 0x3c040800, 0x24841af0,
-       0x00003021, 0x00003821, 0xafbf0018, 0xafa00010, 0x0e00067c, 0xafa00014,
-       0x0a000660, 0x00000000, 0x8fbf0018, 0x03e00008, 0x27bd0020, 0x00000000,
-       0x00000000, 0x00000000, 0x3c020800, 0x34423000, 0x3c030800, 0x34633000,
-       0x3c040800, 0x348437ff, 0x3c010800, 0xac221b74, 0x24020040, 0x3c010800,
-       0xac221b78, 0x3c010800, 0xac201b70, 0xac600000, 0x24630004, 0x0083102b,
-       0x5040fffd, 0xac600000, 0x03e00008, 0x00000000, 0x00804821, 0x8faa0010,
-       0x3c020800, 0x8c421b70, 0x3c040800, 0x8c841b78, 0x8fab0014, 0x24430001,
-       0x0044102b, 0x3c010800, 0xac231b70, 0x14400003, 0x00004021, 0x3c010800,
-       0xac201b70, 0x3c020800, 0x8c421b70, 0x3c030800, 0x8c631b74, 0x91240000,
-       0x00021140, 0x00431021, 0x00481021, 0x25080001, 0xa0440000, 0x29020008,
-       0x1440fff4, 0x25290001, 0x3c020800, 0x8c421b70, 0x3c030800, 0x8c631b74,
-       0x8f64680c, 0x00021140, 0x00431021, 0xac440008, 0xac45000c, 0xac460010,
-       0xac470014, 0xac4a0018, 0x03e00008, 0xac4b001c, 0x00000000, 0x00000000,
-};
-
-static const u32 tg3TsoFwRodata[] = {
-       0x4d61696e, 0x43707542, 0x00000000, 0x4d61696e, 0x43707541, 0x00000000,
-       0x00000000, 0x00000000, 0x73746b6f, 0x66666c64, 0x496e0000, 0x73746b6f,
-       0x66662a2a, 0x00000000, 0x53774576, 0x656e7430, 0x00000000, 0x00000000,
-       0x00000000, 0x00000000, 0x66617461, 0x6c457272, 0x00000000, 0x00000000,
-       0x00000000,
-};
-
-static const u32 tg3TsoFwData[] = {
-       0x00000000, 0x73746b6f, 0x66666c64, 0x5f76312e, 0x362e3000, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000,
-};
-
 /* 5705 needs a special version of the TSO firmware.  */
-#define TG3_TSO5_FW_RELEASE_MAJOR      0x1
-#define TG3_TSO5_FW_RELASE_MINOR       0x2
-#define TG3_TSO5_FW_RELEASE_FIX                0x0
-#define TG3_TSO5_FW_START_ADDR         0x00010000
-#define TG3_TSO5_FW_TEXT_ADDR          0x00010000
-#define TG3_TSO5_FW_TEXT_LEN           0xe90
-#define TG3_TSO5_FW_RODATA_ADDR                0x00010e90
-#define TG3_TSO5_FW_RODATA_LEN         0x50
-#define TG3_TSO5_FW_DATA_ADDR          0x00010f00
-#define TG3_TSO5_FW_DATA_LEN           0x20
-#define TG3_TSO5_FW_SBSS_ADDR          0x00010f20
-#define TG3_TSO5_FW_SBSS_LEN           0x28
-#define TG3_TSO5_FW_BSS_ADDR           0x00010f50
-#define TG3_TSO5_FW_BSS_LEN            0x88
-
-static const u32 tg3Tso5FwText[(TG3_TSO5_FW_TEXT_LEN / 4) + 1] = {
-       0x0c004003, 0x00000000, 0x00010f04, 0x00000000, 0x10000003, 0x00000000,
-       0x0000000d, 0x0000000d, 0x3c1d0001, 0x37bde000, 0x03a0f021, 0x3c100001,
-       0x26100000, 0x0c004010, 0x00000000, 0x0000000d, 0x27bdffe0, 0x3c04fefe,
-       0xafbf0018, 0x0c0042e8, 0x34840002, 0x0c004364, 0x00000000, 0x3c030001,
-       0x90630f34, 0x24020002, 0x3c040001, 0x24840e9c, 0x14620003, 0x24050001,
-       0x3c040001, 0x24840e90, 0x24060002, 0x00003821, 0xafa00010, 0x0c004378,
-       0xafa00014, 0x0c00402c, 0x00000000, 0x8fbf0018, 0x03e00008, 0x27bd0020,
-       0x00000000, 0x00000000, 0x27bdffe0, 0xafbf001c, 0xafb20018, 0xafb10014,
-       0x0c0042d4, 0xafb00010, 0x3c128000, 0x24110001, 0x8f706810, 0x32020400,
-       0x10400007, 0x00000000, 0x8f641008, 0x00921024, 0x14400003, 0x00000000,
-       0x0c004064, 0x00000000, 0x3c020001, 0x90420f56, 0x10510003, 0x32020200,
-       0x1040fff1, 0x00000000, 0x0c0041b4, 0x00000000, 0x08004034, 0x00000000,
-       0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020,
-       0x27bdffe0, 0x3c040001, 0x24840eb0, 0x00002821, 0x00003021, 0x00003821,
-       0xafbf0018, 0xafa00010, 0x0c004378, 0xafa00014, 0x0000d021, 0x24020130,
-       0xaf625000, 0x3c010001, 0xa4200f50, 0x3c010001, 0xa0200f57, 0x8fbf0018,
-       0x03e00008, 0x27bd0020, 0x00000000, 0x00000000, 0x3c030001, 0x24630f60,
-       0x90620000, 0x27bdfff0, 0x14400003, 0x0080c021, 0x08004073, 0x00004821,
-       0x3c022000, 0x03021024, 0x10400003, 0x24090002, 0x08004073, 0xa0600000,
-       0x24090001, 0x00181040, 0x30431f80, 0x346f8008, 0x1520004b, 0x25eb0028,
-       0x3c040001, 0x00832021, 0x8c848010, 0x3c050001, 0x24a50f7a, 0x00041402,
-       0xa0a20000, 0x3c010001, 0xa0240f7b, 0x3c020001, 0x00431021, 0x94428014,
-       0x3c010001, 0xa0220f7c, 0x3c0c0001, 0x01836021, 0x8d8c8018, 0x304200ff,
-       0x24420008, 0x000220c3, 0x24020001, 0x3c010001, 0xa0220f60, 0x0124102b,
-       0x1040000c, 0x00003821, 0x24a6000e, 0x01602821, 0x8ca20000, 0x8ca30004,
-       0x24a50008, 0x24e70001, 0xacc20000, 0xacc30004, 0x00e4102b, 0x1440fff8,
-       0x24c60008, 0x00003821, 0x3c080001, 0x25080f7b, 0x91060000, 0x3c020001,
-       0x90420f7c, 0x2503000d, 0x00c32821, 0x00461023, 0x00021fc2, 0x00431021,
-       0x00021043, 0x1840000c, 0x00002021, 0x91020001, 0x00461023, 0x00021fc2,
-       0x00431021, 0x00021843, 0x94a20000, 0x24e70001, 0x00822021, 0x00e3102a,
-       0x1440fffb, 0x24a50002, 0x00041c02, 0x3082ffff, 0x00622021, 0x00041402,
-       0x00822021, 0x3c02ffff, 0x01821024, 0x3083ffff, 0x00431025, 0x3c010001,
-       0x080040fa, 0xac220f80, 0x3c050001, 0x24a50f7c, 0x90a20000, 0x3c0c0001,
-       0x01836021, 0x8d8c8018, 0x000220c2, 0x1080000e, 0x00003821, 0x01603021,
-       0x24a5000c, 0x8ca20000, 0x8ca30004, 0x24a50008, 0x24e70001, 0xacc20000,
-       0xacc30004, 0x00e4102b, 0x1440fff8, 0x24c60008, 0x3c050001, 0x24a50f7c,
-       0x90a20000, 0x30430007, 0x24020004, 0x10620011, 0x28620005, 0x10400005,
-       0x24020002, 0x10620008, 0x000710c0, 0x080040fa, 0x00000000, 0x24020006,
-       0x1062000e, 0x000710c0, 0x080040fa, 0x00000000, 0x00a21821, 0x9463000c,
-       0x004b1021, 0x080040fa, 0xa4430000, 0x000710c0, 0x00a21821, 0x8c63000c,
-       0x004b1021, 0x080040fa, 0xac430000, 0x00a21821, 0x8c63000c, 0x004b2021,
-       0x00a21021, 0xac830000, 0x94420010, 0xa4820004, 0x95e70006, 0x3c020001,
-       0x90420f7c, 0x3c030001, 0x90630f7a, 0x00e2c823, 0x3c020001, 0x90420f7b,
-       0x24630028, 0x01e34021, 0x24420028, 0x15200012, 0x01e23021, 0x94c2000c,
-       0x3c010001, 0xa4220f78, 0x94c20004, 0x94c30006, 0x3c010001, 0xa4200f76,
-       0x3c010001, 0xa4200f72, 0x00021400, 0x00431025, 0x3c010001, 0xac220f6c,
-       0x95020004, 0x3c010001, 0x08004124, 0xa4220f70, 0x3c020001, 0x94420f70,
-       0x3c030001, 0x94630f72, 0x00431021, 0xa5020004, 0x3c020001, 0x94420f6c,
-       0xa4c20004, 0x3c020001, 0x8c420f6c, 0xa4c20006, 0x3c040001, 0x94840f72,
-       0x3c020001, 0x94420f70, 0x3c0a0001, 0x954a0f76, 0x00441821, 0x3063ffff,
-       0x0062182a, 0x24020002, 0x1122000b, 0x00832023, 0x3c030001, 0x94630f78,
-       0x30620009, 0x10400006, 0x3062fff6, 0xa4c2000c, 0x3c020001, 0x94420f78,
-       0x30420009, 0x01425023, 0x24020001, 0x1122001b, 0x29220002, 0x50400005,
-       0x24020002, 0x11200007, 0x31a2ffff, 0x08004197, 0x00000000, 0x1122001d,
-       0x24020016, 0x08004197, 0x31a2ffff, 0x3c0e0001, 0x95ce0f80, 0x10800005,
-       0x01806821, 0x01c42021, 0x00041c02, 0x3082ffff, 0x00627021, 0x000e1027,
-       0xa502000a, 0x3c030001, 0x90630f7b, 0x31a2ffff, 0x00e21021, 0x0800418d,
-       0x00432023, 0x3c020001, 0x94420f80, 0x00442021, 0x00041c02, 0x3082ffff,
-       0x00622021, 0x00807021, 0x00041027, 0x08004185, 0xa502000a, 0x3c050001,
-       0x24a50f7a, 0x90a30000, 0x14620002, 0x24e2fff2, 0xa5e20034, 0x90a20000,
-       0x00e21023, 0xa5020002, 0x3c030001, 0x94630f80, 0x3c020001, 0x94420f5a,
-       0x30e5ffff, 0x00641821, 0x00451023, 0x00622023, 0x00041c02, 0x3082ffff,
-       0x00622021, 0x00041027, 0xa502000a, 0x3c030001, 0x90630f7c, 0x24620001,
-       0x14a20005, 0x00807021, 0x01631021, 0x90420000, 0x08004185, 0x00026200,
-       0x24620002, 0x14a20003, 0x306200fe, 0x004b1021, 0x944c0000, 0x3c020001,
-       0x94420f82, 0x3183ffff, 0x3c040001, 0x90840f7b, 0x00431021, 0x00e21021,
-       0x00442023, 0x008a2021, 0x00041c02, 0x3082ffff, 0x00622021, 0x00041402,
-       0x00822021, 0x00806821, 0x00041027, 0xa4c20010, 0x31a2ffff, 0x000e1c00,
-       0x00431025, 0x3c040001, 0x24840f72, 0xade20010, 0x94820000, 0x3c050001,
-       0x94a50f76, 0x3c030001, 0x8c630f6c, 0x24420001, 0x00b92821, 0xa4820000,
-       0x3322ffff, 0x00622021, 0x0083182b, 0x3c010001, 0xa4250f76, 0x10600003,
-       0x24a2ffff, 0x3c010001, 0xa4220f76, 0x3c024000, 0x03021025, 0x3c010001,
-       0xac240f6c, 0xaf621008, 0x03e00008, 0x27bd0010, 0x3c030001, 0x90630f56,
-       0x27bdffe8, 0x24020001, 0xafbf0014, 0x10620026, 0xafb00010, 0x8f620cf4,
-       0x2442ffff, 0x3042007f, 0x00021100, 0x8c434000, 0x3c010001, 0xac230f64,
-       0x8c434008, 0x24444000, 0x8c5c4004, 0x30620040, 0x14400002, 0x24020088,
-       0x24020008, 0x3c010001, 0xa4220f68, 0x30620004, 0x10400005, 0x24020001,
-       0x3c010001, 0xa0220f57, 0x080041d5, 0x00031402, 0x3c010001, 0xa0200f57,
-       0x00031402, 0x3c010001, 0xa4220f54, 0x9483000c, 0x24020001, 0x3c010001,
-       0xa4200f50, 0x3c010001, 0xa0220f56, 0x3c010001, 0xa4230f62, 0x24020001,
-       0x1342001e, 0x00000000, 0x13400005, 0x24020003, 0x13420067, 0x00000000,
-       0x080042cf, 0x00000000, 0x3c020001, 0x94420f62, 0x241a0001, 0x3c010001,
-       0xa4200f5e, 0x3c010001, 0xa4200f52, 0x304407ff, 0x00021bc2, 0x00031823,
-       0x3063003e, 0x34630036, 0x00021242, 0x3042003c, 0x00621821, 0x3c010001,
-       0xa4240f58, 0x00832021, 0x24630030, 0x3c010001, 0xa4240f5a, 0x3c010001,
-       0xa4230f5c, 0x3c060001, 0x24c60f52, 0x94c50000, 0x94c30002, 0x3c040001,
-       0x94840f5a, 0x00651021, 0x0044102a, 0x10400013, 0x3c108000, 0x00a31021,
-       0xa4c20000, 0x3c02a000, 0xaf620cf4, 0x3c010001, 0xa0200f56, 0x8f641008,
-       0x00901024, 0x14400003, 0x00000000, 0x0c004064, 0x00000000, 0x8f620cf4,
-       0x00501024, 0x104000b7, 0x00000000, 0x0800420f, 0x00000000, 0x3c030001,
-       0x94630f50, 0x00851023, 0xa4c40000, 0x00621821, 0x3042ffff, 0x3c010001,
-       0xa4230f50, 0xaf620ce8, 0x3c020001, 0x94420f68, 0x34420024, 0xaf620cec,
-       0x94c30002, 0x3c020001, 0x94420f50, 0x14620012, 0x3c028000, 0x3c108000,
-       0x3c02a000, 0xaf620cf4, 0x3c010001, 0xa0200f56, 0x8f641008, 0x00901024,
-       0x14400003, 0x00000000, 0x0c004064, 0x00000000, 0x8f620cf4, 0x00501024,
-       0x1440fff7, 0x00000000, 0x080042cf, 0x241a0003, 0xaf620cf4, 0x3c108000,
-       0x8f641008, 0x00901024, 0x14400003, 0x00000000, 0x0c004064, 0x00000000,
-       0x8f620cf4, 0x00501024, 0x1440fff7, 0x00000000, 0x080042cf, 0x241a0003,
-       0x3c070001, 0x24e70f50, 0x94e20000, 0x03821021, 0xaf620ce0, 0x3c020001,
-       0x8c420f64, 0xaf620ce4, 0x3c050001, 0x94a50f54, 0x94e30000, 0x3c040001,
-       0x94840f58, 0x3c020001, 0x94420f5e, 0x00a32823, 0x00822023, 0x30a6ffff,
-       0x3083ffff, 0x00c3102b, 0x14400043, 0x00000000, 0x3c020001, 0x94420f5c,
-       0x00021400, 0x00621025, 0xaf620ce8, 0x94e20000, 0x3c030001, 0x94630f54,
-       0x00441021, 0xa4e20000, 0x3042ffff, 0x14430021, 0x3c020008, 0x3c020001,
-       0x90420f57, 0x10400006, 0x3c03000c, 0x3c020001, 0x94420f68, 0x34630624,
-       0x0800427c, 0x0000d021, 0x3c020001, 0x94420f68, 0x3c030008, 0x34630624,
-       0x00431025, 0xaf620cec, 0x3c108000, 0x3c02a000, 0xaf620cf4, 0x3c010001,
-       0xa0200f56, 0x8f641008, 0x00901024, 0x14400003, 0x00000000, 0x0c004064,
-       0x00000000, 0x8f620cf4, 0x00501024, 0x10400015, 0x00000000, 0x08004283,
-       0x00000000, 0x3c030001, 0x94630f68, 0x34420624, 0x3c108000, 0x00621825,
-       0x3c028000, 0xaf630cec, 0xaf620cf4, 0x8f641008, 0x00901024, 0x14400003,
-       0x00000000, 0x0c004064, 0x00000000, 0x8f620cf4, 0x00501024, 0x1440fff7,
-       0x00000000, 0x3c010001, 0x080042cf, 0xa4200f5e, 0x3c020001, 0x94420f5c,
-       0x00021400, 0x00c21025, 0xaf620ce8, 0x3c020001, 0x90420f57, 0x10400009,
-       0x3c03000c, 0x3c020001, 0x94420f68, 0x34630624, 0x0000d021, 0x00431025,
-       0xaf620cec, 0x080042c1, 0x3c108000, 0x3c020001, 0x94420f68, 0x3c030008,
-       0x34630604, 0x00431025, 0xaf620cec, 0x3c020001, 0x94420f5e, 0x00451021,
-       0x3c010001, 0xa4220f5e, 0x3c108000, 0x3c02a000, 0xaf620cf4, 0x3c010001,
-       0xa0200f56, 0x8f641008, 0x00901024, 0x14400003, 0x00000000, 0x0c004064,
-       0x00000000, 0x8f620cf4, 0x00501024, 0x1440fff7, 0x00000000, 0x8fbf0014,
-       0x8fb00010, 0x03e00008, 0x27bd0018, 0x00000000, 0x27bdffe0, 0x3c040001,
-       0x24840ec0, 0x00002821, 0x00003021, 0x00003821, 0xafbf0018, 0xafa00010,
-       0x0c004378, 0xafa00014, 0x0000d021, 0x24020130, 0xaf625000, 0x3c010001,
-       0xa4200f50, 0x3c010001, 0xa0200f57, 0x8fbf0018, 0x03e00008, 0x27bd0020,
-       0x27bdffe8, 0x3c1bc000, 0xafbf0014, 0xafb00010, 0xaf60680c, 0x8f626804,
-       0x34420082, 0xaf626804, 0x8f634000, 0x24020b50, 0x3c010001, 0xac220f20,
-       0x24020b78, 0x3c010001, 0xac220f30, 0x34630002, 0xaf634000, 0x0c004315,
-       0x00808021, 0x3c010001, 0xa0220f34, 0x304200ff, 0x24030002, 0x14430005,
-       0x00000000, 0x3c020001, 0x8c420f20, 0x08004308, 0xac5000c0, 0x3c020001,
-       0x8c420f20, 0xac5000bc, 0x8f624434, 0x8f634438, 0x8f644410, 0x3c010001,
-       0xac220f28, 0x3c010001, 0xac230f38, 0x3c010001, 0xac240f24, 0x8fbf0014,
-       0x8fb00010, 0x03e00008, 0x27bd0018, 0x03e00008, 0x24020001, 0x27bdfff8,
-       0x18800009, 0x00002821, 0x8f63680c, 0x8f62680c, 0x1043fffe, 0x00000000,
-       0x24a50001, 0x00a4102a, 0x1440fff9, 0x00000000, 0x03e00008, 0x27bd0008,
-       0x8f634450, 0x3c020001, 0x8c420f28, 0x00031c02, 0x0043102b, 0x14400008,
-       0x3c038000, 0x3c040001, 0x8c840f38, 0x8f624450, 0x00021c02, 0x0083102b,
-       0x1040fffc, 0x3c038000, 0xaf634444, 0x8f624444, 0x00431024, 0x1440fffd,
-       0x00000000, 0x8f624448, 0x03e00008, 0x3042ffff, 0x3082ffff, 0x2442e000,
-       0x2c422001, 0x14400003, 0x3c024000, 0x08004347, 0x2402ffff, 0x00822025,
-       0xaf645c38, 0x8f625c30, 0x30420002, 0x1440fffc, 0x00001021, 0x03e00008,
-       0x00000000, 0x8f624450, 0x3c030001, 0x8c630f24, 0x08004350, 0x3042ffff,
-       0x8f624450, 0x3042ffff, 0x0043102b, 0x1440fffc, 0x00000000, 0x03e00008,
-       0x00000000, 0x27bdffe0, 0x00802821, 0x3c040001, 0x24840ed0, 0x00003021,
-       0x00003821, 0xafbf0018, 0xafa00010, 0x0c004378, 0xafa00014, 0x0800435f,
-       0x00000000, 0x8fbf0018, 0x03e00008, 0x27bd0020, 0x3c020001, 0x3442d600,
-       0x3c030001, 0x3463d600, 0x3c040001, 0x3484ddff, 0x3c010001, 0xac220f40,
-       0x24020040, 0x3c010001, 0xac220f44, 0x3c010001, 0xac200f3c, 0xac600000,
-       0x24630004, 0x0083102b, 0x5040fffd, 0xac600000, 0x03e00008, 0x00000000,
-       0x00804821, 0x8faa0010, 0x3c020001, 0x8c420f3c, 0x3c040001, 0x8c840f44,
-       0x8fab0014, 0x24430001, 0x0044102b, 0x3c010001, 0xac230f3c, 0x14400003,
-       0x00004021, 0x3c010001, 0xac200f3c, 0x3c020001, 0x8c420f3c, 0x3c030001,
-       0x8c630f40, 0x91240000, 0x00021140, 0x00431021, 0x00481021, 0x25080001,
-       0xa0440000, 0x29020008, 0x1440fff4, 0x25290001, 0x3c020001, 0x8c420f3c,
-       0x3c030001, 0x8c630f40, 0x8f64680c, 0x00021140, 0x00431021, 0xac440008,
-       0xac45000c, 0xac460010, 0xac470014, 0xac4a0018, 0x03e00008, 0xac4b001c,
-       0x00000000, 0x00000000, 0x00000000,
-};
-
-static const u32 tg3Tso5FwRodata[(TG3_TSO5_FW_RODATA_LEN / 4) + 1] = {
-       0x4d61696e, 0x43707542, 0x00000000, 0x4d61696e, 0x43707541, 0x00000000,
-       0x00000000, 0x00000000, 0x73746b6f, 0x66666c64, 0x00000000, 0x00000000,
-       0x73746b6f, 0x66666c64, 0x00000000, 0x00000000, 0x66617461, 0x6c457272,
-       0x00000000, 0x00000000, 0x00000000,
-};
-
-static const u32 tg3Tso5FwData[(TG3_TSO5_FW_DATA_LEN / 4) + 1] = {
-       0x00000000, 0x73746b6f, 0x66666c64, 0x5f76312e, 0x322e3000, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000,
-};
 
 /* tp->lock is held. */
 static int tg3_load_tso_firmware(struct tg3 *tp)
 {
        struct fw_info info;
+       const __be32 *fw_data;
        unsigned long cpu_base, cpu_scratch_base, cpu_scratch_size;
        int err, i;
 
        if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
                return 0;
 
+       fw_data = (void *)tp->fw->data;
+
+       /* Firmware blob starts with version numbers, followed by
+          start address and length. We are setting complete length.
+          length = end_address_of_bss - start_address_of_text.
+          Remainder is the blob to be loaded contiguously
+          from start address. */
+
+       info.fw_base = be32_to_cpu(fw_data[1]);
+       cpu_scratch_size = tp->fw_len;
+       info.fw_len = tp->fw->size - 12;
+       info.fw_data = &fw_data[3];
+
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
-               info.text_base = TG3_TSO5_FW_TEXT_ADDR;
-               info.text_len = TG3_TSO5_FW_TEXT_LEN;
-               info.text_data = &tg3Tso5FwText[0];
-               info.rodata_base = TG3_TSO5_FW_RODATA_ADDR;
-               info.rodata_len = TG3_TSO5_FW_RODATA_LEN;
-               info.rodata_data = &tg3Tso5FwRodata[0];
-               info.data_base = TG3_TSO5_FW_DATA_ADDR;
-               info.data_len = TG3_TSO5_FW_DATA_LEN;
-               info.data_data = &tg3Tso5FwData[0];
                cpu_base = RX_CPU_BASE;
                cpu_scratch_base = NIC_SRAM_MBUF_POOL_BASE5705;
-               cpu_scratch_size = (info.text_len +
-                                   info.rodata_len +
-                                   info.data_len +
-                                   TG3_TSO5_FW_SBSS_LEN +
-                                   TG3_TSO5_FW_BSS_LEN);
        } else {
-               info.text_base = TG3_TSO_FW_TEXT_ADDR;
-               info.text_len = TG3_TSO_FW_TEXT_LEN;
-               info.text_data = &tg3TsoFwText[0];
-               info.rodata_base = TG3_TSO_FW_RODATA_ADDR;
-               info.rodata_len = TG3_TSO_FW_RODATA_LEN;
-               info.rodata_data = &tg3TsoFwRodata[0];
-               info.data_base = TG3_TSO_FW_DATA_ADDR;
-               info.data_len = TG3_TSO_FW_DATA_LEN;
-               info.data_data = &tg3TsoFwData[0];
                cpu_base = TX_CPU_BASE;
                cpu_scratch_base = TX_CPU_SCRATCH_BASE;
                cpu_scratch_size = TX_CPU_SCRATCH_SIZE;
@@ -6860,21 +6566,21 @@ static int tg3_load_tso_firmware(struct tg3 *tp)
 
        /* Now startup the cpu. */
        tw32(cpu_base + CPU_STATE, 0xffffffff);
-       tw32_f(cpu_base + CPU_PC,    info.text_base);
+       tw32_f(cpu_base + CPU_PC, info.fw_base);
 
        for (i = 0; i < 5; i++) {
-               if (tr32(cpu_base + CPU_PC) == info.text_base)
+               if (tr32(cpu_base + CPU_PC) == info.fw_base)
                        break;
                tw32(cpu_base + CPU_STATE, 0xffffffff);
                tw32(cpu_base + CPU_MODE,  CPU_MODE_HALT);
-               tw32_f(cpu_base + CPU_PC,    info.text_base);
+               tw32_f(cpu_base + CPU_PC, info.fw_base);
                udelay(1000);
        }
        if (i >= 5) {
                printk(KERN_ERR PFX "tg3_load_tso_firmware fails for %s "
                       "to set CPU PC, is %08x should be %08x\n",
                       tp->dev->name, tr32(cpu_base + CPU_PC),
-                      info.text_base);
+                      info.fw_base);
                return -ENODEV;
        }
        tw32(cpu_base + CPU_STATE, 0xffffffff);
@@ -6883,43 +6589,6 @@ static int tg3_load_tso_firmware(struct tg3 *tp)
 }
 
 
-/* tp->lock is held. */
-static void __tg3_set_mac_addr(struct tg3 *tp, int skip_mac_1)
-{
-       u32 addr_high, addr_low;
-       int i;
-
-       addr_high = ((tp->dev->dev_addr[0] << 8) |
-                    tp->dev->dev_addr[1]);
-       addr_low = ((tp->dev->dev_addr[2] << 24) |
-                   (tp->dev->dev_addr[3] << 16) |
-                   (tp->dev->dev_addr[4] <<  8) |
-                   (tp->dev->dev_addr[5] <<  0));
-       for (i = 0; i < 4; i++) {
-               if (i == 1 && skip_mac_1)
-                       continue;
-               tw32(MAC_ADDR_0_HIGH + (i * 8), addr_high);
-               tw32(MAC_ADDR_0_LOW + (i * 8), addr_low);
-       }
-
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
-               for (i = 0; i < 12; i++) {
-                       tw32(MAC_EXTADDR_0_HIGH + (i * 8), addr_high);
-                       tw32(MAC_EXTADDR_0_LOW + (i * 8), addr_low);
-               }
-       }
-
-       addr_high = (tp->dev->dev_addr[0] +
-                    tp->dev->dev_addr[1] +
-                    tp->dev->dev_addr[2] +
-                    tp->dev->dev_addr[3] +
-                    tp->dev->dev_addr[4] +
-                    tp->dev->dev_addr[5]) &
-               TX_BACKOFF_SEED_MASK;
-       tw32(MAC_TX_BACKOFF_SEED, addr_high);
-}
-
 static int tg3_set_mac_addr(struct net_device *dev, void *p)
 {
        struct tg3 *tp = netdev_priv(dev);
@@ -7024,8 +6693,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 
        tg3_write_sig_legacy(tp, RESET_KIND_INIT);
 
-       if (tp->pci_chip_rev_id == CHIPREV_ID_5784_A0 ||
-           tp->pci_chip_rev_id == CHIPREV_ID_5784_A1) {
+       if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5784_AX) {
                val = tr32(TG3_CPMU_CTRL);
                val &= ~(CPMU_CTRL_LINK_AWARE_MODE | CPMU_CTRL_LINK_IDLE_MODE);
                tw32(TG3_CPMU_CTRL, val);
@@ -7046,6 +6714,13 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                tw32(TG3_CPMU_HST_ACC, val);
        }
 
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) {
+               val = tr32(PCIE_PWR_MGMT_THRESH) & ~PCIE_PWR_MGMT_L1_THRESH_MSK;
+               val |= PCIE_PWR_MGMT_EXT_ASPM_TMR_EN |
+                      PCIE_PWR_MGMT_L1_THRESH_4MS;
+               tw32(PCIE_PWR_MGMT_THRESH, val);
+       }
+
        /* This works around an issue with Athlon chipsets on
         * B3 tigon3 silicon.  This bit has no effect on any
         * other revision.  But do not set this on PCI Express
@@ -7091,8 +6766,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                return err;
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5784 &&
-           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5761 &&
-           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785) {
+           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5761) {
                /* This value is determined during the probe time DMA
                 * engine test, tg3_test_dma.
                 */
@@ -7138,11 +6812,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        else if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) {
                int fw_len;
 
-               fw_len = (TG3_TSO5_FW_TEXT_LEN +
-                         TG3_TSO5_FW_RODATA_LEN +
-                         TG3_TSO5_FW_DATA_LEN +
-                         TG3_TSO5_FW_SBSS_LEN +
-                         TG3_TSO5_FW_BSS_LEN);
+               fw_len = tp->fw_len;
                fw_len = (fw_len + (0x80 - 1)) & ~(0x80 - 1);
                tw32(BUFMGR_MB_POOL_ADDR,
                     NIC_SRAM_MBUF_POOL_BASE5705 + fw_len);
@@ -7308,7 +6978,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        __tg3_set_mac_addr(tp, 0);
 
        /* MTU + ethernet header + FCS + optional VLAN tag */
-       tw32(MAC_RX_MTU_SIZE, tp->dev->mtu + ETH_HLEN + 8);
+       tw32(MAC_RX_MTU_SIZE,
+            tp->dev->mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN);
 
        /* The slot time is changed by tg3_setup_phy if we
         * run at gigabit with half duplex.
@@ -7332,7 +7003,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                      RDMAC_MODE_LNGREAD_ENAB);
 
        if (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_5785 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
                rdmac_mode |= RDMAC_MODE_BD_SBD_CRPT_ENAB |
                              RDMAC_MODE_MBUF_RBD_CRPT_ENAB |
                              RDMAC_MODE_MBUF_SBD_CRPT_ENAB;
@@ -7354,7 +7026,11 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                rdmac_mode |= RDMAC_MODE_FIFO_LONG_BURST;
 
        if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
-               rdmac_mode |= (1 << 27);
+               rdmac_mode |= RDMAC_MODE_IPV4_LSO_EN;
+
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
+               rdmac_mode |= RDMAC_MODE_IPV6_LSO_EN;
 
        /* Receive/send statistics. */
        if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) {
@@ -7472,7 +7148,6 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        udelay(100);
 
        tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0);
-       tp->last_tag = 0;
 
        if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
                tw32_f(DMAC_MODE, DMAC_MODE_ENABLE);
@@ -7501,11 +7176,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        }
 
        /* Enable host coalescing bug fix */
-       if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755) ||
-           (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) ||
-           (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784) ||
-           (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) ||
-           (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785))
+       if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
                val |= WDMAC_MODE_STATUS_TAG_FIX;
 
        tw32_f(WDMAC_MODE, val);
@@ -7566,10 +7237,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        udelay(100);
 
        tp->rx_mode = RX_MODE_ENABLE;
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
+       if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
                tp->rx_mode |= RX_MODE_IPV6_CSUM_ENABLE;
 
        tw32_f(MAC_RX_MODE, tp->rx_mode);
@@ -8011,15 +7679,46 @@ static int tg3_test_msi(struct tg3 *tp)
         */
        tg3_full_lock(tp, 1);
 
-       tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
-       err = tg3_init_hw(tp, 1);
+       tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
+       err = tg3_init_hw(tp, 1);
+
+       tg3_full_unlock(tp);
+
+       if (err)
+               free_irq(tp->pdev->irq, dev);
+
+       return err;
+}
+
+static int tg3_request_firmware(struct tg3 *tp)
+{
+       const __be32 *fw_data;
+
+       if (request_firmware(&tp->fw, tp->fw_needed, &tp->pdev->dev)) {
+               printk(KERN_ERR "%s: Failed to load firmware \"%s\"\n",
+                      tp->dev->name, tp->fw_needed);
+               return -ENOENT;
+       }
+
+       fw_data = (void *)tp->fw->data;
 
-       tg3_full_unlock(tp);
+       /* Firmware blob starts with version numbers, followed by
+        * start address and _full_ length including BSS sections
+        * (which must be longer than the actual data, of course
+        */
 
-       if (err)
-               free_irq(tp->pdev->irq, dev);
+       tp->fw_len = be32_to_cpu(fw_data[2]);   /* includes bss */
+       if (tp->fw_len < (tp->fw->size - 12)) {
+               printk(KERN_ERR "%s: bogus length %d in \"%s\"\n",
+                      tp->dev->name, tp->fw_len, tp->fw_needed);
+               release_firmware(tp->fw);
+               tp->fw = NULL;
+               return -EINVAL;
+       }
 
-       return err;
+       /* We no longer need firmware; we have it. */
+       tp->fw_needed = NULL;
+       return 0;
 }
 
 static int tg3_open(struct net_device *dev)
@@ -8027,6 +7726,22 @@ static int tg3_open(struct net_device *dev)
        struct tg3 *tp = netdev_priv(dev);
        int err;
 
+       if (tp->fw_needed) {
+               err = tg3_request_firmware(tp);
+               if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0) {
+                       if (err)
+                               return err;
+               } else if (err) {
+                       printk(KERN_WARNING "%s: TSO capability disabled.\n",
+                              tp->dev->name);
+                       tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE;
+               } else if (!(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE)) {
+                       printk(KERN_NOTICE "%s: TSO capability restored.\n",
+                              tp->dev->name);
+                       tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
+               }
+       }
+
        netif_carrier_off(tp->dev);
 
        err = tg3_set_power_state(tp, PCI_D0);
@@ -8825,17 +8540,16 @@ static int tg3_get_eeprom_len(struct net_device *dev)
        return tp->nvram_size;
 }
 
-static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val);
-static int tg3_nvram_read_le(struct tg3 *tp, u32 offset, __le32 *val);
-static int tg3_nvram_read_swab(struct tg3 *tp, u32 offset, u32 *val);
-
 static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data)
 {
        struct tg3 *tp = netdev_priv(dev);
        int ret;
        u8  *pd;
        u32 i, offset, len, b_offset, b_count;
-       __le32 val;
+       __be32 val;
+
+       if (tp->tg3_flags3 & TG3_FLG3_NO_NVRAM)
+               return -EINVAL;
 
        if (tp->link_config.phy_is_low_power)
                return -EAGAIN;
@@ -8854,7 +8568,7 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
                        /* i.e. offset=1 len=2 */
                        b_count = len;
                }
-               ret = tg3_nvram_read_le(tp, offset-b_offset, &val);
+               ret = tg3_nvram_read_be32(tp, offset-b_offset, &val);
                if (ret)
                        return ret;
                memcpy(data, ((char*)&val) + b_offset, b_count);
@@ -8866,7 +8580,7 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
        /* read bytes upto the last 4 byte boundary */
        pd = &data[eeprom->len];
        for (i = 0; i < (len - (len & 3)); i += 4) {
-               ret = tg3_nvram_read_le(tp, offset + i, &val);
+               ret = tg3_nvram_read_be32(tp, offset + i, &val);
                if (ret) {
                        eeprom->len += i;
                        return ret;
@@ -8880,7 +8594,7 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
                pd = &data[eeprom->len];
                b_count = len & 3;
                b_offset = offset + len - b_count;
-               ret = tg3_nvram_read_le(tp, b_offset, &val);
+               ret = tg3_nvram_read_be32(tp, b_offset, &val);
                if (ret)
                        return ret;
                memcpy(pd, &val, b_count);
@@ -8897,12 +8611,13 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
        int ret;
        u32 offset, len, b_offset, odd_len;
        u8 *buf;
-       __le32 start, end;
+       __be32 start, end;
 
        if (tp->link_config.phy_is_low_power)
                return -EAGAIN;
 
-       if (eeprom->magic != TG3_EEPROM_MAGIC)
+       if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) ||
+           eeprom->magic != TG3_EEPROM_MAGIC)
                return -EINVAL;
 
        offset = eeprom->offset;
@@ -8910,7 +8625,7 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
 
        if ((b_offset = (offset & 3))) {
                /* adjustments to start on required 4 byte boundary */
-               ret = tg3_nvram_read_le(tp, offset-b_offset, &start);
+               ret = tg3_nvram_read_be32(tp, offset-b_offset, &start);
                if (ret)
                        return ret;
                len += b_offset;
@@ -8924,7 +8639,7 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
                /* adjustments to end on required 4 byte boundary */
                odd_len = 1;
                len = (len + 3) & ~3;
-               ret = tg3_nvram_read_le(tp, offset+len-4, &end);
+               ret = tg3_nvram_read_be32(tp, offset+len-4, &end);
                if (ret)
                        return ret;
        }
@@ -8983,7 +8698,7 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                cmd->duplex = tp->link_config.active_duplex;
        }
        cmd->phy_address = PHY_ADDR;
-       cmd->transceiver = 0;
+       cmd->transceiver = XCVR_INTERNAL;
        cmd->autoneg = tp->link_config.autoneg;
        cmd->maxtxpkt = 0;
        cmd->maxrxpkt = 0;
@@ -9000,26 +8715,58 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                return phy_ethtool_sset(tp->mdio_bus->phy_map[PHY_ADDR], cmd);
        }
 
-       if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) {
-               /* These are the only valid advertisement bits allowed.  */
-               if (cmd->autoneg == AUTONEG_ENABLE &&
-                   (cmd->advertising & ~(ADVERTISED_1000baseT_Half |
-                                         ADVERTISED_1000baseT_Full |
-                                         ADVERTISED_Autoneg |
-                                         ADVERTISED_FIBRE)))
-                       return -EINVAL;
-               /* Fiber can only do SPEED_1000.  */
-               else if ((cmd->autoneg != AUTONEG_ENABLE) &&
-                        (cmd->speed != SPEED_1000))
-                       return -EINVAL;
-       /* Copper cannot force SPEED_1000.  */
-       } else if ((cmd->autoneg != AUTONEG_ENABLE) &&
-                  (cmd->speed == SPEED_1000))
+       if (cmd->autoneg != AUTONEG_ENABLE &&
+           cmd->autoneg != AUTONEG_DISABLE)
                return -EINVAL;
-       else if ((cmd->speed == SPEED_1000) &&
-                (tp->tg3_flags & TG3_FLAG_10_100_ONLY))
+
+       if (cmd->autoneg == AUTONEG_DISABLE &&
+           cmd->duplex != DUPLEX_FULL &&
+           cmd->duplex != DUPLEX_HALF)
                return -EINVAL;
 
+       if (cmd->autoneg == AUTONEG_ENABLE) {
+               u32 mask = ADVERTISED_Autoneg |
+                          ADVERTISED_Pause |
+                          ADVERTISED_Asym_Pause;
+
+               if (!(tp->tg3_flags2 & TG3_FLAG_10_100_ONLY))
+                       mask |= ADVERTISED_1000baseT_Half |
+                               ADVERTISED_1000baseT_Full;
+
+               if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES))
+                       mask |= ADVERTISED_100baseT_Half |
+                               ADVERTISED_100baseT_Full |
+                               ADVERTISED_10baseT_Half |
+                               ADVERTISED_10baseT_Full |
+                               ADVERTISED_TP;
+               else
+                       mask |= ADVERTISED_FIBRE;
+
+               if (cmd->advertising & ~mask)
+                       return -EINVAL;
+
+               mask &= (ADVERTISED_1000baseT_Half |
+                        ADVERTISED_1000baseT_Full |
+                        ADVERTISED_100baseT_Half |
+                        ADVERTISED_100baseT_Full |
+                        ADVERTISED_10baseT_Half |
+                        ADVERTISED_10baseT_Full);
+
+               cmd->advertising &= mask;
+       } else {
+               if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) {
+                       if (cmd->speed != SPEED_1000)
+                               return -EINVAL;
+
+                       if (cmd->duplex != DUPLEX_FULL)
+                               return -EINVAL;
+               } else {
+                       if (cmd->speed != SPEED_100 &&
+                           cmd->speed != SPEED_10)
+                               return -EINVAL;
+               }
+       }
+
        tg3_full_lock(tp, 0);
 
        tp->link_config.autoneg = cmd->autoneg;
@@ -9066,7 +8813,8 @@ static void tg3_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
        else
                wol->supported = 0;
        wol->wolopts = 0;
-       if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE)
+       if ((tp->tg3_flags & TG3_FLAG_WOL_ENABLE) &&
+           device_can_wakeup(&tp->pdev->dev))
                wol->wolopts = WAKE_MAGIC;
        memset(&wol->sopass, 0, sizeof(wol->sopass));
 }
@@ -9116,14 +8864,15 @@ static int tg3_set_tso(struct net_device *dev, u32 value)
                        return -EINVAL;
                return 0;
        }
-       if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) &&
-           (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906)) {
+       if ((dev->features & NETIF_F_IPV6_CSUM) &&
+           (tp->tg3_flags2 & TG3_FLG2_HW_TSO_2)) {
                if (value) {
                        dev->features |= NETIF_F_TSO6;
                        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
                            (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
                             GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX) ||
-                           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
+                           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
+                           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
                                dev->features |= NETIF_F_TSO_ECN;
                } else
                        dev->features &= ~(NETIF_F_TSO6 | NETIF_F_TSO_ECN);
@@ -9238,12 +8987,12 @@ static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam
 
        epause->autoneg = (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG) != 0;
 
-       if (tp->link_config.active_flowctrl & TG3_FLOW_CTRL_RX)
+       if (tp->link_config.active_flowctrl & FLOW_CTRL_RX)
                epause->rx_pause = 1;
        else
                epause->rx_pause = 0;
 
-       if (tp->link_config.active_flowctrl & TG3_FLOW_CTRL_TX)
+       if (tp->link_config.active_flowctrl & FLOW_CTRL_TX)
                epause->tx_pause = 1;
        else
                epause->tx_pause = 0;
@@ -9294,14 +9043,14 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam
                        }
                } else {
                        if (epause->rx_pause)
-                               tp->link_config.flowctrl |= TG3_FLOW_CTRL_RX;
+                               tp->link_config.flowctrl |= FLOW_CTRL_RX;
                        else
-                               tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_RX;
+                               tp->link_config.flowctrl &= ~FLOW_CTRL_RX;
 
                        if (epause->tx_pause)
-                               tp->link_config.flowctrl |= TG3_FLOW_CTRL_TX;
+                               tp->link_config.flowctrl |= FLOW_CTRL_TX;
                        else
-                               tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_TX;
+                               tp->link_config.flowctrl &= ~FLOW_CTRL_TX;
 
                        if (netif_running(dev))
                                tg3_setup_flow_control(tp, 0, 0);
@@ -9321,13 +9070,13 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam
                else
                        tp->tg3_flags &= ~TG3_FLAG_PAUSE_AUTONEG;
                if (epause->rx_pause)
-                       tp->link_config.flowctrl |= TG3_FLOW_CTRL_RX;
+                       tp->link_config.flowctrl |= FLOW_CTRL_RX;
                else
-                       tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_RX;
+                       tp->link_config.flowctrl &= ~FLOW_CTRL_RX;
                if (epause->tx_pause)
-                       tp->link_config.flowctrl |= TG3_FLOW_CTRL_TX;
+                       tp->link_config.flowctrl |= FLOW_CTRL_TX;
                else
-                       tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_TX;
+                       tp->link_config.flowctrl &= ~FLOW_CTRL_TX;
 
                if (netif_running(dev)) {
                        tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
@@ -9378,11 +9127,7 @@ static int tg3_set_tx_csum(struct net_device *dev, u32 data)
                return 0;
        }
 
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
+       if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
                ethtool_op_set_tx_ipv6_csum(dev, data);
        else
                ethtool_op_set_tx_csum(dev, data);
@@ -9466,10 +9211,13 @@ static void tg3_get_ethtool_stats (struct net_device *dev,
 static int tg3_test_nvram(struct tg3 *tp)
 {
        u32 csum, magic;
-       __le32 *buf;
+       __be32 *buf;
        int i, j, k, err = 0, size;
 
-       if (tg3_nvram_read_swab(tp, 0, &magic) != 0)
+       if (tp->tg3_flags3 & TG3_FLG3_NO_NVRAM)
+               return 0;
+
+       if (tg3_nvram_read(tp, 0, &magic) != 0)
                return -EIO;
 
        if (magic == TG3_EEPROM_MAGIC)
@@ -9503,14 +9251,15 @@ static int tg3_test_nvram(struct tg3 *tp)
 
        err = -EIO;
        for (i = 0, j = 0; i < size; i += 4, j++) {
-               if ((err = tg3_nvram_read_le(tp, i, &buf[j])) != 0)
+               err = tg3_nvram_read_be32(tp, i, &buf[j]);
+               if (err)
                        break;
        }
        if (i < size)
                goto out;
 
        /* Selfboot format */
-       magic = swab32(le32_to_cpu(buf[0]));
+       magic = be32_to_cpu(buf[0]);
        if ((magic & TG3_EEPROM_MAGIC_FW_MSK) ==
            TG3_EEPROM_MAGIC_FW) {
                u8 *buf8 = (u8 *) buf, csum8 = 0;
@@ -9539,7 +9288,7 @@ static int tg3_test_nvram(struct tg3 *tp)
        if ((magic & TG3_EEPROM_MAGIC_HW_MSK) ==
            TG3_EEPROM_MAGIC_HW) {
                u8 data[NVRAM_SELFBOOT_DATA_SIZE];
-               u8 parity[NVRAM_SELFBOOT_DATA_SIZE];
+               u8 parity[NVRAM_SELFBOOT_DATA_SIZE];
                u8 *buf8 = (u8 *) buf;
 
                /* Separate the parity bits and the data bytes.  */
@@ -9582,13 +9331,13 @@ static int tg3_test_nvram(struct tg3 *tp)
 
        /* Bootstrap checksum at offset 0x10 */
        csum = calc_crc((unsigned char *) buf, 0x10);
-       if(csum != le32_to_cpu(buf[0x10/4]))
+       if (csum != be32_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 != le32_to_cpu(buf[0xfc/4]))
-                goto out;
+       if (csum != be32_to_cpu(buf[0xfc/4]))
+               goto out;
 
        err = 0;
 
@@ -9899,18 +9648,13 @@ static int tg3_test_memory(struct tg3 *tp)
        int err = 0;
        int i;
 
-       if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
-               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
-                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
-                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
-                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
-                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
-                       mem_tbl = mem_tbl_5755;
-               else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
-                       mem_tbl = mem_tbl_5906;
-               else
-                       mem_tbl = mem_tbl_5705;
-       } else
+       if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
+               mem_tbl = mem_tbl_5755;
+       else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+               mem_tbl = mem_tbl_5906;
+       else if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)
+               mem_tbl = mem_tbl_5705;
+       else
                mem_tbl = mem_tbl_570x;
 
        for (i = 0; mem_tbl[i].offset != 0xffffffff; i++) {
@@ -10110,9 +9854,11 @@ static int tg3_test_loopback(struct tg3 *tp)
        if (err)
                return TG3_LOOPBACK_FAILED;
 
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785) {
+       /* Turn off gphy autopowerdown. */
+       if (tp->tg3_flags3 & TG3_FLG3_PHY_ENABLE_APD)
+               tg3_phy_toggle_apd(tp, false);
+
+       if (tp->tg3_flags & TG3_FLAG_CPMU_PRESENT) {
                int i;
                u32 status;
 
@@ -10139,9 +9885,7 @@ static int tg3_test_loopback(struct tg3 *tp)
        if (tg3_run_loopback(tp, TG3_MAC_LOOPBACK))
                err |= TG3_MAC_LOOPBACK_FAILED;
 
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785) {
+       if (tp->tg3_flags & TG3_FLAG_CPMU_PRESENT) {
                tw32(TG3_CPMU_CTRL, cpmuctrl);
 
                /* Release the mutex */
@@ -10154,6 +9898,10 @@ static int tg3_test_loopback(struct tg3 *tp)
                        err |= TG3_PHY_LOOPBACK_FAILED;
        }
 
+       /* Re-enable gphy autopowerdown. */
+       if (tp->tg3_flags3 & TG3_FLG3_PHY_ENABLE_APD)
+               tg3_phy_toggle_apd(tp, true);
+
        return err;
 }
 
@@ -10298,8 +10046,12 @@ static void tg3_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
 {
        struct tg3 *tp = netdev_priv(dev);
 
-       if (netif_running(dev))
-               tg3_netif_stop(tp);
+       if (!netif_running(dev)) {
+               tp->vlgrp = grp;
+               return;
+       }
+
+       tg3_netif_stop(tp);
 
        tg3_full_lock(tp, 0);
 
@@ -10308,8 +10060,7 @@ static void tg3_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
        /* Update RX_MODE_KEEP_VLAN_TAG bit in RX_MODE register. */
        __tg3_set_rx_mode(dev);
 
-       if (netif_running(dev))
-               tg3_netif_start(tp);
+       tg3_netif_start(tp);
 
        tg3_full_unlock(tp);
 }
@@ -10416,7 +10167,7 @@ static void __devinit tg3_get_eeprom_size(struct tg3 *tp)
 
        tp->nvram_size = EEPROM_CHIP_SIZE;
 
-       if (tg3_nvram_read_swab(tp, 0, &magic) != 0)
+       if (tg3_nvram_read(tp, 0, &magic) != 0)
                return;
 
        if ((magic != TG3_EEPROM_MAGIC) &&
@@ -10432,7 +10183,7 @@ static void __devinit tg3_get_eeprom_size(struct tg3 *tp)
        cursize = 0x10;
 
        while (cursize < tp->nvram_size) {
-               if (tg3_nvram_read_swab(tp, cursize, &val) != 0)
+               if (tg3_nvram_read(tp, cursize, &val) != 0)
                        return;
 
                if (val == magic)
@@ -10448,7 +10199,8 @@ static void __devinit tg3_get_nvram_size(struct tg3 *tp)
 {
        u32 val;
 
-       if (tg3_nvram_read_swab(tp, 0, &val) != 0)
+       if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) ||
+           tg3_nvram_read(tp, 0, &val) != 0)
                return;
 
        /* Selfboot format */
@@ -10459,7 +10211,18 @@ static void __devinit tg3_get_nvram_size(struct tg3 *tp)
 
        if (tg3_nvram_read(tp, 0xf0, &val) == 0) {
                if (val != 0) {
-                       tp->nvram_size = (val >> 16) * 1024;
+                       /* This is confusing.  We want to operate on the
+                        * 16-bit value at offset 0xf2.  The tg3_nvram_read()
+                        * call will read from NVRAM and byteswap the data
+                        * according to the byteswapping settings for all
+                        * other register accesses.  This ensures the data we
+                        * want will always reside in the lower 16-bits.
+                        * However, the data in NVRAM is in LE format, which
+                        * means the data from the NVRAM read will always be
+                        * opposite the endianness of the CPU.  The 16-bit
+                        * byteswap then brings the data to CPU endianness.
+                        */
+                       tp->nvram_size = swab16((u16)(val & 0x0000ffff)) * 1024;
                        return;
                }
        }
@@ -10756,6 +10519,103 @@ static void __devinit tg3_get_5906_nvram_info(struct tg3 *tp)
        tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
 }
 
+static void __devinit tg3_get_57780_nvram_info(struct tg3 *tp)
+{
+       u32 nvcfg1;
+
+       nvcfg1 = tr32(NVRAM_CFG1);
+
+       switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
+       case FLASH_5787VENDOR_ATMEL_EEPROM_376KHZ:
+       case FLASH_5787VENDOR_MICRO_EEPROM_376KHZ:
+               tp->nvram_jedecnum = JEDEC_ATMEL;
+               tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+               tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
+
+               nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
+               tw32(NVRAM_CFG1, nvcfg1);
+               return;
+       case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED:
+       case FLASH_57780VENDOR_ATMEL_AT45DB011D:
+       case FLASH_57780VENDOR_ATMEL_AT45DB011B:
+       case FLASH_57780VENDOR_ATMEL_AT45DB021D:
+       case FLASH_57780VENDOR_ATMEL_AT45DB021B:
+       case FLASH_57780VENDOR_ATMEL_AT45DB041D:
+       case FLASH_57780VENDOR_ATMEL_AT45DB041B:
+               tp->nvram_jedecnum = JEDEC_ATMEL;
+               tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+               tp->tg3_flags2 |= TG3_FLG2_FLASH;
+
+               switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
+               case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED:
+               case FLASH_57780VENDOR_ATMEL_AT45DB011D:
+               case FLASH_57780VENDOR_ATMEL_AT45DB011B:
+                       tp->nvram_size = TG3_NVRAM_SIZE_128KB;
+                       break;
+               case FLASH_57780VENDOR_ATMEL_AT45DB021D:
+               case FLASH_57780VENDOR_ATMEL_AT45DB021B:
+                       tp->nvram_size = TG3_NVRAM_SIZE_256KB;
+                       break;
+               case FLASH_57780VENDOR_ATMEL_AT45DB041D:
+               case FLASH_57780VENDOR_ATMEL_AT45DB041B:
+                       tp->nvram_size = TG3_NVRAM_SIZE_512KB;
+                       break;
+               }
+               break;
+       case FLASH_5752VENDOR_ST_M45PE10:
+       case FLASH_5752VENDOR_ST_M45PE20:
+       case FLASH_5752VENDOR_ST_M45PE40:
+               tp->nvram_jedecnum = JEDEC_ST;
+               tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+               tp->tg3_flags2 |= TG3_FLG2_FLASH;
+
+               switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
+               case FLASH_5752VENDOR_ST_M45PE10:
+                       tp->nvram_size = TG3_NVRAM_SIZE_128KB;
+                       break;
+               case FLASH_5752VENDOR_ST_M45PE20:
+                       tp->nvram_size = TG3_NVRAM_SIZE_256KB;
+                       break;
+               case FLASH_5752VENDOR_ST_M45PE40:
+                       tp->nvram_size = TG3_NVRAM_SIZE_512KB;
+                       break;
+               }
+               break;
+       default:
+               tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM;
+               return;
+       }
+
+       switch (nvcfg1 & NVRAM_CFG1_5752PAGE_SIZE_MASK) {
+       case FLASH_5752PAGE_SIZE_256:
+               tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
+               tp->nvram_pagesize = 256;
+               break;
+       case FLASH_5752PAGE_SIZE_512:
+               tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
+               tp->nvram_pagesize = 512;
+               break;
+       case FLASH_5752PAGE_SIZE_1K:
+               tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
+               tp->nvram_pagesize = 1024;
+               break;
+       case FLASH_5752PAGE_SIZE_2K:
+               tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
+               tp->nvram_pagesize = 2048;
+               break;
+       case FLASH_5752PAGE_SIZE_4K:
+               tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
+               tp->nvram_pagesize = 4096;
+               break;
+       case FLASH_5752PAGE_SIZE_264:
+               tp->nvram_pagesize = 264;
+               break;
+       case FLASH_5752PAGE_SIZE_528:
+               tp->nvram_pagesize = 528;
+               break;
+       }
+}
+
 /* Chips other than 5700/5701 use the NVRAM for fetching info. */
 static void __devinit tg3_nvram_init(struct tg3 *tp)
 {
@@ -10784,167 +10644,34 @@ static void __devinit tg3_nvram_init(struct tg3 *tp)
 
                tp->nvram_size = 0;
 
-               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752)
-                       tg3_get_5752_nvram_info(tp);
-               else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755)
-                       tg3_get_5755_nvram_info(tp);
-               else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
-                        GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
-                        GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
-                       tg3_get_5787_nvram_info(tp);
-               else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
-                       tg3_get_5761_nvram_info(tp);
-               else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
-                       tg3_get_5906_nvram_info(tp);
-               else
-                       tg3_get_nvram_info(tp);
-
-               if (tp->nvram_size == 0)
-                       tg3_get_nvram_size(tp);
-
-               tg3_disable_nvram_access(tp);
-               tg3_nvram_unlock(tp);
-
-       } else {
-               tp->tg3_flags &= ~(TG3_FLAG_NVRAM | TG3_FLAG_NVRAM_BUFFERED);
-
-               tg3_get_eeprom_size(tp);
-       }
-}
-
-static int tg3_nvram_read_using_eeprom(struct tg3 *tp,
-                                       u32 offset, u32 *val)
-{
-       u32 tmp;
-       int i;
-
-       if (offset > EEPROM_ADDR_ADDR_MASK ||
-           (offset % 4) != 0)
-               return -EINVAL;
-
-       tmp = tr32(GRC_EEPROM_ADDR) & ~(EEPROM_ADDR_ADDR_MASK |
-                                       EEPROM_ADDR_DEVID_MASK |
-                                       EEPROM_ADDR_READ);
-       tw32(GRC_EEPROM_ADDR,
-            tmp |
-            (0 << EEPROM_ADDR_DEVID_SHIFT) |
-            ((offset << EEPROM_ADDR_ADDR_SHIFT) &
-             EEPROM_ADDR_ADDR_MASK) |
-            EEPROM_ADDR_READ | EEPROM_ADDR_START);
-
-       for (i = 0; i < 1000; i++) {
-               tmp = tr32(GRC_EEPROM_ADDR);
-
-               if (tmp & EEPROM_ADDR_COMPLETE)
-                       break;
-               msleep(1);
-       }
-       if (!(tmp & EEPROM_ADDR_COMPLETE))
-               return -EBUSY;
-
-       *val = tr32(GRC_EEPROM_DATA);
-       return 0;
-}
-
-#define NVRAM_CMD_TIMEOUT 10000
-
-static int tg3_nvram_exec_cmd(struct tg3 *tp, u32 nvram_cmd)
-{
-       int i;
-
-       tw32(NVRAM_CMD, nvram_cmd);
-       for (i = 0; i < NVRAM_CMD_TIMEOUT; i++) {
-               udelay(10);
-               if (tr32(NVRAM_CMD) & NVRAM_CMD_DONE) {
-                       udelay(10);
-                       break;
-               }
-       }
-       if (i == NVRAM_CMD_TIMEOUT) {
-               return -EBUSY;
-       }
-       return 0;
-}
-
-static u32 tg3_nvram_phys_addr(struct tg3 *tp, u32 addr)
-{
-       if ((tp->tg3_flags & TG3_FLAG_NVRAM) &&
-           (tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) &&
-           (tp->tg3_flags2 & TG3_FLG2_FLASH) &&
-          !(tp->tg3_flags3 & TG3_FLG3_NO_NVRAM_ADDR_TRANS) &&
-           (tp->nvram_jedecnum == JEDEC_ATMEL))
-
-               addr = ((addr / tp->nvram_pagesize) <<
-                       ATMEL_AT45DB0X1B_PAGE_POS) +
-                      (addr % tp->nvram_pagesize);
-
-       return addr;
-}
-
-static u32 tg3_nvram_logical_addr(struct tg3 *tp, u32 addr)
-{
-       if ((tp->tg3_flags & TG3_FLAG_NVRAM) &&
-           (tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) &&
-           (tp->tg3_flags2 & TG3_FLG2_FLASH) &&
-          !(tp->tg3_flags3 & TG3_FLG3_NO_NVRAM_ADDR_TRANS) &&
-           (tp->nvram_jedecnum == JEDEC_ATMEL))
-
-               addr = ((addr >> ATMEL_AT45DB0X1B_PAGE_POS) *
-                       tp->nvram_pagesize) +
-                      (addr & ((1 << ATMEL_AT45DB0X1B_PAGE_POS) - 1));
-
-       return addr;
-}
-
-static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val)
-{
-       int ret;
-
-       if (!(tp->tg3_flags & TG3_FLAG_NVRAM))
-               return tg3_nvram_read_using_eeprom(tp, offset, val);
-
-       offset = tg3_nvram_phys_addr(tp, offset);
-
-       if (offset > NVRAM_ADDR_MSK)
-               return -EINVAL;
-
-       ret = tg3_nvram_lock(tp);
-       if (ret)
-               return ret;
-
-       tg3_enable_nvram_access(tp);
-
-       tw32(NVRAM_ADDR, offset);
-       ret = tg3_nvram_exec_cmd(tp, NVRAM_CMD_RD | NVRAM_CMD_GO |
-               NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_DONE);
-
-       if (ret == 0)
-               *val = swab32(tr32(NVRAM_RDDATA));
-
-       tg3_disable_nvram_access(tp);
-
-       tg3_nvram_unlock(tp);
+               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752)
+                       tg3_get_5752_nvram_info(tp);
+               else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755)
+                       tg3_get_5755_nvram_info(tp);
+               else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
+                        GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
+                        GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
+                       tg3_get_5787_nvram_info(tp);
+               else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
+                       tg3_get_5761_nvram_info(tp);
+               else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+                       tg3_get_5906_nvram_info(tp);
+               else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
+                       tg3_get_57780_nvram_info(tp);
+               else
+                       tg3_get_nvram_info(tp);
 
-       return ret;
-}
+               if (tp->nvram_size == 0)
+                       tg3_get_nvram_size(tp);
 
-static int tg3_nvram_read_le(struct tg3 *tp, u32 offset, __le32 *val)
-{
-       u32 v;
-       int res = tg3_nvram_read(tp, offset, &v);
-       if (!res)
-               *val = cpu_to_le32(v);
-       return res;
-}
+               tg3_disable_nvram_access(tp);
+               tg3_nvram_unlock(tp);
 
-static int tg3_nvram_read_swab(struct tg3 *tp, u32 offset, u32 *val)
-{
-       int err;
-       u32 tmp;
+       } else {
+               tp->tg3_flags &= ~(TG3_FLAG_NVRAM | TG3_FLAG_NVRAM_BUFFERED);
 
-       err = tg3_nvram_read(tp, offset, &tmp);
-       *val = swab32(tmp);
-       return err;
+               tg3_get_eeprom_size(tp);
+       }
 }
 
 static int tg3_nvram_write_block_using_eeprom(struct tg3 *tp,
@@ -10955,13 +10682,19 @@ static int tg3_nvram_write_block_using_eeprom(struct tg3 *tp,
 
        for (i = 0; i < len; i += 4) {
                u32 addr;
-               __le32 data;
+               __be32 data;
 
                addr = offset + i;
 
                memcpy(&data, buf + i, 4);
 
-               tw32(GRC_EEPROM_DATA, le32_to_cpu(data));
+               /*
+                * The SEEPROM interface expects the data to always be opposite
+                * the native endian format.  We accomplish this by reversing
+                * all the operations that would have been performed on the
+                * data from a call to tg3_nvram_read_be32().
+                */
+               tw32(GRC_EEPROM_DATA, swab32(be32_to_cpu(data)));
 
                val = tr32(GRC_EEPROM_ADDR);
                tw32(GRC_EEPROM_ADDR, val | EEPROM_ADDR_COMPLETE);
@@ -11011,8 +10744,9 @@ static int tg3_nvram_write_block_unbuffered(struct tg3 *tp, u32 offset, u32 len,
                phy_addr = offset & ~pagemask;
 
                for (j = 0; j < pagesize; j += 4) {
-                       if ((ret = tg3_nvram_read_le(tp, phy_addr + j,
-                                               (__le32 *) (tmp + j))))
+                       ret = tg3_nvram_read_be32(tp, phy_addr + j,
+                                                 (__be32 *) (tmp + j));
+                       if (ret)
                                break;
                }
                if (ret)
@@ -11059,7 +10793,7 @@ static int tg3_nvram_write_block_unbuffered(struct tg3 *tp, u32 offset, u32 len,
                        __be32 data;
 
                        data = *((__be32 *) (tmp + j));
-                       /* swab32(le32_to_cpu(data)), actually */
+
                        tw32(NVRAM_WRDATA, be32_to_cpu(data));
 
                        tw32(NVRAM_ADDR, phy_addr + j);
@@ -11116,12 +10850,8 @@ static int tg3_nvram_write_block_buffered(struct tg3 *tp, u32 offset, u32 len,
                if (i == (len - 4))
                        nvram_cmd |= NVRAM_CMD_LAST;
 
-               if ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5752) &&
-                   (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5755) &&
-                   (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5787) &&
-                   (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5784) &&
-                   (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5761) &&
-                   (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785) &&
+               if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5752 &&
+                   !(tp->tg3_flags3 & TG3_FLG3_5755_PLUS) &&
                    (tp->nvram_jedecnum == JEDEC_ST) &&
                    (nvram_cmd & NVRAM_CMD_FIRST)) {
 
@@ -11296,10 +11026,9 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
                if (val & VCPU_CFGSHDW_ASPM_DBNC)
                        tp->tg3_flags |= TG3_FLAG_ASPM_WORKAROUND;
                if ((val & VCPU_CFGSHDW_WOL_ENABLE) &&
-                   (val & VCPU_CFGSHDW_WOL_MAGPKT) &&
-                   device_may_wakeup(&tp->pdev->dev))
+                   (val & VCPU_CFGSHDW_WOL_MAGPKT))
                        tp->tg3_flags |= TG3_FLAG_WOL_ENABLE;
-               return;
+               goto done;
        }
 
        tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val);
@@ -11421,15 +11150,17 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
                        if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS)
                                tp->tg3_flags2 |= TG3_FLG2_ASF_NEW_HANDSHAKE;
                }
-               if (nic_cfg & NIC_SRAM_DATA_CFG_APE_ENABLE)
+
+               if ((nic_cfg & NIC_SRAM_DATA_CFG_APE_ENABLE) &&
+                       (tp->tg3_flags2 & TG3_FLG2_5750_PLUS))
                        tp->tg3_flags3 |= TG3_FLG3_ENABLE_APE;
+
                if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES &&
                    !(nic_cfg & NIC_SRAM_DATA_CFG_FIBER_WOL))
                        tp->tg3_flags &= ~TG3_FLAG_WOL_CAP;
 
                if ((tp->tg3_flags & TG3_FLAG_WOL_CAP) &&
-                   (nic_cfg & NIC_SRAM_DATA_CFG_WOL_ENABLE) &&
-                   device_may_wakeup(&tp->pdev->dev))
+                   (nic_cfg & NIC_SRAM_DATA_CFG_WOL_ENABLE))
                        tp->tg3_flags |= TG3_FLAG_WOL_ENABLE;
 
                if (cfg2 & (1 << 17))
@@ -11440,6 +11171,11 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
                if (cfg2 & (1 << 18))
                        tp->tg3_flags2 |= TG3_FLG2_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)) &&
+                   (cfg2 & NIC_SRAM_DATA_CFG_2_APD_EN))
+                       tp->tg3_flags3 |= TG3_FLG3_PHY_ENABLE_APD;
+
                if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) {
                        u32 cfg3;
 
@@ -11455,6 +11191,10 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
                if (cfg4 & NIC_SRAM_RGMII_EXT_IBND_TX_EN)
                        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,
+                                tp->tg3_flags & TG3_FLAG_WOL_ENABLE);
 }
 
 static int __devinit tg3_issue_otp_command(struct tg3 *tp, u32 cmd)
@@ -11516,7 +11256,7 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
                return tg3_phy_init(tp);
 
        /* Reading the PHY ID register can conflict with ASF
-        * firwmare access to the PHY hardware.
+        * firmware access to the PHY hardware.
         */
        err = 0;
        if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
@@ -11639,24 +11379,26 @@ skip_phy_reset:
 
 static void __devinit tg3_read_partno(struct tg3 *tp)
 {
-       unsigned char vpd_data[256];
+       unsigned char vpd_data[256];   /* in little-endian format */
        unsigned int i;
        u32 magic;
 
-       if (tg3_nvram_read_swab(tp, 0x0, &magic))
+       if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) ||
+           tg3_nvram_read(tp, 0x0, &magic))
                goto out_not_found;
 
        if (magic == TG3_EEPROM_MAGIC) {
                for (i = 0; i < 256; i += 4) {
                        u32 tmp;
 
-                       if (tg3_nvram_read(tp, 0x100 + i, &tmp))
+                       /* The data is in little-endian format in NVRAM.
+                        * Use the big-endian read routines to preserve
+                        * the byte order as it exists in NVRAM.
+                        */
+                       if (tg3_nvram_read_be32(tp, 0x100 + i, &tmp))
                                goto out_not_found;
 
-                       vpd_data[i + 0] = ((tmp >>  0) & 0xff);
-                       vpd_data[i + 1] = ((tmp >>  8) & 0xff);
-                       vpd_data[i + 2] = ((tmp >> 16) & 0xff);
-                       vpd_data[i + 3] = ((tmp >> 24) & 0xff);
+                       memcpy(&vpd_data[i], &tmp, sizeof(tmp));
                }
        } else {
                int vpd_cap;
@@ -11682,7 +11424,7 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
                        pci_read_config_dword(tp->pdev, vpd_cap + PCI_VPD_DATA,
                                              &tmp);
                        v = cpu_to_le32(tmp);
-                       memcpy(&vpd_data[i], &v, 4);
+                       memcpy(&vpd_data[i], &v, sizeof(v));
                }
        }
 
@@ -11734,6 +11476,15 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
 out_not_found:
        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
                strcpy(tp->board_part_number, "none");
 }
@@ -11742,54 +11493,133 @@ static int __devinit tg3_fw_img_is_valid(struct tg3 *tp, u32 offset)
 {
        u32 val;
 
-       if (tg3_nvram_read_swab(tp, offset, &val) ||
+       if (tg3_nvram_read(tp, offset, &val) ||
            (val & 0xfc000000) != 0x0c000000 ||
-           tg3_nvram_read_swab(tp, offset + 4, &val) ||
+           tg3_nvram_read(tp, offset + 4, &val) ||
            val != 0)
                return 0;
 
        return 1;
 }
 
-static void __devinit tg3_read_fw_ver(struct tg3 *tp)
+static void __devinit tg3_read_bc_ver(struct tg3 *tp)
 {
-       u32 val, offset, start;
-       u32 ver_offset;
-       int i, bcnt;
+       u32 val, offset, start, ver_offset;
+       int i;
+       bool newver = false;
 
-       if (tg3_nvram_read_swab(tp, 0, &val))
+       if (tg3_nvram_read(tp, 0xc, &offset) ||
+           tg3_nvram_read(tp, 0x4, &start))
                return;
 
-       if (val != TG3_EEPROM_MAGIC)
-               return;
+       offset = tg3_nvram_logical_addr(tp, offset);
 
-       if (tg3_nvram_read_swab(tp, 0xc, &offset) ||
-           tg3_nvram_read_swab(tp, 0x4, &start))
+       if (tg3_nvram_read(tp, offset, &val))
                return;
 
-       offset = tg3_nvram_logical_addr(tp, offset);
+       if ((val & 0xfc000000) == 0x0c000000) {
+               if (tg3_nvram_read(tp, offset + 4, &val))
+                       return;
 
-       if (!tg3_fw_img_is_valid(tp, offset) ||
-           tg3_nvram_read_swab(tp, offset + 8, &ver_offset))
-               return;
+               if (val == 0)
+                       newver = true;
+       }
+
+       if (newver) {
+               if (tg3_nvram_read(tp, offset + 8, &ver_offset))
+                       return;
 
-       offset = offset + ver_offset - start;
-       for (i = 0; i < 16; i += 4) {
-               __le32 v;
-               if (tg3_nvram_read_le(tp, offset + i, &v))
+               offset = offset + ver_offset - start;
+               for (i = 0; i < 16; i += 4) {
+                       __be32 v;
+                       if (tg3_nvram_read_be32(tp, offset + i, &v))
+                               return;
+
+                       memcpy(tp->fw_ver + i, &v, sizeof(v));
+               }
+       } else {
+               u32 major, minor;
+
+               if (tg3_nvram_read(tp, TG3_NVM_PTREV_BCVER, &ver_offset))
                        return;
 
-               memcpy(tp->fw_ver + i, &v, 4);
+               major = (ver_offset & TG3_NVM_BCVER_MAJMSK) >>
+                       TG3_NVM_BCVER_MAJSFT;
+               minor = ver_offset & TG3_NVM_BCVER_MINMSK;
+               snprintf(&tp->fw_ver[0], 32, "v%d.%02d", major, minor);
        }
+}
 
-       if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
-            (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE))
+static void __devinit tg3_read_hwsb_ver(struct tg3 *tp)
+{
+       u32 val, major, minor;
+
+       /* Use native endian representation */
+       if (tg3_nvram_read(tp, TG3_NVM_HWSB_CFG1, &val))
+               return;
+
+       major = (val & TG3_NVM_HWSB_CFG1_MAJMSK) >>
+               TG3_NVM_HWSB_CFG1_MAJSFT;
+       minor = (val & TG3_NVM_HWSB_CFG1_MINMSK) >>
+               TG3_NVM_HWSB_CFG1_MINSFT;
+
+       snprintf(&tp->fw_ver[0], 32, "sb v%d.%02d", major, minor);
+}
+
+static void __devinit tg3_read_sb_ver(struct tg3 *tp, u32 val)
+{
+       u32 offset, major, minor, build;
+
+       tp->fw_ver[0] = 's';
+       tp->fw_ver[1] = 'b';
+       tp->fw_ver[2] = '\0';
+
+       if ((val & TG3_EEPROM_SB_FORMAT_MASK) != TG3_EEPROM_SB_FORMAT_1)
+               return;
+
+       switch (val & TG3_EEPROM_SB_REVISION_MASK) {
+       case TG3_EEPROM_SB_REVISION_0:
+               offset = TG3_EEPROM_SB_F1R0_EDH_OFF;
+               break;
+       case TG3_EEPROM_SB_REVISION_2:
+               offset = TG3_EEPROM_SB_F1R2_EDH_OFF;
+               break;
+       case TG3_EEPROM_SB_REVISION_3:
+               offset = TG3_EEPROM_SB_F1R3_EDH_OFF;
+               break;
+       default:
                return;
+       }
+
+       if (tg3_nvram_read(tp, offset, &val))
+               return;
+
+       build = (val & TG3_EEPROM_SB_EDH_BLD_MASK) >>
+               TG3_EEPROM_SB_EDH_BLD_SHFT;
+       major = (val & TG3_EEPROM_SB_EDH_MAJ_MASK) >>
+               TG3_EEPROM_SB_EDH_MAJ_SHFT;
+       minor =  val & TG3_EEPROM_SB_EDH_MIN_MASK;
+
+       if (minor > 99 || build > 26)
+               return;
+
+       snprintf(&tp->fw_ver[2], 30, " v%d.%02d", major, minor);
+
+       if (build > 0) {
+               tp->fw_ver[8] = 'a' + build - 1;
+               tp->fw_ver[9] = '\0';
+       }
+}
+
+static void __devinit tg3_read_mgmtfw_ver(struct tg3 *tp)
+{
+       u32 val, offset, start;
+       int i, vlen;
 
        for (offset = TG3_NVM_DIR_START;
             offset < TG3_NVM_DIR_END;
             offset += TG3_NVM_DIRENT_SIZE) {
-               if (tg3_nvram_read_swab(tp, offset, &val))
+               if (tg3_nvram_read(tp, offset, &val))
                        return;
 
                if ((val >> TG3_NVM_DIRTYPE_SHIFT) == TG3_NVM_DIRTYPE_ASFINI)
@@ -11801,37 +11631,96 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp)
 
        if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
                start = 0x08000000;
-       else if (tg3_nvram_read_swab(tp, offset - 4, &start))
+       else if (tg3_nvram_read(tp, offset - 4, &start))
                return;
 
-       if (tg3_nvram_read_swab(tp, offset + 4, &offset) ||
+       if (tg3_nvram_read(tp, offset + 4, &offset) ||
            !tg3_fw_img_is_valid(tp, offset) ||
-           tg3_nvram_read_swab(tp, offset + 8, &val))
+           tg3_nvram_read(tp, offset + 8, &val))
                return;
 
        offset += val - start;
 
-       bcnt = strlen(tp->fw_ver);
+       vlen = strlen(tp->fw_ver);
 
-       tp->fw_ver[bcnt++] = ',';
-       tp->fw_ver[bcnt++] = ' ';
+       tp->fw_ver[vlen++] = ',';
+       tp->fw_ver[vlen++] = ' ';
 
        for (i = 0; i < 4; i++) {
-               __le32 v;
-               if (tg3_nvram_read_le(tp, offset, &v))
+               __be32 v;
+               if (tg3_nvram_read_be32(tp, offset, &v))
                        return;
 
                offset += sizeof(v);
 
-               if (bcnt > TG3_VER_SIZE - sizeof(v)) {
-                       memcpy(&tp->fw_ver[bcnt], &v, TG3_VER_SIZE - bcnt);
+               if (vlen > TG3_VER_SIZE - sizeof(v)) {
+                       memcpy(&tp->fw_ver[vlen], &v, TG3_VER_SIZE - vlen);
                        break;
                }
 
-               memcpy(&tp->fw_ver[bcnt], &v, sizeof(v));
-               bcnt += sizeof(v);
+               memcpy(&tp->fw_ver[vlen], &v, sizeof(v));
+               vlen += sizeof(v);
+       }
+}
+
+static void __devinit tg3_read_dash_ver(struct tg3 *tp)
+{
+       int vlen;
+       u32 apedata;
+
+       if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) ||
+           !(tp->tg3_flags  & TG3_FLAG_ENABLE_ASF))
+               return;
+
+       apedata = tg3_ape_read32(tp, TG3_APE_SEG_SIG);
+       if (apedata != APE_SEG_SIG_MAGIC)
+               return;
+
+       apedata = tg3_ape_read32(tp, TG3_APE_FW_STATUS);
+       if (!(apedata & APE_FW_STATUS_READY))
+               return;
+
+       apedata = tg3_ape_read32(tp, TG3_APE_FW_VERSION);
+
+       vlen = strlen(tp->fw_ver);
+
+       snprintf(&tp->fw_ver[vlen], TG3_VER_SIZE - vlen, " DASH v%d.%d.%d.%d",
+                (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,
+                (apedata & APE_FW_VERSION_BLDMSK));
+}
+
+static void __devinit tg3_read_fw_ver(struct tg3 *tp)
+{
+       u32 val;
+
+       if (tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) {
+               tp->fw_ver[0] = 's';
+               tp->fw_ver[1] = 'b';
+               tp->fw_ver[2] = '\0';
+
+               return;
        }
 
+       if (tg3_nvram_read(tp, 0, &val))
+               return;
+
+       if (val == TG3_EEPROM_MAGIC)
+               tg3_read_bc_ver(tp);
+       else if ((val & TG3_EEPROM_MAGIC_FW_MSK) == TG3_EEPROM_MAGIC_FW)
+               tg3_read_sb_ver(tp, val);
+       else if ((val & TG3_EEPROM_MAGIC_HW_MSK) == TG3_EEPROM_MAGIC_HW)
+               tg3_read_hwsb_ver(tp);
+       else
+               return;
+
+       if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
+            (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE))
+               return;
+
+       tg3_read_mgmtfw_ver(tp);
+
        tp->fw_ver[TG3_VER_SIZE - 1] = 0;
 }
 
@@ -11849,11 +11738,10 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                { },
        };
        u32 misc_ctrl_reg;
-       u32 cacheline_sz_reg;
        u32 pci_state_reg, grc_misc_cfg;
        u32 val;
        u16 pci_cmd;
-       int err, pcie_cap;
+       int err;
 
        /* Force memory write invalidate off.  If we leave it on,
         * then on 5700_BX chips we have to enable a workaround.
@@ -11882,7 +11770,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 
                pci_read_config_dword(tp->pdev, TG3PCI_PRODID_ASICREV,
                                      &prod_id_asic_rev);
-               tp->pci_chip_rev_id = prod_id_asic_rev & PROD_ID_ASIC_REV_MASK;
+               tp->pci_chip_rev_id = prod_id_asic_rev;
        }
 
        /* Wrong chip ID in 5752 A0. This code can be removed later
@@ -12019,26 +11907,23 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL,
                               tp->misc_host_ctrl);
 
-       pci_read_config_dword(tp->pdev, TG3PCI_CACHELINESZ,
-                             &cacheline_sz_reg);
-
-       tp->pci_cacheline_sz = (cacheline_sz_reg >>  0) & 0xff;
-       tp->pci_lat_timer    = (cacheline_sz_reg >>  8) & 0xff;
-       tp->pci_hdr_type     = (cacheline_sz_reg >> 16) & 0xff;
-       tp->pci_bist         = (cacheline_sz_reg >> 24) & 0xff;
-
        if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) ||
            (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714))
                tp->pdev_peer = tg3_find_peer(tp);
 
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
+       /* Intentionally exclude ASIC_REV_5906 */
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
+               tp->tg3_flags3 |= TG3_FLG3_5755_PLUS;
+
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906 ||
+           (tp->tg3_flags3 & TG3_FLG3_5755_PLUS) ||
            (tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
                tp->tg3_flags2 |= TG3_FLG2_5750_PLUS;
 
@@ -12046,6 +11931,18 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
            (tp->tg3_flags2 & TG3_FLG2_5750_PLUS))
                tp->tg3_flags2 |= TG3_FLG2_5705_PLUS;
 
+       /* 5700 B0 chips do not support checksumming correctly due
+        * to hardware bugs.
+        */
+       if (tp->pci_chip_rev_id == CHIPREV_ID_5700_B0)
+               tp->tg3_flags |= TG3_FLAG_BROKEN_CHECKSUMS;
+       else {
+               tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS;
+               tp->dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
+               if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
+                       tp->dev->features |= NETIF_F_IPV6_CSUM;
+       }
+
        if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) {
                tp->tg3_flags |= TG3_FLAG_SUPPORT_MSI;
                if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_AX ||
@@ -12055,11 +11952,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                     tp->pdev_peer == tp->pdev))
                        tp->tg3_flags &= ~TG3_FLAG_SUPPORT_MSI;
 
-               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
-                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
-                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
-                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
-                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
+               if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) ||
                    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
                        tp->tg3_flags2 |= TG3_FLG2_HW_TSO_2;
                        tp->tg3_flags2 |= TG3_FLG2_1SHOT_MSI;
@@ -12076,21 +11969,42 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
             (tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
                tp->tg3_flags2 |= TG3_FLG2_JUMBO_CAPABLE;
 
-       pcie_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_EXP);
-       if (pcie_cap != 0) {
+       pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE,
+                             &pci_state_reg);
+
+       tp->pcie_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_EXP);
+       if (tp->pcie_cap != 0) {
+               u16 lnkctl;
+
                tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS;
 
                pcie_set_readrq(tp->pdev, 4096);
 
-               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
-                       u16 lnkctl;
-
-                       pci_read_config_word(tp->pdev,
-                                            pcie_cap + PCI_EXP_LNKCTL,
-                                            &lnkctl);
-                       if (lnkctl & PCI_EXP_LNKCTL_CLKREQ_EN)
+               pci_read_config_word(tp->pdev,
+                                    tp->pcie_cap + PCI_EXP_LNKCTL,
+                                    &lnkctl);
+               if (lnkctl & PCI_EXP_LNKCTL_CLKREQ_EN) {
+                       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
                                tp->tg3_flags2 &= ~TG3_FLG2_HW_TSO_2;
+                       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
+                           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
+                           tp->pci_chip_rev_id == CHIPREV_ID_57780_A0 ||
+                           tp->pci_chip_rev_id == CHIPREV_ID_57780_A1)
+                               tp->tg3_flags3 |= TG3_FLG3_CLKREQ_BUG;
+               }
+       } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785) {
+               tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS;
+       } else if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
+                  (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
+               tp->pcix_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_PCIX);
+               if (!tp->pcix_cap) {
+                       printk(KERN_ERR PFX "Cannot find PCI-X "
+                                           "capability, aborting.\n");
+                       return -EIO;
                }
+
+               if (!(pci_state_reg & PCISTATE_CONV_PCI_MODE))
+                       tp->tg3_flags |= TG3_FLAG_PCIX_MODE;
        }
 
        /* If we have an AMD 762 or VIA K8T800 chipset, write
@@ -12103,42 +12017,29 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
            !(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS))
                tp->tg3_flags |= TG3_FLAG_MBOX_WRITE_REORDER;
 
+       pci_read_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE,
+                            &tp->pci_cacheline_sz);
+       pci_read_config_byte(tp->pdev, PCI_LATENCY_TIMER,
+                            &tp->pci_lat_timer);
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 &&
            tp->pci_lat_timer < 64) {
                tp->pci_lat_timer = 64;
-
-               cacheline_sz_reg  = ((tp->pci_cacheline_sz & 0xff) <<  0);
-               cacheline_sz_reg |= ((tp->pci_lat_timer    & 0xff) <<  8);
-               cacheline_sz_reg |= ((tp->pci_hdr_type     & 0xff) << 16);
-               cacheline_sz_reg |= ((tp->pci_bist         & 0xff) << 24);
-
-               pci_write_config_dword(tp->pdev, TG3PCI_CACHELINESZ,
-                                      cacheline_sz_reg);
-       }
-
-       if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
-           (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
-               tp->pcix_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_PCIX);
-               if (!tp->pcix_cap) {
-                       printk(KERN_ERR PFX "Cannot find PCI-X "
-                                           "capability, aborting.\n");
-                       return -EIO;
-               }
+               pci_write_config_byte(tp->pdev, PCI_LATENCY_TIMER,
+                                     tp->pci_lat_timer);
        }
 
-       pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE,
-                             &pci_state_reg);
-
-       if (tp->pcix_cap && (pci_state_reg & PCISTATE_CONV_PCI_MODE) == 0) {
-               tp->tg3_flags |= TG3_FLAG_PCIX_MODE;
+       if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5700_BX) {
+               /* 5700 BX chips need to have their TX producer index
+                * mailboxes written twice to workaround a bug.
+                */
+               tp->tg3_flags |= TG3_FLAG_TXD_MBOX_HWBUG;
 
-               /* If this is a 5700 BX chipset, and we are in PCI-X
-                * mode, enable register write workaround.
+               /* If we are in PCI-X mode, enable register write workaround.
                 *
                 * The workaround is to use indirect register accesses
                 * for all chip writes not to mailbox registers.
                 */
-               if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5700_BX) {
+               if (tp->tg3_flags & TG3_FLAG_PCIX_MODE) {
                        u32 pm_reg;
 
                        tp->tg3_flags |= TG3_FLAG_PCIX_TARGET_HWBUG;
@@ -12163,12 +12064,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                }
        }
 
-       /* 5700 BX chips need to have their TX producer index mailboxes
-        * written twice to workaround a bug.
-        */
-       if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5700_BX)
-               tp->tg3_flags |= TG3_FLAG_TXD_MBOX_HWBUG;
-
        if ((pci_state_reg & PCISTATE_BUS_SPEED_HIGH) != 0)
                tp->tg3_flags |= TG3_FLAG_PCI_HIGH_SPEED;
        if ((pci_state_reg & PCISTATE_BUS_32BIT) != 0)
@@ -12263,16 +12158,10 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785) {
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
                tp->tg3_flags |= TG3_FLAG_CPMU_PRESENT;
 
-               if (tp->pci_chip_rev_id == CHIPREV_ID_5784_A0 ||
-                   tp->pci_chip_rev_id == CHIPREV_ID_5784_A1 ||
-                   tp->pci_chip_rev_id == CHIPREV_ID_5761_A0 ||
-                   tp->pci_chip_rev_id == CHIPREV_ID_5761_A1)
-                       tp->tg3_flags3 |= TG3_FLG3_5761_5784_AX_FIXES;
-       }
-
        /* Set up tp->grc_local_ctrl before calling tg3_set_power_state().
         * GPIO1 driven high will bring 5700's external PHY out of reset.
         * It is also used as eeprom write protect on LOMs.
@@ -12288,10 +12177,12 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752)
                tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE3;
 
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755)
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
                tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL;
 
-       if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761) {
+       if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761 ||
+           tp->pdev->device == TG3PCI_DEVICE_TIGON3_5761S) {
                /* Turn off the debug UART. */
                tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL;
                if (tp->tg3_flags2 & TG3_FLG2_IS_NIC)
@@ -12308,12 +12199,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                return err;
        }
 
-       /* 5700 B0 chips do not support checksumming correctly due
-        * to hardware bugs.
-        */
-       if (tp->pci_chip_rev_id == CHIPREV_ID_5700_B0)
-               tp->tg3_flags |= TG3_FLAG_BROKEN_CHECKSUMS;
-
        /* Derive initial jumbo mode from MTU assigned in
         * ether_setup() via the alloc_etherdev() call
         */
@@ -12346,7 +12231,10 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        if (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0)
                tp->tg3_flags2 |= TG3_FLG2_PHY_5704_A0_BUG;
 
-       if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
+       if ((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
+           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906 &&
+           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785 &&
+           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57780) {
                if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
                    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
                    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
@@ -12356,8 +12244,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                                tp->tg3_flags2 |= TG3_FLG2_PHY_JITTER_BUG;
                        if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5755M)
                                tp->tg3_flags2 |= TG3_FLG2_PHY_ADJUST_TRIM;
-               } else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906 &&
-                          GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785)
+               } else
                        tp->tg3_flags2 |= TG3_FLG2_PHY_BER_BUG;
        }
 
@@ -12378,7 +12265,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
            GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_BX)
                tp->coalesce_mode |= HOSTCC_MODE_32BYTE;
 
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
+       if (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_USE_PHYLIB;
 
        err = tg3_mdio_init(tp);
@@ -12463,6 +12351,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
             (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5751F ||
              tp->pdev->device == PCI_DEVICE_ID_TIGON3_5753F ||
              tp->pdev->device == PCI_DEVICE_ID_TIGON3_5787F)) ||
+           tp->pdev->device == TG3PCI_DEVICE_TIGON3_57790 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
                tp->tg3_flags |= TG3_FLAG_10_100_ONLY;
 
@@ -12512,20 +12401,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        else
                tp->tg3_flags &= ~TG3_FLAG_POLL_SERDES;
 
-       /* All chips before 5787 can get confused if TX buffers
-        * straddle the 4GB address boundary in some cases.
-        */
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
-               tp->dev->hard_start_xmit = tg3_start_xmit;
-       else
-               tp->dev->hard_start_xmit = tg3_start_xmit_dma_bug;
-
-       tp->rx_offset = 2;
+       tp->rx_offset = NET_IP_ALIGN;
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 &&
            (tp->tg3_flags & TG3_FLAG_PCIX_MODE) != 0)
                tp->rx_offset = 0;
@@ -12616,14 +12492,11 @@ static int __devinit tg3_get_device_address(struct tg3 *tp)
        }
        if (!addr_ok) {
                /* Next, try NVRAM. */
-               if (!tg3_nvram_read(tp, mac_offset + 0, &hi) &&
-                   !tg3_nvram_read(tp, mac_offset + 4, &lo)) {
-                       dev->dev_addr[0] = ((hi >> 16) & 0xff);
-                       dev->dev_addr[1] = ((hi >> 24) & 0xff);
-                       dev->dev_addr[2] = ((lo >>  0) & 0xff);
-                       dev->dev_addr[3] = ((lo >>  8) & 0xff);
-                       dev->dev_addr[4] = ((lo >> 16) & 0xff);
-                       dev->dev_addr[5] = ((lo >> 24) & 0xff);
+               if (!(tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) &&
+                   !tg3_nvram_read_be32(tp, mac_offset + 0, &hi) &&
+                   !tg3_nvram_read_be32(tp, mac_offset + 4, &lo)) {
+                       memcpy(&dev->dev_addr[0], ((char *)&hi) + 2, 2);
+                       memcpy(&dev->dev_addr[2], (char *)&lo, sizeof(lo));
                }
                /* Finally just fetch it out of the MAC control regs. */
                else {
@@ -13241,18 +13114,53 @@ static void __devinit tg3_init_coal(struct tg3 *tp)
        }
 }
 
+static const struct net_device_ops tg3_netdev_ops = {
+       .ndo_open               = tg3_open,
+       .ndo_stop               = tg3_close,
+       .ndo_start_xmit         = tg3_start_xmit,
+       .ndo_get_stats          = tg3_get_stats,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_multicast_list = tg3_set_rx_mode,
+       .ndo_set_mac_address    = tg3_set_mac_addr,
+       .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
+};
+
+static const struct net_device_ops tg3_netdev_ops_dma_bug = {
+       .ndo_open               = tg3_open,
+       .ndo_stop               = tg3_close,
+       .ndo_start_xmit         = tg3_start_xmit_dma_bug,
+       .ndo_get_stats          = tg3_get_stats,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_multicast_list = tg3_set_rx_mode,
+       .ndo_set_mac_address    = tg3_set_mac_addr,
+       .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
+};
+
 static int __devinit tg3_init_one(struct pci_dev *pdev,
                                  const struct pci_device_id *ent)
 {
        static int tg3_version_printed = 0;
-       resource_size_t tg3reg_base;
-       unsigned long tg3reg_len;
        struct net_device *dev;
        struct tg3 *tp;
        int err, pm_cap;
        char str[40];
        u64 dma_mask, persist_dma_mask;
-       DECLARE_MAC_BUF(mac);
 
        if (tg3_version_printed++ == 0)
                printk(KERN_INFO "%s", version);
@@ -13264,13 +13172,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
                return err;
        }
 
-       if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
-               printk(KERN_ERR PFX "Cannot find proper PCI device "
-                      "base address, aborting.\n");
-               err = -ENODEV;
-               goto err_out_disable_pdev;
-       }
-
        err = pci_request_regions(pdev, DRV_MODULE_NAME);
        if (err) {
                printk(KERN_ERR PFX "Cannot obtain PCI resources, "
@@ -13289,9 +13190,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
                goto err_out_free_res;
        }
 
-       tg3reg_base = pci_resource_start(pdev, 0);
-       tg3reg_len = pci_resource_len(pdev, 0);
-
        dev = alloc_etherdev(sizeof(*tp));
        if (!dev) {
                printk(KERN_ERR PFX "Etherdev alloc failed, aborting.\n");
@@ -13303,7 +13201,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
 
 #if TG3_VLAN_TAG_USED
        dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-       dev->vlan_rx_register = tg3_vlan_rx_register;
 #endif
 
        tp = netdev_priv(dev);
@@ -13343,7 +13240,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
        spin_lock_init(&tp->indirect_lock);
        INIT_WORK(&tp->reset_task, tg3_reset_task);
 
-       tp->regs = ioremap_nocache(tg3reg_base, tg3reg_len);
+       tp->regs = pci_ioremap_bar(pdev, BAR_0);
        if (!tp->regs) {
                printk(KERN_ERR PFX "Cannot map device registers, "
                       "aborting.\n");
@@ -13357,21 +13254,10 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
        tp->rx_jumbo_pending = TG3_DEF_RX_JUMBO_RING_PENDING;
        tp->tx_pending = TG3_DEF_TX_RING_PENDING;
 
-       dev->open = tg3_open;
-       dev->stop = tg3_close;
-       dev->get_stats = tg3_get_stats;
-       dev->set_multicast_list = tg3_set_rx_mode;
-       dev->set_mac_address = tg3_set_mac_addr;
-       dev->do_ioctl = tg3_ioctl;
-       dev->tx_timeout = tg3_tx_timeout;
        netif_napi_add(dev, &tp->napi, tg3_poll, 64);
        dev->ethtool_ops = &tg3_ethtool_ops;
        dev->watchdog_timeo = TG3_TX_TIMEOUT;
-       dev->change_mtu = tg3_change_mtu;
        dev->irq = pdev->irq;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       dev->poll_controller = tg3_poll_controller;
-#endif
 
        err = tg3_get_invariants(tp);
        if (err) {
@@ -13380,6 +13266,13 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
                goto err_out_iounmap;
        }
 
+       if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+               dev->netdev_ops = &tg3_netdev_ops;
+       else
+               dev->netdev_ops = &tg3_netdev_ops_dma_bug;
+
+
        /* The EPB bridge inside 5714, 5715, and 5780 and any
         * device behind the EPB cannot support DMA addresses > 40-bit.
         * On 64-bit systems with IOMMU, use 40-bit dma_mask.
@@ -13387,17 +13280,17 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
         * do DMA address check in tg3_start_xmit().
         */
        if (tp->tg3_flags2 & TG3_FLG2_IS_5788)
-               persist_dma_mask = dma_mask = DMA_32BIT_MASK;
+               persist_dma_mask = dma_mask = DMA_BIT_MASK(32);
        else if (tp->tg3_flags & TG3_FLAG_40BIT_DMA_BUG) {
-               persist_dma_mask = dma_mask = DMA_40BIT_MASK;
+               persist_dma_mask = dma_mask = DMA_BIT_MASK(40);
 #ifdef CONFIG_HIGHMEM
-               dma_mask = DMA_64BIT_MASK;
+               dma_mask = DMA_BIT_MASK(64);
 #endif
        } else
-               persist_dma_mask = dma_mask = DMA_64BIT_MASK;
+               persist_dma_mask = dma_mask = DMA_BIT_MASK(64);
 
        /* Configure DMA attributes. */
-       if (dma_mask > DMA_32BIT_MASK) {
+       if (dma_mask > DMA_BIT_MASK(32)) {
                err = pci_set_dma_mask(pdev, dma_mask);
                if (!err) {
                        dev->features |= NETIF_F_HIGHDMA;
@@ -13410,8 +13303,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
                        }
                }
        }
-       if (err || dma_mask == DMA_32BIT_MASK) {
-               err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+       if (err || dma_mask == DMA_BIT_MASK(32)) {
+               err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
                if (err) {
                        printk(KERN_ERR PFX "No usable DMA configuration, "
                               "aborting.\n");
@@ -13421,6 +13314,9 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
 
        tg3_init_bufmgr_config(tp);
 
+       if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0)
+               tp->fw_needed = FIRMWARE_TG3;
+
        if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) {
                tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
        }
@@ -13432,6 +13328,10 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
                tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE;
        } else {
                tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE | TG3_FLG2_TSO_BUG;
+               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)
+                       tp->fw_needed = FIRMWARE_TG3TSO5;
+               else
+                       tp->fw_needed = FIRMWARE_TG3TSO;
        }
 
        /* TSO is on by default on chips that support hardware TSO.
@@ -13439,14 +13339,16 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
         * is off by default, but can be enabled using ethtool.
         */
        if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) {
-               dev->features |= NETIF_F_TSO;
-               if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) &&
-                   (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906))
+               if (dev->features & NETIF_F_IP_CSUM)
+                       dev->features |= NETIF_F_TSO;
+               if ((dev->features & NETIF_F_IPV6_CSUM) &&
+                   (tp->tg3_flags2 & TG3_FLG2_HW_TSO_2))
                        dev->features |= NETIF_F_TSO6;
                if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
                    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
                     GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX) ||
-                       GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
+                       GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
+                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
                        dev->features |= NETIF_F_TSO_ECN;
        }
 
@@ -13462,29 +13364,22 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
        if (err) {
                printk(KERN_ERR PFX "Could not obtain valid ethernet address, "
                       "aborting.\n");
-               goto err_out_iounmap;
+               goto err_out_fw;
        }
 
        if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
-               if (!(pci_resource_flags(pdev, 2) & IORESOURCE_MEM)) {
-                       printk(KERN_ERR PFX "Cannot find proper PCI device "
-                              "base address for APE, aborting.\n");
-                       err = -ENODEV;
-                       goto err_out_iounmap;
-               }
-
-               tg3reg_base = pci_resource_start(pdev, 2);
-               tg3reg_len = pci_resource_len(pdev, 2);
-
-               tp->aperegs = ioremap_nocache(tg3reg_base, tg3reg_len);
+               tp->aperegs = pci_ioremap_bar(pdev, BAR_2);
                if (!tp->aperegs) {
                        printk(KERN_ERR PFX "Cannot map APE registers, "
                               "aborting.\n");
                        err = -ENOMEM;
-                       goto err_out_iounmap;
+                       goto err_out_fw;
                }
 
                tg3_ape_lock_init(tp);
+
+               if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF)
+                       tg3_read_dash_ver(tp);
        }
 
        /*
@@ -13504,25 +13399,9 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
                goto err_out_apeunmap;
        }
 
-       /* Tigon3 can do ipv4 only... and some chips have buggy
-        * checksumming.
-        */
-       if ((tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) == 0) {
-               dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
-               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
-                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
-                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
-                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
-                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
-                       dev->features |= NETIF_F_IPV6_CSUM;
-
-               tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS;
-       } else
-               tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS;
-
        /* flow control autonegotiation is default behavior */
        tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
-       tp->link_config.flowctrl = TG3_FLOW_CTRL_TX | TG3_FLOW_CTRL_RX;
+       tp->link_config.flowctrl = FLOW_CTRL_TX | FLOW_CTRL_RX;
 
        tg3_init_coal(tp);
 
@@ -13535,31 +13414,39 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
                goto err_out_apeunmap;
        }
 
-       printk(KERN_INFO "%s: Tigon3 [partno(%s) rev %04x PHY(%s)] "
-              "(%s) %s Ethernet %s\n",
+       printk(KERN_INFO "%s: Tigon3 [partno(%s) rev %04x] (%s) MAC address %pM\n",
               dev->name,
               tp->board_part_number,
               tp->pci_chip_rev_id,
-              tg3_phy_string(tp),
               tg3_bus_string(tp, str),
-              ((tp->tg3_flags & TG3_FLAG_10_100_ONLY) ? "10/100Base-TX" :
-               ((tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) ? "1000Base-SX" :
-                "10/100/1000Base-T")),
-              print_mac(mac, dev->dev_addr));
+              dev->dev_addr);
 
-       printk(KERN_INFO "%s: RXcsums[%d] LinkChgREG[%d] "
-              "MIirq[%d] ASF[%d] WireSpeed[%d] TSOcap[%d]\n",
+       if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED)
+               printk(KERN_INFO
+                      "%s: attached PHY driver [%s] (mii_bus:phy_addr=%s)\n",
+                      tp->dev->name,
+                      tp->mdio_bus->phy_map[PHY_ADDR]->drv->name,
+                      dev_name(&tp->mdio_bus->phy_map[PHY_ADDR]->dev));
+       else
+               printk(KERN_INFO
+                      "%s: attached PHY is %s (%s Ethernet) (WireSpeed[%d])\n",
+                      tp->dev->name, 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);
+
+       printk(KERN_INFO "%s: RXcsums[%d] LinkChgREG[%d] MIirq[%d] ASF[%d] TSOcap[%d]\n",
               dev->name,
               (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->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0,
-              (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) == 0,
               (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) != 0);
        printk(KERN_INFO "%s: dma_rwctrl[%08x] dma_mask[%d-bit]\n",
               dev->name, tp->dma_rwctrl,
-              (pdev->dma_mask == DMA_32BIT_MASK) ? 32 :
-               (((u64) pdev->dma_mask == DMA_40BIT_MASK) ? 40 : 64));
+              (pdev->dma_mask == DMA_BIT_MASK(32)) ? 32 :
+               (((u64) pdev->dma_mask == DMA_BIT_MASK(40)) ? 40 : 64));
 
        return 0;
 
@@ -13569,6 +13456,10 @@ err_out_apeunmap:
                tp->aperegs = NULL;
        }
 
+err_out_fw:
+       if (tp->fw)
+               release_firmware(tp->fw);
+
 err_out_iounmap:
        if (tp->regs) {
                iounmap(tp->regs);
@@ -13594,6 +13485,9 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev)
        if (dev) {
                struct tg3 *tp = netdev_priv(dev);
 
+               if (tp->fw)
+                       release_firmware(tp->fw);
+
                flush_scheduled_work();
 
                if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {