[U-Boot] [PATCH v3 13/26] net: Handle ethaddr changes as an env callback

Joe Hershberger joe.hershberger at ni.com
Sun May 3 22:12:49 CEST 2015


When the ethaddr is changed in the env, update the device pdata at the
same time (only if it is probed for the DM case; only if registered for
the non-DM case). Again this gets us closer to completely non-polled
env needed to simplify the net_loop.

This requires that the NET feature select the REGEX feature.

Signed-off-by: Joe Hershberger <joe.hershberger at ni.com>
---

Changes in v3:
-New for version 3

Changes in v2: None

 configs/sandbox_defconfig |  1 -
 include/env_callback.h    |  3 +-
 net/Kconfig               |  1 +
 net/eth.c                 | 83 ++++++++++++++++++++++++++++++++++-------------
 4 files changed, 63 insertions(+), 25 deletions(-)

diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 340f5eb..5de7fbe 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -26,4 +26,3 @@ CONFIG_TPM_TIS_SANDBOX=y
 CONFIG_SOUND=y
 CONFIG_CMD_SOUND=y
 CONFIG_SOUND_SANDBOX=y
-CONFIG_REGEX=y
diff --git a/include/env_callback.h b/include/env_callback.h
index 91f3cc0..ab5d42d 100644
--- a/include/env_callback.h
+++ b/include/env_callback.h
@@ -52,7 +52,8 @@
 	"serverip:serverip," \
 	"nvlan:nvlan," \
 	"vlan:vlan," \
-	DNS_CALLBACK
+	DNS_CALLBACK \
+	"eth\\d?addr:ethaddr,"
 #else
 #define NET_CALLBACKS
 #endif
diff --git a/net/Kconfig b/net/Kconfig
index 22b9eaa..22008d0 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -4,6 +4,7 @@
 
 menuconfig NET
 	bool "Networking support"
+	select REGEX
 
 if NET
 
diff --git a/net/eth.c b/net/eth.c
index 3c30232..5d97775 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -9,11 +9,13 @@
 #include <common.h>
 #include <command.h>
 #include <dm.h>
+#include <environment.h>
 #include <net.h>
 #include <miiphy.h>
 #include <phy.h>
 #include <asm/errno.h>
 #include <dm/device-internal.h>
+#include <dm/uclass-internal.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -269,6 +271,33 @@ int eth_get_dev_index(void)
 	return -1;
 }
 
+static int on_ethaddr(const char *name, const char *value, enum env_op op,
+	int flags)
+{
+	int index;
+	int retval;
+	struct udevice *dev;
+
+	/* look for an index after "eth" */
+	index = simple_strtoul(name + 3, NULL, 10);
+
+	retval = uclass_find_device_by_seq(UCLASS_ETH, index, false, &dev);
+	if (!retval) {
+		struct eth_pdata *pdata = dev->platdata;
+		switch (op) {
+		case env_op_create:
+		case env_op_overwrite:
+			eth_parse_enetaddr(value, pdata->enetaddr);
+			break;
+		case env_op_delete:
+			memset(pdata->enetaddr, 0, 6);
+		}
+	}
+
+	return 0;
+}
+U_BOOT_ENV_CALLBACK(ethaddr, on_ethaddr);
+
 int eth_init(void)
 {
 	struct udevice *current;
@@ -286,16 +315,6 @@ int eth_init(void)
 		debug("Trying %s\n", current->name);
 
 		if (device_active(current)) {
-			uchar env_enetaddr[6];
-			struct eth_pdata *pdata = current->platdata;
-
-			/* Sync environment with network device */
-			if (eth_getenv_enetaddr_by_index("eth", current->seq,
-							 env_enetaddr))
-				memcpy(pdata->enetaddr, env_enetaddr, 6);
-			else
-				memset(pdata->enetaddr, 0, 6);
-
 			ret = eth_get_ops(current)->start(current);
 			if (ret >= 0) {
 				struct eth_device_priv *priv =
@@ -619,6 +638,36 @@ int eth_get_dev_index(void)
 	return eth_current->index;
 }
 
+static int on_ethaddr(const char *name, const char *value, enum env_op op,
+	int flags)
+{
+	int index;
+	struct eth_device *dev;
+
+	if (!eth_devices)
+		return 0;
+
+	/* look for an index after "eth" */
+	index = simple_strtoul(name + 3, NULL, 10);
+
+	dev = eth_devices;
+	do {
+		if (dev->index == index) {
+			switch (op) {
+			case env_op_create:
+			case env_op_overwrite:
+				eth_parse_enetaddr(value, dev->enetaddr);
+				break;
+			case env_op_delete:
+				memset(dev->enetaddr, 0, 6);
+			}
+		}
+	} while (dev != eth_devices);
+
+	return 0;
+}
+U_BOOT_ENV_CALLBACK(ethaddr, on_ethaddr);
+
 int eth_write_hwaddr(struct eth_device *dev, const char *base_name,
 		   int eth_number)
 {
@@ -811,25 +860,13 @@ u32 ether_crc(size_t len, unsigned char const *p)
 
 int eth_init(void)
 {
-	struct eth_device *old_current, *dev;
+	struct eth_device *old_current;
 
 	if (!eth_current) {
 		puts("No ethernet found.\n");
 		return -ENODEV;
 	}
 
-	/* Sync environment with network devices */
-	dev = eth_devices;
-	do {
-		uchar env_enetaddr[6];
-
-		if (eth_getenv_enetaddr_by_index("eth", dev->index,
-						 env_enetaddr))
-			memcpy(dev->enetaddr, env_enetaddr, 6);
-
-		dev = dev->next;
-	} while (dev != eth_devices);
-
 	old_current = eth_current;
 	do {
 		debug("Trying %s\n", eth_current->name);
-- 
1.7.11.5



More information about the U-Boot mailing list