[TG3]: update version and reldate
[sfrench/cifs-2.6.git] / drivers / net / tg3.c
index 770e6b6cec6067a02ddf6520113948d930aa85a8..3c9b13b3cf9b3c5ce8c0b0a8498fd5751f8e93de 100644 (file)
@@ -69,8 +69,8 @@
 
 #define DRV_MODULE_NAME                "tg3"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "3.56"
-#define DRV_MODULE_RELDATE     "Apr 1, 2006"
+#define DRV_MODULE_VERSION     "3.60"
+#define DRV_MODULE_RELDATE     "June 17, 2006"
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
@@ -229,6 +229,8 @@ static struct pci_device_id tg3_pci_tbl[] = {
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
        { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5755M,
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+       { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5786,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
        { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787,
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
        { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787M,
@@ -497,21 +499,20 @@ static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val)
        unsigned long flags;
 
        spin_lock_irqsave(&tp->indirect_lock, flags);
-       pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
-       pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
+       if (tp->tg3_flags & TG3_FLAG_SRAM_USE_CONFIG) {
+               pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
+               pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
 
-       /* Always leave this as zero. */
-       pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
-       spin_unlock_irqrestore(&tp->indirect_lock, flags);
-}
+               /* Always leave this as zero. */
+               pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
+       } else {
+               tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, off);
+               tw32_f(TG3PCI_MEM_WIN_DATA, val);
 
-static void tg3_write_mem_fast(struct tg3 *tp, u32 off, u32 val)
-{
-       /* If no workaround is needed, write to mem space directly */
-       if (tp->write32 != tg3_write_indirect_reg32)
-               tw32(NIC_SRAM_WIN_BASE + off, val);
-       else
-               tg3_write_mem(tp, off, val);
+               /* Always leave this as zero. */
+               tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, 0);
+       }
+       spin_unlock_irqrestore(&tp->indirect_lock, flags);
 }
 
 static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val)
@@ -519,11 +520,19 @@ static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val)
        unsigned long flags;
 
        spin_lock_irqsave(&tp->indirect_lock, flags);
-       pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
-       pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
+       if (tp->tg3_flags & TG3_FLAG_SRAM_USE_CONFIG) {
+               pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
+               pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
 
-       /* Always leave this as zero. */
-       pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
+               /* Always leave this as zero. */
+               pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
+       } else {
+               tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, off);
+               *val = tr32(TG3PCI_MEM_WIN_DATA);
+
+               /* Always leave this as zero. */
+               tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, 0);
+       }
        spin_unlock_irqrestore(&tp->indirect_lock, flags);
 }
 
@@ -967,6 +976,8 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp)
        return err;
 }
 
+static void tg3_link_report(struct tg3 *);
+
 /* This will reset the tigon3 PHY if there is no valid
  * link unless the FORCE argument is non-zero.
  */
@@ -980,6 +991,11 @@ static int tg3_phy_reset(struct tg3 *tp)
        if (err != 0)
                return -EBUSY;
 
+       if (netif_running(tp->dev) && netif_carrier_ok(tp->dev)) {
+               netif_carrier_off(tp->dev);
+               tg3_link_report(tp);
+       }
+
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
@@ -1016,6 +1032,12 @@ out:
                tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x14e2);
                tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400);
        }
+       else if (tp->tg3_flags2 & TG3_FLG2_PHY_JITTER_BUG) {
+               tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00);
+               tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x000a);
+               tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x010b);
+               tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400);
+       }
        /* Set Extended packet length bit (bit 14) on all chips that */
        /* support jumbo frames */
        if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) {
@@ -1367,12 +1389,12 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
                }
        }
 
+       tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN);
+
        /* Finally, set the new power state. */
        pci_write_config_word(tp->pdev, pm + PCI_PM_CTRL, power_control);
        udelay(100);    /* Delay after power state change */
 
-       tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN);
-
        return 0;
 }
 
@@ -2945,6 +2967,29 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset)
        return err;
 }
 
