mirror of
https://git.openwrt.org/openwrt/openwrt.git
synced 2025-12-10 06:24:40 +01:00
Add a new microchipsw target aimed add supporting Microchip switch SoC-s. Start by supporting LAN969x SoC-s as the first subtarget. Signed-off-by: Robert Marko <robert.marko@sartura.hr>
137 lines
5.2 KiB
Diff
137 lines
5.2 KiB
Diff
From c9d1b0b54258ba13b567dd116ead3c7c30cba7d8 Mon Sep 17 00:00:00 2001
|
|
From: Daniel Machon <daniel.machon@microchip.com>
|
|
Date: Fri, 3 Oct 2025 14:35:59 +0200
|
|
Subject: [PATCH] net: sparx5/lan969x: fix flooding configuration on bridge
|
|
join/leave
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
The sparx5 driver programs UC/MC/BC flooding in sparx5_update_fwd() by
|
|
unconditionally applying bridge_fwd_mask to all flood PGIDs. Any bridge
|
|
topology change that triggers sparx5_update_fwd() (for example enslaving
|
|
another port) therefore reinstalls flooding in hardware for already
|
|
bridged ports, regardless of their per-port flood flags.
|
|
|
|
This results in clobbering of the flood masks, and desynchronization
|
|
between software and hardware: the bridge still reports “flood off” for
|
|
the port, but hardware has flooding enabled due to unconditional PGID
|
|
reprogramming.
|
|
|
|
Steps to reproduce:
|
|
|
|
$ ip link add br0 type bridge
|
|
$ ip link set br0 up
|
|
$ ip link set eth0 master br0
|
|
$ ip link set eth0 up
|
|
$ bridge link set dev eth0 flood off
|
|
$ ip link set eth1 master br0
|
|
$ ip link set eth1 up
|
|
|
|
At this point, flooding is silently re-enabled for eth0. Software still
|
|
shows “flood off” for eth0, but hardware has flooding enabled.
|
|
|
|
To fix this, flooding is now set explicitly during bridge join/leave,
|
|
through sparx5_port_attr_bridge_flags():
|
|
|
|
On bridge join, UC/MC/BC flooding is enabled by default.
|
|
|
|
On bridge leave, UC/MC/BC flooding is disabled.
|
|
|
|
sparx5_update_fwd() no longer touches the flood PGIDs, clobbering
|
|
the flood masks, and desynchronizing software and hardware.
|
|
|
|
Initialization of the flooding PGIDs have been moved to
|
|
sparx5_start(). This is required as flooding PGIDs defaults to
|
|
0x3fffffff in hardware and the initialization was previously handled
|
|
in sparx5_update_fwd(), which was removed.
|
|
|
|
With this change, user-configured flooding flags persist across bridge
|
|
updates and are no longer overridden by sparx5_update_fwd().
|
|
|
|
Fixes: d6fce5141929 ("net: sparx5: add switching support")
|
|
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
|
Reviewed-by: Simon Horman <horms@kernel.org>
|
|
Link: https://patch.msgid.link/20251003-fix-flood-fwd-v1-1-48eb478b2904@microchip.com
|
|
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|
---
|
|
drivers/net/ethernet/microchip/sparx5/sparx5_main.c | 5 +++++
|
|
.../net/ethernet/microchip/sparx5/sparx5_switchdev.c | 12 ++++++++++++
|
|
drivers/net/ethernet/microchip/sparx5/sparx5_vlan.c | 10 ----------
|
|
3 files changed, 17 insertions(+), 10 deletions(-)
|
|
|
|
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
|
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
|
@@ -709,6 +709,11 @@ static int sparx5_start(struct sparx5 *s
|
|
/* Init masks */
|
|
sparx5_update_fwd(sparx5);
|
|
|
|
+ /* Init flood masks */
|
|
+ for (int pgid = sparx5_get_pgid(sparx5, PGID_UC_FLOOD);
|
|
+ pgid <= sparx5_get_pgid(sparx5, PGID_BCAST); pgid++)
|
|
+ sparx5_pgid_clear(sparx5, pgid);
|
|
+
|
|
/* CPU copy CPU pgids */
|
|
spx5_wr(ANA_AC_PGID_MISC_CFG_PGID_CPU_COPY_ENA_SET(1), sparx5,
|
|
ANA_AC_PGID_MISC_CFG(sparx5_get_pgid(sparx5, PGID_CPU)));
|
|
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c
|
|
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c
|
|
@@ -176,6 +176,7 @@ static int sparx5_port_bridge_join(struc
|
|
struct net_device *bridge,
|
|
struct netlink_ext_ack *extack)
|
|
{
|
|
+ struct switchdev_brport_flags flags = {0};
|
|
struct sparx5 *sparx5 = port->sparx5;
|
|
struct net_device *ndev = port->ndev;
|
|
int err;
|
|
@@ -205,6 +206,11 @@ static int sparx5_port_bridge_join(struc
|
|
*/
|
|
__dev_mc_unsync(ndev, sparx5_mc_unsync);
|
|
|
|
+ /* Enable uc/mc/bc flooding */
|
|
+ flags.mask = BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD;
|
|
+ flags.val = flags.mask;
|
|
+ sparx5_port_attr_bridge_flags(port, flags);
|
|
+
|
|
return 0;
|
|
|
|
err_switchdev_offload:
|
|
@@ -215,6 +221,7 @@ err_switchdev_offload:
|
|
static void sparx5_port_bridge_leave(struct sparx5_port *port,
|
|
struct net_device *bridge)
|
|
{
|
|
+ struct switchdev_brport_flags flags = {0};
|
|
struct sparx5 *sparx5 = port->sparx5;
|
|
|
|
switchdev_bridge_port_unoffload(port->ndev, NULL, NULL, NULL);
|
|
@@ -234,6 +241,11 @@ static void sparx5_port_bridge_leave(str
|
|
|
|
/* Port enters in host more therefore restore mc list */
|
|
__dev_mc_sync(port->ndev, sparx5_mc_sync, sparx5_mc_unsync);
|
|
+
|
|
+ /* Disable uc/mc/bc flooding */
|
|
+ flags.mask = BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD;
|
|
+ flags.val = 0;
|
|
+ sparx5_port_attr_bridge_flags(port, flags);
|
|
}
|
|
|
|
static int sparx5_port_changeupper(struct net_device *dev,
|
|
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_vlan.c
|
|
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_vlan.c
|
|
@@ -167,16 +167,6 @@ void sparx5_update_fwd(struct sparx5 *sp
|
|
/* Divide up fwd mask in 32 bit words */
|
|
bitmap_to_arr32(mask, sparx5->bridge_fwd_mask, SPX5_PORTS);
|
|
|
|
- /* Update flood masks */
|
|
- for (port = sparx5_get_pgid(sparx5, PGID_UC_FLOOD);
|
|
- port <= sparx5_get_pgid(sparx5, PGID_BCAST); port++) {
|
|
- spx5_wr(mask[0], sparx5, ANA_AC_PGID_CFG(port));
|
|
- if (is_sparx5(sparx5)) {
|
|
- spx5_wr(mask[1], sparx5, ANA_AC_PGID_CFG1(port));
|
|
- spx5_wr(mask[2], sparx5, ANA_AC_PGID_CFG2(port));
|
|
- }
|
|
- }
|
|
-
|
|
/* Update SRC masks */
|
|
for (port = 0; port < sparx5->data->consts->n_ports; port++) {
|
|
if (test_bit(port, sparx5->bridge_fwd_mask)) {
|