Просмотр исходного кода

qcacmn: Do smmu unmap for IPA TX and RX doorbell registers

During driver initialization, IPA TX and RX doorbell registers
are provided to wlan as physical addresses. With SMMU S1 enabled,
they're mapped to IOVA of wlan domain.

On driver deinit path, do smmu unmap for the two IOVA addresses.

Change-Id: I85ef1c3e99bef504abf09eebf9ace760b68f35f1
CRs-Fixed: 2768303
Jia Ding 4 лет назад
Родитель
Сommit
9f0246370d
4 измененных файлов с 46 добавлено и 10 удалено
  1. 5 3
      dp/inc/cdp_txrx_ipa.h
  2. 3 2
      dp/inc/cdp_txrx_ops.h
  3. 35 3
      dp/wifi3.0/dp_ipa.c
  4. 3 2
      dp/wifi3.0/dp_ipa.h

+ 5 - 3
dp/inc/cdp_txrx_ipa.h

@@ -427,14 +427,15 @@ cdp_ipa_setup(ol_txrx_soc_handle soc, uint8_t pdev_id, void *ipa_i2w_cb,
 /**
  * cdp_ipa_cleanup() - Disconnect IPA pipes
  * @soc: data path soc handle
+ * @pdev_id: handle to the device instance number
  * @tx_pipe_handle: Tx pipe handle
  * @rx_pipe_handle: Rx pipe handle
  *
  * Return: QDF_STATUS
  */
 static inline QDF_STATUS
-cdp_ipa_cleanup(ol_txrx_soc_handle soc, uint32_t tx_pipe_handle,
-		uint32_t rx_pipe_handle)
+cdp_ipa_cleanup(ol_txrx_soc_handle soc, uint8_t pdev_id,
+		uint32_t tx_pipe_handle, uint32_t rx_pipe_handle)
 {
 	if (!soc || !soc->ops || !soc->ops->ipa_ops) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
@@ -443,7 +444,8 @@ cdp_ipa_cleanup(ol_txrx_soc_handle soc, uint32_t tx_pipe_handle,
 	}
 
 	if (soc->ops->ipa_ops->ipa_cleanup)
-		return soc->ops->ipa_ops->ipa_cleanup(tx_pipe_handle,
+		return soc->ops->ipa_ops->ipa_cleanup(soc, pdev_id,
+						      tx_pipe_handle,
 						      rx_pipe_handle);
 
 	return QDF_STATUS_SUCCESS;

+ 3 - 2
dp/inc/cdp_txrx_ops.h

@@ -1579,8 +1579,9 @@ struct cdp_ipa_ops {
 				bool is_rm_enabled, uint32_t *tx_pipe_handle,
 				uint32_t *rx_pipe_handle);
 #endif /* CONFIG_IPA_WDI_UNIFIED_API */
-	QDF_STATUS (*ipa_cleanup)(uint32_t tx_pipe_handle,
-		uint32_t rx_pipe_handle);
+	QDF_STATUS (*ipa_cleanup)(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
+				  uint32_t tx_pipe_handle,
+				  uint32_t rx_pipe_handle);
 	QDF_STATUS (*ipa_setup_iface)(char *ifname, uint8_t *mac_addr,
 		qdf_ipa_client_type_t prod_client,
 		qdf_ipa_client_type_t cons_client,

+ 35 - 3
dp/wifi3.0/dp_ipa.c

@@ -1642,23 +1642,55 @@ QDF_STATUS dp_ipa_setup_iface(char *ifname, uint8_t *mac_addr,
 
 /**
  * dp_ipa_cleanup() - Disconnect IPA pipes
+ * @soc_hdl: dp soc handle
+ * @pdev_id: dp pdev id
  * @tx_pipe_handle: Tx pipe handle
  * @rx_pipe_handle: Rx pipe handle
  *
  * Return: QDF_STATUS
  */
-QDF_STATUS dp_ipa_cleanup(uint32_t tx_pipe_handle, uint32_t rx_pipe_handle)
+QDF_STATUS dp_ipa_cleanup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
+			  uint32_t tx_pipe_handle, uint32_t rx_pipe_handle)
 {
+	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct dp_ipa_resources *ipa_res;
+	struct dp_pdev *pdev;
 	int ret;
 
 	ret = qdf_ipa_wdi_disconn_pipes();
 	if (ret) {
 		dp_err("ipa_wdi_disconn_pipes: IPA pipe cleanup failed: ret=%d",
 		       ret);
-		return QDF_STATUS_E_FAILURE;
+		status = QDF_STATUS_E_FAILURE;
 	}
 
-	return QDF_STATUS_SUCCESS;
+	pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
+	if (qdf_unlikely(!pdev)) {
+		dp_err_rl("Invalid pdev for pdev_id %d", pdev_id);
+		status = QDF_STATUS_E_FAILURE;
+		goto exit;
+	}
+
+	if (qdf_mem_smmu_s1_enabled(soc->osdev)) {
+		ipa_res = &pdev->ipa_resource;
+
+		/* unmap has to be the reverse order of smmu map */
+		ret = pld_smmu_unmap(soc->osdev->dev,
+				     ipa_res->rx_ready_doorbell_paddr,
+				     sizeof(uint32_t));
+		if (ret)
+			dp_err_rl("IPA RX DB smmu unmap failed");
+
+		ret = pld_smmu_unmap(soc->osdev->dev,
+				     ipa_res->tx_comp_doorbell_paddr,
+				     sizeof(uint32_t));
+		if (ret)
+			dp_err_rl("IPA TX DB smmu unmap failed");
+	}
+
+exit:
+	return status;
 }
 
 /**

+ 3 - 2
dp/wifi3.0/dp_ipa.h

@@ -186,8 +186,9 @@ QDF_STATUS dp_ipa_setup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
 			bool is_rm_enabled, uint32_t *tx_pipe_handle,
 			uint32_t *rx_pipe_handle);
 #endif /* CONFIG_IPA_WDI_UNIFIED_API */
-QDF_STATUS dp_ipa_cleanup(uint32_t tx_pipe_handle,
-		uint32_t rx_pipe_handle);
+QDF_STATUS dp_ipa_cleanup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
+			  uint32_t tx_pipe_handle,
+			  uint32_t rx_pipe_handle);
 QDF_STATUS dp_ipa_remove_header(char *name);
 int dp_ipa_add_header_info(char *ifname, uint8_t *mac_addr,
 		uint8_t session_id, bool is_ipv6_enabled);