forked from Openwrt/openwrt
f89904ad78
Changelog: https://cdn.kernel.org/pub/linux/kernel/v6.x/ChangeLog-6.1.77 Removed upstreamed: generic/backport-6.1/707-v6.8-01-net-phy-at803x-fix-passing-the-wrong-reference-for-c.patch[1] generic/backport-6.1/796-v6.8-ipmr-fix-kernel-panic-when-forwarding-mcast-packets.patch[2] All other patches automatically rebased. 1. https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v6.1.77&id=7dc0fefd37dd5fb03fdac6e3e01b1c2291148ccb 2. https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v6.1.77&id=d2f1b7fe74afd66298dbb3c7b39e7b62e4df1724 Build system: x86/64 Build-tested: x86/64/AMD Cezanne Run-tested: x86/64/AMD Cezanne Signed-off-by: John Audia <therealgraysky@proton.me>
147 lines
4.8 KiB
Diff
147 lines
4.8 KiB
Diff
From 23cfc7172e5297d0bee49ac6f6f8248d1cf0820d Mon Sep 17 00:00:00 2001
|
|
From: Christian Marangi <ansuelsmth@gmail.com>
|
|
Date: Sun, 30 Jul 2023 09:41:10 +0200
|
|
Subject: [PATCH 1/4] net: dsa: qca8k: make learning configurable and keep off
|
|
if standalone
|
|
|
|
Address learning should initially be turned off by the driver for port
|
|
operation in standalone mode, then the DSA core handles changes to it
|
|
via ds->ops->port_bridge_flags().
|
|
|
|
Currently this is not the case for qca8k where learning is enabled
|
|
unconditionally in qca8k_setup for every user port.
|
|
|
|
Handle ports configured in standalone mode by making the learning
|
|
configurable and not enabling it by default.
|
|
|
|
Implement .port_pre_bridge_flags and .port_bridge_flags dsa ops to
|
|
enable learning for bridge that request it and tweak
|
|
.port_stp_state_set to correctly disable learning when port is
|
|
configured in standalone mode.
|
|
|
|
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
|
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
|
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
|
|
Link: https://lore.kernel.org/r/20230730074113.21889-2-ansuelsmth@gmail.com
|
|
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|
---
|
|
drivers/net/dsa/qca/qca8k-8xxx.c | 7 +++--
|
|
drivers/net/dsa/qca/qca8k-common.c | 48 ++++++++++++++++++++++++++++++
|
|
drivers/net/dsa/qca/qca8k.h | 6 ++++
|
|
3 files changed, 58 insertions(+), 3 deletions(-)
|
|
|
|
--- a/drivers/net/dsa/qca/qca8k-8xxx.c
|
|
+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
|
|
@@ -1905,9 +1905,8 @@ qca8k_setup(struct dsa_switch *ds)
|
|
if (ret)
|
|
return ret;
|
|
|
|
- /* Enable ARP Auto-learning by default */
|
|
- ret = regmap_set_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i),
|
|
- QCA8K_PORT_LOOKUP_LEARN);
|
|
+ ret = regmap_clear_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i),
|
|
+ QCA8K_PORT_LOOKUP_LEARN);
|
|
if (ret)
|
|
return ret;
|
|
|
|
@@ -2013,6 +2012,8 @@ static const struct dsa_switch_ops qca8k
|
|
.port_change_mtu = qca8k_port_change_mtu,
|
|
.port_max_mtu = qca8k_port_max_mtu,
|
|
.port_stp_state_set = qca8k_port_stp_state_set,
|
|
+ .port_pre_bridge_flags = qca8k_port_pre_bridge_flags,
|
|
+ .port_bridge_flags = qca8k_port_bridge_flags,
|
|
.port_bridge_join = qca8k_port_bridge_join,
|
|
.port_bridge_leave = qca8k_port_bridge_leave,
|
|
.port_fast_age = qca8k_port_fast_age,
|
|
--- a/drivers/net/dsa/qca/qca8k-common.c
|
|
+++ b/drivers/net/dsa/qca/qca8k-common.c
|
|
@@ -565,9 +565,26 @@ int qca8k_get_mac_eee(struct dsa_switch
|
|
return 0;
|
|
}
|
|
|
|
+static int qca8k_port_configure_learning(struct dsa_switch *ds, int port,
|
|
+ bool learning)
|
|
+{
|
|
+ struct qca8k_priv *priv = ds->priv;
|
|
+
|
|
+ if (learning)
|
|
+ return regmap_set_bits(priv->regmap,
|
|
+ QCA8K_PORT_LOOKUP_CTRL(port),
|
|
+ QCA8K_PORT_LOOKUP_LEARN);
|
|
+ else
|
|
+ return regmap_clear_bits(priv->regmap,
|
|
+ QCA8K_PORT_LOOKUP_CTRL(port),
|
|
+ QCA8K_PORT_LOOKUP_LEARN);
|
|
+}
|
|
+
|
|
void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
|
|
{
|
|
+ struct dsa_port *dp = dsa_to_port(ds, port);
|
|
struct qca8k_priv *priv = ds->priv;
|
|
+ bool learning = false;
|
|
u32 stp_state;
|
|
|
|
switch (state) {
|
|
@@ -582,8 +599,11 @@ void qca8k_port_stp_state_set(struct dsa
|
|
break;
|
|
case BR_STATE_LEARNING:
|
|
stp_state = QCA8K_PORT_LOOKUP_STATE_LEARNING;
|
|
+ learning = dp->learning;
|
|
break;
|
|
case BR_STATE_FORWARDING:
|
|
+ learning = dp->learning;
|
|
+ fallthrough;
|
|
default:
|
|
stp_state = QCA8K_PORT_LOOKUP_STATE_FORWARD;
|
|
break;
|
|
@@ -591,6 +611,34 @@ void qca8k_port_stp_state_set(struct dsa
|
|
|
|
qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
|
|
QCA8K_PORT_LOOKUP_STATE_MASK, stp_state);
|
|
+
|
|
+ qca8k_port_configure_learning(ds, port, learning);
|
|
+}
|
|
+
|
|
+int qca8k_port_pre_bridge_flags(struct dsa_switch *ds, int port,
|
|
+ struct switchdev_brport_flags flags,
|
|
+ struct netlink_ext_ack *extack)
|
|
+{
|
|
+ if (flags.mask & ~BR_LEARNING)
|
|
+ return -EINVAL;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int qca8k_port_bridge_flags(struct dsa_switch *ds, int port,
|
|
+ struct switchdev_brport_flags flags,
|
|
+ struct netlink_ext_ack *extack)
|
|
+{
|
|
+ int ret;
|
|
+
|
|
+ if (flags.mask & BR_LEARNING) {
|
|
+ ret = qca8k_port_configure_learning(ds, port,
|
|
+ flags.val & BR_LEARNING);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
}
|
|
|
|
int qca8k_port_bridge_join(struct dsa_switch *ds, int port,
|
|
--- a/drivers/net/dsa/qca/qca8k.h
|
|
+++ b/drivers/net/dsa/qca/qca8k.h
|
|
@@ -448,6 +448,12 @@ int qca8k_get_mac_eee(struct dsa_switch
|
|
|
|
/* Common bridge function */
|
|
void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state);
|
|
+int qca8k_port_pre_bridge_flags(struct dsa_switch *ds, int port,
|
|
+ struct switchdev_brport_flags flags,
|
|
+ struct netlink_ext_ack *extack);
|
|
+int qca8k_port_bridge_flags(struct dsa_switch *ds, int port,
|
|
+ struct switchdev_brport_flags flags,
|
|
+ struct netlink_ext_ack *extack);
|
|
int qca8k_port_bridge_join(struct dsa_switch *ds, int port,
|
|
struct dsa_bridge bridge,
|
|
bool *tx_fwd_offload,
|