diff options
| author | Stefan Roese <sr@denx.de> | 2007-08-14 16:36:29 +0200 | 
|---|---|---|
| committer | Stefan Roese <sr@denx.de> | 2007-08-14 16:36:29 +0200 | 
| commit | 3b3bff4cbf2cb14f9a3e7d03f26ebab900efe4ae (patch) | |
| tree | fb66bf8861d9f78765160d734a438856f5317cdb /drivers/macb.c | |
| parent | 4ce846ec59f36b85d6644a769690ad3feb667575 (diff) | |
| parent | 4ef35e53c693556c54b0c22d6f873de87bade253 (diff) | |
| download | olio-uboot-2014.01-3b3bff4cbf2cb14f9a3e7d03f26ebab900efe4ae.tar.xz olio-uboot-2014.01-3b3bff4cbf2cb14f9a3e7d03f26ebab900efe4ae.zip | |
Merge with git://www.denx.de/git/u-boot.git
Diffstat (limited to 'drivers/macb.c')
| -rw-r--r-- | drivers/macb.c | 70 | 
1 files changed, 41 insertions, 29 deletions
| diff --git a/drivers/macb.c b/drivers/macb.c index 186ab19d3..95cdc496c 100644 --- a/drivers/macb.c +++ b/drivers/macb.c @@ -17,7 +17,8 @@   */  #include <common.h> -#if defined(CONFIG_MACB) && (CONFIG_COMMANDS & (CFG_CMD_NET | CFG_CMD_MII)) +#if defined(CONFIG_MACB) \ +	&& (defined(CONFIG_CMD_NET) || defined(CONFIG_CMD_MII))  /*   * The u-boot networking stack is a little weird.  It seems like the @@ -51,6 +52,8 @@  #include "macb.h" +#define barrier() asm volatile("" ::: "memory") +  #define CFG_MACB_RX_BUFFER_SIZE		4096  #define CFG_MACB_RX_RING_SIZE		(CFG_MACB_RX_BUFFER_SIZE / 128)  #define CFG_MACB_TX_RING_SIZE		16 @@ -163,7 +166,7 @@ static u16 macb_mdio_read(struct macb_device *macb, u8 reg)  	return MACB_BFEXT(DATA, frame);  } -#if (CONFIG_COMMANDS & CFG_CMD_NET) +#if defined(CONFIG_CMD_NET)  static int macb_send(struct eth_device *netdev, volatile void *packet,  		     int length) @@ -185,31 +188,31 @@ static int macb_send(struct eth_device *netdev, volatile void *packet,  	macb->tx_ring[tx_head].ctrl = ctrl;  	macb->tx_ring[tx_head].addr = paddr; +	barrier();  	macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE) | MACB_BIT(TSTART));  	/*  	 * I guess this is necessary because the networking core may  	 * re-use the transmit buffer as soon as we return...  	 */ -	i = 0; -	while (!(macb->tx_ring[tx_head].ctrl & TXBUF_USED)) { -		if (i > CFG_MACB_TX_TIMEOUT) { -			printf("%s: TX timeout\n", netdev->name); +	for (i = 0; i <= CFG_MACB_TX_TIMEOUT; i++) { +		barrier(); +		ctrl = macb->tx_ring[tx_head].ctrl; +		if (ctrl & TXBUF_USED)  			break; -		}  		udelay(1); -		i++;  	}  	dma_unmap_single(packet, length, paddr);  	if (i <= CFG_MACB_TX_TIMEOUT) { -		ctrl = macb->tx_ring[tx_head].ctrl;  		if (ctrl & TXBUF_UNDERRUN)  			printf("%s: TX underrun\n", netdev->name);  		if (ctrl & TXBUF_EXHAUSTED)  			printf("%s: TX buffers exhausted in mid frame\n",  			       netdev->name); +	} else { +		printf("%s: TX timeout\n", netdev->name);  	}  	/* No one cares anyway */ @@ -234,6 +237,7 @@ static void reclaim_rx_buffers(struct macb_device *macb,  		i++;  	} +	barrier();  	macb->rx_tail = new_tail;  } @@ -283,25 +287,17 @@ static int macb_recv(struct eth_device *netdev)  				rx_tail = 0;  			}  		} +		barrier();  	}  	return 0;  } -static int macb_phy_init(struct macb_device *macb) +static void macb_phy_reset(struct macb_device *macb)  {  	struct eth_device *netdev = &macb->netdev; -	u32 ncfgr; -	u16 phy_id, status, adv, lpa; -	int media, speed, duplex;  	int i; - -	/* Check if the PHY is up to snuff... */ -	phy_id = macb_mdio_read(macb, MII_PHYSID1); -	if (phy_id == 0xffff) { -		printf("%s: No PHY present\n", netdev->name); -		return 0; -	} +	u16 status, adv;  	adv = ADVERTISE_CSMA | ADVERTISE_ALL;  	macb_mdio_write(macb, MII_ADVERTISE, adv); @@ -309,11 +305,6 @@ static int macb_phy_init(struct macb_device *macb)  	macb_mdio_write(macb, MII_BMCR, (BMCR_ANENABLE  					 | BMCR_ANRESTART)); -#if 0 -	for (i = 0; i < 9; i++) -		printf("mii%d: 0x%04x\n", i, macb_mdio_read(macb, i)); -#endif -  	for (i = 0; i < CFG_MACB_AUTONEG_TIMEOUT / 100; i++) {  		status = macb_mdio_read(macb, MII_BMSR);  		if (status & BMSR_ANEGCOMPLETE) @@ -326,13 +317,33 @@ static int macb_phy_init(struct macb_device *macb)  	else  		printf("%s: Autonegotiation timed out (status=0x%04x)\n",  		       netdev->name, status); +} +static int macb_phy_init(struct macb_device *macb) +{ +	struct eth_device *netdev = &macb->netdev; +	u32 ncfgr; +	u16 phy_id, status, adv, lpa; +	int media, speed, duplex; +	int i; + +	/* Check if the PHY is up to snuff... */ +	phy_id = macb_mdio_read(macb, MII_PHYSID1); +	if (phy_id == 0xffff) { +		printf("%s: No PHY present\n", netdev->name); +		return 0; +	} + +	status = macb_mdio_read(macb, MII_BMSR);  	if (!(status & BMSR_LSTATUS)) { +		/* Try to re-negotiate if we don't have link already. */ +		macb_phy_reset(macb); +  		for (i = 0; i < CFG_MACB_AUTONEG_TIMEOUT / 100; i++) { -			udelay(100);  			status = macb_mdio_read(macb, MII_BMSR);  			if (status & BMSR_LSTATUS)  				break; +			udelay(100);  		}  	} @@ -341,6 +352,7 @@ static int macb_phy_init(struct macb_device *macb)  		       netdev->name, status);  		return 0;  	} else { +		adv = macb_mdio_read(macb, MII_ADVERTISE);  		lpa = macb_mdio_read(macb, MII_LPA);  		media = mii_nway_result(lpa & adv);  		speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF) @@ -492,9 +504,9 @@ int macb_eth_initialize(int id, void *regs, unsigned int phy_addr)  	return 0;  } -#endif /* (CONFIG_COMMANDS & CFG_CMD_NET) */ +#endif -#if (CONFIG_COMMANDS & CFG_CMD_MII) +#if defined(CONFIG_CMD_MII)  int miiphy_read(unsigned char addr, unsigned char reg, unsigned short *value)  { @@ -570,6 +582,6 @@ int miiphy_write(unsigned char addr, unsigned char reg, unsigned short value)  	return 0;  } -#endif /* (CONFIG_COMMANDS & CFG_CMD_MII) */ +#endif  #endif /* CONFIG_MACB */ |