dt: protect against NULL matches passed to of_match_node()
[linux-2.6.git] / drivers / of / of_net.c
1 /*
2  * OF helpers for network devices.
3  *
4  * This file is released under the GPLv2
5  *
6  * Initially copied out of arch/powerpc/kernel/prom_parse.c
7  */
8 #include <linux/etherdevice.h>
9 #include <linux/kernel.h>
10 #include <linux/of_net.h>
11
12 /**
13  * Search the device tree for the best MAC address to use.  'mac-address' is
14  * checked first, because that is supposed to contain to "most recent" MAC
15  * address. If that isn't set, then 'local-mac-address' is checked next,
16  * because that is the default address.  If that isn't set, then the obsolete
17  * 'address' is checked, just in case we're using an old device tree.
18  *
19  * Note that the 'address' property is supposed to contain a virtual address of
20  * the register set, but some DTS files have redefined that property to be the
21  * MAC address.
22  *
23  * All-zero MAC addresses are rejected, because those could be properties that
24  * exist in the device tree, but were not set by U-Boot.  For example, the
25  * DTS could define 'mac-address' and 'local-mac-address', with zero MAC
26  * addresses.  Some older U-Boots only initialized 'local-mac-address'.  In
27  * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists
28  * but is all zeros.
29 */
30 const void *of_get_mac_address(struct device_node *np)
31 {
32         struct property *pp;
33
34         pp = of_find_property(np, "mac-address", NULL);
35         if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value))
36                 return pp->value;
37
38         pp = of_find_property(np, "local-mac-address", NULL);
39         if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value))
40                 return pp->value;
41
42         pp = of_find_property(np, "address", NULL);
43         if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value))
44                 return pp->value;
45
46         return NULL;
47 }
48 EXPORT_SYMBOL(of_get_mac_address);