net/bnxt: fix crash in xstats get
[dpdk.git] / drivers / net / bnxt / bnxt_stats.c
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_hwrm.h"
14 #include "bnxt_rxq.h"
15 #include "bnxt_stats.h"
16 #include "bnxt_txq.h"
17 #include "hsi_struct_def_dpdk.h"
18
19 static const struct bnxt_xstats_name_off bnxt_rx_stats_strings[] = {
20         {"rx_64b_frames", offsetof(struct rx_port_stats,
21                                 rx_64b_frames)},
22         {"rx_65b_127b_frames", offsetof(struct rx_port_stats,
23                                 rx_65b_127b_frames)},
24         {"rx_128b_255b_frames", offsetof(struct rx_port_stats,
25                                 rx_128b_255b_frames)},
26         {"rx_256b_511b_frames", offsetof(struct rx_port_stats,
27                                 rx_256b_511b_frames)},
28         {"rx_512b_1023b_frames", offsetof(struct rx_port_stats,
29                                 rx_512b_1023b_frames)},
30         {"rx_1024b_1518b_frames", offsetof(struct rx_port_stats,
31                                 rx_1024b_1518b_frames)},
32         {"rx_good_vlan_frames", offsetof(struct rx_port_stats,
33                                 rx_good_vlan_frames)},
34         {"rx_1519b_2047b_frames", offsetof(struct rx_port_stats,
35                                 rx_1519b_2047b_frames)},
36         {"rx_2048b_4095b_frames", offsetof(struct rx_port_stats,
37                                 rx_2048b_4095b_frames)},
38         {"rx_4096b_9216b_frames", offsetof(struct rx_port_stats,
39                                 rx_4096b_9216b_frames)},
40         {"rx_9217b_16383b_frames", offsetof(struct rx_port_stats,
41                                 rx_9217b_16383b_frames)},
42         {"rx_total_frames", offsetof(struct rx_port_stats,
43                                 rx_total_frames)},
44         {"rx_ucast_frames", offsetof(struct rx_port_stats,
45                                 rx_ucast_frames)},
46         {"rx_mcast_frames", offsetof(struct rx_port_stats,
47                                 rx_mcast_frames)},
48         {"rx_bcast_frames", offsetof(struct rx_port_stats,
49                                 rx_bcast_frames)},
50         {"rx_fcs_err_frames", offsetof(struct rx_port_stats,
51                                 rx_fcs_err_frames)},
52         {"rx_ctrl_frames", offsetof(struct rx_port_stats,
53                                 rx_ctrl_frames)},
54         {"rx_pause_frames", offsetof(struct rx_port_stats,
55                                 rx_pause_frames)},
56         {"rx_pfc_frames", offsetof(struct rx_port_stats,
57                                 rx_pfc_frames)},
58         {"rx_align_err_frames", offsetof(struct rx_port_stats,
59                                 rx_align_err_frames)},
60         {"rx_ovrsz_frames", offsetof(struct rx_port_stats,
61                                 rx_ovrsz_frames)},
62         {"rx_jbr_frames", offsetof(struct rx_port_stats,
63                                 rx_jbr_frames)},
64         {"rx_mtu_err_frames", offsetof(struct rx_port_stats,
65                                 rx_mtu_err_frames)},
66         {"rx_tagged_frames", offsetof(struct rx_port_stats,
67                                 rx_tagged_frames)},
68         {"rx_double_tagged_frames", offsetof(struct rx_port_stats,
69                                 rx_double_tagged_frames)},
70         {"rx_good_frames", offsetof(struct rx_port_stats,
71                                 rx_good_frames)},
72         {"rx_undrsz_frames", offsetof(struct rx_port_stats,
73                                 rx_undrsz_frames)},
74         {"rx_eee_lpi_events", offsetof(struct rx_port_stats,
75                                 rx_eee_lpi_events)},
76         {"rx_eee_lpi_duration", offsetof(struct rx_port_stats,
77                                 rx_eee_lpi_duration)},
78         {"rx_bytes", offsetof(struct rx_port_stats,
79                                 rx_bytes)},
80         {"rx_runt_bytes", offsetof(struct rx_port_stats,
81                                 rx_runt_bytes)},
82         {"rx_runt_frames", offsetof(struct rx_port_stats,
83                                 rx_runt_frames)},
84         {"rx_pfc_ena_frames_pri0", offsetof(struct rx_port_stats,
85                                 rx_pfc_ena_frames_pri0)},
86         {"rx_pfc_ena_frames_pri1", offsetof(struct rx_port_stats,
87                                 rx_pfc_ena_frames_pri1)},
88         {"rx_pfc_ena_frames_pri2", offsetof(struct rx_port_stats,
89                                 rx_pfc_ena_frames_pri2)},
90         {"rx_pfc_ena_frames_pri3", offsetof(struct rx_port_stats,
91                                 rx_pfc_ena_frames_pri3)},
92         {"rx_pfc_ena_frames_pri4", offsetof(struct rx_port_stats,
93                                 rx_pfc_ena_frames_pri4)},
94         {"rx_pfc_ena_frames_pri5", offsetof(struct rx_port_stats,
95                                 rx_pfc_ena_frames_pri5)},
96         {"rx_pfc_ena_frames_pri6", offsetof(struct rx_port_stats,
97                                 rx_pfc_ena_frames_pri6)},
98         {"rx_pfc_ena_frames_pri7", offsetof(struct rx_port_stats,
99                                 rx_pfc_ena_frames_pri7)},
100 };
101
102 static const struct bnxt_xstats_name_off bnxt_tx_stats_strings[] = {
103         {"tx_64b_frames", offsetof(struct tx_port_stats,
104                                 tx_64b_frames)},
105         {"tx_65b_127b_frames", offsetof(struct tx_port_stats,
106                                 tx_65b_127b_frames)},
107         {"tx_128b_255b_frames", offsetof(struct tx_port_stats,
108                                 tx_128b_255b_frames)},
109         {"tx_256b_511b_frames", offsetof(struct tx_port_stats,
110                                 tx_256b_511b_frames)},
111         {"tx_512b_1023b_frames", offsetof(struct tx_port_stats,
112                                 tx_512b_1023b_frames)},
113         {"tx_1024b_1518b_frames", offsetof(struct tx_port_stats,
114                                 tx_1024b_1518b_frames)},
115         {"tx_good_vlan_frames", offsetof(struct tx_port_stats,
116                                 tx_good_vlan_frames)},
117         {"tx_1519b_2047b_frames", offsetof(struct tx_port_stats,
118                                 tx_1519b_2047b_frames)},
119         {"tx_2048b_4095b_frames", offsetof(struct tx_port_stats,
120                                 tx_2048b_4095b_frames)},
121         {"tx_4096b_9216b_frames", offsetof(struct tx_port_stats,
122                                 tx_4096b_9216b_frames)},
123         {"tx_9217b_16383b_frames", offsetof(struct tx_port_stats,
124                                 tx_9217b_16383b_frames)},
125         {"tx_good_frames", offsetof(struct tx_port_stats,
126                                 tx_good_frames)},
127         {"tx_total_frames", offsetof(struct tx_port_stats,
128                                 tx_total_frames)},
129         {"tx_ucast_frames", offsetof(struct tx_port_stats,
130                                 tx_ucast_frames)},
131         {"tx_mcast_frames", offsetof(struct tx_port_stats,
132                                 tx_mcast_frames)},
133         {"tx_bcast_frames", offsetof(struct tx_port_stats,
134                                 tx_bcast_frames)},
135         {"tx_pause_frames", offsetof(struct tx_port_stats,
136                                 tx_pause_frames)},
137         {"tx_pfc_frames", offsetof(struct tx_port_stats,
138                                 tx_pfc_frames)},
139         {"tx_jabber_frames", offsetof(struct tx_port_stats,
140                                 tx_jabber_frames)},
141         {"tx_fcs_err_frames", offsetof(struct tx_port_stats,
142                                 tx_fcs_err_frames)},
143         {"tx_err", offsetof(struct tx_port_stats,
144                                 tx_err)},
145         {"tx_fifo_underruns", offsetof(struct tx_port_stats,
146                                 tx_fifo_underruns)},
147         {"tx_eee_lpi_events", offsetof(struct tx_port_stats,
148                                 tx_eee_lpi_events)},
149         {"tx_eee_lpi_duration", offsetof(struct tx_port_stats,
150                                 tx_eee_lpi_duration)},
151         {"tx_total_collisions", offsetof(struct tx_port_stats,
152                                 tx_total_collisions)},
153         {"tx_bytes", offsetof(struct tx_port_stats,
154                                 tx_bytes)},
155         {"tx_pfc_ena_frames_pri0", offsetof(struct tx_port_stats,
156                                 tx_pfc_ena_frames_pri0)},
157         {"tx_pfc_ena_frames_pri1", offsetof(struct tx_port_stats,
158                                 tx_pfc_ena_frames_pri1)},
159         {"tx_pfc_ena_frames_pri2", offsetof(struct tx_port_stats,
160                                 tx_pfc_ena_frames_pri2)},
161         {"tx_pfc_ena_frames_pri3", offsetof(struct tx_port_stats,
162                                 tx_pfc_ena_frames_pri3)},
163         {"tx_pfc_ena_frames_pri4", offsetof(struct tx_port_stats,
164                                 tx_pfc_ena_frames_pri4)},
165         {"tx_pfc_ena_frames_pri5", offsetof(struct tx_port_stats,
166                                 tx_pfc_ena_frames_pri5)},
167         {"tx_pfc_ena_frames_pri6", offsetof(struct tx_port_stats,
168                                 tx_pfc_ena_frames_pri6)},
169         {"tx_pfc_ena_frames_pri7", offsetof(struct tx_port_stats,
170                                 tx_pfc_ena_frames_pri7)},
171 };
172
173 static const struct bnxt_xstats_name_off bnxt_func_stats_strings[] = {
174         {"tx_ucast_pkts", offsetof(struct hwrm_func_qstats_output,
175                                 tx_ucast_pkts)},
176         {"tx_mcast_pkts", offsetof(struct hwrm_func_qstats_output,
177                                 tx_mcast_pkts)},
178         {"tx_bcast_pkts", offsetof(struct hwrm_func_qstats_output,
179                                 tx_bcast_pkts)},
180         {"tx_discard_pkts", offsetof(struct hwrm_func_qstats_output,
181                                 tx_discard_pkts)},
182         {"tx_drop_pkts", offsetof(struct hwrm_func_qstats_output,
183                                 tx_drop_pkts)},
184         {"tx_ucast_bytes", offsetof(struct hwrm_func_qstats_output,
185                                 tx_ucast_bytes)},
186         {"tx_mcast_bytes", offsetof(struct hwrm_func_qstats_output,
187                                 tx_mcast_bytes)},
188         {"tx_bcast_bytes", offsetof(struct hwrm_func_qstats_output,
189                                 tx_bcast_bytes)},
190         {"rx_ucast_pkts", offsetof(struct hwrm_func_qstats_output,
191                                 rx_ucast_pkts)},
192         {"rx_mcast_pkts", offsetof(struct hwrm_func_qstats_output,
193                                 rx_mcast_pkts)},
194         {"rx_bcast_pkts", offsetof(struct hwrm_func_qstats_output,
195                                 rx_bcast_pkts)},
196         {"rx_discard_pkts", offsetof(struct hwrm_func_qstats_output,
197                                 rx_discard_pkts)},
198         {"rx_drop_pkts", offsetof(struct hwrm_func_qstats_output,
199                                 rx_drop_pkts)},
200         {"rx_ucast_bytes", offsetof(struct hwrm_func_qstats_output,
201                                 rx_ucast_bytes)},
202         {"rx_mcast_bytes", offsetof(struct hwrm_func_qstats_output,
203                                 rx_mcast_bytes)},
204         {"rx_bcast_bytes", offsetof(struct hwrm_func_qstats_output,
205                                 rx_bcast_bytes)},
206         {"rx_agg_pkts", offsetof(struct hwrm_func_qstats_output,
207                                 rx_agg_pkts)},
208         {"rx_agg_bytes", offsetof(struct hwrm_func_qstats_output,
209                                 rx_agg_bytes)},
210         {"rx_agg_events", offsetof(struct hwrm_func_qstats_output,
211                                 rx_agg_events)},
212         {"rx_agg_aborts", offsetof(struct hwrm_func_qstats_output,
213                                 rx_agg_aborts)},
214 };
215
216 static const struct bnxt_xstats_name_off bnxt_rx_ext_stats_strings[] = {
217         {"link_down_events", offsetof(struct rx_port_stats_ext,
218                                 link_down_events)},
219         {"continuous_pause_events", offsetof(struct rx_port_stats_ext,
220                                 continuous_pause_events)},
221         {"resume_pause_events", offsetof(struct rx_port_stats_ext,
222                                 resume_pause_events)},
223         {"continuous_roce_pause_events", offsetof(struct rx_port_stats_ext,
224                                 continuous_roce_pause_events)},
225         {"resume_roce_pause_events", offsetof(struct rx_port_stats_ext,
226                                 resume_roce_pause_events)},
227         {"rx_bytes_cos0", offsetof(struct rx_port_stats_ext,
228                                 rx_bytes_cos0)},
229         {"rx_bytes_cos1", offsetof(struct rx_port_stats_ext,
230                                 rx_bytes_cos1)},
231         {"rx_bytes_cos2", offsetof(struct rx_port_stats_ext,
232                                 rx_bytes_cos2)},
233         {"rx_bytes_cos3", offsetof(struct rx_port_stats_ext,
234                                 rx_bytes_cos3)},
235         {"rx_bytes_cos4", offsetof(struct rx_port_stats_ext,
236                                 rx_bytes_cos4)},
237         {"rx_bytes_cos5", offsetof(struct rx_port_stats_ext,
238                                 rx_bytes_cos5)},
239         {"rx_bytes_cos6", offsetof(struct rx_port_stats_ext,
240                                 rx_bytes_cos6)},
241         {"rx_bytes_cos7", offsetof(struct rx_port_stats_ext,
242                                 rx_bytes_cos7)},
243         {"rx_packets_cos0", offsetof(struct rx_port_stats_ext,
244                                 rx_packets_cos0)},
245         {"rx_packets_cos1", offsetof(struct rx_port_stats_ext,
246                                 rx_packets_cos1)},
247         {"rx_packets_cos2", offsetof(struct rx_port_stats_ext,
248                                 rx_packets_cos2)},
249         {"rx_packets_cos3", offsetof(struct rx_port_stats_ext,
250                                 rx_packets_cos3)},
251         {"rx_packets_cos4", offsetof(struct rx_port_stats_ext,
252                                 rx_packets_cos4)},
253         {"rx_packets_cos5", offsetof(struct rx_port_stats_ext,
254                                 rx_packets_cos5)},
255         {"rx_packets_cos6", offsetof(struct rx_port_stats_ext,
256                                 rx_packets_cos6)},
257         {"rx_packets_cos7", offsetof(struct rx_port_stats_ext,
258                                 rx_packets_cos7)},
259         {"pfc_pri0_rx_duration_us", offsetof(struct rx_port_stats_ext,
260                                 pfc_pri0_rx_duration_us)},
261         {"pfc_pri0_rx_transitions", offsetof(struct rx_port_stats_ext,
262                                 pfc_pri0_rx_transitions)},
263         {"pfc_pri1_rx_duration_us", offsetof(struct rx_port_stats_ext,
264                                 pfc_pri1_rx_duration_us)},
265         {"pfc_pri1_rx_transitions", offsetof(struct rx_port_stats_ext,
266                                 pfc_pri1_rx_transitions)},
267         {"pfc_pri2_rx_duration_us", offsetof(struct rx_port_stats_ext,
268                                 pfc_pri2_rx_duration_us)},
269         {"pfc_pri2_rx_transitions", offsetof(struct rx_port_stats_ext,
270                                 pfc_pri2_rx_transitions)},
271         {"pfc_pri3_rx_duration_us", offsetof(struct rx_port_stats_ext,
272                                 pfc_pri3_rx_duration_us)},
273         {"pfc_pri3_rx_transitions", offsetof(struct rx_port_stats_ext,
274                                 pfc_pri3_rx_transitions)},
275         {"pfc_pri4_rx_duration_us", offsetof(struct rx_port_stats_ext,
276                                 pfc_pri4_rx_duration_us)},
277         {"pfc_pri4_rx_transitions", offsetof(struct rx_port_stats_ext,
278                                 pfc_pri4_rx_transitions)},
279         {"pfc_pri5_rx_duration_us", offsetof(struct rx_port_stats_ext,
280                                 pfc_pri5_rx_duration_us)},
281         {"pfc_pri5_rx_transitions", offsetof(struct rx_port_stats_ext,
282                                 pfc_pri5_rx_transitions)},
283         {"pfc_pri6_rx_duration_us", offsetof(struct rx_port_stats_ext,
284                                 pfc_pri6_rx_duration_us)},
285         {"pfc_pri6_rx_transitions", offsetof(struct rx_port_stats_ext,
286                                 pfc_pri6_rx_transitions)},
287         {"pfc_pri7_rx_duration_us", offsetof(struct rx_port_stats_ext,
288                                 pfc_pri7_rx_duration_us)},
289         {"pfc_pri7_rx_transitions", offsetof(struct rx_port_stats_ext,
290                                 pfc_pri7_rx_transitions)},
291 };
292
293 static const struct bnxt_xstats_name_off bnxt_tx_ext_stats_strings[] = {
294         {"tx_bytes_cos0", offsetof(struct tx_port_stats_ext,
295                                 tx_bytes_cos0)},
296         {"tx_bytes_cos1", offsetof(struct tx_port_stats_ext,
297                                 tx_bytes_cos1)},
298         {"tx_bytes_cos2", offsetof(struct tx_port_stats_ext,
299                                 tx_bytes_cos2)},
300         {"tx_bytes_cos3", offsetof(struct tx_port_stats_ext,
301                                 tx_bytes_cos3)},
302         {"tx_bytes_cos4", offsetof(struct tx_port_stats_ext,
303                                 tx_bytes_cos4)},
304         {"tx_bytes_cos5", offsetof(struct tx_port_stats_ext,
305                                 tx_bytes_cos5)},
306         {"tx_bytes_cos6", offsetof(struct tx_port_stats_ext,
307                                 tx_bytes_cos6)},
308         {"tx_bytes_cos7", offsetof(struct tx_port_stats_ext,
309                                 tx_bytes_cos7)},
310         {"tx_packets_cos0", offsetof(struct tx_port_stats_ext,
311                                 tx_packets_cos0)},
312         {"tx_packets_cos1", offsetof(struct tx_port_stats_ext,
313                                 tx_packets_cos1)},
314         {"tx_packets_cos2", offsetof(struct tx_port_stats_ext,
315                                 tx_packets_cos2)},
316         {"tx_packets_cos3", offsetof(struct tx_port_stats_ext,
317                                 tx_packets_cos3)},
318         {"tx_packets_cos4", offsetof(struct tx_port_stats_ext,
319                                 tx_packets_cos4)},
320         {"tx_packets_cos5", offsetof(struct tx_port_stats_ext,
321                                 tx_packets_cos5)},
322         {"tx_packets_cos6", offsetof(struct tx_port_stats_ext,
323                                 tx_packets_cos6)},
324         {"tx_packets_cos7", offsetof(struct tx_port_stats_ext,
325                                 tx_packets_cos7)},
326         {"pfc_pri0_tx_duration_us", offsetof(struct tx_port_stats_ext,
327                                 pfc_pri0_tx_duration_us)},
328         {"pfc_pri0_tx_transitions", offsetof(struct tx_port_stats_ext,
329                                 pfc_pri0_tx_transitions)},
330         {"pfc_pri1_tx_duration_us", offsetof(struct tx_port_stats_ext,
331                                 pfc_pri1_tx_duration_us)},
332         {"pfc_pri1_tx_transitions", offsetof(struct tx_port_stats_ext,
333                                 pfc_pri1_tx_transitions)},
334         {"pfc_pri2_tx_duration_us", offsetof(struct tx_port_stats_ext,
335                                 pfc_pri2_tx_duration_us)},
336         {"pfc_pri2_tx_transitions", offsetof(struct tx_port_stats_ext,
337                                 pfc_pri2_tx_transitions)},
338         {"pfc_pri3_tx_duration_us", offsetof(struct tx_port_stats_ext,
339                                 pfc_pri3_tx_duration_us)},
340         {"pfc_pri3_tx_transitions", offsetof(struct tx_port_stats_ext,
341                                 pfc_pri3_tx_transitions)},
342         {"pfc_pri4_tx_duration_us", offsetof(struct tx_port_stats_ext,
343                                 pfc_pri4_tx_duration_us)},
344         {"pfc_pri4_tx_transitions", offsetof(struct tx_port_stats_ext,
345                                 pfc_pri4_tx_transitions)},
346         {"pfc_pri5_tx_duration_us", offsetof(struct tx_port_stats_ext,
347                                 pfc_pri5_tx_duration_us)},
348         {"pfc_pri5_tx_transitions", offsetof(struct tx_port_stats_ext,
349                                 pfc_pri5_tx_transitions)},
350         {"pfc_pri6_tx_duration_us", offsetof(struct tx_port_stats_ext,
351                                 pfc_pri6_tx_duration_us)},
352         {"pfc_pri6_tx_transitions", offsetof(struct tx_port_stats_ext,
353                                 pfc_pri6_tx_transitions)},
354         {"pfc_pri7_tx_duration_us", offsetof(struct tx_port_stats_ext,
355                                 pfc_pri7_tx_duration_us)},
356         {"pfc_pri7_tx_transitions", offsetof(struct tx_port_stats_ext,
357                                 pfc_pri7_tx_transitions)},
358 };
359
360 /*
361  * Statistics functions
362  */
363
364 void bnxt_free_stats(struct bnxt *bp)
365 {
366         int i;
367
368         for (i = 0; i < (int)bp->tx_cp_nr_rings; i++) {
369                 struct bnxt_tx_queue *txq = bp->tx_queues[i];
370
371                 bnxt_free_txq_stats(txq);
372         }
373         for (i = 0; i < (int)bp->rx_cp_nr_rings; i++) {
374                 struct bnxt_rx_queue *rxq = bp->rx_queues[i];
375
376                 bnxt_free_rxq_stats(rxq);
377         }
378 }
379
380 int bnxt_stats_get_op(struct rte_eth_dev *eth_dev,
381                            struct rte_eth_stats *bnxt_stats)
382 {
383         int rc = 0;
384         unsigned int i;
385         struct bnxt *bp = eth_dev->data->dev_private;
386         unsigned int num_q_stats;
387
388         rc = is_bnxt_in_error(bp);
389         if (rc)
390                 return rc;
391
392         memset(bnxt_stats, 0, sizeof(*bnxt_stats));
393         if (!(bp->flags & BNXT_FLAG_INIT_DONE)) {
394                 PMD_DRV_LOG(ERR, "Device Initialization not complete!\n");
395                 return -EIO;
396         }
397
398         num_q_stats = RTE_MIN(bp->rx_cp_nr_rings,
399                               (unsigned int)RTE_ETHDEV_QUEUE_STAT_CNTRS);
400
401         for (i = 0; i < num_q_stats; i++) {
402                 struct bnxt_rx_queue *rxq = bp->rx_queues[i];
403                 struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
404
405                 rc = bnxt_hwrm_ctx_qstats(bp, cpr->hw_stats_ctx_id, i,
406                                      bnxt_stats, 1);
407                 if (unlikely(rc))
408                         return rc;
409                 bnxt_stats->rx_nombuf +=
410                                 rte_atomic64_read(&rxq->rx_mbuf_alloc_fail);
411         }
412
413         num_q_stats = RTE_MIN(bp->tx_cp_nr_rings,
414                               (unsigned int)RTE_ETHDEV_QUEUE_STAT_CNTRS);
415
416         for (i = 0; i < num_q_stats; i++) {
417                 struct bnxt_tx_queue *txq = bp->tx_queues[i];
418                 struct bnxt_cp_ring_info *cpr = txq->cp_ring;
419
420                 rc = bnxt_hwrm_ctx_qstats(bp, cpr->hw_stats_ctx_id, i,
421                                      bnxt_stats, 0);
422                 if (unlikely(rc))
423                         return rc;
424         }
425
426         rc = bnxt_hwrm_func_qstats(bp, 0xffff, bnxt_stats);
427         return rc;
428 }
429
430 int bnxt_stats_reset_op(struct rte_eth_dev *eth_dev)
431 {
432         struct bnxt *bp = eth_dev->data->dev_private;
433         unsigned int i;
434         int ret;
435
436         ret = is_bnxt_in_error(bp);
437         if (ret)
438                 return ret;
439
440         if (!(bp->flags & BNXT_FLAG_INIT_DONE)) {
441                 PMD_DRV_LOG(ERR, "Device Initialization not complete!\n");
442                 return -EINVAL;
443         }
444
445         ret = bnxt_clear_all_hwrm_stat_ctxs(bp);
446         for (i = 0; i < bp->rx_cp_nr_rings; i++) {
447                 struct bnxt_rx_queue *rxq = bp->rx_queues[i];
448
449                 rte_atomic64_clear(&rxq->rx_mbuf_alloc_fail);
450         }
451
452         return ret;
453 }
454
455 int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
456                            struct rte_eth_xstat *xstats, unsigned int n)
457 {
458         struct bnxt *bp = eth_dev->data->dev_private;
459         unsigned int count, i;
460         uint64_t tx_drop_pkts;
461         unsigned int rx_port_stats_ext_cnt;
462         unsigned int tx_port_stats_ext_cnt;
463         unsigned int stat_size = sizeof(uint64_t);
464         unsigned int stat_count;
465         int rc;
466
467         rc = is_bnxt_in_error(bp);
468         if (rc)
469                 return rc;
470
471         if (xstats == NULL)
472                 return 0;
473
474         memset(xstats, 0, sizeof(*xstats));
475
476         bnxt_hwrm_port_qstats(bp);
477         bnxt_hwrm_func_qstats_tx_drop(bp, 0xffff, &tx_drop_pkts);
478         bnxt_hwrm_ext_port_qstats(bp);
479         rx_port_stats_ext_cnt = RTE_MIN(RTE_DIM(bnxt_rx_ext_stats_strings),
480                                         (bp->fw_rx_port_stats_ext_size /
481                                          stat_size));
482         tx_port_stats_ext_cnt = RTE_MIN(RTE_DIM(bnxt_tx_ext_stats_strings),
483                                         (bp->fw_tx_port_stats_ext_size /
484                                          stat_size));
485
486         count = RTE_DIM(bnxt_rx_stats_strings) +
487                 RTE_DIM(bnxt_tx_stats_strings) + 1/* For tx_drop_pkts */ +
488                 RTE_DIM(bnxt_rx_ext_stats_strings) +
489                 RTE_DIM(bnxt_tx_ext_stats_strings);
490         stat_count = count;
491
492         if (n < count)
493                 return count;
494
495         count = 0;
496         for (i = 0; i < RTE_DIM(bnxt_rx_stats_strings); i++) {
497                 uint64_t *rx_stats = (uint64_t *)bp->hw_rx_port_stats;
498                 xstats[count].id = count;
499                 xstats[count].value = rte_le_to_cpu_64(
500                                 *(uint64_t *)((char *)rx_stats +
501                                 bnxt_rx_stats_strings[i].offset));
502                 count++;
503         }
504
505         for (i = 0; i < RTE_DIM(bnxt_tx_stats_strings); i++) {
506                 uint64_t *tx_stats = (uint64_t *)bp->hw_tx_port_stats;
507                 xstats[count].id = count;
508                 xstats[count].value = rte_le_to_cpu_64(
509                                  *(uint64_t *)((char *)tx_stats +
510                                 bnxt_tx_stats_strings[i].offset));
511                 count++;
512         }
513
514         /* The Tx drop pkts aka the Anti spoof coounter */
515         xstats[count].id = count;
516         xstats[count].value = rte_le_to_cpu_64(tx_drop_pkts);
517         count++;
518
519         for (i = 0; i < rx_port_stats_ext_cnt; i++) {
520                 uint64_t *rx_stats_ext = (uint64_t *)bp->hw_rx_port_stats_ext;
521
522                 xstats[count].value = rte_le_to_cpu_64
523                                         (*(uint64_t *)((char *)rx_stats_ext +
524                                          bnxt_rx_ext_stats_strings[i].offset));
525
526                 count++;
527         }
528
529         for (i = 0; i < tx_port_stats_ext_cnt; i++) {
530                 uint64_t *tx_stats_ext = (uint64_t *)bp->hw_tx_port_stats_ext;
531
532                 xstats[count].value = rte_le_to_cpu_64
533                                         (*(uint64_t *)((char *)tx_stats_ext +
534                                          bnxt_tx_ext_stats_strings[i].offset));
535
536                 count++;
537         }
538
539         return stat_count;
540 }
541
542 int bnxt_dev_xstats_get_names_op(__rte_unused struct rte_eth_dev *eth_dev,
543         struct rte_eth_xstat_name *xstats_names,
544         __rte_unused unsigned int limit)
545 {
546         /* Account for the Tx drop pkts aka the Anti spoof counter */
547         const unsigned int stat_cnt = RTE_DIM(bnxt_rx_stats_strings) +
548                                 RTE_DIM(bnxt_tx_stats_strings) + 1 +
549                                 RTE_DIM(bnxt_rx_ext_stats_strings) +
550                                 RTE_DIM(bnxt_tx_ext_stats_strings);
551         struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
552         unsigned int i, count;
553         int rc;
554
555         rc = is_bnxt_in_error(bp);
556         if (rc)
557                 return rc;
558
559         if (xstats_names != NULL) {
560                 count = 0;
561
562                 for (i = 0; i < RTE_DIM(bnxt_rx_stats_strings); i++) {
563                         strlcpy(xstats_names[count].name,
564                                 bnxt_rx_stats_strings[i].name,
565                                 sizeof(xstats_names[count].name));
566                         count++;
567                 }
568
569                 for (i = 0; i < RTE_DIM(bnxt_tx_stats_strings); i++) {
570                         strlcpy(xstats_names[count].name,
571                                 bnxt_tx_stats_strings[i].name,
572                                 sizeof(xstats_names[count].name));
573                         count++;
574                 }
575
576                 strlcpy(xstats_names[count].name,
577                         bnxt_func_stats_strings[4].name,
578                         sizeof(xstats_names[count].name));
579                 count++;
580
581                 for (i = 0; i < RTE_DIM(bnxt_rx_ext_stats_strings); i++) {
582                         strlcpy(xstats_names[count].name,
583                                 bnxt_rx_ext_stats_strings[i].name,
584                                 sizeof(xstats_names[count].name));
585
586                         count++;
587                 }
588
589                 for (i = 0; i < RTE_DIM(bnxt_tx_ext_stats_strings); i++) {
590                         strlcpy(xstats_names[count].name,
591                                 bnxt_tx_ext_stats_strings[i].name,
592                                 sizeof(xstats_names[count].name));
593
594                         count++;
595                 }
596
597         }
598         return stat_cnt;
599 }
600
601 int bnxt_dev_xstats_reset_op(struct rte_eth_dev *eth_dev)
602 {
603         struct bnxt *bp = eth_dev->data->dev_private;
604         int ret;
605
606         ret = is_bnxt_in_error(bp);
607         if (ret)
608                 return ret;
609
610         if (BNXT_VF(bp) || !BNXT_SINGLE_PF(bp) ||
611             !(bp->flags & BNXT_FLAG_PORT_STATS)) {
612                 PMD_DRV_LOG(ERR, "Operation not supported\n");
613                 return -ENOTSUP;
614         }
615
616         ret = bnxt_hwrm_port_clr_stats(bp);
617         if (ret != 0)
618                 PMD_DRV_LOG(ERR, "Failed to reset xstats: %s\n",
619                             strerror(-ret));
620
621         return ret;
622 }
623
624 int bnxt_dev_xstats_get_by_id_op(struct rte_eth_dev *dev, const uint64_t *ids,
625                 uint64_t *values, unsigned int limit)
626 {
627         /* Account for the Tx drop pkts aka the Anti spoof counter */
628         const unsigned int stat_cnt = RTE_DIM(bnxt_rx_stats_strings) +
629                                 RTE_DIM(bnxt_tx_stats_strings) + 1 +
630                                 RTE_DIM(bnxt_rx_ext_stats_strings) +
631                                 RTE_DIM(bnxt_tx_ext_stats_strings);
632         struct bnxt *bp = dev->data->dev_private;
633         struct rte_eth_xstat xstats[stat_cnt];
634         uint64_t values_copy[stat_cnt];
635         uint16_t i;
636         int rc;
637
638         rc = is_bnxt_in_error(bp);
639         if (rc)
640                 return rc;
641
642         if (!ids)
643                 return bnxt_dev_xstats_get_op(dev, xstats, stat_cnt);
644
645         bnxt_dev_xstats_get_by_id_op(dev, NULL, values_copy, stat_cnt);
646         for (i = 0; i < limit; i++) {
647                 if (ids[i] >= stat_cnt) {
648                         PMD_DRV_LOG(ERR, "id value isn't valid");
649                         return -EINVAL;
650                 }
651                 values[i] = values_copy[ids[i]];
652         }
653         return stat_cnt;
654 }
655
656 int bnxt_dev_xstats_get_names_by_id_op(struct rte_eth_dev *dev,
657                                 struct rte_eth_xstat_name *xstats_names,
658                                 const uint64_t *ids, unsigned int limit)
659 {
660         /* Account for the Tx drop pkts aka the Anti spoof counter */
661         const unsigned int stat_cnt = RTE_DIM(bnxt_rx_stats_strings) +
662                                 RTE_DIM(bnxt_tx_stats_strings) + 1 +
663                                 RTE_DIM(bnxt_rx_ext_stats_strings) +
664                                 RTE_DIM(bnxt_tx_ext_stats_strings);
665         struct rte_eth_xstat_name xstats_names_copy[stat_cnt];
666         struct bnxt *bp = dev->data->dev_private;
667         uint16_t i;
668         int rc;
669
670         rc = is_bnxt_in_error(bp);
671         if (rc)
672                 return rc;
673
674         if (!ids)
675                 return bnxt_dev_xstats_get_names_op(dev, xstats_names,
676                                                     stat_cnt);
677         bnxt_dev_xstats_get_names_by_id_op(dev, xstats_names_copy, NULL,
678                         stat_cnt);
679
680         for (i = 0; i < limit; i++) {
681                 if (ids[i] >= stat_cnt) {
682                         PMD_DRV_LOG(ERR, "id value isn't valid");
683                         return -EINVAL;
684                 }
685                 strcpy(xstats_names[i].name,
686                                 xstats_names_copy[ids[i]].name);
687         }
688         return stat_cnt;
689 }