76 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			76 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
 | |
| /* Copyright (c) 2016-2018 Mellanox Technologies. All rights reserved */
 | |
| 
 | |
| #include <linux/kernel.h>
 | |
| #include <linux/slab.h>
 | |
| 
 | |
| #include "spectrum.h"
 | |
| 
 | |
| struct mlxsw_sp_kvdl {
 | |
| 	const struct mlxsw_sp_kvdl_ops *kvdl_ops;
 | |
| 	unsigned long priv[0];
 | |
| 	/* priv has to be always the last item */
 | |
| };
 | |
| 
 | |
| int mlxsw_sp_kvdl_init(struct mlxsw_sp *mlxsw_sp)
 | |
| {
 | |
| 	const struct mlxsw_sp_kvdl_ops *kvdl_ops = mlxsw_sp->kvdl_ops;
 | |
| 	struct mlxsw_sp_kvdl *kvdl;
 | |
| 	int err;
 | |
| 
 | |
| 	kvdl = kzalloc(sizeof(*mlxsw_sp->kvdl) + kvdl_ops->priv_size,
 | |
| 		       GFP_KERNEL);
 | |
| 	if (!kvdl)
 | |
| 		return -ENOMEM;
 | |
| 	kvdl->kvdl_ops = kvdl_ops;
 | |
| 	mlxsw_sp->kvdl = kvdl;
 | |
| 
 | |
| 	err = kvdl_ops->init(mlxsw_sp, kvdl->priv);
 | |
| 	if (err)
 | |
| 		goto err_init;
 | |
| 	return 0;
 | |
| 
 | |
| err_init:
 | |
| 	kfree(kvdl);
 | |
| 	return err;
 | |
| }
 | |
| 
 | |
| void mlxsw_sp_kvdl_fini(struct mlxsw_sp *mlxsw_sp)
 | |
| {
 | |
| 	struct mlxsw_sp_kvdl *kvdl = mlxsw_sp->kvdl;
 | |
| 
 | |
| 	kvdl->kvdl_ops->fini(mlxsw_sp, kvdl->priv);
 | |
| 	kfree(kvdl);
 | |
| }
 | |
| 
 | |
| int mlxsw_sp_kvdl_alloc(struct mlxsw_sp *mlxsw_sp,
 | |
| 			enum mlxsw_sp_kvdl_entry_type type,
 | |
| 			unsigned int entry_count, u32 *p_entry_index)
 | |
| {
 | |
| 	struct mlxsw_sp_kvdl *kvdl = mlxsw_sp->kvdl;
 | |
| 
 | |
| 	return kvdl->kvdl_ops->alloc(mlxsw_sp, kvdl->priv, type,
 | |
| 				     entry_count, p_entry_index);
 | |
| }
 | |
| 
 | |
| void mlxsw_sp_kvdl_free(struct mlxsw_sp *mlxsw_sp,
 | |
| 			enum mlxsw_sp_kvdl_entry_type type,
 | |
| 			unsigned int entry_count, int entry_index)
 | |
| {
 | |
| 	struct mlxsw_sp_kvdl *kvdl = mlxsw_sp->kvdl;
 | |
| 
 | |
| 	kvdl->kvdl_ops->free(mlxsw_sp, kvdl->priv, type,
 | |
| 			     entry_count, entry_index);
 | |
| }
 | |
| 
 | |
| int mlxsw_sp_kvdl_alloc_count_query(struct mlxsw_sp *mlxsw_sp,
 | |
| 				    enum mlxsw_sp_kvdl_entry_type type,
 | |
| 				    unsigned int entry_count,
 | |
| 				    unsigned int *p_alloc_count)
 | |
| {
 | |
| 	struct mlxsw_sp_kvdl *kvdl = mlxsw_sp->kvdl;
 | |
| 
 | |
| 	return kvdl->kvdl_ops->alloc_size_query(mlxsw_sp, kvdl->priv, type,
 | |
| 						entry_count, p_alloc_count);
 | |
| }
 | 
