diff mbox series

[net-next,3/6] net: phylink: Correctly handle PCS probe defer from PCS provider

Message ID 20250318235850.6411-4-ansuelsmth@gmail.com (mailing list archive)
State New
Delegated to: Netdev Maintainers
Headers show
Series net: pcs: Introduce support for PCS OF | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for net-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 2 this patch: 2
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers warning 1 maintainers not CCed: andrew@lunn.ch
netdev/build_clang success Errors and warnings before: 2 this patch: 2
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 2 this patch: 2
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 34 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 19 this patch: 19
netdev/source_inline success Was 0 now: 0

Commit Message

Christian Marangi March 18, 2025, 11:58 p.m. UTC
On using OF PCS implementation, it can happen that the PCS driver still
needs to be probed at the time the MAC driver calls .mac_select_pcs.

In such case, PCS provider will return probe defer as the PCS can't be
found in the global provider list. It's expected the MAC driver to
retry probing at a later time when the PCS driver is actually probed.

To handle this, check the return value of phylink_validate (that will
call mac_select_pcs to validate the interface) in phylink_create and
make phylink_create return -EPROBE_DEFER. The MAC driver will check this
return value and retry probing.

PCS can be removed unexpectedly at later time (driver gets removed) and
not available anymore. In such case, PCS provider will also return probe
defer as the PCS can't be found in the global provider list. (as the PCS
driver on removal will delete itself as PCS provider)

To communicate correct error message, in phylink_major_config() detect
this condition and treat -EPROBE_DEFER error from .mac_select_pcs as
-ENOENT as probe defer is only allowed at probe stage.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
 drivers/net/phy/phylink.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 7f71547e89fe..c6d9e4efed13 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -1395,6 +1395,15 @@  static void phylink_major_config(struct phylink *pl, bool restart,
 	if (pl->mac_ops->mac_select_pcs) {
 		pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface);
 		if (IS_ERR(pcs)) {
+			/* PCS can be removed unexpectedly and not available
+			 * anymore.
+			 * PCS provider will return probe defer as the PCS
+			 * can't be found in the global provider list.
+			 * In such case, return -ENOENT as a more symbolic name
+			 * for the error message.
+			 */
+			if (PTR_ERR(pcs) == -EPROBE_DEFER)
+				pcs = ERR_PTR(-ENOENT);
 			phylink_err(pl,
 				    "mac_select_pcs unexpectedly failed: %pe\n",
 				    pcs);
@@ -2004,7 +2013,18 @@  struct phylink *phylink_create(struct phylink_config *config,
 
 	linkmode_fill(pl->supported);
 	linkmode_copy(pl->link_config.advertising, pl->supported);
-	phylink_validate(pl, pl->supported, &pl->link_config);
+	ret = phylink_validate(pl, pl->supported, &pl->link_config);
+	/* The PCS might not available at the time phylink_create
+	 * is called. Check this and communicate to the MAC driver
+	 * that probe should be retried later.
+	 *
+	 * Notice that this can only happen in probe stage and PCS
+	 * is expected to be avaialble in phylink_major_config.
+	 */
+	if (ret == -EPROBE_DEFER) {
+		kfree(pl);
+		return ERR_PTR(ret);
+	}
 
 	ret = phylink_parse_mode(pl, fwnode);
 	if (ret < 0) {