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