All of lore.kernel.org
 help / color / mirror / Atom feed
From: Larry Johnson <lrj@arlinx.com>
To: u-boot@lists.denx.de
Subject: [U-Boot-Users] [PATCH] PPC4xx: Add Ethernet 1000BASE-X support for PPC4xx
Date: Mon, 29 Oct 2007 12:00:56 -0500	[thread overview]
Message-ID: <472611C8.4050107@arlinx.com> (raw)

This patch adds a new switch: "CONFIG_PHY_DYNAMIC_ANEG".  When this symbol
is defined, the PHY will advertise it's capabilities for autonegotiation
based on the capabilities shown in the PHY's status registers, including
1000BASE-X.  When "CONFIG_PHY_DYNAMIC_ANEG" is not defined, the PHY will
advertise hard-coded capabilities, as before.

Signed-off-by: Larry Johnson <lrj@acm.org>
---
diff --git a/common/miiphyutil.c b/common/miiphyutil.c
index c69501f..39e3c20 100644
--- a/common/miiphyutil.c
+++ b/common/miiphyutil.c
@@ -36,7 +36,6 @@
 #include <net.h>

 /* local debug macro */
-#define MII_DEBUG
 #undef MII_DEBUG

 #undef debug
@@ -49,10 +48,10 @@
 struct mii_dev {
 	struct list_head link;
 	char *name;
-	int (* read)(char *devname, unsigned char addr,
-			unsigned char reg, unsigned short *value);
-	int (* write)(char *devname, unsigned char addr,
-			unsigned char reg, unsigned short value);
+	int (*read) (char *devname, unsigned char addr,
+		     unsigned char reg, unsigned short *value);
+	int (*write) (char *devname, unsigned char addr,
+		      unsigned char reg, unsigned short value);
 };

 static struct list_head mii_devs;
@@ -62,21 +61,21 @@ static struct mii_dev *current_mii;
  *
  * Initialize global data. Need to be called before any other miiphy routine.
  */
-void miiphy_init()
+void miiphy_init ()
 {
-		INIT_LIST_HEAD(&mii_devs);
-		current_mii = NULL;
+	INIT_LIST_HEAD (&mii_devs);
+	current_mii = NULL;
 }

 /*****************************************************************************
  *
  * Register read and write MII access routines for the device <name>.
  */
-void miiphy_register(char *name,
-		int (* read)(char *devname, unsigned char addr,
-			unsigned char reg, unsigned short *value),
-		int (* write)(char *devname, unsigned char addr,
-			unsigned char reg, unsigned short value))
+void miiphy_register (char *name,
+		      int (*read) (char *devname, unsigned char addr,
+				   unsigned char reg, unsigned short *value),
+		      int (*write) (char *devname, unsigned char addr,
+				    unsigned char reg, unsigned short value))
 {
 	struct list_head *entry;
 	struct mii_dev *new_dev;
@@ -84,63 +83,64 @@ void miiphy_register(char *name,
 	unsigned int name_len;

 	/* check if we have unique name */
-	list_for_each(entry, &mii_devs) {
-		miidev = list_entry(entry, struct mii_dev, link);
-		if (strcmp(miidev->name, name) == 0) {
-			printf("miiphy_register: non unique device name '%s'\n",
-					name);
+	list_for_each (entry, &mii_devs) {
+		miidev = list_entry (entry, struct mii_dev, link);
+		if (strcmp (miidev->name, name) == 0) {
+			printf ("miiphy_register: non unique device name "
+				"'%s'\n", name);
 			return;
 		}
 	}

 	/* allocate memory */
-	name_len = strlen(name);
-	new_dev = (struct mii_dev *)malloc(sizeof(struct mii_dev) + name_len + 1);
+	name_len = strlen (name);
+	new_dev =
+	    (struct mii_dev *)malloc (sizeof (struct mii_dev) + name_len + 1);

-	if(new_dev == NULL) {
-		printf("miiphy_register: cannot allocate memory for '%s'\n",
-				name);
+	if (new_dev == NULL) {
+		printf ("miiphy_register: cannot allocate memory for '%s'\n",
+			name);
 		return;
 	}
-	memset(new_dev, 0, sizeof(struct mii_dev) + name_len);
+	memset (new_dev, 0, sizeof (struct mii_dev) + name_len);

 	/* initalize mii_dev struct fields */
-	INIT_LIST_HEAD(&new_dev->link);
+	INIT_LIST_HEAD (&new_dev->link);
 	new_dev->read = read;
 	new_dev->write = write;
 	new_dev->name = (char *)(new_dev + 1);
-	strncpy(new_dev->name, name, name_len);
+	strncpy (new_dev->name, name, name_len);
 	new_dev->name[name_len] = '\0';

-	debug("miiphy_register: added '%s', read=0x%08lx, write=0x%08lx\n",
-			new_dev->name, new_dev->read, new_dev->write);
+	debug ("miiphy_register: added '%s', read=0x%08lx, write=0x%08lx\n",
+	       new_dev->name, new_dev->read, new_dev->write);

 	/* add it to the list */
-	list_add_tail(&new_dev->link, &mii_devs);
+	list_add_tail (&new_dev->link, &mii_devs);

 	if (!current_mii)
 		current_mii = new_dev;
 }

-int miiphy_set_current_dev(char *devname)
+int miiphy_set_current_dev (char *devname)
 {
 	struct list_head *entry;
 	struct mii_dev *dev;

-	list_for_each(entry, &mii_devs) {
-		dev = list_entry(entry, struct mii_dev, link);
+	list_for_each (entry, &mii_devs) {
+		dev = list_entry (entry, struct mii_dev, link);

-		if (strcmp(devname, dev->name) == 0) {
+		if (strcmp (devname, dev->name) == 0) {
 			current_mii = dev;
 			return 0;
 		}
 	}

-	printf("No such device: %s\n", devname);
+	printf ("No such device: %s\n", devname);
 	return 1;
 }

-char *miiphy_get_current_dev()
+char *miiphy_get_current_dev ()
 {
 	if (current_mii)
 		return current_mii->name;
@@ -156,8 +156,8 @@ char *miiphy_get_current_dev()
  * Returns:
  *   0 on success
  */
-int miiphy_read(char *devname, unsigned char addr, unsigned char reg,
-		unsigned short *value)
+int miiphy_read (char *devname, unsigned char addr, unsigned char reg,
+		 unsigned short *value)
 {
 	struct list_head *entry;
 	struct mii_dev *dev;
@@ -165,22 +165,22 @@ int miiphy_read(char *devname, unsigned char addr, unsigned char reg,
 	int read_ret = 0;

 	if (!devname) {
-		printf("NULL device name!\n");
+		printf ("NULL device name!\n");
 		return 1;
 	}

-	list_for_each(entry, &mii_devs) {
-		dev = list_entry(entry, struct mii_dev, link);
+	list_for_each (entry, &mii_devs) {
+		dev = list_entry (entry, struct mii_dev, link);

-		if (strcmp(devname, dev->name) == 0) {
+		if (strcmp (devname, dev->name) == 0) {
 			found_dev = 1;
-			read_ret = dev->read(devname, addr, reg, value);
+			read_ret = dev->read (devname, addr, reg, value);
 			break;
 		}
 	}

 	if (found_dev == 0)
-		printf("No such device: %s\n", devname);
+		printf ("No such device: %s\n", devname);

 	return ((found_dev) ? read_ret : 1);
 }
@@ -193,8 +193,8 @@ int miiphy_read(char *devname, unsigned char addr, unsigned char reg,
  * Returns:
  *   0 on success
  */
-int miiphy_write(char *devname, unsigned char addr, unsigned char reg,
-		unsigned short value)
+int miiphy_write (char *devname, unsigned char addr, unsigned char reg,
+		  unsigned short value)
 {
 	struct list_head *entry;
 	struct mii_dev *dev;
@@ -202,22 +202,22 @@ int miiphy_write(char *devname, unsigned char addr, unsigned char reg,
 	int write_ret = 0;

 	if (!devname) {
-		printf("NULL device name!\n");
+		printf ("NULL device name!\n");
 		return 1;
 	}

-	list_for_each(entry, &mii_devs) {
-		dev = list_entry(entry, struct mii_dev, link);
+	list_for_each (entry, &mii_devs) {
+		dev = list_entry (entry, struct mii_dev, link);

-		if (strcmp(devname, dev->name) == 0) {
+		if (strcmp (devname, dev->name) == 0) {
 			found_dev = 1;
-			write_ret = dev->write(devname, addr, reg, value);
+			write_ret = dev->write (devname, addr, reg, value);
 			break;
 		}
 	}

 	if (found_dev == 0)
-		printf("No such device: %s\n", devname);
+		printf ("No such device: %s\n", devname);

 	return ((found_dev) ? write_ret : 1);
 }
@@ -226,23 +226,22 @@ int miiphy_write(char *devname, unsigned char addr, unsigned char reg,
  *
  * Print out list of registered MII capable devices.
  */
-void miiphy_listdev(void)
+void miiphy_listdev (void)
 {
 	struct list_head *entry;
 	struct mii_dev *dev;

-	puts("MII devices: ");
-	list_for_each(entry, &mii_devs) {
-		dev = list_entry(entry, struct mii_dev, link);
-		printf("'%s' ", dev->name);
+	puts ("MII devices: ");
+	list_for_each (entry, &mii_devs) {
+		dev = list_entry (entry, struct mii_dev, link);
+		printf ("'%s' ", dev->name);
 	}
-	puts("\n");
+	puts ("\n");

 	if (current_mii)
-		printf("Current device: '%s'\n", current_mii->name);
+		printf ("Current device: '%s'\n", current_mii->name);
 }

-
 /*****************************************************************************
  *
  * Read the OUI, manufacture's model number, and revision number.
@@ -254,9 +253,7 @@ void miiphy_listdev(void)
  * Returns:
  *   0 on success
  */
-int miiphy_info (char *devname,
-		 unsigned char addr,
-		 unsigned int *oui,
+int miiphy_info (char *devname, unsigned char addr, unsigned int *oui,
 		 unsigned char *model, unsigned char *rev)
 {
 	unsigned int reg = 0;
@@ -288,13 +285,12 @@ int miiphy_info (char *devname,
 #ifdef DEBUG
 	printf ("PHY_PHYIDR[1,2] @ 0x%x = 0x%08x\n", addr, reg);
 #endif
-	*oui   =                 ( reg >> 10);
-	*model = (unsigned char) ((reg >>  4) & 0x0000003F);
-	*rev   = (unsigned char) ( reg        & 0x0000000F);
+	*oui = (reg >> 10);
+	*model = (unsigned char)((reg >> 4) & 0x0000003F);
+	*rev = (unsigned char)(reg & 0x0000000F);
 	return (0);
 }

-
 /*****************************************************************************
  *
  * Reset the PHY.
@@ -345,104 +341,150 @@ int miiphy_reset (char *devname, unsigned char addr)
 	return (0);
 }

-
 /*****************************************************************************
  *
- * Determine the ethernet speed (10/100).
+ * Determine the ethernet speed (10/100/1000).  Return 10 on error.
  */
 int miiphy_speed (char *devname, unsigned char addr)
 {
-	unsigned short reg;
+	u16 bmcr;

 #if defined(CONFIG_PHY_GIGE)
-	if (miiphy_read (devname, addr, PHY_1000BTSR, &reg)) {
-		printf ("PHY 1000BT Status read failed\n");
-	} else {
-		if (reg != 0xFFFF) {
-			if ((reg & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) !=0) {
-				return (_1000BASET);
-			}
+	u16 btsr;
+
+#if defined(CONFIG_PHY_DYNAMIC_ANEG)
+	u16 bmsr;
+
+	/* Check for 1000BASE-X. */
+	if (miiphy_read (devname, addr, PHY_BMSR, &bmsr)) {
+		printf ("PHY status");
+		goto miiphy_read_failed;
+	}
+	if (bmsr & PHY_BMSR_EXT_STAT) {
+		u16 exsr;
+
+		if (miiphy_read (devname, addr, PHY_EXSR, &exsr)) {
+			printf ("PHY extended status");
+			goto miiphy_read_failed;
+		}
+		if (exsr & (PHY_EXSR_1000XF | PHY_EXSR_1000XH)) {
+			/* 1000BASE-X */
+			return _1000BASET;
 		}
 	}
+#endif /*  defined(CONFIG_PHY_DYNAMIC_ANEG) */
+
+	/* Check for 1000BASE-T. */
+	if (miiphy_read (devname, addr, PHY_1000BTSR, &btsr)) {
+		printf ("PHY 1000BT status");
+		goto miiphy_read_failed;
+	}
+	if (btsr != 0xFFFF &&
+	    (btsr & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD))) {
+		return _1000BASET;
+	}
 #endif /* CONFIG_PHY_GIGE */

 	/* Check Basic Management Control Register first. */
-	if (miiphy_read (devname, addr, PHY_BMCR, &reg)) {
-		puts ("PHY speed read failed, assuming 10bT\n");
-		return (_10BASET);
+	if (miiphy_read (devname, addr, PHY_BMCR, &bmcr)) {
+		printf ("PHY speed");
+		goto miiphy_read_failed;
 	}
 	/* Check if auto-negotiation is on. */
-	if ((reg & PHY_BMCR_AUTON) != 0) {
+	if (bmcr & PHY_BMCR_AUTON) {
 		/* Get auto-negotiation results. */
-		if (miiphy_read (devname, addr, PHY_ANLPAR, &reg)) {
-			puts ("PHY AN speed read failed, assuming 10bT\n");
-			return (_10BASET);
-		}
-		if ((reg & PHY_ANLPAR_100) != 0) {
-			return (_100BASET);
-		} else {
-			return (_10BASET);
+		u16 anlpar;
+
+		if (miiphy_read (devname, addr, PHY_ANLPAR, &anlpar)) {
+			printf ("PHY AN speed");
+			goto miiphy_read_failed;
 		}
+		return (anlpar & PHY_ANLPAR_100) ? _100BASET : _10BASET;
 	}
 	/* Get speed from basic control settings. */
-	else if (reg & PHY_BMCR_100MB) {
-		return (_100BASET);
-	} else {
-		return (_10BASET);
-	}
+	return (bmcr & PHY_BMCR_100MB) ? _100BASET : _10BASET;

+      miiphy_read_failed:
+	printf (" read failed, assuming 10BASE-T\n");
+	return _10BASET;
 }

-
 /*****************************************************************************
  *
- * Determine full/half duplex.
+ * Determine full/half duplex.  Return half on error.
  */
 int miiphy_duplex (char *devname, unsigned char addr)
 {
-	unsigned short reg;
+	u16 bmcr;

 #if defined(CONFIG_PHY_GIGE)
-	if (miiphy_read (devname, addr, PHY_1000BTSR, &reg)) {
-		printf ("PHY 1000BT Status read failed\n");
-	} else {
-		if ( (reg != 0xFFFF) &&
-		     (reg & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) ) {
-			if ((reg & PHY_1000BTSR_1000FD) !=0) {
-				return (FULL);
-			} else {
-				return (HALF);
+	u16 btsr;
+
+#if defined(CONFIG_PHY_DYNAMIC_ANEG)
+	u16 bmsr;
+
+	/* Check for 1000BASE-X. */
+	if (miiphy_read (devname, addr, PHY_BMSR, &bmsr)) {
+		printf ("PHY status");
+		goto miiphy_read_failed;
+	}
+	if (bmsr & PHY_BMSR_EXT_STAT) {
+		u16 exsr;
+
+		if (miiphy_read (devname, addr, PHY_EXSR, &exsr)) {
+			printf ("PHY extended status");
+			goto miiphy_read_failed;
+		}
+		if (exsr & (PHY_EXSR_1000XF | PHY_EXSR_1000XH)) {
+			/* 1000BASE-X */
+			u16 anlpar;
+
+			if (miiphy_read (devname, addr, PHY_ANLPAR, &anlpar)) {
+				printf ("1000BASE-X PHY AN duplex");
+				goto miiphy_read_failed;
 			}
+			return (anlpar & PHY_X_ANLPAR_FD) ? FULL : HALF;
+		}
+	}
+#endif /* defined(CONFIG_PHY_DYNAMIC_ANEG) */
+
+	/* Check for 1000BASE-T. */
+	if (miiphy_read (devname, addr, PHY_1000BTSR, &btsr)) {
+		printf ("PHY 1000BT status");
+		goto miiphy_read_failed;
+	}
+	if (btsr != 0xFFFF) {
+		if (btsr & PHY_1000BTSR_1000FD) {
+			return FULL;
+		} else if (btsr & PHY_1000BTSR_1000HD) {
+			return HALF;
 		}
 	}
 #endif /* CONFIG_PHY_GIGE */

 	/* Check Basic Management Control Register first. */
-	if (miiphy_read (devname, addr, PHY_BMCR, &reg)) {
-		puts ("PHY duplex read failed, assuming half duplex\n");
-		return (HALF);
+	if (miiphy_read (devname, addr, PHY_BMCR, &bmcr)) {
+		puts ("PHY duplex");
+		goto miiphy_read_failed;
 	}
 	/* Check if auto-negotiation is on. */
-	if ((reg & PHY_BMCR_AUTON) != 0) {
+	if ((bmcr & PHY_BMCR_AUTON) != 0) {
 		/* Get auto-negotiation results. */
-		if (miiphy_read (devname, addr, PHY_ANLPAR, &reg)) {
-			puts ("PHY AN duplex read failed, assuming half duplex\n");
-			return (HALF);
-		}
+		u16 anlpar;

-		if ((reg & (PHY_ANLPAR_10FD | PHY_ANLPAR_TXFD)) != 0) {
-			return (FULL);
-		} else {
-			return (HALF);
+		if (miiphy_read (devname, addr, PHY_ANLPAR, &anlpar)) {
+			puts ("PHY AN duplex");
+			goto miiphy_read_failed;
 		}
+		return (anlpar & (PHY_ANLPAR_10FD | PHY_ANLPAR_TXFD)) ?
+		    FULL : HALF;
 	}
 	/* Get speed from basic control settings. */
-	else if (reg & PHY_BMCR_DPLX) {
-		return (FULL);
-	} else {
-		return (HALF);
-	}
+	return (bmcr & PHY_BMCR_DPLX) ? FULL : HALF;

+      miiphy_read_failed:
+	printf (" read failed, assuming half duplex\n");
+	return HALF;
 }

 #ifdef CFG_FAULT_ECHO_LINK_DOWN
@@ -455,7 +497,7 @@ int miiphy_link (char *devname, unsigned char addr)
 	unsigned short reg;

 	/* dummy read; needed to latch some phys */
-	(void)miiphy_read(devname, addr, PHY_BMSR, &reg);
+	(void)miiphy_read (devname, addr, PHY_BMSR, &reg);
 	if (miiphy_read (devname, addr, PHY_BMSR, &reg)) {
 		puts ("PHY_BMSR read failed, assuming no link\n");
 		return (0);
@@ -469,5 +511,4 @@ int miiphy_link (char *devname, unsigned char addr)
 	}
 }
 #endif
-
 #endif /* CONFIG_MII */
diff --git a/cpu/ppc4xx/miiphy.c b/cpu/ppc4xx/miiphy.c
index 6b98025..55d777f 100644
--- a/cpu/ppc4xx/miiphy.c
+++ b/cpu/ppc4xx/miiphy.c
@@ -39,6 +39,9 @@
   |  19-Jul-00	 Ported to esd cpci405					     sr
   |  23-Dec-03	 Ported from miiphy.c to 440GX Travis Sawyer		     TBS
   |		 <travis.sawyer@sandburst.com>
+  |  20-Oct-07	 Added support for autonegotiation base on reported	     lrj
+  |		 capabilities, including 1000BASE-X.  Larry Johnson
+  |		 <lrj@acm.org>
   |
   +-----------------------------------------------------------------------------*/

@@ -60,7 +63,6 @@ void miiphy_dump (char *devname, unsigned char addr)
 	unsigned long i;
 	unsigned short data;

-
 	for (i = 0; i < 0x1A; i++) {
 		if (miiphy_read (devname, addr, i, &data)) {
 			printf ("read error for reg %lx\n", i);
@@ -75,15 +77,87 @@ void miiphy_dump (char *devname, unsigned char addr)
 	}			/* end for loop */
 }				/* end dump */

-
 /***********************************************************/
 /* (Re)start autonegotiation				   */
 /***********************************************************/
 int phy_setup_aneg (char *devname, unsigned char addr)
 {
-	unsigned short ctl, adv;
+	u16 bmcr;
+
+#if defined(CONFIG_PHY_DYNAMIC_ANEG)
+	/*
+	 * Set up advertisement based on capablilities reported by the PHY.
+	 * This should work for both copper and fiber.
+	 */
+	u16 bmsr;
+#if defined(CONFIG_PHY_GIGE)
+	u16 exsr = 0x0000;
+#endif
+
+	miiphy_read (devname, addr, PHY_BMSR, &bmsr);
+
+#if defined(CONFIG_PHY_GIGE)
+	if (bmsr & PHY_BMSR_EXT_STAT) {
+		miiphy_read (devname, addr, PHY_EXSR, &exsr);
+	}
+
+	if (exsr & (PHY_EXSR_1000XF | PHY_EXSR_1000XH)) {
+		/* 1000BASE-X */
+		u16 anar = 0x0000;
+
+		if (exsr & PHY_EXSR_1000XF) {
+			anar |= PHY_X_ANLPAR_FD;
+		}
+		if (exsr & PHY_EXSR_1000XH) {
+			anar |= PHY_X_ANLPAR_HD;
+		}
+		miiphy_write (devname, addr, PHY_ANAR, anar);
+	} else
+#endif
+	{
+		u16 anar, btcr;
+
+		miiphy_read (devname, addr, PHY_ANAR, &anar);
+		anar &= ~(0x5000 | PHY_ANLPAR_T4 | PHY_ANLPAR_TXFD |
+			  PHY_ANLPAR_TX | PHY_ANLPAR_10FD | PHY_ANLPAR_10);
+
+		miiphy_read (devname, addr, PHY_1000BTCR, &btcr);
+		btcr &= ~(0x00FF | PHY_1000BTCR_1000FD | PHY_1000BTCR_1000HD);
+
+		if (bmsr & PHY_BMSR_100T4) {
+			anar |= PHY_ANLPAR_T4;
+		}
+		if (bmsr & PHY_BMSR_100TXF) {
+			anar |= PHY_ANLPAR_TXFD;
+		}
+		if (bmsr & PHY_BMSR_100TXH) {
+			anar |= PHY_ANLPAR_TX;
+		}
+		if (bmsr & PHY_BMSR_10TF) {
+			anar |= PHY_ANLPAR_10FD;
+		}
+		if (bmsr & PHY_BMSR_10TH) {
+			anar |= PHY_ANLPAR_10;
+		}
+		miiphy_write (devname, addr, PHY_ANAR, anar);
+
+#if defined(CONFIG_PHY_GIGE)
+		if (exsr & PHY_EXSR_1000TF) {
+			btcr |= PHY_1000BTCR_1000FD;
+		}
+		if (exsr & PHY_EXSR_1000TH) {
+			btcr |= PHY_1000BTCR_1000HD;
+		}
+		miiphy_write (devname, addr, PHY_1000BTCR, btcr);
+#endif
+	}
+
+#else /* defined(CONFIG_PHY_DYNAMIC_ANEG) */
+	/*
+	 * Set up standard advertisement
+	 */
+	u16 adv;

-	/* Setup standard advertise */
 	miiphy_read (devname, addr, PHY_ANAR, &adv);
 	adv |= (PHY_ANLPAR_ACK | PHY_ANLPAR_RF | PHY_ANLPAR_T4 |
 		PHY_ANLPAR_TXFD | PHY_ANLPAR_TX | PHY_ANLPAR_10FD |
@@ -94,15 +168,16 @@ int phy_setup_aneg (char *devname, unsigned char addr)
 	adv |= (0x0300);
 	miiphy_write (devname, addr, PHY_1000BTCR, adv);

+#endif /* defined(CONFIG_PHY_DYNAMIC_ANEG) */
+
 	/* Start/Restart aneg */
-	miiphy_read (devname, addr, PHY_BMCR, &ctl);
-	ctl |= (PHY_BMCR_AUTON | PHY_BMCR_RST_NEG);
-	miiphy_write (devname, addr, PHY_BMCR, ctl);
+	miiphy_read (devname, addr, PHY_BMCR, &bmcr);
+	bmcr |= (PHY_BMCR_AUTON | PHY_BMCR_RST_NEG);
+	miiphy_write (devname, addr, PHY_BMCR, bmcr);

 	return 0;
 }

-
 /***********************************************************/
 /* read a phy reg and return the value with a rc	   */
 /***********************************************************/
@@ -145,21 +220,20 @@ unsigned int miiphy_getemac_offset (void)
 #endif
 }

-
-int emac4xx_miiphy_read (char *devname, unsigned char addr,
-		unsigned char reg, unsigned short *value)
+int emac4xx_miiphy_read (char *devname, unsigned char addr, unsigned char reg,
+			 unsigned short *value)
 {
 	unsigned long sta_reg;	/* STA scratch area */
 	unsigned long i;
 	unsigned long emac_reg;

-
 	emac_reg = miiphy_getemac_offset ();
 	/* see if it is ready for 1000 nsec */
 	i = 0;

 	/* see if it is ready for  sec */
-	while ((in32 (EMAC_STACR + emac_reg) & EMAC_STACR_OC) == EMAC_STACR_OC_MASK) {
+	while ((in32 (EMAC_STACR + emac_reg) & EMAC_STACR_OC) ==
+	       EMAC_STACR_OC_MASK) {
 		udelay (7);
 		if (i > 5) {
 #ifdef ET_DEBUG
@@ -175,10 +249,10 @@ int emac4xx_miiphy_read (char *devname, unsigned char addr,
 	/* set clock (50Mhz) and read flags */
 #if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
     defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
-#if defined(CONFIG_IBM_EMAC4_V4)      /* EMAC4 V4 changed bit setting */
-		sta_reg = (sta_reg & ~EMAC_STACR_OP_MASK) | EMAC_STACR_READ;
+#if defined(CONFIG_IBM_EMAC4_V4)	/* EMAC4 V4 changed bit setting */
+	sta_reg = (sta_reg & ~EMAC_STACR_OP_MASK) | EMAC_STACR_READ;
 #else
-		sta_reg |= EMAC_STACR_READ;
+	sta_reg |= EMAC_STACR_READ;
 #endif
 #else
 	sta_reg = (sta_reg | EMAC_STACR_READ) & ~EMAC_STACR_CLK_100MHZ;
@@ -198,7 +272,7 @@ int emac4xx_miiphy_read (char *devname, unsigned char addr,

 	sta_reg = in32 (EMAC_STACR + emac_reg);
 #ifdef ET_DEBUG
-		printf ("a21: read : EMAC_STACR=0x%0x\n", sta_reg);	/* test-only */
+	printf ("a21: read : EMAC_STACR=0x%0x\n", sta_reg);	/* test-only */
 #endif
 	i = 0;
 	while ((sta_reg & EMAC_STACR_OC) == EMAC_STACR_OC_MASK) {
@@ -216,19 +290,17 @@ int emac4xx_miiphy_read (char *devname, unsigned char addr,
 		return -1;
 	}

-	*value = *(short *) (&sta_reg);
+	*value = *(short *)(&sta_reg);
 	return 0;

-
 }				/* phy_read */

-
 /***********************************************************/
 /* write a phy reg and return the value with a rc	    */
 /***********************************************************/

-int emac4xx_miiphy_write (char *devname, unsigned char addr,
-		unsigned char reg, unsigned short value)
+int emac4xx_miiphy_write (char *devname, unsigned char addr, unsigned char reg,
+			  unsigned short value)
 {
 	unsigned long sta_reg;	/* STA scratch area */
 	unsigned long i;
@@ -238,7 +310,8 @@ int emac4xx_miiphy_write (char *devname, unsigned char addr,
 	/* see if it is ready for 1000 nsec */
 	i = 0;

-	while ((in32 (EMAC_STACR + emac_reg) & EMAC_STACR_OC) == EMAC_STACR_OC_MASK) {
+	while ((in32 (EMAC_STACR + emac_reg) & EMAC_STACR_OC) ==
+	       EMAC_STACR_OC_MASK) {
 		if (i > 5)
 			return -1;
 		udelay (7);
@@ -249,10 +322,10 @@ int emac4xx_miiphy_write (char *devname, unsigned char addr,
 	/* set clock (50Mhz) and read flags */
 #if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
     defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
-#if defined(CONFIG_IBM_EMAC4_V4)      /* EMAC4 V4 changed bit setting */
-		sta_reg = (sta_reg & ~EMAC_STACR_OP_MASK) | EMAC_STACR_WRITE;
+#if defined(CONFIG_IBM_EMAC4_V4)	/* EMAC4 V4 changed bit setting */
+	sta_reg = (sta_reg & ~EMAC_STACR_OP_MASK) | EMAC_STACR_WRITE;
 #else
-		sta_reg |= EMAC_STACR_WRITE;
+	sta_reg |= EMAC_STACR_WRITE;
 #endif
 #else
 	sta_reg = (sta_reg | EMAC_STACR_WRITE) & ~EMAC_STACR_CLK_100MHZ;
@@ -263,8 +336,8 @@ int emac4xx_miiphy_write (char *devname, unsigned char addr,
     !defined(CONFIG_440EPX) && !defined(CONFIG_440GRX)
 	sta_reg = sta_reg | CONFIG_PHY_CLK_FREQ;	/* Set clock frequency (PLB freq. dependend) */
 #endif
-	sta_reg = sta_reg | ((unsigned long) addr << 5);/* Phy address */
-	sta_reg = sta_reg | EMAC_STACR_OC_MASK;		/* new IBM emac v4 */
+	sta_reg = sta_reg | ((unsigned long)addr << 5);	/* Phy address */
+	sta_reg = sta_reg | EMAC_STACR_OC_MASK;	/* new IBM emac v4 */
 	memcpy (&sta_reg, &value, 2);	/* put in data */

 	out32 (EMAC_STACR + emac_reg, sta_reg);
@@ -273,7 +346,7 @@ int emac4xx_miiphy_write (char *devname, unsigned char addr,
 	i = 0;
 	sta_reg = in32 (EMAC_STACR + emac_reg);
 #ifdef ET_DEBUG
-		printf ("a31: read : EMAC_STACR=0x%0x\n", sta_reg);	/* test-only */
+	printf ("a31: read : EMAC_STACR=0x%0x\n", sta_reg);	/* test-only */
 #endif
 	while ((sta_reg & EMAC_STACR_OC) == EMAC_STACR_OC_MASK) {
 		udelay (7);
diff --git a/include/miiphy.h b/include/miiphy.h
index 71716b0..0332e4b 100644
--- a/include/miiphy.h
+++ b/include/miiphy.h
@@ -33,6 +33,7 @@
 |  04-May-99   Created							MKW
 |  07-Jul-99   Added full duplex support				MKW
 |  08-Sep-01   Tweaks							gvb
+|  28-Oct-07   Added 1000BASE-X support.  Larry Johnson <lrj@acm.org>   lrj
 |
 +----------------------------------------------------------------------------*/
 #ifndef _miiphy_h_
@@ -40,26 +41,26 @@

 #include <net.h>

-int  miiphy_read(char *devname, unsigned char addr, unsigned char reg,
+int miiphy_read(char *devname, unsigned char addr, unsigned char reg,
 		unsigned short *value);
-int  miiphy_write(char *devname, unsigned char addr, unsigned char reg,
-		unsigned short value);
-int  miiphy_info(char *devname, unsigned char addr, unsigned int  *oui,
+int miiphy_write(char *devname, unsigned char addr, unsigned char reg,
+		 unsigned short value);
+int miiphy_info(char *devname, unsigned char addr, unsigned int *oui,
 		unsigned char *model, unsigned char *rev);
-int  miiphy_reset(char *devname, unsigned char addr);
-int  miiphy_speed(char *devname, unsigned char addr);
-int  miiphy_duplex(char *devname, unsigned char addr);
+int miiphy_reset(char *devname, unsigned char addr);
+int miiphy_speed(char *devname, unsigned char addr);
+int miiphy_duplex(char *devname, unsigned char addr);
 #ifdef CFG_FAULT_ECHO_LINK_DOWN
-int  miiphy_link(char *devname, unsigned char addr);
+int miiphy_link(char *devname, unsigned char addr);
 #endif

 void miiphy_init(void);

 void miiphy_register(char *devname,
-	int (* read)(char *devname, unsigned char addr,
-		unsigned char reg, unsigned short *value),
-	int (* write)(char *devname, unsigned char addr,
-		unsigned char reg, unsigned short value));
+		     int (*read) (char *devname, unsigned char addr,
+				  unsigned char reg, unsigned short *value),
+		     int (*write) (char *devname, unsigned char addr,
+				   unsigned char reg, unsigned short value));

 int miiphy_set_current_dev(char *devname);
 char *miiphy_get_current_dev(void);
@@ -68,14 +69,14 @@ void miiphy_listdev(void);

 #define BB_MII_DEVNAME	"bbmii"

-int bb_miiphy_read (char *devname, unsigned char addr,
-		unsigned char reg, unsigned short *value);
-int bb_miiphy_write (char *devname, unsigned char addr,
-		unsigned char reg, unsigned short value);
+int bb_miiphy_read(char *devname, unsigned char addr,
+		   unsigned char reg, unsigned short *value);
+int bb_miiphy_write(char *devname, unsigned char addr,
+		    unsigned char reg, unsigned short value);

 /* phy seed setup */
 #define AUTO			99
-#define _1000BASET              1000
+#define _1000BASET		1000
 #define _100BASET		100
 #define _10BASET		10
 #define HALF			22
@@ -90,9 +91,10 @@ int bb_miiphy_write (char *devname, unsigned char addr,
 #define PHY_ANLPAR		0x05
 #define PHY_ANER		0x06
 #define PHY_ANNPTR		0x07
-#define PHY_ANLPNP              0x08
-#define PHY_1000BTCR            0x09
-#define PHY_1000BTSR            0x0A
+#define PHY_ANLPNP		0x08
+#define PHY_1000BTCR		0x09
+#define PHY_1000BTSR		0x0A
+#define PHY_EXSR		0x0F
 #define PHY_PHYSTS		0x10
 #define PHY_MIPSCR		0x11
 #define PHY_MIPGSR		0x12
@@ -126,6 +128,7 @@ int bb_miiphy_write (char *devname, unsigned char addr,
 #define PHY_BMSR_100TXH		0x2000
 #define PHY_BMSR_10TF		0x1000
 #define PHY_BMSR_10TH		0x0800
+#define PHY_BMSR_EXT_STAT	0x0100
 #define PHY_BMSR_PRE_SUP	0x0040
 #define PHY_BMSR_AUTN_COMP	0x0020
 #define PHY_BMSR_RF		0x0010
@@ -138,18 +141,31 @@ int bb_miiphy_write (char *devname, unsigned char addr,
 #define PHY_ANLPAR_NP		0x8000
 #define PHY_ANLPAR_ACK		0x4000
 #define PHY_ANLPAR_RF		0x2000
+#define PHY_ANLPAR_ASYMP	0x0800
+#define PHY_ANLPAR_PAUSE	0x0400
 #define PHY_ANLPAR_T4		0x0200
 #define PHY_ANLPAR_TXFD		0x0100
 #define PHY_ANLPAR_TX		0x0080
 #define PHY_ANLPAR_10FD		0x0040
 #define PHY_ANLPAR_10		0x0020
-#define PHY_ANLPAR_100		0x0380	    /* we can run at 100 */
+#define PHY_ANLPAR_100		0x0380	/* we can run at 100 */
+/* phy ANLPAR 1000BASE-X */
+#define PHY_X_ANLPAR_NP		0x8000
+#define PHY_X_ANLPAR_ACK	0x4000
+#define PHY_X_ANLPAR_RF_MASK	0x3000
+#define PHY_X_ANLPAR_PAUSE_MASK	0x0180
+#define PHY_X_ANLPAR_HD		0x0040
+#define PHY_X_ANLPAR_FD		0x0020

 #define PHY_ANLPAR_PSB_MASK     0x001f
 #define PHY_ANLPAR_PSB_802_3    0x0001
 #define PHY_ANLPAR_PSB_802_9    0x0002

-/* PHY_1000BTSR */
+/* phy 1000BTCR */
+#define PHY_1000BTCR_1000FD     0x0200
+#define PHY_1000BTCR_1000HD     0x0100
+
+/* phy 1000BTSR */
 #define PHY_1000BTSR_MSCF       0x8000
 #define PHY_1000BTSR_MSCR       0x4000
 #define PHY_1000BTSR_LRS        0x2000
@@ -157,4 +173,10 @@ int bb_miiphy_write (char *devname, unsigned char addr,
 #define PHY_1000BTSR_1000FD     0x0800
 #define PHY_1000BTSR_1000HD     0x0400

+/* phy EXSR */
+#define PHY_EXSR_1000XF		0x8000
+#define PHY_EXSR_1000XH		0x4000
+#define PHY_EXSR_1000TF		0x2000
+#define PHY_EXSR_1000TH		0x1000
+
 #endif

             reply	other threads:[~2007-10-29 17:00 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-10-29 17:00 Larry Johnson [this message]
2007-10-29 17:33 ` [U-Boot-Users] [PATCH] PPC4xx: Add Ethernet 1000BASE-X support for PPC4xx Ben Warren
2007-10-29 18:41   ` Larry Johnson
2007-10-29 19:14     ` Jon Loeliger
2007-10-29 19:30       ` Stefan Roese
2007-10-29 19:43         ` Larry Johnson
2007-10-29 19:37       ` Ben Warren
2007-10-29 20:26       ` Wolfgang Denk
2007-10-29 20:25     ` Wolfgang Denk
2007-10-29 21:36       ` Larry Johnson
2007-10-29 19:33 ` Stefan Roese
2007-10-29 20:26 ` Ben Warren
2007-10-29 22:01   ` Larry Johnson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=472611C8.4050107@arlinx.com \
    --to=lrj@arlinx.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.