X-Git-Url: https://git.karo-electronics.de/?a=blobdiff_plain;f=net%2Ftftp.c;h=bafc35458ef876697e0bbe267b94500c00ca7c76;hb=d1f6052e6af18fc9c90a8bdaa4b5f8d916fdab35;hp=bc7fe05465cb9b4c3b0a1e8a1d45264862be7fae;hpb=2ab5be7af009b4a40efe2fa5471497c97e70ed28;p=karo-tx-uboot.git diff --git a/net/tftp.c b/net/tftp.c index bc7fe05465..bafc35458e 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -8,6 +8,7 @@ #include #include +#include #include #include "tftp.h" #include "bootp.h" @@ -40,6 +41,7 @@ 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 @@ -63,7 +65,7 @@ enum { 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 */ @@ -144,19 +146,21 @@ static void parse_multicast_oack(char *pkt, int len); 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) +store_block(int block, uchar *src, unsigned len) { ulong offset = block * TftpBlkSize + TftpBlockWrapOffset; ulong newsize = offset + len; @@ -177,21 +181,24 @@ store_block(unsigned block, uchar *src, unsigned 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 #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 */ @@ -220,7 +227,7 @@ static int load_block(unsigned block, uchar *dst, unsigned len) 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); @@ -280,7 +287,7 @@ static void update_block_number(void) * 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 */ @@ -298,9 +305,17 @@ static void tftp_complete(void) 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 @@ -322,7 +337,7 @@ TftpSend(void) * 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: @@ -346,8 +361,8 @@ TftpSend(void) 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", @@ -420,13 +435,14 @@ TftpSend(void) break; } - NetSendUDPPacket(NetServerEther, TftpRemoteIP, TftpRemotePort, + NetSendUDPPacket(NetServerEther, 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 */ @@ -435,12 +451,11 @@ static void icmp_handler(unsigned type, unsigned code, unsigned dest, } #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) { @@ -458,7 +473,7 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, 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)) { @@ -494,7 +509,7 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, #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(); @@ -549,7 +564,7 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, if (len < 2) return; len -= 2; - TftpBlock = ntohs(*(ushort *)pkt); + TftpBlock = ntohs(*(__be16 *)pkt); update_block_number(); @@ -627,7 +642,7 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, if (MasterClient && (TftpBlock >= TftpEndingBlock)) { puts("\nMulticast tftp done\n"); mcast_cleanup(); - NetState = NETLOOP_SUCCESS; + net_set_state(NETLOOP_SUCCESS); } } else #endif @@ -637,14 +652,14 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, 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: @@ -704,13 +719,13 @@ void TftpStart(enum proto_t protocol) 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; @@ -718,13 +733,13 @@ void TftpStart(enum proto_t protocol) 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; } @@ -737,24 +752,26 @@ void TftpStart(enum proto_t protocol) #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'); @@ -763,7 +780,7 @@ void TftpStart(enum proto_t protocol) 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(); @@ -775,10 +792,11 @@ void TftpStart(enum proto_t protocol) 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 @@ -819,7 +837,7 @@ TftpStartServer(void) 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"); @@ -840,7 +858,10 @@ TftpStartServer(void) #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(NetServerEther, 0, 6); } #endif /* CONFIG_CMD_TFTPSRV */ @@ -863,7 +884,7 @@ TftpStartServer(void) 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; @@ -918,11 +939,11 @@ static void parse_multicast_oack(char *pkt, int len) 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();