162306a36Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 262306a36Sopenharmony_ci/* Copyright (c) 2018 Mellanox Technologies. All rights reserved */ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#include <linux/kernel.h> 562306a36Sopenharmony_ci#include <linux/bitops.h> 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#include "spectrum.h" 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#define MLXSW_SP1_KVDL_SINGLE_BASE 0 1062306a36Sopenharmony_ci#define MLXSW_SP1_KVDL_SINGLE_SIZE 16384 1162306a36Sopenharmony_ci#define MLXSW_SP1_KVDL_SINGLE_END \ 1262306a36Sopenharmony_ci (MLXSW_SP1_KVDL_SINGLE_SIZE + MLXSW_SP1_KVDL_SINGLE_BASE - 1) 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#define MLXSW_SP1_KVDL_CHUNKS_BASE \ 1562306a36Sopenharmony_ci (MLXSW_SP1_KVDL_SINGLE_BASE + MLXSW_SP1_KVDL_SINGLE_SIZE) 1662306a36Sopenharmony_ci#define MLXSW_SP1_KVDL_CHUNKS_SIZE 49152 1762306a36Sopenharmony_ci#define MLXSW_SP1_KVDL_CHUNKS_END \ 1862306a36Sopenharmony_ci (MLXSW_SP1_KVDL_CHUNKS_SIZE + MLXSW_SP1_KVDL_CHUNKS_BASE - 1) 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci#define MLXSW_SP1_KVDL_LARGE_CHUNKS_BASE \ 2162306a36Sopenharmony_ci (MLXSW_SP1_KVDL_CHUNKS_BASE + MLXSW_SP1_KVDL_CHUNKS_SIZE) 2262306a36Sopenharmony_ci#define MLXSW_SP1_KVDL_LARGE_CHUNKS_SIZE \ 2362306a36Sopenharmony_ci (MLXSW_SP_KVD_LINEAR_SIZE - MLXSW_SP1_KVDL_LARGE_CHUNKS_BASE) 2462306a36Sopenharmony_ci#define MLXSW_SP1_KVDL_LARGE_CHUNKS_END \ 2562306a36Sopenharmony_ci (MLXSW_SP1_KVDL_LARGE_CHUNKS_SIZE + MLXSW_SP1_KVDL_LARGE_CHUNKS_BASE - 1) 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci#define MLXSW_SP1_KVDL_SINGLE_ALLOC_SIZE 1 2862306a36Sopenharmony_ci#define MLXSW_SP1_KVDL_CHUNKS_ALLOC_SIZE 32 2962306a36Sopenharmony_ci#define MLXSW_SP1_KVDL_LARGE_CHUNKS_ALLOC_SIZE 512 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_cistruct mlxsw_sp1_kvdl_part_info { 3262306a36Sopenharmony_ci unsigned int part_index; 3362306a36Sopenharmony_ci unsigned int start_index; 3462306a36Sopenharmony_ci unsigned int end_index; 3562306a36Sopenharmony_ci unsigned int alloc_size; 3662306a36Sopenharmony_ci enum mlxsw_sp_resource_id resource_id; 3762306a36Sopenharmony_ci}; 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_cienum mlxsw_sp1_kvdl_part_id { 4062306a36Sopenharmony_ci MLXSW_SP1_KVDL_PART_ID_SINGLE, 4162306a36Sopenharmony_ci MLXSW_SP1_KVDL_PART_ID_CHUNKS, 4262306a36Sopenharmony_ci MLXSW_SP1_KVDL_PART_ID_LARGE_CHUNKS, 4362306a36Sopenharmony_ci}; 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci#define MLXSW_SP1_KVDL_PART_INFO(id) \ 4662306a36Sopenharmony_ci[MLXSW_SP1_KVDL_PART_ID_##id] = { \ 4762306a36Sopenharmony_ci .start_index = MLXSW_SP1_KVDL_##id##_BASE, \ 4862306a36Sopenharmony_ci .end_index = MLXSW_SP1_KVDL_##id##_END, \ 4962306a36Sopenharmony_ci .alloc_size = MLXSW_SP1_KVDL_##id##_ALLOC_SIZE, \ 5062306a36Sopenharmony_ci .resource_id = MLXSW_SP_RESOURCE_KVD_LINEAR_##id, \ 5162306a36Sopenharmony_ci} 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_cistatic const struct mlxsw_sp1_kvdl_part_info mlxsw_sp1_kvdl_parts_info[] = { 5462306a36Sopenharmony_ci MLXSW_SP1_KVDL_PART_INFO(SINGLE), 5562306a36Sopenharmony_ci MLXSW_SP1_KVDL_PART_INFO(CHUNKS), 5662306a36Sopenharmony_ci MLXSW_SP1_KVDL_PART_INFO(LARGE_CHUNKS), 5762306a36Sopenharmony_ci}; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci#define MLXSW_SP1_KVDL_PARTS_INFO_LEN ARRAY_SIZE(mlxsw_sp1_kvdl_parts_info) 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_cistruct mlxsw_sp1_kvdl_part { 6262306a36Sopenharmony_ci struct mlxsw_sp1_kvdl_part_info info; 6362306a36Sopenharmony_ci unsigned long usage[]; /* Entries */ 6462306a36Sopenharmony_ci}; 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_cistruct mlxsw_sp1_kvdl { 6762306a36Sopenharmony_ci struct mlxsw_sp1_kvdl_part *parts[MLXSW_SP1_KVDL_PARTS_INFO_LEN]; 6862306a36Sopenharmony_ci}; 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_cistatic struct mlxsw_sp1_kvdl_part * 7162306a36Sopenharmony_cimlxsw_sp1_kvdl_alloc_size_part(struct mlxsw_sp1_kvdl *kvdl, 7262306a36Sopenharmony_ci unsigned int alloc_size) 7362306a36Sopenharmony_ci{ 7462306a36Sopenharmony_ci struct mlxsw_sp1_kvdl_part *part, *min_part = NULL; 7562306a36Sopenharmony_ci int i; 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci for (i = 0; i < MLXSW_SP1_KVDL_PARTS_INFO_LEN; i++) { 7862306a36Sopenharmony_ci part = kvdl->parts[i]; 7962306a36Sopenharmony_ci if (alloc_size <= part->info.alloc_size && 8062306a36Sopenharmony_ci (!min_part || 8162306a36Sopenharmony_ci part->info.alloc_size <= min_part->info.alloc_size)) 8262306a36Sopenharmony_ci min_part = part; 8362306a36Sopenharmony_ci } 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci return min_part ?: ERR_PTR(-ENOBUFS); 8662306a36Sopenharmony_ci} 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_cistatic struct mlxsw_sp1_kvdl_part * 8962306a36Sopenharmony_cimlxsw_sp1_kvdl_index_part(struct mlxsw_sp1_kvdl *kvdl, u32 kvdl_index) 9062306a36Sopenharmony_ci{ 9162306a36Sopenharmony_ci struct mlxsw_sp1_kvdl_part *part; 9262306a36Sopenharmony_ci int i; 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci for (i = 0; i < MLXSW_SP1_KVDL_PARTS_INFO_LEN; i++) { 9562306a36Sopenharmony_ci part = kvdl->parts[i]; 9662306a36Sopenharmony_ci if (kvdl_index >= part->info.start_index && 9762306a36Sopenharmony_ci kvdl_index <= part->info.end_index) 9862306a36Sopenharmony_ci return part; 9962306a36Sopenharmony_ci } 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci return ERR_PTR(-EINVAL); 10262306a36Sopenharmony_ci} 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_cistatic u32 10562306a36Sopenharmony_cimlxsw_sp1_kvdl_to_kvdl_index(const struct mlxsw_sp1_kvdl_part_info *info, 10662306a36Sopenharmony_ci unsigned int entry_index) 10762306a36Sopenharmony_ci{ 10862306a36Sopenharmony_ci return info->start_index + entry_index * info->alloc_size; 10962306a36Sopenharmony_ci} 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_cistatic unsigned int 11262306a36Sopenharmony_cimlxsw_sp1_kvdl_to_entry_index(const struct mlxsw_sp1_kvdl_part_info *info, 11362306a36Sopenharmony_ci u32 kvdl_index) 11462306a36Sopenharmony_ci{ 11562306a36Sopenharmony_ci return (kvdl_index - info->start_index) / info->alloc_size; 11662306a36Sopenharmony_ci} 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_cistatic int mlxsw_sp1_kvdl_part_alloc(struct mlxsw_sp1_kvdl_part *part, 11962306a36Sopenharmony_ci u32 *p_kvdl_index) 12062306a36Sopenharmony_ci{ 12162306a36Sopenharmony_ci const struct mlxsw_sp1_kvdl_part_info *info = &part->info; 12262306a36Sopenharmony_ci unsigned int entry_index, nr_entries; 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci nr_entries = (info->end_index - info->start_index + 1) / 12562306a36Sopenharmony_ci info->alloc_size; 12662306a36Sopenharmony_ci entry_index = find_first_zero_bit(part->usage, nr_entries); 12762306a36Sopenharmony_ci if (entry_index == nr_entries) 12862306a36Sopenharmony_ci return -ENOBUFS; 12962306a36Sopenharmony_ci __set_bit(entry_index, part->usage); 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci *p_kvdl_index = mlxsw_sp1_kvdl_to_kvdl_index(info, entry_index); 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci return 0; 13462306a36Sopenharmony_ci} 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_cistatic void mlxsw_sp1_kvdl_part_free(struct mlxsw_sp1_kvdl_part *part, 13762306a36Sopenharmony_ci u32 kvdl_index) 13862306a36Sopenharmony_ci{ 13962306a36Sopenharmony_ci const struct mlxsw_sp1_kvdl_part_info *info = &part->info; 14062306a36Sopenharmony_ci unsigned int entry_index; 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci entry_index = mlxsw_sp1_kvdl_to_entry_index(info, kvdl_index); 14362306a36Sopenharmony_ci __clear_bit(entry_index, part->usage); 14462306a36Sopenharmony_ci} 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_cistatic int mlxsw_sp1_kvdl_alloc(struct mlxsw_sp *mlxsw_sp, void *priv, 14762306a36Sopenharmony_ci enum mlxsw_sp_kvdl_entry_type type, 14862306a36Sopenharmony_ci unsigned int entry_count, 14962306a36Sopenharmony_ci u32 *p_entry_index) 15062306a36Sopenharmony_ci{ 15162306a36Sopenharmony_ci struct mlxsw_sp1_kvdl *kvdl = priv; 15262306a36Sopenharmony_ci struct mlxsw_sp1_kvdl_part *part; 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci /* Find partition with smallest allocation size satisfying the 15562306a36Sopenharmony_ci * requested size. 15662306a36Sopenharmony_ci */ 15762306a36Sopenharmony_ci part = mlxsw_sp1_kvdl_alloc_size_part(kvdl, entry_count); 15862306a36Sopenharmony_ci if (IS_ERR(part)) 15962306a36Sopenharmony_ci return PTR_ERR(part); 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci return mlxsw_sp1_kvdl_part_alloc(part, p_entry_index); 16262306a36Sopenharmony_ci} 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_cistatic void mlxsw_sp1_kvdl_free(struct mlxsw_sp *mlxsw_sp, void *priv, 16562306a36Sopenharmony_ci enum mlxsw_sp_kvdl_entry_type type, 16662306a36Sopenharmony_ci unsigned int entry_count, int entry_index) 16762306a36Sopenharmony_ci{ 16862306a36Sopenharmony_ci struct mlxsw_sp1_kvdl *kvdl = priv; 16962306a36Sopenharmony_ci struct mlxsw_sp1_kvdl_part *part; 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci part = mlxsw_sp1_kvdl_index_part(kvdl, entry_index); 17262306a36Sopenharmony_ci if (IS_ERR(part)) 17362306a36Sopenharmony_ci return; 17462306a36Sopenharmony_ci mlxsw_sp1_kvdl_part_free(part, entry_index); 17562306a36Sopenharmony_ci} 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_cistatic int mlxsw_sp1_kvdl_alloc_size_query(struct mlxsw_sp *mlxsw_sp, 17862306a36Sopenharmony_ci void *priv, 17962306a36Sopenharmony_ci enum mlxsw_sp_kvdl_entry_type type, 18062306a36Sopenharmony_ci unsigned int entry_count, 18162306a36Sopenharmony_ci unsigned int *p_alloc_size) 18262306a36Sopenharmony_ci{ 18362306a36Sopenharmony_ci struct mlxsw_sp1_kvdl *kvdl = priv; 18462306a36Sopenharmony_ci struct mlxsw_sp1_kvdl_part *part; 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci part = mlxsw_sp1_kvdl_alloc_size_part(kvdl, entry_count); 18762306a36Sopenharmony_ci if (IS_ERR(part)) 18862306a36Sopenharmony_ci return PTR_ERR(part); 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci *p_alloc_size = part->info.alloc_size; 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_ci return 0; 19362306a36Sopenharmony_ci} 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_cistatic void mlxsw_sp1_kvdl_part_update(struct mlxsw_sp1_kvdl_part *part, 19662306a36Sopenharmony_ci struct mlxsw_sp1_kvdl_part *part_prev, 19762306a36Sopenharmony_ci unsigned int size) 19862306a36Sopenharmony_ci{ 19962306a36Sopenharmony_ci if (!part_prev) { 20062306a36Sopenharmony_ci part->info.end_index = size - 1; 20162306a36Sopenharmony_ci } else { 20262306a36Sopenharmony_ci part->info.start_index = part_prev->info.end_index + 1; 20362306a36Sopenharmony_ci part->info.end_index = part->info.start_index + size - 1; 20462306a36Sopenharmony_ci } 20562306a36Sopenharmony_ci} 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_cistatic struct mlxsw_sp1_kvdl_part * 20862306a36Sopenharmony_cimlxsw_sp1_kvdl_part_init(struct mlxsw_sp *mlxsw_sp, 20962306a36Sopenharmony_ci const struct mlxsw_sp1_kvdl_part_info *info, 21062306a36Sopenharmony_ci struct mlxsw_sp1_kvdl_part *part_prev) 21162306a36Sopenharmony_ci{ 21262306a36Sopenharmony_ci struct devlink *devlink = priv_to_devlink(mlxsw_sp->core); 21362306a36Sopenharmony_ci struct mlxsw_sp1_kvdl_part *part; 21462306a36Sopenharmony_ci bool need_update = true; 21562306a36Sopenharmony_ci unsigned int nr_entries; 21662306a36Sopenharmony_ci u64 resource_size; 21762306a36Sopenharmony_ci int err; 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci err = devl_resource_size_get(devlink, info->resource_id, 22062306a36Sopenharmony_ci &resource_size); 22162306a36Sopenharmony_ci if (err) { 22262306a36Sopenharmony_ci need_update = false; 22362306a36Sopenharmony_ci resource_size = info->end_index - info->start_index + 1; 22462306a36Sopenharmony_ci } 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci nr_entries = div_u64(resource_size, info->alloc_size); 22762306a36Sopenharmony_ci part = kzalloc(struct_size(part, usage, BITS_TO_LONGS(nr_entries)), 22862306a36Sopenharmony_ci GFP_KERNEL); 22962306a36Sopenharmony_ci if (!part) 23062306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci memcpy(&part->info, info, sizeof(part->info)); 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci if (need_update) 23562306a36Sopenharmony_ci mlxsw_sp1_kvdl_part_update(part, part_prev, resource_size); 23662306a36Sopenharmony_ci return part; 23762306a36Sopenharmony_ci} 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_cistatic void mlxsw_sp1_kvdl_part_fini(struct mlxsw_sp1_kvdl_part *part) 24062306a36Sopenharmony_ci{ 24162306a36Sopenharmony_ci kfree(part); 24262306a36Sopenharmony_ci} 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_cistatic int mlxsw_sp1_kvdl_parts_init(struct mlxsw_sp *mlxsw_sp, 24562306a36Sopenharmony_ci struct mlxsw_sp1_kvdl *kvdl) 24662306a36Sopenharmony_ci{ 24762306a36Sopenharmony_ci const struct mlxsw_sp1_kvdl_part_info *info; 24862306a36Sopenharmony_ci struct mlxsw_sp1_kvdl_part *part_prev = NULL; 24962306a36Sopenharmony_ci int err, i; 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci for (i = 0; i < MLXSW_SP1_KVDL_PARTS_INFO_LEN; i++) { 25262306a36Sopenharmony_ci info = &mlxsw_sp1_kvdl_parts_info[i]; 25362306a36Sopenharmony_ci kvdl->parts[i] = mlxsw_sp1_kvdl_part_init(mlxsw_sp, info, 25462306a36Sopenharmony_ci part_prev); 25562306a36Sopenharmony_ci if (IS_ERR(kvdl->parts[i])) { 25662306a36Sopenharmony_ci err = PTR_ERR(kvdl->parts[i]); 25762306a36Sopenharmony_ci goto err_kvdl_part_init; 25862306a36Sopenharmony_ci } 25962306a36Sopenharmony_ci part_prev = kvdl->parts[i]; 26062306a36Sopenharmony_ci } 26162306a36Sopenharmony_ci return 0; 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_cierr_kvdl_part_init: 26462306a36Sopenharmony_ci for (i--; i >= 0; i--) 26562306a36Sopenharmony_ci mlxsw_sp1_kvdl_part_fini(kvdl->parts[i]); 26662306a36Sopenharmony_ci return err; 26762306a36Sopenharmony_ci} 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_cistatic void mlxsw_sp1_kvdl_parts_fini(struct mlxsw_sp1_kvdl *kvdl) 27062306a36Sopenharmony_ci{ 27162306a36Sopenharmony_ci int i; 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci for (i = 0; i < MLXSW_SP1_KVDL_PARTS_INFO_LEN; i++) 27462306a36Sopenharmony_ci mlxsw_sp1_kvdl_part_fini(kvdl->parts[i]); 27562306a36Sopenharmony_ci} 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_cistatic u64 mlxsw_sp1_kvdl_part_occ(struct mlxsw_sp1_kvdl_part *part) 27862306a36Sopenharmony_ci{ 27962306a36Sopenharmony_ci const struct mlxsw_sp1_kvdl_part_info *info = &part->info; 28062306a36Sopenharmony_ci unsigned int nr_entries; 28162306a36Sopenharmony_ci int bit = -1; 28262306a36Sopenharmony_ci u64 occ = 0; 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ci nr_entries = (info->end_index - 28562306a36Sopenharmony_ci info->start_index + 1) / 28662306a36Sopenharmony_ci info->alloc_size; 28762306a36Sopenharmony_ci while ((bit = find_next_bit(part->usage, nr_entries, bit + 1)) 28862306a36Sopenharmony_ci < nr_entries) 28962306a36Sopenharmony_ci occ += info->alloc_size; 29062306a36Sopenharmony_ci return occ; 29162306a36Sopenharmony_ci} 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_cistatic u64 mlxsw_sp1_kvdl_occ_get(void *priv) 29462306a36Sopenharmony_ci{ 29562306a36Sopenharmony_ci const struct mlxsw_sp1_kvdl *kvdl = priv; 29662306a36Sopenharmony_ci u64 occ = 0; 29762306a36Sopenharmony_ci int i; 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ci for (i = 0; i < MLXSW_SP1_KVDL_PARTS_INFO_LEN; i++) 30062306a36Sopenharmony_ci occ += mlxsw_sp1_kvdl_part_occ(kvdl->parts[i]); 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_ci return occ; 30362306a36Sopenharmony_ci} 30462306a36Sopenharmony_ci 30562306a36Sopenharmony_cistatic u64 mlxsw_sp1_kvdl_single_occ_get(void *priv) 30662306a36Sopenharmony_ci{ 30762306a36Sopenharmony_ci const struct mlxsw_sp1_kvdl *kvdl = priv; 30862306a36Sopenharmony_ci struct mlxsw_sp1_kvdl_part *part; 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_ci part = kvdl->parts[MLXSW_SP1_KVDL_PART_ID_SINGLE]; 31162306a36Sopenharmony_ci return mlxsw_sp1_kvdl_part_occ(part); 31262306a36Sopenharmony_ci} 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_cistatic u64 mlxsw_sp1_kvdl_chunks_occ_get(void *priv) 31562306a36Sopenharmony_ci{ 31662306a36Sopenharmony_ci const struct mlxsw_sp1_kvdl *kvdl = priv; 31762306a36Sopenharmony_ci struct mlxsw_sp1_kvdl_part *part; 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_ci part = kvdl->parts[MLXSW_SP1_KVDL_PART_ID_CHUNKS]; 32062306a36Sopenharmony_ci return mlxsw_sp1_kvdl_part_occ(part); 32162306a36Sopenharmony_ci} 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_cistatic u64 mlxsw_sp1_kvdl_large_chunks_occ_get(void *priv) 32462306a36Sopenharmony_ci{ 32562306a36Sopenharmony_ci const struct mlxsw_sp1_kvdl *kvdl = priv; 32662306a36Sopenharmony_ci struct mlxsw_sp1_kvdl_part *part; 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ci part = kvdl->parts[MLXSW_SP1_KVDL_PART_ID_LARGE_CHUNKS]; 32962306a36Sopenharmony_ci return mlxsw_sp1_kvdl_part_occ(part); 33062306a36Sopenharmony_ci} 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_cistatic int mlxsw_sp1_kvdl_init(struct mlxsw_sp *mlxsw_sp, void *priv) 33362306a36Sopenharmony_ci{ 33462306a36Sopenharmony_ci struct devlink *devlink = priv_to_devlink(mlxsw_sp->core); 33562306a36Sopenharmony_ci struct mlxsw_sp1_kvdl *kvdl = priv; 33662306a36Sopenharmony_ci int err; 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_ci err = mlxsw_sp1_kvdl_parts_init(mlxsw_sp, kvdl); 33962306a36Sopenharmony_ci if (err) 34062306a36Sopenharmony_ci return err; 34162306a36Sopenharmony_ci devl_resource_occ_get_register(devlink, 34262306a36Sopenharmony_ci MLXSW_SP_RESOURCE_KVD_LINEAR, 34362306a36Sopenharmony_ci mlxsw_sp1_kvdl_occ_get, 34462306a36Sopenharmony_ci kvdl); 34562306a36Sopenharmony_ci devl_resource_occ_get_register(devlink, 34662306a36Sopenharmony_ci MLXSW_SP_RESOURCE_KVD_LINEAR_SINGLE, 34762306a36Sopenharmony_ci mlxsw_sp1_kvdl_single_occ_get, 34862306a36Sopenharmony_ci kvdl); 34962306a36Sopenharmony_ci devl_resource_occ_get_register(devlink, 35062306a36Sopenharmony_ci MLXSW_SP_RESOURCE_KVD_LINEAR_CHUNKS, 35162306a36Sopenharmony_ci mlxsw_sp1_kvdl_chunks_occ_get, 35262306a36Sopenharmony_ci kvdl); 35362306a36Sopenharmony_ci devl_resource_occ_get_register(devlink, 35462306a36Sopenharmony_ci MLXSW_SP_RESOURCE_KVD_LINEAR_LARGE_CHUNKS, 35562306a36Sopenharmony_ci mlxsw_sp1_kvdl_large_chunks_occ_get, 35662306a36Sopenharmony_ci kvdl); 35762306a36Sopenharmony_ci return 0; 35862306a36Sopenharmony_ci} 35962306a36Sopenharmony_ci 36062306a36Sopenharmony_cistatic void mlxsw_sp1_kvdl_fini(struct mlxsw_sp *mlxsw_sp, void *priv) 36162306a36Sopenharmony_ci{ 36262306a36Sopenharmony_ci struct devlink *devlink = priv_to_devlink(mlxsw_sp->core); 36362306a36Sopenharmony_ci struct mlxsw_sp1_kvdl *kvdl = priv; 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_ci devl_resource_occ_get_unregister(devlink, 36662306a36Sopenharmony_ci MLXSW_SP_RESOURCE_KVD_LINEAR_LARGE_CHUNKS); 36762306a36Sopenharmony_ci devl_resource_occ_get_unregister(devlink, 36862306a36Sopenharmony_ci MLXSW_SP_RESOURCE_KVD_LINEAR_CHUNKS); 36962306a36Sopenharmony_ci devl_resource_occ_get_unregister(devlink, 37062306a36Sopenharmony_ci MLXSW_SP_RESOURCE_KVD_LINEAR_SINGLE); 37162306a36Sopenharmony_ci devl_resource_occ_get_unregister(devlink, 37262306a36Sopenharmony_ci MLXSW_SP_RESOURCE_KVD_LINEAR); 37362306a36Sopenharmony_ci mlxsw_sp1_kvdl_parts_fini(kvdl); 37462306a36Sopenharmony_ci} 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_ciconst struct mlxsw_sp_kvdl_ops mlxsw_sp1_kvdl_ops = { 37762306a36Sopenharmony_ci .priv_size = sizeof(struct mlxsw_sp1_kvdl), 37862306a36Sopenharmony_ci .init = mlxsw_sp1_kvdl_init, 37962306a36Sopenharmony_ci .fini = mlxsw_sp1_kvdl_fini, 38062306a36Sopenharmony_ci .alloc = mlxsw_sp1_kvdl_alloc, 38162306a36Sopenharmony_ci .free = mlxsw_sp1_kvdl_free, 38262306a36Sopenharmony_ci .alloc_size_query = mlxsw_sp1_kvdl_alloc_size_query, 38362306a36Sopenharmony_ci}; 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_ciint mlxsw_sp1_kvdl_resources_register(struct mlxsw_core *mlxsw_core) 38662306a36Sopenharmony_ci{ 38762306a36Sopenharmony_ci struct devlink *devlink = priv_to_devlink(mlxsw_core); 38862306a36Sopenharmony_ci static struct devlink_resource_size_params size_params; 38962306a36Sopenharmony_ci u32 kvdl_max_size; 39062306a36Sopenharmony_ci int err; 39162306a36Sopenharmony_ci 39262306a36Sopenharmony_ci kvdl_max_size = MLXSW_CORE_RES_GET(mlxsw_core, KVD_SIZE) - 39362306a36Sopenharmony_ci MLXSW_CORE_RES_GET(mlxsw_core, KVD_SINGLE_MIN_SIZE) - 39462306a36Sopenharmony_ci MLXSW_CORE_RES_GET(mlxsw_core, KVD_DOUBLE_MIN_SIZE); 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_ci devlink_resource_size_params_init(&size_params, 0, kvdl_max_size, 39762306a36Sopenharmony_ci MLXSW_SP1_KVDL_SINGLE_ALLOC_SIZE, 39862306a36Sopenharmony_ci DEVLINK_RESOURCE_UNIT_ENTRY); 39962306a36Sopenharmony_ci err = devl_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD_LINEAR_SINGLES, 40062306a36Sopenharmony_ci MLXSW_SP1_KVDL_SINGLE_SIZE, 40162306a36Sopenharmony_ci MLXSW_SP_RESOURCE_KVD_LINEAR_SINGLE, 40262306a36Sopenharmony_ci MLXSW_SP_RESOURCE_KVD_LINEAR, 40362306a36Sopenharmony_ci &size_params); 40462306a36Sopenharmony_ci if (err) 40562306a36Sopenharmony_ci return err; 40662306a36Sopenharmony_ci 40762306a36Sopenharmony_ci devlink_resource_size_params_init(&size_params, 0, kvdl_max_size, 40862306a36Sopenharmony_ci MLXSW_SP1_KVDL_CHUNKS_ALLOC_SIZE, 40962306a36Sopenharmony_ci DEVLINK_RESOURCE_UNIT_ENTRY); 41062306a36Sopenharmony_ci err = devl_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD_LINEAR_CHUNKS, 41162306a36Sopenharmony_ci MLXSW_SP1_KVDL_CHUNKS_SIZE, 41262306a36Sopenharmony_ci MLXSW_SP_RESOURCE_KVD_LINEAR_CHUNKS, 41362306a36Sopenharmony_ci MLXSW_SP_RESOURCE_KVD_LINEAR, 41462306a36Sopenharmony_ci &size_params); 41562306a36Sopenharmony_ci if (err) 41662306a36Sopenharmony_ci return err; 41762306a36Sopenharmony_ci 41862306a36Sopenharmony_ci devlink_resource_size_params_init(&size_params, 0, kvdl_max_size, 41962306a36Sopenharmony_ci MLXSW_SP1_KVDL_LARGE_CHUNKS_ALLOC_SIZE, 42062306a36Sopenharmony_ci DEVLINK_RESOURCE_UNIT_ENTRY); 42162306a36Sopenharmony_ci err = devl_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD_LINEAR_LARGE_CHUNKS, 42262306a36Sopenharmony_ci MLXSW_SP1_KVDL_LARGE_CHUNKS_SIZE, 42362306a36Sopenharmony_ci MLXSW_SP_RESOURCE_KVD_LINEAR_LARGE_CHUNKS, 42462306a36Sopenharmony_ci MLXSW_SP_RESOURCE_KVD_LINEAR, 42562306a36Sopenharmony_ci &size_params); 42662306a36Sopenharmony_ci return err; 42762306a36Sopenharmony_ci} 428