[U-Boot] [PATCH v3] fdt: rework fdt_fixup_ethernet() to use env instead of bd_t

Move to using the environment variables 'ethaddr', 'eth1addr', etc.. instead of bd->bi_enetaddr, bi_enet1addr, etc.
This makes the code a bit more flexible to the number of ethernet interfaces.
Signed-off-by: Kumar Gala galak@kernel.crashing.org ---
We walk through the env now searching for 'eth*addr' and parse a match to deal with the fixup.
- k
common/cmd_nvedit.c | 17 +++++++ common/fdt_support.c | 123 ++++++++++++++++++++++++++++++++---------------- cpu/74xx_7xx/cpu.c | 2 +- cpu/mpc512x/cpu.c | 2 +- cpu/mpc8260/cpu.c | 2 +- cpu/mpc83xx/fdt.c | 2 +- cpu/mpc85xx/fdt.c | 2 +- cpu/mpc86xx/fdt.c | 2 +- cpu/mpc8xx/fdt.c | 2 +- cpu/ppc4xx/fdt.c | 2 +- include/common.h | 2 + include/fdt_support.h | 2 +- 12 files changed, 110 insertions(+), 50 deletions(-)
diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index 7089706..9894cf5 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -576,6 +576,23 @@ int envmatch (uchar *s1, int i2) return(-1); }
+/* compare memory to a portion of the environment, similiar + * to memcmp, except s2 is provided by an index into the environment + */ +int envcmp(const void *s1, int i2, size_t count) +{ + const unsigned char *su1; + unsigned char c; + int res = 0, j; + + for(su1 = s1, j = i2; 0 < count; ++su1, ++j, count--) { + c = env_get_char(j); + if ((res = *su1 - c) != 0) + break; + } + + return res; +}
/**************************************************/
diff --git a/common/fdt_support.c b/common/fdt_support.c index 93b144e..527e747 100644 --- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -368,55 +368,96 @@ int fdt_fixup_memory(void *blob, u64 start, u64 size) return 0; }
-#if defined(CONFIG_HAS_ETH0) || defined(CONFIG_HAS_ETH1) ||\ - defined(CONFIG_HAS_ETH2) || defined(CONFIG_HAS_ETH3) - -void fdt_fixup_ethernet(void *fdt, bd_t *bd) +static void fdt_fixup_one_mac(void *fdt, int aliasnode, + int ethidx, void *mac_addr) { - int node; const char *path; + char enet[12]; + + sprintf(enet, "ethernet%d", ethidx); + + path = fdt_getprop(fdt, aliasnode, enet, NULL); + if (!path) { + debug("No alias for %s\n", enet); + return; + } + + do_fixup_by_path(fdt, path, "mac-address", mac_addr, 6, 0); + do_fixup_by_path(fdt, path, "local-mac-address", mac_addr, 6, 1); +} + +void fdt_fixup_ethernet(void *fdt) +{ + int i, j, k, nxt, addr, idx, val, node; + unsigned char c, mac_addr[6];
node = fdt_path_offset(fdt, "/aliases"); - if (node >= 0) { -#if defined(CONFIG_HAS_ETH0) - path = fdt_getprop(fdt, node, "ethernet0", NULL); - if (path) { - do_fixup_by_path(fdt, path, "mac-address", - bd->bi_enetaddr, 6, 0); - do_fixup_by_path(fdt, path, "local-mac-address", - bd->bi_enetaddr, 6, 1); - } -#endif -#if defined(CONFIG_HAS_ETH1) - path = fdt_getprop(fdt, node, "ethernet1", NULL); - if (path) { - do_fixup_by_path(fdt, path, "mac-address", - bd->bi_enet1addr, 6, 0); - do_fixup_by_path(fdt, path, "local-mac-address", - bd->bi_enet1addr, 6, 1); - } -#endif -#if defined(CONFIG_HAS_ETH2) - path = fdt_getprop(fdt, node, "ethernet2", NULL); - if (path) { - do_fixup_by_path(fdt, path, "mac-address", - bd->bi_enet2addr, 6, 0); - do_fixup_by_path(fdt, path, "local-mac-address", - bd->bi_enet2addr, 6, 1); + if (node < 0) + return; + + /* walk the env looking for eth[.*]addr */ + for (i=0; env_get_char(i) != '\0'; i=nxt+1) { + for (nxt=i; env_get_char(nxt) != '\0'; ++nxt) + ; + + /* if the pair isn't long enough, continue */ + if ((nxt - i) < 19) + continue; + + /* if it doesn't start with eth, continue */ + if (0 != envcmp("eth", i, 3)) + continue; + + /* search for the first 'a', in addr= */ + addr = i + 3; + for (; addr < nxt; ++addr) + if (env_get_char(addr) == 'a') + break; + + /* if its not 'addr=', continue */ + if (0 != envcmp("addr=", addr, 5)) + continue; + + /* if we dont have enough chars for the mac addr, continue */ + if ((nxt - addr) < 16) + continue; + + /* extract and convert the index */ + idx = 0; + for (k = i+3; k < addr; ++k) { + c = env_get_char(k); + val = c - '0'; + if (!isdigit(c)) + break; + idx = idx*10 + val; } -#endif -#if defined(CONFIG_HAS_ETH3) - path = fdt_getprop(fdt, node, "ethernet3", NULL); - if (path) { - do_fixup_by_path(fdt, path, "mac-address", - bd->bi_enet3addr, 6, 0); - do_fixup_by_path(fdt, path, "local-mac-address", - bd->bi_enet3addr, 6, 1); + + /* we didnt parse all chars as digits */ + if (k != addr) + continue; + + /* extract mac address */ + for (k = addr + 5, j = 0, val = 0; k < nxt; ++k) { + int tmp; + c = env_get_char(k); + + if (isxdigit(c)) { + if (isdigit(c)) + tmp = c -'0'; + else + tmp = (islower(c) ? + toupper(c) : c) - 'A' + 10; + val = val * 16 + tmp; + } else { + mac_addr[j++] = val; + val = 0; + } } -#endif + mac_addr[j] = val; + + fdt_fixup_one_mac(fdt, node, idx, &mac_addr); } } -#endif
#ifdef CONFIG_HAS_FSL_DR_USB void fdt_fixup_dr_usb(void *blob, bd_t *bd) diff --git a/cpu/74xx_7xx/cpu.c b/cpu/74xx_7xx/cpu.c index ea43c9a..c007abc 100644 --- a/cpu/74xx_7xx/cpu.c +++ b/cpu/74xx_7xx/cpu.c @@ -314,7 +314,7 @@ void ft_cpu_setup(void *blob, bd_t *bd)
fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize);
- fdt_fixup_ethernet(blob, bd); + fdt_fixup_ethernet(blob); } #endif /* ------------------------------------------------------------------------- */ diff --git a/cpu/mpc512x/cpu.c b/cpu/mpc512x/cpu.c index 703e188..1f39ac4 100644 --- a/cpu/mpc512x/cpu.c +++ b/cpu/mpc512x/cpu.c @@ -191,7 +191,7 @@ void ft_cpu_setup(void *blob, bd_t *bd) #endif ft_clock_setup(blob, bd); #ifdef CONFIG_HAS_ETH0 - fdt_fixup_ethernet(blob, bd); + fdt_fixup_ethernet(blob); #endif } #endif diff --git a/cpu/mpc8260/cpu.c b/cpu/mpc8260/cpu.c index 4d5d141..efb8ed6 100644 --- a/cpu/mpc8260/cpu.c +++ b/cpu/mpc8260/cpu.c @@ -307,7 +307,7 @@ void ft_cpu_setup (void *blob, bd_t *bd)
#if defined(CONFIG_HAS_ETH0) || defined(CONFIG_HAS_ETH1) ||\ defined(CONFIG_HAS_ETH2) || defined(CONFIG_HAS_ETH3) - fdt_fixup_ethernet(blob, bd); + fdt_fixup_ethernet(blob); #endif
do_fixup_by_path_u32(blob, cpu_path, "bus-frequency", bd->bi_busfreq, 1); diff --git a/cpu/mpc83xx/fdt.c b/cpu/mpc83xx/fdt.c index fda85c1..39bd9dc 100644 --- a/cpu/mpc83xx/fdt.c +++ b/cpu/mpc83xx/fdt.c @@ -53,7 +53,7 @@ void ft_cpu_setup(void *blob, bd_t *bd)
#if defined(CONFIG_HAS_ETH0) || defined(CONFIG_HAS_ETH1) ||\ defined(CONFIG_HAS_ETH2) || defined(CONFIG_HAS_ETH3) - fdt_fixup_ethernet(blob, bd); + fdt_fixup_ethernet(blob); #endif
do_fixup_by_prop_u32(blob, "device_type", "cpu", 4, diff --git a/cpu/mpc85xx/fdt.c b/cpu/mpc85xx/fdt.c index c159934..bc1550d 100644 --- a/cpu/mpc85xx/fdt.c +++ b/cpu/mpc85xx/fdt.c @@ -212,7 +212,7 @@ void ft_cpu_setup(void *blob, bd_t *bd)
#if defined(CONFIG_HAS_ETH0) || defined(CONFIG_HAS_ETH1) ||\ defined(CONFIG_HAS_ETH2) || defined(CONFIG_HAS_ETH3) - fdt_fixup_ethernet(blob, bd); + fdt_fixup_ethernet(blob); #endif
do_fixup_by_prop_u32(blob, "device_type", "cpu", 4, diff --git a/cpu/mpc86xx/fdt.c b/cpu/mpc86xx/fdt.c index 80a5c78..12d9052 100644 --- a/cpu/mpc86xx/fdt.c +++ b/cpu/mpc86xx/fdt.c @@ -25,7 +25,7 @@ void ft_cpu_setup(void *blob, bd_t *bd)
#if defined(CONFIG_HAS_ETH0) || defined(CONFIG_HAS_ETH1) \ || defined(CONFIG_HAS_ETH2) || defined(CONFIG_HAS_ETH3) - fdt_fixup_ethernet(blob, bd); + fdt_fixup_ethernet(blob); #endif
#ifdef CFG_NS16550 diff --git a/cpu/mpc8xx/fdt.c b/cpu/mpc8xx/fdt.c index 567094a..7130983 100644 --- a/cpu/mpc8xx/fdt.c +++ b/cpu/mpc8xx/fdt.c @@ -40,7 +40,7 @@ void ft_cpu_setup(void *blob, bd_t *bd) gd->brg_clk, 1);
/* Fixup ethernet MAC addresses */ - fdt_fixup_ethernet(blob, bd); + fdt_fixup_ethernet(blob);
fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize); } diff --git a/cpu/ppc4xx/fdt.c b/cpu/ppc4xx/fdt.c index 0323dc5..a97484f 100644 --- a/cpu/ppc4xx/fdt.c +++ b/cpu/ppc4xx/fdt.c @@ -130,7 +130,7 @@ void ft_cpu_setup(void *blob, bd_t *bd) * Fixup all ethernet nodes * Note: aliases in the dts are required for this */ - fdt_fixup_ethernet(blob, bd); + fdt_fixup_ethernet(blob);
/* * Fixup all available PCIe nodes by setting the device_type property diff --git a/include/common.h b/include/common.h index 06ed278..eb865f3 100644 --- a/include/common.h +++ b/include/common.h @@ -241,6 +241,7 @@ extern ulong load_addr; /* Default Load Address */ int env_init (void); void env_relocate (void); int envmatch (uchar *, int); +int envcmp (const void *s1, int i2, size_t count); char *getenv (char *); int getenv_r (char *name, char *buf, unsigned len); int saveenv (void); @@ -260,6 +261,7 @@ void forceenv (char *, char *); #ifdef CONFIG_I386 /* x86 version to be fixed! */ # include <asm/u-boot-i386.h> #endif /* CONFIG_I386 */ +uchar env_get_char (int index);
#ifdef CONFIG_AUTO_COMPLETE int env_complete(char *var, int maxv, char *cmdv[], int maxsz, char *buf); diff --git a/include/fdt_support.h b/include/fdt_support.h index a7c6326..f2f2cd5 100644 --- a/include/fdt_support.h +++ b/include/fdt_support.h @@ -45,7 +45,7 @@ void do_fixup_by_compat(void *fdt, const char *compat, void do_fixup_by_compat_u32(void *fdt, const char *compat, const char *prop, u32 val, int create); int fdt_fixup_memory(void *blob, u64 start, u64 size); -void fdt_fixup_ethernet(void *fdt, bd_t *bd); +void fdt_fixup_ethernet(void *fdt); int fdt_find_and_setprop(void *fdt, const char *node, const char *prop, const void *val, int len, int create); void fdt_fixup_qe_firmware(void *fdt);

