net: Move ARP out of net.c

Separate this functionality out of the net.c behemoth

Signed-off-by: Joe Hershberger <joe.hershberger@ni.com>
Acked-by: Simon Glass <sjg@chromium.org>
Acked-by: Mike Frysinger <vapier@gentoo.org>
diff --git a/net/net.c b/net/net.c
index 8624db0..ae72746 100644
--- a/net/net.c
+++ b/net/net.c
@@ -79,6 +79,7 @@
 #include <command.h>
 #include <linux/compiler.h>
 #include <net.h>
+#include "arp.h"
 #include "bootp.h"
 #include "tftp.h"
 #ifdef CONFIG_CMD_RARP
@@ -99,20 +100,6 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#ifndef	CONFIG_ARP_TIMEOUT
-/* Milliseconds before trying ARP again */
-# define ARP_TIMEOUT		5000UL
-#else
-# define ARP_TIMEOUT		CONFIG_ARP_TIMEOUT
-#endif
-
-
-#ifndef	CONFIG_NET_RETRY_COUNT
-# define ARP_TIMEOUT_COUNT	5	/* # of timeouts before giving up  */
-#else
-# define ARP_TIMEOUT_COUNT	CONFIG_NET_RETRY_COUNT
-#endif
-
 /** BOOTP EXTENTIONS **/
 
 /* Our subnet mask (0=unknown) */
@@ -219,82 +206,6 @@
 
 /**********************************************************************/
 
-IPaddr_t	NetArpWaitPacketIP;
-IPaddr_t	NetArpWaitReplyIP;
-/* MAC address of waiting packet's destination */
-uchar	       *NetArpWaitPacketMAC;
-/* THE transmit packet */
-uchar	       *NetArpWaitTxPacket;
-int		NetArpWaitTxPacketSize;
-uchar		NetArpWaitPacketBuf[PKTSIZE_ALIGN + PKTALIGN];
-ulong		NetArpWaitTimerStart;
-int		NetArpWaitTry;
-
-void ArpRequest(void)
-{
-	uchar *pkt;
-	ARP_t *arp;
-
-	debug("ARP broadcast %d\n", NetArpWaitTry);
-
-	pkt = NetTxPacket;
-
-	pkt += NetSetEther(pkt, NetBcastAddr, PROT_ARP);
-
-	arp = (ARP_t *) pkt;
-
-	arp->ar_hrd = htons(ARP_ETHER);
-	arp->ar_pro = htons(PROT_IP);
-	arp->ar_hln = 6;
-	arp->ar_pln = 4;
-	arp->ar_op = htons(ARPOP_REQUEST);
-
-	/* source ET addr */
-	memcpy(&arp->ar_data[0], NetOurEther, 6);
-	/* source IP addr */
-	NetWriteIP((uchar *) &arp->ar_data[6], NetOurIP);
-	/* dest ET addr = 0 */
-	memset(&arp->ar_data[10], '\0', 6);
-	if ((NetArpWaitPacketIP & NetOurSubnetMask) !=
-	    (NetOurIP & NetOurSubnetMask)) {
-		if (NetOurGatewayIP == 0) {
-			puts("## Warning: gatewayip needed but not set\n");
-			NetArpWaitReplyIP = NetArpWaitPacketIP;
-		} else {
-			NetArpWaitReplyIP = NetOurGatewayIP;
-		}
-	} else {
-		NetArpWaitReplyIP = NetArpWaitPacketIP;
-	}
-
-	NetWriteIP((uchar *) &arp->ar_data[16], NetArpWaitReplyIP);
-	(void) eth_send(NetTxPacket, (pkt - NetTxPacket) + ARP_HDR_SIZE);
-}
-
-void ArpTimeoutCheck(void)
-{
-	ulong t;
-
-	if (!NetArpWaitPacketIP)
-		return;
-
-	t = get_timer(0);
-
-	/* check for arp timeout */
-	if ((t - NetArpWaitTimerStart) > ARP_TIMEOUT) {
-		NetArpWaitTry++;
-
-		if (NetArpWaitTry >= ARP_TIMEOUT_COUNT) {
-			puts("\nARP Retry count exceeded; starting again\n");
-			NetArpWaitTry = 0;
-			NetStartAgain();
-		} else {
-			NetArpWaitTimerStart = t;
-			ArpRequest();
-		}
-	}
-}
-
 /*
  * Check if autoload is enabled. If so, use either NFS or TFTP to download
  * the boot file.
@@ -360,15 +271,11 @@
 	NetRestarted = 0;
 	NetDevExists = 0;
 
-	/* XXX problem with bss workaround */
-	NetArpWaitPacketMAC = NULL;
-	NetArpWaitTxPacket = NULL;
-	NetArpWaitPacketIP = 0;
-	NetArpWaitReplyIP = 0;
-	NetArpWaitTxPacket = NULL;
 	NetTxPacket = NULL;
 	NetTryCount = 1;
 
+	ArpInit();
+
 	if (!NetTxPacket) {
 		int	i;
 		/*
@@ -380,12 +287,6 @@
 			NetRxPackets[i] = NetTxPacket + (i+1)*PKTSIZE_ALIGN;
 	}
 
-	if (!NetArpWaitTxPacket) {
-		NetArpWaitTxPacket = &NetArpWaitPacketBuf[0] + (PKTALIGN - 1);
-		NetArpWaitTxPacket -= (ulong)NetArpWaitTxPacket % PKTALIGN;
-		NetArpWaitTxPacketSize = 0;
-	}
-
 	bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start");
 	eth_halt();
 	eth_set_current();
@@ -659,6 +560,13 @@
  *	Miscelaneous bits.
  */
 
+rxhand_f *
+NetGetHandler(void)
+{
+	return packetHandler;
+}
+
+
 void
 NetSetHandler(rxhand_f *f)
 {
@@ -1070,11 +978,12 @@
 {
 	Ethernet_t *et;
 	IP_t	*ip;
+#ifdef CONFIG_CMD_RARP
 	ARP_t	*arp;
+#endif
 	IPaddr_t tmp;
 	IPaddr_t src_ip;
 	int	x;
-	uchar *pkt;
 #if defined(CONFIG_CMD_CDP)
 	int iscdp;
 #endif
@@ -1171,99 +1080,7 @@
 	switch (x) {
 
 	case PROT_ARP:
-		/*
-		 * We have to deal with two types of ARP packets:
-		 * - REQUEST packets will be answered by sending  our
-		 *   IP address - if we know it.
-		 * - REPLY packates are expected only after we asked
-		 *   for the TFTP server's or the gateway's ethernet
-		 *   address; so if we receive such a packet, we set
-		 *   the server ethernet address
-		 */
-		debug("Got ARP\n");
-
-		arp = (ARP_t *)ip;
-		if (len < ARP_HDR_SIZE) {
-			printf("bad length %d < %d\n", len, ARP_HDR_SIZE);
-			return;
-		}
-		if (ntohs(arp->ar_hrd) != ARP_ETHER)
-			return;
-		if (ntohs(arp->ar_pro) != PROT_IP)
-			return;
-		if (arp->ar_hln != 6)
-			return;
-		if (arp->ar_pln != 4)
-			return;
-
-		if (NetOurIP == 0)
-			return;
-
-		if (NetReadIP(&arp->ar_data[16]) != NetOurIP)
-			return;
-
-		switch (ntohs(arp->ar_op)) {
-		case ARPOP_REQUEST:
-			/* reply with our IP address */
-			debug("Got ARP REQUEST, return our IP\n");
-			pkt = (uchar *)et;
-			pkt += NetSetEther(pkt, et->et_src, PROT_ARP);
-			arp->ar_op = htons(ARPOP_REPLY);
-			memcpy(&arp->ar_data[10], &arp->ar_data[0], 6);
-			NetCopyIP(&arp->ar_data[16], &arp->ar_data[6]);
-			memcpy(&arp->ar_data[0], NetOurEther, 6);
-			NetCopyIP(&arp->ar_data[6], &NetOurIP);
-			(void) eth_send((uchar *)et,
-					(pkt - (uchar *)et) + ARP_HDR_SIZE);
-			return;
-
-		case ARPOP_REPLY:		/* arp reply */
-			/* are we waiting for a reply */
-			if (!NetArpWaitPacketIP || !NetArpWaitPacketMAC)
-				break;
-
-#ifdef CONFIG_KEEP_SERVERADDR
-			if (NetServerIP == NetArpWaitPacketIP) {
-				char buf[20];
-				sprintf(buf, "%pM", arp->ar_data);
-				setenv("serveraddr", buf);
-			}
-#endif
-
-			debug("Got ARP REPLY, set server/gtwy eth addr (%pM)\n",
-				arp->ar_data);
-
-			tmp = NetReadIP(&arp->ar_data[6]);
-
-			/* matched waiting packet's address */
-			if (tmp == NetArpWaitReplyIP) {
-				debug("Got it\n");
-
-				/* save address for later use */
-				memcpy(NetArpWaitPacketMAC,
-				       &arp->ar_data[0], 6);
-
-#ifdef CONFIG_NETCONSOLE
-				(*packetHandler)(0, 0, 0, 0, 0);
-#endif
-				/* modify header, and transmit it */
-				memcpy(((Ethernet_t *)NetArpWaitTxPacket)->
-					et_dest, NetArpWaitPacketMAC, 6);
-				(void) eth_send(NetArpWaitTxPacket,
-						NetArpWaitTxPacketSize);
-
-				/* no arp request pending now */
-				NetArpWaitPacketIP = 0;
-				NetArpWaitTxPacketSize = 0;
-				NetArpWaitPacketMAC = NULL;
-
-			}
-			return;
-		default:
-			debug("Unexpected ARP opcode 0x%x\n",
-			      ntohs(arp->ar_op));
-			return;
-		}
+		ArpReceive(et, ip, len);
 		break;
 
 #ifdef CONFIG_CMD_RARP