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 <linux/seq_file.h>
12 #include <rdma/ib_addr.h>
13
14 #include "bnxt_ulp.h"
15 #include "roce_hsi.h"
16 #include "qplib_res.h"
17 #include "qplib_sp.h"
18 #include "qplib_fp.h"
19 #include "qplib_rcfw.h"
20 #include "bnxt_re.h"
21 #include "ib_verbs.h"
22 #include "debugfs.h"
23
24 static struct dentry *bnxt_re_debugfs_root;
25
26 static const char * const bnxt_re_cq_coal_str[] = {
27 "buf_maxtime",
28 "normal_maxbuf",
29 "during_maxbuf",
30 "en_ring_idle_mode",
31 "enable",
32 };
33
34 static const char * const bnxt_re_cc_gen0_name[] = {
35 "enable_cc",
36 "run_avg_weight_g",
37 "num_phase_per_state",
38 "init_cr",
39 "init_tr",
40 "tos_ecn",
41 "tos_dscp",
42 "alt_vlan_pcp",
43 "alt_vlan_dscp",
44 "rtt",
45 "cc_mode",
46 "tcp_cp",
47 "tx_queue",
48 "inactivity_cp",
49 };
50
bnxt_re_qp_state_str(u8 state)51 static inline const char *bnxt_re_qp_state_str(u8 state)
52 {
53 switch (state) {
54 case CMDQ_MODIFY_QP_NEW_STATE_RESET:
55 return "RST";
56 case CMDQ_MODIFY_QP_NEW_STATE_INIT:
57 return "INIT";
58 case CMDQ_MODIFY_QP_NEW_STATE_RTR:
59 return "RTR";
60 case CMDQ_MODIFY_QP_NEW_STATE_RTS:
61 return "RTS";
62 case CMDQ_MODIFY_QP_NEW_STATE_SQE:
63 return "SQER";
64 case CMDQ_MODIFY_QP_NEW_STATE_SQD:
65 return "SQD";
66 case CMDQ_MODIFY_QP_NEW_STATE_ERR:
67 return "ERR";
68 default:
69 return "Invalid QP state";
70 }
71 }
72
bnxt_re_qp_type_str(u8 type)73 static inline const char *bnxt_re_qp_type_str(u8 type)
74 {
75 switch (type) {
76 case CMDQ_CREATE_QP1_TYPE_GSI: return "QP1";
77 case CMDQ_CREATE_QP_TYPE_GSI: return "QP1";
78 case CMDQ_CREATE_QP_TYPE_RC: return "RC";
79 case CMDQ_CREATE_QP_TYPE_UD: return "UD";
80 case CMDQ_CREATE_QP_TYPE_RAW_ETHERTYPE: return "RAW_ETHERTYPE";
81 default: return "Invalid transport type";
82 }
83 }
84
qp_info_read(struct file * filep,char __user * buffer,size_t count,loff_t * ppos)85 static ssize_t qp_info_read(struct file *filep,
86 char __user *buffer,
87 size_t count, loff_t *ppos)
88 {
89 struct bnxt_re_qp *qp = filep->private_data;
90 struct bnxt_qplib_qp *qplib_qp;
91 u32 rate_limit = 0;
92 char *buf;
93 int len;
94
95 if (*ppos)
96 return 0;
97
98 qplib_qp = &qp->qplib_qp;
99 if (qplib_qp->shaper_allocation_status)
100 rate_limit = qplib_qp->rate_limit;
101
102 buf = kasprintf(GFP_KERNEL,
103 "QPN\t\t: %d\n"
104 "transport\t: %s\n"
105 "state\t\t: %s\n"
106 "mtu\t\t: %d\n"
107 "timeout\t\t: %d\n"
108 "remote QPN\t: %d\n"
109 "shaper allocated : %d\n"
110 "rate limit\t: %d kbps\n",
111 qp->qplib_qp.id,
112 bnxt_re_qp_type_str(qp->qplib_qp.type),
113 bnxt_re_qp_state_str(qp->qplib_qp.state),
114 qp->qplib_qp.mtu,
115 qp->qplib_qp.timeout,
116 qp->qplib_qp.dest_qpn,
117 qplib_qp->shaper_allocation_status,
118 rate_limit);
119 if (!buf)
120 return -ENOMEM;
121 if (count < strlen(buf)) {
122 kfree(buf);
123 return -ENOSPC;
124 }
125 len = simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf));
126 kfree(buf);
127 return len;
128 }
129
130 static const struct file_operations debugfs_qp_fops = {
131 .owner = THIS_MODULE,
132 .open = simple_open,
133 .read = qp_info_read,
134 };
135
bnxt_re_debug_add_qpinfo(struct bnxt_re_dev * rdev,struct bnxt_re_qp * qp)136 void bnxt_re_debug_add_qpinfo(struct bnxt_re_dev *rdev, struct bnxt_re_qp *qp)
137 {
138 char resn[32];
139
140 sprintf(resn, "0x%x", qp->qplib_qp.id);
141 qp->dentry = debugfs_create_file(resn, 0400, rdev->qp_debugfs, qp, &debugfs_qp_fops);
142 }
143
bnxt_re_debug_rem_qpinfo(struct bnxt_re_dev * rdev,struct bnxt_re_qp * qp)144 void bnxt_re_debug_rem_qpinfo(struct bnxt_re_dev *rdev, struct bnxt_re_qp *qp)
145 {
146 debugfs_remove(qp->dentry);
147 }
148
map_cc_config_offset_gen0_ext0(u32 offset,struct bnxt_qplib_cc_param * ccparam,u32 * val)149 static int map_cc_config_offset_gen0_ext0(u32 offset, struct bnxt_qplib_cc_param *ccparam, u32 *val)
150 {
151 u64 map_offset;
152
153 map_offset = BIT(offset);
154
155 switch (map_offset) {
156 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_ENABLE_CC:
157 *val = ccparam->enable;
158 break;
159 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_G:
160 *val = ccparam->g;
161 break;
162 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_NUMPHASEPERSTATE:
163 *val = ccparam->nph_per_state;
164 break;
165 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_INIT_CR:
166 *val = ccparam->init_cr;
167 break;
168 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_INIT_TR:
169 *val = ccparam->init_tr;
170 break;
171 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TOS_ECN:
172 *val = ccparam->tos_ecn;
173 break;
174 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TOS_DSCP:
175 *val = ccparam->tos_dscp;
176 break;
177 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_ALT_VLAN_PCP:
178 *val = ccparam->alt_vlan_pcp;
179 break;
180 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_ALT_TOS_DSCP:
181 *val = ccparam->alt_tos_dscp;
182 break;
183 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_RTT:
184 *val = ccparam->rtt;
185 break;
186 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_CC_MODE:
187 *val = ccparam->cc_mode;
188 break;
189 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TCP_CP:
190 *val = ccparam->tcp_cp;
191 break;
192 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_INACTIVITY_CP:
193 *val = ccparam->inact_th;
194 break;
195 default:
196 return -EINVAL;
197 }
198
199 return 0;
200 }
201
bnxt_re_cc_config_get(struct file * filp,char __user * buffer,size_t usr_buf_len,loff_t * ppos)202 static ssize_t bnxt_re_cc_config_get(struct file *filp, char __user *buffer,
203 size_t usr_buf_len, loff_t *ppos)
204 {
205 struct bnxt_re_cc_param *dbg_cc_param = filp->private_data;
206 struct bnxt_re_dev *rdev = dbg_cc_param->rdev;
207 struct bnxt_qplib_cc_param ccparam = {};
208 u32 offset = dbg_cc_param->offset;
209 char buf[16];
210 u32 val;
211 int rc;
212
213 rc = bnxt_qplib_query_cc_param(&rdev->qplib_res, &ccparam);
214 if (rc)
215 return rc;
216
217 rc = map_cc_config_offset_gen0_ext0(offset, &ccparam, &val);
218 if (rc)
219 return rc;
220
221 rc = snprintf(buf, sizeof(buf), "%d\n", val);
222 if (rc < 0)
223 return rc;
224
225 return simple_read_from_buffer(buffer, usr_buf_len, ppos, (u8 *)(buf), rc);
226 }
227
bnxt_re_fill_gen0_ext0(struct bnxt_qplib_cc_param * ccparam,u32 offset,u32 val)228 static int bnxt_re_fill_gen0_ext0(struct bnxt_qplib_cc_param *ccparam, u32 offset, u32 val)
229 {
230 u32 modify_mask;
231
232 modify_mask = BIT(offset);
233
234 switch (modify_mask) {
235 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_ENABLE_CC:
236 ccparam->enable = val;
237 break;
238 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_G:
239 ccparam->g = val;
240 break;
241 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_NUMPHASEPERSTATE:
242 ccparam->nph_per_state = val;
243 break;
244 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_INIT_CR:
245 ccparam->init_cr = val;
246 break;
247 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_INIT_TR:
248 ccparam->init_tr = val;
249 break;
250 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TOS_ECN:
251 ccparam->tos_ecn = val;
252 break;
253 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TOS_DSCP:
254 ccparam->tos_dscp = val;
255 break;
256 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_ALT_VLAN_PCP:
257 ccparam->alt_vlan_pcp = val;
258 break;
259 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_ALT_TOS_DSCP:
260 ccparam->alt_tos_dscp = val;
261 break;
262 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_RTT:
263 ccparam->rtt = val;
264 break;
265 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_CC_MODE:
266 ccparam->cc_mode = val;
267 break;
268 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TCP_CP:
269 ccparam->tcp_cp = val;
270 break;
271 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TX_QUEUE:
272 return -EOPNOTSUPP;
273 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_INACTIVITY_CP:
274 ccparam->inact_th = val;
275 break;
276 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TIME_PER_PHASE:
277 ccparam->time_pph = val;
278 break;
279 case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_PKTS_PER_PHASE:
280 ccparam->pkts_pph = val;
281 break;
282 }
283
284 ccparam->mask = modify_mask;
285 return 0;
286 }
287
bnxt_re_configure_cc(struct bnxt_re_dev * rdev,u32 gen_ext,u32 offset,u32 val)288 static int bnxt_re_configure_cc(struct bnxt_re_dev *rdev, u32 gen_ext, u32 offset, u32 val)
289 {
290 struct bnxt_qplib_cc_param ccparam = { };
291 int rc;
292
293 if (gen_ext != CC_CONFIG_GEN0_EXT0)
294 return -EOPNOTSUPP;
295
296 rc = bnxt_re_fill_gen0_ext0(&ccparam, offset, val);
297 if (rc)
298 return rc;
299
300 bnxt_qplib_modify_cc(&rdev->qplib_res, &ccparam);
301 return 0;
302 }
303
bnxt_re_cc_config_set(struct file * filp,const char __user * buffer,size_t count,loff_t * ppos)304 static ssize_t bnxt_re_cc_config_set(struct file *filp, const char __user *buffer,
305 size_t count, loff_t *ppos)
306 {
307 struct bnxt_re_cc_param *dbg_cc_param = filp->private_data;
308 struct bnxt_re_dev *rdev = dbg_cc_param->rdev;
309 u32 offset = dbg_cc_param->offset;
310 u8 cc_gen = dbg_cc_param->cc_gen;
311 char buf[16];
312 u32 val;
313 int rc;
314
315 if (count >= sizeof(buf))
316 return -EINVAL;
317
318 if (copy_from_user(buf, buffer, count))
319 return -EFAULT;
320
321 buf[count] = '\0';
322 if (kstrtou32(buf, 0, &val))
323 return -EINVAL;
324
325 rc = bnxt_re_configure_cc(rdev, cc_gen, offset, val);
326 return rc ? rc : count;
327 }
328
329 static const struct file_operations bnxt_re_cc_config_ops = {
330 .owner = THIS_MODULE,
331 .open = simple_open,
332 .read = bnxt_re_cc_config_get,
333 .write = bnxt_re_cc_config_set,
334 };
335
info_show(struct seq_file * m,void * unused)336 static int info_show(struct seq_file *m, void *unused)
337 {
338 struct bnxt_re_dev *rdev = m->private;
339 struct bnxt_re_res_cntrs *res_s = &rdev->stats.res;
340
341 seq_puts(m, "Info:\n");
342 seq_printf(m, "Device Name\t\t: %s\n", dev_name(&rdev->ibdev.dev));
343 seq_printf(m, "PD Watermark\t\t: %llu\n", res_s->pd_watermark);
344 seq_printf(m, "AH Watermark\t\t: %llu\n", res_s->ah_watermark);
345 seq_printf(m, "QP Watermark\t\t: %llu\n", res_s->qp_watermark);
346 seq_printf(m, "RC QP Watermark\t\t: %llu\n", res_s->rc_qp_watermark);
347 seq_printf(m, "UD QP Watermark\t\t: %llu\n", res_s->ud_qp_watermark);
348 seq_printf(m, "SRQ Watermark\t\t: %llu\n", res_s->srq_watermark);
349 seq_printf(m, "CQ Watermark\t\t: %llu\n", res_s->cq_watermark);
350 seq_printf(m, "MR Watermark\t\t: %llu\n", res_s->mr_watermark);
351 seq_printf(m, "MW Watermark\t\t: %llu\n", res_s->mw_watermark);
352 seq_printf(m, "CQ Resize Count\t\t: %d\n", atomic_read(&res_s->resize_count));
353 if (rdev->pacing.dbr_pacing) {
354 seq_printf(m, "DB Pacing Reschedule\t: %llu\n", rdev->stats.pacing.resched);
355 seq_printf(m, "DB Pacing Complete\t: %llu\n", rdev->stats.pacing.complete);
356 seq_printf(m, "DB Pacing Alerts\t: %llu\n", rdev->stats.pacing.alerts);
357 seq_printf(m, "DB FIFO Register\t: 0x%x\n",
358 readl(rdev->en_dev->bar0 + rdev->pacing.dbr_db_fifo_reg_off));
359 }
360
361 return 0;
362 }
363 DEFINE_SHOW_ATTRIBUTE(info);
364
bnxt_re_debugfs_add_info(struct bnxt_re_dev * rdev)365 static void bnxt_re_debugfs_add_info(struct bnxt_re_dev *rdev)
366 {
367 debugfs_create_file("info", 0400, rdev->dbg_root, rdev, &info_fops);
368 }
369
cq_coal_cfg_write(struct file * file,const char __user * buf,size_t count,loff_t * pos)370 static ssize_t cq_coal_cfg_write(struct file *file,
371 const char __user *buf,
372 size_t count, loff_t *pos)
373 {
374 struct seq_file *s = file->private_data;
375 struct bnxt_re_cq_coal_param *param = s->private;
376 struct bnxt_re_dev *rdev = param->rdev;
377 int offset = param->offset;
378 char lbuf[16] = { };
379 u32 val;
380
381 if (count > sizeof(lbuf))
382 return -EINVAL;
383
384 if (copy_from_user(lbuf, buf, count))
385 return -EFAULT;
386
387 lbuf[sizeof(lbuf) - 1] = '\0';
388
389 if (kstrtou32(lbuf, 0, &val))
390 return -EINVAL;
391
392 switch (offset) {
393 case BNXT_RE_COAL_CQ_BUF_MAXTIME:
394 if (val < 1 || val > BNXT_QPLIB_CQ_COAL_MAX_BUF_MAXTIME)
395 return -EINVAL;
396 rdev->cq_coalescing.buf_maxtime = val;
397 break;
398 case BNXT_RE_COAL_CQ_NORMAL_MAXBUF:
399 if (val < 1 || val > BNXT_QPLIB_CQ_COAL_MAX_NORMAL_MAXBUF)
400 return -EINVAL;
401 rdev->cq_coalescing.normal_maxbuf = val;
402 break;
403 case BNXT_RE_COAL_CQ_DURING_MAXBUF:
404 if (val < 1 || val > BNXT_QPLIB_CQ_COAL_MAX_DURING_MAXBUF)
405 return -EINVAL;
406 rdev->cq_coalescing.during_maxbuf = val;
407 break;
408 case BNXT_RE_COAL_CQ_EN_RING_IDLE_MODE:
409 if (val > BNXT_QPLIB_CQ_COAL_MAX_EN_RING_IDLE_MODE)
410 return -EINVAL;
411 rdev->cq_coalescing.en_ring_idle_mode = val;
412 break;
413 case BNXT_RE_COAL_CQ_ENABLE:
414 if (val > 1)
415 return -EINVAL;
416 rdev->cq_coalescing.enable = val;
417 break;
418 default:
419 return -EINVAL;
420 }
421 return count;
422 }
423
cq_coal_cfg_show(struct seq_file * s,void * unused)424 static int cq_coal_cfg_show(struct seq_file *s, void *unused)
425 {
426 struct bnxt_re_cq_coal_param *param = s->private;
427 struct bnxt_re_dev *rdev = param->rdev;
428 int offset = param->offset;
429 u32 val = 0;
430
431 switch (offset) {
432 case BNXT_RE_COAL_CQ_BUF_MAXTIME:
433 val = rdev->cq_coalescing.buf_maxtime;
434 break;
435 case BNXT_RE_COAL_CQ_NORMAL_MAXBUF:
436 val = rdev->cq_coalescing.normal_maxbuf;
437 break;
438 case BNXT_RE_COAL_CQ_DURING_MAXBUF:
439 val = rdev->cq_coalescing.during_maxbuf;
440 break;
441 case BNXT_RE_COAL_CQ_EN_RING_IDLE_MODE:
442 val = rdev->cq_coalescing.en_ring_idle_mode;
443 break;
444 case BNXT_RE_COAL_CQ_ENABLE:
445 val = rdev->cq_coalescing.enable;
446 break;
447 default:
448 return -EINVAL;
449 }
450
451 seq_printf(s, "%u\n", val);
452 return 0;
453 }
454 DEFINE_SHOW_STORE_ATTRIBUTE(cq_coal_cfg);
455
bnxt_re_cleanup_cq_coal_debugfs(struct bnxt_re_dev * rdev)456 static void bnxt_re_cleanup_cq_coal_debugfs(struct bnxt_re_dev *rdev)
457 {
458 debugfs_remove_recursive(rdev->cq_coal_cfg);
459 kfree(rdev->cq_coal_cfg_params);
460 }
461
bnxt_re_init_cq_coal_debugfs(struct bnxt_re_dev * rdev)462 static void bnxt_re_init_cq_coal_debugfs(struct bnxt_re_dev *rdev)
463 {
464 struct bnxt_re_dbg_cq_coal_params *dbg_cq_coal_params;
465 int i;
466
467 if (!_is_cq_coalescing_supported(rdev->dev_attr->dev_cap_flags2))
468 return;
469
470 dbg_cq_coal_params = kzalloc_obj(*dbg_cq_coal_params);
471 if (!dbg_cq_coal_params)
472 return;
473
474 rdev->cq_coal_cfg = debugfs_create_dir("cq_coal_cfg", rdev->dbg_root);
475 rdev->cq_coal_cfg_params = dbg_cq_coal_params;
476
477 for (i = 0; i < BNXT_RE_COAL_CQ_MAX; i++) {
478 dbg_cq_coal_params->params[i].offset = i;
479 dbg_cq_coal_params->params[i].rdev = rdev;
480 debugfs_create_file(bnxt_re_cq_coal_str[i],
481 0600, rdev->cq_coal_cfg,
482 &dbg_cq_coal_params->params[i],
483 &cq_coal_cfg_fops);
484 }
485 }
486
bnxt_re_debugfs_add_pdev(struct bnxt_re_dev * rdev)487 void bnxt_re_debugfs_add_pdev(struct bnxt_re_dev *rdev)
488 {
489 struct pci_dev *pdev = rdev->en_dev->pdev;
490 struct bnxt_re_dbg_cc_config_params *cc_params;
491 int i;
492
493 rdev->dbg_root = debugfs_create_dir(dev_name(&pdev->dev), bnxt_re_debugfs_root);
494
495 rdev->qp_debugfs = debugfs_create_dir("QPs", rdev->dbg_root);
496 rdev->cc_config = debugfs_create_dir("cc_config", rdev->dbg_root);
497
498 bnxt_re_debugfs_add_info(rdev);
499
500 rdev->cc_config_params = kzalloc_obj(*cc_params);
501
502 for (i = 0; i < BNXT_RE_CC_PARAM_GEN0; i++) {
503 struct bnxt_re_cc_param *tmp_params = &rdev->cc_config_params->gen0_parms[i];
504
505 tmp_params->rdev = rdev;
506 tmp_params->offset = i;
507 tmp_params->cc_gen = CC_CONFIG_GEN0_EXT0;
508 tmp_params->dentry = debugfs_create_file(bnxt_re_cc_gen0_name[i], 0400,
509 rdev->cc_config, tmp_params,
510 &bnxt_re_cc_config_ops);
511 }
512
513 bnxt_re_init_cq_coal_debugfs(rdev);
514 }
515
bnxt_re_debugfs_rem_pdev(struct bnxt_re_dev * rdev)516 void bnxt_re_debugfs_rem_pdev(struct bnxt_re_dev *rdev)
517 {
518 bnxt_re_cleanup_cq_coal_debugfs(rdev);
519 debugfs_remove_recursive(rdev->qp_debugfs);
520 debugfs_remove_recursive(rdev->cc_config);
521 kfree(rdev->cc_config_params);
522 debugfs_remove_recursive(rdev->dbg_root);
523 rdev->dbg_root = NULL;
524 }
525
bnxt_re_register_debugfs(void)526 void bnxt_re_register_debugfs(void)
527 {
528 bnxt_re_debugfs_root = debugfs_create_dir("bnxt_re", NULL);
529 }
530
bnxt_re_unregister_debugfs(void)531 void bnxt_re_unregister_debugfs(void)
532 {
533 debugfs_remove(bnxt_re_debugfs_root);
534 }
535