Blame SOURCES/mlnx-dpdk-0009-net-mlx-control-netdevices-through-ioctl-only.patch

c7ffa4
From 8f419225febbd2f02748fb142aab2c1b96fd3902 Mon Sep 17 00:00:00 2001
c7ffa4
From: Adrien Mazarguil <adrien.mazarguil@6wind.com>
c7ffa4
Date: Wed, 7 Feb 2018 11:45:03 +0100
c7ffa4
Subject: [PATCH 9/9] net/mlx: control netdevices through ioctl only
c7ffa4
c7ffa4
Several control operations implemented by these PMDs affect netdevices
c7ffa4
through sysfs, itself subject to file system permission checks enforced by
c7ffa4
the kernel, which limits their use for most purposes to applications
c7ffa4
running with root privileges.
c7ffa4
c7ffa4
Since performing the same operations through ioctl() requires fewer
c7ffa4
capabilities (only CAP_NET_ADMIN) and given the remaining operations are
c7ffa4
already implemented this way, this patch standardizes on ioctl() and gets
c7ffa4
rid of redundant code.
c7ffa4
c7ffa4
Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
c7ffa4
(cherry picked from commit 84c07af48024fc9d1027770e5143106e16ac49e7)
c7ffa4
---
c7ffa4
 drivers/net/mlx4/mlx4_ethdev.c | 192 ++-----------------------------
c7ffa4
 drivers/net/mlx5/mlx5.h        |   2 -
c7ffa4
 drivers/net/mlx5/mlx5_ethdev.c | 255 +++++------------------------------------
c7ffa4
 drivers/net/mlx5/mlx5_stats.c  |  28 ++++-
c7ffa4
 4 files changed, 63 insertions(+), 414 deletions(-)
c7ffa4
c7ffa4
diff --git a/drivers/net/mlx4/mlx4_ethdev.c b/drivers/net/mlx4/mlx4_ethdev.c
c7ffa4
index e2f9509..cf7afe3 100644
c7ffa4
--- a/drivers/net/mlx4/mlx4_ethdev.c
c7ffa4
+++ b/drivers/net/mlx4/mlx4_ethdev.c
c7ffa4
@@ -160,167 +160,6 @@
c7ffa4
 }
c7ffa4
 
