+++ /dev/null
-/* 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
#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
*/
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) */
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
#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
#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 */
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
*/
\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;
\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
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
/*! \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
/*! \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
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;
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;
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;
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
#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
#include <stdarg.h>
#include <assert.h>
#include <vif_interface.h>
-#include <cache_interface.h>
#include <tcpip.h>
#include <version.h>
; 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
#include <version.h>
#include <vif_interface.h>
-#include <cache_interface.h>
#include <store_interface.h>
#include <suspend_interface.h>
struct _XENNET_ADAPTER {
XENVIF_VIF_INTERFACE VifInterface;
- XENBUS_CACHE_INTERFACE CacheInterface;
XENBUS_STORE_INTERFACE StoreInterface;
XENBUS_SUSPEND_INTERFACE SuspendInterface;
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: {
return &Adapter->VifInterface;
}
-PXENBUS_CACHE_INTERFACE
-AdapterGetCacheInterface(
- IN PXENNET_ADAPTER Adapter
- )
-{
- return &Adapter->CacheInterface;
-}
-
PXENNET_TRANSMITTER
AdapterGetTransmitter(
IN PXENNET_ADAPTER Adapter
)
{
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);
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;
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
if (!NT_SUCCESS(status))
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,
sizeof(XENBUS_STORE_INTERFACE),
FALSE);
if (!NT_SUCCESS(status))
- goto fail4;
+ goto fail3;
status = __QueryInterface(DeviceObject,
&GUID_XENBUS_SUSPEND_INTERFACE,
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;
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));
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);
IN PXENNET_ADAPTER Adapter
);
-#include <cache_interface.h>
-extern PXENBUS_CACHE_INTERFACE
-AdapterGetCacheInterface(
- IN PXENNET_ADAPTER Adapter
- );
-
#include "transmitter.h"
extern PXENNET_TRANSMITTER
AdapterGetTransmitter(
#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);
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;
} 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
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;
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);
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;
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
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
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);
}
}
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
);
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
#include "transmitter.h"
#include "adapter.h"
#include <vif_interface.h>
-#include <cache_interface.h>
#include <tcpip.h>
#include "dbg_print.h"
#include "assert.h"
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 (
OUT PXENNET_TRANSMITTER *Transmitter
)
{
+ NTSTATUS status;
+
*Transmitter = ExAllocatePoolWithTag(NonPagedPool,
sizeof(XENNET_TRANSMITTER),
TRANSMITTER_POOL_TAG);
+ status = STATUS_NO_MEMORY;
if (*Transmitter == NULL)
goto fail1;
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
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;
}
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
}
}
-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,
&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);
}
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
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
);
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