net: tftp: use IS_ENABLED(CONFIG_NET_TFTP_VARS) instead of #if
[platform/kernel/u-boot.git] / net / bootp.c
index 42e14ed..6c01e38 100644 (file)
@@ -9,13 +9,18 @@
  */
 
 #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
@@ -26,7 +31,7 @@
 
 /*
  * The timeout for the initial BOOTP/DHCP request used to be described by a
- * counter of fixed-length timeout periods. TIMEOUT_COUNT represents
+ * counter of fixed-length timeout periods. CONFIG_NET_RETRY_COUNT represents
  * that counter
  *
  * Now that the timeout periods are variable (exponential backoff and retry)
  * execute that many retries, and keep sending retry packets until that time
  * is reached.
  */
-#ifndef CONFIG_NET_RETRY_COUNT
-# define TIMEOUT_COUNT 5               /* # of timeouts before giving up */
-#else
-# define TIMEOUT_COUNT (CONFIG_NET_RETRY_COUNT)
-#endif
-#define TIMEOUT_MS     ((3 + (TIMEOUT_COUNT * 5)) * 1000)
+#define TIMEOUT_MS     ((3 + (CONFIG_NET_RETRY_COUNT * 5)) * 1000)
 
 #define PORT_BOOTPS    67              /* BOOTP server UDP port */
 #define PORT_BOOTPC    68              /* BOOTP client UDP port */
@@ -59,7 +59,7 @@ ulong         bootp_start;
 ulong          bootp_timeout;
 char net_nis_domain[32] = {0,}; /* Our NIS domain */
 char net_hostname[32] = {0,}; /* Our hostname */
-char net_root_path[64] = {0,}; /* Our bootpath */
+char net_root_path[CONFIG_BOOTP_MAX_ROOT_PATH_LEN] = {0,}; /* Our bootpath */
 
 static ulong time_taken_max;
 
@@ -141,16 +141,20 @@ static int check_reply_packet(uchar *pkt, unsigned dest, unsigned src,
        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 (IS_ENABLED(CONFIG_BOOTP_SERVERIP))
+               return;
+
+#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);
@@ -158,7 +162,8 @@ static void store_net_params(struct bootp_hdr *bp)
 #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));
        }
@@ -170,7 +175,16 @@ static void store_net_params(struct bootp_hdr *bp)
         * not contain a new value
         */
        if (*net_boot_file_name)
-               setenv("bootfile", net_boot_file_name);
+               env_set("bootfile", net_boot_file_name);
+}
+
+/*
+ * 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);
 }
@@ -334,7 +348,7 @@ static void bootp_process_vendor(u8 *ext, int size)
                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
 }
@@ -359,8 +373,8 @@ static void bootp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
        /*
         *      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 */
@@ -387,12 +401,19 @@ static void bootp_timeout_handler(void)
 
        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)
@@ -414,7 +435,7 @@ static void bootp_timeout_handler(void)
 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;
@@ -488,7 +509,7 @@ static int dhcp_extended(u8 *e, int message_type, struct in_addr server_ip,
                *e++ = tmp & 0xff;
        }
 #if defined(CONFIG_BOOTP_SEND_HOSTNAME)
-       hostname = getenv("hostname");
+       hostname = env_get("hostname");
        if (hostname) {
                int hostnamelen = strlen(hostname);
 
@@ -503,8 +524,8 @@ static int dhcp_extended(u8 *e, int message_type, struct in_addr server_ip,
        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 */
@@ -520,7 +541,7 @@ static int dhcp_extended(u8 *e, int message_type, struct in_addr server_ip,
        *e++ = 0;       /* minor revision */
 
 #ifdef CONFIG_LIB_UUID
-       uuid = getenv("pxeuuid");
+       uuid = env_get("pxeuuid");
 
        if (uuid) {
                if (uuid_str_valid(uuid)) {
@@ -622,7 +643,7 @@ static int bootp_extended(u8 *e)
        *e++ = (576 - 312 + OPT_FIELD_SIZE) & 0xff;
 #endif
 
-       add_vci(e);
+       e = add_vci(e);
 
 #if defined(CONFIG_BOOTP_SUBNETMASK)
        *e++ = 1;               /* Subnet mask request */
@@ -713,9 +734,9 @@ void bootp_request(void)
        dhcp_state = INIT;
 #endif
 
-       ep = getenv("bootpretryperiod");
+       ep = env_get("bootpretryperiod");
        if (ep != NULL)
-               time_taken_max = simple_strtoul(ep, NULL, 10);
+               time_taken_max = dectoul(ep, NULL);
        else
                time_taken_max = TIMEOUT_MS;
 
@@ -883,10 +904,13 @@ static void dhcp_process_options(uchar *popt, uchar *end)
                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)
@@ -1009,9 +1033,6 @@ static void dhcp_send_request_packet(struct bootp_hdr *bp_offer)
        bcast_ip.s_addr = 0xFFFFFFFFL;
        net_set_udp_header(iphdr, bcast_ip, PORT_BOOTPS, PORT_BOOTPC, iplen);
 
-#ifdef CONFIG_BOOTP_DHCP_REQUEST_DELAY
-       udelay(CONFIG_BOOTP_DHCP_REQUEST_DELAY);
-#endif /* CONFIG_BOOTP_DHCP_REQUEST_DELAY */
        debug("Transmitting DHCPREQUEST packet: len = %d\n", pktlen);
        net_send_packet(net_tx_packet, pktlen);
 }
@@ -1034,8 +1055,12 @@ static void dhcp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
        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:
@@ -1052,7 +1077,15 @@ static void dhcp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
                            strlen(CONFIG_SYS_BOOTFILE_PREFIX)) == 0) {
 #endif /* CONFIG_SYS_BOOTFILE_PREFIX */
                        dhcp_packet_process_options(bp);
-                       efi_net_set_dhcp_ack(pkt, len);
+                       if (CONFIG_IS_ENABLED(EFI_LOADER) &&
+                           CONFIG_IS_ENABLED(NET_DEVICES))
+                               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;