Commit f193786d authored by Russell King's avatar Russell King Committed by Greg Kroah-Hartman

net: phylink: avoid reducing support mask

[ Upstream commit 77316763 ]

Avoid reducing the support mask as a result of the interface type
selected for SFP modules, or when setting the link settings through
ethtool - this should only change when the supported link modes of
the hardware combination change.
Signed-off-by: default avatarRussell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent f743ff59
...@@ -1080,6 +1080,7 @@ EXPORT_SYMBOL_GPL(phylink_ethtool_ksettings_get); ...@@ -1080,6 +1080,7 @@ EXPORT_SYMBOL_GPL(phylink_ethtool_ksettings_get);
int phylink_ethtool_ksettings_set(struct phylink *pl, int phylink_ethtool_ksettings_set(struct phylink *pl,
const struct ethtool_link_ksettings *kset) const struct ethtool_link_ksettings *kset)
{ {
__ETHTOOL_DECLARE_LINK_MODE_MASK(support);
struct ethtool_link_ksettings our_kset; struct ethtool_link_ksettings our_kset;
struct phylink_link_state config; struct phylink_link_state config;
int ret; int ret;
...@@ -1090,11 +1091,12 @@ int phylink_ethtool_ksettings_set(struct phylink *pl, ...@@ -1090,11 +1091,12 @@ int phylink_ethtool_ksettings_set(struct phylink *pl,
kset->base.autoneg != AUTONEG_ENABLE) kset->base.autoneg != AUTONEG_ENABLE)
return -EINVAL; return -EINVAL;
linkmode_copy(support, pl->supported);
config = pl->link_config; config = pl->link_config;
/* Mask out unsupported advertisements */ /* Mask out unsupported advertisements */
linkmode_and(config.advertising, kset->link_modes.advertising, linkmode_and(config.advertising, kset->link_modes.advertising,
pl->supported); support);
/* FIXME: should we reject autoneg if phy/mac does not support it? */ /* FIXME: should we reject autoneg if phy/mac does not support it? */
if (kset->base.autoneg == AUTONEG_DISABLE) { if (kset->base.autoneg == AUTONEG_DISABLE) {
...@@ -1104,7 +1106,7 @@ int phylink_ethtool_ksettings_set(struct phylink *pl, ...@@ -1104,7 +1106,7 @@ int phylink_ethtool_ksettings_set(struct phylink *pl,
* duplex. * duplex.
*/ */
s = phy_lookup_setting(kset->base.speed, kset->base.duplex, s = phy_lookup_setting(kset->base.speed, kset->base.duplex,
pl->supported, false); support, false);
if (!s) if (!s)
return -EINVAL; return -EINVAL;
...@@ -1133,7 +1135,7 @@ int phylink_ethtool_ksettings_set(struct phylink *pl, ...@@ -1133,7 +1135,7 @@ int phylink_ethtool_ksettings_set(struct phylink *pl,
__set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, config.advertising); __set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, config.advertising);
} }
if (phylink_validate(pl, pl->supported, &config)) if (phylink_validate(pl, support, &config))
return -EINVAL; return -EINVAL;
/* If autonegotiation is enabled, we must have an advertisement */ /* If autonegotiation is enabled, we must have an advertisement */
...@@ -1583,6 +1585,7 @@ static int phylink_sfp_module_insert(void *upstream, ...@@ -1583,6 +1585,7 @@ static int phylink_sfp_module_insert(void *upstream,
{ {
struct phylink *pl = upstream; struct phylink *pl = upstream;
__ETHTOOL_DECLARE_LINK_MODE_MASK(support) = { 0, }; __ETHTOOL_DECLARE_LINK_MODE_MASK(support) = { 0, };
__ETHTOOL_DECLARE_LINK_MODE_MASK(support1);
struct phylink_link_state config; struct phylink_link_state config;
phy_interface_t iface; phy_interface_t iface;
int ret = 0; int ret = 0;
...@@ -1610,6 +1613,8 @@ static int phylink_sfp_module_insert(void *upstream, ...@@ -1610,6 +1613,8 @@ static int phylink_sfp_module_insert(void *upstream,
return ret; return ret;
} }
linkmode_copy(support1, support);
iface = sfp_select_interface(pl->sfp_bus, id, config.advertising); iface = sfp_select_interface(pl->sfp_bus, id, config.advertising);
if (iface == PHY_INTERFACE_MODE_NA) { if (iface == PHY_INTERFACE_MODE_NA) {
netdev_err(pl->netdev, netdev_err(pl->netdev,
...@@ -1619,7 +1624,7 @@ static int phylink_sfp_module_insert(void *upstream, ...@@ -1619,7 +1624,7 @@ static int phylink_sfp_module_insert(void *upstream,
} }
config.interface = iface; config.interface = iface;
ret = phylink_validate(pl, support, &config); ret = phylink_validate(pl, support1, &config);
if (ret) { if (ret) {
netdev_err(pl->netdev, "validation of %s/%s with support %*pb failed: %d\n", netdev_err(pl->netdev, "validation of %s/%s with support %*pb failed: %d\n",
phylink_an_mode_str(MLO_AN_INBAND), phylink_an_mode_str(MLO_AN_INBAND),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment