162306a36Sopenharmony_ci/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */ 262306a36Sopenharmony_ci/* Copyright (c) 2015-2018 Mellanox Technologies. All rights reserved */ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#ifndef _MLXSW_ITEM_H 562306a36Sopenharmony_ci#define _MLXSW_ITEM_H 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#include <linux/types.h> 862306a36Sopenharmony_ci#include <linux/string.h> 962306a36Sopenharmony_ci#include <linux/bitops.h> 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_cistruct mlxsw_item { 1262306a36Sopenharmony_ci unsigned short offset; /* bytes in container */ 1362306a36Sopenharmony_ci short step; /* step in bytes for indexed items */ 1462306a36Sopenharmony_ci unsigned short in_step_offset; /* offset within one step */ 1562306a36Sopenharmony_ci unsigned char shift; /* shift in bits */ 1662306a36Sopenharmony_ci unsigned char element_size; /* size of element in bit array */ 1762306a36Sopenharmony_ci bool no_real_shift; 1862306a36Sopenharmony_ci union { 1962306a36Sopenharmony_ci unsigned char bits; 2062306a36Sopenharmony_ci unsigned short bytes; 2162306a36Sopenharmony_ci } size; 2262306a36Sopenharmony_ci const char *name; 2362306a36Sopenharmony_ci}; 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_cistatic inline unsigned int 2662306a36Sopenharmony_ci__mlxsw_item_offset(const struct mlxsw_item *item, unsigned short index, 2762306a36Sopenharmony_ci size_t typesize) 2862306a36Sopenharmony_ci{ 2962306a36Sopenharmony_ci BUG_ON(index && !item->step); 3062306a36Sopenharmony_ci if (item->offset % typesize != 0 || 3162306a36Sopenharmony_ci item->step % typesize != 0 || 3262306a36Sopenharmony_ci item->in_step_offset % typesize != 0) { 3362306a36Sopenharmony_ci pr_err("mlxsw: item bug (name=%s,offset=%x,step=%x,in_step_offset=%x,typesize=%zx)\n", 3462306a36Sopenharmony_ci item->name, item->offset, item->step, 3562306a36Sopenharmony_ci item->in_step_offset, typesize); 3662306a36Sopenharmony_ci BUG(); 3762306a36Sopenharmony_ci } 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci return ((item->offset + item->step * index + item->in_step_offset) / 4062306a36Sopenharmony_ci typesize); 4162306a36Sopenharmony_ci} 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_cistatic inline u8 __mlxsw_item_get8(const char *buf, 4462306a36Sopenharmony_ci const struct mlxsw_item *item, 4562306a36Sopenharmony_ci unsigned short index) 4662306a36Sopenharmony_ci{ 4762306a36Sopenharmony_ci unsigned int offset = __mlxsw_item_offset(item, index, sizeof(u8)); 4862306a36Sopenharmony_ci u8 *b = (u8 *) buf; 4962306a36Sopenharmony_ci u8 tmp; 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci tmp = b[offset]; 5262306a36Sopenharmony_ci tmp >>= item->shift; 5362306a36Sopenharmony_ci tmp &= GENMASK(item->size.bits - 1, 0); 5462306a36Sopenharmony_ci if (item->no_real_shift) 5562306a36Sopenharmony_ci tmp <<= item->shift; 5662306a36Sopenharmony_ci return tmp; 5762306a36Sopenharmony_ci} 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_cistatic inline void __mlxsw_item_set8(char *buf, const struct mlxsw_item *item, 6062306a36Sopenharmony_ci unsigned short index, u8 val) 6162306a36Sopenharmony_ci{ 6262306a36Sopenharmony_ci unsigned int offset = __mlxsw_item_offset(item, index, 6362306a36Sopenharmony_ci sizeof(u8)); 6462306a36Sopenharmony_ci u8 *b = (u8 *) buf; 6562306a36Sopenharmony_ci u8 mask = GENMASK(item->size.bits - 1, 0) << item->shift; 6662306a36Sopenharmony_ci u8 tmp; 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci if (!item->no_real_shift) 6962306a36Sopenharmony_ci val <<= item->shift; 7062306a36Sopenharmony_ci val &= mask; 7162306a36Sopenharmony_ci tmp = b[offset]; 7262306a36Sopenharmony_ci tmp &= ~mask; 7362306a36Sopenharmony_ci tmp |= val; 7462306a36Sopenharmony_ci b[offset] = tmp; 7562306a36Sopenharmony_ci} 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_cistatic inline u16 __mlxsw_item_get16(const char *buf, 7862306a36Sopenharmony_ci const struct mlxsw_item *item, 7962306a36Sopenharmony_ci unsigned short index) 8062306a36Sopenharmony_ci{ 8162306a36Sopenharmony_ci unsigned int offset = __mlxsw_item_offset(item, index, sizeof(u16)); 8262306a36Sopenharmony_ci __be16 *b = (__be16 *) buf; 8362306a36Sopenharmony_ci u16 tmp; 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci tmp = be16_to_cpu(b[offset]); 8662306a36Sopenharmony_ci tmp >>= item->shift; 8762306a36Sopenharmony_ci tmp &= GENMASK(item->size.bits - 1, 0); 8862306a36Sopenharmony_ci if (item->no_real_shift) 8962306a36Sopenharmony_ci tmp <<= item->shift; 9062306a36Sopenharmony_ci return tmp; 9162306a36Sopenharmony_ci} 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_cistatic inline void __mlxsw_item_set16(char *buf, const struct mlxsw_item *item, 9462306a36Sopenharmony_ci unsigned short index, u16 val) 9562306a36Sopenharmony_ci{ 9662306a36Sopenharmony_ci unsigned int offset = __mlxsw_item_offset(item, index, 9762306a36Sopenharmony_ci sizeof(u16)); 9862306a36Sopenharmony_ci __be16 *b = (__be16 *) buf; 9962306a36Sopenharmony_ci u16 mask = GENMASK(item->size.bits - 1, 0) << item->shift; 10062306a36Sopenharmony_ci u16 tmp; 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci if (!item->no_real_shift) 10362306a36Sopenharmony_ci val <<= item->shift; 10462306a36Sopenharmony_ci val &= mask; 10562306a36Sopenharmony_ci tmp = be16_to_cpu(b[offset]); 10662306a36Sopenharmony_ci tmp &= ~mask; 10762306a36Sopenharmony_ci tmp |= val; 10862306a36Sopenharmony_ci b[offset] = cpu_to_be16(tmp); 10962306a36Sopenharmony_ci} 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_cistatic inline u32 __mlxsw_item_get32(const char *buf, 11262306a36Sopenharmony_ci const struct mlxsw_item *item, 11362306a36Sopenharmony_ci unsigned short index) 11462306a36Sopenharmony_ci{ 11562306a36Sopenharmony_ci unsigned int offset = __mlxsw_item_offset(item, index, sizeof(u32)); 11662306a36Sopenharmony_ci __be32 *b = (__be32 *) buf; 11762306a36Sopenharmony_ci u32 tmp; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci tmp = be32_to_cpu(b[offset]); 12062306a36Sopenharmony_ci tmp >>= item->shift; 12162306a36Sopenharmony_ci tmp &= GENMASK(item->size.bits - 1, 0); 12262306a36Sopenharmony_ci if (item->no_real_shift) 12362306a36Sopenharmony_ci tmp <<= item->shift; 12462306a36Sopenharmony_ci return tmp; 12562306a36Sopenharmony_ci} 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_cistatic inline void __mlxsw_item_set32(char *buf, const struct mlxsw_item *item, 12862306a36Sopenharmony_ci unsigned short index, u32 val) 12962306a36Sopenharmony_ci{ 13062306a36Sopenharmony_ci unsigned int offset = __mlxsw_item_offset(item, index, 13162306a36Sopenharmony_ci sizeof(u32)); 13262306a36Sopenharmony_ci __be32 *b = (__be32 *) buf; 13362306a36Sopenharmony_ci u32 mask = GENMASK(item->size.bits - 1, 0) << item->shift; 13462306a36Sopenharmony_ci u32 tmp; 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci if (!item->no_real_shift) 13762306a36Sopenharmony_ci val <<= item->shift; 13862306a36Sopenharmony_ci val &= mask; 13962306a36Sopenharmony_ci tmp = be32_to_cpu(b[offset]); 14062306a36Sopenharmony_ci tmp &= ~mask; 14162306a36Sopenharmony_ci tmp |= val; 14262306a36Sopenharmony_ci b[offset] = cpu_to_be32(tmp); 14362306a36Sopenharmony_ci} 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_cistatic inline u64 __mlxsw_item_get64(const char *buf, 14662306a36Sopenharmony_ci const struct mlxsw_item *item, 14762306a36Sopenharmony_ci unsigned short index) 14862306a36Sopenharmony_ci{ 14962306a36Sopenharmony_ci unsigned int offset = __mlxsw_item_offset(item, index, sizeof(u64)); 15062306a36Sopenharmony_ci __be64 *b = (__be64 *) buf; 15162306a36Sopenharmony_ci u64 tmp; 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci tmp = be64_to_cpu(b[offset]); 15462306a36Sopenharmony_ci tmp >>= item->shift; 15562306a36Sopenharmony_ci tmp &= GENMASK_ULL(item->size.bits - 1, 0); 15662306a36Sopenharmony_ci if (item->no_real_shift) 15762306a36Sopenharmony_ci tmp <<= item->shift; 15862306a36Sopenharmony_ci return tmp; 15962306a36Sopenharmony_ci} 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_cistatic inline void __mlxsw_item_set64(char *buf, const struct mlxsw_item *item, 16262306a36Sopenharmony_ci unsigned short index, u64 val) 16362306a36Sopenharmony_ci{ 16462306a36Sopenharmony_ci unsigned int offset = __mlxsw_item_offset(item, index, sizeof(u64)); 16562306a36Sopenharmony_ci __be64 *b = (__be64 *) buf; 16662306a36Sopenharmony_ci u64 mask = GENMASK_ULL(item->size.bits - 1, 0) << item->shift; 16762306a36Sopenharmony_ci u64 tmp; 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_ci if (!item->no_real_shift) 17062306a36Sopenharmony_ci val <<= item->shift; 17162306a36Sopenharmony_ci val &= mask; 17262306a36Sopenharmony_ci tmp = be64_to_cpu(b[offset]); 17362306a36Sopenharmony_ci tmp &= ~mask; 17462306a36Sopenharmony_ci tmp |= val; 17562306a36Sopenharmony_ci b[offset] = cpu_to_be64(tmp); 17662306a36Sopenharmony_ci} 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_cistatic inline void __mlxsw_item_memcpy_from(const char *buf, char *dst, 17962306a36Sopenharmony_ci const struct mlxsw_item *item, 18062306a36Sopenharmony_ci unsigned short index) 18162306a36Sopenharmony_ci{ 18262306a36Sopenharmony_ci unsigned int offset = __mlxsw_item_offset(item, index, sizeof(char)); 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci memcpy(dst, &buf[offset], item->size.bytes); 18562306a36Sopenharmony_ci} 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_cistatic inline void __mlxsw_item_memcpy_to(char *buf, const char *src, 18862306a36Sopenharmony_ci const struct mlxsw_item *item, 18962306a36Sopenharmony_ci unsigned short index) 19062306a36Sopenharmony_ci{ 19162306a36Sopenharmony_ci unsigned int offset = __mlxsw_item_offset(item, index, sizeof(char)); 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci memcpy(&buf[offset], src, item->size.bytes); 19462306a36Sopenharmony_ci} 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_cistatic inline char *__mlxsw_item_data(char *buf, const struct mlxsw_item *item, 19762306a36Sopenharmony_ci unsigned short index) 19862306a36Sopenharmony_ci{ 19962306a36Sopenharmony_ci unsigned int offset = __mlxsw_item_offset(item, index, sizeof(char)); 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci return &buf[offset]; 20262306a36Sopenharmony_ci} 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_cistatic inline u16 20562306a36Sopenharmony_ci__mlxsw_item_bit_array_offset(const struct mlxsw_item *item, 20662306a36Sopenharmony_ci u16 index, u8 *shift) 20762306a36Sopenharmony_ci{ 20862306a36Sopenharmony_ci u16 max_index, be_index; 20962306a36Sopenharmony_ci u16 offset; /* byte offset inside the array */ 21062306a36Sopenharmony_ci u8 in_byte_index; 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci BUG_ON(index && !item->element_size); 21362306a36Sopenharmony_ci if (item->offset % sizeof(u32) != 0 || 21462306a36Sopenharmony_ci BITS_PER_BYTE % item->element_size != 0) { 21562306a36Sopenharmony_ci pr_err("mlxsw: item bug (name=%s,offset=%x,element_size=%x)\n", 21662306a36Sopenharmony_ci item->name, item->offset, item->element_size); 21762306a36Sopenharmony_ci BUG(); 21862306a36Sopenharmony_ci } 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ci max_index = (item->size.bytes << 3) / item->element_size - 1; 22162306a36Sopenharmony_ci be_index = max_index - index; 22262306a36Sopenharmony_ci offset = be_index * item->element_size >> 3; 22362306a36Sopenharmony_ci in_byte_index = index % (BITS_PER_BYTE / item->element_size); 22462306a36Sopenharmony_ci *shift = in_byte_index * item->element_size; 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci return item->offset + offset; 22762306a36Sopenharmony_ci} 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_cistatic inline u8 __mlxsw_item_bit_array_get(const char *buf, 23062306a36Sopenharmony_ci const struct mlxsw_item *item, 23162306a36Sopenharmony_ci u16 index) 23262306a36Sopenharmony_ci{ 23362306a36Sopenharmony_ci u8 shift, tmp; 23462306a36Sopenharmony_ci u16 offset = __mlxsw_item_bit_array_offset(item, index, &shift); 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci tmp = buf[offset]; 23762306a36Sopenharmony_ci tmp >>= shift; 23862306a36Sopenharmony_ci tmp &= GENMASK(item->element_size - 1, 0); 23962306a36Sopenharmony_ci return tmp; 24062306a36Sopenharmony_ci} 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_cistatic inline void __mlxsw_item_bit_array_set(char *buf, 24362306a36Sopenharmony_ci const struct mlxsw_item *item, 24462306a36Sopenharmony_ci u16 index, u8 val) 24562306a36Sopenharmony_ci{ 24662306a36Sopenharmony_ci u8 shift, tmp; 24762306a36Sopenharmony_ci u16 offset = __mlxsw_item_bit_array_offset(item, index, &shift); 24862306a36Sopenharmony_ci u8 mask = GENMASK(item->element_size - 1, 0) << shift; 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci val <<= shift; 25162306a36Sopenharmony_ci val &= mask; 25262306a36Sopenharmony_ci tmp = buf[offset]; 25362306a36Sopenharmony_ci tmp &= ~mask; 25462306a36Sopenharmony_ci tmp |= val; 25562306a36Sopenharmony_ci buf[offset] = tmp; 25662306a36Sopenharmony_ci} 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci#define __ITEM_NAME(_type, _cname, _iname) \ 25962306a36Sopenharmony_ci mlxsw_##_type##_##_cname##_##_iname##_item 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci/* _type: cmd_mbox, reg, etc. 26262306a36Sopenharmony_ci * _cname: containter name (e.g. command name, register name) 26362306a36Sopenharmony_ci * _iname: item name within the container 26462306a36Sopenharmony_ci */ 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_ci#define MLXSW_ITEM8(_type, _cname, _iname, _offset, _shift, _sizebits) \ 26762306a36Sopenharmony_cistatic struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ 26862306a36Sopenharmony_ci .offset = _offset, \ 26962306a36Sopenharmony_ci .shift = _shift, \ 27062306a36Sopenharmony_ci .size = {.bits = _sizebits,}, \ 27162306a36Sopenharmony_ci .name = #_type "_" #_cname "_" #_iname, \ 27262306a36Sopenharmony_ci}; \ 27362306a36Sopenharmony_cistatic inline u8 __maybe_unused \ 27462306a36Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_get(const char *buf) \ 27562306a36Sopenharmony_ci{ \ 27662306a36Sopenharmony_ci return __mlxsw_item_get8(buf, &__ITEM_NAME(_type, _cname, _iname), 0); \ 27762306a36Sopenharmony_ci} \ 27862306a36Sopenharmony_cistatic inline void __maybe_unused \ 27962306a36Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_set(char *buf, u8 val) \ 28062306a36Sopenharmony_ci{ \ 28162306a36Sopenharmony_ci __mlxsw_item_set8(buf, &__ITEM_NAME(_type, _cname, _iname), 0, val); \ 28262306a36Sopenharmony_ci} 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ci#define MLXSW_ITEM8_INDEXED(_type, _cname, _iname, _offset, _shift, _sizebits, \ 28562306a36Sopenharmony_ci _step, _instepoffset, _norealshift) \ 28662306a36Sopenharmony_cistatic struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ 28762306a36Sopenharmony_ci .offset = _offset, \ 28862306a36Sopenharmony_ci .step = _step, \ 28962306a36Sopenharmony_ci .in_step_offset = _instepoffset, \ 29062306a36Sopenharmony_ci .shift = _shift, \ 29162306a36Sopenharmony_ci .no_real_shift = _norealshift, \ 29262306a36Sopenharmony_ci .size = {.bits = _sizebits,}, \ 29362306a36Sopenharmony_ci .name = #_type "_" #_cname "_" #_iname, \ 29462306a36Sopenharmony_ci}; \ 29562306a36Sopenharmony_cistatic inline u8 __maybe_unused \ 29662306a36Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_get(const char *buf, unsigned short index)\ 29762306a36Sopenharmony_ci{ \ 29862306a36Sopenharmony_ci return __mlxsw_item_get8(buf, &__ITEM_NAME(_type, _cname, _iname), \ 29962306a36Sopenharmony_ci index); \ 30062306a36Sopenharmony_ci} \ 30162306a36Sopenharmony_cistatic inline void __maybe_unused \ 30262306a36Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_set(char *buf, unsigned short index, \ 30362306a36Sopenharmony_ci u8 val) \ 30462306a36Sopenharmony_ci{ \ 30562306a36Sopenharmony_ci __mlxsw_item_set8(buf, &__ITEM_NAME(_type, _cname, _iname), \ 30662306a36Sopenharmony_ci index, val); \ 30762306a36Sopenharmony_ci} 30862306a36Sopenharmony_ci 30962306a36Sopenharmony_ci#define MLXSW_ITEM16(_type, _cname, _iname, _offset, _shift, _sizebits) \ 31062306a36Sopenharmony_cistatic struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ 31162306a36Sopenharmony_ci .offset = _offset, \ 31262306a36Sopenharmony_ci .shift = _shift, \ 31362306a36Sopenharmony_ci .size = {.bits = _sizebits,}, \ 31462306a36Sopenharmony_ci .name = #_type "_" #_cname "_" #_iname, \ 31562306a36Sopenharmony_ci}; \ 31662306a36Sopenharmony_cistatic inline u16 __maybe_unused \ 31762306a36Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_get(const char *buf) \ 31862306a36Sopenharmony_ci{ \ 31962306a36Sopenharmony_ci return __mlxsw_item_get16(buf, &__ITEM_NAME(_type, _cname, _iname), 0); \ 32062306a36Sopenharmony_ci} \ 32162306a36Sopenharmony_cistatic inline void __maybe_unused \ 32262306a36Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_set(char *buf, u16 val) \ 32362306a36Sopenharmony_ci{ \ 32462306a36Sopenharmony_ci __mlxsw_item_set16(buf, &__ITEM_NAME(_type, _cname, _iname), 0, val); \ 32562306a36Sopenharmony_ci} 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci#define MLXSW_ITEM16_INDEXED(_type, _cname, _iname, _offset, _shift, _sizebits, \ 32862306a36Sopenharmony_ci _step, _instepoffset, _norealshift) \ 32962306a36Sopenharmony_cistatic struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ 33062306a36Sopenharmony_ci .offset = _offset, \ 33162306a36Sopenharmony_ci .step = _step, \ 33262306a36Sopenharmony_ci .in_step_offset = _instepoffset, \ 33362306a36Sopenharmony_ci .shift = _shift, \ 33462306a36Sopenharmony_ci .no_real_shift = _norealshift, \ 33562306a36Sopenharmony_ci .size = {.bits = _sizebits,}, \ 33662306a36Sopenharmony_ci .name = #_type "_" #_cname "_" #_iname, \ 33762306a36Sopenharmony_ci}; \ 33862306a36Sopenharmony_cistatic inline u16 __maybe_unused \ 33962306a36Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_get(const char *buf, unsigned short index)\ 34062306a36Sopenharmony_ci{ \ 34162306a36Sopenharmony_ci return __mlxsw_item_get16(buf, &__ITEM_NAME(_type, _cname, _iname), \ 34262306a36Sopenharmony_ci index); \ 34362306a36Sopenharmony_ci} \ 34462306a36Sopenharmony_cistatic inline void __maybe_unused \ 34562306a36Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_set(char *buf, unsigned short index, \ 34662306a36Sopenharmony_ci u16 val) \ 34762306a36Sopenharmony_ci{ \ 34862306a36Sopenharmony_ci __mlxsw_item_set16(buf, &__ITEM_NAME(_type, _cname, _iname), \ 34962306a36Sopenharmony_ci index, val); \ 35062306a36Sopenharmony_ci} 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_ci#define MLXSW_ITEM32(_type, _cname, _iname, _offset, _shift, _sizebits) \ 35362306a36Sopenharmony_cistatic struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ 35462306a36Sopenharmony_ci .offset = _offset, \ 35562306a36Sopenharmony_ci .shift = _shift, \ 35662306a36Sopenharmony_ci .size = {.bits = _sizebits,}, \ 35762306a36Sopenharmony_ci .name = #_type "_" #_cname "_" #_iname, \ 35862306a36Sopenharmony_ci}; \ 35962306a36Sopenharmony_cistatic inline u32 __maybe_unused \ 36062306a36Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_get(const char *buf) \ 36162306a36Sopenharmony_ci{ \ 36262306a36Sopenharmony_ci return __mlxsw_item_get32(buf, &__ITEM_NAME(_type, _cname, _iname), 0); \ 36362306a36Sopenharmony_ci} \ 36462306a36Sopenharmony_cistatic inline void __maybe_unused \ 36562306a36Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_set(char *buf, u32 val) \ 36662306a36Sopenharmony_ci{ \ 36762306a36Sopenharmony_ci __mlxsw_item_set32(buf, &__ITEM_NAME(_type, _cname, _iname), 0, val); \ 36862306a36Sopenharmony_ci} 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_ci#define LOCAL_PORT_LSB_SIZE 8 37162306a36Sopenharmony_ci#define LOCAL_PORT_MSB_SIZE 2 37262306a36Sopenharmony_ci 37362306a36Sopenharmony_ci#define MLXSW_ITEM32_LP(_type, _cname, _offset1, _shift1, _offset2, _shift2) \ 37462306a36Sopenharmony_cistatic struct mlxsw_item __ITEM_NAME(_type, _cname, local_port) = { \ 37562306a36Sopenharmony_ci .offset = _offset1, \ 37662306a36Sopenharmony_ci .shift = _shift1, \ 37762306a36Sopenharmony_ci .size = {.bits = LOCAL_PORT_LSB_SIZE,}, \ 37862306a36Sopenharmony_ci .name = #_type "_" #_cname "_local_port", \ 37962306a36Sopenharmony_ci}; \ 38062306a36Sopenharmony_cistatic struct mlxsw_item __ITEM_NAME(_type, _cname, lp_msb) = { \ 38162306a36Sopenharmony_ci .offset = _offset2, \ 38262306a36Sopenharmony_ci .shift = _shift2, \ 38362306a36Sopenharmony_ci .size = {.bits = LOCAL_PORT_MSB_SIZE,}, \ 38462306a36Sopenharmony_ci .name = #_type "_" #_cname "_lp_msb", \ 38562306a36Sopenharmony_ci}; \ 38662306a36Sopenharmony_cistatic inline u32 __maybe_unused \ 38762306a36Sopenharmony_cimlxsw_##_type##_##_cname##_local_port_get(const char *buf) \ 38862306a36Sopenharmony_ci{ \ 38962306a36Sopenharmony_ci u32 local_port, lp_msb; \ 39062306a36Sopenharmony_ci \ 39162306a36Sopenharmony_ci local_port = __mlxsw_item_get32(buf, &__ITEM_NAME(_type, _cname, \ 39262306a36Sopenharmony_ci local_port), 0); \ 39362306a36Sopenharmony_ci lp_msb = __mlxsw_item_get32(buf, &__ITEM_NAME(_type, _cname, lp_msb), \ 39462306a36Sopenharmony_ci 0); \ 39562306a36Sopenharmony_ci return (lp_msb << LOCAL_PORT_LSB_SIZE) + local_port; \ 39662306a36Sopenharmony_ci} \ 39762306a36Sopenharmony_cistatic inline void __maybe_unused \ 39862306a36Sopenharmony_cimlxsw_##_type##_##_cname##_local_port_set(char *buf, u32 val) \ 39962306a36Sopenharmony_ci{ \ 40062306a36Sopenharmony_ci __mlxsw_item_set32(buf, &__ITEM_NAME(_type, _cname, local_port), 0, \ 40162306a36Sopenharmony_ci val & ((1 << LOCAL_PORT_LSB_SIZE) - 1)); \ 40262306a36Sopenharmony_ci __mlxsw_item_set32(buf, &__ITEM_NAME(_type, _cname, lp_msb), 0, \ 40362306a36Sopenharmony_ci val >> LOCAL_PORT_LSB_SIZE); \ 40462306a36Sopenharmony_ci} 40562306a36Sopenharmony_ci 40662306a36Sopenharmony_ci#define MLXSW_ITEM32_INDEXED(_type, _cname, _iname, _offset, _shift, _sizebits, \ 40762306a36Sopenharmony_ci _step, _instepoffset, _norealshift) \ 40862306a36Sopenharmony_cistatic struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ 40962306a36Sopenharmony_ci .offset = _offset, \ 41062306a36Sopenharmony_ci .step = _step, \ 41162306a36Sopenharmony_ci .in_step_offset = _instepoffset, \ 41262306a36Sopenharmony_ci .shift = _shift, \ 41362306a36Sopenharmony_ci .no_real_shift = _norealshift, \ 41462306a36Sopenharmony_ci .size = {.bits = _sizebits,}, \ 41562306a36Sopenharmony_ci .name = #_type "_" #_cname "_" #_iname, \ 41662306a36Sopenharmony_ci}; \ 41762306a36Sopenharmony_cistatic inline u32 __maybe_unused \ 41862306a36Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_get(const char *buf, unsigned short index)\ 41962306a36Sopenharmony_ci{ \ 42062306a36Sopenharmony_ci return __mlxsw_item_get32(buf, &__ITEM_NAME(_type, _cname, _iname), \ 42162306a36Sopenharmony_ci index); \ 42262306a36Sopenharmony_ci} \ 42362306a36Sopenharmony_cistatic inline void __maybe_unused \ 42462306a36Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_set(char *buf, unsigned short index, \ 42562306a36Sopenharmony_ci u32 val) \ 42662306a36Sopenharmony_ci{ \ 42762306a36Sopenharmony_ci __mlxsw_item_set32(buf, &__ITEM_NAME(_type, _cname, _iname), \ 42862306a36Sopenharmony_ci index, val); \ 42962306a36Sopenharmony_ci} 43062306a36Sopenharmony_ci 43162306a36Sopenharmony_ci#define MLXSW_ITEM64(_type, _cname, _iname, _offset, _shift, _sizebits) \ 43262306a36Sopenharmony_cistatic struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ 43362306a36Sopenharmony_ci .offset = _offset, \ 43462306a36Sopenharmony_ci .shift = _shift, \ 43562306a36Sopenharmony_ci .size = {.bits = _sizebits,}, \ 43662306a36Sopenharmony_ci .name = #_type "_" #_cname "_" #_iname, \ 43762306a36Sopenharmony_ci}; \ 43862306a36Sopenharmony_cistatic inline u64 __maybe_unused \ 43962306a36Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_get(const char *buf) \ 44062306a36Sopenharmony_ci{ \ 44162306a36Sopenharmony_ci return __mlxsw_item_get64(buf, &__ITEM_NAME(_type, _cname, _iname), 0); \ 44262306a36Sopenharmony_ci} \ 44362306a36Sopenharmony_cistatic inline void __maybe_unused \ 44462306a36Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_set(char *buf, u64 val) \ 44562306a36Sopenharmony_ci{ \ 44662306a36Sopenharmony_ci __mlxsw_item_set64(buf, &__ITEM_NAME(_type, _cname, _iname), 0, val); \ 44762306a36Sopenharmony_ci} 44862306a36Sopenharmony_ci 44962306a36Sopenharmony_ci#define MLXSW_ITEM64_INDEXED(_type, _cname, _iname, _offset, _shift, \ 45062306a36Sopenharmony_ci _sizebits, _step, _instepoffset, _norealshift) \ 45162306a36Sopenharmony_cistatic struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ 45262306a36Sopenharmony_ci .offset = _offset, \ 45362306a36Sopenharmony_ci .step = _step, \ 45462306a36Sopenharmony_ci .in_step_offset = _instepoffset, \ 45562306a36Sopenharmony_ci .shift = _shift, \ 45662306a36Sopenharmony_ci .no_real_shift = _norealshift, \ 45762306a36Sopenharmony_ci .size = {.bits = _sizebits,}, \ 45862306a36Sopenharmony_ci .name = #_type "_" #_cname "_" #_iname, \ 45962306a36Sopenharmony_ci}; \ 46062306a36Sopenharmony_cistatic inline u64 __maybe_unused \ 46162306a36Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_get(const char *buf, unsigned short index)\ 46262306a36Sopenharmony_ci{ \ 46362306a36Sopenharmony_ci return __mlxsw_item_get64(buf, &__ITEM_NAME(_type, _cname, _iname), \ 46462306a36Sopenharmony_ci index); \ 46562306a36Sopenharmony_ci} \ 46662306a36Sopenharmony_cistatic inline void __maybe_unused \ 46762306a36Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_set(char *buf, unsigned short index, \ 46862306a36Sopenharmony_ci u64 val) \ 46962306a36Sopenharmony_ci{ \ 47062306a36Sopenharmony_ci __mlxsw_item_set64(buf, &__ITEM_NAME(_type, _cname, _iname), \ 47162306a36Sopenharmony_ci index, val); \ 47262306a36Sopenharmony_ci} 47362306a36Sopenharmony_ci 47462306a36Sopenharmony_ci#define MLXSW_ITEM_BUF(_type, _cname, _iname, _offset, _sizebytes) \ 47562306a36Sopenharmony_cistatic struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ 47662306a36Sopenharmony_ci .offset = _offset, \ 47762306a36Sopenharmony_ci .size = {.bytes = _sizebytes,}, \ 47862306a36Sopenharmony_ci .name = #_type "_" #_cname "_" #_iname, \ 47962306a36Sopenharmony_ci}; \ 48062306a36Sopenharmony_cistatic inline void __maybe_unused \ 48162306a36Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_memcpy_from(const char *buf, char *dst) \ 48262306a36Sopenharmony_ci{ \ 48362306a36Sopenharmony_ci __mlxsw_item_memcpy_from(buf, dst, \ 48462306a36Sopenharmony_ci &__ITEM_NAME(_type, _cname, _iname), 0); \ 48562306a36Sopenharmony_ci} \ 48662306a36Sopenharmony_cistatic inline void __maybe_unused \ 48762306a36Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_memcpy_to(char *buf, const char *src) \ 48862306a36Sopenharmony_ci{ \ 48962306a36Sopenharmony_ci __mlxsw_item_memcpy_to(buf, src, \ 49062306a36Sopenharmony_ci &__ITEM_NAME(_type, _cname, _iname), 0); \ 49162306a36Sopenharmony_ci} \ 49262306a36Sopenharmony_cistatic inline char * __maybe_unused \ 49362306a36Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_data(char *buf) \ 49462306a36Sopenharmony_ci{ \ 49562306a36Sopenharmony_ci return __mlxsw_item_data(buf, &__ITEM_NAME(_type, _cname, _iname), 0); \ 49662306a36Sopenharmony_ci} 49762306a36Sopenharmony_ci 49862306a36Sopenharmony_ci#define MLXSW_ITEM_BUF_INDEXED(_type, _cname, _iname, _offset, _sizebytes, \ 49962306a36Sopenharmony_ci _step, _instepoffset) \ 50062306a36Sopenharmony_cistatic struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ 50162306a36Sopenharmony_ci .offset = _offset, \ 50262306a36Sopenharmony_ci .step = _step, \ 50362306a36Sopenharmony_ci .in_step_offset = _instepoffset, \ 50462306a36Sopenharmony_ci .size = {.bytes = _sizebytes,}, \ 50562306a36Sopenharmony_ci .name = #_type "_" #_cname "_" #_iname, \ 50662306a36Sopenharmony_ci}; \ 50762306a36Sopenharmony_cistatic inline void __maybe_unused \ 50862306a36Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_memcpy_from(const char *buf, \ 50962306a36Sopenharmony_ci unsigned short index, \ 51062306a36Sopenharmony_ci char *dst) \ 51162306a36Sopenharmony_ci{ \ 51262306a36Sopenharmony_ci __mlxsw_item_memcpy_from(buf, dst, \ 51362306a36Sopenharmony_ci &__ITEM_NAME(_type, _cname, _iname), index); \ 51462306a36Sopenharmony_ci} \ 51562306a36Sopenharmony_cistatic inline void __maybe_unused \ 51662306a36Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_memcpy_to(char *buf, \ 51762306a36Sopenharmony_ci unsigned short index, \ 51862306a36Sopenharmony_ci const char *src) \ 51962306a36Sopenharmony_ci{ \ 52062306a36Sopenharmony_ci __mlxsw_item_memcpy_to(buf, src, \ 52162306a36Sopenharmony_ci &__ITEM_NAME(_type, _cname, _iname), index); \ 52262306a36Sopenharmony_ci} \ 52362306a36Sopenharmony_cistatic inline char * __maybe_unused \ 52462306a36Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_data(char *buf, unsigned short index) \ 52562306a36Sopenharmony_ci{ \ 52662306a36Sopenharmony_ci return __mlxsw_item_data(buf, \ 52762306a36Sopenharmony_ci &__ITEM_NAME(_type, _cname, _iname), index); \ 52862306a36Sopenharmony_ci} 52962306a36Sopenharmony_ci 53062306a36Sopenharmony_ci#define MLXSW_ITEM_BIT_ARRAY(_type, _cname, _iname, _offset, _sizebytes, \ 53162306a36Sopenharmony_ci _element_size) \ 53262306a36Sopenharmony_cistatic struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ 53362306a36Sopenharmony_ci .offset = _offset, \ 53462306a36Sopenharmony_ci .element_size = _element_size, \ 53562306a36Sopenharmony_ci .size = {.bytes = _sizebytes,}, \ 53662306a36Sopenharmony_ci .name = #_type "_" #_cname "_" #_iname, \ 53762306a36Sopenharmony_ci}; \ 53862306a36Sopenharmony_cistatic inline u8 __maybe_unused \ 53962306a36Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_get(const char *buf, u16 index) \ 54062306a36Sopenharmony_ci{ \ 54162306a36Sopenharmony_ci return __mlxsw_item_bit_array_get(buf, \ 54262306a36Sopenharmony_ci &__ITEM_NAME(_type, _cname, _iname), \ 54362306a36Sopenharmony_ci index); \ 54462306a36Sopenharmony_ci} \ 54562306a36Sopenharmony_cistatic inline void __maybe_unused \ 54662306a36Sopenharmony_cimlxsw_##_type##_##_cname##_##_iname##_set(char *buf, u16 index, u8 val) \ 54762306a36Sopenharmony_ci{ \ 54862306a36Sopenharmony_ci return __mlxsw_item_bit_array_set(buf, \ 54962306a36Sopenharmony_ci &__ITEM_NAME(_type, _cname, _iname), \ 55062306a36Sopenharmony_ci index, val); \ 55162306a36Sopenharmony_ci} \ 55262306a36Sopenharmony_ci 55362306a36Sopenharmony_ci#endif 554