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