hc
2023-11-06 e3e12f52b214121840b44c91de5b3e5af5d3eb84
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
/*
 * HND generic packet pool operation primitives
 *
 * Copyright (C) 2020, 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)        0
#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
 
/* 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;
 
/** 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 */
   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;
#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;
 
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_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 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))
 
#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;
 
#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;
#endif
 
#ifdef BCMALFRAGPOOL
#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
 
#ifdef BCMRESVFRAGPOOL
#define RESV_FRAG_POOL        (pktpool_resv_lfrag)
#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_lfrag;
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_ */