]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/net/tg3.c
tg3: Don't access phy test ctrl reg for 5717+
[net-next-2.6.git] / drivers / net / tg3.c
index eea07484f757a7135614af1080701a9091ef8bed..5d155c50e6e3afa4e435ee6fac0de64e5c0f9a67 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/stringify.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/compiler.h>
 #include "tg3.h"
 
 #define DRV_MODULE_NAME                "tg3"
-#define DRV_MODULE_VERSION     "3.110"
-#define DRV_MODULE_RELDATE     "April 9, 2010"
+#define TG3_MAJ_NUM                    3
+#define TG3_MIN_NUM                    112
+#define DRV_MODULE_VERSION     \
+       __stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM)
+#define DRV_MODULE_RELDATE     "July 11, 2010"
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
@@ -5570,8 +5574,8 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb,
 
        entry = tnapi->tx_prod;
        base_flags = 0;
-       mss = 0;
-       if ((mss = skb_shinfo(skb)->gso_size) != 0) {
+       mss = skb_shinfo(skb)->gso_size;
+       if (mss) {
                int tcp_opt_len, ip_tcp_len;
                u32 hdrlen;
 
@@ -5777,9 +5781,10 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
        if (skb->ip_summed == CHECKSUM_PARTIAL)
                base_flags |= TXD_FLAG_TCPUDP_CSUM;
 
-       if ((mss = skb_shinfo(skb)->gso_size) != 0) {
+       mss = skb_shinfo(skb)->gso_size;
+       if (mss) {
                struct iphdr *iph;
-               u32 tcp_opt_len, ip_tcp_len, hdr_len;
+               u32 tcp_opt_len, hdr_len;
 
                if (skb_header_cloned(skb) &&
                    pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) {
@@ -5787,10 +5792,21 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
                        goto out_unlock;
                }
 
+               iph = ip_hdr(skb);
                tcp_opt_len = tcp_optlen(skb);
-               ip_tcp_len = ip_hdrlen(skb) + sizeof(struct tcphdr);
 
-               hdr_len = ip_tcp_len + tcp_opt_len;
+               if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) {
+                       hdr_len = skb_headlen(skb) - ETH_HLEN;
+               } else {
+                       u32 ip_tcp_len;
+
+                       ip_tcp_len = ip_hdrlen(skb) + sizeof(struct tcphdr);
+                       hdr_len = ip_tcp_len + tcp_opt_len;
+
+                       iph->check = 0;
+                       iph->tot_len = htons(mss + hdr_len);
+               }
+
                if (unlikely((ETH_HLEN + hdr_len) > 80) &&
                             (tp->tg3_flags2 & TG3_FLG2_TSO_BUG))
                        return tg3_tso_bug(tp, skb);
@@ -5798,9 +5814,6 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
                base_flags |= (TXD_FLAG_CPU_PRE_DMA |
                               TXD_FLAG_CPU_POST_DMA);
 
-               iph = ip_hdr(skb);
-               iph->check = 0;
-               iph->tot_len = htons(mss + hdr_len);
                if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) {
                        tcp_hdr(skb)->check = 0;
                        base_flags &= ~TXD_FLAG_TCPUDP_CSUM;
@@ -6621,7 +6634,7 @@ static void tg3_ape_driver_state_change(struct tg3 *tp, int kind)
                apedata = tg3_ape_read32(tp, TG3_APE_HOST_INIT_COUNT);
                tg3_ape_write32(tp, TG3_APE_HOST_INIT_COUNT, ++apedata);
                tg3_ape_write32(tp, TG3_APE_HOST_DRIVER_ID,
-                               APE_HOST_DRIVER_ID_MAGIC);
+                       APE_HOST_DRIVER_ID_MAGIC(TG3_MAJ_NUM, TG3_MIN_NUM));
                tg3_ape_write32(tp, TG3_APE_HOST_BEHAVIOR,
                                APE_HOST_BEHAV_NO_PHYLOCK);
 
@@ -6916,9 +6929,13 @@ static int tg3_chip_reset(struct tg3 *tp)
        val = GRC_MISC_CFG_CORECLK_RESET;
 
        if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) {
-               if (tr32(0x7e2c) == 0x60) {
-                       tw32(0x7e2c, 0x20);
-               }
+               /* Force PCIe 1.0a mode */
+               if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785 &&
+                   !(tp->tg3_flags3 & TG3_FLG3_5717_PLUS) &&
+                   tr32(TG3_PCIE_PHY_TSTCTL) ==
+                   (TG3_PCIE_PHY_TSTCTL_PCIE10 | TG3_PCIE_PHY_TSTCTL_PSCRAM))
+                       tw32(TG3_PCIE_PHY_TSTCTL, TG3_PCIE_PHY_TSTCTL_PSCRAM);
+
                if (tp->pci_chip_rev_id != CHIPREV_ID_5750_A0) {
                        tw32(GRC_MISC_CFG, (1 << 29));
                        val |= (1 << 29);
@@ -6989,8 +7006,7 @@ static int tg3_chip_reset(struct tg3 *tp)
                 * Older PCIe devices only support the 128 byte
                 * MPS setting.  Enforce the restriction.
                 */
-               if (!(tp->tg3_flags & TG3_FLAG_CPMU_PRESENT) ||
-                   (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784))
+               if (!(tp->tg3_flags & TG3_FLAG_CPMU_PRESENT))
                        val16 &= ~PCI_EXP_DEVCTL_PAYLOAD;
                pci_write_config_word(tp->pdev,
                                      tp->pcie_cap + PCI_EXP_DEVCTL,
@@ -7060,36 +7076,10 @@ static int tg3_chip_reset(struct tg3 *tp)
 
        tg3_mdio_start(tp);
 
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) {
-               u8 phy_addr;
-
-               phy_addr = tp->phy_addr;
-               tp->phy_addr = TG3_PHY_PCIE_ADDR;
-
-               tg3_writephy(tp, TG3_PCIEPHY_BLOCK_ADDR,
-                            TG3_PCIEPHY_TXB_BLK << TG3_PCIEPHY_BLOCK_SHIFT);
-               val = TG3_PCIEPHY_TX0CTRL1_TXOCM | TG3_PCIEPHY_TX0CTRL1_RDCTL |
-                     TG3_PCIEPHY_TX0CTRL1_TXCMV | TG3_PCIEPHY_TX0CTRL1_TKSEL |
-                     TG3_PCIEPHY_TX0CTRL1_NB_EN;
-               tg3_writephy(tp, TG3_PCIEPHY_TX0CTRL1, val);
-               udelay(10);
-
-               tg3_writephy(tp, TG3_PCIEPHY_BLOCK_ADDR,
-                            TG3_PCIEPHY_XGXS_BLK1 << TG3_PCIEPHY_BLOCK_SHIFT);
-               val = TG3_PCIEPHY_PWRMGMT4_LOWPWR_EN |
-                     TG3_PCIEPHY_PWRMGMT4_L1PLLPD_EN;
-               tg3_writephy(tp, TG3_PCIEPHY_PWRMGMT4, val);
-               udelay(10);
-
-               tp->phy_addr = phy_addr;
-       }
-
        if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) &&
            tp->pci_chip_rev_id != CHIPREV_ID_5750_A0 &&
            GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785 &&
-           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 &&
-           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5719 &&
-           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57765) {
+           !(tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) {
                val = tr32(0x7c00);
 
                tw32(0x7c00, val | (1 << 25));
@@ -7447,7 +7437,7 @@ static void __tg3_set_coalesce(struct tg3 *tp, struct ethtool_coalesce *ec)
                tw32(HOSTCC_TXCOAL_MAXF_INT, 0);
        }
 
-       if (!(tp->tg3_flags2 & TG3_FLG2_USING_MSIX)) {
+       if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS)) {
                tw32(HOSTCC_RXCOL_TICKS, ec->rx_coalesce_usecs);
                tw32(HOSTCC_RXMAX_FRAMES, ec->rx_max_coalesced_frames);
                tw32(HOSTCC_RXCOAL_MAXF_INT, ec->rx_max_coalesced_frames_irq);
@@ -7762,9 +7752,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        if (err)
                return err;
 
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) {
+       if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) {
                val = tr32(TG3PCI_DMA_RW_CTRL) &
                      ~DMA_RWCTRL_DIS_CACHE_ALIGNMENT;
                if (tp->pci_chip_rev_id == CHIPREV_ID_57765_A0)
@@ -7927,9 +7915,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                             BDINFO_FLAGS_DISABLED);
                }
 
