[U-Boot] [PATCH 5/7] net/designware: Try configuring phy on each dw_eth_init

Amit Virdi
2012-02-29T10:37:24Z

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 | 4 +++
2 files changed, 33 insertions(+), 21 deletions(-)

diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index b5e3974..46780e4 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 != TRUE)
+ configure_phy(dev);
+
/* Reset ethernet hardware */
if (mac_reset(dev) < 0)
return -1;
@@ -421,23 +426,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;
@@ -454,6 +462,8 @@ static int configure_phy(struct eth_device *dev)
else
priv->speed = SPEED_10M;
#endif
+ priv->phy_configured = TRUE;
+
return 0;
}

@@ -514,14 +524,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 = FALSE;

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..42a375b 100644
--- a/drivers/net/designware.h
+++ b/drivers/net/designware.h
@@ -238,6 +238,10 @@ struct dw_eth_dev {
u32 duplex;
u32 tx_currdescnum;
u32 rx_currdescnum;
+ u32 phy_configured;
+#define FALSE (0)
+#define TRUE (!FALSE)
+
u32 padding;

struct dmamacdescr tx_mac_descrtable[CONFIG_TX_DESCR_NUM];
--
1.7.2.2