Initialize device stats and fetch them using sysctl. Signed-off-by: Srikanth Kaka <srikant...@oneconvergence.com> Signed-off-by: Vag Singh <vag.si...@oneconvergence.com> Signed-off-by: Anand Thulasiram <av...@juniper.net> --- drivers/net/mlx5/freebsd/mlx5_ethdev_os.c | 217 ++++++++++++++++++++++ 1 file changed, 217 insertions(+)
diff --git a/drivers/net/mlx5/freebsd/mlx5_ethdev_os.c b/drivers/net/mlx5/freebsd/mlx5_ethdev_os.c index db16027244..a6e28ea4bb 100644 --- a/drivers/net/mlx5/freebsd/mlx5_ethdev_os.c +++ b/drivers/net/mlx5/freebsd/mlx5_ethdev_os.c @@ -6,6 +6,7 @@ #include <stdio.h> #include <stdint.h> #include <net/if_media.h> +#include <sys/sysctl.h> #include <sys/ioctl.h> #include <time.h> @@ -18,6 +19,8 @@ #include "mlx5.h" +static unsigned int xstats_n; + /** * Get interface name from private structure. * @@ -721,6 +724,220 @@ int mlx5_get_module_eeprom(struct rte_eth_dev *dev, return -ENOTSUP; } +/** + * Read device counters table. + * + * @param dev + * Pointer to Ethernet device. + * @param[in] pf + * PF index in case of bonding device, -1 otherwise + * @param[out] stats + * Counters table output buffer. + */ +static void +_mlx5_os_read_dev_counters(struct rte_eth_dev *dev, uint64_t *stats) +{ + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl; + char stat_key[RTE_ETH_XSTATS_NAME_SIZE + 16]; + unsigned int i; + size_t len = sizeof(uint64_t); + uint64_t val; + int ibvindex, ret; + + ibvindex = mlx5_get_ibvindex(priv->sh->ibdev_path); + + for (i = 0; i != xstats_ctrl->mlx5_stats_n; ++i) { + snprintf(stat_key, sizeof(stat_key), "dev.mce.%d.%s", + ibvindex, xstats_ctrl->info[i].ctr_name); + ret = sysctlbyname(stat_key, &val, &len, NULL, 0); + if (ret == -1) { + DRV_LOG(WARNING, "port %u failed to get statistics: %s", + dev->data->port_id, strerror(errno)); + continue; + } + stats[i] += val; + } +} + +/** + * Read device counters. + * + * @param dev + * Pointer to Ethernet device. + * @param[out] stats + * Counters table output buffer. + */ +int +mlx5_os_read_dev_counters(struct rte_eth_dev *dev, uint64_t *stats) +{ + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl; + int i; + + memset(stats, 0, sizeof(*stats) * xstats_ctrl->mlx5_stats_n); + _mlx5_os_read_dev_counters(dev, stats); + /* Read IB counters. */ + for (i = 0; i != xstats_ctrl->mlx5_stats_n; ++i) { + if (!xstats_ctrl->info[i].dev) + continue; + xstats_ctrl->xstats[i] = stats[i]; + } + return 0; +} + +/** + * Query the number of statistics. + * + * @param dev + * Pointer to Ethernet device. + * + * @return + * Number of statistics on success. + */ +int +mlx5_os_get_stats_n(struct rte_eth_dev *dev) +{ + RTE_SET_USED(dev); + return xstats_n; +} + +static const struct mlx5_counter_ctrl mlx5_counters_init[] = { + { + .dpdk_name = "rx_port_unicast_bytes", + .ctr_name = "vstats.rx_unicast_bytes", + }, + { + .dpdk_name = "rx_port_multicast_bytes", + .ctr_name = "vstats.rx_multicast_bytes", + }, + { + .dpdk_name = "rx_port_broadcast_bytes", + .ctr_name = "vstats.rx_broadcast_bytes", + }, + { + .dpdk_name = "rx_port_unicast_packets", + .ctr_name = "vstats.rx_unicast_packets", + }, + { + .dpdk_name = "rx_port_multicast_packets", + .ctr_name = "vstats.rx_multicast_packets", + }, + { + .dpdk_name = "rx_port_broadcast_packets", + .ctr_name = "vstats.rx_broadcast_packets", + }, + { + .dpdk_name = "tx_port_unicast_bytes", + .ctr_name = "vstats.tx_unicast_bytes", + }, + { + .dpdk_name = "tx_port_multicast_bytes", + .ctr_name = "vstats.tx_multicast_bytes", + }, + { + .dpdk_name = "tx_port_broadcast_bytes", + .ctr_name = "vstats.tx_broadcast_bytes", + }, + { + .dpdk_name = "tx_port_unicast_packets", + .ctr_name = "vstats.tx_unicast_packets", + }, + { + .dpdk_name = "tx_port_multicast_packets", + .ctr_name = "vstats.tx_multicast_packets", + }, + { + .dpdk_name = "tx_port_broadcast_packets", + .ctr_name = "vstats.tx_broadcast_packets", + }, + { + .dpdk_name = "rx_wqe_err", + .ctr_name = "vstats.rx_wqe_err", + }, + { + .dpdk_name = "rx_crc_align_errors", + .ctr_name = "pstats.crc_align_errors", + }, + { + .dpdk_name = "rx_in_range_len_errors", + .ctr_name = "pstats.in_range_len_errors", + }, + { + .dpdk_name = "rx_symbol_err", + .ctr_name = "pstats.symbol_err", + }, + { + .dpdk_name = "tx_errors_packets", + .ctr_name = "vstats.tx_error_packets", + }, + { + .dpdk_name = "rx_out_of_buffer", + .ctr_name = "vstats.rx_out_of_buffer", + }, + { + .dpdk_name = "lro_bytes", + .ctr_name = "vstats.lro_bytes", + }, + { + .dpdk_name = "lro_packets", + .ctr_name = "vstats.lro_packets", + }, + { + .dpdk_name = "tso_bytes", + .ctr_name = "vstats.tso_bytes", + }, + { + .dpdk_name = "tso_packets", + .ctr_name = "vstats.tso_packets", + }, + /* Representor only */ + { + .dpdk_name = "rx_packets", + .ctr_name = "vstats.rx_packets", + }, + { + .dpdk_name = "rx_bytes", + .ctr_name = "vstats.rx_bytes", + }, + { + .dpdk_name = "tx_packets", + .ctr_name = "vstats.tx_packets", + }, + { + .dpdk_name = "tx_bytes", + .ctr_name = "vstats.tx_bytes", + }, +}; + +/** + * Init the structures to read device counters. + * + * @param dev + * Pointer to Ethernet device. + */ +void +mlx5_os_stats_init(struct rte_eth_dev *dev) +{ + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl; + struct mlx5_stats_ctrl *stats_ctrl = &priv->stats_ctrl; + unsigned int i, idx; + + xstats_n = RTE_DIM(mlx5_counters_init); + xstats_ctrl->mlx5_stats_n = 0; + + for (i = 0; i != xstats_n; ++i) { + idx = xstats_ctrl->mlx5_stats_n++; + + xstats_ctrl->dev_table_idx[idx] = i; + xstats_ctrl->info[idx] = mlx5_counters_init[i]; + } + xstats_ctrl->stats_n = xstats_n; + mlx5_os_read_dev_counters(dev, xstats_ctrl->base); + stats_ctrl->imissed = 0; +} + /** * Get MAC address by querying netdevice. * -- 2.30.2