-               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
-                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
-                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
+               if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)
                        val = (RX_STD_MAX_SIZE_5705 << BDINFO_FLAGS_MAXLEN_SHIFT) |
                              (TG3_RX_STD_DMA_SZ << 2);
                else
@@ -7946,9 +7932,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                          tp->rx_jumbo_pending : 0;
        tw32_rx_mbox(TG3_RX_JMB_PROD_IDX_REG, tpr->rx_jmb_prod_idx);
 
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) {
+       if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) {
                tw32(STD_REPLENISH_LWM, 32);
                tw32(JMB_REPLENISH_LWM, 16);
        }
@@ -8237,7 +8221,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                for (i = 0; i < TG3_RSS_INDIR_TBL_SIZE; i++) {
                        int idx = i % sizeof(val);
 
-                       ent[idx] = (i % (tp->irq_cnt - 1)) + 1;
+                       ent[idx] = i % (tp->irq_cnt - 1);
                        if (idx == sizeof(val) - 1) {
                                tw32(reg, val);
                                reg += 4;
@@ -8526,7 +8510,7 @@ static void tg3_timer(unsigned long __opaque)
                            (mac_stat & MAC_STATUS_LNKSTATE_CHANGED)) {
                                need_setup = 1;
                        }
-                       if (! netif_carrier_ok(tp->dev) &&
+                       if (!netif_carrier_ok(tp->dev) &&
                            (mac_stat & (MAC_STATUS_PCS_SYNCED |
                                         MAC_STATUS_SIGNAL_DET))) {
                                need_setup = 1;
@@ -8543,7 +8527,7 @@ static void tg3_timer(unsigned long __opaque)
                                tg3_setup_phy(tp, 0);
                        }
                } else if ((tp->tg3_flags2 & TG3_FLG2_MII_SERDES) &&
-                          !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
+                          (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
                        tg3_serdes_parallel_detect(tp);
                }
 
@@ -8638,9 +8622,7 @@ static int tg3_test_interrupt(struct tg3 *tp)
         * Turn off MSI one shot mode.  Otherwise this test has no
         * observable way to know whether the interrupt was delivered.
         */
-       if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
-            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
-            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) &&
+       if ((tp->tg3_flags3 & TG3_FLG3_5717_PLUS) &&
            (tp->tg3_flags2 & TG3_FLG2_USING_MSI)) {
                val = tr32(MSGINT_MODE) | MSGINT_MODE_ONE_SHOT_DISABLE;
                tw32(MSGINT_MODE, val);
@@ -8683,9 +8665,7 @@ static int tg3_test_interrupt(struct tg3 *tp)
 
        if (intr_ok) {
                /* Reenable MSI one shot mode. */
-               if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
-                    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
-                    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) &&
+               if ((tp->tg3_flags3 & TG3_FLG3_5717_PLUS) &&
                    (tp->tg3_flags2 & TG3_FLG2_USING_MSI)) {
                        val = tr32(MSGINT_MODE) & ~MSGINT_MODE_ONE_SHOT_DISABLE;
                        tw32(MSGINT_MODE, val);
@@ -8876,7 +8856,7 @@ static void tg3_ints_fini(struct tg3 *tp)
        else if (tp->tg3_flags2 & TG3_FLG2_USING_MSI)
                pci_disable_msi(tp->pdev);
        tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI_OR_MSIX;
-       tp->tg3_flags3 &= ~TG3_FLG3_ENABLE_RSS;
+       tp->tg3_flags3 &= ~(TG3_FLG3_ENABLE_RSS | TG3_FLG3_ENABLE_TSS);
 }
 
 static int tg3_open(struct net_device *dev)
@@ -8980,11 +8960,8 @@ static int tg3_open(struct net_device *dev)
                        goto err_out2;
                }
 
-               if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 &&
-                   GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5719 &&
-                   GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57765 &&
-                   (tp->tg3_flags2 & TG3_FLG2_USING_MSI) &&
-                   (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI)) {
+               if (!(tp->tg3_flags3 & TG3_FLG3_5717_PLUS) &&
+                   (tp->tg3_flags2 & TG3_FLG2_USING_MSI)) {
                        u32 val = tr32(PCIE_TRANSACTION_CFG);
 
                        tw32(PCIE_TRANSACTION_CFG,
@@ -9021,7 +8998,8 @@ err_out1:
        return err;
 }
 
-static struct net_device_stats *tg3_get_stats(struct net_device *);
+static struct rtnl_link_stats64 *tg3_get_stats64(struct net_device *,
+                                                struct rtnl_link_stats64 *);
 static struct tg3_ethtool_stats *tg3_get_estats(struct tg3 *);
 
 static int tg3_close(struct net_device *dev)
@@ -9055,8 +9033,8 @@ static int tg3_close(struct net_device *dev)
 
        tg3_ints_fini(tp);
 
-       memcpy(&tp->net_stats_prev, tg3_get_stats(tp->dev),
-              sizeof(tp->net_stats_prev));
+       tg3_get_stats64(tp->dev, &tp->net_stats_prev);
+
        memcpy(&tp->estats_prev, tg3_get_estats(tp),
               sizeof(tp->estats_prev));
 
@@ -9069,24 +9047,12 @@ static int tg3_close(struct net_device *dev)
        return 0;
 }
 
-static inline unsigned long get_stat64(tg3_stat64_t *val)
-{
-       unsigned long ret;
-
-#if (BITS_PER_LONG == 32)
-       ret = val->low;
-#else
-       ret = ((u64)val->high << 32) | ((u64)val->low);
-#endif
-       return ret;
-}
-
-static inline u64 get_estat64(tg3_stat64_t *val)
+static inline u64 get_stat64(tg3_stat64_t *val)
 {
        return ((u64)val->high << 32) | ((u64)val->low);
 }
 
-static unsigned long calc_crc_errors(struct tg3 *tp)
+static u64 calc_crc_errors(struct tg3 *tp)
 {
        struct tg3_hw_stats *hw_stats = tp->hw_stats;
 
@@ -9114,7 +9080,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)
 {
@@ -9204,11 +9170,11 @@ static struct tg3_ethtool_stats *tg3_get_estats(struct tg3 *tp)
        return estats;
 }
 
-static struct net_device_stats *tg3_get_stats(struct net_device *dev)
+static struct rtnl_link_stats64 *tg3_get_stats64(struct net_device *dev,
+                                                struct rtnl_link_stats64 *stats)
 {
        struct tg3 *tp = netdev_priv(dev);
-       struct net_device_stats *stats = &tp->net_stats;
-       struct net_device_stats *old_stats = &tp->net_stats_prev;
+       struct rtnl_link_stats64 *old_stats = &tp->net_stats_prev;
        struct tg3_hw_stats *hw_stats = tp->hw_stats;
 
        if (!hw_stats)
@@ -9395,7 +9361,7 @@ static void tg3_get_regs(struct net_device *dev,
        tg3_full_lock(tp, 0);
 
 #define __GET_REG32(reg)       (*(p)++ = tr32(reg))
-#define GET_REG32_LOOP(base,len)               \
+#define GET_REG32_LOOP(base, len)              \
 do {   p = (u32 *)(orig_p + (base));           \
        for (i = 0; i < len; i += 4)            \
                __GET_REG32((base) + i);        \
@@ -9488,7 +9454,7 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
                ret = tg3_nvram_read_be32(tp, offset-b_offset, &val);
                if (ret)
                        return ret;
-               memcpy(data, ((char*)&val) + b_offset, b_count);
+               memcpy(data, ((char *)&val) + b_offset, b_count);
                len -= b_count;
                offset += b_count;
                eeprom->len += b_count;
@@ -10608,8 +10574,8 @@ static int tg3_test_memory(struct tg3 *tp)
                mem_tbl = mem_tbl_570x;
 
        for (i = 0; mem_tbl[i].offset != 0xffffffff; i++) {
-               if ((err = tg3_do_mem_test(tp, mem_tbl[i].offset,
-                   mem_tbl[i].len)) != 0)
+               err = tg3_do_mem_test(tp, mem_tbl[i].offset, mem_tbl[i].len);
+               if (err)
                        break;
        }
 
@@ -10954,7 +10920,7 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
                if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
                        return -EAGAIN;
                phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
-               return phy_mii_ioctl(phydev, data, cmd);
+               return phy_mii_ioctl(phydev, ifr, cmd);
        }
 
        switch (cmd) {
@@ -12800,6 +12766,13 @@ done:
 
 static struct pci_dev * __devinit tg3_find_peer(struct tg3 *);
 
+static void inline vlan_features_add(struct net_device *dev, unsigned long flags)
+{
+#if TG3_VLAN_TAG_USED
+       dev->vlan_features |= flags;
+#endif
+}
+
 static int __devinit tg3_get_invariants(struct tg3 *tp)
 {
        static struct pci_device_id write_reorder_chipsets[] = {
@@ -13003,6 +12976,11 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
                tp->pdev_peer = tg3_find_peer(tp);
 
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
+               tp->tg3_flags3 |= TG3_FLG3_5717_PLUS;
+
        /* Intentionally exclude ASIC_REV_5906 */
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
@@ -13010,9 +12988,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
+           (tp->tg3_flags3 & TG3_FLG3_5717_PLUS))
                tp->tg3_flags3 |= TG3_FLG3_5755_PLUS;
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 ||
@@ -13032,17 +13008,17 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        if (tp->pci_chip_rev_id == CHIPREV_ID_5700_B0)
                tp->tg3_flags |= TG3_FLAG_BROKEN_CHECKSUMS;
        else {
+               unsigned long features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_GRO;
+
                tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS;
-               tp->dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
                if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
-                       tp->dev->features |= NETIF_F_IPV6_CSUM;
-               tp->dev->features |= NETIF_F_GRO;
+                       features |= NETIF_F_IPV6_CSUM;
+               tp->dev->features |= features;
+               vlan_features_add(tp->dev, features);
        }
 
        /* Determine TSO capabilities */
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
+       if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)
                tp->tg3_flags2 |= TG3_FLG2_HW_TSO_3;
        else if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) ||
                 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
@@ -13078,9 +13054,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                        tp->tg3_flags2 |= TG3_FLG2_1SHOT_MSI;
                }
 
-               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
-                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
-                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) {
+               if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) {
                        tp->tg3_flags |= TG3_FLAG_SUPPORT_MSIX;
                        tp->irq_max = TG3_IRQ_MAX_VECS;
                }
@@ -13095,9 +13069,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                tp->tg3_flags3 |= TG3_FLG3_40BIT_DMA_LIMIT_BUG;
        }
 
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
+       if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)
                tp->tg3_flags3 |= TG3_FLG3_USE_JUMBO_BDFLAG;
 
        if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
