Skip to contentSkip to conversation

Introduce EN7581 ethernet support

PATCH Superseded Lorenzo Bianconi 4 participants 8 messages Jul 9, 2024

Subsystems (5)

v6 of 8 Superseded Latest is v8 →

lore
Share & tools
lore

Lorenzo Bianconi

author maintainer
#0 lore raw

v6 cover Introduce EN7581 ethernet support

Add airoha_eth driver in order to introduce ethernet support for Airoha EN7581 SoC available on EN7581 development board. EN7581 mac controller is mainly composed by Frame Engine (FE) and QoS-DMA (QDMA) modules. FE is used for traffic offloading (just basic functionalities are supported now) while QDMA is used for DMA operation and QOS functionalities between mac layer and the dsa switch (hw QoS is not available yet and it will be added in the future). Currently only hw lan features are available, hw wan will be added with subsequent patches.

Changes since v5:
- implement .ndo_get_stats64() callback and remove duplicated ethtool entries
- remove "ethernet-controller.yaml#" from parent node in device tree binding
- rename child node from "mac" to "ethernet" in device tree binding
- fix checkpatch errors
Changes since v4:
- fix compilation warnings
- use airoha_qdma_rr() and not airoha_rr() in airoha_qdma_set_irqmask()
- add missing descriptions in dt-binding
- remove mdio node in binding example
Changes since v3:
- rework architecture to allow future gdm{1,4} support
- read REG_INT_ENABLE() register in airoha_qdma_set_irqmask() to guarantee airoha_qdma_wr() complete in the spinlock critical section - thx Arnd for the clarification
- remove unnecessary wmb()
- remove debugfs
- move register definitions in .c and remove .h
- fix warnings
- enable NAPI thread by default
Changes since v2:
- rename airoha,en7581.yaml in airoha,en7581-eth.yaml
- remove reset dependency in airoha,en7581-eth.yaml
- remove airoha_dev_change_mtu() callback
Changes since v1:
- drop patch 2/3
- remove queue lock for rx queues
- add bql support
- add ethtool stats support
- fix possible infinite loop in airoha_qdma_rx_process routine
- always destroy page_pool in case of error during initialization
- cosmetics

Lorenzo Bianconi (2):
dt-bindings: net: airoha: Add EN7581 ethernet controller
net: airoha: Introduce ethernet support for EN7581 SoC

 .../bindings/net/airoha,en7581-eth.yaml       |  143 +
 MAINTAINERS                                   |    9 +
 drivers/net/ethernet/mediatek/Kconfig         |   11 +-
 drivers/net/ethernet/mediatek/Makefile        |    1 +
 drivers/net/ethernet/mediatek/airoha_eth.c    | 2771 +++++++++++++++++
 5 files changed, 2934 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/net/airoha,en7581-eth.yaml
 create mode 100644 drivers/net/ethernet/mediatek/airoha_eth.c
Signature · 1 line
2.45.2
author maintainer
#1 lore raw

PATCH v6 1/2 dt-bindings: net: airoha: Add EN7581 ethernet controller

Introduce device-tree binding documentation for Airoha EN7581 ethernet mac controller.

---
 .../bindings/net/airoha,en7581-eth.yaml       | 143 ++++++++++++++++++
 1 file changed, 143 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/airoha,en7581-eth.yaml
