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

[win-pv-devel] [PATCH] Move to XENVIF VIF interface version 4



This means we can remove a lot of complexity and crucially we no longer
need to use the XENBUS_CACHE interface, which means we can avoid the race
introduced by commit 026aa32c "Make sure XENBUS interfaces are released
when going into S4".

Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
---
 include/cache_interface.h | 233 -----------------------
 include/vif_interface.h   | 300 +++++++++++++-----------------
 src/coinst/coinst.c       |   1 -
 src/xennet.inf            |   6 +-
 src/xennet/adapter.c      | 136 ++++++--------
 src/xennet/adapter.h      |   6 -
 src/xennet/receiver.c     | 242 ++++++++++--------------
 src/xennet/receiver.h     |  23 +--
 src/xennet/transmitter.c  | 456 +++++-----------------------------------------
 src/xennet/transmitter.h  |  17 +-
 10 files changed, 332 insertions(+), 1088 deletions(-)
 delete mode 100644 include/cache_interface.h

diff --git a/include/cache_interface.h b/include/cache_interface.h
deleted file mode 100644
index ac50a82..0000000
--- a/include/cache_interface.h
+++ /dev/null
@@ -1,233 +0,0 @@
-/* Copyright (c) Citrix Systems Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms,
- * with or without modification, are permitted provided
- * that the following conditions are met:
- *
- * *   Redistributions of source code must retain the above
- *     copyright notice, this list of conditions and the
- *     following disclaimer.
- * *   Redistributions in binary form must reproduce the above
- *     copyright notice, this list of conditions and the
- *     following disclaimer in the documentation and/or other
- *     materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*! \file cache_interface.h
-    \brief XENBUS CACHE Interface
-
-    This interface provides access to XENBUS's object cache
-    implementation.
-*/
-
-#ifndef _XENBUS_CACHE_INTERFACE_H
-#define _XENBUS_CACHE_INTERFACE_H
-
-#ifndef _WINDLL
-
-/*! \typedef XENBUS_CACHE
-    \brief Cache handle
-*/
-typedef struct _XENBUS_CACHE    XENBUS_CACHE, *PXENBUS_CACHE;
-
-/*! \typedef XENBUS_CACHE_ACQUIRE
-    \brief Acquire a reference to the CACHE interface
-
-    \param Interface The interface header
-*/
-typedef NTSTATUS
-(*XENBUS_CACHE_ACQUIRE)(
-    IN  PINTERFACE  Interface
-    );
-
-/*! \typedef XENBUS_CACHE_RELEASE
-    \brief Release a reference to the CACHE interface
-
-    \param Interface The interface header
-*/
-typedef VOID
-(*XENBUS_CACHE_RELEASE)(
-    IN  PINTERFACE  Interface
-    );
-
-/*! \typedef XENBUS_CACHE_CTOR
-    \brief Object creator callback
-
-    \param Argument Context \a Argument supplied to \a XENBUS_CACHE_CREATE
-    \param Object Newly allocated object
-
-    This callback is invoked just after a new object is allocated and may
-    be used to initialize any object data prior to its insertion into the
-    cache.
-*/
-typedef NTSTATUS
-(*XENBUS_CACHE_CTOR)(
-    IN  PVOID   Argument,
-    IN  PVOID   Object
-    );
-
-/*! \typedef XENBUS_CACHE_DTOR
-    \brief Object destructor callback
-
-    \param Argument Context \a Argument supplied to \a XENBUS_CACHE_CREATE
-    \param Object Object about to be freed
-
-    This callback is invoked just after an object is removed from the
-    cache and before it is freed and may be used to tear down any object data.
-*/
-typedef VOID
-(*XENBUS_CACHE_DTOR)(
-    IN  PVOID   Argument,
-    IN  PVOID   Object
-    );
-
-/*! \typedef XENBUS_CACHE_ACQUIRE_LOCK
-    \brief Cache lock callback
-
-    \param Argument Context \a Argument supplied to \a XENBUS_CACHE_CREATE
-
-    This callback is invoked if the cache implementation requires mutual
-    exclusion.
-*/
-typedef VOID
-(*XENBUS_CACHE_ACQUIRE_LOCK)(
-    IN  PVOID   Argument
-    );
-
-/*! \typedef XENBUS_CACHE_RELEASE_LOCK
-    \brief Cache unlock callback
-
-    \param Argument Context \a Argument supplied to \a XENBUS_CACHE_CREATE
-
-    This callback is invoked to release the mutual exclusion lock acquired
-    by a previous invocation of \a XENBUS_CACHE_ACQUIRE_LOCK.
-*/
-typedef VOID
-(*XENBUS_CACHE_RELEASE_LOCK)(
-    IN  PVOID   Argument
-    );
-
-/*! \typedef XENBUS_CACHE_CREATE
-    \brief Create a cache of objects of the given \a Size
-
-    \param Interface The interface header
-    \param Name A name for the cache which will be used in debug output
-    \param Size The size of each object in bytes
-    \param Reservation The target minimum population of the cache
-    \param Ctor A callback which is invoked when a new object created
-    \param Dtor A callback which is invoked when an object is destroyed
-    \param AcquireLock A callback invoked to acquire a spinlock
-    \param ReleaseLock A callback invoked to release the spinlock
-    \param Argument An optional context argument passed to the callbacks
-    \param Cache A pointer to a cache handle to be initialized
-
-    If a non-zero \a Reservation is specified then this method will fail
-    unless that number of objects can be immediately created.
-*/
-typedef NTSTATUS
-(*XENBUS_CACHE_CREATE)(
-    IN  PINTERFACE                  Interface,
-    IN  const CHAR                  *Name,
-    IN  ULONG                       Size,
-    IN  ULONG                       Reservation,
-    IN  XENBUS_CACHE_CTOR           Ctor,
-    IN  XENBUS_CACHE_DTOR           Dtor,
-    IN  XENBUS_CACHE_ACQUIRE_LOCK   AcquireLock,
-    IN  XENBUS_CACHE_RELEASE_LOCK   ReleaseLock,
-    IN  PVOID                       Argument OPTIONAL,
-    OUT PXENBUS_CACHE               *Cache
-    );
-
-/*! \typedef XENBUS_CACHE_GET
-    \brief Get an object from a \a Cache
-
-    \param Interface The interface header
-    \param Cache The cache handle
-    \param Locked If mutually exclusive access to the cache is already
-    guaranteed then set this to TRUE
-*/
-typedef PVOID
-(*XENBUS_CACHE_GET)(
-    IN  PINTERFACE      Interface,
-    IN  PXENBUS_CACHE   Cache,
-    IN  BOOLEAN         Locked
-    );
-
-/*! \typedef XENBUS_CACHE_PUT
-    \brief Return an object to a \a Cache
-
-    \param Interface The interface header
-    \param Cache The cache handle
-    \param Locked If mutually exclusive access to the cache is already
-    guaranteed then set this to TRUE
-*/
-typedef VOID
-(*XENBUS_CACHE_PUT)(
-    IN  PINTERFACE      Interface,
-    IN  PXENBUS_CACHE   Cache,
-    IN  PVOID           Object,
-    IN  BOOLEAN         Locked
-    );
-
-/*! \typedef XENBUS_CACHE_DESTROY
-    \brief Destroy a \a Cache
-
-    \param Interface The interface header
-    \param Cache The cache handle
-
-    All objects must have been returned to the cache prior to destruction
-*/
-typedef VOID
-(*XENBUS_CACHE_DESTROY)(
-    IN  PINTERFACE      Interface,
-    IN  PXENBUS_CACHE   Cache
-    );
-
-// {A98DFD78-416A-4949-92A5-E084F2F4B44E}
-DEFINE_GUID(GUID_XENBUS_CACHE_INTERFACE,
-0xa98dfd78, 0x416a, 0x4949, 0x92, 0xa5, 0xe0, 0x84, 0xf2, 0xf4, 0xb4, 0x4e);
-
-/*! \struct _XENBUS_CACHE_INTERFACE_V1
-    \brief CACHE interface version 1
-    \ingroup interfaces
-*/
-struct _XENBUS_CACHE_INTERFACE_V1 {
-    INTERFACE               Interface;
-    XENBUS_CACHE_ACQUIRE    CacheAcquire;
-    XENBUS_CACHE_RELEASE    CacheRelease;
-    XENBUS_CACHE_CREATE     CacheCreate;
-    XENBUS_CACHE_GET        CacheGet;
-    XENBUS_CACHE_PUT        CachePut;
-    XENBUS_CACHE_DESTROY    CacheDestroy;
-};
-
-typedef struct _XENBUS_CACHE_INTERFACE_V1 XENBUS_CACHE_INTERFACE, 
*PXENBUS_CACHE_INTERFACE;
-
-/*! \def XENBUS_CACHE
-    \brief Macro at assist in method invocation
-*/
-#define XENBUS_CACHE(_Method, _Interface, ...)    \
-    (_Interface)->Cache ## _Method((PINTERFACE)(_Interface), __VA_ARGS__)
-
-#endif  // _WINDLL
-
-#define XENBUS_CACHE_INTERFACE_VERSION_MIN  1
-#define XENBUS_CACHE_INTERFACE_VERSION_MAX  1
-
-#endif  // _XENBUS_CACHE_INTERFACE_H
diff --git a/include/vif_interface.h b/include/vif_interface.h
index e5f8534..27c5d2d 100644
--- a/include/vif_interface.h
+++ b/include/vif_interface.h
@@ -43,6 +43,28 @@
 #include <ifdef.h>
 #include <ethernet.h>
 
+/*! \enum _XENVIF_PACKET_HASH_ALGORITHM
+    \brief Hash algorithm
+*/
+typedef enum _XENVIF_PACKET_HASH_ALGORITHM {
+    /*! None (value should be ignored) */
+    XENVIF_PACKET_HASH_ALGORITHM_NONE = 0,
+    /*! Unspecified hash (value can be used) */
+    XENVIF_PACKET_HASH_ALGORITHM_UNSPECIFIED
+} XENVIF_PACKET_HASH_ALGORITHM, *PXENVIF_PACKET_HASH_ALGORITHM;
+
+/*! \struct _XENVIF_PACKET_HASH_V1
+    \brief Hash information
+*/
+struct _XENVIF_PACKET_HASH_V1 {
+    /*! Hash algorithm used to calculate value */
+    XENVIF_PACKET_HASH_ALGORITHM    Algorithm;
+    /*! Calculated value */
+    ULONG                           Value;
+};
+
+typedef struct _XENVIF_PACKET_HASH_V1 XENVIF_PACKET_HASH, *PXENVIF_PACKET_HASH;
+
 /*! \struct _XENVIF_PACKET_HEADER_V1
     \brief Packet header information
 */
