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