netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next v2 0/3] improve clause 45 support in phylink
@ 2019-12-13 17:54 Russell King - ARM Linux admin
  2019-12-13 18:22 ` [PATCH net-next v2 1/3] net: phylink: improve clause 45 PHY ksettings_set implementation Russell King
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Russell King - ARM Linux admin @ 2019-12-13 17:54 UTC (permalink / raw)
  To: Andrew Lunn, Florian Fainelli, Heiner Kallweit
  Cc: Antoine Tenart, David S. Miller, netdev

Hi,

These three patches improve the clause 45 support in phylink, fixing
some corner cases that have been noticed with the addition of SFP+
NBASE-T modules, but are actually a little more wisespread than I
initially realised.

The first issue was spotted with a NBASE-T PHY on a SFP+ module plugged
into a mvneta platform. When these PHYs are not operating in USXGMII
mode, but are in a single-lane Serdes mode, they will switch between
one of several different PHY interface modes.

If we call the MAC validate() function with the current PHY interface
mode, we will restrict the supported and advertising masks to the link
modes that the current PHY interface mode supports. For example, if we
determine that we want to start the PHY with an interface mode of
2500BASE-X, then this setup will restrict the advertisement and
supported masks to 2.5G speed link modes.

What we actually want for these PHYs is to allow them to support any
link modes that the PHY supports _and_ the MAC is also capable of
supporting. Without knowing the details of the PHY interface modes that
may be used, we can do this by using PHY_INTERFACE_MODE_NA to validate
and restrict the link modes to any that the MAC supports.

mvpp2 with the 88X3310 PHY avoids this problem, because the validate()
implementation allows all MAC supported speeds not only for
PHY_INTERFACE_MODE_NA, but also for XAUI and 10GKR modes.

The first patch addresses this; current MAC drivers should continue to
work as-is, but there will be a follow-on patch to fixup at least
mvpp2.

The second issue addresses a very similar problem that occurs when
trying to use ethtool to alter the advertisement mask - we call
the MAC validate() function with the current interface mode, the
current support and requested advertisement masks. This immediately
restricts the advertisement in the same way as the above.

This patch series addresses both issues, although the patches are not
in the above order.

v2: fix patch 3 missing 1G link modes for SGMII and RGMII interface
    modes.

 drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c |  22 ++++-
 drivers/net/phy/phylink.c                       | 106 +++++++++++++++---------
 2 files changed, 84 insertions(+), 44 deletions(-)

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up
According to speedtest.net: 11.9Mbps down 500kbps up

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH net-next v2 1/3] net: phylink: improve clause 45 PHY ksettings_set implementation
  2019-12-13 17:54 [PATCH net-next v2 0/3] improve clause 45 support in phylink Russell King - ARM Linux admin
@ 2019-12-13 18:22 ` Russell King
  2019-12-13 18:22 ` [PATCH net-next v2 2/3] net: phylink: extend clause 45 PHY validation workaround Russell King
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Russell King @ 2019-12-13 18:22 UTC (permalink / raw)
  To: Andrew Lunn, Florian Fainelli, Heiner Kallweit
  Cc: Antoine Tenart, David S. Miller, netdev

While testing ethtool with the Methode DM7052 module, it was noticed
that attempting to set the advertising mask results in the mask being
truncated to the support offered by the currently chosen PHY interface
mode.

When a PHY dynamically changes the PHY interface mode, limiting the
advertising mask in this way is not correct - if the PHY happened to
negotiate 10GBASE-T, and selected 10GBASE-R as the host interface, we
don't want to restrict the advertisement to just 10GBASE-* modes.

Rework setting the advertisement to take account of this; do not pass
the requested advertisement through phylink_validate(), but rely on
the advertisement restriction (supported mask) set when the PHY was
initially setup.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/net/phy/phylink.c | 84 ++++++++++++++++++++++++---------------
 1 file changed, 53 insertions(+), 31 deletions(-)

diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 8d20cf3ba0b7..2e5bc63c1dfa 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -1229,44 +1229,66 @@ int phylink_ethtool_ksettings_set(struct phylink *pl,
 		__set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, config.advertising);
 	}
 
-	if (phylink_validate(pl, support, &config))
-		return -EINVAL;
-
-	/* If autonegotiation is enabled, we must have an advertisement */
-	if (config.an_enabled && phylink_is_empty_linkmode(config.advertising))
-		return -EINVAL;
-
-	our_kset = *kset;
-	linkmode_copy(our_kset.link_modes.advertising, config.advertising);
-	our_kset.base.speed = config.speed;
-	our_kset.base.duplex = config.duplex;
-
-	/* If we have a PHY, configure the phy */
 	if (pl->phydev) {
+		/* If we have a PHY, we process the kset change via phylib.
+		 * phylib will call our link state function if the PHY
+		 * parameters have changed, which will trigger a resolve
+		 * and update the MAC configuration.
+		 */
+		our_kset = *kset;
+		linkmode_copy(our_kset.link_modes.advertising,
+			      config.advertising);
+		our_kset.base.speed = config.speed;
+		our_kset.base.duplex = config.duplex;
+
 		ret = phy_ethtool_ksettings_set(pl->phydev, &our_kset);
 		if (ret)
 			return ret;
-	}
 
-	mutex_lock(&pl->state_mutex);
-	/* Configure the MAC to match the new settings */
-	linkmode_copy(pl->link_config.advertising, our_kset.link_modes.advertising);
-	pl->link_config.interface = config.interface;
-	pl->link_config.speed = our_kset.base.speed;
-	pl->link_config.duplex = our_kset.base.duplex;
-	pl->link_config.an_enabled = our_kset.base.autoneg != AUTONEG_DISABLE;
+		mutex_lock(&pl->state_mutex);
+		/* Save the new configuration */
+		linkmode_copy(pl->link_config.advertising,
+			      our_kset.link_modes.advertising);
+		pl->link_config.interface = config.interface;
+		pl->link_config.speed = our_kset.base.speed;
+		pl->link_config.duplex = our_kset.base.duplex;
+		pl->link_config.an_enabled = our_kset.base.autoneg !=
+					     AUTONEG_DISABLE;
+		mutex_unlock(&pl->state_mutex);
+	} else {
+		/* For a fixed link, this isn't able to change any parameters,
+		 * which just leaves inband mode.
+		 */
+		if (phylink_validate(pl, support, &config))
+			return -EINVAL;
 
-	/* If we have a PHY, phylib will call our link state function if the
-	 * mode has changed, which will trigger a resolve and update the MAC
-	 * configuration. For a fixed link, this isn't able to change any
-	 * parameters, which just leaves inband mode.
-	 */
-	if (pl->cur_link_an_mode == MLO_AN_INBAND &&
-	    !test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) {
-		phylink_mac_config(pl, &pl->link_config);
-		phylink_mac_an_restart(pl);
+		/* If autonegotiation is enabled, we must have an advertisement */
+		if (config.an_enabled &&
+		    phylink_is_empty_linkmode(config.advertising))
+			return -EINVAL;
+
+		mutex_lock(&pl->state_mutex);
+		linkmode_copy(pl->link_config.advertising, config.advertising);
+		pl->link_config.interface = config.interface;
+		pl->link_config.speed = config.speed;
+		pl->link_config.duplex = config.duplex;
+		pl->link_config.an_enabled = kset->base.autoneg !=
+					     AUTONEG_DISABLE;
+
+		if (pl->cur_link_an_mode == MLO_AN_INBAND &&
+		    !test_bit(PHYLINK_DISABLE_STOPPED,
+			      &pl->phylink_disable_state)) {
+			/* If in 802.3z mode, this updates the advertisement.
+			 *
+			 * If we are in SGMII mode without a PHY, there is no
+			 * advertisement; the only thing we have is the pause
+			 * modes which can only come from a PHY.
+			 */
+			phylink_mac_config(pl, &pl->link_config);
+			phylink_mac_an_restart(pl);
+		}
+		mutex_unlock(&pl->state_mutex);
 	}
-	mutex_unlock(&pl->state_mutex);
 
 	return 0;
 }
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH net-next v2 2/3] net: phylink: extend clause 45 PHY validation workaround
  2019-12-13 17:54 [PATCH net-next v2 0/3] improve clause 45 support in phylink Russell King - ARM Linux admin
  2019-12-13 18:22 ` [PATCH net-next v2 1/3] net: phylink: improve clause 45 PHY ksettings_set implementation Russell King
