* Copyright 2000 Roland Borde
* Copyright 2000 Paolo Scaffardi
* Copyright 2000-2002 Wolfgang Denk, wd@denx.de
+ * SPDX-License-Identifier: GPL-2.0
*/
/*
#include <common.h>
#include <command.h>
+#include <environment.h>
#include <net.h>
#if defined(CONFIG_STATUS_LED)
#include <miiphy.h>
int NetTimeOffset;
#endif
-uchar PktBuf[(PKTBUFSRX+1) * PKTSIZE_ALIGN + PKTALIGN];
+static uchar PktBuf[(PKTBUFSRX+1) * PKTSIZE_ALIGN + PKTALIGN];
/* Receive packet */
uchar *NetRxPackets[PKTBUFSRX];
static int NetTryCount;
+int __maybe_unused net_busy_flag;
+
/**********************************************************************/
+static int on_bootfile(const char *name, const char *value, enum env_op op,
+ int flags)
+{
+ switch (op) {
+ case env_op_create:
+ case env_op_overwrite:
+ copy_filename(BootFile, value, sizeof(BootFile));
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+U_BOOT_ENV_CALLBACK(bootfile, on_bootfile);
+
/*
* Check if autoload is enabled. If so, use either NFS or TFTP to download
* the boot file.
*/
void net_auto_load(void)
{
+#if defined(CONFIG_CMD_NFS)
const char *s = getenv("autoload");
- if (s != NULL) {
- if (*s == 'n') {
- /*
- * Just use BOOTP/RARP to configure system;
- * Do not use TFTP to load the bootfile.
- */
- net_set_state(NETLOOP_SUCCESS);
- return;
- }
-#if defined(CONFIG_CMD_NFS)
- if (strcmp(s, "NFS") == 0) {
- /*
- * Use NFS to load the bootfile.
- */
- NfsStart();
- return;
- }
+ if (s != NULL && strcmp(s, "NFS") == 0) {
+ /*
+ * Use NFS to load the bootfile.
+ */
+ NfsStart();
+ return;
+ }
#endif
+ if (getenv_yesno("autoload") == 0) {
+ /*
+ * Just use BOOTP/RARP to configure system;
+ * Do not use TFTP to load the bootfile.
+ */
+ net_set_state(NETLOOP_SUCCESS);
+ return;
}
TftpStart(TFTPGET);
}
#endif
env_changed_id = env_id;
}
+ if (eth_get_dev())
+ memcpy(NetOurEther, eth_get_dev()->enetaddr, 6);
return;
}
NetRestarted = 0;
NetDevExists = 0;
NetTryCount = 1;
+ debug_cond(DEBUG_INT_STATE, "--- NetLoop Entry\n");
bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start");
net_init();
- eth_halt();
- eth_set_current();
- if (eth_init(bd) < 0) {
+ if (eth_is_on_demand_init() || protocol != NETCONS) {
eth_halt();
- return -1;
- }
+ eth_set_current();
+ if (eth_init(bd) < 0) {
+ eth_halt();
+ return -1;
+ }
+ } else
+ eth_init_state_only(bd);
restart:
- memcpy(NetOurEther, eth_get_dev()->enetaddr, 6);
-
+#ifdef CONFIG_USB_KEYBOARD
+ net_busy_flag = 0;
+#endif
net_set_state(NETLOOP_CONTINUE);
/*
* here on, this code is a state machine driven by received
* packets and timer events.
*/
+ debug_cond(DEBUG_INT_STATE, "--- NetLoop Init\n");
NetInitLoop();
switch (net_check_prereq(protocol)) {
#endif
#if defined(CONFIG_CMD_DHCP)
case DHCP:
- BootpTry = 0;
+ BootpReset();
NetOurIP = 0;
DhcpRequest(); /* Basically same as BOOTP */
break;
#endif
case BOOTP:
- BootpTry = 0;
+ BootpReset();
NetOurIP = 0;
BootpRequest();
break;
CDPStart();
break;
#endif
-#ifdef CONFIG_NETCONSOLE
+#if defined (CONFIG_NETCONSOLE) && !(CONFIG_SPL_BUILD)
case NETCONS:
NcStart();
break;
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
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, "--- NetLoop Abort!\n");
goto done;
}
}
#endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */
#endif /* CONFIG_MII, ... */
+ debug_cond(DEBUG_INT_STATE, "--- NetLoop timeout\n");
x = timeHandler;
timeHandler = (thand_f *)0;
(*x)();
case NETLOOP_SUCCESS:
net_cleanup_loop();
if (NetBootFileXferSize > 0) {
- char buf[20];
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);
+ setenv_hex("filesize", NetBootFileXferSize);
+ setenv_hex("fileaddr", load_addr);
}
- eth_halt();
+ if (protocol != NETCONS)
+ eth_halt();
+ else
+ eth_halt_state_only();
+
+ eth_set_last_protocol(protocol);
+
ret = NetBootFileXferSize;
+ debug_cond(DEBUG_INT_STATE, "--- NetLoop Success!\n");
goto done;
case NETLOOP_FAIL:
net_cleanup_loop();
+ /* Invalidate the last protocol */
+ eth_set_last_protocol(BOOTP);
+ debug_cond(DEBUG_INT_STATE, "--- NetLoop Fail!\n");
goto done;
case NETLOOP_CONTINUE:
}
done:
+#ifdef CONFIG_USB_KEYBOARD
+ net_busy_flag = 0;
+#endif
#ifdef CONFIG_CMD_TFTPPUT
/* Clear out the handlers */
net_set_udp_handler(NULL);
void net_set_udp_handler(rxhand_f *f)
{
+ debug_cond(DEBUG_INT_STATE, "--- NetLoop UDP handler set (%p)\n", f);
if (f == NULL)
udp_packet_handler = dummy_handler;
else
void net_set_arp_handler(rxhand_f *f)
{
+ debug_cond(DEBUG_INT_STATE, "--- NetLoop ARP handler set (%p)\n", f);
if (f == NULL)
arp_packet_handler = dummy_handler;
else
NetSetTimeout(ulong iv, thand_f *f)
{
if (iv == 0) {
+ debug_cond(DEBUG_INT_STATE,
+ "--- NetLoop timeout handler cancelled\n");
timeHandler = (thand_f *)0;
} else {
+ debug_cond(DEBUG_INT_STATE,
+ "--- NetLoop timeout handler set (%p)\n", f);
timeHandler = f;
timeStart = get_timer(0);
- timeDelta = iv;
+ timeDelta = iv * CONFIG_SYS_HZ / 1000;
}
}
/* if MAC address was not discovered yet, do an ARP request */
if (memcmp(ether, NetEtherNullAddr, 6) == 0) {
- debug("sending ARP for %pI4\n", &dest);
+ debug_cond(DEBUG_DEV_PKT, "sending ARP for %pI4\n", &dest);
/* save the ip and eth addr for the packet to send after arp */
NetArpWaitPacketIP = dest;
ArpRequest();
return 1; /* waiting */
} else {
- debug("sending UDP to %pI4/%pM\n", &dest, ether);
+ debug_cond(DEBUG_DEV_PKT, "sending UDP to %pI4/%pM\n",
+ &dest, ether);
NetSendPacket(NetTxPacket, pkt_hdr_size + payload_len);
return 0; /* transmitted */
}
#endif
ushort cti = 0, vlanid = VLAN_NONE, myvlanid, mynvlanid;
- debug("packet received\n");
+ debug_cond(DEBUG_NET_PKT, "packet received\n");
NetRxPacket = inpkt;
NetRxPacketLen = len;
eth_proto = ntohs(et->et_protlen);
- debug("packet received\n");
-
if (eth_proto < 1514) {
struct e802_hdr *et802 = (struct e802_hdr *)et;
/*
struct vlan_ethernet_hdr *vet =
(struct vlan_ethernet_hdr *)et;
- debug("VLAN packet received\n");
+ debug_cond(DEBUG_NET_PKT, "VLAN packet received\n");
/* too small packet? */
if (len < VLAN_ETHER_HDR_SIZE)
len -= VLAN_ETHER_HDR_SIZE;
}
- debug("Receive from protocol 0x%x\n", eth_proto);
+ debug_cond(DEBUG_NET_PKT, "Receive from protocol 0x%x\n", eth_proto);
#if defined(CONFIG_CMD_CDP)
if (iscdp) {
break;
#endif
case PROT_IP:
- debug("Got IP\n");
+ debug_cond(DEBUG_NET_PKT, "Got IP\n");
/* Before we start poking the header, make sure it is there */
if (len < IP_UDP_HDR_SIZE) {
debug("len bad %d < %lu\n", len,
}
/* Check the packet length */
if (len < ntohs(ip->ip_len)) {
- printf("len bad %d < %d\n", len, ntohs(ip->ip_len));
+ debug("len bad %d < %d\n", len, ntohs(ip->ip_len));
return;
}
len = ntohs(ip->ip_len);
- debug("len=%d, v=%02x\n", len, ip->ip_hl_v & 0xff);
+ debug_cond(DEBUG_NET_PKT, "len=%d, v=%02x\n",
+ len, ip->ip_hl_v & 0xff);
/* Can't deal with anything except IPv4 */
if ((ip->ip_hl_v & 0xf0) != 0x40)
if ((ip->ip_hl_v & 0x0f) > 0x05)
return;
/* Check the Checksum of the header */
- if (!NetCksumOk((uchar *)ip, IP_HDR_SIZE / 2)) {
- puts("checksum bad\n");
+ if (!ip_checksum_ok((uchar *)ip, IP_HDR_SIZE)) {
+ debug("checksum bad\n");
return;
}
/* If it is not for us, ignore it */
return;
}
+ debug_cond(DEBUG_DEV_PKT,
+ "received UDP (to=%pI4, from=%pI4, len=%d)\n",
+ &dst_ip, &src_ip, len);
+
#ifdef CONFIG_UDP_CHECKSUM
if (ip->udp_xsum != 0) {
ulong xsum;
#endif
-#ifdef CONFIG_NETCONSOLE
+#if defined (CONFIG_NETCONSOLE) && !(CONFIG_SPL_BUILD)
nc_input_packet((uchar *)ip + IP_UDP_HDR_SIZE,
+ src_ip,
ntohs(ip->udp_dst),
ntohs(ip->udp_src),
ntohs(ip->udp_len) - UDP_HDR_SIZE);
/**********************************************************************/
int
-NetCksumOk(uchar *ptr, int len)
-{
- return !((NetCksum(ptr, len) + 1) & 0xfffe);
-}
-
-
-unsigned
-NetCksum(uchar *ptr, int len)
-{
- ulong xsum;
- ushort *p = (ushort *)ptr;
-
- xsum = 0;
- while (len-- > 0)
- xsum += *p++;
- xsum = (xsum & 0xffff) + (xsum >> 16);
- xsum = (xsum & 0xffff) + (xsum >> 16);
- return xsum & 0xffff;
-}
-
-int
NetEthHdrSize(void)
{
ushort myvlanid;
net_set_ip_header(pkt, dest, NetOurIP);
ip->ip_len = htons(IP_UDP_HDR_SIZE + len);
ip->ip_p = IPPROTO_UDP;
- ip->ip_sum = ~NetCksum((uchar *)ip, IP_HDR_SIZE >> 1);
+ ip->ip_sum = compute_ip_checksum(ip, IP_HDR_SIZE);
ip->udp_src = htons(sport);
ip->udp_dst = htons(dport);