summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Kicinski <kuba@kernel.org>2025-11-03 16:40:37 -0800
committerJakub Kicinski <kuba@kernel.org>2025-11-03 16:40:38 -0800
commitc7321193bcd7ddb22fdd9ae26516c8963e31e134 (patch)
tree5a9625780272d9cd4539e28534c393350270c171
parent7ed8b63ddc9a9578eae81f4da32761568a25efad (diff)
parent3e4ebdc1606adf77744cf8ed7a433d279fdc57ba (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.c21
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;
}