]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/net/tg3.c
tg3: Revert RSS indir tbl setup change
[net-next-2.6.git] / drivers / net / tg3.c
index 573054ae7b58687dbe52eee0be849f0436159e1c..89aa486217876740ae4c934e61f54d041185af64 100644 (file)
@@ -67,8 +67,8 @@
 #include "tg3.h"
 
 #define DRV_MODULE_NAME                "tg3"
-#define DRV_MODULE_VERSION     "3.110"
-#define DRV_MODULE_RELDATE     "April 9, 2010"
+#define DRV_MODULE_VERSION     "3.111"
+#define DRV_MODULE_RELDATE     "June 5, 2010"
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
 #define TG3_RX_JMB_BUFF_RING_SIZE \
        (sizeof(struct ring_info) * TG3_RX_JUMBO_RING_SIZE)
 
-#define TG3_RSS_MIN_NUM_MSIX_VECS      2
-
 /* Due to a hardware bug, the 5701 can only DMA to memory addresses
  * that are at least dword aligned when used in PCIX mode.  The driver
  * works around this bug by double copying the packet.  This workaround
@@ -272,6 +270,7 @@ static DEFINE_PCI_DEVICE_TABLE(tg3_pci_tbl) = {
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57765)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57791)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57795)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5719)},
        {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)},
@@ -585,18 +584,23 @@ static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val)
 static void tg3_ape_lock_init(struct tg3 *tp)
 {
        int i;
+       u32 regbase;
+
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
+               regbase = TG3_APE_LOCK_GRANT;
+       else
+               regbase = TG3_APE_PER_LOCK_GRANT;
 
        /* Make sure the driver hasn't any stale locks. */
        for (i = 0; i < 8; i++)
-               tg3_ape_write32(tp, TG3_APE_LOCK_GRANT + 4 * i,
-                               APE_LOCK_GRANT_DRIVER);
+               tg3_ape_write32(tp, regbase + 4 * i, APE_LOCK_GRANT_DRIVER);
 }
 
 static int tg3_ape_lock(struct tg3 *tp, int locknum)
 {
        int i, off;
        int ret = 0;
-       u32 status;
+       u32 status, req, gnt;
 
        if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE))
                return 0;
@@ -609,13 +613,21 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum)
                return -EINVAL;
        }
 
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) {
+               req = TG3_APE_LOCK_REQ;
+               gnt = TG3_APE_LOCK_GRANT;
+       } else {
+               req = TG3_APE_PER_LOCK_REQ;
+               gnt = TG3_APE_PER_LOCK_GRANT;
+       }
+
        off = 4 * locknum;
 
-       tg3_ape_write32(tp, TG3_APE_LOCK_REQ + off, APE_LOCK_REQ_DRIVER);
+       tg3_ape_write32(tp, req + off, APE_LOCK_REQ_DRIVER);
 
        /* Wait for up to 1 millisecond to acquire lock. */
        for (i = 0; i < 100; i++) {
-               status = tg3_ape_read32(tp, TG3_APE_LOCK_GRANT + off);
+               status = tg3_ape_read32(tp, gnt + off);
                if (status == APE_LOCK_GRANT_DRIVER)
                        break;
                udelay(10);
@@ -623,7 +635,7 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum)
 
        if (status != APE_LOCK_GRANT_DRIVER) {
                /* Revoke the lock request. */
-               tg3_ape_write32(tp, TG3_APE_LOCK_GRANT + off,
+               tg3_ape_write32(tp, gnt + off,
                                APE_LOCK_GRANT_DRIVER);
 
                ret = -EBUSY;
@@ -634,7 +646,7 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum)
 
 static void tg3_ape_unlock(struct tg3 *tp, int locknum)
 {
-       int off;
+       u32 gnt;
 
        if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE))
                return;
@@ -647,8 +659,12 @@ static void tg3_ape_unlock(struct tg3 *tp, int locknum)
                return;
        }
 
-       off = 4 * locknum;
-       tg3_ape_write32(tp, TG3_APE_LOCK_GRANT + off, APE_LOCK_GRANT_DRIVER);
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
+               gnt = TG3_APE_LOCK_GRANT;
+       else
+               gnt = TG3_APE_PER_LOCK_GRANT;
+
+       tg3_ape_write32(tp, gnt + 4 * locknum, APE_LOCK_GRANT_DRIVER);
 }
 
 static void tg3_disable_ints(struct tg3 *tp)
