Ver código fonte

qcacmn: Reo-Cmd: Donot write to reg if no src desc

For reo_cmd ring, in current implementation, we call hal_srng_access_end
in case a descriptor is not available before baling out. This may cause
a write to the shadow register for the reo_cmd ring. In case we are in
the middle of WOW, this can be problematic.
Modify existing implementation to use hal_srng_access_end_reap, which
will not schedule a write to the register and simply return.

Change-Id: Ifb83d904e39b3d749522cd246a5ab3fe51a3104e
CRs-Fixed: 3194289
Mohit Khanna 3 anos atrás
pai
commit
04bf8070da
4 arquivos alterados com 92 adições e 60 exclusões
  1. 1 1
      dp/wifi3.0/dp_types.h
  2. 28 57
      hal/wifi3.0/be/hal_be_reo.c
  3. 34 1
      hal/wifi3.0/hal_api.h
  4. 29 1
      hal/wifi3.0/hal_srng.c

+ 1 - 1
dp/wifi3.0/dp_types.h

@@ -991,7 +991,7 @@ struct reo_desc_deferred_freelist_node {
 struct reo_cmd_event_record {
 	enum hal_reo_cmd_type cmd_type;
 	uint8_t cmd_return_status;
-	uint32_t timestamp;
+	uint64_t timestamp;
 };
 
 /**

+ 28 - 57
hal/wifi3.0/be/hal_be_reo.c

@@ -284,7 +284,7 @@ void hal_set_ba_aging_timeout_be(hal_soc_handle_t hal_soc_hdl, uint8_t ac,
 }
 qdf_export_symbol(hal_set_ba_aging_timeout_be);
 
-static inline void
+static void
 hal_reo_cmd_set_descr_addr_be(uint32_t *reo_desc,
 			      enum hal_reo_cmd_type type,
 			      uint32_t paddr_lo,
@@ -322,7 +322,7 @@ hal_reo_cmd_set_descr_addr_be(uint32_t *reo_desc,
 	}
 }
 
-static inline int
+static int
 hal_reo_cmd_queue_stats_be(hal_ring_handle_t  hal_ring_hdl,
 			   hal_soc_handle_t hal_soc_hdl,
 			   struct hal_reo_cmd_params *cmd)
@@ -333,9 +333,8 @@ hal_reo_cmd_queue_stats_be(hal_ring_handle_t  hal_ring_hdl,
 	hal_srng_access_start(hal_soc_hdl, hal_ring_hdl);
 	reo_desc = hal_srng_src_get_next(hal_soc, hal_ring_hdl);
 	if (!reo_desc) {
-		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
-			  "%s: Out of cmd ring entries", __func__);
-		hal_srng_access_end(hal_soc, hal_ring_hdl);
+		hal_srng_access_end_reap(hal_soc, hal_ring_hdl);
+		hal_warn_rl("Out of cmd ring entries");
 		return -EBUSY;
 	}
 
@@ -361,23 +360,15 @@ hal_reo_cmd_queue_stats_be(hal_ring_handle_t  hal_ring_hdl,
 	HAL_DESC_64_SET_FIELD(reo_desc, REO_GET_QUEUE_STATS, CLEAR_STATS,
 			      cmd->u.stats_params.clear);
 
-	if (hif_pm_runtime_get(hal_soc->hif_handle,
-			       RTPM_ID_HAL_REO_CMD, true) == 0) {
-		hal_srng_access_end(hal_soc_hdl, hal_ring_hdl);
-		hif_pm_runtime_put(hal_soc->hif_handle,
-				   RTPM_ID_HAL_REO_CMD);
-	} else {
-		hal_srng_access_end_reap(hal_soc_hdl, hal_ring_hdl);
-		hal_srng_set_event(hal_ring_hdl, HAL_SRNG_FLUSH_EVENT);
-		hal_srng_inc_flush_cnt(hal_ring_hdl);
-	}
+	hal_srng_access_end_v1(hal_soc_hdl, hal_ring_hdl, RTPM_ID_HAL_REO_CMD,
+			       true);
 
 	val = reo_desc[CMD_HEADER_DW_OFFSET];
 	return HAL_GET_FIELD(UNIFORM_REO_CMD_HEADER, REO_CMD_NUMBER,
 				     val);
 }
 
-static inline int
+static int
 hal_reo_cmd_flush_queue_be(hal_ring_handle_t hal_ring_hdl,
 			   hal_soc_handle_t hal_soc_hdl,
 			   struct hal_reo_cmd_params *cmd)
@@ -388,9 +379,8 @@ hal_reo_cmd_flush_queue_be(hal_ring_handle_t hal_ring_hdl,
 	hal_srng_access_start(hal_soc_hdl, hal_ring_hdl);
 	reo_desc = hal_srng_src_get_next(hal_soc, hal_ring_hdl);
 	if (!reo_desc) {
-		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
-			  "%s: Out of cmd ring entries", __func__);
-		hal_srng_access_end(hal_soc, hal_ring_hdl);
+		hal_srng_access_end_reap(hal_soc, hal_ring_hdl);
+		hal_warn_rl("Out of cmd ring entries");
 		return -EBUSY;
 	}
 
@@ -422,13 +412,14 @@ hal_reo_cmd_flush_queue_be(hal_ring_handle_t hal_ring_hdl,
 				      cmd->u.fl_queue_params.index);
 	}
 
-	hal_srng_access_end(hal_soc, hal_ring_hdl);
+	hal_srng_access_end_v1(hal_soc_hdl, hal_ring_hdl, RTPM_ID_HAL_REO_CMD,
+			       false);
 	val = reo_desc[CMD_HEADER_DW_OFFSET];
 	return HAL_GET_FIELD(UNIFORM_REO_CMD_HEADER, REO_CMD_NUMBER,
 				     val);
 }
 
-static inline int
+static int
 hal_reo_cmd_flush_cache_be(hal_ring_handle_t hal_ring_hdl,
 			   hal_soc_handle_t hal_soc_hdl,
 			   struct hal_reo_cmd_params *cmd)
@@ -449,8 +440,8 @@ hal_reo_cmd_flush_cache_be(hal_ring_handle_t hal_ring_hdl,
 	if (cp->block_use_after_flush) {
 		index = hal_find_zero_bit(hal_soc->reo_res_bitmap);
 		if (index > 3) {
-			qdf_print("No blocking resource available!");
-			hal_srng_access_end(hal_soc, hal_ring_hdl);
+			hal_srng_access_end_reap(hal_soc, hal_ring_hdl);
+			hal_warn_rl("No blocking resource available!");
 			return -EBUSY;
 		}
 		hal_soc->index = index;
@@ -458,7 +449,7 @@ hal_reo_cmd_flush_cache_be(hal_ring_handle_t hal_ring_hdl,
 
 	reo_desc = hal_srng_src_get_next(hal_soc, hal_ring_hdl);
 	if (!reo_desc) {
-		hal_srng_access_end(hal_soc, hal_ring_hdl);
+		hal_srng_access_end_reap(hal_soc, hal_ring_hdl);
 		hal_srng_dump(hal_ring_handle_to_hal_srng(hal_ring_hdl));
 		return -EBUSY;
 	}
@@ -505,23 +496,15 @@ hal_reo_cmd_flush_cache_be(hal_ring_handle_t hal_ring_hdl,
 	HAL_DESC_64_SET_FIELD(reo_desc, REO_FLUSH_CACHE, FLUSH_ENTIRE_CACHE,
 			      cp->flush_entire_cache);
 
-	if (hif_pm_runtime_get(hal_soc->hif_handle,
-			       RTPM_ID_HAL_REO_CMD, true) == 0) {
-		hal_srng_access_end(hal_soc_hdl, hal_ring_hdl);
-		hif_pm_runtime_put(hal_soc->hif_handle,
-				   RTPM_ID_HAL_REO_CMD);
-	} else {
-		hal_srng_access_end_reap(hal_soc_hdl, hal_ring_hdl);
-		hal_srng_set_event(hal_ring_hdl, HAL_SRNG_FLUSH_EVENT);
-		hal_srng_inc_flush_cnt(hal_ring_hdl);
-	}
+	hal_srng_access_end_v1(hal_soc_hdl, hal_ring_hdl, RTPM_ID_HAL_REO_CMD,
+			       false);
 
 	val = reo_desc[CMD_HEADER_DW_OFFSET];
 	return HAL_GET_FIELD(UNIFORM_REO_CMD_HEADER, REO_CMD_NUMBER,
 				     val);
 }
 
-static inline int
+static int
 hal_reo_cmd_unblock_cache_be(hal_ring_handle_t hal_ring_hdl,
 			     hal_soc_handle_t hal_soc_hdl,
 			     struct hal_reo_cmd_params *cmd)
@@ -544,9 +527,8 @@ hal_reo_cmd_unblock_cache_be(hal_ring_handle_t hal_ring_hdl,
 
 	reo_desc = hal_srng_src_get_next(hal_soc, hal_ring_hdl);
 	if (!reo_desc) {
-		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
-			  "%s: Out of cmd ring entries", __func__);
-		hal_srng_access_end(hal_soc, hal_ring_hdl);
+		hal_srng_access_end_reap(hal_soc, hal_ring_hdl);
+		hal_warn_rl("Out of cmd ring entries");
 		return -EBUSY;
 	}
 
@@ -580,7 +562,7 @@ hal_reo_cmd_unblock_cache_be(hal_ring_handle_t hal_ring_hdl,
 				     val);
 }
 
-static inline int
+static int
 hal_reo_cmd_flush_timeout_list_be(hal_ring_handle_t hal_ring_hdl,
 				  hal_soc_handle_t hal_soc_hdl,
 				  struct hal_reo_cmd_params *cmd)
@@ -591,9 +573,8 @@ hal_reo_cmd_flush_timeout_list_be(hal_ring_handle_t hal_ring_hdl,
 	hal_srng_access_start(hal_soc_hdl, hal_ring_hdl);
 	reo_desc = hal_srng_src_get_next(hal_soc, hal_ring_hdl);
 	if (!reo_desc) {
-		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
-			  "%s: Out of cmd ring entries", __func__);
-		hal_srng_access_end(hal_soc, hal_ring_hdl);
+		hal_srng_access_end_reap(hal_soc, hal_ring_hdl);
+		hal_warn_rl("Out of cmd ring entries");
 		return -EBUSY;
 	}
 
@@ -629,7 +610,7 @@ hal_reo_cmd_flush_timeout_list_be(hal_ring_handle_t hal_ring_hdl,
 				     val);
 }
 
-static inline int
+static int
 hal_reo_cmd_update_rx_queue_be(hal_ring_handle_t hal_ring_hdl,
 			       hal_soc_handle_t hal_soc_hdl,
 			       struct hal_reo_cmd_params *cmd)
@@ -643,9 +624,8 @@ hal_reo_cmd_update_rx_queue_be(hal_ring_handle_t hal_ring_hdl,
 	hal_srng_access_start(hal_soc_hdl, hal_ring_hdl);
 	reo_desc = hal_srng_src_get_next(hal_soc, hal_ring_hdl);
 	if (!reo_desc) {
-		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
-			  "%s: Out of cmd ring entries", __func__);
-		hal_srng_access_end(hal_soc, hal_ring_hdl);
+		hal_srng_access_end_reap(hal_soc, hal_ring_hdl);
+		hal_warn_rl("Out of cmd ring entries");
 		return -EBUSY;
 	}
 
@@ -832,17 +812,8 @@ hal_reo_cmd_update_rx_queue_be(hal_ring_handle_t hal_ring_hdl,
 	HAL_DESC_64_SET_FIELD(reo_desc, REO_UPDATE_RX_REO_QUEUE,
 			      PN_127_96, p->pn_127_96);
 
-	if (hif_pm_runtime_get(hal_soc->hif_handle,
-			       RTPM_ID_HAL_REO_CMD, false) == 0) {
-		hal_srng_access_end(hal_soc_hdl, hal_ring_hdl);
-		hif_pm_runtime_put(hal_soc->hif_handle,
-				   RTPM_ID_HAL_REO_CMD);
-	} else {
-		hal_srng_access_end_reap(hal_soc_hdl, hal_ring_hdl);
-		hal_srng_set_event(hal_ring_hdl, HAL_SRNG_FLUSH_EVENT);
-		hal_srng_inc_flush_cnt(hal_ring_hdl);
-	}
-
+	hal_srng_access_end_v1(hal_soc_hdl, hal_ring_hdl, RTPM_ID_HAL_REO_CMD,
+			       false);
 	val = reo_desc[CMD_HEADER_DW_OFFSET];
 	return HAL_GET_FIELD(UNIFORM_REO_CMD_HEADER, REO_CMD_NUMBER,
 				     val);

+ 34 - 1
hal/wifi3.0/hal_api.h

@@ -2202,7 +2202,6 @@ hal_srng_access_end_unlocked(void *hal_soc, hal_ring_handle_t hal_ring_hdl)
  * This API should be used only if hal_srng_access_start was used to
  * start ring access
  *
- * Return: 0 on success; error on failire
  */
 static inline void
 hal_srng_access_end(void *hal_soc, hal_ring_handle_t hal_ring_hdl)
@@ -2218,6 +2217,40 @@ hal_srng_access_end(void *hal_soc, hal_ring_handle_t hal_ring_hdl)
 	SRNG_UNLOCK(&(srng->lock));
 }
 
+void hal_srng_access_end_v1(hal_soc_handle_t hal_soc_hdl,
+			    hal_ring_handle_t hal_ring_hdl,
+			    wlan_rtpm_dbgid rtpm_dbgid,
+			    bool is_critical_ctx);
+
+#ifdef FEATURE_RUNTIME_PM
+#define hal_srng_access_end_v1 hal_srng_rtpm_access_end
+
+/**
+ * hal_srng_rtpm_access_end - RTPM aware, Unlock ring access
+ * @hal_soc: Opaque HAL SOC handle
+ * @hal_ring_hdl: Ring pointer (Source or Destination ring)
+ * @rtpm_dbgid: RTPM debug id
+ * @is_critical_ctx: Whether the calling context is critical
+ *
+ * Function updates the HP/TP value to the hardware register.
+ * The target expects cached head/tail pointer to be updated to the
+ * shared location in the little-endian order, This API ensures that.
+ * This API should be used only if hal_srng_access_start was used to
+ * start ring access
+ *
+ * Return: None
+ */
+void
+hal_srng_rtpm_access_end(hal_soc_handle_t hal_soc_hdl,
+			 hal_ring_handle_t hal_ring_hdl,
+			 wlan_rtpm_dbgid rtpm_dbgid,
+			 bool is_critical_ctx);
+#else
+#define hal_srng_access_end_v1(hal_soc_hdl, hal_ring_hdl, rtpm_dbgid, \
+			       is_critical_ctx)\
+	hal_srng_access_end(hal_soc_hdl, hal_ring_hdl)
+#endif
+
 /* hal_srng_access_end already handles endianness conversion, so use the same */
 #define hal_le_srng_access_end_in_cpu_order \
 	hal_srng_access_end