@ 2019-12-13 18:22 ` Russell King
  2019-12-13 18:22 ` [PATCH net-next v2 3/3] net: mvpp2: update mvpp2 validate() implementation Russell King
  2019-12-17 21:26 ` [PATCH net-next v2 0/3] improve clause 45 support in phylink David Miller
  3 siblings, 0 replies; 6+ messages in thread
From: Russell King @ 2019-12-13 18:22 UTC (permalink / raw)
  To: Andrew Lunn, Florian Fainelli, Heiner Kallweit
  Cc: Antoine Tenart, David S. Miller, netdev

Commit e45d1f5288b8 ("net: phylink: support Clause 45 PHYs on SFP+
modules") added a workaround to support clause 45 PHYs which
dynamically switch their interface mode on SFP+ modules.  This was
implemented by validating the PHYs supported/advertising using
PHY_INTERFACE_MODE_NA, rather than the specific interface mode that
we attached the PHY with.

However, we already have a situation where phylink is used to connect
a Marvell 88X3310 PHY which also behaves in exactly the same way, but
which seemingly doesn't need this.  The reason seems to be that the
mvpp2 driver sets a whole bunch of link modes for
PHY_INTERFACE_MODE_10GKR down to 10Mb/s, despite 10GBASE-R not actually
supporting anything but 10Gb/s speeds.

When testing with drivers that (correctly) take the mvneta approach,
where the validate() method only returns what can be supported /
advertised for the specified link mode, we find that Clause 45 PHYs do
not behave as we expect: their advertisement is restricted to what
the current link will support, rather than what the PHY supports
through its dynamic switching.

Extend this workaround to all such cases; if we have a Clause 45 PHY
attaching via any means, except in USXGMII, XAUI and RXAUI which are
all unable to support this dynamic switching or have other solutions
to it, then we need to validate using PHY_INTERFACE_MODE_NA.

This should allow mvpp2 to switch to a more conformant validate()
implementation.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/net/phy/phylink.c | 22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 2e5bc63c1dfa..896772694bf4 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -735,7 +735,19 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy,
 	memset(&config, 0, sizeof(config));
 	linkmode_copy(supported, phy->supported);
 	linkmode_copy(config.advertising, phy->advertising);
-	config.interface = interface;
+
+	/* Clause 45 PHYs switch their Serdes lane between several different
+	 * modes, normally 10GBASE-R, SGMII. Some use 2500BASE-X for 2.5G
+	 * speeds. We really need to know which interface modes the PHY and
+	 * MAC supports to properly work out which linkmodes can be supported.
+	 */
+	if (phy->is_c45 &&
+	    interface != PHY_INTERFACE_MODE_RXAUI &&
+	    interface != PHY_INTERFACE_MODE_XAUI &&
+	    interface != PHY_INTERFACE_MODE_USXGMII)
+		config.interface = PHY_INTERFACE_MODE_NA;
+	else
+		config.interface = interface;
 
 	ret = phylink_validate(pl, supported, &config);
 	if (ret)
@@ -1904,14 +1916,6 @@ static int phylink_sfp_connect_phy(void *upstream, struct phy_device *phy)
 	if (ret < 0)
 		return ret;
 
-	/* Clause 45 PHYs switch their Serdes lane between several different
-	 * modes, normally 10GBASE-R, SGMII. Some use 2500BASE-X for 2.5G
-	 * speeds.  We really need to know which interface modes the PHY and
-	 * MAC supports to properly work out which linkmodes can be supported.
-	 */
-	if (phy->is_c45)
-		interface = PHY_INTERFACE_MODE_NA;
-
 	ret = phylink_bringup_phy(pl, phy, interface);
 	if (ret)
 		phy_detach(phy);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH net-next v2 3/3] net: mvpp2: update mvpp2 validate() implementation
  2019-12-13 17:54 [PATCH net-next v2 0/3] improve clause 45 support in phylink Russell King - ARM Linux admin
  2019-12-13 18:22 ` [PATCH net-next v2 1/3] net: phylink: improve clause 45 PHY ksettings_set implementation Russell King
  2019-12-13 18:22 ` [PATCH net-next v2 2/3] net: phylink: extend clause 45 PHY validation workaround Russell King
@ 2019-12-13 18:22 ` Russell King
  2019-12-17 10:48   ` Antoine Tenart
  2019-12-17 21:26 ` [PATCH net-next v2 0/3] improve clause 45 support in phylink David Miller
  3 siblings, 1 reply; 6+ messages in thread
