-#include "mlx5.h"
-#include "mlx5_rxtx.h"
-#include "mlx5_defs.h"
-
-struct mlx5_counter_ctrl {
- /* Name of the counter. */
- char dpdk_name[RTE_ETH_XSTATS_NAME_SIZE];
- /* Name of the counter on the device table. */
- char ctr_name[RTE_ETH_XSTATS_NAME_SIZE];
-};
-
-static const struct mlx5_counter_ctrl mlx5_counters_init[] = {
- {
- .dpdk_name = "rx_port_unicast_bytes",
- .ctr_name = "rx_vport_unicast_bytes",
- },
- {
- .dpdk_name = "rx_port_multicast_bytes",
- .ctr_name = "rx_vport_multicast_bytes",
- },
- {
- .dpdk_name = "rx_port_broadcast_bytes",
- .ctr_name = "rx_vport_broadcast_bytes",
- },
- {
- .dpdk_name = "rx_port_unicast_packets",
- .ctr_name = "rx_vport_unicast_packets",
- },
- {
- .dpdk_name = "rx_port_multicast_packets",
- .ctr_name = "rx_vport_multicast_packets",
- },
- {
- .dpdk_name = "rx_port_broadcast_packets",
- .ctr_name = "rx_vport_broadcast_packets",
- },
- {
- .dpdk_name = "tx_port_unicast_bytes",
- .ctr_name = "tx_vport_unicast_bytes",
- },
- {
- .dpdk_name = "tx_port_multicast_bytes",
- .ctr_name = "tx_vport_multicast_bytes",
- },
- {
- .dpdk_name = "tx_port_broadcast_bytes",
- .ctr_name = "tx_vport_broadcast_bytes",
- },
- {
- .dpdk_name = "tx_port_unicast_packets",
- .ctr_name = "tx_vport_unicast_packets",
- },
- {
- .dpdk_name = "tx_port_multicast_packets",
- .ctr_name = "tx_vport_multicast_packets",
- },
- {
- .dpdk_name = "tx_port_broadcast_packets",
- .ctr_name = "tx_vport_broadcast_packets",
- },
- {
- .dpdk_name = "rx_wqe_err",
- .ctr_name = "rx_wqe_err",
- },
- {
- .dpdk_name = "rx_crc_errors_phy",
- .ctr_name = "rx_crc_errors_phy",
- },
- {
- .dpdk_name = "rx_in_range_len_errors_phy",
- .ctr_name = "rx_in_range_len_errors_phy",
- },
- {
- .dpdk_name = "rx_symbol_err_phy",
- .ctr_name = "rx_symbol_err_phy",
- },
- {
- .dpdk_name = "tx_errors_phy",
- .ctr_name = "tx_errors_phy",
- },
- {
- .dpdk_name = "rx_out_of_buffer",
- .ctr_name = "out_of_buffer",
- },
- {
- .dpdk_name = "tx_packets_phy",
- .ctr_name = "tx_packets_phy",
- },
- {
- .dpdk_name = "rx_packets_phy",
- .ctr_name = "rx_packets_phy",
- },
- {
- .dpdk_name = "tx_bytes_phy",
- .ctr_name = "tx_bytes_phy",
- },
- {
- .dpdk_name = "rx_bytes_phy",
- .ctr_name = "rx_bytes_phy",
- },
-};
-
-static const unsigned int xstats_n = RTE_DIM(mlx5_counters_init);
-
-/**
- * Read device counters table.
- *
- * @param priv
- * Pointer to private structure.
- * @param[out] stats
- * Counters table output buffer.
- *
- * @return
- * 0 on success and stats is filled, negative on error.
- */
-static int
-priv_read_dev_counters(struct priv *priv, uint64_t *stats)
-{
- struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl;
- unsigned int i;
- struct ifreq ifr;
- unsigned int stats_sz = xstats_ctrl->stats_n * sizeof(uint64_t);
- unsigned char et_stat_buf[sizeof(struct ethtool_stats) + stats_sz];
- struct ethtool_stats *et_stats = (struct ethtool_stats *)et_stat_buf;
-
- et_stats->cmd = ETHTOOL_GSTATS;
- et_stats->n_stats = xstats_ctrl->stats_n;
- ifr.ifr_data = (caddr_t)et_stats;
- if (priv_ifreq(priv, SIOCETHTOOL, &ifr) != 0) {
- WARN("unable to read statistic values from device");
- return -1;
- }
- for (i = 0; i != xstats_n; ++i) {
- if (priv_is_ib_cntr(mlx5_counters_init[i].ctr_name))
- priv_get_cntr_sysfs(priv,
- mlx5_counters_init[i].ctr_name,
- &stats[i]);
- else
- stats[i] = (uint64_t)
- et_stats->data[xstats_ctrl->dev_table_idx[i]];
- }
- return 0;
-}
-
-/**
- * Query the number of statistics provided by ETHTOOL.
- *
- * @param priv
- * Pointer to private structure.
- *
- * @return
- * Number of statistics on success, -1 on error.
- */
-static int
-priv_ethtool_get_stats_n(struct priv *priv) {
- struct ethtool_drvinfo drvinfo;
- struct ifreq ifr;
-
- drvinfo.cmd = ETHTOOL_GDRVINFO;
- ifr.ifr_data = (caddr_t)&drvinfo;
- if (priv_ifreq(priv, SIOCETHTOOL, &ifr) != 0) {
- WARN("unable to query number of statistics");
- return -1;
- }
- return drvinfo.n_stats;
-}
-
-/**
- * Init the structures to read device counters.
- *
- * @param priv
- * Pointer to private structure.
- */
-void
-priv_xstats_init(struct priv *priv)
-{
- struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl;
- unsigned int i;
- unsigned int j;
- struct ifreq ifr;
- struct ethtool_gstrings *strings = NULL;
- unsigned int dev_stats_n;
- unsigned int str_sz;
-
- dev_stats_n = priv_ethtool_get_stats_n(priv);
- if (dev_stats_n < 1) {
- WARN("no extended statistics available");
- return;
- }
- xstats_ctrl->stats_n = dev_stats_n;
- /* Allocate memory to grab stat names and values. */
- str_sz = dev_stats_n * ETH_GSTRING_LEN;
- strings = (struct ethtool_gstrings *)
- rte_malloc("xstats_strings",
- str_sz + sizeof(struct ethtool_gstrings), 0);
- if (!strings) {
- WARN("unable to allocate memory for xstats");
- return;
- }
- strings->cmd = ETHTOOL_GSTRINGS;
- strings->string_set = ETH_SS_STATS;
- strings->len = dev_stats_n;
- ifr.ifr_data = (caddr_t)strings;
- if (priv_ifreq(priv, SIOCETHTOOL, &ifr) != 0) {
- WARN("unable to get statistic names");
- goto free;
- }
- for (j = 0; j != xstats_n; ++j)
- xstats_ctrl->dev_table_idx[j] = dev_stats_n;
- for (i = 0; i != dev_stats_n; ++i) {
- const char *curr_string = (const char *)
- &strings->data[i * ETH_GSTRING_LEN];