1 /*
2  * Copyright (c) 2016, NVIDIA CORPORATION.
3  *
4  * SPDX-License-Identifier: GPL-2.0+
5  */
6 
7 #include <common.h>
8 #include <fdt_support.h>
9 #include <fdtdec.h>
10 #include <asm/arch/tegra.h>
11 
12 extern unsigned long nvtboot_boot_x0;
13 
14 static int set_fdt_addr(void)
15 {
16 	int ret;
17 
18 	ret = setenv_hex("fdt_addr", nvtboot_boot_x0);
19 	if (ret) {
20 		printf("Failed to set fdt_addr to point at DTB: %d\n", ret);
21 		return ret;
22 	}
23 
24 	return 0;
25 }
26 
27 /*
28  * Attempt to use /chosen/nvidia,ether-mac in the nvtboot DTB to U-Boot's
29  * ethaddr environment variable if possible.
30  */
31 static int set_ethaddr_from_nvtboot(void)
32 {
33 	const void *nvtboot_blob = (void *)nvtboot_boot_x0;
34 	int ret, node, len;
35 	const u32 *prop;
36 
37 	/* Already a valid address in the environment? If so, keep it */
38 	if (getenv("ethaddr"))
39 		return 0;
40 
41 	node = fdt_path_offset(nvtboot_blob, "/chosen");
42 	if (node < 0) {
43 		printf("Can't find /chosen node in nvtboot DTB\n");
44 		return node;
45 	}
46 	prop = fdt_getprop(nvtboot_blob, node, "nvidia,ether-mac", &len);
47 	if (!prop) {
48 		printf("Can't find nvidia,ether-mac property in nvtboot DTB\n");
49 		return -ENOENT;
50 	}
51 
52 	ret = setenv("ethaddr", (void *)prop);
53 	if (ret) {
54 		printf("Failed to set ethaddr from nvtboot DTB: %d\n", ret);
55 		return ret;
56 	}
57 
58 	return 0;
59 }
60 
61 int tegra_soc_board_init_late(void)
62 {
63 	/*
64 	 * Ignore errors here; the value may not be used depending on
65 	 * extlinux.conf or boot script content.
66 	 */
67 	set_fdt_addr();
68 	/* Ignore errors here; not all cases care about Ethernet addresses */
69 	set_ethaddr_from_nvtboot();
70 
71 	return 0;
72 }
73