From: Russell King @ 2019-12-13 18:22 UTC (permalink / raw)
  To: Andrew Lunn, Florian Fainelli, Heiner Kallweit
  Cc: Antoine Tenart, David S. Miller, netdev

Fix up the mvpp2 validate implementation to adopt the same behaviour as
mvneta:
- only allow the link modes that the specified PHY interface mode
  supports with the exception of 1000base-X and 2500base-X.
- use the basex helper to deal with SFP modules that can be switched
  between 1000base-X vs 2500base-X.

This gives consistent behaviour between mvneta and mvpp2.

This commit depends on "net: phylink: extend clause 45 PHY validation
workaround" so is not marked for backporting to stable kernels.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 .../net/ethernet/marvell/mvpp2/mvpp2_main.c   | 22 +++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
index 111b3b8239e1..f09fcbe6ea88 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
@@ -4786,6 +4786,8 @@ static void mvpp2_phylink_validate(struct phylink_config *config,
 			phylink_set(mask, 10000baseER_Full);
 			phylink_set(mask, 10000baseKR_Full);
 		}
+		if (state->interface != PHY_INTERFACE_MODE_NA)
+			break;
 		/* Fall-through */
 	case PHY_INTERFACE_MODE_RGMII:
 	case PHY_INTERFACE_MODE_RGMII_ID:
@@ -4796,13 +4798,23 @@ static void mvpp2_phylink_validate(struct phylink_config *config,
 		phylink_set(mask, 10baseT_Full);
 		phylink_set(mask, 100baseT_Half);
 		phylink_set(mask, 100baseT_Full);
+		phylink_set(mask, 1000baseT_Full);
+		phylink_set(mask, 1000baseX_Full);
+		if (state->interface != PHY_INTERFACE_MODE_NA)
+			break;
 		/* Fall-through */
 	case PHY_INTERFACE_MODE_1000BASEX:
 	case PHY_INTERFACE_MODE_2500BASEX:
-		phylink_set(mask, 1000baseT_Full);
-		phylink_set(mask, 1000baseX_Full);
-		phylink_set(mask, 2500baseT_Full);
-		phylink_set(mask, 2500baseX_Full);
+		if (port->comphy ||
+		    state->interface != PHY_INTERFACE_MODE_2500BASEX) {
+			phylink_set(mask, 1000baseT_Full);
+			phylink_set(mask, 1000baseX_Full);
+		}
+		if (port->comphy ||
+		    state->interface == PHY_INTERFACE_MODE_2500BASEX) {
+			phylink_set(mask, 2500baseT_Full);
+			phylink_set(mask, 2500baseX_Full);
+		}
 		break;
 	default:
 		goto empty_set;
@@ -4811,6 +4823,8 @@ static void mvpp2_phylink_validate(struct phylink_config *config,
 	bitmap_and(supported, supported, mask, __ETHTOOL_LINK_MODE_MASK_NBITS);
 	bitmap_and(state->advertising, state->advertising, mask,
 		   __ETHTOOL_LINK_MODE_MASK_NBITS);
+
+	phylink_helper_basex_speed(state);
 	return;
 
 empty_set:
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH net-next v2 3/3] net: mvpp2: update mvpp2 validate() implementation
  2019-12-13 18:22 ` [PATCH net-next v2 3/3] net: mvpp2: update mvpp2 validate() implementation Russell King
@ 2019-12-17 10:48   ` Antoine Tenart
  0 siblings, 0 replies; 6+ messages in thread
From: Antoine Tenart @ 2019-12-17 10:48 UTC (permalink / raw)
  To: Russell King
  Cc: Andrew Lunn, Florian Fainelli, Heiner Kallweit, Antoine Tenart,
	David S. Miller, netdev

Hello Russell,

On Fri, Dec 13, 2019 at 06:22:12PM +0000, Russell King wrote:
> Fix up the mvpp2 validate implementation to adopt the same behaviour as
> mvneta:
> - only allow the link modes that the specified PHY interface mode
>   supports with the exception of 1000base-X and 2500base-X.
> - use the basex helper to deal with SFP modules that can be switched
>   between 1000base-X vs 2500base-X.
> 
> This gives consistent behaviour between mvneta and mvpp2.
> 
> This commit depends on "net: phylink: extend clause 45 PHY validation
> workaround" so is not marked for backporting to stable kernels.
> 
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>

Acked-by: Antoine Tenart <antoine.tenart@bootlin.com>

Thanks!
Antoine

> ---
>  .../net/ethernet/marvell/mvpp2/mvpp2_main.c   | 22 +++++++++++++++----
>  1 file changed, 18 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
> index 111b3b8239e1..f09fcbe6ea88 100644
> --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
> +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
> @@ -4786,6 +4786,8 @@ static void mvpp2_phylink_validate(struct phylink_config *config,
>  			phylink_set(mask, 10000baseER_Full);
>  			phylink_set(mask, 10000baseKR_Full);
>  		}
> +		if (state->interface != PHY_INTERFACE_MODE_NA)
> +			break;
>  		/* Fall-through */
>  	case PHY_INTERFACE_MODE_RGMII:
>  	case PHY_INTERFACE_MODE_RGMII_ID:
> @@ -4796,13 +4798,23 @@ static void mvpp2_phylink_validate(struct phylink_config *config,
>  		phylink_set(mask, 10baseT_Full);
>  		phylink_set(mask, 100baseT_Half);
>  		phylink_set(mask, 100baseT_Full);
> +		phylink_set(mask, 1000baseT_Full);
> +		phylink_set(mask, 1000baseX_Full);
> +		if (state->interface != PHY_INTERFACE_MODE_NA)
> +			break;
>  		/* Fall-through */
>  	case PHY_INTERFACE_MODE_1000BASEX:
>  	case PHY_INTERFACE_MODE_2500BASEX:
> -		phylink_set(mask, 1000baseT_Full);
> -		phylink_set(mask, 1000baseX_Full);
> -		phylink_set(mask, 2500baseT_Full);
> -		phylink_set(mask, 2500baseX_Full);
> +		if (port->comphy ||
> +		    state->interface != PHY_INTERFACE_MODE_2500BASEX) {
> +			phylink_set(mask, 1000baseT_Full);
> +			phylink_set(mask, 1000baseX_Full);
> +		}
> +		if (port->comphy ||
> +		    state->interface == PHY_INTERFACE_MODE_2500BASEX) {
> +			phylink_set(mask, 2500baseT_Full);
> +			phylink_set(mask, 2500baseX_Full);
> +		}
>  		break;
>  	default:
>  		goto empty_set;
> @@ -4811,6 +4823,8 @@ static void mvpp2_phylink_validate(struct phylink_config *config,
>  	bitmap_and(supported, supported, mask, __ETHTOOL_LINK_MODE_MASK_NBITS);
>  	bitmap_and(state->advertising, state->advertising, mask,
>  		   __ETHTOOL_LINK_MODE_MASK_NBITS);
> +
> +	phylink_helper_basex_speed(state);
>  	return;
>  
>  empty_set:
> -- 
> 2.20.1
> 

-- 
Antoine Ténart, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH net-next v2 0/3] improve clause 45 support in phylink
  2019-12-13 17:54 [PATCH net-next v2 0/3] improve clause 45 support in phylink Russell King - ARM Linux admin
                   ` (2 preceding siblings ...)
  2019-12-13 18:22 ` [PATCH net-next v2 3/3] net: mvpp2: update mvpp2 validate() implementation Russell King
@ 2019-12-17 21:26 ` David Miller
  3 siblings, 0 replies; 6+ messages in thread
From: David Miller @ 2019-12-17 21:26 UTC (permalink / raw)
  To: linux; +Cc: andrew, f.fainelli, hkallweit1, antoine.tenart, netdev

From: Russell King - ARM Linux admin <linux@armlinux.org.uk>
Date: Fri, 13 Dec 2019 17:54:15 +0000

> These three patches improve the clause 45 support in phylink, fixing
> some corner cases that have been noticed with the addition of SFP+
> NBASE-T modules, but are actually a little more wisespread than I
> initially realised.
 ...

Series applied, thank you.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2019-12-17 21:26 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-13 17:54 [PATCH net-next v2 0/3] improve clause 45 support in phylink Russell King - ARM Linux admin
2019-12-13 18:22 ` [PATCH net-next v2 1/3] net: phylink: improve clause 45 PHY ksettings_set implementation Russell King
2019-12-13 18:22 ` [PATCH net-next v2 2/3] net: phylink: extend clause 45 PHY validation workaround Russell King
2019-12-13 18:22 ` [PATCH net-next v2 3/3] net: mvpp2: update mvpp2 validate() implementation Russell King
2019-12-17 10:48   ` Antoine Tenart
2019-12-17 21:26 ` [PATCH net-next v2 0/3] improve clause 45 support in phylink David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).