Netdev List
 help / color / mirror / Atom feed
* [PATCH net v3 0/2] net: dsa: b53: Fix IGMP/MLD snooping
@ 2026-10-28 23:50 Florian Fainelli
  2026-10-28 23:50 ` [PATCH net v3 1/2] net: dsa: b53: Enable IGMP and MLD control packet CPU copies Florian Fainelli
  2026-10-28 23:51 ` [PATCH net v3 2/2] net: dsa: b53: Enable legacy IGMP snooping controls Florian Fainelli
  0 siblings, 2 replies; 3+ messages in thread
From: Florian Fainelli @ 2026-10-28 23:50 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, Jonas Gorski, Andrew Lunn, Vladimir Oltean,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Russell King, Russell King (Oracle), open list

This patch series fixes IGMP and MLD snooping for b53, these were found
by running multicast membership/learning tests.

Changes in v3:

- move general IGMP/MLD snooping comment to be applicable to all
  switches, move comments about zero controls where they belong
- added IGMP snooping programming for older switches, too

Changes in v2:

- export the helper and call it from bcm_sf2.c as well as spotted by
  Sashiko

Florian Fainelli (2):
  net: dsa: b53: Enable IGMP and MLD control packet CPU copies
  net: dsa: b53: Enable legacy IGMP snooping controls

 drivers/net/dsa/b53/b53_common.c | 74 ++++++++++++++++++++++++++++++++
 drivers/net/dsa/b53/b53_priv.h   |  1 +
 drivers/net/dsa/b53/b53_regs.h   | 19 ++++++++
 drivers/net/dsa/bcm_sf2.c        |  5 +++
 4 files changed, 99 insertions(+)

-- 
2.53.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH net v3 1/2] net: dsa: b53: Enable IGMP and MLD control packet CPU copies
  2026-10-28 23:50 [PATCH net v3 0/2] net: dsa: b53: Fix IGMP/MLD snooping Florian Fainelli
@ 2026-10-28 23:50 ` Florian Fainelli
  2026-10-28 23:51 ` [PATCH net v3 2/2] net: dsa: b53: Enable legacy IGMP snooping controls Florian Fainelli
  1 sibling, 0 replies; 3+ messages in thread
From: Florian Fainelli @ 2026-10-28 23:50 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, Jonas Gorski, Andrew Lunn, Vladimir Oltean,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Russell King, Russell King (Oracle), open list

IGMPv2 reports and MLDv1 reports are addressed to the multicast group
itself. Once the first listener is installed in the ARL table, subsequent
reports can follow that entry without reaching the CPU. The bridge then
fails to learn additional listeners, although static MDB forwarding works.

Enable the high-level protocol classifiers so that IGMP and MLD control
packets are copied to the CPU independently of the multicast ARL lookup.
Retain normal L2 forwarding by clearing the CPU-only forwarding modes,
and preserve unrelated protocol-control fields.

Handle the BCM5395's 16-bit register and different classifier fields
separately from the 32-bit layout on the BCM531xx, BCM5301x and newer
integrated RoboSwitch families, including BCM7445, BCM7278 and BCM4908.
Export the helper and call it from bcm_sf2_sw_setup() as well, since SF2
uses its own setup operation instead of b53_setup(). This also restores
the classifiers after the switch reset on resume. Leave older devices
with different IGMP controls untouched, and propagate register access
failures during setup.

The SF2 setup integration and BCM4908 chip gate were updated with
assistance from OpenAI Codex in response to review feedback.

Fixes: 5d65b64a3d97 ("net: dsa: b53: Add support for MDB")
Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
---
 drivers/net/dsa/b53/b53_common.c | 57 ++++++++++++++++++++++++++++++++
 drivers/net/dsa/b53/b53_priv.h   |  1 +
 drivers/net/dsa/b53/b53_regs.h   | 17 ++++++++++
 drivers/net/dsa/bcm_sf2.c        |  5 +++
 4 files changed, 80 insertions(+)

diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index 0880310c9ce3..e54f6d4d1f7b 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -836,6 +836,59 @@ void b53_brcm_hdr_setup(struct dsa_switch *ds, int port)
 }
 EXPORT_SYMBOL(b53_brcm_hdr_setup);
 
+int b53_enable_mcast_snooping(struct b53_device *dev)
+{
+	u16 val16;
+	u32 val;
+	int ret;
+
+	/* Older switches use different IGMP controls, not HL_PRTC_CTRL. */
+	if (is5325(dev) || is5365(dev) || dev->chip_id == BCM5389_DEVICE_ID ||
+	    is5397_98(dev) || is63xx(dev))
+		return 0;
+
+	/* IGMPv2 and MLDv1 reports use the group's destination MAC. Once
+	 * the first listener is offloaded, ordinary multicast forwarding
+	 * can keep subsequent reports from reaching the bridge CPU.
+	 */
+
+	/* BCM5395 has a narrower register and a single IGMP classifier.
+	 * Its ICMPv6 classifier also covers MLD.
+	 */
+	if (dev->chip_id == BCM5395_DEVICE_ID) {
+		ret = b53_read16(dev, B53_MGMT_PAGE, B53_HL_PRTC_CTRL, &val16);
+		if (ret)
+			return ret;
+
+		val16 |= HL_PRTC_IGMP_IP_EN_5395 | HL_PRTC_ICMPV6_EN;
+		/* Zero forwarding modes copy control traffic to the CPU
+		 * independently of the ARL lookup, retaining L2 forwarding.
+		 */
+		val16 &= ~(HL_PRTC_IGMP_FWD_MODE_5395 |
+			   HL_PRTC_ICMPV6_FWD_MODE);
+
+		return b53_write16(dev, B53_MGMT_PAGE, B53_HL_PRTC_CTRL,
+				   val16);
+	}
+
+	ret = b53_read32(dev, B53_MGMT_PAGE, B53_HL_PRTC_CTRL, &val);
+	if (ret)
+		return ret;
+
+	val |= HL_PRTC_IGMP_RPTLVE_EN | HL_PRTC_IGMP_QRY_EN |
+	       HL_PRTC_IGMP_UKN_EN | HL_PRTC_MLD_RPTDONE_EN |
+	       HL_PRTC_MLD_QRY_EN;
+	/* Zero forwarding modes copy control traffic to the CPU
+	 * independently of the ARL lookup, retaining L2 forwarding.
+	 */
+	val &= ~(HL_PRTC_IGMP_RPTLVE_FWD_MODE | HL_PRTC_IGMP_QRY_FWD_MODE |
+		 HL_PRTC_IGMP_UKN_FWD_MODE | HL_PRTC_MLD_RPTDONE_FWD_MODE |
+		 HL_PRTC_MLD_QRY_FWD_MODE);
+
+	return b53_write32(dev, B53_MGMT_PAGE, B53_HL_PRTC_CTRL, val);
+}
+EXPORT_SYMBOL(b53_enable_mcast_snooping);
+
 static void b53_enable_cpu_port(struct b53_device *dev, int port)
 {
 	u8 port_ctrl;
@@ -1334,6 +1387,10 @@ static int b53_setup(struct dsa_switch *ds)
 			b53_disable_port(ds, port);
 	}
 
+	ret = b53_enable_mcast_snooping(dev);
+	if (ret)
+		return ret;
+
 	return b53_setup_devlink_resources(ds);
 }
 
diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h
index 29cca7945df7..c4d2a41c714f 100644
--- a/drivers/net/dsa/b53/b53_priv.h
+++ b/drivers/net/dsa/b53/b53_priv.h
@@ -504,6 +504,7 @@ static inline struct gpio_desc *b53_switch_get_reset_gpio(struct b53_device *dev
 /* Exported functions towards other drivers */
 void b53_imp_vlan_setup(struct dsa_switch *ds, int cpu_port);
 int b53_configure_vlan(struct dsa_switch *ds);
+int b53_enable_mcast_snooping(struct b53_device *dev);
 void b53_get_strings(struct dsa_switch *ds, int port, u32 stringset,
 		     uint8_t *data);
 void b53_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data);
diff --git a/drivers/net/dsa/b53/b53_regs.h b/drivers/net/dsa/b53/b53_regs.h
index 54a278db67c9..cfdb5ed38326 100644
--- a/drivers/net/dsa/b53/b53_regs.h
+++ b/drivers/net/dsa/b53/b53_regs.h
@@ -274,6 +274,23 @@
 /* Revision ID register (8 bit) */
 #define B53_REV_ID			0x40
 
+/* High-level protocol control (16 bit on BCM5395, otherwise 32 bit) */
+#define B53_HL_PRTC_CTRL			0x50
+#define   HL_PRTC_ICMPV6_EN		BIT(4)
+#define   HL_PRTC_ICMPV6_FWD_MODE		BIT(5)
+#define   HL_PRTC_IGMP_IP_EN_5395		BIT(6)
+#define   HL_PRTC_IGMP_FWD_MODE_5395	BIT(8)
+#define   HL_PRTC_IGMP_RPTLVE_EN		BIT(9)
+#define   HL_PRTC_IGMP_RPTLVE_FWD_MODE	BIT(10)
+#define   HL_PRTC_IGMP_QRY_EN		BIT(11)
+#define   HL_PRTC_IGMP_QRY_FWD_MODE	BIT(12)
+#define   HL_PRTC_IGMP_UKN_EN		BIT(13)
+#define   HL_PRTC_IGMP_UKN_FWD_MODE	BIT(14)
+#define   HL_PRTC_MLD_RPTDONE_EN		BIT(15)
+#define   HL_PRTC_MLD_RPTDONE_FWD_MODE	BIT(16)
+#define   HL_PRTC_MLD_QRY_EN		BIT(17)
+#define   HL_PRTC_MLD_QRY_FWD_MODE		BIT(18)
+
 /* Broadcom header RX control (16 bit) */
 #define B53_BRCM_HDR_RX_DIS		0x60
 
diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c
index 9e5713015187..1c846f6d7802 100644
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -1059,6 +1059,7 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds)
 {
 	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
 	unsigned int port;
+	int ret;
 
 	/* Enable all valid ports and disable those unused */
 	for (port = 0; port < priv->hw_params.num_ports; port++) {
@@ -1074,6 +1075,10 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds)
 	b53_configure_vlan(ds);
 	bcm_sf2_enable_acb(ds);
 
+	ret = b53_enable_mcast_snooping(priv->dev);
+	if (ret)
+		return ret;
+
 	return b53_setup_devlink_resources(ds);
 }
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH net v3 2/2] net: dsa: b53: Enable legacy IGMP snooping controls
  2026-10-28 23:50 [PATCH net v3 0/2] net: dsa: b53: Fix IGMP/MLD snooping Florian Fainelli
  2026-10-28 23:50 ` [PATCH net v3 1/2] net: dsa: b53: Enable IGMP and MLD control packet CPU copies Florian Fainelli
@ 2026-10-28 23:51 ` Florian Fainelli
  1 sibling, 0 replies; 3+ messages in thread
From: Florian Fainelli @ 2026-10-28 23:51 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, Jonas Gorski, Andrew Lunn, Vladimir Oltean,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Russell King, Russell King (Oracle), open list

The older switches do not implement the high-level protocol control
register used by newer devices, so they are currently skipped when
setting up multicast control packet delivery to the CPU.

