Changeset 39317 in vbox for trunk/src/VBox/Devices/Network
- Timestamp:
- Nov 15, 2011 8:33:56 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DevE1000.cpp
r39248 r39317 11 11 * 12 12 * @todo IPv6 checksum offloading support 13 * @todo VLAN checksum offloading support14 13 * @todo Flexible Filter / Wakeup (optional?) 15 14 */ … … 227 226 #define RCTL_BSIZE_SHIFT 16 228 227 #define RCTL_VFE 0x00040000 228 #define RCTL_CFIEN 0x00080000 229 #define RCTL_CFI 0x00100000 229 230 #define RCTL_BSEX 0x02000000 230 231 #define RCTL_SECRC 0x04000000 … … 611 612 612 613 614 #define E1K_SPEC_VLAN(s) (s & 0xFFF) 615 #define E1K_SPEC_CFI(s) (!!((s>>12) & 0x1)) 616 #define E1K_SPEC_PRI(s) ((s>>13) & 0x7) 617 613 618 struct E1kRxDStatus 614 619 { … … 635 640 /** @name Descriptor Special field (3.2.3.3) 636 641 * @{ */ 637 unsigned u12VLAN : 12; /**< VLAN identifier. */ 638 unsigned fCFI : 1; /**< Canonical form indicator (VLAN). */ 639 unsigned u3PRI : 3; /**< User priority (VLAN). */ 642 unsigned u16Special : 16; /**< VLAN: Id, Canonical form, Priority. */ 640 643 /** @} */ 641 644 }; … … 685 688 unsigned u8CSS : 8; 686 689 /* Special field*/ 687 unsigned u12VLAN : 12; 688 unsigned fCFI : 1; 689 unsigned u3PRI : 3; 690 unsigned u16Special: 16; 690 691 } dw3; 691 692 }; … … 801 802 * Requires fEOP, fVLE and CTRL.VME to be set. 802 803 * @{ */ 803 unsigned u12VLAN : 12; /**< VLAN identifier. */ 804 unsigned fCFI : 1; /**< Canonical form indicator (VLAN). */ 805 unsigned u3PRI : 3; /**< User priority (VLAN). */ 804 unsigned u16Special: 16; /**< VLAN: Id, Canonical form, Priority. */ 806 805 /** @} */ 807 806 } dw3; … … 888 887 889 888 /** The current Saved state version. */ 890 #define E1K_SAVEDSTATE_VERSION 2 889 #define E1K_SAVEDSTATE_VERSION 3 890 /** Saved state version for VirtualBox 4.1 and earlier. 891 * These did not include VLAN tag fields. */ 892 #define E1K_SAVEDSTATE_VERSION_VBOX_41 2 891 893 /** Saved state version for VirtualBox 3.0 and earlier. 892 894 * This did not include the configuration part nor the E1kEEPROM. */ … … 1028 1030 /** TX: TCP/UDP checksum has to be inserted if true. */ 1029 1031 bool fTCPcsum; 1032 /** TX: VLAN tag has to be inserted if true. */ 1033 bool fVTag; 1034 /** TX: TCI part of VLAN tag to be inserted. */ 1035 uint16_t u16VTagTCI; 1030 1036 /** TX TSE fallback: Number of payload bytes remaining in TSE context. */ 1031 1037 uint32_t u32PayRemain; … … 1038 1044 /** ?: Emulated controller type. */ 1039 1045 E1KCHIP eChip; 1040 uint32_t alignmentFix;1041 1046 1042 1047 /** EMT: EEPROM emulation */ … … 1640 1645 pDesc->status.fTCPE ? "TCPE" : "tcpe", 1641 1646 pDesc->status.fCE ? "CE" : "ce", 1642 pDesc->status.fCFI? "CFI" :"cfi",1643 pDesc->status.u12VLAN,1644 pDesc->status.u3PRI));1647 E1K_SPEC_CFI(pDesc->status.u16Special) ? "CFI" :"cfi", 1648 E1K_SPEC_VLAN(pDesc->status.u16Special), 1649 E1K_SPEC_PRI(pDesc->status.u16Special))); 1645 1650 } 1646 1651 … … 1692 1697 pDesc->data.dw3.fTXSM? " TXSM":"", 1693 1698 pDesc->data.dw3.fIXSM? " IXSM":"", 1694 pDesc->data.dw3.fCFI ? " CFI" :"",1695 pDesc->data.dw3.u12VLAN,1696 pDesc->data.dw3.u3PRI));1699 E1K_SPEC_CFI(pDesc->data.dw3.u16Special) ? "CFI" :"cfi", 1700 E1K_SPEC_VLAN(pDesc->data.dw3.u16Special), 1701 E1K_SPEC_PRI(pDesc->data.dw3.u16Special))); 1697 1702 break; 1698 1703 case E1K_DTYP_LEGACY: … … 1714 1719 pDesc->legacy.cmd.u8CSO, 1715 1720 pDesc->legacy.dw3.u8CSS, 1716 pDesc->legacy.dw3.fCFI ? " CFI" :"",1717 pDesc->legacy.dw3.u12VLAN,1718 pDesc->legacy.dw3.u3PRI));1721 E1K_SPEC_CFI(pDesc->legacy.dw3.u16Special) ? "CFI" :"cfi", 1722 E1K_SPEC_VLAN(pDesc->legacy.dw3.u16Special), 1723 E1K_SPEC_PRI(pDesc->legacy.dw3.u16Special))); 1719 1724 break; 1720 1725 default: … … 2014 2019 2015 2020 Assert(cb <= E1K_MAX_RX_PKT_SIZE); 2016 memcpy(rxPacket, pvBuf, cb); 2021 Assert(cb > 16); 2022 if (status.fVP && cb > 16) 2023 { 2024 uint16_t *u16Ptr = (uint16_t*)pvBuf; 2025 /* VLAN packet -- strip VLAN tag */ 2026 memcpy(rxPacket, pvBuf, 12); /* Copy src and dst addresses */ 2027 status.u16Special = RT_BE2H_U16(u16Ptr[7]); /* Extract VLAN tag */ 2028 memcpy(rxPacket + 12, (uint8_t*)pvBuf + 16, cb - 16); /* Copy the rest of the packet */ 2029 } 2030 else 2031 memcpy(rxPacket, pvBuf, cb); 2017 2032 /* Pad short packets */ 2018 2033 if (cb < 60) … … 2204 2219 if (value & CTRL_VME) 2205 2220 { 2206 E1kLog(("%s VLAN Mode is not supported yet!\n", INSTANCE(pState)));2221 E1kLog(("%s VLAN Mode Enabled\n", INSTANCE(pState))); 2207 2222 } 2208 2223 E1kLog(("%s e1kRegWriteCTRL: mdio dir=%s mdc dir=%s mdc=%s mdio=%d\n", … … 3177 3192 { 3178 3193 PPDMSCATTERGATHER pSg = pState->CTX_SUFF(pTxSg); 3179 uint32_t const cbFrame = pSg ? ( uint32_t)pSg->cbUsed: 0;3194 uint32_t const cbFrame = pSg ? ((uint32_t)pSg->cbUsed + (pState->fVTag ? 4 : 0)) : 0; 3180 3195 Assert(!pSg || pSg->cSegs == 1); 3181 3196 … … 3188 3203 pState->led.Asserted.s.fWriting = pState->led.Actual.s.fWriting = 1; 3189 3204 3205 /* Add VLAN tag */ 3206 if (cbFrame > 16 && pState->fVTag) 3207 { 3208 E1kLog3(("%s Inserting VLAN tag %08x\n", 3209 INSTANCE(pState), RT_BE2H_U16(VET) | (RT_BE2H_U16(pState->u16VTagTCI) << 16))); 3210 memmove((uint8_t*)pSg->aSegs[0].pvSeg + 16, (uint8_t*)pSg->aSegs[0].pvSeg + 12, cbFrame - 12); 3211 *((uint32_t*)pSg->aSegs[0].pvSeg + 3) = RT_BE2H_U16(VET) | (RT_BE2H_U16(pState->u16VTagTCI) << 16); 3212 } 3190 3213 /* Update the stats */ 3191 3214 E1K_INC_CNT32(TPT); … … 3617 3640 static void e1kXmitDesc(E1KSTATE* pState, E1KTXDESC* pDesc, RTGCPHYS addr, bool fOnWorkerThread) 3618 3641 { 3642 uint32_t cbVTag = 0; 3643 3619 3644 e1kPrintTDesc(pState, pDesc, "vvv"); 3620 3645 … … 3667 3692 3668 3693 /* 3694 * The last descriptor of non-TSE packet must contain VLE flag. 3695 * TSE packets have VLE flag in the first descriptor. The later 3696 * case is taken care of a bit later when cbVTag gets assigned. 3697 * 3698 * 1) pDesc->data.cmd.fEOP && !pDesc->data.cmd.fTSE 3699 */ 3700 if (pDesc->data.cmd.fEOP && !pDesc->data.cmd.fTSE) 3701 { 3702 pState->fVTag = pDesc->data.cmd.fVLE; 3703 pState->u16VTagTCI = pDesc->data.dw3.u16Special; 3704 } 3705 /* 3669 3706 * First fragment: Allocate new buffer and save the IXSM and TXSM 3670 3707 * packet options as these are only valid in the first fragment. … … 3677 3714 pState->fIPcsum ? " IP" : "", 3678 3715 pState->fTCPcsum ? " TCP/UDP" : "")); 3716 if (pDesc->data.cmd.fTSE) 3717 { 3718 /* 2) pDesc->data.cmd.fTSE && pState->u16TxPktLen == 0 */ 3719 pState->fVTag = pDesc->data.cmd.fVLE; 3720 pState->u16VTagTCI = pDesc->data.dw3.u16Special; 3721 cbVTag = pState->fVTag ? 4 : 0; 3722 } 3723 else if (pDesc->data.cmd.fEOP) 3724 cbVTag = pDesc->data.cmd.fVLE ? 4 : 0; 3725 else 3726 cbVTag = 4; 3727 E1kLog3(("%s About to allocate TX buffer: cbVTag=%u\n", INSTANCE(pState), cbVTag)); 3679 3728 if (e1kCanDoGso(&pState->GsoCtx, &pDesc->data, &pState->contextTSE)) 3680 e1kXmitAllocBuf(pState, pState->contextTSE.dw2.u20PAYLEN + pState->contextTSE.dw3.u8HDRLEN ,3729 e1kXmitAllocBuf(pState, pState->contextTSE.dw2.u20PAYLEN + pState->contextTSE.dw3.u8HDRLEN + cbVTag, 3681 3730 true /*fExactSize*/, true /*fGso*/); 3682 3731 else 3683 e1kXmitAllocBuf(pState, pState->contextTSE.dw3.u16MSS + pState->contextTSE.dw3.u8HDRLEN ,3732 e1kXmitAllocBuf(pState, pState->contextTSE.dw3.u16MSS + pState->contextTSE.dw3.u8HDRLEN + cbVTag, 3684 3733 pDesc->data.cmd.fTSE /*fExactSize*/, false /*fGso*/); 3685 3734 /** @todo Is there any way to indicating errors other than collisions? Like … … 3765 3814 /* First fragment: allocate new buffer. */ 3766 3815 if (pState->u16TxPktLen == 0) 3816 { 3817 if (pDesc->legacy.cmd.fEOP) 3818 cbVTag = pDesc->legacy.cmd.fVLE ? 4 : 0; 3819 else 3820 cbVTag = 4; 3821 E1kLog3(("%s About to allocate TX buffer: cbVTag=%u\n", INSTANCE(pState), cbVTag)); 3767 3822 /** @todo reset status bits? */ 3768 e1kXmitAllocBuf(pState, pDesc->legacy.cmd.u16Length , pDesc->legacy.cmd.fEOP, false /*fGso*/);3823 e1kXmitAllocBuf(pState, pDesc->legacy.cmd.u16Length + cbVTag, pDesc->legacy.cmd.fEOP, false /*fGso*/); 3769 3824 /** @todo Is there any way to indicating errors other than collisions? Like 3770 3825 * VERR_NET_DOWN. */ 3826 } 3771 3827 3772 3828 /* Add fragment to frame. */ … … 3778 3834 if (pDesc->legacy.cmd.fEOP) 3779 3835 { 3836 pState->fVTag = pDesc->legacy.cmd.fVLE; 3837 pState->u16VTagTCI = pDesc->legacy.dw3.u16Special; 3780 3838 /** @todo Offload processing goes here. */ 3781 3839 e1kTransmitFrame(pState, fOnWorkerThread); … … 4853 4911 } 4854 4912 4913 /* Is VLAN filtering enabled? */ 4914 if (RCTL & RCTL_VFE) 4915 { 4916 uint16_t *u16Ptr = (uint16_t*)pvBuf; 4917 /* Compare TPID with VLAN Ether Type */ 4918 if (RT_BE2H_U16(u16Ptr[6]) == VET) 4919 { 4920 pStatus->fVP = true; 4921 /* It is 802.1q packet indeed, let's filter by VID */ 4922 if (RCTL & RCTL_CFIEN) 4923 { 4924 E1kLog3(("%s VLAN filter: VLAN=%d CFI=%d RCTL_CFI=%d\n", INSTANCE(pState), 4925 E1K_SPEC_VLAN(RT_BE2H_U16(u16Ptr[7])), 4926 E1K_SPEC_CFI(RT_BE2H_U16(u16Ptr[7])), 4927 !!(RCTL & RCTL_CFI))); 4928 if (E1K_SPEC_CFI(RT_BE2H_U16(u16Ptr[7])) != !!(RCTL & RCTL_CFI)) 4929 { 4930 E1kLog2(("%s Packet filter: CFIs do not match in packet and RCTL (%d!=%d)\n", 4931 INSTANCE(pState), E1K_SPEC_CFI(RT_BE2H_U16(u16Ptr[7])), !!(RCTL & RCTL_CFI))); 4932 return false; 4933 } 4934 } 4935 else 4936 E1kLog3(("%s VLAN filter: VLAN=%d\n", INSTANCE(pState), 4937 E1K_SPEC_VLAN(RT_BE2H_U16(u16Ptr[7])))); 4938 if (!ASMBitTest(pState->auVFTA, E1K_SPEC_VLAN(RT_BE2H_U16(u16Ptr[7])))) 4939 { 4940 E1kLog2(("%s Packet filter: no VLAN match (id=%d)\n", 4941 INSTANCE(pState), E1K_SPEC_VLAN(RT_BE2H_U16(u16Ptr[7])))); 4942 return false; 4943 } 4944 } 4945 } 4855 4946 /* Broadcast filtering */ 4856 4947 if (e1kIsBroadcast(pvBuf) && (RCTL & RCTL_BAM)) … … 4885 4976 } 4886 4977 E1kLog2(("%s Packet filter: no perfect match\n", INSTANCE(pState))); 4887 }4888 /* Is VLAN filtering enabled? */4889 if (RCTL & RCTL_VFE)4890 {4891 uint16_t *u16Ptr = (uint16_t*)pvBuf;4892 /* Compare TPID with VLAN Ether Type */4893 if (u16Ptr[6] == VET)4894 {4895 pStatus->fVP = true;4896 /* It is 802.1q packet indeed, let's filter by VID */4897 if (ASMBitTest(pState->auVFTA, RT_BE2H_U16(u16Ptr[7]) & 0xFFF))4898 return true;4899 E1kLog2(("%s Packet filter: no VLAN match\n", INSTANCE(pState)));4900 }4901 4978 } 4902 4979 E1kLog2(("%s Packet filter: packet discarded\n", INSTANCE(pState))); … … 5176 5253 SSMR3PutMem(pSSM, &pState->contextTSE, sizeof(pState->contextTSE)); 5177 5254 SSMR3PutMem(pSSM, &pState->contextNormal, sizeof(pState->contextNormal)); 5255 SSMR3PutBool(pSSM, pState->fVTag); 5256 SSMR3PutU16(pSSM, pState->u16VTagTCI); 5178 5257 /**@todo GSO requires some more state here. */ 5179 5258 E1kLog(("%s State has been saved\n", INSTANCE(pState))); … … 5240 5319 5241 5320 if ( uVersion != E1K_SAVEDSTATE_VERSION 5321 && uVersion != E1K_SAVEDSTATE_VERSION_VBOX_41 5242 5322 && uVersion != E1K_SAVEDSTATE_VERSION_VBOX_30) 5243 5323 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION; … … 5288 5368 rc = SSMR3GetMem(pSSM, &pState->contextNormal, sizeof(pState->contextNormal)); 5289 5369 AssertRCReturn(rc, rc); 5290 5370 if (uVersion > E1K_SAVEDSTATE_VERSION_VBOX_41) 5371 { 5372 SSMR3GetBool(pSSM, &pState->fVTag); 5373 rc = SSMR3GetU16(pSSM, &pState->u16VTagTCI); 5374 AssertRCReturn(rc, rc); 5375 } 5376 else 5377 { 5378 pState->fVTag = false; 5379 pState->u16VTagTCI = 0; 5380 } 5291 5381 /* derived state */ 5292 5382 e1kSetupGsoCtx(&pState->GsoCtx, &pState->contextTSE); … … 5565 5655 { 5566 5656 E1KSTATE* pState = PDMINS_2_DATA(pDevIns, E1KSTATE*); 5567 unsigned 5568 bool fRcvRing = false;5569 bool fXmtRing = false;5657 unsigned i; 5658 // bool fRcvRing = false; 5659 // bool fXmtRing = false; 5570 5660 5571 5661 /* 5572 5662 * Parse args. 5573 */5574 5663 if (pszArgs) 5575 5664 { … … 5577 5666 fXmtRing = strstr(pszArgs, "verbose") || strstr(pszArgs, "xmt"); 5578 5667 } 5668 */ 5579 5669 5580 5670 /*
Note:
See TracChangeset
for help on using the changeset viewer.