From cde9070d9970eef1f7ec2360586c802a16230ad8 Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Fri, 10 May 2024 07:43:50 +0000 Subject: [PATCH] rtl88x2CE_WiFi_linux driver --- kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/hnd_pktpool.c | 449 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 373 insertions(+), 76 deletions(-) diff --git a/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/hnd_pktpool.c b/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/hnd_pktpool.c index 01157e7..689dea5 100644 --- a/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/hnd_pktpool.c +++ b/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/hnd_pktpool.c @@ -1,15 +1,16 @@ -/* SPDX-License-Identifier: GPL-2.0 */ /* * HND generic packet pool operation primitives * - * Copyright (C) 1999-2019, Broadcom Corporation - * + * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation + * + * Copyright (C) 1999-2017, 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 @@ -17,7 +18,7 @@ * 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. @@ -25,7 +26,7 @@ * * <<Broadcom-WL-IPTag/Open:>> * - * $Id: $ + * $Id: hnd_pktpool.c 677681 2017-01-04 09:10:30Z $ */ #include <typedefs.h> @@ -33,6 +34,12 @@ #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 @@ -45,7 +52,7 @@ #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 // endif /* Registry size is one larger than max pools, as slot #0 is reserved */ #define PKTPOOLREG_RSVD_ID (0U) @@ -85,10 +92,9 @@ static int pktpool_deregister(pktpool_t * poolptr); /** add declaration */ -static int pktpool_avail_notify(pktpool_t *pktp); +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) @@ -108,10 +114,12 @@ return pktpools_registry[id] == pp; } -int /* Construct a pool registry to serve a maximum of total_pools */ +/** 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; @@ -131,10 +139,12 @@ return (int)pktpools_max; } -int /* Destruct the pool registry. Ascertain all pools were first de-inited */ +/** 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; @@ -152,7 +162,8 @@ return BCME_OK; } -static int /* Register a pool in a free slot; return the registry slot index */ +/** Registers a pool in a free slot; returns the registry slot index */ +static int pktpool_register(pktpool_t * poolptr) { uint32 poolid; @@ -174,7 +185,8 @@ return PKTPOOL_INVALID_ID; /* error: registry is full */ } -static int /* Deregister a pktpool, given the pool pointer; tag slot as free */ +/** Deregisters a pktpool, given the pool pointer; tag slot as free */ +static int pktpool_deregister(pktpool_t * poolptr) { uint32 poolid; @@ -195,12 +207,10 @@ return BCME_OK; } - -/* +/** * pktpool_init: - * User provides a pktpool_t sturcture and specifies the number of packets to - * be pre-filled into the pool (pplen). The size of all packets in a pool must - * be the same and is specified by plen. + * 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. @@ -211,9 +221,14 @@ * 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 *pplen, int plen, bool istx, uint8 type) +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; @@ -221,9 +236,9 @@ ASSERT(pktp != NULL); ASSERT(osh != NULL); - ASSERT(pplen != NULL); + ASSERT(n_pkts != NULL); - pktplen = *pplen; + pktplen = *n_pkts; bzero(pktp, sizeof(pktpool_t)); @@ -235,7 +250,7 @@ pktp->inited = TRUE; pktp->istx = istx ? TRUE : FALSE; - pktp->plen = (uint16)plen; + pktp->max_pkt_bytes = (uint16)max_pkt_bytes; pktp->type = type; if (HND_PKTPOOL_MUTEX_CREATE("pktpool", &pktp->mutex) != OSL_EXT_SUCCESS) { @@ -247,7 +262,7 @@ for (i = 0; i < pktplen; i++) { void *p; - p = PKTGET(osh, plen, TRUE); + p = PKTGET(osh, max_pkt_bytes, TRUE); if (p == NULL) { /* Not able to allocate all requested pkts @@ -269,17 +284,17 @@ #ifdef BCMDBG_POOL pktp->dbg_q[pktp->dbg_qlen++].p = p; -#endif +#endif // endif } exit: - pktp->len = pktp->avail; + pktp->n_pkts = pktp->avail; - *pplen = pktp->len; + *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. @@ -298,11 +313,11 @@ #ifdef BCMDBG_POOL { int i; - for (i = 0; i <= pktp->len; i++) { + for (i = 0; i <= pktp->n_pkts; i++) { pktp->dbg_q[i].p = NULL; } } -#endif +#endif // endif while (pktp->freelist != NULL) { void * p = pktp->freelist; @@ -315,13 +330,13 @@ PKTFREE(osh, p, pktp->istx); /* free the packet */ freed++; - ASSERT(freed <= pktp->len); + ASSERT(freed <= pktp->n_pkts); } pktp->avail -= freed; ASSERT(pktp->avail == 0); - pktp->len -= freed; + pktp->n_pkts -= freed; pktpool_deregister(pktp); /* release previously acquired unique pool id */ POOLSETID(pktp, PKTPOOL_INVALID_ID); @@ -332,7 +347,7 @@ pktp->inited = FALSE; /* Are there still pending pkts? */ - ASSERT(pktp->len == 0); + ASSERT(pktp->n_pkts == 0); return 0; } @@ -342,19 +357,19 @@ { void *p; int err = 0; - int len, psize, maxlen; + 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->plen != 0); + ASSERT(pktp->max_pkt_bytes != 0); maxlen = pktp->maxlen; psize = minimal ? (maxlen >> 2) : maxlen; - for (len = (int)pktp->len; len < psize; len++) { + for (n_pkts = (int)pktp->n_pkts; n_pkts < psize; n_pkts++) { - p = PKTGET(osh, pktp->len, TRUE); + p = PKTGET(osh, pktp->n_pkts, TRUE); if (p == NULL) { err = BCME_NOMEM; @@ -380,6 +395,134 @@ 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) { @@ -392,6 +535,7 @@ 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--; @@ -408,10 +552,10 @@ pktp->freelist = p; /* free list points to newly inserted packet */ pktp->avail++; - ASSERT(pktp->avail <= pktp->len); + ASSERT(pktp->avail <= pktp->n_pkts); } -/* utility for registering host addr fill function called from pciedev */ +/** 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) @@ -438,8 +582,8 @@ pktp->rxcplidfn.arg = arg; return 0; } -/* Callback functions for split rx modes */ -/* when evr host posts rxbuffer, invike dma_rxfill from pciedev layer */ + +/** whenever host posts rxbuffer, invoke dma_rxfill from pciedev layer */ void pktpool_invoke_dmarxfill(pktpool_t *pktp) { @@ -449,6 +593,8 @@ 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) { @@ -460,7 +606,11 @@ return 0; } -/* No BCMATTACHFN as it is used in xdc_enable_ep which is not an attach function */ + +/** + * 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) { @@ -473,6 +623,14 @@ 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; @@ -482,6 +640,7 @@ ASSERT(pktp->cbs[i].cb == NULL); pktp->cbs[i].cb = cb; pktp->cbs[i].arg = arg; + pktp->cbs[i].refcnt++; pktp->cbcnt++; done: @@ -492,6 +651,55 @@ 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) { @@ -523,6 +731,7 @@ return err; } +/** Calls registered callback functions */ static int pktpool_empty_notify(pktpool_t *pktp) { @@ -688,6 +897,7 @@ } int pktpool_stop_trigger(pktpool_t *pktp, void *p); + int pktpool_stop_trigger(pktpool_t *pktp, void *p) { @@ -732,6 +942,7 @@ int pktpool_avail_notify_normal(osl_t *osh, pktpool_t *pktp) { + BCM_REFERENCE(osh); ASSERT(pktp); /* protect shared resource */ @@ -752,6 +963,7 @@ { int i; int err; + BCM_REFERENCE(osh); ASSERT(pktp); @@ -779,7 +991,7 @@ return err; } -static int +static void pktpool_avail_notify(pktpool_t *pktp) { int i, k, idx; @@ -788,7 +1000,7 @@ ASSERT(pktp); if (pktp->availcb_excl != NULL) { pktp->availcb_excl->cb(pktp, pktp->availcb_excl->arg); - return 0; + return; } k = pktp->cbcnt - 1; @@ -810,9 +1022,10 @@ */ pktp->cbtoggle ^= 1; - return 0; + return; } +/** Gets an empty packet from the caller provided pool */ void * pktpool_get(pktpool_t *pktp) { @@ -821,7 +1034,6 @@ /* protect shared resource */ if (HND_PKTPOOL_MUTEX_ACQUIRE(&pktp->mutex, OSL_EXT_TIME_FOREVER) != OSL_EXT_SUCCESS) return NULL; - p = pktpool_deq(pktp); @@ -834,7 +1046,6 @@ if (p == NULL) goto done; } - done: /* protect shared resource */ @@ -854,7 +1065,7 @@ ASSERT(p != NULL); #ifdef BCMDBG_POOL /* pktpool_stop_trigger(pktp, p); */ -#endif +#endif // endif pktpool_enq(pktp, p); @@ -888,6 +1099,7 @@ return; } +/** Adds a caller provided (empty) packet to the caller provided pool */ int pktpool_add(pktpool_t *pktp, void *p) { @@ -899,21 +1111,21 @@ ASSERT(p != NULL); - if (pktp->len == pktp->maxlen) { + if (pktp->n_pkts == pktp->maxlen) { err = BCME_RANGE; goto done; } /* pkts in pool have same length */ - ASSERT(pktp->plen == PKTLEN(OSH_NULL, p)); + ASSERT(pktp->max_pkt_bytes == PKTLEN(OSH_NULL, p)); PKTSETPOOL(OSH_NULL, p, TRUE, pktp); - pktp->len++; + pktp->n_pkts++; pktpool_enq(pktp, p); #ifdef BCMDBG_POOL pktp->dbg_q[pktp->dbg_qlen++].p = p; -#endif +#endif // endif done: /* protect shared resource */ @@ -923,7 +1135,8 @@ return err; } -/* Force pktpool_setmaxlen () into RAM as it uses a constant +/** + * Force pktpool_setmaxlen () into RAM as it uses a constant * (PKTPOOL_LEN_MAX) that may be changed post tapeout for ROM-based chips. */ int @@ -940,7 +1153,7 @@ * since we currently do not reduce the pool len * already allocated */ - pktp->maxlen = (pktp->len > maxlen) ? pktp->len : maxlen; + pktp->maxlen = (pktp->n_pkts > maxlen) ? pktp->n_pkts : maxlen; /* protect shared resource */ if (HND_PKTPOOL_MUTEX_RELEASE(&pktp->mutex) != OSL_EXT_SUCCESS) @@ -984,27 +1197,37 @@ #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; -void +/** + * 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); - return; + err = BCME_ERROR; + goto error0; } pktpool_shared = MALLOCZ(osh, sizeof(pktpool_t)); if (pktpool_shared == NULL) { ASSERT(0); + err = BCME_NOMEM; goto error1; } @@ -1012,18 +1235,31 @@ pktpool_shared_lfrag = MALLOCZ(osh, sizeof(pktpool_t)); if (pktpool_shared_lfrag == NULL) { ASSERT(0); + err = BCME_NOMEM; goto error2; } -#endif +#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 // endif /* * At this early stage, there's not enough memory to allocate all @@ -1039,8 +1275,9 @@ * were not filled into the pool. */ n = 1; - if (pktpool_init(osh, pktpool_shared, - &n, PKTBUFSZ, FALSE, lbuf_basic) == BCME_ERROR) { + 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; } @@ -1048,40 +1285,76 @@ #if defined(BCMFRAGPOOL) && !defined(BCMFRAGPOOL_DISABLED) n = 1; - if (pktpool_init(osh, pktpool_shared_lfrag, - &n, PKTFRAGSZ, TRUE, lbuf_frag) == BCME_ERROR) { + 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); -#endif +#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 (pktpool_init(osh, pktpool_shared_rxlfrag, - &n, PKTRXFRAGSZ, TRUE, lbuf_rxfrag) == BCME_ERROR) { + 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 // 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; + 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 // endif #if defined(BCMFRAGPOOL) && !defined(BCMFRAGPOOL_DISABLED) pktpool_deinit(osh, pktpool_shared_lfrag); error5: -#endif +#endif // endif #if (defined(BCMRXFRAGPOOL) && !defined(BCMRXFRAGPOOL_DISABLED)) || \ (defined(BCMFRAGPOOL) && !defined(BCMFRAGPOOL_DISABLED)) pktpool_deinit(osh, pktpool_shared); -#endif +#endif // endif error4: #if defined(BCMRXFRAGPOOL) && !defined(BCMRXFRAGPOOL_DISABLED) @@ -1101,19 +1374,36 @@ error1: pktpool_dettach(osh); -} +error0: + MALLOC_CLEAR_NOPERSIST(osh); + return err; +} /* hnd_pktpool_init */ -void +/** is called at each 'wl up' */ +int hnd_pktpool_fill(pktpool_t *pktpool, bool minimal) { - pktpool_fill(pktpool_osh, pktpool, minimal); + return (pktpool_fill(pktpool_osh, pktpool, minimal)); } -/* refill pktpools after reclaim */ +/** 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 */ @@ -1127,6 +1417,13 @@ if (POOL_ENAB(pktpool_shared_rxlfrag)) { pktpool_fill(pktpool_osh, pktpool_shared_rxlfrag, minimal); } -#endif +#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 */ -- Gitblit v1.6.2