The Linux Kernel Mailing List
 help / color / mirror / Atom feed
* [PATCH 0/4] net: dsa: Add SoC-e DSA driver
@ 2026-07-29 16:36 Vasilij Strassheim
  2026-07-29 16:36 ` [PATCH 1/4] dt-bindings: vendor-prefixes: Add soce Vasilij Strassheim
                   ` (4 more replies)
  0 siblings, 5 replies; 44+ messages in thread
From: Vasilij Strassheim @ 2026-07-29 16:36 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Andrew Lunn,
	Vladimir Oltean, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Russell King
  Cc: devicetree, linux-kernel, netdev, Martin Kaistra,
	Vasilij Strassheim

Add initial support for the DSA driver for SoC-e FPGA-based (IP core)
Ethernet switches.

This first functional driver baseline is kept focused on Managed
Redundant Switch (MRS) which is also runtime-tested (25.01 IP using
24.01 layout) on ZynqMP hardware. It includes basic support for
networking (STP, FDB and Phylink), but not the IEEE 802.1Q VLAN tagging.
This will likely be added in the future.

This work is based on non-publicly available SoC-e DSA driver code, with
permission from the company to contribute it under different authorship.
There are different variants of the SoC-e switch IP, which can be
additionally configured at runtime with proprietary userspace software.
All variants share the same DSA features with a few differences in
register layout. Additional SoC-e switch variants might be introduced
later in separate patch series. 

Signed-off-by: Vasilij Strassheim <v.strassheim@linutronix.de>
---
Vasilij Strassheim (4):
      dt-bindings: vendor-prefixes: Add soce
      dt-bindings: net: dsa: Add SoC-e switch IP and DSA bindings
      net: dsa: Add support for SoC-e SDSA tags
      net: dsa: soce: Add initial driver support for MRS switches

 .../bindings/net/dsa/soce,switch-dsa.yaml          | 195 +++++++++++
 .../bindings/net/dsa/soce,switch-ip.yaml           |  54 +++
 .../devicetree/bindings/vendor-prefixes.yaml       |   2 +
 drivers/net/dsa/Kconfig                            |   2 +
 drivers/net/dsa/Makefile                           |   1 +
 drivers/net/dsa/soce/Kconfig                       |  12 +
 drivers/net/dsa/soce/Makefile                      |   6 +
 drivers/net/dsa/soce/soce_common.c                 | 159 +++++++++
 drivers/net/dsa/soce/soce_common.h                 |  36 ++
 drivers/net/dsa/soce/soce_dsa.h                    |  41 +++
 drivers/net/dsa/soce/soce_dsa_core.c               | 354 +++++++++++++++++++
 drivers/net/dsa/soce/soce_mdio.c                   | 381 +++++++++++++++++++++
 drivers/net/dsa/soce/soce_mdio.h                   |  40 +++
 drivers/net/dsa/soce/soce_mrs.h                    |  21 ++
 include/net/dsa.h                                  |   2 +
 net/dsa/Kconfig                                    |   6 +
 net/dsa/Makefile                                   |   1 +
 net/dsa/tag_sdsa.c                                 | 102 ++++++
 18 files changed, 1415 insertions(+)
---
base-commit: 9fb3b84c9577707db14e633ea3c57048380bf822
change-id: 20260729-devel-vstrassheim-soce-dsa-ml-20d6a5adb838

Best regards,
--  
Vasilij Strassheim <v.strassheim@linutronix.de>


^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH 1/4] dt-bindings: vendor-prefixes: Add soce
  2026-07-29 16:36 [PATCH 0/4] net: dsa: Add SoC-e DSA driver Vasilij Strassheim
@ 2026-07-29 16:36 ` Vasilij Strassheim
  2026-07-30  8:50   ` Krzysztof Kozlowski
  2026-07-29 16:36 ` [PATCH 2/4] dt-bindings: net: dsa: Add SoC-e switch IP and DSA bindings Vasilij Strassheim
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 44+ messages in thread
From: Vasilij Strassheim @ 2026-07-29 16:36 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Andrew Lunn,
	Vladimir Oltean, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Russell King
  Cc: devicetree, linux-kernel, netdev, Martin Kaistra,
	Vasilij Strassheim

Add the soce vendor prefix for System-On-Chip Engineering, S.L.

This prefix is used by the new SoC-e Ethernet switch DT bindings.

Signed-off-by: Vasilij Strassheim <v.strassheim@linutronix.de>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 396044f368e7..cf7eefff4230 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1553,6 +1553,8 @@ patternProperties:
     description: Standard Microsystems Corporation
   "^snps,.*":
     description: Synopsys, Inc.
+  "^soce,.*":
+    description: System-On-Chip Engineering, S.L.
   "^sochip,.*":
     description: Shenzhen SoChip Technology Co., Ltd.
   "^socionext,.*":

-- 
2.39.5


^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH 2/4] dt-bindings: net: dsa: Add SoC-e switch IP and DSA bindings
  2026-07-29 16:36 [PATCH 0/4] net: dsa: Add SoC-e DSA driver Vasilij Strassheim
  2026-07-29 16:36 ` [PATCH 1/4] dt-bindings: vendor-prefixes: Add soce Vasilij Strassheim
@ 2026-07-29 16:36 ` Vasilij Strassheim
  2026-07-29 17:11   ` Andrew Lunn
                     ` (3 more replies)
  2026-07-29 16:36 ` [PATCH 3/4] net: dsa: Add support for SoC-e SDSA tags Vasilij Strassheim
                   ` (2 subsequent siblings)
  4 siblings, 4 replies; 44+ messages in thread
From: Vasilij Strassheim @ 2026-07-29 16:36 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Andrew Lunn,
	Vladimir Oltean, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Russell King
  Cc: devicetree, linux-kernel, netdev, Martin Kaistra,
	Vasilij Strassheim

Add DT schema documentation for SoC-e FPGA switch devices.
The binding is split into:
 - a switch IP node describing the MMIO register block
 - a DSA MDIO node describing the DSA-facing switch instance
Both nodes are linked through the soce,switch-ip phandle.

Signed-off-by: Vasilij Strassheim <v.strassheim@linutronix.de>
---
 .../bindings/net/dsa/soce,switch-dsa.yaml          | 195 +++++++++++++++++++++
 .../bindings/net/dsa/soce,switch-ip.yaml           |  54 ++++++
 2 files changed, 249 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/dsa/soce,switch-dsa.yaml b/Documentation/devicetree/bindings/net/dsa/soce,switch-dsa.yaml
new file mode 100644
index 000000000000..a04e2838d14e
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/dsa/soce,switch-dsa.yaml
@@ -0,0 +1,195 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/dsa/soce,switch-dsa.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SoC-e DSA switch MDIO device
+
+maintainers:
+  - SoC-e <info@soc-e.com>
+
+description: |
+  This node is the MDIO-bus device entry for the SoC-e DSA switch driver.
+  It is a lightweight configuration node that lives on the MDIO bus of the
+  SoC Ethernet controller acting as the DSA conduit (CPU port).
+
+  The switch hardware itself (MMIO register interface) is a separate IP core
+  described by a companion node with one of the SoC-e compatible strings,
+  for example:
+    - soce,mrs-<version>
+  See the consolidated IP-core binding:
+    - Documentation/devicetree/bindings/net/dsa/soce,switch-ip.yaml
+  The two nodes are linked via the "soce,switch-ip" phandle property.
+
+  Port sub-nodes follow the DSA port binding documented in dsa-port.yaml.
+  User ports should reference PHY nodes through "phy-handle". These PHY nodes
+  live under the optional "mdio" child node of the switch and are exposed on
+  the switch's synthetic DSA user MDIO bus.
+
+  The PHY-specific properties "soce,mdio-output" and "soce,phy-addr" describe
+  the MDIO bus index and hardware PHY address used by the on-chip MDIO master
+  of the switch IP core.
+
+properties:
+  '#address-cells':
+    const: 1
+
+  '#size-cells':
+    const: 0
+
+  compatible:
+    const: soce,switch-dsa
+
+  reg:
+    description: MDIO address of this device on the parent MDIO bus.
+    maxItems: 1
+
+  soce,switch-ip:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: |
+      Phandle to the SoC-e switch IP core node that provides the MMIO register
+      window for this switch instance. The referenced node must carry a
+      compatible string documented in
+      Documentation/devicetree/bindings/net/dsa/soce,switch-ip.yaml.
+
+  dsa,member:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    minItems: 2
+    maxItems: 2
+    description:
+      DSA cluster membership; see Documentation/devicetree/bindings/net/dsa/dsa.yaml.
+
+  mdio:
+    $ref: /schemas/net/mdio.yaml#
+    description: |
+      Optional child MDIO bus exposing PHY devices attached to switch user
+      ports. PHY nodes referenced by port "phy-handle" properties should be
+      placed here. The PHY address seen by Linux on this bus is the switch port
+      index, not necessarily the hardware PHY address selected internally by
+      the switch IP.
+    unevaluatedProperties: false
+
+    patternProperties:
+      "^ethernet-phy@[0-9a-f]+$":
+        type: object
+        $ref: /schemas/net/ethernet-phy.yaml#
+        unevaluatedProperties: false
+        description:
+          PHY attached to a switch user port through the synthetic switch MDIO
+          bus.
+        properties:
+          soce,mdio-output:
+            $ref: /schemas/types.yaml#/definitions/uint32
+            description: |
+              Zero-based index of the MDIO bus output of the switch IP core to
+              which this PHY is connected.
+
+          soce,phy-addr:
+            $ref: /schemas/types.yaml#/definitions/uint32
+            description: |
+              Hardware PHY address on the MDIO bus selected by
+              "soce,mdio-output".
+
+        required:
+          - soce,mdio-output
+          - soce,phy-addr
+
+  ports:
+    type: object
+    description: Container node for the switch port sub-nodes.
+    properties:
+      '#address-cells':
+        const: 1
+      '#size-cells':
+        const: 0
+
+    patternProperties:
+      "^port@[0-9a-f]+$":
+        $ref: dsa-port.yaml#
+        unevaluatedProperties: false
+        description: |
+          Switch port. In addition to the standard DSA port properties
+          (label, phy-mode, ethernet, fixed-link) the following
+          vendor-specific properties are used for data ports connected to
+          external PHYs.
+
+    required:
+      - '#address-cells'
+      - '#size-cells'
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - soce,switch-ip
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+    /* Excerpt from a Xilinx ZynqMP design (ARM64) */
+    mdio {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        soce_switch: switch@10 {
+            #address-cells = <1>;
+            #size-cells = <0>;
+            compatible = "soce,switch-dsa";
+            reg = <0x10>;
+            soce,switch-ip = <&soce_switch_ip>;
+            dsa,member = <0 0>;
+
+            ports {
+                #address-cells = <1>;
+                #size-cells = <0>;
+
+                port@0 {
+                    reg = <0x0>;
+                    label = "PORT_0";
+                    phy-handle = <&switchphy0>;
+                    phy-mode = "rgmii-id";
+                };
+
+                port@1 {
+                    reg = <0x1>;
+                    label = "PORT_1";
+                    phy-handle = <&switchphy1>;
+                    phy-mode = "rgmii-id";
+                };
+
+                port@2 {
+                    reg = <0x2>;
+                    label = "INTERNAL_PORT";
+                    ethernet = <&gem3>;
+                    phy-mode = "gmii";
+                    fixed-link {
+                        speed = <1000>;
+                        full-duplex;
+                    };
+                };
+            };
+
+            mdio {
+              #address-cells = <1>;
+              #size-cells = <0>;
+
+                switchphy0: ethernet-phy@0 {
+                    compatible = "ethernet-phy-ieee802.3-c22";
+                    reg = <0x0>;
+                    soce,mdio-output = <0x00000000>;
+                    soce,phy-addr = <1>;
+                };
+
+                switchphy1: ethernet-phy@1 {
+                    compatible = "ethernet-phy-ieee802.3-c22";
+                    reg = <0x1>;
+                    soce,mdio-output = <0x00000001>;
+                    soce,phy-addr = <1>;
+                };
+            };
+        };
+    };
diff --git a/Documentation/devicetree/bindings/net/dsa/soce,switch-ip.yaml b/Documentation/devicetree/bindings/net/dsa/soce,switch-ip.yaml
new file mode 100644
index 000000000000..ba9bb396235f
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/dsa/soce,switch-ip.yaml
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/dsa/soce,switch-ip.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SoC-e Ethernet Switch IP core
+
+maintainers:
+  - SoC-e <info@soc-e.com>
+
+description: |
+  SoC-e Ethernet switch IP cores are configurable FPGA switch fabrics with
+  Layer-2 bridging features (including STP/MSTP state control and FDB
+  fast-age support). Some variants also provide TSN functionality.
+
+  This binding describes only the MMIO switch IP core node. The Linux DSA
+  driver is bound via a companion MDIO node described in:
+    Documentation/devicetree/bindings/net/dsa/soce,switch-dsa.yaml.
+
+properties:
+  compatible:
+    enum:
+      - soce,mrs-21-01
+      - soce,mrs-23-02
+      - soce,mrs-24-01
+
+  reg:
+    description: |
+      MMIO base address and size of the switch register window.
+      On 64-bit platforms (ARM64), this is typically encoded as two-cell
+      address and two-cell size values.
+    maxItems: 1
+
+  soce,num-ports:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: |
+      Total number of switch ports (external/user ports plus the CPU uplink
+      port). Must be greater than zero and not exceed the selected IP variant.
+
+required:
+  - compatible
+  - reg
+  - soce,num-ports
+
+additionalProperties: false
+
+examples:
+  - |
+    switch_ip: switch@80020000 {
+        compatible = "soce,mrs-24-01";
+        reg = <0x0 0x80020000 0x0 0x10000>;
+        soce,num-ports = <3>;
+    };

-- 
2.39.5


^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH 3/4] net: dsa: Add support for SoC-e SDSA tags
  2026-07-29 16:36 [PATCH 0/4] net: dsa: Add SoC-e DSA driver Vasilij Strassheim
  2026-07-29 16:36 ` [PATCH 1/4] dt-bindings: vendor-prefixes: Add soce Vasilij Strassheim
  2026-07-29 16:36 ` [PATCH 2/4] dt-bindings: net: dsa: Add SoC-e switch IP and DSA bindings Vasilij Strassheim
@ 2026-07-29 16:36 ` Vasilij Strassheim
  2026-07-29 17:22   ` Andrew Lunn
  2026-07-29 16:36 ` [PATCH 4/4] net: dsa: soce: Add initial driver support for MRS switches Vasilij Strassheim
  2026-07-29 16:56 ` [PATCH 0/4] net: dsa: Add SoC-e DSA driver Andrew Lunn
  4 siblings, 1 reply; 44+ messages in thread
From: Vasilij Strassheim @ 2026-07-29 16:36 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Andrew Lunn,
	Vladimir Oltean, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Russell King
  Cc: devicetree, linux-kernel, netdev, Martin Kaistra,
	Vasilij Strassheim

Add a DSA tagger for the SoC-e SDSA header format used between
the conduit and SoC-e switch ports.

The implementation adds TX tag insertion and RX tag parsing and
registers a new DSA tag protocol.

Signed-off-by: Vasilij Strassheim <v.strassheim@linutronix.de>
---
 include/net/dsa.h  |   2 ++
 net/dsa/Kconfig    |   6 ++++
 net/dsa/Makefile   |   1 +
 net/dsa/tag_sdsa.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 111 insertions(+)

diff --git a/include/net/dsa.h b/include/net/dsa.h
index 8c16ef23cc10..744bbb4d54ea 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -59,6 +59,7 @@ struct tc_action;
 #define DSA_TAG_PROTO_MXL_GSW1XX_VALUE		31
 #define DSA_TAG_PROTO_MXL862_VALUE		32
 #define DSA_TAG_PROTO_NETC_VALUE		33
+#define DSA_TAG_PROTO_SDSA_VALUE		34
 
 enum dsa_tag_protocol {
 	DSA_TAG_PROTO_NONE		= DSA_TAG_PROTO_NONE_VALUE,
@@ -95,6 +96,7 @@ enum dsa_tag_protocol {
 	DSA_TAG_PROTO_MXL_GSW1XX	= DSA_TAG_PROTO_MXL_GSW1XX_VALUE,
 	DSA_TAG_PROTO_MXL862		= DSA_TAG_PROTO_MXL862_VALUE,
 	DSA_TAG_PROTO_NETC		= DSA_TAG_PROTO_NETC_VALUE,
+	DSA_TAG_PROTO_SDSA		= DSA_TAG_PROTO_SDSA_VALUE,
 };
 
 struct dsa_switch;
diff --git a/net/dsa/Kconfig b/net/dsa/Kconfig
index d5e725b90d78..1e1b0f2fb726 100644
--- a/net/dsa/Kconfig
+++ b/net/dsa/Kconfig
@@ -98,6 +98,12 @@ config NET_DSA_TAG_EDSA
 	  Say Y or M if you want to enable support for tagging frames for the
 	  Marvell switches which use EtherType DSA headers.
 
+config NET_DSA_TAG_SDSA
+	tristate "Tag driver for SoC-e switches using EtherType SDSA headers"
+	help
+	  Say Y or M if you want to enable support for tagging frames for the
+	  SoC-e switches.
+
 config NET_DSA_TAG_MTK
 	tristate "Tag driver for Mediatek switches"
 	help
diff --git a/net/dsa/Makefile b/net/dsa/Makefile
index b8c2667cd14a..dc154f10e0a0 100644
--- a/net/dsa/Makefile
+++ b/net/dsa/Makefile
@@ -23,6 +23,7 @@ dsa_core-y += \
 obj-$(CONFIG_NET_DSA_TAG_AR9331) += tag_ar9331.o
 obj-$(CONFIG_NET_DSA_TAG_BRCM_COMMON) += tag_brcm.o
 obj-$(CONFIG_NET_DSA_TAG_DSA_COMMON) += tag_dsa.o
+obj-$(CONFIG_NET_DSA_TAG_SDSA) += tag_sdsa.o
 obj-$(CONFIG_NET_DSA_TAG_GSWIP) += tag_gswip.o
 obj-$(CONFIG_NET_DSA_TAG_HELLCREEK) += tag_hellcreek.o
 obj-$(CONFIG_NET_DSA_TAG_KSZ) += tag_ksz.o
diff --git a/net/dsa/tag_sdsa.c b/net/dsa/tag_sdsa.c
new file mode 100644
index 000000000000..b32dca1e367c
--- /dev/null
+++ b/net/dsa/tag_sdsa.c
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2020 System on Chip engineering, S.L.
+ * Copyright (c) 2026 Linutronix GmbH
+ */
+
+#include <linux/bitops.h>
+#include <linux/etherdevice.h>
+
+#include "tag.h"
+
+#define SDSA_HLEN	8
+
+#define SDSA_NAME	"sdsa"
+#define ETH_P_SDSA	0xDCDC
+
+/* SDSA tag byte layout (after the 12-byte MAC header):
+ * Bytes 0-1: SDSA EtherType (0xDCDC)
+ * Bytes 2-3: Reserved
+ * Byte 4:    Frame type (bits 7-6), VLAN-info bit (bit 5), port[9:5] (bits 4-0)
+ * Byte 5:    Port[4:0] (bits 7-3)
+ * Bytes 6-7: PCP (bits 7-5) / CFI (bit 4) / VID (bits 3-0 + byte 7), only
+ *            meaningful when the VLAN-info bit is set.
+ */
+#define SDSA_TAG_FRAME_TYPE_MASK	GENMASK(7, 6)
+#define SDSA_TAG_VLAN_BIT		BIT(5)
+#define SDSA_TAG_PORT_HI_MASK		GENMASK(4, 0)
+#define SDSA_TAG_PORT_MASK		GENMASK(7, 3)
+
+static struct sk_buff *sdsa_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct dsa_port *dp = dsa_user_to_port(dev);
+	u8 *sdsa_header;
+
+	if (skb_cow_head(skb, SDSA_HLEN) < 0)
+		return NULL;
+
+	skb_push(skb, SDSA_HLEN);
+	dsa_alloc_etype_header(skb, SDSA_HLEN);
+
+	/* Construct the FROM_CPU DSA tag. */
+	sdsa_header = dsa_etype_header_pos_tx(skb);
+	sdsa_header[0] = (ETH_P_SDSA >> 8) & 0xff;
+	sdsa_header[1] = ETH_P_SDSA & 0xff;
+	sdsa_header[2] = 0x00; /* reserved */
+	sdsa_header[3] = 0x00; /* reserved */
+	sdsa_header[4] = FIELD_PREP(SDSA_TAG_FRAME_TYPE_MASK, 1) |
+			 FIELD_PREP(SDSA_TAG_PORT_HI_MASK, dp->index >> 5);
+	sdsa_header[5] = FIELD_PREP(SDSA_TAG_PORT_MASK, dp->index);
+	sdsa_header[6] = 0x00; /* VLAN not supported */
+	sdsa_header[7] = 0x00; /* VLAN not supported */
+
+	return skb;
+}
+
+static struct sk_buff *sdsa_rcv(struct sk_buff *skb, struct net_device *dev)
+{
+	u8 *sdsa_header;
+	int source_port;
+	u8 frame_type;
+
+	if (unlikely(!pskb_may_pull(skb, SDSA_HLEN)))
+		return NULL;
+
+	sdsa_header = dsa_etype_header_pos_rx(skb);
+
+	/* Check that the frame type is TO_CPU. */
+	frame_type = FIELD_GET(SDSA_TAG_FRAME_TYPE_MASK, sdsa_header[4]);
+	if (frame_type != 0)
+		return NULL;
+
+	/* VLAN-tagged traffic is intentionally unsupported yet. */
+	if (sdsa_header[4] & SDSA_TAG_VLAN_BIT)
+		return NULL;
+
+	/* Determine the source port from the two port fields. */
+	source_port = ((sdsa_header[4] & 0x1f) << 5) |
+		      ((sdsa_header[5] & 0xf8) >> 3);
+
+	skb->dev = dsa_conduit_find_user(dev, 0, source_port);
+	if (!skb->dev)
+		return NULL;
+
+	skb_pull_rcsum(skb, SDSA_HLEN);
+	dsa_strip_etype_header(skb, SDSA_HLEN);
+
+	dsa_default_offload_fwd_mark(skb);
+	return skb;
+}
+
+static const struct dsa_device_ops sdsa_netdev_ops = {
+	.name = SDSA_NAME,
+	.proto = DSA_TAG_PROTO_SDSA,
+	.xmit = sdsa_xmit,
+	.rcv = sdsa_rcv,
+	.needed_headroom = SDSA_HLEN,
+};
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("DSA tag driver for SoC-e SDSA protocol");
+MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_SDSA, SDSA_NAME);
+
+module_dsa_tag_driver(sdsa_netdev_ops);

-- 
2.39.5


^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH 4/4] net: dsa: soce: Add initial driver support for MRS switches
  2026-07-29 16:36 [PATCH 0/4] net: dsa: Add SoC-e DSA driver Vasilij Strassheim
                   ` (2 preceding siblings ...)
  2026-07-29 16:36 ` [PATCH 3/4] net: dsa: Add support for SoC-e SDSA tags Vasilij Strassheim
@ 2026-07-29 16:36 ` Vasilij Strassheim
  2026-07-29 17:31   ` Andrew Lunn
                     ` (2 more replies)
  2026-07-29 16:56 ` [PATCH 0/4] net: dsa: Add SoC-e DSA driver Andrew Lunn
  4 siblings, 3 replies; 44+ messages in thread
From: Vasilij Strassheim @ 2026-07-29 16:36 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Andrew Lunn,
	Vladimir Oltean, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Russell King
  Cc: devicetree, linux-kernel, netdev, Martin Kaistra,
	Vasilij Strassheim

Add initial support for SoC-e switches that are based on FPGA IP cores.
This driver provides MDIO access helpers for supported IP register
layouts and common STP/FDB handling.

Managed Redundant Switch (MRS) variant is introduced first with variant
descriptors and register layout mapping. The implementation has been
designed so that additional variants can be added in the future with
minimal effort.

Tested on SoC-e MRS 25.01 hardware using the 24.01 register layout.

Signed-off-by: Vasilij Strassheim <v.strassheim@linutronix.de>
---
 drivers/net/dsa/Kconfig              |   2 +
 drivers/net/dsa/Makefile             |   1 +
 drivers/net/dsa/soce/Kconfig         |  12 ++
 drivers/net/dsa/soce/Makefile        |   6 +
 drivers/net/dsa/soce/soce_common.c   | 159 +++++++++++++++
 drivers/net/dsa/soce/soce_common.h   |  36 ++++
 drivers/net/dsa/soce/soce_dsa.h      |  41 ++++
 drivers/net/dsa/soce/soce_dsa_core.c | 354 ++++++++++++++++++++++++++++++++
 drivers/net/dsa/soce/soce_mdio.c     | 381 +++++++++++++++++++++++++++++++++++
 drivers/net/dsa/soce/soce_mdio.h     |  40 ++++
 drivers/net/dsa/soce/soce_mrs.h      |  21 ++
 11 files changed, 1053 insertions(+)

diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig
index 4ab567c5bbaf..6bf5fd48599b 100644
--- a/drivers/net/dsa/Kconfig
+++ b/drivers/net/dsa/Kconfig
@@ -82,6 +82,8 @@ source "drivers/net/dsa/ocelot/Kconfig"
 
 source "drivers/net/dsa/qca/Kconfig"
 
+source "drivers/net/dsa/soce/Kconfig"
+
 source "drivers/net/dsa/sja1105/Kconfig"
 
 source "drivers/net/dsa/xrs700x/Kconfig"
diff --git a/drivers/net/dsa/Makefile b/drivers/net/dsa/Makefile
index d2975badffc0..624b453f576a 100644
--- a/drivers/net/dsa/Makefile
+++ b/drivers/net/dsa/Makefile
@@ -26,4 +26,5 @@ obj-y				+= ocelot/
 obj-y				+= qca/
 obj-y				+= realtek/
 obj-y				+= sja1105/
+obj-y				+= soce/
 obj-y				+= xrs700x/
diff --git a/drivers/net/dsa/soce/Kconfig b/drivers/net/dsa/soce/Kconfig
new file mode 100644
index 000000000000..97d4e4e838d9
--- /dev/null
+++ b/drivers/net/dsa/soce/Kconfig
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0
+config NET_DSA_SOCE
+	tristate "Soce switches"
+	depends on NET_DSA
+	depends on OF
+	depends on HAS_IOMEM
+	select NET_DSA_TAG_SDSA
+	help
+	  This enables support for switches based on IP core from SoC-E.
+	  Frames are exchanged with the CPU port using the SDSA DSA tag protocol.
+	  The driver supports different variants and versions of switches which
+	  are configurable at runtime.
diff --git a/drivers/net/dsa/soce/Makefile b/drivers/net/dsa/soce/Makefile
new file mode 100644
index 000000000000..a6e74b7d57df
--- /dev/null
+++ b/drivers/net/dsa/soce/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_NET_DSA_SOCE) += soce_dsa.o
+soce_dsa-objs := soce_dsa_core.o
+soce_dsa-objs += soce_mdio.o
+soce_dsa-objs += soce_common.o
diff --git a/drivers/net/dsa/soce/soce_common.c b/drivers/net/dsa/soce/soce_common.c
new file mode 100644
index 000000000000..f7f345a690e4
--- /dev/null
+++ b/drivers/net/dsa/soce/soce_common.c
@@ -0,0 +1,159 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2020 System on Chip engineering, S.L.
+ * Copyright (c) 2026 Linutronix GmbH
+ */
+#include <linux/if_bridge.h>
+#include <linux/bits.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+
+#include "soce_dsa.h"
+#include "soce_mdio.h"
+#include "soce_common.h"
+
+#define SOCE_FAST_AGE_POLL_US		10
+#define SOCE_FAST_AGE_TIMEOUT_US	100000
+
+#define SOCE_STP_PORTS_PER_STATUS_REG	16
+#define SOCE_STP_PORT_STATE_WIDTH	2
+#define SOCE_STP_PORT_STATE_WRITE	BIT(0)
+#define SOCE_STP_MSTID_CIST		0
+
+#define SOCE_STP_PORT_STATE_MASK GENMASK(SOCE_STP_PORT_STATE_WIDTH - 1, 0)
+
+#define SOCE_FDB_CLEAR_UNDER_PROCESS	BIT(7)
+#define SOCE_FDB_CLEAR_FLUSH_MSTID	BIT(4)
+
+static u8 soce_map_stp_state(u8 state)
+{
+	switch (state) {
+	case BR_STATE_DISABLED:
+	case BR_STATE_BLOCKING:
+	case BR_STATE_LISTENING:
+		return 0;
+	case BR_STATE_LEARNING:
+		return 1;
+	case BR_STATE_FORWARDING:
+	default:
+		return 3;
+	}
+}
+
+static void soce_stp_state_set(struct dsa_switch *ds, int port, u8 state,
+			       const struct soce_layout *layout)
+{
+	void __iomem *p_mstp_mstid, *p_mstp_ps_hi, *p_mstp_ps_lo, *p_mstp_pc;
+	struct soce_priv *priv = ds->priv;
+	struct soce_dsa_local *local;
+	u32 ps_hi_n, ps_lo_n;
+	u8 stp_state;
+
+	local = &priv->local;
+	if (!layout || !local->base_addr)
+		return;
+
+	stp_state = soce_map_stp_state(state);
+	p_mstp_pc = local->base_addr + layout->mstp_port_state_control;
+	p_mstp_mstid = local->base_addr + layout->mstp_mstid;
+	p_mstp_ps_lo = local->base_addr + layout->mstp_port_state_lo;
+	p_mstp_ps_hi = local->base_addr + layout->mstp_port_state_hi;
+
+	/* Keep the extra MSTP MSTID write taken from the vendor sequence. */
+	writel(SOCE_STP_MSTID_CIST, p_mstp_mstid);
+
+	ps_lo_n = readl(p_mstp_ps_lo);
+	ps_hi_n = readl(p_mstp_ps_hi);
+
+	if (port >= SOCE_STP_PORTS_PER_STATUS_REG) {
+		port -= SOCE_STP_PORTS_PER_STATUS_REG;
+		ps_hi_n =
+			((ps_hi_n & ~(SOCE_STP_PORT_STATE_MASK
+				      << (port * SOCE_STP_PORT_STATE_WIDTH))) |
+			 (stp_state << (port * SOCE_STP_PORT_STATE_WIDTH)));
+	} else {
+		ps_lo_n =
+			((ps_lo_n & ~(SOCE_STP_PORT_STATE_MASK
+				      << (port * SOCE_STP_PORT_STATE_WIDTH))) |
+			 (stp_state << (port * SOCE_STP_PORT_STATE_WIDTH)));
+	}
+
+	writel(SOCE_STP_MSTID_CIST, p_mstp_mstid);
+	writel(ps_lo_n, p_mstp_ps_lo);
+	writel(ps_hi_n, p_mstp_ps_hi);
+	writel(SOCE_STP_PORT_STATE_WRITE, p_mstp_pc);
+}
+
+static void soce_fast_age(struct dsa_switch *ds, int port,
+			  const struct soce_layout *layout)
+{
+	struct soce_priv *priv = ds->priv;
+	struct soce_dsa_local *local;
+	void __iomem *p_mes_ctrl;
+	u32 val;
+
+	local = &priv->local;
+	if (!layout || !local->base_addr)
+		return;
+
+	p_mes_ctrl = local->base_addr + layout->fdb_ctrl;
+	if (readl_poll_timeout(p_mes_ctrl, val,
+			       !(val & SOCE_FDB_CLEAR_UNDER_PROCESS),
+			       SOCE_FAST_AGE_POLL_US, SOCE_FAST_AGE_TIMEOUT_US))
+		dev_warn(ds->dev, "SoC-e fast_age timeout on port %d\n", port);
+
+	writel(SOCE_FDB_CLEAR_FLUSH_MSTID, p_mes_ctrl);
+}
+
+int soce_setup(struct dsa_switch *ds)
+{
+	return soce_user_mii_bus_register(ds);
+}
+
+void soce_teardown(struct dsa_switch *ds)
+{
+	soce_user_mii_bus_unregister(ds);
+}
+
+int soce_port_enable(struct dsa_switch *ds, int port, struct phy_device *phy)
+{
+	return 0;
+}
+
+void soce_port_disable(struct dsa_switch *ds, int port)
+{
+}
+
+enum dsa_tag_protocol soce_get_tag_protocol(struct dsa_switch *ds, int port,
+					    enum dsa_tag_protocol mprop)
+{
+	return DSA_TAG_PROTO_SDSA;
+}
+
+/* Bridge membership is handled by the switch forwarding model directly. */
+int soce_port_bridge_join(struct dsa_switch *ds, int port,
+			  struct dsa_bridge bridge, bool *tx_fwd_offload,
+			  struct netlink_ext_ack *extack)
+{
+	return 0;
+}
+
+void soce_port_bridge_leave(struct dsa_switch *ds, int port,
+			    struct dsa_bridge bridge)
+{
+}
+
+void soce_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
+{
+	struct soce_priv *priv = ds->priv;
+
+	soce_stp_state_set(ds, port, state, priv->local.layout);
+}
+
+void soce_port_fast_age(struct dsa_switch *ds, int port)
+{
+	struct soce_priv *priv = ds->priv;
+
+	soce_fast_age(ds, port, priv->local.layout);
+}
+
diff --git a/drivers/net/dsa/soce/soce_common.h b/drivers/net/dsa/soce/soce_common.h
new file mode 100644
index 000000000000..2423ba167d9f
--- /dev/null
+++ b/drivers/net/dsa/soce/soce_common.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (c) 2020 System on Chip engineering, S.L.
+ * Copyright (c) 2026 Linutronix GmbH
+ */
+
+#ifndef __SOCE_COMMON_H
+#define __SOCE_COMMON_H
+
+#include <net/dsa.h>
+
+struct phy_device;
+struct netlink_ext_ack;
+
+struct soce_layout {
+	u32 mstp_port_state_control;
+	u32 mstp_mstid;
+	u32 mstp_port_state_lo;
+	u32 mstp_port_state_hi;
+	u32 fdb_ctrl;
+};
+
+int soce_setup(struct dsa_switch *ds);
+void soce_teardown(struct dsa_switch *ds);
+int soce_port_enable(struct dsa_switch *ds, int port, struct phy_device *phy);
+void soce_port_disable(struct dsa_switch *ds, int port);
+enum dsa_tag_protocol soce_get_tag_protocol(struct dsa_switch *ds, int port,
+					    enum dsa_tag_protocol mprop);
+int soce_port_bridge_join(struct dsa_switch *ds, int port,
+			  struct dsa_bridge bridge, bool *tx_fwd_offload,
+			  struct netlink_ext_ack *extack);
+void soce_port_bridge_leave(struct dsa_switch *ds, int port,
+			    struct dsa_bridge bridge);
+void soce_port_stp_state_set(struct dsa_switch *ds, int port, u8 state);
+void soce_port_fast_age(struct dsa_switch *ds, int port);
+
+#endif /* __SOCE_COMMON_H */
diff --git a/drivers/net/dsa/soce/soce_dsa.h b/drivers/net/dsa/soce/soce_dsa.h
new file mode 100644
index 000000000000..edc79d69891d
--- /dev/null
+++ b/drivers/net/dsa/soce/soce_dsa.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (c) 2020 System on Chip engineering, S.L.
+ * Copyright (c) 2026 Linutronix GmbH
+ */
+
+#ifndef __SOCE_DSA_H
+#define __SOCE_DSA_H
+
+#define SOCE_MAX_NUM_PORTS 30
+
+struct soce_mdio {
+	int mdio_output;
+	int phy_addr;
+};
+
+struct dsa_switch;
+struct soce_layout;
+
+struct soce_mdio_ops {
+	int (*phy_read)(struct dsa_switch *ds, int port, int regnum);
+	int (*phy_write)(struct dsa_switch *ds, int port, int regnum, u16 val);
+	int (*phy_read_c45)(struct dsa_switch *ds, int port, int devad,
+			    int regnum);
+	int (*phy_write_c45)(struct dsa_switch *ds, int port, int devad,
+			     int regnum, u16 val);
+};
+
+struct soce_dsa_local {
+	void __iomem *base_addr;
+	void __iomem *mdio_master_addr;
+	struct soce_mdio mdio_info[SOCE_MAX_NUM_PORTS];
+	const struct soce_mdio_ops *mdio_ops;
+	const struct soce_layout *layout;
+};
+
+struct soce_priv {
+	struct soce_dsa_local local;
+	struct dsa_switch *ds;
+};
+
+#endif /* __SOCE_DSA_H */
diff --git a/drivers/net/dsa/soce/soce_dsa_core.c b/drivers/net/dsa/soce/soce_dsa_core.c
new file mode 100644
index 000000000000..b88d00c56d71
--- /dev/null
+++ b/drivers/net/dsa/soce/soce_dsa_core.c
@@ -0,0 +1,354 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2020 System on Chip engineering, S.L.
+ * Copyright (c) 2026 Linutronix GmbH
+ */
+
+#include <linux/module.h>
+#include <linux/phy.h>
+#include <linux/netdevice.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <net/dsa.h>
+
+#include <linux/of_net.h>
+#include <linux/of_platform.h>
+#include <linux/if_bridge.h>
+#include <linux/mdio.h>
+#include <linux/of_mdio.h>
+#include <linux/etherdevice.h>
+#include <linux/phylink.h>
+
+#include "soce_dsa.h"
+#include "soce_common.h"
+#include "soce_mrs.h"
+#include "soce_mdio.h"
+
+static void soce_phylink_get_caps(struct dsa_switch *ds, int port,
+				  struct phylink_config *config)
+{
+	if (dsa_is_cpu_port(ds, port)) {
+		__set_bit(PHY_INTERFACE_MODE_GMII,
+			  config->supported_interfaces);
+		config->mac_capabilities = MAC_10 | MAC_100 | MAC_1000 |
+					   MAC_SYM_PAUSE | MAC_ASYM_PAUSE;
+		return;
+	}
+
+	phy_interface_set_rgmii(config->supported_interfaces);
+	config->mac_capabilities = MAC_10 | MAC_100 | MAC_1000 | MAC_SYM_PAUSE |
+				   MAC_ASYM_PAUSE;
+}
+
+static int soce_phy_read(struct dsa_switch *ds, int port, int regnum)
+{
+	struct soce_priv *priv = ds->priv;
+	struct soce_dsa_local *local;
+
+	local = &priv->local;
+	if (!local->mdio_ops || !local->mdio_ops->phy_read)
+		return 0xffff;
+
+	return local->mdio_ops->phy_read(ds, port, regnum);
+}
+
+static int soce_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
+{
+	struct soce_priv *priv = ds->priv;
+	struct soce_dsa_local *local;
+
+	local = &priv->local;
+	if (!local->mdio_ops || !local->mdio_ops->phy_write)
+		return -EOPNOTSUPP;
+
+	return local->mdio_ops->phy_write(ds, port, regnum, val);
+}
+
+static const struct soce_mdio_ops soce_mdio_ops_20_03 = {
+	.phy_read	= soce_mdio_20_03_read,
+	.phy_write	= soce_mdio_20_03_write,
+};
+
+static const struct soce_mdio_ops soce_mdio_ops_c22_c45 = {
+	.phy_read	= soce_mdio_23_02_read,
+	.phy_write	= soce_mdio_23_02_write,
+	.phy_read_c45	= soce_mdio_23_02_read_c45,
+	.phy_write_c45	= soce_mdio_23_02_write_c45,
+};
+
+static const struct dsa_switch_ops soce_switch_ops = {
+	.get_tag_protocol	= soce_get_tag_protocol,
+	.setup			= soce_setup,
+	.teardown		= soce_teardown,
+	.phylink_get_caps	= soce_phylink_get_caps,
+	.phy_read		= soce_phy_read,
+	.phy_write		= soce_phy_write,
+	.port_enable		= soce_port_enable,
+	.port_disable		= soce_port_disable,
+	.port_bridge_join	= soce_port_bridge_join,
+	.port_bridge_leave	= soce_port_bridge_leave,
+	.port_stp_state_set	= soce_port_stp_state_set,
+	.port_fast_age		= soce_port_fast_age,
+};
+
+struct soce_variant_desc {
+	const char *compatible;
+	u32 mdio_master_offset;
+	const struct soce_layout *layout;
+	const struct soce_mdio_ops *mdio_ops;
+};
+
+static const struct soce_layout soce_mrs_21_01_layout = {
+	.mstp_port_state_control = SOCE_MRS_21_01_MSTP_PORT_STATE_CONTROL_REG,
+	.mstp_mstid		= SOCE_MRS_21_01_MSTP_MSTID_OFFSET,
+	.mstp_port_state_lo	= SOCE_MRS_21_01_MSTP_PORT_STATE_OFFSET_LO,
+	.mstp_port_state_hi	= SOCE_MRS_21_01_MSTP_PORT_STATE_OFFSET_HI,
+	.fdb_ctrl		= SOCE_MRS_21_01_FDB_CTRL_OFFSET,
+};
+
+static const struct soce_layout soce_mrs_24_01_layout = {
+	.mstp_port_state_control = SOCE_MRS_24_01_MSTP_PORT_STATE_CONTROL_REG,
+	.mstp_mstid		= SOCE_MRS_24_01_MSTP_MSTID_OFFSET,
+	.mstp_port_state_lo	= SOCE_MRS_24_01_MSTP_PORT_STATE_OFFSET_LO,
+	.mstp_port_state_hi	= SOCE_MRS_24_01_MSTP_PORT_STATE_OFFSET_HI,
+	.fdb_ctrl		= SOCE_MRS_24_01_FDB_CTRL_OFFSET,
+};
+
+static const struct soce_variant_desc soce_variants[] = {
+	{
+		.compatible		= "soce,mrs-21-01",
+		.mdio_master_offset	= SOCE_MRS_21_01_MDIO_MASTER_OFFSET,
+		.layout			= &soce_mrs_21_01_layout,
+		.mdio_ops		= &soce_mdio_ops_20_03,
+	},
+	{
+		.compatible		= "soce,mrs-23-02",
+		.mdio_master_offset	= SOCE_MRS_21_01_MDIO_MASTER_OFFSET,
+		.layout			= &soce_mrs_24_01_layout,
+		.mdio_ops		= &soce_mdio_ops_c22_c45,
+	},
+	{
+		.compatible		= "soce,mrs-24-01",
+		.mdio_master_offset	= SOCE_MRS_21_01_MDIO_MASTER_OFFSET,
+		.layout			= &soce_mrs_24_01_layout,
+		.mdio_ops		= &soce_mdio_ops_c22_c45,
+	},
+	{ /* sentinel */ },
+};
+
+static const struct soce_variant_desc *
+soce_match_variant(const char *compatible)
+{
+	int i;
+
+	for (i = 0; soce_variants[i].compatible; i++) {
+		if (!strcmp(compatible, soce_variants[i].compatible))
+			return &soce_variants[i];
+	}
+
+	return NULL;
+}
+
+static int soce_sw_parse_port_mdio_config(struct soce_dsa_local *local,
+					  struct device *dev,
+					  struct device_node *port_node,
+					  u32 port)
+{
+	struct device_node *phy_node;
+	u32 val;
+	int ret;
+
+	if (of_find_property(port_node, "ethernet", NULL) ||
+	    of_find_property(port_node, "link", NULL)) {
+		if (of_find_property(port_node, "phy-handle", NULL)) {
+			dev_err(dev,
+				"phy-handle not allowed on CPU/DSA port %u\n",
+				port);
+			return -EINVAL;
+		}
+
+		return 0;
+	}
+
+	phy_node = of_parse_phandle(port_node, "phy-handle", 0);
+	if (!phy_node) {
+		if (of_phy_is_fixed_link(port_node))
+			return 0;
+
+		dev_err(dev, "user port %u requires phy-handle or fixed-link\n",
+			port);
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32(phy_node, "soce,mdio-output", &val);
+	if (ret) {
+		dev_err(dev,
+			"missing soce,mdio-output in %pOF referenced by port %u\n",
+			phy_node, port);
+		goto out_put_phy;
+	}
+	local->mdio_info[port].mdio_output = val;
+
+	ret = of_property_read_u32(phy_node, "soce,phy-addr", &val);
+	if (ret) {
+		dev_err(dev,
+			"missing soce,phy-addr in %pOF referenced by port %u\n",
+			phy_node, port);
+		goto out_put_phy;
+	}
+	local->mdio_info[port].phy_addr = val;
+
+out_put_phy:
+	of_node_put(phy_node);
+	return ret;
+}
+
+static int soce_sw_parse_port_mdio(struct soce_priv *priv, struct device *dev,
+				   u32 numports)
+{
+	struct soce_dsa_local *local = &priv->local;
+	struct device_node *ports_node;
+	struct device_node *port_node;
+	u32 port;
+	int ret;
+
+	ports_node = of_get_child_by_name(dev->of_node, "ports");
+	if (!ports_node) {
+		dev_err(dev, "missing ports node\n");
+		return -EINVAL;
+	}
+
+	for_each_available_child_of_node(ports_node, port_node) {
+		if (of_property_read_u32(port_node, "reg", &port))
+			continue;
+
+		if (port >= numports || port >= SOCE_MAX_NUM_PORTS) {
+			dev_warn(dev,
+				 "ignoring invalid port index %u in %pOF\n",
+				 port, port_node);
+			continue;
+		}
+
+		ret = soce_sw_parse_port_mdio_config(local, dev, port_node,
+						     port);
+		if (ret) {
+			of_node_put(port_node);
+			of_node_put(ports_node);
+			return ret;
+		}
+	}
+
+	of_node_put(ports_node);
+	return 0;
+}
+
+static int soce_sw_probe(struct mdio_device *mdiodev)
+{
+	const struct soce_variant_desc *variant;
+	struct device *dev = &mdiodev->dev;
+	struct device_node *switch_node;
+	struct soce_dsa_local *local;
+	const char *soce_compatible;
+	struct soce_priv *priv;
+	u32 numports;
+	int ret;
+
+	priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL);
+	if (!priv->ds)
+		return -ENOMEM;
+
+	priv->ds->dev = dev;
+	priv->ds->priv = priv;
+	local = &priv->local;
+
+	switch_node = of_parse_phandle(dev->of_node, "soce,switch-ip", 0);
+	if (!switch_node) {
+		dev_err(dev, "missing or invalid switch IP reference\n");
+		return -EINVAL;
+	}
+
+	ret = of_property_read_string(switch_node, "compatible",
+				      &soce_compatible);
+	if (ret) {
+		dev_err(dev, "missing compatible property in %pOF\n",
+			switch_node);
+		of_node_put(switch_node);
+		return -EINVAL;
+	}
+
+	variant = soce_match_variant(soce_compatible);
+	if (!variant) {
+		dev_err(dev, "unsupported compatible '%s' in %pOF\n",
+			soce_compatible, switch_node);
+		of_node_put(switch_node);
+		return -ENODEV;
+	}
+
+	ret = of_property_read_u32(switch_node, "soce,num-ports", &numports);
+	if (ret) {
+		dev_err(dev, "missing soce,num-ports in %pOF\n", switch_node);
+		of_node_put(switch_node);
+		return -EINVAL;
+	}
+	if (numports == 0 || numports > SOCE_MAX_NUM_PORTS) {
+		dev_err(dev, "invalid soce,num-ports %u (max %d)\n", numports,
+			SOCE_MAX_NUM_PORTS);
+		of_node_put(switch_node);
+		return -EINVAL;
+	}
+
+	local->base_addr = devm_of_iomap(dev, switch_node, 0, NULL);
+	if (IS_ERR(local->base_addr)) {
+		dev_err(dev, "failed to map switch register space for %pOF\n",
+			switch_node);
+		of_node_put(switch_node);
+		return PTR_ERR(local->base_addr);
+	}
+
+	priv->ds->ops = &soce_switch_ops;
+	local->mdio_ops = variant->mdio_ops;
+	local->mdio_master_addr =
+		local->base_addr + variant->mdio_master_offset;
+	local->layout = variant->layout;
+	of_node_put(switch_node);
+
+	priv->ds->num_ports = numports;
+	ret = soce_sw_parse_port_mdio(priv, dev, numports);
+	if (ret)
+		return ret;
+
+	dev_set_drvdata(&mdiodev->dev, priv);
+
+	dev_info(dev, "soce %s SDSA driver probed.\n", soce_compatible);
+
+	return dsa_register_switch(priv->ds);
+}
+
+static void soce_sw_remove(struct mdio_device *mdiodev)
+{
+	struct soce_priv *priv = dev_get_drvdata(&mdiodev->dev);
+
+	dsa_unregister_switch(priv->ds);
+}
+
+static const struct of_device_id soce_of_match[] = {
+	{ .compatible = "soce,switch-dsa" },
+	{ /* sentinel */ },
+};
+
+static struct mdio_driver soce_mdio_driver = {
+	.mdiodrv.driver = {
+		.name = "soce-switch-dsa",
+		.of_match_table = soce_of_match,
+	},
+	.probe  = soce_sw_probe,
+	.remove = soce_sw_remove,
+};
+
+mdio_module_driver(soce_mdio_driver);
+MODULE_AUTHOR("Vasilij Strassheim <v.strassheim@linutronix.de>");
+MODULE_DESCRIPTION("Driver for SoC-e ethernet switch family");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/dsa/soce/soce_mdio.c b/drivers/net/dsa/soce/soce_mdio.c
new file mode 100644
index 000000000000..241fc373de8b
--- /dev/null
+++ b/drivers/net/dsa/soce/soce_mdio.c
@@ -0,0 +1,381 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2020 System on Chip engineering, S.L.
+ * Copyright (c) 2026 Linutronix GmbH
+ */
+
+#include <linux/mdio.h>
+#include <linux/of_mdio.h>
+#include <linux/phy.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/bits.h>
+#include <net/dsa.h>
+#include "soce_dsa.h"
+#include "soce_mdio.h"
+
+#define SOCE_MDIO_TIMEOUT 1000
+
+/* MDIO 20.03 control word layout:
+ * [31:27] PHY address, [26:22] register address, [21] operation,
+ * [20] start/operation in progress, [7:0] MDIO bus selection.
+ */
+#define SOCE_MDIO_20_03_CTRL_PHY_ADDR_SHIFT	27
+#define SOCE_MDIO_20_03_CTRL_REG_ADDR_SHIFT	22
+#define SOCE_MDIO_20_03_CTRL_OP_SHIFT		21
+#define SOCE_MDIO_20_03_CTRL_START_SHIFT	20
+#define SOCE_MDIO_20_03_CTRL_OP_WRITE		0U
+
+#define SOCE_MDIO_20_03_CTRL_OP_READ	BIT(SOCE_MDIO_20_03_CTRL_OP_SHIFT)
+#define SOCE_MDIO_20_03_CTRL_START	BIT(SOCE_MDIO_20_03_CTRL_START_SHIFT)
+
+static int soce_user_phy_read(struct mii_bus *bus, int addr, int reg)
+{
+	struct dsa_switch *ds = bus->priv;
+
+	if (ds->phys_mii_mask & BIT(addr))
+		return ds->ops->phy_read(ds, addr, reg);
+
+	return 0xffff;
+}
+
+static int soce_user_phy_write(struct mii_bus *bus, int addr, int reg, u16 val)
+{
+	struct dsa_switch *ds = bus->priv;
+
+	if (ds->phys_mii_mask & BIT(addr))
+		return ds->ops->phy_write(ds, addr, reg, val);
+
+	return 0;
+}
+
+static int soce_user_phy_read_c45(struct mii_bus *bus, int addr, int devad,
+				  int regnum)
+{
+	struct dsa_switch *ds = bus->priv;
+	struct soce_priv *priv = ds->priv;
+	struct soce_dsa_local *local;
+
+	if (!(ds->phys_mii_mask & BIT(addr)))
+		return 0xffff;
+
+	local = &priv->local;
+	if (!local->mdio_ops || !local->mdio_ops->phy_read_c45)
+		return -EOPNOTSUPP;
+
+	return local->mdio_ops->phy_read_c45(ds, addr, devad, regnum);
+}
+
+static int soce_user_phy_write_c45(struct mii_bus *bus, int addr, int devad,
+				   int regnum, u16 val)
+{
+	struct dsa_switch *ds = bus->priv;
+	struct soce_priv *priv = ds->priv;
+	struct soce_dsa_local *local;
+
+	if (!(ds->phys_mii_mask & BIT(addr)))
+		return 0;
+
+	local = &priv->local;
+	if (!local->mdio_ops || !local->mdio_ops->phy_write_c45)
+		return -EOPNOTSUPP;
+
+	return local->mdio_ops->phy_write_c45(ds, addr, devad, regnum, val);
+}
+
+int soce_user_mii_bus_register(struct dsa_switch *ds)
+{
+	struct device_node *mdio_np;
+	int err;
+
+	if (ds->user_mii_bus)
+		return 0;
+
+	ds->user_mii_bus = mdiobus_alloc();
+	if (!ds->user_mii_bus)
+		return -ENOMEM;
+
+	ds->user_mii_bus->priv = ds;
+	ds->user_mii_bus->name = "soce user mii";
+	ds->user_mii_bus->read = soce_user_phy_read;
+	ds->user_mii_bus->write = soce_user_phy_write;
+	ds->user_mii_bus->read_c45 = soce_user_phy_read_c45;
+	ds->user_mii_bus->write_c45 = soce_user_phy_write_c45;
+	snprintf(ds->user_mii_bus->id, MII_BUS_ID_SIZE, "dsa-%d.%d",
+		 ds->dst->index, ds->index);
+	ds->user_mii_bus->parent = ds->dev;
+	ds->user_mii_bus->phy_mask = ~ds->phys_mii_mask;
+
+	mdio_np = of_get_child_by_name(ds->dev->of_node, "mdio");
+	err = of_mdiobus_register(ds->user_mii_bus, mdio_np);
+	of_node_put(mdio_np);
+
+	if (err) {
+		mdiobus_free(ds->user_mii_bus);
+		ds->user_mii_bus = NULL;
+		return err;
+	}
+
+	return 0;
+}
+
+void soce_user_mii_bus_unregister(struct dsa_switch *ds)
+{
+	if (!ds || !ds->user_mii_bus)
+		return;
+
+	mdiobus_unregister(ds->user_mii_bus);
+	mdiobus_free(ds->user_mii_bus);
+	ds->user_mii_bus = NULL;
+}
+
+static int soce_mdio_20_03_wait_for_idle(struct dsa_switch *ds)
+{
+	struct soce_priv *priv = ds->priv;
+	struct soce_dsa_local *local;
+	void __iomem *ctrl;
+	u32 val;
+
+	local = &priv->local;
+	ctrl = local->mdio_master_addr + SOCE_MDIO_CTRL_OFFSET;
+	return readl_poll_timeout(ctrl, val,
+				  !(val & SOCE_MDIO_20_03_CTRL_START), 10,
+				  SOCE_MDIO_TIMEOUT * 1000);
+}
+
+int soce_mdio_20_03_read(struct dsa_switch *ds, int portnumber, int regnum)
+{
+	struct soce_priv *priv = ds->priv;
+	void __iomem *ctrl, *read_reg;
+	struct soce_dsa_local *local;
+	struct soce_mdio *mdio;
+	u32 regvalue;
+	int ret;
+
+	local = &priv->local;
+	mdio = &local->mdio_info[portnumber];
+	ctrl = local->mdio_master_addr + SOCE_MDIO_CTRL_OFFSET;
+	read_reg = local->mdio_master_addr + SOCE_MDIO_20_03_READ_OFFSET;
+
+	regvalue = (mdio->phy_addr << SOCE_MDIO_20_03_CTRL_PHY_ADDR_SHIFT) |
+		   (regnum << SOCE_MDIO_20_03_CTRL_REG_ADDR_SHIFT) |
+		   SOCE_MDIO_20_03_CTRL_OP_READ |
+		   SOCE_MDIO_20_03_CTRL_START |
+		   mdio->mdio_output;
+	writel(regvalue, ctrl);
+
+	ret = soce_mdio_20_03_wait_for_idle(ds);
+	if (ret)
+		return ret;
+
+	return readl(read_reg) & 0xffff;
+}
+
+int soce_mdio_20_03_write(struct dsa_switch *ds, int portnumber, int regnum,
+			  u16 val)
+{
+	struct soce_priv *priv = ds->priv;
+	void __iomem *ctrl, *write_reg;
+	struct soce_dsa_local *local;
+	struct soce_mdio *mdio;
+	u32 regvalue;
+
+	local = &priv->local;
+	mdio = &local->mdio_info[portnumber];
+	ctrl = local->mdio_master_addr + SOCE_MDIO_CTRL_OFFSET;
+	write_reg = local->mdio_master_addr + SOCE_MDIO_20_03_WRITE_OFFSET;
+
+	/* Write data first */
+	writel(val, write_reg);
+
+	/* Then write control */
+	regvalue = (mdio->phy_addr << SOCE_MDIO_20_03_CTRL_PHY_ADDR_SHIFT) |
+		   (regnum << SOCE_MDIO_20_03_CTRL_REG_ADDR_SHIFT) |
+		   SOCE_MDIO_20_03_CTRL_OP_WRITE |
+		   SOCE_MDIO_20_03_CTRL_START |
+		   mdio->mdio_output;
+	writel(regvalue, ctrl);
+
+	return soce_mdio_20_03_wait_for_idle(ds);
+}
+
+static int soce_mdio_23_02_wait_for_idle(struct dsa_switch *ds)
+{
+	struct soce_priv *priv = ds->priv;
+	struct soce_dsa_local *local;
+	void __iomem *ctrl;
+	u32 val;
+
+	local = &priv->local;
+	ctrl = local->mdio_master_addr + SOCE_MDIO_CTRL_OFFSET;
+
+	return readl_poll_timeout(ctrl, val,
+		!(val & (0x1 << SOCE_MDIO_23_02_CTRL_OPSTATUS_OFFSET)), 10,
+		SOCE_MDIO_TIMEOUT * 1000);
+}
+
+static int soce_mdio_23_02_read_c22(struct dsa_switch *ds, int portnumber,
+				    int regnum)
+{
+	void __iomem *ctrl, *params, *read_reg;
+	struct soce_priv *priv = ds->priv;
+	struct soce_dsa_local *local;
+	struct soce_mdio *mdio;
+	u32 regvalue;
+	int ret;
+
+	local = &priv->local;
+	mdio = &local->mdio_info[portnumber];
+	ctrl = local->mdio_master_addr + SOCE_MDIO_CTRL_OFFSET;
+	params = local->mdio_master_addr + SOCE_MDIO_23_02_PARAMS_OFFSET;
+	read_reg = local->mdio_master_addr + SOCE_MDIO_23_02_READ_OFFSET;
+
+	regvalue = (regnum << SOCE_MDIO_23_02_CTRL_REGADDRDEVTYPE_OFFSET) +
+		   (mdio->phy_addr << SOCE_MDIO_23_02_CTRL_PHYADDR_OFFSET);
+	writel(regvalue, params);
+
+	regvalue = ((mdio->mdio_output << SOCE_MDIO_23_02_CTRL_BUS_OFFSET) +
+		    (0x3 << SOCE_MDIO_23_02_CTRL_TRANSTYPE_OFFSET) +
+		    (0x0 << SOCE_MDIO_23_02_CTRL_CLAUSE_OFFSET) +
+		    (0x1 << SOCE_MDIO_23_02_CTRL_OPSTATUS_OFFSET));
+	writel(regvalue, ctrl);
+
+	ret = soce_mdio_23_02_wait_for_idle(ds);
+	if (ret)
+		return ret;
+
+	return readl(read_reg) & 0xffff;
+}
+
+int soce_mdio_23_02_read_c45(struct dsa_switch *ds, int portnumber, int devad,
+			     int regnum)
+{
+	void __iomem *ctrl, *params, *read_reg, *write_reg;
+	struct soce_priv *priv = ds->priv;
+	struct soce_dsa_local *local;
+	struct soce_mdio *mdio;
+	u32 regvalue;
+	int ret;
+
+	local = &priv->local;
+	mdio = &local->mdio_info[portnumber];
+	ctrl = local->mdio_master_addr + SOCE_MDIO_CTRL_OFFSET;
+	params = local->mdio_master_addr + SOCE_MDIO_23_02_PARAMS_OFFSET;
+	write_reg = local->mdio_master_addr + SOCE_MDIO_23_02_WRITE_OFFSET;
+	read_reg = local->mdio_master_addr + SOCE_MDIO_23_02_READ_OFFSET;
+
+	regvalue = (devad << SOCE_MDIO_23_02_CTRL_REGADDRDEVTYPE_OFFSET) +
+		   (mdio->phy_addr << SOCE_MDIO_23_02_CTRL_PHYADDR_OFFSET);
+	writel(regvalue, params);
+
+	writel(regnum, write_reg);
+
+	/* address cycle */
+	regvalue = ((mdio->mdio_output << SOCE_MDIO_23_02_CTRL_BUS_OFFSET) +
+		    (0x0 << SOCE_MDIO_23_02_CTRL_TRANSTYPE_OFFSET) +
+		    (0x1 << SOCE_MDIO_23_02_CTRL_CLAUSE_OFFSET) +
+		    (0x1 << SOCE_MDIO_23_02_CTRL_OPSTATUS_OFFSET));
+	writel(regvalue, ctrl);
+
+	ret = soce_mdio_23_02_wait_for_idle(ds);
+	if (ret)
+		return ret;
+
+	/* read cycle */
+	regvalue = ((mdio->mdio_output << SOCE_MDIO_23_02_CTRL_BUS_OFFSET) +
+		    (0x3 << SOCE_MDIO_23_02_CTRL_TRANSTYPE_OFFSET) +
+		    (0x1 << SOCE_MDIO_23_02_CTRL_CLAUSE_OFFSET) +
+		    (0x1 << SOCE_MDIO_23_02_CTRL_OPSTATUS_OFFSET));
+	writel(regvalue, ctrl);
+
+	ret = soce_mdio_23_02_wait_for_idle(ds);
+	if (ret)
+		return ret;
+
+	return readl(read_reg) & 0xffff;
+}
+
+int soce_mdio_23_02_read(struct dsa_switch *ds, int portnumber, int regnum)
+{
+	return soce_mdio_23_02_read_c22(ds, portnumber, regnum);
+}
+
+static int soce_mdio_23_02_write_c22(struct dsa_switch *ds, int portnumber,
+				     int regnum, u16 val)
+{
+	void __iomem *ctrl, *params, *write_reg;
+	struct soce_priv *priv = ds->priv;
+	struct soce_dsa_local *local;
+	struct soce_mdio *mdio;
+	u32 regvalue;
+
+	local = &priv->local;
+	mdio = &local->mdio_info[portnumber];
+	params = local->mdio_master_addr + SOCE_MDIO_23_02_PARAMS_OFFSET;
+	ctrl = local->mdio_master_addr + SOCE_MDIO_CTRL_OFFSET;
+	write_reg = local->mdio_master_addr + SOCE_MDIO_23_02_WRITE_OFFSET;
+
+	regvalue = (regnum << SOCE_MDIO_23_02_CTRL_REGADDRDEVTYPE_OFFSET) +
+		   (mdio->phy_addr << SOCE_MDIO_23_02_CTRL_PHYADDR_OFFSET);
+	writel(regvalue, params);
+
+	writel(val, write_reg);
+
+	regvalue = ((mdio->mdio_output << SOCE_MDIO_23_02_CTRL_BUS_OFFSET) +
+		    (0x1 << SOCE_MDIO_23_02_CTRL_TRANSTYPE_OFFSET) +
+		    (0x0 << SOCE_MDIO_23_02_CTRL_CLAUSE_OFFSET) +
+		    (0x1 << SOCE_MDIO_23_02_CTRL_OPSTATUS_OFFSET));
+	writel(regvalue, ctrl);
+
+	return soce_mdio_23_02_wait_for_idle(ds);
+}
+
+int soce_mdio_23_02_write_c45(struct dsa_switch *ds, int portnumber, int devad,
+			      int regnum, u16 val)
+{
+	void __iomem *ctrl, *params, *write_reg;
+	struct soce_priv *priv = ds->priv;
+	struct soce_dsa_local *local;
+	struct soce_mdio *mdio;
+	u32 regvalue;
+	int ret;
+
+	local = &priv->local;
+	mdio = &local->mdio_info[portnumber];
+	ctrl = local->mdio_master_addr + SOCE_MDIO_CTRL_OFFSET;
+	params = local->mdio_master_addr + SOCE_MDIO_23_02_PARAMS_OFFSET;
+	write_reg = local->mdio_master_addr + SOCE_MDIO_23_02_WRITE_OFFSET;
+
+	regvalue = (devad << SOCE_MDIO_23_02_CTRL_REGADDRDEVTYPE_OFFSET) +
+		   (mdio->phy_addr << SOCE_MDIO_23_02_CTRL_PHYADDR_OFFSET);
+	writel(regvalue, params);
+
+	writel(regnum, write_reg);
+
+	/* address cycle */
+	regvalue = ((mdio->mdio_output << SOCE_MDIO_23_02_CTRL_BUS_OFFSET) +
+		    (0x0 << SOCE_MDIO_23_02_CTRL_TRANSTYPE_OFFSET) +
+		    (0x1 << SOCE_MDIO_23_02_CTRL_CLAUSE_OFFSET) +
+		    (0x1 << SOCE_MDIO_23_02_CTRL_OPSTATUS_OFFSET));
+	writel(regvalue, ctrl);
+
+	ret = soce_mdio_23_02_wait_for_idle(ds);
+	if (ret)
+		return ret;
+
+	writel(val, write_reg);
+
+	/* write cycle */
+	regvalue = ((mdio->mdio_output << SOCE_MDIO_23_02_CTRL_BUS_OFFSET) +
+		    (0x1 << SOCE_MDIO_23_02_CTRL_TRANSTYPE_OFFSET) +
+		    (0x1 << SOCE_MDIO_23_02_CTRL_CLAUSE_OFFSET) +
+		    (0x1 << SOCE_MDIO_23_02_CTRL_OPSTATUS_OFFSET));
+	writel(regvalue, ctrl);
+
+	return soce_mdio_23_02_wait_for_idle(ds);
+}
+
+int soce_mdio_23_02_write(struct dsa_switch *ds, int portnumber, int regnum,
+			  u16 val)
+{
+	return soce_mdio_23_02_write_c22(ds, portnumber, regnum, val);
+}
diff --git a/drivers/net/dsa/soce/soce_mdio.h b/drivers/net/dsa/soce/soce_mdio.h
new file mode 100644
index 000000000000..a71158ed06b3
--- /dev/null
+++ b/drivers/net/dsa/soce/soce_mdio.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (c) 2020 System on Chip engineering, S.L.
+ * Copyright (c) 2026 Linutronix GmbH
+ */
+
+#ifndef __SOCE_MDIO_H
+#define __SOCE_MDIO_H
+
+#define SOCE_MDIO_CTRL_OFFSET 0x0000
+
+/* for older versions */
+#define SOCE_MDIO_20_03_WRITE_OFFSET	0x0004
+#define SOCE_MDIO_20_03_READ_OFFSET	0x0008
+
+/* for newer versions */
+#define SOCE_MDIO_23_02_PARAMS_OFFSET		0x0004
+#define SOCE_MDIO_23_02_WRITE_OFFSET		0x0008
+#define SOCE_MDIO_23_02_READ_OFFSET		0x000c
+#define SOCE_MDIO_23_02_CTRL_BUS_OFFSET		16
+#define SOCE_MDIO_23_02_CTRL_TRANSTYPE_OFFSET	3
+#define SOCE_MDIO_23_02_CTRL_CLAUSE_OFFSET	1
+#define SOCE_MDIO_23_02_CTRL_OPSTATUS_OFFSET	0
+
+#define SOCE_MDIO_23_02_CTRL_REGADDRDEVTYPE_OFFSET	8
+#define SOCE_MDIO_23_02_CTRL_PHYADDR_OFFSET		0
+
+int soce_mdio_20_03_read(struct dsa_switch *ds, int portnumber, int regnum);
+int soce_mdio_20_03_write(struct dsa_switch *ds, int portnumber, int regnum,
+			  u16 val);
+
+int soce_mdio_23_02_read(struct dsa_switch *ds, int portnumber, int regnum);
+int soce_mdio_23_02_write(struct dsa_switch *ds, int portnumber, int regnum,
+			  u16 val);
+int soce_mdio_23_02_read_c45(struct dsa_switch *ds, int portnumber, int devad,
+			     int regnum);
+int soce_mdio_23_02_write_c45(struct dsa_switch *ds, int portnumber, int devad,
+			      int regnum, u16 val);
+int soce_user_mii_bus_register(struct dsa_switch *ds);
+void soce_user_mii_bus_unregister(struct dsa_switch *ds);
+#endif /* __SOCE_MDIO_H */
diff --git a/drivers/net/dsa/soce/soce_mrs.h b/drivers/net/dsa/soce/soce_mrs.h
new file mode 100644
index 000000000000..cf2b29f1297e
--- /dev/null
+++ b/drivers/net/dsa/soce/soce_mrs.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (c) 2020 System on Chip engineering, S.L.
+ * Copyright (c) 2026 Linutronix GmbH
+ */
+
+#ifndef __SOCE_MRS_H
+#define __SOCE_MRS_H
+
+#define SOCE_MRS_21_01_MSTP_PORT_STATE_CONTROL_REG	0x0D04
+#define SOCE_MRS_21_01_MSTP_MSTID_OFFSET		0x0D08
+#define SOCE_MRS_21_01_MSTP_PORT_STATE_OFFSET_LO	0x0D0C
+#define SOCE_MRS_21_01_MSTP_PORT_STATE_OFFSET_HI	0x0D10
+#define SOCE_MRS_24_01_MSTP_PORT_STATE_CONTROL_REG	0x0F04
+#define SOCE_MRS_24_01_MSTP_MSTID_OFFSET		0x0F08
+#define SOCE_MRS_24_01_MSTP_PORT_STATE_OFFSET_LO	0x0F0C
+#define SOCE_MRS_24_01_MSTP_PORT_STATE_OFFSET_HI	0x0F10
+#define SOCE_MRS_21_01_FDB_CTRL_OFFSET			0x0A0C
+#define SOCE_MRS_24_01_FDB_CTRL_OFFSET			0x0C0C
+#define SOCE_MRS_21_01_MDIO_MASTER_OFFSET		0x0200
+
+#endif /* __SOCE_MRS_H */

-- 
2.39.5


^ permalink raw reply related	[flat|nested] 44+ messages in thread

* Re: [PATCH 0/4] net: dsa: Add SoC-e DSA driver
  2026-07-29 16:36 [PATCH 0/4] net: dsa: Add SoC-e DSA driver Vasilij Strassheim
                   ` (3 preceding siblings ...)
  2026-07-29 16:36 ` [PATCH 4/4] net: dsa: soce: Add initial driver support for MRS switches Vasilij Strassheim
@ 2026-07-29 16:56 ` Andrew Lunn
  2026-08-03 15:22   ` Vasilij Strassheim
  4 siblings, 1 reply; 44+ messages in thread
From: Andrew Lunn @ 2026-07-29 16:56 UTC (permalink / raw)
  To: Vasilij Strassheim
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vladimir Oltean,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Russell King, devicetree, linux-kernel, netdev,
	Martin Kaistra

On Wed, Jul 29, 2026 at 06:36:53PM +0200, Vasilij Strassheim wrote:
> Add initial support for the DSA driver for SoC-e FPGA-based (IP core)
> Ethernet switches.

Let me start with a dumb question. Is this a true soft core switch,
which is synthesised and running in the FPGA? Or is it hardware at the
edge of the FPGA SoC?

If it is synthesised, do we have to deal with different synthesis
options? Are there registers which indicate what these options are?

Where as if it is fixed hardware in the SoC we don't need to worry so
much about variations, it is fixed at the SoC level.

> There are different variants of the SoC-e switch IP, which can be
> additionally configured at runtime with proprietary userspace software.

What sort of configuration?

     Andrew

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 2/4] dt-bindings: net: dsa: Add SoC-e switch IP and DSA bindings
  2026-07-29 16:36 ` [PATCH 2/4] dt-bindings: net: dsa: Add SoC-e switch IP and DSA bindings Vasilij Strassheim
@ 2026-07-29 17:11   ` Andrew Lunn
  2026-08-03 15:29     ` Vasilij Strassheim
  2026-07-29 18:07   ` Rob Herring (Arm)
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 44+ messages in thread
From: Andrew Lunn @ 2026-07-29 17:11 UTC (permalink / raw)
  To: Vasilij Strassheim
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vladimir Oltean,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Russell King, devicetree, linux-kernel, netdev,
	Martin Kaistra

> +description: |
> +  This node is the MDIO-bus device entry for the SoC-e DSA switch driver.
> +  It is a lightweight configuration node that lives on the MDIO bus of the
> +  SoC Ethernet controller acting as the DSA conduit (CPU port).

Must it be the conduit interfaces MDIO bus? There are boards which
exist using Marvell switches where the MDIO bus of the conduit
interface is not a Linux MDIO bus, because it is an intel i210, and
intel likes reinventing the wheel and does not use the Linux MDIO bus
infrastructure. So the MDIO interface of the switch is connected to
two GPIOs and a Linux bit bashing MDIO bus is used.

> +  soce,num-ports:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description: |
> +      Total number of switch ports (external/user ports plus the CPU uplink
> +      port). Must be greater than zero and not exceed the selected IP variant.

Why is this needed if we already have a description of the ports?

    Andrew

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 3/4] net: dsa: Add support for SoC-e SDSA tags
  2026-07-29 16:36 ` [PATCH 3/4] net: dsa: Add support for SoC-e SDSA tags Vasilij Strassheim
@ 2026-07-29 17:22   ` Andrew Lunn
  2026-08-03 15:37     ` Vasilij Strassheim
  0 siblings, 1 reply; 44+ messages in thread
From: Andrew Lunn @ 2026-07-29 17:22 UTC (permalink / raw)
  To: Vasilij Strassheim
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vladimir Oltean,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Russell King, devicetree, linux-kernel, netdev,
	Martin Kaistra

> @@ -98,6 +98,12 @@ config NET_DSA_TAG_EDSA
>  	  Say Y or M if you want to enable support for tagging frames for the
>  	  Marvell switches which use EtherType DSA headers.
>  
> +config NET_DSA_TAG_SDSA
> +	tristate "Tag driver for SoC-e switches using EtherType SDSA headers"
> +	help
> +	  Say Y or M if you want to enable support for tagging frames for the
> +	  SoC-e switches.
> +

These entries are sorted, so it probably should be between
NET_DSA_TAG_RZN1_A5PSW and NET_DSA_TAG_LAN9303.

> @@ -23,6 +23,7 @@ dsa_core-y += \
>  obj-$(CONFIG_NET_DSA_TAG_AR9331) += tag_ar9331.o
>  obj-$(CONFIG_NET_DSA_TAG_BRCM_COMMON) += tag_brcm.o
>  obj-$(CONFIG_NET_DSA_TAG_DSA_COMMON) += tag_dsa.o
> +obj-$(CONFIG_NET_DSA_TAG_SDSA) += tag_sdsa.o
>  obj-$(CONFIG_NET_DSA_TAG_GSWIP) += tag_gswip.o

Also sorted, and this is the wrong spot.

> +#define SDSA_HLEN	8
> +
> +#define SDSA_NAME	"sdsa"

Does SDSA mean anything? Or have you taken net/dsa/tag_dsa.c, and just
changed edsa to sdsa?

