diff --git a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/dsa.c b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/dsa.c index 2ee1e0f4627..d8405d9a247 100644 --- a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/dsa.c +++ b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/dsa.c @@ -329,8 +329,7 @@ static void rtldsa_93xx_phylink_mac_config(struct phylink_config *config, return; cfg = &priv->r->mac_force_mode; - force_dynamic_phy = priv->family_id == RTL9300_FAMILY_ID && - !priv->ports[port].phy && + force_dynamic_phy = !priv->ports[port].phy && (mode == MLO_AN_PHY || state->interface == PHY_INTERFACE_MODE_SGMII); /* Select PCS before dropping force mode to avoid a transient link down. */ @@ -340,8 +339,7 @@ static void rtldsa_93xx_phylink_mac_config(struct phylink_config *config, RTLDSA_MAC_LINK_STATE_SOURCE_PCS, state->interface); - if (priv->family_id == RTL9300_FAMILY_ID && - (mode == MLO_AN_FIXED || force_dynamic_phy)) { + if (mode == MLO_AN_FIXED || force_dynamic_phy) { /* Keep links that require force mode forced down. */ regmap_write(priv->map, priv->r->mac_force_mode_ctrl(port), cfg->force_en_mask | cfg->fc_force_en_mask); @@ -385,8 +383,7 @@ static void rtldsa_93xx_phylink_mac_link_down(struct phylink_config *config, int port = dp->index; cfg = &priv->r->mac_force_mode; - force_dynamic_phy = priv->family_id == RTL9300_FAMILY_ID && - !priv->ports[port].phy && + force_dynamic_phy = !priv->ports[port].phy && (mode == MLO_AN_PHY || interface == PHY_INTERFACE_MODE_SGMII); /* Stop TX/RX to port */ @@ -398,8 +395,7 @@ static void rtldsa_93xx_phylink_mac_link_down(struct phylink_config *config, RTLDSA_MAC_LINK_STATE_SOURCE_PCS, interface); - if (priv->family_id == RTL9300_FAMILY_ID && - (dsa_port_is_cpu(dp) || mode == MLO_AN_FIXED || force_dynamic_phy)) { + if (dsa_port_is_cpu(dp) || mode == MLO_AN_FIXED || force_dynamic_phy) { /* Preserve force mode while forcing the link down. */ regmap_update_bits(priv->map, priv->r->mac_force_mode_ctrl(port), cfg->link_up_mask, 0); @@ -473,9 +469,6 @@ static void rtldsa_93xx_phylink_mac_link_up(struct phylink_config *config, bool dynamic_phy, force_dynamic_phy, keep_forced; u32 mcr, spdsel; - if (priv->family_id != RTL9300_FAMILY_ID) - goto restart; - /* * The RTL93xx polling machinery does more than issue MDIO * transactions. It collects resolved link state and distributes it diff --git a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/mac.h b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/mac.h index 0f7ff70bbaf..2b631f9014e 100644 --- a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/mac.h +++ b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/mac.h @@ -34,7 +34,15 @@ #define RTL930X_MEDIA_SEL BIT(16) #define RTL931X_FORCE_LINK_EN BIT(0) +#define RTL931X_FORCE_DUPLEX_EN BIT(2) +#define RTL931X_FORCE_SPEED_EN BIT(3) +#define RTL931X_MAC_FORCE_FC_EN BIT(4) #define RTL931X_FORCE_LINK BIT(9) +#define RTL931X_DUPLEX_MODE BIT(11) +#define RTL931X_SPEED_SHIFT (12) +#define RTL931X_SPEED_MASK (15 << RTL931X_SPEED_SHIFT) +#define RTL931X_TX_PAUSE_EN BIT(16) +#define RTL931X_RX_PAUSE_EN BIT(17) enum rtldsa_mac_link_state_source { RTLDSA_MAC_LINK_STATE_SOURCE_PCS, diff --git a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl931x.c b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl931x.c index 966cf4245b2..0cef4f06a97 100644 --- a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl931x.c +++ b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl931x.c @@ -2,6 +2,7 @@ #include #include +#include #include "lag.h" #include "l2.h" @@ -82,6 +83,11 @@ #define RTL931X_LED_CLK_SEL_200NS 2 #define RTL931X_LED_CLK_SEL_100NS 3 +#define RTL931X_SMI_PHY_ABLTY_GET_SEL(port) (0x0cac + ((port) / 16) * 4) +#define RTL931X_SMI_PHY_ABLTY_MDIO 0x0 +#define RTL931X_SMI_PHY_ABLTY_SDS 0x2 +#define RTL931X_SMI_PHY_ABLTY_MASK(port) (GENMASK(1, 0) << (((port) % 16) * 2)) + static inline int rtl931x_mac_force_mode_ctrl(int p) { return RTL931X_MAC_FORCE_MODE_CTRL + (p << 2); @@ -382,6 +388,28 @@ static void rtldsa_931x_led_init(struct rtl838x_switch_priv *priv) dev_dbg(dev, "%08x: %08x\n", 0xbb000600 + i * 4, sw_r32(0x0600 + i * 4)); } +static int +rtldsa_931x_mac_link_state_source_set(struct rtl838x_switch_priv *priv, + int port, + enum rtldsa_mac_link_state_source source, + phy_interface_t interface) +{ + u32 mask, src_val; + + if (port >= RTL931X_CPU_PORT) + return 0; + + mask = RTL931X_SMI_PHY_ABLTY_MASK(port); + if (source == RTLDSA_MAC_LINK_STATE_SOURCE_PCS) + src_val = RTL931X_SMI_PHY_ABLTY_SDS; + else + src_val = RTL931X_SMI_PHY_ABLTY_MDIO; + + return regmap_update_bits(priv->map, + RTL931X_SMI_PHY_ABLTY_GET_SEL(port), + mask, field_prep(mask, src_val)); +} + const struct rtldsa_config rtldsa_931x_cfg = { .switch_ops = &rtldsa_93xx_switch_ops, .phylink_mac_ops = &rtldsa_93xx_phylink_mac_ops, @@ -432,10 +460,18 @@ const struct rtldsa_config rtldsa_931x_cfg = { .stp_get = rtldsa_931x_stp_get, .stp_set = rtl931x_stp_set, .mac_force_mode = { - .force_en_mask = RTL931X_FORCE_LINK_EN, + .force_en_mask = RTL931X_FORCE_LINK_EN | + RTL931X_FORCE_DUPLEX_EN | + RTL931X_FORCE_SPEED_EN, + .fc_force_en_mask = RTL931X_MAC_FORCE_FC_EN, .link_up_mask = RTL931X_FORCE_LINK, + .duplex_mask = RTL931X_DUPLEX_MODE, + .speed_mask = RTL931X_SPEED_MASK, + .tx_pause_mask = RTL931X_TX_PAUSE_EN, + .rx_pause_mask = RTL931X_RX_PAUSE_EN, }, .mac_force_mode_ctrl = rtl931x_mac_force_mode_ctrl, + .mac_link_state_source_set = rtldsa_931x_mac_link_state_source_set, .mac_link_sts = RTL931X_MAC_LINK_STS, .mac_port_ctrl = rtl931x_mac_port_ctrl, .mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | MAC_10 | MAC_100 |