summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2019-04-15 11:32:13 +0200
committerTom Warren <twarren@nvidia.com>2019-06-05 09:16:32 -0700
commitebf30e8451f457aebc8232a674fa75823dd10d49 (patch)
treee7ecd8f5cdc54875abb8dc0fb9b3b77ffb7636b0
parent6d93d245c148f10f15724601650fab3a665f102c (diff)
fdtdec: Add fdtdec_set_ethernet_mac_address()
This function can be used to set the local MAC address for the default Ethernet interface in its device tree node. The default interface is identified by the "ethernet" alias. One case where this is useful is for devices that store their MAC address in a custom location. Once extracted, board code can store the MAC address in U-Boot's control DTB so that it will automatically be used by the Ethernet uclass. Signed-off-by: Thierry Reding <treding@nvidia.com> Signed-off-by: Tom Warren <twarren@nvidia.com>
-rw-r--r--include/fdtdec.h24
-rw-r--r--lib/fdtdec.c29
2 files changed, 53 insertions, 0 deletions
diff --git a/include/fdtdec.h b/include/fdtdec.h
index fa8e34f6f9..e6c22dd5cd 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -997,6 +997,30 @@ int fdtdec_setup_memory_banksize_fdt(const void *blob);
int fdtdec_setup_memory_banksize(void);
/**
+ * fdtdec_set_ethernet_mac_address() - set MAC address for default interface
+ *
+ * Looks up the default interface via the "ethernet" alias (in the /aliases
+ * node) and stores the given MAC in its "local-mac-address" property. This
+ * is useful on platforms that store the MAC address in a custom location.
+ * Board code can call this in the late init stage to make sure that the
+ * interface device tree node has the right MAC address configured for the
+ * Ethernet uclass to pick it up.
+ *
+ * Typically the FDT passed into this function will be U-Boot's control DTB.
+ * Given that a lot of code may be holding offsets to various nodes in that
+ * tree, this code will only set the "local-mac-address" property in-place,
+ * which means that it needs to exist and have space for the 6-byte address.
+ * This ensures that the operation is non-destructive and does not invalidate
+ * offsets that other drivers may be using.
+ *
+ * @param fdt FDT blob
+ * @param mac buffer containing the MAC address to set
+ * @param size size of MAC address
+ * @return 0 on success or a negative error code on failure
+ */
+int fdtdec_set_ethernet_mac_address(void *fdt, const u8 *mac, size_t size);
+
+/**
* fdtdec_set_phandle() - sets the phandle of a given node
*
* @param blob FDT blob
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index d0ba888973..3ee786b579 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -1261,6 +1261,35 @@ __weak void *board_fdt_blob_setup(void)
}
#endif
+int fdtdec_set_ethernet_mac_address(void *fdt, const u8 *mac, size_t size)
+{
+ const char *path;
+ int offset, err;
+
+ if (!is_valid_ethaddr(mac))
+ return -EINVAL;
+
+ path = fdt_get_alias(fdt, "ethernet");
+ if (!path)
+ return 0;
+
+ debug("ethernet alias found: %s\n", path);
+
+ offset = fdt_path_offset(fdt, path);
+ if (offset < 0) {
+ debug("ethernet alias points to absent node %s\n", path);
+ return -ENOENT;
+ }
+
+ err = fdt_setprop_inplace(fdt, offset, "local-mac-address", mac, size);
+ if (err < 0)
+ return err;
+
+ debug("MAC address: %pM\n", mac);
+
+ return 0;
+}
+
static int fdtdec_init_reserved_memory(void *blob)
{
int na, ns, node, err;