/*
 * HND generic packet pool operation primitives
 *
 * Copyright (C) 2020, Broadcom.
 *
 *      Unless you and Broadcom execute a separate written software license
 * agreement governing use of this software, this software is licensed to you
 * under the terms of the GNU General Public License version 2 (the "GPL"),
 * available at http://www.broadcom.com/licenses/GPLv2.php, with the
 * following added to such license:
 *
 *      As a special exception, the copyright holders of this software give you
 * permission to link this software with independent modules, and to copy and
 * distribute the resulting executable under terms of your choice, provided that
 * you also meet, for each linked independent module, the terms and conditions of
 * the license of that module.  An independent module is a module which is not
 * derived from this software.  The special exception does not apply to any
 * modifications of the software.
 *
 *
 * <<Broadcom-WL-IPTag/Dual:>>
 */

#include <typedefs.h>
#include <osl.h>
#include <osl_ext.h>
#include <bcmutils.h>
#include <wlioctl.h>
#include <hnd_pktpool.h>
#ifdef HWA
#include <hwa_pub_shared.h>
#endif /* HWA */
#ifdef BCMRESVFRAGPOOL
#include <hnd_resvpool.h>
#endif /* BCMRESVFRAGPOOL */
#ifdef BCMFRWDPOOLREORG
#include <hnd_poolreorg.h>
#endif /* BCMFRWDPOOLREORG */

/* mutex macros for thread safe */
#ifdef HND_PKTPOOL_THREAD_SAFE
#define HND_PKTPOOL_MUTEX_CREATE(name, mutex)	osl_ext_mutex_create(name, mutex)
#define HND_PKTPOOL_MUTEX_DELETE(mutex)		osl_ext_mutex_delete(mutex)
#define HND_PKTPOOL_MUTEX_ACQUIRE(mutex, msec)	osl_ext_mutex_acquire(mutex, msec)
#define HND_PKTPOOL_MUTEX_RELEASE(mutex)	osl_ext_mutex_release(mutex)
#else
#define HND_PKTPOOL_MUTEX_CREATE(name, mutex)	OSL_EXT_SUCCESS
#define HND_PKTPOOL_MUTEX_DELETE(mutex)		OSL_EXT_SUCCESS
#define HND_PKTPOOL_MUTEX_ACQUIRE(mutex, msec)	OSL_EXT_SUCCESS
#define HND_PKTPOOL_MUTEX_RELEASE(mutex)	OSL_EXT_SUCCESS
#endif

/* Registry size is one larger than max pools, as slot #0 is reserved */
#define PKTPOOLREG_RSVD_ID				(0U)
#define PKTPOOLREG_RSVD_PTR				(POOLPTR(0xdeaddead))
#define PKTPOOLREG_FREE_PTR				(POOLPTR(NULL))

#define PKTPOOL_REGISTRY_SET(id, pp)	(pktpool_registry_set((id), (pp)))
#define PKTPOOL_REGISTRY_CMP(id, pp)	(pktpool_registry_cmp((id), (pp)))

/* Tag a registry entry as free for use */
#define PKTPOOL_REGISTRY_CLR(id)		\
		PKTPOOL_REGISTRY_SET((id), PKTPOOLREG_FREE_PTR)
#define PKTPOOL_REGISTRY_ISCLR(id)		\
		(PKTPOOL_REGISTRY_CMP((id), PKTPOOLREG_FREE_PTR))

/* Tag registry entry 0 as reserved */
#define PKTPOOL_REGISTRY_RSV()			\
		PKTPOOL_REGISTRY_SET(PKTPOOLREG_RSVD_ID, PKTPOOLREG_RSVD_PTR)
#define PKTPOOL_REGISTRY_ISRSVD()		\
		(PKTPOOL_REGISTRY_CMP(PKTPOOLREG_RSVD_ID, PKTPOOLREG_RSVD_PTR))

/* Walk all un-reserved entries in registry */
#define PKTPOOL_REGISTRY_FOREACH(id)	\
		for ((id) = 1U; (id) <= pktpools_max; (id)++)

enum pktpool_empty_cb_state {
	EMPTYCB_ENABLED = 0,	/* Enable callback when new packets are added to pool */
	EMPTYCB_DISABLED,	/* Disable callback when new packets are added to pool */
	EMPTYCB_SKIPPED		/* Packet was added to pool when callback was disabled */
};

uint32 pktpools_max = 0U; /* maximum number of pools that may be initialized */
pktpool_t *pktpools_registry[PKTPOOL_MAXIMUM_ID + 1]; /* Pktpool registry */

#ifdef POOL_HEAP_RECONFIG
typedef struct pktpool_heap_cb_reg {
	pktpool_heap_cb_t fn;
	void *ctxt;
	uint32 flag;
} pktpool_heap_cb_reg_t;
#define PKTPOOL_MAX_HEAP_CB	2
pktpool_heap_cb_reg_t	pktpool_heap_cb_reg[PKTPOOL_MAX_HEAP_CB];
uint32 pktpool_heap_rel_active = 0U;

typedef struct d11hdr_buf_list {
	struct d11hdr_buf_list *next;
	uint8 data[];
} d11hdr_buf_list_t;
#ifndef HWA
static void hnd_pktpool_heap_pkt_release(osl_t *osh, pktpool_t *pktp, uint32 flag);
static void hnd_pktpool_heap_pkt_retrieve(pktpool_t *pktp, uint32 flag);
#endif /* !HWA */
static int hnd_pktpool_heap_get_cb(uint8 handle, void *ctxt, void *pkt, uint pktsize);
static void hnd_pktpool_lbuf_free_cb(uint8 poolid);
static pktpool_heap_cb_reg_t *BCMRAMFN(hnd_pool_get_cb_registry)(void);
#endif /* POOL_HEAP_RECONFIG */

/* Register/Deregister a pktpool with registry during pktpool_init/deinit */
static int pktpool_register(pktpool_t * poolptr);
static int pktpool_deregister(pktpool_t * poolptr);

/** add declaration */
static void pktpool_avail_notify(pktpool_t *pktp);

/** accessor functions required when ROMming this file, forced into RAM */

pktpool_t *
BCMRAMFN(get_pktpools_registry)(int id)
{
	return pktpools_registry[id];
}

static void
BCMRAMFN(pktpool_registry_set)(int id, pktpool_t *pp)
{
	pktpools_registry[id] = pp;
}

static bool
BCMRAMFN(pktpool_registry_cmp)(int id, pktpool_t *pp)
{
	return pktpools_registry[id] == pp;
}

/** Constructs a pool registry to serve a maximum of total_pools */
int
pktpool_attach(osl_t *osh, uint32 total_pools)
{
	uint32 poolid;
	BCM_REFERENCE(osh);

	if (pktpools_max != 0U) {
		return BCME_ERROR;
	}

	ASSERT(total_pools <= PKTPOOL_MAXIMUM_ID);

	/* Initialize registry: reserve slot#0 and tag others as free */
	PKTPOOL_REGISTRY_RSV();		/* reserve slot#0 */

	PKTPOOL_REGISTRY_FOREACH(poolid) {	/* tag all unreserved entries as free */
		PKTPOOL_REGISTRY_CLR(poolid);
	}

	pktpools_max = total_pools;

	return (int)pktpools_max;
}

/** Destructs the pool registry. Ascertain all pools were first de-inited */
int
pktpool_dettach(osl_t *osh)
{
	uint32 poolid;
	BCM_REFERENCE(osh);

	if (pktpools_max == 0U) {
		return BCME_OK;
	}

	/* Ascertain that no pools are still registered */
	ASSERT(PKTPOOL_REGISTRY_ISRSVD()); /* assert reserved slot */

	PKTPOOL_REGISTRY_FOREACH(poolid) {	/* ascertain all others are free */
		ASSERT(PKTPOOL_REGISTRY_ISCLR(poolid));
	}

	pktpools_max = 0U; /* restore boot state */

	return BCME_OK;
}

/** Registers a pool in a free slot; returns the registry slot index */
static int
pktpool_register(pktpool_t * poolptr)
{
	uint32 poolid;

	if (pktpools_max == 0U) {
		return PKTPOOL_INVALID_ID; /* registry has not yet been constructed */
	}

	ASSERT(pktpools_max != 0U);

	/* find an empty slot in pktpools_registry */
	PKTPOOL_REGISTRY_FOREACH(poolid) {
		if (PKTPOOL_REGISTRY_ISCLR(poolid)) {
			PKTPOOL_REGISTRY_SET(poolid, POOLPTR(poolptr)); /* register pool */
			return (int)poolid; /* return pool ID */
		}
	} /* FOREACH */

	return PKTPOOL_INVALID_ID;	/* error: registry is full */
}

/** Deregisters a pktpool, given the pool pointer; tag slot as free */
static int
pktpool_deregister(pktpool_t * poolptr)
{
	uint32 poolid;

	ASSERT(POOLPTR(poolptr) != POOLPTR(NULL));

	poolid = POOLID(poolptr);
	ASSERT(poolid <= pktpools_max);

	/* Asertain that a previously registered poolptr is being de-registered */
	if (PKTPOOL_REGISTRY_CMP(poolid, POOLPTR(poolptr))) {
		PKTPOOL_REGISTRY_CLR(poolid); /* mark as free */
	} else {
		ASSERT(0);
		return BCME_ERROR; /* mismatch in registry */
	}

	return BCME_OK;
}

