diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index 45e726af8b8bc4870334d9ae48e39df02762e487..83fa5d7bd8b8057661fa50a7ddff0144cba73b66 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -564,6 +564,13 @@ int do_bootm_subcommand(cmd_tbl_t *cmdtp, int flag, int argc,
 			break;
 		case BOOTM_STATE_OS_GO:
 			disable_interrupts();
+#ifdef CONFIG_NETCONSOLE
+			/*
+			 * Stop the ethernet stack if NetConsole could have
+			 * left it up
+			 */
+			eth_halt();
+#endif
 			arch_preboot_os();
 			boot_fn(BOOTM_STATE_OS_GO, argc, argv, &images);
 			break;
@@ -622,6 +629,11 @@ int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	 */
 	iflag = disable_interrupts();
 
+#ifdef CONFIG_NETCONSOLE
+	/* Stop the ethernet stack if NetConsole could have left it up */
+	eth_halt();
+#endif
+
 #if defined(CONFIG_CMD_USB)
 	/*
 	 * turn off USB to prevent the host controller from writing to the
@@ -1599,6 +1611,11 @@ static int do_bootz(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	 */
 	disable_interrupts();
 
+#ifdef CONFIG_NETCONSOLE
+	/* Stop the ethernet stack if NetConsole could have left it up */
+	eth_halt();
+#endif
+
 #if defined(CONFIG_CMD_USB)
 	/*
 	 * turn off USB to prevent the host controller from writing to the
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index 8fcf31c4e9bb612e900bbcf20a9d9641afb27568..da82aa94ca4f87e592eafafee15f87b54e8ca2c6 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -44,6 +44,11 @@ static short nc_out_port; /* target output port */
 static short nc_in_port; /* source input port */
 static const char *output_packet; /* used by first send udp */
 static int output_packet_len;
+/*
+ * Start with a default last protocol.
+ * We are only interested in NETCONS or not.
+ */
+enum proto_t net_loop_last_protocol = BOOTP;
 
 static void nc_wait_arp_handler(uchar *pkt, unsigned dest,
 				 IPaddr_t sip, unsigned src,
@@ -136,8 +141,13 @@ static void nc_send_packet(const char *buf, int len)
 	}
 
 	if (eth->state != ETH_STATE_ACTIVE) {
-		if (eth_init(gd->bd) < 0)
-			return;
+		if (eth_is_on_demand_init()) {
+			if (eth_init(gd->bd) < 0)
+				return;
+			eth_set_last_protocol(NETCONS);
+		} else
+			eth_init_state_only(gd->bd);
+
 		inited = 1;
 	}
 	pkt = (uchar *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE;
@@ -146,8 +156,12 @@ static void nc_send_packet(const char *buf, int len)
 	ip = nc_ip;
 	NetSendUDPPacket(ether, ip, nc_out_port, nc_in_port, len);
 
-	if (inited)
-		eth_halt();
+	if (inited) {
+		if (eth_is_on_demand_init())
+			eth_halt();
+		else
+			eth_halt_state_only();
+	}
 }
 
 static int nc_start(void)
diff --git a/include/net.h b/include/net.h
index 6d2d6cd84958ef7fb464cf5961705329702c8207..e193b7b60bd65eedcee9f78a1679c15eb9ebd46c 100644
--- a/include/net.h
+++ b/include/net.h
@@ -102,7 +102,14 @@ extern int eth_register(struct eth_device* dev);/* Register network device */
 extern int eth_unregister(struct eth_device *dev);/* Remove network device */
 extern void eth_try_another(int first_restart);	/* Change the device */
 extern void eth_set_current(void);		/* set nterface to ethcur var */
-extern struct eth_device *eth_get_dev(void);	/* get the current device MAC */
+/* get the current device MAC */
+static inline __attribute__((always_inline))
+struct eth_device *eth_get_dev(void)
+{
+	extern struct eth_device *eth_current;
+
+	return eth_current;
+}
 extern struct eth_device *eth_get_dev_by_name(const char *devname);
 extern struct eth_device *eth_get_dev_by_index(int index); /* get dev @ index */
 extern int eth_get_dev_index(void);		/* get the device index */
@@ -151,6 +158,19 @@ extern int eth_rx(void);			/* Check for received packets */
 extern void eth_halt(void);			/* stop SCC */
 extern char *eth_get_name(void);		/* get name of current device */
 
+/* Set active state */
+static inline __attribute__((always_inline)) int eth_init_state_only(bd_t *bis)
+{
+	eth_get_dev()->state = ETH_STATE_ACTIVE;
+
+	return 0;
+}
+/* Set passive state */
+static inline __attribute__((always_inline)) void eth_halt_state_only(void)
+{
+	eth_get_dev()->state = ETH_STATE_PASSIVE;
+}
+
 /*
  * Set the hardware address for an ethernet interface based on 'eth%daddr'
  * environment variable (or just 'ethaddr' if eth_number is 0).
@@ -532,6 +552,26 @@ void NcStart(void);
 int nc_input_packet(uchar *pkt, unsigned dest, unsigned src, unsigned len);
 #endif
 
+static inline __attribute__((always_inline)) int eth_is_on_demand_init(void)
+{
+#ifdef CONFIG_NETCONSOLE
+	extern enum proto_t net_loop_last_protocol;
+
+	return net_loop_last_protocol != NETCONS;
+#else
+	return 1;
+#endif
+}
+
+static inline void eth_set_last_protocol(int protocol)
+{
+#ifdef CONFIG_NETCONSOLE
+	extern enum proto_t net_loop_last_protocol;
+
+	net_loop_last_protocol = protocol;
+#endif
+}
+
 /*
  * Check if autoload is enabled. If so, use either NFS or TFTP to download
  * the boot file.
diff --git a/net/eth.c b/net/eth.c
index bb4d95be8ec4800b17fdb454eda55b8ce6d9f21e..49458c8db914b96aa082920ed800639b73fcbb2a 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -121,12 +121,8 @@ static struct {
 static unsigned int eth_rcv_current, eth_rcv_last;
 #endif
 
-static struct eth_device *eth_devices, *eth_current;
-
-struct eth_device *eth_get_dev(void)
-{
-	return eth_current;
-}
+static struct eth_device *eth_devices;
+struct eth_device *eth_current;
 
 struct eth_device *eth_get_dev_by_name(const char *devname)
 {
diff --git a/net/net.c b/net/net.c
index f4404342f7c2d6d4e2ef26da39c263083e2e0c24..a89946ebe0625bea3bf943e20b04d47f069ec93d 100644
--- a/net/net.c
+++ b/net/net.c
@@ -315,12 +315,15 @@ int NetLoop(enum proto_t protocol)
 
 	bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start");
 	net_init();
-	eth_halt();
-	eth_set_current();
-	if (eth_init(bd) < 0) {
+	if (eth_is_on_demand_init() || protocol != NETCONS) {
 		eth_halt();
-		return -1;
-	}
+		eth_set_current();
+		if (eth_init(bd) < 0) {
+			eth_halt();
+			return -1;
+		}
+	} else
+		eth_init_state_only(bd);
 
 restart:
 	net_set_state(NETLOOP_CONTINUE);
@@ -460,6 +463,9 @@ restart:
 
 			net_cleanup_loop();
 			eth_halt();
+			/* Invalidate the last protocol */
+			eth_set_last_protocol(BOOTP);
+
 			puts("\nAbort\n");
 			/* include a debug print as well incase the debug
 			   messages are directed to stderr */
@@ -517,13 +523,21 @@ restart:
 				sprintf(buf, "%lX", (unsigned long)load_addr);
 				setenv("fileaddr", buf);
 			}
-			eth_halt();
+			if (protocol != NETCONS)
+				eth_halt();
+			else
+				eth_halt_state_only();
+
+			eth_set_last_protocol(protocol);
+
 			ret = NetBootFileXferSize;
 			debug_cond(DEBUG_INT_STATE, "--- NetLoop Success!\n");
 			goto done;
 
 		case NETLOOP_FAIL:
 			net_cleanup_loop();
+			/* Invalidate the last protocol */
+			eth_set_last_protocol(BOOTP);
 			debug_cond(DEBUG_INT_STATE, "--- NetLoop Fail!\n");
 			goto done;