[PATCH net-next v2] net: airoha: select QDMA block according LAN/WAN configuration
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: 2026-03-13 16:28:54
Also in:
linux-mediatek, netdev
Subsystem:
airoha ethernet driver, networking drivers, the rest · Maintainers:
Lorenzo Bianconi, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
Before this patch even GDM ports were assigned to QDMA0 while odd GDM ports were using QDMA1, so, based on the DTS configuration, both QDMA0 and QDMA1 can theoretically receive traffic destinated to the host cpu from LAN or WAN GDM ports. Airoha folks reported the hw design assumes the LAN traffic destinated to the host cpu is be forwarded to QDMA0 while traffic received on WAN GDM port is managed by QDMA1. For this reason, select QDMA block according to the GDM port LAN or WAN configuration: - QDMA0 is used for GDM LAN devices - QDMA1 is used for GDM WAN device Assuming a device with three GDM ports, a typical configuration could be: - MT7530 DSA switch -> GDM1 (eth0) -> QDMA0 (LAN traffic) - External PHY -> GDM2 (eth1) -> QDMA1 (WAN traffic) - External PHY -> GDM3 (eth2) -> QDMA0 (LAN traffic) We can then bridge eth0 DSA port (lanX) with eth2 since they all tx/rx LAN traffic. Please note this patch introduces a change not visible to the user since airoha_eth driver currently supports just the internal phy available via the MT7530 DSA switch and there are no WAN interfaces officially supported since PCS/external phy is not merged mainline yet (it will be posted with following patches). Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> --- Changes in v2: - Update commit log. - Link to v1: https://lore.kernel.org/r/20260310-airoha-qdma-lan-wan-mode-v1-1-64ec74dea872@kernel.org (local) --- drivers/net/ethernet/airoha/airoha_eth.c | 18 ++++++++---------- drivers/net/ethernet/airoha/airoha_eth.h | 1 + 2 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 3e9ec5c178f86fdd055e079078a23461edf97951..b4563b5d53bbf174d45548a5efc6fdfb79d33c19 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c@@ -1754,11 +1754,13 @@ static int airhoha_set_gdm2_loopback(struct airoha_gdm_port *port) static int airoha_dev_init(struct net_device *dev) { struct airoha_gdm_port *port = netdev_priv(dev); - struct airoha_qdma *qdma = port->qdma; - struct airoha_eth *eth = qdma->eth; + struct airoha_eth *eth = port->eth; u32 fe_cpu_port; u8 ppe_id; + /* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */ + port->qdma = ð->qdma[!airoha_is_lan_gdm_port(port)]; + port->dev->irq = port->qdma->irq_banks[0].irq; airoha_set_macaddr(port, dev->dev_addr); switch (port->id) {
@@ -1782,7 +1784,7 @@ static int airoha_dev_init(struct net_device *dev) } fallthrough; default: { - u8 qdma_id = qdma - ð->qdma[0]; + u8 qdma_id = port->qdma - ð->qdma[0]; /* For PPE1 select cpu port according to the running QDMA. */ fe_cpu_port = qdma_id ? FE_PSE_PORT_CDM2 : FE_PSE_PORT_CDM1;
@@ -2866,11 +2868,10 @@ bool airoha_is_valid_gdm_port(struct airoha_eth *eth, } static int airoha_alloc_gdm_port(struct airoha_eth *eth, - struct device_node *np, int index) + struct device_node *np) { const __be32 *id_ptr = of_get_property(np, "reg", NULL); struct airoha_gdm_port *port; - struct airoha_qdma *qdma; struct net_device *dev; int err, p; u32 id;
@@ -2901,7 +2902,6 @@ static int airoha_alloc_gdm_port(struct airoha_eth *eth, return -ENOMEM; } - qdma = ð->qdma[index % AIROHA_MAX_NUM_QDMA]; dev->netdev_ops = &airoha_netdev_ops; dev->ethtool_ops = &airoha_ethtool_ops; dev->max_mtu = AIROHA_MAX_MTU;
@@ -2913,7 +2913,6 @@ static int airoha_alloc_gdm_port(struct airoha_eth *eth, dev->features |= dev->hw_features; dev->vlan_features = dev->hw_features; dev->dev.of_node = np; - dev->irq = qdma->irq_banks[0].irq; SET_NETDEV_DEV(dev, eth->dev); /* reserve hw queues for HTB offloading */
@@ -2934,7 +2933,7 @@ static int airoha_alloc_gdm_port(struct airoha_eth *eth, port = netdev_priv(dev); u64_stats_init(&port->stats.syncp); spin_lock_init(&port->stats.lock); - port->qdma = qdma; + port->eth = eth; port->dev = dev; port->id = id; eth->ports[p] = port;
@@ -3034,7 +3033,6 @@ static int airoha_probe(struct platform_device *pdev) for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) airoha_qdma_start_napi(ð->qdma[i]); - i = 0; for_each_child_of_node(pdev->dev.of_node, np) { if (!of_device_is_compatible(np, "airoha,eth-mac")) continue;
@@ -3042,7 +3040,7 @@ static int airoha_probe(struct platform_device *pdev) if (!of_device_is_available(np)) continue; - err = airoha_alloc_gdm_port(eth, np, i++); + err = airoha_alloc_gdm_port(eth, np); if (err) { of_node_put(np); goto error_napi_stop;
diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
index 59ed7569f7c33620ea694ec52384a37e1917eaf8..8cfa94ec084a16d6b2d3c94c404f25904c1150e3 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h@@ -533,6 +533,7 @@ struct airoha_qdma { struct airoha_gdm_port { struct airoha_qdma *qdma; + struct airoha_eth *eth; struct net_device *dev; int id;
--- base-commit: 8f921f61005450589c0bc1a941a5ddde21d9aed9 change-id: 20260310-airoha-qdma-lan-wan-mode-63d322eefef3 Best regards, -- Lorenzo Bianconi [off-list ref]