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