ixgbe: Move interrupt related values out of ring and into q_vector
[pandora-kernel.git] / drivers / net / tg3.c
index 6f1f36c..8035765 100644 (file)
@@ -608,7 +608,7 @@ 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;
+       u32 regbase, bit;
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
                regbase = TG3_APE_LOCK_GRANT;
@@ -616,20 +616,34 @@ static void tg3_ape_lock_init(struct tg3 *tp)
                regbase = TG3_APE_PER_LOCK_GRANT;
 
        /* Make sure the driver hasn't any stale locks. */
-       for (i = 0; i < 8; i++)
+       for (i = 0; i < 8; i++) {
+               if (i == TG3_APE_LOCK_GPIO)
+                       continue;
                tg3_ape_write32(tp, regbase + 4 * i, APE_LOCK_GRANT_DRIVER);
+       }
+
+       /* Clear the correct bit of the GPIO lock too. */
+       if (!tp->pci_fn)
+               bit = APE_LOCK_GRANT_DRIVER;
+       else
+               bit = 1 << tp->pci_fn;
+
+       tg3_ape_write32(tp, regbase + 4 * TG3_APE_LOCK_GPIO, bit);
 }
 
 static int tg3_ape_lock(struct tg3 *tp, int locknum)
 {
        int i, off;
        int ret = 0;
-       u32 status, req, gnt;
+       u32 status, req, gnt, bit;
 
        if (!tg3_flag(tp, ENABLE_APE))
                return 0;
 
        switch (locknum) {
+       case TG3_APE_LOCK_GPIO:
+               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
+                       return 0;
        case TG3_APE_LOCK_GRC:
        case TG3_APE_LOCK_MEM:
                break;
@@ -647,21 +661,24 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum)
 
        off = 4 * locknum;
 
-       tg3_ape_write32(tp, req + off, APE_LOCK_REQ_DRIVER);
+       if (locknum != TG3_APE_LOCK_GPIO || !tp->pci_fn)
+               bit = APE_LOCK_REQ_DRIVER;
+       else
+               bit = 1 << tp->pci_fn;
+
+       tg3_ape_write32(tp, req + off, bit);
 
        /* Wait for up to 1 millisecond to acquire lock. */
        for (i = 0; i < 100; i++) {
                status = tg3_ape_read32(tp, gnt + off);
-               if (status == APE_LOCK_GRANT_DRIVER)
+               if (status == bit)
                        break;
                udelay(10);
        }
 
-       if (status != APE_LOCK_GRANT_DRIVER) {
+       if (status != bit) {
                /* Revoke the lock request. */
-               tg3_ape_write32(tp, gnt + off,
-                               APE_LOCK_GRANT_DRIVER);
-
+               tg3_ape_write32(tp, gnt + off, bit);
                ret = -EBUSY;
        }
 
@@ -670,12 +687,15 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum)
 
 static void tg3_ape_unlock(struct tg3 *tp, int locknum)
 {
-       u32 gnt;
+       u32 gnt, bit;
 
        if (!tg3_flag(tp, ENABLE_APE))
                return;
 
        switch (locknum) {
+       case TG3_APE_LOCK_GPIO:
+               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
+                       return;
        case TG3_APE_LOCK_GRC:
        case TG3_APE_LOCK_MEM:
                break;
@@ -688,7 +708,12 @@ static void tg3_ape_unlock(struct tg3 *tp, int locknum)
        else
                gnt = TG3_APE_PER_LOCK_GRANT;
 
-       tg3_ape_write32(tp, gnt + 4 * locknum, APE_LOCK_GRANT_DRIVER);
+       if (locknum != TG3_APE_LOCK_GPIO || !tp->pci_fn)
+               bit = APE_LOCK_GRANT_DRIVER;
+       else
+               bit = 1 << tp->pci_fn;
+
+       tg3_ape_write32(tp, gnt + 4 * locknum, bit);
 }
 
 static void tg3_disable_ints(struct tg3 *tp)
@@ -1833,6 +1858,12 @@ static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up)
        }
 
        if (!tp->setlpicnt) {
+               if (current_link_up == 1 &&
+                  !TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) {
+                       tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, 0x0000);
+                       TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
+               }
+
                val = tr32(TG3_CPMU_EEE_MODE);
                tw32(TG3_CPMU_EEE_MODE, val & ~TG3_CPMU_EEEMD_LPI_ENABLE);
        }
@@ -1847,7 +1878,9 @@ static void tg3_phy_eee_enable(struct tg3 *tp)
             GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
             GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) &&
            !TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) {
-               tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, 0x0003);
+               val = MII_TG3_DSP_TAP26_ALNOKO |
+                     MII_TG3_DSP_TAP26_RMRXSTO;
+               tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, val);
                TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
        }
 
@@ -2167,13 +2200,66 @@ out:
        return 0;
 }
 
+#define TG3_GPIO_MSG_DRVR_PRES          0x00000001
+#define TG3_GPIO_MSG_NEED_VAUX          0x00000002
+#define TG3_GPIO_MSG_MASK               (TG3_GPIO_MSG_DRVR_PRES | \
+                                         TG3_GPIO_MSG_NEED_VAUX)
+#define TG3_GPIO_MSG_ALL_DRVR_PRES_MASK \
+       ((TG3_GPIO_MSG_DRVR_PRES << 0) | \
+        (TG3_GPIO_MSG_DRVR_PRES << 4) | \
+        (TG3_GPIO_MSG_DRVR_PRES << 8) | \
+        (TG3_GPIO_MSG_DRVR_PRES << 12))
+
+#define TG3_GPIO_MSG_ALL_NEED_VAUX_MASK \
+       ((TG3_GPIO_MSG_NEED_VAUX << 0) | \
+        (TG3_GPIO_MSG_NEED_VAUX << 4) | \
+        (TG3_GPIO_MSG_NEED_VAUX << 8) | \
+        (TG3_GPIO_MSG_NEED_VAUX << 12))
+
+static inline u32 tg3_set_function_status(struct tg3 *tp, u32 newstat)
+{
+       u32 status, shift;
+
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
+               status = tg3_ape_read32(tp, TG3_APE_GPIO_MSG);
+       else
+               status = tr32(TG3_CPMU_DRV_STATUS);
+
+       shift = TG3_APE_GPIO_MSG_SHIFT + 4 * tp->pci_fn;
+       status &= ~(TG3_GPIO_MSG_MASK << shift);
+       status |= (newstat << shift);
+
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
+               tg3_ape_write32(tp, TG3_APE_GPIO_MSG, status);
+       else
+               tw32(TG3_CPMU_DRV_STATUS, status);
+
+       return status >> TG3_APE_GPIO_MSG_SHIFT;
+}
+
 static inline int tg3_pwrsrc_switch_to_vmain(struct tg3 *tp)
 {
        if (!tg3_flag(tp, IS_NIC))
                return 0;
 
-       tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl,
-                   TG3_GRC_LCLCTL_PWRSW_DELAY);
+       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_5720) {
+               if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO))
+                       return -EIO;
+
+               tg3_set_function_status(tp, TG3_GPIO_MSG_DRVR_PRES);
+
+               tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl,
+                           TG3_GRC_LCLCTL_PWRSW_DELAY);
+
+               tg3_ape_unlock(tp, TG3_APE_LOCK_GPIO);
+       } else {
+               tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl,
+                           TG3_GRC_LCLCTL_PWRSW_DELAY);
+       }
 
        return 0;
 }
@@ -2279,21 +2365,49 @@ static void tg3_pwrsrc_switch_to_vaux(struct tg3 *tp)
        }
 }
 
-static void tg3_frob_aux_power(struct tg3 *tp)
+static void tg3_frob_aux_power_5717(struct tg3 *tp, bool wol_enable)
+{
+       u32 msg = 0;
+
+       /* Serialize power state transitions */
+       if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO))
+               return;
+
+       if (tg3_flag(tp, ENABLE_ASF) || tg3_flag(tp, ENABLE_APE) || wol_enable)
+               msg = TG3_GPIO_MSG_NEED_VAUX;
+
+       msg = tg3_set_function_status(tp, msg);
+
+       if (msg & TG3_GPIO_MSG_ALL_DRVR_PRES_MASK)
+               goto done;
+
+       if (msg & TG3_GPIO_MSG_ALL_NEED_VAUX_MASK)
+               tg3_pwrsrc_switch_to_vaux(tp);
+       else
+               tg3_pwrsrc_die_with_vmain(tp);
+
+done:
+       tg3_ape_unlock(tp, TG3_APE_LOCK_GPIO);
+}
+
+static void tg3_frob_aux_power(struct tg3 *tp, bool include_wol)
 {
        bool need_vaux = false;
 
        /* The GPIOs do something completely different on 57765. */
        if (!tg3_flag(tp, IS_NIC) ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
                return;
 
-       if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
-            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 ||
-            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
-            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) &&
-           tp->pdev_peer != tp->pdev) {
+       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_5720) {
+               tg3_frob_aux_power_5717(tp, include_wol ?
+                                       tg3_flag(tp, WOL_ENABLE) != 0 : 0);
+               return;
+       }
+
+       if (tp->pdev_peer && tp->pdev_peer != tp->pdev) {
                struct net_device *dev_peer;
 
                dev_peer = pci_get_drvdata(tp->pdev_peer);
@@ -2305,13 +2419,14 @@ static void tg3_frob_aux_power(struct tg3 *tp)
                        if (tg3_flag(tp_peer, INIT_COMPLETE))
                                return;
 
-                       if (tg3_flag(tp_peer, WOL_ENABLE) ||
+                       if ((include_wol && tg3_flag(tp_peer, WOL_ENABLE)) ||
                            tg3_flag(tp_peer, ENABLE_ASF))
                                need_vaux = true;
                }
        }
 
