realtek: refactor RTL930x MAC config to fix PHY ports

Currently, network ports using PHYs get a link, but there is no traffic.
Make it work again by moving the MAC config to phylink_mac_link_up.

A similiar change has been previously applied for RTL83xx in commit
cd958d945be0 ("realtek: 6.6: refactor mac config and link up for
RTL83xx").

Fixes: https://github.com/openwrt/openwrt/issues/17010
Signed-off-by: Jan Hoffmann <jan@3e8.eu>
Tested-by: Christoph Krapp <achterin@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/18268
Signed-off-by: Sander Vanheule <sander@svanheule.net>
This commit is contained in:
Jan Hoffmann 2025-02-27 20:43:26 +01:00 committed by Sander Vanheule
parent fa50e53aa9
commit a7e1e13817
2 changed files with 44 additions and 47 deletions

View File

@ -798,10 +798,6 @@ static void rtl93xx_phylink_mac_config(struct dsa_switch *ds, int port,
{
struct rtl838x_switch_priv *priv = ds->priv;
int sds_num;
u32 reg;
pr_info("%s port %d, mode %x, phy-mode: %s, speed %d, link %d\n", __func__,
port, mode, phy_modes(state->interface), state->speed, state->link);
/* Nothing to be done for the CPU-port */
if (port == priv->cpu_port)
@ -817,48 +813,6 @@ static void rtl93xx_phylink_mac_config(struct dsa_switch *ds, int port,
state->interface == PHY_INTERFACE_MODE_SGMII ||
state->interface == PHY_INTERFACE_MODE_10GBASER))
rtl9300_serdes_setup(port, sds_num, state->interface);
reg = sw_r32(priv->r->mac_force_mode_ctrl(port));
reg &= ~(0xf << 3);
switch (state->speed) {
case SPEED_10000:
reg |= 4 << 3;
break;
case SPEED_5000:
reg |= 6 << 3;
break;
case SPEED_2500:
reg |= 5 << 3;
break;
case SPEED_1000:
reg |= 2 << 3;
break;
case SPEED_100:
reg |= 1 << 3;
break;
default:
/* Also covers 10M */
break;
}
if (state->link)
reg |= RTL930X_FORCE_LINK_EN;
if (priv->lagmembers & BIT_ULL(port))
reg |= RTL930X_DUPLEX_MODE | RTL930X_FORCE_LINK_EN;
if (state->duplex == DUPLEX_FULL)
reg |= RTL930X_DUPLEX_MODE;
else
reg &= ~RTL930X_DUPLEX_MODE; /* Clear duplex bit otherwise */
if (priv->ports[port].phy_is_integrated)
reg &= ~RTL930X_FORCE_EN; /* Clear MAC_FORCE_EN to allow SDS-MAC link */
else
reg |= RTL930X_FORCE_EN;
sw_w32(reg, priv->r->mac_force_mode_ctrl(port));
}
static void rtl83xx_phylink_mac_link_down(struct dsa_switch *ds, int port,
@ -964,11 +918,49 @@ static void rtl93xx_phylink_mac_link_up(struct dsa_switch *ds, int port,
int speed, int duplex,
bool tx_pause, bool rx_pause)
{
struct dsa_port *dp = dsa_to_port(ds, port);
struct rtl838x_switch_priv *priv = ds->priv;
u32 mcr, spdsel;
if (speed == SPEED_10000)
spdsel = RTL_SPEED_10000;
else if (speed == SPEED_5000)
spdsel = RTL_SPEED_5000;
else if (speed == SPEED_2500)
spdsel = RTL_SPEED_2500;
else if (speed == SPEED_1000)
spdsel = RTL_SPEED_1000;
else if (speed == SPEED_100)
spdsel = RTL_SPEED_100;
else
spdsel = RTL_SPEED_10;
mcr = sw_r32(priv->r->mac_force_mode_ctrl(port));
if (priv->family_id == RTL9300_FAMILY_ID) {
mcr &= ~RTL930X_RX_PAUSE_EN;
mcr &= ~RTL930X_TX_PAUSE_EN;
mcr &= ~RTL930X_DUPLEX_MODE;
mcr &= ~RTL930X_SPEED_MASK;
mcr |= RTL930X_FORCE_LINK_EN;
mcr |= spdsel << RTL930X_SPEED_SHIFT;
if (tx_pause)
mcr |= RTL930X_TX_PAUSE_EN;
if (rx_pause)
mcr |= RTL930X_RX_PAUSE_EN;
if (duplex == DUPLEX_FULL || priv->lagmembers & BIT_ULL(port))
mcr |= RTL930X_DUPLEX_MODE;
if (dsa_port_is_cpu(dp) || !priv->ports[port].phy_is_integrated)
mcr |= RTL930X_FORCE_EN;
}
pr_debug("%s port %d, mode %x, speed %d, duplex %d, txpause %d, rxpause %d: set mcr=%08x\n",
__func__, port, mode, speed, duplex, tx_pause, rx_pause, mcr);
sw_w32(mcr, priv->r->mac_force_mode_ctrl(port));
/* Restart TX/RX to port */
sw_w32_mask(0, 0x3, priv->r->mac_port_ctrl(port));
/* TODO: Set speed/duplex/pauses */
}
static void rtl83xx_get_strings(struct dsa_switch *ds,

View File

@ -147,6 +147,9 @@
#define RTL_SPEED_10 0
#define RTL_SPEED_100 1
#define RTL_SPEED_1000 2
#define RTL_SPEED_2500 5
#define RTL_SPEED_5000 6
#define RTL_SPEED_10000 4
#define RTL83XX_FORCE_EN (1 << 0)
#define RTL83XX_FORCE_LINK_EN (1 << 1)
@ -169,6 +172,8 @@
#define RTL930X_FORCE_EN (1 << 0)
#define RTL930X_FORCE_LINK_EN (1 << 1)
#define RTL930X_DUPLEX_MODE (1 << 2)
#define RTL930X_SPEED_SHIFT (3)
#define RTL930X_SPEED_MASK (15 << RTL930X_SPEED_SHIFT)
#define RTL930X_TX_PAUSE_EN (1 << 7)
#define RTL930X_RX_PAUSE_EN (1 << 8)
#define RTL930X_MAC_FORCE_FC_EN (1 << 9)