]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
airoha: backport additional fixes for ethernet driver 23934/head
authorLorenzo Bianconi <lorenzo@kernel.org>
Wed, 24 Jun 2026 15:20:54 +0000 (17:20 +0200)
committerChristian Marangi <ansuelsmth@gmail.com>
Thu, 25 Jun 2026 22:54:40 +0000 (00:54 +0200)
Backport fixes for airoha_eth driver from net tree recently merged
upstream.

Refresh all affected patch.

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
[ refresh patch, improve commit title/description ]
Link: https://github.com/openwrt/openwrt/pull/23934
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
14 files changed:
target/linux/airoha/patches-6.18/170-v7.2-net-airoha-Fix-register-index-for-Tx-fwd-counter-con.patch [new file with mode: 0644]
target/linux/airoha/patches-6.18/171-v7.2-net-airoha-Fix-debugfs-new-tuple-display-for-IPv4-RO.patch [new file with mode: 0644]
target/linux/airoha/patches-6.18/172-v7.2-net-airoha-fix-foe_check_time-allocation-size.patch [new file with mode: 0644]
target/linux/airoha/patches-6.18/173-v7.2-net-airoha-Fix-non-standard-return-value-in-airoha_p.patch [new file with mode: 0644]
target/linux/airoha/patches-6.18/174-v7.2-net-airoha-Fix-skb-priority-underflow-in-airoha_dev_.patch [new file with mode: 0644]
target/linux/airoha/patches-6.18/175-v7.2-net-airoha-Fix-TX-scheduler-queue-mask-loop-upper-bo.patch [new file with mode: 0644]
target/linux/airoha/patches-6.18/176-v7.2-net-airoha-Fix-typos-in-comments-and-Kconfig.patch [new file with mode: 0644]
target/linux/airoha/patches-6.18/177-v7.2-net-airoha-Fix-off-by-one-in-airoha_tc_remove_htb_qu.patch [new file with mode: 0644]
target/linux/airoha/patches-6.18/178-v7.2-net-airoha-fix-netif_set_real_num_tx_queues-for-spar.patch [new file with mode: 0644]
target/linux/airoha/patches-6.18/310-07-airoha-ethernet-drop-xsi-mac-reset.patch
target/linux/airoha/patches-6.18/310-10-net-airoha-add-phylink-support.patch
target/linux/airoha/patches-6.18/916-02-net-airoha-Implement-HW-GRO-TCP-support.patch
target/linux/airoha/patches-6.18/920-12-net-airoha-defer-GDM3-GDM4-WAN-mode-and-GDM2-loopbac.patch
target/linux/airoha/patches-6.18/920-13-net-airoha-Rework-MTU-configuration.patch

