summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorMaxime Chevallier <maxime.chevallier@bootlin.com>2026-10-16 15:31:01 +0200
committerJakub Kicinski <kuba@kernel.org>2026-10-21 16:32:04 -0700
commit9e7cd33fafb2ce1fd6cf19fd20f486ea341e6c0c (patch)
tree5704356196210e8f0c2b226f1a7404f3ca634e10 /drivers
parent51ebb13c1d9658328b66b8f67e7992f708567807 (diff)
downloadlinux-9e7cd33fafb2ce1fd6cf19fd20f486ea341e6c0c.tar.gz
linux-9e7cd33fafb2ce1fd6cf19fd20f486ea341e6c0c.zip
net: phy: phy_port: Store information about a port's upstream
MII phy_ports are not meant to be connected directly to a link partner. They are meant to feed into some media converter devices that will expose an MDI phy_port, so far we only support SFP modules for that. In the case an MDI phy_port is backed by an MII port (e.g. a SFP module's port, backed by the SFP cage port), let's keep track of the port id of the MII port backing it. Reviewed-by: Andrew Lunn <andrew@lunn.ch> Tested-by: Aleksei Sviridkin <f@lex.la> Reviewed-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org> Tested-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org> Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com> Link: https://patch.msgid.link/20261016133107.54054-7-maxime.chevallier@bootlin.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/phy/phy_device.c24
-rw-r--r--drivers/net/phy/phylink.c5
2 files changed, 29 insertions, 0 deletions
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 4f897019dce2..5d4508bcfbe9 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1403,6 +1403,7 @@ static int phy_sfp_connect_phy(void *upstream, struct phy_device *phy)
int ret;
phydev->has_sfp_mod_phy = true;
+ phy_set_upstream_port(phy, phydev->sfp_cage_port);
/* If we aren't attached to a netdev, we can't add the SFP PHY to its
* topology.
@@ -1436,6 +1437,8 @@ static void phy_sfp_disconnect_phy(void *upstream, struct phy_device *phy)
if (dev)
phy_link_topo_del_phy(dev, phy);
+
+ phy_set_upstream_port(phy, NULL);
}
/**
@@ -1574,6 +1577,8 @@ static int phy_add_sfp_mod_port(struct phy_device *phydev)
*/
phydev->mod_port = port;
+ port->upstream_port = phydev->sfp_cage_port;
+
return 0;
}
@@ -3704,6 +3709,25 @@ struct phy_port *phy_get_sfp_port(struct phy_device *phydev)
EXPORT_SYMBOL_GPL(phy_get_sfp_port);
/**
+ * phy_set_upstream_port() - Sets the phy_port controlling the MII this PHY is
+ * attached to.
+ * @phydev: pointer to the PHY device we set the upstream of.
+ * @port: The phy_port upstream of this PHY, can be NULL.
+ */
+void phy_set_upstream_port(struct phy_device *phydev, struct phy_port *port)
+{
+ struct phy_port *local_port;
+
+ ASSERT_RTNL();
+
+ phydev->upstream_port = port;
+
+ phy_for_each_port(phydev, local_port)
+ local_port->upstream_port = port;
+}
+EXPORT_SYMBOL_GPL(phy_set_upstream_port);
+
+/**
* fwnode_mdio_find_device - Given a fwnode, find the mdio_device
* @fwnode: pointer to the mdio_device's fwnode
*
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 667f00ddfa5e..e885da1c2831 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -4052,6 +4052,8 @@ static int phylink_add_sfp_mod_port(struct phylink *pl)
}
}
+ port->upstream_port = pl->sfp_cage_port;
+
pl->mod_port = port;
return 0;
@@ -4155,6 +4157,8 @@ static int phylink_sfp_connect_phy(void *upstream, struct phy_device *phy)
phy_interface_and(phy->host_interfaces, phylink_sfp_interfaces,
pl->config->supported_interfaces);
+ phy_set_upstream_port(phy, pl->sfp_cage_port);
+
/* Do the initial configuration */
return phylink_sfp_config_phy(pl, phy);
}
@@ -4163,6 +4167,7 @@ static void phylink_sfp_disconnect_phy(void *upstream,
struct phy_device *phydev)
{
phylink_disconnect_phy(upstream);
+ phy_set_upstream_port(phydev, NULL);
}
static const struct sfp_upstream_ops sfp_phylink_ops = {