[RFC PATCH 08/10] net: dsa: b53: fix unicast/multicast flooding on BCM5325

Álvaro Fernández Rojas posted 10 patches 6 months, 2 weeks ago
There is a newer version of this series
[RFC PATCH 08/10] net: dsa: b53: fix unicast/multicast flooding on BCM5325
Posted by Álvaro Fernández Rojas 6 months, 2 weeks ago
BCM5325 doesn't implement UC_FLOOD_MASK, MC_FLOOD_MASK and IPMC_FLOOD_MASK
registers.
This has to be handled differently with other pages and registers.

Fixes: a8b659e7ff75 ("net: dsa: act as passthrough for bridge port flags")
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
 drivers/net/dsa/b53/b53_common.c | 85 +++++++++++++++++++++++++-------
 drivers/net/dsa/b53/b53_regs.h   | 38 ++++++++++++++
 2 files changed, 105 insertions(+), 18 deletions(-)

diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index 387e1e7ec749..d5216ea2c984 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -560,12 +560,36 @@ static void b53_port_set_ucast_flood(struct b53_device *dev, int port,
 {
 	u16 uc;
 
-	b53_read16(dev, B53_CTRL_PAGE, B53_UC_FLOOD_MASK, &uc);
-	if (unicast)
-		uc |= BIT(port);
-	else
-		uc &= ~BIT(port);
-	b53_write16(dev, B53_CTRL_PAGE, B53_UC_FLOOD_MASK, uc);
+	if (is5325(dev)) {
+		u8 rc;
+
+		if (port == B53_CPU_PORT_25)
+			port = B53_CPU_PORT;
+
+		b53_read16(dev, B53_IEEE_PAGE, B53_IEEE_UCAST_DLF, &uc);
+		if (unicast)
+			uc |= BIT(port) | B53_IEEE_UCAST_DROP_EN;
+		else
+			uc &= ~BIT(port);
+		b53_write16(dev, B53_IEEE_PAGE, B53_IEEE_UCAST_DLF, uc);
+
+		if (port >= B53_CPU_PORT_25)
+			return;
+
+		b53_read8(dev, B53_RATE_CTL_PAGE, B53_RATE_CONTROL(port), &rc);
+		if (unicast)
+			rc |= (RC_DLF_EN | RC_BKT_SIZE_8K | RC_PERCENT_40);
+		else
+			rc &= ~(RC_DLF_EN);
+		b53_write8(dev, B53_RATE_CTL_PAGE, B53_RATE_CONTROL(port), rc);
+	} else {
+		b53_read16(dev, B53_CTRL_PAGE, B53_UC_FLOOD_MASK, &uc);
+		if (unicast)
+			uc |= BIT(port);
+		else
+			uc &= ~BIT(port);
+		b53_write16(dev, B53_CTRL_PAGE, B53_UC_FLOOD_MASK, uc);
+	}
 }
 
 static void b53_port_set_mcast_flood(struct b53_device *dev, int port,
@@ -573,19 +597,44 @@ static void b53_port_set_mcast_flood(struct b53_device *dev, int port,
 {
 	u16 mc;
 
-	b53_read16(dev, B53_CTRL_PAGE, B53_MC_FLOOD_MASK, &mc);
-	if (multicast)
-		mc |= BIT(port);
-	else
-		mc &= ~BIT(port);
-	b53_write16(dev, B53_CTRL_PAGE, B53_MC_FLOOD_MASK, mc);
+	if (is5325(dev)) {
+		u8 rc;
 
-	b53_read16(dev, B53_CTRL_PAGE, B53_IPMC_FLOOD_MASK, &mc);
-	if (multicast)
-		mc |= BIT(port);
-	else
-		mc &= ~BIT(port);
-	b53_write16(dev, B53_CTRL_PAGE, B53_IPMC_FLOOD_MASK, mc);
+		if (port == B53_CPU_PORT_25)
+			port = B53_CPU_PORT;
+
+		b53_read16(dev, B53_IEEE_PAGE, B53_IEEE_MCAST_DLF, &mc);
+		if (multicast)
+			mc |= BIT(port) | B53_IEEE_MCAST_DROP_EN;
+		else
+			mc &= ~BIT(port);
+		b53_write16(dev, B53_IEEE_PAGE, B53_IEEE_MCAST_DLF, mc);
+
+		if (port >= B53_CPU_PORT_25)
+			return;
+
+		b53_read8(dev, B53_RATE_CTL_PAGE, B53_RATE_CONTROL(port), &rc);
+		if (multicast)
+			rc |= (RC_BCAST_EN | RC_MCAST_EN | RC_BKT_SIZE_8K |
+			       RC_PERCENT_40);
+		else
+			rc &= ~(RC_BCAST_EN | RC_MCAST_EN);
+		b53_write8(dev, B53_RATE_CTL_PAGE, B53_RATE_CONTROL(port), rc);
+	} else {
+		b53_read16(dev, B53_CTRL_PAGE, B53_MC_FLOOD_MASK, &mc);
+		if (multicast)
+			mc |= BIT(port);
+		else
+			mc &= ~BIT(port);
+		b53_write16(dev, B53_CTRL_PAGE, B53_MC_FLOOD_MASK, mc);
+
+		b53_read16(dev, B53_CTRL_PAGE, B53_IPMC_FLOOD_MASK, &mc);
+		if (multicast)
+			mc |= BIT(port);
+		else
+			mc &= ~BIT(port);
+		b53_write16(dev, B53_CTRL_PAGE, B53_IPMC_FLOOD_MASK, mc);
+	}
 }
 
 static void b53_port_set_learning(struct b53_device *dev, int port,
diff --git a/drivers/net/dsa/b53/b53_regs.h b/drivers/net/dsa/b53/b53_regs.h
index ab15f36a135a..b0a7ba3d9b65 100644
--- a/drivers/net/dsa/b53/b53_regs.h
+++ b/drivers/net/dsa/b53/b53_regs.h
@@ -29,6 +29,7 @@
 #define B53_ARLIO_PAGE			0x05 /* ARL Access */
 #define B53_FRAMEBUF_PAGE		0x06 /* Management frame access */
 #define B53_MEM_ACCESS_PAGE		0x08 /* Memory access */
+#define B53_IEEE_PAGE			0x0a /* IEEE 802.1X */
 
 /* PHY Registers */
 #define B53_PORT_MII_PAGE(i)		(0x10 + (i)) /* Port i MII Registers */
@@ -47,6 +48,9 @@
 /* VLAN Registers */
 #define B53_VLAN_PAGE			0x34
 
+/* Rate Control Registers */
+#define B53_RATE_CTL_PAGE		0x35
+
 /* Jumbo Frame Registers */
 #define B53_JUMBO_PAGE			0x40
 
@@ -368,6 +372,18 @@
 #define B53_ARL_SRCH_RSTL_MACVID(x)	(B53_ARL_SRCH_RSTL_0_MACVID + ((x) * 0x10))
 #define B53_ARL_SRCH_RSTL(x)		(B53_ARL_SRCH_RSTL_0 + ((x) * 0x10))
 
+/*************************************************************************
+ * IEEE 802.1X Registers
+ *************************************************************************/
+
+/* Multicast DLF Drop Control register (16 bit) */
+#define B53_IEEE_MCAST_DLF		0x94
+#define B53_IEEE_MCAST_DROP_EN		BIT(11)
+
+/* Unicast DLF Drop Control register (16 bit) */
+#define B53_IEEE_UCAST_DLF		0x96
+#define B53_IEEE_UCAST_DROP_EN		BIT(11)
+
 /*************************************************************************
  * Port VLAN Registers
  *************************************************************************/
@@ -478,6 +494,28 @@
 /* VLAN Port Default Tag (16 bit) */
 #define B53_VLAN_PORT_DEF_TAG(i)	(0x10 + 2 * (i))
 
+/*************************************************************************
+ * Rate Control Page Registers
+ *************************************************************************/
+
+#define B53_RATE_CONTROL(i)		(0x00 + (i))
+#define   RC_PERCENT_S			0
+#define   RC_PERCENT_10			(0 << RC_PERCENT_S)
+#define   RC_PERCENT_20			(1 << RC_PERCENT_S)
+#define   RC_PERCENT_30			(2 << RC_PERCENT_S)
+#define   RC_PERCENT_40			(3 << RC_PERCENT_S)
+#define   RC_PERCENT_MASK		(3 << RC_PERCENT_S)
+#define   RC_BKT_SIZE_S			2
+#define   RC_BKT_SIZE_2K		(0 << RC_BKT_SIZE_S)
+#define   RC_BKT_SIZE_4K		(1 << RC_BKT_SIZE_S)
+#define   RC_BKT_SIZE_6K		(2 << RC_BKT_SIZE_S)
+#define   RC_BKT_SIZE_8K		(3 << RC_BKT_SIZE_S)
+#define   RC_BKT_SIZE_MASK		(3 << RC_BKT_SIZE_S)
+#define   RC_DLF_EN			BIT(4)
+#define   RC_BCAST_EN			BIT(5)
+#define   RC_MCAST_EN			BIT(6)
+#define   RC_DROP_FRAME			BIT(7)
+
 /*************************************************************************
  * Jumbo Frame Page Registers
  *************************************************************************/
-- 
2.39.5

Re: [RFC PATCH 08/10] net: dsa: b53: fix unicast/multicast flooding on BCM5325
Posted by Florian Fainelli 6 months, 2 weeks ago
On 5/31/25 03:13, Álvaro Fernández Rojas wrote:
> BCM5325 doesn't implement UC_FLOOD_MASK, MC_FLOOD_MASK and IPMC_FLOOD_MASK
> registers.
> This has to be handled differently with other pages and registers.
> 
> Fixes: a8b659e7ff75 ("net: dsa: act as passthrough for bridge port flags")
> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
> ---

[snip]

> +/*************************************************************************
> + * IEEE 802.1X Registers
> + *************************************************************************/
> +
> +/* Multicast DLF Drop Control register (16 bit) */
> +#define B53_IEEE_MCAST_DLF		0x94
> +#define B53_IEEE_MCAST_DROP_EN		BIT(11)
> +
> +/* Unicast DLF Drop Control register (16 bit) */
> +#define B53_IEEE_UCAST_DLF		0x96
> +#define B53_IEEE_UCAST_DROP_EN		BIT(11)

Are you positive the 5325 implements all of those registers? They are 
not documented in my databook.
-- 
Florian
Re: [RFC PATCH 08/10] net: dsa: b53: fix unicast/multicast flooding on BCM5325
Posted by Jonas Gorski 6 months, 2 weeks ago
On Mon, Jun 2, 2025 at 8:09 PM Florian Fainelli
<florian.fainelli@broadcom.com> wrote:
>
> On 5/31/25 03:13, Álvaro Fernández Rojas wrote:
> > BCM5325 doesn't implement UC_FLOOD_MASK, MC_FLOOD_MASK and IPMC_FLOOD_MASK
> > registers.
> > This has to be handled differently with other pages and registers.
> >
> > Fixes: a8b659e7ff75 ("net: dsa: act as passthrough for bridge port flags")
> > Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
> > ---
>
> [snip]
>
> > +/*************************************************************************
> > + * IEEE 802.1X Registers
> > + *************************************************************************/
> > +
> > +/* Multicast DLF Drop Control register (16 bit) */
> > +#define B53_IEEE_MCAST_DLF           0x94
> > +#define B53_IEEE_MCAST_DROP_EN               BIT(11)
> > +
> > +/* Unicast DLF Drop Control register (16 bit) */
> > +#define B53_IEEE_UCAST_DLF           0x96
> > +#define B53_IEEE_UCAST_DROP_EN               BIT(11)
>
> Are you positive the 5325 implements all of those registers? They are
> not documented in my databook.

They are in 5325E-DS14-R pages 112 - 112 (134/135)

That being said, I don't thing we need to touch the MC/BC/DLF rate
control registers when enabling/disabling flooding - these only limit
how much traffic may be UC / MC  on a port, but apart from that they
do not limit flooding. We don't limit this on other switch models
either.

Regards,
Jonas
Re: [RFC PATCH 08/10] net: dsa: b53: fix unicast/multicast flooding on BCM5325
Posted by Álvaro Fernández Rojas 6 months, 2 weeks ago
Hi Jonas,

El lun, 2 jun 2025 a las 22:08, Jonas Gorski
(<jonas.gorski@gmail.com>) escribió:
>
> On Mon, Jun 2, 2025 at 8:09 PM Florian Fainelli
> <florian.fainelli@broadcom.com> wrote:
> >
> > On 5/31/25 03:13, Álvaro Fernández Rojas wrote:
> > > BCM5325 doesn't implement UC_FLOOD_MASK, MC_FLOOD_MASK and IPMC_FLOOD_MASK
> > > registers.
> > > This has to be handled differently with other pages and registers.
> > >
> > > Fixes: a8b659e7ff75 ("net: dsa: act as passthrough for bridge port flags")
> > > Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
> > > ---
> >
> > [snip]
> >
> > > +/*************************************************************************
> > > + * IEEE 802.1X Registers
> > > + *************************************************************************/
> > > +
> > > +/* Multicast DLF Drop Control register (16 bit) */
> > > +#define B53_IEEE_MCAST_DLF           0x94
> > > +#define B53_IEEE_MCAST_DROP_EN               BIT(11)
> > > +
> > > +/* Unicast DLF Drop Control register (16 bit) */
> > > +#define B53_IEEE_UCAST_DLF           0x96
> > > +#define B53_IEEE_UCAST_DROP_EN               BIT(11)
> >
> > Are you positive the 5325 implements all of those registers? They are
> > not documented in my databook.
>
> They are in 5325E-DS14-R pages 112 - 112 (134/135)
>
> That being said, I don't thing we need to touch the MC/BC/DLF rate
> control registers when enabling/disabling flooding - these only limit
> how much traffic may be UC / MC  on a port, but apart from that they
> do not limit flooding. We don't limit this on other switch models
> either.

In that case there's nothing to enable/disable on the BCM5325 and we
should do an early return on b53_port_set_ucast_flood and
b53_port_set_mcast_flood since UC_FLOOD_MASK, MC_FLOOD_MASK and
IPMC_FLOOD_MASK don't exist.

>
> Regards,
> Jonas

Best regards,
Álvaro.
Re: [RFC PATCH 08/10] net: dsa: b53: fix unicast/multicast flooding on BCM5325
Posted by Jonas Gorski 6 months, 2 weeks ago
On Tue, Jun 3, 2025 at 12:18 PM Álvaro Fernández Rojas
<noltari@gmail.com> wrote:
>
> Hi Jonas,
>
> El lun, 2 jun 2025 a las 22:08, Jonas Gorski
> (<jonas.gorski@gmail.com>) escribió:
> >
> > On Mon, Jun 2, 2025 at 8:09 PM Florian Fainelli
> > <florian.fainelli@broadcom.com> wrote:
> > >
> > > On 5/31/25 03:13, Álvaro Fernández Rojas wrote:
> > > > BCM5325 doesn't implement UC_FLOOD_MASK, MC_FLOOD_MASK and IPMC_FLOOD_MASK
> > > > registers.
> > > > This has to be handled differently with other pages and registers.
> > > >
> > > > Fixes: a8b659e7ff75 ("net: dsa: act as passthrough for bridge port flags")
> > > > Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
> > > > ---
> > >
> > > [snip]
> > >
> > > > +/*************************************************************************
> > > > + * IEEE 802.1X Registers
> > > > + *************************************************************************/
> > > > +
> > > > +/* Multicast DLF Drop Control register (16 bit) */
> > > > +#define B53_IEEE_MCAST_DLF           0x94
> > > > +#define B53_IEEE_MCAST_DROP_EN               BIT(11)
> > > > +
> > > > +/* Unicast DLF Drop Control register (16 bit) */
> > > > +#define B53_IEEE_UCAST_DLF           0x96
> > > > +#define B53_IEEE_UCAST_DROP_EN               BIT(11)
> > >
> > > Are you positive the 5325 implements all of those registers? They are
> > > not documented in my databook.
> >
> > They are in 5325E-DS14-R pages 112 - 112 (134/135)
> >
> > That being said, I don't thing we need to touch the MC/BC/DLF rate
> > control registers when enabling/disabling flooding - these only limit
> > how much traffic may be UC / MC  on a port, but apart from that they
> > do not limit flooding. We don't limit this on other switch models
> > either.
>
> In that case there's nothing to enable/disable on the BCM5325 and we
> should do an early return on b53_port_set_ucast_flood and
> b53_port_set_mcast_flood since UC_FLOOD_MASK, MC_FLOOD_MASK and
> IPMC_FLOOD_MASK don't exist.

You are adding calls to modify the B53_IEEE_UCAST_DLF and
B53_IEEE_MCAST_DLF registers, which are fine and look correct. And
AFAICT these are the equivalent to UC_FLOOD_MASK and MC_FLOOD_MASK,
with no IPMC_FLOOD_MASK equivalent.

It's only the rate control ones I'm not sure are the right thing to
do, at least in the same patch.

Regards,
Jonas
Re: [RFC PATCH 08/10] net: dsa: b53: fix unicast/multicast flooding on BCM5325
Posted by Vladimir Oltean 6 months, 2 weeks ago
On Sat, May 31, 2025 at 12:13:06PM +0200, Álvaro Fernández Rojas wrote:
> BCM5325 doesn't implement UC_FLOOD_MASK, MC_FLOOD_MASK and IPMC_FLOOD_MASK
> registers.
> This has to be handled differently with other pages and registers.
> 
> Fixes: a8b659e7ff75 ("net: dsa: act as passthrough for bridge port flags")
> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
> ---
>  drivers/net/dsa/b53/b53_common.c | 85 +++++++++++++++++++++++++-------
>  drivers/net/dsa/b53/b53_regs.h   | 38 ++++++++++++++
>  2 files changed, 105 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
> index 387e1e7ec749..d5216ea2c984 100644
> --- a/drivers/net/dsa/b53/b53_common.c
> +++ b/drivers/net/dsa/b53/b53_common.c
> @@ -560,12 +560,36 @@ static void b53_port_set_ucast_flood(struct b53_device *dev, int port,
>  {
>  	u16 uc;
>  
> -	b53_read16(dev, B53_CTRL_PAGE, B53_UC_FLOOD_MASK, &uc);
> -	if (unicast)
> -		uc |= BIT(port);
> -	else
> -		uc &= ~BIT(port);
> -	b53_write16(dev, B53_CTRL_PAGE, B53_UC_FLOOD_MASK, uc);
> +	if (is5325(dev)) {

Maybe instead of a big "if (is5325(dev)) else", you could have this instead?

	if (is5325(dev))
		return b5325_port_set_ucast_flood();

	... // go on with regular procedure

Here and in other places.