Преглед изворни кода

qcacmn: Ring IPA TX doorbell with HW HP value

Ring IPA TX doorbell with HW HP value to avoid out-of-sync
scenarios between WLAN and IPA after IPA pipes are disabled
and then re-enabled.

CRs-Fixed: 3479426
Change-Id: Ia88c0228759e241722fe31fd1a252e70484684e9
Jia Ding пре 1 година
родитељ
комит
813e5ff2ec
3 измењених фајлова са 61 додато и 0 уклоњено
  1. 30 0
      dp/wifi3.0/dp_ipa.c
  2. 10 0
      hal/wifi3.0/hal_api.h
  3. 21 0
      hal/wifi3.0/hal_srng.c

+ 30 - 0
dp/wifi3.0/dp_ipa.c

@@ -1059,6 +1059,23 @@ static void dp_ipa_tx_comp_ring_init_hp(struct dp_soc *soc,
 			     res->tx_alt_comp_doorbell_vaddr);
 }
 
+static void
+dp_ipa_tx_comp_ring_update_hp_addr(struct dp_soc *soc,
+				   struct dp_ipa_resources *res)
+{
+	hal_ring_handle_t wbm_srng;
+
+	/* Ring doorbell to WBM2IPA ring with current HW HP value */
+	wbm_srng = soc->tx_comp_ring[IPA_TX_COMP_RING_IDX].hal_srng;
+	hal_srng_dst_update_hp_addr(soc->hal_soc, wbm_srng);
+
+	if (!res->tx_alt_comp_doorbell_paddr)
+		return;
+
+	wbm_srng = soc->tx_comp_ring[IPA_TX_ALT_COMP_RING_IDX].hal_srng;
+	hal_srng_dst_update_hp_addr(soc->hal_soc, wbm_srng);
+}
+
 static void dp_ipa_set_tx_doorbell_paddr(struct dp_soc *soc,
 					 struct dp_ipa_resources *ipa_res)
 {
@@ -1255,6 +1272,17 @@ static inline void dp_ipa_tx_comp_ring_init_hp(struct dp_soc *soc,
 			     res->tx_comp_doorbell_vaddr);
 }
 
+static void
+dp_ipa_tx_comp_ring_update_hp_addr(struct dp_soc *soc,
+				   struct dp_ipa_resources *res)
+{
+	hal_ring_handle_t wbm_srng;
+
+	/* Ring doorbell to WBM2IPA ring with current HW HP value */
+	wbm_srng = soc->tx_comp_ring[IPA_TX_COMP_RING_IDX].hal_srng;
+	hal_srng_dst_update_hp_addr(soc->hal_soc, wbm_srng);
+}
+
 static void dp_ipa_set_tx_doorbell_paddr(struct dp_soc *soc,
 					 struct dp_ipa_resources *ipa_res)
 {
@@ -3500,6 +3528,8 @@ QDF_STATUS dp_ipa_enable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
 	if (soc->ipa_first_tx_db_access) {
 		dp_ipa_tx_comp_ring_init_hp(soc, ipa_res);
 		soc->ipa_first_tx_db_access = false;
+	} else {
+		dp_ipa_tx_comp_ring_update_hp_addr(soc, ipa_res);
 	}
 
 	return QDF_STATUS_SUCCESS;

+ 10 - 0
hal/wifi3.0/hal_api.h

@@ -1302,6 +1302,16 @@ void hal_srng_dst_init_hp(struct hal_soc_handle *hal_soc,
 			  struct hal_srng *srng,
 			  uint32_t *vaddr);
 
+/**
+ * hal_srng_dst_update_hp_addr() - Update hp_addr with current HW HP value
+ * @hal_soc: hal_soc handle
+ * @hal_ring_hdl: Opaque HAL SRNG pointer
+ *
+ * Return: None
+ */
+void hal_srng_dst_update_hp_addr(struct hal_soc_handle *hal_soc,
+				 hal_ring_handle_t hal_ring_hdl);
+
 /**
  * hal_srng_cleanup() - Deinitialize HW SRNG ring.
  * @hal_soc: Opaque HAL SOC handle

+ 21 - 0
hal/wifi3.0/hal_srng.c

@@ -1465,6 +1465,27 @@ void hal_srng_dst_init_hp(struct hal_soc_handle *hal_soc,
 
 qdf_export_symbol(hal_srng_dst_init_hp);
 
+void hal_srng_dst_update_hp_addr(struct hal_soc_handle *hal_soc,
+				 hal_ring_handle_t hal_ring_hdl)
+{
+	struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
+	int32_t hw_hp;
+	int32_t hw_tp;
+
+	if (!srng)
+		return;
+
+	if (srng->u.dst_ring.hp_addr) {
+		hal_get_hw_hptp(hal_soc, hal_ring_hdl, &hw_hp, &hw_tp,
+				WBM2SW_RELEASE);
+		*srng->u.dst_ring.hp_addr = hw_hp;
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
+			  "hw_hp=%d", hw_hp);
+	}
+}
+
+qdf_export_symbol(hal_srng_dst_update_hp_addr);
+
 /**
  * hal_srng_hw_init - Private function to initialize SRNG HW
  * @hal: HAL SOC handle