diff options
| -rw-r--r-- | drivers/net/designware.c | 118 | ||||
| -rw-r--r-- | drivers/net/designware.h | 1 | ||||
| -rw-r--r-- | include/configs/spear-common.h | 1 | 
3 files changed, 51 insertions, 69 deletions
| diff --git a/drivers/net/designware.c b/drivers/net/designware.c index 8f22e00dd..326d550c1 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -28,6 +28,7 @@  #include <common.h>  #include <miiphy.h>  #include <malloc.h> +#include <linux/compiler.h>  #include <linux/err.h>  #include <asm/io.h>  #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); @@ -396,6 +404,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; @@ -405,9 +423,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) @@ -419,6 +434,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; @@ -444,72 +469,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; - -		/* 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; +		/* Print dot all 1s to show progress */ +		if ((get_timer(start) % 1000) == 0) +			putc('.'); + +		/* Try again after 1msec */ +		udelay(1000); +	}; -	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;  } @@ -574,11 +559,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 40020bf26..d668f8fbf 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 36c2a8b16..a6d1cfbcb 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 */  /* USBD driver configuration */  #if defined(CONFIG_SPEAR_USBTTY) |