/**
 * pktpool_init:
 * User provides a pktpool_t structure and specifies the number of packets to
 * be pre-filled into the pool (n_pkts).
 * pktpool_init first attempts to register the pool and fetch a unique poolid.
 * If registration fails, it is considered an BCME_ERR, caused by either the
 * registry was not pre-created (pktpool_attach) or the registry is full.
 * If registration succeeds, then the requested number of packets will be filled
 * into the pool as part of initialization. In the event that there is no
 * available memory to service the request, then BCME_NOMEM will be returned
 * along with the count of how many packets were successfully allocated.
 * In dongle builds, prior to memory reclaimation, one should limit the number
 * of packets to be allocated during pktpool_init and fill the pool up after
 * reclaim stage.
 *
 * @param n_pkts           Number of packets to be pre-filled into the pool
 * @param max_pkt_bytes   The size of all packets in a pool must be the same. E.g. PKTBUFSZ.
 * @param type            e.g. 'lbuf_frag'
 */
int
pktpool_init(osl_t *osh,
	pktpool_t *pktp,
	int *n_pkts,
	int max_pkt_bytes,
	bool istx,
	uint8 type,
	bool is_heap_pool,
	uint32 heap_pool_flag,
	uint16 min_backup_buf)
{
	int i, err = BCME_OK;
	int pktplen;
	uint8 pktp_id;

	ASSERT(pktp != NULL);
	ASSERT(osh != NULL);
	ASSERT(n_pkts != NULL);

	pktplen = *n_pkts;

	bzero(pktp, sizeof(pktpool_t));

	/* assign a unique pktpool id */
	if ((pktp_id = (uint8) pktpool_register(pktp)) == PKTPOOL_INVALID_ID) {
		return BCME_ERROR;
	}
	POOLSETID(pktp, pktp_id);

	pktp->inited = TRUE;
	pktp->istx = istx ? TRUE : FALSE;
	pktp->max_pkt_bytes = (uint16)max_pkt_bytes;
	pktp->type = type;

#ifdef POOL_HEAP_RECONFIG
	pktp->poolheap_flag = heap_pool_flag;
	pktp->poolheap_count = 0;
	pktp->min_backup_buf = min_backup_buf;
	if (is_heap_pool) {
		if (rte_freelist_mgr_register(&pktp->mem_handle,
			hnd_pktpool_heap_get_cb,
			lb_get_pktalloclen(type, max_pkt_bytes),
			pktp) != BCME_OK) {
			return BCME_ERROR;
		}
	}
	pktp->is_heap_pool = is_heap_pool;
#endif
	if (HND_PKTPOOL_MUTEX_CREATE("pktpool", &pktp->mutex) != OSL_EXT_SUCCESS) {
		return BCME_ERROR;
	}

	pktp->maxlen = PKTPOOL_LEN_MAX;
	pktplen = LIMIT_TO_MAX(pktplen, pktp->maxlen);

	for (i = 0; i < pktplen; i++) {
		void *p;
		p = PKTGET(osh, max_pkt_bytes, TRUE);

		if (p == NULL) {
			/* Not able to allocate all requested pkts
			 * so just return what was actually allocated
			 * We can add to the pool later
			 */
			if (pktp->freelist == NULL) /* pktpool free list is empty */
				err = BCME_NOMEM;

			goto exit;
		}

		PKTSETPOOL(osh, p, TRUE, pktp); /* Tag packet with pool ID */

		PKTSETFREELIST(p, pktp->freelist); /* insert p at head of free list */
		pktp->freelist = p;

		pktp->avail++;

#ifdef BCMDBG_POOL
		pktp->dbg_q[pktp->dbg_qlen++].p = p;
#endif
	}

exit:
	pktp->n_pkts = pktp->avail;

	*n_pkts = pktp->n_pkts; /* number of packets managed by pool */
	return err;
} /* pktpool_init */

/**
 * pktpool_deinit:
 * Prior to freeing a pktpool, all packets must be first freed into the pktpool.
 * Upon pktpool_deinit, all packets in the free pool will be freed to the heap.
 * An assert is in place to ensure that there are no packets still lingering
 * around. Packets freed to a pool after the deinit will cause a memory
 * corruption as the pktpool_t structure no longer exists.
 */
int
pktpool_deinit(osl_t *osh, pktpool_t *pktp)
{
	uint16 freed = 0;

	ASSERT(osh != NULL);
	ASSERT(pktp != NULL);

#ifdef BCMDBG_POOL
	{
		int i;
		for (i = 0; i <= pktp->n_pkts; i++) {
			pktp->dbg_q[i].p = NULL;
		}
	}
#endif

	while (pktp->freelist != NULL) {
		void * p = pktp->freelist;

		pktp->freelist = PKTFREELIST(p); /* unlink head packet from free list */
		PKTSETFREELIST(p, NULL);

		PKTSETPOOL(osh, p, FALSE, NULL); /* clear pool ID tag in pkt */

		PKTFREE(osh, p, pktp->istx); /* free the packet */

		freed++;
		ASSERT(freed <= pktp->n_pkts);
	}

	pktp->avail -= freed;
	ASSERT(pktp->avail == 0);

	pktp->n_pkts -= freed;

	pktpool_deregister(pktp); /* release previously acquired unique pool id */
	POOLSETID(pktp, PKTPOOL_INVALID_ID);

	if (HND_PKTPOOL_MUTEX_DELETE(&pktp->mutex) != OSL_EXT_SUCCESS)
		return BCME_ERROR;

	pktp->inited = FALSE;

	/* Are there still pending pkts? */
	ASSERT(pktp->n_pkts == 0);

	return 0;
}

int
pktpool_fill(osl_t *osh, pktpool_t *pktp, bool minimal)
{
	void *p;
	int err = 0;
	int n_pkts, psize, maxlen;

	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_ACQUIRE(&pktp->mutex, OSL_EXT_TIME_FOREVER) != OSL_EXT_SUCCESS)
		return BCME_ERROR;

	ASSERT(pktp->max_pkt_bytes != 0);

	maxlen = pktp->maxlen;
	psize = minimal ? (maxlen >> 2) : maxlen;
	n_pkts = (int)pktp->n_pkts;
#ifdef POOL_HEAP_RECONFIG
	/*
	 * Consider the packets released to freelist mgr also
	 * as part of pool size
	 */
	n_pkts += pktp->is_heap_pool ?
		pktp->poolheap_count : 0;
#endif
	for (; n_pkts < psize; n_pkts++) {

		p = PKTGET(osh, pktp->n_pkts, TRUE);

		if (p == NULL) {
			err = BCME_NOMEM;
			break;
		}

		if (pktpool_add(pktp, p) != BCME_OK) {
			PKTFREE(osh, p, FALSE);
			err = BCME_ERROR;
			break;
		}
	}

	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_RELEASE(&pktp->mutex) != OSL_EXT_SUCCESS)
		return BCME_ERROR;

	if (pktp->cbcnt) {
		if (pktp->empty == FALSE)
			pktpool_avail_notify(pktp);
	}

	return err;
}

#ifdef BCMD11HDRPOOL

/**
 * d11hdr_pool_init:
 * User provides a pktpool_t structure and specifies the number of packets to
 * be pre-filled into the pool (n_pkts).
 * pktpool_init first attempts to register the pool and fetch a unique poolid.
 * If registration fails, it is considered an BCME_ERR, caused by either the
 * registry was not pre-created (pktpool_attach) or the registry is full.
 * If registration succeeds, then the requested number of packets will be filled
 * into the pool as part of initialization. In the event that there is no
 * available memory to service the request, then BCME_NOMEM will be returned
 * along with the count of how many packets were successfully allocated.
 * In dongle builds, prior to memory reclaimation, one should limit the number
 * of packets to be allocated during pktpool_init and fill the pool up after
 * reclaim stage.
 *
 * @param n_pkts           Number of packets to be pre-filled into the pool
 * @param max_pkt_bytes   The size of all packets in a pool must be the same. E.g. PKTBUFSZ.
 * @param type            e.g. 'lbuf_frag'
 */
int
d11hdr_pool_init(osl_t *osh,
	pktpool_t *pktp,
	uint *n_pkts,
	uint max_pkt_bytes,
	bool istx,
	uint8 type,
	bool is_heap_pool,
	uint32 heap_pool_flag,
	uint16 min_backup_buf)
{
	int err = BCME_OK;
	uint i, pktplen;
	uint8 pktp_id;

	ASSERT(pktp != NULL);
	ASSERT(osh != NULL);
	ASSERT(n_pkts != NULL);

	pktplen = *n_pkts;

	bzero(pktp, sizeof(pktpool_t));

	/* assign a unique pktpool id */
	if ((pktp_id = (uint8) pktpool_register(pktp)) == PKTPOOL_INVALID_ID) {
		return BCME_ERROR;
	}
	POOLSETID(pktp, pktp_id);

	pktp->inited = TRUE;
	pktp->istx = istx ? TRUE : FALSE;
	pktp->max_pkt_bytes = (uint16)max_pkt_bytes;
	pktp->type = type;

#ifdef POOL_HEAP_RECONFIG
	pktp->poolheap_flag = heap_pool_flag;
	pktp->poolheap_count = 0;
	pktp->min_backup_buf = min_backup_buf;
	if (is_heap_pool) {
		uint32 buf_size = ROUNDUP(max_pkt_bytes, sizeof(int));
		err = rte_freelist_mgr_register(&pktp->mem_handle,
				hnd_pktpool_heap_get_cb, buf_size, pktp);
		if (err != BCME_OK) {
			return err;
		}
	}
	pktp->is_heap_pool = is_heap_pool;
#endif
	if (HND_PKTPOOL_MUTEX_CREATE("pktpool", &pktp->mutex) != OSL_EXT_SUCCESS) {
		return BCME_ERROR;
	}

	pktp->maxlen = PKTPOOL_LEN_MAX;
	pktplen = LIMIT_TO_MAX(pktplen, pktp->maxlen);

	for (i = 0; i < pktplen; i++) {
		void *p;
		p = MALLOC_ALIGN_CALLSITE(osh, max_pkt_bytes, 0, CALL_SITE);

		if (p == NULL) {
			if (pktp->freelist == NULL) /* pktpool free list is empty */
				err = BCME_NOMEM;

			/* Not able to allocate all requested pkts
			 * so just return what was actually allocated
			 * We can add to the pool later
			 */
			goto exit;
		}
		pktp->n_pkts++;
		d11hdr_pool_enq(pktp, p);
	}

exit:
	*n_pkts = pktp->n_pkts; /* number of packets managed by pool */
	return err;
} /* pktpool_init */

/**
 * pktpool_deinit:
 * Prior to freeing a pktpool, all packets must be first freed into the pktpool.
 * Upon pktpool_deinit, all packets in the free pool will be freed to the heap.
 * An assert is in place to ensure that there are no packets still lingering
 * around. Packets freed to a pool after the deinit will cause a memory
 * corruption as the pktpool_t structure no longer exists.
 */
int
d11hdr_pool_deinit(osl_t *osh, pktpool_t *pktp)
{
	uint16 freed = 0;

	ASSERT(osh != NULL);
	ASSERT(pktp != NULL);

	while (pktp->freelist != NULL) {
		d11hdr_buf_list_t *p;

		p = pktp->freelist;
		pktp->freelist = p->next; /* unlink head packet from free list */
		MFREE(osh, p, pktp->max_pkt_bytes);
		freed++;
		ASSERT(freed <= pktp->n_pkts);
	}

	pktp->avail -= freed;
	ASSERT(pktp->avail == 0);

	pktp->n_pkts -= freed;

	pktpool_deregister(pktp); /* release previously acquired unique pool id */
	POOLSETID(pktp, PKTPOOL_INVALID_ID);

	if (HND_PKTPOOL_MUTEX_DELETE(&pktp->mutex) != OSL_EXT_SUCCESS) {
		return BCME_ERROR;
	}

	pktp->inited = FALSE;

	/* Are there still pending pkts? */
	ASSERT(pktp->n_pkts == 0);

	return 0;
}

int
d11hdr_pool_fill(osl_t *osh, pktpool_t *pktp, bool minimal)
{
	void *p;
	int err = 0;
	uint n_pkts, psize, maxlen;

	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_ACQUIRE(&pktp->mutex, OSL_EXT_TIME_FOREVER) != OSL_EXT_SUCCESS) {
		return BCME_ERROR;
	}

	ASSERT(pktp->max_pkt_bytes != 0);

	maxlen = pktp->maxlen;
	psize = minimal ? (maxlen >> 2) : maxlen;
	n_pkts = pktp->n_pkts;
#ifdef POOL_HEAP_RECONFIG
	/*
	 * Consider the packets released to freelist mgr also
	 * as part of pool size
	 */
	n_pkts += pktp->is_heap_pool ? pktp->poolheap_count : 0;
#endif
	for (; n_pkts < psize; n_pkts++) {
		p = MALLOC_ALIGN_CALLSITE(osh, pktp->max_pkt_bytes, 0, CALL_SITE);
		if (p == NULL) {
			err = BCME_NOMEM;
			break;
		}
		pktp->n_pkts++;
		d11hdr_pool_enq(pktp, p);
	}

	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_RELEASE(&pktp->mutex) != OSL_EXT_SUCCESS) {
		OSL_SYS_HALT();
		return BCME_ERROR;
	}

	return err;
}

void *
BCMFASTPATH(d11hdr_pool_deq)(pktpool_t *pktp)
{
	d11hdr_buf_list_t *p = NULL;

	if (pktp->avail == 0) {
		return NULL;
	}
	ASSERT_FP(pktp->freelist != NULL);

	p = pktp->freelist;  /* dequeue packet from head of pktpool free list */
	pktp->freelist = p->next; /* free list points to next packet */
	pktp->avail--;
	return p;
}

void
BCMFASTPATH(d11hdr_pool_enq)(pktpool_t *pktp, void *p)
{
	ASSERT_FP(p != NULL);
	d11hdr_buf_list_t *pn = p;

	pn->next = pktp->freelist;
	pktp->freelist = pn; /* free list points to newly inserted packet */
	pktp->avail++;
	ASSERT_FP(pktp->avail <= pktp->n_pkts);
}
#endif /* BCMD11HDRPOOL */

#ifdef BCMPOOLRECLAIM
/* New API to decrease the pkts from pool, but not deinit
*/
uint16
pktpool_reclaim(osl_t *osh, pktpool_t *pktp, uint16 free_cnt, uint8 action)
{
	uint16 freed = 0;

	pktpool_cb_extn_t cb = NULL;
	void *arg = NULL;
	void *rem_list_head = NULL;
	void *rem_list_tail = NULL;
	bool dont_free = FALSE;

	ASSERT(osh != NULL);
	ASSERT(pktp != NULL);

	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_ACQUIRE(&pktp->mutex, OSL_EXT_TIME_FOREVER) != OSL_EXT_SUCCESS) {
		return freed;
	}

	if (pktp->avail < free_cnt) {
		free_cnt = pktp->avail;
	}

	if (BCMSPLITRX_ENAB() && (pktp->type == lbuf_rxfrag)) {
		/* If pool is shared rx frag pool, use call back fn to reclaim host address
		 * and Rx cpl ID associated with the pkt.
		 */
		ASSERT(pktp->cbext.cb != NULL);

		cb = pktp->cbext.cb;
		arg = pktp->cbext.arg;

	} else if ((pktp->type == lbuf_basic) && (pktp->rxcplidfn.cb != NULL)) {
		/* If pool is shared rx pool, use call back fn to freeup Rx cpl ID
		 * associated with the pkt.
		 */
		cb = pktp->rxcplidfn.cb;
		arg = pktp->rxcplidfn.arg;
	}

	while ((pktp->freelist != NULL) && (free_cnt)) {
		void * p = pktp->freelist;

		pktp->freelist = PKTFREELIST(p); /* unlink head packet from free list */
		PKTSETFREELIST(p, NULL);

		dont_free = FALSE;

		if (action == FREE_ALL_FRAG_PKTS) {
			/* Free lbufs which are marked as frag_free_mem */
			if (!PKTISFRMFRAG(p)) {
				dont_free = TRUE;
			}
		}

		if (dont_free) {
			if (rem_list_head == NULL) {
				rem_list_head = p;
			} else {
				PKTSETFREELIST(rem_list_tail, p);
			}
			rem_list_tail = p;
			continue;
		}
		if (cb != NULL) {
			if (cb(pktp, arg, p, REMOVE_RXCPLID)) {
				PKTSETFREELIST(p, pktp->freelist);
				pktp->freelist = p;
				break;
			}
		}

		PKTSETPOOL(osh, p, FALSE, NULL); /* clear pool ID tag in pkt */

		pktp->avail--;
		pktp->n_pkts--;

		PKTFREE(osh, p, pktp->istx); /* free the packet */

		freed++;
		free_cnt--;
	}

	if (rem_list_head) {
		PKTSETFREELIST(rem_list_tail, pktp->freelist);
		pktp->freelist = rem_list_head;
	}

	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_RELEASE(&pktp->mutex) != OSL_EXT_SUCCESS) {
		return freed;
	}

	return freed;
}
#endif /* #ifdef BCMPOOLRECLAIM */

/* New API to empty the pkts from pool, but not deinit
* NOTE: caller is responsible to ensure,
*	all pkts are available in pool for free; else LEAK !
*/
int
pktpool_empty(osl_t *osh, pktpool_t *pktp)
{
	uint16 freed = 0;

	ASSERT(osh != NULL);
	ASSERT(pktp != NULL);

	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_ACQUIRE(&pktp->mutex, OSL_EXT_TIME_FOREVER) != OSL_EXT_SUCCESS)
		return BCME_ERROR;

#ifdef BCMDBG_POOL
	{
		int i;
		for (i = 0; i <= pktp->n_pkts; i++) {
			pktp->dbg_q[i].p = NULL;
		}
	}
