[PATCH v2] rpi: Copy eth MAC address from fw DT to loaded DT

Martin Wetterwald martin at wetterwald.eu
Tue Mar 19 22:58:36 CET 2024


Raspberry Pi B models before model 4 don't have an EEPROM nor an OTP to
store the permanent factory MAC address of the NIC.
So the firmware that runs initially computes the factory MAC address of
the board and patches the DTB to give that information to the next
stage.
The MAC is put in the standard property `local-mac-address` which is
inserted in the `ethernet0` node of the firmware-provided FDT.

Here is the algo used by Linux to determine the MAC address (applies for
all models with smsc95xx). It stops as soon as we find a valid MAC.
1) Look at the FDT (mac-address, local-mac-address, address)
2) Try to fetch MAC from EEPROM (always fails on those Raspberry Pis)
[ 3) Check module parameter smsc95xx.macaddr ]
4) Generate a random MAC if we didn't find anything

Note that step 3) only applies in the Raspberry Pi fork of the Linux
kernel. The upstream kernel doesn't have that step, as that module
variable doesn't exist.

When CONFIG_MISC_INIT_R=y, U-Boot requests directly the MAC from the
running firmware in the GPU through the Raspberry Pi Mailbox. It then
stores it in ${usbethaddr} environment variable.
In U-Boot, the MAC is then often given to Linux like this:

> setenv bootargs [...] smsc95xx.macaddr="${usbethaddr}" [...]

This works in the Raspberry Pi fork of the kernel, because that module
parameter exists. But it doesn't work in the upstream kernel.
With the upstream kernel: if we make U-Boot forward the firmware-patched
FDT directly to the kernel, the MAC will be correct, because
`local-mac-addr` will be present. But if we configure U-Boot to give a
fresh FDT to the kernel, the MAC will be randomly generated because the
`local-mac-addr` property set by the firmware was not copied by U-Boot
to the loaded FDT.

This patch extends commit 6d0642494993 ("rpi: Copy properties from
firmware dtb to the loaded dtb") by making U-Boot copy the
`local-mac-address` property from the firmware FDT to the loaded FDT.
It makes it then possible to use the upstream kernel and to give it a
fresh FDT (not the firmware-provided one) without having the kernel
generate a random MAC address.

Note that this is only possible if CONFIG_OF_BOARD_SETUP=y and
ft_board_setup() is called.

Cc: Matthias Brugger <mbrugger at suse.com>
Cc: Peter Robinson <pbrobinson at gmail.com>
Cc: Antoine Mazeas <antoine at karthanis.net>
Signed-off-by: Martin Wetterwald <martin at wetterwald.eu>
---

Changes in v2:
- Clarify the commit message by pointing out that smsc95xx.macaddr
  module param only exists in the Raspberry Pi fork of the Linux kernel
  and not upstream
- Make the intent of the patch clearer in the commit message (booting
  upstream kernel + fresh FDT without having a random-generated MAC)

 board/raspberrypi/rpi/rpi.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c
index 2851ebc985..b36a893047 100644
--- a/board/raspberrypi/rpi/rpi.c
+++ b/board/raspberrypi/rpi/rpi.c
@@ -566,6 +566,9 @@ void  update_fdt_from_fw(void *fdt, void *fw_fdt)
 
 	/* address of the PHY device as provided by the firmware  */
 	copy_property(fdt, fw_fdt, "ethernet0/mdio at e14/ethernet-phy at 1", "reg");
+
+	/* MAC address of the NIC as provided by the firmware */
+	copy_property(fdt, fw_fdt, "ethernet0", "local-mac-address");
 }
 
 int ft_board_setup(void *blob, struct bd_info *bd)
-- 
2.44.0



More information about the U-Boot mailing list