net: phylink: actually fix ksettings_set() ethtool call
authorRussell King (Oracle) <rmk+kernel@armlinux.org.uk>
Thu, 1 Jun 2023 09:12:06 +0000 (10:12 +0100)
committerJakub Kicinski <kuba@kernel.org>
Sat, 3 Jun 2023 06:49:56 +0000 (23:49 -0700)
Raju Lakkaraju reported that the below commit caused a regression
with Lan743x drivers and a 2.5G SFP. Sadly, this is because the commit
was utterly wrong. Let's fix this properly by not moving the
linkmode_and(), but instead copying the link ksettings and then
modifying the advertising mask before passing the modified link
ksettings to phylib.

Fixes: df0acdc59b09 ("net: phylink: fix ksettings_set() ethtool call")
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Link: https://lore.kernel.org/r/E1q4eLm-00Ayxk-GZ@rmk-PC.armlinux.org.uk
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/phy/phylink.c

index e237949..b483111 100644 (file)
@@ -2225,11 +2225,13 @@ int phylink_ethtool_ksettings_set(struct phylink *pl,
 
        ASSERT_RTNL();
 
-       /* Mask out unsupported advertisements */
-       linkmode_and(config.advertising, kset->link_modes.advertising,
-                    pl->supported);
-
        if (pl->phydev) {
+               struct ethtool_link_ksettings phy_kset = *kset;
+
+               linkmode_and(phy_kset.link_modes.advertising,
+                            phy_kset.link_modes.advertising,
+                            pl->supported);
+
                /* We can rely on phylib for this update; we also do not need
                 * to update the pl->link_config settings:
                 * - the configuration returned via ksettings_get() will come
@@ -2248,10 +2250,13 @@ int phylink_ethtool_ksettings_set(struct phylink *pl,
                 *   the presence of a PHY, this should not be changed as that
                 *   should be determined from the media side advertisement.
                 */
-               return phy_ethtool_ksettings_set(pl->phydev, kset);
+               return phy_ethtool_ksettings_set(pl->phydev, &phy_kset);
        }
 
        config = pl->link_config;
+       /* Mask out unsupported advertisements */
+       linkmode_and(config.advertising, kset->link_modes.advertising,
+                    pl->supported);
 
        /* FIXME: should we reject autoneg if phy/mac does not support it? */
        switch (kset->base.autoneg) {