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