]> git.sur5r.net Git - u-boot/blobdiff - net/net.c
netloop: speed up NetLoop
[u-boot] / net / net.c
index cde26801b385b8e29a4e44a5e147514d4112c088..a55f4d33f984ce98f5dc1b046b03466974bd18bb 100644 (file)
--- a/net/net.c
+++ b/net/net.c
 #if defined(CONFIG_CMD_SNTP)
 #include "sntp.h"
 #endif
+#if defined(CONFIG_CDP_VERSION)
+#include <timestamp.h>
+#endif
 
 #if defined(CONFIG_CMD_NET)
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#define ARP_TIMEOUT            5               /* Seconds before trying ARP again */
+#ifndef        CONFIG_ARP_TIMEOUT
+# define ARP_TIMEOUT           5000UL  /* Milliseconds before trying ARP again */
+#else
+# define ARP_TIMEOUT           CONFIG_ARP_TIMEOUT
+#endif
+
+
 #ifndef        CONFIG_NET_RETRY_COUNT
-# define ARP_TIMEOUT_COUNT     5               /* # of timeouts before giving up  */
+# define ARP_TIMEOUT_COUNT     5       /* # of timeouts before giving up  */
 #else
-# define ARP_TIMEOUT_COUNT  (CONFIG_NET_RETRY_COUNT)
+# define ARP_TIMEOUT_COUNT     CONFIG_NET_RETRY_COUNT
 #endif
 
 #if 0
@@ -129,7 +138,7 @@ uchar               NetOurEther[6];         /* Our ethernet address                 */
 uchar          NetServerEther[6] =     /* Boot server enet address             */
                        { 0, 0, 0, 0, 0, 0 };
 IPaddr_t       NetOurIP;               /* Our IP addr (0 = unknown)            */
-IPaddr_t       NetServerIP;            /* Our IP addr (0 = unknown)            */
+IPaddr_t       NetServerIP;            /* Server IP addr (0 = unknown)         */
 volatile uchar *NetRxPkt;              /* Current receive packet               */
 int            NetRxPktLen;            /* Current rx packet length             */
 unsigned       NetIPID;                /* IP packet ID                         */
