aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ucc_geth.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ucc_geth.c')
-rw-r--r--drivers/net/ucc_geth.c58
1 files changed, 57 insertions, 1 deletions
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 0cf22c4f123b..255d28d4f84e 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2006-2007 Freescale Semicondutor, Inc. All rights reserved. 2 * Copyright (C) 2006-2009 Freescale Semicondutor, Inc. All rights reserved.
3 * 3 *
4 * Author: Shlomi Gridish <gridish@freescale.com> 4 * Author: Shlomi Gridish <gridish@freescale.com>
5 * Li Yang <leoli@freescale.com> 5 * Li Yang <leoli@freescale.com>
@@ -1410,6 +1410,9 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
1410 (ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) { 1410 (ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) {
1411 upsmr |= UCC_GETH_UPSMR_TBIM; 1411 upsmr |= UCC_GETH_UPSMR_TBIM;
1412 } 1412 }
1413 if ((ugeth->phy_interface == PHY_INTERFACE_MODE_SGMII))
1414 upsmr |= UCC_GETH_UPSMR_SGMM;
1415
1413 out_be32(&uf_regs->upsmr, upsmr); 1416 out_be32(&uf_regs->upsmr, upsmr);
1414 1417
1415 /* Disable autonegotiation in tbi mode, because by default it 1418 /* Disable autonegotiation in tbi mode, because by default it
@@ -1531,6 +1534,49 @@ static void adjust_link(struct net_device *dev)
1531 spin_unlock_irqrestore(&ugeth->lock, flags); 1534 spin_unlock_irqrestore(&ugeth->lock, flags);
1532} 1535}
1533 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 */
1545static 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
1534/* Configure the PHY for dev. 1580/* Configure the PHY for dev.
1535 * returns 0 if success. -1 if failure 1581 * returns 0 if success. -1 if failure
1536 */ 1582 */
@@ -1554,6 +1600,9 @@ static int init_phy(struct net_device *dev)
1554 return -ENODEV; 1600 return -ENODEV;
1555 } 1601 }
1556 1602
1603 if (priv->phy_interface == PHY_INTERFACE_MODE_SGMII)
1604 uec_configure_serdes(dev);
1605
1557 phydev->supported &= (ADVERTISED_10baseT_Half | 1606 phydev->supported &= (ADVERTISED_10baseT_Half |
1558 ADVERTISED_10baseT_Full | 1607 ADVERTISED_10baseT_Full |
1559 ADVERTISED_100baseT_Half | 1608 ADVERTISED_100baseT_Half |
@@ -3523,6 +3572,8 @@ static phy_interface_t to_phy_interface(const char *phy_connection_type)
3523 return PHY_INTERFACE_MODE_RGMII_RXID; 3572 return PHY_INTERFACE_MODE_RGMII_RXID;
3524 if (strcasecmp(phy_connection_type, "rtbi") == 0) 3573 if (strcasecmp(phy_connection_type, "rtbi") == 0)
3525 return PHY_INTERFACE_MODE_RTBI; 3574 return PHY_INTERFACE_MODE_RTBI;
3575 if (strcasecmp(phy_connection_type, "sgmii") == 0)
3576 return PHY_INTERFACE_MODE_SGMII;
3526 3577
3527 return PHY_INTERFACE_MODE_MII; 3578 return PHY_INTERFACE_MODE_MII;
3528} 3579}
@@ -3567,6 +3618,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
3567 PHY_INTERFACE_MODE_RMII, PHY_INTERFACE_MODE_RGMII, 3618 PHY_INTERFACE_MODE_RMII, PHY_INTERFACE_MODE_RGMII,
3568 PHY_INTERFACE_MODE_GMII, PHY_INTERFACE_MODE_RGMII, 3619 PHY_INTERFACE_MODE_GMII, PHY_INTERFACE_MODE_RGMII,
3569 PHY_INTERFACE_MODE_TBI, PHY_INTERFACE_MODE_RTBI, 3620 PHY_INTERFACE_MODE_TBI, PHY_INTERFACE_MODE_RTBI,
3621 PHY_INTERFACE_MODE_SGMII,
3570 }; 3622 };
3571 3623
3572 ugeth_vdbg("%s: IN", __func__); 3624 ugeth_vdbg("%s: IN", __func__);
@@ -3658,6 +3710,9 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
3658 } 3710 }
3659 ug_info->phy_node = phy; 3711 ug_info->phy_node = phy;
3660 3712
3713 /* Find the TBI PHY node. If it's not there, we don't support SGMII */
3714 ug_info->tbi_node = of_parse_phandle(np, "tbi-handle", 0);
3715
3661 /* get the phy interface type, or default to MII */ 3716 /* get the phy interface type, or default to MII */
3662 prop = of_get_property(np, "phy-connection-type", NULL); 3717 prop = of_get_property(np, "phy-connection-type", NULL);
3663 if (!prop) { 3718 if (!prop) {
@@ -3682,6 +3737,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
3682 case PHY_INTERFACE_MODE_RGMII_TXID: 3737 case PHY_INTERFACE_MODE_RGMII_TXID:
3683 case PHY_INTERFACE_MODE_TBI: 3738 case PHY_INTERFACE_MODE_TBI:
3684 case PHY_INTERFACE_MODE_RTBI: 3739 case PHY_INTERFACE_MODE_RTBI:
3740 case PHY_INTERFACE_MODE_SGMII:
3685 max_speed = SPEED_1000; 3741 max_speed = SPEED_1000;
3686 break; 3742 break;
3687 default: 3743 default: