net: Handle ethaddr changes as an env callback
authorJoe Hershberger <joe.hershberger@ni.com>
Wed, 20 May 2015 19:27:26 +0000 (14:27 -0500)
committerTom Rini <trini@konsulko.com>
Thu, 21 May 2015 13:16:16 +0000 (09:16 -0400)
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@ni.com>
include/env_callback.h
net/Kconfig
net/eth.c

index 91f3cc013c5c02f569ed713d758cfd6bff67aca3..ab5d42dd8138be17f02ac4ad304127d55d16ea22 100644 (file)
@@ -52,7 +52,8 @@
        "serverip:serverip," \
        "nvlan:nvlan," \
        "vlan:vlan," \
-       DNS_CALLBACK
+       DNS_CALLBACK \
+       "eth\\d?addr:ethaddr,"
 #else
 #define NET_CALLBACKS
 #endif
index a2bd4fe580b0063914ee37ebedad55a74663f4d1..524b7e4da23b838033521cdee470864c117f572d 100644 (file)
@@ -4,6 +4,7 @@
 
 menuconfig NET
        bool "Networking support"
+       select REGEX
 
 if NET
 
index a40abb5f949dd36d721342afe4eca4f0d3246296..953b7310bd5cf66362bf04534a552b08eaa3c830 100644 (file)
--- 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;
 
@@ -294,6 +296,33 @@ static int eth_write_hwaddr(struct udevice *dev)
        return ret;
 }
 
+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;
@@ -311,25 +340,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;
-                       int enetaddr_changed = 0;
-
-                       /* Sync environment with network device */
-                       if (eth_getenv_enetaddr_by_index("eth", current->seq,
-                                                        env_enetaddr)) {
-                               enetaddr_changed = memcmp(pdata->enetaddr,
-                                       env_enetaddr, 6);
-                               memcpy(pdata->enetaddr, env_enetaddr, 6);
-                       } else {
-                               memset(env_enetaddr, 0, 6);
-                               enetaddr_changed = memcmp(pdata->enetaddr,
-                                       env_enetaddr, 6);
-                               memset(pdata->enetaddr, 0, 6);
-                       }
-                       if (enetaddr_changed)
-                               eth_write_hwaddr(current);
-
                        ret = eth_get_ops(current)->start(current);
                        if (ret >= 0) {
                                struct eth_device_priv *priv =
@@ -634,6 +644,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)
 {
@@ -832,36 +872,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];
-               int enetaddr_changed = 0;
-
-               if (eth_getenv_enetaddr_by_index("eth", dev->index,
-                                                env_enetaddr)) {
-                       enetaddr_changed = memcmp(dev->enetaddr,
-                               env_enetaddr, 6);
-                       memcpy(dev->enetaddr, env_enetaddr, 6);
-               } else {
-                       memset(env_enetaddr, 0, 6);
-                       enetaddr_changed = memcmp(dev->enetaddr,
-                               env_enetaddr, 6);
-                       memset(dev->enetaddr, 0, 6);
-               }
-               if (enetaddr_changed)
-                       eth_write_hwaddr(dev, "eth", dev->index);
-
-               dev = dev->next;
-       } while (dev != eth_devices);
-
        old_current = eth_current;
        do {
                debug("Trying %s\n", eth_current->name);