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>
This commit is contained in:
parent
bfacad7da1
commit
e58780dcb7
@ -178,7 +178,7 @@
|
||||
|
||||
#define SANDBOX_ETH_SETTINGS "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"
|
||||
|
||||
#define CONFIG_EXTRA_ENV_SETTINGS SANDBOX_SERIAL_SETTINGS \
|
||||
|
@ -124,6 +124,11 @@ struct eth_ops {
|
||||
#define eth_get_ops(dev) ((struct eth_ops *)(dev)->driver->ops)
|
||||
|
||||
struct udevice *eth_get_dev(void); /* get the current device */
|
||||
/*
|
||||
* The devname can be either an exact name given by the driver or device tree
|
||||
* or it can be an alias of the form "eth%d"
|
||||
*/
|
||||
struct udevice *eth_get_dev_by_name(const char *devname);
|
||||
unsigned char *eth_get_ethaddr(void); /* get the current device MAC */
|
||||
/* Used only when NetConsole is enabled */
|
||||
int eth_init_state_only(void); /* Set active state */
|
||||
|
50
net/eth.c
50
net/eth.c
@ -135,6 +135,39 @@ static void eth_set_dev(struct udevice *dev)
|
||||
eth_get_uclass_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 seq = -1;
|
||||
char *endp = NULL;
|
||||
const char *startp = NULL;
|
||||
struct udevice *it;
|
||||
struct uclass *uc;
|
||||
|
||||
/* Must be longer than 3 to be an alias */
|
||||
if (strlen(devname) > strlen("eth")) {
|
||||
startp = devname + strlen("eth");
|
||||
seq = simple_strtoul(startp, &endp, 10);
|
||||
}
|
||||
|
||||
uclass_get(UCLASS_ETH, &uc);
|
||||
uclass_foreach_dev(it, uc) {
|
||||
/* We need the seq to be valid, so make sure it's probed */
|
||||
device_probe(it);
|
||||
/*
|
||||
* Check for the name or the sequence number to match
|
||||
*/
|
||||
if (strcmp(it->name, devname) == 0 ||
|
||||
(endp > startp && it->seq == seq))
|
||||
return it;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned char *eth_get_ethaddr(void)
|
||||
{
|
||||
struct eth_pdata *pdata;
|
||||
@ -421,6 +454,7 @@ UCLASS_DRIVER(eth) = {
|
||||
.pre_remove = eth_pre_remove,
|
||||
.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
|
||||
|
||||
@ -453,6 +487,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;
|
||||
@ -869,7 +908,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();
|
||||
@ -877,14 +915,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();
|
||||
}
|
||||
|
@ -36,3 +36,27 @@ static int dm_test_eth(struct dm_test_state *dms)
|
||||
return 0;
|
||||
}
|
||||
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@10002000", getenv("ethact"));
|
||||
|
||||
setenv("ethact", "eth1");
|
||||
ut_assertok(NetLoop(PING));
|
||||
ut_asserteq_str("eth@10004000", getenv("ethact"));
|
||||
|
||||
/* Expected to fail since eth2 is not defined in the device tree */
|
||||
setenv("ethact", "eth2");
|
||||
ut_assertok(NetLoop(PING));
|
||||
ut_asserteq_str("eth@10002000", getenv("ethact"));
|
||||
|
||||
setenv("ethact", "eth5");
|
||||
ut_assertok(NetLoop(PING));
|
||||
ut_asserteq_str("eth@10003000", getenv("ethact"));
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_eth_alias, DM_TESTF_SCAN_FDT);
|
||||
|
@ -18,6 +18,8 @@
|
||||
testfdt3 = "/b-test";
|
||||
testfdt5 = "/some-bus/c-test@5";
|
||||
testfdt8 = "/a-test";
|
||||
eth0 = "/eth@10002000";
|
||||
eth5 = ð_5;
|
||||
};
|
||||
|
||||
uart0: serial {
|
||||
@ -172,7 +174,7 @@
|
||||
fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x00>;
|
||||
};
|
||||
|
||||
eth@10003000 {
|
||||
eth_5: eth@10003000 {
|
||||
compatible = "sandbox,eth";
|
||||
reg = <0x10003000 0x1000>;
|
||||
fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x11>;
|
||||
|
Loading…
Reference in New Issue
Block a user