1*4a2da0b8SParav Pandit /* 2*4a2da0b8SParav Pandit * Copyright (c) 2013-2017, Mellanox Technologies. All rights reserved. 3*4a2da0b8SParav Pandit * 4*4a2da0b8SParav Pandit * This software is available to you under a choice of one of two 5*4a2da0b8SParav Pandit * licenses. You may choose to be licensed under the terms of the GNU 6*4a2da0b8SParav Pandit * General Public License (GPL) Version 2, available from the file 7*4a2da0b8SParav Pandit * COPYING in the main directory of this source tree, or the 8*4a2da0b8SParav Pandit * OpenIB.org BSD license below: 9*4a2da0b8SParav Pandit * 10*4a2da0b8SParav Pandit * Redistribution and use in source and binary forms, with or 11*4a2da0b8SParav Pandit * without modification, are permitted provided that the following 12*4a2da0b8SParav Pandit * conditions are met: 13*4a2da0b8SParav Pandit * 14*4a2da0b8SParav Pandit * - Redistributions of source code must retain the above 15*4a2da0b8SParav Pandit * copyright notice, this list of conditions and the following 16*4a2da0b8SParav Pandit * disclaimer. 17*4a2da0b8SParav Pandit * 18*4a2da0b8SParav Pandit * - Redistributions in binary form must reproduce the above 19*4a2da0b8SParav Pandit * copyright notice, this list of conditions and the following 20*4a2da0b8SParav Pandit * disclaimer in the documentation and/or other materials 21*4a2da0b8SParav Pandit * provided with the distribution. 22*4a2da0b8SParav Pandit * 23*4a2da0b8SParav Pandit * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24*4a2da0b8SParav Pandit * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25*4a2da0b8SParav Pandit * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26*4a2da0b8SParav Pandit * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27*4a2da0b8SParav Pandit * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28*4a2da0b8SParav Pandit * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29*4a2da0b8SParav Pandit * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30*4a2da0b8SParav Pandit * SOFTWARE. 31*4a2da0b8SParav Pandit */ 32*4a2da0b8SParav Pandit 33*4a2da0b8SParav Pandit #include <linux/debugfs.h> 34*4a2da0b8SParav Pandit 35*4a2da0b8SParav Pandit #include "mlx5_ib.h" 36*4a2da0b8SParav Pandit #include "cmd.h" 37*4a2da0b8SParav Pandit 38*4a2da0b8SParav Pandit enum mlx5_ib_cong_node_type { 39*4a2da0b8SParav Pandit MLX5_IB_RROCE_ECN_RP = 1, 40*4a2da0b8SParav Pandit MLX5_IB_RROCE_ECN_NP = 2, 41*4a2da0b8SParav Pandit }; 42*4a2da0b8SParav Pandit 43*4a2da0b8SParav Pandit static const char * const mlx5_ib_dbg_cc_name[] = { 44*4a2da0b8SParav Pandit "rp_clamp_tgt_rate", 45*4a2da0b8SParav Pandit "rp_clamp_tgt_rate_ati", 46*4a2da0b8SParav Pandit "rp_time_reset", 47*4a2da0b8SParav Pandit "rp_byte_reset", 48*4a2da0b8SParav Pandit "rp_threshold", 49*4a2da0b8SParav Pandit "rp_ai_rate", 50*4a2da0b8SParav Pandit "rp_hai_rate", 51*4a2da0b8SParav Pandit "rp_min_dec_fac", 52*4a2da0b8SParav Pandit "rp_min_rate", 53*4a2da0b8SParav Pandit "rp_rate_to_set_on_first_cnp", 54*4a2da0b8SParav Pandit "rp_dce_tcp_g", 55*4a2da0b8SParav Pandit "rp_dce_tcp_rtt", 56*4a2da0b8SParav Pandit "rp_rate_reduce_monitor_period", 57*4a2da0b8SParav Pandit "rp_initial_alpha_value", 58*4a2da0b8SParav Pandit "rp_gd", 59*4a2da0b8SParav Pandit "np_cnp_dscp", 60*4a2da0b8SParav Pandit "np_cnp_prio_mode", 61*4a2da0b8SParav Pandit "np_cnp_prio", 62*4a2da0b8SParav Pandit }; 63*4a2da0b8SParav Pandit 64*4a2da0b8SParav Pandit #define MLX5_IB_RP_CLAMP_TGT_RATE_ATTR BIT(1) 65*4a2da0b8SParav Pandit #define MLX5_IB_RP_CLAMP_TGT_RATE_ATI_ATTR BIT(2) 66*4a2da0b8SParav Pandit #define MLX5_IB_RP_TIME_RESET_ATTR BIT(3) 67*4a2da0b8SParav Pandit #define MLX5_IB_RP_BYTE_RESET_ATTR BIT(4) 68*4a2da0b8SParav Pandit #define MLX5_IB_RP_THRESHOLD_ATTR BIT(5) 69*4a2da0b8SParav Pandit #define MLX5_IB_RP_AI_RATE_ATTR BIT(7) 70*4a2da0b8SParav Pandit #define MLX5_IB_RP_HAI_RATE_ATTR BIT(8) 71*4a2da0b8SParav Pandit #define MLX5_IB_RP_MIN_DEC_FAC_ATTR BIT(9) 72*4a2da0b8SParav Pandit #define MLX5_IB_RP_MIN_RATE_ATTR BIT(10) 73*4a2da0b8SParav Pandit #define MLX5_IB_RP_RATE_TO_SET_ON_FIRST_CNP_ATTR BIT(11) 74*4a2da0b8SParav Pandit #define MLX5_IB_RP_DCE_TCP_G_ATTR BIT(12) 75*4a2da0b8SParav Pandit #define MLX5_IB_RP_DCE_TCP_RTT_ATTR BIT(13) 76*4a2da0b8SParav Pandit #define MLX5_IB_RP_RATE_REDUCE_MONITOR_PERIOD_ATTR BIT(14) 77*4a2da0b8SParav Pandit #define MLX5_IB_RP_INITIAL_ALPHA_VALUE_ATTR BIT(15) 78*4a2da0b8SParav Pandit #define MLX5_IB_RP_GD_ATTR BIT(16) 79*4a2da0b8SParav Pandit 80*4a2da0b8SParav Pandit #define MLX5_IB_NP_CNP_DSCP_ATTR BIT(3) 81*4a2da0b8SParav Pandit #define MLX5_IB_NP_CNP_PRIO_MODE_ATTR BIT(4) 82*4a2da0b8SParav Pandit 83*4a2da0b8SParav Pandit static enum mlx5_ib_cong_node_type 84*4a2da0b8SParav Pandit mlx5_ib_param_to_node(enum mlx5_ib_dbg_cc_types param_offset) 85*4a2da0b8SParav Pandit { 86*4a2da0b8SParav Pandit if (param_offset >= MLX5_IB_DBG_CC_RP_CLAMP_TGT_RATE && 87*4a2da0b8SParav Pandit param_offset <= MLX5_IB_DBG_CC_RP_GD) 88*4a2da0b8SParav Pandit return MLX5_IB_RROCE_ECN_RP; 89*4a2da0b8SParav Pandit else 90*4a2da0b8SParav Pandit return MLX5_IB_RROCE_ECN_NP; 91*4a2da0b8SParav Pandit } 92*4a2da0b8SParav Pandit 93*4a2da0b8SParav Pandit static u32 mlx5_get_cc_param_val(void *field, int offset) 94*4a2da0b8SParav Pandit { 95*4a2da0b8SParav Pandit switch (offset) { 96*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_CLAMP_TGT_RATE: 97*4a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 98*4a2da0b8SParav Pandit clamp_tgt_rate); 99*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_CLAMP_TGT_RATE_ATI: 100*4a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 101*4a2da0b8SParav Pandit clamp_tgt_rate_after_time_inc); 102*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_TIME_RESET: 103*4a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 104*4a2da0b8SParav Pandit rpg_time_reset); 105*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_BYTE_RESET: 106*4a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 107*4a2da0b8SParav Pandit rpg_byte_reset); 108*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_THRESHOLD: 109*4a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 110*4a2da0b8SParav Pandit rpg_threshold); 111*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_AI_RATE: 112*4a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 113*4a2da0b8SParav Pandit rpg_ai_rate); 114*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_HAI_RATE: 115*4a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 116*4a2da0b8SParav Pandit rpg_hai_rate); 117*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_MIN_DEC_FAC: 118*4a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 119*4a2da0b8SParav Pandit rpg_min_dec_fac); 120*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_MIN_RATE: 121*4a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 122*4a2da0b8SParav Pandit rpg_min_rate); 123*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_RATE_TO_SET_ON_FIRST_CNP: 124*4a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 125*4a2da0b8SParav Pandit rate_to_set_on_first_cnp); 126*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_DCE_TCP_G: 127*4a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 128*4a2da0b8SParav Pandit dce_tcp_g); 129*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_DCE_TCP_RTT: 130*4a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 131*4a2da0b8SParav Pandit dce_tcp_rtt); 132*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_RATE_REDUCE_MONITOR_PERIOD: 133*4a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 134*4a2da0b8SParav Pandit rate_reduce_monitor_period); 135*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_INITIAL_ALPHA_VALUE: 136*4a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 137*4a2da0b8SParav Pandit initial_alpha_value); 138*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_GD: 139*4a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_rp, field, 140*4a2da0b8SParav Pandit rpg_gd); 141*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_NP_CNP_DSCP: 142*4a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_np, field, 143*4a2da0b8SParav Pandit cnp_dscp); 144*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_NP_CNP_PRIO_MODE: 145*4a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_np, field, 146*4a2da0b8SParav Pandit cnp_prio_mode); 147*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_NP_CNP_PRIO: 148*4a2da0b8SParav Pandit return MLX5_GET(cong_control_r_roce_ecn_np, field, 149*4a2da0b8SParav Pandit cnp_802p_prio); 150*4a2da0b8SParav Pandit default: 151*4a2da0b8SParav Pandit return 0; 152*4a2da0b8SParav Pandit } 153*4a2da0b8SParav Pandit } 154*4a2da0b8SParav Pandit 155*4a2da0b8SParav Pandit static void mlx5_ib_set_cc_param_mask_val(void *field, int offset, 156*4a2da0b8SParav Pandit u32 var, u32 *attr_mask) 157*4a2da0b8SParav Pandit { 158*4a2da0b8SParav Pandit switch (offset) { 159*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_CLAMP_TGT_RATE: 160*4a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_CLAMP_TGT_RATE_ATTR; 161*4a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 162*4a2da0b8SParav Pandit clamp_tgt_rate, var); 163*4a2da0b8SParav Pandit break; 164*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_CLAMP_TGT_RATE_ATI: 165*4a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_CLAMP_TGT_RATE_ATI_ATTR; 166*4a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 167*4a2da0b8SParav Pandit clamp_tgt_rate_after_time_inc, var); 168*4a2da0b8SParav Pandit break; 169*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_TIME_RESET: 170*4a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_TIME_RESET_ATTR; 171*4a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 172*4a2da0b8SParav Pandit rpg_time_reset, var); 173*4a2da0b8SParav Pandit break; 174*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_BYTE_RESET: 175*4a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_BYTE_RESET_ATTR; 176*4a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 177*4a2da0b8SParav Pandit rpg_byte_reset, var); 178*4a2da0b8SParav Pandit break; 179*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_THRESHOLD: 180*4a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_THRESHOLD_ATTR; 181*4a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 182*4a2da0b8SParav Pandit rpg_threshold, var); 183*4a2da0b8SParav Pandit break; 184*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_AI_RATE: 185*4a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_AI_RATE_ATTR; 186*4a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 187*4a2da0b8SParav Pandit rpg_ai_rate, var); 188*4a2da0b8SParav Pandit break; 189*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_HAI_RATE: 190*4a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_HAI_RATE_ATTR; 191*4a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 192*4a2da0b8SParav Pandit rpg_hai_rate, var); 193*4a2da0b8SParav Pandit break; 194*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_MIN_DEC_FAC: 195*4a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_MIN_DEC_FAC_ATTR; 196*4a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 197*4a2da0b8SParav Pandit rpg_min_dec_fac, var); 198*4a2da0b8SParav Pandit break; 199*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_MIN_RATE: 200*4a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_MIN_RATE_ATTR; 201*4a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 202*4a2da0b8SParav Pandit rpg_min_rate, var); 203*4a2da0b8SParav Pandit break; 204*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_RATE_TO_SET_ON_FIRST_CNP: 205*4a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_RATE_TO_SET_ON_FIRST_CNP_ATTR; 206*4a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 207*4a2da0b8SParav Pandit rate_to_set_on_first_cnp, var); 208*4a2da0b8SParav Pandit break; 209*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_DCE_TCP_G: 210*4a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_DCE_TCP_G_ATTR; 211*4a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 212*4a2da0b8SParav Pandit dce_tcp_g, var); 213*4a2da0b8SParav Pandit break; 214*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_DCE_TCP_RTT: 215*4a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_DCE_TCP_RTT_ATTR; 216*4a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 217*4a2da0b8SParav Pandit dce_tcp_rtt, var); 218*4a2da0b8SParav Pandit break; 219*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_RATE_REDUCE_MONITOR_PERIOD: 220*4a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_RATE_REDUCE_MONITOR_PERIOD_ATTR; 221*4a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 222*4a2da0b8SParav Pandit rate_reduce_monitor_period, var); 223*4a2da0b8SParav Pandit break; 224*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_INITIAL_ALPHA_VALUE: 225*4a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_INITIAL_ALPHA_VALUE_ATTR; 226*4a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 227*4a2da0b8SParav Pandit initial_alpha_value, var); 228*4a2da0b8SParav Pandit break; 229*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_RP_GD: 230*4a2da0b8SParav Pandit *attr_mask |= MLX5_IB_RP_GD_ATTR; 231*4a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_rp, field, 232*4a2da0b8SParav Pandit rpg_gd, var); 233*4a2da0b8SParav Pandit break; 234*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_NP_CNP_DSCP: 235*4a2da0b8SParav Pandit *attr_mask |= MLX5_IB_NP_CNP_DSCP_ATTR; 236*4a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_np, field, cnp_dscp, var); 237*4a2da0b8SParav Pandit break; 238*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_NP_CNP_PRIO_MODE: 239*4a2da0b8SParav Pandit *attr_mask |= MLX5_IB_NP_CNP_PRIO_MODE_ATTR; 240*4a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_np, field, cnp_prio_mode, var); 241*4a2da0b8SParav Pandit break; 242*4a2da0b8SParav Pandit case MLX5_IB_DBG_CC_NP_CNP_PRIO: 243*4a2da0b8SParav Pandit *attr_mask |= MLX5_IB_NP_CNP_PRIO_MODE_ATTR; 244*4a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_np, field, cnp_prio_mode, 0); 245*4a2da0b8SParav Pandit MLX5_SET(cong_control_r_roce_ecn_np, field, cnp_802p_prio, var); 246*4a2da0b8SParav Pandit break; 247*4a2da0b8SParav Pandit } 248*4a2da0b8SParav Pandit } 249*4a2da0b8SParav Pandit 250*4a2da0b8SParav Pandit static int mlx5_ib_get_cc_params(struct mlx5_ib_dev *dev, int offset, u32 *var) 251*4a2da0b8SParav Pandit { 252*4a2da0b8SParav Pandit int outlen = MLX5_ST_SZ_BYTES(query_cong_params_out); 253*4a2da0b8SParav Pandit void *out; 254*4a2da0b8SParav Pandit void *field; 255*4a2da0b8SParav Pandit int err; 256*4a2da0b8SParav Pandit enum mlx5_ib_cong_node_type node; 257*4a2da0b8SParav Pandit 258*4a2da0b8SParav Pandit out = kvzalloc(outlen, GFP_KERNEL); 259*4a2da0b8SParav Pandit if (!out) 260*4a2da0b8SParav Pandit return -ENOMEM; 261*4a2da0b8SParav Pandit 262*4a2da0b8SParav Pandit node = mlx5_ib_param_to_node(offset); 263*4a2da0b8SParav Pandit 264*4a2da0b8SParav Pandit err = mlx5_cmd_query_cong_params(dev->mdev, node, out, outlen); 265*4a2da0b8SParav Pandit if (err) 266*4a2da0b8SParav Pandit goto free; 267*4a2da0b8SParav Pandit 268*4a2da0b8SParav Pandit field = MLX5_ADDR_OF(query_cong_params_out, out, congestion_parameters); 269*4a2da0b8SParav Pandit *var = mlx5_get_cc_param_val(field, offset); 270*4a2da0b8SParav Pandit 271*4a2da0b8SParav Pandit free: 272*4a2da0b8SParav Pandit kvfree(out); 273*4a2da0b8SParav Pandit return err; 274*4a2da0b8SParav Pandit } 275*4a2da0b8SParav Pandit 276*4a2da0b8SParav Pandit static int mlx5_ib_set_cc_params(struct mlx5_ib_dev *dev, int offset, u32 var) 277*4a2da0b8SParav Pandit { 278*4a2da0b8SParav Pandit int inlen = MLX5_ST_SZ_BYTES(modify_cong_params_in); 279*4a2da0b8SParav Pandit void *in; 280*4a2da0b8SParav Pandit void *field; 281*4a2da0b8SParav Pandit enum mlx5_ib_cong_node_type node; 282*4a2da0b8SParav Pandit u32 attr_mask = 0; 283*4a2da0b8SParav Pandit int err; 284*4a2da0b8SParav Pandit 285*4a2da0b8SParav Pandit in = kvzalloc(inlen, GFP_KERNEL); 286*4a2da0b8SParav Pandit if (!in) 287*4a2da0b8SParav Pandit return -ENOMEM; 288*4a2da0b8SParav Pandit 289*4a2da0b8SParav Pandit MLX5_SET(modify_cong_params_in, in, opcode, 290*4a2da0b8SParav Pandit MLX5_CMD_OP_MODIFY_CONG_PARAMS); 291*4a2da0b8SParav Pandit 292*4a2da0b8SParav Pandit node = mlx5_ib_param_to_node(offset); 293*4a2da0b8SParav Pandit MLX5_SET(modify_cong_params_in, in, cong_protocol, node); 294*4a2da0b8SParav Pandit 295*4a2da0b8SParav Pandit field = MLX5_ADDR_OF(modify_cong_params_in, in, congestion_parameters); 296*4a2da0b8SParav Pandit mlx5_ib_set_cc_param_mask_val(field, offset, var, &attr_mask); 297*4a2da0b8SParav Pandit 298*4a2da0b8SParav Pandit field = MLX5_ADDR_OF(modify_cong_params_in, in, field_select); 299*4a2da0b8SParav Pandit MLX5_SET(field_select_r_roce_rp, field, field_select_r_roce_rp, 300*4a2da0b8SParav Pandit attr_mask); 301*4a2da0b8SParav Pandit 302*4a2da0b8SParav Pandit err = mlx5_cmd_modify_cong_params(dev->mdev, in, inlen); 303*4a2da0b8SParav Pandit kvfree(in); 304*4a2da0b8SParav Pandit return err; 305*4a2da0b8SParav Pandit } 306*4a2da0b8SParav Pandit 307*4a2da0b8SParav Pandit static ssize_t set_param(struct file *filp, const char __user *buf, 308*4a2da0b8SParav Pandit size_t count, loff_t *pos) 309*4a2da0b8SParav Pandit { 310*4a2da0b8SParav Pandit struct mlx5_ib_dbg_param *param = filp->private_data; 311*4a2da0b8SParav Pandit int offset = param->offset; 312*4a2da0b8SParav Pandit char lbuf[11] = { }; 313*4a2da0b8SParav Pandit u32 var; 314*4a2da0b8SParav Pandit int ret; 315*4a2da0b8SParav Pandit 316*4a2da0b8SParav Pandit if (count > sizeof(lbuf)) 317*4a2da0b8SParav Pandit return -EINVAL; 318*4a2da0b8SParav Pandit 319*4a2da0b8SParav Pandit if (copy_from_user(lbuf, buf, count)) 320*4a2da0b8SParav Pandit return -EFAULT; 321*4a2da0b8SParav Pandit 322*4a2da0b8SParav Pandit lbuf[sizeof(lbuf) - 1] = '\0'; 323*4a2da0b8SParav Pandit 324*4a2da0b8SParav Pandit if (kstrtou32(lbuf, 0, &var)) 325*4a2da0b8SParav Pandit return -EINVAL; 326*4a2da0b8SParav Pandit 327*4a2da0b8SParav Pandit ret = mlx5_ib_set_cc_params(param->dev, offset, var); 328*4a2da0b8SParav Pandit return ret ? ret : count; 329*4a2da0b8SParav Pandit } 330*4a2da0b8SParav Pandit 331*4a2da0b8SParav Pandit static ssize_t get_param(struct file *filp, char __user *buf, size_t count, 332*4a2da0b8SParav Pandit loff_t *pos) 333*4a2da0b8SParav Pandit { 334*4a2da0b8SParav Pandit struct mlx5_ib_dbg_param *param = filp->private_data; 335*4a2da0b8SParav Pandit int offset = param->offset; 336*4a2da0b8SParav Pandit u32 var = 0; 337*4a2da0b8SParav Pandit int ret; 338*4a2da0b8SParav Pandit char lbuf[11]; 339*4a2da0b8SParav Pandit 340*4a2da0b8SParav Pandit if (*pos) 341*4a2da0b8SParav Pandit return 0; 342*4a2da0b8SParav Pandit 343*4a2da0b8SParav Pandit ret = mlx5_ib_get_cc_params(param->dev, offset, &var); 344*4a2da0b8SParav Pandit if (ret) 345*4a2da0b8SParav Pandit return ret; 346*4a2da0b8SParav Pandit 347*4a2da0b8SParav Pandit ret = snprintf(lbuf, sizeof(lbuf), "%d\n", var); 348*4a2da0b8SParav Pandit if (ret < 0) 349*4a2da0b8SParav Pandit return ret; 350*4a2da0b8SParav Pandit 351*4a2da0b8SParav Pandit if (copy_to_user(buf, lbuf, ret)) 352*4a2da0b8SParav Pandit return -EFAULT; 353*4a2da0b8SParav Pandit 354*4a2da0b8SParav Pandit *pos += ret; 355*4a2da0b8SParav Pandit return ret; 356*4a2da0b8SParav Pandit } 357*4a2da0b8SParav Pandit 358*4a2da0b8SParav Pandit static const struct file_operations dbg_cc_fops = { 359*4a2da0b8SParav Pandit .owner = THIS_MODULE, 360*4a2da0b8SParav Pandit .open = simple_open, 361*4a2da0b8SParav Pandit .write = set_param, 362*4a2da0b8SParav Pandit .read = get_param, 363*4a2da0b8SParav Pandit }; 364*4a2da0b8SParav Pandit 365*4a2da0b8SParav Pandit void mlx5_ib_cleanup_cong_debugfs(struct mlx5_ib_dev *dev) 366*4a2da0b8SParav Pandit { 367*4a2da0b8SParav Pandit if (!mlx5_debugfs_root || 368*4a2da0b8SParav Pandit !dev->dbg_cc_params || 369*4a2da0b8SParav Pandit !dev->dbg_cc_params->root) 370*4a2da0b8SParav Pandit return; 371*4a2da0b8SParav Pandit 372*4a2da0b8SParav Pandit debugfs_remove_recursive(dev->dbg_cc_params->root); 373*4a2da0b8SParav Pandit kfree(dev->dbg_cc_params); 374*4a2da0b8SParav Pandit dev->dbg_cc_params = NULL; 375*4a2da0b8SParav Pandit } 376*4a2da0b8SParav Pandit 377*4a2da0b8SParav Pandit int mlx5_ib_init_cong_debugfs(struct mlx5_ib_dev *dev) 378*4a2da0b8SParav Pandit { 379*4a2da0b8SParav Pandit struct mlx5_ib_dbg_cc_params *dbg_cc_params; 380*4a2da0b8SParav Pandit int i; 381*4a2da0b8SParav Pandit 382*4a2da0b8SParav Pandit if (!mlx5_debugfs_root) 383*4a2da0b8SParav Pandit goto out; 384*4a2da0b8SParav Pandit 385*4a2da0b8SParav Pandit if (!MLX5_CAP_GEN(dev->mdev, cc_query_allowed) || 386*4a2da0b8SParav Pandit !MLX5_CAP_GEN(dev->mdev, cc_modify_allowed)) 387*4a2da0b8SParav Pandit goto out; 388*4a2da0b8SParav Pandit 389*4a2da0b8SParav Pandit dbg_cc_params = kzalloc(sizeof(*dbg_cc_params), GFP_KERNEL); 390*4a2da0b8SParav Pandit if (!dbg_cc_params) 391*4a2da0b8SParav Pandit goto out; 392*4a2da0b8SParav Pandit 393*4a2da0b8SParav Pandit dev->dbg_cc_params = dbg_cc_params; 394*4a2da0b8SParav Pandit 395*4a2da0b8SParav Pandit dbg_cc_params->root = debugfs_create_dir("cc_params", 396*4a2da0b8SParav Pandit dev->mdev->priv.dbg_root); 397*4a2da0b8SParav Pandit if (!dbg_cc_params->root) 398*4a2da0b8SParav Pandit goto err; 399*4a2da0b8SParav Pandit 400*4a2da0b8SParav Pandit for (i = 0; i < MLX5_IB_DBG_CC_MAX; i++) { 401*4a2da0b8SParav Pandit dbg_cc_params->params[i].offset = i; 402*4a2da0b8SParav Pandit dbg_cc_params->params[i].dev = dev; 403*4a2da0b8SParav Pandit dbg_cc_params->params[i].dentry = 404*4a2da0b8SParav Pandit debugfs_create_file(mlx5_ib_dbg_cc_name[i], 405*4a2da0b8SParav Pandit 0600, dbg_cc_params->root, 406*4a2da0b8SParav Pandit &dbg_cc_params->params[i], 407*4a2da0b8SParav Pandit &dbg_cc_fops); 408*4a2da0b8SParav Pandit if (!dbg_cc_params->params[i].dentry) 409*4a2da0b8SParav Pandit goto err; 410*4a2da0b8SParav Pandit } 411*4a2da0b8SParav Pandit out: return 0; 412*4a2da0b8SParav Pandit 413*4a2da0b8SParav Pandit err: 414*4a2da0b8SParav Pandit mlx5_ib_warn(dev, "cong debugfs failure\n"); 415*4a2da0b8SParav Pandit mlx5_ib_cleanup_cong_debugfs(dev); 416*4a2da0b8SParav Pandit /* 417*4a2da0b8SParav Pandit * We don't want to fail driver if debugfs failed to initialize, 418*4a2da0b8SParav Pandit * so we are not forwarding error to the user. 419*4a2da0b8SParav Pandit */ 420*4a2da0b8SParav Pandit return 0; 421*4a2da0b8SParav Pandit } 422