summaryrefslogtreecommitdiff
path: root/drivers/net/phy/phylink.c
diff options
context:
space:
mode:
authorRussell King (Oracle) <rmk+kernel@armlinux.org.uk>2024-04-26 12:58:22 +0100
committerRussell King (Oracle) <rmk+kernel@armlinux.org.uk>2024-05-02 12:16:37 +0100
commitda763df2bd9a6b39c202449f58a75549616d6a67 (patch)
treee0e699910103ff18438740dc204bbb303ab23bf7 /drivers/net/phy/phylink.c
parent97382104d4bdef38bea9b6fc1469ae478cc66afd (diff)
net: phylink: validate sfp_select_interface() returned interface
When configuring for a SFP PHY, validate that the MAC supports the interface returned from sfp_select_interface(). This is a preparatory step to reorganising how a PHY on a SFP module is handled. Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Diffstat (limited to 'drivers/net/phy/phylink.c')
-rw-r--r--drivers/net/phy/phylink.c43
1 files changed, 30 insertions, 13 deletions
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index d60be55734a9..3755c69514c8 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -2444,6 +2444,32 @@ int phylink_ethtool_set_wol(struct phylink *pl, struct ethtool_wolinfo *wol)
}
EXPORT_SYMBOL_GPL(phylink_ethtool_set_wol);
+static phy_interface_t phylink_sfp_select_interface(struct phylink *pl,
+ const unsigned long *link_modes)
+{
+ phy_interface_t interface;
+
+ interface = sfp_select_interface(pl->sfp_bus, link_modes);
+ if (interface == PHY_INTERFACE_MODE_NA) {
+ phylink_err(pl,
+ "selection of interface failed, advertisement %*pb\n",
+ __ETHTOOL_LINK_MODE_MASK_NBITS,
+ link_modes);
+ return interface;
+ }
+
+ if (!test_bit(interface, pl->config->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);
+ return PHY_INTERFACE_MODE_NA;
+ }
+
+ return interface;
+}
+
static void phylink_merge_link_mode(unsigned long *dst, const unsigned long *b)
{
__ETHTOOL_DECLARE_LINK_MODE_MASK(mask);
@@ -2626,15 +2652,10 @@ int phylink_ethtool_ksettings_set(struct phylink *pl,
* link can be configured correctly.
*/
if (pl->sfp_bus) {
- config.interface = sfp_select_interface(pl->sfp_bus,
+ config.interface = phylink_sfp_select_interface(pl,
config.advertising);
- if (config.interface == PHY_INTERFACE_MODE_NA) {
- phylink_err(pl,
- "selection of interface failed, advertisement %*pb\n",
- __ETHTOOL_LINK_MODE_MASK_NBITS,
- config.advertising);
+ if (config.interface == PHY_INTERFACE_MODE_NA)
return -EINVAL;
- }
/* Revalidate with the selected interface */
linkmode_copy(support, pl->supported);
@@ -3317,13 +3338,9 @@ static int phylink_sfp_config_phy(struct phylink *pl, u8 mode,
return ret;
}
- iface = sfp_select_interface(pl->sfp_bus, config.advertising);
- if (iface == PHY_INTERFACE_MODE_NA) {
- phylink_err(pl,
- "selection of interface failed, advertisement %*pb\n",
- __ETHTOOL_LINK_MODE_MASK_NBITS, config.advertising);
+ iface = phylink_sfp_select_interface(pl, config.advertising);
+ if (iface == PHY_INTERFACE_MODE_NA)
return -EINVAL;
- }
config.interface = iface;
linkmode_copy(support1, support);