[Skiboot] [PATCH] Add -Tn to ibm,loc-code for ethernet adaptors

Daniel Axtens dja at axtens.net
Fri May 15 08:51:08 AEST 2015


On pHyp, the location code of ethernet adaptors ends with -Tn, where n
is the port number on the card. Detect if an adaptor advertises itself
as ethernet based on it's PCI class code, and if it does, give each
PCI function a -Tn suffix, where n = function number + 1. (Therefore n
is between 1 and 8 inclusive)

This is a reasonably non-invasive change to match pHyp
behaviour. Alternatives considered were:

 - putting this in kernel space, which requires messing with the
   device tree, which is frowned upon.
 
 - putting this in user space, which requires patching every userspace
   tool that might consume this data, of which there are several.

As such, while it's a bit of a hack, this is the best place for it.

Signed-off-by: Daniel Axtens <dja at axtens.net>
---
 core/pci.c | 34 +++++++++++++++++++++++++++++++---
 1 file changed, 31 insertions(+), 3 deletions(-)

diff --git a/core/pci.c b/core/pci.c
index 8ea9177..477f806 100644
--- a/core/pci.c
+++ b/core/pci.c
@@ -1145,10 +1145,14 @@ static void pci_add_slot_properties(struct phb *phb, struct pci_slot_info *info,
 	dt_add_property_string(np, "ibm,slot-label", info->label);
 }
 
-static void pci_add_loc_code(struct dt_node *np)
+static void pci_add_loc_code(struct dt_node *np, struct pci_device *pd)
 {
 	struct dt_node *p = np->parent;
 	const char *blcode = NULL;
+	char *lcode;
+	uint32_t class_code;
+	uint8_t class, sub;
+	uint8_t pos, len;
 
 	/* Look for a parent with a slot-location-code */
 	while (p && !blcode) {
@@ -1157,7 +1161,31 @@ static void pci_add_loc_code(struct dt_node *np)
 	}
 	if (!blcode)
 		return;
-	dt_add_property_string(np, "ibm,loc-code", blcode);
+
+	/* ethernet devices get port codes */
+	class_code = dt_prop_get_u32(np, "class-code");
+	class = class_code >> 16;
+	sub = (class_code >> 8) & 0xff;
+	if (class == 0x02 && sub == 0x00) {
+		/* There's usually several spaces at the end of the property.
+		   Test for, but don't rely on, that being the case */
+		len = strlen(blcode);
+		for (pos = 0; pos < len; pos++)
+			if (blcode[pos] == ' ') break;
+		if (pos + 3 < len)
+			lcode = strdup(blcode);
+		else {
+			lcode = malloc(pos + 3);
+			memcpy(lcode, blcode, len);
+		}
+		lcode[pos++] = '-';
+		lcode[pos++] = 'T';
+		lcode[pos++] = (char)(pd->bdfn & 0x7) + '1';
+		lcode[pos++] = '\0';
+		dt_add_property_string(np, "ibm,loc-code", lcode);
+		free(lcode);
+	} else
+		dt_add_property_string(np, "ibm,loc-code", blcode);
 }
 
 static void pci_print_summary_line(struct phb *phb, struct pci_device *pd,
@@ -1288,7 +1316,7 @@ static void pci_add_one_node(struct phb *phb, struct pci_device *pd,
 		pci_add_slot_properties(phb, pd->slot_info, np);
 
 	/* Make up location code */
-	pci_add_loc_code(np);
+	pci_add_loc_code(np, pd);
 
 	/* XXX FIXME: We don't look for BARs, we only put the config space
 	 * entry in the "reg" property. That's enough for Linux and we might
-- 
2.1.4



More information about the Skiboot mailing list