* Patches by Pantelis Antoniou, 30 Mar 2004:
  - add auto-complete support to the U-Boot CLI
  - add support for NETTA and NETPHONE boards; fix NETVIA board

* Patch by Yuli Barcohen, 28 Mar 2004:
  - Add support for MPC8272 family including MPC8247/8248/8271/8272
  - Add support for MPC8272ADS evaluation board (another flavour of MPC8260ADS)
  - Change configuration method for MPC8260ADS family
diff --git a/common/cmd_pcmcia.c b/common/cmd_pcmcia.c
index 963f98f..b7e57bf 100644
--- a/common/cmd_pcmcia.c
+++ b/common/cmd_pcmcia.c
@@ -2607,6 +2607,370 @@
 #endif	/* CONFIG_IDE_8xx_PCCARD */
 
 /* -------------------------------------------------------------------- */
+/* NETTA board by Intracom S.A.						*/
+/* -------------------------------------------------------------------- */
+
+#if defined(CONFIG_NETTA)
+
+/* some sane bit macros */
+#define _BD(_b)				(1U << (31-(_b)))
+#define _BDR(_l, _h)			(((((1U << (31-(_l))) - 1) << 1) | 1) & ~((1U << (31-(_h))) - 1))
+
+#define _BW(_b)				(1U << (15-(_b)))
+#define _BWR(_l, _h)			(((((1U << (15-(_l))) - 1) << 1) | 1) & ~((1U << (15-(_h))) - 1))
+
+#define _BB(_b)				(1U << (7-(_b)))
+#define _BBR(_l, _h)			(((((1U << (7-(_l))) - 1) << 1) | 1) & ~((1U << (7-(_h))) - 1))
+
+#define _B(_b)				_BD(_b)
+#define _BR(_l, _h)			_BDR(_l, _h)
+
+#define PCMCIA_BOARD_MSG "NETTA"
+
+static const unsigned short vppd_masks[2] = { _BW(14), _BW(15) };
+
+static void cfg_vppd(int no)
+{
+	volatile immap_t *immap = (immap_t *)CFG_IMMR;
+	unsigned short mask;
+
+	if ((unsigned int)no >= sizeof(vppd_masks)/sizeof(vppd_masks[0]))
+		return;
+
+	mask = vppd_masks[no];
+
+	immap->im_ioport.iop_papar &= ~mask;
+	immap->im_ioport.iop_paodr &= ~mask;
+	immap->im_ioport.iop_padir |=  mask;
+}
+
+static void set_vppd(int no, int what)
+{
+	volatile immap_t *immap = (immap_t *)CFG_IMMR;
+	unsigned short mask;
+
+	if ((unsigned int)no >= sizeof(vppd_masks)/sizeof(vppd_masks[0]))
+		return;
+
+	mask = vppd_masks[no];
+
+	if (what)
+		immap->im_ioport.iop_padat |= mask;
+	else
+		immap->im_ioport.iop_padat &= ~mask;
+}
+
+static const unsigned short vccd_masks[2] = { _BW(10), _BW(6) };
+
+static void cfg_vccd(int no)
+{
+	volatile immap_t *immap = (immap_t *)CFG_IMMR;
+	unsigned short mask;
+
+	if ((unsigned int)no >= sizeof(vccd_masks)/sizeof(vccd_masks[0]))
+		return;
+
+	mask = vccd_masks[no];
+
+	immap->im_ioport.iop_papar &= ~mask;
+	immap->im_ioport.iop_paodr &= ~mask;
+	immap->im_ioport.iop_padir |=  mask;
+}
+
+static void set_vccd(int no, int what)
+{
+	volatile immap_t *immap = (immap_t *)CFG_IMMR;
+	unsigned short mask;
+
+	if ((unsigned int)no >= sizeof(vccd_masks)/sizeof(vccd_masks[0]))
+		return;
+
+	mask = vccd_masks[no];
+
+	if (what)
+		immap->im_ioport.iop_padat |= mask;
+	else
+		immap->im_ioport.iop_padat &= ~mask;
+}
+
+static const unsigned short oc_mask = _BW(8);
+
+static void cfg_oc(void)
+{
+	volatile immap_t *immap = (immap_t *)CFG_IMMR;
+	unsigned short mask = oc_mask;
+
+	immap->im_ioport.iop_pcdir &= ~mask;
+	immap->im_ioport.iop_pcso  &= ~mask;
+	immap->im_ioport.iop_pcint &= ~mask;
+	immap->im_ioport.iop_pcpar &= ~mask;
+}
+
+static int get_oc(void)
+{
+	volatile immap_t *immap = (immap_t *)CFG_IMMR;
+	unsigned short mask = oc_mask;
+	int what;
+
+	what = !!(immap->im_ioport.iop_pcdat & mask);;
+	return what;
+}
+
+static const unsigned short shdn_mask = _BW(12);
+
+static void cfg_shdn(void)
+{
+	volatile immap_t *immap = (immap_t *)CFG_IMMR;
+	unsigned short mask;
+
+	mask = shdn_mask;
+
+	immap->im_ioport.iop_papar &= ~mask;
+	immap->im_ioport.iop_paodr &= ~mask;
+	immap->im_ioport.iop_padir |=  mask;
+}
+
+static void set_shdn(int what)
+{
+	volatile immap_t *immap = (immap_t *)CFG_IMMR;
+	unsigned short mask;
+
+	mask = shdn_mask;
+
+	if (what)
+		immap->im_ioport.iop_padat |= mask;
+	else
+		immap->im_ioport.iop_padat &= ~mask;
+}
+
+static void cfg_ports (void);
+
+static int hardware_enable(int slot)
+{
+	volatile immap_t	*immap;
+	volatile cpm8xx_t	*cp;
+	volatile pcmconf8xx_t	*pcmp;
+	volatile sysconf8xx_t	*sysp;
+	uint reg, pipr, mask;
+	int i;
+
+	debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
+
+	udelay(10000);
+
+	immap = (immap_t *)CFG_IMMR;
+	sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
+	pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
+	cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
+
+	/* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
+	cfg_ports ();
+
+	/* clear interrupt state, and disable interrupts */
+	pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
+	pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
+
+	/*
+	 * Disable interrupts, DMA, and PCMCIA buffers
+	 * (isolate the interface) and assert RESET signal
+	 */
+	debug ("Disable PCMCIA buffers and assert RESET\n");
+	reg  = 0;
+	reg |= __MY_PCMCIA_GCRX_CXRESET;	/* active high */
+	reg |= __MY_PCMCIA_GCRX_CXOE;		/* active low  */
+	PCMCIA_PGCRX(_slot_) = reg;
+
+	udelay(500);
+
+	/*
+	 * Make sure there is a card in the slot, then configure the interface.
+	 */
+	udelay(10000);
+	debug ("[%d] %s: PIPR(%p)=0x%x\n",
+		__LINE__,__FUNCTION__,
+		&(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
+	if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
+		printf ("   No Card found\n");
+		return (1);
+	}
+
+	/*
+	 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
+	 */
+	mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
+	pipr = pcmp->pcmc_pipr;
+	debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
+		pipr,
+		(reg&PCMCIA_VS1(slot))?"n":"ff",
+		(reg&PCMCIA_VS2(slot))?"n":"ff");
+
+	if ((pipr & mask) == mask) {
+		set_vppd(0, 1); set_vppd(1, 1); 		/* VAVPP => Hi-Z */
+		set_vccd(0, 0); set_vccd(1, 1); 		/* 5V on, 3V off */
+		puts (" 5.0V card found: ");
+	} else {
+		set_vppd(0, 1); set_vppd(1, 1); 		/* VAVPP => Hi-Z */
+		set_vccd(0, 1); set_vccd(1, 0); 		/* 5V off, 3V on */
+		puts (" 3.3V card found: ");
+	}
+
+	/*  Wait 500 ms; use this to check for over-current */
+	for (i=0; i<5000; ++i) {
+		if (!get_oc()) {
+			printf ("   *** Overcurrent - Safety shutdown ***\n");
+			set_vccd(0, 0); set_vccd(1, 0); 		/* VAVPP => Hi-Z */
+			return (1);
+		}
+		udelay (100);
+	}
+
+	debug ("Enable PCMCIA buffers and stop RESET\n");
+	reg  =  PCMCIA_PGCRX(_slot_);
+	reg &= ~__MY_PCMCIA_GCRX_CXRESET;	/* active high */
+	reg &= ~__MY_PCMCIA_GCRX_CXOE;		/* active low  */
+	PCMCIA_PGCRX(_slot_) = reg;
+
+	udelay(250000);	/* some cards need >150 ms to come up :-( */
+
+	debug ("# hardware_enable done\n");
+
+	return (0);
+}
+
+
+#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
+static int hardware_disable(int slot)
+{
+	volatile immap_t	*immap;
+	volatile pcmconf8xx_t	*pcmp;
+	u_long reg;
+
+	debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
+
+	immap = (immap_t *)CFG_IMMR;
+	pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
+
+	/* Configure PCMCIA General Control Register */
+	debug ("Disable PCMCIA buffers and assert RESET\n");
+	reg  = 0;
+	reg |= __MY_PCMCIA_GCRX_CXRESET;	/* active high */
+	reg |= __MY_PCMCIA_GCRX_CXOE;		/* active low  */
+	PCMCIA_PGCRX(_slot_) = reg;
+
+	/* All voltages off / Hi-Z */
+			set_vppd(0, 1); set_vppd(1, 1);
+	set_vccd(0, 1); set_vccd(1, 1);
+
+	udelay(10000);
+
+	return (0);
+}
+#endif	/* CFG_CMD_PCMCIA */
+
+
+static int voltage_set(int slot, int vcc, int vpp)
+{
+	volatile immap_t	*immap;
+	volatile cpm8xx_t	*cp;
+	volatile pcmconf8xx_t	*pcmp;
+	u_long reg;
+	ushort sreg;
+
+	debug ("voltage_set: "
+		PCMCIA_BOARD_MSG
+		" Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
+		'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
+
+	immap = (immap_t *)CFG_IMMR;
+	cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
+	pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
+	/*
+	 * Disable PCMCIA buffers (isolate the interface)
+	 * and assert RESET signal
+	 */
+	debug ("Disable PCMCIA buffers and assert RESET\n");
+	reg  = PCMCIA_PGCRX(_slot_);
+	reg |= __MY_PCMCIA_GCRX_CXRESET;	/* active high */
+	reg |= __MY_PCMCIA_GCRX_CXOE;		/* active low  */
+	PCMCIA_PGCRX(_slot_) = reg;
+	udelay(500);
+
+	/*
+	 * Configure Port C pins for
+	 * 5 Volts Enable and 3 Volts enable,
+	 * Turn all power pins to Hi-Z
+	 */
+	debug ("PCMCIA power OFF\n");
+	cfg_ports ();	/* Enables switch, but all in Hi-Z */
+
+	sreg  = immap->im_ioport.iop_pcdat;
+	set_vppd(0, 1); set_vppd(1, 1);
+
+	switch(vcc) {
+	case  0:
+		break;	/* Switch off		*/
+
+	case 33:
+		set_vccd(0, 1); set_vccd(1, 0);
+		break;
+
+	case 50:
+		set_vccd(0, 0); set_vccd(1, 1);
+		break;
+
+	default:
+		goto done;
+	}
+
+	/* Checking supported voltages */
+
+	debug ("PIPR: 0x%x --> %s\n",
+		pcmp->pcmc_pipr,
+		(pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
+
+done:
+	debug ("Enable PCMCIA buffers and stop RESET\n");
+	reg  =  PCMCIA_PGCRX(_slot_);
+	reg &= ~__MY_PCMCIA_GCRX_CXRESET;	/* active high */
+	reg &= ~__MY_PCMCIA_GCRX_CXOE;		/* active low  */
+	PCMCIA_PGCRX(_slot_) = reg;
+	udelay(500);
+
+	debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
+		slot+'A');
+	return (0);
+}
+
+static void cfg_ports (void)
+{
+	volatile immap_t	*immap;
+	volatile cpm8xx_t	*cp;
+
+	immap = (immap_t *)CFG_IMMR;
+	cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
+
+
+	cfg_vppd(0); cfg_vppd(1);	/* VPPD0,VPPD1 VAVPP => Hi-Z */
+	cfg_vccd(0); cfg_vccd(1);	/* 3V and 5V off */
+	cfg_shdn();
+	cfg_oc();
+
+	/*
+	 * Configure Port A for TPS2211 PC-Card Power-Interface Switch
+	 *
+	 * Switch off all voltages, assert shutdown
+	 */
+	set_vppd(0, 1); set_vppd(1, 1);
+	set_vccd(0, 0); set_vccd(1, 0);
+	set_shdn(1);
+
+	udelay(100000);
+}
+
+#endif	/* NETTA */
+
+
+/* -------------------------------------------------------------------- */
 
 #endif /* CFG_CMD_PCMCIA || (CFG_CMD_IDE && CONFIG_IDE_8xx_PCCARD) */
 
diff --git a/common/command.c b/common/command.c
index dfec9c1..df5d3e9 100644
--- a/common/command.c
+++ b/common/command.c
@@ -217,3 +217,285 @@
 
 	return NULL;	/* not found or ambiguous command */
 }
+
+#ifdef CONFIG_AUTO_COMPLETE
+
+int var_complete(int argc, char *argv[], char last_char, int maxv, char *cmdv[])
+{
+	static char tmp_buf[512];
+	int space;
+
+	space = last_char == '\0' || last_char == ' ' || last_char == '\t';
+
+	if (space && argc == 1)
+		return env_complete("", maxv, cmdv, sizeof(tmp_buf), tmp_buf);
+
+	if (!space && argc == 2)
+		return env_complete(argv[1], maxv, cmdv, sizeof(tmp_buf), tmp_buf);
+
+	return 0;
+}
+
+static void install_auto_complete_handler(const char *cmd,
+		int (*complete)(int argc, char *argv[], char last_char, int maxv, char *cmdv[]))
+{
+	cmd_tbl_t *cmdtp;
+
+	cmdtp = find_cmd(cmd);
+	if (cmdtp == NULL)
+		return;
+
+	cmdtp->complete = complete;
+}
+
+void install_auto_complete(void)
+{
+	install_auto_complete_handler("printenv", var_complete);
+	install_auto_complete_handler("setenv", var_complete);
+#if (CONFIG_COMMANDS & CFG_CMD_RUN)
+	install_auto_complete_handler("run", var_complete);
+#endif
+}
+
+/*************************************************************************************/
+
+static int complete_cmdv(int argc, char *argv[], char last_char, int maxv, char *cmdv[])
+{
+	cmd_tbl_t *cmdtp;
+	const char *p;
+	int len, clen;
+	int n_found = 0;
+	const char *cmd;
+
+	/* sanity? */
+	if (maxv < 2)
+		return -2;
+
+	cmdv[0] = NULL;
+
+	if (argc == 0) {
+		/* output full list of commands */
+		for (cmdtp = &__u_boot_cmd_start; cmdtp != &__u_boot_cmd_end; cmdtp++) {
+			if (n_found >= maxv - 2) {
+				cmdv[n_found++] = "...";
+				break;
+			}
+			cmdv[n_found++] = cmdtp->name;
+		}
+		cmdv[n_found] = NULL;
+		return n_found;
+	}
+
+	/* more than one arg or one but the start of the next */
+	if (argc > 1 || (last_char == '\0' || last_char == ' ' || last_char == '\t')) {
+		cmdtp = find_cmd(argv[0]);
+		if (cmdtp == NULL || cmdtp->complete == NULL) {
+			cmdv[0] = NULL;
+			return 0;
+		}
+		return (*cmdtp->complete)(argc, argv, last_char, maxv, cmdv);
+	}
+
+	cmd = argv[0];
+	/*
+	 * Some commands allow length modifiers (like "cp.b");
+	 * compare command name only until first dot.
+	 */
+	p = strchr(cmd, '.');
+	if (p == NULL)
+		len = strlen(cmd);
+	else
+		len = p - cmd;
+
+	/* return the partial matches */
+	for (cmdtp = &__u_boot_cmd_start; cmdtp != &__u_boot_cmd_end; cmdtp++) {
+
+		clen = strlen(cmdtp->name);
+		if (clen < len)
+			continue;
+
+		if (memcmp(cmd, cmdtp->name, len) != 0)
+			continue;
+
+		/* too many! */
+		if (n_found >= maxv - 2) {
+			cmdv[n_found++] = "...";
+			break;
+		}
+
+		cmdv[n_found++] = cmdtp->name;
+	}
+
+	cmdv[n_found] = NULL;
+	return n_found;
+}
+
+static int make_argv(char *s, int argvsz, char *argv[])
+{
+	int argc = 0;
+
+	/* split into argv */
+	while (argc < argvsz - 1) {
+
+		/* skip any white space */
+		while ((*s == ' ') || (*s == '\t'))
+			++s;
+
+		if (*s == '\0') 	/* end of s, no more args	*/
+			break;
+
+		argv[argc++] = s;	/* begin of argument string	*/
+
+		/* find end of string */
+		while (*s && (*s != ' ') && (*s != '\t'))
+			++s;
+
+		if (*s == '\0')		/* end of s, no more args	*/
+			break;
+
+		*s++ = '\0';		/* terminate current arg	 */
+	}
+	argv[argc] = NULL;
+
+	return argc;
+}
+
+static void print_argv(const char *banner, const char *leader, const char *sep, int linemax, char *argv[])
+{
+	int ll = leader != NULL ? strlen(leader) : 0;
+	int sl = sep != NULL ? strlen(sep) : 0;
+	int len, i;
+
+	if (banner) {
+		puts("\n");
+		puts(banner);
+	}
+
+	i = linemax;	/* force leader and newline */
+	while (*argv != NULL) {
+		len = strlen(*argv) + sl;
+		if (i + len >= linemax) {
+			puts("\n");
+			if (leader)
+				puts(leader);
+			i = ll - sl;
+		} else if (sep)
+			puts(sep);
+		puts(*argv++);
+		i += len;
+	}
+	printf("\n");
+}
+
+static int find_common_prefix(char *argv[])
+{
+	int i, len;
+	char *anchor, *s, *t;
+
+	if (*argv == NULL)
+		return 0;
+
+	/* begin with max */
+	anchor = *argv++;
+	len = strlen(anchor);
+	while ((t = *argv++) != NULL) {
+		s = anchor;
+		for (i = 0; i < len; i++, t++, s++) {
+			if (*t != *s)
+				break;
+		}
+		len = s - anchor;
+	}
+	return len;
+}
+
+static char tmp_buf[CFG_CBSIZE];	/* copy of console I/O buffer	*/
+
+int cmd_auto_complete(const char *const prompt, char *buf, int *np, int *colp)
+{
+	int n = *np, col = *colp;
+	char *argv[CFG_MAXARGS + 1];		/* NULL terminated	*/
+	char *cmdv[20];
+	char *s, *t;
+	const char *sep;
+	int i, j, k, len, seplen, argc;
+	int cnt;
+	char last_char;
+
+	if (strcmp(prompt, CFG_PROMPT) != 0)
+		return 0;	/* not in normal console */
+
+	cnt = strlen(buf);
+	if (cnt >= 1)
+		last_char = buf[cnt - 1];
+	else
+		last_char = '\0';
+
+	/* copy to secondary buffer which will be affected */
+	strcpy(tmp_buf, buf);
+
+	/* separate into argv */
+	argc = make_argv(tmp_buf, sizeof(argv)/sizeof(argv[0]), argv);
+
+	/* do the completion and return the possible completions */
+	i = complete_cmdv(argc, argv, last_char, sizeof(cmdv)/sizeof(cmdv[0]), cmdv);
+
+	/* no match; bell and out */
+	if (i == 0) {
+		if (argc > 1)	/* allow tab for non command */
+			return 0;
+		putc('\a');
+		return 1;
+	}
+
+	s = NULL;
+	len = 0;
+	sep = NULL;
+	seplen = 0;
+	if (i == 1) { /* one match; perfect */
+		k = strlen(argv[argc - 1]);
+		s = cmdv[0] + k;
+		len = strlen(s);
+		sep = " ";
+		seplen = 1;
+	} else if (i > 1 && (j = find_common_prefix(cmdv)) != 0) {	/* more */
+		k = strlen(argv[argc - 1]);
+		j -= k;
+		if (j > 0) {
+			s = cmdv[0] + k;
+			len = j;
+		}
+	}
+
+	if (s != NULL) {
+		k = len + seplen;
+		/* make sure it fits */
+		if (n + k >= CFG_CBSIZE - 2) {
+			putc('\a');
+			return 1;
+		}
+
+		t = buf + cnt;
+		for (i = 0; i < len; i++)
+			*t++ = *s++;
+		if (sep != NULL)
+			for (i = 0; i < seplen; i++)
+				*t++ = sep[i];
+		*t = '\0';
+		n += k;
+		col += k;
+		puts(t - k);
+		if (sep == NULL)
+			putc('\a');
+		*np = n;
+		*colp = col;
+	} else {
+		print_argv(NULL, "  ", " ", 78, cmdv);
+
+		puts(prompt);
+		puts(buf);
+	}
+	return 1;
+}
+
+#endif
diff --git a/common/env_common.c b/common/env_common.c
index e7ee499..d46f24f 100644
--- a/common/env_common.c
+++ b/common/env_common.c
@@ -260,3 +260,44 @@
 	disable_nvram();
 #endif
 }
