Re: [PATCH net-next v1 1/1] net: phy: ax88772a: fix lost pause advertisement configuration
From: Oleksij Rempel
Date: Fri Jun 24 2022 - 05:12:52 EST
I forgot to add PHY maintainers. CCing Andrew and Heiner.
On Fri, Jun 24, 2022 at 09:55:58AM +0200, Oleksij Rempel wrote:
> In case of asix_ax88772a_link_change_notify() workaround, we run soft
> reset which will automatically clear MII_ADVERTISE configuration. The
> PHYlib framework do not know about changed configuration state of the
> PHY, so we need to save and restore all needed configuration registers.
>
> Fixes: dde258469257 ("net: usb/phy: asix: add support for ax88772A/C PHYs")
> Signed-off-by: Oleksij Rempel <o.rempel@xxxxxxxxxxxxxx>
> ---
> drivers/net/phy/ax88796b.c | 37 ++++++++++++++++++++++++++++++++++++-
> 1 file changed, 36 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/phy/ax88796b.c b/drivers/net/phy/ax88796b.c
> index 457896337505..6971d0196917 100644
> --- a/drivers/net/phy/ax88796b.c
> +++ b/drivers/net/phy/ax88796b.c
> @@ -18,6 +18,11 @@ MODULE_DESCRIPTION("Asix PHY driver");
> MODULE_AUTHOR("Michael Schmitz <schmitzmic@xxxxxxxxx>");
> MODULE_LICENSE("GPL");
>
> +struct asix_context {
> + u16 bmcr;
> + u16 advertise;
> +};
> +
> /**
> * asix_soft_reset - software reset the PHY via BMCR_RESET bit
> * @phydev: target phy_device struct
> @@ -83,13 +88,43 @@ static int asix_ax88772a_read_status(struct phy_device *phydev)
> return 0;
> }
>
> +/* save relevant PHY registers to private copy */
> +static void asix_context_save(struct phy_device *phydev,
> + struct asix_context *context)
> +{
> + context->bmcr = phy_read(phydev, MII_BMCR);
> + context->advertise = phy_read(phydev, MII_ADVERTISE);
> +}
> +
> +/* restore relevant PHY registers from private copy */
> +static void asix_context_restore(struct phy_device *phydev,
> + const struct asix_context *context)
> +{
> + u16 bmcr = context->bmcr;
> +
> + phy_write(phydev, MII_ADVERTISE, context->advertise);
> +
> + /* after all settings are restored, restart autoneg */
> + if (phydev->autoneg == AUTONEG_ENABLE)
> + bmcr |= BMCR_ANRESTART;
> +
> + phy_write(phydev, MII_BMCR, bmcr);
> +}
> +
> static void asix_ax88772a_link_change_notify(struct phy_device *phydev)
> {
> /* Reset PHY, otherwise MII_LPA will provide outdated information.
> * This issue is reproducible only with some link partner PHYs
> */
> - if (phydev->state == PHY_NOLINK && phydev->drv->soft_reset)
> + if (phydev->state == PHY_NOLINK && phydev->drv->soft_reset) {
> + struct asix_context context;
> +
> + asix_context_save(phydev, &context);
> +
> phydev->drv->soft_reset(phydev);
> +
> + asix_context_restore(phydev, &context);
> + }
> }
>
> static struct phy_driver asix_driver[] = {
> --
> 2.30.2
>
>
>
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |