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.
This commit is contained in:
Luiz Otavio O Souza 2014-10-23 13:47:19 +00:00
parent 069f1c256a
commit 381fd7619b

View File

@ -1556,57 +1556,56 @@ smsc_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
}
#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;
node = smsc_fdt_find_eth_node(root);
if (node != 0) {
/* Traverse through entire tree to find nodes usb ethernet nodes */
for (child = OF_child(parent); child != 0; child = OF_peer(child)) {
/* Check if there is property */
if ((len = OF_getproplen(node, "local-mac-address")) > 0) {
if (len != ETHER_ADDR_LEN)
return (EINVAL);
/* Find a 'leaf'. Start the search from this node. */
while (OF_child(child)) {
parent = child;
child = OF_child(child);
OF_getprop(node, "local-mac-address", mac,
ETHER_ADDR_LEN);
return (0);
}
if (fdt_is_compatible(child, "net,ethernet") &&
fdt_is_compatible(child, "usb,device")) {
if ((len = OF_getproplen(node, "mac-address")) > 0) {
if (len != ETHER_ADDR_LEN)
return (EINVAL);
/* 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);
}
}
if (OF_peer(child) == 0) {
/* No more siblings. */
child = parent;
parent = OF_parent(child);
OF_getprop(node, "mac-address", mac,
ETHER_ADDR_LEN);
return (0);
}
}