diff options
| author | Jakub Kicinski <kuba@kernel.org> | 2025-11-03 16:40:37 -0800 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2025-11-03 16:40:38 -0800 |
| commit | c7321193bcd7ddb22fdd9ae26516c8963e31e134 (patch) | |
| tree | 5a9625780272d9cd4539e28534c393350270c171 | |
| parent | 7ed8b63ddc9a9578eae81f4da32761568a25efad (diff) | |
| parent | 3e4ebdc1606adf77744cf8ed7a433d279fdc57ba (diff) | |
Merge branch 'net-dsa-b53-fix-bcm63xx-rgmii-user-ports-with-speed-1g'
Jonas Gorski says:
====================
net: dsa: b53: fix bcm63xx rgmii user ports with speed < 1g
It seems that the integrated switch in bcm63xx does not support polling
external PHYs for link configuration. While the appropriate registers
seem to exist with expected content, changing them does nothing.
This results in user ports with external PHYs only working in 1000/fd,
and not in other modes, despite linking up.
Fix this by writing the link result into the port state override
register, like we already do for fixed links.
With this, ports with lower speeds can successfully transmit and receive
packets.
This also aligns the behaviour with the old bcm63xx_enetsw driver for
those ports.
====================
Link: https://patch.msgid.link/20251101132807.50419-1-jonas.gorski@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
| -rw-r--r-- | drivers/net/dsa/b53/b53_common.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c index 2f846381d5a7..bb2c6dfa7835 100644 --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c @@ -1372,6 +1372,10 @@ static void b53_force_port_config(struct b53_device *dev, int port, else reg &= ~PORT_OVERRIDE_FULL_DUPLEX; + reg &= ~(0x3 << GMII_PO_SPEED_S); + if (is5301x(dev) || is58xx(dev)) + reg &= ~PORT_OVERRIDE_SPEED_2000M; + switch (speed) { case 2000: reg |= PORT_OVERRIDE_SPEED_2000M; @@ -1390,6 +1394,11 @@ static void b53_force_port_config(struct b53_device *dev, int port, return; } + if (is5325(dev)) + reg &= ~PORT_OVERRIDE_LP_FLOW_25; + else + reg &= ~(PORT_OVERRIDE_RX_FLOW | PORT_OVERRIDE_TX_FLOW); + if (rx_pause) { if (is5325(dev)) reg |= PORT_OVERRIDE_LP_FLOW_25; @@ -1593,8 +1602,11 @@ static void b53_phylink_mac_link_down(struct phylink_config *config, struct b53_device *dev = dp->ds->priv; int port = dp->index; - if (mode == MLO_AN_PHY) + if (mode == MLO_AN_PHY) { + if (is63xx(dev) && in_range(port, B53_63XX_RGMII0, 4)) + b53_force_link(dev, port, false); return; + } if (mode == MLO_AN_FIXED) { b53_force_link(dev, port, false); @@ -1622,6 +1634,13 @@ static void b53_phylink_mac_link_up(struct phylink_config *config, if (mode == MLO_AN_PHY) { /* Re-negotiate EEE if it was enabled already */ p->eee_enabled = b53_eee_init(ds, port, phydev); + + if (is63xx(dev) && in_range(port, B53_63XX_RGMII0, 4)) { + b53_force_port_config(dev, port, speed, duplex, + tx_pause, rx_pause); + b53_force_link(dev, port, true); + } + return; } |
