From nobody Wed Oct 1 22:26:27 2025 Received: from pandora.armlinux.org.uk (pandora.armlinux.org.uk [78.32.30.218]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 32D252BF00A; Sun, 28 Sep 2025 08:59:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=78.32.30.218 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759049961; cv=none; b=FM/vchsDrlSMAXLy0e7bqUo5ZEJblzHF0AQrpV1+/LnkK5WR1vjQf+7BHt3BByEyaSu/DpdN4FLQpKgYcc03JMn4nTR6+C3yxAvJ73tdNiRYjR4CVlBlpA/KmsioRDNAwF4rqAyxW2wAgcUIErXycP9NujLuV5JMADyzEU0GrMI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759049961; c=relaxed/simple; bh=7xTnRXG0VOxNuO0hi/wTWjNgiWGT5a1unwsIKyZI9tw=; h=In-Reply-To:References:From:To:Cc:Subject:MIME-Version: Content-Disposition:Content-Type:Message-Id:Date; b=meP5d9HhO0cEC28Uq632ZqxSWCZ0D4Y1nhuJ9136iWyOZOueQBQ+w4Ljlv+ndpTtJ2mFcpksjLiYDoMPUyeg7elZB/3cTx63jaHcoUl320vI8e3+BZi9in1cu+13rW3plvuQCEL4QqBVcO3+RGoJlTc0KAkauDYLPSrtn58+fi0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=armlinux.org.uk; spf=none smtp.mailfrom=armlinux.org.uk; dkim=pass (2048-bit key) header.d=armlinux.org.uk header.i=@armlinux.org.uk header.b=aHdaB0Iz; arc=none smtp.client-ip=78.32.30.218 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=armlinux.org.uk Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=armlinux.org.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=armlinux.org.uk header.i=@armlinux.org.uk header.b="aHdaB0Iz" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=armlinux.org.uk; s=pandora-2019; h=Date:Sender:Message-Id:Content-Type: Content-Transfer-Encoding:MIME-Version:Subject:Cc:To:From:References: In-Reply-To:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=mV9Xx0e2xiFAQKlX3WQG8ifo/vHNogs8i5Upjp7iN6U=; b=aHdaB0IzQK+eNrGguUy4O73kcv CmaePoFrti0sL3Dv+J6nXqGKjuPsvZxUlDHYCiX3Ly9x0DeDLDltjmt2EbQHk97YxibEVcekwXZn8 eAkPoWrv0ZtG82b/7WRVSLJsQO8H46L4T7FEzVrH0iQw6iqVp2HX+MEq1Fx8qSo+fXB9bBQNKD/QE 3lRLlZRwxlOYWIxShkgHLeI83HLVn5m5UXqOlXx3eVhZULpizg40WedWAbyiML8nFhEI6ojrOvnJ9 L79gR3bA5G93Qg3E8smKShafWqFF83wy7CyaKLTtxsadJnKrSTYciwyksa1VdXAS6LjriXtG6z9O6 xKjhWK7w==; Received: from e0022681537dd.dyn.armlinux.org.uk ([fd8f:7570:feb6:1:222:68ff:fe15:37dd]:36018 helo=rmk-PC.armlinux.org.uk) by pandora.armlinux.org.uk with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.98.2) (envelope-from ) id 1v2nFJ-000000005Ay-1nKn; Sun, 28 Sep 2025 09:59:06 +0100 Received: from rmk by rmk-PC.armlinux.org.uk with local (Exim 4.98.2) (envelope-from ) id 1v2nFI-00000007jXV-1BYa; Sun, 28 Sep 2025 09:59:04 +0100 In-Reply-To: References: From: "Russell King (Oracle)" To: Andrew Lunn , Heiner Kallweit , Florian Fainelli , Gatien Chevallier Cc: Alexandre Torgue , Andrew Lunn , Andrew Lunn , Christophe Roullier , Conor Dooley , "David S. Miller" , devicetree@vger.kernel.org, Eric Dumazet , Heiner Kallweit , Jakub Kicinski , Krzysztof Kozlowski , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com, Maxime Coquelin , netdev@vger.kernel.org, Paolo Abeni , Rob Herring , Simon Horman , Tristram Ha Subject: [PATCH RFC net-next 3/6] net: phylink: add phylink managed MAC Wake-on-Lan support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Message-Id: Sender: Russell King Date: Sun, 28 Sep 2025 09:59:04 +0100 Add core phylink Wake-on-Lan support. Signed-off-by: Russell King (Oracle) --- drivers/net/phy/phylink.c | 77 +++++++++++++++++++++++++++++++++++++-- include/linux/phylink.h | 26 +++++++++++++ 2 files changed, 99 insertions(+), 4 deletions(-) diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index 9d7799ea1c17..9a3783e719bc 100644 --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c @@ -93,6 +93,9 @@ struct phylink { u8 sfp_port; =20 struct eee_config eee_cfg; + + u32 wolopts_mac; + u8 wol_sopass[SOPASS_MAX]; }; =20 #define phylink_printk(level, pl, fmt, ...) \ @@ -2575,11 +2578,17 @@ EXPORT_SYMBOL_GPL(phylink_rx_clk_stop_unblock); * can also bring down the link between the MAC and PHY. * - If Wake-on-Lan is active, but being handled by the MAC, the MAC * still needs to receive packets, so we can not bring the link down. + * + * Note: when phylink managed Wake-on-Lan is in use, @mac_wol is ignored. + * (struct phylink_mac_ops.mac_set_wol populated.) */ void phylink_suspend(struct phylink *pl, bool mac_wol) { ASSERT_RTNL(); =20 + if (phylink_mac_supports_wol(pl)) + mac_wol =3D !!pl->wolopts_mac; + if (mac_wol && (!pl->netdev || pl->netdev->ethtool->wol_enabled)) { /* Wake-on-Lan enabled, MAC handling */ mutex_lock(&pl->state_mutex); @@ -2673,6 +2682,17 @@ void phylink_resume(struct phylink *pl) } EXPORT_SYMBOL_GPL(phylink_resume); =20 +static bool phylink_mac_supports_wol(struct phylink *pl) +{ + return !!pl->mac_ops->mac_wol_set; +} + +static bool phylink_phy_supports_wol(struct phylink *pl, + struct phy_device *phydev) +{ + return phydev && (pl->config->wol_phy_legacy || phy_can_wakeup(phydev)); +} + /** * phylink_ethtool_get_wol() - get the wake on lan parameters for the PHY * @pl: a pointer to a &struct phylink returned from phylink_create() @@ -2689,8 +2709,21 @@ void phylink_ethtool_get_wol(struct phylink *pl, str= uct ethtool_wolinfo *wol) wol->supported =3D 0; wol->wolopts =3D 0; =20 - if (pl->phydev) - phy_ethtool_get_wol(pl->phydev, wol); + if (phylink_mac_supports_wol(pl)) { + if (phylink_phy_supports_wol(pl, pl->phydev)) + phy_ethtool_get_wol(pl->phydev, wol); + + /* Where the MAC augments the WoL support, merge its support and + * current configuration. + */ + wol->supported |=3D pl->config->wol_mac_support; + wol->wolopts |=3D pl->wolopts_mac; + memcpy(wol->sopass, pl->wol_sopass, sizeof(wol->sopass)); + } else { + /* Legacy */ + if (pl->phydev) + phy_ethtool_get_wol(pl->phydev, wol); + } } EXPORT_SYMBOL_GPL(phylink_ethtool_get_wol); =20 @@ -2707,12 +2740,48 @@ EXPORT_SYMBOL_GPL(phylink_ethtool_get_wol); */ int phylink_ethtool_set_wol(struct phylink *pl, struct ethtool_wolinfo *wo= l) { + struct ethtool_wolinfo w; int ret =3D -EOPNOTSUPP; + bool changed; + u32 wolopts; =20 ASSERT_RTNL(); =20 - if (pl->phydev) - ret =3D phy_ethtool_set_wol(pl->phydev, wol); + if (phylink_mac_supports_wol(pl)) { + wolopts =3D wol->wolopts; + + if (phylink_phy_supports_wol(pl, pl->phydev)) { + ret =3D phy_ethtool_set_wol(pl->phydev, wol); + if (ret !=3D 0 && ret !=3D -EOPNOTSUPP) + return ret; + + phy_ethtool_get_wol(pl->phydev, &w); + + /* Any Wake-on-Lan modes which the PHY is handling + * should not be passed on to the MAC. + */ + wolopts &=3D ~w.wolopts; + } + + wolopts &=3D pl->config->wol_mac_support; + changed =3D pl->wolopts_mac !=3D wolopts; + if (wolopts & WAKE_MAGICSECURE) + changed |=3D !!memcmp(wol->sopass, pl->wol_sopass, + sizeof(wol->sopass)); + memcpy(pl->wol_sopass, wol->sopass, sizeof(pl->wol_sopass)); + + if (changed) { + ret =3D pl->mac_ops->mac_wol_set(pl->config, wolopts, + wol->sopass); + if (!ret) + pl->wolopts_mac =3D wolopts; + } else { + ret =3D 0; + } + } else { + if (pl->phydev) + ret =3D phy_ethtool_set_wol(pl->phydev, wol); + } =20 return ret; } diff --git a/include/linux/phylink.h b/include/linux/phylink.h index 9af0411761d7..59cb58b29d1d 100644 --- a/include/linux/phylink.h +++ b/include/linux/phylink.h @@ -156,6 +156,8 @@ enum phylink_op_type { * @lpi_capabilities: MAC speeds which can support LPI signalling * @lpi_timer_default: Default EEE LPI timer setting. * @eee_enabled_default: If set, EEE will be enabled by phylink at creatio= n time + * @wol_phy_legacy: Use Wake-on-Lan with PHY even if phy_can_wakeup() is f= alse + * @wol_mac_support: Bitmask of MAC supported %WAKE_* options */ struct phylink_config { struct device *dev; @@ -173,6 +175,10 @@ struct phylink_config { unsigned long lpi_capabilities; u32 lpi_timer_default; bool eee_enabled_default; + + /* Wake-on-Lan support */ + bool wol_phy_legacy; + u32 wol_mac_support; }; =20 void phylink_limit_mac_speed(struct phylink_config *config, u32 max_speed); @@ -188,6 +194,7 @@ void phylink_limit_mac_speed(struct phylink_config *con= fig, u32 max_speed); * @mac_link_up: allow the link to come up. * @mac_disable_tx_lpi: disable LPI. * @mac_enable_tx_lpi: enable and configure LPI. + * @mac_wol_set: configure Wake-on-Lan settings at the MAC. * * The individual methods are described more fully below. */ @@ -211,6 +218,9 @@ struct phylink_mac_ops { void (*mac_disable_tx_lpi)(struct phylink_config *config); int (*mac_enable_tx_lpi)(struct phylink_config *config, u32 timer, bool tx_clk_stop); + + int (*mac_wol_set)(struct phylink_config *config, u32 wolopts, + const u8 *sopass); }; =20 #if 0 /* For kernel-doc purposes only. */ @@ -440,6 +450,22 @@ void mac_disable_tx_lpi(struct phylink_config *config); */ int mac_enable_tx_lpi(struct phylink_config *config, u32 timer, bool tx_clk_stop); + +/** + * mac_wol_set() - configure the Wake-on-Lan parameters + * @config: a pointer to a &struct phylink_config. + * @wolopts: Bitmask of %WAKE_* flags for enabled Wake-On-Lan modes. + * @sopass: SecureOn(tm) password; meaningful only for %WAKE_MAGICSECURE + * + * Enable the specified Wake-on-Lan options at the MAC. Options that the + * PHY can handle will have been removed from @wolopts. + * + * The presence of this method enables phylink-managed WoL support. + * + * Returns: 0 on success. + */ +int (*mac_wol_set)(struct phylink_config *config, u32 wolopts, + const u8 *sopass); #endif =20 struct phylink_pcs_ops; --=20 2.47.3