All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Russell King (Oracle)" <linux@armlinux.org.uk>
To: Ong Boon Leong <boon.leong.ong@intel.com>
Cc: Alexandre Torgue <alexandre.torgue@st.com>,
	Jose Abreu <joabreu@synopsys.com>, Andrew Lunn <andrew@lunn.ch>,
	Heiner Kallweit <hkallweit1@gmail.com>,
	Paolo Abeni <pabeni@redhat.com>,
	"David S . Miller" <davem@davemloft.net>,
	Jakub Kicinski <kuba@kernel.org>,
	Maxime Coquelin <mcoquelin.stm32@gmail.com>,
	Alexandre Torgue <alexandre.torgue@foss.st.com>,
	Giuseppe Cavallaro <peppe.cavallaro@st.com>,
	netdev@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH net-next 1/4] net: pcs: xpcs: add CL37 1000BASE-X AN support
Date: Fri, 22 Apr 2022 09:00:41 +0100	[thread overview]
Message-ID: <YmJgqSdF7LMxoSXv@shell.armlinux.org.uk> (raw)
In-Reply-To: <20220422073505.810084-2-boon.leong.ong@intel.com>

Hi,

On Fri, Apr 22, 2022 at 03:35:02PM +0800, Ong Boon Leong wrote:
> @@ -774,6 +788,58 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, unsigned int mode)
>  	return ret;
>  }
>  
> +static int xpcs_config_aneg_c37_1000basex(struct dw_xpcs *xpcs, unsigned int mode,
> +					  const unsigned long *advertising)
> +{
> +	int ret, mdio_ctrl;
> +
> +	/* For AN for 1000BASE-X mode, the settings are :-
> +	 * 1) VR_MII_MMD_CTRL Bit(12) [AN_ENABLE] = 0b (Disable C37 AN in case
> +	 *    it is already enabled)
> +	 * 2) VR_MII_AN_CTRL Bit(2:1)[PCS_MODE] = 00b (1000BASE-X C37)
> +	 * 3) SR_MII_AN_ADV Bit(6)[FD] = 1b (Full Duplex)
> +	 *    Note: Half Duplex is rarely used, so don't advertise.
> +	 * 4) VR_MII_MMD_CTRL Bit(12) [AN_ENABLE] = 1b (Enable C37 AN)

So if this function gets called to update the advertisement - even if
there is no actual change - we go through a AN-disable..AN-enable
dance and cause the link to re-negotiate. That doesn't sound like nice
behaviour.

> +	 */
> +	mdio_ctrl = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL);
> +	if (mdio_ctrl < 0)
> +		return mdio_ctrl;
> +
> +	if (mdio_ctrl & AN_CL37_EN) {
> +		ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL,
> +				 mdio_ctrl & ~AN_CL37_EN);
> +		if (ret < 0)
> +			return ret;
> +	}
> +
> +	ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret &= ~DW_VR_MII_PCS_MODE_MASK;
> +	ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL, ret);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_ADVERTISE);
> +	ret |= ADVERTISE_1000XFULL;
> +	ret = xpcs_write(xpcs, MDIO_MMD_VEND2, MII_ADVERTISE, ret);

What if other bits are already set in the MII_ADVERTISE register?
Maybe consider using phylink_mii_c22_pcs_encode_advertisement()?

The pcs_config() method is also supposed to return either a negative
error, 0 for no advertisement change, or positive for an advertisement
change, in which case phylink will trigger a call to pcs_an_restart().

> +static int xpcs_get_state_c37_1000basex(struct dw_xpcs *xpcs,
> +					struct phylink_link_state *state)
> +{
> +	int lpa, adv;
> +	int ret;
> +
> +	ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL);
> +	if (ret < 0)
> +		return ret;
> +
> +	if (ret & AN_CL37_EN) {
> +		/* Reset link_state */
> +		state->link = false;
> +		state->speed = SPEED_UNKNOWN;
> +		state->duplex = DUPLEX_UNKNOWN;
> +		state->pause = 0;

Phylink guarantees that speed, duplex and pause are set to something
sensible - please remove these. The only one you probably need here
is state->link.

> +
> +		lpa = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_LPA);
> +		if (lpa < 0 || lpa & LPA_RFAULT)
> +			return false;

This function does not return a boolean. Returning "false" is the same
as returning 0, which means "no error" but an error has occurred.

> +
> +		adv = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_ADVERTISE);
> +		if (adv < 0)
> +			return false;

Ditto.

> +
> +		if (lpa & ADVERTISE_1000XFULL &&
> +		    adv & ADVERTISE_1000XFULL) {
> +			state->speed = SPEED_1000;
> +			state->duplex = DUPLEX_FULL;
> +			state->link = true;
> +		}
> +
> +		/* Clear CL37 AN complete status */
> +		ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_INTR_STS, 0);
> +	} else {
> +		state->link = true;
> +		state->speed = SPEED_1000;
> +		state->duplex = DUPLEX_FULL;
> +		state->pause = 0;

If we're in AN-disabled mode, phylink will set state->speed and
state->duplex according to the user's parameters, so there should be no
need to do it here.

> @@ -994,9 +1143,21 @@ void xpcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
>  		return xpcs_config_usxgmii(xpcs, speed);
>  	if (interface == PHY_INTERFACE_MODE_SGMII)
>  		return xpcs_link_up_sgmii(xpcs, mode, speed, duplex);
> +	if (interface == PHY_INTERFACE_MODE_1000BASEX)
> +		return xpcs_link_up_1000basex(xpcs, speed, duplex);
>  }
>  EXPORT_SYMBOL_GPL(xpcs_link_up);
>  
> +static void xpcs_an_restart(struct phylink_pcs *pcs)
> +{
> +	struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs);
> +	int ret;
> +
> +	ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1);
> +	ret |= BMCR_ANRESTART;
> +	ret = xpcs_write(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1, ret);

If xpcs_read() returns an error, we try to write the error back to
the control register? Is that a good idea/

Thanks.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

WARNING: multiple messages have this Message-ID (diff)
From: "Russell King (Oracle)" <linux@armlinux.org.uk>
To: Ong Boon Leong <boon.leong.ong@intel.com>
Cc: Alexandre Torgue <alexandre.torgue@st.com>,
	Jose Abreu <joabreu@synopsys.com>, Andrew Lunn <andrew@lunn.ch>,
	Heiner Kallweit <hkallweit1@gmail.com>,
	Paolo Abeni <pabeni@redhat.com>,
	"David S . Miller" <davem@davemloft.net>,
	Jakub Kicinski <kuba@kernel.org>,
	Maxime Coquelin <mcoquelin.stm32@gmail.com>,
	Alexandre Torgue <alexandre.torgue@foss.st.com>,
	Giuseppe Cavallaro <peppe.cavallaro@st.com>,
	netdev@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH net-next 1/4] net: pcs: xpcs: add CL37 1000BASE-X AN support
Date: Fri, 22 Apr 2022 09:00:41 +0100	[thread overview]
Message-ID: <YmJgqSdF7LMxoSXv@shell.armlinux.org.uk> (raw)
In-Reply-To: <20220422073505.810084-2-boon.leong.ong@intel.com>

Hi,

On Fri, Apr 22, 2022 at 03:35:02PM +0800, Ong Boon Leong wrote:
> @@ -774,6 +788,58 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, unsigned int mode)
>  	return ret;
>  }
>  
> +static int xpcs_config_aneg_c37_1000basex(struct dw_xpcs *xpcs, unsigned int mode,
> +					  const unsigned long *advertising)
> +{
> +	int ret, mdio_ctrl;
> +
> +	/* For AN for 1000BASE-X mode, the settings are :-
> +	 * 1) VR_MII_MMD_CTRL Bit(12) [AN_ENABLE] = 0b (Disable C37 AN in case
> +	 *    it is already enabled)
> +	 * 2) VR_MII_AN_CTRL Bit(2:1)[PCS_MODE] = 00b (1000BASE-X C37)
> +	 * 3) SR_MII_AN_ADV Bit(6)[FD] = 1b (Full Duplex)
> +	 *    Note: Half Duplex is rarely used, so don't advertise.
> +	 * 4) VR_MII_MMD_CTRL Bit(12) [AN_ENABLE] = 1b (Enable C37 AN)

So if this function gets called to update the advertisement - even if
there is no actual change - we go through a AN-disable..AN-enable
dance and cause the link to re-negotiate. That doesn't sound like nice
behaviour.

> +	 */
> +	mdio_ctrl = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL);
> +	if (mdio_ctrl < 0)
> +		return mdio_ctrl;
> +
> +	if (mdio_ctrl & AN_CL37_EN) {
> +		ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL,
> +				 mdio_ctrl & ~AN_CL37_EN);
> +		if (ret < 0)
> +			return ret;
> +	}
> +
> +	ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret &= ~DW_VR_MII_PCS_MODE_MASK;
> +	ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL, ret);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_ADVERTISE);
> +	ret |= ADVERTISE_1000XFULL;
> +	ret = xpcs_write(xpcs, MDIO_MMD_VEND2, MII_ADVERTISE, ret);

What if other bits are already set in the MII_ADVERTISE register?
Maybe consider using phylink_mii_c22_pcs_encode_advertisement()?

The pcs_config() method is also supposed to return either a negative
error, 0 for no advertisement change, or positive for an advertisement
change, in which case phylink will trigger a call to pcs_an_restart().

