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