]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
realtek: phy: add 100base-FX mode to RTL8214FC 23087/head
authorMarkus Stockhausen <markus.stockhausen@gmx.de>
Fri, 24 Apr 2026 20:20:30 +0000 (22:20 +0200)
committerRobert Marko <robimarko@gmail.com>
Tue, 5 May 2026 11:16:08 +0000 (13:16 +0200)
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 <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/23087
Signed-off-by: Robert Marko <robimarko@gmail.com>
target/linux/realtek/files-6.18/drivers/net/phy/realtek/realtek_multiport.c

index 03639475eed029688b42f2ad222ae5fe91d50a7c..29b5cce4c1ace13bb3f25ebd35c3a91a269bcf52 100644 (file)
@@ -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;
 }