From e25c90b45c4764e60e44f302ad337ed6ce066468 Mon Sep 17 00:00:00 2001
From: Vikas Manocha <vikas.manocha@st.com>
Date: Mon, 26 Mar 2012 00:09:57 +0000
Subject: [PATCH] net/designware: Program phy registers when auto-negotiation
 is ON

If AN(auto-negotiation) is ON, speed bit of control register are not
applicable.  Also phy registers were not getting programmed as per the
result of AN. This patch sets only AN bit & restart AN bit for AN ON
selection & programs PHY registers as per AN result.

Signed-off-by: Vikas Manocha <vikas.manocha@st.com>
Signed-off-by: Amit Virdi <amit.virdi@st.com>
---
 drivers/net/designware.c | 43 +++++++++++++++++++++++++++-------------
 1 file changed, 29 insertions(+), 14 deletions(-)

diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index ebb1fff805..56f0c7ac53 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -399,8 +399,7 @@ static int configure_phy(struct eth_device *dev)
 		return -1;
 
 #if defined(CONFIG_DW_AUTONEG)
-	bmcr = BMCR_ANENABLE | BMCR_ANRESTART | BMCR_SPEED100 | \
-	       BMCR_FULLDPLX | BMCR_SPEED1000;
+	bmcr = BMCR_ANENABLE | BMCR_ANRESTART;
 #else
 	bmcr = BMCR_SPEED100 | BMCR_FULLDPLX;
 
@@ -428,23 +427,39 @@ static int configure_phy(struct eth_device *dev)
 	eth_mdio_read(dev, phy_addr, MII_STAT1000, &btsr);
 
 	if (bmsr & BMSR_ANEGCOMPLETE) {
-		if (btsr & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) {
+		if (btsr & PHY_1000BTSR_1000FD) {
 			priv->speed = SPEED_1000M;
-			if (btsr & PHY_1000BTSR_1000FD)
-				priv->duplex = FULL_DUPLEX;
-			else
-				priv->duplex = HALF_DUPLEX;
+			bmcr |= BMCR_SPEED1000;
+			priv->duplex = FULL_DUPLEX;
+			bmcr |= BMCR_FULLDPLX;
+		} else if (btsr & PHY_1000BTSR_1000HD) {
+			priv->speed = SPEED_1000M;
+			bmcr |= BMCR_SPEED1000;
+			priv->duplex = HALF_DUPLEX;
+			bmcr &= ~BMCR_FULLDPLX;
+		} else if (anlpar & LPA_100FULL) {
+			priv->speed = SPEED_100M;
+			bmcr |= BMCR_SPEED100;
+			priv->duplex = FULL_DUPLEX;
+			bmcr |= BMCR_FULLDPLX;
+		} else if (anlpar & LPA_100HALF) {
+			priv->speed = SPEED_100M;
+			bmcr |= BMCR_SPEED100;
+			priv->duplex = HALF_DUPLEX;
+			bmcr &= ~BMCR_FULLDPLX;
+		} else if (anlpar & LPA_10FULL) {
+			priv->speed = SPEED_10M;
+			bmcr &= ~BMCR_SPEED100;
+			priv->duplex = FULL_DUPLEX;
+			bmcr |= BMCR_FULLDPLX;
 		} else {
-			if (anlpar & LPA_100)
-				priv->speed = SPEED_100M;
-			else
 				priv->speed = SPEED_10M;
-
-			if (anlpar & (LPA_10FULL | LPA_100FULL))
-				priv->duplex = FULL_DUPLEX;
-			else
+				bmcr &= ~BMCR_SPEED100;
 				priv->duplex = HALF_DUPLEX;
+				bmcr &= ~BMCR_FULLDPLX;
 		}
+		if (eth_mdio_write(dev, phy_addr, MII_BMCR, bmcr) < 0)
+			return -1;
 	} else
 		return -1;
 #else
-- 
2.39.5