-       if (tg3_flag(tp, WOL_ENABLE) || tg3_flag(tp, ENABLE_ASF))
+       if ((include_wol && tg3_flag(tp, WOL_ENABLE)) ||
+           tg3_flag(tp, ENABLE_ASF))
                need_vaux = true;
 
        if (need_vaux)
@@ -2894,7 +3009,7 @@ static int tg3_power_down_prepare(struct tg3 *tp)
        if (!(device_should_wake) && !tg3_flag(tp, ENABLE_ASF))
                tg3_power_down_phy(tp, do_low_power);
 
-       tg3_frob_aux_power(tp);
+       tg3_frob_aux_power(tp, true);
 
        /* Workaround for unstable PLL clock */
        if ((GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_AX) ||
@@ -3021,20 +3136,6 @@ static int tg3_phy_autoneg_cfg(struct tg3 *tp, u32 advertise, u32 flowctrl)
        if (!err) {
                u32 err2;
 
-               switch (GET_ASIC_REV(tp->pci_chip_rev_id)) {
-               case ASIC_REV_5717:
-               case ASIC_REV_57765:
-                       if (!tg3_phydsp_read(tp, MII_TG3_DSP_CH34TP2, &val))
-                               tg3_phydsp_write(tp, MII_TG3_DSP_CH34TP2, val |
-                                                MII_TG3_DSP_CH34TP2_HIBW01);
-                       /* Fall through */
-               case ASIC_REV_5719:
-                       val = MII_TG3_DSP_TAP26_ALNOKO |
-                             MII_TG3_DSP_TAP26_RMRXSTO |
-                             MII_TG3_DSP_TAP26_OPCSINPT;
-                       tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, val);
-               }
-
                val = 0;
                /* Advertise 100-BaseTX EEE ability */
                if (advertise & ADVERTISED_100baseT_Full)
@@ -3043,6 +3144,25 @@ static int tg3_phy_autoneg_cfg(struct tg3 *tp, u32 advertise, u32 flowctrl)
                if (advertise & ADVERTISED_1000baseT_Full)
                        val |= MDIO_AN_EEE_ADV_1000T;
                err = tg3_phy_cl45_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val);
+               if (err)
+                       val = 0;
+
+               switch (GET_ASIC_REV(tp->pci_chip_rev_id)) {
+               case ASIC_REV_5717:
+               case ASIC_REV_57765:
+               case ASIC_REV_5719:
+                       /* If we advertised any eee advertisements above... */
+                       if (val)
+                               val = MII_TG3_DSP_TAP26_ALNOKO |
+                                     MII_TG3_DSP_TAP26_RMRXSTO |
+                                     MII_TG3_DSP_TAP26_OPCSINPT;
+                       tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, val);
+                       /* Fall through */
+               case ASIC_REV_5720:
+                       if (!tg3_phydsp_read(tp, MII_TG3_DSP_CH34TP2, &val))
+                               tg3_phydsp_write(tp, MII_TG3_DSP_CH34TP2, val |
+                                                MII_TG3_DSP_CH34TP2_HIBW01);
+               }
 
                err2 = TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
                if (!err)
@@ -7305,16 +7425,11 @@ static int tg3_chip_reset(struct tg3 *tp)
                tw32(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl);
        }
 
-       if (tg3_flag(tp, ENABLE_APE))
-               tp->mac_mode = MAC_MODE_APE_TX_EN |
-                              MAC_MODE_APE_RX_EN |
-                              MAC_MODE_TDE_ENABLE;
-
        if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) {
-               tp->mac_mode |= MAC_MODE_PORT_MODE_TBI;
+               tp->mac_mode = MAC_MODE_PORT_MODE_TBI;
                val = tp->mac_mode;
        } else if (tp->phy_flags & TG3_PHYFLG_MII_SERDES) {
-               tp->mac_mode |= MAC_MODE_PORT_MODE_GMII;
+               tp->mac_mode = MAC_MODE_PORT_MODE_GMII;
                val = tp->mac_mode;
        } else
                val = 0;
