| diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h |
| index 879da5e..2b4345a 100644 |
| --- a/drivers/net/mlx5/mlx5.h |
| +++ b/drivers/net/mlx5/mlx5.h |
| @@ -197,6 +197,8 @@ struct mlx5_secondary_data { |
| int mlx5_is_secondary(void); |
| int priv_get_ifname(const struct priv *, char (*)[IF_NAMESIZE]); |
| int priv_ifreq(const struct priv *, int req, struct ifreq *); |
| +int priv_is_ib_cntr(const char *); |
| +int priv_get_cntr_sysfs(struct priv *, const char *, uint64_t *); |
| int priv_get_num_vfs(struct priv *, uint16_t *); |
| int priv_get_mtu(struct priv *, uint16_t *); |
| int priv_set_flags(struct priv *, unsigned int, unsigned int); |
| diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c |
| index 2145965..6b64f44 100644 |
| --- a/drivers/net/mlx5/mlx5_ethdev.c |
| +++ b/drivers/net/mlx5/mlx5_ethdev.c |
| @@ -234,6 +234,23 @@ struct priv * |
| } |
| |
| /** |
| + * Check if the counter is located on ib counters file. |
| + * |
| + * @param[in] cntr |
| + * Counter name. |
| + * |
| + * @return |
| + * 1 if counter is located on ib counters file , 0 otherwise. |
| + */ |
| +int |
| +priv_is_ib_cntr(const char *cntr) |
| +{ |
| + if (!strcmp(cntr, "out_of_buffer")) |
| + return 1; |
| + return 0; |
| +} |
| + |
| +/** |
| * Read from sysfs entry. |
| * |
| * @param[in] priv |
| @@ -260,10 +277,15 @@ struct priv * |
| if (priv_get_ifname(priv, &ifname)) |
| return -1; |
| |
| - MKSTR(path, "%s/device/net/%s/%s", priv->ctx->device->ibdev_path, |
| - ifname, entry); |
| - |
| - file = fopen(path, "rb"); |
| + if (priv_is_ib_cntr(entry)) { |
| + MKSTR(path, "%s/ports/1/hw_counters/%s", |
| + priv->ctx->device->ibdev_path, entry); |
| + file = fopen(path, "rb"); |
| + } else { |
| + MKSTR(path, "%s/device/net/%s/%s", |
| + priv->ctx->device->ibdev_path, ifname, entry); |
| + file = fopen(path, "rb"); |
| + } |
| if (file == NULL) |
| return -1; |
| ret = fread(buf, 1, size, file); |
| @@ -469,6 +491,30 @@ struct priv * |
| } |
| |
| /** |
| + * Read device counter from sysfs. |
| + * |
| + * @param priv |
| + * Pointer to private structure. |
| + * @param name |
| + * Counter name. |
| + * @param[out] cntr |
| + * Counter output buffer. |
| + * |
| + * @return |
| + * 0 on success, -1 on failure and errno is set. |
| + */ |
| +int |
| +priv_get_cntr_sysfs(struct priv *priv, const char *name, uint64_t *cntr) |
| +{ |
| + unsigned long ulong_ctr; |
| + |
| + if (priv_get_sysfs_ulong(priv, name, &ulong_ctr) == -1) |
| + return -1; |
| + *cntr = ulong_ctr; |
| + return 0; |
| +} |
| + |
| +/** |
| * Set device MTU. |
| * |
| * @param priv |
| diff --git a/drivers/net/mlx5/mlx5_stats.c b/drivers/net/mlx5/mlx5_stats.c |
| index 20c957e..a48ebea 100644 |
| --- a/drivers/net/mlx5/mlx5_stats.c |
| +++ b/drivers/net/mlx5/mlx5_stats.c |
| @@ -125,6 +125,10 @@ struct mlx5_counter_ctrl { |
| .dpdk_name = "tx_errors_phy", |
| .ctr_name = "tx_errors_phy", |
| }, |
| + { |
| + .dpdk_name = "rx_out_of_buffer", |
| + .ctr_name = "out_of_buffer", |
| + }, |
| }; |
| |
| static const unsigned int xstats_n = RTE_DIM(mlx5_counters_init); |
| @@ -159,9 +163,15 @@ struct mlx5_counter_ctrl { |
| WARN("unable to read statistic values from device"); |
| return -1; |
| } |
| - for (i = 0; i != xstats_n; ++i) |
| - stats[i] = (uint64_t) |
| - et_stats->data[xstats_ctrl->dev_table_idx[i]]; |
| + 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; |
| } |
| |
| @@ -233,6 +243,8 @@ struct mlx5_counter_ctrl { |
| } |
| } |
| for (j = 0; j != xstats_n; ++j) { |
| + if (priv_is_ib_cntr(mlx5_counters_init[i].ctr_name)) |
| + continue; |
| if (xstats_ctrl->dev_table_idx[j] >= dev_stats_n) { |
| WARN("counter \"%s\" is not recognized", |
| mlx5_counters_init[j].dpdk_name); |