r2504 - in trunk/kernel-2.4/source/kernel-source-2.4.29-2.4.29/debian: . patches patches/series

Joshua Kwan joshk@costa.debian.org
Thu, 17 Feb 2005 10:27:43 +0100


Author: joshk
Date: 2005-02-17 10:27:41 +0100 (Thu, 17 Feb 2005)
New Revision: 2504

Removed:
   trunk/kernel-2.4/source/kernel-source-2.4.29-2.4.29/debian/patches/073_tg3_hw_autoneg.diff
Modified:
   trunk/kernel-2.4/source/kernel-source-2.4.29-2.4.29/debian/changelog
   trunk/kernel-2.4/source/kernel-source-2.4.29-2.4.29/debian/patches/063_firmwareless_tg3.diff
   trunk/kernel-2.4/source/kernel-source-2.4.29-2.4.29/debian/patches/series/2.4.29-1
Log:
refresh firmwareless_tg3.diff, remove hw_autoneg backport

Modified: trunk/kernel-2.4/source/kernel-source-2.4.29-2.4.29/debian/changelog
===================================================================
--- trunk/kernel-2.4/source/kernel-source-2.4.29-2.4.29/debian/changelog	2005-02-17 07:36:51 UTC (rev 2503)
+++ trunk/kernel-2.4/source/kernel-source-2.4.29-2.4.29/debian/changelog	2005-02-17 09:27:41 UTC (rev 2504)
@@ -4,6 +4,7 @@
   * Patches removed
     - 008_DAC960_alpha_fw.diff (merged)
     - 025_proc_tty_security.diff (backport)
+    - 073_tg3_hw_autoneg.diff (backport)
     - 077_isofs_ignore_volseqno.diff (irrelevant)
     - 093_tty_lockup.diff (backport)
     - 114-binfmt_aout-CAN-2004-1074.diff (backport)
@@ -14,7 +15,7 @@
     - 101-503: add Willy Tarreau's hotfix patchset (2.4.29-hf2), addressing
       some new security issues and bugs in 2.4.29
 
- -- Joshua Kwan <joshk@triplehelix.org>  Wed, 16 Feb 2005 16:10:45 -0800
+ -- Joshua Kwan <joshk@triplehelix.org>  Thu, 17 Feb 2005 01:27:04 -0800
 
 kernel-source-2.4.28 (2.4.28-1) unstable; urgency=low
 

Modified: trunk/kernel-2.4/source/kernel-source-2.4.29-2.4.29/debian/patches/063_firmwareless_tg3.diff
===================================================================
--- trunk/kernel-2.4/source/kernel-source-2.4.29-2.4.29/debian/patches/063_firmwareless_tg3.diff	2005-02-17 07:36:51 UTC (rev 2503)
+++ trunk/kernel-2.4/source/kernel-source-2.4.29-2.4.29/debian/patches/063_firmwareless_tg3.diff	2005-02-17 09:27:41 UTC (rev 2504)
@@ -1,12 +1,12 @@
-# origin: Debian (neroden)
+# origin: Debian (neroden, joshk)
 # cset: n/a
-# inclusion: not suitable for mainline
-# description: tg3 that's able to use firmware from userspace.
-# revision date: 2004-11-22
+# inclusion: are you crazy?
+# description: tg3.c with the firmware remove and firmware loading capability
+# revision date: 2005-02-17
 
