diff options
author | Amit Cohen <amcohen@nvidia.com> | 2021-12-01 10:12:33 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2021-12-01 14:52:33 +0000 |
commit | fda39347d90f42dafaec5e8ed7490e8054e8dcad (patch) | |
tree | edd02d88ce5e7f0289d6aa6e224bad66b538ce0c /drivers | |
parent | b25dea489b55a54d6ede2d9836c84ef2f50210fc (diff) | |
download | linux-fda39347d90f42dafaec5e8ed7490e8054e8dcad.tar.bz2 |
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: Amit Cohen <amcohen@nvidia.com>
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Reviewed-by: Petr Machata <petrm@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/item.h | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/item.h b/drivers/net/ethernet/mellanox/mlxsw/item.h index ab70a873a01a..cfafbeb42586 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/item.h +++ b/drivers/net/ethernet/mellanox/mlxsw/item.h @@ -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) = { \ |