]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - net/net.c
dm: eth: Provide a way for drivers to manage packet buffers
[karo-tx-uboot.git] / net / net.c
index 7663b9cd6c92541b657fb3eebcbd72ba98b9a6df..153d52ebdb0d65f48ec6c20d2236e67240d52ab7 100644 (file)
--- a/net/net.c
+++ b/net/net.c
@@ -6,6 +6,7 @@
  *     Copyright 2000 Roland Borde
  *     Copyright 2000 Paolo Scaffardi
  *     Copyright 2000-2002 Wolfgang Denk, wd@denx.de
+ *     SPDX-License-Identifier:        GPL-2.0
  */
 
 /*
@@ -83,6 +84,7 @@
 #include <common.h>
 #include <command.h>
 #include <environment.h>
+#include <errno.h>
 #include <net.h>
 #if defined(CONFIG_STATUS_LED)
 #include <miiphy.h>
@@ -182,10 +184,13 @@ int               NetTimeOffset;
 #endif
 
 static uchar PktBuf[(PKTBUFSRX+1) * PKTSIZE_ALIGN + PKTALIGN];
-
+#ifdef CONFIG_DM_ETH
+/* Receive packets */
+uchar *net_rx_packets[PKTBUFSRX];
+#else
 /* Receive packet */
 uchar *NetRxPackets[PKTBUFSRX];
-
+#endif
 /* Current UDP RX packet handler */
 static rxhand_f *udp_packet_handler;
 /* Current ARP RX packet handler */
@@ -207,6 +212,8 @@ static int net_check_prereq(enum proto_t protocol);
 
 static int NetTryCount;
 
+int __maybe_unused net_busy_flag;
+
 /**********************************************************************/
 
 static int on_bootfile(const char *name, const char *value, enum env_op op,
@@ -272,7 +279,7 @@ static void NetInitLoop(void)
                env_changed_id = env_id;
        }
        if (eth_get_dev())
-               memcpy(NetOurEther, eth_get_dev()->enetaddr, 6);
+               memcpy(NetOurEther, eth_get_ethaddr(), 6);
 
        return;
 }
@@ -301,9 +308,15 @@ void net_init(void)
 
                NetTxPacket = &PktBuf[0] + (PKTALIGN - 1);
                NetTxPacket -= (ulong)NetTxPacket % PKTALIGN;
+#ifdef CONFIG_DM_ETH
+               for (i = 0; i < PKTBUFSRX; i++) {
+                       net_rx_packets[i] = NetTxPacket + (i + 1) *
+                               PKTSIZE_ALIGN;
+               }
+#else
                for (i = 0; i < PKTBUFSRX; i++)
                        NetRxPackets[i] = NetTxPacket + (i + 1) * PKTSIZE_ALIGN;
-
+#endif
                ArpInit();
                net_clear_handlers();
 
