Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 23 Oct 2014 13:47:19 +0000 (UTC)
From:      Luiz Otavio O Souza <loos@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r273546 - head/sys/dev/usb/net
Message-ID:  <201410231347.s9NDlJkP050463@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: loos
Date: Thu Oct 23 13:47:19 2014
New Revision: 273546
URL: https://svnweb.freebsd.org/changeset/base/273546

Log:
  Fix a bug where some DTS layouts could cause the premature ending of the
  search (i.e. without returning any result) and you would end up with a
  random MAC address.
  
  Change the search algorithm to a recursive one to ensure that all the nodes
  on DTS will be verified.
  
  The previous algorithm could not keep up if the DTS has too many sub-nodes.
  
  While here, fix the punctuation on comments.

Modified:
  head/sys/dev/usb/net/if_smsc.c

Modified: head/sys/dev/usb/net/if_smsc.c
==============================================================================
--- head/sys/dev/usb/net/if_smsc.c	Thu Oct 23 13:32:01 2014	(r273545)
+++ head/sys/dev/usb/net/if_smsc.c	Thu Oct 23 13:47:19 2014	(r273546)
@@ -1556,57 +1556,56 @@ smsc_ioctl(struct ifnet *ifp, u_long cmd
 }
 
 #ifdef FDT
+static phandle_t
+smsc_fdt_find_eth_node(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 (fdt_is_compatible(node, "net,ethernet") &&
+		    fdt_is_compatible(node, "usb,device"))
+			return (node);
+		child = smsc_fdt_find_eth_node(node);
+		if (child != 0)
+			return (child);
+	}
+
+	return (0);
+}
+
 /**
- * Get MAC address from FDT blob. Firmware or loader should fill
- * mac-address or local-mac-address property Returns 0 if MAC address
- * obtained, error code otherwise
+ * Get MAC address from FDT blob.  Firmware or loader should fill
+ * mac-address or local-mac-address property.  Returns 0 if MAC address
+ * obtained, error code otherwise.
  */
 static int
 smsc_fdt_find_mac(unsigned char *mac)
 {
-	phandle_t child, parent, root;
+	phandle_t node, root;
 	int len;
 
 	root = OF_finddevice("/");
-	len = 0;
-	parent = root;
-
-	/* Traverse through entire tree to find nodes usb ethernet nodes */
-	for (child = OF_child(parent); child != 0; child = OF_peer(child)) {
-
-		/* Find a 'leaf'. Start the search from this node. */
-		while (OF_child(child)) {
-			parent = child;
-			child = OF_child(child);
-		}
-
-		if (fdt_is_compatible(child, "net,ethernet") &&
-		    fdt_is_compatible(child, "usb,device")) {
+	node = smsc_fdt_find_eth_node(root);
+	if (node != 0) {
 
-			/* Check if there is property */
-			if ((len = OF_getproplen(child, "local-mac-address")) > 0) {
-				if (len != ETHER_ADDR_LEN)
-					return (EINVAL);
-
-				OF_getprop(child, "local-mac-address", mac,
-				    ETHER_ADDR_LEN);
-				return (0);
-			}
-
-			if ((len = OF_getproplen(child, "mac-address")) > 0) {
-				if (len != ETHER_ADDR_LEN)
-					return (EINVAL);
-
-				OF_getprop(child, "mac-address", mac,
-				    ETHER_ADDR_LEN);
-				return (0);
-			}
+		/* Check if there is property */
+		if ((len = OF_getproplen(node, "local-mac-address")) > 0) {
+			if (len != ETHER_ADDR_LEN)
+				return (EINVAL);
+
+			OF_getprop(node, "local-mac-address", mac,
+			    ETHER_ADDR_LEN);
+			return (0);
 		}
 
-		if (OF_peer(child) == 0) {
-			/* No more siblings. */
-			child = parent;
-			parent = OF_parent(child);
+		if ((len = OF_getproplen(node, "mac-address")) > 0) {
+			if (len != ETHER_ADDR_LEN)
+				return (EINVAL);
+
+			OF_getprop(node, "mac-address", mac,
+			    ETHER_ADDR_LEN);
+			return (0);
 		}
 	}
 



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