[U-Boot] [RFC PATCH v3 11/14] dm: eth: Add support for aliases

Simon Glass sjg at chromium.org
Sun Feb 15 16:50:06 CET 2015


Hi Joe,

On 10 February 2015 at 18:30, Joe Hershberger <joe.hershberger at ni.com> wrote:
> Allow network devices to be referred to as "eth0" instead of
> "eth at 12345678" when specified in ethact.
>
> Add tests to verify this behavior.
>
> Signed-off-by: Joe Hershberger <joe.hershberger at ni.com>
>
> ---
>
> Changes in v3:
> -Added support for aliases
>
> Changes in v2: None
>
>  include/configs/sandbox.h |  4 ++--
>  include/fdtdec.h          |  1 +
>  include/net.h             |  5 +++++
>  lib/fdtdec.c              |  1 +
>  net/eth.c                 | 53 +++++++++++++++++++++++++++++++++++++++--------
>  test/dm/eth.c             | 25 ++++++++++++++++++++++
>  test/dm/test.dts          | 10 +++++----
>  7 files changed, 84 insertions(+), 15 deletions(-)
>
> diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h
> index fdba1c8..9df5f74 100644
> --- a/include/configs/sandbox.h
> +++ b/include/configs/sandbox.h
> @@ -187,7 +187,7 @@
>                                         "stderr=serial,lcd\0" \
>                                         "ethaddr=00:00:11:22:33:44\0" \
>                                         "eth1addr=00:00:11:22:33:45\0" \
> -                                       "eth2addr=00:00:11:22:33:46\0" \
> +                                       "eth5addr=00:00:11:22:33:46\0" \
>                                         "ipaddr=1.2.3.4\0"
>  #else
>
> @@ -196,7 +196,7 @@
>                                         "stderr=serial,lcd\0" \
>                                         "ethaddr=00:00:11:22:33:44\0" \
>                                         "eth1addr=00:00:11:22:33:45\0" \
> -                                       "eth2addr=00:00:11:22:33:46\0" \
> +                                       "eth5addr=00:00:11:22:33:46\0" \
>                                         "ipaddr=1.2.3.4\0"
>  #endif
>
> diff --git a/include/fdtdec.h b/include/fdtdec.h
> index 231eed7..e945baa 100644
> --- a/include/fdtdec.h
> +++ b/include/fdtdec.h
> @@ -167,6 +167,7 @@ enum fdt_compat_id {
>         COMPAT_INTEL_GMA,               /* Intel Graphics Media Accelerator */
>         COMPAT_AMS_AS3722,              /* AMS AS3722 PMIC */
>         COMPAT_INTEL_ICH_SPI,           /* Intel ICH7/9 SPI controller */
> +       COMPAT_ETHERNET,                /* Ethernet devices */

SANDBOX_ETHERNET

>
>         COMPAT_COUNT,
>  };
> diff --git a/include/net.h b/include/net.h
> index 11471bd..4e98850 100644
> --- a/include/net.h
> +++ b/include/net.h
> @@ -38,6 +38,8 @@
>
>  #define PKTALIGN       ARCH_DMA_MINALIGN
>
> +#define ETH_MAX_DEVS   32
> +
>  /* IPv4 addresses are always 32 bits in size */
>  typedef __be32         IPaddr_t;
>
> @@ -79,6 +81,8 @@ enum eth_state_t {
>  };
>
>  #ifdef CONFIG_DM_ETH
> +#define ETH_ALIAS_ROOT "eth"
> +
>  struct eth_pdata {
>         phys_addr_t iobase;
>         unsigned char enetaddr[6];
> @@ -96,6 +100,7 @@ struct eth_ops {
>  };
>
>  struct udevice *eth_get_dev(void); /* get the current device */
> +struct udevice *eth_get_dev_by_name(const char *devname);
>  unsigned char *eth_get_ethaddr(void); /* get the current device MAC */
>  int eth_init_state_only(bd_t *bis); /* Set active state */
>  void eth_halt_state_only(void); /* Set passive state */
> diff --git a/lib/fdtdec.c b/lib/fdtdec.c
> index 5bf8f29..33b0a53 100644
> --- a/lib/fdtdec.c
> +++ b/lib/fdtdec.c
> @@ -75,6 +75,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
>         COMPAT(INTEL_GMA, "intel,gma"),
>         COMPAT(AMS_AS3722, "ams,as3722"),
>         COMPAT(INTEL_ICH_SPI, "intel,ich-spi"),
> +       COMPAT(ETHERNET, "eth"),

sandbox,eth

>  };
>
>  const char *fdtdec_get_compatible(enum fdt_compat_id id)
> diff --git a/net/eth.c b/net/eth.c
> index e84b948..762effe 100644
> --- a/net/eth.c
> +++ b/net/eth.c
> @@ -10,11 +10,14 @@
>  #include <command.h>
>  #include <dm.h>
>  #include <dm/device-internal.h>
> +#include <fdtdec.h>
>  #include <net.h>
>  #include <miiphy.h>
>  #include <phy.h>
>  #include <asm/errno.h>
>
> +DECLARE_GLOBAL_DATA_PTR;
> +
>  void eth_parse_enetaddr(const char *addr, uchar *enetaddr)
>  {
>         char *end;
> @@ -121,6 +124,39 @@ static void eth_set_dev(struct udevice *dev)
>         uc_priv->current = dev;
>  }
>
> +/*
> + * Find the udevice that either has the name passed in as devname or has an
> + * alias named devname.
> + */
> +struct udevice *eth_get_dev_by_name(const char *devname)
> +{
> +       int node_list[ETH_MAX_DEVS];
> +       int count;
> +       int seq;
> +       char *endp = NULL;
> +       const char *true_name = devname;
> +       struct udevice *it;
> +       struct uclass *uc;
> +
> +       count = fdtdec_find_aliases_for_id(gd->fdt_blob, ETH_ALIAS_ROOT,
> +                                          COMPAT_ETHERNET, node_list,
> +                                          ETH_MAX_DEVS);
> +
> +       seq = simple_strtoul(devname + strlen(ETH_ALIAS_ROOT), &endp, 10);
> +
> +       if (endp > devname + strlen(ETH_ALIAS_ROOT) && count > seq &&
> +           node_list[seq])
> +               true_name = fdt_get_name(gd->fdt_blob, node_list[seq], NULL);
> +
> +       uclass_get(UCLASS_ETH, &uc);
> +       uclass_foreach_dev(it, uc) {
> +               if (strcmp(it->name, true_name) == 0 || it->seq == seq)
> +                       return it;
> +       }

Is it possible for eth_get_dev_by_name() to just look up the name provided?

You already have this:

uclass_foreach_dev(it, uc) {
if (strcmp(it->name, true_name) == 0 || it->seq == seq)
return it;
}

It feels like you just need to through through the devices in the
uclass and strcmp(dev->name, find_name).

I guess I am suffering because I don't understand what you are trying
to do, so am not sure if there is an easier way with driver model. We
really should not go looking in the device tree in
eth_get_dev_by_name()...driver is responsible for parsing that.

> +
> +       return NULL;
> +}
> +
>  unsigned char *eth_get_ethaddr(void)
>  {
>         struct eth_pdata *pdata;
> @@ -396,6 +432,7 @@ UCLASS_DRIVER(eth) = {
>         .init           = eth_uclass_init,
>         .priv_auto_alloc_size = sizeof(struct eth_uclass_priv),
>         .per_device_auto_alloc_size = sizeof(struct eth_device_priv),
> +       .flags          = DM_UC_FLAG_SEQ_ALIAS,
>  };
>  #endif
>
> @@ -428,6 +465,11 @@ static void eth_set_current_to_next(void)
>         eth_current = eth_current->next;
>  }
>
> +static void eth_set_dev(struct eth_device *dev)
> +{
> +       eth_current = dev;
> +}
> +
>  struct eth_device *eth_get_dev_by_name(const char *devname)
>  {
>         struct eth_device *dev, *target_dev;
> @@ -844,7 +886,6 @@ void eth_set_current(void)
>  {
>         static char *act;
>         static int  env_changed_id;
> -       void *old_current;
>         int     env_id;
>
>         env_id = get_env_id();
> @@ -852,14 +893,8 @@ void eth_set_current(void)
>                 act = getenv("ethact");
>                 env_changed_id = env_id;
>         }
> -       if (act != NULL) {
> -               old_current = eth_get_dev();
> -               do {
> -                       if (strcmp(eth_get_name(), act) == 0)
> -                               return;
> -                       eth_set_current_to_next();
> -               } while (old_current != eth_get_dev());
> -       }
> +       if (act != NULL)
> +               eth_set_dev(eth_get_dev_by_name(act));
>
>         eth_current_changed();
>  }
> diff --git a/test/dm/eth.c b/test/dm/eth.c
> index 2b29fa2..c0a8ab5 100644
> --- a/test/dm/eth.c
> +++ b/test/dm/eth.c
> @@ -37,3 +37,28 @@ static int dm_test_eth(struct dm_test_state *dms)
>  }
>
>  DM_TEST(dm_test_eth, DM_TESTF_SCAN_FDT);
> +
> +static int dm_test_eth_alias(struct dm_test_state *dms)
> +{
> +       NetPingIP = string_to_ip("1.1.2.2");
> +       setenv("ethact", "eth0");
> +       ut_assertok(NetLoop(PING));
> +       ut_asserteq_str("eth at 10002000", getenv("ethact"));
> +
> +       setenv("ethact", "eth1");
> +       ut_assertok(NetLoop(PING));
> +       ut_asserteq_str("eth at 10004000", getenv("ethact"));
> +
> +       /* Expected to fail since eth2 is not defined in the device tree */
> +       setenv("ethact", "eth2");
> +       ut_asserteq(-1, NetLoop(PING));
> +       ut_asserteq_ptr(NULL, getenv("ethact"));
> +
> +       setenv("ethact", "eth5");
> +       ut_assertok(NetLoop(PING));
> +       ut_asserteq_str("eth at 10003000", getenv("ethact"));
> +
> +       return 0;
> +}
> +
> +DM_TEST(dm_test_eth_alias, DM_TESTF_SCAN_FDT);
> diff --git a/test/dm/test.dts b/test/dm/test.dts
> index 2f68cdf..c5008c3 100644
> --- a/test/dm/test.dts
> +++ b/test/dm/test.dts
> @@ -17,6 +17,8 @@
>                 testfdt3 = "/b-test";
>                 testfdt5 = "/some-bus/c-test at 5";
>                 testfdt8 = "/a-test";
> +               eth0 = "/eth at 10002000";
> +               eth5 = &eth_5;
>         };
>
>         uart0: serial {
> @@ -150,19 +152,19 @@
>         };
>
>         eth at 10002000 {
> -               compatible = "sandbox,eth";
> +               compatible = "sandbox,eth", "eth";
>                 reg = <0x10002000 0x1000>;
>                 fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x00>;
>         };
>
> -       eth at 10003000 {
> -               compatible = "sandbox,eth";
> +       eth_5: eth at 10003000 {
> +               compatible = "sandbox,eth", "eth";
>                 reg = <0x10003000 0x1000>;
>                 fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x11>;
>         };
>
>         eth at 10004000 {
> -               compatible = "sandbox,eth";
> +               compatible = "sandbox,eth", "eth";
>                 reg = <0x10004000 0x1000>;
>                 fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x22>;
>         };
> --
> 1.7.11.5
>

Regards,
Simon


More information about the U-Boot mailing list