[U-Boot] [PATCH 02/17] GRETH: Added support for selecting PHY address from config, PHY address was always set to zero before.

Daniel Hellstrom daniel at gaisler.com
Tue May 18 16:48:48 CEST 2010


Signed-off-by: Daniel Hellstrom <daniel at gaisler.com>
---
 drivers/net/greth.c |   69 +++++++++++++++++++++++++++++++-------------------
 1 files changed, 43 insertions(+), 26 deletions(-)

diff --git a/drivers/net/greth.c b/drivers/net/greth.c
index 79bc4d9..a1a88f9 100644
--- a/drivers/net/greth.c
+++ b/drivers/net/greth.c
@@ -45,7 +45,7 @@
 /* ByPass Cache when reading regs */
 #define GRETH_REGLOAD(addr)		SPARC_NOCACHE_READ(addr)
 /* Write-through cache ==> no bypassing needed on writes */
-#define GRETH_REGSAVE(addr,data)	(*(unsigned int *)(addr) = (data))
+#define GRETH_REGSAVE(addr,data) (*(volatile unsigned int *)(addr) = (data))
 #define GRETH_REGORIN(addr,data) GRETH_REGSAVE(addr,GRETH_REGLOAD(addr)|data)
 #define GRETH_REGANDIN(addr,data) GRETH_REGSAVE(addr,GRETH_REGLOAD(addr)&data)
 
@@ -102,12 +102,12 @@ typedef struct {
 } greth_priv;
 
 /* Read MII register 'addr' from core 'regs' */
-static int read_mii(int addr, volatile greth_regs * regs)
+static int read_mii(int phyaddr, int regaddr, volatile greth_regs * regs)
 {
 	while (GRETH_REGLOAD(&regs->mdio) & GRETH_MII_BUSY) {
 	}
 
-	GRETH_REGSAVE(&regs->mdio, (0 << 11) | ((addr & 0x1F) << 6) | 2);
+	GRETH_REGSAVE(&regs->mdio, ((phyaddr & 0x1F) << 11) | ((regaddr & 0x1F) << 6) | 2);
 
 	while (GRETH_REGLOAD(&regs->mdio) & GRETH_MII_BUSY) {
 	}
@@ -119,14 +119,14 @@ static int read_mii(int addr, volatile greth_regs * regs)
 	}
 }
 
-static void write_mii(int addr, int data, volatile greth_regs * regs)
+static void write_mii(int phyaddr, int regaddr, int data, volatile greth_regs * regs)
 {
 	while (GRETH_REGLOAD(&regs->mdio) & GRETH_MII_BUSY) {
 	}
 
 	GRETH_REGSAVE(&regs->mdio,
-		      ((data & 0xFFFF) << 16) | (0 << 11) | ((addr & 0x1F) << 6)
-		      | 1);
+		      ((data & 0xFFFF) << 16) | ((phyaddr & 0x1F) << 11) |
+		      ((regaddr & 0x1F) << 6) | 1);
 
 	while (GRETH_REGLOAD(&regs->mdio) & GRETH_MII_BUSY) {
 	}
@@ -146,8 +146,6 @@ int greth_init(struct eth_device *dev, bd_t * bis)
 	printf("greth_init\n");
 #endif
 
-	GRETH_REGSAVE(&regs->control, 0);
-
 	if (!greth->rxbd_base) {
 
 		/* allocate descriptors */
@@ -161,6 +159,7 @@ int greth_init(struct eth_device *dev, bd_t * bis)
 		    malloc(GRETH_RXBUF_EFF_SIZE * GRETH_RXBD_CNT);
 	}
 