+/* This is called whenever we suspect that the system chipset is re-
+ * ordering the sequence of MMIO to the tx send mailbox. The symptom
+ * is bogus tx completions. We try to recover by setting the
+ * TG3_FLAG_MBOX_WRITE_REORDER flag and resetting the chip later
+ * in the workqueue.
+ */
+static void tg3_tx_recover(struct tg3 *tp)
+{
+       BUG_ON((tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) ||
+              tp->write32_tx_mbox == tg3_write_indirect_mbox);
+
+       printk(KERN_WARNING PFX "%s: The system may be re-ordering memory-"
+              "mapped I/O cycles to the network device, attempting to "
+              "recover. Please report the problem to the driver maintainer "
+              "and include system chipset information.\n", tp->dev->name);
+
+       spin_lock(&tp->lock);
+       spin_lock(&tp->tx_lock);
+       tp->tg3_flags |= TG3_FLAG_TX_RECOVERY_PENDING;
+       spin_unlock(&tp->tx_lock);
+       spin_unlock(&tp->lock);
+}
+
 /* Tigon3 never reports partial packet sends.  So we do not
  * need special logic to handle SKBs that have not had all
  * of their frags sent yet, like SunGEM does.
@@ -2957,10 +3002,12 @@ static void tg3_tx(struct tg3 *tp)
        while (sw_idx != hw_idx) {
                struct tx_ring_info *ri = &tp->tx_buffers[sw_idx];
                struct sk_buff *skb = ri->skb;
-               int i;
+               int i, tx_bug = 0;
 
-               if (unlikely(skb == NULL))
-                       BUG();
+               if (unlikely(skb == NULL)) {
+                       tg3_tx_recover(tp);
+                       return;
+               }
 
                pci_unmap_single(tp->pdev,
                                 pci_unmap_addr(ri, mapping),
@@ -2972,12 +3019,9 @@ static void tg3_tx(struct tg3 *tp)
                sw_idx = NEXT_TX(sw_idx);
 
                for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-                       if (unlikely(sw_idx == hw_idx))
-                               BUG();
-
                        ri = &tp->tx_buffers[sw_idx];
-                       if (unlikely(ri->skb != NULL))
-                               BUG();
+                       if (unlikely(ri->skb != NULL || sw_idx == hw_idx))
+                               tx_bug = 1;
 
                        pci_unmap_page(tp->pdev,
                                       pci_unmap_addr(ri, mapping),
@@ -2988,6 +3032,11 @@ static void tg3_tx(struct tg3 *tp)
                }
 
                dev_kfree_skb(skb);
+
+               if (unlikely(tx_bug)) {
+                       tg3_tx_recover(tp);
+                       return;
+               }
        }
 
        tp->tx_cons = sw_idx;
@@ -3315,6 +3364,11 @@ static int tg3_poll(struct net_device *netdev, int *budget)
        /* run TX completion thread */
        if (sblk->idx[0].tx_consumer != tp->tx_cons) {
                tg3_tx(tp);
+               if (unlikely(tp->tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING)) {
+                       netif_rx_complete(netdev);
+                       schedule_work(&tp->reset_task);
+                       return 0;
+               }
        }
 
        /* run RX thread, within the bounds set by NAPI.
@@ -3528,7 +3582,7 @@ static irqreturn_t tg3_test_isr(int irq, void *dev_id,
        return IRQ_RETVAL(0);
 }
 
-static int tg3_init_hw(struct tg3 *);
+static int tg3_init_hw(struct tg3 *, int);
 static int tg3_halt(struct tg3 *, int, int);
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -3563,8 +3617,15 @@ static void tg3_reset_task(void *_data)
        restart_timer = tp->tg3_flags2 & TG3_FLG2_RESTART_TIMER;
        tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER;
 
+       if (tp->tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING) {
+               tp->write32_tx_mbox = tg3_write32_tx_mbox;
+               tp->write32_rx_mbox = tg3_write_flush_reg32;
+               tp->tg3_flags |= TG3_FLAG_MBOX_WRITE_REORDER;
+               tp->tg3_flags &= ~TG3_FLAG_TX_RECOVERY_PENDING;
+       }
+
        tg3_halt(tp, RESET_KIND_SHUTDOWN, 0);
-       tg3_init_hw(tp);
+       tg3_init_hw(tp, 1);
 
        tg3_netif_start(tp);
 
@@ -4039,7 +4100,7 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
 
        tg3_set_mtu(dev, tp, new_mtu);
 
-       tg3_init_hw(tp);
+       tg3_init_hw(tp, 0);
 
        tg3_netif_start(tp);
 
@@ -4469,9 +4530,8 @@ static void tg3_disable_nvram_access(struct tg3 *tp)
 /* tp->lock is held. */
 static void tg3_write_sig_pre_reset(struct tg3 *tp, int kind)
 {
-       if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X))
-               tg3_write_mem(tp, NIC_SRAM_FIRMWARE_MBOX,
-                             NIC_SRAM_FIRMWARE_MBOX_MAGIC1);
+       tg3_write_mem(tp, NIC_SRAM_FIRMWARE_MBOX,
+                     NIC_SRAM_FIRMWARE_MBOX_MAGIC1);
 
        if (tp->tg3_flags2 & TG3_FLG2_ASF_NEW_HANDSHAKE) {
                switch (kind) {
@@ -4552,13 +4612,12 @@ static int tg3_chip_reset(struct tg3 *tp)
        void (*write_op)(struct tg3 *, u32, u32);
        int i;
 
-       if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) {
-               tg3_nvram_lock(tp);
-               /* No matching tg3_nvram_unlock() after this because
-                * chip reset below will undo the nvram lock.
-                */
-               tp->nvram_lock_cnt = 0;
-       }
+       tg3_nvram_lock(tp);
+
+       /* No matching tg3_nvram_unlock() after this because
+        * chip reset below will undo the nvram lock.
+        */
+       tp->nvram_lock_cnt = 0;
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
@@ -4711,20 +4770,25 @@ static int tg3_chip_reset(struct tg3 *tp)
                tw32_f(MAC_MODE, 0);
        udelay(40);
 
-       if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) {
-               /* Wait for firmware initialization to complete. */
-               for (i = 0; i < 100000; i++) {
-                       tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val);
-                       if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1)
-                               break;
-                       udelay(10);
-               }
-               if (i >= 100000) {
-                       printk(KERN_ERR PFX "tg3_reset_hw timed out for %s, "
-                              "firmware will not restart magic=%08x\n",
-                              tp->dev->name, val);
-                       return -ENODEV;
-               }
+       /* Wait for firmware initialization to complete. */
+       for (i = 0; i < 100000; i++) {
+               tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val);
+               if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1)
+                       break;
+               udelay(10);
+       }
+
+       /* Chip might not be fitted with firmare.  Some Sun onboard
+        * parts are configured like that.  So don't signal the timeout
+        * of the above loop as an error, but do report the lack of
+        * running firmware once.
+        */
+       if (i >= 100000 &&
+           !(tp->tg3_flags2 & TG3_FLG2_NO_FWARE_REPORTED)) {
+               tp->tg3_flags2 |= TG3_FLG2_NO_FWARE_REPORTED;
+
+               printk(KERN_INFO PFX "%s: No firmware running.\n",
+                      tp->dev->name);
        }
 
        if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) &&
