Commit fda39347 authored by Amit Cohen's avatar Amit Cohen Committed by David S. Miller
Browse files

mlxsw: item: Add support for local_port field in a split form



Currently, local_port field uses 8 bits, which means that maximum 256
ports can be used.

As preparation for the next ASIC, which will support more than 256
ports, local_port field should be extended to 10 bits.

It is not possible to use 10 consecutive bits in all registers, and
therefore, the field is split into 2 fields:
1. local_port - the existing 8 bits, represent LSB of the extended
   field.
2. lp_msb - extra 2 bits, represent MSB of the extended field.

To avoid complex programming when reading/writing local_port, add a
dedicated macro which creates get and set functions which handle both parts
of local_port.

Signed-off-by: default avatarAmit Cohen <amcohen@nvidia.com>
Reviewed-by: default avatarJiri Pirko <jiri@nvidia.com>
Reviewed-by: default avatarPetr Machata <petrm@nvidia.com>
Signed-off-by: default avatarIdo Schimmel <idosch@nvidia.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b25dea48
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -367,6 +367,42 @@ mlxsw_##_type##_##_cname##_##_iname##_set(char *buf, u32 val) \
	__mlxsw_item_set32(buf, &__ITEM_NAME(_type, _cname, _iname), 0, val);	\
}

#define LOCAL_PORT_LSB_SIZE 8
#define LOCAL_PORT_MSB_SIZE 2

#define MLXSW_ITEM32_LP(_type, _cname, _offset1, _shift1, _offset2, _shift2)	\
static struct mlxsw_item __ITEM_NAME(_type, _cname, local_port) = {		\
	.offset = _offset1,							\
	.shift = _shift1,							\
	.size = {.bits = LOCAL_PORT_LSB_SIZE,},					\
	.name = #_type "_" #_cname "_local_port",				\
};										\
static struct mlxsw_item __ITEM_NAME(_type, _cname, lp_msb) = {			\
	.offset = _offset2,							\
	.shift = _shift2,							\
	.size = {.bits = LOCAL_PORT_MSB_SIZE,},					\
	.name = #_type "_" #_cname "_lp_msb",					\
};										\
static inline u32 __maybe_unused						\
mlxsw_##_type##_##_cname##_local_port_get(const char *buf)			\
{										\
	u32 local_port, lp_msb;							\
										\
	local_port = __mlxsw_item_get32(buf, &__ITEM_NAME(_type, _cname,	\
					local_port), 0);			\
	lp_msb = __mlxsw_item_get32(buf, &__ITEM_NAME(_type, _cname, lp_msb),	\
				   0);						\
	return (lp_msb << LOCAL_PORT_LSB_SIZE) + local_port;			\
}										\
static inline void __maybe_unused						\
mlxsw_##_type##_##_cname##_local_port_set(char *buf, u32 val)			\
{										\
	__mlxsw_item_set32(buf, &__ITEM_NAME(_type, _cname, local_port), 0,	\
			   val & ((1 << LOCAL_PORT_LSB_SIZE) - 1));		\
	__mlxsw_item_set32(buf, &__ITEM_NAME(_type, _cname, lp_msb), 0,		\
			   val >> LOCAL_PORT_LSB_SIZE);				\
}

#define MLXSW_ITEM32_INDEXED(_type, _cname, _iname, _offset, _shift, _sizebits,	\
			     _step, _instepoffset, _norealshift)		\
static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = {			\