From: Lorenzo Bianconi Date: Wed, 24 Jun 2026 15:20:54 +0000 (+0200) Subject: airoha: backport additional fixes for ethernet driver X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F23934%2Fhead;p=thirdparty%2Fopenwrt.git airoha: backport additional fixes for ethernet driver Backport fixes for airoha_eth driver from net tree recently merged upstream. Refresh all affected patch. Signed-off-by: Lorenzo Bianconi [ refresh patch, improve commit title/description ] Link: https://github.com/openwrt/openwrt/pull/23934 Signed-off-by: Christian Marangi --- 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 index 00000000000..30591786612 --- /dev/null +++ b/target/linux/airoha/patches-6.18/170-v7.2-net-airoha-Fix-register-index-for-Tx-fwd-counter-con.patch @@ -0,0 +1,37 @@ +From 1402ecccf5630a0b7fa4749d7d2e72abc3f3d73d Mon Sep 17 00:00:00 2001 +Message-ID: <1402ecccf5630a0b7fa4749d7d2e72abc3f3d73d.1782312403.git.lorenzo@kernel.org> +From: "Wayen.Yan" +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 +Acked-by: Lorenzo Bianconi +Link: https://patch.msgid.link/6a2b40e7.4dd82583.3a5c46.e566@mx.google.com +Signed-off-by: Jakub Kicinski +--- + 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 index 00000000000..3a487a44c46 --- /dev/null +++ b/target/linux/airoha/patches-6.18/171-v7.2-net-airoha-Fix-debugfs-new-tuple-display-for-IPv4-RO.patch @@ -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" +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 +Acked-by: Lorenzo Bianconi +Link: https://patch.msgid.link/6a2be54b.ef98c1b2.3c3224.2ed8@mx.google.com +Signed-off-by: Jakub Kicinski +--- + 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 index 00000000000..9851f304349 --- /dev/null +++ b/target/linux/airoha/patches-6.18/172-v7.2-net-airoha-fix-foe_check_time-allocation-size.patch @@ -0,0 +1,34 @@ +From 5c121ee635680c93d7074becf14cfbaac140f80d Mon Sep 17 00:00:00 2001 +Message-ID: <5c121ee635680c93d7074becf14cfbaac140f80d.1782312136.git.lorenzo@kernel.org> +From: Wayen Yan +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 +Acked-by: Lorenzo Bianconi +Link: https://patch.msgid.link/178161119471.2163752.14373384830691569758@gmail.com +Signed-off-by: Jakub Kicinski +--- + 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 index 00000000000..e48937d2b49 --- /dev/null +++ b/target/linux/airoha/patches-6.18/173-v7.2-net-airoha-Fix-non-standard-return-value-in-airoha_p.patch @@ -0,0 +1,31 @@ +From 05173fa30add3787e7ab2e735c4ee00431994259 Mon Sep 17 00:00:00 2001 +Message-ID: <05173fa30add3787e7ab2e735c4ee00431994259.1782312341.git.lorenzo@kernel.org> +From: "Wayen.Yan" +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 +Acked-by: Lorenzo Bianconi +Link: https://patch.msgid.link/6a2ca3d9.ad59c0a6.147df9.2a62@mx.google.com +Signed-off-by: Jakub Kicinski +--- + 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 index 00000000000..4ec30e3850a --- /dev/null +++ b/target/linux/airoha/patches-6.18/174-v7.2-net-airoha-Fix-skb-priority-underflow-in-airoha_dev_.patch @@ -0,0 +1,52 @@ +From 86e51aa24686cc95bb35613059e8b94b9b81e3f0 Mon Sep 17 00:00:00 2001 +Message-ID: <86e51aa24686cc95bb35613059e8b94b9b81e3f0.1782312099.git.lorenzo@kernel.org> +From: Wayen Yan +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 +Reviewed-by: Joe Damato +Signed-off-by: Wayen Yan +Link: https://patch.msgid.link/178194366700.2485734.5368768965976693502@gmail.com +Signed-off-by: Jakub Kicinski +--- + 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 index 00000000000..fcf47bcfe34 --- /dev/null +++ b/target/linux/airoha/patches-6.18/175-v7.2-net-airoha-Fix-TX-scheduler-queue-mask-loop-upper-bo.patch @@ -0,0 +1,50 @@ +From 245043dfc2101e7dc6268bf123b75305a91e4e00 Mon Sep 17 00:00:00 2001 +Message-ID: <245043dfc2101e7dc6268bf123b75305a91e4e00.1782312080.git.lorenzo@kernel.org> +From: Wayen Yan +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 +Signed-off-by: Wayen Yan +Link: https://patch.msgid.link/178187479434.2400840.1312143943526335838@gmail.com +Signed-off-by: Jakub Kicinski +--- + 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 index 00000000000..3b10867ea27 --- /dev/null +++ b/target/linux/airoha/patches-6.18/176-v7.2-net-airoha-Fix-typos-in-comments-and-Kconfig.patch @@ -0,0 +1,68 @@ +From a061dfb063fa03ed09cf21145ffff247cf94721a Mon Sep 17 00:00:00 2001 +Message-ID: +In-Reply-To: <05173fa30add3787e7ab2e735c4ee00431994259.1782312317.git.lorenzo@kernel.org> +References: <05173fa30add3787e7ab2e735c4ee00431994259.1782312317.git.lorenzo@kernel.org> +From: "Wayen.Yan" +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 +Acked-by: Lorenzo Bianconi +Link: https://patch.msgid.link/6a2ca74a.c5b1db4e.21a698.01e7@mx.google.com +Signed-off-by: Jakub Kicinski +--- + 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 index 00000000000..821fd6a9305 --- /dev/null +++ b/target/linux/airoha/patches-6.18/177-v7.2-net-airoha-Fix-off-by-one-in-airoha_tc_remove_htb_qu.patch @@ -0,0 +1,34 @@ +From bfcce49c4aaab9339ef7b9a7fa4d8ac5a19cc820 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Lorenzo Bianconi +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 +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20260619-airoha-qos-fixes-v2-1-5c43485038f9@kernel.org +Signed-off-by: Jakub Kicinski +--- + 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 index 00000000000..532a5851a38 --- /dev/null +++ b/target/linux/airoha/patches-6.18/178-v7.2-net-airoha-fix-netif_set_real_num_tx_queues-for-spar.patch @@ -0,0 +1,84 @@ +From 788663dd28e424639318842ba5ae290672528609 Mon Sep 17 00:00:00 2001 +Message-ID: <788663dd28e424639318842ba5ae290672528609.1782366471.git.lorenzo@kernel.org> +In-Reply-To: +References: +From: Lorenzo Bianconi +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 +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260619-airoha-qos-fixes-v2-2-5c43485038f9@kernel.org +Signed-off-by: Jakub Kicinski +--- + 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, diff --git a/target/linux/airoha/patches-6.18/310-07-airoha-ethernet-drop-xsi-mac-reset.patch b/target/linux/airoha/patches-6.18/310-07-airoha-ethernet-drop-xsi-mac-reset.patch index d6560370d28..2af0f1f9ab3 100644 --- a/target/linux/airoha/patches-6.18/310-07-airoha-ethernet-drop-xsi-mac-reset.patch +++ b/target/linux/airoha/patches-6.18/310-07-airoha-ethernet-drop-xsi-mac-reset.patch @@ -15,7 +15,7 @@ Signed-off-by: Christian Marangi --- 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 "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[] = { diff --git a/target/linux/airoha/patches-6.18/310-10-net-airoha-add-phylink-support.patch b/target/linux/airoha/patches-6.18/310-10-net-airoha-add-phylink-support.patch index de636badfb6..6d6c08b9b21 100644 --- a/target/linux/airoha/patches-6.18/310-10-net-airoha-add-phylink-support.patch +++ b/target/linux/airoha/patches-6.18/310-10-net-airoha-add-phylink-support.patch @@ -110,7 +110,7 @@ Signed-off-by: Christian Marangi 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 .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 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 } 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 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 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); diff --git a/target/linux/airoha/patches-6.18/916-02-net-airoha-Implement-HW-GRO-TCP-support.patch b/target/linux/airoha/patches-6.18/916-02-net-airoha-Implement-HW-GRO-TCP-support.patch index 16513e3c258..a07062d7fda 100644 --- a/target/linux/airoha/patches-6.18/916-02-net-airoha-Implement-HW-GRO-TCP-support.patch +++ b/target/linux/airoha/patches-6.18/916-02-net-airoha-Implement-HW-GRO-TCP-support.patch @@ -535,7 +535,7 @@ Signed-off-by: Lorenzo Bianconi 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 .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; diff --git a/target/linux/airoha/patches-6.18/920-12-net-airoha-defer-GDM3-GDM4-WAN-mode-and-GDM2-loopbac.patch b/target/linux/airoha/patches-6.18/920-12-net-airoha-defer-GDM3-GDM4-WAN-mode-and-GDM2-loopbac.patch index 77b37d54832..757d54db704 100644 --- a/target/linux/airoha/patches-6.18/920-12-net-airoha-defer-GDM3-GDM4-WAN-mode-and-GDM2-loopbac.patch +++ b/target/linux/airoha/patches-6.18/920-12-net-airoha-defer-GDM3-GDM4-WAN-mode-and-GDM2-loopbac.patch @@ -333,7 +333,7 @@ Signed-off-by: Lorenzo Bianconi 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 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 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 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 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 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; } diff --git a/target/linux/airoha/patches-6.18/920-13-net-airoha-Rework-MTU-configuration.patch b/target/linux/airoha/patches-6.18/920-13-net-airoha-Rework-MTU-configuration.patch index 2e854b6f492..1769b583720 100644 --- a/target/linux/airoha/patches-6.18/920-13-net-airoha-Rework-MTU-configuration.patch +++ b/target/linux/airoha/patches-6.18/920-13-net-airoha-Rework-MTU-configuration.patch @@ -143,7 +143,7 @@ Signed-off-by: Lorenzo Bianconi 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 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;