New upstream version 18.02
[deb_dpdk.git] / drivers / net / bnxt / bnxt_stats.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) Broadcom Limited.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Broadcom Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <inttypes.h>
35
36 #include <rte_byteorder.h>
37
38 #include "bnxt.h"
39 #include "bnxt_cpr.h"
40 #include "bnxt_hwrm.h"
41 #include "bnxt_rxq.h"
42 #include "bnxt_stats.h"
43 #include "bnxt_txq.h"
44 #include "hsi_struct_def_dpdk.h"
45
46 static const struct bnxt_xstats_name_off bnxt_rx_stats_strings[] = {
47         {"rx_64b_frames", offsetof(struct rx_port_stats,
48                                 rx_64b_frames)},
49         {"rx_65b_127b_frames", offsetof(struct rx_port_stats,
50                                 rx_65b_127b_frames)},
51         {"rx_128b_255b_frames", offsetof(struct rx_port_stats,
52                                 rx_128b_255b_frames)},
53         {"rx_256b_511b_frames", offsetof(struct rx_port_stats,
54                                 rx_256b_511b_frames)},
55         {"rx_512b_1023b_frames", offsetof(struct rx_port_stats,
56                                 rx_512b_1023b_frames)},
57         {"rx_1024b_1518_frames", offsetof(struct rx_port_stats,
58                                 rx_1024b_1518_frames)},
59         {"rx_good_vlan_frames", offsetof(struct rx_port_stats,
60                                 rx_good_vlan_frames)},
61         {"rx_1519b_2047b_frames", offsetof(struct rx_port_stats,
62                                 rx_1519b_2047b_frames)},
63         {"rx_2048b_4095b_frames", offsetof(struct rx_port_stats,
64                                 rx_2048b_4095b_frames)},
65         {"rx_4096b_9216b_frames", offsetof(struct rx_port_stats,
66                                 rx_4096b_9216b_frames)},
67         {"rx_9217b_16383b_frames", offsetof(struct rx_port_stats,
68                                 rx_9217b_16383b_frames)},
69         {"rx_total_frames", offsetof(struct rx_port_stats,
70                                 rx_total_frames)},
71         {"rx_ucast_frames", offsetof(struct rx_port_stats,
72                                 rx_ucast_frames)},
73         {"rx_mcast_frames", offsetof(struct rx_port_stats,
74                                 rx_mcast_frames)},
75         {"rx_bcast_frames", offsetof(struct rx_port_stats,
76                                 rx_bcast_frames)},
77         {"rx_fcs_err_frames", offsetof(struct rx_port_stats,
78                                 rx_fcs_err_frames)},
79         {"rx_ctrl_frames", offsetof(struct rx_port_stats,
80                                 rx_ctrl_frames)},
81         {"rx_pause_frames", offsetof(struct rx_port_stats,
82                                 rx_pause_frames)},
83         {"rx_pfc_frames", offsetof(struct rx_port_stats,
84                                 rx_pfc_frames)},
85         {"rx_align_err_frames", offsetof(struct rx_port_stats,
86                                 rx_align_err_frames)},
87         {"rx_ovrsz_frames", offsetof(struct rx_port_stats,
88                                 rx_ovrsz_frames)},
89         {"rx_jbr_frames", offsetof(struct rx_port_stats,
90                                 rx_jbr_frames)},
91         {"rx_mtu_err_frames", offsetof(struct rx_port_stats,
92                                 rx_mtu_err_frames)},
93         {"rx_tagged_frames", offsetof(struct rx_port_stats,
94                                 rx_tagged_frames)},
95         {"rx_double_tagged_frames", offsetof(struct rx_port_stats,
96                                 rx_double_tagged_frames)},
97         {"rx_good_frames", offsetof(struct rx_port_stats,
98                                 rx_good_frames)},
99         {"rx_undrsz_frames", offsetof(struct rx_port_stats,
100                                 rx_undrsz_frames)},
101         {"rx_eee_lpi_events", offsetof(struct rx_port_stats,
102                                 rx_eee_lpi_events)},
103         {"rx_eee_lpi_duration", offsetof(struct rx_port_stats,
104                                 rx_eee_lpi_duration)},
105         {"rx_bytes", offsetof(struct rx_port_stats,
106                                 rx_bytes)},
107         {"rx_runt_bytes", offsetof(struct rx_port_stats,
108                                 rx_runt_bytes)},
109         {"rx_runt_frames", offsetof(struct rx_port_stats,
110                                 rx_runt_frames)},
111 };
112
113 static const struct bnxt_xstats_name_off bnxt_tx_stats_strings[] = {
114         {"tx_64b_frames", offsetof(struct tx_port_stats,
115                                 tx_64b_frames)},
116         {"tx_65b_127b_frames", offsetof(struct tx_port_stats,
117                                 tx_65b_127b_frames)},
118         {"tx_128b_255b_frames", offsetof(struct tx_port_stats,
119                                 tx_128b_255b_frames)},
120         {"tx_256b_511b_frames", offsetof(struct tx_port_stats,
121                                 tx_256b_511b_frames)},
122         {"tx_512b_1023b_frames", offsetof(struct tx_port_stats,
123                                 tx_512b_1023b_frames)},
124         {"tx_1024b_1518_frames", offsetof(struct tx_port_stats,
125                                 tx_1024b_1518_frames)},
126         {"tx_good_vlan_frames", offsetof(struct tx_port_stats,
127                                 tx_good_vlan_frames)},
128         {"tx_1519b_2047_frames", offsetof(struct tx_port_stats,
129                                 tx_1519b_2047_frames)},
130         {"tx_2048b_4095b_frames", offsetof(struct tx_port_stats,
131                                 tx_2048b_4095b_frames)},
132         {"tx_4096b_9216b_frames", offsetof(struct tx_port_stats,
133                                 tx_4096b_9216b_frames)},
134         {"tx_9217b_16383b_frames", offsetof(struct tx_port_stats,
135                                 tx_9217b_16383b_frames)},
136         {"tx_good_frames", offsetof(struct tx_port_stats,
137                                 tx_good_frames)},
138         {"tx_total_frames", offsetof(struct tx_port_stats,
139                                 tx_total_frames)},
140         {"tx_ucast_frames", offsetof(struct tx_port_stats,
141                                 tx_ucast_frames)},
142         {"tx_mcast_frames", offsetof(struct tx_port_stats,
143                                 tx_mcast_frames)},
144         {"tx_bcast_frames", offsetof(struct tx_port_stats,
145                                 tx_bcast_frames)},
146         {"tx_pause_frames", offsetof(struct tx_port_stats,
147                                 tx_pause_frames)},
148         {"tx_pfc_frames", offsetof(struct tx_port_stats,
149                                 tx_pfc_frames)},
150         {"tx_jabber_frames", offsetof(struct tx_port_stats,
151                                 tx_jabber_frames)},
152         {"tx_fcs_err_frames", offsetof(struct tx_port_stats,
153                                 tx_fcs_err_frames)},
154         {"tx_err", offsetof(struct tx_port_stats,
155                                 tx_err)},
156         {"tx_fifo_underruns", offsetof(struct tx_port_stats,
157                                 tx_fifo_underruns)},
158         {"tx_eee_lpi_events", offsetof(struct tx_port_stats,
159                                 tx_eee_lpi_events)},
160         {"tx_eee_lpi_duration", offsetof(struct tx_port_stats,
161                                 tx_eee_lpi_duration)},
162         {"tx_total_collisions", offsetof(struct tx_port_stats,
163                                 tx_total_collisions)},
164         {"tx_bytes", offsetof(struct tx_port_stats,
165                                 tx_bytes)},
166 };
167
168 static const struct bnxt_xstats_name_off bnxt_func_stats_strings[] = {
169         {"tx_ucast_pkts", offsetof(struct hwrm_func_qstats_output,
170                                 tx_ucast_pkts)},
171         {"tx_mcast_pkts", offsetof(struct hwrm_func_qstats_output,
172                                 tx_mcast_pkts)},
173         {"tx_bcast_pkts", offsetof(struct hwrm_func_qstats_output,
174                                 tx_bcast_pkts)},
175         {"tx_err_pkts", offsetof(struct hwrm_func_qstats_output,
176                                 tx_err_pkts)},
177         {"tx_drop_pkts", offsetof(struct hwrm_func_qstats_output,
178                                 tx_drop_pkts)},
179         {"tx_ucast_bytes", offsetof(struct hwrm_func_qstats_output,
180                                 tx_ucast_bytes)},
181         {"tx_mcast_bytes", offsetof(struct hwrm_func_qstats_output,
182                                 tx_mcast_bytes)},
183         {"tx_bcast_bytes", offsetof(struct hwrm_func_qstats_output,
184                                 tx_bcast_bytes)},
185         {"rx_ucast_pkts", offsetof(struct hwrm_func_qstats_output,
186                                 rx_ucast_pkts)},
187         {"rx_mcast_pkts", offsetof(struct hwrm_func_qstats_output,
188                                 rx_mcast_pkts)},
189         {"rx_bcast_pkts", offsetof(struct hwrm_func_qstats_output,
190                                 rx_bcast_pkts)},
191         {"rx_err_pkts", offsetof(struct hwrm_func_qstats_output,
192                                 rx_err_pkts)},
193         {"rx_drop_pkts", offsetof(struct hwrm_func_qstats_output,
194                                 rx_drop_pkts)},
195         {"rx_ucast_bytes", offsetof(struct hwrm_func_qstats_output,
196                                 rx_ucast_bytes)},
197         {"rx_mcast_bytes", offsetof(struct hwrm_func_qstats_output,
198                                 rx_mcast_bytes)},
199         {"rx_bcast_bytes", offsetof(struct hwrm_func_qstats_output,
200                                 rx_bcast_bytes)},
201         {"rx_agg_pkts", offsetof(struct hwrm_func_qstats_output,
202                                 rx_agg_pkts)},
203         {"rx_agg_bytes", offsetof(struct hwrm_func_qstats_output,
204                                 rx_agg_bytes)},
205         {"rx_agg_events", offsetof(struct hwrm_func_qstats_output,
206                                 rx_agg_events)},
207         {"rx_agg_aborts", offsetof(struct hwrm_func_qstats_output,
208                                 rx_agg_aborts)},
209 };
210
211 /*
212  * Statistics functions
213  */
214
215 void bnxt_free_stats(struct bnxt *bp)
216 {
217         int i;
218
219         for (i = 0; i < (int)bp->tx_cp_nr_rings; i++) {
220                 struct bnxt_tx_queue *txq = bp->tx_queues[i];
221
222                 bnxt_free_txq_stats(txq);
223         }
224         for (i = 0; i < (int)bp->rx_cp_nr_rings; i++) {
225                 struct bnxt_rx_queue *rxq = bp->rx_queues[i];
226
227                 bnxt_free_rxq_stats(rxq);
228         }
229 }
230
231 int bnxt_stats_get_op(struct rte_eth_dev *eth_dev,
232                            struct rte_eth_stats *bnxt_stats)
233 {
234         int rc = 0;
235         unsigned int i;
236         struct bnxt *bp = eth_dev->data->dev_private;
237
238         memset(bnxt_stats, 0, sizeof(*bnxt_stats));
239         if (!(bp->flags & BNXT_FLAG_INIT_DONE)) {
240                 PMD_DRV_LOG(ERR, "Device Initialization not complete!\n");
241                 return 0;
242         }
243
244         for (i = 0; i < bp->rx_cp_nr_rings; i++) {
245                 struct bnxt_rx_queue *rxq = bp->rx_queues[i];
246                 struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
247
248                 rc = bnxt_hwrm_ctx_qstats(bp, cpr->hw_stats_ctx_id, i,
249                                      bnxt_stats, 1);
250                 if (unlikely(rc))
251                         return rc;
252         }
253
254         for (i = 0; i < bp->tx_cp_nr_rings; i++) {
255                 struct bnxt_tx_queue *txq = bp->tx_queues[i];
256                 struct bnxt_cp_ring_info *cpr = txq->cp_ring;
257
258                 rc = bnxt_hwrm_ctx_qstats(bp, cpr->hw_stats_ctx_id, i,
259                                      bnxt_stats, 0);
260                 if (unlikely(rc))
261                         return rc;
262         }
263         rc = bnxt_hwrm_func_qstats(bp, 0xffff, bnxt_stats);
264         if (unlikely(rc))
265                 return rc;
266         bnxt_stats->rx_nombuf = rte_atomic64_read(&bp->rx_mbuf_alloc_fail);
267         return rc;
268 }
269
270 void bnxt_stats_reset_op(struct rte_eth_dev *eth_dev)
271 {
272         struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
273
274         if (!(bp->flags & BNXT_FLAG_INIT_DONE)) {
275                 PMD_DRV_LOG(ERR, "Device Initialization not complete!\n");
276                 return;
277         }
278
279         bnxt_clear_all_hwrm_stat_ctxs(bp);
280         rte_atomic64_clear(&bp->rx_mbuf_alloc_fail);
281 }
282
283 int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
284                            struct rte_eth_xstat *xstats, unsigned int n)
285 {
286         struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
287
288         unsigned int count, i;
289         uint64_t tx_drop_pkts;
290
291         if (!(bp->flags & BNXT_FLAG_PORT_STATS)) {
292                 PMD_DRV_LOG(ERR, "xstats not supported for VF\n");
293                 return 0;
294         }
295
296         bnxt_hwrm_port_qstats(bp);
297         bnxt_hwrm_func_qstats_tx_drop(bp, 0xffff, &tx_drop_pkts);
298
299         count = RTE_DIM(bnxt_rx_stats_strings) +
300                 RTE_DIM(bnxt_tx_stats_strings) + 1; /* For tx_drop_pkts */
301
302         if (n < count)
303                 return count;
304
305         count = 0;
306         for (i = 0; i < RTE_DIM(bnxt_rx_stats_strings); i++) {
307                 uint64_t *rx_stats = (uint64_t *)bp->hw_rx_port_stats;
308                 xstats[count].value = rte_le_to_cpu_64(
309                                 *(uint64_t *)((char *)rx_stats +
310                                 bnxt_rx_stats_strings[i].offset));
311                 count++;
312         }
313
314         for (i = 0; i < RTE_DIM(bnxt_tx_stats_strings); i++) {
315                 uint64_t *tx_stats = (uint64_t *)bp->hw_tx_port_stats;
316                 xstats[count].value = rte_le_to_cpu_64(
317                                  *(uint64_t *)((char *)tx_stats +
318                                 bnxt_tx_stats_strings[i].offset));
319                 count++;
320         }
321
322         /* The Tx drop pkts aka the Anti spoof coounter */
323         xstats[count].value = rte_le_to_cpu_64(tx_drop_pkts);
324         count++;
325
326         return count;
327 }
328
329 int bnxt_dev_xstats_get_names_op(__rte_unused struct rte_eth_dev *eth_dev,
330         struct rte_eth_xstat_name *xstats_names,
331         __rte_unused unsigned int limit)
332 {
333         /* Account for the Tx drop pkts aka the Anti spoof counter */
334         const unsigned int stat_cnt = RTE_DIM(bnxt_rx_stats_strings) +
335                                 RTE_DIM(bnxt_tx_stats_strings) + 1;
336         unsigned int i, count;
337
338         if (xstats_names != NULL) {
339                 count = 0;
340
341                 for (i = 0; i < RTE_DIM(bnxt_rx_stats_strings); i++) {
342                         snprintf(xstats_names[count].name,
343                                 sizeof(xstats_names[count].name),
344                                 "%s",
345                                 bnxt_rx_stats_strings[i].name);
346                         count++;
347                 }
348
349                 for (i = 0; i < RTE_DIM(bnxt_tx_stats_strings); i++) {
350                         snprintf(xstats_names[count].name,
351                                 sizeof(xstats_names[count].name),
352                                 "%s",
353                                 bnxt_tx_stats_strings[i].name);
354                         count++;
355                 }
356
357                 snprintf(xstats_names[count].name,
358                                 sizeof(xstats_names[count].name),
359                                 "%s",
360                                 bnxt_func_stats_strings[4].name);
361                 count++;
362         }
363         return stat_cnt;
364 }
365
366 void bnxt_dev_xstats_reset_op(struct rte_eth_dev *eth_dev)
367 {
368         struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
369
370         if (bp->flags & BNXT_FLAG_PORT_STATS && BNXT_SINGLE_PF(bp))
371                 bnxt_hwrm_port_clr_stats(bp);
372
373         if (BNXT_VF(bp))
374                 PMD_DRV_LOG(ERR, "Operation not supported on a VF device\n");
375         if (!BNXT_SINGLE_PF(bp))
376                 PMD_DRV_LOG(ERR, "Operation not supported on a MF device\n");
377         if (!(bp->flags & BNXT_FLAG_PORT_STATS))
378                 PMD_DRV_LOG(ERR, "Operation not supported\n");
379 }
380
381 int bnxt_dev_xstats_get_by_id_op(struct rte_eth_dev *dev, const uint64_t *ids,
382                 uint64_t *values, unsigned int limit)
383 {
384         /* Account for the Tx drop pkts aka the Anti spoof counter */
385         const unsigned int stat_cnt = RTE_DIM(bnxt_rx_stats_strings) +
386                                 RTE_DIM(bnxt_tx_stats_strings) + 1;
387         struct rte_eth_xstat xstats[stat_cnt];
388         uint64_t values_copy[stat_cnt];
389         uint16_t i;
390
391         if (!ids)
392                 return bnxt_dev_xstats_get_op(dev, xstats, stat_cnt);
393
394         bnxt_dev_xstats_get_by_id_op(dev, NULL, values_copy, stat_cnt);
395         for (i = 0; i < limit; i++) {
396                 if (ids[i] >= stat_cnt) {
397                         PMD_DRV_LOG(ERR, "id value isn't valid");
398                         return -1;
399                 }
400                 values[i] = values_copy[ids[i]];
401         }
402         return stat_cnt;
403 }
404
405 int bnxt_dev_xstats_get_names_by_id_op(struct rte_eth_dev *dev,
406                                 struct rte_eth_xstat_name *xstats_names,
407                                 const uint64_t *ids, unsigned int limit)
408 {
409         /* Account for the Tx drop pkts aka the Anti spoof counter */
410         const unsigned int stat_cnt = RTE_DIM(bnxt_rx_stats_strings) +
411                                 RTE_DIM(bnxt_tx_stats_strings) + 1;
412         struct rte_eth_xstat_name xstats_names_copy[stat_cnt];
413         uint16_t i;
414
415         if (!ids)
416                 return bnxt_dev_xstats_get_names_op(dev, xstats_names,
417                                                     stat_cnt);
418         bnxt_dev_xstats_get_names_by_id_op(dev, xstats_names_copy, NULL,
419                         stat_cnt);
420
421         for (i = 0; i < limit; i++) {
422                 if (ids[i] >= stat_cnt) {
423                         PMD_DRV_LOG(ERR, "id value isn't valid");
424                         return -1;
425                 }
426                 strcpy(xstats_names[i].name,
427                                 xstats_names_copy[ids[i]].name);
428         }
429         return stat_cnt;
430 }