[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH 2/2] Add header/data split support
Now that XENNET is using NDIS 6.1, implement header/data split. See NDIS documentation for more details. This requires using version 3 of the VIF interface from XENVIF to support the requirements for data MDL backfill. Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx> --- include/vif_interface.h | 48 ++++++++++++++++++++-- src/xennet.inf | 8 ++++ src/xennet/adapter.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++-- src/xennet/adapter.h | 13 ------ src/xennet/receiver.c | 82 ++++++++++++++++++++++++++++++------- src/xennet/receiver.h | 6 +++ 6 files changed, 229 insertions(+), 33 deletions(-) diff --git a/include/vif_interface.h b/include/vif_interface.h index d083fd1..e5f8534 100644 --- a/include/vif_interface.h +++ b/include/vif_interface.h @@ -564,6 +564,19 @@ typedef VOID IN XENVIF_VIF_OFFLOAD_OPTIONS Options ); +/*! \typedef XENVIF_VIF_RECEIVER_SET_BACKFILL_SIZE + \brief Set the required receive backfill size (free space before + packet payload). + + \param Interface The interface header + \param Size The required size +*/ +typedef VOID +(*XENVIF_VIF_RECEIVER_SET_BACKFILL_SIZE)( + IN PINTERFACE Interface, + IN ULONG Size + ); + /*! \typedef XENVIF_VIF_TRANSMITTER_QUERY_LARGE_PACKET_SIZE \brief Query the maximum size of packet containing a TCP large segment that can be handled by the transmit side @@ -760,7 +773,6 @@ struct _XENVIF_VIF_INTERFACE_V1 { XENVIF_VIF_MAC_QUERY_FILTER_LEVEL MacQueryFilterLevel; }; - /*! \struct _XENVIF_VIF_INTERFACE_V2 \brief VIF interface version 2 \ingroup interfaces @@ -790,7 +802,37 @@ struct _XENVIF_VIF_INTERFACE_V2 { XENVIF_VIF_MAC_QUERY_FILTER_LEVEL MacQueryFilterLevel; }; -typedef struct _XENVIF_VIF_INTERFACE_V2 XENVIF_VIF_INTERFACE, *PXENVIF_VIF_INTERFACE; +/*! \struct _XENVIF_VIF_INTERFACE_V3 + \brief VIF interface version 3 + \ingroup interfaces +*/ +struct _XENVIF_VIF_INTERFACE_V3 { + INTERFACE Interface; + XENVIF_VIF_ACQUIRE Acquire; + XENVIF_VIF_RELEASE Release; + XENVIF_VIF_ENABLE Enable; + XENVIF_VIF_DISABLE Disable; + XENVIF_VIF_QUERY_STATISTIC QueryStatistic; + XENVIF_VIF_RECEIVER_RETURN_PACKETS ReceiverReturnPackets; + XENVIF_VIF_RECEIVER_SET_OFFLOAD_OPTIONS ReceiverSetOffloadOptions; + XENVIF_VIF_RECEIVER_SET_BACKFILL_SIZE ReceiverSetBackfillSize; + XENVIF_VIF_RECEIVER_QUERY_RING_SIZE ReceiverQueryRingSize; + XENVIF_VIF_TRANSMITTER_GET_PACKET_HEADERS TransmitterGetPacketHeaders; + XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS_V2 TransmitterQueuePackets; + XENVIF_VIF_TRANSMITTER_QUERY_OFFLOAD_OPTIONS TransmitterQueryOffloadOptions; + XENVIF_VIF_TRANSMITTER_QUERY_LARGE_PACKET_SIZE TransmitterQueryLargePacketSize; + XENVIF_VIF_TRANSMITTER_QUERY_RING_SIZE TransmitterQueryRingSize; + XENVIF_VIF_MAC_QUERY_STATE MacQueryState; + XENVIF_VIF_MAC_QUERY_MAXIMUM_FRAME_SIZE MacQueryMaximumFrameSize; + XENVIF_VIF_MAC_QUERY_PERMANENT_ADDRESS MacQueryPermanentAddress; + XENVIF_VIF_MAC_QUERY_CURRENT_ADDRESS MacQueryCurrentAddress; + XENVIF_VIF_MAC_QUERY_MULTICAST_ADDRESSES MacQueryMulticastAddresses; + XENVIF_VIF_MAC_SET_MULTICAST_ADDRESSES MacSetMulticastAddresses; + XENVIF_VIF_MAC_SET_FILTER_LEVEL MacSetFilterLevel; + XENVIF_VIF_MAC_QUERY_FILTER_LEVEL MacQueryFilterLevel; +}; + +typedef struct _XENVIF_VIF_INTERFACE_V3 XENVIF_VIF_INTERFACE, *PXENVIF_VIF_INTERFACE; /*! \def XENVIF_VIF \brief Macro at assist in method invocation @@ -801,6 +843,6 @@ typedef struct _XENVIF_VIF_INTERFACE_V2 XENVIF_VIF_INTERFACE, *PXENVIF_VIF_INTER #endif // _WINDLL #define XENVIF_VIF_INTERFACE_VERSION_MIN 1 -#define XENVIF_VIF_INTERFACE_VERSION_MAX 2 +#define XENVIF_VIF_INTERFACE_VERSION_MAX 3 #endif // _XENVIF_INTERFACE_H diff --git a/src/xennet.inf b/src/xennet.inf index 7e9d9e6..5aa8c6c 100644 --- a/src/xennet.inf +++ b/src/xennet.inf @@ -159,6 +159,13 @@ HKR, Ndi\params\LROIPv6, Optional, 0, "0" HKR, Ndi\params\LROIPv6\enum, "0", 0, %Disabled% HKR, Ndi\params\LROIPv6\enum, "1", 0, %Enabled% +HKR, Ndi\params\*HeaderDataSplit, ParamDesc, 0, %HeaderDataSplit% +HKR, Ndi\params\*HeaderDataSplit, Type, 0, "enum" +HKR, Ndi\params\*HeaderDataSplit, Default, 0, "0" +HKR, Ndi\params\*HeaderDataSplit, Optional, 0, "0" +HKR, Ndi\params\*HeaderDataSplit\enum, "0", 0, %Disabled% +HKR, Ndi\params\*HeaderDataSplit\enum, "1", 0, %Enabled% + [XenNet_Inst.Services] AddService=xennet,0x02,XenNet_Service,XenNet_EventLog @@ -202,6 +209,7 @@ LSOV2IPv4="Large Send Offload V2 (IPv4)" LSOV2IPv6="Large Send Offload V2 (IPv6)" LROIPv4="Large Receive Offload (IPv4)" LROIPv6="Large Receive Offload (IPv6)" +HeaderDataSplit="Header Data Split" Disabled="Disabled" Enabled="Enabled" Enabled-Rx="Rx Enabled" diff --git a/src/xennet/adapter.c b/src/xennet/adapter.c index a1460c7..1e88754 100644 --- a/src/xennet/adapter.c +++ b/src/xennet/adapter.c @@ -44,6 +44,20 @@ #include "dbg_print.h" #include "assert.h" +typedef struct _PROPERTIES { + int ipv4_csum; + int tcpv4_csum; + int udpv4_csum; + int tcpv6_csum; + int udpv6_csum; + int need_csum_value; + int lsov4; + int lsov6; + int lrov4; + int lrov6; + ULONG HeaderDataSplit; +} PROPERTIES, *PPROPERTIES; + struct _XENNET_ADAPTER { XENVIF_VIF_INTERFACE VifInterface; XENBUS_CACHE_INTERFACE CacheInterface; @@ -115,6 +129,7 @@ static NDIS_OID XennetSupportedOids[] = OID_PNP_CAPABILITIES, OID_PNP_QUERY_POWER, OID_PNP_SET_POWER, + OID_GEN_HD_SPLIT_PARAMETERS, }; #define ADAPTER_POOL_TAG 'AteN' @@ -510,7 +525,6 @@ AdapterGetOffloadEncapsulation( TxOptions->OffloadIpVersion6UdpChecksum = 1; RxOptions = ReceiverOffloadOptions(Adapter->Receiver); - RxOptions->Value = 0; RxOptions->OffloadTagManipulation = 1; @@ -622,6 +636,18 @@ invalid_parameter: #undef CHANGE static NDIS_STATUS +AdapterGetHeaderDataSplitParameters( + IN PXENNET_ADAPTER Adapter, + IN PNDIS_HD_SPLIT_PARAMETERS Split + ) +{ + if (Split->HDSplitCombineFlags == NDIS_HD_SPLIT_COMBINE_ALL_HEADERS) + ReceiverSplitHeaderData(Adapter->Receiver, 0); + + return NDIS_STATUS_SUCCESS; +} + +static NDIS_STATUS AdapterQueryGeneralStatistics( IN PXENNET_ADAPTER Adapter, IN PNDIS_STATISTICS_INFO Info, @@ -1204,6 +1230,16 @@ AdapterSetInformation( } break; + case OID_GEN_HD_SPLIT_PARAMETERS: + BytesNeeded = sizeof(NDIS_HD_SPLIT_PARAMETERS); + if (BufferLength >= BytesNeeded) { + ndisStatus = AdapterGetHeaderDataSplitParameters(Adapter, + (PNDIS_HD_SPLIT_PARAMETERS)Buffer); + if (ndisStatus == NDIS_STATUS_SUCCESS) + BytesRead = sizeof(NDIS_HD_SPLIT_PARAMETERS); + } + break; + case OID_GEN_INTERRUPT_MODERATION: case OID_GEN_MACHINE_NAME: Warn = FALSE; @@ -1868,6 +1904,7 @@ AdapterGetAdvancedSettings( READ_PROPERTY(Adapter->Properties.lrov4, L"LROIPv4", 1, Handle); READ_PROPERTY(Adapter->Properties.lrov6, L"LROIPv6", 1, Handle); READ_PROPERTY(Adapter->Properties.need_csum_value, L"NeedChecksumValue", 1, Handle); + READ_PROPERTY(Adapter->Properties.HeaderDataSplit, L"*HeaderDataSplit", 1, Handle); NdisCloseConfiguration(Handle); @@ -2151,6 +2188,63 @@ AdapterSetOffloadAttributes( return ndisStatus; } +static NDIS_STATUS +AdapterSetHeaderDataSplitAttributes( + IN PXENNET_ADAPTER Adapter + ) +{ + NDIS_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES Attribs; + NDIS_HD_SPLIT_ATTRIBUTES Split; + NDIS_STATUS NdisStatus; + + RtlZeroMemory(&Attribs, sizeof(Attribs)); + + Attribs.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES; + Attribs.Header.Revision = NDIS_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES_REVISION_1; + Attribs.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES_REVISION_1; + + RtlZeroMemory(&Split, sizeof(Split)); + + Split.Header.Type = NDIS_OBJECT_TYPE_HD_SPLIT_ATTRIBUTES; + Split.Header.Revision = NDIS_HD_SPLIT_ATTRIBUTES_REVISION_1; + Split.Header.Size = NDIS_SIZEOF_HD_SPLIT_ATTRIBUTES_REVISION_1; + Split.HardwareCapabilities = + NDIS_HD_SPLIT_CAPS_SUPPORTS_HEADER_DATA_SPLIT | + NDIS_HD_SPLIT_CAPS_SUPPORTS_IPV4_OPTIONS | + NDIS_HD_SPLIT_CAPS_SUPPORTS_IPV6_EXTENSION_HEADERS | + NDIS_HD_SPLIT_CAPS_SUPPORTS_TCP_OPTIONS; + + if (Adapter->Properties.HeaderDataSplit != 0) + Split.CurrentCapabilities = Split.HardwareCapabilities; + + Attribs.HDSplitAttributes = &Split; + + NdisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle, + (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs); + if (NdisStatus != NDIS_STATUS_SUCCESS) + goto fail1; + + if (Split.HDSplitFlags == NDIS_HD_SPLIT_ENABLE_HEADER_DATA_SPLIT) { + ASSERT(Split.CurrentCapabilities & NDIS_HD_SPLIT_CAPS_SUPPORTS_HEADER_DATA_SPLIT); + + Info("BackfillSize = %u\n", Split.BackfillSize); + Info("MaxHeaderSize = %u\n", Split.MaxHeaderSize); + + XENVIF_VIF(ReceiverSetBackfillSize, + &Adapter->VifInterface, + Split.BackfillSize); + + ReceiverSplitHeaderData(Adapter->Receiver, Split.MaxHeaderSize); + } + + return NDIS_STATUS_SUCCESS; + +fail1: + Error("fail1 (%08x)\n", NdisStatus); + + return NdisStatus; +} + NDIS_STATUS AdapterInitialize( IN NDIS_HANDLE Handle, @@ -2235,6 +2329,10 @@ AdapterInitialize( if (ndisStatus != NDIS_STATUS_SUCCESS) goto fail11; + ndisStatus = AdapterSetHeaderDataSplitAttributes(*Adapter); + if (ndisStatus != NDIS_STATUS_SUCCESS) + goto fail12; + RtlZeroMemory(&Dma, sizeof(NDIS_SG_DMA_DESCRIPTION)); Dma.Header.Type = NDIS_OBJECT_TYPE_SG_DMA_DESCRIPTION; Dma.Header.Revision = NDIS_SG_DMA_DESCRIPTION_REVISION_1; @@ -2252,14 +2350,15 @@ AdapterInitialize( ndisStatus = AdapterEnable(*Adapter); if (ndisStatus != NDIS_STATUS_SUCCESS) - goto fail12; + goto fail13; return NDIS_STATUS_SUCCESS; -fail12: +fail13: if ((*Adapter)->NdisDmaHandle) NdisMDeregisterScatterGatherDma((*Adapter)->NdisDmaHandle); (*Adapter)->NdisDmaHandle = NULL; +fail12: fail11: fail10: fail9: diff --git a/src/xennet/adapter.h b/src/xennet/adapter.h index 042b863..3cc1d90 100644 --- a/src/xennet/adapter.h +++ b/src/xennet/adapter.h @@ -52,19 +52,6 @@ NDIS_PACKET_TYPE_BROADCAST | \ NDIS_PACKET_TYPE_PROMISCUOUS) -typedef struct _PROPERTIES { - int ipv4_csum; - int tcpv4_csum; - int udpv4_csum; - int tcpv6_csum; - int udpv6_csum; - int need_csum_value; - int lsov4; - int lsov6; - int lrov4; - int lrov6; -} PROPERTIES, *PPROPERTIES; - typedef struct _XENNET_ADAPTER XENNET_ADAPTER, *PXENNET_ADAPTER; extern NDIS_STATUS diff --git a/src/xennet/receiver.c b/src/xennet/receiver.c index 98da49b..17ab27f 100644 --- a/src/xennet/receiver.c +++ b/src/xennet/receiver.c @@ -29,9 +29,12 @@ * SUCH DAMAGE. */ +#include <ndis.h> +#include <util.h> +#include <tcpip.h> + #include "receiver.h" #include "adapter.h" -#include <util.h> #include "dbg_print.h" #include "assert.h" @@ -44,6 +47,7 @@ struct _XENNET_RECEIVER { LONG InNDIS; LONG InNDISMax; XENVIF_VIF_OFFLOAD_OPTIONS OffloadOptions; + ULONG MaxHeaderSize; }; #define RECEIVER_POOL_TAG 'RteN' @@ -166,15 +170,16 @@ __ReceiverReturnNetBufferLists( static PNET_BUFFER_LIST __ReceiverReceivePacket( - IN PXENNET_RECEIVER Receiver, - IN PMDL Mdl, - IN ULONG Offset, - IN ULONG Length, - IN XENVIF_PACKET_CHECKSUM_FLAGS Flags, - IN USHORT TagControlInformation + IN PXENNET_RECEIVER Receiver, + IN PMDL Mdl, + IN ULONG Offset, + IN ULONG Length, + IN XENVIF_PACKET_CHECKSUM_FLAGS Flags, + IN PXENVIF_PACKET_INFO Info ) { PNET_BUFFER_LIST NetBufferList; + PNET_BUFFER NetBuffer; NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO csumInfo; NetBufferList = __ReceiverAllocateNetBufferList(Receiver, @@ -184,6 +189,8 @@ __ReceiverReceivePacket( if (NetBufferList == NULL) goto fail1; + NetBuffer = NET_BUFFER_LIST_FIRST_NB(NetBufferList); + NetBufferList->SourceHandle = AdapterGetHandle(Receiver->Adapter); csumInfo.Value = 0; @@ -199,10 +206,10 @@ __ReceiverReceivePacket( NET_BUFFER_LIST_INFO(NetBufferList, TcpIpChecksumNetBufferListInfo) = (PVOID)(ULONG_PTR)csumInfo.Value; - if (TagControlInformation != 0) { + if (Info->TagControlInformation != 0) { NDIS_NET_BUFFER_LIST_8021Q_INFO Ieee8021QInfo; - UNPACK_TAG_CONTROL_INFORMATION(TagControlInformation, + UNPACK_TAG_CONTROL_INFORMATION(Info->TagControlInformation, Ieee8021QInfo.TagHeader.UserPriority, Ieee8021QInfo.TagHeader.CanonicalFormatId, Ieee8021QInfo.TagHeader.VlanId); @@ -213,6 +220,48 @@ __ReceiverReceivePacket( NET_BUFFER_LIST_INFO(NetBufferList, Ieee8021QNetBufferListInfo) = Ieee8021QInfo.Value; } + if (Info->IpHeader.Offset != 0) { + ULONG NblFlags; + PUCHAR InfoVa; + PIP_HEADER IpHeader; + NDIS_PHYSICAL_ADDRESS DataPhysicalAddress; + + NblFlags = NET_BUFFER_LIST_NBL_FLAGS(NetBufferList); + + InfoVa = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority); + ASSERT(InfoVa != NULL); + InfoVa += Offset; + + IpHeader = (PIP_HEADER)(InfoVa + Info->IpHeader.Offset); + + if (IpHeader->Version == 4) { + NblFlags |= NDIS_NBL_FLAGS_IS_IPV4; + } else { + ASSERT3U(IpHeader->Version, ==, 6); + NblFlags |= NDIS_NBL_FLAGS_IS_IPV6; + } + + if (Info->TcpHeader.Offset != 0) + NblFlags |= NDIS_NBL_FLAGS_IS_TCP; + else if (Info->UdpHeader.Offset != 0) + NblFlags |= NDIS_NBL_FLAGS_IS_UDP; + + if (Mdl->Next != NULL && Info->Length < Receiver->MaxHeaderSize) { + NblFlags |= NDIS_NBL_FLAGS_HD_SPLIT; + if (NblFlags & (NDIS_NBL_FLAGS_IS_TCP | NDIS_NBL_FLAGS_IS_UDP)) + NblFlags |= NDIS_NBL_FLAGS_SPLIT_AT_UPPER_LAYER_PROTOCOL_PAYLOAD; + else + NblFlags |= NDIS_NBL_FLAGS_SPLIT_AT_UPPER_LAYER_PROTOCOL_HEADER; + + DataPhysicalAddress.QuadPart = (ULONGLONG)MmGetMdlPfnArray(Mdl->Next)[0] << PAGE_SHIFT; + DataPhysicalAddress.QuadPart += Mdl->Next->ByteOffset; + + NET_BUFFER_DATA_PHYSICAL_ADDRESS(NetBuffer) = DataPhysicalAddress; + } + + NET_BUFFER_LIST_NBL_FLAGS(NetBufferList) = NblFlags; + } + return NetBufferList; fail2: @@ -394,7 +443,6 @@ again: ULONG Offset; ULONG Length; XENVIF_PACKET_CHECKSUM_FLAGS Flags; - USHORT TagControlInformation; PNET_BUFFER_LIST NetBufferList; if (!LowResources && @@ -411,12 +459,9 @@ again: Offset = Packet->Offset; Length = Packet->Length; Flags = Packet->Flags; - Info = Packet->Info; - TagControlInformation = Info->TagControlInformation; - - NetBufferList = __ReceiverReceivePacket(Receiver, Mdl, Offset, Length, Flags, TagControlInformation); + NetBufferList = __ReceiverReceivePacket(Receiver, Mdl, Offset, Length, Flags, Info); if (NetBufferList != NULL) { *TailNetBufferList = NetBufferList; @@ -454,3 +499,12 @@ ReceiverOffloadOptions( { return &Receiver->OffloadOptions; } + +VOID +ReceiverSplitHeaderData( + IN PXENNET_RECEIVER Receiver, + IN ULONG MaxHeaderSize + ) +{ + Receiver->MaxHeaderSize = MaxHeaderSize; +} diff --git a/src/xennet/receiver.h b/src/xennet/receiver.h index fb69b96..b2cc809 100644 --- a/src/xennet/receiver.h +++ b/src/xennet/receiver.h @@ -66,4 +66,10 @@ ReceiverOffloadOptions( IN PXENNET_RECEIVER Receiver ); +extern VOID +ReceiverSplitHeaderData( + IN PXENNET_RECEIVER Receiver, + IN ULONG MaxHeaderSize + ); + #endif // _XENNET_RECEIVER_H_ -- 2.1.1 _______________________________________________ win-pv-devel mailing list win-pv-devel@xxxxxxxxxxxxxxxxxxxx http://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |