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;
         */
        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
         */
        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
 
 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,
        }
 
        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;
        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)
 
 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 */
 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).
 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.
 
 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)
 {
 
 
        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);
 
                        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 */
                                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;