dm: core: Tidy up ofnode-writing test
[platform/kernel/u-boot.git] / net / net.c
index 58b0417..81905f6 100644 (file)
--- a/net/net.c
+++ b/net/net.c
  *     We want:        - load the boot file
  *     Next step:      none
  *
- * SNTP:
- *
- *     Prerequisites:  - own ethernet address
- *                     - own IP address
- *     We want:        - network time
- *     Next step:      none
  *
  * WOL:
  *
 
 
 #include <common.h>
+#include <bootstage.h>
 #include <command.h>
 #include <console.h>
-#include <environment.h>
+#include <env.h>
+#include <env_internal.h>
 #include <errno.h>
+#include <image.h>
+#include <log.h>
 #include <net.h>
 #include <net/fastboot.h>
 #include <net/tftp.h>
+#if defined(CONFIG_CMD_PCAP)
+#include <net/pcap.h>
+#endif
+#include <net/udp.h>
 #if defined(CONFIG_LED_STATUS)
 #include <miiphy.h>
 #include <status_led.h>
 #include "nfs.h"
 #include "ping.h"
 #include "rarp.h"
-#if defined(CONFIG_CMD_SNTP)
-#include "sntp.h"
-#endif
 #if defined(CONFIG_CMD_WOL)
 #include "wol.h"
 #endif
@@ -177,13 +176,6 @@ u32 net_boot_file_size;
 /* Boot file size in blocks as reported by the DHCP server */
 u32 net_boot_file_expected_size_in_blocks;
 
-#if defined(CONFIG_CMD_SNTP)
-/* NTP server IP address */
-struct in_addr net_ntp_server;
-/* offset time from UTC */
-int            net_ntp_time_offset;
-#endif
-
 static uchar net_pkt_buf[(PKTBUFSRX+1) * PKTSIZE_ALIGN + PKTALIGN];
 /* Receive packets */
 uchar *net_rx_packets[PKTBUFSRX];
@@ -304,18 +296,18 @@ U_BOOT_ENV_CALLBACK(dnsip, on_dnsip);
  */
 void net_auto_load(void)
 {
-#if defined(CONFIG_CMD_NFS)
+#if defined(CONFIG_CMD_NFS) && !defined(CONFIG_SPL_BUILD)
        const char *s = env_get("autoload");
 
        if (s != NULL && strcmp(s, "NFS") == 0) {
                if (net_check_prereq(NFS)) {
 /* We aren't expecting to get a serverip, so just accept the assigned IP */
-#ifdef CONFIG_BOOTP_SERVERIP
-                       net_set_state(NETLOOP_SUCCESS);
-#else
-                       printf("Cannot autoload with NFS\n");
-                       net_set_state(NETLOOP_FAIL);
-#endif
+                       if (IS_ENABLED(CONFIG_BOOTP_SERVERIP)) {
+                               net_set_state(NETLOOP_SUCCESS);
+                       } else {
+                               printf("Cannot autoload with NFS\n");
+                               net_set_state(NETLOOP_FAIL);
+                       }
                        return;
                }
                /*
@@ -335,23 +327,30 @@ void net_auto_load(void)
        }
        if (net_check_prereq(TFTPGET)) {
 /* We aren't expecting to get a serverip, so just accept the assigned IP */
-#ifdef CONFIG_BOOTP_SERVERIP
-               net_set_state(NETLOOP_SUCCESS);
-#else
-               printf("Cannot autoload with TFTPGET\n");
-               net_set_state(NETLOOP_FAIL);
-#endif
+               if (IS_ENABLED(CONFIG_BOOTP_SERVERIP)) {
+                       net_set_state(NETLOOP_SUCCESS);
+               } else {
+                       printf("Cannot autoload with TFTPGET\n");
+                       net_set_state(NETLOOP_FAIL);
+               }
                return;
        }
        tftp_start(TFTPGET);
 }
 
