18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* Copyright (c) 2015-2018 Mellanox Technologies. All rights reserved */ 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci#ifndef _MLXSW_ITEM_H 58c2ecf20Sopenharmony_ci#define _MLXSW_ITEM_H 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include <linux/types.h> 88c2ecf20Sopenharmony_ci#include <linux/string.h> 98c2ecf20Sopenharmony_ci#include <linux/bitops.h> 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_cistruct mlxsw_item { 128c2ecf20Sopenharmony_ci unsigned short offset; /* bytes in container */ 138c2ecf20Sopenharmony_ci short step; /* step in bytes for indexed items */ 148c2ecf20Sopenharmony_ci unsigned short in_step_offset; /* offset within one step */ 158c2ecf20Sopenharmony_ci unsigned char shift; /* shift in bits */ 168c2ecf20Sopenharmony_ci unsigned char element_size; /* size of element in bit array */ 178c2ecf20Sopenharmony_ci bool no_real_shift; 188c2ecf20Sopenharmony_ci union { 198c2ecf20Sopenharmony_ci unsigned char bits; 208c2ecf20Sopenharmony_ci unsigned short bytes; 218c2ecf20Sopenharmony_ci } size; 228c2ecf20Sopenharmony_ci const char *name; 238c2ecf20Sopenharmony_ci}; 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_cistatic inline unsigned int 268c2ecf20Sopenharmony_ci__mlxsw_item_offset(const struct mlxsw_item *item, unsigned short index, 278c2ecf20Sopenharmony_ci size_t typesize) 288c2ecf20Sopenharmony_ci{ 298c2ecf20Sopenharmony_ci BUG_ON(index && !item->step); 308c2ecf20Sopenharmony_ci if (item->offset % typesize != 0 || 318c2ecf20Sopenharmony_ci item->step % typesize != 0 || 328c2ecf20Sopenharmony_ci item->in_step_offset % typesize != 0) { 338c2ecf20Sopenharmony_ci pr_err("mlxsw: item bug (name=%s,offset=%x,step=%x,in_step_offset=%x,typesize=%zx)\n", 348c2ecf20Sopenharmony_ci item->name, item->offset, item->step, 358c2ecf20Sopenharmony_ci item->in_step_offset, typesize); 368c2ecf20Sopenharmony_ci BUG(); 378c2ecf20Sopenharmony_ci } 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci return ((item->offset + item->step * index + item->in_step_offset) / 408c2ecf20Sopenharmony_ci typesize); 418c2ecf20Sopenharmony_ci} 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_cistatic inline u8 __mlxsw_item_get8(const char *buf, 448c2ecf20Sopenharmony_ci const struct mlxsw_item *item, 458c2ecf20Sopenharmony_ci unsigned short index) 468c2ecf20Sopenharmony_ci{ 478c2ecf20Sopenharmony_ci unsigned int offset = __mlxsw_item_offset(item, index, sizeof(u8)); 488c2ecf20Sopenharmony_ci u8 *b = (u8 *) buf; 498c2ecf20Sopenharmony_ci u8 tmp; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci tmp = b[offset]; 528c2ecf20Sopenharmony_ci tmp >>= item->shift; 538c2ecf20Sopenharmony_ci tmp &= GENMASK(item->size.bits - 1, 0); 548c2ecf20Sopenharmony_ci if (item->no_real_shift) 558c2ecf20Sopenharmony_ci tmp <<= item->shift; 568c2ecf20Sopenharmony_ci return tmp; 578c2ecf20Sopenharmony_ci} 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_cistatic inline void __mlxsw_item_set8(char *buf, const struct mlxsw_item *item, 608c2ecf20Sopenharmony_ci unsigned short index, u8 val) 618c2ecf20Sopenharmony_ci{ 628c2ecf20Sopenharmony_ci unsigned int offset = __mlxsw_item_offset(item, index, 638c2ecf20Sopenharmony_ci sizeof(u8)); 648c2ecf20Sopenharmony_ci u8 *b = (u8 *) buf; 658c2ecf20Sopenharmony_ci u8 mask = GENMASK(item->size.bits - 1, 0) << item->shift; 668c2ecf20Sopenharmony_ci u8 tmp; 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci if (!item->no_real_shift) 698c2ecf20Sopenharmony_ci val <<= item->shift; 708c2ecf20Sopenharmony_ci val &= mask; 718c2ecf20Sopenharmony_ci tmp = b[offset]; 728c2ecf20Sopenharmony_ci tmp &= ~mask; 738c2ecf20Sopenharmony_ci tmp |= val; 748c2ecf20Sopenharmony_ci b[offset] = tmp; 758c2ecf20Sopenharmony_ci} 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_cistatic inline u16 __mlxsw_item_get16(const char *buf, 788c2ecf20Sopenharmony_ci const struct mlxsw_item *item, 798c2ecf20Sopenharmony_ci unsigned short index) 808c2ecf20Sopenharmony_ci{ 818c2ecf20Sopenharmony_ci unsigned int offset = __mlxsw_item_offset(item, index, sizeof(u16)); 828c2ecf20Sopenharmony_ci __be16 *b = (__be16 *) buf; 838c2ecf20Sopenharmony_ci u16 tmp; 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci tmp = be16_to_cpu(b[offset]); 868c2ecf20Sopenharmony_ci tmp >>= item->shift; 878c2ecf20Sopenharmony_ci tmp &= GENMASK(item->size.bits - 1, 0); 888c2ecf20Sopenharmony_ci if (item->no_real_shift) 898c2ecf20Sopenharmony_ci tmp <<= item->shift; 908c2ecf20Sopenharmony_ci return tmp; 918c2ecf20Sopenharmony_ci} 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_cistatic inline void __mlxsw_item_set16(char *buf, const struct mlxsw_item *item, 948c2ecf20Sopenharmony_ci unsigned short index, u16 val) 958c2ecf20Sopenharmony_ci{ 968c2ecf20Sopenharmony_ci unsigned int offset = __mlxsw_item_offset(item, index, 978c2ecf20Sopenharmony_ci sizeof(u16)); 988c2ecf20Sopenharmony_ci __be16 *b = (__be16 *) buf; 998c2ecf20Sopenharmony_ci u16 mask = GENMASK(item->size.bits - 1, 0) << item->shift; 1008c2ecf20Sopenharmony_ci u16 tmp; 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci if (!item->no_real_shift) 1038c2ecf20Sopenharmony_ci val <<= item->shift; 1048c2ecf20Sopenharmony_ci val &= mask; 1058c2ecf20Sopenharmony_ci tmp = be16_to_cpu(b[offset]); 1068c2ecf20Sopenharmony_ci tmp &= ~mask; 1078c2ecf20Sopenharmony_ci tmp |= val; 1088c2ecf20Sopenharmony_ci b[offset] = cpu_to_be16(tmp); 1098c2ecf20Sopenharmony_ci} 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_cistatic inline u32 __mlxsw_item_get32(const char *buf, 1128c2ecf20Sopenharmony_ci const struct mlxsw_item *item, 1138c2ecf20Sopenharmony_ci unsigned short index) 1148c2ecf20Sopenharmony_ci{ 1158c2ecf20Sopenharmony_ci unsigned int offset = __mlxsw_item_offset(item, index, sizeof(u32)); 1168c2ecf20Sopenharmony_ci __be32 *b = (__be32 *) buf; 1178c2ecf20Sopenharmony_ci u32 tmp; 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci tmp = be32_to_cpu(b[offset]); 1208c2ecf20Sopenharmony_ci tmp >>= item->shift; 1218c2ecf20Sopenharmony_ci tmp &= GENMASK(item->size.bits - 1, 0); 1228c2ecf20Sopenharmony_ci if (item->no_real_shift) 1238c2ecf20Sopenharmony_ci tmp <<= item->shift; 1248c2ecf20Sopenharmony_ci return tmp; 1258c2ecf20Sopenharmony_ci} 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_cistatic inline void __mlxsw_item_set32(char *buf, const struct mlxsw_item *item, 1288c2ecf20Sopenharmony_ci unsigned short index, u32 val) 1298c2ecf20Sopenharmony_ci{ 1308c2ecf20Sopenharmony_ci unsigned int offset = __mlxsw_item_offset(item, index, 1318c2ecf20Sopenharmony_ci sizeof(u32)); 1328c2ecf20Sopenharmony_ci __be32 *b = (__be32 *) buf; 1338c2ecf20Sopenharmony_ci u32 mask = GENMASK(item->size.bits - 1, 0) << item->shift; 1348c2ecf20Sopenharmony_ci u32 tmp; 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci if (!item->no_real_shift) 1378c2ecf20Sopenharmony_ci val <<= item->shift; 1388c2ecf20Sopenharmony_ci val &= mask; 1398c2ecf20Sopenharmony_ci tmp = be32_to_cpu(b[offset]); 1408c2ecf20Sopenharmony_ci tmp &= ~mask; 1418c2ecf20Sopenharmony_ci tmp |= val; 1428c2ecf20Sopenharmony_ci b[offset] = cpu_to_be32(tmp); 1438c2ecf20Sopenharmony_ci} 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_cistatic inline u64 __mlxsw_item_get64(const char *buf, 1468c2ecf20Sopenharmony_ci const struct mlxsw_item *item, 1478c2ecf20Sopenharmony_ci unsigned short index) 1488c2ecf20Sopenharmony_ci{ 1498c2ecf20Sopenharmony_ci unsigned int offset = __mlxsw_item_offset(item, index, sizeof(u64)); 1508c2ecf20Sopenharmony_ci __be64 *b = (__be64 *) buf; 1518c2ecf20Sopenharmony_ci u64 tmp; 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci tmp = be64_to_cpu(b[offset]); 1548c2ecf20Sopenharmony_ci tmp >>= item->shift; 1558c2ecf20Sopenharmony_ci tmp &= GENMASK_ULL(item->size.bits - 1, 0); 1568c2ecf20Sopenharmony_ci if (item->no_real_shift) 1578c2ecf20Sopenharmony_ci tmp <<= item->shift; 1588c2ecf20Sopenharmony_ci return tmp; 1598c2ecf20Sopenharmony_ci} 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_cistatic inline void __mlxsw_item_set64(char *buf, const struct mlxsw_item *item, 1628c2ecf20Sopenharmony_ci unsigned short index, u64 val) 1638c2ecf20Sopenharmony_ci{ 1648c2ecf20Sopenharmony_ci unsigned int offset = __mlxsw_item_offset(item, index, sizeof(u64)); 1658c2ecf20Sopenharmony_ci __be64 *b = (__be64 *) buf; 1668c2ecf20Sopenharmony_ci u64 mask = GENMASK_ULL(item->size.bits - 1, 0) << item->shift; 1678c2ecf20Sopenharmony_ci u64 tmp; 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_ci if (!item->no_real_shift) 1708c2ecf20Sopenharmony_ci val <<= item->shift; 1718c2ecf20Sopenharmony_ci val &= mask; 1728c2ecf20Sopenharmony_ci tmp = be64_to_cpu(b[offset]); 1738c2ecf20Sopenharmony_ci tmp &= ~mask; 1748c2ecf20Sopenharmony_ci tmp |= val; 1758c2ecf20Sopenharmony_ci b[offset] = cpu_to_be64(tmp); 1768c2ecf20Sopenharmony_ci} 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_cistatic inline void __mlxsw_item_memcpy_from(const char *buf, char *dst, 1798c2ecf20Sopenharmony_ci const struct mlxsw_item *item, 1808c2ecf20Sopenharmony_ci unsigned short index) 1818c2ecf20Sopenharmony_ci{ 1828c2ecf20Sopenharmony_ci unsigned int offset = __mlxsw_item_offset(item, index, sizeof(char)); 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci memcpy(dst, &buf[offset], item->size.bytes); 1858c2ecf20Sopenharmony_ci} 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_cistatic inline void __mlxsw_item_memcpy_to(char *buf, const char *src, 1888c2ecf20Sopenharmony_ci const struct mlxsw_item *item, 1898c2ecf20Sopenharmony_ci unsigned short index) 1908c2ecf20Sopenharmony_ci{ 1918c2ecf20Sopenharmony_ci unsigned int offset = __mlxsw_item_offset(item, index, sizeof(char)); 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_ci memcpy(&buf[offset], src, item->size.bytes); 1948c2ecf20Sopenharmony_ci} 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_cistatic inline char *__mlxsw_item_data(char *buf, const struct mlxsw_item *item, 1978c2ecf20Sopenharmony_ci unsigned short index) 1988c2ecf20Sopenharmony_ci{ 1998c2ecf20Sopenharmony_ci unsigned int offset = __mlxsw_item_offset(item, index, sizeof(char)); 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ci return &buf[offset]; 2028c2ecf20Sopenharmony_ci} 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_cistatic inline u16 2058c2ecf20Sopenharmony_ci__mlxsw_item_bit_array_offset(const struct mlxsw_item *item, 2068c2ecf20Sopenharmony_ci u16 index, u8 *shift) 2078c2ecf20Sopenharmony_ci{ 2088c2ecf20Sopenharmony_ci u16 max_index, be_index; 2098c2ecf20Sopenharmony_ci u16 offset; /* byte offset inside the array */ 2108c2ecf20Sopenharmony_ci u8 in_byte_index; 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_ci BUG_ON(index && !item->element_size); 2138c2ecf20Sopenharmony_ci if (item->offset % sizeof(u32) != 0 || 2148c2ecf20Sopenharmony_ci BITS_PER_BYTE % item->element_size != 0) { 2158c2ecf20Sopenharmony_ci pr_err("mlxsw: item bug (name=%s,offset=%x,element_size=%x)\n", 2168c2ecf20Sopenharmony_ci item->name, item->offset, item->element_size); 2178c2ecf20Sopenharmony_ci BUG(); 2188c2ecf20Sopenharmony_ci } 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ci max_index = (item->size.bytes << 3) / item->element_size - 1; 2218c2ecf20Sopenharmony_ci be_index = max_index - index; 2228c2ecf20Sopenharmony_ci offset = be_index * item->element_size >> 3; 2238c2ecf20Sopenharmony_ci in_byte_index = index % (BITS_PER_BYTE / item->element_size); 2248c2ecf20Sopenharmony_ci *shift = in_byte_index * item->element_size; 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci return item->offset + offset; 2278c2ecf20Sopenharmony_ci} 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_cistatic inline u8 __mlxsw_item_bit_array_get(const char *buf, 2308c2ecf20Sopenharmony_ci const struct mlxsw_item *item, 2318c2ecf20Sopenharmony_ci u16 index) 2328c2ecf20Sopenharmony_ci{ 2338c2ecf20Sopenharmony_ci u8 shift, tmp; 2348c2ecf20Sopenharmony_ci u16 offset = __mlxsw_item_bit_array_offset(item, index, &shift); 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci tmp = buf[offset]; 2378c2ecf20Sopenharmony_ci tmp >>= shift; 2388c2ecf20Sopenharmony_ci tmp &= GENMASK(item->element_size - 1, 0); 2398c2ecf20Sopenharmony_ci return tmp; 2408c2ecf20Sopenharmony_ci} 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_cistatic inline void __mlxsw_item_bit_array_set(char *buf, 2438c2ecf20Sopenharmony_ci const struct mlxsw_item *item, 2448c2ecf20Sopenharmony_ci u16 index, u8 val) 2458c2ecf20Sopenharmony_ci{ 2468c2ecf20Sopenharmony_ci u8 shift, tmp; 2478c2ecf20Sopenharmony_ci u16 offset = __mlxsw_item_bit_array_offset(item, index, &shift); 2488c2ecf20Sopenharmony_ci u8 mask = GENMASK(item->element_size - 1, 0) << shift; 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_ci val <<= shift; 2518c2ecf20Sopenharmony_ci val &= mask; 2528c2ecf20Sopenharmony_ci tmp = buf[offset]; 2538c2ecf20Sopenharmony_ci tmp &= ~mask; 2548c2ecf20Sopenharmony_ci tmp |= val; 2558c2ecf20Sopenharmony_ci buf[offset] = tmp; 2568c2ecf20Sopenharmony_ci} 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ci#define __ITEM_NAME(_type, _cname, _iname) \ 2598c2ecf20Sopenharmony_ci mlxsw_##_type##_##_cname##_##_iname##_item 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_ci/* _type: cmd_mbox, reg, etc. 2628c2ecf20Sopenharmony_ci * _cname: containter name (e.g. command name, register name) 2638c2ecf20Sopenharmony_ci * _iname: item name within the container 2648c2ecf20Sopenharmony_ci */ 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_ci#define MLXSW_ITEM8(_type, _cname, _iname, _offset, _shift, _sizebits) \ 2678c2ecf20Sopenharmony_cistatic struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ 2688c2ecf20Sopenharmony_ci .offset = _offset, \ 2698c2ecf20Sopenharmony_ci .shift = _shift, \ 2708c2ecf20Sopenharmony_ci .size = {.bits = _sizebits,}, \ 2718c2ecf20Sopenharmony_ci .name = #_type "_" #_cname "_" #_iname, \ 2728c2ecf20Sopenharmony_ci}; \ 2738c2ecf20Sopenharmony_cistatic inline u8 mlxsw_##_type##_##_cname##_##_iname##_get(const char *buf) \ 2748c2ecf20Sopenharmony_ci{ \ 2758c2ecf20Sopenharmony_ci return __mlxsw_item_get8(buf, &__ITEM_NAME(_type, _cname, _iname), 0); \ 2768c2ecf20Sopenharmony_ci} \ 2778c2ecf20Sopenharmony_cistatic inline void mlxsw_##_type##_##_cname##_##_iname##_set(char *buf, u8 val)\ 2788c2ecf20Sopenharmony_ci{ \ 2798c2ecf20Sopenharmony_ci __mlxsw_item_set8(buf, &__ITEM_NAME(_type, _cname, _iname), 0, val); \ 2808c2ecf20Sopenharmony_ci} 2818c2ecf20Sopenharmony_ci 2828c2ecf20Sopenharmony_ci#define MLXSW_ITEM8_INDEXED(_type, _cname, _iname, _offset, _shift, _sizebits, \ 2838c2ecf20Sopenharmony_ci _step, _instepoffset, _norealshift) \ 2848c2ecf20Sopenharmony_cistatic struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ 2858c2ecf20Sopenharmony_ci .offset = _offset, \ 2868c2ecf20Sopenharmony_ci .step = _step, \ 2878c2ecf20Sopenharmony_ci .in_step_offset = _instepoffset, \ 2888c2ecf20Sopenharmony_ci .shift = _shift, \ 2898c2ecf20Sopenharmony_ci .no_real_shift = _norealshift, \ 2908c2ecf20Sopenharmony_ci .size = {.bits = _sizebits,}, \ 2918c2ecf20Sopenharmony_ci .name = #_type "_" #_cname "_" #_iname, \ 2928c2ecf20Sopenharmony_ci}; \ 2938c2ecf20Sopenharmony_cistatic inline u8 \ 2948c2ecf20Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_get(const char *buf, unsigned short index)\ 2958c2ecf20Sopenharmony_ci{ \ 2968c2ecf20Sopenharmony_ci return __mlxsw_item_get8(buf, &__ITEM_NAME(_type, _cname, _iname), \ 2978c2ecf20Sopenharmony_ci index); \ 2988c2ecf20Sopenharmony_ci} \ 2998c2ecf20Sopenharmony_cistatic inline void \ 3008c2ecf20Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_set(char *buf, unsigned short index, \ 3018c2ecf20Sopenharmony_ci u8 val) \ 3028c2ecf20Sopenharmony_ci{ \ 3038c2ecf20Sopenharmony_ci __mlxsw_item_set8(buf, &__ITEM_NAME(_type, _cname, _iname), \ 3048c2ecf20Sopenharmony_ci index, val); \ 3058c2ecf20Sopenharmony_ci} 3068c2ecf20Sopenharmony_ci 3078c2ecf20Sopenharmony_ci#define MLXSW_ITEM16(_type, _cname, _iname, _offset, _shift, _sizebits) \ 3088c2ecf20Sopenharmony_cistatic struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ 3098c2ecf20Sopenharmony_ci .offset = _offset, \ 3108c2ecf20Sopenharmony_ci .shift = _shift, \ 3118c2ecf20Sopenharmony_ci .size = {.bits = _sizebits,}, \ 3128c2ecf20Sopenharmony_ci .name = #_type "_" #_cname "_" #_iname, \ 3138c2ecf20Sopenharmony_ci}; \ 3148c2ecf20Sopenharmony_cistatic inline u16 mlxsw_##_type##_##_cname##_##_iname##_get(const char *buf) \ 3158c2ecf20Sopenharmony_ci{ \ 3168c2ecf20Sopenharmony_ci return __mlxsw_item_get16(buf, &__ITEM_NAME(_type, _cname, _iname), 0); \ 3178c2ecf20Sopenharmony_ci} \ 3188c2ecf20Sopenharmony_cistatic inline void mlxsw_##_type##_##_cname##_##_iname##_set(char *buf, u16 val)\ 3198c2ecf20Sopenharmony_ci{ \ 3208c2ecf20Sopenharmony_ci __mlxsw_item_set16(buf, &__ITEM_NAME(_type, _cname, _iname), 0, val); \ 3218c2ecf20Sopenharmony_ci} 3228c2ecf20Sopenharmony_ci 3238c2ecf20Sopenharmony_ci#define MLXSW_ITEM16_INDEXED(_type, _cname, _iname, _offset, _shift, _sizebits, \ 3248c2ecf20Sopenharmony_ci _step, _instepoffset, _norealshift) \ 3258c2ecf20Sopenharmony_cistatic struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ 3268c2ecf20Sopenharmony_ci .offset = _offset, \ 3278c2ecf20Sopenharmony_ci .step = _step, \ 3288c2ecf20Sopenharmony_ci .in_step_offset = _instepoffset, \ 3298c2ecf20Sopenharmony_ci .shift = _shift, \ 3308c2ecf20Sopenharmony_ci .no_real_shift = _norealshift, \ 3318c2ecf20Sopenharmony_ci .size = {.bits = _sizebits,}, \ 3328c2ecf20Sopenharmony_ci .name = #_type "_" #_cname "_" #_iname, \ 3338c2ecf20Sopenharmony_ci}; \ 3348c2ecf20Sopenharmony_cistatic inline u16 \ 3358c2ecf20Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_get(const char *buf, unsigned short index)\ 3368c2ecf20Sopenharmony_ci{ \ 3378c2ecf20Sopenharmony_ci return __mlxsw_item_get16(buf, &__ITEM_NAME(_type, _cname, _iname), \ 3388c2ecf20Sopenharmony_ci index); \ 3398c2ecf20Sopenharmony_ci} \ 3408c2ecf20Sopenharmony_cistatic inline void \ 3418c2ecf20Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_set(char *buf, unsigned short index, \ 3428c2ecf20Sopenharmony_ci u16 val) \ 3438c2ecf20Sopenharmony_ci{ \ 3448c2ecf20Sopenharmony_ci __mlxsw_item_set16(buf, &__ITEM_NAME(_type, _cname, _iname), \ 3458c2ecf20Sopenharmony_ci index, val); \ 3468c2ecf20Sopenharmony_ci} 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_ci#define MLXSW_ITEM32(_type, _cname, _iname, _offset, _shift, _sizebits) \ 3498c2ecf20Sopenharmony_cistatic struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ 3508c2ecf20Sopenharmony_ci .offset = _offset, \ 3518c2ecf20Sopenharmony_ci .shift = _shift, \ 3528c2ecf20Sopenharmony_ci .size = {.bits = _sizebits,}, \ 3538c2ecf20Sopenharmony_ci .name = #_type "_" #_cname "_" #_iname, \ 3548c2ecf20Sopenharmony_ci}; \ 3558c2ecf20Sopenharmony_cistatic inline u32 mlxsw_##_type##_##_cname##_##_iname##_get(const char *buf) \ 3568c2ecf20Sopenharmony_ci{ \ 3578c2ecf20Sopenharmony_ci return __mlxsw_item_get32(buf, &__ITEM_NAME(_type, _cname, _iname), 0); \ 3588c2ecf20Sopenharmony_ci} \ 3598c2ecf20Sopenharmony_cistatic inline void mlxsw_##_type##_##_cname##_##_iname##_set(char *buf, u32 val)\ 3608c2ecf20Sopenharmony_ci{ \ 3618c2ecf20Sopenharmony_ci __mlxsw_item_set32(buf, &__ITEM_NAME(_type, _cname, _iname), 0, val); \ 3628c2ecf20Sopenharmony_ci} 3638c2ecf20Sopenharmony_ci 3648c2ecf20Sopenharmony_ci#define MLXSW_ITEM32_INDEXED(_type, _cname, _iname, _offset, _shift, _sizebits, \ 3658c2ecf20Sopenharmony_ci _step, _instepoffset, _norealshift) \ 3668c2ecf20Sopenharmony_cistatic struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ 3678c2ecf20Sopenharmony_ci .offset = _offset, \ 3688c2ecf20Sopenharmony_ci .step = _step, \ 3698c2ecf20Sopenharmony_ci .in_step_offset = _instepoffset, \ 3708c2ecf20Sopenharmony_ci .shift = _shift, \ 3718c2ecf20Sopenharmony_ci .no_real_shift = _norealshift, \ 3728c2ecf20Sopenharmony_ci .size = {.bits = _sizebits,}, \ 3738c2ecf20Sopenharmony_ci .name = #_type "_" #_cname "_" #_iname, \ 3748c2ecf20Sopenharmony_ci}; \ 3758c2ecf20Sopenharmony_cistatic inline u32 \ 3768c2ecf20Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_get(const char *buf, unsigned short index)\ 3778c2ecf20Sopenharmony_ci{ \ 3788c2ecf20Sopenharmony_ci return __mlxsw_item_get32(buf, &__ITEM_NAME(_type, _cname, _iname), \ 3798c2ecf20Sopenharmony_ci index); \ 3808c2ecf20Sopenharmony_ci} \ 3818c2ecf20Sopenharmony_cistatic inline void \ 3828c2ecf20Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_set(char *buf, unsigned short index, \ 3838c2ecf20Sopenharmony_ci u32 val) \ 3848c2ecf20Sopenharmony_ci{ \ 3858c2ecf20Sopenharmony_ci __mlxsw_item_set32(buf, &__ITEM_NAME(_type, _cname, _iname), \ 3868c2ecf20Sopenharmony_ci index, val); \ 3878c2ecf20Sopenharmony_ci} 3888c2ecf20Sopenharmony_ci 3898c2ecf20Sopenharmony_ci#define MLXSW_ITEM64(_type, _cname, _iname, _offset, _shift, _sizebits) \ 3908c2ecf20Sopenharmony_cistatic struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ 3918c2ecf20Sopenharmony_ci .offset = _offset, \ 3928c2ecf20Sopenharmony_ci .shift = _shift, \ 3938c2ecf20Sopenharmony_ci .size = {.bits = _sizebits,}, \ 3948c2ecf20Sopenharmony_ci .name = #_type "_" #_cname "_" #_iname, \ 3958c2ecf20Sopenharmony_ci}; \ 3968c2ecf20Sopenharmony_cistatic inline u64 mlxsw_##_type##_##_cname##_##_iname##_get(const char *buf) \ 3978c2ecf20Sopenharmony_ci{ \ 3988c2ecf20Sopenharmony_ci return __mlxsw_item_get64(buf, &__ITEM_NAME(_type, _cname, _iname), 0); \ 3998c2ecf20Sopenharmony_ci} \ 4008c2ecf20Sopenharmony_cistatic inline void mlxsw_##_type##_##_cname##_##_iname##_set(char *buf, u64 val)\ 4018c2ecf20Sopenharmony_ci{ \ 4028c2ecf20Sopenharmony_ci __mlxsw_item_set64(buf, &__ITEM_NAME(_type, _cname, _iname), 0, val); \ 4038c2ecf20Sopenharmony_ci} 4048c2ecf20Sopenharmony_ci 4058c2ecf20Sopenharmony_ci#define MLXSW_ITEM64_INDEXED(_type, _cname, _iname, _offset, _shift, \ 4068c2ecf20Sopenharmony_ci _sizebits, _step, _instepoffset, _norealshift) \ 4078c2ecf20Sopenharmony_cistatic struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ 4088c2ecf20Sopenharmony_ci .offset = _offset, \ 4098c2ecf20Sopenharmony_ci .step = _step, \ 4108c2ecf20Sopenharmony_ci .in_step_offset = _instepoffset, \ 4118c2ecf20Sopenharmony_ci .shift = _shift, \ 4128c2ecf20Sopenharmony_ci .no_real_shift = _norealshift, \ 4138c2ecf20Sopenharmony_ci .size = {.bits = _sizebits,}, \ 4148c2ecf20Sopenharmony_ci .name = #_type "_" #_cname "_" #_iname, \ 4158c2ecf20Sopenharmony_ci}; \ 4168c2ecf20Sopenharmony_cistatic inline u64 \ 4178c2ecf20Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_get(const char *buf, unsigned short index)\ 4188c2ecf20Sopenharmony_ci{ \ 4198c2ecf20Sopenharmony_ci return __mlxsw_item_get64(buf, &__ITEM_NAME(_type, _cname, _iname), \ 4208c2ecf20Sopenharmony_ci index); \ 4218c2ecf20Sopenharmony_ci} \ 4228c2ecf20Sopenharmony_cistatic inline void \ 4238c2ecf20Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_set(char *buf, unsigned short index, \ 4248c2ecf20Sopenharmony_ci u64 val) \ 4258c2ecf20Sopenharmony_ci{ \ 4268c2ecf20Sopenharmony_ci __mlxsw_item_set64(buf, &__ITEM_NAME(_type, _cname, _iname), \ 4278c2ecf20Sopenharmony_ci index, val); \ 4288c2ecf20Sopenharmony_ci} 4298c2ecf20Sopenharmony_ci 4308c2ecf20Sopenharmony_ci#define MLXSW_ITEM_BUF(_type, _cname, _iname, _offset, _sizebytes) \ 4318c2ecf20Sopenharmony_cistatic struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ 4328c2ecf20Sopenharmony_ci .offset = _offset, \ 4338c2ecf20Sopenharmony_ci .size = {.bytes = _sizebytes,}, \ 4348c2ecf20Sopenharmony_ci .name = #_type "_" #_cname "_" #_iname, \ 4358c2ecf20Sopenharmony_ci}; \ 4368c2ecf20Sopenharmony_cistatic inline void \ 4378c2ecf20Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_memcpy_from(const char *buf, char *dst) \ 4388c2ecf20Sopenharmony_ci{ \ 4398c2ecf20Sopenharmony_ci __mlxsw_item_memcpy_from(buf, dst, \ 4408c2ecf20Sopenharmony_ci &__ITEM_NAME(_type, _cname, _iname), 0); \ 4418c2ecf20Sopenharmony_ci} \ 4428c2ecf20Sopenharmony_cistatic inline void \ 4438c2ecf20Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_memcpy_to(char *buf, const char *src) \ 4448c2ecf20Sopenharmony_ci{ \ 4458c2ecf20Sopenharmony_ci __mlxsw_item_memcpy_to(buf, src, \ 4468c2ecf20Sopenharmony_ci &__ITEM_NAME(_type, _cname, _iname), 0); \ 4478c2ecf20Sopenharmony_ci} \ 4488c2ecf20Sopenharmony_cistatic inline char * \ 4498c2ecf20Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_data(char *buf) \ 4508c2ecf20Sopenharmony_ci{ \ 4518c2ecf20Sopenharmony_ci return __mlxsw_item_data(buf, &__ITEM_NAME(_type, _cname, _iname), 0); \ 4528c2ecf20Sopenharmony_ci} 4538c2ecf20Sopenharmony_ci 4548c2ecf20Sopenharmony_ci#define MLXSW_ITEM_BUF_INDEXED(_type, _cname, _iname, _offset, _sizebytes, \ 4558c2ecf20Sopenharmony_ci _step, _instepoffset) \ 4568c2ecf20Sopenharmony_cistatic struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ 4578c2ecf20Sopenharmony_ci .offset = _offset, \ 4588c2ecf20Sopenharmony_ci .step = _step, \ 4598c2ecf20Sopenharmony_ci .in_step_offset = _instepoffset, \ 4608c2ecf20Sopenharmony_ci .size = {.bytes = _sizebytes,}, \ 4618c2ecf20Sopenharmony_ci .name = #_type "_" #_cname "_" #_iname, \ 4628c2ecf20Sopenharmony_ci}; \ 4638c2ecf20Sopenharmony_cistatic inline void \ 4648c2ecf20Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_memcpy_from(const char *buf, \ 4658c2ecf20Sopenharmony_ci unsigned short index, \ 4668c2ecf20Sopenharmony_ci char *dst) \ 4678c2ecf20Sopenharmony_ci{ \ 4688c2ecf20Sopenharmony_ci __mlxsw_item_memcpy_from(buf, dst, \ 4698c2ecf20Sopenharmony_ci &__ITEM_NAME(_type, _cname, _iname), index); \ 4708c2ecf20Sopenharmony_ci} \ 4718c2ecf20Sopenharmony_cistatic inline void \ 4728c2ecf20Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_memcpy_to(char *buf, \ 4738c2ecf20Sopenharmony_ci unsigned short index, \ 4748c2ecf20Sopenharmony_ci const char *src) \ 4758c2ecf20Sopenharmony_ci{ \ 4768c2ecf20Sopenharmony_ci __mlxsw_item_memcpy_to(buf, src, \ 4778c2ecf20Sopenharmony_ci &__ITEM_NAME(_type, _cname, _iname), index); \ 4788c2ecf20Sopenharmony_ci} \ 4798c2ecf20Sopenharmony_cistatic inline char * \ 4808c2ecf20Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_data(char *buf, unsigned short index) \ 4818c2ecf20Sopenharmony_ci{ \ 4828c2ecf20Sopenharmony_ci return __mlxsw_item_data(buf, \ 4838c2ecf20Sopenharmony_ci &__ITEM_NAME(_type, _cname, _iname), index); \ 4848c2ecf20Sopenharmony_ci} 4858c2ecf20Sopenharmony_ci 4868c2ecf20Sopenharmony_ci#define MLXSW_ITEM_BIT_ARRAY(_type, _cname, _iname, _offset, _sizebytes, \ 4878c2ecf20Sopenharmony_ci _element_size) \ 4888c2ecf20Sopenharmony_cistatic struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ 4898c2ecf20Sopenharmony_ci .offset = _offset, \ 4908c2ecf20Sopenharmony_ci .element_size = _element_size, \ 4918c2ecf20Sopenharmony_ci .size = {.bytes = _sizebytes,}, \ 4928c2ecf20Sopenharmony_ci .name = #_type "_" #_cname "_" #_iname, \ 4938c2ecf20Sopenharmony_ci}; \ 4948c2ecf20Sopenharmony_cistatic inline u8 \ 4958c2ecf20Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_get(const char *buf, u16 index) \ 4968c2ecf20Sopenharmony_ci{ \ 4978c2ecf20Sopenharmony_ci return __mlxsw_item_bit_array_get(buf, \ 4988c2ecf20Sopenharmony_ci &__ITEM_NAME(_type, _cname, _iname), \ 4998c2ecf20Sopenharmony_ci index); \ 5008c2ecf20Sopenharmony_ci} \ 5018c2ecf20Sopenharmony_cistatic inline void \ 5028c2ecf20Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_set(char *buf, u16 index, u8 val) \ 5038c2ecf20Sopenharmony_ci{ \ 5048c2ecf20Sopenharmony_ci return __mlxsw_item_bit_array_set(buf, \ 5058c2ecf20Sopenharmony_ci &__ITEM_NAME(_type, _cname, _iname), \ 5068c2ecf20Sopenharmony_ci index, val); \ 5078c2ecf20Sopenharmony_ci} \ 5088c2ecf20Sopenharmony_ci 5098c2ecf20Sopenharmony_ci#endif 510