summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Hershberger <joe.hershberger@ni.com>2012-05-23 07:58:01 +0000
committerJoe Hershberger <joe.hershberger@ni.com>2012-05-23 14:19:23 -0500
commitd280d3f430a4056e7baf66dc4be705dc8cc9bd37 (patch)
treeaa2ed9082775d60fa6a6e0ef4096947ad200685e
parent1735188329d8c6357299462275061c05a46e100f (diff)
downloadu-boot-d280d3f430a4056e7baf66dc4be705dc8cc9bd37.tar.gz
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>
-rw-r--r--include/net.h3
-rw-r--r--net/Makefile1
-rw-r--r--net/arp.c213
-rw-r--r--net/arp.h30
-rw-r--r--net/net.c209
5 files changed, 259 insertions, 197 deletions
diff --git a/include/net.h b/include/net.h
index 453231bfbc..64700d915f 100644
--- a/include/net.h
+++ b/include/net.h
@@ -428,7 +428,8 @@ extern void NetSetIP(uchar *, IPaddr_t, int, int, int);
extern int NetCksumOk(uchar *, int); /* Return true if cksum OK */
extern uint NetCksum(uchar *, int); /* Calculate the checksum */
-/* Set callbacks */
+/* Callbacks */
+extern rxhand_f *NetGetHandler(void); /* Get RX packet handler */
extern void NetSetHandler(rxhand_f *); /* Set RX packet handler */
extern void net_set_icmp_handler(rxhand_icmp_f *f); /* Set ICMP RX handler */
extern void NetSetTimeout(ulong, thand_f *);/* Set timeout handler */
diff --git a/net/Makefile b/net/Makefile
index b350bfcc5e..0916a566a2 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -27,6 +27,7 @@ include $(TOPDIR)/config.mk
LIB = $(obj)libnet.o
+COBJS-$(CONFIG_CMD_NET) += arp.o
COBJS-$(CONFIG_CMD_NET) += bootp.o
COBJS-$(CONFIG_CMD_CDP) += cdp.o
COBJS-$(CONFIG_CMD_DNS) += dns.o
diff --git a/net/arp.c b/net/arp.c
new file mode 100644
index 0000000000..f75217c614
--- /dev/null
+++ b/net/arp.c
@@ -0,0 +1,213 @@
+/*
+ * Copied from Linux Monitor (LiMon) - Networking.
+ *
+ * Copyright 1994 - 2000 Neil Russell.
+ * (See License)
+ * Copyright 2000 Roland Borde
+ * Copyright 2000 Paolo Scaffardi
+ * Copyright 2000-2002 Wolfgang Denk, wd@denx.de
+ */
+
+#include <common.h>
+
+#include "arp.h"
+
+#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
+
+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 ArpInit(void)
+{
+ /* XXX problem with bss workaround */
+ NetArpWaitPacketMAC = NULL;
+ NetArpWaitPacketIP = 0;
+ NetArpWaitReplyIP = 0;
+ NetArpWaitTxPacket = &NetArpWaitPacketBuf[0] + (PKTALIGN - 1);
+ NetArpWaitTxPacket -= (ulong)NetArpWaitTxPacket % PKTALIGN;
+ NetArpWaitTxPacketSize = 0;
+}
+
+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();
+ }
+ }
+}
+
+void ArpReceive(Ethernet_t *et, IP_t *ip, int len)
+{
+ ARP_t *arp;
+ IPaddr_t tmp;
+ uchar *pkt;
+
+ /*
+ * 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
+
+ tmp = NetReadIP(&arp->ar_data[6]);
+
+ /* matched waiting packet's address */
+ if (tmp == NetArpWaitReplyIP) {
+ debug("Got ARP REPLY, set eth addr (%pM)\n",
+ arp->ar_data);
+
+ /* save address for later use */
+ memcpy(NetArpWaitPacketMAC,
+ &arp->ar_data[0], 6);
+
+#ifdef CONFIG_NETCONSOLE
+ NetGetHandler()(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;
+ }
+}
diff --git a/net/arp.h b/net/arp.h
new file mode 100644
index 0000000000..4016a9099a
--- /dev/null
+++ b/net/arp.h
@@ -0,0 +1,30 @@
+/*
+ * Copied from Linux Monitor (LiMon) - Networking.
+ *
+ * Copyright 1994 - 2000 Neil Russell.
+ * (See License)
+ * Copyright 2000 Roland Borde
+ * Copyright 2000 Paolo Scaffardi
+ * Copyright 2000-2002 Wolfgang Denk, wd@denx.de
+ */
+
+#ifndef __ARP_H__
+#define __ARP_H__
+
+#include <common.h>
+
+extern IPaddr_t NetArpWaitPacketIP;
+/* MAC address of waiting packet's destination */
+extern uchar *NetArpWaitPacketMAC;
+/* THE transmit packet */
+extern uchar *NetArpWaitTxPacket;
+extern int NetArpWaitTxPacketSize;
+extern ulong NetArpWaitTimerStart;
+extern int NetArpWaitTry;
+
+void ArpInit(void);
+void ArpRequest(void);
+void ArpTimeoutCheck(void);
+void ArpReceive(Ethernet_t *et, IP_t *ip, int len);
+
+#endif /* __ARP_H__ */
diff --git a/net/net.c b/net/net.c
index 8624db03a7..ae72746213 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 @@ static int NetTryCount;
/**********************************************************************/
-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 @@ int NetLoop(enum proto_t protocol)
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 @@ int NetLoop(enum proto_t protocol)
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 @@ void NetStartAgain(void)
* Miscelaneous bits.
*/
+rxhand_f *
+NetGetHandler(void)
+{
+ return packetHandler;
+}
+
+
void
NetSetHandler(rxhand_f *f)
{
@@ -1070,11 +978,12 @@ NetReceive(uchar *inpkt, int len)
{
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 @@ NetReceive(uchar *inpkt, int len)
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