Module Name:    src
Committed By:   phx
Date:           Tue Dec 25 17:07:07 UTC 2012

Modified Files:
        src/sys/arch/sandpoint/stand/altboot: brdsetup.c rge.c

Log Message:
QNAP V200 boards have no EEPROM for the MAC address, so all devices default
to the same address (00:e0:4c:69:20:01).
Now we read the real MAC address from the flash ROM. It is stored at the
beginning of a 512-byte block in ASCII format. Some QNAP's have a broken
ext2 file system, so we cannot look for the file ETH0.MAC_ADDR therein,
but have to search the whole flash in 512-byte steps for candidates...


To generate a diff of this commit:
cvs rdiff -u -r1.31 -r1.32 src/sys/arch/sandpoint/stand/altboot/brdsetup.c
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/sandpoint/stand/altboot/rge.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/sandpoint/stand/altboot/brdsetup.c
diff -u src/sys/arch/sandpoint/stand/altboot/brdsetup.c:1.31 src/sys/arch/sandpoint/stand/altboot/brdsetup.c:1.32
--- src/sys/arch/sandpoint/stand/altboot/brdsetup.c:1.31	Mon Apr 16 16:55:29 2012
+++ src/sys/arch/sandpoint/stand/altboot/brdsetup.c	Tue Dec 25 17:07:06 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: brdsetup.c,v 1.31 2012/04/16 16:55:29 phx Exp $ */
+/* $NetBSD: brdsetup.c,v 1.32 2012/12/25 17:07:06 phx Exp $ */
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -1254,6 +1254,41 @@ read_mac_string(uint8_t *mac, char *p)
 }
 
 /*
+ * Scan through the Flash memory and look for a string starting at 512 bytes
+ * block boundaries, matching the format: xx:xx:xx:xx:xx:xx<NUL>, where "x"
+ * are hexadecimal digits.
+ * Read the first match as our MAC address.
+ * The start address of the search, p, *must* be dividable by 512!
+ * Return false when no suitable MAC string was found.
+ */
+static int
+find_mac_string(uint8_t *mac, char *p)
+{
+	int i;
+
+	for (;;) {
+		for (i = 0; i < 3 * 6; i += 3) {
+			if (!isxdigit((unsigned)p[i]) ||
+			    !isxdigit((unsigned)p[i + 1]))
+				break;
+			if ((i < 5 && p[i + 2] != ':') ||
+			    (i >= 5 && p[i + 2] != '\0'))
+				break;
+		}
+		if (i >= 6) {
+			/* found a valid MAC address */
+			read_mac_string(mac, p);
+			return 1;
+		}
+		if (p >= (char *)0xfffffe00)
+			break;
+		p += 0x200;
+	}
+	return 0;
+}
+
+
+/*
  * For cost saving reasons some NAS boxes lack SEEPROM for NIC's
  * ethernet address and keep it in their Flash memory instead.
  */
@@ -1272,6 +1307,10 @@ read_mac_from_flash(uint8_t *mac)
 	case BRD_DLINKDSM:
 		read_mac_string(mac, (char *)0xfff0ff80);
 		return;
+	case BRD_QNAPTS:
+		if (find_mac_string(mac, (char *)0xfff00000))
+			return;
+		break;
 	default:
 		printf("Warning: This board has no known method defined "
 		    "to determine its MAC address!\n");

Index: src/sys/arch/sandpoint/stand/altboot/rge.c
diff -u src/sys/arch/sandpoint/stand/altboot/rge.c:1.6 src/sys/arch/sandpoint/stand/altboot/rge.c:1.7
--- src/sys/arch/sandpoint/stand/altboot/rge.c:1.6	Sun Oct 30 21:08:33 2011
+++ src/sys/arch/sandpoint/stand/altboot/rge.c	Tue Dec 25 17:07:06 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: rge.c,v 1.6 2011/10/30 21:08:33 phx Exp $ */
+/* $NetBSD: rge.c,v 1.7 2012/12/25 17:07:06 phx Exp $ */
 
 /*-
  * Copyright (c) 2007 The NetBSD Foundation, Inc.
@@ -102,6 +102,9 @@ struct desc {
 #define	 RCR_AM		(1U << 2)	/* accept multicast frame */
 #define	 RCR_APM	(1U << 1)	/* accept unicast frame */
 #define	 RCR_AAP	(1U << 0)	/* promiscuous */
+#define RGE_EECMD	0x50		/* EEPROM command register */
+#define  EECMD_LOCK	0x00
+#define  EECMD_UNLOCK	0xc0
 #define RGE_PHYAR	0x60		/* PHY access */
 #define RGE_PHYSR	0x6c		/* PHY status */
 #define RGE_RMS		0xda		/* Rx maximum frame size */
@@ -146,7 +149,8 @@ rge_init(unsigned tag, void *data)
 	unsigned val;
 	struct local *l;
 	struct desc *txd, *rxd;
-	uint8_t *en = data;
+	uint32_t reg;
+	uint8_t *en;
 
 	l = ALLOC(struct local, 256);	/* desc alignment */
 	memset(l, 0, sizeof(struct local));
@@ -158,14 +162,27 @@ rge_init(unsigned tag, void *data)
 	} while (val & CR_RESET);
 
 	mii_initphy(l);
-
 	en = data;
-	en[0] = CSR_READ_1(l, RGE_IDR0);
-	en[1] = CSR_READ_1(l, RGE_IDR1);
-	en[2] = CSR_READ_1(l, RGE_IDR2);
-	en[3] = CSR_READ_1(l, RGE_IDR3);
-	en[4] = CSR_READ_1(l, RGE_IDR4);
-	en[5] = CSR_READ_1(l, RGE_IDR5);
+
+	if (brdtype == BRD_QNAPTS) {
+		/* read the MAC from flash and write it into the ID-Regs */
+		read_mac_from_flash(en);
+
+		CSR_WRITE_1(l, RGE_EECMD, EECMD_UNLOCK);
+		reg = en[0] | (en[1] << 8) | (en[2] << 16) | (en[3] << 24);
+		CSR_WRITE_4(l, RGE_IDR0, reg);
+		reg = en[4] | (en[5] << 8);
+		CSR_WRITE_4(l, RGE_IDR4, reg);
+		CSR_WRITE_1(l, RGE_EECMD, EECMD_LOCK);
+	} else {
+		/* pretent the ID-Regs have the correct address */
+		en[0] = CSR_READ_1(l, RGE_IDR0);
+		en[1] = CSR_READ_1(l, RGE_IDR1);
+		en[2] = CSR_READ_1(l, RGE_IDR2);
+		en[3] = CSR_READ_1(l, RGE_IDR3);
+		en[4] = CSR_READ_1(l, RGE_IDR4);
+		en[5] = CSR_READ_1(l, RGE_IDR5);
+	}
 
 	printf("MAC address %02x:%02x:%02x:%02x:%02x:%02x\n",
 	    en[0], en[1], en[2], en[3], en[4], en[5]);

Reply via email to