static int eth_stop(struct eth_dev *dev)
 {
+#ifdef RNDIS_COMPLETE_SIGNAL_DISCONNECT
+       unsigned long ts;
+       unsigned long timeout = CONFIG_SYS_HZ; /* 1 sec to stop RNDIS */
+#endif
+
        if (rndis_active(dev)) {
                rndis_set_param_medium(dev->rndis_config, NDIS_MEDIUM_802_3, 0);
                rndis_signal_disconnect(dev->rndis_config);
 
+#ifdef RNDIS_COMPLETE_SIGNAL_DISCONNECT
+               /* Wait until host receives OID_GEN_MEDIA_CONNECT_STATUS */
+               ts = get_timer(0);
+               while (get_timer(ts) < timeout)
+                       usb_gadget_handle_interrupts();
+#endif
+
                rndis_uninit(dev->rndis_config);
                dev->rndis = 0;
        }
        if (!dev->gadget)
                return;
 
+       /*
+        * Some USB controllers may need additional deinitialization here
+        * before dropping pull-up (also due to hardware issues).
+        * For example: unhandled interrupt with status stage started may
+        * bring the controller to fully broken state (until board reset).
+        * There are some variants to debug and fix such cases:
+        * 1) In the case of RNDIS connection eth_stop can perform additional
+        * interrupt handling. See RNDIS_COMPLETE_SIGNAL_DISCONNECT definition.
+        * 2) 'pullup' callback in your UDC driver can be improved to perform
+        * this deinitialization.
+        */
        eth_stop(dev);
 
        usb_gadget_disconnect(dev->gadget);
 
        rndis_per_dev_params[configNr].media_state
                        = NDIS_MEDIA_STATE_DISCONNECTED;
 
+#ifdef RNDIS_COMPLETE_SIGNAL_DISCONNECT
+       return rndis_indicate_status_msg(configNr,
+                                         RNDIS_STATUS_MEDIA_DISCONNECT);
+#else
        return 0;
+#endif
 }
 
 void rndis_uninit(int configNr)
 
 
 #include "ndis.h"
 
+/*
+ * By default rndis_signal_disconnect does not send status message about
+ * RNDIS disconnection to USB host (indicated as cable disconnected).
+ * Define RNDIS_COMPLETE_SIGNAL_DISCONNECT to send it.
+ * However, this will cause 1 sec delay on Ethernet device halt.
+ * Usually you do not need to define it. Mostly usable for debugging.
+ */
+
 #define RNDIS_MAXIMUM_FRAME_SIZE       1518
 #define RNDIS_MAX_TOTAL_SIZE           1558