> +static int xpcs_get_state_c37_1000basex(struct dw_xpcs *xpcs,
> +					struct phylink_link_state *state)
> +{
> +	int lpa, adv;
> +	int ret;
> +
> +	ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL);
> +	if (ret < 0)
> +		return ret;
> +
> +	if (ret & AN_CL37_EN) {
> +		/* Reset link_state */
> +		state->link = false;
> +		state->speed = SPEED_UNKNOWN;
> +		state->duplex = DUPLEX_UNKNOWN;
> +		state->pause = 0;

Phylink guarantees that speed, duplex and pause are set to something
sensible - please remove these. The only one you probably need here
is state->link.

> +
> +		lpa = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_LPA);
> +		if (lpa < 0 || lpa & LPA_RFAULT)
> +			return false;

This function does not return a boolean. Returning "false" is the same
as returning 0, which means "no error" but an error has occurred.

> +
> +		adv = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_ADVERTISE);
> +		if (adv < 0)
> +			return false;

Ditto.

> +
> +		if (lpa & ADVERTISE_1000XFULL &&
> +		    adv & ADVERTISE_1000XFULL) {
> +			state->speed = SPEED_1000;
> +			state->duplex = DUPLEX_FULL;
> +			state->link = true;
> +		}
> +
> +		/* Clear CL37 AN complete status */
> +		ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_INTR_STS, 0);
> +	} else {
> +		state->link = true;
> +		state->speed = SPEED_1000;
> +		state->duplex = DUPLEX_FULL;
> +		state->pause = 0;

If we're in AN-disabled mode, phylink will set state->speed and
state->duplex according to the user's parameters, so there should be no
need to do it here.

> @@ -994,9 +1143,21 @@ void xpcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
>  		return xpcs_config_usxgmii(xpcs, speed);
>  	if (interface == PHY_INTERFACE_MODE_SGMII)
>  		return xpcs_link_up_sgmii(xpcs, mode, speed, duplex);
> +	if (interface == PHY_INTERFACE_MODE_1000BASEX)
> +		return xpcs_link_up_1000basex(xpcs, speed, duplex);
>  }
>  EXPORT_SYMBOL_GPL(xpcs_link_up);
>  
> +static void xpcs_an_restart(struct phylink_pcs *pcs)
> +{
> +	struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs);
> +	int ret;
> +
> +	ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1);
> +	ret |= BMCR_ANRESTART;
> +	ret = xpcs_write(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1, ret);

If xpcs_read() returns an error, we try to write the error back to
the control register? Is that a good idea/

Thanks.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2022-04-22  8:01 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-22  7:35 [PATCH net-next 0/4] pcs-xpcs, stmmac: add 1000BASE-X AN for network switch Ong Boon Leong
2022-04-22  7:35 ` Ong Boon Leong
2022-04-22  7:35 ` [PATCH net-next 1/4] net: pcs: xpcs: add CL37 1000BASE-X AN support Ong Boon Leong
2022-04-22  7:35   ` Ong Boon Leong
2022-04-22  8:00   ` Russell King (Oracle) [this message]
2022-04-22  8:00     ` Russell King (Oracle)
2022-04-25  3:30     ` Ong, Boon Leong
2022-04-25  3:30       ` Ong, Boon Leong
2022-04-22 17:35   ` kernel test robot
2022-04-22 17:35     ` kernel test robot
2022-04-23  3:00   ` kernel test robot
2022-04-23  3:00     ` kernel test robot
2022-04-22  7:35 ` [PATCH net-next 2/4] net: stmmac: introduce PHY-less setup support Ong Boon Leong
2022-04-22  7:35   ` Ong Boon Leong
2022-04-22 12:58   ` Andrew Lunn
2022-04-22 12:58     ` Andrew Lunn
2022-04-23  1:13     ` Ong, Boon Leong
2022-04-23  1:13       ` Ong, Boon Leong
2022-04-22  7:35 ` [PATCH net-next 3/4] stmmac: intel: prepare to support 1000BASE-X phy interface setting Ong Boon Leong
2022-04-22  7:35   ` Ong Boon Leong
2022-04-22  7:35 ` [PATCH net-next 4/4] stmmac: intel: introduce platform data phyless setting for Ericsson system Ong Boon Leong
2022-04-22  7:35   ` Ong Boon Leong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YmJgqSdF7LMxoSXv@shell.armlinux.org.uk \
    --to=linux@armlinux.org.uk \
    --cc=alexandre.torgue@foss.st.com \
    --cc=alexandre.torgue@st.com \
    --cc=andrew@lunn.ch \
    --cc=boon.leong.ong@intel.com \
    --cc=davem@davemloft.net \
    --cc=hkallweit1@gmail.com \
    --cc=joabreu@synopsys.com \
    --cc=kuba@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-stm32@st-md-mailman.stormreply.com \
    --cc=mcoquelin.stm32@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=peppe.cavallaro@st.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.