183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
27ac2fe2dSIlya Yanok /*
37ac2fe2dSIlya Yanok * (C) Copyright 2000-2004
47ac2fe2dSIlya Yanok * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
57ac2fe2dSIlya Yanok *
67ac2fe2dSIlya Yanok * (C) Copyright 2012
77ac2fe2dSIlya Yanok * Ilya Yanok <ilya.yanok@gmail.com>
87ac2fe2dSIlya Yanok */
97ac2fe2dSIlya Yanok #include <common.h>
1036afd451SNikita Kiryanov #include <errno.h>
117ac2fe2dSIlya Yanok #include <spl.h>
127ac2fe2dSIlya Yanok #include <net.h>
13b08c8c48SMasahiro Yamada #include <linux/libfdt.h>
147ac2fe2dSIlya Yanok
15b432b1ebSFaiz Abbas #if defined(CONFIG_SPL_ETH_SUPPORT) || defined(CONFIG_SPL_USB_ETHER)
spl_net_load_read(struct spl_load_info * load,ulong sector,ulong count,void * buf)166dca5e8aSAndrew F. Davis static ulong spl_net_load_read(struct spl_load_info *load, ulong sector,
176dca5e8aSAndrew F. Davis ulong count, void *buf)
186dca5e8aSAndrew F. Davis {
196dca5e8aSAndrew F. Davis debug("%s: sector %lx, count %lx, buf %lx\n",
206dca5e8aSAndrew F. Davis __func__, sector, count, (ulong)buf);
216dca5e8aSAndrew F. Davis memcpy(buf, (void *)(load_addr + sector), count);
226dca5e8aSAndrew F. Davis return count;
236dca5e8aSAndrew F. Davis }
246dca5e8aSAndrew F. Davis
spl_net_load_image(struct spl_image_info * spl_image,struct spl_boot_device * bootdev)252a2ee2acSSimon Glass static int spl_net_load_image(struct spl_image_info *spl_image,
262a2ee2acSSimon Glass struct spl_boot_device *bootdev)
277ac2fe2dSIlya Yanok {
286dca5e8aSAndrew F. Davis struct image_header *header = (struct image_header *)load_addr;
297ac2fe2dSIlya Yanok int rv;
307ac2fe2dSIlya Yanok
317ac2fe2dSIlya Yanok env_init();
327ac2fe2dSIlya Yanok env_relocate();
33382bee57SSimon Glass env_set("autoload", "yes");
34d2eaec60SJoe Hershberger rv = eth_initialize();
357ac2fe2dSIlya Yanok if (rv == 0) {
367ac2fe2dSIlya Yanok printf("No Ethernet devices found\n");
3736afd451SNikita Kiryanov return -ENODEV;
387ac2fe2dSIlya Yanok }
39ecdfd69aSSimon Glass if (bootdev->boot_device_name)
40382bee57SSimon Glass env_set("ethact", bootdev->boot_device_name);
41bc0571fcSJoe Hershberger rv = net_loop(BOOTP);
427ac2fe2dSIlya Yanok if (rv < 0) {
437ac2fe2dSIlya Yanok printf("Problem booting with BOOTP\n");
4436afd451SNikita Kiryanov return rv;
457ac2fe2dSIlya Yanok }
466dca5e8aSAndrew F. Davis
476dca5e8aSAndrew F. Davis if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
486dca5e8aSAndrew F. Davis image_get_magic(header) == FDT_MAGIC) {
496dca5e8aSAndrew F. Davis struct spl_load_info load;
506dca5e8aSAndrew F. Davis
516dca5e8aSAndrew F. Davis debug("Found FIT\n");
526dca5e8aSAndrew F. Davis load.bl_len = 1;
536dca5e8aSAndrew F. Davis load.read = spl_net_load_read;
546dca5e8aSAndrew F. Davis rv = spl_load_simple_fit(spl_image, &load, 0, header);
556dca5e8aSAndrew F. Davis } else {
566dca5e8aSAndrew F. Davis debug("Legacy image\n");
576dca5e8aSAndrew F. Davis
586dca5e8aSAndrew F. Davis rv = spl_parse_image_header(spl_image, header);
596dca5e8aSAndrew F. Davis if (rv)
606dca5e8aSAndrew F. Davis return rv;
616dca5e8aSAndrew F. Davis
626dca5e8aSAndrew F. Davis memcpy((void *)spl_image->load_addr, header, spl_image->size);
636dca5e8aSAndrew F. Davis }
646dca5e8aSAndrew F. Davis
656dca5e8aSAndrew F. Davis return rv;
667ac2fe2dSIlya Yanok }
677ec03893SSimon Glass #endif
687ec03893SSimon Glass
697ec03893SSimon Glass #ifdef CONFIG_SPL_ETH_SUPPORT
spl_net_load_image_cpgmac(struct spl_image_info * spl_image,struct spl_boot_device * bootdev)702a2ee2acSSimon Glass int spl_net_load_image_cpgmac(struct spl_image_info *spl_image,
712a2ee2acSSimon Glass struct spl_boot_device *bootdev)
727ec03893SSimon Glass {
737ec03893SSimon Glass #ifdef CONFIG_SPL_ETH_DEVICE
747ec03893SSimon Glass bootdev->boot_device_name = CONFIG_SPL_ETH_DEVICE;
757ec03893SSimon Glass #endif
767ec03893SSimon Glass
772a2ee2acSSimon Glass return spl_net_load_image(spl_image, bootdev);
787ec03893SSimon Glass }
79ebc4ef61SSimon Glass SPL_LOAD_IMAGE_METHOD("eth device", 0, BOOT_DEVICE_CPGMAC,
80ebc4ef61SSimon Glass spl_net_load_image_cpgmac);
817ec03893SSimon Glass #endif
827ec03893SSimon Glass
83b432b1ebSFaiz Abbas #ifdef CONFIG_SPL_USB_ETHER
spl_net_load_image_usb(struct spl_image_info * spl_image,struct spl_boot_device * bootdev)842a2ee2acSSimon Glass int spl_net_load_image_usb(struct spl_image_info *spl_image,
852a2ee2acSSimon Glass struct spl_boot_device *bootdev)
867ec03893SSimon Glass {
877ec03893SSimon Glass bootdev->boot_device_name = "usb_ether";
88*0f46fb58SJean-Jacques Hiblot #if CONFIG_IS_ENABLED(DM_USB_GADGET)
89*0f46fb58SJean-Jacques Hiblot usb_ether_init();
90*0f46fb58SJean-Jacques Hiblot #endif
912a2ee2acSSimon Glass return spl_net_load_image(spl_image, bootdev);
927ec03893SSimon Glass }
93ebc4ef61SSimon Glass SPL_LOAD_IMAGE_METHOD("USB eth", 0, BOOT_DEVICE_USBETH, spl_net_load_image_usb);
947ec03893SSimon Glass #endif
95