]> Git Repo - J-u-boot.git/blob - net/eth-uclass.c
Merge patch series "configs: Enable CMD_NFS by default"
[J-u-boot.git] / net / eth-uclass.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2001-2015
4  * Wolfgang Denk, DENX Software Engineering, [email protected].
5  * Joe Hershberger, National Instruments
6  */
7
8 #define LOG_CATEGORY UCLASS_ETH
9
10 #include <bootdev.h>
11 #include <bootstage.h>
12 #include <dm.h>
13 #include <env.h>
14 #include <log.h>
15 #include <net.h>
16 #include <nvmem.h>
17 #include <asm/global_data.h>
18 #include <dm/device-internal.h>
19 #include <dm/uclass-internal.h>
20 #include <net/pcap.h>
21 #include "eth_internal.h"
22 #include <eth_phy.h>
23
24 DECLARE_GLOBAL_DATA_PTR;
25
26 /**
27  * struct eth_device_priv - private structure for each Ethernet device
28  *
29  * @state: The state of the Ethernet MAC driver (defined by enum eth_state_t)
30  */
31 struct eth_device_priv {
32         enum eth_state_t state;
33         bool running;
34 };
35
36 /**
37  * struct eth_uclass_priv - The structure attached to the uclass itself
38  *
39  * @current: The Ethernet device that the network functions are using
40  * @no_bootdevs: true to skip binding Ethernet bootdevs (this is a negative flag
41  * so that the default value enables it)
42  */
43 struct eth_uclass_priv {
44         struct udevice *current;
45         bool no_bootdevs;
46 };
47
48 /* eth_errno - This stores the most recent failure code from DM functions */
49 static int eth_errno;
50 /* Are we currently in eth_init() or eth_halt()? */
51 static bool in_init_halt;
52
53 /* board-specific Ethernet Interface initializations. */
54 __weak int board_interface_eth_init(struct udevice *dev,
55                                     phy_interface_t interface_type)
56 {
57         return 0;
58 }
59
60 static struct eth_uclass_priv *eth_get_uclass_priv(void)
61 {
62         struct uclass *uc;
63         int ret;
64
65         ret = uclass_get(UCLASS_ETH, &uc);
66         if (ret)
67                 return NULL;
68
69         assert(uc);
70         return uclass_get_priv(uc);
71 }
72
73 void eth_set_enable_bootdevs(bool enable)
74 {
75         struct eth_uclass_priv *priv = eth_get_uclass_priv();
76
77         if (priv)
78                 priv->no_bootdevs = !enable;
79 }
80
81 void eth_set_current_to_next(void)
82 {
83         struct eth_uclass_priv *uc_priv;
84
85         uc_priv = eth_get_uclass_priv();
86         if (uc_priv->current)
87                 uclass_next_device(&uc_priv->current);
88         if (!uc_priv->current)
89                 uclass_first_device(UCLASS_ETH, &uc_priv->current);
90 }
91
92 /*
93  * Typically this will simply return the active device.
94  * In the case where the most recent active device was unset, this will attempt
95  * to return the device with sequence id 0 (which can be configured by the
96  * device tree). If this fails, fall back to just getting the first device.
97  * The latter is non-deterministic and depends on the order of the probing.
98  * If that device doesn't exist or fails to probe, this function will return
99  * NULL.
100  */
101 struct udevice *eth_get_dev(void)
102 {
103         struct eth_uclass_priv *uc_priv;
104
105         uc_priv = eth_get_uclass_priv();
106         if (!uc_priv)
107                 return NULL;
108
109         if (!uc_priv->current) {
110                 eth_errno = uclass_get_device_by_seq(UCLASS_ETH, 0,
111                                                      &uc_priv->current);
112                 if (eth_errno)
113                         eth_errno = uclass_first_device_err(UCLASS_ETH,
114                                                             &uc_priv->current);
115                 if (eth_errno)
116                         uc_priv->current = NULL;
117         }
118         return uc_priv->current;
119 }
120
121 /*
122  * Typically this will just store a device pointer.
123  * In case it was not probed, we will attempt to do so.
124  * dev may be NULL to unset the active device.
125  */
126 void eth_set_dev(struct udevice *dev)
127 {
128         if (dev && !device_active(dev)) {
129                 eth_errno = device_probe(dev);
130                 if (eth_errno)
131                         dev = NULL;
132         }
133
134         eth_get_uclass_priv()->current = dev;
135 }
136
137 /*
138  * Find the udevice that either has the name passed in as devname or has an
139  * alias named devname.
140  */
141 struct udevice *eth_get_dev_by_name(const char *devname)
142 {
143         int seq = -1;
144         char *endp = NULL;
145         const char *startp = NULL;
146         struct udevice *it;
147         struct uclass *uc;
148         int len = strlen("eth");
149         int ret;
150
151         /* Must be longer than 3 to be an alias */
152         if (!strncmp(devname, "eth", len) && strlen(devname) > len) {
153                 startp = devname + len;
154                 seq = dectoul(startp, &endp);
155         }
156
157         ret = uclass_get(UCLASS_ETH, &uc);
158         if (ret)
159                 return NULL;
160
161         uclass_foreach_dev(it, uc) {
162                 /*
163                  * We don't care about errors from probe here. Either they won't
164                  * match an alias or it will match a literal name and we'll pick
165                  * up the error when we try to probe again in eth_set_dev().
166                  */
167                 if (device_probe(it))
168                         continue;
169                 /* Check for the name or the sequence number to match */
170                 if (strcmp(it->name, devname) == 0 ||
171                     (endp > startp && dev_seq(it) == seq))
172                         return it;
173         }
174
175         return NULL;
176 }
177
178 unsigned char *eth_get_ethaddr(void)
179 {
180         struct eth_pdata *pdata;
181
182         if (eth_get_dev()) {
183                 pdata = dev_get_plat(eth_get_dev());
184                 return pdata->enetaddr;
185         }
186
187         return NULL;
188 }
189
190 /* Set active state without calling start on the driver */
191 int eth_init_state_only(void)
192 {
193         struct udevice *current;
194         struct eth_device_priv *priv;
195
196         current = eth_get_dev();
197         if (!current || !device_active(current))
198                 return -EINVAL;
199
200         priv = dev_get_uclass_priv(current);
201         priv->state = ETH_STATE_ACTIVE;
202
203         return 0;
204 }
205
206 /* Set passive state without calling stop on the driver */
207 void eth_halt_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;
215
216         priv = dev_get_uclass_priv(current);
217         priv->state = ETH_STATE_PASSIVE;
218 }
219
220 int eth_get_dev_index(void)
221 {
222         if (eth_get_dev())
223                 return dev_seq(eth_get_dev());
224         return -1;
225 }
226
227 static int eth_write_hwaddr(struct udevice *dev)
228 {
229         struct eth_pdata *pdata;
230         int ret = 0;
231
232         if (!dev || !device_active(dev))
233                 return -EINVAL;
234
235         /* seq is valid since the device is active */
236         if (eth_get_ops(dev)->write_hwaddr && !eth_mac_skip(dev_seq(dev))) {
237                 pdata = dev_get_plat(dev);
238                 if (!is_valid_ethaddr(pdata->enetaddr)) {
239                         printf("\nError: %s address %pM illegal value\n",
240                                dev->name, pdata->enetaddr);
241                         return -EINVAL;
242                 }
243
244                 /*
245                  * Drivers are allowed to decide not to implement this at
246                  * run-time. E.g. Some devices may use it and some may not.
247                  */
248                 ret = eth_get_ops(dev)->write_hwaddr(dev);
249                 if (ret == -ENOSYS)
250                         ret = 0;
251                 if (ret)
252                         printf("\nWarning: %s failed to set MAC address\n",
253                                dev->name);
254         }
255
256         return ret;
257 }
258
259 static int on_ethaddr(const char *name, const char *value, enum env_op op,
260         int flags)
261 {
262         int index;
263         int retval;
264         struct udevice *dev;
265
266         /* look for an index after "eth" */
267         index = dectoul(name + 3, NULL);
268
269         retval = uclass_find_device_by_seq(UCLASS_ETH, index, &dev);
270         if (!retval) {
271                 struct eth_pdata *pdata = dev_get_plat(dev);
272                 switch (op) {
273                 case env_op_create:
274                 case env_op_overwrite:
275                         string_to_enetaddr(value, pdata->enetaddr);
276                         eth_write_hwaddr(dev);
277                         break;
278                 case env_op_delete:
279                         memset(pdata->enetaddr, 0, ARP_HLEN);
280                 }
281         }
282
283         return 0;
284 }
285 U_BOOT_ENV_CALLBACK(ethaddr, on_ethaddr);
286
287 int eth_start_udev(struct udevice *dev)
288 {
289         struct eth_device_priv *priv = dev_get_uclass_priv(dev);
290         int ret;
291
292         if (priv->running)
293                 return 0;
294
295         if (!device_active(dev))
296                 return -EINVAL;
297
298         ret = eth_get_ops(dev)->start(dev);
299         if (ret < 0)
300                 return ret;
301
302         priv->state = ETH_STATE_ACTIVE;
303         priv->running = true;
304
305         return 0;
306 }
307
308 int eth_init(void)
309 {
310         struct udevice *current = NULL;
311         struct udevice *old_current;
312         int ret = -ENODEV;
313         char *ethrotate;
314         char *ethact;
315
316         if (in_init_halt)
317                 return -EBUSY;
318
319         in_init_halt = true;
320
321         ethact = env_get("ethact");
322         ethrotate = env_get("ethrotate");
323
324         /*
325          * When 'ethrotate' variable is set to 'no' and 'ethact' variable
326          * is already set to an ethernet device, we should stick to 'ethact'.
327          */
328         if ((ethrotate != NULL) && (strcmp(ethrotate, "no") == 0)) {
329                 if (ethact) {
330                         current = eth_get_dev_by_name(ethact);
331                         if (!current) {
332                                 ret = -EINVAL;
333                                 goto end;
334                         }
335                 }
336         }
337
338         if (!current) {
339                 current = eth_get_dev();
340                 if (!current) {
341                         log_err("No ethernet found.\n");
342                         ret = -ENODEV;
343                         goto end;
344                 }
345         }
346
347         old_current = current;
348         do {
349                 if (current) {
350                         debug("Trying %s\n", current->name);
351
352                         ret = eth_start_udev(current);
353                         if (ret < 0)
354                                 ret = eth_errno;
355                         else
356                                 break;
357
358                         debug("FAIL\n");
359                 } else {
360                         debug("PROBE FAIL\n");
361                 }
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 end:
373         in_init_halt = false;
374         return ret;
375 }
376
377 void eth_halt(void)
378 {
379         struct udevice *current;
380         struct eth_device_priv *priv;
381
382         if (in_init_halt)
383                 return;
384
385         in_init_halt = true;
386
387         current = eth_get_dev();
388         if (!current)
389                 goto end;
390
391         priv = dev_get_uclass_priv(current);
392         if (!priv || !priv->running)
393                 goto end;
394
395         eth_get_ops(current)->stop(current);
396         priv->state = ETH_STATE_PASSIVE;
397         priv->running = false;
398
399 end:
400         in_init_halt = false;
401 }
402
403 int eth_is_active(struct udevice *dev)
404 {
405         struct eth_device_priv *priv;
406
407         if (!dev || !device_active(dev))
408                 return 0;
409
410         priv = dev_get_uclass_priv(dev);
411         return priv->state == ETH_STATE_ACTIVE;
412 }
413
414 int eth_send(void *packet, int length)
415 {
416         struct udevice *current;
417         int ret;
418
419         current = eth_get_dev();
420         if (!current)
421                 return -ENODEV;
422
423         if (!eth_is_active(current))
424                 return -EINVAL;
425
426         ret = eth_get_ops(current)->send(current, packet, length);
427         if (ret < 0) {
428                 /* We cannot completely return the error at present */
429                 debug("%s: send() returned error %d\n", __func__, ret);
430         }
431 #if defined(CONFIG_CMD_PCAP)
432         if (ret >= 0)
433                 pcap_post(packet, length, true);
434 #endif
435         return ret;
436 }
437
438 int eth_rx(void)
439 {
440         struct udevice *current;
441         uchar *packet;
442         int flags;
443         int ret;
444         int i;
445
446         current = eth_get_dev();
447         if (!current)
448                 return -ENODEV;
449
450         if (!eth_is_active(current))
451                 return -EINVAL;
452
453         /* Process up to 32 packets at one time */
454         flags = ETH_RECV_CHECK_DEVICE;
455         for (i = 0; i < ETH_PACKETS_BATCH_RECV; i++) {
456                 ret = eth_get_ops(current)->recv(current, flags, &packet);
457                 flags = 0;
458                 if (ret > 0)
459                         net_process_received_packet(packet, ret);
460                 if (ret >= 0 && eth_get_ops(current)->free_pkt)
461                         eth_get_ops(current)->free_pkt(current, packet, ret);
462                 if (ret <= 0)
463                         break;
464         }
465         if (ret == -EAGAIN)
466                 ret = 0;
467         if (ret < 0) {
468                 /* We cannot completely return the error at present */
469                 debug("%s: recv() returned error %d\n", __func__, ret);
470         }
471         return ret;
472 }
473
474 int eth_initialize(void)
475 {
476         int num_devices = 0;
477         struct udevice *dev;
478
479         eth_common_init();
480
481         /*
482          * Devices need to write the hwaddr even if not started so that Linux
483          * will have access to the hwaddr that u-boot stored for the device.
484          * This is accomplished by attempting to probe each device and calling
485          * their write_hwaddr() operation.
486          */
487         uclass_first_device_check(UCLASS_ETH, &dev);
488         if (!dev) {
489                 log_err("No ethernet found.\n");
490                 bootstage_error(BOOTSTAGE_ID_NET_ETH_START);
491         } else {
492                 char *ethprime = env_get("ethprime");
493                 struct udevice *prime_dev = NULL;
494
495                 if (ethprime)
496                         prime_dev = eth_get_dev_by_name(ethprime);
497                 if (prime_dev) {
498                         eth_set_dev(prime_dev);
499                         eth_current_changed();
500                 } else {
501                         eth_set_dev(NULL);
502                 }
503
504                 bootstage_mark(BOOTSTAGE_ID_NET_ETH_INIT);
505                 do {
506                         if (device_active(dev)) {
507                                 if (num_devices)
508                                         printf(", ");
509
510                                 printf("eth%d: %s", dev_seq(dev), dev->name);
511
512                                 if (ethprime && dev == prime_dev)
513                                         printf(" [PRIME]");
514                         }
515
516                         eth_write_hwaddr(dev);
517
518                         if (device_active(dev))
519                                 num_devices++;
520                         uclass_next_device_check(&dev);
521                 } while (dev);
522
523                 if (!num_devices)
524                         log_err("No ethernet found.\n");
525                 putc('\n');
526         }
527
528         return num_devices;
529 }
530
531 static int eth_post_bind(struct udevice *dev)
532 {
533         struct eth_uclass_priv *priv = uclass_get_priv(dev->uclass);
534         int ret;
535
536         if (strchr(dev->name, ' ')) {
537                 printf("\nError: eth device name \"%s\" has a space!\n",
538                        dev->name);
539                 return -EINVAL;
540         }
541
542 #ifdef CONFIG_DM_ETH_PHY
543         eth_phy_binds_nodes(dev);
544 #endif
545         if (CONFIG_IS_ENABLED(BOOTDEV_ETH) && !priv->no_bootdevs) {
546                 ret = bootdev_setup_for_dev(dev, "eth_bootdev");
547                 if (ret)
548                         return log_msg_ret("bootdev", ret);
549         }
550
551         return 0;
552 }
553
554 static int eth_pre_unbind(struct udevice *dev)
555 {
556         /* Don't hang onto a pointer that is going away */
557         if (dev == eth_get_uclass_priv()->current)
558                 eth_set_dev(NULL);
559
560         return 0;
561 }
562
563 static bool eth_dev_get_mac_address(struct udevice *dev, u8 mac[ARP_HLEN])
564 {
565 #if CONFIG_IS_ENABLED(OF_CONTROL)
566         const uint8_t *p;
567         struct nvmem_cell mac_cell;
568
569         p = dev_read_u8_array_ptr(dev, "mac-address", ARP_HLEN);
570         if (!p)
571                 p = dev_read_u8_array_ptr(dev, "local-mac-address", ARP_HLEN);
572
573         if (p) {
574                 memcpy(mac, p, ARP_HLEN);
575                 return true;
576         }
577
578         if (nvmem_cell_get_by_name(dev, "mac-address", &mac_cell))
579                 return false;
580
581         return !nvmem_cell_read(&mac_cell, mac, ARP_HLEN);
582 #else
583         return false;
584 #endif
585 }
586
587 static int eth_post_probe(struct udevice *dev)
588 {
589         struct eth_device_priv *priv = dev_get_uclass_priv(dev);
590         struct eth_pdata *pdata = dev_get_plat(dev);
591         unsigned char env_enetaddr[ARP_HLEN];
592         char *source = "DT";
593
594         priv->state = ETH_STATE_INIT;
595         priv->running = false;
596
597         /* Check if the device has a valid MAC address in device tree */
598         if (!eth_dev_get_mac_address(dev, pdata->enetaddr) ||
599             !is_valid_ethaddr(pdata->enetaddr)) {
600                 /* Check if the device has a MAC address in ROM */
601                 if (eth_get_ops(dev)->read_rom_hwaddr) {
602                         int ret;
603
604                         ret = eth_get_ops(dev)->read_rom_hwaddr(dev);
605                         if (!ret)
606                                 source = "ROM";
607                 }
608         }
609
610         eth_env_get_enetaddr_by_index("eth", dev_seq(dev), env_enetaddr);
611         if (!is_zero_ethaddr(env_enetaddr)) {
612                 if (!is_zero_ethaddr(pdata->enetaddr) &&
613                     memcmp(pdata->enetaddr, env_enetaddr, ARP_HLEN)) {
614                         printf("\nWarning: %s MAC addresses don't match:\n",
615                                dev->name);
616                         printf("Address in %s is\t\t%pM\n",
617                                source, pdata->enetaddr);
618                         printf("Address in environment is\t%pM\n",
619                                env_enetaddr);
620                 }
621
622                 /* Override the ROM MAC address */
623                 memcpy(pdata->enetaddr, env_enetaddr, ARP_HLEN);
624         } else if (is_valid_ethaddr(pdata->enetaddr)) {
625                 eth_env_set_enetaddr_by_index("eth", dev_seq(dev),
626                                               pdata->enetaddr);
627         } else if (is_zero_ethaddr(pdata->enetaddr) ||
628                    !is_valid_ethaddr(pdata->enetaddr)) {
629 #ifdef CONFIG_NET_RANDOM_ETHADDR
630                 net_random_ethaddr(pdata->enetaddr);
631                 printf("\nWarning: %s (eth%d) using random MAC address - %pM\n",
632                        dev->name, dev_seq(dev), pdata->enetaddr);
633                 eth_env_set_enetaddr_by_index("eth", dev_seq(dev),
634                                               pdata->enetaddr);
635 #else
636                 printf("\nError: %s No valid MAC address found.\n",
637                        dev->name);
638                 return -EINVAL;
639 #endif
640         }
641
642         eth_write_hwaddr(dev);
643
644         return 0;
645 }
646
647 static int eth_pre_remove(struct udevice *dev)
648 {
649         struct eth_pdata *pdata = dev_get_plat(dev);
650
651         eth_get_ops(dev)->stop(dev);
652
653         /* clear the MAC address */
654         memset(pdata->enetaddr, 0, ARP_HLEN);
655
656         return 0;
657 }
658
659 UCLASS_DRIVER(ethernet) = {
660         .name           = "ethernet",
661         .id             = UCLASS_ETH,
662         .post_bind      = eth_post_bind,
663         .pre_unbind     = eth_pre_unbind,
664         .post_probe     = eth_post_probe,
665         .pre_remove     = eth_pre_remove,
666         .priv_auto      = sizeof(struct eth_uclass_priv),
667         .per_device_auto        = sizeof(struct eth_device_priv),
668         .flags          = DM_UC_FLAG_SEQ_ALIAS,
669 };
This page took 0.065081 seconds and 4 git commands to generate.