XENVIF_MAC_STATE_CHANGE
} XENVIF_VIF_CALLBACK_TYPE, *PXENVIF_VIF_CALLBACK_TYPE;
-/*! \typedef XENVIF_VIF_CALLBACK_PARAMETERS_V9
+union _XENVIF_VIF_CALLBACK_PARAMETERS_V9 {
+ struct {
+ PVOID Cookie;
+ PXENVIF_TRANSMITTER_PACKET_COMPLETION_INFO Completion;
+ } TransmitterReturnPacket;
+ struct {
+ ULONG Index;
+ PMDL Mdl;
+ ULONG Offset;
+ ULONG Length;
+ XENVIF_PACKET_CHECKSUM_FLAGS Flags;
+ USHORT MaximumSegmentSize;
+ USHORT TagControlInformation;
+ PXENVIF_PACKET_INFO Info;
+ PXENVIF_PACKET_HASH Hash;
+ BOOLEAN More;
+ PVOID Cookie;
+ } ReceiverQueuePacket;
+};
+
+/*! \typedef XENVIF_VIF_CALLBACK_PARAMETERS_V10
\brief VIF interface version 9 parameters for provider to subscriber callback function
\b XENVIF_TRANSMITTER_RETURN_PACKET:
\param Hash Hash information for the packet
\param More A flag to indicate whether more packets will be queued for the same CPU
\param Cookie Cookie that should be passed to XENVIF_RECEIVER_RETURN_PACKET method
+ \param Pause A flag to request that no more packets be queued for a short period of time
\b XENVIF_MAC_STATE_CHANGE:
No additional arguments
*/
-union _XENVIF_VIF_CALLBACK_PARAMETERS_V9 {
+union _XENVIF_VIF_CALLBACK_PARAMETERS_V10 {
struct {
PVOID Cookie;
PXENVIF_TRANSMITTER_PACKET_COMPLETION_INFO Completion;
PXENVIF_PACKET_HASH Hash;
BOOLEAN More;
PVOID Cookie;
+ BOOLEAN Pause;
} ReceiverQueuePacket;
};
...
);
-typedef union _XENVIF_VIF_CALLBACK_PARAMETERS_V9 XENVIF_VIF_CALLBACK_PARAMETERS, *PXENVIF_VIF_CALLBACK_PARAMETERS;
+typedef VOID
+(*XENVIF_VIF_CALLBACK_V9)(
+ IN PVOID Argument OPTIONAL,
+ IN XENVIF_VIF_CALLBACK_TYPE Type,
+ IN union _XENVIF_VIF_CALLBACK_PARAMETERS_V9 *Parameters
+ );
+
+typedef union _XENVIF_VIF_CALLBACK_PARAMETERS_V10 XENVIF_VIF_CALLBACK_PARAMETERS, *PXENVIF_VIF_CALLBACK_PARAMETERS;
/*! \typedef XENVIF_VIF_CALLBACK
\brief Provider to subscriber callback function
IN PVOID Argument OPTIONAL
);
+typedef NTSTATUS
+(*XENVIF_VIF_ENABLE_V9)(
+ IN PINTERFACE Interface,
+ IN XENVIF_VIF_CALLBACK_V9 Callback,
+ IN PVOID Argument OPTIONAL
+ );
+
/*! \typedef XENVIF_VIF_ENABLE
\brief Enable the VIF interface
\ingroup interfaces
*/
struct _XENVIF_VIF_INTERFACE_V9 {
+ INTERFACE Interface;
+ XENVIF_VIF_ACQUIRE Acquire;
+ XENVIF_VIF_RELEASE Release;
+ XENVIF_VIF_ENABLE_V9 EnableVersion9;
+ XENVIF_VIF_DISABLE Disable;
+ XENVIF_VIF_QUERY_STATISTIC QueryStatistic;
+ XENVIF_VIF_QUERY_RING_COUNT QueryRingCount;
+ XENVIF_VIF_UPDATE_HASH_MAPPING UpdateHashMapping;
+ XENVIF_VIF_RECEIVER_RETURN_PACKET ReceiverReturnPacket;
+ XENVIF_VIF_RECEIVER_SET_OFFLOAD_OPTIONS ReceiverSetOffloadOptions;
+ XENVIF_VIF_RECEIVER_SET_BACKFILL_SIZE ReceiverSetBackfillSize;
+ XENVIF_VIF_RECEIVER_QUERY_RING_SIZE ReceiverQueryRingSize;
+ XENVIF_VIF_RECEIVER_SET_HASH_ALGORITHM ReceiverSetHashAlgorithm;
+ XENVIF_VIF_RECEIVER_QUERY_HASH_CAPABILITIES ReceiverQueryHashCapabilities;
+ XENVIF_VIF_RECEIVER_UPDATE_HASH_PARAMETERS ReceiverUpdateHashParameters;
+ XENVIF_VIF_TRANSMITTER_QUEUE_PACKET TransmitterQueuePacket;
+ XENVIF_VIF_TRANSMITTER_QUERY_OFFLOAD_OPTIONS TransmitterQueryOffloadOptions;
+ XENVIF_VIF_TRANSMITTER_QUERY_LARGE_PACKET_SIZE TransmitterQueryLargePacketSize;
+ 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_V10
+ \brief VIF interface version 10
+ \ingroup interfaces
+*/
+struct _XENVIF_VIF_INTERFACE_V10 {
INTERFACE Interface;
XENVIF_VIF_ACQUIRE Acquire;
XENVIF_VIF_RELEASE Release;
XENVIF_VIF_MAC_QUERY_FILTER_LEVEL MacQueryFilterLevel;
};
-typedef struct _XENVIF_VIF_INTERFACE_V9 XENVIF_VIF_INTERFACE, *PXENVIF_VIF_INTERFACE;
+typedef struct _XENVIF_VIF_INTERFACE_V10 XENVIF_VIF_INTERFACE, *PXENVIF_VIF_INTERFACE;
/*! \def XENVIF_VIF
\brief Macro at assist in method invocation
#endif // _WINDLL
#define XENVIF_VIF_INTERFACE_VERSION_MIN 8
-#define XENVIF_VIF_INTERFACE_VERSION_MAX 9
+#define XENVIF_VIF_INTERFACE_VERSION_MAX 10
#endif // _XENVIF_INTERFACE_H
static VOID
__ReceiverPushPackets(
IN PXENNET_RECEIVER Receiver,
- IN ULONG Index
+ IN ULONG Index,
+ OUT PBOOLEAN Pause
)
{
ULONG Flags;
NDIS_RECEIVE_FLAGS_PERFECT_FILTERED;
ASSERT3S(Indicated - Returned, >=, 0);
- if (Indicated - Returned > IN_NDIS_MAX)
+ if (Indicated - Returned > IN_NDIS_MAX) {
Flags |= NDIS_RECEIVE_FLAGS_RESOURCES;
+ *Pause = TRUE;
+ }
__IndicateReceiveNetBufferLists(Receiver,
NetBufferList,
IN PXENVIF_PACKET_INFO Info,
IN PXENVIF_PACKET_HASH Hash,
IN BOOLEAN More,
- IN PVOID Cookie
+ IN PVOID Cookie,
+ OUT PBOOLEAN Pause
)
{
PXENVIF_VIF_INTERFACE VifInterface;
PNET_BUFFER_LIST NetBufferList;
PXENNET_RECEIVER_QUEUE Queue;
+ BOOLEAN Push = !More;
VifInterface = AdapterGetVifInterface(Receiver->Adapter);
}
Queue->Count++;
+ // If we need to indicate low resources, then push the queued packets to NDIS.
+ if (!Push &&
+ Receiver->Indicated + Queue->Count - Receiver->Returned > IN_NDIS_MAX)
+ Push = TRUE;
+
KeReleaseSpinLockFromDpcLevel(&Queue->Lock);
done:
- if (!More)
- __ReceiverPushPackets(Receiver, Index);
+ *Pause = FALSE;
+
+ if (Push)
+ __ReceiverPushPackets(Receiver, Index, Pause);
}
PXENVIF_VIF_OFFLOAD_OPTIONS