From 5ca2679933142f7bf2996590b2e318c298664748 Mon Sep 17 00:00:00 2001
From: wdenk <wdenk>
Date: Sun, 6 Jun 2004 22:11:41 +0000
Subject: [PATCH] Patch by Dave Peverley, 29 Apr 2004: add MAC address
 detection to smc91111 driver

---
 CHANGELOG          |   6 +++
 drivers/lan91c96.c | 128 +++++++++++++++++++++++++++++++++++++++++----
 drivers/lan91c96.h |   1 -
 lib_arm/board.c    |   3 +-
 4 files changed, 126 insertions(+), 12 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 4402e4de1f..dfcc0f722e 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,12 @@
 Changes since U-Boot 1.1.1:
 ======================================================================
 
+* Patch by Dave Peverley, 29 Apr 2004:
+  add MAC address detection to smc91111 driver
+
+* Patch by David Müller, 28 Apr 2004:
+  fix typo in lib_arm/board.c
+
 * Patch by Tolunay Orkun, 20 Apr 2004:
   - README update: add CONFIG_CSB272 and csb272_config
   - add descriptions for some MII/PHY options, CONFIG_I2CFAST, and
diff --git a/drivers/lan91c96.c b/drivers/lan91c96.c
index 189ca87624..032f9780af 100644
--- a/drivers/lan91c96.c
+++ b/drivers/lan91c96.c
@@ -162,7 +162,7 @@ void smc_destructor (void);
  * The kernel calls this function when someone wants to use the device,
  * typically 'ifconfig ethX up'.
  */
-static int smc_open (void);
+static int smc_open (bd_t *bd);
 
 
 /*
@@ -178,6 +178,12 @@ static int smc_close (void);
  */
 static int smc_rcv (void);
 
+/* See if a MAC address is defined in the current environment. If so use it. If not
+ . print a warning and set the environment and other globals with the default.
+ . If an EEPROM is present it really should be consulted.
+*/
+int smc_get_ethaddr(bd_t *bd);
+int get_rom_mac(char *v_rom_mac);
 
 /* ------------------------------------------------------------
  * Internal routines
@@ -588,9 +594,9 @@ void smc_destructor ()
  * Set up everything, reset the card, etc ..
  *
  */
-static int smc_open ()
+static int smc_open (bd_t *bd)
 {
-	int i;			/* used to set hw ethernet address */
+	int i, err;			/* used to set hw ethernet address */
 
 	PRINTK2 ("%s:smc_open\n", SMC_DEV_NAME);
 
@@ -601,6 +607,12 @@ static int smc_open ()
 
 	SMC_SELECT_BANK (1);
 
+	err = smc_get_ethaddr (bd);	/* set smc_mac_addr, and sync it with u-boot globals */
+	if (err < 0) {
+		memset (bd->bi_enetaddr, 0, 6); /* hack to make error stick! upper code will abort if not set */
+		return (-1);	/* upper code ignores this, but NOT bi_enetaddr */
+	}
+#ifdef USE_32_BIT
 	for (i = 0; i < 6; i += 2) {
 		word address;
 
@@ -608,6 +620,10 @@ static int smc_open ()
 		address |= smc_mac_addr[i];
 		SMC_outw (address, LAN91C96_IA0 + i);
 	}
+#else 
+	for (i = 0; i < 6; i++)
+		SMC_outb (smc_mac_addr[i], LAN91C96_IA0 + i);
+#endif
 	return 0;
 }
 
@@ -782,8 +798,7 @@ static void print_packet (byte * buf, int length)
 
 int eth_init (bd_t * bd)
 {
-	smc_open ();
-	return 0;
+	return (smc_open(bd));
 }
 
 void eth_halt ()
@@ -801,10 +816,6 @@ int eth_send (volatile void *packet, int length)
 	return smc_send_packet (packet, length);
 }
 
-int eth_hw_init ()
-{
-	return smc_hw_init ();
-}
 
 /*-------------------------------------------------------------------------
  * smc_hw_init()
@@ -852,4 +863,103 @@ static int smc_hw_init ()
 
 #endif /* COMMANDS & CFG_NET */
 
