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