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