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