Merge branch 'master' of https://gitlab.denx.de/u-boot/custodians/u-boot-spi
[oweals/u-boot.git] / net / eth-uclass.c
index d30b04ba862a8b90d370b97116a7683c1d752f36..031d55862583703d43ed33431dcacfe41424a1f9 100644 (file)
@@ -1,9 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * (C) Copyright 2001-2015
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  * Joe Hershberger, National Instruments
- *
- * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
@@ -308,12 +307,13 @@ void eth_halt(void)
        struct eth_device_priv *priv;
 
        current = eth_get_dev();
-       if (!current || !device_active(current))
+       if (!current || !eth_is_active(current))
                return;
 
        eth_get_ops(current)->stop(current);
        priv = current->uclass_priv;
-       priv->state = ETH_STATE_PASSIVE;
+       if (priv)
+               priv->state = ETH_STATE_PASSIVE;
 }
 
 int eth_is_active(struct udevice *dev)
@@ -336,7 +336,7 @@ int eth_send(void *packet, int length)
        if (!current)
                return -ENODEV;
 
-       if (!device_active(current))
+       if (!eth_is_active(current))
                return -EINVAL;
 
        ret = eth_get_ops(current)->send(current, packet, length);
@@ -359,7 +359,7 @@ int eth_rx(void)
        if (!current)
                return -ENODEV;
 
-       if (!device_active(current))
+       if (!eth_is_active(current))
                return -EINVAL;
 
        /* Process up to 32 packets at one time */
@@ -396,7 +396,7 @@ int eth_initialize(void)
         * This is accomplished by attempting to probe each device and calling
         * their write_hwaddr() operation.
         */
-       uclass_first_device(UCLASS_ETH, &dev);
+       uclass_first_device_check(UCLASS_ETH, &dev);
        if (!dev) {
                printf("No ethernet found.\n");
                bootstage_error(BOOTSTAGE_ID_NET_ETH_START);
@@ -425,7 +425,7 @@ int eth_initialize(void)
 
                        eth_write_hwaddr(dev);
 
-                       uclass_next_device(&dev);
+                       uclass_next_device_check(&dev);
                        num_devices++;
                } while (dev);
 
@@ -455,6 +455,26 @@ static int eth_pre_unbind(struct udevice *dev)
        return 0;
 }
 
+static bool eth_dev_get_mac_address(struct udevice *dev, u8 mac[ARP_HLEN])
+{
+#if IS_ENABLED(CONFIG_OF_CONTROL)
+       const uint8_t *p;
+
+       p = dev_read_u8_array_ptr(dev, "mac-address", ARP_HLEN);
+       if (!p)
+               p = dev_read_u8_array_ptr(dev, "local-mac-address", ARP_HLEN);
+
+       if (!p)
+               return false;
+
+       memcpy(mac, p, ARP_HLEN);
+
+       return true;
+#else
+       return false;
+#endif
+}
+
 static int eth_post_probe(struct udevice *dev)
 {
        struct eth_device_priv *priv = dev->uclass_priv;
@@ -476,10 +496,8 @@ static int eth_post_probe(struct udevice *dev)
                        ops->free_pkt += gd->reloc_off;
                if (ops->stop)
                        ops->stop += gd->reloc_off;
-#ifdef CONFIG_MCAST_TFTP
                if (ops->mcast)
                        ops->mcast += gd->reloc_off;
-#endif
                if (ops->write_hwaddr)
                        ops->write_hwaddr += gd->reloc_off;
                if (ops->read_rom_hwaddr)
@@ -491,9 +509,13 @@ static int eth_post_probe(struct udevice *dev)
 
        priv->state = ETH_STATE_INIT;
 
-       /* Check if the device has a MAC address in ROM */
-       if (eth_get_ops(dev)->read_rom_hwaddr)
-               eth_get_ops(dev)->read_rom_hwaddr(dev);
+       /* Check if the device has a valid MAC address in device tree */
+       if (!eth_dev_get_mac_address(dev, pdata->enetaddr) ||
+           !is_valid_ethaddr(pdata->enetaddr)) {
+               /* Check if the device has a MAC address in ROM */
+               if (eth_get_ops(dev)->read_rom_hwaddr)
+                       eth_get_ops(dev)->read_rom_hwaddr(dev);
+       }
 
        eth_env_get_enetaddr_by_index("eth", dev->seq, env_enetaddr);
        if (!is_zero_ethaddr(env_enetaddr)) {
@@ -526,6 +548,8 @@ static int eth_post_probe(struct udevice *dev)
 #endif
        }
 
+       eth_write_hwaddr(dev);
+
        return 0;
 }