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 default: 174 return -EINVAL; 175 } 176 177 return 0; 178 } 179 180 static ssize_t bnxt_re_cc_config_get(struct file *filp, char __user *buffer, 181 size_t usr_buf_len, loff_t *ppos) 182 { 183 struct bnxt_re_cc_param *dbg_cc_param = filp->private_data; 184 struct bnxt_re_dev *rdev = dbg_cc_param->rdev; 185 struct bnxt_qplib_cc_param ccparam = {}; 186 u32 offset = dbg_cc_param->offset; 187 char buf[16]; 188 u32 val; 189 int rc; 190 191 rc = bnxt_qplib_query_cc_param(&rdev->qplib_res, &ccparam); 192 if (rc) 193 return rc; 194 195 rc = map_cc_config_offset_gen0_ext0(offset, &ccparam, &val); 196 if (rc) 197 return rc; 198 199 rc = snprintf(buf, sizeof(buf), "%d\n", val); 200 if (rc < 0) 201 return rc; 202 203 return simple_read_from_buffer(buffer, usr_buf_len, ppos, (u8 *)(buf), rc); 204 } 205 206 static void bnxt_re_fill_gen0_ext0(struct bnxt_qplib_cc_param *ccparam, u32 offset, u32 val) 207 { 208 u32 modify_mask; 209 210 modify_mask = BIT(offset); 211 212 switch (modify_mask) { 213 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_ENABLE_CC: 214 ccparam->enable = val; 215 break; 216 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_G: 217 ccparam->g = val; 218 break; 219 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_NUMPHASEPERSTATE: 220 ccparam->nph_per_state = val; 221 break; 222 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_INIT_CR: 223 ccparam->init_cr = val; 224 break; 225 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_INIT_TR: 226 ccparam->init_tr = val; 227 break; 228 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TOS_ECN: 229 ccparam->tos_ecn = val; 230 break; 231 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TOS_DSCP: 232 ccparam->tos_dscp = val; 233 break; 234 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_ALT_VLAN_PCP: 235 ccparam->alt_vlan_pcp = val; 236 break; 237 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_ALT_TOS_DSCP: 238 ccparam->alt_tos_dscp = val; 239 break; 240 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_RTT: 241 ccparam->rtt = val; 242 break; 243 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_CC_MODE: 244 ccparam->cc_mode = val; 245 break; 246 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TCP_CP: 247 ccparam->tcp_cp = val; 248 break; 249 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TX_QUEUE: 250 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_INACTIVITY_CP: 251 break; 252 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TIME_PER_PHASE: 253 ccparam->time_pph = val; 254 break; 255 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_PKTS_PER_PHASE: 256 ccparam->pkts_pph = val; 257 break; 258 } 259 260 ccparam->mask = modify_mask; 261 } 262 263 static int bnxt_re_configure_cc(struct bnxt_re_dev *rdev, u32 gen_ext, u32 offset, u32 val) 264 { 265 struct bnxt_qplib_cc_param ccparam = { }; 266 267 /* Supporting only Gen 0 now */ 268 if (gen_ext == CC_CONFIG_GEN0_EXT0) 269 bnxt_re_fill_gen0_ext0(&ccparam, offset, val); 270 else 271 return -EINVAL; 272 273 bnxt_qplib_modify_cc(&rdev->qplib_res, &ccparam); 274 return 0; 275 } 276 277 static ssize_t bnxt_re_cc_config_set(struct file *filp, const char __user *buffer, 278 size_t count, loff_t *ppos) 279 { 280 struct bnxt_re_cc_param *dbg_cc_param = filp->private_data; 281 struct bnxt_re_dev *rdev = dbg_cc_param->rdev; 282 u32 offset = dbg_cc_param->offset; 283 u8 cc_gen = dbg_cc_param->cc_gen; 284 char buf[16]; 285 u32 val; 286 int rc; 287 288 if (count >= sizeof(buf)) 289 return -EINVAL; 290 291 if (copy_from_user(buf, buffer, count)) 292 return -EFAULT; 293 294 buf[count] = '\0'; 295 if (kstrtou32(buf, 0, &val)) 296 return -EINVAL; 297 298 rc = bnxt_re_configure_cc(rdev, cc_gen, offset, val); 299 return rc ? rc : count; 300 } 301 302 static const struct file_operations bnxt_re_cc_config_ops = { 303 .owner = THIS_MODULE, 304 .open = simple_open, 305 .read = bnxt_re_cc_config_get, 306 .write = bnxt_re_cc_config_set, 307 }; 308 309 void bnxt_re_debugfs_add_pdev(struct bnxt_re_dev *rdev) 310 { 311 struct pci_dev *pdev = rdev->en_dev->pdev; 312 struct bnxt_re_dbg_cc_config_params *cc_params; 313 int i; 314 315 rdev->dbg_root = debugfs_create_dir(dev_name(&pdev->dev), bnxt_re_debugfs_root); 316 317 rdev->qp_debugfs = debugfs_create_dir("QPs", rdev->dbg_root); 318 rdev->cc_config = debugfs_create_dir("cc_config", rdev->dbg_root); 319 320 rdev->cc_config_params = kzalloc(sizeof(*cc_params), GFP_KERNEL); 321 322 for (i = 0; i < BNXT_RE_CC_PARAM_GEN0; i++) { 323 struct bnxt_re_cc_param *tmp_params = &rdev->cc_config_params->gen0_parms[i]; 324 325 tmp_params->rdev = rdev; 326 tmp_params->offset = i; 327 tmp_params->cc_gen = CC_CONFIG_GEN0_EXT0; 328 tmp_params->dentry = debugfs_create_file(bnxt_re_cc_gen0_name[i], 0400, 329 rdev->cc_config, tmp_params, 330 &bnxt_re_cc_config_ops); 331 } 332 } 333 334 void bnxt_re_debugfs_rem_pdev(struct bnxt_re_dev *rdev) 335 { 336 debugfs_remove_recursive(rdev->qp_debugfs); 337 debugfs_remove_recursive(rdev->cc_config); 338 kfree(rdev->cc_config_params); 339 debugfs_remove_recursive(rdev->dbg_root); 340 rdev->dbg_root = NULL; 341 } 342 343 void bnxt_re_register_debugfs(void) 344 { 345 bnxt_re_debugfs_root = debugfs_create_dir("bnxt_re", NULL); 346 } 347 348 void bnxt_re_unregister_debugfs(void) 349 { 350 debugfs_remove(bnxt_re_debugfs_root); 351 } 352