]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/net/tg3.c
tg3: Break out mini producer ring handling
[net-next-2.6.git] / drivers / net / tg3.c
index 201be425643a6fb7acb8801bbbb718897c9a6431..606703cf96184b7f10446fb9cacfa5ff5ee61179 100644 (file)
@@ -68,8 +68,8 @@
 
 #define DRV_MODULE_NAME                "tg3"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "3.98"
-#define DRV_MODULE_RELDATE     "February 25, 2009"
+#define DRV_MODULE_VERSION     "3.100"
+#define DRV_MODULE_RELDATE     "August 25, 2009"
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
@@ -219,11 +219,12 @@ static struct pci_device_id tg3_pci_tbl[] = {
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5761E)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5761S)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5761SE)},
-       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5785)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5785_G)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5785_F)},
        {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, TG3PCI_DEVICE_TIGON3_57788)},
        {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)},
@@ -784,7 +785,7 @@ static int tg3_writephy(struct tg3 *tp, int reg, u32 val)
        unsigned int loops;
        int ret;
 
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906 &&
+       if ((tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) &&
            (reg == MII_TG3_CTRL || reg == MII_TG3_AUX_CTRL))
                return 0;
 
@@ -917,7 +918,9 @@ static void tg3_mdio_config_5785(struct tg3 *tp)
                tw32(MAC_PHYCFG2, val);
 
                val = tr32(MAC_PHYCFG1);
-               val &= ~MAC_PHYCFG1_RGMII_INT;
+               val &= ~(MAC_PHYCFG1_RGMII_INT |
+                        MAC_PHYCFG1_RXCLK_TO_MASK | MAC_PHYCFG1_TXCLK_TO_MASK);
+               val |= MAC_PHYCFG1_RXCLK_TIMEOUT | MAC_PHYCFG1_TXCLK_TIMEOUT;
                tw32(MAC_PHYCFG1, val);
 
                return;
@@ -933,15 +936,18 @@ static void tg3_mdio_config_5785(struct tg3 *tp)
 
        tw32(MAC_PHYCFG2, val);
 
-       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) {
+       val = tr32(MAC_PHYCFG1);
+       val &= ~(MAC_PHYCFG1_RXCLK_TO_MASK | MAC_PHYCFG1_TXCLK_TO_MASK |
+                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 |= MAC_PHYCFG1_RXCLK_TIMEOUT | MAC_PHYCFG1_TXCLK_TIMEOUT |
+              MAC_PHYCFG1_RGMII_INT | MAC_PHYCFG1_TXC_DRV;
+       tw32(MAC_PHYCFG1, val);
 
        val = tr32(MAC_EXT_RGMII_MODE);
        val &= ~(MAC_RGMII_MODE_RX_INT_B |
@@ -1064,6 +1070,7 @@ static int tg3_mdio_init(struct tg3 *tp)
        case TG3_PHY_ID_RTL8201E:
        case TG3_PHY_ID_BCMAC131:
                phydev->interface = PHY_INTERFACE_MODE_MII;
+               tp->tg3_flags3 |= TG3_FLG3_PHY_IS_FET;
                break;
        }
 
@@ -1469,14 +1476,38 @@ static void tg3_phydsp_write(struct tg3 *tp, u32 reg, u32 val)
        tg3_writephy(tp, MII_TG3_DSP_RW_PORT, val);
 }
 
+static void tg3_phy_fet_toggle_apd(struct tg3 *tp, bool enable)
+{
+       u32 phytest;
+
+       if (!tg3_readphy(tp, MII_TG3_FET_TEST, &phytest)) {
+               u32 phy;
+
+               tg3_writephy(tp, MII_TG3_FET_TEST,
+                            phytest | MII_TG3_FET_SHADOW_EN);
+               if (!tg3_readphy(tp, MII_TG3_FET_SHDW_AUXSTAT2, &phy)) {
+                       if (enable)
+                               phy |= MII_TG3_FET_SHDW_AUXSTAT2_APD;
+                       else
+                               phy &= ~MII_TG3_FET_SHDW_AUXSTAT2_APD;
+                       tg3_writephy(tp, MII_TG3_FET_SHDW_AUXSTAT2, phy);
+               }
+               tg3_writephy(tp, MII_TG3_FET_TEST, phytest);
+       }
+}
+
 static void tg3_phy_toggle_apd(struct tg3 *tp, bool enable)
 {
        u32 reg;
 
-       if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+       if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
                return;
 
+       if (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) {
+               tg3_phy_fet_toggle_apd(tp, enable);
+               return;
+       }
+
        reg = MII_TG3_MISC_SHDW_WREN |
              MII_TG3_MISC_SHDW_SCR5_SEL |
              MII_TG3_MISC_SHDW_SCR5_LPED |
@@ -1506,20 +1537,22 @@ static void tg3_phy_toggle_automdix(struct tg3 *tp, int enable)
            (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES))
                return;
 
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+       if (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) {
                u32 ephy;
 
-               if (!tg3_readphy(tp, MII_TG3_EPHY_TEST, &ephy)) {
-                       tg3_writephy(tp, MII_TG3_EPHY_TEST,
-                                    ephy | MII_TG3_EPHY_SHADOW_EN);
-                       if (!tg3_readphy(tp, MII_TG3_EPHYTST_MISCCTRL, &phy)) {
+               if (!tg3_readphy(tp, MII_TG3_FET_TEST, &ephy)) {
+                       u32 reg = MII_TG3_FET_SHDW_MISCCTRL;
+
+                       tg3_writephy(tp, MII_TG3_FET_TEST,
+                                    ephy | MII_TG3_FET_SHADOW_EN);
+                       if (!tg3_readphy(tp, reg, &phy)) {
                                if (enable)
-                                       phy |= MII_TG3_EPHYTST_MISCCTRL_MDIX;
+                                       phy |= MII_TG3_FET_SHDW_MISCCTRL_MDIX;
                                else
-                                       phy &= ~MII_TG3_EPHYTST_MISCCTRL_MDIX;
-                               tg3_writephy(tp, MII_TG3_EPHYTST_MISCCTRL, phy);
+                                       phy &= ~MII_TG3_FET_SHDW_MISCCTRL_MDIX;
+                               tg3_writephy(tp, reg, phy);
                        }
-                       tg3_writephy(tp, MII_TG3_EPHY_TEST, ephy);
+                       tg3_writephy(tp, MII_TG3_FET_TEST, ephy);
                }
        } else {
                phy = MII_TG3_AUXCTL_MISC_RDSEL_MISC |
@@ -1910,7 +1943,7 @@ out:
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
                /* adjust output voltage */
-               tg3_writephy(tp, MII_TG3_EPHY_PTEST, 0x12);
+               tg3_writephy(tp, MII_TG3_FET_PTEST, 0x12);
        }
 
        tg3_phy_toggle_automdix(tp, 1);
@@ -1950,7 +1983,8 @@ static void tg3_frob_aux_power(struct tg3 *tp)
                                     GRC_LCLCTRL_GPIO_OUTPUT0 |
                                     GRC_LCLCTRL_GPIO_OUTPUT1),
                                    100);
-               } else if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761) {
+               } else if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761 ||
+                          tp->pdev->device == TG3PCI_DEVICE_TIGON3_5761S) {
                        /* The 5761 non-e device swaps GPIO 0 and GPIO 2. */
                        u32 grc_local_ctrl = GRC_LCLCTRL_GPIO_OE0 |
                                             GRC_LCLCTRL_GPIO_OE1 |
@@ -2455,8 +2489,6 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
                }
        }
 
-       __tg3_set_mac_addr(tp, 0);
-
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
                u32 val;
 
@@ -2656,7 +2688,7 @@ static void tg3_aux_stat_to_speed_duplex(struct tg3 *tp, u32 val, u16 *speed, u8
                break;
 
        default:
-               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+               if (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) {
                        *speed = (val & MII_TG3_AUX_STAT_100) ? SPEED_100 :
                                 SPEED_10;
                        *duplex = (val & MII_TG3_AUX_STAT_FULL) ? DUPLEX_FULL :
@@ -2991,7 +3023,7 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
 
        if (tp->tg3_flags & TG3_FLAG_USE_MI_INTERRUPT)
                tg3_writephy(tp, MII_TG3_IMASK, ~MII_TG3_INT_LINKCHG);
-       else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906)
+       else if (!(tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET))
                tg3_writephy(tp, MII_TG3_IMASK, ~0);
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
@@ -3101,7 +3133,9 @@ relink:
                        tp->mac_mode |= MAC_MODE_PORT_MODE_MII;
                else
                        tp->mac_mode |= MAC_MODE_PORT_MODE_GMII;
-       } else
+       } else if (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET)
+               tp->mac_mode |= MAC_MODE_PORT_MODE_MII;
+       else
                tp->mac_mode |= MAC_MODE_PORT_MODE_GMII;
 
        tp->mac_mode &= ~MAC_MODE_HALF_DUPLEX;
@@ -3168,6 +3202,15 @@ relink:
                        pci_write_config_word(tp->pdev,
                                              tp->pcie_cap + PCI_EXP_LNKCTL,
                                              newlnkctl);
+       } else if (tp->tg3_flags3 & TG3_FLG3_TOGGLE_10_100_L1PLLPD) {
+               u32 newreg, oldreg = tr32(TG3_PCIE_LNKCTL);
+               if (tp->link_config.active_speed == SPEED_100 ||
+                   tp->link_config.active_speed == SPEED_10)
+                       newreg = oldreg & ~TG3_PCIE_LNKCTL_L1_PLL_PD_EN;
+               else
+                       newreg = oldreg | TG3_PCIE_LNKCTL_L1_PLL_PD_EN;
+               if (newreg != oldreg)
+                       tw32(TG3_PCIE_LNKCTL, newreg);
        }
 
        if (current_link_up != netif_carrier_ok(tp->dev)) {
@@ -4656,6 +4699,7 @@ static int tg3_poll(struct napi_struct *napi, int budget)
                         * so we must read it before checking for more work.
                         */
                        tp->last_tag = sblk->status_tag;
+                       tp->last_irq_tag = tp->last_tag;
                        rmb();
                } else
                        sblk->status &= ~SD_STATUS_UPDATED;
@@ -4811,7 +4855,7 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
         * Reading the PCI State register will confirm whether the
         * interrupt is ours and will flush the status block.
         */
