On 08.02.2021 15:03, Serge Semin wrote:
> It has been noticed that RTL8211E PHY stops detecting and reporting events
> when EEE is successfully advertised and RXC stopping in LPI is enabled.
> The freeze happens right after 3.0.10 bit (PC1R "Clock Stop Enable"
> register) is set. At the same time LED2 stops blinking as if EEE mode has
> been disabled. Notably the network traffic still flows through the PHY
> with no obvious problem. Anyway if any MDIO read procedure is performed
> after the "RXC stop in LPI" mode is enabled PHY gets to be unfrozen, LED2
> starts blinking and PHY interrupts happens again. The problem has been
> noticed on RTL8211E PHY working together with DW GMAC 3.73a MAC and
> reporting its event via a dedicated IRQ signal. (Obviously the problem has
> been unnoticed in the polling mode, since it gets naturally fixed by the
> periodic MDIO read procedure from the PHY status register - BMSR.)
> 
> In order to fix that problem we suggest to locally re-implement the MMD
> write method for RTL8211E PHY and perform a dummy read right after the
> PC1R register is accessed to enable the RXC stopping in LPI mode.
> 
> Signed-off-by: Serge Semin <sergey.se...@baikalelectronics.ru>
> ---
>  drivers/net/phy/realtek.c | 37 +++++++++++++++++++++++++++++++++++++
>  1 file changed, 37 insertions(+)
> 
> diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
> index 99ecd6c4c15a..cbb86c257aae 100644
> --- a/drivers/net/phy/realtek.c
> +++ b/drivers/net/phy/realtek.c
> @@ -559,6 +559,42 @@ static int rtl822x_write_mmd(struct phy_device *phydev, 
> int devnum, u16 regnum,
>       return ret;
>  }
>  
> +static int rtl8211e_write_mmd(struct phy_device *phydev, int devnum, u16 
> regnum,
> +                           u16 val)
> +{
> +     int ret;
> +
> +     /* Write to the MMD registers by using the standard control/data pair.
> +      * The only difference is that we need to perform a dummy read after
> +      * the PC1R.CLKSTOP_EN bit is set. It's required to workaround an issue
> +      * of a partial core freeze so LED2 stops blinking in EEE mode, PHY
> +      * stops detecting the link change and raising IRQs until any read from
> +      * its registers performed. That happens only if and right after the PHY
> +      * is enabled to stop RXC in LPI mode.
> +      */
> +     ret = __phy_write(phydev, MII_MMD_CTRL, devnum);
> +     if (ret)
> +             return ret;
> +
> +     ret = __phy_write(phydev, MII_MMD_DATA, regnum);
> +     if (ret)
> +             return ret;
> +
> +     ret = __phy_write(phydev, MII_MMD_CTRL, devnum | MII_MMD_CTRL_NOINCR);
> +     if (ret)
> +             return ret;
> +

Nice analysis. Alternatively to duplicating this code piece we could
export mmd_phy_indirect(). But up to you.

> +     ret = __phy_write(phydev, MII_MMD_DATA, val);
> +     if (ret)
> +             return ret;
> +
> +     if (devnum == MDIO_MMD_PCS && regnum == MDIO_CTRL1 &&
> +         val & MDIO_PCS_CTRL1_CLKSTOP_EN)
> +             ret =  __phy_read(phydev, MII_MMD_DATA);
> +
> +     return ret < 0 ? ret : 0;
> +}
> +
>  static int rtl822x_get_features(struct phy_device *phydev)
>  {
>       int val;
> @@ -725,6 +761,7 @@ static struct phy_driver realtek_drvs[] = {
>               .resume         = genphy_resume,
>               .read_page      = rtl821x_read_page,
>               .write_page     = rtl821x_write_page,
> +             .write_mmd      = rtl8211e_write_mmd,
>       }, {
>               PHY_ID_MATCH_EXACT(0x001cc916),
>               .name           = "RTL8211F Gigabit Ethernet",
> 

Reply via email to