xref: /dpdk/drivers/net/hns3/hns3_regs.c (revision 68a03efeed657e6e05f281479b33b51102797e15)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018-2019 Hisilicon Limited.
3  */
4 
5 #include <ethdev_pci.h>
6 #include <rte_io.h>
7 
8 #include "hns3_ethdev.h"
9 #include "hns3_logs.h"
10 #include "hns3_rxtx.h"
11 #include "hns3_regs.h"
12 
13 #define MAX_SEPARATE_NUM	4
14 #define SEPARATOR_VALUE		0xFFFFFFFF
15 #define REG_NUM_PER_LINE	4
16 #define REG_LEN_PER_LINE	(REG_NUM_PER_LINE * sizeof(uint32_t))
17 
18 static int hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *length);
19 
20 static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_ADDR_L_REG,
21 					  HNS3_CMDQ_TX_ADDR_H_REG,
22 					  HNS3_CMDQ_TX_DEPTH_REG,
23 					  HNS3_CMDQ_TX_TAIL_REG,
24 					  HNS3_CMDQ_TX_HEAD_REG,
25 					  HNS3_CMDQ_RX_ADDR_L_REG,
26 					  HNS3_CMDQ_RX_ADDR_H_REG,
27 					  HNS3_CMDQ_RX_DEPTH_REG,
28 					  HNS3_CMDQ_RX_TAIL_REG,
29 					  HNS3_CMDQ_RX_HEAD_REG,
30 					  HNS3_VECTOR0_CMDQ_SRC_REG,
31 					  HNS3_CMDQ_INTR_STS_REG,
32 					  HNS3_CMDQ_INTR_EN_REG,
33 					  HNS3_CMDQ_INTR_GEN_REG};
34 
35 static const uint32_t common_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE,
36 					    HNS3_VECTOR0_OTER_EN_REG,
37 					    HNS3_MISC_RESET_STS_REG,
38 					    HNS3_VECTOR0_OTHER_INT_STS_REG,
39 					    HNS3_GLOBAL_RESET_REG,
40 					    HNS3_FUN_RST_ING,
41 					    HNS3_GRO_EN_REG};
42 
43 static const uint32_t common_vf_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE,
44 					       HNS3_FUN_RST_ING,
45 					       HNS3_GRO_EN_REG};
46 
47 static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BASEADDR_L_REG,
48 					  HNS3_RING_RX_BASEADDR_H_REG,
49 					  HNS3_RING_RX_BD_NUM_REG,
50 					  HNS3_RING_RX_BD_LEN_REG,
51 					  HNS3_RING_RX_EN_REG,
52 					  HNS3_RING_RX_MERGE_EN_REG,
53 					  HNS3_RING_RX_TAIL_REG,
54 					  HNS3_RING_RX_HEAD_REG,
55 					  HNS3_RING_RX_FBDNUM_REG,
56 					  HNS3_RING_RX_OFFSET_REG,
57 					  HNS3_RING_RX_FBD_OFFSET_REG,
58 					  HNS3_RING_RX_STASH_REG,
59 					  HNS3_RING_RX_BD_ERR_REG,
60 					  HNS3_RING_TX_BASEADDR_L_REG,
61 					  HNS3_RING_TX_BASEADDR_H_REG,
62 					  HNS3_RING_TX_BD_NUM_REG,
63 					  HNS3_RING_TX_EN_REG,
64 					  HNS3_RING_TX_PRIORITY_REG,
65 					  HNS3_RING_TX_TC_REG,
66 					  HNS3_RING_TX_MERGE_EN_REG,
67 					  HNS3_RING_TX_TAIL_REG,
68 					  HNS3_RING_TX_HEAD_REG,
69 					  HNS3_RING_TX_FBDNUM_REG,
70 					  HNS3_RING_TX_OFFSET_REG,
71 					  HNS3_RING_TX_EBD_NUM_REG,
72 					  HNS3_RING_TX_EBD_OFFSET_REG,
73 					  HNS3_RING_TX_BD_ERR_REG,
74 					  HNS3_RING_EN_REG};
75 
76 static const uint32_t tqp_intr_reg_addrs[] = {HNS3_TQP_INTR_CTRL_REG,
77 					      HNS3_TQP_INTR_GL0_REG,
78 					      HNS3_TQP_INTR_GL1_REG,
79 					      HNS3_TQP_INTR_GL2_REG,
80 					      HNS3_TQP_INTR_RL_REG};
81 
82 static const uint32_t hns3_dfx_reg_opcode_list[] = {
83 	HNS3_OPC_DFX_BIOS_COMMON_REG,
84 	HNS3_OPC_DFX_SSU_REG_0,
85 	HNS3_OPC_DFX_SSU_REG_1,
86 	HNS3_OPC_DFX_IGU_EGU_REG,
87 	HNS3_OPC_DFX_RPU_REG_0,
88 	HNS3_OPC_DFX_RPU_REG_1,
89 	HNS3_OPC_DFX_NCSI_REG,
90 	HNS3_OPC_DFX_RTC_REG,
91 	HNS3_OPC_DFX_PPP_REG,
92 	HNS3_OPC_DFX_RCB_REG,
93 	HNS3_OPC_DFX_TQP_REG,
94 	HNS3_OPC_DFX_SSU_REG_2
95 };
96 
97 static int
98 hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
99 		  uint32_t *regs_num_64_bit)
100 {
101 	struct hns3_cmd_desc desc;
102 	int ret;
103 
104 	hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_QUERY_REG_NUM, true);
105 	ret = hns3_cmd_send(hw, &desc, 1);
106 	if (ret) {
107 		hns3_err(hw, "Query register number cmd failed, ret = %d",
108 			 ret);
109 		return ret;
110 	}
111 
112 	*regs_num_32_bit = rte_le_to_cpu_32(desc.data[0]);
113 	*regs_num_64_bit = rte_le_to_cpu_32(desc.data[1]);
114 
115 	return 0;
116 }
117 
118 static int
119 hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
120 {
121 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
122 	uint32_t cmdq_lines, common_lines, ring_lines, tqp_intr_lines;
123 	uint32_t regs_num_32_bit, regs_num_64_bit;
124 	uint32_t dfx_reg_lines;
125 	uint32_t len;
126 	int ret;
127 
128 	cmdq_lines = sizeof(cmdq_reg_addrs) / REG_LEN_PER_LINE + 1;
129 	if (hns->is_vf)
130 		common_lines =
131 			sizeof(common_vf_reg_addrs) / REG_LEN_PER_LINE + 1;
132 	else
133 		common_lines = sizeof(common_reg_addrs) / REG_LEN_PER_LINE + 1;
134 	ring_lines = sizeof(ring_reg_addrs) / REG_LEN_PER_LINE + 1;
135 	tqp_intr_lines = sizeof(tqp_intr_reg_addrs) / REG_LEN_PER_LINE + 1;
136 
137 	len = (cmdq_lines + common_lines + ring_lines * hw->tqps_num +
138 	      tqp_intr_lines * hw->num_msi) * REG_NUM_PER_LINE;
139 
140 	if (!hns->is_vf) {
141 		ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
142 		if (ret) {
143 			hns3_err(hw, "fail to get the number of registers, "
144 				 "ret = %d.", ret);
145 			return ret;
146 		}
147 		dfx_reg_lines = regs_num_32_bit * sizeof(uint32_t) /
148 					REG_LEN_PER_LINE + 1;
149 		dfx_reg_lines += regs_num_64_bit * sizeof(uint64_t) /
150 					REG_LEN_PER_LINE + 1;
151 
152 		ret = hns3_get_dfx_reg_line(hw, &dfx_reg_lines);
153 		if (ret) {
154 			hns3_err(hw, "fail to get the number of dfx registers, "
155 				 "ret = %d.", ret);
156 			return ret;
157 		}
158 		len += dfx_reg_lines * REG_NUM_PER_LINE;
159 	}
160 
161 	*length = len;
162 	return 0;
163 }
164 
165 static int
166 hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
167 {
168 #define HNS3_32_BIT_REG_RTN_DATANUM 8
169 #define HNS3_32_BIT_DESC_NODATA_LEN 2
170 	struct hns3_cmd_desc *desc;
171 	uint32_t *reg_val = data;
172 	uint32_t *desc_data;
173 	int cmd_num;
174 	int i, k, n;
175 	int ret;
176 
177 	if (regs_num == 0)
178 		return 0;
179 
180 	cmd_num = DIV_ROUND_UP(regs_num + HNS3_32_BIT_DESC_NODATA_LEN,
181 			       HNS3_32_BIT_REG_RTN_DATANUM);
182 	desc = rte_zmalloc("hns3-32bit-regs",
183 			   sizeof(struct hns3_cmd_desc) * cmd_num, 0);
184 	if (desc == NULL) {
185 		hns3_err(hw, "Failed to allocate %zx bytes needed to "
186 			 "store 32bit regs",
187 			 sizeof(struct hns3_cmd_desc) * cmd_num);
188 		return -ENOMEM;
189 	}
190 
191 	hns3_cmd_setup_basic_desc(&desc[0], HNS3_OPC_QUERY_32_BIT_REG, true);
192 	ret = hns3_cmd_send(hw, desc, cmd_num);
193 	if (ret) {
194 		hns3_err(hw, "Query 32 bit register cmd failed, ret = %d",
195 			 ret);
196 		rte_free(desc);
197 		return ret;
198 	}
199 
200 	for (i = 0; i < cmd_num; i++) {
201 		if (i == 0) {
202 			desc_data = &desc[i].data[0];
203 			n = HNS3_32_BIT_REG_RTN_DATANUM -
204 			    HNS3_32_BIT_DESC_NODATA_LEN;
205 		} else {
206 			desc_data = (uint32_t *)(&desc[i]);
207 			n = HNS3_32_BIT_REG_RTN_DATANUM;
208 		}
209 		for (k = 0; k < n; k++) {
210 			*reg_val++ = rte_le_to_cpu_32(*desc_data++);
211 
212 			regs_num--;
213 			if (regs_num == 0)
214 				break;
215 		}
216 	}
217 
218 	rte_free(desc);
219 	return 0;
220 }
221 
222 static int
223 hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
224 {
225 #define HNS3_64_BIT_REG_RTN_DATANUM 4
226 #define HNS3_64_BIT_DESC_NODATA_LEN 1
227 	struct hns3_cmd_desc *desc;
228 	uint64_t *reg_val = data;
229 	uint64_t *desc_data;
230 	int cmd_num;
231 	int i, k, n;
232 	int ret;
233 
234 	if (regs_num == 0)
235 		return 0;
236 
237 	cmd_num = DIV_ROUND_UP(regs_num + HNS3_64_BIT_DESC_NODATA_LEN,
238 			       HNS3_64_BIT_REG_RTN_DATANUM);
239 	desc = rte_zmalloc("hns3-64bit-regs",
240 			   sizeof(struct hns3_cmd_desc) * cmd_num, 0);
241 	if (desc == NULL) {
242 		hns3_err(hw, "Failed to allocate %zx bytes needed to "
243 			 "store 64bit regs",
244 			 sizeof(struct hns3_cmd_desc) * cmd_num);
245 		return -ENOMEM;
246 	}
247 
248 	hns3_cmd_setup_basic_desc(&desc[0], HNS3_OPC_QUERY_64_BIT_REG, true);
249 	ret = hns3_cmd_send(hw, desc, cmd_num);
250 	if (ret) {
251 		hns3_err(hw, "Query 64 bit register cmd failed, ret = %d",
252 			 ret);
253 		rte_free(desc);
254 		return ret;
255 	}
256 
257 	for (i = 0; i < cmd_num; i++) {
258 		if (i == 0) {
259 			desc_data = (uint64_t *)(&desc[i].data[0]);
260 			n = HNS3_64_BIT_REG_RTN_DATANUM -
261 			    HNS3_64_BIT_DESC_NODATA_LEN;
262 		} else {
263 			desc_data = (uint64_t *)(&desc[i]);
264 			n = HNS3_64_BIT_REG_RTN_DATANUM;
265 		}
266 		for (k = 0; k < n; k++) {
267 			*reg_val++ = rte_le_to_cpu_64(*desc_data++);
268 
269 			regs_num--;
270 			if (!regs_num)
271 				break;
272 		}
273 	}
274 
275 	rte_free(desc);
276 	return 0;
277 }
278 
279 static int
280 hns3_insert_reg_separator(int reg_num, uint32_t *data)
281 {
282 	int separator_num;
283 	int i;
284 
285 	separator_num = MAX_SEPARATE_NUM - reg_num % REG_NUM_PER_LINE;
286 	for (i = 0; i < separator_num; i++)
287 		*data++ = SEPARATOR_VALUE;
288 	return separator_num;
289 }
290 
291 static int
292 hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
293 {
294 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
295 	uint32_t *origin_data_ptr = data;
296 	uint32_t reg_offset;
297 	int reg_num;
298 	int i, j;
299 
300 	/* fetching per-PF registers values from PF PCIe register space */
301 	reg_num = sizeof(cmdq_reg_addrs) / sizeof(uint32_t);
302 	for (i = 0; i < reg_num; i++)
303 		*data++ = hns3_read_dev(hw, cmdq_reg_addrs[i]);
304 	data += hns3_insert_reg_separator(reg_num, data);
305 
306 	if (hns->is_vf)
307 		reg_num = sizeof(common_vf_reg_addrs) / sizeof(uint32_t);
308 	else
309 		reg_num = sizeof(common_reg_addrs) / sizeof(uint32_t);
310 	for (i = 0; i < reg_num; i++)
311 		if (hns->is_vf)
312 			*data++ = hns3_read_dev(hw, common_vf_reg_addrs[i]);
313 		else
314 			*data++ = hns3_read_dev(hw, common_reg_addrs[i]);
315 	data += hns3_insert_reg_separator(reg_num, data);
316 
317 	reg_num = sizeof(ring_reg_addrs) / sizeof(uint32_t);
318 	for (j = 0; j < hw->tqps_num; j++) {
319 		reg_offset = hns3_get_tqp_reg_offset(j);
320 		for (i = 0; i < reg_num; i++)
321 			*data++ = hns3_read_dev(hw,
322 						ring_reg_addrs[i] + reg_offset);
323 		data += hns3_insert_reg_separator(reg_num, data);
324 	}
325 
326 	reg_num = sizeof(tqp_intr_reg_addrs) / sizeof(uint32_t);
327 	for (j = 0; j < hw->intr_tqps_num; j++) {
328 		reg_offset = hns3_get_tqp_intr_reg_offset(j);
329 		for (i = 0; i < reg_num; i++)
330 			*data++ = hns3_read_dev(hw, tqp_intr_reg_addrs[i] +
331 						reg_offset);
332 		data += hns3_insert_reg_separator(reg_num, data);
333 	}
334 	return data - origin_data_ptr;
335 }
336 
337 static int
338 hns3_get_dfx_reg_bd_num(struct hns3_hw *hw, uint32_t *bd_num_list,
339 			uint32_t list_size)
340 {
341 #define HNS3_GET_DFX_REG_BD_NUM_SIZE	4
342 	struct hns3_cmd_desc desc[HNS3_GET_DFX_REG_BD_NUM_SIZE];
343 	uint32_t index, desc_index;
344 	uint32_t bd_num;
345 	uint32_t i;
346 	int ret;
347 
348 	for (i = 0; i < HNS3_GET_DFX_REG_BD_NUM_SIZE - 1; i++) {
349 		hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_DFX_BD_NUM, true);
350 		desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT);
351 	}
352 	/* The last BD does not need a next flag */
353 	hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_DFX_BD_NUM, true);
354 
355 	ret = hns3_cmd_send(hw, desc, HNS3_GET_DFX_REG_BD_NUM_SIZE);
356 	if (ret) {
357 		hns3_err(hw, "fail to get dfx bd num, ret = %d.\n", ret);
358 		return ret;
359 	}
360 
361 	/* The first data in the first BD is a reserved field */
362 	for (i = 1; i <= list_size; i++) {
363 		desc_index = i / HNS3_CMD_DESC_DATA_NUM;
364 		index = i % HNS3_CMD_DESC_DATA_NUM;
365 		bd_num = rte_le_to_cpu_32(desc[desc_index].data[index]);
366 		bd_num_list[i - 1] = bd_num;
367 	}
368 
369 	return 0;
370 }
371 
372 static int
373 hns3_dfx_reg_cmd_send(struct hns3_hw *hw, struct hns3_cmd_desc *desc,
374 			int bd_num, uint32_t opcode)
375 {
376 	int ret;
377 	int i;
378 
379 	for (i = 0; i < bd_num - 1; i++) {
380 		hns3_cmd_setup_basic_desc(&desc[i], opcode, true);
381 		desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT);
382 	}
383 	/* The last BD does not need a next flag */
384 	hns3_cmd_setup_basic_desc(&desc[i], opcode, true);
385 
386 	ret = hns3_cmd_send(hw, desc, bd_num);
387 	if (ret) {
388 		hns3_err(hw, "fail to query dfx registers, opcode = 0x%04X, "
389 			 "ret = %d.\n", opcode, ret);
390 	}
391 
392 	return ret;
393 }
394 
395 static int
396 hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
397 {
398 	int desc_index;
399 	int reg_num;
400 	int index;
401 	int i;
402 
403 	reg_num = bd_num * HNS3_CMD_DESC_DATA_NUM;
404 	for (i = 0; i < reg_num; i++) {
405 		desc_index = i / HNS3_CMD_DESC_DATA_NUM;
406 		index = i % HNS3_CMD_DESC_DATA_NUM;
407 		*reg++ = desc[desc_index].data[index];
408 	}
409 	reg_num += hns3_insert_reg_separator(reg_num, reg);
410 
411 	return reg_num;
412 }
413 
414 static int
415 hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines)
416 {
417 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
418 	uint32_t bd_num_list[opcode_num];
419 	uint32_t bd_num, data_len;
420 	int ret;
421 	int i;
422 
423 	ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num);
424 	if (ret)
425 		return ret;
426 
427 	for (i = 0; i < opcode_num; i++) {
428 		bd_num = bd_num_list[i];
429 		data_len = bd_num * HNS3_CMD_DESC_DATA_NUM * sizeof(uint32_t);
430 		*lines += data_len / REG_LEN_PER_LINE + 1;
431 	}
432 
433 	return 0;
434 }
435 
436 static int
437 hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
438 {
439 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
440 	uint32_t max_bd_num, bd_num, opcode;
441 	uint32_t bd_num_list[opcode_num];
442 	struct hns3_cmd_desc *cmd_descs;
443 	uint32_t *reg_val = (uint32_t *)*data;
444 	int ret;
445 	int i;
446 
447 	ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num);
448 	if (ret)
449 		return ret;
450 
451 	max_bd_num = 0;
452 	for (i = 0; i < opcode_num; i++)
453 		max_bd_num = RTE_MAX(bd_num_list[i], max_bd_num);
454 
455 	cmd_descs = rte_zmalloc(NULL, sizeof(*cmd_descs) * max_bd_num, 0);
456 	if (cmd_descs == NULL)
457 		return -ENOMEM;
458 
459 	for (i = 0; i < opcode_num; i++) {
460 		opcode = hns3_dfx_reg_opcode_list[i];
461 		bd_num = bd_num_list[i];
462 		if (bd_num == 0)
463 			continue;
464 		ret = hns3_dfx_reg_cmd_send(hw, cmd_descs, bd_num, opcode);
465 		if (ret)
466 			break;
467 		reg_val += hns3_dfx_reg_fetch_data(cmd_descs, bd_num, reg_val);
468 	}
469 	rte_free(cmd_descs);
470 	*data = (void *)reg_val;
471 
472 	return ret;
473 }
474 
475 int
476 hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
477 {
478 #define HNS3_64_BIT_REG_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
479 	struct hns3_adapter *hns = eth_dev->data->dev_private;
480 	struct hns3_hw *hw = &hns->hw;
481 	uint32_t regs_num_32_bit;
482 	uint32_t regs_num_64_bit;
483 	uint32_t length;
484 	uint32_t *data;
485 	int ret;
486 
487 	if (regs == NULL) {
488 		hns3_err(hw, "the input parameter regs is NULL!");
489 		return -EINVAL;
490 	}
491 
492 	ret = hns3_get_regs_length(hw, &length);
493 	if (ret)
494 		return ret;
495 
496 	data = regs->data;
497 	if (data == NULL) {
498 		regs->length = length;
499 		regs->width = sizeof(uint32_t);
500 		return 0;
501 	}
502 
503 	/* Only full register dump is supported */
504 	if (regs->length && regs->length != length)
505 		return -ENOTSUP;
506 
507 	/* fetching per-PF registers values from PF PCIe register space */
508 	data += hns3_direct_access_regs(hw, data);
509 
510 	if (hns->is_vf)
511 		return 0;
512 
513 	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
514 	if (ret) {
515 		hns3_err(hw, "Get register number failed, ret = %d", ret);
516 		return ret;
517 	}
518 
519 	/* fetching PF common registers values from firmware */
520 	ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, data);
521 	if (ret) {
522 		hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
523 		return ret;
524 	}
525 	data += regs_num_32_bit;
526 	data += hns3_insert_reg_separator(regs_num_32_bit, data);
527 
528 	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
529 	if (ret) {
530 		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
531 		return ret;
532 	}
533 	data += regs_num_64_bit * HNS3_64_BIT_REG_SIZE;
534 	data += hns3_insert_reg_separator(regs_num_64_bit *
535 					  HNS3_64_BIT_REG_SIZE, data);
536 
537 	return  hns3_get_dfx_regs(hw, (void **)&data);
538 }
539