xref: /dpdk/drivers/net/bnxt/tf_core/dpool.h (revision e6e8f03e5459f25153f1e4cd3e9ac30d3e473a61)
105b405d5SPeter Spreadborough /* SPDX-License-Identifier: BSD-3-Clause
2*e6e8f03eSRandy Schacher  * Copyright(c) 2019-2023 Broadcom
305b405d5SPeter Spreadborough  * All rights reserved.
405b405d5SPeter Spreadborough  */
505b405d5SPeter Spreadborough 
605b405d5SPeter Spreadborough #ifndef _DPOOL_H_
705b405d5SPeter Spreadborough #define _DPOOL_H_
805b405d5SPeter Spreadborough 
905b405d5SPeter Spreadborough #include <stdint.h>
1005b405d5SPeter Spreadborough #include <stdlib.h>
1105b405d5SPeter Spreadborough 
1205b405d5SPeter Spreadborough #define DP_MAX_FREE_SIZE 0x8000 /* 32K */
1305b405d5SPeter Spreadborough 
1405b405d5SPeter Spreadborough #define DP_INVALID_INDEX 0xffffffff
1505b405d5SPeter Spreadborough 
1605b405d5SPeter Spreadborough #define DP_FLAGS_START   0x80000000
1705b405d5SPeter Spreadborough #define DP_IS_START(flags) ((flags) & DP_FLAGS_START)
1805b405d5SPeter Spreadborough 
1905b405d5SPeter Spreadborough #define DP_FLAGS_SIZE_SHIFT 0
2005b405d5SPeter Spreadborough #define DP_FLAGS_SIZE_MASK  0x07
2105b405d5SPeter Spreadborough 
2205b405d5SPeter Spreadborough #define DP_FLAGS_SIZE(flags) (((flags) >> DP_FLAGS_SIZE_SHIFT) & DP_FLAGS_SIZE_MASK)
2305b405d5SPeter Spreadborough 
2405b405d5SPeter Spreadborough #define DP_IS_FREE(flags) (((flags) & DP_FLAGS_SIZE_MASK) == 0)
2505b405d5SPeter Spreadborough #define DP_IS_USED(flags) ((flags) & DP_FLAGS_SIZE_MASK)
2605b405d5SPeter Spreadborough 
2705b405d5SPeter Spreadborough #define DP_DEFRAG_NONE   0x0
2805b405d5SPeter Spreadborough #define DP_DEFRAG_ALL    0x1
2905b405d5SPeter Spreadborough #define DP_DEFRAG_TO_FIT 0x2
3005b405d5SPeter Spreadborough 
3105b405d5SPeter Spreadborough /**
3205b405d5SPeter Spreadborough  * Free list entry
3305b405d5SPeter Spreadborough  *
3405b405d5SPeter Spreadborough  * Each entry includes an index in to the dpool entry array
3505b405d5SPeter Spreadborough  * and the size of dpool array entry.
3605b405d5SPeter Spreadborough  */
3705b405d5SPeter Spreadborough struct dpool_free_list_entry {
3805b405d5SPeter Spreadborough 	/*
3905b405d5SPeter Spreadborough 	 * Index in to dpool entry array
4005b405d5SPeter Spreadborough 	 */
4105b405d5SPeter Spreadborough 	uint32_t index;
4205b405d5SPeter Spreadborough 	/*
4305b405d5SPeter Spreadborough 	 * The size of the entry in the dpool entry array
4405b405d5SPeter Spreadborough 	 */
4505b405d5SPeter Spreadborough 	uint32_t size;
4605b405d5SPeter Spreadborough };
4705b405d5SPeter Spreadborough 
4805b405d5SPeter Spreadborough /**
4905b405d5SPeter Spreadborough  * Free list
5005b405d5SPeter Spreadborough  *
5105b405d5SPeter Spreadborough  * Used internally to record free entries in the dpool entry array.
5205b405d5SPeter Spreadborough  * Each entry represents a single or multiple contiguous entries
5305b405d5SPeter Spreadborough  * in the dpool entry array.
5405b405d5SPeter Spreadborough  *
5505b405d5SPeter Spreadborough  * Used only during the defrag operation.
5605b405d5SPeter Spreadborough  */
5705b405d5SPeter Spreadborough struct dpool_free_list {
5805b405d5SPeter Spreadborough 	/*
5905b405d5SPeter Spreadborough 	 * Number of entries in the free list
6005b405d5SPeter Spreadborough 	 */
6105b405d5SPeter Spreadborough 	uint32_t size;
6205b405d5SPeter Spreadborough 	/*
6305b405d5SPeter Spreadborough 	 * List of unused entries in the dpool entry array
6405b405d5SPeter Spreadborough 	 */
6505b405d5SPeter Spreadborough 	struct dpool_free_list_entry entry[DP_MAX_FREE_SIZE];
6605b405d5SPeter Spreadborough };
6705b405d5SPeter Spreadborough 
6805b405d5SPeter Spreadborough /**
6905b405d5SPeter Spreadborough  * Adjacent list entry
7005b405d5SPeter Spreadborough  *
7105b405d5SPeter Spreadborough  * Each entry includes and index in to the dpool entry array,
7205b405d5SPeter Spreadborough  * the size of the entry and the counts of free entries to the
7305b405d5SPeter Spreadborough  * right and left off that entry.
7405b405d5SPeter Spreadborough  */
7505b405d5SPeter Spreadborough struct dpool_adj_list_entry {
7605b405d5SPeter Spreadborough 	/*
7705b405d5SPeter Spreadborough 	 * Index in to dpool entry array
7805b405d5SPeter Spreadborough 	 */
7905b405d5SPeter Spreadborough 	uint32_t index;
8005b405d5SPeter Spreadborough 	/*
8105b405d5SPeter Spreadborough 	 * The size of the entry in the dpool entry array
8205b405d5SPeter Spreadborough 	 */
8305b405d5SPeter Spreadborough 	uint32_t size;
8405b405d5SPeter Spreadborough 	/*
8505b405d5SPeter Spreadborough 	 * Number of free entries directly to the  left of
8605b405d5SPeter Spreadborough 	 * this entry
8705b405d5SPeter Spreadborough 	 */
8805b405d5SPeter Spreadborough 	uint32_t left;
8905b405d5SPeter Spreadborough 	/*
9005b405d5SPeter Spreadborough 	 * Number of free entries directly to the right of
9105b405d5SPeter Spreadborough 	 * this entry
9205b405d5SPeter Spreadborough 	 */
9305b405d5SPeter Spreadborough 	uint32_t right;
9405b405d5SPeter Spreadborough };
9505b405d5SPeter Spreadborough 
9605b405d5SPeter Spreadborough /**
9705b405d5SPeter Spreadborough  * Adjacent list
9805b405d5SPeter Spreadborough  *
9905b405d5SPeter Spreadborough  * A list of references to entries in the dpool entry array that
10005b405d5SPeter Spreadborough  * have free entries to the left and right. Since we pack to the
1011993b267SShahaji Bhosle  * left entries will always have a non zero left out.
10205b405d5SPeter Spreadborough  *
10305b405d5SPeter Spreadborough  * Used only during the defrag operation.
10405b405d5SPeter Spreadborough  */
10505b405d5SPeter Spreadborough struct dpool_adj_list {
10605b405d5SPeter Spreadborough 	/*
10705b405d5SPeter Spreadborough 	 * Number of entries in the adj list
10805b405d5SPeter Spreadborough 	 */
10905b405d5SPeter Spreadborough 	uint32_t size;
11005b405d5SPeter Spreadborough 	/*
11105b405d5SPeter Spreadborough 	 * List of entries in the dpool entry array that have
11205b405d5SPeter Spreadborough 	 * free entries directly to their left and right.
11305b405d5SPeter Spreadborough 	 */
11405b405d5SPeter Spreadborough 	struct dpool_adj_list_entry entry[DP_MAX_FREE_SIZE];
11505b405d5SPeter Spreadborough };
11605b405d5SPeter Spreadborough 
11705b405d5SPeter Spreadborough /**
11805b405d5SPeter Spreadborough  * Dpool entry
11905b405d5SPeter Spreadborough  *
12005b405d5SPeter Spreadborough  * Each entry includes flags and the FW index.
12105b405d5SPeter Spreadborough  */
12205b405d5SPeter Spreadborough struct dpool_entry {
12305b405d5SPeter Spreadborough 	uint32_t flags;
12405b405d5SPeter Spreadborough 	uint32_t index;
12505b405d5SPeter Spreadborough 	uint64_t entry_data;
12605b405d5SPeter Spreadborough };
12705b405d5SPeter Spreadborough 
12805b405d5SPeter Spreadborough /**
12905b405d5SPeter Spreadborough  * Dpool
13005b405d5SPeter Spreadborough  *
13105b405d5SPeter Spreadborough  * Used to manage resource pool. Includes the start FW index, the
13205b405d5SPeter Spreadborough  * size of the entry array and the entry array it's self.
13305b405d5SPeter Spreadborough  */
13405b405d5SPeter Spreadborough struct dpool {
13505b405d5SPeter Spreadborough 	uint32_t start_index;
13605b405d5SPeter Spreadborough 	uint32_t size;
13705b405d5SPeter Spreadborough 	uint8_t  max_alloc_size;
13805b405d5SPeter Spreadborough 	void *user_data;
13905b405d5SPeter Spreadborough 	int (*move_callback)(void *user_data,
14005b405d5SPeter Spreadborough 			     uint64_t entry_data,
14105b405d5SPeter Spreadborough 			     uint32_t new_index);
14205b405d5SPeter Spreadborough 	struct dpool_entry *entry;
14305b405d5SPeter Spreadborough };
14405b405d5SPeter Spreadborough 
14505b405d5SPeter Spreadborough /**
14605b405d5SPeter Spreadborough  * dpool_init
14705b405d5SPeter Spreadborough  *
14805b405d5SPeter Spreadborough  * Initialize the dpool
14905b405d5SPeter Spreadborough  *
15005b405d5SPeter Spreadborough  * [in] dpool
15105b405d5SPeter Spreadborough  *      Pointer to a dpool structure that includes an entry field
15205b405d5SPeter Spreadborough  *      that points to the entry array. The user is responsible for
15305b405d5SPeter Spreadborough  *      allocating memory for the dpool struct and the entry array.
15405b405d5SPeter Spreadborough  *
15505b405d5SPeter Spreadborough  * [in] start_index
15605b405d5SPeter Spreadborough  *      The base index to use.
15705b405d5SPeter Spreadborough  *
15805b405d5SPeter Spreadborough  * [in] size
15905b405d5SPeter Spreadborough  *      The number of entries
16005b405d5SPeter Spreadborough  *
16105b405d5SPeter Spreadborough  * [in] max_alloc_size
16205b405d5SPeter Spreadborough  *      The number of entries
16305b405d5SPeter Spreadborough  *
16405b405d5SPeter Spreadborough  * [in] user_data
16505b405d5SPeter Spreadborough  *      Pointer to user data. Will be passed in callbacks.
16605b405d5SPeter Spreadborough  *
16705b405d5SPeter Spreadborough  * [in] move_callback
16805b405d5SPeter Spreadborough  *      Pointer to move EM entry callback.
16905b405d5SPeter Spreadborough  *
17005b405d5SPeter Spreadborough  * Return
17105b405d5SPeter Spreadborough  *      -  0 on success
17205b405d5SPeter Spreadborough  *      - -1 on failure
17305b405d5SPeter Spreadborough  *
17405b405d5SPeter Spreadborough  */
17505b405d5SPeter Spreadborough int dpool_init(struct dpool *dpool,
17605b405d5SPeter Spreadborough 	       uint32_t start_index,
17705b405d5SPeter Spreadborough 	       uint32_t size,
17805b405d5SPeter Spreadborough 	       uint8_t max_alloc_size,
17905b405d5SPeter Spreadborough 	       void *user_data,
18005b405d5SPeter Spreadborough 	       int (*move_callback)(void *, uint64_t, uint32_t));
18105b405d5SPeter Spreadborough 
18205b405d5SPeter Spreadborough /**
18305b405d5SPeter Spreadborough  * dpool_alloc
18405b405d5SPeter Spreadborough  *
18505b405d5SPeter Spreadborough  * Request a FW index of size and if necessary de-fragment the dpool
18605b405d5SPeter Spreadborough  * array.
18705b405d5SPeter Spreadborough  *
18805b405d5SPeter Spreadborough  * [i] dpool
18905b405d5SPeter Spreadborough  *     The dpool
19005b405d5SPeter Spreadborough  *
19105b405d5SPeter Spreadborough  * [i] size
19205b405d5SPeter Spreadborough  *     The size of the requested allocation.
19305b405d5SPeter Spreadborough  *
19405b405d5SPeter Spreadborough  * [i] defrag
19505b405d5SPeter Spreadborough  *     Operation to apply when there is insufficient space:
19605b405d5SPeter Spreadborough  *
19705b405d5SPeter Spreadborough  *     DP_DEFRAG_NONE   (0x0) - Don't do anything.
19805b405d5SPeter Spreadborough  *     DP_DEFRAG_ALL    (0x1) - Defrag until there is nothing left
19905b405d5SPeter Spreadborough  *                              to defrag.
20005b405d5SPeter Spreadborough  *     DP_DEFRAG_TO_FIT (0x2) - Defrag until there is just enough space
20105b405d5SPeter Spreadborough  *                              to insert the requested allocation.
20205b405d5SPeter Spreadborough  *
20305b405d5SPeter Spreadborough  * Return
20405b405d5SPeter Spreadborough  *      - FW index on success
20505b405d5SPeter Spreadborough  *      - DP_INVALID_INDEX on failure
20605b405d5SPeter Spreadborough  *
20705b405d5SPeter Spreadborough  */
20805b405d5SPeter Spreadborough uint32_t dpool_alloc(struct dpool *dpool,
20905b405d5SPeter Spreadborough 		     uint32_t size,
21005b405d5SPeter Spreadborough 		     uint8_t defrag);
21105b405d5SPeter Spreadborough 
21205b405d5SPeter Spreadborough /**
21305b405d5SPeter Spreadborough  * dpool_set_entry_data
21405b405d5SPeter Spreadborough  *
21505b405d5SPeter Spreadborough  * Set the entry data field. This will be passed to callbacks.
21605b405d5SPeter Spreadborough  *
21705b405d5SPeter Spreadborough  * [i] dpool
21805b405d5SPeter Spreadborough  *     The dpool
21905b405d5SPeter Spreadborough  *
22005b405d5SPeter Spreadborough  * [i] index
22105b405d5SPeter Spreadborough  *     FW index
22205b405d5SPeter Spreadborough  *
22305b405d5SPeter Spreadborough  * [i] entry_data
22405b405d5SPeter Spreadborough  *     Entry data value
22505b405d5SPeter Spreadborough  *
22605b405d5SPeter Spreadborough  * Return
22705b405d5SPeter Spreadborough  *      - FW index on success
22805b405d5SPeter Spreadborough  *      - DP_INVALID_INDEX on failure
22905b405d5SPeter Spreadborough  *
23005b405d5SPeter Spreadborough  */
23105b405d5SPeter Spreadborough int dpool_set_entry_data(struct dpool *dpool,
23205b405d5SPeter Spreadborough 			 uint32_t index,
23305b405d5SPeter Spreadborough 			 uint64_t entry_data);
23405b405d5SPeter Spreadborough 
23505b405d5SPeter Spreadborough /**
23605b405d5SPeter Spreadborough  * dpool_free
23705b405d5SPeter Spreadborough  *
23805b405d5SPeter Spreadborough  * Free allocated entry. The is responsible for the dpool and dpool
23905b405d5SPeter Spreadborough  * entry array memory.
24005b405d5SPeter Spreadborough  *
24105b405d5SPeter Spreadborough  * [in] dpool
24205b405d5SPeter Spreadborough  *      The pool
24305b405d5SPeter Spreadborough  *
24405b405d5SPeter Spreadborough  * [in] index
24505b405d5SPeter Spreadborough  *      FW index to free up.
24605b405d5SPeter Spreadborough  *
24705b405d5SPeter Spreadborough  * Result
24805b405d5SPeter Spreadborough  *      - 0  on success
24905b405d5SPeter Spreadborough  *      - -1 on failure
25005b405d5SPeter Spreadborough  *
25105b405d5SPeter Spreadborough  */
25205b405d5SPeter Spreadborough int dpool_free(struct dpool *dpool,
25305b405d5SPeter Spreadborough 	       uint32_t index);
25405b405d5SPeter Spreadborough 
25505b405d5SPeter Spreadborough /**
25605b405d5SPeter Spreadborough  * dpool_free_all
25705b405d5SPeter Spreadborough  *
25805b405d5SPeter Spreadborough  * Free all entries.
25905b405d5SPeter Spreadborough  *
26005b405d5SPeter Spreadborough  * [in] dpool
26105b405d5SPeter Spreadborough  *      The pool
26205b405d5SPeter Spreadborough  *
26305b405d5SPeter Spreadborough  * Result
26405b405d5SPeter Spreadborough  *      - 0  on success
26505b405d5SPeter Spreadborough  *      - -1 on failure
26605b405d5SPeter Spreadborough  *
26705b405d5SPeter Spreadborough  */
26805b405d5SPeter Spreadborough void dpool_free_all(struct dpool *dpool);
26905b405d5SPeter Spreadborough 
27005b405d5SPeter Spreadborough /**
27105b405d5SPeter Spreadborough  * dpool_dump
27205b405d5SPeter Spreadborough  *
27305b405d5SPeter Spreadborough  * Debug/util function to dump the dpool array.
27405b405d5SPeter Spreadborough  *
27505b405d5SPeter Spreadborough  * [in] dpool
27605b405d5SPeter Spreadborough  *      The pool
27705b405d5SPeter Spreadborough  *
27805b405d5SPeter Spreadborough  */
27905b405d5SPeter Spreadborough void dpool_dump(struct dpool *dpool);
28005b405d5SPeter Spreadborough 
28105b405d5SPeter Spreadborough /**
28205b405d5SPeter Spreadborough  * dpool_defrag
28305b405d5SPeter Spreadborough  *
2841993b267SShahaji Bhosle  * De-fragment the dpool array and apply the specified defrag strategy.
28505b405d5SPeter Spreadborough  *
28605b405d5SPeter Spreadborough  * [in] dpool
28705b405d5SPeter Spreadborough  *      The dpool
28805b405d5SPeter Spreadborough  *
28905b405d5SPeter Spreadborough  * [in] entry_size
2901993b267SShahaji Bhosle  *      If using the DP_DEFRAG_TO_FIT strategy defrag will stop when there's
29105b405d5SPeter Spreadborough  *      at least entry_size space available.
29205b405d5SPeter Spreadborough  *
29305b405d5SPeter Spreadborough  * [i] defrag
2941993b267SShahaji Bhosle  *     Defrag strategy:
29505b405d5SPeter Spreadborough  *
29605b405d5SPeter Spreadborough  *     DP_DEFRAG_ALL    (0x1) - Defrag until there is nothing left
29705b405d5SPeter Spreadborough  *                              to defrag.
29805b405d5SPeter Spreadborough  *     DP_DEFRAG_TO_FIT (0x2) - Defrag until there is just enough space
29905b405d5SPeter Spreadborough  *                              to insert the requested allocation.
30005b405d5SPeter Spreadborough  *
30105b405d5SPeter Spreadborough  * Return
30205b405d5SPeter Spreadborough  *      < 0 - on failure
30305b405d5SPeter Spreadborough  *      > 0 - The size of the largest free space
30405b405d5SPeter Spreadborough  */
30505b405d5SPeter Spreadborough int dpool_defrag(struct dpool *dpool,
30605b405d5SPeter Spreadborough 		 uint32_t entry_size,
30705b405d5SPeter Spreadborough 		 uint8_t defrag);
30805b405d5SPeter Spreadborough #endif /* _DPOOL_H_ */
309