18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 28c2ecf20Sopenharmony_ci/* Copyright (c) 2018 Mellanox Technologies. All rights reserved */ 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci#include <linux/kernel.h> 58c2ecf20Sopenharmony_ci#include <linux/bitops.h> 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include "spectrum.h" 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#define MLXSW_SP1_KVDL_SINGLE_BASE 0 108c2ecf20Sopenharmony_ci#define MLXSW_SP1_KVDL_SINGLE_SIZE 16384 118c2ecf20Sopenharmony_ci#define MLXSW_SP1_KVDL_SINGLE_END \ 128c2ecf20Sopenharmony_ci (MLXSW_SP1_KVDL_SINGLE_SIZE + MLXSW_SP1_KVDL_SINGLE_BASE - 1) 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#define MLXSW_SP1_KVDL_CHUNKS_BASE \ 158c2ecf20Sopenharmony_ci (MLXSW_SP1_KVDL_SINGLE_BASE + MLXSW_SP1_KVDL_SINGLE_SIZE) 168c2ecf20Sopenharmony_ci#define MLXSW_SP1_KVDL_CHUNKS_SIZE 49152 178c2ecf20Sopenharmony_ci#define MLXSW_SP1_KVDL_CHUNKS_END \ 188c2ecf20Sopenharmony_ci (MLXSW_SP1_KVDL_CHUNKS_SIZE + MLXSW_SP1_KVDL_CHUNKS_BASE - 1) 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci#define MLXSW_SP1_KVDL_LARGE_CHUNKS_BASE \ 218c2ecf20Sopenharmony_ci (MLXSW_SP1_KVDL_CHUNKS_BASE + MLXSW_SP1_KVDL_CHUNKS_SIZE) 228c2ecf20Sopenharmony_ci#define MLXSW_SP1_KVDL_LARGE_CHUNKS_SIZE \ 238c2ecf20Sopenharmony_ci (MLXSW_SP_KVD_LINEAR_SIZE - MLXSW_SP1_KVDL_LARGE_CHUNKS_BASE) 248c2ecf20Sopenharmony_ci#define MLXSW_SP1_KVDL_LARGE_CHUNKS_END \ 258c2ecf20Sopenharmony_ci (MLXSW_SP1_KVDL_LARGE_CHUNKS_SIZE + MLXSW_SP1_KVDL_LARGE_CHUNKS_BASE - 1) 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci#define MLXSW_SP1_KVDL_SINGLE_ALLOC_SIZE 1 288c2ecf20Sopenharmony_ci#define MLXSW_SP1_KVDL_CHUNKS_ALLOC_SIZE 32 298c2ecf20Sopenharmony_ci#define MLXSW_SP1_KVDL_LARGE_CHUNKS_ALLOC_SIZE 512 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_cistruct mlxsw_sp1_kvdl_part_info { 328c2ecf20Sopenharmony_ci unsigned int part_index; 338c2ecf20Sopenharmony_ci unsigned int start_index; 348c2ecf20Sopenharmony_ci unsigned int end_index; 358c2ecf20Sopenharmony_ci unsigned int alloc_size; 368c2ecf20Sopenharmony_ci enum mlxsw_sp_resource_id resource_id; 378c2ecf20Sopenharmony_ci}; 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_cienum mlxsw_sp1_kvdl_part_id { 408c2ecf20Sopenharmony_ci MLXSW_SP1_KVDL_PART_ID_SINGLE, 418c2ecf20Sopenharmony_ci MLXSW_SP1_KVDL_PART_ID_CHUNKS, 428c2ecf20Sopenharmony_ci MLXSW_SP1_KVDL_PART_ID_LARGE_CHUNKS, 438c2ecf20Sopenharmony_ci}; 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci#define MLXSW_SP1_KVDL_PART_INFO(id) \ 468c2ecf20Sopenharmony_ci[MLXSW_SP1_KVDL_PART_ID_##id] = { \ 478c2ecf20Sopenharmony_ci .start_index = MLXSW_SP1_KVDL_##id##_BASE, \ 488c2ecf20Sopenharmony_ci .end_index = MLXSW_SP1_KVDL_##id##_END, \ 498c2ecf20Sopenharmony_ci .alloc_size = MLXSW_SP1_KVDL_##id##_ALLOC_SIZE, \ 508c2ecf20Sopenharmony_ci .resource_id = MLXSW_SP_RESOURCE_KVD_LINEAR_##id, \ 518c2ecf20Sopenharmony_ci} 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_cistatic const struct mlxsw_sp1_kvdl_part_info mlxsw_sp1_kvdl_parts_info[] = { 548c2ecf20Sopenharmony_ci MLXSW_SP1_KVDL_PART_INFO(SINGLE), 558c2ecf20Sopenharmony_ci MLXSW_SP1_KVDL_PART_INFO(CHUNKS), 568c2ecf20Sopenharmony_ci MLXSW_SP1_KVDL_PART_INFO(LARGE_CHUNKS), 578c2ecf20Sopenharmony_ci}; 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci#define MLXSW_SP1_KVDL_PARTS_INFO_LEN ARRAY_SIZE(mlxsw_sp1_kvdl_parts_info) 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_cistruct mlxsw_sp1_kvdl_part { 628c2ecf20Sopenharmony_ci struct mlxsw_sp1_kvdl_part_info info; 638c2ecf20Sopenharmony_ci unsigned long usage[]; /* Entries */ 648c2ecf20Sopenharmony_ci}; 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_cistruct mlxsw_sp1_kvdl { 678c2ecf20Sopenharmony_ci struct mlxsw_sp1_kvdl_part *parts[MLXSW_SP1_KVDL_PARTS_INFO_LEN]; 688c2ecf20Sopenharmony_ci}; 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_cistatic struct mlxsw_sp1_kvdl_part * 718c2ecf20Sopenharmony_cimlxsw_sp1_kvdl_alloc_size_part(struct mlxsw_sp1_kvdl *kvdl, 728c2ecf20Sopenharmony_ci unsigned int alloc_size) 738c2ecf20Sopenharmony_ci{ 748c2ecf20Sopenharmony_ci struct mlxsw_sp1_kvdl_part *part, *min_part = NULL; 758c2ecf20Sopenharmony_ci int i; 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci for (i = 0; i < MLXSW_SP1_KVDL_PARTS_INFO_LEN; i++) { 788c2ecf20Sopenharmony_ci part = kvdl->parts[i]; 798c2ecf20Sopenharmony_ci if (alloc_size <= part->info.alloc_size && 808c2ecf20Sopenharmony_ci (!min_part || 818c2ecf20Sopenharmony_ci part->info.alloc_size <= min_part->info.alloc_size)) 828c2ecf20Sopenharmony_ci min_part = part; 838c2ecf20Sopenharmony_ci } 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci return min_part ?: ERR_PTR(-ENOBUFS); 868c2ecf20Sopenharmony_ci} 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_cistatic struct mlxsw_sp1_kvdl_part * 898c2ecf20Sopenharmony_cimlxsw_sp1_kvdl_index_part(struct mlxsw_sp1_kvdl *kvdl, u32 kvdl_index) 908c2ecf20Sopenharmony_ci{ 918c2ecf20Sopenharmony_ci struct mlxsw_sp1_kvdl_part *part; 928c2ecf20Sopenharmony_ci int i; 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci for (i = 0; i < MLXSW_SP1_KVDL_PARTS_INFO_LEN; i++) { 958c2ecf20Sopenharmony_ci part = kvdl->parts[i]; 968c2ecf20Sopenharmony_ci if (kvdl_index >= part->info.start_index && 978c2ecf20Sopenharmony_ci kvdl_index <= part->info.end_index) 988c2ecf20Sopenharmony_ci return part; 998c2ecf20Sopenharmony_ci } 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci return ERR_PTR(-EINVAL); 1028c2ecf20Sopenharmony_ci} 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_cistatic u32 1058c2ecf20Sopenharmony_cimlxsw_sp1_kvdl_to_kvdl_index(const struct mlxsw_sp1_kvdl_part_info *info, 1068c2ecf20Sopenharmony_ci unsigned int entry_index) 1078c2ecf20Sopenharmony_ci{ 1088c2ecf20Sopenharmony_ci return info->start_index + entry_index * info->alloc_size; 1098c2ecf20Sopenharmony_ci} 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_cistatic unsigned int 1128c2ecf20Sopenharmony_cimlxsw_sp1_kvdl_to_entry_index(const struct mlxsw_sp1_kvdl_part_info *info, 1138c2ecf20Sopenharmony_ci u32 kvdl_index) 1148c2ecf20Sopenharmony_ci{ 1158c2ecf20Sopenharmony_ci return (kvdl_index - info->start_index) / info->alloc_size; 1168c2ecf20Sopenharmony_ci} 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_cistatic int mlxsw_sp1_kvdl_part_alloc(struct mlxsw_sp1_kvdl_part *part, 1198c2ecf20Sopenharmony_ci u32 *p_kvdl_index) 1208c2ecf20Sopenharmony_ci{ 1218c2ecf20Sopenharmony_ci const struct mlxsw_sp1_kvdl_part_info *info = &part->info; 1228c2ecf20Sopenharmony_ci unsigned int entry_index, nr_entries; 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci nr_entries = (info->end_index - info->start_index + 1) / 1258c2ecf20Sopenharmony_ci info->alloc_size; 1268c2ecf20Sopenharmony_ci entry_index = find_first_zero_bit(part->usage, nr_entries); 1278c2ecf20Sopenharmony_ci if (entry_index == nr_entries) 1288c2ecf20Sopenharmony_ci return -ENOBUFS; 1298c2ecf20Sopenharmony_ci __set_bit(entry_index, part->usage); 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci *p_kvdl_index = mlxsw_sp1_kvdl_to_kvdl_index(info, entry_index); 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci return 0; 1348c2ecf20Sopenharmony_ci} 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_cistatic void mlxsw_sp1_kvdl_part_free(struct mlxsw_sp1_kvdl_part *part, 1378c2ecf20Sopenharmony_ci u32 kvdl_index) 1388c2ecf20Sopenharmony_ci{ 1398c2ecf20Sopenharmony_ci const struct mlxsw_sp1_kvdl_part_info *info = &part->info; 1408c2ecf20Sopenharmony_ci unsigned int entry_index; 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci entry_index = mlxsw_sp1_kvdl_to_entry_index(info, kvdl_index); 1438c2ecf20Sopenharmony_ci __clear_bit(entry_index, part->usage); 1448c2ecf20Sopenharmony_ci} 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_cistatic int mlxsw_sp1_kvdl_alloc(struct mlxsw_sp *mlxsw_sp, void *priv, 1478c2ecf20Sopenharmony_ci enum mlxsw_sp_kvdl_entry_type type, 1488c2ecf20Sopenharmony_ci unsigned int entry_count, 1498c2ecf20Sopenharmony_ci u32 *p_entry_index) 1508c2ecf20Sopenharmony_ci{ 1518c2ecf20Sopenharmony_ci struct mlxsw_sp1_kvdl *kvdl = priv; 1528c2ecf20Sopenharmony_ci struct mlxsw_sp1_kvdl_part *part; 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci /* Find partition with smallest allocation size satisfying the 1558c2ecf20Sopenharmony_ci * requested size. 1568c2ecf20Sopenharmony_ci */ 1578c2ecf20Sopenharmony_ci part = mlxsw_sp1_kvdl_alloc_size_part(kvdl, entry_count); 1588c2ecf20Sopenharmony_ci if (IS_ERR(part)) 1598c2ecf20Sopenharmony_ci return PTR_ERR(part); 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci return mlxsw_sp1_kvdl_part_alloc(part, p_entry_index); 1628c2ecf20Sopenharmony_ci} 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_cistatic void mlxsw_sp1_kvdl_free(struct mlxsw_sp *mlxsw_sp, void *priv, 1658c2ecf20Sopenharmony_ci enum mlxsw_sp_kvdl_entry_type type, 1668c2ecf20Sopenharmony_ci unsigned int entry_count, int entry_index) 1678c2ecf20Sopenharmony_ci{ 1688c2ecf20Sopenharmony_ci struct mlxsw_sp1_kvdl *kvdl = priv; 1698c2ecf20Sopenharmony_ci struct mlxsw_sp1_kvdl_part *part; 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_ci part = mlxsw_sp1_kvdl_index_part(kvdl, entry_index); 1728c2ecf20Sopenharmony_ci if (IS_ERR(part)) 1738c2ecf20Sopenharmony_ci return; 1748c2ecf20Sopenharmony_ci mlxsw_sp1_kvdl_part_free(part, entry_index); 1758c2ecf20Sopenharmony_ci} 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_cistatic int mlxsw_sp1_kvdl_alloc_size_query(struct mlxsw_sp *mlxsw_sp, 1788c2ecf20Sopenharmony_ci void *priv, 1798c2ecf20Sopenharmony_ci enum mlxsw_sp_kvdl_entry_type type, 1808c2ecf20Sopenharmony_ci unsigned int entry_count, 1818c2ecf20Sopenharmony_ci unsigned int *p_alloc_size) 1828c2ecf20Sopenharmony_ci{ 1838c2ecf20Sopenharmony_ci struct mlxsw_sp1_kvdl *kvdl = priv; 1848c2ecf20Sopenharmony_ci struct mlxsw_sp1_kvdl_part *part; 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_ci part = mlxsw_sp1_kvdl_alloc_size_part(kvdl, entry_count); 1878c2ecf20Sopenharmony_ci if (IS_ERR(part)) 1888c2ecf20Sopenharmony_ci return PTR_ERR(part); 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci *p_alloc_size = part->info.alloc_size; 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci return 0; 1938c2ecf20Sopenharmony_ci} 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_cistatic void mlxsw_sp1_kvdl_part_update(struct mlxsw_sp1_kvdl_part *part, 1968c2ecf20Sopenharmony_ci struct mlxsw_sp1_kvdl_part *part_prev, 1978c2ecf20Sopenharmony_ci unsigned int size) 1988c2ecf20Sopenharmony_ci{ 1998c2ecf20Sopenharmony_ci if (!part_prev) { 2008c2ecf20Sopenharmony_ci part->info.end_index = size - 1; 2018c2ecf20Sopenharmony_ci } else { 2028c2ecf20Sopenharmony_ci part->info.start_index = part_prev->info.end_index + 1; 2038c2ecf20Sopenharmony_ci part->info.end_index = part->info.start_index + size - 1; 2048c2ecf20Sopenharmony_ci } 2058c2ecf20Sopenharmony_ci} 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_cistatic struct mlxsw_sp1_kvdl_part * 2088c2ecf20Sopenharmony_cimlxsw_sp1_kvdl_part_init(struct mlxsw_sp *mlxsw_sp, 2098c2ecf20Sopenharmony_ci const struct mlxsw_sp1_kvdl_part_info *info, 2108c2ecf20Sopenharmony_ci struct mlxsw_sp1_kvdl_part *part_prev) 2118c2ecf20Sopenharmony_ci{ 2128c2ecf20Sopenharmony_ci struct devlink *devlink = priv_to_devlink(mlxsw_sp->core); 2138c2ecf20Sopenharmony_ci struct mlxsw_sp1_kvdl_part *part; 2148c2ecf20Sopenharmony_ci bool need_update = true; 2158c2ecf20Sopenharmony_ci unsigned int nr_entries; 2168c2ecf20Sopenharmony_ci size_t usage_size; 2178c2ecf20Sopenharmony_ci u64 resource_size; 2188c2ecf20Sopenharmony_ci int err; 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ci err = devlink_resource_size_get(devlink, info->resource_id, 2218c2ecf20Sopenharmony_ci &resource_size); 2228c2ecf20Sopenharmony_ci if (err) { 2238c2ecf20Sopenharmony_ci need_update = false; 2248c2ecf20Sopenharmony_ci resource_size = info->end_index - info->start_index + 1; 2258c2ecf20Sopenharmony_ci } 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_ci nr_entries = div_u64(resource_size, info->alloc_size); 2288c2ecf20Sopenharmony_ci usage_size = BITS_TO_LONGS(nr_entries) * sizeof(unsigned long); 2298c2ecf20Sopenharmony_ci part = kzalloc(sizeof(*part) + usage_size, GFP_KERNEL); 2308c2ecf20Sopenharmony_ci if (!part) 2318c2ecf20Sopenharmony_ci return ERR_PTR(-ENOMEM); 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ci memcpy(&part->info, info, sizeof(part->info)); 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci if (need_update) 2368c2ecf20Sopenharmony_ci mlxsw_sp1_kvdl_part_update(part, part_prev, resource_size); 2378c2ecf20Sopenharmony_ci return part; 2388c2ecf20Sopenharmony_ci} 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_cistatic void mlxsw_sp1_kvdl_part_fini(struct mlxsw_sp1_kvdl_part *part) 2418c2ecf20Sopenharmony_ci{ 2428c2ecf20Sopenharmony_ci kfree(part); 2438c2ecf20Sopenharmony_ci} 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_cistatic int mlxsw_sp1_kvdl_parts_init(struct mlxsw_sp *mlxsw_sp, 2468c2ecf20Sopenharmony_ci struct mlxsw_sp1_kvdl *kvdl) 2478c2ecf20Sopenharmony_ci{ 2488c2ecf20Sopenharmony_ci const struct mlxsw_sp1_kvdl_part_info *info; 2498c2ecf20Sopenharmony_ci struct mlxsw_sp1_kvdl_part *part_prev = NULL; 2508c2ecf20Sopenharmony_ci int err, i; 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_ci for (i = 0; i < MLXSW_SP1_KVDL_PARTS_INFO_LEN; i++) { 2538c2ecf20Sopenharmony_ci info = &mlxsw_sp1_kvdl_parts_info[i]; 2548c2ecf20Sopenharmony_ci kvdl->parts[i] = mlxsw_sp1_kvdl_part_init(mlxsw_sp, info, 2558c2ecf20Sopenharmony_ci part_prev); 2568c2ecf20Sopenharmony_ci if (IS_ERR(kvdl->parts[i])) { 2578c2ecf20Sopenharmony_ci err = PTR_ERR(kvdl->parts[i]); 2588c2ecf20Sopenharmony_ci goto err_kvdl_part_init; 2598c2ecf20Sopenharmony_ci } 2608c2ecf20Sopenharmony_ci part_prev = kvdl->parts[i]; 2618c2ecf20Sopenharmony_ci } 2628c2ecf20Sopenharmony_ci return 0; 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_cierr_kvdl_part_init: 2658c2ecf20Sopenharmony_ci for (i--; i >= 0; i--) 2668c2ecf20Sopenharmony_ci mlxsw_sp1_kvdl_part_fini(kvdl->parts[i]); 2678c2ecf20Sopenharmony_ci return err; 2688c2ecf20Sopenharmony_ci} 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_cistatic void mlxsw_sp1_kvdl_parts_fini(struct mlxsw_sp1_kvdl *kvdl) 2718c2ecf20Sopenharmony_ci{ 2728c2ecf20Sopenharmony_ci int i; 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci for (i = 0; i < MLXSW_SP1_KVDL_PARTS_INFO_LEN; i++) 2758c2ecf20Sopenharmony_ci mlxsw_sp1_kvdl_part_fini(kvdl->parts[i]); 2768c2ecf20Sopenharmony_ci} 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_cistatic u64 mlxsw_sp1_kvdl_part_occ(struct mlxsw_sp1_kvdl_part *part) 2798c2ecf20Sopenharmony_ci{ 2808c2ecf20Sopenharmony_ci const struct mlxsw_sp1_kvdl_part_info *info = &part->info; 2818c2ecf20Sopenharmony_ci unsigned int nr_entries; 2828c2ecf20Sopenharmony_ci int bit = -1; 2838c2ecf20Sopenharmony_ci u64 occ = 0; 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_ci nr_entries = (info->end_index - 2868c2ecf20Sopenharmony_ci info->start_index + 1) / 2878c2ecf20Sopenharmony_ci info->alloc_size; 2888c2ecf20Sopenharmony_ci while ((bit = find_next_bit(part->usage, nr_entries, bit + 1)) 2898c2ecf20Sopenharmony_ci < nr_entries) 2908c2ecf20Sopenharmony_ci occ += info->alloc_size; 2918c2ecf20Sopenharmony_ci return occ; 2928c2ecf20Sopenharmony_ci} 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_cistatic u64 mlxsw_sp1_kvdl_occ_get(void *priv) 2958c2ecf20Sopenharmony_ci{ 2968c2ecf20Sopenharmony_ci const struct mlxsw_sp1_kvdl *kvdl = priv; 2978c2ecf20Sopenharmony_ci u64 occ = 0; 2988c2ecf20Sopenharmony_ci int i; 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_ci for (i = 0; i < MLXSW_SP1_KVDL_PARTS_INFO_LEN; i++) 3018c2ecf20Sopenharmony_ci occ += mlxsw_sp1_kvdl_part_occ(kvdl->parts[i]); 3028c2ecf20Sopenharmony_ci 3038c2ecf20Sopenharmony_ci return occ; 3048c2ecf20Sopenharmony_ci} 3058c2ecf20Sopenharmony_ci 3068c2ecf20Sopenharmony_cistatic u64 mlxsw_sp1_kvdl_single_occ_get(void *priv) 3078c2ecf20Sopenharmony_ci{ 3088c2ecf20Sopenharmony_ci const struct mlxsw_sp1_kvdl *kvdl = priv; 3098c2ecf20Sopenharmony_ci struct mlxsw_sp1_kvdl_part *part; 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_ci part = kvdl->parts[MLXSW_SP1_KVDL_PART_ID_SINGLE]; 3128c2ecf20Sopenharmony_ci return mlxsw_sp1_kvdl_part_occ(part); 3138c2ecf20Sopenharmony_ci} 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_cistatic u64 mlxsw_sp1_kvdl_chunks_occ_get(void *priv) 3168c2ecf20Sopenharmony_ci{ 3178c2ecf20Sopenharmony_ci const struct mlxsw_sp1_kvdl *kvdl = priv; 3188c2ecf20Sopenharmony_ci struct mlxsw_sp1_kvdl_part *part; 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci part = kvdl->parts[MLXSW_SP1_KVDL_PART_ID_CHUNKS]; 3218c2ecf20Sopenharmony_ci return mlxsw_sp1_kvdl_part_occ(part); 3228c2ecf20Sopenharmony_ci} 3238c2ecf20Sopenharmony_ci 3248c2ecf20Sopenharmony_cistatic u64 mlxsw_sp1_kvdl_large_chunks_occ_get(void *priv) 3258c2ecf20Sopenharmony_ci{ 3268c2ecf20Sopenharmony_ci const struct mlxsw_sp1_kvdl *kvdl = priv; 3278c2ecf20Sopenharmony_ci struct mlxsw_sp1_kvdl_part *part; 3288c2ecf20Sopenharmony_ci 3298c2ecf20Sopenharmony_ci part = kvdl->parts[MLXSW_SP1_KVDL_PART_ID_LARGE_CHUNKS]; 3308c2ecf20Sopenharmony_ci return mlxsw_sp1_kvdl_part_occ(part); 3318c2ecf20Sopenharmony_ci} 3328c2ecf20Sopenharmony_ci 3338c2ecf20Sopenharmony_cistatic int mlxsw_sp1_kvdl_init(struct mlxsw_sp *mlxsw_sp, void *priv) 3348c2ecf20Sopenharmony_ci{ 3358c2ecf20Sopenharmony_ci struct devlink *devlink = priv_to_devlink(mlxsw_sp->core); 3368c2ecf20Sopenharmony_ci struct mlxsw_sp1_kvdl *kvdl = priv; 3378c2ecf20Sopenharmony_ci int err; 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci err = mlxsw_sp1_kvdl_parts_init(mlxsw_sp, kvdl); 3408c2ecf20Sopenharmony_ci if (err) 3418c2ecf20Sopenharmony_ci return err; 3428c2ecf20Sopenharmony_ci devlink_resource_occ_get_register(devlink, 3438c2ecf20Sopenharmony_ci MLXSW_SP_RESOURCE_KVD_LINEAR, 3448c2ecf20Sopenharmony_ci mlxsw_sp1_kvdl_occ_get, 3458c2ecf20Sopenharmony_ci kvdl); 3468c2ecf20Sopenharmony_ci devlink_resource_occ_get_register(devlink, 3478c2ecf20Sopenharmony_ci MLXSW_SP_RESOURCE_KVD_LINEAR_SINGLE, 3488c2ecf20Sopenharmony_ci mlxsw_sp1_kvdl_single_occ_get, 3498c2ecf20Sopenharmony_ci kvdl); 3508c2ecf20Sopenharmony_ci devlink_resource_occ_get_register(devlink, 3518c2ecf20Sopenharmony_ci MLXSW_SP_RESOURCE_KVD_LINEAR_CHUNKS, 3528c2ecf20Sopenharmony_ci mlxsw_sp1_kvdl_chunks_occ_get, 3538c2ecf20Sopenharmony_ci kvdl); 3548c2ecf20Sopenharmony_ci devlink_resource_occ_get_register(devlink, 3558c2ecf20Sopenharmony_ci MLXSW_SP_RESOURCE_KVD_LINEAR_LARGE_CHUNKS, 3568c2ecf20Sopenharmony_ci mlxsw_sp1_kvdl_large_chunks_occ_get, 3578c2ecf20Sopenharmony_ci kvdl); 3588c2ecf20Sopenharmony_ci return 0; 3598c2ecf20Sopenharmony_ci} 3608c2ecf20Sopenharmony_ci 3618c2ecf20Sopenharmony_cistatic void mlxsw_sp1_kvdl_fini(struct mlxsw_sp *mlxsw_sp, void *priv) 3628c2ecf20Sopenharmony_ci{ 3638c2ecf20Sopenharmony_ci struct devlink *devlink = priv_to_devlink(mlxsw_sp->core); 3648c2ecf20Sopenharmony_ci struct mlxsw_sp1_kvdl *kvdl = priv; 3658c2ecf20Sopenharmony_ci 3668c2ecf20Sopenharmony_ci devlink_resource_occ_get_unregister(devlink, 3678c2ecf20Sopenharmony_ci MLXSW_SP_RESOURCE_KVD_LINEAR_LARGE_CHUNKS); 3688c2ecf20Sopenharmony_ci devlink_resource_occ_get_unregister(devlink, 3698c2ecf20Sopenharmony_ci MLXSW_SP_RESOURCE_KVD_LINEAR_CHUNKS); 3708c2ecf20Sopenharmony_ci devlink_resource_occ_get_unregister(devlink, 3718c2ecf20Sopenharmony_ci MLXSW_SP_RESOURCE_KVD_LINEAR_SINGLE); 3728c2ecf20Sopenharmony_ci devlink_resource_occ_get_unregister(devlink, 3738c2ecf20Sopenharmony_ci MLXSW_SP_RESOURCE_KVD_LINEAR); 3748c2ecf20Sopenharmony_ci mlxsw_sp1_kvdl_parts_fini(kvdl); 3758c2ecf20Sopenharmony_ci} 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_ciconst struct mlxsw_sp_kvdl_ops mlxsw_sp1_kvdl_ops = { 3788c2ecf20Sopenharmony_ci .priv_size = sizeof(struct mlxsw_sp1_kvdl), 3798c2ecf20Sopenharmony_ci .init = mlxsw_sp1_kvdl_init, 3808c2ecf20Sopenharmony_ci .fini = mlxsw_sp1_kvdl_fini, 3818c2ecf20Sopenharmony_ci .alloc = mlxsw_sp1_kvdl_alloc, 3828c2ecf20Sopenharmony_ci .free = mlxsw_sp1_kvdl_free, 3838c2ecf20Sopenharmony_ci .alloc_size_query = mlxsw_sp1_kvdl_alloc_size_query, 3848c2ecf20Sopenharmony_ci}; 3858c2ecf20Sopenharmony_ci 3868c2ecf20Sopenharmony_ciint mlxsw_sp1_kvdl_resources_register(struct mlxsw_core *mlxsw_core) 3878c2ecf20Sopenharmony_ci{ 3888c2ecf20Sopenharmony_ci struct devlink *devlink = priv_to_devlink(mlxsw_core); 3898c2ecf20Sopenharmony_ci static struct devlink_resource_size_params size_params; 3908c2ecf20Sopenharmony_ci u32 kvdl_max_size; 3918c2ecf20Sopenharmony_ci int err; 3928c2ecf20Sopenharmony_ci 3938c2ecf20Sopenharmony_ci kvdl_max_size = MLXSW_CORE_RES_GET(mlxsw_core, KVD_SIZE) - 3948c2ecf20Sopenharmony_ci MLXSW_CORE_RES_GET(mlxsw_core, KVD_SINGLE_MIN_SIZE) - 3958c2ecf20Sopenharmony_ci MLXSW_CORE_RES_GET(mlxsw_core, KVD_DOUBLE_MIN_SIZE); 3968c2ecf20Sopenharmony_ci 3978c2ecf20Sopenharmony_ci devlink_resource_size_params_init(&size_params, 0, kvdl_max_size, 3988c2ecf20Sopenharmony_ci MLXSW_SP1_KVDL_SINGLE_ALLOC_SIZE, 3998c2ecf20Sopenharmony_ci DEVLINK_RESOURCE_UNIT_ENTRY); 4008c2ecf20Sopenharmony_ci err = devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD_LINEAR_SINGLES, 4018c2ecf20Sopenharmony_ci MLXSW_SP1_KVDL_SINGLE_SIZE, 4028c2ecf20Sopenharmony_ci MLXSW_SP_RESOURCE_KVD_LINEAR_SINGLE, 4038c2ecf20Sopenharmony_ci MLXSW_SP_RESOURCE_KVD_LINEAR, 4048c2ecf20Sopenharmony_ci &size_params); 4058c2ecf20Sopenharmony_ci if (err) 4068c2ecf20Sopenharmony_ci return err; 4078c2ecf20Sopenharmony_ci 4088c2ecf20Sopenharmony_ci devlink_resource_size_params_init(&size_params, 0, kvdl_max_size, 4098c2ecf20Sopenharmony_ci MLXSW_SP1_KVDL_CHUNKS_ALLOC_SIZE, 4108c2ecf20Sopenharmony_ci DEVLINK_RESOURCE_UNIT_ENTRY); 4118c2ecf20Sopenharmony_ci err = devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD_LINEAR_CHUNKS, 4128c2ecf20Sopenharmony_ci MLXSW_SP1_KVDL_CHUNKS_SIZE, 4138c2ecf20Sopenharmony_ci MLXSW_SP_RESOURCE_KVD_LINEAR_CHUNKS, 4148c2ecf20Sopenharmony_ci MLXSW_SP_RESOURCE_KVD_LINEAR, 4158c2ecf20Sopenharmony_ci &size_params); 4168c2ecf20Sopenharmony_ci if (err) 4178c2ecf20Sopenharmony_ci return err; 4188c2ecf20Sopenharmony_ci 4198c2ecf20Sopenharmony_ci devlink_resource_size_params_init(&size_params, 0, kvdl_max_size, 4208c2ecf20Sopenharmony_ci MLXSW_SP1_KVDL_LARGE_CHUNKS_ALLOC_SIZE, 4218c2ecf20Sopenharmony_ci DEVLINK_RESOURCE_UNIT_ENTRY); 4228c2ecf20Sopenharmony_ci err = devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD_LINEAR_LARGE_CHUNKS, 4238c2ecf20Sopenharmony_ci MLXSW_SP1_KVDL_LARGE_CHUNKS_SIZE, 4248c2ecf20Sopenharmony_ci MLXSW_SP_RESOURCE_KVD_LINEAR_LARGE_CHUNKS, 4258c2ecf20Sopenharmony_ci MLXSW_SP_RESOURCE_KVD_LINEAR, 4268c2ecf20Sopenharmony_ci &size_params); 4278c2ecf20Sopenharmony_ci return err; 4288c2ecf20Sopenharmony_ci} 429