xref: /dpdk/drivers/net/bnxt/tf_core/dpool.h (revision e6e8f03e5459f25153f1e4cd3e9ac30d3e473a61)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019-2023 Broadcom
3  * All rights reserved.
4  */
5 
6 #ifndef _DPOOL_H_
7 #define _DPOOL_H_
8 
9 #include <stdint.h>
10 #include <stdlib.h>
11 
12 #define DP_MAX_FREE_SIZE 0x8000 /* 32K */
13 
14 #define DP_INVALID_INDEX 0xffffffff
15 
16 #define DP_FLAGS_START   0x80000000
17 #define DP_IS_START(flags) ((flags) & DP_FLAGS_START)
18 
19 #define DP_FLAGS_SIZE_SHIFT 0
20 #define DP_FLAGS_SIZE_MASK  0x07
21 
22 #define DP_FLAGS_SIZE(flags) (((flags) >> DP_FLAGS_SIZE_SHIFT) & DP_FLAGS_SIZE_MASK)
23 
24 #define DP_IS_FREE(flags) (((flags) & DP_FLAGS_SIZE_MASK) == 0)
25 #define DP_IS_USED(flags) ((flags) & DP_FLAGS_SIZE_MASK)
26 
27 #define DP_DEFRAG_NONE   0x0
28 #define DP_DEFRAG_ALL    0x1
29 #define DP_DEFRAG_TO_FIT 0x2
30 
31 /**
32  * Free list entry
33  *
34  * Each entry includes an index in to the dpool entry array
35  * and the size of dpool array entry.
36  */
37 struct dpool_free_list_entry {
38 	/*
39 	 * Index in to dpool entry array
40 	 */
41 	uint32_t index;
42 	/*
43 	 * The size of the entry in the dpool entry array
44 	 */
45 	uint32_t size;
46 };
47 
48 /**
49  * Free list
50  *
51  * Used internally to record free entries in the dpool entry array.
52  * Each entry represents a single or multiple contiguous entries
53  * in the dpool entry array.
54  *
55  * Used only during the defrag operation.
56  */
57 struct dpool_free_list {
58 	/*
59 	 * Number of entries in the free list
60 	 */
61 	uint32_t size;
62 	/*
63 	 * List of unused entries in the dpool entry array
64 	 */
65 	struct dpool_free_list_entry entry[DP_MAX_FREE_SIZE];
66 };
67 
68 /**
69  * Adjacent list entry
70  *
71  * Each entry includes and index in to the dpool entry array,
72  * the size of the entry and the counts of free entries to the
73  * right and left off that entry.
74  */
75 struct dpool_adj_list_entry {
76 	/*
77 	 * Index in to dpool entry array
78 	 */
79 	uint32_t index;
80 	/*
81 	 * The size of the entry in the dpool entry array
82 	 */
83 	uint32_t size;
84 	/*
85 	 * Number of free entries directly to the  left of
86 	 * this entry
87 	 */
88 	uint32_t left;
89 	/*
90 	 * Number of free entries directly to the right of
91 	 * this entry
92 	 */
93 	uint32_t right;
94 };
95 
96 /**
97  * Adjacent list
98  *
99  * A list of references to entries in the dpool entry array that
100  * have free entries to the left and right. Since we pack to the
101  * left entries will always have a non zero left out.
102  *
103  * Used only during the defrag operation.
104  */
105 struct dpool_adj_list {
106 	/*
107 	 * Number of entries in the adj list
108 	 */
109 	uint32_t size;
110 	/*
111 	 * List of entries in the dpool entry array that have
112 	 * free entries directly to their left and right.
113 	 */
114 	struct dpool_adj_list_entry entry[DP_MAX_FREE_SIZE];
115 };
116 
117 /**
118  * Dpool entry
119  *
120  * Each entry includes flags and the FW index.
121  */
122 struct dpool_entry {
123 	uint32_t flags;
124 	uint32_t index;
125 	uint64_t entry_data;
126 };
127 
128 /**
129  * Dpool
130  *
131  * Used to manage resource pool. Includes the start FW index, the
132  * size of the entry array and the entry array it's self.
133  */
134 struct dpool {
135 	uint32_t start_index;
136 	uint32_t size;
137 	uint8_t  max_alloc_size;
138 	void *user_data;
139 	int (*move_callback)(void *user_data,
140 			     uint64_t entry_data,
141 			     uint32_t new_index);
142 	struct dpool_entry *entry;
143 };
144 
145 /**
146  * dpool_init
147  *
148  * Initialize the dpool
149  *
150  * [in] dpool
151  *      Pointer to a dpool structure that includes an entry field
152  *      that points to the entry array. The user is responsible for
153  *      allocating memory for the dpool struct and the entry array.
154  *
155  * [in] start_index
156  *      The base index to use.
157  *
158  * [in] size
159  *      The number of entries
160  *
161  * [in] max_alloc_size
162  *      The number of entries
163  *
164  * [in] user_data
165  *      Pointer to user data. Will be passed in callbacks.
166  *
167  * [in] move_callback
168  *      Pointer to move EM entry callback.
169  *
170  * Return
171  *      -  0 on success
172  *      - -1 on failure
173  *
174  */
175 int dpool_init(struct dpool *dpool,
176 	       uint32_t start_index,
177 	       uint32_t size,
178 	       uint8_t max_alloc_size,
179 	       void *user_data,
180 	       int (*move_callback)(void *, uint64_t, uint32_t));
181 
182 /**
183  * dpool_alloc
184  *
185  * Request a FW index of size and if necessary de-fragment the dpool
186  * array.
187  *
188  * [i] dpool
189  *     The dpool
190  *
191  * [i] size
192  *     The size of the requested allocation.
193  *
194  * [i] defrag
195  *     Operation to apply when there is insufficient space:
196  *
197  *     DP_DEFRAG_NONE   (0x0) - Don't do anything.
198  *     DP_DEFRAG_ALL    (0x1) - Defrag until there is nothing left
199  *                              to defrag.
200  *     DP_DEFRAG_TO_FIT (0x2) - Defrag until there is just enough space
201  *                              to insert the requested allocation.
202  *
203  * Return
204  *      - FW index on success
205  *      - DP_INVALID_INDEX on failure
206  *
207  */
208 uint32_t dpool_alloc(struct dpool *dpool,
209 		     uint32_t size,
210 		     uint8_t defrag);
211 
212 /**
213  * dpool_set_entry_data
214  *
215  * Set the entry data field. This will be passed to callbacks.
216  *
217  * [i] dpool
218  *     The dpool
219  *
220  * [i] index
221  *     FW index
222  *
223  * [i] entry_data
224  *     Entry data value
225  *
226  * Return
227  *      - FW index on success
228  *      - DP_INVALID_INDEX on failure
229  *
230  */
231 int dpool_set_entry_data(struct dpool *dpool,
232 			 uint32_t index,
233 			 uint64_t entry_data);
234 
235 /**
236  * dpool_free
237  *
238  * Free allocated entry. The is responsible for the dpool and dpool
239  * entry array memory.
240  *
241  * [in] dpool
242  *      The pool
243  *
244  * [in] index
245  *      FW index to free up.
246  *
247  * Result
248  *      - 0  on success
249  *      - -1 on failure
250  *
251  */
252 int dpool_free(struct dpool *dpool,
253 	       uint32_t index);
254 
255 /**
256  * dpool_free_all
257  *
258  * Free all entries.
259  *
260  * [in] dpool
261  *      The pool
262  *
263  * Result
264  *      - 0  on success
265  *      - -1 on failure
266  *
267  */
268 void dpool_free_all(struct dpool *dpool);
269 
270 /**
271  * dpool_dump
272  *
273  * Debug/util function to dump the dpool array.
274  *
275  * [in] dpool
276  *      The pool
277  *
278  */
279 void dpool_dump(struct dpool *dpool);
280 
281 /**
282  * dpool_defrag
283  *
284  * De-fragment the dpool array and apply the specified defrag strategy.
285  *
286  * [in] dpool
287  *      The dpool
288  *
289  * [in] entry_size
290  *      If using the DP_DEFRAG_TO_FIT strategy defrag will stop when there's
291  *      at least entry_size space available.
292  *
293  * [i] defrag
294  *     Defrag strategy:
295  *
296  *     DP_DEFRAG_ALL    (0x1) - Defrag until there is nothing left
297  *                              to defrag.
298  *     DP_DEFRAG_TO_FIT (0x2) - Defrag until there is just enough space
299  *                              to insert the requested allocation.
300  *
301  * Return
302  *      < 0 - on failure
303  *      > 0 - The size of the largest free space
304  */
305 int dpool_defrag(struct dpool *dpool,
306 		 uint32_t entry_size,
307 		 uint8_t defrag);
308 #endif /* _DPOOL_H_ */
309