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