Sfoglia il codice sorgente

qcacld-3.0: Disable Direct Link CEs MSI on WFDS QMI server down

After direct link WFDS QMI server is down, host driver
unmaps the IPCC MSI address. There is a possibility
where FW can still enqueue entries to direct link CE
resulting in a SMMU fault when CE HW raises interrupt
after copy operation.

Fix is to disable direct link CEs MSI on WFDS QMI
server down indication prior to unmapping the MSI
address.

CRs-Fixed: 3657146
Change-Id: I38ce3bcc143743884d5c464eae74c390bf32eab6
Yeshwanth Sriram Guntuka 1 anno fa
parent
commit
7c5cc5e624

+ 6 - 0
components/dp/core/inc/wlan_dp_wfds.h

@@ -24,6 +24,8 @@
 #include "wlan_qmi_public_struct.h"
 #include "wlan_qmi_wfds_api.h"
 
+#define DP_WFDS_CE_MAX_SRNG QMI_WFDS_CE_MAX_SRNG
+
 /**
  * enum dp_wfds_msg - WFDS message type
  * @DP_WFDS_REQ_MEM_IND_MSG: Memory request indication message
@@ -109,6 +111,8 @@ struct dp_direct_link_iommu_config {
  * @num_mem_arenas: Number of memory arenas requested by QMI server
  * @mem_arena_pages: Pointer to array of mem multi page structure for arenas
  * @ipcc_dma_addr: ipcc dma address
+ * @ipcc_ce_id: ids of CEs that are configured with IPCC MSI info
+ * @ipcc_ce_id_len: number of valid entries in ipcc_ce_id array
  * @iommu_cfg: direct link iommu configuration
  */
 struct dp_direct_link_wfds_context {
@@ -121,6 +125,8 @@ struct dp_direct_link_wfds_context {
 	uint32_t num_mem_arenas;
 	struct qdf_mem_multi_page_t *mem_arena_pages;
 	uint32_t ipcc_dma_addr;
+	uint8_t ipcc_ce_id[DP_WFDS_CE_MAX_SRNG];
+	uint8_t ipcc_ce_id_len;
 	struct dp_direct_link_iommu_config iommu_cfg;
 };
 

+ 12 - 2
components/dp/core/src/wlan_dp_wfds.c

@@ -540,11 +540,15 @@ dp_wfds_handle_ipcc_map_n_cfg_ind(struct wlan_qmi_wfds_ipcc_map_n_cfg_ind_msg *i
 	pld_smmu_map(qdf_ctx->dev, ipcc_msg->ipcc_ce_info[0].ipcc_trig_addr,
 		     &dl_wfds->ipcc_dma_addr, sizeof(uint32_t));
 
-	for (i = 0; i < ipcc_msg->ipcc_ce_info_len; i++)
+	dl_wfds->ipcc_ce_id_len = ipcc_msg->ipcc_ce_info_len;
+
+	for (i = 0; i < ipcc_msg->ipcc_ce_info_len; i++) {
+		dl_wfds->ipcc_ce_id[i] = ipcc_msg->ipcc_ce_info[i].ce_id;
 		hif_set_irq_config_by_ceid(hif_ctx,
 				      ipcc_msg->ipcc_ce_info[i].ce_id,
 				      dl_wfds->ipcc_dma_addr,
 				      ipcc_msg->ipcc_ce_info[i].ipcc_trig_data);
+	}
 
 	dp_wfds_event_post(dl_wfds, DP_WFDS_IPCC_MAP_N_CFG, NULL);
 }
@@ -586,9 +590,15 @@ void dp_wfds_del_server(void)
 		       DP_WFDS_SVC_DISCONNECTED);
 
 	if (dl_wfds_state >= DP_WFDS_SVC_IPCC_MAP_N_CFG_DONE &&
-	    dl_wfds->ipcc_dma_addr)
+	    dl_wfds->ipcc_dma_addr) {
+		for (i = 0; i < dl_wfds->ipcc_ce_id_len; i++)
+			hif_set_irq_config_by_ceid(hif_ctx,
+						   dl_wfds->ipcc_ce_id[i],
+						   0, 0);
+
 		pld_smmu_unmap(qdf_ctx->dev, dl_wfds->ipcc_dma_addr,
 			       sizeof(uint32_t));
+	}
 
 	if (dl_wfds_state >= DP_WFDS_SVC_MEM_CONFIG_DONE) {
 		uint64_t *dma_addr = NULL;