@@ -321,8 +334,7 @@ void net_init(void)
 
 int NetLoop(enum proto_t protocol)
 {
-       bd_t *bd = gd->bd;
-       int ret = -1;
+       int ret = -EINVAL;
 
        NetRestarted = 0;
        NetDevExists = 0;
@@ -334,14 +346,18 @@ int NetLoop(enum proto_t protocol)
        if (eth_is_on_demand_init() || protocol != NETCONS) {
                eth_halt();
                eth_set_current();
-               if (eth_init(bd) < 0) {
+               ret = eth_init();
+               if (ret < 0) {
                        eth_halt();
-                       return -1;
+                       return ret;
                }
        } else
-               eth_init_state_only(bd);
+               eth_init_state_only();
 
 restart:
+#ifdef CONFIG_USB_KEYBOARD
+       net_busy_flag = 0;
+#endif
        net_set_state(NETLOOP_CONTINUE);
 
        /*
@@ -356,7 +372,7 @@ restart:
        case 1:
                /* network not configured */
                eth_halt();
-               return -1;
+               return -ENODEV;
 
        case 2:
                /* network device not configured */
@@ -380,14 +396,14 @@ restart:
 #endif
 #if defined(CONFIG_CMD_DHCP)
                case DHCP:
-                       BootpTry = 0;
+                       BootpReset();
                        NetOurIP = 0;
                        DhcpRequest();          /* Basically same as BOOTP */
                        break;
 #endif
 
                case BOOTP:
-                       BootpTry = 0;
+                       BootpReset();
                        NetOurIP = 0;
                        BootpRequest();
                        break;
@@ -414,7 +430,7 @@ restart:
                        CDPStart();
                        break;
 #endif
-#ifdef CONFIG_NETCONSOLE
+#if defined (CONFIG_NETCONSOLE) && !(CONFIG_SPL_BUILD)
                case NETCONS:
                        NcStart();
                        break;
@@ -433,6 +449,11 @@ restart:
                case LINKLOCAL:
                        link_local_start();
                        break;
+#endif
+#if defined(CONFIG_CMD_BOOTCE)
+               case BOOTME:
+                       BootmeStart();
+                       break;
 #endif
                default:
                        break;
@@ -454,6 +475,9 @@ restart:
                status_led_set(STATUS_LED_RED, STATUS_LED_ON);
 #endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */
 #endif /* CONFIG_MII, ... */
+#ifdef CONFIG_USB_KEYBOARD
+       net_busy_flag = 1;
+#endif
 
        /*
         *      Main packet reception loop.  Loop receiving packets until
@@ -467,6 +491,8 @@ restart:
                /*
                 *      Check the ethernet for a new packet.  The ethernet
                 *      receive routine will process it.
+                *      Most drivers return the most recent packet size, but not
+                *      errors that may have happened.
                 */
                eth_rx();
 
@@ -495,7 +521,7 @@ restart:
                 *      Check for a timeout, and run the timeout handler
                 *      if we have one.
                 */
-               if (timeHandler && ((get_timer(0) - timeStart) > timeDelta)) {
+               if (timeHandler && ((get_timer(timeStart)) > timeDelta)) {
                        thand_f *x;
 
 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
@@ -519,6 +545,8 @@ restart:
                        (*x)();
                }
 
+               if (net_state == NETLOOP_FAIL)
+                       ret = NetStartAgain();
 
                switch (net_state) {
 
@@ -535,10 +563,11 @@ restart:
                                setenv_hex("filesize", NetBootFileXferSize);
                                setenv_hex("fileaddr", load_addr);
                        }
-                       if (protocol != NETCONS)
+                       if (protocol != NETCONS) {
                                eth_halt();
-                       else
+                       } else {
                                eth_halt_state_only();
+                       }
 
                        eth_set_last_protocol(protocol);
 
@@ -559,6 +588,9 @@ restart:
        }
 
 done:
+#ifdef CONFIG_USB_KEYBOARD
+       net_busy_flag = 0;
+#endif
 #ifdef CONFIG_CMD_TFTPPUT
        /* Clear out the handlers */
        net_set_udp_handler(NULL);
@@ -575,11 +607,12 @@ startAgainTimeout(void)
        net_set_state(NETLOOP_RESTART);
 }
 
-void NetStartAgain(void)
+int NetStartAgain(void)
 {
        char *nretry;
        int retry_forever = 0;
        unsigned long retrycnt = 0;
+       int ret;
 
        nretry = getenv("netretry");
        if (nretry) {
@@ -591,13 +624,19 @@ void NetStartAgain(void)
                        retrycnt = 1;
                else
                        retrycnt = simple_strtoul(nretry, NULL, 0);
-       } else
-               retry_forever = 1;
+       } else {
+               retrycnt = 0;
+               retry_forever = 0;
+       }
 
        if ((!retry_forever) && (NetTryCount >= retrycnt)) {
                eth_halt();
                net_set_state(NETLOOP_FAIL);
-               return;
+               /*
+                * We don't provide a way for the protocol to return an error,
+                * but this is almost always the reason.
+                */
+               return -ETIMEDOUT;
        }
 
        NetTryCount++;
@@ -606,7 +645,7 @@ void NetStartAgain(void)
 #if !defined(CONFIG_NET_DO_NOT_TRY_ANOTHER)
        eth_try_another(!NetRestarted);
 #endif
-       eth_init(gd->bd);
+       ret = eth_init();
        if (NetRestartWrap) {
                NetRestartWrap = 0;
                if (NetDevExists) {
@@ -618,6 +657,7 @@ void NetStartAgain(void)
        } else {
                net_set_state(NETLOOP_RESTART);
        }
+       return ret;
 }
 
 /**********************************************************************/
@@ -937,8 +977,7 @@ static void receive_icmp(struct ip_udp_hdr *ip, int len,
        }
 }
 
-void
-NetReceive(uchar *inpkt, int len)
+void net_process_received_packet(uchar *in_packet, int len)
 {
        struct ethernet_hdr *et;
        struct ip_udp_hdr *ip;
@@ -952,9 +991,9 @@ NetReceive(uchar *inpkt, int len)
 
        debug_cond(DEBUG_NET_PKT, "packet received\n");
 
-       NetRxPacket = inpkt;
+       NetRxPacket = in_packet;
        NetRxPacketLen = len;
-       et = (struct ethernet_hdr *)inpkt;
+       et = (struct ethernet_hdr *)in_packet;
 
        /* too small packet? */
        if (len < ETHER_HDR_SIZE)
@@ -962,7 +1001,7 @@ NetReceive(uchar *inpkt, int len)
 
 #ifdef CONFIG_API
        if (push_packet) {
-               (*push_packet)(inpkt, len);
+               (*push_packet)(in_packet, len);
                return;
        }
 #endif
@@ -989,11 +1028,11 @@ NetReceive(uchar *inpkt, int len)
                 */
                eth_proto = ntohs(et802->et_prot);
 
-               ip = (struct ip_udp_hdr *)(inpkt + E802_HDR_SIZE);
+               ip = (struct ip_udp_hdr *)(in_packet + E802_HDR_SIZE);
                len -= E802_HDR_SIZE;
 
        } else if (eth_proto != PROT_VLAN) {    /* normal packet */
-               ip = (struct ip_udp_hdr *)(inpkt + ETHER_HDR_SIZE);
+               ip = (struct ip_udp_hdr *)(in_packet + ETHER_HDR_SIZE);
                len -= ETHER_HDR_SIZE;
 
        } else {                        /* VLAN packet */
@@ -1018,7 +1057,7 @@ NetReceive(uchar *inpkt, int len)
                vlanid = cti & VLAN_IDMASK;
                eth_proto = ntohs(vet->vet_type);
 
-               ip = (struct ip_udp_hdr *)(inpkt + VLAN_ETHER_HDR_SIZE);
+               ip = (struct ip_udp_hdr *)(in_packet + VLAN_ETHER_HDR_SIZE);
                len -= VLAN_ETHER_HDR_SIZE;
        }
 
@@ -1074,7 +1113,7 @@ NetReceive(uchar *inpkt, int len)
                if ((ip->ip_hl_v & 0x0f) > 0x05)
                        return;
                /* Check the Checksum of the header */
-               if (!NetCksumOk((uchar *)ip, IP_HDR_SIZE / 2)) {
+               if (!ip_checksum_ok((uchar *)ip, IP_HDR_SIZE)) {
                        debug("checksum bad\n");
                        return;
                }
@@ -1171,7 +1210,7 @@ NetReceive(uchar *inpkt, int len)
 #endif
 
 
-#ifdef CONFIG_NETCONSOLE
+#if defined (CONFIG_NETCONSOLE) && !(CONFIG_SPL_BUILD)
                nc_input_packet((uchar *)ip + IP_UDP_HDR_SIZE,
                                        src_ip,
                                        ntohs(ip->udp_dst),
@@ -1196,7 +1235,6 @@ NetReceive(uchar *inpkt, int len)
 static int net_check_prereq(enum proto_t protocol)
 {
        switch (protocol) {
-               /* Fall through */
 #if defined(CONFIG_CMD_PING)
        case PING:
                if (NetPingIP == 0) {
@@ -1236,6 +1274,7 @@ common:
 #endif
                /* Fall through */
 
+       case BOOTME:
        case NETCONS:
        case TFTPSRV:
                if (NetOurIP == 0) {
@@ -1278,27 +1317,6 @@ common:
 }
 /**********************************************************************/
 
-int
-NetCksumOk(uchar *ptr, int len)
-{
-       return !((NetCksum(ptr, len) + 1) & 0xfffe);
-}
-
-
-unsigned
-NetCksum(uchar *ptr, int len)
-{
-       ulong   xsum;
-       ushort *p = (ushort *)ptr;
-
-       xsum = 0;
-       while (len-- > 0)
-               xsum += *p++;
-       xsum = (xsum & 0xffff) + (xsum >> 16);
-       xsum = (xsum & 0xffff) + (xsum >> 16);
-       return xsum & 0xffff;
-}
-
 int
 NetEthHdrSize(void)
 {
@@ -1398,7 +1416,7 @@ void net_set_udp_header(uchar *pkt, IPaddr_t dest, int dport, int sport,
        net_set_ip_header(pkt, dest, NetOurIP);
        ip->ip_len   = htons(IP_UDP_HDR_SIZE + len);
        ip->ip_p     = IPPROTO_UDP;
-       ip->ip_sum   = ~NetCksum((uchar *)ip, IP_HDR_SIZE >> 1);
+       ip->ip_sum   = compute_ip_checksum(ip, IP_HDR_SIZE);
 
        ip->udp_src  = htons(sport);
        ip->udp_dst  = htons(dport);