]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: ath12k: Fix invalid IRQ requests during AHB probe
authorAaradhana Sahu <aaradhana.sahu@oss.qualcomm.com>
Tue, 14 Apr 2026 06:28:29 +0000 (11:58 +0530)
committerJeff Johnson <jeff.johnson@oss.qualcomm.com>
Tue, 21 Apr 2026 13:27:53 +0000 (06:27 -0700)
ath12k_ahb_config_ext_irq() iterates over ATH12K_EXT_IRQ_NUM_MAX (16)
entries while checking TX ring masks, but the tcl_to_wbm_rbm_map array
contains only DP_TCL_NUM_RING_MAX (4) valid elements.

When the iterator (j) is greater than or equal to DP_TCL_NUM_RING_MAX,
it accesses tcl_to_wbm_rbm_map[j] out of bounds. This results in
reading uninitialized memory for wbm_ring_num, causing the driver to
evaluate incorrect BIT() conditions and request IRQs for rings that do
not have an assigned interrupt line or device tree entry.

This leads to request_irq() failures with -ENXIO or -EINVAL during
ath12k AHB probe.

Fix this by splitting the loop into two separate loops: one iterating
over DP_TCL_NUM_RING_MAX for TX ring, and another iterating over
ATH12K_EXT_IRQ_NUM_MAX for remaining IRQ entries.
Also add a bounds check for num_irq.

Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.6-01275-QCAHKSWPL_SILICONZ-1

Fixes: 6cee30f0da75 ("wifi: ath12k: add AHB driver support for IPQ5332")
Signed-off-by: Aaradhana Sahu <aaradhana.sahu@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Link: https://patch.msgid.link/20260414062829.2371761-1-aaradhana.sahu@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
drivers/net/wireless/ath/ath12k/ahb.c

index 2dcf0a52e4c15b936907c70ceba392bbfdb72bb6..30733a244454e5528743a6835cb5f8ec7d5962c1 100644 (file)
@@ -583,31 +583,36 @@ static int ath12k_ahb_config_ext_irq(struct ath12k_base *ab)
                netif_napi_add(irq_grp->napi_ndev, &irq_grp->napi,
                               ath12k_ahb_ext_grp_napi_poll);
 
-               for (j = 0; j < ATH12K_EXT_IRQ_NUM_MAX; j++) {
-                       /* For TX ring, ensure that the ring mask and the
-                        * tcl_to_wbm_rbm_map point to the same ring number.
-                        */
+               for (j = 0; j < DP_TCL_NUM_RING_MAX; j++) {
                        if (ring_mask->tx[i] &
-                           BIT(ab->hal.tcl_to_wbm_rbm_map[j].wbm_ring_num)) {
+                           BIT(ab->hal.tcl_to_wbm_rbm_map[j].wbm_ring_num) &&
+                           num_irq < ATH12K_EXT_IRQ_NUM_MAX) {
                                irq_grp->irqs[num_irq++] =
                                        wbm2host_tx_completions_ring1 - j;
                        }
+               }
 
-                       if (ring_mask->rx[i] & BIT(j)) {
+               for (j = 0; j < ATH12K_EXT_IRQ_NUM_MAX; j++) {
+                       if (ring_mask->rx[i] & BIT(j) &&
+                           num_irq < ATH12K_EXT_IRQ_NUM_MAX) {
                                irq_grp->irqs[num_irq++] =
                                        reo2host_destination_ring1 - j;
                        }
 
-                       if (ring_mask->rx_err[i] & BIT(j))
+                       if (ring_mask->rx_err[i] & BIT(j) &&
+                           num_irq < ATH12K_EXT_IRQ_NUM_MAX)
                                irq_grp->irqs[num_irq++] = reo2host_exception;
 
-                       if (ring_mask->rx_wbm_rel[i] & BIT(j))
+                       if (ring_mask->rx_wbm_rel[i] & BIT(j) &&
+                           num_irq < ATH12K_EXT_IRQ_NUM_MAX)
                                irq_grp->irqs[num_irq++] = wbm2host_rx_release;
 
-                       if (ring_mask->reo_status[i] & BIT(j))
+                       if (ring_mask->reo_status[i] & BIT(j) &&
+                           num_irq < ATH12K_EXT_IRQ_NUM_MAX)
                                irq_grp->irqs[num_irq++] = reo2host_status;
 
-                       if (ring_mask->rx_mon_dest[i] & BIT(j))
+                       if (ring_mask->rx_mon_dest[i] & BIT(j) &&
+                           num_irq < ATH12K_EXT_IRQ_NUM_MAX)
                                irq_grp->irqs[num_irq++] =
                                        rxdma2host_monitor_destination_mac1;
                }