From e0f9c4f332c99b213d4a0b7cd21dc0781ceb3d86 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Thu, 23 Sep 2010 10:59:18 +0000 Subject: [PATCH] de2104x: disable autonegotiation on broken hardware At least on older 21041-AA chips (mine is rev. 11), TP duplex autonegotiation causes the card not to work at all (link is up but no packets are transmitted). de4x5 disables autonegotiation completely. But it seems to work on newer (21041-PA rev. 21) so disable it only on rev<20 chips. Signed-off-by: Ondrej Zary Acked-by: Jeff Garzik Signed-off-by: David S. Miller --- drivers/net/tulip/de2104x.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index 5efa57757a2c..9d6b7e9c7a6b 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c @@ -364,6 +364,8 @@ static u16 t21040_csr15[] = { 0, 0, 0x0006, 0x0000, 0x0000, }; /* 21041 transceiver register settings: TP AUTO, BNC, AUI, TP, TP FD*/ static u16 t21041_csr13[] = { 0xEF01, 0xEF09, 0xEF09, 0xEF01, 0xEF09, }; static u16 t21041_csr14[] = { 0xFFFF, 0xF7FD, 0xF7FD, 0x6F3F, 0x6F3D, }; +/* If on-chip autonegotiation is broken, use half-duplex (FF3F) instead */ +static u16 t21041_csr14_brk[] = { 0xFF3F, 0xF7FD, 0xF7FD, 0x6F3F, 0x6F3D, }; static u16 t21041_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, }; @@ -1911,8 +1913,14 @@ static void __devinit de21041_get_srom_info (struct de_private *de) for (i = 0; i < DE_MAX_MEDIA; i++) { if (de->media[i].csr13 == 0xffff) de->media[i].csr13 = t21041_csr13[i]; - if (de->media[i].csr14 == 0xffff) - de->media[i].csr14 = t21041_csr14[i]; + if (de->media[i].csr14 == 0xffff) { + /* autonegotiation is broken at least on some chip + revisions - rev. 0x21 works, 0x11 does not */ + if (de->pdev->revision < 0x20) + de->media[i].csr14 = t21041_csr14_brk[i]; + else + de->media[i].csr14 = t21041_csr14[i]; + } if (de->media[i].csr15 == 0xffff) de->media[i].csr15 = t21041_csr15[i]; } -- GitLab