]> xenbits.xensource.com Git - people/ssmith/nc2-2.6.27.git/commitdiff
patch tg3-3.92n
authorSteven Smith <ssmith@weybridge.uk.xensource.com>
Tue, 30 Jun 2009 11:55:48 +0000 (12:55 +0100)
committerSteven Smith <ssmith@weybridge.uk.xensource.com>
Tue, 30 Jun 2009 11:55:48 +0000 (12:55 +0100)
drivers/net/Makefile
drivers/net/tg3.c
drivers/net/tg3.h
drivers/net/tg3_compat.h [new file with mode: 0644]
drivers/net/tg3_flags.h [new file with mode: 0644]

index 13d9a33a6d9a66be77ae78b892451a56967ce2a8..d163ecaacfa5ec477f286c5fc94cbf359f594398 100644 (file)
@@ -66,6 +66,7 @@ obj-$(CONFIG_NS83820) += ns83820.o
 obj-$(CONFIG_STNIC) += stnic.o 8390.o
 obj-$(CONFIG_FEALNX) += fealnx.o
 obj-$(CONFIG_TIGON3) += tg3.o
+CFLAGS_tg3.o += -DBCM_HAS_PRINT_MAC
 obj-$(CONFIG_BNX2) += bnx2.o
 obj-$(CONFIG_BNX2X) += bnx2x.o
 bnx2x-objs := bnx2x_main.o bnx2x_link.o
index 067e50090bcdb2adcbe554cb3012e9e22c551887..6d5f007a6dc79ba9aee64a3c5239ead2a9fd9a7e 100644 (file)
  *     notice is accompanying it.
  */
 
+#include <linux/version.h>
 
+#if (LINUX_VERSION_CODE < 0x020612)
+#include <linux/config.h>
+#endif
+
+#if (LINUX_VERSION_CODE < 0x020500)
+#if defined(CONFIG_MODVERSIONS) && defined(MODULE) && ! defined(MODVERSIONS)
+#define MODVERSIONS
+#include <linux/modversions.h>
+#endif
+#endif
 #include <linux/module.h>
+#if (LINUX_VERSION_CODE >= 0x20600)
 #include <linux/moduleparam.h>
+#endif
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/compiler.h>
 #include <linux/skbuff.h>
 #include <linux/ethtool.h>
 #include <linux/mii.h>
-#include <linux/phy.h>
-#include <linux/brcmphy.h>
 #include <linux/if_vlan.h>
 #include <linux/ip.h>
 #include <linux/tcp.h>
+#if (LINUX_VERSION_CODE >= 0x20600)
 #include <linux/workqueue.h>
+#endif
 #include <linux/prefetch.h>
+#if (LINUX_VERSION_CODE >= 0x020600)
 #include <linux/dma-mapping.h>
+#endif
+#include <linux/bitops.h>
 
 #include <net/checksum.h>
 #include <net/ip.h>
 #define TG3_VLAN_TAG_USED 0
 #endif
 
+#ifdef NETIF_F_TSO
 #define TG3_TSO_SUPPORT        1
+#else
+#define TG3_TSO_SUPPORT        0
+#endif
 
 #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.92n"
+#define DRV_MODULE_RELDATE     "September 29, 2008"
+
+/* The driver optimizes the hot rx code path by merging a mandatory rx double
+ * copy check with the normal double copy rx threshold check.  On those
+ * architectures where the mandatory double copy is not needed, we can optimize
+ * further by saving a device structure dereference and hardcoding the double
+ * copy threshold in place.
+ */
+#if NET_IP_ALIGN == 0 || defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
+       #define TG3_RX_COPY_THRESH(tp)  RX_COPY_THRESHOLD
+#else
+       #define TG3_RX_COPY_THRESH(tp)  ((tp)->rx_copy_thresh)
+#endif
+
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
                                 TG3_TX_RING_SIZE)
 #define NEXT_TX(N)             (((N) + 1) & (TG3_TX_RING_SIZE - 1))
 
-#define RX_PKT_BUF_SZ          (1536 + tp->rx_offset + 64)
-#define RX_JUMBO_PKT_BUF_SZ    (9046 + tp->rx_offset + 64)
+#define RX_PKT_BUF_SZ          (1536 + 64)
+#define RX_JUMBO_PKT_BUF_SZ    (9046 + 64)
 
 /* 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))
 
@@ -143,8 +178,10 @@ MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_MODULE_VERSION);
 
 static int tg3_debug = -1;     /* -1 == use TG3_DEF_MSG_ENABLE as value */
+#if (LINUX_VERSION_CODE >= 0x20600)
 module_param(tg3_debug, int, 0);
 MODULE_PARM_DESC(tg3_debug, "Tigon3 bitmapped debugging message enable value");
+#endif
 
 static struct pci_device_id tg3_pci_tbl[] = {
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5700)},
@@ -205,10 +242,8 @@ 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_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_BROADCOM, PCI_DEVICE_ID_TIGON3_5761S)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5761SE)},
        {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)},
@@ -664,7 +699,11 @@ static void tg3_restart_ints(struct tg3 *tp)
 static inline void tg3_netif_stop(struct tg3 *tp)
 {
        tp->dev->trans_start = jiffies; /* prevent tx timeout */
+#ifdef TG3_NAPI
        napi_disable(&tp->napi);
+#else
+       netif_poll_disable(tp->dev);
+#endif
        netif_tx_disable(tp->dev);
 }
 
@@ -675,7 +714,11 @@ static inline void tg3_netif_start(struct tg3 *tp)
         * so long as all callers are assured to have free tx slots
         * (such as after tg3_init_hw)
         */
+#ifdef TG3_NAPI
        napi_enable(&tp->napi);
+#else
+       netif_poll_enable(tp->dev);
+#endif
        tp->hw_status->status |= SD_STATUS_UPDATED;
        tg3_enable_ints(tp);
 }
@@ -843,192 +886,6 @@ static int tg3_bmcr_reset(struct tg3 *tp)
        return 0;
 }
 
-static int tg3_mdio_read(struct mii_bus *bp, int mii_id, int reg)
-{
-       struct tg3 *tp = (struct tg3 *)bp->priv;
-       u32 val;
-
-       if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED)
-               return -EAGAIN;
-
-       if (tg3_readphy(tp, reg, &val))
-               return -EIO;
-
-       return val;
-}
-
-static int tg3_mdio_write(struct mii_bus *bp, int mii_id, int reg, u16 val)
-{
-       struct tg3 *tp = (struct tg3 *)bp->priv;
-
-       if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED)
-               return -EAGAIN;
-
-       if (tg3_writephy(tp, reg, val))
-               return -EIO;
-
-       return 0;
-}
-
-static int tg3_mdio_reset(struct mii_bus *bp)
-{
-       return 0;
-}
-
-static void tg3_mdio_config(struct tg3 *tp)
-{
-       u32 val;
-
-       if (tp->mdio_bus.phy_map[PHY_ADDR]->interface !=
-           PHY_INTERFACE_MODE_RGMII)
-               return;
-
-       val = tr32(MAC_PHYCFG1) & ~(MAC_PHYCFG1_RGMII_EXT_RX_DEC |
-                                   MAC_PHYCFG1_RGMII_SND_STAT_EN);
-       if (tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE) {
-               if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_RX_EN)
-                       val |= MAC_PHYCFG1_RGMII_EXT_RX_DEC;
-               if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_TX_EN)
-                       val |= MAC_PHYCFG1_RGMII_SND_STAT_EN;
-       }
-       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 |
-                MAC_RGMII_MODE_RX_ACTIVITY |
-                MAC_RGMII_MODE_RX_ENG_DET |
-                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_EXT_IBND_RX_EN)
-                       val |= MAC_RGMII_MODE_RX_INT_B |
-                              MAC_RGMII_MODE_RX_QUALITY |
-                              MAC_RGMII_MODE_RX_ACTIVITY |
-                              MAC_RGMII_MODE_RX_ENG_DET;
-               if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_TX_EN)
-                       val |= MAC_RGMII_MODE_TX_ENABLE |
-                              MAC_RGMII_MODE_TX_LOWPWR |
-                              MAC_RGMII_MODE_TX_RESET;
-       }
-       tw32(MAC_EXT_RGMII_MODE, val);
-}
-
-static void tg3_mdio_start(struct tg3 *tp)
-{
-       if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) {
-               mutex_lock(&tp->mdio_bus.mdio_lock);
-               tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_PAUSED;
-               mutex_unlock(&tp->mdio_bus.mdio_lock);
-       }
-
-       tp->mi_mode &= ~MAC_MI_MODE_AUTO_POLL;
-       tw32_f(MAC_MI_MODE, tp->mi_mode);
-       udelay(80);
-
-       if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED)
-               tg3_mdio_config(tp);
-}
-
-static void tg3_mdio_stop(struct tg3 *tp)
-{
-       if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) {
-               mutex_lock(&tp->mdio_bus.mdio_lock);
-               tp->tg3_flags3 |= TG3_FLG3_MDIOBUS_PAUSED;
-               mutex_unlock(&tp->mdio_bus.mdio_lock);
-       }
-}
-
-static int tg3_mdio_init(struct tg3 *tp)
-{
-       int i;
-       u32 reg;
-       struct phy_device *phydev;
-       struct mii_bus *mdio_bus = &tp->mdio_bus;
-
-       tg3_mdio_start(tp);
-
-       if (!(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) ||
-           (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED))
-               return 0;
-
-       memset(mdio_bus, 0, sizeof(*mdio_bus));
-
-       mdio_bus->name     = "tg3 mdio bus";
-       snprintf(mdio_bus->id, MII_BUS_ID_SIZE, "%x",
-                (tp->pdev->bus->number << 8) | tp->pdev->devfn);
-       mdio_bus->priv     = tp;
-       mdio_bus->dev      = &tp->pdev->dev;
-       mdio_bus->read     = &tg3_mdio_read;
-       mdio_bus->write    = &tg3_mdio_write;
-       mdio_bus->reset    = &tg3_mdio_reset;
-       mdio_bus->phy_mask = ~(1 << PHY_ADDR);
-       mdio_bus->irq      = &tp->mdio_irq[0];
-
-       for (i = 0; i < PHY_MAX_ADDR; i++)
-               mdio_bus->irq[i] = PHY_POLL;
-
-       /* The bus registration will look for all the PHYs on the mdio bus.
-        * Unfortunately, it does not ensure the PHY is powered up before
-        * accessing the PHY ID registers.  A chip reset is the
-        * quickest way to bring the device back to an operational state..
-        */
-       if (tg3_readphy(tp, MII_BMCR, &reg) || (reg & BMCR_PDOWN))
-               tg3_bmcr_reset(tp);
-
-       i = mdiobus_register(mdio_bus);
-       if (i) {
-               printk(KERN_WARNING "%s: mdiobus_reg failed (0x%x)\n",
-                       tp->dev->name, i);
-               return i;
-       }
-
-       tp->tg3_flags3 |= TG3_FLG3_MDIOBUS_INITED;
-
-       phydev = tp->mdio_bus.phy_map[PHY_ADDR];
-
-if(!phydev || !phydev->drv)
-       return -1;
-
-       switch (phydev->drv->phy_id & phydev->drv->phy_id_mask) {
-       case TG3_PHY_ID_BCM57780:
-               phydev->interface = PHY_INTERFACE_MODE_GMII;
-               phydev->dev_flags = PHY_BRCM_WIRESPEED_ENABLE;
-               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;
-               break;
-       case TG3_PHY_ID_BCMAC131:
-               phydev->interface = PHY_INTERFACE_MODE_MII;
-               break;
-       }
-
-       tg3_mdio_config(tp);
-
-       return 0;
-}
-
-static void tg3_mdio_fini(struct tg3 *tp)
-{
-       if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) {
-               tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_INITED;
-               mdiobus_unregister(&tp->mdio_bus);
-               tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_PAUSED;
-       }
-}
-
 /* tp->lock is held. */
 static inline void tg3_generate_fw_event(struct tg3 *tp)
 {
@@ -1229,10 +1086,7 @@ static void tg3_setup_flow_control(struct tg3 *tp, u32 lcladv, u32 rmtadv)
        u32 old_rx_mode = tp->rx_mode;
        u32 old_tx_mode = tp->tx_mode;
 
-       if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)
-               autoneg = tp->mdio_bus.phy_map[PHY_ADDR]->autoneg;
-       else
-               autoneg = tp->link_config.autoneg;
+       autoneg = tp->link_config.autoneg;
 
        if (autoneg == AUTONEG_ENABLE &&
            (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG)) {
@@ -1262,156 +1116,38 @@ static void tg3_setup_flow_control(struct tg3 *tp, u32 lcladv, u32 rmtadv)
                tw32_f(MAC_TX_MODE, tp->tx_mode);
 }
 
-static void tg3_adjust_link(struct net_device *dev)
-{
-       u8 oldflowctrl, linkmesg = 0;
-       u32 mac_mode, lcl_adv, rmt_adv;
-       struct tg3 *tp = netdev_priv(dev);
-       struct phy_device *phydev = tp->mdio_bus.phy_map[PHY_ADDR];
-
-       spin_lock(&tp->lock);
-
-       mac_mode = tp->mac_mode & ~(MAC_MODE_PORT_MODE_MASK |
-                                   MAC_MODE_HALF_DUPLEX);
-
-       oldflowctrl = tp->link_config.active_flowctrl;
-
-       if (phydev->link) {
-               lcl_adv = 0;
-               rmt_adv = 0;
-
-               if (phydev->speed == SPEED_100 || phydev->speed == SPEED_10)
-                       mac_mode |= MAC_MODE_PORT_MODE_MII;
-               else
-                       mac_mode |= MAC_MODE_PORT_MODE_GMII;
-
-               if (phydev->duplex == DUPLEX_HALF)
-                       mac_mode |= MAC_MODE_HALF_DUPLEX;
-               else {
-                       lcl_adv = tg3_advert_flowctrl_1000T(
-                                 tp->link_config.flowctrl);
-
-                       if (phydev->pause)
-                               rmt_adv = LPA_PAUSE_CAP;
-                       if (phydev->asym_pause)
-                               rmt_adv |= LPA_PAUSE_ASYM;
-               }
-
-               tg3_setup_flow_control(tp, lcl_adv, rmt_adv);
-       } else
-               mac_mode |= MAC_MODE_PORT_MODE_GMII;
-
-       if (mac_mode != tp->mac_mode) {
-               tp->mac_mode = mac_mode;
-               tw32_f(MAC_MODE, tp->mac_mode);
-               udelay(40);
-       }
-
-       if (phydev->speed == SPEED_1000 && phydev->duplex == DUPLEX_HALF)
-               tw32(MAC_TX_LENGTHS,
-                    ((2 << TX_LENGTHS_IPG_CRS_SHIFT) |
-                     (6 << TX_LENGTHS_IPG_SHIFT) |
-                     (0xff << TX_LENGTHS_SLOT_TIME_SHIFT)));
-       else
-               tw32(MAC_TX_LENGTHS,
-                    ((2 << TX_LENGTHS_IPG_CRS_SHIFT) |
-                     (6 << TX_LENGTHS_IPG_SHIFT) |
-                     (32 << TX_LENGTHS_SLOT_TIME_SHIFT)));
-
-       if ((phydev->link && tp->link_config.active_speed == SPEED_INVALID) ||
-           (!phydev->link && tp->link_config.active_speed != SPEED_INVALID) ||
-           phydev->speed != tp->link_config.active_speed ||
-           phydev->duplex != tp->link_config.active_duplex ||
-           oldflowctrl != tp->link_config.active_flowctrl)
-           linkmesg = 1;
-
-       tp->link_config.active_speed = phydev->speed;
-       tp->link_config.active_duplex = phydev->duplex;
-
-       spin_unlock(&tp->lock);
-
-       if (linkmesg)
-               tg3_link_report(tp);
-}
-
-static int tg3_phy_init(struct tg3 *tp)
+static void tg3_phydsp_write(struct tg3 *tp, u32 reg, u32 val)
 {
-       struct phy_device *phydev;
-
-       if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED)
-               return 0;
-
-       /* Bring the PHY back to a known state. */
-       tg3_bmcr_reset(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->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);
-
-       phydev->advertising = phydev->supported;
-
-       printk(KERN_INFO
-              "%s: attached PHY driver [%s] (mii_bus:phy_addr=%s)\n",
-              tp->dev->name, phydev->drv->name, phydev->dev.bus_id);
-
-       return 0;
+       tg3_writephy(tp, MII_TG3_DSP_ADDRESS, reg);
+       tg3_writephy(tp, MII_TG3_DSP_RW_PORT, val);
 }
 
-static void tg3_phy_start(struct tg3 *tp)
+static void tg3_phy_toggle_apd(struct tg3 *tp, int enable)
 {
-       struct phy_device *phydev;
+       u32 reg;
 
-       if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
+       if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
                return;
 
-       phydev = tp->mdio_bus.phy_map[PHY_ADDR];
+       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;
 
-       if (tp->link_config.phy_is_low_power) {
-               tp->link_config.phy_is_low_power = 0;
-               phydev->speed = tp->link_config.orig_speed;
-               phydev->duplex = tp->link_config.orig_duplex;
-               phydev->autoneg = tp->link_config.orig_autoneg;
-               phydev->advertising = tp->link_config.orig_advertising;
-       }
+       tg3_writephy(tp, MII_TG3_MISC_SHDW, reg);
 
-       phy_start(phydev);
 
-       phy_start_aneg(phydev);
-}
+       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;
 
-static void tg3_phy_stop(struct tg3 *tp)
-{
-       if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
-               return;
-
-       phy_stop(tp->mdio_bus.phy_map[PHY_ADDR]);
-}
-
-static void tg3_phy_fini(struct tg3 *tp)
-{
-       if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) {
-               phy_disconnect(tp->mdio_bus.phy_map[PHY_ADDR]);
-               tp->tg3_flags3 &= ~TG3_FLG3_PHY_CONNECTED;
-       }
-}
-
-static void tg3_phydsp_write(struct tg3 *tp, u32 reg, u32 val)
-{
-       tg3_writephy(tp, MII_TG3_DSP_ADDRESS, reg);
-       tg3_writephy(tp, MII_TG3_DSP_RW_PORT, val);
+       tg3_writephy(tp, MII_TG3_MISC_SHDW, reg);
 }
 
 static void tg3_phy_toggle_automdix(struct tg3 *tp, int enable)
@@ -1745,7 +1481,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);
@@ -1755,16 +1492,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, 1);
+       else
+               tg3_phy_toggle_apd(tp, 0);
+
 out:
        if (tp->tg3_flags2 & TG3_FLG2_PHY_ADC_BUG) {
                tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00);
@@ -1992,7 +1728,7 @@ 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 {
                tg3_writephy(tp, MII_TG3_EXT_CTRL,
                             MII_TG3_EXT_CTRL_FORCE_LED_OFF);
                tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2);
@@ -2007,7 +1743,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;
@@ -2017,9 +1754,48 @@ static void tg3_power_down_phy(struct tg3 *tp)
        tg3_writephy(tp, MII_BMCR, BMCR_PDOWN);
 }
 
+/* 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;
+       u16 power_control, power_caps;
+       int pm = tp->pm_cap;
 
        /* Make sure register accesses (indirect or otherwise)
         * will function correctly.
@@ -2028,10 +1804,18 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
                               TG3PCI_MISC_HOST_CTRL,
                               tp->misc_host_ctrl);
 
+       pci_read_config_word(tp->pdev,
+                            pm + PCI_PM_CTRL,
+                            &power_control);
+       power_control |= PCI_PM_CTRL_PME_STATUS;
+       power_control &= ~(PCI_PM_CTRL_STATE_MASK);
        switch (state) {
        case PCI_D0:
-               pci_enable_wake(tp->pdev, state, false);
-               pci_set_power_state(tp->pdev, PCI_D0);
+               power_control |= 0;
+               pci_write_config_word(tp->pdev,
+                                     pm + PCI_PM_CTRL,
+                                     power_control);
+               udelay(100);    /* Delay after power state change */
 
                /* Switch out of Vaux if it is a NIC */
                if (tp->tg3_flags2 & TG3_FLG2_IS_NIC)
@@ -2040,70 +1824,59 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
                return 0;
 
        case PCI_D1:
+               power_control |= 1;
+               break;
+
        case PCI_D2:
+               power_control |= 2;
+               break;
+
        case PCI_D3hot:
+               power_control |= 3;
                break;
 
        default:
-               printk(KERN_ERR PFX "%s: Invalid power state (D%d) requested\n",
-                       tp->dev->name, state);
+               printk(KERN_WARNING PFX "%s: Invalid power state (%d) "
+                      "requested.\n",
+                      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);
+       }
+
+       power_control |= PCI_PM_CTRL_PME_ENABLE;
+
        misc_host_ctrl = tr32(TG3PCI_MISC_HOST_CTRL);
        tw32(TG3PCI_MISC_HOST_CTRL,
             misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT);
 
-       if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
-               if ((tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) &&
-                   !tp->link_config.phy_is_low_power) {
-                       struct phy_device *phydev;
-                       u32 advertising;
-
-                       phydev = tp->mdio_bus.phy_map[PHY_ADDR];
-
-                       tp->link_config.phy_is_low_power = 1;
-
-                       tp->link_config.orig_speed = phydev->speed;
-                       tp->link_config.orig_duplex = phydev->duplex;
-                       tp->link_config.orig_autoneg = phydev->autoneg;
-                       tp->link_config.orig_advertising = phydev->advertising;
-
-                       advertising = ADVERTISED_TP |
-                                     ADVERTISED_Pause |
-                                     ADVERTISED_Autoneg |
-                                     ADVERTISED_10baseT_Half;
-
-                       if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
-                           (tp->tg3_flags & TG3_FLAG_WOL_ENABLE)) {
-                               if (tp->tg3_flags & TG3_FLAG_WOL_SPEED_100MB)
-                                       advertising |=
-                                               ADVERTISED_100baseT_Half |
-                                               ADVERTISED_100baseT_Full |
-                                               ADVERTISED_10baseT_Full;
-                               else
-                                       advertising |= ADVERTISED_10baseT_Full;
-                       }
-
-                       phydev->advertising = advertising;
-
-                       phy_start_aneg(phydev);
-               }
-       } else {
-               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;
-                       tp->link_config.orig_duplex = tp->link_config.duplex;
-                       tp->link_config.orig_autoneg = tp->link_config.autoneg;
-               }
+       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;
+               tp->link_config.orig_duplex = tp->link_config.duplex;
+               tp->link_config.orig_autoneg = tp->link_config.autoneg;
+       }
 
-               if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)) {
-                       tp->link_config.speed = SPEED_10;
-                       tp->link_config.duplex = DUPLEX_HALF;
-                       tp->link_config.autoneg = AUTONEG_ENABLE;
-                       tg3_setup_phy(tp, 0);
-               }
+       if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)) {
+               tp->link_config.speed = SPEED_10;
+               tp->link_config.duplex = DUPLEX_HALF;
+               tp->link_config.autoneg = AUTONEG_ENABLE;
+               tg3_setup_phy(tp, 0);
        }
 
+       __tg3_set_mac_addr(tp, 0);
+
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
                u32 val;
 
@@ -2117,7 +1890,12 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
                        tg3_read_mem(tp, NIC_SRAM_FW_ASF_STATUS_MBOX, &val);
                        if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1)
                                break;
+#if (LINUX_VERSION_CODE < 0x20607)
+                       set_current_state(TASK_UNINTERRUPTIBLE);
+                       schedule_timeout(HZ / 1000);
+#else
                        msleep(1);
+#endif
                }
        }
        if (tp->tg3_flags & TG3_FLAG_WOL_CAP)
@@ -2126,14 +1904,14 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
                                                     WOL_DRV_WOL |
                                                     WOL_SET_MAGIC_PKT);
 
+       pci_read_config_word(tp->pdev, pm + PCI_PM_PMC, &power_caps);
+
        if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE) {
                u32 mac_mode;
 
                if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) {
-                       if (!(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)) {
-                               tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x5a);
-                               udelay(40);
-                       }
+                       tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x5a);
+                       udelay(40);
 
                        if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)
                                mac_mode = MAC_MODE_PORT_MODE_GMII;
@@ -2158,11 +1936,17 @@ 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))
+               if (((power_caps & PCI_PM_CAP_PME_D3cold) &&
+                    (tp->tg3_flags & TG3_FLAG_WOL_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) {
+               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) {
                        mac_mode |= tp->mac_mode &
                                    (MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN);
                        if (mac_mode & MAC_MODE_APE_TX_EN)
@@ -2258,11 +2042,9 @@ 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)
-               pci_enable_wake(tp->pdev, state, true);
-
        /* Finally, set the new power state. */
-       pci_set_power_state(tp->pdev, state);
+       pci_write_config_word(tp->pdev, pm + PCI_PM_CTRL, power_control);
+       udelay(100);    /* Delay after power state change */
 
        return 0;
 }
@@ -2797,6 +2579,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);
@@ -3773,8 +3573,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;
@@ -3970,14 +3769,14 @@ static int tg3_alloc_rx_skb(struct tg3 *tp, u32 opaque_key,
         * Callers depend upon this behavior and assume that
         * we leave everything unchanged if we fail.
         */
-       skb = netdev_alloc_skb(tp->dev, skb_size);
+       skb = netdev_alloc_skb(tp->dev, skb_size + tp->rx_offset);
        if (skb == NULL)
                return -ENOMEM;
 
        skb_reserve(skb, tp->rx_offset);
 
        mapping = pci_map_single(tp->pdev, skb->data,
-                                skb_size - tp->rx_offset,
+                                skb_size,
                                 PCI_DMA_FROMDEVICE);
 
        map->skb = skb;
@@ -4033,13 +3832,6 @@ static void tg3_recycle_rx(struct tg3 *tp, u32 opaque_key,
        src_map->skb = NULL;
 }
 
-#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);
-}
-#endif
-
 /* The RX ring scheme is composed of multiple rings which post fresh
  * buffers to the chip, and one special ring the chip uses to report
  * status back to the host.
@@ -4085,6 +3877,8 @@ static int tg3_rx(struct tg3 *tp, int budget)
                struct sk_buff *skb;
                dma_addr_t dma_addr;
                u32 opaque_key, desc_idx, *post_ptr;
+               bool hw_vlan __maybe_unused = false;
+               u16 vtag __maybe_unused = 0;
 
                desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK;
                opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK;
@@ -4119,11 +3913,7 @@ static int tg3_rx(struct tg3 *tp, int budget)
 
                len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) - 4; /* omit crc */
 
-               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()] */
-               ) {
+               if (len > TG3_RX_COPY_THRESH(tp)) {
                        int skb_size;
 
                        skb_size = tg3_alloc_rx_skb(tp, opaque_key,
@@ -4132,7 +3922,7 @@ static int tg3_rx(struct tg3 *tp, int budget)
                                goto drop_it;
 
                        pci_unmap_single(tp->pdev, dma_addr,
-                                        skb_size - tp->rx_offset,
+                                        skb_size,
                                         PCI_DMA_FROMDEVICE);
 
                        skb_put(skb, len);
@@ -4142,11 +3932,11 @@ 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 + VLAN_HLEN);
                        if (copy_skb == NULL)
                                goto drop_it_no_recycle;
 
-                       skb_reserve(copy_skb, 2);
+                       skb_reserve(copy_skb, TG3_RAW_IP_ALIGN + VLAN_HLEN);
                        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);
@@ -4165,13 +3955,34 @@ 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)) &&
+                   (ntohs(skb->protocol) != ETH_P_8021Q)) {
+                       dev_kfree_skb(skb);
+                       goto next_pkt;
+               }
+
+               if (desc->type_flags & RXD_FLAG_VLAN &&
+                   !(tp->rx_mode & RX_MODE_KEEP_VLAN_TAG)) {
+                       vtag = desc->err_vlan & RXD_VLAN_MASK;
 #if TG3_VLAN_TAG_USED
-               if (tp->vlgrp != NULL &&
-                   desc->type_flags & RXD_FLAG_VLAN) {
-                       tg3_vlan_rx(tp, skb,
-                                   desc->err_vlan & RXD_VLAN_MASK);
-               } else
+                       if (tp->vlgrp)
+                               hw_vlan = true;
+                       else
 #endif
+                       {
+                               struct vlan_ethhdr *ve = (struct vlan_ethhdr *)
+                                                        __skb_push(skb, VLAN_HLEN);
+
+                               memmove(ve, skb->data + VLAN_HLEN, ETH_ALEN * 2);
+                               ve->h_vlan_proto = htons(ETH_P_8021Q);
+                               ve->h_vlan_TCI = htons(vtag);
+                       }
+               }
+
+               if (hw_vlan)
+                       vlan_hwaccel_receive_skb(skb, tp->vlgrp, vtag);
+               else
                        netif_receive_skb(skb);
 
                tp->dev->last_rx = jiffies;
@@ -4204,6 +4015,9 @@ next_pkt_nopost:
        tp->rx_rcb_ptr = sw_idx;
        tw32_rx_mbox(MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW, sw_idx);
 
+       /* Some platforms need to sync memory here */
+       wmb();
+
        /* Refill RX ring(s). */
        if (work_mask & RXD_OPAQUE_RING_STD) {
                sw_idx = tp->rx_std_ptr % TG3_RX_RING_SIZE;
@@ -4220,6 +4034,8 @@ next_pkt_nopost:
        return received;
 }
 
+#ifdef TG3_NAPI
+
 static int tg3_poll_work(struct tg3 *tp, int work_done, int budget)
 {
        struct tg3_hw_status *sblk = tp->hw_status;
@@ -4232,15 +4048,7 @@ static int tg3_poll_work(struct tg3 *tp, int work_done, int budget)
                        sblk->status = SD_STATUS_UPDATED |
                                (sblk->status & ~SD_STATUS_LINK_CHG);
                        spin_lock(&tp->lock);
-                       if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
-                               tw32_f(MAC_STATUS,
-                                    (MAC_STATUS_SYNC_CHANGED |
-                                     MAC_STATUS_CFG_CHANGED |
-                                     MAC_STATUS_MI_COMPLETION |
-                                     MAC_STATUS_LNKSTATE_CHANGED));
-                               udelay(40);
-                       } else
-                               tg3_setup_phy(tp, 0);
+                       tg3_setup_phy(tp, 0);
                        spin_unlock(&tp->lock);
                }
        }
@@ -4303,6 +4111,72 @@ tx_recovery:
        return work_done;
 }
 
+#else
+
+static int tg3_poll(struct net_device *netdev, int *budget)
+{
+       struct tg3 *tp = netdev_priv(netdev);
+       struct tg3_hw_status *sblk = tp->hw_status;
+       int done;
+
+       /* handle link change and other phy events */
+       if (!(tp->tg3_flags &
+             (TG3_FLAG_USE_LINKCHG_REG |
+              TG3_FLAG_POLL_SERDES))) {
+               if (sblk->status & SD_STATUS_LINK_CHG) {
+                       sblk->status = SD_STATUS_UPDATED |
+                               (sblk->status & ~SD_STATUS_LINK_CHG);
+                       spin_lock(&tp->lock);
+                       tg3_setup_phy(tp, 0);
+                       spin_unlock(&tp->lock);
+               }
+       }
+
+       /* run TX completion thread */
+       if (sblk->idx[0].tx_consumer != tp->tx_cons) {
+               tg3_tx(tp);
+               if (unlikely(tp->tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING)) {
+                       netif_rx_complete(netdev);
+                       schedule_work(&tp->reset_task);
+                       return 0;
+               }
+       }
+
+       /* run RX thread, within the bounds set by NAPI.
+        * All RX "locking" is done by ensuring outside
+        * code synchronizes with dev->poll()
+        */
+       if (sblk->idx[0].rx_producer != tp->rx_rcb_ptr) {
+               int orig_budget = *budget;
+               int work_done;
+
+               if (orig_budget > netdev->quota)
+                       orig_budget = netdev->quota;
+
+               work_done = tg3_rx(tp, orig_budget);
+
+               *budget -= work_done;
+               netdev->quota -= work_done;
+       }
+
+       if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) {
+               tp->last_tag = sblk->status_tag;
+               rmb();
+       } else
+               sblk->status &= ~SD_STATUS_UPDATED;
+
+       /* if no more work, tell net stack and NIC we're done */
+       done = !tg3_has_work(tp);
+       if (done) {
+               netif_rx_complete(netdev);
+               tg3_restart_ints(tp);
+       }
+
+       return (done ? 0 : 1);
+}
+
+#endif /* TG3_NAPI */
+
 static void tg3_irq_quiesce(struct tg3 *tp)
 {
        BUG_ON(tp->irq_sync);
@@ -4310,7 +4184,11 @@ static void tg3_irq_quiesce(struct tg3 *tp)
        tp->irq_sync = 1;
        smp_mb();
 
+#if (LINUX_VERSION_CODE >= 0x2051c)
        synchronize_irq(tp->pdev->irq);
+#else
+       synchronize_irq();
+#endif
 }
 
 static inline int tg3_irq_sync(struct tg3 *tp)
@@ -4338,7 +4216,11 @@ static inline void tg3_full_unlock(struct tg3 *tp)
 /* One-shot MSI handler - Chip automatically disables interrupt
  * after sending MSI so driver doesn't have to do it.
  */
+#if (LINUX_VERSION_CODE < 0x20613)
+static irqreturn_t tg3_msi_1shot(int irq, void *dev_id, struct pt_regs *regs)
+#else
 static irqreturn_t tg3_msi_1shot(int irq, void *dev_id)
+#endif
 {
        struct net_device *dev = dev_id;
        struct tg3 *tp = netdev_priv(dev);
@@ -4347,7 +4229,11 @@ 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)))
+#ifdef TG3_NAPI
                netif_rx_schedule(dev, &tp->napi);
+#else
+               netif_rx_schedule(dev);         /* schedule NAPI poll */
+#endif
 
        return IRQ_HANDLED;
 }
@@ -4356,7 +4242,11 @@ static irqreturn_t tg3_msi_1shot(int irq, void *dev_id)
  * flush status block and interrupt mailbox. PCI ordering rules
  * guarantee that MSI will arrive after the status block.
  */
+#if (LINUX_VERSION_CODE < 0x20613)
+static irqreturn_t tg3_msi(int irq, void *dev_id, struct pt_regs *regs)
+#else
 static irqreturn_t tg3_msi(int irq, void *dev_id)
+#endif
 {
        struct net_device *dev = dev_id;
        struct tg3 *tp = netdev_priv(dev);
@@ -4372,12 +4262,20 @@ 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)))
+#ifdef TG3_NAPI
                netif_rx_schedule(dev, &tp->napi);
+#else
+               netif_rx_schedule(dev);         /* schedule NAPI poll */
+#endif
 
        return IRQ_RETVAL(1);
 }
 
+#if (LINUX_VERSION_CODE < 0x20613)
+static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+#else
 static irqreturn_t tg3_interrupt(int irq, void *dev_id)
+#endif
 {
        struct net_device *dev = dev_id;
        struct tg3 *tp = netdev_priv(dev);
@@ -4414,7 +4312,11 @@ 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]);
+#ifdef TG3_NAPI
                netif_rx_schedule(dev, &tp->napi);
+#else
+               netif_rx_schedule(dev);         /* schedule NAPI poll */
+#endif
        } else {
                /* No work, shared interrupt perhaps?  re-enable
                 * interrupts, and flush that PCI write
@@ -4426,7 +4328,11 @@ out:
        return IRQ_RETVAL(handled);
 }
 
+#if (LINUX_VERSION_CODE < 0x20613)
+static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id, struct pt_regs *regs)
+#else
 static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
+#endif
 {
        struct net_device *dev = dev_id;
        struct tg3 *tp = netdev_priv(dev);
@@ -4460,6 +4366,7 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
        tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
        if (tg3_irq_sync(tp))
                goto out;
+#ifdef TG3_NAPI
        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
@@ -4470,12 +4377,28 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
                tp->last_tag = sblk->status_tag;
                __netif_rx_schedule(dev, &tp->napi);
        }
+#else
+       if (netif_rx_schedule_prep(dev)) {
+               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);
+       }
+#endif
 out:
        return IRQ_RETVAL(handled);
 }
 
 /* ISR for interrupt test */
+#if (LINUX_VERSION_CODE < 0x020613)
+static irqreturn_t tg3_test_isr(int irq, void *dev_id, struct pt_regs *regs)
+#else
 static irqreturn_t tg3_test_isr(int irq, void *dev_id)
+#endif
 {
        struct net_device *dev = dev_id;
        struct tg3 *tp = netdev_priv(dev);
@@ -4509,26 +4432,52 @@ static int tg3_restart_hw(struct tg3 *tp, int reset_phy)
                tg3_full_unlock(tp);
                del_timer_sync(&tp->timer);
                tp->irq_sync = 0;
+#ifdef TG3_NAPI
                napi_enable(&tp->napi);
+#else
+               netif_poll_enable(tp->dev);
+#endif
                dev_close(tp->dev);
                tg3_full_lock(tp, 0);
        }
        return err;
 }
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
+#if defined(HAVE_POLL_CONTROLLER) || defined(CONFIG_NET_POLL_CONTROLLER)
 static void tg3_poll_controller(struct net_device *dev)
 {
        struct tg3 *tp = netdev_priv(dev);
 
+#if defined(RED_HAT_LINUX_KERNEL) && (LINUX_VERSION_CODE < 0x20600)
+       if (netdump_mode) {
+               tg3_interrupt(tp->pdev->irq, dev, NULL);
+               if (dev->poll_list.prev) {
+                       int budget = 64;
+
+                       tg3_poll(dev, &budget);
+               }
+       }
+       else
+#endif
+#if (LINUX_VERSION_CODE < 0x020613)
+       tg3_interrupt(tp->pdev->irq, dev, NULL);
+#else
        tg3_interrupt(tp->pdev->irq, dev);
+#endif
 }
 #endif
 
+#if defined(INIT_DELAYED_WORK_DEFERRABLE) || defined(INIT_WORK_NAR)
 static void tg3_reset_task(struct work_struct *work)
+#else
+static void tg3_reset_task(void *_data)
+#endif
 {
+#if defined(INIT_DELAYED_WORK_DEFERRABLE) || defined(INIT_WORK_NAR)
        struct tg3 *tp = container_of(work, struct tg3, reset_task);
-       int err;
+#else
+       struct tg3 *tp = _data;
+#endif
        unsigned int restart_timer;
 
        tg3_full_lock(tp, 0);
@@ -4540,8 +4489,6 @@ static void tg3_reset_task(struct work_struct *work)
 
        tg3_full_unlock(tp);
 
-       tg3_phy_stop(tp);
-
        tg3_netif_stop(tp);
 
        tg3_full_lock(tp, 1);
@@ -4557,8 +4504,7 @@ static void tg3_reset_task(struct work_struct *work)
        }
 
        tg3_halt(tp, RESET_KIND_SHUTDOWN, 0);
-       err = tg3_init_hw(tp, 1);
-       if (err)
+       if (tg3_init_hw(tp, 1))
                goto out;
 
        tg3_netif_start(tp);
@@ -4568,9 +4514,6 @@ static void tg3_reset_task(struct work_struct *work)
 
 out:
        tg3_full_unlock(tp);
-
-       if (!err)
-               tg3_phy_start(tp);
 }
 
 static void tg3_dump_short_state(struct tg3 *tp)
@@ -4738,6 +4681,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        entry = tp->tx_prod;
        base_flags = 0;
+#if TG3_TSO_SUPPORT != 0
        mss = 0;
        if ((mss = skb_shinfo(skb)->gso_size) != 0) {
                int tcp_opt_len, ip_tcp_len;
@@ -4748,9 +4692,12 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        goto out_unlock;
                }
 
+#ifndef BCM_NO_TSO6
                if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
                        mss |= (skb_headlen(skb) - ETH_HLEN) << 9;
-               else {
+               else
+#endif
+               {
                        struct iphdr *iph = ip_hdr(skb);
 
                        tcp_opt_len = tcp_optlen(skb);
@@ -4769,6 +4716,11 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
        }
        else if (skb->ip_summed == CHECKSUM_PARTIAL)
                base_flags |= TXD_FLAG_TCPUDP_CSUM;
+#else
+       mss = 0;
+       if (skb->ip_summed == CHECKSUM_PARTIAL)
+               base_flags |= TXD_FLAG_TCPUDP_CSUM;
+#endif
 #if TG3_VLAN_TAG_USED
        if (tp->vlgrp != NULL && vlan_tx_tag_present(skb))
                base_flags |= (TXD_FLAG_VLAN |
@@ -4810,6 +4762,9 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
                }
        }
 
+       /* Some platforms need to sync memory here */
+       wmb();
+
        /* Packets are ready, update Tx producer idx local and on card. */
        tw32_tx_mbox((MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW), entry);
 
@@ -4820,7 +4775,9 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        netif_wake_queue(tp->dev);
        }
 
+#if TG3_TSO_SUPPORT != 0
 out_unlock:
+#endif
        mmiowb();
 
        dev->trans_start = jiffies;
@@ -4828,6 +4785,228 @@ out_unlock:
        return NETDEV_TX_OK;
 }
 
+#if TG3_TSO_SUPPORT != 0
+#ifndef NETIF_F_GSO
+
+struct sk_buff *skb_segment(struct sk_buff *skb, int features)
+{
+       struct sk_buff *segs = NULL;
+       struct sk_buff *tail = NULL;
+       unsigned int mss = skb_shinfo(skb)->gso_size;
+       unsigned int doffset = skb->data - skb->mac.raw;
+       unsigned int offset = doffset;
+       unsigned int headroom;
+       unsigned int len;
+       int nfrags = skb_shinfo(skb)->nr_frags;
+       int err = -ENOMEM;
+       int i = 0;
+       int pos;
+
+       __skb_push(skb, doffset);
+       headroom = skb_headroom(skb);
+       pos = skb_headlen(skb);
+
+       do {
+               struct sk_buff *nskb;
+               skb_frag_t *frag;
+               int hsize;
+               int k;
+               int size;
+
+               len = skb->len - offset;
+               if (len > mss)
+                       len = mss;
+
+               hsize = skb_headlen(skb) - offset;
+               if (hsize < 0)
+                       hsize = 0;
+               if (hsize > len)
+                       hsize = len;
+
+               nskb = alloc_skb(hsize + doffset + headroom, GFP_ATOMIC);
+               if (unlikely(!nskb))
+                       goto err;
+
+               if (segs)
+                       tail->next = nskb;
+               else
+                       segs = nskb;
+               tail = nskb;
+
+               nskb->dev = skb->dev;
+               nskb->priority = skb->priority;
+               nskb->protocol = skb->protocol;
+               nskb->dst = dst_clone(skb->dst);
+               memcpy(nskb->cb, skb->cb, sizeof(skb->cb));
+               nskb->pkt_type = skb->pkt_type;
+               nskb->mac_len = skb->mac_len;
+
+               skb_reserve(nskb, headroom);
+               nskb->mac.raw = nskb->data;
+               nskb->nh.raw = nskb->data + skb->mac_len;
+               nskb->h.raw = nskb->nh.raw + (skb->h.raw - skb->nh.raw);
+               memcpy(skb_put(nskb, doffset), skb->data, doffset);
+
+               frag = skb_shinfo(nskb)->frags;
+               k = 0;
+
+               nskb->ip_summed = CHECKSUM_PARTIAL;
+               nskb->csum = skb->csum;
+               memcpy(skb_put(nskb, hsize), skb->data + offset, hsize);
+
+               while (pos < offset + len) {
+                       BUG_ON(i >= nfrags);
+
+                       *frag = skb_shinfo(skb)->frags[i];
+                       get_page(frag->page);
+                       size = frag->size;
+
+                       if (pos < offset) {
+                               frag->page_offset += offset - pos;
+                               frag->size -= offset - pos;
+                       }
+
+                       k++;
+
+                       if (pos + size <= offset + len) {
+                               i++;
+                               pos += size;
+                       } else {
+                               frag->size -= pos + size - (offset + len);
+                               break;
+                       }
+
+                       frag++;
+               }
+
+               skb_shinfo(nskb)->nr_frags = k;
+               nskb->data_len = len - hsize;
+               nskb->len += nskb->data_len;
+               nskb->truesize += nskb->data_len;
+       } while ((offset += len) < skb->len);
+
+       return segs;
+
+err:
+       while ((skb = segs)) {
+               segs = skb->next;
+               kfree(skb);
+       }
+       return ERR_PTR(err);
+}
+
+static struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
+{
+       struct sk_buff *segs = ERR_PTR(-EINVAL);
+       struct tcphdr *th;
+       unsigned thlen;
+       unsigned int seq;
+       u32 delta;
+       unsigned int oldlen;
+       unsigned int len;
+
+       if (!pskb_may_pull(skb, sizeof(*th)))
+               goto out;
+
+       th = skb->h.th;
+       thlen = th->doff * 4;
+       if (thlen < sizeof(*th))
+               goto out;
+
+       if (!pskb_may_pull(skb, thlen))
+               goto out;
+
+       oldlen = (u16)~skb->len;
+       __skb_pull(skb, thlen);
+
+       segs = skb_segment(skb, features);
+       if (IS_ERR(segs))
+               goto out;
+
+       len = skb_shinfo(skb)->gso_size;
+       delta = htonl(oldlen + (thlen + len));
+
+       skb = segs;
+       th = skb->h.th;
+       seq = ntohl(th->seq);
+
+       do {
+               th->fin = th->psh = 0;
+
+               th->check = ~csum_fold((u32)((u32)th->check +
+                                      (u32)delta));
+               seq += len;
+               skb = skb->next;
+               th = skb->h.th;
+
+               th->seq = htonl(seq);
+               th->cwr = 0;
+       } while (skb->next);
+
+       delta = htonl(oldlen + (skb->tail - skb->h.raw) + skb->data_len);
+       th->check = ~csum_fold((u32)((u32)th->check +
+                               (u32)delta));
+out:
+       return segs;
+}
+
+static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features)
+{
+       struct sk_buff *segs = ERR_PTR(-EINVAL);
+       struct iphdr *iph;
+       int ihl;
+       int id;
+
+       if (unlikely(!pskb_may_pull(skb, sizeof(*iph))))
+               goto out;
+
+       iph = skb->nh.iph;
+       ihl = iph->ihl * 4;
+       if (ihl < sizeof(*iph))
+               goto out;
+
+       if (unlikely(!pskb_may_pull(skb, ihl)))
+               goto out;
+
+       skb->h.raw = __skb_pull(skb, ihl);
+       iph = skb->nh.iph;
+       id = ntohs(iph->id);
+       segs = ERR_PTR(-EPROTONOSUPPORT);
+
+       segs = tcp_tso_segment(skb, features);
+
+       if (!segs || IS_ERR(segs))
+               goto out;
+
+       skb = segs;
+       do {
+               iph = skb->nh.iph;
+               iph->id = htons(id++);
+               iph->tot_len = htons(skb->len - skb->mac_len);
+               iph->check = 0;
+               iph->check = ip_fast_csum(skb->nh.raw, iph->ihl);
+       } while ((skb = skb->next));
+
+out:
+       return segs;
+}
+
+static struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features)
+{
+       struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT);
+
+       skb->mac.raw = skb->data;
+       skb->mac_len = skb->nh.raw - skb->data;
+       __skb_pull(skb, skb->mac_len);
+
+       segs = inet_gso_segment(skb, features);
+
+       __skb_push(skb, skb->data - skb->mac.raw);
+       return segs;
+}
+
+#endif
+
 static int tg3_start_xmit_dma_bug(struct sk_buff *, struct net_device *);
 
 /* Use GSO to workaround a rare TSO bug that may be triggered when the
@@ -4863,6 +5042,8 @@ tg3_tso_bug_end:
        return NETDEV_TX_OK;
 }
 
+#endif
+
 /* hard_start_xmit for devices that have the 4G bug and/or 40-bit bug and
  * support TG3_FLG2_HW_TSO_1 or firmware TSO only.
  */
@@ -4895,8 +5076,10 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
        base_flags = 0;
        if (skb->ip_summed == CHECKSUM_PARTIAL)
                base_flags |= TXD_FLAG_TCPUDP_CSUM;
+#if TG3_TSO_SUPPORT != 0
        mss = 0;
-       if ((mss = skb_shinfo(skb)->gso_size) != 0) {
+       if (((mss = skb_shinfo(skb)->gso_size) != 0) &&
+           (skb_shinfo(skb)->gso_segs > 1)) {
                struct iphdr *iph;
                int tcp_opt_len, ip_tcp_len, hdr_len;
 
@@ -4946,6 +5129,9 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
                        }
                }
        }
+#else
+       mss = 0;
+#endif
 #if TG3_VLAN_TAG_USED
        if (tp->vlgrp != NULL && vlan_tx_tag_present(skb))
                base_flags |= (TXD_FLAG_VLAN |
@@ -5021,6 +5207,9 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
                entry = start;
        }
 
+       /* Some platforms need to sync memory here */
+       wmb();
+
        /* Packets are ready, update Tx producer idx local and on card. */
        tw32_tx_mbox((MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW), entry);
 
@@ -5047,7 +5236,9 @@ static inline void tg3_set_mtu(struct net_device *dev, struct tg3 *tp,
        if (new_mtu > ETH_DATA_LEN) {
                if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) {
                        tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE;
+#if TG3_TSO_SUPPORT != 0
                        ethtool_op_set_tso(dev, 0);
+#endif
                }
                else
                        tp->tg3_flags |= TG3_FLAG_JUMBO_RING_ENABLE;
@@ -5074,8 +5265,6 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
                return 0;
        }
 
-       tg3_phy_stop(tp);
-
        tg3_netif_stop(tp);
 
        tg3_full_lock(tp, 1);
@@ -5091,9 +5280,6 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
 
        tg3_full_unlock(tp);
 
-       if (!err)
-               tg3_phy_start(tp);
-
        return err;
 }
 
@@ -5116,7 +5302,7 @@ static void tg3_free_rings(struct tg3 *tp)
                        continue;
                pci_unmap_single(tp->pdev,
                                 pci_unmap_addr(rxp, mapping),
-                                tp->rx_pkt_buf_sz - tp->rx_offset,
+                                tp->rx_pkt_buf_sz,
                                 PCI_DMA_FROMDEVICE);
                dev_kfree_skb_any(rxp->skb);
                rxp->skb = NULL;
@@ -5129,7 +5315,7 @@ static void tg3_free_rings(struct tg3 *tp)
                        continue;
                pci_unmap_single(tp->pdev,
                                 pci_unmap_addr(rxp, mapping),
-                                RX_JUMBO_PKT_BUF_SZ - tp->rx_offset,
+                                RX_JUMBO_PKT_BUF_SZ,
                                 PCI_DMA_FROMDEVICE);
                dev_kfree_skb_any(rxp->skb);
                rxp->skb = NULL;
@@ -5202,7 +5388,7 @@ static int tg3_init_rings(struct tg3 *tp)
                struct tg3_rx_buffer_desc *rxd;
 
                rxd = &tp->rx_std[i];
-               rxd->idx_len = (tp->rx_pkt_buf_sz - tp->rx_offset - 64)
+               rxd->idx_len = (tp->rx_pkt_buf_sz - 64)
                        << RXD_LEN_SHIFT;
                rxd->type_flags = (RXD_FLAG_END << RXD_FLAGS_SHIFT);
                rxd->opaque = (RXD_OPAQUE_RING_STD |
@@ -5214,7 +5400,7 @@ static int tg3_init_rings(struct tg3 *tp)
                        struct tg3_rx_buffer_desc *rxd;
 
                        rxd = &tp->rx_jumbo[i];
-                       rxd->idx_len = (RX_JUMBO_PKT_BUF_SZ - tp->rx_offset - 64)
+                       rxd->idx_len = (RX_JUMBO_PKT_BUF_SZ - 64)
                                << RXD_LEN_SHIFT;
                        rxd->type_flags = (RXD_FLAG_END << RXD_FLAGS_SHIFT) |
                                RXD_FLAG_JUMBO;
@@ -5588,6 +5774,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:
@@ -5762,7 +5955,7 @@ static void tg3_restore_pci_state(struct tg3 *tp)
        }
 
        /* 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,
@@ -5803,8 +5996,6 @@ static int tg3_chip_reset(struct tg3 *tp)
 
        tg3_nvram_lock(tp);
 
-       tg3_mdio_stop(tp);
-
        tg3_ape_lock(tp, TG3_APE_LOCK_GRC);
 
        /* No matching tg3_nvram_unlock() after this because
@@ -5822,9 +6013,7 @@ static int tg3_chip_reset(struct tg3 *tp)
            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_57780 ||
-           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)
                tw32(GRC_FASTBOOT_PC, 0);
 
        /*
@@ -5850,7 +6039,11 @@ static int tg3_chip_reset(struct tg3 *tp)
        }
        tp->last_tag = 0;
        smp_mb();
+#if (LINUX_VERSION_CODE >= 0x2051c)
        synchronize_irq(tp->pdev->irq);
+#else
+       synchronize_irq();
+#endif
 
        /* do the reset */
        val = GRC_MISC_CFG_CORECLK_RESET;
@@ -5956,7 +6149,7 @@ static int tg3_chip_reset(struct tg3 *tp)
        } else if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) {
                tp->mac_mode = MAC_MODE_PORT_MODE_GMII;
                tw32_f(MAC_MODE, tp->mac_mode);
-       } else if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
+       } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) {
                tp->mac_mode &= (MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN);
                if (tp->mac_mode & MAC_MODE_APE_TX_EN)
                        tp->mac_mode |= MAC_MODE_TDE_ENABLE;
@@ -5965,8 +6158,6 @@ static int tg3_chip_reset(struct tg3 *tp)
                tw32_f(MAC_MODE, 0);
        udelay(40);
 
-       tg3_mdio_start(tp);
-
        tg3_ape_unlock(tp, TG3_APE_LOCK_GRC);
 
        err = tg3_poll_fw(tp);
@@ -6338,6 +6529,7 @@ static int tg3_load_5701_a0_firmware_fix(struct tg3 *tp)
        return 0;
 }
 
+#if TG3_TSO_SUPPORT != 0
 
 #define TG3_TSO_FW_RELEASE_MAJOR       0x1
 #define TG3_TSO_FW_RELASE_MINOR                0x6
@@ -6914,43 +7106,7 @@ static int tg3_load_tso_firmware(struct tg3 *tp)
        return 0;
 }
 
-
-/* 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);
-}
+#endif /* TG3_TSO_SUPPORT != 0 */
 
 static int tg3_set_mac_addr(struct net_device *dev, void *p)
 {
@@ -7046,8 +7202,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                tg3_abort_hw(tp, 1);
        }
 
-       if (reset_phy &&
-           !(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB))
+       if (reset_phy)
                tg3_phy_reset(tp);
 
        err = tg3_chip_reset(tp);
@@ -7056,8 +7211,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);
@@ -7123,9 +7277,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_57780 &&
-           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.
                 */
@@ -7168,6 +7320,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                tw32(BUFMGR_DMA_DESC_POOL_ADDR, NIC_SRAM_DMA_DESC_POOL_BASE);
                tw32(BUFMGR_DMA_DESC_POOL_SIZE, NIC_SRAM_DMA_DESC_POOL_SIZE);
        }
+#if TG3_TSO_SUPPORT != 0
        else if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) {
                int fw_len;
 
@@ -7182,6 +7335,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                tw32(BUFMGR_MB_POOL_SIZE,
                     NIC_SRAM_MBUF_POOL_SIZE5705 - fw_len - 0xa00);
        }
+#endif
 
        if (tp->dev->mtu <= ETH_DATA_LEN) {
                tw32(BUFMGR_MB_RDMA_LOW_WATER,
@@ -7341,7 +7495,7 @@ 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.
@@ -7364,9 +7518,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                      RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB |
                      RDMAC_MODE_LNGREAD_ENAB);
 
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784)
                rdmac_mode |= RDMAC_MODE_BD_SBD_CRPT_ENAB |
                              RDMAC_MODE_MBUF_RBD_CRPT_ENAB |
                              RDMAC_MODE_MBUF_SBD_CRPT_ENAB;
@@ -7387,8 +7539,10 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)
                rdmac_mode |= RDMAC_MODE_FIFO_LONG_BURST;
 
+#if TG3_TSO_SUPPORT != 0
        if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
                rdmac_mode |= (1 << 27);
+#endif
 
        /* Receive/send statistics. */
        if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) {
@@ -7461,7 +7615,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                udelay(10);
        }
 
-       if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
                tp->mac_mode &= MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN;
        else
                tp->mac_mode = 0;
@@ -7538,9 +7692,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        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_57780) ||
-           (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))
                val |= WDMAC_MODE_STATUS_TAG_FIX;
 
        tw32_f(WDMAC_MODE, val);
@@ -7579,8 +7731,10 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        tw32(RCVBDI_MODE, RCVBDI_MODE_ENABLE | RCVBDI_MODE_RCB_ATTN_ENAB);
        tw32(RCVDBDI_MODE, RCVDBDI_MODE_ENABLE | RCVDBDI_MODE_INV_RING_SZ);
        tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE);
+#if TG3_TSO_SUPPORT != 0
        if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
                tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE | 0x8);
+#endif
        tw32(SNDBDI_MODE, SNDBDI_MODE_ENABLE | SNDBDI_MODE_ATTN_ENABLE);
        tw32(SNDBDS_MODE, SNDBDS_MODE_ENABLE | SNDBDS_MODE_ATTN_ENABLE);
 
@@ -7590,11 +7744,13 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                        return err;
        }
 
+#if TG3_TSO_SUPPORT != 0
        if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) {
                err = tg3_load_tso_firmware(tp);
                if (err)
                        return err;
        }
+#endif
 
        tp->tx_mode = TX_MODE_ENABLE;
        tw32_f(MAC_TX_MODE, tp->tx_mode);
@@ -7603,14 +7759,23 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        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_57780 ||
-           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)
                tp->rx_mode |= RX_MODE_IPV6_CSUM_ENABLE;
 
        tw32_f(MAC_RX_MODE, tp->rx_mode);
        udelay(10);
 
+       if (tp->link_config.phy_is_low_power) {
+               tp->link_config.phy_is_low_power = 0;
+               tp->link_config.speed = tp->link_config.orig_speed;
+               tp->link_config.duplex = tp->link_config.orig_duplex;
+               tp->link_config.autoneg = tp->link_config.orig_autoneg;
+       }
+
+       tp->mi_mode &= ~MAC_MI_MODE_AUTO_POLL;
+       tw32_f(MAC_MI_MODE, tp->mi_mode);
+       udelay(80);
+
        tw32(MAC_LED_CTRL, tp->led_ctrl);
 
        tw32(MAC_MI_STAT, MAC_MI_STAT_LNKSTAT_ATTN_ENAB);
@@ -7657,28 +7822,19 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
        }
 
-       if (!(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)) {
-               if (tp->link_config.phy_is_low_power) {
-                       tp->link_config.phy_is_low_power = 0;
-                       tp->link_config.speed = tp->link_config.orig_speed;
-                       tp->link_config.duplex = tp->link_config.orig_duplex;
-                       tp->link_config.autoneg = tp->link_config.orig_autoneg;
-               }
-
-               err = tg3_setup_phy(tp, 0);
-               if (err)
-                       return err;
+       err = tg3_setup_phy(tp, 0);
+       if (err)
+               return err;
 
-               if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) &&
-                   GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906) {
-                       u32 tmp;
+       if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) &&
+           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906) {
+               u32 tmp;
 
-                       /* Clear CRC stats. */
-                       if (!tg3_readphy(tp, MII_TG3_TEST1, &tmp)) {
-                               tg3_writephy(tp, MII_TG3_TEST1,
-                                            tmp | MII_TG3_TEST1_CRC_EN);
-                               tg3_readphy(tp, 0x14, &tmp);
-                       }
+               /* Clear CRC stats. */
+               if (!tg3_readphy(tp, MII_TG3_TEST1, &tmp)) {
+                       tg3_writephy(tp, MII_TG3_TEST1,
+                                    tmp | MII_TG3_TEST1_CRC_EN);
+                       tg3_readphy(tp, 0x14, &tmp);
                }
        }
 
@@ -7748,11 +7904,21 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
  */
 static int tg3_init_hw(struct tg3 *tp, int reset_phy)
 {
+       int err;
+
+       /* Force the chip into D0. */
+       err = tg3_set_power_state(tp, PCI_D0);
+       if (err)
+               goto out;
+
        tg3_switch_clocks(tp);
 
        tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0);
 
-       return tg3_reset_hw(tp, reset_phy);
+       err = tg3_reset_hw(tp, reset_phy);
+
+out:
+       return err;
 }
 
 #define TG3_STAT_ADD32(PSTAT, REG) \
@@ -7925,7 +8091,11 @@ restart_timer:
 
 static int tg3_request_irq(struct tg3 *tp)
 {
+#if (LINUX_VERSION_CODE < 0x020613)
+       irqreturn_t (*fn)(int, void *, struct pt_regs *);
+#else
        irq_handler_t fn;
+#endif
        unsigned long flags;
        struct net_device *dev = tp->dev;
 
@@ -7979,7 +8149,12 @@ static int tg3_test_interrupt(struct tg3 *tp)
                        break;
                }
 
+#if (LINUX_VERSION_CODE < 0x20607)
+               set_current_state(TASK_UNINTERRUPTIBLE);
+               schedule_timeout(10);
+#else
                msleep(10);
+#endif
        }
 
        tg3_disable_ints(tp);
@@ -8034,7 +8209,9 @@ static int tg3_test_msi(struct tg3 *tp)
                       tp->dev->name);
 
        free_irq(tp->pdev->irq, dev);
+#ifdef CONFIG_PCI_MSI
        pci_disable_msi(tp->pdev);
+#endif
 
        tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
 
@@ -8065,11 +8242,13 @@ static int tg3_open(struct net_device *dev)
 
        netif_carrier_off(tp->dev);
 
+       tg3_full_lock(tp, 0);
+
        err = tg3_set_power_state(tp, PCI_D0);
-       if (err)
+       if (err) {
+               tg3_full_unlock(tp);
                return err;
-
-       tg3_full_lock(tp, 0);
+       }
 
        tg3_disable_ints(tp);
        tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
@@ -8083,6 +8262,7 @@ static int tg3_open(struct net_device *dev)
        if (err)
                return err;
 
+#ifdef CONFIG_PCI_MSI
        if (tp->tg3_flags & TG3_FLAG_SUPPORT_MSI) {
                /* All MSI supporting chips should support tagged
                 * status.  Assert that this is the case.
@@ -8093,23 +8273,38 @@ static int tg3_open(struct net_device *dev)
                } else if (pci_enable_msi(tp->pdev) == 0) {
                        u32 msi_mode;
 
+#ifndef BCM_HAS_INTX_MSI_WORKAROUND
+                       /* Hardware bug - MSI won't work if INTX disabled. */
+                       if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)
+#if (LINUX_VERSION_CODE < 0x2060e)
+                               tg3_enable_intx(tp->pdev);
+#else
+                               pci_intx(tp->pdev, 1);
+#endif
+#endif
+
                        msi_mode = tr32(MSGINT_MODE);
                        tw32(MSGINT_MODE, msi_mode | MSGINT_MODE_ENABLE);
                        tp->tg3_flags2 |= TG3_FLG2_USING_MSI;
                }
        }
+#endif
        err = tg3_request_irq(tp);
 
        if (err) {
                if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
+#ifdef CONFIG_PCI_MSI
                        pci_disable_msi(tp->pdev);
+#endif
                        tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
                }
                tg3_free_consistent(tp);
                return err;
        }
 
+#ifdef TG3_NAPI
        napi_enable(&tp->napi);
+#endif
 
        tg3_full_lock(tp, 0);
 
@@ -8138,10 +8333,14 @@ static int tg3_open(struct net_device *dev)
        tg3_full_unlock(tp);
 
        if (err) {
+#ifdef TG3_NAPI
                napi_disable(&tp->napi);
+#endif
                free_irq(tp->pdev->irq, dev);
                if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
+#ifdef CONFIG_PCI_MSI
                        pci_disable_msi(tp->pdev);
+#endif
                        tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
                }
                tg3_free_consistent(tp);
@@ -8155,7 +8354,9 @@ static int tg3_open(struct net_device *dev)
                        tg3_full_lock(tp, 0);
 
                        if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
+#ifdef CONFIG_PCI_MSI
                                pci_disable_msi(tp->pdev);
+#endif
                                tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
                        }
                        tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
@@ -8164,7 +8365,9 @@ static int tg3_open(struct net_device *dev)
 
                        tg3_full_unlock(tp);
 
+#ifdef TG3_NAPI
                        napi_disable(&tp->napi);
+#endif
 
                        return err;
                }
@@ -8179,8 +8382,6 @@ static int tg3_open(struct net_device *dev)
                }
        }
 
-       tg3_phy_start(tp);
-
        tg3_full_lock(tp, 0);
 
        add_timer(&tp->timer);
@@ -8429,8 +8630,16 @@ static int tg3_close(struct net_device *dev)
 {
        struct tg3 *tp = netdev_priv(dev);
 
+#ifdef TG3_NAPI
        napi_disable(&tp->napi);
+#endif
+
+#if (LINUX_VERSION_CODE >= 0x20616)
        cancel_work_sync(&tp->reset_task);
+#else
+       set_current_state(TASK_UNINTERRUPTIBLE);
+       schedule_timeout(1);
+#endif
 
        netif_stop_queue(dev);
 
@@ -8451,7 +8660,9 @@ static int tg3_close(struct net_device *dev)
 
        free_irq(tp->pdev->irq, dev);
        if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
+#ifdef CONFIG_PCI_MSI
                pci_disable_msi(tp->pdev);
+#endif
                tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
        }
 
@@ -8481,11 +8692,6 @@ static inline unsigned long get_stat64(tg3_stat64_t *val)
        return ret;
 }
 
-static inline u64 get_estat64(tg3_stat64_t *val)
-{
-       return ((u64)val->high << 32) | ((u64)val->low);
-}
-
 static unsigned long calc_crc_errors(struct tg3 *tp)
 {
        struct tg3_hw_stats *hw_stats = tp->hw_stats;
@@ -8514,7 +8720,7 @@ static unsigned long calc_crc_errors(struct tg3 *tp)
 
 #define ESTAT_ADD(member) \
        estats->member =        old_estats->member + \
-                               get_estat64(&hw_stats->member)
+                               get_stat64(&hw_stats->member)
 
 static struct tg3_ethtool_stats *tg3_get_estats(struct tg3 *tp)
 {
@@ -8854,17 +9060,20 @@ do {    p = (u32 *)(orig_p + (reg));            \
        tg3_full_unlock(tp);
 }
 
+#if (LINUX_VERSION_CODE >= 0x20418)
 static int tg3_get_eeprom_len(struct net_device *dev)
 {
        struct tg3 *tp = netdev_priv(dev);
 
        return tp->nvram_size;
 }
+#endif
 
 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);
 
+#ifdef ETHTOOL_GEEPROM
 static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data)
 {
        struct tg3 *tp = netdev_priv(dev);
@@ -8924,9 +9133,11 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
        }
        return 0;
 }
+#endif
 
 static int tg3_nvram_write_block(struct tg3 *tp, u32 offset, u32 len, u8 *buf);
 
+#ifdef ETHTOOL_SEEPROM
 static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data)
 {
        struct tg3 *tp = netdev_priv(dev);
@@ -8984,17 +9195,12 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
 
        return ret;
 }
+#endif
 
 static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
        struct tg3 *tp = netdev_priv(dev);
 
-       if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
-               if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
-                       return -EAGAIN;
-               return phy_ethtool_gset(tp->mdio_bus.phy_map[PHY_ADDR], cmd);
-       }
-
        cmd->supported = (SUPPORTED_Autoneg);
 
        if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY))
@@ -9027,14 +9233,8 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 }
 
 static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
-       struct tg3 *tp = netdev_priv(dev);
-
-       if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
-               if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
-                       return -EAGAIN;
-               return phy_ethtool_sset(tp->mdio_bus.phy_map[PHY_ADDR], cmd);
-       }
+{
+       struct tg3 *tp = netdev_priv(dev);
 
        if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) {
                /* These are the only valid advertisement bits allowed.  */
@@ -9096,8 +9296,7 @@ static void tg3_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
        struct tg3 *tp = netdev_priv(dev);
 
-       if ((tp->tg3_flags & TG3_FLAG_WOL_CAP) &&
-           device_can_wakeup(&tp->pdev->dev))
+       if (tp->tg3_flags & TG3_FLAG_WOL_CAP)
                wol->supported = WAKE_MAGIC;
        else
                wol->supported = 0;
@@ -9110,22 +9309,18 @@ static void tg3_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 static int tg3_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
        struct tg3 *tp = netdev_priv(dev);
-       struct device *dp = &tp->pdev->dev;
 
        if (wol->wolopts & ~WAKE_MAGIC)
                return -EINVAL;
        if ((wol->wolopts & WAKE_MAGIC) &&
-           !((tp->tg3_flags & TG3_FLAG_WOL_CAP) && device_can_wakeup(dp)))
+           !(tp->tg3_flags & TG3_FLAG_WOL_CAP))
                return -EINVAL;
 
        spin_lock_bh(&tp->lock);
-       if (wol->wolopts & WAKE_MAGIC) {
+       if (wol->wolopts & WAKE_MAGIC)
                tp->tg3_flags |= TG3_FLAG_WOL_ENABLE;
-               device_set_wakeup_enable(dp, true);
-       } else {
+       else
                tp->tg3_flags &= ~TG3_FLAG_WOL_ENABLE;
-               device_set_wakeup_enable(dp, false);
-       }
        spin_unlock_bh(&tp->lock);
 
        return 0;
@@ -9143,6 +9338,7 @@ static void tg3_set_msglevel(struct net_device *dev, u32 value)
        tp->msg_enable = value;
 }
 
+#if TG3_TSO_SUPPORT != 0
 static int tg3_set_tso(struct net_device *dev, u32 value)
 {
        struct tg3 *tp = netdev_priv(dev);
@@ -9158,19 +9354,19 @@ static int tg3_set_tso(struct net_device *dev, u32 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_57780 ||
-                           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
+                            GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX))
                                dev->features |= NETIF_F_TSO_ECN;
                } else
                        dev->features &= ~(NETIF_F_TSO6 | NETIF_F_TSO_ECN);
        }
        return ethtool_op_set_tso(dev, value);
 }
+#endif
 
 static int tg3_nway_reset(struct net_device *dev)
 {
        struct tg3 *tp = netdev_priv(dev);
+       u32 bmcr;
        int r;
 
        if (!netif_running(dev))
@@ -9179,25 +9375,17 @@ static int tg3_nway_reset(struct net_device *dev)
        if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)
                return -EINVAL;
 
-       if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
-               if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
-                       return -EAGAIN;
-               r = phy_start_aneg(tp->mdio_bus.phy_map[PHY_ADDR]);
-       } else {
-               u32 bmcr;
-
-               spin_lock_bh(&tp->lock);
-               r = -EINVAL;
-               tg3_readphy(tp, MII_BMCR, &bmcr);
-               if (!tg3_readphy(tp, MII_BMCR, &bmcr) &&
-                   ((bmcr & BMCR_ANENABLE) ||
-                    (tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT))) {
-                       tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANRESTART |
-                                                  BMCR_ANENABLE);
-                       r = 0;
-               }
-               spin_unlock_bh(&tp->lock);
+       spin_lock_bh(&tp->lock);
+       r = -EINVAL;
+       tg3_readphy(tp, MII_BMCR, &bmcr);
+       if (!tg3_readphy(tp, MII_BMCR, &bmcr) &&
+           ((bmcr & BMCR_ANENABLE) ||
+            (tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT))) {
+               tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANRESTART |
+                                          BMCR_ANENABLE);
+               r = 0;
        }
+       spin_unlock_bh(&tp->lock);
 
        return r;
 }
@@ -9239,7 +9427,6 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e
                return -EINVAL;
 
        if (netif_running(dev)) {
-               tg3_phy_stop(tp);
                tg3_netif_stop(tp);
                irq_sync = 1;
        }
@@ -9263,9 +9450,6 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e
 
        tg3_full_unlock(tp);
 
-       if (irq_sync && !err)
-               tg3_phy_start(tp);
-
        return err;
 }
 
@@ -9289,93 +9473,37 @@ static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam
 static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause)
 {
        struct tg3 *tp = netdev_priv(dev);
-       int err = 0;
-
-       if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
-               if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
-                       return -EAGAIN;
-
-               if (epause->autoneg) {
-                       u32 newadv;
-                       struct phy_device *phydev;
-
-                       phydev = tp->mdio_bus.phy_map[PHY_ADDR];
-
-                       if (epause->rx_pause) {
-                               if (epause->tx_pause)
-                                       newadv = ADVERTISED_Pause;
-                               else
-                                       newadv = ADVERTISED_Pause |
-                                                ADVERTISED_Asym_Pause;
-                       } else if (epause->tx_pause) {
-                               newadv = ADVERTISED_Asym_Pause;
-                       } else
-                               newadv = 0;
-
-                       if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) {
-                               u32 oldadv = phydev->advertising &
-                                            (ADVERTISED_Pause |
-                                             ADVERTISED_Asym_Pause);
-                               if (oldadv != newadv) {
-                                       phydev->advertising &=
-                                               ~(ADVERTISED_Pause |
-                                                 ADVERTISED_Asym_Pause);
-                                       phydev->advertising |= newadv;
-                                       err = phy_start_aneg(phydev);
-                               }
-                       } else {
-                               tp->link_config.advertising &=
-                                               ~(ADVERTISED_Pause |
-                                                 ADVERTISED_Asym_Pause);
-                               tp->link_config.advertising |= newadv;
-                       }
-               } else {
-                       if (epause->rx_pause)
-                               tp->link_config.flowctrl |= TG3_FLOW_CTRL_RX;
-                       else
-                               tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_RX;
-
-                       if (epause->tx_pause)
-                               tp->link_config.flowctrl |= TG3_FLOW_CTRL_TX;
-                       else
-                               tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_TX;
-
-                       if (netif_running(dev))
-                               tg3_setup_flow_control(tp, 0, 0);
-               }
-       } else {
-               int irq_sync = 0;
-
-               if (netif_running(dev)) {
-                       tg3_netif_stop(tp);
-                       irq_sync = 1;
-               }
+       int irq_sync = 0, err = 0;
 
-               tg3_full_lock(tp, irq_sync);
+       if (netif_running(dev)) {
+               tg3_netif_stop(tp);
+               irq_sync = 1;
+       }
 
-               if (epause->autoneg)
-                       tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
-               else
-                       tp->tg3_flags &= ~TG3_FLAG_PAUSE_AUTONEG;
-               if (epause->rx_pause)
-                       tp->link_config.flowctrl |= TG3_FLOW_CTRL_RX;
-               else
-                       tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_RX;
-               if (epause->tx_pause)
-                       tp->link_config.flowctrl |= TG3_FLOW_CTRL_TX;
-               else
-                       tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_TX;
+       tg3_full_lock(tp, irq_sync);
 
-               if (netif_running(dev)) {
-                       tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
-                       err = tg3_restart_hw(tp, 1);
-                       if (!err)
-                               tg3_netif_start(tp);
-               }
+       if (epause->autoneg)
+               tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
+       else
+               tp->tg3_flags &= ~TG3_FLAG_PAUSE_AUTONEG;
+       if (epause->rx_pause)
+               tp->link_config.flowctrl |= TG3_FLOW_CTRL_RX;
+       else
+               tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_RX;
+       if (epause->tx_pause)
+               tp->link_config.flowctrl |= TG3_FLOW_CTRL_TX;
+       else
+               tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_TX;
 
-               tg3_full_unlock(tp);
+       if (netif_running(dev)) {
+               tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
+               err = tg3_restart_hw(tp, 1);
+               if (!err)
+                       tg3_netif_start(tp);
        }
 
+       tg3_full_unlock(tp);
+
        return err;
 }
 
@@ -9405,6 +9533,7 @@ static int tg3_set_rx_csum(struct net_device *dev, u32 data)
        return 0;
 }
 
+#ifdef BCM_HAS_SET_TX_CSUM
 static int tg3_set_tx_csum(struct net_device *dev, u32 data)
 {
        struct tg3 *tp = netdev_priv(dev);
@@ -9418,15 +9547,20 @@ static int tg3_set_tx_csum(struct net_device *dev, u32 data)
        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_57780 ||
-           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)
+#if defined(BCM_HAS_ETHTOOL_OP_SET_TX_IPV6_CSUM)
                ethtool_op_set_tx_ipv6_csum(dev, data);
+#elif defined(BCM_HAS_ETHTOOL_OP_SET_TX_HW_CSUM)
+               ethtool_op_set_tx_hw_csum(dev, data);
+#else
+               tg3_set_tx_hw_csum(dev, data);
+#endif
        else
                ethtool_op_set_tx_csum(dev, data);
 
        return 0;
 }
+#endif
 
 static int tg3_get_sset_count (struct net_device *dev, int sset)
 {
@@ -9440,6 +9574,18 @@ static int tg3_get_sset_count (struct net_device *dev, int sset)
        }
 }
 
+#if (LINUX_VERSION_CODE < 0x020618)
+static int tg3_get_stats_count (struct net_device *dev)
+{
+       return tg3_get_sset_count(dev, ETH_SS_STATS);
+}
+
+static int tg3_get_test_count (struct net_device *dev)
+{
+       return tg3_get_sset_count(dev, ETH_SS_TEST);
+}
+#endif
+
 static void tg3_get_strings (struct net_device *dev, u32 stringset, u8 *buf)
 {
        switch (stringset) {
@@ -9480,7 +9626,12 @@ static int tg3_phys_id(struct net_device *dev, u32 data)
                        tw32(MAC_LED_CTRL, LED_CTRL_LNKLED_OVERRIDE |
                                           LED_CTRL_TRAFFIC_OVERRIDE);
 
+#if (LINUX_VERSION_CODE < 0x20607)
+               set_current_state(TASK_INTERRUPTIBLE);
+               if (schedule_timeout(HZ / 2))
+#else
                if (msleep_interruptible(500))
+#endif
                        break;
        }
        tw32(MAC_LED_CTRL, tp->led_ctrl);
@@ -9636,7 +9787,7 @@ out:
 }
 
 #define TG3_SERDES_TIMEOUT_SEC 2
-#define TG3_COPPER_TIMEOUT_SEC 6
+#define TG3_COPPER_TIMEOUT_SEC 7
 
 static int tg3_test_link(struct tg3 *tp)
 {
@@ -9654,7 +9805,12 @@ static int tg3_test_link(struct tg3 *tp)
                if (netif_carrier_ok(tp->dev))
                        return 0;
 
+#if (LINUX_VERSION_CODE < 0x20607)
+               set_current_state(TASK_INTERRUPTIBLE);
+               if (schedule_timeout(HZ))
+#else
                if (msleep_interruptible(1000))
+#endif
                        break;
        }
 
@@ -9941,9 +10097,7 @@ static int tg3_test_memory(struct tg3 *tp)
                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_57780 ||
-                   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)
                        mem_tbl = mem_tbl_5755;
                else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
                        mem_tbl = mem_tbl_5906;
@@ -10073,6 +10227,9 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
        tp->tx_prod++;
        num_pkts++;
 
+       /* Some platforms need to sync memory here */
+       wmb();
+
        tw32_tx_mbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW,
                     tp->tx_prod);
        tr32_mailbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW);
@@ -10149,10 +10306,12 @@ static int tg3_test_loopback(struct tg3 *tp)
        if (err)
                return TG3_LOOPBACK_FAILED;
 
+       /* Turn off gphy autopowerdown. */
+       if (tp->tg3_flags3 & TG3_FLG3_PHY_ENABLE_APD)
+               tg3_phy_toggle_apd(tp, 0);
+
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
-           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) {
                int i;
                u32 status;
 
@@ -10180,21 +10339,22 @@ static int tg3_test_loopback(struct tg3 *tp)
                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_57780 ||
-           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) {
                tw32(TG3_CPMU_CTRL, cpmuctrl);
 
                /* Release the mutex */
                tw32(TG3_CPMU_MUTEX_GNT, CPMU_MUTEX_GNT_DRIVER);
        }
 
-       if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) &&
-           !(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)) {
+       if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) {
                if (tg3_run_loopback(tp, TG3_PHY_LOOPBACK))
                        err |= TG3_PHY_LOOPBACK_FAILED;
        }
 
+       /* Re-enable gphy autopowerdown. */
+       if (tp->tg3_flags3 & TG3_FLG3_PHY_ENABLE_APD)
+               tg3_phy_toggle_apd(tp, 1);
+
        return err;
 }
 
@@ -10217,10 +10377,9 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
                data[1] = 1;
        }
        if (etest->flags & ETH_TEST_FL_OFFLINE) {
-               int err, err2 = 0, irq_sync = 0;
+               int err, irq_sync = 0;
 
                if (netif_running(dev)) {
-                       tg3_phy_stop(tp);
                        tg3_netif_stop(tp);
                        irq_sync = 1;
                }
@@ -10261,15 +10420,11 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
                tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
                if (netif_running(dev)) {
                        tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
-                       err2 = tg3_restart_hw(tp, 1);
-                       if (!err2)
+                       if (!tg3_restart_hw(tp, 1))
                                tg3_netif_start(tp);
                }
 
                tg3_full_unlock(tp);
-
-               if (irq_sync && !err2)
-                       tg3_phy_start(tp);
        }
        if (tp->link_config.phy_is_low_power)
                tg3_set_power_state(tp, PCI_D3hot);
@@ -10278,16 +10433,14 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
 
 static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
+#if (LINUX_VERSION_CODE >= 0x020607)
        struct mii_ioctl_data *data = if_mii(ifr);
+#else
+       struct mii_ioctl_data *data = (struct mii_ioctl_data *) &ifr->ifr_ifru;
+#endif
        struct tg3 *tp = netdev_priv(dev);
        int err;
 
-       if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
-               if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
-                       return -EAGAIN;
-               return phy_mii_ioctl(tp->mdio_bus.phy_map[PHY_ADDR], data, cmd);
-       }
-
        switch(cmd) {
        case SIOCGMIIPHY:
                data->phy_id = PHY_ADDR;
@@ -10354,6 +10507,21 @@ static void tg3_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
 
        tg3_full_unlock(tp);
 }
+
+static void tg3_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
+{
+       struct tg3 *tp = netdev_priv(dev);
+
+       if (netif_running(dev))
+               tg3_netif_stop(tp);
+
+       tg3_full_lock(tp, 0);
+       vlan_group_set_device(tp->vlgrp, vid, NULL);
+       tg3_full_unlock(tp);
+
+       if (netif_running(dev))
+               tg3_netif_start(tp);
+}
 #endif
 
 static int tg3_get_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
@@ -10418,7 +10586,7 @@ static int tg3_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
        return 0;
 }
 
-static const struct ethtool_ops tg3_ethtool_ops = {
+static struct ethtool_ops tg3_ethtool_ops = {
        .get_settings           = tg3_get_settings,
        .set_settings           = tg3_set_settings,
        .get_drvinfo            = tg3_get_drvinfo,
@@ -10430,25 +10598,49 @@ static const struct ethtool_ops tg3_ethtool_ops = {
        .set_msglevel           = tg3_set_msglevel,
        .nway_reset             = tg3_nway_reset,
        .get_link               = ethtool_op_get_link,
+#if (LINUX_VERSION_CODE >= 0x20418)
        .get_eeprom_len         = tg3_get_eeprom_len,
+#endif
+#ifdef ETHTOOL_GEEPROM
        .get_eeprom             = tg3_get_eeprom,
+#endif
+#ifdef ETHTOOL_SEEPROM
        .set_eeprom             = tg3_set_eeprom,
+#endif
        .get_ringparam          = tg3_get_ringparam,
        .set_ringparam          = tg3_set_ringparam,
        .get_pauseparam         = tg3_get_pauseparam,
        .set_pauseparam         = tg3_set_pauseparam,
        .get_rx_csum            = tg3_get_rx_csum,
        .set_rx_csum            = tg3_set_rx_csum,
+       .get_tx_csum            = ethtool_op_get_tx_csum,
+#ifdef BCM_HAS_SET_TX_CSUM
        .set_tx_csum            = tg3_set_tx_csum,
+#endif
+       .get_sg                 = ethtool_op_get_sg,
        .set_sg                 = ethtool_op_set_sg,
+#if TG3_TSO_SUPPORT != 0
+       .get_tso                = ethtool_op_get_tso,
        .set_tso                = tg3_set_tso,
+#endif
+#if (LINUX_VERSION_CODE < 0x20618)
+       .self_test_count        = tg3_get_test_count,
+#endif
        .self_test              = tg3_self_test,
        .get_strings            = tg3_get_strings,
        .phys_id                = tg3_phys_id,
+#if (LINUX_VERSION_CODE < 0x20618)
+       .get_stats_count        = tg3_get_stats_count,
+#endif
        .get_ethtool_stats      = tg3_get_ethtool_stats,
        .get_coalesce           = tg3_get_coalesce,
        .set_coalesce           = tg3_set_coalesce,
+#if (LINUX_VERSION_CODE >= 0x20618)
        .get_sset_count         = tg3_get_sset_count,
+#endif
+#if defined(ETHTOOL_GPERMADDR) && (LINUX_VERSION_CODE < 0x020617)
+       .get_perm_addr          = ethtool_op_get_perm_addr,
+#endif
 };
 
 static void __devinit tg3_get_eeprom_size(struct tg3 *tp)
@@ -10805,7 +10997,12 @@ static void __devinit tg3_nvram_init(struct tg3 *tp)
              (EEPROM_DEFAULT_CLOCK_PERIOD <<
               EEPROM_ADDR_CLKPERD_SHIFT)));
 
+#if (LINUX_VERSION_CODE < 0x20607)
+       set_current_state(TASK_UNINTERRUPTIBLE);
+       schedule_timeout(HZ / 1000);
+#else
        msleep(1);
+#endif
 
        /* Enable seeprom accesses. */
        tw32_f(GRC_LOCAL_CTRL,
@@ -10830,9 +11027,7 @@ static void __devinit tg3_nvram_init(struct tg3 *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_57780 ||
-                        GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
+                        GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784)
                        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);
@@ -10879,7 +11074,12 @@ static int tg3_nvram_read_using_eeprom(struct tg3 *tp,
 
                if (tmp & EEPROM_ADDR_COMPLETE)
                        break;
+#if (LINUX_VERSION_CODE < 0x20607)
+               set_current_state(TASK_UNINTERRUPTIBLE);
+               schedule_timeout(HZ / 1000);
+#else
                msleep(1);
+#endif
        }
        if (!(tmp & EEPROM_ADDR_COMPLETE))
                return -EBUSY;
@@ -11021,7 +11221,12 @@ static int tg3_nvram_write_block_using_eeprom(struct tg3 *tp,
 
                        if (val & EEPROM_ADDR_COMPLETE)
                                break;
+#if (LINUX_VERSION_CODE < 0x20607)
+                       set_current_state(TASK_UNINTERRUPTIBLE);
+                       schedule_timeout(HZ / 1000);
+#else
                        msleep(1);
+#endif
                }
                if (!(val & EEPROM_ADDR_COMPLETE)) {
                        rc = -EBUSY;
@@ -11162,9 +11367,7 @@ static int tg3_nvram_write_block_buffered(struct tg3 *tp, u32 offset, u32 len,
                    (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_57780) &&
                    (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5761) &&
-                   (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785) &&
                    (tp->nvram_jedecnum == JEDEC_ST) &&
                    (nvram_cmd & NVRAM_CMD_FIRST)) {
 
@@ -11308,7 +11511,12 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
        pci_read_config_word(tp->pdev, tp->pm_cap + PCI_PM_CTRL, &pmcsr);
        pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
        pci_write_config_word(tp->pdev, tp->pm_cap + PCI_PM_CTRL, pmcsr);
+#if (LINUX_VERSION_CODE < 0x20607)
+       set_current_state(TASK_UNINTERRUPTIBLE);
+       schedule_timeout(HZ / 1000);
+#else
        msleep(1);
+#endif
 
        /* Make sure register accesses (indirect or otherwise)
         * will function correctly.
@@ -11339,17 +11547,15 @@ 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)) {
+                   (val & VCPU_CFGSHDW_WOL_MAGPKT))
                        tp->tg3_flags |= TG3_FLAG_WOL_ENABLE;
-                       device_set_wakeup_enable(&tp->pdev->dev, true);
-               }
                return;
        }
 
        tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val);
        if (val == NIC_SRAM_DATA_SIG_MAGIC) {
                u32 nic_cfg, led_cfg;
-               u32 nic_phy_id, ver, cfg2 = 0, cfg4 = 0, eeprom_phy_id;
+               u32 nic_phy_id, ver, cfg2 = 0, eeprom_phy_id;
                int eeprom_phy_serdes = 0;
 
                tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg);
@@ -11363,9 +11569,6 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
                    (ver > 0) && (ver < 0x100))
                        tg3_read_mem(tp, NIC_SRAM_DATA_CFG_2, &cfg2);
 
-               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
-                       tg3_read_mem(tp, NIC_SRAM_DATA_CFG_4, &cfg4);
-
                if ((nic_cfg & NIC_SRAM_DATA_CFG_PHY_TYPE_MASK) ==
                    NIC_SRAM_DATA_CFG_PHY_TYPE_FIBER)
                        eeprom_phy_serdes = 1;
@@ -11471,11 +11674,9 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
                    !(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)) {
+               if (tp->tg3_flags & TG3_FLAG_WOL_CAP &&
+                   nic_cfg & NIC_SRAM_DATA_CFG_WOL_ENABLE)
                        tp->tg3_flags |= TG3_FLAG_WOL_ENABLE;
-                       device_set_wakeup_enable(&tp->pdev->dev, true);
-               }
 
                if (cfg2 & (1 << 17))
                        tp->tg3_flags2 |= TG3_FLG2_CAPACITIVE_COUPLING;
@@ -11485,6 +11686,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;
 
@@ -11492,13 +11698,6 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
                        if (cfg3 & NIC_SRAM_ASPM_DEBOUNCE)
                                tp->tg3_flags |= TG3_FLAG_ASPM_WORKAROUND;
                }
-
-               if (cfg4 & NIC_SRAM_RGMII_STD_IBND_DISABLE)
-                       tp->tg3_flags3 |= TG3_FLG3_RGMII_STD_IBND_DISABLE;
-               if (cfg4 & NIC_SRAM_RGMII_EXT_IBND_RX_EN)
-                       tp->tg3_flags3 |= TG3_FLG3_RGMII_EXT_IBND_RX_EN;
-               if (cfg4 & NIC_SRAM_RGMII_EXT_IBND_TX_EN)
-                       tp->tg3_flags3 |= TG3_FLG3_RGMII_EXT_IBND_TX_EN;
        }
 }
 
@@ -11557,9 +11756,6 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
        u32 hw_phy_id, hw_phy_id_masked;
        int err;
 
-       if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)
-               return tg3_phy_init(tp);
-
        /* Reading the PHY ID register can conflict with ASF
         * firwmare access to the PHY hardware.
         */
@@ -11719,7 +11915,12 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
                                                     PCI_VPD_ADDR, &tmp16);
                                if (tmp16 & 0x8000)
                                        break;
+#if (LINUX_VERSION_CODE < 0x20607)
+                               set_current_state(TASK_UNINTERRUPTIBLE);
+                               schedule_timeout(1);
+#else
                                msleep(1);
+#endif
                        }
                        if (!(tmp16 & 0x8000))
                                goto out_not_found;
@@ -11796,6 +11997,51 @@ static int __devinit tg3_fw_img_is_valid(struct tg3 *tp, u32 offset)
        return 1;
 }
 
+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_swab(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_fw_ver(struct tg3 *tp)
 {
        u32 val, offset, start;
@@ -11805,8 +12051,12 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp)
        if (tg3_nvram_read_swab(tp, 0, &val))
                return;
 
-       if (val != TG3_EEPROM_MAGIC)
+       if (val != TG3_EEPROM_MAGIC) {
+               if ((val & TG3_EEPROM_MAGIC_FW_MSK) == TG3_EEPROM_MAGIC_FW)
+                       tg3_read_sb_ver(tp, val);
+
                return;
+       }
 
        if (tg3_nvram_read_swab(tp, 0xc, &offset) ||
            tg3_nvram_read_swab(tp, 0x4, &start))
@@ -11884,6 +12134,7 @@ static struct pci_dev * __devinit tg3_find_peer(struct tg3 *);
 
 static int __devinit tg3_get_invariants(struct tg3 *tp)
 {
+#if (LINUX_VERSION_CODE >= 0x2060a)
        static struct pci_device_id write_reorder_chipsets[] = {
                { PCI_DEVICE(PCI_VENDOR_ID_AMD,
                             PCI_DEVICE_ID_AMD_FE_GATE_700C) },
@@ -11893,12 +12144,13 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                             PCI_DEVICE_ID_VIA_8385_0) },
                { },
        };
+#endif
        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.
@@ -11927,7 +12179,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;
+               tp->pci_chip_rev_id = prod_id_asic_rev & PROD_ID_ASIC_REV_MASK;
        }
 
        /* Wrong chip ID in 5752 A0. This code can be removed later
@@ -11981,7 +12233,11 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                                continue;
                        }
                        if (pci_id->rev != PCI_ANY_ID) {
-                               if (bridge->revision > pci_id->rev)
+                               u8 rev;
+
+                               pci_read_config_byte(bridge, PCI_REVISION_ID,
+                                                    &rev);
+                               if (rev > pci_id->rev)
                                        continue;
                        }
                        if (bridge->subordinate &&
@@ -12081,9 +12337,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
            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_57780 ||
            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->tg3_flags2 & TG3_FLG2_5780_CLASS))
                tp->tg3_flags2 |= TG3_FLG2_5750_PLUS;
@@ -12104,9 +12358,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                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_57780 ||
                    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->tg3_flags2 |= TG3_FLG2_HW_TSO_2;
                        tp->tg3_flags2 |= TG3_FLG2_1SHOT_MSI;
@@ -12119,25 +12371,42 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                }
        }
 
-       if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
+       if (!(tp->tg3_flags2 & TG3_FLG2_5750_PLUS) ||
             (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->tg3_flags3 |= TG3_FLG3_CLKREQ_BUG;
                }
+       } 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
@@ -12146,7 +12415,16 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
         * every mailbox register write to force the writes to be
         * posted to the chip in order.
         */
+#if (LINUX_VERSION_CODE < 0x2060a)
+       if ((pci_find_device(PCI_VENDOR_ID_AMD,
+                            PCI_DEVICE_ID_AMD_FE_GATE_700C, NULL) ||
+            pci_find_device(PCI_VENDOR_ID_AMD,
+                            PCI_DEVICE_ID_AMD_8131_BRIDGE, NULL) ||
+            pci_find_device(PCI_VENDOR_ID_VIA,
+                            PCI_DEVICE_ID_VIA_8385_0, NULL)) &&
+#else
        if (pci_dev_present(write_reorder_chipsets) &&
+#endif
            !(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS))
                tp->tg3_flags |= TG3_FLAG_MBOX_WRITE_REORDER;
 
@@ -12163,29 +12441,18 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                                       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_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;
@@ -12210,12 +12477,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)
@@ -12309,18 +12570,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        }
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
-           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)
                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.
@@ -12398,15 +12650,13 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                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_57780 ||
                    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) {
                        if (tp->pdev->device != PCI_DEVICE_ID_TIGON3_5756 &&
                            tp->pdev->device != PCI_DEVICE_ID_TIGON3_5722)
                                tp->tg3_flags2 |= TG3_FLG2_PHY_JITTER_BUG;
                        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 if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906)
                        tp->tg3_flags2 |= TG3_FLG2_PHY_BER_BUG;
        }
 
@@ -12427,12 +12677,9 @@ 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)
-               tp->tg3_flags3 |= TG3_FLG3_USE_PHYLIB;
-
-       err = tg3_mdio_init(tp);
-       if (err)
-               return err;
+       /* Initialize MAC MI mode, polling disabled. */
+       tw32_f(MAC_MI_MODE, tp->mi_mode);
+       udelay(80);
 
        /* Initialize data/descriptor byte/word swapping. */
        val = tr32(GRC_MODE);
@@ -12494,7 +12741,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        }
 
        /* Preserve the APE MAC_MODE bits */
-       if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
                tp->mac_mode = tr32(MAC_MODE) |
                               MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN;
        else
@@ -12520,7 +12767,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                printk(KERN_ERR PFX "(%s) phy probe failed, err %d\n",
                       pci_name(tp->pdev), err);
                /* ... but do not return immediately ... */
-               tg3_mdio_fini(tp);
        }
 
        tg3_read_partno(tp);
@@ -12567,18 +12813,21 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        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_57780 ||
            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 + VLAN_HLEN;
+       tp->rx_copy_thresh = RX_COPY_THRESHOLD;
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 &&
-           (tp->tg3_flags & TG3_FLAG_PCIX_MODE) != 0)
-               tp->rx_offset = 0;
+           (tp->tg3_flags & TG3_FLAG_PCIX_MODE) != 0) {
+               tp->rx_offset -= NET_IP_ALIGN;
+#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
+               tp->rx_copy_thresh = ~(u16)0;
+#endif
+       }
 
        tp->rx_std_max_post = TG3_RX_RING_SIZE;
 
@@ -12696,7 +12945,9 @@ static int __devinit tg3_get_device_address(struct tg3 *tp)
 #endif
                return -EINVAL;
        }
+#ifdef ETHTOOL_GPERMADDR
        memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
+#endif
        return 0;
 }
 
@@ -13083,17 +13334,25 @@ static int __devinit tg3_test_dma(struct tg3 *tp)
        }
        if ((tp->dma_rwctrl & DMA_RWCTRL_WRITE_BNDRY_MASK) !=
            DMA_RWCTRL_WRITE_BNDRY_16) {
+#if (LINUX_VERSION_CODE >= 0x2060a)
                static struct pci_device_id dma_wait_state_chipsets[] = {
                        { PCI_DEVICE(PCI_VENDOR_ID_APPLE,
                                     PCI_DEVICE_ID_APPLE_UNI_N_PCI15) },
                        { },
                };
+#endif
 
                /* DMA test passed without adjusting DMA boundary,
                 * now look for chipsets that are known to expose the
                 * DMA bug without failing the test.
                 */
-               if (pci_dev_present(dma_wait_state_chipsets)) {
+#if (LINUX_VERSION_CODE < 0x2060a)
+               if (pci_find_device(PCI_VENDOR_ID_APPLE,
+                       PCI_DEVICE_ID_APPLE_UNI_N_PCI15, NULL))
+#else
+               if (pci_dev_present(dma_wait_state_chipsets))
+#endif
+               {
                        tp->dma_rwctrl &= ~DMA_RWCTRL_WRITE_BNDRY_MASK;
                        tp->dma_rwctrl |= DMA_RWCTRL_WRITE_BNDRY_16;
                }
@@ -13190,7 +13449,6 @@ static char * __devinit tg3_phy_string(struct tg3 *tp)
        case PHY_ID_BCM5756:    return "5722/5756";
        case PHY_ID_BCM5906:    return "5906";
        case PHY_ID_BCM5761:    return "5761";
-       case PHY_ID_BCM57780:   return "57780";
        case PHY_ID_BCM8002:    return "8002/serdes";
        case 0:                 return "serdes";
        default:                return "unknown";
@@ -13296,7 +13554,6 @@ 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;
@@ -13340,9 +13597,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");
@@ -13350,11 +13604,15 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
                goto err_out_free_res;
        }
 
+       SET_MODULE_OWNER(dev);
+#if (LINUX_VERSION_CODE >= 0x20419)
        SET_NETDEV_DEV(dev, &pdev->dev);
+#endif
 
 #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;
+       dev->vlan_rx_kill_vid = tg3_vlan_rx_kill_vid;
 #endif
 
        tp = netdev_priv(dev);
@@ -13392,9 +13650,17 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
 #endif
        spin_lock_init(&tp->lock);
        spin_lock_init(&tp->indirect_lock);
+#if defined(INIT_DELAYED_WORK_DEFERRABLE) || defined(INIT_WORK_NAR)
        INIT_WORK(&tp->reset_task, tg3_reset_task);
+#else
+       INIT_WORK(&tp->reset_task, tg3_reset_task, tp);
+#endif
 
-       tp->regs = ioremap_nocache(tg3reg_base, tg3reg_len);
+       dev->mem_start = pci_resource_start(pdev, 0);
+       tg3reg_len = pci_resource_len(pdev, 0);
+       dev->mem_end = dev->mem_start + tg3reg_len;
+
+       tp->regs = ioremap_nocache(dev->mem_start, tg3reg_len);
        if (!tp->regs) {
                printk(KERN_ERR PFX "Cannot map device registers, "
                       "aborting.\n");
@@ -13415,12 +13681,17 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
        dev->set_mac_address = tg3_set_mac_addr;
        dev->do_ioctl = tg3_ioctl;
        dev->tx_timeout = tg3_tx_timeout;
+#ifdef TG3_NAPI
        netif_napi_add(dev, &tp->napi, tg3_poll, 64);
+#else
+       dev->poll = tg3_poll;
+       dev->weight = 64;
+#endif
        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
+#if defined(HAVE_POLL_CONTROLLER) || defined(CONFIG_NET_POLL_CONTROLLER)
        dev->poll_controller = tg3_poll_controller;
 #endif
 
@@ -13472,6 +13743,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
 
        tg3_init_bufmgr_config(tp);
 
+#if TG3_TSO_SUPPORT != 0
        if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) {
                tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
        }
@@ -13496,12 +13768,11 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
                        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_57780 ||
-                       GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
+                    GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX))
                        dev->features |= NETIF_F_TSO_ECN;
        }
 
+#endif
 
        if (tp->pci_chip_rev_id == CHIPREV_ID_5705_A1 &&
            !(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) &&
@@ -13518,6 +13789,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
        }
 
        if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
+               resource_size_t tg3reg_base;
+
                if (!(pci_resource_flags(pdev, 2) & IORESOURCE_MEM)) {
                        printk(KERN_ERR PFX "Cannot find proper PCI device "
                               "base address for APE, aborting.\n");
@@ -13560,15 +13833,23 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
         * checksumming.
         */
        if ((tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) == 0) {
+#ifdef NETIF_F_IPV6_CSUM
                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)
+            dev->features |= NETIF_F_IPV6_CSUM;
+#else
                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_57780 ||
-                   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;
-
+                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
+                       dev->features |= NETIF_F_HW_CSUM;
+               else
+                       dev->features |= NETIF_F_IP_CSUM;
+               dev->features |= NETIF_F_SG;
+#endif
                tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS;
        } else
                tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS;
@@ -13629,7 +13910,11 @@ err_out_iounmap:
        }
 
 err_out_free_dev:
+#if (LINUX_VERSION_CODE >= 0x20418)
        free_netdev(dev);
+#else
+       kfree(dev);
+#endif
 
 err_out_free_res:
        pci_release_regions(pdev);
@@ -13647,13 +13932,9 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev)
        if (dev) {
                struct tg3 *tp = netdev_priv(dev);
 
+#if (LINUX_VERSION_CODE >= 0x20600)
                flush_scheduled_work();
-
-               if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
-                       tg3_phy_fini(tp);
-                       tg3_mdio_fini(tp);
-               }
-
+#endif
                unregister_netdev(dev);
                if (tp->aperegs) {
                        iounmap(tp->aperegs);
@@ -13663,31 +13944,43 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev)
                        iounmap(tp->regs);
                        tp->regs = NULL;
                }
+#if (LINUX_VERSION_CODE >= 0x20418)
                free_netdev(dev);
+#else
+               kfree(dev);
+#endif
                pci_release_regions(pdev);
                pci_disable_device(pdev);
                pci_set_drvdata(pdev, NULL);
        }
 }
 
+#if (LINUX_VERSION_CODE < 0x2060b)
+static int tg3_suspend(struct pci_dev *pdev, u32 state)
+#else
 static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
+#endif
 {
        struct net_device *dev = pci_get_drvdata(pdev);
        struct tg3 *tp = netdev_priv(dev);
-       pci_power_t target_state;
        int err;
 
        /* PCI register 4 needs to be saved whether netif_running() or not.
         * MSI address and data need to be saved if using MSI and
         * netif_running().
         */
+#if (LINUX_VERSION_CODE < 0x2060a)
+       pci_save_state(pdev, tp->pci_cfg_state);
+#else
        pci_save_state(pdev);
+#endif
 
        if (!netif_running(dev))
                return 0;
 
+#if (LINUX_VERSION_CODE >= 0x20600)
        flush_scheduled_work();
-       tg3_phy_stop(tp);
+#endif
        tg3_netif_stop(tp);
 
        del_timer_sync(&tp->timer);
@@ -13703,17 +13996,16 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
        tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
        tg3_full_unlock(tp);
 
-       target_state = pdev->pm_cap ? pci_target_state(pdev) : PCI_D3hot;
-
-       err = tg3_set_power_state(tp, target_state);
+#if (LINUX_VERSION_CODE < 0x2060b)
+       err = tg3_set_power_state(tp, state);
+#else
+       err = tg3_set_power_state(tp, pci_choose_state(pdev, state));
+#endif
        if (err) {
-               int err2;
-
                tg3_full_lock(tp, 0);
 
                tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
-               err2 = tg3_restart_hw(tp, 1);
-               if (err2)
+               if (tg3_restart_hw(tp, 1))
                        goto out;
 
                tp->timer.expires = jiffies + tp->timer_offset;
@@ -13724,9 +14016,6 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
 
 out:
                tg3_full_unlock(tp);
-
-               if (!err2)
-                       tg3_phy_start(tp);
        }
 
        return err;
@@ -13738,7 +14027,11 @@ static int tg3_resume(struct pci_dev *pdev)
        struct tg3 *tp = netdev_priv(dev);
        int err;
 
+#if (LINUX_VERSION_CODE < 0x2060a)
+       pci_restore_state(tp->pdev, tp->pci_cfg_state);
+#else
        pci_restore_state(tp->pdev);
+#endif
 
        if (!netif_running(dev))
                return 0;
@@ -13747,6 +14040,17 @@ static int tg3_resume(struct pci_dev *pdev)
        if (err)
                return err;
 
+#ifndef BCM_HAS_INTX_MSI_WORKAROUND
+       /* Hardware bug - MSI won't work if INTX disabled. */
+       if ((tp->tg3_flags2 & TG3_FLG2_5780_CLASS) &&
+           (tp->tg3_flags2 & TG3_FLG2_USING_MSI))
+#if (LINUX_VERSION_CODE < 0x2060e)
+               tg3_enable_intx(tp->pdev);
+#else
+               pci_intx(tp->pdev, 1);
+#endif
+#endif
+
        netif_device_attach(dev);
 
        tg3_full_lock(tp, 0);
@@ -13764,9 +14068,6 @@ static int tg3_resume(struct pci_dev *pdev)
 out:
        tg3_full_unlock(tp);
 
-       if (!err)
-               tg3_phy_start(tp);
-
        return err;
 }
 
