IB/mlx5: Support RoCE ICRC encapsulated error counter
authorTalat Batheesh <talatb@mellanox.com>
Thu, 21 Jun 2018 12:37:56 +0000 (15:37 +0300)
committerJason Gunthorpe <jgg@mellanox.com>
Fri, 22 Jun 2018 14:51:14 +0000 (08:51 -0600)
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: Talat Batheesh <talatb@mellanox.com>
Reviewed-by: Mark Bloch <markb@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
drivers/infiniband/hw/mlx5/cmd.c
drivers/infiniband/hw/mlx5/cmd.h
drivers/infiniband/hw/mlx5/main.c
drivers/infiniband/hw/mlx5/mlx5_ib.h

index 188512b..026717e 100644 (file)
@@ -170,3 +170,15 @@ int mlx5_cmd_dealloc_memic(struct mlx5_memic *memic, u64 addr, u64 length)
 
        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);
+}
index e7206c8..b946c47 100644 (file)
@@ -40,6 +40,7 @@
 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,
                               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,
                                void *in, int in_size);
 int mlx5_cmd_alloc_memic(struct mlx5_memic *memic, phys_addr_t *addr,
index e52dd21..ce37df2 100644 (file)
@@ -4683,6 +4683,15 @@ static const struct mlx5_ib_counter extended_err_cnts[] = {
        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)
 {
        int i;
@@ -4718,7 +4727,10 @@ static int __mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev,
                cnts->num_cong_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);
        if (!cnts->names)
                return -ENOMEM;
@@ -4775,6 +4787,13 @@ static void mlx5_ib_fill_counters(struct mlx5_ib_dev *dev,
                        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)
@@ -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,
                                          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);
 }
 
@@ -4853,6 +4873,34 @@ free:
        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,
                                struct rdma_hw_stats *stats,
                                u8 port_num, int index)
@@ -4866,13 +4914,21 @@ static int mlx5_ib_get_hw_stats(struct ib_device *ibdev,
        if (!stats)
                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 */
        ret = mlx5_ib_query_q_counters(dev->mdev, port, stats);
        if (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)) {
                mdev = mlx5_ib_get_native_port_mdev(dev, port_num,
                                                    &mdev_port_num);
index d89c8fe..298d6a3 100644 (file)
@@ -665,6 +665,7 @@ struct mlx5_ib_counters {
        size_t *offsets;
        u32 num_q_counters;
        u32 num_cong_counters;
+       u32 num_ext_ppcnt_counters;
        u16 set_id;
        bool set_id_valid;
 };