diff --git a/target/linux/airoha/patches-6.18/170-v7.2-net-airoha-Fix-register-index-for-Tx-fwd-counter-con.patch b/target/linux/airoha/patches-6.18/170-v7.2-net-airoha-Fix-register-index-for-Tx-fwd-counter-con.patch
new file mode 100644 (file)
index 0000000..3059178
--- /dev/null
@@ -0,0 +1,37 @@
+From 1402ecccf5630a0b7fa4749d7d2e72abc3f3d73d Mon Sep 17 00:00:00 2001
+Message-ID: <1402ecccf5630a0b7fa4749d7d2e72abc3f3d73d.1782312403.git.lorenzo@kernel.org>
+From: "Wayen.Yan" <win847@gmail.com>
+Date: Fri, 12 Jun 2026 07:09:13 +0800
+Subject: [PATCH 1/2] net: airoha: Fix register index for Tx-fwd counter
+ configuration
+
+In airoha_qdma_init_qos_stats(), the Tx-fwd counter configuration
+register uses the same index (i << 1) as the Tx-cpu counter, which
+overwrites the Tx-cpu configuration. The Tx-fwd counter value register
+correctly uses (i << 1) + 1, so the configuration register should use
+the same index.
+
+Fix the REG_CNTR_CFG index from (i << 1) to ((i << 1) + 1) so that
+the Tx-fwd counter is properly configured instead of clobbering the
+Tx-cpu counter config.
+
+Fixes: 20bf7d07c956 ("net: airoha: Add sched ETS offload support")
+Signed-off-by: Wayen.Yan <win847@gmail.com>
+Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://patch.msgid.link/6a2b40e7.4dd82583.3a5c46.e566@mx.google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/airoha/airoha_eth.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/airoha/airoha_eth.c
++++ b/drivers/net/ethernet/airoha/airoha_eth.c
+@@ -1331,7 +1331,7 @@ static void airoha_qdma_init_qos_stats(s
+                              FIELD_PREP(CNTR_CHAN_MASK, i));
+               /* Tx-fwd transferred count */
+               airoha_qdma_wr(qdma, REG_CNTR_VAL((i << 1) + 1), 0);
+-              airoha_qdma_wr(qdma, REG_CNTR_CFG(i << 1),
++              airoha_qdma_wr(qdma, REG_CNTR_CFG((i << 1) + 1),
+                              CNTR_EN_MASK | CNTR_ALL_QUEUE_EN_MASK |
+                              CNTR_ALL_DSCP_RING_EN_MASK |
+                              FIELD_PREP(CNTR_SRC_MASK, 1) |
diff --git a/target/linux/airoha/patches-6.18/171-v7.2-net-airoha-Fix-debugfs-new-tuple-display-for-IPv4-RO.patch b/target/linux/airoha/patches-6.18/171-v7.2-net-airoha-Fix-debugfs-new-tuple-display-for-IPv4-RO.patch
new file mode 100644 (file)
index 0000000..3a487a4
--- /dev/null
@@ -0,0 +1,44 @@
+From 1c3a77471afbb3981af28f7f7c8b2487558e4b00 Mon Sep 17 00:00:00 2001
+Message-ID: <1c3a77471afbb3981af28f7f7c8b2487558e4b00.1782312403.git.lorenzo@kernel.org>
+In-Reply-To: <1402ecccf5630a0b7fa4749d7d2e72abc3f3d73d.1782312403.git.lorenzo@kernel.org>
+References: <1402ecccf5630a0b7fa4749d7d2e72abc3f3d73d.1782312403.git.lorenzo@kernel.org>
+From: "Wayen.Yan" <win847@gmail.com>
+Date: Fri, 12 Jun 2026 07:09:56 +0800
+Subject: [PATCH 2/2] net: airoha: Fix debugfs new-tuple display for IPv4 ROUTE
+ entries
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+In airoha_ppe_debugfs_foe_show(), the second switch statement falls
+through from PPE_PKT_TYPE_IPV4_HNAPT/DSLITE to PPE_PKT_TYPE_IPV4_ROUTE,
+accessing hwe->ipv4.new_tuple for all three types. However, IPv4 ROUTE
+(3-tuple) entries do not contain a valid new_tuple — this field is only
+meaningful for NATted flows (HNAPT/DSLITE). For ROUTE entries, the
+memory at the new_tuple offset holds routing information, not NAT data,
+so displaying "new=" produces garbage output.
+
+Display new_tuple only for HNAPT and DSLITE, and let IPV4_ROUTE fall
+through to the default case.
+
+Fixes: 3fe15c640f38 ("net: airoha: Introduce PPE debugfs support")
+Link: https://lore.kernel.org/6a2b40ea.4dd82583.3a5c46.e5a2@mx.google.com
+Signed-off-by: Wayen.Yan <win847@gmail.com>
+Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://patch.msgid.link/6a2be54b.ef98c1b2.3c3224.2ed8@mx.google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/airoha/airoha_ppe_debugfs.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/net/ethernet/airoha/airoha_ppe_debugfs.c
++++ b/drivers/net/ethernet/airoha/airoha_ppe_debugfs.c
+@@ -121,8 +121,6 @@ static int airoha_ppe_debugfs_foe_show(s
+               case PPE_PKT_TYPE_IPV4_DSLITE:
+                       src_port = &hwe->ipv4.new_tuple.src_port;
+                       dest_port = &hwe->ipv4.new_tuple.dest_port;
+-                      fallthrough;
+-              case PPE_PKT_TYPE_IPV4_ROUTE:
+                       src_addr = &hwe->ipv4.new_tuple.src_ip;
+                       dest_addr = &hwe->ipv4.new_tuple.dest_ip;
+                       seq_puts(m, " new=");
diff --git a/target/linux/airoha/patches-6.18/172-v7.2-net-airoha-fix-foe_check_time-allocation-size.patch b/target/linux/airoha/patches-6.18/172-v7.2-net-airoha-fix-foe_check_time-allocation-size.patch
new file mode 100644 (file)
index 0000000..9851f30
--- /dev/null
@@ -0,0 +1,34 @@
+From 5c121ee635680c93d7074becf14cfbaac140f80d Mon Sep 17 00:00:00 2001
+Message-ID: <5c121ee635680c93d7074becf14cfbaac140f80d.1782312136.git.lorenzo@kernel.org>
+From: Wayen Yan <win847@gmail.com>
+Date: Tue, 16 Jun 2026 19:52:36 +0800
+Subject: [PATCH] net: airoha: fix foe_check_time allocation size
+
+foe_check_time is declared as u16 pointer but was allocated with
+only ppe_num_entries bytes instead of ppe_num_entries * sizeof(u16).
+
+When airoha_ppe_foe_verify_entry() is called with hash >= ppe_num_entries/2,
+it writes beyond the allocated buffer, causing heap buffer overflow and
+potential kernel crash.
+
+Fixes: 6d5b601d52a2 ("net: airoha: ppe: Dynamically allocate foe_check_time array in airoha_ppe struct")
+Signed-off-by: Wayen Yan <win847@gmail.com>
+Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://patch.msgid.link/178161119471.2163752.14373384830691569758@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/airoha/airoha_ppe.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/airoha/airoha_ppe.c
++++ b/drivers/net/ethernet/airoha/airoha_ppe.c
+@@ -1601,7 +1601,8 @@ int airoha_ppe_init(struct airoha_eth *e
+                       return -ENOMEM;
+       }
+-      ppe->foe_check_time = devm_kzalloc(eth->dev, ppe_num_entries,
++      ppe->foe_check_time = devm_kzalloc(eth->dev,
++                                         ppe_num_entries * sizeof(*ppe->foe_check_time),
+                                          GFP_KERNEL);
+       if (!ppe->foe_check_time)
+               return -ENOMEM;
diff --git a/target/linux/airoha/patches-6.18/173-v7.2-net-airoha-Fix-non-standard-return-value-in-airoha_p.patch b/target/linux/airoha/patches-6.18/173-v7.2-net-airoha-Fix-non-standard-return-value-in-airoha_p.patch
new file mode 100644 (file)
index 0000000..e48937d
--- /dev/null
@@ -0,0 +1,31 @@
+From 05173fa30add3787e7ab2e735c4ee00431994259 Mon Sep 17 00:00:00 2001
+Message-ID: <05173fa30add3787e7ab2e735c4ee00431994259.1782312341.git.lorenzo@kernel.org>
+From: "Wayen.Yan" <win847@gmail.com>
+Date: Sat, 13 Jun 2026 08:22:31 +0800
+Subject: [PATCH] net: airoha: Fix non-standard return value in
+ airoha_ppe_get_wdma_info()
+
+airoha_ppe_get_wdma_info() returns -1 when the last path in the
+forwarding path stack is not of type DEV_PATH_MTK_WDMA. This is not
+a standard kernel error code. Replace it with -EINVAL since the
+input path type is invalid from the caller's perspective.
+
+Signed-off-by: Wayen.Yan <win847@gmail.com>
+Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://patch.msgid.link/6a2ca3d9.ad59c0a6.147df9.2a62@mx.google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/airoha/airoha_ppe.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/airoha/airoha_ppe.c
++++ b/drivers/net/ethernet/airoha/airoha_ppe.c
+@@ -277,7 +277,7 @@ static int airoha_ppe_get_wdma_info(stru
+       path = &stack.path[stack.num_paths - 1];
+       if (path->type != DEV_PATH_MTK_WDMA)
+-              return -1;
++              return -EINVAL;
+       info->idx = path->mtk_wdma.wdma_idx;
+       info->bss = path->mtk_wdma.bss;
diff --git a/target/linux/airoha/patches-6.18/174-v7.2-net-airoha-Fix-skb-priority-underflow-in-airoha_dev_.patch b/target/linux/airoha/patches-6.18/174-v7.2-net-airoha-Fix-skb-priority-underflow-in-airoha_dev_.patch
new file mode 100644 (file)
index 0000000..4ec30e3
--- /dev/null
@@ -0,0 +1,52 @@
+From 86e51aa24686cc95bb35613059e8b94b9b81e3f0 Mon Sep 17 00:00:00 2001
+Message-ID: <86e51aa24686cc95bb35613059e8b94b9b81e3f0.1782312099.git.lorenzo@kernel.org>
+From: Wayen Yan <win847@gmail.com>
+Date: Sat, 20 Jun 2026 16:17:44 +0800
+Subject: [PATCH] net: airoha: Fix skb->priority underflow in
+ airoha_dev_select_queue()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+In airoha_dev_select_queue(), the expression:
+
+  queue = (skb->priority - 1) % AIROHA_NUM_QOS_QUEUES;
+
+implicitly converts to unsigned arithmetic: when skb->priority is 0
+(the default for unclassified traffic), (0u - 1u) wraps to UINT_MAX,
+and UINT_MAX % 8 = 7, routing default best-effort packets to the
+highest-priority QoS queue. This causes QoS inversion where the
+majority of traffic on a PON gateway starves actual high-priority
+flows (VoIP, gaming, etc.).
+
+The "- 1" offset was a leftover from the ETS offload implementation
+that has since been removed. The correct mapping is a direct modulo:
+
+  queue = skb->priority % AIROHA_NUM_QOS_QUEUES;
+
+This maps priority 0 → queue 0 (lowest), priority 7 → queue 7
+(highest), with higher priorities wrapping around. This is the
+standard Linux sk_prio → HW queue mapping used by other drivers.
+
+Fixes: 2b288b81560b ("net: airoha: Introduce ndo_select_queue callback")
+Link: https://lore.kernel.org/netdev/178185573207.2378135.3729126358670287878@gmail.com/
+Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Reviewed-by: Joe Damato <joe@dama.to>
+Signed-off-by: Wayen Yan <win847@gmail.com>
+Link: https://patch.msgid.link/178194366700.2485734.5368768965976693502@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/airoha/airoha_eth.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/airoha/airoha_eth.c
++++ b/drivers/net/ethernet/airoha/airoha_eth.c
+@@ -2110,7 +2110,7 @@ static u16 airoha_dev_select_queue(struc
+        */
+       channel = netdev_uses_dsa(netdev) ? skb_get_queue_mapping(skb) : port->id;
+       channel = channel % AIROHA_NUM_QOS_CHANNELS;
+-      queue = (skb->priority - 1) % AIROHA_NUM_QOS_QUEUES; /* QoS queue */
++      queue = skb->priority % AIROHA_NUM_QOS_QUEUES;
+       queue = channel * AIROHA_NUM_QOS_QUEUES + queue;
+       return queue < netdev->num_tx_queues ? queue : 0;
diff --git a/target/linux/airoha/patches-6.18/175-v7.2-net-airoha-Fix-TX-scheduler-queue-mask-loop-upper-bo.patch b/target/linux/airoha/patches-6.18/175-v7.2-net-airoha-Fix-TX-scheduler-queue-mask-loop-upper-bo.patch
new file mode 100644 (file)
index 0000000..fcf47bc
--- /dev/null
@@ -0,0 +1,50 @@
+From 245043dfc2101e7dc6268bf123b75305a91e4e00 Mon Sep 17 00:00:00 2001
+Message-ID: <245043dfc2101e7dc6268bf123b75305a91e4e00.1782312080.git.lorenzo@kernel.org>
+From: Wayen Yan <win847@gmail.com>
+Date: Fri, 19 Jun 2026 21:12:06 +0800
+Subject: [PATCH] net: airoha: Fix TX scheduler queue mask loop upper bound
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+In airoha_qdma_set_chan_tx_sched(), the loop clearing queue mask was
+using AIROHA_NUM_TX_RING (32) instead of AIROHA_NUM_QOS_QUEUES (8).
+
+Each channel has 8 queues, and TXQ_DISABLE_CHAN_QUEUE_MASK(channel, i)
+computes BIT(i + (channel * 8)). With i ranging 0..31, this causes:
+- channel 0: clears bit 0..31 (all 4 channels) instead of 0..7
+- channel 1: clears bit 8..31 (channels 1-3) instead of 8..15
+- channel 2: clears bit 16..31 (channels 2-3) instead of 16..23
+- channel 3: clears bit 24..31 (channel 3 only) - correct by accident
+
+While BIT(32+) on arm64 produces 64-bit values truncated to 0 in u32
+mask parameter, the loop still incorrectly clears queues within the
+same channel beyond queue 7.
+
+Even though this is functionally harmless (the register resets to 0
+and is only ever cleared, never set — so clearing extra bits is a
+no-op), the loop bound is semantically wrong and should be fixed for
+correctness and clarity.
+
+Fix by using AIROHA_NUM_QOS_QUEUES (8) as the loop upper bound.
+
+Fixes: ef1ca9271313 ("net: airoha: Add sched HTB offload support")
+Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Wayen Yan <win847@gmail.com>
+Link: https://patch.msgid.link/178187479434.2400840.1312143943526335838@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/airoha/airoha_eth.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/airoha/airoha_eth.c
++++ b/drivers/net/ethernet/airoha/airoha_eth.c
+@@ -2395,7 +2395,7 @@ static int airoha_qdma_set_chan_tx_sched
+       struct airoha_gdm_dev *dev = netdev_priv(netdev);
+       int i;
+-      for (i = 0; i < AIROHA_NUM_TX_RING; i++)
++      for (i = 0; i < AIROHA_NUM_QOS_QUEUES; i++)
+               airoha_qdma_clear(dev->qdma, REG_QUEUE_CLOSE_CFG(channel),
+                                 TXQ_DISABLE_CHAN_QUEUE_MASK(channel, i));
diff --git a/target/linux/airoha/patches-6.18/176-v7.2-net-airoha-Fix-typos-in-comments-and-Kconfig.patch b/target/linux/airoha/patches-6.18/176-v7.2-net-airoha-Fix-typos-in-comments-and-Kconfig.patch
new file mode 100644 (file)
index 0000000..3b10867
--- /dev/null
@@ -0,0 +1,68 @@
+From a061dfb063fa03ed09cf21145ffff247cf94721a Mon Sep 17 00:00:00 2001
+Message-ID: <a061dfb063fa03ed09cf21145ffff247cf94721a.1782312317.git.lorenzo@kernel.org>
+In-Reply-To: <05173fa30add3787e7ab2e735c4ee00431994259.1782312317.git.lorenzo@kernel.org>
+References: <05173fa30add3787e7ab2e735c4ee00431994259.1782312317.git.lorenzo@kernel.org>
+From: "Wayen.Yan" <win847@gmail.com>
+Date: Sat, 13 Jun 2026 08:41:16 +0800
+Subject: [PATCH 2/2] net: airoha: Fix typos in comments and Kconfig
+
+Fix several typos found during code review:
+- Kconfig: "Aiorha" -> "Airoha" in NET_AIROHA_FLOW_STATS help text
+- Comment: "CMD1" -> "CDM1" (Central DMA, not Command)
+- Comments: "GMD1/2/3/4" -> "GDM1/2/3/4" (Gigabit DMA, not GMD)
+
+These are pure comment and documentation fixes with no functional impact.
+
+Signed-off-by: Wayen.Yan <win847@gmail.com>
+Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://patch.msgid.link/6a2ca74a.c5b1db4e.21a698.01e7@mx.google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/airoha/Kconfig      |  2 +-
+ drivers/net/ethernet/airoha/airoha_eth.c | 10 +++++-----
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/ethernet/airoha/Kconfig
++++ b/drivers/net/ethernet/airoha/Kconfig
+@@ -29,6 +29,6 @@ config NET_AIROHA_FLOW_STATS
+       bool "Airoha flow stats"
+       depends on NET_AIROHA && NET_AIROHA_NPU
+       help
+-        Enable Aiorha flowtable statistic counters.
++        Enable Airoha flowtable statistic counters.
+ endif #NET_VENDOR_AIROHA
+--- a/drivers/net/ethernet/airoha/airoha_eth.c
++++ b/drivers/net/ethernet/airoha/airoha_eth.c
+@@ -344,18 +344,18 @@ static void airoha_fe_pse_ports_init(str
+                             FIELD_PREP(PSE_ALLRSV_MASK, all_rsv));
+       }
+-      /* CMD1 */
++      /* CDM1 */
+       for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_CDM1]; q++)
+               airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM1, q,
+                                        PSE_QUEUE_RSV_PAGES);
+-      /* GMD1 */
++      /* GDM1 */
+       for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_GDM1]; q++)
+               airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM1, q,
+                                        PSE_QUEUE_RSV_PAGES);
+-      /* GMD2 */
++      /* GDM2 */
+       for (q = 6; q < pse_port_num_queues[FE_PSE_PORT_GDM2]; q++)
+               airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM2, q, 0);
+-      /* GMD3 */
++      /* GDM3 */
+       for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_GDM3]; q++)
+               airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM3, q,
+                                        PSE_QUEUE_RSV_PAGES);
+@@ -390,7 +390,7 @@ static void airoha_fe_pse_ports_init(str
+                                                        q, 0);
+               }
+       }
+-      /* GMD4 */
++      /* GDM4 */
+       for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_GDM4]; q++)
+               airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM4, q,
+                                        PSE_QUEUE_RSV_PAGES);
diff --git a/target/linux/airoha/patches-6.18/177-v7.2-net-airoha-Fix-off-by-one-in-airoha_tc_remove_htb_qu.patch b/target/linux/airoha/patches-6.18/177-v7.2-net-airoha-Fix-off-by-one-in-airoha_tc_remove_htb_qu.patch
new file mode 100644 (file)
index 0000000..821fd6a
--- /dev/null
@@ -0,0 +1,34 @@
+From bfcce49c4aaab9339ef7b9a7fa4d8ac5a19cc820 Mon Sep 17 00:00:00 2001
+Message-ID: <bfcce49c4aaab9339ef7b9a7fa4d8ac5a19cc820.1782366471.git.lorenzo@kernel.org>
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Fri, 19 Jun 2026 13:37:13 +0200
+Subject: [PATCH 1/2] net: airoha: Fix off-by-one in
+ airoha_tc_remove_htb_queue()
+
+airoha_tc_htb_alloc_leaf_queue() computes the HTB QoS channel index
+as opt->classid % AIROHA_NUM_QOS_CHANNELS and stores it in qos_sq_bmap.
+However, airoha_tc_remove_htb_queue() clears the HTB configuration
+using queue + 1 as the channel index, causing an off-by-one error.
+Use queue directly as the QoS channel index to match the allocation
+logic.
+
+Fixes: ef1ca9271313b ("net: airoha: Add sched HTB offload support")
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://patch.msgid.link/20260619-airoha-qos-fixes-v2-1-5c43485038f9@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/airoha/airoha_eth.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/airoha/airoha_eth.c
++++ b/drivers/net/ethernet/airoha/airoha_eth.c
+@@ -3006,7 +3006,7 @@ static void airoha_tc_remove_htb_queue(s
+       struct airoha_qdma *qdma = dev->qdma;
+       netif_set_real_num_tx_queues(netdev, netdev->real_num_tx_queues - 1);
+-      airoha_qdma_set_tx_rate_limit(netdev, queue + 1, 0, 0);
++      airoha_qdma_set_tx_rate_limit(netdev, queue, 0, 0);
+       clear_bit(queue, qdma->qos_channel_map);
+       clear_bit(queue, dev->qos_sq_bmap);
diff --git a/target/linux/airoha/patches-6.18/178-v7.2-net-airoha-fix-netif_set_real_num_tx_queues-for-spar.patch b/target/linux/airoha/patches-6.18/178-v7.2-net-airoha-fix-netif_set_real_num_tx_queues-for-spar.patch
new file mode 100644 (file)
index 0000000..532a585
--- /dev/null
@@ -0,0 +1,84 @@
+From 788663dd28e424639318842ba5ae290672528609 Mon Sep 17 00:00:00 2001
+Message-ID: <788663dd28e424639318842ba5ae290672528609.1782366471.git.lorenzo@kernel.org>
+In-Reply-To: <bfcce49c4aaab9339ef7b9a7fa4d8ac5a19cc820.1782366471.git.lorenzo@kernel.org>
+References: <bfcce49c4aaab9339ef7b9a7fa4d8ac5a19cc820.1782366471.git.lorenzo@kernel.org>
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Fri, 19 Jun 2026 13:37:14 +0200
+Subject: [PATCH 2/2] net: airoha: fix netif_set_real_num_tx_queues for sparse
+ QoS channels
+
+airoha_tc_htb_alloc_leaf_queue() assigns queue IDs based on the channel
+index (opt->qid = AIROHA_NUM_TX_RING + channel), but updates
+real_num_tx_queues with a simple increment (num_tx_queues + 1). When QoS
+channels are allocated sparsely (e.g., channels 0 and 3 without 1 and
+2), the returned qid can exceed real_num_tx_queues, causing out-of-bounds
+accesses in the networking stack.
+For example, allocating channel 0 then channel 3 results in
+real_num_tx_queues = 34 but qid = 35, which is out of range [0, 34).
+Fix this by computing real_num_tx_queues based on the highest active
+channel index rather than using a simple counter, in both the allocation
+and deletion paths.
+
+Fixes: ef1ca9271313b ("net: airoha: Add sched HTB offload support")
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260619-airoha-qos-fixes-v2-2-5c43485038f9@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/airoha/airoha_eth.c | 25 +++++++++++++++---------
+ 1 file changed, 16 insertions(+), 9 deletions(-)
+
+--- a/drivers/net/ethernet/airoha/airoha_eth.c
++++ b/drivers/net/ethernet/airoha/airoha_eth.c
+@@ -2789,7 +2789,7 @@ static int airoha_tc_htb_alloc_leaf_queu
+                                         struct tc_htb_qopt_offload *opt)
+ {
+       u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
+-      int err, num_tx_queues = netdev->real_num_tx_queues;
++      int err, num_tx_queues = AIROHA_NUM_TX_RING + channel + 1;
+       struct airoha_gdm_dev *dev = netdev_priv(netdev);
+       struct airoha_qdma *qdma = dev->qdma;
+@@ -2806,13 +2806,15 @@ static int airoha_tc_htb_alloc_leaf_queu
+       if (err)
+               goto error;
+-      err = netif_set_real_num_tx_queues(netdev, num_tx_queues + 1);
+-      if (err) {
+-              airoha_qdma_set_tx_rate_limit(netdev, channel, 0,
+-                                            opt->quantum);
+-              NL_SET_ERR_MSG_MOD(opt->extack,
+-                                 "failed setting real_num_tx_queues");
+-              goto error;
++      if (num_tx_queues > netdev->real_num_tx_queues) {
++              err = netif_set_real_num_tx_queues(netdev, num_tx_queues);
++              if (err) {
++                      airoha_qdma_set_tx_rate_limit(netdev, channel, 0,
++                                                    opt->quantum);
++                      NL_SET_ERR_MSG_MOD(opt->extack,
++                                         "failed setting real_num_tx_queues");
++                      goto error;
++              }
+       }
+       set_bit(channel, dev->qos_sq_bmap);
+@@ -3003,13 +3005,18 @@ static int airoha_dev_setup_tc_block(str
+ static void airoha_tc_remove_htb_queue(struct net_device *netdev, int queue)
+ {
+       struct airoha_gdm_dev *dev = netdev_priv(netdev);
++      int num_tx_queues = AIROHA_NUM_TX_RING;
+       struct airoha_qdma *qdma = dev->qdma;
+-      netif_set_real_num_tx_queues(netdev, netdev->real_num_tx_queues - 1);
+       airoha_qdma_set_tx_rate_limit(netdev, queue, 0, 0);
+       clear_bit(queue, qdma->qos_channel_map);
+       clear_bit(queue, dev->qos_sq_bmap);
++
++      if (!bitmap_empty(dev->qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS))
++              num_tx_queues += find_last_bit(dev->qos_sq_bmap,
++                                             AIROHA_NUM_QOS_CHANNELS) + 1;
++      netif_set_real_num_tx_queues(netdev, num_tx_queues);
+ }
+ static int airoha_tc_htb_delete_leaf_queue(struct net_device *netdev,
index d6560370d28c16ad3f0818bb4f975d83e9480270..2af0f1f9ab328a767538c6e16c45c88c1d5f6460 100644 (file)
@@ -15,7 +15,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
 
 --- a/drivers/net/ethernet/airoha/airoha_eth.c
 +++ b/drivers/net/ethernet/airoha/airoha_eth.c
-@@ -3511,7 +3511,6 @@ static void airoha_remove(struct platfor
+@@ -3518,7 +3518,6 @@ static void airoha_remove(struct platfor
  }
  
  static const char * const en7581_xsi_rsts_names[] = {
@@ -23,7 +23,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
        "hsi0-mac",
        "hsi1-mac",
        "hsi-mac",
-@@ -3598,7 +3597,6 @@ static int airoha_en7581_get_dev_from_sp
+@@ -3605,7 +3604,6 @@ static int airoha_en7581_get_dev_from_sp
  }
  
  static const char * const an7583_xsi_rsts_names[] = {
index de636badfb60c33e66d132b0600ca54c56a91c87..6d6c08b9b218a8e8d8076989dbc5b2f2cd708c13 100644 (file)
@@ -110,7 +110,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
  static int airoha_qdma_set_chan_tx_sched(struct net_device *netdev,
                                         int channel, enum tx_sched_mode mode,
                                         const u16 *weights, u8 n_weights)
-@@ -3119,7 +3149,8 @@ static const struct ethtool_ops airoha_e
+@@ -3126,7 +3156,8 @@ static const struct ethtool_ops airoha_e
        .get_drvinfo            = airoha_ethtool_get_drvinfo,
        .get_eth_mac_stats      = airoha_ethtool_get_mac_stats,
        .get_rmon_stats         = airoha_ethtool_get_rmon_stats,
@@ -120,7 +120,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
        .get_link               = ethtool_op_get_link,
  };
  
-@@ -3175,6 +3206,159 @@ bool airoha_is_valid_gdm_dev(struct airo
+@@ -3182,6 +3213,159 @@ bool airoha_is_valid_gdm_dev(struct airo
        return false;
  }
  
@@ -280,7 +280,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
  static int airoha_alloc_gdm_device(struct airoha_eth *eth,
                                   struct airoha_gdm_port *port,
                                   int nbq, struct device_node *np)
-@@ -3238,7 +3422,7 @@ static int airoha_alloc_gdm_device(struc
+@@ -3245,7 +3429,7 @@ static int airoha_alloc_gdm_device(struc
        dev->nbq = nbq;
        port->devs[index] = dev;
  
@@ -289,7 +289,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
  }
  
  static int airoha_alloc_gdm_port(struct airoha_eth *eth,
-@@ -3273,7 +3457,7 @@ static int airoha_alloc_gdm_port(struct
+@@ -3280,7 +3464,7 @@ static int airoha_alloc_gdm_port(struct
                return -ENOMEM;
  
        port->id = id;
@@ -298,7 +298,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
        eth->ports[p] = port;
  
        err = airoha_metadata_dst_alloc(port);
-@@ -3464,6 +3648,8 @@ error_napi_stop:
+@@ -3471,6 +3655,8 @@ error_napi_stop:
                        netdev = netdev_from_priv(dev);
                        if (netdev->reg_state == NETREG_REGISTERED)
                                unregister_netdev(netdev);
@@ -307,7 +307,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
                        of_node_put(netdev->dev.of_node);
                }
                airoha_metadata_dst_free(port);
-@@ -3500,6 +3686,7 @@ static void airoha_remove(struct platfor
+@@ -3507,6 +3693,7 @@ static void airoha_remove(struct platfor
  
                        netdev = netdev_from_priv(dev);
                        unregister_netdev(netdev);
index 16513e3c25849cc32a8776188025420828ed001c..a07062d7fda255aa658d4c084fc8136d1366df9c 100644 (file)
@@ -535,7 +535,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
                                   struct net_device *netdev)
  {
-@@ -3139,6 +3449,8 @@ static const struct net_device_ops airoh
+@@ -3146,6 +3456,8 @@ static const struct net_device_ops airoh
        .ndo_stop               = airoha_dev_stop,
        .ndo_change_mtu         = airoha_dev_change_mtu,
        .ndo_select_queue       = airoha_dev_select_queue,
@@ -544,7 +544,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        .ndo_start_xmit         = airoha_dev_xmit,
        .ndo_get_stats64        = airoha_dev_get_stats64,
        .ndo_set_mac_address    = airoha_dev_set_macaddr,
-@@ -3380,11 +3692,9 @@ static int airoha_alloc_gdm_device(struc
+@@ -3387,11 +3699,9 @@ static int airoha_alloc_gdm_device(struc
        netdev->ethtool_ops = &airoha_ethtool_ops;
        netdev->max_mtu = AIROHA_MAX_MTU;
        netdev->watchdog_timeo = 5 * HZ;
index 77b37d54832618d55eb93d82face53dad14fc5d2..757d54db704eff9ecd1e346965ce15e556bb3e58 100644 (file)
@@ -333,7 +333,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        int i;
  
 +      qdma = airoha_qdma_deref(dev);
-       for (i = 0; i < AIROHA_NUM_TX_RING; i++)
+       for (i = 0; i < AIROHA_NUM_QOS_QUEUES; i++)
 -              airoha_qdma_clear(dev->qdma, REG_QUEUE_CLOSE_CFG(channel),
 +              airoha_qdma_clear(qdma, REG_QUEUE_CLOSE_CFG(channel),
                                  TXQ_DISABLE_CHAN_QUEUE_MASK(channel, i));
@@ -407,7 +407,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                if (err)
 @@ -3138,11 +3234,12 @@ static int airoha_tc_htb_alloc_leaf_queu
        u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
-       int err, num_tx_queues = netdev->real_num_tx_queues;
+       int err, num_tx_queues = AIROHA_NUM_TX_RING + channel + 1;
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
 -      struct airoha_qdma *qdma = dev->qdma;
 +      struct airoha_qdma *qdma;
@@ -419,7 +419,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        if (test_and_set_bit(channel, qdma->qos_channel_map)) {
                NL_SET_ERR_MSG_MOD(opt->extack,
                                   "qdma qos channel already in use");
-@@ -3176,7 +3273,7 @@ static int airoha_qdma_set_rx_meter(stru
+@@ -3178,7 +3275,7 @@ static int airoha_qdma_set_rx_meter(stru
                                    u32 rate, u32 bucket_size,
                                    enum trtcm_unit_type unit_type)
  {
@@ -428,21 +428,20 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        int i;
  
        for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
-@@ -3350,11 +3447,12 @@ static int airoha_dev_setup_tc_block(str
- static void airoha_tc_remove_htb_queue(struct net_device *netdev, int queue)
+@@ -3353,10 +3450,11 @@ static void airoha_tc_remove_htb_queue(s
  {
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
+       int num_tx_queues = AIROHA_NUM_TX_RING;
 -      struct airoha_qdma *qdma = dev->qdma;
 +      struct airoha_qdma *qdma;
  
-       netif_set_real_num_tx_queues(netdev, netdev->real_num_tx_queues - 1);
-       airoha_qdma_set_tx_rate_limit(netdev, queue + 1, 0, 0);
+       airoha_qdma_set_tx_rate_limit(netdev, queue, 0, 0);
  
 +      qdma = airoha_qdma_deref(dev);
        clear_bit(queue, qdma->qos_channel_map);
        clear_bit(queue, dev->qos_sq_bmap);
- }
-@@ -3375,6 +3473,95 @@ static int airoha_tc_htb_delete_leaf_que
+@@ -3382,6 +3480,95 @@ static int airoha_tc_htb_delete_leaf_que
        return 0;
  }
  
@@ -538,7 +537,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  static int airoha_tc_htb_destroy(struct net_device *netdev)
  {
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
-@@ -3383,6 +3570,8 @@ static int airoha_tc_htb_destroy(struct
+@@ -3390,6 +3577,8 @@ static int airoha_tc_htb_destroy(struct
        for_each_set_bit(q, dev->qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS)
                airoha_tc_remove_htb_queue(netdev, q);
  
@@ -547,7 +546,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        return 0;
  }
  
-@@ -3402,24 +3591,33 @@ static int airoha_tc_get_htb_get_leaf_qu
+@@ -3409,24 +3598,33 @@ static int airoha_tc_get_htb_get_leaf_qu
        return 0;
  }
  
index 2e854b6f4929089747d21b0a07ac10a694e6aebc..1769b58372090ca965182580fa71a5a59632d84f 100644 (file)
@@ -143,7 +143,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
        return 0;
  }
-@@ -3490,6 +3465,7 @@ static void airoha_disable_qos_for_gdm34
+@@ -3497,6 +3472,7 @@ static void airoha_disable_qos_for_gdm34
  
        dev->flags &= ~AIROHA_PRIV_F_WAN;
        airoha_dev_set_qdma(dev);
@@ -151,7 +151,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
        airoha_set_macaddr(dev, netdev->dev_addr);
        if (netif_running(netdev))
-@@ -3538,6 +3514,7 @@ static int airoha_enable_qos_for_gdm34(s
+@@ -3545,6 +3521,7 @@ static int airoha_enable_qos_for_gdm34(s
        if (err)
                goto error_disable_loopback;