[U-Boot] [PATCH 06/11] arm: sunxi: Use read_rom_hwaddr() to obtain MAC address
Olliver Schinagl
oliver at schinagl.nl
Tue Nov 8 16:54:32 CET 2016
With the newly introduced hooks, we can now set the MAC address at the
lowest level properly. The user is still free to override it via a
u-boot environment variable.
Signed-off-by: Olliver Schinagl <oliver at schinagl.nl>
---
arch/arm/include/asm/arch-sunxi/sys_proto.h | 8 +++
board/sunxi/board.c | 103 +++++++++++++++++++---------
2 files changed, 80 insertions(+), 31 deletions(-)
diff --git a/arch/arm/include/asm/arch-sunxi/sys_proto.h b/arch/arm/include/asm/arch-sunxi/sys_proto.h
index a373319..5b24b86 100644
--- a/arch/arm/include/asm/arch-sunxi/sys_proto.h
+++ b/arch/arm/include/asm/arch-sunxi/sys_proto.h
@@ -30,4 +30,12 @@ void eth_init_board(void);
static inline void eth_init_board(void) {}
#endif
+#if CONFIG_SUNXI_EMAC
+int sunxi_board_read_rom_hwaddr(unsigned char *enetaddr);
+#endif
+
+#if defined(CONFIG_SUNXI_GMAC) || defined(CONFIG_ETH_DESIGNWARE)
+int dw_board_read_rom_hwaddr(unsigned char *enetaddr);
+#endif
+
#endif
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index 5365638..9b56a89 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -21,6 +21,7 @@
#include <asm/arch/gpio.h>
#include <asm/arch/mmc.h>
#include <asm/arch/spl.h>
+#include <asm/arch/sys_proto.h>
#include <asm/arch/usb_phy.h>
#ifndef CONFIG_ARM64
#include <asm/armv7.h>
@@ -584,6 +585,76 @@ void get_board_serial(struct tag_serialnr *serialnr)
}
#endif
+static void _sunxi_gen_sid_hwaddr(unsigned char *enetaddr, uint8_t cnt)
+{
+ uint8_t mac_addr[ARP_HLEN] = { 0x00 };
+ unsigned int sid[4];
+ int ret;
+
+ ret = sunxi_get_sid(sid);
+ if (ret == 0 && sid[0] != 0) {
+ /*
+ * The single words 1 - 3 of the SID have quite a few bits
+ * which are the same on many models, so we take a crc32
+ * of all 3 words, to get a more unique value.
+ *
+ * Note we only do this on newer SoCs as we cannot change
+ * the algorithm on older SoCs since those have been using
+ * fixed mac-addresses based on only using word 3 for a
+ * long time and changing a fixed mac-address with an
+ * u-boot update is not good.
+ */
+#if !defined(CONFIG_MACH_SUN4I) && !defined(CONFIG_MACH_SUN5I) && \
+ !defined(CONFIG_MACH_SUN6I) && !defined(CONFIG_MACH_SUN7I) && \
+ !defined(CONFIG_MACH_SUN8I_A23) && !defined(CONFIG_MACH_SUN8I_A33)
+ sid[3] = crc32(0, (unsigned char *)&sid[1], 12);
+#endif
+
+ /* Ensure the NIC specific bytes of the mac are not all 0 */
+ if ((sid[3] & 0xffffff) == 0)
+ sid[3] |= 0x800000;
+
+ /* Non OUI / registered MAC address */
+ mac_addr[0] = (cnt << 4) | 0x02;
+ mac_addr[1] = (sid[0] >> 0) & 0xff;
+ mac_addr[2] = (sid[3] >> 24) & 0xff;
+ mac_addr[3] = (sid[3] >> 16) & 0xff;
+ mac_addr[4] = (sid[3] >> 8) & 0xff;
+ mac_addr[5] = (sid[3] >> 0) & 0xff;
+ }
+
+ memcpy(enetaddr, mac_addr, ARP_HLEN);
+}
+
+static int sunxi_read_rom_hwaddr(unsigned char *enetaddr)
+{
+ static unsigned int cnt;
+
+ _sunxi_gen_sid_hwaddr(enetaddr, cnt);
+
+ /* First call, first stored MAC address, increase for next call */
+ cnt++;
+
+ if (is_zero_ethaddr(enetaddr))
+ return -ENOSYS;
+
+ printf("MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n",
+ enetaddr[0], enetaddr[1], enetaddr[2],
+ enetaddr[3], enetaddr[4], enetaddr[5]);
+
+ return 0;
+}
+
+int sunxi_board_read_rom_hwaddr(unsigned char *enetaddr)
+{
+ return sunxi_read_rom_hwaddr(enetaddr);
+}
+
+int dw_board_read_rom_hwaddr(unsigned char *enetaddr)
+{
+ return sunxi_read_rom_hwaddr(enetaddr);
+}
+
/*
* Check the SPL header for the "sunxi" variant. If found: parse values
* that might have been passed by the loader ("fel" utility), and update
@@ -625,9 +696,7 @@ static void setup_environment(const void *fdt)
{
char serial_string[17] = { 0 };
unsigned int sid[4];
- uint8_t mac_addr[6];
- char ethaddr[16];
- int i, ret;
+ int ret;
ret = sunxi_get_sid(sid);
if (ret == 0 && sid[0] != 0) {
@@ -648,34 +717,6 @@ static void setup_environment(const void *fdt)
sid[3] = crc32(0, (unsigned char *)&sid[1], 12);
#endif
- /* Ensure the NIC specific bytes of the mac are not all 0 */
- if ((sid[3] & 0xffffff) == 0)
- sid[3] |= 0x800000;
-
- for (i = 0; i < 4; i++) {
- sprintf(ethaddr, "ethernet%d", i);
- if (!fdt_get_alias(fdt, ethaddr))
- continue;
-
- if (i == 0)
- strcpy(ethaddr, "ethaddr");
- else
- sprintf(ethaddr, "eth%daddr", i);
-
- if (getenv(ethaddr))
- continue;
-
- /* Non OUI / registered MAC address */
- mac_addr[0] = (i << 4) | 0x02;
- mac_addr[1] = (sid[0] >> 0) & 0xff;
- mac_addr[2] = (sid[3] >> 24) & 0xff;
- mac_addr[3] = (sid[3] >> 16) & 0xff;
- mac_addr[4] = (sid[3] >> 8) & 0xff;
- mac_addr[5] = (sid[3] >> 0) & 0xff;
-
- eth_setenv_enetaddr(ethaddr, mac_addr);
- }
-
if (!getenv("serial#")) {
snprintf(serial_string, sizeof(serial_string),
"%08x%08x", sid[0], sid[3]);
--
2.10.2
More information about the U-Boot
mailing list