Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'icrc-counter' into rdma.git for-next

For dependencies, branch based on 'mellanox/mlx5-next' of
git://git.kernel.org/pub/scm/linux/kernel/git/mellanox/linux.git

Pull RoCE ICRC counters from Leon Romanovsky:

====================
This series exposes RoCE ICRC counter through existing RDMA hw_counters
sysfs interface.

The first patch has all HW definitions in mlx5_ifc.h file and second patch
is the actual counter implementation.
====================

* branch 'icrc-counter':
IB/mlx5: Support RoCE ICRC encapsulated error counter
net/mlx5: Add RoCE RX ICRC encapsulated counter

+81 -6
+12
drivers/infiniband/hw/mlx5/cmd.c
··· 170 170 171 171 return err; 172 172 } 173 + 174 + int mlx5_cmd_query_ext_ppcnt_counters(struct mlx5_core_dev *dev, void *out) 175 + { 176 + u32 in[MLX5_ST_SZ_DW(ppcnt_reg)] = {}; 177 + int sz = MLX5_ST_SZ_BYTES(ppcnt_reg); 178 + 179 + MLX5_SET(ppcnt_reg, in, local_port, 1); 180 + 181 + MLX5_SET(ppcnt_reg, in, grp, MLX5_ETHERNET_EXTENDED_COUNTERS_GROUP); 182 + return mlx5_core_access_reg(dev, in, sz, out, sz, MLX5_REG_PPCNT, 183 + 0, 0); 184 + }
+1
drivers/infiniband/hw/mlx5/cmd.h
··· 40 40 int mlx5_cmd_null_mkey(struct mlx5_core_dev *dev, u32 *null_mkey); 41 41 int mlx5_cmd_query_cong_params(struct mlx5_core_dev *dev, int cong_point, 42 42 void *out, int out_size); 43 + int mlx5_cmd_query_ext_ppcnt_counters(struct mlx5_core_dev *dev, void *out); 43 44 int mlx5_cmd_modify_cong_params(struct mlx5_core_dev *mdev, 44 45 void *in, int in_size); 45 46 int mlx5_cmd_alloc_memic(struct mlx5_memic *memic, phys_addr_t *addr,
+59 -3
drivers/infiniband/hw/mlx5/main.c
··· 4677 4677 INIT_Q_COUNTER(req_cqe_flush_error), 4678 4678 }; 4679 4679 4680 + #define INIT_EXT_PPCNT_COUNTER(_name) \ 4681 + { .name = #_name, .offset = \ 4682 + MLX5_BYTE_OFF(ppcnt_reg, \ 4683 + counter_set.eth_extended_cntrs_grp_data_layout._name##_high)} 4684 + 4685 + static const struct mlx5_ib_counter ext_ppcnt_cnts[] = { 4686 + INIT_EXT_PPCNT_COUNTER(rx_icrc_encapsulated), 4687 + }; 4688 + 4680 4689 static void mlx5_ib_dealloc_counters(struct mlx5_ib_dev *dev) 4681 4690 { 4682 4691 int i; ··· 4721 4712 cnts->num_cong_counters = ARRAY_SIZE(cong_cnts); 4722 4713 num_counters += ARRAY_SIZE(cong_cnts); 4723 4714 } 4724 - 4715 + if (MLX5_CAP_PCAM_FEATURE(dev->mdev, rx_icrc_encapsulated_counter)) { 4716 + cnts->num_ext_ppcnt_counters = ARRAY_SIZE(ext_ppcnt_cnts); 4717 + num_counters += ARRAY_SIZE(ext_ppcnt_cnts); 4718 + } 4725 4719 cnts->names = kcalloc(num_counters, sizeof(cnts->names), GFP_KERNEL); 4726 4720 if (!cnts->names) 4727 4721 return -ENOMEM; ··· 4781 4769 offsets[j] = cong_cnts[i].offset; 4782 4770 } 4783 4771 } 4772 + 4773 + if (MLX5_CAP_PCAM_FEATURE(dev->mdev, rx_icrc_encapsulated_counter)) { 4774 + for (i = 0; i < ARRAY_SIZE(ext_ppcnt_cnts); i++, j++) { 4775 + names[j] = ext_ppcnt_cnts[i].name; 4776 + offsets[j] = ext_ppcnt_cnts[i].offset; 4777 + } 4778 + } 4784 4779 } 4785 4780 4786 4781 static int mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev) ··· 4833 4814 4834 4815 return rdma_alloc_hw_stats_struct(port->cnts.names, 4835 4816 port->cnts.num_q_counters + 4836 - port->cnts.num_cong_counters, 4817 + port->cnts.num_cong_counters + 4818 + port->cnts.num_ext_ppcnt_counters, 4837 4819 RDMA_HW_STATS_DEFAULT_LIFESPAN); 4838 4820 } 4839 4821 ··· 4867 4847 return ret; 4868 4848 } 4869 4849 4850 + static int mlx5_ib_query_ext_ppcnt_counters(struct mlx5_ib_dev *dev, 4851 + struct mlx5_ib_port *port, 4852 + struct rdma_hw_stats *stats) 4853 + { 4854 + int offset = port->cnts.num_q_counters + port->cnts.num_cong_counters; 4855 + int sz = MLX5_ST_SZ_BYTES(ppcnt_reg); 4856 + int ret, i; 4857 + void *out; 4858 + 4859 + out = kvzalloc(sz, GFP_KERNEL); 4860 + if (!out) 4861 + return -ENOMEM; 4862 + 4863 + ret = mlx5_cmd_query_ext_ppcnt_counters(dev->mdev, out); 4864 + if (ret) 4865 + goto free; 4866 + 4867 + for (i = 0; i < port->cnts.num_ext_ppcnt_counters; i++) { 4868 + stats->value[i + offset] = 4869 + be64_to_cpup((__be64 *)(out + 4870 + port->cnts.offsets[i + offset])); 4871 + } 4872 + 4873 + free: 4874 + kvfree(out); 4875 + return ret; 4876 + } 4877 + 4870 4878 static int mlx5_ib_get_hw_stats(struct ib_device *ibdev, 4871 4879 struct rdma_hw_stats *stats, 4872 4880 u8 port_num, int index) ··· 4908 4860 if (!stats) 4909 4861 return -EINVAL; 4910 4862 4911 - num_counters = port->cnts.num_q_counters + port->cnts.num_cong_counters; 4863 + num_counters = port->cnts.num_q_counters + 4864 + port->cnts.num_cong_counters + 4865 + port->cnts.num_ext_ppcnt_counters; 4912 4866 4913 4867 /* q_counters are per IB device, query the master mdev */ 4914 4868 ret = mlx5_ib_query_q_counters(dev->mdev, port, stats); 4915 4869 if (ret) 4916 4870 return ret; 4871 + 4872 + if (MLX5_CAP_PCAM_FEATURE(dev->mdev, rx_icrc_encapsulated_counter)) { 4873 + ret = mlx5_ib_query_ext_ppcnt_counters(dev, port, stats); 4874 + if (ret) 4875 + return ret; 4876 + } 4917 4877 4918 4878 if (MLX5_CAP_GEN(dev->mdev, cc_query_allowed)) { 4919 4879 mdev = mlx5_ib_get_native_port_mdev(dev, port_num,
+1
drivers/infiniband/hw/mlx5/mlx5_ib.h
··· 666 666 size_t *offsets; 667 667 u32 num_q_counters; 668 668 u32 num_cong_counters; 669 + u32 num_ext_ppcnt_counters; 669 670 u16 set_id; 670 671 bool set_id_valid; 671 672 };
+8 -3
include/linux/mlx5/mlx5_ifc.h
··· 1685 1685 1686 1686 u8 rx_buffer_full_low[0x20]; 1687 1687 1688 - u8 reserved_at_1c0[0x600]; 1688 + u8 rx_icrc_encapsulated_high[0x20]; 1689 + 1690 + u8 rx_icrc_encapsulated_low[0x20]; 1691 + 1692 + u8 reserved_at_200[0x5c0]; 1689 1693 }; 1690 1694 1691 1695 struct mlx5_ifc_eth_3635_cntrs_grp_data_layout_bits { ··· 8052 8048 }; 8053 8049 8054 8050 struct mlx5_ifc_pcam_enhanced_features_bits { 8055 - u8 reserved_at_0[0x76]; 8056 - 8051 + u8 reserved_at_0[0x6d]; 8052 + u8 rx_icrc_encapsulated_counter[0x1]; 8053 + u8 reserved_at_6e[0x8]; 8057 8054 u8 pfcc_mask[0x1]; 8058 8055 u8 reserved_at_77[0x4]; 8059 8056 u8 rx_buffer_fullness_counters[0x1];