@@ -13781,7 +14082,11 @@ static struct pci_driver tg3_driver = {
 
 static int __init tg3_init(void)
 {
+#if (LINUX_VERSION_CODE < 0x020613)
+       return pci_module_init(&tg3_driver);
+#else
        return pci_register_driver(&tg3_driver);
+#endif
 }
 
 static void __exit tg3_cleanup(void)
index 09b763d5bebed07e74a0926273247684acbbb43b..57dca63fe4cd384f2147426464b134db9a63c43a 100644 (file)
@@ -9,6 +9,423 @@
 #ifndef _T3_H
 #define _T3_H
 
+#if !defined(PCI_DEVICE_ID_TIGON3_5704S_2)
+#define PCI_DEVICE_ID_TIGON3_5704S_2   0x1649
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5705F)
+#define PCI_DEVICE_ID_TIGON3_5705F     0x166e
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5720)
+#define PCI_DEVICE_ID_TIGON3_5720      0x1658
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5721)
+#define PCI_DEVICE_ID_TIGON3_5721      0x1659
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5750)
+#define PCI_DEVICE_ID_TIGON3_5750      0x1676
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5751)
+#define PCI_DEVICE_ID_TIGON3_5751      0x1677
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5750M)
+#define PCI_DEVICE_ID_TIGON3_5750M     0x167c
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5751M)
+#define PCI_DEVICE_ID_TIGON3_5751M     0x167d
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5751F)
+#define PCI_DEVICE_ID_TIGON3_5751F     0x167e
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5789)
+#define PCI_DEVICE_ID_TIGON3_5789      0x169d
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5753)
+#define PCI_DEVICE_ID_TIGON3_5753      0x16f7
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5753M)
+#define PCI_DEVICE_ID_TIGON3_5753M     0x16fd
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5753F)
+#define PCI_DEVICE_ID_TIGON3_5753F     0x16fe
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5781)
+#define PCI_DEVICE_ID_TIGON3_5781      0x16dd
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5752)
+#define PCI_DEVICE_ID_TIGON3_5752      0x1600
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5752M)
+#define PCI_DEVICE_ID_TIGON3_5752M     0x1601
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5714)
+#define PCI_DEVICE_ID_TIGON3_5714      0x1668
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5714S)
+#define PCI_DEVICE_ID_TIGON3_5714S     0x1669
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5780)
+#define PCI_DEVICE_ID_TIGON3_5780      0x166a
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5780S)
+#define PCI_DEVICE_ID_TIGON3_5780S     0x166b
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5715)
+#define PCI_DEVICE_ID_TIGON3_5715      0x1678
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5715S)
+#define PCI_DEVICE_ID_TIGON3_5715S     0x1679
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5756)
+#define PCI_DEVICE_ID_TIGON3_5756      0x1674
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5754)
+#define PCI_DEVICE_ID_TIGON3_5754      0x167a
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5754M)
+#define PCI_DEVICE_ID_TIGON3_5754M     0x1672
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5755)
+#define PCI_DEVICE_ID_TIGON3_5755      0x167b
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5755M)
+#define PCI_DEVICE_ID_TIGON3_5755M     0x1673
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5722)
+#define PCI_DEVICE_ID_TIGON3_5722      0x165a
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5786)
+#define PCI_DEVICE_ID_TIGON3_5786      0x169a
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5787M)
+#define PCI_DEVICE_ID_TIGON3_5787M     0x1693
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5787)
+#define PCI_DEVICE_ID_TIGON3_5787      0x169b
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5787F)
+#define PCI_DEVICE_ID_TIGON3_5787F     0x167f
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5906)
+#define PCI_DEVICE_ID_TIGON3_5906      0x1712
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5906M)
+#define PCI_DEVICE_ID_TIGON3_5906M     0x1713
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5784)
+#define PCI_DEVICE_ID_TIGON3_5784      0x1698
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5764)
+#define PCI_DEVICE_ID_TIGON3_5764      0x1684
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5723)
+#define PCI_DEVICE_ID_TIGON3_5723      0x165b
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5761)
+#define PCI_DEVICE_ID_TIGON3_5761      0x1681
+#endif
+
+#if !defined(PCI_DEVICE_ID_TIGON3_5761E)
+#define PCI_DEVICE_ID_TIGON3_5761E     0x1680
+#endif
+
+#define PCI_DEVICE_ID_TIGON3_5761S     0x1688
+#define PCI_DEVICE_ID_TIGON3_5761SE    0x1689
+
+#if !defined(PCI_DEVICE_ID_APPLE_TIGON3)
+#define PCI_DEVICE_ID_APPLE_TIGON3     0x1645
+#endif
+
+#if !defined(PCI_DEVICE_ID_APPLE_UNI_N_PCI15)
+#define PCI_DEVICE_ID_APPLE_UNI_N_PCI15        0x002e
+#endif
+
+#if !defined(PCI_DEVICE_ID_VIA_8385_0)
+#define PCI_DEVICE_ID_VIA_8385_0       0x3188
+#endif
+
+#if !defined(PCI_DEVICE_ID_AMD_8131_BRIDGE)
+#define PCI_DEVICE_ID_AMD_8131_BRIDGE  0x7450
+#endif
+
+#if !defined(PCI_DEVICE_ID_SERVERWORKS_EPB)
+#define PCI_DEVICE_ID_SERVERWORKS_EPB  0x0103
+#endif
+
+#if !defined(PCI_VENDOR_ID_ARIMA)
+#define PCI_VENDOR_ID_ARIMA            0x161f
+#endif
+
+#ifndef PCI_DEVICE
+#define PCI_DEVICE(vend,dev) \
+       .vendor = (vend), .device = (dev), \
+       .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
+#endif
+
+#if !defined(PCI_VPD_ADDR)
+#define PCI_VPD_ADDR   2
+#define PCI_VPD_DATA   4
+#endif
+
+#ifndef NETDEV_TX_OK
+#define NETDEV_TX_OK 0
+#endif
+
+#ifndef NETDEV_TX_BUSY
+#define NETDEV_TX_BUSY 1
+#endif
+
+#ifndef NETDEV_TX_LOCKED
+#define NETDEV_TX_LOCKED -1
+#endif
+
+#include "tg3_compat.h"
+
+#ifndef CHECKSUM_PARTIAL
+#define CHECKSUM_PARTIAL CHECKSUM_HW
+#endif
+
+#ifndef DMA_64BIT_MASK
+#define DMA_64BIT_MASK ((u64) 0xffffffffffffffffULL)
+#define DMA_32BIT_MASK ((u64) 0x00000000ffffffffULL)
+#endif
+
+#ifndef DMA_40BIT_MASK
+#define DMA_40BIT_MASK ((u64) 0x000000ffffffffffULL)
+#endif
+
+#ifndef mmiowb
+#define mmiowb()
+#endif
+
+#ifndef PCI_D0
+typedef u32 pm_message_t;
+typedef u32 pci_power_t;
+#define PCI_D0         0
+#define PCI_D1         1
+#define PCI_D2         2
+#define PCI_D3hot      3
+#endif
+
+#ifndef WARN_ON
+#define WARN_ON(x)
+#endif
+
+#ifndef IRQ_RETVAL
+typedef void irqreturn_t;
+#define IRQ_RETVAL(x)
+#define IRQ_HANDLED
+#define IRQ_NONE
+#endif
+
+#ifndef IRQF_SHARED
+#define IRQF_SHARED SA_SHIRQ
+#endif
+
+#ifndef IRQF_SAMPLE_RANDOM
+#define IRQF_SAMPLE_RANDOM SA_SAMPLE_RANDOM
+#endif
+
+#if (LINUX_VERSION_CODE < 0x020604)
+#define MODULE_VERSION(version)
+#endif
+
+#if (LINUX_VERSION_CODE <= 0x020600)
+#define schedule_work(x)       schedule_task(x)
+#define work_struct            tq_struct
+#define INIT_WORK(x, y, z)     INIT_TQUEUE(x, y, z)
+#endif
+
+#ifndef ADVERTISE_PAUSE
+#define ADVERTISE_PAUSE_CAP            0x0400
+#endif
+#ifndef ADVERTISE_PAUSE_ASYM
+#define ADVERTISE_PAUSE_ASYM           0x0800
+#endif
+#ifndef LPA_PAUSE
+#define LPA_PAUSE_CAP                  0x0400
+#endif
+#ifndef LPA_PAUSE_ASYM
+#define LPA_PAUSE_ASYM                 0x0800
+#endif
+#ifndef MII_CTRL1000
+#define MII_CTRL1000                   0x9
+#endif
+#ifndef MII_STAT1000
+#define MII_STAT1000            0xa
+#endif
+#ifndef BMCR_SPEED1000
+#define BMCR_SPEED1000                 0x40
+#endif
+#ifndef ADVERTISE_1000FULL
+#define ADVERTISE_1000FULL             0x0200
+#define ADVERTISE_1000HALF             0x0100
+#endif
+#ifndef ADVERTISE_1000XFULL
+#define ADVERTISE_1000XFULL            0x20
+#define ADVERTISE_1000XHALF            0x40
+#define ADVERTISE_1000XPAUSE           0x80
+#define ADVERTISE_1000XPSE_ASYM                0x100
+#define LPA_1000XFULL                  0x20
+#define LPA_1000XHALF                  0x40
+#define LPA_1000XPAUSE                 0x80
+#define LPA_1000XPAUSE_ASYM            0x100
+#endif
+
+#if (LINUX_VERSION_CODE >= 0x020618)
+#define TG3_NAPI
+#endif
+
+#if (LINUX_VERSION_CODE < 0x020420)
+#define ETH_SS_TEST  0
+#define ETH_SS_STATS 1
+#endif
+
+#if (LINUX_VERSION_CODE < 0x020605)
+#define pci_dma_sync_single_for_cpu(pdev, map, len, dir)       \
+       pci_dma_sync_single(pdev, map, len, dir)
+
+#define pci_dma_sync_single_for_device(pdev, map, len, dir)
+#endif
+
+#if (LINUX_VERSION_CODE < 0x020600)
+#define pci_get_device(x, y, z)        pci_find_device(x, y, z)
+#define pci_get_slot(x, y)     pci_find_slot((x)->number, y)
+#define pci_dev_put(x)
+#endif
+
+#if (LINUX_VERSION_CODE < 0x020547)
+#define pci_set_consistent_dma_mask(pdev, mask) (0)
+#endif
+
+#if (LINUX_VERSION_CODE < 0x020612)
+static inline struct sk_buff *netdev_alloc_skb(struct net_device *dev,
+               unsigned int length)
+{
+       struct sk_buff *skb = dev_alloc_skb(length);
+       if (skb)
+               skb->dev = dev;
+       return skb;
+}
+#endif
+
+#ifndef NETIF_F_GSO
+static inline void netif_tx_lock(struct net_device *dev)
+{
+       spin_lock(&dev->xmit_lock);
+       dev->xmit_lock_owner = smp_processor_id();
+}
+
+static inline void netif_tx_unlock(struct net_device *dev)
+{
+       dev->xmit_lock_owner = -1;
+       spin_unlock(&dev->xmit_lock);
+}
+#endif
+
+#if !defined(HAVE_NETDEV_PRIV) && (LINUX_VERSION_CODE != 0x020603) && (LINUX_VERSION_CODE != 0x020604) && (LINUX_VERSION_CODE != 0x20605)
+static inline void *netdev_priv(struct net_device *dev)
+{
+       return dev->priv;
+}
+#endif
+
+#ifdef OLD_NETIF
+static inline void netif_poll_disable(struct net_device *dev)
+{
+       while (test_and_set_bit(__LINK_STATE_RX_SCHED, &dev->state)) {
+               /* No hurry. */
+               current->state = TASK_INTERRUPTIBLE;
+               schedule_timeout(1);
+       }
+}
+
+static inline void netif_poll_enable(struct net_device *dev)
+{
+       clear_bit(__LINK_STATE_RX_SCHED, &dev->state);
+}
+
+static inline void netif_tx_disable(struct net_device *dev)
+{
+       spin_lock_bh(&dev->xmit_lock);
+       netif_stop_queue(dev);
+       spin_unlock_bh(&dev->xmit_lock);
+}
+
+#endif
+
+#if (LINUX_VERSION_CODE < 0x2060c)
+static inline int skb_header_cloned(struct sk_buff *skb) { return 0; }
+#endif
+
+#ifndef VLAN_GROUP_ARRAY_SPLIT_PARTS
+static inline void vlan_group_set_device(struct vlan_group *vg, int vlan_id,
+                                        struct net_device *dev)
+{
+       if (vg)
+               vg->vlan_devices[vlan_id] = dev;
+}
+#endif
+#if (LINUX_VERSION_CODE < 0x2060e)
+static inline void tg3_enable_intx(struct pci_dev *pdev)
+{
+       u16 pci_command;
+
+       pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
+       if (pci_command & PCI_COMMAND_INTX_DISABLE)
+               pci_write_config_word(pdev, PCI_COMMAND,
+                                     pci_command & ~PCI_COMMAND_INTX_DISABLE);
+}
+#endif
+
+#ifndef SET_MODULE_OWNER
+#define SET_MODULE_OWNER(dev) do { } while (0)
+#endif
+
+#ifndef NETIF_F_LLTX
+#define NETIF_F_LLTX   0
+#endif
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+#endif
+
 #define TG3_64BIT_REG_HIGH             0x00UL
 #define TG3_64BIT_REG_LOW              0x04UL
 
 #define TG3_BDINFO_NIC_ADDR            0xcUL /* 32-bit */
 #define TG3_BDINFO_SIZE                        0x10UL
 
-#define RX_COPY_THRESHOLD              256
+#define RX_COPY_THRESHOLD              256
 
 #define TG3_RX_INTERNAL_RING_SZ_5906   32
 
 #define  TG3PCI_DEVICE_TIGON3_2                 0x1645 /* BCM5701 */
 #define  TG3PCI_DEVICE_TIGON3_3                 0x1646 /* BCM5702 */
 #define  TG3PCI_DEVICE_TIGON3_4                 0x1647 /* BCM5703 */
-#define  TG3PCI_DEVICE_TIGON3_57780     0x1692
-#define  TG3PCI_DEVICE_TIGON3_57760     0x1690
-#define  TG3PCI_DEVICE_TIGON3_57790     0x1694
-#define  TG3PCI_DEVICE_TIGON3_57720     0x168c
 #define TG3PCI_COMMAND                 0x00000004
 #define TG3PCI_STATUS                  0x00000006
 #define TG3PCI_CCREVID                 0x00000008
 #define TG3PCI_IRQ_PIN                 0x0000003d
 #define TG3PCI_MIN_GNT                 0x0000003e
 #define TG3PCI_MAX_LAT                 0x0000003f
+#ifndef PCI_X_CMD_READ_2K
+#define  PCI_X_CMD_READ_2K             0x0008
+#endif
 /* 0x40 --> 0x64 unused */
 #define TG3PCI_MSI_DATA                        0x00000064
 /* 0x66 --> 0x68 unused */
 #define  CHIPREV_ID_5752_A1             0x6001
 #define  CHIPREV_ID_5714_A2             0x9002
 #define  CHIPREV_ID_5906_A1             0xc001
-#define  CHIPREV_ID_5784_A0             0x5784000
-#define  CHIPREV_ID_5784_A1             0x5784001
-#define  CHIPREV_ID_5761_A0             0x5761000
-#define  CHIPREV_ID_5761_A1             0x5761001
 #define  GET_ASIC_REV(CHIP_REV_ID)     ((CHIP_REV_ID) >> 12)
 #define   ASIC_REV_5700                         0x07
 #define   ASIC_REV_5701                         0x00
 #define   ASIC_REV_USE_PROD_ID_REG      0x0f
 #define   ASIC_REV_5784                         0x5784
 #define   ASIC_REV_5761                         0x5761
-#define   ASIC_REV_5785                         0x5785
-#define   ASIC_REV_57780                0x57780
 #define  GET_CHIP_REV(CHIP_REV_ID)     ((CHIP_REV_ID) >> 8)
 #define   CHIPREV_5700_AX               0x70
 #define   CHIPREV_5700_BX               0x71
 #define  MAC_MODE_TDE_ENABLE            0x00200000
 #define  MAC_MODE_RDE_ENABLE            0x00400000
 #define  MAC_MODE_FHDE_ENABLE           0x00800000
+#define  MAC_MODE_KEEP_FRAME_IN_WOL     0x01000000
 #define  MAC_MODE_APE_RX_EN             0x08000000
 #define  MAC_MODE_APE_TX_EN             0x10000000
 #define MAC_STATUS                     0x00000404
 #define MAC_SERDES_CFG                 0x00000590
 #define  MAC_SERDES_CFG_EDGE_SELECT     0x00001000
 #define MAC_SERDES_STAT                        0x00000594
