diff mbox series

[2/2] realtek: use assisted learning on CPU port

Message ID 20221021215427.3719844-3-jan@3e8.eu
State Superseded
Delegated to: Sander Vanheule
Headers show
Series realtek: fix L2 entry setup and learning on CPU port | expand

Commit Message

Jan Hoffmann Oct. 21, 2022, 9:54 p.m. UTC
L2 learning on the CPU port is currently not consistently configured and
relies on the default configuration of the device. On RTL83xx, it is
disabled for packets transmitted with a TX header, as hardware learning
corrupts the forwarding table otherwise. As a result, unneeded flooding
of traffic for the CPU port can already happen on some devices now. It
is also likely that similar issues exist on RTL93xx, which doesn't have
a field to disable learning in the TX header.

To address this, disable hardware learning for the CPU port globally on
all devices. Instead, enable assisted learning to let DSA write FDB
entries to the switch.

For now, this does not sync local/bridge entries to the switch. However,
support for that was added in Linux 5.14, so the next switch to a newer
kernel version is going to fix this.

Signed-off-by: Jan Hoffmann <jan@3e8.eu>
---
 .../files-5.10/drivers/net/dsa/rtl83xx/dsa.c     | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

Comments

Sander Vanheule Oct. 23, 2022, 6:24 p.m. UTC | #1
Hi Jan,

On Fri, 2022-10-21 at 23:54 +0200, Jan Hoffmann wrote:
> L2 learning on the CPU port is currently not consistently configured and
> relies on the default configuration of the device. On RTL83xx, it is
> disabled for packets transmitted with a TX header, as hardware learning
> corrupts the forwarding table otherwise. As a result, unneeded flooding
> of traffic for the CPU port can already happen on some devices now. It
> is also likely that similar issues exist on RTL93xx, which doesn't have
> a field to disable learning in the TX header.
> 
> To address this, disable hardware learning for the CPU port globally on
> all devices. Instead, enable assisted learning to let DSA write FDB
> entries to the switch.
> 
> For now, this does not sync local/bridge entries to the switch. However,
> support for that was added in Linux 5.14, so the next switch to a newer
> kernel version is going to fix this.
> 
> Signed-off-by: Jan Hoffmann <jan@3e8.eu>
> ---
>  .../files-5.10/drivers/net/dsa/rtl83xx/dsa.c     | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 
> diff --git a/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/dsa.c
> b/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/dsa.c
> index 45b489afa124..f45002f33bfb 100644
> --- a/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/dsa.c
> +++ b/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/dsa.c
> @@ -162,6 +162,16 @@ static void rtl83xx_setup_bpdu_traps(struct
> rtl838x_switch_priv *priv)
>                 priv->r->set_receive_management_action(i, BPDU, COPY2CPU);
>  }
>  
> +static void rtl83xx_port_set_salrn(struct rtl838x_switch_priv *priv,
> +                                  int port, bool enable)
> +{
> +       int offset = (port & 0xf) << 1;

I find this masking and shifting unintuitive, because the intention here is not
to stuff the value in a bitfield (which is how I would read this). Instead, this
calculates the offset in an array of 2-bit fields, so just do that explicitly
and let the compiler translate this into more efficient masking and shifting:

	int offset = (port % 16) * 2;

> +       int val = enable ? 0 : 2;

Please add some form of description for these values:

	#define SALRN_MODE_HARDWARE	0
	#define SALRN_MODE_DISABLED	2

Or with an RTL83XX_ prefix.

> +
> +       sw_w32_mask(0x3 << offset, val << offset,
> +                   priv->r->l2_port_new_salrn(port));
> +}
> +
> 

Best,
Sander
diff mbox series

Patch

diff --git a/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/dsa.c b/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/dsa.c
index 45b489afa124..f45002f33bfb 100644
--- a/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/dsa.c
+++ b/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/dsa.c
@@ -162,6 +162,16 @@  static void rtl83xx_setup_bpdu_traps(struct rtl838x_switch_priv *priv)
 		priv->r->set_receive_management_action(i, BPDU, COPY2CPU);
 }
 
+static void rtl83xx_port_set_salrn(struct rtl838x_switch_priv *priv,
+				   int port, bool enable)
+{
+	int offset = (port & 0xf) << 1;
+	int val = enable ? 0 : 2;
+
+	sw_w32_mask(0x3 << offset, val << offset,
+		    priv->r->l2_port_new_salrn(port));
+}
+
 static int rtl83xx_setup(struct dsa_switch *ds)
 {
 	int i;
@@ -205,6 +215,9 @@  static int rtl83xx_setup(struct dsa_switch *ds)
 
 	priv->r->l2_learning_setup();
 
+	rtl83xx_port_set_salrn(priv, priv->cpu_port, false);
+	ds->assisted_learning_on_cpu_port = true;
+
 	/*
 	 *  Make sure all frames sent to the switch's MAC are trapped to the CPU-port
 	 *  0: FWD, 1: DROP, 2: TRAP2CPU
@@ -263,6 +276,9 @@  static int rtl93xx_setup(struct dsa_switch *ds)
 
 	priv->r->l2_learning_setup();
 
+	rtl83xx_port_set_salrn(priv, priv->cpu_port, false);
+	ds->assisted_learning_on_cpu_port = true;
+
 	rtl83xx_enable_phy_polling(priv);
 
 	priv->r->pie_init(priv);