> +static struct sk_buff *sdsa_xmit(struct sk_buff *skb, struct net_device *dev)
> +{
> +	struct dsa_port *dp = dsa_user_to_port(dev);
> +	u8 *sdsa_header;
> +
> +	if (skb_cow_head(skb, SDSA_HLEN) < 0)
> +		return NULL;
> +
> +	skb_push(skb, SDSA_HLEN);
> +	dsa_alloc_etype_header(skb, SDSA_HLEN);
> +
> +	/* Construct the FROM_CPU DSA tag. */

Is FROM_CPU a concept for this device? Are there other types of tag?

> +	sdsa_header = dsa_etype_header_pos_tx(skb);
> +	sdsa_header[0] = (ETH_P_SDSA >> 8) & 0xff;
> +	sdsa_header[1] = ETH_P_SDSA & 0xff;
> +	sdsa_header[2] = 0x00; /* reserved */
> +	sdsa_header[3] = 0x00; /* reserved */
> +	sdsa_header[4] = FIELD_PREP(SDSA_TAG_FRAME_TYPE_MASK, 1) |
> +			 FIELD_PREP(SDSA_TAG_PORT_HI_MASK, dp->index >> 5);
> +	sdsa_header[5] = FIELD_PREP(SDSA_TAG_PORT_MASK, dp->index);
> +	sdsa_header[6] = 0x00; /* VLAN not supported */
> +	sdsa_header[7] = 0x00; /* VLAN not supported */
> +
> +	return skb;
> +}
> +
> +static struct sk_buff *sdsa_rcv(struct sk_buff *skb, struct net_device *dev)
> +{
> +	u8 *sdsa_header;
> +	int source_port;
> +	u8 frame_type;
> +
> +	if (unlikely(!pskb_may_pull(skb, SDSA_HLEN)))
> +		return NULL;
> +
> +	sdsa_header = dsa_etype_header_pos_rx(skb);
> +
> +	/* Check that the frame type is TO_CPU. */
> +	frame_type = FIELD_GET(SDSA_TAG_FRAME_TYPE_MASK, sdsa_header[4]);
> +	if (frame_type != 0)

#define for TO_CPU?

	Andrew

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 4/4] net: dsa: soce: Add initial driver support for MRS switches
  2026-07-29 16:36 ` [PATCH 4/4] net: dsa: soce: Add initial driver support for MRS switches Vasilij Strassheim
@ 2026-07-29 17:31   ` Andrew Lunn
  2026-08-03 15:40     ` Vasilij Strassheim
  2026-07-29 20:05   ` Andrew Lunn
  2026-07-30  9:01   ` Krzysztof Kozlowski
  2 siblings, 1 reply; 44+ messages in thread
From: Andrew Lunn @ 2026-07-29 17:31 UTC (permalink / raw)
  To: Vasilij Strassheim
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vladimir Oltean,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Russell King, devicetree, linux-kernel, netdev,
	Martin Kaistra

> +static int soce_sw_probe(struct mdio_device *mdiodev)
> +{
> +	const struct soce_variant_desc *variant;
> +	struct device *dev = &mdiodev->dev;
> +	struct device_node *switch_node;
> +	struct soce_dsa_local *local;
> +	const char *soce_compatible;
> +	struct soce_priv *priv;
> +	u32 numports;
> +	int ret;
> +
> +	priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL);
> +	if (!priv->ds)
> +		return -ENOMEM;
> +
> +	priv->ds->dev = dev;
> +	priv->ds->priv = priv;
> +	local = &priv->local;
> +
> +	switch_node = of_parse_phandle(dev->of_node, "soce,switch-ip", 0);
> +	if (!switch_node) {
> +		dev_err(dev, "missing or invalid switch IP reference\n");
> +		return -EINVAL;
> +	}
> +
> +	ret = of_property_read_string(switch_node, "compatible",
> +				      &soce_compatible);
> +	if (ret) {
> +		dev_err(dev, "missing compatible property in %pOF\n",
> +			switch_node);
> +		of_node_put(switch_node);
> +		return -EINVAL;
> +	}
> +
> +	variant = soce_match_variant(soce_compatible);
> +	if (!variant) {
> +		dev_err(dev, "unsupported compatible '%s' in %pOF\n",
> +			soce_compatible, switch_node);
> +		of_node_put(switch_node);
> +		return -ENODEV;
> +	}
> +
> +	ret = of_property_read_u32(switch_node, "soce,num-ports", &numports);
> +	if (ret) {
> +		dev_err(dev, "missing soce,num-ports in %pOF\n", switch_node);
> +		of_node_put(switch_node);
> +		return -EINVAL;
> +	}
> +	if (numports == 0 || numports > SOCE_MAX_NUM_PORTS) {
> +		dev_err(dev, "invalid soce,num-ports %u (max %d)\n", numports,
> +			SOCE_MAX_NUM_PORTS);
> +		of_node_put(switch_node);
> +		return -EINVAL;
> +	}
> +
> +	local->base_addr = devm_of_iomap(dev, switch_node, 0, NULL);
> +	if (IS_ERR(local->base_addr)) {
> +		dev_err(dev, "failed to map switch register space for %pOF\n",
> +			switch_node);
> +		of_node_put(switch_node);
> +		return PTR_ERR(local->base_addr);
> +	}
> +
> +	priv->ds->ops = &soce_switch_ops;
> +	local->mdio_ops = variant->mdio_ops;
> +	local->mdio_master_addr =
> +		local->base_addr + variant->mdio_master_offset;
> +	local->layout = variant->layout;
> +	of_node_put(switch_node);
> +
> +	priv->ds->num_ports = numports;
> +	ret = soce_sw_parse_port_mdio(priv, dev, numports);
> +	if (ret)
> +		return ret;
> +
> +	dev_set_drvdata(&mdiodev->dev, priv);
> +
> +	dev_info(dev, "soce %s SDSA driver probed.\n", soce_compatible);
> +
> +	return dsa_register_switch(priv->ds);
> +}

Looking at this struct mdio_device *mdiodev is not used, other than
for ->dev. Is this device actually on an MDIO bus?

	Andrew

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 2/4] dt-bindings: net: dsa: Add SoC-e switch IP and DSA bindings
  2026-07-29 16:36 ` [PATCH 2/4] dt-bindings: net: dsa: Add SoC-e switch IP and DSA bindings Vasilij Strassheim
  2026-07-29 17:11   ` Andrew Lunn
@ 2026-07-29 18:07   ` Rob Herring (Arm)
  2026-08-03 15:47     ` Vasilij Strassheim
  2026-07-30  8:56   ` Krzysztof Kozlowski
  2026-07-30  8:56   ` Krzysztof Kozlowski
  3 siblings, 1 reply; 44+ messages in thread
From: Rob Herring (Arm) @ 2026-07-29 18:07 UTC (permalink / raw)
  To: Vasilij Strassheim
  Cc: Russell King, Paolo Abeni, netdev, Conor Dooley, Vladimir Oltean,
	Simon Horman, David S. Miller, Martin Kaistra, linux-kernel,
	Krzysztof Kozlowski, Andrew Lunn, Eric Dumazet, devicetree,
	Jakub Kicinski


On Wed, 29 Jul 2026 18:36:55 +0200, Vasilij Strassheim wrote:
> Add DT schema documentation for SoC-e FPGA switch devices.
> The binding is split into:
>  - a switch IP node describing the MMIO register block
>  - a DSA MDIO node describing the DSA-facing switch instance
> Both nodes are linked through the soce,switch-ip phandle.
> 
> Signed-off-by: Vasilij Strassheim <v.strassheim@linutronix.de>
> ---
>  .../bindings/net/dsa/soce,switch-dsa.yaml          | 195 +++++++++++++++++++++
>  .../bindings/net/dsa/soce,switch-ip.yaml           |  54 ++++++
>  2 files changed, 249 insertions(+)
> 

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/net/dsa/soce,switch-ip.example.dtb: switch@80020000 (soce,mrs-24-01): reg: [[0, 2147614720], [0, 65536]] is too long
	from schema $id: http://devicetree.org/schemas/net/dsa/soce,switch-ip.yaml

doc reference errors (make refcheckdocs):

See https://patchwork.kernel.org/project/devicetree/patch/20260729-devel-vstrassheim-soce-dsa-ml-v1-2-be569dae1b20@linutronix.de

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 4/4] net: dsa: soce: Add initial driver support for MRS switches
  2026-07-29 16:36 ` [PATCH 4/4] net: dsa: soce: Add initial driver support for MRS switches Vasilij Strassheim
  2026-07-29 17:31   ` Andrew Lunn
@ 2026-07-29 20:05   ` Andrew Lunn
  2026-08-03 16:01     ` Vasilij Strassheim
  2026-07-30  9:01   ` Krzysztof Kozlowski
  2 siblings, 1 reply; 44+ messages in thread
From: Andrew Lunn @ 2026-07-29 20:05 UTC (permalink / raw)
  To: Vasilij Strassheim
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vladimir Oltean,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Russell King, devicetree, linux-kernel, netdev,
	Martin Kaistra

