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

Joe Hershberger joe.hershberger at ni.com
Wed Feb 11 02:30:30 CET 2015


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 */
 
 	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"),
 };
 
 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;
+	}
+
+	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



More information about the U-Boot mailing list