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

qcacmn: IOMMU map and unmap RX buffers to LPASS SMMU CB

IOMMU map and unmap RX buffers into LPASS SMMU context
bank for LPASS to access RX buffers in direct link
usecases.

Change-Id: Ie72a008309e3abdf3fbc7198bb5d3af5e9497180
CRs-Fixed: 3356568
Yeshwanth Sriram Guntuka пре 2 година
родитељ
комит
34d893df39

+ 7 - 1
dp/wifi3.0/dp_rx.c

@@ -3128,6 +3128,12 @@ dp_pdev_rx_buffers_attach(struct dp_soc *dp_soc, uint32_t mac_id,
 					rx_desc_pool->buf_size, true,
 					__func__, __LINE__);
 
+			dp_audio_smmu_map(dp_soc->osdev,
+					  qdf_mem_paddr_from_dmaaddr(dp_soc->osdev,
+								     QDF_NBUF_CB_PADDR(nbuf)),
+					  QDF_NBUF_CB_PADDR(nbuf),
+					  rx_desc_pool->buf_size);
+
 			desc_list = next;
 		}
 
@@ -3366,7 +3372,7 @@ dp_rx_pdev_buffers_free(struct dp_pdev *pdev)
 
 	rx_desc_pool = &soc->rx_desc_buf[mac_for_pdev];
 
-	dp_rx_desc_nbuf_free(soc, rx_desc_pool);
+	dp_rx_desc_nbuf_free(soc, rx_desc_pool, false);
 	dp_rx_buffer_pool_deinit(soc, mac_for_pdev);
 }
 

+ 55 - 1
dp/wifi3.0/dp_rx.h

