17ac2fe2dSIlya Yanok /*
27ac2fe2dSIlya Yanok * (C) Copyright 2000-2004
37ac2fe2dSIlya Yanok * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
47ac2fe2dSIlya Yanok *
57ac2fe2dSIlya Yanok * (C) Copyright 2012
67ac2fe2dSIlya Yanok * Ilya Yanok <ilya.yanok@gmail.com>
77ac2fe2dSIlya Yanok *
81a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+
97ac2fe2dSIlya Yanok */
107ac2fe2dSIlya Yanok #include <common.h>
1136afd451SNikita Kiryanov #include <errno.h>
127ac2fe2dSIlya Yanok #include <spl.h>
137ac2fe2dSIlya Yanok #include <net.h>
140e00a84cSMasahiro Yamada #include <linux/libfdt.h>
157ac2fe2dSIlya Yanok
167ac2fe2dSIlya Yanok DECLARE_GLOBAL_DATA_PTR;
177ac2fe2dSIlya Yanok
187ec03893SSimon Glass #if defined(CONFIG_SPL_ETH_SUPPORT) || defined(CONFIG_SPL_USBETH_SUPPORT)
spl_net_load_read(struct spl_load_info * load,ulong sector,ulong count,void * buf)196dca5e8aSAndrew F. Davis static ulong spl_net_load_read(struct spl_load_info *load, ulong sector,
206dca5e8aSAndrew F. Davis ulong count, void *buf)
216dca5e8aSAndrew F. Davis {
226dca5e8aSAndrew F. Davis debug("%s: sector %lx, count %lx, buf %lx\n",
236dca5e8aSAndrew F. Davis __func__, sector, count, (ulong)buf);
246dca5e8aSAndrew F. Davis memcpy(buf, (void *)(load_addr + sector), count);
256dca5e8aSAndrew F. Davis return count;
266dca5e8aSAndrew F. Davis }
276dca5e8aSAndrew F. Davis
spl_net_load_image(struct spl_image_info * spl_image,struct spl_boot_device * bootdev)282a2ee2acSSimon Glass static int spl_net_load_image(struct spl_image_info *spl_image,
292a2ee2acSSimon Glass struct spl_boot_device *bootdev)
307ac2fe2dSIlya Yanok {
316dca5e8aSAndrew F. Davis struct image_header *header = (struct image_header *)load_addr;
327ac2fe2dSIlya Yanok int rv;
337ac2fe2dSIlya Yanok
347ac2fe2dSIlya Yanok env_init();
357ac2fe2dSIlya Yanok env_relocate();
36382bee57SSimon Glass env_set("autoload", "yes");
37d2eaec60SJoe Hershberger rv = eth_initialize();
387ac2fe2dSIlya Yanok if (rv == 0) {
397ac2fe2dSIlya Yanok printf("No Ethernet devices found\n");
4036afd451SNikita Kiryanov return -ENODEV;
417ac2fe2dSIlya Yanok }
42ecdfd69aSSimon Glass if (bootdev->boot_device_name)
43382bee57SSimon Glass env_set("ethact", bootdev->boot_device_name);
44bc0571fcSJoe Hershberger rv = net_loop(BOOTP);
457ac2fe2dSIlya Yanok if (rv < 0) {
467ac2fe2dSIlya Yanok printf("Problem booting with BOOTP\n");
4736afd451SNikita Kiryanov return rv;
487ac2fe2dSIlya Yanok }
496dca5e8aSAndrew F. Davis
50*22c7c1a8SJoseph Chen #ifdef CONFIG_SPL_FIT_IMAGE_MULTIPLE
51*22c7c1a8SJoseph Chen if ((IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
52*22c7c1a8SJoseph Chen image_get_magic(header) == FDT_MAGIC) ||
53*22c7c1a8SJoseph Chen CONFIG_SPL_FIT_IMAGE_MULTIPLE > 1) {
54*22c7c1a8SJoseph Chen #else
556dca5e8aSAndrew F. Davis if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
566dca5e8aSAndrew F. Davis image_get_magic(header) == FDT_MAGIC) {
57*22c7c1a8SJoseph Chen #endif
586dca5e8aSAndrew F. Davis struct spl_load_info load;
596dca5e8aSAndrew F. Davis
606dca5e8aSAndrew F. Davis debug("Found FIT\n");
616dca5e8aSAndrew F. Davis load.bl_len = 1;
626dca5e8aSAndrew F. Davis load.read = spl_net_load_read;
636dca5e8aSAndrew F. Davis rv = spl_load_simple_fit(spl_image, &load, 0, header);
646dca5e8aSAndrew F. Davis } else {
656dca5e8aSAndrew F. Davis debug("Legacy image\n");
666dca5e8aSAndrew F. Davis
676dca5e8aSAndrew F. Davis rv = spl_parse_image_header(spl_image, header);
686dca5e8aSAndrew F. Davis if (rv)
696dca5e8aSAndrew F. Davis return rv;
706dca5e8aSAndrew F. Davis
716dca5e8aSAndrew F. Davis memcpy((void *)spl_image->load_addr, header, spl_image->size);
726dca5e8aSAndrew F. Davis }
736dca5e8aSAndrew F. Davis
746dca5e8aSAndrew F. Davis return rv;
757ac2fe2dSIlya Yanok }
767ec03893SSimon Glass #endif
777ec03893SSimon Glass
787ec03893SSimon Glass #ifdef CONFIG_SPL_ETH_SUPPORT
792a2ee2acSSimon Glass int spl_net_load_image_cpgmac(struct spl_image_info *spl_image,
802a2ee2acSSimon Glass struct spl_boot_device *bootdev)
817ec03893SSimon Glass {
827ec03893SSimon Glass #ifdef CONFIG_SPL_ETH_DEVICE
837ec03893SSimon Glass bootdev->boot_device_name = CONFIG_SPL_ETH_DEVICE;
847ec03893SSimon Glass #endif
857ec03893SSimon Glass
862a2ee2acSSimon Glass return spl_net_load_image(spl_image, bootdev);
877ec03893SSimon Glass }
88ebc4ef61SSimon Glass SPL_LOAD_IMAGE_METHOD("eth device", 0, BOOT_DEVICE_CPGMAC,
89ebc4ef61SSimon Glass spl_net_load_image_cpgmac);
907ec03893SSimon Glass #endif
917ec03893SSimon Glass
927ec03893SSimon Glass #ifdef CONFIG_SPL_USBETH_SUPPORT
932a2ee2acSSimon Glass int spl_net_load_image_usb(struct spl_image_info *spl_image,
942a2ee2acSSimon Glass struct spl_boot_device *bootdev)
957ec03893SSimon Glass {
967ec03893SSimon Glass bootdev->boot_device_name = "usb_ether";
977ec03893SSimon Glass
982a2ee2acSSimon Glass return spl_net_load_image(spl_image, bootdev);
997ec03893SSimon Glass }
100ebc4ef61SSimon Glass SPL_LOAD_IMAGE_METHOD("USB eth", 0, BOOT_DEVICE_USBETH, spl_net_load_image_usb);
1017ec03893SSimon Glass #endif
102