diff options
-rw-r--r-- | drivers/net/sis190.c | 49 |
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 | ||
282 | enum sis190_feature { | ||
283 | F_HAS_RGMII = 1, | ||
284 | F_PHY_88E1111 = 2 | ||
285 | }; | ||
286 | |||
282 | struct sis190_private { | 287 | struct 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 | ||
305 | struct sis190_phy { | 311 | struct 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 | ||
1328 | static 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 | ||
1538 | static void sis190_set_rgmii(struct sis190_private *tp, u8 reg) | ||
1539 | { | ||
1540 | tp->features |= (reg & 0x80) ? F_HAS_RGMII : 0; | ||
1541 | } | ||
1542 | |||
1509 | static int __devinit sis190_get_mac_addr_from_eeprom(struct pci_dev *pdev, | 1543 | static 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); |