STM32 gotchas
77.ETH does not work with certain APB2 clock settings

This issue has been brought up here and here.

STM32F4xx for connection between ETH/MAC and external PHY supports both the MII and RMII standard (the latter requiring less pins, at the expense of 50MHz clocking of the interface instead of 25MHz). This is accomplished by a relatively small "insert" between pins and the ETH/MAC module itself, which demultiplexes the RMII signals onto MII signals and also generates MII clocks from RMII clock, so that the ETH/MAC module is entirely unaware of the RMII/MII "duality" and works purely on MII interface.

This "insert" is controlled by a single control bit, SYSCFG_PMC.MII_RMII_SEL. SYSCFG is a unit which does not have any inherent functionality, it's just a collection of registers to "gather" such "orphan" control bits from various "intermediate" modules too small to grant them status of standalone module (i.e. assign a memory range for registers, assign clock enable bit(s) in RCC, etc.).

SYSCFG is clocked from APB2, i.e. if APB2 prescaler is set to a high value, it may take so many system clocks until a write to its register actually results in change of the related internal signal.

In this particular case, the Cube "library" code switched MII/RMII by writing SYSCFG_PMC.MII_RMII_SEL, and immediately after that initiated an ETH/MAC reset by writing into a self-clearing register bit in ETH/MAC itself. ETH/MAC is clocked directly from system clock, the MII/RMII clocks have not been properly switched in the RMII/MII "insert" by the time the ETH/MAC reset was initiated, thus the reset did not work properly, resulting in the whole (rather complex) ETH/MAC module not to work properly.

Workaround consisted of inserting a dummy read from SYSCFG before initiating ETH/MAC reset, which is a method to ensure that the write to SYSCFG register was actually finished.

This is an example of subtle errors stemming from timing details within the complex SoC fabric of STM32.