1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* Microchip Sparx5 Switch driver |
3 | * |
4 | * Copyright (c) 2023 Microchip Technology Inc. and its subsidiaries. |
5 | */ |
6 | |
7 | #include "sparx5_main_regs.h" |
8 | #include "sparx5_main.h" |
9 | |
10 | static u32 sparx5_pool_id_to_idx(u32 id) |
11 | { |
12 | return --id; |
13 | } |
14 | |
15 | u32 sparx5_pool_idx_to_id(u32 idx) |
16 | { |
17 | return ++idx; |
18 | } |
19 | |
20 | /* Release resource from pool. |
21 | * Return reference count on success, otherwise return error. |
22 | */ |
23 | int sparx5_pool_put(struct sparx5_pool_entry *pool, int size, u32 id) |
24 | { |
25 | struct sparx5_pool_entry *e_itr; |
26 | |
27 | e_itr = (pool + sparx5_pool_id_to_idx(id)); |
28 | if (e_itr->ref_cnt == 0) |
29 | return -EINVAL; |
30 | |
31 | return --e_itr->ref_cnt; |
32 | } |
33 | |
34 | /* Get resource from pool. |
35 | * Return reference count on success, otherwise return error. |
36 | */ |
37 | int sparx5_pool_get(struct sparx5_pool_entry *pool, int size, u32 *id) |
38 | { |
39 | struct sparx5_pool_entry *e_itr; |
40 | int i; |
41 | |
42 | for (i = 0, e_itr = pool; i < size; i++, e_itr++) { |
43 | if (e_itr->ref_cnt == 0) { |
44 | *id = sparx5_pool_idx_to_id(idx: i); |
45 | return ++e_itr->ref_cnt; |
46 | } |
47 | } |
48 | |
49 | return -ENOSPC; |
50 | } |
51 | |
52 | /* Get resource from pool that matches index. |
53 | * Return reference count on success, otherwise return error. |
54 | */ |
55 | int sparx5_pool_get_with_idx(struct sparx5_pool_entry *pool, int size, u32 idx, |
56 | u32 *id) |
57 | { |
58 | struct sparx5_pool_entry *e_itr; |
59 | int i, ret = -ENOSPC; |
60 | |
61 | for (i = 0, e_itr = pool; i < size; i++, e_itr++) { |
62 | /* Pool index of first free entry */ |
63 | if (e_itr->ref_cnt == 0 && ret == -ENOSPC) |
64 | ret = i; |
65 | /* Tc index already in use ? */ |
66 | if (e_itr->idx == idx && e_itr->ref_cnt > 0) { |
67 | ret = i; |
68 | break; |
69 | } |
70 | } |
71 | |
72 | /* Did we find a free entry? */ |
73 | if (ret >= 0) { |
74 | *id = sparx5_pool_idx_to_id(idx: ret); |
75 | e_itr = (pool + ret); |
76 | e_itr->idx = idx; |
77 | return ++e_itr->ref_cnt; |
78 | } |
79 | |
80 | return ret; |
81 | } |
82 | |