Pārlūkot izejas kodu

qcacmn: Fix delay req queue not update to date issue

Delay write of SRNG regs may happen on different CPUs.
Sometimes wmb may not sufficient to protect the update
in sequence.

So to fix update issue sleep and retry before checking
again for update.

CRs-Fixed: 3717683
Change-Id: I6c7916f91ecefa8175d3e3d9108d018fc8a42cfc
Amit Mehta 1 gadu atpakaļ
vecāks
revīzija
1c3aaa5b19
1 mainītis faili ar 12 papildinājumiem un 3 dzēšanām
  1. 12 3
      hal/wifi3.0/hal_srng.c

+ 12 - 3
hal/wifi3.0/hal_srng.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -796,6 +796,8 @@ static inline bool hal_reg_write_need_delay(struct hal_reg_write_q_elem *elem)
 }
 #endif
 
+#define MAX_DELAYED_REG_WRITE_RETRY 5
+
 /**
  * hal_reg_write_work() - Worker to process delayed writes
  * @arg: hal_soc pointer
@@ -811,6 +813,7 @@ static void hal_reg_write_work(void *arg)
 	uint8_t ring_id;
 	uint32_t *addr;
 	uint32_t num_processed = 0;
+	uint8_t retry_count = 0;
 
 	q_elem = &hal->reg_write_queue[(hal->read_idx)];
 	q_elem->work_scheduled_time = qdf_get_log_timestamp();
@@ -843,9 +846,14 @@ static void hal_reg_write_work(void *arg)
 		if (qdf_unlikely(!q_elem->srng ||
 				 (qdf_atomic_read(&q_elem->ring_id) !=
 				 q_elem->srng->ring_id))) {
-			hal_err_rl("q_elem fields not up to date %d %d",
-				   q_elem->srng->ring_id,
+			hal_err_rl("q_elem fields not up to date 0x%x 0x%x",
+				   q_elem->srng ? q_elem->srng->ring_id : 0xDEAD,
 				   qdf_atomic_read(&q_elem->ring_id));
+			if (retry_count++ < MAX_DELAYED_REG_WRITE_RETRY) {
+				/* Sleep for 1ms before retry */
+				qdf_sleep(1);
+				continue;
+			}
 			qdf_assert_always(0);
 		}
 
@@ -876,6 +884,7 @@ static void hal_reg_write_work(void *arg)
 		hal->read_idx = (hal->read_idx + 1) &
 					(HAL_REG_WRITE_QUEUE_LEN - 1);
 		q_elem = &hal->reg_write_queue[(hal->read_idx)];
+		retry_count = 0;
 	}
 
 	hif_allow_link_low_power_states(hal->hif_handle);