X-Git-Url: https://git.librecmc.org/?p=oweals%2Fu-boot.git;a=blobdiff_plain;f=net%2Feth-uclass.c;h=8bf2eabe9026df405825ddf3b78aedf5d417f94b;hp=a356a088262d333e578d5723f6d680db0da2d466;hb=b77d0292ca9f3ca69259dca7e2c5e193a403b289;hpb=161b1fe745394f34c4aa506edc964089785919f6 diff --git a/net/eth-uclass.c b/net/eth-uclass.c index a356a08826..8bf2eabe90 100644 --- a/net/eth-uclass.c +++ b/net/eth-uclass.c @@ -1,19 +1,21 @@ +// 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 #include -#include +#include #include #include #include +#include #include "eth_internal.h" +DECLARE_GLOBAL_DATA_PTR; + /** * struct eth_device_priv - private structure for each Ethernet device * @@ -179,7 +181,7 @@ int eth_get_dev_index(void) static int eth_write_hwaddr(struct udevice *dev) { - struct eth_pdata *pdata = dev->platdata; + struct eth_pdata *pdata; int ret = 0; if (!dev || !device_active(dev)) @@ -187,6 +189,7 @@ static int eth_write_hwaddr(struct udevice *dev) /* seq is valid since the device is active */ if (eth_get_ops(dev)->write_hwaddr && !eth_mac_skip(dev->seq)) { + pdata = dev->platdata; if (!is_valid_ethaddr(pdata->enetaddr)) { printf("\nError: %s address %pM illegal value\n", dev->name, pdata->enetaddr); @@ -224,10 +227,11 @@ static int on_ethaddr(const char *name, const char *value, enum env_op op, switch (op) { case env_op_create: case env_op_overwrite: - eth_parse_enetaddr(value, pdata->enetaddr); + string_to_enetaddr(value, pdata->enetaddr); + eth_write_hwaddr(dev); break; case env_op_delete: - memset(pdata->enetaddr, 0, 6); + memset(pdata->enetaddr, 0, ARP_HLEN); } } @@ -237,8 +241,8 @@ U_BOOT_ENV_CALLBACK(ethaddr, on_ethaddr); int eth_init(void) { - char *ethact = getenv("ethact"); - char *ethrotate = getenv("ethrotate"); + char *ethact = env_get("ethact"); + char *ethrotate = env_get("ethrotate"); struct udevice *current = NULL; struct udevice *old_current; int ret = -ENODEV; @@ -304,12 +308,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) @@ -332,7 +337,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); @@ -340,6 +345,10 @@ int eth_send(void *packet, int length) /* We cannot completely return the error at present */ debug("%s: send() returned error %d\n", __func__, ret); } +#if defined(CONFIG_CMD_PCAP) + if (ret >= 0) + pcap_post(packet, length, true); +#endif return ret; } @@ -355,7 +364,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 */ @@ -392,12 +401,12 @@ 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); } else { - char *ethprime = getenv("ethprime"); + char *ethprime = env_get("ethprime"); struct udevice *prime_dev = NULL; if (ethprime) @@ -411,20 +420,25 @@ int eth_initialize(void) bootstage_mark(BOOTSTAGE_ID_NET_ETH_INIT); do { - if (num_devices) - printf(", "); + if (dev->seq != -1) { + if (num_devices) + printf(", "); - printf("eth%d: %s", dev->seq, dev->name); + printf("eth%d: %s", dev->seq, dev->name); - if (ethprime && dev == prime_dev) - printf(" [PRIME]"); + if (ethprime && dev == prime_dev) + printf(" [PRIME]"); + } eth_write_hwaddr(dev); - uclass_next_device(&dev); - num_devices++; + if (dev->seq != -1) + num_devices++; + uclass_next_device_check(&dev); } while (dev); + if (!num_devices) + printf("No ethernet found.\n"); putc('\n'); } @@ -451,11 +465,32 @@ 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; struct eth_pdata *pdata = dev->platdata; - unsigned char env_enetaddr[6]; + unsigned char env_enetaddr[ARP_HLEN]; + char *source = "DT"; #if defined(CONFIG_NEEDS_MANUAL_RELOC) struct eth_ops *ops = eth_get_ops(dev); @@ -472,10 +507,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) @@ -487,29 +520,35 @@ 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)) { + source = "ROM"; + /* 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_getenv_enetaddr_by_index("eth", dev->seq, env_enetaddr); + eth_env_get_enetaddr_by_index("eth", dev->seq, env_enetaddr); if (!is_zero_ethaddr(env_enetaddr)) { if (!is_zero_ethaddr(pdata->enetaddr) && - memcmp(pdata->enetaddr, env_enetaddr, 6)) { + memcmp(pdata->enetaddr, env_enetaddr, ARP_HLEN)) { printf("\nWarning: %s MAC addresses don't match:\n", dev->name); - printf("Address in SROM is %pM\n", - pdata->enetaddr); - printf("Address in environment is %pM\n", + printf("Address in %s is\t\t%pM\n", + source, pdata->enetaddr); + printf("Address in environment is\t%pM\n", env_enetaddr); } /* Override the ROM MAC address */ - memcpy(pdata->enetaddr, env_enetaddr, 6); + memcpy(pdata->enetaddr, env_enetaddr, ARP_HLEN); } else if (is_valid_ethaddr(pdata->enetaddr)) { - eth_setenv_enetaddr_by_index("eth", dev->seq, pdata->enetaddr); - printf("\nWarning: %s using MAC address from ROM\n", - dev->name); - } else if (is_zero_ethaddr(pdata->enetaddr)) { + eth_env_set_enetaddr_by_index("eth", dev->seq, pdata->enetaddr); + printf("\nWarning: %s using MAC address from %s\n", + dev->name, source); + } else if (is_zero_ethaddr(pdata->enetaddr) || + !is_valid_ethaddr(pdata->enetaddr)) { #ifdef CONFIG_NET_RANDOM_ETHADDR net_random_ethaddr(pdata->enetaddr); printf("\nWarning: %s (eth%d) using random MAC address - %pM\n", @@ -521,6 +560,8 @@ static int eth_post_probe(struct udevice *dev) #endif } + eth_write_hwaddr(dev); + return 0; } @@ -531,7 +572,7 @@ static int eth_pre_remove(struct udevice *dev) eth_get_ops(dev)->stop(dev); /* clear the MAC address */ - memset(pdata->enetaddr, 0, 6); + memset(pdata->enetaddr, 0, ARP_HLEN); return 0; }