?? net_core.c
字號:
/* * vivi/net/net_core.c * * Based on u-boot * * $Id: net_core.c,v 1.0 2004/08/12 11:14:01 kingmonkey Exp $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Description: some functions for net routines . * */ #include "config.h" #include "machine.h"#include "printk.h"#include "bootp.h"#include "tftp.h"#include "rarp.h"#include "nfs.h"#include "time.h"#include "net.h"#include <string.h>#include <types.h>//#define ET_DEBUG 0#define ARP_TIMEOUT 50 /* Seconds before trying ARP again */#ifndef CONFIG_NET_RETRY_COUNT#define ARP_TIMEOUT_COUNT 100 /* # of timeouts before giving up */#else#define ARP_TIMEOUT_COUNT (CONFIG_NET_RETRY_COUNT)#endifnet_config *global_bd = (net_config *)(VIVI_PRIV_RAM_BASE + NET_CONFIG_OFFSET + 8); /* gloable config info from flash*/ulong downfilesize;ulong downfileaddr;/** BOOTP EXTENTIONS **/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 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=0; /* Our IP addr (0 = unknown) */IPaddr_t NetServerIP=0; /* Our IP addr (0 = unknown) */volatile uchar *NetRxPkt; /* Current receive packet */int NetRxPktLen=0; /* Current rx packet length */unsigned NetIPID=0; /* IP packet ID */uchar NetBcastAddr[6] ={ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; /* Ethernet bcast address */uchar NetEtherNullAddr[6] = { 0, 0, 0, 0, 0, 0 };#ifdef CONFIG_CMD_CDPuchar NetCDPAddr[6] = { 0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcc }; /* Ethernet bcast address */#endifint NetState=0; /* Network loop state *//* XXX in both little & big endian machines 0xFFFF == ntohs(-1) */ushort NetOurVLAN = 0xFFFF; /* default is without VLAN */ushort NetOurNativeVLAN = 0xFFFF; /* ditto */char BootFile[128]={0,}; /* Boot File name */#ifdef CONFIG_CMD_PINGIPaddr_t NetPingIP=0; /* the ip address to ping */static void PingStart(void);#endif#ifdef CONFIG_CMD_CDPstatic void CDPStart(void);#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);/**********************************************************************/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;extern int eth_init(net_config *bis); /* Initialize the device */extern int eth_send(volatile void *packet, int length); /* Send a packet */extern int eth_rx(void); /* Check for received packets */extern void eth_halt(void); /* stop SCC */extern char *eth_get_name(void); /* get name of current device */void ArpRequest (void){ int i; volatile uchar *pkt; ARP_t *arp;// printk("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); memcpy (&arp->ar_data[0], NetOurEther, 6); /* source ET addr */ NetWriteIP ((uchar *) & arp->ar_data[6], NetOurIP); /* source IP addr */ for (i = 10; i < 16; ++i) { arp->ar_data[i] = 0; /* dest ET addr = 0 */ } if ((NetArpWaitPacketIP & NetOurSubnetMask) != (NetOurIP & NetOurSubnetMask)) { if (NetOurGatewayIP == 0) { printk("## Warning: gatewayip needed but not set\n"); } 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 * CFG_HZ) { NetArpWaitTry++; if (NetArpWaitTry >= ARP_TIMEOUT_COUNT) { printk("\nARP Retry count exceeded; starting again\n"); NetArpWaitTry = 0; NetStartAgain(); } else { NetArpWaitTimerStart = t; ArpRequest(); } }}/**********************************************************************//* * Main network processing loop. */intNetLoop(proto_t protocol){ net_config *bd = global_bd; downfilesize = 0; /* XXX problem with bss workaround */ NetArpWaitPacketMAC = NULL; NetArpWaitTxPacket = NULL; NetArpWaitPacketIP = 0; NetArpWaitReplyIP = 0; NetArpWaitTxPacket = NULL; NetTxPacket = NULL; 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(); if (eth_init(bd) < 0) return(-1);restart: memcpy (NetOurEther, bd->bi_enetaddr, 6); 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) { case NFS: case PING: case TFTP:/* NetCopyIP(&NetOurIP, &bd->bi_ip_addr); NetCopyIP(&NetOurGatewayIP, &bd->gatewayip); NetCopyIP(&NetOurSubnetMask, &bd->netmask); NetCopyVLAN(&NetOurVLAN, &bd->vlan); NetCopyVLAN(&NetOurNativeVLAN, &bd->nvlan); NetOurIP=htonl(bd->bi_ip_addr); NetOurGatewayIP=htonl(bd->gatewayip); NetOurSubnetMask=htonl(bd->netmask); NetOurVLAN=htonl(bd->vlan); NetOurNativeVLAN=htonl(bd->nvlan);*/ NetOurIP=bd->bi_ip_addr; NetOurGatewayIP=bd->gatewayip; NetOurSubnetMask=bd->netmask; NetOurVLAN=bd->vlan; NetOurNativeVLAN=bd->nvlan; switch (protocol) { case NFS: case TFTP:// NetCopyIP(&NetServerIP, &bd->serverip);// NetServerIP=htonl(bd->serverip); NetServerIP=bd->serverip; break; case PING: /* nothing */ break; default: break; } 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; NetCopyIP(&NetServerIP, &bd->serverip); NetCopyVLAN(&NetOurVLAN, &bd->vlan); NetCopyVLAN(&NetOurNativeVLAN, &bd->nvlan); case CDP: NetCopyVLAN(&NetOurVLAN, &bd->vlan); NetCopyVLAN(&NetOurNativeVLAN, &bd->nvlan); break; default: break; } switch (net_check_prereq (protocol)) { case 1: /* network not configured */ return (-1); case 0: switch (protocol) { case TFTP: #ifdef CONFIG_CMD_TFTP /* always use ARP to get server ethernet address */ TftpStart(); #endif break; case DHCP: /* Start with a clean slate... */ NetOurIP = 0; NetCopyIP(&NetServerIP, &bd->serverip); #ifdef CONFIG_CMD_DHCP DhcpRequest(); /* Basically same as BOOTP */ #endif break; case BOOTP: #ifdef CONFIG_CMD_BOOTP BootpTry = 0; BootpRequest (); #endif break; case RARP: #ifdef CONFIG_CMD_RARP RarpTry = 0; RarpRequest (); #endif break; case PING: #ifdef CONFIG_CMD_PING PingStart(); #endif break; case NFS: #ifdef CONFIG_CMD_NFS NfsStart(); #endif break; case CDP: #ifdef CONFIG_CMD_CDP CDPStart(); #endif break; default: break; } NetBootFileXferSize = 0; break; } /* * Main packet reception loop. Loop receiving packets until * someone sets `NetQuit'. */ for (;;) { // PingStart();// printk("here for netloop\n"); /* * 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(); printk("\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; x = timeHandler; timeHandler = (thand_f *)0; (*x)(); } switch (NetState) { case NETLOOP_RESTART: printk("goto restart\n"); goto restart; case NETLOOP_SUCCESS: if (NetBootFileXferSize > 0) { printk("Bytes transferred = %ld (%lx hex)\n",NetBootFileXferSize,NetBootFileXferSize); downfilesize = NetBootFileXferSize; } 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 */ return ;}void NetStartAgain (void){ // eth_halt ();// NetState = NETLOOP_FAIL; NetSetTimeout (10 * CFG_HZ, startAgainTimeout); NetSetHandler (startAgainHandler); return; }/**********************************************************************//* * Miscelaneous bits. */voidNetSetHandler(rxhand_f * f){ packetHandler = f;}voidNetSetTimeout(int 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; /* if MAC address was not discovered yet, save the packet and do an ARP request */ if (memcmp(ether, NetEtherNullAddr, 6) == 0) {// printk("sending ARP for "); print_IPaddr(dest); printk("\n"); NetArpWaitPacketIP = dest; NetArpWaitPacketMAC = ether;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -