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> 14*0e00a84cSMasahiro 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) 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 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 506dca5e8aSAndrew F. Davis if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && 516dca5e8aSAndrew F. Davis image_get_magic(header) == FDT_MAGIC) { 526dca5e8aSAndrew F. Davis struct spl_load_info load; 536dca5e8aSAndrew F. Davis 546dca5e8aSAndrew F. Davis debug("Found FIT\n"); 556dca5e8aSAndrew F. Davis load.bl_len = 1; 566dca5e8aSAndrew F. Davis load.read = spl_net_load_read; 576dca5e8aSAndrew F. Davis rv = spl_load_simple_fit(spl_image, &load, 0, header); 586dca5e8aSAndrew F. Davis } else { 596dca5e8aSAndrew F. Davis debug("Legacy image\n"); 606dca5e8aSAndrew F. Davis 616dca5e8aSAndrew F. Davis rv = spl_parse_image_header(spl_image, header); 626dca5e8aSAndrew F. Davis if (rv) 636dca5e8aSAndrew F. Davis return rv; 646dca5e8aSAndrew F. Davis 656dca5e8aSAndrew F. Davis memcpy((void *)spl_image->load_addr, header, spl_image->size); 666dca5e8aSAndrew F. Davis } 676dca5e8aSAndrew F. Davis 686dca5e8aSAndrew F. Davis return rv; 697ac2fe2dSIlya Yanok } 707ec03893SSimon Glass #endif 717ec03893SSimon Glass 727ec03893SSimon Glass #ifdef CONFIG_SPL_ETH_SUPPORT 732a2ee2acSSimon Glass int spl_net_load_image_cpgmac(struct spl_image_info *spl_image, 742a2ee2acSSimon Glass struct spl_boot_device *bootdev) 757ec03893SSimon Glass { 767ec03893SSimon Glass #ifdef CONFIG_SPL_ETH_DEVICE 777ec03893SSimon Glass bootdev->boot_device_name = CONFIG_SPL_ETH_DEVICE; 787ec03893SSimon Glass #endif 797ec03893SSimon Glass 802a2ee2acSSimon Glass return spl_net_load_image(spl_image, bootdev); 817ec03893SSimon Glass } 82ebc4ef61SSimon Glass SPL_LOAD_IMAGE_METHOD("eth device", 0, BOOT_DEVICE_CPGMAC, 83ebc4ef61SSimon Glass spl_net_load_image_cpgmac); 847ec03893SSimon Glass #endif 857ec03893SSimon Glass 867ec03893SSimon Glass #ifdef CONFIG_SPL_USBETH_SUPPORT 872a2ee2acSSimon Glass int spl_net_load_image_usb(struct spl_image_info *spl_image, 882a2ee2acSSimon Glass struct spl_boot_device *bootdev) 897ec03893SSimon Glass { 907ec03893SSimon Glass bootdev->boot_device_name = "usb_ether"; 917ec03893SSimon Glass 922a2ee2acSSimon Glass return spl_net_load_image(spl_image, bootdev); 937ec03893SSimon Glass } 94ebc4ef61SSimon Glass SPL_LOAD_IMAGE_METHOD("USB eth", 0, BOOT_DEVICE_USBETH, spl_net_load_image_usb); 957ec03893SSimon Glass #endif 96