1 /* 2 * HND generic packet pool operation primitives 3 * 4 * Copyright (C) 2020, Broadcom. 5 * 6 * Unless you and Broadcom execute a separate written software license 7 * agreement governing use of this software, this software is licensed to you 8 * under the terms of the GNU General Public License version 2 (the "GPL"), 9 * available at http://www.broadcom.com/licenses/GPLv2.php, with the 10 * following added to such license: 11 * 12 * As a special exception, the copyright holders of this software give you 13 * permission to link this software with independent modules, and to copy and 14 * distribute the resulting executable under terms of your choice, provided that 15 * you also meet, for each linked independent module, the terms and conditions of 16 * the license of that module. An independent module is a module which is not 17 * derived from this software. The special exception does not apply to any 18 * modifications of the software. 19 * 20 * 21 * <<Broadcom-WL-IPTag/Dual:>> 22 */ 23 24 #ifndef _hnd_pktpool_h_ 25 #define _hnd_pktpool_h_ 26 27 #include <typedefs.h> 28 #include <osl.h> 29 #include <osl_ext.h> 30 31 #ifdef __cplusplus 32 extern "C" { 33 #endif 34 35 /* mutex macros for thread safe */ 36 #ifdef HND_PKTPOOL_THREAD_SAFE 37 #define HND_PKTPOOL_MUTEX_DECL(mutex) OSL_EXT_MUTEX_DECL(mutex) 38 #else 39 #define HND_PKTPOOL_MUTEX_DECL(mutex) 40 #endif 41 42 #ifdef BCMPKTPOOL 43 #define POOL_ENAB(pool) ((pool) && (pool)->inited) 44 #else /* BCMPKTPOOL */ 45 #define POOL_ENAB(bus) 0 46 #endif /* BCMPKTPOOL */ 47 48 #ifndef PKTPOOL_LEN_MAX 49 #define PKTPOOL_LEN_MAX 40 50 #endif /* PKTPOOL_LEN_MAX */ 51 #define PKTPOOL_CB_MAX 3 52 #define PKTPOOL_CB_MAX_AVL 4 53 54 /* REMOVE_RXCPLID is an arg for pktpool callback function for removing rxcplID 55 * and host addr associated with the rxfrag or shared pool buffer during pktpool_reclaim(). 56 */ 57 #define REMOVE_RXCPLID 2 58 59 #define FREE_ALL_PKTS 0 60 #define FREE_ALL_FRAG_PKTS 1 61 62 /* forward declaration */ 63 struct pktpool; 64 65 typedef void (*pktpool_cb_t)(struct pktpool *pool, void *arg); 66 typedef struct { 67 pktpool_cb_t cb; 68 void *arg; 69 uint8 refcnt; 70 } pktpool_cbinfo_t; 71 72 /** PCIe SPLITRX related: call back fn extension to populate host address in pool pkt */ 73 typedef int (*pktpool_cb_extn_t)(struct pktpool *pool, void *arg1, void* pkt, int arg2, 74 uint *pktcnt); 75 typedef struct { 76 pktpool_cb_extn_t cb; 77 void *arg; 78 } pktpool_cbextn_info_t; 79 80 #ifdef BCMDBG_POOL 81 /* pkt pool debug states */ 82 #define POOL_IDLE 0 83 #define POOL_RXFILL 1 84 #define POOL_RXDH 2 85 #define POOL_RXD11 3 86 #define POOL_TXDH 4 87 #define POOL_TXD11 5 88 #define POOL_AMPDU 6 89 #define POOL_TXENQ 7 90 91 typedef struct { 92 void *p; 93 uint32 cycles; 94 uint32 dur; 95 } pktpool_dbg_t; 96 97 typedef struct { 98 uint8 txdh; /* tx to host */ 99 uint8 txd11; /* tx to d11 */ 100 uint8 enq; /* waiting in q */ 101 uint8 rxdh; /* rx from host */ 102 uint8 rxd11; /* rx from d11 */ 103 uint8 rxfill; /* dma_rxfill */ 104 uint8 idle; /* avail in pool */ 105 } pktpool_stats_t; 106 #endif /* BCMDBG_POOL */ 107 108 typedef struct pktpool { 109 bool inited; /**< pktpool_init was successful */ 110 uint8 type; /**< type of lbuf: basic, frag, etc */ 111 uint8 id; /**< pktpool ID: index in registry */ 112 bool istx; /**< direction: transmit or receive data path */ 113 HND_PKTPOOL_MUTEX_DECL(mutex) /**< thread-safe mutex */ 114 115 void * freelist; /**< free list: see PKTNEXTFREE(), PKTSETNEXTFREE() */ 116 uint16 avail; /**< number of packets in pool's free list */ 117 uint16 n_pkts; /**< number of packets managed by pool */ 118 uint16 maxlen; /**< maximum size of pool <= PKTPOOL_LEN_MAX */ 119 uint16 max_pkt_bytes; /**< size of pkt buffer in [bytes], excluding lbuf|lbuf_frag */ 120 121 bool empty; 122 uint8 cbtoggle; 123 uint8 cbcnt; 124 uint8 ecbcnt; 125 uint8 emptycb_disable; /**< Value of type enum pktpool_empty_cb_state */ 126 pktpool_cbinfo_t *availcb_excl; 127 pktpool_cbinfo_t cbs[PKTPOOL_CB_MAX_AVL]; 128 pktpool_cbinfo_t ecbs[PKTPOOL_CB_MAX]; 129 pktpool_cbextn_info_t cbext; /**< PCIe SPLITRX related */ 130 pktpool_cbextn_info_t rxcplidfn; 131 pktpool_cbinfo_t dmarxfill; 132 /* variables for pool_heap management */ 133 uint32 poolheap_flag; 134 uint16 poolheap_count; /* Number of allocation done from this pool */ 135 uint16 min_backup_buf; /* Minimum number of buffer that should be kept in pool */ 136 bool is_heap_pool; /* Whether this pool can be used as heap */ 137 bool release_active; 138 uint8 mem_handle; 139 #ifdef BCMDBG_POOL 140 uint8 dbg_cbcnt; 141 pktpool_cbinfo_t dbg_cbs[PKTPOOL_CB_MAX]; 142 uint16 dbg_qlen; 143 pktpool_dbg_t dbg_q[PKTPOOL_LEN_MAX + 1]; 144 #endif 145 } pktpool_t; 146 147 pktpool_t *get_pktpools_registry(int id); 148 #define pktpool_get(pktp) (pktpool_get_ext((pktp), (pktp)->type, NULL)) 149 150 /* Incarnate a pktpool registry. On success returns total_pools. */ 151 extern int pktpool_attach(osl_t *osh, uint32 total_pools); 152 extern int pktpool_dettach(osl_t *osh); /* Relinquish registry */ 153 154 extern int pktpool_init(osl_t *osh, pktpool_t *pktp, int *pktplen, int plen, bool istx, uint8 type, 155 bool is_heap_pool, uint32 heap_pool_flag, uint16 min_backup_buf); 156 extern int pktpool_deinit(osl_t *osh, pktpool_t *pktp); 157 extern int pktpool_fill(osl_t *osh, pktpool_t *pktp, bool minimal); 158 extern int pktpool_empty(osl_t *osh, pktpool_t *pktp); 159 extern uint16 pktpool_reclaim(osl_t *osh, pktpool_t *pktp, uint16 free_cnt, uint8 action); 160 void pktpool_update_freelist(pktpool_t *pktp, void *p, uint pkts_consumed); 161 extern void* pktpool_get_ext(pktpool_t *pktp, uint8 type, uint *pktcnt); 162 extern void pktpool_free(pktpool_t *pktp, void *p); 163 void pktpool_nfree(pktpool_t *pktp, void *head, void *tail, uint count); 164 extern int pktpool_add(pktpool_t *pktp, void *p); 165 extern int pktpool_avail_notify_normal(osl_t *osh, pktpool_t *pktp); 166 extern int pktpool_avail_notify_exclusive(osl_t *osh, pktpool_t *pktp, pktpool_cb_t cb); 167 extern int pktpool_avail_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg); 168 extern int pktpool_avail_deregister(pktpool_t *pktp, pktpool_cb_t cb, void *arg); 169 extern int pktpool_empty_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg); 170 extern int pktpool_setmaxlen(pktpool_t *pktp, uint16 max_pkts); 171 extern int pktpool_setmaxlen_strict(osl_t *osh, pktpool_t *pktp, uint16 max_pkts); 172 extern void pktpool_emptycb_disable(pktpool_t *pktp, bool disable); 173 extern bool pktpool_emptycb_disabled(pktpool_t *pktp); 174 extern int pktpool_hostaddr_fill_register(pktpool_t *pktp, pktpool_cb_extn_t cb, void *arg1); 175 extern int pktpool_rxcplid_fill_register(pktpool_t *pktp, pktpool_cb_extn_t cb, void *arg); 176 extern void pktpool_invoke_dmarxfill(pktpool_t *pktp); 177 extern int pkpool_haddr_avail_register_cb(pktpool_t *pktp, pktpool_cb_t cb, void *arg); 178 extern int pktpool_avail(pktpool_t *pktpool); 179 180 #define POOLPTR(pp) ((pktpool_t *)(pp)) 181 #define POOLID(pp) (POOLPTR(pp)->id) 182 183 #define POOLSETID(pp, ppid) (POOLPTR(pp)->id = (ppid)) 184 185 #define pktpool_tot_pkts(pp) (POOLPTR(pp)->n_pkts) /**< n_pkts = avail + in_use <= max_pkts */ 186 #define pktpool_max_pkt_bytes(pp) (POOLPTR(pp)->max_pkt_bytes) 187 #define pktpool_max_pkts(pp) (POOLPTR(pp)->maxlen) 188 189 /* 190 * ---------------------------------------------------------------------------- 191 * A pool ID is assigned with a pkt pool during pool initialization. This is 192 * done by maintaining a registry of all initialized pools, and the registry 193 * index at which the pool is registered is used as the pool's unique ID. 194 * ID 0 is reserved and is used to signify an invalid pool ID. 195 * All packets henceforth allocated from a pool will be tagged with the pool's 196 * unique ID. Packets allocated from the heap will use the reserved ID = 0. 197 * Packets with non-zero pool id signify that they were allocated from a pool. 198 * A maximum of 15 pools are supported, allowing a 4bit pool ID to be used 199 * in place of a 32bit pool pointer in each packet. 200 * ---------------------------------------------------------------------------- 201 */ 202 #define PKTPOOL_INVALID_ID (0) 203 #define PKTPOOL_MAXIMUM_ID (15) 204 205 /* Registry of pktpool(s) */ 206 /* Pool ID to/from Pool Pointer converters */ 207 #define PKTPOOL_ID2PTR(id) (get_pktpools_registry(id)) 208 #define PKTPOOL_PTR2ID(pp) (POOLID(pp)) 209 210 #ifndef PKTID_POOL 211 /* max pktids reserved for pktpool is updated properly in Makeconf */ 212 #define PKTID_POOL (PKT_MAXIMUM_ID - 32u) 213 #endif /* PKTID_POOL */ 214 extern uint32 total_pool_pktid_count; 215 216 #ifdef BCMDBG_POOL 217 extern int pktpool_dbg_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg); 218 extern int pktpool_start_trigger(pktpool_t *pktp, void *p); 219 extern int pktpool_dbg_dump(pktpool_t *pktp); 220 extern int pktpool_dbg_notify(pktpool_t *pktp); 221 extern int pktpool_stats_dump(pktpool_t *pktp, pktpool_stats_t *stats); 222 #endif /* BCMDBG_POOL */ 223 224 #ifdef BCMPKTPOOL 225 #define SHARED_POOL (pktpool_shared) 226 extern pktpool_t *pktpool_shared; 227 #ifdef BCMFRAGPOOL 228 #define SHARED_FRAG_POOL (pktpool_shared_lfrag) 229 extern pktpool_t *pktpool_shared_lfrag; 230 #endif 231 232 #ifdef BCMALFRAGPOOL 233 #define SHARED_ALFRAG_POOL (pktpool_shared_alfrag) 234 extern pktpool_t *pktpool_shared_alfrag; 235 236 #define SHARED_ALFRAG_DATA_POOL (pktpool_shared_alfrag_data) 237 extern pktpool_t *pktpool_shared_alfrag_data; 238 #endif 239 240 #ifdef BCMRESVFRAGPOOL 241 #define RESV_FRAG_POOL (pktpool_resv_lfrag) 242 #define RESV_POOL_INFO (resv_pool_info) 243 #else 244 #define RESV_FRAG_POOL ((struct pktpool *)NULL) 245 #define RESV_POOL_INFO (NULL) 246 #endif /* BCMRESVFRAGPOOL */ 247 248 /** PCIe SPLITRX related */ 249 #define SHARED_RXFRAG_POOL (pktpool_shared_rxlfrag) 250 extern pktpool_t *pktpool_shared_rxlfrag; 251 252 #define SHARED_RXDATA_POOL (pktpool_shared_rxdata) 253 extern pktpool_t *pktpool_shared_rxdata; 254 255 int hnd_pktpool_init(osl_t *osh); 256 void hnd_pktpool_deinit(osl_t *osh); 257 int hnd_pktpool_fill(pktpool_t *pktpool, bool minimal); 258 void hnd_pktpool_refill(bool minimal); 259 260 #ifdef BCMRESVFRAGPOOL 261 extern pktpool_t *pktpool_resv_lfrag; 262 extern struct resv_info *resv_pool_info; 263 #endif /* BCMRESVFRAGPOOL */ 264 265 /* Current identified use case flags for pool heap manager */ 266 #define POOL_HEAP_FLAG_D3 (1 << 0) 267 #define POOL_HEAP_FLAG_RSRVPOOL (1 << 1) 268 269 #ifdef POOL_HEAP_RECONFIG 270 typedef void (*pktpool_heap_cb_t)(void *arg, bool entry); 271 272 extern void hnd_pktpool_heap_handle(osl_t *osh, uint32 flag, bool enable); 273 extern int hnd_pktpool_heap_register_cb(pktpool_heap_cb_t fn, void *ctxt, uint32 flag); 274 extern int hnd_pktpool_heap_deregister_cb(pktpool_heap_cb_t fn); 275 extern void *hnd_pktpool_freelist_alloc(uint size, uint alignbits, uint32 flag); 276 extern uint16 hnd_pktpool_get_min_bkup_buf(pktpool_t *pktp); 277 #endif /* POOL_HEAP_RECONFIG */ 278 extern uint32 hnd_pktpool_get_total_poolheap_count(void); 279 280 #else /* BCMPKTPOOL */ 281 #define SHARED_POOL ((struct pktpool *)NULL) 282 #endif /* BCMPKTPOOL */ 283 284 #ifdef __cplusplus 285 } 286 #endif 287 288 #endif /* _hnd_pktpool_h_ */ 289