Patchwork [U-Boot,2/3] phylib: wait for TN2020 to achieve SERDES lane alignment at startup

login
register
mail settings
Submitter Timur Tabi
Date Oct. 5, 2011, 7 p.m.
Message ID <1317841251-27295-2-git-send-email-timur@freescale.com>
Download mbox | patch
Permalink /patch/117907/
State Superseded
Headers show

Comments

Timur Tabi - Oct. 5, 2011, 7 p.m.
Before the Teranetics TN2020 PHY can be used, the SERDES lanes need to be
aligned, so wait for lane alignment before completing the startup sequence.

Note that this process can take up to three seconds.

Signed-off-by: Timur Tabi <timur@freescale.com>
---
 drivers/net/phy/teranetics.c |   32 ++++++++++++++++++++++++++++++++
 1 files changed, 32 insertions(+), 0 deletions(-)

Patch

diff --git a/drivers/net/phy/teranetics.c b/drivers/net/phy/teranetics.c
index 5932bf0..97fe5f4 100644
--- a/drivers/net/phy/teranetics.c
+++ b/drivers/net/phy/teranetics.c
@@ -43,6 +43,38 @@  int tn2020_config(struct phy_device *phydev)
 
 int tn2020_startup(struct phy_device *phydev)
 {
+	unsigned int timeout = 5 * 1000; /* 5 second timeout */
+
+#define MDIO_PHYXS_LANE_READY (MDIO_PHYXS_LNSTAT_SYNC0 | \
+			       MDIO_PHYXS_LNSTAT_SYNC1 | \
+			       MDIO_PHYXS_LNSTAT_SYNC2 | \
+			       MDIO_PHYXS_LNSTAT_SYNC3 | \
+			       MDIO_PHYXS_LNSTAT_ALIGN)
+
+	/*
+	 * Wait for the XAUI-SERDES lanes to align first.  Under normal
+	 * circumstances, this can take up to three seconds.
+	 */
+	while (--timeout) {
+		int reg = phy_read(phydev, MDIO_MMD_PHYXS, MDIO_PHYXS_LNSTAT);
+		if (reg < 0) {
+			printf("TN2020: Error reading from PHY at "
+			       "address %u\n", phydev->addr);
+			break;
+		}
+		if ((reg & MDIO_PHYXS_LANE_READY) == MDIO_PHYXS_LANE_READY)
+			break;
+		udelay(1000);
+	}
+	if (!timeout) {
+		/*
+		 * A timeout is bad, but it may not be fatal, so don't
+		 * return an error.  Display a warning instead.
+		 */
+		printf("TN2020: Timeout waiting for PHY at address %u to "
+		       "align.\n", phydev->addr);
+	}
+
 	if (phydev->port != PORT_FIBRE)
 		return gen10g_startup(phydev);