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