[openwrt/openwrt] realtek: simplify RTL8214FC patches for ethtool copper/fiber switching

LEDE Commits lede-commits at lists.infradead.org
Mon May 26 01:38:01 PDT 2025


robimarko pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/1bef83bb230fe1695050746b56175d35b50da6b1

commit 1bef83bb230fe1695050746b56175d35b50da6b1
Author: Markus Stockhausen <markus.stockhausen at gmx.de>
AuthorDate: Fri May 16 03:31:07 2025 -0400

    realtek: simplify RTL8214FC patches for ethtool copper/fiber switching
    
    There is a patch/bug cascade in the realtek target phy code that must be resolved.
    
    1. The phy_driver structure is patched to add features ONLY needed for RTL8214FC
    
    2. The kernel is patched to allow switching fiber/copper port of phys through ethtool
       by calling these new features.
    
    3. With those patches applied the bootup always switches RTL8214FC ports to copper.
       Even if a SFP module was found before and the phy driver switched to fibre before.
    
    3. So another patch is needed that reprobes the SFP module to activate fiber again.
    
    4. Because of the reprobing we need a fourth patch that avoid duplicate devices.
    
    Simplify this by removing all patches and reusing the existing ethtool phy tunable
    interface. The command line usage might be counterintuitive but it avoids tons of
    problems in the code. In addition, this scenario is not used frequently.
    
    Before:ethtool -s lan25 port fibre/tp
    After: ethtool --set-phy-tunable lan25 downshift on/off
    
    Signed-off-by: Markus Stockhausen <markus.stockhausen at gmx.de>
    Link: https://github.com/openwrt/openwrt/pull/18816
    Signed-off-by: Robert Marko <robimarko at gmail.com>
---
 .../files-6.6/drivers/net/phy/rtl83xx-phy.c        | 43 ++++++++++++----------
 ...706-include-linux-add-phy-ops-for-rtl838x.patch |  4 +-
 ...8-drivers-net-phy-eee-support-for-rtl838x.patch | 16 +-------
 ...-phy-sfp-re-probe-modules-on-DEV_UP-event.patch | 37 -------------------
 .../714-net-phy-sfp-add-support-for-SMBus.patch    |  2 +-
 5 files changed, 28 insertions(+), 74 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 8ca8c2a3db..cf79b9bbe4 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
@@ -1084,27 +1084,32 @@ static void rtl8214fc_media_set(struct phy_device *phydev, bool set_fibre)
 	}
 }
 
-static int rtl8214fc_set_port(struct phy_device *phydev, int port)
+static int rtl8214fc_set_tunable(struct phy_device *phydev,
+				 struct ethtool_tunable *tuna, const void *data)
 {
-	bool is_fibre = (port == PORT_FIBRE ? true : false);
-	int addr = phydev->mdio.addr;
-
-	pr_debug("%s port %d to %d\n", __func__, addr, port);
-
-	rtl8214fc_media_set(phydev, is_fibre);
-
-	return 0;
+	/*
+	 * The RTL8214FC driver usually detects insertion of SFP modules and automatically toggles
+	 * between copper and fiber. There may be cases where the user wants to switch the port on
+	 * demand. Usually ethtool offers to change the port of a multiport network card with
+	 * "ethtool -s lan25 port fibre/tp" if the driver supports it. This does not work for
+	 * attached phys. For more details see phy_ethtool_ksettings_set(). To avoid patching the
+	 * kernel misuse the phy downshift tunable to offer that feature. For this use
+	 * "ethtool --set-phy-tunable lan25 downshift on/off".
+	 */
+	switch (tuna->id) {
+	case ETHTOOL_PHY_DOWNSHIFT:
+		rtl8214fc_media_set(phydev, !rtl8214fc_media_is_fibre(phydev));
+		return 0;
+	default:
+		return -EOPNOTSUPP;
+	}
 }
 
