aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sis190.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sis190.c')
-rw-r--r--drivers/net/sis190.c131
1 files changed, 86 insertions, 45 deletions
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index bf3440aa6c24..92f75529eff8 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -179,14 +179,6 @@ enum sis190_register_content {
179 TxInterFrameGapShift = 24, 179 TxInterFrameGapShift = 24,
180 TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */ 180 TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */
181 181
182 /* StationControl */
183 _1000bpsF = 0x1c00,
184 _1000bpsH = 0x0c00,
185 _100bpsF = 0x1800,
186 _100bpsH = 0x0800,
187 _10bpsF = 0x1400,
188 _10bpsH = 0x0400,
189
190 LinkStatus = 0x02, // unused 182 LinkStatus = 0x02, // unused
191 FullDup = 0x01, // unused 183 FullDup = 0x01, // unused
192 184
@@ -279,6 +271,12 @@ enum sis190_eeprom_address {
279 EEPROMMACAddr = 0x03 271 EEPROMMACAddr = 0x03
280}; 272};
281 273
274enum sis190_feature {
275 F_HAS_RGMII = 1,
276 F_PHY_88E1111 = 2,
277 F_PHY_BCM5461 = 4
278};
279
282struct sis190_private { 280struct sis190_private {
283 void __iomem *mmio_addr; 281 void __iomem *mmio_addr;
284 struct pci_dev *pci_dev; 282 struct pci_dev *pci_dev;
@@ -300,6 +298,7 @@ struct sis190_private {
300 u32 msg_enable; 298 u32 msg_enable;
301 struct mii_if_info mii_if; 299 struct mii_if_info mii_if;
302 struct list_head first_phy; 300 struct list_head first_phy;
301 u32 features;
303}; 302};
304 303
305struct sis190_phy { 304struct sis190_phy {
@@ -321,24 +320,25 @@ static struct mii_chip_info {
321 const char *name; 320 const char *name;
322 u16 id[2]; 321 u16 id[2];
323 unsigned int type; 322 unsigned int type;
323 u32 feature;
324} mii_chip_table[] = { 324} mii_chip_table[] = {
325 { "Broadcom PHY BCM5461", { 0x0020, 0x60c0 }, LAN }, 325 { "Broadcom PHY BCM5461", { 0x0020, 0x60c0 }, LAN, F_PHY_BCM5461 },
326 { "Agere PHY ET1101B", { 0x0282, 0xf010 }, LAN }, 326 { "Agere PHY ET1101B", { 0x0282, 0xf010 }, LAN, 0 },
327 { "Marvell PHY 88E1111", { 0x0141, 0x0cc0 }, LAN }, 327 { "Marvell PHY 88E1111", { 0x0141, 0x0cc0 }, LAN, F_PHY_88E1111 },
328 { "Realtek PHY RTL8201", { 0x0000, 0x8200 }, LAN }, 328 { "Realtek PHY RTL8201", { 0x0000, 0x8200 }, LAN, 0 },
329 { NULL, } 329 { NULL, }
330}; 330};
331 331
332const static struct { 332const static struct {
333 const char *name; 333 const char *name;
334 u8 version; /* depend on docs */
335 u32 RxConfigMask; /* clear the bits supported by this chip */
336} sis_chip_info[] = { 334} sis_chip_info[] = {
337 { DRV_NAME, 0x00, 0xff7e1880, }, 335 { "SiS 190 PCI Fast Ethernet adapter" },
336 { "SiS 191 PCI Gigabit Ethernet adapter" },
338}; 337};
339 338
340static struct pci_device_id sis190_pci_tbl[] __devinitdata = { 339static struct pci_device_id sis190_pci_tbl[] __devinitdata = {
341 { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x0190), 0, 0, 0 }, 340 { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x0190), 0, 0, 0 },
341 { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x0191), 0, 0, 1 },
342 { 0, }, 342 { 0, },
343}; 343};
344 344
@@ -360,7 +360,7 @@ MODULE_VERSION(DRV_VERSION);
360MODULE_LICENSE("GPL"); 360MODULE_LICENSE("GPL");
361 361
362static const u32 sis190_intr_mask = 362static const u32 sis190_intr_mask =
363 RxQEmpty | RxQInt | TxQ1Int | TxQ0Int | RxHalt | TxHalt; 363 RxQEmpty | RxQInt | TxQ1Int | TxQ0Int | RxHalt | TxHalt | LinkChange;
364 364
365/* 365/*
366 * Maximum number of multicast addresses to filter (vs. Rx-all-multicast). 366 * Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
@@ -879,11 +879,6 @@ static void sis190_hw_start(struct net_device *dev)
879 879
880 SIS_W32(IntrStatus, 0xffffffff); 880 SIS_W32(IntrStatus, 0xffffffff);
881 SIS_W32(IntrMask, 0x0); 881 SIS_W32(IntrMask, 0x0);
882 /*
883 * Default is 100Mbps.
884 * A bit strange: 100Mbps is 0x1801 elsewhere -- FR 2005/06/09
885 */
886 SIS_W16(StationControl, 0x1901);
887 SIS_W32(GMIIControl, 0x0); 882 SIS_W32(GMIIControl, 0x0);
888 SIS_W32(TxMacControl, 0x60); 883 SIS_W32(TxMacControl, 0x60);
889 SIS_W16(RxMacControl, 0x02); 884 SIS_W16(RxMacControl, 0x02);
@@ -923,35 +918,30 @@ static void sis190_phy_task(void * data)
923 BMSR_ANEGCOMPLETE)) { 918 BMSR_ANEGCOMPLETE)) {
924 net_link(tp, KERN_WARNING "%s: PHY reset until link up.\n", 919 net_link(tp, KERN_WARNING "%s: PHY reset until link up.\n",
925 dev->name); 920 dev->name);
921 netif_carrier_off(dev);
926 mdio_write(ioaddr, phy_id, MII_BMCR, val | BMCR_RESET); 922 mdio_write(ioaddr, phy_id, MII_BMCR, val | BMCR_RESET);
927 mod_timer(&tp->timer, jiffies + SIS190_PHY_TIMEOUT); 923 mod_timer(&tp->timer, jiffies + SIS190_PHY_TIMEOUT);
928 } else { 924 } else {
929 /* Rejoice ! */ 925 /* Rejoice ! */
930 struct { 926 struct {
931 int val; 927 int val;
928 u32 ctl;
932 const char *msg; 929 const char *msg;
933 u16 ctl;
934 } reg31[] = { 930 } reg31[] = {
935 { LPA_1000XFULL | LPA_SLCT, 931 { LPA_1000XFULL | LPA_SLCT, 0x07000c00 | 0x00001000,
936 "1000 Mbps Full Duplex", 932 "1000 Mbps Full Duplex" },
937 0x01 | _1000bpsF }, 933 { LPA_1000XHALF | LPA_SLCT, 0x07000c00,
938 { LPA_1000XHALF | LPA_SLCT, 934 "1000 Mbps Half Duplex" },
939 "1000 Mbps Half Duplex", 935 { LPA_100FULL, 0x04000800 | 0x00001000,
940 0x01 | _1000bpsH }, 936 "100 Mbps Full Duplex" },
941 { LPA_100FULL, 937 { LPA_100HALF, 0x04000800,
942 "100 Mbps Full Duplex", 938 "100 Mbps Half Duplex" },
943 0x01 | _100bpsF }, 939 { LPA_10FULL, 0x04000400 | 0x00001000,
944 { LPA_100HALF, 940 "10 Mbps Full Duplex" },
945 "100 Mbps Half Duplex", 941 { LPA_10HALF, 0x04000400,
946 0x01 | _100bpsH }, 942 "10 Mbps Half Duplex" },
947 { LPA_10FULL, 943 { 0, 0x04000400, "unknown" }
948 "10 Mbps Full Duplex", 944 }, *p;
949 0x01 | _10bpsF },
950 { LPA_10HALF,
951 "10 Mbps Half Duplex",
952 0x01 | _10bpsH },
953 { 0, "unknown", 0x0000 }
954 }, *p;
955 u16 adv; 945 u16 adv;
956 946
957 val = mdio_read(ioaddr, phy_id, 0x1f); 947 val = mdio_read(ioaddr, phy_id, 0x1f);
@@ -964,12 +954,29 @@ static void sis190_phy_task(void * data)
964 954
965 val &= adv; 955 val &= adv;
966 956
967 for (p = reg31; p->ctl; p++) { 957 for (p = reg31; p->val; p++) {
968 if ((val & p->val) == p->val) 958 if ((val & p->val) == p->val)
969 break; 959 break;
970 } 960 }
971 if (p->ctl) 961
972 SIS_W16(StationControl, p->ctl); 962 p->ctl |= SIS_R32(StationControl) & ~0x0f001c00;
963
964 if ((tp->features & F_HAS_RGMII) &&
965 (tp->features & F_PHY_BCM5461)) {
966 // Set Tx Delay in RGMII mode.
967 mdio_write(ioaddr, phy_id, 0x18, 0xf1c7);
968 udelay(200);
969 mdio_write(ioaddr, phy_id, 0x1c, 0x8c00);
970 p->ctl |= 0x03000000;
971 }
972
973 SIS_W32(StationControl, p->ctl);
974
975 if (tp->features & F_HAS_RGMII) {
976 SIS_W32(RGDelay, 0x0441);
977 SIS_W32(RGDelay, 0x0440);
978 }
979
973 net_link(tp, KERN_INFO "%s: link on %s mode.\n", dev->name, 980 net_link(tp, KERN_INFO "%s: link on %s mode.\n", dev->name,
974 p->msg); 981 p->msg);
975 netif_carrier_on(dev); 982 netif_carrier_on(dev);
@@ -1308,6 +1315,7 @@ static void sis190_init_phy(struct net_device *dev, struct sis190_private *tp,
1308 phy->type = (p->type == MIX) ? 1315 phy->type = (p->type == MIX) ?
1309 ((mii_status & (BMSR_100FULL | BMSR_100HALF)) ? 1316 ((mii_status & (BMSR_100FULL | BMSR_100HALF)) ?
1310 LAN : HOME) : p->type; 1317 LAN : HOME) : p->type;
1318 tp->features |= p->feature;
1311 } else 1319 } else
1312 phy->type = UNKNOWN; 1320 phy->type = UNKNOWN;
1313 1321
@@ -1316,6 +1324,25 @@ static void sis190_init_phy(struct net_device *dev, struct sis190_private *tp,
1316 (phy->type == UNKNOWN) ? "Unknown PHY" : p->name, phy_id); 1324 (phy->type == UNKNOWN) ? "Unknown PHY" : p->name, phy_id);
1317} 1325}
1318 1326
1327static void sis190_mii_probe_88e1111_fixup(struct sis190_private *tp)
1328{
1329 if (tp->features & F_PHY_88E1111) {
1330 void __iomem *ioaddr = tp->mmio_addr;
1331 int phy_id = tp->mii_if.phy_id;
1332 u16 reg[2][2] = {
1333 { 0x808b, 0x0ce1 },
1334 { 0x808f, 0x0c60 }
1335 }, *p;
1336
1337 p = (tp->features & F_HAS_RGMII) ? reg[0] : reg[1];
1338
1339 mdio_write(ioaddr, phy_id, 0x1b, p[0]);
1340 udelay(200);
1341 mdio_write(ioaddr, phy_id, 0x14, p[1]);
1342 udelay(200);
1343 }
1344}
1345
1319/** 1346/**
1320 * sis190_mii_probe - Probe MII PHY for sis190 1347 * sis190_mii_probe - Probe MII PHY for sis190
1321 * @dev: the net device to probe for 1348 * @dev: the net device to probe for
@@ -1366,6 +1393,8 @@ static int __devinit sis190_mii_probe(struct net_device *dev)
1366 /* Select default PHY for mac */ 1393 /* Select default PHY for mac */
1367 sis190_default_phy(dev); 1394 sis190_default_phy(dev);
1368 1395
1396 sis190_mii_probe_88e1111_fixup(tp);
1397
1369 mii_if->dev = dev; 1398 mii_if->dev = dev;
1370 mii_if->mdio_read = __mdio_read; 1399 mii_if->mdio_read = __mdio_read;
1371 mii_if->mdio_write = __mdio_write; 1400 mii_if->mdio_write = __mdio_write;
@@ -1505,6 +1534,11 @@ static void sis190_tx_timeout(struct net_device *dev)
1505 netif_wake_queue(dev); 1534 netif_wake_queue(dev);
1506} 1535}
1507 1536
1537static void sis190_set_rgmii(struct sis190_private *tp, u8 reg)
1538{
1539 tp->features |= (reg & 0x80) ? F_HAS_RGMII : 0;
1540}
1541
1508static int __devinit sis190_get_mac_addr_from_eeprom(struct pci_dev *pdev, 1542static int __devinit sis190_get_mac_addr_from_eeprom(struct pci_dev *pdev,
1509 struct net_device *dev) 1543 struct net_device *dev)
1510{ 1544{
@@ -1532,6 +1566,8 @@ static int __devinit sis190_get_mac_addr_from_eeprom(struct pci_dev *pdev,
1532 ((u16 *)dev->dev_addr)[0] = le16_to_cpu(w); 1566 ((u16 *)dev->dev_addr)[0] = le16_to_cpu(w);
1533 } 1567 }
1534 1568
1569 sis190_set_rgmii(tp, sis190_read_eeprom(ioaddr, EEPROMInfo));
1570
1535 return 0; 1571 return 0;
1536} 1572}
1537 1573
@@ -1577,6 +1613,8 @@ static int __devinit sis190_get_mac_addr_from_apc(struct pci_dev *pdev,
1577 outb(0x12, 0x78); 1613 outb(0x12, 0x78);
1578 reg = inb(0x79); 1614 reg = inb(0x79);
1579 1615
1616 sis190_set_rgmii(tp, reg);
1617
1580 /* Restore the value to ISA Bridge */ 1618 /* Restore the value to ISA Bridge */
1581 pci_write_config_byte(isa_bridge, 0x48, tmp8); 1619 pci_write_config_byte(isa_bridge, 0x48, tmp8);
1582 pci_dev_put(isa_bridge); 1620 pci_dev_put(isa_bridge);
@@ -1799,6 +1837,9 @@ static int __devinit sis190_init_one(struct pci_dev *pdev,
1799 dev->dev_addr[2], dev->dev_addr[3], 1837 dev->dev_addr[2], dev->dev_addr[3],
1800 dev->dev_addr[4], dev->dev_addr[5]); 1838 dev->dev_addr[4], dev->dev_addr[5]);
1801 1839
1840 net_probe(tp, KERN_INFO "%s: %s mode.\n", dev->name,
1841 (tp->features & F_HAS_RGMII) ? "RGMII" : "GMII");
1842
1802 netif_carrier_off(dev); 1843 netif_carrier_off(dev);
1803 1844
1804 sis190_set_speed_auto(dev); 1845 sis190_set_speed_auto(dev);