Blame SOURCES/0003-Netronome-biosdevname-support-8.patch

36e89a
From 8f2d9991d50e09ba9af842fb592b37d0c2021a06 Mon Sep 17 00:00:00 2001
36e89a
From: dirkjacobus <dirkjacobus@gmail.com>
36e89a
Date: Sun, 11 Nov 2018 23:29:24 -0800
36e89a
Subject: [PATCH] Netronome biosdevname support (#8)
36e89a
36e89a
* Add support for Netronome netdevices
36e89a
36e89a
Netronome netdevices also provide multiple ports through the same
36e89a
function.
36e89a
36e89a
* Set devID with phys_port_name index for nfp devices
36e89a
36e89a
Netronome netdevices should rather use the index from the phys_port_name
36e89a
attribute instead of the dev_port/dev_id
36e89a
attributes.
36e89a
36e89a
* Exclude naming Netronome logical devices
36e89a
36e89a
Some drivers, like the Netronome nfp driver, expose logical devices such
36e89a
as representors and switchdev uplink devices.
36e89a
36e89a
There isn't currently a naming scheme for such devices, so exclude them
36e89a
from the biosdevname naming policy.
36e89a
36e89a
Split ports also don't have a naming scheme defined for biosdevname, so
36e89a
its better to exclude them from naming.
36e89a
36e89a
Identification of such devices will always be driver dependent.
36e89a
At the moment, only 'nfp' driver devices are considered for exclusion.
36e89a
---
36e89a
 src/bios_device.c |  6 ++++-
36e89a
 src/eths.c        | 65 ++++++++++++++++++++++++++++++++++++++++-------
36e89a
 src/eths.h        |  6 +++++
36e89a
 3 files changed, 67 insertions(+), 10 deletions(-)
36e89a
36e89a
diff --git a/src/bios_device.c b/src/bios_device.c
36e89a
index 3cc528b..4882513 100644
36e89a
--- a/src/bios_device.c
36e89a
+++ b/src/bios_device.c
36e89a
@@ -214,7 +214,7 @@ static void sort_device_list(struct libbiosdevname_state *state)
36e89a
 	list_splice(&sorted_devices, &state->bios_devices);
36e89a
 }
36e89a
 
36e89a
-/* Check for Mellanox/Chelsio drivers */
36e89a
+/* Check for multiport drivers */
36e89a
 int ismultiport(const char *driver)
36e89a
 {
36e89a
 	if (!strncmp(driver, "mlx4", 4))
36e89a
@@ -223,6 +223,8 @@ int ismultiport(const char *driver)
36e89a
 		return 1;
36e89a
 	if (!strncmp(driver, "exanic", 6))
36e89a
 		return 1;
36e89a
+	if (!strncmp(driver, "nfp", 3))
36e89a
+		return 1;
36e89a
 	return 0;
36e89a
 }
36e89a
 
36e89a
@@ -248,6 +250,8 @@ static void match_pci_and_eth_devs(struct libbiosdevname_state *state)
36e89a
 			/* Ignore if devtype is fcoe */
36e89a
 			if (netdev_devtype_is_fcoe(n))
36e89a
 				continue;
36e89a
+			if (!netdev_is_eligible(n))
36e89a
+				continue;
36e89a
 			b = malloc(sizeof(*b));
36e89a
 			if (!b)
36e89a
 				continue;
36e89a
diff --git a/src/eths.c b/src/eths.c
36e89a
index d2c4d36..688c3af 100644
36e89a
--- a/src/eths.c
36e89a
+++ b/src/eths.c
36e89a
@@ -35,21 +35,67 @@ char *pr_ether(char *buf, const int size, const unsigned char *s)
36e89a
 	return (buf);
36e89a
 }
36e89a
 
36e89a
-static void eths_get_devid(const char *devname, int *devid)
36e89a
+static int eths_get_phys_port_name_id(const char *devname)
36e89a
+{
36e89a
+	char *portstr = NULL;
36e89a
+	char path[PATH_MAX];
36e89a
+	int index = -1;
36e89a
+
36e89a
+	/* Only devices that have a phys_port_name of 'pX' are considered here,
36e89a
+	 * with the index 'X' extracted.
36e89a
+	 */
36e89a
+	snprintf(path, sizeof(path), "/sys/class/net/%s/phys_port_name", devname);
36e89a
+	if (sysfs_read_file(path, &portstr) == 0) {
36e89a
+		char *res = NULL;
36e89a
+
36e89a
+		if (portstr[0] == 'p') {
36e89a
+			index = strtol(&portstr[1], &res, 10);
36e89a
+			/* Reset to invalid if the format is unexpected. */
36e89a
+			if (*res)
36e89a
+				index = -1;
36e89a
+		}
36e89a
+
36e89a
+		free(portstr);
36e89a
+	}
36e89a
+
36e89a
+	return index;
36e89a
+}
36e89a
+
36e89a
+static void eths_get_dev_eligible(struct network_device *dev)
36e89a
+{
36e89a
+	/* By default, all network devices are eligible for naming. Some may
36e89a
+	 * opt-out explicitly below.
36e89a
+	 */
36e89a
+	dev->is_eligible = 1;
36e89a
+
36e89a
+	if (dev->drvinfo_valid && strcmp(dev->drvinfo.driver, "nfp") == 0) {
36e89a
+		dev->is_eligible = (eths_get_phys_port_name_id(dev->kernel_name) >= 0 ? 1 : 0);
36e89a
+	}
36e89a
+}
36e89a
+
36e89a
+static void eths_get_devid(struct network_device *dev)
36e89a
 {
36e89a
 	char path[PATH_MAX];
36e89a
 	char *devidstr = NULL;
36e89a
 
36e89a
-	*devid = -1;
36e89a
-	snprintf(path, sizeof(path), "/sys/class/net/%s/dev_port", devname);
36e89a
-	if (sysfs_read_file(path, &devidstr) == 0) {
36e89a
-		sscanf(devidstr, "%i", devid);
36e89a
-		free(devidstr);
36e89a
+	dev->devid = -1;
36e89a
+
36e89a
+	/* For some drivers, the phys_port_name index, e.g. pX, is the correct
36e89a
+	 * dev ID to use instead of the dev_port attribute.
36e89a
+	 */
36e89a
+	if (dev->drvinfo_valid && strcmp(dev->drvinfo.driver, "nfp") == 0) {
36e89a
+		dev->devid = eths_get_phys_port_name_id(dev->kernel_name);
36e89a
 	} else {
36e89a
-		snprintf(path, sizeof(path), "/sys/class/net/%s/dev_id", devname);
36e89a
+		snprintf(path, sizeof(path), "/sys/class/net/%s/dev_port", dev->kernel_name);
36e89a
 		if (sysfs_read_file(path, &devidstr) == 0) {
36e89a
-			sscanf(devidstr, "%i", devid);
36e89a
+			sscanf(devidstr, "%i", &dev->devid);
36e89a
 			free(devidstr);
36e89a
+		} else {
36e89a
+			snprintf(path, sizeof(path), "/sys/class/net/%s/dev_id", dev->kernel_name);
36e89a
+			if (sysfs_read_file(path, &devidstr) == 0) {
36e89a
+				sscanf(devidstr, "%i", &dev->devid);
36e89a
+				free(devidstr);
36e89a
+			}
36e89a
 		}
36e89a
 	}
36e89a
 }
36e89a
@@ -224,13 +270,14 @@ static void fill_eth_dev(struct network_device *dev)
36e89a
 	eths_get_ifindex(dev->kernel_name, &dev->ifindex);
36e89a
 	eths_get_hwaddr(dev->kernel_name, dev->dev_addr, sizeof(dev->dev_addr), &dev->arphrd_type);
36e89a
 	eths_get_permaddr(dev->kernel_name, dev->perm_addr, sizeof(dev->perm_addr));
36e89a
-	eths_get_devid(dev->kernel_name, &dev->devid);
36e89a
 	devtype = eths_get_devtype(dev);
36e89a
 	if (devtype > 0)
36e89a
 		dev->devtype_is_fcoe = 1;
36e89a
 	rc = eths_get_info(dev->kernel_name, &dev->drvinfo);
36e89a
 	if (rc == 0)
36e89a
 		dev->drvinfo_valid = 1;
36e89a
+	eths_get_devid(dev);
36e89a
+	eths_get_dev_eligible(dev);
36e89a
 }
36e89a
 
36e89a
 void free_eths(struct libbiosdevname_state *state)
36e89a
diff --git a/src/eths.h b/src/eths.h
36e89a
index b695d3d..49e399d 100644
36e89a
--- a/src/eths.h
36e89a
+++ b/src/eths.h
36e89a
@@ -30,6 +30,7 @@ struct network_device {
36e89a
 	int devid;
36e89a
 	int devtype_is_fcoe;
36e89a
 	char *devtype;
36e89a
+	int is_eligible:1; /* not eligible for naming when 0 */
36e89a
 };
36e89a
 
36e89a
 extern void get_eths(struct libbiosdevname_state *state);
36e89a
@@ -68,4 +69,9 @@ static inline int netdev_arphrd_type_is_eth(const struct network_device *dev)
36e89a
         return (dev->arphrd_type == ARPHRD_ETHER);
36e89a
 }
36e89a
 
36e89a
+static inline int netdev_is_eligible(const struct network_device *dev)
36e89a
+{
36e89a
+	return (!!dev->is_eligible);
36e89a
+}
36e89a
+
36e89a
 #endif /* __ETHS_H_INCLUDED */
36e89a
-- 
36e89a
2.17.2
36e89a