@@ -13298,9 +13270,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
+           (tp->tg3_flags3 & TG3_FLG3_5717_PLUS))
                tp->tg3_flags |= TG3_FLAG_CPMU_PRESENT;
 
        /* Set up tp->grc_local_ctrl before calling tg3_set_power_state().
@@ -13379,9 +13349,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
            !(tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) &&
            GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785 &&
            GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57780 &&
-           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 &&
-           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5719 &&
-           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57765) {
+           !(tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) {
                if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
                    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
                    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
@@ -13421,8 +13389,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                return err;
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 &&
-           (tp->pci_chip_rev_id != CHIPREV_ID_5717_A0 ||
-                (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)))
+           tp->pci_chip_rev_id != CHIPREV_ID_5717_A0)
                return -ENOTSUPP;
 
        /* Initialize data/descriptor byte/word swapping. */
@@ -13719,9 +13686,7 @@ static u32 __devinit tg3_calc_dma_bndry(struct tg3 *tp, u32 val)
 #endif
 #endif
 
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) {
+       if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) {
                val = goal ? 0 : DMA_RWCTRL_DIS_CACHE_ALIGNMENT;
                goto out;
        }
@@ -13932,9 +13897,7 @@ static int __devinit tg3_test_dma(struct tg3 *tp)
 
        tp->dma_rwctrl = tg3_calc_dma_bndry(tp, tp->dma_rwctrl);
 
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
+       if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)
                goto out;
 
        if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) {
@@ -14132,9 +14095,7 @@ static void __devinit tg3_init_link_config(struct tg3 *tp)
 
 static void __devinit tg3_init_bufmgr_config(struct tg3 *tp)
 {
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) {
+       if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) {
                tp->bufmgr_config.mbuf_read_dma_low_water =
                        DEFAULT_MB_RDMA_LOW_WATER_5705;
                tp->bufmgr_config.mbuf_mac_rx_low_water =
@@ -14317,7 +14278,7 @@ static const struct net_device_ops tg3_netdev_ops = {
        .ndo_open               = tg3_open,
        .ndo_stop               = tg3_close,
        .ndo_start_xmit         = tg3_start_xmit,
-       .ndo_get_stats          = tg3_get_stats,
+       .ndo_get_stats64        = tg3_get_stats64,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_multicast_list = tg3_set_rx_mode,
        .ndo_set_mac_address    = tg3_set_mac_addr,
@@ -14336,7 +14297,7 @@ static const struct net_device_ops tg3_netdev_ops_dma_bug = {
        .ndo_open               = tg3_open,
        .ndo_stop               = tg3_close,
        .ndo_start_xmit         = tg3_start_xmit_dma_bug,
-       .ndo_get_stats          = tg3_get_stats,
+       .ndo_get_stats64        = tg3_get_stats64,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_multicast_list = tg3_set_rx_mode,
        .ndo_set_mac_address    = tg3_set_mac_addr,
@@ -14525,20 +14486,25 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
         * is off by default, but can be enabled using ethtool.
         */
        if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO) &&
-           (dev->features & NETIF_F_IP_CSUM))
+           (dev->features & NETIF_F_IP_CSUM)) {
                dev->features |= NETIF_F_TSO;
-
+               vlan_features_add(dev, NETIF_F_TSO);
+       }
        if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) ||
            (tp->tg3_flags2 & TG3_FLG2_HW_TSO_3)) {
-               if (dev->features & NETIF_F_IPV6_CSUM)
+               if (dev->features & NETIF_F_IPV6_CSUM) {
                        dev->features |= NETIF_F_TSO6;
+                       vlan_features_add(dev, NETIF_F_TSO6);
+               }
                if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_3) ||
                    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
                    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
                     GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX) ||
                        GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
-                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
+                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) {
                        dev->features |= NETIF_F_TSO_ECN;
+                       vlan_features_add(dev, NETIF_F_TSO_ECN);
+               }
        }
 
        if (tp->pci_chip_rev_id == CHIPREV_ID_5705_A1 &&