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

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