[openwrt/openwrt] realtek: dsa: rtl931x: configure phy ability source
LEDE Commits
lede-commits at lists.infradead.org
Fri Jan 2 12:36:02 PST 2026
hauke pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/e58192934151ca6500f6bc81b580239d6204d864
commit e58192934151ca6500f6bc81b580239d6204d864
Author: Jonas Jelonek <jelonek.jonas at gmail.com>
AuthorDate: Thu Jan 1 20:11:17 2026 +0000
realtek: dsa: rtl931x: configure phy ability source
The MAC can get PHY abilities, link status, etc. via different ways. In
RTL931x, the corresponding register needs to be setup properly. By
default, all ports use out-of-band MDIO polling to retrieve that
information. Thus, PHY-backed ports usually work with the default
setting.
For SFP ports, there is no MDIO polling available. Instead, the SerDes
ability bus needs to be used to retrieve the link information.
So far, the bootloader (e.g. U-boot) had to properly initialize that
setting. Instead of relying on that, do that properly during MAC setup.
Signed-off-by: Jonas Jelonek <jelonek.jonas at gmail.com>
Link: https://github.com/openwrt/openwrt/pull/21351
Signed-off-by: Hauke Mehrtens <hauke at hauke-m.de>
---
.../files-6.12/drivers/net/dsa/rtl83xx/dsa.c | 4 +++
.../files-6.12/drivers/net/dsa/rtl83xx/rtl83xx.h | 1 +
.../files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c | 29 ++++++++++++++++++++++
3 files changed, 34 insertions(+)
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 5ddff2a1b4..b9c7cda60c 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
@@ -614,6 +614,10 @@ static int rtl93xx_setup(struct dsa_switch *ds)
}
priv->r->traffic_set(priv->cpu_port, BIT_ULL(priv->cpu_port));
+ /* Configure how MAC gets PHY ability for each port */
+ if (priv->family_id == RTL9310_FAMILY_ID)
+ rtldsa_931x_config_phy_ability_source(priv);
+
if (priv->family_id == RTL9300_FAMILY_ID)
rtl930x_print_matrix();
else if (priv->family_id == RTL9310_FAMILY_ID)
diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl83xx.h b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl83xx.h
index a3cb62ceb7..38a8f94ef8 100644
--- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl83xx.h
+++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl83xx.h
@@ -182,6 +182,7 @@ void rtl930x_print_matrix(void);
/* RTL931x-specific */
irqreturn_t rtl931x_switch_irq(int irq, void *dev_id);
void rtl931x_print_matrix(void);
+void rtldsa_931x_config_phy_ability_source(struct rtl838x_switch_priv *priv);
int rtl83xx_lag_add(struct dsa_switch *ds, int group, int port, struct netdev_lag_upper_info *info);
int rtl83xx_lag_del(struct dsa_switch *ds, int group, int port);
diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c
index bb51c6e7e8..e6e42a4bc1 100644
--- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c
+++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c
@@ -25,6 +25,11 @@
#define RTL931X_VLAN_PORT_TAG_ITPID_IDX_MASK GENMASK(2, 1)
#define RTL931X_VLAN_PORT_TAG_ITPID_KEEP_MASK GENMASK(0, 0)
+#define RTLDSA_931X_SMI_PHY_ABLTY_GET_SEL 0x0cac
+#define RTLDSA_931X_PHY_ABLTY_OUTBAND_MDIO 0x0
+#define RTLDSA_931X_PHY_ABLTY_INBAND_SDS_POLL 0x1
+#define RTLDSA_931X_PHY_ABLTY_SDS_ABLTY_BUS 0x2
+
/* Definition of the RTL931X-specific template field IDs as used in the PIE */
enum template_field_id {
TEMPLATE_FIELD_SPM0 = 1,
@@ -1764,6 +1769,30 @@ static void rtldsa_931x_qos_init(struct rtl838x_switch_priv *priv)
rtldsa_931x_qos_set_scheduling_queue_weights(priv);
}
+void rtldsa_931x_config_phy_ability_source(struct rtl838x_switch_priv *priv)
+{
+ u32 phy_ablty_sel[4] = {0};
+
+ for (int port = 0; port < priv->cpu_port; port++) {
+ u32 val = RTLDSA_931X_PHY_ABLTY_OUTBAND_MDIO;
+
+ /* port driven by SerDes */
+ if (!priv->ports[port].phy && priv->pcs[port])
+ val = RTLDSA_931X_PHY_ABLTY_SDS_ABLTY_BUS;
+
+ phy_ablty_sel[port / 16] |= (val & 0x3) << ((port % 16) * 2);
+ }
+
+ pr_debug("%s: phy_ablty_sel [0] %x [1] %x [2] %x [3] %x\n", __func__,
+ phy_ablty_sel[0], phy_ablty_sel[1], phy_ablty_sel[2],
+ phy_ablty_sel[3]);
+
+ sw_w32(phy_ablty_sel[0], RTLDSA_931X_SMI_PHY_ABLTY_GET_SEL);
+ sw_w32(phy_ablty_sel[1], RTLDSA_931X_SMI_PHY_ABLTY_GET_SEL + 0x4);
+ sw_w32(phy_ablty_sel[2], RTLDSA_931X_SMI_PHY_ABLTY_GET_SEL + 0x8);
+ sw_w32(phy_ablty_sel[3], RTLDSA_931X_SMI_PHY_ABLTY_GET_SEL + 0xc);
+}
+
const struct rtl838x_reg rtl931x_reg = {
.mask_port_reg_be = rtl839x_mask_port_reg_be,
.set_port_reg_be = rtl839x_set_port_reg_be,
More information about the lede-commits
mailing list