Index: /trunk/src/VBox/Devices/Network/DevE1000.cpp
===================================================================
--- /trunk/src/VBox/Devices/Network/DevE1000.cpp	(revision 88528)
+++ /trunk/src/VBox/Devices/Network/DevE1000.cpp	(revision 88529)
@@ -1123,4 +1123,6 @@
     /** TX: Fetched TX descriptors. */
     E1KTXDESC   aTxDescriptors[E1K_TXD_CACHE_SIZE];
+    /** TX: Validity of TX descriptors. Set by e1kLocateTxPacket, used by e1kXmitPacket. */
+    bool        afTxDValid[E1K_TXD_CACHE_SIZE];
     /** TX: Actual number of fetched TX descriptors. */
     uint8_t     nTxDFetched;
@@ -5148,11 +5150,4 @@
     e1kPrintTDesc(pThis, pDesc, "vvv");
 
-    if (pDesc->legacy.dw3.fDD)
-    {
-        E1kLog(("%s e1kXmitDesc: skipping bad descriptor ^^^\n", pThis->szPrf));
-        e1kDescReport(pDevIns, pThis, pDesc, addr);
-        return VINF_SUCCESS;
-    }
-
 //#ifdef E1K_USE_TX_TIMERS
     if (pThis->fTidEnabled)
@@ -5177,5 +5172,5 @@
             if (pDesc->data.cmd.u20DTALEN == 0 || pDesc->data.u64BufAddr == 0)
             {
-                E1kLog2(("% Empty data descriptor, skipped.\n", pThis->szPrf));
+                E1kLog2(("%s Empty data descriptor, skipped.\n", pThis->szPrf));
                 if (pDesc->data.cmd.fEOP)
                 {
@@ -5303,5 +5298,5 @@
 }
 
-DECLINLINE(void) e1kUpdateTxContext(PE1KSTATE pThis, E1KTXDESC *pDesc)
+DECLINLINE(bool) e1kUpdateTxContext(PE1KSTATE pThis, E1KTXDESC *pDesc)
 {
     if (pDesc->context.dw2.fTSE)
@@ -5334,4 +5329,5 @@
              pDesc->context.tu.u8CSO,
              pDesc->context.tu.u16CSE));
+    return true; /* TODO: Consider returning false for invalid descriptors */
 }
 
@@ -5351,12 +5347,16 @@
     uint32_t cbPacket = 0;
 
+    /* Since we process one packet at a time we will only mark current packet's descriptors as valid */
+    memset(pThis->afTxDValid, 0, sizeof(pThis->afTxDValid));
     for (int i = pThis->iTxDCurrent; i < pThis->nTxDFetched; ++i)
     {
         E1KTXDESC *pDesc = &pThis->aTxDescriptors[i];
+        /* Assume the descriptor valid until proven otherwise. */
+        pThis->afTxDValid[i] = true;
         switch (e1kGetDescType(pDesc))
         {
             case E1K_DTYP_CONTEXT:
                 if (cbPacket == 0)
-                    e1kUpdateTxContext(pThis, pDesc);
+                    pThis->afTxDValid[i] = e1kUpdateTxContext(pThis, pDesc);
                 else
                     E1kLog(("%s e1kLocateTxPacket: ignoring a context descriptor in the middle of a packet, cbPacket=%d\n",
@@ -5369,5 +5369,5 @@
                     E1kLog(("%s e1kLocateTxPacket: ignoring a legacy descriptor in the segmentation context, cbPacket=%d\n",
                             pThis->szPrf, cbPacket));
-                    pDesc->legacy.dw3.fDD = true; /* Make sure it is skipped by processing */
+                    pThis->afTxDValid[i] = false; /* Make sure it is skipped by processing */
                     continue;
                 }
@@ -5384,5 +5384,5 @@
                     E1kLog(("%s e1kLocateTxPacket: ignoring %sTSE descriptor in the %ssegmentation context, cbPacket=%d\n",
                             pThis->szPrf, pDesc->data.cmd.fTSE ? "" : "non-", fTSE ? "" : "non-", cbPacket));
-                    pDesc->data.dw3.fDD = true; /* Make sure it is skipped by processing */
+                    pThis->afTxDValid[i] = false; /* Make sure it is skipped by processing */
                     continue;
                 }
@@ -5469,5 +5469,13 @@
         E1kLog3(("%s About to process new TX descriptor at %08x%08x, TDLEN=%08x, TDH=%08x, TDT=%08x\n",
                  pThis->szPrf, TDBAH, TDBAL + pTxdc->tdh * sizeof(E1KTXDESC), pTxdc->tdlen, pTxdc->tdh, pTxdc->tdt));
-        rc = e1kXmitDesc(pDevIns, pThis, pThisCC, pDesc, e1kDescAddr(TDBAH, TDBAL, pTxdc->tdh), fOnWorkerThread);
+        if (!pThis->afTxDValid[pThis->iTxDCurrent])
+        {
+            e1kPrintTDesc(pThis, pDesc, "vvv");
+            E1kLog(("%s e1kXmitDesc: skipping bad descriptor ^^^\n", pThis->szPrf));
+            e1kDescReport(pDevIns, pThis, pDesc, e1kDescAddr(TDBAH, TDBAL, pTxdc->tdh));
+            rc = VINF_SUCCESS;
+        }
+        else
+            rc = e1kXmitDesc(pDevIns, pThis, pThisCC, pDesc, e1kDescAddr(TDBAH, TDBAL, pTxdc->tdh), fOnWorkerThread);
         if (RT_FAILURE(rc))
             break;
