Index: trunk/src/VBox/Devices/Network/DevVirtioNet_1_0.cpp
===================================================================
--- trunk/src/VBox/Devices/Network/DevVirtioNet_1_0.cpp	(revision 83058)
+++ trunk/src/VBox/Devices/Network/DevVirtioNet_1_0.cpp	(revision 83153)
@@ -415,4 +415,6 @@
     uint8_t                 aVlanFilter[VIRTIONET_MAX_VLAN_ID / sizeof(uint8_t)];
 
+    bool                    fLog;
+
     /* Receive-blocking-related fields ***************************************/
 
@@ -522,5 +524,5 @@
 {
     PVIRTIONET pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIONET);
-    LogFunc(("%s\n", INSTANCE(pThis)));
+    Log10Func(("%s\n", INSTANCE(pThis)));
     return PDMDevHlpSUPSemEventSignal(pDevIns, pThis->aWorkers[(uintptr_t)pThread->pvUser].hEvtProcess);
 }
@@ -535,5 +537,5 @@
     AssertReturnVoid(pThis->hEventRxDescAvail != NIL_SUPSEMEVENT);
 
-    LogFunc(("%s Waking downstream driver's Rx buf waiter thread\n", INSTANCE(pThis)));
+    Log10Func(("%s Waking downstream driver's Rx buf waiter thread\n", INSTANCE(pThis)));
     int rc = PDMDevHlpSUPSemEventSignal(pDevIns, pThis->hEventRxDescAvail);
     AssertRC(rc);
@@ -560,15 +562,8 @@
 DECLINLINE(void) virtioNetR3PacketDump(PVIRTIONET pThis, const uint8_t *pbPacket, size_t cb, const char *pszText)
 {
-# ifdef DEBUG
-#  if 0
-    Log(("%s %s packet #%d (%d bytes):\n",
-         INSTANCE(pThis), pszText, ++pThis->u32PktNo, cb));
-    Log3(("%.*Rhxd\n", cb, pbPacket));
-#  else
+//    if (!LogIs12Enabled())
+//        return;
+
     vboxEthPacketDump(INSTANCE(pThis), pszText, pbPacket, (uint32_t)cb);
-#  endif
-# else
-    RT_NOREF4(pThis, pbPacket, cb, pszText);
-# endif
 }
 
@@ -757,5 +752,5 @@
     PVIRTIONET pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIONET);
 
-    LogFunc(("%s uOffset: %d, cb: %d: %.*Rhxs\n", INSTANCE(pThis), uOffset, cb, RT_MAX(cb, 8) , pv));
+    Log10Func(("%s uOffset: %d, cb: %d: %.*Rhxs\n", INSTANCE(pThis), uOffset, cb, RT_MAX(cb, 8) , pv));
     return virtioNetR3CfgAccessed(PDMDEVINS_2_DATA(pDevIns, PVIRTIONET), uOffset, (void *)pv, cb, true /*fWrite*/);
 }
@@ -797,5 +792,5 @@
 
     RT_NOREF(pThisCC);
-    LogFunc(("%s LOAD EXEC!!\n", INSTANCE(pThis)));
+    Log7Func(("%s LOAD EXEC!!\n", INSTANCE(pThis)));
 
     AssertReturn(uPass == SSM_PASS_FINAL, VERR_SSM_UNEXPECTED_PASS);
