On Thu, Jan 19, 2012 at 4:53 PM, Joe Hershberger <joe.hershber...@ni.com> wrote: > Signed-off-by: Joe Hershberger <joe.hershber...@ni.com>
Acked-by: Simon Glass <s...@chromium.org> > Cc: Joe Hershberger <joe.hershber...@gmail.com> > Cc: Wolfgang Denk <w...@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, w...@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, w...@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@lists.denx.de > http://lists.denx.de/mailman/listinfo/u-boot _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot