Network boot of Raspberry Pi 4 leads to unstable network in U-Boot
André Althaus <[email protected]>
| Newsgroups | org.u-boot-project.lists.u-boot |
|---|---|
| Message-ID | <[email protected]> |
I'm trying to netboot a Raspberry Pi 4 B and use the U-Boot pxe bootflow
to bring up a NixOS system (using the extlinux.conf file created by NixOS).
When I do that the U-Boot DHCP process retries multiple times to get an
IP and sometimes running out of retries. The TFTP transfers afterwards
show many timeouts (T).
I tried to boot the same firmware files and U-Boot binary from the SD
card and then the pxe bootflow works without problems.
Every time the dhcp fails or the tftp timeout occurs, I can see the crc
error counter on the switch port increase.
I suspect, that the firmware leaves the network peripherals in some
state that is not completely reset/initialized by u-boot.
I tried to debug it with Qwen AI 3.8 and actually got a seemingly
working patch. Obviously I'm not confident this is the correct fix.
/proc/cpuinfo:
Revision : c03114
Serial : 1000000057c90c1d
Model : Raspberry Pi 4 Model B Rev 1.4
vcgencmd version:
May 21 2026 11:20:25
Copyright (c) 2012 Broadcom
version 288930ab4712b99596f32732664aaaeb881ef1e0 (clean) (release) (start)
rpi-eeprom-update:
BOOTLOADER: up to date
CURRENT: So 17. Mai 19:13:18 UTC 2026 (1779045198)
LATEST: Fr 9. Jan 16:12:13 UTC 2026 (1767975133)
RELEASE: default
(/nix/store/0a6v8w38pn6gfagyc5f0czz0jhhqpz40-raspberrypi-eeprom-2026.05.11-2712/lib/firmware/raspberrypi/bootloader-2711/default)
Use raspi-config to change the release.
VL805_FW: Using bootloader EEPROM
VL805: up to date
CURRENT: 000138c0
LATEST: 000138c0
rpi-eeprom-config:
[all]
BOOT_UART=0
WAKE_ON_GPIO=1
ENABLE_SELF_UPDATE=1
BOOT_ORDER=0xf21
NET_INSTALL_AT_POWER_ON=1
u-boot master (ece349ade2973e220f524ce59e59711cc919263f):
make rpi_arm64_defconfig
Additional configs:
CONFIG_CMD_MII=y
CONFIG_BOOTSTD_FULL=y
CONFIG_USE_BOOTCOMMAND=y
CONFIG_BOOTCOMMAND="bootflow scan -lb pxe"
CONFIG_LOG=y
CONFIG_LOG_MAX_LEVEL=7
CONFIG_LOG_CONSOLE=y
During the debugging, Qwen told me to try the following manual reset of
the PHY after the firmware started u-boot and before running the bootflow:
mii write 1 0 0x8000 # PHY soft reset
mii read 1 0 # repeat until bit15 clears (PHY
reset done)
1140
mii write 1 4 0x01E1 # advertise 10/100 F+H, pause (known-good value)
mii write 1 9 0x0300 # 1000T cap
mii write 1 0 0x1200 # AN enable + AN restart
mii read 1 1 # expect 0x796D (link up) after ~2 s
7949
Afterwards the bootflow worked without problems.
It added the following patch which seems to fix the problems:
diff --git a/drivers/net/bcmgenet.c b/drivers/net/bcmgenet.c
index a0264dc386d..1c867e61dd2 100644
--- a/drivers/net/bcmgenet.c
+++ b/drivers/net/bcmgenet.c
@@ -601,6 +601,30 @@ static int bcmgenet_mdio_init(const char *name,
struct udevice *priv)
return mdio_register(bus);
}
+static int bcmgenet_phy_soft_reset(struct bcmgenet_eth_priv *priv)
+{
+ int val;
+ int timeout = 100; /* ms */
+
+ /* Firmware may leave the internal GPHY in a state where MDIO
+ * auto-negotiation works but the RGMII data path corrupts frames,
+ * so force the PHY back to its defaults before attaching to it. */
+ if (bcmgenet_mdio_write(priv->bus, priv->phyaddr, 0, MII_BMCR,
BIT(15)))
+ return -EIO;
+
+ do {
+ udelay(1000);
+ val = bcmgenet_mdio_read(priv->bus, priv->phyaddr, 0, MII_BMCR);
+ if (val < 0)
+ return val;
+ } while ((val & BIT(15)) && --timeout);
+
+ if (!timeout)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
/* We only support RGMII (as used on the RPi4). */
static int bcmgenet_interface_set(struct bcmgenet_eth_priv *priv)
{
@@ -665,6 +689,12 @@ static int bcmgenet_eth_probe(struct udevice *dev)
return ret;
priv->bus = miiphy_get_dev_by_name(name);
+ if (!priv->bus)
+ return -ENODEV;
+
+ ret = bcmgenet_phy_soft_reset(priv);
+ if (ret)
+ return ret;
return bcmgenet_phy_init(priv, dev);
}
Its explanation:
The Broadcom legacy firmware performs its own DHCP/TFTP over the same
GENET before loading U-Boot, then shuts the MAC/PD down and hands off
without re-initialising the embedded GPHY. At hand-off the
GPHY's MDIO register file and IEEE auto-negotiation still function, so
U-Boot's generic PHY machinery brings the link up cleanly — but the
RGMII/PMA data path is left in a firmware-era state that corrupts
frames on the wire (bad FCS, visible only as the switch's receive CRC
errors under load).
Two facts support this being an initialisation-missing problem rather
than a driver bug in the normal path:
- The identical binary is stable when booting from SD, i.e. when the
firmware never used the network (a clean, default-like GPHY state
reaches U-Boot).
- A single PHY soft-reset at first use fully cures it; there is no other
state difference between the two paths that was found
(speed/duplex/advertise settings are identical once link is up).
If you need more information or some register values, I can provide them.
--
André Althaus
TU Dortmund/DELTA/Beschleunigerphysik
Maria-Goeppert-Mayer-Str. 2a
D-44221 Dortmund
Tel.: 0231 755 5488
smime.p7s
(application/pkcs7-signature, 3.9 KB) - not displayed