@@ -53,14 +75,25 @@ struct  _XENVIF_PACKET_HEADER_V1 {
     ULONG   Length;
 };
 
-/*! \struct _XENVIF_PACKET_INFO_V1
+struct _XENVIF_PACKET_INFO_V1 {
+    ULONG                           Length;
+    USHORT                          TagControlInformation;
+    BOOLEAN                         IsAFragment;
+    struct _XENVIF_PACKET_HEADER_V1 EthernetHeader;
+    struct _XENVIF_PACKET_HEADER_V1 LLCSnapHeader;
+    struct _XENVIF_PACKET_HEADER_V1 IpHeader;
+    struct _XENVIF_PACKET_HEADER_V1 IpOptions;
+    struct _XENVIF_PACKET_HEADER_V1 TcpHeader;
+    struct _XENVIF_PACKET_HEADER_V1 TcpOptions;
+    struct _XENVIF_PACKET_HEADER_V1 UdpHeader;
+};
+
+/*! \struct _XENVIF_PACKET_INFO_V2
     \brief Packet information
 */
-struct _XENVIF_PACKET_INFO_V1 {
+struct _XENVIF_PACKET_INFO_V2 {
     /*! Total length of all headers */
     ULONG                           Length;
-    /*! VLAN TCI if present (0 indicates not present) */
-    USHORT                          TagControlInformation;
     /*! TRUE if the packet is an IP fragment */
     BOOLEAN                         IsAFragment;
     /*! Ethernet header (stripped of any VLAN tag) */
@@ -79,7 +112,7 @@ struct _XENVIF_PACKET_INFO_V1 {
     struct _XENVIF_PACKET_HEADER_V1 UdpHeader;
 };
 
-typedef struct _XENVIF_PACKET_INFO_V1   XENVIF_PACKET_INFO, 
*PXENVIF_PACKET_INFO;
+typedef struct _XENVIF_PACKET_INFO_V2   XENVIF_PACKET_INFO, 
*PXENVIF_PACKET_INFO;
 
 #pragma warning(push)
 #pragma warning(disable:4214)   // nonstandard extension used : bit field 
types other than int
@@ -120,32 +153,18 @@ typedef struct _XENVIF_PACKET_CHECKSUM_FLAGS_V1 
XENVIF_PACKET_CHECKSUM_FLAGS, *P
 
 #pragma warning(pop)
 
-/*! \struct _XENVIF_RECEIVER_PACKET_V1
-    \brief Receive-side packet structure
-*/
 struct _XENVIF_RECEIVER_PACKET_V1 {
-    /*! List entry used for chaining packets together */
     LIST_ENTRY                              ListEntry;
-    /*! Pointer to packet information */
     struct _XENVIF_PACKET_INFO_V1           *Info;
-    /*! Offset of start of packet in MDL */
     ULONG                                   Offset;
-    /*! Total length of packet */
     ULONG                                   Length;
-    /*! Checksum flags */
     struct _XENVIF_PACKET_CHECKSUM_FLAGS_V1 Flags;
-    /*! TCP MSS if the packet contains a TCP large segment */
     USHORT                                  MaximumSegmentSize;
-    /*! Opaque cookie used to store context information for packet return */
     PVOID                                   Cookie;
-    /*! MDL referencing the initial buffer of the packet */
     MDL                                     Mdl;
-    /*! PFN information, which must always follow an MDL */
     PFN_NUMBER                              __Pfn;
 };
 
-typedef struct _XENVIF_RECEIVER_PACKET_V1 XENVIF_RECEIVER_PACKET, 
*PXENVIF_RECEIVER_PACKET;
-
 #pragma warning(push)
 #pragma warning(disable:4214)   // nonstandard extension used : bit field 
types other than int
 #pragma warning(disable:4201)   // nonstandard extension used : nameless 
struct/union
@@ -190,32 +209,18 @@ typedef struct _XENVIF_VIF_OFFLOAD_OPTIONS_V1 
XENVIF_VIF_OFFLOAD_OPTIONS, *PXENV
 
 #pragma pack(push, 1) 
 
-/*! \struct _XENVIF_TRANSMITTER_PACKET_SEND_INFO_V1
-    \brief Packet information passed from subscriber to provider on
-    transmit side packet send
-
-    To fit into the reserved space in NDIS_PACKET and NET_BUFFER structures
-    this structure must be at most the size of 3 pointer types.
-*/
 struct _XENVIF_TRANSMITTER_PACKET_SEND_INFO_V1 {
-    /*! Offload options for this packet */
     XENVIF_VIF_OFFLOAD_OPTIONS  OffloadOptions;
-    /*! TCP MSS (used only if OffloadOptions.OffloadIpVersion[4|6]LargePacket 
is set) */
     USHORT                      MaximumSegmentSize;
-    /*! VLAN TCI (used only if OffloadOptions.OffloadTagManipulation is set) */
     USHORT                      TagControlInformation;
 };
 
-typedef struct _XENVIF_TRANSMITTER_PACKET_SEND_INFO_V1 
XENVIF_TRANSMITTER_PACKET_SEND_INFO, *PXENVIF_TRANSMITTER_PACKET_SEND_INFO;
-
 /*! \enum _XENVIF_TRANSMITTER_PACKET_STATUS
     \brief Transmit-side packet status
 */
 typedef enum _XENVIF_TRANSMITTER_PACKET_STATUS {
-    /*! Packet was queued for the backend */
-    XENVIF_TRANSMITTER_PACKET_PENDING = 1,
     /*! Packet has been successfully processed by the backend */
-    XENVIF_TRANSMITTER_PACKET_OK,
+    XENVIF_TRANSMITTER_PACKET_OK = 2,
     /*! Packet was dropped */
     XENVIF_TRANSMITTER_PACKET_DROPPED,
     /*! There was a problem handling the packet */
@@ -242,73 +247,19 @@ struct _XENVIF_TRANSMITTER_PACKET_COMPLETION_INFO_V1 {
 
 typedef struct _XENVIF_TRANSMITTER_PACKET_COMPLETION_INFO_V1 
XENVIF_TRANSMITTER_PACKET_COMPLETION_INFO, 
*PXENVIF_TRANSMITTER_PACKET_COMPLETION_INFO;
 
-#pragma warning(push)
-#pragma warning(disable:4201)   // nonstandard extension used : nameless 
struct/union
-
-/*! \struct _XENVIF_TRANSMITTER_PACKET_V1
-    \brief Transmit-side packet structure
-*/
-struct _XENVIF_TRANSMITTER_PACKET_V1 {
-    /*! Pointer used for chaining packets together */
-    struct _XENVIF_TRANSMITTER_PACKET_V1                        *Next;
-    union {
-        struct _XENVIF_TRANSMITTER_PACKET_SEND_INFO_V1          Send;
-        struct _XENVIF_TRANSMITTER_PACKET_COMPLETION_INFO_V1    Completion;
-    };
-};
-
-typedef struct _XENVIF_TRANSMITTER_PACKET_V1 XENVIF_TRANSMITTER_PACKET_V1, 
*PXENVIF_TRANSMITTER_PACKET_V1;
-
-#pragma warning(pop)
-
 #pragma pack(pop) 
 
-C_ASSERT(sizeof (struct _XENVIF_TRANSMITTER_PACKET_V1) <= (3 * sizeof 
(PVOID)));
-
-/*! \struct _XENVIF_TRANSMITTER_PACKET_V2
-    \brief Transmit-side packet structure (v2)
-*/
 struct _XENVIF_TRANSMITTER_PACKET_V2 {
-    /*! List entry used for chaining packets together */
-    LIST_ENTRY                                  ListEntry;
-    /*! Opaque cookie used to store context information for packet return */
-    PVOID                                       Cookie;
-    /*! Hash value set by subscriber */
-    ULONG                                       Value;
-    /*! Packet information passed from subscriber to provider */
-    XENVIF_TRANSMITTER_PACKET_SEND_INFO         Send;
-    /*! Packet information passed from provider to subscriber on packet return 
*/
-    XENVIF_TRANSMITTER_PACKET_COMPLETION_INFO   Completion;
-    /*! Packet data MDL */
-    PMDL                                        Mdl;
-    /*! Offset into MDL to start of packet */
-    ULONG                                       Offset;
-    /*! Packet length */
-    ULONG                                       Length;
+    LIST_ENTRY                                              ListEntry;
+    PVOID                                                   Cookie;
+    ULONG                                                   Value;
+    struct _XENVIF_TRANSMITTER_PACKET_SEND_INFO_V1          Send;
+    struct _XENVIF_TRANSMITTER_PACKET_COMPLETION_INFO_V1    Completion;
+    PMDL                                                    Mdl;
+    ULONG                                                   Offset;
+    ULONG                                                   Length;
 };
 
-typedef struct _XENVIF_TRANSMITTER_PACKET_V2 XENVIF_TRANSMITTER_PACKET, 
*PXENVIF_TRANSMITTER_PACKET;
-
-/*! \enum _XENVIF_TRANSMITTER_PACKET_OFFSET
-    \brief Offsets of packet metadata relative to
-    XENVIF_TRANSMITTER_PACKET pointer
-
-    Because the transmit side packet structure is limited to 3 pointer
-    types in size, not all information about the packet can be passed in
-    the structure. Other information can, however, be found by applying
-    these byte offsets to the structure pointer and then dereferencing the
-    specified type.
-*/
-typedef enum _XENVIF_TRANSMITTER_PACKET_OFFSET {
-    /*! The offset of the start of the packet within the MDL (type ULONG) */
-    XENVIF_TRANSMITTER_PACKET_OFFSET_OFFSET = 0,
-    /*! The total length of the packet (type ULONG) */
-    XENVIF_TRANSMITTER_PACKET_LENGTH_OFFSET,
-    /*! MDL referencing the initial buffer of the packet (type PMDL) */
-    XENVIF_TRANSMITTER_PACKET_MDL_OFFSET,
-    XENVIF_TRANSMITTER_PACKET_OFFSET_COUNT
-} XENVIF_TRANSMITTER_PACKET_OFFSET, *PXENVIF_TRANSMITTER_PACKET_OFFSET;
-
 /*! \enum _XENVIF_VIF_STATISTIC
     \brief Interface statistics
 */
@@ -368,10 +319,10 @@ typedef enum _XENVIF_MAC_FILTER_LEVEL {
     \brief Type of callback (see \ref XENVIF_VIF_CALLBACK)
 */
 typedef enum _XENVIF_VIF_CALLBACK_TYPE {
-    /*! Return transmit side packets to the subscriber */
-    XENVIF_TRANSMITTER_RETURN_PACKETS = 0,
-    /*! Queue receive side packets at the subscriber */
-    XENVIF_RECEIVER_QUEUE_PACKETS,
+    /*! Return a transmit side packet to the subscriber */
+    XENVIF_TRANSMITTER_RETURN_PACKET = 0,
+    /*! Queue a receive side packet at the subscriber */
+    XENVIF_RECEIVER_QUEUE_PACKET,
     /*! Notify the subscriber of a MAC (link) state has change */
     XENVIF_MAC_STATE_CHANGE
 } XENVIF_VIF_CALLBACK_TYPE, *PXENVIF_VIF_CALLBACK_TYPE;
@@ -403,11 +354,19 @@ typedef VOID
     \param Type The callback type
     \param ... Additional paramaters required by \a Type
 
-    \b XENVIF_TRANSMITTER_RETURN_PACKETS:
-    \param Head The head of a chain of XENVIF_TRANSMITTER_PACKET
+    \b XENVIF_TRANSMITTER_RETURN_PACKET:
+    \param Cookie Cookie supplied to XENVIF_TRANSMITTER_QUEUE_PACKET
+    \param Completion Packet completion information
 
-    \b XENVIF_RECEIVER_QUEUE_PACKETS:
-    \param List List of XENVIF_TRANSMITTER_PACKET
+    \b XENVIF_RECEIVER_QUEUE_PACKET:
+    \param Mdl The initial MDL of the packet
+    \param Offset The offset of the packet data in the initial MDL
+    \param Length The total length of the packet
+    \param Flags Packet checksum flags
+    \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 Info Header information for the packet
+    \param Cookie Cookie that should be passed to 
XENVIF_RECEIVER_RETURN_PACKET method
 
     \b XENVIF_MAC_STATE_CHANGE:
     No additional arguments
@@ -468,74 +427,63 @@ typedef NTSTATUS
     OUT PULONGLONG              Value
     );
 
-/*! \typedef XENVIF_VIF_RECEIVER_RETURN_PACKETS
-    \brief Return packets queues for receive by \ref XENVIF_VIF_CALLBACK
-    (Type = \ref XENVIF_RECEIVER_QUEUE_PACKETS)
-
-    \param Interface The interface header
-    \param List List of \ref _XENVIF_RECEIVER_PACKET_V1
-*/
 typedef VOID
-(*XENVIF_VIF_RECEIVER_RETURN_PACKETS)(
+(*XENVIF_VIF_RECEIVER_RETURN_PACKETS_V1)(
     IN  PINTERFACE  Interface,
     IN  PLIST_ENTRY List
     );
 
-/*! \typedef XENVIF_VIF_TRANSMITTER_SET_PACKET_OFFSET
-    \brief Set byte offset of packet information relative to
-    XENVIF_TRANSMITTER_PACKET pointer.
-
-    See \ref _XENVIF_TRANSMITTER_PACKET_OFFSET.
+/*! \typedef XENVIF_VIF_RECEIVER_RETURN_PACKET
+    \brief Return packets queued for receive by \ref XENVIF_VIF_CALLBACK
+    (Type = \ref XENVIF_RECEIVER_QUEUE_PACKET)
 
     \param Interface The interface header
-    \param Type The offset type
-    \param Value The offset value
+    \param Cookie Cookie passed to XENVIF_RECEIVER_QUEUE_PACKET callback
 */
-typedef NTSTATUS
-(*XENVIF_VIF_TRANSMITTER_SET_PACKET_OFFSET)(
-    IN  PINTERFACE                          Interface,
-    IN  XENVIF_TRANSMITTER_PACKET_OFFSET    Type,
-    IN  LONG_PTR                            Value
+typedef VOID
+(*XENVIF_VIF_RECEIVER_RETURN_PACKET)(
+    IN  PINTERFACE  Interface,
+    IN  PVOID       Cookie
     );
 
-/*! \typedef XENVIF_VIF_TRANSMITTER_GET_PACKET_HEADERS
-    \brief Get the packet headers into supplied buffer
-
-    \param Interface The interface header
-    \param Packet The packet to acquire headers for.
-    \param Headers The buffer to receive headers.
-    \param Info The offsets into Headers for relevant headers
-*/
 typedef NTSTATUS
-(*XENVIF_VIF_TRANSMITTER_GET_PACKET_HEADERS)(
-    IN  PINTERFACE                  Interface,
-    IN  PXENVIF_TRANSMITTER_PACKET  Packet,
-    OUT PVOID                       Headers,
-    OUT PXENVIF_PACKET_INFO         Info
+(*XENVIF_VIF_TRANSMITTER_GET_PACKET_HEADERS_V2)(
+    IN  PINTERFACE                              Interface,
+    IN  struct _XENVIF_TRANSMITTER_PACKET_V2    *Packet,
+    OUT PVOID                                   Headers,
+    OUT PXENVIF_PACKET_INFO                     Info
     );
 
-/*! \typedef XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS
-    \brief Queue transmit side packets at the provider
-
-    \param Interface The interface header
-    \param Head The head of a chain of _XENVIF_TRANSMITTER_PACKET_V1
-*/
 typedef NTSTATUS
-(*XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS)(
-    IN  PINTERFACE                      Interface,
-    IN  PXENVIF_TRANSMITTER_PACKET_V1   Head
+(*XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS_V2)(
+    IN  PINTERFACE  Interface,
+    IN  PLIST_ENTRY List
     );
 
-/*! \typedef XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS_V2
-    \brief Queue transmit side packets at the provider
+/*! \typedef XENVIF_VIF_TRANSMITTER_QUEUE_PACKET
+    \brief Queue a packet at the provider's transmit side
 
     \param Interface The interface header
-    \param List List of _XENVIF_TRANSMITTER_PACKET_V2
+    \param Mdl The initial MDL of the packet
+    \param Offset The offset of the packet data in the initial MDL
+    \param Length The total length of the packet
+    \param OffloadOptions The requested offload options for this packet
+    \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 Cookie A cookie specified by the caller that will be passed to the 
XENVIF_TRANSMITTER_RETURN_PACKET callback
 */
-typedef NTSTATUS
-(*XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS_V2)(
-    IN  PINTERFACE  Interface,
-    IN  PLIST_ENTRY List
+typedef VOID
+(*XENVIF_VIF_TRANSMITTER_QUEUE_PACKET)(
+    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_QUERY_OFFLOAD_OPTIONS
@@ -594,7 +542,7 @@ typedef VOID
 
 /*! \typedef XENVIF_VIF_TRANSMITTER_QUERY_RING_SIZE
     \brief Query the maximum number of transmit side packets that can
-    be queued in the shared ring between frontend and backend
+    be queued in each shared ring between frontend and backend
 
     \param Interface The interface header
     \param Size Buffer to receive the maximum number of packets
@@ -607,7 +555,7 @@ typedef VOID
 
 /*! \typedef XENVIF_VIF_RECEIVER_QUERY_RING_SIZE
     \brief Query the maximum number of receive side packets that can
-    be queued in the shared ring between backend and frontend
+    be queued in each shared ring between backend and frontend
 
     \param Interface The interface header
     \param Size Buffer to receive the maximum number of packets
@@ -744,22 +692,22 @@ typedef NTSTATUS
 DEFINE_GUID(GUID_XENVIF_VIF_INTERFACE, 
 0x76f279cd, 0xca11, 0x418b, 0x92, 0xe8, 0xc5, 0x7f, 0x77, 0xde, 0xe, 0x2e);
 
-/*! \struct _XENVIF_VIF_INTERFACE_V1
-    \brief VIF interface version 1
+/*! \struct _XENVIF_VIF_INTERFACE_V2
+    \brief VIF interface version 2
     \ingroup interfaces
 */
-struct _XENVIF_VIF_INTERFACE_V1 {
+struct _XENVIF_VIF_INTERFACE_V2 {
     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_RETURN_PACKETS_V1           
ReceiverReturnPacketsVersion1;
     XENVIF_VIF_RECEIVER_SET_OFFLOAD_OPTIONS         ReceiverSetOffloadOptions;
     XENVIF_VIF_RECEIVER_QUERY_RING_SIZE             ReceiverQueryRingSize;
-    XENVIF_VIF_TRANSMITTER_SET_PACKET_OFFSET        TransmitterSetPacketOffset;
-    XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS            TransmitterQueuePackets;
+    XENVIF_VIF_TRANSMITTER_GET_PACKET_HEADERS_V2    
TransmitterGetPacketHeadersVersion2;
+    XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS_V2         
TransmitterQueuePacketsVersion2;
     XENVIF_VIF_TRANSMITTER_QUERY_OFFLOAD_OPTIONS    
TransmitterQueryOffloadOptions;
     XENVIF_VIF_TRANSMITTER_QUERY_LARGE_PACKET_SIZE  
TransmitterQueryLargePacketSize;
     XENVIF_VIF_TRANSMITTER_QUERY_RING_SIZE          TransmitterQueryRingSize;
@@ -773,22 +721,23 @@ struct _XENVIF_VIF_INTERFACE_V1 {
     XENVIF_VIF_MAC_QUERY_FILTER_LEVEL               MacQueryFilterLevel;
 };
 
-/*! \struct _XENVIF_VIF_INTERFACE_V2
-    \brief VIF interface version 2
+/*! \struct _XENVIF_VIF_INTERFACE_V3
+    \brief VIF interface version 3
     \ingroup interfaces
 */
-struct _XENVIF_VIF_INTERFACE_V2 {
+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_RETURN_PACKETS_V1           
ReceiverReturnPacketsVersion1;
     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_GET_PACKET_HEADERS_V2    
TransmitterGetPacketHeadersVersion2;
+    XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS_V2         
TransmitterQueuePacketsVersion2;
     XENVIF_VIF_TRANSMITTER_QUERY_OFFLOAD_OPTIONS    
TransmitterQueryOffloadOptions;
     XENVIF_VIF_TRANSMITTER_QUERY_LARGE_PACKET_SIZE  
TransmitterQueryLargePacketSize;
     XENVIF_VIF_TRANSMITTER_QUERY_RING_SIZE          TransmitterQueryRingSize;
@@ -802,23 +751,22 @@ struct _XENVIF_VIF_INTERFACE_V2 {
     XENVIF_VIF_MAC_QUERY_FILTER_LEVEL               MacQueryFilterLevel;
 };
 
-/*! \struct _XENVIF_VIF_INTERFACE_V3
-    \brief VIF interface version 3
+/*! \struct _XENVIF_VIF_INTERFACE_V4
+    \brief VIF interface version 4
     \ingroup interfaces
 */
-struct _XENVIF_VIF_INTERFACE_V3 {
+struct _XENVIF_VIF_INTERFACE_V4 {
     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_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_TRANSMITTER_GET_PACKET_HEADERS       
TransmitterGetPacketHeaders;
-    XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS_V2         TransmitterQueuePackets;
+    XENVIF_VIF_TRANSMITTER_QUEUE_PACKET             TransmitterQueuePacket;
     XENVIF_VIF_TRANSMITTER_QUERY_OFFLOAD_OPTIONS    
TransmitterQueryOffloadOptions;
     XENVIF_VIF_TRANSMITTER_QUERY_LARGE_PACKET_SIZE  
TransmitterQueryLargePacketSize;
     XENVIF_VIF_TRANSMITTER_QUERY_RING_SIZE          TransmitterQueryRingSize;
@@ -832,7 +780,7 @@ struct _XENVIF_VIF_INTERFACE_V3 {
     XENVIF_VIF_MAC_QUERY_FILTER_LEVEL               MacQueryFilterLevel;
 };
 
-typedef struct _XENVIF_VIF_INTERFACE_V3 XENVIF_VIF_INTERFACE, 
*PXENVIF_VIF_INTERFACE;
+typedef struct _XENVIF_VIF_INTERFACE_V4 XENVIF_VIF_INTERFACE, 
*PXENVIF_VIF_INTERFACE;
 
 /*! \def XENVIF_VIF
     \brief Macro at assist in method invocation
@@ -842,7 +790,7 @@ typedef struct _XENVIF_VIF_INTERFACE_V3 
XENVIF_VIF_INTERFACE, *PXENVIF_VIF_INTER
 
 #endif  // _WINDLL
 
-#define XENVIF_VIF_INTERFACE_VERSION_MIN    1
-#define XENVIF_VIF_INTERFACE_VERSION_MAX    3
+#define XENVIF_VIF_INTERFACE_VERSION_MIN    2
+#define XENVIF_VIF_INTERFACE_VERSION_MAX    4
 
 #endif  // _XENVIF_INTERFACE_H
diff --git a/src/coinst/coinst.c b/src/coinst/coinst.c
index f60aa43..345b0c6 100644
--- a/src/coinst/coinst.c
+++ b/src/coinst/coinst.c
@@ -45,7 +45,6 @@
 #include <stdarg.h>
 #include <assert.h>
 #include <vif_interface.h>
-#include <cache_interface.h>
 
 #include <tcpip.h>
 #include <version.h>
diff --git a/src/xennet.inf b/src/xennet.inf
index 6c4c457..88aaac4 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
 ; -----------          -------         --------
 
-%XenNetDesc%           =XenNet_Inst,   
XENVIF\VEN_@VENDOR_PREFIX@@VENDOR_DEVICE_ID@&DEV_NET&REV_08000004
-%XenNetDesc%           =XenNet_Inst,   
XENVIF\VEN_@VENDOR_PREFIX@0001&DEV_NET&REV_08000004
-%XenNetDesc%           =XenNet_Inst,   
XENVIF\VEN_@VENDOR_PREFIX@0002&DEV_NET&REV_08000004
+%XenNetDesc%           =XenNet_Inst,   
XENVIF\VEN_@VENDOR_PREFIX@@VENDOR_DEVICE_ID@&DEV_NET&REV_08000006
+%XenNetDesc%           =XenNet_Inst,   
XENVIF\VEN_@VENDOR_PREFIX@0001&DEV_NET&REV_08000006
+%XenNetDesc%           =XenNet_Inst,   
XENVIF\VEN_@VENDOR_PREFIX@0002&DEV_NET&REV_08000006
 
 [XenNet_Inst] 
 Characteristics=0x84
diff --git a/src/xennet/adapter.c b/src/xennet/adapter.c
index 2c35636..52c7b58 100644
--- a/src/xennet/adapter.c
+++ b/src/xennet/adapter.c
@@ -37,7 +37,6 @@
 #include <version.h>
 
 #include <vif_interface.h>
-#include <cache_interface.h>
 #include <store_interface.h>
 #include <suspend_interface.h>
 
@@ -66,7 +65,6 @@ typedef struct _PROPERTIES {
 
 struct _XENNET_ADAPTER {
     XENVIF_VIF_INTERFACE        VifInterface;
-    XENBUS_CACHE_INTERFACE      CacheInterface;
     XENBUS_STORE_INTERFACE      StoreInterface;
     XENBUS_SUSPEND_INTERFACE    SuspendInterface;
 
@@ -195,20 +193,46 @@ AdapterVifCallback(
     va_start(Arguments, Type);
 
     switch (Type) {
-    case XENVIF_TRANSMITTER_RETURN_PACKETS: {
-        PLIST_ENTRY List;
+    case XENVIF_TRANSMITTER_RETURN_PACKET: {
+        PVOID                                       Cookie;
+        PXENVIF_TRANSMITTER_PACKET_COMPLETION_INFO  Completion;
 
-        List = va_arg(Arguments, PLIST_ENTRY);
+        Cookie = va_arg(Arguments, PVOID);
+        Completion = va_arg(Arguments, 
PXENVIF_TRANSMITTER_PACKET_COMPLETION_INFO);
 
-        TransmitterCompletePackets(Adapter->Transmitter, List);
+        TransmitterReturnPacket(Adapter->Transmitter,
+                                Cookie,
+                                Completion);
         break;
     }
-    case XENVIF_RECEIVER_QUEUE_PACKETS: {
-        PLIST_ENTRY List;
-
-        List = va_arg(Arguments, PLIST_ENTRY);
-
-        ReceiverReceivePackets(Adapter->Receiver, List);
+    case XENVIF_RECEIVER_QUEUE_PACKET: {
+        PMDL                            Mdl;
+        ULONG                           Offset;
+        ULONG                           Length;
+        XENVIF_PACKET_CHECKSUM_FLAGS    Flags;
+        USHORT                          MaximumSegmentSize;
+        USHORT                          TagControlInformation;
+        PXENVIF_PACKET_INFO             Info;
+        PVOID                           Cookie;
+
+        Mdl = va_arg(Arguments, PMDL);
+        Offset = va_arg(Arguments, ULONG);
+        Length = va_arg(Arguments, ULONG);
+        Flags = va_arg(Arguments, XENVIF_PACKET_CHECKSUM_FLAGS);
+        MaximumSegmentSize = va_arg(Arguments, USHORT);
+        TagControlInformation = va_arg(Arguments, USHORT);
+        Info = va_arg(Arguments, PXENVIF_PACKET_INFO);
+        Cookie = va_arg(Arguments, PVOID);
+
+        ReceiverQueuePacket(Adapter->Receiver,
+                            Mdl,
+                            Offset,
+                            Length,
+                            Flags,
+                            MaximumSegmentSize,
+                            TagControlInformation,
+                            Info,
+                            Cookie);
         break;
     }
     case XENVIF_MAC_STATE_CHANGE: {
@@ -1050,14 +1074,6 @@ AdapterGetVifInterface(
     return &Adapter->VifInterface;
 }
 
-PXENBUS_CACHE_INTERFACE
-AdapterGetCacheInterface(
-    IN  PXENNET_ADAPTER     Adapter
-    )
-{
-    return &Adapter->CacheInterface;
-}
-
 PXENNET_TRANSMITTER
 AdapterGetTransmitter(
     IN  PXENNET_ADAPTER     Adapter
@@ -1469,41 +1485,27 @@ AdapterEnable(
     )
 {
     NTSTATUS                status;
-    NDIS_STATUS             ndisStatus;
 
     ASSERT(!Adapter->Enabled);
 
-    status = XENBUS_CACHE(Acquire,
-                          &Adapter->CacheInterface);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
     status = XENBUS_STORE(Acquire,
                           &Adapter->StoreInterface);
     if (!NT_SUCCESS(status))
-        goto fail2;
+        goto fail1;
 
     status = XENBUS_SUSPEND(Acquire,
                             &Adapter->SuspendInterface);
     if (!NT_SUCCESS(status))
-        goto fail3;
+        goto fail2;
 
     (VOID) AdapterSetDistribution(Adapter);
 
-    ndisStatus = TransmitterEnable(Adapter->Transmitter);
-    if (ndisStatus != NDIS_STATUS_SUCCESS)
-        goto fail4;
-
-    ndisStatus = ReceiverEnable(Adapter->Receiver);
-    if (ndisStatus != NDIS_STATUS_SUCCESS)
-        goto fail5;
-
     status = XENVIF_VIF(Enable,
                         &Adapter->VifInterface,
                         AdapterVifCallback,
                         Adapter);
     if (!NT_SUCCESS(status))
-        goto fail6;
+        goto fail3;
 
     AdapterMediaStateChange(Adapter);
 
@@ -1511,22 +1513,13 @@ AdapterEnable(
 
     return NDIS_STATUS_SUCCESS;
 
-fail6:
-    ReceiverDisable(Adapter->Receiver);
-
-fail5:
-    TransmitterDisable(Adapter->Transmitter);
-
-fail4:
+fail3:
     AdapterClearDistribution(Adapter);
 
     XENBUS_SUSPEND(Release, &Adapter->SuspendInterface);
 
-fail3:
-    XENBUS_STORE(Release, &Adapter->StoreInterface);
-
 fail2:
-    XENBUS_CACHE(Release, &Adapter->CacheInterface);
+    XENBUS_STORE(Release, &Adapter->StoreInterface);
 
 fail1:
     return NDIS_STATUS_FAILURE;
@@ -1545,14 +1538,10 @@ AdapterDisable(
 
     AdapterMediaStateChange(Adapter);
 
-    ReceiverDisable(Adapter->Receiver);
-    TransmitterDisable(Adapter->Transmitter);
-
     AdapterClearDistribution(Adapter);
 
     XENBUS_SUSPEND(Release, &Adapter->SuspendInterface);
     XENBUS_STORE(Release, &Adapter->StoreInterface);
-    XENBUS_CACHE(Release, &Adapter->CacheInterface);
 }
 
 VOID
@@ -2779,22 +2768,13 @@ AdapterInitialize(
         goto fail2;
 
     status = __QueryInterface(DeviceObject,
-                              &GUID_XENBUS_CACHE_INTERFACE,
-                              XENBUS_CACHE_INTERFACE_VERSION_MAX,
-                              (PINTERFACE)&(*Adapter)->CacheInterface,
-                              sizeof(XENBUS_CACHE_INTERFACE),
-                              FALSE);
-    if (!NT_SUCCESS(status))
-        goto fail3;
-
-    status = __QueryInterface(DeviceObject,
                               &GUID_XENBUS_STORE_INTERFACE,
                               XENBUS_STORE_INTERFACE_VERSION_MAX,
                               (PINTERFACE)&(*Adapter)->StoreInterface,
                               sizeof(XENBUS_STORE_INTERFACE),
                               FALSE);
     if (!NT_SUCCESS(status))
-        goto fail4;
+        goto fail3;
 
     status = __QueryInterface(DeviceObject,
                               &GUID_XENBUS_SUSPEND_INTERFACE,
@@ -2803,42 +2783,42 @@ AdapterInitialize(
                               sizeof(XENBUS_SUSPEND_INTERFACE),
                               FALSE);
     if (!NT_SUCCESS(status))
-        goto fail5;
+        goto fail4;
 
     status = XENVIF_VIF(Acquire,
                         &(*Adapter)->VifInterface);
     if (!NT_SUCCESS(status))
-        goto fail6;
+        goto fail5;
 
     (*Adapter)->NdisAdapterHandle = Handle;
 
     ndisStatus = TransmitterInitialize(*Adapter, &(*Adapter)->Transmitter);
     if (ndisStatus != NDIS_STATUS_SUCCESS)
-        goto fail7;
+        goto fail6;
 
     ndisStatus = ReceiverInitialize(*Adapter, &(*Adapter)->Receiver);
     if (ndisStatus != NDIS_STATUS_SUCCESS)
-        goto fail8;
+        goto fail7;
 
     ndisStatus = AdapterGetAdvancedSettings(*Adapter);
     if (ndisStatus != NDIS_STATUS_SUCCESS)
-        goto fail9;
+        goto fail8;
 
     ndisStatus = AdapterSetRegistrationAttributes(*Adapter);
     if (ndisStatus != NDIS_STATUS_SUCCESS)
-        goto fail10;
+        goto fail9;
 
     ndisStatus = AdapterSetGeneralAttributes(*Adapter);
     if (ndisStatus != NDIS_STATUS_SUCCESS)
-        goto fail11;
+        goto fail10;
 
     ndisStatus = AdapterSetOffloadAttributes(*Adapter);
     if (ndisStatus != NDIS_STATUS_SUCCESS)
-        goto fail12;
+        goto fail11;
 
     ndisStatus = AdapterSetHeaderDataSplitAttributes(*Adapter);
     if (ndisStatus != NDIS_STATUS_SUCCESS)
-        goto fail13;
+        goto fail12;
 
     RtlZeroMemory(&Dma, sizeof(NDIS_SG_DMA_DESCRIPTION));
     Dma.Header.Type = NDIS_OBJECT_TYPE_SG_DMA_DESCRIPTION;
@@ -2857,31 +2837,28 @@ AdapterInitialize(
 
     return NDIS_STATUS_SUCCESS;
 
-fail13:
 fail12:
 fail11:
 fail10:
 fail9:
+fail8:
     ReceiverTeardown((*Adapter)->Receiver);
     (*Adapter)->Receiver = NULL;
 
-fail8:
+fail7:
     TransmitterTeardown((*Adapter)->Transmitter);
     (*Adapter)->Transmitter = NULL;
 
-fail7:
+fail6:
     (*Adapter)->NdisAdapterHandle = NULL;
 
     XENVIF_VIF(Release, &(*Adapter)->VifInterface);
 
-fail6:
-    RtlZeroMemory(&(*Adapter)->SuspendInterface, 
sizeof(XENBUS_SUSPEND_INTERFACE));
-
 fail5:
-    RtlZeroMemory(&(*Adapter)->StoreInterface, sizeof(XENBUS_STORE_INTERFACE));
+    RtlZeroMemory(&(*Adapter)->SuspendInterface, 
sizeof(XENBUS_SUSPEND_INTERFACE));
 
 fail4:
-    RtlZeroMemory(&(*Adapter)->CacheInterface, sizeof(XENBUS_CACHE_INTERFACE));
+    RtlZeroMemory(&(*Adapter)->StoreInterface, sizeof(XENBUS_STORE_INTERFACE));
 
 fail3:
     RtlZeroMemory(&(*Adapter)->VifInterface, sizeof(XENVIF_VIF_INTERFACE));
@@ -2914,7 +2891,6 @@ AdapterTeardown(
 
     RtlZeroMemory(&Adapter->SuspendInterface, 
sizeof(XENBUS_SUSPEND_INTERFACE));
     RtlZeroMemory(&Adapter->StoreInterface, sizeof(XENBUS_STORE_INTERFACE));
-    RtlZeroMemory(&Adapter->CacheInterface, sizeof(XENBUS_CACHE_INTERFACE));
     RtlZeroMemory(&Adapter->VifInterface, sizeof(XENVIF_VIF_INTERFACE));
 
     __AdapterFree(Adapter);
diff --git a/src/xennet/adapter.h b/src/xennet/adapter.h
index 5b2495a..5b0b338 100644
--- a/src/xennet/adapter.h
+++ b/src/xennet/adapter.h
@@ -76,12 +76,6 @@ AdapterGetVifInterface(
     IN  PXENNET_ADAPTER     Adapter
     );
 
-#include <cache_interface.h>
-extern PXENBUS_CACHE_INTERFACE
-AdapterGetCacheInterface(
-    IN  PXENNET_ADAPTER     Adapter
-    );
-
 #include "transmitter.h"
 extern PXENNET_TRANSMITTER
 AdapterGetTransmitter(
diff --git a/src/xennet/receiver.c b/src/xennet/receiver.c
index 8bfc10b..4a408c4 100644
--- a/src/xennet/receiver.c
+++ b/src/xennet/receiver.c
@@ -53,15 +53,23 @@ struct _XENNET_RECEIVER {
 #define RECEIVER_POOL_TAG       'RteN'
 #define IN_NDIS_MAX             1024
 
+typedef struct _NET_BUFFER_LIST_RESERVED {
+    PVOID   Cookie;
+} NET_BUFFER_LIST_RESERVED, *PNET_BUFFER_LIST_RESERVED;
+
+C_ASSERT(sizeof (NET_BUFFER_LIST_RESERVED) <= RTL_FIELD_SIZE(NET_BUFFER_LIST, 
MiniportReserved));
+
 static PNET_BUFFER_LIST
 __ReceiverAllocateNetBufferList(
-    IN  PXENNET_RECEIVER    Receiver,
-    IN  PMDL                Mdl,
-    IN  ULONG               Offset,
-    IN  ULONG               Length
+    IN  PXENNET_RECEIVER        Receiver,
+    IN  PMDL                    Mdl,
+    IN  ULONG                   Offset,
+    IN  ULONG                   Length,
+    IN  PVOID                   Cookie
     )
 {
-    PNET_BUFFER_LIST        NetBufferList;
+    PNET_BUFFER_LIST            NetBufferList;
+    PNET_BUFFER_LIST_RESERVED   ListReserved;
 
     ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL);
     KeAcquireSpinLockAtDpcLevel(&Receiver->Lock);
@@ -94,16 +102,27 @@ __ReceiverAllocateNetBufferList(
 
     KeReleaseSpinLockFromDpcLevel(&Receiver->Lock);
 
+    ListReserved = 
(PNET_BUFFER_LIST_RESERVED)NET_BUFFER_LIST_MINIPORT_RESERVED(NetBufferList);
+    ASSERT3P(ListReserved->Cookie, ==, NULL);
+    ListReserved->Cookie = Cookie;
+
     return NetBufferList;
 }        
 
-static VOID
+static PVOID
 __ReceiverReleaseNetBufferList(
-    IN  PXENNET_RECEIVER    Receiver,
-    IN  PNET_BUFFER_LIST    NetBufferList,
-    IN  BOOLEAN             Cache
+    IN  PXENNET_RECEIVER        Receiver,
+    IN  PNET_BUFFER_LIST        NetBufferList,
+    IN  BOOLEAN                 Cache
     )
 {
+    PNET_BUFFER_LIST_RESERVED   ListReserved;
+    PVOID                       Cookie;
+
+    ListReserved = 
(PNET_BUFFER_LIST_RESERVED)NET_BUFFER_LIST_MINIPORT_RESERVED(NetBufferList);
+    Cookie = ListReserved->Cookie;
+    ListReserved->Cookie = NULL;
+
     if (Cache) {
         PNET_BUFFER_LIST    Old;
         PNET_BUFFER_LIST    New;
@@ -119,53 +138,29 @@ __ReceiverReleaseNetBufferList(
     } else {
         NdisFreeNetBufferList(NetBufferList);
     }
+
+    return Cookie;
 }
 
-static FORCEINLINE ULONG
-__ReceiverReturnNetBufferLists(
+static FORCEINLINE VOID
+__ReceiverReturnNetBufferList(
     IN  PXENNET_RECEIVER    Receiver,
     IN  PNET_BUFFER_LIST    NetBufferList,
     IN  BOOLEAN             Cache
     )
 {
     PXENVIF_VIF_INTERFACE   VifInterface;
-    LIST_ENTRY              List;
-    ULONG                   Count;
+    PVOID                   Cookie;
 
     VifInterface = AdapterGetVifInterface(Receiver->Adapter);
-    InitializeListHead(&List);
-
-    Count = 0;
-    while (NetBufferList != NULL) {
-        PNET_BUFFER_LIST        Next;
-        PNET_BUFFER             NetBuffer;
-        PMDL                    Mdl;
-        PXENVIF_RECEIVER_PACKET Packet;
 
-        Next = NET_BUFFER_LIST_NEXT_NBL(NetBufferList);
-        NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL;
-
-        NetBuffer = NET_BUFFER_LIST_FIRST_NB(NetBufferList);
-        ASSERT3P(NET_BUFFER_NEXT_NB(NetBuffer), ==, NULL);
+    Cookie = __ReceiverReleaseNetBufferList(Receiver, NetBufferList, Cache);
 
-        Mdl = NET_BUFFER_FIRST_MDL(NetBuffer);
+    XENVIF_VIF(ReceiverReturnPacket,
+               VifInterface,
+               Cookie);
 
-        __ReceiverReleaseNetBufferList(Receiver, NetBufferList, Cache);
-
-        Packet = CONTAINING_RECORD(Mdl, XENVIF_RECEIVER_PACKET, Mdl);
-
-        InsertTailList(&List, &Packet->ListEntry);
-
-        Count++;
-        NetBufferList = Next;
-    }
-
-    if (Count != 0)
-        XENVIF_VIF(ReceiverReturnPackets,
-                   VifInterface,
-                   &List);
-
-    return Count;
+    (VOID) InterlockedIncrement(&Receiver->InNDIS);
 }
 
 static PNET_BUFFER_LIST
@@ -175,17 +170,23 @@ __ReceiverReceivePacket(
     IN  ULONG                                   Offset,
     IN  ULONG                                   Length,
     IN  XENVIF_PACKET_CHECKSUM_FLAGS            Flags,
-    IN  PXENVIF_PACKET_INFO                     Info
+    IN  USHORT                                  MaximumSegmentSize,
+    IN  USHORT                                  TagControlInformation,
+    IN  PXENVIF_PACKET_INFO                     Info,
+    IN  PVOID                                   Cookie
     )
 {
     PNET_BUFFER_LIST                            NetBufferList;
     PNET_BUFFER                                 NetBuffer;
     NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO   csumInfo;
 
+    UNREFERENCED_PARAMETER(MaximumSegmentSize);
+
     NetBufferList = __ReceiverAllocateNetBufferList(Receiver,
                                                     Mdl,
                                                     Offset,
-                                                    Length);
+                                                    Length,
+                                                    Cookie);
     if (NetBufferList == NULL)
         goto fail1;
 
@@ -206,10 +207,10 @@ __ReceiverReceivePacket(
 
     NET_BUFFER_LIST_INFO(NetBufferList, TcpIpChecksumNetBufferListInfo) = 
(PVOID)(ULONG_PTR)csumInfo.Value;
 
-    if (Info->TagControlInformation != 0) {
+    if (TagControlInformation != 0) {
         NDIS_NET_BUFFER_LIST_8021Q_INFO Ieee8021QInfo;
 
-        UNPACK_TAG_CONTROL_INFORMATION(Info->TagControlInformation,
+        UNPACK_TAG_CONTROL_INFORMATION(TagControlInformation,
                                        Ieee8021QInfo.TagHeader.UserPriority,
                                        
Ieee8021QInfo.TagHeader.CanonicalFormatId,
                                        Ieee8021QInfo.TagHeader.VlanId);
@@ -265,31 +266,26 @@ __ReceiverReceivePacket(
     return NetBufferList;
 
 fail2:
-    __ReceiverReleaseNetBufferList(Receiver, NetBufferList, TRUE);
+    (VOID) __ReceiverReleaseNetBufferList(Receiver, NetBufferList, TRUE);
 
 fail1:
     return NULL;
 }
 
 static VOID
-__ReceiverPushPackets(
+__ReceiverPushPacket(
     IN  PXENNET_RECEIVER    Receiver,
-    IN  PNET_BUFFER_LIST    NetBufferList,
-    IN  ULONG               Count,
-    IN  BOOLEAN             LowResources
+    IN  PNET_BUFFER_LIST    NetBufferList
     )
 {
     ULONG                   Flags;
     LONG                    InNDIS;
 
-    InNDIS = Receiver->InNDIS;
+    InNDIS = InterlockedIncrement(&Receiver->InNDIS);
 
     Flags = NDIS_RECEIVE_FLAGS_DISPATCH_LEVEL;
-    if (LowResources) {
+    if (InNDIS > IN_NDIS_MAX)
         Flags |= NDIS_RECEIVE_FLAGS_RESOURCES;
-    } else {
-        InNDIS = __InterlockedAdd(&Receiver->InNDIS, Count);
-    }
 
     for (;;) {
         LONG    InNDISMax;
@@ -307,11 +303,11 @@ __ReceiverPushPackets(
     NdisMIndicateReceiveNetBufferLists(AdapterGetHandle(Receiver->Adapter),
                                        NetBufferList,
                                        NDIS_DEFAULT_PORT_NUMBER,
-                                       Count,
+                                       1,
                                        Flags);
 
-    if (LowResources)
-        (VOID) __ReceiverReturnNetBufferLists(Receiver, NetBufferList, FALSE);
+    if (Flags & NDIS_RECEIVE_FLAGS_RESOURCES)
+        (VOID) __ReceiverReturnNetBufferList(Receiver, NetBufferList, FALSE);
 }
 
 NDIS_STATUS
@@ -359,24 +355,6 @@ fail1:
     return status;
 }
 
-NDIS_STATUS
-ReceiverEnable (
-    IN  PXENNET_RECEIVER    Receiver
-    )
-{
-    UNREFERENCED_PARAMETER(Receiver);
-
-    return NDIS_STATUS_SUCCESS;
-}
-
-VOID
-ReceiverDisable (
-    IN  PXENNET_RECEIVER    Receiver
-    )
-{
-    UNREFERENCED_PARAMETER(Receiver);
-}
-
 VOID
 ReceiverTeardown(
     IN  PXENNET_RECEIVER    Receiver
@@ -425,88 +403,54 @@ ReceiverReturnNetBufferLists(
     IN  ULONG               ReturnFlags
     )
 {
-    ULONG                   Count;
-
     UNREFERENCED_PARAMETER(ReturnFlags);
 
-    Count = __ReceiverReturnNetBufferLists(Receiver, NetBufferList, TRUE);
-    (VOID) __InterlockedSubtract(&Receiver->InNDIS, Count);
+    while (NetBufferList != NULL) {
+        PNET_BUFFER_LIST        Next;
+
+        Next = NET_BUFFER_LIST_NEXT_NBL(NetBufferList);
+        NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL;
+
+        __ReceiverReturnNetBufferList(Receiver, NetBufferList, TRUE);
+
+        NetBufferList = Next;
+    }
 }
 
 VOID
-ReceiverReceivePackets(
-    IN  PXENNET_RECEIVER    Receiver,
-    IN  PLIST_ENTRY         List
+ReceiverQueuePacket(
+    IN  PXENNET_RECEIVER                Receiver,
+    IN  PMDL                            Mdl,
+    IN  ULONG                           Offset,
+    IN  ULONG                           Length,
+    IN  XENVIF_PACKET_CHECKSUM_FLAGS    Flags,
+    IN  USHORT                          MaximumSegmentSize,
+    IN  USHORT                          TagControlInformation,
+    IN  PXENVIF_PACKET_INFO             Info,
+    IN  PVOID                           Cookie
     )
 {
-    PXENVIF_VIF_INTERFACE   VifInterface;
-    PNET_BUFFER_LIST        HeadNetBufferList;
-    PNET_BUFFER_LIST        *TailNetBufferList;
-    ULONG                   Count;
-    BOOLEAN                 LowResources;
+    PXENVIF_VIF_INTERFACE               VifInterface;
+    PNET_BUFFER_LIST                    NetBufferList;
 
     VifInterface = AdapterGetVifInterface(Receiver->Adapter);
-    LowResources = FALSE;
-
-again:
-    HeadNetBufferList = NULL;
-    TailNetBufferList = &HeadNetBufferList;
-    Count = 0;
-
-    while (!IsListEmpty(List)) {
-        PLIST_ENTRY                     ListEntry;
-        PXENVIF_RECEIVER_PACKET         Packet;
-        PXENVIF_PACKET_INFO             Info;
-        PMDL                            Mdl;
-        ULONG                           Offset;
-        ULONG                           Length;
-        XENVIF_PACKET_CHECKSUM_FLAGS    Flags;
-        PNET_BUFFER_LIST                NetBufferList;
-
-        if (!LowResources &&
-            Receiver->InNDIS + Count > IN_NDIS_MAX)
-            break;
-
-        ListEntry = RemoveHeadList(List);
-        ASSERT(ListEntry != List);
-
-        RtlZeroMemory(ListEntry, sizeof (LIST_ENTRY));
-
-        Packet = CONTAINING_RECORD(ListEntry, XENVIF_RECEIVER_PACKET, 
ListEntry);
-        Mdl = &Packet->Mdl;
-        Offset = Packet->Offset;
-        Length = Packet->Length;
-        Flags = Packet->Flags;
-        Info = Packet->Info;
-
-        NetBufferList = __ReceiverReceivePacket(Receiver, Mdl, Offset, Length, 
Flags, Info);
-
-        if (NetBufferList != NULL) {
-            *TailNetBufferList = NetBufferList;
-            TailNetBufferList = &NET_BUFFER_LIST_NEXT_NBL(NetBufferList);
-            Count++;
-        } else {
-            LIST_ENTRY  PacketList;
 
-            InitializeListHead(&PacketList);
-            InsertTailList(&PacketList, &Packet->ListEntry);
+    NetBufferList = __ReceiverReceivePacket(Receiver,
+                                            Mdl,
+                                            Offset,
+                                            Length,
+                                            Flags,
+                                            MaximumSegmentSize,
+                                            TagControlInformation,
+                                            Info,
+                                            Cookie);
 
-            XENVIF_VIF(ReceiverReturnPackets,
-                       VifInterface,
-                       &PacketList);
-        }
-    }
-
-    if (Count != 0) {
-        ASSERT(HeadNetBufferList != NULL);
-
-        __ReceiverPushPackets(Receiver, HeadNetBufferList, Count, 
LowResources);
-    }
-
-    if (!IsListEmpty(List)) {
-        ASSERT(!LowResources);
-        LowResources = TRUE;
-        goto again;
+    if (NetBufferList != NULL) {
+        __ReceiverPushPacket(Receiver, NetBufferList);
+    } else {
+        XENVIF_VIF(ReceiverReturnPacket,
+                   VifInterface,
+                   Cookie);
     }
 }
 
diff --git a/src/xennet/receiver.h b/src/xennet/receiver.h
index 33701a9..fbc0151 100644
--- a/src/xennet/receiver.h
+++ b/src/xennet/receiver.h
@@ -43,16 +43,6 @@ ReceiverInitialize(
     OUT PXENNET_RECEIVER    *Receiver
     );
 
-extern NDIS_STATUS
-ReceiverEnable(
-    IN  PXENNET_RECEIVER    Receiver
-    );
-
-extern VOID
-ReceiverDisable(
-    IN  PXENNET_RECEIVER    Receiver
-    );
-
 extern VOID
 ReceiverTeardown(
     IN  PXENNET_RECEIVER    Receiver
@@ -66,9 +56,16 @@ ReceiverReturnNetBufferLists(
     );
 
 extern VOID
-ReceiverReceivePackets(
-    IN  PXENNET_RECEIVER    Receiver,
-    IN  PLIST_ENTRY         List
+ReceiverQueuePacket(
+    IN  PXENNET_RECEIVER                Receiver,
+    IN  PMDL                            Mdl,
+    IN  ULONG                           Offset,
+    IN  ULONG                           Length,
+    IN  XENVIF_PACKET_CHECKSUM_FLAGS    Flags,
+    IN  USHORT                          MaximumSegmentSize,
+    IN  USHORT                          TagControlInformation,
+    IN  PXENVIF_PACKET_INFO             Info,
+    IN  PVOID                           Cookie
     );
 
 extern PXENVIF_VIF_OFFLOAD_OPTIONS
diff --git a/src/xennet/transmitter.c b/src/xennet/transmitter.c
index 8c80c7e..5574b9c 100644
--- a/src/xennet/transmitter.c
+++ b/src/xennet/transmitter.c
@@ -33,7 +33,6 @@
 #include "transmitter.h"
 #include "adapter.h"
 #include <vif_interface.h>
-#include <cache_interface.h>
 #include <tcpip.h>
 #include "dbg_print.h"
 #include "assert.h"
@@ -42,98 +41,9 @@ struct _XENNET_TRANSMITTER {
     PXENNET_ADAPTER             Adapter;
     XENVIF_VIF_OFFLOAD_OPTIONS  OffloadOptions;
     KSPIN_LOCK                  Lock;
-    PXENBUS_CACHE               PacketCache;
-    PXENBUS_CACHE               BufferCache;
 };
 
-#define XENNET_PACKET_CACHE_MIN     32
 #define TRANSMITTER_POOL_TAG        'TteN'
-#define BUFFER_CACHE_ITEM_SIZE      512
-#define MAX_HEADERS_LENGTH          (sizeof(IP_ADDRESS) + sizeof(IP_ADDRESS) + 
sizeof(USHORT) + sizeof(USHORT))
-
-static NTSTATUS
-__TransmitterPacketCtor(
-    IN  PVOID       Argument,
-    IN  PVOID       Object
-    )
-{
-    UNREFERENCED_PARAMETER(Argument);
-    UNREFERENCED_PARAMETER(Object);
-    return STATUS_SUCCESS;
-}
-
-static VOID
-__TransmitterPacketDtor(
-    IN  PVOID       Argument,
-    IN  PVOID       Object
-    )
-{
-    UNREFERENCED_PARAMETER(Argument);
-    UNREFERENCED_PARAMETER(Object);
-}
-
-static VOID
-__TransmitterPacketAcquireLock(
-    IN  PVOID           Argument
-    )
-{
-    PXENNET_TRANSMITTER Transmitter = Argument;
-
-    KeAcquireSpinLockAtDpcLevel(&Transmitter->Lock);
-}
-
-static VOID
-__TransmitterPacketReleaseLock(
-    IN  PVOID           Argument
-    )
-{
-    PXENNET_TRANSMITTER Transmitter = Argument;
-
-#pragma prefast(suppress:26110)
-    KeReleaseSpinLockFromDpcLevel(&Transmitter->Lock);
-}
-
-static NTSTATUS
-__TransmitterBufferCtor(
-    IN  PVOID       Argument,
-    IN  PVOID       Object
-    )
-{
-    UNREFERENCED_PARAMETER(Argument);
-    UNREFERENCED_PARAMETER(Object);
-    return STATUS_SUCCESS;
-}
-
-static VOID
-__TransmitterBufferDtor(
-    IN  PVOID       Argument,
-    IN  PVOID       Object
-    )
-{
-    UNREFERENCED_PARAMETER(Argument);
-    UNREFERENCED_PARAMETER(Object);
-}
-
-static VOID
-__TransmitterBufferAcquireLock(
-    IN  PVOID           Argument
-    )
-{
-    PXENNET_TRANSMITTER Transmitter = Argument;
-
-    KeAcquireSpinLockAtDpcLevel(&Transmitter->Lock);
-}
-
-static VOID
-__TransmitterBufferReleaseLock(
-    IN  PVOID           Argument
-    )
-{
-    PXENNET_TRANSMITTER Transmitter = Argument;
-
-#pragma prefast(suppress:26110)
-    KeReleaseSpinLockFromDpcLevel(&Transmitter->Lock);
-}
 
 NDIS_STATUS
 TransmitterInitialize (
@@ -141,10 +51,13 @@ TransmitterInitialize (
     OUT PXENNET_TRANSMITTER *Transmitter
     )
 {
+    NTSTATUS                status;
+
     *Transmitter = ExAllocatePoolWithTag(NonPagedPool,
                                          sizeof(XENNET_TRANSMITTER),
                                          TRANSMITTER_POOL_TAG);
 
+    status = STATUS_NO_MEMORY;
     if (*Transmitter == NULL)
         goto fail1;
 
@@ -157,84 +70,12 @@ TransmitterInitialize (
     return NDIS_STATUS_SUCCESS;
 
 fail1:
-    return NDIS_STATUS_FAILURE;
-}
-
-NDIS_STATUS
-TransmitterEnable (
-    IN  PXENNET_TRANSMITTER Transmitter
-    )
-{
-    PXENBUS_CACHE_INTERFACE CacheInterface;
-    NTSTATUS                status;
-
-    CacheInterface = AdapterGetCacheInterface(Transmitter->Adapter);
-
-    status = XENBUS_CACHE(Create,
-                          CacheInterface,
-                          "packet_cache",
-                          sizeof(XENVIF_TRANSMITTER_PACKET),
-                          XENNET_PACKET_CACHE_MIN,
-                          __TransmitterPacketCtor,
-                          __TransmitterPacketDtor,
-                          __TransmitterPacketAcquireLock,
-                          __TransmitterPacketReleaseLock,
-                          Transmitter,
-                          &Transmitter->PacketCache);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status = XENBUS_CACHE(Create,
-                          CacheInterface,
-                          "buffer_cache",
-                          BUFFER_CACHE_ITEM_SIZE,
-                          0,
-                          __TransmitterBufferCtor,
-                          __TransmitterBufferDtor,
-                          __TransmitterBufferAcquireLock,
-                          __TransmitterBufferReleaseLock,
-                          Transmitter,
-                          &Transmitter->BufferCache);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    return NDIS_STATUS_SUCCESS;
-
-fail2:
-    Error("fail2\n");
-
-    XENBUS_CACHE(Destroy,
-                 CacheInterface,
-                 Transmitter->PacketCache);
-    Transmitter->PacketCache = NULL;
-
-fail1:
     Error("fail1\n (%08x)", status);
 
     return NDIS_STATUS_FAILURE;
 }
 
 VOID
-TransmitterDisable (
-    IN  PXENNET_TRANSMITTER Transmitter
-    )
-{
-    PXENBUS_CACHE_INTERFACE CacheInterface;
-
-    CacheInterface = AdapterGetCacheInterface(Transmitter->Adapter);
-
-    XENBUS_CACHE(Destroy,
-                 CacheInterface,
-                 Transmitter->BufferCache);
-    Transmitter->BufferCache = NULL;
-
-    XENBUS_CACHE(Destroy,
-                 CacheInterface,
-                 Transmitter->PacketCache);
-    Transmitter->PacketCache = NULL;
-}
-
-VOID
 TransmitterTeardown(
     IN  PXENNET_TRANSMITTER Transmitter
     )
@@ -247,74 +88,6 @@ TransmitterTeardown(
     ExFreePoolWithTag(Transmitter, TRANSMITTER_POOL_TAG);
 }
 
-static FORCEINLINE PXENVIF_TRANSMITTER_PACKET
-__TransmitterGetPacket(
-    IN  PXENNET_TRANSMITTER Transmitter
-    )
-{
-    PXENBUS_CACHE_INTERFACE CacheInterface;
-
-    CacheInterface = AdapterGetCacheInterface(Transmitter->Adapter);
-
-    return XENBUS_CACHE(Get,
-                        CacheInterface,
-                        Transmitter->PacketCache,
-                        FALSE);
-}
-
-static FORCEINLINE VOID
-__TransmitterPutPacket(
-    IN  PXENNET_TRANSMITTER         Transmitter,
-    IN  PXENVIF_TRANSMITTER_PACKET  Packet
-    )
-{
-    PXENBUS_CACHE_INTERFACE CacheInterface;
-
-    CacheInterface = AdapterGetCacheInterface(Transmitter->Adapter);
-
-    RtlZeroMemory(Packet, sizeof(XENVIF_TRANSMITTER_PACKET));
-
-    XENBUS_CACHE(Put,
-                 CacheInterface,
-                 Transmitter->PacketCache,
-                 Packet,
-                 FALSE);
-}
-
-static FORCEINLINE PVOID
-__TransmitterGetBuffer(
-    IN  PXENNET_TRANSMITTER Transmitter
-    )
-{
-    PXENBUS_CACHE_INTERFACE CacheInterface;
-
-    CacheInterface = AdapterGetCacheInterface(Transmitter->Adapter);
-
-    return XENBUS_CACHE(Get,
-                        CacheInterface,
-                        Transmitter->BufferCache,
-                        FALSE);
-}
-
-static FORCEINLINE VOID
-__TransmitterPutBuffer(
-    IN  PXENNET_TRANSMITTER Transmitter,
-    IN  PVOID               Buffer
-    )
-{
-    PXENBUS_CACHE_INTERFACE CacheInterface;
-
-    CacheInterface = AdapterGetCacheInterface(Transmitter->Adapter);
-
-    RtlZeroMemory(Buffer, BUFFER_CACHE_ITEM_SIZE);
-
-    XENBUS_CACHE(Put,
-                 CacheInterface,
-                 Transmitter->BufferCache,
-                 Buffer,
-                 FALSE);
-}
-
 typedef struct _NET_BUFFER_LIST_RESERVED {
     LONG    Reference;
 } NET_BUFFER_LIST_RESERVED, *PNET_BUFFER_LIST_RESERVED;
@@ -348,34 +121,22 @@ __TransmitterCompleteNetBufferList(
 }
 
 static VOID
-__TransmitterCompletePackets(
-    IN  PXENNET_TRANSMITTER Transmitter,
-    IN  PLIST_ENTRY         List,
-    IN  NDIS_STATUS         Status
+__TransmitterReturnPacket(
+    IN  PXENNET_TRANSMITTER     Transmitter,
+    IN  PVOID                   Cookie,
+    IN  NDIS_STATUS             Status
     )
 {
-    while (!IsListEmpty(List)) {
-        PLIST_ENTRY                 ListEntry;
-        PXENVIF_TRANSMITTER_PACKET  Packet;
-        PNET_BUFFER_LIST            NetBufferList;
-        PNET_BUFFER_LIST_RESERVED   ListReserved;
+    PNET_BUFFER_LIST            NetBufferList = Cookie;
+    PNET_BUFFER_LIST_RESERVED   ListReserved;
 
-        ListEntry = RemoveHeadList(List);
-        ASSERT3P(ListEntry, !=, List);
+    ASSERT(NetBufferList != NULL);
 
-        Packet = CONTAINING_RECORD(ListEntry, XENVIF_TRANSMITTER_PACKET, 
ListEntry);
+    ListReserved = 
(PNET_BUFFER_LIST_RESERVED)NET_BUFFER_LIST_MINIPORT_RESERVED(NetBufferList);
 
-        NetBufferList = Packet->Cookie;
-        ASSERT(NetBufferList != NULL);
-
-        ListReserved = 
(PNET_BUFFER_LIST_RESERVED)NET_BUFFER_LIST_MINIPORT_RESERVED(NetBufferList);
-
-        ASSERT(ListReserved->Reference != 0);
-        if (InterlockedDecrement(&ListReserved->Reference) == 0)
-            __TransmitterCompleteNetBufferList(Transmitter, NetBufferList, 
Status);
-
-        __TransmitterPutPacket(Transmitter, Packet);
-    }
+    ASSERT(ListReserved->Reference != 0);
+    if (InterlockedDecrement(&ListReserved->Reference) == 0)
+        __TransmitterCompleteNetBufferList(Transmitter, NetBufferList, Status);
 }
 
 static VOID
@@ -444,127 +205,6 @@ __TransmitterOffloadOptions(
     }
 }
 
-static ULONG
-__Hash(
-    IN  PVOID                       Buffer,
-    IN  ULONG                       Length
-    )
-{
-    PUCHAR                          Array = (PUCHAR)Buffer;
-    ULONG                           Accumulator;
-    ULONG                           Index;
-
-    Accumulator = 0;
-
-    for (Index = 0; Index < Length; ++Index) {
-        ULONG   Overflow;
-
-        Accumulator = (Accumulator << 4) + Array[Index];
-
-        Overflow = Accumulator & 0x00000f00;
-        if (Overflow != 0) {
-            Accumulator ^= Overflow >> 8;
-            Accumulator ^= Overflow;
-        }
-    }
-
-    return Accumulator;
-}
-
-static ULONG
-__TransmitterCalculateHash(
-    IN  PVOID                       Buffer,
-    IN  PXENVIF_PACKET_INFO         Info
-    )
-{
-    UCHAR       Headers[MAX_HEADERS_LENGTH];
-    PUCHAR      Ptr;
-
-    Ptr = (PUCHAR)Headers;
-
-    if (Info->IpHeader.Length) {
-        PIP_HEADER  Ip = (PIP_HEADER)((PUCHAR)Buffer + Info->IpHeader.Offset);
-
-        switch (Ip->Version) {
-        case 4:
-            RtlCopyMemory(Ptr, &Ip->Version4.SourceAddress, 
sizeof(IPV4_ADDRESS));
-            Ptr += sizeof(IPV4_ADDRESS);
-            RtlCopyMemory(Ptr, &Ip->Version4.DestinationAddress, 
sizeof(IPV4_ADDRESS));
-            Ptr += sizeof(IPV4_ADDRESS);
-            break;
-        case 6:
-            RtlCopyMemory(Ptr, &Ip->Version6.SourceAddress, 
sizeof(IPV6_ADDRESS));
-            Ptr += sizeof(IPV6_ADDRESS);
-            RtlCopyMemory(Ptr, &Ip->Version6.DestinationAddress, 
sizeof(IPV6_ADDRESS));
-            Ptr += sizeof(IPV6_ADDRESS);
-            break;
-        default:
-            break;
-        }
-    }
-
-    if (Info->TcpHeader.Length) {
-        PTCP_HEADER Tcp = (PTCP_HEADER)((PUCHAR)Buffer + 
Info->TcpHeader.Offset);
-
-        RtlCopyMemory(Ptr, &Tcp->SourcePort, sizeof(USHORT));
-        Ptr += sizeof(USHORT);
-        RtlCopyMemory(Ptr, &Tcp->DestinationPort, sizeof(USHORT));
-        Ptr += sizeof(USHORT);
-    } else if (Info->UdpHeader.Length) {
-        PUDP_HEADER Udp = (PUDP_HEADER)((PUCHAR)Buffer + 
Info->UdpHeader.Offset);
-
-        RtlCopyMemory(Ptr, &Udp->SourcePort, sizeof(USHORT));
-        Ptr += sizeof(USHORT);
-        RtlCopyMemory(Ptr, &Udp->DestinationPort, sizeof(USHORT));
-        Ptr += sizeof(USHORT);
-    }
-
-    if (Ptr == (PUCHAR)Headers)
-        return 0;
-
-    return __Hash(Headers, (ULONG)((ULONG_PTR)Ptr - (ULONG_PTR)Headers));
-}
-
-static ULONG
-__TransmitterGetHash(
-    IN  PXENNET_TRANSMITTER         Transmitter,
-    IN  PXENVIF_TRANSMITTER_PACKET  Packet
-    )
-{
-    PXENVIF_VIF_INTERFACE           VifInterface;
-    ULONG                           Hash;
-    XENVIF_PACKET_INFO              Info;
-    PVOID                           Buffer;
-    NTSTATUS                        status;
-
-    Hash = 0;
-    VifInterface = AdapterGetVifInterface(Transmitter->Adapter);
-
-    Buffer = __TransmitterGetBuffer(Transmitter);
-    if (Buffer == NULL)
-        goto fail1;
-
-    RtlZeroMemory(&Info, sizeof(XENVIF_PACKET_INFO));
-
-    status = XENVIF_VIF(TransmitterGetPacketHeaders,
-                        VifInterface,
-                        Packet,
-                        Buffer,
-                        &Info);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    Hash = __TransmitterCalculateHash(Buffer, &Info);
-
-    __TransmitterPutBuffer(Transmitter, Buffer);
-    return Hash;
-
-fail2:
-    __TransmitterPutBuffer(Transmitter, Buffer);
-fail1:
-    return 0;
-}
-
 VOID
 TransmitterSendNetBufferLists(
     IN  PXENNET_TRANSMITTER     Transmitter,
@@ -603,41 +243,30 @@ TransmitterSendNetBufferLists(
                                     &TagControlInformation,
                                     &MaximumSegmentSize);
 
+        OffloadOptions.Value &= Transmitter->OffloadOptions.Value;
+
         ListReserved = 
(PNET_BUFFER_LIST_RESERVED)NET_BUFFER_LIST_MINIPORT_RESERVED(NetBufferList);
         RtlZeroMemory(ListReserved, sizeof (NET_BUFFER_LIST_RESERVED));
 
         NetBuffer = NET_BUFFER_LIST_FIRST_NB(NetBufferList);
         while (NetBuffer != NULL) {
-            PXENVIF_TRANSMITTER_PACKET  Packet;
-
-            Packet = __TransmitterGetPacket(Transmitter);
-            if (Packet == NULL) {
-                while (ListReserved->Reference--) {
-                    PLIST_ENTRY     ListEntry;
-
-                    ListEntry = RemoveTailList(&List);
-                    ASSERT3P(ListEntry, !=, &List);
-
-                    Packet = CONTAINING_RECORD(ListEntry, 
XENVIF_TRANSMITTER_PACKET, ListEntry);
-
-                    __TransmitterPutPacket(Transmitter, Packet);
-                }
-                __TransmitterCompleteNetBufferList(Transmitter, NetBufferList, 
NDIS_STATUS_NOT_ACCEPTED);
-                break;
-            }
+            PVOID               Cookie = NetBufferList;
+            XENVIF_PACKET_HASH  Hash;
 
             ListReserved->Reference++;
 
-            Packet->Cookie = NetBufferList;
-            Packet->Send.OffloadOptions.Value = OffloadOptions.Value & 
Transmitter->OffloadOptions.Value;
-            Packet->Send.MaximumSegmentSize = MaximumSegmentSize;
-            Packet->Send.TagControlInformation = TagControlInformation;
-            Packet->Mdl = NET_BUFFER_CURRENT_MDL(NetBuffer);
-            Packet->Length = NET_BUFFER_DATA_LENGTH(NetBuffer);
-            Packet->Offset = NET_BUFFER_CURRENT_MDL_OFFSET(NetBuffer);
-            Packet->Value = __TransmitterGetHash(Transmitter, Packet);
+            Hash.Algorithm = XENVIF_PACKET_HASH_ALGORITHM_NONE;
 
-            InsertTailList(&List, &Packet->ListEntry);
+            XENVIF_VIF(TransmitterQueuePacket,
+                       AdapterGetVifInterface(Transmitter->Adapter),
+                       NET_BUFFER_CURRENT_MDL(NetBuffer),
+                       NET_BUFFER_CURRENT_MDL_OFFSET(NetBuffer),
+                       NET_BUFFER_DATA_LENGTH(NetBuffer),
+                       OffloadOptions,
+                       MaximumSegmentSize,
+                       TagControlInformation,
+                       &Hash,
+                       Cookie);
 
             NetBuffer = NET_BUFFER_NEXT_NB(NetBuffer);
         }
@@ -645,26 +274,25 @@ TransmitterSendNetBufferLists(
         NetBufferList = ListNext;
     }
 
-    if (!IsListEmpty(&List)) {
-        NTSTATUS    status; 
-
-        status = XENVIF_VIF(TransmitterQueuePackets,
-                            AdapterGetVifInterface(Transmitter->Adapter),
-                            &List);
-        if (!NT_SUCCESS(status))
-            __TransmitterCompletePackets(Transmitter, &List, 
NDIS_STATUS_NOT_ACCEPTED);
-    }
-
     NDIS_LOWER_IRQL(Irql, DISPATCH_LEVEL);
 }
 
 VOID
-TransmitterCompletePackets(
-    IN  PXENNET_TRANSMITTER Transmitter,
-    IN  PLIST_ENTRY         List
+TransmitterReturnPacket(
+    IN  PXENNET_TRANSMITTER                         Transmitter,
+    IN  PVOID                                       Cookie,
+    IN  PXENVIF_TRANSMITTER_PACKET_COMPLETION_INFO  Completion
     )
 {
-    __TransmitterCompletePackets(Transmitter, List, NDIS_STATUS_SUCCESS);
+    NDIS_STATUS                                     Status;
+
+    UNREFERENCED_PARAMETER(Completion);
+
+    Status = (Completion->Status == XENVIF_TRANSMITTER_PACKET_OK) ?
+             NDIS_STATUS_SUCCESS :
+             NDIS_STATUS_NOT_ACCEPTED;
+
+    __TransmitterReturnPacket(Transmitter, Cookie, Status);
 }
 
 PXENVIF_VIF_OFFLOAD_OPTIONS
diff --git a/src/xennet/transmitter.h b/src/xennet/transmitter.h
index 363b91e..585c5ac 100644
--- a/src/xennet/transmitter.h
+++ b/src/xennet/transmitter.h
@@ -43,16 +43,6 @@ TransmitterInitialize(
     OUT PXENNET_TRANSMITTER *Transmitter
     );
 
-extern NDIS_STATUS
-TransmitterEnable(
-    IN  PXENNET_TRANSMITTER Transmitter
-    );
-
-extern VOID
-TransmitterDisable(
-    IN  PXENNET_TRANSMITTER Transmitter
-    );
-
 extern VOID
 TransmitterTeardown(
     IN  PXENNET_TRANSMITTER Transmitter
@@ -67,9 +57,10 @@ TransmitterSendNetBufferLists (
     );
 
 extern VOID
-TransmitterCompletePackets(
-    IN  PXENNET_TRANSMITTER Transmitter,
-    IN  PLIST_ENTRY         List
+TransmitterReturnPacket(
+    IN  PXENNET_TRANSMITTER                         Transmitter,
+    IN  PVOID                                       Cookie,
+    IN  PXENVIF_TRANSMITTER_PACKET_COMPLETION_INFO  Completion
     );
 
 extern PXENVIF_VIF_OFFLOAD_OPTIONS
-- 
2.1.1


_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
http://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®.