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