Commit e58780dcb7b8656ebc2dd6ba6d0da728bc65bf40

Authored by Joe Hershberger
Committed by Simon Glass
1 parent bfacad7da1

dm: eth: Add support for aliases

Allow network devices to be referred to as "eth0" instead of
"eth@12345678" when specified in ethact.

Add tests to verify this behavior.

Signed-off-by: Joe Hershberger <joe.hershberger@ni.com>
Reviewed-by: Simon Glass <sjg@chromium.org>

Showing 5 changed files with 74 additions and 11 deletions Side-by-side Diff

include/configs/sandbox.h
... ... @@ -178,7 +178,7 @@
178 178  
179 179 #define SANDBOX_ETH_SETTINGS "ethaddr=00:00:11:22:33:44\0" \
180 180 "eth1addr=00:00:11:22:33:45\0" \
181   - "eth2addr=00:00:11:22:33:46addr=00:00:11:22:33:46\0" \" \
  181 + "eth5addr=00:00:11:22:33:46addr=00:00:11:22:33:46\0" \" \
182 182 "ipaddr=1.2.3.4\0"
183 183  
184 184 #define CONFIG_EXTRA_ENV_SETTINGS SANDBOX_SERIAL_SETTINGS \
... ... @@ -124,6 +124,11 @@
124 124 #define eth_get_ops(dev) ((struct eth_ops *)(dev)->driver->ops)
125 125  
126 126 struct udevice *eth_get_dev(void); /* get the current device */
  127 +/*
  128 + * The devname can be either an exact name given by the driver or device tree
  129 + * or it can be an alias of the form "eth%d"
  130 + */
  131 +struct udevice *eth_get_dev_by_name(const char *devname);
127 132 unsigned char *eth_get_ethaddr(void); /* get the current device MAC */
128 133 /* Used only when NetConsole is enabled */
129 134 int eth_init_state_only(void); /* Set active state */
... ... @@ -135,6 +135,39 @@
135 135 eth_get_uclass_priv()->current = dev;
136 136 }
137 137  
  138 +/*
  139 + * Find the udevice that either has the name passed in as devname or has an
  140 + * alias named devname.
  141 + */
  142 +struct udevice *eth_get_dev_by_name(const char *devname)
  143 +{
  144 + int seq = -1;
  145 + char *endp = NULL;
  146 + const char *startp = NULL;
  147 + struct udevice *it;
  148 + struct uclass *uc;
  149 +
  150 + /* Must be longer than 3 to be an alias */
  151 + if (strlen(devname) > strlen("eth")) {
  152 + startp = devname + strlen("eth");
  153 + seq = simple_strtoul(startp, &endp, 10);
  154 + }
  155 +
  156 + uclass_get(UCLASS_ETH, &uc);
  157 + uclass_foreach_dev(it, uc) {
  158 + /* We need the seq to be valid, so make sure it's probed */
  159 + device_probe(it);
  160 + /*
  161 + * Check for the name or the sequence number to match
  162 + */
  163 + if (strcmp(it->name, devname) == 0 ||
  164 + (endp > startp && it->seq == seq))
  165 + return it;
  166 + }
  167 +
  168 + return NULL;
  169 +}
  170 +
138 171 unsigned char *eth_get_ethaddr(void)
139 172 {
140 173 struct eth_pdata *pdata;
... ... @@ -421,6 +454,7 @@
421 454 .pre_remove = eth_pre_remove,
422 455 .priv_auto_alloc_size = sizeof(struct eth_uclass_priv),
423 456 .per_device_auto_alloc_size = sizeof(struct eth_device_priv),
  457 + .flags = DM_UC_FLAG_SEQ_ALIAS,
424 458 };
425 459 #endif
426 460  
... ... @@ -453,6 +487,11 @@
453 487 eth_current = eth_current->next;
454 488 }
455 489  
  490 +static void eth_set_dev(struct eth_device *dev)
  491 +{
  492 + eth_current = dev;
  493 +}
  494 +
456 495 struct eth_device *eth_get_dev_by_name(const char *devname)
457 496 {
458 497 struct eth_device *dev, *target_dev;
... ... @@ -869,7 +908,6 @@
869 908 {
870 909 static char *act;
871 910 static int env_changed_id;
872   - void *old_current;
873 911 int env_id;
874 912  
875 913 env_id = get_env_id();
... ... @@ -877,14 +915,8 @@
877 915 act = getenv("ethact");
878 916 env_changed_id = env_id;
879 917 }
880   - if (act != NULL) {
881   - old_current = eth_get_dev();
882   - do {
883   - if (strcmp(eth_get_name(), act) == 0)
884   - return;
885   - eth_set_current_to_next();
886   - } while (old_current != eth_get_dev());
887   - }
  918 + if (act != NULL)
  919 + eth_set_dev(eth_get_dev_by_name(act));
888 920  
889 921 eth_current_changed();
890 922 }
... ... @@ -36,4 +36,28 @@
36 36 return 0;
37 37 }
38 38 DM_TEST(dm_test_eth, DM_TESTF_SCAN_FDT);
  39 +
  40 +static int dm_test_eth_alias(struct dm_test_state *dms)
  41 +{
  42 + NetPingIP = string_to_ip("1.1.2.2");
  43 + setenv("ethact", "eth0");
  44 + ut_assertok(NetLoop(PING));
  45 + ut_asserteq_str("eth@10002000", getenv("ethact"));
  46 +
  47 + setenv("ethact", "eth1");
  48 + ut_assertok(NetLoop(PING));
  49 + ut_asserteq_str("eth@10004000", getenv("ethact"));
  50 +
  51 + /* Expected to fail since eth2 is not defined in the device tree */
  52 + setenv("ethact", "eth2");
  53 + ut_assertok(NetLoop(PING));
  54 + ut_asserteq_str("eth@10002000", getenv("ethact"));
  55 +
  56 + setenv("ethact", "eth5");
  57 + ut_assertok(NetLoop(PING));
  58 + ut_asserteq_str("eth@10003000", getenv("ethact"));
  59 +
  60 + return 0;
  61 +}
  62 +DM_TEST(dm_test_eth_alias, DM_TESTF_SCAN_FDT);
... ... @@ -18,6 +18,8 @@
18 18 testfdt3 = "/b-test";
19 19 testfdt5 = "/some-bus/c-test@5";
20 20 testfdt8 = "/a-test";
  21 + eth0 = "/eth@10002000";
  22 + eth5 = &eth_5;
21 23 };
22 24  
23 25 uart0: serial {
... ... @@ -172,7 +174,7 @@
172 174 fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x00>;
173 175 };
174 176  
175   - eth@10003000 {
  177 + eth_5: eth@10003000 {
176 178 compatible = "sandbox,eth";
177 179 reg = <0x10003000 0x1000>;
178 180 fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x11>;