*/
#include <common.h>
+#include <bootstage.h>
#include <command.h>
+#include <env.h>
#include <efi_loader.h>
+#include <log.h>
#include <net.h>
+#include <rand.h>
+#include <uuid.h>
+#include <linux/delay.h>
#include <net/tftp.h>
#include "bootp.h"
-#include "nfs.h"
-#ifdef CONFIG_STATUS_LED
+#ifdef CONFIG_LED_STATUS
#include <status_led.h>
#endif
#ifdef CONFIG_BOOTP_RANDOM_DELAY
return retval;
}
-/*
- * Copy parameters of interest from BOOTP_REPLY/DHCP_OFFER packet
- */
-static void store_net_params(struct bootp_hdr *bp)
+static void store_bootp_params(struct bootp_hdr *bp)
{
#if !defined(CONFIG_BOOTP_SERVERIP)
struct in_addr tmp_ip;
+ bool overwrite_serverip = true;
+
+#if defined(CONFIG_BOOTP_PREFER_SERVERIP)
+ overwrite_serverip = false;
+#endif
net_copy_ip(&tmp_ip, &bp->bp_siaddr);
- if (tmp_ip.s_addr != 0)
+ if (tmp_ip.s_addr != 0 && (overwrite_serverip || !net_server_ip.s_addr))
net_copy_ip(&net_server_ip, &bp->bp_siaddr);
memcpy(net_server_ethaddr,
((struct ethernet_hdr *)net_rx_packet)->et_src, 6);
#if defined(CONFIG_CMD_DHCP)
!(dhcp_option_overload & OVERLOAD_FILE) &&
#endif
- (strlen(bp->bp_file) > 0)) {
+ (strlen(bp->bp_file) > 0) &&
+ !net_boot_file_name_explicit) {
copy_filename(net_boot_file_name, bp->bp_file,
sizeof(net_boot_file_name));
}
* not contain a new value
*/
if (*net_boot_file_name)
- setenv("bootfile", net_boot_file_name);
+ env_set("bootfile", net_boot_file_name);
+#endif
+}
+
+/*
+ * Copy parameters of interest from BOOTP_REPLY/DHCP_OFFER packet
+ */
+static void store_net_params(struct bootp_hdr *bp)
+{
+#if !defined(CONFIG_SERVERIP_FROM_PROXYDHCP)
+ store_bootp_params(bp);
#endif
net_copy_ip(&net_ip, &bp->bp_yiaddr);
}
debug("net_nis_domain : %s\n", net_nis_domain);
#if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_NTPSERVER)
- if (net_ntp_server)
+ if (net_ntp_server.s_addr)
debug("net_ntp_server : %pI4\n", &net_ntp_server);
#endif
}
/*
* Got a good BOOTP reply. Copy the data into our variables.
*/
-#if defined(CONFIG_STATUS_LED) && defined(STATUS_LED_BOOT)
- status_led_set(STATUS_LED_BOOT, STATUS_LED_OFF);
+#if defined(CONFIG_LED_STATUS) && defined(CONFIG_LED_STATUS_BOOT_ENABLE)
+ status_led_set(CONFIG_LED_STATUS_BOOT, CONFIG_LED_STATUS_OFF);
#endif
store_net_params(bp); /* Store net parameters from reply */
if (time_taken >= time_taken_max) {
#ifdef CONFIG_BOOTP_MAY_FAIL
- puts("\nRetry time exceeded\n");
- net_set_state(NETLOOP_FAIL);
-#else
- puts("\nRetry time exceeded; starting again\n");
- net_start_again();
+ char *ethrotate;
+
+ ethrotate = env_get("ethrotate");
+ if ((ethrotate && strcmp(ethrotate, "no") == 0) ||
+ net_restart_wrap) {
+ puts("\nRetry time exceeded\n");
+ net_set_state(NETLOOP_FAIL);
+ } else
#endif
+ {
+ puts("\nRetry time exceeded; starting again\n");
+ net_start_again();
+ }
} else {
bootp_timeout *= 2;
if (bootp_timeout > 2000)
static u8 *add_vci(u8 *e)
{
char *vci = NULL;
- char *env_vci = getenv("bootp_vci");
+ char *env_vci = env_get("bootp_vci");
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_NET_VCI_STRING)
vci = CONFIG_SPL_NET_VCI_STRING;
*e++ = tmp & 0xff;
}
#if defined(CONFIG_BOOTP_SEND_HOSTNAME)
- hostname = getenv("hostname");
+ hostname = env_get("hostname");
if (hostname) {
int hostnamelen = strlen(hostname);
clientarch = CONFIG_BOOTP_PXE_CLIENTARCH;
#endif
- if (getenv("bootp_arch"))
- clientarch = getenv_ulong("bootp_arch", 16, clientarch);
+ if (env_get("bootp_arch"))
+ clientarch = env_get_ulong("bootp_arch", 16, clientarch);
if (clientarch > 0) {
*e++ = 93; /* Client System Architecture */
*e++ = 0; /* minor revision */
#ifdef CONFIG_LIB_UUID
- uuid = getenv("pxeuuid");
+ uuid = env_get("pxeuuid");
if (uuid) {
if (uuid_str_valid(uuid)) {
dhcp_state = INIT;
#endif
- ep = getenv("bootpretryperiod");
+ ep = env_get("bootpretryperiod");
if (ep != NULL)
time_taken_max = simple_strtoul(ep, NULL, 10);
else
case 66: /* Ignore TFTP server name */
break;
case 67: /* Bootfile option */
- size = truncate_sz("Bootfile",
- sizeof(net_boot_file_name), oplen);
- memcpy(&net_boot_file_name, popt + 2, size);
- net_boot_file_name[size] = 0;
+ if (!net_boot_file_name_explicit) {
+ size = truncate_sz("Bootfile",
+ sizeof(net_boot_file_name),
+ oplen);
+ memcpy(&net_boot_file_name, popt + 2, size);
+ net_boot_file_name[size] = 0;
+ }
break;
default:
#if defined(CONFIG_BOOTP_VENDOREX)
debug("DHCPHandler: got DHCP packet: (src=%d, dst=%d, len=%d) state: "
"%d\n", src, dest, len, dhcp_state);
- if (net_read_ip(&bp->bp_yiaddr).s_addr == 0)
+ if (net_read_ip(&bp->bp_yiaddr).s_addr == 0) {
+#if defined(CONFIG_SERVERIP_FROM_PROXYDHCP)
+ store_bootp_params(bp);
+#endif
return;
+ }
switch (dhcp_state) {
case SELECTING:
dhcp_packet_process_options(bp);
efi_net_set_dhcp_ack(pkt, len);
+#if defined(CONFIG_SERVERIP_FROM_PROXYDHCP)
+ if (!net_server_ip.s_addr)
+ udelay(CONFIG_SERVERIP_FROM_PROXYDHCP_DELAY_MS *
+ 1000);
+#endif /* CONFIG_SERVERIP_FROM_PROXYDHCP */
+
debug("TRANSITIONING TO REQUESTING STATE\n");
dhcp_state = REQUESTING;