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

Commit bd88344f authored by Wu Gao's avatar Wu Gao Committed by nshrivas
Browse files

qcacmn: Allocate lut based on number of DBR entry

CFR component allocate 140 luts but some of platform use 48 of them,
which allocate huge memory at one time and waste memory in some
platform. In low memory case, it may be failed to alloc luts at one
time. So, allocate lut based on number of DBR entry and split memory
allocation.

Change-Id: Id49c3f9a0f81cfa6d639cb72b62bb377911f0e77
CRs-Fixed: 2679470
parent bf5f67ee
Loading
Loading
Loading
Loading
+8 −6
Original line number Diff line number Diff line
@@ -44,11 +44,13 @@ static u_int32_t end_magic = 0xBEAFDEAD;
static struct look_up_table *get_lut_entry(struct pdev_cfr *pcfr,
					   int offset)
{
	if (offset > NUM_LUT_ENTRIES) {
		cfr_err("Invalid offset\n");
	if (offset >= pcfr->lut_num) {
		cfr_err("Invalid offset %d, lut_num %d",
			offset, pcfr->lut_num);
		return NULL;
	}
	return &pcfr->lut[offset];

	return pcfr->lut[offset];
}

/**
@@ -105,7 +107,7 @@ void target_if_cfr_dump_lut_enh(struct wlan_objmgr_pdev *pdev)
		return;
	}

	for (i = 0; i < NUM_LUT_ENTRIES; i++) {
	for (i = 0; i < pcfr->lut_num; i++) {
		lut = get_lut_entry(pcfr, i);
		if (!lut)
			continue;
@@ -153,7 +155,7 @@ static void cfr_free_pending_dbr_events(struct wlan_objmgr_pdev *pdev)
		return;
	}

	for (i = 0; i < NUM_LUT_ENTRIES; i++) {
	for (i = 0; i < pcfr->lut_num; i++) {
		lut = get_lut_entry(pcfr, i);
		if (!lut)
			continue;
@@ -1375,7 +1377,7 @@ static os_timer_func(lut_ageout_timer_task)

	cur_tstamp = qdf_ktime_to_ms(qdf_ktime_get());

	for (i = 0; i < NUM_LUT_ENTRIES; i++) {
	for (i = 0; i < pcfr->lut_num; i++) {
		lut = get_lut_entry(pcfr, i);
		if (!lut)
			continue;
+80 −12
Original line number Diff line number Diff line
@@ -24,10 +24,58 @@
#include <wlan_cfr_tgt_api.h>
#include <qdf_streamfs.h>
#include <target_if.h>
#include <target_if_direct_buf_rx_api.h>
#ifndef CFR_USE_FIXED_FOLDER
#include <os_if_athvar.h>
#endif

/**
 * wlan_cfr_get_dbr_num_entries() - Get entry number of DBR ring
 * @pdev - the physical device object.
 *
 * Return : Entry number of DBR ring.
 */
static uint32_t
wlan_cfr_get_dbr_num_entries(struct wlan_objmgr_pdev *pdev)
{
	struct wlan_objmgr_psoc *psoc;
	struct wlan_psoc_host_dbr_ring_caps *dbr_ring_cap;
	uint8_t num_dbr_ring_caps, cap_idx, pdev_id;
	struct target_psoc_info *tgt_psoc_info;
	uint32_t num_entries = MAX_LUT_ENTRIES;

	if (!pdev) {
		cfr_err("Invalid pdev");
		return num_entries;
	}

	psoc = wlan_pdev_get_psoc(pdev);
	if (!psoc) {
		cfr_err("psoc is null");
		return num_entries;
	}

	tgt_psoc_info = wlan_psoc_get_tgt_if_handle(psoc);
	if (!tgt_psoc_info) {
		cfr_err("target_psoc_info is null");
		return num_entries;
	}

	num_dbr_ring_caps = target_psoc_get_num_dbr_ring_caps(tgt_psoc_info);
	dbr_ring_cap = target_psoc_get_dbr_ring_caps(tgt_psoc_info);
	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);

	for (cap_idx = 0; cap_idx < num_dbr_ring_caps; cap_idx++) {
		if (dbr_ring_cap[cap_idx].pdev_id == pdev_id &&
		    dbr_ring_cap[cap_idx].mod_id == DBR_MODULE_CFR)
			num_entries = dbr_ring_cap[cap_idx].ring_elems_min;
	}

	num_entries = QDF_MIN(num_entries, MAX_LUT_ENTRIES);
	cfr_debug("pdev id %d, num_entries %d", pdev_id, num_entries);

	return num_entries;
}