Documentation/devicetree/bindings/net/airoha,en7581-eth.yaml new file +143 -0
new file mode 100644
index 000000000000..c578637c5826
@@ -0,0 +1,143 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/airoha,en7581-eth.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Airoha EN7581 Frame Engine Ethernet controller
+
+maintainers:
+  - Lorenzo Bianconi <[email protected]>
+
+description:
+  The frame engine ethernet controller can be found on Airoha SoCs.
+  These SoCs have multi-GMAC ports.
+
+properties:
+  compatible:
+    enum:
+      - airoha,en7581-eth
+
+  reg:
+    items:
+      - description: Frame engine base address
+      - description: QDMA0 base address
+      - description: QDMA1 base address
+
+  reg-names:
+    items:
+      - const: fe
+      - const: qdma0
+      - const: qdma1
+
+  interrupts:
+    items:
+      - description: QDMA lan irq0
+      - description: QDMA lan irq1
+      - description: QDMA lan irq2
+      - description: QDMA lan irq3
+      - description: QDMA wan irq0
+      - description: QDMA wan irq1
+      - description: QDMA wan irq2
+      - description: QDMA wan irq3
+      - description: FE error irq
+      - description: PDMA irq
+
+  resets:
+    maxItems: 8
+
+  reset-names:
+    items:
+      - const: fe
+      - const: pdma
+      - const: qdma
+      - const: xsi-mac
+      - const: hsi0-mac
+      - const: hsi1-mac
+      - const: hsi-mac
+      - const: xfp-mac
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 0
+
+patternProperties:
+  "^ethernet@[1-4]$":
+    type: object
+    unevaluatedProperties: false
+    $ref: ethernet-controller.yaml#
+    description:
+      Ethernet GMAC port associated to the MAC controller
+    properties:
+      compatible:
+        const: airoha,eth-mac
+
+      reg:
+        minimum: 1
+        maximum: 4
+        description: GMAC port identifier
+
+    required:
+      - reg
+      - compatible
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - resets
+  - reset-names
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/clock/en7523-clk.h>
+
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      eth: ethernet@1fb50000 {
+        compatible = "airoha,en7581-eth";
+        reg = <0 0x1fb50000 0 0x2600>,
+              <0 0x1fb54000 0 0x2000>,
+              <0 0x1fb56000 0 0x2000>;
+        reg-names = "fe", "qdma0", "qdma1";
+
+        resets = <&scuclk 44>,
+                 <&scuclk 30>,
+                 <&scuclk 31>,
+                 <&scuclk 6>,
+                 <&scuclk 15>,
+                 <&scuclk 16>,
+                 <&scuclk 17>,
+                 <&scuclk 26>;
+        reset-names = "fe", "pdma", "qdma", "xsi-mac",
+                      "hsi0-mac", "hsi1-mac", "hsi-mac",
+                      "xfp-mac";
+
+        interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        mac: ethernet@1 {
+          compatible = "airoha,eth-mac";
+          reg = <1>;
+        };
+      };
+    };
Signature · 1 line
2.45.2
maintainer Reviewed-by on v6 1/2
#2 lore raw

Re: [PATCH v6 net-next 1/2] dt-bindings: net: airoha: Add EN7581 ethernet controller

Quoted 9 lines · Lorenzo Bianconi

Introduce device-tree binding documentation for Airoha EN7581 ethernet mac controller.

---
 .../bindings/net/airoha,en7581-eth.yaml       | 143 ++++++++++++++++++
 1 file changed, 143 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/airoha,en7581-eth.yaml
author maintainer
#3 lore raw

PATCH v6 2/2 net: airoha: Introduce ethernet support for EN7581 SoC

In reply to Lorenzo Bianconi

Add airoha_eth driver in order to introduce ethernet support for Airoha EN7581 SoC available on EN7581 development board (en7581-evb). en7581-evb networking architecture is composed by airoha_eth as mac controller (cpu port) and a mt7530 dsa based switch.
EN7581 mac controller is mainly composed by Frame Engine (FE) and QoS-DMA (QDMA) modules. FE is used for traffic offloading (just basic functionalities are supported now) while QDMA is used for DMA operation and QOS functionalities between mac layer and the dsa switch (hw QoS is not available yet and it will be added in the future). Currently only hw lan features are available, hw wan will be added with subsequent patches.

---
 MAINTAINERS                                |    9 +
 drivers/net/ethernet/mediatek/Kconfig      |   11 +-
 drivers/net/ethernet/mediatek/Makefile     |    1 +
 drivers/net/ethernet/mediatek/airoha_eth.c | 2771 ++++++++++++++++++++
 4 files changed, 2791 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/ethernet/mediatek/airoha_eth.c
MAINTAINERS +9 -0
index e0f28278e504..520e002433e1 100644
@@ -682,6 +682,15 @@ S:	Supported
 F:	fs/aio.c
 F:	include/linux/*aio*.h
 
+AIROHA ETHERNET DRIVER
+M:	Lorenzo Bianconi <[email protected]>
+L:	[email protected] (moderated for non-subscribers)
+L:	[email protected] (moderated for non-subscribers)
+L:	[email protected]
+S:	Maintained
+F:	Documentation/devicetree/bindings/net/airoha,en7581-eth.yaml
+F:	drivers/net/ethernet/mediatek/airoha_eth.c
+
 AIROHA SPI SNFI DRIVER
 M:	Lorenzo Bianconi <[email protected]>
 M:	Ray Liu <[email protected]>
drivers/net/ethernet/mediatek/Kconfig +10 -1
index da0db417ab69..e16d0ea5d418 100644
@@ -1,12 +1,21 @@
 # SPDX-License-Identifier: GPL-2.0-only
 config NET_VENDOR_MEDIATEK
 	bool "MediaTek devices"
-	depends on ARCH_MEDIATEK || SOC_MT7621 || SOC_MT7620 || COMPILE_TEST
+	depends on ARCH_MEDIATEK || ARCH_AIROHA || SOC_MT7621 || SOC_MT7620 || COMPILE_TEST
 	help
 	  If you have a Mediatek SoC with ethernet, say Y.
 
 if NET_VENDOR_MEDIATEK
 
+config NET_AIROHA
+	tristate "Airoha SoC Gigabit Ethernet support"
+	depends on NET_DSA || !NET_DSA
+	select PAGE_POOL
+	select PAGE_POOL_STATS
+	help
+	  This driver supports the gigabit ethernet MACs in the
+	  Airoha SoC family.
+
 config NET_MEDIATEK_SOC_WED
 	depends on ARCH_MEDIATEK || COMPILE_TEST
 	def_bool NET_MEDIATEK_SOC != n
drivers/net/ethernet/mediatek/Makefile +1 -0
index 03e008fbc859..ddbb7f4a516c 100644
@@ -11,3 +11,4 @@ mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_debugfs.o
 endif
 obj-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_ops.o
 obj-$(CONFIG_NET_MEDIATEK_STAR_EMAC) += mtk_star_emac.o
+obj-$(CONFIG_NET_AIROHA) += airoha_eth.o
drivers/net/ethernet/mediatek/airoha_eth.c new file +2771 -0

2,771 lines not on this page · raw message

Signature · 1 line
2.45.2
reviewer Reviewed-by on v6 2/2
#4 lore raw

Re: [PATCH v6 net-next 2/2] net: airoha: Introduce ethernet support for EN7581 SoC

Quoted 12 lines · Lorenzo Bianconi

Add airoha_eth driver in order to introduce ethernet support for Airoha EN7581 SoC available on EN7581 development board (en7581-evb). en7581-evb networking architecture is composed by airoha_eth as mac controller (cpu port) and a mt7530 dsa based switch.
EN7581 mac controller is mainly composed by Frame Engine (FE) and QoS-DMA (QDMA) modules. FE is used for traffic offloading (just basic functionalities are supported now) while QDMA is used for DMA operation and QOS functionalities between mac layer and the dsa switch (hw QoS is not available yet and it will be added in the future). Currently only hw lan features are available, hw wan will be added with subsequent patches.

Quoted 2 lines
Reviewed-by on v6 2/2
#5 lore raw

Re: [PATCH v6 net-next 2/2] net: airoha: Introduce ethernet support for EN7581 SoC

In reply to Lorenzo Bianconi

drivers/net/ethernet/mediatek/airoha_eth.c line 1544

Quoted 13 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +13 -0
+static int airoha_qdma_init_rx_queue(struct airoha_eth *eth,
+				     struct airoha_queue *q, int ndesc)
+{
+	struct page_pool_params pp_params = {
+		.order = 0,
+		.pool_size = 256,
+		.flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV,
+		.dma_dir = DMA_FROM_DEVICE,
+		.max_len = PAGE_SIZE,
+		.nid = NUMA_NO_NODE,
+		.dev = eth->dev,
+		.napi = &q->napi,
+	};

I think you can make this const.

Quoted 4 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +3 -0
+static int airoha_alloc_gdm_port(struct airoha_eth *eth, struct device_node *np)
+{
 
+	port = netdev_priv(dev);

drivers/net/ethernet/mediatek/airoha_eth.c line 2629

Quoted 10 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +10 -0
+	mutex_init(&port->stats.mutex);
+	port->dev = dev;
+	port->eth = eth;
+	port->id = id;
+
+	err = register_netdev(dev);
+	if (err)
+		return err;
+
+	eth->ports[index] = port;

eth->ports[index] appears to be used in airoha_qdma_rx_process(). There is a small race condition here, since the interface could be in use before register_netdev() returns, e.g. NFS root. It would be better to do the assignment before registering the interface.

These are quite minor, so please add to the next version:

Andrew

---
pw-bot: cr

author maintainer
#6 lore raw

Re: [PATCH v6 net-next 2/2] net: airoha: Introduce ethernet support for EN7581 SoC

Quoted 7 lines
Quoted 7 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +7 -0
+static int airoha_qdma_init_rx_queue(struct airoha_eth *eth,
+				     struct airoha_queue *q, int ndesc)
+{
+	struct page_pool_params pp_params = {
+		.order = 0,
+		.pool_size = 256,
+		.flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV,
Quoted 8 lines

drivers/net/ethernet/mediatek/airoha_eth.c line 1544

Quoted 6 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +6 -0
+		.dma_dir = DMA_FROM_DEVICE,
+		.max_len = PAGE_SIZE,
+		.nid = NUMA_NO_NODE,
+		.dev = eth->dev,
+		.napi = &q->napi,
+	};

I think you can make this const.

ack

Quoted 13 lines
Quoted 13 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +11 -0
+static int airoha_alloc_gdm_port(struct airoha_eth *eth, struct device_node *np)
+{
 
+	port = netdev_priv(dev);
+	mutex_init(&port->stats.mutex);
+	port->dev = dev;
+	port->eth = eth;
+	port->id = id;
+
+	err = register_netdev(dev);
+	if (err)
+		return err;
Quoted 8 lines

drivers/net/ethernet/mediatek/airoha_eth.c line 2629

Quoted 2 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +2 -0
+
+	eth->ports[index] = port;

eth->ports[index] appears to be used in airoha_qdma_rx_process(). There is a small race condition here, since the interface could be in use before register_netdev() returns, e.g. NFS root. It would be better to do the assignment before registering the interface.

actually I check eth->ports[] is not NULL before accessing it in airoha_qdma_rx_process():

	p = airoha_qdma_get_gdm_port(eth, desc);
	if (p < 0 || !eth->ports[p]) {
		...
	}

Moreover, in airoha_alloc_gdm_port(), I set eth->ports[index] pointer just if register_netdev() is successful in order to avoid to call unregister_netdev() on an not-registered net_device in the airoha_probe() error path. I guess we can even check reg_state for this:

	for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
		...
		if (dev->reg_state == NETREG_REGISTERED)
			unregister_netdev(dev);
	}

What do you prefer?

Regards,
Lorenzo

Quoted 9 lines

These are quite minor, so please add to the next version:

Andrew

---
pw-bot: cr

#7 lore raw

Re: [PATCH v6 net-next 2/2] net: airoha: Introduce ethernet support for EN7581 SoC

Quoted 21 lines
Quoted 12 lines
Quoted 12 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +11 -0
+static int airoha_alloc_gdm_port(struct airoha_eth *eth, struct device_node *np)
+{
 
+	port = netdev_priv(dev);
+	mutex_init(&port->stats.mutex);
+	port->dev = dev;
+	port->eth = eth;
+	port->id = id;
+
+	err = register_netdev(dev);
+	if (err)
+		return err;
Quoted 8 lines

drivers/net/ethernet/mediatek/airoha_eth.c line 2629

Quoted 2 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +2 -0
+
+	eth->ports[index] = port;

eth->ports[index] appears to be used in airoha_qdma_rx_process(). There is a small race condition here, since the interface could be in use before register_netdev() returns, e.g. NFS root. It would be better to do the assignment before registering the interface.

Quoted 7 lines

actually I check eth->ports[] is not NULL before accessing it in airoha_qdma_rx_process():

	p = airoha_qdma_get_gdm_port(eth, desc);
	if (p < 0 || !eth->ports[p]) {
		...
	}

Yes, you check it is not NULL, so you don't de-reference anything. But i did not spend enough time to check if you leek something as a result of it being NULL?

Quoted 10 lines

Moreover, in airoha_alloc_gdm_port(), I set eth->ports[index] pointer just if register_netdev() is successful in order to avoid to call unregister_netdev() on an not-registered net_device in the airoha_probe() error path. I guess we can even check reg_state for this:

	for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
		...
		if (dev->reg_state == NETREG_REGISTERED)
			unregister_netdev(dev);
	}

I prefer checking reg_state. Problems with this race condition are hard to track down, so it is better to not have it in the first place.

Andrew