From 0e8231c8872bee643f94b862ab754dd254309c90 Mon Sep 17 00:00:00 2001 From: Lorenz Brun Date: Fri, 10 Oct 2025 23:11:38 +0200 Subject: [PATCH] realtek: fix SFP ports on RTL83xx Right now the phylink capability function enables 2.5G and 10G modes on Maple and Cypress, which they mostly (other than two SERDES on Cypress) don't support. This causes these modes to be selected and break the link as they are not supported by hardware. I looked into doing this properly, but it cannot just be done based on SoC, but needs to take the whole topology into account as a given MAC might have very different capabilities depending on what SERDES are assigned to it. So for now just use 1G and QSGMII for RTL83xx and 10G for RTL93xx. This mostly works, except it will downgrade some 10G links on RTL839x, but since there are also 1G SFPs on these this cannot be solved without fully accounting for the global MAC and SERDES configuration. So this makes all of the 1G SFP slots work again, while keeping most of the 10G SFP+ slots working at 10G with minimal changes. Signed-off-by: Lorenz Brun Link: https://github.com/openwrt/openwrt/pull/20374 Signed-off-by: Hauke Mehrtens --- .../files-6.12/drivers/net/dsa/rtl83xx/dsa.c | 37 ++++++++++++++----- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/dsa.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/dsa.c index a84d1be6d6d..38608734f3c 100644 --- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/dsa.c +++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/dsa.c @@ -613,25 +613,44 @@ static void rtl83xx_config_interface(int port, phy_interface_t interface) pr_debug("configured port %d for interface %s\n", port, phy_modes(interface)); } -static void rtldsa_phylink_get_caps(struct dsa_switch *ds, int port, +static void rtldsa_83xx_phylink_get_caps(struct dsa_switch *ds, int port, struct phylink_config *config) { /* - * TODO: This capability check will need some love. Depending on the model and the - * port different MAC features and link modes are supported. For now just enable all - * required MAC and PHY capabilites so that we can make use of the ports. + * TODO: This needs to take into account the MAC to SERDES mapping and the + * specific SoC capabilities. Right now we just assume all RTL83xx ports + * support up to 1G standalone and QSGMII as that covers most real-world + * use cases. */ + config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | MAC_10 | MAC_100 | + MAC_1000FD; + __set_bit(PHY_INTERFACE_MODE_1000BASEX, config->supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_GMII, config->supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_INTERNAL, config->supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_SGMII, config->supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_QSGMII, config->supported_interfaces); +} + +static void rtldsa_93xx_phylink_get_caps(struct dsa_switch *ds, int port, + struct phylink_config *config) +{ + /* + * TODO: This needs to take into account the MAC to SERDES mapping and the + * specific SoC capabilities. Right now we just assume all RTL93xx ports + * support up to 10G standalone and up to USXGMII as that covers most + * real-world use cases. + */ config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | MAC_10 | MAC_100 | MAC_1000FD | MAC_2500FD | MAC_5000FD | MAC_10000FD; __set_bit(PHY_INTERFACE_MODE_1000BASEX, config->supported_interfaces); - __set_bit(PHY_INTERFACE_MODE_10GBASER, config->supported_interfaces); - __set_bit(PHY_INTERFACE_MODE_2500BASEX, config->supported_interfaces); __set_bit(PHY_INTERFACE_MODE_GMII, config->supported_interfaces); __set_bit(PHY_INTERFACE_MODE_INTERNAL, config->supported_interfaces); - __set_bit(PHY_INTERFACE_MODE_QSGMII, config->supported_interfaces); __set_bit(PHY_INTERFACE_MODE_SGMII, config->supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_QSGMII, config->supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_10GBASER, config->supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_2500BASEX, config->supported_interfaces); __set_bit(PHY_INTERFACE_MODE_USXGMII, config->supported_interfaces); } @@ -2562,7 +2581,7 @@ const struct dsa_switch_ops rtl83xx_switch_ops = { .phy_read = rtldsa_phy_read, .phy_write = rtldsa_phy_write, - .phylink_get_caps = rtldsa_phylink_get_caps, + .phylink_get_caps = rtldsa_83xx_phylink_get_caps, .phylink_mac_config = rtl83xx_phylink_mac_config, .phylink_mac_link_down = rtl83xx_phylink_mac_link_down, .phylink_mac_link_up = rtl83xx_phylink_mac_link_up, @@ -2619,7 +2638,7 @@ const struct dsa_switch_ops rtl93xx_switch_ops = { .phy_read = rtldsa_phy_read, .phy_write = rtldsa_phy_write, - .phylink_get_caps = rtldsa_phylink_get_caps, + .phylink_get_caps = rtldsa_93xx_phylink_get_caps, .phylink_mac_config = rtl93xx_phylink_mac_config, .phylink_mac_link_down = rtl93xx_phylink_mac_link_down, .phylink_mac_link_up = rtl93xx_phylink_mac_link_up, -- 2.47.3