Skip to contentSkip to conversation

Introduce EN7581 ethernet support

PATCH Superseded Lorenzo Bianconi 2 participants 9 messages Jul 10, 2024 – Jul 12, 2024

Subsystems (5)

v7 of 8 Superseded Latest is v8 →

lore
Share & tools
lore

Lorenzo Bianconi

author maintainer
#0 lore raw

v7 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 v6:
- set eth->ports[] before registering netdevice
- make page_pool_params const
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    | 2768 +++++++++++++++++
 5 files changed, 2931 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 v7 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
author maintainer
#2 lore raw

PATCH v7 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 | 2768 ++++++++++++++++++++
 4 files changed, 2788 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 +2768 -0

2,768 lines not on this page · raw message

Signature · 1 line
2.45.2
maintainer
#3 lore raw

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

Quoted 11 lines · On Wed, 10 Jul 2024 10:47:41 +0200 Lorenzo Bianconi wrote:

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.

It seems a bit unusual for DSA to have multiple ports, isn't it? Can you explain how this driver differs from normal DSA a little more in the commit message?

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

Quoted 6 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +6 -0
+static void airoha_dev_get_stats64(struct net_device *dev,
+				   struct rtnl_link_stats64 *storage)
+{
+	struct airoha_gdm_port *port = netdev_priv(dev);
+
+	mutex_lock(&port->stats.mutex);

can't take sleeping locks here :( Gotta do periodic updates from a workqueue or spinlock. there are callers under RCU (annoyingly)

Quoted 44 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +44 -0
+	airoha_update_hw_stats(port);
+	storage->rx_packets = port->stats.rx_ok_pkts;
+	storage->tx_packets = port->stats.tx_ok_pkts;
+	storage->rx_bytes = port->stats.rx_ok_bytes;
+	storage->tx_bytes = port->stats.tx_ok_bytes;
+	storage->multicast = port->stats.rx_multicast;
+	storage->rx_errors = port->stats.rx_errors;
+	storage->rx_dropped = port->stats.rx_drops;
+	storage->tx_dropped = port->stats.tx_drops;
+	storage->rx_crc_errors = port->stats.rx_crc_error;
+	storage->rx_over_errors = port->stats.rx_over_errors;
+
+	mutex_unlock(&port->stats.mutex);
+}
+
+static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
+				   struct net_device *dev)
+{
+	struct skb_shared_info *sinfo = skb_shinfo(skb);
+	struct airoha_gdm_port *port = netdev_priv(dev);
+	int i, qid = skb_get_queue_mapping(skb);
+	struct airoha_eth *eth = port->eth;
+	u32 nr_frags, msg0 = 0, msg1;
+	u32 len = skb_headlen(skb);
+	struct netdev_queue *txq;
+	struct airoha_queue *q;
+	void *data = skb->data;
+	u16 index;
+	u8 fport;
+
+	if (skb->ip_summed == CHECKSUM_PARTIAL)
+		msg0 |= FIELD_PREP(QDMA_ETH_TXMSG_TCO_MASK, 1) |
+			FIELD_PREP(QDMA_ETH_TXMSG_UCO_MASK, 1) |
+			FIELD_PREP(QDMA_ETH_TXMSG_ICO_MASK, 1);
+
+	/* TSO: fill MSS info in tcp checksum field */
+	if (skb_is_gso(skb)) {
+		if (skb_cow_head(skb, 0))
+			goto error;
+
+		if (sinfo->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) {
+			__be16 csum = cpu_to_be16(sinfo->gso_size);
+
+			tcp_hdr(skb)->check = (__force __sum16)csum;

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

Quoted 10 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +10 -0
+			msg0 |= FIELD_PREP(QDMA_ETH_TXMSG_TSO_MASK, 1);
+		}
+	}
+
+	fport = port->id == 4 ? FE_PSE_PORT_GDM4 : port->id;
+	msg1 = FIELD_PREP(QDMA_ETH_TXMSG_FPORT_MASK, fport) |
+	       FIELD_PREP(QDMA_ETH_TXMSG_METER_MASK, 0x7f);
+
+	if (WARN_ON_ONCE(qid >= ARRAY_SIZE(eth->q_tx)))
+		qid = 0;

Hm, how? Stack should protect against that.

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

Quoted 11 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +11 -0
+	q = &eth->q_tx[qid];
+	if (WARN_ON_ONCE(!q->ndesc))
+		goto error;
+
+	spin_lock_bh(&q->lock);
+
+	nr_frags = 1 + sinfo->nr_frags;
+	if (q->queued + nr_frags > q->ndesc) {
+		/* not enough space in the queue */
+		spin_unlock_bh(&q->lock);
+		return NETDEV_TX_BUSY;

no need to stop the queue?

Quoted 59 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +59 -0
+	}
+
+	index = q->head;
+	for (i = 0; i < nr_frags; i++) {
+		struct airoha_qdma_desc *desc = &q->desc[index];
+		struct airoha_queue_entry *e = &q->entry[index];
+		skb_frag_t *frag = &sinfo->frags[i];
+		dma_addr_t addr;
+		u32 val;
+
+		addr = dma_map_single(dev->dev.parent, data, len,
+				      DMA_TO_DEVICE);
+		if (unlikely(dma_mapping_error(dev->dev.parent, addr)))
+			goto error_unmap;
+
+		index = (index + 1) % q->ndesc;
+
+		val = FIELD_PREP(QDMA_DESC_LEN_MASK, len);
+		if (i < nr_frags - 1)
+			val |= FIELD_PREP(QDMA_DESC_MORE_MASK, 1);
+		WRITE_ONCE(desc->ctrl, cpu_to_le32(val));
+		WRITE_ONCE(desc->addr, cpu_to_le32(addr));
+		val = FIELD_PREP(QDMA_DESC_NEXT_ID_MASK, index);
+		WRITE_ONCE(desc->data, cpu_to_le32(val));
+		WRITE_ONCE(desc->msg0, cpu_to_le32(msg0));
+		WRITE_ONCE(desc->msg1, cpu_to_le32(msg1));
+		WRITE_ONCE(desc->msg2, cpu_to_le32(0xffff));
+
+		e->skb = i ? NULL : skb;
+		e->dma_addr = addr;
+		e->dma_len = len;
+
+		airoha_qdma_rmw(eth, REG_TX_CPU_IDX(qid), TX_RING_CPU_IDX_MASK,
+				FIELD_PREP(TX_RING_CPU_IDX_MASK, index));
+
+		data = skb_frag_address(frag);
+		len = skb_frag_size(frag);
+	}
+
+	q->head = index;
+	q->queued += i;
+
+	txq = netdev_get_tx_queue(dev, qid);
+	netdev_tx_sent_queue(txq, skb->len);
+	skb_tx_timestamp(skb);
+
+	if (q->ndesc - q->queued < q->free_thr)
+		netif_tx_stop_queue(txq);
+
+	spin_unlock_bh(&q->lock);
+
+	return NETDEV_TX_OK;
+
+error_unmap:
+	for (i--; i >= 0; i++)
+		dma_unmap_single(dev->dev.parent, q->entry[i].dma_addr,
+				 q->entry[i].dma_len, DMA_TO_DEVICE);
+
+	spin_unlock_bh(&q->lock);

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

Quoted 10 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +10 -0
+error:
+	dev_kfree_skb_any(skb);
+	dev->stats.tx_dropped++;
+
+	return NETDEV_TX_OK;
+}
+
+static const char * const airoha_ethtool_stats_name[] = {
+	"tx_eth_bc_cnt",
+	"tx_eth_mc_cnt",

struct ethtool_eth_mac_stats

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

Quoted 8 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +8 -0
+	"tx_eth_lt64_cnt",
+	"tx_eth_eq64_cnt",
+	"tx_eth_65_127_cnt",
+	"tx_eth_128_255_cnt",
+	"tx_eth_256_511_cnt",
+	"tx_eth_512_1023_cnt",
+	"tx_eth_1024_1518_cnt",
+	"tx_eth_gt1518_cnt",

struct ethtool_rmon_stats

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

Quoted 3 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +3 -0
+	"rx_eth_bc_cnt",
+	"rx_eth_frag_cnt",
+	"rx_eth_jabber_cnt",

those are also covered.. somewhere..

Quoted 63 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +63 -0
+	"rx_eth_fc_drops",
+	"rx_eth_rc_drops",
+	"rx_eth_lt64_cnt",
+	"rx_eth_eq64_cnt",
+	"rx_eth_65_127_cnt",
+	"rx_eth_128_255_cnt",
+	"rx_eth_256_511_cnt",
+	"rx_eth_512_1023_cnt",
+	"rx_eth_1024_1518_cnt",
+	"rx_eth_gt1518_cnt",
+};
+
+static void airoha_ethtool_get_drvinfo(struct net_device *dev,
+				       struct ethtool_drvinfo *info)
+{
+	struct airoha_gdm_port *port = netdev_priv(dev);
+	struct airoha_eth *eth = port->eth;
+
+	strscpy(info->driver, eth->dev->driver->name, sizeof(info->driver));
+	strscpy(info->bus_info, dev_name(eth->dev), sizeof(info->bus_info));
+	info->n_stats = ARRAY_SIZE(airoha_ethtool_stats_name) +
+			page_pool_ethtool_stats_get_count();
+}
+
+static void airoha_ethtool_get_strings(struct net_device *dev, u32 sset,
+				       u8 *data)
+{
+	int i;
+
+	if (sset != ETH_SS_STATS)
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(airoha_ethtool_stats_name); i++)
+		ethtool_puts(&data, airoha_ethtool_stats_name[i]);
+
+	page_pool_ethtool_stats_get_strings(data);
+}
+
+static int airoha_ethtool_get_sset_count(struct net_device *dev, int sset)
+{
+	if (sset != ETH_SS_STATS)
+		return -EOPNOTSUPP;
+
+	return ARRAY_SIZE(airoha_ethtool_stats_name) +
+	       page_pool_ethtool_stats_get_count();
+}
+
+static void airoha_ethtool_get_stats(struct net_device *dev,
+				     struct ethtool_stats *stats, u64 *data)
+{
+	int off = offsetof(struct airoha_hw_stats, tx_broadcast) / sizeof(u64);
+	struct airoha_gdm_port *port = netdev_priv(dev);
+	u64 *hw_stats = (u64 *)&port->stats + off;
+	struct page_pool_stats pp_stats = {};
+	struct airoha_eth *eth = port->eth;
+	int i;
+
+	BUILD_BUG_ON(ARRAY_SIZE(airoha_ethtool_stats_name) + off !=
+		     sizeof(struct airoha_hw_stats) / sizeof(u64));
+
+	mutex_lock(&port->stats.mutex);
+
+	airoha_update_hw_stats(port);

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

Quoted 10 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +10 -0
+	for (i = 0; i < ARRAY_SIZE(airoha_ethtool_stats_name); i++)
+		*data++ = hw_stats[i];
+
+	for (i = 0; i < ARRAY_SIZE(eth->q_rx); i++) {
+		if (!eth->q_rx[i].ndesc)
+			continue;
+
+		page_pool_get_stats(eth->q_rx[i].page_pool, &pp_stats);
+	}
+	page_pool_ethtool_stats_get(data, &pp_stats);

We can't use the netlink stats because of the shared DMA / shared device? mlxsw had a similar problem recently:

https://lore.kernel.org/all/[email protected]/

Can we list the stats without a netdev or add a new netlink attr to describe such devices? BTW setting pp->netdev to an unregistered device is probably a bad idea, we should add a WARN_ON() for that if we don't have one 😮️

Quoted 5 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +5 -0
+	for_each_child_of_node(pdev->dev.of_node, np) {
+		if (!of_device_is_compatible(np, "airoha,eth-mac"))
+			continue;
+
+		if (!of_device_is_available(np))

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

Quoted 10 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +10 -0
+			continue;
+
+		err = airoha_alloc_gdm_port(eth, np);
+		if (err) {
+			of_node_put(np);
+			goto error;
+		}
+	}
+
+	airoha_qdma_start_napi(eth);

Are you sure starting the NAPI after registration is safe? Nothing will go wrong if interface gets opened before airoha_qdma_start_napi() gets to run?

Also you don't seem to call napi_disable(), NAPI can reschedule itself, and netif_napi_del() doesn't wait for quiescence.

author maintainer
#4 lore raw

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

Quoted 13 lines · On Wed, 10 Jul 2024 10:47:41 +0200 Lorenzo Bianconi wrote:
Quoted 11 lines

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 3 lines

It seems a bit unusual for DSA to have multiple ports, isn't it? Can you explain how this driver differs from normal DSA a little more in the commit message?

The Airoha eth SoC architecture is similar to mtk_eth_soc one (e.g MT7988a). The FrameEngine (FE) module has multiple GDM ports that are connected to different blocks. Current airoha_eth driver supports just GDM1 that is connected to a MT7530 DSA switch (I have not posted a tiny patch for mt7530 driver yet). In the future we will support even GDM{2,3,4} that will connect to differ phy modues (e.g. 2.5Gbps phy).

Quoted 10 lines

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

Quoted 7 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +6 -0
+static void airoha_dev_get_stats64(struct net_device *dev,
+				   struct rtnl_link_stats64 *storage)
+{
+	struct airoha_gdm_port *port = netdev_priv(dev);
+
+	mutex_lock(&port->stats.mutex);

can't take sleeping locks here :( Gotta do periodic updates from a workqueue or spinlock. there are callers under RCU (annoyingly)

ack, I will fix it in v8

Quoted 49 lines
Quoted 49 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +48 -0
+	airoha_update_hw_stats(port);
+	storage->rx_packets = port->stats.rx_ok_pkts;
+	storage->tx_packets = port->stats.tx_ok_pkts;
+	storage->rx_bytes = port->stats.rx_ok_bytes;
+	storage->tx_bytes = port->stats.tx_ok_bytes;
+	storage->multicast = port->stats.rx_multicast;
+	storage->rx_errors = port->stats.rx_errors;
+	storage->rx_dropped = port->stats.rx_drops;
+	storage->tx_dropped = port->stats.tx_drops;
+	storage->rx_crc_errors = port->stats.rx_crc_error;
+	storage->rx_over_errors = port->stats.rx_over_errors;
+
+	mutex_unlock(&port->stats.mutex);
+}
+
+static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
+				   struct net_device *dev)
+{
+	struct skb_shared_info *sinfo = skb_shinfo(skb);
+	struct airoha_gdm_port *port = netdev_priv(dev);
+	int i, qid = skb_get_queue_mapping(skb);
+	struct airoha_eth *eth = port->eth;
+	u32 nr_frags, msg0 = 0, msg1;
+	u32 len = skb_headlen(skb);
+	struct netdev_queue *txq;
+	struct airoha_queue *q;
+	void *data = skb->data;
+	u16 index;
+	u8 fport;
+
+	if (skb->ip_summed == CHECKSUM_PARTIAL)
+		msg0 |= FIELD_PREP(QDMA_ETH_TXMSG_TCO_MASK, 1) |
+			FIELD_PREP(QDMA_ETH_TXMSG_UCO_MASK, 1) |
+			FIELD_PREP(QDMA_ETH_TXMSG_ICO_MASK, 1);
+
+	/* TSO: fill MSS info in tcp checksum field */
+	if (skb_is_gso(skb)) {
+		if (skb_cow_head(skb, 0))
+			goto error;
+
+		if (sinfo->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) {
+			__be16 csum = cpu_to_be16(sinfo->gso_size);
+
+			tcp_hdr(skb)->check = (__force __sum16)csum;
+			msg0 |= FIELD_PREP(QDMA_ETH_TXMSG_TSO_MASK, 1);
+		}
+	}
+
Quoted 8 lines

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

Quoted 6 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +6 -0
+	fport = port->id == 4 ? FE_PSE_PORT_GDM4 : port->id;
+	msg1 = FIELD_PREP(QDMA_ETH_TXMSG_FPORT_MASK, fport) |
+	       FIELD_PREP(QDMA_ETH_TXMSG_METER_MASK, 0x7f);
+
+	if (WARN_ON_ONCE(qid >= ARRAY_SIZE(eth->q_tx)))
+		qid = 0;

Hm, how? Stack should protect against that.

ack, I will fix it in v8

Quoted 14 lines

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

Quoted 12 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +11 -0
+	q = &eth->q_tx[qid];
+	if (WARN_ON_ONCE(!q->ndesc))
+		goto error;
+
+	spin_lock_bh(&q->lock);
+
+	nr_frags = 1 + sinfo->nr_frags;
+	if (q->queued + nr_frags > q->ndesc) {
+		/* not enough space in the queue */
+		spin_unlock_bh(&q->lock);
+		return NETDEV_TX_BUSY;

no need to stop the queue?

reviewing this chunk, I guess we can get rid of it since we already block the txq at the end of airoha_dev_xmit() if we do not have enough space for the next packet:

	if (q->ndesc - q->queued < q->free_thr)
		netif_tx_stop_queue(txq);
Quoted 84 lines
Quoted 60 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +59 -0
+	}
+
+	index = q->head;
+	for (i = 0; i < nr_frags; i++) {
+		struct airoha_qdma_desc *desc = &q->desc[index];
+		struct airoha_queue_entry *e = &q->entry[index];
+		skb_frag_t *frag = &sinfo->frags[i];
+		dma_addr_t addr;
+		u32 val;
+
+		addr = dma_map_single(dev->dev.parent, data, len,
+				      DMA_TO_DEVICE);
+		if (unlikely(dma_mapping_error(dev->dev.parent, addr)))
+			goto error_unmap;
+
+		index = (index + 1) % q->ndesc;
+
+		val = FIELD_PREP(QDMA_DESC_LEN_MASK, len);
+		if (i < nr_frags - 1)
+			val |= FIELD_PREP(QDMA_DESC_MORE_MASK, 1);
+		WRITE_ONCE(desc->ctrl, cpu_to_le32(val));
+		WRITE_ONCE(desc->addr, cpu_to_le32(addr));
+		val = FIELD_PREP(QDMA_DESC_NEXT_ID_MASK, index);
+		WRITE_ONCE(desc->data, cpu_to_le32(val));
+		WRITE_ONCE(desc->msg0, cpu_to_le32(msg0));
+		WRITE_ONCE(desc->msg1, cpu_to_le32(msg1));
+		WRITE_ONCE(desc->msg2, cpu_to_le32(0xffff));
+
+		e->skb = i ? NULL : skb;
+		e->dma_addr = addr;
+		e->dma_len = len;
+
+		airoha_qdma_rmw(eth, REG_TX_CPU_IDX(qid), TX_RING_CPU_IDX_MASK,
+				FIELD_PREP(TX_RING_CPU_IDX_MASK, index));
+
+		data = skb_frag_address(frag);
+		len = skb_frag_size(frag);
+	}
+
+	q->head = index;
+	q->queued += i;
+
+	txq = netdev_get_tx_queue(dev, qid);
+	netdev_tx_sent_queue(txq, skb->len);
+	skb_tx_timestamp(skb);
+
+	if (q->ndesc - q->queued < q->free_thr)
+		netif_tx_stop_queue(txq);
+
+	spin_unlock_bh(&q->lock);
+
+	return NETDEV_TX_OK;
+
+error_unmap:
+	for (i--; i >= 0; i++)
+		dma_unmap_single(dev->dev.parent, q->entry[i].dma_addr,
+				 q->entry[i].dma_len, DMA_TO_DEVICE);
+
+	spin_unlock_bh(&q->lock);

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

Quoted 10 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +10 -0
+error:
+	dev_kfree_skb_any(skb);
+	dev->stats.tx_dropped++;
+
+	return NETDEV_TX_OK;
+}
+
+static const char * const airoha_ethtool_stats_name[] = {
+	"tx_eth_bc_cnt",
+	"tx_eth_mc_cnt",

struct ethtool_eth_mac_stats

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

Quoted 8 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +8 -0
+	"tx_eth_lt64_cnt",
+	"tx_eth_eq64_cnt",
+	"tx_eth_65_127_cnt",
+	"tx_eth_128_255_cnt",
+	"tx_eth_256_511_cnt",
+	"tx_eth_512_1023_cnt",
+	"tx_eth_1024_1518_cnt",
+	"tx_eth_gt1518_cnt",

struct ethtool_rmon_stats

Quoted 5 lines

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

Quoted 3 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +3 -0
+	"rx_eth_bc_cnt",
+	"rx_eth_frag_cnt",
+	"rx_eth_jabber_cnt",

those are also covered.. somewhere..

ack, I guess we can use .get_eth_mac_stats() and .get_rmon_stats() callbacks and get rid of .get_ethtool_stats() one since it will duplicate stats otherwise.

Quoted 78 lines
Quoted 64 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +63 -0
+	"rx_eth_fc_drops",
+	"rx_eth_rc_drops",
+	"rx_eth_lt64_cnt",
+	"rx_eth_eq64_cnt",
+	"rx_eth_65_127_cnt",
+	"rx_eth_128_255_cnt",
+	"rx_eth_256_511_cnt",
+	"rx_eth_512_1023_cnt",
+	"rx_eth_1024_1518_cnt",
+	"rx_eth_gt1518_cnt",
+};
+
+static void airoha_ethtool_get_drvinfo(struct net_device *dev,
+				       struct ethtool_drvinfo *info)
+{
+	struct airoha_gdm_port *port = netdev_priv(dev);
+	struct airoha_eth *eth = port->eth;
+
+	strscpy(info->driver, eth->dev->driver->name, sizeof(info->driver));
+	strscpy(info->bus_info, dev_name(eth->dev), sizeof(info->bus_info));
+	info->n_stats = ARRAY_SIZE(airoha_ethtool_stats_name) +
+			page_pool_ethtool_stats_get_count();
+}
+
+static void airoha_ethtool_get_strings(struct net_device *dev, u32 sset,
+				       u8 *data)
+{
+	int i;
+
+	if (sset != ETH_SS_STATS)
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(airoha_ethtool_stats_name); i++)
+		ethtool_puts(&data, airoha_ethtool_stats_name[i]);
+
+	page_pool_ethtool_stats_get_strings(data);
+}
+
+static int airoha_ethtool_get_sset_count(struct net_device *dev, int sset)
+{
+	if (sset != ETH_SS_STATS)
+		return -EOPNOTSUPP;
+
+	return ARRAY_SIZE(airoha_ethtool_stats_name) +
+	       page_pool_ethtool_stats_get_count();
+}
+
+static void airoha_ethtool_get_stats(struct net_device *dev,
+				     struct ethtool_stats *stats, u64 *data)
+{
+	int off = offsetof(struct airoha_hw_stats, tx_broadcast) / sizeof(u64);
+	struct airoha_gdm_port *port = netdev_priv(dev);
+	u64 *hw_stats = (u64 *)&port->stats + off;
+	struct page_pool_stats pp_stats = {};
+	struct airoha_eth *eth = port->eth;
+	int i;
+
+	BUILD_BUG_ON(ARRAY_SIZE(airoha_ethtool_stats_name) + off !=
+		     sizeof(struct airoha_hw_stats) / sizeof(u64));
+
+	mutex_lock(&port->stats.mutex);
+
+	airoha_update_hw_stats(port);

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

Quoted 10 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +10 -0
+	for (i = 0; i < ARRAY_SIZE(airoha_ethtool_stats_name); i++)
+		*data++ = hw_stats[i];
+
+	for (i = 0; i < ARRAY_SIZE(eth->q_rx); i++) {
+		if (!eth->q_rx[i].ndesc)
+			continue;
+
+		page_pool_get_stats(eth->q_rx[i].page_pool, &pp_stats);
+	}
+	page_pool_ethtool_stats_get(data, &pp_stats);

We can't use the netlink stats because of the shared DMA / shared device? mlxsw had a similar problem recently:

Quoted 6 lines

https://lore.kernel.org/all/[email protected]/

Can we list the stats without a netdev or add a new netlink attr to describe such devices? BTW setting pp->netdev to an unregistered device is probably a bad idea, we should add a WARN_ON() for that if we don't have one 😮️

ack, we have the same architecture here, rx queues/page_pools are shared between net_devices. So far I used page_pool stats just for debugging so I will remove them for the moment till we have a good/defined solution for this kind of architecture.

Quoted 21 lines
Quoted 6 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +5 -0
+	for_each_child_of_node(pdev->dev.of_node, np) {
+		if (!of_device_is_compatible(np, "airoha,eth-mac"))
+			continue;
+
+		if (!of_device_is_available(np))

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

Quoted 10 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +10 -0
+			continue;
+
+		err = airoha_alloc_gdm_port(eth, np);
+		if (err) {
+			of_node_put(np);
+			goto error;
+		}
+	}
+
+	airoha_qdma_start_napi(eth);

Are you sure starting the NAPI after registration is safe? Nothing will go wrong if interface gets opened before airoha_qdma_start_napi() gets to run?

Quoted 2 lines

Also you don't seem to call napi_disable(), NAPI can reschedule itself, and netif_napi_del() doesn't wait for quiescence.

ack, I will fix it in v8.

Regards,
Lorenzo

maintainer
#5 lore raw

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

Quoted 17 lines · On Fri, 12 Jul 2024 15:47:38 +0200 Lorenzo Bianconi wrote:
Quoted 13 lines · On Wed, 10 Jul 2024 10:47:41 +0200 Lorenzo Bianconi wrote:
Quoted 11 lines

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 3 lines

It seems a bit unusual for DSA to have multiple ports, isn't it? Can you explain how this driver differs from normal DSA a little more in the commit message?

Quoted 6 lines

The Airoha eth SoC architecture is similar to mtk_eth_soc one (e.g MT7988a). The FrameEngine (FE) module has multiple GDM ports that are connected to different blocks. Current airoha_eth driver supports just GDM1 that is connected to a MT7530 DSA switch (I have not posted a tiny patch for mt7530 driver yet). In the future we will support even GDM{2,3,4} that will connect to differ phy modues (e.g. 2.5Gbps phy).

What I'm confused by is the mentioned of DSA. You put the port in the descriptor, and there can only be one switch on the other side, right?

Quoted 14 lines
Quoted 5 lines
Quoted 5 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +5 -0
+	q = &eth->q_tx[qid];
+	if (WARN_ON_ONCE(!q->ndesc))
+		goto error;
+
+	spin_lock_bh(&q->lock);
Quoted 8 lines

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

Quoted 6 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +6 -0
+
+	nr_frags = 1 + sinfo->nr_frags;
+	if (q->queued + nr_frags > q->ndesc) {
+		/* not enough space in the queue */
+		spin_unlock_bh(&q->lock);
+		return NETDEV_TX_BUSY;  

no need to stop the queue?

Quoted 6 lines

reviewing this chunk, I guess we can get rid of it since we already block the txq at the end of airoha_dev_xmit() if we do not have enough space for the next packet:

	if (q->ndesc - q->queued < q->free_thr)
		netif_tx_stop_queue(txq);

But @q is shared in your case isn't it? Unless we walk and stop all ports this won't save us. Coincidentally not sure how useful BQL can be in a setup like this :( It will have no way to figure out the real egress rate given that each netdev only sees a (non-)random sample of traffic sharing the queue :(

author maintainer
#6 lore raw

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

Quoted 25 lines · On Fri, 12 Jul 2024 15:47:38 +0200 Lorenzo Bianconi wrote:
Quoted 17 lines
Quoted 13 lines · On Wed, 10 Jul 2024 10:47:41 +0200 Lorenzo Bianconi wrote:
Quoted 11 lines

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 3 lines

It seems a bit unusual for DSA to have multiple ports, isn't it? Can you explain how this driver differs from normal DSA a little more in the commit message?

Quoted 6 lines

The Airoha eth SoC architecture is similar to mtk_eth_soc one (e.g MT7988a). The FrameEngine (FE) module has multiple GDM ports that are connected to different blocks. Current airoha_eth driver supports just GDM1 that is connected to a MT7530 DSA switch (I have not posted a tiny patch for mt7530 driver yet). In the future we will support even GDM{2,3,4} that will connect to differ phy modues (e.g. 2.5Gbps phy).

Quoted 2 lines

What I'm confused by is the mentioned of DSA. You put the port in the descriptor, and there can only be one switch on the other side, right?

do you mean fport in msg1 (airoha_dev_xmit())?

	fport = port->id == 4 ? FE_PSE_PORT_GDM4 : port->id;
	msg1 = FIELD_PREP(QDMA_ETH_TXMSG_FPORT_MASK, fport) |
	       ...

fport refers to the GDM port and not to the dsa user port. Am I missing something?

Quoted 19 lines
Quoted 19 lines
Quoted 14 lines

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

Quoted 12 lines
drivers/net/ethernet/mediatek/airoha_eth.c new file +11 -0
+	q = &eth->q_tx[qid];
+	if (WARN_ON_ONCE(!q->ndesc))
+		goto error;
+
+	spin_lock_bh(&q->lock);
+
+	nr_frags = 1 + sinfo->nr_frags;
+	if (q->queued + nr_frags > q->ndesc) {
+		/* not enough space in the queue */
+		spin_unlock_bh(&q->lock);
+		return NETDEV_TX_BUSY;  

no need to stop the queue?

reviewing this chunk, I guess we can get rid of it since we already block the txq at the end of airoha_dev_xmit() if we do not have enough space for the next packet:

Quoted 5 lines
Quoted 2 lines
	if (q->ndesc - q->queued < q->free_thr)
		netif_tx_stop_queue(txq);

But @q is shared in your case isn't it? Unless we walk and stop all ports this won't save us. Coincidentally not sure how useful BQL can

Oh, right. We can theoretically have a packet from another netdevice for the same hw queue. I will stop the queue in this case.

Quoted 3 lines

be in a setup like this :( It will have no way to figure out the real egress rate given that each netdev only sees a (non-)random sample of traffic sharing the queue :(

do you prefer to remove BQL support?

Regards,
Lorenzo

Quoted 2 lines
maintainer
#7 lore raw

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

Quoted 11 lines · On Fri, 12 Jul 2024 16:43:58 +0200 Lorenzo Bianconi wrote:
Quoted 10 lines · On Fri, 12 Jul 2024 15:47:38 +0200 Lorenzo Bianconi wrote:
Quoted 6 lines

The Airoha eth SoC architecture is similar to mtk_eth_soc one (e.g MT7988a). The FrameEngine (FE) module has multiple GDM ports that are connected to different blocks. Current airoha_eth driver supports just GDM1 that is connected to a MT7530 DSA switch (I have not posted a tiny patch for mt7530 driver yet). In the future we will support even GDM{2,3,4} that will connect to differ phy modues (e.g. 2.5Gbps phy).

What I'm confused by is the mentioned of DSA. You put the port in the descriptor, and there can only be one switch on the other side, right?

Quoted 8 lines

do you mean fport in msg1 (airoha_dev_xmit())?

	fport = port->id == 4 ? FE_PSE_PORT_GDM4 : port->id;
	msg1 = FIELD_PREP(QDMA_ETH_TXMSG_FPORT_MASK, fport) |
	       ...

fport refers to the GDM port and not to the dsa user port. Am I missing something?

Ooh, I see, reading what you explained previously now makes sense. So only 1 of the ports goes to the DSA switch, and the other ones are connected to SoC pins? A diagram would be worth a 1000 words ;)

Quoted 5 lines
Quoted 3 lines

be in a setup like this :( It will have no way to figure out the real egress rate given that each netdev only sees a (non-)random sample of traffic sharing the queue :(

do you prefer to remove BQL support?

No strong preference, I worry it will do more harm than good in this case. It's not what it's designed for basically. But without testing it's all speculation, so up to you, users can always disable using sysfs.

author maintainer
#8 lore raw

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

Quoted 18 lines · On Fri, 12 Jul 2024 16:43:58 +0200 Lorenzo Bianconi wrote:
Quoted 17 lines
Quoted 10 lines · On Fri, 12 Jul 2024 15:47:38 +0200 Lorenzo Bianconi wrote:
Quoted 6 lines

The Airoha eth SoC architecture is similar to mtk_eth_soc one (e.g MT7988a). The FrameEngine (FE) module has multiple GDM ports that are connected to different blocks. Current airoha_eth driver supports just GDM1 that is connected to a MT7530 DSA switch (I have not posted a tiny patch for mt7530 driver yet). In the future we will support even GDM{2,3,4} that will connect to differ phy modues (e.g. 2.5Gbps phy).

What I'm confused by is the mentioned of DSA. You put the port in the descriptor, and there can only be one switch on the other side, right?

do you mean fport in msg1 (airoha_dev_xmit())?

	fport = port->id == 4 ? FE_PSE_PORT_GDM4 : port->id;
	msg1 = FIELD_PREP(QDMA_ETH_TXMSG_FPORT_MASK, fport) |
	       ...
Quoted 6 lines
Quoted 2 lines

fport refers to the GDM port and not to the dsa user port. Am I missing something?

Ooh, I see, reading what you explained previously now makes sense. So only 1 of the ports goes to the DSA switch, and the other ones are connected to SoC pins? A diagram would be worth a 1000 words ;)

exactly, just GDM1 FE port is connected to the DSA switch. I will try to do my best for the diagram :)

Quoted 11 lines
Quoted 6 lines
Quoted 4 lines

be in a setup like this :( It will have no way to figure out the real egress rate given that each netdev only sees a (non-)random sample of traffic sharing the queue :(

do you prefer to remove BQL support?

No strong preference, I worry it will do more harm than good in this case. It's not what it's designed for basically. But without testing it's all speculation, so up to you, users can always disable using sysfs.

let me take a look to it again but, if it is not harmful, I would prefer to remove it and add it in the future if necessary.

Regards,
Lorenzo