Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 18 Oct 2016 23:27:50 +0000 (UTC)
From:      Oleksandr Tymoshenko <gonzo@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r307585 - stable/11/sys/dev/usb/net
Message-ID:  <201610182327.u9INRovA037341@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gonzo
Date: Tue Oct 18 23:27:50 2016
New Revision: 307585
URL: https://svnweb.freebsd.org/changeset/base/307585

Log:
  MFC r307154:
  
  [fdt] Add one more heuristic to determine MAC address of the SMSC device
  
  - If check for net,ethernet/usb,device compatible node fails, try to find
      .../usb/hub/ethernet, where ... is bus path that can depend on actual HW.
      net,ethernet/usb,device compatibity strings are FreeBSD custom invention
      that is used only in RPi DTBs and since there is no other way to tie USB
      device to FDT node we just do our best effort here to work with upstream
      device tree
  
  - Use -1 value to indicate invalid phandle_t, 0 is valid phandle value and
      shouldn't be used as error signal

Modified:
  stable/11/sys/dev/usb/net/if_smsc.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/dev/usb/net/if_smsc.c
==============================================================================
--- stable/11/sys/dev/usb/net/if_smsc.c	Tue Oct 18 23:20:49 2016	(r307584)
+++ stable/11/sys/dev/usb/net/if_smsc.c	Tue Oct 18 23:27:50 2016	(r307585)
@@ -1556,6 +1556,9 @@ smsc_ioctl(struct ifnet *ifp, u_long cmd
 }
 
 #ifdef FDT
+/*
+ * This is FreeBSD-specific compatibility strings for RPi/RPi2
+ */
 static phandle_t
 smsc_fdt_find_eth_node(phandle_t start)
 {
@@ -1567,11 +1570,68 @@ smsc_fdt_find_eth_node(phandle_t start)
 		    fdt_is_compatible(node, "usb,device"))
 			return (node);
 		child = smsc_fdt_find_eth_node(node);
-		if (child != 0)
+		if (child != -1)
 			return (child);
 	}
 
-	return (0);
+	return (-1);
+}
+
+/*
+ * Check if node's path is <*>/usb/hub/ethernet
+ */
+static int
+smsc_fdt_is_usb_eth(phandle_t node)
+{
+	char name[16];
+	int len;
+
+	memset(name, 0, sizeof(name));
+	len = OF_getprop(node, "name", name, sizeof(name));
+	if (len <= 0)
+		return (0);
+
+	if (strcmp(name, "ethernet"))
+		return (0);
+
+	node = OF_parent(node);
+	if (node == -1)
+		return (0);
+	len = OF_getprop(node, "name", name, sizeof(name));
+	if (len <= 0)
+		return (0);
+
+	if (strcmp(name, "hub"))
+		return (0);
+
+	node = OF_parent(node);
+	if (node == -1)
+		return (0);
+	len = OF_getprop(node, "name", name, sizeof(name));
+	if (len <= 0)
+		return (0);
+
+	if (strcmp(name, "usb"))
+		return (0);
+
+	return (1);
+}
+
+static phandle_t
+smsc_fdt_find_eth_node_by_path(phandle_t start)
+{
+	phandle_t child, node;
+
+	/* Traverse through entire tree to find usb ethernet nodes. */
+	for (node = OF_child(start); node != 0; node = OF_peer(node)) {
+		if (smsc_fdt_is_usb_eth(node))
+			return (node);
+		child = smsc_fdt_find_eth_node_by_path(node);
+		if (child != -1)
+			return (child);
+	}
+
+	return (-1);
 }
 
 /**
@@ -1587,8 +1647,14 @@ smsc_fdt_find_mac(unsigned char *mac)
 
 	root = OF_finddevice("/");
 	node = smsc_fdt_find_eth_node(root);
-	if (node != 0) {
+	/*
+	 * If it's not FreeBSD FDT blob for RPi, try more
+	 *     generic .../usb/hub/ethernet
+	 */
+	if (node == -1)
+		node = smsc_fdt_find_eth_node_by_path(root);
 
+	if (node != -1) {
 		/* Check if there is property */
 		if ((len = OF_getproplen(node, "local-mac-address")) > 0) {
 			if (len != ETHER_ADDR_LEN)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201610182327.u9INRovA037341>