fsl: simplify the "mac id" command, improve boot-time informational message

The "mac id" command took a 4-character parameter as the identifier string.
However, for any given board, only one kind of identifier is acceptable, so it
makes no sense to ask the user to type it in.  Instead, if the user enters
"mac id", the identifier (and also the version, if it's NXID) will
automatically be set to the correct value.

Improve the message that is displayed when EEPROM is read during boot.  It now
displays "EEPROM:" and then either an error message or the EEPROM identifier
if successful.

If the identifier in EEPROM is valid, then always reject a bad CRC, even if the
CRC field has not been initialized.

Don't force the MAC address count to MAX_NUM_PORTS or less.  Forcing the value
to be changed resulting in an in-memory copy that does not match what's in
hardware, even though the user did not request that change.

Finally, always update the CRC value in the in-memory copy after any field
is changed, so that the CRC is always correct.

Signed-off-by: Timur Tabi <timur@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
diff --git a/board/freescale/common/sys_eeprom.c b/board/freescale/common/sys_eeprom.c
index 3e1e332..c0fff68 100644
--- a/board/freescale/common/sys_eeprom.c
+++ b/board/freescale/common/sys_eeprom.c
@@ -186,12 +186,25 @@
 }
 
 /**
+ *  update_crc - update the CRC
+ *
+ *  This function should be called after each update to the EEPROM structure,
+ *  to make sure the CRC is always correct.
+ */
+static void update_crc(void)
+{
+	u32 crc;
+
+	crc = crc32(0, (void *)&e, sizeof(e) - 4);
+	e.crc = cpu_to_be32(crc);
+}
+
+/**
  * prog_eeprom - write the EEPROM from memory
  */
 static int prog_eeprom(void)
 {
-	int ret, i, length;
-	unsigned int crc;
+	int ret, i;
 	void *p;
 #ifdef CONFIG_SYS_EEPROM_BUS_NUM
 	unsigned int bus;
@@ -204,19 +217,16 @@
 #else
 	memset(e.res_0, 0xFF, sizeof(e.res_0));
 #endif
-
-	length = sizeof(e);
-	crc = crc32(0, (void *)&e, length - 4);
-	e.crc = cpu_to_be32(crc);
+	update_crc();
 
 #ifdef CONFIG_SYS_EEPROM_BUS_NUM
 	bus = i2c_get_bus_num();
 	i2c_set_bus_num(CONFIG_SYS_EEPROM_BUS_NUM);
 #endif
 
-	for (i = 0, p = &e; i < length; i += 8, p += 8) {
+	for (i = 0, p = &e; i < sizeof(e); i += 8, p += 8) {
 		ret = i2c_write(CONFIG_SYS_I2C_EEPROM_ADDR, i, CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
-			p, min((length - i), 8));
+			p, min((sizeof(e) - i), 8));
 		if (ret)
 			break;
 		udelay(5000);	/* 5ms write cycle timing */
@@ -273,6 +283,8 @@
 
 	for (i = 0; i < 6; i++)
 		e.date[i] = h2i(string[2 * i]) << 4 | h2i(string[2 * i + 1]);
+
+	update_crc();
 }
 
 /**
@@ -297,11 +309,12 @@
 		if (*p == ':')
 			p++;
 	}
+
+	update_crc();
 }
 
 int do_mac(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
-	int i;
 	char cmd;
 
 	if (argc == 1) {
@@ -316,9 +329,13 @@
 		return 0;
 	}
 
-	if ((cmd == 'i') && (argc > 2)) {
-		for (i = 0; i < 4; i++)
-			e.id[i] = argv[2][i];
+	if (cmd == 'i') {
+#ifdef CONFIG_SYS_I2C_EEPROM_NXID
+		memcpy(e.id, "NXID", sizeof(e.id));
+		e.version = 0;
+#else
+		memcpy(e.id, "CCID", sizeof(e.id));
+#endif
 		return 0;
 	}
 
@@ -346,6 +363,7 @@
 	case 'n':	/* serial number */
 		memset(e.sn, 0, sizeof(e.sn));
 		strncpy((char *)e.sn, argv[2], sizeof(e.sn) - 1);
+		update_crc();
 		break;
 	case 'e':	/* errata */
 #ifdef CONFIG_SYS_I2C_EEPROM_NXID
@@ -355,12 +373,14 @@
 		e.errata[0] = argv[2][0];
 		e.errata[1] = argv[2][1];
 #endif
+		update_crc();
 		break;
 	case 'd':	/* date BCD format YYMMDDhhmmss */
 		set_date(argv[2]);
 		break;
 	case 'p':	/* MAC table size */
 		e.mac_count = simple_strtoul(argv[2], NULL, 16);
+		update_crc();
 		break;
 	case '0' ... '7':	/* "mac 0" through "mac 7" */
 		set_mac_address(cmd - '0', argv[2]);
@@ -388,6 +408,9 @@
 int mac_read_from_eeprom(void)
 {
 	unsigned int i;
+	u32 crc;
+
+	puts("EEPROM: ");
 
 	if (read_eeprom()) {
 		printf("Read failed.\n");
@@ -395,31 +418,18 @@
 	}
 
 	if (!is_valid) {
-		printf("Invalid ID (%02x %02x %02x %02x)\n", e.id[0], e.id[1], e.id[2], e.id[3]);
+		printf("Invalid ID (%02x %02x %02x %02x)\n",
+		       e.id[0], e.id[1], e.id[2], e.id[3]);
 		return -1;
 	}
 
-	if (be32_to_cpu(e.crc) != 0xFFFFFFFF) {
-		u32 crc = crc32(0, (void *)&e, sizeof(e) - 4);
-
-		if (crc != be32_to_cpu(e.crc)) {
-			printf("CRC mismatch (%08x != %08x).\n", crc,
-				be32_to_cpu(e.crc));
-			return -1;
-		}
+	crc = crc32(0, (void *)&e, sizeof(e) - 4);
+	if (crc != be32_to_cpu(e.crc)) {
+		printf("CRC mismatch (%08x != %08x)\n", crc, be32_to_cpu(e.crc));
+		return -1;
 	}
 
-	/* Check the number of MAC addresses which is limited to
-	 * MAX_NUM_PORTS.
-	 */
-	if (e.mac_count > MAX_NUM_PORTS) {
-		printf("Warning: The number of MAC addresses is greater"
-			" than %u, force it to %u.\n", MAX_NUM_PORTS,
-			MAX_NUM_PORTS);
-		e.mac_count = MAX_NUM_PORTS;
-	}
-
-	for (i = 0; i < e.mac_count; i++) {
+	for (i = 0; i < min(e.mac_count, MAX_NUM_PORTS); i++) {
 		if (memcmp(&e.mac[i], "\0\0\0\0\0\0", 6) &&
 		    memcmp(&e.mac[i], "\xFF\xFF\xFF\xFF\xFF\xFF", 6)) {
 			char ethaddr[18];
@@ -441,6 +451,13 @@
 		}
 	}
 
+#ifdef CONFIG_SYS_I2C_EEPROM_NXID
+	printf("%c%c%c%c v%u\n", e.id[0], e.id[1], e.id[2], e.id[3],
+		be32_to_cpu(e.version));
+#else
+	printf("%c%c%c%c\n", e.id[0], e.id[1], e.id[2], e.id[3]);
+#endif
+
 	return 0;
 }