mirror of
https://github.com/openwrt/openwrt.git
synced 2025-04-21 09:31:57 +00:00
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>
This commit is contained in:
parent
a001630a1a
commit
30d2fcffeb
target/linux/generic/backport-5.15
774-v5.16-01-net-dsa-rtl8366rb-Support-bridge-offloading.patch774-v5.16-02-net-dsa-rtl8366-Drop-custom-VLAN-set-up.patch774-v5.16-03-net-dsa-rtl8366rb-Rewrite-weird-VLAN-filering-enable.patch774-v5.16-06-net-dsa-rtl8366-Drop-and-depromote-pointless-prints.patch774-v5.16-07-net-dsa-rtl8366rb-Use-core-filtering-tracking.patch774-v5.16-08-net-dsa-rtl8366rb-Support-disabling-learning.patch774-v5.16-09-net-dsa-rtl8366rb-Support-fast-aging.patch774-v5.16-10-net-dsa-rtl8366rb-Support-setting-STP-state.patch
141
target/linux/generic/backport-5.15/774-v5.16-01-net-dsa-rtl8366rb-Support-bridge-offloading.patch
Normal file
141
target/linux/generic/backport-5.15/774-v5.16-01-net-dsa-rtl8366rb-Support-bridge-offloading.patch
Normal file
@ -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
target/linux/generic/backport-5.15/774-v5.16-02-net-dsa-rtl8366-Drop-custom-VLAN-set-up.patch
Normal file
118
target/linux/generic/backport-5.15/774-v5.16-02-net-dsa-rtl8366-Drop-custom-VLAN-set-up.patch
Normal file
@ -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;
|
||||
}
|
||||
|
270
target/linux/generic/backport-5.15/774-v5.16-03-net-dsa-rtl8366rb-Rewrite-weird-VLAN-filering-enable.patch
Normal file
270
target/linux/generic/backport-5.15/774-v5.16-03-net-dsa-rtl8366rb-Rewrite-weird-VLAN-filering-enable.patch
Normal file
@ -0,0 +1,270 @@
|
||||
From 7028f54b620f8df344b18e46e4a78e266091ab45 Mon Sep 17 00:00:00 2001
|
||||
From: Linus Walleij <linus.walleij@linaro.org>
|
||||
Date: Sun, 26 Sep 2021 00:59:26 +0200
|
||||
Subject: [PATCH 03/11] net: dsa: rtl8366rb: Rewrite weird VLAN filering
|
||||
enablement
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
While we were defining one VLAN per port for isolating the ports
|
||||
the port_vlan_filtering() callback was implemented to enable a
|
||||
VLAN on the port + 1. This function makes no sense, not only is
|
||||
it incomplete as it only enables the VLAN, it doesn't do what
|
||||
the callback is supposed to do, which is to selectively enable
|
||||
and disable filtering on a certain port.
|
||||
|
||||
Implement the correct callback: we have two registers dealing
|
||||
with filtering on the RTL9366RB, so we implement an ASIC-specific
|
||||
callback and implement filering using the register bit that makes
|
||||
the switch drop frames if the port is not in the VLAN member set.
|
||||
|
||||
The DSA documentation Documentation/networking/switchdev.rst states:
|
||||
|
||||
When the bridge has VLAN filtering enabled and a PVID is not
|
||||
configured on the ingress port, untagged and 802.1p tagged
|
||||
packets must be dropped. When the bridge has VLAN filtering
|
||||
enabled and a PVID exists on the ingress port, untagged and
|
||||
priority-tagged packets must be accepted and forwarded according
|
||||
to the bridge's port membership of the PVID VLAN. When the
|
||||
bridge has VLAN filtering disabled, the presence/lack of a
|
||||
PVID should not influence the packet forwarding decision.
|
||||
|
||||
To comply with this, we add two arrays of bool in the RTL8366RB
|
||||
state that keeps track of if filtering and PVID is enabled or
|
||||
not for each port. We then add code such that whenever filtering
|
||||
or PVID changes, we update the filter according to the
|
||||
specification.
|
||||
|
||||
Cc: Vladimir Oltean <olteanv@gmail.com>
|
||||
Cc: Mauri Sandberg <sandberg@mailfence.com>
|
||||
Cc: Alvin Šipraga <alsi@bang-olufsen.dk>
|
||||
Cc: Florian Fainelli <f.fainelli@gmail.com>
|
||||
Cc: 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/realtek-smi-core.h | 2 -
|
||||
drivers/net/dsa/rtl8366.c | 35 ----------
|
||||
drivers/net/dsa/rtl8366rb.c | 102 +++++++++++++++++++++++++++--
|
||||
3 files changed, 95 insertions(+), 44 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/realtek-smi-core.h
|
||||
+++ b/drivers/net/dsa/realtek-smi-core.h
|
||||
@@ -129,8 +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_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,
|
||||
const struct switchdev_obj_port_vlan *vlan,
|
||||
struct netlink_ext_ack *extack);
|
||||
--- a/drivers/net/dsa/rtl8366.c
|
||||
+++ b/drivers/net/dsa/rtl8366.c
|
||||
@@ -292,41 +292,6 @@ int rtl8366_reset_vlan(struct realtek_sm
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl8366_reset_vlan);
|
||||
|
||||
-int rtl8366_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering,
|
||||
- struct netlink_ext_ack *extack)
|
||||
-{
|
||||
- struct realtek_smi *smi = ds->priv;
|
||||
- struct rtl8366_vlan_4k vlan4k;
|
||||
- int ret;
|
||||
-
|
||||
- /* Use VLAN nr port + 1 since VLAN0 is not valid */
|
||||
- if (!smi->ops->is_vlan_valid(smi, port + 1))
|
||||
- return -EINVAL;
|
||||
-
|
||||
- dev_info(smi->dev, "%s filtering on port %d\n",
|
||||
- vlan_filtering ? "enable" : "disable",
|
||||
- port);
|
||||
-
|
||||
- /* TODO:
|
||||
- * The hardware support filter ID (FID) 0..7, I have no clue how to
|
||||
- * support this in the driver when the callback only says on/off.
|
||||
- */
|
||||
- ret = smi->ops->get_vlan_4k(smi, port + 1, &vlan4k);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- /* Just set the filter to FID 1 for now then */
|
||||
- ret = rtl8366_set_vlan(smi, port + 1,
|
||||
- vlan4k.member,
|
||||
- vlan4k.untag,
|
||||
- 1);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-EXPORT_SYMBOL_GPL(rtl8366_vlan_filtering);
|
||||
-
|
||||
int rtl8366_vlan_add(struct dsa_switch *ds, int port,
|
||||
const struct switchdev_obj_port_vlan *vlan,
|
||||
struct netlink_ext_ack *extack)
|
||||
--- a/drivers/net/dsa/rtl8366rb.c
|
||||
+++ b/drivers/net/dsa/rtl8366rb.c
|
||||
@@ -143,6 +143,21 @@
|
||||
#define RTL8366RB_PHY_NO_OFFSET 9
|
||||
#define RTL8366RB_PHY_NO_MASK (0x1f << 9)
|
||||
|
||||
+/* VLAN Ingress Control Register 1, one bit per port.
|
||||
+ * bit 0 .. 5 will make the switch drop ingress frames without
|
||||
+ * VID such as untagged or priority-tagged frames for respective
|
||||
+ * port.
|
||||
+ * bit 6 .. 11 will make the switch drop ingress frames carrying
|
||||
+ * a C-tag with VID != 0 for respective port.
|
||||
+ */
|
||||
+#define RTL8366RB_VLAN_INGRESS_CTRL1_REG 0x037E
|
||||
+#define RTL8366RB_VLAN_INGRESS_CTRL1_DROP(port) (BIT((port)) | BIT((port) + 6))
|
||||
+
|
||||
+/* VLAN Ingress Control Register 2, one bit per port.
|
||||
+ * bit0 .. bit5 will make the switch drop all ingress frames with
|
||||
+ * a VLAN classification that does not include the port is in its
|
||||
+ * member set.
|
||||
+ */
|
||||
#define RTL8366RB_VLAN_INGRESS_CTRL2_REG 0x037f
|
||||
|
||||
/* LED control registers */
|
||||
@@ -321,9 +336,13 @@
|
||||
/**
|
||||
* struct rtl8366rb - RTL8366RB-specific data
|
||||
* @max_mtu: per-port max MTU setting
|
||||
+ * @pvid_enabled: if PVID is set for respective port
|
||||
+ * @vlan_filtering: if VLAN filtering is enabled for respective port
|
||||
*/
|
||||
struct rtl8366rb {
|
||||
unsigned int max_mtu[RTL8366RB_NUM_PORTS];
|
||||
+ bool pvid_enabled[RTL8366RB_NUM_PORTS];
|
||||
+ bool vlan_filtering[RTL8366RB_NUM_PORTS];
|
||||
};
|
||||
|
||||
static struct rtl8366_mib_counter rtl8366rb_mib_counters[] = {
|
||||
@@ -933,11 +952,13 @@ static int rtl8366rb_setup(struct dsa_sw
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- /* Discard VLAN tagged packets if the port is not a member of
|
||||
- * the VLAN with which the packets is associated.
|
||||
- */
|
||||
+ /* Accept all packets by default, we enable filtering on-demand */
|
||||
+ ret = regmap_write(smi->map, RTL8366RB_VLAN_INGRESS_CTRL1_REG,
|
||||
+ 0);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
ret = regmap_write(smi->map, RTL8366RB_VLAN_INGRESS_CTRL2_REG,
|
||||
- RTL8366RB_PORT_ALL);
|
||||
+ 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -1209,6 +1230,53 @@ rtl8366rb_port_bridge_leave(struct dsa_s
|
||||
RTL8366RB_PORT_ISO_PORTS(port_bitmap), 0);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * rtl8366rb_drop_untagged() - make the switch drop untagged and C-tagged frames
|
||||
+ * @smi: SMI state container
|
||||
+ * @port: the port to drop untagged and C-tagged frames on
|
||||
+ * @drop: whether to drop or pass untagged and C-tagged frames
|
||||
+ */
|
||||
+static int rtl8366rb_drop_untagged(struct realtek_smi *smi, int port, bool drop)
|
||||
+{
|
||||
+ return regmap_update_bits(smi->map, RTL8366RB_VLAN_INGRESS_CTRL1_REG,
|
||||
+ RTL8366RB_VLAN_INGRESS_CTRL1_DROP(port),
|
||||
+ drop ? RTL8366RB_VLAN_INGRESS_CTRL1_DROP(port) : 0);
|
||||
+}
|
||||
+
|
||||
+static int rtl8366rb_vlan_filtering(struct dsa_switch *ds, int port,
|
||||
+ bool vlan_filtering,
|
||||
+ struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ struct realtek_smi *smi = ds->priv;
|
||||
+ struct rtl8366rb *rb;
|
||||
+ int ret;
|
||||
+
|
||||
+ rb = smi->chip_data;
|
||||
+
|
||||
+ dev_dbg(smi->dev, "port %d: %s VLAN filtering\n", port,
|
||||
+ vlan_filtering ? "enable" : "disable");
|
||||
+
|
||||
+ /* If the port is not in the member set, the frame will be dropped */
|
||||
+ ret = regmap_update_bits(smi->map, RTL8366RB_VLAN_INGRESS_CTRL2_REG,
|
||||
+ BIT(port), vlan_filtering ? BIT(port) : 0);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Keep track if filtering is enabled on each port */
|
||||
+ rb->vlan_filtering[port] = vlan_filtering;
|
||||
+
|
||||
+ /* If VLAN filtering is enabled and PVID is also enabled, we must
|
||||
+ * not drop any untagged or C-tagged frames. If we turn off VLAN
|
||||
+ * filtering on a port, we need ti accept any frames.
|
||||
+ */
|
||||
+ if (vlan_filtering)
|
||||
+ ret = rtl8366rb_drop_untagged(smi, port, !rb->pvid_enabled[port]);
|
||||
+ else
|
||||
+ ret = rtl8366rb_drop_untagged(smi, port, false);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int rtl8366rb_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
|
||||
{
|
||||
struct realtek_smi *smi = ds->priv;
|
||||
@@ -1420,14 +1488,34 @@ static int rtl8366rb_get_mc_index(struct
|
||||
|
||||
static int rtl8366rb_set_mc_index(struct realtek_smi *smi, int port, int index)
|
||||
{
|
||||
+ struct rtl8366rb *rb;
|
||||
+ bool pvid_enabled;
|
||||
+ int ret;
|
||||
+
|
||||
+ rb = smi->chip_data;
|
||||
+ pvid_enabled = !!index;
|
||||
+
|
||||
if (port >= smi->num_ports || index >= RTL8366RB_NUM_VLANS)
|
||||
return -EINVAL;
|
||||
|
||||
- return regmap_update_bits(smi->map, RTL8366RB_PORT_VLAN_CTRL_REG(port),
|
||||
+ ret = regmap_update_bits(smi->map, RTL8366RB_PORT_VLAN_CTRL_REG(port),
|
||||
RTL8366RB_PORT_VLAN_CTRL_MASK <<
|
||||
RTL8366RB_PORT_VLAN_CTRL_SHIFT(port),
|
||||
(index & RTL8366RB_PORT_VLAN_CTRL_MASK) <<
|
||||
RTL8366RB_PORT_VLAN_CTRL_SHIFT(port));
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ rb->pvid_enabled[port] = pvid_enabled;
|
||||
+
|
||||
+ /* If VLAN filtering is enabled and PVID is also enabled, we must
|
||||
+ * not drop any untagged or C-tagged frames. Make sure to update the
|
||||
+ * filtering setting.
|
||||
+ */
|
||||
+ if (rb->vlan_filtering[port])
|
||||
+ ret = rtl8366rb_drop_untagged(smi, port, !pvid_enabled);
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static bool rtl8366rb_is_vlan_valid(struct realtek_smi *smi, unsigned int vlan)
|
||||
@@ -1437,7 +1525,7 @@ static bool rtl8366rb_is_vlan_valid(stru
|
||||
if (smi->vlan4k_enabled)
|
||||
max = RTL8366RB_NUM_VIDS - 1;
|
||||
|
||||
- if (vlan == 0 || vlan > max)
|
||||
+ if (vlan > max)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@@ -1594,7 +1682,7 @@ static const struct dsa_switch_ops rtl83
|
||||
.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_filtering = rtl8366rb_vlan_filtering,
|
||||
.port_vlan_add = rtl8366_vlan_add,
|
||||
.port_vlan_del = rtl8366_vlan_del,
|
||||
.port_enable = rtl8366rb_port_enable,
|
51
target/linux/generic/backport-5.15/774-v5.16-06-net-dsa-rtl8366-Drop-and-depromote-pointless-prints.patch
Normal file
51
target/linux/generic/backport-5.15/774-v5.16-06-net-dsa-rtl8366-Drop-and-depromote-pointless-prints.patch
Normal file
@ -0,0 +1,51 @@
|
||||
From ddb59a5dc42714999c335dab4bf256125ba3120c Mon Sep 17 00:00:00 2001
|
||||
From: Linus Walleij <linus.walleij@linaro.org>
|
||||
Date: Sun, 26 Sep 2021 00:59:29 +0200
|
||||
Subject: [PATCH 06/11] net: dsa: rtl8366: Drop and depromote pointless prints
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
We don't need a message for every VLAN association, dbg
|
||||
is fine. The message about adding the DSA or CPU
|
||||
port to a VLAN is directly misleading, this is perfectly
|
||||
fine.
|
||||
|
||||
Cc: Vladimir Oltean <olteanv@gmail.com>
|
||||
Cc: Mauri Sandberg <sandberg@mailfence.com>
|
||||
Cc: DENG Qingfang <dqfext@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/rtl8366.c | 11 ++++-------
|
||||
1 file changed, 4 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/rtl8366.c
|
||||
+++ b/drivers/net/dsa/rtl8366.c
|
||||
@@ -318,12 +318,9 @@ int rtl8366_vlan_add(struct dsa_switch *
|
||||
return ret;
|
||||
}
|
||||
|
||||
- dev_info(smi->dev, "add VLAN %d on port %d, %s, %s\n",
|
||||
- vlan->vid, port, untagged ? "untagged" : "tagged",
|
||||
- pvid ? " PVID" : "no PVID");
|
||||
-
|
||||
- if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port))
|
||||
- dev_err(smi->dev, "port is DSA or CPU port\n");
|
||||
+ dev_dbg(smi->dev, "add VLAN %d on port %d, %s, %s\n",
|
||||
+ vlan->vid, port, untagged ? "untagged" : "tagged",
|
||||
+ pvid ? "PVID" : "no PVID");
|
||||
|
||||
member |= BIT(port);
|
||||
|
||||
@@ -356,7 +353,7 @@ int rtl8366_vlan_del(struct dsa_switch *
|
||||
struct realtek_smi *smi = ds->priv;
|
||||
int ret, i;
|
||||
|
||||
- dev_info(smi->dev, "del VLAN %04x on port %d\n", vlan->vid, port);
|
||||
+ dev_dbg(smi->dev, "del VLAN %d on port %d\n", vlan->vid, port);
|
||||
|
||||
for (i = 0; i < smi->num_vlan_mc; i++) {
|
||||
struct rtl8366_vlan_mc vlanmc;
|
61
target/linux/generic/backport-5.15/774-v5.16-07-net-dsa-rtl8366rb-Use-core-filtering-tracking.patch
Normal file
61
target/linux/generic/backport-5.15/774-v5.16-07-net-dsa-rtl8366rb-Use-core-filtering-tracking.patch
Normal file
@ -0,0 +1,61 @@
|
||||
From 5c9b66f3c8a3f72fa2a58e89a57c6d7afd550bf0 Mon Sep 17 00:00:00 2001
|
||||
From: Linus Walleij <linus.walleij@linaro.org>
|
||||
Date: Wed, 29 Sep 2021 13:23:22 +0200
|
||||
Subject: [PATCH 07/11] net: dsa: rtl8366rb: Use core filtering tracking
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
We added a state variable to track whether a certain port
|
||||
was VLAN filtering or not, but we can just inquire the DSA
|
||||
core about this.
|
||||
|
||||
Cc: Vladimir Oltean <olteanv@gmail.com>
|
||||
Cc: Mauri Sandberg <sandberg@mailfence.com>
|
||||
Cc: DENG Qingfang <dqfext@gmail.com>
|
||||
Cc: Alvin Šipraga <alsi@bang-olufsen.dk>
|
||||
Cc: 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/rtl8366rb.c | 9 ++-------
|
||||
1 file changed, 2 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/rtl8366rb.c
|
||||
+++ b/drivers/net/dsa/rtl8366rb.c
|
||||
@@ -337,12 +337,10 @@
|
||||
* struct rtl8366rb - RTL8366RB-specific data
|
||||
* @max_mtu: per-port max MTU setting
|
||||
* @pvid_enabled: if PVID is set for respective port
|
||||
- * @vlan_filtering: if VLAN filtering is enabled for respective port
|
||||
*/
|
||||
struct rtl8366rb {
|
||||
unsigned int max_mtu[RTL8366RB_NUM_PORTS];
|
||||
bool pvid_enabled[RTL8366RB_NUM_PORTS];
|
||||
- bool vlan_filtering[RTL8366RB_NUM_PORTS];
|
||||
};
|
||||
|
||||
static struct rtl8366_mib_counter rtl8366rb_mib_counters[] = {
|
||||
@@ -1262,12 +1260,9 @@ static int rtl8366rb_vlan_filtering(stru
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- /* Keep track if filtering is enabled on each port */
|
||||
- rb->vlan_filtering[port] = vlan_filtering;
|
||||
-
|
||||
/* If VLAN filtering is enabled and PVID is also enabled, we must
|
||||
* not drop any untagged or C-tagged frames. If we turn off VLAN
|
||||
- * filtering on a port, we need ti accept any frames.
|
||||
+ * filtering on a port, we need to accept any frames.
|
||||
*/
|
||||
if (vlan_filtering)
|
||||
ret = rtl8366rb_drop_untagged(smi, port, !rb->pvid_enabled[port]);
|
||||
@@ -1512,7 +1507,7 @@ static int rtl8366rb_set_mc_index(struct
|
||||
* not drop any untagged or C-tagged frames. Make sure to update the
|
||||
* filtering setting.
|
||||
*/
|
||||
- if (rb->vlan_filtering[port])
|
||||
+ if (dsa_port_is_vlan_filtering(dsa_to_port(smi->ds, port)))
|
||||
ret = rtl8366rb_drop_untagged(smi, port, !pvid_enabled);
|
||||
|
||||
return ret;
|
115
target/linux/generic/backport-5.15/774-v5.16-08-net-dsa-rtl8366rb-Support-disabling-learning.patch
Normal file
115
target/linux/generic/backport-5.15/774-v5.16-08-net-dsa-rtl8366rb-Support-disabling-learning.patch
Normal file
@ -0,0 +1,115 @@
|
||||
From 831a3d26bea0d14f8563eecf96def660a74a3000 Mon Sep 17 00:00:00 2001
|
||||
From: Linus Walleij <linus.walleij@linaro.org>
|
||||
Date: Tue, 5 Oct 2021 21:47:02 +0200
|
||||
Subject: [PATCH 08/11] net: dsa: rtl8366rb: Support disabling learning
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The RTL8366RB hardware supports disabling learning per-port
|
||||
so let's make use of this feature. Rename some unfortunately
|
||||
named registers in the process.
|
||||
|
||||
Suggested-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Cc: Alvin Šipraga <alsi@bang-olufsen.dk>
|
||||
Cc: Mauri Sandberg <sandberg@mailfence.com>
|
||||
Cc: Florian Fainelli <f.fainelli@gmail.com>
|
||||
Cc: DENG Qingfang <dqfext@gmail.com>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@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 | 50 ++++++++++++++++++++++++++++++++-----
|
||||
1 file changed, 44 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/rtl8366rb.c
|
||||
+++ b/drivers/net/dsa/rtl8366rb.c
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/etherdevice.h>
|
||||
+#include <linux/if_bridge.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/irqchip/chained_irq.h>
|
||||
@@ -42,9 +43,12 @@
|
||||
/* Port Enable Control register */
|
||||
#define RTL8366RB_PECR 0x0001
|
||||
|
||||
-/* Switch Security Control registers */
|
||||
-#define RTL8366RB_SSCR0 0x0002
|
||||
-#define RTL8366RB_SSCR1 0x0003
|
||||
+/* Switch per-port learning disablement register */
|
||||
+#define RTL8366RB_PORT_LEARNDIS_CTRL 0x0002
|
||||
+
|
||||
+/* Security control, actually aging register */
|
||||
+#define RTL8366RB_SECURITY_CTRL 0x0003
|
||||
+
|
||||
#define RTL8366RB_SSCR2 0x0004
|
||||
#define RTL8366RB_SSCR2_DROP_UNKNOWN_DA BIT(0)
|
||||
|
||||
@@ -927,13 +931,14 @@ static int rtl8366rb_setup(struct dsa_sw
|
||||
/* layer 2 size, see rtl8366rb_change_mtu() */
|
||||
rb->max_mtu[i] = 1532;
|
||||
|
||||
- /* Enable learning for all ports */
|
||||
- ret = regmap_write(smi->map, RTL8366RB_SSCR0, 0);
|
||||
+ /* Disable learning for all ports */
|
||||
+ ret = regmap_write(smi->map, RTL8366RB_PORT_LEARNDIS_CTRL,
|
||||
+ RTL8366RB_PORT_ALL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Enable auto ageing for all ports */
|
||||
- ret = regmap_write(smi->map, RTL8366RB_SSCR1, 0);
|
||||
+ ret = regmap_write(smi->map, RTL8366RB_SECURITY_CTRL, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -1272,6 +1277,37 @@ static int rtl8366rb_vlan_filtering(stru
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int
|
||||
+rtl8366rb_port_pre_bridge_flags(struct dsa_switch *ds, int port,
|
||||
+ struct switchdev_brport_flags flags,
|
||||
+ struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ /* We support enabling/disabling learning */
|
||||
+ if (flags.mask & ~(BR_LEARNING))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+rtl8366rb_port_bridge_flags(struct dsa_switch *ds, int port,
|
||||
+ struct switchdev_brport_flags flags,
|
||||
+ struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ struct realtek_smi *smi = ds->priv;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (flags.mask & BR_LEARNING) {
|
||||
+ ret = regmap_update_bits(smi->map, RTL8366RB_PORT_LEARNDIS_CTRL,
|
||||
+ BIT(port),
|
||||
+ (flags.val & BR_LEARNING) ? 0 : BIT(port));
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int rtl8366rb_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
|
||||
{
|
||||
struct realtek_smi *smi = ds->priv;
|
||||
@@ -1682,6 +1718,8 @@ static const struct dsa_switch_ops rtl83
|
||||
.port_vlan_del = rtl8366_vlan_del,
|
||||
.port_enable = rtl8366rb_port_enable,
|
||||
.port_disable = rtl8366rb_port_disable,
|
||||
+ .port_pre_bridge_flags = rtl8366rb_port_pre_bridge_flags,
|
||||
+ .port_bridge_flags = rtl8366rb_port_bridge_flags,
|
||||
.port_change_mtu = rtl8366rb_change_mtu,
|
||||
.port_max_mtu = rtl8366rb_max_mtu,
|
||||
};
|
57
target/linux/generic/backport-5.15/774-v5.16-09-net-dsa-rtl8366rb-Support-fast-aging.patch
Normal file
57
target/linux/generic/backport-5.15/774-v5.16-09-net-dsa-rtl8366rb-Support-fast-aging.patch
Normal file
@ -0,0 +1,57 @@
|
||||
From 8eb13420eb9ab4a4e2ebd612bf5dc9dba0039236 Mon Sep 17 00:00:00 2001
|
||||
From: Linus Walleij <linus.walleij@linaro.org>
|
||||
Date: Tue, 5 Oct 2021 21:47:03 +0200
|
||||
Subject: [PATCH 09/11] net: dsa: rtl8366rb: Support fast aging
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This implements fast aging per-port using the special "security"
|
||||
register, which will flush any learned L2 LUT entries on a port.
|
||||
|
||||
The vendor API just enabled setting and clearing this bit, so
|
||||
we set it to age out any entries on the port and then we clear
|
||||
it again.
|
||||
|
||||
Suggested-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Cc: Mauri Sandberg <sandberg@mailfence.com>
|
||||
Cc: DENG Qingfang <dqfext@gmail.com>
|
||||
Cc: Florian Fainelli <f.fainelli@gmail.com>
|
||||
Reviewed-by: Alvin Šipraga <alsi@bang-olufsen.dk>
|
||||
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/rtl8366rb.c | 14 ++++++++++++++
|
||||
1 file changed, 14 insertions(+)
|
||||
|
||||
--- a/drivers/net/dsa/rtl8366rb.c
|
||||
+++ b/drivers/net/dsa/rtl8366rb.c
|
||||
@@ -1308,6 +1308,19 @@ rtl8366rb_port_bridge_flags(struct dsa_s
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void
|
||||
+rtl8366rb_port_fast_age(struct dsa_switch *ds, int port)
|
||||
+{
|
||||
+ struct realtek_smi *smi = ds->priv;
|
||||
+
|
||||
+ /* This will age out any learned L2 entries */
|
||||
+ regmap_update_bits(smi->map, RTL8366RB_SECURITY_CTRL,
|
||||
+ BIT(port), BIT(port));
|
||||
+ /* Restore the normal state of things */
|
||||
+ regmap_update_bits(smi->map, RTL8366RB_SECURITY_CTRL,
|
||||
+ BIT(port), 0);
|
||||
+}
|
||||
+
|
||||
static int rtl8366rb_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
|
||||
{
|
||||
struct realtek_smi *smi = ds->priv;
|
||||
@@ -1720,6 +1733,7 @@ static const struct dsa_switch_ops rtl83
|
||||
.port_disable = rtl8366rb_port_disable,
|
||||
.port_pre_bridge_flags = rtl8366rb_port_pre_bridge_flags,
|
||||
.port_bridge_flags = rtl8366rb_port_bridge_flags,
|
||||
+ .port_fast_age = rtl8366rb_port_fast_age,
|
||||
.port_change_mtu = rtl8366rb_change_mtu,
|
||||
.port_max_mtu = rtl8366rb_max_mtu,
|
||||
};
|
107
target/linux/generic/backport-5.15/774-v5.16-10-net-dsa-rtl8366rb-Support-setting-STP-state.patch
Normal file
107
target/linux/generic/backport-5.15/774-v5.16-10-net-dsa-rtl8366rb-Support-setting-STP-state.patch
Normal file
@ -0,0 +1,107 @@
|
||||
From 90c855471a89d3e05ecf5b6464bd04abf2c83b70 Mon Sep 17 00:00:00 2001
|
||||
From: Linus Walleij <linus.walleij@linaro.org>
|
||||
Date: Tue, 5 Oct 2021 21:47:04 +0200
|
||||
Subject: [PATCH 10/11] net: dsa: rtl8366rb: Support setting STP state
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This adds support for setting the STP state to the RTL8366RB
|
||||
DSA switch. This rids the following message from the kernel on
|
||||
e.g. OpenWrt:
|
||||
|
||||
DSA: failed to set STP state 3 (-95)
|
||||
|
||||
Since the RTL8366RB has one STP state register per FID with
|
||||
two bit per port in each, we simply loop over all the FIDs
|
||||
and set the state on all of them.
|
||||
|
||||
Cc: Vladimir Oltean <olteanv@gmail.com>
|
||||
Cc: Alvin Šipraga <alsi@bang-olufsen.dk>
|
||||
Cc: Mauri Sandberg <sandberg@mailfence.com>
|
||||
Cc: DENG Qingfang <dqfext@gmail.com>
|
||||
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/rtl8366rb.c | 48 +++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 48 insertions(+)
|
||||
|
||||
--- a/drivers/net/dsa/rtl8366rb.c
|
||||
+++ b/drivers/net/dsa/rtl8366rb.c
|
||||
@@ -110,6 +110,18 @@
|
||||
|
||||
#define RTL8366RB_POWER_SAVING_REG 0x0021
|
||||
|
||||
+/* Spanning tree status (STP) control, two bits per port per FID */
|
||||
+#define RTL8366RB_STP_STATE_BASE 0x0050 /* 0x0050..0x0057 */
|
||||
+#define RTL8366RB_STP_STATE_DISABLED 0x0
|
||||
+#define RTL8366RB_STP_STATE_BLOCKING 0x1
|
||||
+#define RTL8366RB_STP_STATE_LEARNING 0x2
|
||||
+#define RTL8366RB_STP_STATE_FORWARDING 0x3
|
||||
+#define RTL8366RB_STP_MASK GENMASK(1, 0)
|
||||
+#define RTL8366RB_STP_STATE(port, state) \
|
||||
+ ((state) << ((port) * 2))
|
||||
+#define RTL8366RB_STP_STATE_MASK(port) \
|
||||
+ RTL8366RB_STP_STATE((port), RTL8366RB_STP_MASK)
|
||||
+
|
||||
/* CPU port control reg */
|
||||
#define RTL8368RB_CPU_CTRL_REG 0x0061
|
||||
#define RTL8368RB_CPU_PORTS_MSK 0x00FF
|
||||
@@ -234,6 +246,7 @@
|
||||
#define RTL8366RB_NUM_LEDGROUPS 4
|
||||
#define RTL8366RB_NUM_VIDS 4096
|
||||
#define RTL8366RB_PRIORITYMAX 7
|
||||
+#define RTL8366RB_NUM_FIDS 8
|
||||
#define RTL8366RB_FIDMAX 7
|
||||
|
||||
#define RTL8366RB_PORT_1 BIT(0) /* In userspace port 0 */
|
||||
@@ -1309,6 +1322,40 @@ rtl8366rb_port_bridge_flags(struct dsa_s
|
||||
}
|
||||
|
||||
static void
|
||||
+rtl8366rb_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
|
||||
+{
|
||||
+ struct realtek_smi *smi = ds->priv;
|
||||
+ u32 val;
|
||||
+ int i;
|
||||
+
|
||||
+ switch (state) {
|
||||
+ case BR_STATE_DISABLED:
|
||||
+ val = RTL8366RB_STP_STATE_DISABLED;
|
||||
+ break;
|
||||
+ case BR_STATE_BLOCKING:
|
||||
+ case BR_STATE_LISTENING:
|
||||
+ val = RTL8366RB_STP_STATE_BLOCKING;
|
||||
+ break;
|
||||
+ case BR_STATE_LEARNING:
|
||||
+ val = RTL8366RB_STP_STATE_LEARNING;
|
||||
+ break;
|
||||
+ case BR_STATE_FORWARDING:
|
||||
+ val = RTL8366RB_STP_STATE_FORWARDING;
|
||||
+ break;
|
||||
+ default:
|
||||
+ dev_err(smi->dev, "unknown bridge state requested\n");
|
||||
+ return;
|
||||
+ };
|
||||
+
|
||||
+ /* Set the same status for the port on all the FIDs */
|
||||
+ for (i = 0; i < RTL8366RB_NUM_FIDS; i++) {
|
||||
+ regmap_update_bits(smi->map, RTL8366RB_STP_STATE_BASE + i,
|
||||
+ RTL8366RB_STP_STATE_MASK(port),
|
||||
+ RTL8366RB_STP_STATE(port, val));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
rtl8366rb_port_fast_age(struct dsa_switch *ds, int port)
|
||||
{
|
||||
struct realtek_smi *smi = ds->priv;
|
||||
@@ -1733,6 +1780,7 @@ static const struct dsa_switch_ops rtl83
|
||||
.port_disable = rtl8366rb_port_disable,
|
||||
.port_pre_bridge_flags = rtl8366rb_port_pre_bridge_flags,
|
||||
.port_bridge_flags = rtl8366rb_port_bridge_flags,
|
||||
+ .port_stp_state_set = rtl8366rb_port_stp_state_set,
|
||||
.port_fast_age = rtl8366rb_port_fast_age,
|
||||
.port_change_mtu = rtl8366rb_change_mtu,
|
||||
.port_max_mtu = rtl8366rb_max_mtu,
|
Loading…
x
Reference in New Issue
Block a user