include/configs: Use new CONFIG_CMD_* in various [NO]* named board config files.
[platform/kernel/u-boot.git] / net / net.c
index d7523fd..250abcd 100644 (file)
--- a/net/net.c
+++ b/net/net.c
  *
  * DHCP:
  *
- *     Prerequisites:   - own ethernet address
- *     We want:         - IP, Netmask, ServerIP, Gateway IP
- *                      - bootfilename, lease time
- *     Next step:       - TFTP
+ *     Prerequisites:  - own ethernet address
+ *     We want:                - IP, Netmask, ServerIP, Gateway IP
+ *                     - bootfilename, lease time
+ *     Next step:      - TFTP
  *
  * TFTP:
  *
  *                       derived from our own IP address)
  *     We want:        - load the boot file
  *     Next step:      none
+ *
+ * SNTP:
+ *
+ *     Prerequisites:  - own ethernet address
+ *                     - own IP address
+ *     We want:        - network time
+ *     Next step:      none
  */
 
 
 #include <status_led.h>
 #include <miiphy.h>
 #endif
+#if (CONFIG_COMMANDS & CFG_CMD_SNTP) || defined(CONFIG_CMD_SNTP)
+#include "sntp.h"
+#endif
 
-#if (CONFIG_COMMANDS & CFG_CMD_NET)
+#if (CONFIG_COMMANDS & CFG_CMD_NET) || defined(CONFIG_CMD_NET)
+
+DECLARE_GLOBAL_DATA_PTR;
 
 #define ARP_TIMEOUT            5               /* Seconds before trying ARP again */
 #ifndef        CONFIG_NET_RETRY_COUNT
@@ -121,7 +133,7 @@ uchar               NetBcastAddr[6] =       /* Ethernet bcast address               */
                        { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 uchar          NetEtherNullAddr[6] =
                        { 0, 0, 0, 0, 0, 0 };
-#if (CONFIG_COMMANDS & CFG_CMD_CDP)
+#if (CONFIG_COMMANDS & CFG_CMD_CDP) || defined(CONFIG_CMD_CDP)
 uchar          NetCDPAddr[6] =         /* Ethernet bcast address               */
                        { 0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcc };
 #endif
@@ -138,16 +150,21 @@ ushort            NetOurNativeVLAN = 0xFFFF;      /* ditto                        */
 
 char           BootFile[128];          /* Boot File name                       */
 
-#if (CONFIG_COMMANDS & CFG_CMD_PING)
+#if (CONFIG_COMMANDS & CFG_CMD_PING) || defined(CONFIG_CMD_PING)
 IPaddr_t       NetPingIP;              /* the ip address to ping               */
 
 static void PingStart(void);
 #endif
 
-#if (CONFIG_COMMANDS & CFG_CMD_CDP)
+#if (CONFIG_COMMANDS & CFG_CMD_CDP) || defined(CONFIG_CMD_CDP)
 static void CDPStart(void);
 #endif
 
+#if (CONFIG_COMMANDS & CFG_CMD_SNTP) || defined(CONFIG_CMD_SNTP)
+IPaddr_t       NetNtpServerIP;         /* NTP server IP address                */
+int            NetTimeOffset=0;        /* offset time from UTC                 */
+#endif
+
 #ifdef CONFIG_NETCONSOLE
 void NcStart(void);
 int nc_input_packet(uchar *pkt, unsigned dest, unsigned src, unsigned len);
@@ -170,7 +187,7 @@ static int net_check_prereq (proto_t protocol);
 IPaddr_t       NetArpWaitPacketIP;
 IPaddr_t       NetArpWaitReplyIP;
 uchar         *NetArpWaitPacketMAC;    /* MAC address of waiting packet's destination  */
-uchar          *NetArpWaitTxPacket;    /* THE transmit packet                  */
+uchar         *NetArpWaitTxPacket;     /* THE transmit packet                  */
 int            NetArpWaitTxPacketSize;
 uchar          NetArpWaitPacketBuf[PKTSIZE_ALIGN + PKTALIGN];
 ulong          NetArpWaitTimerStart;
@@ -197,8 +214,8 @@ void ArpRequest (void)
        arp->ar_pln = 4;
        arp->ar_op = htons (ARPOP_REQUEST);
 
-       memcpy (&arp->ar_data[0], NetOurEther, 6);              /* source ET addr       */
-       NetWriteIP ((uchar *) & arp->ar_data[6], NetOurIP);     /* source IP addr       */
+       memcpy (&arp->ar_data[0], NetOurEther, 6);              /* source ET addr       */
+       NetWriteIP ((uchar *) & arp->ar_data[6], NetOurIP);     /* source IP addr       */
        for (i = 10; i < 16; ++i) {
                arp->ar_data[i] = 0;                            /* dest ET addr = 0     */
        }
@@ -207,8 +224,10 @@ void ArpRequest (void)
            (NetOurIP & NetOurSubnetMask)) {
                if (NetOurGatewayIP == 0) {
                        puts ("## Warning: gatewayip needed but not set\n");
+                       NetArpWaitReplyIP = NetArpWaitPacketIP;
+               } else {
+                       NetArpWaitReplyIP = NetOurGatewayIP;
                }
-               NetArpWaitReplyIP = NetOurGatewayIP;
        } else {
                NetArpWaitReplyIP = NetArpWaitPacketIP;
        }
@@ -249,8 +268,6 @@ void ArpTimeoutCheck(void)
 int
 NetLoop(proto_t protocol)
 {
-       DECLARE_GLOBAL_DATA_PTR;
-
        bd_t *bd = gd->bd;
 
 #ifdef CONFIG_NET_MULTI
@@ -288,8 +305,10 @@ NetLoop(proto_t protocol)
 #ifdef CONFIG_NET_MULTI
        eth_set_current();
 #endif
-       if (eth_init(bd) < 0)
+       if (eth_init(bd) < 0) {
+               eth_halt();
                return(-1);
+       }
 
 restart:
 #ifdef CONFIG_NET_MULTI
@@ -307,12 +326,15 @@ restart:
         */
 
        switch (protocol) {
-#if (CONFIG_COMMANDS & CFG_CMD_NFS)
+#if (CONFIG_COMMANDS & CFG_CMD_NFS) || defined(CONFIG_CMD_NFS)
        case NFS:
 #endif
-#if (CONFIG_COMMANDS & CFG_CMD_PING)
+#if (CONFIG_COMMANDS & CFG_CMD_PING) || defined(CONFIG_CMD_PING)
        case PING:
 #endif
+#if (CONFIG_COMMANDS & CFG_CMD_SNTP) || defined(CONFIG_CMD_SNTP)
+       case SNTP:
+#endif
        case NETCONS:
        case TFTP:
                NetCopyIP(&NetOurIP, &bd->bi_ip_addr);
@@ -322,18 +344,23 @@ restart:
                NetOurNativeVLAN = getenv_VLAN("nvlan");
 
                switch (protocol) {
-#if (CONFIG_COMMANDS & CFG_CMD_NFS)
+#if (CONFIG_COMMANDS & CFG_CMD_NFS) || defined(CONFIG_CMD_NFS)
                case NFS:
 #endif
                case NETCONS:
                case TFTP:
                        NetServerIP = getenv_IPaddr ("serverip");
                        break;
-#if (CONFIG_COMMANDS & CFG_CMD_PING)
+#if (CONFIG_COMMANDS & CFG_CMD_PING) || defined(CONFIG_CMD_PING)
                case PING:
                        /* nothing */
                        break;
 #endif
+#if (CONFIG_COMMANDS & CFG_CMD_SNTP) || defined(CONFIG_CMD_SNTP)
+               case SNTP:
+                       /* nothing */
+                       break;
+#endif
                default:
                        break;
                }
@@ -347,11 +374,11 @@ restart:
                 */
                NetOurIP = 0;
                NetServerIP = getenv_IPaddr ("serverip");
-               NetOurVLAN = getenv_VLAN("vlan");       /* VLANs must be read */
-               NetOurNativeVLAN = getenv_VLAN("nvlan");
-       case CDP:
-               NetOurVLAN = getenv_VLAN("vlan");       /* VLANs must be read */
-               NetOurNativeVLAN = getenv_VLAN("nvlan");
+               NetOurVLAN = getenv_VLAN("vlan");       /* VLANs must be read */
+               NetOurNativeVLAN = getenv_VLAN("nvlan");
+       case CDP:
+               NetOurVLAN = getenv_VLAN("vlan");       /* VLANs must be read */
+               NetOurNativeVLAN = getenv_VLAN("nvlan");
                break;
        default:
                break;
@@ -360,6 +387,7 @@ restart:
        switch (net_check_prereq (protocol)) {
        case 1:
                /* network not configured */
+               eth_halt();
                return (-1);
 
 #ifdef CONFIG_NET_MULTI
@@ -378,7 +406,7 @@ restart:
                        TftpStart();
                        break;
 
-#if (CONFIG_COMMANDS & CFG_CMD_DHCP)
+#if (CONFIG_COMMANDS & CFG_CMD_DHCP) || defined(CONFIG_CMD_DHCP)
                case DHCP:
                        /* Start with a clean slate... */
                        BootpTry = 0;
@@ -397,17 +425,17 @@ restart:
                        RarpTry = 0;
                        RarpRequest ();
                        break;
-#if (CONFIG_COMMANDS & CFG_CMD_PING)
+#if (CONFIG_COMMANDS & CFG_CMD_PING) || defined(CONFIG_CMD_PING)
                case PING:
                        PingStart();
                        break;
 #endif
-#if (CONFIG_COMMANDS & CFG_CMD_NFS)
+#if (CONFIG_COMMANDS & CFG_CMD_NFS) || defined(CONFIG_CMD_NFS)
                case NFS:
                        NfsStart();
                        break;
 #endif
-#if (CONFIG_COMMANDS & CFG_CMD_CDP)
+#if (CONFIG_COMMANDS & CFG_CMD_CDP) || defined(CONFIG_CMD_CDP)
                case CDP:
                        CDPStart();
                        break;
@@ -417,6 +445,11 @@ restart:
                        NcStart();
                        break;
 #endif
+#if (CONFIG_COMMANDS & CFG_CMD_SNTP) || defined(CONFIG_CMD_SNTP)
+               case SNTP:
+                       SntpStart();
+                       break;
+#endif
                default:
                        break;
                }
@@ -425,12 +458,12 @@ restart:
                break;
        }
 
-#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)
+#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII) || defined(CONFIG_CMD_MII)
 #if defined(CFG_FAULT_ECHO_LINK_DOWN) && defined(CONFIG_STATUS_LED) && defined(STATUS_LED_RED)
        /*
         * Echo the inverted link state to the fault LED.
         */
-       if(miiphy_link(CFG_FAULT_MII_ADDR)) {
+       if(miiphy_link(eth_get_dev()->name, CFG_FAULT_MII_ADDR)) {
                status_led_set (STATUS_LED_RED, STATUS_LED_OFF);
        } else {
                status_led_set (STATUS_LED_RED, STATUS_LED_ON);
@@ -440,7 +473,7 @@ restart:
 
        /*
         *      Main packet reception loop.  Loop receiving packets until
-        *      someone sets `NetQuit'.
+        *      someone sets `NetState' to a state that terminates.
         */
        for (;;) {
                WATCHDOG_RESET();
@@ -474,17 +507,19 @@ restart:
                if (timeHandler && ((get_timer(0) - timeStart) > timeDelta)) {
                        thand_f *x;
 
-#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)
-#if defined(CFG_FAULT_ECHO_LINK_DOWN) && defined(CONFIG_STATUS_LED) && defined(STATUS_LED_RED)
+#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII) || defined(CONFIG_CMD_MII)
+#  if defined(CFG_FAULT_ECHO_LINK_DOWN) && \
+      defined(CONFIG_STATUS_LED) &&       \
+      defined(STATUS_LED_RED)
                        /*
                         * Echo the inverted link state to the fault LED.
                         */
-                       if(miiphy_link(CFG_FAULT_MII_ADDR)) {
+                       if(miiphy_link(eth_get_dev()->name, CFG_FAULT_MII_ADDR)) {
                                status_led_set (STATUS_LED_RED, STATUS_LED_OFF);
                        } else {
                                status_led_set (STATUS_LED_RED, STATUS_LED_ON);
                        }
-#endif /* CFG_FAULT_ECHO_LINK_DOWN, ... */
+#  endif /* CFG_FAULT_ECHO_LINK_DOWN, ... */
 #endif /* CONFIG_MII, ... */
                        x = timeHandler;
                        timeHandler = (thand_f *)0;
@@ -537,9 +572,6 @@ startAgainHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len)
 
 void NetStartAgain (void)
 {
-#ifdef CONFIG_NET_MULTI
-       DECLARE_GLOBAL_DATA_PTR;
-#endif
        char *nretry;
        int noretry = 0, once = 0;
 
@@ -655,7 +687,7 @@ NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport, int len)
        return 0;       /* transmitted */
 }
 
-#if (CONFIG_COMMANDS & CFG_CMD_PING)
+#if (CONFIG_COMMANDS & CFG_CMD_PING) || defined(CONFIG_CMD_PING)
 static ushort PingSeqNo;
 
 int PingSend(void)
@@ -745,7 +777,7 @@ static void PingStart(void)
 }
 #endif /* CFG_CMD_PING */
 
-#if (CONFIG_COMMANDS & CFG_CMD_CDP)
+#if (CONFIG_COMMANDS & CFG_CMD_CDP) || defined(CONFIG_CMD_CDP)
 
 #define CDP_DEVICE_ID_TLV              0x0001
 #define CDP_ADDRESS_TLV                        0x0002
@@ -777,6 +809,7 @@ static ushort CDP_compute_csum(const uchar *buff, ushort len)
        int     odd;
        ulong   result = 0;
        ushort  leftover;
+       ushort *p;
 
        if (len > 0) {
                odd = 1 & (ulong)buff;
@@ -786,14 +819,19 @@ static ushort CDP_compute_csum(const uchar *buff, ushort len)
                        buff++;
                }
                while (len > 1) {
-                       result += *((const ushort *)buff)++;
+                       p = (ushort *)buff;
+                       result += *p++;
+                       buff = (uchar *)p;
                        if (result & 0x80000000)
                                result = (result & 0xFFFF) + (result >> 16);
                        len -= 2;
                }
                if (len) {
                        leftover = (signed short)(*(const signed char *)buff);
-                       /* * XXX CISCO SUCKS big time! (and blows too) */
+                       /* CISCO SUCKS big time! (and blows too):
+                        * CDP uses the IP checksum algorithm with a twist;
+                        * for the last byte it *sign* extends and sums.
+                        */
                        result = (result & 0xffff0000) | ((result + leftover) & 0x0000ffff);
                }
                while (result >> 16)
@@ -1102,7 +1140,7 @@ NetReceive(volatile uchar * inpkt, int len)
        IPaddr_t tmp;
        int     x;
        uchar *pkt;
-#if (CONFIG_COMMANDS & CFG_CMD_CDP)
+#if (CONFIG_COMMANDS & CFG_CMD_CDP) || defined(CONFIG_CMD_CDP)
        int iscdp;
 #endif
        ushort cti = 0, vlanid = VLAN_NONE, myvlanid, mynvlanid;
@@ -1119,7 +1157,7 @@ NetReceive(volatile uchar * inpkt, int len)
        if (len < ETHER_HDR_SIZE)
                return;
 
-#if (CONFIG_COMMANDS & CFG_CMD_CDP)
+#if (CONFIG_COMMANDS & CFG_CMD_CDP) || defined(CONFIG_CMD_CDP)
        /* keep track if packet is CDP */
        iscdp = memcmp(et->et_dest, NetCDPAddr, 6) == 0;
 #endif
@@ -1162,7 +1200,7 @@ NetReceive(volatile uchar * inpkt, int len)
 
                /* if no VLAN active */
                if ((ntohs(NetOurVLAN) & VLAN_IDMASK) == VLAN_NONE
-#if (CONFIG_COMMANDS & CFG_CMD_CDP)
+#if (CONFIG_COMMANDS & CFG_CMD_CDP) || defined(CONFIG_CMD_CDP)
                                && iscdp == 0
 #endif
                                )
@@ -1180,7 +1218,7 @@ NetReceive(volatile uchar * inpkt, int len)
        printf("Receive from protocol 0x%x\n", x);
 #endif
 
-#if (CONFIG_COMMANDS & CFG_CMD_CDP)
+#if (CONFIG_COMMANDS & CFG_CMD_CDP) || defined(CONFIG_CMD_CDP)
        if (iscdp) {
                CDPHandler((uchar *)ip, len);
                return;
@@ -1372,20 +1410,40 @@ NetReceive(volatile uchar * inpkt, int len)
 
                        switch (icmph->type) {
                        case ICMP_REDIRECT:
-                       if (icmph->code != ICMP_REDIR_HOST)
+                               if (icmph->code != ICMP_REDIR_HOST)
+                                       return;
+                               puts (" ICMP Host Redirect to ");
+                               print_IPaddr(icmph->un.gateway);
+                               putc(' ');
                                return;
-                       puts (" ICMP Host Redirect to ");
-                       print_IPaddr(icmph->un.gateway);
-                       putc(' ');
-                               break;
-#if (CONFIG_COMMANDS & CFG_CMD_PING)
+#if (CONFIG_COMMANDS & CFG_CMD_PING) || defined(CONFIG_CMD_PING)
                        case ICMP_ECHO_REPLY:
                                /*
                                 *      IP header OK.  Pass the packet to the current handler.
                                 */
                                /* XXX point to ip packet */
                                (*packetHandler)((uchar *)ip, 0, 0, 0);
-                               break;
+                               return;
+                       case ICMP_ECHO_REQUEST:
+#ifdef ET_DEBUG
+                               printf ("Got ICMP ECHO REQUEST, return %d bytes \n",
+                                       ETHER_HDR_SIZE + len);
+#endif
+                               memcpy (&et->et_dest[0], &et->et_src[0], 6);
+                               memcpy (&et->et_src[ 0], NetOurEther, 6);
+
+                               ip->ip_sum = 0;
+                               ip->ip_off = 0;
+                               NetCopyIP((void*)&ip->ip_dst, &ip->ip_src);
+                               NetCopyIP((void*)&ip->ip_src, &NetOurIP);
+                               ip->ip_sum = ~NetCksum((uchar *)ip, IP_HDR_SIZE_NO_UDP >> 1);
+
+                               icmph->type = ICMP_ECHO_REPLY;
+                               icmph->checksum = 0;
+                               icmph->checksum = ~NetCksum((uchar *)icmph,
+                                               (len - IP_HDR_SIZE_NO_UDP) >> 1);
+                               (void) eth_send((uchar *)et, ETHER_HDR_SIZE + len);
+                               return;
 #endif
                        default:
                                return;
@@ -1394,6 +1452,46 @@ NetReceive(volatile uchar * inpkt, int len)
                        return;
                }
 
+#ifdef CONFIG_UDP_CHECKSUM
+               if (ip->udp_xsum != 0) {
+                       ulong   xsum;
+                       ushort *sumptr;
+                       ushort  sumlen;
+
+                       xsum  = ip->ip_p;
+                       xsum += (ntohs(ip->udp_len));
+                       xsum += (ntohl(ip->ip_src) >> 16) & 0x0000ffff;
+                       xsum += (ntohl(ip->ip_src) >>  0) & 0x0000ffff;
+                       xsum += (ntohl(ip->ip_dst) >> 16) & 0x0000ffff;
+                       xsum += (ntohl(ip->ip_dst) >>  0) & 0x0000ffff;
+
+                       sumlen = ntohs(ip->udp_len);
+                       sumptr = (ushort *) &(ip->udp_src);
+
+                       while (sumlen > 1) {
+                               ushort sumdata;
+
+                               sumdata = *sumptr++;
+                               xsum += ntohs(sumdata);
+                               sumlen -= 2;
+                       }
+                       if (sumlen > 0) {
+                               ushort sumdata;
+
+                               sumdata = *(unsigned char *) sumptr;
+                               sumdata = (sumdata << 8) & 0xff00;
+                               xsum += sumdata;
+                       }
+                       while ((xsum >> 16) != 0) {
+                               xsum = (xsum & 0x0000ffff) + ((xsum >> 16) & 0x0000ffff);
+                       }
+                       if ((xsum != 0x00000000) && (xsum != 0x0000ffff)) {
+                               printf(" UDP wrong checksum %08x %08x\n", xsum, ntohs(ip->udp_xsum));
+                               return;
+                       }
+               }
+#endif
+
 #ifdef CONFIG_NETCONSOLE
                nc_input_packet((uchar *)ip +IP_HDR_SIZE,
                                                ntohs(ip->udp_dst),
@@ -1418,7 +1516,7 @@ static int net_check_prereq (proto_t protocol)
 {
        switch (protocol) {
                /* Fall through */
-#if (CONFIG_COMMANDS & CFG_CMD_PING)
+#if (CONFIG_COMMANDS & CFG_CMD_PING) || defined(CONFIG_CMD_PING)
        case PING:
                if (NetPingIP == 0) {
                        puts ("*** ERROR: ping address not given\n");
@@ -1426,7 +1524,15 @@ static int net_check_prereq (proto_t protocol)
                }
                goto common;
 #endif
-#if (CONFIG_COMMANDS & CFG_CMD_NFS)
+#if (CONFIG_COMMANDS & CFG_CMD_SNTP) || defined(CONFIG_CMD_SNTP)
+       case SNTP:
+               if (NetNtpServerIP == 0) {
+                       puts ("*** ERROR: NTP server address not given\n");
+                       return (1);
+               }
+               goto common;
+#endif
+#if (CONFIG_COMMANDS & CFG_CMD_NFS) || defined(CONFIG_CMD_NFS)
        case NFS:
 #endif
        case NETCONS:
@@ -1435,8 +1541,8 @@ static int net_check_prereq (proto_t protocol)
                        puts ("*** ERROR: `serverip' not set\n");
                        return (1);
                }
-#if (CONFIG_COMMANDS & CFG_CMD_PING)
-             common:
+#if (CONFIG_COMMANDS & (CFG_CMD_PING | CFG_CMD_SNTP)) || defined(CONFIG_CMD_PING) || defined(CONFIG_CMD_SNTP)
+    common:
 #endif
 
                if (NetOurIP == 0) {
@@ -1493,10 +1599,11 @@ unsigned
 NetCksum(uchar * ptr, int len)
 {
        ulong   xsum;
+       ushort *p = (ushort *)ptr;
 
        xsum = 0;
        while (len-- > 0)
-               xsum += *((ushort *)ptr)++;
+               xsum += *p++;
        xsum = (xsum & 0xffff) + (xsum >> 16);
        xsum = (xsum & 0xffff) + (xsum >> 16);
        return (xsum & 0xffff);
@@ -1573,7 +1680,7 @@ NetSetIP(volatile uchar * xip, IPaddr_t dest, int dport, int sport, int len)
        ip->ip_sum   = ~NetCksum((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2);
 }
 
-void copy_filename (uchar *dst, uchar *src, int size)
+void copy_filename (char *dst, char *src, int size)
 {
        if (*src && (*src == '"')) {
                ++src;