[openwrt/openwrt] realtek: proper RTL8214FC fibre/copper detection

LEDE Commits lede-commits at lists.infradead.org
Fri May 9 01:24:21 PDT 2025


robimarko pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/4cfd1c450181893a8063588eafd4eadef6a7e235

commit 4cfd1c450181893a8063588eafd4eadef6a7e235
Author: Markus Stockhausen <markus.stockhausen at gmx.de>
AuthorDate: Tue May 6 02:44:43 2025 -0400

    realtek: proper RTL8214FC fibre/copper detection
    
    The RTL8214FC currently uses generic PHY functions. That makes it look like a copper
    device. Switching to/from fibre works fortunately but the autonegotiation handling
    still works on MII_LPA (PHY register 5) as if a copper link is used. Fix that by
    
    - advertising a superset of TP/FIBRE features
    - using clause 37 functions when on fibre
    
    Additionally enhance the code of the driver to assist further development.
    
    - log the speed of the inserted module to detect wrongly inserted 10gbase-r modules
    - order phy driver functions alphabetically (keep match/name on top)
    - remove genphy_loopback as the kernel uses it if not provided
    
    Remark! The driver internally uses PORT_MII for the TP port. Align with that and
    report MII to ethtool instead of TP. Other drivers do the same and it can be
    changed in the future if needed.
    
    Signed-off-by: Markus Stockhausen <markus.stockhausen at gmx.de>
    Link: https://github.com/openwrt/openwrt/pull/18724
    Signed-off-by: Robert Marko <robimarko at gmail.com>
---
 .../files-6.6/drivers/net/phy/rtl83xx-phy.c        | 69 +++++++++++++++++++---
 1 file changed, 62 insertions(+), 7 deletions(-)

diff --git a/target/linux/realtek/files-6.6/drivers/net/phy/rtl83xx-phy.c b/target/linux/realtek/files-6.6/drivers/net/phy/rtl83xx-phy.c
index 94ccbe5769..ffea742194 100644
--- a/target/linux/realtek/files-6.6/drivers/net/phy/rtl83xx-phy.c
+++ b/target/linux/realtek/files-6.6/drivers/net/phy/rtl83xx-phy.c
@@ -1124,6 +1124,52 @@ static int rtl8214fc_get_port(struct phy_device *phydev)
 	return PORT_MII;
 }
 
+static int rtl8214fc_get_features(struct phy_device *phydev)
+{
+	int ret = 0;
+
+	ret = genphy_read_abilities(phydev);
+	if (ret)
+		return ret;
+	/*
+	 * The RTL8214FC only advertises TP capabilities in the standard registers. This is
+	 * independent from what fibre/copper combination is currently activated. For now just
+	 * announce the superset of all possible features.
+	 */
+	linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, phydev->supported);
+	linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported);
+
+	return 0;
+}
+
+static int rtl8214fc_read_status(struct phy_device *phydev)
+{
+	bool changed;
+	int ret;
+
+	if (rtl8214fc_media_is_fibre(phydev)) {
+		phydev->port = PORT_FIBRE;
+		ret = genphy_c37_read_status(phydev, &changed);
+	} else {
+		phydev->port = PORT_MII; /* for now aligend with rest of code */
+		ret = genphy_read_status(phydev);
+	}
+
+	return ret;
+}
+
+static int rtl8214fc_config_aneg(struct phy_device *phydev)
+{
+	int ret;
+
+	if (rtl8214fc_media_is_fibre(phydev))
+		ret = genphy_c37_config_aneg(phydev);
+	else
+		ret = genphy_config_aneg(phydev);
+
+	return ret;
+}
+
 /* Enable EEE on the RTL8218B PHYs
  * The method used is not the preferred way (which would be based on the MAC-EEE state,
  * but the only way that works since the kernel first enables EEE in the MAC
@@ -3713,7 +3759,15 @@ int rtl931x_link_sts_get(u32 sds)
 
 static int rtl8214fc_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
 {
+	__ETHTOOL_DECLARE_LINK_MODE_MASK(support) = { 0, };
+	DECLARE_PHY_INTERFACE_MASK(interfaces);
 	struct phy_device *phydev = upstream;
+	phy_interface_t iface;
+
+	sfp_parse_support(phydev->sfp_bus, id, support, interfaces);
+	iface = sfp_select_interface(phydev->sfp_bus, support);
+
+	dev_info(&phydev->mdio.dev, "%s SFP module inserted\n", phy_modes(iface));
 
 	rtl8214fc_media_set(phydev, true);
 
@@ -3914,17 +3968,18 @@ static struct phy_driver rtl83xx_phy_driver[] = {
 	{
 		.match_phy_device = rtl8214fc_match_phy_device,
 		.name		= "Realtek RTL8214FC",
-		.features	= PHY_GBIT_FIBRE_FEATURES,
+		.config_aneg	= rtl8214fc_config_aneg,
+		.get_eee	= rtl8214fc_get_eee,
+		.get_features	= rtl8214fc_get_features,
+		.get_port	= rtl8214fc_get_port,
 		.probe		= rtl8214fc_phy_probe,
 		.read_page	= rtl821x_read_page,
-		.write_page	= rtl821x_write_page,
-		.suspend	= rtl8214fc_suspend,
+		.read_status    = rtl8214fc_read_status,
 		.resume		= rtl8214fc_resume,
-		.set_loopback	= genphy_loopback,
-		.set_port	= rtl8214fc_set_port,
-		.get_port	= rtl8214fc_get_port,
 		.set_eee	= rtl8214fc_set_eee,
-		.get_eee	= rtl8214fc_get_eee,
+		.set_port	= rtl8214fc_set_port,
+		.suspend	= rtl8214fc_suspend,
+		.write_page	= rtl821x_write_page,
 	},
 	{
 		.match_phy_device = rtl8218b_ext_match_phy_device,




More information about the lede-commits mailing list