Index: /trunk/src/VBox/Devices/Network/DevVirtioNet.cpp
===================================================================
--- /trunk/src/VBox/Devices/Network/DevVirtioNet.cpp	(revision 23978)
+++ /trunk/src/VBox/Devices/Network/DevVirtioNet.cpp	(revision 23979)
@@ -197,4 +197,5 @@
 PDMBOTHCBDECL(int)      vnetSetConfig(void *pState, uint32_t port, uint32_t cb, void *data);
 PDMBOTHCBDECL(void)     vnetReset(void *pState);
+PDMBOTHCBDECL(void)     vnetReady(void *pState);
 #ifdef DEBUG
 static const char *vnetGetQueueName(void *pvState, PVQUEUE pQueue);
@@ -220,4 +221,5 @@
     int       (*pfnSetConfig)(void *pvState, uint32_t port, uint32_t cb, void *data);
     void      (*pfnReset)(void *pvState);
+    void      (*pfnReady)(void *pvState);
 #ifdef DEBUG
     const char *(*pfnGetQueueName)(void *pvState, PVQUEUE pQueue);
@@ -229,5 +231,5 @@
         0x1AF4, 0x1000, 0x1AF4, 1 + VIRTIO_NET_ID, 0x0200, 3, "virtio-net", "vnet%d",
         vnetGetHostFeatures, vnetGetHostMinimalFeatures, vnetSetHostFeatures,
-        vnetGetConfig, vnetSetConfig, vnetReset
+        vnetGetConfig, vnetSetConfig, vnetReset, vnetReady
 #ifdef DEBUG
         , vnetGetQueueName
@@ -236,5 +238,5 @@
     { /* Virtio Block Device */
         0x1AF4, 0x1001, 0x1AF4, 1 + VIRTIO_BLK_ID, 0x0180, 2, "virtio-blk", "vblk%d",
-        NULL, NULL, NULL, NULL, NULL, NULL
+        NULL, NULL, NULL, NULL, NULL, NULL, NULL
 #ifdef DEBUG
         , NULL
@@ -654,4 +656,5 @@
     int         rc     = VINF_SUCCESS;
     const char *szInst = INSTANCE(pState);
+    bool        fHasBecomeReady;
     STAM_PROFILE_ADV_START(&pState->CTXSUFF(StatIOWrite), a);
 
@@ -665,5 +668,5 @@
             if (VPCI_F_BAD_FEATURE & u32)
             {
-                Log(("%s Guest failed to negotiate properly! (guest=%x)\n",
+                Log(("%s WARNING! Guest failed to negotiate properly (guest=%x)\n",
                      INSTANCE(pState), u32));
                 pState->uGuestFeatures = g_VPCIDevices[pState->enmDevType].pfnGetHostMinimalFeatures(pState);
@@ -720,8 +723,11 @@
             Assert(cb == 1);
             u32 &= 0xFF;
+            fHasBecomeReady = !(pState->uStatus & VPCI_STATUS_DRV_OK) && (u32 & VPCI_STATUS_DRV_OK);
             pState->uStatus = u32;
             /* Writing 0 to the status port triggers device reset. */
             if (u32 == 0)
                 g_VPCIDevices[pState->enmDevType].pfnReset(pState);
+            else if (fHasBecomeReady)
+                g_VPCIDevices[pState->enmDevType].pfnReady(pState);
             break;
 
@@ -1111,4 +1117,8 @@
     R3PTRTYPE(PPDMINETWORKCONNECTOR) pDrv;    /**< Connector of attached network driver. */
 
+    R3PTRTYPE(PPDMQUEUE)    pCanRxQueueR3;           /**< Rx wakeup signaller - R3. */
+    R0PTRTYPE(PPDMQUEUE)    pCanRxQueueR0;           /**< Rx wakeup signaller - R0. */
+    RCPTRTYPE(PPDMQUEUE)    pCanRxQueueRC;           /**< Rx wakeup signaller - RC. */
+
     PTMTIMERR3  pLinkUpTimer;                             /**< Link Up(/Restore) Timer. */
 
@@ -1288,4 +1298,22 @@
 
 #endif /* IN_RING3 */
+
+/**
+ * This function is called when the driver becomes ready.
+ *
+ * @param   pState      The device state structure.
+ */
+PDMBOTHCBDECL(void) vnetReady(void *pvState)
+{
+    VNETSTATE *pState = (VNETSTATE*)pvState;
+    Log(("%s Driver became ready, waking up RX thread...\n", INSTANCE(pState)));
+#ifdef IN_RING3
+    vnetWakeupReceive(pState->VPCI.CTX_SUFF(pDevIns));
+#else
+    PPDMQUEUEITEMCORE pItem = PDMQueueAlloc(pState->CTX_SUFF(pCanRxQueue));
+    if (pItem)
+        PDMQueueInsert(pState->CTX_SUFF(pCanRxQueue), pItem);
+#endif
+}
 
 
@@ -1699,4 +1727,11 @@
     return rc;*/
 
+    /* Create the RX notifier signaller. */
+    rc = PDMDevHlpPDMQueueCreate(pDevIns, sizeof(PDMQUEUEITEMCORE), 1, 0,
+                                 vnetCanRxQueueConsumer, true, "VNet-Rcv", &pState->pCanRxQueueR3);
+    if (RT_FAILURE(rc))
+        return rc;
+    pState->pCanRxQueueR0 = PDMQueueR0Ptr(pState->pCanRxQueueR3);
+    pState->pCanRxQueueRC = PDMQueueRCPtr(pState->pCanRxQueueR3);
 
     /* Create Link Up Timer */
@@ -1793,4 +1828,5 @@
     VNETSTATE* pState = PDMINS_2_DATA(pDevIns, VNETSTATE*);
     vpciRelocate(pDevIns, offDelta);
+    pState->pCanRxQueueRC = PDMQueueRCPtr(pState->pCanRxQueueR3);
     // TBD
 }
