Changeset 94274 in vbox for trunk/src/VBox/Devices/Network
- Timestamp:
- Mar 16, 2022 5:36:35 PM (3 years ago)
- svn:sync-xref-src-repo-rev:
- 150533
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DevE1000.cpp
r93115 r94274 776 776 #define E1K_DTYP_CONTEXT 0 777 777 #define E1K_DTYP_DATA 1 778 #define E1K_DTYP_INVALID 2 778 779 779 780 struct E1kTDLegacy … … 1710 1711 uint32_t tdh; 1711 1712 uint32_t tdt; 1713 uint8_t nextPacket; 1712 1714 }; 1713 1715 typedef struct E1kTxDContext E1KTXDC, *PE1KTXDC; … … 3719 3721 * @param pCtx The context descriptor. 3720 3722 */ 3721 DECLINLINE( void) e1kSetupGsoCtx(PPDMNETWORKGSO pGso, E1KTXCTX const *pCtx)3723 DECLINLINE(bool) e1kSetupGsoCtx(PPDMNETWORKGSO pGso, E1KTXCTX const *pCtx) 3722 3724 { 3723 3725 pGso->u8Type = PDMNETWORKGSOTYPE_INVALID; … … 3731 3733 { 3732 3734 E1kLog(("e1kSetupGsoCtx: IPCSS=%#x\n", pCtx->ip.u8CSS)); 3733 return ;3735 return false; 3734 3736 } 3735 3737 if (RT_UNLIKELY( pCtx->tu.u8CSS < (size_t)pCtx->ip.u8CSS + (pCtx->dw2.fIP ? RTNETIPV4_MIN_LEN : RTNETIPV6_MIN_LEN) )) 3736 3738 { 3737 3739 E1kLog(("e1kSetupGsoCtx: TUCSS=%#x\n", pCtx->tu.u8CSS)); 3738 return ;3740 return false; 3739 3741 } 3740 3742 if (RT_UNLIKELY( pCtx->dw2.fTCP … … 3743 3745 { 3744 3746 E1kLog(("e1kSetupGsoCtx: HDRLEN=%#x TCP=%d\n", pCtx->dw3.u8HDRLEN, pCtx->dw2.fTCP)); 3745 return ;3747 return false; 3746 3748 } 3747 3749 … … 3750 3752 { 3751 3753 E1kLog(("e1kSetupGsoCtx: TUCSE=%#x HDRLEN=%#x\n", pCtx->tu.u16CSE, pCtx->dw3.u8HDRLEN)); 3752 return ;3754 return false; 3753 3755 } 3754 3756 … … 3757 3759 { 3758 3760 E1kLog(("e1kSetupGsoCtx: IPCSO=%#x IPCSS=%#x\n", pCtx->ip.u8CSO, pCtx->ip.u8CSS)); 3759 return ;3761 return false; 3760 3762 } 3761 3763 … … 3767 3769 { 3768 3770 E1kLog(("e1kSetupGsoCtx: TUCSO=%#x TUCSS=%#x TCP=%d\n", pCtx->ip.u8CSO, pCtx->ip.u8CSS, pCtx->dw2.fTCP)); 3769 return ;3771 return false; 3770 3772 } 3771 3773 … … 3778 3780 E1kLog(("e1kSetupGsoCtx: HDRLEN(=%#x) + PAYLEN(=%#x) = %#x, max is %#x\n", 3779 3781 pCtx->dw3.u8HDRLEN, pCtx->dw2.u20PAYLEN, pCtx->dw3.u8HDRLEN + pCtx->dw2.u20PAYLEN, VBOX_MAX_GSO_SIZE)); 3780 return ;3782 return false; 3781 3783 } 3782 3784 … … 3815 3817 E1kLog2(("e1kSetupGsoCtx: mss=%#x hdr=%#x hdrseg=%#x hdr1=%#x hdr2=%#x %s\n", 3816 3818 pGso->cbMaxSeg, pGso->cbHdrsTotal, pGso->cbHdrsSeg, pGso->offHdr1, pGso->offHdr2, PDMNetGsoTypeName((PDMNETWORKGSOTYPE)pGso->u8Type) )); 3819 return PDMNetGsoIsValid(pGso, sizeof(*pGso), pGso->cbMaxSeg * 5); 3817 3820 } 3818 3821 … … 4178 4181 Assert(!pSg || pSg->cSegs == 1); 4179 4182 4183 if (cbFrame < 14) 4184 { 4185 Log(("%s Ignoring invalid frame (%u bytes)\n", pThis->szPrf, cbFrame)); 4186 return; 4187 } 4180 4188 if (cbFrame > 70) /* unqualified guess */ 4181 4189 pThis->led.Asserted.s.fWriting = pThis->led.Actual.s.fWriting = 1; … … 4203 4211 4204 4212 /* Add VLAN tag */ 4205 if (cbFrame > 12 && pThis->fVTag )4213 if (cbFrame > 12 && pThis->fVTag && pSg->cbUsed + 4 <= pSg->cbAvailable) 4206 4214 { 4207 4215 E1kLog3(("%s Inserting VLAN tag %08x\n", … … 5277 5285 { 5278 5286 E1kLog(("%s Empty legacy descriptor, skipped.\n", pThis->szPrf)); 5287 if (pDesc->data.cmd.fEOP) 5288 { 5289 e1kTransmitFrame(pDevIns, pThis, pThisCC, fOnWorkerThread); 5290 pThis->u16TxPktLen = 0; 5291 } 5279 5292 } 5280 5293 else … … 5325 5338 if (pDesc->context.dw2.fTSE) 5326 5339 { 5340 if (!e1kSetupGsoCtx(&pThis->GsoCtx, &pDesc->context)) 5341 { 5342 pThis->contextTSE.dw2.u4DTYP = E1K_DTYP_INVALID; 5343 return false; 5344 } 5327 5345 pThis->contextTSE = pDesc->context; 5328 5346 uint32_t cbMaxSegmentSize = pThis->contextTSE.dw3.u16MSS + pThis->contextTSE.dw3.u8HDRLEN + 4; /*VTAG*/ … … 5355 5373 } 5356 5374 5357 static bool e1kLocateTxPacket(PE1KSTATE pThis) 5375 enum E1kPacketType 5376 { 5377 E1K_PACKET_NONE = 0, 5378 E1K_PACKET_LEGACY, 5379 E1K_PACKET_NORMAL, 5380 E1K_PACKET_TSE 5381 }; 5382 5383 static int e1kLocateTxPacket(PE1KSTATE pThis, PE1KTXDC pTxdc) 5358 5384 { 5359 5385 LogFlow(("%s e1kLocateTxPacket: ENTER cbTxAlloc=%d\n", … … 5367 5393 } 5368 5394 5395 pThis->fGSO = false; 5396 pThis->fVTag = false; 5397 pThis->fIPcsum = false; 5398 pThis->fTCPcsum = false; 5399 pThis->u16TxPktLen = 0; 5400 5401 enum E1kPacketType packetType = E1K_PACKET_NONE; 5402 enum E1kPacketType expectedPacketType = E1K_PACKET_NONE; 5403 /* 5404 * Valid packets start with 1 or 0 context descriptors, followed by 1 or 5405 * more data descriptors of the same type: legacy, normal or TSE. Note 5406 * that legacy descriptors do not belong to neither normal nor segmentation 5407 * contexts rendering the sequence (context_descriptor, legacy_descriptor) 5408 * invalid, but the context descriptor will still be applied and the legacy 5409 * descriptor will be treated as the beginning of next packet. 5410 */ 5411 bool fInvalidPacket = false; 5369 5412 bool fTSE = false; 5370 5413 uint32_t cbPacket = 0; … … 5375 5418 { 5376 5419 E1KTXDESC *pDesc = &pThis->aTxDescriptors[i]; 5377 /* Assume the descriptor valid until proven otherwise. */ 5378 pThis->afTxDValid[i] = true; 5420 5379 5421 switch (e1kGetDescType(pDesc)) 5380 5422 { 5381 5423 case E1K_DTYP_CONTEXT: 5424 /* There can be only one context per packet. Each context descriptor starts a new packet. */ 5425 if (packetType != E1K_PACKET_NONE) 5426 { 5427 fInvalidPacket = true; 5428 break; 5429 } 5430 packetType = (pDesc->context.dw2.fTSE) ? E1K_PACKET_TSE : E1K_PACKET_NORMAL; 5382 5431 if (cbPacket == 0) 5383 5432 pThis->afTxDValid[i] = e1kUpdateTxContext(pThis, pDesc); … … 5387 5436 continue; 5388 5437 case E1K_DTYP_LEGACY: 5438 if (packetType != E1K_PACKET_NONE && packetType != E1K_PACKET_LEGACY) 5439 { 5440 fInvalidPacket = true; 5441 break; 5442 } 5443 packetType = E1K_PACKET_LEGACY; 5389 5444 /* Skip invalid descriptors. */ 5390 5445 if (cbPacket > 0 && (pThis->fGSO || fTSE)) … … 5392 5447 E1kLog(("%s e1kLocateTxPacket: ignoring a legacy descriptor in the segmentation context, cbPacket=%d\n", 5393 5448 pThis->szPrf, cbPacket)); 5394 pThis->afTxDValid[i] = false; /* Make sure it is skipped by processing */5395 5449 continue; 5396 5450 } 5451 pThis->afTxDValid[i] = true; /* Passed all checks, process it */ 5452 5397 5453 /* Skip empty descriptors. */ 5398 5454 if (!pDesc->legacy.u64BufAddr || !pDesc->legacy.cmd.u16Length) … … 5402 5458 break; 5403 5459 case E1K_DTYP_DATA: 5460 expectedPacketType = pDesc->data.cmd.fTSE ? E1K_PACKET_TSE : E1K_PACKET_NORMAL; 5461 if (packetType != E1K_PACKET_NONE && packetType != expectedPacketType) 5462 { 5463 fInvalidPacket = true; 5464 break; 5465 } 5404 5466 /* Skip invalid descriptors. */ 5467 if (pDesc->data.cmd.fTSE) 5468 { 5469 if (pThis->contextTSE.dw2.u4DTYP == E1K_DTYP_INVALID) 5470 { 5471 E1kLog(("%s e1kLocateTxPacket: ignoring TSE descriptor in invalid segmentation context, cbPacket=%d\n", 5472 pThis->szPrf, cbPacket)); 5473 continue; 5474 } 5475 } 5476 else /* !TSE */ 5477 { 5478 if (pThis->contextNormal.dw2.u4DTYP == E1K_DTYP_INVALID) 5479 { 5480 E1kLog(("%s e1kLocateTxPacket: ignoring non-TSE descriptor in invalid normal context, cbPacket=%d\n", 5481 pThis->szPrf, cbPacket)); 5482 continue; 5483 } 5484 } 5405 5485 if (cbPacket > 0 && (bool)pDesc->data.cmd.fTSE != fTSE) 5406 5486 { 5407 5487 E1kLog(("%s e1kLocateTxPacket: ignoring %sTSE descriptor in the %ssegmentation context, cbPacket=%d\n", 5408 5488 pThis->szPrf, pDesc->data.cmd.fTSE ? "" : "non-", fTSE ? "" : "non-", cbPacket)); 5409 pThis->afTxDValid[i] = false; /* Make sure it is skipped by processing */5410 5489 continue; 5411 5490 } 5491 pThis->afTxDValid[i] = true; /* Passed all checks, process it */ 5492 5412 5493 /* Skip empty descriptors. */ 5413 5494 if (!pDesc->data.u64BufAddr || !pDesc->data.cmd.u20DTALEN) … … 5439 5520 continue; 5440 5521 } 5522 if (fInvalidPacket) 5523 { 5524 for (int index = pThis->iTxDCurrent; index < i; ++index) 5525 pThis->afTxDValid[index] = false; /* Make sure all descriptors for this packet are skipped by processing */ 5526 LogFlow(("%s e1kLocateTxPacket: marked %d descriptors as invalid\n", pThis->szPrf, i - pThis->iTxDCurrent)); 5527 LogFlow(("%s e1kLocateTxPacket: RET true cbTxAlloc=%d cbPacket=%d%s%s\n", 5528 pThis->szPrf, pThis->cbTxAlloc, cbPacket, 5529 pThis->fGSO ? " GSO" : "", fTSE ? " TSE" : "")); 5530 pTxdc->nextPacket = i; 5531 return true; 5532 } 5441 5533 if (pDesc->legacy.cmd.fEOP) 5442 5534 { … … 5463 5555 pThis->szPrf, pThis->cbTxAlloc, cbPacket, 5464 5556 pThis->fGSO ? " GSO" : "", fTSE ? " TSE" : "")); 5557 pTxdc->nextPacket = i + 1; 5465 5558 return true; 5466 5559 } … … 5472 5565 LogFlow(("%s e1kLocateTxPacket: RET true cbTxAlloc=%d, zero packet!\n", 5473 5566 pThis->szPrf, pThis->cbTxAlloc)); 5567 pTxdc->nextPacket = pThis->nTxDFetched; 5474 5568 return true; 5475 5569 } … … 5487 5581 pThis->szPrf, pThis->iTxDCurrent, pThis->nTxDFetched)); 5488 5582 5489 while (pThis->iTxDCurrent < pT his->nTxDFetched)5583 while (pThis->iTxDCurrent < pTxdc->nextPacket && pThis->iTxDCurrent < pThis->nTxDFetched) 5490 5584 { 5491 5585 E1KTXDESC *pDesc = &pThis->aTxDescriptors[pThis->iTxDCurrent]; … … 5679 5773 while (fTxContextValid && !pThis->fLocked && e1kTxDLazyLoad(pDevIns, pThis, &txdc)) 5680 5774 { 5681 while (e1kLocateTxPacket(pThis ))5775 while (e1kLocateTxPacket(pThis, &txdc)) 5682 5776 { 5777 Log4(("%s e1kXmitPending: Located packet at %d. Next packet at %d\n", 5778 pThis->szPrf, pThis->iTxDCurrent, txdc.nextPacket)); 5683 5779 fIncomplete = false; 5684 5780 /* Found a complete packet, allocate it. */
Note:
See TracChangeset
for help on using the changeset viewer.