diff options
author | John Rigby <john.rigby@linaro.org> | 2011-12-16 15:50:05 -0700 |
---|---|---|
committer | John Rigby <john.rigby@linaro.org> | 2012-08-16 10:08:03 -0600 |
commit | 0470e3db0c6ddfba370b3eb383585cfe8a2d8aad (patch) | |
tree | b2cab3ad708b0dff8f03593f900a4707fe64b672 /arch/arm | |
parent | 03e97daa2e5a2aa681d6e3f007c623e7e86d0551 (diff) |
OMAP4 Panda: Generate a unique usbethaddr
The panda board has a usb nic but the nic has no
rom. Use the die-id to generate a unique address.
This is derived from an RFC kernel patch by Andy Green
that does the same thing:
https://patchwork.kernel.org/patch/660541/
[RFC PATCH 1/2] OMAP2+: add cpu id register to MAC address helper
Signed-off-by: John Rigby <john.rigby@linaro.org>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/cpu/armv7/omap-common/hwinit-common.c | 41 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-omap4/cpu.h | 11 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-omap4/sys_proto.h | 1 |
3 files changed, 53 insertions, 0 deletions
diff --git a/arch/arm/cpu/armv7/omap-common/hwinit-common.c b/arch/arm/cpu/armv7/omap-common/hwinit-common.c index 459ebb55e..f5040b4d6 100644 --- a/arch/arm/cpu/armv7/omap-common/hwinit-common.c +++ b/arch/arm/cpu/armv7/omap-common/hwinit-common.c @@ -28,6 +28,7 @@ * MA 02111-1307 USA */ #include <common.h> +#include <asm/io.h> #include <asm/arch/sys_proto.h> #include <asm/sizes.h> #include <asm/emif.h> @@ -244,6 +245,46 @@ int print_cpuinfo(void) return 0; } + +/* + * this uses the unique per-cpu info from the cpu fuses set at factory to + * generate a 6-byte MAC address. Two bits in the generated code are used + * to elaborate the generated address into four, so it can be used on multiple + * network interfaces. + */ +void omap4_die_id_to_ethernet_mac(u8 *mac, int subtype) +{ + struct ctrl_id *id_base = (struct ctrl_id *)(CTRL_BASE + 0x200); + u32 idcode; + u32 id[4]; + + idcode = readl(&id_base->idcode); + id[0] = readl(&id_base->die_id_0); + id[1] = readl(&id_base->die_id_1); + id[2] = readl(&id_base->die_id_2); + id[3] = readl(&id_base->die_id_3); + + mac[0] = id[2]; + mac[1] = id[2] >> 8; + mac[2] = id[1]; + mac[3] = id[1] >> 8; + mac[4] = id[1] >> 16; + mac[5] = id[1] >> 24; + /* XOR other chip-specific data with ID */ + idcode ^= id[3]; + + mac[0] ^= idcode; + mac[1] ^= idcode >> 8; + mac[2] ^= idcode >> 16; + mac[3] ^= idcode >> 24; + + /* allow four MACs from this same basic data */ + mac[1] = (mac[1] & ~0xc0) | ((subtype & 3) << 6); + + /* mark it as not multicast and outside official 80211 MAC namespace */ + mac[0] = (mac[0] & ~1) | 2; +} + #ifndef CONFIG_SYS_DCACHE_OFF void enable_caches(void) { diff --git a/arch/arm/include/asm/arch-omap4/cpu.h b/arch/arm/include/asm/arch-omap4/cpu.h index a8c4c60c8..9b5c0a802 100644 --- a/arch/arm/include/asm/arch-omap4/cpu.h +++ b/arch/arm/include/asm/arch-omap4/cpu.h @@ -94,6 +94,17 @@ struct gptimer { u32 tcicr; /* 0x40 rw */ u32 tcar2; /* 0x44 r */ }; + +struct ctrl_id { + u32 die_id_0; /* 0x00 */ + u32 idcode; /* 0x04 */ + u32 die_id_1; /* 0x08 */ + u32 die_id_2; /* 0x0c */ + u32 die_id_3; /* 0x10 */ + u32 prod_id_0; /* 0x14 */ + u32 prod_id_1; /* 0x18 */ +}; + #endif /* __ASSEMBLY__ */ #endif /* __KERNEL_STRICT_NAMES */ diff --git a/arch/arm/include/asm/arch-omap4/sys_proto.h b/arch/arm/include/asm/arch-omap4/sys_proto.h index d633573c2..1294ce479 100644 --- a/arch/arm/include/asm/arch-omap4/sys_proto.h +++ b/arch/arm/include/asm/arch-omap4/sys_proto.h @@ -59,6 +59,7 @@ void omap_vc_init(u16 speed_khz); int omap_vc_bypass_send_value(u8 sa, u8 reg_addr, u8 reg_data); u32 warm_reset(void); void force_emif_self_refresh(void); +void omap4_die_id_to_ethernet_mac(u8 *, int); /* * This is used to verify if the configuration header * was executed by Romcode prior to control of transfer |