/* Current RX packet handler */
static rxhand_f *packetHandler;
+#ifdef CONFIG_CMD_TFTPPUT
+static rxhand_icmp_f *packet_icmp_handler; /* Current ICMP rx handler */
+#endif
/* Current timeout handler */
static thand_f *timeHandler;
/* Time base value */
/* THE transmit packet */
volatile uchar *NetTxPacket;
-static int net_check_prereq(proto_t protocol);
+static int net_check_prereq(enum proto_t protocol);
static int NetTryCount;
void ArpRequest(void)
{
- int i;
volatile uchar *pkt;
ARP_t *arp;
memcpy(&arp->ar_data[0], NetOurEther, 6);
/* source IP addr */
NetWriteIP((uchar *) &arp->ar_data[6], NetOurIP);
- for (i = 10; i < 16; ++i) {
- /* dest ET addr = 0 */
- arp->ar_data[i] = 0;
- }
-
+ /* dest ET addr = 0 */
+ memset(&arp->ar_data[10], '\0', 6);
if ((NetArpWaitPacketIP & NetOurSubnetMask) !=
(NetOurIP & NetOurSubnetMask)) {
if (NetOurGatewayIP == 0) {
}
}
-static void
-NetInitLoop(proto_t protocol)
+/*
+ * Check if autoload is enabled. If so, use either NFS or TFTP to download
+ * the boot file.
+ */
+void net_auto_load(void)
+{
+ 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.
+ */
+ NetState = NETLOOP_SUCCESS;
+ return;
+ }
+#if defined(CONFIG_CMD_NFS)
+ if (strcmp(s, "NFS") == 0) {
+ /*
+ * Use NFS to load the bootfile.
+ */
+ NfsStart();
+ return;
+ }
+#endif
+ }
+ TftpStart(TFTPGET);
+}
+
+static void NetInitLoop(enum proto_t protocol)
{
static int env_changed_id;
bd_t *bd = gd->bd;
* Main network processing loop.
*/
-int
-NetLoop(proto_t protocol)
+int NetLoop(enum proto_t protocol)
{
bd_t *bd = gd->bd;
+ int ret = -1;
NetRestarted = 0;
NetDevExists = 0;
case 0:
NetDevExists = 1;
+ NetBootFileXferSize = 0;
switch (protocol) {
- case TFTP:
+ case TFTPGET:
+#ifdef CONFIG_CMD_TFTPPUT
+ case TFTPPUT:
+#endif
/* always use ARP to get server ethernet address */
- TftpStart();
+ TftpStart(protocol);
break;
#ifdef CONFIG_CMD_TFTPSRV
case TFTPSRV:
break;
}
- NetBootFileXferSize = 0;
break;
}
if (ctrlc()) {
eth_halt();
puts("\nAbort\n");
- return -1;
+ goto done;
}
ArpTimeoutCheck();
setenv("fileaddr", buf);
}
eth_halt();
- return NetBootFileXferSize;
+ ret = NetBootFileXferSize;
+ goto done;
case NETLOOP_FAIL:
- return -1;
+ goto done;
}
}
+
+done:
+#ifdef CONFIG_CMD_TFTPPUT
+ /* Clear out the handlers */
+ NetSetHandler(NULL);
+ net_set_icmp_handler(NULL);
+#endif
+ return ret;
}
/**********************************************************************/
packetHandler = f;
}
+#ifdef CONFIG_CMD_TFTPPUT
+void net_set_icmp_handler(rxhand_icmp_f *f)
+{
+ packet_icmp_handler = f;
+}
+#endif
void
NetSetTimeout(ulong iv, thand_f *f)
break;
#endif
default:
+#ifdef CONFIG_CMD_TFTPPUT
+ if (packet_icmp_handler)
+ packet_icmp_handler(icmph->type, icmph->code,
+ ntohs(ip->udp_dst), src_ip, ntohs(ip->udp_src),
+ icmph->un.data, ntohs(ip->udp_len));
+#endif
break;
}
}
* subnet. So this is probably a warning that your
* configuration might be wrong. But I'm not really
* sure if there aren't any other situations.
+ *
+ * Simon Glass <sjg@chromium.org>: We get an ICMP when
+ * we send a tftp packet to a dead connection, or when
+ * there is no server at the other end.
*/
if (ip->ip_p == IPPROTO_ICMP) {
receive_icmp(ip, len, src_ip, et);
/**********************************************************************/
-static int net_check_prereq(proto_t protocol)
+static int net_check_prereq(enum proto_t protocol)
{
switch (protocol) {
/* Fall through */
#if defined(CONFIG_CMD_NFS)
case NFS:
#endif
- case TFTP:
+ case TFTPGET:
+ case TFTPPUT:
if (NetServerIP == 0) {
puts("*** ERROR: `serverip' not set\n");
return 1;