Patches by Pantelis Antoniou, 30 Mar 2004:
add networking support for VLANs (802.1q), and CDP (Cisco Discovery Protocol)
diff --git a/common/cmd_nand.c b/common/cmd_nand.c
index 0e49e9f..c2e67ab 100644
--- a/common/cmd_nand.c
+++ b/common/cmd_nand.c
@@ -9,6 +9,7 @@
 #include <command.h>
 #include <malloc.h>
 #include <asm/io.h>
+#include <watchdog.h>
 
 #ifdef CONFIG_SHOW_BOOT_PROGRESS
 # include <status_led.h>
@@ -63,6 +64,7 @@
 #define NANDRW_READ	0x01
 #define NANDRW_WRITE	0x00
 #define NANDRW_JFFS2	0x02
+#define NANDRW_JFFS2_SKIP	0x04
 
 /*
  * Function Prototypes
@@ -207,6 +209,11 @@
 		}
 		else if (cmdtail && !strncmp(cmdtail, ".jffs2", 2))
 			cmd |= NANDRW_JFFS2;	/* skip bad blocks */
+		else if (cmdtail && !strncmp(cmdtail, ".jffs2s", 2)) {
+			cmd |= NANDRW_JFFS2;	/* skip bad blocks (on read too) */
+			if (cmd & NANDRW_READ)
+				cmd |= NANDRW_JFFS2_SKIP;	/* skip bad blocks (on read too) */
+		}
 #ifdef SXNI855T
 		/* need ".e" same as ".j" for compatibility with older units */
 		else if (cmdtail && !strcmp(cmdtail, ".e"))
@@ -258,7 +265,7 @@
 	"nand    - NAND sub-system\n",
 	"info  - show available NAND devices\n"
 	"nand device [dev] - show or set current device\n"
-	"nand read[.jffs2]  addr off size\n"
+	"nand read[.jffs2[s]]  addr off size\n"
 	"nand write[.jffs2] addr off size - read/write `size' bytes starting\n"
 	"    at offset `off' to/from memory address `addr'\n"
 	"nand erase [clean] [off size] - erase `size' bytes from\n"
@@ -420,6 +427,7 @@
  *	1: NANDRW_READ			read, fail on bad block
  *	2: NANDRW_WRITE | NANDRW_JFFS2	write, skip bad blocks
  *	3: NANDRW_READ | NANDRW_JFFS2	read, data all 0xff for bad blocks
+ *      7: NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP read, skip bad blocks
  */
 static int nand_rw (struct nand_chip* nand, int cmd,
 	    size_t start, size_t len,
@@ -450,6 +458,10 @@
 					}
 					continue;
 				}
+				else if (cmd == (NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP)) {
+					start += erasesize;
+					continue;
+				}
 				else if (cmd == (NANDRW_WRITE | NANDRW_JFFS2)) {
 					/* skip bad block */
 					start += erasesize;
diff --git a/common/cmd_net.c b/common/cmd_net.c
index f13e9d4..85a9023 100644
--- a/common/cmd_net.c
+++ b/common/cmd_net.c
@@ -96,7 +96,7 @@
 
 static void netboot_update_env(void)
 {
-    char tmp[16] ;
+    char tmp[22] ;
 
     if (NetOurGatewayIP) {
 	ip_to_string (NetOurGatewayIP, tmp);
@@ -139,6 +139,16 @@
     if (NetOurNISDomain[0])
 	setenv("domain", NetOurNISDomain);
 
+    if (ntohs(NetOurVLAN) != (ushort)-1) {
+	    VLAN_to_string(NetOurVLAN, tmp);
+	    setenv("vlan", tmp);
+    }
+
+    if (ntohs(NetOurNativeVLAN) != (ushort)-1) {
+	    VLAN_to_string(NetOurNativeVLAN, tmp);
+	    setenv("vlan", tmp);
+    }
+
 }
 static int
 netboot_common (int proto, cmd_tbl_t *cmdtp, int argc, char *argv[])
@@ -238,4 +248,47 @@
 );
 #endif	/* CFG_CMD_PING */
 
+#if (CONFIG_COMMANDS & CFG_CMD_CDP)
+
+static void cdp_update_env(void)
+{
+	char tmp[16];
+
+	if (CDPApplianceVLAN != htons(-1)) {
+		printf("CDP offered appliance VLAN %d\n", ntohs(CDPApplianceVLAN));
+		VLAN_to_string(CDPApplianceVLAN, tmp);
+		setenv("vlan", tmp);
+		NetOurVLAN = CDPApplianceVLAN;
+	}
+
+	if (CDPNativeVLAN != htons(-1)) {
+		printf("CDP offered native VLAN %d\n", ntohs(CDPNativeVLAN));
+		VLAN_to_string(CDPNativeVLAN, tmp);
+		setenv("nvlan", tmp);
+		NetOurNativeVLAN = CDPNativeVLAN;
+	}
+
+}
+
+int do_cdp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	int r;
+
+	r = NetLoop(CDP);
+	if (r < 0) {
+		printf("cdp failed; perhaps not a CISCO switch?\n");
+		return 1;
+	}
+
+	cdp_update_env();
+
+	return 0;
+}
+
+U_BOOT_CMD(
+	cdp,	1,	1,	do_cdp,
+	"cdp     - Perform CDP network configuration\n",
+);
+#endif	/* CFG_CMD_CDP */
+
 #endif	/* CFG_CMD_NET */
diff --git a/common/miiphyutil.c b/common/miiphyutil.c
index 919de3e..721d109 100644
--- a/common/miiphyutil.c
+++ b/common/miiphyutil.c
@@ -203,6 +203,8 @@
 {
 	unsigned short reg;
 
+	/* dummy read; needed to latch some phys */
+	(void)miiphy_read(addr, PHY_BMSR, &reg);
 	if (miiphy_read (addr, PHY_BMSR, &reg)) {
 		puts ("PHY_BMSR read failed, assuming no link\n");
 		return (0);