xref: /f-stack/dpdk/drivers/net/bnxt/bnxt_stats.c (revision 2d9fd380)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2014-2018 Broadcom
3  * All rights reserved.
4  */
5 
6 #include <inttypes.h>
7 
8 #include <rte_string_fns.h>
9 #include <rte_byteorder.h>
10 
11 #include "bnxt.h"
12 #include "bnxt_cpr.h"
13 #include "bnxt_filter.h"
14 #include "bnxt_hwrm.h"
15 #include "bnxt_rxq.h"
16 #include "bnxt_stats.h"
17 #include "bnxt_txq.h"
18 #include "bnxt_vnic.h"
19 #include "hsi_struct_def_dpdk.h"
20 
21 static const struct bnxt_xstats_name_off bnxt_rx_stats_strings[] = {
22 	{"rx_64b_frames", offsetof(struct rx_port_stats,
23 				rx_64b_frames)},
24 	{"rx_65b_127b_frames", offsetof(struct rx_port_stats,
25 				rx_65b_127b_frames)},
26 	{"rx_128b_255b_frames", offsetof(struct rx_port_stats,
27 				rx_128b_255b_frames)},
28 	{"rx_256b_511b_frames", offsetof(struct rx_port_stats,
29 				rx_256b_511b_frames)},
30 	{"rx_512b_1023b_frames", offsetof(struct rx_port_stats,
31 				rx_512b_1023b_frames)},
32 	{"rx_1024b_1518b_frames", offsetof(struct rx_port_stats,
33 				rx_1024b_1518b_frames)},
34 	{"rx_good_vlan_frames", offsetof(struct rx_port_stats,
35 				rx_good_vlan_frames)},
36 	{"rx_1519b_2047b_frames", offsetof(struct rx_port_stats,
37 				rx_1519b_2047b_frames)},
38 	{"rx_2048b_4095b_frames", offsetof(struct rx_port_stats,
39 				rx_2048b_4095b_frames)},
40 	{"rx_4096b_9216b_frames", offsetof(struct rx_port_stats,
41 				rx_4096b_9216b_frames)},
42 	{"rx_9217b_16383b_frames", offsetof(struct rx_port_stats,
43 				rx_9217b_16383b_frames)},
44 	{"rx_total_frames", offsetof(struct rx_port_stats,
45 				rx_total_frames)},
46 	{"rx_ucast_frames", offsetof(struct rx_port_stats,
47 				rx_ucast_frames)},
48 	{"rx_mcast_frames", offsetof(struct rx_port_stats,
49 				rx_mcast_frames)},
50 	{"rx_bcast_frames", offsetof(struct rx_port_stats,
51 				rx_bcast_frames)},
52 	{"rx_fcs_err_frames", offsetof(struct rx_port_stats,
53 				rx_fcs_err_frames)},
54 	{"rx_ctrl_frames", offsetof(struct rx_port_stats,
55 				rx_ctrl_frames)},
56 	{"rx_pause_frames", offsetof(struct rx_port_stats,
57 				rx_pause_frames)},
58 	{"rx_pfc_frames", offsetof(struct rx_port_stats,
59 				rx_pfc_frames)},
60 	{"rx_unsupported_opcode_frames", offsetof(struct rx_port_stats,
61 				rx_unsupported_opcode_frames)},
62 	{"rx_unsupported_da_pausepfc_frames", offsetof(struct rx_port_stats,
63 				rx_unsupported_da_pausepfc_frames)},
64 	{"rx_wrong_sa_frames", offsetof(struct rx_port_stats,
65 				rx_wrong_sa_frames)},
66 	{"rx_align_err_frames", offsetof(struct rx_port_stats,
67 				rx_align_err_frames)},
68 	{"rx_oor_len_frames", offsetof(struct rx_port_stats,
69 				rx_oor_len_frames)},
70 	{"rx_code_err_frames", offsetof(struct rx_port_stats,
71 				rx_code_err_frames)},
72 	{"rx_false_carrier_frames", offsetof(struct rx_port_stats,
73 				rx_false_carrier_frames)},
74 	{"rx_ovrsz_frames", offsetof(struct rx_port_stats,
75 				rx_ovrsz_frames)},
76 	{"rx_jbr_frames", offsetof(struct rx_port_stats,
77 				rx_jbr_frames)},
78 	{"rx_mtu_err_frames", offsetof(struct rx_port_stats,
79 				rx_mtu_err_frames)},
80 	{"rx_match_crc_frames", offsetof(struct rx_port_stats,
81 				rx_match_crc_frames)},
82 	{"rx_promiscuous_frames", offsetof(struct rx_port_stats,
83 				rx_promiscuous_frames)},
84 	{"rx_tagged_frames", offsetof(struct rx_port_stats,
85 				rx_tagged_frames)},
86 	{"rx_double_tagged_frames", offsetof(struct rx_port_stats,
87 				rx_double_tagged_frames)},
88 	{"rx_trunc_frames", offsetof(struct rx_port_stats,
89 				rx_trunc_frames)},
90 	{"rx_good_frames", offsetof(struct rx_port_stats,
91 				rx_good_frames)},
92 	{"rx_sch_crc_err_frames", offsetof(struct rx_port_stats,
93 				rx_sch_crc_err_frames)},
94 	{"rx_undrsz_frames", offsetof(struct rx_port_stats,
95 				rx_undrsz_frames)},
96 	{"rx_frag_frames", offsetof(struct rx_port_stats,
97 				rx_frag_frames)},
98 	{"rx_eee_lpi_events", offsetof(struct rx_port_stats,
99 				rx_eee_lpi_events)},
100 	{"rx_eee_lpi_duration", offsetof(struct rx_port_stats,
101 				rx_eee_lpi_duration)},
102 	{"rx_llfc_physical_msgs", offsetof(struct rx_port_stats,
103 				rx_llfc_physical_msgs)},
104 	{"rx_llfc_logical_msgs", offsetof(struct rx_port_stats,
105 				rx_llfc_logical_msgs)},
106 	{"rx_llfc_msgs_with_crc_err", offsetof(struct rx_port_stats,
107 				rx_llfc_msgs_with_crc_err)},
108 	{"rx_hcfc_msgs", offsetof(struct rx_port_stats,
109 				rx_hcfc_msgs)},
110 	{"rx_hcfc_msgs_with_crc_err", offsetof(struct rx_port_stats,
111 				rx_hcfc_msgs_with_crc_err)},
112 	{"rx_bytes", offsetof(struct rx_port_stats,
113 				rx_bytes)},
114 	{"rx_runt_bytes", offsetof(struct rx_port_stats,
115 				rx_runt_bytes)},
116 	{"rx_runt_frames", offsetof(struct rx_port_stats,
117 				rx_runt_frames)},
118 	{"rx_pfc_xon2xoff_frames_pri0", offsetof(struct rx_port_stats,
119 				rx_pfc_xon2xoff_frames_pri0)},
120 	{"rx_pfc_xon2xoff_frames_pri1", offsetof(struct rx_port_stats,
121 				rx_pfc_xon2xoff_frames_pri1)},
122 	{"rx_pfc_xon2xoff_frames_pri2", offsetof(struct rx_port_stats,
123 				rx_pfc_xon2xoff_frames_pri2)},
124 	{"rx_pfc_xon2xoff_frames_pri3", offsetof(struct rx_port_stats,
125 				rx_pfc_xon2xoff_frames_pri3)},
126 	{"rx_pfc_xon2xoff_frames_pri4", offsetof(struct rx_port_stats,
127 				rx_pfc_xon2xoff_frames_pri4)},
128 	{"rx_pfc_xon2xoff_frames_pri5", offsetof(struct rx_port_stats,
129 				rx_pfc_xon2xoff_frames_pri5)},
130 	{"rx_pfc_xon2xoff_frames_pri6", offsetof(struct rx_port_stats,
131 				rx_pfc_xon2xoff_frames_pri6)},
132 	{"rx_pfc_xon2xoff_frames_pri7", offsetof(struct rx_port_stats,
133 				rx_pfc_xon2xoff_frames_pri7)},
134 	{"rx_pfc_ena_frames_pri0", offsetof(struct rx_port_stats,
135 				rx_pfc_ena_frames_pri0)},
136 	{"rx_pfc_ena_frames_pri1", offsetof(struct rx_port_stats,
137 				rx_pfc_ena_frames_pri1)},
138 	{"rx_pfc_ena_frames_pri2", offsetof(struct rx_port_stats,
139 				rx_pfc_ena_frames_pri2)},
140 	{"rx_pfc_ena_frames_pri3", offsetof(struct rx_port_stats,
141 				rx_pfc_ena_frames_pri3)},
142 	{"rx_pfc_ena_frames_pri4", offsetof(struct rx_port_stats,
143 				rx_pfc_ena_frames_pri4)},
144 	{"rx_pfc_ena_frames_pri5", offsetof(struct rx_port_stats,
145 				rx_pfc_ena_frames_pri5)},
146 	{"rx_pfc_ena_frames_pri6", offsetof(struct rx_port_stats,
147 				rx_pfc_ena_frames_pri6)},
148 	{"rx_pfc_ena_frames_pri7", offsetof(struct rx_port_stats,
149 				rx_pfc_ena_frames_pri7)},
150 	{"rx_stat_discard", offsetof(struct rx_port_stats,
151 				rx_stat_discard)},
152 	{"rx_stat_err", offsetof(struct rx_port_stats,
153 				rx_stat_err)},
154 };
155 
156 static const struct bnxt_xstats_name_off bnxt_tx_stats_strings[] = {
157 	{"tx_64b_frames", offsetof(struct tx_port_stats,
158 				tx_64b_frames)},
159 	{"tx_65b_127b_frames", offsetof(struct tx_port_stats,
160 				tx_65b_127b_frames)},
161 	{"tx_128b_255b_frames", offsetof(struct tx_port_stats,
162 				tx_128b_255b_frames)},
163 	{"tx_256b_511b_frames", offsetof(struct tx_port_stats,
164 				tx_256b_511b_frames)},
165 	{"tx_512b_1023b_frames", offsetof(struct tx_port_stats,
166 				tx_512b_1023b_frames)},
167 	{"tx_1024b_1518b_frames", offsetof(struct tx_port_stats,
168 				tx_1024b_1518b_frames)},
169 	{"tx_good_vlan_frames", offsetof(struct tx_port_stats,
170 				tx_good_vlan_frames)},
171 	{"tx_1519b_2047b_frames", offsetof(struct tx_port_stats,
172 				tx_1519b_2047b_frames)},
173 	{"tx_2048b_4095b_frames", offsetof(struct tx_port_stats,
174 				tx_2048b_4095b_frames)},
175 	{"tx_4096b_9216b_frames", offsetof(struct tx_port_stats,
176 				tx_4096b_9216b_frames)},
177 	{"tx_9217b_16383b_frames", offsetof(struct tx_port_stats,
178 				tx_9217b_16383b_frames)},
179 	{"tx_good_frames", offsetof(struct tx_port_stats,
180 				tx_good_frames)},
181 	{"tx_total_frames", offsetof(struct tx_port_stats,
182 				tx_total_frames)},
183 	{"tx_ucast_frames", offsetof(struct tx_port_stats,
184 				tx_ucast_frames)},
185 	{"tx_mcast_frames", offsetof(struct tx_port_stats,
186 				tx_mcast_frames)},
187 	{"tx_bcast_frames", offsetof(struct tx_port_stats,
188 				tx_bcast_frames)},
189 	{"tx_pause_frames", offsetof(struct tx_port_stats,
190 				tx_pause_frames)},
191 	{"tx_pfc_frames", offsetof(struct tx_port_stats,
192 				tx_pfc_frames)},
193 	{"tx_jabber_frames", offsetof(struct tx_port_stats,
194 				tx_jabber_frames)},
195 	{"tx_fcs_err_frames", offsetof(struct tx_port_stats,
196 				tx_fcs_err_frames)},
197 	{"tx_control_frames", offsetof(struct tx_port_stats,
198 				tx_control_frames)},
199 	{"tx_oversz_frames", offsetof(struct tx_port_stats,
200 				tx_oversz_frames)},
201 	{"tx_single_dfrl_frames", offsetof(struct tx_port_stats,
202 				tx_single_dfrl_frames)},
203 	{"tx_multi_dfrl_frames", offsetof(struct tx_port_stats,
204 				tx_multi_dfrl_frames)},
205 	{"tx_single_coll_frames", offsetof(struct tx_port_stats,
206 				tx_single_coll_frames)},
207 	{"tx_multi_coll_frames", offsetof(struct tx_port_stats,
208 				tx_multi_coll_frames)},
209 	{"tx_late_coll_frames", offsetof(struct tx_port_stats,
210 				tx_late_coll_frames)},
211 	{"tx_excessive_coll_frames", offsetof(struct tx_port_stats,
212 				tx_excessive_coll_frames)},
213 	{"tx_frag_frames", offsetof(struct tx_port_stats,
214 				tx_frag_frames)},
215 	{"tx_err", offsetof(struct tx_port_stats,
216 				tx_err)},
217 	{"tx_tagged_frames", offsetof(struct tx_port_stats,
218 				tx_tagged_frames)},
219 	{"tx_dbl_tagged_frames", offsetof(struct tx_port_stats,
220 				tx_dbl_tagged_frames)},
221 	{"tx_runt_frames", offsetof(struct tx_port_stats,
222 				tx_runt_frames)},
223 	{"tx_fifo_underruns", offsetof(struct tx_port_stats,
224 				tx_fifo_underruns)},
225 	{"tx_eee_lpi_events", offsetof(struct tx_port_stats,
226 				tx_eee_lpi_events)},
227 	{"tx_eee_lpi_duration", offsetof(struct tx_port_stats,
228 				tx_eee_lpi_duration)},
229 	{"tx_total_collisions", offsetof(struct tx_port_stats,
230 				tx_total_collisions)},
231 	{"tx_bytes", offsetof(struct tx_port_stats,
232 				tx_bytes)},
233 	{"tx_pfc_ena_frames_pri0", offsetof(struct tx_port_stats,
234 				tx_pfc_ena_frames_pri0)},
235 	{"tx_pfc_ena_frames_pri1", offsetof(struct tx_port_stats,
236 				tx_pfc_ena_frames_pri1)},
237 	{"tx_pfc_ena_frames_pri2", offsetof(struct tx_port_stats,
238 				tx_pfc_ena_frames_pri2)},
239 	{"tx_pfc_ena_frames_pri3", offsetof(struct tx_port_stats,
240 				tx_pfc_ena_frames_pri3)},
241 	{"tx_pfc_ena_frames_pri4", offsetof(struct tx_port_stats,
242 				tx_pfc_ena_frames_pri4)},
243 	{"tx_pfc_ena_frames_pri5", offsetof(struct tx_port_stats,
244 				tx_pfc_ena_frames_pri5)},
245 	{"tx_pfc_ena_frames_pri6", offsetof(struct tx_port_stats,
246 				tx_pfc_ena_frames_pri6)},
247 	{"tx_pfc_ena_frames_pri7", offsetof(struct tx_port_stats,
248 				tx_pfc_ena_frames_pri7)},
249 	{"tx_llfc_logical_msgs", offsetof(struct tx_port_stats,
250 				tx_llfc_logical_msgs)},
251 	{"tx_hcfc_msgs", offsetof(struct tx_port_stats,
252 				tx_hcfc_msgs)},
253 	{"tx_xthol_frames", offsetof(struct tx_port_stats,
254 				tx_xthol_frames)},
255 	{"tx_stat_discard", offsetof(struct tx_port_stats,
256 				tx_stat_discard)},
257 	{"tx_stat_error", offsetof(struct tx_port_stats,
258 				tx_stat_error)},
259 };
260 
261 static const struct bnxt_xstats_name_off bnxt_func_stats_strings[] = {
262 	{"tx_ucast_pkts", offsetof(struct hwrm_func_qstats_output,
263 				tx_ucast_pkts)},
264 	{"tx_mcast_pkts", offsetof(struct hwrm_func_qstats_output,
265 				tx_mcast_pkts)},
266 	{"tx_bcast_pkts", offsetof(struct hwrm_func_qstats_output,
267 				tx_bcast_pkts)},
268 	{"tx_discard_pkts", offsetof(struct hwrm_func_qstats_output,
269 				tx_discard_pkts)},
270 	{"tx_drop_pkts", offsetof(struct hwrm_func_qstats_output,
271 				tx_drop_pkts)},
272 	{"tx_ucast_bytes", offsetof(struct hwrm_func_qstats_output,
273 				tx_ucast_bytes)},
274 	{"tx_mcast_bytes", offsetof(struct hwrm_func_qstats_output,
275 				tx_mcast_bytes)},
276 	{"tx_bcast_bytes", offsetof(struct hwrm_func_qstats_output,
277 				tx_bcast_bytes)},
278 	{"rx_ucast_pkts", offsetof(struct hwrm_func_qstats_output,
279 				rx_ucast_pkts)},
280 	{"rx_mcast_pkts", offsetof(struct hwrm_func_qstats_output,
281 				rx_mcast_pkts)},
282 	{"rx_bcast_pkts", offsetof(struct hwrm_func_qstats_output,
283 				rx_bcast_pkts)},
284 	{"rx_discard_pkts", offsetof(struct hwrm_func_qstats_output,
285 				rx_discard_pkts)},
286 	{"rx_drop_pkts", offsetof(struct hwrm_func_qstats_output,
287 				rx_drop_pkts)},
288 	{"rx_ucast_bytes", offsetof(struct hwrm_func_qstats_output,
289 				rx_ucast_bytes)},
290 	{"rx_mcast_bytes", offsetof(struct hwrm_func_qstats_output,
291 				rx_mcast_bytes)},
292 	{"rx_bcast_bytes", offsetof(struct hwrm_func_qstats_output,
293 				rx_bcast_bytes)},
294 	{"rx_agg_pkts", offsetof(struct hwrm_func_qstats_output,
295 				rx_agg_pkts)},
296 	{"rx_agg_bytes", offsetof(struct hwrm_func_qstats_output,
297 				rx_agg_bytes)},
298 	{"rx_agg_events", offsetof(struct hwrm_func_qstats_output,
299 				rx_agg_events)},
300 	{"rx_agg_aborts", offsetof(struct hwrm_func_qstats_output,
301 				rx_agg_aborts)},
302 };
303 
304 
305 static const struct bnxt_xstats_name_off bnxt_rx_ext_stats_strings[] = {
306 	{"link_down_events", offsetof(struct rx_port_stats_ext,
307 				link_down_events)},
308 	{"continuous_pause_events", offsetof(struct rx_port_stats_ext,
309 				continuous_pause_events)},
310 	{"resume_pause_events", offsetof(struct rx_port_stats_ext,
311 				resume_pause_events)},
312 	{"continuous_roce_pause_events", offsetof(struct rx_port_stats_ext,
313 				continuous_roce_pause_events)},
314 	{"resume_roce_pause_events", offsetof(struct rx_port_stats_ext,
315 				resume_roce_pause_events)},
316 	{"rx_bytes_cos0", offsetof(struct rx_port_stats_ext,
317 				rx_bytes_cos0)},
318 	{"rx_bytes_cos1", offsetof(struct rx_port_stats_ext,
319 				rx_bytes_cos1)},
320 	{"rx_bytes_cos2", offsetof(struct rx_port_stats_ext,
321 				rx_bytes_cos2)},
322 	{"rx_bytes_cos3", offsetof(struct rx_port_stats_ext,
323 				rx_bytes_cos3)},
324 	{"rx_bytes_cos4", offsetof(struct rx_port_stats_ext,
325 				rx_bytes_cos4)},
326 	{"rx_bytes_cos5", offsetof(struct rx_port_stats_ext,
327 				rx_bytes_cos5)},
328 	{"rx_bytes_cos6", offsetof(struct rx_port_stats_ext,
329 				rx_bytes_cos6)},
330 	{"rx_bytes_cos7", offsetof(struct rx_port_stats_ext,
331 				rx_bytes_cos7)},
332 	{"rx_packets_cos0", offsetof(struct rx_port_stats_ext,
333 				rx_packets_cos0)},
334 	{"rx_packets_cos1", offsetof(struct rx_port_stats_ext,
335 				rx_packets_cos1)},
336 	{"rx_packets_cos2", offsetof(struct rx_port_stats_ext,
337 				rx_packets_cos2)},
338 	{"rx_packets_cos3", offsetof(struct rx_port_stats_ext,
339 				rx_packets_cos3)},
340 	{"rx_packets_cos4", offsetof(struct rx_port_stats_ext,
341 				rx_packets_cos4)},
342 	{"rx_packets_cos5", offsetof(struct rx_port_stats_ext,
343 				rx_packets_cos5)},
344 	{"rx_packets_cos6", offsetof(struct rx_port_stats_ext,
345 				rx_packets_cos6)},
346 	{"rx_packets_cos7", offsetof(struct rx_port_stats_ext,
347 				rx_packets_cos7)},
348 	{"pfc_pri0_rx_duration_us", offsetof(struct rx_port_stats_ext,
349 				pfc_pri0_rx_duration_us)},
350 	{"pfc_pri0_rx_transitions", offsetof(struct rx_port_stats_ext,
351 				pfc_pri0_rx_transitions)},
352 	{"pfc_pri1_rx_duration_us", offsetof(struct rx_port_stats_ext,
353 				pfc_pri1_rx_duration_us)},
354 	{"pfc_pri1_rx_transitions", offsetof(struct rx_port_stats_ext,
355 				pfc_pri1_rx_transitions)},
356 	{"pfc_pri2_rx_duration_us", offsetof(struct rx_port_stats_ext,
357 				pfc_pri2_rx_duration_us)},
358 	{"pfc_pri2_rx_transitions", offsetof(struct rx_port_stats_ext,
359 				pfc_pri2_rx_transitions)},
360 	{"pfc_pri3_rx_duration_us", offsetof(struct rx_port_stats_ext,
361 				pfc_pri3_rx_duration_us)},
362 	{"pfc_pri3_rx_transitions", offsetof(struct rx_port_stats_ext,
363 				pfc_pri3_rx_transitions)},
364 	{"pfc_pri4_rx_duration_us", offsetof(struct rx_port_stats_ext,
365 				pfc_pri4_rx_duration_us)},
366 	{"pfc_pri4_rx_transitions", offsetof(struct rx_port_stats_ext,
367 				pfc_pri4_rx_transitions)},
368 	{"pfc_pri5_rx_duration_us", offsetof(struct rx_port_stats_ext,
369 				pfc_pri5_rx_duration_us)},
370 	{"pfc_pri5_rx_transitions", offsetof(struct rx_port_stats_ext,
371 				pfc_pri5_rx_transitions)},
372 	{"pfc_pri6_rx_duration_us", offsetof(struct rx_port_stats_ext,
373 				pfc_pri6_rx_duration_us)},
374 	{"pfc_pri6_rx_transitions", offsetof(struct rx_port_stats_ext,
375 				pfc_pri6_rx_transitions)},
376 	{"pfc_pri7_rx_duration_us", offsetof(struct rx_port_stats_ext,
377 				pfc_pri7_rx_duration_us)},
378 	{"pfc_pri7_rx_transitions", offsetof(struct rx_port_stats_ext,
379 				pfc_pri7_rx_transitions)},
380 	{"rx_bits",		offsetof(struct rx_port_stats_ext,
381 				rx_bits)},
382 	{"rx_buffer_passed_threshold", offsetof(struct rx_port_stats_ext,
383 				rx_buffer_passed_threshold)},
384 	{"rx_pcs_symbol_err",	offsetof(struct rx_port_stats_ext,
385 				rx_pcs_symbol_err)},
386 	{"rx_corrected_bits",	offsetof(struct rx_port_stats_ext,
387 				rx_corrected_bits)},
388 	{"rx_discard_bytes_cos0", offsetof(struct rx_port_stats_ext,
389 				rx_discard_bytes_cos0)},
390 	{"rx_discard_bytes_cos1", offsetof(struct rx_port_stats_ext,
391 				rx_discard_bytes_cos1)},
392 	{"rx_discard_bytes_cos2", offsetof(struct rx_port_stats_ext,
393 				rx_discard_bytes_cos2)},
394 	{"rx_discard_bytes_cos3", offsetof(struct rx_port_stats_ext,
395 				rx_discard_bytes_cos3)},
396 	{"rx_discard_bytes_cos4", offsetof(struct rx_port_stats_ext,
397 				rx_discard_bytes_cos4)},
398 	{"rx_discard_bytes_cos5", offsetof(struct rx_port_stats_ext,
399 				rx_discard_bytes_cos5)},
400 	{"rx_discard_bytes_cos6", offsetof(struct rx_port_stats_ext,
401 				rx_discard_bytes_cos6)},
402 	{"rx_discard_bytes_cos7", offsetof(struct rx_port_stats_ext,
403 				rx_discard_bytes_cos7)},
404 	{"rx_discard_packets_cos0", offsetof(struct rx_port_stats_ext,
405 				rx_discard_packets_cos0)},
406 	{"rx_discard_packets_cos1", offsetof(struct rx_port_stats_ext,
407 				rx_discard_packets_cos1)},
408 	{"rx_discard_packets_cos2", offsetof(struct rx_port_stats_ext,
409 				rx_discard_packets_cos2)},
410 	{"rx_discard_packets_cos3", offsetof(struct rx_port_stats_ext,
411 				rx_discard_packets_cos3)},
412 	{"rx_discard_packets_cos4", offsetof(struct rx_port_stats_ext,
413 				rx_discard_packets_cos4)},
414 	{"rx_discard_packets_cos5", offsetof(struct rx_port_stats_ext,
415 				rx_discard_packets_cos5)},
416 	{"rx_discard_packets_cos6", offsetof(struct rx_port_stats_ext,
417 				rx_discard_packets_cos6)},
418 	{"rx_discard_packets_cos7", offsetof(struct rx_port_stats_ext,
419 				rx_discard_packets_cos7)},
420 };
421 
422 static const struct bnxt_xstats_name_off bnxt_tx_ext_stats_strings[] = {
423 	{"tx_bytes_cos0", offsetof(struct tx_port_stats_ext,
424 				tx_bytes_cos0)},
425 	{"tx_bytes_cos1", offsetof(struct tx_port_stats_ext,
426 				tx_bytes_cos1)},
427 	{"tx_bytes_cos2", offsetof(struct tx_port_stats_ext,
428 				tx_bytes_cos2)},
429 	{"tx_bytes_cos3", offsetof(struct tx_port_stats_ext,
430 				tx_bytes_cos3)},
431 	{"tx_bytes_cos4", offsetof(struct tx_port_stats_ext,
432 				tx_bytes_cos4)},
433 	{"tx_bytes_cos5", offsetof(struct tx_port_stats_ext,
434 				tx_bytes_cos5)},
435 	{"tx_bytes_cos6", offsetof(struct tx_port_stats_ext,
436 				tx_bytes_cos6)},
437 	{"tx_bytes_cos7", offsetof(struct tx_port_stats_ext,
438 				tx_bytes_cos7)},
439 	{"tx_packets_cos0", offsetof(struct tx_port_stats_ext,
440 				tx_packets_cos0)},
441 	{"tx_packets_cos1", offsetof(struct tx_port_stats_ext,
442 				tx_packets_cos1)},
443 	{"tx_packets_cos2", offsetof(struct tx_port_stats_ext,
444 				tx_packets_cos2)},
445 	{"tx_packets_cos3", offsetof(struct tx_port_stats_ext,
446 				tx_packets_cos3)},
447 	{"tx_packets_cos4", offsetof(struct tx_port_stats_ext,
448 				tx_packets_cos4)},
449 	{"tx_packets_cos5", offsetof(struct tx_port_stats_ext,
450 				tx_packets_cos5)},
451 	{"tx_packets_cos6", offsetof(struct tx_port_stats_ext,
452 				tx_packets_cos6)},
453 	{"tx_packets_cos7", offsetof(struct tx_port_stats_ext,
454 				tx_packets_cos7)},
455 	{"pfc_pri0_tx_duration_us", offsetof(struct tx_port_stats_ext,
456 				pfc_pri0_tx_duration_us)},
457 	{"pfc_pri0_tx_transitions", offsetof(struct tx_port_stats_ext,
458 				pfc_pri0_tx_transitions)},
459 	{"pfc_pri1_tx_duration_us", offsetof(struct tx_port_stats_ext,
460 				pfc_pri1_tx_duration_us)},
461 	{"pfc_pri1_tx_transitions", offsetof(struct tx_port_stats_ext,
462 				pfc_pri1_tx_transitions)},
463 	{"pfc_pri2_tx_duration_us", offsetof(struct tx_port_stats_ext,
464 				pfc_pri2_tx_duration_us)},
465 	{"pfc_pri2_tx_transitions", offsetof(struct tx_port_stats_ext,
466 				pfc_pri2_tx_transitions)},
467 	{"pfc_pri3_tx_duration_us", offsetof(struct tx_port_stats_ext,
468 				pfc_pri3_tx_duration_us)},
469 	{"pfc_pri3_tx_transitions", offsetof(struct tx_port_stats_ext,
470 				pfc_pri3_tx_transitions)},
471 	{"pfc_pri4_tx_duration_us", offsetof(struct tx_port_stats_ext,
472 				pfc_pri4_tx_duration_us)},
473 	{"pfc_pri4_tx_transitions", offsetof(struct tx_port_stats_ext,
474 				pfc_pri4_tx_transitions)},
475 	{"pfc_pri5_tx_duration_us", offsetof(struct tx_port_stats_ext,
476 				pfc_pri5_tx_duration_us)},
477 	{"pfc_pri5_tx_transitions", offsetof(struct tx_port_stats_ext,
478 				pfc_pri5_tx_transitions)},
479 	{"pfc_pri6_tx_duration_us", offsetof(struct tx_port_stats_ext,
480 				pfc_pri6_tx_duration_us)},
481 	{"pfc_pri6_tx_transitions", offsetof(struct tx_port_stats_ext,
482 				pfc_pri6_tx_transitions)},
483 	{"pfc_pri7_tx_duration_us", offsetof(struct tx_port_stats_ext,
484 				pfc_pri7_tx_duration_us)},
485 	{"pfc_pri7_tx_transitions", offsetof(struct tx_port_stats_ext,
486 				pfc_pri7_tx_transitions)},
487 };
488 
489 /*
490  * Statistics functions
491  */
492 
bnxt_free_stats(struct bnxt * bp)493 void bnxt_free_stats(struct bnxt *bp)
494 {
495 	int i;
496 
497 	for (i = 0; i < (int)bp->tx_cp_nr_rings; i++) {
498 		struct bnxt_tx_queue *txq = bp->tx_queues[i];
499 
500 		bnxt_free_txq_stats(txq);
501 	}
502 	for (i = 0; i < (int)bp->rx_cp_nr_rings; i++) {
503 		struct bnxt_rx_queue *rxq = bp->rx_queues[i];
504 
505 		bnxt_free_rxq_stats(rxq);
506 	}
507 }
508 
bnxt_stats_get_op(struct rte_eth_dev * eth_dev,struct rte_eth_stats * bnxt_stats)509 int bnxt_stats_get_op(struct rte_eth_dev *eth_dev,
510 			   struct rte_eth_stats *bnxt_stats)
511 {
512 	int rc = 0;
513 	unsigned int i;
514 	struct bnxt *bp = eth_dev->data->dev_private;
515 	unsigned int num_q_stats;
516 
517 	rc = is_bnxt_in_error(bp);
518 	if (rc)
519 		return rc;
520 
521 	if (!eth_dev->data->dev_started)
522 		return -EIO;
523 
524 	num_q_stats = RTE_MIN(bp->rx_cp_nr_rings,
525 			      (unsigned int)RTE_ETHDEV_QUEUE_STAT_CNTRS);
526 
527 	for (i = 0; i < num_q_stats; i++) {
528 		struct bnxt_rx_queue *rxq = bp->rx_queues[i];
529 		struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
530 
531 		rc = bnxt_hwrm_ctx_qstats(bp, cpr->hw_stats_ctx_id, i,
532 				     bnxt_stats, 1);
533 		if (unlikely(rc))
534 			return rc;
535 		bnxt_stats->rx_nombuf +=
536 				rte_atomic64_read(&rxq->rx_mbuf_alloc_fail);
537 	}
538 
539 	num_q_stats = RTE_MIN(bp->tx_cp_nr_rings,
540 			      (unsigned int)RTE_ETHDEV_QUEUE_STAT_CNTRS);
541 
542 	for (i = 0; i < num_q_stats; i++) {
543 		struct bnxt_tx_queue *txq = bp->tx_queues[i];
544 		struct bnxt_cp_ring_info *cpr = txq->cp_ring;
545 
546 		rc = bnxt_hwrm_ctx_qstats(bp, cpr->hw_stats_ctx_id, i,
547 				     bnxt_stats, 0);
548 		if (unlikely(rc))
549 			return rc;
550 	}
551 
552 	rc = bnxt_hwrm_func_qstats(bp, 0xffff, bnxt_stats, NULL);
553 	return rc;
554 }
555 
bnxt_stats_reset_op(struct rte_eth_dev * eth_dev)556 int bnxt_stats_reset_op(struct rte_eth_dev *eth_dev)
557 {
558 	struct bnxt *bp = eth_dev->data->dev_private;
559 	unsigned int i;
560 	int ret;
561 
562 	ret = is_bnxt_in_error(bp);
563 	if (ret)
564 		return ret;
565 
566 	if (!eth_dev->data->dev_started) {
567 		PMD_DRV_LOG(ERR, "Device Initialization not complete!\n");
568 		return -EINVAL;
569 	}
570 
571 	ret = bnxt_clear_all_hwrm_stat_ctxs(bp);
572 	for (i = 0; i < bp->rx_cp_nr_rings; i++) {
573 		struct bnxt_rx_queue *rxq = bp->rx_queues[i];
574 
575 		rte_atomic64_clear(&rxq->rx_mbuf_alloc_fail);
576 	}
577 
578 	return ret;
579 }
580 
bnxt_dev_xstats_get_op(struct rte_eth_dev * eth_dev,struct rte_eth_xstat * xstats,unsigned int n)581 int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
582 			   struct rte_eth_xstat *xstats, unsigned int n)
583 {
584 	struct bnxt *bp = eth_dev->data->dev_private;
585 	unsigned int count, i;
586 	unsigned int rx_port_stats_ext_cnt;
587 	unsigned int tx_port_stats_ext_cnt;
588 	unsigned int stat_size = sizeof(uint64_t);
589 	struct hwrm_func_qstats_output func_qstats = {0};
590 	unsigned int stat_count;
591 	int rc;
592 
593 	rc = is_bnxt_in_error(bp);
594 	if (rc)
595 		return rc;
596 
597 	if (xstats == NULL)
598 		return 0;
599 
600 	memset(xstats, 0, sizeof(*xstats));
601 
602 	bnxt_hwrm_func_qstats(bp, 0xffff, NULL, &func_qstats);
603 	bnxt_hwrm_port_qstats(bp);
604 	bnxt_hwrm_ext_port_qstats(bp);
605 	rx_port_stats_ext_cnt = RTE_MIN(RTE_DIM(bnxt_rx_ext_stats_strings),
606 					(bp->fw_rx_port_stats_ext_size /
607 					 stat_size));
608 	tx_port_stats_ext_cnt = RTE_MIN(RTE_DIM(bnxt_tx_ext_stats_strings),
609 					(bp->fw_tx_port_stats_ext_size /
610 					 stat_size));
611 
612 	count = RTE_DIM(bnxt_rx_stats_strings) +
613 		RTE_DIM(bnxt_tx_stats_strings) +
614 		RTE_DIM(bnxt_func_stats_strings) +
615 		RTE_DIM(bnxt_rx_ext_stats_strings) +
616 		RTE_DIM(bnxt_tx_ext_stats_strings) +
617 		bnxt_flow_stats_cnt(bp);
618 
619 	stat_count = count;
620 
621 	if (n < count)
622 		return count;
623 
624 	count = 0;
625 	for (i = 0; i < RTE_DIM(bnxt_rx_stats_strings); i++) {
626 		uint64_t *rx_stats = (uint64_t *)bp->hw_rx_port_stats;
627 		xstats[count].id = count;
628 		xstats[count].value = rte_le_to_cpu_64(
629 				*(uint64_t *)((char *)rx_stats +
630 				bnxt_rx_stats_strings[i].offset));
631 		count++;
632 	}
633 
634 	for (i = 0; i < RTE_DIM(bnxt_tx_stats_strings); i++) {
635 		uint64_t *tx_stats = (uint64_t *)bp->hw_tx_port_stats;
636 		xstats[count].id = count;
637 		xstats[count].value = rte_le_to_cpu_64(
638 				 *(uint64_t *)((char *)tx_stats +
639 				bnxt_tx_stats_strings[i].offset));
640 		count++;
641 	}
642 
643 	for (i = 0; i < RTE_DIM(bnxt_func_stats_strings); i++) {
644 		xstats[count].id = count;
645 		xstats[count].value =
646 			rte_le_to_cpu_64(*(uint64_t *)((char *)&func_qstats +
647 					 bnxt_func_stats_strings[i].offset));
648 		count++;
649 	}
650 
651 
652 	for (i = 0; i < rx_port_stats_ext_cnt; i++) {
653 		uint64_t *rx_stats_ext = (uint64_t *)bp->hw_rx_port_stats_ext;
654 
655 		xstats[count].value = rte_le_to_cpu_64
656 					(*(uint64_t *)((char *)rx_stats_ext +
657 					 bnxt_rx_ext_stats_strings[i].offset));
658 
659 		count++;
660 	}
661 
662 	for (i = 0; i < tx_port_stats_ext_cnt; i++) {
663 		uint64_t *tx_stats_ext = (uint64_t *)bp->hw_tx_port_stats_ext;
664 
665 		xstats[count].value = rte_le_to_cpu_64
666 					(*(uint64_t *)((char *)tx_stats_ext +
667 					 bnxt_tx_ext_stats_strings[i].offset));
668 		count++;
669 	}
670 
671 	if (bp->fw_cap & BNXT_FW_CAP_ADV_FLOW_COUNTERS &&
672 	    bp->fw_cap & BNXT_FW_CAP_ADV_FLOW_MGMT &&
673 	    BNXT_FLOW_XSTATS_EN(bp)) {
674 		int j;
675 
676 		i = 0;
677 		for (j = 0; j < bp->max_vnics; j++) {
678 			struct bnxt_filter_info *filter;
679 			struct bnxt_vnic_info *vnic;
680 			struct rte_flow *flow;
681 
682 			vnic = &bp->vnic_info[j];
683 			if (vnic && vnic->fw_vnic_id == INVALID_VNIC_ID)
684 				continue;
685 
686 			if (STAILQ_EMPTY(&vnic->flow_list))
687 				continue;
688 
689 			STAILQ_FOREACH(flow, &vnic->flow_list, next) {
690 				if (!flow || !flow->filter)
691 					continue;
692 
693 				filter = flow->filter;
694 				xstats[count].id = count;
695 				xstats[count].value =
696 					filter->hw_stats.bytes;
697 				count++;
698 				xstats[count].id = count;
699 				xstats[count].value =
700 					filter->hw_stats.packets;
701 				count++;
702 				if (++i > bp->max_l2_ctx)
703 					break;
704 			}
705 			if (i > bp->max_l2_ctx)
706 				break;
707 		}
708 	}
709 
710 	return stat_count;
711 }
712 
bnxt_flow_stats_cnt(struct bnxt * bp)713 int bnxt_flow_stats_cnt(struct bnxt *bp)
714 {
715 	if (bp->fw_cap & BNXT_FW_CAP_ADV_FLOW_COUNTERS &&
716 	    bp->fw_cap & BNXT_FW_CAP_ADV_FLOW_MGMT &&
717 	    BNXT_FLOW_XSTATS_EN(bp)) {
718 		struct bnxt_xstats_name_off flow_bytes[bp->max_l2_ctx];
719 		struct bnxt_xstats_name_off flow_pkts[bp->max_l2_ctx];
720 
721 		return RTE_DIM(flow_bytes) + RTE_DIM(flow_pkts);
722 	}
723 
724 	return 0;
725 }
726 
bnxt_dev_xstats_get_names_op(struct rte_eth_dev * eth_dev,struct rte_eth_xstat_name * xstats_names,__rte_unused unsigned int limit)727 int bnxt_dev_xstats_get_names_op(struct rte_eth_dev *eth_dev,
728 		struct rte_eth_xstat_name *xstats_names,
729 		__rte_unused unsigned int limit)
730 {
731 	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
732 	const unsigned int stat_cnt = RTE_DIM(bnxt_rx_stats_strings) +
733 				RTE_DIM(bnxt_tx_stats_strings) +
734 				RTE_DIM(bnxt_func_stats_strings) +
735 				RTE_DIM(bnxt_rx_ext_stats_strings) +
736 				RTE_DIM(bnxt_tx_ext_stats_strings) +
737 				bnxt_flow_stats_cnt(bp);
738 	unsigned int i, count = 0;
739 	int rc;
740 
741 	rc = is_bnxt_in_error(bp);
742 	if (rc)
743 		return rc;
744 
745 	if (xstats_names != NULL) {
746 		count = 0;
747 
748 		for (i = 0; i < RTE_DIM(bnxt_rx_stats_strings); i++) {
749 			strlcpy(xstats_names[count].name,
750 				bnxt_rx_stats_strings[i].name,
751 				sizeof(xstats_names[count].name));
752 			count++;
753 		}
754 
755 		for (i = 0; i < RTE_DIM(bnxt_tx_stats_strings); i++) {
756 			strlcpy(xstats_names[count].name,
757 				bnxt_tx_stats_strings[i].name,
758 				sizeof(xstats_names[count].name));
759 			count++;
760 		}
761 
762 		for (i = 0; i < RTE_DIM(bnxt_func_stats_strings); i++) {
763 			strlcpy(xstats_names[count].name,
764 				bnxt_func_stats_strings[i].name,
765 				sizeof(xstats_names[count].name));
766 			count++;
767 		}
768 
769 		for (i = 0; i < RTE_DIM(bnxt_rx_ext_stats_strings); i++) {
770 			strlcpy(xstats_names[count].name,
771 				bnxt_rx_ext_stats_strings[i].name,
772 				sizeof(xstats_names[count].name));
773 
774 			count++;
775 		}
776 
777 		for (i = 0; i < RTE_DIM(bnxt_tx_ext_stats_strings); i++) {
778 			strlcpy(xstats_names[count].name,
779 				bnxt_tx_ext_stats_strings[i].name,
780 				sizeof(xstats_names[count].name));
781 
782 			count++;
783 		}
784 
785 		if (bp->fw_cap & BNXT_FW_CAP_ADV_FLOW_COUNTERS &&
786 		    bp->fw_cap & BNXT_FW_CAP_ADV_FLOW_MGMT &&
787 		    BNXT_FLOW_XSTATS_EN(bp)) {
788 			for (i = 0; i < bp->max_l2_ctx; i++) {
789 				char buf[RTE_ETH_XSTATS_NAME_SIZE];
790 
791 				sprintf(buf, "flow_%d_bytes", i);
792 				strlcpy(xstats_names[count].name, buf,
793 					sizeof(xstats_names[count].name));
794 				count++;
795 
796 				sprintf(buf, "flow_%d_packets", i);
797 				strlcpy(xstats_names[count].name, buf,
798 					sizeof(xstats_names[count].name));
799 
800 				count++;
801 			}
802 		}
803 	}
804 
805 	return stat_cnt;
806 }
807 
bnxt_dev_xstats_reset_op(struct rte_eth_dev * eth_dev)808 int bnxt_dev_xstats_reset_op(struct rte_eth_dev *eth_dev)
809 {
810 	struct bnxt *bp = eth_dev->data->dev_private;
811 	int ret;
812 
813 	ret = is_bnxt_in_error(bp);
814 	if (ret)
815 		return ret;
816 
817 	if (BNXT_VF(bp) || !BNXT_SINGLE_PF(bp) ||
818 	    !(bp->flags & BNXT_FLAG_PORT_STATS)) {
819 		PMD_DRV_LOG(ERR, "Operation not supported\n");
820 		return -ENOTSUP;
821 	}
822 
823 	ret = bnxt_hwrm_port_clr_stats(bp);
824 	if (ret != 0)
825 		PMD_DRV_LOG(ERR, "Failed to reset xstats: %s\n",
826 			    strerror(-ret));
827 
828 	return ret;
829 }
830 
831 /* Update the input context memory with the flow counter IDs
832  * of the flows that we are interested in.
833  * Also, update the output tables with the current local values
834  * since that is what will be used by FW to accumulate
835  */
bnxt_update_fc_pre_qstat(uint32_t * in_tbl,uint64_t * out_tbl,struct bnxt_filter_info * filter,uint32_t * ptbl_cnt)836 static void bnxt_update_fc_pre_qstat(uint32_t *in_tbl,
837 				     uint64_t *out_tbl,
838 				     struct bnxt_filter_info *filter,
839 				     uint32_t *ptbl_cnt)
840 {
841 	uint32_t in_tbl_cnt = *ptbl_cnt;
842 
843 	in_tbl[in_tbl_cnt] = filter->flow_id;
844 	out_tbl[2 * in_tbl_cnt] = filter->hw_stats.packets;
845 	out_tbl[2 * in_tbl_cnt + 1] = filter->hw_stats.bytes;
846 	in_tbl_cnt++;
847 	*ptbl_cnt = in_tbl_cnt;
848 }
849 
850 /* Post issuing counter_qstats cmd, update the driver's local stat
851  * entries with the values DMA-ed by FW in the output table
852  */
bnxt_update_fc_post_qstat(struct bnxt_filter_info * filter,uint64_t * out_tbl,uint32_t out_tbl_idx)853 static void bnxt_update_fc_post_qstat(struct bnxt_filter_info *filter,
854 				      uint64_t *out_tbl,
855 				      uint32_t out_tbl_idx)
856 {
857 	filter->hw_stats.packets = out_tbl[2 * out_tbl_idx];
858 	filter->hw_stats.bytes = out_tbl[(2 * out_tbl_idx) + 1];
859 }
860 
bnxt_update_fc_tbl(struct bnxt * bp,uint16_t ctr,struct bnxt_filter_info * en_tbl[],uint16_t in_flow_cnt)861 static int bnxt_update_fc_tbl(struct bnxt *bp, uint16_t ctr,
862 			      struct bnxt_filter_info *en_tbl[],
863 			      uint16_t in_flow_cnt)
864 {
865 	uint32_t *in_rx_tbl;
866 	uint64_t *out_rx_tbl;
867 	uint32_t in_rx_tbl_cnt = 0;
868 	uint32_t out_rx_tbl_cnt = 0;
869 	int i, rc = 0;
870 
871 	in_rx_tbl = (uint32_t *)bp->flow_stat->rx_fc_in_tbl.va;
872 	out_rx_tbl = (uint64_t *)bp->flow_stat->rx_fc_out_tbl.va;
873 
874 	for (i = 0; i < in_flow_cnt; i++) {
875 		if (!en_tbl[i])
876 			continue;
877 
878 		/* Currently only ingress/Rx flows are supported anyway. */
879 		bnxt_update_fc_pre_qstat(in_rx_tbl, out_rx_tbl,
880 					 en_tbl[i], &in_rx_tbl_cnt);
881 	}
882 
883 	/* Currently only ingress/Rx flows are supported */
884 	if (in_rx_tbl_cnt) {
885 		rc = bnxt_hwrm_cfa_counter_qstats(bp, BNXT_DIR_RX, ctr,
886 						  in_rx_tbl_cnt);
887 		if (rc)
888 			return rc;
889 	}
890 
891 	for (i = 0; i < in_flow_cnt; i++) {
892 		if (!en_tbl[i])
893 			continue;
894 
895 		/* Currently only ingress/Rx flows are supported */
896 		bnxt_update_fc_post_qstat(en_tbl[i], out_rx_tbl,
897 					  out_rx_tbl_cnt);
898 		out_rx_tbl_cnt++;
899 	}
900 
901 	return rc;
902 }
903 
904 /* Walks through the list which has all the flows
905  * requesting for explicit flow counters.
906  */
bnxt_flow_stats_req(struct bnxt * bp)907 int bnxt_flow_stats_req(struct bnxt *bp)
908 {
909 	int i;
910 	int rc = 0;
911 	struct rte_flow *flow;
912 	uint16_t in_flow_tbl_cnt = 0;
913 	struct bnxt_vnic_info *vnic = NULL;
914 	struct bnxt_filter_info *valid_en_tbl[bp->flow_stat->max_fc];
915 	uint16_t counter_type = CFA_COUNTER_CFG_IN_COUNTER_TYPE_FC;
916 
917 	bnxt_acquire_flow_lock(bp);
918 	for (i = 0; i < bp->max_vnics; i++) {
919 		vnic = &bp->vnic_info[i];
920 		if (vnic && vnic->fw_vnic_id == INVALID_VNIC_ID)
921 			continue;
922 
923 		if (STAILQ_EMPTY(&vnic->flow_list))
924 			continue;
925 
926 		STAILQ_FOREACH(flow, &vnic->flow_list, next) {
927 			if (!flow || !flow->filter)
928 				continue;
929 
930 			valid_en_tbl[in_flow_tbl_cnt++] = flow->filter;
931 			if (in_flow_tbl_cnt >= bp->flow_stat->max_fc) {
932 				rc = bnxt_update_fc_tbl(bp, counter_type,
933 							valid_en_tbl,
934 							in_flow_tbl_cnt);
935 				if (rc)
936 					goto err;
937 				in_flow_tbl_cnt = 0;
938 				continue;
939 			}
940 		}
941 	}
942 
943 	if (!in_flow_tbl_cnt) {
944 		bnxt_release_flow_lock(bp);
945 		goto out;
946 	}
947 
948 	rc = bnxt_update_fc_tbl(bp, counter_type, valid_en_tbl,
949 				in_flow_tbl_cnt);
950 	if (!rc) {
951 		bnxt_release_flow_lock(bp);
952 		return 0;
953 	}
954 
955 err:
956 	/* If cmd fails once, no need of
957 	 * invoking again every second
958 	 */
959 	bnxt_release_flow_lock(bp);
960 	bnxt_cancel_fc_thread(bp);
961 out:
962 	return rc;
963 }
964