[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[win-pv-devel] [PATCH 4/4] Make use of batching support



XENVIF_VIF_INTERFACE version 7 adds support for batch indications on both
the transmit and receive side. This patch imports the updated interface
header and makes use of this new functionality.

Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
---
 include/vif_interface.h  |  56 +++++++++++++++++++--
 src/xennet.inf           |   6 +--
 src/xennet/adapter.c     |   3 ++
 src/xennet/receiver.c    | 126 +++++++++++++++++++++++++++++++++++------------
 src/xennet/receiver.h    |   1 +
 src/xennet/transmitter.c |  69 +++++++++++++-------------
 6 files changed, 189 insertions(+), 72 deletions(-)

diff --git a/include/vif_interface.h b/include/vif_interface.h
index 853554d..4a95989 100644
--- a/include/vif_interface.h
+++ b/include/vif_interface.h
@@ -391,6 +391,7 @@ typedef VOID
     \param TagControlInformation The VLAN TCI (used only if 
OffloadOptions.OffloadTagManipulation is set)
     \param Info Header information for the packet
     \param Hash Hash information for the packet
+    \param More A flag to indicate whether more packets will be queued for the 
same CPU
     \param Cookie Cookie that should be passed to 
XENVIF_RECEIVER_RETURN_PACKET method
 
     \b XENVIF_MAC_STATE_CHANGE:
@@ -527,6 +528,19 @@ typedef VOID
     IN  PVOID                       Cookie
     );
 
+typedef NTSTATUS
+(*XENVIF_VIF_TRANSMITTER_QUEUE_PACKET_V5)(
+    IN  PINTERFACE                  Interface,
+    IN  PMDL                        Mdl,
+    IN  ULONG                       Offset,
+    IN  ULONG                       Length,
+    IN  XENVIF_VIF_OFFLOAD_OPTIONS  OffloadOptions,
+    IN  USHORT                      MaximumSegmentSize,
+    IN  USHORT                      TagControlInformation,
+    IN  PXENVIF_PACKET_HASH         Hash,
+    IN  PVOID                       Cookie
+    );
+
 /*! \typedef XENVIF_VIF_TRANSMITTER_QUEUE_PACKET
     \brief Queue a packet at the provider's transmit side
 
@@ -538,6 +552,7 @@ typedef VOID
     \param MaximumSegmentSize The TCP MSS (used only if 
OffloadOptions.OffloadIpVersion[4|6]LargePacket is set)
     \param TagControlInformation The VLAN TCI (used only if 
OffloadOptions.OffloadTagManipulation is set)
     \param Hash Hash information for the packet
+    \param More A flag to indicate whether there will more packets queued with 
the same value of Hash
     \param Cookie A cookie specified by the caller that will be passed to the 
XENVIF_TRANSMITTER_RETURN_PACKET callback
 */
 typedef NTSTATUS
@@ -550,6 +565,7 @@ typedef NTSTATUS
     IN  USHORT                      MaximumSegmentSize,
     IN  USHORT                      TagControlInformation,
     IN  PXENVIF_PACKET_HASH         Hash,
+    IN  BOOLEAN                     More,
     IN  PVOID                       Cookie
     );
 
