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