Patchwork [U-Boot,V2,5/8] net/designware: Try configuring phy on each dw_eth_init

login
register
mail settings
Submitter Amit Virdi
Date March 26, 2012, 10:09 a.m.
Message ID <1332756599-19304-6-git-send-email-amit.virdi@st.com>
Download mbox | patch
Permalink /patch/148689/
State Accepted
Commit 13edd1706c56371dc6a67f7bef874f6d8b7af8eb
Delegated to: Joe Hershberger
Headers show

Comments

Amit Virdi - March 26, 2012, 10:09 a.m.
From: Vipin Kumar <vipin.kumar@st.com>

Phy autonegotiation works only when the ethernet cable is plugged in.
Since the phy was configured only at the init time, a plugged in cable
was necessary to initialize the phy properly.

This patch keeps a flag to check if the phy initialization has
succeeded, and calls configure_phy routine at every init if this flag
reports otherwise.

Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
Signed-off-by: Amit Virdi <amit.virdi@st.com>
---
 drivers/net/designware.c |   50 ++++++++++++++++++++++++++-------------------
 drivers/net/designware.h |    1 +
 2 files changed, 30 insertions(+), 21 deletions(-)
Joe Hershberger - April 4, 2012, 5:35 p.m.
On Mon, Mar 26, 2012 at 5:09 AM, Amit Virdi <amit.virdi@st.com> wrote:
> From: Vipin Kumar <vipin.kumar@st.com>
>
> Phy autonegotiation works only when the ethernet cable is plugged in.
> Since the phy was configured only at the init time, a plugged in cable
> was necessary to initialize the phy properly.
>
> This patch keeps a flag to check if the phy initialization has
> succeeded, and calls configure_phy routine at every init if this flag
> reports otherwise.
>
> Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
> Signed-off-by: Amit Virdi <amit.virdi@st.com>

Applied.

Thanks,
-Joe

Patch

diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index 933032c..ebb1fff 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -32,6 +32,8 @@ 
 #include <asm/io.h>
 #include "designware.h"
 
+static int configure_phy(struct eth_device *dev);
+
 static void tx_descs_init(struct eth_device *dev)
 {
 	struct dw_eth_dev *priv = dev->priv;
@@ -144,6 +146,9 @@  static int dw_eth_init(struct eth_device *dev, bd_t *bis)
 	struct eth_dma_regs *dma_p = priv->dma_regs_p;
 	u32 conf;
 
+	if (priv->phy_configured != 1)
+		configure_phy(dev);
+
 	/* Reset ethernet hardware */
 	if (mac_reset(dev) < 0)
 		return -1;
@@ -422,23 +427,26 @@  static int configure_phy(struct eth_device *dev)
 	eth_mdio_read(dev, phy_addr, MII_LPA, &anlpar);
 	eth_mdio_read(dev, phy_addr, MII_STAT1000, &btsr);
 
-	if (btsr & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) {
-		priv->speed = SPEED_1000M;
-		if (btsr & PHY_1000BTSR_1000FD)
-			priv->duplex = FULL_DUPLEX;
-		else
-			priv->duplex = HALF_DUPLEX;
-	} 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
-			priv->duplex = HALF_DUPLEX;
-	}
+	if (bmsr & BMSR_ANEGCOMPLETE) {
+		if (btsr & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) {
+			priv->speed = SPEED_1000M;
+			if (btsr & PHY_1000BTSR_1000FD)
+				priv->duplex = FULL_DUPLEX;
+			else
+				priv->duplex = HALF_DUPLEX;
+		} 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
+				priv->duplex = HALF_DUPLEX;
+		}
+	} else
+		return -1;
 #else
 	if (eth_mdio_read(dev, phy_addr, MII_BMCR, &ctrl) < 0)
 		return -1;
@@ -455,6 +463,8 @@  static int configure_phy(struct eth_device *dev)
 	else
 		priv->speed = SPEED_10M;
 #endif
+	priv->phy_configured = 1;
+
 	return 0;
 }
 
@@ -515,14 +525,12 @@  int designware_initialize(u32 id, ulong base_addr, u32 phy_addr)
 	priv->dma_regs_p = (struct eth_dma_regs *)(base_addr +
 			DW_DMA_BASE_OFFSET);
 	priv->address = phy_addr;
+	priv->phy_configured = 0;
 
 	if (mac_reset(dev) < 0)
 		return -1;
 
-	if (configure_phy(dev) < 0) {
-		printf("Phy could not be configured\n");
-		return -1;
-	}
+	configure_phy(dev);
 
 	dev->init = dw_eth_init;
 	dev->send = dw_eth_send;
diff --git a/drivers/net/designware.h b/drivers/net/designware.h
index 42133b3..abf729d 100644
--- a/drivers/net/designware.h
+++ b/drivers/net/designware.h
@@ -238,6 +238,7 @@  struct dw_eth_dev {
 	u32 duplex;
 	u32 tx_currdescnum;
 	u32 rx_currdescnum;
+	u32 phy_configured;
 	u32 padding;
 
 	struct dmamacdescr tx_mac_descrtable[CONFIG_TX_DESCR_NUM];