From 858ea761172f225faac6ba07a59cb0b9497a6d88 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Sun, 27 Dec 2009 20:59:54 +0000 Subject: ar71xx: fix random wireless mac address on the TEW-632BRP/DIR-615 boards SVN-Revision: 18951 --- target/linux/ar71xx/config-2.6.30 | 1 + target/linux/ar71xx/config-2.6.31 | 1 + target/linux/ar71xx/config-2.6.32 | 1 + target/linux/ar71xx/files/arch/mips/ar71xx/Kconfig | 5 ++ .../linux/ar71xx/files/arch/mips/ar71xx/Makefile | 2 + .../files/arch/mips/ar71xx/mach-dir-615-c1.c | 15 ++++- .../files/arch/mips/ar71xx/mach-tew-632brp.c | 15 ++++- target/linux/ar71xx/files/arch/mips/ar71xx/nvram.c | 75 ++++++++++++++++++++++ target/linux/ar71xx/files/arch/mips/ar71xx/nvram.h | 19 ++++++ 9 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 target/linux/ar71xx/files/arch/mips/ar71xx/nvram.c create mode 100644 target/linux/ar71xx/files/arch/mips/ar71xx/nvram.h (limited to 'target/linux') diff --git a/target/linux/ar71xx/config-2.6.30 b/target/linux/ar71xx/config-2.6.30 index 0f0b541..56c1d2f 100644 --- a/target/linux/ar71xx/config-2.6.30 +++ b/target/linux/ar71xx/config-2.6.30 @@ -34,6 +34,7 @@ CONFIG_AR71XX_MACH_WNR2000=y CONFIG_AR71XX_MACH_WP543=y CONFIG_AR71XX_MACH_WRT160NL=y CONFIG_AR71XX_MACH_WRT400N=y +CONFIG_AR71XX_NVRAM=y CONFIG_AR71XX_WDT=y # CONFIG_ARCH_HAS_ILOG2_U32 is not set # CONFIG_ARCH_HAS_ILOG2_U64 is not set diff --git a/target/linux/ar71xx/config-2.6.31 b/target/linux/ar71xx/config-2.6.31 index 7795cfc..9e4db50 100644 --- a/target/linux/ar71xx/config-2.6.31 +++ b/target/linux/ar71xx/config-2.6.31 @@ -36,6 +36,7 @@ CONFIG_AR71XX_MACH_WNR2000=y CONFIG_AR71XX_MACH_WP543=y CONFIG_AR71XX_MACH_WRT160NL=y CONFIG_AR71XX_MACH_WRT400N=y +CONFIG_AR71XX_NVRAM=y CONFIG_AR71XX_WDT=y # CONFIG_ARCH_HAS_ILOG2_U32 is not set # CONFIG_ARCH_HAS_ILOG2_U64 is not set diff --git a/target/linux/ar71xx/config-2.6.32 b/target/linux/ar71xx/config-2.6.32 index 6b483b3..2de9983 100644 --- a/target/linux/ar71xx/config-2.6.32 +++ b/target/linux/ar71xx/config-2.6.32 @@ -36,6 +36,7 @@ CONFIG_AR71XX_MACH_WNR2000=y CONFIG_AR71XX_MACH_WP543=y CONFIG_AR71XX_MACH_WRT160NL=y CONFIG_AR71XX_MACH_WRT400N=y +CONFIG_AR71XX_NVRAM=y CONFIG_AR71XX_WDT=y # CONFIG_ARCH_HAS_ILOG2_U32 is not set # CONFIG_ARCH_HAS_ILOG2_U64 is not set diff --git a/target/linux/ar71xx/files/arch/mips/ar71xx/Kconfig b/target/linux/ar71xx/files/arch/mips/ar71xx/Kconfig index e2aaa66..48fca77 100644 --- a/target/linux/ar71xx/files/arch/mips/ar71xx/Kconfig +++ b/target/linux/ar71xx/files/arch/mips/ar71xx/Kconfig @@ -25,6 +25,7 @@ config AR71XX_MACH_DIR_615_C1 select AR71XX_DEV_AR913X_WMAC select AR71XX_DEV_GPIO_BUTTONS select AR71XX_DEV_LEDS_GPIO + select AR71XX_NVRAM default n config AR71XX_MACH_DIR_825_B1 @@ -171,6 +172,7 @@ config AR71XX_MACH_TEW_632BRP select AR71XX_DEV_AR913X_WMAC select AR71XX_DEV_GPIO_BUTTONS select AR71XX_DEV_LEDS_GPIO + select AR71XX_NVRAM default n config AR71XX_MACH_UBNT @@ -212,4 +214,7 @@ config AR71XX_DEV_PB42_PCI config AR71XX_DEV_USB def_bool n +config AR71XX_NVRAM + def_bool n + endif diff --git a/target/linux/ar71xx/files/arch/mips/ar71xx/Makefile b/target/linux/ar71xx/files/arch/mips/ar71xx/Makefile index db118fb..3a632f7 100644 --- a/target/linux/ar71xx/files/arch/mips/ar71xx/Makefile +++ b/target/linux/ar71xx/files/arch/mips/ar71xx/Makefile @@ -23,6 +23,8 @@ obj-$(CONFIG_AR71XX_DEV_M25P80) += dev-m25p80.o obj-$(CONFIG_AR71XX_DEV_PB42_PCI) += dev-pb42-pci.o obj-$(CONFIG_AR71XX_DEV_USB) += dev-usb.o +obj-$(CONFIG_AR71XX_NVRAM) += nvram.o + obj-$(CONFIG_AR71XX_MACH_AP81) += mach-ap81.o obj-$(CONFIG_AR71XX_MACH_AP83) += mach-ap83.o obj-$(CONFIG_AR71XX_MACH_AW_NR580) += mach-aw-nr580.o diff --git a/target/linux/ar71xx/files/arch/mips/ar71xx/mach-dir-615-c1.c b/target/linux/ar71xx/files/arch/mips/ar71xx/mach-dir-615-c1.c index b5dde36..e3b6aab 100644 --- a/target/linux/ar71xx/files/arch/mips/ar71xx/mach-dir-615-c1.c +++ b/target/linux/ar71xx/files/arch/mips/ar71xx/mach-dir-615-c1.c @@ -20,6 +20,7 @@ #include "dev-ar913x-wmac.h" #include "dev-gpio-buttons.h" #include "dev-leds-gpio.h" +#include "nvram.h" #define DIR_615C1_GPIO_LED_ORANGE_STATUS 1 /* ORANGE:STATUS:TRICOLOR */ #define DIR_615C1_GPIO_LED_BLUE_WPS 3 /* BLUE:WPS */ @@ -36,6 +37,9 @@ #define DIR_615C1_BUTTONS_POLL_INTERVAL 20 +#define DIR_615C1_CONFIG_ADDR 0x1f020000 +#define DIR_615C1_CONFIG_SIZE 0x10000 + #ifdef CONFIG_MTD_PARTITIONS static struct mtd_partition dir_615c1_partitions[] = { { @@ -126,7 +130,16 @@ static struct gpio_button dir_615c1_gpio_buttons[] __initdata = { static void __init dir_615c1_setup(void) { + const char *config = (char *) KSEG1ADDR(DIR_615C1_CONFIG_ADDR); u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); + u8 mac[6]; + u8 *wlan_mac = NULL; + + if (nvram_parse_mac_addr(config, DIR_615C1_CONFIG_SIZE, + "lan_mac=", mac) == 0) { + ar71xx_set_mac_base(mac); + wlan_mac = mac; + } ar71xx_add_device_mdio(0x0); @@ -150,7 +163,7 @@ static void __init dir_615c1_setup(void) ARRAY_SIZE(dir_615c1_gpio_buttons), dir_615c1_gpio_buttons); - ar913x_add_device_wmac(eeprom, NULL); + ar913x_add_device_wmac(eeprom, wlan_mac); } MIPS_MACHINE(AR71XX_MACH_DIR_615_C1, "D-Link DIR-615 rev. C1", dir_615c1_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ar71xx/mach-tew-632brp.c b/target/linux/ar71xx/files/arch/mips/ar71xx/mach-tew-632brp.c index cb2e16d..bb4cee6 100644 --- a/target/linux/ar71xx/files/arch/mips/ar71xx/mach-tew-632brp.c +++ b/target/linux/ar71xx/files/arch/mips/ar71xx/mach-tew-632brp.c @@ -20,6 +20,7 @@ #include "dev-ar913x-wmac.h" #include "dev-gpio-buttons.h" #include "dev-leds-gpio.h" +#include "nvram.h" #define TEW_632BRP_GPIO_LED_STATUS 1 #define TEW_632BRP_GPIO_LED_WPS 3 @@ -29,6 +30,9 @@ #define TEW_632BRP_BUTTONS_POLL_INTERVAL 20 +#define TEW_632BRP_CONFIG_ADDR 0x1f020000 +#define TEW_632BRP_CONFIG_SIZE 0x10000 + #ifdef CONFIG_MTD_PARTITIONS static struct mtd_partition tew_632brp_partitions[] = { { @@ -102,7 +106,16 @@ static struct gpio_button tew_632brp_gpio_buttons[] __initdata = { static void __init tew_632brp_setup(void) { + const char *config = (char *) KSEG1ADDR(TEW_632BRP_CONFIG_ADDR); u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); + u8 mac[6]; + u8 *wlan_mac = NULL; + + if (nvram_parse_mac_addr(config, TEW_632BRP_CONFIG_SIZE, + "lan_mac=", mac) == 0) { + ar71xx_set_mac_base(mac); + wlan_mac = mac; + } ar71xx_add_device_mdio(0x0); @@ -126,7 +139,7 @@ static void __init tew_632brp_setup(void) ARRAY_SIZE(tew_632brp_gpio_buttons), tew_632brp_gpio_buttons); - ar913x_add_device_wmac(eeprom, NULL); + ar913x_add_device_wmac(eeprom, wlan_mac); } MIPS_MACHINE(AR71XX_MACH_TEW_632BRP, "TRENDnet TEW-632BRP", tew_632brp_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ar71xx/nvram.c b/target/linux/ar71xx/files/arch/mips/ar71xx/nvram.c new file mode 100644 index 0000000..e6d1f80 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ar71xx/nvram.c @@ -0,0 +1,75 @@ +/* + * Atheros AR71xx minimal nvram support + * + * Copyright (C) 2009 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include + +#include "nvram.h" + +char *nvram_find_var(const char *name, const char *buf, unsigned buf_len) +{ + unsigned len = strlen(name); + char *cur, *last; + + if (buf_len == 0 || len == 0) + return NULL; + + if (buf_len < len) + return NULL; + + if (len == 1) + return memchr(buf, (int) *name, buf_len); + + last = (char *) buf + buf_len - len; + for (cur = (char *) buf; cur <= last; cur++) + if (cur[0] == name[0] && memcmp(cur, name, len) == 0) + return cur + len; + + return NULL; +} + +int nvram_parse_mac_addr(const char *nvram, unsigned nvram_len, + const char *name, char *mac) +{ + char *buf; + char *mac_str; + int ret; + int t; + + buf = vmalloc(nvram_len); + if (!buf) + return -ENOMEM; + + memcpy(buf, nvram, nvram_len); + buf[nvram_len - 1] = '\0'; + + mac_str = nvram_find_var(name, buf, nvram_len); + if (!mac_str) { + ret = -EINVAL; + goto free; + } + + t = sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", + &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]); + + if (t != 6) { + ret = -EINVAL; + goto free; + } + + ret = 0; + + free: + vfree(buf); + return ret; +} diff --git a/target/linux/ar71xx/files/arch/mips/ar71xx/nvram.h b/target/linux/ar71xx/files/arch/mips/ar71xx/nvram.h new file mode 100644 index 0000000..b025d3f --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ar71xx/nvram.h @@ -0,0 +1,19 @@ +/* + * Atheros AR71xx minimal nvram support + * + * Copyright (C) 2009 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#ifndef _AR71XX_NVRAM_H +#define _AR71XX_NVRAM_H + +char *nvram_find_var(const char *name, const char *buf, + unsigned buf_len) __init; +int nvram_parse_mac_addr(const char *nvram, unsigned nvram_len, + const char *name, char *mac) __init; + +#endif /* _AR71XX_NVRAM_H */ -- cgit v1.1