xref: /linux/drivers/infiniband/hw/bnxt_re/debugfs.c (revision dd91b5e1d6448794c07378d1be12e3261c8769e7)
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