diff options
Diffstat (limited to 'drivers/net/ucc_geth.c')
-rw-r--r-- | drivers/net/ucc_geth.c | 113 |
1 files changed, 46 insertions, 67 deletions
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index e2f2e91cfdd2..40c6eba775ce 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c | |||
@@ -65,8 +65,6 @@ | |||
65 | 65 | ||
66 | static DEFINE_SPINLOCK(ugeth_lock); | 66 | static DEFINE_SPINLOCK(ugeth_lock); |
67 | 67 | ||
68 | static void uec_configure_serdes(struct net_device *dev); | ||
69 | |||
70 | static struct { | 68 | static struct { |
71 | u32 msg_enable; | 69 | u32 msg_enable; |
72 | } debug = { -1 }; | 70 | } debug = { -1 }; |
@@ -1536,6 +1534,49 @@ static void adjust_link(struct net_device *dev) | |||
1536 | spin_unlock_irqrestore(&ugeth->lock, flags); | 1534 | spin_unlock_irqrestore(&ugeth->lock, flags); |
1537 | } | 1535 | } |
1538 | 1536 | ||
1537 | /* Initialize TBI PHY interface for communicating with the | ||
1538 | * SERDES lynx PHY on the chip. We communicate with this PHY | ||
1539 | * through the MDIO bus on each controller, treating it as a | ||
1540 | * "normal" PHY at the address found in the UTBIPA register. We assume | ||
1541 | * that the UTBIPA register is valid. Either the MDIO bus code will set | ||
1542 | * it to a value that doesn't conflict with other PHYs on the bus, or the | ||
1543 | * value doesn't matter, as there are no other PHYs on the bus. | ||
1544 | */ | ||
1545 | static void uec_configure_serdes(struct net_device *dev) | ||
1546 | { | ||
1547 | struct ucc_geth_private *ugeth = netdev_priv(dev); | ||
1548 | struct ucc_geth_info *ug_info = ugeth->ug_info; | ||
1549 | struct phy_device *tbiphy; | ||
1550 | |||
1551 | if (!ug_info->tbi_node) { | ||
1552 | dev_warn(&dev->dev, "SGMII mode requires that the device " | ||
1553 | "tree specify a tbi-handle\n"); | ||
1554 | return; | ||
1555 | } | ||
1556 | |||
1557 | tbiphy = of_phy_find_device(ug_info->tbi_node); | ||
1558 | if (!tbiphy) { | ||
1559 | dev_err(&dev->dev, "error: Could not get TBI device\n"); | ||
1560 | return; | ||
1561 | } | ||
1562 | |||
1563 | /* | ||
1564 | * If the link is already up, we must already be ok, and don't need to | ||
1565 | * configure and reset the TBI<->SerDes link. Maybe U-Boot configured | ||
1566 | * everything for us? Resetting it takes the link down and requires | ||
1567 | * several seconds for it to come back. | ||
1568 | */ | ||
1569 | if (phy_read(tbiphy, ENET_TBI_MII_SR) & TBISR_LSTATUS) | ||
1570 | return; | ||
1571 | |||
1572 | /* Single clk mode, mii mode off(for serdes communication) */ | ||
1573 | phy_write(tbiphy, ENET_TBI_MII_ANA, TBIANA_SETTINGS); | ||
1574 | |||
1575 | phy_write(tbiphy, ENET_TBI_MII_TBICON, TBICON_CLK_SELECT); | ||
1576 | |||
1577 | phy_write(tbiphy, ENET_TBI_MII_CR, TBICR_SETTINGS); | ||
1578 | } | ||
1579 | |||
1539 | /* Configure the PHY for dev. | 1580 | /* Configure the PHY for dev. |
1540 | * returns 0 if success. -1 if failure | 1581 | * returns 0 if success. -1 if failure |
1541 | */ | 1582 | */ |
@@ -1577,41 +1618,7 @@ static int init_phy(struct net_device *dev) | |||
1577 | return 0; | 1618 | return 0; |
1578 | } | 1619 | } |
1579 | 1620 | ||
1580 | /* Initialize TBI PHY interface for communicating with the | ||
1581 | * SERDES lynx PHY on the chip. We communicate with this PHY | ||
1582 | * through the MDIO bus on each controller, treating it as a | ||
1583 | * "normal" PHY at the address found in the UTBIPA register. We assume | ||
1584 | * that the UTBIPA register is valid. Either the MDIO bus code will set | ||
1585 | * it to a value that doesn't conflict with other PHYs on the bus, or the | ||
1586 | * value doesn't matter, as there are no other PHYs on the bus. | ||
1587 | */ | ||
1588 | static void uec_configure_serdes(struct net_device *dev) | ||
1589 | { | ||
1590 | struct ucc_geth_private *ugeth = netdev_priv(dev); | ||
1591 | |||
1592 | if (!ugeth->tbiphy) { | ||
1593 | printk(KERN_WARNING "SGMII mode requires that the device " | ||
1594 | "tree specify a tbi-handle\n"); | ||
1595 | return; | ||
1596 | } | ||
1597 | 1621 | ||
1598 | /* | ||
1599 | * If the link is already up, we must already be ok, and don't need to | ||
1600 | * configure and reset the TBI<->SerDes link. Maybe U-Boot configured | ||
1601 | * everything for us? Resetting it takes the link down and requires | ||
1602 | * several seconds for it to come back. | ||
1603 | */ | ||
1604 | if (phy_read(ugeth->tbiphy, ENET_TBI_MII_SR) & TBISR_LSTATUS) | ||
1605 | return; | ||
1606 | |||
1607 | /* Single clk mode, mii mode off(for serdes communication) */ | ||
1608 | phy_write(ugeth->tbiphy, ENET_TBI_MII_ANA, TBIANA_SETTINGS); | ||
1609 | |||
1610 | phy_write(ugeth->tbiphy, ENET_TBI_MII_TBICON, TBICON_CLK_SELECT); | ||
1611 | |||
1612 | phy_write(ugeth->tbiphy, ENET_TBI_MII_CR, TBICR_SETTINGS); | ||
1613 | |||
1614 | } | ||
1615 | 1622 | ||
1616 | static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth) | 1623 | static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth) |
1617 | { | 1624 | { |
@@ -3711,6 +3718,9 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma | |||
3711 | } | 3718 | } |
3712 | ug_info->phy_node = phy; | 3719 | ug_info->phy_node = phy; |
3713 | 3720 | ||
3721 | /* Find the TBI PHY node. If it's not there, we don't support SGMII */ | ||
3722 | ug_info->tbi_node = of_parse_phandle(np, "tbi-handle", 0); | ||
3723 | |||
3714 | /* get the phy interface type, or default to MII */ | 3724 | /* get the phy interface type, or default to MII */ |
3715 | prop = of_get_property(np, "phy-connection-type", NULL); | 3725 | prop = of_get_property(np, "phy-connection-type", NULL); |
3716 | if (!prop) { | 3726 | if (!prop) { |
@@ -3818,37 +3828,6 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma | |||
3818 | ugeth->ndev = dev; | 3828 | ugeth->ndev = dev; |
3819 | ugeth->node = np; | 3829 | ugeth->node = np; |
3820 | 3830 | ||
3821 | /* Find the TBI PHY. If it's not there, we don't support SGMII */ | ||
3822 | ph = of_get_property(np, "tbi-handle", NULL); | ||
3823 | if (ph) { | ||
3824 | struct device_node *tbi = of_find_node_by_phandle(*ph); | ||
3825 | struct of_device *ofdev; | ||
3826 | struct mii_bus *bus; | ||
3827 | const unsigned int *id; | ||
3828 | |||
3829 | if (!tbi) | ||
3830 | return 0; | ||
3831 | |||
3832 | mdio = of_get_parent(tbi); | ||
3833 | if (!mdio) | ||
3834 | return 0; | ||
3835 | |||
3836 | ofdev = of_find_device_by_node(mdio); | ||
3837 | |||
3838 | of_node_put(mdio); | ||
3839 | |||
3840 | id = of_get_property(tbi, "reg", NULL); | ||
3841 | if (!id) | ||
3842 | return 0; | ||
3843 | of_node_put(tbi); | ||
3844 | |||
3845 | bus = dev_get_drvdata(&ofdev->dev); | ||
3846 | if (!bus) | ||
3847 | return 0; | ||
3848 | |||
3849 | ugeth->tbiphy = bus->phy_map[*id]; | ||
3850 | } | ||
3851 | |||
3852 | return 0; | 3831 | return 0; |
3853 | } | 3832 | } |
3854 | 3833 | ||