@@ -137,6 +146,9 @@ uchar               NetBcastAddr[6] =       /* Ethernet bcast address               */
                        { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 uchar          NetEtherNullAddr[6] =
                        { 0, 0, 0, 0, 0, 0 };
+#ifdef CONFIG_API
+void           (*push_packet)(volatile void *, int len) = 0;
+#endif
 #if defined(CONFIG_CMD_CDP)
 uchar          NetCDPAddr[6] =         /* Ethernet bcast address               */
                        { 0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcc };
@@ -155,7 +167,7 @@ ushort              NetOurNativeVLAN = 0xFFFF;      /* ditto                        */
 char           BootFile[128];          /* Boot File name                       */
 
 #if defined(CONFIG_CMD_PING)
-IPaddr_t       NetPingIP;              /* the ip address to ping               */
+IPaddr_t       NetPingIP;              /* the ip address to ping               */
 
 static void PingStart(void);
 #endif
@@ -193,10 +205,12 @@ IPaddr_t  NetArpWaitReplyIP;
 uchar         *NetArpWaitPacketMAC;    /* MAC address of waiting packet's destination  */
 uchar         *NetArpWaitTxPacket;     /* THE transmit packet                  */
 int            NetArpWaitTxPacketSize;
-uchar          NetArpWaitPacketBuf[PKTSIZE_ALIGN + PKTALIGN];
+uchar          NetArpWaitPacketBuf[PKTSIZE_ALIGN + PKTALIGN];
 ulong          NetArpWaitTimerStart;
 int            NetArpWaitTry;
 
+int            env_changed_id = 0;
+
 void ArpRequest (void)
 {
        int i;
@@ -250,7 +264,7 @@ void ArpTimeoutCheck(void)
        t = get_timer(0);
 
        /* check for arp timeout */
-       if ((t - NetArpWaitTimerStart) > ARP_TIMEOUT * CFG_HZ) {
+       if ((t - NetArpWaitTimerStart) > ARP_TIMEOUT) {
                NetArpWaitTry++;
 
                if (NetArpWaitTry >= ARP_TIMEOUT_COUNT) {
@@ -264,6 +278,78 @@ void ArpTimeoutCheck(void)
        }
 }
 
+int
+NetInitLoop(proto_t protocol)
+{
+       bd_t *bd = gd->bd;
+       int env_id = get_env_id ();
+
+       /* update only when the environment has changed */
+       if (env_changed_id == env_id)
+               return 0;
+
+       switch (protocol) {
+#if defined(CONFIG_CMD_NFS)
+       case NFS:
+#endif
+#if defined(CONFIG_CMD_PING)
+       case PING:
+#endif
+#if defined(CONFIG_CMD_SNTP)
+       case SNTP:
+#endif
+       case NETCONS:
+       case TFTP:
+               NetCopyIP(&NetOurIP, &bd->bi_ip_addr);
+               NetOurGatewayIP = getenv_IPaddr ("gatewayip");
+               NetOurSubnetMask= getenv_IPaddr ("netmask");
+               NetOurVLAN = getenv_VLAN("vlan");
+               NetOurNativeVLAN = getenv_VLAN("nvlan");
+
+               switch (protocol) {
+#if defined(CONFIG_CMD_NFS)
+               case NFS:
+#endif
+               case NETCONS:
+               case TFTP:
+                       NetServerIP = getenv_IPaddr ("serverip");
+                       break;
+#if defined(CONFIG_CMD_PING)
+               case PING:
+                       /* nothing */
+                       break;
+#endif
+#if defined(CONFIG_CMD_SNTP)
+               case SNTP:
+                       /* nothing */
+                       break;
+#endif
+               default:
+                       break;
+               }
+
+               break;
+       case BOOTP:
+       case RARP:
+               /*
+                * initialize our IP addr to 0 in order to accept ANY
+                * IP addr assigned to us by the BOOTP / RARP server
+                */
+               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");
+               break;
+       default:
+               break;
+       }
+       env_changed_id = env_id;
+       return 0;
+}
+
 /**********************************************************************/
 /*
  *     Main network processing loop.
@@ -328,65 +414,7 @@ restart:
         *      here on, this code is a state machine driven by received
         *      packets and timer events.
         */
-
-       switch (protocol) {
-#if defined(CONFIG_CMD_NFS)
-       case NFS:
-#endif
-#if defined(CONFIG_CMD_PING)
-       case PING:
-#endif
-#if defined(CONFIG_CMD_SNTP)
-       case SNTP:
-#endif
-       case NETCONS:
-       case TFTP:
-               NetCopyIP(&NetOurIP, &bd->bi_ip_addr);
-               NetOurGatewayIP = getenv_IPaddr ("gatewayip");
-               NetOurSubnetMask= getenv_IPaddr ("netmask");
-               NetOurVLAN = getenv_VLAN("vlan");
-               NetOurNativeVLAN = getenv_VLAN("nvlan");
-
-               switch (protocol) {
-#if defined(CONFIG_CMD_NFS)
-               case NFS:
-#endif
-               case NETCONS:
-               case TFTP:
-                       NetServerIP = getenv_IPaddr ("serverip");
-                       break;
-#if defined(CONFIG_CMD_PING)
-               case PING:
-                       /* nothing */
-                       break;
-#endif
-#if defined(CONFIG_CMD_SNTP)
-               case SNTP:
-                       /* nothing */
-                       break;
-#endif
-               default:
-                       break;
-               }
-
-               break;
-       case BOOTP:
-       case RARP:
-               /*
-                * initialize our IP addr to 0 in order to accept ANY
-                * IP addr assigned to us by the BOOTP / RARP server
-                */
-               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");
-               break;
-       default:
-               break;
-       }
+       NetInitLoop(protocol);
 
        switch (net_check_prereq (protocol)) {
        case 1:
@@ -463,16 +491,16 @@ restart:
        }
 
 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
-#if defined(CFG_FAULT_ECHO_LINK_DOWN) && defined(CONFIG_STATUS_LED) && defined(STATUS_LED_RED)
+#if defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN) && defined(CONFIG_STATUS_LED) && defined(STATUS_LED_RED)
        /*
         * Echo the inverted link state to the fault LED.
         */
-       if(miiphy_link(eth_get_dev()->name, CFG_FAULT_MII_ADDR)) {
+       if(miiphy_link(eth_get_dev()->name, CONFIG_SYS_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 /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */
 #endif /* CONFIG_MII, ... */
 
        /*
@@ -491,7 +519,7 @@ restart:
                 *      Check the ethernet for a new packet.  The ethernet
                 *      receive routine will process it.
                 */
-                       eth_rx();
+               eth_rx();
 
                /*
                 *      Abort if ctrl-c was pressed.
@@ -512,18 +540,18 @@ restart:
                        thand_f *x;
 
 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
-#  if defined(CFG_FAULT_ECHO_LINK_DOWN) && \
+#  if defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN) && \
       defined(CONFIG_STATUS_LED) &&       \
       defined(STATUS_LED_RED)
                        /*
                         * Echo the inverted link state to the fault LED.
                         */
-                       if(miiphy_link(eth_get_dev()->name, CFG_FAULT_MII_ADDR)) {
+                       if(miiphy_link(eth_get_dev()->name, CONFIG_SYS_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 /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */
 #endif /* CONFIG_MII, ... */
                        x = timeHandler;
                        timeHandler = (thand_f *)0;
@@ -589,16 +617,18 @@ void NetStartAgain (void)
                return;
        }
 #ifndef CONFIG_NET_MULTI
-       NetSetTimeout (10 * CFG_HZ, startAgainTimeout);
+       NetSetTimeout (10000UL, startAgainTimeout);
        NetSetHandler (startAgainHandler);
 #else  /* !CONFIG_NET_MULTI*/
        eth_halt ();
+#if !defined(CONFIG_NET_DO_NOT_TRY_ANOTHER)
        eth_try_another (!NetRestarted);
+#endif
        eth_init (gd->bd);
        if (NetRestartWrap) {
                NetRestartWrap = 0;
                if (NetDevExists && !once) {
-                       NetSetTimeout (10 * CFG_HZ, startAgainTimeout);
+                       NetSetTimeout (10000UL, startAgainTimeout);
                        NetSetHandler (startAgainHandler);
                } else {
                        NetState = NETLOOP_FAIL;
@@ -724,7 +754,7 @@ int PingSend(void)
        ip->ip_tos   = 0;
        ip->ip_len   = htons(IP_HDR_SIZE_NO_UDP + 8);
        ip->ip_id    = htons(NetIPID++);
-       ip->ip_off   = htons(0x4000);   /* No fragmentation */
+       ip->ip_off   = htons(IP_FLAGS_DFRAG);   /* Don't fragment */
        ip->ip_ttl   = 255;
        ip->ip_p     = 0x01;            /* ICMP */
        ip->ip_sum   = 0;
@@ -735,7 +765,7 @@ int PingSend(void)
        s = &ip->udp_src;               /* XXX ICMP starts here */
        s[0] = htons(0x0800);           /* echo-request, code */
        s[1] = 0;                       /* checksum */
-       s[2] = 0;                       /* identifier */
+       s[2] = 0;                       /* identifier */
        s[3] = htons(PingSeqNo++);      /* sequence number */
        s[1] = ~NetCksum((uchar *)s, 8/2);
 
@@ -774,7 +804,7 @@ static void PingStart(void)
 #if defined(CONFIG_NET_MULTI)
        printf ("Using %s device\n", eth_get_name());
 #endif /* CONFIG_NET_MULTI */
-       NetSetTimeout (10 * CFG_HZ, PingTimeout);
+       NetSetTimeout (10000UL, PingTimeout);
        NetSetHandler (PingHandler);
 
        PingSend();
@@ -797,7 +827,7 @@ static void PingStart(void)
 #define CDP_SYSOBJECT_TLV              0x0015
 #define CDP_MANAGEMENT_ADDRESS_TLV     0x0016
 
-#define CDP_TIMEOUT                    (CFG_HZ/4)      /* one packet every 250ms */
+#define CDP_TIMEOUT                    250UL   /* one packet every 250ms */
 
 static int CDPSeq;
 static int CDPOK;
@@ -1161,6 +1191,13 @@ NetReceive(volatile uchar * inpkt, int len)
        if (len < ETHER_HDR_SIZE)
                return;
 
+#ifdef CONFIG_API
+       if (push_packet) {
+               (*push_packet)(inpkt, len);
+               return;
+       }
+#endif
+
 #if defined(CONFIG_CMD_CDP)
        /* keep track if packet is CDP */
        iscdp = memcmp(et->et_dest, NetCDPAddr, 6) == 0;
@@ -1367,7 +1404,7 @@ NetReceive(volatile uchar * inpkt, int len)
                puts ("Got IP\n");
 #endif
                if (len < IP_HDR_SIZE) {
-                       debug ("len bad %d < %d\n", len, IP_HDR_SIZE);
+                       debug ("len bad %d < %lu\n", len, (ulong)IP_HDR_SIZE);
                        return;
                }
                if (len < ntohs(ip->ip_len)) {
@@ -1381,7 +1418,12 @@ NetReceive(volatile uchar * inpkt, int len)
                if ((ip->ip_hl_v & 0xf0) != 0x40) {
                        return;
                }
-               if (ip->ip_off & htons(0x1fff)) { /* Can't deal w/ fragments */
+               /* Can't deal with fragments */
+               if (ip->ip_off & htons(IP_OFFS | IP_FLAGS_MFRAG)) {
+                       return;
+               }
+               /* can't deal with headers > 20 bytes */
+               if ((ip->ip_hl_v & 0x0f) > 0x05) {
                        return;
                }
                if (!NetCksumOk((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2)) {
@@ -1493,7 +1535,8 @@ NetReceive(volatile uchar * inpkt, int len)
                                xsum = (xsum & 0x0000ffff) + ((xsum >> 16) & 0x0000ffff);
                        }
                        if ((xsum != 0x00000000) && (xsum != 0x0000ffff)) {
-                               printf(" UDP wrong checksum %08x %08x\n", xsum, ntohs(ip->udp_xsum));
+                               printf(" UDP wrong checksum %08lx %08x\n",
+                                       xsum, ntohs(ip->udp_xsum));
                                return;
                        }
                }
@@ -1657,7 +1700,7 @@ NetSetEther(volatile uchar * xet, uchar * addr, uint prot)
 void
 NetSetIP(volatile uchar * xip, IPaddr_t dest, int dport, int sport, int len)
 {
-       volatile IP_t *ip = (IP_t *)xip;
+       IP_t *ip = (IP_t *)xip;
 
        /*
         *      If the data is an odd number of bytes, zero the
@@ -1675,7 +1718,7 @@ NetSetIP(volatile uchar * xip, IPaddr_t dest, int dport, int sport, int len)
        ip->ip_tos   = 0;
        ip->ip_len   = htons(IP_HDR_SIZE + len);
        ip->ip_id    = htons(NetIPID++);
-       ip->ip_off   = htons(0x4000);   /* No fragmentation */
+       ip->ip_off   = htons(IP_FLAGS_DFRAG);   /* Don't fragment */
        ip->ip_ttl   = 255;
        ip->ip_p     = 17;              /* UDP */
        ip->ip_sum   = 0;