@@ -820,5 +815,5 @@
         if (pThis->afQueueAttached[idxQueue])
         {
-            LogFunc(("%s Waking %s worker.\n", INSTANCE(pThis), VIRTQNAME(idxQueue)));
+            Log7Func(("%s Waking %s worker.\n", INSTANCE(pThis), VIRTQNAME(idxQueue)));
             rc = PDMDevHlpSUPSemEventSignal(pDevIns, pThis->aWorkers[idxQueue].hEvtProcess);
             AssertRCReturn(rc, rc);
@@ -839,5 +834,5 @@
     RT_NOREF(pThisCC);
 
-    LogFunc(("%s SAVE EXEC!!\n", INSTANCE(pThis)));
+    Log7Func(("%s SAVE EXEC!!\n", INSTANCE(pThis)));
 
     for (int idxQueue = 0; idxQueue < pThis->cVirtQueues; idxQueue++)
@@ -865,5 +860,5 @@
     /** @todo create test to conclusively determine I/O has been quiesced and add it here: */
 
-    LogFunc(("%s Device I/O activity quiesced: %s\n",
+    Log7Func(("%s Device I/O activity quiesced: %s\n",
         INSTANCE(pThis), virtioCoreGetStateChangeText(pThisCC->enmQuiescingFor)));
 
@@ -911,5 +906,5 @@
 {
     PVIRTIONET pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIONET);
-    LogFunc(("%s\n", INSTANCE(pThis)));
+    Log7Func(("%s\n", INSTANCE(pThis)));
     pThis->fResetting = true;
     virtioNetR3QuiesceDevice(pDevIns, kvirtIoVmStateChangedReset);
@@ -924,5 +919,5 @@
     PVIRTIONET   pThis   = PDMDEVINS_2_DATA(pDevIns, PVIRTIONET);
     PVIRTIONETCC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIONETCC);
-    LogFunc(("%s\n", INSTANCE(pThis)));
+    Log7Func(("%s\n", INSTANCE(pThis)));
 
     RT_NOREF2(pThis, pThisCC);
@@ -937,5 +932,5 @@
 {
     PVIRTIONET   pThis   = PDMDEVINS_2_DATA(pDevIns, PVIRTIONET);
-    LogFunc(("%s\n", INSTANCE(pThis)));
+    Log7Func(("%s\n", INSTANCE(pThis)));
 
     virtioNetR3SuspendOrPowerOff(pDevIns, kvirtIoVmStateChangedPowerOff);
@@ -948,5 +943,5 @@
 {
     PVIRTIONET   pThis   = PDMDEVINS_2_DATA(pDevIns, PVIRTIONET);
-    LogFunc(("%s \n", INSTANCE(pThis)));
+    Log7Func(("%s \n", INSTANCE(pThis)));
     virtioNetR3SuspendOrPowerOff(pDevIns, kvirtIoVmStateChangedSuspend);
 }
@@ -959,5 +954,5 @@
     PVIRTIONET   pThis   = PDMDEVINS_2_DATA(pDevIns, PVIRTIONET);
     PVIRTIONETCC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIONETCC);
-    LogFunc(("\n"));
+    Log7Func(("\n"));
 
     pThisCC->fQuiescing = false;
@@ -975,5 +970,5 @@
         if (ASMAtomicReadBool(&pThisCC->aWorkers[idxQueue].fSleeping))
         {
-            Log6Func(("%s waking %s worker.\n", INSTANCE(pThis), VIRTQNAME(idxQueue)));
+            Log7Func(("%s waking %s worker.\n", INSTANCE(pThis), VIRTQNAME(idxQueue)));
             int rc = PDMDevHlpSUPSemEventSignal(pDevIns, pThis->aWorkers[idxQueue].hEvtProcess);
             AssertRC(rc);
@@ -1020,5 +1015,5 @@
 void virtioNetR3SetReadLed(PVIRTIONETR3 pThisR3, bool fOn)
 {
-    Log6Func(("%s\n", fOn ? "on" : "off"));
+    Log10Func(("%s\n", fOn ? "on" : "off"));
     if (fOn)
         pThisR3->led.Asserted.s.fReading = pThisR3->led.Actual.s.fReading = 1;
@@ -1036,5 +1031,5 @@
 void virtioNetR3SetWriteLed(PVIRTIONETR3 pThisR3, bool fOn)
 {
-    Log6Func(("%s\n", fOn ? "on" : "off"));
+    Log10Func(("%s\n", fOn ? "on" : "off"));
     if (fOn)
         pThisR3->led.Asserted.s.fWriting = pThisR3->led.Actual.s.fWriting = 1;
@@ -1060,18 +1055,18 @@
     if (!pThis->fVirtioReady)
     {
-        LogFunc(("%s %s VirtIO not ready (rc = VERR_NET_NO_BUFFER_SPACE)\n", LOGPARAMS));
+        Log8Func(("%s %s VirtIO not ready (rc = VERR_NET_NO_BUFFER_SPACE)\n", LOGPARAMS));
     }
     else if (!virtioCoreIsQueueEnabled(&pThis->Virtio, RXQIDX_QPAIR(idxQueue)))
     {
-        LogFunc(("%s %s queue not enabled (rc = VERR_NET_NO_BUFFER_SPACE)\n", LOGPARAMS));
+        Log8Func(("%s %s queue not enabled (rc = VERR_NET_NO_BUFFER_SPACE)\n", LOGPARAMS));
     }
     else if (virtioCoreQueueIsEmpty(pDevIns, &pThis->Virtio, RXQIDX_QPAIR(idxQueue)))
     {
-        LogFunc(("%s %s queue is empty (rc = VERR_NET_NO_BUFFER_SPACE)\n", LOGPARAMS));
+        Log8Func(("%s %s queue is empty (rc = VERR_NET_NO_BUFFER_SPACE)\n", LOGPARAMS));
         virtioCoreQueueSetNotify(&pThis->Virtio, RXQIDX_QPAIR(idxQueue), true);
     }
     else
     {
-        LogFunc(("%s %s ready with available buffers\n", LOGPARAMS));
+        Log8Func(("%s %s ready with available buffers\n", LOGPARAMS));
         virtioCoreQueueSetNotify(&pThis->Virtio, RXQIDX_QPAIR(idxQueue), false);
         return VINF_SUCCESS;
@@ -1124,5 +1119,5 @@
     if (virtioNetR3AreRxBufsAvail(pDevIns, pThis))
     {
-            LogFunc(("%s Rx bufs now available, releasing waiter...\n", INSTANCE(pThis)));
+            Log10Func(("%s Rx bufs now available, releasing waiter...\n", INSTANCE(pThis)));
             return VINF_SUCCESS;
     }
@@ -1137,8 +1132,8 @@
         if (virtioNetR3AreRxBufsAvail(pDevIns, pThis))
         {
-                LogFunc(("%s Rx bufs now available, releasing waiter...\n", INSTANCE(pThis)));
+                Log10Func(("%s Rx bufs now available, releasing waiter...\n", INSTANCE(pThis)));
                 return VINF_SUCCESS;
         }
-        LogFunc(("%s Starved for guest Rx bufs, waiting %u ms ...\n",
+        Log9Func(("%s Starved for guest Rx bufs, waiting %u ms ...\n",
                  INSTANCE(pThis), timeoutMs));
 
@@ -1155,5 +1150,5 @@
     ASMAtomicXchgBool(&pThis->fLeafWantsRxBuffers, false);
 
-    LogFlowFunc(("%s Wait for Rx buffers available was interrupted\n", INSTANCE(pThis)));
+    Log7Func(("%s Wait for Rx buffers available was interrupted\n", INSTANCE(pThis)));
     return VERR_INTERRUPTED;
 }
@@ -1250,5 +1245,21 @@
 static bool virtioNetR3AddressFilter(PVIRTIONET pThis, const void *pvBuf, size_t cb)
 {
-    LogFunc(("%s\n", INSTANCE(pThis)));
+
+    if (LogIs11Enabled())
+    {
+        char *pszType;
+        if (virtioNetR3IsMulticast(pvBuf))
+            pszType = (char *)"Multicast";
+        else if (virtioNetR3IsBroadcast(pvBuf))
+            pszType = (char *)"Broadcast";
+        else
+            pszType = (char *)"Unicast";
+
+        LogFunc(("%s node(%RTmac %s%s), pkt(%RTmac %s)",
+                 INSTANCE(pThis), pThis->virtioNetConfig.uMacAddress.au8,
+                 pThis->fPromiscuous ? "promiscuous" : "",
+                 pThis->fAllMulticast ? " all-multicast" : "",
+                 pvBuf,  pszType));
+    }
 
     if (pThis->fPromiscuous)
@@ -1262,23 +1273,49 @@
         && !ASMBitTest(pThis->aVlanFilter, RT_BE2H_U16(uPtr[7]) & 0xFFF))
     {
-        Log4Func(("%s not our VLAN, returning false\n", INSTANCE(pThis)));
+        Log11Func(("\n%s not our VLAN, returning false\n", INSTANCE(pThis)));
         return false;
     }
 
+uint8_t src[6] = { 0xA8, 0x20, 0x66, 0x57, 0x50, 0x3C };
+uint8_t dst[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+if (memcmp(pvBuf, dst, 6) == 0 && memcmp(((uint8_t *)pvBuf) + 6, src, 6) == 0)
+{
+    pThis->fLog = true;
+    virtioNetR3PacketDump(pThis, (const uint8_t *)pvBuf, cb, "<-- Incoming");
+}
+
     if (virtioNetR3IsBroadcast(pvBuf))
+    {
+        Log11(("... accept (broadcast)\n"));
+        if (LogIs12Enabled())
+            virtioNetR3PacketDump(pThis, (const uint8_t *)pvBuf, cb, "<-- Incoming");
         return true;
-
+    }
     if (pThis->fAllMulticast && virtioNetR3IsMulticast(pvBuf))
+    {
+        Log11(("... accept (all-multicast mode)\n"));
+        if (LogIs12Enabled())
+            virtioNetR3PacketDump(pThis, (const uint8_t *)pvBuf, cb, "<-- Incoming");
         return true;
+    }
 
     if (!memcmp(pThis->virtioNetConfig.uMacAddress.au8, pvBuf, sizeof(RTMAC)))
+    {
+        Log11((". . . accept (direct to this node)\n"));
+        if (LogIs12Enabled())
+            virtioNetR3PacketDump(pThis, (const uint8_t *)pvBuf, cb, "<-- Incoming");
         return true;
-
-    Log4Func(("%s : %RTmac (conf) != %RTmac (dest)\n",
-        INSTANCE(pThis), pThis->virtioNetConfig.uMacAddress.au8, pvBuf));
+    }
 
     for (uint16_t i = 0; i < pThis->cMulticastFilterMacs; i++)
+    {
         if (!memcmp(&pThis->aMacMulticastFilter[i], pvBuf, sizeof(RTMAC)))
+        {
+            Log11(("... accept (in multicast array)\n"));
+            if (LogIs12Enabled())
+                virtioNetR3PacketDump(pThis, (const uint8_t *)pvBuf, cb, "<-- Incoming");
             return true;
+        }
+    }
 
     /** @todo Original combined unicast & multicast into one table. Should we distinguish? */
@@ -1286,10 +1323,11 @@
     for (uint16_t i = 0; i < pThis->cUnicastFilterMacs; i++)
         if (!memcmp(&pThis->aMacUnicastFilter[i], pvBuf, sizeof(RTMAC)))
+        {
+            Log11(("... accept (in unicast array)\n"));
             return true;
-
-    Log2Func(("%s failed all tests, returning false, packet dump follows:\n",
-        INSTANCE(pThis)));
-
-    virtioNetR3PacketDump(pThis, (const uint8_t *)pvBuf, cb, "<-- Incoming");
+        }
+
+    if (LogIs12Enabled())
+        Log(("... reject\n"));
 
     return false;
@@ -1316,5 +1354,5 @@
     RT_NOREF(pThisCC);
 
-    LogFunc(("%s\n", INSTANCE(pThis)));
+    LogFunc(("%s (%RTmac)\n", INSTANCE(pThis), pvBuf));
     VIRTIONET_PKT_HDR_T rxPktHdr;
 
@@ -1353,10 +1391,10 @@
     }
 
-    virtioNetR3PacketDump(pThis, (const uint8_t *)pvBuf, cb, "<-- Incoming");
+//    virtioNetR3PacketDump(pThis, (const uint8_t *)pvBuf, cb, "<-- Incoming");
 
     uint16_t cSegsAllocated = VIRTIONET_PREALLOCATE_RX_SEG_COUNT;
 
-    PRTSGBUF pVirtSegBufToGuest = NULL;
-    PRTSGSEG paVirtSegsToGuest = (PRTSGSEG)RTMemAllocZ(sizeof(RTSGSEG) * cSegsAllocated);
+    PRTSGBUF pVirtSegBufToGuest = (PRTSGBUF)RTMemAllocZ(sizeof(RTSGBUF));
+    PRTSGSEG paVirtSegsToGuest  = (PRTSGSEG)RTMemAllocZ(sizeof(RTSGSEG) * cSegsAllocated);
     AssertReturn(paVirtSegsToGuest, VERR_NO_MEMORY);
 
@@ -1365,5 +1403,5 @@
 
     uint8_t fAddPktHdr = true;
-    uint32_t uOffset;
+    uint32_t uOffset = 0;
 
     while (uOffset < cb)
@@ -1393,4 +1431,5 @@
         if (fAddPktHdr)
         {
+LogFunc(("Add pkthdr\n"));
             /* Lead with packet header */
             paVirtSegsToGuest[cSegs].cbSeg = sizeof(VIRTIONET_PKT_HDR_T);
@@ -1398,18 +1437,21 @@
             AssertReturn(paVirtSegsToGuest[0].pvSeg, VERR_NO_MEMORY);
 
+            cbDescChainLeft -= sizeof(VIRTIONET_PKT_HDR_T);
+
+            memcpy(paVirtSegsToGuest[cSegs].pvSeg, &rxPktHdr, sizeof(VIRTIONET_PKT_HDR_T));
+
             /* Calculate & cache the field we will need to update later in gcPhys memory */
             gcPhysPktHdrNumBuffers = pDescChain->pSgPhysReturn->paSegs[0].gcPhys
                                      + RT_UOFFSETOF(VIRTIONET_PKT_HDR_T, uNumBuffers);
 
-            if (cSegs++ >= cSegsAllocated)
-            {
-                cSegsAllocated <<= 1; /* double the allocation size */
-                paVirtSegsToGuest = (PRTSGSEG)RTMemRealloc(paVirtSegsToGuest, sizeof(RTSGSEG) * cSegsAllocated);
-                AssertReturn(paVirtSegsToGuest, VERR_NO_MEMORY);
-            }
-
             fAddPktHdr = false;
-            cbDescChainLeft -= sizeof(VIRTIONET_PKT_HDR_T);
         }
+        if (cSegs++ >= cSegsAllocated)
+        {
+            cSegsAllocated <<= 1; /* double the allocation size */
+            paVirtSegsToGuest = (PRTSGSEG)RTMemRealloc(paVirtSegsToGuest, sizeof(RTSGSEG) * cSegsAllocated);
+            AssertReturn(paVirtSegsToGuest, VERR_NO_MEMORY);
+        }
+LogFunc(("Add new post-hdr segment\n"));
 
         /* Append remaining Rx pkt or as much current desc chain has room for */
@@ -1421,5 +1463,7 @@
 
         RTSgBufInit(pVirtSegBufToGuest, paVirtSegsToGuest, cSegs);
-
+//if (pThis->fLog)
+//    RT_BREAKPOINT();
+        Log7Func(("Send Rx pkt to guest...\n"));
         virtioCoreR3QueuePut(pDevIns, &pThis->Virtio, RXQIDX_QPAIR(idxQueue),
                              pVirtSegBufToGuest, pDescChain, true);
@@ -1438,10 +1482,11 @@
     virtioCoreQueueSync(pDevIns, &pThis->Virtio, RXQIDX_QPAIR(idxQueue));
 
-    for (int i = 0; i < 2; i++)
-        RTMemFree(paVirtSegsToGuest[i].pvSeg);
+//    for (int i = 0; i < cSegs; i++)
+//        RTMemFree(paVirtSegsToGuest[i].pvSeg);
 
     RTMemFree(paVirtSegsToGuest);
     RTMemFree(pVirtSegBufToGuest);
 
+    Log7(("\n"));
     if (uOffset < cb)
     {
@@ -1449,5 +1494,5 @@
         return VERR_TOO_MUCH_DATA;
     }
-
+pThis->fLog = false;
     return VINF_SUCCESS;
 }
@@ -1459,5 +1504,4 @@
                                                size_t cb, PCPDMNETWORKGSO pGso)
 {
-LogFunc(("\n"));
     PVIRTIONETCC    pThisCC = RT_FROM_MEMBER(pInterface, VIRTIONETCC, INetworkDown);
     PPDMDEVINS      pDevIns = pThisCC->pDevIns;
@@ -1502,5 +1546,5 @@
     }
 
-    Log2Func(("%s pvBuf=%p cb=%u pGso=%p\n", INSTANCE(pThis), pvBuf, cb, pGso));
+    Log10Func(("%s pvBuf=%p cb=%3u pGso=%p ...", INSTANCE(pThis), pvBuf, cb, pGso));
 
     /** @todo If we ever start using more than one Rx/Tx queue pair, is a random queue
@@ -1658,5 +1702,5 @@
             virtioNetR3PullChain(pDevIns, pThis, pDescChain, &cMacs, sizeof(cMacs));
             cbRemaining -= sizeof(cMacs);
-            Log6Func(("%s Guest provided %d unicast MAC Table entries\n", INSTANCE(pThis), cMacs));
+            Log7Func(("%s Guest provided %d unicast MAC Table entries\n", INSTANCE(pThis), cMacs));
             if (cMacs)
             {
@@ -1672,5 +1716,5 @@
             virtioNetR3PullChain(pDevIns, pThis, pDescChain, &cMacs, sizeof(cMacs));
             cbRemaining -= sizeof(cMacs);
-            Log6Func(("%s Guest provided %d multicast MAC Table entries\n", INSTANCE(pThis), cMacs));
+            Log10Func(("%s Guest provided %d multicast MAC Table entries\n", INSTANCE(pThis), cMacs));
             if (cMacs)
             {
@@ -1755,5 +1799,5 @@
                          RT_MIN(pDescChain->cbPhysSend, sizeof(VIRTIONET_CTRL_HDR_T)));
 
-    Log6Func(("%s CTRL COMMAND: class=%d command=%d\n", INSTANCE(pThis), pCtrlPktHdr->uClass, pCtrlPktHdr->uCmd));
+    Log7Func(("%s CTRL COMMAND: class=%d command=%d\n", INSTANCE(pThis), pCtrlPktHdr->uClass, pCtrlPktHdr->uCmd));
 
     uint8_t uAck;
@@ -1783,5 +1827,5 @@
             }
             pThis->virtioNetConfig.uStatus &= ~VIRTIONET_F_ANNOUNCE;
-            Log6Func(("%s Clearing VIRTIONET_F_ANNOUNCE in config status\n", INSTANCE(pThis)));
+            Log7Func(("%s Clearing VIRTIONET_F_ANNOUNCE in config status\n", INSTANCE(pThis)));
             break;
 
@@ -1876,4 +1920,5 @@
                                PPDMNETWORKGSO pGso, PVIRTIONET_PKT_HDR_T pPktHdr)
 {
+LogFunc(("\n"));
     virtioNetR3PacketDump(pThis, (uint8_t *)pSgBuf->aSegs[0].pvSeg, pSgBuf->cbUsed, "--> Outgoing");
     if (pGso)
@@ -1926,4 +1971,6 @@
                                          uint16_t idxQueue, bool fOnWorkerThread)
 {
+
+LogFunc(("\n"));
     PVIRTIOCORE pVirtio = &pThis->Virtio;
 
@@ -1963,6 +2010,16 @@
     unsigned int cbPktHdr = sizeof(VIRTIONET_PKT_HDR_T);
 
-    Log3Func(("%s About to transmit %d pending packets\n", INSTANCE(pThis),
-              virtioCoreR3QueuePendingCount(pVirtio->pDevIns, pVirtio, idxQueue)));
+    int cPkts = virtioCoreR3QueuePendingCount(pVirtio->pDevIns, pVirtio, idxQueue);
+    if (!cPkts)
+    {
+        LogFunc(("%s No packets to send found on %s\n", INSTANCE(pThis), VIRTQNAME(idxQueue)));
+
+        if (pDrv)
+            pDrv->pfnEndXmit(pDrv);
+
+        ASMAtomicWriteU32(&pThis->uIsTransmitting, 0);
+        return;
+    }
+    LogFunc(("%s About to transmit %d pending packets\n", INSTANCE(pThis), cPkts));
 
     virtioNetR3SetWriteLed(pThisCC, true);
@@ -1973,8 +2030,8 @@
     {
         if (RT_SUCCESS(rc))
-            Log6Func(("%s fetched descriptor chain from %s\n", INSTANCE(pThis), VIRTQNAME(idxQueue)));
+            Log10Func(("%s fetched descriptor chain from %s\n", INSTANCE(pThis), VIRTQNAME(idxQueue)));
         else
         {
-            LogFunc(("%s Failed find expected data on %s, rc = %Rrc\n", INSTANCE(pThis), VIRTQNAME(idxQueue), rc));
+            LogFunc(("%s failed to find expected data on %s, rc = %Rrc\n", INSTANCE(pThis), VIRTQNAME(idxQueue), rc));
             break;
         }
@@ -2065,4 +2122,5 @@
 static DECLCALLBACK(void) virtioNetR3NetworkDown_XmitPending(PPDMINETWORKDOWN pInterface)
 {
+    LogFunc(("\n"));
     PVIRTIONETCC    pThisCC = RT_FROM_MEMBER(pInterface, VIRTIONETCC, INetworkDown);
     PPDMDEVINS      pDevIns = pThisCC->pDevIns;
@@ -2071,5 +2129,4 @@
     /** @todo If we ever start using more than one Rx/Tx queue pair, is a random queue
           selection algorithm feasible or even necessary */
-    LogFunc(("\n"));
     virtioNetR3TransmitPendingPackets(pDevIns, pThis, pThisCC, TXQIDX_QPAIR(0), false /*fOnWorkerThread*/);
 }
@@ -2091,9 +2148,9 @@
 #endif
 
-    Log6Func(("%s %s has available buffers\n", INSTANCE(pThis), VIRTQNAME(idxQueue)));
+    Log10Func(("%s %s has available buffers\n", INSTANCE(pThis), VIRTQNAME(idxQueue)));
 
     if (IS_RX_QUEUE(idxQueue))
     {
-        LogFunc(("%s Receive buffers have been added, waking Rx thread.\n",
+        Log10Func(("%s Receive buffers have been added, waking Rx thread.\n",
             INSTANCE(pThis)));
         virtioNetR3WakeupRxBufWaiter(pDevIns);
@@ -2106,5 +2163,5 @@
             if (ASMAtomicReadBool(&pWorkerR3->fSleeping))
             {
-                Log6Func(("%s waking %s worker.\n", INSTANCE(pThis), VIRTQNAME(idxQueue)));
+                Log10Func(("%s waking %s worker.\n", INSTANCE(pThis), VIRTQNAME(idxQueue)));
                 int rc = PDMDevHlpSUPSemEventSignal(pDevIns, pWorker->hEvtProcess);
                 AssertRC(rc);
@@ -2140,5 +2197,5 @@
             if (!fNotificationSent)
             {
-                Log6Func(("%s %s worker sleeping...\n", INSTANCE(pThis), VIRTQNAME(idxQueue)));
+                Log10Func(("%s %s worker sleeping...\n", INSTANCE(pThis), VIRTQNAME(idxQueue)));
                 Assert(ASMAtomicReadBool(&pWorkerR3->fSleeping));
                 int rc = PDMDevHlpSUPSemEventWaitNoResume(pDevIns, pWorker->hEvtProcess, RT_INDEFINITE_WAIT);
@@ -2151,5 +2208,5 @@
                     continue;
                 }
-                Log6Func(("%s %s worker woken\n", INSTANCE(pThis), VIRTQNAME(idxQueue)));
+                Log10Func(("%s %s worker woken\n", INSTANCE(pThis), VIRTQNAME(idxQueue)));
                 ASMAtomicWriteBool(&pWorkerR3->fNotified, false);
             }
@@ -2164,10 +2221,10 @@
              if (IS_CTRL_QUEUE(idxQueue))
              {
-                 Log6Func(("%s fetching next descriptor chain from %s\n", INSTANCE(pThis), VIRTQNAME(idxQueue)));
+                 Log10Func(("%s fetching next descriptor chain from %s\n", INSTANCE(pThis), VIRTQNAME(idxQueue)));
                  PVIRTIO_DESC_CHAIN_T pDescChain;
                  int rc = virtioCoreR3QueueGet(pDevIns, &pThis->Virtio, idxQueue, &pDescChain, true);
                  if (rc == VERR_NOT_AVAILABLE)
                  {
-                    Log6Func(("%s Nothing found in %s\n", INSTANCE(pThis), VIRTQNAME(idxQueue)));
+                    Log10Func(("%s Nothing found in %s\n", INSTANCE(pThis), VIRTQNAME(idxQueue)));
                     continue;
                  }
@@ -2176,5 +2233,6 @@
              else if (IS_TX_QUEUE(idxQueue))
              {
-                 Log6Func(("%s Notified of data to transmit\n", INSTANCE(pThis)));
+LogFunc(("Worker thread notified of pending Xmit packets!!!!!!\n"));
+                 Log10Func(("%s Notified of data to transmit\n", INSTANCE(pThis)));
                  virtioNetR3TransmitPendingPackets(pDevIns, pThis, pThisCC,
                                                    idxQueue, true /* fOnWorkerThread */);
@@ -2279,5 +2337,5 @@
     bool fActiveLinkIsUp = (enmState == PDMNETWORKLINKSTATE_UP);
 
-    LogFunc(("%s enmState=%d\n", INSTANCE(pThis), enmState));
+    Log7Func(("%s enmState=%d\n", INSTANCE(pThis), enmState));
     if (enmState == PDMNETWORKLINKSTATE_DOWN_RESUME)
     {
@@ -2319,5 +2377,5 @@
 static int virtioNetR3DestroyWorkerThreads(PPDMDEVINS pDevIns, PVIRTIONET pThis, PVIRTIONETCC pThisCC)
 {
-    LogFunc(("%s\n", INSTANCE(pThis)));
+    Log10Func(("%s\n", INSTANCE(pThis)));
     int rc = VINF_SUCCESS;
     for (unsigned idxQueue = 0; idxQueue < pThis->cVirtQueues; idxQueue++)
@@ -2343,6 +2401,5 @@
 static int virtioNetR3CreateWorkerThreads(PPDMDEVINS pDevIns, PVIRTIONET pThis, PVIRTIONETCC pThisCC)
 {
-    LogFunc(("%s\n", INSTANCE(pThis)));
-
+    Log10Func(("%s\n", INSTANCE(pThis)));
     int rc = VINF_SUCCESS;
     /* Attach the queues and create worker threads for them: */
@@ -2350,22 +2407,21 @@
     {
         /* Skip creating threads for receive queues, only create for transmit queues & control queue */
-        if (IS_RX_QUEUE(idxQueue))
-            continue;
-
-        rc = PDMDevHlpSUPSemEventCreate(pDevIns, &pThis->aWorkers[idxQueue].hEvtProcess);
-
-        if (RT_FAILURE(rc))
-            return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
-                                       N_("DevVirtioNET: Failed to create SUP event semaphore"));
-
-        rc = PDMDevHlpThreadCreate(pDevIns, &pThisCC->aWorkers[idxQueue].pThread,
-                                   (void *)(uintptr_t)idxQueue, virtioNetR3WorkerThread,
-                                   virtioNetR3WakeupWorker, 0, RTTHREADTYPE_IO, VIRTQNAME(idxQueue));
-        if (rc != VINF_SUCCESS)
+        if (!IS_RX_QUEUE(idxQueue))
         {
-            LogRel(("Error creating thread for Virtual Queue %s: %Rrc\n", VIRTQNAME(idxQueue), rc));
-            return rc;
+            rc = PDMDevHlpSUPSemEventCreate(pDevIns, &pThis->aWorkers[idxQueue].hEvtProcess);
+
+            if (RT_FAILURE(rc))
+                return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
+                                           N_("DevVirtioNET: Failed to create SUP event semaphore"));
+
+            rc = PDMDevHlpThreadCreate(pDevIns, &pThisCC->aWorkers[idxQueue].pThread,
+                                       (void *)(uintptr_t)idxQueue, virtioNetR3WorkerThread,
+                                       virtioNetR3WakeupWorker, 0, RTTHREADTYPE_IO, VIRTQNAME(idxQueue));
+            if (rc != VINF_SUCCESS)
+            {
+                LogRel(("Error creating thread for Virtual Queue %s: %Rrc\n", VIRTQNAME(idxQueue), rc));
+                return rc;
+            }
         }
-
         pThis->afQueueAttached[idxQueue] = true;
     }
@@ -2380,6 +2436,4 @@
     PVIRTIONET     pThis     = RT_FROM_MEMBER(pVirtio,  VIRTIONET, Virtio);
     PVIRTIONETCC   pThisCC   = RT_FROM_MEMBER(pVirtioCC, VIRTIONETCC, Virtio);
-
-    LogFunc(("%s\n", INSTANCE(pThis)));
 
     pThis->fVirtioReady = fVirtioReady;
@@ -2397,4 +2451,5 @@
             (void) virtioCoreR3QueueAttach(&pThis->Virtio, idxQueue, VIRTQNAME(idxQueue));
             pThis->afQueueAttached[idxQueue] = true;
+            virtioCoreQueueIsEmpty(pThisCC->pDevIns, &pThis->Virtio, idxQueue);
             virtioCoreQueueSetNotify(&pThis->Virtio, idxQueue, true);
         }
@@ -2405,5 +2460,5 @@
 
         pThis->virtioNetConfig.uStatus = pThis->fCableConnected ? VIRTIONET_F_LINK_UP : 0;
-        LogFunc(("%s Link is %s\n", INSTANCE(pThis), pThis->fCableConnected ? "up" : "down"));
+        Log7Func(("%s Link is %s\n", INSTANCE(pThis), pThis->fCableConnected ? "up" : "down"));
 
         pThis->fPromiscuous  = true;
@@ -2442,5 +2497,5 @@
     PVIRTIONETCC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIONETCC);
 
-    LogFunc(("%s\n", INSTANCE(pThis)));
+    Log7Func(("%s\n", INSTANCE(pThis)));
     AssertLogRelReturnVoid(iLUN == 0);
 
@@ -2469,5 +2524,5 @@
     RT_NOREF(fFlags);
 
-    LogFunc(("%s", INSTANCE(pThis)));
+    Log7Func(("%s", INSTANCE(pThis)));
 
     AssertLogRelReturn(iLUN == 0, VERR_PDM_NO_SUCH_LUN);
@@ -2560,5 +2615,5 @@
      * Quick initialization of the state data, making sure that the destructor always works.
      */
-    LogFunc(("PDM device instance: %d\n", iInstance));
+    Log7Func(("PDM device instance: %d\n", iInstance));
 
 
