I tried to understand what's happening in U-Boot regarding the PHY.
What I see is that the PHY in the Raspberry Pi 4 needs to be reset when U-Boot is run after the firmware loaded it via netboot.
As far as I can tell, the bcmgenet driver will use the generic pyh driver in drivers/net/phy/phy.c and this one is not resetting the PHY. Some other broadcom phy drivers in drivers/net/phy/broadcom.c use a config op that adds a phy_reset() call (bcm5461_config).
Is there a reason the generic driver does not reset the phy?It seems the best way would be to add a new phy driver to broadcom.c that targets the Raspberry Pi 4 and overrides the config op with one that does the reset.
I don't have access to other Raspberry Pi models, but this might also be necessary for others.
Am 20.08.26 um 16:35 schrieb André Althaus:
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 Broadcomversion 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=yDuring 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 resetmii read 1 0 # repeat until bit15 clears (PHY reset done)1140mii 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.
smime.p7s
Description: Kryptografische S/MIME-Signatur