Dear Kumar Gala,
In message Pine.LNX.4.64.0808190924520.6029@blarg.am.freescale.net you wrote:
--- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -368,55 +368,96 @@ int fdt_fixup_memory(void *blob, u64 start, u64 size)
...
- /* walk the env looking for eth[.*]addr */
- for (i=0; env_get_char(i) != '\0'; i=nxt+1) {
for (nxt=i; env_get_char(nxt) != '\0'; ++nxt)
;
Please do not do this. env_get_char() is a function that is internal to the environment handling code. It is not supposed to be exported to arbitrary code. Please do not make any assumptions about the internals of how the environment is stored.
NAK.
Best regards,
Wolfgang Denk

On Aug 19, 2008, at 10:06 AM, Wolfgang Denk wrote:
Dear Kumar Gala,
In message Pine.LNX.4.64.0808190924520.6029@blarg.am.freescale.net you wrote:
--- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -368,55 +368,96 @@ int fdt_fixup_memory(void *blob, u64 start, u64 size)
...
- /* walk the env looking for eth[.*]addr */
- for (i=0; env_get_char(i) != '\0'; i=nxt+1) {
for (nxt=i; env_get_char(nxt) != '\0'; ++nxt)
;
Please do not do this. env_get_char() is a function that is internal to the environment handling code. It is not supposed to be exported to arbitrary code. Please do not make any assumptions about the internals of how the environment is stored.
NAK.
I'm so confused.. how does one 'iterate' over the environment than? As you agree with Scott's suggestion in:
http://lists.denx.de/pipermail/u-boot/2008-August/000498.html
- k

On Tue, Aug 19, 2008 at 10:23:54AM -0500, Kumar Gala wrote:
Please do not do this. env_get_char() is a function that is internal to the environment handling code. It is not supposed to be exported to arbitrary code. Please do not make any assumptions about the internals of how the environment is stored.
NAK.
I'm so confused.. how does one 'iterate' over the environment than? As you agree with Scott's suggestion in:
http://lists.denx.de/pipermail/u-boot/2008-August/000498.html
Add something to the env code itself to iterate with a callback pointer.
-Scott
participants (3)
-
Kumar Gala
-
Scott Wood
-
Wolfgang Denk