1 // SPDX-License-Identifier: GPL-2.0+
3 * (C) Copyright 2001-2015
4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5 * Joe Hershberger, National Instruments
14 #include <asm/global_data.h>
15 #include <dm/device-internal.h>
16 #include <dm/uclass-internal.h>
18 #include "eth_internal.h"
21 DECLARE_GLOBAL_DATA_PTR;
24 * struct eth_device_priv - private structure for each Ethernet device
26 * @state: The state of the Ethernet MAC driver (defined by enum eth_state_t)
28 struct eth_device_priv {
29 enum eth_state_t state;
34 * struct eth_uclass_priv - The structure attached to the uclass itself
36 * @current: The Ethernet device that the network functions are using
38 struct eth_uclass_priv {
39 struct udevice *current;
42 /* eth_errno - This stores the most recent failure code from DM functions */
45 static struct eth_uclass_priv *eth_get_uclass_priv(void)
50 ret = uclass_get(UCLASS_ETH, &uc);
55 return uclass_get_priv(uc);
58 void eth_set_current_to_next(void)
60 struct eth_uclass_priv *uc_priv;
62 uc_priv = eth_get_uclass_priv();
64 uclass_next_device(&uc_priv->current);
65 if (!uc_priv->current)
66 uclass_first_device(UCLASS_ETH, &uc_priv->current);
70 * Typically this will simply return the active device.
71 * In the case where the most recent active device was unset, this will attempt
72 * to return the first device. If that device doesn't exist or fails to probe,
73 * this function will return NULL.
75 struct udevice *eth_get_dev(void)
77 struct eth_uclass_priv *uc_priv;
79 uc_priv = eth_get_uclass_priv();
83 if (!uc_priv->current)
84 eth_errno = uclass_first_device(UCLASS_ETH,
86 return uc_priv->current;
90 * Typically this will just store a device pointer.
91 * In case it was not probed, we will attempt to do so.
92 * dev may be NULL to unset the active device.
94 void eth_set_dev(struct udevice *dev)
96 if (dev && !device_active(dev)) {
97 eth_errno = device_probe(dev);
102 eth_get_uclass_priv()->current = dev;
106 * Find the udevice that either has the name passed in as devname or has an
107 * alias named devname.
109 struct udevice *eth_get_dev_by_name(const char *devname)
113 const char *startp = NULL;
116 int len = strlen("eth");
119 /* Must be longer than 3 to be an alias */
120 if (!strncmp(devname, "eth", len) && strlen(devname) > len) {
121 startp = devname + len;
122 seq = simple_strtoul(startp, &endp, 10);
125 ret = uclass_get(UCLASS_ETH, &uc);
129 uclass_foreach_dev(it, uc) {
131 * We don't care about errors from probe here. Either they won't
132 * match an alias or it will match a literal name and we'll pick
133 * up the error when we try to probe again in eth_set_dev().
135 if (device_probe(it))
137 /* Check for the name or the sequence number to match */
138 if (strcmp(it->name, devname) == 0 ||
139 (endp > startp && dev_seq(it) == seq))
146 unsigned char *eth_get_ethaddr(void)
148 struct eth_pdata *pdata;
151 pdata = dev_get_plat(eth_get_dev());
152 return pdata->enetaddr;
158 /* Set active state without calling start on the driver */
159 int eth_init_state_only(void)
161 struct udevice *current;
162 struct eth_device_priv *priv;
164 current = eth_get_dev();
165 if (!current || !device_active(current))
168 priv = dev_get_uclass_priv(current);
169 priv->state = ETH_STATE_ACTIVE;
174 /* Set passive state without calling stop on the driver */
175 void eth_halt_state_only(void)
177 struct udevice *current;
178 struct eth_device_priv *priv;
180 current = eth_get_dev();
181 if (!current || !device_active(current))
184 priv = dev_get_uclass_priv(current);
185 priv->state = ETH_STATE_PASSIVE;
188 int eth_get_dev_index(void)
191 return dev_seq(eth_get_dev());
195 static int eth_write_hwaddr(struct udevice *dev)
197 struct eth_pdata *pdata;
200 if (!dev || !device_active(dev))
203 /* seq is valid since the device is active */
204 if (eth_get_ops(dev)->write_hwaddr && !eth_mac_skip(dev_seq(dev))) {
205 pdata = dev_get_plat(dev);
206 if (!is_valid_ethaddr(pdata->enetaddr)) {
207 printf("\nError: %s address %pM illegal value\n",
208 dev->name, pdata->enetaddr);
213 * Drivers are allowed to decide not to implement this at
214 * run-time. E.g. Some devices may use it and some may not.
216 ret = eth_get_ops(dev)->write_hwaddr(dev);
220 printf("\nWarning: %s failed to set MAC address\n",
227 static int on_ethaddr(const char *name, const char *value, enum env_op op,
234 /* look for an index after "eth" */
235 index = simple_strtoul(name + 3, NULL, 10);
237 retval = uclass_find_device_by_seq(UCLASS_ETH, index, &dev);
239 struct eth_pdata *pdata = dev_get_plat(dev);
242 case env_op_overwrite:
243 string_to_enetaddr(value, pdata->enetaddr);
244 eth_write_hwaddr(dev);
247 memset(pdata->enetaddr, 0, ARP_HLEN);
253 U_BOOT_ENV_CALLBACK(ethaddr, on_ethaddr);
257 char *ethact = env_get("ethact");
258 char *ethrotate = env_get("ethrotate");
259 struct udevice *current = NULL;
260 struct udevice *old_current;
264 * When 'ethrotate' variable is set to 'no' and 'ethact' variable
265 * is already set to an ethernet device, we should stick to 'ethact'.
267 if ((ethrotate != NULL) && (strcmp(ethrotate, "no") == 0)) {
269 current = eth_get_dev_by_name(ethact);
276 current = eth_get_dev();
278 log_err("No ethernet found.\n");
283 old_current = current;
286 debug("Trying %s\n", current->name);
288 if (device_active(current)) {
289 ret = eth_get_ops(current)->start(current);
291 struct eth_device_priv *priv =
292 dev_get_uclass_priv(current);
294 priv->state = ETH_STATE_ACTIVE;
295 priv->running = true;
304 debug("PROBE FAIL\n");
308 * If ethrotate is enabled, this will change "current",
309 * otherwise we will drop out of this while loop immediately
312 /* This will ensure the new "current" attempted to probe */
313 current = eth_get_dev();
314 } while (old_current != current);
321 struct udevice *current;
322 struct eth_device_priv *priv;
324 current = eth_get_dev();
328 priv = dev_get_uclass_priv(current);
329 if (!priv || !priv->running)
332 eth_get_ops(current)->stop(current);
333 priv->state = ETH_STATE_PASSIVE;
334 priv->running = false;
337 int eth_is_active(struct udevice *dev)
339 struct eth_device_priv *priv;
341 if (!dev || !device_active(dev))
344 priv = dev_get_uclass_priv(dev);
345 return priv->state == ETH_STATE_ACTIVE;
348 int eth_send(void *packet, int length)
350 struct udevice *current;
353 current = eth_get_dev();
357 if (!eth_is_active(current))
360 ret = eth_get_ops(current)->send(current, packet, length);
362 /* We cannot completely return the error at present */
363 debug("%s: send() returned error %d\n", __func__, ret);
365 #if defined(CONFIG_CMD_PCAP)
367 pcap_post(packet, length, true);
374 struct udevice *current;
380 current = eth_get_dev();
384 if (!eth_is_active(current))
387 /* Process up to 32 packets at one time */
388 flags = ETH_RECV_CHECK_DEVICE;
389 for (i = 0; i < ETH_PACKETS_BATCH_RECV; i++) {
390 ret = eth_get_ops(current)->recv(current, flags, &packet);
393 net_process_received_packet(packet, ret);
394 if (ret >= 0 && eth_get_ops(current)->free_pkt)
395 eth_get_ops(current)->free_pkt(current, packet, ret);
402 /* We cannot completely return the error at present */
403 debug("%s: recv() returned error %d\n", __func__, ret);
408 int eth_initialize(void)
416 * Devices need to write the hwaddr even if not started so that Linux
417 * will have access to the hwaddr that u-boot stored for the device.
418 * This is accomplished by attempting to probe each device and calling
419 * their write_hwaddr() operation.
421 uclass_first_device_check(UCLASS_ETH, &dev);
423 log_err("No ethernet found.\n");
424 bootstage_error(BOOTSTAGE_ID_NET_ETH_START);
426 char *ethprime = env_get("ethprime");
427 struct udevice *prime_dev = NULL;
430 prime_dev = eth_get_dev_by_name(ethprime);
432 eth_set_dev(prime_dev);
433 eth_current_changed();
438 bootstage_mark(BOOTSTAGE_ID_NET_ETH_INIT);
440 if (device_active(dev)) {
444 printf("eth%d: %s", dev_seq(dev), dev->name);
446 if (ethprime && dev == prime_dev)
450 eth_write_hwaddr(dev);
452 if (device_active(dev))
454 uclass_next_device_check(&dev);
458 log_err("No ethernet found.\n");
465 static int eth_post_bind(struct udevice *dev)
467 if (strchr(dev->name, ' ')) {
468 printf("\nError: eth device name \"%s\" has a space!\n",
473 #ifdef CONFIG_DM_ETH_PHY
474 eth_phy_binds_nodes(dev);
480 static int eth_pre_unbind(struct udevice *dev)
482 /* Don't hang onto a pointer that is going away */
483 if (dev == eth_get_uclass_priv()->current)
489 static bool eth_dev_get_mac_address(struct udevice *dev, u8 mac[ARP_HLEN])
491 #if CONFIG_IS_ENABLED(OF_CONTROL)
494 p = dev_read_u8_array_ptr(dev, "mac-address", ARP_HLEN);
496 p = dev_read_u8_array_ptr(dev, "local-mac-address", ARP_HLEN);
501 memcpy(mac, p, ARP_HLEN);
509 static int eth_post_probe(struct udevice *dev)
511 struct eth_device_priv *priv = dev_get_uclass_priv(dev);
512 struct eth_pdata *pdata = dev_get_plat(dev);
513 unsigned char env_enetaddr[ARP_HLEN];
516 #if defined(CONFIG_NEEDS_MANUAL_RELOC)
517 struct eth_ops *ops = eth_get_ops(dev);
518 static int reloc_done;
522 ops->start += gd->reloc_off;
524 ops->send += gd->reloc_off;
526 ops->recv += gd->reloc_off;
528 ops->free_pkt += gd->reloc_off;
530 ops->stop += gd->reloc_off;
532 ops->mcast += gd->reloc_off;
533 if (ops->write_hwaddr)
534 ops->write_hwaddr += gd->reloc_off;
535 if (ops->read_rom_hwaddr)
536 ops->read_rom_hwaddr += gd->reloc_off;
542 priv->state = ETH_STATE_INIT;
543 priv->running = false;
545 /* Check if the device has a valid MAC address in device tree */
546 if (!eth_dev_get_mac_address(dev, pdata->enetaddr) ||
547 !is_valid_ethaddr(pdata->enetaddr)) {
549 /* Check if the device has a MAC address in ROM */
550 if (eth_get_ops(dev)->read_rom_hwaddr)
551 eth_get_ops(dev)->read_rom_hwaddr(dev);
554 eth_env_get_enetaddr_by_index("eth", dev_seq(dev), env_enetaddr);
555 if (!is_zero_ethaddr(env_enetaddr)) {
556 if (!is_zero_ethaddr(pdata->enetaddr) &&
557 memcmp(pdata->enetaddr, env_enetaddr, ARP_HLEN)) {
558 printf("\nWarning: %s MAC addresses don't match:\n",
560 printf("Address in %s is\t\t%pM\n",
561 source, pdata->enetaddr);
562 printf("Address in environment is\t%pM\n",
566 /* Override the ROM MAC address */
567 memcpy(pdata->enetaddr, env_enetaddr, ARP_HLEN);
568 } else if (is_valid_ethaddr(pdata->enetaddr)) {
569 eth_env_set_enetaddr_by_index("eth", dev_seq(dev),
571 } else if (is_zero_ethaddr(pdata->enetaddr) ||
572 !is_valid_ethaddr(pdata->enetaddr)) {
573 #ifdef CONFIG_NET_RANDOM_ETHADDR
574 net_random_ethaddr(pdata->enetaddr);
575 printf("\nWarning: %s (eth%d) using random MAC address - %pM\n",
576 dev->name, dev_seq(dev), pdata->enetaddr);
578 printf("\nError: %s address not set.\n",
584 eth_write_hwaddr(dev);
589 static int eth_pre_remove(struct udevice *dev)
591 struct eth_pdata *pdata = dev_get_plat(dev);
593 eth_get_ops(dev)->stop(dev);
595 /* clear the MAC address */
596 memset(pdata->enetaddr, 0, ARP_HLEN);
601 UCLASS_DRIVER(eth) = {
604 .post_bind = eth_post_bind,
605 .pre_unbind = eth_pre_unbind,
606 .post_probe = eth_post_probe,
607 .pre_remove = eth_pre_remove,
608 .priv_auto = sizeof(struct eth_uclass_priv),
609 .per_device_auto = sizeof(struct eth_device_priv),
610 .flags = DM_UC_FLAG_SEQ_ALIAS,