@@ -908,7 +924,7 @@ struct _XENVIF_VIF_INTERFACE_V5 {
     XENVIF_VIF_RECEIVER_SET_OFFLOAD_OPTIONS         ReceiverSetOffloadOptions;
     XENVIF_VIF_RECEIVER_SET_BACKFILL_SIZE           ReceiverSetBackfillSize;
     XENVIF_VIF_RECEIVER_QUERY_RING_SIZE             ReceiverQueryRingSize;
-    XENVIF_VIF_TRANSMITTER_QUEUE_PACKET             TransmitterQueuePacket;
+    XENVIF_VIF_TRANSMITTER_QUEUE_PACKET_V5          TransmitterQueuePacket;
     XENVIF_VIF_TRANSMITTER_QUERY_OFFLOAD_OPTIONS    
TransmitterQueryOffloadOptions;
     XENVIF_VIF_TRANSMITTER_QUERY_LARGE_PACKET_SIZE  
TransmitterQueryLargePacketSize;
     XENVIF_VIF_TRANSMITTER_QUERY_RING_SIZE          TransmitterQueryRingSize;
@@ -942,6 +958,40 @@ struct _XENVIF_VIF_INTERFACE_V6 {
     XENVIF_VIF_RECEIVER_SET_HASH_ALGORITHM          ReceiverSetHashAlgorithm;
     XENVIF_VIF_RECEIVER_QUERY_HASH_CAPABILITIES     
ReceiverQueryHashCapabilities;
     XENVIF_VIF_RECEIVER_UPDATE_HASH_PARAMETERS      
ReceiverUpdateHashParameters;
+    XENVIF_VIF_TRANSMITTER_QUEUE_PACKET_V5          TransmitterQueuePacket;
+    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;
+};
+
+/*! \struct _XENVIF_VIF_INTERFACE_V7
+    \brief VIF interface version 7
+    \ingroup interfaces
+*/
+struct _XENVIF_VIF_INTERFACE_V7 {
+    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_QUERY_RING_COUNT                     QueryRingCount;
+    XENVIF_VIF_UPDATE_HASH_MAPPING                  UpdateHashMapping;
+    XENVIF_VIF_RECEIVER_RETURN_PACKET               ReceiverReturnPacket;
+    XENVIF_VIF_RECEIVER_SET_OFFLOAD_OPTIONS         ReceiverSetOffloadOptions;
+    XENVIF_VIF_RECEIVER_SET_BACKFILL_SIZE           ReceiverSetBackfillSize;
+    XENVIF_VIF_RECEIVER_QUERY_RING_SIZE             ReceiverQueryRingSize;
+    XENVIF_VIF_RECEIVER_SET_HASH_ALGORITHM          ReceiverSetHashAlgorithm;
+    XENVIF_VIF_RECEIVER_QUERY_HASH_CAPABILITIES     
ReceiverQueryHashCapabilities;
+    XENVIF_VIF_RECEIVER_UPDATE_HASH_PARAMETERS      
ReceiverUpdateHashParameters;
     XENVIF_VIF_TRANSMITTER_QUEUE_PACKET             TransmitterQueuePacket;
     XENVIF_VIF_TRANSMITTER_QUERY_OFFLOAD_OPTIONS    
TransmitterQueryOffloadOptions;
     XENVIF_VIF_TRANSMITTER_QUERY_LARGE_PACKET_SIZE  
TransmitterQueryLargePacketSize;
@@ -956,7 +1006,7 @@ struct _XENVIF_VIF_INTERFACE_V6 {
     XENVIF_VIF_MAC_QUERY_FILTER_LEVEL               MacQueryFilterLevel;
 };
 
-typedef struct _XENVIF_VIF_INTERFACE_V6 XENVIF_VIF_INTERFACE, 
*PXENVIF_VIF_INTERFACE;
+typedef struct _XENVIF_VIF_INTERFACE_V7 XENVIF_VIF_INTERFACE, 
*PXENVIF_VIF_INTERFACE;
 
 /*! \def XENVIF_VIF
     \brief Macro at assist in method invocation
@@ -967,6 +1017,6 @@ typedef struct _XENVIF_VIF_INTERFACE_V6 
XENVIF_VIF_INTERFACE, *PXENVIF_VIF_INTER
 #endif  // _WINDLL
 
 #define XENVIF_VIF_INTERFACE_VERSION_MIN    2
-#define XENVIF_VIF_INTERFACE_VERSION_MAX    6
+#define XENVIF_VIF_INTERFACE_VERSION_MAX    7
 
 #endif  // _XENVIF_INTERFACE_H
diff --git a/src/xennet.inf b/src/xennet.inf
index 2b42c04..d50e6b3 100644
--- a/src/xennet.inf
+++ b/src/xennet.inf
@@ -61,9 +61,9 @@ 
xennet_coinst_@MAJOR_VERSION@_@MINOR_VERSION@_@MICRO_VERSION@_@BUILD_NUMBER@.dll
 ; DisplayName          Section         DeviceID
 ; -----------          -------         --------
 
-%XenNetName%           =XenNet_Inst,   
XENVIF\VEN_@VENDOR_PREFIX@@VENDOR_DEVICE_ID@&DEV_NET&REV_0800000B
-%XenNetName%           =XenNet_Inst,   
XENVIF\VEN_@VENDOR_PREFIX@0001&DEV_NET&REV_0800000B
-%XenNetName%           =XenNet_Inst,   
XENVIF\VEN_@VENDOR_PREFIX@0002&DEV_NET&REV_0800000B
+%XenNetName%           =XenNet_Inst,   
XENVIF\VEN_@VENDOR_PREFIX@@VENDOR_DEVICE_ID@&DEV_NET&REV_0800000C
+%XenNetName%           =XenNet_Inst,   
XENVIF\VEN_@VENDOR_PREFIX@0001&DEV_NET&REV_0800000C
+%XenNetName%           =XenNet_Inst,   
XENVIF\VEN_@VENDOR_PREFIX@0002&DEV_NET&REV_0800000C
 
 [XenNet_Inst] 
 Characteristics=0x84
diff --git a/src/xennet/adapter.c b/src/xennet/adapter.c
index 3c161e2..6587db4 100644
--- a/src/xennet/adapter.c
+++ b/src/xennet/adapter.c
@@ -228,6 +228,7 @@ AdapterVifCallback(
         USHORT                          TagControlInformation;
         PXENVIF_PACKET_INFO             Info;
         PXENVIF_PACKET_HASH             Hash;
+        BOOLEAN                         More;
         PVOID                           Cookie;
 
         Mdl = va_arg(Arguments, PMDL);
@@ -238,6 +239,7 @@ AdapterVifCallback(
         TagControlInformation = va_arg(Arguments, USHORT);
         Info = va_arg(Arguments, PXENVIF_PACKET_INFO);
         Hash = va_arg(Arguments, PXENVIF_PACKET_HASH);
+        More = va_arg(Arguments, BOOLEAN);
         Cookie = va_arg(Arguments, PVOID);
 
         ReceiverQueuePacket(Adapter->Receiver,
@@ -249,6 +251,7 @@ AdapterVifCallback(
                             TagControlInformation,
                             Info,
                             Hash,
+                            More,
                             Cookie);
         break;
     }
diff --git a/src/xennet/receiver.c b/src/xennet/receiver.c
index 693d1ac..b76dd9a 100644
--- a/src/xennet/receiver.c
+++ b/src/xennet/receiver.c
@@ -40,11 +40,18 @@
 #include "dbg_print.h"
 #include "assert.h"
 
+typedef struct _XENNET_RECEIVER_QUEUE {
+    PNET_BUFFER_LIST    Head;
+    PNET_BUFFER_LIST    Tail;
+    ULONG               Count;
+} XENNET_RECEIVER_QUEUE, *PXENNET_RECEIVER_QUEUE;
+
 struct _XENNET_RECEIVER {
     PXENNET_ADAPTER             Adapter;
     NDIS_HANDLE                 NetBufferListPool;
     PNET_BUFFER_LIST            PutList;
     PNET_BUFFER_LIST            GetList[HVM_MAX_VCPUS];
+    XENNET_RECEIVER_QUEUE       Queue[HVM_MAX_VCPUS];
     LONG                        InNDIS;
     XENVIF_VIF_OFFLOAD_OPTIONS  OffloadOptions;
 };
@@ -58,6 +65,52 @@ typedef struct _NET_BUFFER_LIST_RESERVED {
 
 C_ASSERT(sizeof (NET_BUFFER_LIST_RESERVED) <= RTL_FIELD_SIZE(NET_BUFFER_LIST, 
MiniportReserved));
 
+static FORCEINLINE PNET_BUFFER_LIST
+__ReceiverGetNetBufferList(
+    IN  PXENNET_RECEIVER    Receiver
+    )
+{
+    ULONG                   Index;
+    PNET_BUFFER_LIST        NetBufferList;
+
+    Index = KeGetCurrentProcessorNumberEx(NULL);
+
+    NetBufferList = Receiver->GetList[Index];
+
+    if (NetBufferList == NULL)
+        Receiver->GetList[Index] =
+            InterlockedExchangePointer(&Receiver->PutList, NULL);
+
+    NetBufferList = Receiver->GetList[Index];
+
+    if (NetBufferList == NULL)
+        return NULL;
+
+    Receiver->GetList[Index] = NET_BUFFER_LIST_NEXT_NBL(NetBufferList);
+    NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL;
+
+    return NetBufferList;
+}
+
+static FORCEINLINE VOID
+__ReceiverPutNetBufferList(
+    IN  PXENNET_RECEIVER    Receiver,
+    IN  PNET_BUFFER_LIST    NetBufferList
+    )
+{
+    PNET_BUFFER_LIST        Old;
+    PNET_BUFFER_LIST        New;
+
+    ASSERT3P(NET_BUFFER_LIST_NEXT_NBL(NetBufferList), ==, NULL);
+
+    do {
+        Old = Receiver->PutList;
+
+        NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = Old;
+        New = NetBufferList;
+    } while (InterlockedCompareExchangePointer(&Receiver->PutList, New, Old) 
!= Old);
+}
+
 static PNET_BUFFER_LIST
 __ReceiverAllocateNetBufferList(
     IN  PXENNET_RECEIVER        Receiver,
@@ -67,24 +120,15 @@ __ReceiverAllocateNetBufferList(
     IN  PVOID                   Cookie
     )
 {
-    ULONG                       Index;
     PNET_BUFFER_LIST            NetBufferList;
     PNET_BUFFER_LIST_RESERVED   ListReserved;
 
     ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL);
 
-    Index = KeGetCurrentProcessorNumberEx(NULL);
-
-    if (Receiver->GetList[Index] == NULL)
-        Receiver->GetList[Index] = 
InterlockedExchangePointer(&Receiver->PutList, NULL);
-
-    NetBufferList = Receiver->GetList[Index];
+    NetBufferList = __ReceiverGetNetBufferList(Receiver);
     if (NetBufferList != NULL) {
         PNET_BUFFER NetBuffer;
 
-        Receiver->GetList[Index] = NET_BUFFER_LIST_NEXT_NBL(NetBufferList);
-        NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL;
-
         NET_BUFFER_LIST_INFO(NetBufferList, TcpIpChecksumNetBufferListInfo) = 
NULL;
         NET_BUFFER_LIST_INFO(NetBufferList, Ieee8021QNetBufferListInfo) = NULL;
         NET_BUFFER_LIST_INFO(NetBufferList, NetBufferListHashInfo) = NULL;
@@ -129,21 +173,10 @@ __ReceiverReleaseNetBufferList(
     Cookie = ListReserved->Cookie;
     ListReserved->Cookie = NULL;
 
-    if (Cache) {
-        PNET_BUFFER_LIST    Old;
-        PNET_BUFFER_LIST    New;
-
-        ASSERT3P(NET_BUFFER_LIST_NEXT_NBL(NetBufferList), ==, NULL);
-
-        do {
-            Old = Receiver->PutList;
-
-            NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = Old;
-            New = NetBufferList;
-        } while (InterlockedCompareExchangePointer(&Receiver->PutList, New, 
Old) != Old);
-    } else {
+    if (Cache)
+        __ReceiverPutNetBufferList(Receiver, NetBufferList);
+    else
         NdisFreeNetBufferList(NetBufferList);
-    }
 
     return Cookie;
 }
@@ -272,24 +305,36 @@ fail1:
 }
 
 static VOID
-__ReceiverPushPacket(
+__ReceiverPushPackets(
     IN  PXENNET_RECEIVER    Receiver,
-    IN  PNET_BUFFER_LIST    NetBufferList
+    IN  ULONG               Index
     )
 {
     ULONG                   Flags;
     LONG                    InNDIS;
+    PXENNET_RECEIVER_QUEUE  Queue;
+    PNET_BUFFER_LIST        NetBufferList;
+    ULONG                   Count;
 
     InNDIS = InterlockedIncrement(&Receiver->InNDIS);
 
-    Flags = NDIS_RECEIVE_FLAGS_DISPATCH_LEVEL;
+    Flags = NDIS_RECEIVE_FLAGS_DISPATCH_LEVEL |
+            NDIS_RECEIVE_FLAGS_PERFECT_FILTERED;
+
     if (InNDIS > IN_NDIS_MAX)
         Flags |= NDIS_RECEIVE_FLAGS_RESOURCES;
 
+    Queue = &Receiver->Queue[Index];
+
+    NetBufferList = Queue->Head;
+    Count = Queue->Count;
+
+    RtlZeroMemory(Queue, sizeof (XENNET_RECEIVER_QUEUE));
+
     NdisMIndicateReceiveNetBufferLists(AdapterGetHandle(Receiver->Adapter),
                                        NetBufferList,
                                        NDIS_DEFAULT_PORT_NUMBER,
-                                       1,
+                                       Count,
                                        Flags);
 
     if (Flags & NDIS_RECEIVE_FLAGS_RESOURCES)
@@ -416,11 +461,14 @@ ReceiverQueuePacket(
     IN  USHORT                          TagControlInformation,
     IN  PXENVIF_PACKET_INFO             Info,
     IN  PXENVIF_PACKET_HASH             Hash,
+    IN  BOOLEAN                         More,
     IN  PVOID                           Cookie
     )
 {
     PXENVIF_VIF_INTERFACE               VifInterface;
     PNET_BUFFER_LIST                    NetBufferList;
+    ULONG                               Index;
+    PXENNET_RECEIVER_QUEUE              Queue;
 
     VifInterface = AdapterGetVifInterface(Receiver->Adapter);
 
@@ -434,14 +482,28 @@ ReceiverQueuePacket(
                                             Info,
                                             Hash,
                                             Cookie);
-
-    if (NetBufferList != NULL) {
-        __ReceiverPushPacket(Receiver, NetBufferList);
-    } else {
+    if (NetBufferList == NULL) {
         XENVIF_VIF(ReceiverReturnPacket,
                    VifInterface,
                    Cookie);
+        return;
     }
+
+    Index = KeGetCurrentProcessorNumberEx(NULL);
+
+    Queue = &Receiver->Queue[Index];
+
+    if (Queue->Head == NULL) {
+        ASSERT3U(Queue->Count, ==, 0);
+        Queue->Head = Queue->Tail = NetBufferList;
+    } else {
+        NET_BUFFER_LIST_NEXT_NBL(Queue->Tail) = NetBufferList;
+        Queue->Tail = NetBufferList;
+    }
+    Queue->Count++;
+
+    if (!More)
+        __ReceiverPushPackets(Receiver, Index);
 }
 
 PXENVIF_VIF_OFFLOAD_OPTIONS
diff --git a/src/xennet/receiver.h b/src/xennet/receiver.h
index 73ffc7e..e753095 100644
--- a/src/xennet/receiver.h
+++ b/src/xennet/receiver.h
@@ -66,6 +66,7 @@ ReceiverQueuePacket(
     IN  USHORT                          TagControlInformation,
     IN  PXENVIF_PACKET_INFO             Info,
     IN  PXENVIF_PACKET_HASH             Hash,
+    IN  BOOLEAN                         More,
     IN  PVOID                           Cookie
     );
 
diff --git a/src/xennet/transmitter.c b/src/xennet/transmitter.c
index 432198c..72f54ed 100644
--- a/src/xennet/transmitter.c
+++ b/src/xennet/transmitter.c
@@ -267,6 +267,7 @@ TransmitterSendNetBufferLists(
         XENVIF_VIF_OFFLOAD_OPTIONS  OffloadOptions;
         USHORT                      TagControlInformation;
         USHORT                      MaximumSegmentSize;
+        XENVIF_PACKET_HASH          Hash;
 
         ListNext = NET_BUFFER_LIST_NEXT_NBL(NetBufferList);
         NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL;
@@ -278,52 +279,51 @@ TransmitterSendNetBufferLists(
 
         OffloadOptions.Value &= Transmitter->OffloadOptions.Value;
 
-        ListReserved = 
(PNET_BUFFER_LIST_RESERVED)NET_BUFFER_LIST_MINIPORT_RESERVED(NetBufferList);
-        RtlZeroMemory(ListReserved, sizeof (NET_BUFFER_LIST_RESERVED));
+        switch (NET_BUFFER_LIST_GET_HASH_FUNCTION(NetBufferList)) {
+        case NdisHashFunctionToeplitz:
+            Hash.Algorithm = XENVIF_PACKET_HASH_ALGORITHM_TOEPLITZ;
+            break;
 
-        __TransmitterGetNetBufferList(Transmitter, NetBufferList);
+        default:
+            Hash.Algorithm = XENVIF_PACKET_HASH_ALGORITHM_NONE;
+            break;
+        }
 
-        NetBuffer = NET_BUFFER_LIST_FIRST_NB(NetBufferList);
-        while (NetBuffer != NULL) {
-            PNET_BUFFER         NetBufferListNext = 
NET_BUFFER_NEXT_NB(NetBuffer);
-            PVOID               Cookie = NetBufferList;
-            XENVIF_PACKET_HASH  Hash;
-            NTSTATUS            status;
+        switch (NET_BUFFER_LIST_GET_HASH_TYPE(NetBufferList)) {
+        case NDIS_HASH_IPV4:
+            Hash.Type = XENVIF_PACKET_HASH_TYPE_IPV4;
+            break;
 
-            __TransmitterGetNetBufferList(Transmitter, NetBufferList);
+        case NDIS_HASH_TCP_IPV4:
+            Hash.Type = XENVIF_PACKET_HASH_TYPE_IPV4_TCP;
+            break;
 
-            switch (NET_BUFFER_LIST_GET_HASH_FUNCTION(NetBufferList)) {
-            case NdisHashFunctionToeplitz:
-                Hash.Algorithm = XENVIF_PACKET_HASH_ALGORITHM_TOEPLITZ;
-                break;
+        case NDIS_HASH_IPV6:
+            Hash.Type = XENVIF_PACKET_HASH_TYPE_IPV6;
+            break;
 
-            default:
-                Hash.Algorithm = XENVIF_PACKET_HASH_ALGORITHM_NONE;
-                break;
-            }
+        case NDIS_HASH_TCP_IPV6:
+            Hash.Type = XENVIF_PACKET_HASH_TYPE_IPV6_TCP;
+            break;
 
-            switch (NET_BUFFER_LIST_GET_HASH_TYPE(NetBufferList)) {
-            case NDIS_HASH_IPV4:
-                Hash.Type = XENVIF_PACKET_HASH_TYPE_IPV4;
+        default:
                 break;
+        }
 
-            case NDIS_HASH_TCP_IPV4:
-                Hash.Type = XENVIF_PACKET_HASH_TYPE_IPV4_TCP;
-                break;
+        Hash.Value = NET_BUFFER_LIST_GET_HASH_VALUE(NetBufferList);
 
-            case NDIS_HASH_IPV6:
-                Hash.Type = XENVIF_PACKET_HASH_TYPE_IPV6;
-                break;
+        ListReserved = 
(PNET_BUFFER_LIST_RESERVED)NET_BUFFER_LIST_MINIPORT_RESERVED(NetBufferList);
+        RtlZeroMemory(ListReserved, sizeof (NET_BUFFER_LIST_RESERVED));
 
-            case NDIS_HASH_TCP_IPV6:
-                Hash.Type = XENVIF_PACKET_HASH_TYPE_IPV6_TCP;
-                break;
+        __TransmitterGetNetBufferList(Transmitter, NetBufferList);
 
-            default:
-                break;
-            }
+        NetBuffer = NET_BUFFER_LIST_FIRST_NB(NetBufferList);
+        while (NetBuffer != NULL) {
+            PNET_BUFFER         NetBufferListNext = 
NET_BUFFER_NEXT_NB(NetBuffer);
+            PVOID               Cookie = NetBufferList;
+            NTSTATUS            status;
 
-            Hash.Value = NET_BUFFER_LIST_GET_HASH_VALUE(NetBufferList);
+            __TransmitterGetNetBufferList(Transmitter, NetBufferList);
 
             status = XENVIF_VIF(TransmitterQueuePacket,
                                 AdapterGetVifInterface(Transmitter->Adapter),
@@ -334,6 +334,7 @@ TransmitterSendNetBufferLists(
                                 MaximumSegmentSize,
                                 TagControlInformation,
                                 &Hash,
+                                (NetBufferListNext != NULL) ? TRUE : FALSE,
                                 Cookie);
             if (!NT_SUCCESS(status)) {
                 __TransmitterReturnPacket(Transmitter, Cookie,
-- 
2.1.1


_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.