]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: ath11k: clear shared SRNG pointer state on restart
authorKyle Farnung <kfarnung@gmail.com>
Thu, 14 May 2026 04:52:12 +0000 (21:52 -0700)
committerJeff Johnson <jeff.johnson@oss.qualcomm.com>
Mon, 18 May 2026 13:47:03 +0000 (06:47 -0700)
LMAC rings reuse the shared rdp/wrp pointer buffers without going
through the normal SRNG hw-init path that zeros non-LMAC ring
pointers. After restart, ath11k_hal_srng_clear() can therefore hand
stale hp/tp state from the previous firmware instance back to the new
one.

Clear the shared pointer buffers while keeping the allocations in
place so restart still avoids reallocating SRNG DMA memory, but starts
with fresh ring-pointer state.

Fixes: 32be3ca4cf78b ("wifi: ath11k: HAL SRNG: don't deinitialize and re-initialize again")
Cc: stable@vger.kernel.org
Closes: https://lore.kernel.org/all/CAOPSVF04q6uvVdq8GTRLHBrVMdpt9=o9wVcFMc6f-yhmSBcZqQ@mail.gmail.com/
Signed-off-by: Kyle Farnung <kfarnung@gmail.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Link: https://patch.msgid.link/20260513-kfarnung-ath11k-srng-clear-pointer-state-v1-1-bc700dd8b333@gmail.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
drivers/net/wireless/ath/ath11k/hal.c

index e821e5a62c1c0a54b841c26fda49a4c0f1a4e804..98bd9e3f0aae952fd85165cda20ca1dbce22a4c4 100644 (file)
@@ -1387,14 +1387,22 @@ EXPORT_SYMBOL(ath11k_hal_srng_deinit);
 
 void ath11k_hal_srng_clear(struct ath11k_base *ab)
 {
-       /* No need to memset rdp and wrp memory since each individual
-        * segment would get cleared in ath11k_hal_srng_src_hw_init()
-        * and ath11k_hal_srng_dst_hw_init().
+       /*
+        * Preserve the shared pointer buffers, but clear the previous
+        * firmware instance's hp/tp state before handing them back to FW.
+        * LMAC rings reuse this shared memory without going through the
+        * normal SRNG hw-init path that zeros non-LMAC ring pointers.
         */
        memset(ab->hal.srng_list, 0,
               sizeof(ab->hal.srng_list));
        memset(ab->hal.shadow_reg_addr, 0,
               sizeof(ab->hal.shadow_reg_addr));
+       if (ab->hal.rdp.vaddr)
+               memset(ab->hal.rdp.vaddr, 0,
+                      sizeof(*ab->hal.rdp.vaddr) * HAL_SRNG_RING_ID_MAX);
+       if (ab->hal.wrp.vaddr)
+               memset(ab->hal.wrp.vaddr, 0,
+                      sizeof(*ab->hal.wrp.vaddr) * HAL_SRNG_NUM_LMAC_RINGS);
        ab->hal.avail_blk_resource = 0;
        ab->hal.current_blk_index = 0;
        ab->hal.num_shadow_reg_configured = 0;