Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f7d77da6 authored by Mohit Khanna's avatar Mohit Khanna Committed by snandini
Browse files

qcacmn: Add support to use pre-alloc mem

Add logic to pre-allocate DP consistent memory and reuse later
on wifi on/off. This prevents memory fragmentation.

Change-Id: I1e5eb0da39950a5d028dd46d38ff715f283e53ff
CRs-Fixed: 2740889
parent 2e3a4044
Loading
Loading
Loading
Loading
+15 −4
Original line number Diff line number Diff line
@@ -1098,12 +1098,23 @@ struct ol_if_ops {
	enum QDF_GLOBAL_MODE (*get_con_mode)(void);
#ifdef QCA_PEER_MULTIQ_SUPPORT
	int (*peer_ast_flowid_map)(struct cdp_ctrl_objmgr_psoc *ol_soc_handle,
			       uint16_t peer_id, uint8_t vdev_id, uint8_t *peer_mac_addr);
				   uint16_t peer_id, uint8_t vdev_id,
				   uint8_t *peer_mac_addr);
#endif
#ifdef DP_MEM_PRE_ALLOC
	void *(*dp_prealloc_get_consistent)(uint32_t *size,
					    void **base_vaddr_unaligned,
					    qdf_dma_addr_t *paddr_unaligned,
					    qdf_dma_addr_t *paddr_aligned,
					    uint32_t align,
					    uint32_t ring_type);
	void (*dp_prealloc_put_consistent)(qdf_size_t size,
					   void *vaddr_unligned,
					   qdf_dma_addr_t paddr);
#endif
	/* TODO: Add any other control path calls required to OL_IF/WMA layer */

};


#ifdef DP_PEER_EXTENDED_API
/**
 * struct cdp_misc_ops - mcl ops not classified
+2 −0
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@
#include "dp_types.h"

#define RX_BUFFER_SIZE_PKTLOG_LITE 1024
/* Alignment for consistent memory for DP rings*/
#define DP_RING_BASE_ALIGN 8


#define DP_RSSI_INVAL 0x80
+102 −23
Original line number Diff line number Diff line
@@ -1348,6 +1348,96 @@ dp_srng_configure_interrupt_thresholds(struct dp_soc *soc,
}
#endif


#ifdef DP_MEM_PRE_ALLOC
static inline
void *dp_srng_aligned_mem_alloc_consistent(struct dp_soc *soc,
					   struct dp_srng *srng,
					   struct hal_srng_params *ring_params,
					   uint32_t ring_type)
{
	void *mem;

	qdf_assert(!srng->is_mem_prealloc);

	if (!soc->cdp_soc.ol_ops->dp_prealloc_get_consistent) {
		dp_warn("dp_prealloc_get_consistent is null!");
		goto qdf;
	}

	mem =
		soc->cdp_soc.ol_ops->dp_prealloc_get_consistent
						(&srng->alloc_size,
						&srng->base_vaddr_unaligned,
						&srng->base_paddr_unaligned,
						&ring_params->ring_base_paddr,
						DP_RING_BASE_ALIGN, ring_type);

	if (mem) {
		srng->is_mem_prealloc = true;
		goto end;
	}
qdf:
	mem =  qdf_aligned_mem_alloc_consistent(soc->osdev, &srng->alloc_size,
						&srng->base_vaddr_unaligned,
						&srng->base_paddr_unaligned,
						&ring_params->ring_base_paddr,
						DP_RING_BASE_ALIGN);
end:
	dp_info("%s memory %pK dp_srng %pK alloc_size %d num_entries %d",
		srng->is_mem_prealloc ? "pre-alloc" : "dynamic-alloc", mem,
		srng, srng->alloc_size, srng->num_entries);
	return mem;
}

static inline void dp_srng_mem_free_consistent(struct dp_soc *soc,
					       struct dp_srng *srng)
{
	if (srng->is_mem_prealloc) {
		if (!soc->cdp_soc.ol_ops->dp_prealloc_put_consistent) {
			dp_warn("dp_prealloc_put_consistent is null!");
			QDF_BUG(0);
			return;
		}
		soc->cdp_soc.ol_ops->dp_prealloc_put_consistent
						(srng->alloc_size,
						 srng->base_vaddr_unaligned,
						 srng->base_paddr_unaligned);

	} else {
		qdf_mem_free_consistent(soc->osdev, soc->osdev->dev,
					srng->alloc_size,
					srng->base_vaddr_unaligned,
					srng->base_paddr_unaligned, 0);
	}
}

#else

static inline
void *dp_srng_aligned_mem_alloc_consistent(struct dp_soc *soc,
					   struct dp_srng *srng,
					   struct hal_srng_params *ring_params,
					   uint32_t ring_type)