-static void net_init_loop(void)
+static int net_init_loop(void)
 {
        if (eth_get_dev())
                memcpy(net_ethaddr, eth_get_ethaddr(), 6);
+       else
+               /*
+                * Not ideal, but there's no way to get the actual error, and I
+                * don't feel like fixing all the users of eth_get_dev to deal
+                * with errors.
+                */
+               return -ENONET;
 
-       return;
+       return 0;
 }
 
 static void net_clear_handlers(void)
@@ -366,7 +365,7 @@ static void net_cleanup_loop(void)
        net_clear_handlers();
 }
 
-void net_init(void)
+int net_init(void)
 {
        static int first_call = 1;
 
@@ -389,7 +388,7 @@ void net_init(void)
                first_call = 0;
        }
 
-       net_init_loop();
+       return net_init_loop();
 }
 
 /**********************************************************************/
@@ -402,6 +401,10 @@ int net_loop(enum proto_t protocol)
        int ret = -EINVAL;
        enum net_loop_state prev_net_state = net_state;
 
+#if defined(CONFIG_CMD_PING)
+       if (protocol != PING)
+               net_ping_ip.s_addr = 0;
+#endif
        net_restarted = 0;
        net_dev_exists = 0;
        net_try_count = 1;
@@ -409,7 +412,7 @@ int net_loop(enum proto_t protocol)
 
        bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start");
        net_init();
-       if (eth_is_on_demand_init() || protocol != NETCONS) {
+       if (eth_is_on_demand_init()) {
                eth_halt();
                eth_set_current();
                ret = eth_init();
@@ -449,6 +452,7 @@ restart:
                net_dev_exists = 1;
                net_boot_file_size = 0;
                switch (protocol) {
+#ifdef CONFIG_CMD_TFTPBOOT
                case TFTPGET:
 #ifdef CONFIG_CMD_TFTPPUT
                case TFTPPUT:
@@ -456,6 +460,7 @@ restart:
                        /* always use ARP to get server ethernet address */
                        tftp_start(protocol);
                        break;
+#endif
 #ifdef CONFIG_CMD_TFTPSRV
                case TFTPSRV:
                        tftp_start_server();
@@ -473,13 +478,13 @@ restart:
                        dhcp_request();         /* Basically same as BOOTP */
                        break;
 #endif
-
+#if defined(CONFIG_CMD_BOOTP)
                case BOOTP:
                        bootp_reset();
                        net_ip.s_addr = 0;
                        bootp_request();
                        break;
-
+#endif
 #if defined(CONFIG_CMD_RARP)
                case RARP:
                        rarp_try = 0;
@@ -492,7 +497,7 @@ restart:
                        ping_start();
                        break;
 #endif
-#if defined(CONFIG_CMD_NFS)
+#if defined(CONFIG_CMD_NFS) && !defined(CONFIG_SPL_BUILD)
                case NFS:
                        nfs_start();
                        break;
@@ -507,11 +512,6 @@ restart:
                        nc_start();
                        break;
 #endif
-#if defined(CONFIG_CMD_SNTP)
-               case SNTP:
-                       sntp_start();
-                       break;
-#endif
 #if defined(CONFIG_CMD_DNS)
                case DNS:
                        dns_start();
@@ -531,6 +531,9 @@ restart:
                        break;
                }
 
+               if (IS_ENABLED(CONFIG_PROT_UDP) && protocol == UDP)
+                       udp_start();
+
                break;
        }
 
@@ -557,9 +560,6 @@ restart:
         */
        for (;;) {
                WATCHDOG_RESET();
-#ifdef CONFIG_SHOW_ACTIVITY
-               show_activity(1);
-#endif
                if (arp_timeout_check() > 0)
                        time_start = get_timer(0);
 
@@ -635,7 +635,7 @@ restart:
                                printf("Bytes transferred = %d (%x hex)\n",
                                       net_boot_file_size, net_boot_file_size);
                                env_set_hex("filesize", net_boot_file_size);
-                               env_set_hex("fileaddr", load_addr);
+                               env_set_hex("fileaddr", image_load_addr);
                        }
                        if (protocol != NETCONS)
                                eth_halt();
@@ -671,6 +671,11 @@ done:
        net_set_icmp_handler(NULL);
 #endif
        net_set_state(prev_net_state);
+
+#if defined(CONFIG_CMD_PCAP)
+       if (pcap_active())
+               pcap_print_status();
+#endif
        return ret;
 }
 
@@ -876,9 +881,6 @@ int net_send_ip_packet(uchar *ether, struct in_addr dest, int dport, int sport,
  * to the algorithm in RFC815. It returns NULL or the pointer to
  * a complete packet, in static storage
  */
-#ifndef CONFIG_NET_MAXDEFRAG
-#define CONFIG_NET_MAXDEFRAG 16384
-#endif
 #define IP_PKTSIZE (CONFIG_NET_MAXDEFRAG)
 
 #define IP_MAXUDP (IP_PKTSIZE - IP_HDR_SIZE)
@@ -905,6 +907,9 @@ static struct ip_udp_hdr *__net_defragment(struct ip_udp_hdr *ip, int *lenp)
        int offset8, start, len, done = 0;
        u16 ip_off = ntohs(ip->ip_off);
 
+       if (ip->ip_len < IP_MIN_FRAG_DATAGRAM_SIZE)
+               return NULL;
+
        /* payload starts after IP header, this fragment is in there */
        payload = (struct hole *)(pkt_buff + IP_HDR_SIZE);
        offset8 =  (ip_off & IP_OFFS);
@@ -1083,6 +1088,9 @@ void net_process_received_packet(uchar *in_packet, int len)
 
        debug_cond(DEBUG_NET_PKT, "packet received\n");
 
+#if defined(CONFIG_CMD_PCAP)
+       pcap_post(in_packet, len, false);
+#endif
        net_rx_packet = in_packet;
        net_rx_packet_len = len;
        et = (struct ethernet_hdr *)in_packet;
@@ -1252,14 +1260,16 @@ void net_process_received_packet(uchar *in_packet, int len)
                        return;
                }
 
+               if (ntohs(ip->udp_len) < UDP_HDR_SIZE || ntohs(ip->udp_len) > ntohs(ip->ip_len))
+                       return;
+
                debug_cond(DEBUG_DEV_PKT,
                           "received UDP (to=%pI4, from=%pI4, len=%d)\n",
                           &dst_ip, &src_ip, len);
 