@@ -1069,14 +1085,11 @@ static int tg3_mdio_init(struct tg3 *tp)
        u32 reg;
        struct phy_device *phydev;
 
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) {
-               u32 funcnum, is_serdes;
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) {
+               u32 is_serdes;
 
-               funcnum = tr32(TG3_CPMU_STATUS) & TG3_CPMU_STATUS_PCIE_FUNC;
-               if (funcnum)
-                       tp->phy_addr = 2;
-               else
-                       tp->phy_addr = 1;
+               tp->phy_addr = PCI_FUNC(tp->pdev->devfn) + 1;
 
                if (tp->pci_chip_rev_id != CHIPREV_ID_5717_A0)
                        is_serdes = tr32(SG_DIG_STATUS) & SG_DIG_IS_SERDES;
@@ -1589,7 +1602,8 @@ static void tg3_phy_toggle_apd(struct tg3 *tp, bool enable)
        u32 reg;
 
        if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
-               (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 &&
+           ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+             GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) &&
             (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)))
                return;
 
@@ -1964,7 +1978,8 @@ static int tg3_phy_reset(struct tg3 *tp)
                }
        }
 
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 &&
+       if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) &&
            (tp->tg3_flags2 & TG3_FLG2_MII_SERDES))
                return 0;
 
@@ -2049,6 +2064,7 @@ static void tg3_frob_aux_power(struct tg3 *tp)
 
        /* The GPIOs do something completely different on 57765. */
        if ((tp->tg3_flags2 & TG3_FLG2_IS_NIC) == 0 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
                return;
 
@@ -4191,6 +4207,8 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset)
                                        current_duplex = DUPLEX_FULL;
                                else
                                        current_duplex = DUPLEX_HALF;
+                       } else if (!(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
+                               /* Link is up via parallel detect */
                        } else {
                                current_link_up = 0;
                        }
@@ -6212,6 +6230,8 @@ static void tg3_free_rings(struct tg3 *tp)
        for (j = 0; j < tp->irq_cnt; j++) {
                struct tg3_napi *tnapi = &tp->napi[j];
 
+               tg3_rx_prodring_free(tp, &tp->prodring[j]);
+
                if (!tnapi->tx_buffers)
                        continue;
 
@@ -6247,8 +6267,6 @@ static void tg3_free_rings(struct tg3 *tp)
 
                        dev_kfree_skb_any(skb);
                }
-
-               tg3_rx_prodring_free(tp, &tp->prodring[j]);
        }
 }
 
@@ -6782,7 +6800,8 @@ static void tg3_restore_pci_state(struct tg3 *tp)
        /* Allow reads and writes to the APE register and memory space. */
        if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
                val |= PCISTATE_ALLOW_APE_CTLSPC_WR |
-                      PCISTATE_ALLOW_APE_SHMEM_WR;
+                      PCISTATE_ALLOW_APE_SHMEM_WR |
+                      PCISTATE_ALLOW_APE_PSPACE_WR;
        pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE, val);
 
        pci_write_config_word(tp->pdev, PCI_COMMAND, tp->pci_cmd);
@@ -7069,6 +7088,7 @@ static int tg3_chip_reset(struct tg3 *tp)
            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) {
                val = tr32(0x7c00);
 
@@ -7504,7 +7524,8 @@ static void tg3_rings_reset(struct tg3 *tp)
 
 
        /* Disable all receive return rings but the first. */
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
                limit = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE * 17;
        else if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
                limit = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE * 16;
@@ -7720,7 +7741,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                 */
                val = tr32(TG3PCI_PCISTATE);
                val |= PCISTATE_ALLOW_APE_CTLSPC_WR |
-                      PCISTATE_ALLOW_APE_SHMEM_WR;
+                      PCISTATE_ALLOW_APE_SHMEM_WR |
+                      PCISTATE_ALLOW_APE_PSPACE_WR;
                tw32(TG3PCI_PCISTATE, val);
        }
 
@@ -7741,6 +7763,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_5717 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) {
                val = tr32(TG3PCI_DMA_RW_CTRL) &
                      ~DMA_RWCTRL_DIS_CACHE_ALIGNMENT;
@@ -7869,7 +7892,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
             ((u64) tpr->rx_std_mapping >> 32));
        tw32(RCVDBDI_STD_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW,
             ((u64) tpr->rx_std_mapping & 0xffffffff));
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717)
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 &&
+           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5719)
                tw32(RCVDBDI_STD_BD + TG3_BDINFO_NIC_ADDR,
                     NIC_SRAM_RX_BUFFER_DESC);
 
@@ -7894,7 +7918,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                        tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS,
                             (RX_JUMBO_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT) |
                             BDINFO_FLAGS_USE_EXT_RECV);
-                       if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717)
+                       if (!(tp->tg3_flags3 & TG3_FLG3_USE_JUMBO_BDFLAG) ||
+                           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
                                tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_NIC_ADDR,
                                     NIC_SRAM_RX_JUMBO_BUFFER_DESC);
                } else {
@@ -7903,6 +7928,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                }
 
                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)
                        val = (RX_STD_MAX_SIZE_5705 << BDINFO_FLAGS_MAXLEN_SHIFT) |
                              (TG3_RX_STD_DMA_SZ << 2);
@@ -7921,6 +7947,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        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) {
                tw32(STD_REPLENISH_LWM, 32);
                tw32(JMB_REPLENISH_LWM, 16);
@@ -7956,7 +7983,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                      RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB |
                      RDMAC_MODE_LNGREAD_ENAB);
 
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
                rdmac_mode |= RDMAC_MODE_MULT_DMA_RD_DIS;
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
@@ -8195,6 +8223,9 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        }
 
        tp->tx_mode = TX_MODE_ENABLE;
+       if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+               tp->tx_mode |= TX_MODE_MBUF_LOCKUP_FIX;
        tw32_f(MAC_TX_MODE, tp->tx_mode);
        udelay(100);
 
@@ -8511,8 +8542,10 @@ static void tg3_timer(unsigned long __opaque)
                                }
                                tg3_setup_phy(tp, 0);
                        }
-               } else if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)
+               } else if ((tp->tg3_flags2 & TG3_FLG2_MII_SERDES) &&
+                          !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
                        tg3_serdes_parallel_detect(tp);
+               }
 
                tp->timer_counter = tp->timer_multiplier;
        }
@@ -8606,6 +8639,7 @@ static int tg3_test_interrupt(struct tg3 *tp)
         * 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) &&
            (tp->tg3_flags2 & TG3_FLG2_USING_MSI)) {
                val = tr32(MSGINT_MODE) | MSGINT_MODE_ONE_SHOT_DISABLE;
@@ -8650,6 +8684,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) &&
                    (tp->tg3_flags2 & TG3_FLG2_USING_MSI)) {
                        val = tr32(MSGINT_MODE) & ~MSGINT_MODE_ONE_SHOT_DISABLE;
@@ -8775,9 +8810,9 @@ static bool tg3_enable_msix(struct tg3 *tp)
        }
 
        rc = pci_enable_msix(tp->pdev, msix_ent, tp->irq_cnt);
-       if (rc != 0) {
-               if (rc < TG3_RSS_MIN_NUM_MSIX_VECS)
-                       return false;
+       if (rc < 0) {
+               return false;
+       } else if (rc != 0) {
                if (pci_enable_msix(tp->pdev, msix_ent, rc))
                        return false;
                netdev_notice(tp->dev, "Requested %d MSI-X vectors, received %d\n",
@@ -8785,16 +8820,19 @@ static bool tg3_enable_msix(struct tg3 *tp)
                tp->irq_cnt = rc;
        }
 
-       tp->tg3_flags3 |= TG3_FLG3_ENABLE_RSS;
-
        for (i = 0; i < tp->irq_max; i++)
                tp->napi[i].irq_vec = msix_ent[i].vector;
 
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) {
-               tp->tg3_flags3 |= TG3_FLG3_ENABLE_TSS;
-               tp->dev->real_num_tx_queues = tp->irq_cnt - 1;
-       } else
-               tp->dev->real_num_tx_queues = 1;
+       tp->dev->real_num_tx_queues = 1;
+       if (tp->irq_cnt > 1) {
+               tp->tg3_flags3 |= TG3_FLG3_ENABLE_RSS;
+
+               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) {
+                       tp->tg3_flags3 |= TG3_FLG3_ENABLE_TSS;
+                       tp->dev->real_num_tx_queues = tp->irq_cnt - 1;
+               }
+       }
 
        return true;
 }
@@ -8943,6 +8981,7 @@ static int tg3_open(struct net_device *dev)
                }
 
                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)) {
@@ -8982,7 +9021,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)
@@ -9016,8 +9056,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));
 
@@ -9030,24 +9070,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;
 
@@ -9075,7 +9103,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)
 {
@@ -9165,11 +9193,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)
@@ -10554,7 +10582,8 @@ static int tg3_test_memory(struct tg3 *tp)
        int err = 0;
        int i;
 
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
                mem_tbl = mem_tbl_5717;
        else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
                mem_tbl = mem_tbl_57765;
@@ -11634,7 +11663,8 @@ static void __devinit tg3_nvram_init(struct tg3 *tp)
                else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
                         GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
                        tg3_get_57780_nvram_info(tp);
-               else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
+               else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+                        GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
                        tg3_get_5717_nvram_info(tp);
                else
                        tg3_get_nvram_info(tp);
@@ -12070,11 +12100,10 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
 
                tp->phy_id = eeprom_phy_id;
                if (eeprom_phy_serdes) {
-                       if ((tp->tg3_flags2 & TG3_FLG2_5780_CLASS) ||
-                           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
-                               tp->tg3_flags2 |= TG3_FLG2_MII_SERDES;
-                       else
+                       if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
                                tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES;
+                       else
+                               tp->tg3_flags2 |= TG3_FLG2_MII_SERDES;
                }
 
                if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS)
@@ -12760,6 +12789,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[] = {
@@ -12804,7 +12840,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 
                if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717 ||
                    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 ||
-                   tp->pdev->device == TG3PCI_DEVICE_TIGON3_5724)
+                   tp->pdev->device == TG3PCI_DEVICE_TIGON3_5724 ||
+                   tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719)
                        pci_read_config_dword(tp->pdev,
                                              TG3PCI_GEN2_PRODID_ASICREV,
                                              &prod_id_asic_rev);
@@ -12970,6 +13007,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
            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_5755_PLUS;
 
@@ -12990,15 +13028,18 @@ 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)
                tp->tg3_flags2 |= TG3_FLG2_HW_TSO_3;
        else if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) ||
@@ -13036,6 +13077,7 @@ static int __devinit tg3_get_invariants(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) {
                        tp->tg3_flags |= TG3_FLAG_SUPPORT_MSIX;
                        tp->irq_max = TG3_IRQ_MAX_VECS;
@@ -13043,6 +13085,7 @@ static int __devinit tg3_get_invariants(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_5906)
                tp->tg3_flags3 |= TG3_FLG3_SHORT_DMA_BUG;
        else if (!(tp->tg3_flags3 & TG3_FLG3_5755_PLUS)) {
@@ -13051,6 +13094,7 @@ static int __devinit tg3_get_invariants(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)
                tp->tg3_flags3 |= TG3_FLG3_USE_JUMBO_BDFLAG;
 
@@ -13242,7 +13286,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                 * APE register and memory space.
                 */
                pci_state_reg |= PCISTATE_ALLOW_APE_CTLSPC_WR |
-                                PCISTATE_ALLOW_APE_SHMEM_WR;
+                                PCISTATE_ALLOW_APE_SHMEM_WR |
+                                PCISTATE_ALLOW_APE_PSPACE_WR;
                pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE,
                                       pci_state_reg);
        }
@@ -13252,6 +13297,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
            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_flags |= TG3_FLAG_CPMU_PRESENT;
 
@@ -13332,6 +13378,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
            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) {
                if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
                    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
@@ -13580,9 +13627,12 @@ static int __devinit tg3_get_device_address(struct tg3 *tp)
                        tw32_f(NVRAM_CMD, NVRAM_CMD_RESET);
                else
                        tg3_nvram_unlock(tp);
-       } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) {
-               if (tr32(TG3_CPMU_STATUS) & TG3_CPMU_STATUS_PCIE_FUNC)
+       } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+                  GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) {
+               if (PCI_FUNC(tp->pdev->devfn) & 1)
                        mac_offset = 0xcc;
+               if (PCI_FUNC(tp->pdev->devfn) > 1)
+                       mac_offset += 0x18c;
        } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
                mac_offset = 0x10;
 
@@ -13668,6 +13718,7 @@ static u32 __devinit tg3_calc_dma_bndry(struct tg3 *tp, u32 val)
 #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) {
                val = goal ? 0 : DMA_RWCTRL_DIS_CACHE_ALIGNMENT;
                goto out;
@@ -13880,6 +13931,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)
                goto out;
 
@@ -14079,6 +14131,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) {
                tp->bufmgr_config.mbuf_read_dma_low_water =
                        DEFAULT_MB_RDMA_LOW_WATER_5705;
@@ -14156,6 +14209,7 @@ static char * __devinit tg3_phy_string(struct tg3 *tp)
        case TG3_PHY_ID_BCM5718C:       return "5718C";
        case TG3_PHY_ID_BCM5718S:       return "5718S";
        case TG3_PHY_ID_BCM57765:       return "57765";
+       case TG3_PHY_ID_BCM5719C:       return "5719C";
        case TG3_PHY_ID_BCM8002:        return "8002/serdes";
        case 0:                 return "serdes";
        default:                return "unknown";
@@ -14261,7 +14315,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,
@@ -14280,7 +14334,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,
@@ -14404,7 +14458,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
        }
 
        if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) &&
-           tp->pci_chip_rev_id != CHIPREV_ID_5717_A0)
+           tp->pci_chip_rev_id != CHIPREV_ID_5717_A0 &&
+           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5719)
                dev->netdev_ops = &tg3_netdev_ops;
        else
                dev->netdev_ops = &tg3_netdev_ops_dma_bug;
@@ -14468,20 +14523,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 &&