[U-Boot] [PATCH 06/28] net: Move ARP out of net.c
Simon Glass
sjg at chromium.org
Tue Jan 24 06:35:09 CET 2012
On Thu, Jan 19, 2012 at 4:53 PM, Joe Hershberger <joe.hershberger at ni.com> wrote:
> Signed-off-by: Joe Hershberger <joe.hershberger at ni.com>
Acked-by: Simon Glass <sjg at chromium.org>
> Cc: Joe Hershberger <joe.hershberger at gmail.com>
> Cc: Wolfgang Denk <wd at denx.de>
> ---
> include/net.h | 3 +-
> net/Makefile | 1 +
> net/arp.c | 213 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> net/arp.h | 30 ++++++++
> net/net.c | 209 ++++----------------------------------------------------
> 5 files changed, 259 insertions(+), 197 deletions(-)
> create mode 100644 net/arp.c
> create mode 100644 net/arp.h
>
> diff --git a/include/net.h b/include/net.h
> index 0396b69..2d00233 100644
> --- a/include/net.h
> +++ b/include/net.h
> @@ -418,7 +418,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 b350bfc..0916a56 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 0000000..f75217c
> --- /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 at 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 0000000..09c763d
> --- /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 at denx.de
> + */
> +
> +#ifndef __ARP_H__
> +#define __ARP_H__
> +
> +#include <net.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 48d3ca8..2dae5a0 100644
> --- a/net/net.c
> +++ b/net/net.c
> @@ -78,6 +78,7 @@
> #include <watchdog.h>
> #include <command.h>
> #include <net.h>
> +#include "arp.h"
> #include "bootp.h"
> #include "tftp.h"
> #ifdef CONFIG_CMD_RARP
> @@ -100,20 +101,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) */
> @@ -220,82 +207,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.
> @@ -363,15 +274,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;
> /*
> @@ -383,12 +290,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;
> - }
> -
> eth_halt();
> eth_set_current();
> if (eth_init(bd) < 0) {
> @@ -661,6 +562,13 @@ void NetStartAgain(void)
> * Miscelaneous bits.
> */
>
> +rxhand_f *
> +NetGetHandler(void)
> +{
> + return packetHandler;
> +}
> +
> +
> void
> NetSetHandler(rxhand_f *f)
> {
> @@ -1072,11 +980,12 @@ NetReceive(volatile 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
> @@ -1173,99 +1082,7 @@ NetReceive(volatile 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
> --
> 1.6.0.2
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
More information about the U-Boot
mailing list