Ver Fonte

qcacmn: Do not use WBM2SW4 as tx completion ring

Ageout flush does not happen for WBM2SW4 if there
is only one TX completion pending in FIFO and all the
other WBM release rings are not active. This is due to
an issue in HW and this prevents suspend to happen due
to pending tx completions.

Fix is to avoid using WBM2SW4 release ring and instead
reuse WBM2SW0.

Change-Id: I250d8c9d460895449939212ebdb7abd62edb0234
CRs-Fixed: 3124733
Yeshwanth Sriram Guntuka há 3 anos atrás
pai
commit
c467daf31c
4 ficheiros alterados com 52 adições e 11 exclusões
  1. 2 0
      dp/wifi3.0/dp_internal.h
  2. 22 7
      dp/wifi3.0/dp_main.c
  3. 27 2
      dp/wifi3.0/li/dp_li.c
  4. 1 2
      wlan_cfg/wlan_cfg.c

+ 2 - 0
dp/wifi3.0/dp_internal.h

@@ -41,6 +41,8 @@
 /* Macro For NYSM value received in VHT TLV */
 #define VHT_SGI_NYSM 3
 
+#define INVALID_WBM_RING_NUM 0xFF
+
 /* struct htt_dbgfs_cfg - structure to maintain required htt data
  * @msg_word: htt msg sent to upper layer
  * @m: qdf debugfs file pointer

+ 22 - 7
dp/wifi3.0/dp_main.c

@@ -4432,8 +4432,8 @@ static void dp_deinit_tx_pair_by_index(struct dp_soc *soc, int index)
 						&tcl_ring_num,
 						&wbm_ring_num);
 
-	if (tcl_ring_num == -1 || wbm_ring_num == -1) {
-		dp_err("incorrect tcl/wbm ring num for index %u", index);
+	if (tcl_ring_num == -1) {
+		dp_err("incorrect tcl ring num for index %u", index);
 		return;
 	}
 
@@ -4446,6 +4446,9 @@ static void dp_deinit_tx_pair_by_index(struct dp_soc *soc, int index)
 	dp_srng_deinit(soc, &soc->tcl_data_ring[index], TCL_DATA,
 		       tcl_ring_num);
 
+	if (wbm_ring_num == INVALID_WBM_RING_NUM)
+		return;
+
 	wlan_minidump_remove(soc->tx_comp_ring[index].base_vaddr_unaligned,
 			     soc->tx_comp_ring[index].alloc_size,
 			     soc->ctrl_psoc,
@@ -4480,8 +4483,8 @@ static QDF_STATUS dp_init_tx_ring_pair_by_index(struct dp_soc *soc,
 						&tcl_ring_num,
 						&wbm_ring_num);
 
-	if (tcl_ring_num == -1 || wbm_ring_num == -1) {
-		dp_err("incorrect tcl/wbm ring num for index %u", index);
+	if (tcl_ring_num == -1) {
+		dp_err("incorrect tcl ring num for index %u", index);
 		goto fail1;
 	}
 
@@ -4497,20 +4500,24 @@ static QDF_STATUS dp_init_tx_ring_pair_by_index(struct dp_soc *soc,
 			  WLAN_MD_DP_SRNG_TCL_DATA,
 			  "tcl_data_ring");
 
+	if (wbm_ring_num == INVALID_WBM_RING_NUM)
+		goto set_rbm;
+
 	if (dp_srng_init(soc, &soc->tx_comp_ring[index], WBM2SW_RELEASE,
 			 wbm_ring_num, 0)) {
 		dp_err("dp_srng_init failed for tx_comp_ring");
 		goto fail1;
 	}
 
-	bm_id = wlan_cfg_get_rbm_id_for_index(soc->wlan_cfg_ctx, tcl_ring_num);
-
-	soc->arch_ops.tx_implicit_rbm_set(soc, tcl_ring_num, bm_id);
 	wlan_minidump_log(soc->tx_comp_ring[index].base_vaddr_unaligned,
 			  soc->tx_comp_ring[index].alloc_size,
 			  soc->ctrl_psoc,
 			  WLAN_MD_DP_SRNG_TX_COMP,
 			  "tcl_comp_ring");
+set_rbm:
+	bm_id = wlan_cfg_get_rbm_id_for_index(soc->wlan_cfg_ctx, tcl_ring_num);
+
+	soc->arch_ops.tx_implicit_rbm_set(soc, tcl_ring_num, bm_id);
 
 	return QDF_STATUS_SUCCESS;
 
@@ -4563,6 +4570,10 @@ static QDF_STATUS dp_alloc_tx_ring_pair_by_index(struct dp_soc *soc,
 	if (!wlan_cfg_get_dp_soc_nss_cfg(soc_cfg_ctx))
 		cached = WLAN_CFG_DST_RING_CACHED_DESC;
 
+	if (wlan_cfg_get_wbm_ring_num_for_index(soc->wlan_cfg_ctx, index) ==
+	    INVALID_WBM_RING_NUM)
+		return QDF_STATUS_SUCCESS;
+
 	if (dp_srng_alloc(soc, &soc->tx_comp_ring[index], WBM2SW_RELEASE,
 			  tx_comp_ring_size, cached)) {
 		dp_err("dp_srng_alloc failed for tx_comp_ring");
@@ -11387,6 +11398,10 @@ static void dp_display_srng_info(struct cdp_soc_t *soc_hdl)
 				&tp, &hp);
 		dp_info("TCL DATA ring[%d]: hp=0x%x, tp=0x%x", i, hp, tp);
 
+		if (wlan_cfg_get_wbm_ring_num_for_index(soc->wlan_cfg_ctx, i) ==
+		    INVALID_WBM_RING_NUM)
+			continue;
+
 		hal_get_sw_hptp(hal_soc, soc->tx_comp_ring[i].hal_srng,
 				&tp, &hp);
 		dp_info("TX comp ring[%d]: hp=0x%x, tp=0x%x", i, hp, tp);

+ 27 - 2
dp/wifi3.0/li/dp_li.c

@@ -26,12 +26,18 @@
 #include "dp_li_rx.h"
 #include "dp_peer.h"
 #include <wlan_utility.h>
+#include "dp_ipa.h"
 
 #if defined(WLAN_MAX_PDEVS) && (WLAN_MAX_PDEVS == 1)
 static struct wlan_cfg_tcl_wbm_ring_num_map g_tcl_wbm_map_array[MAX_TCL_DATA_RINGS] = {
 	{.tcl_ring_num = 0, .wbm_ring_num = 0, .wbm_rbm_id = HAL_LI_WBM_SW0_BM_ID, .for_ipa = 0},
-	{1, 4, HAL_LI_WBM_SW4_BM_ID, 1}, /* For IPA */
-	{2, 2, HAL_LI_WBM_SW2_BM_ID, 1} /* For IPA */};
+	/*
+	 * INVALID_WBM_RING_NUM implies re-use of an existing WBM2SW ring
+	 * as indicated by rbm id.
+	 */
+	{1, INVALID_WBM_RING_NUM, HAL_LI_WBM_SW0_BM_ID, 0},
+	{2, 2, HAL_LI_WBM_SW2_BM_ID, 0}
+};
 #else
 static struct wlan_cfg_tcl_wbm_ring_num_map g_tcl_wbm_map_array[MAX_TCL_DATA_RINGS] = {
 	{.tcl_ring_num = 0, .wbm_ring_num = 0, .wbm_rbm_id = HAL_LI_WBM_SW0_BM_ID, .for_ipa = 0},
@@ -40,6 +46,24 @@ static struct wlan_cfg_tcl_wbm_ring_num_map g_tcl_wbm_map_array[MAX_TCL_DATA_RIN
 };
 #endif
 
+#ifdef IPA_WDI3_TX_TWO_PIPES
+static inline void
+dp_soc_cfg_update_tcl_wbm_map_for_ipa(struct wlan_cfg_dp_soc_ctxt *cfg_ctx)
+{
+	if (!cfg_ctx->ipa_enabled)
+		return;
+
+	cfg_ctx->tcl_wbm_map_array[IPA_TX_ALT_RING_IDX].wbm_ring_num = 4;
+	cfg_ctx->tcl_wbm_map_array[IPA_TX_ALT_RING_IDX].wbm_rbm_id =
+							   HAL_LI_WBM_SW4_BM_ID;
+}
+#else
+static inline void
+dp_soc_cfg_update_tcl_wbm_map_for_ipa(struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx)
+{
+}
+#endif
+
 static void dp_soc_cfg_attach_li(struct dp_soc *soc)
 {
 	struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx = soc->wlan_cfg_ctx;
@@ -47,6 +71,7 @@ static void dp_soc_cfg_attach_li(struct dp_soc *soc)
 	wlan_cfg_set_rx_rel_ring_id(soc_cfg_ctx, WBM2SW_REL_ERR_RING_NUM);
 
 	soc_cfg_ctx->tcl_wbm_map_array = g_tcl_wbm_map_array;
+	dp_soc_cfg_update_tcl_wbm_map_for_ipa(soc_cfg_ctx);
 }
 
 qdf_size_t dp_get_context_size_li(enum dp_context_type context_type)

+ 1 - 2
wlan_cfg/wlan_cfg.c

@@ -146,8 +146,7 @@ static const uint8_t tx_ring_mask_msi[WLAN_CFG_INT_NUM_CONTEXTS] = {
 
 #ifdef TX_MULTI_TCL
 static const uint8_t multi_tx_ring_mask_msi[WLAN_CFG_INT_NUM_CONTEXTS] = {
-	[0] = WLAN_CFG_TX_RING_MASK_0, [4] = WLAN_CFG_TX_RING_MASK_2,
-	[5] = WLAN_CFG_TX_RING_MASK_4};
+	[0] = WLAN_CFG_TX_RING_MASK_0, [4] = WLAN_CFG_TX_RING_MASK_2};
 
 #ifdef IPA_OFFLOAD
 static inline const