-/* 0x598 --> 0x5a0 unused */
-#define MAC_PHYCFG1                    0x000005a0
-#define  MAC_PHYCFG1_RGMII_INT          0x00000001
-#define  MAC_PHYCFG1_RGMII_EXT_RX_DEC   0x02000000
-#define  MAC_PHYCFG1_RGMII_SND_STAT_EN  0x04000000
-#define  MAC_PHYCFG1_TXC_DRV            0x20000000
-#define MAC_PHYCFG2                    0x000005a4
-#define  MAC_PHYCFG2_INBAND_ENABLE      0x00000001
-#define MAC_EXT_RGMII_MODE             0x000005a8
-#define  MAC_RGMII_MODE_TX_ENABLE       0x00000001
-#define  MAC_RGMII_MODE_TX_LOWPWR       0x00000002
-#define  MAC_RGMII_MODE_TX_RESET        0x00000004
-#define  MAC_RGMII_MODE_RX_INT_B        0x00000100
-#define  MAC_RGMII_MODE_RX_QUALITY      0x00000200
-#define  MAC_RGMII_MODE_RX_ACTIVITY     0x00000400
-#define  MAC_RGMII_MODE_RX_ENG_DET      0x00000800
-/* 0x5ac --> 0x5b0 unused */
+/* 0x598 --> 0x5b0 unused */
 #define SERDES_RX_CTRL                 0x000005b0      /* 5780/5714 only */
 #define  SERDES_RX_SIG_DETECT           0x00000400
 #define SG_DIG_CTRL                    0x000005b0
 
 #define TG3_CPMU_LSPD_1000MB_CLK       0x0000360c
 #define  CPMU_LSPD_1000MB_MACCLK_62_5   0x00000000
+#define  CPMU_LSPD_1000MB_MACCLK_30_0   0x00030000
 #define  CPMU_LSPD_1000MB_MACCLK_12_5   0x00110000
 #define  CPMU_LSPD_1000MB_MACCLK_MASK   0x001f0000
 #define TG3_CPMU_LNK_AWARE_PWRMD       0x00003610
 #define  GRC_MISC_CFG_BOARD_ID_5788    0x00010000
 #define  GRC_MISC_CFG_BOARD_ID_5788M   0x00018000
 #define  GRC_MISC_CFG_BOARD_ID_AC91002A1 0x00018000
+#define  GRC_MISC_CFG_BOARD_ID_5754    0x00008000
+#define  GRC_MISC_CFG_BOARD_ID_5754M   0x0000c000
 #define  GRC_MISC_CFG_EPHY_IDDQ                0x00200000
 #define  GRC_MISC_CFG_KEEP_GPHY_POWER  0x04000000
 #define GRC_LOCAL_CTRL                 0x00006808
 #define TG3_NVM_DIRTYPE_SHIFT          24
 #define TG3_NVM_DIRTYPE_ASFINI         1
 
+#define TG3_EEPROM_SB_F1R0_EDH_OFF     0x10
+#define TG3_EEPROM_SB_F1R2_EDH_OFF     0x14
+#define TG3_EEPROM_SB_F1R2_MBA_OFF     0x10
+#define TG3_EEPROM_SB_F1R3_EDH_OFF     0x18
+#define TG3_EEPROM_SB_EDH_MAJ_MASK     0x00000700
+#define TG3_EEPROM_SB_EDH_MAJ_SHFT     8
+#define TG3_EEPROM_SB_EDH_MIN_MASK     0x000000ff
+#define TG3_EEPROM_SB_EDH_BLD_MASK     0x0000f800
+#define TG3_EEPROM_SB_EDH_BLD_SHFT     11
+
+
 /* 32K Window into NIC internal memory */
 #define NIC_SRAM_WIN_BASE              0x00008000
 
 
 #define NIC_SRAM_DATA_CFG_2            0x00000d38
 
+#define  NIC_SRAM_DATA_CFG_2_APD_EN     0x00000400
 #define  SHASTA_EXT_LED_MODE_MASK       0x00018000
 #define  SHASTA_EXT_LED_LEGACY          0x00000000
 #define  SHASTA_EXT_LED_SHARED          0x00008000
 #define NIC_SRAM_DATA_CFG_3            0x00000d3c
 #define  NIC_SRAM_ASPM_DEBOUNCE                 0x00000002
 
-#define NIC_SRAM_DATA_CFG_4            0x00000d60
-#define  NIC_SRAM_GMII_MODE             0x00000002
-#define  NIC_SRAM_RGMII_STD_IBND_DISABLE 0x00000004
-#define  NIC_SRAM_RGMII_EXT_IBND_RX_EN  0x00000008
-#define  NIC_SRAM_RGMII_EXT_IBND_TX_EN  0x00000010
-
 #define NIC_SRAM_RX_MINI_BUFFER_DESC   0x00001000
 
 #define NIC_SRAM_DMA_DESC_POOL_BASE    0x00002000
 #define MII_TG3_ISTAT                  0x1a /* IRQ status register */
 #define MII_TG3_IMASK                  0x1b /* IRQ mask register */
 
-#define MII_TG3_MISC_SHDW              0x1c
-#define MII_TG3_MISC_SHDW_WREN         0x8000
-#define MII_TG3_MISC_SHDW_APD_SEL      0x2800
-
-#define MII_TG3_MISC_SHDW_APD_WKTM_84MS        0x0001
-
 /* ISTAT/IMASK event bits */
 #define MII_TG3_INT_LINKCHG            0x0002
 #define MII_TG3_INT_SPEEDCHG           0x0004
 #define TG3_APE_LOCK_GRC                1
 #define TG3_APE_LOCK_MEM                4
 
-#define TG3_EEPROM_SB_F1R2_MBA_OFF     0x10
 
 
 /* There are two ways to manage the TX descriptors on the tigon3.
@@ -2055,35 +2452,35 @@ struct tg3_internal_buffer_desc {
 
 #define TG3_HW_STATUS_SIZE             0x50
 struct tg3_hw_status {
-       u32                             status;
+       volatile u32                    status;
 #define SD_STATUS_UPDATED              0x00000001
 #define SD_STATUS_LINK_CHG             0x00000002
 #define SD_STATUS_ERROR                        0x00000004
 
-       u32                             status_tag;
+       volatile u32                    status_tag;
 
 #ifdef __BIG_ENDIAN
-       u16                             rx_consumer;
-       u16                             rx_jumbo_consumer;
+       volatile u16                    rx_consumer;
+       volatile u16                    rx_jumbo_consumer;
 #else
-       u16                             rx_jumbo_consumer;
-       u16                             rx_consumer;
+       volatile u16                    rx_jumbo_consumer;
+       volatile u16                    rx_consumer;
 #endif
 
 #ifdef __BIG_ENDIAN
-       u16                             reserved;
-       u16                             rx_mini_consumer;
+       volatile u16                    reserved;
+       volatile u16                    rx_mini_consumer;
 #else
-       u16                             rx_mini_consumer;
-       u16                             reserved;
+       volatile u16                    rx_mini_consumer;
+       volatile u16                    reserved;
 #endif
        struct {
 #ifdef __BIG_ENDIAN
-               u16                     tx_consumer;
-               u16                     rx_producer;
+               volatile u16            tx_consumer;
+               volatile u16            rx_producer;
 #else
-               u16                     rx_producer;
-               u16                     tx_consumer;
+               volatile u16            rx_producer;
+               volatile u16            tx_consumer;
 #endif
        }                               idx[16];
 };
@@ -2236,7 +2633,6 @@ struct tg3_link_config {
        u16                             orig_speed;
        u8                              orig_duplex;
        u8                              orig_autoneg;
-       u32                             orig_advertising;
 };
 
 struct tg3_bufmgr_config {
@@ -2405,7 +2801,9 @@ struct tg3 {
        dma_addr_t                      tx_desc_mapping;
 
        /* begin "rx thread" cacheline section */
+#ifdef TG3_NAPI
        struct napi_struct              napi;
+#endif
        void                            (*write32_rx_mbox) (struct tg3 *, u32,
                                                            u32);
        u32                             rx_rcb_ptr;
@@ -2442,7 +2840,8 @@ struct tg3 {
        unsigned long                   last_event_jiffies;
        };
 
-       u32                             rx_offset;
+       u16                             rx_offset;
+       u16                             rx_copy_thresh;
        u32                             tg3_flags;
 #define TG3_FLAG_TAGGED_STATUS         0x00000001
 #define TG3_FLAG_TXD_MBOX_HWBUG                0x00000002
@@ -2513,15 +2912,9 @@ struct tg3 {
        u32                             tg3_flags3;
 #define TG3_FLG3_NO_NVRAM_ADDR_TRANS   0x00000001
 #define TG3_FLG3_ENABLE_APE            0x00000002
-#define TG3_FLG3_5761_5784_AX_FIXES    0x00000004
+#define TG3_FLG3_PHY_ENABLE_APD                0x00000004
 #define TG3_FLG3_5701_DMA_BUG          0x00000008
-#define TG3_FLG3_USE_PHYLIB            0x00000010
-#define TG3_FLG3_MDIOBUS_INITED                0x00000020
-#define TG3_FLG3_MDIOBUS_PAUSED                0x00000040
-#define TG3_FLG3_PHY_CONNECTED         0x00000080
-#define TG3_FLG3_RGMII_STD_IBND_DISABLE        0x00000100
-#define TG3_FLG3_RGMII_EXT_IBND_RX_EN  0x00000200
-#define TG3_FLG3_RGMII_EXT_IBND_TX_EN  0x00000400
+#define TG3_FLG3_CLKREQ_BUG            0x00000010
 
        struct timer_list               timer;
        u16                             timer_counter;
@@ -2557,13 +2950,16 @@ struct tg3 {
        u8                              pci_lat_timer;
        u8                              pci_hdr_type;
        u8                              pci_bist;
+#if (LINUX_VERSION_CODE < 0x2060a)
+       u32                             pci_cfg_state[64 / sizeof(u32)];
+#endif
 
        int                             pm_cap;
        int                             msi_cap;
+       union {
        int                             pcix_cap;
-
-       struct mii_bus                  mdio_bus;
-       int                             mdio_irq[PHY_MAX_ADDR];
+       int                             pcie_cap;
+       };
 
        /* PHY info */
        u32                             phy_id;
@@ -2593,10 +2989,6 @@ struct tg3 {
 #define PHY_REV_BCM5401_B2             0x3
 #define PHY_REV_BCM5401_C0             0x6
 #define PHY_REV_BCM5411_X0             0x1 /* Found on Netgear GA302T */
-#define TG3_PHY_ID_BCM50610            0x0143bd60
-#define TG3_PHY_ID_BCMAC131            0x0143bc70
-#define TG3_PHY_ID_BCM57780            0x03625d90
-
 
        u32                             led_ctrl;
        u32                             phy_otp;
diff --git a/drivers/net/tg3_compat.h b/drivers/net/tg3_compat.h
new file mode 100644 (file)
index 0000000..7d1a1d7
--- /dev/null
@@ -0,0 +1,209 @@
+#include "tg3_flags.h"
+
+#if !defined(__maybe_unused)
+#define __maybe_unused  /* unimplemented */
+#endif
+
+#if !defined(__iomem)
+#define __iomem
+#endif
+
+#ifndef __acquires
+#define __acquires(x)
+#endif
+
+#ifndef __releases
+#define __releases(x)
+#endif
+
+#ifndef PCI_DEVICE_ID_INTEL_PXH_0
+#define PCI_DEVICE_ID_INTEL_PXH_0 0x0329
+#endif
+
+#ifndef PCI_DEVICE_ID_INTEL_PXH_1
+#define PCI_DEVICE_ID_INTEL_PXH_1 0x032A
+#endif
+
+#ifndef BCM_HAS_BOOL
+typedef int bool;
+#define false 0
+#define true  1
+#endif
+
+#ifndef BCM_HAS_LE32
+typedef u32 __le32;
+typedef u32 __be32;
+#endif
+
+#ifndef BCM_HAS_RESOURCE_SIZE_T
+typedef unsigned long resource_size_t;
+#endif
+
+#ifndef BCM_HAS_KZALLOC
+static inline void *kzalloc(size_t size, int flags)
+{
+       void * memptr = kmalloc(size, flags);
+       if (memptr)
+               memset(memptr, 0, size);
+
+       return memptr;
+}
+#endif
+
+#ifndef BCM_HAS_USECS_TO_JIFFIES
+unsigned long usecs_to_jiffies(const unsigned int u)
+{
+       if (u > jiffies_to_usecs(MAX_JIFFY_OFFSET))
+               return MAX_JIFFY_OFFSET;
+#if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
+       return (u + (USEC_PER_SEC / HZ) - 1) / (USEC_PER_SEC / HZ);
+#elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC)
+       return u * (HZ / USEC_PER_SEC);
+#else
+       return (USEC_TO_HZ_MUL32 * u + USEC_TO_HZ_ADJ32)
+               >> USEC_TO_HZ_SHR32;
+#endif
+}
+#endif
+
+#ifndef BCM_HAS_SKB_COPY_FROM_LINEAR_DATA
+static inline void skb_copy_from_linear_data(const struct sk_buff *skb,
+                                            void *to,
+                                            const unsigned int len)
+{
+       memcpy(to, skb->data, len);
+}
+#endif
+
+#ifndef PCI_CAP_ID_EXP
+#define PCI_CAP_ID_EXP 0x10
+#endif
+#ifndef PCI_EXP_LNKCTL
+#define PCI_EXP_LNKCTL 16
+#endif
+#ifndef PCI_EXP_LNKCTL_CLKREQ_EN
+#define PCI_EXP_LNKCTL_CLKREQ_EN 0x100
+#endif
+
+#ifndef BCM_HAS_PCIE_SET_READRQ
+#ifndef PCI_EXP_DEVCTL
+#define PCI_EXP_DEVCTL         8
+#endif
+#ifndef PCI_EXP_DEVCTL_READRQ
+#define PCI_EXP_DEVCTL_READRQ  0x7000
+#endif
+static inline int pcie_set_readrq(struct pci_dev *dev, int rq)
+{
+       int cap, err = -EINVAL;
+       u16 ctl, v;
+
+       if (rq < 128 || rq > 4096 || (rq & (rq-1)))
+               goto out;
+
+       v = (ffs(rq) - 8) << 12;
+
+       cap = pci_find_capability(dev, PCI_CAP_ID_EXP);
+       if (!cap)
+               goto out;
+
+       err = pci_read_config_word(dev, cap + PCI_EXP_DEVCTL, &ctl);
+       if (err)
+               goto out;
+
+       if ((ctl & PCI_EXP_DEVCTL_READRQ) != v) {
+               ctl &= ~PCI_EXP_DEVCTL_READRQ;
+               ctl |= v;
+               err = pci_write_config_dword(dev, cap + PCI_EXP_DEVCTL, ctl);
+       }
+
+out:
+       return err;
+}
+#endif /* BCM_HAS_PCIE_SET_READRQ */
+
+#ifndef ETH_FCS_LEN
+#define ETH_FCS_LEN 4
+#endif
+
+#ifndef BCM_HAS_PRINT_MAC
+#define DECLARE_MAC_BUF(_mac) char _mac[18]
+
+#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
+
+static char *print_mac(char * buf, const u8 *addr)
+{
+       sprintf(buf, MAC_FMT,
+               addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
+       return buf;
+}
+#endif
+
+
+#ifndef NET_IP_ALIGN
+#define NET_IP_ALIGN 2
+#endif
+
+
+#if !defined(BCM_HAS_ETHTOOL_OP_SET_TX_IPV6_CSUM) && \
+    !defined(BCM_HAS_ETHTOOL_OP_SET_TX_HW_CSUM)   && \
+     defined(BCM_HAS_SET_TX_CSUM)
+static int tg3_set_tx_hw_csum(struct net_device *dev, u32 data)
+{
+       if (data)
+               dev->features |= NETIF_F_HW_CSUM;
+       else
+               dev->features &= ~NETIF_F_HW_CSUM;
+
+       return 0;
+}
+#endif
+
+
+#ifdef NETIF_F_TSO
+#ifndef NETIF_F_GSO
+#define gso_size tso_size
+#define gso_segs tso_segs
+#endif
+#ifndef NETIF_F_TSO6
+#define NETIF_F_TSO6   0
+#define BCM_NO_TSO6     1
+#endif
+#ifndef NETIF_F_TSO_ECN
+#define NETIF_F_TSO_ECN 0
+#endif
+
+#ifndef BCM_HAS_SKB_TRANSPORT_OFFSET
+static inline int skb_transport_offset(const struct sk_buff *skb)
+{
+       return (int) (skb->h.raw - skb->data);
+}
+#endif
+
+#ifndef BCM_HAS_IP_HDR
+static inline struct iphdr *ip_hdr(const struct sk_buff *skb)
+{
+       return skb->nh.iph;
+}
+#endif
+
+#ifndef BCM_HAS_IP_HDRLEN
+static inline unsigned int ip_hdrlen(const struct sk_buff *skb)
+{
+       return ip_hdr(skb)->ihl * 4;
+}
+#endif
+
+#ifndef BCM_HAS_TCP_HDR
+static inline struct tcphdr *tcp_hdr(const struct sk_buff *skb)
+{
+       return skb->h.th;
+}
+#endif
+
+#ifndef BCM_HAS_TCP_OPTLEN
+static inline unsigned int tcp_optlen(const struct sk_buff *skb)
+{
+       return (tcp_hdr(skb)->doff - 5) * 4;
+}
+#endif
+#endif
diff --git a/drivers/net/tg3_flags.h b/drivers/net/tg3_flags.h
new file mode 100644 (file)
index 0000000..349e0da
--- /dev/null
@@ -0,0 +1,14 @@
+#define BCM_HAS_BOOL
+#define BCM_HAS_LE32
+#define BCM_HAS_RESOURCE_SIZE_T
+#define BCM_HAS_KZALLOC
+#define BCM_HAS_USECS_TO_JIFFIES
+#define BCM_HAS_SKB_COPY_FROM_LINEAR_DATA
+#define BCM_HAS_PCIE_SET_READRQ
+#define BCM_HAS_ETHTOOL_OP_SET_TX_HW_CSUM
+#define BCM_HAS_SET_TX_CSUM
+#define BCM_HAS_SKB_TRANSPORT_OFFSET
+#define BCM_HAS_IP_HDR
+#define BCM_HAS_IP_HDRLEN
+#define BCM_HAS_TCP_HDR
+#define BCM_HAS_TCP_OPTLEN