{
	return qdf_aligned_mem_alloc_consistent(soc->osdev, &srng->alloc_size,
						&srng->base_vaddr_unaligned,
						&srng->base_paddr_unaligned,
						&ring_params->ring_base_paddr,
						DP_RING_BASE_ALIGN);
}

static inline void dp_srng_mem_free_consistent(struct dp_soc *soc,
					       struct dp_srng *srng)
{
	qdf_mem_free_consistent(soc->osdev, soc->osdev->dev,
				srng->alloc_size,
				srng->base_vaddr_unaligned,
				srng->base_paddr_unaligned, 0);
}

#endif /* DP_MEM_PRE_ALLOC */
/**
 * dp_srng_setup() - Internal function to setup SRNG rings used by data path
 * @soc: datapath soc handle
@@ -1364,8 +1454,6 @@ static int dp_srng_setup(struct dp_soc *soc, struct dp_srng *srng,
{
	hal_soc_handle_t hal_soc = soc->hal_soc;
	uint32_t entry_size = hal_srng_get_entrysize(hal_soc, ring_type);
	/* TODO: See if we should get align size from hal */
	uint32_t ring_base_align = 8;
	struct hal_srng_params ring_params;
	uint32_t max_entries = hal_srng_max_entries(hal_soc, ring_type);

@@ -1382,19 +1470,16 @@ static int dp_srng_setup(struct dp_soc *soc, struct dp_srng *srng,
	if (!dp_is_soc_reinit(soc)) {
		if (!cached) {
			ring_params.ring_base_vaddr =
			    qdf_aligned_mem_alloc_consistent(
						soc->osdev, &srng->alloc_size,
						&srng->base_vaddr_unaligned,
						&srng->base_paddr_unaligned,
						&ring_params.ring_base_paddr,
						ring_base_align);
			    dp_srng_aligned_mem_alloc_consistent(soc, srng,
								 &ring_params,
								 ring_type);
		} else {
			ring_params.ring_base_vaddr = qdf_aligned_malloc(
					&srng->alloc_size,
					&srng->base_vaddr_unaligned,
					&srng->base_paddr_unaligned,
					&ring_params.ring_base_paddr,
					ring_base_align);
					DP_RING_BASE_ALIGN);
		}

		if (!ring_params.ring_base_vaddr) {
@@ -1406,7 +1491,7 @@ static int dp_srng_setup(struct dp_soc *soc, struct dp_srng *srng,

	ring_params.ring_base_paddr = (qdf_dma_addr_t)qdf_align(
			(unsigned long)(srng->base_paddr_unaligned),
			ring_base_align);
			DP_RING_BASE_ALIGN);

	ring_params.ring_base_vaddr = (void *)(
			(unsigned long)(srng->base_vaddr_unaligned) +
@@ -1417,7 +1502,7 @@ static int dp_srng_setup(struct dp_soc *soc, struct dp_srng *srng,

	ring_params.num_entries = num_entries;

	dp_verbose_debug("Ring type: %d, num:%d vaddr %pK paddr %pK entries %u",
	dp_info("Ring type: %d, num:%d vaddr %pK paddr %pK entries %u",
		ring_type, ring_num,
		(void *)ring_params.ring_base_vaddr,
		(void *)ring_params.ring_base_paddr,
@@ -1451,10 +1536,7 @@ static int dp_srng_setup(struct dp_soc *soc, struct dp_srng *srng,
		if (cached) {
			qdf_mem_free(srng->base_vaddr_unaligned);
		} else {
			qdf_mem_free_consistent(soc->osdev, soc->osdev->dev,
						srng->alloc_size,
						srng->base_vaddr_unaligned,
						srng->base_paddr_unaligned, 0);
			dp_srng_mem_free_consistent(soc, srng);
		}
	}

@@ -1508,10 +1590,7 @@ static void dp_srng_cleanup(struct dp_soc *soc, struct dp_srng *srng,

	if (srng->alloc_size && srng->base_vaddr_unaligned) {
		if (!srng->cached) {
			qdf_mem_free_consistent(soc->osdev, soc->osdev->dev,
						srng->alloc_size,
						srng->base_vaddr_unaligned,
						srng->base_paddr_unaligned, 0);
			dp_srng_mem_free_consistent(soc, srng);
		} else {
			qdf_mem_free(srng->base_vaddr_unaligned);
		}
+3 −0
Original line number Diff line number Diff line
@@ -503,6 +503,9 @@ struct dp_srng {
	uint8_t cached;
	int irq;
	uint32_t num_entries;
#ifdef DP_MEM_PRE_ALLOC
	uint8_t is_mem_prealloc;
#endif
};

struct dp_rx_reorder_array_elem {