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)
*/
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
*/
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.
-
- \param Interface The interface header
- \param Type The offset type
- \param Value The offset value
-*/
-typedef NTSTATUS
-(*XENVIF_VIF_TRANSMITTER_SET_PACKET_OFFSET)(
- IN PINTERFACE Interface,
- IN XENVIF_TRANSMITTER_PACKET_OFFSET Type,
- IN LONG_PTR Value
- );
-
/*! \typedef XENVIF_VIF_TRANSMITTER_GET_PACKET_HEADERS
\brief Get the packet headers into supplied buffer
OUT PXENVIF_PACKET_INFO Info
);
-typedef NTSTATUS
-(*XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS_V1)(
- IN PINTERFACE Interface,
- IN PXENVIF_TRANSMITTER_PACKET_V1 Head
- );
-
/*! \typedef XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS
\brief Queue transmit side packets at the provider
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
- \ingroup interfaces
-*/
-struct _XENVIF_VIF_INTERFACE_V1 {
- INTERFACE Interface;
- XENVIF_VIF_ACQUIRE Acquire;
- XENVIF_VIF_RELEASE Release;
- XENVIF_VIF_ENABLE Enable;
- XENVIF_VIF_DISABLE Disable;
- XENVIF_VIF_QUERY_STATISTIC QueryStatistic;
- XENVIF_VIF_RECEIVER_RETURN_PACKETS ReceiverReturnPackets;
- XENVIF_VIF_RECEIVER_SET_OFFLOAD_OPTIONS ReceiverSetOffloadOptions;
- XENVIF_VIF_RECEIVER_QUERY_RING_SIZE ReceiverQueryRingSize;
- XENVIF_VIF_TRANSMITTER_SET_PACKET_OFFSET TransmitterSetPacketOffset;
- XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS_V1 TransmitterQueuePacketsVersion1;
- XENVIF_VIF_TRANSMITTER_QUERY_OFFLOAD_OPTIONS TransmitterQueryOffloadOptions;
- XENVIF_VIF_TRANSMITTER_QUERY_LARGE_PACKET_SIZE TransmitterQueryLargePacketSize;
- XENVIF_VIF_TRANSMITTER_QUERY_RING_SIZE TransmitterQueryRingSize;
- XENVIF_VIF_MAC_QUERY_STATE MacQueryState;
- XENVIF_VIF_MAC_QUERY_MAXIMUM_FRAME_SIZE MacQueryMaximumFrameSize;
- XENVIF_VIF_MAC_QUERY_PERMANENT_ADDRESS MacQueryPermanentAddress;
- XENVIF_VIF_MAC_QUERY_CURRENT_ADDRESS MacQueryCurrentAddress;
- XENVIF_VIF_MAC_QUERY_MULTICAST_ADDRESSES MacQueryMulticastAddresses;
- XENVIF_VIF_MAC_SET_MULTICAST_ADDRESSES MacSetMulticastAddresses;
- XENVIF_VIF_MAC_SET_FILTER_LEVEL MacSetFilterLevel;
- XENVIF_VIF_MAC_QUERY_FILTER_LEVEL MacQueryFilterLevel;
-};
-
/*! \struct _XENVIF_VIF_INTERFACE_V2
\brief VIF interface version 2
\ingroup interfaces
#endif // _WINDLL
-#define XENVIF_VIF_INTERFACE_VERSION_MIN 1
+#define XENVIF_VIF_INTERFACE_VERSION_MIN 2
#define XENVIF_VIF_INTERFACE_VERSION_MAX 3
#endif // _XENVIF_INTERFACE_H
PXENVIF_TRANSMITTER_RING *Ring;
LONG MaxQueues;
LONG NumQueues;
- LONG_PTR Offset[XENVIF_TRANSMITTER_PACKET_OFFSET_COUNT];
BOOLEAN Split;
BOOLEAN MulticastControl;
ULONG DisableIpVersion4Gso;
#define XENVIF_TRANSMITTER_LOCK_BIT ((ULONG_PTR)1)
-static FORCEINLINE ULONG
-__TransmitterReversePacketList(
- IN PXENVIF_TRANSMITTER_PACKET_V1 *Packet
- )
-{
- PXENVIF_TRANSMITTER_PACKET_V1 HeadPacket;
- ULONG Count;
-
- HeadPacket = NULL;
- Count = 0;
-
- while (*Packet != NULL) {
- PXENVIF_TRANSMITTER_PACKET_V1 Next;
-
- ASSERT(((ULONG_PTR)*Packet & XENVIF_TRANSMITTER_LOCK_BIT) == 0);
-
- Next = (*Packet)->Next;
-
- (*Packet)->Next = HeadPacket;
- HeadPacket = *Packet;
-
- *Packet = Next;
- Count++;
- }
-
- *Packet = HeadPacket;
-
- return Count;
-}
-
static DECLSPEC_NOINLINE VOID
TransmitterRingSwizzle(
IN PXENVIF_TRANSMITTER_RING Ring
)
{
PXENVIF_FRONTEND Frontend;
- PXENVIF_VIF_CONTEXT VifContext;
-
- Frontend = Transmitter->Frontend;
- VifContext = PdoGetVifContext(FrontendGetPdo(Frontend));
-
- switch (VifGetVersion(VifContext)) {
- case 1: {
- PXENVIF_TRANSMITTER_PACKET_V1 HeadPacket;
- PXENVIF_TRANSMITTER_PACKET_V1 NextPacket;
-
- HeadPacket = NextPacket = NULL;
-
- while (!IsListEmpty(List)) {
- PLIST_ENTRY ListEntry;
- PXENVIF_TRANSMITTER_PACKET Packet;
-
- ListEntry = RemoveTailList(List);
- ASSERT3P(ListEntry, !=, List);
-
- Packet = CONTAINING_RECORD(ListEntry, XENVIF_TRANSMITTER_PACKET, ListEntry);
- Packet->ListEntry.Flink = Packet->ListEntry.Blink = NULL;
-
- HeadPacket = Packet->Cookie;
- HeadPacket->Next = NextPacket;
- NextPacket = HeadPacket;
-
- HeadPacket->Completion = Packet->Completion;
- __TransmitterPutPacket(Transmitter, Packet);
- }
-
- if (HeadPacket != NULL)
- VifTransmitterReturnPacketsVersion1(VifContext, HeadPacket);
+ if (IsListEmpty(List))
+ return;
- break;
- }
- default:
- if (!IsListEmpty(List))
- VifTransmitterReturnPackets(VifContext, List);
+ Frontend = Transmitter->Frontend;
- break;
- }
+ VifTransmitterReturnPackets(PdoGetVifContext(FrontendGetPdo(Frontend)),
+ List);
}
static FORCEINLINE BOOLEAN
IN BOOLEAN Crashing
)
{
- PXENVIF_TRANSMITTER Transmitter = Argument;
-
+ UNREFERENCED_PARAMETER(Argument);
UNREFERENCED_PARAMETER(Crashing);
-
- XENBUS_DEBUG(Printf,
- &Transmitter->DebugInterface,
- "OFFSETS: Offset @ %ld Length @ %ld Mdl @ %ld\n",
- Transmitter->Offset[XENVIF_TRANSMITTER_PACKET_OFFSET_OFFSET],
- Transmitter->Offset[XENVIF_TRANSMITTER_PACKET_LENGTH_OFFSET],
- Transmitter->Offset[XENVIF_TRANSMITTER_PACKET_MDL_OFFSET]);
}
NTSTATUS
ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
KeFlushQueuedDpcs();
- RtlZeroMemory(Transmitter->Offset,
- sizeof (LONG_PTR) * XENVIF_TRANSMITTER_PACKET_OFFSET_COUNT);
-
Index = Transmitter->MaxQueues;
while (--Index >= 0) {
PXENVIF_TRANSMITTER_RING Ring = Transmitter->Ring[Index];
__TransmitterFree(Transmitter);
}
-NTSTATUS
-TransmitterSetPacketOffset(
- IN PXENVIF_TRANSMITTER Transmitter,
- IN XENVIF_TRANSMITTER_PACKET_OFFSET Type,
- IN LONG_PTR Value
- )
-{
- NTSTATUS status;
-
- status = STATUS_INVALID_PARAMETER;
- if (Type >= XENVIF_TRANSMITTER_PACKET_OFFSET_COUNT)
- goto fail1;
-
- Transmitter->Offset[Type] = Value;
-
- return STATUS_SUCCESS;
-
-fail1:
- Error("fail1 (%08x)\n", status);
-
- return status;
-}
-
static BOOLEAN
__TransmitterGetPacketHeadersPullup(
IN PVOID Argument,
return status;
}
-VOID
-TransmitterQueuePacketsVersion1(
- IN PXENVIF_TRANSMITTER Transmitter,
- IN PXENVIF_TRANSMITTER_PACKET_V1 HeadPacket
- )
-{
-#define OFFSET_EXISTS(_Transmitter, _Packet, _Type) \
- ((_Transmitter)->Offset[XENVIF_TRANSMITTER_PACKET_ ## _Type ## _OFFSET] != 0)
-
-#define OFFSET(_Transmitter, _Packet, _Type) \
- ((OFFSET_EXISTS(_Transmitter, _Packet, _Type)) ? \
- (PVOID)((PUCHAR)(_Packet) + \
- (_Transmitter)->Offset[XENVIF_TRANSMITTER_PACKET_ ## _Type ## _OFFSET]) : \
- NULL)
-
- LIST_ENTRY List;
- PXENVIF_FRONTEND Frontend;
- PXENVIF_VIF_CONTEXT VifContext;
-
- Frontend = Transmitter->Frontend;
- VifContext = PdoGetVifContext(FrontendGetPdo(Frontend));
-
- ASSERT3U(VifGetVersion(VifContext), ==, 1);
-
- InitializeListHead(&List);
-
- while (HeadPacket != NULL) {
- PXENVIF_TRANSMITTER_PACKET Packet;
-
- Packet = __TransmitterGetPacket(Transmitter);
- if (Packet == NULL)
- break;
-
- Packet->Cookie = HeadPacket;
- Packet->Send = HeadPacket->Send;
-
- ASSERT(OFFSET_EXISTS(Transmitter, HeadPacket, MDL));
- Packet->Mdl = *(PMDL *)OFFSET(Transmitter, HeadPacket, MDL);
-
- if (OFFSET_EXISTS(Transmitter, HeadPacket, OFFSET))
- Packet->Offset = *(PULONG)OFFSET(Transmitter, HeadPacket, OFFSET);
- else
- Packet->Offset = 0;
-
- ASSERT(OFFSET_EXISTS(Transmitter, HeadPacket, LENGTH));
- Packet->Length = *(PULONG)OFFSET(Transmitter, HeadPacket, LENGTH);
-
- // Packets from legacy clients go to queue 0.
- Packet->Value = 0;
-
- InsertTailList(&List, &Packet->ListEntry);
-
- HeadPacket = HeadPacket->Next;
- }
-
- if (!IsListEmpty(&List))
- TransmitterQueuePackets(Transmitter, &List);
-
- if (HeadPacket != NULL)
- VifTransmitterReturnPacketsVersion1(VifContext,
- HeadPacket);
-
-#undef OFFSET
-#undef OFFSET_EXISTS
-}
-
VOID
TransmitterQueuePackets(
IN PXENVIF_TRANSMITTER Transmitter,
OUT PULONG Size
);
-extern VOID
-TransmitterQueuePacketsVersion1(
- IN PXENVIF_TRANSMITTER Transmitter,
- IN PXENVIF_TRANSMITTER_PACKET_V1 HeadPacket
- );
-
extern VOID
TransmitterQueuePackets(
IN PXENVIF_TRANSMITTER Transmitter,
OUT PULONG Size
);
-extern NTSTATUS
-TransmitterSetPacketOffset(
- IN PXENVIF_TRANSMITTER Transmitter,
- IN XENVIF_TRANSMITTER_PACKET_OFFSET Type,
- IN LONG_PTR Value
- );
-
extern NTSTATUS
TransmitterGetPacketHeaders(
IN PXENVIF_TRANSMITTER Transmitter,
return status;
}
-static NTSTATUS
-VifTransmitterSetPacketOffset(
- IN PINTERFACE Interface,
- IN XENVIF_TRANSMITTER_PACKET_OFFSET Type,
- IN LONG_PTR Value
- )
-{
- PXENVIF_VIF_CONTEXT Context = Interface->Context;
- NTSTATUS status;
-
- AcquireMrswLockShared(&Context->Lock);
-
- ASSERT3U(VifGetVersion(Context), ==, 1);
- status = TransmitterSetPacketOffset(FrontendGetTransmitter(Context->Frontend),
- Type,
- Value);
-
- ReleaseMrswLockShared(&Context->Lock);
-
- return status;
-}
-
static VOID
VifReceiverReturnPackets(
IN PINTERFACE Interface,
return status;
}
-static NTSTATUS
-VifTransmitterQueuePacketsVersion1(
- IN PINTERFACE Interface,
- IN PXENVIF_TRANSMITTER_PACKET_V1 Head
- )
-{
- PXENVIF_VIF_CONTEXT Context = Interface->Context;
- NTSTATUS status;
-
- AcquireMrswLockShared(&Context->Lock);
-
- status = STATUS_UNSUCCESSFUL;
- if (Context->Enabled == FALSE)
- goto fail1;
-
- ASSERT3U(VifGetVersion(Context), ==, 1);
- TransmitterQueuePacketsVersion1(FrontendGetTransmitter(Context->Frontend),
- Head);
-
- ReleaseMrswLockShared(&Context->Lock);
-
- return STATUS_SUCCESS;
-
-fail1:
- ReleaseMrswLockShared(&Context->Lock);
-
- return status;
-}
-
static NTSTATUS
VifTransmitterQueuePackets(
IN PINTERFACE Interface,
ReleaseMrswLockExclusive(&Context->Lock, Irql, FALSE);
}
-static struct _XENVIF_VIF_INTERFACE_V1 VifInterfaceVersion1 = {
- { sizeof (struct _XENVIF_VIF_INTERFACE_V1), 1, NULL, NULL, NULL },
- VifAcquire,
- VifRelease,
- VifEnable,
- VifDisable,
- VifQueryStatistic,
- VifReceiverReturnPackets,
- VifReceiverSetOffloadOptions,
- VifReceiverQueryRingSize,
- VifTransmitterSetPacketOffset,
- VifTransmitterQueuePacketsVersion1,
- VifTransmitterQueryOffloadOptions,
- VifTransmitterQueryLargePacketSize,
- VifTransmitterQueryRingSize,
- VifMacQueryState,
- VifMacQueryMaximumFrameSize,
- VifMacQueryPermanentAddress,
- VifMacQueryCurrentAddress,
- VifMacQueryMulticastAddresses,
- VifMacSetMulticastAddresses,
- VifMacSetFilterLevel,
- VifMacQueryFilterLevel
-};
-
static struct _XENVIF_VIF_INTERFACE_V2 VifInterfaceVersion2 = {
{ sizeof (struct _XENVIF_VIF_INTERFACE_V2), 2, NULL, NULL, NULL },
VifAcquire,
NTSTATUS status;
switch (Version) {
- case 1: {
- struct _XENVIF_VIF_INTERFACE_V1 *VifInterface;
-
- VifInterface = (struct _XENVIF_VIF_INTERFACE_V1 *)Interface;
-
- status = STATUS_BUFFER_OVERFLOW;
- if (Size < sizeof (struct _XENVIF_VIF_INTERFACE_V1))
- break;
-
- *VifInterface = VifInterfaceVersion1;
-
- ASSERT3U(Interface->Version, ==, Version);
- Interface->Context = Context;
-
- status = STATUS_SUCCESS;
- break;
- }
case 2: {
struct _XENVIF_VIF_INTERFACE_V2 *VifInterface;
List);
}
-VOID
-VifTransmitterReturnPacketsVersion1(
- IN PXENVIF_VIF_CONTEXT Context,
- IN PXENVIF_TRANSMITTER_PACKET_V1 Head
- )
-{
- ASSERT3U(VifGetVersion(Context), ==, 1);
-
- Context->Callback(Context->Argument,
- XENVIF_TRANSMITTER_RETURN_PACKETS,
- Head);
-}
-
VOID
VifTransmitterReturnPackets(
IN PXENVIF_VIF_CONTEXT Context,
IN PLIST_ENTRY List
);
-extern VOID
-VifTransmitterReturnPacketsVersion1(
- IN PXENVIF_VIF_CONTEXT Context,
- IN PXENVIF_TRANSMITTER_PACKET_V1 Head
- );
-
extern VOID
VifTransmitterReturnPackets(
IN PXENVIF_VIF_CONTEXT Context,