Re: [PATCH net-next v0] net: phy: aquantia: poll status register
From: Aryan Srivastava
Date: Wed Oct 09 2024 - 18:25:38 EST
On Tue, 2024-10-08 at 23:40 +0200, Andrew Lunn wrote:
> On Mon, Oct 07, 2024 at 10:35:36AM +1300, Aryan Srivastava wrote:
> > The system interface connection status register is not immediately
> > correct upon line side link up. This results in the status being
> > read as
> > OFF and then transitioning to the correct host side link mode with
> > a
> > short delay. This results in the phylink framework passing the OFF
> > status down to all MAC config drivers, resulting in the host side
> > link
> > being misconfigured, which in turn can lead to link flapping or
> > complete
> > packet loss in some cases.
> >
> > Mitigate this by periodically polling the register until it not
> > showing
> > the OFF state. This will be done every 1ms for 10ms, using the same
> > poll/timeout as the processor intensive operation reads.
>
> Does the datasheet say anything about when MDIO_PHYXS_VEND_IF_STATUS
> is valid?
>
The datasheet is quite brief about the registers. There is basic
description, but not much towards any nuances they might have,
unfortunately.
> > #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_XAUI 4
> > #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII 6
> > #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_RXAUI 7
> > +#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_OFF 9
> > #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII 10
> >
> > #define MDIO_AN_VEND_PROV 0xc400
> > @@ -342,9 +343,18 @@ static int aqr107_read_status(struct
> > phy_device *phydev)
> > if (!phydev->link || phydev->autoneg == AUTONEG_DISABLE)
> > return 0;
> >
> > - val = phy_read_mmd(phydev, MDIO_MMD_PHYXS,
> > MDIO_PHYXS_VEND_IF_STATUS);
> > - if (val < 0)
> > - return val;
> > + /**
> > + * The status register is not immediately correct on line
> > side link up.
> > + * Poll periodically until it reflects the correct ON
> > state.
> > + */
> > + ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_PHYXS,
> > + MDIO_PHYXS_VEND_IF_STATUS,
> > val,
> > + (FIELD_GET(MDIO_PHYXS_VEND_
> > IF_STATUS_TYPE_MASK, val) !=
> > + MDIO_PHYXS_VEND_IF_STATUS_T
> > YPE_OFF),
> > + AQR107_OP_IN_PROG_SLEEP,
> > + AQR107_OP_IN_PROG_TIMEOUT,
> > false);
> > + if (ret)
> > + return ret;
>
> I don't know if returning ETIMEDOUT is the correct thing to do
> here. It might be better to set phydev->link to false, since there is
> no end to end link yet.
Yes I agree, will change this to use 'val' regardless of the return,
and let the switch/case deal with the OFF status as required.
>
> Andrew
Cheers,
Aryan