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 DECLARE_GLOBAL_DATA_PTR; 17 18 #if defined(CONFIG_SPL_ETH_SUPPORT) || defined(CONFIG_SPL_USBETH_SUPPORT) 19 static ulong spl_net_load_read(struct spl_load_info *load, ulong sector, 20 ulong count, void *buf) 21 { 22 debug("%s: sector %lx, count %lx, buf %lx\n", 23 __func__, sector, count, (ulong)buf); 24 memcpy(buf, (void *)(load_addr + sector), count); 25 return count; 26 } 27 28 static int spl_net_load_image(struct spl_image_info *spl_image, 29 struct spl_boot_device *bootdev) 30 { 31 struct image_header *header = (struct image_header *)load_addr; 32 int rv; 33 34 env_init(); 35 env_relocate(); 36 env_set("autoload", "yes"); 37 rv = eth_initialize(); 38 if (rv == 0) { 39 printf("No Ethernet devices found\n"); 40 return -ENODEV; 41 } 42 if (bootdev->boot_device_name) 43 env_set("ethact", bootdev->boot_device_name); 44 rv = net_loop(BOOTP); 45 if (rv < 0) { 46 printf("Problem booting with BOOTP\n"); 47 return rv; 48 } 49 50 #ifdef CONFIG_SPL_FIT_IMAGE_MULTIPLE 51 if ((IS_ENABLED(CONFIG_SPL_LOAD_FIT) && 52 image_get_magic(header) == FDT_MAGIC) || 53 CONFIG_SPL_FIT_IMAGE_MULTIPLE > 1) { 54 #else 55 if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && 56 image_get_magic(header) == FDT_MAGIC) { 57 #endif 58 struct spl_load_info load; 59 60 debug("Found FIT\n"); 61 load.bl_len = 1; 62 load.read = spl_net_load_read; 63 rv = spl_load_simple_fit(spl_image, &load, 0, header); 64 } else { 65 debug("Legacy image\n"); 66 67 rv = spl_parse_image_header(spl_image, header); 68 if (rv) 69 return rv; 70 71 memcpy((void *)spl_image->load_addr, header, spl_image->size); 72 } 73 74 return rv; 75 } 76 #endif 77 78 #ifdef CONFIG_SPL_ETH_SUPPORT 79 int spl_net_load_image_cpgmac(struct spl_image_info *spl_image, 80 struct spl_boot_device *bootdev) 81 { 82 #ifdef CONFIG_SPL_ETH_DEVICE 83 bootdev->boot_device_name = CONFIG_SPL_ETH_DEVICE; 84 #endif 85 86 return spl_net_load_image(spl_image, bootdev); 87 } 88 SPL_LOAD_IMAGE_METHOD("eth device", 0, BOOT_DEVICE_CPGMAC, 89 spl_net_load_image_cpgmac); 90 #endif 91 92 #ifdef CONFIG_SPL_USBETH_SUPPORT 93 int spl_net_load_image_usb(struct spl_image_info *spl_image, 94 struct spl_boot_device *bootdev) 95 { 96 bootdev->boot_device_name = "usb_ether"; 97 98 return spl_net_load_image(spl_image, bootdev); 99 } 100 SPL_LOAD_IMAGE_METHOD("USB eth", 0, BOOT_DEVICE_USBETH, spl_net_load_image_usb); 101 #endif 102