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 * 125af4f09f2SNélio Laranjeiro * @param dev 126af4f09f2SNélio Laranjeiro * Pointer to Ethernet device. 127a4193ae3SShahaf Shuler * @param[out] stats 128a4193ae3SShahaf Shuler * Counters table output buffer. 129a4193ae3SShahaf Shuler * 130a4193ae3SShahaf Shuler * @return 131a6d83b6aSNélio Laranjeiro * 0 on success and stats is filled, negative errno value otherwise and 132a6d83b6aSNélio Laranjeiro * rte_errno is set. 133a4193ae3SShahaf Shuler */ 134a4193ae3SShahaf Shuler static int 135af4f09f2SNélio Laranjeiro mlx5_read_dev_counters(struct rte_eth_dev *dev, uint64_t *stats) 136a4193ae3SShahaf Shuler { 137af4f09f2SNélio Laranjeiro struct priv *priv = dev->data->dev_private; 138a4193ae3SShahaf Shuler struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl; 139a4193ae3SShahaf Shuler unsigned int i; 140a4193ae3SShahaf Shuler struct ifreq ifr; 14125b73ba6SThierry Herbelot unsigned int stats_sz = xstats_ctrl->stats_n * sizeof(uint64_t); 14225b73ba6SThierry Herbelot unsigned char et_stat_buf[sizeof(struct ethtool_stats) + stats_sz]; 14325b73ba6SThierry Herbelot struct ethtool_stats *et_stats = (struct ethtool_stats *)et_stat_buf; 144a6d83b6aSNélio Laranjeiro int ret; 145a4193ae3SShahaf Shuler 146a4193ae3SShahaf Shuler et_stats->cmd = ETHTOOL_GSTATS; 147a4193ae3SShahaf Shuler et_stats->n_stats = xstats_ctrl->stats_n; 148a4193ae3SShahaf Shuler ifr.ifr_data = (caddr_t)et_stats; 149a6d83b6aSNélio Laranjeiro ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr); 150a6d83b6aSNélio Laranjeiro if (ret) { 151*a170a30dSNélio Laranjeiro DRV_LOG(WARNING, 152*a170a30dSNélio Laranjeiro "port %u unable to read statistic values from device", 1530f99970bSNélio Laranjeiro dev->data->port_id); 154a6d83b6aSNélio Laranjeiro return ret; 155a4193ae3SShahaf Shuler } 156859081d3SShahaf Shuler for (i = 0; i != xstats_n; ++i) { 157fc40db99SAdrien Mazarguil if (mlx5_counters_init[i].ib) { 158fc40db99SAdrien Mazarguil FILE *file; 159fc40db99SAdrien Mazarguil MKSTR(path, "%s/ports/1/hw_counters/%s", 160fc40db99SAdrien Mazarguil priv->ibdev_path, 161fc40db99SAdrien Mazarguil mlx5_counters_init[i].ctr_name); 162fc40db99SAdrien Mazarguil 163fc40db99SAdrien Mazarguil file = fopen(path, "rb"); 164fc40db99SAdrien Mazarguil if (file) { 165fc40db99SAdrien Mazarguil int n = fscanf(file, "%" SCNu64, &stats[i]); 166fc40db99SAdrien Mazarguil 167fc40db99SAdrien Mazarguil fclose(file); 168fc40db99SAdrien Mazarguil if (n != 1) 169fc40db99SAdrien Mazarguil stats[i] = 0; 170fc40db99SAdrien Mazarguil } 171fc40db99SAdrien Mazarguil } else { 172a4193ae3SShahaf Shuler stats[i] = (uint64_t) 173a4193ae3SShahaf Shuler et_stats->data[xstats_ctrl->dev_table_idx[i]]; 174859081d3SShahaf Shuler } 175fc40db99SAdrien Mazarguil } 176a4193ae3SShahaf Shuler return 0; 177a4193ae3SShahaf Shuler } 178a4193ae3SShahaf Shuler 179a4193ae3SShahaf Shuler /** 180e62bc9e7SShahaf Shuler * Query the number of statistics provided by ETHTOOL. 181e62bc9e7SShahaf Shuler * 182af4f09f2SNélio Laranjeiro * @param dev 183af4f09f2SNélio Laranjeiro * Pointer to Ethernet device. 184e62bc9e7SShahaf Shuler * 185e62bc9e7SShahaf Shuler * @return 186a6d83b6aSNélio Laranjeiro * Number of statistics on success, negative errno value otherwise and 187a6d83b6aSNélio Laranjeiro * rte_errno is set. 188e62bc9e7SShahaf Shuler */ 189e62bc9e7SShahaf Shuler static int 190af4f09f2SNélio Laranjeiro mlx5_ethtool_get_stats_n(struct rte_eth_dev *dev) { 191e62bc9e7SShahaf Shuler struct ethtool_drvinfo drvinfo; 192e62bc9e7SShahaf Shuler struct ifreq ifr; 193a6d83b6aSNélio Laranjeiro int ret; 194e62bc9e7SShahaf Shuler 195e62bc9e7SShahaf Shuler drvinfo.cmd = ETHTOOL_GDRVINFO; 196e62bc9e7SShahaf Shuler ifr.ifr_data = (caddr_t)&drvinfo; 197a6d83b6aSNélio Laranjeiro ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr); 198a6d83b6aSNélio Laranjeiro if (ret) { 199*a170a30dSNélio Laranjeiro DRV_LOG(WARNING, "port %u unable to query number of statistics", 2000f99970bSNélio Laranjeiro dev->data->port_id); 201a6d83b6aSNélio Laranjeiro return ret; 202e62bc9e7SShahaf Shuler } 203e62bc9e7SShahaf Shuler return drvinfo.n_stats; 204e62bc9e7SShahaf Shuler } 205e62bc9e7SShahaf Shuler 206e62bc9e7SShahaf Shuler /** 207a4193ae3SShahaf Shuler * Init the structures to read device counters. 208a4193ae3SShahaf Shuler * 209af4f09f2SNélio Laranjeiro * @param dev 210af4f09f2SNélio Laranjeiro * Pointer to Ethernet device. 211a4193ae3SShahaf Shuler */ 212a4193ae3SShahaf Shuler void 213af4f09f2SNélio Laranjeiro mlx5_xstats_init(struct rte_eth_dev *dev) 214a4193ae3SShahaf Shuler { 215af4f09f2SNélio Laranjeiro struct priv *priv = dev->data->dev_private; 216a4193ae3SShahaf Shuler struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl; 217a4193ae3SShahaf Shuler unsigned int i; 218a4193ae3SShahaf Shuler unsigned int j; 219a4193ae3SShahaf Shuler struct ifreq ifr; 220a4193ae3SShahaf Shuler struct ethtool_gstrings *strings = NULL; 221a4193ae3SShahaf Shuler unsigned int dev_stats_n; 222a4193ae3SShahaf Shuler unsigned int str_sz; 223a6d83b6aSNélio Laranjeiro int ret; 224a4193ae3SShahaf Shuler 225a6d83b6aSNélio Laranjeiro ret = mlx5_ethtool_get_stats_n(dev); 226a6d83b6aSNélio Laranjeiro if (ret < 0) { 227*a170a30dSNélio Laranjeiro DRV_LOG(WARNING, "port %u no extended statistics available", 2280f99970bSNélio Laranjeiro dev->data->port_id); 229a4193ae3SShahaf Shuler return; 230a4193ae3SShahaf Shuler } 231a6d83b6aSNélio Laranjeiro dev_stats_n = ret; 232a4193ae3SShahaf Shuler xstats_ctrl->stats_n = dev_stats_n; 233a4193ae3SShahaf Shuler /* Allocate memory to grab stat names and values. */ 234a4193ae3SShahaf Shuler str_sz = dev_stats_n * ETH_GSTRING_LEN; 235a4193ae3SShahaf Shuler strings = (struct ethtool_gstrings *) 236a4193ae3SShahaf Shuler rte_malloc("xstats_strings", 237a4193ae3SShahaf Shuler str_sz + sizeof(struct ethtool_gstrings), 0); 238a4193ae3SShahaf Shuler if (!strings) { 239*a170a30dSNélio Laranjeiro DRV_LOG(WARNING, "port %u unable to allocate memory for xstats", 2400f99970bSNélio Laranjeiro dev->data->port_id); 241a4193ae3SShahaf Shuler return; 242a4193ae3SShahaf Shuler } 243a4193ae3SShahaf Shuler strings->cmd = ETHTOOL_GSTRINGS; 244a4193ae3SShahaf Shuler strings->string_set = ETH_SS_STATS; 245a4193ae3SShahaf Shuler strings->len = dev_stats_n; 246a4193ae3SShahaf Shuler ifr.ifr_data = (caddr_t)strings; 247a6d83b6aSNélio Laranjeiro ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr); 248a6d83b6aSNélio Laranjeiro if (ret) { 249*a170a30dSNélio Laranjeiro DRV_LOG(WARNING, "port %u unable to get statistic names", 2500f99970bSNélio Laranjeiro dev->data->port_id); 251a4193ae3SShahaf Shuler goto free; 252a4193ae3SShahaf Shuler } 253a4193ae3SShahaf Shuler for (j = 0; j != xstats_n; ++j) 254a4193ae3SShahaf Shuler xstats_ctrl->dev_table_idx[j] = dev_stats_n; 255a4193ae3SShahaf Shuler for (i = 0; i != dev_stats_n; ++i) { 256a4193ae3SShahaf Shuler const char *curr_string = (const char *) 257a4193ae3SShahaf Shuler &strings->data[i * ETH_GSTRING_LEN]; 258a4193ae3SShahaf Shuler 259a4193ae3SShahaf Shuler for (j = 0; j != xstats_n; ++j) { 260a4193ae3SShahaf Shuler if (!strcmp(mlx5_counters_init[j].ctr_name, 261a4193ae3SShahaf Shuler curr_string)) { 262a4193ae3SShahaf Shuler xstats_ctrl->dev_table_idx[j] = i; 263a4193ae3SShahaf Shuler break; 264a4193ae3SShahaf Shuler } 265a4193ae3SShahaf Shuler } 266a4193ae3SShahaf Shuler } 267a4193ae3SShahaf Shuler for (j = 0; j != xstats_n; ++j) { 268fc40db99SAdrien Mazarguil if (mlx5_counters_init[j].ib) 269859081d3SShahaf Shuler continue; 270a4193ae3SShahaf Shuler if (xstats_ctrl->dev_table_idx[j] >= dev_stats_n) { 271*a170a30dSNélio Laranjeiro DRV_LOG(WARNING, 272*a170a30dSNélio Laranjeiro "port %u counter \"%s\" is not recognized", 2730f99970bSNélio Laranjeiro dev->data->port_id, 274a4193ae3SShahaf Shuler mlx5_counters_init[j].dpdk_name); 275a4193ae3SShahaf Shuler goto free; 276a4193ae3SShahaf Shuler } 277a4193ae3SShahaf Shuler } 278a4193ae3SShahaf Shuler /* Copy to base at first time. */ 279a4193ae3SShahaf Shuler assert(xstats_n <= MLX5_MAX_XSTATS); 280a6d83b6aSNélio Laranjeiro ret = mlx5_read_dev_counters(dev, xstats_ctrl->base); 281a6d83b6aSNélio Laranjeiro if (ret) 282*a170a30dSNélio Laranjeiro DRV_LOG(ERR, "port %u cannot read device counters: %s", 2830f99970bSNélio Laranjeiro dev->data->port_id, strerror(rte_errno)); 284a4193ae3SShahaf Shuler free: 285a4193ae3SShahaf Shuler rte_free(strings); 286a4193ae3SShahaf Shuler } 287a4193ae3SShahaf Shuler 288a4193ae3SShahaf Shuler /** 289af4f09f2SNélio Laranjeiro * DPDK callback to get extended device statistics. 290a4193ae3SShahaf Shuler * 291af4f09f2SNélio Laranjeiro * @param dev 292af4f09f2SNélio Laranjeiro * Pointer to Ethernet device. 293a4193ae3SShahaf Shuler * @param[out] stats 294a4193ae3SShahaf Shuler * Pointer to rte extended stats table. 295af4f09f2SNélio Laranjeiro * @param n 296af4f09f2SNélio Laranjeiro * The size of the stats table. 297a4193ae3SShahaf Shuler * 298a4193ae3SShahaf Shuler * @return 299a4193ae3SShahaf Shuler * Number of extended stats on success and stats is filled, 300a6d83b6aSNélio Laranjeiro * negative on error and rte_errno is set. 301a4193ae3SShahaf Shuler */ 302af4f09f2SNélio Laranjeiro int 303af4f09f2SNélio Laranjeiro mlx5_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *stats, 304af4f09f2SNélio Laranjeiro unsigned int n) 305a4193ae3SShahaf Shuler { 306af4f09f2SNélio Laranjeiro struct priv *priv = dev->data->dev_private; 307a4193ae3SShahaf Shuler unsigned int i; 308a4193ae3SShahaf Shuler uint64_t counters[n]; 309a4193ae3SShahaf Shuler 310af4f09f2SNélio Laranjeiro if (n >= xstats_n && stats) { 311af4f09f2SNélio Laranjeiro struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl; 312af4f09f2SNélio Laranjeiro int stats_n; 313a6d83b6aSNélio Laranjeiro int ret; 314af4f09f2SNélio Laranjeiro 315af4f09f2SNélio Laranjeiro stats_n = mlx5_ethtool_get_stats_n(dev); 316af4f09f2SNélio Laranjeiro if (stats_n < 0) 317a6d83b6aSNélio Laranjeiro return stats_n; 318af4f09f2SNélio Laranjeiro if (xstats_ctrl->stats_n != stats_n) 319af4f09f2SNélio Laranjeiro mlx5_xstats_init(dev); 320af4f09f2SNélio Laranjeiro ret = mlx5_read_dev_counters(dev, counters); 321af4f09f2SNélio Laranjeiro if (ret) 322af4f09f2SNélio Laranjeiro return ret; 323a4193ae3SShahaf Shuler for (i = 0; i != xstats_n; ++i) { 324a4193ae3SShahaf Shuler stats[i].id = i; 325a4193ae3SShahaf Shuler stats[i].value = (counters[i] - xstats_ctrl->base[i]); 326a4193ae3SShahaf Shuler } 327a4193ae3SShahaf Shuler } 328af4f09f2SNélio Laranjeiro return n; 329a4193ae3SShahaf Shuler } 330a4193ae3SShahaf Shuler 33187011737SAdrien Mazarguil /** 33287011737SAdrien Mazarguil * DPDK callback to get device statistics. 33387011737SAdrien Mazarguil * 33487011737SAdrien Mazarguil * @param dev 33587011737SAdrien Mazarguil * Pointer to Ethernet device structure. 33687011737SAdrien Mazarguil * @param[out] stats 33787011737SAdrien Mazarguil * Stats structure output buffer. 338a6d83b6aSNélio Laranjeiro * 339a6d83b6aSNélio Laranjeiro * @return 340a6d83b6aSNélio Laranjeiro * 0 on success and stats is filled, negative errno value otherwise and 341a6d83b6aSNélio Laranjeiro * rte_errno is set. 34287011737SAdrien Mazarguil */ 343d5b0924bSMatan Azrad int 34487011737SAdrien Mazarguil mlx5_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) 34587011737SAdrien Mazarguil { 34601d79216SNélio Laranjeiro struct priv *priv = dev->data->dev_private; 34787011737SAdrien Mazarguil struct rte_eth_stats tmp = {0}; 34887011737SAdrien Mazarguil unsigned int i; 34987011737SAdrien Mazarguil unsigned int idx; 35087011737SAdrien Mazarguil 35187011737SAdrien Mazarguil /* Add software counters. */ 35287011737SAdrien Mazarguil for (i = 0; (i != priv->rxqs_n); ++i) { 35378142aacSNélio Laranjeiro struct mlx5_rxq_data *rxq = (*priv->rxqs)[i]; 35487011737SAdrien Mazarguil 35587011737SAdrien Mazarguil if (rxq == NULL) 35687011737SAdrien Mazarguil continue; 35787011737SAdrien Mazarguil idx = rxq->stats.idx; 35887011737SAdrien Mazarguil if (idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) { 35987011737SAdrien Mazarguil #ifdef MLX5_PMD_SOFT_COUNTERS 36087011737SAdrien Mazarguil tmp.q_ipackets[idx] += rxq->stats.ipackets; 36187011737SAdrien Mazarguil tmp.q_ibytes[idx] += rxq->stats.ibytes; 36287011737SAdrien Mazarguil #endif 36387011737SAdrien Mazarguil tmp.q_errors[idx] += (rxq->stats.idropped + 36487011737SAdrien Mazarguil rxq->stats.rx_nombuf); 36587011737SAdrien Mazarguil } 36687011737SAdrien Mazarguil #ifdef MLX5_PMD_SOFT_COUNTERS 36787011737SAdrien Mazarguil tmp.ipackets += rxq->stats.ipackets; 36887011737SAdrien Mazarguil tmp.ibytes += rxq->stats.ibytes; 36987011737SAdrien Mazarguil #endif 37087011737SAdrien Mazarguil tmp.ierrors += rxq->stats.idropped; 37187011737SAdrien Mazarguil tmp.rx_nombuf += rxq->stats.rx_nombuf; 37287011737SAdrien Mazarguil } 37387011737SAdrien Mazarguil for (i = 0; (i != priv->txqs_n); ++i) { 374991b04f6SNélio Laranjeiro struct mlx5_txq_data *txq = (*priv->txqs)[i]; 37587011737SAdrien Mazarguil 37687011737SAdrien Mazarguil if (txq == NULL) 37787011737SAdrien Mazarguil continue; 37887011737SAdrien Mazarguil idx = txq->stats.idx; 37987011737SAdrien Mazarguil if (idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) { 38087011737SAdrien Mazarguil #ifdef MLX5_PMD_SOFT_COUNTERS 38187011737SAdrien Mazarguil tmp.q_opackets[idx] += txq->stats.opackets; 38287011737SAdrien Mazarguil tmp.q_obytes[idx] += txq->stats.obytes; 38387011737SAdrien Mazarguil #endif 3849f9a48ebSShahaf Shuler tmp.q_errors[idx] += txq->stats.oerrors; 38587011737SAdrien Mazarguil } 38687011737SAdrien Mazarguil #ifdef MLX5_PMD_SOFT_COUNTERS 38787011737SAdrien Mazarguil tmp.opackets += txq->stats.opackets; 38887011737SAdrien Mazarguil tmp.obytes += txq->stats.obytes; 38987011737SAdrien Mazarguil #endif 3909f9a48ebSShahaf Shuler tmp.oerrors += txq->stats.oerrors; 39187011737SAdrien Mazarguil } 39287011737SAdrien Mazarguil #ifndef MLX5_PMD_SOFT_COUNTERS 39387011737SAdrien Mazarguil /* FIXME: retrieve and add hardware counters. */ 39487011737SAdrien Mazarguil #endif 39587011737SAdrien Mazarguil *stats = tmp; 396d5b0924bSMatan Azrad return 0; 39787011737SAdrien Mazarguil } 39887011737SAdrien Mazarguil 39987011737SAdrien Mazarguil /** 40087011737SAdrien Mazarguil * DPDK callback to clear device statistics. 40187011737SAdrien Mazarguil * 40287011737SAdrien Mazarguil * @param dev 40387011737SAdrien Mazarguil * Pointer to Ethernet device structure. 40487011737SAdrien Mazarguil */ 40587011737SAdrien Mazarguil void 40687011737SAdrien Mazarguil mlx5_stats_reset(struct rte_eth_dev *dev) 40787011737SAdrien Mazarguil { 40887011737SAdrien Mazarguil struct priv *priv = dev->data->dev_private; 40987011737SAdrien Mazarguil unsigned int i; 41087011737SAdrien Mazarguil unsigned int idx; 41187011737SAdrien Mazarguil 41287011737SAdrien Mazarguil for (i = 0; (i != priv->rxqs_n); ++i) { 41387011737SAdrien Mazarguil if ((*priv->rxqs)[i] == NULL) 41487011737SAdrien Mazarguil continue; 41587011737SAdrien Mazarguil idx = (*priv->rxqs)[i]->stats.idx; 41687011737SAdrien Mazarguil (*priv->rxqs)[i]->stats = 41787011737SAdrien Mazarguil (struct mlx5_rxq_stats){ .idx = idx }; 41887011737SAdrien Mazarguil } 41987011737SAdrien Mazarguil for (i = 0; (i != priv->txqs_n); ++i) { 42087011737SAdrien Mazarguil if ((*priv->txqs)[i] == NULL) 42187011737SAdrien Mazarguil continue; 4227efc807dSAdrien Mazarguil idx = (*priv->txqs)[i]->stats.idx; 42387011737SAdrien Mazarguil (*priv->txqs)[i]->stats = 42487011737SAdrien Mazarguil (struct mlx5_txq_stats){ .idx = idx }; 42587011737SAdrien Mazarguil } 42687011737SAdrien Mazarguil #ifndef MLX5_PMD_SOFT_COUNTERS 42787011737SAdrien Mazarguil /* FIXME: reset hardware counters. */ 42887011737SAdrien Mazarguil #endif 42987011737SAdrien Mazarguil } 430a4193ae3SShahaf Shuler 431a4193ae3SShahaf Shuler /** 432a4193ae3SShahaf Shuler * DPDK callback to clear device extended statistics. 433a4193ae3SShahaf Shuler * 434a4193ae3SShahaf Shuler * @param dev 435a4193ae3SShahaf Shuler * Pointer to Ethernet device structure. 436a4193ae3SShahaf Shuler */ 437a4193ae3SShahaf Shuler void 438a4193ae3SShahaf Shuler mlx5_xstats_reset(struct rte_eth_dev *dev) 439a4193ae3SShahaf Shuler { 44001d79216SNélio Laranjeiro struct priv *priv = dev->data->dev_private; 441e62bc9e7SShahaf Shuler struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl; 442e62bc9e7SShahaf Shuler int stats_n; 443af4f09f2SNélio Laranjeiro unsigned int i; 444af4f09f2SNélio Laranjeiro unsigned int n = xstats_n; 445af4f09f2SNélio Laranjeiro uint64_t counters[n]; 446a6d83b6aSNélio Laranjeiro int ret; 447a4193ae3SShahaf Shuler 448af4f09f2SNélio Laranjeiro stats_n = mlx5_ethtool_get_stats_n(dev); 449a6d83b6aSNélio Laranjeiro if (stats_n < 0) { 450*a170a30dSNélio Laranjeiro DRV_LOG(ERR, "port %u cannot get stats: %s", dev->data->port_id, 451a6d83b6aSNélio Laranjeiro strerror(-stats_n)); 4527b2423cdSNélio Laranjeiro return; 453a6d83b6aSNélio Laranjeiro } 454e62bc9e7SShahaf Shuler if (xstats_ctrl->stats_n != stats_n) 455af4f09f2SNélio Laranjeiro mlx5_xstats_init(dev); 456a6d83b6aSNélio Laranjeiro ret = mlx5_read_dev_counters(dev, counters); 457a6d83b6aSNélio Laranjeiro if (ret) { 458*a170a30dSNélio Laranjeiro DRV_LOG(ERR, "port %u cannot read device counters: %s", 4590f99970bSNélio Laranjeiro dev->data->port_id, strerror(rte_errno)); 460af4f09f2SNélio Laranjeiro return; 461a6d83b6aSNélio Laranjeiro } 462af4f09f2SNélio Laranjeiro for (i = 0; i != n; ++i) 463af4f09f2SNélio Laranjeiro xstats_ctrl->base[i] = counters[i]; 464a4193ae3SShahaf Shuler } 465a4193ae3SShahaf Shuler 466a4193ae3SShahaf Shuler /** 467a4193ae3SShahaf Shuler * DPDK callback to retrieve names of extended device statistics 468a4193ae3SShahaf Shuler * 469a4193ae3SShahaf Shuler * @param dev 470a4193ae3SShahaf Shuler * Pointer to Ethernet device structure. 471a4193ae3SShahaf Shuler * @param[out] xstats_names 472a4193ae3SShahaf Shuler * Buffer to insert names into. 473a4193ae3SShahaf Shuler * @param n 474a4193ae3SShahaf Shuler * Number of names. 475a4193ae3SShahaf Shuler * 476a4193ae3SShahaf Shuler * @return 477a4193ae3SShahaf Shuler * Number of xstats names. 478a4193ae3SShahaf Shuler */ 479a4193ae3SShahaf Shuler int 48056f08e16SNélio Laranjeiro mlx5_xstats_get_names(struct rte_eth_dev *dev __rte_unused, 481a4193ae3SShahaf Shuler struct rte_eth_xstat_name *xstats_names, unsigned int n) 482a4193ae3SShahaf Shuler { 483a4193ae3SShahaf Shuler unsigned int i; 484a4193ae3SShahaf Shuler 485a4193ae3SShahaf Shuler if (n >= xstats_n && xstats_names) { 486a4193ae3SShahaf Shuler for (i = 0; i != xstats_n; ++i) { 487a4193ae3SShahaf Shuler strncpy(xstats_names[i].name, 488a4193ae3SShahaf Shuler mlx5_counters_init[i].dpdk_name, 489a4193ae3SShahaf Shuler RTE_ETH_XSTATS_NAME_SIZE); 490a4193ae3SShahaf Shuler xstats_names[i].name[RTE_ETH_XSTATS_NAME_SIZE - 1] = 0; 491a4193ae3SShahaf Shuler } 492a4193ae3SShahaf Shuler } 493a4193ae3SShahaf Shuler return xstats_n; 494a4193ae3SShahaf Shuler } 495