From: Markus Stockhausen Date: Fri, 16 May 2025 07:31:07 +0000 (-0400) Subject: realtek: simplify RTL8214FC patches for ethtool copper/fiber switching X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F18816%2Fhead;p=thirdparty%2Fopenwrt.git 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 Link: https://github.com/openwrt/openwrt/pull/18816 Signed-off-by: Robert Marko --- 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 8ca8c2a3db3..cf79b9bbe44 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 09255c57214..3404d55ed3c 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 --- 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 a92045ba8a7..44461992b17 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 --- 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 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 9f9051045e3..00000000000 --- 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 -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 ---- - 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 ea6149281d1..4fb1e7f293a 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 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) {