Subject: Re: PHY reset may still be asserted during MDIO probe

From: Andrew Lunn <[email-masked]>
Date: Fri, 9 Jul 2021 18:22:21 +0200

On Fri, Jul 09, 2021 at 05:33:36PM +0200, Geert Uytterhoeven wrote:
> Hi all,
> 
> I'm investigating a network failure after kexec on the Renesas Koelsch
> and Salvator-XS development boards, using the sh-eth or ravb driver.
> 
> During normal boot, the Ethernet interface is working fine:
> 
>     libphy: get_phy_c22_id:814: sh_mii: mdiobus_read() MII_PHYSID1 returned 34
>     libphy: get_phy_c22_id:824: sh_mii: mdiobus_read() MII_PHYSID2 returned 5431
>     libphy: get_phy_c22_id:832: sh_mii: phy_id = 0x00221537
>     libphy: get_phy_device:895: sh_mii: get_phy_c22_id() returned 0
>     fwnode_mdiobus_register_phy:109: sh_mii: get_phy_device() returned (ptrval)
>     fwnode_mdiobus_phy_device_register:46: sh_mii: fwnode_irq_get() returned 191
>     libphy: mdiobus_register_gpiod:48: mdiodev->reset_gpio = (ptrval)
>     mdio_bus ee700000.ethernet-ffffffff:01:
> mdiobus_register_device:88: assert MDIO reset
>     libphy: mdio_device_reset:124: calling gpiod_set_value_cansleep(..., 1)
>     mdio_bus ee700000.ethernet-ffffffff:01: phy_device_register:931:
> deassert PHY reset
>     libphy: mdio_device_reset:124: calling gpiod_set_value_cansleep(..., 0)
>     Micrel KSZ8041RNLI ee700000.ethernet-ffffffff:01: phy_probe:3026:
> deassert PHY reset
>     libphy: mdio_device_reset:124: calling gpiod_set_value_cansleep(..., 0)
>     fwnode_mdiobus_phy_device_register:75: sh_mii:
> phy_device_register() returned 0
>     fwnode_mdiobus_register_phy:137: sh_mii:
> fwnode_mdiobus_phy_device_register() returned 0
>     of_mdiobus_register:188: of_mdiobus_register_phy(sh_mii,
> /soc/ethernet@ee700000/ethernet-phy@1, 1) returned 0
>     sh-eth ee700000.ethernet eth0: Base address at 0xee700000,
> 2e:09:0a:00:6d:85, IRQ 126.
> 
> When using kexec, the PHY reset is asserted before starting the
> new kernel:
> 
>     Micrel KSZ8041RNLI ee700000.ethernet-ffffffff:01: phy_detach:1759:
> assert PHY reset
>     libphy: mdio_device_reset:124: calling gpiod_set_value_cansleep(..., 1)
>     kexec_core: Starting new kernel
>     Bye!
> 
> The new kernel fails to probe the PHY, as the PHY reset is still
> asserted:
> 
>     libphy: get_phy_c22_id:814: sh_mii: mdiobus_read() MII_PHYSID1
> returned 65535
>     libphy: get_phy_c22_id:824: sh_mii: mdiobus_read() MII_PHYSID2
> returned 65535

The per PHY reset is historically 'interesting'. It makes the
assumption the PHY can be detected when in reset, because the PHY it
was added for could be detected when in reset. And it turns out to be,
most PHYs cannot be detected when held in reset.

The simple solution is to make use of the MDIO bus reset property, as
Russell suggested. If you don't want to do that, you need to put the
PHY ID into DT. The core will then skip scanning the bus for the PHY,
and go straight to instantiating the PHY, and then it should be
brought out of reset.

	Andrew