c7ffa4
 /**
c7ffa4
- * Read from sysfs entry.
c7ffa4
- *
c7ffa4
- * @param[in] priv
c7ffa4
- *   Pointer to private structure.
c7ffa4
- * @param[in] entry
c7ffa4
- *   Entry name relative to sysfs path.
c7ffa4
- * @param[out] buf
c7ffa4
- *   Data output buffer.
c7ffa4
- * @param size
c7ffa4
- *   Buffer size.
c7ffa4
- *
c7ffa4
- * @return
c7ffa4
- *   Number of bytes read on success, negative errno value otherwise and
c7ffa4
- *   rte_errno is set.
c7ffa4
- */
c7ffa4
-static int
c7ffa4
-mlx4_sysfs_read(const struct priv *priv, const char *entry,
c7ffa4
-		char *buf, size_t size)
c7ffa4
-{
c7ffa4
-	char ifname[IF_NAMESIZE];
c7ffa4
-	FILE *file;
c7ffa4
-	int ret;
c7ffa4
-
c7ffa4
-	ret = mlx4_get_ifname(priv, &ifname);
c7ffa4
-	if (ret)
c7ffa4
-		return ret;
c7ffa4
-
c7ffa4
-	MKSTR(path, "%s/device/net/%s/%s", priv->ctx->device->ibdev_path,
c7ffa4
-	      ifname, entry);
c7ffa4
-
c7ffa4
-	file = fopen(path, "rb");
c7ffa4
-	if (file == NULL) {
c7ffa4
-		rte_errno = errno;
c7ffa4
-		return -rte_errno;
c7ffa4
-	}
c7ffa4
-	ret = fread(buf, 1, size, file);
c7ffa4
-	if ((size_t)ret < size && ferror(file)) {
c7ffa4
-		rte_errno = EIO;
c7ffa4
-		ret = -rte_errno;
c7ffa4
-	} else {
c7ffa4
-		ret = size;
c7ffa4
-	}
c7ffa4
-	fclose(file);
c7ffa4
-	return ret;
c7ffa4
-}
c7ffa4
-
c7ffa4
-/**
c7ffa4
- * Write to sysfs entry.
c7ffa4
- *
c7ffa4
- * @param[in] priv
c7ffa4
- *   Pointer to private structure.
c7ffa4
- * @param[in] entry
c7ffa4
- *   Entry name relative to sysfs path.
c7ffa4
- * @param[in] buf
c7ffa4
- *   Data buffer.
c7ffa4
- * @param size
c7ffa4
- *   Buffer size.
c7ffa4
- *
c7ffa4
- * @return
c7ffa4
- *   Number of bytes written on success, negative errno value otherwise and
c7ffa4
- *   rte_errno is set.
c7ffa4
- */
c7ffa4
-static int
c7ffa4
-mlx4_sysfs_write(const struct priv *priv, const char *entry,
c7ffa4
-		 char *buf, size_t size)
c7ffa4
-{
c7ffa4
-	char ifname[IF_NAMESIZE];
c7ffa4
-	FILE *file;
c7ffa4
-	int ret;
c7ffa4
-
c7ffa4
-	ret = mlx4_get_ifname(priv, &ifname);
c7ffa4
-	if (ret)
c7ffa4
-		return ret;
c7ffa4
-
c7ffa4
-	MKSTR(path, "%s/device/net/%s/%s", priv->ctx->device->ibdev_path,
c7ffa4
-	      ifname, entry);
c7ffa4
-
c7ffa4
-	file = fopen(path, "wb");
c7ffa4
-	if (file == NULL) {
c7ffa4
-		rte_errno = errno;
c7ffa4
-		return -rte_errno;
c7ffa4
-	}
c7ffa4
-	ret = fwrite(buf, 1, size, file);
c7ffa4
-	if ((size_t)ret < size || ferror(file)) {
c7ffa4
-		rte_errno = EIO;
c7ffa4
-		ret = -rte_errno;
c7ffa4
-	} else {
c7ffa4
-		ret = size;
c7ffa4
-	}
c7ffa4
-	fclose(file);
c7ffa4
-	return ret;
c7ffa4
-}
c7ffa4
-
c7ffa4
-/**
c7ffa4
- * Get unsigned long sysfs property.
c7ffa4
- *
c7ffa4
- * @param priv
c7ffa4
- *   Pointer to private structure.
c7ffa4
- * @param[in] name
c7ffa4
- *   Entry name relative to sysfs path.
c7ffa4
- * @param[out] value
c7ffa4
- *   Value output buffer.
c7ffa4
- *
c7ffa4
- * @return
c7ffa4
- *   0 on success, negative errno value otherwise and rte_errno is set.
c7ffa4
- */
c7ffa4
-static int
c7ffa4
-mlx4_get_sysfs_ulong(struct priv *priv, const char *name, unsigned long *value)
c7ffa4
-{
c7ffa4
-	int ret;
c7ffa4
-	unsigned long value_ret;
c7ffa4
-	char value_str[32];
c7ffa4
-
c7ffa4
-	ret = mlx4_sysfs_read(priv, name, value_str, (sizeof(value_str) - 1));
c7ffa4
-	if (ret < 0) {
c7ffa4
-		DEBUG("cannot read %s value from sysfs: %s",
c7ffa4
-		      name, strerror(rte_errno));
c7ffa4
-		return ret;
c7ffa4
-	}
c7ffa4
-	value_str[ret] = '\0';
c7ffa4
-	errno = 0;
c7ffa4
-	value_ret = strtoul(value_str, NULL, 0);
c7ffa4
-	if (errno) {
c7ffa4
-		rte_errno = errno;
c7ffa4
-		DEBUG("invalid %s value `%s': %s", name, value_str,
c7ffa4
-		      strerror(rte_errno));
c7ffa4
-		return -rte_errno;
c7ffa4
-	}
c7ffa4
-	*value = value_ret;
c7ffa4
-	return 0;
c7ffa4
-}
c7ffa4
-
c7ffa4
-/**
c7ffa4
- * Set unsigned long sysfs property.
c7ffa4
- *
c7ffa4
- * @param priv
c7ffa4
- *   Pointer to private structure.
c7ffa4
- * @param[in] name
c7ffa4
- *   Entry name relative to sysfs path.
c7ffa4
- * @param value
c7ffa4
- *   Value to set.
c7ffa4
- *
c7ffa4
- * @return
c7ffa4
- *   0 on success, negative errno value otherwise and rte_errno is set.
c7ffa4
- */
c7ffa4
-static int
c7ffa4
-mlx4_set_sysfs_ulong(struct priv *priv, const char *name, unsigned long value)
c7ffa4
-{
c7ffa4
-	int ret;
c7ffa4
-	MKSTR(value_str, "%lu", value);
c7ffa4
-
c7ffa4
-	ret = mlx4_sysfs_write(priv, name, value_str, (sizeof(value_str) - 1));
c7ffa4
-	if (ret < 0) {
c7ffa4
-		DEBUG("cannot write %s `%s' (%lu) to sysfs: %s",
c7ffa4
-		      name, value_str, value, strerror(rte_errno));
c7ffa4
-		return ret;
c7ffa4
-	}
c7ffa4
-	return 0;
c7ffa4
-}
c7ffa4
-
c7ffa4
-/**
c7ffa4
  * Perform ifreq ioctl() on associated Ethernet device.
c7ffa4
  *
c7ffa4
  * @param[in] priv
c7ffa4
@@ -389,12 +228,12 @@
c7ffa4
 int
c7ffa4
 mlx4_mtu_get(struct priv *priv, uint16_t *mtu)
c7ffa4
 {
c7ffa4
-	unsigned long ulong_mtu = 0;
c7ffa4
-	int ret = mlx4_get_sysfs_ulong(priv, "mtu", &ulong_mtu);
c7ffa4
+	struct ifreq request;
c7ffa4
+	int ret = mlx4_ifreq(priv, SIOCGIFMTU, &request);
c7ffa4
 
c7ffa4
 	if (ret)
c7ffa4
 		return ret;
c7ffa4
-	*mtu = ulong_mtu;
c7ffa4
+	*mtu = request.ifr_mtu;
c7ffa4
 	return 0;
c7ffa4
 }
c7ffa4
 
c7ffa4
@@ -413,20 +252,13 @@
c7ffa4
 mlx4_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
c7ffa4
 {
c7ffa4
 	struct priv *priv = dev->data->dev_private;
c7ffa4
-	uint16_t new_mtu;
c7ffa4
-	int ret = mlx4_set_sysfs_ulong(priv, "mtu", mtu);
c7ffa4
+	struct ifreq request = { .ifr_mtu = mtu, };
c7ffa4
+	int ret = mlx4_ifreq(priv, SIOCSIFMTU, &request);
c7ffa4
 
c7ffa4
 	if (ret)
c7ffa4
 		return ret;
c7ffa4
-	ret = mlx4_mtu_get(priv, &new_mtu);
c7ffa4
-	if (ret)
c7ffa4
-		return ret;
c7ffa4
-	if (new_mtu == mtu) {
c7ffa4
-		priv->mtu = mtu;
c7ffa4
-		return 0;
c7ffa4
-	}
c7ffa4
-	rte_errno = EINVAL;
c7ffa4
-	return -rte_errno;
c7ffa4
+	priv->mtu = mtu;
c7ffa4
+	return 0;
c7ffa4
 }
c7ffa4
 
c7ffa4
 /**
c7ffa4
@@ -445,14 +277,14 @@
c7ffa4
 static int
c7ffa4
 mlx4_set_flags(struct priv *priv, unsigned int keep, unsigned int flags)
c7ffa4
 {
c7ffa4
-	unsigned long tmp = 0;
c7ffa4
-	int ret = mlx4_get_sysfs_ulong(priv, "flags", &tmp);
c7ffa4
+	struct ifreq request;
c7ffa4
+	int ret = mlx4_ifreq(priv, SIOCGIFFLAGS, &request);
c7ffa4
 
c7ffa4
 	if (ret)
c7ffa4
 		return ret;
c7ffa4
-	tmp &= keep;
c7ffa4
-	tmp |= (flags & (~keep));
c7ffa4
-	return mlx4_set_sysfs_ulong(priv, "flags", tmp);
c7ffa4
+	request.ifr_flags &= keep;
c7ffa4
+	request.ifr_flags |= flags & ~keep;
c7ffa4
+	return mlx4_ifreq(priv, SIOCSIFFLAGS, &request);
c7ffa4
 }
c7ffa4
 
c7ffa4
 /**
c7ffa4
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
c7ffa4
index e6a69b8..a34121c 100644
c7ffa4
--- a/drivers/net/mlx5/mlx5.h
c7ffa4
+++ b/drivers/net/mlx5/mlx5.h
c7ffa4
@@ -186,8 +186,6 @@ struct priv {
c7ffa4
 int mlx5_is_secondary(void);
c7ffa4
 int priv_get_ifname(const struct priv *, char (*)[IF_NAMESIZE]);
c7ffa4
 int priv_ifreq(const struct priv *, int req, struct ifreq *);
c7ffa4
-int priv_is_ib_cntr(const char *);
c7ffa4
-int priv_get_cntr_sysfs(struct priv *, const char *, uint64_t *);
c7ffa4
 int priv_get_num_vfs(struct priv *, uint16_t *);
c7ffa4
 int priv_get_mtu(struct priv *, uint16_t *);
c7ffa4
 int priv_set_flags(struct priv *, unsigned int, unsigned int);
c7ffa4
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
c7ffa4
index 5620cce..4dffa4f 100644
c7ffa4
--- a/drivers/net/mlx5/mlx5_ethdev.c
c7ffa4
+++ b/drivers/net/mlx5/mlx5_ethdev.c
c7ffa4
@@ -35,6 +35,7 @@
c7ffa4
 
c7ffa4
 #include <stddef.h>
c7ffa4
 #include <assert.h>
c7ffa4
+#include <inttypes.h>
c7ffa4
 #include <unistd.h>
c7ffa4
 #include <stdint.h>
c7ffa4
 #include <stdio.h>
c7ffa4
@@ -228,181 +229,6 @@ struct priv *
c7ffa4
 }
c7ffa4
 
c7ffa4
 /**
c7ffa4
- * Check if the counter is located on ib counters file.
c7ffa4
- *
c7ffa4
- * @param[in] cntr
c7ffa4
- *   Counter name.
c7ffa4
- *
c7ffa4
- * @return
c7ffa4
- *   1 if counter is located on ib counters file , 0 otherwise.
c7ffa4
- */
c7ffa4
-int
c7ffa4
-priv_is_ib_cntr(const char *cntr)
c7ffa4
-{
c7ffa4
-	if (!strcmp(cntr, "out_of_buffer"))
c7ffa4
-		return 1;
c7ffa4
-	return 0;
c7ffa4
-}
c7ffa4
-
c7ffa4
-/**
c7ffa4
- * Read from sysfs entry.
c7ffa4
- *
c7ffa4
- * @param[in] priv
c7ffa4
- *   Pointer to private structure.
c7ffa4
- * @param[in] entry
c7ffa4
- *   Entry name relative to sysfs path.
c7ffa4
- * @param[out] buf
c7ffa4
- *   Data output buffer.
c7ffa4
- * @param size
c7ffa4
- *   Buffer size.
c7ffa4
- *
c7ffa4
- * @return
c7ffa4
- *   0 on success, -1 on failure and errno is set.
c7ffa4
- */
c7ffa4
-static int
c7ffa4
-priv_sysfs_read(const struct priv *priv, const char *entry,
c7ffa4
-		char *buf, size_t size)
c7ffa4
-{
c7ffa4
-	char ifname[IF_NAMESIZE];
c7ffa4
-	FILE *file;
c7ffa4
-	int ret;
c7ffa4
-	int err;
c7ffa4
-
c7ffa4
-	if (priv_get_ifname(priv, &ifname))
c7ffa4
-		return -1;
c7ffa4
-
c7ffa4
-	if (priv_is_ib_cntr(entry)) {
c7ffa4
-		MKSTR(path, "%s/ports/1/hw_counters/%s",
c7ffa4
-		      priv->ibdev_path, entry);
c7ffa4
-		file = fopen(path, "rb");
c7ffa4
-	} else {
c7ffa4
-		MKSTR(path, "%s/device/net/%s/%s",
c7ffa4
-		      priv->ibdev_path, ifname, entry);
c7ffa4
-		file = fopen(path, "rb");
c7ffa4
-	}
c7ffa4
-	if (file == NULL)
c7ffa4
-		return -1;
c7ffa4
-	ret = fread(buf, 1, size, file);
c7ffa4
-	err = errno;
c7ffa4
-	if (((size_t)ret < size) && (ferror(file)))
c7ffa4
-		ret = -1;
c7ffa4
-	else
c7ffa4
-		ret = size;
c7ffa4
-	fclose(file);
c7ffa4
-	errno = err;
c7ffa4
-	return ret;
c7ffa4
-}
c7ffa4
-
c7ffa4
-/**
c7ffa4
- * Write to sysfs entry.
c7ffa4
- *
c7ffa4
- * @param[in] priv
c7ffa4
- *   Pointer to private structure.
c7ffa4
- * @param[in] entry
c7ffa4
- *   Entry name relative to sysfs path.
c7ffa4
- * @param[in] buf
c7ffa4
- *   Data buffer.
c7ffa4
- * @param size
c7ffa4
- *   Buffer size.
c7ffa4
- *
c7ffa4
- * @return
c7ffa4
- *   0 on success, -1 on failure and errno is set.
c7ffa4
- */
c7ffa4
-static int
c7ffa4
-priv_sysfs_write(const struct priv *priv, const char *entry,
c7ffa4
-		 char *buf, size_t size)
c7ffa4
-{
c7ffa4
-	char ifname[IF_NAMESIZE];
c7ffa4
-	FILE *file;
c7ffa4
-	int ret;
c7ffa4
-	int err;
c7ffa4
-
c7ffa4
-	if (priv_get_ifname(priv, &ifname))
c7ffa4
-		return -1;
c7ffa4
-
c7ffa4
-	MKSTR(path, "%s/device/net/%s/%s", priv->ibdev_path, ifname, entry);
c7ffa4
-
c7ffa4
-	file = fopen(path, "wb");
c7ffa4
-	if (file == NULL)
c7ffa4
-		return -1;
c7ffa4
-	ret = fwrite(buf, 1, size, file);
c7ffa4
-	err = errno;
c7ffa4
-	if (((size_t)ret < size) || (ferror(file)))
c7ffa4
-		ret = -1;
c7ffa4
-	else
c7ffa4
-		ret = size;
c7ffa4
-	fclose(file);
c7ffa4
-	errno = err;
c7ffa4
-	return ret;
c7ffa4
-}
c7ffa4
-
c7ffa4
-/**
c7ffa4
- * Get unsigned long sysfs property.
c7ffa4
- *
c7ffa4
- * @param priv
c7ffa4
- *   Pointer to private structure.
c7ffa4
- * @param[in] name
c7ffa4
- *   Entry name relative to sysfs path.
c7ffa4
- * @param[out] value
c7ffa4
- *   Value output buffer.
c7ffa4
- *
c7ffa4
- * @return
c7ffa4
- *   0 on success, -1 on failure and errno is set.
c7ffa4
- */
c7ffa4
-static int
c7ffa4
-priv_get_sysfs_ulong(struct priv *priv, const char *name, unsigned long *value)
c7ffa4
-{
c7ffa4
-	int ret;
c7ffa4
-	unsigned long value_ret;
c7ffa4
-	char value_str[32];
c7ffa4
-
c7ffa4
-	ret = priv_sysfs_read(priv, name, value_str, (sizeof(value_str) - 1));
c7ffa4
-	if (ret == -1) {
c7ffa4
-		DEBUG("cannot read %s value from sysfs: %s",
c7ffa4
-		      name, strerror(errno));
c7ffa4
-		return -1;
c7ffa4
-	}
c7ffa4
-	value_str[ret] = '\0';
c7ffa4
-	errno = 0;
c7ffa4
-	value_ret = strtoul(value_str, NULL, 0);
c7ffa4
-	if (errno) {
c7ffa4
-		DEBUG("invalid %s value `%s': %s", name, value_str,
c7ffa4
-		      strerror(errno));
c7ffa4
-		return -1;
c7ffa4
-	}
c7ffa4
-	*value = value_ret;
c7ffa4
-	return 0;
c7ffa4
-}
c7ffa4
-
c7ffa4
-/**
c7ffa4
- * Set unsigned long sysfs property.
c7ffa4
- *
c7ffa4
- * @param priv
c7ffa4
- *   Pointer to private structure.
c7ffa4
- * @param[in] name
c7ffa4
- *   Entry name relative to sysfs path.
c7ffa4
- * @param value
c7ffa4
- *   Value to set.
c7ffa4
- *
c7ffa4
- * @return
c7ffa4
- *   0 on success, -1 on failure and errno is set.
c7ffa4
- */
c7ffa4
-static int
c7ffa4
-priv_set_sysfs_ulong(struct priv *priv, const char *name, unsigned long value)
c7ffa4
-{
c7ffa4
-	int ret;
c7ffa4
-	MKSTR(value_str, "%lu", value);
c7ffa4
-
c7ffa4
-	ret = priv_sysfs_write(priv, name, value_str, (sizeof(value_str) - 1));
c7ffa4
-	if (ret == -1) {
c7ffa4
-		DEBUG("cannot write %s `%s' (%lu) to sysfs: %s",
c7ffa4
-		      name, value_str, value, strerror(errno));
c7ffa4
-		return -1;
c7ffa4
-	}
c7ffa4
-	return 0;
c7ffa4
-}
c7ffa4
-
c7ffa4
-/**
c7ffa4
  * Perform ifreq ioctl() on associated Ethernet device.
c7ffa4
  *
c7ffa4
  * @param[in] priv
c7ffa4
@@ -445,20 +271,25 @@ struct priv *
c7ffa4
 {
c7ffa4
 	/* The sysfs entry name depends on the operating system. */
c7ffa4
 	const char **name = (const char *[]){
c7ffa4
-		"device/sriov_numvfs",
c7ffa4
-		"device/mlx5_num_vfs",
c7ffa4
+		"sriov_numvfs",
c7ffa4
+		"mlx5_num_vfs",
c7ffa4
 		NULL,
c7ffa4
 	};
c7ffa4
-	int ret;
c7ffa4
 
c7ffa4
 	do {
c7ffa4
-		unsigned long ulong_num_vfs;
c7ffa4
+		int n;
c7ffa4
+		FILE *file;
c7ffa4
+		MKSTR(path, "%s/device/%s", priv->ibdev_path, *name);
c7ffa4
 
c7ffa4
-		ret = priv_get_sysfs_ulong(priv, *name, &ulong_num_vfs);
c7ffa4
-		if (!ret)
c7ffa4
-			*num_vfs = ulong_num_vfs;
c7ffa4
-	} while (*(++name) && ret);
c7ffa4
-	return ret;
c7ffa4
+		file = fopen(path, "rb");
c7ffa4
+		if (!file)
c7ffa4
+			continue;
c7ffa4
+		n = fscanf(file, "%" SCNu16, num_vfs);
c7ffa4
+		fclose(file);
c7ffa4
+		if (n == 1)
c7ffa4
+			return 0;
c7ffa4
+	} while (*(++name));
c7ffa4
+	return -1;
c7ffa4
 }
c7ffa4
 
c7ffa4
 /**
c7ffa4
@@ -475,35 +306,12 @@ struct priv *
c7ffa4
 int
c7ffa4
 priv_get_mtu(struct priv *priv, uint16_t *mtu)
c7ffa4
 {
c7ffa4
-	unsigned long ulong_mtu;
c7ffa4
+	struct ifreq request;
c7ffa4
+	int ret = priv_ifreq(priv, SIOCGIFMTU, &request);
c7ffa4
 
c7ffa4
-	if (priv_get_sysfs_ulong(priv, "mtu", &ulong_mtu) == -1)
c7ffa4
-		return -1;
c7ffa4
-	*mtu = ulong_mtu;
c7ffa4
-	return 0;
c7ffa4
-}
c7ffa4
-
c7ffa4
-/**
c7ffa4
- * Read device counter from sysfs.
c7ffa4
- *
c7ffa4
- * @param priv
c7ffa4
- *   Pointer to private structure.
c7ffa4
- * @param name
c7ffa4
- *   Counter name.
c7ffa4
- * @param[out] cntr
c7ffa4
- *   Counter output buffer.
c7ffa4
- *
c7ffa4
- * @return
c7ffa4
- *   0 on success, -1 on failure and errno is set.
c7ffa4
- */
c7ffa4
-int
c7ffa4
-priv_get_cntr_sysfs(struct priv *priv, const char *name, uint64_t *cntr)
c7ffa4
-{
c7ffa4
-	unsigned long ulong_ctr;
c7ffa4
-
c7ffa4
-	if (priv_get_sysfs_ulong(priv, name, &ulong_ctr) == -1)
c7ffa4
-		return -1;
c7ffa4
-	*cntr = ulong_ctr;
c7ffa4
+	if (ret)
c7ffa4
+		return ret;
c7ffa4
+	*mtu = request.ifr_mtu;
c7ffa4
 	return 0;
c7ffa4
 }
