Changeset 31755 in vbox for trunk/src/VBox/Devices/Network
- Timestamp:
- Aug 18, 2010 12:01:40 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DevVirtioNet.cpp
r30219 r31755 19 19 #define LOG_GROUP LOG_GROUP_DEV_VIRTIO_NET 20 20 #define VNET_GC_SUPPORT 21 //#define VNET_WITH_GSO 21 22 22 23 #include <VBox/pdmdev.h> 23 24 #include <VBox/pdmnetifs.h> 24 25 #include <iprt/asm.h> 26 #include <iprt/net.h> 25 27 #include <iprt/semaphore.h> 26 28 #ifdef IN_RING3 … … 190 192 STAMCOUNTER StatReceiveBytes; 191 193 STAMCOUNTER StatTransmitBytes; 194 STAMCOUNTER StatReceiveGSO; 195 STAMCOUNTER StatTransmitPackets; 196 STAMCOUNTER StatTransmitGSO; 197 STAMCOUNTER StatTransmitCSum; 192 198 #if defined(VBOX_WITH_STATISTICS) 193 199 STAMPROFILE StatReceive; … … 205 211 #ifndef VBOX_DEVICE_STRUCT_TESTCASE 206 212 207 #define VNETHDR_GSO_NONE 0 213 #define VNETHDR_F_NEEDS_CSUM 1 // Use u16CSumStart, u16CSumOffset 214 215 #define VNETHDR_GSO_NONE 0 // Not a GSO frame 216 #define VNETHDR_GSO_TCPV4 1 // GSO frame, IPv4 TCP (TSO) 217 #define VNETHDR_GSO_UDP 3 // GSO frame, IPv4 UDP (UFO) 218 #define VNETHDR_GSO_TCPV6 4 // GSO frame, IPv6 TCP 219 #define VNETHDR_GSO_ECN 0x80 // TCP has ECN set 208 220 209 221 struct VNetHdr … … 304 316 | VNET_F_CTRL_VQ 305 317 | VNET_F_CTRL_RX 306 | VNET_F_CTRL_VLAN; 318 | VNET_F_CTRL_VLAN 319 #ifdef VNET_WITH_GSO 320 | VNET_F_CSUM 321 | VNET_F_HOST_TSO4 322 | VNET_F_HOST_TSO6 323 | VNET_F_HOST_UFO 324 #endif 325 ; 307 326 } 308 327 … … 831 850 Log(("%s Receive buffers has been added, waking up receive thread.\n", INSTANCE(pState))); 832 851 vnetWakeupReceive(pState->VPCI.CTX_SUFF(pDevIns)); 852 } 853 854 /** 855 * Sets up the GSO context according to the Virtio header. 856 * 857 * @param pGso The GSO context to setup. 858 * @param pCtx The context descriptor. 859 */ 860 DECLINLINE(PPDMNETWORKGSO) vnetSetupGsoCtx(PPDMNETWORKGSO pGso, VNETHDR const *pHdr) 861 { 862 pGso->u8Type = PDMNETWORKGSOTYPE_INVALID; 863 864 if (pHdr->u8GSOType & VNETHDR_GSO_ECN) 865 { 866 AssertMsgFailed(("Unsupported flag in virtio header: ECN\n")); 867 return NULL; 868 } 869 switch (pHdr->u8GSOType & ~VNETHDR_GSO_ECN) 870 { 871 case VNETHDR_GSO_TCPV4: 872 pGso->u8Type = PDMNETWORKGSOTYPE_IPV4_TCP; 873 break; 874 case VNETHDR_GSO_TCPV6: 875 pGso->u8Type = PDMNETWORKGSOTYPE_IPV6_TCP; 876 break; 877 case VNETHDR_GSO_UDP: 878 pGso->u8Type = PDMNETWORKGSOTYPE_IPV4_UDP; 879 break; 880 default: 881 return NULL; 882 } 883 if (pHdr->u8Flags & VNETHDR_F_NEEDS_CSUM) 884 pGso->offHdr2 = pHdr->u16CSumStart; 885 else 886 { 887 AssertMsgFailed(("GSO without checksum offloading!\n")); 888 return NULL; 889 } 890 pGso->offHdr1 = sizeof(RTNETETHERHDR); 891 pGso->cbHdrs = pHdr->u16HdrLen; 892 pGso->cbMaxSeg = pHdr->u16GSOSize; 893 return pGso; 894 } 895 896 DECLINLINE(uint16_t) vnetCSum16(const void *pvBuf, size_t cb) 897 { 898 uint32_t csum = 0; 899 uint16_t *pu16 = (uint16_t *)pvBuf; 900 901 while (cb > 1) 902 { 903 csum += *pu16++; 904 cb -= 2; 905 } 906 if (cb) 907 csum += *(uint8_t*)pu16; 908 while (csum >> 16) 909 csum = (csum >> 16) + (csum & 0xFFFF); 910 return ~csum; 911 } 912 913 DECLINLINE(void) vnetCompleteChecksum(uint8_t *pBuf, unsigned cbSize, uint16_t uStart, uint16_t uOffset) 914 { 915 *(uint16_t*)(pBuf + uStart + uOffset) = vnetCSum16(pBuf + uStart, cbSize - uStart); 833 916 } 834 917 … … 895 978 if (pState->pDrv) 896 979 { 980 VNETHDR Hdr; 981 PDMNETWORKGSO Gso, *pGso; 982 983 PDMDevHlpPhysRead(pState->VPCI.CTX_SUFF(pDevIns), elem.aSegsOut[0].addr, 984 &Hdr, sizeof(Hdr)); 985 986 STAM_REL_COUNTER_INC(&pState->StatTransmitPackets); 987 897 988 vnetPacketDump(pState, pState->pTxBuf, uOffset, "--> Outgoing"); 898 989 899 990 STAM_PROFILE_START(&pState->StatTransmitSend, a); 900 991 992 pGso = vnetSetupGsoCtx(&Gso, &Hdr); 993 if (pGso) 994 STAM_REL_COUNTER_INC(&pState->StatTransmitGSO); 995 else if (Hdr.u8Flags & VNETHDR_F_NEEDS_CSUM) 996 { 997 STAM_REL_COUNTER_INC(&pState->StatTransmitCSum); 998 /* 999 * This is not GSO frame but checksum offloading is requested. 1000 */ 1001 vnetCompleteChecksum(pState->pTxBuf, uOffset, Hdr.u16CSumStart, Hdr.u16CSumOffset); 1002 } 901 1003 /** @todo Optimize away the extra copying! (lazy bird) */ 902 1004 PPDMSCATTERGATHER pSgBuf; 903 int rc = pState->pDrv->pfnAllocBuf(pState->pDrv, uOffset, NULL /*pGso*/, &pSgBuf);1005 int rc = pState->pDrv->pfnAllocBuf(pState->pDrv, uOffset, pGso, &pSgBuf); 904 1006 if (RT_SUCCESS(rc)) 905 1007 { … … 1805 1907 AssertRC(rc); 1806 1908 1807 PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatReceiveBytes, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES, "Amount of data received", "/Devices/VNet%d/ReceiveBytes", iInstance); 1808 PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTransmitBytes, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES, "Amount of data transmitted", "/Devices/VNet%d/TransmitBytes", iInstance); 1909 PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatReceiveBytes, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES, "Amount of data received", "/Devices/VNet%d/Bytes/Receive", iInstance); 1910 PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTransmitBytes, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES, "Amount of data transmitted", "/Devices/VNet%d/Bytes/Transmit", iInstance); 1911 PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatReceiveGSO, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, "Number of received GSO packets", "/Devices/VNet%d/Packets/ReceiveGSO", iInstance); 1912 PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTransmitPackets, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, "Number of sent packets", "/Devices/VNet%d/Packets/Transmit", iInstance); 1913 PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTransmitGSO, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, "Number of sent GSO packets", "/Devices/VNet%d/Packets/Transmit-Gso", iInstance); 1914 PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTransmitCSum, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, "Number of completed TX checksums", "/Devices/VNet%d/Packets/Transmit-Csum", iInstance); 1809 1915 #if defined(VBOX_WITH_STATISTICS) 1810 1916 PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatReceive, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling receive", "/Devices/VNet%d/Receive/Total", iInstance);
Note:
See TracChangeset
for help on using the changeset viewer.