-       if (unlikely(sblk->status_tag == tp->last_tag)) {
+       if (unlikely(sblk->status_tag == tp->last_irq_tag)) {
                if ((tp->tg3_flags & TG3_FLAG_CHIP_RESETTING) ||
                    (tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
                        handled = 0;
@@ -4831,18 +4875,22 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
         * excessive spurious interrupts can be worse in some cases.
         */
        tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
+
+       /*
+        * In a shared interrupt configuration, sometimes other devices'
+        * interrupts will scream.  We record the current status tag here
+        * so that the above check can report that the screaming interrupts
+        * are unhandled.  Eventually they will be silenced.
+        */
+       tp->last_irq_tag = sblk->status_tag;
+
        if (tg3_irq_sync(tp))
                goto out;
-       if (napi_schedule_prep(&tp->napi)) {
-               prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
-               /* Update last_tag to mark that this status has been
-                * seen. Because interrupt may be shared, we may be
-                * racing with tg3_poll(), so only update last_tag
-                * if tg3_poll() is not scheduled.
-                */
-               tp->last_tag = sblk->status_tag;
-               __napi_schedule(&tp->napi);
-       }
+
+       prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
+
+       napi_schedule(&tp->napi);
+
 out:
        return IRQ_RETVAL(handled);
 }
@@ -5017,7 +5065,7 @@ static int tigon3_dma_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb,
                /* New SKB is guaranteed to be linear. */
                entry = *start;
                ret = skb_dma_map(&tp->pdev->dev, new_skb, DMA_TO_DEVICE);
-               new_addr = skb_shinfo(new_skb)->dma_maps[0];
+               new_addr = skb_shinfo(new_skb)->dma_head;
 
                /* Make sure new skb does not cross any 4G boundaries.
                 * Drop the packet if it does.
@@ -5151,7 +5199,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        sp = skb_shinfo(skb);
 
-       mapping = sp->dma_maps[0];
+       mapping = sp->dma_head;
 
        tp->tx_buffers[entry].skb = skb;
 
@@ -5169,7 +5217,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
                        len = frag->size;
-                       mapping = sp->dma_maps[i + 1];
+                       mapping = sp->dma_maps[i];
                        tp->tx_buffers[entry].skb = NULL;
 
                        tg3_set_txd(tp, entry, mapping, len,
@@ -5190,9 +5238,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
        }
 
 out_unlock:
-       mmiowb();
-
-       dev->trans_start = jiffies;
+       mmiowb();
 
        return NETDEV_TX_OK;
 }
@@ -5329,7 +5375,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
 
        sp = skb_shinfo(skb);
 
-       mapping = sp->dma_maps[0];
+       mapping = sp->dma_head;
 
        tp->tx_buffers[entry].skb = skb;
 
@@ -5354,7 +5400,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
                        skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
                        len = frag->size;
-                       mapping = sp->dma_maps[i + 1];
+                       mapping = sp->dma_maps[i];
 
                        tp->tx_buffers[entry].skb = NULL;
 
@@ -5403,9 +5449,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
        }
 
 out_unlock:
-       mmiowb();
-
-       dev->trans_start = jiffies;
+       mmiowb();
 
        return NETDEV_TX_OK;
 }
@@ -6156,9 +6200,15 @@ static int tg3_chip_reset(struct tg3 *tp)
                tp->hw_status->status_tag = 0;
        }
        tp->last_tag = 0;
+       tp->last_irq_tag = 0;
        smp_mb();
        synchronize_irq(tp->pdev->irq);
 
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) {
+               val = tr32(TG3_PCIE_LNKCTL) & ~TG3_PCIE_LNKCTL_L1_PLL_PD_EN;
+               tw32(TG3_PCIE_LNKCTL, val | TG3_PCIE_LNKCTL_L1_PLL_PD_DIS);
+       }
+
        /* do the reset */
        val = GRC_MISC_CFG_CORECLK_RESET;
 
@@ -6211,6 +6261,8 @@ static int tg3_chip_reset(struct tg3 *tp)
        udelay(120);
 
        if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) && tp->pcie_cap) {
+               u16 val16;
+
                if (tp->pci_chip_rev_id == CHIPREV_ID_5750_A0) {
                        int i;
                        u32 cfg_val;
@@ -6224,12 +6276,22 @@ static int tg3_chip_reset(struct tg3 *tp)
                                               cfg_val | (1 << 15));
                }
 
-               /* Set PCIE max payload size to 128 bytes and
-                * clear the "no snoop" and "relaxed ordering" bits.
+               /* Clear the "no snoop" and "relaxed ordering" bits. */
+               pci_read_config_word(tp->pdev,
+                                    tp->pcie_cap + PCI_EXP_DEVCTL,
+                                    &val16);
+               val16 &= ~(PCI_EXP_DEVCTL_RELAX_EN |
+                          PCI_EXP_DEVCTL_NOSNOOP_EN);
+               /*
+                * 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))
+                       val16 &= ~PCI_EXP_DEVCTL_PAYLOAD;
                pci_write_config_word(tp->pdev,
                                      tp->pcie_cap + PCI_EXP_DEVCTL,
-                                     0);
+                                     val16);
 
                pcie_set_readrq(tp->pdev, 4096);
 
@@ -6287,14 +6349,14 @@ 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);
        if (err)
                return err;
 
+       tg3_mdio_start(tp);
+
        if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) &&
            tp->pci_chip_rev_id != CHIPREV_ID_5750_A0) {
                val = tr32(0x7c00);
@@ -6350,6 +6412,8 @@ static int tg3_halt(struct tg3 *tp, int kind, int silent)
        tg3_abort_hw(tp, silent);
        err = tg3_chip_reset(tp);
 
+       __tg3_set_mac_addr(tp, 0);
+
        tg3_write_sig_legacy(tp, kind);
        tg3_write_sig_post_reset(tp, kind);
 
@@ -6711,6 +6775,27 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                tw32(TG3_CPMU_HST_ACC, val);
        }
 
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) {
+               val = tr32(PCIE_PWR_MGMT_THRESH) & ~PCIE_PWR_MGMT_L1_THRESH_MSK;
+               val |= PCIE_PWR_MGMT_EXT_ASPM_TMR_EN |
+                      PCIE_PWR_MGMT_L1_THRESH_4MS;
+               tw32(PCIE_PWR_MGMT_THRESH, val);
+
+               val = tr32(TG3_PCIE_EIDLE_DELAY) & ~TG3_PCIE_EIDLE_DELAY_MASK;
+               tw32(TG3_PCIE_EIDLE_DELAY, val | TG3_PCIE_EIDLE_DELAY_13_CLKS);
+
+               tw32(TG3_CORR_ERR_STAT, TG3_CORR_ERR_STAT_CLEAR);
+       }
+
+       if (tp->tg3_flags3 & TG3_FLG3_TOGGLE_10_100_L1PLLPD) {
+               val = tr32(TG3_PCIE_LNKCTL);
+               if (tp->tg3_flags3 & TG3_FLG3_CLKREQ_BUG)
+                       val |= TG3_PCIE_LNKCTL_L1_PLL_PD_DIS;
+               else
+                       val &= ~TG3_PCIE_LNKCTL_L1_PLL_PD_DIS;
+               tw32(TG3_PCIE_LNKCTL, val);
+       }
+
        /* This works around an issue with Athlon chipsets on
         * B3 tigon3 silicon.  This bit has no effect on any
         * other revision.  But do not set this on PCI Express
@@ -6882,19 +6967,16 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        tw32(RCVDBDI_STD_BD + TG3_BDINFO_NIC_ADDR,
             NIC_SRAM_RX_BUFFER_DESC);
 
-       /* Don't even try to program the JUMBO/MINI buffer descriptor
-        * configs on 5705.
-        */
-       if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
-               tw32(RCVDBDI_STD_BD + TG3_BDINFO_MAXLEN_FLAGS,
-                    RX_STD_MAX_SIZE_5705 << BDINFO_FLAGS_MAXLEN_SHIFT);
-       } else {
-               tw32(RCVDBDI_STD_BD + TG3_BDINFO_MAXLEN_FLAGS,
-                    RX_STD_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT);
-
+       /* Disable the mini ring */
+       if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
                tw32(RCVDBDI_MINI_BD + TG3_BDINFO_MAXLEN_FLAGS,
                     BDINFO_FLAGS_DISABLED);
 
+       /* Program the jumbo buffer descriptor ring control
+        * blocks on those devices that have them.
+        */
+       if ((tp->tg3_flags2 & TG3_FLG2_JUMBO_CAPABLE) &&
+           !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
                /* Setup replenish threshold. */
                tw32(RCVBDI_JUMBO_THRESH, tp->rx_jumbo_pending / 8);
 
@@ -6912,7 +6994,11 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                             BDINFO_FLAGS_DISABLED);
                }
 
