]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - net/eth.c
arm: mxs: ocotp: disable OCOTP clock after access is finished
[karo-tx-uboot.git] / 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
20 DECLARE_GLOBAL_DATA_PTR;
21
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
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
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
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
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
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  */
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
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
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
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  */
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  */
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  */
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
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 */
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 */
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
267 int eth_get_dev_index(void)
268 {
269         if (eth_get_dev())
270                 return eth_get_dev()->seq;
271         return -1;
272 }
273
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                 /*
291                  * Drivers are allowed to decide not to implement this at
292                  * run-time. E.g. Some devices may use it and some may not.
293                  */
294                 ret = eth_get_ops(dev)->write_hwaddr(dev);
295                 if (ret == -ENOSYS)
296                         ret = 0;
297                 if (ret)
298                         printf("\nWarning: %s failed to set MAC address\n",
299                                dev->name);
300         }
301
302         return ret;
303 }
304
305 static int on_ethaddr(const char *name, const char *value, enum env_op op,
306         int flags)
307 {
308         int index;
309         int retval;
310         struct udevice *dev;
311
312         /* look for an index after "eth" */
313         index = simple_strtoul(name + 3, NULL, 10);
314
315         retval = uclass_find_device_by_seq(UCLASS_ETH, index, false, &dev);
316         if (!retval) {
317                 struct eth_pdata *pdata = dev->platdata;
318                 switch (op) {
319                 case env_op_create:
320                 case env_op_overwrite:
321                         eth_parse_enetaddr(value, pdata->enetaddr);
322                         break;
323                 case env_op_delete:
324                         memset(pdata->enetaddr, 0, 6);
325                 }
326         }
327
328         return 0;
329 }
330 U_BOOT_ENV_CALLBACK(ethaddr, on_ethaddr);
331
332 int eth_init(void)
333 {
334         struct udevice *current;
335         struct udevice *old_current;
336         int ret = -ENODEV;
337
338         current = eth_get_dev();
339         if (!current) {
340                 printf("No ethernet found.\n");
341                 return -ENODEV;
342         }
343
344         old_current = current;
345         do {
346                 debug("Trying %s\n", current->name);
347
348                 if (device_active(current)) {
349                         ret = eth_get_ops(current)->start(current);
350                         if (ret >= 0) {
351                                 struct eth_device_priv *priv =
352                                         current->uclass_priv;
353
354                                 priv->state = ETH_STATE_ACTIVE;
355                                 return 0;
356                         }
357                 } else {
358                         ret = eth_errno;
359                 }
360
361                 debug("FAIL\n");
362
363                 /*
364                  * If ethrotate is enabled, this will change "current",
365                  * otherwise we will drop out of this while loop immediately
366                  */
367                 eth_try_another(0);
368                 /* This will ensure the new "current" attempted to probe */
369                 current = eth_get_dev();
370         } while (old_current != current);
371
372         return ret;
373 }
374
375 void eth_halt(void)
376 {
377         struct udevice *current;
378         struct eth_device_priv *priv;
379
380         current = eth_get_dev();
381         if (!current || !device_active(current))
382                 return;
383
384         eth_get_ops(current)->stop(current);
385         priv = current->uclass_priv;
386         priv->state = ETH_STATE_PASSIVE;
387 }
388
389 int eth_send(void *packet, int length)
390 {
391         struct udevice *current;
392         int ret;
393
394         current = eth_get_dev();
395         if (!current)
396                 return -ENODEV;
397
398         if (!device_active(current))
399                 return -EINVAL;
400
401         ret = eth_get_ops(current)->send(current, packet, length);
402         if (ret < 0) {
403                 /* We cannot completely return the error at present */
404                 debug("%s: send() returned error %d\n", __func__, ret);
405         }
406         return ret;
407 }
408
409 int eth_rx(void)
410 {
411         struct udevice *current;
412         uchar *packet;
413         int flags;
414         int ret;
415         int i;
416
417         current = eth_get_dev();
418         if (!current)
419                 return -ENODEV;
420
421         if (!device_active(current))
422                 return -EINVAL;
423
424         /* Process up to 32 packets at one time */
425         flags = ETH_RECV_CHECK_DEVICE;
426         for (i = 0; i < 32; i++) {
427                 ret = eth_get_ops(current)->recv(current, flags, &packet);
428                 flags = 0;
429                 if (ret > 0)
430                         net_process_received_packet(packet, ret);
431                 if (ret >= 0 && eth_get_ops(current)->free_pkt)
432                         eth_get_ops(current)->free_pkt(current, packet, ret);
433                 if (ret <= 0)
434                         break;
435         }
436         if (ret == -EAGAIN)
437                 ret = 0;
438         if (ret < 0) {
439                 /* We cannot completely return the error at present */
440                 debug("%s: recv() returned error %d\n", __func__, ret);
441         }
442         return ret;
443 }
444
445 int eth_initialize(void)
446 {
447         int num_devices = 0;
448         struct udevice *dev;
449
450         eth_common_init();
451
452         /*
453          * Devices need to write the hwaddr even if not started so that Linux
454          * will have access to the hwaddr that u-boot stored for the device.
455          * This is accomplished by attempting to probe each device and calling
456          * their write_hwaddr() operation.
457          */
458         uclass_first_device(UCLASS_ETH, &dev);
459         if (!dev) {
460                 printf("No ethernet found.\n");
461                 bootstage_error(BOOTSTAGE_ID_NET_ETH_START);
462         } else {
463                 char *ethprime = getenv("ethprime");
464                 struct udevice *prime_dev = NULL;
465
466                 if (ethprime)
467                         prime_dev = eth_get_dev_by_name(ethprime);
468                 if (prime_dev) {
469                         eth_set_dev(prime_dev);
470                         eth_current_changed();
471                 } else {
472                         eth_set_dev(NULL);
473                 }
474
475                 bootstage_mark(BOOTSTAGE_ID_NET_ETH_INIT);
476                 do {
477                         if (num_devices)
478                                 printf(", ");
479
480                         printf("eth%d: %s", dev->seq, dev->name);
481
482                         if (ethprime && dev == prime_dev)
483                                 printf(" [PRIME]");
484
485                         eth_write_hwaddr(dev);
486
487                         uclass_next_device(&dev);
488                         num_devices++;
489                 } while (dev);
490
491                 putc('\n');
492         }
493
494         return num_devices;
495 }
496
497 static int eth_post_bind(struct udevice *dev)
498 {
499         if (strchr(dev->name, ' ')) {
500                 printf("\nError: eth device name \"%s\" has a space!\n",
501                        dev->name);
502                 return -EINVAL;
503         }
504
505         return 0;
506 }
507
508 static int eth_pre_unbind(struct udevice *dev)
509 {
510         /* Don't hang onto a pointer that is going away */
511         if (dev == eth_get_uclass_priv()->current)
512                 eth_set_dev(NULL);
513
514         return 0;
515 }
516
517 static int eth_post_probe(struct udevice *dev)
518 {
519         struct eth_device_priv *priv = dev->uclass_priv;
520         struct eth_pdata *pdata = dev->platdata;
521         unsigned char env_enetaddr[6];
522
523         priv->state = ETH_STATE_INIT;
524
525         /* Check if the device has a MAC address in ROM */
526         if (eth_get_ops(dev)->read_rom_hwaddr)
527                 eth_get_ops(dev)->read_rom_hwaddr(dev);
528
529         eth_getenv_enetaddr_by_index("eth", dev->seq, env_enetaddr);
530         if (!is_zero_ethaddr(env_enetaddr)) {
531                 if (!is_zero_ethaddr(pdata->enetaddr) &&
532                     memcmp(pdata->enetaddr, env_enetaddr, 6)) {
533                         printf("\nWarning: %s MAC addresses don't match:\n",
534                                dev->name);
535                         printf("Address in SROM is         %pM\n",
536                                pdata->enetaddr);
537                         printf("Address in environment is  %pM\n",
538                                env_enetaddr);
539                 }
540
541                 /* Override the ROM MAC address */
542                 memcpy(pdata->enetaddr, env_enetaddr, 6);
543         } else if (is_valid_ethaddr(pdata->enetaddr)) {
544                 eth_setenv_enetaddr_by_index("eth", dev->seq, pdata->enetaddr);
545                 printf("\nWarning: %s using MAC address from ROM\n",
546                        dev->name);
547         } else if (is_zero_ethaddr(pdata->enetaddr)) {
548 #ifdef CONFIG_NET_RANDOM_ETHADDR
549                 net_random_ethaddr(pdata->enetaddr);
550                 printf("\nWarning: %s (eth%d) using random MAC address - %pM\n",
551                        dev->name, dev->seq, pdata->enetaddr);
552 #else
553                 printf("\nError: %s address not set.\n",
554                        dev->name);
555                 return -EINVAL;
556 #endif
557         }
558
559         return 0;
560 }
561
562 static int eth_pre_remove(struct udevice *dev)
563 {
564         eth_get_ops(dev)->stop(dev);
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
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         } while (dev != eth_devices);
681
682         return 0;
683 }
684 U_BOOT_ENV_CALLBACK(ethaddr, on_ethaddr);
685
686 int eth_write_hwaddr(struct eth_device *dev, const char *base_name,
687                    int eth_number)
688 {
689         unsigned char env_enetaddr[6];
690         int ret = 0;
691
692         eth_getenv_enetaddr_by_index(base_name, eth_number, env_enetaddr);
693
694         if (!is_zero_ethaddr(env_enetaddr)) {
695                 if (!is_zero_ethaddr(dev->enetaddr) &&
696                     memcmp(dev->enetaddr, env_enetaddr, 6)) {
697                         printf("\nWarning: %s MAC addresses don't match:\n",
698                                dev->name);
699                         printf("Address in SROM is         %pM\n",
700                                dev->enetaddr);
701                         printf("Address in environment is  %pM\n",
702                                env_enetaddr);
703                 }
704
705                 memcpy(dev->enetaddr, env_enetaddr, 6);
706         } else if (is_valid_ethaddr(dev->enetaddr)) {
707                 eth_setenv_enetaddr_by_index(base_name, eth_number,
708                                              dev->enetaddr);
709                 printf("\nWarning: %s using MAC address from net device\n",
710                        dev->name);
711         } else if (is_zero_ethaddr(dev->enetaddr)) {
712 #ifdef CONFIG_NET_RANDOM_ETHADDR
713                 net_random_ethaddr(dev->enetaddr);
714                 printf("\nWarning: %s (eth%d) using random MAC address - %pM\n",
715                        dev->name, eth_number, dev->enetaddr);
716 #else
717                 printf("\nError: %s address not set.\n",
718                        dev->name);
719                 return -EINVAL;
720 #endif
721         }
722
723         if (dev->write_hwaddr && !eth_mac_skip(eth_number)) {
724                 if (!is_valid_ethaddr(dev->enetaddr)) {
725                         printf("\nError: %s address %pM illegal value\n",
726                                dev->name, dev->enetaddr);
727                         return -EINVAL;
728                 }
729
730                 ret = dev->write_hwaddr(dev);
731                 if (ret)
732                         printf("\nWarning: %s failed to set MAC address\n",
733                                dev->name);
734         }
735
736         return ret;
737 }
738
739 int eth_register(struct eth_device *dev)
740 {
741         struct eth_device *d;
742         static int index;
743
744         assert(strlen(dev->name) < sizeof(dev->name));
745
746         if (!eth_devices) {
747                 eth_devices = dev;
748                 eth_current = dev;
749                 eth_current_changed();
750         } else {
751                 for (d = eth_devices; d->next != eth_devices; d = d->next)
752                         ;
753                 d->next = dev;
754         }
755
756         dev->state = ETH_STATE_INIT;
757         dev->next  = eth_devices;
758         dev->index = index++;
759
760         return 0;
761 }
762
763 int eth_unregister(struct eth_device *dev)
764 {
765         struct eth_device *cur;
766
767         /* No device */
768         if (!eth_devices)
769                 return -ENODEV;
770
771         for (cur = eth_devices; cur->next != eth_devices && cur->next != dev;
772              cur = cur->next)
773                 ;
774
775         /* Device not found */
776         if (cur->next != dev)
777                 return -ENODEV;
778
779         cur->next = dev->next;
780
781         if (eth_devices == dev)
782                 eth_devices = dev->next == eth_devices ? NULL : dev->next;
783
784         if (eth_current == dev) {
785                 eth_current = eth_devices;
786                 eth_current_changed();
787         }
788
789         return 0;
790 }
791
792 int eth_initialize(void)
793 {
794         int num_devices = 0;
795
796         eth_devices = NULL;
797         eth_current = NULL;
798         eth_common_init();
799
800         if (!eth_devices) {
801                 puts("No ethernet found.\n");
802                 bootstage_error(BOOTSTAGE_ID_NET_ETH_START);
803         } else {
804                 struct eth_device *dev = eth_devices;
805                 char *ethprime = getenv("ethprime");
806
807                 bootstage_mark(BOOTSTAGE_ID_NET_ETH_INIT);
808                 do {
809                         if (dev->index)
810                                 puts(", ");
811
812                         printf("%s", dev->name);
813
814                         if (ethprime && strcmp(dev->name, ethprime) == 0) {
815                                 eth_current = dev;
816                                 puts(" [PRIME]");
817                         }
818
819                         if (strchr(dev->name, ' '))
820                                 puts("\nWarning: eth device name has a space!"
821                                         "\n");
822
823                         eth_write_hwaddr(dev, "eth", dev->index);
824
825                         dev = dev->next;
826                         num_devices++;
827                 } while (dev != eth_devices);
828
829                 eth_current_changed();
830                 putc('\n');
831         }
832
833         return num_devices;
834 }
835
836 #ifdef CONFIG_MCAST_TFTP
837 /* Multicast.
838  * mcast_addr: multicast ipaddr from which multicast Mac is made
839  * join: 1=join, 0=leave.
840  */
841 int eth_mcast_join(struct in_addr mcast_ip, int join)
842 {
843         u8 mcast_mac[6];
844         if (!eth_current || !eth_current->mcast)
845                 return -1;
846         mcast_mac[5] = htonl(mcast_ip.s_addr) & 0xff;
847         mcast_mac[4] = (htonl(mcast_ip.s_addr)>>8) & 0xff;
848         mcast_mac[3] = (htonl(mcast_ip.s_addr)>>16) & 0x7f;
849         mcast_mac[2] = 0x5e;
850         mcast_mac[1] = 0x0;
851         mcast_mac[0] = 0x1;
852         return eth_current->mcast(eth_current, mcast_mac, join);
853 }
854
855 /* the 'way' for ethernet-CRC-32. Spliced in from Linux lib/crc32.c
856  * and this is the ethernet-crc method needed for TSEC -- and perhaps
857  * some other adapter -- hash tables
858  */
859 #define CRCPOLY_LE 0xedb88320
860 u32 ether_crc(size_t len, unsigned char const *p)
861 {
862         int i;
863         u32 crc;
864         crc = ~0;
865         while (len--) {
866                 crc ^= *p++;
867                 for (i = 0; i < 8; i++)
868                         crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
869         }
870         /* an reverse the bits, cuz of way they arrive -- last-first */
871         crc = (crc >> 16) | (crc << 16);
872         crc = (crc >> 8 & 0x00ff00ff) | (crc << 8 & 0xff00ff00);
873         crc = (crc >> 4 & 0x0f0f0f0f) | (crc << 4 & 0xf0f0f0f0);
874         crc = (crc >> 2 & 0x33333333) | (crc << 2 & 0xcccccccc);
875         crc = (crc >> 1 & 0x55555555) | (crc << 1 & 0xaaaaaaaa);
876         return crc;
877 }
878
879 #endif
880
881
882 int eth_init(void)
883 {
884         struct eth_device *old_current;
885
886         if (!eth_current) {
887                 puts("No ethernet found.\n");
888                 return -ENODEV;
889         }
890
891         old_current = eth_current;
892         do {
893                 debug("Trying %s\n", eth_current->name);
894
895                 if (eth_current->init(eth_current, gd->bd) >= 0) {
896                         eth_current->state = ETH_STATE_ACTIVE;
897
898                         return 0;
899                 }
900                 debug("FAIL\n");
901
902                 eth_try_another(0);
903         } while (old_current != eth_current);
904
905         return -ETIMEDOUT;
906 }
907
908 void eth_halt(void)
909 {
910         if (!eth_current)
911                 return;
912
913         eth_current->halt(eth_current);
914
915         eth_current->state = ETH_STATE_PASSIVE;
916 }
917
918 int eth_send(void *packet, int length)
919 {
920         if (!eth_current)
921                 return -ENODEV;
922
923         return eth_current->send(eth_current, packet, length);
924 }
925
926 int eth_rx(void)
927 {
928         if (!eth_current)
929                 return -ENODEV;
930
931         return eth_current->recv(eth_current);
932 }
933 #endif /* ifndef CONFIG_DM_ETH */
934
935 #ifdef CONFIG_API
936 static void eth_save_packet(void *packet, int length)
937 {
938         char *p = packet;
939         int i;
940
941         if ((eth_rcv_last+1) % PKTBUFSRX == eth_rcv_current)
942                 return;
943
944         if (PKTSIZE < length)
945                 return;
946
947         for (i = 0; i < length; i++)
948                 eth_rcv_bufs[eth_rcv_last].data[i] = p[i];
949
950         eth_rcv_bufs[eth_rcv_last].length = length;
951         eth_rcv_last = (eth_rcv_last + 1) % PKTBUFSRX;
952 }
953
954 int eth_receive(void *packet, int length)
955 {
956         char *p = packet;
957         void *pp = push_packet;
958         int i;
959
960         if (eth_rcv_current == eth_rcv_last) {
961                 push_packet = eth_save_packet;
962                 eth_rx();
963                 push_packet = pp;
964
965                 if (eth_rcv_current == eth_rcv_last)
966                         return -1;
967         }
968
969         length = min(eth_rcv_bufs[eth_rcv_current].length, length);
970
971         for (i = 0; i < length; i++)
972                 p[i] = eth_rcv_bufs[eth_rcv_current].data[i];
973
974         eth_rcv_current = (eth_rcv_current + 1) % PKTBUFSRX;
975         return length;
976 }
977 #endif /* CONFIG_API */
978
979 static void eth_current_changed(void)
980 {
981         char *act = getenv("ethact");
982         /* update current ethernet name */
983         if (eth_get_dev()) {
984                 if (act == NULL || strcmp(act, eth_get_name()) != 0)
985                         setenv("ethact", eth_get_name());
986         }
987         /*
988          * remove the variable completely if there is no active
989          * interface
990          */
991         else if (act != NULL)
992                 setenv("ethact", NULL);
993 }
994
995 void eth_try_another(int first_restart)
996 {
997         static void *first_failed;
998         char *ethrotate;
999
1000         /*
1001          * Do not rotate between network interfaces when
1002          * 'ethrotate' variable is set to 'no'.
1003          */
1004         ethrotate = getenv("ethrotate");
1005         if ((ethrotate != NULL) && (strcmp(ethrotate, "no") == 0))
1006                 return;
1007
1008         if (!eth_get_dev())
1009                 return;
1010
1011         if (first_restart)
1012                 first_failed = eth_get_dev();
1013
1014         eth_set_current_to_next();
1015
1016         eth_current_changed();
1017
1018         if (first_failed == eth_get_dev())
1019                 net_restart_wrap = 1;
1020 }
1021
1022 void eth_set_current(void)
1023 {
1024         static char *act;
1025         static int  env_changed_id;
1026         int     env_id;
1027
1028         env_id = get_env_id();
1029         if ((act == NULL) || (env_changed_id != env_id)) {
1030                 act = getenv("ethact");
1031                 env_changed_id = env_id;
1032         }
1033
1034         if (act == NULL) {
1035                 char *ethprime = getenv("ethprime");
1036                 void *dev = NULL;
1037
1038                 if (ethprime)
1039                         dev = eth_get_dev_by_name(ethprime);
1040                 if (dev)
1041                         eth_set_dev(dev);
1042                 else
1043                         eth_set_dev(NULL);
1044         } else {
1045                 eth_set_dev(eth_get_dev_by_name(act));
1046         }
1047
1048         eth_current_changed();
1049 }
1050
1051 const char *eth_get_name(void)
1052 {
1053         return eth_get_dev() ? eth_get_dev()->name : "unknown";
1054 }