7cda36c7960122086acbccd2806d53984c788992
[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 <rte_ethdev.h>
6 #include <rte_io.h>
7 #include <rte_malloc.h>
8
9 #include "hns3_ethdev.h"
10 #include "hns3_rxtx.h"
11 #include "hns3_logs.h"
12 #include "hns3_regs.h"
13
14 /* The statistics of the per-rxq basic stats */
15 static const struct hns3_xstats_name_offset hns3_rxq_basic_stats_strings[] = {
16         {"packets",
17                 HNS3_RXQ_BASIC_STATS_FIELD_OFFSET(packets)},
18         {"bytes",
19                 HNS3_RXQ_BASIC_STATS_FIELD_OFFSET(bytes)},
20         {"errors",
21                 HNS3_RXQ_BASIC_STATS_FIELD_OFFSET(errors)}
22 };
23
24 /* The statistics of the per-txq basic stats */
25 static const struct hns3_xstats_name_offset hns3_txq_basic_stats_strings[] = {
26         {"packets",
27                 HNS3_TXQ_BASIC_STATS_FIELD_OFFSET(packets)},
28         {"bytes",
29                 HNS3_TXQ_BASIC_STATS_FIELD_OFFSET(bytes)}
30 };
31
32 /* MAC statistics */
33 static const struct hns3_xstats_name_offset hns3_mac_strings[] = {
34         {"mac_tx_mac_pause_num",
35                 HNS3_MAC_STATS_OFFSET(mac_tx_mac_pause_num)},
36         {"mac_rx_mac_pause_num",
37                 HNS3_MAC_STATS_OFFSET(mac_rx_mac_pause_num)},
38         {"mac_tx_control_pkt_num",
39                 HNS3_MAC_STATS_OFFSET(mac_tx_ctrl_pkt_num)},
40         {"mac_rx_control_pkt_num",
41                 HNS3_MAC_STATS_OFFSET(mac_rx_ctrl_pkt_num)},
42         {"mac_tx_pfc_pkt_num",
43                 HNS3_MAC_STATS_OFFSET(mac_tx_pfc_pause_pkt_num)},
44         {"mac_tx_pfc_pri0_pkt_num",
45                 HNS3_MAC_STATS_OFFSET(mac_tx_pfc_pri0_pkt_num)},
46         {"mac_tx_pfc_pri1_pkt_num",
47                 HNS3_MAC_STATS_OFFSET(mac_tx_pfc_pri1_pkt_num)},
48         {"mac_tx_pfc_pri2_pkt_num",
49                 HNS3_MAC_STATS_OFFSET(mac_tx_pfc_pri2_pkt_num)},
50         {"mac_tx_pfc_pri3_pkt_num",
51                 HNS3_MAC_STATS_OFFSET(mac_tx_pfc_pri3_pkt_num)},
52         {"mac_tx_pfc_pri4_pkt_num",
53                 HNS3_MAC_STATS_OFFSET(mac_tx_pfc_pri4_pkt_num)},
54         {"mac_tx_pfc_pri5_pkt_num",
55                 HNS3_MAC_STATS_OFFSET(mac_tx_pfc_pri5_pkt_num)},
56         {"mac_tx_pfc_pri6_pkt_num",
57                 HNS3_MAC_STATS_OFFSET(mac_tx_pfc_pri6_pkt_num)},
58         {"mac_tx_pfc_pri7_pkt_num",
59                 HNS3_MAC_STATS_OFFSET(mac_tx_pfc_pri7_pkt_num)},
60         {"mac_rx_pfc_pkt_num",
61                 HNS3_MAC_STATS_OFFSET(mac_rx_pfc_pause_pkt_num)},
62         {"mac_rx_pfc_pri0_pkt_num",
63                 HNS3_MAC_STATS_OFFSET(mac_rx_pfc_pri0_pkt_num)},
64         {"mac_rx_pfc_pri1_pkt_num",
65                 HNS3_MAC_STATS_OFFSET(mac_rx_pfc_pri1_pkt_num)},
66         {"mac_rx_pfc_pri2_pkt_num",
67                 HNS3_MAC_STATS_OFFSET(mac_rx_pfc_pri2_pkt_num)},
68         {"mac_rx_pfc_pri3_pkt_num",
69                 HNS3_MAC_STATS_OFFSET(mac_rx_pfc_pri3_pkt_num)},
70         {"mac_rx_pfc_pri4_pkt_num",
71                 HNS3_MAC_STATS_OFFSET(mac_rx_pfc_pri4_pkt_num)},
72         {"mac_rx_pfc_pri5_pkt_num",
73                 HNS3_MAC_STATS_OFFSET(mac_rx_pfc_pri5_pkt_num)},
74         {"mac_rx_pfc_pri6_pkt_num",
75                 HNS3_MAC_STATS_OFFSET(mac_rx_pfc_pri6_pkt_num)},
76         {"mac_rx_pfc_pri7_pkt_num",
77                 HNS3_MAC_STATS_OFFSET(mac_rx_pfc_pri7_pkt_num)},
78         {"mac_tx_total_pkt_num",
79                 HNS3_MAC_STATS_OFFSET(mac_tx_total_pkt_num)},
80         {"mac_tx_total_oct_num",
81                 HNS3_MAC_STATS_OFFSET(mac_tx_total_oct_num)},
82         {"mac_tx_good_pkt_num",
83                 HNS3_MAC_STATS_OFFSET(mac_tx_good_pkt_num)},
84         {"mac_tx_bad_pkt_num",
85                 HNS3_MAC_STATS_OFFSET(mac_tx_bad_pkt_num)},
86         {"mac_tx_good_oct_num",
87                 HNS3_MAC_STATS_OFFSET(mac_tx_good_oct_num)},
88         {"mac_tx_bad_oct_num",
89                 HNS3_MAC_STATS_OFFSET(mac_tx_bad_oct_num)},
90         {"mac_tx_uni_pkt_num",
91                 HNS3_MAC_STATS_OFFSET(mac_tx_uni_pkt_num)},
92         {"mac_tx_multi_pkt_num",
93                 HNS3_MAC_STATS_OFFSET(mac_tx_multi_pkt_num)},
94         {"mac_tx_broad_pkt_num",
95                 HNS3_MAC_STATS_OFFSET(mac_tx_broad_pkt_num)},
96         {"mac_tx_undersize_pkt_num",
97                 HNS3_MAC_STATS_OFFSET(mac_tx_undersize_pkt_num)},
98         {"mac_tx_oversize_pkt_num",
99                 HNS3_MAC_STATS_OFFSET(mac_tx_oversize_pkt_num)},
100         {"mac_tx_64_oct_pkt_num",
101                 HNS3_MAC_STATS_OFFSET(mac_tx_64_oct_pkt_num)},
102         {"mac_tx_65_127_oct_pkt_num",
103                 HNS3_MAC_STATS_OFFSET(mac_tx_65_127_oct_pkt_num)},
104         {"mac_tx_128_255_oct_pkt_num",
105                 HNS3_MAC_STATS_OFFSET(mac_tx_128_255_oct_pkt_num)},
106         {"mac_tx_256_511_oct_pkt_num",
107                 HNS3_MAC_STATS_OFFSET(mac_tx_256_511_oct_pkt_num)},
108         {"mac_tx_512_1023_oct_pkt_num",
109                 HNS3_MAC_STATS_OFFSET(mac_tx_512_1023_oct_pkt_num)},
110         {"mac_tx_1024_1518_oct_pkt_num",
111                 HNS3_MAC_STATS_OFFSET(mac_tx_1024_1518_oct_pkt_num)},
112         {"mac_tx_1519_2047_oct_pkt_num",
113                 HNS3_MAC_STATS_OFFSET(mac_tx_1519_2047_oct_pkt_num)},
114         {"mac_tx_2048_4095_oct_pkt_num",
115                 HNS3_MAC_STATS_OFFSET(mac_tx_2048_4095_oct_pkt_num)},
116         {"mac_tx_4096_8191_oct_pkt_num",
117                 HNS3_MAC_STATS_OFFSET(mac_tx_4096_8191_oct_pkt_num)},
118         {"mac_tx_8192_9216_oct_pkt_num",
119                 HNS3_MAC_STATS_OFFSET(mac_tx_8192_9216_oct_pkt_num)},
120         {"mac_tx_9217_12287_oct_pkt_num",
121                 HNS3_MAC_STATS_OFFSET(mac_tx_9217_12287_oct_pkt_num)},
122         {"mac_tx_12288_16383_oct_pkt_num",
123                 HNS3_MAC_STATS_OFFSET(mac_tx_12288_16383_oct_pkt_num)},
124         {"mac_tx_1519_max_good_pkt_num",
125                 HNS3_MAC_STATS_OFFSET(mac_tx_1519_max_good_oct_pkt_num)},
126         {"mac_tx_1519_max_bad_pkt_num",
127                 HNS3_MAC_STATS_OFFSET(mac_tx_1519_max_bad_oct_pkt_num)},
128         {"mac_rx_total_pkt_num",
129                 HNS3_MAC_STATS_OFFSET(mac_rx_total_pkt_num)},
130         {"mac_rx_total_oct_num",
131                 HNS3_MAC_STATS_OFFSET(mac_rx_total_oct_num)},
132         {"mac_rx_good_pkt_num",
133                 HNS3_MAC_STATS_OFFSET(mac_rx_good_pkt_num)},
134         {"mac_rx_bad_pkt_num",
135                 HNS3_MAC_STATS_OFFSET(mac_rx_bad_pkt_num)},
136         {"mac_rx_good_oct_num",
137                 HNS3_MAC_STATS_OFFSET(mac_rx_good_oct_num)},
138         {"mac_rx_bad_oct_num",
139                 HNS3_MAC_STATS_OFFSET(mac_rx_bad_oct_num)},
140         {"mac_rx_uni_pkt_num",
141                 HNS3_MAC_STATS_OFFSET(mac_rx_uni_pkt_num)},
142         {"mac_rx_multi_pkt_num",
143                 HNS3_MAC_STATS_OFFSET(mac_rx_multi_pkt_num)},
144         {"mac_rx_broad_pkt_num",
145                 HNS3_MAC_STATS_OFFSET(mac_rx_broad_pkt_num)},
146         {"mac_rx_undersize_pkt_num",
147                 HNS3_MAC_STATS_OFFSET(mac_rx_undersize_pkt_num)},
148         {"mac_rx_oversize_pkt_num",
149                 HNS3_MAC_STATS_OFFSET(mac_rx_oversize_pkt_num)},
150         {"mac_rx_64_oct_pkt_num",
151                 HNS3_MAC_STATS_OFFSET(mac_rx_64_oct_pkt_num)},
152         {"mac_rx_65_127_oct_pkt_num",
153                 HNS3_MAC_STATS_OFFSET(mac_rx_65_127_oct_pkt_num)},
154         {"mac_rx_128_255_oct_pkt_num",
155                 HNS3_MAC_STATS_OFFSET(mac_rx_128_255_oct_pkt_num)},
156         {"mac_rx_256_511_oct_pkt_num",
157                 HNS3_MAC_STATS_OFFSET(mac_rx_256_511_oct_pkt_num)},
158         {"mac_rx_512_1023_oct_pkt_num",
159                 HNS3_MAC_STATS_OFFSET(mac_rx_512_1023_oct_pkt_num)},
160         {"mac_rx_1024_1518_oct_pkt_num",
161                 HNS3_MAC_STATS_OFFSET(mac_rx_1024_1518_oct_pkt_num)},
162         {"mac_rx_1519_2047_oct_pkt_num",
163                 HNS3_MAC_STATS_OFFSET(mac_rx_1519_2047_oct_pkt_num)},
164         {"mac_rx_2048_4095_oct_pkt_num",
165                 HNS3_MAC_STATS_OFFSET(mac_rx_2048_4095_oct_pkt_num)},
166         {"mac_rx_4096_8191_oct_pkt_num",
167                 HNS3_MAC_STATS_OFFSET(mac_rx_4096_8191_oct_pkt_num)},
168         {"mac_rx_8192_9216_oct_pkt_num",
169                 HNS3_MAC_STATS_OFFSET(mac_rx_8192_9216_oct_pkt_num)},
170         {"mac_rx_9217_12287_oct_pkt_num",
171                 HNS3_MAC_STATS_OFFSET(mac_rx_9217_12287_oct_pkt_num)},
172         {"mac_rx_12288_16383_oct_pkt_num",
173                 HNS3_MAC_STATS_OFFSET(mac_rx_12288_16383_oct_pkt_num)},
174         {"mac_rx_1519_max_good_pkt_num",
175                 HNS3_MAC_STATS_OFFSET(mac_rx_1519_max_good_oct_pkt_num)},
176         {"mac_rx_1519_max_bad_pkt_num",
177                 HNS3_MAC_STATS_OFFSET(mac_rx_1519_max_bad_oct_pkt_num)},
178         {"mac_tx_fragment_pkt_num",
179                 HNS3_MAC_STATS_OFFSET(mac_tx_fragment_pkt_num)},
180         {"mac_tx_undermin_pkt_num",
181                 HNS3_MAC_STATS_OFFSET(mac_tx_undermin_pkt_num)},
182         {"mac_tx_jabber_pkt_num",
183                 HNS3_MAC_STATS_OFFSET(mac_tx_jabber_pkt_num)},
184         {"mac_tx_err_all_pkt_num",
185                 HNS3_MAC_STATS_OFFSET(mac_tx_err_all_pkt_num)},
186         {"mac_tx_from_app_good_pkt_num",
187                 HNS3_MAC_STATS_OFFSET(mac_tx_from_app_good_pkt_num)},
188         {"mac_tx_from_app_bad_pkt_num",
189                 HNS3_MAC_STATS_OFFSET(mac_tx_from_app_bad_pkt_num)},
190         {"mac_rx_fragment_pkt_num",
191                 HNS3_MAC_STATS_OFFSET(mac_rx_fragment_pkt_num)},
192         {"mac_rx_undermin_pkt_num",
193                 HNS3_MAC_STATS_OFFSET(mac_rx_undermin_pkt_num)},
194         {"mac_rx_jabber_pkt_num",
195                 HNS3_MAC_STATS_OFFSET(mac_rx_jabber_pkt_num)},
196         {"mac_rx_fcs_err_pkt_num",
197                 HNS3_MAC_STATS_OFFSET(mac_rx_fcs_err_pkt_num)},
198         {"mac_rx_send_app_good_pkt_num",
199                 HNS3_MAC_STATS_OFFSET(mac_rx_send_app_good_pkt_num)},
200         {"mac_rx_send_app_bad_pkt_num",
201                 HNS3_MAC_STATS_OFFSET(mac_rx_send_app_bad_pkt_num)}
202 };
203
204 /* The statistic of reset */
205 static const struct hns3_xstats_name_offset hns3_reset_stats_strings[] = {
206         {"REQ_RESET_CNT",
207                 HNS3_RESET_STATS_FIELD_OFFSET(request_cnt)},
208         {"GLOBAL_RESET_CNT",
209                 HNS3_RESET_STATS_FIELD_OFFSET(global_cnt)},
210         {"IMP_RESET_CNT",
211                 HNS3_RESET_STATS_FIELD_OFFSET(imp_cnt)},
212         {"RESET_EXEC_CNT",
213                 HNS3_RESET_STATS_FIELD_OFFSET(exec_cnt)},
214         {"RESET_SUCCESS_CNT",
215                 HNS3_RESET_STATS_FIELD_OFFSET(success_cnt)},
216         {"RESET_FAIL_CNT",
217                 HNS3_RESET_STATS_FIELD_OFFSET(fail_cnt)},
218         {"RESET_MERGE_CNT",
219                 HNS3_RESET_STATS_FIELD_OFFSET(merge_cnt)}
220 };
221
222 /* The statistic of errors in Rx BD */
223 static const struct hns3_xstats_name_offset hns3_rx_bd_error_strings[] = {
224         {"PKT_LEN_ERRORS",
225                 HNS3_RX_BD_ERROR_STATS_FIELD_OFFSET(pkt_len_errors)},
226         {"L2_ERRORS",
227                 HNS3_RX_BD_ERROR_STATS_FIELD_OFFSET(l2_errors)}
228 };
229
230 /* The dfx statistic in Rx datapath */
231 static const struct hns3_xstats_name_offset hns3_rxq_dfx_stats_strings[] = {
232         {"L3_CHECKSUM_ERRORS",
233                 HNS3_RXQ_DFX_STATS_FIELD_OFFSET(l3_csum_errors)},
234         {"L4_CHECKSUM_ERRORS",
235                 HNS3_RXQ_DFX_STATS_FIELD_OFFSET(l4_csum_errors)},
236         {"OL3_CHECKSUM_ERRORS",
237                 HNS3_RXQ_DFX_STATS_FIELD_OFFSET(ol3_csum_errors)},
238         {"OL4_CHECKSUM_ERRORS",
239                 HNS3_RXQ_DFX_STATS_FIELD_OFFSET(ol4_csum_errors)}
240 };
241
242 /* The dfx statistic in Tx datapath */
243 static const struct hns3_xstats_name_offset hns3_txq_dfx_stats_strings[] = {
244         {"OVER_LENGTH_PKT_CNT",
245                 HNS3_TXQ_DFX_STATS_FIELD_OFFSET(over_length_pkt_cnt)},
246         {"EXCEED_LIMITED_BD_PKT_CNT",
247                 HNS3_TXQ_DFX_STATS_FIELD_OFFSET(exceed_limit_bd_pkt_cnt)},
248         {"EXCEED_LIMITED_BD_PKT_REASSEMBLE_FAIL_CNT",
249                 HNS3_TXQ_DFX_STATS_FIELD_OFFSET(exceed_limit_bd_reassem_fail)},
250         {"UNSUPPORTED_TUNNEL_PKT_CNT",
251                 HNS3_TXQ_DFX_STATS_FIELD_OFFSET(unsupported_tunnel_pkt_cnt)},
252         {"QUEUE_FULL_CNT",
253                 HNS3_TXQ_DFX_STATS_FIELD_OFFSET(queue_full_cnt)},
254         {"SHORT_PKT_PAD_FAIL_CNT",
255                 HNS3_TXQ_DFX_STATS_FIELD_OFFSET(pkt_padding_fail_cnt)}
256 };
257
258 /* The statistic of rx queue */
259 static const struct hns3_xstats_name_offset hns3_rx_queue_strings[] = {
260         {"RX_QUEUE_FBD", HNS3_RING_RX_FBDNUM_REG}
261 };
262
263 /* The statistic of tx queue */
264 static const struct hns3_xstats_name_offset hns3_tx_queue_strings[] = {
265         {"TX_QUEUE_FBD", HNS3_RING_TX_FBDNUM_REG}
266 };
267
268 /* The statistic of imissed packet */
269 static const struct hns3_xstats_name_offset hns3_imissed_stats_strings[] = {
270         {"RPU_DROP_CNT",
271                 HNS3_IMISSED_STATS_FIELD_OFFSET(rpu_rx_drop_cnt)},
272 };
273
274 #define HNS3_NUM_MAC_STATS (sizeof(hns3_mac_strings) / \
275         sizeof(hns3_mac_strings[0]))
276
277 #define HNS3_NUM_RESET_XSTATS (sizeof(hns3_reset_stats_strings) / \
278         sizeof(hns3_reset_stats_strings[0]))
279
280 #define HNS3_NUM_RX_BD_ERROR_XSTATS (sizeof(hns3_rx_bd_error_strings) / \
281         sizeof(hns3_rx_bd_error_strings[0]))
282
283 #define HNS3_NUM_RXQ_DFX_XSTATS (sizeof(hns3_rxq_dfx_stats_strings) / \
284         sizeof(hns3_rxq_dfx_stats_strings[0]))
285
286 #define HNS3_NUM_TXQ_DFX_XSTATS (sizeof(hns3_txq_dfx_stats_strings) / \
287         sizeof(hns3_txq_dfx_stats_strings[0]))
288
289 #define HNS3_NUM_RX_QUEUE_STATS (sizeof(hns3_rx_queue_strings) / \
290         sizeof(hns3_rx_queue_strings[0]))
291
292 #define HNS3_NUM_TX_QUEUE_STATS (sizeof(hns3_tx_queue_strings) / \
293         sizeof(hns3_tx_queue_strings[0]))
294
295 #define HNS3_NUM_RXQ_BASIC_STATS (sizeof(hns3_rxq_basic_stats_strings) / \
296         sizeof(hns3_rxq_basic_stats_strings[0]))
297
298 #define HNS3_NUM_TXQ_BASIC_STATS (sizeof(hns3_txq_basic_stats_strings) / \
299         sizeof(hns3_txq_basic_stats_strings[0]))
300
301 #define HNS3_NUM_IMISSED_XSTATS (sizeof(hns3_imissed_stats_strings) / \
302         sizeof(hns3_imissed_stats_strings[0]))
303
304 #define HNS3_FIX_NUM_STATS (HNS3_NUM_MAC_STATS + \
305                             HNS3_NUM_RESET_XSTATS + HNS3_NUM_IMISSED_XSTATS)
306
307 static void hns3_tqp_stats_clear(struct hns3_hw *hw);
308
309 /*
310  * Query all the MAC statistics data of Network ICL command ,opcode id: 0x0034.
311  * This command is used before send 'query_mac_stat command', the descriptor
312  * number of 'query_mac_stat command' must match with reg_num in this command.
313  * @praram hw
314  *   Pointer to structure hns3_hw.
315  * @return
316  *   0 on success.
317  */
318 static int
319 hns3_update_mac_stats(struct hns3_hw *hw, const uint32_t desc_num)
320 {
321         uint64_t *data = (uint64_t *)(&hw->mac_stats);
322         struct hns3_cmd_desc *desc;
323         uint64_t *desc_data;
324         uint16_t i, k, n;
325         int ret;
326
327         desc = rte_malloc("hns3_mac_desc",
328                           desc_num * sizeof(struct hns3_cmd_desc), 0);
329         if (desc == NULL) {
330                 hns3_err(hw, "Mac_update_stats alloced desc malloc fail");
331                 return -ENOMEM;
332         }
333
334         hns3_cmd_setup_basic_desc(desc, HNS3_OPC_STATS_MAC_ALL, true);
335         ret = hns3_cmd_send(hw, desc, desc_num);
336         if (ret) {
337                 hns3_err(hw, "Update complete MAC pkt stats fail : %d", ret);
338                 rte_free(desc);
339                 return ret;
340         }
341
342         for (i = 0; i < desc_num; i++) {
343                 /* For special opcode 0034, only the first desc has the head */
344                 if (i == 0) {
345                         desc_data = (uint64_t *)(&desc[i].data[0]);
346                         n = HNS3_RD_FIRST_STATS_NUM;
347                 } else {
348                         desc_data = (uint64_t *)(&desc[i]);
349                         n = HNS3_RD_OTHER_STATS_NUM;
350                 }
351
352                 for (k = 0; k < n; k++) {
353                         *data += rte_le_to_cpu_64(*desc_data);
354                         data++;
355                         desc_data++;
356                 }
357         }
358         rte_free(desc);
359
360         return 0;
361 }
362
363 /*
364  * Query Mac stat reg num command ,opcode id: 0x0033.
365  * This command is used before send 'query_mac_stat command', the descriptor
366  * number of 'query_mac_stat command' must match with reg_num in this command.
367  * @praram rte_stats
368  *   Pointer to structure rte_eth_stats.
369  * @return
370  *   0 on success.
371  */
372 static int
373 hns3_mac_query_reg_num(struct rte_eth_dev *dev, uint32_t *desc_num)
374 {
375         struct hns3_adapter *hns = dev->data->dev_private;
376         struct hns3_hw *hw = &hns->hw;
377         struct hns3_cmd_desc desc;
378         uint32_t *desc_data;
379         uint32_t reg_num;
380         int ret;
381
382         hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_QUERY_MAC_REG_NUM, true);
383         ret = hns3_cmd_send(hw, &desc, 1);
384         if (ret)
385                 return ret;
386
387         /*
388          * The num of MAC statistics registers that are provided by IMP in this
389          * version.
390          */
391         desc_data = (uint32_t *)(&desc.data[0]);
392         reg_num = rte_le_to_cpu_32(*desc_data);
393
394         /*
395          * The descriptor number of 'query_additional_mac_stat command' is
396          * '1 + (reg_num-3)/4 + ((reg_num-3)%4 !=0)';
397          * This value is 83 in this version
398          */
399         *desc_num = 1 + ((reg_num - 3) >> 2) +
400                     (uint32_t)(((reg_num - 3) & 0x3) ? 1 : 0);
401
402         return 0;
403 }
404
405 static int
406 hns3_query_update_mac_stats(struct rte_eth_dev *dev)
407 {
408         struct hns3_adapter *hns = dev->data->dev_private;
409         struct hns3_hw *hw = &hns->hw;
410         uint32_t desc_num;
411         int ret;
412
413         ret = hns3_mac_query_reg_num(dev, &desc_num);
414         if (ret == 0)
415                 ret = hns3_update_mac_stats(hw, desc_num);
416         else
417                 hns3_err(hw, "Query mac reg num fail : %d", ret);
418         return ret;
419 }
420
421 static int
422 hns3_update_rpu_drop_stats(struct hns3_hw *hw)
423 {
424         struct hns3_rx_missed_stats *stats = &hw->imissed_stats;
425         struct hns3_query_rpu_cmd *req;
426         struct hns3_cmd_desc desc;
427         uint64_t cnt;
428         uint32_t tc_num;
429         int ret;
430
431         hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_DFX_RPU_REG_0, true);
432         req = (struct hns3_query_rpu_cmd *)desc.data;
433
434         /*
435          * tc_num is 0, means rpu stats of all TC channels will be
436          * get from firmware
437          */
438         tc_num = 0;
439         req->tc_queue_num = rte_cpu_to_le_32(tc_num);
440         ret = hns3_cmd_send(hw, &desc, 1);
441         if (ret) {
442                 hns3_err(hw, "failed to query RPU stats: %d", ret);
443                 return ret;
444         }
445
446         cnt = rte_le_to_cpu_32(req->rpu_rx_pkt_drop_cnt);
447         stats->rpu_rx_drop_cnt += cnt;
448
449         return 0;
450 }
451
452 int
453 hns3_update_imissed_stats(struct hns3_hw *hw, bool is_clear)
454 {
455         int ret;
456
457         ret = hns3_update_rpu_drop_stats(hw);
458         if (ret)
459                 return ret;
460
461         if (is_clear)
462                 memset(&hw->imissed_stats, 0, sizeof(hw->imissed_stats));
463
464         return 0;
465 }
466
467 /*
468  * Query tqp tx queue statistics ,opcode id: 0x0B03.
469  * Query tqp rx queue statistics ,opcode id: 0x0B13.
470  * Get all statistics of a port.
471  * @param eth_dev
472  *   Pointer to Ethernet device.
473  * @praram rte_stats
474  *   Pointer to structure rte_eth_stats.
475  * @return
476  *   0 on success.
477  */
478 int
479 hns3_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *rte_stats)
480 {
481         struct hns3_adapter *hns = eth_dev->data->dev_private;
482         struct hns3_hw *hw = &hns->hw;
483         struct hns3_rx_missed_stats *imissed_stats = &hw->imissed_stats;
484         struct hns3_tqp_stats *stats = &hw->tqp_stats;
485         struct hns3_rx_queue *rxq;
486         struct hns3_tx_queue *txq;
487         uint64_t cnt;
488         uint16_t i;
489         int ret;
490
491         if (!hns->is_vf) {
492                 /* Update imissed stats */
493                 ret = hns3_update_imissed_stats(hw, false);
494                 if (ret) {
495                         hns3_err(hw, "update imissed stats failed, ret = %d",
496                                  ret);
497                         return ret;
498                 }
499
500                 rte_stats->imissed = imissed_stats->rpu_rx_drop_cnt;
501         }
502
503         /* Reads all the stats of a rxq in a loop to keep them synchronized */
504         for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
505                 rxq = eth_dev->data->rx_queues[i];
506                 if (rxq == NULL)
507                         continue;
508
509                 cnt = hns3_read_dev(rxq, HNS3_RING_RX_PKTNUM_RECORD_REG);
510                 /*
511                  * Read hardware and software in adjacent positions to minumize
512                  * the timing variance.
513                  */
514                 rte_stats->ierrors += rxq->err_stats.l2_errors +
515                                       rxq->err_stats.pkt_len_errors;
516                 stats->rcb_rx_ring_pktnum_rcd += cnt;
517                 stats->rcb_rx_ring_pktnum[i] += cnt;
518                 rte_stats->ibytes += rxq->basic_stats.bytes;
519         }
520
521         /* Reads all the stats of a txq in a loop to keep them synchronized */
522         for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
523                 txq = eth_dev->data->tx_queues[i];
524                 if (txq == NULL)
525                         continue;
526
527                 cnt = hns3_read_dev(txq, HNS3_RING_TX_PKTNUM_RECORD_REG);
528                 stats->rcb_tx_ring_pktnum_rcd += cnt;
529                 stats->rcb_tx_ring_pktnum[i] += cnt;
530                 rte_stats->obytes += txq->basic_stats.bytes;
531         }
532
533         rte_stats->oerrors = 0;
534         /*
535          * If HW statistics are reset by stats_reset, but a lot of residual
536          * packets exist in the hardware queue and these packets are error
537          * packets, flip overflow may occurred. So return 0 in this case.
538          */
539         rte_stats->ipackets =
540                 stats->rcb_rx_ring_pktnum_rcd > rte_stats->ierrors ?
541                 stats->rcb_rx_ring_pktnum_rcd - rte_stats->ierrors : 0;
542         rte_stats->opackets  = stats->rcb_tx_ring_pktnum_rcd -
543                 rte_stats->oerrors;
544         rte_stats->rx_nombuf = eth_dev->data->rx_mbuf_alloc_failed;
545
546         return 0;
547 }
548
549 int
550 hns3_stats_reset(struct rte_eth_dev *eth_dev)
551 {
552         struct hns3_adapter *hns = eth_dev->data->dev_private;
553         struct hns3_hw *hw = &hns->hw;
554         struct hns3_rx_queue *rxq;
555         struct hns3_tx_queue *txq;
556         uint16_t i;
557         int ret;
558
559         if (!hns->is_vf) {
560                 /*
561                  * Note: Reading hardware statistics of imissed registers will
562                  * clear them.
563                  */
564                 ret = hns3_update_imissed_stats(hw, true);
565                 if (ret) {
566                         hns3_err(hw, "clear imissed stats failed, ret = %d",
567                                  ret);
568                         return ret;
569                 }
570         }
571
572         for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
573                 rxq = eth_dev->data->rx_queues[i];
574                 if (rxq == NULL)
575                         continue;
576
577                 rxq->err_stats.pkt_len_errors = 0;
578                 rxq->err_stats.l2_errors = 0;
579         }
580
581         /* Clear all the stats of a rxq in a loop to keep them synchronized */
582         for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
583                 rxq = eth_dev->data->rx_queues[i];
584                 if (rxq == NULL)
585                         continue;
586
587                 memset(&rxq->basic_stats, 0,
588                                 sizeof(struct hns3_rx_basic_stats));
589
590                 /* This register is read-clear */
591                 (void)hns3_read_dev(rxq, HNS3_RING_RX_PKTNUM_RECORD_REG);
592                 rxq->err_stats.pkt_len_errors = 0;
593                 rxq->err_stats.l2_errors = 0;
594         }
595
596         /* Clear all the stats of a txq in a loop to keep them synchronized */
597         for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
598                 txq = eth_dev->data->tx_queues[i];
599                 if (txq == NULL)
600                         continue;
601
602                 memset(&txq->basic_stats, 0,
603                                 sizeof(struct hns3_tx_basic_stats));
604
605                 /* This register is read-clear */
606                 (void)hns3_read_dev(txq, HNS3_RING_TX_PKTNUM_RECORD_REG);
607         }
608
609         hns3_tqp_stats_clear(hw);
610
611         return 0;
612 }
613
614 static int
615 hns3_mac_stats_reset(__rte_unused struct rte_eth_dev *dev)
616 {
617         struct hns3_adapter *hns = dev->data->dev_private;
618         struct hns3_hw *hw = &hns->hw;
619         struct hns3_mac_stats *mac_stats = &hw->mac_stats;
620         int ret;
621
622         ret = hns3_query_update_mac_stats(dev);
623         if (ret) {
624                 hns3_err(hw, "Clear Mac stats fail : %d", ret);
625                 return ret;
626         }
627
628         memset(mac_stats, 0, sizeof(struct hns3_mac_stats));
629
630         return 0;
631 }
632
633 /* This function calculates the number of xstats based on the current config */
634 static int
635 hns3_xstats_calc_num(struct rte_eth_dev *dev)
636 {
637 #define HNS3_PF_VF_RX_COMM_STATS_NUM    (HNS3_NUM_RX_BD_ERROR_XSTATS + \
638                                          HNS3_NUM_RXQ_DFX_XSTATS + \
639                                          HNS3_NUM_RX_QUEUE_STATS + \
640                                          HNS3_NUM_RXQ_BASIC_STATS)
641 #define HNS3_PF_VF_TX_COMM_STATS_NUM    (HNS3_NUM_TXQ_DFX_XSTATS + \
642                                          HNS3_NUM_TX_QUEUE_STATS + \
643                                          HNS3_NUM_TXQ_BASIC_STATS)
644
645         struct hns3_adapter *hns = dev->data->dev_private;
646         uint16_t nb_rx_q = dev->data->nb_rx_queues;
647         uint16_t nb_tx_q = dev->data->nb_tx_queues;
648         int rx_comm_stats_num = nb_rx_q * HNS3_PF_VF_RX_COMM_STATS_NUM;
649         int tx_comm_stats_num = nb_tx_q * HNS3_PF_VF_TX_COMM_STATS_NUM;
650
651         if (hns->is_vf)
652                 return rx_comm_stats_num + tx_comm_stats_num +
653                         HNS3_NUM_RESET_XSTATS;
654         else
655                 return rx_comm_stats_num + tx_comm_stats_num +
656                         HNS3_FIX_NUM_STATS;
657 }
658
659 static void
660 hns3_queue_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
661                      int *count)
662 {
663         struct hns3_adapter *hns = dev->data->dev_private;
664         struct hns3_hw *hw = &hns->hw;
665         uint32_t reg_offset;
666         uint16_t i, j;
667
668         /* Get rx queue stats */
669         for (j = 0; j < dev->data->nb_rx_queues; j++) {
670                 for (i = 0; i < HNS3_NUM_RX_QUEUE_STATS; i++) {
671                         reg_offset = hns3_get_tqp_reg_offset(j);
672                         xstats[*count].value = hns3_read_dev(hw,
673                                 reg_offset + hns3_rx_queue_strings[i].offset);
674                         xstats[*count].id = *count;
675                         (*count)++;
676                 }
677         }
678
679         /* Get tx queue stats */
680         for (j = 0; j < dev->data->nb_tx_queues; j++) {
681                 for (i = 0; i < HNS3_NUM_TX_QUEUE_STATS; i++) {
682                         reg_offset = hns3_get_tqp_reg_offset(j);
683                         xstats[*count].value = hns3_read_dev(hw,
684                                 reg_offset + hns3_tx_queue_strings[i].offset);
685                         xstats[*count].id = *count;
686                         (*count)++;
687                 }
688         }
689 }
690
691 static void
692 hns3_rxq_dfx_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
693                        int *count)
694 {
695         struct hns3_rx_dfx_stats *dfx_stats;
696         struct hns3_rx_queue *rxq;
697         uint16_t i, j;
698         char *val;
699
700         for (i = 0; i < dev->data->nb_rx_queues; i++) {
701                 rxq = (struct hns3_rx_queue *)dev->data->rx_queues[i];
702                 if (rxq == NULL)
703                         continue;
704
705                 dfx_stats = &rxq->dfx_stats;
706                 for (j = 0; j < HNS3_NUM_RXQ_DFX_XSTATS; j++) {
707                         val = (char *)dfx_stats +
708                                 hns3_rxq_dfx_stats_strings[j].offset;
709                         xstats[*count].value = *(uint64_t *)val;
710                         xstats[*count].id = *count;
711                         (*count)++;
712                 }
713         }
714 }
715
716 static void
717 hns3_txq_dfx_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
718                        int *count)
719 {
720         struct hns3_tx_dfx_stats *dfx_stats;
721         struct hns3_tx_queue *txq;
722         uint16_t i, j;
723         char *val;
724
725         for (i = 0; i < dev->data->nb_tx_queues; i++) {
726                 txq = (struct hns3_tx_queue *)dev->data->tx_queues[i];
727                 if (txq == NULL)
728                         continue;
729
730                 dfx_stats = &txq->dfx_stats;
731                 for (j = 0; j < HNS3_NUM_TXQ_DFX_XSTATS; j++) {
732                         val = (char *)dfx_stats +
733                                 hns3_txq_dfx_stats_strings[j].offset;
734                         xstats[*count].value = *(uint64_t *)val;
735                         xstats[*count].id = *count;
736                         (*count)++;
737                 }
738         }
739 }
740
741 static void
742 hns3_tqp_dfx_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
743                        int *count)
744 {
745         hns3_rxq_dfx_stats_get(dev, xstats, count);
746         hns3_txq_dfx_stats_get(dev, xstats, count);
747 }
748
749 static void
750 hns3_rxq_basic_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
751                          int *count)
752 {
753         struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
754         struct hns3_tqp_stats *stats = &hw->tqp_stats;
755         struct hns3_rx_basic_stats *rxq_stats;
756         struct hns3_rx_queue *rxq;
757         uint16_t i, j;
758         uint32_t cnt;
759         char *val;
760
761         for (i = 0; i < dev->data->nb_rx_queues; i++) {
762                 rxq = dev->data->rx_queues[i];
763                 if (rxq == NULL)
764                         continue;
765
766                 cnt = hns3_read_dev(rxq, HNS3_RING_RX_PKTNUM_RECORD_REG);
767                 /*
768                  * Read hardware and software in adjacent positions to minimize
769                  * the time difference.
770                  */
771                 rxq_stats = &rxq->basic_stats;
772                 rxq_stats->errors = rxq->err_stats.l2_errors +
773                                         rxq->err_stats.pkt_len_errors;
774                 stats->rcb_rx_ring_pktnum_rcd += cnt;
775                 stats->rcb_rx_ring_pktnum[i] += cnt;
776
777                 /*
778                  * If HW statistics are reset by stats_reset, but a lot of
779                  * residual packets exist in the hardware queue and these
780                  * packets are error packets, flip overflow may occurred.
781                  * So return 0 in this case.
782                  */
783                 rxq_stats->packets =
784                         stats->rcb_rx_ring_pktnum[i] > rxq_stats->errors ?
785                         stats->rcb_rx_ring_pktnum[i] - rxq_stats->errors : 0;
786                 for (j = 0; j < HNS3_NUM_RXQ_BASIC_STATS; j++) {
787                         val = (char *)rxq_stats +
788                                 hns3_rxq_basic_stats_strings[j].offset;
789                         xstats[*count].value = *(uint64_t *)val;
790                         xstats[*count].id = *count;
791                         (*count)++;
792                 }
793         }
794 }
795
796 static void
797 hns3_txq_basic_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
798                          int *count)
799 {
800         struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
801         struct hns3_tqp_stats *stats = &hw->tqp_stats;
802         struct hns3_tx_basic_stats *txq_stats;
803         struct hns3_tx_queue *txq;
804         uint16_t i, j;
805         uint32_t cnt;
806         char *val;
807
808         for (i = 0; i < dev->data->nb_tx_queues; i++) {
809                 txq = dev->data->tx_queues[i];
810                 if (txq == NULL)
811                         continue;
812
813                 cnt = hns3_read_dev(txq, HNS3_RING_TX_PKTNUM_RECORD_REG);
814                 stats->rcb_tx_ring_pktnum_rcd += cnt;
815                 stats->rcb_tx_ring_pktnum[i] += cnt;
816
817                 txq_stats = &txq->basic_stats;
818                 txq_stats->packets = stats->rcb_tx_ring_pktnum[i];
819
820                 for (j = 0; j < HNS3_NUM_TXQ_BASIC_STATS; j++) {
821                         val = (char *)txq_stats +
822                                 hns3_txq_basic_stats_strings[j].offset;
823                         xstats[*count].value = *(uint64_t *)val;
824                         xstats[*count].id = *count;
825                         (*count)++;
826                 }
827         }
828 }
829
830 static void
831 hns3_tqp_basic_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
832                          int *count)
833 {
834         hns3_rxq_basic_stats_get(dev, xstats, count);
835         hns3_txq_basic_stats_get(dev, xstats, count);
836 }
837
838 /*
839  * Retrieve extended(tqp | Mac) statistics of an Ethernet device.
840  * @param dev
841  *   Pointer to Ethernet device.
842  * @praram xstats
843  *   A pointer to a table of structure of type *rte_eth_xstat*
844  *   to be filled with device statistics ids and values.
845  *   This parameter can be set to NULL if n is 0.
846  * @param n
847  *   The size of the xstats array (number of elements).
848  * @return
849  *   0 on fail, count(The size of the statistics elements) on success.
850  */
851 int
852 hns3_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
853                     unsigned int n)
854 {
855         struct hns3_adapter *hns = dev->data->dev_private;
856         struct hns3_hw *hw = &hns->hw;
857         struct hns3_rx_missed_stats *imissed_stats = &hw->imissed_stats;
858         struct hns3_mac_stats *mac_stats = &hw->mac_stats;
859         struct hns3_reset_stats *reset_stats = &hw->reset.stats;
860         struct hns3_rx_bd_errors_stats *rx_err_stats;
861         struct hns3_rx_queue *rxq;
862         uint16_t i, j;
863         char *addr;
864         int count;
865         int ret;
866
867         if (xstats == NULL)
868                 return 0;
869
870         count = hns3_xstats_calc_num(dev);
871         if ((int)n < count)
872                 return count;
873
874         count = 0;
875
876         hns3_tqp_basic_stats_get(dev, xstats, &count);
877
878         if (!hns->is_vf) {
879                 /* Update Mac stats */
880                 ret = hns3_query_update_mac_stats(dev);
881                 if (ret < 0) {
882                         hns3_err(hw, "Update Mac stats fail : %d", ret);
883                         return ret;
884                 }
885
886                 /* Get MAC stats from hw->hw_xstats.mac_stats struct */
887                 for (i = 0; i < HNS3_NUM_MAC_STATS; i++) {
888                         addr = (char *)mac_stats + hns3_mac_strings[i].offset;
889                         xstats[count].value = *(uint64_t *)addr;
890                         xstats[count].id = count;
891                         count++;
892                 }
893
894                 ret = hns3_update_imissed_stats(hw, false);
895                 if (ret) {
896                         hns3_err(hw, "update imissed stats failed, ret = %d",
897                                  ret);
898                         return ret;
899                 }
900
901                 for (i = 0; i < HNS3_NUM_IMISSED_XSTATS; i++) {
902                         addr = (char *)imissed_stats +
903                                 hns3_imissed_stats_strings[i].offset;
904                         xstats[count].value = *(uint64_t *)addr;
905                         xstats[count].id = count;
906                         count++;
907                 }
908
909         }
910
911         /* Get the reset stat */
912         for (i = 0; i < HNS3_NUM_RESET_XSTATS; i++) {
913                 addr = (char *)reset_stats + hns3_reset_stats_strings[i].offset;
914                 xstats[count].value = *(uint64_t *)addr;
915                 xstats[count].id = count;
916                 count++;
917         }
918
919         /* Get the Rx BD errors stats */
920         for (j = 0; j < dev->data->nb_rx_queues; j++) {
921                 for (i = 0; i < HNS3_NUM_RX_BD_ERROR_XSTATS; i++) {
922                         rxq = dev->data->rx_queues[j];
923                         if (rxq) {
924                                 rx_err_stats = &rxq->err_stats;
925                                 addr = (char *)rx_err_stats +
926                                         hns3_rx_bd_error_strings[i].offset;
927                                 xstats[count].value = *(uint64_t *)addr;
928                                 xstats[count].id = count;
929                                 count++;
930                         }
931                 }
932         }
933
934         hns3_tqp_dfx_stats_get(dev, xstats, &count);
935         hns3_queue_stats_get(dev, xstats, &count);
936
937         return count;
938 }
939
940 static void
941 hns3_tqp_basic_stats_name_get(struct rte_eth_dev *dev,
942                               struct rte_eth_xstat_name *xstats_names,
943                               uint32_t *count)
944 {
945         uint16_t i, j;
946
947         for (i = 0; i < dev->data->nb_rx_queues; i++) {
948                 for (j = 0; j < HNS3_NUM_RXQ_BASIC_STATS; j++) {
949                         snprintf(xstats_names[*count].name,
950                                  sizeof(xstats_names[*count].name),
951                                  "rx_q%u_%s", i,
952                                  hns3_rxq_basic_stats_strings[j].name);
953                         (*count)++;
954                 }
955         }
956         for (i = 0; i < dev->data->nb_tx_queues; i++) {
957                 for (j = 0; j < HNS3_NUM_TXQ_BASIC_STATS; j++) {
958                         snprintf(xstats_names[*count].name,
959                                  sizeof(xstats_names[*count].name),
960                                  "tx_q%u_%s", i,
961                                  hns3_txq_basic_stats_strings[j].name);
962                         (*count)++;
963                 }
964         }
965 }
966
967 static void
968 hns3_tqp_dfx_stats_name_get(struct rte_eth_dev *dev,
969                             struct rte_eth_xstat_name *xstats_names,
970                             uint32_t *count)
971 {
972         uint16_t i, j;
973
974         for (i = 0; i < dev->data->nb_rx_queues; i++) {
975                 for (j = 0; j < HNS3_NUM_RXQ_DFX_XSTATS; j++) {
976                         snprintf(xstats_names[*count].name,
977                                  sizeof(xstats_names[*count].name),
978                                  "rx_q%u_%s", i,
979                                  hns3_rxq_dfx_stats_strings[j].name);
980                         (*count)++;
981                 }
982         }
983
984         for (i = 0; i < dev->data->nb_tx_queues; i++) {
985                 for (j = 0; j < HNS3_NUM_TXQ_DFX_XSTATS; j++) {
986                         snprintf(xstats_names[*count].name,
987                                  sizeof(xstats_names[*count].name),
988                                  "tx_q%u_%s", i,
989                                  hns3_txq_dfx_stats_strings[j].name);
990                         (*count)++;
991                 }
992         }
993 }
994
995 /*
996  * Retrieve names of extended statistics of an Ethernet device.
997  *
998  * There is an assumption that 'xstat_names' and 'xstats' arrays are matched
999  * by array index:
1000  *  xstats_names[i].name => xstats[i].value
1001  *
1002  * And the array index is same with id field of 'struct rte_eth_xstat':
1003  *  xstats[i].id == i
1004  *
1005  * This assumption makes key-value pair matching less flexible but simpler.
1006  *
1007  * @param dev
1008  *   Pointer to Ethernet device.
1009  * @param xstats_names
1010  *   An rte_eth_xstat_name array of at least *size* elements to
1011  *   be filled. If set to NULL, the function returns the required number
1012  *   of elements.
1013  * @param size
1014  *   The size of the xstats_names array (number of elements).
1015  * @return
1016  *   - A positive value lower or equal to size: success. The return value
1017  *     is the number of entries filled in the stats table.
1018  */
1019 int
1020 hns3_dev_xstats_get_names(struct rte_eth_dev *dev,
1021                           struct rte_eth_xstat_name *xstats_names,
1022                           __rte_unused unsigned int size)
1023 {
1024         struct hns3_adapter *hns = dev->data->dev_private;
1025         int cnt_stats = hns3_xstats_calc_num(dev);
1026         uint32_t count = 0;
1027         uint16_t i, j;
1028
1029         if (xstats_names == NULL)
1030                 return cnt_stats;
1031
1032         hns3_tqp_basic_stats_name_get(dev, xstats_names, &count);
1033
1034         /* Note: size limited checked in rte_eth_xstats_get_names() */
1035         if (!hns->is_vf) {
1036                 /* Get MAC name from hw->hw_xstats.mac_stats struct */
1037                 for (i = 0; i < HNS3_NUM_MAC_STATS; i++) {
1038                         snprintf(xstats_names[count].name,
1039                                  sizeof(xstats_names[count].name),
1040                                  "%s", hns3_mac_strings[i].name);
1041                         count++;
1042                 }
1043
1044                 for (i = 0; i < HNS3_NUM_IMISSED_XSTATS; i++) {
1045                         snprintf(xstats_names[count].name,
1046                                  sizeof(xstats_names[count].name),
1047                                  "%s", hns3_imissed_stats_strings[i].name);
1048                         count++;
1049                 }
1050         }
1051         for (i = 0; i < HNS3_NUM_RESET_XSTATS; i++) {
1052                 snprintf(xstats_names[count].name,
1053                          sizeof(xstats_names[count].name),
1054                          "%s", hns3_reset_stats_strings[i].name);
1055                 count++;
1056         }
1057
1058         for (j = 0; j < dev->data->nb_rx_queues; j++) {
1059                 for (i = 0; i < HNS3_NUM_RX_BD_ERROR_XSTATS; i++) {
1060                         snprintf(xstats_names[count].name,
1061                                  sizeof(xstats_names[count].name),
1062                                  "rx_q%u_%s", j,
1063                                  hns3_rx_bd_error_strings[i].name);
1064                         count++;
1065                 }
1066         }
1067
1068         hns3_tqp_dfx_stats_name_get(dev, xstats_names, &count);
1069
1070         for (j = 0; j < dev->data->nb_rx_queues; j++) {
1071                 for (i = 0; i < HNS3_NUM_RX_QUEUE_STATS; i++) {
1072                         snprintf(xstats_names[count].name,
1073                                  sizeof(xstats_names[count].name),
1074                                  "rx_q%u_%s", j, hns3_rx_queue_strings[i].name);
1075                         count++;
1076                 }
1077         }
1078
1079         for (j = 0; j < dev->data->nb_tx_queues; j++) {
1080                 for (i = 0; i < HNS3_NUM_TX_QUEUE_STATS; i++) {
1081                         snprintf(xstats_names[count].name,
1082                                  sizeof(xstats_names[count].name),
1083                                  "tx_q%u_%s", j, hns3_tx_queue_strings[i].name);
1084                         count++;
1085                 }
1086         }
1087
1088         return count;
1089 }
1090
1091 /*
1092  * Retrieve extended statistics of an Ethernet device.
1093  *
1094  * @param dev
1095  *   Pointer to Ethernet device.
1096  * @param ids
1097  *   A pointer to an ids array passed by application. This tells which
1098  *   statistics values function should retrieve. This parameter
1099  *   can be set to NULL if size is 0. In this case function will retrieve
1100  *   all avalible statistics.
1101  * @param values
1102  *   A pointer to a table to be filled with device statistics values.
1103  * @param size
1104  *   The size of the ids array (number of elements).
1105  * @return
1106  *   - A positive value lower or equal to size: success. The return value
1107  *     is the number of entries filled in the stats table.
1108  *   - A positive value higher than size: error, the given statistics table
1109  *     is too small. The return value corresponds to the size that should
1110  *     be given to succeed. The entries in the table are not valid and
1111  *     shall not be used by the caller.
1112  *   - 0 on no ids.
1113  */
1114 int
1115 hns3_dev_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids,
1116                           uint64_t *values, uint32_t size)
1117 {
1118         const uint32_t cnt_stats = hns3_xstats_calc_num(dev);
1119         struct hns3_adapter *hns = dev->data->dev_private;
1120         struct rte_eth_xstat *values_copy;
1121         struct hns3_hw *hw = &hns->hw;
1122         uint32_t count_value;
1123         uint64_t len;
1124         uint32_t i;
1125
1126         if (ids == NULL && values == NULL)
1127                 return cnt_stats;
1128
1129         if (ids == NULL)
1130                 if (size < cnt_stats)
1131                         return cnt_stats;
1132
1133         len = cnt_stats * sizeof(struct rte_eth_xstat);
1134         values_copy = rte_zmalloc("hns3_xstats_values", len, 0);
1135         if (values_copy == NULL) {
1136                 hns3_err(hw, "Failed to allocate %" PRIx64 " bytes needed "
1137                              "to store statistics values", len);
1138                 return -ENOMEM;
1139         }
1140
1141         count_value = hns3_dev_xstats_get(dev, values_copy, cnt_stats);
1142         if (count_value != cnt_stats) {
1143                 rte_free(values_copy);
1144                 return -EINVAL;
1145         }
1146
1147         if (ids == NULL && values != NULL) {
1148                 for (i = 0; i < cnt_stats; i++)
1149                         memcpy(&values[i], &values_copy[i].value,
1150                                sizeof(values[i]));
1151
1152                 rte_free(values_copy);
1153                 return cnt_stats;
1154         }
1155
1156         for (i = 0; i < size; i++) {
1157                 if (ids[i] >= cnt_stats) {
1158                         hns3_err(hw, "ids[%u] (%" PRIx64 ") is invalid, "
1159                                      "should < %u", i, ids[i], cnt_stats);
1160                         rte_free(values_copy);
1161                         return -EINVAL;
1162                 }
1163                 memcpy(&values[i], &values_copy[ids[i]].value,
1164                         sizeof(values[i]));
1165         }
1166
1167         rte_free(values_copy);
1168         return size;
1169 }
1170
1171 /*
1172  * Retrieve names of extended statistics of an Ethernet device.
1173  *
1174  * @param dev
1175  *   Pointer to Ethernet device.
1176  * @param xstats_names
1177  *   An rte_eth_xstat_name array of at least *size* elements to
1178  *   be filled. If set to NULL, the function returns the required number
1179  *   of elements.
1180  * @param ids
1181  *   IDs array given by app to retrieve specific statistics
1182  * @param size
1183  *   The size of the xstats_names array (number of elements).
1184  * @return
1185  *   - A positive value lower or equal to size: success. The return value
1186  *     is the number of entries filled in the stats table.
1187  *   - A positive value higher than size: error, the given statistics table
1188  *     is too small. The return value corresponds to the size that should
1189  *     be given to succeed. The entries in the table are not valid and
1190  *     shall not be used by the caller.
1191  */
1192 int
1193 hns3_dev_xstats_get_names_by_id(struct rte_eth_dev *dev,
1194                                 struct rte_eth_xstat_name *xstats_names,
1195                                 const uint64_t *ids, uint32_t size)
1196 {
1197         const uint32_t cnt_stats = hns3_xstats_calc_num(dev);
1198         struct hns3_adapter *hns = dev->data->dev_private;
1199         struct rte_eth_xstat_name *names_copy;
1200         struct hns3_hw *hw = &hns->hw;
1201         uint64_t len;
1202         uint32_t i;
1203
1204         if (xstats_names == NULL)
1205                 return cnt_stats;
1206
1207         if (ids == NULL) {
1208                 if (size < cnt_stats)
1209                         return cnt_stats;
1210
1211                 return hns3_dev_xstats_get_names(dev, xstats_names, cnt_stats);
1212         }
1213
1214         len = cnt_stats * sizeof(struct rte_eth_xstat_name);
1215         names_copy = rte_zmalloc("hns3_xstats_names", len, 0);
1216         if (names_copy == NULL) {
1217                 hns3_err(hw, "Failed to allocate %" PRIx64 " bytes needed "
1218                              "to store statistics names", len);
1219                 return -ENOMEM;
1220         }
1221
1222         (void)hns3_dev_xstats_get_names(dev, names_copy, cnt_stats);
1223
1224         for (i = 0; i < size; i++) {
1225                 if (ids[i] >= cnt_stats) {
1226                         hns3_err(hw, "ids[%u] (%" PRIx64 ") is invalid, "
1227                                      "should < %u", i, ids[i], cnt_stats);
1228                         rte_free(names_copy);
1229                         return -EINVAL;
1230                 }
1231                 snprintf(xstats_names[i].name, sizeof(xstats_names[i].name),
1232                          "%s", names_copy[ids[i]].name);
1233         }
1234
1235         rte_free(names_copy);
1236         return size;
1237 }
1238
1239 static void
1240 hns3_tqp_dfx_stats_clear(struct rte_eth_dev *dev)
1241 {
1242         struct hns3_rx_queue *rxq;
1243         struct hns3_tx_queue *txq;
1244         uint16_t i;
1245
1246         /* Clear Rx dfx stats */
1247         for (i = 0; i < dev->data->nb_rx_queues; i++) {
1248                 rxq = dev->data->rx_queues[i];
1249                 if (rxq)
1250                         memset(&rxq->dfx_stats, 0,
1251                                sizeof(struct hns3_rx_dfx_stats));
1252         }
1253
1254         /* Clear Tx dfx stats */
1255         for (i = 0; i < dev->data->nb_tx_queues; i++) {
1256                 txq = dev->data->tx_queues[i];
1257                 if (txq)
1258                         memset(&txq->dfx_stats, 0,
1259                                sizeof(struct hns3_tx_dfx_stats));
1260         }
1261 }
1262
1263 int
1264 hns3_dev_xstats_reset(struct rte_eth_dev *dev)
1265 {
1266         struct hns3_adapter *hns = dev->data->dev_private;
1267         int ret;
1268
1269         /* Clear tqp stats */
1270         ret = hns3_stats_reset(dev);
1271         if (ret)
1272                 return ret;
1273
1274         hns3_tqp_dfx_stats_clear(dev);
1275
1276         /* Clear reset stats */
1277         memset(&hns->hw.reset.stats, 0, sizeof(struct hns3_reset_stats));
1278
1279         if (hns->is_vf)
1280                 return 0;
1281
1282         /* HW registers are cleared on read */
1283         ret = hns3_mac_stats_reset(dev);
1284         if (ret)
1285                 return ret;
1286
1287         return 0;
1288 }
1289
1290 int
1291 hns3_tqp_stats_init(struct hns3_hw *hw)
1292 {
1293         struct hns3_tqp_stats *tqp_stats = &hw->tqp_stats;
1294
1295         tqp_stats->rcb_rx_ring_pktnum = rte_zmalloc("hns3_rx_ring_pkt_num",
1296                                          sizeof(uint64_t) * hw->tqps_num, 0);
1297         if (tqp_stats->rcb_rx_ring_pktnum == NULL) {
1298                 hns3_err(hw, "failed to allocate rx_ring pkt_num.");
1299                 return -ENOMEM;
1300         }
1301
1302         tqp_stats->rcb_tx_ring_pktnum = rte_zmalloc("hns3_tx_ring_pkt_num",
1303                                          sizeof(uint64_t) * hw->tqps_num, 0);
1304         if (tqp_stats->rcb_tx_ring_pktnum == NULL) {
1305                 hns3_err(hw, "failed to allocate tx_ring pkt_num.");
1306                 rte_free(tqp_stats->rcb_rx_ring_pktnum);
1307                 tqp_stats->rcb_rx_ring_pktnum = NULL;
1308                 return -ENOMEM;
1309         }
1310
1311         return 0;
1312 }
1313
1314 void
1315 hns3_tqp_stats_uninit(struct hns3_hw *hw)
1316 {
1317         struct hns3_tqp_stats *tqp_stats = &hw->tqp_stats;
1318
1319         rte_free(tqp_stats->rcb_rx_ring_pktnum);
1320         tqp_stats->rcb_rx_ring_pktnum = NULL;
1321         rte_free(tqp_stats->rcb_tx_ring_pktnum);
1322         tqp_stats->rcb_tx_ring_pktnum = NULL;
1323 }
1324
1325 static void
1326 hns3_tqp_stats_clear(struct hns3_hw *hw)
1327 {
1328         struct hns3_tqp_stats *stats = &hw->tqp_stats;
1329
1330         stats->rcb_rx_ring_pktnum_rcd = 0;
1331         stats->rcb_tx_ring_pktnum_rcd = 0;
1332         memset(stats->rcb_rx_ring_pktnum, 0, sizeof(uint64_t) * hw->tqps_num);
1333         memset(stats->rcb_tx_ring_pktnum, 0, sizeof(uint64_t) * hw->tqps_num);
1334 }