#endif

	while (pktp->freelist != NULL) {
		void * p = pktp->freelist;

		pktp->freelist = PKTFREELIST(p); /* unlink head packet from free list */
		PKTSETFREELIST(p, NULL);

		PKTSETPOOL(osh, p, FALSE, NULL); /* clear pool ID tag in pkt */

		PKTFREE(osh, p, pktp->istx); /* free the packet */

		freed++;
		ASSERT(freed <= pktp->n_pkts);
	}

	pktp->avail -= freed;
	ASSERT(pktp->avail == 0);

	pktp->n_pkts -= freed;

	ASSERT(pktp->n_pkts == 0);

	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_RELEASE(&pktp->mutex) != OSL_EXT_SUCCESS)
		return BCME_ERROR;

	return 0;
}

int
pktpool_avail(pktpool_t *pktpool)
{
	int avail = pktpool->avail;

	if (avail == 0) {
		pktpool_emptycb_disable(pktpool, FALSE);
	}

	return avail;
}

static void *
BCMFASTPATH(pktpool_deq)(pktpool_t *pktp)
{
	void *p = NULL;

	if (pktp->avail == 0)
		return NULL;

	ASSERT_FP(pktp->freelist != NULL);

	p = pktp->freelist;  /* dequeue packet from head of pktpool free list */
	pktp->freelist = PKTFREELIST(p); /* free list points to next packet */

	PKTSETFREELIST(p, NULL);

	pktp->avail--;

	return p;
}

static void
BCMFASTPATH(pktpool_enq)(pktpool_t *pktp, void *p)
{
	ASSERT_FP(p != NULL);

	PKTSETFREELIST(p, pktp->freelist); /* insert at head of pktpool free list */
	pktp->freelist = p; /* free list points to newly inserted packet */

	pktp->avail++;
	ASSERT_FP(pktp->avail <= pktp->n_pkts);
}

/** utility for registering host addr fill function called from pciedev */
int
pktpool_hostaddr_fill_register(pktpool_t *pktp, pktpool_cb_extn_t cb, void *arg)
{

	ASSERT(cb != NULL);

	ASSERT(pktp->cbext.cb == NULL);
	pktp->cbext.cb = cb;
	pktp->cbext.arg = arg;
	return 0;
}

int
pktpool_rxcplid_fill_register(pktpool_t *pktp, pktpool_cb_extn_t cb, void *arg)
{

	ASSERT(cb != NULL);

	if (pktp == NULL)
		return BCME_ERROR;
	ASSERT(pktp->rxcplidfn.cb == NULL);
	pktp->rxcplidfn.cb = cb;
	pktp->rxcplidfn.arg = arg;
	return 0;
}

/** whenever host posts rxbuffer, invoke dma_rxfill from pciedev layer */
void
pktpool_invoke_dmarxfill(pktpool_t *pktp)
{
	ASSERT(pktp->dmarxfill.cb);
	ASSERT(pktp->dmarxfill.arg);

	if (pktp->dmarxfill.cb)
		pktp->dmarxfill.cb(pktp, pktp->dmarxfill.arg);
}

/** Registers callback functions for split rx mode */
int
pkpool_haddr_avail_register_cb(pktpool_t *pktp, pktpool_cb_t cb, void *arg)
{

	ASSERT(cb != NULL);

	pktp->dmarxfill.cb = cb;
	pktp->dmarxfill.arg = arg;

	return 0;
}

/**
 * Registers callback functions.
 * No BCMATTACHFN as it is used in xdc_enable_ep which is not an attach function
 */
int
pktpool_avail_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg)
{
	int err = 0;
	int i;

	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_ACQUIRE(&pktp->mutex, OSL_EXT_TIME_FOREVER) != OSL_EXT_SUCCESS)
		return BCME_ERROR;

	ASSERT(cb != NULL);

	for (i = 0; i < pktp->cbcnt; i++) {
		ASSERT(pktp->cbs[i].cb != NULL);
		if ((cb == pktp->cbs[i].cb) && (arg == pktp->cbs[i].arg)) {
			pktp->cbs[i].refcnt++;
			goto done;
		}
	}

	i = pktp->cbcnt;
	if (i == PKTPOOL_CB_MAX_AVL) {
		err = BCME_ERROR;
		goto done;
	}

	ASSERT(pktp->cbs[i].cb == NULL);
	pktp->cbs[i].cb = cb;
	pktp->cbs[i].arg = arg;
	pktp->cbs[i].refcnt++;
	pktp->cbcnt++;

	/* force enable empty callback */
	pktpool_emptycb_disable(pktp, FALSE);
done:
	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_RELEASE(&pktp->mutex) != OSL_EXT_SUCCESS)
		return BCME_ERROR;

	return err;
}

/* No BCMATTACHFN as it is used in a non-attach function */
int
pktpool_avail_deregister(pktpool_t *pktp, pktpool_cb_t cb, void *arg)
{
	int err = 0;
	int i, k;

	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_ACQUIRE(&pktp->mutex, OSL_EXT_TIME_FOREVER) != OSL_EXT_SUCCESS) {
		return BCME_ERROR;
	}

	ASSERT(cb != NULL);

	for (i = 0; i < pktp->cbcnt; i++) {
		ASSERT(pktp->cbs[i].cb != NULL);
		if ((cb == pktp->cbs[i].cb) && (arg == pktp->cbs[i].arg)) {
			pktp->cbs[i].refcnt--;
			if (pktp->cbs[i].refcnt) {
				/* Still there are references to this callback */
				goto done;
			}
			/* Moving any more callbacks to fill the hole */
			for (k = i+1; k < pktp->cbcnt; i++, k++) {
				pktp->cbs[i].cb = pktp->cbs[k].cb;
				pktp->cbs[i].arg = pktp->cbs[k].arg;
				pktp->cbs[i].refcnt = pktp->cbs[k].refcnt;
			}

			/* reset the last callback */
			pktp->cbs[i].cb = NULL;
			pktp->cbs[i].arg = NULL;
			pktp->cbs[i].refcnt = 0;

			pktp->cbcnt--;
			goto done;
		}
	}

done:
	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_RELEASE(&pktp->mutex) != OSL_EXT_SUCCESS) {
		return BCME_ERROR;
	}

	return err;
}

/** Registers callback functions */
int
pktpool_empty_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg)
{
	int err = 0;
	int i;

	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_ACQUIRE(&pktp->mutex, OSL_EXT_TIME_FOREVER) != OSL_EXT_SUCCESS)
		return BCME_ERROR;

	ASSERT(cb != NULL);

	i = pktp->ecbcnt;
	if (i == PKTPOOL_CB_MAX) {
		err = BCME_ERROR;
		goto done;
	}

	ASSERT(pktp->ecbs[i].cb == NULL);
	pktp->ecbs[i].cb = cb;
	pktp->ecbs[i].arg = arg;
	pktp->ecbcnt++;

done:
	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_RELEASE(&pktp->mutex) != OSL_EXT_SUCCESS)
		return BCME_ERROR;

	return err;
}

/** Calls registered callback functions */
static int
pktpool_empty_notify(pktpool_t *pktp)
{
	int i;

	pktp->empty = TRUE;
	for (i = 0; i < pktp->ecbcnt; i++) {
		ASSERT(pktp->ecbs[i].cb != NULL);
		pktp->ecbs[i].cb(pktp, pktp->ecbs[i].arg);
	}
	pktp->empty = FALSE;

	return 0;
}

#ifdef BCMDBG_POOL
int
pktpool_dbg_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg)
{
	int err = 0;
	int i;

	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_ACQUIRE(&pktp->mutex, OSL_EXT_TIME_FOREVER) != OSL_EXT_SUCCESS)
		return BCME_ERROR;

	ASSERT(cb);

	i = pktp->dbg_cbcnt;
	if (i == PKTPOOL_CB_MAX) {
		err = BCME_ERROR;
		goto done;
	}

	ASSERT(pktp->dbg_cbs[i].cb == NULL);
	pktp->dbg_cbs[i].cb = cb;
	pktp->dbg_cbs[i].arg = arg;
	pktp->dbg_cbcnt++;

done:
	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_RELEASE(&pktp->mutex) != OSL_EXT_SUCCESS)
		return BCME_ERROR;

	return err;
}

int pktpool_dbg_notify(pktpool_t *pktp);

int
pktpool_dbg_notify(pktpool_t *pktp)
{
	int i;

	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_ACQUIRE(&pktp->mutex, OSL_EXT_TIME_FOREVER) != OSL_EXT_SUCCESS)
		return BCME_ERROR;

	for (i = 0; i < pktp->dbg_cbcnt; i++) {
		ASSERT(pktp->dbg_cbs[i].cb);
		pktp->dbg_cbs[i].cb(pktp, pktp->dbg_cbs[i].arg);
	}

	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_RELEASE(&pktp->mutex) != OSL_EXT_SUCCESS)
		return BCME_ERROR;

	return 0;
}

