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