]>
Commit | Line | Data |
---|---|---|
9f95a23c TL |
1 | /* SPDX-License-Identifier: BSD-3-Clause |
2 | * Copyright 2015 6WIND S.A. | |
3 | * Copyright 2015 Mellanox Technologies, Ltd | |
11fdf7f2 TL |
4 | */ |
5 | ||
9f95a23c | 6 | #include <inttypes.h> |
11fdf7f2 TL |
7 | #include <linux/sockios.h> |
8 | #include <linux/ethtool.h> | |
9f95a23c TL |
9 | #include <stdint.h> |
10 | #include <stdio.h> | |
11fdf7f2 | 11 | |
9f95a23c | 12 | #include <rte_ethdev_driver.h> |
11fdf7f2 TL |
13 | #include <rte_common.h> |
14 | #include <rte_malloc.h> | |
11fdf7f2 TL |
15 | |
16 | #include "mlx5.h" | |
17 | #include "mlx5_rxtx.h" | |
18 | #include "mlx5_defs.h" | |
19 | ||
11fdf7f2 TL |
20 | static const struct mlx5_counter_ctrl mlx5_counters_init[] = { |
21 | { | |
22 | .dpdk_name = "rx_port_unicast_bytes", | |
23 | .ctr_name = "rx_vport_unicast_bytes", | |
24 | }, | |
25 | { | |
26 | .dpdk_name = "rx_port_multicast_bytes", | |
27 | .ctr_name = "rx_vport_multicast_bytes", | |
28 | }, | |
29 | { | |
30 | .dpdk_name = "rx_port_broadcast_bytes", | |
31 | .ctr_name = "rx_vport_broadcast_bytes", | |
32 | }, | |
33 | { | |
34 | .dpdk_name = "rx_port_unicast_packets", | |
35 | .ctr_name = "rx_vport_unicast_packets", | |
36 | }, | |
37 | { | |
38 | .dpdk_name = "rx_port_multicast_packets", | |
39 | .ctr_name = "rx_vport_multicast_packets", | |
40 | }, | |
41 | { | |
42 | .dpdk_name = "rx_port_broadcast_packets", | |
43 | .ctr_name = "rx_vport_broadcast_packets", | |
44 | }, | |
45 | { | |
46 | .dpdk_name = "tx_port_unicast_bytes", | |
47 | .ctr_name = "tx_vport_unicast_bytes", | |
48 | }, | |
49 | { | |
50 | .dpdk_name = "tx_port_multicast_bytes", | |
51 | .ctr_name = "tx_vport_multicast_bytes", | |
52 | }, | |
53 | { | |
54 | .dpdk_name = "tx_port_broadcast_bytes", | |
55 | .ctr_name = "tx_vport_broadcast_bytes", | |
56 | }, | |
57 | { | |
58 | .dpdk_name = "tx_port_unicast_packets", | |
59 | .ctr_name = "tx_vport_unicast_packets", | |
60 | }, | |
61 | { | |
62 | .dpdk_name = "tx_port_multicast_packets", | |
63 | .ctr_name = "tx_vport_multicast_packets", | |
64 | }, | |
65 | { | |
66 | .dpdk_name = "tx_port_broadcast_packets", | |
67 | .ctr_name = "tx_vport_broadcast_packets", | |
68 | }, | |
69 | { | |
70 | .dpdk_name = "rx_wqe_err", | |
71 | .ctr_name = "rx_wqe_err", | |
72 | }, | |
73 | { | |
74 | .dpdk_name = "rx_crc_errors_phy", | |
75 | .ctr_name = "rx_crc_errors_phy", | |
76 | }, | |
77 | { | |
78 | .dpdk_name = "rx_in_range_len_errors_phy", | |
79 | .ctr_name = "rx_in_range_len_errors_phy", | |
80 | }, | |
81 | { | |
82 | .dpdk_name = "rx_symbol_err_phy", | |
83 | .ctr_name = "rx_symbol_err_phy", | |
84 | }, | |
85 | { | |
86 | .dpdk_name = "tx_errors_phy", | |
87 | .ctr_name = "tx_errors_phy", | |
88 | }, | |
89 | { | |
90 | .dpdk_name = "rx_out_of_buffer", | |
91 | .ctr_name = "out_of_buffer", | |
9f95a23c TL |
92 | .ib = 1, |
93 | }, | |
94 | { | |
95 | .dpdk_name = "tx_packets_phy", | |
96 | .ctr_name = "tx_packets_phy", | |
97 | }, | |
98 | { | |
99 | .dpdk_name = "rx_packets_phy", | |
100 | .ctr_name = "rx_packets_phy", | |
101 | }, | |
102 | { | |
103 | .dpdk_name = "tx_discards_phy", | |
104 | .ctr_name = "tx_discards_phy", | |
105 | }, | |
106 | { | |
107 | .dpdk_name = "rx_discards_phy", | |
108 | .ctr_name = "rx_discards_phy", | |
109 | }, | |
110 | { | |
111 | .dpdk_name = "tx_bytes_phy", | |
112 | .ctr_name = "tx_bytes_phy", | |
113 | }, | |
114 | { | |
115 | .dpdk_name = "rx_bytes_phy", | |
116 | .ctr_name = "rx_bytes_phy", | |
117 | }, | |
118 | /* Representor only */ | |
119 | { | |
120 | .dpdk_name = "rx_packets", | |
121 | .ctr_name = "vport_rx_packets", | |
122 | }, | |
123 | { | |
124 | .dpdk_name = "rx_bytes", | |
125 | .ctr_name = "vport_rx_bytes", | |
126 | }, | |
127 | { | |
128 | .dpdk_name = "tx_packets", | |
129 | .ctr_name = "vport_tx_packets", | |
130 | }, | |
131 | { | |
132 | .dpdk_name = "tx_bytes", | |
133 | .ctr_name = "vport_tx_bytes", | |
11fdf7f2 TL |
134 | }, |
135 | }; | |
136 | ||
137 | static const unsigned int xstats_n = RTE_DIM(mlx5_counters_init); | |
138 | ||
9f95a23c TL |
139 | static inline void |
140 | mlx5_read_ib_stat(struct mlx5_priv *priv, const char *ctr_name, uint64_t *stat) | |
141 | { | |
142 | FILE *file; | |
143 | if (priv->sh) { | |
144 | MKSTR(path, "%s/ports/%d/hw_counters/%s", | |
145 | priv->sh->ibdev_path, | |
146 | priv->ibv_port, | |
147 | ctr_name); | |
148 | ||
149 | file = fopen(path, "rb"); | |
150 | if (file) { | |
151 | int n = fscanf(file, "%" SCNu64, stat); | |
152 | ||
153 | fclose(file); | |
154 | if (n == 1) | |
155 | return; | |
156 | } | |
157 | } | |
158 | *stat = 0; | |
159 | } | |
160 | ||
11fdf7f2 TL |
161 | /** |
162 | * Read device counters table. | |
163 | * | |
9f95a23c TL |
164 | * @param dev |
165 | * Pointer to Ethernet device. | |
11fdf7f2 TL |
166 | * @param[out] stats |
167 | * Counters table output buffer. | |
168 | * | |
169 | * @return | |
9f95a23c TL |
170 | * 0 on success and stats is filled, negative errno value otherwise and |
171 | * rte_errno is set. | |
11fdf7f2 TL |
172 | */ |
173 | static int | |
9f95a23c | 174 | mlx5_read_dev_counters(struct rte_eth_dev *dev, uint64_t *stats) |
11fdf7f2 | 175 | { |
9f95a23c | 176 | struct mlx5_priv *priv = dev->data->dev_private; |
11fdf7f2 TL |
177 | struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl; |
178 | unsigned int i; | |
179 | struct ifreq ifr; | |
9f95a23c TL |
180 | unsigned int stats_sz = xstats_ctrl->stats_n * sizeof(uint64_t); |
181 | unsigned char et_stat_buf[sizeof(struct ethtool_stats) + stats_sz]; | |
182 | struct ethtool_stats *et_stats = (struct ethtool_stats *)et_stat_buf; | |
183 | int ret; | |
11fdf7f2 TL |
184 | |
185 | et_stats->cmd = ETHTOOL_GSTATS; | |
186 | et_stats->n_stats = xstats_ctrl->stats_n; | |
187 | ifr.ifr_data = (caddr_t)et_stats; | |
9f95a23c TL |
188 | ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr); |
189 | if (ret) { | |
190 | DRV_LOG(WARNING, | |
191 | "port %u unable to read statistic values from device", | |
192 | dev->data->port_id); | |
193 | return ret; | |
11fdf7f2 | 194 | } |
9f95a23c TL |
195 | for (i = 0; i != xstats_ctrl->mlx5_stats_n; ++i) { |
196 | if (xstats_ctrl->info[i].ib) { | |
197 | mlx5_read_ib_stat(priv, xstats_ctrl->info[i].ctr_name, | |
198 | &stats[i]); | |
199 | } else { | |
11fdf7f2 TL |
200 | stats[i] = (uint64_t) |
201 | et_stats->data[xstats_ctrl->dev_table_idx[i]]; | |
9f95a23c | 202 | } |
11fdf7f2 TL |
203 | } |
204 | return 0; | |
205 | } | |
206 | ||
207 | /** | |
208 | * Query the number of statistics provided by ETHTOOL. | |
209 | * | |
9f95a23c TL |
210 | * @param dev |
211 | * Pointer to Ethernet device. | |
11fdf7f2 TL |
212 | * |
213 | * @return | |
9f95a23c TL |
214 | * Number of statistics on success, negative errno value otherwise and |
215 | * rte_errno is set. | |
11fdf7f2 TL |
216 | */ |
217 | static int | |
9f95a23c | 218 | mlx5_ethtool_get_stats_n(struct rte_eth_dev *dev) { |
11fdf7f2 TL |
219 | struct ethtool_drvinfo drvinfo; |
220 | struct ifreq ifr; | |
9f95a23c | 221 | int ret; |
11fdf7f2 TL |
222 | |
223 | drvinfo.cmd = ETHTOOL_GDRVINFO; | |
224 | ifr.ifr_data = (caddr_t)&drvinfo; | |
9f95a23c TL |
225 | ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr); |
226 | if (ret) { | |
227 | DRV_LOG(WARNING, "port %u unable to query number of statistics", | |
228 | dev->data->port_id); | |
229 | return ret; | |
11fdf7f2 TL |
230 | } |
231 | return drvinfo.n_stats; | |
232 | } | |
233 | ||
234 | /** | |
235 | * Init the structures to read device counters. | |
236 | * | |
9f95a23c TL |
237 | * @param dev |
238 | * Pointer to Ethernet device. | |
11fdf7f2 TL |
239 | */ |
240 | void | |
9f95a23c | 241 | mlx5_stats_init(struct rte_eth_dev *dev) |
11fdf7f2 | 242 | { |
9f95a23c | 243 | struct mlx5_priv *priv = dev->data->dev_private; |
11fdf7f2 | 244 | struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl; |
9f95a23c | 245 | struct mlx5_stats_ctrl *stats_ctrl = &priv->stats_ctrl; |
11fdf7f2 TL |
246 | unsigned int i; |
247 | unsigned int j; | |
248 | struct ifreq ifr; | |
249 | struct ethtool_gstrings *strings = NULL; | |
250 | unsigned int dev_stats_n; | |
251 | unsigned int str_sz; | |
9f95a23c | 252 | int ret; |
11fdf7f2 | 253 | |
9f95a23c TL |
254 | /* So that it won't aggregate for each init. */ |
255 | xstats_ctrl->mlx5_stats_n = 0; | |
256 | ret = mlx5_ethtool_get_stats_n(dev); | |
257 | if (ret < 0) { | |
258 | DRV_LOG(WARNING, "port %u no extended statistics available", | |
259 | dev->data->port_id); | |
11fdf7f2 TL |
260 | return; |
261 | } | |
9f95a23c | 262 | dev_stats_n = ret; |
11fdf7f2 TL |
263 | /* Allocate memory to grab stat names and values. */ |
264 | str_sz = dev_stats_n * ETH_GSTRING_LEN; | |
265 | strings = (struct ethtool_gstrings *) | |
266 | rte_malloc("xstats_strings", | |
267 | str_sz + sizeof(struct ethtool_gstrings), 0); | |
268 | if (!strings) { | |
9f95a23c TL |
269 | DRV_LOG(WARNING, "port %u unable to allocate memory for xstats", |
270 | dev->data->port_id); | |
11fdf7f2 TL |
271 | return; |
272 | } | |
273 | strings->cmd = ETHTOOL_GSTRINGS; | |
274 | strings->string_set = ETH_SS_STATS; | |
275 | strings->len = dev_stats_n; | |
276 | ifr.ifr_data = (caddr_t)strings; | |
9f95a23c TL |
277 | ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr); |
278 | if (ret) { | |
279 | DRV_LOG(WARNING, "port %u unable to get statistic names", | |
280 | dev->data->port_id); | |
11fdf7f2 TL |
281 | goto free; |
282 | } | |
11fdf7f2 TL |
283 | for (i = 0; i != dev_stats_n; ++i) { |
284 | const char *curr_string = (const char *) | |
285 | &strings->data[i * ETH_GSTRING_LEN]; | |
286 | ||
287 | for (j = 0; j != xstats_n; ++j) { | |
288 | if (!strcmp(mlx5_counters_init[j].ctr_name, | |
289 | curr_string)) { | |
9f95a23c TL |
290 | unsigned int idx = xstats_ctrl->mlx5_stats_n++; |
291 | ||
292 | xstats_ctrl->dev_table_idx[idx] = i; | |
293 | xstats_ctrl->info[idx] = mlx5_counters_init[j]; | |
11fdf7f2 TL |
294 | break; |
295 | } | |
296 | } | |
297 | } | |
9f95a23c TL |
298 | /* Add IB counters. */ |
299 | for (i = 0; i != xstats_n; ++i) { | |
300 | if (mlx5_counters_init[i].ib) { | |
301 | unsigned int idx = xstats_ctrl->mlx5_stats_n++; | |
302 | ||
303 | xstats_ctrl->info[idx] = mlx5_counters_init[i]; | |
11fdf7f2 TL |
304 | } |
305 | } | |
9f95a23c TL |
306 | assert(xstats_ctrl->mlx5_stats_n <= MLX5_MAX_XSTATS); |
307 | xstats_ctrl->stats_n = dev_stats_n; | |
11fdf7f2 | 308 | /* Copy to base at first time. */ |
9f95a23c TL |
309 | ret = mlx5_read_dev_counters(dev, xstats_ctrl->base); |
310 | if (ret) | |
311 | DRV_LOG(ERR, "port %u cannot read device counters: %s", | |
312 | dev->data->port_id, strerror(rte_errno)); | |
313 | mlx5_read_ib_stat(priv, "out_of_buffer", &stats_ctrl->imissed_base); | |
11fdf7f2 TL |
314 | free: |
315 | rte_free(strings); | |
316 | } | |
317 | ||
318 | /** | |
9f95a23c | 319 | * DPDK callback to get extended device statistics. |
11fdf7f2 | 320 | * |
9f95a23c TL |
321 | * @param dev |
322 | * Pointer to Ethernet device. | |
11fdf7f2 TL |
323 | * @param[out] stats |
324 | * Pointer to rte extended stats table. | |
9f95a23c TL |
325 | * @param n |
326 | * The size of the stats table. | |
11fdf7f2 TL |
327 | * |
328 | * @return | |
329 | * Number of extended stats on success and stats is filled, | |
9f95a23c | 330 | * negative on error and rte_errno is set. |
11fdf7f2 | 331 | */ |
9f95a23c TL |
332 | int |
333 | mlx5_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *stats, | |
334 | unsigned int n) | |
11fdf7f2 | 335 | { |
9f95a23c | 336 | struct mlx5_priv *priv = dev->data->dev_private; |
11fdf7f2 | 337 | unsigned int i; |
11fdf7f2 | 338 | uint64_t counters[n]; |
11fdf7f2 | 339 | struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl; |
9f95a23c | 340 | uint16_t mlx5_stats_n = xstats_ctrl->mlx5_stats_n; |
11fdf7f2 | 341 | |
9f95a23c TL |
342 | if (n >= mlx5_stats_n && stats) { |
343 | int stats_n; | |
344 | int ret; | |
345 | ||
346 | stats_n = mlx5_ethtool_get_stats_n(dev); | |
347 | if (stats_n < 0) | |
348 | return stats_n; | |
349 | if (xstats_ctrl->stats_n != stats_n) | |
350 | mlx5_stats_init(dev); | |
351 | ret = mlx5_read_dev_counters(dev, counters); | |
352 | if (ret) | |
353 | return ret; | |
354 | for (i = 0; i != mlx5_stats_n; ++i) { | |
355 | stats[i].id = i; | |
356 | stats[i].value = (counters[i] - xstats_ctrl->base[i]); | |
357 | } | |
358 | } | |
359 | return mlx5_stats_n; | |
11fdf7f2 TL |
360 | } |
361 | ||
362 | /** | |
363 | * DPDK callback to get device statistics. | |
364 | * | |
365 | * @param dev | |
366 | * Pointer to Ethernet device structure. | |
367 | * @param[out] stats | |
368 | * Stats structure output buffer. | |
9f95a23c TL |
369 | * |
370 | * @return | |
371 | * 0 on success and stats is filled, negative errno value otherwise and | |
372 | * rte_errno is set. | |
11fdf7f2 | 373 | */ |
9f95a23c | 374 | int |
11fdf7f2 TL |
375 | mlx5_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) |
376 | { | |
9f95a23c TL |
377 | struct mlx5_priv *priv = dev->data->dev_private; |
378 | struct rte_eth_stats tmp; | |
11fdf7f2 TL |
379 | unsigned int i; |
380 | unsigned int idx; | |
381 | ||
9f95a23c | 382 | memset(&tmp, 0, sizeof(tmp)); |
11fdf7f2 TL |
383 | /* Add software counters. */ |
384 | for (i = 0; (i != priv->rxqs_n); ++i) { | |
9f95a23c | 385 | struct mlx5_rxq_data *rxq = (*priv->rxqs)[i]; |
11fdf7f2 TL |
386 | |
387 | if (rxq == NULL) | |
388 | continue; | |
9f95a23c | 389 | idx = rxq->idx; |
11fdf7f2 TL |
390 | if (idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) { |
391 | #ifdef MLX5_PMD_SOFT_COUNTERS | |
392 | tmp.q_ipackets[idx] += rxq->stats.ipackets; | |
393 | tmp.q_ibytes[idx] += rxq->stats.ibytes; | |
394 | #endif | |
395 | tmp.q_errors[idx] += (rxq->stats.idropped + | |
396 | rxq->stats.rx_nombuf); | |
397 | } | |
398 | #ifdef MLX5_PMD_SOFT_COUNTERS | |
399 | tmp.ipackets += rxq->stats.ipackets; | |
400 | tmp.ibytes += rxq->stats.ibytes; | |
401 | #endif | |
402 | tmp.ierrors += rxq->stats.idropped; | |
403 | tmp.rx_nombuf += rxq->stats.rx_nombuf; | |
404 | } | |
405 | for (i = 0; (i != priv->txqs_n); ++i) { | |
9f95a23c | 406 | struct mlx5_txq_data *txq = (*priv->txqs)[i]; |
11fdf7f2 TL |
407 | |
408 | if (txq == NULL) | |
409 | continue; | |
9f95a23c | 410 | idx = txq->idx; |
11fdf7f2 TL |
411 | if (idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) { |
412 | #ifdef MLX5_PMD_SOFT_COUNTERS | |
413 | tmp.q_opackets[idx] += txq->stats.opackets; | |
414 | tmp.q_obytes[idx] += txq->stats.obytes; | |
415 | #endif | |
9f95a23c | 416 | tmp.q_errors[idx] += txq->stats.oerrors; |
11fdf7f2 TL |
417 | } |
418 | #ifdef MLX5_PMD_SOFT_COUNTERS | |
419 | tmp.opackets += txq->stats.opackets; | |
420 | tmp.obytes += txq->stats.obytes; | |
421 | #endif | |
9f95a23c | 422 | tmp.oerrors += txq->stats.oerrors; |
11fdf7f2 | 423 | } |
9f95a23c TL |
424 | mlx5_read_ib_stat(priv, "out_of_buffer", &tmp.imissed); |
425 | tmp.imissed -= priv->stats_ctrl.imissed_base; | |
11fdf7f2 TL |
426 | #ifndef MLX5_PMD_SOFT_COUNTERS |
427 | /* FIXME: retrieve and add hardware counters. */ | |
428 | #endif | |
429 | *stats = tmp; | |
9f95a23c | 430 | return 0; |
11fdf7f2 TL |
431 | } |
432 | ||
433 | /** | |
434 | * DPDK callback to clear device statistics. | |
435 | * | |
436 | * @param dev | |
437 | * Pointer to Ethernet device structure. | |
438 | */ | |
439 | void | |
440 | mlx5_stats_reset(struct rte_eth_dev *dev) | |
441 | { | |
9f95a23c TL |
442 | struct mlx5_priv *priv = dev->data->dev_private; |
443 | struct mlx5_stats_ctrl *stats_ctrl = &priv->stats_ctrl; | |
11fdf7f2 | 444 | unsigned int i; |
11fdf7f2 | 445 | |
11fdf7f2 TL |
446 | for (i = 0; (i != priv->rxqs_n); ++i) { |
447 | if ((*priv->rxqs)[i] == NULL) | |
448 | continue; | |
9f95a23c TL |
449 | memset(&(*priv->rxqs)[i]->stats, 0, |
450 | sizeof(struct mlx5_rxq_stats)); | |
11fdf7f2 TL |
451 | } |
452 | for (i = 0; (i != priv->txqs_n); ++i) { | |
453 | if ((*priv->txqs)[i] == NULL) | |
454 | continue; | |
9f95a23c TL |
455 | memset(&(*priv->txqs)[i]->stats, 0, |
456 | sizeof(struct mlx5_txq_stats)); | |
11fdf7f2 | 457 | } |
9f95a23c | 458 | mlx5_read_ib_stat(priv, "out_of_buffer", &stats_ctrl->imissed_base); |
11fdf7f2 TL |
459 | #ifndef MLX5_PMD_SOFT_COUNTERS |
460 | /* FIXME: reset hardware counters. */ | |
461 | #endif | |
11fdf7f2 TL |
462 | } |
463 | ||
464 | /** | |
465 | * DPDK callback to clear device extended statistics. | |
466 | * | |
467 | * @param dev | |
468 | * Pointer to Ethernet device structure. | |
469 | */ | |
470 | void | |
471 | mlx5_xstats_reset(struct rte_eth_dev *dev) | |
472 | { | |
9f95a23c | 473 | struct mlx5_priv *priv = dev->data->dev_private; |
11fdf7f2 TL |
474 | struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl; |
475 | int stats_n; | |
9f95a23c TL |
476 | unsigned int i; |
477 | unsigned int n = xstats_ctrl->mlx5_stats_n; | |
478 | uint64_t counters[n]; | |
479 | int ret; | |
11fdf7f2 | 480 | |
9f95a23c TL |
481 | stats_n = mlx5_ethtool_get_stats_n(dev); |
482 | if (stats_n < 0) { | |
483 | DRV_LOG(ERR, "port %u cannot get stats: %s", dev->data->port_id, | |
484 | strerror(-stats_n)); | |
11fdf7f2 | 485 | return; |
9f95a23c | 486 | } |
11fdf7f2 | 487 | if (xstats_ctrl->stats_n != stats_n) |
9f95a23c TL |
488 | mlx5_stats_init(dev); |
489 | ret = mlx5_read_dev_counters(dev, counters); | |
490 | if (ret) { | |
491 | DRV_LOG(ERR, "port %u cannot read device counters: %s", | |
492 | dev->data->port_id, strerror(rte_errno)); | |
493 | return; | |
494 | } | |
495 | for (i = 0; i != n; ++i) | |
496 | xstats_ctrl->base[i] = counters[i]; | |
11fdf7f2 TL |
497 | } |
498 | ||
499 | /** | |
500 | * DPDK callback to retrieve names of extended device statistics | |
501 | * | |
502 | * @param dev | |
503 | * Pointer to Ethernet device structure. | |
504 | * @param[out] xstats_names | |
505 | * Buffer to insert names into. | |
506 | * @param n | |
507 | * Number of names. | |
508 | * | |
509 | * @return | |
510 | * Number of xstats names. | |
511 | */ | |
512 | int | |
9f95a23c TL |
513 | mlx5_xstats_get_names(struct rte_eth_dev *dev __rte_unused, |
514 | struct rte_eth_xstat_name *xstats_names, unsigned int n) | |
11fdf7f2 | 515 | { |
11fdf7f2 | 516 | unsigned int i; |
9f95a23c TL |
517 | struct mlx5_priv *priv = dev->data->dev_private; |
518 | struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl; | |
519 | unsigned int mlx5_xstats_n = xstats_ctrl->mlx5_stats_n; | |
11fdf7f2 | 520 | |
9f95a23c TL |
521 | if (n >= mlx5_xstats_n && xstats_names) { |
522 | for (i = 0; i != mlx5_xstats_n; ++i) { | |
11fdf7f2 | 523 | strncpy(xstats_names[i].name, |
9f95a23c | 524 | xstats_ctrl->info[i].dpdk_name, |
11fdf7f2 TL |
525 | RTE_ETH_XSTATS_NAME_SIZE); |
526 | xstats_names[i].name[RTE_ETH_XSTATS_NAME_SIZE - 1] = 0; | |
527 | } | |
11fdf7f2 | 528 | } |
9f95a23c | 529 | return mlx5_xstats_n; |
11fdf7f2 | 530 | } |