From 01df243f21af81e48d83e8cdd55e98dd86946106 Mon Sep 17 00:00:00 2001 From: Markus Stockhausen Date: Fri, 24 Apr 2026 22:20:30 +0200 Subject: [PATCH] realtek: phy: add 100base-FX mode to RTL8214FC Add the basic bits to allow 100base-FX SFP mode on the RTL8214FC. While this looks good fom ethtool perspective, it does not really change the phy registers to enforce the mode. The SFP is still driven in 1000base-X. While it might seem useless at the moment this at least opens up a new phy control method. This comes handy with one known bug. In rare cases a SFP that is plugged in during boot does not get a link. One option to revive the dead port seems to be root@OpenWrt:~# ethtool -s lan28 speed 100 duplex full autoneg off rtl83xx-switch 1b000000.switchcore:ethernet-switch lan28: Link is Up - 100Mbps/Full - flow control off switch: port 28(lan28) entered blocking state switch: port 28(lan28) entered forwarding state rtl83xx_fib_event: FIB_RULE ADD/DEL for IPv6 not supported rtl83xx_fib_event: FIB_RULE ADD/DEL for IPv6 not supported Signed-off-by: Markus Stockhausen Link: https://github.com/openwrt/openwrt/pull/23087 Signed-off-by: Robert Marko --- .../drivers/net/phy/realtek/realtek_multiport.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/target/linux/realtek/files-6.18/drivers/net/phy/realtek/realtek_multiport.c b/target/linux/realtek/files-6.18/drivers/net/phy/realtek/realtek_multiport.c index 03639475eed..29b5cce4c1a 100644 --- a/target/linux/realtek/files-6.18/drivers/net/phy/realtek/realtek_multiport.c +++ b/target/linux/realtek/files-6.18/drivers/net/phy/realtek/realtek_multiport.c @@ -300,6 +300,7 @@ static int rtl8214fc_get_features(struct phy_device *phydev) * announce the superset of all possible features. */ linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, phydev->supported); + linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Full_BIT, phydev->supported); linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported); return 0; @@ -325,10 +326,15 @@ static int rtl8214fc_config_aneg(struct phy_device *phydev) { int ret; - if (rtl8214fc_media_is_fibre(phydev)) + if (rtl8214fc_media_is_fibre(phydev)) { + if (linkmode_test_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, phydev->advertising)) { + linkmode_clear_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, phydev->advertising); + linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Full_BIT, phydev->advertising); + } ret = genphy_c37_config_aneg(phydev); - else + } else { ret = genphy_config_aneg(phydev); + } return ret; } -- 2.47.3