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 <linux@rainbow-software.org>
Acked-by: Jeff Garzik <jgarzik@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by Ondrej Zary and committed by David S. Miller e0f9c4f3 f064af1e

+10 -2
+10 -2
drivers/net/tulip/de2104x.c
··· 364 /* 21041 transceiver register settings: TP AUTO, BNC, AUI, TP, TP FD*/ 365 static u16 t21041_csr13[] = { 0xEF01, 0xEF09, 0xEF09, 0xEF01, 0xEF09, }; 366 static u16 t21041_csr14[] = { 0xFFFF, 0xF7FD, 0xF7FD, 0x6F3F, 0x6F3D, }; 367 static u16 t21041_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, }; 368 369 ··· 1913 for (i = 0; i < DE_MAX_MEDIA; i++) { 1914 if (de->media[i].csr13 == 0xffff) 1915 de->media[i].csr13 = t21041_csr13[i]; 1916 - if (de->media[i].csr14 == 0xffff) 1917 - de->media[i].csr14 = t21041_csr14[i]; 1918 if (de->media[i].csr15 == 0xffff) 1919 de->media[i].csr15 = t21041_csr15[i]; 1920 }
··· 364 /* 21041 transceiver register settings: TP AUTO, BNC, AUI, TP, TP FD*/ 365 static u16 t21041_csr13[] = { 0xEF01, 0xEF09, 0xEF09, 0xEF01, 0xEF09, }; 366 static u16 t21041_csr14[] = { 0xFFFF, 0xF7FD, 0xF7FD, 0x6F3F, 0x6F3D, }; 367 + /* If on-chip autonegotiation is broken, use half-duplex (FF3F) instead */ 368 + static u16 t21041_csr14_brk[] = { 0xFF3F, 0xF7FD, 0xF7FD, 0x6F3F, 0x6F3D, }; 369 static u16 t21041_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, }; 370 371 ··· 1911 for (i = 0; i < DE_MAX_MEDIA; i++) { 1912 if (de->media[i].csr13 == 0xffff) 1913 de->media[i].csr13 = t21041_csr13[i]; 1914 + if (de->media[i].csr14 == 0xffff) { 1915 + /* autonegotiation is broken at least on some chip 1916 + revisions - rev. 0x21 works, 0x11 does not */ 1917 + if (de->pdev->revision < 0x20) 1918 + de->media[i].csr14 = t21041_csr14_brk[i]; 1919 + else 1920 + de->media[i].csr14 = t21041_csr14[i]; 1921 + } 1922 if (de->media[i].csr15 == 0xffff) 1923 de->media[i].csr15 = t21041_csr15[i]; 1924 }