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, 4166fb1d5dSEdward Srouji MLX5_IB_RROCE_GENERAL = 3, 424a2da0b8SParav Pandit }; 434a2da0b8SParav Pandit 444a2da0b8SParav Pandit static const char * const mlx5_ib_dbg_cc_name[] = { 454a2da0b8SParav Pandit "rp_clamp_tgt_rate", 464a2da0b8SParav Pandit "rp_clamp_tgt_rate_ati", 474a2da0b8SParav Pandit "rp_time_reset", 484a2da0b8SParav Pandit "rp_byte_reset", 494a2da0b8SParav Pandit "rp_threshold", 504a2da0b8SParav Pandit "rp_ai_rate", 519e3aaf68SParav Pandit "rp_max_rate", 524a2da0b8SParav Pandit "rp_hai_rate", 534a2da0b8SParav Pandit "rp_min_dec_fac", 544a2da0b8SParav Pandit "rp_min_rate", 554a2da0b8SParav Pandit "rp_rate_to_set_on_first_cnp", 564a2da0b8SParav Pandit "rp_dce_tcp_g", 574a2da0b8SParav Pandit "rp_dce_tcp_rtt", 584a2da0b8SParav Pandit "rp_rate_reduce_monitor_period", 594a2da0b8SParav Pandit "rp_initial_alpha_value", 604a2da0b8SParav Pandit "rp_gd", 619e3aaf68SParav Pandit "np_min_time_between_cnps", 624a2da0b8SParav Pandit "np_cnp_dscp", 634a2da0b8SParav Pandit "np_cnp_prio_mode", 644a2da0b8SParav Pandit "np_cnp_prio", 6566fb1d5dSEdward Srouji "rtt_resp_dscp_valid", 6666fb1d5dSEdward Srouji "rtt_resp_dscp", 674a2da0b8SParav Pandit }; 684a2da0b8SParav Pandit 694a2da0b8SParav Pandit #define MLX5_IB_RP_CLAMP_TGT_RATE_ATTR BIT(1) 704a2da0b8SParav Pandit #define MLX5_IB_RP_CLAMP_TGT_RATE_ATI_ATTR BIT(2) 714a2da0b8SParav Pandit #define MLX5_IB_RP_TIME_RESET_ATTR BIT(3) 724a2da0b8SParav Pandit #define MLX5_IB_RP_BYTE_RESET_ATTR BIT(4) 734a2da0b8SParav Pandit #define MLX5_IB_RP_THRESHOLD_ATTR BIT(5) 749e3aaf68SParav Pandit #define MLX5_IB_RP_MAX_RATE_ATTR BIT(6) 754a2da0b8SParav Pandit #define MLX5_IB_RP_AI_RATE_ATTR BIT(7) 764a2da0b8SParav Pandit #define MLX5_IB_RP_HAI_RATE_ATTR BIT(8) 774a2da0b8SParav Pandit #define MLX5_IB_RP_MIN_DEC_FAC_ATTR BIT(9) 784a2da0b8SParav Pandit #define MLX5_IB_RP_MIN_RATE_ATTR BIT(10) 794a2da0b8SParav Pandit #define MLX5_IB_RP_RATE_TO_SET_ON_FIRST_CNP_ATTR BIT(11) 804a2da0b8SParav Pandit #define MLX5_IB_RP_DCE_TCP_G_ATTR BIT(12) 814a2da0b8SParav Pandit #define MLX5_IB_RP_DCE_TCP_RTT_ATTR BIT(13) 824a2da0b8SParav Pandit #define MLX5_IB_RP_RATE_REDUCE_MONITOR_PERIOD_ATTR BIT(14) 834a2da0b8SParav Pandit #define MLX5_IB_RP_INITIAL_ALPHA_VALUE_ATTR BIT(15) 844a2da0b8SParav Pandit #define MLX5_IB_RP_GD_ATTR BIT(16) 854a2da0b8SParav Pandit 869e3aaf68SParav Pandit #define MLX5_IB_NP_MIN_TIME_BETWEEN_CNPS_ATTR BIT(2) 874a2da0b8SParav Pandit #define MLX5_IB_NP_CNP_DSCP_ATTR BIT(3) 884a2da0b8SParav Pandit #define MLX5_IB_NP_CNP_PRIO_MODE_ATTR BIT(4) 894a2da0b8SParav Pandit 9066fb1d5dSEdward Srouji #define MLX5_IB_GENERAL_RTT_RESP_DSCP_ATTR BIT(0) 9166fb1d5dSEdward Srouji 924a2da0b8SParav Pandit static enum mlx5_ib_cong_node_type 934a2da0b8SParav Pandit mlx5_ib_param_to_node(enum mlx5_ib_dbg_cc_types param_offset) 944a2da0b8SParav Pandit { 9566fb1d5dSEdward Srouji if (param_offset <= MLX5_IB_DBG_CC_RP_GD) 964a2da0b8SParav Pandit return MLX5_IB_RROCE_ECN_RP; 9766fb1d5dSEdward Srouji 9866fb1d5dSEdward Srouji if (param_offset <= MLX5_IB_DBG_CC_NP_CNP_PRIO) 994a2da0b8SParav Pandit return MLX5_IB_RROCE_ECN_NP; 10066fb1d5dSEdward Srouji 10166fb1d5dSEdward Srouji return MLX5_IB_RROCE_GENERAL; 1024a2da0b8SParav Pandit } 1034a2da0b8SParav Pandit 1044a2da0b8SParav Pandit static u32 mlx5_get_cc_param_val(void *field, int offset) 1054a2da0b8SParav Pandit { 1064a2da0b8SParav Pandit switch (offset) { 1074a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_CLAMP_TGT_RATE: 1084a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 1094a2da0b8SParav Pandit clamp_tgt_rate); 1104a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_CLAMP_TGT_RATE_ATI: 1114a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 1124a2da0b8SParav Pandit clamp_tgt_rate_after_time_inc); 1134a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_TIME_RESET: 1144a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 1154a2da0b8SParav Pandit rpg_time_reset); 1164a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_BYTE_RESET: 1174a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 1184a2da0b8SParav Pandit rpg_byte_reset); 1194a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_THRESHOLD: 1204a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 1214a2da0b8SParav Pandit rpg_threshold); 1224a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_AI_RATE: 1234a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 1244a2da0b8SParav Pandit rpg_ai_rate); 1259e3aaf68SParav Pandit case MLX5_IB_DBG_CC_RP_MAX_RATE: 1269e3aaf68SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 1279e3aaf68SParav Pandit rpg_max_rate); 1284a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_HAI_RATE: 1294a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 1304a2da0b8SParav Pandit rpg_hai_rate); 1314a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_MIN_DEC_FAC: 1324a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 1334a2da0b8SParav Pandit rpg_min_dec_fac); 1344a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_MIN_RATE: 1354a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 1364a2da0b8SParav Pandit rpg_min_rate); 1374a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_RATE_TO_SET_ON_FIRST_CNP: 1384a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 1394a2da0b8SParav Pandit rate_to_set_on_first_cnp); 1404a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_DCE_TCP_G: 1414a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 1424a2da0b8SParav Pandit dce_tcp_g); 1434a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_DCE_TCP_RTT: 1444a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 1454a2da0b8SParav Pandit dce_tcp_rtt); 1464a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_RATE_REDUCE_MONITOR_PERIOD: 1474a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 1484a2da0b8SParav Pandit rate_reduce_monitor_period); 1494a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_INITIAL_ALPHA_VALUE: 1504a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 1514a2da0b8SParav Pandit initial_alpha_value); 1524a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_GD: 1534a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 1544a2da0b8SParav Pandit rpg_gd); 1559e3aaf68SParav Pandit case MLX5_IB_DBG_CC_NP_MIN_TIME_BETWEEN_CNPS: 1569e3aaf68SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_np, field, 1579e3aaf68SParav Pandit min_time_between_cnps); 1584a2da0b8SParav Pandit case MLX5_IB_DBG_CC_NP_CNP_DSCP: 1594a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_np, field, 1604a2da0b8SParav Pandit cnp_dscp); 1614a2da0b8SParav Pandit case MLX5_IB_DBG_CC_NP_CNP_PRIO_MODE: 1624a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_np, field, 1634a2da0b8SParav Pandit cnp_prio_mode); 1644a2da0b8SParav Pandit case MLX5_IB_DBG_CC_NP_CNP_PRIO: 1654a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_np, field, 1664a2da0b8SParav Pandit cnp_802p_prio); 16766fb1d5dSEdward Srouji case MLX5_IB_DBG_CC_GENERAL_RTT_RESP_DSCP_VALID: 16866fb1d5dSEdward Srouji return MLX5_GET(cong_control_r_roce_general, field, 16966fb1d5dSEdward Srouji rtt_resp_dscp_valid); 17066fb1d5dSEdward Srouji case MLX5_IB_DBG_CC_GENERAL_RTT_RESP_DSCP: 17166fb1d5dSEdward Srouji return MLX5_GET(cong_control_r_roce_general, field, 17266fb1d5dSEdward Srouji rtt_resp_dscp); 1734a2da0b8SParav Pandit default: 1744a2da0b8SParav Pandit return 0; 1754a2da0b8SParav Pandit } 1764a2da0b8SParav Pandit } 1774a2da0b8SParav Pandit 1784a2da0b8SParav Pandit static void mlx5_ib_set_cc_param_mask_val(void *field, int offset, 1794a2da0b8SParav Pandit u32 var, u32 *attr_mask) 1804a2da0b8SParav Pandit { 1814a2da0b8SParav Pandit switch (offset) { 1824a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_CLAMP_TGT_RATE: 1834a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_CLAMP_TGT_RATE_ATTR; 1844a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 1854a2da0b8SParav Pandit clamp_tgt_rate, var); 1864a2da0b8SParav Pandit break; 1874a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_CLAMP_TGT_RATE_ATI: 1884a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_CLAMP_TGT_RATE_ATI_ATTR; 1894a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 1904a2da0b8SParav Pandit clamp_tgt_rate_after_time_inc, var); 1914a2da0b8SParav Pandit break; 1924a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_TIME_RESET: 1934a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_TIME_RESET_ATTR; 1944a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 1954a2da0b8SParav Pandit rpg_time_reset, var); 1964a2da0b8SParav Pandit break; 1974a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_BYTE_RESET: 1984a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_BYTE_RESET_ATTR; 1994a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 2004a2da0b8SParav Pandit rpg_byte_reset, var); 2014a2da0b8SParav Pandit break; 2024a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_THRESHOLD: 2034a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_THRESHOLD_ATTR; 2044a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 2054a2da0b8SParav Pandit rpg_threshold, var); 2064a2da0b8SParav Pandit break; 2074a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_AI_RATE: 2084a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_AI_RATE_ATTR; 2094a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 2104a2da0b8SParav Pandit rpg_ai_rate, var); 2114a2da0b8SParav Pandit break; 2129e3aaf68SParav Pandit case MLX5_IB_DBG_CC_RP_MAX_RATE: 2139e3aaf68SParav Pandit *attr_mask |= MLX5_IB_RP_MAX_RATE_ATTR; 2149e3aaf68SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 2159e3aaf68SParav Pandit rpg_max_rate, var); 2169e3aaf68SParav Pandit break; 2174a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_HAI_RATE: 2184a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_HAI_RATE_ATTR; 2194a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 2204a2da0b8SParav Pandit rpg_hai_rate, var); 2214a2da0b8SParav Pandit break; 2224a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_MIN_DEC_FAC: 2234a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_MIN_DEC_FAC_ATTR; 2244a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 2254a2da0b8SParav Pandit rpg_min_dec_fac, var); 2264a2da0b8SParav Pandit break; 2274a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_MIN_RATE: 2284a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_MIN_RATE_ATTR; 2294a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 2304a2da0b8SParav Pandit rpg_min_rate, var); 2314a2da0b8SParav Pandit break; 2324a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_RATE_TO_SET_ON_FIRST_CNP: 2334a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_RATE_TO_SET_ON_FIRST_CNP_ATTR; 2344a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 2354a2da0b8SParav Pandit rate_to_set_on_first_cnp, var); 2364a2da0b8SParav Pandit break; 2374a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_DCE_TCP_G: 2384a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_DCE_TCP_G_ATTR; 2394a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 2404a2da0b8SParav Pandit dce_tcp_g, var); 2414a2da0b8SParav Pandit break; 2424a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_DCE_TCP_RTT: 2434a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_DCE_TCP_RTT_ATTR; 2444a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 2454a2da0b8SParav Pandit dce_tcp_rtt, var); 2464a2da0b8SParav Pandit break; 2474a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_RATE_REDUCE_MONITOR_PERIOD: 2484a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_RATE_REDUCE_MONITOR_PERIOD_ATTR; 2494a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 2504a2da0b8SParav Pandit rate_reduce_monitor_period, var); 2514a2da0b8SParav Pandit break; 2524a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_INITIAL_ALPHA_VALUE: 2534a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_INITIAL_ALPHA_VALUE_ATTR; 2544a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 2554a2da0b8SParav Pandit initial_alpha_value, var); 2564a2da0b8SParav Pandit break; 2574a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_GD: 2584a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_GD_ATTR; 2594a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 2604a2da0b8SParav Pandit rpg_gd, var); 2614a2da0b8SParav Pandit break; 2629e3aaf68SParav Pandit case MLX5_IB_DBG_CC_NP_MIN_TIME_BETWEEN_CNPS: 2639e3aaf68SParav Pandit *attr_mask |= MLX5_IB_NP_MIN_TIME_BETWEEN_CNPS_ATTR; 2649e3aaf68SParav Pandit MLX5_SET(cong_control_r_roce_ecn_np, field, 2659e3aaf68SParav Pandit min_time_between_cnps, var); 2669e3aaf68SParav Pandit break; 2674a2da0b8SParav Pandit case MLX5_IB_DBG_CC_NP_CNP_DSCP: 2684a2da0b8SParav Pandit *attr_mask |= MLX5_IB_NP_CNP_DSCP_ATTR; 2694a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_np, field, cnp_dscp, var); 2704a2da0b8SParav Pandit break; 2714a2da0b8SParav Pandit case MLX5_IB_DBG_CC_NP_CNP_PRIO_MODE: 2724a2da0b8SParav Pandit *attr_mask |= MLX5_IB_NP_CNP_PRIO_MODE_ATTR; 2734a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_np, field, cnp_prio_mode, var); 2744a2da0b8SParav Pandit break; 2754a2da0b8SParav Pandit case MLX5_IB_DBG_CC_NP_CNP_PRIO: 2764a2da0b8SParav Pandit *attr_mask |= MLX5_IB_NP_CNP_PRIO_MODE_ATTR; 2774a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_np, field, cnp_prio_mode, 0); 2784a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_np, field, cnp_802p_prio, var); 2794a2da0b8SParav Pandit break; 28066fb1d5dSEdward Srouji case MLX5_IB_DBG_CC_GENERAL_RTT_RESP_DSCP_VALID: 28166fb1d5dSEdward Srouji *attr_mask |= MLX5_IB_GENERAL_RTT_RESP_DSCP_ATTR; 28266fb1d5dSEdward Srouji MLX5_SET(cong_control_r_roce_general, field, rtt_resp_dscp_valid, var); 28366fb1d5dSEdward Srouji break; 28466fb1d5dSEdward Srouji case MLX5_IB_DBG_CC_GENERAL_RTT_RESP_DSCP: 28566fb1d5dSEdward Srouji *attr_mask |= MLX5_IB_GENERAL_RTT_RESP_DSCP_ATTR; 28666fb1d5dSEdward Srouji MLX5_SET(cong_control_r_roce_general, field, rtt_resp_dscp_valid, 1); 28766fb1d5dSEdward Srouji MLX5_SET(cong_control_r_roce_general, field, rtt_resp_dscp, var); 28866fb1d5dSEdward Srouji break; 2894a2da0b8SParav Pandit } 2904a2da0b8SParav Pandit } 2914a2da0b8SParav Pandit 2921fb7f897SMark Bloch static int mlx5_ib_get_cc_params(struct mlx5_ib_dev *dev, u32 port_num, 293a9e546e7SParav Pandit int offset, u32 *var) 2944a2da0b8SParav Pandit { 2954a2da0b8SParav Pandit int outlen = MLX5_ST_SZ_BYTES(query_cong_params_out); 2964a2da0b8SParav Pandit void *out; 2974a2da0b8SParav Pandit void *field; 2984a2da0b8SParav Pandit int err; 2994a2da0b8SParav Pandit enum mlx5_ib_cong_node_type node; 300a9e546e7SParav Pandit struct mlx5_core_dev *mdev; 301a9e546e7SParav Pandit 302a9e546e7SParav Pandit /* Takes a 1-based port number */ 303a9e546e7SParav Pandit mdev = mlx5_ib_get_native_port_mdev(dev, port_num + 1, NULL); 304a9e546e7SParav Pandit if (!mdev) 305a9e546e7SParav Pandit return -ENODEV; 3064a2da0b8SParav Pandit 3074a2da0b8SParav Pandit out = kvzalloc(outlen, GFP_KERNEL); 308a9e546e7SParav Pandit if (!out) { 309a9e546e7SParav Pandit err = -ENOMEM; 310a9e546e7SParav Pandit goto alloc_err; 311a9e546e7SParav Pandit } 3124a2da0b8SParav Pandit 3134a2da0b8SParav Pandit node = mlx5_ib_param_to_node(offset); 3144a2da0b8SParav Pandit 31531578defSLeon Romanovsky err = mlx5_cmd_query_cong_params(mdev, node, out); 3164a2da0b8SParav Pandit if (err) 3174a2da0b8SParav Pandit goto free; 3184a2da0b8SParav Pandit 3194a2da0b8SParav Pandit field = MLX5_ADDR_OF(query_cong_params_out, out, congestion_parameters); 3204a2da0b8SParav Pandit *var = mlx5_get_cc_param_val(field, offset); 3214a2da0b8SParav Pandit 3224a2da0b8SParav Pandit free: 3234a2da0b8SParav Pandit kvfree(out); 324a9e546e7SParav Pandit alloc_err: 325a9e546e7SParav Pandit mlx5_ib_put_native_port_mdev(dev, port_num + 1); 3264a2da0b8SParav Pandit return err; 3274a2da0b8SParav Pandit } 3284a2da0b8SParav Pandit 3291fb7f897SMark Bloch static int mlx5_ib_set_cc_params(struct mlx5_ib_dev *dev, u32 port_num, 330a9e546e7SParav Pandit int offset, u32 var) 3314a2da0b8SParav Pandit { 3324a2da0b8SParav Pandit int inlen = MLX5_ST_SZ_BYTES(modify_cong_params_in); 3334a2da0b8SParav Pandit void *in; 3344a2da0b8SParav Pandit void *field; 3354a2da0b8SParav Pandit enum mlx5_ib_cong_node_type node; 336a9e546e7SParav Pandit struct mlx5_core_dev *mdev; 3374a2da0b8SParav Pandit u32 attr_mask = 0; 3384a2da0b8SParav Pandit int err; 3394a2da0b8SParav Pandit 340a9e546e7SParav Pandit /* Takes a 1-based port number */ 341a9e546e7SParav Pandit mdev = mlx5_ib_get_native_port_mdev(dev, port_num + 1, NULL); 342a9e546e7SParav Pandit if (!mdev) 343a9e546e7SParav Pandit return -ENODEV; 344a9e546e7SParav Pandit 3454a2da0b8SParav Pandit in = kvzalloc(inlen, GFP_KERNEL); 346a9e546e7SParav Pandit if (!in) { 347a9e546e7SParav Pandit err = -ENOMEM; 348a9e546e7SParav Pandit goto alloc_err; 349a9e546e7SParav Pandit } 3504a2da0b8SParav Pandit 3514a2da0b8SParav Pandit MLX5_SET(modify_cong_params_in, in, opcode, 3524a2da0b8SParav Pandit MLX5_CMD_OP_MODIFY_CONG_PARAMS); 3534a2da0b8SParav Pandit 3544a2da0b8SParav Pandit node = mlx5_ib_param_to_node(offset); 3554a2da0b8SParav Pandit MLX5_SET(modify_cong_params_in, in, cong_protocol, node); 3564a2da0b8SParav Pandit 3574a2da0b8SParav Pandit field = MLX5_ADDR_OF(modify_cong_params_in, in, congestion_parameters); 3584a2da0b8SParav Pandit mlx5_ib_set_cc_param_mask_val(field, offset, var, &attr_mask); 3594a2da0b8SParav Pandit 3604a2da0b8SParav Pandit field = MLX5_ADDR_OF(modify_cong_params_in, in, field_select); 3614a2da0b8SParav Pandit MLX5_SET(field_select_r_roce_rp, field, field_select_r_roce_rp, 3624a2da0b8SParav Pandit attr_mask); 3634a2da0b8SParav Pandit 36431578defSLeon Romanovsky err = mlx5_cmd_exec_in(dev->mdev, modify_cong_params, in); 3654a2da0b8SParav Pandit kvfree(in); 366a9e546e7SParav Pandit alloc_err: 367a9e546e7SParav Pandit mlx5_ib_put_native_port_mdev(dev, port_num + 1); 3684a2da0b8SParav Pandit return err; 3694a2da0b8SParav Pandit } 3704a2da0b8SParav Pandit 3714a2da0b8SParav Pandit static ssize_t set_param(struct file *filp, const char __user *buf, 3724a2da0b8SParav Pandit size_t count, loff_t *pos) 3734a2da0b8SParav Pandit { 3744a2da0b8SParav Pandit struct mlx5_ib_dbg_param *param = filp->private_data; 3754a2da0b8SParav Pandit int offset = param->offset; 3764a2da0b8SParav Pandit char lbuf[11] = { }; 3774a2da0b8SParav Pandit u32 var; 3784a2da0b8SParav Pandit int ret; 3794a2da0b8SParav Pandit 3804a2da0b8SParav Pandit if (count > sizeof(lbuf)) 3814a2da0b8SParav Pandit return -EINVAL; 3824a2da0b8SParav Pandit 3834a2da0b8SParav Pandit if (copy_from_user(lbuf, buf, count)) 3844a2da0b8SParav Pandit return -EFAULT; 3854a2da0b8SParav Pandit 3864a2da0b8SParav Pandit lbuf[sizeof(lbuf) - 1] = '\0'; 3874a2da0b8SParav Pandit 3884a2da0b8SParav Pandit if (kstrtou32(lbuf, 0, &var)) 3894a2da0b8SParav Pandit return -EINVAL; 3904a2da0b8SParav Pandit 391a9e546e7SParav Pandit ret = mlx5_ib_set_cc_params(param->dev, param->port_num, offset, var); 3924a2da0b8SParav Pandit return ret ? ret : count; 3934a2da0b8SParav Pandit } 3944a2da0b8SParav Pandit 3954a2da0b8SParav Pandit static ssize_t get_param(struct file *filp, char __user *buf, size_t count, 3964a2da0b8SParav Pandit loff_t *pos) 3974a2da0b8SParav Pandit { 3984a2da0b8SParav Pandit struct mlx5_ib_dbg_param *param = filp->private_data; 3994a2da0b8SParav Pandit int offset = param->offset; 4004a2da0b8SParav Pandit u32 var = 0; 4014a2da0b8SParav Pandit int ret; 4024a2da0b8SParav Pandit char lbuf[11]; 4034a2da0b8SParav Pandit 404a9e546e7SParav Pandit ret = mlx5_ib_get_cc_params(param->dev, param->port_num, offset, &var); 4054a2da0b8SParav Pandit if (ret) 4064a2da0b8SParav Pandit return ret; 4074a2da0b8SParav Pandit 4084a2da0b8SParav Pandit ret = snprintf(lbuf, sizeof(lbuf), "%d\n", var); 4094a2da0b8SParav Pandit if (ret < 0) 4104a2da0b8SParav Pandit return ret; 4114a2da0b8SParav Pandit 41260e6627fSJann Horn return simple_read_from_buffer(buf, count, pos, lbuf, ret); 4134a2da0b8SParav Pandit } 4144a2da0b8SParav Pandit 4154a2da0b8SParav Pandit static const struct file_operations dbg_cc_fops = { 4164a2da0b8SParav Pandit .owner = THIS_MODULE, 4174a2da0b8SParav Pandit .open = simple_open, 4184a2da0b8SParav Pandit .write = set_param, 4194a2da0b8SParav Pandit .read = get_param, 4204a2da0b8SParav Pandit }; 4214a2da0b8SParav Pandit 4221fb7f897SMark Bloch void mlx5_ib_cleanup_cong_debugfs(struct mlx5_ib_dev *dev, u32 port_num) 4234a2da0b8SParav Pandit { 4244a2da0b8SParav Pandit if (!mlx5_debugfs_root || 425a9e546e7SParav Pandit !dev->port[port_num].dbg_cc_params || 426a9e546e7SParav Pandit !dev->port[port_num].dbg_cc_params->root) 4274a2da0b8SParav Pandit return; 4284a2da0b8SParav Pandit 429a9e546e7SParav Pandit debugfs_remove_recursive(dev->port[port_num].dbg_cc_params->root); 430a9e546e7SParav Pandit kfree(dev->port[port_num].dbg_cc_params); 431a9e546e7SParav Pandit dev->port[port_num].dbg_cc_params = NULL; 4324a2da0b8SParav Pandit } 4334a2da0b8SParav Pandit 4341fb7f897SMark Bloch void mlx5_ib_init_cong_debugfs(struct mlx5_ib_dev *dev, u32 port_num) 4354a2da0b8SParav Pandit { 4364a2da0b8SParav Pandit struct mlx5_ib_dbg_cc_params *dbg_cc_params; 437a9e546e7SParav Pandit struct mlx5_core_dev *mdev; 4384a2da0b8SParav Pandit int i; 4394a2da0b8SParav Pandit 4404a2da0b8SParav Pandit if (!mlx5_debugfs_root) 44173eb8f03SGreg Kroah-Hartman return; 4424a2da0b8SParav Pandit 443a9e546e7SParav Pandit /* Takes a 1-based port number */ 444a9e546e7SParav Pandit mdev = mlx5_ib_get_native_port_mdev(dev, port_num + 1, NULL); 445a9e546e7SParav Pandit if (!mdev) 44673eb8f03SGreg Kroah-Hartman return; 4474a2da0b8SParav Pandit 448a9e546e7SParav Pandit if (!MLX5_CAP_GEN(mdev, cc_query_allowed) || 449a9e546e7SParav Pandit !MLX5_CAP_GEN(mdev, cc_modify_allowed)) 450a9e546e7SParav Pandit goto put_mdev; 451a9e546e7SParav Pandit 4524a2da0b8SParav Pandit dbg_cc_params = kzalloc(sizeof(*dbg_cc_params), GFP_KERNEL); 4534a2da0b8SParav Pandit if (!dbg_cc_params) 454a9e546e7SParav Pandit goto err; 4554a2da0b8SParav Pandit 456a9e546e7SParav Pandit dev->port[port_num].dbg_cc_params = dbg_cc_params; 4574a2da0b8SParav Pandit 45866771a1cSMoshe Shemesh dbg_cc_params->root = debugfs_create_dir("cc_params", mlx5_debugfs_get_dev_root(mdev)); 4594a2da0b8SParav Pandit 4604a2da0b8SParav Pandit for (i = 0; i < MLX5_IB_DBG_CC_MAX; i++) { 461*25f7f281SMark Zhang if ((i == MLX5_IB_DBG_CC_GENERAL_RTT_RESP_DSCP_VALID || 462*25f7f281SMark Zhang i == MLX5_IB_DBG_CC_GENERAL_RTT_RESP_DSCP)) 463*25f7f281SMark Zhang if (!MLX5_CAP_GEN(mdev, roce) || 464*25f7f281SMark Zhang !MLX5_CAP_ROCE(mdev, roce_cc_general)) 465*25f7f281SMark Zhang continue; 466*25f7f281SMark Zhang 4674a2da0b8SParav Pandit dbg_cc_params->params[i].offset = i; 4684a2da0b8SParav Pandit dbg_cc_params->params[i].dev = dev; 469a9e546e7SParav Pandit dbg_cc_params->params[i].port_num = port_num; 4704a2da0b8SParav Pandit dbg_cc_params->params[i].dentry = 4714a2da0b8SParav Pandit debugfs_create_file(mlx5_ib_dbg_cc_name[i], 4724a2da0b8SParav Pandit 0600, dbg_cc_params->root, 4734a2da0b8SParav Pandit &dbg_cc_params->params[i], 4744a2da0b8SParav Pandit &dbg_cc_fops); 4754a2da0b8SParav Pandit } 476a9e546e7SParav Pandit 477a9e546e7SParav Pandit put_mdev: 478a9e546e7SParav Pandit mlx5_ib_put_native_port_mdev(dev, port_num + 1); 47973eb8f03SGreg Kroah-Hartman return; 4804a2da0b8SParav Pandit 4814a2da0b8SParav Pandit err: 4824a2da0b8SParav Pandit mlx5_ib_warn(dev, "cong debugfs failure\n"); 483a9e546e7SParav Pandit mlx5_ib_cleanup_cong_debugfs(dev, port_num); 484a9e546e7SParav Pandit mlx5_ib_put_native_port_mdev(dev, port_num + 1); 485a9e546e7SParav Pandit 4864a2da0b8SParav Pandit /* 4874a2da0b8SParav Pandit * We don't want to fail driver if debugfs failed to initialize, 4884a2da0b8SParav Pandit * so we are not forwarding error to the user. 4894a2da0b8SParav Pandit */ 49073eb8f03SGreg Kroah-Hartman return; 4914a2da0b8SParav Pandit } 492