@@ -8452,12 +8567,11 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                udelay(10);
        }
 
-       if (tg3_flag(tp, ENABLE_APE))
-               tp->mac_mode = MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN;
-       else
-               tp->mac_mode = 0;
        tp->mac_mode |= MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE |
-               MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | MAC_MODE_FHDE_ENABLE;
+                       MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE |
+                       MAC_MODE_FHDE_ENABLE;
+       if (tg3_flag(tp, ENABLE_APE))
+               tp->mac_mode |= MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN;
        if (!tg3_flag(tp, 5705_PLUS) &&
            !(tp->phy_flags & TG3_PHYFLG_PHY_SERDES) &&
            GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700)
@@ -8609,15 +8723,24 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        udelay(100);
 
        if (tg3_flag(tp, ENABLE_RSS)) {
+               int i = 0;
                u32 reg = MAC_RSS_INDIR_TBL_0;
-               u8 *ent = (u8 *)&val;
 
-               /* Setup the indirection table */
-               for (i = 0; i < TG3_RSS_INDIR_TBL_SIZE; i++) {
-                       int idx = i % sizeof(val);
+               if (tp->irq_cnt == 2) {
+                       for (i = 0; i < TG3_RSS_INDIR_TBL_SIZE; i += 8) {
+                               tw32(reg, 0x0);
+                               reg += 4;
+                       }
+               } else {
+                       u32 val;
 
-                       ent[idx] = i % (tp->irq_cnt - 1);
-                       if (idx == sizeof(val) - 1) {
+                       while (i < TG3_RSS_INDIR_TBL_SIZE) {
+                               val = i % (tp->irq_cnt - 1);
+                               i++;
+                               for (; i % 8; i++) {
+                                       val <<= 4;
+                                       val |= (i % (tp->irq_cnt - 1));
+                               }
                                tw32(reg, val);
                                reg += 4;
                        }
@@ -9060,7 +9183,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 (tg3_flag(tp, 57765_PLUS) && tg3_flag(tp, USING_MSI)) {
+       if (tg3_flag(tp, 57765_PLUS)) {
                val = tr32(MSGINT_MODE) | MSGINT_MODE_ONE_SHOT_DISABLE;
                tw32(MSGINT_MODE, val);
        }
@@ -9088,6 +9211,10 @@ static int tg3_test_interrupt(struct tg3 *tp)
                        break;
                }
 
+               if (tg3_flag(tp, 57765_PLUS) &&
+                   tnapi->hw_status->status_tag != tnapi->last_tag)
+                       tw32_mailbox_f(tnapi->int_mbox, tnapi->last_tag << 24);
+
                msleep(10);
        }
 
@@ -9102,7 +9229,7 @@ static int tg3_test_interrupt(struct tg3 *tp)
 
        if (intr_ok) {
                /* Reenable MSI one shot mode. */
-               if (tg3_flag(tp, 57765_PLUS) && tg3_flag(tp, USING_MSI)) {
+               if (tg3_flag(tp, 57765_PLUS)) {
                        val = tr32(MSGINT_MODE) & ~MSGINT_MODE_ONE_SHOT_DISABLE;
                        tw32(MSGINT_MODE, val);
                }
@@ -9450,6 +9577,8 @@ err_out2:
 
 err_out1:
        tg3_ints_fini(tp);
+       tg3_frob_aux_power(tp, false);
+       pci_set_power_state(tp->pdev, PCI_D3hot);
        return err;
 }
 
@@ -10444,7 +10573,7 @@ static void tg3_get_ethtool_stats(struct net_device *dev,
        memcpy(tmp_stats, tg3_get_estats(tp), sizeof(tp->estats));
 }
 
-static __be32 * tg3_vpd_readblock(struct tg3 *tp)
+static __be32 *tg3_vpd_readblock(struct tg3 *tp, u32 *vpdlen)
 {
        int i;
        __be32 *buf;
@@ -10511,6 +10640,8 @@ static __be32 * tg3_vpd_readblock(struct tg3 *tp)
                        goto error;
        }
 
+       *vpdlen = len;
+
        return buf;
 
 error:
@@ -10524,13 +10655,13 @@ error:
 #define NVRAM_SELFBOOT_FORMAT1_3_SIZE  0x1c
 #define NVRAM_SELFBOOT_FORMAT1_4_SIZE  0x20
 #define NVRAM_SELFBOOT_FORMAT1_5_SIZE  0x24
-#define NVRAM_SELFBOOT_FORMAT1_6_SIZE  0x4c
+#define NVRAM_SELFBOOT_FORMAT1_6_SIZE  0x50
 #define NVRAM_SELFBOOT_HW_SIZE 0x20
 #define NVRAM_SELFBOOT_DATA_SIZE 0x1c
 
 static int tg3_test_nvram(struct tg3 *tp)
 {
-       u32 csum, magic;
+       u32 csum, magic, len;
        __be32 *buf;
        int i, j, k, err = 0, size;
 
@@ -10671,18 +10802,17 @@ static int tg3_test_nvram(struct tg3 *tp)
 
        kfree(buf);
 
-       buf = tg3_vpd_readblock(tp);
+       buf = tg3_vpd_readblock(tp, &len);
        if (!buf)
                return -ENOMEM;
 
-       i = pci_vpd_find_tag((u8 *)buf, 0, TG3_NVM_VPD_LEN,
-                            PCI_VPD_LRDT_RO_DATA);
+       i = pci_vpd_find_tag((u8 *)buf, 0, len, PCI_VPD_LRDT_RO_DATA);
        if (i > 0) {
                j = pci_vpd_lrdt_size(&((u8 *)buf)[i]);
                if (j < 0)
                        goto out;
 
-               if (i + PCI_VPD_LRDT_TAG_SIZE + j > TG3_NVM_VPD_LEN)
+               if (i + PCI_VPD_LRDT_TAG_SIZE + j > len)
                        goto out;
 
                i += PCI_VPD_LRDT_TAG_SIZE;
@@ -13026,7 +13156,9 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
        }
 
        if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES) &&
-           ((tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 &&
+           (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
+            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 ||
+            (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 &&
              tp->pci_chip_rev_id != CHIPREV_ID_5717_A0) ||
             (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 &&
              tp->pci_chip_rev_id != CHIPREV_ID_57765_A0)))
@@ -13078,14 +13210,14 @@ static void __devinit tg3_read_vpd(struct tg3 *tp)
 {
        u8 *vpd_data;
        unsigned int block_end, rosize, len;
+       u32 vpdlen;
        int j, i = 0;
 
-       vpd_data = (u8 *)tg3_vpd_readblock(tp);
+       vpd_data = (u8 *)tg3_vpd_readblock(tp, &vpdlen);
        if (!vpd_data)
                goto out_no_vpd;
 
-       i = pci_vpd_find_tag(vpd_data, 0, TG3_NVM_VPD_LEN,
-                            PCI_VPD_LRDT_RO_DATA);
+       i = pci_vpd_find_tag(vpd_data, 0, vpdlen, PCI_VPD_LRDT_RO_DATA);
        if (i < 0)
                goto out_not_found;
 
@@ -13093,7 +13225,7 @@ static void __devinit tg3_read_vpd(struct tg3 *tp)
        block_end = i + PCI_VPD_LRDT_TAG_SIZE + rosize;
        i += PCI_VPD_LRDT_TAG_SIZE;
 
-       if (block_end > TG3_NVM_VPD_LEN)
+       if (block_end > vpdlen)
                goto out_not_found;
 
        j = pci_vpd_find_info_keyword(vpd_data, i, rosize,
@@ -13118,7 +13250,7 @@ static void __devinit tg3_read_vpd(struct tg3 *tp)
                        goto partno;
 
                memcpy(tp->fw_ver, &vpd_data[j], len);
-               strncat(tp->fw_ver, " bc ", TG3_NVM_VPD_LEN - len - 1);
+               strncat(tp->fw_ver, " bc ", vpdlen - len - 1);
        }
 
 partno:
@@ -13131,7 +13263,7 @@ partno:
 
        i += PCI_VPD_INFO_FLD_HDR_SIZE;
        if (len > TG3_BPN_SIZE ||
-           (len + i) > TG3_NVM_VPD_LEN)
+           (len + i) > vpdlen)
                goto out_not_found;
 
        memcpy(tp->board_part_number, &vpd_data[i], len);
@@ -13651,9 +13783,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        }
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714)
                tp->pdev_peer = tg3_find_peer(tp);
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
@@ -15296,6 +15426,11 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
 
        pci_set_drvdata(pdev, dev);
 
+       if (tg3_flag(tp, 5717_PLUS)) {
+               /* Resume a low-power mode */
+               tg3_frob_aux_power(tp, false);
+       }
+
        err = register_netdev(dev);
        if (err) {
                dev_err(&pdev->dev, "Cannot register net device, aborting\n");