1 /* 2 * HND generic packet pool operation primitives 3 * 4 * Copyright (C) 1999-2017, Broadcom Corporation 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 * 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 613891 2016-01-20 10:05:44Z $ 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 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 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 59 /* forward declaration */ 60 struct pktpool; 61 62 typedef void (*pktpool_cb_t)(struct pktpool *pool, void *arg); 63 typedef struct { 64 pktpool_cb_t cb; 65 void *arg; 66 } pktpool_cbinfo_t; 67 68 /** PCIe SPLITRX related: call back fn extension to populate host address in pool pkt */ 69 typedef int (*pktpool_cb_extn_t)(struct pktpool *pool, void *arg1, void* pkt, bool arg2); 70 typedef struct { 71 pktpool_cb_extn_t cb; 72 void *arg; 73 } pktpool_cbextn_info_t; 74 75 76 #ifdef BCMDBG_POOL 77 /* pkt pool debug states */ 78 #define POOL_IDLE 0 79 #define POOL_RXFILL 1 80 #define POOL_RXDH 2 81 #define POOL_RXD11 3 82 #define POOL_TXDH 4 83 #define POOL_TXD11 5 84 #define POOL_AMPDU 6 85 #define POOL_TXENQ 7 86 87 typedef struct { 88 void *p; 89 uint32 cycles; 90 uint32 dur; 91 } pktpool_dbg_t; 92 93 typedef struct { 94 uint8 txdh; /* tx to host */ 95 uint8 txd11; /* tx to d11 */ 96 uint8 enq; /* waiting in q */ 97 uint8 rxdh; /* rx from host */ 98 uint8 rxd11; /* rx from d11 */ 99 uint8 rxfill; /* dma_rxfill */ 100 uint8 idle; /* avail in pool */ 101 } pktpool_stats_t; 102 #endif /* BCMDBG_POOL */ 103 104 typedef struct pktpool { 105 bool inited; /**< pktpool_init was successful */ 106 uint8 type; /**< type of lbuf: basic, frag, etc */ 107 uint8 id; /**< pktpool ID: index in registry */ 108 bool istx; /**< direction: transmit or receive data path */ 109 HND_PKTPOOL_MUTEX_DECL(mutex) /**< thread-safe mutex */ 110 111 void *freelist; /**< free list: see PKTNEXTFREE(), PKTSETNEXTFREE() */ 112 uint16 avail; /**< number of packets in pool's free list */ 113 uint16 len; /**< number of packets managed by pool */ 114 uint16 maxlen; /**< maximum size of pool <= PKTPOOL_LEN_MAX */ 115 uint16 plen; /**< size of pkt buffer in [bytes], excluding lbuf|lbuf_frag */ 116 117 bool empty; 118 uint8 cbtoggle; 119 uint8 cbcnt; 120 uint8 ecbcnt; 121 uint8 emptycb_disable; /**< Value of type enum pktpool_empty_cb_state */ 122 pktpool_cbinfo_t *availcb_excl; 123 pktpool_cbinfo_t cbs[PKTPOOL_CB_MAX_AVL]; 124 pktpool_cbinfo_t ecbs[PKTPOOL_CB_MAX]; 125 pktpool_cbextn_info_t cbext; /**< PCIe SPLITRX related */ 126 pktpool_cbextn_info_t rxcplidfn; 127 #ifdef BCMDBG_POOL 128 uint8 dbg_cbcnt; 129 pktpool_cbinfo_t dbg_cbs[PKTPOOL_CB_MAX]; 130 uint16 dbg_qlen; 131 pktpool_dbg_t dbg_q[PKTPOOL_LEN_MAX + 1]; 132 #endif 133 pktpool_cbinfo_t dmarxfill; 134 } pktpool_t; 135 136 137 pktpool_t *get_pktpools_registry(int id); 138 139 /* Incarnate a pktpool registry. On success returns total_pools. */ 140 extern int pktpool_attach(osl_t *osh, uint32 total_pools); 141 extern int pktpool_dettach(osl_t *osh); /* Relinquish registry */ 142 143 extern int pktpool_init(osl_t *osh, pktpool_t *pktp, int *pktplen, int plen, bool istx, uint8 type); 144 extern int pktpool_deinit(osl_t *osh, pktpool_t *pktp); 145 extern int pktpool_fill(osl_t *osh, pktpool_t *pktp, bool minimal); 146 extern void* pktpool_get(pktpool_t *pktp); 147 extern void pktpool_free(pktpool_t *pktp, void *p); 148 extern int pktpool_add(pktpool_t *pktp, void *p); 149 extern int pktpool_avail_notify_normal(osl_t *osh, pktpool_t *pktp); 150 extern int pktpool_avail_notify_exclusive(osl_t *osh, pktpool_t *pktp, pktpool_cb_t cb); 151 extern int pktpool_avail_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg); 152 extern int pktpool_empty_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg); 153 extern int pktpool_setmaxlen(pktpool_t *pktp, uint16 maxlen); 154 extern int pktpool_setmaxlen_strict(osl_t *osh, pktpool_t *pktp, uint16 maxlen); 155 extern void pktpool_emptycb_disable(pktpool_t *pktp, bool disable); 156 extern bool pktpool_emptycb_disabled(pktpool_t *pktp); 157 extern int pktpool_hostaddr_fill_register(pktpool_t *pktp, pktpool_cb_extn_t cb, void *arg1); 158 extern int pktpool_rxcplid_fill_register(pktpool_t *pktp, pktpool_cb_extn_t cb, void *arg); 159 extern void pktpool_invoke_dmarxfill(pktpool_t *pktp); 160 extern int pkpool_haddr_avail_register_cb(pktpool_t *pktp, pktpool_cb_t cb, void *arg); 161 162 #define POOLPTR(pp) ((pktpool_t *)(pp)) 163 #define POOLID(pp) (POOLPTR(pp)->id) 164 165 #define POOLSETID(pp, ppid) (POOLPTR(pp)->id = (ppid)) 166 167 #define pktpool_len(pp) (POOLPTR(pp)->len) /**< returns packet length in [bytes] */ 168 #define pktpool_avail(pp) (POOLPTR(pp)->avail) 169 #define pktpool_plen(pp) (POOLPTR(pp)->plen) 170 #define pktpool_maxlen(pp) (POOLPTR(pp)->maxlen) 171 172 173 /* 174 * ---------------------------------------------------------------------------- 175 * A pool ID is assigned with a pkt pool during pool initialization. This is 176 * done by maintaining a registry of all initialized pools, and the registry 177 * index at which the pool is registered is used as the pool's unique ID. 178 * ID 0 is reserved and is used to signify an invalid pool ID. 179 * All packets henceforth allocated from a pool will be tagged with the pool's 180 * unique ID. Packets allocated from the heap will use the reserved ID = 0. 181 * Packets with non-zero pool id signify that they were allocated from a pool. 182 * A maximum of 15 pools are supported, allowing a 4bit pool ID to be used 183 * in place of a 32bit pool pointer in each packet. 184 * ---------------------------------------------------------------------------- 185 */ 186 #define PKTPOOL_INVALID_ID (0) 187 #define PKTPOOL_MAXIMUM_ID (15) 188 189 /* Registry of pktpool(s) */ 190 /* Pool ID to/from Pool Pointer converters */ 191 #define PKTPOOL_ID2PTR(id) (get_pktpools_registry(id)) 192 #define PKTPOOL_PTR2ID(pp) (POOLID(pp)) 193 194 #ifdef BCMDBG_POOL 195 extern int pktpool_dbg_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg); 196 extern int pktpool_start_trigger(pktpool_t *pktp, void *p); 197 extern int pktpool_dbg_dump(pktpool_t *pktp); 198 extern int pktpool_dbg_notify(pktpool_t *pktp); 199 extern int pktpool_stats_dump(pktpool_t *pktp, pktpool_stats_t *stats); 200 #endif /* BCMDBG_POOL */ 201 202 #ifdef BCMPKTPOOL 203 #define SHARED_POOL (pktpool_shared) 204 extern pktpool_t *pktpool_shared; 205 #ifdef BCMFRAGPOOL 206 #define SHARED_FRAG_POOL (pktpool_shared_lfrag) 207 extern pktpool_t *pktpool_shared_lfrag; 208 #endif 209 210 /** PCIe SPLITRX related */ 211 #define SHARED_RXFRAG_POOL (pktpool_shared_rxlfrag) 212 extern pktpool_t *pktpool_shared_rxlfrag; 213 214 int hnd_pktpool_init(osl_t *osh); 215 int hnd_pktpool_fill(pktpool_t *pktpool, bool minimal); 216 void hnd_pktpool_refill(bool minimal); 217 #else /* BCMPKTPOOL */ 218 #define SHARED_POOL ((struct pktpool *)NULL) 219 #endif /* BCMPKTPOOL */ 220 221 #ifdef __cplusplus 222 } 223 #endif 224 225 #endif /* _hnd_pktpool_h_ */ 226