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