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