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 <[email protected]>
---
 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

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to