X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=net%2Feth-uclass.c;h=7f89f65c92a3ad4ac1bcc61b23044c050631b205;hb=361377dbdbc9f0f59b954248a696ad46ad5036b7;hp=fa3f5497a2902577f2bbb84947d918836b7bcbab;hpb=406fd7e207d3593f150079514a371dccdc651ce7;p=oweals%2Fu-boot.git diff --git a/net/eth-uclass.c b/net/eth-uclass.c index fa3f5497a2..7f89f65c92 100644 --- a/net/eth-uclass.c +++ b/net/eth-uclass.c @@ -6,12 +6,16 @@ */ #include +#include #include -#include +#include +#include #include #include #include +#include #include "eth_internal.h" +#include DECLARE_GLOBAL_DATA_PTR; @@ -39,8 +43,12 @@ static int eth_errno; static struct eth_uclass_priv *eth_get_uclass_priv(void) { struct uclass *uc; + int ret; + + ret = uclass_get(UCLASS_ETH, &uc); + if (ret) + return NULL; - uclass_get(UCLASS_ETH, &uc); assert(uc); return uc->priv; } @@ -101,6 +109,7 @@ struct udevice *eth_get_dev_by_name(const char *devname) struct udevice *it; struct uclass *uc; int len = strlen("eth"); + int ret; /* Must be longer than 3 to be an alias */ if (!strncmp(devname, "eth", len) && strlen(devname) > len) { @@ -108,7 +117,10 @@ struct udevice *eth_get_dev_by_name(const char *devname) seq = simple_strtoul(startp, &endp, 10); } - uclass_get(UCLASS_ETH, &uc); + ret = uclass_get(UCLASS_ETH, &uc); + if (ret) + return NULL; + uclass_foreach_dev(it, uc) { /* * We need the seq to be valid, so try to probe it. @@ -226,7 +238,7 @@ 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: @@ -312,7 +324,8 @@ void eth_halt(void) 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) @@ -343,6 +356,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; } @@ -414,20 +431,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); + if (dev->seq != -1) + num_devices++; uclass_next_device_check(&dev); - num_devices++; } while (dev); + if (!num_devices) + printf("No ethernet found.\n"); putc('\n'); } @@ -442,6 +464,10 @@ static int eth_post_bind(struct udevice *dev) return -EINVAL; } +#ifdef CONFIG_DM_ETH_PHY + eth_phy_binds_nodes(dev); +#endif + return 0; } @@ -454,11 +480,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[ARP_HLEN]; + char *source = "DT"; #if defined(CONFIG_NEEDS_MANUAL_RELOC) struct eth_ops *ops = eth_get_ops(dev); @@ -475,10 +522,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) @@ -490,9 +535,14 @@ 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_env_get_enetaddr_by_index("eth", dev->seq, env_enetaddr); if (!is_zero_ethaddr(env_enetaddr)) { @@ -500,9 +550,9 @@ static int eth_post_probe(struct udevice *dev) memcmp(pdata->enetaddr, env_enetaddr, ARP_HLEN)) { printf("\nWarning: %s MAC addresses don't match:\n", dev->name); - printf("Address in ROM 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); } @@ -510,8 +560,8 @@ static int eth_post_probe(struct udevice *dev) memcpy(pdata->enetaddr, env_enetaddr, ARP_HLEN); } else if (is_valid_ethaddr(pdata->enetaddr)) { eth_env_set_enetaddr_by_index("eth", dev->seq, pdata->enetaddr); - printf("\nWarning: %s using MAC address from ROM\n", - dev->name); + 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 @@ -525,6 +575,8 @@ static int eth_post_probe(struct udevice *dev) #endif } + eth_write_hwaddr(dev); + return 0; }