Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/sandpoint/stand/altboot QNAP V200 boards have no EE...



details:   https://anonhg.NetBSD.org/src/rev/2644bba90481
branches:  trunk
changeset: 783491:2644bba90481
user:      phx <phx%NetBSD.org@localhost>
date:      Tue Dec 25 17:07:06 2012 +0000

description:
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...

diffstat:

 sys/arch/sandpoint/stand/altboot/brdsetup.c |  41 ++++++++++++++++++++++++++++-
 sys/arch/sandpoint/stand/altboot/rge.c      |  35 ++++++++++++++++++------
 2 files changed, 66 insertions(+), 10 deletions(-)

diffs (126 lines):

diff -r 89475691a672 -r 2644bba90481 sys/arch/sandpoint/stand/altboot/brdsetup.c
--- a/sys/arch/sandpoint/stand/altboot/brdsetup.c       Tue Dec 25 17:02:35 2012 +0000
+++ b/sys/arch/sandpoint/stand/altboot/brdsetup.c       Tue Dec 25 17:07:06 2012 +0000
@@ -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 @@
 }
 
 /*
+ * 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 @@
        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");
diff -r 89475691a672 -r 2644bba90481 sys/arch/sandpoint/stand/altboot/rge.c
--- a/sys/arch/sandpoint/stand/altboot/rge.c    Tue Dec 25 17:02:35 2012 +0000
+++ b/sys/arch/sandpoint/stand/altboot/rge.c    Tue Dec 25 17:07:06 2012 +0000
@@ -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 @@
 #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 @@
        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 @@
        } while (val & CR_RESET);
 
        mii_initphy(l);
+       en = data;
 
-       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]);



Home | Main Index | Thread Index | Old Index