Commit 237a44d2 authored by Rohan Garg's avatar Rohan Garg

rockchip: 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's avatarRohan Garg <rohan.garg@collabora.com>

Series-cc: Klaus Goger <klaus.goger@theobroma-systems.com>
Series-cc: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
parent 871e4421
Pipeline #4599 passed with stages
in 3 minutes and 2 seconds
......@@ -6,8 +6,11 @@
#include <common.h>
#include <dm.h>
#include <dm/pinctrl.h>
#include <environment.h>
#include <misc.h>
#include <asm/arch-rockchip/periph.h>
#include <power/regulator.h>
#include <u-boot/sha256.h>
int board_init(void)
{
......@@ -33,3 +36,98 @@ int board_init(void)
out:
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
}
int misc_init_r(void)
{
setup_serial();
setup_macaddr();
return 0;
}
......@@ -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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment