1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2 /* Copyright (c) 2016-2018 Mellanox Technologies. All rights reserved */ 3 4 #include <linux/kernel.h> 5 #include <linux/slab.h> 6 7 #include "spectrum.h" 8 9 struct mlxsw_sp_kvdl { 10 const struct mlxsw_sp_kvdl_ops *kvdl_ops; 11 unsigned long priv[0]; 12 /* priv has to be always the last item */ 13 }; 14 15 int mlxsw_sp_kvdl_init(struct mlxsw_sp *mlxsw_sp) 16 { 17 const struct mlxsw_sp_kvdl_ops *kvdl_ops = mlxsw_sp->kvdl_ops; 18 struct mlxsw_sp_kvdl *kvdl; 19 int err; 20 21 kvdl = kzalloc(sizeof(*mlxsw_sp->kvdl) + kvdl_ops->priv_size, 22 GFP_KERNEL); 23 if (!kvdl) 24 return -ENOMEM; 25 kvdl->kvdl_ops = kvdl_ops; 26 mlxsw_sp->kvdl = kvdl; 27 28 err = kvdl_ops->init(mlxsw_sp, kvdl->priv); 29 if (err) 30 goto err_init; 31 return 0; 32 33 err_init: 34 kfree(kvdl); 35 return err; 36 } 37 38 void mlxsw_sp_kvdl_fini(struct mlxsw_sp *mlxsw_sp) 39 { 40 struct mlxsw_sp_kvdl *kvdl = mlxsw_sp->kvdl; 41 42 kvdl->kvdl_ops->fini(mlxsw_sp, kvdl->priv); 43 kfree(kvdl); 44 } 45 46 int mlxsw_sp_kvdl_alloc(struct mlxsw_sp *mlxsw_sp, 47 enum mlxsw_sp_kvdl_entry_type type, 48 unsigned int entry_count, u32 *p_entry_index) 49 { 50 struct mlxsw_sp_kvdl *kvdl = mlxsw_sp->kvdl; 51 52 return kvdl->kvdl_ops->alloc(mlxsw_sp, kvdl->priv, type, 53 entry_count, p_entry_index); 54 } 55 56 void mlxsw_sp_kvdl_free(struct mlxsw_sp *mlxsw_sp, 57 enum mlxsw_sp_kvdl_entry_type type, 58 unsigned int entry_count, int entry_index) 59 { 60 struct mlxsw_sp_kvdl *kvdl = mlxsw_sp->kvdl; 61 62 kvdl->kvdl_ops->free(mlxsw_sp, kvdl->priv, type, 63 entry_count, entry_index); 64 } 65 66 int mlxsw_sp_kvdl_alloc_count_query(struct mlxsw_sp *mlxsw_sp, 67 enum mlxsw_sp_kvdl_entry_type type, 68 unsigned int entry_count, 69 unsigned int *p_alloc_count) 70 { 71 struct mlxsw_sp_kvdl *kvdl = mlxsw_sp->kvdl; 72 73 return kvdl->kvdl_ops->alloc_size_query(mlxsw_sp, kvdl->priv, type, 74 entry_count, p_alloc_count); 75 } 76