From mboxrd@z Thu Jan 1 00:00:00 1970 From: Amit Virdi Date: Wed, 9 May 2012 14:59:04 +0530 Subject: [U-Boot] [PATCH] net: Multiple updates/enhancements to designware.c In-Reply-To: <1336462154-21061-1-git-send-email-sr@denx.de> References: <1336462154-21061-1-git-send-email-sr@denx.de> Message-ID: <4FAA38E0.9080905@st.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Stefan, On 5/8/2012 12:59 PM, Stefan Roese wrote: > This patch adds the following changes to designware ethernet driver > found on the ST SPEAr SoC: > > - Don't init MAC& PHY upon startup. This causes a delay, waiting for > the auto negotiation to complete. And we don't want this delay to > always happen. Especially not on platforms where ethernet is not > used at all (e.g. booting via flash). > Instead postpone the MAC / PHY configuration to the stage, where > ethernet is first used. > - Add possibility for board specific PHY init code. This is needed > for example on the X600 board, where the Vitesse PHY needs to be > configured for GMII mode. > This board specific PHY init is done via the function > designware_board_phy_init(). And this driver now adds a weak default > which can be overridden by board code. > - Use common functions miiphy_speed()& miiphy_duplex() to read > link status from PHY. > - Print status and progress of auto negotiation. > - Print link status (speed, dupex) upon first usage. > > Signed-off-by: Stefan Roese > Cc: Amit Virdi > Cc: Vipin Kumar > Cc: Joe Hershberger > --- > drivers/net/designware.c | 114 +++++++++++++++++----------------------- > drivers/net/designware.h | 1 + > include/configs/spear-common.h | 1 + > 3 files changed, 49 insertions(+), 67 deletions(-) > > diff --git a/drivers/net/designware.c b/drivers/net/designware.c > index e263022..945e57b 100644 > --- a/drivers/net/designware.c > +++ b/drivers/net/designware.c > @@ -28,6 +28,7 @@ > #include > #include > #include > +#include > #include > #include > #include "designware.h" > @@ -153,6 +154,13 @@ static int dw_eth_init(struct eth_device *dev, bd_t *bis) > if (priv->phy_configured != 1) > configure_phy(dev); > > + /* Print link status only once */ > + if (!priv->link_printed) { > + printf("ENET Speed is %d Mbps - %s duplex connection\n", > + priv->speed, (priv->duplex == HALF) ? "HALF" : "FULL"); > + priv->link_printed = 1; > + } > + > /* Reset ethernet hardware */ > if (mac_reset(dev)< 0) > return -1; > @@ -168,17 +176,17 @@ static int dw_eth_init(struct eth_device *dev, bd_t *bis) > > conf = FRAMEBURSTENABLE | DISABLERXOWN; > > - if (priv->speed != SPEED_1000M) > + if (priv->speed != 1000) > conf |= MII_PORTSELECT; > > if ((priv->interface != PHY_INTERFACE_MODE_MII)&& > (priv->interface != PHY_INTERFACE_MODE_GMII)) { > > - if (priv->speed == SPEED_100M) > + if (priv->speed == 100) > conf |= FES_100; > } > > - if (priv->duplex == FULL_DUPLEX) > + if (priv->duplex == FULL) > conf |= FULLDPLXMODE; > > writel(conf,&mac_p->conf); > @@ -397,6 +405,16 @@ static int dw_reset_phy(struct eth_device *dev) > return 0; > } > > +/* > + * Add weak default function for board specific PHY configuration > + */ > +int __weak designware_board_phy_init(struct eth_device *dev, int phy_addr, > + int (*mii_write)(struct eth_device *, u8, u8, u16), > + int dw_reset_phy(struct eth_device *)) > +{ > + return 0; > +} > + > static int configure_phy(struct eth_device *dev) > { > struct dw_eth_dev *priv = dev->priv; > @@ -406,9 +424,6 @@ static int configure_phy(struct eth_device *dev) > u16 bmsr; > u32 timeout; > ulong start; > - u16 anlpar, btsr; > -#else > - u16 ctrl; > #endif > > #if defined(CONFIG_DW_SEARCH_PHY) > @@ -420,6 +435,16 @@ static int configure_phy(struct eth_device *dev) > #else > phy_addr = priv->address; > #endif > + > + /* > + * Some boards need board specific PHY initialization. This is > + * after the main driver init code but before the auto negotiation > + * is run. > + */ > + if (designware_board_phy_init(dev, phy_addr, > + eth_mdio_write, dw_reset_phy)< 0) > + return -1; > + > if (dw_reset_phy(dev)< 0) > return -1; > > @@ -445,72 +470,32 @@ static int configure_phy(struct eth_device *dev) > #if defined(CONFIG_DW_AUTONEG) > timeout = CONFIG_AUTONEG_TIMEOUT; > start = get_timer(0); > - > + puts("Waiting for PHY auto negotiation to complete"); > while (get_timer(start)< timeout) { > eth_mdio_read(dev, phy_addr, MII_BMSR,&bmsr); > - if (bmsr& BMSR_ANEGCOMPLETE) > + if (bmsr& BMSR_ANEGCOMPLETE) { > + priv->phy_configured = 1; > break; > + } > + > + /* Print dot all 1s to show progress */ > + if ((get_timer(start) % 100000) == 0) > + putc('.'); > > /* Try again after 10usec */ > udelay(10); > }; > > - eth_mdio_read(dev, phy_addr, MII_LPA,&anlpar); > - eth_mdio_read(dev, phy_addr, MII_STAT1000,&btsr); > - > - if (bmsr& BMSR_ANEGCOMPLETE) { > - if (btsr& PHY_1000BTSR_1000FD) { > - priv->speed = SPEED_1000M; > - 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 { > - priv->speed = SPEED_10M; > - 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 > - if (eth_mdio_read(dev, phy_addr, MII_BMCR,&ctrl)< 0) > - return -1; > - > - if (ctrl& BMCR_FULLDPLX) > - priv->duplex = FULL_DUPLEX; > - else > - priv->duplex = HALF_DUPLEX; > - > - if (ctrl& BMCR_SPEED1000) > - priv->speed = SPEED_1000M; > - else if (ctrl& BMCR_SPEED100) > - priv->speed = SPEED_100M; > + if (!(bmsr& BMSR_ANEGCOMPLETE)) > + puts(" TIMEOUT!\n"); > else > - priv->speed = SPEED_10M; > -#endif > + puts(" done\n"); > +#else > priv->phy_configured = 1; > +#endif > + > + priv->speed = miiphy_speed(dev->name, phy_addr); > + priv->duplex = miiphy_duplex(dev->name, phy_addr); > > return 0; > } > @@ -575,11 +560,6 @@ int designware_initialize(u32 id, ulong base_addr, u32 phy_addr, u32 interface) > priv->phy_configured = 0; > priv->interface = interface; > > - if (mac_reset(dev)< 0) > - return -1; > - > - configure_phy(dev); > - > dev->init = dw_eth_init; > dev->send = dw_eth_send; > dev->recv = dw_eth_recv; > diff --git a/drivers/net/designware.h b/drivers/net/designware.h > index 40020bf..d668f8f 100644 > --- a/drivers/net/designware.h > +++ b/drivers/net/designware.h > @@ -240,6 +240,7 @@ struct dw_eth_dev { > u32 tx_currdescnum; > u32 rx_currdescnum; > u32 phy_configured; > + int link_printed; > u32 padding; > > struct dmamacdescr tx_mac_descrtable[CONFIG_TX_DESCR_NUM]; > diff --git a/include/configs/spear-common.h b/include/configs/spear-common.h > index 3366895..78cc33f 100644 > --- a/include/configs/spear-common.h > +++ b/include/configs/spear-common.h > @@ -38,6 +38,7 @@ > #define CONFIG_NET_MULTI > #define CONFIG_PHY_RESET_DELAY 10000 /* in usec */ > #define CONFIG_DW_AUTONEG > +#define CONFIG_PHY_GIGE /* Include GbE speed/duplex detection */ > Shouldn't this come in a separate patch? Otherwise, Acked-by: Amit Virdi Regards Amit Virdi > /* USBD driver configuration */ > #if defined(CONFIG_SPEAR_USBTTY)