-       }
+               val = RX_STD_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT;
+       } else
+               val = RX_STD_MAX_SIZE_5705 << BDINFO_FLAGS_MAXLEN_SHIFT;
+
+       tw32(RCVDBDI_STD_BD + TG3_BDINFO_MAXLEN_FLAGS, val);
 
        /* There is only one send ring on 5705/5750, no need to explicitly
         * disable the others.
@@ -7138,7 +7224,6 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        udelay(100);
 
        tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0);
-       tp->last_tag = 0;
 
        if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
                tw32_f(DMAC_MODE, DMAC_MODE_ENABLE);
@@ -7155,7 +7240,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 &&
             tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) {
-               if ((tp->tg3_flags & TG3_FLG2_TSO_CAPABLE) &&
+               if ((tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) &&
                    (tp->pci_chip_rev_id == CHIPREV_ID_5705_A1 ||
                     tp->pci_chip_rev_id == CHIPREV_ID_5705_A2)) {
                        /* nothing */
@@ -7293,7 +7378,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                        return err;
 
                if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) &&
-                   GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906) {
+                   !(tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET)) {
                        u32 tmp;
 
                        /* Clear CRC stats. */
@@ -8539,6 +8624,9 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
        u32 i, offset, len, b_offset, b_count;
        __be32 val;
 
+       if (tp->tg3_flags3 & TG3_FLG3_NO_NVRAM)
+               return -EINVAL;
+
        if (tp->link_config.phy_is_low_power)
                return -EAGAIN;
 
@@ -8604,7 +8692,8 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
        if (tp->link_config.phy_is_low_power)
                return -EAGAIN;
 
-       if (eeprom->magic != TG3_EEPROM_MAGIC)
+       if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) ||
+           eeprom->magic != TG3_EEPROM_MAGIC)
                return -EINVAL;
 
        offset = eeprom->offset;
@@ -9201,6 +9290,9 @@ static int tg3_test_nvram(struct tg3 *tp)
        __be32 *buf;
        int i, j, k, err = 0, size;
 
+       if (tp->tg3_flags3 & TG3_FLG3_NO_NVRAM)
+               return 0;
+
        if (tg3_nvram_read(tp, 0, &magic) != 0)
                return -EIO;
 
@@ -9683,18 +9775,8 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
        } else if (loopback_mode == TG3_PHY_LOOPBACK) {
                u32 val;
 
-               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
-                       u32 phytest;
-
-                       if (!tg3_readphy(tp, MII_TG3_EPHY_TEST, &phytest)) {
-                               u32 phy;
-
-                               tg3_writephy(tp, MII_TG3_EPHY_TEST,
-                                            phytest | MII_TG3_EPHY_SHADOW_EN);
-                               if (!tg3_readphy(tp, 0x1b, &phy))
-                                       tg3_writephy(tp, 0x1b, phy & ~0x20);
-                               tg3_writephy(tp, MII_TG3_EPHY_TEST, phytest);
-                       }
+               if (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) {
+                       tg3_phy_fet_toggle_apd(tp, false);
                        val = BMCR_LOOPBACK | BMCR_FULLDPLX | BMCR_SPEED100;
                } else
                        val = BMCR_LOOPBACK | BMCR_FULLDPLX | BMCR_SPEED1000;
@@ -9705,8 +9787,9 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
                udelay(40);
 
                mac_mode = tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK;
-               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
-                       tg3_writephy(tp, MII_TG3_EPHY_PTEST, 0x1800);
+               if (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) {
+                       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+                               tg3_writephy(tp, MII_TG3_FET_PTEST, 0x1800);
                        mac_mode |= MAC_MODE_PORT_MODE_MII;
                } else
                        mac_mode |= MAC_MODE_PORT_MODE_GMII;
@@ -10183,7 +10266,8 @@ static void __devinit tg3_get_nvram_size(struct tg3 *tp)
 {
        u32 val;
 
-       if (tg3_nvram_read(tp, 0, &val) != 0)
+       if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) ||
+           tg3_nvram_read(tp, 0, &val) != 0)
                return;
 
        /* Selfboot format */
@@ -10219,8 +10303,7 @@ static void __devinit tg3_get_nvram_info(struct tg3 *tp)
        nvcfg1 = tr32(NVRAM_CFG1);
        if (nvcfg1 & NVRAM_CFG1_FLASHIF_ENAB) {
                tp->tg3_flags2 |= TG3_FLG2_FLASH;
-       }
-       else {
+       } else {
                nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
                tw32(NVRAM_CFG1, nvcfg1);
        }
@@ -10228,37 +10311,36 @@ static void __devinit tg3_get_nvram_info(struct tg3 *tp)
        if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) ||
            (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
                switch (nvcfg1 & NVRAM_CFG1_VENDOR_MASK) {
-                       case FLASH_VENDOR_ATMEL_FLASH_BUFFERED:
-                               tp->nvram_jedecnum = JEDEC_ATMEL;
-                               tp->nvram_pagesize = ATMEL_AT45DB0X1B_PAGE_SIZE;
-                               tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-                               break;
-                       case FLASH_VENDOR_ATMEL_FLASH_UNBUFFERED:
-                               tp->nvram_jedecnum = JEDEC_ATMEL;
-                               tp->nvram_pagesize = ATMEL_AT25F512_PAGE_SIZE;
-                               break;
-                       case FLASH_VENDOR_ATMEL_EEPROM:
-                               tp->nvram_jedecnum = JEDEC_ATMEL;
-                               tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
-                               tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-                               break;
-                       case FLASH_VENDOR_ST:
-                               tp->nvram_jedecnum = JEDEC_ST;
-                               tp->nvram_pagesize = ST_M45PEX0_PAGE_SIZE;
-                               tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-                               break;
-                       case FLASH_VENDOR_SAIFUN:
-                               tp->nvram_jedecnum = JEDEC_SAIFUN;
-                               tp->nvram_pagesize = SAIFUN_SA25F0XX_PAGE_SIZE;
-                               break;
-                       case FLASH_VENDOR_SST_SMALL:
-                       case FLASH_VENDOR_SST_LARGE:
-                               tp->nvram_jedecnum = JEDEC_SST;
-                               tp->nvram_pagesize = SST_25VF0X0_PAGE_SIZE;
-                               break;
+               case FLASH_VENDOR_ATMEL_FLASH_BUFFERED:
+                       tp->nvram_jedecnum = JEDEC_ATMEL;
+                       tp->nvram_pagesize = ATMEL_AT45DB0X1B_PAGE_SIZE;
+                       tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+                       break;
+               case FLASH_VENDOR_ATMEL_FLASH_UNBUFFERED:
+                       tp->nvram_jedecnum = JEDEC_ATMEL;
+                       tp->nvram_pagesize = ATMEL_AT25F512_PAGE_SIZE;
+                       break;
+               case FLASH_VENDOR_ATMEL_EEPROM:
+                       tp->nvram_jedecnum = JEDEC_ATMEL;
+                       tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
+                       tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+                       break;
+               case FLASH_VENDOR_ST:
+                       tp->nvram_jedecnum = JEDEC_ST;
+                       tp->nvram_pagesize = ST_M45PEX0_PAGE_SIZE;
+                       tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+                       break;
+               case FLASH_VENDOR_SAIFUN:
+                       tp->nvram_jedecnum = JEDEC_SAIFUN;
+                       tp->nvram_pagesize = SAIFUN_SA25F0XX_PAGE_SIZE;
+                       break;
+               case FLASH_VENDOR_SST_SMALL:
+               case FLASH_VENDOR_SST_LARGE:
+                       tp->nvram_jedecnum = JEDEC_SST;
+                       tp->nvram_pagesize = SST_25VF0X0_PAGE_SIZE;
+                       break;
                }
-       }
-       else {
+       } else {
                tp->nvram_jedecnum = JEDEC_ATMEL;
                tp->nvram_pagesize = ATMEL_AT45DB0X1B_PAGE_SIZE;
                tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
@@ -10276,48 +10358,47 @@ static void __devinit tg3_get_5752_nvram_info(struct tg3 *tp)
                tp->tg3_flags2 |= TG3_FLG2_PROTECTED_NVRAM;
 
        switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
-               case FLASH_5752VENDOR_ATMEL_EEPROM_64KHZ:
-               case FLASH_5752VENDOR_ATMEL_EEPROM_376KHZ:
-                       tp->nvram_jedecnum = JEDEC_ATMEL;
-                       tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-                       break;
-               case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED:
-                       tp->nvram_jedecnum = JEDEC_ATMEL;
-                       tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-                       tp->tg3_flags2 |= TG3_FLG2_FLASH;
-                       break;
-               case FLASH_5752VENDOR_ST_M45PE10:
-               case FLASH_5752VENDOR_ST_M45PE20:
-               case FLASH_5752VENDOR_ST_M45PE40:
-                       tp->nvram_jedecnum = JEDEC_ST;
-                       tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-                       tp->tg3_flags2 |= TG3_FLG2_FLASH;
-                       break;
+       case FLASH_5752VENDOR_ATMEL_EEPROM_64KHZ:
+       case FLASH_5752VENDOR_ATMEL_EEPROM_376KHZ:
+               tp->nvram_jedecnum = JEDEC_ATMEL;
+               tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+               break;
+       case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED:
+               tp->nvram_jedecnum = JEDEC_ATMEL;
+               tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+               tp->tg3_flags2 |= TG3_FLG2_FLASH;
+               break;
+       case FLASH_5752VENDOR_ST_M45PE10:
+       case FLASH_5752VENDOR_ST_M45PE20:
+       case FLASH_5752VENDOR_ST_M45PE40:
+               tp->nvram_jedecnum = JEDEC_ST;
+               tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+               tp->tg3_flags2 |= TG3_FLG2_FLASH;
+               break;
        }
 
        if (tp->tg3_flags2 & TG3_FLG2_FLASH) {
                switch (nvcfg1 & NVRAM_CFG1_5752PAGE_SIZE_MASK) {
-                       case FLASH_5752PAGE_SIZE_256:
-                               tp->nvram_pagesize = 256;
-                               break;
-                       case FLASH_5752PAGE_SIZE_512:
-                               tp->nvram_pagesize = 512;
-                               break;
-                       case FLASH_5752PAGE_SIZE_1K:
-                               tp->nvram_pagesize = 1024;
-                               break;
-                       case FLASH_5752PAGE_SIZE_2K:
-                               tp->nvram_pagesize = 2048;
-                               break;
-                       case FLASH_5752PAGE_SIZE_4K:
-                               tp->nvram_pagesize = 4096;
-                               break;
-                       case FLASH_5752PAGE_SIZE_264:
-                               tp->nvram_pagesize = 264;
-                               break;
+               case FLASH_5752PAGE_SIZE_256:
+                       tp->nvram_pagesize = 256;
+                       break;
+               case FLASH_5752PAGE_SIZE_512:
+                       tp->nvram_pagesize = 512;
+                       break;
+               case FLASH_5752PAGE_SIZE_1K:
+                       tp->nvram_pagesize = 1024;
+                       break;
+               case FLASH_5752PAGE_SIZE_2K:
+                       tp->nvram_pagesize = 2048;
+                       break;
+               case FLASH_5752PAGE_SIZE_4K:
+                       tp->nvram_pagesize = 4096;
+                       break;
+               case FLASH_5752PAGE_SIZE_264:
+                       tp->nvram_pagesize = 264;
+                       break;
                }
-       }
-       else {
+       } else {
                /* For eeprom, set pagesize to maximum eeprom size */
                tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
 
@@ -10340,45 +10421,45 @@ static void __devinit tg3_get_5755_nvram_info(struct tg3 *tp)
 
        nvcfg1 &= NVRAM_CFG1_5752VENDOR_MASK;
        switch (nvcfg1) {
-               case FLASH_5755VENDOR_ATMEL_FLASH_1:
-               case FLASH_5755VENDOR_ATMEL_FLASH_2:
-               case FLASH_5755VENDOR_ATMEL_FLASH_3:
-               case FLASH_5755VENDOR_ATMEL_FLASH_5:
-                       tp->nvram_jedecnum = JEDEC_ATMEL;
-                       tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-                       tp->tg3_flags2 |= TG3_FLG2_FLASH;
-                       tp->nvram_pagesize = 264;
-                       if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_1 ||
-                           nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_5)
-                               tp->nvram_size = (protect ? 0x3e200 :
-                                                 TG3_NVRAM_SIZE_512KB);
-                       else if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_2)
-                               tp->nvram_size = (protect ? 0x1f200 :
-                                                 TG3_NVRAM_SIZE_256KB);
-                       else
-                               tp->nvram_size = (protect ? 0x1f200 :
-                                                 TG3_NVRAM_SIZE_128KB);
-                       break;
-               case FLASH_5752VENDOR_ST_M45PE10:
-               case FLASH_5752VENDOR_ST_M45PE20:
-               case FLASH_5752VENDOR_ST_M45PE40:
-                       tp->nvram_jedecnum = JEDEC_ST;
-                       tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-                       tp->tg3_flags2 |= TG3_FLG2_FLASH;
-                       tp->nvram_pagesize = 256;
-                       if (nvcfg1 == FLASH_5752VENDOR_ST_M45PE10)
-                               tp->nvram_size = (protect ?
-                                                 TG3_NVRAM_SIZE_64KB :
-                                                 TG3_NVRAM_SIZE_128KB);
-                       else if (nvcfg1 == FLASH_5752VENDOR_ST_M45PE20)
-                               tp->nvram_size = (protect ?
-                                                 TG3_NVRAM_SIZE_64KB :
-                                                 TG3_NVRAM_SIZE_256KB);
-                       else
-                               tp->nvram_size = (protect ?
-                                                 TG3_NVRAM_SIZE_128KB :
-                                                 TG3_NVRAM_SIZE_512KB);
-                       break;
+       case FLASH_5755VENDOR_ATMEL_FLASH_1:
+       case FLASH_5755VENDOR_ATMEL_FLASH_2:
+       case FLASH_5755VENDOR_ATMEL_FLASH_3:
+       case FLASH_5755VENDOR_ATMEL_FLASH_5:
+               tp->nvram_jedecnum = JEDEC_ATMEL;
+               tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+               tp->tg3_flags2 |= TG3_FLG2_FLASH;
+               tp->nvram_pagesize = 264;
+               if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_1 ||
+                   nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_5)
+                       tp->nvram_size = (protect ? 0x3e200 :
+                                         TG3_NVRAM_SIZE_512KB);
+               else if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_2)
+                       tp->nvram_size = (protect ? 0x1f200 :
+                                         TG3_NVRAM_SIZE_256KB);
+               else
+                       tp->nvram_size = (protect ? 0x1f200 :
+                                         TG3_NVRAM_SIZE_128KB);
+               break;
+       case FLASH_5752VENDOR_ST_M45PE10:
+       case FLASH_5752VENDOR_ST_M45PE20:
+       case FLASH_5752VENDOR_ST_M45PE40:
+               tp->nvram_jedecnum = JEDEC_ST;
+               tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+               tp->tg3_flags2 |= TG3_FLG2_FLASH;
+               tp->nvram_pagesize = 256;
+               if (nvcfg1 == FLASH_5752VENDOR_ST_M45PE10)
+                       tp->nvram_size = (protect ?
+                                         TG3_NVRAM_SIZE_64KB :
+                                         TG3_NVRAM_SIZE_128KB);
+               else if (nvcfg1 == FLASH_5752VENDOR_ST_M45PE20)
+                       tp->nvram_size = (protect ?
+                                         TG3_NVRAM_SIZE_64KB :
+                                         TG3_NVRAM_SIZE_256KB);
+               else
+                       tp->nvram_size = (protect ?
+                                         TG3_NVRAM_SIZE_128KB :
+                                         TG3_NVRAM_SIZE_512KB);
+               break;
        }
 }
 
