[net-next RFC PATCH v5 01/10] net: phylink: keep and use MAC supported_interfaces in phylink struct

Christian Marangi
2026-05-05T18:27:28Z

Add in phylink struct a copy of supported_interfaces from phylink_config
and make use of that instead of relying on phylink_config value.

This in preparation for support of PCS handling internally to phylink
where a PCS can be removed or added after the phylink is created and we
need both a reference of the supported_interfaces value from
phylink_config and an internal value that can be updated with the new
PCS info.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
drivers/net/phy/phylink.c | 22 +++++++++++++++-------
1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 087ac63f9193..4d59c0dd78db 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -60,6 +60,11 @@ struct phylink {
/* The link configuration settings */
struct phylink_link_state link_config;

+ /* What interface are supported by the current link.
+ * Can change on removal or addition of new PCS.
+ */
+ DECLARE_PHY_INTERFACE_MASK(supported_interfaces);
+
/* The current settings */
phy_interface_t cur_interface;

@@ -629,7 +634,7 @@ static int phylink_validate_mask(struct phylink *pl, struct phy_device *phy,
static int phylink_validate(struct phylink *pl, unsigned long *supported,
struct phylink_link_state *state)
{
- const unsigned long *interfaces = pl->config->supported_interfaces;
+ const unsigned long *interfaces = pl->supported_interfaces;

if (state->interface == PHY_INTERFACE_MODE_NA)
return phylink_validate_mask(pl, NULL, supported, state,
@@ -1868,6 +1873,9 @@ struct phylink *phylink_create(struct phylink_config *config,
mutex_init(&pl->state_mutex);
INIT_WORK(&pl->resolve, phylink_resolve);

+ phy_interface_copy(pl->supported_interfaces,
+ config->supported_interfaces);
+
pl->config = config;
if (config->type == PHYLINK_NETDEV) {
pl->netdev = to_net_dev(config->dev);
@@ -2026,7 +2034,7 @@ static int phylink_validate_phy(struct phylink *pl, struct phy_device *phy,
* those which the host supports.
*/
phy_interface_and(interfaces, phy->possible_interfaces,
- pl->config->supported_interfaces);
+ pl->supported_interfaces);

if (phy_interface_empty(interfaces)) {
phylink_err(pl, "PHY has no common interfaces\n");
@@ -2828,12 +2836,12 @@ static phy_interface_t phylink_sfp_select_interface(struct phylink *pl,
return interface;
}

- if (!test_bit(interface, pl->config->supported_interfaces)) {
+ if (!test_bit(interface, pl->supported_interfaces)) {
phylink_err(pl,
"selection of interface failed, SFP selected %s (%u) but MAC supports %*pbl\n",
phy_modes(interface), interface,
(int)PHY_INTERFACE_MODE_MAX,
- pl->config->supported_interfaces);
+ pl->supported_interfaces);
return PHY_INTERFACE_MODE_NA;
}

@@ -3761,14 +3769,14 @@ static int phylink_sfp_config_optical(struct phylink *pl)

phylink_dbg(pl, "optical SFP: interfaces=[mac=%*pbl, sfp=%*pbl]\n",
(int)PHY_INTERFACE_MODE_MAX,
- pl->config->supported_interfaces,
+ pl->supported_interfaces,
(int)PHY_INTERFACE_MODE_MAX,
pl->sfp_interfaces);

/* Find the union of the supported interfaces by the PCS/MAC and
* the SFP module.
*/
- phy_interface_and(pl->sfp_interfaces, pl->config->supported_interfaces,
+ phy_interface_and(pl->sfp_interfaces, pl->supported_interfaces,
pl->sfp_interfaces);
if (phy_interface_empty(pl->sfp_interfaces)) {
phylink_err(pl, "unsupported SFP module: no common interface modes\n");
@@ -3939,7 +3947,7 @@ static int phylink_sfp_connect_phy(void *upstream, struct phy_device *phy)

/* Set the PHY's host supported interfaces */
phy_interface_and(phy->host_interfaces, phylink_sfp_interfaces,
- pl->config->supported_interfaces);
+ pl->supported_interfaces);

/* Do the initial configuration */
return phylink_sfp_config_phy(pl, phy);
--
2.53.0