187011737SAdrien Mazarguil /*- 287011737SAdrien Mazarguil * BSD LICENSE 387011737SAdrien Mazarguil * 487011737SAdrien Mazarguil * Copyright 2015 6WIND S.A. 587011737SAdrien Mazarguil * Copyright 2015 Mellanox. 687011737SAdrien Mazarguil * 787011737SAdrien Mazarguil * Redistribution and use in source and binary forms, with or without 887011737SAdrien Mazarguil * modification, are permitted provided that the following conditions 987011737SAdrien Mazarguil * are met: 1087011737SAdrien Mazarguil * 1187011737SAdrien Mazarguil * * Redistributions of source code must retain the above copyright 1287011737SAdrien Mazarguil * notice, this list of conditions and the following disclaimer. 1387011737SAdrien Mazarguil * * Redistributions in binary form must reproduce the above copyright 1487011737SAdrien Mazarguil * notice, this list of conditions and the following disclaimer in 1587011737SAdrien Mazarguil * the documentation and/or other materials provided with the 1687011737SAdrien Mazarguil * distribution. 1787011737SAdrien Mazarguil * * Neither the name of 6WIND S.A. nor the names of its 1887011737SAdrien Mazarguil * contributors may be used to endorse or promote products derived 1987011737SAdrien Mazarguil * from this software without specific prior written permission. 2087011737SAdrien Mazarguil * 2187011737SAdrien Mazarguil * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2287011737SAdrien Mazarguil * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2387011737SAdrien Mazarguil * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2487011737SAdrien Mazarguil * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2587011737SAdrien Mazarguil * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2687011737SAdrien Mazarguil * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2787011737SAdrien Mazarguil * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2887011737SAdrien Mazarguil * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2987011737SAdrien Mazarguil * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3087011737SAdrien Mazarguil * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3187011737SAdrien Mazarguil * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3287011737SAdrien Mazarguil */ 3387011737SAdrien Mazarguil 34a4193ae3SShahaf Shuler #include <linux/sockios.h> 35a4193ae3SShahaf Shuler #include <linux/ethtool.h> 36a4193ae3SShahaf Shuler 3787011737SAdrien Mazarguil #include <rte_ethdev.h> 38a4193ae3SShahaf Shuler #include <rte_common.h> 39a4193ae3SShahaf Shuler #include <rte_malloc.h> 4087011737SAdrien Mazarguil 4187011737SAdrien Mazarguil #include "mlx5.h" 4287011737SAdrien Mazarguil #include "mlx5_rxtx.h" 4387011737SAdrien Mazarguil #include "mlx5_defs.h" 4487011737SAdrien Mazarguil 45a4193ae3SShahaf Shuler struct mlx5_counter_ctrl { 46a4193ae3SShahaf Shuler /* Name of the counter. */ 47a4193ae3SShahaf Shuler char dpdk_name[RTE_ETH_XSTATS_NAME_SIZE]; 48a4193ae3SShahaf Shuler /* Name of the counter on the device table. */ 49a4193ae3SShahaf Shuler char ctr_name[RTE_ETH_XSTATS_NAME_SIZE]; 50a4193ae3SShahaf Shuler }; 51a4193ae3SShahaf Shuler 52a4193ae3SShahaf Shuler static const struct mlx5_counter_ctrl mlx5_counters_init[] = { 53a4193ae3SShahaf Shuler { 54a4193ae3SShahaf Shuler .dpdk_name = "rx_port_unicast_bytes", 55a4193ae3SShahaf Shuler .ctr_name = "rx_vport_unicast_bytes", 56a4193ae3SShahaf Shuler }, 57a4193ae3SShahaf Shuler { 58a4193ae3SShahaf Shuler .dpdk_name = "rx_port_multicast_bytes", 59a4193ae3SShahaf Shuler .ctr_name = "rx_vport_multicast_bytes", 60a4193ae3SShahaf Shuler }, 61a4193ae3SShahaf Shuler { 62a4193ae3SShahaf Shuler .dpdk_name = "rx_port_broadcast_bytes", 63a4193ae3SShahaf Shuler .ctr_name = "rx_vport_broadcast_bytes", 64a4193ae3SShahaf Shuler }, 65a4193ae3SShahaf Shuler { 66a4193ae3SShahaf Shuler .dpdk_name = "rx_port_unicast_packets", 67a4193ae3SShahaf Shuler .ctr_name = "rx_vport_unicast_packets", 68a4193ae3SShahaf Shuler }, 69a4193ae3SShahaf Shuler { 70a4193ae3SShahaf Shuler .dpdk_name = "rx_port_multicast_packets", 71a4193ae3SShahaf Shuler .ctr_name = "rx_vport_multicast_packets", 72a4193ae3SShahaf Shuler }, 73a4193ae3SShahaf Shuler { 74a4193ae3SShahaf Shuler .dpdk_name = "rx_port_broadcast_packets", 75a4193ae3SShahaf Shuler .ctr_name = "rx_vport_broadcast_packets", 76a4193ae3SShahaf Shuler }, 77a4193ae3SShahaf Shuler { 78a4193ae3SShahaf Shuler .dpdk_name = "tx_port_unicast_bytes", 79a4193ae3SShahaf Shuler .ctr_name = "tx_vport_unicast_bytes", 80a4193ae3SShahaf Shuler }, 81a4193ae3SShahaf Shuler { 82a4193ae3SShahaf Shuler .dpdk_name = "tx_port_multicast_bytes", 83a4193ae3SShahaf Shuler .ctr_name = "tx_vport_multicast_bytes", 84a4193ae3SShahaf Shuler }, 85a4193ae3SShahaf Shuler { 86a4193ae3SShahaf Shuler .dpdk_name = "tx_port_broadcast_bytes", 87a4193ae3SShahaf Shuler .ctr_name = "tx_vport_broadcast_bytes", 88a4193ae3SShahaf Shuler }, 89a4193ae3SShahaf Shuler { 90a4193ae3SShahaf Shuler .dpdk_name = "tx_port_unicast_packets", 91a4193ae3SShahaf Shuler .ctr_name = "tx_vport_unicast_packets", 92a4193ae3SShahaf Shuler }, 93a4193ae3SShahaf Shuler { 94a4193ae3SShahaf Shuler .dpdk_name = "tx_port_multicast_packets", 95a4193ae3SShahaf Shuler .ctr_name = "tx_vport_multicast_packets", 96a4193ae3SShahaf Shuler }, 97a4193ae3SShahaf Shuler { 98a4193ae3SShahaf Shuler .dpdk_name = "tx_port_broadcast_packets", 99a4193ae3SShahaf Shuler .ctr_name = "tx_vport_broadcast_packets", 100a4193ae3SShahaf Shuler }, 101a4193ae3SShahaf Shuler { 102a4193ae3SShahaf Shuler .dpdk_name = "rx_wqe_err", 103a4193ae3SShahaf Shuler .ctr_name = "rx_wqe_err", 104a4193ae3SShahaf Shuler }, 105a4193ae3SShahaf Shuler { 106a4193ae3SShahaf Shuler .dpdk_name = "rx_crc_errors_phy", 107a4193ae3SShahaf Shuler .ctr_name = "rx_crc_errors_phy", 108a4193ae3SShahaf Shuler }, 109a4193ae3SShahaf Shuler { 110a4193ae3SShahaf Shuler .dpdk_name = "rx_in_range_len_errors_phy", 111a4193ae3SShahaf Shuler .ctr_name = "rx_in_range_len_errors_phy", 112a4193ae3SShahaf Shuler }, 113a4193ae3SShahaf Shuler { 114a4193ae3SShahaf Shuler .dpdk_name = "rx_symbol_err_phy", 115a4193ae3SShahaf Shuler .ctr_name = "rx_symbol_err_phy", 116a4193ae3SShahaf Shuler }, 117a4193ae3SShahaf Shuler { 118a4193ae3SShahaf Shuler .dpdk_name = "tx_errors_phy", 119a4193ae3SShahaf Shuler .ctr_name = "tx_errors_phy", 120a4193ae3SShahaf Shuler }, 121859081d3SShahaf Shuler { 122859081d3SShahaf Shuler .dpdk_name = "rx_out_of_buffer", 123859081d3SShahaf Shuler .ctr_name = "out_of_buffer", 124859081d3SShahaf Shuler }, 125a4193ae3SShahaf Shuler }; 126a4193ae3SShahaf Shuler 127a4193ae3SShahaf Shuler static const unsigned int xstats_n = RTE_DIM(mlx5_counters_init); 128a4193ae3SShahaf Shuler 129a4193ae3SShahaf Shuler /** 130a4193ae3SShahaf Shuler * Read device counters table. 131a4193ae3SShahaf Shuler * 132a4193ae3SShahaf Shuler * @param priv 133a4193ae3SShahaf Shuler * Pointer to private structure. 134a4193ae3SShahaf Shuler * @param[out] stats 135a4193ae3SShahaf Shuler * Counters table output buffer. 136a4193ae3SShahaf Shuler * 137a4193ae3SShahaf Shuler * @return 138a4193ae3SShahaf Shuler * 0 on success and stats is filled, negative on error. 139a4193ae3SShahaf Shuler */ 140a4193ae3SShahaf Shuler static int 141a4193ae3SShahaf Shuler priv_read_dev_counters(struct priv *priv, uint64_t *stats) 142a4193ae3SShahaf Shuler { 143a4193ae3SShahaf Shuler struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl; 144a4193ae3SShahaf Shuler unsigned int i; 145a4193ae3SShahaf Shuler struct ifreq ifr; 146a4193ae3SShahaf Shuler unsigned int stats_sz = (xstats_ctrl->stats_n * sizeof(uint64_t)) + 147a4193ae3SShahaf Shuler sizeof(struct ethtool_stats); 148a4193ae3SShahaf Shuler struct ethtool_stats et_stats[(stats_sz + ( 149a4193ae3SShahaf Shuler sizeof(struct ethtool_stats) - 1)) / 150a4193ae3SShahaf Shuler sizeof(struct ethtool_stats)]; 151a4193ae3SShahaf Shuler 152a4193ae3SShahaf Shuler et_stats->cmd = ETHTOOL_GSTATS; 153a4193ae3SShahaf Shuler et_stats->n_stats = xstats_ctrl->stats_n; 154a4193ae3SShahaf Shuler ifr.ifr_data = (caddr_t)et_stats; 155a4193ae3SShahaf Shuler if (priv_ifreq(priv, SIOCETHTOOL, &ifr) != 0) { 156a4193ae3SShahaf Shuler WARN("unable to read statistic values from device"); 157a4193ae3SShahaf Shuler return -1; 158a4193ae3SShahaf Shuler } 159859081d3SShahaf Shuler for (i = 0; i != xstats_n; ++i) { 160859081d3SShahaf Shuler if (priv_is_ib_cntr(mlx5_counters_init[i].ctr_name)) 161859081d3SShahaf Shuler priv_get_cntr_sysfs(priv, 162859081d3SShahaf Shuler mlx5_counters_init[i].ctr_name, 163859081d3SShahaf Shuler &stats[i]); 164859081d3SShahaf Shuler else 165a4193ae3SShahaf Shuler stats[i] = (uint64_t) 166a4193ae3SShahaf Shuler et_stats->data[xstats_ctrl->dev_table_idx[i]]; 167859081d3SShahaf Shuler } 168a4193ae3SShahaf Shuler return 0; 169a4193ae3SShahaf Shuler } 170a4193ae3SShahaf Shuler 171a4193ae3SShahaf Shuler /** 172e62bc9e7SShahaf Shuler * Query the number of statistics provided by ETHTOOL. 173e62bc9e7SShahaf Shuler * 174e62bc9e7SShahaf Shuler * @param priv 175e62bc9e7SShahaf Shuler * Pointer to private structure. 176e62bc9e7SShahaf Shuler * 177e62bc9e7SShahaf Shuler * @return 178e62bc9e7SShahaf Shuler * Number of statistics on success, -1 on error. 179e62bc9e7SShahaf Shuler */ 180e62bc9e7SShahaf Shuler static int 181e62bc9e7SShahaf Shuler priv_ethtool_get_stats_n(struct priv *priv) { 182e62bc9e7SShahaf Shuler struct ethtool_drvinfo drvinfo; 183e62bc9e7SShahaf Shuler struct ifreq ifr; 184e62bc9e7SShahaf Shuler 185e62bc9e7SShahaf Shuler drvinfo.cmd = ETHTOOL_GDRVINFO; 186e62bc9e7SShahaf Shuler ifr.ifr_data = (caddr_t)&drvinfo; 187e62bc9e7SShahaf Shuler if (priv_ifreq(priv, SIOCETHTOOL, &ifr) != 0) { 188e62bc9e7SShahaf Shuler WARN("unable to query number of statistics"); 189e62bc9e7SShahaf Shuler return -1; 190e62bc9e7SShahaf Shuler } 191e62bc9e7SShahaf Shuler return drvinfo.n_stats; 192e62bc9e7SShahaf Shuler } 193e62bc9e7SShahaf Shuler 194e62bc9e7SShahaf Shuler /** 195a4193ae3SShahaf Shuler * Init the structures to read device counters. 196a4193ae3SShahaf Shuler * 197a4193ae3SShahaf Shuler * @param priv 198a4193ae3SShahaf Shuler * Pointer to private structure. 199a4193ae3SShahaf Shuler */ 200a4193ae3SShahaf Shuler void 201a4193ae3SShahaf Shuler priv_xstats_init(struct priv *priv) 202a4193ae3SShahaf Shuler { 203a4193ae3SShahaf Shuler struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl; 204a4193ae3SShahaf Shuler unsigned int i; 205a4193ae3SShahaf Shuler unsigned int j; 206a4193ae3SShahaf Shuler struct ifreq ifr; 207a4193ae3SShahaf Shuler struct ethtool_gstrings *strings = NULL; 208a4193ae3SShahaf Shuler unsigned int dev_stats_n; 209a4193ae3SShahaf Shuler unsigned int str_sz; 210a4193ae3SShahaf Shuler 211e62bc9e7SShahaf Shuler dev_stats_n = priv_ethtool_get_stats_n(priv); 212a4193ae3SShahaf Shuler if (dev_stats_n < 1) { 213a4193ae3SShahaf Shuler WARN("no extended statistics available"); 214a4193ae3SShahaf Shuler return; 215a4193ae3SShahaf Shuler } 216a4193ae3SShahaf Shuler xstats_ctrl->stats_n = dev_stats_n; 217a4193ae3SShahaf Shuler /* Allocate memory to grab stat names and values. */ 218a4193ae3SShahaf Shuler str_sz = dev_stats_n * ETH_GSTRING_LEN; 219a4193ae3SShahaf Shuler strings = (struct ethtool_gstrings *) 220a4193ae3SShahaf Shuler rte_malloc("xstats_strings", 221a4193ae3SShahaf Shuler str_sz + sizeof(struct ethtool_gstrings), 0); 222a4193ae3SShahaf Shuler if (!strings) { 223a4193ae3SShahaf Shuler WARN("unable to allocate memory for xstats"); 224a4193ae3SShahaf Shuler return; 225a4193ae3SShahaf Shuler } 226a4193ae3SShahaf Shuler strings->cmd = ETHTOOL_GSTRINGS; 227a4193ae3SShahaf Shuler strings->string_set = ETH_SS_STATS; 228a4193ae3SShahaf Shuler strings->len = dev_stats_n; 229a4193ae3SShahaf Shuler ifr.ifr_data = (caddr_t)strings; 230a4193ae3SShahaf Shuler if (priv_ifreq(priv, SIOCETHTOOL, &ifr) != 0) { 231a4193ae3SShahaf Shuler WARN("unable to get statistic names"); 232a4193ae3SShahaf Shuler goto free; 233a4193ae3SShahaf Shuler } 234a4193ae3SShahaf Shuler for (j = 0; j != xstats_n; ++j) 235a4193ae3SShahaf Shuler xstats_ctrl->dev_table_idx[j] = dev_stats_n; 236a4193ae3SShahaf Shuler for (i = 0; i != dev_stats_n; ++i) { 237a4193ae3SShahaf Shuler const char *curr_string = (const char *) 238a4193ae3SShahaf Shuler &strings->data[i * ETH_GSTRING_LEN]; 239a4193ae3SShahaf Shuler 240a4193ae3SShahaf Shuler for (j = 0; j != xstats_n; ++j) { 241a4193ae3SShahaf Shuler if (!strcmp(mlx5_counters_init[j].ctr_name, 242a4193ae3SShahaf Shuler curr_string)) { 243a4193ae3SShahaf Shuler xstats_ctrl->dev_table_idx[j] = i; 244a4193ae3SShahaf Shuler break; 245a4193ae3SShahaf Shuler } 246a4193ae3SShahaf Shuler } 247a4193ae3SShahaf Shuler } 248a4193ae3SShahaf Shuler for (j = 0; j != xstats_n; ++j) { 2494b2e6df2SShahaf Shuler if (priv_is_ib_cntr(mlx5_counters_init[j].ctr_name)) 250859081d3SShahaf Shuler continue; 251a4193ae3SShahaf Shuler if (xstats_ctrl->dev_table_idx[j] >= dev_stats_n) { 252a4193ae3SShahaf Shuler WARN("counter \"%s\" is not recognized", 253a4193ae3SShahaf Shuler mlx5_counters_init[j].dpdk_name); 254a4193ae3SShahaf Shuler goto free; 255a4193ae3SShahaf Shuler } 256a4193ae3SShahaf Shuler } 257a4193ae3SShahaf Shuler /* Copy to base at first time. */ 258a4193ae3SShahaf Shuler assert(xstats_n <= MLX5_MAX_XSTATS); 259a4193ae3SShahaf Shuler priv_read_dev_counters(priv, xstats_ctrl->base); 260a4193ae3SShahaf Shuler free: 261a4193ae3SShahaf Shuler rte_free(strings); 262a4193ae3SShahaf Shuler } 263a4193ae3SShahaf Shuler 264a4193ae3SShahaf Shuler /** 265a4193ae3SShahaf Shuler * Get device extended statistics. 266a4193ae3SShahaf Shuler * 267a4193ae3SShahaf Shuler * @param priv 268a4193ae3SShahaf Shuler * Pointer to private structure. 269a4193ae3SShahaf Shuler * @param[out] stats 270a4193ae3SShahaf Shuler * Pointer to rte extended stats table. 271a4193ae3SShahaf Shuler * 272a4193ae3SShahaf Shuler * @return 273a4193ae3SShahaf Shuler * Number of extended stats on success and stats is filled, 274a4193ae3SShahaf Shuler * negative on error. 275a4193ae3SShahaf Shuler */ 276a4193ae3SShahaf Shuler static int 277a4193ae3SShahaf Shuler priv_xstats_get(struct priv *priv, struct rte_eth_xstat *stats) 278a4193ae3SShahaf Shuler { 279a4193ae3SShahaf Shuler struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl; 280a4193ae3SShahaf Shuler unsigned int i; 281a4193ae3SShahaf Shuler unsigned int n = xstats_n; 282a4193ae3SShahaf Shuler uint64_t counters[n]; 283a4193ae3SShahaf Shuler 284a4193ae3SShahaf Shuler if (priv_read_dev_counters(priv, counters) < 0) 285a4193ae3SShahaf Shuler return -1; 286a4193ae3SShahaf Shuler for (i = 0; i != xstats_n; ++i) { 287a4193ae3SShahaf Shuler stats[i].id = i; 288a4193ae3SShahaf Shuler stats[i].value = (counters[i] - xstats_ctrl->base[i]); 289a4193ae3SShahaf Shuler } 290a4193ae3SShahaf Shuler return n; 291a4193ae3SShahaf Shuler } 292a4193ae3SShahaf Shuler 293a4193ae3SShahaf Shuler /** 294a4193ae3SShahaf Shuler * Reset device extended statistics. 295a4193ae3SShahaf Shuler * 296a4193ae3SShahaf Shuler * @param priv 297a4193ae3SShahaf Shuler * Pointer to private structure. 298a4193ae3SShahaf Shuler */ 299a4193ae3SShahaf Shuler static void 300a4193ae3SShahaf Shuler priv_xstats_reset(struct priv *priv) 301a4193ae3SShahaf Shuler { 302a4193ae3SShahaf Shuler struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl; 303a4193ae3SShahaf Shuler unsigned int i; 304a4193ae3SShahaf Shuler unsigned int n = xstats_n; 305a4193ae3SShahaf Shuler uint64_t counters[n]; 306a4193ae3SShahaf Shuler 307a4193ae3SShahaf Shuler if (priv_read_dev_counters(priv, counters) < 0) 308a4193ae3SShahaf Shuler return; 309a4193ae3SShahaf Shuler for (i = 0; i != n; ++i) 310a4193ae3SShahaf Shuler xstats_ctrl->base[i] = counters[i]; 311a4193ae3SShahaf Shuler } 312a4193ae3SShahaf Shuler 31387011737SAdrien Mazarguil /** 31487011737SAdrien Mazarguil * DPDK callback to get device statistics. 31587011737SAdrien Mazarguil * 31687011737SAdrien Mazarguil * @param dev 31787011737SAdrien Mazarguil * Pointer to Ethernet device structure. 31887011737SAdrien Mazarguil * @param[out] stats 31987011737SAdrien Mazarguil * Stats structure output buffer. 32087011737SAdrien Mazarguil */ 321*d5b0924bSMatan Azrad int 32287011737SAdrien Mazarguil mlx5_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) 32387011737SAdrien Mazarguil { 324a48deadaSOr Ami struct priv *priv = mlx5_get_priv(dev); 32587011737SAdrien Mazarguil struct rte_eth_stats tmp = {0}; 32687011737SAdrien Mazarguil unsigned int i; 32787011737SAdrien Mazarguil unsigned int idx; 32887011737SAdrien Mazarguil 32987011737SAdrien Mazarguil priv_lock(priv); 33087011737SAdrien Mazarguil /* Add software counters. */ 33187011737SAdrien Mazarguil for (i = 0; (i != priv->rxqs_n); ++i) { 33278142aacSNélio Laranjeiro struct mlx5_rxq_data *rxq = (*priv->rxqs)[i]; 33387011737SAdrien Mazarguil 33487011737SAdrien Mazarguil if (rxq == NULL) 33587011737SAdrien Mazarguil continue; 33687011737SAdrien Mazarguil idx = rxq->stats.idx; 33787011737SAdrien Mazarguil if (idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) { 33887011737SAdrien Mazarguil #ifdef MLX5_PMD_SOFT_COUNTERS 33987011737SAdrien Mazarguil tmp.q_ipackets[idx] += rxq->stats.ipackets; 34087011737SAdrien Mazarguil tmp.q_ibytes[idx] += rxq->stats.ibytes; 34187011737SAdrien Mazarguil #endif 34287011737SAdrien Mazarguil tmp.q_errors[idx] += (rxq->stats.idropped + 34387011737SAdrien Mazarguil rxq->stats.rx_nombuf); 34487011737SAdrien Mazarguil } 34587011737SAdrien Mazarguil #ifdef MLX5_PMD_SOFT_COUNTERS 34687011737SAdrien Mazarguil tmp.ipackets += rxq->stats.ipackets; 34787011737SAdrien Mazarguil tmp.ibytes += rxq->stats.ibytes; 34887011737SAdrien Mazarguil #endif 34987011737SAdrien Mazarguil tmp.ierrors += rxq->stats.idropped; 35087011737SAdrien Mazarguil tmp.rx_nombuf += rxq->stats.rx_nombuf; 35187011737SAdrien Mazarguil } 35287011737SAdrien Mazarguil for (i = 0; (i != priv->txqs_n); ++i) { 353991b04f6SNélio Laranjeiro struct mlx5_txq_data *txq = (*priv->txqs)[i]; 35487011737SAdrien Mazarguil 35587011737SAdrien Mazarguil if (txq == NULL) 35687011737SAdrien Mazarguil continue; 35787011737SAdrien Mazarguil idx = txq->stats.idx; 35887011737SAdrien Mazarguil if (idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) { 35987011737SAdrien Mazarguil #ifdef MLX5_PMD_SOFT_COUNTERS 36087011737SAdrien Mazarguil tmp.q_opackets[idx] += txq->stats.opackets; 36187011737SAdrien Mazarguil tmp.q_obytes[idx] += txq->stats.obytes; 36287011737SAdrien Mazarguil #endif 3639f9a48ebSShahaf Shuler tmp.q_errors[idx] += txq->stats.oerrors; 36487011737SAdrien Mazarguil } 36587011737SAdrien Mazarguil #ifdef MLX5_PMD_SOFT_COUNTERS 36687011737SAdrien Mazarguil tmp.opackets += txq->stats.opackets; 36787011737SAdrien Mazarguil tmp.obytes += txq->stats.obytes; 36887011737SAdrien Mazarguil #endif 3699f9a48ebSShahaf Shuler tmp.oerrors += txq->stats.oerrors; 37087011737SAdrien Mazarguil } 37187011737SAdrien Mazarguil #ifndef MLX5_PMD_SOFT_COUNTERS 37287011737SAdrien Mazarguil /* FIXME: retrieve and add hardware counters. */ 37387011737SAdrien Mazarguil #endif 37487011737SAdrien Mazarguil *stats = tmp; 37587011737SAdrien Mazarguil priv_unlock(priv); 376*d5b0924bSMatan Azrad return 0; 37787011737SAdrien Mazarguil } 37887011737SAdrien Mazarguil 37987011737SAdrien Mazarguil /** 38087011737SAdrien Mazarguil * DPDK callback to clear device statistics. 38187011737SAdrien Mazarguil * 38287011737SAdrien Mazarguil * @param dev 38387011737SAdrien Mazarguil * Pointer to Ethernet device structure. 38487011737SAdrien Mazarguil */ 38587011737SAdrien Mazarguil void 38687011737SAdrien Mazarguil mlx5_stats_reset(struct rte_eth_dev *dev) 38787011737SAdrien Mazarguil { 38887011737SAdrien Mazarguil struct priv *priv = dev->data->dev_private; 38987011737SAdrien Mazarguil unsigned int i; 39087011737SAdrien Mazarguil unsigned int idx; 39187011737SAdrien Mazarguil 39287011737SAdrien Mazarguil priv_lock(priv); 39387011737SAdrien Mazarguil for (i = 0; (i != priv->rxqs_n); ++i) { 39487011737SAdrien Mazarguil if ((*priv->rxqs)[i] == NULL) 39587011737SAdrien Mazarguil continue; 39687011737SAdrien Mazarguil idx = (*priv->rxqs)[i]->stats.idx; 39787011737SAdrien Mazarguil (*priv->rxqs)[i]->stats = 39887011737SAdrien Mazarguil (struct mlx5_rxq_stats){ .idx = idx }; 39987011737SAdrien Mazarguil } 40087011737SAdrien Mazarguil for (i = 0; (i != priv->txqs_n); ++i) { 40187011737SAdrien Mazarguil if ((*priv->txqs)[i] == NULL) 40287011737SAdrien Mazarguil continue; 4037efc807dSAdrien Mazarguil idx = (*priv->txqs)[i]->stats.idx; 40487011737SAdrien Mazarguil (*priv->txqs)[i]->stats = 40587011737SAdrien Mazarguil (struct mlx5_txq_stats){ .idx = idx }; 40687011737SAdrien Mazarguil } 40787011737SAdrien Mazarguil #ifndef MLX5_PMD_SOFT_COUNTERS 40887011737SAdrien Mazarguil /* FIXME: reset hardware counters. */ 40987011737SAdrien Mazarguil #endif 41087011737SAdrien Mazarguil priv_unlock(priv); 41187011737SAdrien Mazarguil } 412a4193ae3SShahaf Shuler 413a4193ae3SShahaf Shuler /** 414a4193ae3SShahaf Shuler * DPDK callback to get extended device statistics. 415a4193ae3SShahaf Shuler * 416a4193ae3SShahaf Shuler * @param dev 417a4193ae3SShahaf Shuler * Pointer to Ethernet device structure. 418a4193ae3SShahaf Shuler * @param[out] stats 419a4193ae3SShahaf Shuler * Stats table output buffer. 420a4193ae3SShahaf Shuler * @param n 421a4193ae3SShahaf Shuler * The size of the stats table. 422a4193ae3SShahaf Shuler * 423a4193ae3SShahaf Shuler * @return 424a4193ae3SShahaf Shuler * Number of xstats on success, negative on failure. 425a4193ae3SShahaf Shuler */ 426a4193ae3SShahaf Shuler int 427a4193ae3SShahaf Shuler mlx5_xstats_get(struct rte_eth_dev *dev, 428a4193ae3SShahaf Shuler struct rte_eth_xstat *stats, unsigned int n) 429a4193ae3SShahaf Shuler { 430a4193ae3SShahaf Shuler struct priv *priv = mlx5_get_priv(dev); 431a4193ae3SShahaf Shuler int ret = xstats_n; 432a4193ae3SShahaf Shuler 433a4193ae3SShahaf Shuler if (n >= xstats_n && stats) { 434e62bc9e7SShahaf Shuler struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl; 435e62bc9e7SShahaf Shuler int stats_n; 436e62bc9e7SShahaf Shuler 437a4193ae3SShahaf Shuler priv_lock(priv); 438e62bc9e7SShahaf Shuler stats_n = priv_ethtool_get_stats_n(priv); 439b5743da3SMatan Azrad if (stats_n < 0) { 440b5743da3SMatan Azrad priv_unlock(priv); 441e62bc9e7SShahaf Shuler return -1; 442b5743da3SMatan Azrad } 443e62bc9e7SShahaf Shuler if (xstats_ctrl->stats_n != stats_n) 444e62bc9e7SShahaf Shuler priv_xstats_init(priv); 445a4193ae3SShahaf Shuler ret = priv_xstats_get(priv, stats); 446a4193ae3SShahaf Shuler priv_unlock(priv); 447a4193ae3SShahaf Shuler } 448a4193ae3SShahaf Shuler return ret; 449a4193ae3SShahaf Shuler } 450a4193ae3SShahaf Shuler 451a4193ae3SShahaf Shuler /** 452a4193ae3SShahaf Shuler * DPDK callback to clear device extended statistics. 453a4193ae3SShahaf Shuler * 454a4193ae3SShahaf Shuler * @param dev 455a4193ae3SShahaf Shuler * Pointer to Ethernet device structure. 456a4193ae3SShahaf Shuler */ 457a4193ae3SShahaf Shuler void 458a4193ae3SShahaf Shuler mlx5_xstats_reset(struct rte_eth_dev *dev) 459a4193ae3SShahaf Shuler { 460a4193ae3SShahaf Shuler struct priv *priv = mlx5_get_priv(dev); 461e62bc9e7SShahaf Shuler struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl; 462e62bc9e7SShahaf Shuler int stats_n; 463a4193ae3SShahaf Shuler 464a4193ae3SShahaf Shuler priv_lock(priv); 465e62bc9e7SShahaf Shuler stats_n = priv_ethtool_get_stats_n(priv); 466e62bc9e7SShahaf Shuler if (stats_n < 0) 467b5743da3SMatan Azrad goto unlock; 468e62bc9e7SShahaf Shuler if (xstats_ctrl->stats_n != stats_n) 469e62bc9e7SShahaf Shuler priv_xstats_init(priv); 470a4193ae3SShahaf Shuler priv_xstats_reset(priv); 471b5743da3SMatan Azrad unlock: 472a4193ae3SShahaf Shuler priv_unlock(priv); 473a4193ae3SShahaf Shuler } 474a4193ae3SShahaf Shuler 475a4193ae3SShahaf Shuler /** 476a4193ae3SShahaf Shuler * DPDK callback to retrieve names of extended device statistics 477a4193ae3SShahaf Shuler * 478a4193ae3SShahaf Shuler * @param dev 479a4193ae3SShahaf Shuler * Pointer to Ethernet device structure. 480a4193ae3SShahaf Shuler * @param[out] xstats_names 481a4193ae3SShahaf Shuler * Buffer to insert names into. 482a4193ae3SShahaf Shuler * @param n 483a4193ae3SShahaf Shuler * Number of names. 484a4193ae3SShahaf Shuler * 485a4193ae3SShahaf Shuler * @return 486a4193ae3SShahaf Shuler * Number of xstats names. 487a4193ae3SShahaf Shuler */ 488a4193ae3SShahaf Shuler int 489a4193ae3SShahaf Shuler mlx5_xstats_get_names(struct rte_eth_dev *dev, 490a4193ae3SShahaf Shuler struct rte_eth_xstat_name *xstats_names, unsigned int n) 491a4193ae3SShahaf Shuler { 492a4193ae3SShahaf Shuler struct priv *priv = mlx5_get_priv(dev); 493a4193ae3SShahaf Shuler unsigned int i; 494a4193ae3SShahaf Shuler 495a4193ae3SShahaf Shuler if (n >= xstats_n && xstats_names) { 496a4193ae3SShahaf Shuler priv_lock(priv); 497a4193ae3SShahaf Shuler for (i = 0; i != xstats_n; ++i) { 498a4193ae3SShahaf Shuler strncpy(xstats_names[i].name, 499a4193ae3SShahaf Shuler mlx5_counters_init[i].dpdk_name, 500a4193ae3SShahaf Shuler RTE_ETH_XSTATS_NAME_SIZE); 501a4193ae3SShahaf Shuler xstats_names[i].name[RTE_ETH_XSTATS_NAME_SIZE - 1] = 0; 502a4193ae3SShahaf Shuler } 503a4193ae3SShahaf Shuler priv_unlock(priv); 504a4193ae3SShahaf Shuler } 505a4193ae3SShahaf Shuler return xstats_n; 506a4193ae3SShahaf Shuler } 507