[PATCH net-next 05/13] net: phy: Create SFP phy_port before registering usptream

Maxime Chevallier
2026-01-27T13:42:33Z

When dealing with PHY-driver SFP, we create a phy_port representing the
SFP bus when we know we have such a bus.

We can move the port creation before registering the sfp upstream ops,
as long as we know the SFP bus is there. This will allow passing the
phy_port along with the upstream information to the SFP bus.

Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
---
drivers/net/phy/phy_device.c | 40 +++++++++++++++++++++++-------------
1 file changed, 26 insertions(+), 14 deletions(-)

diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 8a3eb1839a3d..819c9e81bdef 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1665,13 +1665,13 @@ static void phy_del_port(struct phy_device *phydev, struct phy_port *port)
phydev->n_ports--;
}

-static int phy_setup_sfp_port(struct phy_device *phydev)
+static struct phy_port *phy_setup_sfp_port(struct phy_device *phydev)
{
struct phy_port *port = phy_port_alloc();
int ret;

if (!port)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);

port->parent_type = PHY_PORT_PHY;
port->phy = phydev;
@@ -1686,10 +1686,12 @@ static int phy_setup_sfp_port(struct phy_device *phydev)
* when attaching the port to the phydev.
*/
ret = phy_add_port(phydev, port);
- if (ret)
+ if (ret) {
phy_port_destroy(port);
+ return ERR_PTR(ret);
+ }

- return ret;
+ return port;
}

/**
@@ -1698,22 +1700,32 @@ static int phy_setup_sfp_port(struct phy_device *phydev)
*/
static int phy_sfp_probe(struct phy_device *phydev)
{
+ struct phy_port *port;
struct sfp_bus *bus;
- int ret = 0;
+ int ret;
+
+ if (!phydev->mdio.dev.fwnode)
+ return 0;

- if (phydev->mdio.dev.fwnode) {
- bus = sfp_bus_find_fwnode(phydev->mdio.dev.fwnode);
- if (IS_ERR(bus))
- return PTR_ERR(bus);
+ bus = sfp_bus_find_fwnode(phydev->mdio.dev.fwnode);
+ if (IS_ERR(bus))
+ return PTR_ERR(bus);

- phydev->sfp_bus = bus;
+ phydev->sfp_bus = bus;

- ret = sfp_bus_add_upstream(bus, phydev, &sfp_phydev_ops);
- sfp_bus_put(bus);
+ if (bus) {
+ port = phy_setup_sfp_port(phydev);
+ if (IS_ERR(port)) {
+ sfp_bus_put(bus);
+ return PTR_ERR(port);
+ }
}

- if (!ret && phydev->sfp_bus)
- ret = phy_setup_sfp_port(phydev);
+ ret = sfp_bus_add_upstream(bus, phydev, &sfp_phydev_ops);
+ sfp_bus_put(bus);
+
+ if (ret && port)
+ phy_del_port(phydev, port);

return ret;
}
--
2.49.0