+ 29 - 1
hal/wifi3.0/hal_srng.c

@@ -1784,11 +1784,39 @@ void hal_set_low_threshold(hal_ring_handle_t hal_ring_hdl,
 }
 qdf_export_symbol(hal_set_low_threshold);
 
+#ifdef FEATURE_RUNTIME_PM
+void
+hal_srng_rtpm_access_end(hal_soc_handle_t hal_soc_hdl,
+			 hal_ring_handle_t hal_ring_hdl,
+			 wlan_rtpm_dbgid rtpm_dbgid,
+			 bool is_critical_ctx)
+{
+	struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
+
+	if (qdf_unlikely(!hal_ring_hdl)) {
+		qdf_print("Error: Invalid hal_ring\n");
+		return;
+	}
+
+	if (hif_pm_runtime_get(hal_soc->hif_handle,
+			       rtpm_dbgid, is_critical_ctx) == 0) {
+		hal_srng_access_end(hal_soc_hdl, hal_ring_hdl);
+		hif_pm_runtime_put(hal_soc->hif_handle,
+				   rtpm_dbgid);
+	} else {
+		hal_srng_access_end_reap(hal_soc_hdl, hal_ring_hdl);
+		hal_srng_set_event(hal_ring_hdl, HAL_SRNG_FLUSH_EVENT);
+		hal_srng_inc_flush_cnt(hal_ring_hdl);
+	}
+}
+
+qdf_export_symbol(hal_srng_rtpm_access_end);
+#endif /* FEATURE_RUNTIME_PM */
+
 #ifdef FORCE_WAKE
 void hal_set_init_phase(hal_soc_handle_t soc, bool init_phase)
 {
 	struct hal_soc *hal_soc = (struct hal_soc *)soc;
-
 	hal_soc->init_phase = init_phase;
 }
 #endif /* FORCE_WAKE */