forked from openwrt/openwrt
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
generic: backport 5.16 RTL8366RB improvements
The prerequisite DSA changes for the nice RTL8366RB improvements are already backported so bring back these changes as well. Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
- Loading branch information
Showing
8 changed files
with
920 additions
and
0 deletions.
There are no files selected for viewing
141 changes: 141 additions & 0 deletions
141
...inux/generic/backport-5.15/774-v5.16-01-net-dsa-rtl8366rb-Support-bridge-offloading.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
From c9111895fd38dadf125e07be627778a9950d8d77 Mon Sep 17 00:00:00 2001 | ||
From: DENG Qingfang <dqfext@gmail.com> | ||
Date: Sun, 26 Sep 2021 00:59:24 +0200 | ||
Subject: [PATCH 01/11] net: dsa: rtl8366rb: Support bridge offloading | ||
MIME-Version: 1.0 | ||
Content-Type: text/plain; charset=UTF-8 | ||
Content-Transfer-Encoding: 8bit | ||
|
||
Use port isolation registers to configure bridge offloading. | ||
|
||
Tested on the D-Link DIR-685, switching between ports and | ||
sniffing ports to make sure no packets leak. | ||
|
||
Cc: Vladimir Oltean <olteanv@gmail.com> | ||
Cc: Mauri Sandberg <sandberg@mailfence.com> | ||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com> | ||
Reviewed-by: Alvin Šipraga <alsi@bang-olufsen.dk> | ||
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> | ||
Signed-off-by: DENG Qingfang <dqfext@gmail.com> | ||
Signed-off-by: Linus Walleij <linus.walleij@linaro.org> | ||
Signed-off-by: David S. Miller <davem@davemloft.net> | ||
--- | ||
drivers/net/dsa/rtl8366rb.c | 86 +++++++++++++++++++++++++++++++++++++ | ||
1 file changed, 86 insertions(+) | ||
|
||
--- a/drivers/net/dsa/rtl8366rb.c | ||
+++ b/drivers/net/dsa/rtl8366rb.c | ||
@@ -300,6 +300,13 @@ | ||
#define RTL8366RB_INTERRUPT_STATUS_REG 0x0442 | ||
#define RTL8366RB_NUM_INTERRUPT 14 /* 0..13 */ | ||
|
||
+/* Port isolation registers */ | ||
+#define RTL8366RB_PORT_ISO_BASE 0x0F08 | ||
+#define RTL8366RB_PORT_ISO(pnum) (RTL8366RB_PORT_ISO_BASE + (pnum)) | ||
+#define RTL8366RB_PORT_ISO_EN BIT(0) | ||
+#define RTL8366RB_PORT_ISO_PORTS_MASK GENMASK(7, 1) | ||
+#define RTL8366RB_PORT_ISO_PORTS(pmask) ((pmask) << 1) | ||
+ | ||
/* bits 0..5 enable force when cleared */ | ||
#define RTL8366RB_MAC_FORCE_CTRL_REG 0x0F11 | ||
|
||
@@ -835,6 +842,21 @@ static int rtl8366rb_setup(struct dsa_sw | ||
if (ret) | ||
return ret; | ||
|
||
+ /* Isolate all user ports so they can only send packets to itself and the CPU port */ | ||
+ for (i = 0; i < RTL8366RB_PORT_NUM_CPU; i++) { | ||
+ ret = regmap_write(smi->map, RTL8366RB_PORT_ISO(i), | ||
+ RTL8366RB_PORT_ISO_PORTS(BIT(RTL8366RB_PORT_NUM_CPU)) | | ||
+ RTL8366RB_PORT_ISO_EN); | ||
+ if (ret) | ||
+ return ret; | ||
+ } | ||
+ /* CPU port can send packets to all ports */ | ||
+ ret = regmap_write(smi->map, RTL8366RB_PORT_ISO(RTL8366RB_PORT_NUM_CPU), | ||
+ RTL8366RB_PORT_ISO_PORTS(dsa_user_ports(ds)) | | ||
+ RTL8366RB_PORT_ISO_EN); | ||
+ if (ret) | ||
+ return ret; | ||
+ | ||
/* Set up the "green ethernet" feature */ | ||
ret = rtl8366rb_jam_table(rtl8366rb_green_jam, | ||
ARRAY_SIZE(rtl8366rb_green_jam), smi, false); | ||
@@ -1127,6 +1149,68 @@ rtl8366rb_port_disable(struct dsa_switch | ||
rb8366rb_set_port_led(smi, port, false); | ||
} | ||
|
||
+static int | ||
+rtl8366rb_port_bridge_join(struct dsa_switch *ds, int port, | ||
+ struct net_device *bridge) | ||
+{ | ||
+ struct realtek_smi *smi = ds->priv; | ||
+ unsigned int port_bitmap = 0; | ||
+ int ret, i; | ||
+ | ||
+ /* Loop over all other ports than the current one */ | ||
+ for (i = 0; i < RTL8366RB_PORT_NUM_CPU; i++) { | ||
+ /* Current port handled last */ | ||
+ if (i == port) | ||
+ continue; | ||
+ /* Not on this bridge */ | ||
+ if (dsa_to_port(ds, i)->bridge_dev != bridge) | ||
+ continue; | ||
+ /* Join this port to each other port on the bridge */ | ||
+ ret = regmap_update_bits(smi->map, RTL8366RB_PORT_ISO(i), | ||
+ RTL8366RB_PORT_ISO_PORTS(BIT(port)), | ||
+ RTL8366RB_PORT_ISO_PORTS(BIT(port))); | ||
+ if (ret) | ||
+ dev_err(smi->dev, "failed to join port %d\n", port); | ||
+ | ||
+ port_bitmap |= BIT(i); | ||
+ } | ||
+ | ||
+ /* Set the bits for the ports we can access */ | ||
+ return regmap_update_bits(smi->map, RTL8366RB_PORT_ISO(port), | ||
+ RTL8366RB_PORT_ISO_PORTS(port_bitmap), | ||
+ RTL8366RB_PORT_ISO_PORTS(port_bitmap)); | ||
+} | ||
+ | ||
+static void | ||
+rtl8366rb_port_bridge_leave(struct dsa_switch *ds, int port, | ||
+ struct net_device *bridge) | ||
+{ | ||
+ struct realtek_smi *smi = ds->priv; | ||
+ unsigned int port_bitmap = 0; | ||
+ int ret, i; | ||
+ | ||
+ /* Loop over all other ports than this one */ | ||
+ for (i = 0; i < RTL8366RB_PORT_NUM_CPU; i++) { | ||
+ /* Current port handled last */ | ||
+ if (i == port) | ||
+ continue; | ||
+ /* Not on this bridge */ | ||
+ if (dsa_to_port(ds, i)->bridge_dev != bridge) | ||
+ continue; | ||
+ /* Remove this port from any other port on the bridge */ | ||
+ ret = regmap_update_bits(smi->map, RTL8366RB_PORT_ISO(i), | ||
+ RTL8366RB_PORT_ISO_PORTS(BIT(port)), 0); | ||
+ if (ret) | ||
+ dev_err(smi->dev, "failed to leave port %d\n", port); | ||
+ | ||
+ port_bitmap |= BIT(i); | ||
+ } | ||
+ | ||
+ /* Clear the bits for the ports we can not access, leave ourselves */ | ||
+ regmap_update_bits(smi->map, RTL8366RB_PORT_ISO(port), | ||
+ RTL8366RB_PORT_ISO_PORTS(port_bitmap), 0); | ||
+} | ||
+ | ||
static int rtl8366rb_change_mtu(struct dsa_switch *ds, int port, int new_mtu) | ||
{ | ||
struct realtek_smi *smi = ds->priv; | ||
@@ -1510,6 +1594,8 @@ static const struct dsa_switch_ops rtl83 | ||
.get_strings = rtl8366_get_strings, | ||
.get_ethtool_stats = rtl8366_get_ethtool_stats, | ||
.get_sset_count = rtl8366_get_sset_count, | ||
+ .port_bridge_join = rtl8366rb_port_bridge_join, | ||
+ .port_bridge_leave = rtl8366rb_port_bridge_leave, | ||
.port_vlan_filtering = rtl8366_vlan_filtering, | ||
.port_vlan_add = rtl8366_vlan_add, | ||
.port_vlan_del = rtl8366_vlan_del, |
118 changes: 118 additions & 0 deletions
118
...et/linux/generic/backport-5.15/774-v5.16-02-net-dsa-rtl8366-Drop-custom-VLAN-set-up.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
From 96cf10a8e7297065459473c081a6fb6432a22312 Mon Sep 17 00:00:00 2001 | ||
From: Linus Walleij <linus.walleij@linaro.org> | ||
Date: Sun, 26 Sep 2021 00:59:25 +0200 | ||
Subject: [PATCH 02/11] net: dsa: rtl8366: Drop custom VLAN set-up | ||
MIME-Version: 1.0 | ||
Content-Type: text/plain; charset=UTF-8 | ||
Content-Transfer-Encoding: 8bit | ||
|
||
This hacky default VLAN setup was done in order to direct | ||
packets to the right ports and provide port isolation, both | ||
which we now support properly using custom tags and proper | ||
bridge port isolation. | ||
|
||
We can drop the custom VLAN code and leave all VLAN handling | ||
alone, as users expect things to be. We can also drop | ||
ds->configure_vlan_while_not_filtering = false; and let | ||
the core deal with any VLANs it wants. | ||
|
||
Cc: Mauri Sandberg <sandberg@mailfence.com> | ||
Cc: DENG Qingfang <dqfext@gmail.com> | ||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com> | ||
Reviewed-by: Alvin Šipraga <alsi@bang-olufsen.dk> | ||
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> | ||
Signed-off-by: Linus Walleij <linus.walleij@linaro.org> | ||
Signed-off-by: David S. Miller <davem@davemloft.net> | ||
--- | ||
drivers/net/dsa/realtek-smi-core.h | 1 - | ||
drivers/net/dsa/rtl8366.c | 48 ------------------------------ | ||
drivers/net/dsa/rtl8366rb.c | 4 +-- | ||
3 files changed, 1 insertion(+), 52 deletions(-) | ||
|
||
--- a/drivers/net/dsa/realtek-smi-core.h | ||
+++ b/drivers/net/dsa/realtek-smi-core.h | ||
@@ -129,7 +129,6 @@ int rtl8366_set_pvid(struct realtek_smi | ||
int rtl8366_enable_vlan4k(struct realtek_smi *smi, bool enable); | ||
int rtl8366_enable_vlan(struct realtek_smi *smi, bool enable); | ||
int rtl8366_reset_vlan(struct realtek_smi *smi); | ||
-int rtl8366_init_vlan(struct realtek_smi *smi); | ||
int rtl8366_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, | ||
struct netlink_ext_ack *extack); | ||
int rtl8366_vlan_add(struct dsa_switch *ds, int port, | ||
--- a/drivers/net/dsa/rtl8366.c | ||
+++ b/drivers/net/dsa/rtl8366.c | ||
@@ -292,54 +292,6 @@ int rtl8366_reset_vlan(struct realtek_sm | ||
} | ||
EXPORT_SYMBOL_GPL(rtl8366_reset_vlan); | ||
|
||
-int rtl8366_init_vlan(struct realtek_smi *smi) | ||
-{ | ||
- int port; | ||
- int ret; | ||
- | ||
- ret = rtl8366_reset_vlan(smi); | ||
- if (ret) | ||
- return ret; | ||
- | ||
- /* Loop over the available ports, for each port, associate | ||
- * it with the VLAN (port+1) | ||
- */ | ||
- for (port = 0; port < smi->num_ports; port++) { | ||
- u32 mask; | ||
- | ||
- if (port == smi->cpu_port) | ||
- /* For the CPU port, make all ports members of this | ||
- * VLAN. | ||
- */ | ||
- mask = GENMASK((int)smi->num_ports - 1, 0); | ||
- else | ||
- /* For all other ports, enable itself plus the | ||
- * CPU port. | ||
- */ | ||
- mask = BIT(port) | BIT(smi->cpu_port); | ||
- | ||
- /* For each port, set the port as member of VLAN (port+1) | ||
- * and untagged, except for the CPU port: the CPU port (5) is | ||
- * member of VLAN 6 and so are ALL the other ports as well. | ||
- * Use filter 0 (no filter). | ||
- */ | ||
- dev_info(smi->dev, "VLAN%d port mask for port %d, %08x\n", | ||
- (port + 1), port, mask); | ||
- ret = rtl8366_set_vlan(smi, (port + 1), mask, mask, 0); | ||
- if (ret) | ||
- return ret; | ||
- | ||
- dev_info(smi->dev, "VLAN%d port %d, PVID set to %d\n", | ||
- (port + 1), port, (port + 1)); | ||
- ret = rtl8366_set_pvid(smi, port, (port + 1)); | ||
- if (ret) | ||
- return ret; | ||
- } | ||
- | ||
- return rtl8366_enable_vlan(smi, true); | ||
-} | ||
-EXPORT_SYMBOL_GPL(rtl8366_init_vlan); | ||
- | ||
int rtl8366_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, | ||
struct netlink_ext_ack *extack) | ||
{ | ||
--- a/drivers/net/dsa/rtl8366rb.c | ||
+++ b/drivers/net/dsa/rtl8366rb.c | ||
@@ -985,7 +985,7 @@ static int rtl8366rb_setup(struct dsa_sw | ||
return ret; | ||
} | ||
|
||
- ret = rtl8366_init_vlan(smi); | ||
+ ret = rtl8366_reset_vlan(smi); | ||
if (ret) | ||
return ret; | ||
|
||
@@ -999,8 +999,6 @@ static int rtl8366rb_setup(struct dsa_sw | ||
return -ENODEV; | ||
} | ||
|
||
- ds->configure_vlan_while_not_filtering = false; | ||
- | ||
return 0; | ||
} | ||
|
Oops, something went wrong.