diff --git a/CHANGELOG b/CHANGELOG
index 4a5e5616437dad6e6caf46f65d079d8af0630bbd..3a9d22ab5a63d46935f03a48b4c9c47f324148f9 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,14 @@
 Changes for U-Boot 1.0.0:
 ======================================================================
 
+* Make fatload set filesize environment variable
+
+* enable basic / medium / high-end configurations for PPChameleonEVB
+  board; fix NAND code
+
+* enable TFTP client code to specify to the server the desired
+  timeout value (see RFC-2349)
+
 * Improve SDRAM setup for TRAB board
 
 * Suppress all output with splashscreen configured only if "splashimage"
diff --git a/Makefile b/Makefile
index 1719cc544da8f98cbad5216c14666b9c762e9656..80dc424d72ed4182aeb264c728b41f10774dc54d 100644
--- a/Makefile
+++ b/Makefile
@@ -478,6 +478,7 @@ wtk_config:	unconfig
 #########################################################################
 ## PPC4xx Systems
 #########################################################################
+xtract_4xx = $(subst _MODEL_BA,,$(subst _MODEL_ME,,$(subst _MODEL_HI,,$(subst _config,,$1))))
 
 ADCIOP_config:	unconfig
 	@./mkconfig $(@:_config=) ppc ppc4xx adciop esd
@@ -557,8 +558,24 @@ PLU405_config:	unconfig
 PMC405_config:	unconfig
 	@./mkconfig $(@:_config=) ppc ppc4xx pmc405 esd
 
+PPChameleonEVB_MODEL_BA_config	\
+PPChameleonEVB_MODEL_ME_config	\
+PPChameleonEVB_MODEL_HI_config	\
 PPChameleonEVB_config:	unconfig
-	@./mkconfig $(@:_config=) ppc ppc4xx PPChameleonEVB dave
+	@ >include/config.h
+	@[ -z "$(findstring _MODEL_BA,$@)" ] || \
+		{ echo "#define CONFIG_PPCHAMELEON_MODULE_MODEL 0" >>include/config.h ; \
+		  echo "... BASIC model" ; \
+		}
+	@[ -z "$(findstring _MODEL_ME,$@)" ] || \
+		{ echo "#define CONFIG_PPCHAMELEON_MODULE_MODEL 1" >>include/config.h ; \
+		  echo "... MEDIUM model" ; \
+		}
+	@[ -z "$(findstring _MODEL_HI,$@)" ] || \
+		{ echo "#define CONFIG_PPCHAMELEON_MODULE_MODEL 2" >>include/config.h ; \
+		  echo "... HIGH-END model" ; \
+		}
+	@./mkconfig -a $(call xtract_4xx,$@) ppc ppc4xx PPChameleonEVB dave
 
 VOH405_config:	unconfig
 	@./mkconfig $(@:_config=) ppc ppc4xx voh405 esd
diff --git a/board/dave/PPChameleonEVB/PPChameleonEVB.c b/board/dave/PPChameleonEVB/PPChameleonEVB.c
index 47670fa21bf195c1b99ba2b4c0fd86a4c02ce841..811f6f8d4b57e7bb3541081102c3e4b5cb3b0273 100644
--- a/board/dave/PPChameleonEVB/PPChameleonEVB.c
+++ b/board/dave/PPChameleonEVB/PPChameleonEVB.c
@@ -261,10 +261,13 @@ nand_probe(ulong physadr);
 void
 nand_init(void)
 {
-	ulong totlen;
+	ulong totlen = 0;
 
+#if (CONFIG_PPCHAMELEON_MODULE_MODEL == CONFIG_PPCHAMELEON_MODULE_ME) || \
+    (CONFIG_PPCHAMELEON_MODULE_MODEL == CONFIG_PPCHAMELEON_MODULE_HI)
 	debug ("Probing at 0x%.8x\n", CFG_NAND0_BASE);
-	totlen = nand_probe (CFG_NAND0_BASE);
+	totlen += nand_probe (CFG_NAND0_BASE);
+#endif	/* CONFIG_PPCHAMELEON_MODULE_ME, CONFIG_PPCHAMELEON_MODULE_HI */
 
 	debug ("Probing at 0x%.8x\n", CFG_NAND1_BASE);
 	totlen += nand_probe (CFG_NAND1_BASE);
diff --git a/board/trab/auto_update.c b/board/trab/auto_update.c
index c9c61eaabe63a474d892f1fdd2f2995795b345a7..3113cf89ad00858cbdaf826018f7919b835c2f56 100644
--- a/board/trab/auto_update.c
+++ b/board/trab/auto_update.c
@@ -313,9 +313,12 @@ au_do_update(int idx, long sz, int repeat)
 
 	/* execute a script */
 	if (hdr->ih_type == IH_TYPE_SCRIPT) {
-		addr = (char *)((char *)hdr + sizeof(*hdr) + 8);
-		parse_string_outer(addr,
-			FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
+		addr = (char *)((char *)hdr + sizeof(*hdr));
+		/* stick a NULL at the end of the script, otherwise */
+		/* parse_string_outer() runs off the end. */
+		addr[ntohl(hdr->ih_size)] = 0;
+		addr += 8;
+		parse_string_outer(addr, FLAG_PARSE_SEMICOLON);
 		return 0;
 	}
 
@@ -333,8 +336,7 @@ au_do_update(int idx, long sz, int repeat)
 #endif
 		debug ("protect off %lx %lx\n", start, end);
 		sprintf(strbuf, "protect off %lx %lx\n", start, end);
-		parse_string_outer(strbuf,
-			FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
+		parse_string_outer(strbuf, FLAG_PARSE_SEMICOLON);
 	}
 
 	/*
@@ -344,12 +346,11 @@ au_do_update(int idx, long sz, int repeat)
 	if (repeat == 0) {
 		debug ("erase %lx %lx\n", start, end);
 		sprintf(strbuf, "erase %lx %lx\n", start, end);
-		parse_string_outer(strbuf,
-			FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
+		parse_string_outer(strbuf, FLAG_PARSE_SEMICOLON);
 	}
 	wait_ms(100);
-	/* strip the header - except for the kernel */
-	if (idx == IDX_FIRMWARE || idx == IDX_DISK || idx == IDX_APP) {
+	/* strip the header - except for the kernel and app */
+	if (idx == IDX_FIRMWARE || idx == IDX_DISK) {
 		addr = (char *)((char *)hdr + sizeof(*hdr));
 #ifdef AU_UPDATE_TEST
 		/* copy it to where Linux goes */
@@ -367,8 +368,7 @@ au_do_update(int idx, long sz, int repeat)
 	/* copy the data from RAM to FLASH */
 	debug ("cp.b %p %lx %x\n", addr, start, nbytes);
 	sprintf(strbuf, "cp.b %p %lx %x\n", addr, start, nbytes);
-	parse_string_outer(strbuf,
-		FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
+	parse_string_outer(strbuf, FLAG_PARSE_SEMICOLON);
 
 	/* check the dcrc of the copy */
 	if (crc32 (0, (char *)(start + off), ntohl(hdr->ih_size)) != ntohl(hdr->ih_dcrc)) {
@@ -381,8 +381,7 @@ au_do_update(int idx, long sz, int repeat)
 	if (idx == IDX_FIRMWARE) {
 		debug ("protect on %lx %lx\n", start, end);
 		sprintf(strbuf, "protect on %lx %lx\n", start, end);
-		parse_string_outer(strbuf,
-			FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
+		parse_string_outer(strbuf, FLAG_PARSE_SEMICOLON);
 	}
 	return 0;
 }
@@ -493,8 +492,11 @@ do_auto_update(void)
 	env = getenv("firmware_nd");
 	if (env != NULL)
 		end = simple_strtoul(env, NULL, 16);
-	if (start >= 0 && end && end > start)
+	if (start >= 0 && end && end > start) {
 		ausize[IDX_FIRMWARE] = (end + 1) - start;
+		aufl_layout[0].start = start;
+		aufl_layout[0].end = end;
+	}
 	start = -1;
 	end = 0;
 	env = getenv("kernel_st");
@@ -503,8 +505,11 @@ do_auto_update(void)
 	env = getenv("kernel_nd");
 	if (env != NULL)
 		end = simple_strtoul(env, NULL, 16);
-	if (start >= 0 && end && end > start)
+	if (start >= 0 && end && end > start) {
 		ausize[IDX_KERNEL] = (end + 1) - start;
+		aufl_layout[1].start = start;
+		aufl_layout[1].end = end;
+	}
 	start = -1;
 	end = 0;
 	env = getenv("app_st");
@@ -513,8 +518,11 @@ do_auto_update(void)
 	env = getenv("app_nd");
 	if (env != NULL)
 		end = simple_strtoul(env, NULL, 16);
-	if (start >= 0 && end && end > start)
+	if (start >= 0 && end && end > start) {
 		ausize[IDX_APP] = (end + 1) - start;
+		aufl_layout[2].start = start;
+		aufl_layout[2].end = end;
+	}
 	start = -1;
 	end = 0;
 	env = getenv("disk_st");
@@ -523,8 +531,11 @@ do_auto_update(void)
 	env = getenv("disk_nd");
 	if (env != NULL)
 		end = simple_strtoul(env, NULL, 16);
-	if (start >= 0 && end && end > start)
+	if (start >= 0 && end && end > start) {
 		ausize[IDX_DISK] = (end + 1) - start;
+		aufl_layout[3].start = start;
+		aufl_layout[3].end = end;
+	}
 	/* make sure that we see CTRL-C and save the old state */
 	old_ctrlc = disable_ctrlc(0);
 
diff --git a/common/cmd_fat.c b/common/cmd_fat.c
index 2a1da95b819ff397a2c51a69cecaaad1e19a165d..c5b3f06fe8a4f2d575d3e3b6f050c7536ccfabb9 100644
--- a/common/cmd_fat.c
+++ b/common/cmd_fat.c
@@ -74,6 +74,7 @@ int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	long size;
 	unsigned long offset;
 	unsigned long count;
+	char buf [12];
 	block_dev_desc_t *dev_desc=NULL;
 	int dev=0;
 	int part=1;
@@ -107,11 +108,15 @@ int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 		count = 0;
 	size = file_fat_read (argv[4], (unsigned char *) offset, count);
 
-	if(size==-1)
+	if(size==-1) {
 		printf("\n** Unable to read \"%s\" from %s %d:%d **\n",argv[4],argv[1],dev,part);
-	else
+	} else {
 		printf ("\n%ld bytes read\n", size);
 
+		sprintf(buf, "%lX", size);
+		setenv("filesize", buf);
+	}
+
 	return size;
 }
 
diff --git a/common/cmd_fdos.c b/common/cmd_fdos.c
index adaddcd4ff7cbd5205a3b5a0587b650c144ec35e..dc02b3595c2a64035faf7021e7a3013b459c87ee 100644
--- a/common/cmd_fdos.c
+++ b/common/cmd_fdos.c
@@ -43,7 +43,7 @@ int do_fdosboot(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
     char *ep;
     int size;
     int rcode = 0;
-    char buf [10];
+    char buf [12];
     int drive = CFG_FDC_DRIVE_NUMBER;
 
     /* pre-set load_addr */
diff --git a/include/configs/PPChameleonEVB.h b/include/configs/PPChameleonEVB.h
index 7c7b98ceb46793adf026123ae0c6ef3e8a31b27f..1630bc32b1932a3942e4ad9e3688b856dcb1841b 100644
--- a/include/configs/PPChameleonEVB.h
+++ b/include/configs/PPChameleonEVB.h
@@ -1,9 +1,12 @@
 /*
- * (C) Copyright 2001-2003
- * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
+ * (C) Copyright 2003
+ * DAVE Srl
  *
- * See file CREDITS for list of people who contributed to this
- * project.
+ * http://www.dave-tech.it
+ * http://www.wawnet.biz
+ * mailto:info@wawnet.biz
+ *
+ * Credits: Stefan Roese, Wolfgang Denk
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -28,6 +31,13 @@
 #ifndef __CONFIG_H
 #define __CONFIG_H
 
+#define CONFIG_PPCHAMELEON_MODULE_BA	0	/* Basic    Model */	
+#define CONFIG_PPCHAMELEON_MODULE_ME	1	/* Medium   Model */
+#define CONFIG_PPCHAMELEON_MODULE_HI	2	/* High-End Model */
+#ifndef	CONFIG_PPCHAMELEON_MODULE_MODEL
+#define	CONFIG_PPCHAMELEON_MODULE_MODEL	CONFIG_PPCHAMELEON_MODULE_BA
+#endif
+
 /*
  * Debug stuff
  */
@@ -150,6 +160,7 @@
 
 #define CFG_MAX_NAND_DEVICE	2	/* Max number of NAND devices		*/
 #define SECTORSIZE 512
+#define NAND_NO_RB
 
 #define ADDR_COLUMN 1
 #define ADDR_PAGE 2
@@ -248,19 +259,15 @@
         } \
 } while(0)
 
+#ifdef NAND_NO_RB
+/* constant delay (see also tR in the datasheet) */
 #define NAND_WAIT_READY(nand) do { \
-	ulong mask = 0; \
-	switch ((ulong)(((struct nand_chip *)nand)->IO_ADDR)) { \
-	case CFG_NAND0_BASE: \
-		mask = CFG_NAND0_RDY; \
-		break; \
-	case CFG_NAND1_BASE: \
-		mask = CFG_NAND1_RDY; \
-		break; \
-	} \
-	while (!(in32(GPIO0_IR) & mask)) \
-		; \
+	udelay(12); \
 } while (0)
+#else
+/* use the R/B pin */
+/* TBD */
+#endif
 
 #define WRITE_NAND_COMMAND(d, adr) do{ *(volatile __u8 *)((unsigned long)adr) = (__u8)(d); } while(0)
 #define WRITE_NAND_ADDRESS(d, adr) do{ *(volatile __u8 *)((unsigned long)adr) = (__u8)(d); } while(0)
diff --git a/include/image.h b/include/image.h
index b93d1041f9fffbf105f43d2defcf0eb7513128cc..9c6f95b054c224124e4e22b87e55ddeddb3ee4b3 100644
--- a/include/image.h
+++ b/include/image.h
@@ -112,6 +112,7 @@
 #define IH_TYPE_MULTI		4	/* Multi-File Image		*/
 #define IH_TYPE_FIRMWARE	5	/* Firmware Image		*/
 #define IH_TYPE_SCRIPT		6	/* Script file			*/
+#define IH_TYPE_FILESYSTEM	7	/* Filesystem Image (any type)	*/
 
 /*
  * Compression Types
diff --git a/net/tftp.c b/net/tftp.c
index 1154cb9120b97acf462b3dc1b6a455fe66542829..049df6830a0f79f6021aa2ee5b559cfc12f01faa 100644
--- a/net/tftp.c
+++ b/net/tftp.c
@@ -15,7 +15,7 @@
 #if (CONFIG_COMMANDS & CFG_CMD_NET)
 
 #define WELL_KNOWN_PORT	69		/* Well known TFTP port #		*/
-#define TIMEOUT		2		/* Seconds to timeout for a lost pkt	*/
+#define TIMEOUT		5		/* Seconds to timeout for a lost pkt	*/
 #ifndef	CONFIG_NET_RETRY_COUNT
 # define TIMEOUT_COUNT	10		/* # of timeouts before giving up  */
 #else
@@ -32,6 +32,7 @@
 #define TFTP_DATA	3
 #define TFTP_ACK	4
 #define TFTP_ERROR	5
+#define TFTP_OACK	6
 
 
 static int	TftpServerPort;		/* The UDP port at their end		*/
@@ -44,6 +45,7 @@ static int	TftpState;
 #define STATE_DATA	2
 #define STATE_TOO_LARGE	3
 #define STATE_BAD_MAGIC	4
+#define STATE_OACK	5
 
 #define DEFAULT_NAME_LEN	(8 + 4 + 1)
 static char default_filename[DEFAULT_NAME_LEN];
@@ -113,10 +115,18 @@ TftpSend (void)
 		pkt += strlen(tftp_filename) + 1;
 		strcpy ((char *)pkt, "octet");
 		pkt += 5 /*strlen("octet")*/ + 1;
+		strcpy ((char *)pkt, "timeout");
+		pkt += 7 /*strlen("timeout")*/ + 1;
+		sprintf((char *)pkt, "%d", TIMEOUT);
+#ifdef ET_DEBUG
+		printf("send option \"timeout %s\"\n", (char *)pkt);
+#endif
+		pkt += strlen((char *)pkt) + 1;
 		len = pkt - xp;
 		break;
 
 	case STATE_DATA:
+	case STATE_OACK:
 		xp = pkt;
 		*((ushort *)pkt)++ = htons(TFTP_ACK);
 		*((ushort *)pkt)++ = htons(TftpBlock);
@@ -173,6 +183,14 @@ TftpHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len)
 	default:
 		break;
 
+	case TFTP_OACK:
+#ifdef ET_DEBUG
+		printf("Got OACK: %s %s\n", pkt, pkt+strlen(pkt)+1);
+#endif
+		TftpState = STATE_OACK;
+		TftpServerPort = src;
+		TftpSend (); /* Send ACK */
+		break;
 	case TFTP_DATA:
 		if (len < 2)
 			return;
@@ -184,7 +202,13 @@ TftpHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len)
 			puts ("\n\t ");
 		}
 
+#ifdef ET_DEBUG
 		if (TftpState == STATE_RRQ) {
+			printf("Server did not acknowledge timeout option!\n");
+		}
+#endif
+
+		if (TftpState == STATE_RRQ || TftpState == STATE_OACK) {
 			TftpState = STATE_DATA;
 			TftpServerPort = src;
 			TftpLastBlock = 0;
@@ -305,6 +329,7 @@ TftpStart (void)
 	TftpTimeoutCount = 0;
 	TftpState = STATE_RRQ;
 	TftpOurPort = 1024 + (get_timer(0) % 3072);
+	TftpBlock = 0;
 
 	/* zero out server ether in case the server ip has changed */
 	memset(NetServerEther, 0, 6);