* [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
* 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 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
* [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
* 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 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 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: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-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 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 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-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-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 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 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-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
* 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 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-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 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
* [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
* 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 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 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 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
* [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 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 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 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 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 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 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 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 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-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 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 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 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
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