xref: /dpdk/drivers/net/hns3/hns3_stats.c (revision a65342d9)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018-2021 HiSilicon Limited.
3  */
4 
5 #include <rte_ethdev.h>
6 #include <rte_io.h>
7 #include <rte_malloc.h>
8 
9 #include "hns3_ethdev.h"
10 #include "hns3_rxtx.h"
11 #include "hns3_logs.h"
12 #include "hns3_regs.h"
13 
14 /* The statistics of the per-rxq basic stats */
15 static const struct hns3_xstats_name_offset hns3_rxq_basic_stats_strings[] = {
16 	{"packets",
17 		HNS3_RXQ_BASIC_STATS_FIELD_OFFSET(packets)},
18 	{"bytes",
19 		HNS3_RXQ_BASIC_STATS_FIELD_OFFSET(bytes)},
20 	{"errors",
21 		HNS3_RXQ_BASIC_STATS_FIELD_OFFSET(errors)}
22 };
23 
24 /* The statistics of the per-txq basic stats */
25 static const struct hns3_xstats_name_offset hns3_txq_basic_stats_strings[] = {
26 	{"packets",
27 		HNS3_TXQ_BASIC_STATS_FIELD_OFFSET(packets)},
28 	{"bytes",
29 		HNS3_TXQ_BASIC_STATS_FIELD_OFFSET(bytes)}
30 };
31 
32 /* MAC statistics */
33 static const struct hns3_xstats_name_offset hns3_mac_strings[] = {
34 	{"mac_tx_mac_pause_num",
35 		HNS3_MAC_STATS_OFFSET(mac_tx_mac_pause_num)},
36 	{"mac_rx_mac_pause_num",
37 		HNS3_MAC_STATS_OFFSET(mac_rx_mac_pause_num)},
38 	{"mac_tx_control_pkt_num",
39 		HNS3_MAC_STATS_OFFSET(mac_tx_ctrl_pkt_num)},
40 	{"mac_rx_control_pkt_num",
41 		HNS3_MAC_STATS_OFFSET(mac_rx_ctrl_pkt_num)},
42 	{"mac_tx_pfc_pkt_num",
43 		HNS3_MAC_STATS_OFFSET(mac_tx_pfc_pause_pkt_num)},
44 	{"mac_tx_pfc_pri0_pkt_num",
45 		HNS3_MAC_STATS_OFFSET(mac_tx_pfc_pri0_pkt_num)},
46 	{"mac_tx_pfc_pri1_pkt_num",
47 		HNS3_MAC_STATS_OFFSET(mac_tx_pfc_pri1_pkt_num)},
48 	{"mac_tx_pfc_pri2_pkt_num",
49 		HNS3_MAC_STATS_OFFSET(mac_tx_pfc_pri2_pkt_num)},
50 	{"mac_tx_pfc_pri3_pkt_num",
51 		HNS3_MAC_STATS_OFFSET(mac_tx_pfc_pri3_pkt_num)},
52 	{"mac_tx_pfc_pri4_pkt_num",
53 		HNS3_MAC_STATS_OFFSET(mac_tx_pfc_pri4_pkt_num)},
54 	{"mac_tx_pfc_pri5_pkt_num",
55 		HNS3_MAC_STATS_OFFSET(mac_tx_pfc_pri5_pkt_num)},
56 	{"mac_tx_pfc_pri6_pkt_num",
57 		HNS3_MAC_STATS_OFFSET(mac_tx_pfc_pri6_pkt_num)},
58 	{"mac_tx_pfc_pri7_pkt_num",
59 		HNS3_MAC_STATS_OFFSET(mac_tx_pfc_pri7_pkt_num)},
60 	{"mac_rx_pfc_pkt_num",
61 		HNS3_MAC_STATS_OFFSET(mac_rx_pfc_pause_pkt_num)},
62 	{"mac_rx_pfc_pri0_pkt_num",
63 		HNS3_MAC_STATS_OFFSET(mac_rx_pfc_pri0_pkt_num)},
64 	{"mac_rx_pfc_pri1_pkt_num",
65 		HNS3_MAC_STATS_OFFSET(mac_rx_pfc_pri1_pkt_num)},
66 	{"mac_rx_pfc_pri2_pkt_num",
67 		HNS3_MAC_STATS_OFFSET(mac_rx_pfc_pri2_pkt_num)},
68 	{"mac_rx_pfc_pri3_pkt_num",
69 		HNS3_MAC_STATS_OFFSET(mac_rx_pfc_pri3_pkt_num)},
70 	{"mac_rx_pfc_pri4_pkt_num",
71 		HNS3_MAC_STATS_OFFSET(mac_rx_pfc_pri4_pkt_num)},
72 	{"mac_rx_pfc_pri5_pkt_num",
73 		HNS3_MAC_STATS_OFFSET(mac_rx_pfc_pri5_pkt_num)},
74 	{"mac_rx_pfc_pri6_pkt_num",
75 		HNS3_MAC_STATS_OFFSET(mac_rx_pfc_pri6_pkt_num)},
76 	{"mac_rx_pfc_pri7_pkt_num",
77 		HNS3_MAC_STATS_OFFSET(mac_rx_pfc_pri7_pkt_num)},
78 	{"mac_tx_total_pkt_num",
79 		HNS3_MAC_STATS_OFFSET(mac_tx_total_pkt_num)},
80 	{"mac_tx_total_oct_num",
81 		HNS3_MAC_STATS_OFFSET(mac_tx_total_oct_num)},
82 	{"mac_tx_good_pkt_num",
83 		HNS3_MAC_STATS_OFFSET(mac_tx_good_pkt_num)},
84 	{"mac_tx_bad_pkt_num",
85 		HNS3_MAC_STATS_OFFSET(mac_tx_bad_pkt_num)},
86 	{"mac_tx_good_oct_num",
87 		HNS3_MAC_STATS_OFFSET(mac_tx_good_oct_num)},
88 	{"mac_tx_bad_oct_num",
89 		HNS3_MAC_STATS_OFFSET(mac_tx_bad_oct_num)},
90 	{"mac_tx_uni_pkt_num",
91 		HNS3_MAC_STATS_OFFSET(mac_tx_uni_pkt_num)},
92 	{"mac_tx_multi_pkt_num",
93 		HNS3_MAC_STATS_OFFSET(mac_tx_multi_pkt_num)},
94 	{"mac_tx_broad_pkt_num",
95 		HNS3_MAC_STATS_OFFSET(mac_tx_broad_pkt_num)},
96 	{"mac_tx_undersize_pkt_num",
97 		HNS3_MAC_STATS_OFFSET(mac_tx_undersize_pkt_num)},
98 	{"mac_tx_oversize_pkt_num",
99 		HNS3_MAC_STATS_OFFSET(mac_tx_oversize_pkt_num)},
100 	{"mac_tx_64_oct_pkt_num",
101 		HNS3_MAC_STATS_OFFSET(mac_tx_64_oct_pkt_num)},
102 	{"mac_tx_65_127_oct_pkt_num",
103 		HNS3_MAC_STATS_OFFSET(mac_tx_65_127_oct_pkt_num)},
104 	{"mac_tx_128_255_oct_pkt_num",
105 		HNS3_MAC_STATS_OFFSET(mac_tx_128_255_oct_pkt_num)},
106 	{"mac_tx_256_511_oct_pkt_num",
107 		HNS3_MAC_STATS_OFFSET(mac_tx_256_511_oct_pkt_num)},
108 	{"mac_tx_512_1023_oct_pkt_num",
109 		HNS3_MAC_STATS_OFFSET(mac_tx_512_1023_oct_pkt_num)},
110 	{"mac_tx_1024_1518_oct_pkt_num",
111 		HNS3_MAC_STATS_OFFSET(mac_tx_1024_1518_oct_pkt_num)},
112 	{"mac_tx_1519_2047_oct_pkt_num",
113 		HNS3_MAC_STATS_OFFSET(mac_tx_1519_2047_oct_pkt_num)},
114 	{"mac_tx_2048_4095_oct_pkt_num",
115 		HNS3_MAC_STATS_OFFSET(mac_tx_2048_4095_oct_pkt_num)},
116 	{"mac_tx_4096_8191_oct_pkt_num",
117 		HNS3_MAC_STATS_OFFSET(mac_tx_4096_8191_oct_pkt_num)},
118 	{"mac_tx_8192_9216_oct_pkt_num",
119 		HNS3_MAC_STATS_OFFSET(mac_tx_8192_9216_oct_pkt_num)},
120 	{"mac_tx_9217_12287_oct_pkt_num",
121 		HNS3_MAC_STATS_OFFSET(mac_tx_9217_12287_oct_pkt_num)},
122 	{"mac_tx_12288_16383_oct_pkt_num",
123 		HNS3_MAC_STATS_OFFSET(mac_tx_12288_16383_oct_pkt_num)},
124 	{"mac_tx_1519_max_good_pkt_num",
125 		HNS3_MAC_STATS_OFFSET(mac_tx_1519_max_good_oct_pkt_num)},
126 	{"mac_tx_1519_max_bad_pkt_num",
127 		HNS3_MAC_STATS_OFFSET(mac_tx_1519_max_bad_oct_pkt_num)},
128 	{"mac_rx_total_pkt_num",
129 		HNS3_MAC_STATS_OFFSET(mac_rx_total_pkt_num)},
130 	{"mac_rx_total_oct_num",
131 		HNS3_MAC_STATS_OFFSET(mac_rx_total_oct_num)},
132 	{"mac_rx_good_pkt_num",
133 		HNS3_MAC_STATS_OFFSET(mac_rx_good_pkt_num)},
134 	{"mac_rx_bad_pkt_num",
135 		HNS3_MAC_STATS_OFFSET(mac_rx_bad_pkt_num)},
136 	{"mac_rx_good_oct_num",
137 		HNS3_MAC_STATS_OFFSET(mac_rx_good_oct_num)},
138 	{"mac_rx_bad_oct_num",
139 		HNS3_MAC_STATS_OFFSET(mac_rx_bad_oct_num)},
140 	{"mac_rx_uni_pkt_num",
141 		HNS3_MAC_STATS_OFFSET(mac_rx_uni_pkt_num)},
142 	{"mac_rx_multi_pkt_num",
143 		HNS3_MAC_STATS_OFFSET(mac_rx_multi_pkt_num)},
144 	{"mac_rx_broad_pkt_num",
145 		HNS3_MAC_STATS_OFFSET(mac_rx_broad_pkt_num)},
146 	{"mac_rx_undersize_pkt_num",
147 		HNS3_MAC_STATS_OFFSET(mac_rx_undersize_pkt_num)},
148 	{"mac_rx_oversize_pkt_num",
149 		HNS3_MAC_STATS_OFFSET(mac_rx_oversize_pkt_num)},
150 	{"mac_rx_64_oct_pkt_num",
151 		HNS3_MAC_STATS_OFFSET(mac_rx_64_oct_pkt_num)},
152 	{"mac_rx_65_127_oct_pkt_num",
153 		HNS3_MAC_STATS_OFFSET(mac_rx_65_127_oct_pkt_num)},
154 	{"mac_rx_128_255_oct_pkt_num",
155 		HNS3_MAC_STATS_OFFSET(mac_rx_128_255_oct_pkt_num)},
156 	{"mac_rx_256_511_oct_pkt_num",
157 		HNS3_MAC_STATS_OFFSET(mac_rx_256_511_oct_pkt_num)},
158 	{"mac_rx_512_1023_oct_pkt_num",
159 		HNS3_MAC_STATS_OFFSET(mac_rx_512_1023_oct_pkt_num)},
160 	{"mac_rx_1024_1518_oct_pkt_num",
161 		HNS3_MAC_STATS_OFFSET(mac_rx_1024_1518_oct_pkt_num)},
162 	{"mac_rx_1519_2047_oct_pkt_num",
163 		HNS3_MAC_STATS_OFFSET(mac_rx_1519_2047_oct_pkt_num)},
164 	{"mac_rx_2048_4095_oct_pkt_num",
165 		HNS3_MAC_STATS_OFFSET(mac_rx_2048_4095_oct_pkt_num)},
166 	{"mac_rx_4096_8191_oct_pkt_num",
167 		HNS3_MAC_STATS_OFFSET(mac_rx_4096_8191_oct_pkt_num)},
168 	{"mac_rx_8192_9216_oct_pkt_num",
169 		HNS3_MAC_STATS_OFFSET(mac_rx_8192_9216_oct_pkt_num)},
170 	{"mac_rx_9217_12287_oct_pkt_num",
171 		HNS3_MAC_STATS_OFFSET(mac_rx_9217_12287_oct_pkt_num)},
172 	{"mac_rx_12288_16383_oct_pkt_num",
173 		HNS3_MAC_STATS_OFFSET(mac_rx_12288_16383_oct_pkt_num)},
174 	{"mac_rx_1519_max_good_pkt_num",
175 		HNS3_MAC_STATS_OFFSET(mac_rx_1519_max_good_oct_pkt_num)},
176 	{"mac_rx_1519_max_bad_pkt_num",
177 		HNS3_MAC_STATS_OFFSET(mac_rx_1519_max_bad_oct_pkt_num)},
178 	{"mac_tx_fragment_pkt_num",
179 		HNS3_MAC_STATS_OFFSET(mac_tx_fragment_pkt_num)},
180 	{"mac_tx_undermin_pkt_num",
181 		HNS3_MAC_STATS_OFFSET(mac_tx_undermin_pkt_num)},
182 	{"mac_tx_jabber_pkt_num",
183 		HNS3_MAC_STATS_OFFSET(mac_tx_jabber_pkt_num)},
184 	{"mac_tx_err_all_pkt_num",
185 		HNS3_MAC_STATS_OFFSET(mac_tx_err_all_pkt_num)},
186 	{"mac_tx_from_app_good_pkt_num",
187 		HNS3_MAC_STATS_OFFSET(mac_tx_from_app_good_pkt_num)},
188 	{"mac_tx_from_app_bad_pkt_num",
189 		HNS3_MAC_STATS_OFFSET(mac_tx_from_app_bad_pkt_num)},
190 	{"mac_rx_fragment_pkt_num",
191 		HNS3_MAC_STATS_OFFSET(mac_rx_fragment_pkt_num)},
192 	{"mac_rx_undermin_pkt_num",
193 		HNS3_MAC_STATS_OFFSET(mac_rx_undermin_pkt_num)},
194 	{"mac_rx_jabber_pkt_num",
195 		HNS3_MAC_STATS_OFFSET(mac_rx_jabber_pkt_num)},
196 	{"mac_rx_fcs_err_pkt_num",
197 		HNS3_MAC_STATS_OFFSET(mac_rx_fcs_err_pkt_num)},
198 	{"mac_rx_send_app_good_pkt_num",
199 		HNS3_MAC_STATS_OFFSET(mac_rx_send_app_good_pkt_num)},
200 	{"mac_rx_send_app_bad_pkt_num",
201 		HNS3_MAC_STATS_OFFSET(mac_rx_send_app_bad_pkt_num)}
202 };
203 
204 /* The statistic of reset */
205 static const struct hns3_xstats_name_offset hns3_reset_stats_strings[] = {
206 	{"REQ_RESET_CNT",
207 		HNS3_RESET_STATS_FIELD_OFFSET(request_cnt)},
208 	{"GLOBAL_RESET_CNT",
209 		HNS3_RESET_STATS_FIELD_OFFSET(global_cnt)},
210 	{"IMP_RESET_CNT",
211 		HNS3_RESET_STATS_FIELD_OFFSET(imp_cnt)},
212 	{"RESET_EXEC_CNT",
213 		HNS3_RESET_STATS_FIELD_OFFSET(exec_cnt)},
214 	{"RESET_SUCCESS_CNT",
215 		HNS3_RESET_STATS_FIELD_OFFSET(success_cnt)},
216 	{"RESET_FAIL_CNT",
217 		HNS3_RESET_STATS_FIELD_OFFSET(fail_cnt)},
218 	{"RESET_MERGE_CNT",
219 		HNS3_RESET_STATS_FIELD_OFFSET(merge_cnt)}
220 };
221 
222 /* The statistic of errors in Rx BD */
223 static const struct hns3_xstats_name_offset hns3_rx_bd_error_strings[] = {
224 	{"PKT_LEN_ERRORS",
225 		HNS3_RX_BD_ERROR_STATS_FIELD_OFFSET(pkt_len_errors)},
226 	{"L2_ERRORS",
227 		HNS3_RX_BD_ERROR_STATS_FIELD_OFFSET(l2_errors)}
228 };
229 
230 /* The dfx statistic in Rx datapath */
231 static const struct hns3_xstats_name_offset hns3_rxq_dfx_stats_strings[] = {
232 	{"L3_CHECKSUM_ERRORS",
233 		HNS3_RXQ_DFX_STATS_FIELD_OFFSET(l3_csum_errors)},
234 	{"L4_CHECKSUM_ERRORS",
235 		HNS3_RXQ_DFX_STATS_FIELD_OFFSET(l4_csum_errors)},
236 	{"OL3_CHECKSUM_ERRORS",
237 		HNS3_RXQ_DFX_STATS_FIELD_OFFSET(ol3_csum_errors)},
238 	{"OL4_CHECKSUM_ERRORS",
239 		HNS3_RXQ_DFX_STATS_FIELD_OFFSET(ol4_csum_errors)}
240 };
241 
242 /* The dfx statistic in Tx datapath */
243 static const struct hns3_xstats_name_offset hns3_txq_dfx_stats_strings[] = {
244 	{"OVER_LENGTH_PKT_CNT",
245 		HNS3_TXQ_DFX_STATS_FIELD_OFFSET(over_length_pkt_cnt)},
246 	{"EXCEED_LIMITED_BD_PKT_CNT",
247 		HNS3_TXQ_DFX_STATS_FIELD_OFFSET(exceed_limit_bd_pkt_cnt)},
248 	{"EXCEED_LIMITED_BD_PKT_REASSEMBLE_FAIL_CNT",
249 		HNS3_TXQ_DFX_STATS_FIELD_OFFSET(exceed_limit_bd_reassem_fail)},
250 	{"UNSUPPORTED_TUNNEL_PKT_CNT",
251 		HNS3_TXQ_DFX_STATS_FIELD_OFFSET(unsupported_tunnel_pkt_cnt)},
252 	{"QUEUE_FULL_CNT",
253 		HNS3_TXQ_DFX_STATS_FIELD_OFFSET(queue_full_cnt)},
254 	{"SHORT_PKT_PAD_FAIL_CNT",
255 		HNS3_TXQ_DFX_STATS_FIELD_OFFSET(pkt_padding_fail_cnt)}
256 };
257 
258 /* The statistic of rx queue */
259 static const struct hns3_xstats_name_offset hns3_rx_queue_strings[] = {
260 	{"RX_QUEUE_FBD", HNS3_RING_RX_FBDNUM_REG}
261 };
262 
263 /* The statistic of tx queue */
264 static const struct hns3_xstats_name_offset hns3_tx_queue_strings[] = {
265 	{"TX_QUEUE_FBD", HNS3_RING_TX_FBDNUM_REG}
266 };
267 
268 /* The statistic of imissed packet */
269 static const struct hns3_xstats_name_offset hns3_imissed_stats_strings[] = {
270 	{"RPU_DROP_CNT",
271 		HNS3_IMISSED_STATS_FIELD_OFFSET(rpu_rx_drop_cnt)},
272 	{"SSU_DROP_CNT",
273 		HNS3_IMISSED_STATS_FIELD_OFFSET(ssu_rx_drop_cnt)},
274 };
275 
276 #define HNS3_NUM_MAC_STATS (sizeof(hns3_mac_strings) / \
277 	sizeof(hns3_mac_strings[0]))
278 
279 #define HNS3_NUM_RESET_XSTATS (sizeof(hns3_reset_stats_strings) / \
280 	sizeof(hns3_reset_stats_strings[0]))
281 
282 #define HNS3_NUM_RX_BD_ERROR_XSTATS (sizeof(hns3_rx_bd_error_strings) / \
283 	sizeof(hns3_rx_bd_error_strings[0]))
284 
285 #define HNS3_NUM_RXQ_DFX_XSTATS (sizeof(hns3_rxq_dfx_stats_strings) / \
286 	sizeof(hns3_rxq_dfx_stats_strings[0]))
287 
288 #define HNS3_NUM_TXQ_DFX_XSTATS (sizeof(hns3_txq_dfx_stats_strings) / \
289 	sizeof(hns3_txq_dfx_stats_strings[0]))
290 
291 #define HNS3_NUM_RX_QUEUE_STATS (sizeof(hns3_rx_queue_strings) / \
292 	sizeof(hns3_rx_queue_strings[0]))
293 
294 #define HNS3_NUM_TX_QUEUE_STATS (sizeof(hns3_tx_queue_strings) / \
295 	sizeof(hns3_tx_queue_strings[0]))
296 
297 #define HNS3_NUM_RXQ_BASIC_STATS (sizeof(hns3_rxq_basic_stats_strings) / \
298 	sizeof(hns3_rxq_basic_stats_strings[0]))
299 
300 #define HNS3_NUM_TXQ_BASIC_STATS (sizeof(hns3_txq_basic_stats_strings) / \
301 	sizeof(hns3_txq_basic_stats_strings[0]))
302 
303 #define HNS3_NUM_IMISSED_XSTATS (sizeof(hns3_imissed_stats_strings) / \
304 	sizeof(hns3_imissed_stats_strings[0]))
305 
306 #define HNS3_FIX_NUM_STATS (HNS3_NUM_MAC_STATS + HNS3_NUM_RESET_XSTATS)
307 
308 static void hns3_tqp_stats_clear(struct hns3_hw *hw);
309 
310 static int
hns3_update_mac_stats(struct hns3_hw * hw)311 hns3_update_mac_stats(struct hns3_hw *hw)
312 {
313 #define HNS3_MAC_STATS_REG_NUM_PER_DESC	4
314 
315 	uint64_t *data = (uint64_t *)(&hw->mac_stats);
316 	struct hns3_cmd_desc *desc;
317 	uint32_t stats_iterms;
318 	uint64_t *desc_data;
319 	uint32_t desc_num;
320 	uint16_t i;
321 	int ret;
322 
323 	/* The first desc has a 64-bit header, so need to consider it. */
324 	desc_num = hw->mac_stats_reg_num / HNS3_MAC_STATS_REG_NUM_PER_DESC + 1;
325 	desc = rte_malloc("hns3_mac_desc",
326 			  desc_num * sizeof(struct hns3_cmd_desc), 0);
327 	if (desc == NULL) {
328 		hns3_err(hw, "Mac_update_stats alloced desc malloc fail");
329 		return -ENOMEM;
330 	}
331 
332 	hns3_cmd_setup_basic_desc(desc, HNS3_OPC_STATS_MAC_ALL, true);
333 	ret = hns3_cmd_send(hw, desc, desc_num);
334 	if (ret) {
335 		hns3_err(hw, "Update complete MAC pkt stats fail : %d", ret);
336 		rte_free(desc);
337 		return ret;
338 	}
339 
340 	stats_iterms = RTE_MIN(sizeof(hw->mac_stats) / sizeof(uint64_t),
341 			       hw->mac_stats_reg_num);
342 	desc_data = (uint64_t *)(&desc[0].data[0]);
343 	for (i = 0; i < stats_iterms; i++) {
344 		/*
345 		 * Data memory is continuous and only the first descriptor has a
346 		 * header in this command.
347 		 */
348 		*data += rte_le_to_cpu_64(*desc_data);
349 		data++;
350 		desc_data++;
351 	}
352 	rte_free(desc);
353 
354 	return 0;
355 }
356 
357 static int
hns3_mac_query_reg_num(struct hns3_hw * hw,uint32_t * reg_num)358 hns3_mac_query_reg_num(struct hns3_hw *hw, uint32_t *reg_num)
359 {
360 #define HNS3_MAC_STATS_RSV_REG_NUM_ON_HIP08_B	3
361 	struct hns3_cmd_desc desc;
362 	int ret;
363 
364 	hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_QUERY_MAC_REG_NUM, true);
365 	ret = hns3_cmd_send(hw, &desc, 1);
366 	if (ret) {
367 		hns3_err(hw, "failed to query MAC statistic reg number, ret = %d",
368 			 ret);
369 		return ret;
370 	}
371 
372 	/* The number of MAC statistics registers are provided by firmware. */
373 	*reg_num = rte_le_to_cpu_32(desc.data[0]);
374 	if (*reg_num == 0) {
375 		hns3_err(hw, "MAC statistic reg number is invalid!");
376 		return -ENODATA;
377 	}
378 
379 	/*
380 	 * If driver doesn't request the firmware to report more MAC statistics
381 	 * iterms and the total number of MAC statistics registers by using new
382 	 * method, firmware will only reports the number of valid statistics
383 	 * registers. However, structure hns3_mac_stats in driver contains valid
384 	 * and reserved statistics iterms. In this case, the total register
385 	 * number must be added to three reserved statistics registers.
386 	 */
387 	*reg_num += HNS3_MAC_STATS_RSV_REG_NUM_ON_HIP08_B;
388 
389 	return 0;
390 }
391 
392 int
hns3_query_mac_stats_reg_num(struct hns3_hw * hw)393 hns3_query_mac_stats_reg_num(struct hns3_hw *hw)
394 {
395 	uint32_t mac_stats_reg_num = 0;
396 	int ret;
397 
398 	ret = hns3_mac_query_reg_num(hw, &mac_stats_reg_num);
399 	if (ret)
400 		return ret;
401 
402 	hw->mac_stats_reg_num = mac_stats_reg_num;
403 	if (hw->mac_stats_reg_num > sizeof(hw->mac_stats) / sizeof(uint64_t))
404 		hns3_warn(hw, "MAC stats reg number from firmware is greater than stats iterms in driver.");
405 
406 	return 0;
407 }
408 
409 static int
hns3_query_update_mac_stats(struct rte_eth_dev * dev)410 hns3_query_update_mac_stats(struct rte_eth_dev *dev)
411 {
412 	struct hns3_adapter *hns = dev->data->dev_private;
413 	struct hns3_hw *hw = &hns->hw;
414 
415 	return hns3_update_mac_stats(hw);
416 }
417 
418 static int
hns3_update_port_rpu_drop_stats(struct hns3_hw * hw)419 hns3_update_port_rpu_drop_stats(struct hns3_hw *hw)
420 {
421 	struct hns3_rx_missed_stats *stats = &hw->imissed_stats;
422 	struct hns3_query_rpu_cmd *req;
423 	struct hns3_cmd_desc desc;
424 	uint64_t cnt;
425 	uint32_t tc_num;
426 	int ret;
427 
428 	hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_DFX_RPU_REG_0, true);
429 	req = (struct hns3_query_rpu_cmd *)desc.data;
430 
431 	/*
432 	 * tc_num is 0, means rpu stats of all TC channels will be
433 	 * get from firmware
434 	 */
435 	tc_num = 0;
436 	req->tc_queue_num = rte_cpu_to_le_32(tc_num);
437 	ret = hns3_cmd_send(hw, &desc, 1);
438 	if (ret) {
439 		hns3_err(hw, "failed to query RPU stats: %d", ret);
440 		return ret;
441 	}
442 
443 	cnt = rte_le_to_cpu_32(req->rpu_rx_pkt_drop_cnt);
444 	stats->rpu_rx_drop_cnt += cnt;
445 
446 	return 0;
447 }
448 
449 static void
hns3_update_function_rpu_drop_stats(struct hns3_hw * hw)450 hns3_update_function_rpu_drop_stats(struct hns3_hw *hw)
451 {
452 	struct hns3_rx_missed_stats *stats = &hw->imissed_stats;
453 
454 	stats->rpu_rx_drop_cnt += hns3_read_dev(hw, HNS3_RPU_DROP_CNT_REG);
455 }
456 
457 static int
hns3_update_rpu_drop_stats(struct hns3_hw * hw)458 hns3_update_rpu_drop_stats(struct hns3_hw *hw)
459 {
460 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
461 	int ret = 0;
462 
463 	if (hw->drop_stats_mode == HNS3_PKTS_DROP_STATS_MODE1 && !hns->is_vf)
464 		ret = hns3_update_port_rpu_drop_stats(hw);
465 	else if (hw->drop_stats_mode == HNS3_PKTS_DROP_STATS_MODE2)
466 		hns3_update_function_rpu_drop_stats(hw);
467 
468 	return ret;
469 }
470 
471 static int
hns3_get_ssu_drop_stats(struct hns3_hw * hw,struct hns3_cmd_desc * desc,int bd_num,bool is_rx)472 hns3_get_ssu_drop_stats(struct hns3_hw *hw, struct hns3_cmd_desc *desc,
473 			int bd_num, bool is_rx)
474 {
475 	struct hns3_query_ssu_cmd *req;
476 	int ret;
477 	int i;
478 
479 	for (i = 0; i < bd_num - 1; i++) {
480 		hns3_cmd_setup_basic_desc(&desc[i],
481 					  HNS3_OPC_SSU_DROP_REG, true);
482 		desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT);
483 	}
484 	hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_SSU_DROP_REG, true);
485 	req = (struct hns3_query_ssu_cmd *)desc[0].data;
486 	req->rxtx = is_rx ? 0 : 1;
487 	ret = hns3_cmd_send(hw, desc, bd_num);
488 
489 	return ret;
490 }
491 
492 static int
hns3_update_port_rx_ssu_drop_stats(struct hns3_hw * hw)493 hns3_update_port_rx_ssu_drop_stats(struct hns3_hw *hw)
494 {
495 	struct hns3_rx_missed_stats *stats = &hw->imissed_stats;
496 	struct hns3_cmd_desc desc[HNS3_OPC_SSU_DROP_REG_NUM];
497 	struct hns3_query_ssu_cmd *req;
498 	uint64_t cnt;
499 	int ret;
500 
501 	ret = hns3_get_ssu_drop_stats(hw, desc, HNS3_OPC_SSU_DROP_REG_NUM,
502 				      true);
503 	if (ret) {
504 		hns3_err(hw, "failed to get Rx SSU drop stats, ret = %d", ret);
505 		return ret;
506 	}
507 
508 	req = (struct hns3_query_ssu_cmd *)desc[0].data;
509 	cnt = rte_le_to_cpu_32(req->oq_drop_cnt) +
510 		rte_le_to_cpu_32(req->full_drop_cnt) +
511 		rte_le_to_cpu_32(req->part_drop_cnt);
512 
513 	stats->ssu_rx_drop_cnt += cnt;
514 
515 	return 0;
516 }
517 
518 static int
hns3_update_port_tx_ssu_drop_stats(struct hns3_hw * hw)519 hns3_update_port_tx_ssu_drop_stats(struct hns3_hw *hw)
520 {
521 	struct hns3_cmd_desc desc[HNS3_OPC_SSU_DROP_REG_NUM];
522 	struct hns3_query_ssu_cmd *req;
523 	uint64_t cnt;
524 	int ret;
525 
526 	ret = hns3_get_ssu_drop_stats(hw, desc, HNS3_OPC_SSU_DROP_REG_NUM,
527 				      false);
528 	if (ret) {
529 		hns3_err(hw, "failed to get Tx SSU drop stats, ret = %d", ret);
530 		return ret;
531 	}
532 
533 	req = (struct hns3_query_ssu_cmd *)desc[0].data;
534 	cnt = rte_le_to_cpu_32(req->oq_drop_cnt) +
535 		rte_le_to_cpu_32(req->full_drop_cnt) +
536 		rte_le_to_cpu_32(req->part_drop_cnt);
537 
538 	hw->oerror_stats += cnt;
539 
540 	return 0;
541 }
542 
543 static int
hns3_update_imissed_stats(struct hns3_hw * hw,bool is_clear)544 hns3_update_imissed_stats(struct hns3_hw *hw, bool is_clear)
545 {
546 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
547 	int ret;
548 
549 	if (hw->drop_stats_mode == HNS3_PKTS_DROP_STATS_MODE1 && hns->is_vf)
550 		return 0;
551 
552 	if (hw->drop_stats_mode == HNS3_PKTS_DROP_STATS_MODE2 && !hns->is_vf) {
553 		ret = hns3_update_port_rx_ssu_drop_stats(hw);
554 		if (ret)
555 			return ret;
556 	}
557 
558 	ret = hns3_update_rpu_drop_stats(hw);
559 	if (ret)
560 		return ret;
561 
562 	if (is_clear)
563 		memset(&hw->imissed_stats, 0, sizeof(hw->imissed_stats));
564 
565 	return 0;
566 }
567 
568 static int
hns3_update_oerror_stats(struct hns3_hw * hw,bool is_clear)569 hns3_update_oerror_stats(struct hns3_hw *hw, bool is_clear)
570 {
571 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
572 	int ret;
573 
574 	if (hw->drop_stats_mode == HNS3_PKTS_DROP_STATS_MODE1 || hns->is_vf)
575 		return 0;
576 
577 	ret = hns3_update_port_tx_ssu_drop_stats(hw);
578 	if (ret)
579 		return ret;
580 
581 	if (is_clear)
582 		hw->oerror_stats = 0;
583 
584 	return 0;
585 }
586 
587 static void
hns3_rcb_rx_ring_stats_get(struct hns3_rx_queue * rxq,struct hns3_tqp_stats * stats)588 hns3_rcb_rx_ring_stats_get(struct hns3_rx_queue *rxq,
589 			   struct hns3_tqp_stats *stats)
590 {
591 	uint32_t cnt;
592 
593 	cnt = hns3_read_dev(rxq, HNS3_RING_RX_PKTNUM_RECORD_REG);
594 	stats->rcb_rx_ring_pktnum_rcd += cnt;
595 	stats->rcb_rx_ring_pktnum[rxq->queue_id] += cnt;
596 }
597 
598 static void
hns3_rcb_tx_ring_stats_get(struct hns3_tx_queue * txq,struct hns3_tqp_stats * stats)599 hns3_rcb_tx_ring_stats_get(struct hns3_tx_queue *txq,
600 			   struct hns3_tqp_stats *stats)
601 {
602 	uint32_t cnt;
603 
604 	cnt = hns3_read_dev(txq, HNS3_RING_TX_PKTNUM_RECORD_REG);
605 	stats->rcb_tx_ring_pktnum_rcd += cnt;
606 	stats->rcb_tx_ring_pktnum[txq->queue_id] += cnt;
607 }
608 
609 /*
610  * Query tqp tx queue statistics ,opcode id: 0x0B03.
611  * Query tqp rx queue statistics ,opcode id: 0x0B13.
612  * Get all statistics of a port.
613  * @param eth_dev
614  *   Pointer to Ethernet device.
615  * @praram rte_stats
616  *   Pointer to structure rte_eth_stats.
617  * @return
618  *   0 on success.
619  */
620 int
hns3_stats_get(struct rte_eth_dev * eth_dev,struct rte_eth_stats * rte_stats)621 hns3_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *rte_stats)
622 {
623 	struct hns3_adapter *hns = eth_dev->data->dev_private;
624 	struct hns3_hw *hw = &hns->hw;
625 	struct hns3_rx_missed_stats *imissed_stats = &hw->imissed_stats;
626 	struct hns3_tqp_stats *stats = &hw->tqp_stats;
627 	struct hns3_rx_queue *rxq;
628 	struct hns3_tx_queue *txq;
629 	uint16_t i;
630 	int ret;
631 
632 	/* Update imissed stats */
633 	ret = hns3_update_imissed_stats(hw, false);
634 	if (ret) {
635 		hns3_err(hw, "update imissed stats failed, ret = %d", ret);
636 		goto out;
637 	}
638 	rte_stats->imissed = imissed_stats->rpu_rx_drop_cnt +
639 				imissed_stats->ssu_rx_drop_cnt;
640 
641 	/* Get the error stats and bytes of received packets */
642 	for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
643 		rxq = eth_dev->data->rx_queues[i];
644 		if (rxq == NULL)
645 			continue;
646 
647 		rte_spinlock_lock(&hw->stats_lock);
648 		hns3_rcb_rx_ring_stats_get(rxq, stats);
649 		rte_spinlock_unlock(&hw->stats_lock);
650 
651 		rte_stats->ierrors += rxq->err_stats.l2_errors +
652 				      rxq->err_stats.pkt_len_errors;
653 		rte_stats->ibytes += rxq->basic_stats.bytes;
654 	}
655 
656 	/* Reads all the stats of a txq in a loop to keep them synchronized */
657 	for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
658 		txq = eth_dev->data->tx_queues[i];
659 		if (txq == NULL)
660 			continue;
661 
662 		rte_spinlock_lock(&hw->stats_lock);
663 		hns3_rcb_tx_ring_stats_get(txq, stats);
664 		rte_spinlock_unlock(&hw->stats_lock);
665 		rte_stats->obytes += txq->basic_stats.bytes;
666 	}
667 
668 	ret = hns3_update_oerror_stats(hw, false);
669 	if (ret) {
670 		hns3_err(hw, "update oerror stats failed, ret = %d", ret);
671 		goto out;
672 	}
673 	rte_stats->oerrors = hw->oerror_stats;
674 
675 	/*
676 	 * If HW statistics are reset by stats_reset, but a lot of residual
677 	 * packets exist in the hardware queue and these packets are error
678 	 * packets, flip overflow may occurred. So return 0 in this case.
679 	 */
680 	rte_stats->ipackets =
681 		stats->rcb_rx_ring_pktnum_rcd > rte_stats->ierrors ?
682 		stats->rcb_rx_ring_pktnum_rcd - rte_stats->ierrors : 0;
683 	rte_stats->opackets  = stats->rcb_tx_ring_pktnum_rcd -
684 		rte_stats->oerrors;
685 	rte_stats->rx_nombuf = eth_dev->data->rx_mbuf_alloc_failed;
686 out:
687 	return ret;
688 }
689 
690 int
hns3_stats_reset(struct rte_eth_dev * eth_dev)691 hns3_stats_reset(struct rte_eth_dev *eth_dev)
692 {
693 	struct hns3_adapter *hns = eth_dev->data->dev_private;
694 	struct hns3_hw *hw = &hns->hw;
695 	struct hns3_rx_queue *rxq;
696 	struct hns3_tx_queue *txq;
697 	uint16_t i;
698 	int ret;
699 
700 	/*
701 	 * Note: Reading hardware statistics of imissed registers will
702 	 * clear them.
703 	 */
704 	ret = hns3_update_imissed_stats(hw, true);
705 	if (ret) {
706 		hns3_err(hw, "clear imissed stats failed, ret = %d", ret);
707 		goto out;
708 	}
709 
710 	/*
711 	 * Note: Reading hardware statistics of oerror registers will
712 	 * clear them.
713 	 */
714 	ret = hns3_update_oerror_stats(hw, true);
715 	if (ret) {
716 		hns3_err(hw, "clear oerror stats failed, ret = %d", ret);
717 		goto out;
718 	}
719 
720 	for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
721 		rxq = eth_dev->data->rx_queues[i];
722 		if (rxq == NULL)
723 			continue;
724 
725 		rxq->err_stats.pkt_len_errors = 0;
726 		rxq->err_stats.l2_errors = 0;
727 	}
728 
729 	/* Clear all the stats of a rxq in a loop to keep them synchronized */
730 	for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
731 		rxq = eth_dev->data->rx_queues[i];
732 		if (rxq == NULL)
733 			continue;
734 
735 		rte_spinlock_lock(&hw->stats_lock);
736 		memset(&rxq->basic_stats, 0,
737 				sizeof(struct hns3_rx_basic_stats));
738 
739 		/* This register is read-clear */
740 		(void)hns3_read_dev(rxq, HNS3_RING_RX_PKTNUM_RECORD_REG);
741 		rxq->err_stats.pkt_len_errors = 0;
742 		rxq->err_stats.l2_errors = 0;
743 		rte_spinlock_unlock(&hw->stats_lock);
744 	}
745 
746 	/* Clear all the stats of a txq in a loop to keep them synchronized */
747 	for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
748 		txq = eth_dev->data->tx_queues[i];
749 		if (txq == NULL)
750 			continue;
751 
752 		rte_spinlock_lock(&hw->stats_lock);
753 		memset(&txq->basic_stats, 0,
754 				sizeof(struct hns3_tx_basic_stats));
755 
756 		/* This register is read-clear */
757 		(void)hns3_read_dev(txq, HNS3_RING_TX_PKTNUM_RECORD_REG);
758 		rte_spinlock_unlock(&hw->stats_lock);
759 	}
760 
761 	rte_spinlock_lock(&hw->stats_lock);
762 	hns3_tqp_stats_clear(hw);
763 	rte_spinlock_unlock(&hw->stats_lock);
764 out:
765 	return ret;
766 }
767 
768 static int
hns3_mac_stats_reset(__rte_unused struct rte_eth_dev * dev)769 hns3_mac_stats_reset(__rte_unused struct rte_eth_dev *dev)
770 {
771 	struct hns3_adapter *hns = dev->data->dev_private;
772 	struct hns3_hw *hw = &hns->hw;
773 	struct hns3_mac_stats *mac_stats = &hw->mac_stats;
774 	int ret;
775 
776 	ret = hns3_query_update_mac_stats(dev);
777 	if (ret) {
778 		hns3_err(hw, "Clear Mac stats fail : %d", ret);
779 		return ret;
780 	}
781 
782 	memset(mac_stats, 0, sizeof(struct hns3_mac_stats));
783 
784 	return 0;
785 }
786 
787 static int
hns3_get_imissed_stats_num(struct hns3_adapter * hns)788 hns3_get_imissed_stats_num(struct hns3_adapter *hns)
789 {
790 #define NO_IMISSED_STATS_NUM   0
791 #define RPU_STATS_ITEM_NUM     1
792 	struct hns3_hw *hw = &hns->hw;
793 
794 	if (hw->drop_stats_mode == HNS3_PKTS_DROP_STATS_MODE1 && hns->is_vf)
795 		return NO_IMISSED_STATS_NUM;
796 
797 	if (hw->drop_stats_mode == HNS3_PKTS_DROP_STATS_MODE2 && !hns->is_vf)
798 		return HNS3_NUM_IMISSED_XSTATS;
799 
800 	return RPU_STATS_ITEM_NUM;
801 }
802 
803 /* This function calculates the number of xstats based on the current config */
804 static int
hns3_xstats_calc_num(struct rte_eth_dev * dev)805 hns3_xstats_calc_num(struct rte_eth_dev *dev)
806 {
807 #define HNS3_PF_VF_RX_COMM_STATS_NUM	(HNS3_NUM_RX_BD_ERROR_XSTATS + \
808 					 HNS3_NUM_RXQ_DFX_XSTATS + \
809 					 HNS3_NUM_RX_QUEUE_STATS + \
810 					 HNS3_NUM_RXQ_BASIC_STATS)
811 #define HNS3_PF_VF_TX_COMM_STATS_NUM	(HNS3_NUM_TXQ_DFX_XSTATS + \
812 					 HNS3_NUM_TX_QUEUE_STATS + \
813 					 HNS3_NUM_TXQ_BASIC_STATS)
814 
815 	struct hns3_adapter *hns = dev->data->dev_private;
816 	uint16_t nb_rx_q = dev->data->nb_rx_queues;
817 	uint16_t nb_tx_q = dev->data->nb_tx_queues;
818 	int rx_comm_stats_num = nb_rx_q * HNS3_PF_VF_RX_COMM_STATS_NUM;
819 	int tx_comm_stats_num = nb_tx_q * HNS3_PF_VF_TX_COMM_STATS_NUM;
820 	int stats_num;
821 
822 	stats_num = rx_comm_stats_num + tx_comm_stats_num;
823 	stats_num += hns3_get_imissed_stats_num(hns);
824 
825 	if (hns->is_vf)
826 		stats_num += HNS3_NUM_RESET_XSTATS;
827 	else
828 		stats_num += HNS3_FIX_NUM_STATS;
829 
830 	return stats_num;
831 }
832 
833 static void
hns3_queue_stats_get(struct rte_eth_dev * dev,struct rte_eth_xstat * xstats,int * count)834 hns3_queue_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
835 		     int *count)
836 {
837 	struct hns3_adapter *hns = dev->data->dev_private;
838 	struct hns3_hw *hw = &hns->hw;
839 	uint32_t reg_offset;
840 	uint16_t i, j;
841 
842 	/* Get rx queue stats */
843 	for (j = 0; j < dev->data->nb_rx_queues; j++) {
844 		for (i = 0; i < HNS3_NUM_RX_QUEUE_STATS; i++) {
845 			reg_offset = hns3_get_tqp_reg_offset(j);
846 			xstats[*count].value = hns3_read_dev(hw,
847 				reg_offset + hns3_rx_queue_strings[i].offset);
848 			xstats[*count].id = *count;
849 			(*count)++;
850 		}
851 	}
852 
853 	/* Get tx queue stats */
854 	for (j = 0; j < dev->data->nb_tx_queues; j++) {
855 		for (i = 0; i < HNS3_NUM_TX_QUEUE_STATS; i++) {
856 			reg_offset = hns3_get_tqp_reg_offset(j);
857 			xstats[*count].value = hns3_read_dev(hw,
858 				reg_offset + hns3_tx_queue_strings[i].offset);
859 			xstats[*count].id = *count;
860 			(*count)++;
861 		}
862 	}
863 }
864 
865 static void
hns3_rxq_dfx_stats_get(struct rte_eth_dev * dev,struct rte_eth_xstat * xstats,int * count)866 hns3_rxq_dfx_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
867 		       int *count)
868 {
869 	struct hns3_rx_dfx_stats *dfx_stats;
870 	struct hns3_rx_queue *rxq;
871 	uint16_t i, j;
872 	char *val;
873 
874 	for (i = 0; i < dev->data->nb_rx_queues; i++) {
875 		rxq = (struct hns3_rx_queue *)dev->data->rx_queues[i];
876 		if (rxq == NULL)
877 			continue;
878 
879 		dfx_stats = &rxq->dfx_stats;
880 		for (j = 0; j < HNS3_NUM_RXQ_DFX_XSTATS; j++) {
881 			val = (char *)dfx_stats +
882 				hns3_rxq_dfx_stats_strings[j].offset;
883 			xstats[*count].value = *(uint64_t *)val;
884 			xstats[*count].id = *count;
885 			(*count)++;
886 		}
887 	}
888 }
889 
890 static void
hns3_txq_dfx_stats_get(struct rte_eth_dev * dev,struct rte_eth_xstat * xstats,int * count)891 hns3_txq_dfx_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
892 		       int *count)
893 {
894 	struct hns3_tx_dfx_stats *dfx_stats;
895 	struct hns3_tx_queue *txq;
896 	uint16_t i, j;
897 	char *val;
898 
899 	for (i = 0; i < dev->data->nb_tx_queues; i++) {
900 		txq = (struct hns3_tx_queue *)dev->data->tx_queues[i];
901 		if (txq == NULL)
902 			continue;
903 
904 		dfx_stats = &txq->dfx_stats;
905 		for (j = 0; j < HNS3_NUM_TXQ_DFX_XSTATS; j++) {
906 			val = (char *)dfx_stats +
907 				hns3_txq_dfx_stats_strings[j].offset;
908 			xstats[*count].value = *(uint64_t *)val;
909 			xstats[*count].id = *count;
910 			(*count)++;
911 		}
912 	}
913 }
914 
915 static void
hns3_tqp_dfx_stats_get(struct rte_eth_dev * dev,struct rte_eth_xstat * xstats,int * count)916 hns3_tqp_dfx_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
917 		       int *count)
918 {
919 	hns3_rxq_dfx_stats_get(dev, xstats, count);
920 	hns3_txq_dfx_stats_get(dev, xstats, count);
921 }
922 
923 static void
hns3_rxq_basic_stats_get(struct rte_eth_dev * dev,struct rte_eth_xstat * xstats,int * count)924 hns3_rxq_basic_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
925 			 int *count)
926 {
927 	struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
928 	struct hns3_tqp_stats *stats = &hw->tqp_stats;
929 	struct hns3_rx_basic_stats *rxq_stats;
930 	struct hns3_rx_queue *rxq;
931 	uint16_t i, j;
932 	char *val;
933 
934 	for (i = 0; i < dev->data->nb_rx_queues; i++) {
935 		rxq = dev->data->rx_queues[i];
936 		if (rxq == NULL)
937 			continue;
938 
939 		hns3_rcb_rx_ring_stats_get(rxq, stats);
940 		rxq_stats = &rxq->basic_stats;
941 		rxq_stats->errors = rxq->err_stats.l2_errors +
942 					rxq->err_stats.pkt_len_errors;
943 
944 		/*
945 		 * If HW statistics are reset by stats_reset, but a lot of
946 		 * residual packets exist in the hardware queue and these
947 		 * packets are error packets, flip overflow may occurred.
948 		 * So return 0 in this case.
949 		 */
950 		rxq_stats->packets =
951 			stats->rcb_rx_ring_pktnum[i] > rxq_stats->errors ?
952 			stats->rcb_rx_ring_pktnum[i] - rxq_stats->errors : 0;
953 		for (j = 0; j < HNS3_NUM_RXQ_BASIC_STATS; j++) {
954 			val = (char *)rxq_stats +
955 				hns3_rxq_basic_stats_strings[j].offset;
956 			xstats[*count].value = *(uint64_t *)val;
957 			xstats[*count].id = *count;
958 			(*count)++;
959 		}
960 	}
961 }
962 
963 static void
hns3_txq_basic_stats_get(struct rte_eth_dev * dev,struct rte_eth_xstat * xstats,int * count)964 hns3_txq_basic_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
965 			 int *count)
966 {
967 	struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
968 	struct hns3_tqp_stats *stats = &hw->tqp_stats;
969 	struct hns3_tx_basic_stats *txq_stats;
970 	struct hns3_tx_queue *txq;
971 	uint16_t i, j;
972 	char *val;
973 
974 	for (i = 0; i < dev->data->nb_tx_queues; i++) {
975 		txq = dev->data->tx_queues[i];
976 		if (txq == NULL)
977 			continue;
978 
979 		hns3_rcb_tx_ring_stats_get(txq, stats);
980 
981 		txq_stats = &txq->basic_stats;
982 		txq_stats->packets = stats->rcb_tx_ring_pktnum[i];
983 
984 		for (j = 0; j < HNS3_NUM_TXQ_BASIC_STATS; j++) {
985 			val = (char *)txq_stats +
986 				hns3_txq_basic_stats_strings[j].offset;
987 			xstats[*count].value = *(uint64_t *)val;
988 			xstats[*count].id = *count;
989 			(*count)++;
990 		}
991 	}
992 }
993 
994 static void
hns3_tqp_basic_stats_get(struct rte_eth_dev * dev,struct rte_eth_xstat * xstats,int * count)995 hns3_tqp_basic_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
996 			 int *count)
997 {
998 	hns3_rxq_basic_stats_get(dev, xstats, count);
999 	hns3_txq_basic_stats_get(dev, xstats, count);
1000 }
1001 
1002 static void
hns3_imissed_stats_get(struct rte_eth_dev * dev,struct rte_eth_xstat * xstats,int * count)1003 hns3_imissed_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
1004 			  int *count)
1005 {
1006 	struct hns3_adapter *hns = dev->data->dev_private;
1007 	struct hns3_hw *hw = &hns->hw;
1008 	struct hns3_rx_missed_stats *imissed_stats = &hw->imissed_stats;
1009 	int imissed_stats_num;
1010 	int cnt = *count;
1011 	char *addr;
1012 	uint16_t i;
1013 
1014 	imissed_stats_num = hns3_get_imissed_stats_num(hns);
1015 
1016 	for (i = 0; i < imissed_stats_num; i++) {
1017 		addr = (char *)imissed_stats +
1018 			hns3_imissed_stats_strings[i].offset;
1019 		xstats[cnt].value = *(uint64_t *)addr;
1020 		xstats[cnt].id = cnt;
1021 		cnt++;
1022 	}
1023 
1024 	*count = cnt;
1025 }
1026 
1027 /*
1028  * Retrieve extended(tqp | Mac) statistics of an Ethernet device.
1029  * @param dev
1030  *   Pointer to Ethernet device.
1031  * @praram xstats
1032  *   A pointer to a table of structure of type *rte_eth_xstat*
1033  *   to be filled with device statistics ids and values.
1034  *   This parameter can be set to NULL if n is 0.
1035  * @param n
1036  *   The size of the xstats array (number of elements).
1037  * @return
1038  *   0 on fail, count(The size of the statistics elements) on success.
1039  */
1040 int
hns3_dev_xstats_get(struct rte_eth_dev * dev,struct rte_eth_xstat * xstats,unsigned int n)1041 hns3_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
1042 		    unsigned int n)
1043 {
1044 	struct hns3_adapter *hns = dev->data->dev_private;
1045 	struct hns3_hw *hw = &hns->hw;
1046 	struct hns3_mac_stats *mac_stats = &hw->mac_stats;
1047 	struct hns3_reset_stats *reset_stats = &hw->reset.stats;
1048 	struct hns3_rx_bd_errors_stats *rx_err_stats;
1049 	struct hns3_rx_queue *rxq;
1050 	uint16_t i, j;
1051 	char *addr;
1052 	int count;
1053 	int ret;
1054 
1055 	if (xstats == NULL)
1056 		return 0;
1057 
1058 	count = hns3_xstats_calc_num(dev);
1059 	if ((int)n < count)
1060 		return count;
1061 
1062 	count = 0;
1063 
1064 	rte_spinlock_lock(&hw->stats_lock);
1065 	hns3_tqp_basic_stats_get(dev, xstats, &count);
1066 
1067 	if (!hns->is_vf) {
1068 		/* Update Mac stats */
1069 		ret = hns3_query_update_mac_stats(dev);
1070 		if (ret < 0) {
1071 			hns3_err(hw, "Update Mac stats fail : %d", ret);
1072 			rte_spinlock_unlock(&hw->stats_lock);
1073 			return ret;
1074 		}
1075 
1076 		/* Get MAC stats from hw->hw_xstats.mac_stats struct */
1077 		for (i = 0; i < HNS3_NUM_MAC_STATS; i++) {
1078 			addr = (char *)mac_stats + hns3_mac_strings[i].offset;
1079 			xstats[count].value = *(uint64_t *)addr;
1080 			xstats[count].id = count;
1081 			count++;
1082 		}
1083 	}
1084 	rte_spinlock_unlock(&hw->stats_lock);
1085 
1086 	ret = hns3_update_imissed_stats(hw, false);
1087 	if (ret) {
1088 		hns3_err(hw, "update imissed stats failed, ret = %d", ret);
1089 		return ret;
1090 	}
1091 
1092 	hns3_imissed_stats_get(dev, xstats, &count);
1093 
1094 	/* Get the reset stat */
1095 	for (i = 0; i < HNS3_NUM_RESET_XSTATS; i++) {
1096 		addr = (char *)reset_stats + hns3_reset_stats_strings[i].offset;
1097 		xstats[count].value = *(uint64_t *)addr;
1098 		xstats[count].id = count;
1099 		count++;
1100 	}
1101 
1102 	/* Get the Rx BD errors stats */
1103 	for (j = 0; j < dev->data->nb_rx_queues; j++) {
1104 		for (i = 0; i < HNS3_NUM_RX_BD_ERROR_XSTATS; i++) {
1105 			rxq = dev->data->rx_queues[j];
1106 			if (rxq) {
1107 				rx_err_stats = &rxq->err_stats;
1108 				addr = (char *)rx_err_stats +
1109 					hns3_rx_bd_error_strings[i].offset;
1110 				xstats[count].value = *(uint64_t *)addr;
1111 				xstats[count].id = count;
1112 				count++;
1113 			}
1114 		}
1115 	}
1116 
1117 	rte_spinlock_lock(&hw->stats_lock);
1118 	hns3_tqp_dfx_stats_get(dev, xstats, &count);
1119 	hns3_queue_stats_get(dev, xstats, &count);
1120 	rte_spinlock_unlock(&hw->stats_lock);
1121 
1122 	return count;
1123 }
1124 
1125 static void
hns3_tqp_basic_stats_name_get(struct rte_eth_dev * dev,struct rte_eth_xstat_name * xstats_names,uint32_t * count)1126 hns3_tqp_basic_stats_name_get(struct rte_eth_dev *dev,
1127 			      struct rte_eth_xstat_name *xstats_names,
1128 			      uint32_t *count)
1129 {
1130 	uint16_t i, j;
1131 
1132 	for (i = 0; i < dev->data->nb_rx_queues; i++) {
1133 		for (j = 0; j < HNS3_NUM_RXQ_BASIC_STATS; j++) {
1134 			snprintf(xstats_names[*count].name,
1135 				 sizeof(xstats_names[*count].name),
1136 				 "rx_q%u_%s", i,
1137 				 hns3_rxq_basic_stats_strings[j].name);
1138 			(*count)++;
1139 		}
1140 	}
1141 	for (i = 0; i < dev->data->nb_tx_queues; i++) {
1142 		for (j = 0; j < HNS3_NUM_TXQ_BASIC_STATS; j++) {
1143 			snprintf(xstats_names[*count].name,
1144 				 sizeof(xstats_names[*count].name),
1145 				 "tx_q%u_%s", i,
1146 				 hns3_txq_basic_stats_strings[j].name);
1147 			(*count)++;
1148 		}
1149 	}
1150 }
1151 
1152 static void
hns3_tqp_dfx_stats_name_get(struct rte_eth_dev * dev,struct rte_eth_xstat_name * xstats_names,uint32_t * count)1153 hns3_tqp_dfx_stats_name_get(struct rte_eth_dev *dev,
1154 			    struct rte_eth_xstat_name *xstats_names,
1155 			    uint32_t *count)
1156 {
1157 	uint16_t i, j;
1158 
1159 	for (i = 0; i < dev->data->nb_rx_queues; i++) {
1160 		for (j = 0; j < HNS3_NUM_RXQ_DFX_XSTATS; j++) {
1161 			snprintf(xstats_names[*count].name,
1162 				 sizeof(xstats_names[*count].name),
1163 				 "rx_q%u_%s", i,
1164 				 hns3_rxq_dfx_stats_strings[j].name);
1165 			(*count)++;
1166 		}
1167 	}
1168 
1169 	for (i = 0; i < dev->data->nb_tx_queues; i++) {
1170 		for (j = 0; j < HNS3_NUM_TXQ_DFX_XSTATS; j++) {
1171 			snprintf(xstats_names[*count].name,
1172 				 sizeof(xstats_names[*count].name),
1173 				 "tx_q%u_%s", i,
1174 				 hns3_txq_dfx_stats_strings[j].name);
1175 			(*count)++;
1176 		}
1177 	}
1178 }
1179 
1180 static void
hns3_imissed_stats_name_get(struct rte_eth_dev * dev,struct rte_eth_xstat_name * xstats_names,uint32_t * count)1181 hns3_imissed_stats_name_get(struct rte_eth_dev *dev,
1182 			    struct rte_eth_xstat_name *xstats_names,
1183 			    uint32_t *count)
1184 {
1185 	struct hns3_adapter *hns = dev->data->dev_private;
1186 	uint32_t cnt = *count;
1187 	int imissed_stats_num;
1188 	uint16_t i;
1189 
1190 	imissed_stats_num = hns3_get_imissed_stats_num(hns);
1191 
1192 	for (i = 0; i < imissed_stats_num; i++) {
1193 		snprintf(xstats_names[cnt].name,
1194 			 sizeof(xstats_names[cnt].name),
1195 			 "%s", hns3_imissed_stats_strings[i].name);
1196 		cnt++;
1197 	}
1198 
1199 	*count = cnt;
1200 }
1201 
1202 /*
1203  * Retrieve names of extended statistics of an Ethernet device.
1204  *
1205  * There is an assumption that 'xstat_names' and 'xstats' arrays are matched
1206  * by array index:
1207  *  xstats_names[i].name => xstats[i].value
1208  *
1209  * And the array index is same with id field of 'struct rte_eth_xstat':
1210  *  xstats[i].id == i
1211  *
1212  * This assumption makes key-value pair matching less flexible but simpler.
1213  *
1214  * @param dev
1215  *   Pointer to Ethernet device.
1216  * @param xstats_names
1217  *   An rte_eth_xstat_name array of at least *size* elements to
1218  *   be filled. If set to NULL, the function returns the required number
1219  *   of elements.
1220  * @param size
1221  *   The size of the xstats_names array (number of elements).
1222  * @return
1223  *   - A positive value lower or equal to size: success. The return value
1224  *     is the number of entries filled in the stats table.
1225  */
1226 int
hns3_dev_xstats_get_names(struct rte_eth_dev * dev,struct rte_eth_xstat_name * xstats_names,__rte_unused unsigned int size)1227 hns3_dev_xstats_get_names(struct rte_eth_dev *dev,
1228 			  struct rte_eth_xstat_name *xstats_names,
1229 			  __rte_unused unsigned int size)
1230 {
1231 	struct hns3_adapter *hns = dev->data->dev_private;
1232 	int cnt_stats = hns3_xstats_calc_num(dev);
1233 	uint32_t count = 0;
1234 	uint16_t i, j;
1235 
1236 	if (xstats_names == NULL)
1237 		return cnt_stats;
1238 
1239 	hns3_tqp_basic_stats_name_get(dev, xstats_names, &count);
1240 
1241 	/* Note: size limited checked in rte_eth_xstats_get_names() */
1242 	if (!hns->is_vf) {
1243 		/* Get MAC name from hw->hw_xstats.mac_stats struct */
1244 		for (i = 0; i < HNS3_NUM_MAC_STATS; i++) {
1245 			snprintf(xstats_names[count].name,
1246 				 sizeof(xstats_names[count].name),
1247 				 "%s", hns3_mac_strings[i].name);
1248 			count++;
1249 		}
1250 	}
1251 
1252 	hns3_imissed_stats_name_get(dev, xstats_names, &count);
1253 
1254 	for (i = 0; i < HNS3_NUM_RESET_XSTATS; i++) {
1255 		snprintf(xstats_names[count].name,
1256 			 sizeof(xstats_names[count].name),
1257 			 "%s", hns3_reset_stats_strings[i].name);
1258 		count++;
1259 	}
1260 
1261 	for (j = 0; j < dev->data->nb_rx_queues; j++) {
1262 		for (i = 0; i < HNS3_NUM_RX_BD_ERROR_XSTATS; i++) {
1263 			snprintf(xstats_names[count].name,
1264 				 sizeof(xstats_names[count].name),
1265 				 "rx_q%u_%s", j,
1266 				 hns3_rx_bd_error_strings[i].name);
1267 			count++;
1268 		}
1269 	}
1270 
1271 	hns3_tqp_dfx_stats_name_get(dev, xstats_names, &count);
1272 
1273 	for (j = 0; j < dev->data->nb_rx_queues; j++) {
1274 		for (i = 0; i < HNS3_NUM_RX_QUEUE_STATS; i++) {
1275 			snprintf(xstats_names[count].name,
1276 				 sizeof(xstats_names[count].name),
1277 				 "rx_q%u_%s", j, hns3_rx_queue_strings[i].name);
1278 			count++;
1279 		}
1280 	}
1281 
1282 	for (j = 0; j < dev->data->nb_tx_queues; j++) {
1283 		for (i = 0; i < HNS3_NUM_TX_QUEUE_STATS; i++) {
1284 			snprintf(xstats_names[count].name,
1285 				 sizeof(xstats_names[count].name),
1286 				 "tx_q%u_%s", j, hns3_tx_queue_strings[i].name);
1287 			count++;
1288 		}
1289 	}
1290 
1291 	return count;
1292 }
1293 
1294 /*
1295  * Retrieve extended statistics of an Ethernet device.
1296  *
1297  * @param dev
1298  *   Pointer to Ethernet device.
1299  * @param ids
1300  *   A pointer to an ids array passed by application. This tells which
1301  *   statistics values function should retrieve. This parameter
1302  *   can be set to NULL if size is 0. In this case function will retrieve
1303  *   all available statistics.
1304  * @param values
1305  *   A pointer to a table to be filled with device statistics values.
1306  * @param size
1307  *   The size of the ids array (number of elements).
1308  * @return
1309  *   - A positive value lower or equal to size: success. The return value
1310  *     is the number of entries filled in the stats table.
1311  *   - A positive value higher than size: error, the given statistics table
1312  *     is too small. The return value corresponds to the size that should
1313  *     be given to succeed. The entries in the table are not valid and
1314  *     shall not be used by the caller.
1315  *   - 0 on no ids.
1316  */
1317 int
hns3_dev_xstats_get_by_id(struct rte_eth_dev * dev,const uint64_t * ids,uint64_t * values,uint32_t size)1318 hns3_dev_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids,
1319 			  uint64_t *values, uint32_t size)
1320 {
1321 	const uint32_t cnt_stats = hns3_xstats_calc_num(dev);
1322 	struct hns3_adapter *hns = dev->data->dev_private;
1323 	struct rte_eth_xstat *values_copy;
1324 	struct hns3_hw *hw = &hns->hw;
1325 	uint32_t count_value;
1326 	uint64_t len;
1327 	uint32_t i;
1328 
1329 	if (ids == NULL && values == NULL)
1330 		return cnt_stats;
1331 
1332 	if (ids == NULL)
1333 		if (size < cnt_stats)
1334 			return cnt_stats;
1335 
1336 	len = cnt_stats * sizeof(struct rte_eth_xstat);
1337 	values_copy = rte_zmalloc("hns3_xstats_values", len, 0);
1338 	if (values_copy == NULL) {
1339 		hns3_err(hw, "Failed to allocate 0x%" PRIx64 " bytes needed "
1340 			     "to store statistics values", len);
1341 		return -ENOMEM;
1342 	}
1343 
1344 	count_value = hns3_dev_xstats_get(dev, values_copy, cnt_stats);
1345 	if (count_value != cnt_stats) {
1346 		rte_free(values_copy);
1347 		return -EINVAL;
1348 	}
1349 
1350 	if (ids == NULL && values != NULL) {
1351 		for (i = 0; i < cnt_stats; i++)
1352 			memcpy(&values[i], &values_copy[i].value,
1353 			       sizeof(values[i]));
1354 
1355 		rte_free(values_copy);
1356 		return cnt_stats;
1357 	}
1358 
1359 	for (i = 0; i < size; i++) {
1360 		if (ids[i] >= cnt_stats) {
1361 			hns3_err(hw, "ids[%u] (%" PRIu64 ") is invalid, "
1362 				     "should < %u", i, ids[i], cnt_stats);
1363 			rte_free(values_copy);
1364 			return -EINVAL;
1365 		}
1366 		memcpy(&values[i], &values_copy[ids[i]].value,
1367 			sizeof(values[i]));
1368 	}
1369 
1370 	rte_free(values_copy);
1371 	return size;
1372 }
1373 
1374 /*
1375  * Retrieve names of extended statistics of an Ethernet device.
1376  *
1377  * @param dev
1378  *   Pointer to Ethernet device.
1379  * @param ids
1380  *   IDs array given by app to retrieve specific statistics
1381  * @param xstats_names
1382  *   An rte_eth_xstat_name array of at least *size* elements to
1383  *   be filled. If set to NULL, the function returns the required number
1384  *   of elements.
1385  * @param size
1386  *   The size of the xstats_names array (number of elements).
1387  * @return
1388  *   - A positive value lower or equal to size: success. The return value
1389  *     is the number of entries filled in the stats table.
1390  *   - A positive value higher than size: error, the given statistics table
1391  *     is too small. The return value corresponds to the size that should
1392  *     be given to succeed. The entries in the table are not valid and
1393  *     shall not be used by the caller.
1394  */
1395 int
hns3_dev_xstats_get_names_by_id(struct rte_eth_dev * dev,const uint64_t * ids,struct rte_eth_xstat_name * xstats_names,uint32_t size)1396 hns3_dev_xstats_get_names_by_id(struct rte_eth_dev *dev,
1397 				const uint64_t *ids,
1398 				struct rte_eth_xstat_name *xstats_names,
1399 				uint32_t size)
1400 {
1401 	const uint32_t cnt_stats = hns3_xstats_calc_num(dev);
1402 	struct hns3_adapter *hns = dev->data->dev_private;
1403 	struct rte_eth_xstat_name *names_copy;
1404 	struct hns3_hw *hw = &hns->hw;
1405 	uint64_t len;
1406 	uint32_t i;
1407 
1408 	if (xstats_names == NULL)
1409 		return cnt_stats;
1410 
1411 	if (ids == NULL) {
1412 		if (size < cnt_stats)
1413 			return cnt_stats;
1414 
1415 		return hns3_dev_xstats_get_names(dev, xstats_names, cnt_stats);
1416 	}
1417 
1418 	len = cnt_stats * sizeof(struct rte_eth_xstat_name);
1419 	names_copy = rte_zmalloc("hns3_xstats_names", len, 0);
1420 	if (names_copy == NULL) {
1421 		hns3_err(hw, "Failed to allocate 0x%" PRIx64 " bytes needed "
1422 			     "to store statistics names", len);
1423 		return -ENOMEM;
1424 	}
1425 
1426 	(void)hns3_dev_xstats_get_names(dev, names_copy, cnt_stats);
1427 
1428 	for (i = 0; i < size; i++) {
1429 		if (ids[i] >= cnt_stats) {
1430 			hns3_err(hw, "ids[%u] (%" PRIu64 ") is invalid, "
1431 				     "should < %u", i, ids[i], cnt_stats);
1432 			rte_free(names_copy);
1433 			return -EINVAL;
1434 		}
1435 		snprintf(xstats_names[i].name, sizeof(xstats_names[i].name),
1436 			 "%s", names_copy[ids[i]].name);
1437 	}
1438 
1439 	rte_free(names_copy);
1440 	return size;
1441 }
1442 
1443 static void
hns3_tqp_dfx_stats_clear(struct rte_eth_dev * dev)1444 hns3_tqp_dfx_stats_clear(struct rte_eth_dev *dev)
1445 {
1446 	struct hns3_rx_queue *rxq;
1447 	struct hns3_tx_queue *txq;
1448 	uint16_t i;
1449 
1450 	/* Clear Rx dfx stats */
1451 	for (i = 0; i < dev->data->nb_rx_queues; i++) {
1452 		rxq = dev->data->rx_queues[i];
1453 		if (rxq)
1454 			memset(&rxq->dfx_stats, 0,
1455 			       sizeof(struct hns3_rx_dfx_stats));
1456 	}
1457 
1458 	/* Clear Tx dfx stats */
1459 	for (i = 0; i < dev->data->nb_tx_queues; i++) {
1460 		txq = dev->data->tx_queues[i];
1461 		if (txq)
1462 			memset(&txq->dfx_stats, 0,
1463 			       sizeof(struct hns3_tx_dfx_stats));
1464 	}
1465 }
1466 
1467 int
hns3_dev_xstats_reset(struct rte_eth_dev * dev)1468 hns3_dev_xstats_reset(struct rte_eth_dev *dev)
1469 {
1470 	struct hns3_adapter *hns = dev->data->dev_private;
1471 	struct hns3_hw *hw = &hns->hw;
1472 	int ret;
1473 
1474 	/* Clear tqp stats */
1475 	ret = hns3_stats_reset(dev);
1476 	if (ret)
1477 		return ret;
1478 
1479 	rte_spinlock_lock(&hw->stats_lock);
1480 	hns3_tqp_dfx_stats_clear(dev);
1481 
1482 	/* Clear reset stats */
1483 	memset(&hns->hw.reset.stats, 0, sizeof(struct hns3_reset_stats));
1484 
1485 	if (hns->is_vf)
1486 		goto out;
1487 
1488 	/* HW registers are cleared on read */
1489 	ret = hns3_mac_stats_reset(dev);
1490 
1491 out:
1492 	rte_spinlock_unlock(&hw->stats_lock);
1493 
1494 	return ret;
1495 }
1496 
1497 static int
hns3_tqp_stats_init(struct hns3_hw * hw)1498 hns3_tqp_stats_init(struct hns3_hw *hw)
1499 {
1500 	struct hns3_tqp_stats *tqp_stats = &hw->tqp_stats;
1501 
1502 	tqp_stats->rcb_rx_ring_pktnum = rte_zmalloc("hns3_rx_ring_pkt_num",
1503 					 sizeof(uint64_t) * hw->tqps_num, 0);
1504 	if (tqp_stats->rcb_rx_ring_pktnum == NULL) {
1505 		hns3_err(hw, "failed to allocate rx_ring pkt_num.");
1506 		return -ENOMEM;
1507 	}
1508 
1509 	tqp_stats->rcb_tx_ring_pktnum = rte_zmalloc("hns3_tx_ring_pkt_num",
1510 					 sizeof(uint64_t) * hw->tqps_num, 0);
1511 	if (tqp_stats->rcb_tx_ring_pktnum == NULL) {
1512 		hns3_err(hw, "failed to allocate tx_ring pkt_num.");
1513 		rte_free(tqp_stats->rcb_rx_ring_pktnum);
1514 		tqp_stats->rcb_rx_ring_pktnum = NULL;
1515 		return -ENOMEM;
1516 	}
1517 
1518 	return 0;
1519 }
1520 
1521 static void
hns3_tqp_stats_uninit(struct hns3_hw * hw)1522 hns3_tqp_stats_uninit(struct hns3_hw *hw)
1523 {
1524 	struct hns3_tqp_stats *tqp_stats = &hw->tqp_stats;
1525 
1526 	rte_free(tqp_stats->rcb_rx_ring_pktnum);
1527 	tqp_stats->rcb_rx_ring_pktnum = NULL;
1528 	rte_free(tqp_stats->rcb_tx_ring_pktnum);
1529 	tqp_stats->rcb_tx_ring_pktnum = NULL;
1530 }
1531 
1532 static void
hns3_tqp_stats_clear(struct hns3_hw * hw)1533 hns3_tqp_stats_clear(struct hns3_hw *hw)
1534 {
1535 	struct hns3_tqp_stats *stats = &hw->tqp_stats;
1536 
1537 	stats->rcb_rx_ring_pktnum_rcd = 0;
1538 	stats->rcb_tx_ring_pktnum_rcd = 0;
1539 	memset(stats->rcb_rx_ring_pktnum, 0, sizeof(uint64_t) * hw->tqps_num);
1540 	memset(stats->rcb_tx_ring_pktnum, 0, sizeof(uint64_t) * hw->tqps_num);
1541 }
1542 
1543 int
hns3_stats_init(struct hns3_hw * hw)1544 hns3_stats_init(struct hns3_hw *hw)
1545 {
1546 	int ret;
1547 
1548 	rte_spinlock_init(&hw->stats_lock);
1549 	/* Hardware statistics of imissed registers cleared. */
1550 	ret = hns3_update_imissed_stats(hw, true);
1551 	if (ret) {
1552 		hns3_err(hw, "clear imissed stats failed, ret = %d", ret);
1553 		return ret;
1554 	}
1555 
1556 	return hns3_tqp_stats_init(hw);
1557 }
1558 
1559 void
hns3_stats_uninit(struct hns3_hw * hw)1560 hns3_stats_uninit(struct hns3_hw *hw)
1561 {
1562 	hns3_tqp_stats_uninit(hw);
1563 }
1564 
1565 static void
hns3_update_queues_stats(struct hns3_hw * hw)1566 hns3_update_queues_stats(struct hns3_hw *hw)
1567 {
1568 	struct rte_eth_dev_data *data = hw->data;
1569 	struct hns3_rx_queue *rxq;
1570 	struct hns3_tx_queue *txq;
1571 	uint16_t i;
1572 
1573 	for (i = 0; i < data->nb_rx_queues; i++) {
1574 		rxq = data->rx_queues[i];
1575 		if (rxq != NULL)
1576 			hns3_rcb_rx_ring_stats_get(rxq, &hw->tqp_stats);
1577 	}
1578 
1579 	for (i = 0; i < data->nb_tx_queues; i++) {
1580 		txq = data->tx_queues[i];
1581 		if (txq != NULL)
1582 			hns3_rcb_tx_ring_stats_get(txq, &hw->tqp_stats);
1583 	}
1584 }
1585 
1586 /*
1587  * Some hardware statistics registers are not 64-bit. If hardware statistics are
1588  * not obtained for a long time, these statistics may be reversed. This function
1589  * is used to update these hardware statistics in periodic task.
1590  */
1591 void
hns3_update_hw_stats(struct hns3_hw * hw)1592 hns3_update_hw_stats(struct hns3_hw *hw)
1593 {
1594 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
1595 
1596 	rte_spinlock_lock(&hw->stats_lock);
1597 	if (!hns->is_vf)
1598 		hns3_update_mac_stats(hw);
1599 
1600 	hns3_update_queues_stats(hw);
1601 	rte_spinlock_unlock(&hw->stats_lock);
1602 }
1603