net/hns3: fix copyright date
[dpdk.git] / drivers / net / hns3 / hns3_regs.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018-2021 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         ret = hns3_get_regs_length(hw, &length);
488         if (ret)
489                 return ret;
490
491         data = regs->data;
492         if (data == NULL) {
493                 regs->length = length;
494                 regs->width = sizeof(uint32_t);
495                 return 0;
496         }
497
498         /* Only full register dump is supported */
499         if (regs->length && regs->length != length)
500                 return -ENOTSUP;
501
502         /* fetching per-PF registers values from PF PCIe register space */
503         data += hns3_direct_access_regs(hw, data);
504
505         if (hns->is_vf)
506                 return 0;
507
508         ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
509         if (ret) {
510                 hns3_err(hw, "Get register number failed, ret = %d", ret);
511                 return ret;
512         }
513
514         /* fetching PF common registers values from firmware */
515         ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, data);
516         if (ret) {
517                 hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
518                 return ret;
519         }
520         data += regs_num_32_bit;
521         data += hns3_insert_reg_separator(regs_num_32_bit, data);
522
523         ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
524         if (ret) {
525                 hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
526                 return ret;
527         }
528         data += regs_num_64_bit * HNS3_64_BIT_REG_SIZE;
529         data += hns3_insert_reg_separator(regs_num_64_bit *
530                                           HNS3_64_BIT_REG_SIZE, data);
531
532         return  hns3_get_dfx_regs(hw, (void **)&data);
533 }