[PATCH v3 09/13] stm32mp1: spl: Configure MAC address when booting OP-TEE

Alexandru Gagniuc mr.nuke.me at gmail.com
Fri Oct 8 21:56:51 CEST 2021

When OP-TEE is booted as the SPL payload, the stage after OP-TEE is
not guaranteed to be u-boot. Thus the FDT patching in u-boot is not
guaranteed to occur. Add this step to SPL.

The patching by stm32_fdt_setup_mac_addr() is done in SPL, and patches
the target FDT directly. This differs is different from
setup_mac_address(), which sets the "ethaddr" env variable, and does
not work in SPL.

An alternative way of setting the MAC is to patch the kernel's
devicetree to use the "nvmem-cells" property. This would backend on
the linux BSEC driver, which relies on an SMCC call. That call is
implemented only by TF-A, not by SPL. Thus linux will not be able to
read the MAC from OTP, and this alternative method will fail.

Changing the linux driver is not feasible is our goal is to support
the current linux LTS release (v5.14). Implementing the SMCC call
would require SPL finagling, and possibly carry security side-effects.

Thus, adding "mac-address" nodes to the kernel devicetree is the most
economical method in terms of lines of code and complexity.

Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
 arch/arm/mach-stm32mp/cpu.c                   | 22 +++++++++++++++++++
 .../arm/mach-stm32mp/include/mach/sys_proto.h |  3 +++
 arch/arm/mach-stm32mp/spl.c                   |  1 +
 3 files changed, 26 insertions(+)

diff --git a/arch/arm/mach-stm32mp/cpu.c b/arch/arm/mach-stm32mp/cpu.c
index 8727de513c..2b8b67bb40 100644
--- a/arch/arm/mach-stm32mp/cpu.c
+++ b/arch/arm/mach-stm32mp/cpu.c
@@ -10,6 +10,7 @@
 #include <cpu_func.h>
 #include <debug_uart.h>
 #include <env.h>
+#include <fdt_support.h>
 #include <init.h>
 #include <log.h>
 #include <lmb.h>
@@ -646,6 +647,27 @@ __weak int setup_mac_address(void)
 	return 0;
+int stm32_fdt_setup_mac_addr(void *fdt)
+	int ret;
+	uchar enetaddr[ARP_HLEN];
+	ret = stm32_read_otp_mac(enetaddr);
+	if (ret < 0)
+		return ret;
+	if (!is_valid_ethaddr(enetaddr)) {
+		printf("invalid MAC address in OTP\n");
+		return -EINVAL;
+	}
+	ret = fdt_ethernet_set_macaddr(fdt, 0, enetaddr);
+	if (ret)
+		debug("Failed to set mac address from OTP: %d\n", ret);
+	return ret;
 static int setup_serial_number(void)
 	char serial_string[25];
diff --git a/arch/arm/mach-stm32mp/include/mach/sys_proto.h b/arch/arm/mach-stm32mp/include/mach/sys_proto.h
index 4149d3a133..2d24cfee3f 100644
--- a/arch/arm/mach-stm32mp/include/mach/sys_proto.h
+++ b/arch/arm/mach-stm32mp/include/mach/sys_proto.h
@@ -47,7 +47,10 @@ void get_soc_name(char name[SOC_NAME_SIZE]);
 /* return boot mode */
 u32 get_bootmode(void);
+/* Set 'ethaddr' env variable with MAC from OTP (useful for u-boot proper) */
 int setup_mac_address(void);
+/* Patch the first 'ethernet' node of FDT with MAC from OTP (useful for SPL) */
+int stm32_fdt_setup_mac_addr(void *fdt);
 /* board power management : configure vddcore according OPP */
 void board_vddcore_init(u32 voltage_mv);
diff --git a/arch/arm/mach-stm32mp/spl.c b/arch/arm/mach-stm32mp/spl.c
index 405eff68a3..d9fdc5926c 100644
--- a/arch/arm/mach-stm32mp/spl.c
+++ b/arch/arm/mach-stm32mp/spl.c
@@ -181,6 +181,7 @@ void stm32_init_tzc_for_optee(void)
 void spl_board_prepare_for_optee(void *fdt)
+	stm32_fdt_setup_mac_addr(fdt);

More information about the U-Boot mailing list