]> git.sur5r.net Git - u-boot/blobdiff - net/bootp.c
spi: fsl_qspi: Fix issues on arm64
[u-boot] / net / bootp.c
index 9cf0d640259b9545d3bc002e03265f2a2918befb..d7852dbb447a123b5e45af89e6483b5d5c3a9a53 100644 (file)
@@ -60,6 +60,8 @@ char net_nis_domain[32] = {0,}; /* Our NIS domain */
 char net_hostname[32] = {0,}; /* Our hostname */
 char net_root_path[64] = {0,}; /* Our bootpath */
 
+static ulong time_taken_max;
+
 #if defined(CONFIG_CMD_DHCP)
 static dhcp_state_t dhcp_state = INIT;
 static u32 dhcp_leasetime;
@@ -130,6 +132,8 @@ static int check_reply_packet(uchar *pkt, unsigned dest, unsigned src,
                retval = -5;
        else if (!bootp_match_id(net_read_u32(&bp->bp_id)))
                retval = -6;
+       else if (memcmp(bp->bp_chaddr, net_ethaddr, HWL_ETHER) != 0)
+               retval = -7;
 
        debug("Filtering pkt = %d\n", retval);
 
@@ -380,7 +384,7 @@ static void bootp_timeout_handler(void)
 {
        ulong time_taken = get_timer(bootp_start);
 
-       if (time_taken >= TIMEOUT_MS) {
+       if (time_taken >= time_taken_max) {
 #ifdef CONFIG_BOOTP_MAY_FAIL
                puts("\nRetry time exceeded\n");
                net_set_state(NETLOOP_FAIL);
@@ -675,12 +679,19 @@ void bootp_request(void)
        u32 bootp_id;
        struct in_addr zero_ip;
        struct in_addr bcast_ip;
+       char *ep;  /* Environment pointer */
 
        bootstage_mark_name(BOOTSTAGE_ID_BOOTP_START, "bootp_start");
 #if defined(CONFIG_CMD_DHCP)
        dhcp_state = INIT;
 #endif
 
+       ep = getenv("bootpretryperiod");
+       if (ep != NULL)
+               time_taken_max = simple_strtoul(ep, NULL, 10);
+       else
+               time_taken_max = TIMEOUT_MS;
+
 #ifdef CONFIG_BOOTP_RANDOM_DELAY               /* Random BOOTP delay */
        if (bootp_try == 0)
                srand_mac();
@@ -773,14 +784,12 @@ void bootp_request(void)
 }
 
 #if defined(CONFIG_CMD_DHCP)
-static void dhcp_process_options(uchar *popt, struct bootp_hdr *bp)
+static void dhcp_process_options(uchar *popt, uchar *end)
 {
-       uchar *end = popt + BOOTP_HDR_SIZE;
        int oplen, size;
 #if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_TIMEOFFSET)
        int *to_ptr;
 #endif
-       dhcp_option_overload = 0;
 
        while (popt < end && *popt != 0xff) {
                oplen = *(popt + 1);
@@ -865,6 +874,35 @@ static void dhcp_process_options(uchar *popt, struct bootp_hdr *bp)
        }
 }
 
+static void dhcp_packet_process_options(struct bootp_hdr *bp)
+{
+       uchar *popt = (uchar *)&bp->bp_vend[4];
+       uchar *end = popt + BOOTP_HDR_SIZE;
+
+       if (net_read_u32((u32 *)&bp->bp_vend[0]) != htonl(BOOTP_VENDOR_MAGIC))
+               return;
+
+       dhcp_option_overload = 0;
+
+       /*
+        * The 'options' field MUST be interpreted first, 'file' next,
+        * 'sname' last.
+        */
+       dhcp_process_options(popt, end);
+
+       if (dhcp_option_overload & OVERLOAD_FILE) {
+               popt = (uchar *)bp->bp_file;
+               end = popt + sizeof(bp->bp_file);
+               dhcp_process_options(popt, end);
+       }
+
+       if (dhcp_option_overload & OVERLOAD_SNAME) {
+               popt = (uchar *)bp->bp_sname;
+               end = popt + sizeof(bp->bp_sname);
+               dhcp_process_options(popt, end);
+       }
+}
+
 static int dhcp_message_type(unsigned char *popt)
 {
        if (net_read_u32((u32 *)popt) != htonl(BOOTP_VENDOR_MAGIC))
@@ -922,6 +960,7 @@ static void dhcp_send_request_packet(struct bootp_hdr *bp_offer)
        net_write_ip(&bp->bp_giaddr, zero_ip);
 
        memcpy(bp->bp_chaddr, net_ethaddr, 6);
+       copy_filename(bp->bp_file, net_boot_file_name, sizeof(bp->bp_file));
 
        /*
         * ID is the id of the OFFER packet
@@ -968,6 +1007,9 @@ 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)
+               return;
+
        switch (dhcp_state) {
        case SELECTING:
                /*
@@ -982,14 +1024,11 @@ static void dhcp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
                            CONFIG_SYS_BOOTFILE_PREFIX,
                            strlen(CONFIG_SYS_BOOTFILE_PREFIX)) == 0) {
 #endif /* CONFIG_SYS_BOOTFILE_PREFIX */
+                       dhcp_packet_process_options(bp);
 
                        debug("TRANSITIONING TO REQUESTING STATE\n");
                        dhcp_state = REQUESTING;
 
-                       if (net_read_u32((u32 *)&bp->bp_vend[0]) ==
-                                               htonl(BOOTP_VENDOR_MAGIC))
-                               dhcp_process_options((u8 *)&bp->bp_vend[4], bp);
-
                        net_set_timeout_handler(5000, bootp_timeout_handler);
                        dhcp_send_request_packet(bp);
 #ifdef CONFIG_SYS_BOOTFILE_PREFIX
@@ -1002,9 +1041,7 @@ static void dhcp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
                debug("DHCP State: REQUESTING\n");
 
                if (dhcp_message_type((u8 *)bp->bp_vend) == DHCP_ACK) {
-                       if (net_read_u32((u32 *)&bp->bp_vend[0]) ==
-                                               htonl(BOOTP_VENDOR_MAGIC))
-                               dhcp_process_options((u8 *)&bp->bp_vend[4], bp);
+                       dhcp_packet_process_options(bp);
                        /* Store net params from reply */
                        store_net_params(bp);
                        dhcp_state = BOUND;