[PATCH net-next 3/3] net: phy: dp83869: Support 1000Base-X SFP modules
From: Romain Gantois <romain.gantois@bootlin.com>
Date: 2025-05-14 07:50:13
Also in:
lkml
Subsystem:
ethernet phy library, networking drivers, the rest · Maintainers:
Andrew Lunn, Heiner Kallweit, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
The DP83869 PHY supports multiple operational modes, including RGMII-to-1000Base-X, which can be used to link an RGMII-capable Ethernet MAC to a downstream fiber SFP module. +-------+ +---------+ +-----------------+ | | RGMII | | 1000Base-X | | | MAC |<-------> | DP83869 |<---------->| fiber SFP module| | | | | | | +-------+ +---------+ +-----------------+ Register the attach_port() callback, to set the supported downstream interface modes for SFP ports and provide the configure_mii() callback, which sets the correct DP83869 operational mode when a compatible SFP module is inserted. Signed-off-by: Romain Gantois <romain.gantois@bootlin.com> --- drivers/net/phy/dp83869.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+)
diff --git a/drivers/net/phy/dp83869.c b/drivers/net/phy/dp83869.c
index 000660aae16ed46166774e7235cd8a6df94be047..6d43c39ac525714a495327ec5a1a22b5e653b1cd 100644
--- a/drivers/net/phy/dp83869.c
+++ b/drivers/net/phy/dp83869.c@@ -10,6 +10,7 @@ #include <linux/module.h> #include <linux/of.h> #include <linux/phy.h> +#include <linux/phy_port.h> #include <linux/delay.h> #include <linux/bitfield.h>
@@ -876,6 +877,57 @@ static int dp83869_config_init(struct phy_device *phydev) return ret; } +static int dp83869_port_configure_serdes(struct phy_port *port, bool enable, + phy_interface_t interface) +{ + struct phy_device *phydev = port_phydev(port); + struct dp83869_private *dp83869; + int ret; + + if (!enable) + return 0; + + dp83869 = phydev->priv; + + switch (interface) { + case PHY_INTERFACE_MODE_1000BASEX: + dp83869->mode = DP83869_RGMII_1000_BASE; + break; + default: + phydev_err(phydev, "Incompatible SFP module inserted\n"); + return -EINVAL; + } + + ret = dp83869_configure_mode(phydev, dp83869); + if (ret) + return ret; + + /* Update advertisement */ + if (mutex_trylock(&phydev->lock)) { + ret = dp83869_config_aneg(phydev); + mutex_unlock(&phydev->lock); + } + + return ret; +} + +static const struct phy_port_ops dp83869_serdes_port_ops = { + .configure_mii = dp83869_port_configure_serdes, +}; + +static int dp83869_attach_port(struct phy_device *phydev, + struct phy_port *port) +{ + if (!port->is_serdes) + return 0; + + port->ops = &dp83869_serdes_port_ops; + + __set_bit(PHY_INTERFACE_MODE_1000BASEX, port->interfaces); + + return 0; +} + static int dp83869_probe(struct phy_device *phydev) { struct dp83869_private *dp83869;
@@ -931,6 +983,7 @@ static int dp83869_phy_reset(struct phy_device *phydev) .set_tunable = dp83869_set_tunable, \ .get_wol = dp83869_get_wol, \ .set_wol = dp83869_set_wol, \ + .attach_port = dp83869_attach_port, \ .suspend = genphy_suspend, \ .resume = genphy_resume, \ }
--
2.49.0