#include <common.h>
#include <command.h>
+#include <mapmem.h>
#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
TFTP_ERR_FILE_ALREADY_EXISTS = 6,
};
-static IPaddr_t TftpRemoteIP;
+static struct in_addr tftp_remote_ip;
/* The UDP port at their end */
static int TftpRemotePort;
/* The UDP port at our end */
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..*/
static void
mcast_cleanup(void)
{
- if (Mcast_addr)
- eth_mcast_join(Mcast_addr, 0);
+ if (net_mcast_addr)
+ eth_mcast_join(net_mcast_addr, 0);
if (Bitmap)
free(Bitmap);
Bitmap = NULL;
- Mcast_addr = Multicast = Mcast_port = 0;
+ net_mcast_addr.s_addr = 0;
+ Multicast = 0;
+ Mcast_port = 0;
TftpEndingBlock = -1;
}
#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);
+ void *ptr = map_sysmem(load_addr + offset, len);
+
+ memcpy(ptr, src, len);
+ unmap_sysmem(ptr);
}
#ifdef CONFIG_MCAST_TFTP
if (Multicast)
ext2_set_bit(block, Bitmap);
#endif
- if (NetBootFileXferSize < newsize)
- NetBootFileXferSize = newsize;
+ if (net_boot_file_size < newsize)
+ net_boot_file_size = newsize;
}
/* Clear our state ready for a new transfer */
ulong offset = ((int)block - 1) * len + TftpBlockWrapOffset;
ulong tosend = len;
- tosend = min(NetBootFileXferSize - offset, tosend);
+ tosend = min(net_boot_file_size - offset, tosend);
(void)memcpy(dst, (void *)(save_addr + offset), tosend);
debug("%s: block=%d, offset=%ld, len=%d, tosend=%ld\n", __func__,
block, offset, len, tosend);
* number of 0 this means that there was a wrap
* around of the (16 bit) counter.
*/
- if (TftpBlock == 0) {
+ if (TftpBlock == 0 && TftpLastBlock != 0) {
TftpBlockWrap++;
TftpBlockWrapOffset += TftpBlkSize * TFTP_SEQUENCE_SIZE;
TftpTimeoutCount = 0; /* we've done well, reset thhe timeout */
putc('#');
TftpNumchars++;
}
-#endif
+ puts(" ");
+ print_size(TftpTsize, "");
+#endif
+ time_start = get_timer(time_start);
+ if (time_start > 0) {
+ puts("\n\t "); /* Line up with "Loading: " */
+ print_size(net_boot_file_size /
+ 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 = net_tx_packet + net_eth_hdr_size() + IP_UDP_HDR_SIZE;
switch (TftpState) {
case STATE_SEND_RRQ:
debug("send option \"timeout %s\"\n", (char *)pkt);
pkt += strlen((char *)pkt) + 1;
#ifdef CONFIG_TFTP_TSIZE
- pkt += sprintf((char *)pkt, "tsize%c%lu%c",
- 0, NetBootFileXferSize, 0);
+ pkt += sprintf((char *)pkt, "tsize%c%u%c",
+ 0, net_boot_file_size, 0);
#endif
/* try for more effic. blk size */
pkt += sprintf((char *)pkt, "blksize%c%d%c",
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;
break;
}
- NetSendUDPPacket(NetServerEther, TftpRemoteIP, TftpRemotePort,
- TftpOurPort, len);
+ net_send_udp_packet(net_server_ethaddr, tftp_remote_ip, TftpRemotePort,
+ 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)
+ struct in_addr sip, unsigned src, uchar *pkt,
+ unsigned len)
{
if (type == ICMP_NOT_REACH && code == ICMP_NOT_REACH_PORT) {
/* Oh dear the other end has gone away */
}
#endif
-static void
-TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
- unsigned len)
+static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr 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)) {
#ifdef CONFIG_CMD_TFTPSRV
case TFTP_WRQ:
debug("Got WRQ\n");
- TftpRemoteIP = sip;
+ tftp_remote_ip = sip;
TftpRemotePort = src;
TftpOurPort = 1024 + (get_timer(0) % 3072);
new_transfer();
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:
debug("TFTP blocksize = %i, timeout = %ld ms\n",
TftpBlkSizeOption, TftpTimeoutMSecs);
- TftpRemoteIP = NetServerIP;
- if (BootFile[0] == '\0') {
+ tftp_remote_ip = net_server_ip;
+ if (net_boot_file_name[0] == '\0') {
sprintf(default_filename, "%02X%02X%02X%02X.img",
- NetOurIP & 0xFF,
- (NetOurIP >> 8) & 0xFF,
- (NetOurIP >> 16) & 0xFF,
- (NetOurIP >> 24) & 0xFF);
+ net_ip.s_addr & 0xFF,
+ (net_ip.s_addr >> 8) & 0xFF,
+ (net_ip.s_addr >> 16) & 0xFF,
+ (net_ip.s_addr >> 24) & 0xFF);
strncpy(tftp_filename, default_filename, MAX_LEN);
tftp_filename[MAX_LEN-1] = 0;
printf("*** Warning: no boot file name; using '%s'\n",
tftp_filename);
} else {
- char *p = strchr(BootFile, ':');
+ char *p = strchr(net_boot_file_name, ':');
if (p == NULL) {
- strncpy(tftp_filename, BootFile, MAX_LEN);
+ strncpy(tftp_filename, net_boot_file_name, MAX_LEN);
tftp_filename[MAX_LEN-1] = 0;
} else {
- TftpRemoteIP = string_to_ip(BootFile);
+ tftp_remote_ip = string_to_ip(net_boot_file_name);
strncpy(tftp_filename, p + 1, MAX_LEN);
tftp_filename[MAX_LEN-1] = 0;
}
#else
"from",
#endif
- &TftpRemoteIP, &NetOurIP);
+ &tftp_remote_ip, &net_ip);
/* Check if we need to send across this subnet */
- if (NetOurGatewayIP && NetOurSubnetMask) {
- IPaddr_t OurNet = NetOurIP & NetOurSubnetMask;
- IPaddr_t RemoteNet = TftpRemoteIP & NetOurSubnetMask;
-
- if (OurNet != RemoteNet)
- printf("; sending through gateway %pI4",
- &NetOurGatewayIP);
+ if (net_gateway.s_addr && net_netmask.s_addr) {
+ struct in_addr our_net;
+ struct in_addr remote_net;
+
+ our_net.s_addr = net_ip.s_addr & net_netmask.s_addr;
+ remote_net.s_addr = tftp_remote_ip.s_addr & net_netmask.s_addr;
+ if (our_net.s_addr != remote_net.s_addr)
+ printf("; sending through gateway %pI4", &net_gateway);
}
putc('\n');
printf("Filename '%s'.", tftp_filename);
- if (NetBootFileSize) {
- printf(" Size is 0x%x Bytes = ", NetBootFileSize<<9);
- print_size(NetBootFileSize<<9, "");
+ if (net_boot_file_expected_size_in_blocks) {
+ printf(" Size is 0x%x Bytes = ",
+ net_boot_file_expected_size_in_blocks << 9);
+ print_size(net_boot_file_expected_size_in_blocks << 9, "");
}
putc('\n');
if (TftpWriting) {
printf("Save address: 0x%lx\n", save_addr);
printf("Save size: 0x%lx\n", save_size);
- NetBootFileXferSize = save_size;
+ net_boot_file_size = save_size;
puts("Saving: *\b");
TftpState = STATE_SEND_WRQ;
new_transfer();
TftpState = STATE_SEND_RRQ;
}
+ time_start = get_timer(0);
TftpTimeoutCountMax = TftpRRQTimeoutCountMax;
NetSetTimeout(TftpTimeoutMSecs, TftpTimeout);
- NetSetHandler(TftpHandler);
+ net_set_udp_handler(tftp_handler);
#ifdef CONFIG_CMD_TFTPPUT
net_set_icmp_handler(icmp_handler);
#endif
TftpBlock = 0;
/* zero out server ether in case the server ip has changed */
- memset(NetServerEther, 0, 6);
+ memset(net_server_ethaddr, 0, 6);
/* Revert TftpBlkSize to dflt */
TftpBlkSize = TFTP_BLOCK_SIZE;
#ifdef CONFIG_MCAST_TFTP
tftp_filename[0] = 0;
printf("Using %s device\n", eth_get_name());
- printf("Listening for TFTP transfer on %pI4\n", &NetOurIP);
+ printf("Listening for TFTP transfer on %pI4\n", &net_ip);
printf("Load address: 0x%lx\n", load_addr);
puts("Loading: *\b");
#endif
TftpState = STATE_RECV_WRQ;
- NetSetHandler(TftpHandler);
+ net_set_udp_handler(tftp_handler);
+
+ /* zero out server ether in case the server ip has changed */
+ memset(net_server_ethaddr, 0, 6);
}
#endif /* CONFIG_CMD_TFTPSRV */
static void parse_multicast_oack(char *pkt, int len)
{
int i;
- IPaddr_t addr;
+ struct in_addr addr;
char *mc_adr, *port, *mc;
mc_adr = port = mc = NULL;
Multicast = 1;
}
addr = string_to_ip(mc_adr);
- if (Mcast_addr != addr) {
- if (Mcast_addr)
- eth_mcast_join(Mcast_addr, 0);
- Mcast_addr = addr;
- if (eth_mcast_join(Mcast_addr, 1)) {
+ if (net_mcast_addr.s_addr != addr.s_addr) {
+ if (net_mcast_addr.s_addr)
+ eth_mcast_join(net_mcast_addr, 0);
+ net_mcast_addr = addr;
+ if (eth_mcast_join(net_mcast_addr, 1)) {
printf("Fail to set mcast, revert to TFTP\n");
ProhibitMcast = 1;
mcast_cleanup();