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]);