1 /* 2 * HND generic packet pool operation primitives 3 * 4 * Copyright (C) 1999-2019, 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 16 * of the license of that module. An independent module is a module which is 17 * not derived from this software. The special exception does not apply to any 18 * modifications of the software. 19 * 20 * Notwithstanding the above, under no circumstances may you combine this 21 * software in any way with any other Broadcom software provided under a license 22 * other than the GPL, without Broadcom's express prior written consent. 23 * 24 * 25 * <<Broadcom-WL-IPTag/Open:>> 26 * 27 * $Id: hnd_pktpool.h 633941 2016-04-26 07:04:26Z $ 28 */ 29 30 #ifndef _hnd_pktpool_h_ 31 #define _hnd_pktpool_h_ 32 33 #include <osl_ext.h> 34 35 #ifdef __cplusplus 36 extern "C" { 37 #endif // endif 38 39 /* mutex macros for thread safe */ 40 #ifdef HND_PKTPOOL_THREAD_SAFE 41 #define HND_PKTPOOL_MUTEX_DECL(mutex) OSL_EXT_MUTEX_DECL(mutex) 42 #else 43 #define HND_PKTPOOL_MUTEX_DECL(mutex) 44 #endif // endif 45 46 #ifdef BCMPKTPOOL 47 #define POOL_ENAB(pool) ((pool) && (pool)->inited) 48 #else /* BCMPKTPOOL */ 49 #define POOL_ENAB(bus) 0 50 #endif /* BCMPKTPOOL */ 51 52 #ifndef PKTPOOL_LEN_MAX 53 #define PKTPOOL_LEN_MAX 40 54 #endif /* PKTPOOL_LEN_MAX */ 55 #define PKTPOOL_CB_MAX 3 56 #define PKTPOOL_CB_MAX_AVL 4 57 58 /* REMOVE_RXCPLID is an arg for pktpool callback function for removing rxcplID 59 * and host addr associated with the rxfrag or shared pool buffer during 60 * pktpool_reclaim(). 61 */ 62 #define REMOVE_RXCPLID 2 63 64 /* forward declaration */ 65 struct pktpool; 66 67 typedef void (*pktpool_cb_t)(struct pktpool *pool, void *arg); 68 typedef struct { 69 pktpool_cb_t cb; 70 void *arg; 71 uint8 refcnt; 72 } pktpool_cbinfo_t; 73 74 /** PCIe SPLITRX related: call back fn extension to populate host address in 75 * pool pkt */ 76 typedef int (*pktpool_cb_extn_t)(struct pktpool *pool, void *arg1, void *pkt, 77 int arg2); 78 typedef struct { 79 pktpool_cb_extn_t cb; 80 void *arg; 81 } pktpool_cbextn_info_t; 82 83 #ifdef BCMDBG_POOL 84 /* pkt pool debug states */ 85 #define POOL_IDLE 0 86 #define POOL_RXFILL 1 87 #define POOL_RXDH 2 88 #define POOL_RXD11 3 89 #define POOL_TXDH 4 90 #define POOL_TXD11 5 91 #define POOL_AMPDU 6 92 #define POOL_TXENQ 7 93 94 typedef struct { 95 void *p; 96 uint32 cycles; 97 uint32 dur; 98 } pktpool_dbg_t; 99 100 typedef struct { 101 uint8 txdh; /* tx to host */ 102 uint8 txd11; /* tx to d11 */ 103 uint8 enq; /* waiting in q */ 104 uint8 rxdh; /* rx from host */ 105 uint8 rxd11; /* rx from d11 */ 106 uint8 rxfill; /* dma_rxfill */ 107 uint8 idle; /* avail in pool */ 108 } pktpool_stats_t; 109 #endif /* BCMDBG_POOL */ 110 111 typedef struct pktpool { 112 bool inited; /**< pktpool_init was successful */ 113 uint8 type; /**< type of lbuf: basic, frag, etc */ 114 uint8 id; /**< pktpool ID: index in registry */ 115 bool istx; /**< direction: transmit or receive data path */ 116 HND_PKTPOOL_MUTEX_DECL(mutex) /**< thread-safe mutex */ 117 118 void *freelist; /**< free list: see PKTNEXTFREE(), PKTSETNEXTFREE() */ 119 uint16 avail; /**< number of packets in pool's free list */ 120 uint16 n_pkts; /**< number of packets managed by pool */ 121 uint16 maxlen; /**< maximum size of pool <= PKTPOOL_LEN_MAX */ 122 uint16 max_pkt_bytes; /**< size of pkt buffer in [bytes], excluding 123 lbuf|lbuf_frag */ 124 125 bool empty; 126 uint8 cbtoggle; 127 uint8 cbcnt; 128 uint8 ecbcnt; 129 uint8 emptycb_disable; /**< Value of type enum pktpool_empty_cb_state */ 130 pktpool_cbinfo_t *availcb_excl; 131 pktpool_cbinfo_t cbs[PKTPOOL_CB_MAX_AVL]; 132 pktpool_cbinfo_t ecbs[PKTPOOL_CB_MAX]; 133 pktpool_cbextn_info_t cbext; /**< PCIe SPLITRX related */ 134 pktpool_cbextn_info_t rxcplidfn; 135 #ifdef BCMDBG_POOL 136 uint8 dbg_cbcnt; 137 pktpool_cbinfo_t dbg_cbs[PKTPOOL_CB_MAX]; 138 uint16 dbg_qlen; 139 pktpool_dbg_t dbg_q[PKTPOOL_LEN_MAX + 1]; 140 #endif // endif 141 pktpool_cbinfo_t dmarxfill; 142 } pktpool_t; 143 144 pktpool_t *get_pktpools_registry(int id); 145 146 /* Incarnate a pktpool registry. On success returns total_pools. */ 147 extern int pktpool_attach(osl_t *osh, uint32 total_pools); 148 extern int pktpool_dettach(osl_t *osh); /* Relinquish registry */ 149 150 extern int pktpool_init(osl_t *osh, pktpool_t *pktp, int *n_pkts, 151 int max_pkt_bytes, bool istx, uint8 type); 152 extern int pktpool_deinit(osl_t *osh, pktpool_t *pktp); 153 extern int pktpool_fill(osl_t *osh, pktpool_t *pktp, bool minimal); 154 extern int pktpool_empty(osl_t *osh, pktpool_t *pktp); 155 extern uint16 pktpool_reclaim(osl_t *osh, pktpool_t *pktp, uint16 free_cnt); 156 extern void *pktpool_get(pktpool_t *pktp); 157 extern void pktpool_free(pktpool_t *pktp, void *p); 158 extern int pktpool_add(pktpool_t *pktp, void *p); 159 extern int pktpool_avail_notify_normal(osl_t *osh, pktpool_t *pktp); 160 extern int pktpool_avail_notify_exclusive(osl_t *osh, pktpool_t *pktp, 161 pktpool_cb_t cb); 162 extern int pktpool_avail_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg); 163 extern int pktpool_avail_deregister(pktpool_t *pktp, pktpool_cb_t cb, 164 void *arg); 165 extern int pktpool_empty_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg); 166 extern int pktpool_setmaxlen(pktpool_t *pktp, uint16 max_pkts); 167 extern int pktpool_setmaxlen_strict(osl_t *osh, pktpool_t *pktp, 168 uint16 max_pkts); 169 extern void pktpool_emptycb_disable(pktpool_t *pktp, bool disable); 170 extern bool pktpool_emptycb_disabled(pktpool_t *pktp); 171 extern int pktpool_hostaddr_fill_register(pktpool_t *pktp, pktpool_cb_extn_t cb, 172 void *arg1); 173 extern int pktpool_rxcplid_fill_register(pktpool_t *pktp, pktpool_cb_extn_t cb, 174 void *arg); 175 extern void pktpool_invoke_dmarxfill(pktpool_t *pktp); 176 extern int pkpool_haddr_avail_register_cb(pktpool_t *pktp, pktpool_cb_t cb, 177 void *arg); 178 179 #define POOLPTR(pp) ((pktpool_t *)(pp)) 180 #define POOLID(pp) (POOLPTR(pp)->id) 181 182 #define POOLSETID(pp, ppid) (POOLPTR(pp)->id = (ppid)) 183 184 #define pktpool_tot_pkts(pp) \ 185 (POOLPTR(pp)->n_pkts) /**< n_pkts = avail + in_use <= max_pkts */ 186 #define pktpool_avail(pp) (POOLPTR(pp)->avail) 187 #define pktpool_max_pkt_bytes(pp) (POOLPTR(pp)->max_pkt_bytes) 188 #define pktpool_max_pkts(pp) (POOLPTR(pp)->maxlen) 189 190 /* 191 * ---------------------------------------------------------------------------- 192 * A pool ID is assigned with a pkt pool during pool initialization. This is 193 * done by maintaining a registry of all initialized pools, and the registry 194 * index at which the pool is registered is used as the pool's unique ID. 195 * ID 0 is reserved and is used to signify an invalid pool ID. 196 * All packets henceforth allocated from a pool will be tagged with the pool's 197 * unique ID. Packets allocated from the heap will use the reserved ID = 0. 198 * Packets with non-zero pool id signify that they were allocated from a pool. 199 * A maximum of 15 pools are supported, allowing a 4bit pool ID to be used 200 * in place of a 32bit pool pointer in each packet. 201 * ---------------------------------------------------------------------------- 202 */ 203 #define PKTPOOL_INVALID_ID (0) 204 #define PKTPOOL_MAXIMUM_ID (15) 205 206 /* Registry of pktpool(s) */ 207 /* Pool ID to/from Pool Pointer converters */ 208 #define PKTPOOL_ID2PTR(id) (get_pktpools_registry(id)) 209 #define PKTPOOL_PTR2ID(pp) (POOLID(pp)) 210 211 #ifdef BCMDBG_POOL 212 extern int pktpool_dbg_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg); 213 extern int pktpool_start_trigger(pktpool_t *pktp, void *p); 214 extern int pktpool_dbg_dump(pktpool_t *pktp); 215 extern int pktpool_dbg_notify(pktpool_t *pktp); 216 extern int pktpool_stats_dump(pktpool_t *pktp, pktpool_stats_t *stats); 217 #endif /* BCMDBG_POOL */ 218 219 #ifdef BCMPKTPOOL 220 #define SHARED_POOL (pktpool_shared) 221 extern pktpool_t *pktpool_shared; 222 #ifdef BCMFRAGPOOL 223 #define SHARED_FRAG_POOL (pktpool_shared_lfrag) 224 extern pktpool_t *pktpool_shared_lfrag; 225 #endif // endif 226 227 #ifdef BCMRESVFRAGPOOL 228 #define RESV_FRAG_POOL (pktpool_resv_lfrag) 229 #define RESV_POOL_INFO (resv_pool_info) 230 #else 231 #define RESV_FRAG_POOL ((struct pktpool *)NULL) 232 #define RESV_POOL_INFO (NULL) 233 #endif /* BCMRESVFRAGPOOL */ 234 235 /** PCIe SPLITRX related */ 236 #define SHARED_RXFRAG_POOL (pktpool_shared_rxlfrag) 237 extern pktpool_t *pktpool_shared_rxlfrag; 238 239 int hnd_pktpool_init(osl_t *osh); 240 int hnd_pktpool_fill(pktpool_t *pktpool, bool minimal); 241 void hnd_pktpool_refill(bool minimal); 242 #ifdef BCMRESVFRAGPOOL 243 extern pktpool_t *pktpool_resv_lfrag; 244 extern struct resv_info *resv_pool_info; 245 #endif /* BCMRESVFRAGPOOL */ 246 #else /* BCMPKTPOOL */ 247 #define SHARED_POOL ((struct pktpool *)NULL) 248 #endif /* BCMPKTPOOL */ 249 250 #ifdef __cplusplus 251 } 252 #endif // endif 253 254 #endif /* _hnd_pktpool_h_ */ 255