Commit 9f876f3d authored by Talat Batheesh's avatar Talat Batheesh Committed by Jason Gunthorpe

IB/mlx5: Support RoCE ICRC encapsulated error counter

This patch adds support to query the counter that counts the
RoCE packets with corrupted ICRC (Invariant Cyclic Redundancy Code).

This counter will be under
/sys/class/infiniband/<mlx5-dev>/ports/<port>/hw_counters/

rx_icrc_encapsulated - The number of RoCE packets with ICRC
error.
Signed-off-by: default avatarTalat Batheesh <talatb@mellanox.com>
Reviewed-by: default avatarMark Bloch <markb@mellanox.com>
Signed-off-by: default avatarLeon Romanovsky <leonro@mellanox.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent 0af5107c
...@@ -170,3 +170,15 @@ int mlx5_cmd_dealloc_memic(struct mlx5_memic *memic, u64 addr, u64 length) ...@@ -170,3 +170,15 @@ int mlx5_cmd_dealloc_memic(struct mlx5_memic *memic, u64 addr, u64 length)
return err; return err;
} }
int mlx5_cmd_query_ext_ppcnt_counters(struct mlx5_core_dev *dev, void *out)
{
u32 in[MLX5_ST_SZ_DW(ppcnt_reg)] = {};
int sz = MLX5_ST_SZ_BYTES(ppcnt_reg);
MLX5_SET(ppcnt_reg, in, local_port, 1);
MLX5_SET(ppcnt_reg, in, grp, MLX5_ETHERNET_EXTENDED_COUNTERS_GROUP);
return mlx5_core_access_reg(dev, in, sz, out, sz, MLX5_REG_PPCNT,
0, 0);
}
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
int mlx5_cmd_null_mkey(struct mlx5_core_dev *dev, u32 *null_mkey); int mlx5_cmd_null_mkey(struct mlx5_core_dev *dev, u32 *null_mkey);
int mlx5_cmd_query_cong_params(struct mlx5_core_dev *dev, int cong_point, int mlx5_cmd_query_cong_params(struct mlx5_core_dev *dev, int cong_point,
void *out, int out_size); void *out, int out_size);
int mlx5_cmd_query_ext_ppcnt_counters(struct mlx5_core_dev *dev, void *out);
int mlx5_cmd_modify_cong_params(struct mlx5_core_dev *mdev, int mlx5_cmd_modify_cong_params(struct mlx5_core_dev *mdev,
void *in, int in_size); void *in, int in_size);
int mlx5_cmd_alloc_memic(struct mlx5_memic *memic, phys_addr_t *addr, int mlx5_cmd_alloc_memic(struct mlx5_memic *memic, phys_addr_t *addr,
......
...@@ -4683,6 +4683,15 @@ static const struct mlx5_ib_counter extended_err_cnts[] = { ...@@ -4683,6 +4683,15 @@ static const struct mlx5_ib_counter extended_err_cnts[] = {
INIT_Q_COUNTER(req_cqe_flush_error), INIT_Q_COUNTER(req_cqe_flush_error),
}; };
#define INIT_EXT_PPCNT_COUNTER(_name) \
{ .name = #_name, .offset = \
MLX5_BYTE_OFF(ppcnt_reg, \
counter_set.eth_extended_cntrs_grp_data_layout._name##_high)}
static const struct mlx5_ib_counter ext_ppcnt_cnts[] = {
INIT_EXT_PPCNT_COUNTER(rx_icrc_encapsulated),
};
static void mlx5_ib_dealloc_counters(struct mlx5_ib_dev *dev) static void mlx5_ib_dealloc_counters(struct mlx5_ib_dev *dev)
{ {
int i; int i;
...@@ -4718,7 +4727,10 @@ static int __mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev, ...@@ -4718,7 +4727,10 @@ static int __mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev,
cnts->num_cong_counters = ARRAY_SIZE(cong_cnts); cnts->num_cong_counters = ARRAY_SIZE(cong_cnts);
num_counters += ARRAY_SIZE(cong_cnts); num_counters += ARRAY_SIZE(cong_cnts);
} }
if (MLX5_CAP_PCAM_FEATURE(dev->mdev, rx_icrc_encapsulated_counter)) {
cnts->num_ext_ppcnt_counters = ARRAY_SIZE(ext_ppcnt_cnts);
num_counters += ARRAY_SIZE(ext_ppcnt_cnts);
}
cnts->names = kcalloc(num_counters, sizeof(cnts->names), GFP_KERNEL); cnts->names = kcalloc(num_counters, sizeof(cnts->names), GFP_KERNEL);
if (!cnts->names) if (!cnts->names)
return -ENOMEM; return -ENOMEM;
...@@ -4775,6 +4787,13 @@ static void mlx5_ib_fill_counters(struct mlx5_ib_dev *dev, ...@@ -4775,6 +4787,13 @@ static void mlx5_ib_fill_counters(struct mlx5_ib_dev *dev,
offsets[j] = cong_cnts[i].offset; offsets[j] = cong_cnts[i].offset;
} }
} }
if (MLX5_CAP_PCAM_FEATURE(dev->mdev, rx_icrc_encapsulated_counter)) {
for (i = 0; i < ARRAY_SIZE(ext_ppcnt_cnts); i++, j++) {
names[j] = ext_ppcnt_cnts[i].name;
offsets[j] = ext_ppcnt_cnts[i].offset;
}
}
} }
static int mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev) static int mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev)
...@@ -4820,7 +4839,8 @@ static struct rdma_hw_stats *mlx5_ib_alloc_hw_stats(struct ib_device *ibdev, ...@@ -4820,7 +4839,8 @@ static struct rdma_hw_stats *mlx5_ib_alloc_hw_stats(struct ib_device *ibdev,
return rdma_alloc_hw_stats_struct(port->cnts.names, return rdma_alloc_hw_stats_struct(port->cnts.names,
port->cnts.num_q_counters + port->cnts.num_q_counters +
port->cnts.num_cong_counters, port->cnts.num_cong_counters +
port->cnts.num_ext_ppcnt_counters,
RDMA_HW_STATS_DEFAULT_LIFESPAN); RDMA_HW_STATS_DEFAULT_LIFESPAN);
} }
...@@ -4853,6 +4873,34 @@ static int mlx5_ib_query_q_counters(struct mlx5_core_dev *mdev, ...@@ -4853,6 +4873,34 @@ static int mlx5_ib_query_q_counters(struct mlx5_core_dev *mdev,
return ret; return ret;
} }
static int mlx5_ib_query_ext_ppcnt_counters(struct mlx5_ib_dev *dev,
struct mlx5_ib_port *port,
struct rdma_hw_stats *stats)
{
int offset = port->cnts.num_q_counters + port->cnts.num_cong_counters;
int sz = MLX5_ST_SZ_BYTES(ppcnt_reg);
int ret, i;
void *out;
out = kvzalloc(sz, GFP_KERNEL);
if (!out)
return -ENOMEM;
ret = mlx5_cmd_query_ext_ppcnt_counters(dev->mdev, out);
if (ret)
goto free;
for (i = 0; i < port->cnts.num_ext_ppcnt_counters; i++) {
stats->value[i + offset] =
be64_to_cpup((__be64 *)(out +
port->cnts.offsets[i + offset]));
}
free:
kvfree(out);
return ret;
}
static int mlx5_ib_get_hw_stats(struct ib_device *ibdev, static int mlx5_ib_get_hw_stats(struct ib_device *ibdev,
struct rdma_hw_stats *stats, struct rdma_hw_stats *stats,
u8 port_num, int index) u8 port_num, int index)
...@@ -4866,13 +4914,21 @@ static int mlx5_ib_get_hw_stats(struct ib_device *ibdev, ...@@ -4866,13 +4914,21 @@ static int mlx5_ib_get_hw_stats(struct ib_device *ibdev,
if (!stats) if (!stats)
return -EINVAL; return -EINVAL;
num_counters = port->cnts.num_q_counters + port->cnts.num_cong_counters; num_counters = port->cnts.num_q_counters +
port->cnts.num_cong_counters +
port->cnts.num_ext_ppcnt_counters;
/* q_counters are per IB device, query the master mdev */ /* q_counters are per IB device, query the master mdev */
ret = mlx5_ib_query_q_counters(dev->mdev, port, stats); ret = mlx5_ib_query_q_counters(dev->mdev, port, stats);
if (ret) if (ret)
return ret; return ret;
if (MLX5_CAP_PCAM_FEATURE(dev->mdev, rx_icrc_encapsulated_counter)) {
ret = mlx5_ib_query_ext_ppcnt_counters(dev, port, stats);
if (ret)
return ret;
}
if (MLX5_CAP_GEN(dev->mdev, cc_query_allowed)) { if (MLX5_CAP_GEN(dev->mdev, cc_query_allowed)) {
mdev = mlx5_ib_get_native_port_mdev(dev, port_num, mdev = mlx5_ib_get_native_port_mdev(dev, port_num,
&mdev_port_num); &mdev_port_num);
......
...@@ -665,6 +665,7 @@ struct mlx5_ib_counters { ...@@ -665,6 +665,7 @@ struct mlx5_ib_counters {
size_t *offsets; size_t *offsets;
u32 num_q_counters; u32 num_q_counters;
u32 num_cong_counters; u32 num_cong_counters;
u32 num_ext_ppcnt_counters;
u16 set_id; u16 set_id;
bool set_id_valid; bool set_id_valid;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment