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