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