Enable the IP-layer IGMP classifier in the 8-bit global management
configuration register on BCM5325E, BCM5365, BCM5389, BCM5397/5398 and
BCM63xx. Their manuals place this control at bit 3 of page 0x02, offset
0x00. Preserve the other management fields and propagate access errors.
Clear the separate IGMP redirection enable on BCM6318 and BCM63268 to
use snooping mode, as documented in 6318-PR100-R and 63X68-PR201-R.

These legacy classifiers have fixed forwarding behavior, including
query flooding which excludes the IMP on BCM5397/5398 and BCM63xx.
They do not provide the newer per-message IGMP/MLD controls. This change
only enables the documented legacy IGMP handling; it does not add MLD
classification.

Keep BCM5325M and unidentified BCM5325 variants excluded. The BCM5325M
manual reserves the global management IGMP bit and instead describes
snooping through the shared mirroring engine, requiring a different
implementation and coordination with port mirroring.

Fixes: 5d65b64a3d97 ("net: dsa: b53: Add support for MDB")
Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
---
 drivers/net/dsa/b53/b53_common.c | 23 ++++++++++++++++++++---
 drivers/net/dsa/b53/b53_regs.h   |  2 ++
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index e54f6d4d1f7b..957a1501d3f4 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -841,12 +841,29 @@ int b53_enable_mcast_snooping(struct b53_device *dev)
 	u16 val16;
 	u32 val;
 	int ret;
+	u8 val8;
 
-	/* Older switches use different IGMP controls, not HL_PRTC_CTRL. */
-	if (is5325(dev) || is5365(dev) || dev->chip_id == BCM5389_DEVICE_ID ||
-	    is5397_98(dev) || is63xx(dev))
+	/* BCM5325M snooping uses the mirroring engine instead. */
+	if (is5325(dev) && !is5325e(dev))
 		return 0;
 
+	/* Older switches classify IGMP in the global management register.
+	 * They do not provide the separate MLD controls of newer switches.
+	 */
+	if (is5325e(dev) || is5365(dev) ||
+	    dev->chip_id == BCM5389_DEVICE_ID || is5397_98(dev) || is63xx(dev)) {
+		ret = b53_read8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, &val8);
+		if (ret)
+			return ret;
+
+		val8 |= GC_IGMP_IP_EN;
+		/* Disable the separate IGMP redirection mode on BCM6318/63268. */
+		if (is6318_268(dev))
+			val8 &= ~GC_IGMP_RED_EN_6318_268;
+
+		return b53_write8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, val8);
+	}
+
 	/* IGMPv2 and MLDv1 reports use the group's destination MAC. Once
 	 * the first listener is offloaded, ordinary multicast forwarding
 	 * can keep subsequent reports from reaching the bridge CPU.
diff --git a/drivers/net/dsa/b53/b53_regs.h b/drivers/net/dsa/b53/b53_regs.h
index cfdb5ed38326..e994d3a188c7 100644
--- a/drivers/net/dsa/b53/b53_regs.h
+++ b/drivers/net/dsa/b53/b53_regs.h
@@ -217,6 +217,8 @@
 #define B53_GLOBAL_CONFIG		0x00
 #define   GC_RESET_MIB			0x01
 #define   GC_RX_BPDU_EN			0x02
+#define   GC_IGMP_IP_EN			BIT(3)
+#define   GC_IGMP_RED_EN_6318_268		BIT(4)
 #define   GC_MIB_AC_HDR_EN		0x10
 #define   GC_MIB_AC_EN			0x20
 #define   GC_FRM_MGMT_PORT_M		0xC0
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-10-28 23:51 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-28 23:50 [PATCH net v3 0/2] net: dsa: b53: Fix IGMP/MLD snooping Florian Fainelli
2026-10-28 23:50 ` [PATCH net v3 1/2] net: dsa: b53: Enable IGMP and MLD control packet CPU copies Florian Fainelli
2026-10-28 23:51 ` [PATCH net v3 2/2] net: dsa: b53: Enable legacy IGMP snooping controls Florian Fainelli

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox