82 lines
1.7 KiB
C
82 lines
1.7 KiB
C
|
// 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;
|
||
|
}
|