+	memset(greth->rxbuf_base, 0, GRETH_RXBUF_EFF_SIZE * GRETH_RXBD_CNT);
 	/* initate rx decriptors */
 	for (i = 0; i < GRETH_RXBD_CNT; i++) {
 		greth->rxbd_base[i].addr = (unsigned int)
@@ -219,6 +218,11 @@ int greth_init_phy(greth_priv * dev, bd_t * bis)
 	greth_regs *regs = dev->regs;
 	int tmp, tmp1, tmp2, i;
 	unsigned int start, timeout;
+#ifdef CONFIG_SYS_GRLIB_GRETH_PHYADDR
+	int phyaddr = CONFIG_SYS_GRLIB_GRETH_PHYADDR;
+#else
+	int phyaddr = 0;
+#endif
 
 	/* X msecs to ticks */
 	timeout = usec2ticks(GRETH_PHY_TIMEOUT_MS * 1000);
@@ -230,17 +234,25 @@ int greth_init_phy(greth_priv * dev, bd_t * bis)
 
 	/* get phy control register default values */
 
-	while ((tmp = read_mii(0, regs)) & 0x8000) {
-		if (get_timer(start) > timeout)
+	while ((tmp = read_mii(phyaddr, 0, regs)) & 0x8000) {
+		if (get_timer(start) > timeout) {
+#ifdef DEBUG
+			printf("greth_init_phy: PHY read 1 failed\n");
+#endif
 			return 1;	/* Fail */
+		}
 	}
 
 	/* reset PHY and wait for completion */
-	write_mii(0, 0x8000 | tmp, regs);
+	write_mii(phyaddr, 0, 0x8000 | tmp, regs);
 
-	while (((tmp = read_mii(0, regs))) & 0x8000) {
-		if (get_timer(start) > timeout)
+	while (((tmp = read_mii(phyaddr, 0, regs))) & 0x8000) {
+		if (get_timer(start) > timeout) {
+#ifdef DEBUG
+			printf("greth_init_phy: PHY read 2 failed\n");
+#endif
 			return 1;	/* Fail */
+		}
 	}
 
 	/* Check if PHY is autoneg capable and then determine operating
@@ -251,16 +263,16 @@ int greth_init_phy(greth_priv * dev, bd_t * bis)
 	dev->sp = 0;
 	dev->auto_neg = 0;
 	if (!((tmp >> 12) & 1)) {
-		write_mii(0, 0, regs);
+		write_mii(phyaddr, 0, 0, regs);
 	} else {
 		/* wait for auto negotiation to complete and then check operating mode */
 		dev->auto_neg = 1;
 		i = 0;
-		while (!(((tmp = read_mii(1, regs)) >> 5) & 1)) {
+		while (!(((tmp = read_mii(phyaddr, 1, regs)) >> 5) & 1)) {
 			if (get_timer(start) > timeout) {
 				printf("Auto negotiation timed out. "
 				       "Selecting default config\n");
-				tmp = read_mii(0, regs);
+				tmp = read_mii(phyaddr, 0, regs);
 				dev->gb = ((tmp >> 6) & 1)
 				    && !((tmp >> 13) & 1);
 				dev->sp = !((tmp >> 6) & 1)
@@ -270,8 +282,8 @@ int greth_init_phy(greth_priv * dev, bd_t * bis)
 			}
 		}
 		if ((tmp >> 8) & 1) {
-			tmp1 = read_mii(9, regs);
-			tmp2 = read_mii(10, regs);
+			tmp1 = read_mii(phyaddr, 9, regs);
+			tmp2 = read_mii(phyaddr, 10, regs);
 			if ((tmp1 & GRETH_MII_EXTADV_1000FD) &&
 			    (tmp2 & GRETH_MII_EXTPRT_1000FD)) {
 				dev->gb = 1;
@@ -284,8 +296,8 @@ int greth_init_phy(greth_priv * dev, bd_t * bis)
 			}
 		}
 		if ((dev->gb == 0) || ((dev->gb == 1) && (dev->gbit_mac == 0))) {
-			tmp1 = read_mii(4, regs);
-			tmp2 = read_mii(5, regs);
+			tmp1 = read_mii(phyaddr, 4, regs);
+			tmp2 = read_mii(phyaddr, 5, regs);
 			if ((tmp1 & GRETH_MII_100TXFD) &&
 			    (tmp2 & GRETH_MII_100TXFD)) {
 				dev->sp = 1;
@@ -302,7 +314,7 @@ int greth_init_phy(greth_priv * dev, bd_t * bis)
 			if ((dev->gb == 1) && (dev->gbit_mac == 0)) {
 				dev->gb = 0;
 				dev->fd = 0;
-				write_mii(0, dev->sp << 13, regs);
+				write_mii(phyaddr, 0, dev->sp << 13, regs);
 			}
 		}
 
@@ -314,8 +326,8 @@ int greth_init_phy(greth_priv * dev, bd_t * bis)
 #endif
 	/* Read out PHY info if extended registers are available */
 	if (tmp & 1) {
-		tmp1 = read_mii(2, regs);
-		tmp2 = read_mii(3, regs);
+		tmp1 = read_mii(phyaddr, 2, regs);
+		tmp2 = read_mii(phyaddr, 3, regs);
 		tmp1 = (tmp1 << 6) | ((tmp2 >> 10) & 0x3F);
 		tmp = tmp2 & 0xF;
 
@@ -542,10 +554,9 @@ int greth_recv(struct eth_device *dev)
 		/* increase index */
 		greth->rxbd_curr =
 		    ((unsigned int)greth->rxbd_curr >=
-		     (unsigned int)greth->rxbd_max) ? greth->
-		    rxbd_base : (greth->rxbd_curr + 1);
+		     (unsigned int)greth->rxbd_max) ? greth->rxbd_base : (greth->rxbd_curr + 1);
 
-	};
+	}
 
 	if (enable) {
 		GRETH_REGORIN(&regs->control, GRETH_RXEN);
@@ -630,6 +641,9 @@ int greth_initialize(bd_t * bis)
 	/* initiate PHY, select speed/duplex depending on connected PHY */
 	if (greth_init_phy(greth, bis)) {
 		/* Failed to init PHY (timedout) */
+#ifdef DEBUG
+		printf("GRETH[0x%08x]: Failed to init PHY\n", greth->regs);
+#endif
 		return -1;
 	}
 
@@ -658,5 +672,8 @@ int greth_initialize(bd_t * bis)
 	/* set and remember MAC address */
 	greth_set_hwaddr(greth, addr);
 
+#ifdef DEBUG
+	printf("GRETH[0x%08x]: Initialized successfully\n", greth->regs);
+#endif
 	return 0;
 }
-- 
1.5.4



More information about the U-Boot mailing list