-static int rtl8214fc_get_port(struct phy_device *phydev)
+static int rtl8214fc_get_tunable(struct phy_device *phydev,
+				 struct ethtool_tunable *tuna, void *data)
 {
-	int addr = phydev->mdio.addr;
-
-	pr_debug("%s: port %d\n", __func__, addr);
-	if (rtl8214fc_media_is_fibre(phydev))
-		return PORT_FIBRE;
-
-	return PORT_MII;
+	/* Needed to make rtl8214fc_set_tunable() work */
+	return 0;
 }
 
 static int rtl8214fc_get_features(struct phy_device *phydev)
@@ -3954,13 +3959,13 @@ static struct phy_driver rtl83xx_phy_driver[] = {
 		.config_aneg	= rtl8214fc_config_aneg,
 		.get_eee	= rtl8214fc_get_eee,
 		.get_features	= rtl8214fc_get_features,
-		.get_port	= rtl8214fc_get_port,
+		.get_tunable    = rtl8214fc_get_tunable,
 		.probe		= rtl8214fc_phy_probe,
 		.read_page	= rtl821x_read_page,
 		.read_status    = rtl8214fc_read_status,
 		.resume		= rtl8214fc_resume,
 		.set_eee	= rtl8214fc_set_eee,
-		.set_port	= rtl8214fc_set_port,
+		.set_tunable	= rtl8214fc_set_tunable,
 		.suspend	= rtl8214fc_suspend,
 		.write_page	= rtl821x_write_page,
 	},
diff --git a/target/linux/realtek/patches-6.6/706-include-linux-add-phy-ops-for-rtl838x.patch b/target/linux/realtek/patches-6.6/706-include-linux-add-phy-ops-for-rtl838x.patch
index 09255c5721..3404d55ed3 100644
--- a/target/linux/realtek/patches-6.6/706-include-linux-add-phy-ops-for-rtl838x.patch
+++ b/target/linux/realtek/patches-6.6/706-include-linux-add-phy-ops-for-rtl838x.patch
@@ -21,12 +21,10 @@ Submitted-by: John Crispin <john at phrozen.org>
 
 --- a/include/linux/phy.h
 +++ b/include/linux/phy.h
-@@ -1181,6 +1181,10 @@ struct phy_driver {
+@@ -1181,6 +1181,8 @@ struct phy_driver {
  	 */
  	int (*led_polarity_set)(struct phy_device *dev, int index,
  				unsigned long modes);
-+	int (*get_port)(struct phy_device *dev);
-+	int (*set_port)(struct phy_device *dev, int port);
 +	int (*get_eee)(struct phy_device *dev, struct ethtool_eee *e);
 +	int (*set_eee)(struct phy_device *dev, struct ethtool_eee *e);
  };
diff --git a/target/linux/realtek/patches-6.6/708-drivers-net-phy-eee-support-for-rtl838x.patch b/target/linux/realtek/patches-6.6/708-drivers-net-phy-eee-support-for-rtl838x.patch
index a92045ba8a..44461992b1 100644
--- a/target/linux/realtek/patches-6.6/708-drivers-net-phy-eee-support-for-rtl838x.patch
+++ b/target/linux/realtek/patches-6.6/708-drivers-net-phy-eee-support-for-rtl838x.patch
@@ -21,19 +21,7 @@ Submitted-by: John Crispin <john at phrozen.org>
 
 --- a/drivers/net/phy/phylink.c
 +++ b/drivers/net/phy/phylink.c
-@@ -2503,6 +2503,11 @@ int phylink_ethtool_ksettings_set(struct
- 		 *   the presence of a PHY, this should not be changed as that
- 		 *   should be determined from the media side advertisement.
- 		 */
-+		if (pl->phydev->drv->get_port && pl->phydev->drv->set_port) {
-+			if(pl->phydev->drv->get_port(pl->phydev) != kset->base.port) {
-+				pl->phydev->drv->set_port(pl->phydev, kset->base.port);
-+			}
-+		}
- 		return phy_ethtool_ksettings_set(pl->phydev, &phy_kset);
- 	}
- 
-@@ -2805,8 +2810,11 @@ int phylink_ethtool_get_eee(struct phyli
+@@ -2805,8 +2805,11 @@ int phylink_ethtool_get_eee(struct phyli
  
  	ASSERT_RTNL();
  
@@ -46,7 +34,7 @@ Submitted-by: John Crispin <john at phrozen.org>
  
  	return ret;
  }
-@@ -2823,8 +2831,11 @@ int phylink_ethtool_set_eee(struct phyli
+@@ -2823,8 +2826,11 @@ int phylink_ethtool_set_eee(struct phyli
  
  	ASSERT_RTNL();
  
diff --git a/target/linux/realtek/patches-6.6/710-net-phy-sfp-re-probe-modules-on-DEV_UP-event.patch b/target/linux/realtek/patches-6.6/710-net-phy-sfp-re-probe-modules-on-DEV_UP-event.patch
deleted file mode 100644
index 9f9051045e..0000000000
--- a/target/linux/realtek/patches-6.6/710-net-phy-sfp-re-probe-modules-on-DEV_UP-event.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From a381ac0aa281fdb0b41a39d8a2bc08fd88f6db92 Mon Sep 17 00:00:00 2001
-From: Antoine Tenart <antoine.tenart at bootlin.com>
-Date: Tue, 25 Feb 2020 16:32:37 +0100
-Subject: [PATCH 1/3] net: phy: sfp: re-probe modules on DEV_UP event
-
-Signed-off-by: Antoine Tenart <antoine.tenart at bootlin.com>
----
- drivers/net/phy/sfp.c | 7 +++++++
- 1 file changed, 7 insertions(+)
-
---- a/drivers/net/phy/sfp.c
-+++ b/drivers/net/phy/sfp.c
-@@ -1570,6 +1570,10 @@ static void sfp_hwmon_probe(struct work_
- 	struct sfp *sfp = container_of(work, struct sfp, hwmon_probe.work);
- 	int err;
- 
-+	/* Avoid duplicate hwmon devices when re-probing */
-+	if (sfp->hwmon_dev)
-+		return;
-+
- 	/* hwmon interface needs to access 16bit registers in atomic way to
- 	 * guarantee coherency of the diagnostic monitoring data. If it is not
- 	 * possible to guarantee coherency because EEPROM is broken in such way
-@@ -2432,6 +2436,13 @@ static void sfp_sm_module(struct sfp *sf
- 		return;
- 	}
- 
-+	/* Re-probe the SFP modules when an interface is brought up, as the MAC
-+	 * do not report its link status (This means Phylink wouldn't be
-+	 * triggered if the PHY had a link before a MAC is brought up).
-+	 */
-+	if (event == SFP_E_DEV_UP && sfp->sm_mod_state == SFP_MOD_PRESENT)
-+		sfp_sm_mod_next(sfp, SFP_MOD_PROBE, T_SERIAL);
-+
- 	switch (sfp->sm_mod_state) {
- 	default:
- 		if (event == SFP_E_INSERT) {
diff --git a/target/linux/realtek/patches-6.6/714-net-phy-sfp-add-support-for-SMBus.patch b/target/linux/realtek/patches-6.6/714-net-phy-sfp-add-support-for-SMBus.patch
index ea6149281d..4fb1e7f293 100644
--- a/target/linux/realtek/patches-6.6/714-net-phy-sfp-add-support-for-SMBus.patch
+++ b/target/linux/realtek/patches-6.6/714-net-phy-sfp-add-support-for-SMBus.patch
@@ -107,7 +107,7 @@ Signed-off-by: Antoine Tenart <antoine.tenart at bootlin.com>
  static void sfp_i2c_mdiobus_destroy(struct sfp *sfp)
  {
  	mdiobus_unregister(sfp->i2c_mii);
-@@ -1888,9 +1965,15 @@ static void sfp_sm_fault(struct sfp *sfp
+@@ -1884,9 +1961,15 @@ static void sfp_sm_fault(struct sfp *sfp
  
  static int sfp_sm_add_mdio_bus(struct sfp *sfp)
  {




More information about the lede-commits mailing list