[U-Boot] [PATCH v2 1/3] rockchip: rk3399: derive ethaddr from cpuid

Generate a MAC address based on the cpuid available in the efuse block: Use the first 6 byte of the cpuid's SHA256 hash and set the locally administered bits. Also ensure that the multicast bit is cleared.
The MAC address is only generated and set if there is no ethaddr present in the saved environment.
This is based off of Klaus Goger's work in 8adc9d
Signed-off-by: Rohan Garg rohan.garg@collabora.com
---
arch/arm/include/asm/arch-rockchip/misc.h | 13 +++ arch/arm/mach-rockchip/Makefile | 2 + arch/arm/mach-rockchip/misc.c | 108 ++++++++++++++++++++++ board/rockchip/evb_rk3399/evb-rk3399.c | 13 +++ 4 files changed, 136 insertions(+) create mode 100644 arch/arm/include/asm/arch-rockchip/misc.h create mode 100644 arch/arm/mach-rockchip/misc.c
diff --git a/arch/arm/include/asm/arch-rockchip/misc.h b/arch/arm/include/asm/arch-rockchip/misc.h new file mode 100644 index 0000000000..11ca4eb033 --- /dev/null +++ b/arch/arm/include/asm/arch-rockchip/misc.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * RK3399: Architecture common definitions + * + * Copyright (C) 2019 Collabora Inc - https://www.collabora.com/ + * Rohan Garg rohan.garg@collabora.com + */ + +void rockchip_cpuid_from_efuse(const u32 cpuid_offset, + const u32 cpuid_length, + u8 *cpuid); +void rockchip_cpuid_set(const u8 *cpuid, const u32 cpuid_length); +void rockchip_setup_macaddr(void); diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile index 23760a959a..43d895564f 100644 --- a/arch/arm/mach-rockchip/Makefile +++ b/arch/arm/mach-rockchip/Makefile @@ -47,6 +47,8 @@ obj-y += rk_timer.o endif endif
+obj-y += misc.o + obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036/ obj-$(CONFIG_ROCKCHIP_RK3128) += rk3128/ ifndef CONFIG_TPL_BUILD diff --git a/arch/arm/mach-rockchip/misc.c b/arch/arm/mach-rockchip/misc.c new file mode 100644 index 0000000000..3e6110cc8b --- /dev/null +++ b/arch/arm/mach-rockchip/misc.c @@ -0,0 +1,108 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * RK3399: Architecture common definitions + * + * Copyright (C) 2019 Collabora Inc - https://www.collabora.com/ + * Rohan Garg rohan.garg@collabora.com + * + * Based on puma-rk3399.c: + * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH + */ + +#include <common.h> +#include <u-boot/sha256.h> +#include <dm/uclass-internal.h> +#include <environment.h> + +#include <asm/arch-rockchip/misc.h> + +void rockchip_setup_macaddr(void) +{ +#if CONFIG_IS_ENABLED(CMD_NET) + int ret; + const char *cpuid = env_get("cpuid#"); + u8 hash[SHA256_SUM_LEN]; + int size = sizeof(hash); + u8 mac_addr[6]; + + /* Only generate a MAC address, if none is set in the environment */ + if (env_get("ethaddr")) + return; + + if (!cpuid) { + debug("%s: could not retrieve 'cpuid#'\n", __func__); + return; + } + + ret = hash_block("sha256", (void *)cpuid, strlen(cpuid), hash, &size); + if (ret) { + debug("%s: failed to calculate SHA256\n", __func__); + return; + } + + /* Copy 6 bytes of the hash to base the MAC address on */ + memcpy(mac_addr, hash, 6); + + /* Make this a valid MAC address and set it */ + mac_addr[0] &= 0xfe; /* clear multicast bit */ + mac_addr[0] |= 0x02; /* set local assignment bit (IEEE802) */ + eth_env_set_enetaddr("ethaddr", mac_addr); +#endif +} + +void rockchip_cpuid_from_efuse(const u32 cpuid_offset, + const u32 cpuid_length, + u8 *cpuid) +{ +#if CONFIG_IS_ENABLED(ROCKCHIP_EFUSE) + struct udevice *dev; + int ret; + + /* retrieve the device */ + ret = uclass_get_device_by_driver(UCLASS_MISC, + DM_GET_DRIVER(rockchip_efuse), &dev); + if (ret) { + debug("%s: could not find efuse device\n", __func__); + return; + } + + /* read the cpu_id range from the efuses */ + ret = misc_read(dev, cpuid_offset, cpuid, sizeof(cpuid)); + if (ret) { + debug("%s: reading cpuid from the efuses failed\n", + __func__); + return; + } +#endif +} + +void rockchip_cpuid_set(const u8 *cpuid, const u32 cpuid_length) +{ + u8 low[cpuid_length/2], high[cpuid_length/2]; + char cpuid_str[cpuid_length * 2 + 1]; + u64 serialno; + char serialno_str[17]; + int i; + + memset(cpuid_str, 0, sizeof(cpuid_str)); + for (i = 0; i < 16; i++) + sprintf(&cpuid_str[i * 2], "%02x", cpuid[i]); + + debug("cpuid: %s\n", cpuid_str); + + /* + * Mix the cpuid bytes using the same rules as in + * ${linux}/drivers/soc/rockchip/rockchip-cpuinfo.c + */ + for (i = 0; i < 8; i++) { + low[i] = cpuid[1 + (i << 1)]; + high[i] = cpuid[i << 1]; + } + + serialno = crc32_no_comp(0, low, 8); + serialno |= (u64)crc32_no_comp(serialno, high, 8) << 32; + snprintf(serialno_str, sizeof(serialno_str), "%016llx", serialno); + + env_set("cpuid#", cpuid_str); + env_set("serial#", serialno_str); +} diff --git a/board/rockchip/evb_rk3399/evb-rk3399.c b/board/rockchip/evb_rk3399/evb-rk3399.c index eb1b832274..9253866c02 100644 --- a/board/rockchip/evb_rk3399/evb-rk3399.c +++ b/board/rockchip/evb_rk3399/evb-rk3399.c @@ -7,6 +7,7 @@ #include <dm.h> #include <dm/pinctrl.h> #include <asm/arch-rockchip/periph.h> +#include <asm/arch-rockchip/misc.h> #include <power/regulator.h>
int board_init(void) @@ -33,3 +34,15 @@ int board_init(void) out: return 0; } + +int misc_init_r(void) +{ + const u32 cpuid_offset = 0x7; + const u32 cpuid_length = 0x10; + u8 cpuid[cpuid_length]; + + rockchip_cpuid_from_efuse(cpuid_offset, cpuid_length, cpuid); + rockchip_cpuid_set(cpuid, cpuid_length); + rockchip_setup_macaddr(); + return 0; +}

This enables us to set a static MAC address
Signed-off-by: Rohan Garg rohan.garg@collabora.com ---
configs/rock-pi-4-rk3399_defconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/configs/rock-pi-4-rk3399_defconfig b/configs/rock-pi-4-rk3399_defconfig index be670df23f..dc84ded86c 100644 --- a/configs/rock-pi-4-rk3399_defconfig +++ b/configs/rock-pi-4-rk3399_defconfig @@ -58,3 +58,4 @@ CONFIG_USB_ETHER_SMSC95XX=y CONFIG_USE_TINY_PRINTF=y CONFIG_SPL_TINY_MEMSET=y CONFIG_ERRNO_STR=y +CONFIG_MISC_INIT_R=y

We should use the shared helpers to setup the necessary parts
Signed-off-by: Rohan Garg rohan.garg@collabora.com ---
.../puma_rk3399/puma-rk3399.c | 98 ++----------------- 1 file changed, 8 insertions(+), 90 deletions(-)
diff --git a/board/theobroma-systems/puma_rk3399/puma-rk3399.c b/board/theobroma-systems/puma_rk3399/puma-rk3399.c index 251cd2d566..af94ed998a 100644 --- a/board/theobroma-systems/puma_rk3399/puma-rk3399.c +++ b/board/theobroma-systems/puma_rk3399/puma-rk3399.c @@ -17,6 +17,7 @@ #include <asm/arch-rockchip/clock.h> #include <asm/arch-rockchip/hardware.h> #include <asm/arch-rockchip/grf_rk3399.h> +#include <asm/arch-rockchip/misc.h> #include <asm/arch-rockchip/periph.h> #include <power/regulator.h> #include <u-boot/sha256.h> @@ -36,94 +37,6 @@ int board_init(void) return 0; }
-static void setup_macaddr(void) -{ -#if CONFIG_IS_ENABLED(CMD_NET) - int ret; - const char *cpuid = env_get("cpuid#"); - u8 hash[SHA256_SUM_LEN]; - int size = sizeof(hash); - u8 mac_addr[6]; - - /* Only generate a MAC address, if none is set in the environment */ - if (env_get("ethaddr")) - return; - - if (!cpuid) { - debug("%s: could not retrieve 'cpuid#'\n", __func__); - return; - } - - ret = hash_block("sha256", (void *)cpuid, strlen(cpuid), hash, &size); - if (ret) { - debug("%s: failed to calculate SHA256\n", __func__); - return; - } - - /* Copy 6 bytes of the hash to base the MAC address on */ - memcpy(mac_addr, hash, 6); - - /* Make this a valid MAC address and set it */ - mac_addr[0] &= 0xfe; /* clear multicast bit */ - mac_addr[0] |= 0x02; /* set local assignment bit (IEEE802) */ - eth_env_set_enetaddr("ethaddr", mac_addr); -#endif -} - -static void setup_serial(void) -{ -#if CONFIG_IS_ENABLED(ROCKCHIP_EFUSE) - const u32 cpuid_offset = 0x7; - const u32 cpuid_length = 0x10; - - struct udevice *dev; - int ret, i; - u8 cpuid[cpuid_length]; - u8 low[cpuid_length/2], high[cpuid_length/2]; - char cpuid_str[cpuid_length * 2 + 1]; - u64 serialno; - char serialno_str[17]; - - /* retrieve the device */ - ret = uclass_get_device_by_driver(UCLASS_MISC, - DM_GET_DRIVER(rockchip_efuse), &dev); - if (ret) { - debug("%s: could not find efuse device\n", __func__); - return; - } - - /* read the cpu_id range from the efuses */ - ret = misc_read(dev, cpuid_offset, &cpuid, sizeof(cpuid)); - if (ret) { - debug("%s: reading cpuid from the efuses failed\n", - __func__); - return; - } - - memset(cpuid_str, 0, sizeof(cpuid_str)); - for (i = 0; i < 16; i++) - sprintf(&cpuid_str[i * 2], "%02x", cpuid[i]); - - debug("cpuid: %s\n", cpuid_str); - - /* - * Mix the cpuid bytes using the same rules as in - * ${linux}/drivers/soc/rockchip/rockchip-cpuinfo.c - */ - for (i = 0; i < 8; i++) { - low[i] = cpuid[1 + (i << 1)]; - high[i] = cpuid[i << 1]; - } - - serialno = crc32_no_comp(0, low, 8); - serialno |= (u64)crc32_no_comp(serialno, high, 8) << 32; - snprintf(serialno_str, sizeof(serialno_str), "%016llx", serialno); - - env_set("cpuid#", cpuid_str); - env_set("serial#", serialno_str); -#endif -} - static void setup_iodomain(void) { const u32 GRF_IO_VSEL_GPIO4CD_SHIFT = 3; @@ -213,8 +126,13 @@ static int setup_boottargets(void)
int misc_init_r(void) { - setup_serial(); - setup_macaddr(); + const u32 cpuid_offset = 0x7; + const u32 cpuid_length = 0x10; + u8 cpuid[cpuid_length]; + + rockchip_cpuid_from_efuse(cpuid_offset, cpuid_length, cpuid); + rockchip_cpuid_set(cpuid, cpuid_length); + rockchip_setup_macaddr(); setup_iodomain(); setup_boottargets();

Hi Rohan,
On 2019/7/12 下午10:22, Rohan Garg wrote:
Generate a MAC address based on the cpuid available in the efuse block: Use the first 6 byte of the cpuid's SHA256 hash and set the locally administered bits. Also ensure that the multicast bit is cleared.
The MAC address is only generated and set if there is no ethaddr present in the saved environment.
This is based off of Klaus Goger's work in 8adc9d
Signed-off-by: Rohan Garg rohan.garg@collabora.com
arch/arm/include/asm/arch-rockchip/misc.h | 13 +++ arch/arm/mach-rockchip/Makefile | 2 + arch/arm/mach-rockchip/misc.c | 108 ++++++++++++++++++++++ board/rockchip/evb_rk3399/evb-rk3399.c | 13 +++ 4 files changed, 136 insertions(+) create mode 100644 arch/arm/include/asm/arch-rockchip/misc.h create mode 100644 arch/arm/mach-rockchip/misc.c
diff --git a/arch/arm/include/asm/arch-rockchip/misc.h b/arch/arm/include/asm/arch-rockchip/misc.h new file mode 100644 index 0000000000..11ca4eb033 --- /dev/null +++ b/arch/arm/include/asm/arch-rockchip/misc.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/*
- RK3399: Architecture common definitions
- Copyright (C) 2019 Collabora Inc - https://www.collabora.com/
Rohan Garg <rohan.garg@collabora.com>
- */
+void rockchip_cpuid_from_efuse(const u32 cpuid_offset,
const u32 cpuid_length,
u8 *cpuid);
+void rockchip_cpuid_set(const u8 *cpuid, const u32 cpuid_length); +void rockchip_setup_macaddr(void); diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile index 23760a959a..43d895564f 100644 --- a/arch/arm/mach-rockchip/Makefile +++ b/arch/arm/mach-rockchip/Makefile @@ -47,6 +47,8 @@ obj-y += rk_timer.o endif endif
+obj-y += misc.o
This should be depends on CONFIG_MISC_INIT_R.
- obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036/ obj-$(CONFIG_ROCKCHIP_RK3128) += rk3128/ ifndef CONFIG_TPL_BUILD
diff --git a/arch/arm/mach-rockchip/misc.c b/arch/arm/mach-rockchip/misc.c new file mode 100644 index 0000000000..3e6110cc8b --- /dev/null +++ b/arch/arm/mach-rockchip/misc.c @@ -0,0 +1,108 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/*
- RK3399: Architecture common definitions
- Copyright (C) 2019 Collabora Inc - https://www.collabora.com/
Rohan Garg <rohan.garg@collabora.com>
- Based on puma-rk3399.c:
(C) Copyright 2017 Theobroma Systems Design und Consulting GmbH
- */
+#include <common.h> +#include <u-boot/sha256.h> +#include <dm/uclass-internal.h> +#include <environment.h>
+#include <asm/arch-rockchip/misc.h>
+void rockchip_setup_macaddr(void) +{ +#if CONFIG_IS_ENABLED(CMD_NET)
- int ret;
- const char *cpuid = env_get("cpuid#");
- u8 hash[SHA256_SUM_LEN];
- int size = sizeof(hash);
- u8 mac_addr[6];
- /* Only generate a MAC address, if none is set in the environment */
- if (env_get("ethaddr"))
return;
- if (!cpuid) {
debug("%s: could not retrieve 'cpuid#'\n", __func__);
return;
- }
- ret = hash_block("sha256", (void *)cpuid, strlen(cpuid), hash, &size);
- if (ret) {
debug("%s: failed to calculate SHA256\n", __func__);
return;
- }
- /* Copy 6 bytes of the hash to base the MAC address on */
- memcpy(mac_addr, hash, 6);
- /* Make this a valid MAC address and set it */
- mac_addr[0] &= 0xfe; /* clear multicast bit */
- mac_addr[0] |= 0x02; /* set local assignment bit (IEEE802) */
- eth_env_set_enetaddr("ethaddr", mac_addr);
+#endif +}
+void rockchip_cpuid_from_efuse(const u32 cpuid_offset,
const u32 cpuid_length,
u8 *cpuid)
+{ +#if CONFIG_IS_ENABLED(ROCKCHIP_EFUSE)
- struct udevice *dev;
- int ret;
- /* retrieve the device */
- ret = uclass_get_device_by_driver(UCLASS_MISC,
DM_GET_DRIVER(rockchip_efuse), &dev);
- if (ret) {
debug("%s: could not find efuse device\n", __func__);
return;
- }
- /* read the cpu_id range from the efuses */
- ret = misc_read(dev, cpuid_offset, cpuid, sizeof(cpuid));
- if (ret) {
debug("%s: reading cpuid from the efuses failed\n",
__func__);
return;
- }
+#endif +}
+void rockchip_cpuid_set(const u8 *cpuid, const u32 cpuid_length) +{
- u8 low[cpuid_length/2], high[cpuid_length/2];
- char cpuid_str[cpuid_length * 2 + 1];
- u64 serialno;
- char serialno_str[17];
- int i;
- memset(cpuid_str, 0, sizeof(cpuid_str));
- for (i = 0; i < 16; i++)
sprintf(&cpuid_str[i * 2], "%02x", cpuid[i]);
- debug("cpuid: %s\n", cpuid_str);
- /*
* Mix the cpuid bytes using the same rules as in
* ${linux}/drivers/soc/rockchip/rockchip-cpuinfo.c
*/
- for (i = 0; i < 8; i++) {
low[i] = cpuid[1 + (i << 1)];
high[i] = cpuid[i << 1];
- }
- serialno = crc32_no_comp(0, low, 8);
- serialno |= (u64)crc32_no_comp(serialno, high, 8) << 32;
- snprintf(serialno_str, sizeof(serialno_str), "%016llx", serialno);
- env_set("cpuid#", cpuid_str);
- env_set("serial#", serialno_str);
+} diff --git a/board/rockchip/evb_rk3399/evb-rk3399.c b/board/rockchip/evb_rk3399/evb-rk3399.c index eb1b832274..9253866c02 100644 --- a/board/rockchip/evb_rk3399/evb-rk3399.c +++ b/board/rockchip/evb_rk3399/evb-rk3399.c @@ -7,6 +7,7 @@ #include <dm.h> #include <dm/pinctrl.h> #include <asm/arch-rockchip/periph.h> +#include <asm/arch-rockchip/misc.h> #include <power/regulator.h>
int board_init(void) @@ -33,3 +34,15 @@ int board_init(void) out: return 0; }
+int misc_init_r(void) +{
It's great to make these code as common code so that other SoCs
can share it, is it possible to also make this function common?
Not every SoC have efuse driver, so for those SoCs, we need a random
serial No.
- const u32 cpuid_offset = 0x7;
- const u32 cpuid_length = 0x10;
- u8 cpuid[cpuid_length];
- rockchip_cpuid_from_efuse(cpuid_offset, cpuid_length, cpuid);
- rockchip_cpuid_set(cpuid, cpuid_length);
- rockchip_setup_macaddr();
It will be better for these function calls with return value.
There should be a blank line before 'return';
Thanks,
- Kever
- return 0;
+}

Hey Kever
This should be depends on CONFIG_MISC_INIT_R.
Ack.
It's great to make these code as common code so that other SoCs
can share it, is it possible to also make this function common?
Not every SoC have efuse driver, so for those SoCs, we need a random
serial No.
Do you think we can merge this as is for now and then move onto making it more generic for other devices at a later date?
- const u32 cpuid_offset = 0x7;
- const u32 cpuid_length = 0x10;
- u8 cpuid[cpuid_length];
- rockchip_cpuid_from_efuse(cpuid_offset, cpuid_length, cpuid);
- rockchip_cpuid_set(cpuid, cpuid_length);
- rockchip_setup_macaddr();
It will be better for these function calls with return value.
There should be a blank line before 'return';
Ack.
Cheers Rohan Garg

HI Rohan,
On 2019/7/19 下午10:56, Rohan Garg wrote:
Hey Kever
This should be depends on CONFIG_MISC_INIT_R.
Ack.
It's great to make these code as common code so that other SoCs
can share it, is it possible to also make this function common?
Not every SoC have efuse driver, so for those SoCs, we need a random
serial No.
Do you think we can merge this as is for now and then move onto making it more generic for other devices at a later date?
This is a per-SoC feature, so it's fine to add this into rk3399-board.c without
much extra work, and other device can enable or disable it by the option
CONFIG_MISC_INIT_R. So I think you can move the code from evb-rk3399.c
to rk3399-board.c directly.
Thanks,
- Kever
- const u32 cpuid_offset = 0x7;
- const u32 cpuid_length = 0x10;
- u8 cpuid[cpuid_length];
- rockchip_cpuid_from_efuse(cpuid_offset, cpuid_length, cpuid);
- rockchip_cpuid_set(cpuid, cpuid_length);
- rockchip_setup_macaddr();
It will be better for these function calls with return value.
There should be a blank line before 'return';
Ack.
Cheers Rohan Garg
participants (2)
-
Kever Yang
-
Rohan Garg