aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sis190.c
diff options
context:
space:
mode:
authorRiccardo Ghetta <birrachiara@tin.it>2009-06-04 05:05:20 -0400
committerDavid S. Miller <davem@davemloft.net>2009-06-08 03:15:14 -0400
commit1feede014bf3c58f60b35f91dcd8a2f89b3908ad (patch)
treea0e7058620a59c7e11931ed6769c774c2a502422 /drivers/net/sis190.c
parent856f8f41d44c9a310665213745bba655e52641fd (diff)
sis190: fix gigabit negotiation
Fixes an initialization error; the chip negotiates gigabit, but the driver mistakenly handled it as 100Mb. Changes based on both SiS own GPL driver and forcedeth. Hopefully should fix http://bugzilla.kernel.org/show_bug.cgi?id=9735 http://bugzilla.kernel.org/show_bug.cgi?id=11149 Signed-off-by: Riccardo Ghetta <birrachiara@tin.it> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/sis190.c')
-rw-r--r--drivers/net/sis190.c37
1 files changed, 25 insertions, 12 deletions
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index 75bd947d40bf..e2247669a495 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -47,7 +47,7 @@
47#define PHY_ID_ANY 0x1f 47#define PHY_ID_ANY 0x1f
48#define MII_REG_ANY 0x1f 48#define MII_REG_ANY 0x1f
49 49
50#define DRV_VERSION "1.2" 50#define DRV_VERSION "1.3"
51#define DRV_NAME "sis190" 51#define DRV_NAME "sis190"
52#define SIS190_DRIVER_NAME DRV_NAME " Gigabit Ethernet driver " DRV_VERSION 52#define SIS190_DRIVER_NAME DRV_NAME " Gigabit Ethernet driver " DRV_VERSION
53#define PFX DRV_NAME ": " 53#define PFX DRV_NAME ": "
@@ -943,9 +943,9 @@ static void sis190_phy_task(struct work_struct *work)
943 u32 ctl; 943 u32 ctl;
944 const char *msg; 944 const char *msg;
945 } reg31[] = { 945 } reg31[] = {
946 { LPA_1000XFULL | LPA_SLCT, 0x07000c00 | 0x00001000, 946 { LPA_1000FULL, 0x07000c00 | 0x00001000,
947 "1000 Mbps Full Duplex" }, 947 "1000 Mbps Full Duplex" },
948 { LPA_1000XHALF | LPA_SLCT, 0x07000c00, 948 { LPA_1000HALF, 0x07000c00,
949 "1000 Mbps Half Duplex" }, 949 "1000 Mbps Half Duplex" },
950 { LPA_100FULL, 0x04000800 | 0x00001000, 950 { LPA_100FULL, 0x04000800 | 0x00001000,
951 "100 Mbps Full Duplex" }, 951 "100 Mbps Full Duplex" },
@@ -956,22 +956,35 @@ static void sis190_phy_task(struct work_struct *work)
956 { LPA_10HALF, 0x04000400, 956 { LPA_10HALF, 0x04000400,
957 "10 Mbps Half Duplex" }, 957 "10 Mbps Half Duplex" },
958 { 0, 0x04000400, "unknown" } 958 { 0, 0x04000400, "unknown" }
959 }, *p; 959 }, *p = NULL;
960 u16 adv; 960 u16 adv, autoexp, gigadv, gigrec;
961 961
962 val = mdio_read(ioaddr, phy_id, 0x1f); 962 val = mdio_read(ioaddr, phy_id, 0x1f);
963 net_link(tp, KERN_INFO "%s: mii ext = %04x.\n", dev->name, val); 963 net_link(tp, KERN_INFO "%s: mii ext = %04x.\n", dev->name, val);
964 964
965 val = mdio_read(ioaddr, phy_id, MII_LPA); 965 val = mdio_read(ioaddr, phy_id, MII_LPA);
966 adv = mdio_read(ioaddr, phy_id, MII_ADVERTISE); 966 adv = mdio_read(ioaddr, phy_id, MII_ADVERTISE);
967 net_link(tp, KERN_INFO "%s: mii lpa = %04x adv = %04x.\n", 967 autoexp = mdio_read(ioaddr, phy_id, MII_EXPANSION);
968 dev->name, val, adv); 968 net_link(tp, KERN_INFO "%s: mii lpa=%04x adv=%04x exp=%04x.\n",
969 969 dev->name, val, adv, autoexp);
970 val &= adv; 970
971 if (val & LPA_NPAGE && autoexp & EXPANSION_NWAY) {
972 /* check for gigabit speed */
973 gigadv = mdio_read(ioaddr, phy_id, MII_CTRL1000);
974 gigrec = mdio_read(ioaddr, phy_id, MII_STAT1000);
975 val = (gigadv & (gigrec >> 2));
976 if (val & ADVERTISE_1000FULL)
977 p = reg31;
978 else if (val & ADVERTISE_1000HALF)
979 p = reg31 + 1;
980 }
981 if (!p) {
982 val &= adv;
971 983
972 for (p = reg31; p->val; p++) { 984 for (p = reg31; p->val; p++) {
973 if ((val & p->val) == p->val) 985 if ((val & p->val) == p->val)
974 break; 986 break;
987 }
975 } 988 }
976 989
977 p->ctl |= SIS_R32(StationControl) & ~0x0f001c00; 990 p->ctl |= SIS_R32(StationControl) & ~0x0f001c00;