@@ -10389,34 +10470,34 @@ static void __devinit tg3_get_5787_nvram_info(struct tg3 *tp)
        nvcfg1 = tr32(NVRAM_CFG1);
 
        switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
-               case FLASH_5787VENDOR_ATMEL_EEPROM_64KHZ:
-               case FLASH_5787VENDOR_ATMEL_EEPROM_376KHZ:
-               case FLASH_5787VENDOR_MICRO_EEPROM_64KHZ:
-               case FLASH_5787VENDOR_MICRO_EEPROM_376KHZ:
-                       tp->nvram_jedecnum = JEDEC_ATMEL;
-                       tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-                       tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
+       case FLASH_5787VENDOR_ATMEL_EEPROM_64KHZ:
+       case FLASH_5787VENDOR_ATMEL_EEPROM_376KHZ:
+       case FLASH_5787VENDOR_MICRO_EEPROM_64KHZ:
+       case FLASH_5787VENDOR_MICRO_EEPROM_376KHZ:
+               tp->nvram_jedecnum = JEDEC_ATMEL;
+               tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+               tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
 
-                       nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
-                       tw32(NVRAM_CFG1, nvcfg1);
-                       break;
-               case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED:
-               case FLASH_5755VENDOR_ATMEL_FLASH_1:
-               case FLASH_5755VENDOR_ATMEL_FLASH_2:
-               case FLASH_5755VENDOR_ATMEL_FLASH_3:
-                       tp->nvram_jedecnum = JEDEC_ATMEL;
-                       tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-                       tp->tg3_flags2 |= TG3_FLG2_FLASH;
-                       tp->nvram_pagesize = 264;
-                       break;
-               case FLASH_5752VENDOR_ST_M45PE10:
-               case FLASH_5752VENDOR_ST_M45PE20:
-               case FLASH_5752VENDOR_ST_M45PE40:
-                       tp->nvram_jedecnum = JEDEC_ST;
-                       tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-                       tp->tg3_flags2 |= TG3_FLG2_FLASH;
-                       tp->nvram_pagesize = 256;
-                       break;
+               nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
+               tw32(NVRAM_CFG1, nvcfg1);
+               break;
+       case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED:
+       case FLASH_5755VENDOR_ATMEL_FLASH_1:
+       case FLASH_5755VENDOR_ATMEL_FLASH_2:
+       case FLASH_5755VENDOR_ATMEL_FLASH_3:
+               tp->nvram_jedecnum = JEDEC_ATMEL;
+               tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+               tp->tg3_flags2 |= TG3_FLG2_FLASH;
+               tp->nvram_pagesize = 264;
+               break;
+       case FLASH_5752VENDOR_ST_M45PE10:
+       case FLASH_5752VENDOR_ST_M45PE20:
+       case FLASH_5752VENDOR_ST_M45PE40:
+               tp->nvram_jedecnum = JEDEC_ST;
+               tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+               tp->tg3_flags2 |= TG3_FLG2_FLASH;
+               tp->nvram_pagesize = 256;
+               break;
        }
 }
 
@@ -10434,63 +10515,63 @@ static void __devinit tg3_get_5761_nvram_info(struct tg3 *tp)
 
        nvcfg1 &= NVRAM_CFG1_5752VENDOR_MASK;
        switch (nvcfg1) {
-               case FLASH_5761VENDOR_ATMEL_ADB021D:
-               case FLASH_5761VENDOR_ATMEL_ADB041D:
-               case FLASH_5761VENDOR_ATMEL_ADB081D:
-               case FLASH_5761VENDOR_ATMEL_ADB161D:
-               case FLASH_5761VENDOR_ATMEL_MDB021D:
-               case FLASH_5761VENDOR_ATMEL_MDB041D:
-               case FLASH_5761VENDOR_ATMEL_MDB081D:
-               case FLASH_5761VENDOR_ATMEL_MDB161D:
-                       tp->nvram_jedecnum = JEDEC_ATMEL;
-                       tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-                       tp->tg3_flags2 |= TG3_FLG2_FLASH;
-                       tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
-                       tp->nvram_pagesize = 256;
-                       break;
-               case FLASH_5761VENDOR_ST_A_M45PE20:
-               case FLASH_5761VENDOR_ST_A_M45PE40:
-               case FLASH_5761VENDOR_ST_A_M45PE80:
-               case FLASH_5761VENDOR_ST_A_M45PE16:
-               case FLASH_5761VENDOR_ST_M_M45PE20:
-               case FLASH_5761VENDOR_ST_M_M45PE40:
-               case FLASH_5761VENDOR_ST_M_M45PE80:
-               case FLASH_5761VENDOR_ST_M_M45PE16:
-                       tp->nvram_jedecnum = JEDEC_ST;
-                       tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-                       tp->tg3_flags2 |= TG3_FLG2_FLASH;
-                       tp->nvram_pagesize = 256;
-                       break;
+       case FLASH_5761VENDOR_ATMEL_ADB021D:
+       case FLASH_5761VENDOR_ATMEL_ADB041D:
+       case FLASH_5761VENDOR_ATMEL_ADB081D:
+       case FLASH_5761VENDOR_ATMEL_ADB161D:
+       case FLASH_5761VENDOR_ATMEL_MDB021D:
+       case FLASH_5761VENDOR_ATMEL_MDB041D:
+       case FLASH_5761VENDOR_ATMEL_MDB081D:
+       case FLASH_5761VENDOR_ATMEL_MDB161D:
+               tp->nvram_jedecnum = JEDEC_ATMEL;
+               tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+               tp->tg3_flags2 |= TG3_FLG2_FLASH;
+               tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
+               tp->nvram_pagesize = 256;
+               break;
+       case FLASH_5761VENDOR_ST_A_M45PE20:
+       case FLASH_5761VENDOR_ST_A_M45PE40:
+       case FLASH_5761VENDOR_ST_A_M45PE80:
+       case FLASH_5761VENDOR_ST_A_M45PE16:
+       case FLASH_5761VENDOR_ST_M_M45PE20:
+       case FLASH_5761VENDOR_ST_M_M45PE40:
+       case FLASH_5761VENDOR_ST_M_M45PE80:
+       case FLASH_5761VENDOR_ST_M_M45PE16:
+               tp->nvram_jedecnum = JEDEC_ST;
+               tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+               tp->tg3_flags2 |= TG3_FLG2_FLASH;
+               tp->nvram_pagesize = 256;
+               break;
        }
 
        if (protect) {
                tp->nvram_size = tr32(NVRAM_ADDR_LOCKOUT);
        } else {
                switch (nvcfg1) {
-                       case FLASH_5761VENDOR_ATMEL_ADB161D:
-                       case FLASH_5761VENDOR_ATMEL_MDB161D:
-                       case FLASH_5761VENDOR_ST_A_M45PE16:
-                       case FLASH_5761VENDOR_ST_M_M45PE16:
-                               tp->nvram_size = TG3_NVRAM_SIZE_2MB;
-                               break;
-                       case FLASH_5761VENDOR_ATMEL_ADB081D:
-                       case FLASH_5761VENDOR_ATMEL_MDB081D:
-                       case FLASH_5761VENDOR_ST_A_M45PE80:
-                       case FLASH_5761VENDOR_ST_M_M45PE80:
-                               tp->nvram_size = TG3_NVRAM_SIZE_1MB;
-                               break;
-                       case FLASH_5761VENDOR_ATMEL_ADB041D:
-                       case FLASH_5761VENDOR_ATMEL_MDB041D:
-                       case FLASH_5761VENDOR_ST_A_M45PE40:
-                       case FLASH_5761VENDOR_ST_M_M45PE40:
-                               tp->nvram_size = TG3_NVRAM_SIZE_512KB;
-                               break;
-                       case FLASH_5761VENDOR_ATMEL_ADB021D:
-                       case FLASH_5761VENDOR_ATMEL_MDB021D:
-                       case FLASH_5761VENDOR_ST_A_M45PE20:
-                       case FLASH_5761VENDOR_ST_M_M45PE20:
-                               tp->nvram_size = TG3_NVRAM_SIZE_256KB;
-                               break;
+               case FLASH_5761VENDOR_ATMEL_ADB161D:
+               case FLASH_5761VENDOR_ATMEL_MDB161D:
+               case FLASH_5761VENDOR_ST_A_M45PE16:
+               case FLASH_5761VENDOR_ST_M_M45PE16:
+                       tp->nvram_size = TG3_NVRAM_SIZE_2MB;
+                       break;
+               case FLASH_5761VENDOR_ATMEL_ADB081D:
+               case FLASH_5761VENDOR_ATMEL_MDB081D:
+               case FLASH_5761VENDOR_ST_A_M45PE80:
+               case FLASH_5761VENDOR_ST_M_M45PE80:
+                       tp->nvram_size = TG3_NVRAM_SIZE_1MB;
+                       break;
+               case FLASH_5761VENDOR_ATMEL_ADB041D:
+               case FLASH_5761VENDOR_ATMEL_MDB041D:
+               case FLASH_5761VENDOR_ST_A_M45PE40:
+               case FLASH_5761VENDOR_ST_M_M45PE40:
+                       tp->nvram_size = TG3_NVRAM_SIZE_512KB;
+                       break;
+               case FLASH_5761VENDOR_ATMEL_ADB021D:
+               case FLASH_5761VENDOR_ATMEL_MDB021D:
+               case FLASH_5761VENDOR_ST_A_M45PE20:
+               case FLASH_5761VENDOR_ST_M_M45PE20:
+                       tp->nvram_size = TG3_NVRAM_SIZE_256KB;
+                       break;
                }
        }
 }
