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
bnxt_re_qp_state_str(u8 state)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
bnxt_re_qp_type_str(u8 type)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
qp_info_read(struct file * filep,char __user * buffer,size_t count,loff_t * ppos)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
bnxt_re_debug_add_qpinfo(struct bnxt_re_dev * rdev,struct bnxt_re_qp * qp)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
bnxt_re_debug_rem_qpinfo(struct bnxt_re_dev * rdev,struct bnxt_re_qp * qp)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
map_cc_config_offset_gen0_ext0(u32 offset,struct bnxt_qplib_cc_param * ccparam,u32 * val)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
bnxt_re_cc_config_get(struct file * filp,char __user * buffer,size_t usr_buf_len,loff_t * ppos)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
bnxt_re_fill_gen0_ext0(struct bnxt_qplib_cc_param * ccparam,u32 offset,u32 val)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
bnxt_re_configure_cc(struct bnxt_re_dev * rdev,u32 gen_ext,u32 offset,u32 val)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
bnxt_re_cc_config_set(struct file * filp,const char __user * buffer,size_t count,loff_t * ppos)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
bnxt_re_debugfs_add_pdev(struct bnxt_re_dev * rdev)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
bnxt_re_debugfs_rem_pdev(struct bnxt_re_dev * rdev)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
bnxt_re_register_debugfs(void)351 void bnxt_re_register_debugfs(void)
352 {
353 bnxt_re_debugfs_root = debugfs_create_dir("bnxt_re", NULL);
354 }
355
bnxt_re_unregister_debugfs(void)356 void bnxt_re_unregister_debugfs(void)
357 {
358 debugfs_remove(bnxt_re_debugfs_root);
359 }
360