]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - net/eth.c
karo: tx6: configure all pads with explicit pad_ctl values
[karo-tx-uboot.git] / net / eth.c
index 8e6acfef89c25170f79728aad5e1ab3c9d7445b4..d3ec8d64d596d3a8e51336617b8de0032c87812b 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;
 
@@ -60,16 +62,6 @@ static inline int eth_setenv_enetaddr_by_index(const char *base_name, int index,
        return eth_setenv_enetaddr(enetvar, enetaddr);
 }
 
-static void eth_env_init(void)
-{
-       const char *s;
-
-       s = getenv("bootfile");
-       if (s != NULL)
-               copy_filename(net_boot_file_name, s,
-                             sizeof(net_boot_file_name));
-}
-
 static int eth_mac_skip(int index)
 {
        char enetvar[15];
@@ -104,8 +96,6 @@ static void eth_common_init(void)
        phy_init();
 #endif
 
-       eth_env_init();
-
        /*
         * If board-specific initialization exists, call it.
         * If not, call a CPU-specific one
@@ -281,6 +271,64 @@ int eth_get_dev_index(void)
        return -1;
 }
 
+static int eth_write_hwaddr(struct udevice *dev)
+{
+       struct eth_pdata *pdata = dev->platdata;
+       int ret = 0;
+
+       if (!dev || !device_active(dev))
+               return -EINVAL;
+
+       /* seq is valid since the device is active */
+       if (eth_get_ops(dev)->write_hwaddr && !eth_mac_skip(dev->seq)) {
+               if (!is_valid_ethaddr(pdata->enetaddr)) {
+                       printf("\nError: %s address %pM illegal value\n",
+                              dev->name, pdata->enetaddr);
+                       return -EINVAL;
+               }
+
+               /*
+                * Drivers are allowed to decide not to implement this at
+                * run-time. E.g. Some devices may use it and some may not.
+                */
+               ret = eth_get_ops(dev)->write_hwaddr(dev);
+               if (ret == -ENOSYS)
+                       ret = 0;
+               if (ret)
+                       printf("\nWarning: %s failed to set MAC address\n",
+                              dev->name);
+       }
+
+       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;
@@ -298,16 +346,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 =
@@ -372,6 +410,7 @@ int eth_rx(void)
 {
        struct udevice *current;
        uchar *packet;
+       int flags;
        int ret;
        int i;
 
@@ -383,8 +422,10 @@ int eth_rx(void)
                return -EINVAL;
 
        /* Process up to 32 packets at one time */
+       flags = ETH_RECV_CHECK_DEVICE;
        for (i = 0; i < 32; i++) {
-               ret = eth_get_ops(current)->recv(current, &packet);
+               ret = eth_get_ops(current)->recv(current, flags, &packet);
+               flags = 0;
                if (ret > 0)
                        net_process_received_packet(packet, ret);
                if (ret >= 0 && eth_get_ops(current)->free_pkt)
@@ -401,31 +442,6 @@ int eth_rx(void)
        return ret;
 }
 
-static int eth_write_hwaddr(struct udevice *dev)
-{
-       struct eth_pdata *pdata = dev->platdata;
-       int ret = 0;
-
-       if (!dev || !device_active(dev))
-               return -EINVAL;
-
-       /* seq is valid since the device is active */
-       if (eth_get_ops(dev)->write_hwaddr && !eth_mac_skip(dev->seq)) {
-               if (!is_valid_ethaddr(pdata->enetaddr)) {
-                       printf("\nError: %s address %pM illegal value\n",
-                              dev->name, pdata->enetaddr);
-                       return -EINVAL;
-               }
-
-               ret = eth_get_ops(dev)->write_hwaddr(dev);
-               if (ret)
-                       printf("\nWarning: %s failed to set MAC address\n",
-                              dev->name);
-       }
-
-       return ret;
-}
-
 int eth_initialize(void)
 {
        int num_devices = 0;
@@ -529,9 +545,15 @@ static int eth_post_probe(struct udevice *dev)
                printf("\nWarning: %s using MAC address from ROM\n",
                       dev->name);
        } else if (is_zero_ethaddr(pdata->enetaddr)) {
+#ifdef CONFIG_NET_RANDOM_ETHADDR
+               net_random_ethaddr(pdata->enetaddr);
+               printf("\nWarning: %s (eth%d) using random MAC address - %pM\n",
+                      dev->name, dev->seq, pdata->enetaddr);
+#else
                printf("\nError: %s address not set.\n",
                       dev->name);
                return -EINVAL;
+#endif
        }
 
        return 0;
@@ -631,6 +653,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)
 {
@@ -657,9 +709,15 @@ int eth_write_hwaddr(struct eth_device *dev, const char *base_name,
                printf("\nWarning: %s using MAC address from net device\n",
                       dev->name);
        } else if (is_zero_ethaddr(dev->enetaddr)) {
+#ifdef CONFIG_NET_RANDOM_ETHADDR
+               net_random_ethaddr(dev->enetaddr);
+               printf("\nWarning: %s (eth%d) using random MAC address - %pM\n",
+                      dev->name, eth_number, dev->enetaddr);
+#else
                printf("\nError: %s address not set.\n",
                       dev->name);
                return -EINVAL;
+#endif
        }
 
        if (dev->write_hwaddr && !eth_mac_skip(eth_number)) {
@@ -823,25 +881,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);