+
+#ifdef CONFIG_AUTO_COMPLETE
+int env_complete(char *var, int maxv, char *cmdv[], int bufsz, char *buf)
+{
+	int i, nxt, len, vallen, found;
+	const char *lval, *rval;
+
+	found = 0;
+	cmdv[0] = NULL;
+
+	len = strlen(var);
+	/* now iterate over the variables and select those that match */
+	for (i=0; env_get_char(i) != '\0'; i=nxt+1) {
+
+		for (nxt=i; env_get_char(nxt) != '\0'; ++nxt)
+			;
+
+		lval = env_get_addr(i);
+		rval = strchr(lval, '=');
+		if (rval != NULL) {
+			vallen = rval - lval;
+			rval++;
+		} else
+			vallen = strlen(lval);
+
+		if (len > 0 && (vallen < len || memcmp(lval, var, len) != 0))
+			continue;
+
+		if (found >= maxv - 2 || bufsz < vallen + 1) {
+			cmdv[found++] = "...";
+			break;
+		}
+		cmdv[found++] = buf;
+		memcpy(buf, lval, vallen); buf += vallen; bufsz -= vallen;
+		*buf++ = '\0'; bufsz--;
+	}
+
+	cmdv[found] = NULL;
+	return found;
+}
+#endif
diff --git a/common/main.c b/common/main.c
index 156e4bc..7ce9b75 100644
--- a/common/main.c
+++ b/common/main.c
@@ -365,6 +365,10 @@
 	u_boot_hush_start ();
 #endif
 
+#ifdef CONFIG_AUTO_COMPLETE
+	install_auto_complete();
+#endif
+
 #ifdef CONFIG_PREBOOT
 	if ((p = getenv ("preboot")) != NULL) {
 # ifdef CONFIG_AUTOBOOT_KEYED
@@ -608,6 +612,14 @@
 			 */
 			if (n < CFG_CBSIZE-2) {
 				if (c == '\t') {	/* expand TABs		*/
+#ifdef CONFIG_AUTO_COMPLETE
+					/* if auto completion triggered just continue */
+					*p = '\0';
+					if (cmd_auto_complete(prompt, console_buffer, &n, &col)) {
+						p = console_buffer + n;	/* reset */
+						continue;
+					}
+#endif
 					puts (tab_seq+(col&07));
 					col += 8 - (col&07);
 				} else {