1 /*
2  * (C) Copyright 2001-2015
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  * Joe Hershberger, National Instruments
5  *
6  * SPDX-License-Identifier:	GPL-2.0+
7  */
8 
9 #include <common.h>
10 #include <command.h>
11 #include <dm.h>
12 #include <environment.h>
13 #include <net.h>
14 #include <miiphy.h>
15 #include <phy.h>
16 #include <asm/errno.h>
17 #include <dm/device-internal.h>
18 #include <dm/uclass-internal.h>
19 
20 DECLARE_GLOBAL_DATA_PTR;
21 
eth_parse_enetaddr(const char * addr,uchar * enetaddr)22 void eth_parse_enetaddr(const char *addr, uchar *enetaddr)
23 {
24 	char *end;
25 	int i;
26 
27 	for (i = 0; i < 6; ++i) {
28 		enetaddr[i] = addr ? simple_strtoul(addr, &end, 16) : 0;
29 		if (addr)
30 			addr = (*end) ? end + 1 : end;
31 	}
32 }
33 
eth_getenv_enetaddr(char * name,uchar * enetaddr)34 int eth_getenv_enetaddr(char *name, uchar *enetaddr)
35 {
36 	eth_parse_enetaddr(getenv(name), enetaddr);
37 	return is_valid_ethaddr(enetaddr);
38 }
39 
eth_setenv_enetaddr(char * name,const uchar * enetaddr)40 int eth_setenv_enetaddr(char *name, const uchar *enetaddr)
41 {
42 	char buf[20];
43 
44 	sprintf(buf, "%pM", enetaddr);
45 
46 	return setenv(name, buf);
47 }
48 
eth_getenv_enetaddr_by_index(const char * base_name,int index,uchar * enetaddr)49 int eth_getenv_enetaddr_by_index(const char *base_name, int index,
50 				 uchar *enetaddr)
51 {
52 	char enetvar[32];
53 	sprintf(enetvar, index ? "%s%daddr" : "%saddr", base_name, index);
54 	return eth_getenv_enetaddr(enetvar, enetaddr);
55 }
56 
eth_setenv_enetaddr_by_index(const char * base_name,int index,uchar * enetaddr)57 static inline int eth_setenv_enetaddr_by_index(const char *base_name, int index,
58 				 uchar *enetaddr)
59 {
60 	char enetvar[32];
61 	sprintf(enetvar, index ? "%s%daddr" : "%saddr", base_name, index);
62 	return eth_setenv_enetaddr(enetvar, enetaddr);
63 }
64 
eth_mac_skip(int index)65 static int eth_mac_skip(int index)
66 {
67 	char enetvar[15];
68 	char *skip_state;
69 
70 	sprintf(enetvar, index ? "eth%dmacskip" : "ethmacskip", index);
71 	skip_state = getenv(enetvar);
72 	return skip_state != NULL;
73 }
74 
75 static void eth_current_changed(void);
76 
77 /*
78  * CPU and board-specific Ethernet initializations.  Aliased function
79  * signals caller to move on
80  */
__def_eth_init(bd_t * bis)81 static int __def_eth_init(bd_t *bis)
82 {
83 	return -1;
84 }
85 int cpu_eth_init(bd_t *bis) __attribute__((weak, alias("__def_eth_init")));
86 int board_eth_init(bd_t *bis) __attribute__((weak, alias("__def_eth_init")));
87 
eth_common_init(void)88 static void eth_common_init(void)
89 {
90 	bootstage_mark(BOOTSTAGE_ID_NET_ETH_START);
91 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB)
92 	miiphy_init();
93 #endif
94 
95 #ifdef CONFIG_PHYLIB
96 	phy_init();
97 #endif
98 
99 	/*
100 	 * If board-specific initialization exists, call it.
101 	 * If not, call a CPU-specific one
102 	 */
103 	if (board_eth_init != __def_eth_init) {
104 		if (board_eth_init(gd->bd) < 0)
105 			printf("Board Net Initialization Failed\n");
106 	} else if (cpu_eth_init != __def_eth_init) {
107 		if (cpu_eth_init(gd->bd) < 0)
108 			printf("CPU Net Initialization Failed\n");
109 	} else {
110 		printf("Net Initialization Skipped\n");
111 	}
112 }
113 
114 #ifdef CONFIG_DM_ETH
115 /**
116  * struct eth_device_priv - private structure for each Ethernet device
117  *
118  * @state: The state of the Ethernet MAC driver (defined by enum eth_state_t)
119  */
120 struct eth_device_priv {
121 	enum eth_state_t state;
122 };
123 
124 /**
125  * struct eth_uclass_priv - The structure attached to the uclass itself
126  *
127  * @current: The Ethernet device that the network functions are using
128  */
129 struct eth_uclass_priv {
130 	struct udevice *current;
131 };
132 
133 /* eth_errno - This stores the most recent failure code from DM functions */
134 static int eth_errno;
135 
eth_get_uclass_priv(void)136 static struct eth_uclass_priv *eth_get_uclass_priv(void)
137 {
138 	struct uclass *uc;
139 
140 	uclass_get(UCLASS_ETH, &uc);
141 	assert(uc);
142 	return uc->priv;
143 }
144 
eth_set_current_to_next(void)145 static void eth_set_current_to_next(void)
146 {
147 	struct eth_uclass_priv *uc_priv;
148 
149 	uc_priv = eth_get_uclass_priv();
150 	if (uc_priv->current)
151 		uclass_next_device(&uc_priv->current);
152 	if (!uc_priv->current)
153 		uclass_first_device(UCLASS_ETH, &uc_priv->current);
154 }
155 
156 /*
157  * Typically this will simply return the active device.
158  * In the case where the most recent active device was unset, this will attempt
159  * to return the first device. If that device doesn't exist or fails to probe,
160  * this function will return NULL.
161  */
eth_get_dev(void)162 struct udevice *eth_get_dev(void)
163 {
164 	struct eth_uclass_priv *uc_priv;
165 
166 	uc_priv = eth_get_uclass_priv();
167 	if (!uc_priv->current)
168 		eth_errno = uclass_first_device(UCLASS_ETH,
169 				    &uc_priv->current);
170 	return uc_priv->current;
171 }
172 
173 /*
174  * Typically this will just store a device pointer.
175  * In case it was not probed, we will attempt to do so.
176  * dev may be NULL to unset the active device.
177  */
eth_set_dev(struct udevice * dev)178 static void eth_set_dev(struct udevice *dev)
179 {
180 	if (dev && !device_active(dev))
181 		eth_errno = device_probe(dev);
182 	eth_get_uclass_priv()->current = dev;
183 }
184 
185 /*
186  * Find the udevice that either has the name passed in as devname or has an
187  * alias named devname.
188  */
eth_get_dev_by_name(const char * devname)189 struct udevice *eth_get_dev_by_name(const char *devname)
190 {
191 	int seq = -1;
192 	char *endp = NULL;
193 	const char *startp = NULL;
194 	struct udevice *it;
195 	struct uclass *uc;
196 
197 	/* Must be longer than 3 to be an alias */
198 	if (strlen(devname) > strlen("eth")) {
199 		startp = devname + strlen("eth");
200 		seq = simple_strtoul(startp, &endp, 10);
201 	}
202 
203 	uclass_get(UCLASS_ETH, &uc);
204 	uclass_foreach_dev(it, uc) {
205 		/*
206 		 * We need the seq to be valid, so try to probe it.
207 		 * If the probe fails, the seq will not match since it will be
208 		 * -1 instead of what we are looking for.
209 		 * We don't care about errors from probe here. Either they won't
210 		 * match an alias or it will match a literal name and we'll pick
211 		 * up the error when we try to probe again in eth_set_dev().
212 		 */
213 		device_probe(it);
214 		/*
215 		 * Check for the name or the sequence number to match
216 		 */
217 		if (strcmp(it->name, devname) == 0 ||
218 		    (endp > startp && it->seq == seq))
219 			return it;
220 	}
221 
222 	return NULL;
223 }
224 
eth_get_ethaddr(void)225 unsigned char *eth_get_ethaddr(void)
226 {
227 	struct eth_pdata *pdata;
228 
229 	if (eth_get_dev()) {
230 		pdata = eth_get_dev()->platdata;
231 		return pdata->enetaddr;
232 	}
233 
234 	return NULL;
235 }
236 
237 /* Set active state without calling start on the driver */
eth_init_state_only(void)238 int eth_init_state_only(void)
239 {
240 	struct udevice *current;
241 	struct eth_device_priv *priv;
242 
243 	current = eth_get_dev();
244 	if (!current || !device_active(current))
245 		return -EINVAL;
246 
247 	priv = current->uclass_priv;
248 	priv->state = ETH_STATE_ACTIVE;
249 
250 	return 0;
251 }
252 
253 /* Set passive state without calling stop on the driver */
eth_halt_state_only(void)254 void eth_halt_state_only(void)
255 {
256 	struct udevice *current;
257 	struct eth_device_priv *priv;
258 
259 	current = eth_get_dev();
260 	if (!current || !device_active(current))
261 		return;
262 
263 	priv = current->uclass_priv;
264 	priv->state = ETH_STATE_PASSIVE;
265 }
266 
eth_get_dev_index(void)267 int eth_get_dev_index(void)
268 {
269 	if (eth_get_dev())
270 		return eth_get_dev()->seq;
271 	return -1;
272 }
273 
eth_write_hwaddr(struct udevice * dev)274 static int eth_write_hwaddr(struct udevice *dev)
275 {
276 	struct eth_pdata *pdata = dev->platdata;
277 	int ret = 0;
278 
279 	if (!dev || !device_active(dev))
280 		return -EINVAL;
281 
282 	/* seq is valid since the device is active */
283 	if (eth_get_ops(dev)->write_hwaddr && !eth_mac_skip(dev->seq)) {
284 		if (!is_valid_ethaddr(pdata->enetaddr)) {
285 			printf("\nError: %s address %pM illegal value\n",
286 			       dev->name, pdata->enetaddr);
287 			return -EINVAL;
288 		}
289 
290 		ret = eth_get_ops(dev)->write_hwaddr(dev);
291 		if (ret)
292 			printf("\nWarning: %s failed to set MAC address\n",
293 			       dev->name);
294 	}
295 
296 	return ret;
297 }
298 
on_ethaddr(const char * name,const char * value,enum env_op op,int flags)299 static int on_ethaddr(const char *name, const char *value, enum env_op op,
300 	int flags)
301 {
302 	int index;
303 	int retval;
304 	struct udevice *dev;
305 
306 	/* look for an index after "eth" */
307 	index = simple_strtoul(name + 3, NULL, 10);
308 
309 	retval = uclass_find_device_by_seq(UCLASS_ETH, index, false, &dev);
310 	if (!retval) {
311 		struct eth_pdata *pdata = dev->platdata;
312 		switch (op) {
313 		case env_op_create:
314 		case env_op_overwrite:
315 			eth_parse_enetaddr(value, pdata->enetaddr);
316 			break;
317 		case env_op_delete:
318 			memset(pdata->enetaddr, 0, 6);
319 		}
320 	}
321 
322 	return 0;
323 }
324 U_BOOT_ENV_CALLBACK(ethaddr, on_ethaddr);
325 
eth_init(void)326 int eth_init(void)
327 {
328 	struct udevice *current;
329 	struct udevice *old_current;
330 	int ret = -ENODEV;
331 
332 	current = eth_get_dev();
333 	if (!current) {
334 		printf("No ethernet found.\n");
335 		return -ENODEV;
336 	}
337 
338 	old_current = current;
339 	do {
340 		debug("Trying %s\n", current->name);
341 
342 		if (device_active(current)) {
343 			ret = eth_get_ops(current)->start(current);
344 			if (ret >= 0) {
345 				struct eth_device_priv *priv =
346 					current->uclass_priv;
347 
348 				priv->state = ETH_STATE_ACTIVE;
349 				return 0;
350 			}
351 		} else {
352 			ret = eth_errno;
353 		}
354 
355 		debug("FAIL\n");
356 
357 		/*
358 		 * If ethrotate is enabled, this will change "current",
359 		 * otherwise we will drop out of this while loop immediately
360 		 */
361 		eth_try_another(0);
362 		/* This will ensure the new "current" attempted to probe */
363 		current = eth_get_dev();
364 	} while (old_current != current);
365 
366 	return ret;
367 }
368 
eth_halt(void)369 void eth_halt(void)
370 {
371 	struct udevice *current;
372 	struct eth_device_priv *priv;
373 
374 	current = eth_get_dev();
375 	if (!current || !device_active(current))
376 		return;
377 
378 	eth_get_ops(current)->stop(current);
379 	priv = current->uclass_priv;
380 	priv->state = ETH_STATE_PASSIVE;
381 }
382 
eth_send(void * packet,int length)383 int eth_send(void *packet, int length)
384 {
385 	struct udevice *current;
386 	int ret;
387 
388 	current = eth_get_dev();
389 	if (!current)
390 		return -ENODEV;
391 
392 	if (!device_active(current))
393 		return -EINVAL;
394 
395 	ret = eth_get_ops(current)->send(current, packet, length);
396 	if (ret < 0) {
397 		/* We cannot completely return the error at present */
398 		debug("%s: send() returned error %d\n", __func__, ret);
399 	}
400 	return ret;
401 }
402 
eth_rx(void)403 int eth_rx(void)
404 {
405 	struct udevice *current;
406 	uchar *packet;
407 	int ret;
408 	int i;
409 
410 	current = eth_get_dev();
411 	if (!current)
412 		return -ENODEV;
413 
414 	if (!device_active(current))
415 		return -EINVAL;
416 
417 	/* Process up to 32 packets at one time */
418 	for (i = 0; i < 32; i++) {
419 		ret = eth_get_ops(current)->recv(current, &packet);
420 		if (ret > 0)
421 			net_process_received_packet(packet, ret);
422 		if (ret >= 0 && eth_get_ops(current)->free_pkt)
423 			eth_get_ops(current)->free_pkt(current, packet, ret);
424 		if (ret <= 0)
425 			break;
426 	}
427 	if (ret == -EAGAIN)
428 		ret = 0;
429 	if (ret < 0) {
430 		/* We cannot completely return the error at present */
431 		debug("%s: recv() returned error %d\n", __func__, ret);
432 	}
433 	return ret;
434 }
435 
eth_initialize(void)436 int eth_initialize(void)
437 {
438 	int num_devices = 0;
439 	struct udevice *dev;
440 
441 	eth_common_init();
442 
443 	/*
444 	 * Devices need to write the hwaddr even if not started so that Linux
445 	 * will have access to the hwaddr that u-boot stored for the device.
446 	 * This is accomplished by attempting to probe each device and calling
447 	 * their write_hwaddr() operation.
448 	 */
449 	uclass_first_device(UCLASS_ETH, &dev);
450 	if (!dev) {
451 		printf("No ethernet found.\n");
452 		bootstage_error(BOOTSTAGE_ID_NET_ETH_START);
453 	} else {
454 		char *ethprime = getenv("ethprime");
455 		struct udevice *prime_dev = NULL;
456 
457 		if (ethprime)
458 			prime_dev = eth_get_dev_by_name(ethprime);
459 		if (prime_dev) {
460 			eth_set_dev(prime_dev);
461 			eth_current_changed();
462 		} else {
463 			eth_set_dev(NULL);
464 		}
465 
466 		bootstage_mark(BOOTSTAGE_ID_NET_ETH_INIT);
467 		do {
468 			if (num_devices)
469 				printf(", ");
470 
471 			printf("eth%d: %s", dev->seq, dev->name);
472 
473 			if (ethprime && dev == prime_dev)
474 				printf(" [PRIME]");
475 
476 			eth_write_hwaddr(dev);
477 
478 			uclass_next_device(&dev);
479 			num_devices++;
480 		} while (dev);
481 
482 		putc('\n');
483 	}
484 
485 	return num_devices;
486 }
487 
eth_post_bind(struct udevice * dev)488 static int eth_post_bind(struct udevice *dev)
489 {
490 	if (strchr(dev->name, ' ')) {
491 		printf("\nError: eth device name \"%s\" has a space!\n",
492 		       dev->name);
493 		return -EINVAL;
494 	}
495 
496 	return 0;
497 }
498 
eth_pre_unbind(struct udevice * dev)499 static int eth_pre_unbind(struct udevice *dev)
500 {
501 	/* Don't hang onto a pointer that is going away */
502 	if (dev == eth_get_uclass_priv()->current)
503 		eth_set_dev(NULL);
504 
505 	return 0;
506 }
507 
eth_post_probe(struct udevice * dev)508 static int eth_post_probe(struct udevice *dev)
509 {
510 	struct eth_device_priv *priv = dev->uclass_priv;
511 	struct eth_pdata *pdata = dev->platdata;
512 	unsigned char env_enetaddr[6];
513 
514 	priv->state = ETH_STATE_INIT;
515 
516 	/* Check if the device has a MAC address in ROM */
517 	if (eth_get_ops(dev)->read_rom_hwaddr)
518 		eth_get_ops(dev)->read_rom_hwaddr(dev);
519 
520 	eth_getenv_enetaddr_by_index("eth", dev->seq, env_enetaddr);
521 	if (!is_zero_ethaddr(env_enetaddr)) {
522 		if (!is_zero_ethaddr(pdata->enetaddr) &&
523 		    memcmp(pdata->enetaddr, env_enetaddr, 6)) {
524 			printf("\nWarning: %s MAC addresses don't match:\n",
525 			       dev->name);
526 			printf("Address in SROM is         %pM\n",
527 			       pdata->enetaddr);
528 			printf("Address in environment is  %pM\n",
529 			       env_enetaddr);
530 		}
531 
532 		/* Override the ROM MAC address */
533 		memcpy(pdata->enetaddr, env_enetaddr, 6);
534 	} else if (is_valid_ethaddr(pdata->enetaddr)) {
535 		eth_setenv_enetaddr_by_index("eth", dev->seq, pdata->enetaddr);
536 		printf("\nWarning: %s using MAC address from ROM\n",
537 		       dev->name);
538 	} else if (is_zero_ethaddr(pdata->enetaddr)) {
539 #ifdef CONFIG_NET_RANDOM_ETHADDR
540 		net_random_ethaddr(pdata->enetaddr);
541 		printf("\nWarning: %s (eth%d) using random MAC address - %pM\n",
542 		       dev->name, dev->seq, pdata->enetaddr);
543 #else
544 		printf("\nError: %s address not set.\n",
545 		       dev->name);
546 		return -EINVAL;
547 #endif
548 	}
549 
550 	return 0;
551 }
552 
eth_pre_remove(struct udevice * dev)553 static int eth_pre_remove(struct udevice *dev)
554 {
555 	eth_get_ops(dev)->stop(dev);
556 
557 	return 0;
558 }
559 
560 UCLASS_DRIVER(eth) = {
561 	.name		= "eth",
562 	.id		= UCLASS_ETH,
563 	.post_bind	= eth_post_bind,
564 	.pre_unbind	= eth_pre_unbind,
565 	.post_probe	= eth_post_probe,
566 	.pre_remove	= eth_pre_remove,
567 	.priv_auto_alloc_size = sizeof(struct eth_uclass_priv),
568 	.per_device_auto_alloc_size = sizeof(struct eth_device_priv),
569 	.flags		= DM_UC_FLAG_SEQ_ALIAS,
570 };
571 #endif
572 
573 #ifndef CONFIG_DM_ETH
574 
575 #ifdef CONFIG_API
576 static struct {
577 	uchar data[PKTSIZE];
578 	int length;
579 } eth_rcv_bufs[PKTBUFSRX];
580 
581 static unsigned int eth_rcv_current, eth_rcv_last;
582 #endif
583 
584 static struct eth_device *eth_devices;
585 struct eth_device *eth_current;
586 
eth_set_current_to_next(void)587 static void eth_set_current_to_next(void)
588 {
589 	eth_current = eth_current->next;
590 }
591 
eth_set_dev(struct eth_device * dev)592 static void eth_set_dev(struct eth_device *dev)
593 {
594 	eth_current = dev;
595 }
596 
eth_get_dev_by_name(const char * devname)597 struct eth_device *eth_get_dev_by_name(const char *devname)
598 {
599 	struct eth_device *dev, *target_dev;
600 
601 	BUG_ON(devname == NULL);
602 
603 	if (!eth_devices)
604 		return NULL;
605 
606 	dev = eth_devices;
607 	target_dev = NULL;
608 	do {
609 		if (strcmp(devname, dev->name) == 0) {
610 			target_dev = dev;
611 			break;
612 		}
613 		dev = dev->next;
614 	} while (dev != eth_devices);
615 
616 	return target_dev;
617 }
618 
eth_get_dev_by_index(int index)619 struct eth_device *eth_get_dev_by_index(int index)
620 {
621 	struct eth_device *dev, *target_dev;
622 
623 	if (!eth_devices)
624 		return NULL;
625 
626 	dev = eth_devices;
627 	target_dev = NULL;
628 	do {
629 		if (dev->index == index) {
630 			target_dev = dev;
631 			break;
632 		}
633 		dev = dev->next;
634 	} while (dev != eth_devices);
635 
636 	return target_dev;
637 }
638 
eth_get_dev_index(void)639 int eth_get_dev_index(void)
640 {
641 	if (!eth_current)
642 		return -1;
643 
644 	return eth_current->index;
645 }
646 
on_ethaddr(const char * name,const char * value,enum env_op op,int flags)647 static int on_ethaddr(const char *name, const char *value, enum env_op op,
648 	int flags)
649 {
650 	int index;
651 	struct eth_device *dev;
652 
653 	if (!eth_devices)
654 		return 0;
655 
656 	/* look for an index after "eth" */
657 	index = simple_strtoul(name + 3, NULL, 10);
658 
659 	dev = eth_devices;
660 	do {
661 		if (dev->index == index) {
662 			switch (op) {
663 			case env_op_create:
664 			case env_op_overwrite:
665 				eth_parse_enetaddr(value, dev->enetaddr);
666 				break;
667 			case env_op_delete:
668 				memset(dev->enetaddr, 0, 6);
669 			}
670 		}
671 	} while (dev != eth_devices);
672 
673 	return 0;
674 }
675 U_BOOT_ENV_CALLBACK(ethaddr, on_ethaddr);
676 
eth_write_hwaddr(struct eth_device * dev,const char * base_name,int eth_number)677 int eth_write_hwaddr(struct eth_device *dev, const char *base_name,
678 		   int eth_number)
679 {
680 	unsigned char env_enetaddr[6];
681 	int ret = 0;
682 
683 	eth_getenv_enetaddr_by_index(base_name, eth_number, env_enetaddr);
684 
685 	if (!is_zero_ethaddr(env_enetaddr)) {
686 		if (!is_zero_ethaddr(dev->enetaddr) &&
687 		    memcmp(dev->enetaddr, env_enetaddr, 6)) {
688 			printf("\nWarning: %s MAC addresses don't match:\n",
689 			       dev->name);
690 			printf("Address in SROM is         %pM\n",
691 			       dev->enetaddr);
692 			printf("Address in environment is  %pM\n",
693 			       env_enetaddr);
694 		}
695 
696 		memcpy(dev->enetaddr, env_enetaddr, 6);
697 	} else if (is_valid_ethaddr(dev->enetaddr)) {
698 		eth_setenv_enetaddr_by_index(base_name, eth_number,
699 					     dev->enetaddr);
700 		printf("\nWarning: %s using MAC address from net device\n",
701 		       dev->name);
702 	} else if (is_zero_ethaddr(dev->enetaddr)) {
703 #ifdef CONFIG_NET_RANDOM_ETHADDR
704 		net_random_ethaddr(dev->enetaddr);
705 		printf("\nWarning: %s (eth%d) using random MAC address - %pM\n",
706 		       dev->name, eth_number, dev->enetaddr);
707 #else
708 		printf("\nError: %s address not set.\n",
709 		       dev->name);
710 		return -EINVAL;
711 #endif
712 	}
713 
714 	if (dev->write_hwaddr && !eth_mac_skip(eth_number)) {
715 		if (!is_valid_ethaddr(dev->enetaddr)) {
716 			printf("\nError: %s address %pM illegal value\n",
717 			       dev->name, dev->enetaddr);
718 			return -EINVAL;
719 		}
720 
721 		ret = dev->write_hwaddr(dev);
722 		if (ret)
723 			printf("\nWarning: %s failed to set MAC address\n",
724 			       dev->name);
725 	}
726 
727 	return ret;
728 }
729 
eth_register(struct eth_device * dev)730 int eth_register(struct eth_device *dev)
731 {
732 	struct eth_device *d;
733 	static int index;
734 
735 	assert(strlen(dev->name) < sizeof(dev->name));
736 
737 	if (!eth_devices) {
738 		eth_devices = dev;
739 		eth_current = dev;
740 		eth_current_changed();
741 	} else {
742 		for (d = eth_devices; d->next != eth_devices; d = d->next)
743 			;
744 		d->next = dev;
745 	}
746 
747 	dev->state = ETH_STATE_INIT;
748 	dev->next  = eth_devices;
749 	dev->index = index++;
750 
751 	return 0;
752 }
753 
eth_unregister(struct eth_device * dev)754 int eth_unregister(struct eth_device *dev)
755 {
756 	struct eth_device *cur;
757 
758 	/* No device */
759 	if (!eth_devices)
760 		return -ENODEV;
761 
762 	for (cur = eth_devices; cur->next != eth_devices && cur->next != dev;
763 	     cur = cur->next)
764 		;
765 
766 	/* Device not found */
767 	if (cur->next != dev)
768 		return -ENODEV;
769 
770 	cur->next = dev->next;
771 
772 	if (eth_devices == dev)
773 		eth_devices = dev->next == eth_devices ? NULL : dev->next;
774 
775 	if (eth_current == dev) {
776 		eth_current = eth_devices;
777 		eth_current_changed();
778 	}
779 
780 	return 0;
781 }
782 
eth_initialize(void)783 int eth_initialize(void)
784 {
785 	int num_devices = 0;
786 
787 	eth_devices = NULL;
788 	eth_current = NULL;
789 	eth_common_init();
790 
791 	if (!eth_devices) {
792 		puts("No ethernet found.\n");
793 		bootstage_error(BOOTSTAGE_ID_NET_ETH_START);
794 	} else {
795 		struct eth_device *dev = eth_devices;
796 		char *ethprime = getenv("ethprime");
797 
798 		bootstage_mark(BOOTSTAGE_ID_NET_ETH_INIT);
799 		do {
800 			if (dev->index)
801 				puts(", ");
802 
803 			printf("%s", dev->name);
804 
805 			if (ethprime && strcmp(dev->name, ethprime) == 0) {
806 				eth_current = dev;
807 				puts(" [PRIME]");
808 			}
809 
810 			if (strchr(dev->name, ' '))
811 				puts("\nWarning: eth device name has a space!"
812 					"\n");
813 
814 			eth_write_hwaddr(dev, "eth", dev->index);
815 
816 			dev = dev->next;
817 			num_devices++;
818 		} while (dev != eth_devices);
819 
820 		eth_current_changed();
821 		putc('\n');
822 	}
823 
824 	return num_devices;
825 }
826 
827 #ifdef CONFIG_MCAST_TFTP
828 /* Multicast.
829  * mcast_addr: multicast ipaddr from which multicast Mac is made
830  * join: 1=join, 0=leave.
831  */
eth_mcast_join(struct in_addr mcast_ip,int join)832 int eth_mcast_join(struct in_addr mcast_ip, int join)
833 {
834 	u8 mcast_mac[6];
835 	if (!eth_current || !eth_current->mcast)
836 		return -1;
837 	mcast_mac[5] = htonl(mcast_ip.s_addr) & 0xff;
838 	mcast_mac[4] = (htonl(mcast_ip.s_addr)>>8) & 0xff;
839 	mcast_mac[3] = (htonl(mcast_ip.s_addr)>>16) & 0x7f;
840 	mcast_mac[2] = 0x5e;
841 	mcast_mac[1] = 0x0;
842 	mcast_mac[0] = 0x1;
843 	return eth_current->mcast(eth_current, mcast_mac, join);
844 }
845 
846 /* the 'way' for ethernet-CRC-32. Spliced in from Linux lib/crc32.c
847  * and this is the ethernet-crc method needed for TSEC -- and perhaps
848  * some other adapter -- hash tables
849  */
850 #define CRCPOLY_LE 0xedb88320
ether_crc(size_t len,unsigned char const * p)851 u32 ether_crc(size_t len, unsigned char const *p)
852 {
853 	int i;
854 	u32 crc;
855 	crc = ~0;
856 	while (len--) {
857 		crc ^= *p++;
858 		for (i = 0; i < 8; i++)
859 			crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
860 	}
861 	/* an reverse the bits, cuz of way they arrive -- last-first */
862 	crc = (crc >> 16) | (crc << 16);
863 	crc = (crc >> 8 & 0x00ff00ff) | (crc << 8 & 0xff00ff00);
864 	crc = (crc >> 4 & 0x0f0f0f0f) | (crc << 4 & 0xf0f0f0f0);
865 	crc = (crc >> 2 & 0x33333333) | (crc << 2 & 0xcccccccc);
866 	crc = (crc >> 1 & 0x55555555) | (crc << 1 & 0xaaaaaaaa);
867 	return crc;
868 }
869 
870 #endif
871 
872 
eth_init(void)873 int eth_init(void)
874 {
875 	struct eth_device *old_current;
876 
877 	if (!eth_current) {
878 		puts("No ethernet found.\n");
879 		return -ENODEV;
880 	}
881 
882 	old_current = eth_current;
883 	do {
884 		debug("Trying %s\n", eth_current->name);
885 
886 		if (eth_current->init(eth_current, gd->bd) >= 0) {
887 			eth_current->state = ETH_STATE_ACTIVE;
888 
889 			return 0;
890 		}
891 		debug("FAIL\n");
892 
893 		eth_try_another(0);
894 	} while (old_current != eth_current);
895 
896 	return -ETIMEDOUT;
897 }
898 
eth_halt(void)899 void eth_halt(void)
900 {
901 	if (!eth_current)
902 		return;
903 
904 	eth_current->halt(eth_current);
905 
906 	eth_current->state = ETH_STATE_PASSIVE;
907 }
908 
eth_send(void * packet,int length)909 int eth_send(void *packet, int length)
910 {
911 	if (!eth_current)
912 		return -ENODEV;
913 
914 	return eth_current->send(eth_current, packet, length);
915 }
916 
eth_rx(void)917 int eth_rx(void)
918 {
919 	if (!eth_current)
920 		return -ENODEV;
921 
922 	return eth_current->recv(eth_current);
923 }
924 #endif /* ifndef CONFIG_DM_ETH */
925 
926 #ifdef CONFIG_API
eth_save_packet(void * packet,int length)927 static void eth_save_packet(void *packet, int length)
928 {
929 	char *p = packet;
930 	int i;
931 
932 	if ((eth_rcv_last+1) % PKTBUFSRX == eth_rcv_current)
933 		return;
934 
935 	if (PKTSIZE < length)
936 		return;
937 
938 	for (i = 0; i < length; i++)
939 		eth_rcv_bufs[eth_rcv_last].data[i] = p[i];
940 
941 	eth_rcv_bufs[eth_rcv_last].length = length;
942 	eth_rcv_last = (eth_rcv_last + 1) % PKTBUFSRX;
943 }
944 
eth_receive(void * packet,int length)945 int eth_receive(void *packet, int length)
946 {
947 	char *p = packet;
948 	void *pp = push_packet;
949 	int i;
950 
951 	if (eth_rcv_current == eth_rcv_last) {
952 		push_packet = eth_save_packet;
953 		eth_rx();
954 		push_packet = pp;
955 
956 		if (eth_rcv_current == eth_rcv_last)
957 			return -1;
958 	}
959 
960 	length = min(eth_rcv_bufs[eth_rcv_current].length, length);
961 
962 	for (i = 0; i < length; i++)
963 		p[i] = eth_rcv_bufs[eth_rcv_current].data[i];
964 
965 	eth_rcv_current = (eth_rcv_current + 1) % PKTBUFSRX;
966 	return length;
967 }
968 #endif /* CONFIG_API */
969 
eth_current_changed(void)970 static void eth_current_changed(void)
971 {
972 	char *act = getenv("ethact");
973 	/* update current ethernet name */
974 	if (eth_get_dev()) {
975 		if (act == NULL || strcmp(act, eth_get_name()) != 0)
976 			setenv("ethact", eth_get_name());
977 	}
978 	/*
979 	 * remove the variable completely if there is no active
980 	 * interface
981 	 */
982 	else if (act != NULL)
983 		setenv("ethact", NULL);
984 }
985 
eth_try_another(int first_restart)986 void eth_try_another(int first_restart)
987 {
988 	static void *first_failed;
989 	char *ethrotate;
990 
991 	/*
992 	 * Do not rotate between network interfaces when
993 	 * 'ethrotate' variable is set to 'no'.
994 	 */
995 	ethrotate = getenv("ethrotate");
996 	if ((ethrotate != NULL) && (strcmp(ethrotate, "no") == 0))
997 		return;
998 
999 	if (!eth_get_dev())
1000 		return;
1001 
1002 	if (first_restart)
1003 		first_failed = eth_get_dev();
1004 
1005 	eth_set_current_to_next();
1006 
1007 	eth_current_changed();
1008 
1009 	if (first_failed == eth_get_dev())
1010 		net_restart_wrap = 1;
1011 }
1012 
eth_set_current(void)1013 void eth_set_current(void)
1014 {
1015 	static char *act;
1016 	static int  env_changed_id;
1017 	int	env_id;
1018 
1019 	env_id = get_env_id();
1020 	if ((act == NULL) || (env_changed_id != env_id)) {
1021 		act = getenv("ethact");
1022 		env_changed_id = env_id;
1023 	}
1024 
1025 	if (act == NULL) {
1026 		char *ethprime = getenv("ethprime");
1027 		void *dev = NULL;
1028 
1029 		if (ethprime)
1030 			dev = eth_get_dev_by_name(ethprime);
1031 		if (dev)
1032 			eth_set_dev(dev);
1033 		else
1034 			eth_set_dev(NULL);
1035 	} else {
1036 		eth_set_dev(eth_get_dev_by_name(act));
1037 	}
1038 
1039 	eth_current_changed();
1040 }
1041 
eth_get_name(void)1042 const char *eth_get_name(void)
1043 {
1044 	return eth_get_dev() ? eth_get_dev()->name : "unknown";
1045 }
1046