fix(stm32h7): poll MDIO completion in microseconds, plus two upstream mdio fixes - #414
Merged
Merged
Conversation
The struct stm32_mdio_bus_s aka g_stm32_mdio_bus has not been referenced at all, because mdio_register() allocates its own structure. Then lower half drivers receive only their respective part in mdio_read() and mdio_write() because MDIO_WRITE/MDIO_READ provides only d->lower to the specific lower level drivers. Signed-off-by: Pavel Pisa <pisa@fel.cvut.cz> (cherry picked from commit b6cb94a)
Use correct register Signed-off-by: Luchian Mihai <luchiann.mihai@gmail.com> (cherry picked from commit 85ad737)
dakejahl
marked this pull request as ready for review
September 7, 2026 15:13
…t 5 ms steps stm32_c22_read() and stm32_c22_write() waited for the MACMDIOAR busy bit with up_mdelay(5) between checks. A Clause 22 frame takes about 30 us, so the first check always sees the bus busy and every PHY register access costs a 5 ms busy-wait, roughly 150 times the transfer. stm32_phyinit() waits for link-up with PHY_RETRY_TIMEOUT (6552) MSR reads. With no cable attached that is 33 s of CPU spent in up_mdelay() inside ifup, with the network lock held: on an STM32H753 the netinit thread pinned the core at 44% for the first 65 s after boot and every socket operation on other threads blocked until it gave up. Before the MDIO bus refactor, stm32_phyread() polled the busy bit in a tight loop. Poll every 10 us instead, with the timeout expressed in microseconds so the total bound stays at 10 ms, and report the timeout from the result rather than the loop counter so a transfer that completes on the last iteration is not logged as timed out. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> (cherry picked from commit 304cbb1)
dakejahl
force-pushed
the
dakejahl/stm32h7-mdio-poll
branch
from
September 7, 2026 15:13
d3971c4 to
fe4580c
Compare
dakejahl
added a commit
to PX4/PX4-Autopilot
that referenced
this pull request
Sep 7, 2026
Every PHY register access on STM32H7 spent 5 ms in up_mdelay(), so the boot-time autonegotiation link wait ran netinit at 44% CPU for 65 s with the net lock held whenever no ethernet cable was attached (PX4/NuttX#414, apache/nuttx#20067). Also picks up the two upstream stm32_mdio fixes for the lower-half cast and the Clause 22 write register field.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Backports three
stm32_mdio.cfixes for STM32H7 ethernet: two already on apache master (private-structure use, RDA field in the Clause 22 write) and apache/nuttx#20067 (merged as 304cbb1), which replaces the 5 ms busy-wait between MDIO completion checks with 10 us polling.Problem
Every PHY register access on H7 costs a 5 ms
up_mdelay()because the transfer (~30 us) is never complete on the first check.stm32_phyinit()issues 6552 of them waiting for link-up, so on any H7 board booting without an ethernet cable (STM32H7_AUTONEG+NETINIT_MONITOR: ark fmu-v6s/v6x, px4 fmu-v6x, ...)netinitpins the core at ~44% for the first ~65 s, priority-inherited to 100, with the net lock held. The UDP MAVLink instance and any other socket user stalls until the link wait times out. Steady state after that is 0.4%, one 5 ms read per poll.The other two commits are needed for the fix to cherry-pick cleanly and are real bugs: the lower-half cast reads
timeoutfrom the wrong object, and the C22 write put the PHY address in the register-address field.Solution
Poll every 10 us with a 10 ms bound. Measured on ARK FMU-V6X (STM32H753, LAN8742A), no cable,
top onceevery 2 s from power-on (shell up at ~12 s):