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