+
+/* smc_get_ethaddr (bd_t * bd)
+ *
+ * This checks both the environment and the ROM for an ethernet address. If
+ * found, the environment takes precedence.
+ */
+
+int smc_get_ethaddr (bd_t * bd)
+{
+	int env_size = 0;
+	int rom_valid = 0;
+	int env_present = 0;
+	int reg = 0;
+	char *s = NULL;
+	char *e = NULL;
+	char *v_mac, es[] = "11:22:33:44:55:66";
+	uchar s_env_mac[64];
+	uchar v_env_mac[6];
+	uchar v_rom_mac[6];
+
+	env_size = getenv_r ("ethaddr", s_env_mac, sizeof (s_env_mac));
+	if (env_size != sizeof(es)) {	/* Ignore if env is bad or not set */
+		printf ("\n*** Warning: ethaddr is not set properly, ignoring!!\n");
+	} else {
+		env_present = 1;
+		s = s_env_mac;
+
+		for (reg = 0; reg < 6; ++reg) { /* turn string into mac value */
+			v_env_mac[reg] = s ? simple_strtoul (s, &e, 16) : 0;
+			if (s)
+				s = (*e) ? e + 1 : e;
+		}
+	}
+
+	rom_valid = get_rom_mac (v_rom_mac);	/* get ROM mac value if any */
+
+	if (!env_present) {	/* if NO env */
+		if (rom_valid) {	/* but ROM is valid */
+			v_mac = v_rom_mac;
+			sprintf (s_env_mac, "%02X:%02X:%02X:%02X:%02X:%02X",
+				 v_mac[0], v_mac[1], v_mac[2], v_mac[3],
+				 v_mac[4], v_mac[5]);
+			setenv ("ethaddr", s_env_mac);
+		} else {	/* no env, bad ROM */
+			printf ("\n*** ERROR: ethaddr is NOT set !!\n");
+			return (-1);
+		}
+	} else {		/* good env, don't care ROM */
+		v_mac = v_env_mac;	/* always use a good env over a ROM */
+	}
+
+	if (env_present && rom_valid) { /* if both env and ROM are good */
+		if (memcmp (v_env_mac, v_rom_mac, 6) != 0) {
+			printf ("\nWarning: MAC addresses don't match:\n");
+			printf ("\tHW MAC address:  "
+				"%02X:%02X:%02X:%02X:%02X:%02X\n",
+				v_rom_mac[0], v_rom_mac[1],
+				v_rom_mac[2], v_rom_mac[3],
+				v_rom_mac[4], v_rom_mac[5] );
+			printf ("\t\"ethaddr\" value: "
+				"%02X:%02X:%02X:%02X:%02X:%02X\n",
+				v_env_mac[0], v_env_mac[1],
+				v_env_mac[2], v_env_mac[3],
+				v_env_mac[4], v_env_mac[5]) ;
+			debug ("### Set MAC addr from environment\n");
+		}
+	}
+	memcpy (bd->bi_enetaddr, v_mac, 6);	/* update global address to match env (allows env changing) */
+	smc_set_mac_addr (v_mac);	/* use old function to update smc default */
+	PRINTK("Using MAC Address %02X:%02X:%02X:%02X:%02X:%02X\n", v_mac[0], v_mac[1],
+		v_mac[2], v_mac[3], v_mac[4], v_mac[5]);
+	return (0);
+}
+
+/* 
+ * get_rom_mac()
+ * Note, this has omly been tested for the OMAP730 P2.
+ */
+
+int get_rom_mac (char *v_rom_mac)
+{
+#ifdef HARDCODE_MAC	/* used for testing or to supress run time warnings */
+	char hw_mac_addr[] = { 0x02, 0x80, 0xad, 0x20, 0x31, 0xb8 };
+
+	memcpy (v_rom_mac, hw_mac_addr, 6);
+	return (1);
+#else
+	int i;
+	SMC_SELECT_BANK (1);
+	for (i=0; i<6; i++)
+	{
+		v_rom_mac[i] = SMC_inb (LAN91C96_IA0 + i);
+	}
+	return (1);
+#endif
+}
+
+
+
 #endif /* CONFIG_DRIVER_LAN91C96 */
diff --git a/drivers/lan91c96.h b/drivers/lan91c96.h
index 4eb7d7f045..5c2afcef23 100644
--- a/drivers/lan91c96.h
+++ b/drivers/lan91c96.h
@@ -52,7 +52,6 @@
  */
 
 void smc_set_mac_addr(const char *addr);
-int eth_hw_init(void);
 
 
 /* I want some simple types */
diff --git a/lib_arm/board.c b/lib_arm/board.c
index 314126af5e..193980eff9 100644
--- a/lib_arm/board.c
+++ b/lib_arm/board.c
@@ -54,7 +54,7 @@ const char version_string[] =
 extern void cs8900_get_enetaddr (uchar * addr);
 #endif
 
-#ifdef CONFIG_DRIVER_CS8900
+#ifdef CONFIG_DRIVER_RTL8019
 extern void rtl8019_get_enetaddr (uchar * addr);
 #endif
 
@@ -306,7 +306,6 @@ void start_armboot (void)
 	if (getenv ("ethaddr")) {
 		smc_set_mac_addr(gd->bd->bi_enetaddr);
 	}
-	/* eth_hw_init(); */
 #endif /* CONFIG_DRIVER_LAN91C96 */
 
 	/* Initialize from environment */
-- 
GitLab