e802c0b1a2fe18a683539c79480c9b2938bfa7f8
[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         {"SSU_DROP_CNT",
273                 HNS3_IMISSED_STATS_FIELD_OFFSET(ssu_rx_drop_cnt)},
274 };
275
276 #define HNS3_NUM_MAC_STATS (sizeof(hns3_mac_strings) / \
277         sizeof(hns3_mac_strings[0]))
278
279 #define HNS3_NUM_RESET_XSTATS (sizeof(hns3_reset_stats_strings) / \
280         sizeof(hns3_reset_stats_strings[0]))
281
282 #define HNS3_NUM_RX_BD_ERROR_XSTATS (sizeof(hns3_rx_bd_error_strings) / \
283         sizeof(hns3_rx_bd_error_strings[0]))
284
285 #define HNS3_NUM_RXQ_DFX_XSTATS (sizeof(hns3_rxq_dfx_stats_strings) / \
286         sizeof(hns3_rxq_dfx_stats_strings[0]))
287
288 #define HNS3_NUM_TXQ_DFX_XSTATS (sizeof(hns3_txq_dfx_stats_strings) / \
289         sizeof(hns3_txq_dfx_stats_strings[0]))
290
291 #define HNS3_NUM_RX_QUEUE_STATS (sizeof(hns3_rx_queue_strings) / \
292         sizeof(hns3_rx_queue_strings[0]))
293
294 #define HNS3_NUM_TX_QUEUE_STATS (sizeof(hns3_tx_queue_strings) / \
295         sizeof(hns3_tx_queue_strings[0]))
296
297 #define HNS3_NUM_RXQ_BASIC_STATS (sizeof(hns3_rxq_basic_stats_strings) / \
298         sizeof(hns3_rxq_basic_stats_strings[0]))
299
300 #define HNS3_NUM_TXQ_BASIC_STATS (sizeof(hns3_txq_basic_stats_strings) / \
301         sizeof(hns3_txq_basic_stats_strings[0]))
302
303 #define HNS3_NUM_IMISSED_XSTATS (sizeof(hns3_imissed_stats_strings) / \
304         sizeof(hns3_imissed_stats_strings[0]))
305
306 #define HNS3_FIX_NUM_STATS (HNS3_NUM_MAC_STATS + HNS3_NUM_RESET_XSTATS)
307
308 static void hns3_tqp_stats_clear(struct hns3_hw *hw);
309
310 /*
311  * Query all the MAC statistics data of Network ICL command ,opcode id: 0x0034.
312  * This command is used before send 'query_mac_stat command', the descriptor
313  * number of 'query_mac_stat command' must match with reg_num in this command.
314  * @praram hw
315  *   Pointer to structure hns3_hw.
316  * @return
317  *   0 on success.
318  */
319 static int
320 hns3_update_mac_stats(struct hns3_hw *hw, const uint32_t desc_num)
321 {
322         uint64_t *data = (uint64_t *)(&hw->mac_stats);
323         struct hns3_cmd_desc *desc;
324         uint64_t *desc_data;
325         uint16_t i, k, n;
326         int ret;
327
328         desc = rte_malloc("hns3_mac_desc",
329                           desc_num * sizeof(struct hns3_cmd_desc), 0);
330         if (desc == NULL) {
331                 hns3_err(hw, "Mac_update_stats alloced desc malloc fail");
332                 return -ENOMEM;
333         }
334
335         hns3_cmd_setup_basic_desc(desc, HNS3_OPC_STATS_MAC_ALL, true);
336         ret = hns3_cmd_send(hw, desc, desc_num);
337         if (ret) {
338                 hns3_err(hw, "Update complete MAC pkt stats fail : %d", ret);
339                 rte_free(desc);
340                 return ret;
341         }
342
343         for (i = 0; i < desc_num; i++) {
344                 /* For special opcode 0034, only the first desc has the head */
345                 if (i == 0) {
346                         desc_data = (uint64_t *)(&desc[i].data[0]);
347                         n = HNS3_RD_FIRST_STATS_NUM;
348                 } else {
349                         desc_data = (uint64_t *)(&desc[i]);
350                         n = HNS3_RD_OTHER_STATS_NUM;
351                 }
352
353                 for (k = 0; k < n; k++) {
354                         *data += rte_le_to_cpu_64(*desc_data);
355                         data++;
356                         desc_data++;
357                 }
358         }
359         rte_free(desc);
360
361         return 0;
362 }
363
364 /*
365  * Query Mac stat reg num command ,opcode id: 0x0033.
366  * This command is used before send 'query_mac_stat command', the descriptor
367  * number of 'query_mac_stat command' must match with reg_num in this command.
368  * @praram rte_stats
369  *   Pointer to structure rte_eth_stats.
370  * @return
371  *   0 on success.
372  */
373 static int
374 hns3_mac_query_reg_num(struct rte_eth_dev *dev, uint32_t *desc_num)
375 {
376         struct hns3_adapter *hns = dev->data->dev_private;
377         struct hns3_hw *hw = &hns->hw;
378         struct hns3_cmd_desc desc;
379         uint32_t *desc_data;
380         uint32_t reg_num;
381         int ret;
382
383         hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_QUERY_MAC_REG_NUM, true);
384         ret = hns3_cmd_send(hw, &desc, 1);
385         if (ret)
386                 return ret;
387
388         /*
389          * The num of MAC statistics registers that are provided by IMP in this
390          * version.
391          */
392         desc_data = (uint32_t *)(&desc.data[0]);
393         reg_num = rte_le_to_cpu_32(*desc_data);
394
395         /*
396          * The descriptor number of 'query_additional_mac_stat command' is
397          * '1 + (reg_num-3)/4 + ((reg_num-3)%4 !=0)';
398          * This value is 83 in this version
399          */
400         *desc_num = 1 + ((reg_num - 3) >> 2) +
401                     (uint32_t)(((reg_num - 3) & 0x3) ? 1 : 0);
402
403         return 0;
404 }
405
406 static int
407 hns3_query_update_mac_stats(struct rte_eth_dev *dev)
408 {
409         struct hns3_adapter *hns = dev->data->dev_private;
410         struct hns3_hw *hw = &hns->hw;
411         uint32_t desc_num;
412         int ret;
413
414         ret = hns3_mac_query_reg_num(dev, &desc_num);
415         if (ret == 0)
416                 ret = hns3_update_mac_stats(hw, desc_num);
417         else
418                 hns3_err(hw, "Query mac reg num fail : %d", ret);
419         return ret;
420 }
421
422 static int
423 hns3_update_port_rpu_drop_stats(struct hns3_hw *hw)
424 {
425         struct hns3_rx_missed_stats *stats = &hw->imissed_stats;
426         struct hns3_query_rpu_cmd *req;
427         struct hns3_cmd_desc desc;
428         uint64_t cnt;
429         uint32_t tc_num;
430         int ret;
431
432         hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_DFX_RPU_REG_0, true);
433         req = (struct hns3_query_rpu_cmd *)desc.data;
434
435         /*
436          * tc_num is 0, means rpu stats of all TC channels will be
437          * get from firmware
438          */
439         tc_num = 0;
440         req->tc_queue_num = rte_cpu_to_le_32(tc_num);
441         ret = hns3_cmd_send(hw, &desc, 1);
442         if (ret) {
443                 hns3_err(hw, "failed to query RPU stats: %d", ret);
444                 return ret;
445         }
446
447         cnt = rte_le_to_cpu_32(req->rpu_rx_pkt_drop_cnt);
448         stats->rpu_rx_drop_cnt += cnt;
449
450         return 0;
451 }
452
453 static void
454 hns3_update_function_rpu_drop_stats(struct hns3_hw *hw)
455 {
456         struct hns3_rx_missed_stats *stats = &hw->imissed_stats;
457
458         stats->rpu_rx_drop_cnt += hns3_read_dev(hw, HNS3_RPU_DROP_CNT_REG);
459 }
460
461 static int
462 hns3_update_rpu_drop_stats(struct hns3_hw *hw)
463 {
464         struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
465         int ret = 0;
466
467         if (hw->drop_stats_mode == HNS3_PKTS_DROP_STATS_MODE1 && !hns->is_vf)
468                 ret = hns3_update_port_rpu_drop_stats(hw);
469         else if (hw->drop_stats_mode == HNS3_PKTS_DROP_STATS_MODE2)
470                 hns3_update_function_rpu_drop_stats(hw);
471
472         return ret;
473 }
474
475 static int
476 hns3_get_ssu_drop_stats(struct hns3_hw *hw, struct hns3_cmd_desc *desc,
477                         int bd_num, bool is_rx)
478 {
479         struct hns3_query_ssu_cmd *req;
480         int ret;
481         int i;
482
483         for (i = 0; i < bd_num - 1; i++) {
484                 hns3_cmd_setup_basic_desc(&desc[i],
485                                           HNS3_OPC_SSU_DROP_REG, true);
486                 desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT);
487         }
488         hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_SSU_DROP_REG, true);
489         req = (struct hns3_query_ssu_cmd *)desc[0].data;
490         req->rxtx = is_rx ? 0 : 1;
491         ret = hns3_cmd_send(hw, desc, bd_num);
492
493         return ret;
494 }
495
496 static int
497 hns3_update_port_rx_ssu_drop_stats(struct hns3_hw *hw)
498 {
499         struct hns3_rx_missed_stats *stats = &hw->imissed_stats;
500         struct hns3_cmd_desc desc[HNS3_OPC_SSU_DROP_REG_NUM];
501         struct hns3_query_ssu_cmd *req;
502         uint64_t cnt;
503         int ret;
504
505         ret = hns3_get_ssu_drop_stats(hw, desc, HNS3_OPC_SSU_DROP_REG_NUM,
506                                       true);
507         if (ret) {
508                 hns3_err(hw, "failed to get Rx SSU drop stats, ret = %d", ret);
509                 return ret;
510         }
511
512         req = (struct hns3_query_ssu_cmd *)desc[0].data;
513         cnt = rte_le_to_cpu_32(req->oq_drop_cnt) +
514                 rte_le_to_cpu_32(req->full_drop_cnt) +
515                 rte_le_to_cpu_32(req->part_drop_cnt);
516
517         stats->ssu_rx_drop_cnt += cnt;
518
519         return 0;
520 }
521
522 int
523 hns3_update_imissed_stats(struct hns3_hw *hw, bool is_clear)
524 {
525         struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
526         int ret;
527
528         if (hw->drop_stats_mode == HNS3_PKTS_DROP_STATS_MODE1 && hns->is_vf)
529                 return 0;
530
531         if (hw->drop_stats_mode == HNS3_PKTS_DROP_STATS_MODE2 && !hns->is_vf) {
532                 ret = hns3_update_port_rx_ssu_drop_stats(hw);
533                 if (ret)
534                         return ret;
535         }
536
537         ret = hns3_update_rpu_drop_stats(hw);
538         if (ret)
539                 return ret;
540
541         if (is_clear)
542                 memset(&hw->imissed_stats, 0, sizeof(hw->imissed_stats));
543
544         return 0;
545 }
546
547 /*
548  * Query tqp tx queue statistics ,opcode id: 0x0B03.
549  * Query tqp rx queue statistics ,opcode id: 0x0B13.
550  * Get all statistics of a port.
551  * @param eth_dev
552  *   Pointer to Ethernet device.
553  * @praram rte_stats
554  *   Pointer to structure rte_eth_stats.
555  * @return
556  *   0 on success.
557  */
558 int
559 hns3_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *rte_stats)
560 {
561         struct hns3_adapter *hns = eth_dev->data->dev_private;
562         struct hns3_hw *hw = &hns->hw;
563         struct hns3_rx_missed_stats *imissed_stats = &hw->imissed_stats;
564         struct hns3_tqp_stats *stats = &hw->tqp_stats;
565         struct hns3_rx_queue *rxq;
566         struct hns3_tx_queue *txq;
567         uint64_t cnt;
568         uint16_t i;
569         int ret;
570
571         /* Update imissed stats */
572         ret = hns3_update_imissed_stats(hw, false);
573         if (ret) {
574                 hns3_err(hw, "update imissed stats failed, ret = %d",
575                          ret);
576                 return ret;
577         }
578         rte_stats->imissed = imissed_stats->rpu_rx_drop_cnt +
579                                 imissed_stats->ssu_rx_drop_cnt;
580
581         /* Get the error stats and bytes of received packets */
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                 cnt = hns3_read_dev(rxq, HNS3_RING_RX_PKTNUM_RECORD_REG);
588                 /*
589                  * Read hardware and software in adjacent positions to minumize
590                  * the timing variance.
591                  */
592                 rte_stats->ierrors += rxq->err_stats.l2_errors +
593                                       rxq->err_stats.pkt_len_errors;
594                 stats->rcb_rx_ring_pktnum_rcd += cnt;
595                 stats->rcb_rx_ring_pktnum[i] += cnt;
596                 rte_stats->ibytes += rxq->basic_stats.bytes;
597         }
598
599         /* Reads all the stats of a txq in a loop to keep them synchronized */
600         for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
601                 txq = eth_dev->data->tx_queues[i];
602                 if (txq == NULL)
603                         continue;
604
605                 cnt = hns3_read_dev(txq, HNS3_RING_TX_PKTNUM_RECORD_REG);
606                 stats->rcb_tx_ring_pktnum_rcd += cnt;
607                 stats->rcb_tx_ring_pktnum[i] += cnt;
608                 rte_stats->obytes += txq->basic_stats.bytes;
609         }
610
611         rte_stats->oerrors = 0;
612         /*
613          * If HW statistics are reset by stats_reset, but a lot of residual
614          * packets exist in the hardware queue and these packets are error
615          * packets, flip overflow may occurred. So return 0 in this case.
616          */
617         rte_stats->ipackets =
618                 stats->rcb_rx_ring_pktnum_rcd > rte_stats->ierrors ?
619                 stats->rcb_rx_ring_pktnum_rcd - rte_stats->ierrors : 0;
620         rte_stats->opackets  = stats->rcb_tx_ring_pktnum_rcd -
621                 rte_stats->oerrors;
622         rte_stats->rx_nombuf = eth_dev->data->rx_mbuf_alloc_failed;
623
624         return 0;
625 }
626
627 int
628 hns3_stats_reset(struct rte_eth_dev *eth_dev)
629 {
630         struct hns3_adapter *hns = eth_dev->data->dev_private;
631         struct hns3_hw *hw = &hns->hw;
632         struct hns3_rx_queue *rxq;
633         struct hns3_tx_queue *txq;
634         uint16_t i;
635         int ret;
636
637         /*
638          * Note: Reading hardware statistics of imissed registers will
639          * clear them.
640          */
641         ret = hns3_update_imissed_stats(hw, true);
642         if (ret) {
643                 hns3_err(hw, "clear imissed stats failed, ret = %d", ret);
644                 return ret;
645         }
646
647         for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
648                 rxq = eth_dev->data->rx_queues[i];
649                 if (rxq == NULL)
650                         continue;
651
652                 rxq->err_stats.pkt_len_errors = 0;
653                 rxq->err_stats.l2_errors = 0;
654         }
655
656         /* Clear all the stats of a rxq in a loop to keep them synchronized */
657         for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
658                 rxq = eth_dev->data->rx_queues[i];
659                 if (rxq == NULL)
660                         continue;
661
662                 memset(&rxq->basic_stats, 0,
663                                 sizeof(struct hns3_rx_basic_stats));
664
665                 /* This register is read-clear */
666                 (void)hns3_read_dev(rxq, HNS3_RING_RX_PKTNUM_RECORD_REG);
667                 rxq->err_stats.pkt_len_errors = 0;
668                 rxq->err_stats.l2_errors = 0;
669         }
670
671         /* Clear all the stats of a txq in a loop to keep them synchronized */
672         for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
673                 txq = eth_dev->data->tx_queues[i];
674                 if (txq == NULL)
675                         continue;
676
677                 memset(&txq->basic_stats, 0,
678                                 sizeof(struct hns3_tx_basic_stats));
679
680                 /* This register is read-clear */
681                 (void)hns3_read_dev(txq, HNS3_RING_TX_PKTNUM_RECORD_REG);
682         }
683
684         hns3_tqp_stats_clear(hw);
685
686         return 0;
687 }
688
689 static int
690 hns3_mac_stats_reset(__rte_unused struct rte_eth_dev *dev)
691 {
692         struct hns3_adapter *hns = dev->data->dev_private;
693         struct hns3_hw *hw = &hns->hw;
694         struct hns3_mac_stats *mac_stats = &hw->mac_stats;
695         int ret;
696
697         ret = hns3_query_update_mac_stats(dev);
698         if (ret) {
699                 hns3_err(hw, "Clear Mac stats fail : %d", ret);
700                 return ret;
701         }
702
703         memset(mac_stats, 0, sizeof(struct hns3_mac_stats));
704
705         return 0;
706 }
707
708 static int
709 hns3_get_imissed_stats_num(struct hns3_adapter *hns)
710 {
711 #define NO_IMISSED_STATS_NUM   0
712 #define RPU_STATS_ITEM_NUM     1
713         struct hns3_hw *hw = &hns->hw;
714
715         if (hw->drop_stats_mode == HNS3_PKTS_DROP_STATS_MODE1 && hns->is_vf)
716                 return NO_IMISSED_STATS_NUM;
717
718         if (hw->drop_stats_mode == HNS3_PKTS_DROP_STATS_MODE2 && !hns->is_vf)
719                 return HNS3_NUM_IMISSED_XSTATS;
720
721         return RPU_STATS_ITEM_NUM;
722 }
723
724 /* This function calculates the number of xstats based on the current config */
725 static int
726 hns3_xstats_calc_num(struct rte_eth_dev *dev)
727 {
728 #define HNS3_PF_VF_RX_COMM_STATS_NUM    (HNS3_NUM_RX_BD_ERROR_XSTATS + \
729                                          HNS3_NUM_RXQ_DFX_XSTATS + \
730                                          HNS3_NUM_RX_QUEUE_STATS + \
731                                          HNS3_NUM_RXQ_BASIC_STATS)
732 #define HNS3_PF_VF_TX_COMM_STATS_NUM    (HNS3_NUM_TXQ_DFX_XSTATS + \
733                                          HNS3_NUM_TX_QUEUE_STATS + \
734                                          HNS3_NUM_TXQ_BASIC_STATS)
735
736         struct hns3_adapter *hns = dev->data->dev_private;
737         uint16_t nb_rx_q = dev->data->nb_rx_queues;
738         uint16_t nb_tx_q = dev->data->nb_tx_queues;
739         int rx_comm_stats_num = nb_rx_q * HNS3_PF_VF_RX_COMM_STATS_NUM;
740         int tx_comm_stats_num = nb_tx_q * HNS3_PF_VF_TX_COMM_STATS_NUM;
741         int stats_num;
742
743         stats_num = rx_comm_stats_num + tx_comm_stats_num;
744         stats_num += hns3_get_imissed_stats_num(hns);
745
746         if (hns->is_vf)
747                 stats_num += HNS3_NUM_RESET_XSTATS;
748         else
749                 stats_num += HNS3_FIX_NUM_STATS;
750
751         return stats_num;
752 }
753
754 static void
755 hns3_queue_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
756                      int *count)
757 {
758         struct hns3_adapter *hns = dev->data->dev_private;
759         struct hns3_hw *hw = &hns->hw;
760         uint32_t reg_offset;
761         uint16_t i, j;
762
763         /* Get rx queue stats */
764         for (j = 0; j < dev->data->nb_rx_queues; j++) {
765                 for (i = 0; i < HNS3_NUM_RX_QUEUE_STATS; i++) {
766                         reg_offset = hns3_get_tqp_reg_offset(j);
767                         xstats[*count].value = hns3_read_dev(hw,
768                                 reg_offset + hns3_rx_queue_strings[i].offset);
769                         xstats[*count].id = *count;
770                         (*count)++;
771                 }
772         }
773
774         /* Get tx queue stats */
775         for (j = 0; j < dev->data->nb_tx_queues; j++) {
776                 for (i = 0; i < HNS3_NUM_TX_QUEUE_STATS; i++) {
777                         reg_offset = hns3_get_tqp_reg_offset(j);
778                         xstats[*count].value = hns3_read_dev(hw,
779                                 reg_offset + hns3_tx_queue_strings[i].offset);
780                         xstats[*count].id = *count;
781                         (*count)++;
782                 }
783         }
784 }
785
786 static void
787 hns3_rxq_dfx_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
788                        int *count)
789 {
790         struct hns3_rx_dfx_stats *dfx_stats;
791         struct hns3_rx_queue *rxq;
792         uint16_t i, j;
793         char *val;
794
795         for (i = 0; i < dev->data->nb_rx_queues; i++) {
796                 rxq = (struct hns3_rx_queue *)dev->data->rx_queues[i];
797                 if (rxq == NULL)
798                         continue;
799
800                 dfx_stats = &rxq->dfx_stats;
801                 for (j = 0; j < HNS3_NUM_RXQ_DFX_XSTATS; j++) {
802                         val = (char *)dfx_stats +
803                                 hns3_rxq_dfx_stats_strings[j].offset;
804                         xstats[*count].value = *(uint64_t *)val;
805                         xstats[*count].id = *count;
806                         (*count)++;
807                 }
808         }
809 }
810
811 static void
812 hns3_txq_dfx_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
813                        int *count)
814 {
815         struct hns3_tx_dfx_stats *dfx_stats;
816         struct hns3_tx_queue *txq;
817         uint16_t i, j;
818         char *val;
819
820         for (i = 0; i < dev->data->nb_tx_queues; i++) {
821                 txq = (struct hns3_tx_queue *)dev->data->tx_queues[i];
822                 if (txq == NULL)
823                         continue;
824
825                 dfx_stats = &txq->dfx_stats;
826                 for (j = 0; j < HNS3_NUM_TXQ_DFX_XSTATS; j++) {
827                         val = (char *)dfx_stats +
828                                 hns3_txq_dfx_stats_strings[j].offset;
829                         xstats[*count].value = *(uint64_t *)val;
830                         xstats[*count].id = *count;
831                         (*count)++;
832                 }
833         }
834 }
835
836 static void
837 hns3_tqp_dfx_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
838                        int *count)
839 {
840         hns3_rxq_dfx_stats_get(dev, xstats, count);
841         hns3_txq_dfx_stats_get(dev, xstats, count);
842 }
843
844 static void
845 hns3_rxq_basic_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
846                          int *count)
847 {
848         struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
849         struct hns3_tqp_stats *stats = &hw->tqp_stats;
850         struct hns3_rx_basic_stats *rxq_stats;
851         struct hns3_rx_queue *rxq;
852         uint16_t i, j;
853         uint32_t cnt;
854         char *val;
855
856         for (i = 0; i < dev->data->nb_rx_queues; i++) {
857                 rxq = dev->data->rx_queues[i];
858                 if (rxq == NULL)
859                         continue;
860
861                 cnt = hns3_read_dev(rxq, HNS3_RING_RX_PKTNUM_RECORD_REG);
862                 /*
863                  * Read hardware and software in adjacent positions to minimize
864                  * the time difference.
865                  */
866                 rxq_stats = &rxq->basic_stats;
867                 rxq_stats->errors = rxq->err_stats.l2_errors +
868                                         rxq->err_stats.pkt_len_errors;
869                 stats->rcb_rx_ring_pktnum_rcd += cnt;
870                 stats->rcb_rx_ring_pktnum[i] += cnt;
871
872                 /*
873                  * If HW statistics are reset by stats_reset, but a lot of
874                  * residual packets exist in the hardware queue and these
875                  * packets are error packets, flip overflow may occurred.
876                  * So return 0 in this case.
877                  */
878                 rxq_stats->packets =
879                         stats->rcb_rx_ring_pktnum[i] > rxq_stats->errors ?
880                         stats->rcb_rx_ring_pktnum[i] - rxq_stats->errors : 0;
881                 for (j = 0; j < HNS3_NUM_RXQ_BASIC_STATS; j++) {
882                         val = (char *)rxq_stats +
883                                 hns3_rxq_basic_stats_strings[j].offset;
884                         xstats[*count].value = *(uint64_t *)val;
885                         xstats[*count].id = *count;
886                         (*count)++;
887                 }
888         }
889 }
890
891 static void
892 hns3_txq_basic_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
893                          int *count)
894 {
895         struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
896         struct hns3_tqp_stats *stats = &hw->tqp_stats;
897         struct hns3_tx_basic_stats *txq_stats;
898         struct hns3_tx_queue *txq;
899         uint16_t i, j;
900         uint32_t cnt;
901         char *val;
902
903         for (i = 0; i < dev->data->nb_tx_queues; i++) {
904                 txq = dev->data->tx_queues[i];
905                 if (txq == NULL)
906                         continue;
907
908                 cnt = hns3_read_dev(txq, HNS3_RING_TX_PKTNUM_RECORD_REG);
909                 stats->rcb_tx_ring_pktnum_rcd += cnt;
910                 stats->rcb_tx_ring_pktnum[i] += cnt;
911
912                 txq_stats = &txq->basic_stats;
913                 txq_stats->packets = stats->rcb_tx_ring_pktnum[i];
914
915                 for (j = 0; j < HNS3_NUM_TXQ_BASIC_STATS; j++) {
916                         val = (char *)txq_stats +
917                                 hns3_txq_basic_stats_strings[j].offset;
918                         xstats[*count].value = *(uint64_t *)val;
919                         xstats[*count].id = *count;
920                         (*count)++;
921                 }
922         }
923 }
924
925 static void
926 hns3_tqp_basic_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
927                          int *count)
928 {
929         hns3_rxq_basic_stats_get(dev, xstats, count);
930         hns3_txq_basic_stats_get(dev, xstats, count);
931 }
932
933 static void
934 hns3_imissed_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
935                           int *count)
936 {
937         struct hns3_adapter *hns = dev->data->dev_private;
938         struct hns3_hw *hw = &hns->hw;
939         struct hns3_rx_missed_stats *imissed_stats = &hw->imissed_stats;
940         int imissed_stats_num;
941         int cnt = *count;
942         char *addr;
943         uint16_t i;
944
945         imissed_stats_num = hns3_get_imissed_stats_num(hns);
946
947         for (i = 0; i < imissed_stats_num; i++) {
948                 addr = (char *)imissed_stats +
949                         hns3_imissed_stats_strings[i].offset;
950                 xstats[cnt].value = *(uint64_t *)addr;
951                 xstats[cnt].id = cnt;
952                 cnt++;
953         }
954
955         *count = cnt;
956 }
957
958 /*
959  * Retrieve extended(tqp | Mac) statistics of an Ethernet device.
960  * @param dev
961  *   Pointer to Ethernet device.
962  * @praram xstats
963  *   A pointer to a table of structure of type *rte_eth_xstat*
964  *   to be filled with device statistics ids and values.
965  *   This parameter can be set to NULL if n is 0.
966  * @param n
967  *   The size of the xstats array (number of elements).
968  * @return
969  *   0 on fail, count(The size of the statistics elements) on success.
970  */
971 int
972 hns3_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
973                     unsigned int n)
974 {
975         struct hns3_adapter *hns = dev->data->dev_private;
976         struct hns3_hw *hw = &hns->hw;
977         struct hns3_mac_stats *mac_stats = &hw->mac_stats;
978         struct hns3_reset_stats *reset_stats = &hw->reset.stats;
979         struct hns3_rx_bd_errors_stats *rx_err_stats;
980         struct hns3_rx_queue *rxq;
981         uint16_t i, j;
982         char *addr;
983         int count;
984         int ret;
985
986         if (xstats == NULL)
987                 return 0;
988
989         count = hns3_xstats_calc_num(dev);
990         if ((int)n < count)
991                 return count;
992
993         count = 0;
994
995         hns3_tqp_basic_stats_get(dev, xstats, &count);
996
997         if (!hns->is_vf) {
998                 /* Update Mac stats */
999                 ret = hns3_query_update_mac_stats(dev);
1000                 if (ret < 0) {
1001                         hns3_err(hw, "Update Mac stats fail : %d", ret);
1002                         return ret;
1003                 }
1004
1005                 /* Get MAC stats from hw->hw_xstats.mac_stats struct */
1006                 for (i = 0; i < HNS3_NUM_MAC_STATS; i++) {
1007                         addr = (char *)mac_stats + hns3_mac_strings[i].offset;
1008                         xstats[count].value = *(uint64_t *)addr;
1009                         xstats[count].id = count;
1010                         count++;
1011                 }
1012         }
1013
1014         ret = hns3_update_imissed_stats(hw, false);
1015         if (ret) {
1016                 hns3_err(hw, "update imissed stats failed, ret = %d",
1017                          ret);
1018                 return ret;
1019         }
1020
1021         hns3_imissed_stats_get(dev, xstats, &count);
1022
1023         /* Get the reset stat */
1024         for (i = 0; i < HNS3_NUM_RESET_XSTATS; i++) {
1025                 addr = (char *)reset_stats + hns3_reset_stats_strings[i].offset;
1026                 xstats[count].value = *(uint64_t *)addr;
1027                 xstats[count].id = count;
1028                 count++;
1029         }
1030
1031         /* Get the Rx BD errors stats */
1032         for (j = 0; j < dev->data->nb_rx_queues; j++) {
1033                 for (i = 0; i < HNS3_NUM_RX_BD_ERROR_XSTATS; i++) {
1034                         rxq = dev->data->rx_queues[j];
1035                         if (rxq) {
1036                                 rx_err_stats = &rxq->err_stats;
1037                                 addr = (char *)rx_err_stats +
1038                                         hns3_rx_bd_error_strings[i].offset;
1039                                 xstats[count].value = *(uint64_t *)addr;
1040                                 xstats[count].id = count;
1041                                 count++;
1042                         }
1043                 }
1044         }
1045
1046         hns3_tqp_dfx_stats_get(dev, xstats, &count);
1047         hns3_queue_stats_get(dev, xstats, &count);
1048
1049         return count;
1050 }
1051
1052 static void
1053 hns3_tqp_basic_stats_name_get(struct rte_eth_dev *dev,
1054                               struct rte_eth_xstat_name *xstats_names,
1055                               uint32_t *count)
1056 {
1057         uint16_t i, j;
1058
1059         for (i = 0; i < dev->data->nb_rx_queues; i++) {
1060                 for (j = 0; j < HNS3_NUM_RXQ_BASIC_STATS; j++) {
1061                         snprintf(xstats_names[*count].name,
1062                                  sizeof(xstats_names[*count].name),
1063                                  "rx_q%u_%s", i,
1064                                  hns3_rxq_basic_stats_strings[j].name);
1065                         (*count)++;
1066                 }
1067         }
1068         for (i = 0; i < dev->data->nb_tx_queues; i++) {
1069                 for (j = 0; j < HNS3_NUM_TXQ_BASIC_STATS; j++) {
1070                         snprintf(xstats_names[*count].name,
1071                                  sizeof(xstats_names[*count].name),
1072                                  "tx_q%u_%s", i,
1073                                  hns3_txq_basic_stats_strings[j].name);
1074                         (*count)++;
1075                 }
1076         }
1077 }
1078
1079 static void
1080 hns3_tqp_dfx_stats_name_get(struct rte_eth_dev *dev,
1081                             struct rte_eth_xstat_name *xstats_names,
1082                             uint32_t *count)
1083 {
1084         uint16_t i, j;
1085
1086         for (i = 0; i < dev->data->nb_rx_queues; i++) {
1087                 for (j = 0; j < HNS3_NUM_RXQ_DFX_XSTATS; j++) {
1088                         snprintf(xstats_names[*count].name,
1089                                  sizeof(xstats_names[*count].name),
1090                                  "rx_q%u_%s", i,
1091                                  hns3_rxq_dfx_stats_strings[j].name);
1092                         (*count)++;
1093                 }
1094         }
1095
1096         for (i = 0; i < dev->data->nb_tx_queues; i++) {
1097                 for (j = 0; j < HNS3_NUM_TXQ_DFX_XSTATS; j++) {
1098                         snprintf(xstats_names[*count].name,
1099                                  sizeof(xstats_names[*count].name),
1100                                  "tx_q%u_%s", i,
1101                                  hns3_txq_dfx_stats_strings[j].name);
1102                         (*count)++;
1103                 }
1104         }
1105 }
1106
1107 static void
1108 hns3_imissed_stats_name_get(struct rte_eth_dev *dev,
1109                             struct rte_eth_xstat_name *xstats_names,
1110                             uint32_t *count)
1111 {
1112         struct hns3_adapter *hns = dev->data->dev_private;
1113         uint32_t cnt = *count;
1114         int imissed_stats_num;
1115         uint16_t i;
1116
1117         imissed_stats_num = hns3_get_imissed_stats_num(hns);
1118
1119         for (i = 0; i < imissed_stats_num; i++) {
1120                 snprintf(xstats_names[cnt].name,
1121                          sizeof(xstats_names[cnt].name),
1122                          "%s", hns3_imissed_stats_strings[i].name);
1123                 cnt++;
1124         }
1125
1126         *count = cnt;
1127 }
1128
1129 /*
1130  * Retrieve names of extended statistics of an Ethernet device.
1131  *
1132  * There is an assumption that 'xstat_names' and 'xstats' arrays are matched
1133  * by array index:
1134  *  xstats_names[i].name => xstats[i].value
1135  *
1136  * And the array index is same with id field of 'struct rte_eth_xstat':
1137  *  xstats[i].id == i
1138  *
1139  * This assumption makes key-value pair matching less flexible but simpler.
1140  *
1141  * @param dev
1142  *   Pointer to Ethernet device.
1143  * @param xstats_names
1144  *   An rte_eth_xstat_name array of at least *size* elements to
1145  *   be filled. If set to NULL, the function returns the required number
1146  *   of elements.
1147  * @param size
1148  *   The size of the xstats_names array (number of elements).
1149  * @return
1150  *   - A positive value lower or equal to size: success. The return value
1151  *     is the number of entries filled in the stats table.
1152  */
1153 int
1154 hns3_dev_xstats_get_names(struct rte_eth_dev *dev,
1155                           struct rte_eth_xstat_name *xstats_names,
1156                           __rte_unused unsigned int size)
1157 {
1158         struct hns3_adapter *hns = dev->data->dev_private;
1159         int cnt_stats = hns3_xstats_calc_num(dev);
1160         uint32_t count = 0;
1161         uint16_t i, j;
1162
1163         if (xstats_names == NULL)
1164                 return cnt_stats;
1165
1166         hns3_tqp_basic_stats_name_get(dev, xstats_names, &count);
1167
1168         /* Note: size limited checked in rte_eth_xstats_get_names() */
1169         if (!hns->is_vf) {
1170                 /* Get MAC name from hw->hw_xstats.mac_stats struct */
1171                 for (i = 0; i < HNS3_NUM_MAC_STATS; i++) {
1172                         snprintf(xstats_names[count].name,
1173                                  sizeof(xstats_names[count].name),
1174                                  "%s", hns3_mac_strings[i].name);
1175                         count++;
1176                 }
1177         }
1178
1179         hns3_imissed_stats_name_get(dev, xstats_names, &count);
1180
1181         for (i = 0; i < HNS3_NUM_RESET_XSTATS; i++) {
1182                 snprintf(xstats_names[count].name,
1183                          sizeof(xstats_names[count].name),
1184                          "%s", hns3_reset_stats_strings[i].name);
1185                 count++;
1186         }
1187
1188         for (j = 0; j < dev->data->nb_rx_queues; j++) {
1189                 for (i = 0; i < HNS3_NUM_RX_BD_ERROR_XSTATS; i++) {
1190                         snprintf(xstats_names[count].name,
1191                                  sizeof(xstats_names[count].name),
1192                                  "rx_q%u_%s", j,
1193                                  hns3_rx_bd_error_strings[i].name);
1194                         count++;
1195                 }
1196         }
1197
1198         hns3_tqp_dfx_stats_name_get(dev, xstats_names, &count);
1199
1200         for (j = 0; j < dev->data->nb_rx_queues; j++) {
1201                 for (i = 0; i < HNS3_NUM_RX_QUEUE_STATS; i++) {
1202                         snprintf(xstats_names[count].name,
1203                                  sizeof(xstats_names[count].name),
1204                                  "rx_q%u_%s", j, hns3_rx_queue_strings[i].name);
1205                         count++;
1206                 }
1207         }
1208
1209         for (j = 0; j < dev->data->nb_tx_queues; j++) {
1210                 for (i = 0; i < HNS3_NUM_TX_QUEUE_STATS; i++) {
1211                         snprintf(xstats_names[count].name,
1212                                  sizeof(xstats_names[count].name),
1213                                  "tx_q%u_%s", j, hns3_tx_queue_strings[i].name);
1214                         count++;
1215                 }
1216         }
1217
1218         return count;
1219 }
1220
1221 /*
1222  * Retrieve extended statistics of an Ethernet device.
1223  *
1224  * @param dev
1225  *   Pointer to Ethernet device.
1226  * @param ids
1227  *   A pointer to an ids array passed by application. This tells which
1228  *   statistics values function should retrieve. This parameter
1229  *   can be set to NULL if size is 0. In this case function will retrieve
1230  *   all avalible statistics.
1231  * @param values
1232  *   A pointer to a table to be filled with device statistics values.
1233  * @param size
1234  *   The size of the ids array (number of elements).
1235  * @return
1236  *   - A positive value lower or equal to size: success. The return value
1237  *     is the number of entries filled in the stats table.
1238  *   - A positive value higher than size: error, the given statistics table
1239  *     is too small. The return value corresponds to the size that should
1240  *     be given to succeed. The entries in the table are not valid and
1241  *     shall not be used by the caller.
1242  *   - 0 on no ids.
1243  */
1244 int
1245 hns3_dev_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids,
1246                           uint64_t *values, uint32_t size)
1247 {
1248         const uint32_t cnt_stats = hns3_xstats_calc_num(dev);
1249         struct hns3_adapter *hns = dev->data->dev_private;
1250         struct rte_eth_xstat *values_copy;
1251         struct hns3_hw *hw = &hns->hw;
1252         uint32_t count_value;
1253         uint64_t len;
1254         uint32_t i;
1255
1256         if (ids == NULL && values == NULL)
1257                 return cnt_stats;
1258
1259         if (ids == NULL)
1260                 if (size < cnt_stats)
1261                         return cnt_stats;
1262
1263         len = cnt_stats * sizeof(struct rte_eth_xstat);
1264         values_copy = rte_zmalloc("hns3_xstats_values", len, 0);
1265         if (values_copy == NULL) {
1266                 hns3_err(hw, "Failed to allocate %" PRIx64 " bytes needed "
1267                              "to store statistics values", len);
1268                 return -ENOMEM;
1269         }
1270
1271         count_value = hns3_dev_xstats_get(dev, values_copy, cnt_stats);
1272         if (count_value != cnt_stats) {
1273                 rte_free(values_copy);
1274                 return -EINVAL;
1275         }
1276
1277         if (ids == NULL && values != NULL) {
1278                 for (i = 0; i < cnt_stats; i++)
1279                         memcpy(&values[i], &values_copy[i].value,
1280                                sizeof(values[i]));
1281
1282                 rte_free(values_copy);
1283                 return cnt_stats;
1284         }
1285
1286         for (i = 0; i < size; i++) {
1287                 if (ids[i] >= cnt_stats) {
1288                         hns3_err(hw, "ids[%u] (%" PRIx64 ") is invalid, "
1289                                      "should < %u", i, ids[i], cnt_stats);
1290                         rte_free(values_copy);
1291                         return -EINVAL;
1292                 }
1293                 memcpy(&values[i], &values_copy[ids[i]].value,
1294                         sizeof(values[i]));
1295         }
1296
1297         rte_free(values_copy);
1298         return size;
1299 }
1300
1301 /*
1302  * Retrieve names of extended statistics of an Ethernet device.
1303  *
1304  * @param dev
1305  *   Pointer to Ethernet device.
1306  * @param xstats_names
1307  *   An rte_eth_xstat_name array of at least *size* elements to
1308  *   be filled. If set to NULL, the function returns the required number
1309  *   of elements.
1310  * @param ids
1311  *   IDs array given by app to retrieve specific statistics
1312  * @param size
1313  *   The size of the xstats_names array (number of elements).
1314  * @return
1315  *   - A positive value lower or equal to size: success. The return value
1316  *     is the number of entries filled in the stats table.
1317  *   - A positive value higher than size: error, the given statistics table
1318  *     is too small. The return value corresponds to the size that should
1319  *     be given to succeed. The entries in the table are not valid and
1320  *     shall not be used by the caller.
1321  */
1322 int
1323 hns3_dev_xstats_get_names_by_id(struct rte_eth_dev *dev,
1324                                 struct rte_eth_xstat_name *xstats_names,
1325                                 const uint64_t *ids, uint32_t size)
1326 {
1327         const uint32_t cnt_stats = hns3_xstats_calc_num(dev);
1328         struct hns3_adapter *hns = dev->data->dev_private;
1329         struct rte_eth_xstat_name *names_copy;
1330         struct hns3_hw *hw = &hns->hw;
1331         uint64_t len;
1332         uint32_t i;
1333
1334         if (xstats_names == NULL)
1335                 return cnt_stats;
1336
1337         if (ids == NULL) {
1338                 if (size < cnt_stats)
1339                         return cnt_stats;
1340
1341                 return hns3_dev_xstats_get_names(dev, xstats_names, cnt_stats);
1342         }
1343
1344         len = cnt_stats * sizeof(struct rte_eth_xstat_name);
1345         names_copy = rte_zmalloc("hns3_xstats_names", len, 0);
1346         if (names_copy == NULL) {
1347                 hns3_err(hw, "Failed to allocate %" PRIx64 " bytes needed "
1348                              "to store statistics names", len);
1349                 return -ENOMEM;
1350         }
1351
1352         (void)hns3_dev_xstats_get_names(dev, names_copy, cnt_stats);
1353
1354         for (i = 0; i < size; i++) {
1355                 if (ids[i] >= cnt_stats) {
1356                         hns3_err(hw, "ids[%u] (%" PRIx64 ") is invalid, "
1357                                      "should < %u", i, ids[i], cnt_stats);
1358                         rte_free(names_copy);
1359                         return -EINVAL;
1360                 }
1361                 snprintf(xstats_names[i].name, sizeof(xstats_names[i].name),
1362                          "%s", names_copy[ids[i]].name);
1363         }
1364
1365         rte_free(names_copy);
1366         return size;
1367 }
1368
1369 static void
1370 hns3_tqp_dfx_stats_clear(struct rte_eth_dev *dev)
1371 {
1372         struct hns3_rx_queue *rxq;
1373         struct hns3_tx_queue *txq;
1374         uint16_t i;
1375
1376         /* Clear Rx dfx stats */
1377         for (i = 0; i < dev->data->nb_rx_queues; i++) {
1378                 rxq = dev->data->rx_queues[i];
1379                 if (rxq)
1380                         memset(&rxq->dfx_stats, 0,
1381                                sizeof(struct hns3_rx_dfx_stats));
1382         }
1383
1384         /* Clear Tx dfx stats */
1385         for (i = 0; i < dev->data->nb_tx_queues; i++) {
1386                 txq = dev->data->tx_queues[i];
1387                 if (txq)
1388                         memset(&txq->dfx_stats, 0,
1389                                sizeof(struct hns3_tx_dfx_stats));
1390         }
1391 }
1392
1393 int
1394 hns3_dev_xstats_reset(struct rte_eth_dev *dev)
1395 {
1396         struct hns3_adapter *hns = dev->data->dev_private;
1397         int ret;
1398
1399         /* Clear tqp stats */
1400         ret = hns3_stats_reset(dev);
1401         if (ret)
1402                 return ret;
1403
1404         hns3_tqp_dfx_stats_clear(dev);
1405
1406         /* Clear reset stats */
1407         memset(&hns->hw.reset.stats, 0, sizeof(struct hns3_reset_stats));
1408
1409         if (hns->is_vf)
1410                 return 0;
1411
1412         /* HW registers are cleared on read */
1413         ret = hns3_mac_stats_reset(dev);
1414         if (ret)
1415                 return ret;
1416
1417         return 0;
1418 }
1419
1420 int
1421 hns3_tqp_stats_init(struct hns3_hw *hw)
1422 {
1423         struct hns3_tqp_stats *tqp_stats = &hw->tqp_stats;
1424
1425         tqp_stats->rcb_rx_ring_pktnum = rte_zmalloc("hns3_rx_ring_pkt_num",
1426                                          sizeof(uint64_t) * hw->tqps_num, 0);
1427         if (tqp_stats->rcb_rx_ring_pktnum == NULL) {
1428                 hns3_err(hw, "failed to allocate rx_ring pkt_num.");
1429                 return -ENOMEM;
1430         }
1431
1432         tqp_stats->rcb_tx_ring_pktnum = rte_zmalloc("hns3_tx_ring_pkt_num",
1433                                          sizeof(uint64_t) * hw->tqps_num, 0);
1434         if (tqp_stats->rcb_tx_ring_pktnum == NULL) {
1435                 hns3_err(hw, "failed to allocate tx_ring pkt_num.");
1436                 rte_free(tqp_stats->rcb_rx_ring_pktnum);
1437                 tqp_stats->rcb_rx_ring_pktnum = NULL;
1438                 return -ENOMEM;
1439         }
1440
1441         return 0;
1442 }
1443
1444 void
1445 hns3_tqp_stats_uninit(struct hns3_hw *hw)
1446 {
1447         struct hns3_tqp_stats *tqp_stats = &hw->tqp_stats;
1448
1449         rte_free(tqp_stats->rcb_rx_ring_pktnum);
1450         tqp_stats->rcb_rx_ring_pktnum = NULL;
1451         rte_free(tqp_stats->rcb_tx_ring_pktnum);
1452         tqp_stats->rcb_tx_ring_pktnum = NULL;
1453 }
1454
1455 static void
1456 hns3_tqp_stats_clear(struct hns3_hw *hw)
1457 {
1458         struct hns3_tqp_stats *stats = &hw->tqp_stats;
1459
1460         stats->rcb_rx_ring_pktnum_rcd = 0;
1461         stats->rcb_tx_ring_pktnum_rcd = 0;
1462         memset(stats->rcb_rx_ring_pktnum, 0, sizeof(uint64_t) * hw->tqps_num);
1463         memset(stats->rcb_tx_ring_pktnum, 0, sizeof(uint64_t) * hw->tqps_num);
1464 }