|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH 02/10] Add VIF interface version 2
Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx>
---
include/vif_interface.h | 84 ++++++++++++++++++++++--
src/xenvif/transmitter.c | 164 ++++++++++++++++++++++++++++++++++++++++-------
src/xenvif/transmitter.h | 17 +++++
src/xenvif/vif.c | 145 +++++++++++++++++++++++++++++++++++++++--
src/xenvif/vif.h | 11 ++++
5 files changed, 386 insertions(+), 35 deletions(-)
diff --git a/include/vif_interface.h b/include/vif_interface.h
index 8bde731..4ce61c4 100644
--- a/include/vif_interface.h
+++ b/include/vif_interface.h
@@ -116,6 +116,7 @@ struct _XENVIF_PACKET_CHECKSUM_FLAGS_V1 {
};
};
+
typedef struct _XENVIF_PACKET_CHECKSUM_FLAGS_V1 XENVIF_PACKET_CHECKSUM_FLAGS,
*PXENVIF_PACKET_CHECKSUM_FLAGS;
#pragma warning(pop)
@@ -269,17 +270,25 @@ C_ASSERT(sizeof (struct _XENVIF_TRANSMITTER_PACKET_V1) <=
(3 * sizeof (PVOID)));
\brief Transmit-side packet structure
*/
struct _XENVIF_TRANSMITTER_PACKET_V2 {
+ /*! List entry used for chaining packets together */
LIST_ENTRY ListEntry;
+ /*! MDL referencing the packet's buffer */
PMDL Mdl;
+ /*! Offset of start of packet in MDL */
ULONG Offset;
+ /*! Total length of packet */
ULONG Length;
+ /*! Opaque cookie used to store context information for packet return */
PVOID Cookie;
+ /*! Packet information passed down to subscriber */
XENVIF_TRANSMITTER_PACKET_SEND_INFO Send;
+ /*! Information passed up from subscriber for packet completion */
XENVIF_TRANSMITTER_PACKET_COMPLETION_INFO Completion;
};
typedef struct _XENVIF_TRANSMITTER_PACKET_V2 XENVIF_TRANSMITTER_PACKET_V2,
*PXENVIF_TRANSMITTER_PACKET_V2;
+
/*! \enum _XENVIF_TRANSMITTER_PACKET_OFFSET
\brief Offsets of packet metadata relative to
XENVIF_TRANSMITTER_PACKET_V1 pointer
@@ -501,6 +510,34 @@ typedef NTSTATUS
IN PXENVIF_TRANSMITTER_PACKET_V1 Head
);
+/*! \typedef XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS_V2
+ \brief Queue transmit side packets at the provider
+
+ \param Interface The interface header
+ \param List List of XENVIF_TRANSMITTER_PACKET_V2
+*/
+typedef NTSTATUS
+(*XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS_V2)(
+ IN PINTERFACE Interface,
+ IN PLIST_ENTRY List
+ );
+
+/*! \typedef XENVIF_VIF_TRANSMITTER_GET_PACKET_HEADERS
+ \brief Get a copy of the packet headers and each the offset of each
+
+ \param Interface The interface header
+*/
+typedef NTSTATUS
+(*XENVIF_VIF_TRANSMITTER_GET_PACKET_HEADERS)(
+ IN PINTERFACE Interface,
+ IN PMDL Mdl,
+ IN ULONG Offset,
+ IN ULONG Length,
+ OUT PVOID HeaderBuffer,
+ IN ULONG HeaderLength,
+ OUT PXENVIF_PACKET_INFO Info
+ );
+
/*! \typedef XENVIF_VIF_TRANSMITTER_QUERY_OFFLOAD_OPTIONS
\brief Query the available set of transmit side offload options
@@ -694,10 +731,6 @@ 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
- \ingroup interfaces
-*/
struct _XENVIF_VIF_INTERFACE_V1 {
INTERFACE Interface;
XENVIF_VIF_ACQUIRE Acquire;
@@ -723,17 +756,54 @@ struct _XENVIF_VIF_INTERFACE_V1 {
XENVIF_VIF_MAC_QUERY_FILTER_LEVEL MacQueryFilterLevel;
};
-typedef struct _XENVIF_VIF_INTERFACE_V1 XENVIF_VIF_INTERFACE,
*PXENVIF_VIF_INTERFACE;
+typedef struct _XENVIF_VIF_INTERFACE_V1 XENVIF_VIF_INTERFACE_V1,
*PXENVIF_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_SET_OFFLOAD_OPTIONS ReceiverSetOffloadOptions;
+ XENVIF_VIF_RECEIVER_QUERY_RING_SIZE ReceiverQueryRingSize;
+ XENVIF_VIF_TRANSMITTER_SET_PACKET_OFFSET
TransmitterSetPacketOffset; // obsolete
+ XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS_V1 TransmitterQueuePackets;
// obsolete
+ 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;
+ XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS_V2 TransmitterQueuePacketsV2;
+ XENVIF_VIF_TRANSMITTER_GET_PACKET_HEADERS
TransmitterGetPacketHeaders;
+};
+
+typedef struct _XENVIF_VIF_INTERFACE_V2 XENVIF_VIF_INTERFACE_V2,
*PXENVIF_VIF_INTERFACE_V2;
+
+typedef struct _XENVIF_VIF_INTERFACE_V2 XENVIF_VIF_INTERFACE,
*PXENVIF_VIF_INTERFACE;
/*! \def XENVIF_VIF
- \brief Macro at assist in method invocation
+ \brief Macro to assist in method invocation
*/
#define XENVIF_VIF(_Method, _Interface, ...) \
(_Interface)-> ## _Method((PINTERFACE)(_Interface), __VA_ARGS__)
+/*! \def XENVIF_VIF_VERSION
+ \brief Macro to assist in getting interface version in use
+*/
+#define XENVIF_VIF_VERSION(_Interface) \
+ ((_Interface)->Interface.Version)
+
#endif // _WINDLL
#define XENVIF_VIF_INTERFACE_VERSION_MIN 1
-#define XENVIF_VIF_INTERFACE_VERSION_MAX 1
+#define XENVIF_VIF_INTERFACE_VERSION_MAX 2
#endif // _XENVIF_INTERFACE_H
diff --git a/src/xenvif/transmitter.c b/src/xenvif/transmitter.c
index 38e4cb2..6fd542e 100644
--- a/src/xenvif/transmitter.c
+++ b/src/xenvif/transmitter.c
@@ -2386,33 +2386,44 @@ TransmitterReturnPackets(
IN PLIST_ENTRY List
)
{
- PXENVIF_FRONTEND Frontend;
- PXENVIF_TRANSMITTER_PACKET_V1 HeadPacket;
- PXENVIF_TRANSMITTER_PACKET_V1 NextPacket;
+ PXENVIF_VIF_CONTEXT Context;
+
+ Context = PdoGetVifContext(FrontendGetPdo(Transmitter->Frontend));
- HeadPacket = NULL;
- NextPacket = NULL;
- while (!IsListEmpty(List)) {
- PLIST_ENTRY ListEntry;
- PXENVIF_TRANSMITTER_PACKET_V2 Packet;
+ switch (VifGetVersion(Context)) {
+ case 1: {
+ PXENVIF_TRANSMITTER_PACKET_V1 HeadPacket;
+ PXENVIF_TRANSMITTER_PACKET_V1 NextPacket;
- ListEntry = RemoveTailList(List);
- ASSERT3P(ListEntry, !=, List);
+ HeadPacket = NULL;
+ NextPacket = NULL;
+ while (!IsListEmpty(List)) {
+ PLIST_ENTRY ListEntry;
+ PXENVIF_TRANSMITTER_PACKET_V2 Packet;
- Packet = CONTAINING_RECORD(ListEntry, XENVIF_TRANSMITTER_PACKET_V2,
ListEntry);
+ ListEntry = RemoveTailList(List);
+ ASSERT3P(ListEntry, !=, List);
- HeadPacket = Packet->Cookie;
- HeadPacket->Next = NextPacket;
- HeadPacket->Completion = Packet->Completion;
+ Packet = CONTAINING_RECORD(ListEntry,
XENVIF_TRANSMITTER_PACKET_V2, ListEntry);
- __TransmitterPutPacket(Transmitter, Packet);
- NextPacket = HeadPacket;
- }
+ HeadPacket = Packet->Cookie;
+ HeadPacket->Next = NextPacket;
+ HeadPacket->Completion = Packet->Completion;
- Frontend = Transmitter->Frontend;
+ __TransmitterPutPacket(Transmitter, Packet);
+ NextPacket = HeadPacket;
+ }
- VifTransmitterReturnPackets(PdoGetVifContext(FrontendGetPdo(Frontend)),
- HeadPacket);
+ VifTransmitterReturnPackets(Context, HeadPacket);
+ break;
+ }
+ case 2:
+ VifTransmitterReturnPacketsV2(Context, List);
+ break;
+ default:
+ ASSERT(FALSE);
+ break;
+ }
}
static FORCEINLINE BOOLEAN
@@ -3803,9 +3814,9 @@ TransmitterQueuePacketsV1(
// if HeadPacket != NULL, errors occured and need returning
if (HeadPacket != NULL) {
PXENVIF_TRANSMITTER_PACKET_V1 Packet;
- PXENVIF_FRONTEND Frontend;
+ PXENVIF_VIF_CONTEXT Context;
- Frontend = Transmitter->Frontend;
+ Context = PdoGetVifContext(FrontendGetPdo(Transmitter->Frontend));
Packet = HeadPacket;
while (Packet != NULL) {
@@ -3813,8 +3824,7 @@ TransmitterQueuePacketsV1(
Packet = Packet->Next;
}
- VifTransmitterReturnPackets(PdoGetVifContext(FrontendGetPdo(Frontend)),
- HeadPacket);
+ VifTransmitterReturnPackets(Context, HeadPacket);
}
#undef OFFSET
@@ -3822,6 +3832,112 @@ TransmitterQueuePacketsV1(
}
VOID
+TransmitterQueuePacketsV2(
+ IN PXENVIF_TRANSMITTER Transmitter,
+ IN PLIST_ENTRY List
+ )
+{
+ PLIST_ENTRY ListEntry;
+ PXENVIF_TRANSMITTER_RING Ring;
+
+ // We need to hash for a ring eventually. Since there is only a
+ // single ring for now, we just use that.
+ ListEntry = Transmitter->List.Flink;
+ Ring = CONTAINING_RECORD(ListEntry, XENVIF_TRANSMITTER_RING, ListEntry);
+
+ __TransmitterRingQueuePackets(Ring, List);
+}
+
+static BOOLEAN
+TransmitterHeaderPullup(
+ IN PVOID Argument,
+ IN PUCHAR DestinationVa,
+ IN PXENVIF_PACKET_PAYLOAD Payload,
+ IN ULONG Length
+ )
+{
+ PMDL Mdl;
+ ULONG Offset;
+
+ UNREFERENCED_PARAMETER(Argument);
+
+ Mdl = Payload->Mdl;
+ Offset = Payload->Offset;
+
+ if (Payload->Length < Length)
+ goto fail1;
+
+ Payload->Length -= Length;
+
+ while (Length != 0) {
+ PUCHAR MdlMappedSystemVa;
+ ULONG MdlByteCount;
+ ULONG CopyLength;
+
+ ASSERT(Mdl != NULL);
+
+ MdlMappedSystemVa = MmGetSystemAddressForMdlSafe(Mdl,
NormalPagePriority);
+ ASSERT(MdlMappedSystemVa != NULL);
+
+ MdlMappedSystemVa += Offset;
+
+ MdlByteCount = Mdl->ByteCount - Offset;
+
+ CopyLength = __min(MdlByteCount, Length);
+
+ RtlCopyMemory(DestinationVa, MdlMappedSystemVa, CopyLength);
+ DestinationVa += CopyLength;
+
+ Offset += CopyLength;
+ Length -= CopyLength;
+
+ MdlByteCount -= CopyLength;
+ if (MdlByteCount == 0) {
+ Mdl = Mdl->Next;
+ Offset = 0;
+ }
+ }
+
+ Payload->Mdl = Mdl;
+ Payload->Offset = Offset;
+
+ return TRUE;
+
+fail1:
+ Error("fail1\n");
+
+ return FALSE;
+}
+
+NTSTATUS
+TransmitterGetPacketHeaders(
+ IN PXENVIF_TRANSMITTER Transmitter,
+ IN PMDL Mdl,
+ IN ULONG Offset,
+ IN ULONG Length,
+ OUT PVOID HeaderBuffer,
+ IN ULONG HeaderLength,
+ OUT PXENVIF_PACKET_INFO Info
+ )
+{
+ XENVIF_PACKET_PAYLOAD Payload;
+ NTSTATUS status;
+
+ UNREFERENCED_PARAMETER(Transmitter);
+
+ Payload.Mdl = Mdl;
+ Payload.Offset = Offset;
+ Payload.Length = Length;
+
+ status = ParsePacket(HeaderBuffer,
+ TransmitterHeaderPullup,
+ &HeaderLength,
+ &Payload,
+ Info);
+ return status;
+}
+
+VOID
TransmitterAbortPackets(
IN PXENVIF_TRANSMITTER Transmitter
)
diff --git a/src/xenvif/transmitter.h b/src/xenvif/transmitter.h
index 661eeae..c359c20 100644
--- a/src/xenvif/transmitter.h
+++ b/src/xenvif/transmitter.h
@@ -113,6 +113,23 @@ TransmitterQueuePacketsV1(
);
extern VOID
+TransmitterQueuePacketsV2(
+ IN PXENVIF_TRANSMITTER Transmitter,
+ IN PLIST_ENTRY List
+ );
+
+extern NTSTATUS
+TransmitterGetPacketHeaders(
+ IN PXENVIF_TRANSMITTER Transmitter,
+ IN PMDL Mdl,
+ IN ULONG Offset,
+ IN ULONG Length,
+ OUT PVOID HeaderBuffer,
+ IN ULONG HeaderLength,
+ OUT PXENVIF_PACKET_INFO Info
+ );
+
+extern VOID
TransmitterQueryOffloadOptions(
IN PXENVIF_TRANSMITTER Transmitter,
OUT PXENVIF_VIF_OFFLOAD_OPTIONS Options
diff --git a/src/xenvif/vif.c b/src/xenvif/vif.c
index d6da258..8c1156a 100644
--- a/src/xenvif/vif.c
+++ b/src/xenvif/vif.c
@@ -46,6 +46,7 @@ struct _XENVIF_VIF_CONTEXT {
PXENVIF_PDO Pdo;
XENVIF_MRSW_LOCK Lock;
LONG References;
+ ULONG Version;
PXENVIF_FRONTEND Frontend;
BOOLEAN Enabled;
XENVIF_VIF_CALLBACK Callback;
@@ -302,6 +303,75 @@ fail1:
return status;
}
+static NTSTATUS
+VifTransmitterQueuePacketsV2(
+ IN PINTERFACE Interface,
+ IN PLIST_ENTRY List
+ )
+{
+ PXENVIF_VIF_CONTEXT Context = Interface->Context;
+ NTSTATUS status;
+
+ AcquireMrswLockShared(&Context->Lock);
+
+ status = STATUS_UNSUCCESSFUL;
+ if (Context->Enabled == FALSE)
+ goto fail1;
+
+ TransmitterQueuePacketsV2(FrontendGetTransmitter(Context->Frontend),
+ List);
+
+ ReleaseMrswLockShared(&Context->Lock);
+
+ return STATUS_SUCCESS;
+
+fail1:
+ ReleaseMrswLockShared(&Context->Lock);
+
+ return status;
+}
+
+static NTSTATUS
+VifTransmitterGetPacketHeaders(
+ IN PINTERFACE Interface,
+ IN PMDL Mdl,
+ IN ULONG Offset,
+ IN ULONG Length,
+ OUT PVOID HeaderBuffer,
+ IN ULONG HeaderLength,
+ OUT PXENVIF_PACKET_INFO Info
+ )
+{
+ PXENVIF_VIF_CONTEXT Context = Interface->Context;
+ NTSTATUS status;
+
+ AcquireMrswLockShared(&Context->Lock);
+
+ status = STATUS_UNSUCCESSFUL;
+ if (Context->Enabled == FALSE)
+ goto fail1;
+
+ status =
TransmitterGetPacketHeaders(FrontendGetTransmitter(Context->Frontend),
+ Mdl,
+ Offset,
+ Length,
+ HeaderBuffer,
+ HeaderLength,
+ Info);
+ if (!NT_SUCCESS(status))
+ goto fail2;
+
+ ReleaseMrswLockShared(&Context->Lock);
+
+ return STATUS_SUCCESS;
+
+fail2:
+fail1:
+ ReleaseMrswLockShared(&Context->Lock);
+
+ return status;
+}
+
static VOID
VifTransmitterQueryOffloadOptions(
IN PINTERFACE Interface,
@@ -560,7 +630,9 @@ VifAcquire(
if (Context->References++ != 0)
goto done;
- Trace("====>\n");
+ Trace("====> (%u)\n", Interface->Version);
+
+ Context->Version = Interface->Version;
status = XENBUS_SUSPEND(Acquire, &Context->SuspendInterface);
if (!NT_SUCCESS(status))
@@ -577,7 +649,7 @@ VifAcquire(
Context->Frontend = PdoGetFrontend(Context->Pdo);
- Trace("<====\n");
+ Trace("<==== (%u)\n", Interface->Version);
done:
ReleaseMrswLockExclusive(&Context->Lock, Irql, FALSE);
@@ -612,7 +684,7 @@ VifRelease(
if (--Context->References > 0)
goto done;
- Trace("====>\n");
+ Trace("====> (%u)\n", Interface->Version);
ASSERT(!Context->Enabled);
@@ -625,7 +697,9 @@ VifRelease(
XENBUS_SUSPEND(Release, &Context->SuspendInterface);
- Trace("<====\n");
+ Context->Version = 0;
+
+ Trace("<==== (%u)\n", Interface->Version);
done:
ReleaseMrswLockExclusive(&Context->Lock, Irql, FALSE);
@@ -656,6 +730,33 @@ static struct _XENVIF_VIF_INTERFACE_V1
VifInterfaceVersion1 = {
VifMacQueryFilterLevel
};
+static struct _XENVIF_VIF_INTERFACE_V2 VifInterfaceVersion2 = {
+ { sizeof (struct _XENVIF_VIF_INTERFACE_V2), 2, NULL, NULL, NULL },
+ VifAcquire,
+ VifRelease,
+ VifEnable,
+ VifDisable,
+ VifQueryStatistic,
+ VifReceiverReturnPackets,
+ VifReceiverSetOffloadOptions,
+ VifReceiverQueryRingSize,
+ VifTransmitterSetPacketOffset,
+ VifTransmitterQueuePackets,
+ VifTransmitterQueryOffloadOptions,
+ VifTransmitterQueryLargePacketSize,
+ VifTransmitterQueryRingSize,
+ VifMacQueryState,
+ VifMacQueryMaximumFrameSize,
+ VifMacQueryPermanentAddress,
+ VifMacQueryCurrentAddress,
+ VifMacQueryMulticastAddresses,
+ VifMacSetMulticastAddresses,
+ VifMacSetFilterLevel,
+ VifMacQueryFilterLevel,
+ VifTransmitterQueuePacketsV2,
+ VifTransmitterGetPacketHeaders
+};
+
NTSTATUS
VifInitialize(
IN PXENVIF_PDO Pdo,
@@ -737,6 +838,23 @@ VifGetInterface(
status = STATUS_SUCCESS;
break;
}
+ case 2: {
+ struct _XENVIF_VIF_INTERFACE_V2 *VifInterface;
+
+ VifInterface = (struct _XENVIF_VIF_INTERFACE_V2 *)Interface;
+
+ status = STATUS_BUFFER_OVERFLOW;
+ if (Size < sizeof(struct _XENVIF_VIF_INTERFACE_V2))
+ break;
+
+ *VifInterface = VifInterfaceVersion2;
+
+ ASSERT3U(Interface->Version, ==, Version);
+ Interface->Context = Context;
+
+ status = STATUS_SUCCESS;
+ break;
+ }
default:
status = STATUS_NOT_SUPPORTED;
break;
@@ -793,6 +911,25 @@ VifTransmitterReturnPackets(
Head);
}
+VOID
+VifTransmitterReturnPacketsV2(
+ IN PXENVIF_VIF_CONTEXT Context,
+ IN PLIST_ENTRY List
+ )
+{
+ Context->Callback(Context->Argument,
+ XENVIF_TRANSMITTER_RETURN_PACKETS,
+ List);
+}
+
+ULONG
+VifGetVersion(
+ IN PXENVIF_VIF_CONTEXT Context
+ )
+{
+ return Context->Version;
+}
+
extern PXENVIF_THREAD
VifGetMacThread(
IN PXENVIF_VIF_CONTEXT Context
diff --git a/src/xenvif/vif.h b/src/xenvif/vif.h
index 0ef6687..fe0f9e4 100644
--- a/src/xenvif/vif.h
+++ b/src/xenvif/vif.h
@@ -74,10 +74,21 @@ VifTransmitterReturnPackets(
IN PXENVIF_TRANSMITTER_PACKET_V1 Head
);
+extern VOID
+VifTransmitterReturnPacketsV2(
+ IN PXENVIF_VIF_CONTEXT Context,
+ IN PLIST_ENTRY List
+ );
+
extern PXENVIF_THREAD
VifGetMacThread(
IN PXENVIF_VIF_CONTEXT Context
);
+extern ULONG
+VifGetVersion(
+ IN PXENVIF_VIF_CONTEXT Context
+ );
+
#endif // _XENVIF_VIF_H
--
1.9.4.msysgit.1
_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
http://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |