1 // SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause 2 /* 3 * Copyright (c) 2024, Broadcom. All rights reserved. The term 4 * Broadcom refers to Broadcom Limited and/or its subsidiaries. 5 * 6 * Description: Debugfs component of the bnxt_re driver 7 */ 8 9 #include <linux/debugfs.h> 10 #include <linux/pci.h> 11 #include <rdma/ib_addr.h> 12 13 #include "bnxt_ulp.h" 14 #include "roce_hsi.h" 15 #include "qplib_res.h" 16 #include "qplib_sp.h" 17 #include "qplib_fp.h" 18 #include "qplib_rcfw.h" 19 #include "bnxt_re.h" 20 #include "ib_verbs.h" 21 #include "debugfs.h" 22 23 static struct dentry *bnxt_re_debugfs_root; 24 25 static const char * const bnxt_re_cc_gen0_name[] = { 26 "enable_cc", 27 "run_avg_weight_g", 28 "num_phase_per_state", 29 "init_cr", 30 "init_tr", 31 "tos_ecn", 32 "tos_dscp", 33 "alt_vlan_pcp", 34 "alt_vlan_dscp", 35 "rtt", 36 "cc_mode", 37 "tcp_cp", 38 "tx_queue", 39 "inactivity_cp", 40 }; 41 42 static inline const char *bnxt_re_qp_state_str(u8 state) 43 { 44 switch (state) { 45 case CMDQ_MODIFY_QP_NEW_STATE_RESET: 46 return "RST"; 47 case CMDQ_MODIFY_QP_NEW_STATE_INIT: 48 return "INIT"; 49 case CMDQ_MODIFY_QP_NEW_STATE_RTR: 50 return "RTR"; 51 case CMDQ_MODIFY_QP_NEW_STATE_RTS: 52 return "RTS"; 53 case CMDQ_MODIFY_QP_NEW_STATE_SQE: 54 return "SQER"; 55 case CMDQ_MODIFY_QP_NEW_STATE_SQD: 56 return "SQD"; 57 case CMDQ_MODIFY_QP_NEW_STATE_ERR: 58 return "ERR"; 59 default: 60 return "Invalid QP state"; 61 } 62 } 63 64 static inline const char *bnxt_re_qp_type_str(u8 type) 65 { 66 switch (type) { 67 case CMDQ_CREATE_QP1_TYPE_GSI: return "QP1"; 68 case CMDQ_CREATE_QP_TYPE_GSI: return "QP1"; 69 case CMDQ_CREATE_QP_TYPE_RC: return "RC"; 70 case CMDQ_CREATE_QP_TYPE_UD: return "UD"; 71 case CMDQ_CREATE_QP_TYPE_RAW_ETHERTYPE: return "RAW_ETHERTYPE"; 72 default: return "Invalid transport type"; 73 } 74 } 75 76 static ssize_t qp_info_read(struct file *filep, 77 char __user *buffer, 78 size_t count, loff_t *ppos) 79 { 80 struct bnxt_re_qp *qp = filep->private_data; 81 char *buf; 82 int len; 83 84 if (*ppos) 85 return 0; 86 87 buf = kasprintf(GFP_KERNEL, 88 "QPN\t\t: %d\n" 89 "transport\t: %s\n" 90 "state\t\t: %s\n" 91 "mtu\t\t: %d\n" 92 "timeout\t\t: %d\n" 93 "remote QPN\t: %d\n", 94 qp->qplib_qp.id, 95 bnxt_re_qp_type_str(qp->qplib_qp.type), 96 bnxt_re_qp_state_str(qp->qplib_qp.state), 97 qp->qplib_qp.mtu, 98 qp->qplib_qp.timeout, 99 qp->qplib_qp.dest_qpn); 100 if (!buf) 101 return -ENOMEM; 102 if (count < strlen(buf)) { 103 kfree(buf); 104 return -ENOSPC; 105 } 106 len = simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf)); 107 kfree(buf); 108 return len; 109 } 110 111 static const struct file_operations debugfs_qp_fops = { 112 .owner = THIS_MODULE, 113 .open = simple_open, 114 .read = qp_info_read, 115 }; 116 117 void bnxt_re_debug_add_qpinfo(struct bnxt_re_dev *rdev, struct bnxt_re_qp *qp) 118 { 119 char resn[32]; 120 121 sprintf(resn, "0x%x", qp->qplib_qp.id); 122 qp->dentry = debugfs_create_file(resn, 0400, rdev->qp_debugfs, qp, &debugfs_qp_fops); 123 } 124 125 void bnxt_re_debug_rem_qpinfo(struct bnxt_re_dev *rdev, struct bnxt_re_qp *qp) 126 { 127 debugfs_remove(qp->dentry); 128 } 129 130 static int map_cc_config_offset_gen0_ext0(u32 offset, struct bnxt_qplib_cc_param *ccparam, u32 *val) 131 { 132 u64 map_offset; 133 134 map_offset = BIT(offset); 135 136 switch (map_offset) { 137 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_ENABLE_CC: 138 *val = ccparam->enable; 139 break; 140 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_G: 141 *val = ccparam->g; 142 break; 143 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_NUMPHASEPERSTATE: 144 *val = ccparam->nph_per_state; 145 break; 146 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_INIT_CR: 147 *val = ccparam->init_cr; 148 break; 149 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_INIT_TR: 150 *val = ccparam->init_tr; 151 break; 152 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TOS_ECN: 153 *val = ccparam->tos_ecn; 154 break; 155 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TOS_DSCP: 156 *val = ccparam->tos_dscp; 157 break; 158 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_ALT_VLAN_PCP: 159 *val = ccparam->alt_vlan_pcp; 160 break; 161 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_ALT_TOS_DSCP: 162 *val = ccparam->alt_tos_dscp; 163 break; 164 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_RTT: 165 *val = ccparam->rtt; 166 break; 167 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_CC_MODE: 168 *val = ccparam->cc_mode; 169 break; 170 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TCP_CP: 171 *val = ccparam->tcp_cp; 172 break; 173 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_INACTIVITY_CP: 174 *val = ccparam->inact_th; 175 break; 176 default: 177 return -EINVAL; 178 } 179 180 return 0; 181 } 182 183 static ssize_t bnxt_re_cc_config_get(struct file *filp, char __user *buffer, 184 size_t usr_buf_len, loff_t *ppos) 185 { 186 struct bnxt_re_cc_param *dbg_cc_param = filp->private_data; 187 struct bnxt_re_dev *rdev = dbg_cc_param->rdev; 188 struct bnxt_qplib_cc_param ccparam = {}; 189 u32 offset = dbg_cc_param->offset; 190 char buf[16]; 191 u32 val; 192 int rc; 193 194 rc = bnxt_qplib_query_cc_param(&rdev->qplib_res, &ccparam); 195 if (rc) 196 return rc; 197 198 rc = map_cc_config_offset_gen0_ext0(offset, &ccparam, &val); 199 if (rc) 200 return rc; 201 202 rc = snprintf(buf, sizeof(buf), "%d\n", val); 203 if (rc < 0) 204 return rc; 205 206 return simple_read_from_buffer(buffer, usr_buf_len, ppos, (u8 *)(buf), rc); 207 } 208 209 static int bnxt_re_fill_gen0_ext0(struct bnxt_qplib_cc_param *ccparam, u32 offset, u32 val) 210 { 211 u32 modify_mask; 212 213 modify_mask = BIT(offset); 214 215 switch (modify_mask) { 216 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_ENABLE_CC: 217 ccparam->enable = val; 218 break; 219 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_G: 220 ccparam->g = val; 221 break; 222 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_NUMPHASEPERSTATE: 223 ccparam->nph_per_state = val; 224 break; 225 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_INIT_CR: 226 ccparam->init_cr = val; 227 break; 228 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_INIT_TR: 229 ccparam->init_tr = val; 230 break; 231 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TOS_ECN: 232 ccparam->tos_ecn = val; 233 break; 234 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TOS_DSCP: 235 ccparam->tos_dscp = val; 236 break; 237 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_ALT_VLAN_PCP: 238 ccparam->alt_vlan_pcp = val; 239 break; 240 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_ALT_TOS_DSCP: 241 ccparam->alt_tos_dscp = val; 242 break; 243 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_RTT: 244 ccparam->rtt = val; 245 break; 246 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_CC_MODE: 247 ccparam->cc_mode = val; 248 break; 249 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TCP_CP: 250 ccparam->tcp_cp = val; 251 break; 252 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TX_QUEUE: 253 return -EOPNOTSUPP; 254 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_INACTIVITY_CP: 255 ccparam->inact_th = val; 256 break; 257 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TIME_PER_PHASE: 258 ccparam->time_pph = val; 259 break; 260 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_PKTS_PER_PHASE: 261 ccparam->pkts_pph = val; 262 break; 263 } 264 265 ccparam->mask = modify_mask; 266 return 0; 267 } 268 269 static int bnxt_re_configure_cc(struct bnxt_re_dev *rdev, u32 gen_ext, u32 offset, u32 val) 270 { 271 struct bnxt_qplib_cc_param ccparam = { }; 272 int rc; 273 274 if (gen_ext != CC_CONFIG_GEN0_EXT0) 275 return -EOPNOTSUPP; 276 277 rc = bnxt_re_fill_gen0_ext0(&ccparam, offset, val); 278 if (rc) 279 return rc; 280 281 bnxt_qplib_modify_cc(&rdev->qplib_res, &ccparam); 282 return 0; 283 } 284 285 static ssize_t bnxt_re_cc_config_set(struct file *filp, const char __user *buffer, 286 size_t count, loff_t *ppos) 287 { 288 struct bnxt_re_cc_param *dbg_cc_param = filp->private_data; 289 struct bnxt_re_dev *rdev = dbg_cc_param->rdev; 290 u32 offset = dbg_cc_param->offset; 291 u8 cc_gen = dbg_cc_param->cc_gen; 292 char buf[16]; 293 u32 val; 294 int rc; 295 296 if (count >= sizeof(buf)) 297 return -EINVAL; 298 299 if (copy_from_user(buf, buffer, count)) 300 return -EFAULT; 301 302 buf[count] = '\0'; 303 if (kstrtou32(buf, 0, &val)) 304 return -EINVAL; 305 306 rc = bnxt_re_configure_cc(rdev, cc_gen, offset, val); 307 return rc ? rc : count; 308 } 309 310 static const struct file_operations bnxt_re_cc_config_ops = { 311 .owner = THIS_MODULE, 312 .open = simple_open, 313 .read = bnxt_re_cc_config_get, 314 .write = bnxt_re_cc_config_set, 315 }; 316 317 void bnxt_re_debugfs_add_pdev(struct bnxt_re_dev *rdev) 318 { 319 struct pci_dev *pdev = rdev->en_dev->pdev; 320 struct bnxt_re_dbg_cc_config_params *cc_params; 321 int i; 322 323 rdev->dbg_root = debugfs_create_dir(dev_name(&pdev->dev), bnxt_re_debugfs_root); 324 325 rdev->qp_debugfs = debugfs_create_dir("QPs", rdev->dbg_root); 326 rdev->cc_config = debugfs_create_dir("cc_config", rdev->dbg_root); 327 328 rdev->cc_config_params = kzalloc(sizeof(*cc_params), GFP_KERNEL); 329 330 for (i = 0; i < BNXT_RE_CC_PARAM_GEN0; i++) { 331 struct bnxt_re_cc_param *tmp_params = &rdev->cc_config_params->gen0_parms[i]; 332 333 tmp_params->rdev = rdev; 334 tmp_params->offset = i; 335 tmp_params->cc_gen = CC_CONFIG_GEN0_EXT0; 336 tmp_params->dentry = debugfs_create_file(bnxt_re_cc_gen0_name[i], 0400, 337 rdev->cc_config, tmp_params, 338 &bnxt_re_cc_config_ops); 339 } 340 } 341 342 void bnxt_re_debugfs_rem_pdev(struct bnxt_re_dev *rdev) 343 { 344 debugfs_remove_recursive(rdev->qp_debugfs); 345 debugfs_remove_recursive(rdev->cc_config); 346 kfree(rdev->cc_config_params); 347 debugfs_remove_recursive(rdev->dbg_root); 348 rdev->dbg_root = NULL; 349 } 350 351 void bnxt_re_register_debugfs(void) 352 { 353 bnxt_re_debugfs_root = debugfs_create_dir("bnxt_re", NULL); 354 } 355 356 void bnxt_re_unregister_debugfs(void) 357 { 358 debugfs_remove(bnxt_re_debugfs_root); 359 } 360