1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429 |
- /*
- * HND generic packet pool operation primitives
- *
- * Portions of this code are copyright (c) 2020 Cypress Semiconductor Corporation
- *
- * Copyright (C) 1999-2020, Broadcom Corporation
- *
- * 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.
- *
- * Notwithstanding the above, under no circumstances may you combine this
- * software in any way with any other Broadcom software provided under a license
- * other than the GPL, without Broadcom's express prior written consent.
- *
- *
- * <<Broadcom-WL-IPTag/Open:>>
- *
- * $Id: hnd_pktpool.c 677681 2017-01-04 09:10:30Z $
- */
- #include <typedefs.h>
- #include <osl.h>
- #include <osl_ext.h>
- #include <bcmutils.h>
- #include <hnd_pktpool.h>
- #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 // 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 */
- /* 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)
- {
- 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;
- 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 // 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 // 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;
- for (n_pkts = (int)pktp->n_pkts; 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 BCMPOOLRECLAIM
- /* New API to decrease the pkts from pool, but not deinit
- */
- uint16
- pktpool_reclaim(osl_t *osh, pktpool_t *pktp, uint16 free_cnt)
- {
- uint16 freed = 0;
- pktpool_cb_extn_t cb = NULL;
- void *arg = NULL;
- 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);
- 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 */
- PKTFREE(osh, p, pktp->istx); /* free the packet */
- freed++;
- free_cnt--;
- }
- pktp->avail -= freed;
- pktp->n_pkts -= freed;
- /* 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 // 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;
- }
- static void *
- pktpool_deq(pktpool_t *pktp)
- {
- void *p = NULL;
- if (pktp->avail == 0)
- return NULL;
- ASSERT(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
- pktpool_enq(pktpool_t *pktp, void *p)
- {
- ASSERT(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(pktp->avail <= pktp->n_pkts);
- }
- /** utility for registering host addr fill function called from pciedev */
- int
- /* BCMATTACHFN */
- (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++;
- 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;
- int avail;
- ASSERT(pktp);
- 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++) {
- avail = pktp->avail;
- if (avail) {
- 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 *
- pktpool_get(pktpool_t *pktp)
- {
- 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)
- goto done;
- }
- done:
- /* protect shared resource */
- if (HND_PKTPOOL_MUTEX_RELEASE(&pktp->mutex) != OSL_EXT_SUCCESS)
- return NULL;
- return p;
- }
- void
- 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(p != NULL);
- #ifdef BCMDBG_POOL
- /* pktpool_stop_trigger(pktp, p); */
- #endif // 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 // 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)
- {
- 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)) {
- pktpool_avail_notify(pktp);
- }
- /* Enable or temporarily disable callback when packet becomes available. */
- pktp->emptycb_disable = disable ? EMPTYCB_DISABLED : EMPTYCB_ENABLED;
- }
- 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;
- static osl_t *pktpool_osh = NULL;
- /**
- * Initializes several packet pools and allocates packets within those pools.
- */
- int
- hnd_pktpool_init(osl_t *osh)
- {
- int err = BCME_OK;
- int n;
- /* 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 error0;
- }
- pktpool_shared = MALLOCZ(osh, sizeof(pktpool_t));
- if (pktpool_shared == NULL) {
- ASSERT(0);
- err = BCME_NOMEM;
- goto error1;
- }
- #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 error2;
- }
- #if defined(BCMRESVFRAGPOOL) && !defined(BCMRESVFRAGPOOL_DISABLED)
- resv_pool_info = hnd_resv_pool_alloc(osh);
- if (resv_pool_info == NULL) {
- ASSERT(0);
- goto error2;
- }
- pktpool_resv_lfrag = resv_pool_info->pktp;
- if (pktpool_resv_lfrag == NULL) {
- ASSERT(0);
- goto error2;
- }
- #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 error3;
- }
- #endif // endif
- /*
- * 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 */
- if ((err = pktpool_init(osh, pktpool_shared,
- &n, PKTBUFSZ, FALSE, lbuf_basic)) != BCME_OK) {
- ASSERT(0);
- goto error4;
- }
- pktpool_setmaxlen(pktpool_shared, SHARED_POOL_LEN);
- #if defined(BCMFRAGPOOL) && !defined(BCMFRAGPOOL_DISABLED)
- n = 1;
- if ((err = pktpool_init(osh, pktpool_shared_lfrag,
- &n, PKTFRAGSZ, TRUE, lbuf_frag)) != BCME_OK) {
- ASSERT(0);
- goto error5;
- }
- pktpool_setmaxlen(pktpool_shared_lfrag, SHARED_FRAG_POOL_LEN);
- #if defined(BCMRESVFRAGPOOL) && !defined(BCMRESVFRAGPOOL_DISABLED)
- n = 0; /* IMPORTANT: DO NOT allocate any packets in resv pool */
- if (pktpool_init(osh, pktpool_resv_lfrag,
- &n, PKTFRAGSZ, TRUE, lbuf_frag) == BCME_ERROR) {
- ASSERT(0);
- goto error5;
- }
- pktpool_setmaxlen(pktpool_resv_lfrag, RESV_FRAG_POOL_LEN);
- #endif /* RESVFRAGPOOL */
- #endif /* BCMFRAGPOOL */
- #if defined(BCMRXFRAGPOOL) && !defined(BCMRXFRAGPOOL_DISABLED)
- n = 1;
- if ((err = pktpool_init(osh, pktpool_shared_rxlfrag,
- &n, PKTRXFRAGSZ, TRUE, lbuf_rxfrag)) != BCME_OK) {
- ASSERT(0);
- goto error6;
- }
- pktpool_setmaxlen(pktpool_shared_rxlfrag, SHARED_RXFRAG_POOL_LEN);
- #endif // endif
- #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 // endif
- #if defined(BCMRXFRAGPOOL) && !defined(BCMRXFRAGPOOL_DISABLED)
- pktpool_shared_rxlfrag,
- #else
- NULL,
- #endif // endif
- pktpool_shared)) == NULL) {
- ASSERT(0);
- goto error7;
- }
- #endif /* defined(BCMFRWDPOOLREORG) && !defined(BCMFRWDPOOLREORG_DISABLED) */
- pktpool_osh = osh;
- MALLOC_CLEAR_NOPERSIST(osh);
- return BCME_OK;
- #if defined(BCMFRWDPOOLREORG) && !defined(BCMFRWDPOOLREORG_DISABLED)
- /* detach poolreorg module */
- poolreorg_detach(frwd_poolreorg_info);
- error7:
- #endif /* defined(BCMFRWDPOOLREORG) && !defined(BCMFRWDPOOLREORG_DISABLED) */
- #if defined(BCMRXFRAGPOOL) && !defined(BCMRXFRAGPOOL_DISABLED)
- pktpool_deinit(osh, pktpool_shared_rxlfrag);
- error6:
- #endif // endif
- #if defined(BCMFRAGPOOL) && !defined(BCMFRAGPOOL_DISABLED)
- pktpool_deinit(osh, pktpool_shared_lfrag);
- error5:
- #endif // endif
- #if (defined(BCMRXFRAGPOOL) && !defined(BCMRXFRAGPOOL_DISABLED)) || \
- (defined(BCMFRAGPOOL) && !defined(BCMFRAGPOOL_DISABLED))
- pktpool_deinit(osh, pktpool_shared);
- #endif // endif
- error4:
- #if defined(BCMRXFRAGPOOL) && !defined(BCMRXFRAGPOOL_DISABLED)
- hnd_free(pktpool_shared_rxlfrag);
- pktpool_shared_rxlfrag = (pktpool_t *)NULL;
- error3:
- #endif /* BCMRXFRAGPOOL */
- #if defined(BCMFRAGPOOL) && !defined(BCMFRAGPOOL_DISABLED)
- hnd_free(pktpool_shared_lfrag);
- pktpool_shared_lfrag = (pktpool_t *)NULL;
- error2:
- #endif /* BCMFRAGPOOL */
- hnd_free(pktpool_shared);
- pktpool_shared = (pktpool_t *)NULL;
- error1:
- pktpool_dettach(osh);
- error0:
- MALLOC_CLEAR_NOPERSIST(osh);
- return err;
- } /* hnd_pktpool_init */
- /** 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 // endif
- #if defined(BCMFRAGPOOL) && defined(BCMRESVFRAGPOOL)
- if (POOL_ENAB(pktpool_resv_lfrag)) {
- int resv_size = (PKTFRAGSZ + LBUFFRAGSZ)*RESV_FRAG_POOL_LEN;
- hnd_resv_pool_init(resv_pool_info, resv_size);
- hnd_resv_pool_enable(resv_pool_info);
- }
- #endif /* BCMRESVFRAGPOOL */
- }
- #endif /* BCMPKTPOOL */
|