/**********************************************************************/
/*
* Main network processing loop.
*/
int
NetLoop(proto_t protocol)
{
bd_t *bd = gd->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;
if (!NetTxPacket) {
int i;
/*
* Setup packet buffers, aligned correctly.
*/
NetTxPacket = &PktBuf[0] + (PKTALIGN - 1);
NetTxPacket -= (ulong)NetTxPacket % PKTALIGN; //分配NetTxPacket
for (i = 0; i < PKTBUFSRX; i++) {
NetRxPackets[i] = NetTxPacket + (i+1)*PKTSIZE_ALIGN; //分配NetRxPackets[4]
}
}
if (!NetArpWaitTxPacket) {
NetArpWaitTxPacket = &NetArpWaitPacketBuf[0] + (PKTALIGN - 1);
NetArpWaitTxPacket -= (ulong)NetArpWaitTxPacket % PKTALIGN; //分配NetArpWaitTxPacket
NetArpWaitTxPacketSize = 0; //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); //读取本机MAC地址
#else
memcpy (NetOurEther, bd->bi_enetaddr, 6);
#endif
NetState = NETLOOP_CONTINUE; //设置网络状态为OK
/*
* 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) { //选择命令
#if (CONFIG_COMMANDS & CFG_CMD_NFS)
case NFS:
#endif
#if (CONFIG_COMMANDS & CFG_CMD_PING) //定义了的命令
case PING:
#endif
#if (CONFIG_COMMANDS & CFG_CMD_SNTP)
case SNTP:
#endif
case NETCONS:
case TFTP:
NetCopyIP(&NetOurIP, &bd->bi_ip_addr); //读取本机ip地址
NetOurGatewayIP = getenv_IPaddr ("gatewayip"); //读取本机网关地址
NetOurSubnetMask= getenv_IPaddr ("netmask"); //读取本机掩码地址
NetOurVLAN = getenv_VLAN("vlan"); //读取虚拟网
NetOurNativeVLAN = getenv_VLAN("nvlan"); //读取虚拟网
switch (protocol) {
#if (CONFIG_COMMANDS & CFG_CMD_NFS)
case NFS:
#endif
case NETCONS:
case TFTP:
NetServerIP = getenv_IPaddr ("serverip");
break;
#if (CONFIG_COMMANDS & CFG_CMD_PING)
case PING:
/* nothing */
break;
#endif
#if (CONFIG_COMMANDS & CFG_CMD_SNTP)
case SNTP:
/* nothing */
break;
#endif
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;
NetServerIP = getenv_IPaddr ("serverip");
NetOurVLAN = getenv_VLAN("vlan"); /* VLANs must be read */
NetOurNativeVLAN = getenv_VLAN("nvlan");
case CDP:
NetOurVLAN = getenv_VLAN("vlan"); /* VLANs must be read */
NetOurNativeVLAN = getenv_VLAN("nvlan");
break;
default:
break;
}
switch (net_check_prereq (protocol)) { //检测命令格式,正确返回0
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;
#if (CONFIG_COMMANDS & CFG_CMD_DHCP)
case DHCP:
/* Start with a clean slate... */
BootpTry = 0;
NetOurIP = 0;
NetServerIP = getenv_IPaddr ("serverip");
DhcpRequest(); /* Basically same as BOOTP */
break;
#endif /* CFG_CMD_DHCP */
case BOOTP:
BootpTry = 0;
BootpRequest ();
break;
case RARP:
RarpTry = 0;
RarpRequest ();
break;
#if (CONFIG_COMMANDS & CFG_CMD_PING)
case PING:
PingStart();
break;
#endif
#if (CONFIG_COMMANDS & CFG_CMD_NFS)
case NFS:
NfsStart();
break;
#endif
#if (CONFIG_COMMANDS & CFG_CMD_CDP)
case CDP:
CDPStart();
break;
#endif
#ifdef CONFIG_NETCONSOLE
case NETCONS:
NcStart();
break;
#endif
#if (CONFIG_COMMANDS & CFG_CMD_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();
puts ("\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[10];
printf("Bytes transferred = %ld (%lx hex)\n",
NetBootFileXferSize,
NetBootFileXferSize);
sprintf(buf, "%lx", NetBootFileXferSize);
setenv("filesize", buf);
sprintf(buf, "%lX", (unsigned long)load_addr);
setenv("fileaddr", buf);
}
eth_halt();
return NetBootFileXferSize;
case NETLOOP_FAIL:
return (-1);
}
}
}
/*
* Main network processing loop.
*/
int
NetLoop(proto_t protocol)
{
bd_t *bd = gd->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;
if (!NetTxPacket) {
int i;
/*
* Setup packet buffers, aligned correctly.
*/
NetTxPacket = &PktBuf[0] + (PKTALIGN - 1);
NetTxPacket -= (ulong)NetTxPacket % PKTALIGN; //分配NetTxPacket
for (i = 0; i < PKTBUFSRX; i++) {
NetRxPackets[i] = NetTxPacket + (i+1)*PKTSIZE_ALIGN; //分配NetRxPackets[4]
}
}
if (!NetArpWaitTxPacket) {
NetArpWaitTxPacket = &NetArpWaitPacketBuf[0] + (PKTALIGN - 1);
NetArpWaitTxPacket -= (ulong)NetArpWaitTxPacket % PKTALIGN; //分配NetArpWaitTxPacket
NetArpWaitTxPacketSize = 0; //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); //读取本机MAC地址
#else
memcpy (NetOurEther, bd->bi_enetaddr, 6);
#endif
NetState = NETLOOP_CONTINUE; //设置网络状态为OK
/*
* 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) { //选择命令
#if (CONFIG_COMMANDS & CFG_CMD_NFS)
case NFS:
#endif
#if (CONFIG_COMMANDS & CFG_CMD_PING) //定义了的命令
case PING:
#endif
#if (CONFIG_COMMANDS & CFG_CMD_SNTP)
case SNTP:
#endif
case NETCONS:
case TFTP:
NetCopyIP(&NetOurIP, &bd->bi_ip_addr); //读取本机ip地址
NetOurGatewayIP = getenv_IPaddr ("gatewayip"); //读取本机网关地址
NetOurSubnetMask= getenv_IPaddr ("netmask"); //读取本机掩码地址
NetOurVLAN = getenv_VLAN("vlan"); //读取虚拟网
NetOurNativeVLAN = getenv_VLAN("nvlan"); //读取虚拟网
switch (protocol) {
#if (CONFIG_COMMANDS & CFG_CMD_NFS)
case NFS:
#endif
case NETCONS:
case TFTP:
NetServerIP = getenv_IPaddr ("serverip");
break;
#if (CONFIG_COMMANDS & CFG_CMD_PING)
case PING:
/* nothing */
break;
#endif
#if (CONFIG_COMMANDS & CFG_CMD_SNTP)
case SNTP:
/* nothing */
break;
#endif
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;
NetServerIP = getenv_IPaddr ("serverip");
NetOurVLAN = getenv_VLAN("vlan"); /* VLANs must be read */
NetOurNativeVLAN = getenv_VLAN("nvlan");
case CDP:
NetOurVLAN = getenv_VLAN("vlan"); /* VLANs must be read */
NetOurNativeVLAN = getenv_VLAN("nvlan");
break;
default:
break;
}
switch (net_check_prereq (protocol)) { //检测命令格式,正确返回0
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;
#if (CONFIG_COMMANDS & CFG_CMD_DHCP)
case DHCP:
/* Start with a clean slate... */
BootpTry = 0;
NetOurIP = 0;
NetServerIP = getenv_IPaddr ("serverip");
DhcpRequest(); /* Basically same as BOOTP */
break;
#endif /* CFG_CMD_DHCP */
case BOOTP:
BootpTry = 0;
BootpRequest ();
break;
case RARP:
RarpTry = 0;
RarpRequest ();
break;
#if (CONFIG_COMMANDS & CFG_CMD_PING)
case PING:
PingStart();
break;
#endif
#if (CONFIG_COMMANDS & CFG_CMD_NFS)
case NFS:
NfsStart();
break;
#endif
#if (CONFIG_COMMANDS & CFG_CMD_CDP)
case CDP:
CDPStart();
break;
#endif
#ifdef CONFIG_NETCONSOLE
case NETCONS:
NcStart();
break;
#endif
#if (CONFIG_COMMANDS & CFG_CMD_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();
puts ("\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[10];
printf("Bytes transferred = %ld (%lx hex)\n",
NetBootFileXferSize,
NetBootFileXferSize);
sprintf(buf, "%lx", NetBootFileXferSize);
setenv("filesize", buf);
sprintf(buf, "%lX", (unsigned long)load_addr);
setenv("fileaddr", buf);
}
eth_halt();
return NetBootFileXferSize;
case NETLOOP_FAIL:
return (-1);
}
}
}