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,