فهرست منبع

qcacmn: Avoid use of map and unmap API in simple path

Add qdf wrapper for dma_clean_range and avoid use of DMA
map/unmap APIs in Tx. simple fast path.
Gain of ~150 Mbps is observed while running 4 radio traffic.

Change-Id: I0e96bfee43fe810da8c861cb0f4535fb0ba7f6f7
Neha Bisht 3 سال پیش
والد
کامیت
ebf445a844
4فایلهای تغییر یافته به همراه82 افزوده شده و 9 حذف شده
  1. 48 8
      dp/wifi3.0/dp_tx.c
  2. 13 0
      qdf/inc/qdf_nbuf.h
  3. 3 0
      qdf/linux/src/i_qdf_nbuf_m.h
  4. 18 1
      qdf/linux/src/i_qdf_nbuf_w.h

+ 48 - 8
dp/wifi3.0/dp_tx.c

@@ -1852,6 +1852,49 @@ static inline QDF_STATUS dp_tx_msdu_single_map(struct dp_vdev *vdev,
 }
 #endif
 
+#if defined(QCA_DP_TX_NBUF_NO_MAP_UNMAP) && !defined(BUILD_X86)
+static inline
+qdf_dma_addr_t dp_tx_nbuf_map(struct dp_vdev *vdev,
+			      struct dp_tx_desc_s *tx_desc,
+			      qdf_nbuf_t nbuf)
+{
+	qdf_nbuf_dma_clean_range((void *)nbuf->data,
+				 (void *)(nbuf->data + nbuf->len));
+	return (qdf_dma_addr_t)qdf_mem_virt_to_phys(nbuf->data);
+}
+
+static inline
+void dp_tx_nbuf_unmap(struct dp_soc *soc,
+		      struct dp_tx_desc_s *desc)
+{
+}
+#else
+static inline
+qdf_dma_addr_t dp_tx_nbuf_map(struct dp_vdev *vdev,
+			      struct dp_tx_desc_s *tx_desc,
+			      qdf_nbuf_t nbuf)
+{
+	QDF_STATUS ret = QDF_STATUS_E_FAILURE;
+
+	ret = dp_tx_msdu_single_map(vdev, tx_desc, nbuf);
+	if (qdf_unlikely(QDF_IS_STATUS_ERROR(ret)))
+		return 0;
+
+	return qdf_nbuf_mapped_paddr_get(nbuf);
+}
+
+static inline
+void dp_tx_nbuf_unmap(struct dp_soc *soc,
+		      struct dp_tx_desc_s *desc)
+{
+	qdf_nbuf_unmap_nbytes_single_paddr(soc->osdev,
+					   desc->nbuf,
+					   desc->dma_addr,
+					   QDF_DMA_TO_DEVICE,
+					   desc->length);
+}
+#endif
+
 #ifdef MESH_MODE_SUPPORT
 /**
  * dp_tx_update_mesh_flags() - Update descriptor flags for mesh VAP
@@ -2006,6 +2049,7 @@ dp_tx_send_msdu_single(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
 	enum cdp_tx_sw_drop drop_code = TX_MAX_DROP;
 	uint8_t tid = msdu_info->tid;
 	struct cdp_tid_tx_stats *tid_stats = NULL;
+	qdf_dma_addr_t paddr;
 
 	/* Setup Tx descriptor for an MSDU, and MSDU extension descriptor */
 	tx_desc = dp_tx_prepare_desc_single(vdev, nbuf, tx_q->desc_pool_id,
@@ -2038,8 +2082,8 @@ dp_tx_send_msdu_single(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
 
 	dp_tx_update_mesh_flags(soc, vdev, tx_desc);
 
-	if (qdf_unlikely(QDF_STATUS_SUCCESS !=
-			 dp_tx_msdu_single_map(vdev, tx_desc, nbuf))) {
+	paddr =  dp_tx_nbuf_map(vdev, tx_desc, nbuf);
+	if (!paddr) {
 		/* Handle failure */
 		dp_err("qdf_nbuf_map failed");
 		DP_STATS_INC(vdev, tx_i.dropped.dma_error, 1);
@@ -2047,7 +2091,7 @@ dp_tx_send_msdu_single(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
 		goto release_desc;
 	}
 
-	tx_desc->dma_addr = qdf_nbuf_mapped_paddr_get(tx_desc->nbuf);
+	tx_desc->dma_addr = paddr;
 	dp_tx_desc_history_add(soc, tx_desc->dma_addr, nbuf,
 			       tx_desc->id, DP_TX_DESC_MAP);
 	dp_tx_update_mcast_param(peer_id, &htt_tcl_metadata, vdev, msdu_info);
@@ -4512,11 +4556,7 @@ dp_tx_comp_process_desc_list(struct dp_soc *soc,
 			 */
 			dp_tx_desc_history_add(soc, desc->dma_addr, desc->nbuf,
 					       desc->id, DP_TX_COMP_UNMAP);
-			qdf_nbuf_unmap_nbytes_single_paddr(soc->osdev,
-							   desc->nbuf,
-							   desc->dma_addr,
-							   QDF_DMA_TO_DEVICE,
-							   desc->length);
+			dp_tx_nbuf_unmap(soc, desc);
 			qdf_nbuf_free(desc->nbuf);
 			dp_tx_desc_free(soc, desc, desc->pool_id);
 			desc = next;

+ 13 - 0
qdf/inc/qdf_nbuf.h

@@ -1133,6 +1133,19 @@ static inline int qdf_nbuf_get_num_frags(qdf_nbuf_t buf)
 	return __qdf_nbuf_get_num_frags(buf);
 }
 
+/**
+ * qdf_nbuf_dma_clean_range() - Clean the specified virtual address range
+ * @buf_start: start address
+ * @buf_end: end address
+ *
+ * Return: none
+ */
+static inline void
+qdf_nbuf_dma_clean_range(const void *buf_start, const void *buf_end)
+{
+	__qdf_nbuf_dma_clean_range(buf_start, buf_end);
+}
+
 /**
  * qdf_nbuf_get_frag_len() - get fragment length
  * @buf: Network buffer

+ 3 - 0
qdf/linux/src/i_qdf_nbuf_m.h

@@ -212,4 +212,7 @@ __qdf_nbuf_dma_clean_range_no_dsb(const void *buf_start, const void *buf_end) {}
 
 static inline void
 __qdf_dsb(void) {}
+
+static inline void
+__qdf_nbuf_dma_clean_range(const void *buf_start, const void *buf_end) {}
 #endif /*_I_QDF_NBUF_M_H */

+ 18 - 1
qdf/linux/src/i_qdf_nbuf_w.h

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2014-2022 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-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
@@ -190,6 +190,11 @@ __qdf_dsb(void)
 #endif
 }
 
+static inline void
+__qdf_nbuf_dma_clean_range(const void *buf_start, const void *buf_end)
+{
+	dmac_clean_range(buf_start, buf_end);
+}
 #elif defined(__LINUX_MIPS32_ARCH__) || defined(__LINUX_MIPS64_ARCH__)
 static inline void
 __qdf_nbuf_dma_inv_range(const void *buf_start, const void *buf_end)
@@ -216,6 +221,13 @@ static inline void
 __qdf_dsb(void)
 {
 }
+
+static inline void
+__qdf_nbuf_dma_clean_range(const void *buf_start, const void *buf_end)
+{
+	dma_cache_wback((unsigned long)buf_start,
+			(unsigned long)(buf_end - buf_start));
+}
 #else
 static inline void
 __qdf_nbuf_dma_inv_range(const void *buf_start, const void *buf_end)
@@ -236,5 +248,10 @@ static inline void
 __qdf_dsb(void)
 {
 }
+
+static inline void
+__qdf_nbuf_dma_clean_range(const void *buf_start, const void *buf_end)
+{
+}
 #endif
 #endif /*_I_QDF_NBUF_W_H */