+static void show_block_marker(void)
+{
+#ifdef CONFIG_TFTP_TSIZE
+ if (tftp_tsize) {
+ ulong pos = tftp_cur_block * tftp_block_size +
+ tftp_block_wrap_offset;
+
+ while (tftp_tsize_num_hash < pos * 50 / tftp_tsize) {
+ putc('#');
+ tftp_tsize_num_hash++;
+ }
+ } else
+#endif
+ {
+ if (((tftp_cur_block - 1) % 10) == 0)
+ putc('#');
+ else if ((tftp_cur_block % (10 * HASHES_PER_LINE)) == 0)
+ puts("\n\t ");
+ }
+}
+
+/**
+ * restart the current transfer due to an error
+ *
+ * @param msg Message to print for user
+ */
+static void restart(const char *msg)
+{
+ printf("\n%s; starting again\n", msg);
+#ifdef CONFIG_MCAST_TFTP
+ mcast_cleanup();
+#endif
+ net_start_again();
+}
+
+/*
+ * Check if the block number has wrapped, and update progress
+ *
+ * TODO: The egregious use of global variables in this file should be tidied.
+ */
+static void update_block_number(void)
+{
+ /*
+ * RFC1350 specifies that the first data packet will
+ * have sequence number 1. If we receive a sequence
+ * number of 0 this means that there was a wrap
+ * around of the (16 bit) counter.
+ */
+ if (tftp_cur_block == 0 && tftp_prev_block != 0) {
+ tftp_block_wrap++;
+ tftp_block_wrap_offset += tftp_block_size * TFTP_SEQUENCE_SIZE;
+ timeout_count = 0; /* we've done well, reset the timeout */
+ } else {
+ show_block_marker();
+ }
+}
+
+/* The TFTP get or put is complete */
+static void tftp_complete(void)
+{
+#ifdef CONFIG_TFTP_TSIZE
+ /* Print hash marks for the last packet received */
+ while (tftp_tsize && tftp_tsize_num_hash < 49) {
+ putc('#');
+ tftp_tsize_num_hash++;
+ }
+ puts(" ");
+ print_size(tftp_tsize, "");
+#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");
+ net_set_state(NETLOOP_SUCCESS);
+}
+
+static void tftp_send(void)