> +static u8 soce_map_stp_state(u8 state)
> +{
> +	switch (state) {
> +	case BR_STATE_DISABLED:
> +	case BR_STATE_BLOCKING:
> +	case BR_STATE_LISTENING:
> +		return 0;
> +	case BR_STATE_LEARNING:
> +		return 1;
> +	case BR_STATE_FORWARDING:
> +	default:
> +		return 3;

#defines for 0, 1 and 3.

What does 2 mean?

Since you don't implement bridge offload, i'm not sure having STP
states makes any sense.

> +static void soce_fast_age(struct dsa_switch *ds, int port,
> +			  const struct soce_layout *layout)
> +{
> +	struct soce_priv *priv = ds->priv;
> +	struct soce_dsa_local *local;
> +	void __iomem *p_mes_ctrl;
> +	u32 val;

Does aging make any sense without bridge offload?

> +/* Bridge membership is handled by the switch forwarding model directly. */
> +int soce_port_bridge_join(struct dsa_switch *ds, int port,
> +			  struct dsa_bridge bridge, bool *tx_fwd_offload,
> +			  struct netlink_ext_ack *extack)
> +{
> +	return 0;
> +}
> +
> +void soce_port_bridge_leave(struct dsa_switch *ds, int port,
> +			    struct dsa_bridge bridge)
> +{
> +}

If you don't support bridge offload, you should not need these.

> +static void soce_phylink_get_caps(struct dsa_switch *ds, int port,
> +				  struct phylink_config *config)
> +{
> +	if (dsa_is_cpu_port(ds, port)) {
> +		__set_bit(PHY_INTERFACE_MODE_GMII,

Is that really true? What is part of the IP core, and what is to do
with integration of the core into the system as a whole? It seems like
RGMII is also supported, so why cannot i instantiate a RGMII MII blob
for the CPU port as well?

> +			  config->supported_interfaces);
> +		config->mac_capabilities = MAC_10 | MAC_100 | MAC_1000 |
> +					   MAC_SYM_PAUSE | MAC_ASYM_PAUSE;
> +		return;
> +	}
> +
> +	phy_interface_set_rgmii(config->supported_interfaces);

And flipping that around, if the core supports GMII, could i
instantiate a GMII user port?

> +static const struct dsa_switch_ops soce_switch_ops = {
> +	.get_tag_protocol	= soce_get_tag_protocol,
> +	.setup			= soce_setup,
> +	.teardown		= soce_teardown,
> +	.phylink_get_caps	= soce_phylink_get_caps,
> +	.phy_read		= soce_phy_read,
> +	.phy_write		= soce_phy_write,

phy_read and phy_write are legacy. Instantiate a Linux MDIO bus and
don't list anything here.

> +static const struct soce_variant_desc *
> +soce_match_variant(const char *compatible)
> +{
> +	int i;
> +
> +	for (i = 0; soce_variants[i].compatible; i++) {
> +		if (!strcmp(compatible, soce_variants[i].compatible))
> +			return &soce_variants[i];
> +	}
> +
> +	return NULL;

This kind of looks like a reinvention of of_device_get_match_data()

> +static int soce_sw_parse_port_mdio_config(struct soce_dsa_local *local,
> +					  struct device *dev,
> +					  struct device_node *port_node,
> +					  u32 port)
> +{
> +	struct device_node *phy_node;
> +	u32 val;
> +	int ret;
> +
> +	if (of_find_property(port_node, "ethernet", NULL) ||
> +	    of_find_property(port_node, "link", NULL)) {
> +		if (of_find_property(port_node, "phy-handle", NULL)) {
> +			dev_err(dev,
> +				"phy-handle not allowed on CPU/DSA port %u\n",
> +				port);
> +			return -EINVAL;
> +		}
> +
> +		return 0;
> +	}

Why is all of this parsing of DT needed? These should all be standard
properties which the DSA core handles.

This currently has the feel of being a "vendor crap" driver. Please
spend some time to clean this driver up, bring it up to Mainline
standards.

	Andrew

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 1/4] dt-bindings: vendor-prefixes: Add soce
  2026-07-29 16:36 ` [PATCH 1/4] dt-bindings: vendor-prefixes: Add soce Vasilij Strassheim
@ 2026-07-30  8:50   ` Krzysztof Kozlowski
  2026-08-03 16:03     ` Vasilij Strassheim
  0 siblings, 1 reply; 44+ messages in thread
From: Krzysztof Kozlowski @ 2026-07-30  8:50 UTC (permalink / raw)
  To: Vasilij Strassheim
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Andrew Lunn,
	Vladimir Oltean, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Russell King, devicetree, linux-kernel,
	netdev, Martin Kaistra

On Wed, Jul 29, 2026 at 06:36:54PM +0200, Vasilij Strassheim wrote:
> Add the soce vendor prefix for System-On-Chip Engineering, S.L.
> 
> This prefix is used by the new SoC-e Ethernet switch DT bindings.

Drop, implied. You explain here things which are not obvious. You can
also look at git history to see how this is done.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 2/4] dt-bindings: net: dsa: Add SoC-e switch IP and DSA bindings
  2026-07-29 16:36 ` [PATCH 2/4] dt-bindings: net: dsa: Add SoC-e switch IP and DSA bindings Vasilij Strassheim
  2026-07-29 17:11   ` Andrew Lunn
  2026-07-29 18:07   ` Rob Herring (Arm)
@ 2026-07-30  8:56   ` Krzysztof Kozlowski
  2026-08-03 16:15     ` Vasilij Strassheim
  2026-07-30  8:56   ` Krzysztof Kozlowski
  3 siblings, 1 reply; 44+ messages in thread
From: Krzysztof Kozlowski @ 2026-07-30  8:56 UTC (permalink / raw)
  To: Vasilij Strassheim
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Andrew Lunn,
	Vladimir Oltean, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Russell King, devicetree, linux-kernel,
	netdev, Martin Kaistra

On Wed, Jul 29, 2026 at 06:36:55PM +0200, Vasilij Strassheim wrote:
> Add DT schema documentation for SoC-e FPGA switch devices.
> The binding is split into:
>  - a switch IP node describing the MMIO register block
>  - a DSA MDIO node describing the DSA-facing switch instance
> Both nodes are linked through the soce,switch-ip phandle.
> 
> Signed-off-by: Vasilij Strassheim <v.strassheim@linutronix.de>
> ---
>  .../bindings/net/dsa/soce,switch-dsa.yaml          | 195 +++++++++++++++++++++
>  .../bindings/net/dsa/soce,switch-ip.yaml           |  54 ++++++
>  2 files changed, 249 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/net/dsa/soce,switch-dsa.yaml b/Documentation/devicetree/bindings/net/dsa/soce,switch-dsa.yaml
> new file mode 100644
> index 000000000000..a04e2838d14e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/dsa/soce,switch-dsa.yaml
> @@ -0,0 +1,195 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/net/dsa/soce,switch-dsa.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: SoC-e DSA switch MDIO device
> +
> +maintainers:
> +  - SoC-e <info@soc-e.com>

Nope, as explained more than once group boxes are not accepted.

> +
> +description: |
> +  This node is the MDIO-bus device entry for the SoC-e DSA switch driver.

Node is not for a driver. Explain the hardware, not drivers, not DTS.


> +  It is a lightweight configuration node that lives on the MDIO bus of the
> +  SoC Ethernet controller acting as the DSA conduit (CPU port).
> +
> +  The switch hardware itself (MMIO register interface) is a separate IP core
> +  described by a companion node with one of the SoC-e compatible strings,
> +  for example:
> +    - soce,mrs-<version>

How is this relevant here? do you describe this compatible?

> +  See the consolidated IP-core binding:
> +    - Documentation/devicetree/bindings/net/dsa/soce,switch-ip.yaml
> +  The two nodes are linked via the "soce,switch-ip" phandle property.
> +
> +  Port sub-nodes follow the DSA port binding documented in dsa-port.yaml.
> +  User ports should reference PHY nodes through "phy-handle". These PHY nodes
> +  live under the optional "mdio" child node of the switch and are exposed on
> +  the switch's synthetic DSA user MDIO bus.
> +
> +  The PHY-specific properties "soce,mdio-output" and "soce,phy-addr" describe
> +  the MDIO bus index and hardware PHY address used by the on-chip MDIO master
> +  of the switch IP core.
> +
> +properties:
> +  '#address-cells':
> +    const: 1
> +
> +  '#size-cells':
> +    const: 0

You need to follow DTS coding style.

> +
> +  compatible:
> +    const: soce,switch-dsa

Way too generic. I understand that SoCe will NEVER - and you certify
that - develop a second, different "switch-dsa" model and they call this
one like this?

> +
> +  reg:
> +    description: MDIO address of this device on the parent MDIO bus.

Drop.

> +    maxItems: 1
> +
> +  soce,switch-ip:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description: |
> +      Phandle to the SoC-e switch IP core node that provides the MMIO register
> +      window for this switch instance. The referenced node must carry a
> +      compatible string documented in
> +      Documentation/devicetree/bindings/net/dsa/soce,switch-ip.yaml.
> +
> +  dsa,member:
> +    $ref: /schemas/types.yaml#/definitions/uint32-array

Why do you need to redefine existing property?

> +    minItems: 2
> +    maxItems: 2
> +    description:
> +      DSA cluster membership; see Documentation/devicetree/bindings/net/dsa/dsa.yaml.

Drop. Do not redefine properties. See other bindings how this is done.

> +
> +  mdio:
> +    $ref: /schemas/net/mdio.yaml#
> +    description: |
> +      Optional child MDIO bus exposing PHY devices attached to switch user
> +      ports. PHY nodes referenced by port "phy-handle" properties should be
> +      placed here. The PHY address seen by Linux on this bus is the switch port
> +      index, not necessarily the hardware PHY address selected internally by
> +      the switch IP.
> +    unevaluatedProperties: false
> +
> +    patternProperties:
> +      "^ethernet-phy@[0-9a-f]+$":

Use consistent quotes.

> +        type: object
> +        $ref: /schemas/net/ethernet-phy.yaml#
> +        unevaluatedProperties: false
> +        description:
> +          PHY attached to a switch user port through the synthetic switch MDIO
> +          bus.
> +        properties:
> +          soce,mdio-output:
> +            $ref: /schemas/types.yaml#/definitions/uint32
> +            description: |
> +              Zero-based index of the MDIO bus output of the switch IP core to
> +              which this PHY is connected.
> +
> +          soce,phy-addr:
> +            $ref: /schemas/types.yaml#/definitions/uint32
> +            description: |
> +              Hardware PHY address on the MDIO bus selected by
> +              "soce,mdio-output".
> +
> +        required:
> +          - soce,mdio-output
> +          - soce,phy-addr
> +
> +  ports:
> +    type: object
> +    description: Container node for the switch port sub-nodes.
> +    properties:
> +      '#address-cells':
> +        const: 1
> +      '#size-cells':
> +        const: 0
> +
> +    patternProperties:
> +      "^port@[0-9a-f]+$":
> +        $ref: dsa-port.yaml#
> +        unevaluatedProperties: false
> +        description: |
> +          Switch port. In addition to the standard DSA port properties
> +          (label, phy-mode, ethernet, fixed-link) the following
> +          vendor-specific properties are used for data ports connected to
> +          external PHYs.
> +
> +    required:
> +      - '#address-cells'
> +      - '#size-cells'
> +
> +    additionalProperties: false
> +
> +required:
> +  - compatible
> +  - reg
> +  - soce,switch-ip
> +  - ports
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    /* Excerpt from a Xilinx ZynqMP design (ARM64) */
> +    mdio {
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        soce_switch: switch@10 {
> +            #address-cells = <1>;
> +            #size-cells = <0>;
> +            compatible = "soce,switch-dsa";
> +            reg = <0x10>;
> +            soce,switch-ip = <&soce_switch_ip>;
> +            dsa,member = <0 0>;
> +
> +            ports {
> +                #address-cells = <1>;
> +                #size-cells = <0>;
> +
> +                port@0 {
> +                    reg = <0x0>;
> +                    label = "PORT_0";
> +                    phy-handle = <&switchphy0>;
> +                    phy-mode = "rgmii-id";
> +                };
> +
> +                port@1 {
> +                    reg = <0x1>;
> +                    label = "PORT_1";
> +                    phy-handle = <&switchphy1>;
> +                    phy-mode = "rgmii-id";
> +                };
> +
> +                port@2 {
> +                    reg = <0x2>;
> +                    label = "INTERNAL_PORT";
> +                    ethernet = <&gem3>;
> +                    phy-mode = "gmii";
> +                    fixed-link {
> +                        speed = <1000>;
> +                        full-duplex;
> +                    };
> +                };
> +            };
> +
> +            mdio {
> +              #address-cells = <1>;
> +              #size-cells = <0>;
> +
> +                switchphy0: ethernet-phy@0 {
> +                    compatible = "ethernet-phy-ieee802.3-c22";
> +                    reg = <0x0>;
> +                    soce,mdio-output = <0x00000000>;
> +                    soce,phy-addr = <1>;
> +                };
> +
> +                switchphy1: ethernet-phy@1 {
> +                    compatible = "ethernet-phy-ieee802.3-c22";
> +                    reg = <0x1>;
> +                    soce,mdio-output = <0x00000001>;
> +                    soce,phy-addr = <1>;
> +                };
> +            };
> +        };
> +    };
> diff --git a/Documentation/devicetree/bindings/net/dsa/soce,switch-ip.yaml b/Documentation/devicetree/bindings/net/dsa/soce,switch-ip.yaml
> new file mode 100644
> index 000000000000..ba9bb396235f
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/dsa/soce,switch-ip.yaml

Filename must match compatible.

> @@ -0,0 +1,54 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/net/dsa/soce,switch-ip.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: SoC-e Ethernet Switch IP core
> +
> +maintainers:
> +  - SoC-e <info@soc-e.com>
> +
> +description: |
> +  SoC-e Ethernet switch IP cores are configurable FPGA switch fabrics with
> +  Layer-2 bridging features (including STP/MSTP state control and FDB
> +  fast-age support). Some variants also provide TSN functionality.
> +
> +  This binding describes only the MMIO switch IP core node. The Linux DSA
> +  driver is bound via a companion MDIO node described in:
> +    Documentation/devicetree/bindings/net/dsa/soce,switch-dsa.yaml.
> +
> +properties:
> +  compatible:
> +    enum:
> +      - soce,mrs-21-01
> +      - soce,mrs-23-02
> +      - soce,mrs-24-01
> +
> +  reg:
> +    description: |
> +      MMIO base address and size of the switch register window.
> +      On 64-bit platforms (ARM64), this is typically encoded as two-cell
> +      address and two-cell size values.

Pointless. Please open any other existing binding.

> +    maxItems: 1
> +
> +  soce,num-ports:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description: |
> +      Total number of switch ports (external/user ports plus the CPU uplink
> +      port). Must be greater than zero and not exceed the selected IP variant.

Either implied by compatible or not properly placed. Looks like propertt
of the DSA.

> +
> +required:
> +  - compatible
> +  - reg
> +  - soce,num-ports
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    switch_ip: switch@80020000 {

ethernet-switch

And drop unused label.

Considering this wasn't tested I should not even give here review...

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 2/4] dt-bindings: net: dsa: Add SoC-e switch IP and DSA bindings
  2026-07-29 16:36 ` [PATCH 2/4] dt-bindings: net: dsa: Add SoC-e switch IP and DSA bindings Vasilij Strassheim
                     ` (2 preceding siblings ...)
  2026-07-30  8:56   ` Krzysztof Kozlowski
@ 2026-07-30  8:56   ` Krzysztof Kozlowski
  2026-08-03 16:16     ` Vasilij Strassheim
  3 siblings, 1 reply; 44+ messages in thread
From: Krzysztof Kozlowski @ 2026-07-30  8:56 UTC (permalink / raw)
  To: Vasilij Strassheim
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Andrew Lunn,
	Vladimir Oltean, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Russell King, devicetree, linux-kernel,
	netdev, Martin Kaistra

On Wed, Jul 29, 2026 at 06:36:55PM +0200, Vasilij Strassheim wrote:
> Add DT schema documentation for SoC-e FPGA switch devices.
> The binding is split into:
>  - a switch IP node describing the MMIO register block
>  - a DSA MDIO node describing the DSA-facing switch instance
> Both nodes are linked through the soce,switch-ip phandle.

A nit, subject: drop second/last, redundant "bindings". The
"dt-bindings" prefix is already stating that these are bindings.
See also:
https://elixir.bootlin.com/linux/v7.1-rc7/source/Documentation/devicetree/bindings/submitting-patches.rst#L23

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 4/4] net: dsa: soce: Add initial driver support for MRS switches
  2026-07-29 16:36 ` [PATCH 4/4] net: dsa: soce: Add initial driver support for MRS switches Vasilij Strassheim
  2026-07-29 17:31   ` Andrew Lunn
  2026-07-29 20:05   ` Andrew Lunn
@ 2026-07-30  9:01   ` Krzysztof Kozlowski
  2026-08-03 16:23     ` Vasilij Strassheim
  2 siblings, 1 reply; 44+ messages in thread
From: Krzysztof Kozlowski @ 2026-07-30  9:01 UTC (permalink / raw)
  To: Vasilij Strassheim
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Andrew Lunn,
	Vladimir Oltean, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Russell King, devicetree, linux-kernel,
	netdev, Martin Kaistra

On Wed, Jul 29, 2026 at 06:36:57PM +0200, Vasilij Strassheim wrote:
> +static const struct soce_variant_desc soce_variants[] = {
> +	{
> +		.compatible		= "soce,mrs-21-01",
> +		.mdio_master_offset	= SOCE_MRS_21_01_MDIO_MASTER_OFFSET,
> +		.layout			= &soce_mrs_21_01_layout,
> +		.mdio_ops		= &soce_mdio_ops_20_03,
> +	},
> +	{
> +		.compatible		= "soce,mrs-23-02",
> +		.mdio_master_offset	= SOCE_MRS_21_01_MDIO_MASTER_OFFSET,
> +		.layout			= &soce_mrs_24_01_layout,
> +		.mdio_ops		= &soce_mdio_ops_c22_c45,
> +	},
> +	{
> +		.compatible		= "soce,mrs-24-01",
> +		.mdio_master_offset	= SOCE_MRS_21_01_MDIO_MASTER_OFFSET,
> +		.layout			= &soce_mrs_24_01_layout,
> +		.mdio_ops		= &soce_mdio_ops_c22_c45,
> +	},
> +	{ /* sentinel */ },
> +};
> +
> +static const struct soce_variant_desc *
> +soce_match_variant(const char *compatible)
> +{
> +	int i;
> +
> +	for (i = 0; soce_variants[i].compatible; i++) {
> +		if (!strcmp(compatible, soce_variants[i].compatible))
> +			return &soce_variants[i];

Do not re-invent OF matching. This is supposed to be of_device_id table.

> +	}
> +
> +	return NULL;
> +}
> +
> +static int soce_sw_parse_port_mdio_config(struct soce_dsa_local *local,
> +					  struct device *dev,
> +					  struct device_node *port_node,
> +					  u32 port)
> +{
> +	struct device_node *phy_node;
> +	u32 val;
> +	int ret;
> +
> +	if (of_find_property(port_node, "ethernet", NULL) ||
> +	    of_find_property(port_node, "link", NULL)) {
> +		if (of_find_property(port_node, "phy-handle", NULL)) {
> +			dev_err(dev,
> +				"phy-handle not allowed on CPU/DSA port %u\n",
> +				port);
> +			return -EINVAL;
> +		}
> +
> +		return 0;
> +	}
> +
> +	phy_node = of_parse_phandle(port_node, "phy-handle", 0);
> +	if (!phy_node) {
> +		if (of_phy_is_fixed_link(port_node))
> +			return 0;
> +
> +		dev_err(dev, "user port %u requires phy-handle or fixed-link\n",
> +			port);
> +		return -EINVAL;
> +	}
> +
> +	ret = of_property_read_u32(phy_node, "soce,mdio-output", &val);
> +	if (ret) {
> +		dev_err(dev,
> +			"missing soce,mdio-output in %pOF referenced by port %u\n",
> +			phy_node, port);
> +		goto out_put_phy;
> +	}
> +	local->mdio_info[port].mdio_output = val;
> +
> +	ret = of_property_read_u32(phy_node, "soce,phy-addr", &val);
> +	if (ret) {
> +		dev_err(dev,
> +			"missing soce,phy-addr in %pOF referenced by port %u\n",
> +			phy_node, port);
> +		goto out_put_phy;
> +	}
> +	local->mdio_info[port].phy_addr = val;
> +
> +out_put_phy:
> +	of_node_put(phy_node);
> +	return ret;
> +}
> +
> +static int soce_sw_parse_port_mdio(struct soce_priv *priv, struct device *dev,
> +				   u32 numports)
> +{
> +	struct soce_dsa_local *local = &priv->local;
> +	struct device_node *ports_node;
> +	struct device_node *port_node;
> +	u32 port;
> +	int ret;
> +
> +	ports_node = of_get_child_by_name(dev->of_node, "ports");
> +	if (!ports_node) {
> +		dev_err(dev, "missing ports node\n");
> +		return -EINVAL;
> +	}
> +
> +	for_each_available_child_of_node(ports_node, port_node) {

Why not scoped?

> +		if (of_property_read_u32(port_node, "reg", &port))
> +			continue;
> +
> +		if (port >= numports || port >= SOCE_MAX_NUM_PORTS) {
> +			dev_warn(dev,
> +				 "ignoring invalid port index %u in %pOF\n",
> +				 port, port_node);
> +			continue;
> +		}
> +
> +		ret = soce_sw_parse_port_mdio_config(local, dev, port_node,
> +						     port);
> +		if (ret) {
> +			of_node_put(port_node);
> +			of_node_put(ports_node);
> +			return ret;
> +		}
> +	}
> +
> +	of_node_put(ports_node);
> +	return 0;
> +}
> +
> +static int soce_sw_probe(struct mdio_device *mdiodev)
> +{
> +	const struct soce_variant_desc *variant;
> +	struct device *dev = &mdiodev->dev;
> +	struct device_node *switch_node;
> +	struct soce_dsa_local *local;
> +	const char *soce_compatible;
> +	struct soce_priv *priv;
> +	u32 numports;
> +	int ret;
> +
> +	priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL);
> +	if (!priv->ds)
> +		return -ENOMEM;
> +
> +	priv->ds->dev = dev;
> +	priv->ds->priv = priv;
> +	local = &priv->local;
> +
> +	switch_node = of_parse_phandle(dev->of_node, "soce,switch-ip", 0);
> +	if (!switch_node) {
> +		dev_err(dev, "missing or invalid switch IP reference\n");
> +		return -EINVAL;
> +	}
> +
> +	ret = of_property_read_string(switch_node, "compatible",
> +				      &soce_compatible);
> +	if (ret) {
> +		dev_err(dev, "missing compatible property in %pOF\n",
> +			switch_node);
> +		of_node_put(switch_node);
> +		return -EINVAL;
> +	}
> +
> +	variant = soce_match_variant(soce_compatible);
> +	if (!variant) {
> +		dev_err(dev, "unsupported compatible '%s' in %pOF\n",
> +			soce_compatible, switch_node);
> +		of_node_put(switch_node);

Use proper error handling exit paths with goto.

> +		return -ENODEV;
> +	}
> +
> +	ret = of_property_read_u32(switch_node, "soce,num-ports", &numports);
> +	if (ret) {
> +		dev_err(dev, "missing soce,num-ports in %pOF\n", switch_node);
> +		of_node_put(switch_node);
> +		return -EINVAL;
> +	}
> +	if (numports == 0 || numports > SOCE_MAX_NUM_PORTS) {
> +		dev_err(dev, "invalid soce,num-ports %u (max %d)\n", numports,
> +			SOCE_MAX_NUM_PORTS);
> +		of_node_put(switch_node);
> +		return -EINVAL;
> +	}
> +
> +	local->base_addr = devm_of_iomap(dev, switch_node, 0, NULL);
> +	if (IS_ERR(local->base_addr)) {
> +		dev_err(dev, "failed to map switch register space for %pOF\n",
> +			switch_node);
> +		of_node_put(switch_node);
> +		return PTR_ERR(local->base_addr);
> +	}
> +
> +	priv->ds->ops = &soce_switch_ops;
> +	local->mdio_ops = variant->mdio_ops;
> +	local->mdio_master_addr =
> +		local->base_addr + variant->mdio_master_offset;
> +	local->layout = variant->layout;
> +	of_node_put(switch_node);
> +
> +	priv->ds->num_ports = numports;
> +	ret = soce_sw_parse_port_mdio(priv, dev, numports);
> +	if (ret)
> +		return ret;
> +
> +	dev_set_drvdata(&mdiodev->dev, priv);
> +
> +	dev_info(dev, "soce %s SDSA driver probed.\n", soce_compatible);

Drop, driver should be silent on success.

> +
> +	return dsa_register_switch(priv->ds);
> +}
> +
> +static void soce_sw_remove(struct mdio_device *mdiodev)
> +{
> +	struct soce_priv *priv = dev_get_drvdata(&mdiodev->dev);
> +
> +	dsa_unregister_switch(priv->ds);
> +}
> +
> +static const struct of_device_id soce_of_match[] = {
> +	{ .compatible = "soce,switch-dsa" },
> +	{ /* sentinel */ },
> +};
> +
> +static struct mdio_driver soce_mdio_driver = {
> +	.mdiodrv.driver = {
> +		.name = "soce-switch-dsa",
> +		.of_match_table = soce_of_match,
> +	},
> +	.probe  = soce_sw_probe,
> +	.remove = soce_sw_remove,
> +};

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 0/4] net: dsa: Add SoC-e DSA driver
  2026-07-29 16:56 ` [PATCH 0/4] net: dsa: Add SoC-e DSA driver Andrew Lunn
@ 2026-08-03 15:22   ` Vasilij Strassheim
  2026-08-03 16:32     ` Andrew Lunn
  0 siblings, 1 reply; 44+ messages in thread
From: Vasilij Strassheim @ 2026-08-03 15:22 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vladimir Oltean,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Russell King, devicetree, linux-kernel, netdev,
	Martin Kaistra

On Wed, 2026-07-29 at 18:56 +0200, Andrew Lunn wrote:
> On Wed, Jul 29, 2026 at 06:36:53PM +0200, Vasilij Strassheim wrote:
> > Add initial support for the DSA driver for SoC-e FPGA-based (IP core)
> > Ethernet switches.
> 
> Let me start with a dumb question. Is this a true soft core switch,
> which is synthesised and running in the FPGA? Or is it hardware at the
> edge of the FPGA SoC?

I should have made that clearer right away. This is a true soft-core
switch that is synthesized and runs in AMD FPGAs.
I have a version in which both the MAC and the switch are synthesized
in FPGA, and two hardware PHYs are connected to the switch. The switch
provides an MDIO bus for the PHYs.

> 
> If it is synthesised, do we have to deal with different synthesis
> options? Are there registers which indicate what these options are?

While setting up the switch, users will need to explore various
synthesis options. Once it's up and running, it should be possible to
load a preconfigured bitstream into the FPGA without having to deal with
these options in the DSA driver. The device Tree should then match the
configuration.
However, users are provided with instructions and a user-space
library/software from SoC-e to check and adjust the options if necessary. 
DSA tagging, for example, is one of the synthesis options. If this option
is not active, the DSA driver will not work.

> Where as if it is fixed hardware in the SoC we don't need to worry so
> much about variations, it is fixed at the SoC level.
> 
> > There are different variants of the SoC-e switch IP, which can be
> > additionally configured at runtime with proprietary userspace software.
> 
> What sort of configuration?

Different kinds e.g. general interface configuration, traffic
management, redundancy, ...
Most of them are listed on the product page:
https://soc-e.com/products/10m-100m-1g-managed-redundant-switch-mrs/

DSA integration can stay as lean as possible to support only basic
functionality for different variants and versions of the switch.

> 
>      Andrew

Thanks,
Vasilij


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 2/4] dt-bindings: net: dsa: Add SoC-e switch IP and DSA bindings
  2026-07-29 17:11   ` Andrew Lunn
@ 2026-08-03 15:29     ` Vasilij Strassheim
  2026-08-03 16:35       ` Andrew Lunn
  0 siblings, 1 reply; 44+ messages in thread
From: Vasilij Strassheim @ 2026-08-03 15:29 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vladimir Oltean,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Russell King, devicetree, linux-kernel, netdev,
	Martin Kaistra

On Wed, 2026-07-29 at 19:11 +0200, Andrew Lunn wrote:
> > +description: |
> > +  This node is the MDIO-bus device entry for the SoC-e DSA switch driver.
> > +  It is a lightweight configuration node that lives on the MDIO bus of the
> > +  SoC Ethernet controller acting as the DSA conduit (CPU port).
> 
> Must it be the conduit interfaces MDIO bus? There are boards which
> exist using Marvell switches where the MDIO bus of the conduit
> interface is not a Linux MDIO bus, because it is an intel i210, and
> intel likes reinventing the wheel and does not use the Linux MDIO bus
> infrastructure. So the MDIO interface of the switch is connected to
> two GPIOs and a Linux bit bashing MDIO bus is used.
> 
There are synthesis options for various management interfaces. MDIO and
MMIO are two of them. I only have one variant for the memory-mapped
version. For v2, I'll discard everything else and update the
documentation accordingly.

> > +  soce,num-ports:
> > +    $ref: /schemas/types.yaml#/definitions/uint32
> > +    description: |
> > +      Total number of switch ports (external/user ports plus the CPU uplink
> > +      port). Must be greater than zero and not exceed the selected IP variant.
> 
> Why is this needed if we already have a description of the ports?

Not needed, I will change it in the next version.

> 
>     Andrew

Thanks,
Vasilij

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 3/4] net: dsa: Add support for SoC-e SDSA tags
  2026-07-29 17:22   ` Andrew Lunn
@ 2026-08-03 15:37     ` Vasilij Strassheim
  2026-08-03 16:46       ` Andrew Lunn
  0 siblings, 1 reply; 44+ messages in thread
From: Vasilij Strassheim @ 2026-08-03 15:37 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vladimir Oltean,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Russell King, devicetree, linux-kernel, netdev,
	Martin Kaistra

On Wed, 2026-07-29 at 19:22 +0200, Andrew Lunn wrote:
> > @@ -98,6 +98,12 @@ config NET_DSA_TAG_EDSA
> >  	  Say Y or M if you want to enable support for tagging frames for the
> >  	  Marvell switches which use EtherType DSA headers.
> >  
> > +config NET_DSA_TAG_SDSA
> > +	tristate "Tag driver for SoC-e switches using EtherType SDSA headers"
> > +	help
> > +	  Say Y or M if you want to enable support for tagging frames for the
> > +	  SoC-e switches.
> > +
> 
> These entries are sorted, so it probably should be between
> NET_DSA_TAG_RZN1_A5PSW and NET_DSA_TAG_LAN9303.

I will insert it as suggested. To better understand, what is the sort order?
To me, it seems like there's also a good spot between
NET_DSA_TAG_LAN9303 and NET_DSA_TAG_SJA1105.

> 
> > @@ -23,6 +23,7 @@ dsa_core-y += \
> >  obj-$(CONFIG_NET_DSA_TAG_AR9331) += tag_ar9331.o
> >  obj-$(CONFIG_NET_DSA_TAG_BRCM_COMMON) += tag_brcm.o
> >  obj-$(CONFIG_NET_DSA_TAG_DSA_COMMON) += tag_dsa.o
> > +obj-$(CONFIG_NET_DSA_TAG_SDSA) += tag_sdsa.o
> >  obj-$(CONFIG_NET_DSA_TAG_GSWIP) += tag_gswip.o
> 
> Also sorted, and this is the wrong spot.

Oh yes, I'll place it between tag_rzn1_a5psw and tag_sja1105.

> 
> > +#define SDSA_HLEN	8
> > +
> > +#define SDSA_NAME	"sdsa"
> 
> Does SDSA mean anything? Or have you taken net/dsa/tag_dsa.c, and just
> changed edsa to sdsa?

The "S" stands for Soc-e. I don't have any preferences and just took it
from the original code.

> 
> > +static struct sk_buff *sdsa_xmit(struct sk_buff *skb, struct net_device *dev)
> > +{
> > +	struct dsa_port *dp = dsa_user_to_port(dev);
> > +	u8 *sdsa_header;
> > +
> > +	if (skb_cow_head(skb, SDSA_HLEN) < 0)
> > +		return NULL;
> > +
> > +	skb_push(skb, SDSA_HLEN);
> > +	dsa_alloc_etype_header(skb, SDSA_HLEN);
> > +
> > +	/* Construct the FROM_CPU DSA tag. */
> 
> Is FROM_CPU a concept for this device? Are there other types of tag?

Yes, the documentation describes two types of tagging headers for frames from
the switch to the CPU and from the CPU to the switch. The tags differ in some
bits.

> 
> > +	sdsa_header = dsa_etype_header_pos_tx(skb);
> > +	sdsa_header[0] = (ETH_P_SDSA >> 8) & 0xff;
> > +	sdsa_header[1] = ETH_P_SDSA & 0xff;
> > +	sdsa_header[2] = 0x00; /* reserved */
> > +	sdsa_header[3] = 0x00; /* reserved */
> > +	sdsa_header[4] = FIELD_PREP(SDSA_TAG_FRAME_TYPE_MASK, 1) |
> > +			 FIELD_PREP(SDSA_TAG_PORT_HI_MASK, dp->index >> 5);
> > +	sdsa_header[5] = FIELD_PREP(SDSA_TAG_PORT_MASK, dp->index);
> > +	sdsa_header[6] = 0x00; /* VLAN not supported */
> > +	sdsa_header[7] = 0x00; /* VLAN not supported */
> > +
> > +	return skb;
> > +}
> > +
> > +static struct sk_buff *sdsa_rcv(struct sk_buff *skb, struct net_device *dev)
> > +{
> > +	u8 *sdsa_header;
> > +	int source_port;
> > +	u8 frame_type;
> > +
> > +	if (unlikely(!pskb_may_pull(skb, SDSA_HLEN)))
> > +		return NULL;
> > +
> > +	sdsa_header = dsa_etype_header_pos_rx(skb);
> > +
> > +	/* Check that the frame type is TO_CPU. */
> > +	frame_type = FIELD_GET(SDSA_TAG_FRAME_TYPE_MASK, sdsa_header[4]);
> > +	if (frame_type != 0)
> 
> #define for TO_CPU?

I will add definitions for both TO_CPU and FROM_CPU.

> 
> 	Andrew

Thanks,
Vasilij


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 4/4] net: dsa: soce: Add initial driver support for MRS switches
  2026-07-29 17:31   ` Andrew Lunn
@ 2026-08-03 15:40     ` Vasilij Strassheim
  0 siblings, 0 replies; 44+ messages in thread
From: Vasilij Strassheim @ 2026-08-03 15:40 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vladimir Oltean,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Russell King, devicetree, linux-kernel, netdev,
	Martin Kaistra

On Wed, 2026-07-29 at 19:31 +0200, Andrew Lunn wrote:
> > +static int soce_sw_probe(struct mdio_device *mdiodev)
> > +{
> > +	const struct soce_variant_desc *variant;
> > +	struct device *dev = &mdiodev->dev;
> > +	struct device_node *switch_node;
> > +	struct soce_dsa_local *local;
> > +	const char *soce_compatible;
> > +	struct soce_priv *priv;
> > +	u32 numports;
> > +	int ret;
> > +
> > +	priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
> > +	if (!priv)
> > +		return -ENOMEM;
> > +
> > +	priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL);
> > +	if (!priv->ds)
> > +		return -ENOMEM;
> > +
> > +	priv->ds->dev = dev;
> > +	priv->ds->priv = priv;
> > +	local = &priv->local;
> > +
> > +	switch_node = of_parse_phandle(dev->of_node, "soce,switch-ip", 0);
> > +	if (!switch_node) {
> > +		dev_err(dev, "missing or invalid switch IP reference\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	ret = of_property_read_string(switch_node, "compatible",
> > +				      &soce_compatible);
> > +	if (ret) {
> > +		dev_err(dev, "missing compatible property in %pOF\n",
> > +			switch_node);
> > +		of_node_put(switch_node);
> > +		return -EINVAL;
> > +	}
> > +
> > +	variant = soce_match_variant(soce_compatible);
> > +	if (!variant) {
> > +		dev_err(dev, "unsupported compatible '%s' in %pOF\n",
> > +			soce_compatible, switch_node);
> > +		of_node_put(switch_node);
> > +		return -ENODEV;
> > +	}
> > +
> > +	ret = of_property_read_u32(switch_node, "soce,num-ports", &numports);
> > +	if (ret) {
> > +		dev_err(dev, "missing soce,num-ports in %pOF\n", switch_node);
> > +		of_node_put(switch_node);
> > +		return -EINVAL;
> > +	}
> > +	if (numports == 0 || numports > SOCE_MAX_NUM_PORTS) {
> > +		dev_err(dev, "invalid soce,num-ports %u (max %d)\n", numports,
> > +			SOCE_MAX_NUM_PORTS);
> > +		of_node_put(switch_node);
> > +		return -EINVAL;
> > +	}
> > +
> > +	local->base_addr = devm_of_iomap(dev, switch_node, 0, NULL);
> > +	if (IS_ERR(local->base_addr)) {
> > +		dev_err(dev, "failed to map switch register space for %pOF\n",
> > +			switch_node);
> > +		of_node_put(switch_node);
> > +		return PTR_ERR(local->base_addr);
> > +	}
> > +
> > +	priv->ds->ops = &soce_switch_ops;
> > +	local->mdio_ops = variant->mdio_ops;
> > +	local->mdio_master_addr =
> > +		local->base_addr + variant->mdio_master_offset;
> > +	local->layout = variant->layout;
> > +	of_node_put(switch_node);
> > +
> > +	priv->ds->num_ports = numports;
> > +	ret = soce_sw_parse_port_mdio(priv, dev, numports);
> > +	if (ret)
> > +		return ret;
> > +
> > +	dev_set_drvdata(&mdiodev->dev, priv);
> > +
> > +	dev_info(dev, "soce %s SDSA driver probed.\n", soce_compatible);
> > +
> > +	return dsa_register_switch(priv->ds);
> > +}
> 
> Looking at this struct mdio_device *mdiodev is not used, other than
> for ->dev. Is this device actually on an MDIO bus?

I only have a memory-mapped version to test. I will remove this *mdiodev in
the next version.

> 
> 	Andrew

Thanks,
Vasilij


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 2/4] dt-bindings: net: dsa: Add SoC-e switch IP and DSA bindings
  2026-07-29 18:07   ` Rob Herring (Arm)
@ 2026-08-03 15:47     ` Vasilij Strassheim
  0 siblings, 0 replies; 44+ messages in thread
From: Vasilij Strassheim @ 2026-08-03 15:47 UTC (permalink / raw)
  To: Rob Herring (Arm)
  Cc: Russell King, Paolo Abeni, netdev, Conor Dooley, Vladimir Oltean,
	Simon Horman, David S. Miller, Martin Kaistra, linux-kernel,
	Krzysztof Kozlowski, Andrew Lunn, Eric Dumazet, devicetree,
	Jakub Kicinski

On Wed, 2026-07-29 at 13:07 -0500, Rob Herring (Arm) wrote:
> On Wed, 29 Jul 2026 18:36:55 +0200, Vasilij Strassheim wrote:
> > Add DT schema documentation for SoC-e FPGA switch devices.
> > The binding is split into:
> >  - a switch IP node describing the MMIO register block
> >  - a DSA MDIO node describing the DSA-facing switch instance
> > Both nodes are linked through the soce,switch-ip phandle.
> > 
> > Signed-off-by: Vasilij Strassheim <v.strassheim@linutronix.de>
> > ---
> >  .../bindings/net/dsa/soce,switch-dsa.yaml          | 195 +++++++++++++++++++++
> >  .../bindings/net/dsa/soce,switch-ip.yaml           |  54 ++++++
> >  2 files changed, 249 insertions(+)
> > 
> 
> My bot found errors running 'make dt_binding_check' on your patch:
> 
> yamllint warnings/errors:
> 
> dtschema/dtc warnings/errors:
> Documentation/devicetree/bindings/net/dsa/soce,switch-ip.example.dtb: switch@80020000 (soce,mrs-24-01): reg: [[0, 2147614720], [0, 65536]] is too long
> 	from schema $id: http://devicetree.org/schemas/net/dsa/soce,switch-ip.yaml
> 
> doc reference errors (make refcheckdocs):
> 
> See https://patchwork.kernel.org/project/devicetree/patch/20260729-devel-vstrassheim-soce-dsa-ml-v1-2-be569dae1b20@linutronix.de
> 
I can reproduce that and will fix it. I have to make a lot changes there
before re-submitting.

> The base for the series is generally the latest rc1. A different dependency
> should be noted in *this* patch.

Got ot, I'll rebase the next version to net-next and add the information in
this patch.

> 
> If you already ran 'make dt_binding_check' and didn't see the above
> error(s), then make sure 'yamllint' is installed and dt-schema is up to
> date:
> 
> pip3 install dtschema --upgrade
> 
> Please check and re-submit after running the above command yourself. Note
> that DT_SCHEMA_FILES can be set to your schema file to speed up checking
> your schema. However, it must be unset to test all examples with your schema.
> 

Thanks for the tips! I will clean up and test it.

Vasilij


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 4/4] net: dsa: soce: Add initial driver support for MRS switches
  2026-07-29 20:05   ` Andrew Lunn
@ 2026-08-03 16:01     ` Vasilij Strassheim
  2026-08-03 16:49       ` Andrew Lunn
  0 siblings, 1 reply; 44+ messages in thread
From: Vasilij Strassheim @ 2026-08-03 16:01 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vladimir Oltean,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Russell King, devicetree, linux-kernel, netdev,
	Martin Kaistra

On Wed, 2026-07-29 at 22:05 +0200, Andrew Lunn wrote:
> > +static u8 soce_map_stp_state(u8 state)
> > +{
> > +	switch (state) {
> > +	case BR_STATE_DISABLED:
> > +	case BR_STATE_BLOCKING:
> > +	case BR_STATE_LISTENING:
> > +		return 0;
> > +	case BR_STATE_LEARNING:
> > +		return 1;
> > +	case BR_STATE_FORWARDING:
> > +	default:
> > +		return 3;
> 
> #defines for 0, 1 and 3.
> 
> What does 2 mean?
> 
> Since you don't implement bridge offload, i'm not sure having STP
> states makes any sense.

I tested bridge and STP and observed the callback calls with something like
this (reduced setup):
# ip link add name br0 type bridge
# ip link set dev port0 master br0
# ip link set dev port1 master br0
# brctl stp br0 on

That probably wasn't enough. I'll take a closer look at it and either fix it
or remove it for the next version.

> 
> > +static void soce_fast_age(struct dsa_switch *ds, int port,
> > +			  const struct soce_layout *layout)
> > +{
> > +	struct soce_priv *priv = ds->priv;
> > +	struct soce_dsa_local *local;
> > +	void __iomem *p_mes_ctrl;
> > +	u32 val;
> 
> Does aging make any sense without bridge offload?

Same as above. I'll take a closer look at it and either fix it or remove it
for the next version.

> 
> > +/* Bridge membership is handled by the switch forwarding model directly. */
> > +int soce_port_bridge_join(struct dsa_switch *ds, int port,
> > +			  struct dsa_bridge bridge, bool *tx_fwd_offload,
> > +			  struct netlink_ext_ack *extack)
> > +{
> > +	return 0;
> > +}
> > +
> > +void soce_port_bridge_leave(struct dsa_switch *ds, int port,
> > +			    struct dsa_bridge bridge)
> > +{
> > +}
> 
> If you don't support bridge offload, you should not need these.

Also here. I'll take a closer look at it and either fix it or remove it for
the next version.

> 
> > +static void soce_phylink_get_caps(struct dsa_switch *ds, int port,
> > +				  struct phylink_config *config)
> > +{
> > +	if (dsa_is_cpu_port(ds, port)) {
> > +		__set_bit(PHY_INTERFACE_MODE_GMII,
> 
> Is that really true? What is part of the IP core, and what is to do
> with integration of the core into the system as a whole? It seems like
> RGMII is also supported, so why cannot i instantiate a RGMII MII blob
> for the CPU port as well?

No it's wrong, I will adjust that.

> 
> > +			  config->supported_interfaces);
> > +		config->mac_capabilities = MAC_10 | MAC_100 | MAC_1000 |
> > +					   MAC_SYM_PAUSE | MAC_ASYM_PAUSE;
> > +		return;
> > +	}
> > +
> > +	phy_interface_set_rgmii(config->supported_interfaces);
> 
> And flipping that around, if the core supports GMII, could i
> instantiate a GMII user port?

Will also be fixed in the next version.

> 
> > +static const struct dsa_switch_ops soce_switch_ops = {
> > +	.get_tag_protocol	= soce_get_tag_protocol,
> > +	.setup			= soce_setup,
> > +	.teardown		= soce_teardown,
> > +	.phylink_get_caps	= soce_phylink_get_caps,
> > +	.phy_read		= soce_phy_read,
> > +	.phy_write		= soce_phy_write,
> 
> phy_read and phy_write are legacy. Instantiate a Linux MDIO bus and
> don't list anything here.

I will do it.

> 
> > +static const struct soce_variant_desc *
> > +soce_match_variant(const char *compatible)
> > +{
> > +	int i;
> > +
> > +	for (i = 0; soce_variants[i].compatible; i++) {
> > +		if (!strcmp(compatible, soce_variants[i].compatible))
> > +			return &soce_variants[i];
> > +	}
> > +
> > +	return NULL;
> 
> This kind of looks like a reinvention of of_device_get_match_data()

I will update this in the next version.

> 
> > +static int soce_sw_parse_port_mdio_config(struct soce_dsa_local *local,
> > +					  struct device *dev,
> > +					  struct device_node *port_node,
> > +					  u32 port)
> > +{
> > +	struct device_node *phy_node;
> > +	u32 val;
> > +	int ret;
> > +
> > +	if (of_find_property(port_node, "ethernet", NULL) ||
> > +	    of_find_property(port_node, "link", NULL)) {
> > +		if (of_find_property(port_node, "phy-handle", NULL)) {
> > +			dev_err(dev,
> > +				"phy-handle not allowed on CPU/DSA port %u\n",
> > +				port);
> > +			return -EINVAL;
> > +		}
> > +
> > +		return 0;
> > +	}
> 
> Why is all of this parsing of DT needed? These should all be standard
> properties which the DSA core handles.

I will make greater adjustments to the driver here and in other places for
the next version.

> 
> This currently has the feel of being a "vendor crap" driver. Please
> spend some time to clean this driver up, bring it up to Mainline
> standards.

This is actually already the cleaner version.
Thank you for the feedback. This will allow me to reorganize the project
accordingly and adapt the code more closely to already mainlined drivers.
It looks like Lantiq provides a good example.

> 
> 	Andrew

Thanks,
Vasilij


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 1/4] dt-bindings: vendor-prefixes: Add soce
  2026-07-30  8:50   ` Krzysztof Kozlowski
@ 2026-08-03 16:03     ` Vasilij Strassheim
  0 siblings, 0 replies; 44+ messages in thread
From: Vasilij Strassheim @ 2026-08-03 16:03 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Andrew Lunn,
	Vladimir Oltean, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Russell King, devicetree, linux-kernel,
	netdev, Martin Kaistra

On Thu, 2026-07-30 at 10:50 +0200, Krzysztof Kozlowski wrote:
> On Wed, Jul 29, 2026 at 06:36:54PM +0200, Vasilij Strassheim wrote:
> > Add the soce vendor prefix for System-On-Chip Engineering, S.L.
> > 
> > This prefix is used by the new SoC-e Ethernet switch DT bindings.
> 
> Drop, implied. You explain here things which are not obvious. You can
> also look at git history to see how this is done.
> 
I see. I will fix that before re-submitting.

> Best regards,
> Krzysztof

Thanks,
Vasilij

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 2/4] dt-bindings: net: dsa: Add SoC-e switch IP and DSA bindings
  2026-07-30  8:56   ` Krzysztof Kozlowski
@ 2026-08-03 16:15     ` Vasilij Strassheim
  2026-08-03 16:43       ` Andrew Lunn
  2026-08-04  6:25       ` Krzysztof Kozlowski
  0 siblings, 2 replies; 44+ messages in thread
From: Vasilij Strassheim @ 2026-08-03 16:15 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Andrew Lunn,
	Vladimir Oltean, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Russell King, devicetree, linux-kernel,
	netdev, Martin Kaistra

On Thu, 2026-07-30 at 10:56 +0200, Krzysztof Kozlowski wrote:
> On Wed, Jul 29, 2026 at 06:36:55PM +0200, Vasilij Strassheim wrote:
> > Add DT schema documentation for SoC-e FPGA switch devices.
> > The binding is split into:
> >  - a switch IP node describing the MMIO register block
> >  - a DSA MDIO node describing the DSA-facing switch instance
> > Both nodes are linked through the soce,switch-ip phandle.
> > 
> > Signed-off-by: Vasilij Strassheim <v.strassheim@linutronix.de>
> > ---
> >  .../bindings/net/dsa/soce,switch-dsa.yaml          | 195 +++++++++++++++++++++
> >  .../bindings/net/dsa/soce,switch-ip.yaml           |  54 ++++++
> >  2 files changed, 249 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/net/dsa/soce,switch-dsa.yaml b/Documentation/devicetree/bindings/net/dsa/soce,switch-dsa.yaml
> > new file mode 100644
> > index 000000000000..a04e2838d14e
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/net/dsa/soce,switch-dsa.yaml
> > @@ -0,0 +1,195 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/net/dsa/soce,switch-dsa.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: SoC-e DSA switch MDIO device
> > +
> > +maintainers:
> > +  - SoC-e <info@soc-e.com>
> 
> Nope, as explained more than once group boxes are not accepted.

That rule makes actually sense. I just saw UNGLinuxDriver@microchip.com in
several places and thought it wasn't completely forbidden here.
Will change it to my address in the next version.

> 
> > +
> > +description: |
> > +  This node is the MDIO-bus device entry for the SoC-e DSA switch driver.
> 
> Node is not for a driver. Explain the hardware, not drivers, not DTS.

Got it, will change it for the next version.

> 
> 
> > +  It is a lightweight configuration node that lives on the MDIO bus of the
> > +  SoC Ethernet controller acting as the DSA conduit (CPU port).
> > +
> > +  The switch hardware itself (MMIO register interface) is a separate IP core
> > +  described by a companion node with one of the SoC-e compatible strings,
> > +  for example:
> > +    - soce,mrs-<version>
> 
> How is this relevant here? do you describe this compatible?

I will completely rework the documentation to reflect other code changes and
take the comment into account.
> 
> > +  See the consolidated IP-core binding:
> > +    - Documentation/devicetree/bindings/net/dsa/soce,switch-ip.yaml
> > +  The two nodes are linked via the "soce,switch-ip" phandle property.
> > +
> > +  Port sub-nodes follow the DSA port binding documented in dsa-port.yaml.
> > +  User ports should reference PHY nodes through "phy-handle". These PHY nodes
> > +  live under the optional "mdio" child node of the switch and are exposed on
> > +  the switch's synthetic DSA user MDIO bus.
> > +
> > +  The PHY-specific properties "soce,mdio-output" and "soce,phy-addr" describe
> > +  the MDIO bus index and hardware PHY address used by the on-chip MDIO master
> > +  of the switch IP core.
> > +
> > +properties:
> > +  '#address-cells':
> > +    const: 1
> > +
> > +  '#size-cells':
> > +    const: 0
> 
> You need to follow DTS coding style.

I will check and correct this.

> 
> > +
> > +  compatible:
> > +    const: soce,switch-dsa
> 
> Way too generic. I understand that SoCe will NEVER - and you certify
> that - develop a second, different "switch-dsa" model and they call this
> one like this?

It is intentionally generic to cover the common basics of all variants and
configurations of the synthesized switch in DSA.
I'm not sure what kind of guarantee I'm supposed to provide here regarding
SoCe. If switch-dsa is already mainline in the future, then a different
compatible will be needed for incompatible new models.

> > +
> > +  reg:
> > +    description: MDIO address of this device on the parent MDIO bus.
> 
> Drop.

Will do.

> 
> > +    maxItems: 1
> > +
> > +  soce,switch-ip:
> > +    $ref: /schemas/types.yaml#/definitions/phandle
> > +    description: |
> > +      Phandle to the SoC-e switch IP core node that provides the MMIO register
> > +      window for this switch instance. The referenced node must carry a
> > +      compatible string documented in
> > +      Documentation/devicetree/bindings/net/dsa/soce,switch-ip.yaml.
> > +
> > +  dsa,member:
> > +    $ref: /schemas/types.yaml#/definitions/uint32-array
> 
> Why do you need to redefine existing property?

This will be reworked in the next version.

> 
> > +    minItems: 2
> > +    maxItems: 2
> > +    description:
> > +      DSA cluster membership; see Documentation/devicetree/bindings/net/dsa/dsa.yaml.
> 
> Drop. Do not redefine properties. See other bindings how this is done.

I will do that.

> 
> > +
> > +  mdio:
> > +    $ref: /schemas/net/mdio.yaml#
> > +    description: |
> > +      Optional child MDIO bus exposing PHY devices attached to switch user
> > +      ports. PHY nodes referenced by port "phy-handle" properties should be
> > +      placed here. The PHY address seen by Linux on this bus is the switch port
> > +      index, not necessarily the hardware PHY address selected internally by
> > +      the switch IP.
> > +    unevaluatedProperties: false
> > +
> > +    patternProperties:
> > +      "^ethernet-phy@[0-9a-f]+$":
> 
> Use consistent quotes.

Got it.

> 
> > +        type: object
> > +        $ref: /schemas/net/ethernet-phy.yaml#
> > +        unevaluatedProperties: false
> > +        description:
> > +          PHY attached to a switch user port through the synthetic switch MDIO
> > +          bus.
> > +        properties:
> > +          soce,mdio-output:
> > +            $ref: /schemas/types.yaml#/definitions/uint32
> > +            description: |
> > +              Zero-based index of the MDIO bus output of the switch IP core to
> > +              which this PHY is connected.
> > +
> > +          soce,phy-addr:
> > +            $ref: /schemas/types.yaml#/definitions/uint32
> > +            description: |
> > +              Hardware PHY address on the MDIO bus selected by
> > +              "soce,mdio-output".
> > +
> > +        required:
> > +          - soce,mdio-output
> > +          - soce,phy-addr
> > +
> > +  ports:
> > +    type: object
> > +    description: Container node for the switch port sub-nodes.
> > +    properties:
> > +      '#address-cells':
> > +        const: 1
> > +      '#size-cells':
> > +        const: 0
> > +
> > +    patternProperties:
> > +      "^port@[0-9a-f]+$":
> > +        $ref: dsa-port.yaml#
> > +        unevaluatedProperties: false
> > +        description: |
> > +          Switch port. In addition to the standard DSA port properties
> > +          (label, phy-mode, ethernet, fixed-link) the following
> > +          vendor-specific properties are used for data ports connected to
> > +          external PHYs.
> > +
> > +    required:
> > +      - '#address-cells'
> > +      - '#size-cells'
> > +
> > +    additionalProperties: false
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - soce,switch-ip
> > +  - ports
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    /* Excerpt from a Xilinx ZynqMP design (ARM64) */
> > +    mdio {
> > +        #address-cells = <1>;
> > +        #size-cells = <0>;
> > +
> > +        soce_switch: switch@10 {
> > +            #address-cells = <1>;
> > +            #size-cells = <0>;
> > +            compatible = "soce,switch-dsa";
> > +            reg = <0x10>;
> > +            soce,switch-ip = <&soce_switch_ip>;
> > +            dsa,member = <0 0>;
> > +
> > +            ports {
> > +                #address-cells = <1>;
> > +                #size-cells = <0>;
> > +
> > +                port@0 {
> > +                    reg = <0x0>;
> > +                    label = "PORT_0";
> > +                    phy-handle = <&switchphy0>;
> > +                    phy-mode = "rgmii-id";
> > +                };
> > +
> > +                port@1 {
> > +                    reg = <0x1>;
> > +                    label = "PORT_1";
> > +                    phy-handle = <&switchphy1>;
> > +                    phy-mode = "rgmii-id";
> > +                };
> > +
> > +                port@2 {
> > +                    reg = <0x2>;
> > +                    label = "INTERNAL_PORT";
> > +                    ethernet = <&gem3>;
> > +                    phy-mode = "gmii";
> > +                    fixed-link {
> > +                        speed = <1000>;
> > +                        full-duplex;
> > +                    };
> > +                };
> > +            };
> > +
> > +            mdio {
> > +              #address-cells = <1>;
> > +              #size-cells = <0>;
> > +
> > +                switchphy0: ethernet-phy@0 {
> > +                    compatible = "ethernet-phy-ieee802.3-c22";
> > +                    reg = <0x0>;
> > +                    soce,mdio-output = <0x00000000>;
> > +                    soce,phy-addr = <1>;
> > +                };
> > +
> > +                switchphy1: ethernet-phy@1 {
> > +                    compatible = "ethernet-phy-ieee802.3-c22";
> > +                    reg = <0x1>;
> > +                    soce,mdio-output = <0x00000001>;
> > +                    soce,phy-addr = <1>;
> > +                };
> > +            };
> > +        };
> > +    };
> > diff --git a/Documentation/devicetree/bindings/net/dsa/soce,switch-ip.yaml b/Documentation/devicetree/bindings/net/dsa/soce,switch-ip.yaml
> > new file mode 100644
> > index 000000000000..ba9bb396235f
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/net/dsa/soce,switch-ip.yaml
> 
> Filename must match compatible.

I will rewrite the entire documentation to have a single file and take that
into account.

> 
> > @@ -0,0 +1,54 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/net/dsa/soce,switch-ip.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: SoC-e Ethernet Switch IP core
> > +
> > +maintainers:
> > +  - SoC-e <info@soc-e.com>
> > +
> > +description: |
> > +  SoC-e Ethernet switch IP cores are configurable FPGA switch fabrics with
> > +  Layer-2 bridging features (including STP/MSTP state control and FDB
> > +  fast-age support). Some variants also provide TSN functionality.
> > +
> > +  This binding describes only the MMIO switch IP core node. The Linux DSA
> > +  driver is bound via a companion MDIO node described in:
> > +    Documentation/devicetree/bindings/net/dsa/soce,switch-dsa.yaml.
> > +
> > +properties:
> > +  compatible:
> > +    enum:
> > +      - soce,mrs-21-01
> > +      - soce,mrs-23-02
> > +      - soce,mrs-24-01
> > +
> > +  reg:
> > +    description: |
> > +      MMIO base address and size of the switch register window.
> > +      On 64-bit platforms (ARM64), this is typically encoded as two-cell
> > +      address and two-cell size values.
> 
> Pointless. Please open any other existing binding.

Got it.

> 
> > +    maxItems: 1
> > +
> > +  soce,num-ports:
> > +    $ref: /schemas/types.yaml#/definitions/uint32
> > +    description: |
> > +      Total number of switch ports (external/user ports plus the CPU uplink
> > +      port). Must be greater than zero and not exceed the selected IP variant.
> 
> Either implied by compatible or not properly placed. Looks like propertt
> of the DSA.

This will be removed.

> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - soce,num-ports
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    switch_ip: switch@80020000 {
> 
> ethernet-switch
> 
> And drop unused label.

I will adjust it.

> 
> Considering this wasn't tested I should not even give here review...
> 
Thank you very much for the review!
I'm not sure what you mean by not tested. I ran make dt_binding_check` few
times, but forgot to do it after making the latest adjustments.
The driver also worked for different people with the device tree that I tried
to reflect here.

I will take a closer look at the documentation and other drivers, before I
send the next version.

> Best regards,
> Krzysztof
> 

Thanks,
Vasilij


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 2/4] dt-bindings: net: dsa: Add SoC-e switch IP and DSA bindings
  2026-07-30  8:56   ` Krzysztof Kozlowski
@ 2026-08-03 16:16     ` Vasilij Strassheim
  0 siblings, 0 replies; 44+ messages in thread
From: Vasilij Strassheim @ 2026-08-03 16:16 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Andrew Lunn,
	Vladimir Oltean, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Russell King, devicetree, linux-kernel,
	netdev, Martin Kaistra

On Thu, 2026-07-30 at 10:56 +0200, Krzysztof Kozlowski wrote:
> On Wed, Jul 29, 2026 at 06:36:55PM +0200, Vasilij Strassheim wrote:
> > Add DT schema documentation for SoC-e FPGA switch devices.
> > The binding is split into:
> >  - a switch IP node describing the MMIO register block
> >  - a DSA MDIO node describing the DSA-facing switch instance
> > Both nodes are linked through the soce,switch-ip phandle.
> 
> A nit, subject: drop second/last, redundant "bindings". The
> "dt-bindings" prefix is already stating that these are bindings.
> See also:
> https://elixir.bootlin.com/linux/v7.1-rc7/source/Documentation/devicetree/bindings/submitting-patches.rst#L23
> 
I will fix that.

> Best regards,
> Krzysztof
> 

Thanks,
Vasilij

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 4/4] net: dsa: soce: Add initial driver support for MRS switches
  2026-07-30  9:01   ` Krzysztof Kozlowski
@ 2026-08-03 16:23     ` Vasilij Strassheim
  0 siblings, 0 replies; 44+ messages in thread
From: Vasilij Strassheim @ 2026-08-03 16:23 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Andrew Lunn,
	Vladimir Oltean, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Russell King, devicetree, linux-kernel,
	netdev, Martin Kaistra

On Thu, 2026-07-30 at 11:01 +0200, Krzysztof Kozlowski wrote:
> On Wed, Jul 29, 2026 at 06:36:57PM +0200, Vasilij Strassheim wrote:
> > +static const struct soce_variant_desc soce_variants[] = {
> > +	{
> > +		.compatible		= "soce,mrs-21-01",
> > +		.mdio_master_offset	= SOCE_MRS_21_01_MDIO_MASTER_OFFSET,
> > +		.layout			= &soce_mrs_21_01_layout,
> > +		.mdio_ops		= &soce_mdio_ops_20_03,
> > +	},
> > +	{
> > +		.compatible		= "soce,mrs-23-02",
> > +		.mdio_master_offset	= SOCE_MRS_21_01_MDIO_MASTER_OFFSET,
> > +		.layout			= &soce_mrs_24_01_layout,
> > +		.mdio_ops		= &soce_mdio_ops_c22_c45,
> > +	},
> > +	{
> > +		.compatible		= "soce,mrs-24-01",
> > +		.mdio_master_offset	= SOCE_MRS_21_01_MDIO_MASTER_OFFSET,
> > +		.layout			= &soce_mrs_24_01_layout,
> > +		.mdio_ops		= &soce_mdio_ops_c22_c45,
> > +	},
> > +	{ /* sentinel */ },
> > +};
> > +
> > +static const struct soce_variant_desc *
> > +soce_match_variant(const char *compatible)
> > +{
> > +	int i;
> > +
> > +	for (i = 0; soce_variants[i].compatible; i++) {
> > +		if (!strcmp(compatible, soce_variants[i].compatible))
> > +			return &soce_variants[i];
> 
> Do not re-invent OF matching. This is supposed to be of_device_id table.

I will change that.

> 
> > +	}
> > +
> > +	return NULL;
> > +}
> > +
> > +static int soce_sw_parse_port_mdio_config(struct soce_dsa_local *local,
> > +					  struct device *dev,
> > +					  struct device_node *port_node,
> > +					  u32 port)
> > +{
> > +	struct device_node *phy_node;
> > +	u32 val;
> > +	int ret;
> > +
> > +	if (of_find_property(port_node, "ethernet", NULL) ||
> > +	    of_find_property(port_node, "link", NULL)) {
> > +		if (of_find_property(port_node, "phy-handle", NULL)) {
> > +			dev_err(dev,
> > +				"phy-handle not allowed on CPU/DSA port %u\n",
> > +				port);
> > +			return -EINVAL;
> > +		}
> > +
> > +		return 0;
> > +	}
> > +
> > +	phy_node = of_parse_phandle(port_node, "phy-handle", 0);
> > +	if (!phy_node) {
> > +		if (of_phy_is_fixed_link(port_node))
> > +			return 0;
> > +
> > +		dev_err(dev, "user port %u requires phy-handle or fixed-link\n",
> > +			port);
> > +		return -EINVAL;
> > +	}
> > +
> > +	ret = of_property_read_u32(phy_node, "soce,mdio-output", &val);
> > +	if (ret) {
> > +		dev_err(dev,
> > +			"missing soce,mdio-output in %pOF referenced by port %u\n",
> > +			phy_node, port);
> > +		goto out_put_phy;
> > +	}
> > +	local->mdio_info[port].mdio_output = val;
> > +
> > +	ret = of_property_read_u32(phy_node, "soce,phy-addr", &val);
> > +	if (ret) {
> > +		dev_err(dev,
> > +			"missing soce,phy-addr in %pOF referenced by port %u\n",
> > +			phy_node, port);
> > +		goto out_put_phy;
> > +	}
> > +	local->mdio_info[port].phy_addr = val;
> > +
> > +out_put_phy:
> > +	of_node_put(phy_node);
> > +	return ret;
> > +}
> > +
> > +static int soce_sw_parse_port_mdio(struct soce_priv *priv, struct device *dev,
> > +				   u32 numports)
> > +{
> > +	struct soce_dsa_local *local = &priv->local;
> > +	struct device_node *ports_node;
> > +	struct device_node *port_node;
> > +	u32 port;
> > +	int ret;
> > +
> > +	ports_node = of_get_child_by_name(dev->of_node, "ports");
> > +	if (!ports_node) {
> > +		dev_err(dev, "missing ports node\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	for_each_available_child_of_node(ports_node, port_node) {
> 
> Why not scoped?

I will change it to scoped.

> 
> > +		if (of_property_read_u32(port_node, "reg", &port))
> > +			continue;
> > +
> > +		if (port >= numports || port >= SOCE_MAX_NUM_PORTS) {
> > +			dev_warn(dev,
> > +				 "ignoring invalid port index %u in %pOF\n",
> > +				 port, port_node);
> > +			continue;
> > +		}
> > +
> > +		ret = soce_sw_parse_port_mdio_config(local, dev, port_node,
> > +						     port);
> > +		if (ret) {
> > +			of_node_put(port_node);
> > +			of_node_put(ports_node);
> > +			return ret;
> > +		}
> > +	}
> > +
> > +	of_node_put(ports_node);
> > +	return 0;
> > +}
> > +
> > +static int soce_sw_probe(struct mdio_device *mdiodev)
> > +{
> > +	const struct soce_variant_desc *variant;
> > +	struct device *dev = &mdiodev->dev;
> > +	struct device_node *switch_node;
> > +	struct soce_dsa_local *local;
> > +	const char *soce_compatible;
> > +	struct soce_priv *priv;
> > +	u32 numports;
> > +	int ret;
> > +
> > +	priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
> > +	if (!priv)
> > +		return -ENOMEM;
> > +
> > +	priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL);
> > +	if (!priv->ds)
> > +		return -ENOMEM;
> > +
> > +	priv->ds->dev = dev;
> > +	priv->ds->priv = priv;
> > +	local = &priv->local;
> > +
> > +	switch_node = of_parse_phandle(dev->of_node, "soce,switch-ip", 0);
> > +	if (!switch_node) {
> > +		dev_err(dev, "missing or invalid switch IP reference\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	ret = of_property_read_string(switch_node, "compatible",
> > +				      &soce_compatible);
> > +	if (ret) {
> > +		dev_err(dev, "missing compatible property in %pOF\n",
> > +			switch_node);
> > +		of_node_put(switch_node);
> > +		return -EINVAL;
> > +	}
> > +
> > +	variant = soce_match_variant(soce_compatible);
> > +	if (!variant) {
> > +		dev_err(dev, "unsupported compatible '%s' in %pOF\n",
> > +			soce_compatible, switch_node);
> > +		of_node_put(switch_node);
> 
> Use proper error handling exit paths with goto.

I will do it.

> 
> > +		return -ENODEV;
> > +	}
> > +
> > +	ret = of_property_read_u32(switch_node, "soce,num-ports", &numports);
> > +	if (ret) {
> > +		dev_err(dev, "missing soce,num-ports in %pOF\n", switch_node);
> > +		of_node_put(switch_node);
> > +		return -EINVAL;
> > +	}
> > +	if (numports == 0 || numports > SOCE_MAX_NUM_PORTS) {
> > +		dev_err(dev, "invalid soce,num-ports %u (max %d)\n", numports,
> > +			SOCE_MAX_NUM_PORTS);
> > +		of_node_put(switch_node);
> > +		return -EINVAL;
> > +	}
> > +
> > +	local->base_addr = devm_of_iomap(dev, switch_node, 0, NULL);
> > +	if (IS_ERR(local->base_addr)) {
> > +		dev_err(dev, "failed to map switch register space for %pOF\n",
> > +			switch_node);
> > +		of_node_put(switch_node);
> > +		return PTR_ERR(local->base_addr);
> > +	}
> > +
> > +	priv->ds->ops = &soce_switch_ops;
> > +	local->mdio_ops = variant->mdio_ops;
> > +	local->mdio_master_addr =
> > +		local->base_addr + variant->mdio_master_offset;
> > +	local->layout = variant->layout;
> > +	of_node_put(switch_node);
> > +
> > +	priv->ds->num_ports = numports;
> > +	ret = soce_sw_parse_port_mdio(priv, dev, numports);
> > +	if (ret)
> > +		return ret;
> > +
> > +	dev_set_drvdata(&mdiodev->dev, priv);
> > +
> > +	dev_info(dev, "soce %s SDSA driver probed.\n", soce_compatible);
> 
> Drop, driver should be silent on success.

Does this really apply to DSA drivers? I see some corresponding dev_info()
entries in mainlined drivers. See for example mv88e6060_probe(),
gswip_probe_common() and sja1105_probe().
And there are others as well, especially if you consider the _detect()
functions that are called from _probe().
I also find it very helpful for troubleshooting, so I'd like to keep it along
with some additional information about the hardware, just like other drivers.

> 
> > +
> > +	return dsa_register_switch(priv->ds);
> > +}
> > +
> > +static void soce_sw_remove(struct mdio_device *mdiodev)
> > +{
> > +	struct soce_priv *priv = dev_get_drvdata(&mdiodev->dev);
> > +
> > +	dsa_unregister_switch(priv->ds);
> > +}
> > +
> > +static const struct of_device_id soce_of_match[] = {
> > +	{ .compatible = "soce,switch-dsa" },
> > +	{ /* sentinel */ },
> > +};
> > +
> > +static struct mdio_driver soce_mdio_driver = {
> > +	.mdiodrv.driver = {
> > +		.name = "soce-switch-dsa",
> > +		.of_match_table = soce_of_match,
> > +	},
> > +	.probe  = soce_sw_probe,
> > +	.remove = soce_sw_remove,
> > +};
> 
> Best regards,
> Krzysztof
> 

Thanks,
Vasilij


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 0/4] net: dsa: Add SoC-e DSA driver
  2026-08-03 15:22   ` Vasilij Strassheim
@ 2026-08-03 16:32     ` Andrew Lunn
  2026-08-05 12:28       ` Vasilij Strassheim
  0 siblings, 1 reply; 44+ messages in thread
From: Andrew Lunn @ 2026-08-03 16:32 UTC (permalink / raw)
  To: Vasilij Strassheim
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vladimir Oltean,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Russell King, devicetree, linux-kernel, netdev,
	Martin Kaistra

On Mon, Aug 03, 2026 at 05:22:35PM +0200, Vasilij Strassheim wrote:
> On Wed, 2026-07-29 at 18:56 +0200, Andrew Lunn wrote:
> > On Wed, Jul 29, 2026 at 06:36:53PM +0200, Vasilij Strassheim wrote:
> > > Add initial support for the DSA driver for SoC-e FPGA-based (IP core)
> > > Ethernet switches.
> > 
> > Let me start with a dumb question. Is this a true soft core switch,
> > which is synthesised and running in the FPGA? Or is it hardware at the
> > edge of the FPGA SoC?
> 
> I should have made that clearer right away. This is a true soft-core
> switch that is synthesized and runs in AMD FPGAs.

Only AMD FPGAs? Or you have only used it with AMD FPGS?

> I have a version in which both the MAC and the switch are synthesized
> in FPGA, and two hardware PHYs are connected to the switch. The switch
> provides an MDIO bus for the PHYs.
> 
> > 
> > If it is synthesised, do we have to deal with different synthesis
> > options? Are there registers which indicate what these options are?
> 
> While setting up the switch, users will need to explore various
> synthesis options. Once it's up and running, it should be possible to
> load a preconfigured bitstream into the FPGA without having to deal with
> these options in the DSA driver. The device Tree should then match the
> configuration.

This is where we often run into issues. The driver sometimes makes
assumptions about how the device has been synthesised. Somebody
synthesise it differently, it breaks, and the driver has to be changed
without breaking backwards compatibility.

If the hardware actually enumerates itself, tells us how it has been
configured for synthesis, and the driver looks at these registers, you
tend to have less assumptions and so less issues later.

This is also one area what DT is not so great. You are not actually
describing hardware. Clearly, it is not software, but it is malleable,
jellyware. The less you put in DT, the more you get from the jellywere
itself, the better.

	Andrew

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 2/4] dt-bindings: net: dsa: Add SoC-e switch IP and DSA bindings
  2026-08-03 15:29     ` Vasilij Strassheim
