#include <net.h>
#include "tftp.h"
#include "bootp.h"
+#ifdef CONFIG_SYS_DIRECT_FLASH_TFTP
+#include <flash.h>
+#endif
/* Well known TFTP port # */
#define WELL_KNOWN_PORT 69
static ulong TftpTimeoutMSecs = TIMEOUT;
static int TftpTimeoutCountMax = TIMEOUT_COUNT;
+static ulong time_start; /* Record time we started tftp */
/*
* These globals govern the timeout behavior when attempting a connection to a
static char tftp_filename[MAX_LEN];
-#ifdef CONFIG_SYS_DIRECT_FLASH_TFTP
-extern flash_info_t flash_info[];
-#endif
-
/* 512 is poor choice for ethernet, MTU is typically 1500.
* Minus eth.hdrs thats 1468. Can get 2x better throughput with
* almost-MTU block sizes. At least try... fall back to 512 if need be.
static int PrevBitmapHole, Mapsize = MTFTP_BITMAPSIZE;
static uchar ProhibitMcast, MasterClient;
static uchar Multicast;
-extern IPaddr_t Mcast_addr;
static int Mcast_port;
static ulong TftpEndingBlock; /* can get 'last' block before done..*/
#endif /* CONFIG_MCAST_TFTP */
-static __inline__ void
-store_block(unsigned block, uchar *src, unsigned len)
+static inline void
+store_block(int block, uchar *src, unsigned len)
{
ulong offset = block * TftpBlkSize + TftpBlockWrapOffset;
ulong newsize = offset + len;
rc = flash_write((char *)src, (ulong)(load_addr+offset), len);
if (rc) {
flash_perror(rc);
- NetState = NETLOOP_FAIL;
+ net_set_state(NETLOOP_FAIL);
return;
}
- }
- else
+ } else
#endif /* CONFIG_SYS_DIRECT_FLASH_TFTP */
{
(void)memcpy((void *)(load_addr + offset), src, len);
}
/* Clear our state ready for a new transfer */
-void new_transfer(void)
+static void new_transfer(void)
{
TftpLastBlock = 0;
TftpBlockWrap = 0;
TftpNumchars++;
}
#endif
+ time_start = get_timer(time_start);
+ if (time_start > 0) {
+ puts("\n\t "); /* Line up with "Loading: " */
+ print_size(NetBootFileXferSize /
+ time_start * 1000, "/s");
+ }
puts("\ndone\n");
- NetState = NETLOOP_SUCCESS;
+ net_set_state(NETLOOP_SUCCESS);
}
static void
TftpSend(void)
{
uchar *pkt;
- volatile uchar *xp;
- int len = 0;
- volatile ushort *s;
+ uchar *xp;
+ int len = 0;
+ ushort *s;
#ifdef CONFIG_MCAST_TFTP
/* Multicast TFTP.. non-MasterClients do not ACK data. */
* We will always be sending some sort of packet, so
* cobble together the packet headers now.
*/
- pkt = (uchar *)(NetTxPacket + NetEthHdrSize() + IP_HDR_SIZE);
+ pkt = NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE;
switch (TftpState) {
case STATE_SEND_RRQ:
case STATE_SEND_WRQ:
xp = pkt;
s = (ushort *)pkt;
+#ifdef CONFIG_CMD_TFTPPUT
*s++ = htons(TftpState == STATE_SEND_RRQ ? TFTP_RRQ :
TFTP_WRQ);
+#else
+ *s++ = htons(TFTP_RRQ);
+#endif
pkt = (uchar *)s;
strcpy((char *)pkt, tftp_filename);
pkt += strlen(tftp_filename) + 1;
0, TftpBlkSizeOption, 0);
#ifdef CONFIG_MCAST_TFTP
/* Check all preconditions before even trying the option */
- if (!ProhibitMcast
- && (Bitmap = malloc(Mapsize))
- && eth_get_dev()->mcast) {
- free(Bitmap);
- Bitmap = NULL;
- pkt += sprintf((char *)pkt, "multicast%c%c", 0, 0);
+ if (!ProhibitMcast) {
+ Bitmap = malloc(Mapsize);
+ if (Bitmap && eth_get_dev()->mcast) {
+ free(Bitmap);
+ Bitmap = NULL;
+ pkt += sprintf((char *)pkt, "multicast%c%c",
+ 0, 0);
+ }
}
#endif /* CONFIG_MCAST_TFTP */
len = pkt - xp;
TftpOurPort, len);
}
-
+#ifdef CONFIG_CMD_TFTPPUT
static void icmp_handler(unsigned type, unsigned code, unsigned dest,
IPaddr_t sip, unsigned src, uchar *pkt, unsigned len)
{
restart("TFTP server died");
}
}
+#endif
static void
TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
unsigned len)
{
- ushort proto;
- ushort *s;
+ __be16 proto;
+ __be16 *s;
int i;
if (dest != TftpOurPort) {
return;
len -= 2;
/* warning: don't use increment (++) in ntohs() macros!! */
- s = (ushort *)pkt;
+ s = (__be16 *)pkt;
proto = *s++;
pkt = (uchar *)s;
switch (ntohs(proto)) {
if (len < 2)
return;
len -= 2;
- TftpBlock = ntohs(*(ushort *)pkt);
+ TftpBlock = ntohs(*(__be16 *)pkt);
update_block_number();
if (MasterClient && (TftpBlock >= TftpEndingBlock)) {
puts("\nMulticast tftp done\n");
mcast_cleanup();
- NetState = NETLOOP_SUCCESS;
+ net_set_state(NETLOOP_SUCCESS);
}
- }
- else
+ } else
#endif
if (len < TftpBlkSize)
tftp_complete();
case TFTP_ERROR:
printf("\nTFTP error: '%s' (%d)\n",
- pkt + 2, ntohs(*(ushort *)pkt));
+ pkt + 2, ntohs(*(__be16 *)pkt));
- switch (ntohs(*(ushort *)pkt)) {
+ switch (ntohs(*(__be16 *)pkt)) {
case TFTP_ERR_FILE_NOT_FOUND:
case TFTP_ERR_ACCESS_DENIED:
puts("Not retrying...\n");
eth_halt();
- NetState = NETLOOP_FAIL;
+ net_set_state(NETLOOP_FAIL);
break;
case TFTP_ERR_UNDEFINED:
case TFTP_ERR_DISK_FULL:
TftpRemoteIP = NetServerIP;
if (BootFile[0] == '\0') {
- sprintf(default_filename, "%02lX%02lX%02lX%02lX.img",
+ sprintf(default_filename, "%02X%02X%02X%02X.img",
NetOurIP & 0xFF,
(NetOurIP >> 8) & 0xFF,
(NetOurIP >> 16) & 0xFF,
printf("Using %s device\n", eth_get_name());
printf("TFTP %s server %pI4; our IP address is %pI4",
- protocol == TFTPPUT ? "to" : "from", &TftpRemoteIP, &NetOurIP);
+#ifdef CONFIG_CMD_TFTPPUT
+ protocol == TFTPPUT ? "to" : "from",
+#else
+ "from",
+#endif
+ &TftpRemoteIP, &NetOurIP);
/* Check if we need to send across this subnet */
if (NetOurGatewayIP && NetOurSubnetMask) {
TftpState = STATE_SEND_RRQ;
}
+ time_start = get_timer(0);
TftpTimeoutCountMax = TftpRRQTimeoutCountMax;
NetSetTimeout(TftpTimeoutMSecs, TftpTimeout);
- NetSetHandler(TftpHandler);
+ net_set_udp_handler(TftpHandler);
+#ifdef CONFIG_CMD_TFTPPUT
net_set_icmp_handler(icmp_handler);
-
+#endif
TftpRemotePort = WELL_KNOWN_PORT;
TftpTimeoutCount = 0;
/* Use a pseudo-random port unless a specific port is set */
#endif
TftpState = STATE_RECV_WRQ;
- NetSetHandler(TftpHandler);
+ net_set_udp_handler(TftpHandler);
}
#endif /* CONFIG_CMD_TFTPSRV */