int
pktpool_dbg_dump(pktpool_t *pktp)
{
	int i;

	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_ACQUIRE(&pktp->mutex, OSL_EXT_TIME_FOREVER) != OSL_EXT_SUCCESS)
		return BCME_ERROR;

	printf("pool len=%d maxlen=%d\n",  pktp->dbg_qlen, pktp->maxlen);
	for (i = 0; i < pktp->dbg_qlen; i++) {
		ASSERT(pktp->dbg_q[i].p);
		printf("%d, p: 0x%x dur:%lu us state:%d\n", i,
			pktp->dbg_q[i].p, pktp->dbg_q[i].dur/100, PKTPOOLSTATE(pktp->dbg_q[i].p));
	}

	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_RELEASE(&pktp->mutex) != OSL_EXT_SUCCESS)
		return BCME_ERROR;

	return 0;
}

int
pktpool_stats_dump(pktpool_t *pktp, pktpool_stats_t *stats)
{
	int i;
	int state;

	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_ACQUIRE(&pktp->mutex, OSL_EXT_TIME_FOREVER) != OSL_EXT_SUCCESS)
		return BCME_ERROR;

	bzero(stats, sizeof(pktpool_stats_t));
	for (i = 0; i < pktp->dbg_qlen; i++) {
		ASSERT(pktp->dbg_q[i].p != NULL);

		state = PKTPOOLSTATE(pktp->dbg_q[i].p);
		switch (state) {
			case POOL_TXENQ:
				stats->enq++; break;
			case POOL_TXDH:
				stats->txdh++; break;
			case POOL_TXD11:
				stats->txd11++; break;
			case POOL_RXDH:
				stats->rxdh++; break;
			case POOL_RXD11:
				stats->rxd11++; break;
			case POOL_RXFILL:
				stats->rxfill++; break;
			case POOL_IDLE:
				stats->idle++; break;
		}
	}

	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_RELEASE(&pktp->mutex) != OSL_EXT_SUCCESS)
		return BCME_ERROR;

	return 0;
}

int
pktpool_start_trigger(pktpool_t *pktp, void *p)
{
	uint32 cycles, i;

	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_ACQUIRE(&pktp->mutex, OSL_EXT_TIME_FOREVER) != OSL_EXT_SUCCESS)
		return BCME_ERROR;

	if (!PKTPOOL(OSH_NULL, p))
		goto done;

	OSL_GETCYCLES(cycles);

	for (i = 0; i < pktp->dbg_qlen; i++) {
		ASSERT(pktp->dbg_q[i].p != NULL);

		if (pktp->dbg_q[i].p == p) {
			pktp->dbg_q[i].cycles = cycles;
			break;
		}
	}

done:
	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_RELEASE(&pktp->mutex) != OSL_EXT_SUCCESS)
		return BCME_ERROR;

	return 0;
}

int pktpool_stop_trigger(pktpool_t *pktp, void *p);

int
pktpool_stop_trigger(pktpool_t *pktp, void *p)
{
	uint32 cycles, i;

	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_ACQUIRE(&pktp->mutex, OSL_EXT_TIME_FOREVER) != OSL_EXT_SUCCESS)
		return BCME_ERROR;

	if (!PKTPOOL(OSH_NULL, p))
		goto done;

	OSL_GETCYCLES(cycles);

	for (i = 0; i < pktp->dbg_qlen; i++) {
		ASSERT(pktp->dbg_q[i].p != NULL);

		if (pktp->dbg_q[i].p == p) {
			if (pktp->dbg_q[i].cycles == 0)
				break;

			if (cycles >= pktp->dbg_q[i].cycles)
				pktp->dbg_q[i].dur = cycles - pktp->dbg_q[i].cycles;
			else
				pktp->dbg_q[i].dur =
					(((uint32)-1) - pktp->dbg_q[i].cycles) + cycles + 1;

			pktp->dbg_q[i].cycles = 0;
			break;
		}
	}

done:
	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_RELEASE(&pktp->mutex) != OSL_EXT_SUCCESS)
		return BCME_ERROR;

	return 0;
}
#endif /* BCMDBG_POOL */

int
pktpool_avail_notify_normal(osl_t *osh, pktpool_t *pktp)
{
	BCM_REFERENCE(osh);
	ASSERT(pktp);

	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_ACQUIRE(&pktp->mutex, OSL_EXT_TIME_FOREVER) != OSL_EXT_SUCCESS)
		return BCME_ERROR;

	pktp->availcb_excl = NULL;

	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_RELEASE(&pktp->mutex) != OSL_EXT_SUCCESS)
		return BCME_ERROR;

	return 0;
}

int
pktpool_avail_notify_exclusive(osl_t *osh, pktpool_t *pktp, pktpool_cb_t cb)
{
	int i;
	int err;
	BCM_REFERENCE(osh);

	ASSERT(pktp);

	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_ACQUIRE(&pktp->mutex, OSL_EXT_TIME_FOREVER) != OSL_EXT_SUCCESS)
		return BCME_ERROR;

	ASSERT(pktp->availcb_excl == NULL);
	for (i = 0; i < pktp->cbcnt; i++) {
		if (cb == pktp->cbs[i].cb) {
			pktp->availcb_excl = &pktp->cbs[i];
			break;
		}
	}

	if (pktp->availcb_excl == NULL)
		err = BCME_ERROR;
	else
		err = 0;

	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_RELEASE(&pktp->mutex) != OSL_EXT_SUCCESS)
		return BCME_ERROR;

	return err;
}

static void
pktpool_avail_notify(pktpool_t *pktp)
{
	int i, k, idx;

	ASSERT(pktp);
	pktpool_emptycb_disable(pktp, TRUE);

	if (pktp->availcb_excl != NULL) {
		pktp->availcb_excl->cb(pktp, pktp->availcb_excl->arg);
		return;
	}

	k = pktp->cbcnt - 1;
	for (i = 0; i < pktp->cbcnt; i++) {
		/* callbacks are getting disabled at this func entry.
		 * For the case of avail is say 5, and first callback
		 * consumes exactly 5 due to dma rxpost setting, then
		 * further callbacks will not getting notified if avail check
		 * is present.
		 * so calling all cbs even if pktp->avail is zero, so that
		 * cbs get oppurtunity to enable callbacks if their
		 * operation is in progress / not completed.
		 */
		if (pktp->cbtoggle)
			idx = i;
		else
			idx = k--;

		ASSERT(pktp->cbs[idx].cb != NULL);
		pktp->cbs[idx].cb(pktp, pktp->cbs[idx].arg);
	}

	/* Alternate between filling from head or tail
	 */
	pktp->cbtoggle ^= 1;

	return;
}

/** Gets an empty packet from the caller provided pool */
void *
BCMFASTPATH(pktpool_get_ext)(pktpool_t *pktp, uint8 type)
{
	void *p;

	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_ACQUIRE(&pktp->mutex, OSL_EXT_TIME_FOREVER) != OSL_EXT_SUCCESS)
		return NULL;

	p = pktpool_deq(pktp);

	if (p == NULL) {
		/* Notify and try to reclaim tx pkts */
		if (pktp->ecbcnt)
			pktpool_empty_notify(pktp);

		p = pktpool_deq(pktp);
		if (p == NULL) {
			pktpool_emptycb_disable(pktp, FALSE);
			goto done;
		}
	}

done:
	if ((pktp->avail == 0) && (pktp->emptycb_disable == EMPTYCB_SKIPPED)) {
		pktp->emptycb_disable = EMPTYCB_DISABLED;
	}
	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_RELEASE(&pktp->mutex) != OSL_EXT_SUCCESS)
		return NULL;

	return p;
}

void
BCMFASTPATH(pktpool_free)(pktpool_t *pktp, void *p)
{
	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_ACQUIRE(&pktp->mutex, OSL_EXT_TIME_FOREVER) != OSL_EXT_SUCCESS)
		return;

	ASSERT_FP(p != NULL);
#ifdef BCMDBG_POOL
	/* pktpool_stop_trigger(pktp, p); */
#endif

	pktpool_enq(pktp, p);

	/**
	 * Feed critical DMA with freshly freed packets, to avoid DMA starvation.
	 * If any avail callback functions are registered, send a notification
	 * that a new packet is available in the pool.
	 */
	if (pktp->cbcnt) {
		/* To more efficiently use the cpu cycles, callbacks can be temporarily disabled.
		 * This allows to feed on burst basis as opposed to inefficient per-packet basis.
		 */
		if (pktp->emptycb_disable == EMPTYCB_ENABLED) {
			/**
			 * If the call originated from pktpool_empty_notify, the just freed packet
			 * is needed in pktpool_get.
			 * Therefore don't call pktpool_avail_notify.
			 */
			if (pktp->empty == FALSE)
				pktpool_avail_notify(pktp);
		} else {
			/**
			 * The callback is temporarily disabled, log that a packet has been freed.
			 */
			pktp->emptycb_disable = EMPTYCB_SKIPPED;
		}
	}

	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_RELEASE(&pktp->mutex) != OSL_EXT_SUCCESS)
		return;
}