@ 2026-08-03 16:35       ` Andrew Lunn
  2026-08-05 12:33         ` Vasilij Strassheim
  0 siblings, 1 reply; 44+ messages in thread
From: Andrew Lunn @ 2026-08-03 16:35 UTC (permalink / raw)
  To: Vasilij Strassheim
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vladimir Oltean,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Russell King, devicetree, linux-kernel, netdev,
	Martin Kaistra

> There are synthesis options for various management interfaces. MDIO and
> MMIO are two of them. I only have one variant for the memory-mapped
> version. For v2, I'll discard everything else and update the
> documentation accordingly.

Please take a look at the DSA drivers which support multiple
interfaces.

You probably want a MMIO driver which creates a regmap, and passes it
to the core driver. A future MDIO driver can create a regmap and pass
it to the core driver.

The DT binding should be similarly structured, a .yaml file for the
core, and a .yaml for the MMIO wrapper.

	Andrew

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 2/4] dt-bindings: net: dsa: Add SoC-e switch IP and DSA bindings
  2026-08-03 16:15     ` Vasilij Strassheim
@ 2026-08-03 16:43       ` Andrew Lunn
  2026-08-05 12:40         ` Vasilij Strassheim
  2026-08-05 13:32         ` Benedikt Spranger
  2026-08-04  6:25       ` Krzysztof Kozlowski
  1 sibling, 2 replies; 44+ messages in thread
From: Andrew Lunn @ 2026-08-03 16:43 UTC (permalink / raw)
  To: Vasilij Strassheim
  Cc: Krzysztof Kozlowski, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Vladimir Oltean, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Russell King,
	devicetree, linux-kernel, netdev, Martin Kaistra

> > > +  compatible:
> > > +    const: soce,switch-dsa
> > 
> > Way too generic. I understand that SoCe will NEVER - and you certify
> > that - develop a second, different "switch-dsa" model and they call this
> > one like this?
> 
> It is intentionally generic to cover the common basics of all variants and
> configurations of the synthesized switch in DSA.
> I'm not sure what kind of guarantee I'm supposed to provide here regarding
> SoCe. If switch-dsa is already mainline in the future, then a different
> compatible will be needed for incompatible new models.

If it is not compatible, it needs a different compatible.

It gets interesting with something you synthesizer, something where
there are a number of different synthesise options. How do you define
compatible? You might want a very specific compatible, for your
synthesise configuration, and a more generic compatible which might
work for other synthesise configurations, but maybe not?

     Andrew

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 3/4] net: dsa: Add support for SoC-e SDSA tags
  2026-08-03 15:37     ` Vasilij Strassheim
@ 2026-08-03 16:46       ` Andrew Lunn
  2026-08-05 12:47         ` Vasilij Strassheim
  0 siblings, 1 reply; 44+ messages in thread
From: Andrew Lunn @ 2026-08-03 16:46 UTC (permalink / raw)
  To: Vasilij Strassheim
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vladimir Oltean,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Russell King, devicetree, linux-kernel, netdev,
	Martin Kaistra

On Mon, Aug 03, 2026 at 05:37:26PM +0200, Vasilij Strassheim wrote:
> On Wed, 2026-07-29 at 19:22 +0200, Andrew Lunn wrote:
> > > @@ -98,6 +98,12 @@ config NET_DSA_TAG_EDSA
> > >  	  Say Y or M if you want to enable support for tagging frames for the
> > >  	  Marvell switches which use EtherType DSA headers.
> > >  
> > > +config NET_DSA_TAG_SDSA
> > > +	tristate "Tag driver for SoC-e switches using EtherType SDSA headers"
> > > +	help
> > > +	  Say Y or M if you want to enable support for tagging frames for the
> > > +	  SoC-e switches.
> > > +
> > 
> > These entries are sorted, so it probably should be between
> > NET_DSA_TAG_RZN1_A5PSW and NET_DSA_TAG_LAN9303.
> 
> I will insert it as suggested. To better understand, what is the sort order?

The tristate string.

    Andrew

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 4/4] net: dsa: soce: Add initial driver support for MRS switches
  2026-08-03 16:01     ` Vasilij Strassheim
@ 2026-08-03 16:49       ` Andrew Lunn
  2026-08-05 12:48         ` Vasilij Strassheim
  0 siblings, 1 reply; 44+ messages in thread
From: Andrew Lunn @ 2026-08-03 16:49 UTC (permalink / raw)
  To: Vasilij Strassheim
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vladimir Oltean,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Russell King, devicetree, linux-kernel, netdev,
	Martin Kaistra

On Mon, Aug 03, 2026 at 06:01:23PM +0200, Vasilij Strassheim wrote:
> On Wed, 2026-07-29 at 22:05 +0200, Andrew Lunn wrote:
> > > +static u8 soce_map_stp_state(u8 state)
> > > +{
> > > +	switch (state) {
> > > +	case BR_STATE_DISABLED:
> > > +	case BR_STATE_BLOCKING:
> > > +	case BR_STATE_LISTENING:
> > > +		return 0;
> > > +	case BR_STATE_LEARNING:
> > > +		return 1;
> > > +	case BR_STATE_FORWARDING:
> > > +	default:
> > > +		return 3;
> > 
> > #defines for 0, 1 and 3.
> > 
> > What does 2 mean?
> > 
> > Since you don't implement bridge offload, i'm not sure having STP
> > states makes any sense.
> 
> I tested bridge and STP and observed the callback calls with something like
> this (reduced setup):
> # ip link add name br0 type bridge
> # ip link set dev port0 master br0
> # ip link set dev port1 master br0
> # brctl stp br0 on
> 
> That probably wasn't enough. I'll take a closer look at it and either fix it
> or remove it for the next version.

For a really minimal DSA driver, look at mv88e6060. But it is also
really old, and does not always follow best practices, e.g. .phy_read
and .phy_write which should be replaced by a Linux MDIO driver.

	Andrew

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 2/4] dt-bindings: net: dsa: Add SoC-e switch IP and DSA bindings
  2026-08-03 16:15     ` Vasilij Strassheim
  2026-08-03 16:43       ` Andrew Lunn
@ 2026-08-04  6:25       ` Krzysztof Kozlowski
  2026-08-05 13:03         ` Vasilij Strassheim
  1 sibling, 1 reply; 44+ messages in thread
From: Krzysztof Kozlowski @ 2026-08-04  6:25 UTC (permalink / raw)
  To: Vasilij Strassheim
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Andrew Lunn,
	Vladimir Oltean, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Russell King, devicetree, linux-kernel,
	netdev, Martin Kaistra

On 03/08/2026 18:15, Vasilij Strassheim wrote:
> On Thu, 2026-07-30 at 10:56 +0200, Krzysztof Kozlowski wrote:
>> On Wed, Jul 29, 2026 at 06:36:55PM +0200, Vasilij Strassheim wrote:
>>> Add DT schema documentation for SoC-e FPGA switch devices.
>>> The binding is split into:
>>>  - a switch IP node describing the MMIO register block
>>>  - a DSA MDIO node describing the DSA-facing switch instance
>>> Both nodes are linked through the soce,switch-ip phandle.
>>>
>>> Signed-off-by: Vasilij Strassheim <v.strassheim@linutronix.de>
>>> ---
>>>  .../bindings/net/dsa/soce,switch-dsa.yaml          | 195 +++++++++++++++++++++
>>>  .../bindings/net/dsa/soce,switch-ip.yaml           |  54 ++++++
>>>  2 files changed, 249 insertions(+)
>>>
>>> diff --git a/Documentation/devicetree/bindings/net/dsa/soce,switch-dsa.yaml b/Documentation/devicetree/bindings/net/dsa/soce,switch-dsa.yaml
>>> new file mode 100644
>>> index 000000000000..a04e2838d14e
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/net/dsa/soce,switch-dsa.yaml
>>> @@ -0,0 +1,195 @@
>>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>>> +%YAML 1.2
>>> +---
>>> +$id: http://devicetree.org/schemas/net/dsa/soce,switch-dsa.yaml#
>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>> +
>>> +title: SoC-e DSA switch MDIO device
>>> +
>>> +maintainers:
>>> +  - SoC-e <info@soc-e.com>
>>
>> Nope, as explained more than once group boxes are not accepted.
> 
> That rule makes actually sense. I just saw UNGLinuxDriver@microchip.com in
> several places and thought it wasn't completely forbidden here.
> Will change it to my address in the next version.
> 
>>
>>> +
>>> +description: |
>>> +  This node is the MDIO-bus device entry for the SoC-e DSA switch driver.
>>
>> Node is not for a driver. Explain the hardware, not drivers, not DTS.
> 
> Got it, will change it for the next version.
> 
>>
>>
>>> +  It is a lightweight configuration node that lives on the MDIO bus of the
>>> +  SoC Ethernet controller acting as the DSA conduit (CPU port).
>>> +
>>> +  The switch hardware itself (MMIO register interface) is a separate IP core
>>> +  described by a companion node with one of the SoC-e compatible strings,
>>> +  for example:
>>> +    - soce,mrs-<version>
>>
>> How is this relevant here? do you describe this compatible?
> 
> I will completely rework the documentation to reflect other code changes and
> take the comment into account.
>>
>>> +  See the consolidated IP-core binding:
>>> +    - Documentation/devicetree/bindings/net/dsa/soce,switch-ip.yaml
>>> +  The two nodes are linked via the "soce,switch-ip" phandle property.
>>> +
>>> +  Port sub-nodes follow the DSA port binding documented in dsa-port.yaml.
>>> +  User ports should reference PHY nodes through "phy-handle". These PHY nodes
>>> +  live under the optional "mdio" child node of the switch and are exposed on
>>> +  the switch's synthetic DSA user MDIO bus.
>>> +
>>> +  The PHY-specific properties "soce,mdio-output" and "soce,phy-addr" describe
>>> +  the MDIO bus index and hardware PHY address used by the on-chip MDIO master
>>> +  of the switch IP core.
>>> +
>>> +properties:
>>> +  '#address-cells':
>>> +    const: 1
>>> +
>>> +  '#size-cells':
>>> +    const: 0
>>
>> You need to follow DTS coding style.
> 
> I will check and correct this.
> 
>>
>>> +
>>> +  compatible:
>>> +    const: soce,switch-dsa
>>
>> Way too generic. I understand that SoCe will NEVER - and you certify
>> that - develop a second, different "switch-dsa" model and they call this
>> one like this?
> 
> It is intentionally generic to cover the common basics of all variants and
> configurations of the synthesized switch in DSA.

Compatible must not be generic, as expressed hundreds times and
documented in writing bindings.

> I'm not sure what kind of guarantee I'm supposed to provide here regarding
> SoCe. If switch-dsa is already mainline in the future, then a different
> compatible will be needed for incompatible new models.

I also don't know what guarantee you must provide, it's you who wants to
add an exception.

...

>>> +
>>> +examples:
>>> +  - |
>>> +    switch_ip: switch@80020000 {
>>
>> ethernet-switch
>>
>> And drop unused label.
> 
> I will adjust it.
> 
>>
>> Considering this wasn't tested I should not even give here review...
>>
> Thank you very much for the review!
> I'm not sure what you mean by not tested. I ran make dt_binding_check` few
> times, but forgot to do it after making the latest adjustments.

Untested as it has an obvious failure as reported by bot.


Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 0/4] net: dsa: Add SoC-e DSA driver
  2026-08-03 16:32     ` Andrew Lunn
@ 2026-08-05 12:28       ` Vasilij Strassheim
  0 siblings, 0 replies; 44+ messages in thread
From: Vasilij Strassheim @ 2026-08-05 12:28 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vladimir Oltean,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Russell King, devicetree, linux-kernel, netdev,
	Martin Kaistra

On Mon, 2026-08-03 at 18:32 +0200, Andrew Lunn wrote:
> On Mon, Aug 03, 2026 at 05:22:35PM +0200, Vasilij Strassheim wrote:
> > On Wed, 2026-07-29 at 18:56 +0200, Andrew Lunn wrote:
> > > On Wed, Jul 29, 2026 at 06:36:53PM +0200, Vasilij Strassheim wrote:
> > > > Add initial support for the DSA driver for SoC-e FPGA-based (IP core)
> > > > Ethernet switches.
> > > 
> > > Let me start with a dumb question. Is this a true soft core switch,
> > > which is synthesised and running in the FPGA? Or is it hardware at the
> > > edge of the FPGA SoC?
> > 
> > I should have made that clearer right away. This is a true soft-core
> > switch that is synthesized and runs in AMD FPGAs.
> 
> Only AMD FPGAs? Or you have only used it with AMD FPGS?

That's what the documentation says. However the webpage says: 
	AMD/Xilinx and Microchip supported. Other vendors to be
	supported in the future.
I don't know any more details than that.

> 
> > I have a version in which both the MAC and the switch are synthesized
> > in FPGA, and two hardware PHYs are connected to the switch. The switch
> > provides an MDIO bus for the PHYs.
> > 
> > > 
> > > If it is synthesised, do we have to deal with different synthesis
> > > options? Are there registers which indicate what these options are?
> > 
> > While setting up the switch, users will need to explore various
> > synthesis options. Once it's up and running, it should be possible to
> > load a preconfigured bitstream into the FPGA without having to deal with
> > these options in the DSA driver. The device Tree should then match the
> > configuration.
> 
> This is where we often run into issues. The driver sometimes makes
> assumptions about how the device has been synthesised. Somebody
> synthesise it differently, it breaks, and the driver has to be changed
> without breaking backwards compatibility.
> 
> If the hardware actually enumerates itself, tells us how it has been
> configured for synthesis, and the driver looks at these registers, you
> tend to have less assumptions and so less issues later.
> 
> This is also one area what DT is not so great. You are not actually
> describing hardware. Clearly, it is not software, but it is malleable,
> jellyware. The less you put in DT, the more you get from the jellywere
> itself, the better.
> 

Yes, that makes sense. With this v1, I had to work around a few
non-technical limitations. I will try to resolve these and come up with
a new version where as much as necessary is read out from the jellyware.

With further adjustments, the dt-bindings should then contain only the
bare essentials. Not more that any other DSA driver would need.

> 	Andrew

Thanks,
Vasilij


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 2/4] dt-bindings: net: dsa: Add SoC-e switch IP and DSA bindings
  2026-08-03 16:35       ` Andrew Lunn
@ 2026-08-05 12:33         ` Vasilij Strassheim
  0 siblings, 0 replies; 44+ messages in thread
From: Vasilij Strassheim @ 2026-08-05 12:33 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vladimir Oltean,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Russell King, devicetree, linux-kernel, netdev,
	Martin Kaistra

On Mon, 2026-08-03 at 18:35 +0200, Andrew Lunn wrote:
> > There are synthesis options for various management interfaces. MDIO and
> > MMIO are two of them. I only have one variant for the memory-mapped
> > version. For v2, I'll discard everything else and update the
> > documentation accordingly.
> 
> Please take a look at the DSA drivers which support multiple
> interfaces.

Thank you for the tip. I think hellcreek and lantiq can serve as
examples. Both are also synthesized switches. Like hellcreek, I will
keep only one interface in the next version.

> You probably want a MMIO driver which creates a regmap, and passes it
> to the core driver. A future MDIO driver can create a regmap and pass
> it to the core driver.
> 
> The DT binding should be similarly structured, a .yaml file for the
> core, and a .yaml for the MMIO wrapper.

I think that once I have implemented all the suggestions made so far, a
single DT binding with a .yaml file should be enough. Just like in the
two examples mentioned.

> 
> 	Andrew

Thanks,
Vasilij

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 2/4] dt-bindings: net: dsa: Add SoC-e switch IP and DSA bindings
  2026-08-03 16:43       ` Andrew Lunn
@ 2026-08-05 12:40         ` Vasilij Strassheim
  2026-08-05 12:53           ` Andrew Lunn
  2026-08-05 13:32         ` Benedikt Spranger
  1 sibling, 1 reply; 44+ messages in thread
From: Vasilij Strassheim @ 2026-08-05 12:40 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Krzysztof Kozlowski, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Vladimir Oltean, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Russell King,
	devicetree, linux-kernel, netdev, Martin Kaistra

On Mon, 2026-08-03 at 18:43 +0200, Andrew Lunn wrote:
> > > > +  compatible:
> > > > +    const: soce,switch-dsa
> > > 
> > > Way too generic. I understand that SoCe will NEVER - and you certify
> > > that - develop a second, different "switch-dsa" model and they call this
> > > one like this?
> > 
> > It is intentionally generic to cover the common basics of all variants and
> > configurations of the synthesized switch in DSA.
> > I'm not sure what kind of guarantee I'm supposed to provide here regarding
> > SoCe. If switch-dsa is already mainline in the future, then a different
> > compatible will be needed for incompatible new models.
> 
> If it is not compatible, it needs a different compatible.
> 
> It gets interesting with something you synthesizer, something where
> there are a number of different synthesise options. How do you define
> compatible? You might want a very specific compatible, for your
> synthesise configuration, and a more generic compatible which might
> work for other synthesise configurations, but maybe not?
> 
Yes, that's not really satisfying.

I will tweak the driver so that it reads as much as possible from
registers. Currently, I'm considering adopting SoC-e IP Core families as
the compatible option. In my case, that would mean soce,mrs. Or if still
too generic something like mrs-switch-v1.0 or mrs-basic.

However, I won't be able to submit a v2 in the next few weeks. Maybe
I (or someone else) will come up with something better by then.

>      Andrew

Thanks
Vasilij

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 3/4] net: dsa: Add support for SoC-e SDSA tags
  2026-08-03 16:46       ` Andrew Lunn
@ 2026-08-05 12:47         ` Vasilij Strassheim
  0 siblings, 0 replies; 44+ messages in thread
From: Vasilij Strassheim @ 2026-08-05 12:47 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vladimir Oltean,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Russell King, devicetree, linux-kernel, netdev,
	Martin Kaistra

On Mon, 2026-08-03 at 18:46 +0200, Andrew Lunn wrote:
> On Mon, Aug 03, 2026 at 05:37:26PM +0200, Vasilij Strassheim wrote:
> > On Wed, 2026-07-29 at 19:22 +0200, Andrew Lunn wrote:
> > > > @@ -98,6 +98,12 @@ config NET_DSA_TAG_EDSA
> > > >  	  Say Y or M if you want to enable support for tagging frames for the
> > > >  	  Marvell switches which use EtherType DSA headers.
> > > >  
> > > > +config NET_DSA_TAG_SDSA
> > > > +	tristate "Tag driver for SoC-e switches using EtherType SDSA headers"
> > > > +	help
> > > > +	  Say Y or M if you want to enable support for tagging frames for the
> > > > +	  SoC-e switches.
> > > > +
> > > 
> > > These entries are sorted, so it probably should be between
> > > NET_DSA_TAG_RZN1_A5PSW and NET_DSA_TAG_LAN9303.
> > 
> > I will insert it as suggested. To better understand, what is the sort order?
> 
> The tristate string.

I see, thank you. I will keep that in mind in the future.

> 
>     Andrew

Vasilij

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 4/4] net: dsa: soce: Add initial driver support for MRS switches
  2026-08-03 16:49       ` Andrew Lunn
@ 2026-08-05 12:48         ` Vasilij Strassheim
  0 siblings, 0 replies; 44+ messages in thread