---- a/drivers/net/tg3.c	1970-01-01 10:00:00.000000000 +1000
-+++ b/drivers/net/tg3.c	2004-08-13 10:14:36.000000000 -0700
-@@ -0,0 +1,7968 @@
+--- /dev/null	2005-02-15 14:35:44.491210208 -0800
++++ a/drivers/net/tg3.c	2005-02-17 01:22:17.728929240 -0800
+@@ -0,0 +1,8085 @@
 +/*
 + * tg3.c: Broadcom Tigon3 ethernet driver.
 + *
@@ -68,8 +68,8 @@
 +
 +#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.15"
++#define DRV_MODULE_RELDATE	"January 6, 2005"
 +
 +#define TG3_DEF_MAC_MODE	0
 +#define TG3_DEF_RX_MODE		0
@@ -213,6 +213,14 @@
 +	  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_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,
@@ -453,9 +461,14 @@
 +		       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 (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 ||
++	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) {
++		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));
@@ -473,7 +486,8 @@
 +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,
@@ -481,7 +495,7 @@
 +		udelay(80);
 +	}
 +
-+	*val = 0xffffffff;
++	*val = 0x0;
 +
 +	frame_val  = ((PHY_ADDR << MI_COM_PHY_ADDR_SHIFT) &
 +		      MI_COM_PHY_ADDR_MASK);
@@ -492,7 +506,7 @@
 +	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);
 +
@@ -501,10 +515,11 @@
 +			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;
 +	}
@@ -520,7 +535,8 @@
 +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,
@@ -538,7 +554,7 @@
 +	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) {
@@ -546,10 +562,11 @@
 +			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) {
@@ -869,34 +886,54 @@
 +			      GRC_LCLCTRL_GPIO_OUTPUT1));
 +			udelay(100);
 +		} else {
++			int 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) != 0;
++
++			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);
 +
++			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;
++			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_OUTPUT0 |
-+			      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));
-+			udelay(100);
++			grc_local_ctrl = GRC_LCLCTRL_GPIO_OE0 |
++					 GRC_LCLCTRL_GPIO_OE1 |
++					 GRC_LCLCTRL_GPIO_OE2 |
++					 GRC_LCLCTRL_GPIO_OUTPUT0 |
++					 GRC_LCLCTRL_GPIO_OUTPUT1;
++			if (!no_gpio2) {
++				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 &&
@@ -991,7 +1028,7 @@
 +		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;
@@ -1003,7 +1040,7 @@
 +	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);
 +
@@ -1125,30 +1162,34 @@
 +	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;
++	} else {
++		new_tg3_flags = tp->tg3_flags;
 +	}
 +
-+	tp->tg3_flags &= ~(TG3_FLAG_RX_PAUSE | TG3_FLAG_TX_PAUSE);
-+	tp->tg3_flags |= new_tg3_flags;
-+
 +	if (new_tg3_flags & TG3_FLAG_RX_PAUSE)
 +		tp->rx_mode |= RX_MODE_FLOW_CTRL_ENABLE;
 +	else
@@ -1498,6 +1539,18 @@
 +	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);
@@ -1577,7 +1630,7 @@
 +			tg3_setup_flow_control(tp, local_adv, remote_adv);
 +		}
 +	}
-+
++relink:
 +	if (current_link_up == 0) {
 +		u32 tmp;
 +
@@ -1627,7 +1680,7 @@
 +	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 {
@@ -1976,62 +2029,273 @@
 +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;
++	tw32_f(MAC_TX_AUTO_NEG, 0);
 +
-+		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;
++	tmp = tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK;
++	tw32_f(MAC_MODE, tmp | MAC_MODE_PORT_MODE_GMII);
++	udelay(40);
 +
-+		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_MODE, tp->mac_mode | MAC_MODE_SEND_CONFIGS);
++	udelay(40);
 +
-+		tw32_f(MAC_TX_AUTO_NEG, 0);
++	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;
 +
-+		tmp = tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK;
-+		tw32_f(MAC_MODE, tmp | MAC_MODE_PORT_MODE_GMII);
-+		udelay(40);
++		udelay(1);
++	}
 +
-+		tw32_f(MAC_MODE, tp->mac_mode | MAC_MODE_SEND_CONFIGS);
-+		udelay(40);
++	tp->mac_mode &= ~MAC_MODE_SEND_CONFIGS;
++	tw32_f(MAC_MODE, tp->mac_mode);
++	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)
++	*flags = aninfo.flags;
++
++	if (status == ANEG_DONE &&
++	    (aninfo.flags & (MR_AN_COMPLETE | MR_LINK_OK |
++			     MR_LP_ADV_FULL_DUPLEX)))
++		res = 1;
++
++	return res;
++}
++
++static void tg3_init_bcm8002(struct tg3 *tp)
++{
++	u32 mac_status = tr32(MAC_STATUS);
++	int i;
++
++	/* 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;
++
++	/* 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);
++
++	/* 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);
++
++	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);
++
++	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);
++
++	/* Deselect the channel register so we can read the PHYID
++	 * later.
++	 */
++	tg3_writephy(tp, 0x10, 0x8011);
++}
++
++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 (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;
++
++		serdes_cfg = tr32(MAC_SERDES_CFG) &
++			((1 << 23) | (1 << 22) | (1 << 21) | (1 << 20));
++	}
++
++	sg_dig_ctrl = tr32(SG_DIG_CTRL);
++
++	if (tp->link_config.autoneg != AUTONEG_ENABLE) {
++		if (sg_dig_ctrl & (1 << 31)) {
++			if (workaround) {
++				u32 val = serdes_cfg;
++
++				if (port_a)
++					val |= 0xc010880;
++				else
++					val |= 0x4010880;
++				tw32_f(MAC_SERDES_CFG, val);
++			}
++			tw32_f(SG_DIG_CTRL, 0x01388400);
++		}
++		if (mac_status & MAC_STATUS_PCS_SYNCED) {
++			tg3_setup_flow_control(tp, 0, 0);
++			current_link_up = 1;
++		}
++		goto out;
++	}
++
++	/* Want auto-negotiation.  */
++	expected_sg_dig_ctrl = 0x81388400;
++
++	/* Pause capability */
++	expected_sg_dig_ctrl |= (1 << 11);
++
++	/* Asymettric pause */
++	expected_sg_dig_ctrl |= (1 << 12);
++
++	if (sg_dig_ctrl != expected_sg_dig_ctrl) {
++		if (workaround)
++			tw32_f(MAC_SERDES_CFG, serdes_cfg | 0xc011880);
++		tw32_f(SG_DIG_CTRL, expected_sg_dig_ctrl | (1 << 30));
++		udelay(5);
++		tw32_f(SG_DIG_CTRL, expected_sg_dig_ctrl);
++
++		tp->tg3_flags2 |= TG3_FLG2_PHY_JUST_INITTED;
++	} else if (mac_status & (MAC_STATUS_PCS_SYNCED |
++				 MAC_STATUS_SIGNAL_DET)) {
++		int i;
++
++		/* 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);
 +
-+			udelay(1);
++		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 |= 0xc010880;
++					else
++						val |= 0x4010880;
++
++					tw32_f(MAC_SERDES_CFG, val);
++				}
++
++				tw32_f(SG_DIG_CTRL, 0x01388400);
++				udelay(40);
++
++				mac_status = tr32(MAC_STATUS);
++				if (mac_status & MAC_STATUS_PCS_SYNCED) {
++					tg3_setup_flow_control(tp, 0, 0);
++					current_link_up = 1;
++				}
++			}
 +		}
++	}
 +
-+		tp->mac_mode &= ~MAC_MODE_SEND_CONFIGS;
-+		tw32_f(MAC_MODE, tp->mac_mode);
-+		udelay(40);
++out:
++	return current_link_up;
++}
 +
-+		*flags = aninfo.flags;
++static int tg3_setup_fiber_by_hand(struct tg3 *tp, u32 mac_status)
++{
++	int current_link_up = 0;
 +
-+		if (status == ANEG_DONE &&
-+		    (aninfo.flags & (MR_AN_COMPLETE | MR_LINK_OK |
-+				     MR_LP_ADV_FULL_DUPLEX)))
-+			res = 1;
++ 	if (!(mac_status & MAC_STATUS_PCS_SYNCED)) {
++		tp->tg3_flags &= ~TG3_FLAG_GOT_SERDES_FLOWCTL;
++		goto out;
 +	}
 +
-+	return res;
++	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)
@@ -2039,6 +2303,7 @@
 +	u32 orig_pause_cfg;
 +	u16 orig_active_speed;
 +	u8 orig_active_duplex;
++	u32 mac_status;
 +	int current_link_up;
 +	int i;
 +
@@ -2048,119 +2313,44 @@
 +	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->tg3_flags2 & TG3_FLG2_HW_AUTONEG) {
-+		/* Allow time for the hardware to auto-negotiate (195ms) */
-+		unsigned int tick = 0;
++	if (tp->phy_id == PHY_ID_BCM8002)
++		tg3_init_bcm8002(tp);
 +
-+		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);
-+	}
-+
-+	/* 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);
-+
-+		/* 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);
-+
-+		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);
-+
-+		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);
-+
-+		/* 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);
++	/* Enable link change event even when serdes polling.  */
++	tw32_f(MAC_EVENT, MAC_EVENT_LNKSTATE_CHANGED);
 +	udelay(40);
 +
 +	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;
++	mac_status = tr32(MAC_STATUS);
 +
-+				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->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);
 +
-+				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 < 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;
-+			}
-+		} else {
-+			/* Forcing 1000FD link up. */
-+			current_link_up = 1;
-+			tp->tg3_flags |= TG3_FLAG_GOT_SERDES_FLOWCTL;
-+		}
-+	} else
-+		tp->tg3_flags &= ~TG3_FLAG_GOT_SERDES_FLOWCTL;
-+
 +	tp->mac_mode &= ~MAC_MODE_LINK_POLARITY;
 +	tw32_f(MAC_MODE, tp->mac_mode);
 +	udelay(40);
@@ -2170,19 +2360,24 @@
 +		 (tp->hw_status->status & ~SD_STATUS_LINK_CHG));
 +
 +	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)
++		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;
 +	}
 +
-+	if ((tr32(MAC_STATUS) & MAC_STATUS_PCS_SYNCED) == 0)
++	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;
@@ -2214,15 +2409,6 @@
 +			tg3_link_report(tp);
 +	}
 +
-+	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);
-+		}
-+	}
-+
 +	return 0;
 +}
 +
@@ -2230,7 +2416,7 @@
 +{
 +	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);
@@ -2748,11 +2934,11 @@
 +	tg3_halt(tp);
 +	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);
 +}
@@ -2822,6 +3008,7 @@
 +			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;
@@ -2833,35 +3020,11 @@
 +		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)
@@ -3050,20 +3213,8 @@
 +	}
 +
 +	/* 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_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW), entry);
 +
-+		tw32_tx_mbox((MAILBOX_SNDNIC_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);
@@ -3112,9 +3263,10 @@
 +
 +	tg3_init_hw(tp);
 +
++	tg3_netif_start(tp);
++
 +	spin_unlock(&tp->tx_lock);
 +	spin_unlock_irq(&tp->lock);
-+	tg3_netif_start(tp);
 +
 +	return 0;
 +}
@@ -3200,7 +3352,6 @@
 + */
 +static void tg3_init_rings(struct tg3 *tp)
 +{
-+	unsigned long start, end;
 +	u32 i;
 +
 +	/* Free up all the SKBs. */
@@ -3210,22 +3361,8 @@
 +	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));
++	memset(tp->tx_ring, 0, TG3_TX_RING_BYTES);
 +
-+	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;
-+	}
-+
 +	/* Initialize invariants of the rings, we only set this
 +	 * stuff once.  This works because the card does not
 +	 * write into the rx buffer posting rings.
@@ -3355,15 +3492,10 @@
 +	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,
@@ -3605,6 +3737,8 @@
 +	}
 +}
 +
++static void tg3_stop_fw(struct tg3 *);
++
 +/* tp->lock is held. */
 +static int tg3_chip_reset(struct tg3 *tp)
 +{
@@ -3612,7 +3746,7 @@
 +	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);
 +
 +	/*
@@ -3707,6 +3841,11 @@
 +
 +	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) {
@@ -3723,7 +3862,7 @@
 +		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
@@ -3738,7 +3877,7 @@
 +		udelay(10);
 +	}
 +	if (i >= 100000 &&
-+	    !(tp->tg3_flags2 & TG3_FLG2_SUN_5704)) {
++	    !(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) {
 +		printk(KERN_ERR PFX "tg3_reset_hw timed out for %s, "
 +		       "firmware will not restart magic=%08x\n",
 +		       tp->dev->name, val);
@@ -4321,10 +4460,7 @@
 +			  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)
@@ -4477,18 +4613,11 @@
 +	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.
@@ -4754,14 +4883,14 @@
 +	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 (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) {
 +		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
 +			/* Set drive transmission level to 1.2V  */
 +			val = tr32(MAC_SERDES_CFG);
@@ -4779,22 +4908,8 @@
 +	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;
 +	}
 +
@@ -4802,7 +4917,7 @@
 +	if (err)
 +		return err;
 +
-+	if (tp->phy_id != PHY_ID_SERDES) {
++	if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) {
 +		u32 tmp;
 +
 +		/* Clear CRC stats. */
@@ -4994,7 +5109,8 @@
 +				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) {
@@ -5047,8 +5163,8 @@
 +	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)
@@ -5390,7 +5506,7 @@
 +{
 +	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;
@@ -5746,8 +5862,8 @@
 +	return EEPROM_CHIP_SIZE;
 +}
 +
-+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);
 +static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data)
 +{
 +	struct tg3 *tp = dev->priv;
@@ -5821,7 +5937,7 @@
 +		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 |
@@ -5850,7 +5966,7 @@
 +	    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 |
@@ -5908,7 +6024,7 @@
 +	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;
 +  
@@ -6004,10 +6120,9 @@
 +
 +	tg3_halt(tp);
 +	tg3_init_hw(tp);
-+	netif_wake_queue(tp->dev);
++	tg3_netif_start(tp);
 +	spin_unlock(&tp->tx_lock);
 +	spin_unlock_irq(&tp->lock);
-+	tg3_netif_start(tp);
 +  
 +	return 0;
 +}
@@ -6017,8 +6132,8 @@
 +	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)
@@ -6033,18 +6148,18 @@
 +	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;
++		tp->tg3_flags &= ~TG3_FLAG_TX_PAUSE;
 +	tg3_halt(tp);
 +	tg3_init_hw(tp);
++	tg3_netif_start(tp);
 +	spin_unlock(&tp->tx_lock);
 +	spin_unlock_irq(&tp->lock);
-+	tg3_netif_start(tp);
 +  
 +	return 0;
 +}
@@ -6131,7 +6246,7 @@
 +	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);
@@ -6144,7 +6259,7 @@
 +	}
 +
 +	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))
@@ -6231,7 +6346,7 @@
 +{
 +	int j;
 +
-+	if (tp->tg3_flags2 & TG3_FLG2_SUN_5704)
++	if (tp->tg3_flags2 & TG3_FLG2_SUN_570X)
 +		return;
 +
 +	tw32_f(GRC_EEPROM_ADDR,
@@ -6279,8 +6394,8 @@
 +	}
 +}
 +
-+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;
@@ -6318,8 +6433,8 @@
 +{
 +	int i;
 +
-+	if (tp->tg3_flags2 & TG3_FLG2_SUN_5704) {
-+		printk(KERN_ERR PFX "Attempt to do nvram_read on Sun 5704\n");
++	if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) {
++		printk(KERN_ERR PFX "Attempt to do nvram_read on Sun 570X\n");
 +		return -EINVAL;
 +	}
 +
@@ -6381,10 +6496,10 @@
 +	{ 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 */
@@ -6393,7 +6508,7 @@
 +	/* 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 */
 +
@@ -6406,37 +6521,43 @@
 +	/* 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;
++}
 +
++static int __devinit tg3_phy_probe(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 eeprom_signature_found, eeprom_phy_serdes, err;
++
++	tp->phy_id = PHY_ID_INVALID;
 +	eeprom_phy_id = PHY_ID_INVALID;
++	eeprom_phy_serdes = 0;
 +	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, cfg2;
 +
 +		tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg);
 +		tp->nic_sram_data_cfg = nic_cfg;
@@ -6444,21 +6565,19 @@
 +		eeprom_signature_found = 1;
 +
 +		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;
++		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;
-+			}
-+		}
++			eeprom_phy_id  = (id1 >> 16) << 10;
++			eeprom_phy_id |= (id2 & 0xfc00) << 16;
++			eeprom_phy_id |= (id2 & 0x03ff) <<  0;
++		} else
++			eeprom_phy_id = 0;
 +
 +		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) {
 +			tg3_read_mem(tp, NIC_SRAM_DATA_CFG_2, &led_cfg);
@@ -6520,6 +6639,10 @@
 +		}
 +		if (nic_cfg & NIC_SRAM_DATA_CFG_FIBER_WOL)
 +			tp->tg3_flags |= TG3_FLAG_SERDES_WOL_CAP;
++
++		tg3_read_mem(tp, NIC_SRAM_DATA_PHY_ID, &cfg2);
++		if (cfg2 & (1 << 17))
++			tp->tg3_flags2 |= TG3_FLG2_CAPACITIVE_COUPLING;
 +	}
 +
 +	/* Reading the PHY ID register can conflict with ASF
@@ -6546,20 +6669,31 @@
 +
 +	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 (eeprom_signature_found) {
++			tp->phy_id = eeprom_phy_id;
++			if (eeprom_phy_serdes)
++				tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES;
++		} 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;
 +
@@ -6616,7 +6750,7 @@
 +	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 |
@@ -6635,11 +6769,11 @@
 +	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;
 +	}
 +
@@ -6700,27 +6834,21 @@
 +}
 +
 +#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;
@@ -6737,8 +6865,8 @@
 +	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
@@ -6983,32 +7111,17 @@
 +	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))
@@ -7023,7 +7136,8 @@
 +	      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);
@@ -7035,7 +7149,7 @@
 +
 +	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)
@@ -7058,13 +7172,13 @@
 +	 * 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;
@@ -7135,7 +7249,7 @@
 +
 +	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))
@@ -7157,7 +7271,7 @@
 +		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);
@@ -7331,7 +7445,8 @@
 +#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)
@@ -7500,8 +7615,8 @@
 +	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_BCM8002:	return "8002/serdes";
++	case 0:			return "serdes";
 +	default:		return "unknown";
 +	};
 +}
@@ -7646,7 +7761,7 @@
 +	spin_lock_init(&tp->indirect_lock);
 +	INIT_TQUEUE(&tp->reset_task, tg3_reset_task, tp);
 +
-+	tp->regs = (unsigned long) ioremap(tg3reg_base, tg3reg_len);
++	tp->regs = (unsigned long) ioremap_nocache(tg3reg_base, tg3reg_len);
 +	if (tp->regs == 0UL) {
 +		printk(KERN_ERR PFX "Cannot map device registers, "
 +		       "aborting.\n");
@@ -7786,6 +7901,9 @@
 +	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, "
@@ -7817,11 +7935,10 @@
 +		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,
@@ -7900,11 +8017,11 @@
 +		tp->timer.expires = jiffies + tp->timer_offset;
 +		add_timer(&tp->timer);
 +
++		netif_device_attach(dev);
++		tg3_netif_start(tp);
++
 +		spin_unlock(&tp->tx_lock);
 +		spin_unlock_irq(&tp->lock);
-+
-+		netif_device_attach(dev);
-+		tg3_netif_start(tp);
 +	}
 +
 +	return err;
@@ -7937,11 +8054,11 @@
 +
 +	tg3_enable_ints(tp);
 +
++	tg3_netif_start(tp);
++
 +	spin_unlock(&tp->tx_lock);
 +	spin_unlock_irq(&tp->lock);
 +
-+	tg3_netif_start(tp);
-+
 +	return 0;
 +}
 +

Deleted: trunk/kernel-2.4/source/kernel-source-2.4.29-2.4.29/debian/patches/073_tg3_hw_autoneg.diff
===================================================================
--- trunk/kernel-2.4/source/kernel-source-2.4.29-2.4.29/debian/patches/073_tg3_hw_autoneg.diff	2005-02-17 07:36:51 UTC (rev 2503)
+++ trunk/kernel-2.4/source/kernel-source-2.4.29-2.4.29/debian/patches/073_tg3_hw_autoneg.diff	2005-02-17 09:27:41 UTC (rev 2504)
@@ -1,43 +0,0 @@
-# origin: bk
-# cset: 1.1493.3.10
-# inclusion: n/a (projected: 2.4.28-pre3)
-# description: fix hw autoneg problems
-# revision date: 2004-09-03
-
-# This is a BitKeeper generated diff -Nru style patch.
-#
-# ChangeSet
-#   2004/08/30 15:12:10-07:00 mchan@broadcom.com 
-#   [TG3]: Check MAC_STATUS_SIGNAL_DET in serdes polling.
-#   
-#   Otherwise we do not handle properly the case
-#   where the switch/hub does not support auto-
-#   negotiation.  This is what was breaking 5704
-#   hw fiber autoneg.
-#   
-#   Signed-off-by: David S. Miller <davem@davemloft.net>
-# 
-# drivers/net/tg3.c
-#   2004/08/30 15:11:48-07:00 mchan@broadcom.com +2 -1
-#   [TG3]: Check MAC_STATUS_SIGNAL_DET in serdes polling.
-#   
-#   Otherwise we do not handle properly the case
-#   where the switch/hub does not support auto-
-#   negotiation.  This is what was breaking 5704
-#   hw fiber autoneg.
-#   
-#   Signed-off-by: David S. Miller <davem@davemloft.net>
-# 
-diff -Nru a/drivers/net/tg3.c b/drivers/net/tg3.c
---- a/drivers/net/tg3.c	2004-09-03 18:33:38 -07:00
-+++ b/drivers/net/tg3.c	2004-09-03 18:33:38 -07:00
-@@ -5602,7 +5602,8 @@
- 				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) {

Modified: trunk/kernel-2.4/source/kernel-source-2.4.29-2.4.29/debian/patches/series/2.4.29-1
===================================================================
--- trunk/kernel-2.4/source/kernel-source-2.4.29-2.4.29/debian/patches/series/2.4.29-1	2005-02-17 07:36:51 UTC (rev 2503)
+++ trunk/kernel-2.4/source/kernel-source-2.4.29-2.4.29/debian/patches/series/2.4.29-1	2005-02-17 09:27:41 UTC (rev 2504)
@@ -71,7 +71,6 @@
 + 070_ide_scan_pcibus.diff
 + 071_dep_fw_loader-2.diff
 + 072_6300esb_sata.diff
-+ 073_tg3_hw_autoneg.diff
 + 075_lvm_ioctl.diff
 + 076_isofs_acorn_support.diff
 + 078_isofs_nodot_execute.diff