@@ -4928,9 +4992,8 @@ static int tg3_halt_cpu(struct tg3 *tp, u32 offset)
 {
        int i;
 
-       if (offset == TX_CPU_BASE &&
-           (tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
-               BUG();
+       BUG_ON(offset == TX_CPU_BASE &&
+           (tp->tg3_flags2 & TG3_FLG2_5705_PLUS));
 
        if (offset == RX_CPU_BASE) {
                for (i = 0; i < 10000; i++) {
@@ -5717,9 +5780,23 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p)
        if (!netif_running(dev))
                return 0;
 
-       spin_lock_bh(&tp->lock);
-       __tg3_set_mac_addr(tp);
-       spin_unlock_bh(&tp->lock);
+       if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
+               /* Reset chip so that ASF can re-init any MAC addresses it
+                * needs.
+                */
+               tg3_netif_stop(tp);
+               tg3_full_lock(tp, 1);
+
+               tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
+               tg3_init_hw(tp, 0);
+
+               tg3_netif_start(tp);
+               tg3_full_unlock(tp);
+       } else {
+               spin_lock_bh(&tp->lock);
+               __tg3_set_mac_addr(tp);
+               spin_unlock_bh(&tp->lock);
+       }
 
        return 0;
 }
@@ -5769,7 +5846,7 @@ static void __tg3_set_coalesce(struct tg3 *tp, struct ethtool_coalesce *ec)
 }
 
 /* tp->lock is held. */
-static int tg3_reset_hw(struct tg3 *tp)
+static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 {
        u32 val, rdmac_mode;
        int i, err, limit;
@@ -5784,7 +5861,7 @@ static int tg3_reset_hw(struct tg3 *tp)
                tg3_abort_hw(tp, 1);
        }
 
-       if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)
+       if ((tp->tg3_flags2 & TG3_FLG2_MII_SERDES) && reset_phy)
                tg3_phy_reset(tp);
 
        err = tg3_chip_reset(tp);
@@ -5833,10 +5910,14 @@ static int tg3_reset_hw(struct tg3 *tp)
                          GRC_MODE_NO_TX_PHDR_CSUM |
                          GRC_MODE_NO_RX_PHDR_CSUM);
        tp->grc_mode |= GRC_MODE_HOST_SENDBDS;
-       if (tp->tg3_flags & TG3_FLAG_NO_TX_PSEUDO_CSUM)
-               tp->grc_mode |= GRC_MODE_NO_TX_PHDR_CSUM;
-       if (tp->tg3_flags & TG3_FLAG_NO_RX_PSEUDO_CSUM)
-               tp->grc_mode |= GRC_MODE_NO_RX_PHDR_CSUM;
+
+       /* Pseudo-header checksum is done by hardware logic and not
+        * the offload processers, so make the chip do the pseudo-
+        * header checksums on receive.  For transmit it is more
+        * convenient to do the pseudo-header checksum in software
+        * as Linux does that on transmit for us in all cases.
+        */
+       tp->grc_mode |= GRC_MODE_NO_TX_PHDR_CSUM;
 
        tw32(GRC_MODE,
             tp->grc_mode |
@@ -6321,7 +6402,7 @@ static int tg3_reset_hw(struct tg3 *tp)
                tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
        }
 
-       err = tg3_setup_phy(tp, 1);
+       err = tg3_setup_phy(tp, reset_phy);
        if (err)
                return err;
 
@@ -6394,7 +6475,7 @@ static int tg3_reset_hw(struct tg3 *tp)
 /* Called at device open time to get the chip ready for
  * packet processing.  Invoked with tp->lock held.
  */
-static int tg3_init_hw(struct tg3 *tp)
+static int tg3_init_hw(struct tg3 *tp, int reset_phy)
 {
        int err;
 
@@ -6407,7 +6488,7 @@ static int tg3_init_hw(struct tg3 *tp)
 
        tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0);
 
-       err = tg3_reset_hw(tp);
+       err = tg3_reset_hw(tp, reset_phy);
 
 out:
        return err;
@@ -6455,6 +6536,10 @@ static void tg3_periodic_fetch_stats(struct tg3 *tp)
        TG3_STAT_ADD32(&sp->rx_frame_too_long_errors, MAC_RX_STATS_FRAME_TOO_LONG);
        TG3_STAT_ADD32(&sp->rx_jabbers, MAC_RX_STATS_JABBERS);
        TG3_STAT_ADD32(&sp->rx_undersize_packets, MAC_RX_STATS_UNDERSIZE);
+
+       TG3_STAT_ADD32(&sp->rxbds_empty, RCVLPC_NO_RCV_BD_CNT);
+       TG3_STAT_ADD32(&sp->rx_discards, RCVLPC_IN_DISCARDS_CNT);
+       TG3_STAT_ADD32(&sp->rx_errors, RCVLPC_IN_ERRORS_CNT);
 }
 
 static void tg3_timer(unsigned long __opaque)
@@ -6540,11 +6625,11 @@ static void tg3_timer(unsigned long __opaque)
                if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
                        u32 val;
 
-                       tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_MBOX,
-                                          FWCMD_NICDRV_ALIVE2);
-                       tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4);
+                       tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX,
+                                     FWCMD_NICDRV_ALIVE2);
+                       tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4);
                        /* 5 seconds timeout */
-                       tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5);
+                       tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5);
                        val = tr32(GRC_RX_CPU_EVENT);
                        val |= (1 << 14);
                        tw32(GRC_RX_CPU_EVENT, val);
@@ -6677,7 +6762,7 @@ static int tg3_test_msi(struct tg3 *tp)
        tg3_full_lock(tp, 1);
 
        tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
-       err = tg3_init_hw(tp);
+       err = tg3_init_hw(tp, 1);
 
        tg3_full_unlock(tp);
 
@@ -6742,7 +6827,7 @@ static int tg3_open(struct net_device *dev)
 
        tg3_full_lock(tp, 0);
 
-       err = tg3_init_hw(tp);
+       err = tg3_init_hw(tp, 1);
        if (err) {
                tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
                tg3_free_rings(tp);
@@ -7620,21 +7705,23 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                cmd->supported |= (SUPPORTED_1000baseT_Half |
                                   SUPPORTED_1000baseT_Full);
 
-       if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES))
+       if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)) {
                cmd->supported |= (SUPPORTED_100baseT_Half |
                                  SUPPORTED_100baseT_Full |
                                  SUPPORTED_10baseT_Half |
                                  SUPPORTED_10baseT_Full |
                                  SUPPORTED_MII);
-       else
+               cmd->port = PORT_TP;
+       } else {
                cmd->supported |= SUPPORTED_FIBRE;
+               cmd->port = PORT_FIBRE;
+       }
   
        cmd->advertising = tp->link_config.advertising;
        if (netif_running(dev)) {
                cmd->speed = tp->link_config.active_speed;
                cmd->duplex = tp->link_config.active_duplex;
        }
-       cmd->port = 0;
        cmd->phy_address = PHY_ADDR;
        cmd->transceiver = 0;
        cmd->autoneg = tp->link_config.autoneg;
@@ -7833,7 +7920,7 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e
 
        if (netif_running(dev)) {
                tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
-               tg3_init_hw(tp);
+               tg3_init_hw(tp, 1);
                tg3_netif_start(tp);
        }
 
@@ -7878,7 +7965,7 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam
 
        if (netif_running(dev)) {
                tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
-               tg3_init_hw(tp);
+               tg3_init_hw(tp, 1);
                tg3_netif_start(tp);
        }
 
@@ -8039,9 +8126,13 @@ static int tg3_test_nvram(struct tg3 *tp)
                for (i = 0; i < size; i++)
                        csum8 += buf8[i];
 
-               if (csum8 == 0)
-                       return 0;
-               return -EIO;
+               if (csum8 == 0) {
+                       err = 0;
+                       goto out;
+               }
+
+               err = -EIO;
+               goto out;
        }
 
        /* Bootstrap checksum at offset 0x10 */
@@ -8417,6 +8508,9 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
 
        tx_len = 1514;
        skb = dev_alloc_skb(tx_len);
+       if (!skb)
+               return -ENOMEM;
+
        tx_data = skb_put(skb, tx_len);
        memcpy(tx_data, tp->dev->dev_addr, 6);
        memset(tx_data + 6, 0x0, 8);
@@ -8512,7 +8606,7 @@ static int tg3_test_loopback(struct tg3 *tp)
        if (!netif_running(tp->dev))
                return TG3_LOOPBACK_FAILED;
 
-       tg3_reset_hw(tp);
+       tg3_reset_hw(tp, 1);
 
        if (tg3_run_loopback(tp, TG3_MAC_LOOPBACK))
                err |= TG3_MAC_LOOPBACK_FAILED;
@@ -8586,7 +8680,7 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
                tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
                if (netif_running(dev)) {
                        tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
-                       tg3_init_hw(tp);
+                       tg3_init_hw(tp, 1);
                        tg3_netif_start(tp);
                }
 
@@ -9029,9 +9123,6 @@ static void __devinit tg3_nvram_init(struct tg3 *tp)
 {
        int j;
 
-       if (tp->tg3_flags2 & TG3_FLG2_SUN_570X)
-               return;
-
        tw32_f(GRC_EEPROM_ADDR,
             (EEPROM_ADDR_FSM_RESET |
              (EEPROM_DEFAULT_CLOCK_PERIOD <<
@@ -9164,11 +9255,6 @@ static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val)
 {
        int ret;
 
-       if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) {
-               printk(KERN_ERR PFX "Attempt to do nvram_read on Sun 570X\n");
-               return -EINVAL;
-       }
-
        if (!(tp->tg3_flags & TG3_FLAG_NVRAM))
                return tg3_nvram_read_using_eeprom(tp, offset, val);
 
@@ -9367,7 +9453,7 @@ static int tg3_nvram_write_block_buffered(struct tg3 *tp, u32 offset, u32 len,
 
                if ((page_off == 0) || (i == 0))
                        nvram_cmd |= NVRAM_CMD_FIRST;
-               else if (page_off == (tp->nvram_pagesize - 4))
+               if (page_off == (tp->nvram_pagesize - 4))
                        nvram_cmd |= NVRAM_CMD_LAST;
 
                if (i == (len - 4))
@@ -9401,11 +9487,6 @@ static int tg3_nvram_write_block(struct tg3 *tp, u32 offset, u32 len, u8 *buf)
 {
        int ret;
 
-       if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) {
-               printk(KERN_ERR PFX "Attempt to do nvram_write on Sun 570X\n");
-               return -EINVAL;
-       }
-
        if (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) {
                tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl &
                       ~GRC_LCLCTRL_GPIO_OUTPUT1);
@@ -9532,12 +9613,19 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
        pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL,
                               tp->misc_host_ctrl);
 
+       /* The memory arbiter has to be enabled in order for SRAM accesses
+        * to succeed.  Normally on powerup the tg3 chip firmware will make
+        * sure it is enabled, but other entities such as system netboot
+        * code might disable it.
+        */
+       val = tr32(MEMARB_MODE);
+       tw32(MEMARB_MODE, val | MEMARB_MODE_ENABLE);
+
        tp->phy_id = PHY_ID_INVALID;
        tp->led_ctrl = LED_CTRL_MODE_PHY_1;
 
-       /* Do not even try poking around in here on Sun parts.  */
-       if (tp->tg3_flags2 & TG3_FLG2_SUN_570X)
-               return;
+       /* Assume an onboard device by default.  */
+       tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT;
 
        tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val);
        if (val == NIC_SRAM_DATA_SIG_MAGIC) {
@@ -9635,10 +9723,10 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
                    tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL)
                        tp->led_ctrl = LED_CTRL_MODE_PHY_2;
 
-               if ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700) &&
-                   (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) &&
-                   (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP))
+               if (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP)
                        tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT;
+               else
+                       tp->tg3_flags &= ~TG3_FLAG_EEPROM_WRITE_PROT;
 
                if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) {
                        tp->tg3_flags |= TG3_FLAG_ENABLE_ASF;
@@ -9787,16 +9875,8 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
        int i;
        u32 magic;
 
-       if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) {
-               /* Sun decided not to put the necessary bits in the
-                * NVRAM of their onboard tg3 parts :(
-                */
-               strcpy(tp->board_part_number, "Sun 570X");
-               return;
-       }
-
        if (tg3_nvram_read_swab(tp, 0x0, &magic))
-               return;
+               goto out_not_found;
 
        if (magic == TG3_EEPROM_MAGIC) {
                for (i = 0; i < 256; i += 4) {
@@ -9827,6 +9907,9 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
                                        break;
                                msleep(1);
                        }
+                       if (!(tmp16 & 0x8000))
+                               goto out_not_found;
+
                        pci_read_config_dword(tp->pdev, vpd_cap + PCI_VPD_DATA,
                                              &tmp);
                        tmp = cpu_to_le32(tmp);
@@ -9918,37 +10001,6 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp)
        }
 }
 
