330 lines
12 KiB
C
Executable File
330 lines
12 KiB
C
Executable File
/*
|
|
* HND generic packet pool operation primitives
|
|
*
|
|
* Copyright (C) 2022, 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:>>
|
|
*/
|
|
|
|
#ifndef _hnd_pktpool_h_
|
|
#define _hnd_pktpool_h_
|
|
|
|
#include <typedefs.h>
|
|
#include <osl.h>
|
|
#include <osl_ext.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/* mutex macros for thread safe */
|
|
#ifdef HND_PKTPOOL_THREAD_SAFE
|
|
#define HND_PKTPOOL_MUTEX_DECL(mutex) OSL_EXT_MUTEX_DECL(mutex)
|
|
#else
|
|
#define HND_PKTPOOL_MUTEX_DECL(mutex)
|
|
#endif
|
|
|
|
#ifdef BCMPKTPOOL
|
|
#define POOL_ENAB(pool) ((pool) && (pool)->inited)
|
|
#else /* BCMPKTPOOL */
|
|
#define POOL_ENAB(bus) (FALSE)
|
|
#endif /* BCMPKTPOOL */
|
|
|
|
#ifndef PKTPOOL_LEN_MAX
|
|
#define PKTPOOL_LEN_MAX 40
|
|
#endif /* PKTPOOL_LEN_MAX */
|
|
#define PKTPOOL_CB_MAX 3
|
|
#define PKTPOOL_CB_MAX_AVL 4
|
|
|
|
/* REMOVE_RXCPLID is an arg for pktpool callback function for removing rxcplID
|
|
* and host addr associated with the rxfrag or shared pool buffer during pktpool_reclaim().
|
|
*/
|
|
#define REMOVE_RXCPLID 2
|
|
|
|
#define FREE_ALL_PKTS 0
|
|
#define FREE_ALL_FRAG_PKTS 1
|
|
|
|
/* PKTPOOL_ALLOC ISSUES */
|
|
#define PKT_ALLOC_SUCCESS 0
|
|
#define PKT_ALLOC_FAIL_GENERIC -1
|
|
#define PKT_ALLOC_FAIL_NOPKT -2
|
|
#define PKT_ALLOC_FAIL_NOCMPLID -3
|
|
#define PKT_ALLOC_FAIL_NOHOSTADDR -4
|
|
|
|
/* forward declaration */
|
|
struct pktpool;
|
|
|
|
typedef void (*pktpool_cb_t)(struct pktpool *pool, void *arg);
|
|
typedef struct {
|
|
pktpool_cb_t cb;
|
|
void *arg;
|
|
uint8 refcnt;
|
|
} pktpool_cbinfo_t;
|
|
|
|
typedef void (*pktpool_rxurb_cb_t)(struct pktpool *pool, void *arg, uint8 *addr, uint16 len);
|
|
typedef struct {
|
|
pktpool_rxurb_cb_t cb;
|
|
void *arg;
|
|
} pktpool_rxurb_cbinfo_t;
|
|
|
|
/** PCIe SPLITRX related: call back fn extension to populate host address in pool pkt */
|
|
typedef int (*pktpool_cb_extn_t)(struct pktpool *pool, void *arg1, void* pkt, int arg2,
|
|
uint *pktcnt);
|
|
typedef struct {
|
|
pktpool_cb_extn_t cb;
|
|
void *arg;
|
|
} pktpool_cbextn_info_t;
|
|
|
|
#ifdef BCMDBG_POOL
|
|
/* pkt pool debug states */
|
|
#define POOL_IDLE 0
|
|
#define POOL_RXFILL 1
|
|
#define POOL_RXDH 2
|
|
#define POOL_RXD11 3
|
|
#define POOL_TXDH 4
|
|
#define POOL_TXD11 5
|
|
#define POOL_AMPDU 6
|
|
#define POOL_TXENQ 7
|
|
|
|
typedef struct {
|
|
void *p;
|
|
uint32 cycles;
|
|
uint32 dur;
|
|
} pktpool_dbg_t;
|
|
|
|
typedef struct {
|
|
uint8 txdh; /* tx to host */
|
|
uint8 txd11; /* tx to d11 */
|
|
uint8 enq; /* waiting in q */
|
|
uint8 rxdh; /* rx from host */
|
|
uint8 rxd11; /* rx from d11 */
|
|
uint8 rxfill; /* dma_rxfill */
|
|
uint8 idle; /* avail in pool */
|
|
} pktpool_stats_t;
|
|
#endif /* BCMDBG_POOL */
|
|
|
|
typedef struct pktpool {
|
|
bool inited; /**< pktpool_init was successful */
|
|
uint8 type; /**< type of lbuf: basic, frag, etc */
|
|
uint8 id; /**< pktpool ID: index in registry */
|
|
bool istx; /**< direction: transmit or receive data path */
|
|
HND_PKTPOOL_MUTEX_DECL(mutex) /**< thread-safe mutex */
|
|
|
|
void * freelist; /**< free list: see PKTNEXTFREE(), PKTSETNEXTFREE() */
|
|
uint16 avail; /**< number of packets in pool's free list */
|
|
uint16 n_pkts; /**< number of packets managed by pool */
|
|
uint16 maxlen; /**< maximum size of pool <= PKTPOOL_LEN_MAX */
|
|
uint16 max_pkt_bytes; /**< size of pkt buffer in [bytes], excluding lbuf|lbuf_frag */
|
|
|
|
bool empty;
|
|
uint8 cbtoggle;
|
|
uint8 cbcnt;
|
|
uint8 ecbcnt;
|
|
uint8 emptycb_disable; /**< Value of type enum pktpool_empty_cb_state */
|
|
uint8 metasz; /**< size of tx or rx metadata allocated after lbuf struct */
|
|
uint16 metaoff; /**< offset of tx or rx metadata allocated after lbuf struct */
|
|
pktpool_cbinfo_t *availcb_excl;
|
|
pktpool_cbinfo_t cbs[PKTPOOL_CB_MAX_AVL];
|
|
pktpool_cbinfo_t ecbs[PKTPOOL_CB_MAX];
|
|
pktpool_cbextn_info_t cbext; /**< PCIe SPLITRX related */
|
|
pktpool_cbextn_info_t rxcplidfn;
|
|
pktpool_cbinfo_t dmarxfill;
|
|
/* variables for pool_heap management */
|
|
uint32 poolheap_flag;
|
|
uint16 poolheap_count; /* Number of allocation done from this pool */
|
|
uint16 min_backup_buf; /* Minimum number of buffer that should be kept in pool */
|
|
bool is_heap_pool; /* Whether this pool can be used as heap */
|
|
bool release_active;
|
|
uint8 mem_handle;
|
|
|
|
struct resv_info *resv_info; /* Resv frag pool info */
|
|
uint resv_pool_idx;
|
|
pktpool_cbextn_info_t cb_haddr; /**< PCIe SPLITRX related */
|
|
pktpool_rxurb_cbinfo_t dmarxurb; /**< dma rx urb related */
|
|
|
|
uint32 pktpool_flags; /* different packet pool flags */
|
|
void *freelist_tail; /* free list tail, used only in specific rxlfrag pools */
|
|
|
|
#ifdef BCMDBG_POOL
|
|
uint8 dbg_cbcnt;
|
|
pktpool_cbinfo_t dbg_cbs[PKTPOOL_CB_MAX];
|
|
uint16 dbg_qlen;
|
|
pktpool_dbg_t dbg_q[PKTPOOL_LEN_MAX + 1];
|
|
#endif
|
|
} pktpool_t;
|
|
|
|
/* Flags to indicate the packet pool status.
|
|
* PKTPOOL_RXLFRAG_SORTED_INSERT: Ordered list of rxfrag packets.
|
|
* PKTPOOL_POOL_ZERO: Allow reset of private packet pool memory
|
|
* and verify prior usage
|
|
*/
|
|
#define PKTPOOL_RXLFRAG_SORTED_INSERT 0x00000001u
|
|
#define PKTPOOL_POOL_ZERO 0x00000002u
|
|
|
|
pktpool_t *get_pktpools_registry(int id);
|
|
#define pktpool_get(pktp) (pktpool_get_ext((pktp), (pktp)->type, NULL))
|
|
|
|
/* Incarnate a pktpool registry. On success returns total_pools. */
|
|
extern int pktpool_attach(osl_t *osh, uint32 total_pools);
|
|
extern int pktpool_dettach(osl_t *osh); /* Relinquish registry */
|
|
|
|
extern int pktpool_init(osl_t *osh, pktpool_t *pktp, int *pktplen, int plen, bool istx, uint8 type,
|
|
bool is_heap_pool, uint32 heap_pool_flag, uint16 min_backup_buf);
|
|
extern int pktpool_deinit(osl_t *osh, pktpool_t *pktp);
|
|
extern int pktpool_fill(osl_t *osh, pktpool_t *pktp, bool minimal);
|
|
extern int pktpool_empty(osl_t *osh, pktpool_t *pktp);
|
|
extern uint16 pktpool_reclaim(osl_t *osh, pktpool_t *pktp, uint16 free_cnt, uint8 action);
|
|
void pktpool_update_freelist(pktpool_t *pktp, void *p, uint pkts_consumed);
|
|
extern void* pktpool_get_ext(pktpool_t *pktp, uint8 type, uint *pktcnt);
|
|
extern void pktpool_free(pktpool_t *pktp, void *p);
|
|
void pktpool_nfree(pktpool_t *pktp, void *head, void *tail, uint count);
|
|
extern int pktpool_add(pktpool_t *pktp, void *p);
|
|
extern int pktpool_avail_notify_normal(osl_t *osh, pktpool_t *pktp);
|
|
extern int pktpool_avail_notify_exclusive(osl_t *osh, pktpool_t *pktp, pktpool_cb_t cb);
|
|
extern int pktpool_avail_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg);
|
|
extern int pktpool_avail_deregister(pktpool_t *pktp, pktpool_cb_t cb, void *arg);
|
|
extern int pktpool_empty_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg);
|
|
extern int pktpool_setmaxlen(pktpool_t *pktp, uint16 max_pkts);
|
|
extern int pktpool_setmaxlen_strict(osl_t *osh, pktpool_t *pktp, uint16 max_pkts);
|
|
extern void pktpool_emptycb_disable(pktpool_t *pktp, bool disable);
|
|
extern bool pktpool_emptycb_disabled(pktpool_t *pktp);
|
|
extern int pktpool_hostaddr_fill_register(pktpool_t *pktp, pktpool_cb_extn_t cb, void *arg1);
|
|
extern int pktpool_hostaddr_ext_fill_register(pktpool_t *pktp, pktpool_cb_extn_t cb, void *arg1);
|
|
extern int pktpool_rxcplid_fill_register(pktpool_t *pktp, pktpool_cb_extn_t cb, void *arg);
|
|
extern void pktpool_invoke_dmarxfill(pktpool_t *pktp);
|
|
extern int pkpool_haddr_avail_register_cb(pktpool_t *pktp, pktpool_cb_t cb, void *arg);
|
|
extern int pkpool_rxurb_register_cb(pktpool_t *pktp, pktpool_rxurb_cb_t cb, void *arg);
|
|
extern int pktpool_avail(pktpool_t *pktpool);
|
|
|
|
#define POOLPTR(pp) ((pktpool_t *)(pp))
|
|
#define POOLID(pp) (POOLPTR(pp)->id)
|
|
|
|
#define POOLSETID(pp, ppid) (POOLPTR(pp)->id = (ppid))
|
|
|
|
#define pktpool_tot_pkts(pp) (POOLPTR(pp)->n_pkts) /**< n_pkts = avail + in_use <= max_pkts */
|
|
#define pktpool_max_pkt_bytes(pp) (POOLPTR(pp)->max_pkt_bytes)
|
|
#define pktpool_max_pkts(pp) (POOLPTR(pp)->maxlen)
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------------
|
|
* A pool ID is assigned with a pkt pool during pool initialization. This is
|
|
* done by maintaining a registry of all initialized pools, and the registry
|
|
* index at which the pool is registered is used as the pool's unique ID.
|
|
* ID 0 is reserved and is used to signify an invalid pool ID.
|
|
* All packets henceforth allocated from a pool will be tagged with the pool's
|
|
* unique ID. Packets allocated from the heap will use the reserved ID = 0.
|
|
* Packets with non-zero pool id signify that they were allocated from a pool.
|
|
* A maximum of 15 pools are supported, allowing a 4bit pool ID to be used
|
|
* in place of a 32bit pool pointer in each packet.
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
#define PKTPOOL_INVALID_ID (0)
|
|
#define PKTPOOL_MAXIMUM_ID (15)
|
|
|
|
/* Registry of pktpool(s) */
|
|
/* Pool ID to/from Pool Pointer converters */
|
|
#define PKTPOOL_ID2PTR(id) (get_pktpools_registry(id))
|
|
#define PKTPOOL_PTR2ID(pp) (POOLID(pp))
|
|
|
|
/* 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))
|
|
|
|
#ifndef PKTID_POOL
|
|
/* max pktids reserved for pktpool is updated properly in Makeconf */
|
|
#define PKTID_POOL (PKT_MAXIMUM_ID - 32u)
|
|
#endif /* PKTID_POOL */
|
|
extern uint32 total_pool_pktid_count;
|
|
|
|
extern int pktpool_get_last_err(pktpool_t *pktp);
|
|
#define PKTPOOL_ERR_TYPE_SPLIT_SUPPORTED
|
|
|
|
#ifdef BCMDBG_POOL
|
|
extern int pktpool_dbg_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg);
|
|
extern int pktpool_start_trigger(pktpool_t *pktp, void *p);
|
|
extern int pktpool_dbg_dump(pktpool_t *pktp);
|
|
extern int pktpool_dbg_notify(pktpool_t *pktp);
|
|
extern int pktpool_stats_dump(pktpool_t *pktp, pktpool_stats_t *stats);
|
|
#endif /* BCMDBG_POOL */
|
|
|
|
#ifdef BCMPKTPOOL
|
|
#define SHARED_POOL (pktpool_shared)
|
|
extern pktpool_t *pktpool_shared;
|
|
#ifdef BCMFRAGPOOL
|
|
#define SHARED_FRAG_POOL (pktpool_shared_lfrag)
|
|
extern pktpool_t *pktpool_shared_lfrag;
|
|
#define SHARED_ALFRAG_POOL (pktpool_shared_alfrag)
|
|
extern pktpool_t *pktpool_shared_alfrag;
|
|
#define SHARED_ALFRAG_DATA_POOL (pktpool_shared_alfrag_data)
|
|
extern pktpool_t *pktpool_shared_alfrag_data;
|
|
#endif /* BCMFRAGPOOL */
|
|
|
|
#ifdef BCMRESVFRAGPOOL
|
|
#define RESV_FRAG_POOL (NULL)
|
|
#define RESV_ALFRAG_POOL (pktpool_resv_alfrag)
|
|
#define RESV_ALFRAG_DATA_POOL (pktpool_resv_alfrag_data)
|
|
#define RESV_POOL_INFO (resv_pool_info)
|
|
#else
|
|
#define RESV_FRAG_POOL ((struct pktpool *)NULL)
|
|
#define RESV_POOL_INFO (NULL)
|
|
#endif /* BCMRESVFRAGPOOL */
|
|
|
|
/** PCIe SPLITRX related */
|
|
#define SHARED_RXFRAG_POOL (pktpool_shared_rxlfrag)
|
|
extern pktpool_t *pktpool_shared_rxlfrag;
|
|
|
|
#define SHARED_RXDATA_POOL (pktpool_shared_rxdata)
|
|
extern pktpool_t *pktpool_shared_rxdata;
|
|
|
|
int hnd_pktpool_init(osl_t *osh);
|
|
void hnd_pktpool_deinit(osl_t *osh);
|
|
int hnd_pktpool_fill(pktpool_t *pktpool, bool minimal);
|
|
void hnd_pktpool_refill(bool minimal);
|
|
|
|
#ifdef BCMRESVFRAGPOOL
|
|
extern pktpool_t *pktpool_resv_alfrag;
|
|
extern pktpool_t *pktpool_resv_alfrag_data;
|
|
extern struct resv_info *resv_pool_info;
|
|
#endif /* BCMRESVFRAGPOOL */
|
|
|
|
/* Current identified use case flags for pool heap manager */
|
|
#define POOL_HEAP_FLAG_D3 (1 << 0)
|
|
#define POOL_HEAP_FLAG_RSRVPOOL (1 << 1)
|
|
|
|
#ifdef POOL_HEAP_RECONFIG
|
|
typedef void (*pktpool_heap_cb_t)(void *arg, bool entry);
|
|
|
|
extern void hnd_pktpool_heap_handle(osl_t *osh, uint32 flag, bool enable);
|
|
extern int hnd_pktpool_heap_register_cb(pktpool_heap_cb_t fn, void *ctxt, uint32 flag);
|
|
extern int hnd_pktpool_heap_deregister_cb(pktpool_heap_cb_t fn);
|
|
extern void *hnd_pktpool_freelist_alloc(uint size, uint alignbits, uint32 flag);
|
|
extern uint16 hnd_pktpool_get_min_bkup_buf(pktpool_t *pktp);
|
|
#endif /* POOL_HEAP_RECONFIG */
|
|
extern uint32 hnd_pktpool_get_total_poolheap_count(void);
|
|
|
|
#else /* BCMPKTPOOL */
|
|
#define SHARED_POOL ((struct pktpool *)NULL)
|
|
#endif /* BCMPKTPOOL */
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* _hnd_pktpool_h_ */
|