@@ -931,7 +931,8 @@ void dp_rx_desc_nbuf_and_pool_free(struct dp_soc *soc, uint32_t pool_id,
  * Return: None
  */
 void dp_rx_desc_nbuf_free(struct dp_soc *soc,
-			  struct rx_desc_pool *rx_desc_pool);
+			  struct rx_desc_pool *rx_desc_pool,
+			  bool is_mon_pool);
 
 #ifdef DP_RX_MON_MEM_FRAG
 /*
@@ -2378,6 +2379,52 @@ bool dp_rx_pkt_tracepoints_enabled(void)
 		qdf_trace_dp_rx_pkt_enabled());
 }
 
+#ifdef FEATURE_DIRECT_LINK
+/**
+ * dp_audio_smmu_map()- Map memory region into Audio SMMU CB
+ * @qdf_dev: pointer to QDF device structure
+ * @paddr: physical address
+ * @iova: DMA address
+ * @size: memory region size
+ *
+ * Return: 0 on success else failure code
+ */
+static inline
+int dp_audio_smmu_map(qdf_device_t qdf_dev, qdf_dma_addr_t paddr,
+		      qdf_dma_addr_t iova, qdf_size_t size)
+{
+	return pld_audio_smmu_map(qdf_dev->dev, paddr, iova, size);
+}
+
+/**
+ * dp_audio_smmu_unmap()- Remove memory region mapping from Audio SMMU CB
+ * @qdf_dev: pointer to QDF device structure
+ * @iova: DMA address
+ * @size: memory region size
+ *
+ * Return: None
+ */
+static inline
+void dp_audio_smmu_unmap(qdf_device_t qdf_dev, qdf_dma_addr_t iova,
+			 qdf_size_t size)
+{
+	pld_audio_smmu_unmap(qdf_dev->dev, iova, size);
+}
+#else
+static inline
+int dp_audio_smmu_map(qdf_device_t qdf_dev, qdf_dma_addr_t paddr,
+		      qdf_dma_addr_t iova, qdf_size_t size)
+{
+	return 0;
+}
+
+static inline
+void dp_audio_smmu_unmap(qdf_device_t qdf_dev, qdf_dma_addr_t iova,
+			 qdf_size_t size)
+{
+}
+#endif
+
 #if defined(QCA_DP_RX_NBUF_NO_MAP_UNMAP) && !defined(BUILD_X86)
 static inline
 QDF_STATUS dp_pdev_rx_buffers_attach_simple(struct dp_soc *soc, uint32_t mac_id,
@@ -2596,6 +2643,11 @@ void dp_rx_nbuf_unmap(struct dp_soc *soc,
 
 	rx_desc_pool = &soc->rx_desc_buf[rx_desc->pool_id];
 	dp_ipa_reo_ctx_buf_mapping_lock(soc, reo_ring_num);
+
+	dp_audio_smmu_unmap(soc->osdev,
+			    QDF_NBUF_CB_PADDR(rx_desc->nbuf),
+			    rx_desc_pool->buf_size);
+
 	dp_ipa_handle_rx_buf_smmu_mapping(soc, rx_desc->nbuf,
 					  rx_desc_pool->buf_size,
 					  false, __func__, __LINE__);
@@ -2612,6 +2664,8 @@ void dp_rx_nbuf_unmap_pool(struct dp_soc *soc,
 			   struct rx_desc_pool *rx_desc_pool,
 			   qdf_nbuf_t nbuf)
 {
+	dp_audio_smmu_unmap(soc->osdev, QDF_NBUF_CB_PADDR(nbuf),
+			    rx_desc_pool->buf_size);
 	dp_ipa_handle_rx_buf_smmu_mapping(soc, nbuf, rx_desc_pool->buf_size,
 					  false, __func__, __LINE__);
 	qdf_nbuf_unmap_nbytes_single(soc->osdev, nbuf, QDF_DMA_FROM_DEVICE,

+ 24 - 1
dp/wifi3.0/dp_rx_buffer_pool.c

@@ -164,6 +164,12 @@ void dp_rx_refill_buff_pool_enqueue(struct dp_soc *soc)
 				continue;
 			}
 
+			dp_audio_smmu_map(dev,
+					  qdf_mem_paddr_from_dmaaddr(dev,
+								     QDF_NBUF_CB_PADDR(nbuf)),
+					  QDF_NBUF_CB_PADDR(nbuf),
+					  rx_desc_pool->buf_size);
+
 			buff_pool->buf_elem[head++] = nbuf;
 			head &= (DP_RX_REFILL_BUFF_POOL_SIZE - 1);
 			count++;
@@ -257,11 +263,19 @@ dp_rx_buffer_pool_nbuf_map(struct dp_soc *soc,
 {
 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
 
-	if (!QDF_NBUF_CB_PADDR((nbuf_frag_info_t->virt_addr).nbuf))
+	if (!QDF_NBUF_CB_PADDR((nbuf_frag_info_t->virt_addr).nbuf)) {
 		ret = qdf_nbuf_map_nbytes_single(soc->osdev,
 						 (nbuf_frag_info_t->virt_addr).nbuf,
 						 QDF_DMA_FROM_DEVICE,
 						 rx_desc_pool->buf_size);
+		if (QDF_IS_STATUS_SUCCESS(ret))
+			dp_audio_smmu_map(soc->osdev,
+					  qdf_mem_paddr_from_dmaaddr(soc->osdev,
+								     QDF_NBUF_CB_PADDR((nbuf_frag_info_t->virt_addr).nbuf)),
+					  QDF_NBUF_CB_PADDR((nbuf_frag_info_t->virt_addr).nbuf),
+					  rx_desc_pool->buf_size);
+	}
+
 
 	return ret;
 }
@@ -300,6 +314,12 @@ static void dp_rx_refill_buff_pool_init(struct dp_soc *soc, u8 mac_id)
 			continue;
 		}
 
+		dp_audio_smmu_map(soc->osdev,
+				  qdf_mem_paddr_from_dmaaddr(soc->osdev,
+							     QDF_NBUF_CB_PADDR(nbuf)),
+				  QDF_NBUF_CB_PADDR(nbuf),
+				  rx_desc_pool->buf_size);
+
 		buff_pool->buf_elem[head] = nbuf;
 		head++;
 	}
@@ -361,6 +381,9 @@ static void dp_rx_refill_buff_pool_deinit(struct dp_soc *soc, u8 mac_id)
 		return;
 
 	while ((nbuf = dp_rx_refill_buff_pool_dequeue_nbuf(soc))) {
+		dp_audio_smmu_unmap(soc->osdev,
+				    QDF_NBUF_CB_PADDR(nbuf),
+				    rx_desc_pool->buf_size);
 		qdf_nbuf_unmap_nbytes_single(soc->osdev, nbuf,
 					     QDF_DMA_BIDIRECTIONAL,
 					     rx_desc_pool->buf_size);

+ 17 - 4
dp/wifi3.0/dp_rx_buffer_pool.h

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -212,10 +213,22 @@ dp_rx_buffer_pool_nbuf_map(struct dp_soc *soc,
 			   struct rx_desc_pool *rx_desc_pool,
 			   struct dp_rx_nbuf_frag_info *nbuf_frag_info_t)
 {
-	return qdf_nbuf_map_nbytes_single(soc->osdev,
-					 (nbuf_frag_info_t->virt_addr).nbuf,
-					 QDF_DMA_FROM_DEVICE,
-					 rx_desc_pool->buf_size);
+	QDF_STATUS status;
+
+	status = qdf_nbuf_map_nbytes_single(soc->osdev,
+					    (nbuf_frag_info_t->virt_addr).nbuf,
+					    QDF_DMA_FROM_DEVICE,
+					    rx_desc_pool->buf_size);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	dp_audio_smmu_map(soc->osdev,
+			  qdf_mem_paddr_from_dmaaddr(soc->osdev,
+						     QDF_NBUF_CB_PADDR((nbuf_frag_info_t->virt_addr).nbuf)),
+			  QDF_NBUF_CB_PADDR((nbuf_frag_info_t->virt_addr).nbuf),
+			  rx_desc_pool->buf_size);
+
+	return status;
 }
 
 static inline void dp_rx_schedule_refill_thread(struct dp_soc *soc) { }

+ 5 - 0
dp/wifi3.0/dp_rx_defrag.c

@@ -1343,6 +1343,11 @@ static QDF_STATUS dp_rx_defrag_reo_reinject(struct dp_txrx_peer *txrx_peer,
 	dp_ipa_handle_rx_buf_smmu_mapping(soc, head, rx_desc_pool->buf_size,
 					  true, __func__, __LINE__);
 
+	dp_audio_smmu_map(soc->osdev,
+			  qdf_mem_paddr_from_dmaaddr(soc->osdev,
+						     QDF_NBUF_CB_PADDR(head)),
+			  QDF_NBUF_CB_PADDR(head), rx_desc_pool->buf_size);
+
 	/*
 	 * As part of rx frag handler buffer was unmapped and rx desc
 	 * unmapped is set to 1. So again for defrag reinject frame reset

+ 13 - 5
dp/wifi3.0/dp_rx_desc.c

@@ -210,7 +210,8 @@ static QDF_STATUS dp_rx_desc_nbuf_collect(struct dp_soc *soc,
 static void dp_rx_desc_nbuf_cleanup(struct dp_soc *soc,
 				    qdf_nbuf_t nbuf_unmap_list,
 				    qdf_nbuf_t nbuf_free_list,
-				    uint16_t buf_size)
+				    uint16_t buf_size,
+				    bool is_mon_pool)
 {
 	qdf_nbuf_t nbuf = nbuf_unmap_list;
 	qdf_nbuf_t next;
@@ -218,6 +219,11 @@ static void dp_rx_desc_nbuf_cleanup(struct dp_soc *soc,
 	while (nbuf) {
 		next = nbuf->next;
 
+		if (!is_mon_pool)
+			dp_audio_smmu_unmap(soc->osdev,
+					    QDF_NBUF_CB_PADDR(nbuf),
+					    buf_size);
+
 		if (dp_ipa_handle_rx_buf_smmu_mapping(soc, nbuf, buf_size,
 					   false, __func__, __LINE__))
 			dp_info_rl("Unable to unmap nbuf: %pK", nbuf);
@@ -246,12 +252,13 @@ void dp_rx_desc_nbuf_and_pool_free(struct dp_soc *soc, uint32_t pool_id,
 				&nbuf_unmap_list, &nbuf_free_list);
 	qdf_spin_unlock_bh(&rx_desc_pool->lock);
 	dp_rx_desc_nbuf_cleanup(soc, nbuf_unmap_list, nbuf_free_list,
-				rx_desc_pool->buf_size);
+				rx_desc_pool->buf_size, false);
 	qdf_spinlock_destroy(&rx_desc_pool->lock);
 }
 
 void dp_rx_desc_nbuf_free(struct dp_soc *soc,
-			  struct rx_desc_pool *rx_desc_pool)
+			  struct rx_desc_pool *rx_desc_pool,
+			  bool is_mon_pool)
 {
 	qdf_nbuf_t nbuf_unmap_list = NULL;
 	qdf_nbuf_t nbuf_free_list = NULL;
@@ -260,7 +267,7 @@ void dp_rx_desc_nbuf_free(struct dp_soc *soc,
 				&nbuf_unmap_list, &nbuf_free_list);
 	qdf_spin_unlock_bh(&rx_desc_pool->lock);
 	dp_rx_desc_nbuf_cleanup(soc, nbuf_unmap_list, nbuf_free_list,
-				rx_desc_pool->buf_size);
+				rx_desc_pool->buf_size, is_mon_pool);
 }
 
 qdf_export_symbol(dp_rx_desc_nbuf_free);
@@ -425,7 +432,8 @@ void dp_rx_desc_nbuf_and_pool_free(struct dp_soc *soc, uint32_t pool_id,
 }
 
 void dp_rx_desc_nbuf_free(struct dp_soc *soc,
-			  struct rx_desc_pool *rx_desc_pool)
+			  struct rx_desc_pool *rx_desc_pool,
+			  bool is_mon_pool)
 {
 	qdf_nbuf_t nbuf;
 	int i;

+ 1 - 1
dp/wifi3.0/monitor/1.0/dp_rx_mon_dest_1.0.c

@@ -915,7 +915,7 @@ void dp_rx_pdev_mon_buf_buffers_free(struct dp_pdev *pdev, uint32_t mac_id)
 	if (rx_desc_pool->rx_mon_dest_frag_enable)
 		dp_rx_desc_frag_free(soc, rx_desc_pool);
 	else
-		dp_rx_desc_nbuf_free(soc, rx_desc_pool);
+		dp_rx_desc_nbuf_free(soc, rx_desc_pool, true);
 }
 
 QDF_STATUS

+ 1 - 1
dp/wifi3.0/monitor/1.0/dp_rx_mon_status_1.0.c

@@ -988,7 +988,7 @@ dp_rx_pdev_mon_status_buffers_free(struct dp_pdev *pdev, uint32_t mac_id)
 
 	dp_debug("Mon RX Status Desc Pool Free pdev[%d]", pdev_id);
 
-	dp_rx_desc_nbuf_free(soc, rx_desc_pool);
+	dp_rx_desc_nbuf_free(soc, rx_desc_pool, true);
 }
 
 /*