net/hns3: get Rx/Tx queue fbd in xstats
[dpdk.git] / drivers / net / hns3 / hns3_stats.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018-2019 Hisilicon Limited.
3  */
4
5 #include <stdbool.h>
6 #include <stdint.h>
7 #include <rte_common.h>
8 #include <rte_ethdev.h>
9 #include <rte_io.h>
10 #include <rte_malloc.h>
11 #include <rte_spinlock.h>
12
13 #include "hns3_ethdev.h"
14 #include "hns3_rxtx.h"
15 #include "hns3_logs.h"
16 #include "hns3_regs.h"
17
18 /* MAC statistics */
19 static const struct hns3_xstats_name_offset hns3_mac_strings[] = {
20         {"mac_tx_mac_pause_num",
21                 HNS3_MAC_STATS_OFFSET(mac_tx_mac_pause_num)},
22         {"mac_rx_mac_pause_num",
23                 HNS3_MAC_STATS_OFFSET(mac_rx_mac_pause_num)},
24         {"mac_tx_control_pkt_num",
25                 HNS3_MAC_STATS_OFFSET(mac_tx_ctrl_pkt_num)},
26         {"mac_rx_control_pkt_num",
27                 HNS3_MAC_STATS_OFFSET(mac_rx_ctrl_pkt_num)},
28         {"mac_tx_pfc_pkt_num",
29                 HNS3_MAC_STATS_OFFSET(mac_tx_pfc_pause_pkt_num)},
30         {"mac_tx_pfc_pri0_pkt_num",
31                 HNS3_MAC_STATS_OFFSET(mac_tx_pfc_pri0_pkt_num)},
32         {"mac_tx_pfc_pri1_pkt_num",
33                 HNS3_MAC_STATS_OFFSET(mac_tx_pfc_pri1_pkt_num)},
34         {"mac_tx_pfc_pri2_pkt_num",
35                 HNS3_MAC_STATS_OFFSET(mac_tx_pfc_pri2_pkt_num)},
36         {"mac_tx_pfc_pri3_pkt_num",
37                 HNS3_MAC_STATS_OFFSET(mac_tx_pfc_pri3_pkt_num)},
38         {"mac_tx_pfc_pri4_pkt_num",
39                 HNS3_MAC_STATS_OFFSET(mac_tx_pfc_pri4_pkt_num)},
40         {"mac_tx_pfc_pri5_pkt_num",
41                 HNS3_MAC_STATS_OFFSET(mac_tx_pfc_pri5_pkt_num)},
42         {"mac_tx_pfc_pri6_pkt_num",
43                 HNS3_MAC_STATS_OFFSET(mac_tx_pfc_pri6_pkt_num)},
44         {"mac_tx_pfc_pri7_pkt_num",
45                 HNS3_MAC_STATS_OFFSET(mac_tx_pfc_pri7_pkt_num)},
46         {"mac_rx_pfc_pkt_num",
47                 HNS3_MAC_STATS_OFFSET(mac_rx_pfc_pause_pkt_num)},
48         {"mac_rx_pfc_pri0_pkt_num",
49                 HNS3_MAC_STATS_OFFSET(mac_rx_pfc_pri0_pkt_num)},
50         {"mac_rx_pfc_pri1_pkt_num",
51                 HNS3_MAC_STATS_OFFSET(mac_rx_pfc_pri1_pkt_num)},
52         {"mac_rx_pfc_pri2_pkt_num",
53                 HNS3_MAC_STATS_OFFSET(mac_rx_pfc_pri2_pkt_num)},
54         {"mac_rx_pfc_pri3_pkt_num",
55                 HNS3_MAC_STATS_OFFSET(mac_rx_pfc_pri3_pkt_num)},
56         {"mac_rx_pfc_pri4_pkt_num",
57                 HNS3_MAC_STATS_OFFSET(mac_rx_pfc_pri4_pkt_num)},
58         {"mac_rx_pfc_pri5_pkt_num",
59                 HNS3_MAC_STATS_OFFSET(mac_rx_pfc_pri5_pkt_num)},
60         {"mac_rx_pfc_pri6_pkt_num",
61                 HNS3_MAC_STATS_OFFSET(mac_rx_pfc_pri6_pkt_num)},
62         {"mac_rx_pfc_pri7_pkt_num",
63                 HNS3_MAC_STATS_OFFSET(mac_rx_pfc_pri7_pkt_num)},
64         {"mac_tx_total_pkt_num",
65                 HNS3_MAC_STATS_OFFSET(mac_tx_total_pkt_num)},
66         {"mac_tx_total_oct_num",
67                 HNS3_MAC_STATS_OFFSET(mac_tx_total_oct_num)},
68         {"mac_tx_good_pkt_num",
69                 HNS3_MAC_STATS_OFFSET(mac_tx_good_pkt_num)},
70         {"mac_tx_bad_pkt_num",
71                 HNS3_MAC_STATS_OFFSET(mac_tx_bad_pkt_num)},
72         {"mac_tx_good_oct_num",
73                 HNS3_MAC_STATS_OFFSET(mac_tx_good_oct_num)},
74         {"mac_tx_bad_oct_num",
75                 HNS3_MAC_STATS_OFFSET(mac_tx_bad_oct_num)},
76         {"mac_tx_uni_pkt_num",
77                 HNS3_MAC_STATS_OFFSET(mac_tx_uni_pkt_num)},
78         {"mac_tx_multi_pkt_num",
79                 HNS3_MAC_STATS_OFFSET(mac_tx_multi_pkt_num)},
80         {"mac_tx_broad_pkt_num",
81                 HNS3_MAC_STATS_OFFSET(mac_tx_broad_pkt_num)},
82         {"mac_tx_undersize_pkt_num",
83                 HNS3_MAC_STATS_OFFSET(mac_tx_undersize_pkt_num)},
84         {"mac_tx_oversize_pkt_num",
85                 HNS3_MAC_STATS_OFFSET(mac_tx_oversize_pkt_num)},
86         {"mac_tx_64_oct_pkt_num",
87                 HNS3_MAC_STATS_OFFSET(mac_tx_64_oct_pkt_num)},
88         {"mac_tx_65_127_oct_pkt_num",
89                 HNS3_MAC_STATS_OFFSET(mac_tx_65_127_oct_pkt_num)},
90         {"mac_tx_128_255_oct_pkt_num",
91                 HNS3_MAC_STATS_OFFSET(mac_tx_128_255_oct_pkt_num)},
92         {"mac_tx_256_511_oct_pkt_num",
93                 HNS3_MAC_STATS_OFFSET(mac_tx_256_511_oct_pkt_num)},
94         {"mac_tx_512_1023_oct_pkt_num",
95                 HNS3_MAC_STATS_OFFSET(mac_tx_512_1023_oct_pkt_num)},
96         {"mac_tx_1024_1518_oct_pkt_num",
97                 HNS3_MAC_STATS_OFFSET(mac_tx_1024_1518_oct_pkt_num)},
98         {"mac_tx_1519_2047_oct_pkt_num",
99                 HNS3_MAC_STATS_OFFSET(mac_tx_1519_2047_oct_pkt_num)},
100         {"mac_tx_2048_4095_oct_pkt_num",
101                 HNS3_MAC_STATS_OFFSET(mac_tx_2048_4095_oct_pkt_num)},
102         {"mac_tx_4096_8191_oct_pkt_num",
103                 HNS3_MAC_STATS_OFFSET(mac_tx_4096_8191_oct_pkt_num)},
104         {"mac_tx_8192_9216_oct_pkt_num",
105                 HNS3_MAC_STATS_OFFSET(mac_tx_8192_9216_oct_pkt_num)},
106         {"mac_tx_9217_12287_oct_pkt_num",
107                 HNS3_MAC_STATS_OFFSET(mac_tx_9217_12287_oct_pkt_num)},
108         {"mac_tx_12288_16383_oct_pkt_num",
109                 HNS3_MAC_STATS_OFFSET(mac_tx_12288_16383_oct_pkt_num)},
110         {"mac_tx_1519_max_good_pkt_num",
111                 HNS3_MAC_STATS_OFFSET(mac_tx_1519_max_good_oct_pkt_num)},
112         {"mac_tx_1519_max_bad_pkt_num",
113                 HNS3_MAC_STATS_OFFSET(mac_tx_1519_max_bad_oct_pkt_num)},
114         {"mac_rx_total_pkt_num",
115                 HNS3_MAC_STATS_OFFSET(mac_rx_total_pkt_num)},
116         {"mac_rx_total_oct_num",
117                 HNS3_MAC_STATS_OFFSET(mac_rx_total_oct_num)},
118         {"mac_rx_good_pkt_num",
119                 HNS3_MAC_STATS_OFFSET(mac_rx_good_pkt_num)},
120         {"mac_rx_bad_pkt_num",
121                 HNS3_MAC_STATS_OFFSET(mac_rx_bad_pkt_num)},
122         {"mac_rx_good_oct_num",
123                 HNS3_MAC_STATS_OFFSET(mac_rx_good_oct_num)},
124         {"mac_rx_bad_oct_num",
125                 HNS3_MAC_STATS_OFFSET(mac_rx_bad_oct_num)},
126         {"mac_rx_uni_pkt_num",
127                 HNS3_MAC_STATS_OFFSET(mac_rx_uni_pkt_num)},
128         {"mac_rx_multi_pkt_num",
129                 HNS3_MAC_STATS_OFFSET(mac_rx_multi_pkt_num)},
130         {"mac_rx_broad_pkt_num",
131                 HNS3_MAC_STATS_OFFSET(mac_rx_broad_pkt_num)},
132         {"mac_rx_undersize_pkt_num",
133                 HNS3_MAC_STATS_OFFSET(mac_rx_undersize_pkt_num)},
134         {"mac_rx_oversize_pkt_num",
135                 HNS3_MAC_STATS_OFFSET(mac_rx_oversize_pkt_num)},
136         {"mac_rx_64_oct_pkt_num",
137                 HNS3_MAC_STATS_OFFSET(mac_rx_64_oct_pkt_num)},
138         {"mac_rx_65_127_oct_pkt_num",
139                 HNS3_MAC_STATS_OFFSET(mac_rx_65_127_oct_pkt_num)},
140         {"mac_rx_128_255_oct_pkt_num",
141                 HNS3_MAC_STATS_OFFSET(mac_rx_128_255_oct_pkt_num)},
142         {"mac_rx_256_511_oct_pkt_num",
143                 HNS3_MAC_STATS_OFFSET(mac_rx_256_511_oct_pkt_num)},
144         {"mac_rx_512_1023_oct_pkt_num",
145                 HNS3_MAC_STATS_OFFSET(mac_rx_512_1023_oct_pkt_num)},
146         {"mac_rx_1024_1518_oct_pkt_num",
147                 HNS3_MAC_STATS_OFFSET(mac_rx_1024_1518_oct_pkt_num)},
148         {"mac_rx_1519_2047_oct_pkt_num",
149                 HNS3_MAC_STATS_OFFSET(mac_rx_1519_2047_oct_pkt_num)},
150         {"mac_rx_2048_4095_oct_pkt_num",
151                 HNS3_MAC_STATS_OFFSET(mac_rx_2048_4095_oct_pkt_num)},
152         {"mac_rx_4096_8191_oct_pkt_num",
153                 HNS3_MAC_STATS_OFFSET(mac_rx_4096_8191_oct_pkt_num)},
154         {"mac_rx_8192_9216_oct_pkt_num",
155                 HNS3_MAC_STATS_OFFSET(mac_rx_8192_9216_oct_pkt_num)},
156         {"mac_rx_9217_12287_oct_pkt_num",
157                 HNS3_MAC_STATS_OFFSET(mac_rx_9217_12287_oct_pkt_num)},
158         {"mac_rx_12288_16383_oct_pkt_num",
159                 HNS3_MAC_STATS_OFFSET(mac_rx_12288_16383_oct_pkt_num)},
160         {"mac_rx_1519_max_good_pkt_num",
161                 HNS3_MAC_STATS_OFFSET(mac_rx_1519_max_good_oct_pkt_num)},
162         {"mac_rx_1519_max_bad_pkt_num",
163                 HNS3_MAC_STATS_OFFSET(mac_rx_1519_max_bad_oct_pkt_num)},
164         {"mac_tx_fragment_pkt_num",
165                 HNS3_MAC_STATS_OFFSET(mac_tx_fragment_pkt_num)},
166         {"mac_tx_undermin_pkt_num",
167                 HNS3_MAC_STATS_OFFSET(mac_tx_undermin_pkt_num)},
168         {"mac_tx_jabber_pkt_num",
169                 HNS3_MAC_STATS_OFFSET(mac_tx_jabber_pkt_num)},
170         {"mac_tx_err_all_pkt_num",
171                 HNS3_MAC_STATS_OFFSET(mac_tx_err_all_pkt_num)},
172         {"mac_tx_from_app_good_pkt_num",
173                 HNS3_MAC_STATS_OFFSET(mac_tx_from_app_good_pkt_num)},
174         {"mac_tx_from_app_bad_pkt_num",
175                 HNS3_MAC_STATS_OFFSET(mac_tx_from_app_bad_pkt_num)},
176         {"mac_rx_fragment_pkt_num",
177                 HNS3_MAC_STATS_OFFSET(mac_rx_fragment_pkt_num)},
178         {"mac_rx_undermin_pkt_num",
179                 HNS3_MAC_STATS_OFFSET(mac_rx_undermin_pkt_num)},
180         {"mac_rx_jabber_pkt_num",
181                 HNS3_MAC_STATS_OFFSET(mac_rx_jabber_pkt_num)},
182         {"mac_rx_fcs_err_pkt_num",
183                 HNS3_MAC_STATS_OFFSET(mac_rx_fcs_err_pkt_num)},
184         {"mac_rx_send_app_good_pkt_num",
185                 HNS3_MAC_STATS_OFFSET(mac_rx_send_app_good_pkt_num)},
186         {"mac_rx_send_app_bad_pkt_num",
187                 HNS3_MAC_STATS_OFFSET(mac_rx_send_app_bad_pkt_num)}
188 };
189
190 static const struct hns3_xstats_name_offset hns3_error_int_stats_strings[] = {
191         {"MAC_AFIFO_TNL_INT_R",
192                 HNS3_ERR_INT_STATS_FIELD_OFFSET(mac_afifo_tnl_intr_cnt)},
193         {"PPU_MPF_ABNORMAL_INT_ST2",
194                 HNS3_ERR_INT_STATS_FIELD_OFFSET(ppu_mpf_abnormal_intr_st2_cnt)},
195         {"SSU_PORT_BASED_ERR_INT",
196                 HNS3_ERR_INT_STATS_FIELD_OFFSET(ssu_port_based_pf_intr_cnt)},
197         {"PPP_PF_ABNORMAL_INT_ST0",
198                 HNS3_ERR_INT_STATS_FIELD_OFFSET(ppp_pf_abnormal_intr_cnt)},
199         {"PPU_PF_ABNORMAL_INT_ST",
200                 HNS3_ERR_INT_STATS_FIELD_OFFSET(ppu_pf_abnormal_intr_cnt)}
201 };
202
203 /* The statistic of reset */
204 static const struct hns3_xstats_name_offset hns3_reset_stats_strings[] = {
205         {"REQ_RESET_CNT",
206                 HNS3_RESET_STATS_FIELD_OFFSET(request_cnt)},
207         {"GLOBAL_RESET_CNT",
208                 HNS3_RESET_STATS_FIELD_OFFSET(global_cnt)},
209         {"IMP_RESET_CNT",
210                 HNS3_RESET_STATS_FIELD_OFFSET(imp_cnt)},
211         {"RESET_EXEC_CNT",
212                 HNS3_RESET_STATS_FIELD_OFFSET(exec_cnt)},
213         {"RESET_SUCCESS_CNT",
214                 HNS3_RESET_STATS_FIELD_OFFSET(success_cnt)},
215         {"RESET_FAIL_CNT",
216                 HNS3_RESET_STATS_FIELD_OFFSET(fail_cnt)},
217         {"RESET_MERGE_CNT",
218                 HNS3_RESET_STATS_FIELD_OFFSET(merge_cnt)}
219 };
220
221 /* The statistic of errors in Rx BD */
222 static const struct hns3_xstats_name_offset hns3_rx_bd_error_strings[] = {
223         {"RX_PKT_LEN_ERRORS",
224                 HNS3_RX_BD_ERROR_STATS_FIELD_OFFSET(pkt_len_errors)},
225         {"L2_RX_ERRORS",
226                 HNS3_RX_BD_ERROR_STATS_FIELD_OFFSET(l2_errors)},
227         {"RX_L3_CHECKSUM_ERRORS",
228                 HNS3_RX_BD_ERROR_STATS_FIELD_OFFSET(l3_csum_erros)},
229         {"RX_L4_CHECKSUM_ERRORS",
230                 HNS3_RX_BD_ERROR_STATS_FIELD_OFFSET(l4_csum_erros)},
231         {"RX_OL3_CHECKSUM_ERRORS",
232                 HNS3_RX_BD_ERROR_STATS_FIELD_OFFSET(ol3_csum_erros)},
233         {"RX_OL4_CHECKSUM_ERRORS",
234                 HNS3_RX_BD_ERROR_STATS_FIELD_OFFSET(ol4_csum_erros)}
235 };
236
237 /* The statistic of rx queue */
238 static const struct hns3_xstats_name_offset hns3_rx_queue_strings[] = {
239         {"RX_QUEUE_FBD", HNS3_RING_RX_FBDNUM_REG}
240 };
241
242 /* The statistic of tx queue */
243 static const struct hns3_xstats_name_offset hns3_tx_queue_strings[] = {
244         {"TX_QUEUE_FBD", HNS3_RING_TX_FBDNUM_REG}
245 };
246
247 #define HNS3_NUM_MAC_STATS (sizeof(hns3_mac_strings) / \
248         sizeof(hns3_mac_strings[0]))
249
250 #define HNS3_NUM_ERROR_INT_XSTATS (sizeof(hns3_error_int_stats_strings) / \
251         sizeof(hns3_error_int_stats_strings[0]))
252
253 #define HNS3_NUM_RESET_XSTATS (sizeof(hns3_reset_stats_strings) / \
254         sizeof(hns3_reset_stats_strings[0]))
255
256 #define HNS3_NUM_RX_BD_ERROR_XSTATS (sizeof(hns3_rx_bd_error_strings) / \
257         sizeof(hns3_rx_bd_error_strings[0]))
258
259 #define HNS3_NUM_RX_QUEUE_STATS (sizeof(hns3_rx_queue_strings) / \
260         sizeof(hns3_rx_queue_strings[0]))
261
262 #define HNS3_NUM_TX_QUEUE_STATS (sizeof(hns3_tx_queue_strings) / \
263         sizeof(hns3_tx_queue_strings[0]))
264
265 #define HNS3_FIX_NUM_STATS (HNS3_NUM_MAC_STATS + HNS3_NUM_ERROR_INT_XSTATS + \
266                             HNS3_NUM_RESET_XSTATS)
267
268 /*
269  * Query all the MAC statistics data of Network ICL command ,opcode id: 0x0034.
270  * This command is used before send 'query_mac_stat command', the descriptor
271  * number of 'query_mac_stat command' must match with reg_num in this command.
272  * @praram hw
273  *   Pointer to structure hns3_hw.
274  * @return
275  *   0 on success.
276  */
277 static int
278 hns3_update_mac_stats(struct hns3_hw *hw, const uint32_t desc_num)
279 {
280         uint64_t *data = (uint64_t *)(&hw->mac_stats);
281         struct hns3_cmd_desc *desc;
282         uint64_t *desc_data;
283         uint16_t i, k, n;
284         int ret;
285
286         desc = rte_malloc("hns3_mac_desc",
287                           desc_num * sizeof(struct hns3_cmd_desc), 0);
288         if (desc == NULL) {
289                 hns3_err(hw, "Mac_update_stats alloced desc malloc fail");
290                 return -ENOMEM;
291         }
292
293         hns3_cmd_setup_basic_desc(desc, HNS3_OPC_STATS_MAC_ALL, true);
294         ret = hns3_cmd_send(hw, desc, desc_num);
295         if (ret) {
296                 hns3_err(hw, "Update complete MAC pkt stats fail : %d", ret);
297                 rte_free(desc);
298                 return ret;
299         }
300
301         for (i = 0; i < desc_num; i++) {
302                 /* For special opcode 0034, only the first desc has the head */
303                 if (i == 0) {
304                         desc_data = (uint64_t *)(&desc[i].data[0]);
305                         n = HNS3_RD_FIRST_STATS_NUM;
306                 } else {
307                         desc_data = (uint64_t *)(&desc[i]);
308                         n = HNS3_RD_OTHER_STATS_NUM;
309                 }
310
311                 for (k = 0; k < n; k++) {
312                         *data += rte_le_to_cpu_64(*desc_data);
313                         data++;
314                         desc_data++;
315                 }
316         }
317         rte_free(desc);
318
319         return 0;
320 }
321
322 /*
323  * Query Mac stat reg num command ,opcode id: 0x0033.
324  * This command is used before send 'query_mac_stat command', the descriptor
325  * number of 'query_mac_stat command' must match with reg_num in this command.
326  * @praram rte_stats
327  *   Pointer to structure rte_eth_stats.
328  * @return
329  *   0 on success.
330  */
331 static int
332 hns3_mac_query_reg_num(struct rte_eth_dev *dev, uint32_t *desc_num)
333 {
334         struct hns3_adapter *hns = dev->data->dev_private;
335         struct hns3_hw *hw = &hns->hw;
336         struct hns3_cmd_desc desc;
337         uint32_t *desc_data;
338         uint32_t reg_num;
339         int ret;
340
341         hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_QUERY_MAC_REG_NUM, true);
342         ret = hns3_cmd_send(hw, &desc, 1);
343         if (ret)
344                 return ret;
345
346         /*
347          * The num of MAC statistics registers that are provided by IMP in this
348          * version.
349          */
350         desc_data = (uint32_t *)(&desc.data[0]);
351         reg_num = rte_le_to_cpu_32(*desc_data);
352
353         /*
354          * The descriptor number of 'query_additional_mac_stat command' is
355          * '1 + (reg_num-3)/4 + ((reg_num-3)%4 !=0)';
356          * This value is 83 in this version
357          */
358         *desc_num = 1 + ((reg_num - 3) >> 2) +
359                     (uint32_t)(((reg_num - 3) & 0x3) ? 1 : 0);
360
361         return 0;
362 }
363
364 static int
365 hns3_query_update_mac_stats(struct rte_eth_dev *dev)
366 {
367         struct hns3_adapter *hns = dev->data->dev_private;
368         struct hns3_hw *hw = &hns->hw;
369         uint32_t desc_num;
370         int ret;
371
372         ret = hns3_mac_query_reg_num(dev, &desc_num);
373         if (ret == 0)
374                 ret = hns3_update_mac_stats(hw, desc_num);
375         else
376                 hns3_err(hw, "Query mac reg num fail : %d", ret);
377         return ret;
378 }
379
380 /* Get tqp stats from register */
381 static int
382 hns3_update_tqp_stats(struct hns3_hw *hw)
383 {
384         struct hns3_tqp_stats *stats = &hw->tqp_stats;
385         struct hns3_cmd_desc desc;
386         uint64_t cnt;
387         uint16_t i;
388         int ret;
389
390         for (i = 0; i < hw->tqps_num; i++) {
391                 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_QUERY_RX_STATUS,
392                                           true);
393
394                 desc.data[0] = rte_cpu_to_le_32((uint32_t)i &
395                                                 HNS3_QUEUE_ID_MASK);
396                 ret = hns3_cmd_send(hw, &desc, 1);
397                 if (ret) {
398                         hns3_err(hw, "Failed to query RX No.%d queue stat: %d",
399                                  i, ret);
400                         return ret;
401                 }
402                 cnt = rte_le_to_cpu_32(desc.data[1]);
403                 stats->rcb_rx_ring_pktnum_rcd += cnt;
404                 stats->rcb_rx_ring_pktnum[i] += cnt;
405
406                 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_QUERY_TX_STATUS,
407                                           true);
408
409                 desc.data[0] = rte_cpu_to_le_32((uint32_t)i &
410                                                 HNS3_QUEUE_ID_MASK);
411                 ret = hns3_cmd_send(hw, &desc, 1);
412                 if (ret) {
413                         hns3_err(hw, "Failed to query TX No.%d queue stat: %d",
414                                  i, ret);
415                         return ret;
416                 }
417                 cnt = rte_le_to_cpu_32(desc.data[1]);
418                 stats->rcb_tx_ring_pktnum_rcd += cnt;
419                 stats->rcb_tx_ring_pktnum[i] += cnt;
420         }
421
422         return 0;
423 }
424
425 /*
426  * Query tqp tx queue statistics ,opcode id: 0x0B03.
427  * Query tqp rx queue statistics ,opcode id: 0x0B13.
428  * Get all statistics of a port.
429  * @param eth_dev
430  *   Pointer to Ethernet device.
431  * @praram rte_stats
432  *   Pointer to structure rte_eth_stats.
433  * @return
434  *   0 on success.
435  */
436 int
437 hns3_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *rte_stats)
438 {
439         struct hns3_adapter *hns = eth_dev->data->dev_private;
440         struct hns3_hw *hw = &hns->hw;
441         struct hns3_tqp_stats *stats = &hw->tqp_stats;
442         struct hns3_rx_queue *rxq;
443         struct hns3_tx_queue *txq;
444         uint64_t cnt;
445         uint64_t num;
446         uint16_t i;
447         int ret;
448
449         /* Update tqp stats by read register */
450         ret = hns3_update_tqp_stats(hw);
451         if (ret) {
452                 hns3_err(hw, "Update tqp stats fail : %d", ret);
453                 return ret;
454         }
455
456         /* Get the error stats of received packets */
457         num = RTE_MIN(RTE_ETHDEV_QUEUE_STAT_CNTRS, eth_dev->data->nb_rx_queues);
458         for (i = 0; i != num; ++i) {
459                 rxq = eth_dev->data->rx_queues[i];
460                 if (rxq) {
461                         cnt = rxq->l2_errors + rxq->pkt_len_errors;
462                         rte_stats->q_errors[i] = cnt;
463                         rte_stats->q_ipackets[i] =
464                                 stats->rcb_rx_ring_pktnum[i] - cnt;
465                         rte_stats->ierrors += cnt;
466                 }
467         }
468         /* Get the error stats of transmitted packets */
469         num = RTE_MIN(RTE_ETHDEV_QUEUE_STAT_CNTRS, eth_dev->data->nb_tx_queues);
470         for (i = 0; i < num; i++) {
471                 txq = eth_dev->data->tx_queues[i];
472                 if (txq)
473                         rte_stats->q_opackets[i] = stats->rcb_tx_ring_pktnum[i];
474         }
475
476         rte_stats->oerrors = 0;
477         rte_stats->ipackets  = stats->rcb_rx_ring_pktnum_rcd -
478                 rte_stats->ierrors;
479         rte_stats->opackets  = stats->rcb_tx_ring_pktnum_rcd -
480                 rte_stats->oerrors;
481         rte_stats->rx_nombuf = eth_dev->data->rx_mbuf_alloc_failed;
482
483         return 0;
484 }
485
486 int
487 hns3_stats_reset(struct rte_eth_dev *eth_dev)
488 {
489         struct hns3_adapter *hns = eth_dev->data->dev_private;
490         struct hns3_hw *hw = &hns->hw;
491         struct hns3_tqp_stats *stats = &hw->tqp_stats;
492         struct hns3_cmd_desc desc_reset;
493         struct hns3_rx_queue *rxq;
494         uint16_t i;
495         int ret;
496
497         /*
498          * If this is a reset xstats is NULL, and we have cleared the
499          * registers by reading them.
500          */
501         for (i = 0; i < hw->tqps_num; i++) {
502                 hns3_cmd_setup_basic_desc(&desc_reset, HNS3_OPC_QUERY_RX_STATUS,
503                                           true);
504                 desc_reset.data[0] = rte_cpu_to_le_32((uint32_t)i &
505                                                       HNS3_QUEUE_ID_MASK);
506                 ret = hns3_cmd_send(hw, &desc_reset, 1);
507                 if (ret) {
508                         hns3_err(hw, "Failed to reset RX No.%d queue stat: %d",
509                                  i, ret);
510                 }
511
512                 hns3_cmd_setup_basic_desc(&desc_reset, HNS3_OPC_QUERY_TX_STATUS,
513                                           true);
514                 desc_reset.data[0] = rte_cpu_to_le_32((uint32_t)i &
515                                                       HNS3_QUEUE_ID_MASK);
516                 ret = hns3_cmd_send(hw, &desc_reset, 1);
517                 if (ret) {
518                         hns3_err(hw, "Failed to reset TX No.%d queue stat: %d",
519                                  i, ret);
520                 }
521         }
522
523         /* Clear Rx BD and Tx error stats */
524         for (i = 0; i != eth_dev->data->nb_rx_queues; ++i) {
525                 rxq = eth_dev->data->rx_queues[i];
526                 if (rxq) {
527                         rxq->pkt_len_errors = 0;
528                         rxq->l2_errors = 0;
529                         rxq->l3_csum_erros = 0;
530                         rxq->l4_csum_erros = 0;
531                         rxq->ol3_csum_erros = 0;
532                         rxq->ol4_csum_erros = 0;
533                 }
534         }
535
536         memset(stats, 0, sizeof(struct hns3_tqp_stats));
537
538         return 0;
539 }
540
541 static void
542 hns3_mac_stats_reset(__rte_unused struct rte_eth_dev *dev)
543 {
544         struct hns3_adapter *hns = dev->data->dev_private;
545         struct hns3_hw *hw = &hns->hw;
546         struct hns3_mac_stats *mac_stats = &hw->mac_stats;
547         int ret;
548
549         ret = hns3_query_update_mac_stats(dev);
550         if (ret)
551                 hns3_err(hw, "Clear Mac stats fail : %d", ret);
552
553         memset(mac_stats, 0, sizeof(struct hns3_mac_stats));
554 }
555
556 /* This function calculates the number of xstats based on the current config */
557 static int
558 hns3_xstats_calc_num(struct rte_eth_dev *dev)
559 {
560         struct hns3_adapter *hns = dev->data->dev_private;
561         int bderr_stats = dev->data->nb_rx_queues * HNS3_NUM_RX_BD_ERROR_XSTATS;
562         int rx_queue_stats = dev->data->nb_rx_queues * HNS3_NUM_RX_QUEUE_STATS;
563         int tx_queue_stats = dev->data->nb_tx_queues * HNS3_NUM_TX_QUEUE_STATS;
564
565         if (hns->is_vf)
566                 return bderr_stats + rx_queue_stats + tx_queue_stats +
567                         HNS3_NUM_RESET_XSTATS;
568         else
569                 return bderr_stats + rx_queue_stats + tx_queue_stats +
570                         HNS3_FIX_NUM_STATS;
571 }
572
573 /*
574  * Retrieve extended(tqp | Mac) statistics of an Ethernet device.
575  * @param dev
576  *   Pointer to Ethernet device.
577  * @praram xstats
578  *   A pointer to a table of structure of type *rte_eth_xstat*
579  *   to be filled with device statistics ids and values.
580  *   This parameter can be set to NULL if n is 0.
581  * @param n
582  *   The size of the xstats array (number of elements).
583  * @return
584  *   0 on fail, count(The size of the statistics elements) on success.
585  */
586 int
587 hns3_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
588                     unsigned int n)
589 {
590         struct hns3_adapter *hns = dev->data->dev_private;
591         struct hns3_pf *pf = &hns->pf;
592         struct hns3_hw *hw = &hns->hw;
593         struct hns3_mac_stats *mac_stats = &hw->mac_stats;
594         struct hns3_reset_stats *reset_stats = &hw->reset.stats;
595         struct hns3_rx_queue *rxq;
596         uint32_t reg_offset;
597         uint16_t i, j;
598         char *addr;
599         int count;
600         int ret;
601
602         if (xstats == NULL)
603                 return 0;
604
605         count = hns3_xstats_calc_num(dev);
606         if ((int)n < count)
607                 return count;
608
609         count = 0;
610
611         if (!hns->is_vf) {
612                 /* Update Mac stats */
613                 ret = hns3_query_update_mac_stats(dev);
614                 if (ret) {
615                         hns3_err(hw, "Update Mac stats fail : %d", ret);
616                         return 0;
617                 }
618
619                 /* Get MAC stats from hw->hw_xstats.mac_stats struct */
620                 for (i = 0; i < HNS3_NUM_MAC_STATS; i++) {
621                         addr = (char *)mac_stats + hns3_mac_strings[i].offset;
622                         xstats[count].value = *(uint64_t *)addr;
623                         xstats[count].id = count;
624                         count++;
625                 }
626
627                 for (i = 0; i < HNS3_NUM_ERROR_INT_XSTATS; i++) {
628                         addr = (char *)&pf->abn_int_stats +
629                                hns3_error_int_stats_strings[i].offset;
630                         xstats[count].value = *(uint64_t *)addr;
631                         xstats[count].id = count;
632                         count++;
633                 }
634         }
635
636         /* Get the reset stat */
637         for (i = 0; i < HNS3_NUM_RESET_XSTATS; i++) {
638                 addr = (char *)reset_stats + hns3_reset_stats_strings[i].offset;
639                 xstats[count].value = *(uint64_t *)addr;
640                 xstats[count].id = count;
641                 count++;
642         }
643
644         /* Get the Rx BD errors stats */
645         for (j = 0; j < dev->data->nb_rx_queues; j++) {
646                 for (i = 0; i < HNS3_NUM_RX_BD_ERROR_XSTATS; i++) {
647                         rxq = dev->data->rx_queues[j];
648                         addr = (char *)rxq + hns3_rx_bd_error_strings[i].offset;
649                         xstats[count].value = *(uint64_t *)addr;
650                         xstats[count].id = count;
651                         count++;
652                 }
653         }
654
655         /* Get rx queue stats */
656         for (j = 0; j < dev->data->nb_rx_queues; j++) {
657                 for (i = 0; i < HNS3_NUM_RX_QUEUE_STATS; i++) {
658                         reg_offset = HNS3_TQP_REG_OFFSET +
659                                         HNS3_TQP_REG_SIZE * j;
660                         xstats[count].value = hns3_read_dev(hw,
661                                 reg_offset + hns3_rx_queue_strings[i].offset);
662                         xstats[count].id = count;
663                         count++;
664                 }
665         }
666
667         /* Get tx queue stats */
668         for (j = 0; j < dev->data->nb_tx_queues; j++) {
669                 for (i = 0; i < HNS3_NUM_TX_QUEUE_STATS; i++) {
670                         reg_offset = HNS3_TQP_REG_OFFSET +
671                                         HNS3_TQP_REG_SIZE * j;
672                         xstats[count].value = hns3_read_dev(hw,
673                                 reg_offset + hns3_tx_queue_strings[i].offset);
674                         xstats[count].id = count;
675                         count++;
676                 }
677         }
678
679         return count;
680 }
681
682 /*
683  * Retrieve names of extended statistics of an Ethernet device.
684  *
685  * There is an assumption that 'xstat_names' and 'xstats' arrays are matched
686  * by array index:
687  *  xstats_names[i].name => xstats[i].value
688  *
689  * And the array index is same with id field of 'struct rte_eth_xstat':
690  *  xstats[i].id == i
691  *
692  * This assumption makes key-value pair matching less flexible but simpler.
693  *
694  * @param dev
695  *   Pointer to Ethernet device.
696  * @param xstats_names
697  *   An rte_eth_xstat_name array of at least *size* elements to
698  *   be filled. If set to NULL, the function returns the required number
699  *   of elements.
700  * @param size
701  *   The size of the xstats_names array (number of elements).
702  * @return
703  *   - A positive value lower or equal to size: success. The return value
704  *     is the number of entries filled in the stats table.
705  */
706 int
707 hns3_dev_xstats_get_names(struct rte_eth_dev *dev,
708                           struct rte_eth_xstat_name *xstats_names,
709                           __rte_unused unsigned int size)
710 {
711         struct hns3_adapter *hns = dev->data->dev_private;
712         int cnt_stats = hns3_xstats_calc_num(dev);
713         uint32_t count = 0;
714         uint16_t i, j;
715
716         if (xstats_names == NULL)
717                 return cnt_stats;
718
719         /* Note: size limited checked in rte_eth_xstats_get_names() */
720         if (!hns->is_vf) {
721                 /* Get MAC name from hw->hw_xstats.mac_stats struct */
722                 for (i = 0; i < HNS3_NUM_MAC_STATS; i++) {
723                         snprintf(xstats_names[count].name,
724                                  sizeof(xstats_names[count].name),
725                                  "%s", hns3_mac_strings[i].name);
726                         count++;
727                 }
728
729                 for (i = 0; i < HNS3_NUM_ERROR_INT_XSTATS; i++) {
730                         snprintf(xstats_names[count].name,
731                                  sizeof(xstats_names[count].name),
732                                  "%s", hns3_error_int_stats_strings[i].name);
733                         count++;
734                 }
735         }
736         for (i = 0; i < HNS3_NUM_RESET_XSTATS; i++) {
737                 snprintf(xstats_names[count].name,
738                          sizeof(xstats_names[count].name),
739                          "%s", hns3_reset_stats_strings[i].name);
740                 count++;
741         }
742
743         for (j = 0; j < dev->data->nb_rx_queues; j++) {
744                 for (i = 0; i < HNS3_NUM_RX_BD_ERROR_XSTATS; i++) {
745                         snprintf(xstats_names[count].name,
746                                  sizeof(xstats_names[count].name),
747                                  "rx_q%u%s", j,
748                                  hns3_rx_bd_error_strings[i].name);
749                         count++;
750                 }
751         }
752
753         for (j = 0; j < dev->data->nb_rx_queues; j++) {
754                 for (i = 0; i < HNS3_NUM_RX_QUEUE_STATS; i++) {
755                         snprintf(xstats_names[count].name,
756                                  sizeof(xstats_names[count].name),
757                                  "rx_q%u%s", j, hns3_rx_queue_strings[i].name);
758                         count++;
759                 }
760         }
761
762         for (j = 0; j < dev->data->nb_tx_queues; j++) {
763                 for (i = 0; i < HNS3_NUM_TX_QUEUE_STATS; i++) {
764                         snprintf(xstats_names[count].name,
765                                  sizeof(xstats_names[count].name),
766                                  "tx_q%u%s", j, hns3_tx_queue_strings[i].name);
767                         count++;
768                 }
769         }
770
771         return count;
772 }
773
774 /*
775  * Retrieve extended statistics of an Ethernet device.
776  *
777  * @param dev
778  *   Pointer to Ethernet device.
779  * @param ids
780  *   A pointer to an ids array passed by application. This tells which
781  *   statistics values function should retrieve. This parameter
782  *   can be set to NULL if size is 0. In this case function will retrieve
783  *   all avalible statistics.
784  * @param values
785  *   A pointer to a table to be filled with device statistics values.
786  * @param size
787  *   The size of the ids array (number of elements).
788  * @return
789  *   - A positive value lower or equal to size: success. The return value
790  *     is the number of entries filled in the stats table.
791  *   - A positive value higher than size: error, the given statistics table
792  *     is too small. The return value corresponds to the size that should
793  *     be given to succeed. The entries in the table are not valid and
794  *     shall not be used by the caller.
795  *   - 0 on no ids.
796  */
797 int
798 hns3_dev_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids,
799                           uint64_t *values, uint32_t size)
800 {
801         const uint32_t cnt_stats = hns3_xstats_calc_num(dev);
802         struct hns3_adapter *hns = dev->data->dev_private;
803         struct rte_eth_xstat *values_copy;
804         struct hns3_hw *hw = &hns->hw;
805         uint32_t count_value;
806         uint64_t len;
807         uint32_t i;
808         int ret;
809
810         if (ids == NULL || size < cnt_stats)
811                 return cnt_stats;
812
813         /* Update tqp stats by read register */
814         ret = hns3_update_tqp_stats(hw);
815         if (ret) {
816                 hns3_err(hw, "Update tqp stats fail : %d", ret);
817                 return ret;
818         }
819
820         len = cnt_stats * sizeof(struct rte_eth_xstat);
821         values_copy = rte_zmalloc("hns3_xstats_values", len, 0);
822         if (values_copy == NULL) {
823                 hns3_err(hw, "Failed to allocate %" PRIx64 " bytes needed "
824                              "to store statistics values", len);
825                 return -ENOMEM;
826         }
827
828         count_value = hns3_dev_xstats_get(dev, values_copy, cnt_stats);
829         if (count_value != cnt_stats) {
830                 rte_free(values_copy);
831                 return -EINVAL;
832         }
833
834         for (i = 0; i < size; i++) {
835                 if (ids[i] >= cnt_stats) {
836                         hns3_err(hw, "ids[%d] (%" PRIx64 ") is invalid, "
837                                      "should < %u", i, ids[i], cnt_stats);
838                         rte_free(values_copy);
839                         return -EINVAL;
840                 }
841                 memcpy(&values[i], &values_copy[ids[i]].value,
842                         sizeof(values[i]));
843         }
844
845         rte_free(values_copy);
846         return size;
847 }
848
849 /*
850  * Retrieve names of extended statistics of an Ethernet device.
851  *
852  * @param dev
853  *   Pointer to Ethernet device.
854  * @param xstats_names
855  *   An rte_eth_xstat_name array of at least *size* elements to
856  *   be filled. If set to NULL, the function returns the required number
857  *   of elements.
858  * @param ids
859  *   IDs array given by app to retrieve specific statistics
860  * @param size
861  *   The size of the xstats_names array (number of elements).
862  * @return
863  *   - A positive value lower or equal to size: success. The return value
864  *     is the number of entries filled in the stats table.
865  *   - A positive value higher than size: error, the given statistics table
866  *     is too small. The return value corresponds to the size that should
867  *     be given to succeed. The entries in the table are not valid and
868  *     shall not be used by the caller.
869  */
870 int
871 hns3_dev_xstats_get_names_by_id(struct rte_eth_dev *dev,
872                                 struct rte_eth_xstat_name *xstats_names,
873                                 const uint64_t *ids, uint32_t size)
874 {
875         const uint32_t cnt_stats = hns3_xstats_calc_num(dev);
876         struct hns3_adapter *hns = dev->data->dev_private;
877         struct rte_eth_xstat_name *names_copy;
878         struct hns3_hw *hw = &hns->hw;
879         uint64_t len;
880         uint32_t i;
881
882         if (ids == NULL || xstats_names == NULL)
883                 return cnt_stats;
884
885         len = cnt_stats * sizeof(struct rte_eth_xstat_name);
886         names_copy = rte_zmalloc("hns3_xstats_names", len, 0);
887         if (names_copy == NULL) {
888                 hns3_err(hw, "Failed to allocate %" PRIx64 " bytes needed "
889                              "to store statistics names", len);
890                 return -ENOMEM;
891         }
892
893         (void)hns3_dev_xstats_get_names(dev, names_copy, cnt_stats);
894
895         for (i = 0; i < size; i++) {
896                 if (ids[i] >= cnt_stats) {
897                         hns3_err(hw, "ids[%d] (%" PRIx64 ") is invalid, "
898                                      "should < %u", i, ids[i], cnt_stats);
899                         rte_free(names_copy);
900                         return -EINVAL;
901                 }
902                 snprintf(xstats_names[i].name, sizeof(xstats_names[i].name),
903                          "%s", names_copy[ids[i]].name);
904         }
905
906         rte_free(names_copy);
907         return size;
908 }
909
910 int
911 hns3_dev_xstats_reset(struct rte_eth_dev *dev)
912 {
913         struct hns3_adapter *hns = dev->data->dev_private;
914         struct hns3_pf *pf = &hns->pf;
915
916         /* Clear tqp stats */
917         (void)hns3_stats_reset(dev);
918         /* Clear reset stats */
919         memset(&hns->hw.reset.stats, 0, sizeof(struct hns3_reset_stats));
920
921         if (hns->is_vf)
922                 return 0;
923
924         /* HW registers are cleared on read */
925         hns3_mac_stats_reset(dev);
926         /* Clear error stats */
927         memset(&pf->abn_int_stats, 0, sizeof(struct hns3_err_msix_intr_stats));
928
929         return 0;
930 }