// SPDX-License-Identifier: GPL-2.0+ /* Microchip Sparx5 Switch driver * * Copyright (c) 2023 Microchip Technology Inc. and its subsidiaries. */ #include "sparx5_main_regs.h" #include "sparx5_main.h" static u32 sparx5_pool_id_to_idx(u32 id) { return --id; } u32 sparx5_pool_idx_to_id(u32 idx) { return ++idx; } /* Release resource from pool. * Return reference count on success, otherwise return error. */ int sparx5_pool_put(struct sparx5_pool_entry *pool, int size, u32 id) { struct sparx5_pool_entry *e_itr; e_itr = (pool + sparx5_pool_id_to_idx(id)); if (e_itr->ref_cnt == 0) return -EINVAL; return --e_itr->ref_cnt; } /* Get resource from pool. * Return reference count on success, otherwise return error. */ int sparx5_pool_get(struct sparx5_pool_entry *pool, int size, u32 *id) { struct sparx5_pool_entry *e_itr; int i; for (i = 0, e_itr = pool; i < size; i++, e_itr++) { if (e_itr->ref_cnt == 0) { *id = sparx5_pool_idx_to_id(i); return ++e_itr->ref_cnt; } } return -ENOSPC; } /* Get resource from pool that matches index. * Return reference count on success, otherwise return error. */ int sparx5_pool_get_with_idx(struct sparx5_pool_entry *pool, int size, u32 idx, u32 *id) { struct sparx5_pool_entry *e_itr; int i, ret = -ENOSPC; for (i = 0, e_itr = pool; i < size; i++, e_itr++) { /* Pool index of first free entry */ if (e_itr->ref_cnt == 0 && ret == -ENOSPC) ret = i; /* Tc index already in use ? */ if (e_itr->idx == idx && e_itr->ref_cnt > 0) { ret = i; break; } } /* Did we find a free entry? */ if (ret >= 0) { *id = sparx5_pool_idx_to_id(ret); e_itr = (pool + ret); e_itr->idx = idx; return ++e_itr->ref_cnt; } return ret; }