From: Vasilij Strassheim @ 2026-08-05 12:48 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vladimir Oltean,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Russell King, devicetree, linux-kernel, netdev,
	Martin Kaistra

On Mon, 2026-08-03 at 18:49 +0200, Andrew Lunn wrote:
> On Mon, Aug 03, 2026 at 06:01:23PM +0200, Vasilij Strassheim wrote:
> > On Wed, 2026-07-29 at 22:05 +0200, Andrew Lunn wrote:
> > > > +static u8 soce_map_stp_state(u8 state)
> > > > +{
> > > > +	switch (state) {
> > > > +	case BR_STATE_DISABLED:
> > > > +	case BR_STATE_BLOCKING:
> > > > +	case BR_STATE_LISTENING:
> > > > +		return 0;
> > > > +	case BR_STATE_LEARNING:
> > > > +		return 1;
> > > > +	case BR_STATE_FORWARDING:
> > > > +	default:
> > > > +		return 3;
> > > 
> > > #defines for 0, 1 and 3.
> > > 
> > > What does 2 mean?
> > > 
> > > Since you don't implement bridge offload, i'm not sure having STP
> > > states makes any sense.
> > 
> > I tested bridge and STP and observed the callback calls with something like
> > this (reduced setup):
> > # ip link add name br0 type bridge
> > # ip link set dev port0 master br0
> > # ip link set dev port1 master br0
> > # brctl stp br0 on
> > 
> > That probably wasn't enough. I'll take a closer look at it and either fix it
> > or remove it for the next version.
> 
> For a really minimal DSA driver, look at mv88e6060. But it is also
> really old, and does not always follow best practices, e.g. .phy_read
> and .phy_write which should be replaced by a Linux MDIO driver.

Will do that and compare it with newer drivers as well.

> 	Andrew

Thanks,
Vasilij

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 2/4] dt-bindings: net: dsa: Add SoC-e switch IP and DSA bindings
  2026-08-05 12:40         ` Vasilij Strassheim
@ 2026-08-05 12:53           ` Andrew Lunn
  2026-08-05 13:17             ` Vasilij Strassheim
  0 siblings, 1 reply; 44+ messages in thread
From: Andrew Lunn @ 2026-08-05 12:53 UTC (permalink / raw)
  To: Vasilij Strassheim
  Cc: Krzysztof Kozlowski, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Vladimir Oltean, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Russell King,
	devicetree, linux-kernel, netdev, Martin Kaistra

On Wed, Aug 05, 2026 at 02:40:53PM +0200, Vasilij Strassheim wrote:
> On Mon, 2026-08-03 at 18:43 +0200, Andrew Lunn wrote:
> > > > > +  compatible:
> > > > > +    const: soce,switch-dsa
> > > > 
> > > > Way too generic. I understand that SoCe will NEVER - and you certify
> > > > that - develop a second, different "switch-dsa" model and they call this
> > > > one like this?
> > > 
> > > It is intentionally generic to cover the common basics of all variants and
> > > configurations of the synthesized switch in DSA.
> > > I'm not sure what kind of guarantee I'm supposed to provide here regarding
> > > SoCe. If switch-dsa is already mainline in the future, then a different
> > > compatible will be needed for incompatible new models.
> > 
> > If it is not compatible, it needs a different compatible.
> > 
> > It gets interesting with something you synthesizer, something where
> > there are a number of different synthesise options. How do you define
> > compatible? You might want a very specific compatible, for your
> > synthesise configuration, and a more generic compatible which might
> > work for other synthesise configurations, but maybe not?
> > 
> Yes, that's not really satisfying.

That is the problem with FPGAs and jellyware.

> I will tweak the driver so that it reads as much as possible from
> registers. Currently, I'm considering adopting SoC-e IP Core families as
> the compatible option.

I would probably make that the fallback.

Maybe look around at how IP licensed from Synopsys and other vendors
of IP cores work. It is slightly different use case in that these are
generally integrated into silicon, so are fixed, but the chip vendor
often puts logic around the licensed core which needs driving, and
they sometimes integrate the core wrongly, so need workarounds. So you
often have a compatible for the specific vendors overall integration,
and a fallback compatible for the IP core version.

I would suggest something similar here, compatibles for each SoC-e IP
core version, plus a compatible for your specific device.

     Andrew

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 2/4] dt-bindings: net: dsa: Add SoC-e switch IP and DSA bindings
  2026-08-04  6:25       ` Krzysztof Kozlowski
@ 2026-08-05 13:03         ` Vasilij Strassheim
  0 siblings, 0 replies; 44+ messages in thread
From: Vasilij Strassheim @ 2026-08-05 13:03 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Andrew Lunn,
	Vladimir Oltean, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Russell King, devicetree, linux-kernel,
	netdev, Martin Kaistra

On Tue, 2026-08-04 at 08:25 +0200, Krzysztof Kozlowski wrote:
> On 03/08/2026 18:15, Vasilij Strassheim wrote:
> > On Thu, 2026-07-30 at 10:56 +0200, Krzysztof Kozlowski wrote:
> > > On Wed, Jul 29, 2026 at 06:36:55PM +0200, Vasilij Strassheim wrote:
> > > > Add DT schema documentation for SoC-e FPGA switch devices.
> > > > The binding is split into:
> > > >  - a switch IP node describing the MMIO register block
> > > >  - a DSA MDIO node describing the DSA-facing switch instance
> > > > Both nodes are linked through the soce,switch-ip phandle.
> > > > 
> > > > Signed-off-by: Vasilij Strassheim <v.strassheim@linutronix.de>
> > > > ---
> > > >  .../bindings/net/dsa/soce,switch-dsa.yaml          | 195 +++++++++++++++++++++
> > > >  .../bindings/net/dsa/soce,switch-ip.yaml           |  54 ++++++
> > > >  2 files changed, 249 insertions(+)
> > > > 
> > > > diff --git a/Documentation/devicetree/bindings/net/dsa/soce,switch-dsa.yaml b/Documentation/devicetree/bindings/net/dsa/soce,switch-dsa.yaml
> > > > new file mode 100644
> > > > index 000000000000..a04e2838d14e
> > > > --- /dev/null
> > > > +++ b/Documentation/devicetree/bindings/net/dsa/soce,switch-dsa.yaml
> > > 
[...]
> > > > +
> > > > +  compatible:
> > > > +    const: soce,switch-dsa
> > > 
> > > Way too generic. I understand that SoCe will NEVER - and you certify
> > > that - develop a second, different "switch-dsa" model and they call this
> > > one like this?
> > 
> > It is intentionally generic to cover the common basics of all variants and
> > configurations of the synthesized switch in DSA.
> 
> Compatible must not be generic, as expressed hundreds times and
> documented in writing bindings.

I probably misunderstood a few concepts around bindings, and I apologize
for that. For the next version, I would base it on the existing SoC-e IP
core families. Single DT binding file should then be sufficient.

I think a suitable filename would be something like soce,switch.yaml. That's
roughly in line with the existing nxp,netc-switch.yaml.
Or soce,swip.yaml, as in lantiq,gswip.yaml.

> 
> > I'm not sure what kind of guarantee I'm supposed to provide here regarding
> > SoCe. If switch-dsa is already mainline in the future, then a different
> > compatible will be needed for incompatible new models.
> 
> I also don't know what guarantee you must provide, it's you who wants to
> add an exception.

Okay, there's no need to make an exception for this case, I will change
the compatible to something suitable.

I also understand now, that the DT bindings are not necessarily used
only in Linux. However, I would like to use them for the DSA driver of the
Soft IP Core Switch. The driver can be adapted so that it reads a
wide variety of configurations and versions from the synthesized switch
and deal with them without any additional properties.

Would “soce,mrs” be suitable as “compatible” in this case? If that's
still too generic maybe “soce,mrs-switch-v1.0”
I will think more about it in the next few weeks, before I submit the
new version. Would be happy to hear any better suggestions that you, or
someone else, might have.

> ...
> 
> > > > +
> > > > +examples:
> > > > +  - |
> > > > +    switch_ip: switch@80020000 {
> > > 
> > > ethernet-switch
> > > 
> > > And drop unused label.
> > 
> > I will adjust it.
> > 
> > > 
> > > Considering this wasn't tested I should not even give here review...
> > > 
> > Thank you very much for the review!
> > I'm not sure what you mean by not tested. I ran make dt_binding_check` few
> > times, but forgot to do it after making the latest adjustments.
> 
> Untested as it has an obvious failure as reported by bot.

I know better now, that should not happen again in the future.

> 
> Best regards,
> Krzysztof

Thanks,
Vasilij


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 2/4] dt-bindings: net: dsa: Add SoC-e switch IP and DSA bindings
  2026-08-05 12:53           ` Andrew Lunn
@ 2026-08-05 13:17             ` Vasilij Strassheim
  0 siblings, 0 replies; 44+ messages in thread
From: Vasilij Strassheim @ 2026-08-05 13:17 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Krzysztof Kozlowski, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Vladimir Oltean, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Russell King,
	devicetree, linux-kernel, netdev, Martin Kaistra

On Wed, 2026-08-05 at 14:53 +0200, Andrew Lunn wrote:
> On Wed, Aug 05, 2026 at 02:40:53PM +0200, Vasilij Strassheim wrote:
> > On Mon, 2026-08-03 at 18:43 +0200, Andrew Lunn wrote:
> > > > > > +  compatible:
> > > > > > +    const: soce,switch-dsa
> > > > > 
> > > > > Way too generic. I understand that SoCe will NEVER - and you certify
> > > > > that - develop a second, different "switch-dsa" model and they call this
> > > > > one like this?
> > > > 
> > > > It is intentionally generic to cover the common basics of all variants and
> > > > configurations of the synthesized switch in DSA.
> > > > I'm not sure what kind of guarantee I'm supposed to provide here regarding
> > > > SoCe. If switch-dsa is already mainline in the future, then a different
> > > > compatible will be needed for incompatible new models.
> > > 
> > > If it is not compatible, it needs a different compatible.
> > > 
> > > It gets interesting with something you synthesizer, something where
> > > there are a number of different synthesise options. How do you define
> > > compatible? You might want a very specific compatible, for your
> > > synthesise configuration, and a more generic compatible which might
> > > work for other synthesise configurations, but maybe not?
> > > 
> > Yes, that's not really satisfying.
> 
> That is the problem with FPGAs and jellyware.
> 
> > I will tweak the driver so that it reads as much as possible from
> > registers. Currently, I'm considering adopting SoC-e IP Core families as
> > the compatible option.
> 
> I would probably make that the fallback.
> 
> Maybe look around at how IP licensed from Synopsys and other vendors
> of IP cores work. It is slightly different use case in that these are
> generally integrated into silicon, so are fixed, but the chip vendor
> often puts logic around the licensed core which needs driving, and
> they sometimes integrate the core wrongly, so need workarounds. So you
> often have a compatible for the specific vendors overall integration,
> and a fallback compatible for the IP core version.
> 
> I would suggest something similar here, compatibles for each SoC-e IP
> core version, plus a compatible for your specific device.

I've seen something similar on Cadence macb as well. “cdns,gem” is
commented as #Generic there, but I wasn't sure where that came from. In
this case, it must be such a fallback. Thanks for the explanation, I
will take that into account for the new version.


Vasilij

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 2/4] dt-bindings: net: dsa: Add SoC-e switch IP and DSA bindings
  2026-08-03 16:43       ` Andrew Lunn
  2026-08-05 12:40         ` Vasilij Strassheim
@ 2026-08-05 13:32         ` Benedikt Spranger
  2026-08-05 13:53           ` Andrew Lunn
  1 sibling, 1 reply; 44+ messages in thread
From: Benedikt Spranger @ 2026-08-05 13:32 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Vasilij Strassheim, Krzysztof Kozlowski, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Vladimir Oltean,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Russell King, devicetree, linux-kernel, netdev,
	Martin Kaistra

On Mon, 3 Aug 2026 18:43:23 +0200
Andrew Lunn <andrew@lunn.ch> wrote:

> If it is not compatible, it needs a different compatible.
This is quite tricky here - namewise. 

> It gets interesting with something you synthesizer, something where
> there are a number of different synthesise options. How do you define
> compatible? You might want a very specific compatible, for your
> synthesise configuration, and a more generic compatible which might
> work for other synthesise configurations, but maybe not?

SOC-E sells quite a bunch of switch IPs (MES, MRS, NTS to name some).
As far as we know for now, these different IP cores can be determined
by reading specific registers, which seem to be on the same spot across
different IPs. You may wonder about "It seems". Since we have only a
limited access for information about different IPs, we have examined the
vendor linux DSA driver and the surrounding configuration software.

So for now the different features can be read out at specific registers
- an autoconfiguration of the DSA driver is therefor possible. Now to
the compatible string. The easiest way is to name it after the IP core
name: MES, MRS or NTS. But that's wishfull thinking:

You can use the MRS IP core an disable all management features. You
have an unmanaged switch with an MDIO interface. Terefore you can not
rely on the compatible string and have to verify the feature registers.
Also you have to switch device trees for different IP cores for no good.

The big plus for this solution is less struggle with the devicetree
police.

So in fact the compatible string should reflect a register layout
nessesary to determine the switch IP and configuration. There is no
such name in the documentation, as we can see so far.

As a suggestion from my side: soce,switch-reg-layout-v1

If this minimal set of registers changes in an incompatible way, the
version number can be increased.

Regards
    Bene

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 2/4] dt-bindings: net: dsa: Add SoC-e switch IP and DSA bindings
  2026-08-05 13:32         ` Benedikt Spranger
@ 2026-08-05 13:53           ` Andrew Lunn
  2026-08-05 14:27             ` Benedikt Spranger
  0 siblings, 1 reply; 44+ messages in thread
From: Andrew Lunn @ 2026-08-05 13:53 UTC (permalink / raw)
  To: Benedikt Spranger
  Cc: Vasilij Strassheim, Krzysztof Kozlowski, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Vladimir Oltean,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Russell King, devicetree, linux-kernel, netdev,
	Martin Kaistra

On Wed, Aug 05, 2026 at 03:32:20PM +0200, Benedikt Spranger wrote:
> On Mon, 3 Aug 2026 18:43:23 +0200
> Andrew Lunn <andrew@lunn.ch> wrote:
> 
> > If it is not compatible, it needs a different compatible.
> This is quite tricky here - namewise. 

Yep.

> 
> > It gets interesting with something you synthesizer, something where
> > there are a number of different synthesise options. How do you define
> > compatible? You might want a very specific compatible, for your
> > synthesise configuration, and a more generic compatible which might
> > work for other synthesise configurations, but maybe not?
> 
> SOC-E sells quite a bunch of switch IPs (MES, MRS, NTS to name some).
> As far as we know for now, these different IP cores can be determined
> by reading specific registers, which seem to be on the same spot across
> different IPs. You may wonder about "It seems". Since we have only a
> limited access for information about different IPs, we have examined the
> vendor linux DSA driver and the surrounding configuration software.

Take a look at the mv88e6xxx driver. Marvell switches have an ID
register. But Marvell keep moving it around. So the compatible is just
about where to find the ID register.

However, that is silicon. For licensed IP, you are not driving just
the licensed IP, but also what has been put around it for integration
into the system as a whole. Regulator, clocks, etc. The stmmac driver
is an example of that, the driver has a core which covers the licensed
IP, and then a number of glue drivers which extend that to cover all
the integration logic. Another example i've worked on is the Open
Cores I2C driver, i2c-ocores.c. It has a generic compatible
"opencores,i2c-ocores", plus some integration specific compatibles,
"aeroflexgaisler,i2cmst", "sifive,fu540-c000-i2c", "sifive,i2c0".

So i suspect you will need to support integration specific
compatibles.

One way to consider this. Look at your FPGA design. Delete the
licensed core. What do you have left? Does it need software to drive
it?

	Andrew

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 2/4] dt-bindings: net: dsa: Add SoC-e switch IP and DSA bindings
  2026-08-05 13:53           ` Andrew Lunn
@ 2026-08-05 14:27             ` Benedikt Spranger
  2026-08-06 13:35               ` Andrew Lunn
  0 siblings, 1 reply; 44+ messages in thread
From: Benedikt Spranger @ 2026-08-05 14:27 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Vasilij Strassheim, Krzysztof Kozlowski, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Vladimir Oltean,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Russell King, devicetree, linux-kernel, netdev,
	Martin Kaistra

Am Wed, 5 Aug 2026 15:53:59 +0200
schrieb Andrew Lunn <andrew@lunn.ch>:

> So i suspect you will need to support integration specific
> compatibles.

Me too. But for *now* things are, better seem to be, simple. The aim is
not to plug forseeable future development.

> One way to consider this. Look at your FPGA design. Delete the
> licensed core. What do you have left? Does it need software to drive
> it?
The minimal IP core is an unmanaged switch. No need for a DSA driver
here. The IP core profides a MDIO bus, therefor a MDIO driver would be
good. The version register in combination with some feature register
can be determined to get the needed information to configure the DSA
driver, or in the minimal case to return -ENODEV.

Thats, why I suggest to have a compatible string, which reflects the
register layout needed to determine the switch configuration:

1) Read the version register
2) Upon the version read the feature register
3) Be happy and configure the switch.

Regards
    Bene

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 2/4] dt-bindings: net: dsa: Add SoC-e switch IP and DSA bindings
  2026-08-05 14:27             ` Benedikt Spranger
@ 2026-08-06 13:35               ` Andrew Lunn
  2026-08-06 15:25                 ` Benedikt Spranger
  0 siblings, 1 reply; 44+ messages in thread
From: Andrew Lunn @ 2026-08-06 13:35 UTC (permalink / raw)
  To: Benedikt Spranger
  Cc: Vasilij Strassheim, Krzysztof Kozlowski, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Vladimir Oltean,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Russell King, devicetree, linux-kernel, netdev,
	Martin Kaistra

On Wed, Aug 05, 2026 at 04:27:05PM +0200, Benedikt Spranger wrote:
> Am Wed, 5 Aug 2026 15:53:59 +0200
> schrieb Andrew Lunn <andrew@lunn.ch>:
> 
> > So i suspect you will need to support integration specific
> > compatibles.
> 
> Me too. But for *now* things are, better seem to be, simple. The aim is
> not to plug forseeable future development.
> 
> > One way to consider this. Look at your FPGA design. Delete the
> > licensed core. What do you have left? Does it need software to drive
> > it?

> The minimal IP core is an unmanaged switch. No need for a DSA driver
> here. The IP core profides a MDIO bus, therefor a MDIO driver would be
> good. The version register in combination with some feature register
> can be determined to get the needed information to configure the DSA
> driver, or in the minimal case to return -ENODEV.

I think you misunderstood my comment. I expect the MDIO bus is part of
the licensed core. So when you take your FPGA design, and delete the
licensed part, that disappears as well. When you delete the licensed
part, you should have a big hole in the middle of the design, leaving
just what surrounds the switch. That is that logical? Clock dividers?
Logic to map the switch registers to MMIO, so maybe a PCIe device
core? Does any of this surrounding logic need software? If it does,
that is probably specific to your design, and needs a compatible which
covers both the licensed switch core, and the surrounding design
specific logic.

	Andrew

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 2/4] dt-bindings: net: dsa: Add SoC-e switch IP and DSA bindings
  2026-08-06 13:35               ` Andrew Lunn
@ 2026-08-06 15:25                 ` Benedikt Spranger
  0 siblings, 0 replies; 44+ messages in thread
From: Benedikt Spranger @ 2026-08-06 15:25 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Vasilij Strassheim, Krzysztof Kozlowski, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Vladimir Oltean,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Russell King, devicetree, linux-kernel, netdev,
	Martin Kaistra

On Thu, 6 Aug 2026 15:35:36 +0200
Andrew Lunn <andrew@lunn.ch> wrote:

> > The minimal IP core is an unmanaged switch. No need for a DSA driver
> > here. The IP core profides a MDIO bus, therefor a MDIO driver would
> > be good. The version register in combination with some feature
> > register can be determined to get the needed information to
> > configure the DSA driver, or in the minimal case to return -ENODEV.
 
> I think you misunderstood my comment. I expect the MDIO bus is part of
> the licensed core.
OK, I did the second step, but the first was not clear, so lets do some
ASCII art:

                     ---------
               S_AXI |   S   | port_0_gmii
              clk_in |   W   |     ...
               reset |   I   | port_N_gmii
           IP_enable |   T   |
default_op_mode[4:0] |   C   |
         port_0_link |   H   | port_0_phy_rst_n
             ...     |       |     ...
         port_N_link |   I   | port_N_phy_rst_n
          S_AXI_ACLK |   P   |
       S_AXI_ARESETN |       |
                     ---------

The switch is connected through an AXI Stream interface i.e. the memory
interface ==> Device Tree binding needed (Base Register)
Other AXI related signals are hiden and need no device tree
representation.

The switch has one mandatory and 6 optional clocks:
1. System Clock / clk_in (mandatory)
2. AXI4 Lite Clock
3. AXI Stream Clock
4. port_x_ref_rmii_clk
5. PHY RX Clock
6. PHY TX Clock
7. Port_x MDC

Here are all Device Tree bindings optional, since the mandatory clock
can be provided by some not exposed internal clock signal as in our
case and the other clocks are optional.

GMII ports ==> The ports are defined by the DSA bindings.

reset ==> optional GPIO device tree binding

IP_enable ==> optional GPIO device tree binding

default_op_mode ==> optional GPIO device tree bindings

port_x_link and port_x_phy_rst_n are signals to the PHY ==> mdio device
tree binding.

> So when you take your FPGA design, and delete the
> licensed part, that disappears as well. When you delete the licensed
> part, you should have a big hole in the middle of the design, leaving
> just what surrounds the switch. That is that logical? Clock dividers?
See above; hope that helps.

> Logic to map the switch registers to MMIO, so maybe a PCIe device
> core?
The AXI bus may connected to an PCIe bridge for example. In our case it
is connected directly to the SoC ARM core.

> Does any of this surrounding logic need software?
In our case: No.

> If it does, that is probably specific to your design, and needs a
> compatible which covers both the licensed switch core, and the
> surrounding design specific logic.

In our case the clocks are routed to fixed clocks, which have no device
tree representation. reset , IP_enable and default_op_mode are an fixed
levels.

Therefore no need for a detailed compatible string and no optional
device tree properties. Clean and simple *knock on wood*

Regards
    Bene

^ permalink raw reply	[flat|nested] 44+ messages in thread

end of thread, other threads:[~2026-08-06 15:25 UTC | newest]

Thread overview: 44+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-29 16:36 [PATCH 0/4] net: dsa: Add SoC-e DSA driver Vasilij Strassheim
2026-07-29 16:36 ` [PATCH 1/4] dt-bindings: vendor-prefixes: Add soce Vasilij Strassheim
2026-07-30  8:50   ` Krzysztof Kozlowski
2026-08-03 16:03     ` Vasilij Strassheim
2026-07-29 16:36 ` [PATCH 2/4] dt-bindings: net: dsa: Add SoC-e switch IP and DSA bindings Vasilij Strassheim
2026-07-29 17:11   ` Andrew Lunn
2026-08-03 15:29     ` Vasilij Strassheim
2026-08-03 16:35       ` Andrew Lunn
2026-08-05 12:33         ` Vasilij Strassheim
2026-07-29 18:07   ` Rob Herring (Arm)
2026-08-03 15:47     ` Vasilij Strassheim
2026-07-30  8:56   ` Krzysztof Kozlowski
2026-08-03 16:15     ` Vasilij Strassheim
2026-08-03 16:43       ` Andrew Lunn
2026-08-05 12:40         ` Vasilij Strassheim
2026-08-05 12:53           ` Andrew Lunn
2026-08-05 13:17             ` Vasilij Strassheim
2026-08-05 13:32         ` Benedikt Spranger
2026-08-05 13:53           ` Andrew Lunn
2026-08-05 14:27             ` Benedikt Spranger
2026-08-06 13:35               ` Andrew Lunn
2026-08-06 15:25                 ` Benedikt Spranger
2026-08-04  6:25       ` Krzysztof Kozlowski
2026-08-05 13:03         ` Vasilij Strassheim
2026-07-30  8:56   ` Krzysztof Kozlowski
2026-08-03 16:16     ` Vasilij Strassheim
2026-07-29 16:36 ` [PATCH 3/4] net: dsa: Add support for SoC-e SDSA tags Vasilij Strassheim
2026-07-29 17:22   ` Andrew Lunn
2026-08-03 15:37     ` Vasilij Strassheim
2026-08-03 16:46       ` Andrew Lunn
2026-08-05 12:47         ` Vasilij Strassheim
2026-07-29 16:36 ` [PATCH 4/4] net: dsa: soce: Add initial driver support for MRS switches Vasilij Strassheim
2026-07-29 17:31   ` Andrew Lunn
2026-08-03 15:40     ` Vasilij Strassheim
2026-07-29 20:05   ` Andrew Lunn
2026-08-03 16:01     ` Vasilij Strassheim
2026-08-03 16:49       ` Andrew Lunn
2026-08-05 12:48         ` Vasilij Strassheim
2026-07-30  9:01   ` Krzysztof Kozlowski
2026-08-03 16:23     ` Vasilij Strassheim
2026-07-29 16:56 ` [PATCH 0/4] net: dsa: Add SoC-e DSA driver Andrew Lunn
2026-08-03 15:22   ` Vasilij Strassheim
2026-08-03 16:32     ` Andrew Lunn
2026-08-05 12:28       ` Vasilij Strassheim

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox