Re: TG3 doesn't work in kernel 2.4.27 (David S. Miller)

From: Brian Somers
Date: Fri Sep 10 2004 - 07:37:17 EST


David S. Miller wrote:
On Thu, 26 Aug 2004 11:49:57 +0100
Brian Somers <brian.somers@xxxxxxx> wrote:


Can we get this guy to try running an older version of tg3 to see
what change introduce the issue?


Brian, we already narrowed it down to exactly the hw autoneg
changes Sun wrote. It breaks the IBM blades onboard 5704
fibre chips. Reverting your change or disabling hw autoneg
in the new code both fix the problem.

The problem seems to be that autoneg is disabled on the IBM switches.
After disabling autoneg on the Sun shelf switches, I see the problem.
This patch fixes things by reverting to sw autoneg which defaults to
a 1000Mbps/full-duplex link but with no flow control when it fails
(IBM should really have autoneg enabled!) - I'd appreciate it if
someone could test this against an IBM blade.

The patch is against the 2.6.8-1.521 version of tg3.c but should
hopefully apply to other recent versions. If there are problems,
because tw32_f() isn't defined, change

tw32_f(x, y);

to

tw32(x, y);
tr32(x);

Cheers.

--
Brian Somers Sun Microsystems
Sparc House, Guillemont Park
Software Engineer - LSE Minley Road, Blackwater
Tel: +44 1252 421 263 Ext: 21263 Camberley GU17 9QG
--- tg3.c.orig 2004-09-10 13:24:28.000000000 +0100
+++ tg3.c 2004-09-10 13:24:14.000000000 +0100
@@ -2051,9 +2051,25 @@
break;
udelay(1);
}
- if (tick >= 195000)
- printk(KERN_INFO PFX "%s: HW autoneg failed !\n",
+ if (tick >= 195000) {
+ u32 digctrl, txctrl;
+
+ printk(KERN_INFO PFX
+ "%s: HW autoneg failed - disabled\n",
tp->dev->name);
+
+ digctrl = tr32(SG_DIG_CTRL);
+ digctrl &= ~SG_DIG_USING_HW_AUTONEG;
+
+ txctrl = tr32(MAC_SERDES_CFG);
+ txctrl &= ~MAC_SERDES_CFG_EDGE_SELECT;
+ tw32_f(MAC_SERDES_CFG, txctrl);
+ tw32_f(SG_DIG_CTRL, digctrl | SG_DIG_SOFT_RESET);
+ udelay(5);
+ tw32_f(SG_DIG_CTRL, digctrl);
+
+ tp->tg3_flags2 &= ~TG3_FLG2_HW_AUTONEG;
+ }
}

/* Reset when initting first time or we have a link. */
@@ -5280,7 +5296,6 @@
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);