/** Adds a caller provided (empty) packet to the caller provided pool */
int
pktpool_add(pktpool_t *pktp, void *p)
{
	int err = 0;

	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_ACQUIRE(&pktp->mutex, OSL_EXT_TIME_FOREVER) != OSL_EXT_SUCCESS)
		return BCME_ERROR;

	ASSERT(p != NULL);

	if (pktp->n_pkts == pktp->maxlen) {
		err = BCME_RANGE;
		goto done;
	}

	/* pkts in pool have same length */
	ASSERT(pktp->max_pkt_bytes == PKTLEN(OSH_NULL, p));
	PKTSETPOOL(OSH_NULL, p, TRUE, pktp);

	pktp->n_pkts++;
	pktpool_enq(pktp, p);

#ifdef BCMDBG_POOL
	pktp->dbg_q[pktp->dbg_qlen++].p = p;
#endif

done:
	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_RELEASE(&pktp->mutex) != OSL_EXT_SUCCESS)
		return BCME_ERROR;

	return err;
}

/**
 * Force pktpool_setmaxlen () into RAM as it uses a constant
 * (PKTPOOL_LEN_MAX) that may be changed post tapeout for ROM-based chips.
 */
int
BCMRAMFN(pktpool_setmaxlen)(pktpool_t *pktp, uint16 maxlen)
{
	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_ACQUIRE(&pktp->mutex, OSL_EXT_TIME_FOREVER) != OSL_EXT_SUCCESS)
		return BCME_ERROR;

	if (maxlen > PKTPOOL_LEN_MAX)
		maxlen = PKTPOOL_LEN_MAX;

	/* if pool is already beyond maxlen, then just cap it
	 * since we currently do not reduce the pool len
	 * already allocated
	 */
	pktp->maxlen = (pktp->n_pkts > maxlen) ? pktp->n_pkts : maxlen;

	/* protect shared resource */
	if (HND_PKTPOOL_MUTEX_RELEASE(&pktp->mutex) != OSL_EXT_SUCCESS)
		return BCME_ERROR;

	return pktp->maxlen;
}

void
pktpool_emptycb_disable(pktpool_t *pktp, bool disable)
{
	bool notify = FALSE;
	ASSERT(pktp);

	/**
	 * To more efficiently use the cpu cycles, callbacks can be temporarily disabled.
	 * If callback is going to be re-enabled, check if any packet got
	 * freed and added back to the pool while callback was disabled.
	 * When this is the case do the callback now, provided that callback functions
	 * are registered and this call did not originate from pktpool_empty_notify.
	 */
	if ((!disable) && (pktp->cbcnt) && (pktp->empty == FALSE) &&
		(pktp->emptycb_disable == EMPTYCB_SKIPPED)) {
		notify = TRUE;
	}

	/* Enable or temporarily disable callback when packet becomes available. */
	if (disable) {
		if (pktp->emptycb_disable == EMPTYCB_ENABLED) {
			/* mark disabled only if enabled.
			 * if state is EMPTYCB_SKIPPED, it means already
			 * disabled and some pkts are freed. So don't lose the state
			 * of skipped to ensure calling pktpool_avail_notify().
			 */
			pktp->emptycb_disable = EMPTYCB_DISABLED;
		}
	} else {
		pktp->emptycb_disable = EMPTYCB_ENABLED;
	}
	if (notify) {
		/* pktpool_emptycb_disable() is called from pktpool_avail_notify() and
		 * pktp->cbs. To have the result of most recent call, notify after
		 * emptycb_disable is modified.
		 * This change also prevents any recursive calls of pktpool_avail_notify()
		 * from pktp->cbs if pktpool_emptycb_disable() is called from them.
		 */
		pktpool_avail_notify(pktp);
	}
}

bool
pktpool_emptycb_disabled(pktpool_t *pktp)
{
	ASSERT(pktp);
	return pktp->emptycb_disable != EMPTYCB_ENABLED;
}

#ifdef BCMPKTPOOL
#include <hnd_lbuf.h>

pktpool_t *pktpool_shared = NULL;

#ifdef BCMFRAGPOOL
pktpool_t *pktpool_shared_lfrag = NULL;
#ifdef BCMRESVFRAGPOOL
pktpool_t *pktpool_resv_lfrag = NULL;
struct resv_info *resv_pool_info = NULL;
#endif /* BCMRESVFRAGPOOL */
#endif /* BCMFRAGPOOL */

pktpool_t *pktpool_shared_rxlfrag = NULL;

#if defined(BCMD11HDRPOOL)
pktpool_t *pktpool_d11hdr = NULL;
#endif /* defined(BCMRXFRAGPOOL) */

static osl_t *pktpool_osh = NULL;
static uint32 total_poolheap_count = 0U;

/**
 * Initializes several packet pools and allocates packets within those pools.
 */
int
hnd_pktpool_init(osl_t *osh)
{
	int err = BCME_OK;
	int n, pktsz;
	bool is_heap_pool;

	BCM_REFERENCE(pktsz);
	BCM_REFERENCE(is_heap_pool);

	/* Construct a packet pool registry before initializing packet pools */
	n = pktpool_attach(osh, PKTPOOL_MAXIMUM_ID);
	if (n != PKTPOOL_MAXIMUM_ID) {
		ASSERT(0);
		err = BCME_ERROR;
		goto error;
	}

	pktpool_shared = MALLOCZ(osh, sizeof(pktpool_t));
	if (pktpool_shared == NULL) {
		ASSERT(0);
		err = BCME_NOMEM;
		goto error;
	}

#if defined(BCMFRAGPOOL) && !defined(BCMFRAGPOOL_DISABLED)
	pktpool_shared_lfrag = MALLOCZ(osh, sizeof(pktpool_t));
	if (pktpool_shared_lfrag == NULL) {
		ASSERT(0);
		err = BCME_NOMEM;
		goto error;
	}

#if defined(BCMRESVFRAGPOOL) && !defined(BCMRESVFRAGPOOL_DISABLED)
	resv_pool_info = hnd_resv_pool_alloc(osh);
	if (resv_pool_info == NULL) {
		err = BCME_NOMEM;
		ASSERT(0);
		goto error;
	}
	pktpool_resv_lfrag = resv_pool_info->pktp;
	if (pktpool_resv_lfrag == NULL) {
		err = BCME_ERROR;
		ASSERT(0);
		goto error;
	}
#endif	/* RESVFRAGPOOL */
#endif /* FRAGPOOL */

#if defined(BCMRXFRAGPOOL) && !defined(BCMRXFRAGPOOL_DISABLED)
	pktpool_shared_rxlfrag = MALLOCZ(osh, sizeof(pktpool_t));
	if (pktpool_shared_rxlfrag == NULL) {
		ASSERT(0);
		err = BCME_NOMEM;
		goto error;
	}
#endif

#if defined(BCMD11HDRPOOL) && !defined(BCMD11HDRPOOL_DISABLED)
	pktpool_d11hdr = MALLOCZ(osh, sizeof(pktpool_t));
	if (pktpool_d11hdr == NULL) {
		ASSERT(0);
		err = BCME_NOMEM;
		goto error;
	}
#endif /* BCMD11HDRPOOL && !BCMD11HDRPOOL_DISABLED */

	/*
	 * At this early stage, there's not enough memory to allocate all
	 * requested pkts in the shared pool.  Need to add to the pool
	 * after reclaim
	 *
	 * n = NRXBUFPOST + SDPCMD_RXBUFS;
	 *
	 * Initialization of packet pools may fail (BCME_ERROR), if the packet pool
	 * registry is not initialized or the registry is depleted.
	 *
	 * A BCME_NOMEM error only indicates that the requested number of packets
	 * were not filled into the pool.
	 */
	n = 1;
	MALLOC_SET_NOPERSIST(osh); /* Ensure subsequent allocations are non-persist */
#ifdef HWA
	if ((err = pktpool_init(osh, pktpool_shared,
			&n, PKTBUFSZ, FALSE, lbuf_hwa_basic, FALSE, 0, 0)) != BCME_OK) {
#else
	if ((err = pktpool_init(osh, pktpool_shared,
			&n, PKTBUFSZ, FALSE, lbuf_basic, FALSE, 0, 0)) != BCME_OK) {
#endif
		ASSERT(0);
		goto error;
	}
	pktpool_setmaxlen(pktpool_shared, SHARED_POOL_LEN);

#if defined(BCMFRAGPOOL) && !defined(BCMFRAGPOOL_DISABLED)
	n = 1;
#if (!defined(HWA) && ((defined(EVENTLOG_D3_PRESERVE) && \
	!defined(EVENTLOG_D3_PRESERVE_DISABLED)) || defined(BCMPOOLRECLAIM)))
	is_heap_pool = TRUE;
#else
	is_heap_pool = FALSE;
#endif /* !HWA && (( EVENTLOG_D3_PRESERVE && !EVENTLOG_D3_PRESERVE_DISABLED) || BCMPOOLRECLAIM)  */

	if (HWA_SUBMODULES_TXPOST_ENAB()) {
		pktpool_shared_lfrag->type = lbuf_frag;
	} else {
		if ((err = pktpool_init(osh, pktpool_shared_lfrag, &n, PKTFRAGSZ, TRUE, lbuf_frag,
				is_heap_pool, POOL_HEAP_FLAG_D3, SHARED_FRAG_POOL_LEN >> 3)) !=
				BCME_OK) {
			ASSERT(0);
			goto error;
		}
		pktpool_setmaxlen(pktpool_shared_lfrag, SHARED_FRAG_POOL_LEN);
	}