-#ifdef CONFIG_UDP_CHECKSUM
-               if (ip->udp_xsum != 0) {
+               if (IS_ENABLED(CONFIG_UDP_CHECKSUM) && ip->udp_xsum != 0) {
                        ulong   xsum;
-                       ushort *sumptr;
+                       u8 *sumptr;
                        ushort  sumlen;
 
                        xsum  = ip->ip_p;
@@ -1270,22 +1280,16 @@ void net_process_received_packet(uchar *in_packet, int len)
                        xsum += (ntohl(ip->ip_dst.s_addr) >>  0) & 0x0000ffff;
 
                        sumlen = ntohs(ip->udp_len);
-                       sumptr = (ushort *)&(ip->udp_src);
+                       sumptr = (u8 *)&ip->udp_src;
 
                        while (sumlen > 1) {
-                               ushort sumdata;
-
-                               sumdata = *sumptr++;
-                               xsum += ntohs(sumdata);
+                               /* inlined ntohs() to avoid alignment errors */
+                               xsum += (sumptr[0] << 8) + sumptr[1];
+                               sumptr += 2;
                                sumlen -= 2;
                        }
-                       if (sumlen > 0) {
-                               ushort sumdata;
-
-                               sumdata = *(unsigned char *)sumptr;
-                               sumdata = (sumdata << 8) & 0xff00;
-                               xsum += sumdata;
-                       }
+                       if (sumlen > 0)
+                               xsum += (sumptr[0] << 8) + sumptr[0];
                        while ((xsum >> 16) != 0) {
                                xsum = (xsum & 0x0000ffff) +
                                       ((xsum >> 16) & 0x0000ffff);
@@ -1296,7 +1300,6 @@ void net_process_received_packet(uchar *in_packet, int len)
                                return;
                        }
                }
-#endif
 
 #if defined(CONFIG_NETCONSOLE) && !defined(CONFIG_SPL_BUILD)
                nc_input_packet((uchar *)ip + IP_UDP_HDR_SIZE,
@@ -1336,14 +1339,6 @@ static int net_check_prereq(enum proto_t protocol)
                }
                goto common;
 #endif
-#if defined(CONFIG_CMD_SNTP)
-       case SNTP:
-               if (net_ntp_server.s_addr == 0) {
-                       puts("*** ERROR: NTP server address not given\n");
-                       return 1;
-               }
-               goto common;
-#endif
 #if defined(CONFIG_CMD_DNS)
        case DNS:
                if (net_dns_server.s_addr == 0) {
@@ -1352,6 +1347,13 @@ static int net_check_prereq(enum proto_t protocol)
                }
                goto common;
 #endif
+#if defined(CONFIG_PROT_UDP)
+       case UDP:
+               if (udp_prereq())
+                       return 1;
+               goto common;
+#endif
+
 #if defined(CONFIG_CMD_NFS)
        case NFS:
 #endif
@@ -1362,8 +1364,8 @@ static int net_check_prereq(enum proto_t protocol)
                        puts("*** ERROR: `serverip' not set\n");
                        return 1;
                }
-#if    defined(CONFIG_CMD_PING) || defined(CONFIG_CMD_SNTP) || \
-       defined(CONFIG_CMD_DNS)
+#if    defined(CONFIG_CMD_PING) || \
+       defined(CONFIG_CMD_DNS) || defined(CONFIG_PROT_UDP)
 common:
 #endif
                /* Fall through */
@@ -1539,14 +1541,19 @@ int is_serverip_in_cmd(void)
 int net_parse_bootfile(struct in_addr *ipaddr, char *filename, int max_len)
 {
        char *colon;
+       struct in_addr ip;
+       ip.s_addr = 0;
 
        if (net_boot_file_name[0] == '\0')
                return 0;
 
        colon = strchr(net_boot_file_name, ':');
        if (colon) {
-               if (ipaddr)
-                       *ipaddr = string_to_ip(net_boot_file_name);
+               ip = string_to_ip(net_boot_file_name);
+               if (ipaddr && ip.s_addr)
+                       *ipaddr = ip;
+       }
+       if (ip.s_addr) {
                strncpy(filename, colon + 1, max_len);
        } else {
                strncpy(filename, net_boot_file_name, max_len);
@@ -1556,20 +1563,6 @@ int net_parse_bootfile(struct in_addr *ipaddr, char *filename, int max_len)
        return 1;
 }
 
-#if    defined(CONFIG_CMD_NFS)         || \
-       defined(CONFIG_CMD_SNTP)        || \
-       defined(CONFIG_CMD_DNS)
-/*
- * make port a little random (1024-17407)
- * This keeps the math somewhat trivial to compute, and seems to work with
- * all supported protocols/clients/servers
- */
-unsigned int random_port(void)
-{
-       return 1024 + (get_timer(0) % 0x4000);
-}
-#endif
-
 void ip_to_string(struct in_addr x, char *s)
 {
        x.s_addr = ntohl(x.s_addr);
@@ -1604,7 +1597,7 @@ ushort string_to_vlan(const char *s)
        if (*s < '0' || *s > '9')
                id = VLAN_NONE;
        else
-               id = (ushort)simple_strtoul(s, NULL, 10);
+               id = (ushort)dectoul(s, NULL);
 
        return htons(id);
 }