A port waiting for its PHY reported the MAC's full set of link modes and accepted settings for them, which describes a link that cannot come up. Report an empty set and refuse to configure until the PHY arrives. Every path through net/ethtool/ zeroes the reply before the get op, so the pending path only stamps the unknown speed and duplex. Setting pause parameters needs the same guard, because it is gated on the same MAC-derived mask; reading them does not, since it reports the configured request rather than a capability. The EEE calls need no guard either: they already return -EOPNOTSUPP when no PHY is attached. Assisted-by: LLM Signed-off-by: Aleksei Sviridkin --- drivers/net/phy/phylink.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index bceeac954779..942d5fe943a1 100644 --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c @@ -2290,6 +2290,11 @@ EXPORT_SYMBOL_GPL(phylink_connect_phy); #define PHYLINK_SLOW_PHY_WARN_MS 60000 #define PHYLINK_SLOW_PHY_POLL_MAX_MS 30000 +static bool phylink_slow_phy_pending(struct phylink *pl) +{ + return pl->slow_phy_fwnode && !pl->phydev; +} + /* Bound, not drv: drv is published before the driver's probe runs. The * device lock cannot be taken under rtnl, and losing this race costs a * generic-driver attach, not memory safety. @@ -3087,6 +3092,14 @@ int phylink_ethtool_ksettings_get(struct phylink *pl, ASSERT_RTNL(); + /* No PHY yet: the port supports nothing, not what the MAC alone can. */ + if (phylink_slow_phy_pending(pl)) { + kset->base.port = pl->link_port; + kset->base.speed = SPEED_UNKNOWN; + kset->base.duplex = DUPLEX_UNKNOWN; + return 0; + } + if (pl->phydev) phy_ethtool_ksettings_get(pl->phydev, kset); else @@ -3159,6 +3172,10 @@ int phylink_ethtool_ksettings_set(struct phylink *pl, ASSERT_RTNL(); + /* Would configure the MAC alone, for a link that cannot come up. */ + if (phylink_slow_phy_pending(pl)) + return -EOPNOTSUPP; + if (pl->phydev) { struct ethtool_link_ksettings phy_kset = *kset; @@ -3373,6 +3390,10 @@ int phylink_ethtool_set_pauseparam(struct phylink *pl, if (pl->req_link_an_mode == MLO_AN_FIXED) return -EOPNOTSUPP; + /* pl->supported still describes the MAC, so the test below passes. */ + if (phylink_slow_phy_pending(pl)) + return -EOPNOTSUPP; + if (!phylink_test(pl->supported, Pause) && !phylink_test(pl->supported, Asym_Pause)) return -EOPNOTSUPP; -- 2.53.0