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(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(ret); 75 e_itr = (pool + ret); 76 e_itr->idx = idx; 77 return ++e_itr->ref_cnt; 78 } 79 80 return ret; 81 } 82