aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/sis190.c49
1 files changed, 45 insertions, 4 deletions
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index 5f1d0ad54969..95ec3af9ec74 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -279,6 +279,11 @@ enum sis190_eeprom_address {
279 EEPROMMACAddr = 0x03 279 EEPROMMACAddr = 0x03
280}; 280};
281 281
282enum sis190_feature {
283 F_HAS_RGMII = 1,
284 F_PHY_88E1111 = 2
285};
286
282struct sis190_private { 287struct sis190_private {
283 void __iomem *mmio_addr; 288 void __iomem *mmio_addr;
284 struct pci_dev *pci_dev; 289 struct pci_dev *pci_dev;
@@ -300,6 +305,7 @@ struct sis190_private {
300 u32 msg_enable; 305 u32 msg_enable;
301 struct mii_if_info mii_if; 306 struct mii_if_info mii_if;
302 struct list_head first_phy; 307 struct list_head first_phy;
308 u32 features;
303}; 309};
304 310
305struct sis190_phy { 311struct sis190_phy {
@@ -321,11 +327,12 @@ static struct mii_chip_info {
321 const char *name; 327 const char *name;
322 u16 id[2]; 328 u16 id[2];
323 unsigned int type; 329 unsigned int type;
330 u32 feature;
324} mii_chip_table[] = { 331} mii_chip_table[] = {
325 { "Broadcom PHY BCM5461", { 0x0020, 0x60c0 }, LAN }, 332 { "Broadcom PHY BCM5461", { 0x0020, 0x60c0 }, LAN, 0 },
326 { "Agere PHY ET1101B", { 0x0282, 0xf010 }, LAN }, 333 { "Agere PHY ET1101B", { 0x0282, 0xf010 }, LAN, 0 },
327 { "Marvell PHY 88E1111", { 0x0141, 0x0cc0 }, LAN }, 334 { "Marvell PHY 88E1111", { 0x0141, 0x0cc0 }, LAN, F_PHY_88E1111 },
328 { "Realtek PHY RTL8201", { 0x0000, 0x8200 }, LAN }, 335 { "Realtek PHY RTL8201", { 0x0000, 0x8200 }, LAN, 0 },
329 { NULL, } 336 { NULL, }
330}; 337};
331 338
@@ -1309,6 +1316,7 @@ static void sis190_init_phy(struct net_device *dev, struct sis190_private *tp,
1309 phy->type = (p->type == MIX) ? 1316 phy->type = (p->type == MIX) ?
1310 ((mii_status & (BMSR_100FULL | BMSR_100HALF)) ? 1317 ((mii_status & (BMSR_100FULL | BMSR_100HALF)) ?
1311 LAN : HOME) : p->type; 1318 LAN : HOME) : p->type;
1319 tp->features |= p->feature;
1312 } else 1320 } else
1313 phy->type = UNKNOWN; 1321 phy->type = UNKNOWN;
1314 1322
@@ -1317,6 +1325,25 @@ static void sis190_init_phy(struct net_device *dev, struct sis190_private *tp,
1317 (phy->type == UNKNOWN) ? "Unknown PHY" : p->name, phy_id); 1325 (phy->type == UNKNOWN) ? "Unknown PHY" : p->name, phy_id);
1318} 1326}
1319 1327
1328static void sis190_mii_probe_88e1111_fixup(struct sis190_private *tp)
1329{
1330 if (tp->features & F_PHY_88E1111) {
1331 void __iomem *ioaddr = tp->mmio_addr;
1332 int phy_id = tp->mii_if.phy_id;
1333 u16 reg[2][2] = {
1334 { 0x808b, 0x0ce1 },
1335 { 0x808f, 0x0c60 }
1336 }, *p;
1337
1338 p = (tp->features & F_HAS_RGMII) ? reg[0] : reg[1];
1339
1340 mdio_write(ioaddr, phy_id, 0x1b, p[0]);
1341 udelay(200);
1342 mdio_write(ioaddr, phy_id, 0x14, p[1]);
1343 udelay(200);
1344 }
1345}
1346
1320/** 1347/**
1321 * sis190_mii_probe - Probe MII PHY for sis190 1348 * sis190_mii_probe - Probe MII PHY for sis190
1322 * @dev: the net device to probe for 1349 * @dev: the net device to probe for
@@ -1367,6 +1394,8 @@ static int __devinit sis190_mii_probe(struct net_device *dev)
1367 /* Select default PHY for mac */ 1394 /* Select default PHY for mac */
1368 sis190_default_phy(dev); 1395 sis190_default_phy(dev);
1369 1396
1397 sis190_mii_probe_88e1111_fixup(tp);
1398
1370 mii_if->dev = dev; 1399 mii_if->dev = dev;
1371 mii_if->mdio_read = __mdio_read; 1400 mii_if->mdio_read = __mdio_read;
1372 mii_if->mdio_write = __mdio_write; 1401 mii_if->mdio_write = __mdio_write;
@@ -1506,6 +1535,11 @@ static void sis190_tx_timeout(struct net_device *dev)
1506 netif_wake_queue(dev); 1535 netif_wake_queue(dev);
1507} 1536}
1508 1537
1538static void sis190_set_rgmii(struct sis190_private *tp, u8 reg)
1539{
1540 tp->features |= (reg & 0x80) ? F_HAS_RGMII : 0;
1541}
1542
1509static int __devinit sis190_get_mac_addr_from_eeprom(struct pci_dev *pdev, 1543static int __devinit sis190_get_mac_addr_from_eeprom(struct pci_dev *pdev,
1510 struct net_device *dev) 1544 struct net_device *dev)
1511{ 1545{
@@ -1533,6 +1567,8 @@ static int __devinit sis190_get_mac_addr_from_eeprom(struct pci_dev *pdev,
1533 ((u16 *)dev->dev_addr)[0] = le16_to_cpu(w); 1567 ((u16 *)dev->dev_addr)[0] = le16_to_cpu(w);
1534 } 1568 }
1535 1569
1570 sis190_set_rgmii(tp, sis190_read_eeprom(ioaddr, EEPROMInfo));
1571
1536 return 0; 1572 return 0;
1537} 1573}
1538 1574
@@ -1578,6 +1614,8 @@ static int __devinit sis190_get_mac_addr_from_apc(struct pci_dev *pdev,
1578 outb(0x12, 0x78); 1614 outb(0x12, 0x78);
1579 reg = inb(0x79); 1615 reg = inb(0x79);
1580 1616
1617 sis190_set_rgmii(tp, reg);
1618
1581 /* Restore the value to ISA Bridge */ 1619 /* Restore the value to ISA Bridge */
1582 pci_write_config_byte(isa_bridge, 0x48, tmp8); 1620 pci_write_config_byte(isa_bridge, 0x48, tmp8);
1583 pci_dev_put(isa_bridge); 1621 pci_dev_put(isa_bridge);
@@ -1800,6 +1838,9 @@ static int __devinit sis190_init_one(struct pci_dev *pdev,
1800 dev->dev_addr[2], dev->dev_addr[3], 1838 dev->dev_addr[2], dev->dev_addr[3],
1801 dev->dev_addr[4], dev->dev_addr[5]); 1839 dev->dev_addr[4], dev->dev_addr[5]);
1802 1840
1841 net_probe(tp, KERN_INFO "%s: %s mode.\n", dev->name,
1842 (tp->features & F_HAS_RGMII) ? "RGMII" : "GMII");
1843
1803 netif_carrier_off(dev); 1844 netif_carrier_off(dev);
1804 1845
1805 sis190_set_speed_auto(dev); 1846 sis190_set_speed_auto(dev);