v2019.10
1 /**********************************************************************/ 2 /* 3 * Main network processing loop. 4 */ 5 6 int net_loop(enum proto_t protocol) 7 { 8 int ret = -EINVAL; 9 enum net_loop_state prev_net_state = net_state; 10 11 net_restarted = 0; 12 net_dev_exists = 0; 13 net_try_count = 1; 14 debug_cond(DEBUG_INT_STATE, "--- net_loop Entry\n"); 15 16 bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start"); 17 net_init(); 18 if (eth_is_on_demand_init() || protocol != NETCONS) { 19 eth_halt(); 20 eth_set_current(); 21 ret = eth_init(); 22 if (ret < 0) { 23 eth_halt(); 24 return ret; 25 } 26 } else { 27 eth_init_state_only(); 28 } 29 restart: 30 #ifdef CONFIG_USB_KEYBOARD 31 net_busy_flag = 0; 32 #endif 33 net_set_state(NETLOOP_CONTINUE); 34 35 /* 36 * Start the ball rolling with the given start function. From 37 * here on, this code is a state machine driven by received 38 * packets and timer events. 39 */ 40 debug_cond(DEBUG_INT_STATE, "--- net_loop Init\n"); 41 net_init_loop(); 42 43 switch (net_check_prereq(protocol)) { 44 case 1: 45 /* network not configured */ 46 eth_halt(); 47 net_set_state(prev_net_state); 48 return -ENODEV; 49 50 case 2: 51 /* network device not configured */ 52 break; 53 54 case 0: 55 net_dev_exists = 1; 56 net_boot_file_size = 0; 57 switch (protocol) { 58 case TFTPGET: 59 #ifdef CONFIG_CMD_TFTPPUT 60 case TFTPPUT: 61 #endif 62 /* always use ARP to get server ethernet address */ 63 tftp_start(protocol); 64 break; 65 #ifdef CONFIG_CMD_TFTPSRV 66 case TFTPSRV: 67 tftp_start_server(); 68 break; 69 #endif 70 #ifdef CONFIG_UDP_FUNCTION_FASTBOOT 71 case FASTBOOT: 72 fastboot_start_server(); 73 break; 74 #endif 75 #if defined(CONFIG_CMD_DHCP) 76 case DHCP: 77 bootp_reset(); 78 net_ip.s_addr = 0; 79 dhcp_request(); /* Basically same as BOOTP */ 80 break; 81 #endif 82 83 case BOOTP: 84 bootp_reset(); 85 net_ip.s_addr = 0; 86 bootp_request(); 87 break; 88 89 #if defined(CONFIG_CMD_RARP) 90 case RARP: 91 rarp_try = 0; 92 net_ip.s_addr = 0; 93 rarp_request(); 94 break; 95 #endif 96 #if defined(CONFIG_CMD_PING) 97 case PING: 98 ping_start(); 99 break; 100 #endif 101 #if defined(CONFIG_CMD_NFS) 102 case NFS: 103 nfs_start(); 104 break; 105 #endif 106 #if defined(CONFIG_CMD_CDP) 107 case CDP: 108 cdp_start(); 109 break; 110 #endif 111 #if defined(CONFIG_NETCONSOLE) && !defined(CONFIG_SPL_BUILD) 112 case NETCONS: 113 nc_start(); 114 break; 115 #endif 116 #if defined(CONFIG_CMD_SNTP) 117 case SNTP: 118 sntp_start(); 119 break; 120 #endif 121 #if defined(CONFIG_CMD_DNS) 122 case DNS: 123 dns_start(); 124 break; 125 #endif 126 #if defined(CONFIG_CMD_LINK_LOCAL) 127 case LINKLOCAL: 128 link_local_start(); 129 break; 130 #endif 131 #if defined(CONFIG_CMD_WOL) 132 case WOL: 133 wol_start(); 134 break; 135 #endif 136 default: 137 break; 138 } 139 140 break; 141 } 142 143 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) 144 #if defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN) && \ 145 defined(CONFIG_LED_STATUS) && \ 146 defined(CONFIG_LED_STATUS_RED) 147 /* 148 * Echo the inverted link state to the fault LED. 149 */ 150 if (miiphy_link(eth_get_dev()->name, CONFIG_SYS_FAULT_MII_ADDR)) 151 status_led_set(CONFIG_LED_STATUS_RED, CONFIG_LED_STATUS_OFF); 152 else 153 status_led_set(CONFIG_LED_STATUS_RED, CONFIG_LED_STATUS_ON); 154 #endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */ 155 #endif /* CONFIG_MII, ... */ 156 #ifdef CONFIG_USB_KEYBOARD 157 net_busy_flag = 1; 158 #endif 159 160 /* 161 * Main packet reception loop. Loop receiving packets until 162 * someone sets `net_state' to a state that terminates. 163 */ 164 for (;;) { 165 WATCHDOG_RESET(); 166 #ifdef CONFIG_SHOW_ACTIVITY 167 show_activity(1); 168 #endif 169 if (arp_timeout_check() > 0) 170 time_start = get_timer(0); 171 172 /* 173 * Check the ethernet for a new packet. The ethernet 174 * receive routine will process it. 175 * Most drivers return the most recent packet size, but not 176 * errors that may have happened. 177 */ 178 eth_rx(); 179 180 /* 181 * Abort if ctrl-c was pressed. 182 */ 183 if (ctrlc()) { 184 /* cancel any ARP that may not have completed */ 185 net_arp_wait_packet_ip.s_addr = 0; 186 187 net_cleanup_loop(); 188 eth_halt(); 189 /* Invalidate the last protocol */ 190 eth_set_last_protocol(BOOTP); 191 192 puts("\nAbort\n"); 193 /* include a debug print as well incase the debug 194 messages are directed to stderr */ 195 debug_cond(DEBUG_INT_STATE, "--- net_loop Abort!\n"); 196 ret = -EINTR; 197 goto done; 198 } 199 200 /* 201 * Check for a timeout, and run the timeout handler 202 * if we have one. 203 */ 204 if (time_handler && 205 ((get_timer(0) - time_start) > time_delta)) { 206 thand_f *x; 207 208 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) 209 #if defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN) && \ 210 defined(CONFIG_LED_STATUS) && \ 211 defined(CONFIG_LED_STATUS_RED) 212 /* 213 * Echo the inverted link state to the fault LED. 214 */ 215 if (miiphy_link(eth_get_dev()->name, 216 CONFIG_SYS_FAULT_MII_ADDR)) 217 status_led_set(CONFIG_LED_STATUS_RED, 218 CONFIG_LED_STATUS_OFF); 219 else 220 status_led_set(CONFIG_LED_STATUS_RED, 221 CONFIG_LED_STATUS_ON); 222 #endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */ 223 #endif /* CONFIG_MII, ... */ 224 debug_cond(DEBUG_INT_STATE, "--- net_loop timeout\n"); 225 x = time_handler; 226 time_handler = (thand_f *)0; 227 (*x)(); 228 } 229 230 if (net_state == NETLOOP_FAIL) 231 ret = net_start_again(); 232 233 switch (net_state) { 234 case NETLOOP_RESTART: 235 net_restarted = 1; 236 goto restart; 237 238 case NETLOOP_SUCCESS: 239 net_cleanup_loop(); 240 if (net_boot_file_size > 0) { 241 printf("Bytes transferred = %d (%x hex)\n", 242 net_boot_file_size, net_boot_file_size); 243 env_set_hex("filesize", net_boot_file_size); 244 env_set_hex("fileaddr", load_addr); 245 } 246 if (protocol != NETCONS) 247 eth_halt(); 248 else 249 eth_halt_state_only(); 250 251 eth_set_last_protocol(protocol); 252 253 ret = net_boot_file_size; 254 debug_cond(DEBUG_INT_STATE, "--- net_loop Success!\n"); 255 goto done; 256 257 case NETLOOP_FAIL: 258 net_cleanup_loop(); 259 /* Invalidate the last protocol */ 260 eth_set_last_protocol(BOOTP); 261 debug_cond(DEBUG_INT_STATE, "--- net_loop Fail!\n"); 262 ret = -ENONET; 263 goto done; 264 265 case NETLOOP_CONTINUE: 266 continue; 267 } 268 } 269 270 done: 271 #ifdef CONFIG_USB_KEYBOARD 272 net_busy_flag = 0; 273 #endif 274 #ifdef CONFIG_CMD_TFTPPUT 275 /* Clear out the handlers */ 276 net_set_udp_handler(NULL); 277 net_set_icmp_handler(NULL); 278 #endif 279 net_set_state(prev_net_state); 280 281 #if defined(CONFIG_CMD_PCAP) 282 if (pcap_active()) 283 pcap_print_status(); 284 #endif 285 return ret; 286 }