📄 net.c
字号:
/* * 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 *//* * General Desription: * * The user interface supports commands for BOOTP, RARP, and TFTP. * Also, we support ARP internally. Depending on available data, * these interact as follows: * * BOOTP: * * Prerequisites: - own ethernet address * We want: - own IP address * - TFTP server IP address * - name of bootfile * Next step: ARP * * RARP: * * Prerequisites: - own ethernet address * We want: - own IP address * - TFTP server IP address * Next step: ARP * * ARP: * * Prerequisites: - own ethernet address * - own IP address * - TFTP server IP address * We want: - TFTP server ethernet address * Next step: TFTP * * DHCP: * * Prerequisites: - own ethernet address * We want: - IP, Netmask, ServerIP, Gateway IP * - bootfilename, lease time * Next step: - TFTP * * TFTP: * * Prerequisites: - own ethernet address * - own IP address * - TFTP server IP address * - TFTP server ethernet address * - name of bootfile (if unknown, we use a default name * derived from our own IP address) * We want: - load the boot file * Next step: none * * NFS: * * Prerequisites: - own ethernet address * - own IP address * - name of bootfile (if unknown, we use a default name * derived from our own IP address) * We want: - load the boot file * Next step: none * * SNTP: * * Prerequisites: - own ethernet address * - own IP address * We want: - network time * Next step: none */#include "config.h"#include "machine.h"#include "mmu.h"#include "heap.h"#include "serial.h"#include "printk.h"#include "command.h"#include "priv_data.h"#include "getcmd.h"#include "vivi_string.h"#include "processor.h"#include "priv_data.h"#include <reset_handle.h>#include <types.h>#include <net.h>#include "bootp.h"#include "tftp.h"#include "rarp.h"#include "nfs.h"#ifdef CONFIG_STATUS_LED#include <status_led.h>#include <miiphy.h>#endif#ifdef CONFIG_NET_SNTP#include "sntp.h"#endif//#if (CONFIG_COMMANDS & CFG_CMD_NET)#ifdef CONFIG_NETWORK#define ARP_TIMEOUT 50 /* Seconds before trying ARP again */#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#if 1//#define ET_DEBUG#define ET_DEBUGNEW#endif/** BOOTP EXTENTIONS **///bd_t global_bd;IPaddr_t NetOurSubnetMask=0; /* Our subnet mask (0=unknown) */IPaddr_t NetOurGatewayIP=0; /* Our gateways IP address */IPaddr_t NetOurDNSIP=0; /* Our DNS IP address */#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_DNS2)IPaddr_t NetOurDNS2IP=0; /* Our 2nd DNS IP address */#endifchar NetOurNISDomain[32]={0,}; /* Our NIS domain */char NetOurHostName[32]={0,}; /* Our hostname */char NetOurRootPath[64]={0,}; /* Our bootpath */ushort NetBootFileSize=0; /* Our bootfile size in blocks *//** END OF BOOTP EXTENTIONS **/ulong downfilesize;ulong NetBootFileXferSize; /* The actual transferred size of the bootfile (in bytes) */uchar NetOurEther[6]; /* Our ethernet address */uchar NetServerEther[6] = /* Boot server enet address */ { 0, 0, 0, 0, 0, 0 };IPaddr_t NetOurIP; /* Our IP addr (0 = unknown) */IPaddr_t NetServerIP; /* Our IP addr (0 = unknown) */volatile uchar *NetRxPkt; /* Current receive packet */int NetRxPktLen; /* Current rx packet length */unsigned NetIPID; /* IP packet ID */const uchar NetBcastAddr[6] = /* Ethernet bcast address */ { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };const uchar NetEtherNullAddr[6] = { 0, 0, 0, 0, 0, 0 };int NetState; /* Network loop state */#ifdef CONFIG_NET_MULTIint NetRestartWrap = 0; /* Tried all network devices */static int NetRestarted = 0; /* Network loop restarted */static int NetDevExists = 0; /* At least one device configured */#endif/* XXX in both little & big endian machines 0xFFFF == ntohs(-1) */char BootFile[128]; /* Boot File name */#ifdef CONFIG_NET_PINGIPaddr_t NetPingIP; /* the ip address to ping */static void PingStart(void);#endif#ifdef CONFIG_NET_SNTPIPaddr_t NetNtpServerIP; /* NTP server IP address */int NetTimeOffset=0; /* offset time from UTC */#endif#ifdef CONFIG_NETCONSOLEvoid NcStart(void);int nc_input_packet(uchar *pkt, unsigned dest, unsigned src, unsigned len);#endifvolatile uchar PktBuf[(PKTBUFSRX+1) * PKTSIZE_ALIGN + PKTALIGN];volatile uchar *NetRxPackets[PKTBUFSRX]; /* Receive packets */static rxhand_f *packetHandler; /* Current RX packet handler */static thand_f *timeHandler; /* Current timeout handler */static ulong timeStart; /* Time base value */static ulong timeDelta; /* Current timeout value */volatile uchar *NetTxPacket = 0; /* THE transmit packet */static int net_check_prereq (proto_t protocol);const bd_t *global_bd = (bd_t *)(VIVI_PRIV_RAM_BASE+NET_CONFIG_OFFSET+8);unsigned long load_addr;/**********************************************************************/IPaddr_t NetArpWaitPacketIP;IPaddr_t NetArpWaitReplyIP;uchar *NetArpWaitPacketMAC; /* MAC address of waiting packet's destination */uchar *NetArpWaitTxPacket; /* THE transmit packet */int NetArpWaitTxPacketSize;uchar NetArpWaitPacketBuf[PKTSIZE_ALIGN + PKTALIGN];ulong NetArpWaitTimerStart;int NetArpWaitTry;void ArpRequest (void){ int i; volatile uchar *pkt; ARP_t *arp;#ifdef ET_DEBUGNEW printk ("ARP broadcast %d\n", NetArpWaitTry);#endif 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); memcpy (arp->ar_sha, NetOurEther, 6); /* source ET addr */ NetWriteIP ((uchar *) arp->ar_spa, NetOurIP); /* source IP addr */ for (i = 0; i < 6; ++i) { arp->ar_tha[i] = 0; /* dest ET addr = 0 */ } if ((NetArpWaitPacketIP & NetOurSubnetMask) != (NetOurIP & NetOurSubnetMask)) { if (NetOurGatewayIP == 0) { putstr ("## Warning: gatewayip needed but not set\n"); } NetArpWaitReplyIP = NetOurGatewayIP; } else { NetArpWaitReplyIP = NetArpWaitPacketIP; } NetWriteIP ((uchar *) arp->ar_tpa, 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 * CFG_HZ) { NetArpWaitTry++; if (NetArpWaitTry >= ARP_TIMEOUT_COUNT) { putstr ("\nARP Retry count exceeded; \ngive up!\n\n"); //NetArpWaitTry = 0; //NetStartAgain(); NetState = NETLOOP_FAIL; } else { NetArpWaitTimerStart = t; ArpRequest(); } }}/**********************************************************************//* * Main network processing loop. */intNetLoop(proto_t protocol){ DECLARE_GLOBAL_DATA_PTR; int i; bd_t *bd = global_bd;#ifdef CONFIG_NET_MULTI NetRestarted = 0; NetDevExists = 0;#endif /* XXX problem with bss workaround */ NetArpWaitPacketMAC = NULL; NetArpWaitTxPacket = NULL; NetArpWaitPacketIP = 0; NetArpWaitReplyIP = 0; NetArpWaitTxPacket = NULL; NetTxPacket = NULL; downfilesize = 0; if (!NetTxPacket) { int i; /* * Setup packet buffers, aligned correctly. */ NetTxPacket = &PktBuf[0] + (PKTALIGN - 1); NetTxPacket -= (ulong)NetTxPacket % PKTALIGN; for (i = 0; i < PKTBUFSRX; i++) { NetRxPackets[i] = NetTxPacket + (i+1)*PKTSIZE_ALIGN; } } if (!NetArpWaitTxPacket) { NetArpWaitTxPacket = &NetArpWaitPacketBuf[0] + (PKTALIGN - 1); NetArpWaitTxPacket -= (ulong)NetArpWaitTxPacket % PKTALIGN; NetArpWaitTxPacketSize = 0; } eth_halt();#ifdef CONFIG_NET_MULTI eth_set_current();#endif if (eth_init(bd) < 0) { eth_halt(); return(-1); }restart:#ifdef CONFIG_NET_MULTI memcpy (NetOurEther, eth_get_dev()->enetaddr, 6);#else memcpy (NetOurEther, bd->bi_enetaddr, 6);#endif NetState = NETLOOP_CONTINUE; /* * Start the ball rolling with the given start function. From * here on, this code is a state machine driven by received * packets and timer events. */ switch (protocol) {#ifdef CONFIG_NET_NFS case NFS:#endif case NETCONS: case TFTP: //NetServerIP = getenv_IPaddr ("serverip"); NetCopyIP(&NetServerIP, &bd->serverip);#ifdef CONFIG_NET_PING case PING: NetCopyIP(&NetPingIP, &bd->serverip);#endif#ifdef CONFIG_NET_SNTP case SNTP:#endif NetCopyIP(&NetOurIP, &bd->ipaddr); //NetOurSubnetMask= getenv_IPaddr ("netmask"); NetCopyIP(&NetOurSubnetMask, &bd->netmask); //NetOurGatewayIP = getenv_IPaddr ("gateway"); NetCopyIP(&NetOurGatewayIP, &bd->gateway); break; case BOOTP: case RARP: /* * initialize our IP addr to 0 in order to accept ANY * IP addr assigned to us by the BOOTP / RARP server */ NetOurIP = 0; //NetServerIP = getenv_IPaddr ("serverip"); NetCopyIP(&NetServerIP, &bd->serverip); default: break; } switch (net_check_prereq (protocol)) { case 1: /* network not configured */ eth_halt(); return (-1);#ifdef CONFIG_NET_MULTI case 2: /* network device not configured */ break;#endif /* CONFIG_NET_MULTI */ case 0:#ifdef CONFIG_NET_MULTI NetDevExists = 1;#endif switch (protocol) { case TFTP: /* always use ARP to get server ethernet address */ TftpStart(); break;#ifdef CONFIG_NET_DHCP case DHCP: /* Start with a clean slate... */ BootpTry = 0; NetOurIP = 0; //NetServerIP = getenv_IPaddr ("serverip"); NetCopyIP(&NetServerIP, &bd->serverip); DhcpRequest(); /* Basically same as BOOTP */ break;#endif /* CFG_CMD_DHCP */#ifdef CONFIG_NET_BOOTP case BOOTP: BootpTry = 0; BootpRequest (); break;#endif#ifdef CONFIG_NET_RARP case RARP: RarpTry = 0; RarpRequest (); break;#endif#ifdef CONFIG_NET_PING case PING: PingStart(); break;#endif#ifdef CONFIG_NET_NFS case NFS: NfsStart(); break;#endif#ifdef CONFIG_NETCONSOLE case NETCONS: NcStart(); break;#endif#ifdef CONFIG_NET_SNTP case SNTP: SntpStart(); break;#endif default: break; } NetBootFileXferSize = 0; break; }#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)#if defined(CFG_FAULT_ECHO_LINK_DOWN) && defined(CONFIG_STATUS_LED) && defined(STATUS_LED_RED) /* * Echo the inverted link state to the fault LED. */ if(miiphy_link(eth_get_dev()->name, CFG_FAULT_MII_ADDR)) { status_led_set (STATUS_LED_RED, STATUS_LED_OFF); } else { status_led_set (STATUS_LED_RED, STATUS_LED_ON); }#endif /* CFG_FAULT_ECHO_LINK_DOWN, ... */#endif /* CONFIG_MII, ... */ /* * Main packet reception loop. Loop receiving packets until * someone sets `NetState' to a state that terminates. */ for (;;) { //WATCHDOG_RESET();#ifdef CONFIG_SHOW_ACTIVITY { extern void show_activity(int arg); show_activity(1); }#endif /* * Check the ethernet for a new packet. The ethernet * receive routine will process it. */ eth_rx(); /* * Abort if ctrl-c was pressed. */ if (ctrlc()) { eth_halt(); putstr ("\nAbort\n"); return (-1); } ArpTimeoutCheck(); /* * Check for a timeout, and run the timeout handler * if we have one. */ if (timeHandler && ((get_timer(0) - timeStart) > timeDelta)) { thand_f *x;#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)# if defined(CFG_FAULT_ECHO_LINK_DOWN) && \ defined(CONFIG_STATUS_LED) && \ defined(STATUS_LED_RED) /* * Echo the inverted link state to the fault LED. */ if(miiphy_link(eth_get_dev()->name, CFG_FAULT_MII_ADDR)) { status_led_set (STATUS_LED_RED, STATUS_LED_OFF); } else { status_led_set (STATUS_LED_RED, STATUS_LED_ON); }# endif /* CFG_FAULT_ECHO_LINK_DOWN, ... */#endif /* CONFIG_MII, ... */ x = timeHandler; timeHandler = (thand_f *)0; (*x)(); } switch (NetState) { case NETLOOP_RESTART:#ifdef CONFIG_NET_MULTI NetRestarted = 1;#endif goto restart; case NETLOOP_SUCCESS: if (NetBootFileXferSize > 0) { char buf[20]; printk("Bytes transferred = %ld (%lx hex)\n", NetBootFileXferSize, NetBootFileXferSize); sprintf(buf, "%lx", NetBootFileXferSize); //setenv("filesize", buf); downfilesize = NetBootFileXferSize; sprintf(buf, "%lX", (unsigned long)load_addr); //setenv("fileaddr", buf); } eth_halt(); return NetBootFileXferSize; case NETLOOP_FAIL: return (-1); } }}/**********************************************************************/static voidstartAgainTimeout(void){ NetState = NETLOOP_RESTART;}static voidstartAgainHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len){ /* Totally ignore the packet */}void NetStartAgain (void){#ifdef CONFIG_NET_MULTI //DECLARE_GLOBAL_DATA_PTR;#endif char *nretry; int noretry = 0, once = 0; if ((nretry = getenv ("netretry")) != NULL) { noretry = (strcmp (nretry, "no") == 0); once = (strcmp (nretry, "once") == 0); } if (noretry) { eth_halt (); NetState = NETLOOP_FAIL; return; }#ifndef CONFIG_NET_MULTI NetSetTimeout (10 * CFG_HZ, startAgainTimeout); NetSetHandler (startAgainHandler);#else /* !CONFIG_NET_MULTI*/ eth_halt (); eth_try_another (!NetRestarted); eth_init (global_bd); if (NetRestartWrap) { NetRestartWrap = 0; if (NetDevExists && !once) { NetSetTimeout (10 * CFG_HZ, startAgainTimeout); NetSetHandler (startAgainHandler); } else { NetState = NETLOOP_FAIL; } } else { NetState = NETLOOP_RESTART; }#endif /* CONFIG_NET_MULTI */}/**********************************************************************//* * Miscelaneous bits. */voidNetSetHandler(rxhand_f * f){ packetHandler = f;}voidNetSetTimeout(ulong iv, thand_f * f){ if (iv == 0) { timeHandler = (thand_f *)0; } else { timeHandler = f; timeStart = get_timer(0); timeDelta = iv; }}voidNetSendPacket(volatile uchar * pkt, int len){ (void) eth_send(pkt, len);}intNetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport, int len){ uchar *pkt; /* convert to new style broadcast */ if (dest == 0) dest = 0xFFFFFFFF; /* if broadcast, make the ether address a broadcast and don't do ARP */ if (dest == 0xFFFFFFFF) ether = NetBcastAddr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -