From: Carlo Szelinsky <github@szelinsky.de>
To: Kory Maincent <kory.maincent@bootlin.com>,
Oleksij Rempel <o.rempel@pengutronix.de>,
Andrew Lunn <andrew+netdev@lunn.ch>
Cc: Heiner Kallweit <hkallweit1@gmail.com>,
Russell King <linux@armlinux.org.uk>,
Jakub Kicinski <kuba@kernel.org>,
"David S . Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Paolo Abeni <pabeni@redhat.com>, Simon Horman <horms@kernel.org>,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
Carlo Szelinsky <github@szelinsky.de>
Subject: [PATCH 3/3] net: pse-pd: add lazy PSE control resolution for modular drivers
Date: Sun, 29 Mar 2026 18:10:14 +0200 [thread overview]
Message-ID: <20260329161014.2908509-4-github@szelinsky.de> (raw)
In-Reply-To: <20260329161014.2908509-1-github@szelinsky.de>
When a PSE controller driver is built as a module and was not probed
during PHY registration, the PHY ends up with psec=NULL. Add
pse_control_try_resolve() to lazily resolve the PSE control on first
ethtool access.
Call pse_control_try_resolve() in both the GET and SET ethtool PSE
handlers, before checking phydev->psec. The function is serialized by
RTNL (enforced via ASSERT_RTNL), preventing concurrent callers from
double-allocating a PSE control.
If resolution fails (e.g. the module still has not loaded), a debug
message is emitted via phydev_dbg() and the handler falls through to
the existing "No PSE is attached" error path.
Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
---
drivers/net/pse-pd/pse_core.c | 36 +++++++++++++++++++++++++++++++++++
include/linux/pse-pd/pse.h | 5 +++++
net/ethtool/pse-pd.c | 4 ++++
3 files changed, 45 insertions(+)
diff --git a/drivers/net/pse-pd/pse_core.c b/drivers/net/pse-pd/pse_core.c
index 566b07c336bf..390df23a991c 100644
--- a/drivers/net/pse-pd/pse_core.c
+++ b/drivers/net/pse-pd/pse_core.c
@@ -1569,6 +1569,42 @@ struct pse_control *of_pse_control_get(struct device_node *node,
}
EXPORT_SYMBOL_GPL(of_pse_control_get);
+/**
+ * pse_control_try_resolve - attempt to resolve a deferred PSE control
+ * @phydev: the PHY device whose PSE control may need resolution
+ *
+ * When a PSE controller driver is built as a module, it may not have
+ * probed when PHYs were registered on the MDIO bus. This function
+ * retries PSE control acquisition and should be called before
+ * accessing phydev->psec in ethtool handlers.
+ *
+ * Context: Caller must hold RTNL.
+ */
+void pse_control_try_resolve(struct phy_device *phydev)
+{
+ struct device_node *np;
+ struct pse_control *psec;
+
+ ASSERT_RTNL();
+
+ if (phydev->psec)
+ return;
+
+ np = phydev->mdio.dev.of_node;
+ if (!np || !of_property_present(np, "pses"))
+ return;
+
+ psec = of_pse_control_get(np, phydev);
+ if (IS_ERR(psec)) {
+ phydev_dbg(phydev, "failed to resolve PSE control: %pe\n",
+ psec);
+ return;
+ }
+
+ phydev->psec = psec;
+}
+EXPORT_SYMBOL_GPL(pse_control_try_resolve);
+
/**
* pse_get_sw_admin_state - Convert the software admin state to c33 or podl
* admin state value used in the standard
diff --git a/include/linux/pse-pd/pse.h b/include/linux/pse-pd/pse.h
index b86cce740551..d2f9b7c1acdf 100644
--- a/include/linux/pse-pd/pse.h
+++ b/include/linux/pse-pd/pse.h
@@ -350,6 +350,7 @@ int devm_pse_irq_helper(struct pse_controller_dev *pcdev, int irq,
struct pse_control *of_pse_control_get(struct device_node *node,
struct phy_device *phydev);
void pse_control_put(struct pse_control *psec);
+void pse_control_try_resolve(struct phy_device *phydev);
int pse_ethtool_get_status(struct pse_control *psec,
struct netlink_ext_ack *extack,
@@ -379,6 +380,10 @@ static inline void pse_control_put(struct pse_control *psec)
{
}
+static inline void pse_control_try_resolve(struct phy_device *phydev)
+{
+}
+
static inline int pse_ethtool_get_status(struct pse_control *psec,
struct netlink_ext_ack *extack,
struct ethtool_pse_control_status *status)
diff --git a/net/ethtool/pse-pd.c b/net/ethtool/pse-pd.c
index 2eb9bdc2dcb9..adffc230acd6 100644
--- a/net/ethtool/pse-pd.c
+++ b/net/ethtool/pse-pd.c
@@ -42,6 +42,8 @@ static int pse_get_pse_attributes(struct phy_device *phydev,
return -EOPNOTSUPP;
}
+ pse_control_try_resolve(phydev);
+
if (!phydev->psec) {
NL_SET_ERR_MSG(extack, "No PSE is attached");
return -EOPNOTSUPP;
@@ -249,6 +251,8 @@ ethnl_set_pse_validate(struct phy_device *phydev, struct genl_info *info)
return -EOPNOTSUPP;
}
+ pse_control_try_resolve(phydev);
+
if (!phydev->psec) {
NL_SET_ERR_MSG(info->extack, "No PSE is attached");
return -EOPNOTSUPP;
--
2.43.0
next prev parent reply other threads:[~2026-03-29 16:10 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-29 16:10 [PATCH 0/3] net: pse-pd: support module-based PSE controller drivers Carlo Szelinsky
2026-03-29 16:10 ` [PATCH 1/3] net: mdio: treat PSE EPROBE_DEFER as non-fatal during PHY registration Carlo Szelinsky
2026-03-30 11:16 ` Kory Maincent
2026-03-29 16:10 ` [PATCH 2/3] net: pse-pd: prevent regulator cleanup from disabling unclaimed PSE PIs Carlo Szelinsky
2026-03-30 11:17 ` Kory Maincent
2026-03-29 16:10 ` Carlo Szelinsky [this message]
2026-03-30 11:23 ` [PATCH 3/3] net: pse-pd: add lazy PSE control resolution for modular drivers Kory Maincent
2026-03-30 11:09 ` [PATCH 0/3] net: pse-pd: support module-based PSE controller drivers Kory Maincent
2026-03-30 13:29 ` [PATCH net-next v2 " Carlo Szelinsky
2026-03-30 13:29 ` [PATCH net-next v2 1/3] net: pse-pd: prevent regulator cleanup from disabling unclaimed PSE PIs Carlo Szelinsky
2026-04-01 2:28 ` Jakub Kicinski
2026-04-06 10:22 ` Oleksij Rempel
2026-03-30 13:29 ` [PATCH net-next v2 2/3] net: pse-pd: add lazy PSE control resolution for modular drivers Carlo Szelinsky
2026-03-30 13:29 ` [PATCH net-next v2 3/3] net: mdio: treat PSE EPROBE_DEFER as non-fatal during PHY registration Carlo Szelinsky
2026-03-30 14:11 ` Andrew Lunn
2026-04-03 13:31 ` Carlo Szelinsky
2026-04-03 13:38 ` Kory Maincent
2026-04-06 8:42 ` Oleksij Rempel
2026-04-07 9:31 ` Kory Maincent
2026-04-03 15:16 ` Andrew Lunn
2026-04-05 18:57 ` Carlo Szelinsky
2026-04-06 9:30 ` Oleksij Rempel
2026-04-06 12:22 ` Andrew Lunn
2026-04-06 14:12 ` Oleksij Rempel
2026-04-07 9:40 ` Kory Maincent
2026-04-06 12:42 ` Andrew Lunn
2026-04-06 14:43 ` Carlo Szelinsky
2026-04-06 15:21 ` Andrew Lunn
2026-04-08 21:07 ` Carlo Szelinsky
2026-04-08 21:56 ` Andrew Lunn
2026-04-09 12:30 ` Andrew Lunn
2026-04-09 13:09 ` Kory Maincent
2026-04-09 15:34 ` Andrew Lunn
2026-04-09 16:08 ` Russell King (Oracle)
2026-04-09 19:54 ` Andrew Lunn
2026-04-13 9:28 ` Kory Maincent
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260329161014.2908509-4-github@szelinsky.de \
--to=github@szelinsky.de \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=hkallweit1@gmail.com \
--cc=horms@kernel.org \
--cc=kory.maincent@bootlin.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=netdev@vger.kernel.org \
--cc=o.rempel@pengutronix.de \
--cc=pabeni@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.