xref: /dpdk/drivers/net/mlx5/mlx5_stats.c (revision af4f09f28294fac762ff413fbf14b48c42c128fd)
18fd92a66SOlivier Matz /* SPDX-License-Identifier: BSD-3-Clause
287011737SAdrien Mazarguil  * Copyright 2015 6WIND S.A.
387011737SAdrien Mazarguil  * Copyright 2015 Mellanox.
487011737SAdrien Mazarguil  */
587011737SAdrien Mazarguil 
6fc40db99SAdrien Mazarguil #include <inttypes.h>
7a4193ae3SShahaf Shuler #include <linux/sockios.h>
8a4193ae3SShahaf Shuler #include <linux/ethtool.h>
9fc40db99SAdrien Mazarguil #include <stdint.h>
10fc40db99SAdrien Mazarguil #include <stdio.h>
11a4193ae3SShahaf Shuler 
12ffc905f3SFerruh Yigit #include <rte_ethdev_driver.h>
13a4193ae3SShahaf Shuler #include <rte_common.h>
14a4193ae3SShahaf Shuler #include <rte_malloc.h>
1587011737SAdrien Mazarguil 
1687011737SAdrien Mazarguil #include "mlx5.h"
1787011737SAdrien Mazarguil #include "mlx5_rxtx.h"
1887011737SAdrien Mazarguil #include "mlx5_defs.h"
1987011737SAdrien Mazarguil 
20a4193ae3SShahaf Shuler struct mlx5_counter_ctrl {
21a4193ae3SShahaf Shuler 	/* Name of the counter. */
22a4193ae3SShahaf Shuler 	char dpdk_name[RTE_ETH_XSTATS_NAME_SIZE];
23a4193ae3SShahaf Shuler 	/* Name of the counter on the device table. */
24a4193ae3SShahaf Shuler 	char ctr_name[RTE_ETH_XSTATS_NAME_SIZE];
25fc40db99SAdrien Mazarguil 	uint32_t ib:1; /**< Nonzero for IB counters. */
26a4193ae3SShahaf Shuler };
27a4193ae3SShahaf Shuler 
28a4193ae3SShahaf Shuler static const struct mlx5_counter_ctrl mlx5_counters_init[] = {
29a4193ae3SShahaf Shuler 	{
30a4193ae3SShahaf Shuler 		.dpdk_name = "rx_port_unicast_bytes",
31a4193ae3SShahaf Shuler 		.ctr_name = "rx_vport_unicast_bytes",
32a4193ae3SShahaf Shuler 	},
33a4193ae3SShahaf Shuler 	{
34a4193ae3SShahaf Shuler 		.dpdk_name = "rx_port_multicast_bytes",
35a4193ae3SShahaf Shuler 		.ctr_name = "rx_vport_multicast_bytes",
36a4193ae3SShahaf Shuler 	},
37a4193ae3SShahaf Shuler 	{
38a4193ae3SShahaf Shuler 		.dpdk_name = "rx_port_broadcast_bytes",
39a4193ae3SShahaf Shuler 		.ctr_name = "rx_vport_broadcast_bytes",
40a4193ae3SShahaf Shuler 	},
41a4193ae3SShahaf Shuler 	{
42a4193ae3SShahaf Shuler 		.dpdk_name = "rx_port_unicast_packets",
43a4193ae3SShahaf Shuler 		.ctr_name = "rx_vport_unicast_packets",
44a4193ae3SShahaf Shuler 	},
45a4193ae3SShahaf Shuler 	{
46a4193ae3SShahaf Shuler 		.dpdk_name = "rx_port_multicast_packets",
47a4193ae3SShahaf Shuler 		.ctr_name = "rx_vport_multicast_packets",
48a4193ae3SShahaf Shuler 	},
49a4193ae3SShahaf Shuler 	{
50a4193ae3SShahaf Shuler 		.dpdk_name = "rx_port_broadcast_packets",
51a4193ae3SShahaf Shuler 		.ctr_name = "rx_vport_broadcast_packets",
52a4193ae3SShahaf Shuler 	},
53a4193ae3SShahaf Shuler 	{
54a4193ae3SShahaf Shuler 		.dpdk_name = "tx_port_unicast_bytes",
55a4193ae3SShahaf Shuler 		.ctr_name = "tx_vport_unicast_bytes",
56a4193ae3SShahaf Shuler 	},
57a4193ae3SShahaf Shuler 	{
58a4193ae3SShahaf Shuler 		.dpdk_name = "tx_port_multicast_bytes",
59a4193ae3SShahaf Shuler 		.ctr_name = "tx_vport_multicast_bytes",
60a4193ae3SShahaf Shuler 	},
61a4193ae3SShahaf Shuler 	{
62a4193ae3SShahaf Shuler 		.dpdk_name = "tx_port_broadcast_bytes",
63a4193ae3SShahaf Shuler 		.ctr_name = "tx_vport_broadcast_bytes",
64a4193ae3SShahaf Shuler 	},
65a4193ae3SShahaf Shuler 	{
66a4193ae3SShahaf Shuler 		.dpdk_name = "tx_port_unicast_packets",
67a4193ae3SShahaf Shuler 		.ctr_name = "tx_vport_unicast_packets",
68a4193ae3SShahaf Shuler 	},
69a4193ae3SShahaf Shuler 	{
70a4193ae3SShahaf Shuler 		.dpdk_name = "tx_port_multicast_packets",
71a4193ae3SShahaf Shuler 		.ctr_name = "tx_vport_multicast_packets",
72a4193ae3SShahaf Shuler 	},
73a4193ae3SShahaf Shuler 	{
74a4193ae3SShahaf Shuler 		.dpdk_name = "tx_port_broadcast_packets",
75a4193ae3SShahaf Shuler 		.ctr_name = "tx_vport_broadcast_packets",
76a4193ae3SShahaf Shuler 	},
77a4193ae3SShahaf Shuler 	{
78a4193ae3SShahaf Shuler 		.dpdk_name = "rx_wqe_err",
79a4193ae3SShahaf Shuler 		.ctr_name = "rx_wqe_err",
80a4193ae3SShahaf Shuler 	},
81a4193ae3SShahaf Shuler 	{
82a4193ae3SShahaf Shuler 		.dpdk_name = "rx_crc_errors_phy",
83a4193ae3SShahaf Shuler 		.ctr_name = "rx_crc_errors_phy",
84a4193ae3SShahaf Shuler 	},
85a4193ae3SShahaf Shuler 	{
86a4193ae3SShahaf Shuler 		.dpdk_name = "rx_in_range_len_errors_phy",
87a4193ae3SShahaf Shuler 		.ctr_name = "rx_in_range_len_errors_phy",
88a4193ae3SShahaf Shuler 	},
89a4193ae3SShahaf Shuler 	{
90a4193ae3SShahaf Shuler 		.dpdk_name = "rx_symbol_err_phy",
91a4193ae3SShahaf Shuler 		.ctr_name = "rx_symbol_err_phy",
92a4193ae3SShahaf Shuler 	},
93a4193ae3SShahaf Shuler 	{
94a4193ae3SShahaf Shuler 		.dpdk_name = "tx_errors_phy",
95a4193ae3SShahaf Shuler 		.ctr_name = "tx_errors_phy",
96a4193ae3SShahaf Shuler 	},
97859081d3SShahaf Shuler 	{
98859081d3SShahaf Shuler 		.dpdk_name = "rx_out_of_buffer",
99859081d3SShahaf Shuler 		.ctr_name = "out_of_buffer",
100fc40db99SAdrien Mazarguil 		.ib = 1,
101859081d3SShahaf Shuler 	},
1020c62250bSShahaf Shuler 	{
1030c62250bSShahaf Shuler 		.dpdk_name = "tx_packets_phy",
1040c62250bSShahaf Shuler 		.ctr_name = "tx_packets_phy",
1050c62250bSShahaf Shuler 	},
1060c62250bSShahaf Shuler 	{
1070c62250bSShahaf Shuler 		.dpdk_name = "rx_packets_phy",
1080c62250bSShahaf Shuler 		.ctr_name = "rx_packets_phy",
1090c62250bSShahaf Shuler 	},
1100c62250bSShahaf Shuler 	{
1110c62250bSShahaf Shuler 		.dpdk_name = "tx_bytes_phy",
1120c62250bSShahaf Shuler 		.ctr_name = "tx_bytes_phy",
1130c62250bSShahaf Shuler 	},
1140c62250bSShahaf Shuler 	{
1150c62250bSShahaf Shuler 		.dpdk_name = "rx_bytes_phy",
1160c62250bSShahaf Shuler 		.ctr_name = "rx_bytes_phy",
1170c62250bSShahaf Shuler 	},
118a4193ae3SShahaf Shuler };
119a4193ae3SShahaf Shuler 
120a4193ae3SShahaf Shuler static const unsigned int xstats_n = RTE_DIM(mlx5_counters_init);
121a4193ae3SShahaf Shuler 
122a4193ae3SShahaf Shuler /**
123a4193ae3SShahaf Shuler  * Read device counters table.
124a4193ae3SShahaf Shuler  *
125*af4f09f2SNélio Laranjeiro  * @param dev
126*af4f09f2SNélio Laranjeiro  *   Pointer to Ethernet device.
127a4193ae3SShahaf Shuler  * @param[out] stats
128a4193ae3SShahaf Shuler  *   Counters table output buffer.
129a4193ae3SShahaf Shuler  *
130a4193ae3SShahaf Shuler  * @return
131a4193ae3SShahaf Shuler  *   0 on success and stats is filled, negative on error.
132a4193ae3SShahaf Shuler  */
133a4193ae3SShahaf Shuler static int
134*af4f09f2SNélio Laranjeiro mlx5_read_dev_counters(struct rte_eth_dev *dev, uint64_t *stats)
135a4193ae3SShahaf Shuler {
136*af4f09f2SNélio Laranjeiro 	struct priv *priv = dev->data->dev_private;
137a4193ae3SShahaf Shuler 	struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl;
138a4193ae3SShahaf Shuler 	unsigned int i;
139a4193ae3SShahaf Shuler 	struct ifreq ifr;
14025b73ba6SThierry Herbelot 	unsigned int stats_sz = xstats_ctrl->stats_n * sizeof(uint64_t);
14125b73ba6SThierry Herbelot 	unsigned char et_stat_buf[sizeof(struct ethtool_stats) + stats_sz];
14225b73ba6SThierry Herbelot 	struct ethtool_stats *et_stats = (struct ethtool_stats *)et_stat_buf;
143a4193ae3SShahaf Shuler 
144a4193ae3SShahaf Shuler 	et_stats->cmd = ETHTOOL_GSTATS;
145a4193ae3SShahaf Shuler 	et_stats->n_stats = xstats_ctrl->stats_n;
146a4193ae3SShahaf Shuler 	ifr.ifr_data = (caddr_t)et_stats;
147*af4f09f2SNélio Laranjeiro 	if (mlx5_ifreq(dev, SIOCETHTOOL, &ifr) != 0) {
148a4193ae3SShahaf Shuler 		WARN("unable to read statistic values from device");
149a4193ae3SShahaf Shuler 		return -1;
150a4193ae3SShahaf Shuler 	}
151859081d3SShahaf Shuler 	for (i = 0; i != xstats_n; ++i) {
152fc40db99SAdrien Mazarguil 		if (mlx5_counters_init[i].ib) {
153fc40db99SAdrien Mazarguil 			FILE *file;
154fc40db99SAdrien Mazarguil 			MKSTR(path, "%s/ports/1/hw_counters/%s",
155fc40db99SAdrien Mazarguil 			      priv->ibdev_path,
156fc40db99SAdrien Mazarguil 			      mlx5_counters_init[i].ctr_name);
157fc40db99SAdrien Mazarguil 
158fc40db99SAdrien Mazarguil 			file = fopen(path, "rb");
159fc40db99SAdrien Mazarguil 			if (file) {
160fc40db99SAdrien Mazarguil 				int n = fscanf(file, "%" SCNu64, &stats[i]);
161fc40db99SAdrien Mazarguil 
162fc40db99SAdrien Mazarguil 				fclose(file);
163fc40db99SAdrien Mazarguil 				if (n != 1)
164fc40db99SAdrien Mazarguil 					stats[i] = 0;
165fc40db99SAdrien Mazarguil 			}
166fc40db99SAdrien Mazarguil 		} else {
167a4193ae3SShahaf Shuler 			stats[i] = (uint64_t)
168a4193ae3SShahaf Shuler 				et_stats->data[xstats_ctrl->dev_table_idx[i]];
169859081d3SShahaf Shuler 		}
170fc40db99SAdrien Mazarguil 	}
171a4193ae3SShahaf Shuler 	return 0;
172a4193ae3SShahaf Shuler }
173a4193ae3SShahaf Shuler 
174a4193ae3SShahaf Shuler /**
175e62bc9e7SShahaf Shuler  * Query the number of statistics provided by ETHTOOL.
176e62bc9e7SShahaf Shuler  *
177*af4f09f2SNélio Laranjeiro  * @param dev
178*af4f09f2SNélio Laranjeiro  *   Pointer to Ethernet device.
179e62bc9e7SShahaf Shuler  *
180e62bc9e7SShahaf Shuler  * @return
181e62bc9e7SShahaf Shuler  *   Number of statistics on success, -1 on error.
182e62bc9e7SShahaf Shuler  */
183e62bc9e7SShahaf Shuler static int
184*af4f09f2SNélio Laranjeiro mlx5_ethtool_get_stats_n(struct rte_eth_dev *dev) {
185e62bc9e7SShahaf Shuler 	struct ethtool_drvinfo drvinfo;
186e62bc9e7SShahaf Shuler 	struct ifreq ifr;
187e62bc9e7SShahaf Shuler 
188e62bc9e7SShahaf Shuler 	drvinfo.cmd = ETHTOOL_GDRVINFO;
189e62bc9e7SShahaf Shuler 	ifr.ifr_data = (caddr_t)&drvinfo;
190*af4f09f2SNélio Laranjeiro 	if (mlx5_ifreq(dev, SIOCETHTOOL, &ifr) != 0) {
191e62bc9e7SShahaf Shuler 		WARN("unable to query number of statistics");
192e62bc9e7SShahaf Shuler 		return -1;
193e62bc9e7SShahaf Shuler 	}
194e62bc9e7SShahaf Shuler 	return drvinfo.n_stats;
195e62bc9e7SShahaf Shuler }
196e62bc9e7SShahaf Shuler 
197e62bc9e7SShahaf Shuler /**
198a4193ae3SShahaf Shuler  * Init the structures to read device counters.
199a4193ae3SShahaf Shuler  *
200*af4f09f2SNélio Laranjeiro  * @param dev
201*af4f09f2SNélio Laranjeiro  *   Pointer to Ethernet device.
202a4193ae3SShahaf Shuler  */
203a4193ae3SShahaf Shuler void
204*af4f09f2SNélio Laranjeiro mlx5_xstats_init(struct rte_eth_dev *dev)
205a4193ae3SShahaf Shuler {
206*af4f09f2SNélio Laranjeiro 	struct priv *priv = dev->data->dev_private;
207a4193ae3SShahaf Shuler 	struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl;
208a4193ae3SShahaf Shuler 	unsigned int i;
209a4193ae3SShahaf Shuler 	unsigned int j;
210a4193ae3SShahaf Shuler 	struct ifreq ifr;
211a4193ae3SShahaf Shuler 	struct ethtool_gstrings *strings = NULL;
212a4193ae3SShahaf Shuler 	unsigned int dev_stats_n;
213a4193ae3SShahaf Shuler 	unsigned int str_sz;
214a4193ae3SShahaf Shuler 
215*af4f09f2SNélio Laranjeiro 	dev_stats_n = mlx5_ethtool_get_stats_n(dev);
216a4193ae3SShahaf Shuler 	if (dev_stats_n < 1) {
217a4193ae3SShahaf Shuler 		WARN("no extended statistics available");
218a4193ae3SShahaf Shuler 		return;
219a4193ae3SShahaf Shuler 	}
220a4193ae3SShahaf Shuler 	xstats_ctrl->stats_n = dev_stats_n;
221a4193ae3SShahaf Shuler 	/* Allocate memory to grab stat names and values. */
222a4193ae3SShahaf Shuler 	str_sz = dev_stats_n * ETH_GSTRING_LEN;
223a4193ae3SShahaf Shuler 	strings = (struct ethtool_gstrings *)
224a4193ae3SShahaf Shuler 		  rte_malloc("xstats_strings",
225a4193ae3SShahaf Shuler 			     str_sz + sizeof(struct ethtool_gstrings), 0);
226a4193ae3SShahaf Shuler 	if (!strings) {
227a4193ae3SShahaf Shuler 		WARN("unable to allocate memory for xstats");
228a4193ae3SShahaf Shuler 		return;
229a4193ae3SShahaf Shuler 	}
230a4193ae3SShahaf Shuler 	strings->cmd = ETHTOOL_GSTRINGS;
231a4193ae3SShahaf Shuler 	strings->string_set = ETH_SS_STATS;
232a4193ae3SShahaf Shuler 	strings->len = dev_stats_n;
233a4193ae3SShahaf Shuler 	ifr.ifr_data = (caddr_t)strings;
234*af4f09f2SNélio Laranjeiro 	if (mlx5_ifreq(dev, SIOCETHTOOL, &ifr) != 0) {
235a4193ae3SShahaf Shuler 		WARN("unable to get statistic names");
236a4193ae3SShahaf Shuler 		goto free;
237a4193ae3SShahaf Shuler 	}
238a4193ae3SShahaf Shuler 	for (j = 0; j != xstats_n; ++j)
239a4193ae3SShahaf Shuler 		xstats_ctrl->dev_table_idx[j] = dev_stats_n;
240a4193ae3SShahaf Shuler 	for (i = 0; i != dev_stats_n; ++i) {
241a4193ae3SShahaf Shuler 		const char *curr_string = (const char *)
242a4193ae3SShahaf Shuler 			&strings->data[i * ETH_GSTRING_LEN];
243a4193ae3SShahaf Shuler 
244a4193ae3SShahaf Shuler 		for (j = 0; j != xstats_n; ++j) {
245a4193ae3SShahaf Shuler 			if (!strcmp(mlx5_counters_init[j].ctr_name,
246a4193ae3SShahaf Shuler 				    curr_string)) {
247a4193ae3SShahaf Shuler 				xstats_ctrl->dev_table_idx[j] = i;
248a4193ae3SShahaf Shuler 				break;
249a4193ae3SShahaf Shuler 			}
250a4193ae3SShahaf Shuler 		}
251a4193ae3SShahaf Shuler 	}
252a4193ae3SShahaf Shuler 	for (j = 0; j != xstats_n; ++j) {
253fc40db99SAdrien Mazarguil 		if (mlx5_counters_init[j].ib)
254859081d3SShahaf Shuler 			continue;
255a4193ae3SShahaf Shuler 		if (xstats_ctrl->dev_table_idx[j] >= dev_stats_n) {
256a4193ae3SShahaf Shuler 			WARN("counter \"%s\" is not recognized",
257a4193ae3SShahaf Shuler 			     mlx5_counters_init[j].dpdk_name);
258a4193ae3SShahaf Shuler 			goto free;
259a4193ae3SShahaf Shuler 		}
260a4193ae3SShahaf Shuler 	}
261a4193ae3SShahaf Shuler 	/* Copy to base at first time. */
262a4193ae3SShahaf Shuler 	assert(xstats_n <= MLX5_MAX_XSTATS);
263*af4f09f2SNélio Laranjeiro 	mlx5_read_dev_counters(dev, xstats_ctrl->base);
264a4193ae3SShahaf Shuler free:
265a4193ae3SShahaf Shuler 	rte_free(strings);
266a4193ae3SShahaf Shuler }
267a4193ae3SShahaf Shuler 
268a4193ae3SShahaf Shuler /**
269*af4f09f2SNélio Laranjeiro  * DPDK callback to get extended device statistics.
270a4193ae3SShahaf Shuler  *
271*af4f09f2SNélio Laranjeiro  * @param dev
272*af4f09f2SNélio Laranjeiro  *   Pointer to Ethernet device.
273a4193ae3SShahaf Shuler  * @param[out] stats
274a4193ae3SShahaf Shuler  *   Pointer to rte extended stats table.
275*af4f09f2SNélio Laranjeiro  * @param n
276*af4f09f2SNélio Laranjeiro  *   The size of the stats table.
277a4193ae3SShahaf Shuler  *
278a4193ae3SShahaf Shuler  * @return
279a4193ae3SShahaf Shuler  *   Number of extended stats on success and stats is filled,
280a4193ae3SShahaf Shuler  *   negative on error.
281a4193ae3SShahaf Shuler  */
282*af4f09f2SNélio Laranjeiro int
283*af4f09f2SNélio Laranjeiro mlx5_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *stats,
284*af4f09f2SNélio Laranjeiro 		unsigned int n)
285a4193ae3SShahaf Shuler {
286*af4f09f2SNélio Laranjeiro 	struct priv *priv = dev->data->dev_private;
287a4193ae3SShahaf Shuler 	unsigned int i;
288a4193ae3SShahaf Shuler 	uint64_t counters[n];
289*af4f09f2SNélio Laranjeiro 	int ret = 0;
290a4193ae3SShahaf Shuler 
291*af4f09f2SNélio Laranjeiro 	if (n >= xstats_n && stats) {
292*af4f09f2SNélio Laranjeiro 		struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl;
293*af4f09f2SNélio Laranjeiro 		int stats_n;
294*af4f09f2SNélio Laranjeiro 
295*af4f09f2SNélio Laranjeiro 		stats_n = mlx5_ethtool_get_stats_n(dev);
296*af4f09f2SNélio Laranjeiro 		if (stats_n < 0)
297a4193ae3SShahaf Shuler 			return -1;
298*af4f09f2SNélio Laranjeiro 		if (xstats_ctrl->stats_n != stats_n)
299*af4f09f2SNélio Laranjeiro 			mlx5_xstats_init(dev);
300*af4f09f2SNélio Laranjeiro 		ret = mlx5_read_dev_counters(dev, counters);
301*af4f09f2SNélio Laranjeiro 		if (ret)
302*af4f09f2SNélio Laranjeiro 			return ret;
303a4193ae3SShahaf Shuler 		for (i = 0; i != xstats_n; ++i) {
304a4193ae3SShahaf Shuler 			stats[i].id = i;
305a4193ae3SShahaf Shuler 			stats[i].value = (counters[i] - xstats_ctrl->base[i]);
306a4193ae3SShahaf Shuler 		}
307a4193ae3SShahaf Shuler 	}
308*af4f09f2SNélio Laranjeiro 	return n;
309a4193ae3SShahaf Shuler }
310a4193ae3SShahaf Shuler 
31187011737SAdrien Mazarguil /**
31287011737SAdrien Mazarguil  * DPDK callback to get device statistics.
31387011737SAdrien Mazarguil  *
31487011737SAdrien Mazarguil  * @param dev
31587011737SAdrien Mazarguil  *   Pointer to Ethernet device structure.
31687011737SAdrien Mazarguil  * @param[out] stats
31787011737SAdrien Mazarguil  *   Stats structure output buffer.
31887011737SAdrien Mazarguil  */
319d5b0924bSMatan Azrad int
32087011737SAdrien Mazarguil mlx5_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
32187011737SAdrien Mazarguil {
32201d79216SNélio Laranjeiro 	struct priv *priv = dev->data->dev_private;
32387011737SAdrien Mazarguil 	struct rte_eth_stats tmp = {0};
32487011737SAdrien Mazarguil 	unsigned int i;
32587011737SAdrien Mazarguil 	unsigned int idx;
32687011737SAdrien Mazarguil 
32787011737SAdrien Mazarguil 	/* Add software counters. */
32887011737SAdrien Mazarguil 	for (i = 0; (i != priv->rxqs_n); ++i) {
32978142aacSNélio Laranjeiro 		struct mlx5_rxq_data *rxq = (*priv->rxqs)[i];
33087011737SAdrien Mazarguil 
33187011737SAdrien Mazarguil 		if (rxq == NULL)
33287011737SAdrien Mazarguil 			continue;
33387011737SAdrien Mazarguil 		idx = rxq->stats.idx;
33487011737SAdrien Mazarguil 		if (idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
33587011737SAdrien Mazarguil #ifdef MLX5_PMD_SOFT_COUNTERS
33687011737SAdrien Mazarguil 			tmp.q_ipackets[idx] += rxq->stats.ipackets;
33787011737SAdrien Mazarguil 			tmp.q_ibytes[idx] += rxq->stats.ibytes;
33887011737SAdrien Mazarguil #endif
33987011737SAdrien Mazarguil 			tmp.q_errors[idx] += (rxq->stats.idropped +
34087011737SAdrien Mazarguil 					      rxq->stats.rx_nombuf);
34187011737SAdrien Mazarguil 		}
34287011737SAdrien Mazarguil #ifdef MLX5_PMD_SOFT_COUNTERS
34387011737SAdrien Mazarguil 		tmp.ipackets += rxq->stats.ipackets;
34487011737SAdrien Mazarguil 		tmp.ibytes += rxq->stats.ibytes;
34587011737SAdrien Mazarguil #endif
34687011737SAdrien Mazarguil 		tmp.ierrors += rxq->stats.idropped;
34787011737SAdrien Mazarguil 		tmp.rx_nombuf += rxq->stats.rx_nombuf;
34887011737SAdrien Mazarguil 	}
34987011737SAdrien Mazarguil 	for (i = 0; (i != priv->txqs_n); ++i) {
350991b04f6SNélio Laranjeiro 		struct mlx5_txq_data *txq = (*priv->txqs)[i];
35187011737SAdrien Mazarguil 
35287011737SAdrien Mazarguil 		if (txq == NULL)
35387011737SAdrien Mazarguil 			continue;
35487011737SAdrien Mazarguil 		idx = txq->stats.idx;
35587011737SAdrien Mazarguil 		if (idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
35687011737SAdrien Mazarguil #ifdef MLX5_PMD_SOFT_COUNTERS
35787011737SAdrien Mazarguil 			tmp.q_opackets[idx] += txq->stats.opackets;
35887011737SAdrien Mazarguil 			tmp.q_obytes[idx] += txq->stats.obytes;
35987011737SAdrien Mazarguil #endif
3609f9a48ebSShahaf Shuler 			tmp.q_errors[idx] += txq->stats.oerrors;
36187011737SAdrien Mazarguil 		}
36287011737SAdrien Mazarguil #ifdef MLX5_PMD_SOFT_COUNTERS
36387011737SAdrien Mazarguil 		tmp.opackets += txq->stats.opackets;
36487011737SAdrien Mazarguil 		tmp.obytes += txq->stats.obytes;
36587011737SAdrien Mazarguil #endif
3669f9a48ebSShahaf Shuler 		tmp.oerrors += txq->stats.oerrors;
36787011737SAdrien Mazarguil 	}
36887011737SAdrien Mazarguil #ifndef MLX5_PMD_SOFT_COUNTERS
36987011737SAdrien Mazarguil 	/* FIXME: retrieve and add hardware counters. */
37087011737SAdrien Mazarguil #endif
37187011737SAdrien Mazarguil 	*stats = tmp;
372d5b0924bSMatan Azrad 	return 0;
37387011737SAdrien Mazarguil }
37487011737SAdrien Mazarguil 
37587011737SAdrien Mazarguil /**
37687011737SAdrien Mazarguil  * DPDK callback to clear device statistics.
37787011737SAdrien Mazarguil  *
37887011737SAdrien Mazarguil  * @param dev
37987011737SAdrien Mazarguil  *   Pointer to Ethernet device structure.
38087011737SAdrien Mazarguil  */
38187011737SAdrien Mazarguil void
38287011737SAdrien Mazarguil mlx5_stats_reset(struct rte_eth_dev *dev)
38387011737SAdrien Mazarguil {
38487011737SAdrien Mazarguil 	struct priv *priv = dev->data->dev_private;
38587011737SAdrien Mazarguil 	unsigned int i;
38687011737SAdrien Mazarguil 	unsigned int idx;
38787011737SAdrien Mazarguil 
38887011737SAdrien Mazarguil 	for (i = 0; (i != priv->rxqs_n); ++i) {
38987011737SAdrien Mazarguil 		if ((*priv->rxqs)[i] == NULL)
39087011737SAdrien Mazarguil 			continue;
39187011737SAdrien Mazarguil 		idx = (*priv->rxqs)[i]->stats.idx;
39287011737SAdrien Mazarguil 		(*priv->rxqs)[i]->stats =
39387011737SAdrien Mazarguil 			(struct mlx5_rxq_stats){ .idx = idx };
39487011737SAdrien Mazarguil 	}
39587011737SAdrien Mazarguil 	for (i = 0; (i != priv->txqs_n); ++i) {
39687011737SAdrien Mazarguil 		if ((*priv->txqs)[i] == NULL)
39787011737SAdrien Mazarguil 			continue;
3987efc807dSAdrien Mazarguil 		idx = (*priv->txqs)[i]->stats.idx;
39987011737SAdrien Mazarguil 		(*priv->txqs)[i]->stats =
40087011737SAdrien Mazarguil 			(struct mlx5_txq_stats){ .idx = idx };
40187011737SAdrien Mazarguil 	}
40287011737SAdrien Mazarguil #ifndef MLX5_PMD_SOFT_COUNTERS
40387011737SAdrien Mazarguil 	/* FIXME: reset hardware counters. */
40487011737SAdrien Mazarguil #endif
40587011737SAdrien Mazarguil }
406a4193ae3SShahaf Shuler 
407a4193ae3SShahaf Shuler /**
408a4193ae3SShahaf Shuler  * DPDK callback to clear device extended statistics.
409a4193ae3SShahaf Shuler  *
410a4193ae3SShahaf Shuler  * @param dev
411a4193ae3SShahaf Shuler  *   Pointer to Ethernet device structure.
412a4193ae3SShahaf Shuler  */
413a4193ae3SShahaf Shuler void
414a4193ae3SShahaf Shuler mlx5_xstats_reset(struct rte_eth_dev *dev)
415a4193ae3SShahaf Shuler {
41601d79216SNélio Laranjeiro 	struct priv *priv = dev->data->dev_private;
417e62bc9e7SShahaf Shuler 	struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl;
418e62bc9e7SShahaf Shuler 	int stats_n;
419*af4f09f2SNélio Laranjeiro 	unsigned int i;
420*af4f09f2SNélio Laranjeiro 	unsigned int n = xstats_n;
421*af4f09f2SNélio Laranjeiro 	uint64_t counters[n];
422a4193ae3SShahaf Shuler 
423*af4f09f2SNélio Laranjeiro 	stats_n = mlx5_ethtool_get_stats_n(dev);
424e62bc9e7SShahaf Shuler 	if (stats_n < 0)
4257b2423cdSNélio Laranjeiro 		return;
426e62bc9e7SShahaf Shuler 	if (xstats_ctrl->stats_n != stats_n)
427*af4f09f2SNélio Laranjeiro 		mlx5_xstats_init(dev);
428*af4f09f2SNélio Laranjeiro 	if (mlx5_read_dev_counters(dev, counters) < 0)
429*af4f09f2SNélio Laranjeiro 		return;
430*af4f09f2SNélio Laranjeiro 	for (i = 0; i != n; ++i)
431*af4f09f2SNélio Laranjeiro 		xstats_ctrl->base[i] = counters[i];
432a4193ae3SShahaf Shuler }
433a4193ae3SShahaf Shuler 
434a4193ae3SShahaf Shuler /**
435a4193ae3SShahaf Shuler  * DPDK callback to retrieve names of extended device statistics
436a4193ae3SShahaf Shuler  *
437a4193ae3SShahaf Shuler  * @param dev
438a4193ae3SShahaf Shuler  *   Pointer to Ethernet device structure.
439a4193ae3SShahaf Shuler  * @param[out] xstats_names
440a4193ae3SShahaf Shuler  *   Buffer to insert names into.
441a4193ae3SShahaf Shuler  * @param n
442a4193ae3SShahaf Shuler  *   Number of names.
443a4193ae3SShahaf Shuler  *
444a4193ae3SShahaf Shuler  * @return
445a4193ae3SShahaf Shuler  *   Number of xstats names.
446a4193ae3SShahaf Shuler  */
447a4193ae3SShahaf Shuler int
44856f08e16SNélio Laranjeiro mlx5_xstats_get_names(struct rte_eth_dev *dev __rte_unused,
449a4193ae3SShahaf Shuler 		struct rte_eth_xstat_name *xstats_names, unsigned int n)
450a4193ae3SShahaf Shuler {
451a4193ae3SShahaf Shuler 	unsigned int i;
452a4193ae3SShahaf Shuler 
453a4193ae3SShahaf Shuler 	if (n >= xstats_n && xstats_names) {
454a4193ae3SShahaf Shuler 		for (i = 0; i != xstats_n; ++i) {
455a4193ae3SShahaf Shuler 			strncpy(xstats_names[i].name,
456a4193ae3SShahaf Shuler 				mlx5_counters_init[i].dpdk_name,
457a4193ae3SShahaf Shuler 				RTE_ETH_XSTATS_NAME_SIZE);
458a4193ae3SShahaf Shuler 			xstats_names[i].name[RTE_ETH_XSTATS_NAME_SIZE - 1] = 0;
459a4193ae3SShahaf Shuler 		}
460a4193ae3SShahaf Shuler 	}
461a4193ae3SShahaf Shuler 	return xstats_n;
462a4193ae3SShahaf Shuler }
463