-#ifdef CONFIG_SPARC64
-static int __devinit tg3_is_sun_570X(struct tg3 *tp)
-{
-       struct pci_dev *pdev = tp->pdev;
-       struct pcidev_cookie *pcp = pdev->sysdata;
-
-       if (pcp != NULL) {
-               int node = pcp->prom_node;
-               u32 venid;
-               int err;
-
-               err = prom_getproperty(node, "subsystem-vendor-id",
-                                      (char *) &venid, sizeof(venid));
-               if (err == 0 || err == -1)
-                       return 0;
-               if (venid == PCI_VENDOR_ID_SUN)
-                       return 1;
-
-               /* TG3 chips onboard the SunBlade-2500 don't have the
-                * subsystem-vendor-id set to PCI_VENDOR_ID_SUN but they
-                * are distinguishable from non-Sun variants by being
-                * named "network" by the firmware.  Non-Sun cards will
-                * show up as being named "ethernet".
-                */
-               if (!strcmp(pcp->prom_name, "network"))
-                       return 1;
-       }
-       return 0;
-}
-#endif
-
 static int __devinit tg3_get_invariants(struct tg3 *tp)
 {
        static struct pci_device_id write_reorder_chipsets[] = {
@@ -9965,11 +10017,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        u16 pci_cmd;
        int err;
 
-#ifdef CONFIG_SPARC64
-       if (tg3_is_sun_570X(tp))
-               tp->tg3_flags2 |= TG3_FLG2_SUN_570X;
-#endif
-
        /* Force memory write invalidate off.  If we leave it on,
         * then on 5700_BX chips we have to enable a workaround.
         * The workaround is to set the TG3PCI_DMA_RW_CTRL boundary
@@ -10262,6 +10309,12 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd);
        }
 
+       if (tp->write32 == tg3_write_indirect_reg32 ||
+           ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) &&
+            (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
+             GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)))
+               tp->tg3_flags |= TG3_FLAG_SRAM_USE_CONFIG;
+
        /* Get eeprom hw config before calling tg3_set_power_state().
         * In particular, the TG3_FLAG_EEPROM_WRITE_PROT flag must be
         * determined before calling tg3_set_power_state() so that
@@ -10304,15 +10357,6 @@ 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;
 
-       /* Pseudo-header checksum is done by hardware logic and not
-        * the offload processers, so make the chip do the pseudo-
-        * header checksums on receive.  For transmit it is more
-        * convenient to do the pseudo-header checksum in software
-        * as Linux does that on transmit for us in all cases.
-        */
-       tp->tg3_flags |= TG3_FLAG_NO_TX_PSEUDO_CSUM;
-       tp->tg3_flags &= ~TG3_FLAG_NO_RX_PSEUDO_CSUM;
-
        /* Derive initial jumbo mode from MTU assigned in
         * ether_setup() via the alloc_etherdev() call
         */
@@ -10344,10 +10388,13 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        if (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0)
                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_5755) &&
-           (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5787))
-               tp->tg3_flags2 |= TG3_FLG2_PHY_BER_BUG;
+       if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
+               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
+                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
+                       tp->tg3_flags2 |= TG3_FLG2_PHY_JITTER_BUG;
+               else
+                       tp->tg3_flags2 |= TG3_FLG2_PHY_BER_BUG;
+       }
 
        tp->coalesce_mode = 0;
        if (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_AX &&
@@ -10546,8 +10593,7 @@ static int __devinit tg3_get_device_address(struct tg3 *tp)
 #endif
 
        mac_offset = 0x7c;
-       if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 &&
-            !(tp->tg3_flags & TG3_FLG2_SUN_570X)) ||
+       if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) ||
            (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
                if (tr32(TG3PCI_DUAL_MAC_CTRL) & DUAL_MAC_CTRL_ID)
                        mac_offset = 0xcc;
@@ -10574,8 +10620,7 @@ static int __devinit tg3_get_device_address(struct tg3 *tp)
        }
        if (!addr_ok) {
                /* Next, try NVRAM. */
-               if (!(tp->tg3_flags & TG3_FLG2_SUN_570X) &&
-                   !tg3_nvram_read(tp, mac_offset + 0, &hi) &&
+               if (!tg3_nvram_read(tp, mac_offset + 0, &hi) &&
                    !tg3_nvram_read(tp, mac_offset + 4, &lo)) {
                        dev->dev_addr[0] = ((hi >> 16) & 0xff);
                        dev->dev_addr[1] = ((hi >> 24) & 0xff);
@@ -11560,7 +11605,7 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
                tg3_full_lock(tp, 0);
 
                tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
-               tg3_init_hw(tp);
+               tg3_init_hw(tp, 1);
 
                tp->timer.expires = jiffies + tp->timer_offset;
                add_timer(&tp->timer);
@@ -11594,7 +11639,7 @@ static int tg3_resume(struct pci_dev *pdev)
        tg3_full_lock(tp, 0);
 
        tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
-       tg3_init_hw(tp);
+       tg3_init_hw(tp, 1);
 
        tp->timer.expires = jiffies + tp->timer_offset;
        add_timer(&tp->timer);