QDF_STATUS
wlan_cfr_psoc_obj_create_handler(struct wlan_objmgr_psoc *psoc, void *arg)
@@ -35,12 +83,11 @@ wlan_cfr_psoc_obj_create_handler(struct wlan_objmgr_psoc *psoc, void *arg)
	struct psoc_cfr *cfr_sc = NULL;

	cfr_sc = (struct psoc_cfr *)qdf_mem_malloc(sizeof(struct psoc_cfr));
	if (NULL == cfr_sc) {
	if (!cfr_sc) {
		cfr_err("Failed to allocate cfr_ctx object\n");
		return QDF_STATUS_E_NOMEM;
	}

	qdf_mem_zero(cfr_sc, sizeof(struct psoc_cfr));
	cfr_sc->psoc_obj = psoc;

	wlan_objmgr_psoc_component_obj_attach(psoc, WLAN_UMAC_COMP_CFR,
@@ -57,7 +104,7 @@ wlan_cfr_psoc_obj_destroy_handler(struct wlan_objmgr_psoc *psoc, void *arg)

	cfr_sc = wlan_objmgr_psoc_get_comp_private_obj(psoc,
						       WLAN_UMAC_COMP_CFR);
	if (NULL != cfr_sc) {
	if (cfr_sc) {
		wlan_objmgr_psoc_component_obj_detach(psoc, WLAN_UMAC_COMP_CFR,
						      (void *)cfr_sc);
		qdf_mem_free(cfr_sc);
@@ -70,19 +117,34 @@ QDF_STATUS
wlan_cfr_pdev_obj_create_handler(struct wlan_objmgr_pdev *pdev, void *arg)
{
	struct pdev_cfr *pa = NULL;
	uint32_t idx;

	if (NULL == pdev) {
	if (!pdev) {
		cfr_err("PDEV is NULL\n");
		return QDF_STATUS_E_FAILURE;
	}

	pa = (struct pdev_cfr *)qdf_mem_malloc(sizeof(struct pdev_cfr));
	if (NULL == pa) {
	if (!pa) {
		cfr_err("Failed to allocate pdev_cfr object\n");
		return QDF_STATUS_E_NOMEM;
	}
	qdf_mem_zero(pa, sizeof(struct pdev_cfr));
	pa->pdev_obj = pdev;
	pa->lut_num = wlan_cfr_get_dbr_num_entries(pdev);
	if (!pa->lut_num) {
		cfr_err("lut num is 0");
		return QDF_STATUS_E_INVAL;
	}
	pa->lut = (struct look_up_table **)qdf_mem_malloc(pa->lut_num *
			sizeof(struct look_up_table *));
	if (!pa->lut) {
		cfr_err("Failed to allocate lut, lut num %d", pa->lut_num);
		qdf_mem_free(pa);
		return QDF_STATUS_E_NOMEM;
	}
	for (idx = 0; idx < pa->lut_num; idx++)
		pa->lut[idx] = (struct look_up_table *)qdf_mem_malloc(
			sizeof(struct look_up_table));

	wlan_objmgr_pdev_component_obj_attach(pdev, WLAN_UMAC_COMP_CFR,
					      (void *)pa, QDF_STATUS_SUCCESS);
@@ -94,16 +156,22 @@ QDF_STATUS
wlan_cfr_pdev_obj_destroy_handler(struct wlan_objmgr_pdev *pdev, void *arg)
{
	struct pdev_cfr *pa = NULL;
	uint32_t idx;

	if (NULL == pdev) {
	if (!pdev) {
		cfr_err("PDEV is NULL\n");
		return QDF_STATUS_E_FAILURE;
	}

	pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR);
	if (NULL != pa) {
	if (pa) {
		wlan_objmgr_pdev_component_obj_detach(pdev, WLAN_UMAC_COMP_CFR,
						      (void *)pa);
		if (pa->lut) {
			for (idx = 0; idx < pa->lut_num; idx++)
				qdf_mem_free(pa->lut[idx]);
			qdf_mem_free(pa->lut);
		}
		qdf_mem_free(pa);
	}

@@ -115,13 +183,13 @@ wlan_cfr_peer_obj_create_handler(struct wlan_objmgr_peer *peer, void *arg)
{
	struct peer_cfr *pe = NULL;

	if (NULL == peer) {
	if (!peer) {
		cfr_err("PEER is NULL\n");
		return QDF_STATUS_E_FAILURE;
	}

	pe = (struct peer_cfr *)qdf_mem_malloc(sizeof(struct peer_cfr));
	if (NULL == pe) {
	if (!pe) {
		cfr_err("Failed to allocate peer_cfr object\n");
		return QDF_STATUS_E_FAILURE;
	}
@@ -142,7 +210,7 @@ wlan_cfr_peer_obj_destroy_handler(struct wlan_objmgr_peer *peer, void *arg)
	struct wlan_objmgr_pdev *pdev = NULL;
	struct pdev_cfr *pa = NULL;

	if (NULL == peer) {
	if (!peer) {
		cfr_err("PEER is NULL\n");
		return QDF_STATUS_E_FAILURE;
	}
@@ -162,7 +230,7 @@ wlan_cfr_peer_obj_destroy_handler(struct wlan_objmgr_peer *peer, void *arg)
			pa->cfr_current_sta_count--;
	}

	if (NULL != pe) {
	if (pe) {
		wlan_objmgr_peer_component_obj_detach(peer, WLAN_UMAC_COMP_CFR,
						      (void *)pe);
		qdf_mem_free(pe);
+3 −1
Original line number Diff line number Diff line
@@ -441,6 +441,7 @@ struct cfr_rcc_param {
 * dir_ptr: Parent directory of relayfs file
 * lut: lookup table used to store asynchronous DBR and TX/RX events for
 * correlation
 * lut_num: Number of lut
 * dbr_buf_size: Size of DBR completion buffer
 * dbr_num_bufs: No. of DBR completions
 * tx_evt_cnt: No. of TX completion events till CFR stop was issued
@@ -481,7 +482,8 @@ struct pdev_cfr {
	uint32_t subbuf_size;
	qdf_streamfs_chan_t chan_ptr;
	qdf_dentry_t dir_ptr;
	struct look_up_table lut[MAX_LUT_ENTRIES];
	struct look_up_table **lut;
	uint32_t lut_num;
	uint32_t dbr_buf_size;
	uint32_t dbr_num_bufs;
	uint64_t tx_evt_cnt;