c7ffa4
 
c7ffa4
@@ -521,15 +329,9 @@ struct priv *
c7ffa4
 static int
c7ffa4
 priv_set_mtu(struct priv *priv, uint16_t mtu)
c7ffa4
 {
c7ffa4
-	uint16_t new_mtu;
c7ffa4
+	struct ifreq request = { .ifr_mtu = mtu, };
c7ffa4
 
c7ffa4
-	if (priv_set_sysfs_ulong(priv, "mtu", mtu) ||
c7ffa4
-	    priv_get_mtu(priv, &new_mtu))
c7ffa4
-		return -1;
c7ffa4
-	if (new_mtu == mtu)
c7ffa4
-		return 0;
c7ffa4
-	errno = EINVAL;
c7ffa4
-	return -1;
c7ffa4
+	return priv_ifreq(priv, SIOCSIFMTU, &request);
c7ffa4
 }
c7ffa4
 
c7ffa4
 /**
c7ffa4
@@ -548,13 +350,14 @@ struct priv *
c7ffa4
 int
c7ffa4
 priv_set_flags(struct priv *priv, unsigned int keep, unsigned int flags)
c7ffa4
 {
c7ffa4
-	unsigned long tmp;
c7ffa4
+	struct ifreq request;
c7ffa4
+	int ret = priv_ifreq(priv, SIOCGIFFLAGS, &request);
c7ffa4
 
c7ffa4
-	if (priv_get_sysfs_ulong(priv, "flags", &tmp) == -1)
c7ffa4
-		return -1;
c7ffa4
-	tmp &= keep;
c7ffa4
-	tmp |= (flags & (~keep));
c7ffa4
-	return priv_set_sysfs_ulong(priv, "flags", tmp);
c7ffa4
+	if (ret)
c7ffa4
+		return ret;
c7ffa4
+	request.ifr_flags &= keep;
c7ffa4
+	request.ifr_flags |= flags & ~keep;
c7ffa4
+	return priv_ifreq(priv, SIOCSIFFLAGS, &request);
c7ffa4
 }
c7ffa4
 
c7ffa4
 /**
c7ffa4
diff --git a/drivers/net/mlx5/mlx5_stats.c b/drivers/net/mlx5/mlx5_stats.c
c7ffa4
index 5e225d3..48422cc 100644
c7ffa4
--- a/drivers/net/mlx5/mlx5_stats.c
c7ffa4
+++ b/drivers/net/mlx5/mlx5_stats.c
c7ffa4
@@ -31,8 +31,11 @@
c7ffa4
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
c7ffa4
  */
c7ffa4
 
c7ffa4
+#include <inttypes.h>
c7ffa4
 #include <linux/sockios.h>
c7ffa4
 #include <linux/ethtool.h>
c7ffa4
+#include <stdint.h>
c7ffa4
+#include <stdio.h>
c7ffa4
 
c7ffa4
 #include <rte_ethdev.h>
c7ffa4
 #include <rte_common.h>
c7ffa4
@@ -47,6 +50,7 @@ struct mlx5_counter_ctrl {
c7ffa4
 	char dpdk_name[RTE_ETH_XSTATS_NAME_SIZE];
c7ffa4
 	/* Name of the counter on the device table. */
c7ffa4
 	char ctr_name[RTE_ETH_XSTATS_NAME_SIZE];
c7ffa4
+	uint32_t ib:1; /**< Nonzero for IB counters. */
c7ffa4
 };
c7ffa4
 
c7ffa4
 static const struct mlx5_counter_ctrl mlx5_counters_init[] = {
c7ffa4
@@ -121,6 +125,7 @@ struct mlx5_counter_ctrl {
c7ffa4
 	{
c7ffa4
 		.dpdk_name = "rx_out_of_buffer",
c7ffa4
 		.ctr_name = "out_of_buffer",
c7ffa4
+		.ib = 1,
c7ffa4
 	},
c7ffa4
 };
c7ffa4
 
c7ffa4
@@ -157,13 +162,24 @@ struct mlx5_counter_ctrl {
c7ffa4
 		return -1;
c7ffa4
 	}
c7ffa4
 	for (i = 0; i != xstats_n; ++i) {
c7ffa4
-		if (priv_is_ib_cntr(mlx5_counters_init[i].ctr_name))
c7ffa4
-			priv_get_cntr_sysfs(priv,
c7ffa4
-					    mlx5_counters_init[i].ctr_name,
c7ffa4
-					    &stats[i]);
c7ffa4
-		else
c7ffa4
+		if (mlx5_counters_init[i].ib) {
c7ffa4
+			FILE *file;
c7ffa4
+			MKSTR(path, "%s/ports/1/hw_counters/%s",
c7ffa4
+			      priv->ibdev_path,
c7ffa4
+			      mlx5_counters_init[i].ctr_name);
c7ffa4
+
c7ffa4
+			file = fopen(path, "rb");
c7ffa4
+			if (file) {
c7ffa4
+				int n = fscanf(file, "%" SCNu64, &stats[i]);
c7ffa4
+
c7ffa4
+				fclose(file);
c7ffa4
+				if (n != 1)
c7ffa4
+					stats[i] = 0;
c7ffa4
+			}
c7ffa4
+		} else {
c7ffa4
 			stats[i] = (uint64_t)
c7ffa4
 				et_stats->data[xstats_ctrl->dev_table_idx[i]];
c7ffa4
+		}
c7ffa4
 	}
c7ffa4
 	return 0;
c7ffa4
 }
c7ffa4
@@ -246,7 +262,7 @@ struct mlx5_counter_ctrl {
c7ffa4
 		}
c7ffa4
 	}
c7ffa4
 	for (j = 0; j != xstats_n; ++j) {
c7ffa4
-		if (priv_is_ib_cntr(mlx5_counters_init[j].ctr_name))
c7ffa4
+		if (mlx5_counters_init[j].ib)
c7ffa4
 			continue;
c7ffa4
 		if (xstats_ctrl->dev_table_idx[j] >= dev_stats_n) {
c7ffa4
 			WARN("counter \"%s\" is not recognized",
c7ffa4
-- 
c7ffa4
1.8.3.1
c7ffa4