14a2da0b8SParav Pandit /* 24a2da0b8SParav Pandit * Copyright (c) 2013-2017, Mellanox Technologies. All rights reserved. 34a2da0b8SParav Pandit * 44a2da0b8SParav Pandit * This software is available to you under a choice of one of two 54a2da0b8SParav Pandit * licenses. You may choose to be licensed under the terms of the GNU 64a2da0b8SParav Pandit * General Public License (GPL) Version 2, available from the file 74a2da0b8SParav Pandit * COPYING in the main directory of this source tree, or the 84a2da0b8SParav Pandit * OpenIB.org BSD license below: 94a2da0b8SParav Pandit * 104a2da0b8SParav Pandit * Redistribution and use in source and binary forms, with or 114a2da0b8SParav Pandit * without modification, are permitted provided that the following 124a2da0b8SParav Pandit * conditions are met: 134a2da0b8SParav Pandit * 144a2da0b8SParav Pandit * - Redistributions of source code must retain the above 154a2da0b8SParav Pandit * copyright notice, this list of conditions and the following 164a2da0b8SParav Pandit * disclaimer. 174a2da0b8SParav Pandit * 184a2da0b8SParav Pandit * - Redistributions in binary form must reproduce the above 194a2da0b8SParav Pandit * copyright notice, this list of conditions and the following 204a2da0b8SParav Pandit * disclaimer in the documentation and/or other materials 214a2da0b8SParav Pandit * provided with the distribution. 224a2da0b8SParav Pandit * 234a2da0b8SParav Pandit * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 244a2da0b8SParav Pandit * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 254a2da0b8SParav Pandit * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 264a2da0b8SParav Pandit * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 274a2da0b8SParav Pandit * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 284a2da0b8SParav Pandit * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 294a2da0b8SParav Pandit * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 304a2da0b8SParav Pandit * SOFTWARE. 314a2da0b8SParav Pandit */ 324a2da0b8SParav Pandit 334a2da0b8SParav Pandit #include <linux/debugfs.h> 344a2da0b8SParav Pandit 354a2da0b8SParav Pandit #include "mlx5_ib.h" 364a2da0b8SParav Pandit #include "cmd.h" 374a2da0b8SParav Pandit 384a2da0b8SParav Pandit enum mlx5_ib_cong_node_type { 394a2da0b8SParav Pandit MLX5_IB_RROCE_ECN_RP = 1, 404a2da0b8SParav Pandit MLX5_IB_RROCE_ECN_NP = 2, 414a2da0b8SParav Pandit }; 424a2da0b8SParav Pandit 434a2da0b8SParav Pandit static const char * const mlx5_ib_dbg_cc_name[] = { 444a2da0b8SParav Pandit "rp_clamp_tgt_rate", 454a2da0b8SParav Pandit "rp_clamp_tgt_rate_ati", 464a2da0b8SParav Pandit "rp_time_reset", 474a2da0b8SParav Pandit "rp_byte_reset", 484a2da0b8SParav Pandit "rp_threshold", 494a2da0b8SParav Pandit "rp_ai_rate", 50*9e3aaf68SParav Pandit "rp_max_rate", 514a2da0b8SParav Pandit "rp_hai_rate", 524a2da0b8SParav Pandit "rp_min_dec_fac", 534a2da0b8SParav Pandit "rp_min_rate", 544a2da0b8SParav Pandit "rp_rate_to_set_on_first_cnp", 554a2da0b8SParav Pandit "rp_dce_tcp_g", 564a2da0b8SParav Pandit "rp_dce_tcp_rtt", 574a2da0b8SParav Pandit "rp_rate_reduce_monitor_period", 584a2da0b8SParav Pandit "rp_initial_alpha_value", 594a2da0b8SParav Pandit "rp_gd", 60*9e3aaf68SParav Pandit "np_min_time_between_cnps", 614a2da0b8SParav Pandit "np_cnp_dscp", 624a2da0b8SParav Pandit "np_cnp_prio_mode", 634a2da0b8SParav Pandit "np_cnp_prio", 644a2da0b8SParav Pandit }; 654a2da0b8SParav Pandit 664a2da0b8SParav Pandit #define MLX5_IB_RP_CLAMP_TGT_RATE_ATTR BIT(1) 674a2da0b8SParav Pandit #define MLX5_IB_RP_CLAMP_TGT_RATE_ATI_ATTR BIT(2) 684a2da0b8SParav Pandit #define MLX5_IB_RP_TIME_RESET_ATTR BIT(3) 694a2da0b8SParav Pandit #define MLX5_IB_RP_BYTE_RESET_ATTR BIT(4) 704a2da0b8SParav Pandit #define MLX5_IB_RP_THRESHOLD_ATTR BIT(5) 71*9e3aaf68SParav Pandit #define MLX5_IB_RP_MAX_RATE_ATTR BIT(6) 724a2da0b8SParav Pandit #define MLX5_IB_RP_AI_RATE_ATTR BIT(7) 734a2da0b8SParav Pandit #define MLX5_IB_RP_HAI_RATE_ATTR BIT(8) 744a2da0b8SParav Pandit #define MLX5_IB_RP_MIN_DEC_FAC_ATTR BIT(9) 754a2da0b8SParav Pandit #define MLX5_IB_RP_MIN_RATE_ATTR BIT(10) 764a2da0b8SParav Pandit #define MLX5_IB_RP_RATE_TO_SET_ON_FIRST_CNP_ATTR BIT(11) 774a2da0b8SParav Pandit #define MLX5_IB_RP_DCE_TCP_G_ATTR BIT(12) 784a2da0b8SParav Pandit #define MLX5_IB_RP_DCE_TCP_RTT_ATTR BIT(13) 794a2da0b8SParav Pandit #define MLX5_IB_RP_RATE_REDUCE_MONITOR_PERIOD_ATTR BIT(14) 804a2da0b8SParav Pandit #define MLX5_IB_RP_INITIAL_ALPHA_VALUE_ATTR BIT(15) 814a2da0b8SParav Pandit #define MLX5_IB_RP_GD_ATTR BIT(16) 824a2da0b8SParav Pandit 83*9e3aaf68SParav Pandit #define MLX5_IB_NP_MIN_TIME_BETWEEN_CNPS_ATTR BIT(2) 844a2da0b8SParav Pandit #define MLX5_IB_NP_CNP_DSCP_ATTR BIT(3) 854a2da0b8SParav Pandit #define MLX5_IB_NP_CNP_PRIO_MODE_ATTR BIT(4) 864a2da0b8SParav Pandit 874a2da0b8SParav Pandit static enum mlx5_ib_cong_node_type 884a2da0b8SParav Pandit mlx5_ib_param_to_node(enum mlx5_ib_dbg_cc_types param_offset) 894a2da0b8SParav Pandit { 904a2da0b8SParav Pandit if (param_offset >= MLX5_IB_DBG_CC_RP_CLAMP_TGT_RATE && 914a2da0b8SParav Pandit param_offset <= MLX5_IB_DBG_CC_RP_GD) 924a2da0b8SParav Pandit return MLX5_IB_RROCE_ECN_RP; 934a2da0b8SParav Pandit else 944a2da0b8SParav Pandit return MLX5_IB_RROCE_ECN_NP; 954a2da0b8SParav Pandit } 964a2da0b8SParav Pandit 974a2da0b8SParav Pandit static u32 mlx5_get_cc_param_val(void *field, int offset) 984a2da0b8SParav Pandit { 994a2da0b8SParav Pandit switch (offset) { 1004a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_CLAMP_TGT_RATE: 1014a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 1024a2da0b8SParav Pandit clamp_tgt_rate); 1034a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_CLAMP_TGT_RATE_ATI: 1044a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 1054a2da0b8SParav Pandit clamp_tgt_rate_after_time_inc); 1064a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_TIME_RESET: 1074a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 1084a2da0b8SParav Pandit rpg_time_reset); 1094a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_BYTE_RESET: 1104a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 1114a2da0b8SParav Pandit rpg_byte_reset); 1124a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_THRESHOLD: 1134a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 1144a2da0b8SParav Pandit rpg_threshold); 1154a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_AI_RATE: 1164a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 1174a2da0b8SParav Pandit rpg_ai_rate); 118*9e3aaf68SParav Pandit case MLX5_IB_DBG_CC_RP_MAX_RATE: 119*9e3aaf68SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 120*9e3aaf68SParav Pandit rpg_max_rate); 1214a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_HAI_RATE: 1224a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 1234a2da0b8SParav Pandit rpg_hai_rate); 1244a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_MIN_DEC_FAC: 1254a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 1264a2da0b8SParav Pandit rpg_min_dec_fac); 1274a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_MIN_RATE: 1284a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 1294a2da0b8SParav Pandit rpg_min_rate); 1304a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_RATE_TO_SET_ON_FIRST_CNP: 1314a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 1324a2da0b8SParav Pandit rate_to_set_on_first_cnp); 1334a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_DCE_TCP_G: 1344a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 1354a2da0b8SParav Pandit dce_tcp_g); 1364a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_DCE_TCP_RTT: 1374a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 1384a2da0b8SParav Pandit dce_tcp_rtt); 1394a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_RATE_REDUCE_MONITOR_PERIOD: 1404a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 1414a2da0b8SParav Pandit rate_reduce_monitor_period); 1424a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_INITIAL_ALPHA_VALUE: 1434a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 1444a2da0b8SParav Pandit initial_alpha_value); 1454a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_GD: 1464a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 1474a2da0b8SParav Pandit rpg_gd); 148*9e3aaf68SParav Pandit case MLX5_IB_DBG_CC_NP_MIN_TIME_BETWEEN_CNPS: 149*9e3aaf68SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_np, field, 150*9e3aaf68SParav Pandit min_time_between_cnps); 1514a2da0b8SParav Pandit case MLX5_IB_DBG_CC_NP_CNP_DSCP: 1524a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_np, field, 1534a2da0b8SParav Pandit cnp_dscp); 1544a2da0b8SParav Pandit case MLX5_IB_DBG_CC_NP_CNP_PRIO_MODE: 1554a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_np, field, 1564a2da0b8SParav Pandit cnp_prio_mode); 1574a2da0b8SParav Pandit case MLX5_IB_DBG_CC_NP_CNP_PRIO: 1584a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_np, field, 1594a2da0b8SParav Pandit cnp_802p_prio); 1604a2da0b8SParav Pandit default: 1614a2da0b8SParav Pandit return 0; 1624a2da0b8SParav Pandit } 1634a2da0b8SParav Pandit } 1644a2da0b8SParav Pandit 1654a2da0b8SParav Pandit static void mlx5_ib_set_cc_param_mask_val(void *field, int offset, 1664a2da0b8SParav Pandit u32 var, u32 *attr_mask) 1674a2da0b8SParav Pandit { 1684a2da0b8SParav Pandit switch (offset) { 1694a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_CLAMP_TGT_RATE: 1704a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_CLAMP_TGT_RATE_ATTR; 1714a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 1724a2da0b8SParav Pandit clamp_tgt_rate, var); 1734a2da0b8SParav Pandit break; 1744a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_CLAMP_TGT_RATE_ATI: 1754a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_CLAMP_TGT_RATE_ATI_ATTR; 1764a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 1774a2da0b8SParav Pandit clamp_tgt_rate_after_time_inc, var); 1784a2da0b8SParav Pandit break; 1794a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_TIME_RESET: 1804a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_TIME_RESET_ATTR; 1814a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 1824a2da0b8SParav Pandit rpg_time_reset, var); 1834a2da0b8SParav Pandit break; 1844a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_BYTE_RESET: 1854a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_BYTE_RESET_ATTR; 1864a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 1874a2da0b8SParav Pandit rpg_byte_reset, var); 1884a2da0b8SParav Pandit break; 1894a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_THRESHOLD: 1904a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_THRESHOLD_ATTR; 1914a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 1924a2da0b8SParav Pandit rpg_threshold, var); 1934a2da0b8SParav Pandit break; 1944a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_AI_RATE: 1954a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_AI_RATE_ATTR; 1964a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 1974a2da0b8SParav Pandit rpg_ai_rate, var); 1984a2da0b8SParav Pandit break; 199*9e3aaf68SParav Pandit case MLX5_IB_DBG_CC_RP_MAX_RATE: 200*9e3aaf68SParav Pandit *attr_mask |= MLX5_IB_RP_MAX_RATE_ATTR; 201*9e3aaf68SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 202*9e3aaf68SParav Pandit rpg_max_rate, var); 203*9e3aaf68SParav Pandit break; 2044a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_HAI_RATE: 2054a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_HAI_RATE_ATTR; 2064a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 2074a2da0b8SParav Pandit rpg_hai_rate, var); 2084a2da0b8SParav Pandit break; 2094a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_MIN_DEC_FAC: 2104a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_MIN_DEC_FAC_ATTR; 2114a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 2124a2da0b8SParav Pandit rpg_min_dec_fac, var); 2134a2da0b8SParav Pandit break; 2144a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_MIN_RATE: 2154a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_MIN_RATE_ATTR; 2164a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 2174a2da0b8SParav Pandit rpg_min_rate, var); 2184a2da0b8SParav Pandit break; 2194a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_RATE_TO_SET_ON_FIRST_CNP: 2204a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_RATE_TO_SET_ON_FIRST_CNP_ATTR; 2214a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 2224a2da0b8SParav Pandit rate_to_set_on_first_cnp, var); 2234a2da0b8SParav Pandit break; 2244a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_DCE_TCP_G: 2254a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_DCE_TCP_G_ATTR; 2264a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 2274a2da0b8SParav Pandit dce_tcp_g, var); 2284a2da0b8SParav Pandit break; 2294a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_DCE_TCP_RTT: 2304a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_DCE_TCP_RTT_ATTR; 2314a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 2324a2da0b8SParav Pandit dce_tcp_rtt, var); 2334a2da0b8SParav Pandit break; 2344a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_RATE_REDUCE_MONITOR_PERIOD: 2354a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_RATE_REDUCE_MONITOR_PERIOD_ATTR; 2364a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 2374a2da0b8SParav Pandit rate_reduce_monitor_period, var); 2384a2da0b8SParav Pandit break; 2394a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_INITIAL_ALPHA_VALUE: 2404a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_INITIAL_ALPHA_VALUE_ATTR; 2414a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 2424a2da0b8SParav Pandit initial_alpha_value, var); 2434a2da0b8SParav Pandit break; 2444a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_GD: 2454a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_GD_ATTR; 2464a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 2474a2da0b8SParav Pandit rpg_gd, var); 2484a2da0b8SParav Pandit break; 249*9e3aaf68SParav Pandit case MLX5_IB_DBG_CC_NP_MIN_TIME_BETWEEN_CNPS: 250*9e3aaf68SParav Pandit *attr_mask |= MLX5_IB_NP_MIN_TIME_BETWEEN_CNPS_ATTR; 251*9e3aaf68SParav Pandit MLX5_SET(cong_control_r_roce_ecn_np, field, 252*9e3aaf68SParav Pandit min_time_between_cnps, var); 253*9e3aaf68SParav Pandit break; 2544a2da0b8SParav Pandit case MLX5_IB_DBG_CC_NP_CNP_DSCP: 2554a2da0b8SParav Pandit *attr_mask |= MLX5_IB_NP_CNP_DSCP_ATTR; 2564a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_np, field, cnp_dscp, var); 2574a2da0b8SParav Pandit break; 2584a2da0b8SParav Pandit case MLX5_IB_DBG_CC_NP_CNP_PRIO_MODE: 2594a2da0b8SParav Pandit *attr_mask |= MLX5_IB_NP_CNP_PRIO_MODE_ATTR; 2604a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_np, field, cnp_prio_mode, var); 2614a2da0b8SParav Pandit break; 2624a2da0b8SParav Pandit case MLX5_IB_DBG_CC_NP_CNP_PRIO: 2634a2da0b8SParav Pandit *attr_mask |= MLX5_IB_NP_CNP_PRIO_MODE_ATTR; 2644a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_np, field, cnp_prio_mode, 0); 2654a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_np, field, cnp_802p_prio, var); 2664a2da0b8SParav Pandit break; 2674a2da0b8SParav Pandit } 2684a2da0b8SParav Pandit } 2694a2da0b8SParav Pandit 270a9e546e7SParav Pandit static int mlx5_ib_get_cc_params(struct mlx5_ib_dev *dev, u8 port_num, 271a9e546e7SParav Pandit int offset, u32 *var) 2724a2da0b8SParav Pandit { 2734a2da0b8SParav Pandit int outlen = MLX5_ST_SZ_BYTES(query_cong_params_out); 2744a2da0b8SParav Pandit void *out; 2754a2da0b8SParav Pandit void *field; 2764a2da0b8SParav Pandit int err; 2774a2da0b8SParav Pandit enum mlx5_ib_cong_node_type node; 278a9e546e7SParav Pandit struct mlx5_core_dev *mdev; 279a9e546e7SParav Pandit 280a9e546e7SParav Pandit /* Takes a 1-based port number */ 281a9e546e7SParav Pandit mdev = mlx5_ib_get_native_port_mdev(dev, port_num + 1, NULL); 282a9e546e7SParav Pandit if (!mdev) 283a9e546e7SParav Pandit return -ENODEV; 2844a2da0b8SParav Pandit 2854a2da0b8SParav Pandit out = kvzalloc(outlen, GFP_KERNEL); 286a9e546e7SParav Pandit if (!out) { 287a9e546e7SParav Pandit err = -ENOMEM; 288a9e546e7SParav Pandit goto alloc_err; 289a9e546e7SParav Pandit } 2904a2da0b8SParav Pandit 2914a2da0b8SParav Pandit node = mlx5_ib_param_to_node(offset); 2924a2da0b8SParav Pandit 293a9e546e7SParav Pandit err = mlx5_cmd_query_cong_params(mdev, node, out, outlen); 2944a2da0b8SParav Pandit if (err) 2954a2da0b8SParav Pandit goto free; 2964a2da0b8SParav Pandit 2974a2da0b8SParav Pandit field = MLX5_ADDR_OF(query_cong_params_out, out, congestion_parameters); 2984a2da0b8SParav Pandit *var = mlx5_get_cc_param_val(field, offset); 2994a2da0b8SParav Pandit 3004a2da0b8SParav Pandit free: 3014a2da0b8SParav Pandit kvfree(out); 302a9e546e7SParav Pandit alloc_err: 303a9e546e7SParav Pandit mlx5_ib_put_native_port_mdev(dev, port_num + 1); 3044a2da0b8SParav Pandit return err; 3054a2da0b8SParav Pandit } 3064a2da0b8SParav Pandit 307a9e546e7SParav Pandit static int mlx5_ib_set_cc_params(struct mlx5_ib_dev *dev, u8 port_num, 308a9e546e7SParav Pandit int offset, u32 var) 3094a2da0b8SParav Pandit { 3104a2da0b8SParav Pandit int inlen = MLX5_ST_SZ_BYTES(modify_cong_params_in); 3114a2da0b8SParav Pandit void *in; 3124a2da0b8SParav Pandit void *field; 3134a2da0b8SParav Pandit enum mlx5_ib_cong_node_type node; 314a9e546e7SParav Pandit struct mlx5_core_dev *mdev; 3154a2da0b8SParav Pandit u32 attr_mask = 0; 3164a2da0b8SParav Pandit int err; 3174a2da0b8SParav Pandit 318a9e546e7SParav Pandit /* Takes a 1-based port number */ 319a9e546e7SParav Pandit mdev = mlx5_ib_get_native_port_mdev(dev, port_num + 1, NULL); 320a9e546e7SParav Pandit if (!mdev) 321a9e546e7SParav Pandit return -ENODEV; 322a9e546e7SParav Pandit 3234a2da0b8SParav Pandit in = kvzalloc(inlen, GFP_KERNEL); 324a9e546e7SParav Pandit if (!in) { 325a9e546e7SParav Pandit err = -ENOMEM; 326a9e546e7SParav Pandit goto alloc_err; 327a9e546e7SParav Pandit } 3284a2da0b8SParav Pandit 3294a2da0b8SParav Pandit MLX5_SET(modify_cong_params_in, in, opcode, 3304a2da0b8SParav Pandit MLX5_CMD_OP_MODIFY_CONG_PARAMS); 3314a2da0b8SParav Pandit 3324a2da0b8SParav Pandit node = mlx5_ib_param_to_node(offset); 3334a2da0b8SParav Pandit MLX5_SET(modify_cong_params_in, in, cong_protocol, node); 3344a2da0b8SParav Pandit 3354a2da0b8SParav Pandit field = MLX5_ADDR_OF(modify_cong_params_in, in, congestion_parameters); 3364a2da0b8SParav Pandit mlx5_ib_set_cc_param_mask_val(field, offset, var, &attr_mask); 3374a2da0b8SParav Pandit 3384a2da0b8SParav Pandit field = MLX5_ADDR_OF(modify_cong_params_in, in, field_select); 3394a2da0b8SParav Pandit MLX5_SET(field_select_r_roce_rp, field, field_select_r_roce_rp, 3404a2da0b8SParav Pandit attr_mask); 3414a2da0b8SParav Pandit 342a9e546e7SParav Pandit err = mlx5_cmd_modify_cong_params(mdev, in, inlen); 3434a2da0b8SParav Pandit kvfree(in); 344a9e546e7SParav Pandit alloc_err: 345a9e546e7SParav Pandit mlx5_ib_put_native_port_mdev(dev, port_num + 1); 3464a2da0b8SParav Pandit return err; 3474a2da0b8SParav Pandit } 3484a2da0b8SParav Pandit 3494a2da0b8SParav Pandit static ssize_t set_param(struct file *filp, const char __user *buf, 3504a2da0b8SParav Pandit size_t count, loff_t *pos) 3514a2da0b8SParav Pandit { 3524a2da0b8SParav Pandit struct mlx5_ib_dbg_param *param = filp->private_data; 3534a2da0b8SParav Pandit int offset = param->offset; 3544a2da0b8SParav Pandit char lbuf[11] = { }; 3554a2da0b8SParav Pandit u32 var; 3564a2da0b8SParav Pandit int ret; 3574a2da0b8SParav Pandit 3584a2da0b8SParav Pandit if (count > sizeof(lbuf)) 3594a2da0b8SParav Pandit return -EINVAL; 3604a2da0b8SParav Pandit 3614a2da0b8SParav Pandit if (copy_from_user(lbuf, buf, count)) 3624a2da0b8SParav Pandit return -EFAULT; 3634a2da0b8SParav Pandit 3644a2da0b8SParav Pandit lbuf[sizeof(lbuf) - 1] = '\0'; 3654a2da0b8SParav Pandit 3664a2da0b8SParav Pandit if (kstrtou32(lbuf, 0, &var)) 3674a2da0b8SParav Pandit return -EINVAL; 3684a2da0b8SParav Pandit 369a9e546e7SParav Pandit ret = mlx5_ib_set_cc_params(param->dev, param->port_num, offset, var); 3704a2da0b8SParav Pandit return ret ? ret : count; 3714a2da0b8SParav Pandit } 3724a2da0b8SParav Pandit 3734a2da0b8SParav Pandit static ssize_t get_param(struct file *filp, char __user *buf, size_t count, 3744a2da0b8SParav Pandit loff_t *pos) 3754a2da0b8SParav Pandit { 3764a2da0b8SParav Pandit struct mlx5_ib_dbg_param *param = filp->private_data; 3774a2da0b8SParav Pandit int offset = param->offset; 3784a2da0b8SParav Pandit u32 var = 0; 3794a2da0b8SParav Pandit int ret; 3804a2da0b8SParav Pandit char lbuf[11]; 3814a2da0b8SParav Pandit 382a9e546e7SParav Pandit ret = mlx5_ib_get_cc_params(param->dev, param->port_num, offset, &var); 3834a2da0b8SParav Pandit if (ret) 3844a2da0b8SParav Pandit return ret; 3854a2da0b8SParav Pandit 3864a2da0b8SParav Pandit ret = snprintf(lbuf, sizeof(lbuf), "%d\n", var); 3874a2da0b8SParav Pandit if (ret < 0) 3884a2da0b8SParav Pandit return ret; 3894a2da0b8SParav Pandit 39060e6627fSJann Horn return simple_read_from_buffer(buf, count, pos, lbuf, ret); 3914a2da0b8SParav Pandit } 3924a2da0b8SParav Pandit 3934a2da0b8SParav Pandit static const struct file_operations dbg_cc_fops = { 3944a2da0b8SParav Pandit .owner = THIS_MODULE, 3954a2da0b8SParav Pandit .open = simple_open, 3964a2da0b8SParav Pandit .write = set_param, 3974a2da0b8SParav Pandit .read = get_param, 3984a2da0b8SParav Pandit }; 3994a2da0b8SParav Pandit 400a9e546e7SParav Pandit void mlx5_ib_cleanup_cong_debugfs(struct mlx5_ib_dev *dev, u8 port_num) 4014a2da0b8SParav Pandit { 4024a2da0b8SParav Pandit if (!mlx5_debugfs_root || 403a9e546e7SParav Pandit !dev->port[port_num].dbg_cc_params || 404a9e546e7SParav Pandit !dev->port[port_num].dbg_cc_params->root) 4054a2da0b8SParav Pandit return; 4064a2da0b8SParav Pandit 407a9e546e7SParav Pandit debugfs_remove_recursive(dev->port[port_num].dbg_cc_params->root); 408a9e546e7SParav Pandit kfree(dev->port[port_num].dbg_cc_params); 409a9e546e7SParav Pandit dev->port[port_num].dbg_cc_params = NULL; 4104a2da0b8SParav Pandit } 4114a2da0b8SParav Pandit 41273eb8f03SGreg Kroah-Hartman void mlx5_ib_init_cong_debugfs(struct mlx5_ib_dev *dev, u8 port_num) 4134a2da0b8SParav Pandit { 4144a2da0b8SParav Pandit struct mlx5_ib_dbg_cc_params *dbg_cc_params; 415a9e546e7SParav Pandit struct mlx5_core_dev *mdev; 4164a2da0b8SParav Pandit int i; 4174a2da0b8SParav Pandit 4184a2da0b8SParav Pandit if (!mlx5_debugfs_root) 41973eb8f03SGreg Kroah-Hartman return; 4204a2da0b8SParav Pandit 421a9e546e7SParav Pandit /* Takes a 1-based port number */ 422a9e546e7SParav Pandit mdev = mlx5_ib_get_native_port_mdev(dev, port_num + 1, NULL); 423a9e546e7SParav Pandit if (!mdev) 42473eb8f03SGreg Kroah-Hartman return; 4254a2da0b8SParav Pandit 426a9e546e7SParav Pandit if (!MLX5_CAP_GEN(mdev, cc_query_allowed) || 427a9e546e7SParav Pandit !MLX5_CAP_GEN(mdev, cc_modify_allowed)) 428a9e546e7SParav Pandit goto put_mdev; 429a9e546e7SParav Pandit 4304a2da0b8SParav Pandit dbg_cc_params = kzalloc(sizeof(*dbg_cc_params), GFP_KERNEL); 4314a2da0b8SParav Pandit if (!dbg_cc_params) 432a9e546e7SParav Pandit goto err; 4334a2da0b8SParav Pandit 434a9e546e7SParav Pandit dev->port[port_num].dbg_cc_params = dbg_cc_params; 4354a2da0b8SParav Pandit 4364a2da0b8SParav Pandit dbg_cc_params->root = debugfs_create_dir("cc_params", 437a9e546e7SParav Pandit mdev->priv.dbg_root); 4384a2da0b8SParav Pandit 4394a2da0b8SParav Pandit for (i = 0; i < MLX5_IB_DBG_CC_MAX; i++) { 4404a2da0b8SParav Pandit dbg_cc_params->params[i].offset = i; 4414a2da0b8SParav Pandit dbg_cc_params->params[i].dev = dev; 442a9e546e7SParav Pandit dbg_cc_params->params[i].port_num = port_num; 4434a2da0b8SParav Pandit dbg_cc_params->params[i].dentry = 4444a2da0b8SParav Pandit debugfs_create_file(mlx5_ib_dbg_cc_name[i], 4454a2da0b8SParav Pandit 0600, dbg_cc_params->root, 4464a2da0b8SParav Pandit &dbg_cc_params->params[i], 4474a2da0b8SParav Pandit &dbg_cc_fops); 4484a2da0b8SParav Pandit } 449a9e546e7SParav Pandit 450a9e546e7SParav Pandit put_mdev: 451a9e546e7SParav Pandit mlx5_ib_put_native_port_mdev(dev, port_num + 1); 45273eb8f03SGreg Kroah-Hartman return; 4534a2da0b8SParav Pandit 4544a2da0b8SParav Pandit err: 4554a2da0b8SParav Pandit mlx5_ib_warn(dev, "cong debugfs failure\n"); 456a9e546e7SParav Pandit mlx5_ib_cleanup_cong_debugfs(dev, port_num); 457a9e546e7SParav Pandit mlx5_ib_put_native_port_mdev(dev, port_num + 1); 458a9e546e7SParav Pandit 4594a2da0b8SParav Pandit /* 4604a2da0b8SParav Pandit * We don't want to fail driver if debugfs failed to initialize, 4614a2da0b8SParav Pandit * so we are not forwarding error to the user. 4624a2da0b8SParav Pandit */ 46373eb8f03SGreg Kroah-Hartman return; 4644a2da0b8SParav Pandit } 465