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 	default:
174 		return -EINVAL;
175 	}
176 
177 	return 0;
178 }
179 
bnxt_re_cc_config_get(struct file * filp,char __user * buffer,size_t usr_buf_len,loff_t * ppos)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 
bnxt_re_fill_gen0_ext0(struct bnxt_qplib_cc_param * ccparam,u32 offset,u32 val)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 
bnxt_re_configure_cc(struct bnxt_re_dev * rdev,u32 gen_ext,u32 offset,u32 val)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 
bnxt_re_cc_config_set(struct file * filp,const char __user * buffer,size_t count,loff_t * ppos)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 
bnxt_re_debugfs_add_pdev(struct bnxt_re_dev * rdev)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 
bnxt_re_debugfs_rem_pdev(struct bnxt_re_dev * rdev)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 
bnxt_re_register_debugfs(void)343 void bnxt_re_register_debugfs(void)
344 {
345 	bnxt_re_debugfs_root = debugfs_create_dir("bnxt_re", NULL);
346 }
347 
bnxt_re_unregister_debugfs(void)348 void bnxt_re_unregister_debugfs(void)
349 {
350 	debugfs_remove(bnxt_re_debugfs_root);
351 }
352