[PATCH net-next v3 8/8] net: dsa: soce: Disable unsupported hardware STP

From: Vasilij Strassheim

Date: Wed Sep 23 2026 - 06:46:42 EST


The driver does not implement hardware STP offloading yet. Switch cores
synthesized with the STP feature enabled may therefore retain their
reset configuration and block frame forwarding.

Detect the synthesized STP feature and disable it during switch setup,
leaving STP state handling to the Linux bridge.

Signed-off-by: Vasilij Strassheim <v.strassheim@xxxxxxxxxxxxx>
---
drivers/net/dsa/soce/soce_dsa.h | 1 +
drivers/net/dsa/soce/soce_dsa_core.c | 20 ++++++++++++++++++++
2 files changed, 21 insertions(+)

diff --git a/drivers/net/dsa/soce/soce_dsa.h b/drivers/net/dsa/soce/soce_dsa.h
index 41533a89d680..bb9e65567ec6 100644
--- a/drivers/net/dsa/soce/soce_dsa.h
+++ b/drivers/net/dsa/soce/soce_dsa.h
@@ -22,6 +22,7 @@ struct soce_dsa_local {
struct soce_features {
u32 num_ports;
bool port_vlan;
+ bool stp;
};

struct soce_priv {
diff --git a/drivers/net/dsa/soce/soce_dsa_core.c b/drivers/net/dsa/soce/soce_dsa_core.c
index f93ce9da8400..3b9fde7a547e 100644
--- a/drivers/net/dsa/soce/soce_dsa_core.c
+++ b/drivers/net/dsa/soce/soce_dsa_core.c
@@ -36,6 +36,7 @@
#define SOCE_IMPL_FEATURES0_OFFSET 0x000c
#define SOCE_IMPL_FEATURES0_NUM_PORTS_MASK GENMASK(31, 27)
#define SOCE_IMPL_FEATURES0_PORT_VLAN BIT(9)
+#define SOCE_IMPL_FEATURES0_STP BIT(20)
#define SOCE_IMPL_FEATURES0_DSA BIT(23)

#define SOCE_DSA_REGS_BASE 0x1200
@@ -51,6 +52,10 @@
#define SOCE_PORTS_CTRL_INGR_EN BIT(0)
#define SOCE_PORTS_CTRL_EGR_EN BIT(1)

+#define SOCE_STP_REGS_BASE 0x0f00
+#define SOCE_STP_CTRL_OFFSET SOCE_STP_REGS_BASE
+#define SOCE_STP_CTRL_ENABLE BIT(0)
+
#define SOCE_VLAN_REGS_BASE 0x0d00
#define SOCE_VLAN_CTRL_OFFSET SOCE_VLAN_REGS_BASE
#define SOCE_VLAN_CTRL_ENABLE BIT(0)
@@ -160,6 +165,7 @@ static int soce_sw_detect_features(struct soce_dsa_local *local,
return -ENODEV;

features->port_vlan = regval & SOCE_IMPL_FEATURES0_PORT_VLAN;
+ features->stp = regval & SOCE_IMPL_FEATURES0_STP;

implemented_numports =
FIELD_GET(SOCE_IMPL_FEATURES0_NUM_PORTS_MASK, regval);
@@ -200,6 +206,16 @@ static void soce_sw_disable_tagging(struct soce_dsa_local *local)
writel(regval, base + SOCE_CUSTOM_RULES_TAGGING_OFFSET);
}

+static void soce_stp_disable(struct soce_dsa_local *local)
+{
+ void __iomem *base = local->base_addr;
+ u32 regval;
+
+ regval = readl(base + SOCE_STP_CTRL_OFFSET);
+ regval &= ~SOCE_STP_CTRL_ENABLE;
+ writel(regval, base + SOCE_STP_CTRL_OFFSET);
+}
+
static void soce_vlan_set_enabled(struct soce_dsa_local *local, bool enabled)
{
void __iomem *base = local->base_addr;
@@ -420,6 +436,10 @@ static int soce_setup(struct dsa_switch *ds)
if (ret)
return ret;

+ /* Unconfigured hardware STP blocks frame forwarding. */
+ if (priv->features.stp)
+ soce_stp_disable(&priv->local);
+
soce_sw_enable_tagging(&priv->local);

return 0;

--
2.39.5