* [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