#if defined(BCMRESVFRAGPOOL) && !defined(BCMRESVFRAGPOOL_DISABLED) && !defined(HWA)
	n = 0; /* IMPORTANT: DO NOT allocate any packets in resv pool */
#ifdef RESV_POOL_HEAP
	is_heap_pool = TRUE;
#endif /* RESV_POOL_HEAP */

	if ((err = pktpool_init(osh, pktpool_resv_lfrag, &n, PKTFRAGSZ, TRUE, lbuf_frag,
		is_heap_pool, POOL_HEAP_FLAG_RSRVPOOL, 0)) != BCME_OK) {
		ASSERT(0);
		goto error;
	}
	pktpool_setmaxlen(pktpool_resv_lfrag, RESV_FRAG_POOL_LEN);
#endif /* RESVFRAGPOOL */
#endif /* BCMFRAGPOOL */

#if defined(BCMRXFRAGPOOL) && !defined(BCMRXFRAGPOOL_DISABLED)
	n = 1;
	if (HWA_SUBMODULES_RXPOSTFILL_ENAB()) {
		pktsz = 1;
	} else {
		pktsz = RXPKTFRAGDATASZ;
	}
#ifdef RESV_POOL_HEAP
	is_heap_pool = BCMPOOLRECLAIM_ENAB() ? TRUE : FALSE;
#else
	is_heap_pool = FALSE;
#endif /* RESV_POOL_HEAP */

	if ((err = pktpool_init(osh, pktpool_shared_rxlfrag, &n, pktsz, TRUE, lbuf_rxfrag,
			is_heap_pool, POOL_HEAP_FLAG_D3, 0)) != BCME_OK) {
		ASSERT(0);
		goto error;
	}

	if (HWA_SUBMODULES_RXPOSTFILL_ENAB()) {
		pktpool_setmaxlen(pktpool_shared_rxlfrag, 1);
	} else {
		pktpool_setmaxlen(pktpool_shared_rxlfrag, SHARED_RXFRAG_POOL_LEN);
	}
#endif /* defined(BCMRXFRAGPOOL) && !defined(BCMRXFRAGPOOL_DISABLED) */

#if defined(BCMD11HDRPOOL) && !defined(BCMD11HDRPOOL_DISABLED)
	{
		uint n_pkts = 1;
		uint buf_size = (TXD11HDRSPACESZ + sizeof(lbuf_d11hdr_t));
		err = d11hdr_pool_init(osh, pktpool_d11hdr,
				&n_pkts, buf_size, FALSE, 0, FALSE, 0, 0);
		if (err != BCME_OK) {
			ASSERT(0);
			goto error;
		}
		pktpool_setmaxlen(pktpool_d11hdr, D11HDR_POOL_LEN);
	}
#endif /* defined(BCMD11HDRPOOL) && !defined(BCMD11HDRPOOL_DISABLED) */

#if defined(BCMFRWDPOOLREORG) && !defined(BCMFRWDPOOLREORG_DISABLED)
	/* Attach poolreorg module */
	if ((frwd_poolreorg_info = poolreorg_attach(osh,
#if defined(BCMFRAGPOOL) && !defined(BCMFRAGPOOL_DISABLED)
			pktpool_shared_lfrag,
#else
			NULL,
#endif /* defined(BCMFRAGPOOL) && !defined(BCMFRAGPOOL_DISABLED) */
#if defined(BCMRXFRAGPOOL) && !defined(BCMRXFRAGPOOL_DISABLED)
			pktpool_shared_rxlfrag,
#else
			NULL,
#endif /* BCMRXFRAGPOOL */
			pktpool_shared)) == NULL) {
		ASSERT(0);
		err = BCME_NOMEM;
		goto error;
	}
#endif /* defined(BCMFRWDPOOLREORG) && !defined(BCMFRWDPOOLREORG_DISABLED) */

	pktpool_osh = osh;
	MALLOC_CLEAR_NOPERSIST(osh);

#ifdef POOL_HEAP_RECONFIG
	lbuf_free_cb_set(hnd_pktpool_lbuf_free_cb);
#endif

	return BCME_OK;

error:
	hnd_pktpool_deinit(osh);

	return err;
} /* hnd_pktpool_init */

void
hnd_pktpool_deinit(osl_t *osh)
{
#if defined(BCMFRWDPOOLREORG) && !defined(BCMFRWDPOOLREORG_DISABLED)
	if (frwd_poolreorg_info != NULL) {
		poolreorg_detach(frwd_poolreorg_info);
	}
#endif /* defined(BCMFRWDPOOLREORG) && !defined(BCMFRWDPOOLREORG_DISABLED) */

#if defined(BCMRXFRAGPOOL) && !defined(BCMRXFRAGPOOL_DISABLED)
	if (pktpool_shared_rxlfrag != NULL) {
		if (pktpool_shared_rxlfrag->inited) {
			pktpool_deinit(osh, pktpool_shared_rxlfrag);
		}

		hnd_free(pktpool_shared_rxlfrag);
		pktpool_shared_rxlfrag = (pktpool_t *)NULL;
	}
#endif

#if defined(BCMFRAGPOOL) && !defined(BCMFRAGPOOL_DISABLED)
	if (pktpool_shared_lfrag != NULL) {
		if (!HWA_SUBMODULES_TXPOST_ENAB() && pktpool_shared_lfrag->inited) {
			pktpool_deinit(osh, pktpool_shared_lfrag);
		}
		hnd_free(pktpool_shared_lfrag);
		pktpool_shared_lfrag = (pktpool_t *)NULL;
	}
#endif /* BCMFRAGPOOL */

#if defined(BCMD11HDRPOOL) && !defined(BCMD11HDRPOOL_DISABLED)
	if (pktpool_d11hdr != NULL) {
		if (pktpool_d11hdr->inited) {
			pktpool_deinit(osh, pktpool_d11hdr);
		}

		hnd_free(pktpool_d11hdr);
		pktpool_d11hdr = (pktpool_t *)NULL;
	}
#endif /* BCMD11HDRPOOL */

#if defined(BCMRESVFRAGPOOL) && !defined(BCMRESVFRAGPOOL_DISABLED)
	if (resv_pool_info != NULL) {
		if (pktpool_resv_lfrag != NULL) {
			pktpool_resv_lfrag = NULL;
		}
		hnd_free(resv_pool_info);
	}
#endif /* RESVFRAGPOOL */

	if (pktpool_shared != NULL) {
		if (pktpool_shared->inited) {
			pktpool_deinit(osh, pktpool_shared);
		}

		hnd_free(pktpool_shared);
		pktpool_shared = (pktpool_t *)NULL;
	}

	pktpool_dettach(osh);

	MALLOC_CLEAR_NOPERSIST(osh);
}

/** is called at each 'wl up' */
int
hnd_pktpool_fill(pktpool_t *pktpool, bool minimal)
{
	return (pktpool_fill(pktpool_osh, pktpool, minimal));
}

/** refills pktpools after reclaim, is called once */
void
hnd_pktpool_refill(bool minimal)
{
	if (POOL_ENAB(pktpool_shared)) {
#if defined(SRMEM)
		if (SRMEM_ENAB()) {
			int maxlen = pktpool_max_pkts(pktpool_shared);
			int n_pkts = pktpool_tot_pkts(pktpool_shared);

			for (; n_pkts < maxlen; n_pkts++) {
				void *p;
				if ((p = PKTSRGET(pktpool_max_pkt_bytes(pktpool_shared))) == NULL)
					break;
				pktpool_add(pktpool_shared, p);
			}
		}
#endif /* SRMEM */
		pktpool_fill(pktpool_osh, pktpool_shared, minimal);
	}
/* fragpool reclaim */
#ifdef BCMFRAGPOOL
	if (POOL_ENAB(pktpool_shared_lfrag)) {
		pktpool_fill(pktpool_osh, pktpool_shared_lfrag, minimal);
	}
#endif /* BCMFRAGPOOL */

/* rx fragpool reclaim */
#ifdef BCMRXFRAGPOOL
	if (POOL_ENAB(pktpool_shared_rxlfrag)) {
		pktpool_fill(pktpool_osh, pktpool_shared_rxlfrag, minimal);
	}
#endif
#if defined(BCMFRAGPOOL) && defined(BCMRESVFRAGPOOL)
	if (POOL_ENAB(pktpool_resv_lfrag)) {
		int resv_size = (pktpool_resv_lfrag->max_pkt_bytes + LBUFFRAGSZ) *
			pktpool_resv_lfrag->maxlen;
		hnd_resv_pool_init(resv_pool_info, resv_size);
		hnd_resv_pool_enable(resv_pool_info);
	}
#endif /* BCMRESVFRAGPOOL */
}

#ifdef POOL_HEAP_RECONFIG
#define hnd_pktpool_release_active_set(pktp)	(pktpool_heap_rel_active |= (1 << pktp->id))
#define hnd_pktpool_release_active_reset(pktp)	(pktpool_heap_rel_active &= ~(1 << pktp->id))
/* Function enable/disable heap pool usage */

#ifdef HWA
void
hnd_pktpool_heap_handle(osl_t *osh, uint32 flag, bool enable)
{
	hwa_info_t *hwa_dev = hwa_info_get();
	hwa_bufpool_heap_handle(hwa_dev, flag, enable);
	return;
}

/* Do memory allocation from pool heap memory */
void *
hnd_pktpool_freelist_alloc(uint size, uint alignbits, uint32 flag)
{
	void *p = NULL;
	hwa_info_t *hwa_dev = hwa_info_get();
	p = hwa_bufpool_freelist_alloc(hwa_dev, size, alignbits, flag);
	return p;
}
#else
void
hnd_pktpool_heap_handle(osl_t *osh, uint32 flag, bool enable)
{
	int i = 0;
	pktpool_t *pktp;
	/*
	 * Loop through all the registerd pktpools.
	 * Trigger retreave of pkts from the heap back to pool if no
	 * flags are active.
	 */
	for (i = 1; i < PKTPOOL_MAXIMUM_ID; i++) {
		if ((pktp = get_pktpools_registry(i)) != NULL) {
			if ((flag == pktp->poolheap_flag) && pktp->is_heap_pool) {
				if (enable) {
					hnd_pktpool_heap_pkt_release(pktpool_osh, pktp, flag);
				} else {
					hnd_pktpool_heap_pkt_retrieve(pktp, flag);
				}
			}
		}
	}
}

/* Do memory allocation from pool heap memory */
void *
hnd_pktpool_freelist_alloc(uint size, uint alignbits, uint32 flag)
{
	int i = 0;
	pktpool_t *pktp;
	void *p = NULL;
	for (i = 1; i < PKTPOOL_MAXIMUM_ID; i++) {
		if ((pktp = get_pktpools_registry(i)) != NULL) {
			if ((flag == pktp->poolheap_flag) && pktp->is_heap_pool) {
				p = rte_freelist_mgr_alloc(size, alignbits, pktp->mem_handle);
				if (p)
					break;
			}
		}
	}
	return p;
}
#endif /* HWA */

#ifndef HWA
/* Release pkts from pool to free heap */
static void
hnd_pktpool_heap_pkt_release(osl_t *osh, pktpool_t *pktp, uint32 flag)
{
	pktpool_cb_extn_t cb = NULL;
	void *arg = NULL;
	int i = 0;
	pktpool_heap_cb_reg_t *pktp_heap_cb = hnd_pool_get_cb_registry();

	pktp->release_active = FALSE;
	hnd_pktpool_release_active_reset(pktp);

	if (pktp->n_pkts <= pktp->min_backup_buf)
		return;
	/* call module specific callbacks */
	if (BCMSPLITRX_ENAB() && (pktp->type == lbuf_rxfrag)) {
		/* If pool is shared rx frag pool, use call back fn to reclaim host address
		 * and Rx cpl ID associated with the pkt.
		 */
		ASSERT(pktp->cbext.cb != NULL);
		cb = pktp->cbext.cb;
		arg = pktp->cbext.arg;
	} else if ((pktp->type == lbuf_basic) && (pktp->rxcplidfn.cb != NULL)) {
		/* If pool is shared rx pool, use call back fn to freeup Rx cpl ID
		 * associated with the pkt.
		 */
		cb = pktp->rxcplidfn.cb;
		arg = pktp->rxcplidfn.arg;
	}

	while (pktp->avail > pktp->min_backup_buf) {
		void * p = pktp->freelist;

		pktp->freelist = PKTFREELIST(p); /* unlink head packet from free list */
		PKTSETFREELIST(p, NULL);

		if (cb != NULL) {
			if (cb(pktp, arg, p, REMOVE_RXCPLID)) {
				PKTSETFREELIST(p, pktp->freelist);
				pktp->freelist = p;
				break;
			}
		}

		PKTSETPOOL(osh, p, FALSE, NULL); /* clear pool ID tag in pkt */

		lb_set_nofree(p);
		PKTFREE(osh, p, pktp->istx); /* free the packet */

		rte_freelist_mgr_add(p, pktp->mem_handle);
		pktp->avail--;
		pktp->n_pkts--;
		pktp->poolheap_count++;
		total_poolheap_count++;
	}

	/* Execute call back for upper layer which used pkt from heap */
	for (i = 0; i < PKTPOOL_MAX_HEAP_CB; i++) {
		if ((pktp_heap_cb[i].fn != NULL) &&
			(flag == pktp_heap_cb[i].flag))
			(pktp_heap_cb[i].fn)(pktp_heap_cb[i].ctxt, TRUE);
	}

}
#endif /* !HWA */

static pktpool_heap_cb_reg_t *
BCMRAMFN(hnd_pool_get_cb_registry)(void)
{
	return pktpool_heap_cb_reg;
}

static void
BCMFASTPATH(hnd_pktpool_lbuf_free_cb)(uint8 poolid)
{
	int i = 0;
	pktpool_t *pktp;

	if (poolid == PKTPOOL_INVALID_ID && pktpool_heap_rel_active) {
		for (i = 1; i < PKTPOOL_MAXIMUM_ID; i++) {
			if ((pktp = get_pktpools_registry(i)) != NULL) {
				if (pktp->is_heap_pool && (pktp->release_active)) {
					rte_freelist_mgr_release(pktp->mem_handle);
				}
			}
		}
	}
}

#ifndef HWA
/* Take back pkts from free mem and refill pool */
static void
hnd_pktpool_heap_pkt_retrieve(pktpool_t *pktp, uint32 flag)
{
	int i = 0;
	pktpool_heap_cb_reg_t *pktp_heap_cb = hnd_pool_get_cb_registry();
	pktp->release_active = TRUE;
	hnd_pktpool_release_active_set(pktp);

	/* Execute call back for upper layer which used pkt from heap */
	for (i = 0; i < PKTPOOL_MAX_HEAP_CB; i++) {
		if ((pktp_heap_cb[i].fn != NULL) &&
			(flag == pktp_heap_cb[i].flag))
			(pktp_heap_cb[i].fn)(pktp_heap_cb[i].ctxt, FALSE);
	}

	rte_freelist_mgr_release(pktp->mem_handle);
}
#endif /* !HWA */

/* Function to add back the pkt to pktpool */
static int
hnd_pktpool_heap_get_cb(uint8 handle, void *ctxt, void *pkt, uint pktsize)
{
	pktpool_t *pktp = (pktpool_t *)ctxt;
	struct lbuf *lb;
	int ret = BCME_ERROR;
	if (pktp != NULL) {
		if ((lb = PKTALLOC_ON_LOC(pktpool_osh, pktp->max_pkt_bytes,
			pktp->type, pkt, pktsize)) != NULL) {
			if ((ret = pktpool_add(pktp, lb)) == BCME_OK) {
				pktp->poolheap_count--;
#ifndef HWA
				total_poolheap_count--;
#endif /* HWA */
				if (pktp->poolheap_count == 0) {
					pktp->release_active = FALSE;
					hnd_pktpool_release_active_reset(pktp);
				}
				if (pktp->cbcnt) {
					if (pktp->empty == FALSE)
						pktpool_avail_notify(pktp);
				}
			} else {
				/*
				 * pktpool_add failed indicate already max
				 * number of pkts are available in pool. So
				 * free this buffer to heap
				 */
				PKTFREE(pktpool_osh, lb, pktsize);
			}
			ret = BCME_OK;
		}
	}
	return ret;
}

int
hnd_pktpool_heap_register_cb(pktpool_heap_cb_t fn, void *ctxt, uint32 flag)
{
	int i = 0;
	int err = BCME_ERROR;
	pktpool_heap_cb_reg_t *pktp_heap_cb = hnd_pool_get_cb_registry();

	/* Search for free entry */
	for (i = 0; i < PKTPOOL_MAX_HEAP_CB; i++) {
		if (pktp_heap_cb[i].fn == NULL)
			break;
	}

	if (i < PKTPOOL_MAX_HEAP_CB) {
		pktp_heap_cb[i].fn = fn;
		pktp_heap_cb[i].ctxt = ctxt;
		pktp_heap_cb[i].flag = flag;
		err = BCME_OK;
	}
	return err;
}

int
hnd_pktpool_heap_deregister_cb(pktpool_heap_cb_t fn)
{
	int i = 0;
	int err = BCME_ERROR;
	pktpool_heap_cb_reg_t *pktp_heap_cb = hnd_pool_get_cb_registry();

	/* Search for matching entry */
	for (i = 0; i < PKTPOOL_MAX_HEAP_CB; i++) {
		if (pktp_heap_cb[i].fn == fn)
			break;
	}

	if (i < PKTPOOL_MAX_HEAP_CB) {
		pktp_heap_cb[i].fn = NULL;
		err = BCME_OK;
	}
	return err;
}

uint16
hnd_pktpool_get_min_bkup_buf(pktpool_t *pktp)
{
	return pktp->min_backup_buf;
}
#endif /* POOL_HEAP_RECONFIG */

uint32
hnd_pktpool_get_total_poolheap_count(void)
{
	return total_poolheap_count;
}
#endif /* BCMPKTPOOL */
