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

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