net/bnxt: add dpool allocator for EM allocation
[dpdk.git] / drivers / net / bnxt / tf_core / dpool.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019-2021 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 cout.
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 stratagy.
285  *
286  * [in] dpool
287  *      The dpool
288  *
289  * [in] entry_size
290  *      If using the DP_DEFRAG_TO_FIT stratagy defrag will stop when there's
291  *      at least entry_size space available.
292  *
293  * [i] defrag
294  *     Defrag stratagy:
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
309 #endif /* _DPOOL_H_ */