From: Nathan Rossi <nathan.ro...@digi.com> The mv88e6xxx devices cannot automatically select between 1000BASE-X and 2500BASE-X and rely on configuration (gpio pins Px_SMODE/S_MODE and/or OF phy-mode) to select between the two modes.
However when configuring a cpu/dsa port as 1000BASE-X with a inband or fixed link phy the mode is always overridden to 2500BASE-X by the call of phylink_helper_basex_speed in phylink_validate due to the order of setup with respect to advertised modes and auto negotiation being enabled. During the initial setup of the phy the phy-mode property defined for the port is configured before any calls to phylink_validate. The first call to phylink_validate sets the advertised modes to all valid modes and phylink_validate masks to supported modes, for the ports that support 1000BASE-X/2500BASE-X both are advertised. At this stage the speed is not yet configured and the phylink_helper_basex_speed function overrides the mode to 2500BASE-X due to all modes being advertised and auto negotiation being enabled. After the speed is configured phylink_validate is called again, the same logic applies and the mode is set to 2500BASE-X (due to auto negotiation). As such it is not possible for a fixed link to be configured as 1000BASE-X, as the mode cannot be configured (e.g. via phy-mode property) and the link cannot be automatically selected as 1000BASE-X. This change prevents the advertising of 2500BASE-X when the port is already configured for 1000BASE-X, which in turn prevents the phylink_helper_basex_speed from always overriding to 2500BASE-X. This allows for the mode to correctly propagate from the phy-mode property to the port configuration. Signed-off-by: Nathan Rossi <nathan.ro...@digi.com> --- drivers/net/dsa/mv88e6xxx/chip.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 54aa942eed..5c52906b29 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -650,6 +650,13 @@ static void mv88e6xxx_validate(struct dsa_switch *ds, int port, if (chip->info->ops->phylink_validate) chip->info->ops->phylink_validate(chip, port, mask, state); + /* Advertise 2500BASEX only if 1000BASEX is not configured, this + * prevents phylink_helper_basex_speed from always overriding the + * 1000BASEX mode since auto negotiation is always enabled. + */ + if (state->interface == PHY_INTERFACE_MODE_1000BASEX) + phylink_clear(mask, 2500baseX_Full); + bitmap_and(supported, supported, mask, __ETHTOOL_LINK_MODE_MASK_NBITS); bitmap_and(state->advertising, state->advertising, mask, __ETHTOOL_LINK_MODE_MASK_NBITS); --- 2.30.0