diff options
Diffstat (limited to 'openvz-sources/022.072-r1/5108_linux-2.6.8.1-tg3-3.27.rh.patch')
-rw-r--r-- | openvz-sources/022.072-r1/5108_linux-2.6.8.1-tg3-3.27.rh.patch | 4631 |
1 files changed, 0 insertions, 4631 deletions
diff --git a/openvz-sources/022.072-r1/5108_linux-2.6.8.1-tg3-3.27.rh.patch b/openvz-sources/022.072-r1/5108_linux-2.6.8.1-tg3-3.27.rh.patch deleted file mode 100644 index d5146ab..0000000 --- a/openvz-sources/022.072-r1/5108_linux-2.6.8.1-tg3-3.27.rh.patch +++ /dev/null @@ -1,4631 +0,0 @@ ---- linux-2.6.8.1-t043-libata-update//drivers/net/tg3.c 2005-10-20 17:56:53.000000000 +0400 -+++ rhel4u2//drivers/net/tg3.c 2005-10-19 11:47:13.000000000 +0400 -@@ -4,12 +4,16 @@ - * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com) - * Copyright (C) 2001, 2002, 2003 Jeff Garzik (jgarzik@pobox.com) - * Copyright (C) 2004 Sun Microsystems Inc. -+ * Copyright (C) 2005 Broadcom Corporation. -+ * -+ * Firmware is: -+ * Copyright (C) 2000-2003 Broadcom Corporation. - */ - - #include <linux/config.h> - - #include <linux/module.h> -- -+#include <linux/moduleparam.h> - #include <linux/kernel.h> - #include <linux/types.h> - #include <linux/compiler.h> -@@ -53,12 +57,13 @@ - #define TG3_TSO_SUPPORT 0 - #endif - -+#include "tg3_compat.h" - #include "tg3.h" - - #define DRV_MODULE_NAME "tg3" - #define PFX DRV_MODULE_NAME ": " --#define DRV_MODULE_VERSION "3.8" --#define DRV_MODULE_RELDATE "July 14, 2004" -+#define DRV_MODULE_VERSION "3.27-rh" -+#define DRV_MODULE_RELDATE "May 5, 2005" - - #define TG3_DEF_MAC_MODE 0 - #define TG3_DEF_RX_MODE 0 -@@ -81,8 +86,7 @@ - /* hardware minimum and maximum for a single frame's data payload */ - #define TG3_MIN_MTU 60 - #define TG3_MAX_MTU(tp) \ -- ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705 && \ -- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750) ? 9000 : 1500) -+ (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ? 9000 : 1500) - - /* These numbers seem to be hard coded in the NIC firmware somehow. - * You can't change the ring sizes, but you can change where you place -@@ -100,9 +104,7 @@ - * replace things like '% foo' with '& (foo - 1)'. - */ - #define TG3_RX_RCB_RING_SIZE(tp) \ -- ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 || \ -- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) ? \ -- 512 : 1024) -+ ((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ? 512 : 1024) - - #define TG3_TX_RING_SIZE 512 - #define TG3_DEF_TX_RING_PENDING (TG3_TX_RING_SIZE - 1) -@@ -138,10 +140,11 @@ static char version[] __devinitdata = - MODULE_AUTHOR("David S. Miller (davem@redhat.com) and Jeff Garzik (jgarzik@pobox.com)"); - MODULE_DESCRIPTION("Broadcom Tigon3 ethernet driver"); - MODULE_LICENSE("GPL"); --MODULE_PARM(tg3_debug, "i"); --MODULE_PARM_DESC(tg3_debug, "Tigon3 bitmapped debugging message enable value"); -+MODULE_VERSION(DRV_MODULE_VERSION); - - static int tg3_debug = -1; /* -1 == use TG3_DEF_MSG_ENABLE as value */ -+module_param(tg3_debug, int, 0); -+MODULE_PARM_DESC(tg3_debug, "Tigon3 bitmapped debugging message enable value"); - - static struct pci_device_id tg3_pci_tbl[] = { - { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5700, -@@ -202,6 +205,16 @@ 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_5751F, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, -+ { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5752, -+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, -+ { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5753, -+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, -+ { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5753M, -+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, -+ { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5753F, -+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, -+ { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5781, -+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, - { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, - { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX, -@@ -221,8 +234,8 @@ static struct pci_device_id tg3_pci_tbl[ - - MODULE_DEVICE_TABLE(pci, tg3_pci_tbl); - --struct { -- char string[ETH_GSTRING_LEN]; -+static struct { -+ const char string[ETH_GSTRING_LEN]; - } ethtool_stats_keys[TG3_NUM_STATS] = { - { "rx_octets" }, - { "rx_fragments" }, -@@ -328,7 +341,7 @@ static void _tw32_flush(struct tg3 *tp, - pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val); - spin_unlock_irqrestore(&tp->indirect_lock, flags); - } else { -- unsigned long dest = tp->regs + off; -+ void __iomem *dest = tp->regs + off; - writel(val, dest); - readl(dest); /* always flush PCI write */ - } -@@ -336,7 +349,7 @@ static void _tw32_flush(struct tg3 *tp, - - static inline void _tw32_rx_mbox(struct tg3 *tp, u32 off, u32 val) - { -- unsigned long mbox = tp->regs + off; -+ void __iomem *mbox = tp->regs + off; - writel(val, mbox); - if (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) - readl(mbox); -@@ -344,7 +357,7 @@ static inline void _tw32_rx_mbox(struct - - static inline void _tw32_tx_mbox(struct tg3 *tp, u32 off, u32 val) - { -- unsigned long mbox = tp->regs + off; -+ void __iomem *mbox = tp->regs + off; - writel(val, mbox); - if (tp->tg3_flags & TG3_FLAG_TXD_MBOX_HWBUG) - writel(val, mbox); -@@ -414,6 +427,43 @@ static void tg3_enable_ints(struct tg3 * - tg3_cond_int(tp); - } - -+static inline unsigned int tg3_has_work(struct tg3 *tp) -+{ -+ struct tg3_hw_status *sblk = tp->hw_status; -+ unsigned int work_exists = 0; -+ -+ /* check for phy events */ -+ if (!(tp->tg3_flags & -+ (TG3_FLAG_USE_LINKCHG_REG | -+ TG3_FLAG_POLL_SERDES))) { -+ if (sblk->status & SD_STATUS_LINK_CHG) -+ work_exists = 1; -+ } -+ /* check for RX/TX work to do */ -+ if (sblk->idx[0].tx_consumer != tp->tx_cons || -+ sblk->idx[0].rx_producer != tp->rx_rcb_ptr) -+ work_exists = 1; -+ -+ return work_exists; -+} -+ -+/* tg3_restart_ints -+ * similar to tg3_enable_ints, but it accurately determines whether there -+ * is new work pending and can return without flushing the PIO write -+ * which reenables interrupts -+ */ -+static void tg3_restart_ints(struct tg3 *tp) -+{ -+ tw32(TG3PCI_MISC_HOST_CTRL, -+ (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT)); -+ tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000000); -+ mmiowb(); -+ -+ if (tg3_has_work(tp)) -+ tw32(HOSTCC_MODE, tp->coalesce_mode | -+ (HOSTCC_MODE_ENABLE | HOSTCC_MODE_NOW)); -+} -+ - static inline void tg3_netif_stop(struct tg3 *tp) - { - netif_poll_disable(tp->dev); -@@ -442,9 +492,13 @@ static void tg3_switch_clocks(struct tg3 - 0x1f); - tp->pci_clock_ctrl = clock_ctrl; - -- if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705 && -- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750 && -- (orig_clock_ctrl & CLOCK_CTRL_44MHZ_CORE) != 0) { -+ if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) { -+ if (orig_clock_ctrl & CLOCK_CTRL_625_CORE) { -+ tw32_f(TG3PCI_CLOCK_CTRL, -+ clock_ctrl | CLOCK_CTRL_625_CORE); -+ udelay(40); -+ } -+ } else if ((orig_clock_ctrl & CLOCK_CTRL_44MHZ_CORE) != 0) { - tw32_f(TG3PCI_CLOCK_CTRL, - clock_ctrl | - (CLOCK_CTRL_44MHZ_CORE | CLOCK_CTRL_ALTCLK)); -@@ -462,7 +516,8 @@ static void tg3_switch_clocks(struct tg3 - static int tg3_readphy(struct tg3 *tp, int reg, u32 *val) - { - u32 frame_val; -- int loops, ret; -+ unsigned int loops; -+ int ret; - - if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) { - tw32_f(MAC_MI_MODE, -@@ -470,7 +525,7 @@ static int tg3_readphy(struct tg3 *tp, i - udelay(80); - } - -- *val = 0xffffffff; -+ *val = 0x0; - - frame_val = ((PHY_ADDR << MI_COM_PHY_ADDR_SHIFT) & - MI_COM_PHY_ADDR_MASK); -@@ -481,7 +536,7 @@ static int tg3_readphy(struct tg3 *tp, i - tw32_f(MAC_MI_COM, frame_val); - - loops = PHY_BUSY_LOOPS; -- while (loops-- > 0) { -+ while (loops != 0) { - udelay(10); - frame_val = tr32(MAC_MI_COM); - -@@ -490,10 +545,11 @@ static int tg3_readphy(struct tg3 *tp, i - frame_val = tr32(MAC_MI_COM); - break; - } -+ loops -= 1; - } - - ret = -EBUSY; -- if (loops > 0) { -+ if (loops != 0) { - *val = frame_val & MI_COM_DATA_MASK; - ret = 0; - } -@@ -509,7 +565,8 @@ static int tg3_readphy(struct tg3 *tp, i - static int tg3_writephy(struct tg3 *tp, int reg, u32 val) - { - u32 frame_val; -- int loops, ret; -+ unsigned int loops; -+ int ret; - - if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) { - tw32_f(MAC_MI_MODE, -@@ -527,7 +584,7 @@ static int tg3_writephy(struct tg3 *tp, - tw32_f(MAC_MI_COM, frame_val); - - loops = PHY_BUSY_LOOPS; -- while (loops-- > 0) { -+ while (loops != 0) { - udelay(10); - frame_val = tr32(MAC_MI_COM); - if ((frame_val & MI_COM_BUSY) == 0) { -@@ -535,10 +592,11 @@ static int tg3_writephy(struct tg3 *tp, - frame_val = tr32(MAC_MI_COM); - break; - } -+ loops -= 1; - } - - ret = -EBUSY; -- if (loops > 0) -+ if (loops != 0) - ret = 0; - - if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) { -@@ -556,9 +614,10 @@ static void tg3_phy_set_wirespeed(struct - if (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) - return; - -- tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x7007); -- tg3_readphy(tp, MII_TG3_AUX_CTRL, &val); -- tg3_writephy(tp, MII_TG3_AUX_CTRL, (val | (1 << 15) | (1 << 4))); -+ if (!tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x7007) && -+ !tg3_readphy(tp, MII_TG3_AUX_CTRL, &val)) -+ tg3_writephy(tp, MII_TG3_AUX_CTRL, -+ (val | (1 << 15) | (1 << 4))); - } - - static int tg3_bmcr_reset(struct tg3 *tp) -@@ -599,9 +658,10 @@ static int tg3_wait_macro_done(struct tg - while (limit--) { - u32 tmp32; - -- tg3_readphy(tp, 0x16, &tmp32); -- if ((tmp32 & 0x1000) == 0) -- break; -+ if (!tg3_readphy(tp, 0x16, &tmp32)) { -+ if ((tmp32 & 0x1000) == 0) -+ break; -+ } - } - if (limit <= 0) - return -EBUSY; -@@ -653,9 +713,9 @@ static int tg3_phy_write_and_check_testp - for (i = 0; i < 6; i += 2) { - u32 low, high; - -- tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &low); -- tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &high); -- if (tg3_wait_macro_done(tp)) { -+ if (tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &low) || -+ tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &high) || -+ tg3_wait_macro_done(tp)) { - *resetp = 1; - return -EBUSY; - } -@@ -711,7 +771,9 @@ static int tg3_phy_reset_5703_4_5(struct - } - - /* Disable transmitter and interrupt. */ -- tg3_readphy(tp, MII_TG3_EXT_CTRL, ®32); -+ if (tg3_readphy(tp, MII_TG3_EXT_CTRL, ®32)) -+ continue; -+ - reg32 |= 0x3000; - tg3_writephy(tp, MII_TG3_EXT_CTRL, reg32); - -@@ -720,7 +782,9 @@ static int tg3_phy_reset_5703_4_5(struct - BMCR_FULLDPLX | TG3_BMCR_SPEED1000); - - /* Set to master mode. */ -- tg3_readphy(tp, MII_TG3_CTRL, &phy9_orig); -+ if (tg3_readphy(tp, MII_TG3_CTRL, &phy9_orig)) -+ continue; -+ - tg3_writephy(tp, MII_TG3_CTRL, - (MII_TG3_CTRL_AS_MASTER | - MII_TG3_CTRL_ENABLE_AS_MASTER)); -@@ -758,9 +822,11 @@ static int tg3_phy_reset_5703_4_5(struct - - tg3_writephy(tp, MII_TG3_CTRL, phy9_orig); - -- tg3_readphy(tp, MII_TG3_EXT_CTRL, ®32); -- reg32 &= ~0x3000; -- tg3_writephy(tp, MII_TG3_EXT_CTRL, reg32); -+ if (!tg3_readphy(tp, MII_TG3_EXT_CTRL, ®32)) { -+ reg32 &= ~0x3000; -+ tg3_writephy(tp, MII_TG3_EXT_CTRL, reg32); -+ } else if (!err) -+ err = -EBUSY; - - return err; - } -@@ -819,15 +885,26 @@ out: - if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) { - /* Cannot do read-modify-write on 5401 */ - tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4c20); -- } else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705 && -- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750) { -+ } else if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { - u32 phy_reg; - - /* Set bit 14 with read-modify-write to preserve other bits */ -- tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0007); -- tg3_readphy(tp, MII_TG3_AUX_CTRL, &phy_reg); -- tg3_writephy(tp, MII_TG3_AUX_CTRL, phy_reg | 0x4000); -+ if (!tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0007) && -+ !tg3_readphy(tp, MII_TG3_AUX_CTRL, &phy_reg)) -+ tg3_writephy(tp, MII_TG3_AUX_CTRL, phy_reg | 0x4000); -+ } -+ -+ /* Set phy register 0x10 bit 0 to high fifo elasticity to support -+ * jumbo frames transmission. -+ */ -+ if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { -+ u32 phy_reg; -+ -+ if (!tg3_readphy(tp, MII_TG3_EXT_CTRL, &phy_reg)) -+ tg3_writephy(tp, MII_TG3_EXT_CTRL, -+ phy_reg | MII_TG3_EXT_CTRL_FIFO_ELASTIC); - } -+ - tg3_phy_set_wirespeed(tp); - return 0; - } -@@ -858,34 +935,42 @@ static void tg3_frob_aux_power(struct tg - GRC_LCLCTRL_GPIO_OUTPUT1)); - udelay(100); - } else { -+ u32 no_gpio2; -+ u32 grc_local_ctrl; -+ - if (tp_peer != tp && - (tp_peer->tg3_flags & TG3_FLAG_INIT_COMPLETE) != 0) - return; - -+ /* On 5753 and variants, GPIO2 cannot be used. */ -+ no_gpio2 = tp->nic_sram_data_cfg & -+ NIC_SRAM_DATA_CFG_NO_GPIO2; -+ -+ grc_local_ctrl = GRC_LCLCTRL_GPIO_OE0 | -+ GRC_LCLCTRL_GPIO_OE1 | -+ GRC_LCLCTRL_GPIO_OE2 | -+ GRC_LCLCTRL_GPIO_OUTPUT1 | -+ GRC_LCLCTRL_GPIO_OUTPUT2; -+ if (no_gpio2) { -+ grc_local_ctrl &= ~(GRC_LCLCTRL_GPIO_OE2 | -+ GRC_LCLCTRL_GPIO_OUTPUT2); -+ } - tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | -- (GRC_LCLCTRL_GPIO_OE0 | -- GRC_LCLCTRL_GPIO_OE1 | -- GRC_LCLCTRL_GPIO_OE2 | -- GRC_LCLCTRL_GPIO_OUTPUT1 | -- GRC_LCLCTRL_GPIO_OUTPUT2)); -+ grc_local_ctrl); - udelay(100); - -- tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | -- (GRC_LCLCTRL_GPIO_OE0 | -- GRC_LCLCTRL_GPIO_OE1 | -- GRC_LCLCTRL_GPIO_OE2 | -- GRC_LCLCTRL_GPIO_OUTPUT0 | -- GRC_LCLCTRL_GPIO_OUTPUT1 | -- GRC_LCLCTRL_GPIO_OUTPUT2)); -- udelay(100); -+ grc_local_ctrl |= GRC_LCLCTRL_GPIO_OUTPUT0; - - tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | -- (GRC_LCLCTRL_GPIO_OE0 | -- GRC_LCLCTRL_GPIO_OE1 | -- GRC_LCLCTRL_GPIO_OE2 | -- GRC_LCLCTRL_GPIO_OUTPUT0 | -- GRC_LCLCTRL_GPIO_OUTPUT1)); -+ grc_local_ctrl); - udelay(100); -+ -+ if (!no_gpio2) { -+ grc_local_ctrl &= ~GRC_LCLCTRL_GPIO_OUTPUT2; -+ tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | -+ grc_local_ctrl); -+ udelay(100); -+ } - } - } else { - if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 && -@@ -918,6 +1003,7 @@ static int tg3_setup_phy(struct tg3 *, i - #define RESET_KIND_SUSPEND 2 - - static void tg3_write_sig_post_reset(struct tg3 *, int); -+static int tg3_halt_cpu(struct tg3 *, u32); - - static int tg3_set_power_state(struct tg3 *tp, int state) - { -@@ -943,8 +1029,13 @@ static int tg3_set_power_state(struct tg - pci_write_config_word(tp->pdev, - pm + PCI_PM_CTRL, - power_control); -- tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl); -- udelay(100); -+ udelay(100); /* Delay after power state change */ -+ -+ /* Switch out of Vaux if it is not a LOM */ -+ if (!(tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT)) { -+ tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl); -+ udelay(100); -+ } - - return 0; - -@@ -980,7 +1071,7 @@ static int tg3_set_power_state(struct tg - tp->link_config.orig_autoneg = tp->link_config.autoneg; - } - -- if (tp->phy_id != PHY_ID_SERDES) { -+ if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) { - tp->link_config.speed = SPEED_10; - tp->link_config.duplex = DUPLEX_HALF; - tp->link_config.autoneg = AUTONEG_ENABLE; -@@ -992,7 +1083,7 @@ static int tg3_set_power_state(struct tg - if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE) { - u32 mac_mode; - -- if (tp->phy_id != PHY_ID_SERDES) { -+ if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) { - tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x5a); - udelay(40); - -@@ -1005,7 +1096,7 @@ static int tg3_set_power_state(struct tg - mac_mode = MAC_MODE_PORT_MODE_TBI; - } - -- if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750) -+ if (!(tp->tg3_flags2 & TG3_FLG2_5750_PLUS)) - tw32(MAC_LED_CTRL, tp->led_ctrl); - - if (((power_caps & PCI_PM_CAP_PME_D3cold) && -@@ -1032,7 +1123,7 @@ static int tg3_set_power_state(struct tg - CLOCK_CTRL_ALTCLK | - CLOCK_CTRL_PWRDOWN_PLL133); - udelay(40); -- } else if (!((GET_ASIC_REV(tp->pci_chip_rev_id) == 5750) && -+ } else if (!((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) && - (tp->tg3_flags & TG3_FLAG_ENABLE_ASF))) { - u32 newbits1, newbits2; - -@@ -1042,8 +1133,7 @@ static int tg3_set_power_state(struct tg - CLOCK_CTRL_TXCLK_DISABLE | - CLOCK_CTRL_ALTCLK); - newbits2 = newbits1 | CLOCK_CTRL_44MHZ_CORE; -- } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 || -- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) { -+ } else if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) { - newbits1 = CLOCK_CTRL_625_CORE; - newbits2 = newbits1 | CLOCK_CTRL_ALTCLK; - } else { -@@ -1057,8 +1147,7 @@ static int tg3_set_power_state(struct tg - tw32_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits2); - udelay(40); - -- if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705 && -- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750) { -+ if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { - u32 newbits3; - - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || -@@ -1078,8 +1167,20 @@ static int tg3_set_power_state(struct tg - - tg3_frob_aux_power(tp); - -+ /* Workaround for unstable PLL clock */ -+ if ((GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_AX) || -+ (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_BX)) { -+ u32 val = tr32(0x7d00); -+ -+ val &= ~((1 << 16) | (1 << 4) | (1 << 2) | (1 << 1) | 1); -+ tw32(0x7d00, val); -+ if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) -+ tg3_halt_cpu(tp, RX_CPU_BASE); -+ } -+ - /* 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); - -@@ -1114,29 +1215,33 @@ static void tg3_setup_flow_control(struc - u32 old_rx_mode = tp->rx_mode; - u32 old_tx_mode = tp->tx_mode; - -- if (local_adv & ADVERTISE_PAUSE_CAP) { -- if (local_adv & ADVERTISE_PAUSE_ASYM) { -- if (remote_adv & LPA_PAUSE_CAP) -- new_tg3_flags |= -- (TG3_FLAG_RX_PAUSE | -- TG3_FLAG_TX_PAUSE); -- else if (remote_adv & LPA_PAUSE_ASYM) -- new_tg3_flags |= -- (TG3_FLAG_RX_PAUSE); -- } else { -- if (remote_adv & LPA_PAUSE_CAP) -- new_tg3_flags |= -- (TG3_FLAG_RX_PAUSE | -- TG3_FLAG_TX_PAUSE); -+ if (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG) { -+ if (local_adv & ADVERTISE_PAUSE_CAP) { -+ if (local_adv & ADVERTISE_PAUSE_ASYM) { -+ if (remote_adv & LPA_PAUSE_CAP) -+ new_tg3_flags |= -+ (TG3_FLAG_RX_PAUSE | -+ TG3_FLAG_TX_PAUSE); -+ else if (remote_adv & LPA_PAUSE_ASYM) -+ new_tg3_flags |= -+ (TG3_FLAG_RX_PAUSE); -+ } else { -+ if (remote_adv & LPA_PAUSE_CAP) -+ new_tg3_flags |= -+ (TG3_FLAG_RX_PAUSE | -+ TG3_FLAG_TX_PAUSE); -+ } -+ } else if (local_adv & ADVERTISE_PAUSE_ASYM) { -+ if ((remote_adv & LPA_PAUSE_CAP) && -+ (remote_adv & LPA_PAUSE_ASYM)) -+ new_tg3_flags |= TG3_FLAG_TX_PAUSE; - } -- } else if (local_adv & ADVERTISE_PAUSE_ASYM) { -- if ((remote_adv & LPA_PAUSE_CAP) && -- (remote_adv & LPA_PAUSE_ASYM)) -- new_tg3_flags |= TG3_FLAG_TX_PAUSE; -- } - -- tp->tg3_flags &= ~(TG3_FLAG_RX_PAUSE | TG3_FLAG_TX_PAUSE); -- tp->tg3_flags |= new_tg3_flags; -+ tp->tg3_flags &= ~(TG3_FLAG_RX_PAUSE | TG3_FLAG_TX_PAUSE); -+ tp->tg3_flags |= new_tg3_flags; -+ } else { -+ new_tg3_flags = tp->tg3_flags; -+ } - - if (new_tg3_flags & TG3_FLAG_RX_PAUSE) - tp->rx_mode |= RX_MODE_FLOW_CTRL_ENABLE; -@@ -1197,7 +1302,7 @@ static void tg3_aux_stat_to_speed_duplex - }; - } - --static int tg3_phy_copper_begin(struct tg3 *tp) -+static void tg3_phy_copper_begin(struct tg3 *tp) - { - u32 new_adv; - int i; -@@ -1312,15 +1417,16 @@ static int tg3_phy_copper_begin(struct t - if (tp->link_config.duplex == DUPLEX_FULL) - bmcr |= BMCR_FULLDPLX; - -- tg3_readphy(tp, MII_BMCR, &orig_bmcr); -- if (bmcr != orig_bmcr) { -+ if (!tg3_readphy(tp, MII_BMCR, &orig_bmcr) && -+ (bmcr != orig_bmcr)) { - tg3_writephy(tp, MII_BMCR, BMCR_LOOPBACK); - for (i = 0; i < 1500; i++) { - u32 tmp; - - udelay(10); -- tg3_readphy(tp, MII_BMSR, &tmp); -- tg3_readphy(tp, MII_BMSR, &tmp); -+ if (tg3_readphy(tp, MII_BMSR, &tmp) || -+ tg3_readphy(tp, MII_BMSR, &tmp)) -+ continue; - if (!(tmp & BMSR_LSTATUS)) { - udelay(40); - break; -@@ -1333,8 +1439,6 @@ static int tg3_phy_copper_begin(struct t - tg3_writephy(tp, MII_BMCR, - BMCR_ANENABLE | BMCR_ANRESTART); - } -- -- return 0; - } - - static int tg3_init_5401phy_dsp(struct tg3 *tp) -@@ -1369,7 +1473,9 @@ static int tg3_copper_is_advertising_all - { - u32 adv_reg, all_mask; - -- tg3_readphy(tp, MII_ADVERTISE, &adv_reg); -+ if (tg3_readphy(tp, MII_ADVERTISE, &adv_reg)) -+ return 0; -+ - all_mask = (ADVERTISE_10HALF | ADVERTISE_10FULL | - ADVERTISE_100HALF | ADVERTISE_100FULL); - if ((adv_reg & all_mask) != all_mask) -@@ -1377,7 +1483,9 @@ static int tg3_copper_is_advertising_all - if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) { - u32 tg3_ctrl; - -- tg3_readphy(tp, MII_TG3_CTRL, &tg3_ctrl); -+ if (tg3_readphy(tp, MII_TG3_CTRL, &tg3_ctrl)) -+ return 0; -+ - all_mask = (MII_TG3_CTRL_ADV_1000_HALF | - MII_TG3_CTRL_ADV_1000_FULL); - if ((tg3_ctrl & all_mask) != all_mask) -@@ -1417,8 +1525,8 @@ static int tg3_setup_copper_phy(struct t - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) && - netif_carrier_ok(tp->dev)) { - tg3_readphy(tp, MII_BMSR, &bmsr); -- tg3_readphy(tp, MII_BMSR, &bmsr); -- if (!(bmsr & BMSR_LSTATUS)) -+ if (!tg3_readphy(tp, MII_BMSR, &bmsr) && -+ !(bmsr & BMSR_LSTATUS)) - force_reset = 1; - } - if (force_reset) -@@ -1426,9 +1534,8 @@ static int tg3_setup_copper_phy(struct t - - if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) { - tg3_readphy(tp, MII_BMSR, &bmsr); -- tg3_readphy(tp, MII_BMSR, &bmsr); -- -- if (!(tp->tg3_flags & TG3_FLAG_INIT_COMPLETE)) -+ if (tg3_readphy(tp, MII_BMSR, &bmsr) || -+ !(tp->tg3_flags & TG3_FLAG_INIT_COMPLETE)) - bmsr = 0; - - if (!(bmsr & BMSR_LSTATUS)) { -@@ -1439,8 +1546,8 @@ static int tg3_setup_copper_phy(struct t - tg3_readphy(tp, MII_BMSR, &bmsr); - for (i = 0; i < 1000; i++) { - udelay(10); -- tg3_readphy(tp, MII_BMSR, &bmsr); -- if (bmsr & BMSR_LSTATUS) { -+ if (!tg3_readphy(tp, MII_BMSR, &bmsr) && -+ (bmsr & BMSR_LSTATUS)) { - udelay(40); - break; - } -@@ -1487,11 +1594,23 @@ static int tg3_setup_copper_phy(struct t - current_speed = SPEED_INVALID; - current_duplex = DUPLEX_INVALID; - -+ if (tp->tg3_flags2 & TG3_FLG2_CAPACITIVE_COUPLING) { -+ u32 val; -+ -+ tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4007); -+ tg3_readphy(tp, MII_TG3_AUX_CTRL, &val); -+ if (!(val & (1 << 10))) { -+ val |= (1 << 10); -+ tg3_writephy(tp, MII_TG3_AUX_CTRL, val); -+ goto relink; -+ } -+ } -+ - bmsr = 0; - for (i = 0; i < 100; i++) { - tg3_readphy(tp, MII_BMSR, &bmsr); -- tg3_readphy(tp, MII_BMSR, &bmsr); -- if (bmsr & BMSR_LSTATUS) -+ if (!tg3_readphy(tp, MII_BMSR, &bmsr) && -+ (bmsr & BMSR_LSTATUS)) - break; - udelay(40); - } -@@ -1502,8 +1621,8 @@ static int tg3_setup_copper_phy(struct t - tg3_readphy(tp, MII_TG3_AUX_STAT, &aux_stat); - for (i = 0; i < 2000; i++) { - udelay(10); -- tg3_readphy(tp, MII_TG3_AUX_STAT, &aux_stat); -- if (aux_stat) -+ if (!tg3_readphy(tp, MII_TG3_AUX_STAT, &aux_stat) && -+ aux_stat) - break; - } - -@@ -1514,7 +1633,8 @@ static int tg3_setup_copper_phy(struct t - bmcr = 0; - for (i = 0; i < 200; i++) { - tg3_readphy(tp, MII_BMCR, &bmcr); -- tg3_readphy(tp, MII_BMCR, &bmcr); -+ if (tg3_readphy(tp, MII_BMCR, &bmcr)) -+ continue; - if (bmcr && bmcr != 0x7fff) - break; - udelay(10); -@@ -1551,10 +1671,13 @@ static int tg3_setup_copper_phy(struct t - (tp->link_config.autoneg == AUTONEG_ENABLE)) { - u32 local_adv, remote_adv; - -- tg3_readphy(tp, MII_ADVERTISE, &local_adv); -+ if (tg3_readphy(tp, MII_ADVERTISE, &local_adv)) -+ local_adv = 0; - local_adv &= (ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM); - -- tg3_readphy(tp, MII_LPA, &remote_adv); -+ if (tg3_readphy(tp, MII_LPA, &remote_adv)) -+ remote_adv = 0; -+ - remote_adv &= (LPA_PAUSE_CAP | LPA_PAUSE_ASYM); - - /* If we are not advertising full pause capability, -@@ -1566,15 +1689,15 @@ static int tg3_setup_copper_phy(struct t - tg3_setup_flow_control(tp, local_adv, remote_adv); - } - } -- -+relink: - if (current_link_up == 0) { - u32 tmp; - - tg3_phy_copper_begin(tp); - - tg3_readphy(tp, MII_BMSR, &tmp); -- tg3_readphy(tp, MII_BMSR, &tmp); -- if (tmp & BMSR_LSTATUS) -+ if (!tg3_readphy(tp, MII_BMSR, &tmp) && -+ (tmp & BMSR_LSTATUS)) - current_link_up = 1; - } - -@@ -1616,7 +1739,7 @@ static int tg3_setup_copper_phy(struct t - tw32_f(MAC_MODE, tp->mac_mode); - udelay(40); - -- if (tp->tg3_flags & (TG3_FLAG_USE_LINKCHG_REG | TG3_FLAG_POLL_SERDES)) { -+ if (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) { - /* Polled via timer. */ - tw32_f(MAC_EVENT, 0); - } else { -@@ -1965,261 +2088,399 @@ static int tg3_fiber_aneg_smachine(struc - static int fiber_autoneg(struct tg3 *tp, u32 *flags) - { - int res = 0; -+ struct tg3_fiber_aneginfo aninfo; -+ int status = ANEG_FAILED; -+ unsigned int tick; -+ u32 tmp; - -- if (tp->tg3_flags2 & TG3_FLG2_HW_AUTONEG) { -- u32 dig_status; -- -- dig_status = tr32(SG_DIG_STATUS); -- *flags = 0; -- if (dig_status & SG_DIG_PARTNER_ASYM_PAUSE) -- *flags |= MR_LP_ADV_ASYM_PAUSE; -- if (dig_status & SG_DIG_PARTNER_PAUSE_CAPABLE) -- *flags |= MR_LP_ADV_SYM_PAUSE; -- -- if ((dig_status & SG_DIG_AUTONEG_COMPLETE) && -- !(dig_status & (SG_DIG_AUTONEG_ERROR | -- SG_DIG_PARTNER_FAULT_MASK))) -- res = 1; -- } else { -- struct tg3_fiber_aneginfo aninfo; -- int status = ANEG_FAILED; -- unsigned int tick; -- u32 tmp; -- -- tw32_f(MAC_TX_AUTO_NEG, 0); -+ tw32_f(MAC_TX_AUTO_NEG, 0); - -- tmp = tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK; -- tw32_f(MAC_MODE, tmp | MAC_MODE_PORT_MODE_GMII); -- udelay(40); -+ tmp = tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK; -+ tw32_f(MAC_MODE, tmp | MAC_MODE_PORT_MODE_GMII); -+ udelay(40); - -- tw32_f(MAC_MODE, tp->mac_mode | MAC_MODE_SEND_CONFIGS); -- udelay(40); -+ tw32_f(MAC_MODE, tp->mac_mode | MAC_MODE_SEND_CONFIGS); -+ udelay(40); - -- memset(&aninfo, 0, sizeof(aninfo)); -- aninfo.flags |= MR_AN_ENABLE; -- aninfo.state = ANEG_STATE_UNKNOWN; -- aninfo.cur_time = 0; -- tick = 0; -- while (++tick < 195000) { -- status = tg3_fiber_aneg_smachine(tp, &aninfo); -- if (status == ANEG_DONE || status == ANEG_FAILED) -- break; -+ memset(&aninfo, 0, sizeof(aninfo)); -+ aninfo.flags |= MR_AN_ENABLE; -+ aninfo.state = ANEG_STATE_UNKNOWN; -+ aninfo.cur_time = 0; -+ tick = 0; -+ while (++tick < 195000) { -+ status = tg3_fiber_aneg_smachine(tp, &aninfo); -+ if (status == ANEG_DONE || status == ANEG_FAILED) -+ break; - -- udelay(1); -- } -+ udelay(1); -+ } - -- tp->mac_mode &= ~MAC_MODE_SEND_CONFIGS; -- tw32_f(MAC_MODE, tp->mac_mode); -- udelay(40); -+ tp->mac_mode &= ~MAC_MODE_SEND_CONFIGS; -+ tw32_f(MAC_MODE, tp->mac_mode); -+ udelay(40); - -- *flags = aninfo.flags; -+ *flags = aninfo.flags; - -- if (status == ANEG_DONE && -- (aninfo.flags & (MR_AN_COMPLETE | MR_LINK_OK | -- MR_LP_ADV_FULL_DUPLEX))) -- res = 1; -- } -+ if (status == ANEG_DONE && -+ (aninfo.flags & (MR_AN_COMPLETE | MR_LINK_OK | -+ MR_LP_ADV_FULL_DUPLEX))) -+ res = 1; - - return res; - } - --static int tg3_setup_fiber_phy(struct tg3 *tp, int force_reset) -+static void tg3_init_bcm8002(struct tg3 *tp) - { -- u32 orig_pause_cfg; -- u16 orig_active_speed; -- u8 orig_active_duplex; -- int current_link_up; -+ u32 mac_status = tr32(MAC_STATUS); - int i; - -- orig_pause_cfg = -- (tp->tg3_flags & (TG3_FLAG_RX_PAUSE | -- TG3_FLAG_TX_PAUSE)); -- orig_active_speed = tp->link_config.active_speed; -- orig_active_duplex = tp->link_config.active_duplex; -- -- tp->mac_mode &= ~(MAC_MODE_PORT_MODE_MASK | MAC_MODE_HALF_DUPLEX); -- tp->mac_mode |= MAC_MODE_PORT_MODE_TBI; -- tw32_f(MAC_MODE, tp->mac_mode); -- udelay(40); -+ /* Reset when initting first time or we have a link. */ -+ if ((tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) && -+ !(mac_status & MAC_STATUS_PCS_SYNCED)) -+ return; - -- if (tp->tg3_flags2 & TG3_FLG2_HW_AUTONEG) { -- /* Allow time for the hardware to auto-negotiate (195ms) */ -- unsigned int tick = 0; -+ /* Set PLL lock range. */ -+ tg3_writephy(tp, 0x16, 0x8007); - -- while (++tick < 195000) { -- if (tr32(SG_DIG_STATUS) & SG_DIG_AUTONEG_COMPLETE) -- break; -- udelay(1); -- } -- if (tick >= 195000) -- printk(KERN_INFO PFX "%s: HW autoneg failed !\n", -- tp->dev->name); -- } -+ /* SW reset */ -+ tg3_writephy(tp, MII_BMCR, BMCR_RESET); - -- /* Reset when initting first time or we have a link. */ -- if (!(tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) || -- (tr32(MAC_STATUS) & MAC_STATUS_PCS_SYNCED)) { -- /* Set PLL lock range. */ -- tg3_writephy(tp, 0x16, 0x8007); -- -- /* SW reset */ -- tg3_writephy(tp, MII_BMCR, BMCR_RESET); -- -- /* Wait for reset to complete. */ -- /* XXX schedule_timeout() ... */ -- for (i = 0; i < 500; i++) -- udelay(10); -+ /* Wait for reset to complete. */ -+ /* XXX schedule_timeout() ... */ -+ for (i = 0; i < 500; i++) -+ udelay(10); - -- /* Config mode; select PMA/Ch 1 regs. */ -- tg3_writephy(tp, 0x10, 0x8411); -+ /* Config mode; select PMA/Ch 1 regs. */ -+ tg3_writephy(tp, 0x10, 0x8411); - -- /* Enable auto-lock and comdet, select txclk for tx. */ -- tg3_writephy(tp, 0x11, 0x0a10); -+ /* Enable auto-lock and comdet, select txclk for tx. */ -+ tg3_writephy(tp, 0x11, 0x0a10); - -- tg3_writephy(tp, 0x18, 0x00a0); -- tg3_writephy(tp, 0x16, 0x41ff); -+ tg3_writephy(tp, 0x18, 0x00a0); -+ tg3_writephy(tp, 0x16, 0x41ff); - -- /* Assert and deassert POR. */ -- tg3_writephy(tp, 0x13, 0x0400); -- udelay(40); -- tg3_writephy(tp, 0x13, 0x0000); -+ /* Assert and deassert POR. */ -+ tg3_writephy(tp, 0x13, 0x0400); -+ udelay(40); -+ tg3_writephy(tp, 0x13, 0x0000); - -- tg3_writephy(tp, 0x11, 0x0a50); -- udelay(40); -- tg3_writephy(tp, 0x11, 0x0a10); -+ tg3_writephy(tp, 0x11, 0x0a50); -+ udelay(40); -+ tg3_writephy(tp, 0x11, 0x0a10); - -- /* Wait for signal to stabilize */ -- /* XXX schedule_timeout() ... */ -- for (i = 0; i < 15000; i++) -- udelay(10); -+ /* Wait for signal to stabilize */ -+ /* XXX schedule_timeout() ... */ -+ for (i = 0; i < 15000; i++) -+ udelay(10); - -- /* Deselect the channel register so we can read the PHYID -- * later. -- */ -- tg3_writephy(tp, 0x10, 0x8011); -- } -+ /* Deselect the channel register so we can read the PHYID -+ * later. -+ */ -+ tg3_writephy(tp, 0x10, 0x8011); -+} - -- /* Enable link change interrupt unless serdes polling. */ -- if (!(tp->tg3_flags & TG3_FLAG_POLL_SERDES)) -- tw32_f(MAC_EVENT, MAC_EVENT_LNKSTATE_CHANGED); -- else -- tw32_f(MAC_EVENT, 0); -- udelay(40); -+static int tg3_setup_fiber_hw_autoneg(struct tg3 *tp, u32 mac_status) -+{ -+ u32 sg_dig_ctrl, sg_dig_status; -+ u32 serdes_cfg, expected_sg_dig_ctrl; -+ int workaround, port_a; -+ int current_link_up; - -+ serdes_cfg = 0; -+ expected_sg_dig_ctrl = 0; -+ workaround = 0; -+ port_a = 1; - current_link_up = 0; -- if (tr32(MAC_STATUS) & MAC_STATUS_PCS_SYNCED) { -- if (tp->link_config.autoneg == AUTONEG_ENABLE) { -- u32 flags; -- -- if (fiber_autoneg(tp, &flags)) { -- u32 local_adv, remote_adv; - -- local_adv = ADVERTISE_PAUSE_CAP; -- remote_adv = 0; -- if (flags & MR_LP_ADV_SYM_PAUSE) -- remote_adv |= LPA_PAUSE_CAP; -- if (flags & MR_LP_ADV_ASYM_PAUSE) -- remote_adv |= LPA_PAUSE_ASYM; -+ if (tp->pci_chip_rev_id != CHIPREV_ID_5704_A0 && -+ tp->pci_chip_rev_id != CHIPREV_ID_5704_A1) { -+ workaround = 1; -+ if (tr32(TG3PCI_DUAL_MAC_CTRL) & DUAL_MAC_CTRL_ID) -+ port_a = 0; -+ -+ /* preserve bits 0-11,13,14 for signal pre-emphasis */ -+ /* preserve bits 20-23 for voltage regulator */ -+ serdes_cfg = tr32(MAC_SERDES_CFG) & 0x00f06fff; -+ } - -- tg3_setup_flow_control(tp, local_adv, remote_adv); -+ sg_dig_ctrl = tr32(SG_DIG_CTRL); - -- tp->tg3_flags |= -- TG3_FLAG_GOT_SERDES_FLOWCTL; -- current_link_up = 1; -- } -- for (i = 0; i < 60; i++) { -- udelay(20); -- tw32_f(MAC_STATUS, -- (MAC_STATUS_SYNC_CHANGED | -- MAC_STATUS_CFG_CHANGED)); -- udelay(40); -- if ((tr32(MAC_STATUS) & -- (MAC_STATUS_SYNC_CHANGED | -- MAC_STATUS_CFG_CHANGED)) == 0) -- break; -- } -- if (current_link_up == 0 && -- (tr32(MAC_STATUS) & MAC_STATUS_PCS_SYNCED)) { -- current_link_up = 1; -+ if (tp->link_config.autoneg != AUTONEG_ENABLE) { -+ if (sg_dig_ctrl & (1 << 31)) { -+ if (workaround) { -+ u32 val = serdes_cfg; -+ -+ if (port_a) -+ val |= 0xc010000; -+ else -+ val |= 0x4010000; -+ tw32_f(MAC_SERDES_CFG, val); - } -- } else { -- /* Forcing 1000FD link up. */ -+ tw32_f(SG_DIG_CTRL, 0x01388400); -+ } -+ if (mac_status & MAC_STATUS_PCS_SYNCED) { -+ tg3_setup_flow_control(tp, 0, 0); - current_link_up = 1; -- tp->tg3_flags |= TG3_FLAG_GOT_SERDES_FLOWCTL; - } -- } else -- tp->tg3_flags &= ~TG3_FLAG_GOT_SERDES_FLOWCTL; -+ goto out; -+ } - -- tp->mac_mode &= ~MAC_MODE_LINK_POLARITY; -- tw32_f(MAC_MODE, tp->mac_mode); -- udelay(40); -+ /* Want auto-negotiation. */ -+ expected_sg_dig_ctrl = 0x81388400; - -- tp->hw_status->status = -- (SD_STATUS_UPDATED | -- (tp->hw_status->status & ~SD_STATUS_LINK_CHG)); -+ /* Pause capability */ -+ expected_sg_dig_ctrl |= (1 << 11); - -- for (i = 0; i < 100; i++) { -- udelay(20); -- tw32_f(MAC_STATUS, -- (MAC_STATUS_SYNC_CHANGED | -- MAC_STATUS_CFG_CHANGED)); -- udelay(40); -- if ((tr32(MAC_STATUS) & -- (MAC_STATUS_SYNC_CHANGED | -- MAC_STATUS_CFG_CHANGED)) == 0) -- break; -- } -+ /* Asymettric pause */ -+ expected_sg_dig_ctrl |= (1 << 12); - -- if ((tr32(MAC_STATUS) & MAC_STATUS_PCS_SYNCED) == 0) -- current_link_up = 0; -+ if (sg_dig_ctrl != expected_sg_dig_ctrl) { -+ if (workaround) -+ tw32_f(MAC_SERDES_CFG, serdes_cfg | 0xc011000); -+ tw32_f(SG_DIG_CTRL, expected_sg_dig_ctrl | (1 << 30)); -+ udelay(5); -+ tw32_f(SG_DIG_CTRL, expected_sg_dig_ctrl); - -- if (current_link_up == 1) { -- tp->link_config.active_speed = SPEED_1000; -- tp->link_config.active_duplex = DUPLEX_FULL; -- tw32(MAC_LED_CTRL, (tp->led_ctrl | -- LED_CTRL_LNKLED_OVERRIDE | -- LED_CTRL_1000MBPS_ON)); -- } else { -- tp->link_config.active_speed = SPEED_INVALID; -- tp->link_config.active_duplex = DUPLEX_INVALID; -- tw32(MAC_LED_CTRL, (tp->led_ctrl | -- LED_CTRL_LNKLED_OVERRIDE | -- LED_CTRL_TRAFFIC_OVERRIDE)); -- } -+ tp->tg3_flags2 |= TG3_FLG2_PHY_JUST_INITTED; -+ } else if (mac_status & (MAC_STATUS_PCS_SYNCED | -+ MAC_STATUS_SIGNAL_DET)) { -+ int i; - -- if (current_link_up != netif_carrier_ok(tp->dev)) { -- if (current_link_up) -- netif_carrier_on(tp->dev); -- else -- netif_carrier_off(tp->dev); -- tg3_link_report(tp); -- } else { -- u32 now_pause_cfg = -- tp->tg3_flags & (TG3_FLAG_RX_PAUSE | -- TG3_FLAG_TX_PAUSE); -- if (orig_pause_cfg != now_pause_cfg || -- orig_active_speed != tp->link_config.active_speed || -- orig_active_duplex != tp->link_config.active_duplex) -- tg3_link_report(tp); -- } -+ /* Giver time to negotiate (~200ms) */ -+ for (i = 0; i < 40000; i++) { -+ sg_dig_status = tr32(SG_DIG_STATUS); -+ if (sg_dig_status & (0x3)) -+ break; -+ udelay(5); -+ } -+ mac_status = tr32(MAC_STATUS); - -- if ((tr32(MAC_STATUS) & MAC_STATUS_PCS_SYNCED) == 0) { -- tw32_f(MAC_MODE, tp->mac_mode | MAC_MODE_LINK_POLARITY); -- udelay(40); -- if (tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) { -- tw32_f(MAC_MODE, tp->mac_mode); -- udelay(40); -+ if ((sg_dig_status & (1 << 1)) && -+ (mac_status & MAC_STATUS_PCS_SYNCED)) { -+ u32 local_adv, remote_adv; -+ -+ local_adv = ADVERTISE_PAUSE_CAP; -+ remote_adv = 0; -+ if (sg_dig_status & (1 << 19)) -+ remote_adv |= LPA_PAUSE_CAP; -+ if (sg_dig_status & (1 << 20)) -+ remote_adv |= LPA_PAUSE_ASYM; -+ -+ tg3_setup_flow_control(tp, local_adv, remote_adv); -+ current_link_up = 1; -+ tp->tg3_flags2 &= ~TG3_FLG2_PHY_JUST_INITTED; -+ } else if (!(sg_dig_status & (1 << 1))) { -+ if (tp->tg3_flags2 & TG3_FLG2_PHY_JUST_INITTED) -+ tp->tg3_flags2 &= ~TG3_FLG2_PHY_JUST_INITTED; -+ else { -+ if (workaround) { -+ u32 val = serdes_cfg; -+ -+ if (port_a) -+ val |= 0xc010000; -+ else -+ val |= 0x4010000; -+ -+ tw32_f(MAC_SERDES_CFG, val); -+ } -+ -+ tw32_f(SG_DIG_CTRL, 0x01388400); -+ udelay(40); -+ -+ /* Link parallel detection - link is up */ -+ /* only if we have PCS_SYNC and not */ -+ /* receiving config code words */ -+ mac_status = tr32(MAC_STATUS); -+ if ((mac_status & MAC_STATUS_PCS_SYNCED) && -+ !(mac_status & MAC_STATUS_RCVD_CFG)) { -+ tg3_setup_flow_control(tp, 0, 0); -+ current_link_up = 1; -+ } -+ } - } - } - -- return 0; -+out: -+ return current_link_up; - } - --static int tg3_setup_phy(struct tg3 *tp, int force_reset) -+static int tg3_setup_fiber_by_hand(struct tg3 *tp, u32 mac_status) -+{ -+ int current_link_up = 0; -+ -+ if (!(mac_status & MAC_STATUS_PCS_SYNCED)) { -+ tp->tg3_flags &= ~TG3_FLAG_GOT_SERDES_FLOWCTL; -+ goto out; -+ } -+ -+ if (tp->link_config.autoneg == AUTONEG_ENABLE) { -+ u32 flags; -+ int i; -+ -+ if (fiber_autoneg(tp, &flags)) { -+ u32 local_adv, remote_adv; -+ -+ local_adv = ADVERTISE_PAUSE_CAP; -+ remote_adv = 0; -+ if (flags & MR_LP_ADV_SYM_PAUSE) -+ remote_adv |= LPA_PAUSE_CAP; -+ if (flags & MR_LP_ADV_ASYM_PAUSE) -+ remote_adv |= LPA_PAUSE_ASYM; -+ -+ tg3_setup_flow_control(tp, local_adv, remote_adv); -+ -+ tp->tg3_flags |= TG3_FLAG_GOT_SERDES_FLOWCTL; -+ current_link_up = 1; -+ } -+ for (i = 0; i < 30; i++) { -+ udelay(20); -+ tw32_f(MAC_STATUS, -+ (MAC_STATUS_SYNC_CHANGED | -+ MAC_STATUS_CFG_CHANGED)); -+ udelay(40); -+ if ((tr32(MAC_STATUS) & -+ (MAC_STATUS_SYNC_CHANGED | -+ MAC_STATUS_CFG_CHANGED)) == 0) -+ break; -+ } -+ -+ mac_status = tr32(MAC_STATUS); -+ if (current_link_up == 0 && -+ (mac_status & MAC_STATUS_PCS_SYNCED) && -+ !(mac_status & MAC_STATUS_RCVD_CFG)) -+ current_link_up = 1; -+ } else { -+ /* Forcing 1000FD link up. */ -+ current_link_up = 1; -+ tp->tg3_flags |= TG3_FLAG_GOT_SERDES_FLOWCTL; -+ -+ tw32_f(MAC_MODE, (tp->mac_mode | MAC_MODE_SEND_CONFIGS)); -+ udelay(40); -+ } -+ -+out: -+ return current_link_up; -+} -+ -+static int tg3_setup_fiber_phy(struct tg3 *tp, int force_reset) -+{ -+ u32 orig_pause_cfg; -+ u16 orig_active_speed; -+ u8 orig_active_duplex; -+ u32 mac_status; -+ int current_link_up; -+ int i; -+ -+ orig_pause_cfg = -+ (tp->tg3_flags & (TG3_FLAG_RX_PAUSE | -+ TG3_FLAG_TX_PAUSE)); -+ orig_active_speed = tp->link_config.active_speed; -+ orig_active_duplex = tp->link_config.active_duplex; -+ -+ if (!(tp->tg3_flags2 & TG3_FLG2_HW_AUTONEG) && -+ netif_carrier_ok(tp->dev) && -+ (tp->tg3_flags & TG3_FLAG_INIT_COMPLETE)) { -+ mac_status = tr32(MAC_STATUS); -+ mac_status &= (MAC_STATUS_PCS_SYNCED | -+ MAC_STATUS_SIGNAL_DET | -+ MAC_STATUS_CFG_CHANGED | -+ MAC_STATUS_RCVD_CFG); -+ if (mac_status == (MAC_STATUS_PCS_SYNCED | -+ MAC_STATUS_SIGNAL_DET)) { -+ tw32_f(MAC_STATUS, (MAC_STATUS_SYNC_CHANGED | -+ MAC_STATUS_CFG_CHANGED)); -+ return 0; -+ } -+ } -+ -+ tw32_f(MAC_TX_AUTO_NEG, 0); -+ -+ tp->mac_mode &= ~(MAC_MODE_PORT_MODE_MASK | MAC_MODE_HALF_DUPLEX); -+ tp->mac_mode |= MAC_MODE_PORT_MODE_TBI; -+ tw32_f(MAC_MODE, tp->mac_mode); -+ udelay(40); -+ -+ if (tp->phy_id == PHY_ID_BCM8002) -+ tg3_init_bcm8002(tp); -+ -+ /* Enable link change event even when serdes polling. */ -+ tw32_f(MAC_EVENT, MAC_EVENT_LNKSTATE_CHANGED); -+ udelay(40); -+ -+ current_link_up = 0; -+ mac_status = tr32(MAC_STATUS); -+ -+ if (tp->tg3_flags2 & TG3_FLG2_HW_AUTONEG) -+ current_link_up = tg3_setup_fiber_hw_autoneg(tp, mac_status); -+ else -+ current_link_up = tg3_setup_fiber_by_hand(tp, mac_status); -+ -+ tp->mac_mode &= ~MAC_MODE_LINK_POLARITY; -+ tw32_f(MAC_MODE, tp->mac_mode); -+ udelay(40); -+ -+ tp->hw_status->status = -+ (SD_STATUS_UPDATED | -+ (tp->hw_status->status & ~SD_STATUS_LINK_CHG)); -+ -+ for (i = 0; i < 100; i++) { -+ tw32_f(MAC_STATUS, (MAC_STATUS_SYNC_CHANGED | -+ MAC_STATUS_CFG_CHANGED)); -+ udelay(5); -+ if ((tr32(MAC_STATUS) & (MAC_STATUS_SYNC_CHANGED | -+ MAC_STATUS_CFG_CHANGED)) == 0) -+ break; -+ } -+ -+ mac_status = tr32(MAC_STATUS); -+ if ((mac_status & MAC_STATUS_PCS_SYNCED) == 0) { -+ current_link_up = 0; -+ if (tp->link_config.autoneg == AUTONEG_ENABLE) { -+ tw32_f(MAC_MODE, (tp->mac_mode | -+ MAC_MODE_SEND_CONFIGS)); -+ udelay(1); -+ tw32_f(MAC_MODE, tp->mac_mode); -+ } -+ } -+ -+ if (current_link_up == 1) { -+ tp->link_config.active_speed = SPEED_1000; -+ tp->link_config.active_duplex = DUPLEX_FULL; -+ tw32(MAC_LED_CTRL, (tp->led_ctrl | -+ LED_CTRL_LNKLED_OVERRIDE | -+ LED_CTRL_1000MBPS_ON)); -+ } else { -+ tp->link_config.active_speed = SPEED_INVALID; -+ tp->link_config.active_duplex = DUPLEX_INVALID; -+ tw32(MAC_LED_CTRL, (tp->led_ctrl | -+ LED_CTRL_LNKLED_OVERRIDE | -+ LED_CTRL_TRAFFIC_OVERRIDE)); -+ } -+ -+ if (current_link_up != netif_carrier_ok(tp->dev)) { -+ if (current_link_up) -+ netif_carrier_on(tp->dev); -+ else -+ netif_carrier_off(tp->dev); -+ tg3_link_report(tp); -+ } else { -+ u32 now_pause_cfg = -+ tp->tg3_flags & (TG3_FLAG_RX_PAUSE | -+ TG3_FLAG_TX_PAUSE); -+ if (orig_pause_cfg != now_pause_cfg || -+ orig_active_speed != tp->link_config.active_speed || -+ orig_active_duplex != tp->link_config.active_duplex) -+ tg3_link_report(tp); -+ } -+ -+ return 0; -+} -+ -+static int tg3_setup_phy(struct tg3 *tp, int force_reset) - { - int err; - -- if (tp->phy_id == PHY_ID_SERDES) { -+ if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) { - err = tg3_setup_fiber_phy(tp, force_reset); - } else { - err = tg3_setup_copper_phy(tp, force_reset); -@@ -2237,8 +2498,7 @@ static int tg3_setup_phy(struct tg3 *tp, - (6 << TX_LENGTHS_IPG_SHIFT) | - (32 << TX_LENGTHS_SLOT_TIME_SHIFT))); - -- if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705 && -- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750) { -+ if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { - if (netif_carrier_ok(tp->dev)) { - tw32(HOSTCC_STAT_COAL_TICKS, - DEFAULT_STAT_COAL_TICKS); -@@ -2450,8 +2710,8 @@ static int tg3_vlan_rx(struct tg3 *tp, s - static int tg3_rx(struct tg3 *tp, int budget) - { - u32 work_mask; -- u32 rx_rcb_ptr = tp->rx_rcb_ptr; -- u16 hw_idx, sw_idx; -+ u32 sw_idx = tp->rx_rcb_ptr; -+ u16 hw_idx; - int received; - - hw_idx = tp->hw_status->idx[0].rx_producer; -@@ -2460,7 +2720,6 @@ static int tg3_rx(struct tg3 *tp, int bu - * the opaque cookie. - */ - rmb(); -- sw_idx = rx_rcb_ptr % TG3_RX_RCB_RING_SIZE(tp); - work_mask = 0; - received = 0; - while (sw_idx != hw_idx && budget > 0) { -@@ -2502,7 +2761,11 @@ static int tg3_rx(struct tg3 *tp, int bu - - len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) - 4; /* omit crc */ - -- if (len > RX_COPY_THRESHOLD) { -+ if (len > RX_COPY_THRESHOLD -+ && tp->rx_offset == 2 -+ /* rx_offset != 2 iff this is a 5701 card running -+ * in PCI-X mode [see tg3_get_invariants()] */ -+ ) { - int skb_size; - - skb_size = tg3_alloc_rx_skb(tp, opaque_key, -@@ -2561,14 +2824,19 @@ static int tg3_rx(struct tg3 *tp, int bu - next_pkt: - (*post_ptr)++; - next_pkt_nopost: -- rx_rcb_ptr++; -- sw_idx = rx_rcb_ptr % TG3_RX_RCB_RING_SIZE(tp); -+ sw_idx++; -+ sw_idx %= TG3_RX_RCB_RING_SIZE(tp); -+ -+ /* Refresh hw_idx to see if there is new work */ -+ if (sw_idx == hw_idx) { -+ hw_idx = tp->hw_status->idx[0].rx_producer; -+ rmb(); -+ } - } - - /* ACK the status ring. */ -- tp->rx_rcb_ptr = rx_rcb_ptr; -- tw32_rx_mbox(MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW, -- (rx_rcb_ptr % TG3_RX_RCB_RING_SIZE(tp))); -+ tp->rx_rcb_ptr = sw_idx; -+ tw32_rx_mbox(MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW, sw_idx); - - /* Refill RX ring(s). */ - if (work_mask & RXD_OPAQUE_RING_STD) { -@@ -2581,6 +2849,7 @@ next_pkt_nopost: - tw32_rx_mbox(MAILBOX_RCV_JUMBO_PROD_IDX + TG3_64BIT_REG_LOW, - sw_idx); - } -+ mmiowb(); - - return received; - } -@@ -2639,31 +2908,48 @@ static int tg3_poll(struct net_device *n - if (done) { - spin_lock_irqsave(&tp->lock, flags); - __netif_rx_complete(netdev); -- tg3_enable_ints(tp); -+ tg3_restart_ints(tp); - spin_unlock_irqrestore(&tp->lock, flags); - } - - return (done ? 0 : 1); - } - --static inline unsigned int tg3_has_work(struct net_device *dev, struct tg3 *tp) -+/* MSI ISR - No need to check for interrupt sharing and no need to -+ * flush status block and interrupt mailbox. PCI ordering rules -+ * guarantee that MSI will arrive after the status block. -+ */ -+static irqreturn_t tg3_msi(int irq, void *dev_id, struct pt_regs *regs) - { -+ struct net_device *dev = dev_id; -+ struct tg3 *tp = netdev_priv(dev); - struct tg3_hw_status *sblk = tp->hw_status; -- unsigned int work_exists = 0; -+ unsigned long flags; - -- /* check for phy events */ -- if (!(tp->tg3_flags & -- (TG3_FLAG_USE_LINKCHG_REG | -- TG3_FLAG_POLL_SERDES))) { -- if (sblk->status & SD_STATUS_LINK_CHG) -- work_exists = 1; -+ spin_lock_irqsave(&tp->lock, flags); -+ -+ /* -+ * writing any value to intr-mbox-0 clears PCI INTA# and -+ * chip-internal interrupt pending events. -+ * writing non-zero to intr-mbox-0 additional tells the -+ * NIC to stop sending us irqs, engaging "in-intr-handler" -+ * event coalescing. -+ */ -+ tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); -+ sblk->status &= ~SD_STATUS_UPDATED; -+ -+ if (likely(tg3_has_work(tp))) -+ netif_rx_schedule(dev); /* schedule NAPI poll */ -+ else { -+ /* no work, re-enable interrupts -+ */ -+ tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, -+ 0x00000000); - } -- /* check for RX/TX work to do */ -- if (sblk->idx[0].tx_consumer != tp->tx_cons || -- sblk->idx[0].rx_producer != tp->rx_rcb_ptr) -- work_exists = 1; - -- return work_exists; -+ spin_unlock_irqrestore(&tp->lock, flags); -+ -+ return IRQ_RETVAL(1); - } - - static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs) -@@ -2676,7 +2962,13 @@ static irqreturn_t tg3_interrupt(int irq - - spin_lock_irqsave(&tp->lock, flags); - -- if (sblk->status & SD_STATUS_UPDATED) { -+ /* In INTx mode, it is possible for the interrupt to arrive at -+ * the CPU before the status block posted prior to the interrupt. -+ * Reading the PCI State register will confirm whether the -+ * interrupt is ours and will flush the status block. -+ */ -+ if ((sblk->status & SD_STATUS_UPDATED) || -+ !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) { - /* - * writing any value to intr-mbox-0 clears PCI INTA# and - * chip-internal interrupt pending events. -@@ -2693,7 +2985,7 @@ static irqreturn_t tg3_interrupt(int irq - tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); - sblk->status &= ~SD_STATUS_UPDATED; - -- if (likely(tg3_has_work(dev, tp))) -+ if (likely(tg3_has_work(tp))) - netif_rx_schedule(dev); /* schedule NAPI poll */ - else { - /* no work, shared interrupt perhaps? re-enable -@@ -2712,13 +3004,31 @@ static irqreturn_t tg3_interrupt(int irq - return IRQ_RETVAL(handled); - } - -+/* ISR for interrupt test */ -+static irqreturn_t tg3_test_isr(int irq, void *dev_id, -+ struct pt_regs *regs) -+{ -+ struct net_device *dev = dev_id; -+ struct tg3 *tp = netdev_priv(dev); -+ struct tg3_hw_status *sblk = tp->hw_status; -+ -+ if (sblk->status & SD_STATUS_UPDATED) { -+ tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, -+ 0x00000001); -+ return IRQ_RETVAL(1); -+ } -+ return IRQ_RETVAL(0); -+} -+ - static int tg3_init_hw(struct tg3 *); --static int tg3_halt(struct tg3 *); -+static int tg3_halt(struct tg3 *, int); - - #ifdef CONFIG_NET_POLL_CONTROLLER - static void tg3_poll_controller(struct net_device *dev) - { -- tg3_interrupt(dev->irq, dev, NULL); -+ struct tg3 *tp = netdev_priv(dev); -+ -+ tg3_interrupt(tp->pdev->irq, dev, NULL); - } - #endif - -@@ -2735,14 +3045,14 @@ static void tg3_reset_task(void *_data) - restart_timer = tp->tg3_flags2 & TG3_FLG2_RESTART_TIMER; - tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER; - -- tg3_halt(tp); -+ tg3_halt(tp, 0); - tg3_init_hw(tp); - -+ tg3_netif_start(tp); -+ - spin_unlock(&tp->tx_lock); - spin_unlock_irq(&tp->lock); - -- tg3_netif_start(tp); -- - if (restart_timer) - mod_timer(&tp->timer, jiffies + 1); - } -@@ -2801,6 +3111,7 @@ static int tigon3_4gb_hwbug_workaround(s - tp->tx_buffers[entry].skb = NULL; - } - entry = NEXT_TX(entry); -+ i++; - } - - dev_kfree_skb(skb); -@@ -2812,6 +3123,7 @@ static void tg3_set_txd(struct tg3 *tp, - dma_addr_t mapping, int len, u32 flags, - u32 mss_and_is_end) - { -+ struct tg3_tx_buffer_desc *txd = &tp->tx_ring[entry]; - int is_end = (mss_and_is_end & 0x1); - u32 mss = (mss_and_is_end >> 1); - u32 vlan_tag = 0; -@@ -2823,35 +3135,11 @@ static void tg3_set_txd(struct tg3 *tp, - flags &= 0xffff; - } - vlan_tag |= (mss << TXD_MSS_SHIFT); -- if (tp->tg3_flags & TG3_FLAG_HOST_TXDS) { -- struct tg3_tx_buffer_desc *txd = &tp->tx_ring[entry]; -- -- txd->addr_hi = ((u64) mapping >> 32); -- txd->addr_lo = ((u64) mapping & 0xffffffff); -- txd->len_flags = (len << TXD_LEN_SHIFT) | flags; -- txd->vlan_tag = vlan_tag << TXD_VLAN_TAG_SHIFT; -- } else { -- struct tx_ring_info *txr = &tp->tx_buffers[entry]; -- unsigned long txd; -- -- txd = (tp->regs + -- NIC_SRAM_WIN_BASE + -- NIC_SRAM_TX_BUFFER_DESC); -- txd += (entry * TXD_SIZE); - -- /* Save some PIOs */ -- if (sizeof(dma_addr_t) != sizeof(u32)) -- writel(((u64) mapping >> 32), -- txd + TXD_ADDR + TG3_64BIT_REG_HIGH); -- -- writel(((u64) mapping & 0xffffffff), -- txd + TXD_ADDR + TG3_64BIT_REG_LOW); -- writel(len << TXD_LEN_SHIFT | flags, txd + TXD_LEN_FLAGS); -- if (txr->prev_vlan_tag != vlan_tag) { -- writel(vlan_tag << TXD_VLAN_TAG_SHIFT, txd + TXD_VLAN_TAG); -- txr->prev_vlan_tag = vlan_tag; -- } -- } -+ txd->addr_hi = ((u64) mapping >> 32); -+ txd->addr_lo = ((u64) mapping & 0xffffffff); -+ txd->len_flags = (len << TXD_LEN_SHIFT) | flags; -+ txd->vlan_tag = vlan_tag << TXD_VLAN_TAG_SHIFT; - } - - static inline int tg3_4g_overflow_test(dma_addr_t mapping, int len) -@@ -2892,7 +3180,11 @@ static int tg3_start_xmit(struct sk_buff - * So we really do need to disable interrupts when taking - * tx_lock here. - */ -- spin_lock_irqsave(&tp->tx_lock, flags); -+ local_irq_save(flags); -+ if (!spin_trylock(&tp->tx_lock)) { -+ local_irq_restore(flags); -+ return NETDEV_TX_LOCKED; -+ } - - /* This is a hard error, log it. */ - if (unlikely(TX_BUFFS_AVAIL(tp) <= (skb_shinfo(skb)->nr_frags + 1))) { -@@ -2900,7 +3192,7 @@ static int tg3_start_xmit(struct sk_buff - spin_unlock_irqrestore(&tp->tx_lock, flags); - printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n", - dev->name); -- return 1; -+ return NETDEV_TX_BUSY; - } - - entry = tp->tx_prod; -@@ -2913,6 +3205,12 @@ static int tg3_start_xmit(struct sk_buff - (mss = skb_shinfo(skb)->tso_size) != 0) { - int tcp_opt_len, ip_tcp_len; - -+ if (skb_header_cloned(skb) && -+ pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) { -+ dev_kfree_skb(skb); -+ goto out_unlock; -+ } -+ - tcp_opt_len = ((skb->h.th->doff - 5) * 4); - ip_tcp_len = (skb->nh.iph->ihl * 4) + sizeof(struct tcphdr); - -@@ -2921,11 +3219,19 @@ static int tg3_start_xmit(struct sk_buff - - skb->nh.iph->check = 0; - skb->nh.iph->tot_len = ntohs(mss + ip_tcp_len + tcp_opt_len); -- skb->h.th->check = ~csum_tcpudp_magic(skb->nh.iph->saddr, -- skb->nh.iph->daddr, -- 0, IPPROTO_TCP, 0); -+ if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) { -+ skb->h.th->check = 0; -+ base_flags &= ~TXD_FLAG_TCPUDP_CSUM; -+ } -+ else { -+ skb->h.th->check = -+ ~csum_tcpudp_magic(skb->nh.iph->saddr, -+ skb->nh.iph->daddr, -+ 0, IPPROTO_TCP, 0); -+ } - -- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { -+ if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO) || -+ (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)) { - if (tcp_opt_len || skb->nh.iph->ihl > 5) { - int tsflags; - -@@ -2992,7 +3298,7 @@ static int tg3_start_xmit(struct sk_buff - would_hit_hwbug = entry + 1; - } - -- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) -+ if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) - tg3_set_txd(tp, entry, mapping, len, - base_flags, (i == last)|(mss << 1)); - else -@@ -3040,30 +3346,19 @@ static int tg3_start_xmit(struct sk_buff - } - - /* Packets are ready, update Tx producer idx local and on card. */ -- if (tp->tg3_flags & TG3_FLAG_HOST_TXDS) { -- tw32_tx_mbox((MAILBOX_SNDHOST_PROD_IDX_0 + -- TG3_64BIT_REG_LOW), entry); -- } else { -- /* First, make sure tg3 sees last descriptor fully -- * in SRAM. -- */ -- if (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) -- tr32(MAILBOX_SNDNIC_PROD_IDX_0 + TG3_64BIT_REG_LOW); -- -- tw32_tx_mbox((MAILBOX_SNDNIC_PROD_IDX_0 + -- TG3_64BIT_REG_LOW), entry); -- } -+ tw32_tx_mbox((MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW), entry); - - tp->tx_prod = entry; - if (TX_BUFFS_AVAIL(tp) <= (MAX_SKB_FRAGS + 1)) - netif_stop_queue(dev); - - out_unlock: -+ mmiowb(); - spin_unlock_irqrestore(&tp->tx_lock, flags); - - dev->trans_start = jiffies; - -- return 0; -+ return NETDEV_TX_OK; - } - - static inline void tg3_set_mtu(struct net_device *dev, struct tg3 *tp, -@@ -3096,15 +3391,16 @@ static int tg3_change_mtu(struct net_dev - spin_lock_irq(&tp->lock); - spin_lock(&tp->tx_lock); - -- tg3_halt(tp); -+ tg3_halt(tp, 1); - - tg3_set_mtu(dev, tp, new_mtu); - - tg3_init_hw(tp); - -+ tg3_netif_start(tp); -+ - spin_unlock(&tp->tx_lock); - spin_unlock_irq(&tp->lock); -- tg3_netif_start(tp); - - return 0; - } -@@ -3190,7 +3486,6 @@ static void tg3_free_rings(struct tg3 *t - */ - static void tg3_init_rings(struct tg3 *tp) - { -- unsigned long start, end; - u32 i; - - /* Free up all the SKBs. */ -@@ -3200,21 +3495,7 @@ static void tg3_init_rings(struct tg3 *t - memset(tp->rx_std, 0, TG3_RX_RING_BYTES); - memset(tp->rx_jumbo, 0, TG3_RX_JUMBO_RING_BYTES); - memset(tp->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp)); -- -- if (tp->tg3_flags & TG3_FLAG_HOST_TXDS) { -- memset(tp->tx_ring, 0, TG3_TX_RING_BYTES); -- } else { -- start = (tp->regs + -- NIC_SRAM_WIN_BASE + -- NIC_SRAM_TX_BUFFER_DESC); -- end = start + TG3_TX_RING_BYTES; -- while (start < end) { -- writel(0, start); -- start += 4; -- } -- for (i = 0; i < TG3_TX_RING_SIZE; i++) -- tp->tx_buffers[i].prev_vlan_tag = 0; -- } -+ memset(tp->tx_ring, 0, TG3_TX_RING_BYTES); - - /* Initialize invariants of the rings, we only set this - * stuff once. This works because the card does not -@@ -3345,15 +3626,10 @@ static int tg3_alloc_consistent(struct t - if (!tp->rx_rcb) - goto err_out; - -- if (tp->tg3_flags & TG3_FLAG_HOST_TXDS) { -- tp->tx_ring = pci_alloc_consistent(tp->pdev, TG3_TX_RING_BYTES, -- &tp->tx_desc_mapping); -- if (!tp->tx_ring) -- goto err_out; -- } else { -- tp->tx_ring = NULL; -- tp->tx_desc_mapping = 0; -- } -+ tp->tx_ring = pci_alloc_consistent(tp->pdev, TG3_TX_RING_BYTES, -+ &tp->tx_desc_mapping); -+ if (!tp->tx_ring) -+ goto err_out; - - tp->hw_status = pci_alloc_consistent(tp->pdev, - TG3_HW_STATUS_SIZE, -@@ -3382,13 +3658,12 @@ err_out: - /* To stop a block, clear the enable bit and poll till it - * clears. tp->lock is held. - */ --static int tg3_stop_block(struct tg3 *tp, unsigned long ofs, u32 enable_bit) -+static int tg3_stop_block(struct tg3 *tp, unsigned long ofs, u32 enable_bit, int silent) - { - unsigned int i; - u32 val; - -- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 || -- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) { -+ if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) { - switch (ofs) { - case RCVLSC_MODE: - case DMAC_MODE: -@@ -3416,7 +3691,7 @@ static int tg3_stop_block(struct tg3 *tp - break; - } - -- if (i == MAX_WAIT_CNT) { -+ if (i == MAX_WAIT_CNT && !silent) { - printk(KERN_ERR PFX "tg3_stop_block timed out, " - "ofs=%lx enable_bit=%x\n", - ofs, enable_bit); -@@ -3427,7 +3702,7 @@ static int tg3_stop_block(struct tg3 *tp - } - - /* tp->lock is held. */ --static int tg3_abort_hw(struct tg3 *tp) -+static int tg3_abort_hw(struct tg3 *tp, int silent) - { - int i, err; - -@@ -3437,22 +3712,20 @@ static int tg3_abort_hw(struct tg3 *tp) - tw32_f(MAC_RX_MODE, tp->rx_mode); - udelay(10); - -- err = tg3_stop_block(tp, RCVBDI_MODE, RCVBDI_MODE_ENABLE); -- err |= tg3_stop_block(tp, RCVLPC_MODE, RCVLPC_MODE_ENABLE); -- err |= tg3_stop_block(tp, RCVLSC_MODE, RCVLSC_MODE_ENABLE); -- err |= tg3_stop_block(tp, RCVDBDI_MODE, RCVDBDI_MODE_ENABLE); -- err |= tg3_stop_block(tp, RCVDCC_MODE, RCVDCC_MODE_ENABLE); -- err |= tg3_stop_block(tp, RCVCC_MODE, RCVCC_MODE_ENABLE); -- -- err |= tg3_stop_block(tp, SNDBDS_MODE, SNDBDS_MODE_ENABLE); -- err |= tg3_stop_block(tp, SNDBDI_MODE, SNDBDI_MODE_ENABLE); -- err |= tg3_stop_block(tp, SNDDATAI_MODE, SNDDATAI_MODE_ENABLE); -- err |= tg3_stop_block(tp, RDMAC_MODE, RDMAC_MODE_ENABLE); -- err |= tg3_stop_block(tp, SNDDATAC_MODE, SNDDATAC_MODE_ENABLE); -- err |= tg3_stop_block(tp, DMAC_MODE, DMAC_MODE_ENABLE); -- err |= tg3_stop_block(tp, SNDBDC_MODE, SNDBDC_MODE_ENABLE); -- if (err) -- goto out; -+ err = tg3_stop_block(tp, RCVBDI_MODE, RCVBDI_MODE_ENABLE, silent); -+ err |= tg3_stop_block(tp, RCVLPC_MODE, RCVLPC_MODE_ENABLE, silent); -+ err |= tg3_stop_block(tp, RCVLSC_MODE, RCVLSC_MODE_ENABLE, silent); -+ err |= tg3_stop_block(tp, RCVDBDI_MODE, RCVDBDI_MODE_ENABLE, silent); -+ err |= tg3_stop_block(tp, RCVDCC_MODE, RCVDCC_MODE_ENABLE, silent); -+ err |= tg3_stop_block(tp, RCVCC_MODE, RCVCC_MODE_ENABLE, silent); -+ -+ err |= tg3_stop_block(tp, SNDBDS_MODE, SNDBDS_MODE_ENABLE, silent); -+ err |= tg3_stop_block(tp, SNDBDI_MODE, SNDBDI_MODE_ENABLE, silent); -+ err |= tg3_stop_block(tp, SNDDATAI_MODE, SNDDATAI_MODE_ENABLE, silent); -+ err |= tg3_stop_block(tp, RDMAC_MODE, RDMAC_MODE_ENABLE, silent); -+ err |= tg3_stop_block(tp, SNDDATAC_MODE, SNDDATAC_MODE_ENABLE, silent); -+ err |= tg3_stop_block(tp, DMAC_MODE, DMAC_MODE_ENABLE, silent); -+ err |= tg3_stop_block(tp, SNDBDC_MODE, SNDBDC_MODE_ENABLE, silent); - - tp->mac_mode &= ~MAC_MODE_TDE_ENABLE; - tw32_f(MAC_MODE, tp->mac_mode); -@@ -3470,27 +3743,24 @@ static int tg3_abort_hw(struct tg3 *tp) - printk(KERN_ERR PFX "tg3_abort_hw timed out for %s, " - "TX_MODE_ENABLE will not clear MAC_TX_MODE=%08x\n", - tp->dev->name, tr32(MAC_TX_MODE)); -- return -ENODEV; -+ err |= -ENODEV; - } - -- err = tg3_stop_block(tp, HOSTCC_MODE, HOSTCC_MODE_ENABLE); -- err |= tg3_stop_block(tp, WDMAC_MODE, WDMAC_MODE_ENABLE); -- err |= tg3_stop_block(tp, MBFREE_MODE, MBFREE_MODE_ENABLE); -+ err |= tg3_stop_block(tp, HOSTCC_MODE, HOSTCC_MODE_ENABLE, silent); -+ err |= tg3_stop_block(tp, WDMAC_MODE, WDMAC_MODE_ENABLE, silent); -+ err |= tg3_stop_block(tp, MBFREE_MODE, MBFREE_MODE_ENABLE, silent); - - tw32(FTQ_RESET, 0xffffffff); - tw32(FTQ_RESET, 0x00000000); - -- err |= tg3_stop_block(tp, BUFMGR_MODE, BUFMGR_MODE_ENABLE); -- err |= tg3_stop_block(tp, MEMARB_MODE, MEMARB_MODE_ENABLE); -- if (err) -- goto out; -+ err |= tg3_stop_block(tp, BUFMGR_MODE, BUFMGR_MODE_ENABLE, silent); -+ err |= tg3_stop_block(tp, MEMARB_MODE, MEMARB_MODE_ENABLE, silent); - - if (tp->hw_status) - memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE); - if (tp->hw_stats) - memset(tp->hw_stats, 0, sizeof(struct tg3_hw_stats)); - --out: - return err; - } - -@@ -3520,10 +3790,33 @@ static void tg3_nvram_unlock(struct tg3 - } - - /* tp->lock is held. */ -+static void tg3_enable_nvram_access(struct tg3 *tp) -+{ -+ if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) && -+ !(tp->tg3_flags2 & TG3_FLG2_PROTECTED_NVRAM)) { -+ u32 nvaccess = tr32(NVRAM_ACCESS); -+ -+ tw32(NVRAM_ACCESS, nvaccess | ACCESS_ENABLE); -+ } -+} -+ -+/* tp->lock is held. */ -+static void tg3_disable_nvram_access(struct tg3 *tp) -+{ -+ if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) && -+ !(tp->tg3_flags2 & TG3_FLG2_PROTECTED_NVRAM)) { -+ u32 nvaccess = tr32(NVRAM_ACCESS); -+ -+ tw32(NVRAM_ACCESS, nvaccess & ~ACCESS_ENABLE); -+ } -+} -+ -+/* tp->lock is held. */ - static void tg3_write_sig_pre_reset(struct tg3 *tp, int kind) - { -- tg3_write_mem(tp, NIC_SRAM_FIRMWARE_MBOX, -- NIC_SRAM_FIRMWARE_MBOX_MAGIC1); -+ if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) -+ tg3_write_mem(tp, NIC_SRAM_FIRMWARE_MBOX, -+ NIC_SRAM_FIRMWARE_MBOX_MAGIC1); - - if (tp->tg3_flags2 & TG3_FLG2_ASF_NEW_HANDSHAKE) { - switch (kind) { -@@ -3595,6 +3888,8 @@ static void tg3_write_sig_legacy(struct - } - } - -+static void tg3_stop_fw(struct tg3 *); -+ - /* tp->lock is held. */ - static int tg3_chip_reset(struct tg3 *tp) - { -@@ -3602,7 +3897,7 @@ static int tg3_chip_reset(struct tg3 *tp - u32 flags_save; - int i; - -- if (!(tp->tg3_flags2 & TG3_FLG2_SUN_5704)) -+ if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) - tg3_nvram_lock(tp); - - /* -@@ -3627,8 +3922,7 @@ static int tg3_chip_reset(struct tg3 *tp - } - } - -- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 || -- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) -+ if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) - val |= GRC_MISC_CFG_KEEP_GPHY_POWER; - tw32(GRC_MISC_CFG, val); - -@@ -3697,6 +3991,11 @@ static int tg3_chip_reset(struct tg3 *tp - - tw32(MEMARB_MODE, MEMARB_MODE_ENABLE); - -+ if (tp->pci_chip_rev_id == CHIPREV_ID_5750_A3) { -+ tg3_stop_fw(tp); -+ tw32(0x5000, 0x400); -+ } -+ - tw32(GRC_MODE, tp->grc_mode); - - if (tp->pci_chip_rev_id == CHIPREV_ID_5705_A0) { -@@ -3713,26 +4012,27 @@ static int tg3_chip_reset(struct tg3 *tp - tw32(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl); - } - -- if (tp->phy_id == PHY_ID_SERDES) { -+ if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) { - tp->mac_mode = MAC_MODE_PORT_MODE_TBI; - tw32_f(MAC_MODE, tp->mac_mode); - } else - tw32_f(MAC_MODE, 0); - udelay(40); - -- /* 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 && -- !(tp->tg3_flags2 & TG3_FLG2_SUN_5704)) { -- printk(KERN_ERR PFX "tg3_reset_hw timed out for %s, " -- "firmware will not restart magic=%08x\n", -- tp->dev->name, val); -- return -ENODEV; -+ 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; -+ } - } - - if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) && -@@ -3752,7 +4052,7 @@ static int tg3_chip_reset(struct tg3 *tp - tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg); - if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) { - tp->tg3_flags |= TG3_FLAG_ENABLE_ASF; -- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) -+ if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) - tp->tg3_flags2 |= TG3_FLG2_ASF_NEW_HANDSHAKE; - } - } -@@ -3782,7 +4082,7 @@ static void tg3_stop_fw(struct tg3 *tp) - } - - /* tp->lock is held. */ --static int tg3_halt(struct tg3 *tp) -+static int tg3_halt(struct tg3 *tp, int silent) - { - int err; - -@@ -3790,7 +4090,7 @@ static int tg3_halt(struct tg3 *tp) - - tg3_write_sig_pre_reset(tp, RESET_KIND_SHUTDOWN); - -- tg3_abort_hw(tp); -+ tg3_abort_hw(tp, silent); - err = tg3_chip_reset(tp); - - tg3_write_sig_legacy(tp, RESET_KIND_SHUTDOWN); -@@ -3937,7 +4237,7 @@ static int tg3_halt_cpu(struct tg3 *tp, - int i; - - if (offset == TX_CPU_BASE && -- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) -+ (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) - BUG(); - - if (offset == RX_CPU_BASE) { -@@ -3991,14 +4291,14 @@ static int tg3_load_firmware_cpu(struct - void (*write_op)(struct tg3 *, u32, u32); - - if (cpu_base == TX_CPU_BASE && -- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { -+ (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { - printk(KERN_ERR PFX "tg3_load_firmware_cpu: Trying to load " - "TX cpu firmware on %s which is 5705.\n", - tp->dev->name); - return -EINVAL; - } - -- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) -+ if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) - write_op = tg3_write_mem; - else - write_op = tg3_write_indirect_reg32; -@@ -4399,7 +4699,7 @@ static u32 tg3TsoFwText[(TG3_TSO_FW_TEXT - 0xac470014, 0xac4a0018, 0x03e00008, 0xac4b001c, 0x00000000, 0x00000000, - }; - --u32 tg3TsoFwRodata[] = { -+static u32 tg3TsoFwRodata[] = { - 0x4d61696e, 0x43707542, 0x00000000, 0x4d61696e, 0x43707541, 0x00000000, - 0x00000000, 0x00000000, 0x73746b6f, 0x66666c64, 0x496e0000, 0x73746b6f, - 0x66662a2a, 0x00000000, 0x53774576, 0x656e7430, 0x00000000, 0x00000000, -@@ -4407,7 +4707,7 @@ u32 tg3TsoFwRodata[] = { - 0x00000000, - }; - --u32 tg3TsoFwData[] = { -+static u32 tg3TsoFwData[] = { - 0x00000000, 0x73746b6f, 0x66666c64, 0x5f76312e, 0x362e3000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, -@@ -4588,14 +4888,14 @@ static u32 tg3Tso5FwText[(TG3_TSO5_FW_TE - 0x00000000, 0x00000000, 0x00000000, - }; - --u32 tg3Tso5FwRodata[(TG3_TSO5_FW_RODATA_LEN / 4) + 1] = { -+static u32 tg3Tso5FwRodata[(TG3_TSO5_FW_RODATA_LEN / 4) + 1] = { - 0x4d61696e, 0x43707542, 0x00000000, 0x4d61696e, 0x43707541, 0x00000000, - 0x00000000, 0x00000000, 0x73746b6f, 0x66666c64, 0x00000000, 0x00000000, - 0x73746b6f, 0x66666c64, 0x00000000, 0x00000000, 0x66617461, 0x6c457272, - 0x00000000, 0x00000000, 0x00000000, - }; - --u32 tg3Tso5FwData[(TG3_TSO5_FW_DATA_LEN / 4) + 1] = { -+static u32 tg3Tso5FwData[(TG3_TSO5_FW_DATA_LEN / 4) + 1] = { - 0x00000000, 0x73746b6f, 0x66666c64, 0x5f76312e, 0x322e3000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, - }; -@@ -4607,7 +4907,7 @@ static int tg3_load_tso_firmware(struct - unsigned long cpu_base, cpu_scratch_base, cpu_scratch_size; - int err, i; - -- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) -+ if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) - return 0; - - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { -@@ -4691,9 +4991,8 @@ static void __tg3_set_mac_addr(struct tg - tw32(MAC_ADDR_0_LOW + (i * 8), addr_low); - } - -- if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 && -- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701 && -- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) { -+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 || -+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) { - for (i = 0; i < 12; i++) { - tw32(MAC_EXTADDR_0_HIGH + (i * 8), addr_high); - tw32(MAC_EXTADDR_0_LOW + (i * 8), addr_low); -@@ -4739,7 +5038,7 @@ static void tg3_set_bdinfo(struct tg3 *t - (bdinfo_addr + TG3_BDINFO_MAXLEN_FLAGS), - maxlen_flags); - -- if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) -+ if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) - tg3_write_mem(tp, - (bdinfo_addr + TG3_BDINFO_NIC_ADDR), - nic_addr); -@@ -4760,9 +5059,7 @@ static int tg3_reset_hw(struct tg3 *tp) - tg3_write_sig_pre_reset(tp, RESET_KIND_INIT); - - if (tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) { -- err = tg3_abort_hw(tp); -- if (err) -- return err; -+ tg3_abort_hw(tp, 1); - } - - err = tg3_chip_reset(tp); -@@ -4810,10 +5107,7 @@ static int tg3_reset_hw(struct tg3 *tp) - GRC_MODE_4X_NIC_SEND_RINGS | - GRC_MODE_NO_TX_PHDR_CSUM | - GRC_MODE_NO_RX_PHDR_CSUM); -- if (tp->tg3_flags & TG3_FLAG_HOST_TXDS) -- tp->grc_mode |= GRC_MODE_HOST_SENDBDS; -- else -- tp->grc_mode |= GRC_MODE_4X_NIC_SEND_RINGS; -+ 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) -@@ -4830,7 +5124,7 @@ static int tg3_reset_hw(struct tg3 *tp) - tw32(GRC_MISC_CFG, val); - - /* Initialize MBUF/DESC pool. */ -- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) { -+ if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) { - /* Do nothing. */ - } else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) { - tw32(BUFMGR_MB_POOL_ADDR, NIC_SRAM_MBUF_POOL_BASE); -@@ -4920,8 +5214,7 @@ static int tg3_reset_hw(struct tg3 *tp) - /* Don't even try to program the JUMBO/MINI buffer descriptor - * configs on 5705. - */ -- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 || -- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) { -+ 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 { -@@ -4953,8 +5246,7 @@ static int tg3_reset_hw(struct tg3 *tp) - /* There is only one send ring on 5705/5750, no need to explicitly - * disable the others. - */ -- if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705 && -- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750) { -+ if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { - /* Clear out send RCB ring in SRAM. */ - for (i = NIC_SRAM_SEND_RCB; i < NIC_SRAM_RCV_RET_RCB; i += TG3_BDINFO_SIZE) - tg3_write_mem(tp, i + TG3_BDINFO_MAXLEN_FLAGS, -@@ -4966,24 +5258,16 @@ static int tg3_reset_hw(struct tg3 *tp) - tw32_mailbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW, 0); - tw32_tx_mbox(MAILBOX_SNDNIC_PROD_IDX_0 + TG3_64BIT_REG_LOW, 0); - -- if (tp->tg3_flags & TG3_FLAG_HOST_TXDS) { -- tg3_set_bdinfo(tp, NIC_SRAM_SEND_RCB, -- tp->tx_desc_mapping, -- (TG3_TX_RING_SIZE << -- BDINFO_FLAGS_MAXLEN_SHIFT), -- NIC_SRAM_TX_BUFFER_DESC); -- } else { -- tg3_set_bdinfo(tp, NIC_SRAM_SEND_RCB, -- 0, -- BDINFO_FLAGS_DISABLED, -- NIC_SRAM_TX_BUFFER_DESC); -- } -+ tg3_set_bdinfo(tp, NIC_SRAM_SEND_RCB, -+ tp->tx_desc_mapping, -+ (TG3_TX_RING_SIZE << -+ BDINFO_FLAGS_MAXLEN_SHIFT), -+ NIC_SRAM_TX_BUFFER_DESC); - - /* There is only one receive return ring on 5705/5750, no need - * to explicitly disable the others. - */ -- if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705 && -- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750) { -+ if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { - for (i = NIC_SRAM_RCV_RET_RCB; i < NIC_SRAM_STATS_BLK; - i += TG3_BDINFO_SIZE) { - tg3_write_mem(tp, i + TG3_BDINFO_MAXLEN_FLAGS, -@@ -5037,6 +5321,8 @@ static int tg3_reset_hw(struct tg3 *tp) - RDMAC_MODE_LNGREAD_ENAB); - if (tp->tg3_flags & TG3_FLAG_SPLIT_MODE) - rdmac_mode |= RDMAC_MODE_SPLIT_ENABLE; -+ -+ /* If statement applies to 5705 and 5750 PCI devices only */ - 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)) { -@@ -5050,8 +5336,11 @@ static int tg3_reset_hw(struct tg3 *tp) - } - } - -+ if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) -+ rdmac_mode |= RDMAC_MODE_FIFO_LONG_BURST; -+ - #if TG3_TSO_SUPPORT != 0 -- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) -+ if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) - rdmac_mode |= (1 << 27); - #endif - -@@ -5082,8 +5371,7 @@ static int tg3_reset_hw(struct tg3 *tp) - tw32(HOSTCC_TXCOL_TICKS, LOW_TXCOL_TICKS); - tw32(HOSTCC_RXMAX_FRAMES, 1); - tw32(HOSTCC_TXMAX_FRAMES, LOW_RXMAX_FRAMES); -- if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705 && -- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750) { -+ if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { - tw32(HOSTCC_RXCOAL_TICK_INT, 0); - tw32(HOSTCC_TXCOAL_TICK_INT, 0); - } -@@ -5096,8 +5384,7 @@ static int tg3_reset_hw(struct tg3 *tp) - tw32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_LOW, - ((u64) tp->status_mapping & 0xffffffff)); - -- if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705 && -- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750) { -+ if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { - /* Status/statistics block address. See tg3_timer, - * the tg3_periodic_fetch_stats call there, and - * tg3_get_stats to see how this works for 5705/5750 chips. -@@ -5116,8 +5403,7 @@ static int tg3_reset_hw(struct tg3 *tp) - - tw32(RCVCC_MODE, RCVCC_MODE_ENABLE | RCVCC_MODE_ATTN_ENABLE); - tw32(RCVLPC_MODE, RCVLPC_MODE_ENABLE); -- if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705 && -- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750) -+ if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) - tw32(RCVLSC_MODE, RCVLSC_MODE_ENABLE | RCVLSC_MODE_ATTN_ENABLE); - - /* Clear statistics/status block in chip, and status block in ram. */ -@@ -5134,18 +5420,35 @@ static int tg3_reset_hw(struct tg3 *tp) - tw32_f(MAC_MODE, tp->mac_mode | MAC_MODE_RXSTAT_CLEAR | MAC_MODE_TXSTAT_CLEAR); - udelay(40); - -- tp->grc_local_ctrl = GRC_LCLCTRL_INT_ON_ATTN | GRC_LCLCTRL_AUTO_SEEPROM; -- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) -+ /* tp->grc_local_ctrl is partially set up during tg3_get_invariants(). -+ * If TG3_FLAG_EEPROM_WRITE_PROT is set, we should read the -+ * register to preserve the GPIO settings for LOMs. The GPIOs, -+ * whether used as inputs or outputs, are set by boot code after -+ * reset. -+ */ -+ if (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) { -+ u32 gpio_mask; -+ -+ gpio_mask = GRC_LCLCTRL_GPIO_OE0 | GRC_LCLCTRL_GPIO_OE2 | -+ GRC_LCLCTRL_GPIO_OUTPUT0 | GRC_LCLCTRL_GPIO_OUTPUT2; -+ -+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752) -+ gpio_mask |= GRC_LCLCTRL_GPIO_OE3 | -+ GRC_LCLCTRL_GPIO_OUTPUT3; -+ -+ tp->grc_local_ctrl |= tr32(GRC_LOCAL_CTRL) & gpio_mask; -+ -+ /* GPIO1 must be driven high for eeprom write protect */ - tp->grc_local_ctrl |= (GRC_LCLCTRL_GPIO_OE1 | - GRC_LCLCTRL_GPIO_OUTPUT1); -+ } - tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl); - udelay(100); - - tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0); - tr32(MAILBOX_INTERRUPT_0); - -- if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705 && -- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750) { -+ if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { - tw32_f(DMAC_MODE, DMAC_MODE_ENABLE); - udelay(40); - } -@@ -5156,6 +5459,7 @@ static int tg3_reset_hw(struct tg3 *tp) - WDMAC_MODE_FIFOURUN_ENAB | WDMAC_MODE_FIFOOREAD_ENAB | - WDMAC_MODE_LNGREAD_ENAB); - -+ /* If statement applies to 5705 and 5750 PCI devices only */ - 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) { -@@ -5192,8 +5496,7 @@ static int tg3_reset_hw(struct tg3 *tp) - udelay(40); - - tw32(RCVDCC_MODE, RCVDCC_MODE_ENABLE | RCVDCC_MODE_ATTN_ENABLE); -- if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705 && -- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750) -+ if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) - tw32(MBFREE_MODE, MBFREE_MODE_ENABLE); - tw32(SNDDATAC_MODE, SNDDATAC_MODE_ENABLE); - tw32(SNDBDC_MODE, SNDBDC_MODE_ENABLE | SNDBDC_MODE_ATTN_ENABLE); -@@ -5201,7 +5504,7 @@ static int tg3_reset_hw(struct tg3 *tp) - tw32(RCVDBDI_MODE, RCVDBDI_MODE_ENABLE | RCVDBDI_MODE_INV_RING_SZ); - tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE); - #if TG3_TSO_SUPPORT != 0 -- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) -+ if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) - tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE | 0x8); - #endif - tw32(SNDBDI_MODE, SNDBDI_MODE_ENABLE | SNDBDI_MODE_ATTN_ENABLE); -@@ -5243,16 +5546,18 @@ static int tg3_reset_hw(struct tg3 *tp) - tw32(MAC_LED_CTRL, tp->led_ctrl); - - tw32(MAC_MI_STAT, MAC_MI_STAT_LNKSTAT_ATTN_ENAB); -- if (tp->phy_id == PHY_ID_SERDES) { -+ if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) { - tw32_f(MAC_RX_MODE, RX_MODE_RESET); - udelay(10); - } - tw32_f(MAC_RX_MODE, tp->rx_mode); - udelay(10); - -- if (tp->phy_id == PHY_ID_SERDES) { -- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) { -+ if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) { -+ if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) && -+ !(tp->tg3_flags2 & TG3_FLG2_SERDES_PREEMPHASIS)) { - /* Set drive transmission level to 1.2V */ -+ /* only if the signal pre-emphasis bit is not set */ - val = tr32(MAC_SERDES_CFG); - val &= 0xfffff000; - val |= 0x880; -@@ -5268,22 +5573,8 @@ static int tg3_reset_hw(struct tg3 *tp) - tw32_f(MAC_LOW_WMARK_MAX_RX_FRAME, 2); - - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 && -- tp->phy_id == PHY_ID_SERDES) { -- /* Enable hardware link auto-negotiation */ -- u32 digctrl, txctrl; -- -- digctrl = SG_DIG_USING_HW_AUTONEG | SG_DIG_CRC16_CLEAR_N | -- SG_DIG_LOCAL_DUPLEX_STATUS | SG_DIG_LOCAL_LINK_STATUS | -- (2 << SG_DIG_SPEED_STATUS_SHIFT) | SG_DIG_FIBER_MODE | -- SG_DIG_GBIC_ENABLE; -- -- txctrl = tr32(MAC_SERDES_CFG); -- tw32_f(MAC_SERDES_CFG, txctrl | MAC_SERDES_CFG_EDGE_SELECT); -- tw32_f(SG_DIG_CTRL, digctrl | SG_DIG_SOFT_RESET); -- tr32(SG_DIG_CTRL); -- udelay(5); -- tw32_f(SG_DIG_CTRL, digctrl); -- -+ (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) { -+ /* Use hardware link auto-negotiation */ - tp->tg3_flags2 |= TG3_FLG2_HW_AUTONEG; - } - -@@ -5291,13 +5582,14 @@ static int tg3_reset_hw(struct tg3 *tp) - if (err) - return err; - -- if (tp->phy_id != PHY_ID_SERDES) { -+ if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) { - u32 tmp; - - /* Clear CRC stats. */ -- tg3_readphy(tp, 0x1e, &tmp); -- tg3_writephy(tp, 0x1e, tmp | 0x8000); -- tg3_readphy(tp, 0x14, &tmp); -+ if (!tg3_readphy(tp, 0x1e, &tmp)) { -+ tg3_writephy(tp, 0x1e, tmp | 0x8000); -+ tg3_readphy(tp, 0x14, &tmp); -+ } - } - - __tg3_set_rx_mode(tp->dev); -@@ -5308,8 +5600,7 @@ static int tg3_reset_hw(struct tg3 *tp) - tw32(MAC_RCV_RULE_1, 0x86000004 & RCV_RULE_DISABLE_MASK); - tw32(MAC_RCV_VALUE_1, 0xffffffff & RCV_RULE_DISABLE_MASK); - -- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 || -- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) -+ if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) - limit = 8; - else - limit = 16; -@@ -5453,8 +5744,7 @@ static void tg3_timer(unsigned long __op - return; - } - -- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 || -- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) -+ if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) - tg3_periodic_fetch_stats(tp); - - /* This part only runs once per second. */ -@@ -5483,7 +5773,8 @@ static void tg3_timer(unsigned long __op - need_setup = 1; - } - if (! netif_carrier_ok(tp->dev) && -- (mac_stat & MAC_STATUS_PCS_SYNCED)) { -+ (mac_stat & (MAC_STATUS_PCS_SYNCED | -+ MAC_STATUS_SIGNAL_DET))) { - need_setup = 1; - } - if (need_setup) { -@@ -5522,11 +5813,123 @@ static void tg3_timer(unsigned long __op - add_timer(&tp->timer); - } - --static int tg3_open(struct net_device *dev) -+static int tg3_test_interrupt(struct tg3 *tp) - { -- struct tg3 *tp = netdev_priv(dev); -- int err; -- -+ struct net_device *dev = tp->dev; -+ int err, i; -+ u32 int_mbox = 0; -+ -+ tg3_disable_ints(tp); -+ -+ free_irq(tp->pdev->irq, dev); -+ -+ err = request_irq(tp->pdev->irq, tg3_test_isr, -+ SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev); -+ if (err) -+ return err; -+ -+ tg3_enable_ints(tp); -+ -+ tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE | -+ HOSTCC_MODE_NOW); -+ -+ for (i = 0; i < 5; i++) { -+ int_mbox = tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); -+ if (int_mbox != 0) -+ break; -+ msleep(10); -+ } -+ -+ tg3_disable_ints(tp); -+ -+ free_irq(tp->pdev->irq, dev); -+ -+ if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) -+ err = request_irq(tp->pdev->irq, tg3_msi, -+ SA_SAMPLE_RANDOM, dev->name, dev); -+ else -+ err = request_irq(tp->pdev->irq, tg3_interrupt, -+ SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev); -+ -+ if (err) -+ return err; -+ -+ if (int_mbox != 0) -+ return 0; -+ -+ return -EIO; -+} -+ -+/* Returns 0 if MSI test succeeds or MSI test fails and INTx mode is -+ * successfully restored -+ */ -+static int tg3_test_msi(struct tg3 *tp) -+{ -+ struct net_device *dev = tp->dev; -+ int err; -+ u16 pci_cmd; -+ -+ if (!(tp->tg3_flags2 & TG3_FLG2_USING_MSI)) -+ return 0; -+ -+ /* Turn off SERR reporting in case MSI terminates with Master -+ * Abort. -+ */ -+ pci_read_config_word(tp->pdev, PCI_COMMAND, &pci_cmd); -+ pci_write_config_word(tp->pdev, PCI_COMMAND, -+ pci_cmd & ~PCI_COMMAND_SERR); -+ -+ err = tg3_test_interrupt(tp); -+ -+ pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd); -+ -+ if (!err) -+ return 0; -+ -+ /* other failures */ -+ if (err != -EIO) -+ return err; -+ -+ /* MSI test failed, go back to INTx mode */ -+ printk(KERN_WARNING PFX "%s: No interrupt was generated using MSI, " -+ "switching to INTx mode. Please report this failure to " -+ "the PCI maintainer and include system chipset information.\n", -+ tp->dev->name); -+ -+ free_irq(tp->pdev->irq, dev); -+ pci_disable_msi(tp->pdev); -+ -+ tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI; -+ -+ err = request_irq(tp->pdev->irq, tg3_interrupt, -+ SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev); -+ -+ if (err) -+ return err; -+ -+ /* Need to reset the chip because the MSI cycle may have terminated -+ * with Master Abort. -+ */ -+ spin_lock_irq(&tp->lock); -+ spin_lock(&tp->tx_lock); -+ -+ tg3_halt(tp, 1); -+ err = tg3_init_hw(tp); -+ -+ spin_unlock(&tp->tx_lock); -+ spin_unlock_irq(&tp->lock); -+ -+ if (err) -+ free_irq(tp->pdev->irq, dev); -+ -+ return err; -+} -+ -+static int tg3_open(struct net_device *dev) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ int err; -+ - spin_lock_irq(&tp->lock); - spin_lock(&tp->tx_lock); - -@@ -5536,17 +5939,36 @@ static int tg3_open(struct net_device *d - spin_unlock(&tp->tx_lock); - spin_unlock_irq(&tp->lock); - -- /* If you move this call, make sure TG3_FLAG_HOST_TXDS in -- * tp->tg3_flags is accurate at that new place. -+ /* The placement of this call is tied -+ * to the setup and use of Host TX descriptors. - */ - err = tg3_alloc_consistent(tp); - if (err) - return err; - -- err = request_irq(dev->irq, tg3_interrupt, -- SA_SHIRQ, dev->name, dev); -+ if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) && -+ (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5750_AX) && -+ (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5750_BX)) { -+ if (pci_enable_msi(tp->pdev) == 0) { -+ u32 msi_mode; -+ -+ msi_mode = tr32(MSGINT_MODE); -+ tw32(MSGINT_MODE, msi_mode | MSGINT_MODE_ENABLE); -+ tp->tg3_flags2 |= TG3_FLG2_USING_MSI; -+ } -+ } -+ if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) -+ err = request_irq(tp->pdev->irq, tg3_msi, -+ SA_SAMPLE_RANDOM, dev->name, dev); -+ else -+ err = request_irq(tp->pdev->irq, tg3_interrupt, -+ SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev); - - if (err) { -+ if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) { -+ pci_disable_msi(tp->pdev); -+ tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI; -+ } - tg3_free_consistent(tp); - return err; - } -@@ -5556,7 +5978,7 @@ static int tg3_open(struct net_device *d - - err = tg3_init_hw(tp); - if (err) { -- tg3_halt(tp); -+ tg3_halt(tp, 1); - tg3_free_rings(tp); - } else { - tp->timer_offset = HZ / 10; -@@ -5567,23 +5989,47 @@ static int tg3_open(struct net_device *d - tp->timer.expires = jiffies + tp->timer_offset; - tp->timer.data = (unsigned long) tp; - tp->timer.function = tg3_timer; -- add_timer(&tp->timer); -- -- tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; - } - - spin_unlock(&tp->tx_lock); - spin_unlock_irq(&tp->lock); - - if (err) { -- free_irq(dev->irq, dev); -+ free_irq(tp->pdev->irq, dev); -+ if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) { -+ pci_disable_msi(tp->pdev); -+ tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI; -+ } - tg3_free_consistent(tp); - return err; - } - -+ if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) { -+ err = tg3_test_msi(tp); -+ if (err) { -+ spin_lock_irq(&tp->lock); -+ spin_lock(&tp->tx_lock); -+ -+ if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) { -+ pci_disable_msi(tp->pdev); -+ tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI; -+ } -+ tg3_halt(tp, 1); -+ tg3_free_rings(tp); -+ tg3_free_consistent(tp); -+ -+ spin_unlock(&tp->tx_lock); -+ spin_unlock_irq(&tp->lock); -+ -+ return err; -+ } -+ } -+ - spin_lock_irq(&tp->lock); - spin_lock(&tp->tx_lock); - -+ add_timer(&tp->timer); -+ tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; - tg3_enable_ints(tp); - - spin_unlock(&tp->tx_lock); -@@ -5841,7 +6287,7 @@ static int tg3_close(struct net_device * - - tg3_disable_ints(tp); - -- tg3_halt(tp); -+ tg3_halt(tp, 1); - tg3_free_rings(tp); - tp->tg3_flags &= - ~(TG3_FLAG_INIT_COMPLETE | -@@ -5851,7 +6297,11 @@ static int tg3_close(struct net_device * - spin_unlock(&tp->tx_lock); - spin_unlock_irq(&tp->lock); - -- free_irq(dev->irq, dev); -+ free_irq(tp->pdev->irq, dev); -+ if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) { -+ pci_disable_msi(tp->pdev); -+ tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI; -+ } - - memcpy(&tp->net_stats_prev, tg3_get_stats(tp->dev), - sizeof(tp->net_stats_prev)); -@@ -5879,16 +6329,18 @@ static unsigned long calc_crc_errors(str - { - struct tg3_hw_stats *hw_stats = tp->hw_stats; - -- if (tp->phy_id != PHY_ID_SERDES && -+ if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) && - (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)) { - unsigned long flags; - u32 val; - - spin_lock_irqsave(&tp->lock, flags); -- tg3_readphy(tp, 0x1e, &val); -- tg3_writephy(tp, 0x1e, val | 0x8000); -- tg3_readphy(tp, 0x14, &val); -+ if (!tg3_readphy(tp, 0x1e, &val)) { -+ tg3_writephy(tp, 0x1e, val | 0x8000); -+ tg3_readphy(tp, 0x14, &val); -+ } else -+ val = 0; - spin_unlock_irqrestore(&tp->lock, flags); - - tp->phy_crc_errors += val; -@@ -6152,7 +6604,9 @@ static void tg3_set_rx_mode(struct net_d - struct tg3 *tp = netdev_priv(dev); - - spin_lock_irq(&tp->lock); -+ spin_lock(&tp->tx_lock); - __tg3_set_rx_mode(dev); -+ spin_unlock(&tp->tx_lock); - spin_unlock_irq(&tp->lock); - } - -@@ -6232,14 +6686,16 @@ do { p = (u32 *)(orig_p + (reg)); \ - - static int tg3_get_eeprom_len(struct net_device *dev) - { -- return EEPROM_CHIP_SIZE; -+ struct tg3 *tp = netdev_priv(dev); -+ -+ return tp->nvram_size; - } - --static int __devinit tg3_nvram_read_using_eeprom(struct tg3 *tp, -- u32 offset, u32 *val); -+static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val); -+ - static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data) - { -- struct tg3 *tp = dev->priv; -+ struct tg3 *tp = netdev_priv(dev); - int ret; - u8 *pd; - u32 i, offset, len, val, b_offset, b_count; -@@ -6248,10 +6704,7 @@ static int tg3_get_eeprom(struct net_dev - len = eeprom->len; - eeprom->len = 0; - -- ret = tg3_nvram_read_using_eeprom(tp, 0, &eeprom->magic); -- if (ret) -- return ret; -- eeprom->magic = swab32(eeprom->magic); -+ eeprom->magic = TG3_EEPROM_MAGIC; - - if (offset & 3) { - /* adjustments to start on required 4 byte boundary */ -@@ -6261,9 +6714,10 @@ static int tg3_get_eeprom(struct net_dev - /* i.e. offset=1 len=2 */ - b_count = len; - } -- ret = tg3_nvram_read_using_eeprom(tp, offset-b_offset, &val); -+ ret = tg3_nvram_read(tp, offset-b_offset, &val); - if (ret) - return ret; -+ val = cpu_to_le32(val); - memcpy(data, ((char*)&val) + b_offset, b_count); - len -= b_count; - offset += b_count; -@@ -6273,12 +6727,13 @@ static int tg3_get_eeprom(struct net_dev - /* read bytes upto the last 4 byte boundary */ - pd = &data[eeprom->len]; - for (i = 0; i < (len - (len & 3)); i += 4) { -- ret = tg3_nvram_read_using_eeprom(tp, offset + i, -- (u32*)(pd + i)); -+ ret = tg3_nvram_read(tp, offset + i, &val); - if (ret) { - eeprom->len += i; - return ret; - } -+ val = cpu_to_le32(val); -+ memcpy(pd + i, &val, 4); - } - eeprom->len += i; - -@@ -6287,30 +6742,85 @@ static int tg3_get_eeprom(struct net_dev - pd = &data[eeprom->len]; - b_count = len & 3; - b_offset = offset + len - b_count; -- ret = tg3_nvram_read_using_eeprom(tp, b_offset, &val); -+ ret = tg3_nvram_read(tp, b_offset, &val); - if (ret) - return ret; -+ val = cpu_to_le32(val); - memcpy(pd, ((char*)&val), b_count); - eeprom->len += b_count; - } - return 0; - } - -+static int tg3_nvram_write_block(struct tg3 *tp, u32 offset, u32 len, u8 *buf); -+ -+static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data) -+{ -+ struct tg3 *tp = netdev_priv(dev); -+ int ret; -+ u32 offset, len, b_offset, odd_len, start, end; -+ u8 *buf; -+ -+ if (eeprom->magic != TG3_EEPROM_MAGIC) -+ return -EINVAL; -+ -+ offset = eeprom->offset; -+ len = eeprom->len; -+ -+ if ((b_offset = (offset & 3))) { -+ /* adjustments to start on required 4 byte boundary */ -+ ret = tg3_nvram_read(tp, offset-b_offset, &start); -+ if (ret) -+ return ret; -+ start = cpu_to_le32(start); -+ len += b_offset; -+ offset &= ~3; -+ if (len < 4) -+ len = 4; -+ } -+ -+ odd_len = 0; -+ if (len & 3) { -+ /* adjustments to end on required 4 byte boundary */ -+ odd_len = 1; -+ len = (len + 3) & ~3; -+ ret = tg3_nvram_read(tp, offset+len-4, &end); -+ if (ret) -+ return ret; -+ end = cpu_to_le32(end); -+ } -+ -+ buf = data; -+ if (b_offset || odd_len) { -+ buf = kmalloc(len, GFP_KERNEL); -+ if (buf == 0) -+ return -ENOMEM; -+ if (b_offset) -+ memcpy(buf, &start, 4); -+ if (odd_len) -+ memcpy(buf+len-4, &end, 4); -+ memcpy(buf + b_offset, data, eeprom->len); -+ } -+ -+ ret = tg3_nvram_write_block(tp, offset, len, buf); -+ -+ if (buf != data) -+ kfree(buf); -+ -+ return ret; -+} -+ - static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) - { - struct tg3 *tp = netdev_priv(dev); - -- if (!(tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) || -- tp->link_config.phy_is_low_power) -- return -EAGAIN; -- - cmd->supported = (SUPPORTED_Autoneg); - - if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) - cmd->supported |= (SUPPORTED_1000baseT_Half | - SUPPORTED_1000baseT_Full); - -- if (tp->phy_id != PHY_ID_SERDES) -+ if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) - cmd->supported |= (SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_10baseT_Half | -@@ -6320,8 +6830,10 @@ static int tg3_get_settings(struct net_d - cmd->supported |= SUPPORTED_FIBRE; - - cmd->advertising = tp->link_config.advertising; -- cmd->speed = tp->link_config.active_speed; -- cmd->duplex = tp->link_config.active_duplex; -+ 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; -@@ -6335,11 +6847,7 @@ static int tg3_set_settings(struct net_d - { - struct tg3 *tp = netdev_priv(dev); - -- if (!(tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) || -- tp->link_config.phy_is_low_power) -- return -EAGAIN; -- -- if (tp->phy_id == PHY_ID_SERDES) { -+ if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) { - /* These are the only valid advertisement bits allowed. */ - if (cmd->autoneg == AUTONEG_ENABLE && - (cmd->advertising & ~(ADVERTISED_1000baseT_Half | -@@ -6363,7 +6871,9 @@ static int tg3_set_settings(struct net_d - tp->link_config.duplex = cmd->duplex; - } - -- tg3_setup_phy(tp, 1); -+ if (netif_running(dev)) -+ tg3_setup_phy(tp, 1); -+ - spin_unlock(&tp->tx_lock); - spin_unlock_irq(&tp->lock); - -@@ -6397,7 +6907,7 @@ static int tg3_set_wol(struct net_device - if (wol->wolopts & ~WAKE_MAGIC) - return -EINVAL; - if ((wol->wolopts & WAKE_MAGIC) && -- tp->phy_id == PHY_ID_SERDES && -+ tp->tg3_flags2 & TG3_FLG2_PHY_SERDES && - !(tp->tg3_flags & TG3_FLAG_SERDES_WOL_CAP)) - return -EINVAL; - -@@ -6443,11 +6953,14 @@ static int tg3_nway_reset(struct net_dev - u32 bmcr; - int r; - -+ if (!netif_running(dev)) -+ return -EAGAIN; -+ - spin_lock_irq(&tp->lock); -- tg3_readphy(tp, MII_BMCR, &bmcr); -- tg3_readphy(tp, MII_BMCR, &bmcr); - r = -EINVAL; -- if (bmcr & BMCR_ANENABLE) { -+ tg3_readphy(tp, MII_BMCR, &bmcr); -+ if (!tg3_readphy(tp, MII_BMCR, &bmcr) && -+ (bmcr & BMCR_ANENABLE)) { - tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANRESTART); - r = 0; - } -@@ -6479,7 +6992,9 @@ static int tg3_set_ringparam(struct net_ - (ering->tx_pending > TG3_TX_RING_SIZE - 1)) - return -EINVAL; - -- tg3_netif_stop(tp); -+ if (netif_running(dev)) -+ tg3_netif_stop(tp); -+ - spin_lock_irq(&tp->lock); - spin_lock(&tp->tx_lock); - -@@ -6491,12 +7006,14 @@ static int tg3_set_ringparam(struct net_ - tp->rx_jumbo_pending = ering->rx_jumbo_pending; - tp->tx_pending = ering->tx_pending; - -- tg3_halt(tp); -- tg3_init_hw(tp); -- netif_wake_queue(tp->dev); -+ if (netif_running(dev)) { -+ tg3_halt(tp, 1); -+ tg3_init_hw(tp); -+ tg3_netif_start(tp); -+ } -+ - spin_unlock(&tp->tx_lock); - spin_unlock_irq(&tp->lock); -- tg3_netif_start(tp); - - return 0; - } -@@ -6506,15 +7023,17 @@ static void tg3_get_pauseparam(struct ne - struct tg3 *tp = netdev_priv(dev); - - epause->autoneg = (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG) != 0; -- epause->rx_pause = (tp->tg3_flags & TG3_FLAG_PAUSE_RX) != 0; -- epause->tx_pause = (tp->tg3_flags & TG3_FLAG_PAUSE_TX) != 0; -+ epause->rx_pause = (tp->tg3_flags & TG3_FLAG_RX_PAUSE) != 0; -+ epause->tx_pause = (tp->tg3_flags & TG3_FLAG_TX_PAUSE) != 0; - } - - static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) - { - struct tg3 *tp = netdev_priv(dev); - -- tg3_netif_stop(tp); -+ if (netif_running(dev)) -+ tg3_netif_stop(tp); -+ - spin_lock_irq(&tp->lock); - spin_lock(&tp->tx_lock); - if (epause->autoneg) -@@ -6522,18 +7041,21 @@ static int tg3_set_pauseparam(struct net - else - tp->tg3_flags &= ~TG3_FLAG_PAUSE_AUTONEG; - if (epause->rx_pause) -- tp->tg3_flags |= TG3_FLAG_PAUSE_RX; -+ tp->tg3_flags |= TG3_FLAG_RX_PAUSE; - else -- tp->tg3_flags &= ~TG3_FLAG_PAUSE_RX; -+ tp->tg3_flags &= ~TG3_FLAG_RX_PAUSE; - if (epause->tx_pause) -- tp->tg3_flags |= TG3_FLAG_PAUSE_TX; -+ tp->tg3_flags |= TG3_FLAG_TX_PAUSE; - else -- tp->tg3_flags &= ~TG3_FLAG_PAUSE_TX; -- tg3_halt(tp); -- tg3_init_hw(tp); -+ tp->tg3_flags &= ~TG3_FLAG_TX_PAUSE; -+ -+ if (netif_running(dev)) { -+ tg3_halt(tp, 1); -+ tg3_init_hw(tp); -+ tg3_netif_start(tp); -+ } - spin_unlock(&tp->tx_lock); - spin_unlock_irq(&tp->lock); -- tg3_netif_start(tp); - - return 0; - } -@@ -6602,7 +7124,7 @@ static void tg3_get_strings (struct net_ - static void tg3_get_ethtool_stats (struct net_device *dev, - struct ethtool_stats *estats, u64 *tmp_stats) - { -- struct tg3 *tp = dev->priv; -+ struct tg3 *tp = netdev_priv(dev); - memcpy(tmp_stats, tg3_get_estats(tp), sizeof(tp->estats)); - } - -@@ -6620,7 +7142,7 @@ static int tg3_ioctl(struct net_device * - case SIOCGMIIREG: { - u32 mii_regval; - -- if (tp->phy_id == PHY_ID_SERDES) -+ if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) - break; /* We have no PHY */ - - spin_lock_irq(&tp->lock); -@@ -6633,7 +7155,7 @@ static int tg3_ioctl(struct net_device * - } - - case SIOCSMIIREG: -- if (tp->phy_id == PHY_ID_SERDES) -+ if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) - break; /* We have no PHY */ - - if (!capable(CAP_NET_ADMIN)) -@@ -6696,6 +7218,7 @@ static struct ethtool_ops tg3_ethtool_op - .get_link = ethtool_op_get_link, - .get_eeprom_len = tg3_get_eeprom_len, - .get_eeprom = tg3_get_eeprom, -+ .set_eeprom = tg3_set_eeprom, - .get_ringparam = tg3_get_ringparam, - .set_ringparam = tg3_set_ringparam, - .get_pauseparam = tg3_get_pauseparam, -@@ -6715,12 +7238,170 @@ static struct ethtool_ops tg3_ethtool_op - .get_ethtool_stats = tg3_get_ethtool_stats, - }; - -+static void __devinit tg3_get_eeprom_size(struct tg3 *tp) -+{ -+ u32 cursize, val; -+ -+ tp->nvram_size = EEPROM_CHIP_SIZE; -+ -+ if (tg3_nvram_read(tp, 0, &val) != 0) -+ return; -+ -+ if (swab32(val) != TG3_EEPROM_MAGIC) -+ return; -+ -+ /* -+ * Size the chip by reading offsets at increasing powers of two. -+ * When we encounter our validation signature, we know the addressing -+ * has wrapped around, and thus have our chip size. -+ */ -+ cursize = 0x800; -+ -+ while (cursize < tp->nvram_size) { -+ if (tg3_nvram_read(tp, cursize, &val) != 0) -+ return; -+ -+ if (swab32(val) == TG3_EEPROM_MAGIC) -+ break; -+ -+ cursize <<= 1; -+ } -+ -+ tp->nvram_size = cursize; -+} -+ -+static void __devinit tg3_get_nvram_size(struct tg3 *tp) -+{ -+ u32 val; -+ -+ if (tg3_nvram_read(tp, 0xf0, &val) == 0) { -+ if (val != 0) { -+ tp->nvram_size = (val >> 16) * 1024; -+ return; -+ } -+ } -+ tp->nvram_size = 0x20000; -+} -+ -+static void __devinit tg3_get_nvram_info(struct tg3 *tp) -+{ -+ u32 nvcfg1; -+ -+ nvcfg1 = tr32(NVRAM_CFG1); -+ if (nvcfg1 & NVRAM_CFG1_FLASHIF_ENAB) { -+ tp->tg3_flags2 |= TG3_FLG2_FLASH; -+ } -+ else { -+ nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS; -+ tw32(NVRAM_CFG1, nvcfg1); -+ } -+ -+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) { -+ 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; -+ } -+ } -+ else { -+ tp->nvram_jedecnum = JEDEC_ATMEL; -+ tp->nvram_pagesize = ATMEL_AT45DB0X1B_PAGE_SIZE; -+ tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED; -+ } -+} -+ -+static void __devinit tg3_get_5752_nvram_info(struct tg3 *tp) -+{ -+ u32 nvcfg1; -+ -+ nvcfg1 = tr32(NVRAM_CFG1); -+ -+ /* NVRAM protection for TPM */ -+ if (nvcfg1 & (1 << 27)) -+ 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; -+ } -+ -+ 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; -+ } -+ } -+ else { -+ /* For eeprom, set pagesize to maximum eeprom size */ -+ tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE; -+ -+ nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS; -+ tw32(NVRAM_CFG1, nvcfg1); -+ } -+} -+ - /* Chips other than 5700/5701 use the NVRAM for fetching info. */ - static void __devinit tg3_nvram_init(struct tg3 *tp) - { - int j; - -- if (tp->tg3_flags2 & TG3_FLG2_SUN_5704) -+ if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) - return; - - tw32_f(GRC_EEPROM_ADDR, -@@ -6739,37 +7420,28 @@ static void __devinit tg3_nvram_init(str - - if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 && - GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) { -- u32 nvcfg1; -- -- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) { -- u32 nvaccess = tr32(NVRAM_ACCESS); -+ tp->tg3_flags |= TG3_FLAG_NVRAM; - -- tw32_f(NVRAM_ACCESS, nvaccess | ACCESS_ENABLE); -- } -+ tg3_enable_nvram_access(tp); - -- nvcfg1 = tr32(NVRAM_CFG1); -+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752) -+ tg3_get_5752_nvram_info(tp); -+ else -+ tg3_get_nvram_info(tp); - -- tp->tg3_flags |= TG3_FLAG_NVRAM; -- if (nvcfg1 & NVRAM_CFG1_FLASHIF_ENAB) { -- if (nvcfg1 & NVRAM_CFG1_BUFFERED_MODE) -- tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED; -- } else { -- nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS; -- tw32(NVRAM_CFG1, nvcfg1); -- } -+ tg3_get_nvram_size(tp); - -- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) { -- u32 nvaccess = tr32(NVRAM_ACCESS); -+ tg3_disable_nvram_access(tp); - -- tw32_f(NVRAM_ACCESS, nvaccess & ~ACCESS_ENABLE); -- } - } else { - tp->tg3_flags &= ~(TG3_FLAG_NVRAM | TG3_FLAG_NVRAM_BUFFERED); -+ -+ tg3_get_eeprom_size(tp); - } - } - --static int __devinit tg3_nvram_read_using_eeprom(struct tg3 *tp, -- u32 offset, u32 *val) -+static int tg3_nvram_read_using_eeprom(struct tg3 *tp, -+ u32 offset, u32 *val) - { - u32 tmp; - int i; -@@ -6802,62 +7474,318 @@ static int __devinit tg3_nvram_read_usin - return 0; - } - --static int __devinit tg3_nvram_read(struct tg3 *tp, -- u32 offset, u32 *val) -+#define NVRAM_CMD_TIMEOUT 10000 -+ -+static int tg3_nvram_exec_cmd(struct tg3 *tp, u32 nvram_cmd) - { - int i; - -- if (tp->tg3_flags2 & TG3_FLG2_SUN_5704) { -- printk(KERN_ERR PFX "Attempt to do nvram_read on Sun 5704\n"); -+ tw32(NVRAM_CMD, nvram_cmd); -+ for (i = 0; i < NVRAM_CMD_TIMEOUT; i++) { -+ udelay(10); -+ if (tr32(NVRAM_CMD) & NVRAM_CMD_DONE) { -+ udelay(10); -+ break; -+ } -+ } -+ if (i == NVRAM_CMD_TIMEOUT) { -+ return -EBUSY; -+ } -+ return 0; -+} -+ -+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); - -- if (tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) -- offset = ((offset / NVRAM_BUFFERED_PAGE_SIZE) << -- NVRAM_BUFFERED_PAGE_POS) + -- (offset % NVRAM_BUFFERED_PAGE_SIZE); -+ if ((tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) && -+ (tp->tg3_flags2 & TG3_FLG2_FLASH) && -+ (tp->nvram_jedecnum == JEDEC_ATMEL)) { -+ -+ offset = ((offset / tp->nvram_pagesize) << -+ ATMEL_AT45DB0X1B_PAGE_POS) + -+ (offset % tp->nvram_pagesize); -+ } - - if (offset > NVRAM_ADDR_MSK) - return -EINVAL; - - tg3_nvram_lock(tp); - -- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) { -- u32 nvaccess = tr32(NVRAM_ACCESS); -+ tg3_enable_nvram_access(tp); -+ -+ tw32(NVRAM_ADDR, offset); -+ ret = tg3_nvram_exec_cmd(tp, NVRAM_CMD_RD | NVRAM_CMD_GO | -+ NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_DONE); -+ -+ if (ret == 0) -+ *val = swab32(tr32(NVRAM_RDDATA)); -+ -+ tg3_nvram_unlock(tp); -+ -+ tg3_disable_nvram_access(tp); -+ -+ return ret; -+} -+ -+static int tg3_nvram_write_block_using_eeprom(struct tg3 *tp, -+ u32 offset, u32 len, u8 *buf) -+{ -+ int i, j, rc = 0; -+ u32 val; -+ -+ for (i = 0; i < len; i += 4) { -+ u32 addr, data; -+ -+ addr = offset + i; -+ -+ memcpy(&data, buf + i, 4); - -- tw32_f(NVRAM_ACCESS, nvaccess | ACCESS_ENABLE); -+ tw32(GRC_EEPROM_DATA, cpu_to_le32(data)); -+ -+ val = tr32(GRC_EEPROM_ADDR); -+ tw32(GRC_EEPROM_ADDR, val | EEPROM_ADDR_COMPLETE); -+ -+ val &= ~(EEPROM_ADDR_ADDR_MASK | EEPROM_ADDR_DEVID_MASK | -+ EEPROM_ADDR_READ); -+ tw32(GRC_EEPROM_ADDR, val | -+ (0 << EEPROM_ADDR_DEVID_SHIFT) | -+ (addr & EEPROM_ADDR_ADDR_MASK) | -+ EEPROM_ADDR_START | -+ EEPROM_ADDR_WRITE); -+ -+ for (j = 0; j < 10000; j++) { -+ val = tr32(GRC_EEPROM_ADDR); -+ -+ if (val & EEPROM_ADDR_COMPLETE) -+ break; -+ udelay(100); -+ } -+ if (!(val & EEPROM_ADDR_COMPLETE)) { -+ rc = -EBUSY; -+ break; -+ } - } - -- tw32(NVRAM_ADDR, offset); -- tw32(NVRAM_CMD, -- NVRAM_CMD_RD | NVRAM_CMD_GO | -- NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_DONE); -+ return rc; -+} - -- /* Wait for done bit to clear. */ -- for (i = 0; i < 1000; i++) { -- udelay(10); -- if (tr32(NVRAM_CMD) & NVRAM_CMD_DONE) { -- udelay(10); -- *val = swab32(tr32(NVRAM_RDDATA)); -+/* offset and length are dword aligned */ -+static int tg3_nvram_write_block_unbuffered(struct tg3 *tp, u32 offset, u32 len, -+ u8 *buf) -+{ -+ int ret = 0; -+ u32 pagesize = tp->nvram_pagesize; -+ u32 pagemask = pagesize - 1; -+ u32 nvram_cmd; -+ u8 *tmp; -+ -+ tmp = kmalloc(pagesize, GFP_KERNEL); -+ if (tmp == NULL) -+ return -ENOMEM; -+ -+ while (len) { -+ int j; -+ u32 phy_addr, page_off, size; -+ -+ phy_addr = offset & ~pagemask; -+ -+ for (j = 0; j < pagesize; j += 4) { -+ if ((ret = tg3_nvram_read(tp, phy_addr + j, -+ (u32 *) (tmp + j)))) -+ break; -+ } -+ if (ret) - break; -+ -+ page_off = offset & pagemask; -+ size = pagesize; -+ if (len < size) -+ size = len; -+ -+ len -= size; -+ -+ memcpy(tmp + page_off, buf, size); -+ -+ offset = offset + (pagesize - page_off); -+ -+ tg3_enable_nvram_access(tp); -+ -+ /* -+ * Before we can erase the flash page, we need -+ * to issue a special "write enable" command. -+ */ -+ nvram_cmd = NVRAM_CMD_WREN | NVRAM_CMD_GO | NVRAM_CMD_DONE; -+ -+ if (tg3_nvram_exec_cmd(tp, nvram_cmd)) -+ break; -+ -+ /* Erase the target page */ -+ tw32(NVRAM_ADDR, phy_addr); -+ -+ nvram_cmd = NVRAM_CMD_GO | NVRAM_CMD_DONE | NVRAM_CMD_WR | -+ NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_ERASE; -+ -+ if (tg3_nvram_exec_cmd(tp, nvram_cmd)) -+ break; -+ -+ /* Issue another write enable to start the write. */ -+ nvram_cmd = NVRAM_CMD_WREN | NVRAM_CMD_GO | NVRAM_CMD_DONE; -+ -+ if (tg3_nvram_exec_cmd(tp, nvram_cmd)) -+ break; -+ -+ for (j = 0; j < pagesize; j += 4) { -+ u32 data; -+ -+ data = *((u32 *) (tmp + j)); -+ tw32(NVRAM_WRDATA, cpu_to_be32(data)); -+ -+ tw32(NVRAM_ADDR, phy_addr + j); -+ -+ nvram_cmd = NVRAM_CMD_GO | NVRAM_CMD_DONE | -+ NVRAM_CMD_WR; -+ -+ if (j == 0) -+ nvram_cmd |= NVRAM_CMD_FIRST; -+ else if (j == (pagesize - 4)) -+ nvram_cmd |= NVRAM_CMD_LAST; -+ -+ if ((ret = tg3_nvram_exec_cmd(tp, nvram_cmd))) -+ break; - } -+ if (ret) -+ break; - } - -- tg3_nvram_unlock(tp); -+ nvram_cmd = NVRAM_CMD_WRDI | NVRAM_CMD_GO | NVRAM_CMD_DONE; -+ tg3_nvram_exec_cmd(tp, nvram_cmd); - -- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) { -- u32 nvaccess = tr32(NVRAM_ACCESS); -+ kfree(tmp); -+ -+ return ret; -+} -+ -+/* offset and length are dword aligned */ -+static int tg3_nvram_write_block_buffered(struct tg3 *tp, u32 offset, u32 len, -+ u8 *buf) -+{ -+ int i, ret = 0; -+ -+ for (i = 0; i < len; i += 4, offset += 4) { -+ u32 data, page_off, phy_addr, nvram_cmd; -+ -+ memcpy(&data, buf + i, 4); -+ tw32(NVRAM_WRDATA, cpu_to_be32(data)); -+ -+ page_off = offset % tp->nvram_pagesize; -+ -+ if ((tp->tg3_flags2 & TG3_FLG2_FLASH) && -+ (tp->nvram_jedecnum == JEDEC_ATMEL)) { -+ -+ phy_addr = ((offset / tp->nvram_pagesize) << -+ ATMEL_AT45DB0X1B_PAGE_POS) + page_off; -+ } -+ else { -+ phy_addr = offset; -+ } -+ -+ tw32(NVRAM_ADDR, phy_addr); -+ -+ nvram_cmd = NVRAM_CMD_GO | NVRAM_CMD_DONE | NVRAM_CMD_WR; -+ -+ if ((page_off == 0) || (i == 0)) -+ nvram_cmd |= NVRAM_CMD_FIRST; -+ else if (page_off == (tp->nvram_pagesize - 4)) -+ nvram_cmd |= NVRAM_CMD_LAST; -+ -+ if (i == (len - 4)) -+ nvram_cmd |= NVRAM_CMD_LAST; -+ -+ if ((tp->nvram_jedecnum == JEDEC_ST) && -+ (nvram_cmd & NVRAM_CMD_FIRST)) { - -- tw32_f(NVRAM_ACCESS, nvaccess & ~ACCESS_ENABLE); -+ if ((ret = tg3_nvram_exec_cmd(tp, -+ NVRAM_CMD_WREN | NVRAM_CMD_GO | -+ NVRAM_CMD_DONE))) -+ -+ break; -+ } -+ if (!(tp->tg3_flags2 & TG3_FLG2_FLASH)) { -+ /* We always do complete word writes to eeprom. */ -+ nvram_cmd |= (NVRAM_CMD_FIRST | NVRAM_CMD_LAST); -+ } -+ -+ if ((ret = tg3_nvram_exec_cmd(tp, nvram_cmd))) -+ break; - } -+ return ret; -+} - -- if (i >= 1000) -- return -EBUSY; -+/* offset and length are dword aligned */ -+static int tg3_nvram_write_block(struct tg3 *tp, u32 offset, u32 len, u8 *buf) -+{ -+ int ret; - -- return 0; -+ 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); -+ udelay(40); -+ } -+ -+ if (!(tp->tg3_flags & TG3_FLAG_NVRAM)) { -+ ret = tg3_nvram_write_block_using_eeprom(tp, offset, len, buf); -+ } -+ else { -+ u32 grc_mode; -+ -+ tg3_nvram_lock(tp); -+ -+ tg3_enable_nvram_access(tp); -+ if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) && -+ !(tp->tg3_flags2 & TG3_FLG2_PROTECTED_NVRAM)) -+ tw32(NVRAM_WRITE1, 0x406); -+ -+ grc_mode = tr32(GRC_MODE); -+ tw32(GRC_MODE, grc_mode | GRC_MODE_NVRAM_WR_ENABLE); -+ -+ if ((tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) || -+ !(tp->tg3_flags2 & TG3_FLG2_FLASH)) { -+ -+ ret = tg3_nvram_write_block_buffered(tp, offset, len, -+ buf); -+ } -+ else { -+ ret = tg3_nvram_write_block_unbuffered(tp, offset, len, -+ buf); -+ } -+ -+ grc_mode = tr32(GRC_MODE); -+ tw32(GRC_MODE, grc_mode & ~GRC_MODE_NVRAM_WR_ENABLE); -+ -+ tg3_disable_nvram_access(tp); -+ tg3_nvram_unlock(tp); -+ } -+ -+ if (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) { -+ tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl); -+ udelay(40); -+ } -+ -+ return ret; - } - - struct subsys_tbl_ent { -@@ -6870,10 +7798,10 @@ static struct subsys_tbl_ent subsys_id_t - { PCI_VENDOR_ID_BROADCOM, 0x1644, PHY_ID_BCM5401 }, /* BCM95700A6 */ - { PCI_VENDOR_ID_BROADCOM, 0x0001, PHY_ID_BCM5701 }, /* BCM95701A5 */ - { PCI_VENDOR_ID_BROADCOM, 0x0002, PHY_ID_BCM8002 }, /* BCM95700T6 */ -- { PCI_VENDOR_ID_BROADCOM, 0x0003, PHY_ID_SERDES }, /* BCM95700A9 */ -+ { PCI_VENDOR_ID_BROADCOM, 0x0003, 0 }, /* BCM95700A9 */ - { PCI_VENDOR_ID_BROADCOM, 0x0005, PHY_ID_BCM5701 }, /* BCM95701T1 */ - { PCI_VENDOR_ID_BROADCOM, 0x0006, PHY_ID_BCM5701 }, /* BCM95701T8 */ -- { PCI_VENDOR_ID_BROADCOM, 0x0007, PHY_ID_SERDES }, /* BCM95701A7 */ -+ { PCI_VENDOR_ID_BROADCOM, 0x0007, 0 }, /* BCM95701A7 */ - { PCI_VENDOR_ID_BROADCOM, 0x0008, PHY_ID_BCM5701 }, /* BCM95701A10 */ - { PCI_VENDOR_ID_BROADCOM, 0x8008, PHY_ID_BCM5701 }, /* BCM95701A12 */ - { PCI_VENDOR_ID_BROADCOM, 0x0009, PHY_ID_BCM5703 }, /* BCM95703Ax1 */ -@@ -6882,7 +7810,7 @@ static struct subsys_tbl_ent subsys_id_t - /* 3com boards. */ - { PCI_VENDOR_ID_3COM, 0x1000, PHY_ID_BCM5401 }, /* 3C996T */ - { PCI_VENDOR_ID_3COM, 0x1006, PHY_ID_BCM5701 }, /* 3C996BT */ -- { PCI_VENDOR_ID_3COM, 0x1004, PHY_ID_SERDES }, /* 3C996SX */ -+ { PCI_VENDOR_ID_3COM, 0x1004, 0 }, /* 3C996SX */ - { PCI_VENDOR_ID_3COM, 0x1007, PHY_ID_BCM5701 }, /* 3C1000T */ - { PCI_VENDOR_ID_3COM, 0x1008, PHY_ID_BCM5701 }, /* 3C940BR01 */ - -@@ -6895,65 +7823,84 @@ static struct subsys_tbl_ent subsys_id_t - /* Compaq boards. */ - { PCI_VENDOR_ID_COMPAQ, 0x007c, PHY_ID_BCM5701 }, /* BANSHEE */ - { PCI_VENDOR_ID_COMPAQ, 0x009a, PHY_ID_BCM5701 }, /* BANSHEE_2 */ -- { PCI_VENDOR_ID_COMPAQ, 0x007d, PHY_ID_SERDES }, /* CHANGELING */ -+ { PCI_VENDOR_ID_COMPAQ, 0x007d, 0 }, /* CHANGELING */ - { PCI_VENDOR_ID_COMPAQ, 0x0085, PHY_ID_BCM5701 }, /* NC7780 */ - { PCI_VENDOR_ID_COMPAQ, 0x0099, PHY_ID_BCM5701 }, /* NC7780_2 */ - - /* IBM boards. */ -- { PCI_VENDOR_ID_IBM, 0x0281, PHY_ID_SERDES } /* IBM??? */ -+ { PCI_VENDOR_ID_IBM, 0x0281, 0 } /* IBM??? */ - }; - --static int __devinit tg3_phy_probe(struct tg3 *tp) -+static inline struct subsys_tbl_ent *lookup_by_subsys(struct tg3 *tp) - { -- u32 eeprom_phy_id, hw_phy_id_1, hw_phy_id_2; -- u32 hw_phy_id, hw_phy_id_masked; -- u32 val; -- int i, eeprom_signature_found, err; -+ int i; - -- tp->phy_id = PHY_ID_INVALID; - for (i = 0; i < ARRAY_SIZE(subsys_id_to_phy_id); i++) { - if ((subsys_id_to_phy_id[i].subsys_vendor == - tp->pdev->subsystem_vendor) && - (subsys_id_to_phy_id[i].subsys_devid == -- tp->pdev->subsystem_device)) { -- tp->phy_id = subsys_id_to_phy_id[i].phy_id; -- break; -- } -+ tp->pdev->subsystem_device)) -+ return &subsys_id_to_phy_id[i]; - } -+ return NULL; -+} -+ -+/* Since this function may be called in D3-hot power state during -+ * tg3_init_one(), only config cycles are allowed. -+ */ -+static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) -+{ -+ u32 val; -+ -+ /* Make sure register accesses (indirect or otherwise) -+ * will function correctly. -+ */ -+ pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL, -+ tp->misc_host_ctrl); -+ -+ tp->phy_id = PHY_ID_INVALID; -+ tp->led_ctrl = LED_CTRL_MODE_PHY_1; - -- eeprom_phy_id = PHY_ID_INVALID; -- eeprom_signature_found = 0; - tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val); - if (val == NIC_SRAM_DATA_SIG_MAGIC) { - u32 nic_cfg, led_cfg; -+ u32 nic_phy_id, ver, cfg2 = 0, eeprom_phy_id; -+ int eeprom_phy_serdes = 0; - - tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg); - tp->nic_sram_data_cfg = nic_cfg; - -- eeprom_signature_found = 1; -+ tg3_read_mem(tp, NIC_SRAM_DATA_VER, &ver); -+ ver >>= NIC_SRAM_DATA_VER_SHIFT; -+ if ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700) && -+ (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) && -+ (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5703) && -+ (ver > 0) && (ver < 0x100)) -+ tg3_read_mem(tp, NIC_SRAM_DATA_CFG_2, &cfg2); - - if ((nic_cfg & NIC_SRAM_DATA_CFG_PHY_TYPE_MASK) == -- NIC_SRAM_DATA_CFG_PHY_TYPE_FIBER) { -- eeprom_phy_id = PHY_ID_SERDES; -- } else { -- u32 nic_phy_id; -+ NIC_SRAM_DATA_CFG_PHY_TYPE_FIBER) -+ eeprom_phy_serdes = 1; - -- tg3_read_mem(tp, NIC_SRAM_DATA_PHY_ID, &nic_phy_id); -- if (nic_phy_id != 0) { -- u32 id1 = nic_phy_id & NIC_SRAM_DATA_PHY_ID1_MASK; -- u32 id2 = nic_phy_id & NIC_SRAM_DATA_PHY_ID2_MASK; -- -- eeprom_phy_id = (id1 >> 16) << 10; -- eeprom_phy_id |= (id2 & 0xfc00) << 16; -- eeprom_phy_id |= (id2 & 0x03ff) << 0; -- } -- } -+ tg3_read_mem(tp, NIC_SRAM_DATA_PHY_ID, &nic_phy_id); -+ if (nic_phy_id != 0) { -+ u32 id1 = nic_phy_id & NIC_SRAM_DATA_PHY_ID1_MASK; -+ u32 id2 = nic_phy_id & NIC_SRAM_DATA_PHY_ID2_MASK; -+ -+ eeprom_phy_id = (id1 >> 16) << 10; -+ eeprom_phy_id |= (id2 & 0xfc00) << 16; -+ eeprom_phy_id |= (id2 & 0x03ff) << 0; -+ } else -+ eeprom_phy_id = 0; -+ -+ tp->phy_id = eeprom_phy_id; -+ if (eeprom_phy_serdes) -+ tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES; - -- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) { -- tg3_read_mem(tp, NIC_SRAM_DATA_CFG_2, &led_cfg); -- led_cfg &= (NIC_SRAM_DATA_CFG_LED_MODE_MASK | -+ if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) -+ led_cfg = cfg2 & (NIC_SRAM_DATA_CFG_LED_MODE_MASK | - SHASTA_EXT_LED_MODE_MASK); -- } else -+ else - led_cfg = nic_cfg & NIC_SRAM_DATA_CFG_LED_MODE_MASK; - - switch (led_cfg) { -@@ -6996,20 +7943,34 @@ static int __devinit tg3_phy_probe(struc - 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_5703) || -- (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) || -- (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)) && -+ 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)) - tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT; - - if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) { - tp->tg3_flags |= TG3_FLAG_ENABLE_ASF; -- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) -+ if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) - tp->tg3_flags2 |= TG3_FLG2_ASF_NEW_HANDSHAKE; - } - if (nic_cfg & NIC_SRAM_DATA_CFG_FIBER_WOL) - tp->tg3_flags |= TG3_FLAG_SERDES_WOL_CAP; -+ -+ if (cfg2 & (1 << 17)) -+ tp->tg3_flags2 |= TG3_FLG2_CAPACITIVE_COUPLING; -+ -+ /* serdes signal pre-emphasis in register 0x590 set by */ -+ /* bootcode if bit 18 is set */ -+ if (cfg2 & (1 << 18)) -+ tp->tg3_flags2 |= TG3_FLG2_SERDES_PREEMPHASIS; - } -+} -+ -+static int __devinit tg3_phy_probe(struct tg3 *tp) -+{ -+ u32 hw_phy_id_1, hw_phy_id_2; -+ u32 hw_phy_id, hw_phy_id_masked; -+ int err; - - /* Reading the PHY ID register can conflict with ASF - * firwmare access to the PHY hardware. -@@ -7035,27 +7996,37 @@ static int __devinit tg3_phy_probe(struc - - if (!err && KNOWN_PHY_ID(hw_phy_id_masked)) { - tp->phy_id = hw_phy_id; -+ if (hw_phy_id_masked == PHY_ID_BCM8002) -+ tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES; - } else { -- /* phy_id currently holds the value found in the -- * subsys_id_to_phy_id[] table or PHY_ID_INVALID -- * if a match was not found there. -- */ -- if (tp->phy_id == PHY_ID_INVALID) { -- if (!eeprom_signature_found || -- !KNOWN_PHY_ID(eeprom_phy_id & PHY_ID_MASK)) -+ if (tp->phy_id != PHY_ID_INVALID) { -+ /* Do nothing, phy ID already set up in -+ * tg3_get_eeprom_hw_cfg(). -+ */ -+ } else { -+ struct subsys_tbl_ent *p; -+ -+ /* No eeprom signature? Try the hardcoded -+ * subsys device table. -+ */ -+ p = lookup_by_subsys(tp); -+ if (!p) - return -ENODEV; -- tp->phy_id = eeprom_phy_id; -+ -+ tp->phy_id = p->phy_id; -+ if (!tp->phy_id || -+ tp->phy_id == PHY_ID_BCM8002) -+ tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES; - } - } - -- if (tp->phy_id != PHY_ID_SERDES && -+ if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) && - !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) { - u32 bmsr, adv_reg, tg3_ctrl; - - tg3_readphy(tp, MII_BMSR, &bmsr); -- tg3_readphy(tp, MII_BMSR, &bmsr); -- -- if (bmsr & BMSR_LSTATUS) -+ if (!tg3_readphy(tp, MII_BMSR, &bmsr) && -+ (bmsr & BMSR_LSTATUS)) - goto skip_phy_reset; - - err = tg3_phy_reset(tp); -@@ -7102,10 +8073,7 @@ skip_phy_reset: - err = tg3_init_5401phy_dsp(tp); - } - -- if (!eeprom_signature_found) -- tp->led_ctrl = LED_CTRL_MODE_PHY_1; -- -- if (tp->phy_id == PHY_ID_SERDES) -+ if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) - tp->link_config.advertising = - (ADVERTISED_1000baseT_Half | - ADVERTISED_1000baseT_Full | -@@ -7124,11 +8092,11 @@ static void __devinit tg3_read_partno(st - unsigned char vpd_data[256]; - int i; - -- if (tp->tg3_flags2 & TG3_FLG2_SUN_5704) { -+ 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 5704"); -+ strcpy(tp->board_part_number, "Sun 570X"); - return; - } - -@@ -7189,27 +8157,21 @@ out_not_found: - } - - #ifdef CONFIG_SPARC64 --static int __devinit tg3_is_sun_5704(struct tg3 *tp) -+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, devid; -+ u32 venid; - int err; - - err = prom_getproperty(node, "subsystem-vendor-id", - (char *) &venid, sizeof(venid)); - if (err == 0 || err == -1) - return 0; -- err = prom_getproperty(node, "subsystem-id", -- (char *) &devid, sizeof(devid)); -- if (err == 0 || err == -1) -- return 0; -- -- if (venid == PCI_VENDOR_ID_SUN && -- devid == PCI_DEVICE_ID_TIGON3_5704) -+ if (venid == PCI_VENDOR_ID_SUN) - return 1; - } - return 0; -@@ -7218,6 +8180,19 @@ static int __devinit tg3_is_sun_5704(str - - static int __devinit tg3_get_invariants(struct tg3 *tp) - { -+ static struct pci_device_id write_reorder_chipsets[] = { -+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, -+ PCI_DEVICE_ID_INTEL_82801AA_8) }, -+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, -+ PCI_DEVICE_ID_INTEL_82801AB_8) }, -+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, -+ PCI_DEVICE_ID_INTEL_82801BA_11) }, -+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, -+ PCI_DEVICE_ID_INTEL_82801BA_6) }, -+ { PCI_DEVICE(PCI_VENDOR_ID_AMD, -+ PCI_DEVICE_ID_AMD_FE_GATE_700C) }, -+ { }, -+ }; - u32 misc_ctrl_reg; - u32 cacheline_sz_reg; - u32 pci_state_reg, grc_misc_cfg; -@@ -7226,8 +8201,8 @@ static int __devinit tg3_get_invariants( - int err; - - #ifdef CONFIG_SPARC64 -- if (tg3_is_sun_5704(tp)) -- tp->tg3_flags2 |= TG3_FLG2_SUN_5704; -+ if (tg3_is_sun_570X(tp)) -+ tp->tg3_flags2 |= TG3_FLG2_SUN_570X; - #endif - - /* If we have an AMD 762 or Intel ICH/ICH0/ICH2 chipset, write -@@ -7236,16 +8211,7 @@ static int __devinit tg3_get_invariants( - * every mailbox register write to force the writes to be - * posted to the chip in order. - */ -- if (pci_find_device(PCI_VENDOR_ID_INTEL, -- PCI_DEVICE_ID_INTEL_82801AA_8, NULL) || -- pci_find_device(PCI_VENDOR_ID_INTEL, -- PCI_DEVICE_ID_INTEL_82801AB_8, NULL) || -- pci_find_device(PCI_VENDOR_ID_INTEL, -- PCI_DEVICE_ID_INTEL_82801BA_11, NULL) || -- pci_find_device(PCI_VENDOR_ID_INTEL, -- PCI_DEVICE_ID_INTEL_82801BA_6, NULL) || -- pci_find_device(PCI_VENDOR_ID_AMD, -- PCI_DEVICE_ID_AMD_FE_GATE_700C, NULL)) -+ if (pci_dev_present(write_reorder_chipsets)) - tp->tg3_flags |= TG3_FLAG_MBOX_WRITE_REORDER; - - /* Force memory write invalidate off. If we leave it on, -@@ -7271,6 +8237,12 @@ static int __devinit tg3_get_invariants( - tp->pci_chip_rev_id = (misc_ctrl_reg >> - MISC_HOST_CTRL_CHIPREV_SHIFT); - -+ /* Wrong chip ID in 5752 A0. This code can be removed later -+ * as A0 is not in production. -+ */ -+ if (tp->pci_chip_rev_id == CHIPREV_ID_5752_A0_HW) -+ tp->pci_chip_rev_id = CHIPREV_ID_5752_A0; -+ - /* Initialize misc host control in PCI block. */ - tp->misc_host_ctrl |= (misc_ctrl_reg & - MISC_HOST_CTRL_CHIPREV); -@@ -7285,6 +8257,17 @@ static int __devinit tg3_get_invariants( - tp->pci_hdr_type = (cacheline_sz_reg >> 16) & 0xff; - tp->pci_bist = (cacheline_sz_reg >> 24) & 0xff; - -+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 || -+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752) -+ tp->tg3_flags2 |= TG3_FLG2_5750_PLUS; -+ -+ if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) || -+ (tp->tg3_flags2 & TG3_FLG2_5750_PLUS)) -+ tp->tg3_flags2 |= TG3_FLG2_5705_PLUS; -+ -+ if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) -+ tp->tg3_flags2 |= TG3_FLG2_HW_TSO; -+ - if (pci_find_capability(tp->pdev, PCI_CAP_ID_EXP) != 0) - tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS; - -@@ -7360,6 +8343,31 @@ static int __devinit tg3_get_invariants( - pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE, pci_state_reg); - } - -+ /* 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 -+ * we know whether or not to switch out of Vaux power. -+ * When the flag is set, it means that GPIO1 is used for eeprom -+ * write protect and also implies that it is a LOM where GPIOs -+ * are not used to switch power. -+ */ -+ tg3_get_eeprom_hw_cfg(tp); -+ -+ /* Set up tp->grc_local_ctrl before calling tg3_set_power_state(). -+ * GPIO1 driven high will bring 5700's external PHY out of reset. -+ * It is also used as eeprom write protect on LOMs. -+ */ -+ tp->grc_local_ctrl = GRC_LCLCTRL_INT_ON_ATTN | GRC_LCLCTRL_AUTO_SEEPROM; -+ if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) || -+ (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT)) -+ tp->grc_local_ctrl |= (GRC_LCLCTRL_GPIO_OE1 | -+ GRC_LCLCTRL_GPIO_OUTPUT1); -+ /* Unused GPIO3 must be driven as output on 5752 because there -+ * are no pull-up resistors on unused GPIO pins. -+ */ -+ else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752) -+ tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE3; -+ - /* Force the chip into D0. */ - err = tg3_set_power_state(tp, 0); - if (err) { -@@ -7412,8 +8420,7 @@ static int __devinit tg3_get_invariants( - if (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0) - tp->tg3_flags2 |= TG3_FLG2_PHY_5704_A0_BUG; - -- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 || -- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) -+ if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) - tp->tg3_flags2 |= TG3_FLG2_PHY_BER_BUG; - - /* Only 5701 and later support tagged irq status mode. -@@ -7453,7 +8460,7 @@ static int __devinit tg3_get_invariants( - chiprevid == CHIPREV_ID_5701_B0 || - chiprevid == CHIPREV_ID_5701_B2 || - chiprevid == CHIPREV_ID_5701_B5) { -- unsigned long sram_base; -+ void __iomem *sram_base; - - /* Write some dummy words into the SRAM status block - * area, see if it reads back correctly. If the return -@@ -7472,32 +8479,17 @@ static int __devinit tg3_get_invariants( - udelay(50); - tg3_nvram_init(tp); - -- /* Always use host TXDs, it performs better in particular -- * with multi-frag packets. The tests below are kept here -- * as documentation should we change this decision again -- * in the future. -- */ -- tp->tg3_flags |= TG3_FLAG_HOST_TXDS; -- --#if 0 -- /* Determine if TX descriptors will reside in -- * main memory or in the chip SRAM. -- */ -- if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0 || -- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 || -- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) -- tp->tg3_flags |= TG3_FLAG_HOST_TXDS; --#endif -- - grc_misc_cfg = tr32(GRC_MISC_CFG); - grc_misc_cfg &= GRC_MISC_CFG_BOARD_ID_MASK; - -+ /* Broadcom's driver says that CIOBE multisplit has a bug */ -+#if 0 - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 && - grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5704CIOBE) { - tp->tg3_flags |= TG3_FLAG_SPLIT_MODE; - tp->split_mode_max_reqs = SPLIT_MODE_5704_MAX_REQ; - } -- -+#endif - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 && - (grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788 || - grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788M)) -@@ -7512,7 +8504,8 @@ static int __devinit tg3_get_invariants( - tp->pdev->device == PCI_DEVICE_ID_TIGON3_5901_2 || - tp->pdev->device == PCI_DEVICE_ID_TIGON3_5705F)) || - (tp->pdev->vendor == PCI_VENDOR_ID_BROADCOM && -- tp->pdev->device == PCI_DEVICE_ID_TIGON3_5751F)) -+ (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5751F || -+ tp->pdev->device == PCI_DEVICE_ID_TIGON3_5753F))) - tp->tg3_flags |= TG3_FLAG_10_100_ONLY; - - err = tg3_phy_probe(tp); -@@ -7524,7 +8517,7 @@ static int __devinit tg3_get_invariants( - - tg3_read_partno(tp); - -- if (tp->phy_id == PHY_ID_SERDES) { -+ if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) { - tp->tg3_flags &= ~TG3_FLAG_USE_MI_INTERRUPT; - } else { - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) -@@ -7547,13 +8540,13 @@ static int __devinit tg3_get_invariants( - * upon subsystem IDs. - */ - if (tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL && -- tp->phy_id != PHY_ID_SERDES) { -+ !(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) { - tp->tg3_flags |= (TG3_FLAG_USE_MI_INTERRUPT | - TG3_FLAG_USE_LINKCHG_REG); - } - - /* For all SERDES we poll the MAC status register. */ -- if (tp->phy_id == PHY_ID_SERDES) -+ if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) - tp->tg3_flags |= TG3_FLAG_POLL_SERDES; - else - tp->tg3_flags &= ~TG3_FLAG_POLL_SERDES; -@@ -7624,7 +8617,7 @@ static int __devinit tg3_get_device_addr - - mac_offset = 0x7c; - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 && -- !(tp->tg3_flags & TG3_FLG2_SUN_5704)) { -+ !(tp->tg3_flags & TG3_FLG2_SUN_570X)) { - if (tr32(TG3PCI_DUAL_MAC_CTRL) & DUAL_MAC_CTRL_ID) - mac_offset = 0xcc; - if (tg3_nvram_lock(tp)) -@@ -7646,7 +8639,7 @@ static int __devinit tg3_get_device_addr - dev->dev_addr[5] = (lo >> 0) & 0xff; - } - /* Next, try NVRAM. */ -- else if (!(tp->tg3_flags & TG3_FLG2_SUN_5704) && -+ else if (!(tp->tg3_flags & TG3_FLG2_SUN_570X) && - !tg3_nvram_read(tp, mac_offset + 0, &hi) && - !tg3_nvram_read(tp, mac_offset + 4, &lo)) { - dev->dev_addr[0] = ((hi >> 16) & 0xff); -@@ -7819,7 +8812,8 @@ static int __devinit tg3_test_dma(struct - #endif - - if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) { -- tp->dma_rwctrl |= 0x001f0000; -+ /* DMA read watermark not used on PCIE */ -+ tp->dma_rwctrl |= 0x00180000; - } else if (!(tp->tg3_flags & TG3_FLAG_PCIX_MODE)) { - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) -@@ -7988,8 +8982,9 @@ static char * __devinit tg3_phy_string(s - case PHY_ID_BCM5704: return "5704"; - case PHY_ID_BCM5705: return "5705"; - case PHY_ID_BCM5750: return "5750"; -- case PHY_ID_BCM8002: return "8002"; -- case PHY_ID_SERDES: return "serdes"; -+ case PHY_ID_BCM5752: return "5752"; -+ case PHY_ID_BCM8002: return "8002/serdes"; -+ case 0: return "serdes"; - default: return "unknown"; - }; - } -@@ -8096,6 +9091,7 @@ static int __devinit tg3_init_one(struct - - if (pci_using_dac) - dev->features |= NETIF_F_HIGHDMA; -+ dev->features |= NETIF_F_LLTX; - #if TG3_VLAN_TAG_USED - dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; - dev->vlan_rx_register = tg3_vlan_rx_register; -@@ -8141,7 +9137,7 @@ static int __devinit tg3_init_one(struct - spin_lock_init(&tp->indirect_lock); - INIT_WORK(&tp->reset_task, tg3_reset_task, tp); - -- tp->regs = (unsigned long) ioremap(tg3reg_base, tg3reg_len); -+ tp->regs = ioremap_nocache(tg3reg_base, tg3reg_len); - if (tp->regs == 0UL) { - printk(KERN_ERR PFX "Cannot map device registers, " - "aborting.\n"); -@@ -8181,8 +9177,7 @@ static int __devinit tg3_init_one(struct - goto err_out_iounmap; - } - -- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 || -- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) { -+ if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) { - tp->bufmgr_config.mbuf_read_dma_low_water = - DEFAULT_MB_RDMA_LOW_WATER_5705; - tp->bufmgr_config.mbuf_mac_rx_low_water = -@@ -8192,11 +9187,13 @@ static int __devinit tg3_init_one(struct - } - - #if TG3_TSO_SUPPORT != 0 -- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || -+ if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) { -+ tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE; -+ } -+ else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 || - tp->pci_chip_rev_id == CHIPREV_ID_5705_A0 || -- ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0 && -- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750)) { -+ (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0) { - tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE; - } else { - tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE; -@@ -8236,7 +9233,7 @@ static int __devinit tg3_init_one(struct - (tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) { - pci_save_state(tp->pdev, tp->pci_cfg_state); - tw32(MEMARB_MODE, MEMARB_MODE_ENABLE); -- tg3_halt(tp); -+ tg3_halt(tp, 1); - } - - err = tg3_test_dma(tp); -@@ -8257,6 +9254,9 @@ static int __devinit tg3_init_one(struct - if (tp->tg3_flags2 & TG3_FLG2_IS_5788) - dev->features &= ~NETIF_F_HIGHDMA; - -+ /* flow control autonegotiation is default behavior */ -+ tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG; -+ - err = register_netdev(dev); - if (err) { - printk(KERN_ERR PFX "Cannot register net device, " -@@ -8288,11 +9288,10 @@ static int __devinit tg3_init_one(struct - printk("%2.2x%c", dev->dev_addr[i], - i == 5 ? '\n' : ':'); - -- printk(KERN_INFO "%s: HostTXDS[%d] RXcsums[%d] LinkChgREG[%d] " -+ printk(KERN_INFO "%s: RXcsums[%d] LinkChgREG[%d] " - "MIirq[%d] ASF[%d] Split[%d] WireSpeed[%d] " - "TSOcap[%d] \n", - dev->name, -- (tp->tg3_flags & TG3_FLAG_HOST_TXDS) != 0, - (tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) != 0, - (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) != 0, - (tp->tg3_flags & TG3_FLAG_USE_MI_INTERRUPT) != 0, -@@ -8304,7 +9303,7 @@ static int __devinit tg3_init_one(struct - return 0; - - err_out_iounmap: -- iounmap((void *) tp->regs); -+ iounmap(tp->regs); - - err_out_free_dev: - free_netdev(dev); -@@ -8326,7 +9325,7 @@ static void __devexit tg3_remove_one(str - struct tg3 *tp = netdev_priv(dev); - - unregister_netdev(dev); -- iounmap((void *)tp->regs); -+ iounmap(tp->regs); - free_netdev(dev); - pci_release_regions(pdev); - pci_disable_device(pdev); -@@ -8334,7 +9333,7 @@ static void __devexit tg3_remove_one(str - } - } - --static int tg3_suspend(struct pci_dev *pdev, u32 state) -+static int tg3_suspend(struct pci_dev *pdev, pm_message_t state) - { - struct net_device *dev = pci_get_drvdata(pdev); - struct tg3 *tp = netdev_priv(dev); -@@ -8357,11 +9356,11 @@ static int tg3_suspend(struct pci_dev *p - - spin_lock_irq(&tp->lock); - spin_lock(&tp->tx_lock); -- tg3_halt(tp); -+ tg3_halt(tp, 1); - spin_unlock(&tp->tx_lock); - spin_unlock_irq(&tp->lock); - -- err = tg3_set_power_state(tp, state); -+ err = tg3_set_power_state(tp, pci_choose_state(pdev, state)); - if (err) { - spin_lock_irq(&tp->lock); - spin_lock(&tp->tx_lock); -@@ -8371,11 +9370,11 @@ static int tg3_suspend(struct pci_dev *p - tp->timer.expires = jiffies + tp->timer_offset; - add_timer(&tp->timer); - -- spin_unlock(&tp->tx_lock); -- spin_unlock_irq(&tp->lock); -- - netif_device_attach(dev); - tg3_netif_start(tp); -+ -+ spin_unlock(&tp->tx_lock); -+ spin_unlock_irq(&tp->lock); - } - - return err; -@@ -8408,11 +9407,11 @@ static int tg3_resume(struct pci_dev *pd - - tg3_enable_ints(tp); - -+ tg3_netif_start(tp); -+ - spin_unlock(&tp->tx_lock); - spin_unlock_irq(&tp->lock); - -- tg3_netif_start(tp); -- - return 0; - } - ---- linux-2.6.8.1-t043-libata-update//drivers/net/tg3_compat.h 1970-01-01 03:00:00.000000000 +0300 -+++ rhel4u2//drivers/net/tg3_compat.h 2005-10-19 11:47:13.000000000 +0400 -@@ -0,0 +1,41 @@ -+#ifndef __TG3_COMPAT_H__ -+#define __TG3_COMPAT_H__ -+ -+#define skb_header_cloned(skb) 0 -+ -+#define pci_choose_state(pdev, state) (state) -+ -+typedef u32 pm_message_t; -+ -+#ifndef ADVERTISE_PAUSE -+#define ADVERTISE_PAUSE_CAP 0x0400 -+#endif -+#ifndef ADVERTISE_PAUSE_ASYM -+#define ADVERTISE_PAUSE_ASYM 0x0800 -+#endif -+#ifndef LPA_PAUSE -+#define LPA_PAUSE_CAP 0x0400 -+#endif -+#ifndef LPA_PAUSE_ASYM -+#define LPA_PAUSE_ASYM 0x0800 -+#endif -+ -+/** -+ * pci_dev_present - Returns 1 if device matching the device list is present, 0 if not. -+ * @ids: A pointer to a null terminated list of struct pci_device_id structures -+ * that describe the type of PCI device the caller is trying to find. -+ * -+ * This is a cheap knock-off, just to help in back-porting tg3 from -+ * later kernels...beware of changes in usage... -+ */ -+static inline int pci_dev_present(const struct pci_device_id *ids) -+{ -+ const struct pci_device_id *dev; -+ -+ for (dev = ids; dev->vendor; dev++) { -+ if (pci_find_device(dev->vendor, dev->device, NULL)) -+ return 1; -+ } -+ return 0; -+} -+#endif /* __TG3_COMPAT_H__ */ ---- linux-2.6.8.1-t043-libata-update//drivers/net/tg3.h 2005-10-20 17:56:53.000000000 +0400 -+++ rhel4u2//drivers/net/tg3.h 2005-10-19 11:47:13.000000000 +0400 -@@ -124,6 +124,10 @@ - #define CHIPREV_ID_5705_A3 0x3003 - #define CHIPREV_ID_5750_A0 0x4000 - #define CHIPREV_ID_5750_A1 0x4001 -+#define CHIPREV_ID_5750_A3 0x4003 -+#define CHIPREV_ID_5752_A0_HW 0x5000 -+#define CHIPREV_ID_5752_A0 0x6000 -+#define CHIPREV_ID_5752_A1 0x6001 - #define GET_ASIC_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 12) - #define ASIC_REV_5700 0x07 - #define ASIC_REV_5701 0x00 -@@ -131,6 +135,7 @@ - #define ASIC_REV_5704 0x02 - #define ASIC_REV_5705 0x03 - #define ASIC_REV_5750 0x04 -+#define ASIC_REV_5752 0x06 - #define GET_CHIP_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 8) - #define CHIPREV_5700_AX 0x70 - #define CHIPREV_5700_BX 0x71 -@@ -139,6 +144,8 @@ - #define CHIPREV_5703_AX 0x10 - #define CHIPREV_5704_AX 0x20 - #define CHIPREV_5704_BX 0x21 -+#define CHIPREV_5750_AX 0x40 -+#define CHIPREV_5750_BX 0x41 - #define GET_METAL_REV(CHIP_REV_ID) ((CHIP_REV_ID) & 0xff) - #define METAL_REV_A0 0x00 - #define METAL_REV_A1 0x01 -@@ -1273,6 +1280,7 @@ - #define GRC_MODE_HOST_STACKUP 0x00010000 - #define GRC_MODE_HOST_SENDBDS 0x00020000 - #define GRC_MODE_NO_TX_PHDR_CSUM 0x00100000 -+#define GRC_MODE_NVRAM_WR_ENABLE 0x00200000 - #define GRC_MODE_NO_RX_PHDR_CSUM 0x00800000 - #define GRC_MODE_IRQ_ON_TX_CPU_ATTN 0x01000000 - #define GRC_MODE_IRQ_ON_RX_CPU_ATTN 0x02000000 -@@ -1303,6 +1311,9 @@ - #define GRC_LCLCTRL_CLEARINT 0x00000002 - #define GRC_LCLCTRL_SETINT 0x00000004 - #define GRC_LCLCTRL_INT_ON_ATTN 0x00000008 -+#define GRC_LCLCTRL_GPIO_INPUT3 0x00000020 -+#define GRC_LCLCTRL_GPIO_OE3 0x00000040 -+#define GRC_LCLCTRL_GPIO_OUTPUT3 0x00000080 - #define GRC_LCLCTRL_GPIO_INPUT0 0x00000100 - #define GRC_LCLCTRL_GPIO_INPUT1 0x00000200 - #define GRC_LCLCTRL_GPIO_INPUT2 0x00000400 -@@ -1365,6 +1376,8 @@ - #define NVRAM_CMD_ERASE 0x00000040 - #define NVRAM_CMD_FIRST 0x00000080 - #define NVRAM_CMD_LAST 0x00000100 -+#define NVRAM_CMD_WREN 0x00010000 -+#define NVRAM_CMD_WRDI 0x00020000 - #define NVRAM_STAT 0x00007004 - #define NVRAM_WRDATA 0x00007008 - #define NVRAM_ADDR 0x0000700c -@@ -1374,8 +1387,32 @@ - #define NVRAM_CFG1_FLASHIF_ENAB 0x00000001 - #define NVRAM_CFG1_BUFFERED_MODE 0x00000002 - #define NVRAM_CFG1_PASS_THRU 0x00000004 -+#define NVRAM_CFG1_STATUS_BITS 0x00000070 - #define NVRAM_CFG1_BIT_BANG 0x00000008 -+#define NVRAM_CFG1_FLASH_SIZE 0x02000000 - #define NVRAM_CFG1_COMPAT_BYPASS 0x80000000 -+#define NVRAM_CFG1_VENDOR_MASK 0x03000003 -+#define FLASH_VENDOR_ATMEL_EEPROM 0x02000000 -+#define FLASH_VENDOR_ATMEL_FLASH_BUFFERED 0x02000003 -+#define FLASH_VENDOR_ATMEL_FLASH_UNBUFFERED 0x00000003 -+#define FLASH_VENDOR_ST 0x03000001 -+#define FLASH_VENDOR_SAIFUN 0x01000003 -+#define FLASH_VENDOR_SST_SMALL 0x00000001 -+#define FLASH_VENDOR_SST_LARGE 0x02000001 -+#define NVRAM_CFG1_5752VENDOR_MASK 0x03c00003 -+#define FLASH_5752VENDOR_ATMEL_EEPROM_64KHZ 0x00000000 -+#define FLASH_5752VENDOR_ATMEL_EEPROM_376KHZ 0x02000000 -+#define FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED 0x02000003 -+#define FLASH_5752VENDOR_ST_M45PE10 0x02400000 -+#define FLASH_5752VENDOR_ST_M45PE20 0x02400002 -+#define FLASH_5752VENDOR_ST_M45PE40 0x02400001 -+#define NVRAM_CFG1_5752PAGE_SIZE_MASK 0x70000000 -+#define FLASH_5752PAGE_SIZE_256 0x00000000 -+#define FLASH_5752PAGE_SIZE_512 0x10000000 -+#define FLASH_5752PAGE_SIZE_1K 0x20000000 -+#define FLASH_5752PAGE_SIZE_2K 0x30000000 -+#define FLASH_5752PAGE_SIZE_4K 0x40000000 -+#define FLASH_5752PAGE_SIZE_264 0x50000000 - #define NVRAM_CFG2 0x00007018 - #define NVRAM_CFG3 0x0000701c - #define NVRAM_SWARB 0x00007020 -@@ -1395,15 +1432,16 @@ - #define SWARB_REQ1 0x00002000 - #define SWARB_REQ2 0x00004000 - #define SWARB_REQ3 0x00008000 --#define NVRAM_BUFFERED_PAGE_SIZE 264 --#define NVRAM_BUFFERED_PAGE_POS 9 - #define NVRAM_ACCESS 0x00007024 - #define ACCESS_ENABLE 0x00000001 - #define ACCESS_WR_ENABLE 0x00000002 --/* 0x7024 --> 0x7400 unused */ -+#define NVRAM_WRITE1 0x00007028 -+/* 0x702c --> 0x7400 unused */ - - /* 0x7400 --> 0x8000 unused */ - -+#define TG3_EEPROM_MAGIC 0x669955aa -+ - /* 32K Window into NIC internal memory */ - #define NIC_SRAM_WIN_BASE 0x00008000 - -@@ -1435,6 +1473,10 @@ - #define NIC_SRAM_DATA_CFG_EEPROM_WP 0x00000100 - #define NIC_SRAM_DATA_CFG_MINI_PCI 0x00001000 - #define NIC_SRAM_DATA_CFG_FIBER_WOL 0x00004000 -+#define NIC_SRAM_DATA_CFG_NO_GPIO2 0x00100000 -+ -+#define NIC_SRAM_DATA_VER 0x00000b5c -+#define NIC_SRAM_DATA_VER_SHIFT 16 - - #define NIC_SRAM_DATA_PHY_ID 0x00000b74 - #define NIC_SRAM_DATA_PHY_ID1_MASK 0xffff0000 -@@ -1497,6 +1539,7 @@ - #define MII_TG3_CTRL_ENABLE_AS_MASTER 0x1000 - - #define MII_TG3_EXT_CTRL 0x10 /* Extended control register */ -+#define MII_TG3_EXT_CTRL_FIFO_ELASTIC 0x0001 - #define MII_TG3_EXT_CTRL_LNK3_LED_MODE 0x0002 - #define MII_TG3_EXT_CTRL_TBI 0x8000 - -@@ -1529,26 +1572,12 @@ - #define MII_TG3_INT_DUPLEXCHG 0x0008 - #define MII_TG3_INT_ANEG_PAGE_RX 0x0400 - --/* XXX Add this to mii.h */ --#ifndef ADVERTISE_PAUSE --#define ADVERTISE_PAUSE_CAP 0x0400 --#endif --#ifndef ADVERTISE_PAUSE_ASYM --#define ADVERTISE_PAUSE_ASYM 0x0800 --#endif --#ifndef LPA_PAUSE --#define LPA_PAUSE_CAP 0x0400 --#endif --#ifndef LPA_PAUSE_ASYM --#define LPA_PAUSE_ASYM 0x0800 --#endif -- - /* There are two ways to manage the TX descriptors on the tigon3. - * Either the descriptors are in host DMA'able memory, or they - * exist only in the cards on-chip SRAM. All 16 send bds are under - * the same mode, they may not be configured individually. - * -- * The mode we use is controlled by TG3_FLAG_HOST_TXDS in tp->tg3_flags. -+ * This driver always uses host memory TX descriptors. - * - * To use host memory TX descriptors: - * 1) Set GRC_MODE_HOST_SENDBDS in GRC_MODE register. -@@ -1988,7 +2017,7 @@ struct tg3 { - spinlock_t lock; - spinlock_t indirect_lock; - -- unsigned long regs; -+ void __iomem *regs; - struct net_device *dev; - struct pci_dev *pdev; - -@@ -2004,7 +2033,6 @@ struct tg3 { - - spinlock_t tx_lock; - -- /* TX descs are only used if TG3_FLAG_HOST_TXDS is set. */ - struct tg3_tx_buffer_desc *tx_ring; - struct tx_ring_info *tx_buffers; - dma_addr_t tx_desc_mapping; -@@ -2040,7 +2068,6 @@ struct tg3 { - - u32 rx_offset; - u32 tg3_flags; --#define TG3_FLAG_HOST_TXDS 0x00000001 - #define TG3_FLAG_TXD_MBOX_HWBUG 0x00000002 - #define TG3_FLAG_RX_CHECKSUMS 0x00000004 - #define TG3_FLAG_USE_LINKCHG_REG 0x00000008 -@@ -2070,15 +2097,13 @@ struct tg3 { - #define TG3_FLAG_JUMBO_ENABLE 0x00800000 - #define TG3_FLAG_10_100_ONLY 0x01000000 - #define TG3_FLAG_PAUSE_AUTONEG 0x02000000 --#define TG3_FLAG_PAUSE_RX 0x04000000 --#define TG3_FLAG_PAUSE_TX 0x08000000 - #define TG3_FLAG_BROKEN_CHECKSUMS 0x10000000 - #define TG3_FLAG_GOT_SERDES_FLOWCTL 0x20000000 - #define TG3_FLAG_SPLIT_MODE 0x40000000 - #define TG3_FLAG_INIT_COMPLETE 0x80000000 - u32 tg3_flags2; - #define TG3_FLG2_RESTART_TIMER 0x00000001 --#define TG3_FLG2_SUN_5704 0x00000002 -+#define TG3_FLG2_SUN_570X 0x00000002 - #define TG3_FLG2_NO_ETH_WIRE_SPEED 0x00000004 - #define TG3_FLG2_IS_5788 0x00000008 - #define TG3_FLG2_MAX_RXPEND_64 0x00000010 -@@ -2089,6 +2114,16 @@ struct tg3 { - #define TG3_FLG2_PCI_EXPRESS 0x00000200 - #define TG3_FLG2_ASF_NEW_HANDSHAKE 0x00000400 - #define TG3_FLG2_HW_AUTONEG 0x00000800 -+#define TG3_FLG2_PHY_JUST_INITTED 0x00001000 -+#define TG3_FLG2_PHY_SERDES 0x00002000 -+#define TG3_FLG2_CAPACITIVE_COUPLING 0x00004000 -+#define TG3_FLG2_FLASH 0x00008000 -+#define TG3_FLG2_HW_TSO 0x00010000 -+#define TG3_FLG2_SERDES_PREEMPHASIS 0x00020000 -+#define TG3_FLG2_5705_PLUS 0x00040000 -+#define TG3_FLG2_5750_PLUS 0x00080000 -+#define TG3_FLG2_PROTECTED_NVRAM 0x00100000 -+#define TG3_FLG2_USING_MSI 0x00200000 - - u32 split_mode_max_reqs; - #define SPLIT_MODE_5704_MAX_REQ 3 -@@ -2135,8 +2170,8 @@ struct tg3 { - #define PHY_ID_BCM5704 0x60008190 - #define PHY_ID_BCM5705 0x600081a0 - #define PHY_ID_BCM5750 0x60008180 -+#define PHY_ID_BCM5752 0x60008100 - #define PHY_ID_BCM8002 0x60010140 --#define PHY_ID_SERDES 0xfeedbee0 - #define PHY_ID_INVALID 0xffffffff - #define PHY_ID_REV_MASK 0x0000000f - #define PHY_REV_BCM5401_B0 0x1 -@@ -2159,11 +2194,39 @@ struct tg3 { - (X) == PHY_ID_BCM5411 || (X) == PHY_ID_BCM5701 || \ - (X) == PHY_ID_BCM5703 || (X) == PHY_ID_BCM5704 || \ - (X) == PHY_ID_BCM5705 || (X) == PHY_ID_BCM5750 || \ -- (X) == PHY_ID_BCM8002 || (X) == PHY_ID_SERDES) -+ (X) == PHY_ID_BCM8002) - - struct tg3_hw_stats *hw_stats; - dma_addr_t stats_mapping; - struct work_struct reset_task; -+ -+ u32 nvram_size; -+ u32 nvram_pagesize; -+ u32 nvram_jedecnum; -+ -+#define JEDEC_ATMEL 0x1f -+#define JEDEC_ST 0x20 -+#define JEDEC_SAIFUN 0x4f -+#define JEDEC_SST 0xbf -+ -+#define ATMEL_AT24C64_CHIP_SIZE (64 * 1024) -+#define ATMEL_AT24C64_PAGE_SIZE (32) -+ -+#define ATMEL_AT24C512_CHIP_SIZE (512 * 1024) -+#define ATMEL_AT24C512_PAGE_SIZE (128) -+ -+#define ATMEL_AT45DB0X1B_PAGE_POS 9 -+#define ATMEL_AT45DB0X1B_PAGE_SIZE 264 -+ -+#define ATMEL_AT25F512_PAGE_SIZE 256 -+ -+#define ST_M45PEX0_PAGE_SIZE 256 -+ -+#define SAIFUN_SA25F0XX_PAGE_SIZE 256 -+ -+#define SST_25VF0X0_PAGE_SIZE 4098 -+ -+ - }; - - #endif /* !(_T3_H) */ |