1/*-
2 *   BSD LICENSE
3 *
4 *   Copyright 2015 6WIND S.A.
5 *   Copyright 2015 Mellanox.
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 6WIND S.A. 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/* DPDK headers don't like -pedantic. */
35#ifdef PEDANTIC
36#pragma GCC diagnostic ignored "-Wpedantic"
37#endif
38#include <rte_ethdev.h>
39#ifdef PEDANTIC
40#pragma GCC diagnostic error "-Wpedantic"
41#endif
42
43#include "mlx5.h"
44#include "mlx5_rxtx.h"
45#include "mlx5_defs.h"
46
47/**
48 * DPDK callback to get device statistics.
49 *
50 * @param dev
51 *   Pointer to Ethernet device structure.
52 * @param[out] stats
53 *   Stats structure output buffer.
54 */
55void
56mlx5_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
57{
58	struct priv *priv = mlx5_get_priv(dev);
59	struct rte_eth_stats tmp = {0};
60	unsigned int i;
61	unsigned int idx;
62
63	priv_lock(priv);
64	/* Add software counters. */
65	for (i = 0; (i != priv->rxqs_n); ++i) {
66		struct rxq *rxq = (*priv->rxqs)[i];
67
68		if (rxq == NULL)
69			continue;
70		idx = rxq->stats.idx;
71		if (idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
72#ifdef MLX5_PMD_SOFT_COUNTERS
73			tmp.q_ipackets[idx] += rxq->stats.ipackets;
74			tmp.q_ibytes[idx] += rxq->stats.ibytes;
75#endif
76			tmp.q_errors[idx] += (rxq->stats.idropped +
77					      rxq->stats.rx_nombuf);
78		}
79#ifdef MLX5_PMD_SOFT_COUNTERS
80		tmp.ipackets += rxq->stats.ipackets;
81		tmp.ibytes += rxq->stats.ibytes;
82#endif
83		tmp.ierrors += rxq->stats.idropped;
84		tmp.rx_nombuf += rxq->stats.rx_nombuf;
85	}
86	for (i = 0; (i != priv->txqs_n); ++i) {
87		struct txq *txq = (*priv->txqs)[i];
88
89		if (txq == NULL)
90			continue;
91		idx = txq->stats.idx;
92		if (idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
93#ifdef MLX5_PMD_SOFT_COUNTERS
94			tmp.q_opackets[idx] += txq->stats.opackets;
95			tmp.q_obytes[idx] += txq->stats.obytes;
96#endif
97			tmp.q_errors[idx] += txq->stats.oerrors;
98		}
99#ifdef MLX5_PMD_SOFT_COUNTERS
100		tmp.opackets += txq->stats.opackets;
101		tmp.obytes += txq->stats.obytes;
102#endif
103		tmp.oerrors += txq->stats.oerrors;
104	}
105#ifndef MLX5_PMD_SOFT_COUNTERS
106	/* FIXME: retrieve and add hardware counters. */
107#endif
108	*stats = tmp;
109	priv_unlock(priv);
110}
111
112/**
113 * DPDK callback to clear device statistics.
114 *
115 * @param dev
116 *   Pointer to Ethernet device structure.
117 */
118void
119mlx5_stats_reset(struct rte_eth_dev *dev)
120{
121	struct priv *priv = dev->data->dev_private;
122	unsigned int i;
123	unsigned int idx;
124
125	priv_lock(priv);
126	for (i = 0; (i != priv->rxqs_n); ++i) {
127		if ((*priv->rxqs)[i] == NULL)
128			continue;
129		idx = (*priv->rxqs)[i]->stats.idx;
130		(*priv->rxqs)[i]->stats =
131			(struct mlx5_rxq_stats){ .idx = idx };
132	}
133	for (i = 0; (i != priv->txqs_n); ++i) {
134		if ((*priv->txqs)[i] == NULL)
135			continue;
136		idx = (*priv->txqs)[i]->stats.idx;
137		(*priv->txqs)[i]->stats =
138			(struct mlx5_txq_stats){ .idx = idx };
139	}
140#ifndef MLX5_PMD_SOFT_COUNTERS
141	/* FIXME: reset hardware counters. */
142#endif
143	priv_unlock(priv);
144}
145