Ver Fonte

qcacmn: Support unaligned consistent memory prealloc

Support unaligned consistent memory prealloc for CE srng
memory.

Change-Id: I7c014e4c13602de89d03e2f7c5efb39b5b376226
CRs-Fixed: 2761282
Jinwei Chen há 4 anos atrás
pai
commit
652bd3a42b
5 ficheiros alterados com 163 adições e 16 exclusões
  1. 6 0
      hif/inc/hif.h
  2. 6 0
      hif/src/ce/ce_internal.h
  3. 52 16
      hif/src/ce/ce_main.c
  4. 58 0
      hif/src/hif_main.c
  5. 41 0
      hif/src/hif_main.h

+ 6 - 0
hif/inc/hif.h

@@ -583,6 +583,8 @@ struct htc_callbacks {
  * @is_load_unload_in_progress: Query if driver state Load/Unload in Progress
  * @is_driver_unloading: Query if driver is unloading.
  * @get_bandwidth_level: Query current bandwidth level for the driver
+ * @prealloc_get_consistent_mem_unligned: get prealloc unaligned consistent mem
+ * @prealloc_put_consistent_mem_unligned: put unaligned consistent mem to pool
  * This Structure provides callback pointer for HIF to query hdd for driver
  * states.
  */
@@ -594,6 +596,10 @@ struct hif_driver_state_callbacks {
 	bool (*is_driver_unloading)(void *context);
 	bool (*is_target_ready)(void *context);
 	int (*get_bandwidth_level)(void *context);
+	void *(*prealloc_get_consistent_mem_unaligned)(qdf_size_t size,
+						       qdf_dma_addr_t *paddr,
+						       uint32_t ring_type);
+	void (*prealloc_put_consistent_mem_unaligned)(void *vaddr);
 };
 
 /* This API detaches the HTC layer from the HIF device */

+ 6 - 0
hif/src/ce/ce_internal.h

@@ -89,6 +89,12 @@ struct CE_ring_state {
 	unsigned int high_water_mark_nentries;
 	void *srng_ctx;
 	void **per_transfer_context;
+
+	/* HAL CE ring type */
+	uint32_t hal_ring_type;
+	/* ring memory prealloc */
+	uint8_t is_ring_prealloc;
+
 	OS_DMA_MEM_CONTEXT(ce_dmacontext); /* OS Specific DMA context */
 };
 

+ 52 - 16
hif/src/ce/ce_main.c

@@ -58,6 +58,10 @@
 #define QCA_WIFI_SUPPORT_SRNG
 #endif
 
+#ifdef QCA_WIFI_SUPPORT_SRNG
+#include <hal_api.h>
+#endif
+
 /* Forward references */
 QDF_STATUS hif_post_recv_buffers_for_pipe(struct HIF_CE_pipe_info *pipe_info);
 
@@ -1018,11 +1022,14 @@ static QDF_STATUS ce_alloc_desc_ring(struct hif_softc *scn, unsigned int CE_id,
 						scn->ipa_ce_ring->vaddr;
 	} else {
 		ce_ring->base_addr_owner_space_unaligned =
-			qdf_mem_alloc_consistent(scn->qdf_dev,
-						 scn->qdf_dev->dev,
-						 (nentries * desc_size +
-						 CE_DESC_RING_ALIGN),
-						 base_addr);
+			hif_mem_alloc_consistent_unaligned
+					(scn,
+					 (nentries * desc_size +
+					  CE_DESC_RING_ALIGN),
+					 base_addr,
+					 ce_ring->hal_ring_type,
+					 &ce_ring->is_ring_prealloc);
+
 		if (!ce_ring->base_addr_owner_space_unaligned) {
 			HIF_ERROR("%s: Failed to allocate DMA memory for ce ring id : %u",
 				  __func__, CE_id);
@@ -1053,10 +1060,12 @@ static void ce_free_desc_ring(struct hif_softc *scn, unsigned int CE_id,
 		}
 		ce_ring->base_addr_owner_space_unaligned = NULL;
 	} else {
-		qdf_mem_free_consistent(scn->qdf_dev, scn->qdf_dev->dev,
-			ce_ring->nentries * desc_size + CE_DESC_RING_ALIGN,
-			ce_ring->base_addr_owner_space_unaligned,
-			ce_ring->base_addr_CE_space, 0);
+		hif_mem_free_consistent_unaligned
+			(scn,
+			 ce_ring->nentries * desc_size + CE_DESC_RING_ALIGN,
+			 ce_ring->base_addr_owner_space_unaligned,
+			 ce_ring->base_addr_CE_space, 0,
+			 ce_ring->is_ring_prealloc);
 		ce_ring->base_addr_owner_space_unaligned = NULL;
 	}
 }
@@ -1067,9 +1076,14 @@ static QDF_STATUS ce_alloc_desc_ring(struct hif_softc *scn, unsigned int CE_id,
 				     unsigned int nentries, uint32_t desc_size)
 {
 	ce_ring->base_addr_owner_space_unaligned =
-		qdf_mem_alloc_consistent(scn->qdf_dev, scn->qdf_dev->dev,
+			hif_mem_alloc_consistent_unaligned
+					(scn,
 					 (nentries * desc_size +
-					 CE_DESC_RING_ALIGN), base_addr);
+					  CE_DESC_RING_ALIGN),
+					 base_addr,
+					 ce_ring->hal_ring_type,
+					 &ce_ring->is_ring_prealloc);
+
 	if (!ce_ring->base_addr_owner_space_unaligned) {
 		HIF_ERROR("%s: Failed to allocate DMA memory for ce ring id : %u",
 			  __func__, CE_id);
@@ -1081,10 +1095,12 @@ static QDF_STATUS ce_alloc_desc_ring(struct hif_softc *scn, unsigned int CE_id,
 static void ce_free_desc_ring(struct hif_softc *scn, unsigned int CE_id,
 			      struct CE_ring_state *ce_ring, uint32_t desc_size)
 {
-	qdf_mem_free_consistent(scn->qdf_dev, scn->qdf_dev->dev,
-		ce_ring->nentries * desc_size + CE_DESC_RING_ALIGN,
-		ce_ring->base_addr_owner_space_unaligned,
-		ce_ring->base_addr_CE_space, 0);
+	hif_mem_free_consistent_unaligned
+		(scn,
+		 ce_ring->nentries * desc_size + CE_DESC_RING_ALIGN,
+		 ce_ring->base_addr_owner_space_unaligned,
+		 ce_ring->base_addr_CE_space, 0,
+		 ce_ring->is_ring_prealloc);
 	ce_ring->base_addr_owner_space_unaligned = NULL;
 }
 #endif /* IPA_OFFLOAD */
@@ -1184,7 +1200,26 @@ static inline uint32_t ce_get_desc_size(struct hif_softc *scn,
 	return hif_state->ce_services->ce_get_desc_size(ring_type);
 }
 
-
+#ifdef QCA_WIFI_SUPPORT_SRNG
+static inline int32_t ce_ring_type_to_hal_ring_type(uint32_t ce_ring_type)
+{
+	switch (ce_ring_type) {
+	case CE_RING_SRC:
+		return CE_SRC;
+	case CE_RING_DEST:
+		return CE_DST;
+	case CE_RING_STATUS:
+		return CE_DST_STATUS;
+	default:
+		return -EINVAL;
+	}
+}
+#else
+static int32_t ce_ring_type_to_hal_ring_type(uint32_t ce_ring_type)
+{
+	return 0;
+}
+#endif
 static struct CE_ring_state *ce_alloc_ring_state(struct CE_state *CE_state,
 		uint8_t ring_type, uint32_t nentries)
 {
@@ -1209,6 +1244,7 @@ static struct CE_ring_state *ce_alloc_ring_state(struct CE_state *CE_state,
 	ce_ring->low_water_mark_nentries = 0;
 	ce_ring->high_water_mark_nentries = nentries;
 	ce_ring->per_transfer_context = (void **)ptr;
+	ce_ring->hal_ring_type = ce_ring_type_to_hal_ring_type(ring_type);
 
 	desc_size = ce_get_desc_size(scn, ring_type);
 

+ 58 - 0
hif/src/hif_main.c

@@ -1525,6 +1525,64 @@ int hif_get_bandwidth_level(struct hif_opaque_softc *hif_handle)
 
 qdf_export_symbol(hif_get_bandwidth_level);
 
+#ifdef DP_MEM_PRE_ALLOC
+void *hif_mem_alloc_consistent_unaligned(struct hif_softc *scn,
+					 qdf_size_t size,
+					 qdf_dma_addr_t *paddr,
+					 uint32_t ring_type,
+					 uint8_t *is_mem_prealloc)
+{
+	void *vaddr = NULL;
+	struct hif_driver_state_callbacks *cbk =
+				hif_get_callbacks_handle(scn);
+
+	*is_mem_prealloc = false;
+	if (cbk && cbk->prealloc_get_consistent_mem_unaligned) {
+		vaddr = cbk->prealloc_get_consistent_mem_unaligned(size,
+								   paddr,
+								   ring_type);
+		if (vaddr) {
+			*is_mem_prealloc = true;
+			goto end;
+		}
+	}
+
+	vaddr = qdf_mem_alloc_consistent(scn->qdf_dev,
+					 scn->qdf_dev->dev,
+					 size,
+					 paddr);
+end:
+	dp_info("%s va_unaligned %pK pa_unaligned %pK size %d ring_type %d",
+		*is_mem_prealloc ? "pre-alloc" : "dynamic-alloc", vaddr,
+		(void *)*paddr, (int)size, ring_type);
+
+	return vaddr;
+}
+
+void hif_mem_free_consistent_unaligned(struct hif_softc *scn,
+				       qdf_size_t size,
+				       void *vaddr,
+				       qdf_dma_addr_t paddr,
+				       qdf_dma_context_t memctx,
+				       uint8_t is_mem_prealloc)
+{
+	struct hif_driver_state_callbacks *cbk =
+				hif_get_callbacks_handle(scn);
+
+	if (is_mem_prealloc) {
+		if (cbk && cbk->prealloc_put_consistent_mem_unaligned) {
+			cbk->prealloc_put_consistent_mem_unaligned(vaddr);
+		} else {
+			dp_warn("dp_prealloc_put_consistent_unligned NULL");
+			QDF_BUG(0);
+		}
+	} else {
+		qdf_mem_free_consistent(scn->qdf_dev, scn->qdf_dev->dev,
+					size, vaddr, paddr, memctx);
+	}
+}
+#endif
+
 /**
  * hif_batch_send() - API to access hif specific function
  * ce_batch_send.

+ 41 - 0
hif/src/hif_main.h

@@ -381,6 +381,47 @@ void hif_wlan_disable(struct hif_softc *scn);
 int hif_target_sleep_state_adjust(struct hif_softc *scn,
 					 bool sleep_ok,
 					 bool wait_for_it);
+
+#ifdef DP_MEM_PRE_ALLOC
+void *hif_mem_alloc_consistent_unaligned(struct hif_softc *scn,
+					 qdf_size_t size,
+					 qdf_dma_addr_t *paddr,
+					 uint32_t ring_type,
+					 uint8_t *is_mem_prealloc);
+
+void hif_mem_free_consistent_unaligned(struct hif_softc *scn,
+				       qdf_size_t size,
+				       void *vaddr,
+				       qdf_dma_addr_t paddr,
+				       qdf_dma_context_t memctx,
+				       uint8_t is_mem_prealloc);
+#else
+static inline
+void *hif_mem_alloc_consistent_unaligned(struct hif_softc *scn,
+					 qdf_size_t size,
+					 qdf_dma_addr_t *paddr,
+					 uint32_t ring_type,
+					 uint8_t *is_mem_prealloc)
+{
+	return qdf_mem_alloc_consistent(scn->qdf_dev,
+					scn->qdf_dev->dev,
+					size,
+					paddr);
+}
+
+static inline
+void hif_mem_free_consistent_unaligned(struct hif_softc *scn,
+				       qdf_size_t size,
+				       void *vaddr,
+				       qdf_dma_addr_t paddr,
+				       qdf_dma_context_t memctx,
+				       uint8_t is_mem_prealloc)
+{
+	return qdf_mem_free_consistent(scn->qdf_dev, scn->qdf_dev->dev,
+				       size, vaddr, paddr, memctx);
+}
+#endif
+
 /**
  * hif_get_rx_ctx_id() - Returns NAPI instance ID based on CE ID
  * @ctx_id: Rx CE context ID