1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2000-2004 4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 5 * 6 * (C) Copyright 2012 7 * Ilya Yanok <ilya.yanok@gmail.com> 8 */ 9 #include <common.h> 10 #include <errno.h> 11 #include <spl.h> 12 #include <net.h> 13 #include <linux/libfdt.h> 14 15 #if defined(CONFIG_SPL_ETH_SUPPORT) || defined(CONFIG_SPL_USB_ETHER) 16 static ulong spl_net_load_read(struct spl_load_info *load, ulong sector, 17 ulong count, void *buf) 18 { 19 debug("%s: sector %lx, count %lx, buf %lx\n", 20 __func__, sector, count, (ulong)buf); 21 memcpy(buf, (void *)(load_addr + sector), count); 22 return count; 23 } 24 25 static int spl_net_load_image(struct spl_image_info *spl_image, 26 struct spl_boot_device *bootdev) 27 { 28 struct image_header *header = (struct image_header *)load_addr; 29 int rv; 30 31 env_init(); 32 env_relocate(); 33 env_set("autoload", "yes"); 34 rv = eth_initialize(); 35 if (rv == 0) { 36 printf("No Ethernet devices found\n"); 37 return -ENODEV; 38 } 39 if (bootdev->boot_device_name) 40 env_set("ethact", bootdev->boot_device_name); 41 rv = net_loop(BOOTP); 42 if (rv < 0) { 43 printf("Problem booting with BOOTP\n"); 44 return rv; 45 } 46 47 if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && 48 image_get_magic(header) == FDT_MAGIC) { 49 struct spl_load_info load; 50 51 debug("Found FIT\n"); 52 load.bl_len = 1; 53 load.read = spl_net_load_read; 54 rv = spl_load_simple_fit(spl_image, &load, 0, header); 55 } else { 56 debug("Legacy image\n"); 57 58 rv = spl_parse_image_header(spl_image, header); 59 if (rv) 60 return rv; 61 62 memcpy((void *)spl_image->load_addr, header, spl_image->size); 63 } 64 65 return rv; 66 } 67 #endif 68 69 #ifdef CONFIG_SPL_ETH_SUPPORT 70 int spl_net_load_image_cpgmac(struct spl_image_info *spl_image, 71 struct spl_boot_device *bootdev) 72 { 73 #ifdef CONFIG_SPL_ETH_DEVICE 74 bootdev->boot_device_name = CONFIG_SPL_ETH_DEVICE; 75 #endif 76 77 return spl_net_load_image(spl_image, bootdev); 78 } 79 SPL_LOAD_IMAGE_METHOD("eth device", 0, BOOT_DEVICE_CPGMAC, 80 spl_net_load_image_cpgmac); 81 #endif 82 83 #ifdef CONFIG_SPL_USB_ETHER 84 int spl_net_load_image_usb(struct spl_image_info *spl_image, 85 struct spl_boot_device *bootdev) 86 { 87 bootdev->boot_device_name = "usb_ether"; 88 #if CONFIG_IS_ENABLED(DM_USB_GADGET) 89 usb_ether_init(); 90 #endif 91 return spl_net_load_image(spl_image, bootdev); 92 } 93 SPL_LOAD_IMAGE_METHOD("USB eth", 0, BOOT_DEVICE_USBETH, spl_net_load_image_usb); 94 #endif 95