@@ -10565,6 +10646,7 @@ static void __devinit tg3_get_57780_nvram_info(struct tg3 *tp)
                }
                break;
        default:
+               tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM;
                return;
        }
 
@@ -11365,7 +11447,8 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
        unsigned int i;
        u32 magic;
 
-       if (tg3_nvram_read(tp, 0x0, &magic))
+       if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) ||
+           tg3_nvram_read(tp, 0x0, &magic))
                goto out_not_found;
 
        if (magic == TG3_EEPROM_MAGIC) {
@@ -11457,6 +11540,18 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
 out_not_found:
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
                strcpy(tp->board_part_number, "BCM95906");
+       else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 &&
+                tp->pdev->device == TG3PCI_DEVICE_TIGON3_57780)
+               strcpy(tp->board_part_number, "BCM57780");
+       else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 &&
+                tp->pdev->device == TG3PCI_DEVICE_TIGON3_57760)
+               strcpy(tp->board_part_number, "BCM57760");
+       else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 &&
+                tp->pdev->device == TG3PCI_DEVICE_TIGON3_57790)
+               strcpy(tp->board_part_number, "BCM57790");
+       else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 &&
+                tp->pdev->device == TG3PCI_DEVICE_TIGON3_57788)
+               strcpy(tp->board_part_number, "BCM57788");
        else
                strcpy(tp->board_part_number, "none");
 }
@@ -11667,6 +11762,14 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp)
 {
        u32 val;
 
+       if (tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) {
+               tp->fw_ver[0] = 's';
+               tp->fw_ver[1] = 'b';
+               tp->fw_ver[2] = '\0';
+
+               return;
+       }
+
        if (tg3_nvram_read(tp, 0, &val))
                return;
 
@@ -11952,7 +12055,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                                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 ||
-                           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
+                           tp->pci_chip_rev_id == CHIPREV_ID_57780_A0 ||
+                           tp->pci_chip_rev_id == CHIPREV_ID_57780_A1)
                                tp->tg3_flags3 |= TG3_FLG3_CLKREQ_BUG;
                }
        } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785) {
@@ -12144,7 +12248,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
                tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL;
 
-       if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761) {
+       if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761 ||
+           tp->pdev->device == TG3PCI_DEVICE_TIGON3_5761S) {
                /* Turn off the debug UART. */
                tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL;
                if (tp->tg3_flags2 & TG3_FLG2_IS_NIC)
@@ -12178,12 +12283,15 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                tp->tg3_flags |= TG3_FLAG_WOL_SPEED_100MB;
        }
 
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+               tp->tg3_flags3 |= TG3_FLG3_PHY_IS_FET;
+
        /* A few boards don't want Ethernet@WireSpeed phy feature */
        if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) ||
            ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) &&
             (tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) &&
             (tp->pci_chip_rev_id != CHIPREV_ID_5705_A1)) ||
-           (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) ||
+           (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) ||
            (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES))
                tp->tg3_flags2 |= TG3_FLG2_NO_ETH_WIRE_SPEED;
 
@@ -12194,7 +12302,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                tp->tg3_flags2 |= TG3_FLG2_PHY_5704_A0_BUG;
 
        if ((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
-           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906 &&
+           !(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) {
                if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
@@ -12231,6 +12339,11 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
                tp->tg3_flags3 |= TG3_FLG3_USE_PHYLIB;
 
+       if ((tp->pci_chip_rev_id == CHIPREV_ID_57780_A1 &&
+            tr32(RCVLPC_STATS_ENABLE) & RCVLPC_STATSENAB_ASF_FIX) ||
+           tp->pci_chip_rev_id == CHIPREV_ID_57780_A0)
+               tp->tg3_flags3 |= TG3_FLG3_TOGGLE_10_100_L1PLLPD;
+
        err = tg3_mdio_init(tp);
        if (err)
                return err;
@@ -12314,7 +12427,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
              tp->pdev->device == PCI_DEVICE_ID_TIGON3_5753F ||
              tp->pdev->device == PCI_DEVICE_ID_TIGON3_5787F)) ||
            tp->pdev->device == TG3PCI_DEVICE_TIGON3_57790 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+           (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET))
                tp->tg3_flags |= TG3_FLAG_10_100_ONLY;
 
        err = tg3_phy_probe(tp);
@@ -12454,7 +12567,8 @@ static int __devinit tg3_get_device_address(struct tg3 *tp)
        }
        if (!addr_ok) {
                /* Next, try NVRAM. */
-               if (!tg3_nvram_read_be32(tp, mac_offset + 0, &hi) &&
+               if (!(tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) &&
+                   !tg3_nvram_read_be32(tp, mac_offset + 0, &hi) &&
                    !tg3_nvram_read_be32(tp, mac_offset + 4, &lo)) {
                        memcpy(&dev->dev_addr[0], ((char *)&hi) + 2, 2);
                        memcpy(&dev->dev_addr[2], (char *)&lo, sizeof(lo));