/**********************************************************************/
/*
* Main network processing loop.
*/
int net_loop(enum proto_t protocol)
//ping命令调用的时候,protocol = ping
{
int ret = -EINVAL;
net_restarted = 0;
net_dev_exists = 0;
net_try_count = 1;
debug_cond(DEBUG_INT_STATE, "--- net_loop Entry\n");
bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start");
net_init();
//初始化网络
if (eth_is_on_demand_init() || protocol != NETCONS) {
//protocol != NETCONS成立
eth_halt();
eth_set_current();
ret = eth_init();
if (ret < 0) {
eth_halt();
return ret;
}
} else {
eth_init_state_only();
}
restart:
#ifdef CONFIG_USB_KEYBOARD
net_busy_flag = 0;
#endif
net_set_state(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.
*/
debug_cond(DEBUG_INT_STATE, "--- net_loop Init\n");
net_init_loop();
switch (net_check_prereq(protocol)) {
case 1:
/* network not configured */
eth_halt();
return -ENODEV;
case 2:
/* network device not configured */
break;
case 0:
net_dev_exists = 1;
net_boot_file_size = 0;
switch (protocol) {
case TFTPGET:
#ifdef CONFIG_CMD_TFTPPUT
case TFTPPUT:
#endif
/* always use ARP to get server ethernet address */
tftp_start(protocol);
break;
#ifdef CONFIG_CMD_TFTPSRV
case TFTPSRV:
tftp_start_server();
break;
#endif
#if defined(CONFIG_CMD_DHCP)
case DHCP:
bootp_reset();
net_ip.s_addr = 0;
dhcp_request(); /* Basically same as BOOTP */
break;
#endif
case BOOTP:
bootp_reset();
net_ip.s_addr = 0;
bootp_request();
break;
#if defined(CONFIG_CMD_RARP)
case RARP:
rarp_try = 0;
net_ip.s_addr = 0;
rarp_request();
break;
#endif
#if defined(CONFIG_CMD_PING)
case PING:
ping_start();
break;
#endif
#if defined(CONFIG_CMD_NFS)
case NFS:
nfs_start();
break;
#endif
#if defined(CONFIG_CMD_CDP)
case CDP:
cdp_start();
break;
#endif
#if defined(CONFIG_NETCONSOLE) && !(CONFIG_SPL_BUILD)
case NETCONS:
nc_start();
break;
#endif
#if defined(CONFIG_CMD_SNTP)
case SNTP:
sntp_start();
break;
#endif
#if defined(CONFIG_CMD_DNS)
case DNS:
dns_start();
break;
#endif
#if defined(CONFIG_CMD_LINK_LOCAL)
case LINKLOCAL:
link_local_start();
break;
#endif
default:
break;
}
break;
}
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
#if defined(CONFIG_SYS_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, CONFIG_SYS_FAULT_MII_ADDR))
status_led_set(STATUS_LED_RED, STATUS_LED_OFF);
else
status_led_set(STATUS_LED_RED, STATUS_LED_ON);
#endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */
#endif /* CONFIG_MII, ... */
#ifdef CONFIG_USB_KEYBOARD
net_busy_flag = 1;
#endif
/*
* Main packet reception loop. Loop receiving packets until
* someone sets `net_state' to a state that terminates.
*/
for (;;) {
WATCHDOG_RESET();
#ifdef CONFIG_SHOW_ACTIVITY
show_activity(1);
#endif
if (arp_timeout_check() > 0)
time_start = get_timer(0);
/*
* Check the ethernet for a new packet. The ethernet
* receive routine will process it.
* Most drivers return the most recent packet size, but not
* errors that may have happened.
*/
eth_rx();
/*
* Abort if ctrl-c was pressed.
*/
if (ctrlc()) {
/* cancel any ARP that may not have completed */
net_arp_wait_packet_ip.s_addr = 0;
net_cleanup_loop();
eth_halt();
/* Invalidate the last protocol */
eth_set_last_protocol(BOOTP);
puts("\nAbort\n");
/* include a debug print as well incase the debug
messages are directed to stderr */
debug_cond(DEBUG_INT_STATE, "--- net_loop Abort!\n");
ret = -EINTR;
goto done;
}
/*
* Check for a timeout, and run the timeout handler
* if we have one.
*/
if (time_handler &&
((get_timer(0) - time_start) > time_delta)) {
thand_f *x;
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
#if defined(CONFIG_SYS_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,
CONFIG_SYS_FAULT_MII_ADDR))
status_led_set(STATUS_LED_RED, STATUS_LED_OFF);
else
status_led_set(STATUS_LED_RED, STATUS_LED_ON);
#endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */
#endif /* CONFIG_MII, ... */
debug_cond(DEBUG_INT_STATE, "--- net_loop timeout\n");
x = time_handler;
time_handler = (thand_f *)0;
(*x)();
}
if (net_state == NETLOOP_FAIL)
ret = net_start_again();
switch (net_state) {
case NETLOOP_RESTART:
net_restarted = 1;
goto restart;
case NETLOOP_SUCCESS:
net_cleanup_loop();
if (net_boot_file_size > 0) {
printf("Bytes transferred = %d (%x hex)\n",
net_boot_file_size, net_boot_file_size);
setenv_hex("filesize", net_boot_file_size);
setenv_hex("fileaddr", load_addr);
}
if (protocol != NETCONS)
eth_halt();
else
eth_halt_state_only();
eth_set_last_protocol(protocol);
ret = net_boot_file_size;
debug_cond(DEBUG_INT_STATE, "--- net_loop Success!\n");
goto done;
case NETLOOP_FAIL:
net_cleanup_loop();
/* Invalidate the last protocol */
eth_set_last_protocol(BOOTP);
debug_cond(DEBUG_INT_STATE, "--- net_loop Fail!\n");
goto done;
case NETLOOP_CONTINUE:
continue;
}
}
done:
#ifdef CONFIG_USB_KEYBOARD
net_busy_flag = 0;
#endif
#ifdef CONFIG_CMD_TFTPPUT
/* Clear out the handlers */
net_set_udp_handler(NULL);
net_set_icmp_handler(NULL);
#endif
return ret;
}
整理去除不运行的后
int net_loop(enum proto_t protocol)
//ping命令调用的时候,protocol = ping
{
int ret = -EINVAL;
net_restarted = 0;
net_dev_exists = 0;
net_try_count = 1;
net_init();
//初始化网络
eth_halt();
eth_set_current();
ret = eth_init();
if (ret < 0) {
eth_halt();
return ret;
}
restart:
net_set_state(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.
*/
net_init_loop();
net_dev_exists = 1;
net_boot_file_size = 0;
ping_start();
/*
* Main packet reception loop. Loop receiving packets until
* someone sets `net_state' to a state that terminates.
*/
for (;;) {
WATCHDOG_RESET();
if (arp_timeout_check() > 0)
time_start = get_timer(0);
/*
* Check the ethernet for a new packet. The ethernet
* receive routine will process it.
* Most drivers return the most recent packet size, but not
* errors that may have happened.
*/
eth_rx();
if (net_state == NETLOOP_FAIL)
ret = net_start_again();
switch (net_state) {
case NETLOOP_RESTART:
net_restarted = 1;
goto restart;
case NETLOOP_SUCCESS:
net_cleanup_loop();
if (net_boot_file_size > 0) {
printf("Bytes transferred = %d (%x hex)\n",
net_boot_file_size, net_boot_file_size);
setenv_hex("filesize", net_boot_file_size);
setenv_hex("fileaddr", load_addr);
}
if (protocol != NETCONS)
eth_halt();
else
eth_halt_state_only();
eth_set_last_protocol(protocol);
ret = net_boot_file_size;
debug_cond(DEBUG_INT_STATE, "--- net_loop Success!\n");
goto done;
case NETLOOP_FAIL:
net_cleanup_loop();
/* Invalidate the last protocol */
eth_set_last_protocol(BOOTP);
debug_cond(DEBUG_INT_STATE, "--- net_loop Fail!\n");
goto done;
case NETLOOP_CONTINUE:
continue;
}
}
return ret;
}
由此可见,ping命令先是一系列初始化,
net_init();
eth_init();
net_init_loop();
然后
ping_start();
启动ping命令的操作
最后通过死循环调用
eth_rx();
进行接收处理数据。