[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH 3/6] Refactor for more maintainability.
Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx> --- src/xennet/adapter.c | 3515 ++++++++++++++++++------------------------ src/xennet/adapter.h | 148 +- src/xennet/common.h | 36 - src/xennet/main.c | 348 ----- src/xennet/project.h | 66 - src/xennet/receiver.c | 328 ++-- src/xennet/receiver.h | 58 +- src/xennet/std.h | 45 - src/xennet/transmitter.c | 301 ++-- src/xennet/transmitter.h | 50 +- vs2012/xennet/xennet.vcxproj | 3 +- vs2013/xennet/xennet.vcxproj | 3 +- 12 files changed, 1963 insertions(+), 2938 deletions(-) delete mode 100644 src/xennet/common.h delete mode 100644 src/xennet/main.c delete mode 100644 src/xennet/project.h delete mode 100644 src/xennet/std.h diff --git a/src/xennet/adapter.c b/src/xennet/adapter.c index 7cc49fb..a718a82 100644 --- a/src/xennet/adapter.c +++ b/src/xennet/adapter.c @@ -29,50 +29,31 @@ * SUCH DAMAGE. */ +#include <ndis.h> +#include "adapter.h" +#include "transmitter.h" +#include "receiver.h" +#include <vif_interface.h> #include <version.h> -#include "common.h" +#include "dbg_print.h" +#include "assert.h" -#pragma warning(disable:4711) +struct _XENNET_ADAPTER { + XENVIF_VIF_INTERFACE VifInterface; -// -// List of supported OIDs. -// + ULONG MaximumFrameSize; + ULONG CurrentLookahead; -static NDIS_STATUS -AdapterSetRegistrationAttributes ( - IN PADAPTER Adapter - ); - -static NDIS_STATUS -AdapterSetGeneralAttributes ( - IN PADAPTER Adapter - ); - -static NDIS_STATUS -AdapterSetOffloadAttributes ( - IN PADAPTER Adapter - ); - -static MINIPORT_PROCESS_SG_LIST AdapterProcessSGList; -static VOID -AdapterProcessSGList ( - IN PDEVICE_OBJECT DeviceObject, - IN PVOID Reserved, - IN PSCATTER_GATHER_LIST SGL, - IN PVOID Context - ); - -static NDIS_STATUS -AdapterSetInformation ( - IN PADAPTER Adapter, - IN PNDIS_OID_REQUEST NdisRequest - ); + NDIS_HANDLE NdisAdapterHandle; + NDIS_HANDLE NdisDmaHandle; + NDIS_PNP_CAPABILITIES Capabilities; + NDIS_OFFLOAD Offload; + PROPERTIES Properties; -static NDIS_STATUS -AdapterQueryInformation ( - IN PADAPTER Adapter, - IN PNDIS_OID_REQUEST NdisRequest - ); + PXENNET_RECEIVER Receiver; + PXENNET_TRANSMITTER Transmitter; + BOOLEAN Enabled; +}; static NDIS_OID XennetSupportedOids[] = { @@ -129,28 +110,25 @@ static NDIS_OID XennetSupportedOids[] = OID_PNP_SET_POWER, }; -#define INITIALIZE_NDIS_OBJ_HEADER(obj, type) do { \ - (obj).Header.Type = NDIS_OBJECT_TYPE_ ## type ; \ - (obj).Header.Revision = NDIS_ ## type ## _REVISION_1; \ - (obj).Header.Size = sizeof(obj); \ -} while (0) +#define ADAPTER_POOL_TAG 'AteN' -NTSTATUS AllocAdapter(OUT PADAPTER *Adapter) +__drv_functionClass(MINIPORT_PROCESS_SG_LIST) +static VOID +AdapterProcessSGList( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Reserved, + IN PSCATTER_GATHER_LIST SGL, + IN PVOID Context + ) { - if (Adapter == NULL) - return STATUS_INVALID_PARAMETER; - - *Adapter = (PADAPTER)ExAllocatePoolWithTag(NonPagedPool, sizeof (ADAPTER), ' TEN'); - if (*Adapter == NULL) - return STATUS_INSUFFICIENT_RESOURCES; + UNREFERENCED_PARAMETER(DeviceObject); + UNREFERENCED_PARAMETER(Reserved); + UNREFERENCED_PARAMETER(SGL); + UNREFERENCED_PARAMETER(Context); - return STATUS_SUCCESS; + ASSERT(FALSE); } -// -// Scatter gather allocate handler callback. -// Should never get called. -// __drv_functionClass(MINIPORT_ALLOCATE_SHARED_MEM_COMPLETE) static VOID AdapterAllocateComplete ( @@ -168,140 +146,17 @@ AdapterAllocateComplete ( UNREFERENCED_PARAMETER(Context); ASSERT(FALSE); - - return; -} - -// -// Required NDIS6 handler. -// Should never get called. -// -VOID -AdapterCancelOidRequest ( - IN NDIS_HANDLE NdisHandle, - IN PVOID RequestId - ) -{ - UNREFERENCED_PARAMETER(NdisHandle); - UNREFERENCED_PARAMETER(RequestId); - - return; -} - -// -// Required NDIS6 handler. -// Should never get called. -// - -VOID -AdapterCancelSendNetBufferLists ( - IN NDIS_HANDLE NdisHandle, - IN PVOID CancelId - ) -{ - UNREFERENCED_PARAMETER(NdisHandle); - UNREFERENCED_PARAMETER(CancelId); - - return; -} - -BOOLEAN -AdapterCheckForHang ( - IN NDIS_HANDLE NdisHandle - ) -{ - UNREFERENCED_PARAMETER(NdisHandle); - - return FALSE; -} - -// -// Frees resources obtained by AdapterInitialize. -// -VOID -AdapterCleanup ( - IN PADAPTER Adapter - ) -{ - Trace("====>\n"); - - TransmitterDelete(&Adapter->Transmitter); - ReceiverCleanup(&Adapter->Receiver); - - if (Adapter->NdisDmaHandle != NULL) - NdisMDeregisterScatterGatherDma(Adapter->NdisDmaHandle); - - XENVIF_VIF(Release, &Adapter->VifInterface); - Adapter->AcquiredInterfaces = FALSE; - - Trace("<====\n"); - return; -} - -static VOID -AdapterMediaStateChange( - IN PADAPTER Adapter - ) -{ - NDIS_LINK_STATE LinkState; - NDIS_STATUS_INDICATION StatusIndication; - - NdisZeroMemory(&LinkState, sizeof (NDIS_LINK_STATE)); - - LinkState.Header.Revision = NDIS_LINK_STATE_REVISION_1; - LinkState.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - LinkState.Header.Size = sizeof(NDIS_LINK_STATE); - - XENVIF_VIF(MacQueryState, - &Adapter->VifInterface, - &LinkState.MediaConnectState, - &LinkState.RcvLinkSpeed, - &LinkState.MediaDuplexState); - - if (LinkState.MediaConnectState == MediaConnectStateUnknown) { - Info("LINK: STATE UNKNOWN\n"); - } else if (LinkState.MediaConnectState == MediaConnectStateDisconnected) { - Info("LINK: DOWN\n"); - } else { - ASSERT3U(LinkState.MediaConnectState, ==, MediaConnectStateConnected); - - if (LinkState.MediaDuplexState == MediaDuplexStateHalf) - Info("LINK: UP: SPEED=%u DUPLEX=HALF\n", LinkState.RcvLinkSpeed); - else if (LinkState.MediaDuplexState == MediaDuplexStateFull) - Info("LINK: UP: SPEED=%u DUPLEX=FULL\n", LinkState.RcvLinkSpeed); - else - Info("LINK: UP: SPEED=%u DUPLEX=UNKNOWN\n", LinkState.RcvLinkSpeed); - } - - LinkState.XmitLinkSpeed = LinkState.RcvLinkSpeed; - - NdisZeroMemory(&StatusIndication, sizeof (NDIS_STATUS_INDICATION)); - - StatusIndication.Header.Type = NDIS_OBJECT_TYPE_STATUS_INDICATION; - StatusIndication.Header.Revision = NDIS_STATUS_INDICATION_REVISION_1; - StatusIndication.Header.Size = sizeof (NDIS_STATUS_INDICATION); - StatusIndication.SourceHandle = Adapter->NdisAdapterHandle; - StatusIndication.StatusCode = NDIS_STATUS_LINK_STATE; - StatusIndication.StatusBuffer = &LinkState; - StatusIndication.StatusBufferSize = sizeof (NDIS_LINK_STATE); - - NdisMIndicateStatusEx(Adapter->NdisAdapterHandle, &StatusIndication); } - -// -// Initializes adapter by allocating required resources and connects to -// netback. -// - static VOID AdapterVifCallback( IN PVOID Context, IN XENVIF_VIF_CALLBACK_TYPE Type, - ...) + ... + ) { - PADAPTER Adapter = Context; - va_list Arguments; + PXENNET_ADAPTER Adapter = Context; + va_list Arguments; va_start(Arguments, Type); @@ -319,7 +174,7 @@ AdapterVifCallback( List = va_arg(Arguments, PLIST_ENTRY); - ReceiverReceivePackets(&Adapter->Receiver, List); + ReceiverReceivePackets(Adapter->Receiver, List); break; } case XENVIF_MAC_STATE_CHANGE: { @@ -331,2247 +186,1925 @@ AdapterVifCallback( va_end(Arguments); } -NDIS_STATUS -AdapterGetAdvancedSettings( - IN PADAPTER pAdapter +static VOID +AdapterIndicateOffloadChanged( + IN PXENNET_ADAPTER Adapter ) { - NDIS_CONFIGURATION_OBJECT configObject; - NDIS_HANDLE hConfigurationHandle; - NDIS_STRING ndisValue; - PNDIS_CONFIGURATION_PARAMETER pNdisData; - NDIS_STATUS ndisStatus; - NTSTATUS status; - - configObject.Header.Type = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT; - configObject.Header.Revision = NDIS_CONFIGURATION_OBJECT_REVISION_1; - configObject.Header.Size = NDIS_SIZEOF_CONFIGURATION_OBJECT_REVISION_1; - configObject.NdisHandle = pAdapter->NdisAdapterHandle; - configObject.Flags = 0; + NDIS_STATUS_INDICATION Status; + NDIS_OFFLOAD Offload; + PXENVIF_VIF_OFFLOAD_OPTIONS RxOptions; + PXENVIF_VIF_OFFLOAD_OPTIONS TxOptions; - ndisStatus = NdisOpenConfigurationEx(&configObject, &hConfigurationHandle); + RxOptions = ReceiverOffloadOptions(Adapter->Receiver); + TxOptions = TransmitterOffloadOptions(Adapter->Transmitter); - status = STATUS_UNSUCCESSFUL; - if (ndisStatus != NDIS_STATUS_SUCCESS) - goto fail1; - -#define read_property(field, name, default_val) \ - do { \ - RtlInitUnicodeString(&ndisValue, name); \ - NdisReadConfiguration(&ndisStatus, &pNdisData, hConfigurationHandle, &ndisValue, NdisParameterInteger); \ - if (ndisStatus == NDIS_STATUS_SUCCESS) { \ - pAdapter->Properties.field = pNdisData->ParameterData.IntegerData; \ - } else { \ - pAdapter->Properties.field = default_val; \ - } \ - } while (FALSE); - - read_property(ipv4_csum, L"*IPChecksumOffloadIPv4", 3); - read_property(tcpv4_csum, L"*TCPChecksumOffloadIPv4", 3); - read_property(udpv4_csum, L"*UDPChecksumOffloadIPv4", 3); - read_property(tcpv6_csum, L"*TCPChecksumOffloadIPv6", 3); - read_property(udpv6_csum, L"*UDPChecksumOffloadIPv6", 3); - read_property(lsov4, L"*LSOv2IPv4", 1); - read_property(lsov6, L"*LSOv2IPv6", 1); - read_property(lrov4, L"LROIPv4", 1); - read_property(lrov6, L"LROIPv6", 1); - read_property(need_csum_value, L"NeedChecksumValue", 1); - - NdisCloseConfiguration(hConfigurationHandle); - - return NDIS_STATUS_SUCCESS; - -fail1: - Error("fail1\n"); - return NDIS_STATUS_FAILURE; -} + RtlZeroMemory(&Offload, sizeof(NDIS_OFFLOAD)); + Offload.Header.Type = NDIS_OBJECT_TYPE_OFFLOAD; + Offload.Header.Revision = NDIS_OFFLOAD_REVISION_1; + Offload.Header.Size = sizeof(NDIS_OFFLOAD); -NDIS_STATUS -AdapterInitialize ( - IN PADAPTER Adapter, - IN NDIS_HANDLE AdapterHandle - ) -{ - NDIS_STATUS ndisStatus; - NDIS_SG_DMA_DESCRIPTION DmaDescription; - NTSTATUS status; + Offload.Checksum.IPv4Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; - status = XENVIF_VIF(Acquire, &Adapter->VifInterface); - if (!NT_SUCCESS(status)) - return NDIS_STATUS_FAILURE; + if (RxOptions->OffloadIpVersion4HeaderChecksum) { + Offload.Checksum.IPv4Receive.IpChecksum = 1; + Offload.Checksum.IPv4Receive.IpOptionsSupported = 1; + } + if (RxOptions->OffloadIpVersion4TcpChecksum) { + Offload.Checksum.IPv4Receive.TcpChecksum = 1; + Offload.Checksum.IPv4Receive.TcpOptionsSupported = 1; + } + if (RxOptions->OffloadIpVersion4UdpChecksum) { + Offload.Checksum.IPv4Receive.UdpChecksum = 1; + } - Adapter->AcquiredInterfaces = TRUE; + Offload.Checksum.IPv6Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; + Offload.Checksum.IPv6Receive.IpExtensionHeadersSupported = 1; - Trace("====>\n"); + if (RxOptions->OffloadIpVersion6TcpChecksum) { + Offload.Checksum.IPv6Receive.TcpChecksum = 1; + Offload.Checksum.IPv6Receive.TcpOptionsSupported = 1; + } + if (RxOptions->OffloadIpVersion6UdpChecksum) { + Offload.Checksum.IPv6Receive.UdpChecksum = 1; + } - Adapter->NdisAdapterHandle = AdapterHandle; + XENVIF_VIF(ReceiverSetOffloadOptions, + &Adapter->VifInterface, + *RxOptions); - RtlZeroMemory(&Adapter->Capabilities, sizeof (Adapter->Capabilities)); + Offload.Checksum.IPv4Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; - Adapter->Transmitter = (PTRANSMITTER)ExAllocatePoolWithTag(NonPagedPool, sizeof(TRANSMITTER), ' TEN'); - if (!Adapter->Transmitter) { - ndisStatus = NDIS_STATUS_RESOURCES; - goto exit; + if (TxOptions->OffloadIpVersion4HeaderChecksum) { + Offload.Checksum.IPv4Transmit.IpChecksum = 1; + Offload.Checksum.IPv4Transmit.IpOptionsSupported = 1; } - - RtlZeroMemory(Adapter->Transmitter, sizeof (TRANSMITTER)); - - ndisStatus = ReceiverInitialize(&Adapter->Receiver); - if (ndisStatus != NDIS_STATUS_SUCCESS) { - goto exit; + if (TxOptions->OffloadIpVersion4TcpChecksum) { + Offload.Checksum.IPv4Transmit.TcpChecksum = 1; + Offload.Checksum.IPv4Transmit.TcpOptionsSupported = 1; } - - ndisStatus = TransmitterInitialize(Adapter->Transmitter, Adapter); - if (ndisStatus != NDIS_STATUS_SUCCESS) { - goto exit; + if (TxOptions->OffloadIpVersion4UdpChecksum) { + Offload.Checksum.IPv4Transmit.UdpChecksum = 1; } - ndisStatus = AdapterGetAdvancedSettings(Adapter); - if (ndisStatus != NDIS_STATUS_SUCCESS) { - goto exit; - } + Offload.Checksum.IPv6Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; + Offload.Checksum.IPv6Transmit.IpExtensionHeadersSupported = 1; - ndisStatus = AdapterSetRegistrationAttributes(Adapter); - if (ndisStatus != NDIS_STATUS_SUCCESS) { - goto exit; + if (TxOptions->OffloadIpVersion6TcpChecksum) { + Offload.Checksum.IPv6Transmit.TcpChecksum = 1; + Offload.Checksum.IPv6Transmit.TcpOptionsSupported = 1; } - - ndisStatus = AdapterSetGeneralAttributes(Adapter); - if (ndisStatus != NDIS_STATUS_SUCCESS) { - goto exit; + if (TxOptions->OffloadIpVersion6UdpChecksum) { + Offload.Checksum.IPv6Transmit.UdpChecksum = 1; } - ndisStatus = AdapterSetOffloadAttributes(Adapter); - if (ndisStatus != NDIS_STATUS_SUCCESS) { - goto exit; + if (TxOptions->OffloadIpVersion4LargePacket) { + XENVIF_VIF(TransmitterQueryLargePacketSize, + &Adapter->VifInterface, + 4, + &Offload.LsoV2.IPv4.MaxOffLoadSize); + Offload.LsoV2.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; + Offload.LsoV2.IPv4.MinSegmentCount = 2; } - NdisZeroMemory(&DmaDescription, sizeof(DmaDescription)); - - DmaDescription.Header.Type = NDIS_OBJECT_TYPE_SG_DMA_DESCRIPTION; - DmaDescription.Header.Revision = NDIS_SG_DMA_DESCRIPTION_REVISION_1; - DmaDescription.Header.Size = sizeof(NDIS_SG_DMA_DESCRIPTION); - DmaDescription.Flags = NDIS_SG_DMA_64_BIT_ADDRESS; - DmaDescription.MaximumPhysicalMapping = 65536; - DmaDescription.ProcessSGListHandler = AdapterProcessSGList; - DmaDescription.SharedMemAllocateCompleteHandler = AdapterAllocateComplete; - - ndisStatus = NdisMRegisterScatterGatherDma(Adapter->NdisAdapterHandle, - &DmaDescription, - &Adapter->NdisDmaHandle); - if (ndisStatus != NDIS_STATUS_SUCCESS) - Adapter->NdisDmaHandle = NULL; + if (TxOptions->OffloadIpVersion6LargePacket) { + XENVIF_VIF(TransmitterQueryLargePacketSize, + &Adapter->VifInterface, + 6, + &Offload.LsoV2.IPv6.MaxOffLoadSize); + Offload.LsoV2.IPv6.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; + Offload.LsoV2.IPv6.MinSegmentCount = 2; + Offload.LsoV2.IPv6.IpExtensionHeadersSupported = 1; + Offload.LsoV2.IPv6.TcpOptionsSupported = 1; + } - ASSERT(!Adapter->Enabled); - status = XENVIF_VIF(Enable, - &Adapter->VifInterface, - AdapterVifCallback, - Adapter); - if (NT_SUCCESS(status)) { - TransmitterEnable(Adapter->Transmitter); - Adapter->Enabled = TRUE; - ndisStatus = NDIS_STATUS_SUCCESS; - } else { - ndisStatus = NDIS_STATUS_FAILURE; + if (!RtlEqualMemory(&Adapter->Offload, &Offload, sizeof(NDIS_OFFLOAD))) { + Adapter->Offload = Offload; + // DISPPLAY_OFFLOAD(Offload); } -exit: - if (ndisStatus != NDIS_STATUS_SUCCESS) - XENVIF_VIF(Release, &Adapter->VifInterface); + RtlZeroMemory(&Status, sizeof(NDIS_STATUS_INDICATION)); + Status.Header.Type = NDIS_OBJECT_TYPE_STATUS_INDICATION; + Status.Header.Revision = NDIS_STATUS_INDICATION_REVISION_1; + Status.Header.Size = sizeof(NDIS_STATUS_INDICATION); + Status.StatusCode = NDIS_STATUS_TASK_OFFLOAD_CURRENT_CONFIG; + Status.StatusBuffer = &Offload; + Status.StatusBufferSize = sizeof(Offload); - Trace("<==== (%08x)\n", ndisStatus); - return ndisStatus; + NdisMIndicateStatusEx(Adapter->NdisAdapterHandle, &Status); } -// -// Scatter gather process handler callback. -// Should never get called. -// static VOID -AdapterProcessSGList ( - IN PDEVICE_OBJECT DeviceObject, - IN PVOID Reserved, - IN PSCATTER_GATHER_LIST SGL, - IN PVOID Context +AdapterGetPacketFilter( + IN PXENNET_ADAPTER Adapter, + OUT PULONG PacketFilter ) { - UNREFERENCED_PARAMETER(DeviceObject); - UNREFERENCED_PARAMETER(Reserved); - UNREFERENCED_PARAMETER(SGL); - UNREFERENCED_PARAMETER(Context); + XENVIF_MAC_FILTER_LEVEL UnicastFilterLevel; + XENVIF_MAC_FILTER_LEVEL MulticastFilterLevel; + XENVIF_MAC_FILTER_LEVEL BroadcastFilterLevel; - ASSERT(FALSE); + XENVIF_VIF(MacQueryFilterLevel, + &Adapter->VifInterface, + ETHERNET_ADDRESS_UNICAST, + &UnicastFilterLevel); - return; -} + XENVIF_VIF(MacQueryFilterLevel, + &Adapter->VifInterface, + ETHERNET_ADDRESS_MULTICAST, + &MulticastFilterLevel); -// -// Get\Set OID handler. -// -NDIS_STATUS -AdapterOidRequest ( - IN NDIS_HANDLE NdisHandle, - IN PNDIS_OID_REQUEST NdisRequest - ) -{ - NDIS_STATUS ndisStatus; - PADAPTER Adapter = (PADAPTER)NdisHandle; + XENVIF_VIF(MacQueryFilterLevel, + &Adapter->VifInterface, + ETHERNET_ADDRESS_BROADCAST, + &BroadcastFilterLevel); - switch (NdisRequest->RequestType) { - case NdisRequestSetInformation: - ndisStatus = AdapterSetInformation(Adapter, NdisRequest); - break; - - case NdisRequestQueryInformation: - case NdisRequestQueryStatistics: - ndisStatus = AdapterQueryInformation(Adapter, NdisRequest); - break; + *PacketFilter = 0; - default: - ndisStatus = NDIS_STATUS_NOT_SUPPORTED; - break; - }; + if (UnicastFilterLevel == XENVIF_MAC_FILTER_ALL) { + ASSERT3U(MulticastFilterLevel, ==, XENVIF_MAC_FILTER_ALL); + ASSERT3U(BroadcastFilterLevel, ==, XENVIF_MAC_FILTER_ALL); - return ndisStatus; + *PacketFilter |= NDIS_PACKET_TYPE_PROMISCUOUS; + return; + } else if (UnicastFilterLevel == XENVIF_MAC_FILTER_MATCHING) { + *PacketFilter |= NDIS_PACKET_TYPE_DIRECTED; + } + + if (MulticastFilterLevel == XENVIF_MAC_FILTER_ALL) + *PacketFilter |= NDIS_PACKET_TYPE_ALL_MULTICAST; + else if (MulticastFilterLevel == XENVIF_MAC_FILTER_MATCHING) + *PacketFilter |= NDIS_PACKET_TYPE_MULTICAST; + + if (BroadcastFilterLevel == XENVIF_MAC_FILTER_ALL) + *PacketFilter |= NDIS_PACKET_TYPE_BROADCAST; } -// -// Temporarily pauses adapter. -// -NDIS_STATUS -AdapterPause ( - IN NDIS_HANDLE NdisHandle, - IN PNDIS_MINIPORT_PAUSE_PARAMETERS MiniportPauseParameters +static NDIS_STATUS +AdapterSetPacketFilter( + IN PXENNET_ADAPTER Adapter, + IN PULONG PacketFilter ) { - PADAPTER Adapter = (PADAPTER)NdisHandle; - UNREFERENCED_PARAMETER(MiniportPauseParameters); + XENVIF_MAC_FILTER_LEVEL UnicastFilterLevel; + XENVIF_MAC_FILTER_LEVEL MulticastFilterLevel; + XENVIF_MAC_FILTER_LEVEL BroadcastFilterLevel; - Trace("====>\n"); + if (*PacketFilter & ~XENNET_SUPPORTED_PACKET_FILTERS) + return NDIS_STATUS_INVALID_PARAMETER; - if (!Adapter->Enabled) + if (*PacketFilter & NDIS_PACKET_TYPE_PROMISCUOUS) { + UnicastFilterLevel = XENVIF_MAC_FILTER_ALL; + MulticastFilterLevel = XENVIF_MAC_FILTER_ALL; + BroadcastFilterLevel = XENVIF_MAC_FILTER_ALL; goto done; + } - XENVIF_VIF(Disable, - &Adapter->VifInterface); + if (*PacketFilter & NDIS_PACKET_TYPE_DIRECTED) + UnicastFilterLevel = XENVIF_MAC_FILTER_MATCHING; + else + UnicastFilterLevel = XENVIF_MAC_FILTER_NONE; - AdapterMediaStateChange(Adapter); + if (*PacketFilter & NDIS_PACKET_TYPE_ALL_MULTICAST) + MulticastFilterLevel = XENVIF_MAC_FILTER_ALL; + else if (*PacketFilter & NDIS_PACKET_TYPE_MULTICAST) + MulticastFilterLevel = XENVIF_MAC_FILTER_MATCHING; + else + MulticastFilterLevel = XENVIF_MAC_FILTER_NONE; - Adapter->Enabled = FALSE; + if (*PacketFilter & NDIS_PACKET_TYPE_BROADCAST) + BroadcastFilterLevel = XENVIF_MAC_FILTER_ALL; + else + BroadcastFilterLevel = XENVIF_MAC_FILTER_NONE; done: - Trace("<====\n"); + XENVIF_VIF(MacSetFilterLevel, + &Adapter->VifInterface, + ETHERNET_ADDRESS_UNICAST, + UnicastFilterLevel); + + XENVIF_VIF(MacSetFilterLevel, + &Adapter->VifInterface, + ETHERNET_ADDRESS_MULTICAST, + MulticastFilterLevel); + + XENVIF_VIF(MacSetFilterLevel, + &Adapter->VifInterface, + ETHERNET_ADDRESS_BROADCAST, + BroadcastFilterLevel); + return NDIS_STATUS_SUCCESS; } -// -// Handles PNP and Power events. NOP. -// -VOID -AdapterPnPEventHandler ( - IN NDIS_HANDLE NdisHandle, - IN PNET_DEVICE_PNP_EVENT NetDevicePnPEvent +static NDIS_STATUS +AdapterGetOffloadEncapsulation( + IN PXENNET_ADAPTER Adapter, + IN PNDIS_OFFLOAD_ENCAPSULATION Offload ) { - UNREFERENCED_PARAMETER(NdisHandle); + XENVIF_VIF_OFFLOAD_OPTIONS Options; + PXENVIF_VIF_OFFLOAD_OPTIONS TxOptions; + PXENVIF_VIF_OFFLOAD_OPTIONS RxOptions; + if (Offload->IPv4.Enabled == NDIS_OFFLOAD_SET_ON && + Offload->IPv4.EncapsulationType != NDIS_ENCAPSULATION_IEEE_802_3) + goto invalid_parameter; - switch (NetDevicePnPEvent->DevicePnPEvent) { - case NdisDevicePnPEventQueryRemoved: - break; + if (Offload->IPv6.Enabled == NDIS_OFFLOAD_SET_ON && + Offload->IPv6.EncapsulationType != NDIS_ENCAPSULATION_IEEE_802_3) + goto invalid_parameter; - case NdisDevicePnPEventRemoved: - break; - - case NdisDevicePnPEventSurpriseRemoved: - break; + XENVIF_VIF(TransmitterQueryOffloadOptions, + &Adapter->VifInterface, + &Options); - case NdisDevicePnPEventQueryStopped: - break; + TxOptions = TransmitterOffloadOptions(Adapter->Transmitter); + TxOptions->Value = 0; + TxOptions->OffloadTagManipulation = 1; + + if (Adapter->Properties.lsov4 && Options.OffloadIpVersion4LargePacket) + TxOptions->OffloadIpVersion4LargePacket = 1; + if (Adapter->Properties.lsov6 && Options.OffloadIpVersion6LargePacket) + TxOptions->OffloadIpVersion6LargePacket = 1; + if ((Adapter->Properties.ipv4_csum & 1) && Options.OffloadIpVersion4HeaderChecksum) + TxOptions->OffloadIpVersion4HeaderChecksum = 1; + if ((Adapter->Properties.tcpv4_csum & 1) && Options.OffloadIpVersion4TcpChecksum) + TxOptions->OffloadIpVersion4TcpChecksum = 1; + if ((Adapter->Properties.udpv4_csum & 1) && Options.OffloadIpVersion4UdpChecksum) + TxOptions->OffloadIpVersion4UdpChecksum = 1; + if ((Adapter->Properties.tcpv6_csum & 1) && Options.OffloadIpVersion6TcpChecksum) + TxOptions->OffloadIpVersion6TcpChecksum = 1; + if ((Adapter->Properties.udpv6_csum & 1) && Options.OffloadIpVersion6UdpChecksum) + TxOptions->OffloadIpVersion6UdpChecksum = 1; + + RxOptions = ReceiverOffloadOptions(Adapter->Receiver); + + RxOptions->Value = 0; + RxOptions->OffloadTagManipulation = 1; - case NdisDevicePnPEventStopped: - break; - - case NdisDevicePnPEventPowerProfileChanged: - break; - - default: - break; - }; + if (Adapter->Properties.need_csum_value) + RxOptions->NeedChecksumValue = 1; + if (Adapter->Properties.lrov4) + RxOptions->OffloadIpVersion4LargePacket = 1; + if (Adapter->Properties.lrov4) + RxOptions->NeedLargePacketSplit = 1; + if (Adapter->Properties.lrov6) + RxOptions->OffloadIpVersion6LargePacket = 1; + if (Adapter->Properties.lrov6) + RxOptions->NeedLargePacketSplit = 1; + if (Adapter->Properties.ipv4_csum & 2) + RxOptions->OffloadIpVersion4HeaderChecksum = 1; + if (Adapter->Properties.tcpv4_csum & 2) + RxOptions->OffloadIpVersion4TcpChecksum = 1; + if (Adapter->Properties.udpv4_csum & 2) + RxOptions->OffloadIpVersion4UdpChecksum = 1; + if (Adapter->Properties.tcpv6_csum & 2) + RxOptions->OffloadIpVersion6TcpChecksum = 1; + if (Adapter->Properties.udpv6_csum & 2) + RxOptions->OffloadIpVersion6UdpChecksum = 1; + + AdapterIndicateOffloadChanged(Adapter); + return NDIS_STATUS_SUCCESS; - return; +invalid_parameter: + return NDIS_STATUS_INVALID_PARAMETER; } -// -// Reports general statistics to NDIS. -// -static NDIS_STATUS -AdapterQueryGeneralStatistics ( - IN PADAPTER Adapter, - IN PNDIS_STATISTICS_INFO NdisStatisticsInfo +#define NO_CHANGE(x) ((x) == NDIS_OFFLOAD_PARAMETERS_NO_CHANGE) +#define RX_ENABLED(x) ((x) == NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED || \ + (x) == NDIS_OFFLOAD_PARAMETERS_RX_ENABLED_TX_DISABLED) +#define TX_ENABLED(x) ((x) == NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED || \ + (x) == NDIS_OFFLOAD_PARAMETERS_TX_ENABLED_RX_DISABLED) +#define CHANGE(x, y) (((x) == (y)) ? 0 : (((x) = (y)) != (y))) + +static NDIS_STATUS +AdapterGetTcpOffloadParameters( + IN PXENNET_ADAPTER Adapter, + IN PNDIS_OFFLOAD_PARAMETERS Offload ) { - NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS; - ULONGLONG Value; + XENVIF_VIF_OFFLOAD_OPTIONS Options; + PXENVIF_VIF_OFFLOAD_OPTIONS TxOptions; + PXENVIF_VIF_OFFLOAD_OPTIONS RxOptions; + BOOLEAN Changed; + + XENVIF_VIF(TransmitterQueryOffloadOptions, + &Adapter->VifInterface, + &Options); + + if (!NO_CHANGE(Offload->IPsecV1)) + goto invalid_parameter; + if (!NO_CHANGE(Offload->LsoV1)) + goto invalid_parameter; + if (!NO_CHANGE(Offload->TcpConnectionIPv4)) + goto invalid_parameter; + if (!NO_CHANGE(Offload->TcpConnectionIPv6)) + goto invalid_parameter; + if (!NO_CHANGE(Offload->LsoV2IPv4) && + !(Options.OffloadIpVersion4LargePacket)) + goto invalid_parameter; + if (!NO_CHANGE(Offload->LsoV2IPv6) && + !(Options.OffloadIpVersion6LargePacket)) + goto invalid_parameter; + + Changed = FALSE; + TxOptions = TransmitterOffloadOptions(Adapter->Transmitter); + RxOptions = ReceiverOffloadOptions(Adapter->Receiver); + + if (Offload->LsoV2IPv4 == NDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED) { + Changed |= CHANGE(TxOptions->OffloadIpVersion4LargePacket, 1); + } else if (Offload->LsoV2IPv4 == NDIS_OFFLOAD_PARAMETERS_LSOV2_DISABLED) { + Changed |= CHANGE(TxOptions->OffloadIpVersion4LargePacket, 0); + } + + if (Offload->LsoV2IPv6 == NDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED) { + Changed |= CHANGE(TxOptions->OffloadIpVersion6LargePacket, 1); + } else if (Offload->LsoV2IPv6 == NDIS_OFFLOAD_PARAMETERS_LSOV2_DISABLED) { + Changed |= CHANGE(TxOptions->OffloadIpVersion6LargePacket, 0); + } - NdisZeroMemory(NdisStatisticsInfo, sizeof(NDIS_STATISTICS_INFO)); - NdisStatisticsInfo->Header.Revision = NDIS_OBJECT_REVISION_1; - NdisStatisticsInfo->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisStatisticsInfo->Header.Size = sizeof(NDIS_STATISTICS_INFO); + Changed |= CHANGE(TxOptions->OffloadIpVersion4HeaderChecksum, TX_ENABLED(Offload->IPv4Checksum)); + Changed |= CHANGE(TxOptions->OffloadIpVersion4TcpChecksum, TX_ENABLED(Offload->TCPIPv4Checksum)); + Changed |= CHANGE(TxOptions->OffloadIpVersion4UdpChecksum, TX_ENABLED(Offload->UDPIPv4Checksum)); + Changed |= CHANGE(TxOptions->OffloadIpVersion6TcpChecksum, TX_ENABLED(Offload->TCPIPv6Checksum)); + Changed |= CHANGE(TxOptions->OffloadIpVersion6UdpChecksum, TX_ENABLED(Offload->UDPIPv6Checksum)); + + Changed |= CHANGE(RxOptions->OffloadIpVersion4HeaderChecksum, RX_ENABLED(Offload->IPv4Checksum)); + Changed |= CHANGE(RxOptions->OffloadIpVersion4TcpChecksum, RX_ENABLED(Offload->TCPIPv4Checksum)); + Changed |= CHANGE(RxOptions->OffloadIpVersion4UdpChecksum, RX_ENABLED(Offload->UDPIPv4Checksum)); + Changed |= CHANGE(RxOptions->OffloadIpVersion6TcpChecksum, RX_ENABLED(Offload->TCPIPv6Checksum)); + Changed |= CHANGE(RxOptions->OffloadIpVersion6UdpChecksum, RX_ENABLED(Offload->UDPIPv6Checksum)); + + if (Changed) + AdapterIndicateOffloadChanged(Adapter); + + return NDIS_STATUS_SUCCESS; + +invalid_parameter: + return NDIS_STATUS_INVALID_PARAMETER; +} + +#undef NO_CHANGE +#undef RX_ENABLED +#undef TX_ENABLED +#undef CHANGE + +static NDIS_STATUS +AdapterQueryGeneralStatistics( + IN PXENNET_ADAPTER Adapter, + IN PNDIS_STATISTICS_INFO Info + ) +{ + ULONGLONG Value; - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_RCV_ERROR; + RtlZeroMemory(Info, sizeof(NDIS_STATISTICS_INFO)); + Info->Header.Revision = NDIS_OBJECT_REVISION_1; + Info->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + Info->Header.Size = sizeof(NDIS_STATISTICS_INFO); + Info->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_RCV_ERROR; (VOID) XENVIF_VIF(QueryStatistic, &Adapter->VifInterface, XENVIF_RECEIVER_BACKEND_ERRORS, &Value); - - NdisStatisticsInfo->ifInErrors = Value; - + Info->ifInErrors = Value; (VOID) XENVIF_VIF(QueryStatistic, &Adapter->VifInterface, XENVIF_RECEIVER_FRONTEND_ERRORS, &Value); + Info->ifInErrors += Value; - NdisStatisticsInfo->ifInErrors += Value; - - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_RCV_DISCARDS; - + Info->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_RCV_DISCARDS; (VOID) XENVIF_VIF(QueryStatistic, &Adapter->VifInterface, XENVIF_RECEIVER_PACKETS_DROPPED, &Value); + Info->ifInDiscards = Value; - NdisStatisticsInfo->ifInDiscards = Value; - - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BYTES_RCV; - + Info->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BYTES_RCV; (VOID) XENVIF_VIF(QueryStatistic, &Adapter->VifInterface, XENVIF_RECEIVER_UNICAST_OCTETS, &Value); - - NdisStatisticsInfo->ifHCInOctets = Value; - + Info->ifHCInOctets = Value; (VOID) XENVIF_VIF(QueryStatistic, &Adapter->VifInterface, XENVIF_RECEIVER_MULTICAST_OCTETS, &Value); - - NdisStatisticsInfo->ifHCInOctets += Value; - + Info->ifHCInOctets += Value; (VOID) XENVIF_VIF(QueryStatistic, &Adapter->VifInterface, XENVIF_RECEIVER_BROADCAST_OCTETS, &Value); + Info->ifHCInOctets += Value; - NdisStatisticsInfo->ifHCInOctets += Value; - - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_RCV; - + Info->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_RCV; (VOID) XENVIF_VIF(QueryStatistic, &Adapter->VifInterface, XENVIF_RECEIVER_UNICAST_OCTETS, &Value); + Info->ifHCInUcastOctets = Value; - NdisStatisticsInfo->ifHCInUcastOctets = Value; - - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_RCV; - + Info->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_RCV; (VOID) XENVIF_VIF(QueryStatistic, &Adapter->VifInterface, XENVIF_RECEIVER_UNICAST_PACKETS, &Value); - - NdisStatisticsInfo->ifHCInUcastPkts = Value; - - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_RCV; - + Info->ifHCInUcastPkts = Value; + + Info->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_RCV; (VOID) XENVIF_VIF(QueryStatistic, &Adapter->VifInterface, XENVIF_RECEIVER_MULTICAST_OCTETS, &Value); + Info->ifHCInMulticastOctets = Value; - NdisStatisticsInfo->ifHCInMulticastOctets = Value; - - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_MULTICAST_FRAMES_RCV; - + Info->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_MULTICAST_FRAMES_RCV; (VOID) XENVIF_VIF(QueryStatistic, &Adapter->VifInterface, XENVIF_RECEIVER_MULTICAST_PACKETS, &Value); + Info->ifHCInMulticastPkts = Value; - NdisStatisticsInfo->ifHCInMulticastPkts = Value; - - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_RCV; - + Info->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_RCV; (VOID) XENVIF_VIF(QueryStatistic, &Adapter->VifInterface, XENVIF_RECEIVER_BROADCAST_OCTETS, &Value); + Info->ifHCInBroadcastOctets = Value; - NdisStatisticsInfo->ifHCInBroadcastOctets = Value; - - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BROADCAST_FRAMES_RCV; - + Info->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BROADCAST_FRAMES_RCV; (VOID) XENVIF_VIF(QueryStatistic, &Adapter->VifInterface, XENVIF_RECEIVER_BROADCAST_PACKETS, &Value); + Info->ifHCInBroadcastPkts = Value; - NdisStatisticsInfo->ifHCInBroadcastPkts = Value; - - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_XMIT_ERROR; - + Info->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_XMIT_ERROR; (VOID) XENVIF_VIF(QueryStatistic, &Adapter->VifInterface, XENVIF_TRANSMITTER_BACKEND_ERRORS, &Value); - - NdisStatisticsInfo->ifOutErrors = Value; - + Info->ifOutErrors = Value; (VOID) XENVIF_VIF(QueryStatistic, &Adapter->VifInterface, XENVIF_TRANSMITTER_FRONTEND_ERRORS, &Value); + Info->ifOutErrors += Value; - NdisStatisticsInfo->ifOutErrors += Value; - - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BYTES_XMIT; - + Info->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BYTES_XMIT; (VOID) XENVIF_VIF(QueryStatistic, &Adapter->VifInterface, XENVIF_TRANSMITTER_UNICAST_OCTETS, &Value); - - NdisStatisticsInfo->ifHCOutOctets = Value; - + Info->ifHCOutOctets = Value; (VOID) XENVIF_VIF(QueryStatistic, &Adapter->VifInterface, XENVIF_TRANSMITTER_MULTICAST_OCTETS, &Value); - - NdisStatisticsInfo->ifHCOutOctets += Value; - + Info->ifHCOutOctets += Value; (VOID) XENVIF_VIF(QueryStatistic, &Adapter->VifInterface, XENVIF_TRANSMITTER_BROADCAST_OCTETS, &Value); + Info->ifHCOutOctets += Value; - NdisStatisticsInfo->ifHCOutOctets += Value; - - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_XMIT; - + Info->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_XMIT; (VOID) XENVIF_VIF(QueryStatistic, &Adapter->VifInterface, XENVIF_TRANSMITTER_UNICAST_OCTETS, &Value); + Info->ifHCOutUcastOctets = Value; - NdisStatisticsInfo->ifHCOutUcastOctets = Value; - - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_XMIT; - + Info->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_XMIT; (VOID) XENVIF_VIF(QueryStatistic, &Adapter->VifInterface, XENVIF_TRANSMITTER_UNICAST_PACKETS, &Value); + Info->ifHCOutUcastPkts = Value; - NdisStatisticsInfo->ifHCOutUcastPkts = Value; - - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_XMIT; - + Info->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_XMIT; (VOID) XENVIF_VIF(QueryStatistic, &Adapter->VifInterface, XENVIF_TRANSMITTER_MULTICAST_OCTETS, &Value); + Info->ifHCOutMulticastOctets = Value; - NdisStatisticsInfo->ifHCOutMulticastOctets = Value; - - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_MULTICAST_FRAMES_XMIT; - + Info->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_MULTICAST_FRAMES_XMIT; (VOID) XENVIF_VIF(QueryStatistic, &Adapter->VifInterface, XENVIF_TRANSMITTER_MULTICAST_PACKETS, &Value); + Info->ifHCOutMulticastPkts = Value; - NdisStatisticsInfo->ifHCOutMulticastPkts = Value; - - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_XMIT; - + Info->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_XMIT; (VOID) XENVIF_VIF(QueryStatistic, &Adapter->VifInterface, XENVIF_TRANSMITTER_BROADCAST_OCTETS, &Value); + Info->ifHCOutBroadcastOctets = Value; - NdisStatisticsInfo->ifHCOutBroadcastOctets = Value; - - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BROADCAST_FRAMES_XMIT; - + Info->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BROADCAST_FRAMES_XMIT; (VOID) XENVIF_VIF(QueryStatistic, &Adapter->VifInterface, XENVIF_TRANSMITTER_BROADCAST_PACKETS, &Value); + Info->ifHCOutBroadcastPkts = Value; - NdisStatisticsInfo->ifHCOutBroadcastPkts = Value; + Info->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_XMIT_DISCARDS; + Info->ifOutDiscards = 0; - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_XMIT_DISCARDS; - NdisStatisticsInfo->ifOutDiscards = 0; + return NDIS_STATUS_SUCCESS; +} +static NDIS_STATUS +AdapterQueryMulticastList( + IN PXENNET_ADAPTER Adapter, + IN PVOID Buffer, + IN ULONG BufferLength, + IN OUT PULONG BytesNeeded + ) +{ + ULONG Count; + NDIS_STATUS ndisStatus; + NTSTATUS status; + + XENVIF_VIF(MacQueryMulticastAddresses, + &Adapter->VifInterface, + NULL, + &Count); + *BytesNeeded = Count * ETHERNET_ADDRESS_LENGTH; + + ndisStatus = NDIS_STATUS_INVALID_LENGTH; + if (BufferLength < *BytesNeeded) + goto fail1; + + status = XENVIF_VIF(MacQueryMulticastAddresses, + &Adapter->VifInterface, + Buffer, + &Count); + ndisStatus = NDIS_STATUS_FAILURE; + if (!NT_SUCCESS(status)) + goto fail2; + + return NDIS_STATUS_SUCCESS; + +fail2: +fail1: return ndisStatus; } -static VOID -GetPacketFilter(PADAPTER Adapter, PULONG PacketFilter) +static FORCEINLINE NDIS_STATUS +AdapterSetMulticastAddresses( + IN PXENNET_ADAPTER Adapter, + IN PETHERNET_ADDRESS Address, + IN ULONG Count + ) { - XENVIF_MAC_FILTER_LEVEL UnicastFilterLevel; - XENVIF_MAC_FILTER_LEVEL MulticastFilterLevel; - XENVIF_MAC_FILTER_LEVEL BroadcastFilterLevel; + NTSTATUS status; - XENVIF_VIF(MacQueryFilterLevel, - &Adapter->VifInterface, - ETHERNET_ADDRESS_UNICAST, - &UnicastFilterLevel); + status = XENVIF_VIF(MacSetMulticastAddresses, + &Adapter->VifInterface, + Address, + Count); + if (!NT_SUCCESS(status)) + return NDIS_STATUS_INVALID_DATA; - XENVIF_VIF(MacQueryFilterLevel, - &Adapter->VifInterface, - ETHERNET_ADDRESS_MULTICAST, - &MulticastFilterLevel); + return NDIS_STATUS_SUCCESS; +} - XENVIF_VIF(MacQueryFilterLevel, - &Adapter->VifInterface, - ETHERNET_ADDRESS_BROADCAST, - &BroadcastFilterLevel); +static NDIS_STATUS +AdapterGetXmitOk( + IN PXENNET_ADAPTER Adapter, + OUT PULONGLONG Buffer + ) +{ + ULONGLONG Value; - *PacketFilter = 0; + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_TRANSMITTER_UNICAST_PACKETS, + &Value); - if (UnicastFilterLevel == XENVIF_MAC_FILTER_ALL) { - ASSERT3U(MulticastFilterLevel, ==, XENVIF_MAC_FILTER_ALL); - ASSERT3U(BroadcastFilterLevel, ==, XENVIF_MAC_FILTER_ALL); + *Buffer = (ULONG)Value; - *PacketFilter |= NDIS_PACKET_TYPE_PROMISCUOUS; - return; - } else if (UnicastFilterLevel == XENVIF_MAC_FILTER_MATCHING) { - *PacketFilter |= NDIS_PACKET_TYPE_DIRECTED; - } + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_TRANSMITTER_MULTICAST_PACKETS, + &Value); + + *Buffer += (ULONG)Value; - if (MulticastFilterLevel == XENVIF_MAC_FILTER_ALL) - *PacketFilter |= NDIS_PACKET_TYPE_ALL_MULTICAST; - else if (MulticastFilterLevel == XENVIF_MAC_FILTER_MATCHING) - *PacketFilter |= NDIS_PACKET_TYPE_MULTICAST; + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_TRANSMITTER_BROADCAST_PACKETS, + &Value); + + *Buffer += (ULONG)Value; - if (BroadcastFilterLevel == XENVIF_MAC_FILTER_ALL) - *PacketFilter |= NDIS_PACKET_TYPE_BROADCAST; + return NDIS_STATUS_SUCCESS; } -#define MIN(_x, _y) (((_x) < (_y)) ? (_x) : (_y)) - -// -// Handles OID queries. -// -#pragma warning(push) -#pragma warning(disable:6262) -static NDIS_STATUS -AdapterQueryInformation ( - IN PADAPTER Adapter, - IN PNDIS_OID_REQUEST NdisRequest +static NDIS_STATUS +AdapterGetRcvOk( + IN PXENNET_ADAPTER Adapter, + OUT PULONGLONG Buffer ) { - ULONG bytesAvailable = 0; - ULONG bytesNeeded = 0; - ULONG bytesWritten = 0; - BOOLEAN doCopy = TRUE; - PVOID info = NULL; - ULONGLONG infoData; - ULONG informationBufferLength; - PVOID informationBuffer; - NDIS_INTERRUPT_MODERATION_PARAMETERS intModParams; - NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS; - NDIS_OID oid; - - informationBuffer = NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer; - informationBufferLength = NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength; - oid = NdisRequest->DATA.QUERY_INFORMATION.Oid; - switch (oid) { - case OID_PNP_CAPABILITIES: - Trace("PNP_CAPABILITIES\n"); - - info = &Adapter->Capabilities; - bytesAvailable = sizeof(Adapter->Capabilities); - break; - - case OID_PNP_QUERY_POWER: - Trace("QUERY_POWER\n"); - - bytesNeeded = sizeof(NDIS_DEVICE_POWER_STATE); - if (informationBufferLength >= bytesNeeded) { - PNDIS_DEVICE_POWER_STATE state; - - state = (PNDIS_DEVICE_POWER_STATE)informationBuffer; - switch (*state) { - case NdisDeviceStateD0: - Trace("D0\n"); - break; - - case NdisDeviceStateD1: - Trace("D1\n"); - break; - - case NdisDeviceStateD2: - Trace("D2\n"); - break; - - case NdisDeviceStateD3: - Trace("D3\n"); - break; - } - } - break; - - case OID_GEN_SUPPORTED_LIST: - info = &XennetSupportedOids[0]; - bytesAvailable = sizeof(XennetSupportedOids); - break; - - case OID_GEN_HARDWARE_STATUS: - infoData = NdisHardwareStatusReady; - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - - case OID_GEN_MEDIA_SUPPORTED: - case OID_GEN_MEDIA_IN_USE: - infoData = XENNET_MEDIA_TYPE; - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - - case OID_GEN_MAXIMUM_LOOKAHEAD: - infoData = Adapter->MaximumFrameSize; - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - - case OID_GEN_TRANSMIT_BUFFER_SPACE: - XENVIF_VIF(TransmitterQueryRingSize, - &Adapter->VifInterface, - (PULONG)&infoData); - infoData *= Adapter->MaximumFrameSize; - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - - case OID_GEN_RECEIVE_BUFFER_SPACE: - XENVIF_VIF(TransmitterQueryRingSize, - &Adapter->VifInterface, - (PULONG)&infoData); - infoData *= Adapter->MaximumFrameSize; - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - - case OID_GEN_TRANSMIT_BLOCK_SIZE: - case OID_GEN_RECEIVE_BLOCK_SIZE: - infoData = Adapter->MaximumFrameSize; - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - - case OID_GEN_VENDOR_DESCRIPTION: - info = COMPANY_NAME_STR; - bytesAvailable = (ULONG)strlen(info) + 1; - break; - - case OID_GEN_VENDOR_DRIVER_VERSION: - infoData = ((MAJOR_VERSION << 8) | MINOR_VERSION) << 8; - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - - case OID_GEN_DRIVER_VERSION: - infoData = (6 << 8) | 0; - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - - case OID_GEN_MAC_OPTIONS: - infoData = XENNET_MAC_OPTIONS; - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - - case OID_GEN_STATISTICS: - doCopy = FALSE; - - bytesAvailable = sizeof(NDIS_STATISTICS_INFO); - if (informationBufferLength >= bytesAvailable) { - ndisStatus = AdapterQueryGeneralStatistics(Adapter, - informationBuffer); - - } - - break; - - case OID_802_3_MULTICAST_LIST: { - ULONG Count; - - doCopy = FALSE; - - XENVIF_VIF(MacQueryMulticastAddresses, - &Adapter->VifInterface, - NULL, - &Count); - bytesAvailable = Count * ETHERNET_ADDRESS_LENGTH; + ULONGLONG Value; - if (informationBufferLength >= bytesAvailable) { - NTSTATUS status; + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_UNICAST_PACKETS, + &Value); - status = XENVIF_VIF(MacQueryMulticastAddresses, - &Adapter->VifInterface, - informationBuffer, - &Count); - if (!NT_SUCCESS(status)) - ndisStatus = NDIS_STATUS_FAILURE; - } + *Buffer = (ULONG)Value; - break; - } - case OID_802_3_PERMANENT_ADDRESS: - XENVIF_VIF(MacQueryPermanentAddress, - &Adapter->VifInterface, - (PETHERNET_ADDRESS)&infoData); - info = &infoData; - bytesAvailable = sizeof (ETHERNET_ADDRESS); - break; + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_MULTICAST_PACKETS, + &Value); + + *Buffer += (ULONG)Value; - case OID_802_3_CURRENT_ADDRESS: - XENVIF_VIF(MacQueryCurrentAddress, - &Adapter->VifInterface, - (PETHERNET_ADDRESS)&infoData); - info = &infoData; - bytesAvailable = sizeof (ETHERNET_ADDRESS); - break; - - case OID_GEN_MAXIMUM_FRAME_SIZE: - infoData = Adapter->MaximumFrameSize - - sizeof (ETHERNET_TAGGED_HEADER); - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - - case OID_GEN_MAXIMUM_TOTAL_SIZE: - infoData = Adapter->MaximumFrameSize - - sizeof (ETHERNET_TAGGED_HEADER) + - sizeof (ETHERNET_UNTAGGED_HEADER); - - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - - case OID_GEN_CURRENT_LOOKAHEAD: - infoData = Adapter->CurrentLookahead; - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - - case OID_GEN_VENDOR_ID: - infoData = 0x5853; - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - - case OID_GEN_LINK_SPEED: { - ULONG64 LinkSpeed; + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_BROADCAST_PACKETS, + &Value); + + *Buffer += (ULONG)Value; - XENVIF_VIF(MacQueryState, - &Adapter->VifInterface, - NULL, - &LinkSpeed, - NULL); + return NDIS_STATUS_SUCCESS; +} - infoData = (ULONG)(LinkSpeed / 100); - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - } - case OID_GEN_MEDIA_CONNECT_STATUS: - XENVIF_VIF(MacQueryState, - &Adapter->VifInterface, - (PNET_IF_MEDIA_CONNECT_STATE)&infoData, - NULL, - NULL); - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - case OID_GEN_MAXIMUM_SEND_PACKETS: - infoData = 16; - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - - case OID_GEN_CURRENT_PACKET_FILTER: - GetPacketFilter(Adapter, (PULONG)&infoData); - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - - case OID_GEN_XMIT_OK: { - ULONGLONG Value; - - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_TRANSMITTER_UNICAST_PACKETS, - &Value); +static NDIS_STATUS +AdapterGetXmitError( + IN PXENNET_ADAPTER Adapter, + OUT PULONG Buffer + ) +{ + ULONGLONG Value; - infoData = Value; + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_TRANSMITTER_BACKEND_ERRORS, + &Value); - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_TRANSMITTER_MULTICAST_PACKETS, - &Value); + *Buffer = (ULONG)Value; - infoData += Value; + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_TRANSMITTER_FRONTEND_ERRORS, + &Value); + + *Buffer += (ULONG)Value; - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_TRANSMITTER_BROADCAST_PACKETS, - &Value); + return NDIS_STATUS_SUCCESS; +} - infoData += Value; +static FORCEINLINE NDIS_STATUS +AdapterGetRcvError( + IN PXENNET_ADAPTER Adapter, + OUT PULONG Buffer + ) +{ + ULONGLONG Value; - info = &infoData; - bytesAvailable = sizeof(ULONGLONG); - break; - } - case OID_GEN_RCV_OK: { - ULONGLONG Value; + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_BACKEND_ERRORS, + &Value); - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_RECEIVER_UNICAST_PACKETS, - &Value); + *Buffer = (ULONG)Value; - infoData = Value; + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_FRONTEND_ERRORS, + &Value); + + *Buffer += (ULONG)Value; - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_RECEIVER_MULTICAST_PACKETS, - &Value); + return NDIS_STATUS_SUCCESS; +} - infoData += Value; +static FORCEINLINE NDIS_STATUS +AdapterInterruptModeration( + IN PXENNET_ADAPTER Adapter, + IN PNDIS_INTERRUPT_MODERATION_PARAMETERS Params + ) +{ + UNREFERENCED_PARAMETER(Adapter); - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_RECEIVER_BROADCAST_PACKETS, - &Value); + Params->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + Params->Header.Revision = NDIS_INTERRUPT_MODERATION_PARAMETERS_REVISION_1; + Params->Header.Size = sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS); - infoData += Value; + Params->Flags = 0; + Params->InterruptModeration = NdisInterruptModerationNotSupported; - info = &infoData; - bytesAvailable = sizeof(ULONGLONG); - break; - } - case OID_GEN_XMIT_ERROR: { - ULONGLONG Value; + return NDIS_STATUS_SUCCESS; +} - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_TRANSMITTER_BACKEND_ERRORS, - &Value); +NDIS_HANDLE +AdapterGetHandle( + IN PXENNET_ADAPTER Adapter + ) +{ + return Adapter->NdisAdapterHandle; +} - infoData = Value; +PXENVIF_VIF_INTERFACE +AdapterGetVifInterface( + IN PXENNET_ADAPTER Adapter + ) +{ + return &Adapter->VifInterface; +} - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_TRANSMITTER_FRONTEND_ERRORS, - &Value); +PXENNET_TRANSMITTER +AdapterGetTransmitter( + IN PXENNET_ADAPTER Adapter + ) +{ + return Adapter->Transmitter; +} - infoData += Value; +PXENNET_RECEIVER +AdapterGetReceiver( + IN PXENNET_ADAPTER Adapter + ) +{ + return Adapter->Receiver; +} - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - } - case OID_GEN_RCV_ERROR: { - ULONGLONG Value; +NDIS_STATUS +AdapterEnable( + IN PXENNET_ADAPTER Adapter + ) +{ + NTSTATUS status; - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_RECEIVER_BACKEND_ERRORS, - &Value); + if (Adapter->Enabled) + return NDIS_STATUS_SUCCESS; - infoData = Value; + status = XENVIF_VIF(Enable, + &Adapter->VifInterface, + AdapterVifCallback, + Adapter); + if (!NT_SUCCESS(status)) + goto fail1; - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_RECEIVER_FRONTEND_ERRORS, - &Value); + TransmitterEnable(Adapter->Transmitter); + Adapter->Enabled = TRUE; - infoData += Value; + return NDIS_STATUS_SUCCESS; - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - } - case OID_GEN_RCV_NO_BUFFER: - infoData = 0; // We'd need to query VIF TX drop stats from dom0 - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - - case OID_GEN_TRANSMIT_QUEUE_LENGTH: - infoData = 0; - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - - case OID_802_3_MAXIMUM_LIST_SIZE: - infoData = 32; - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - - case OID_IP4_OFFLOAD_STATS: - case OID_IP6_OFFLOAD_STATS: - case OID_GEN_SUPPORTED_GUIDS: - ndisStatus = NDIS_STATUS_NOT_SUPPORTED; - break; - - case OID_GEN_RCV_CRC_ERROR: - infoData = 0; - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - - case OID_802_3_RCV_ERROR_ALIGNMENT: - case OID_802_3_XMIT_ONE_COLLISION: - case OID_802_3_XMIT_MORE_COLLISIONS: - infoData = 0; - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - - case OID_GEN_DIRECTED_BYTES_XMIT: { - ULONGLONG Value; - - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_TRANSMITTER_UNICAST_OCTETS, - &Value); +fail1: + return NDIS_STATUS_FAILURE; +} - infoData = Value; +BOOLEAN +AdapterDisable( + IN PXENNET_ADAPTER Adapter + ) +{ + if (!Adapter->Enabled) + return FALSE; - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - } - case OID_GEN_DIRECTED_FRAMES_XMIT: { - ULONGLONG Value; + XENVIF_VIF(Disable, + &Adapter->VifInterface); - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_TRANSMITTER_UNICAST_PACKETS, - &Value); + AdapterMediaStateChange(Adapter); - infoData = Value; + Adapter->Enabled = FALSE; - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - } - case OID_GEN_MULTICAST_BYTES_XMIT: { - ULONGLONG Value; + return TRUE; +} - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_TRANSMITTER_MULTICAST_OCTETS, - &Value); +VOID +AdapterMediaStateChange( + IN PXENNET_ADAPTER Adapter + ) +{ + NDIS_LINK_STATE LinkState; + NDIS_STATUS_INDICATION StatusIndication; - infoData = Value; + RtlZeroMemory(&LinkState, sizeof (NDIS_LINK_STATE)); + LinkState.Header.Revision = NDIS_LINK_STATE_REVISION_1; + LinkState.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + LinkState.Header.Size = sizeof(NDIS_LINK_STATE); - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - } - case OID_GEN_MULTICAST_FRAMES_XMIT: { - ULONGLONG Value; + XENVIF_VIF(MacQueryState, + &Adapter->VifInterface, + &LinkState.MediaConnectState, + &LinkState.RcvLinkSpeed, + &LinkState.MediaDuplexState); - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_TRANSMITTER_MULTICAST_PACKETS, - &Value); + if (LinkState.MediaConnectState == MediaConnectStateUnknown) { + Info("LINK: STATE UNKNOWN\n"); + } else if (LinkState.MediaConnectState == MediaConnectStateDisconnected) { + Info("LINK: DOWN\n"); + } else { + ASSERT3U(LinkState.MediaConnectState, ==, MediaConnectStateConnected); - infoData = Value; + if (LinkState.MediaDuplexState == MediaDuplexStateHalf) + Info("LINK: UP: SPEED=%u DUPLEX=HALF\n", LinkState.RcvLinkSpeed); + else if (LinkState.MediaDuplexState == MediaDuplexStateFull) + Info("LINK: UP: SPEED=%u DUPLEX=FULL\n", LinkState.RcvLinkSpeed); + else + Info("LINK: UP: SPEED=%u DUPLEX=UNKNOWN\n", LinkState.RcvLinkSpeed); + } - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - } - case OID_GEN_BROADCAST_BYTES_XMIT: { - ULONGLONG Value; + LinkState.XmitLinkSpeed = LinkState.RcvLinkSpeed; - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_TRANSMITTER_BROADCAST_OCTETS, - &Value); + RtlZeroMemory(&StatusIndication, sizeof (NDIS_STATUS_INDICATION)); + StatusIndication.Header.Type = NDIS_OBJECT_TYPE_STATUS_INDICATION; + StatusIndication.Header.Revision = NDIS_STATUS_INDICATION_REVISION_1; + StatusIndication.Header.Size = sizeof (NDIS_STATUS_INDICATION); + + StatusIndication.SourceHandle = Adapter->NdisAdapterHandle; + StatusIndication.StatusCode = NDIS_STATUS_LINK_STATE; + StatusIndication.StatusBuffer = &LinkState; + StatusIndication.StatusBufferSize = sizeof (NDIS_LINK_STATE); - infoData = Value; + NdisMIndicateStatusEx(Adapter->NdisAdapterHandle, &StatusIndication); +} - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; +NDIS_STATUS +AdapterSetInformation( + IN PXENNET_ADAPTER Adapter, + IN PNDIS_OID_REQUEST Request + ) +{ + PVOID Buffer; + ULONG BufferLength; + ULONG BytesNeeded; + ULONG BytesRead; + NDIS_STATUS ndisStatus; + + Buffer = Request->DATA.SET_INFORMATION.InformationBuffer; + BufferLength = Request->DATA.SET_INFORMATION.InformationBufferLength; + BytesNeeded = BytesRead = 0; + ndisStatus = NDIS_STATUS_SUCCESS; + + switch (Request->DATA.SET_INFORMATION.Oid) { + case OID_PNP_SET_POWER: + BytesNeeded = sizeof(NDIS_DEVICE_POWER_STATE); + // do nothing + break; + + case OID_GEN_CURRENT_LOOKAHEAD: + BytesNeeded = sizeof(ULONG); + Adapter->CurrentLookahead = Adapter->MaximumFrameSize; + if (BufferLength == BytesNeeded) { + Adapter->CurrentLookahead = *(PULONG)Buffer; + BytesRead = sizeof(ULONG); + } + break; + + case OID_GEN_CURRENT_PACKET_FILTER: + BytesNeeded = sizeof(ULONG); + if (BufferLength == BytesNeeded) { + AdapterSetPacketFilter(Adapter, + (PULONG)Buffer); + BytesRead = sizeof(ULONG); } - case OID_GEN_BROADCAST_FRAMES_XMIT: { - ULONGLONG Value; + break; - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_TRANSMITTER_BROADCAST_PACKETS, - &Value); + case OID_802_3_MULTICAST_LIST: + BytesNeeded = ETHERNET_ADDRESS_LENGTH; + if (BufferLength % ETHERNET_ADDRESS_LENGTH == 0) { + ndisStatus = AdapterSetMulticastAddresses(Adapter, + Buffer, + BufferLength / ETHERNET_ADDRESS_LENGTH); + if (ndisStatus == NDIS_STATUS_SUCCESS) + BytesRead = BufferLength; + } else { + ndisStatus = NDIS_STATUS_INVALID_LENGTH; + } + break; - infoData = Value; + case OID_OFFLOAD_ENCAPSULATION: + BytesNeeded = sizeof(NDIS_OFFLOAD_ENCAPSULATION); + if (BufferLength >= BytesNeeded) { + ndisStatus = AdapterGetOffloadEncapsulation(Adapter, + (PNDIS_OFFLOAD_ENCAPSULATION)Buffer); + if (ndisStatus == NDIS_STATUS_SUCCESS) + BytesRead = sizeof(NDIS_OFFLOAD_ENCAPSULATION); + } + break; - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; + case OID_TCP_OFFLOAD_PARAMETERS: + BytesNeeded = sizeof(NDIS_OFFLOAD_PARAMETERS); + if (BufferLength >= BytesNeeded) { + ndisStatus = AdapterGetTcpOffloadParameters(Adapter, + (PNDIS_OFFLOAD_PARAMETERS)Buffer); + if (ndisStatus == NDIS_STATUS_SUCCESS) + BytesRead = sizeof(NDIS_OFFLOAD_PARAMETERS); } - case OID_GEN_DIRECTED_BYTES_RCV: { - ULONGLONG Value; + break; - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_RECEIVER_UNICAST_OCTETS, - &Value); + case OID_GEN_INTERRUPT_MODERATION: + case OID_GEN_MACHINE_NAME: + default: + ndisStatus = NDIS_STATUS_NOT_SUPPORTED; + break; + } + + Request->DATA.SET_INFORMATION.BytesNeeded = BytesNeeded; + if (ndisStatus == NDIS_STATUS_SUCCESS) + Request->DATA.SET_INFORMATION.BytesRead = BytesRead; - infoData = Value; + return ndisStatus; +} - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; +static FORCEINLINE NDIS_STATUS +__CopyBuffer( + IN PVOID Buffer, + IN ULONG BufferLength, + IN PVOID Source, + IN OUT PULONG SourceLength + ) +{ + if (BufferLength >= *SourceLength) { + RtlCopyMemory(Buffer, Source, *SourceLength); + return NDIS_STATUS_SUCCESS; + } else { + *SourceLength = BufferLength; + RtlCopyMemory(Buffer, Source, *SourceLength); + return NDIS_STATUS_BUFFER_TOO_SHORT; + } +} + +static FORCEINLINE NDIS_STATUS +__SetUlong( + IN PVOID Buffer, + IN ULONG BufferLength, + IN ULONG Source, + IN OUT PULONG SourceLength + ) +{ + if (BufferLength >= sizeof(ULONG)) { + *(PULONG)Buffer = Source; + *SourceLength = sizeof(ULONG); + return NDIS_STATUS_SUCCESS; + } else { + *SourceLength = 0; + return NDIS_STATUS_BUFFER_TOO_SHORT; + } +} + +NDIS_STATUS +AdapterQueryInformation( + IN PXENNET_ADAPTER Adapter, + IN PNDIS_OID_REQUEST Request + ) +{ + PVOID Buffer; + ULONG BufferLength; + ULONG BytesNeeded; + ULONG BytesWritten; + ULONG Value32; + ULONGLONG Value64; + NDIS_STATUS ndisStatus; + + Buffer = Request->DATA.QUERY_INFORMATION.InformationBuffer; + BufferLength = Request->DATA.QUERY_INFORMATION.InformationBufferLength; + BytesNeeded = BytesWritten = sizeof(ULONG); + ndisStatus = NDIS_STATUS_SUCCESS; + + switch (Request->DATA.QUERY_INFORMATION.Oid) { + case OID_PNP_CAPABILITIES: + BytesNeeded = BytesWritten = sizeof(Adapter->Capabilities); + ndisStatus = __CopyBuffer(Buffer, + BufferLength, + &Adapter->Capabilities, + &BytesWritten); + break; + + case OID_PNP_QUERY_POWER: + BytesNeeded = sizeof(NDIS_DEVICE_POWER_STATE); + // do nothing + break; + + case OID_GEN_SUPPORTED_LIST: + BytesNeeded = BytesWritten = sizeof(XennetSupportedOids); + ndisStatus = __CopyBuffer(Buffer, + BufferLength, + &XennetSupportedOids[0], + &BytesWritten); + break; + + case OID_GEN_HARDWARE_STATUS: + ndisStatus = __SetUlong(Buffer, + BufferLength, + NdisHardwareStatusReady, + &BytesWritten); + break; + + case OID_GEN_MEDIA_SUPPORTED: + case OID_GEN_MEDIA_IN_USE: + ndisStatus = __SetUlong(Buffer, + BufferLength, + XENNET_MEDIA_TYPE, + &BytesWritten); + break; + + case OID_GEN_MAXIMUM_LOOKAHEAD: + case OID_GEN_TRANSMIT_BLOCK_SIZE: + case OID_GEN_RECEIVE_BLOCK_SIZE: + ndisStatus = __SetUlong(Buffer, + BufferLength, + Adapter->MaximumFrameSize, + &BytesWritten); + break; + + case OID_GEN_TRANSMIT_BUFFER_SPACE: + case OID_GEN_RECEIVE_BUFFER_SPACE: + XENVIF_VIF(TransmitterQueryRingSize, + &Adapter->VifInterface, + (PULONG)&Value32); + Value32 *= Adapter->MaximumFrameSize; + ndisStatus = __SetUlong(Buffer, + BufferLength, + Value32, + &BytesWritten); + break; + + case OID_GEN_VENDOR_DESCRIPTION: + BytesNeeded = BytesWritten = (ULONG)strlen(COMPANY_NAME_STR) + 1; + ndisStatus = __CopyBuffer(Buffer, + BufferLength, + COMPANY_NAME_STR, + &BytesWritten); + break; + + case OID_GEN_VENDOR_DRIVER_VERSION: + ndisStatus = __SetUlong(Buffer, + BufferLength, + ((MAJOR_VERSION << 8) | MINOR_VERSION) << 8, + &BytesWritten); + break; + + case OID_GEN_DRIVER_VERSION: + ndisStatus = __SetUlong(Buffer, + BufferLength, + (6 << 8) | 0, // NDIS 6.0 + &BytesWritten); + break; + + case OID_GEN_MAC_OPTIONS: + ndisStatus = __SetUlong(Buffer, + BufferLength, + XENNET_MAC_OPTIONS, + &BytesWritten); + break; + + case OID_GEN_STATISTICS: + BytesNeeded = BytesWritten = sizeof(NDIS_STATISTICS_INFO); + if (BufferLength >= BytesNeeded) + ndisStatus = AdapterQueryGeneralStatistics(Adapter, + (PNDIS_STATISTICS_INFO)Buffer); + break; + + case OID_802_3_MULTICAST_LIST: + ndisStatus = AdapterQueryMulticastList(Adapter, + Buffer, + BufferLength, + &BytesNeeded); + BytesWritten = BytesNeeded; + break; + + case OID_802_3_PERMANENT_ADDRESS: + BytesNeeded = BytesWritten = sizeof(ETHERNET_ADDRESS); + if (BufferLength >= BytesNeeded) { + XENVIF_VIF(MacQueryPermanentAddress, + &Adapter->VifInterface, + (PETHERNET_ADDRESS)Buffer); } - case OID_GEN_DIRECTED_FRAMES_RCV: { - ULONGLONG Value; + break; - XENVIF_VIF(QueryStatistic, + case OID_802_3_CURRENT_ADDRESS: + BytesNeeded = BytesWritten = sizeof(ETHERNET_ADDRESS); + if (BufferLength >= BytesNeeded) { + XENVIF_VIF(MacQueryCurrentAddress, &Adapter->VifInterface, - XENVIF_RECEIVER_UNICAST_PACKETS, - &Value); + (PETHERNET_ADDRESS)Buffer); + } + break; - infoData = Value; + case OID_GEN_MAXIMUM_FRAME_SIZE: + ndisStatus = __SetUlong(Buffer, + BufferLength, + Adapter->MaximumFrameSize - sizeof(ETHERNET_TAGGED_HEADER), + &BytesWritten); + break; - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - } - case OID_GEN_MULTICAST_BYTES_RCV: { - ULONGLONG Value; + case OID_GEN_MAXIMUM_TOTAL_SIZE: + ndisStatus = __SetUlong(Buffer, + BufferLength, + Adapter->MaximumFrameSize - + sizeof(ETHERNET_TAGGED_HEADER) + + sizeof (ETHERNET_UNTAGGED_HEADER), + &BytesWritten); + break; - XENVIF_VIF(QueryStatistic, + case OID_GEN_CURRENT_LOOKAHEAD: + ndisStatus = __SetUlong(Buffer, + BufferLength, + Adapter->CurrentLookahead, + &BytesWritten); + break; + + case OID_GEN_VENDOR_ID: + ndisStatus = __SetUlong(Buffer, + BufferLength, + 0x5853, + &BytesWritten); + break; + + case OID_GEN_LINK_SPEED: + XENVIF_VIF(MacQueryState, + &Adapter->VifInterface, + NULL, + &Value64, + NULL); + ndisStatus = __SetUlong(Buffer, + BufferLength, + (ULONG)(Value64 / 100), + &BytesWritten); + break; + + case OID_GEN_MEDIA_CONNECT_STATUS: + if (BufferLength >= sizeof(ULONG)) { + XENVIF_VIF(MacQueryState, &Adapter->VifInterface, - XENVIF_RECEIVER_MULTICAST_OCTETS, - &Value); + (PNET_IF_MEDIA_CONNECT_STATE)Buffer, + NULL, + NULL); + } + break; - infoData = Value; + case OID_GEN_MAXIMUM_SEND_PACKETS: + ndisStatus = __SetUlong(Buffer, + BufferLength, + 16, + &BytesWritten); + break; - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; + case OID_GEN_CURRENT_PACKET_FILTER: + if (BufferLength >= sizeof(ULONG)) { + AdapterGetPacketFilter(Adapter, + (PULONG)Buffer); } - case OID_GEN_MULTICAST_FRAMES_RCV: { - ULONGLONG Value; + break; - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_RECEIVER_MULTICAST_PACKETS, - &Value); + case OID_GEN_XMIT_OK: + BytesNeeded = BytesWritten = sizeof(ULONGLONG); + if (BufferLength >= BytesNeeded) { + ndisStatus = AdapterGetXmitOk(Adapter, + (PULONGLONG)Buffer); + } + break; - infoData = Value; + case OID_GEN_RCV_OK: + BytesNeeded = BytesWritten = sizeof(ULONGLONG); + if (BufferLength >= BytesNeeded) { + ndisStatus = AdapterGetRcvOk(Adapter, + (PULONGLONG)Buffer); + } + break; - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; + case OID_GEN_XMIT_ERROR: + if (BufferLength >= BytesNeeded) { + ndisStatus = AdapterGetXmitError(Adapter, + (PULONG)Buffer); } - case OID_GEN_BROADCAST_BYTES_RCV: { - ULONGLONG Value; + break; - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_RECEIVER_BROADCAST_OCTETS, - &Value); + case OID_GEN_RCV_ERROR: + if (BufferLength >= BytesNeeded) { + ndisStatus = AdapterGetRcvError(Adapter, + (PULONG)Buffer); + } + break; + + case OID_GEN_RCV_NO_BUFFER: + case OID_GEN_TRANSMIT_QUEUE_LENGTH: + case OID_GEN_RCV_CRC_ERROR: + case OID_802_3_RCV_ERROR_ALIGNMENT: + case OID_802_3_XMIT_ONE_COLLISION: + case OID_802_3_XMIT_MORE_COLLISIONS: + ndisStatus = __SetUlong(Buffer, + BufferLength, + 0, + &BytesWritten); + break; + + case OID_802_3_MAXIMUM_LIST_SIZE: + ndisStatus = __SetUlong(Buffer, + BufferLength, + 32, + &BytesWritten); + break; + + case OID_GEN_DIRECTED_BYTES_XMIT: + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_TRANSMITTER_UNICAST_OCTETS, + &Value64); + ndisStatus = __SetUlong(Buffer, + BufferLength, + (ULONG)Value64, + &BytesWritten); + break; + + case OID_GEN_DIRECTED_FRAMES_XMIT: + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_TRANSMITTER_UNICAST_PACKETS, + &Value64); + ndisStatus = __SetUlong(Buffer, + BufferLength, + (ULONG)Value64, + &BytesWritten); + break; + + case OID_GEN_MULTICAST_BYTES_XMIT: + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_TRANSMITTER_MULTICAST_OCTETS, + &Value64); + ndisStatus = __SetUlong(Buffer, + BufferLength, + (ULONG)Value64, + &BytesWritten); + break; + + case OID_GEN_MULTICAST_FRAMES_XMIT: + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_TRANSMITTER_MULTICAST_PACKETS, + &Value64); + ndisStatus = __SetUlong(Buffer, + BufferLength, + (ULONG)Value64, + &BytesWritten); + break; + + case OID_GEN_BROADCAST_BYTES_XMIT: + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_TRANSMITTER_BROADCAST_OCTETS, + &Value64); + ndisStatus = __SetUlong(Buffer, + BufferLength, + (ULONG)Value64, + &BytesWritten); + break; + + case OID_GEN_BROADCAST_FRAMES_XMIT: + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_TRANSMITTER_BROADCAST_PACKETS, + &Value64); + ndisStatus = __SetUlong(Buffer, + BufferLength, + (ULONG)Value64, + &BytesWritten); + break; + + case OID_GEN_DIRECTED_BYTES_RCV: + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_UNICAST_OCTETS, + &Value64); + ndisStatus = __SetUlong(Buffer, + BufferLength, + (ULONG)Value64, + &BytesWritten); + break; + + case OID_GEN_DIRECTED_FRAMES_RCV: + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_UNICAST_PACKETS, + &Value64); + ndisStatus = __SetUlong(Buffer, + BufferLength, + (ULONG)Value64, + &BytesWritten); + break; - infoData = Value; + case OID_GEN_MULTICAST_BYTES_RCV: + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_MULTICAST_OCTETS, + &Value64); + ndisStatus = __SetUlong(Buffer, + BufferLength, + (ULONG)Value64, + &BytesWritten); + break; - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - } - case OID_GEN_BROADCAST_FRAMES_RCV: { - ULONGLONG Value; + case OID_GEN_MULTICAST_FRAMES_RCV: + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_MULTICAST_PACKETS, + &Value64); + ndisStatus = __SetUlong(Buffer, + BufferLength, + (ULONG)Value64, + &BytesWritten); + break; - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_RECEIVER_BROADCAST_PACKETS, - &Value); + case OID_GEN_BROADCAST_BYTES_RCV: + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_BROADCAST_OCTETS, + &Value64); + ndisStatus = __SetUlong(Buffer, + BufferLength, + (ULONG)Value64, + &BytesWritten); + break; - infoData = Value; + case OID_GEN_BROADCAST_FRAMES_RCV: + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_BROADCAST_PACKETS, + &Value64); + ndisStatus = __SetUlong(Buffer, + BufferLength, + (ULONG)Value64, + &BytesWritten); + break; - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; + case OID_GEN_INTERRUPT_MODERATION: + BytesNeeded = BytesWritten = sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS); + if (BufferLength >= BytesWritten) { + ndisStatus = AdapterInterruptModeration(Adapter, + (PNDIS_INTERRUPT_MODERATION_PARAMETERS)Buffer); } - case OID_GEN_INTERRUPT_MODERATION: - intModParams.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - intModParams.Header.Revision = NDIS_INTERRUPT_MODERATION_PARAMETERS_REVISION_1; - intModParams.Header.Size = sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS); - intModParams.Flags = 0; - intModParams.InterruptModeration = NdisInterruptModerationNotSupported; - info = &intModParams; - bytesAvailable = sizeof(intModParams); - break; + break; + + case OID_IP4_OFFLOAD_STATS: + case OID_IP6_OFFLOAD_STATS: + case OID_GEN_SUPPORTED_GUIDS: // We don't handle these since NDIS 6.0 is supposed to do this for us - case OID_GEN_MAC_ADDRESS: - case OID_GEN_MAX_LINK_SPEED: - ndisStatus = NDIS_STATUS_NOT_SUPPORTED; - break; - - // ignore these common unwanted OIDs - case OID_GEN_INIT_TIME_MS: - case OID_GEN_RESET_COUNTS: - case OID_GEN_MEDIA_SENSE_COUNTS: - ndisStatus = NDIS_STATUS_NOT_SUPPORTED; - break; - - default: - ndisStatus = NDIS_STATUS_NOT_SUPPORTED; - break; - }; - - if (ndisStatus == NDIS_STATUS_SUCCESS) { - if (bytesAvailable <= informationBufferLength) { - bytesNeeded = bytesAvailable; - bytesWritten = bytesAvailable; - } else { - bytesNeeded = bytesAvailable; - bytesWritten = informationBufferLength; - ndisStatus = NDIS_STATUS_BUFFER_TOO_SHORT; - } + case OID_GEN_MAC_ADDRESS: + case OID_GEN_MAX_LINK_SPEED: - if (bytesWritten && doCopy) { - NdisMoveMemory(informationBuffer, info, bytesWritten); + // ignore these common unwanted OIDs + case OID_GEN_INIT_TIME_MS: + case OID_GEN_RESET_COUNTS: + case OID_GEN_MEDIA_SENSE_COUNTS: - if (oid == OID_GEN_XMIT_OK || oid == OID_GEN_RCV_OK) - ndisStatus = NDIS_STATUS_SUCCESS; - } + default: + ndisStatus = NDIS_STATUS_NOT_SUPPORTED; + BytesNeeded = 0; + break; } - - NdisRequest->DATA.QUERY_INFORMATION.BytesWritten = bytesWritten; - NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded = bytesNeeded; + + if (ndisStatus == NDIS_STATUS_SUCCESS) + Request->DATA.QUERY_INFORMATION.BytesWritten = BytesWritten; + + Request->DATA.QUERY_INFORMATION.BytesNeeded = BytesNeeded; + return ndisStatus; } -#pragma warning(pop) -NDIS_STATUS -AdapterReset ( - IN NDIS_HANDLE MiniportAdapterContext, - OUT PBOOLEAN AddressingReset +static NTSTATUS +__QueryInterface( + IN PDEVICE_OBJECT DeviceObject, + IN const GUID *Guid, + IN ULONG Version, + OUT PINTERFACE Interface, + IN ULONG Size, + IN BOOLEAN Optional ) { - UNREFERENCED_PARAMETER(MiniportAdapterContext); - + KEVENT Event; + IO_STATUS_BLOCK StatusBlock; + PIRP Irp; + PIO_STACK_LOCATION StackLocation; + NTSTATUS status; - *AddressingReset = FALSE; + ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL); - return NDIS_STATUS_SUCCESS; -} + KeInitializeEvent(&Event, NotificationEvent, FALSE); + RtlZeroMemory(&StatusBlock, sizeof(IO_STATUS_BLOCK)); -// -// Restarts a paused adapter. -// -NDIS_STATUS -AdapterRestart ( - IN NDIS_HANDLE MiniportAdapterContext, - IN PNDIS_MINIPORT_RESTART_PARAMETERS MiniportRestartParameters - ) -{ - NTSTATUS status; - NDIS_STATUS ndisStatus; - PADAPTER Adapter = (PADAPTER)MiniportAdapterContext; + Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, + DeviceObject, + NULL, + 0, + NULL, + &Event, + &StatusBlock); - UNREFERENCED_PARAMETER(MiniportRestartParameters); + status = STATUS_UNSUCCESSFUL; + if (Irp == NULL) + goto fail1; - Trace("====>\n"); + StackLocation = IoGetNextIrpStackLocation(Irp); + StackLocation->MinorFunction = IRP_MN_QUERY_INTERFACE; - if (Adapter->Enabled) { - ndisStatus = NDIS_STATUS_SUCCESS; - goto done; + StackLocation->Parameters.QueryInterface.InterfaceType = Guid; + StackLocation->Parameters.QueryInterface.Size = (USHORT)Size; + StackLocation->Parameters.QueryInterface.Version = (USHORT)Version; + StackLocation->Parameters.QueryInterface.Interface = Interface; + + Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; + + status = IoCallDriver(DeviceObject, Irp); + if (status == STATUS_PENDING) { + (VOID) KeWaitForSingleObject(&Event, + Executive, + KernelMode, + FALSE, + NULL); + status = StatusBlock.Status; } - status = XENVIF_VIF(Enable, - &Adapter->VifInterface, - AdapterVifCallback, - Adapter); - if (NT_SUCCESS(status)) { - TransmitterEnable(Adapter->Transmitter); - Adapter->Enabled = TRUE; - ndisStatus = NDIS_STATUS_SUCCESS; - } else { - ndisStatus = NDIS_STATUS_FAILURE; + if (!NT_SUCCESS(status)) { + if (status == STATUS_NOT_SUPPORTED && Optional) + goto done; + + goto fail2; } done: - Trace("<====\n"); - return ndisStatus; -} + return STATUS_SUCCESS; -// -// Recycle of received net buffer lists. -// -VOID -AdapterReturnNetBufferLists ( - IN NDIS_HANDLE MiniportAdapterContext, - IN PNET_BUFFER_LIST NetBufferLists, - IN ULONG ReturnFlags - ) -{ - PADAPTER Adapter = (PADAPTER)MiniportAdapterContext; +fail2: + Error("fail2\n"); - ReceiverReturnNetBufferLists(&Adapter->Receiver, - NetBufferLists, - ReturnFlags); +fail1: + Error("fail1 (%08x)\n", status); - return; + return status; } -// -// Used to send net buffer lists. -// -VOID -AdapterSendNetBufferLists ( - IN NDIS_HANDLE MiniportAdapterContext, - IN PNET_BUFFER_LIST NetBufferList, - IN NDIS_PORT_NUMBER PortNumber, - IN ULONG SendFlags +#define READ_PROPERTY(field, name, defaultval, handle) \ + do { \ + NDIS_STATUS _Status; \ + NDIS_STRING _Value; \ + PNDIS_CONFIGURATION_PARAMETER _Data; \ + RtlInitUnicodeString(&_Value, name); \ + NdisReadConfiguration(&_Status, &_Data, handle, \ + &_Value, NdisParameterInteger); \ + if (_Status == NDIS_STATUS_SUCCESS) \ + field = _Data->ParameterData.IntegerData; \ + else \ + field = defaultval; \ + } while (FALSE); + +static NDIS_STATUS +AdapterGetAdvancedSettings( + IN PXENNET_ADAPTER Adapter ) { - PADAPTER Adapter = (PADAPTER)MiniportAdapterContext; + NDIS_CONFIGURATION_OBJECT Config; + NDIS_HANDLE Handle; + NDIS_STATUS ndisStatus; + + RtlZeroMemory(&Config, sizeof(NDIS_CONFIGURATION_OBJECT)); + Config.Header.Type = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT; + Config.Header.Revision = NDIS_CONFIGURATION_OBJECT_REVISION_1; + Config.Header.Size = sizeof(NDIS_CONFIGURATION_OBJECT); + Config.NdisHandle = Adapter->NdisAdapterHandle; + Config.Flags = 0; + + ndisStatus = NdisOpenConfigurationEx(&Config, &Handle); + if (ndisStatus != NDIS_STATUS_SUCCESS) + goto fail1; - TransmitterSendNetBufferLists(Adapter->Transmitter, - NetBufferList, - PortNumber, - SendFlags); -} + READ_PROPERTY(Adapter->Properties.ipv4_csum, L"*IPChecksumOffloadIPv4", 3, Handle); + READ_PROPERTY(Adapter->Properties.tcpv4_csum, L"*TCPChecksumOffloadIPv4", 3, Handle); + READ_PROPERTY(Adapter->Properties.udpv4_csum, L"*UDPChecksumOffloadIPv4", 3, Handle); + READ_PROPERTY(Adapter->Properties.tcpv6_csum, L"*TCPChecksumOffloadIPv6", 3, Handle); + READ_PROPERTY(Adapter->Properties.udpv6_csum, L"*UDPChecksumOffloadIPv6", 3, Handle); + READ_PROPERTY(Adapter->Properties.lsov4, L"*LSOv2IPv4", 1, Handle); + READ_PROPERTY(Adapter->Properties.lsov6, L"*LSOv2IPv6", 1, Handle); + READ_PROPERTY(Adapter->Properties.lrov4, L"LROIPv4", 1, Handle); + READ_PROPERTY(Adapter->Properties.lrov6, L"LROIPv6", 1, Handle); + READ_PROPERTY(Adapter->Properties.need_csum_value, L"NeedChecksumValue", 1, Handle); + + NdisCloseConfiguration(Handle); -#define XENNET_MEDIA_MAX_SPEED 1000000000ull + return NDIS_STATUS_SUCCESS; + +fail1: + return NDIS_STATUS_FAILURE; +} -#define XENNET_SUPPORTED_PACKET_FILTERS \ - (NDIS_PACKET_TYPE_DIRECTED | \ - NDIS_PACKET_TYPE_MULTICAST | \ - NDIS_PACKET_TYPE_ALL_MULTICAST | \ - NDIS_PACKET_TYPE_BROADCAST | \ - NDIS_PACKET_TYPE_PROMISCUOUS) +#undef READ_PROPERTY -// -// Sets general adapter attributes. -// static NDIS_STATUS -AdapterSetGeneralAttributes ( - IN PADAPTER Adapter +AdapterSetRegistrationAttributes( + IN PXENNET_ADAPTER Adapter ) { - PNDIS_MINIPORT_ADAPTER_ATTRIBUTES adapterAttributes; - NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES generalAttributes; - NDIS_STATUS ndisStatus; + NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES Attribs; + NDIS_STATUS ndisStatus; + + RtlZeroMemory(&Attribs, sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES)); + Attribs.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES; + Attribs.Header.Revision = NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1; + Attribs.Header.Size = sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES); + Attribs.MiniportAdapterContext = (NDIS_HANDLE)Adapter; + Attribs.AttributeFlags = NDIS_MINIPORT_ATTRIBUTES_BUS_MASTER | + NDIS_MINIPORT_ATTRIBUTES_NO_HALT_ON_SUSPEND; + Attribs.CheckForHangTimeInSeconds = 0; + Attribs.InterfaceType = XENNET_INTERFACE_TYPE; - NdisZeroMemory(&generalAttributes, - sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES)); - - generalAttributes.Header.Type = - NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES; + ndisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle, + (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs); - generalAttributes.Header.Revision = - NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_1; + return ndisStatus; +} - generalAttributes.Header.Size = - sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES); +static NDIS_STATUS +AdapterSetGeneralAttributes( + IN PXENNET_ADAPTER Adapter + ) +{ + NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES Attribs; + NDIS_STATUS ndisStatus; - generalAttributes.MediaType = XENNET_MEDIA_TYPE; + RtlZeroMemory(&Attribs, sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES)); + Attribs.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES; + Attribs.Header.Revision = NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_1; + Attribs.Header.Size = sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES); + Attribs.MediaType = XENNET_MEDIA_TYPE; XENVIF_VIF(MacQueryMaximumFrameSize, &Adapter->VifInterface, (PULONG)&Adapter->MaximumFrameSize); - generalAttributes.MtuSize = Adapter->MaximumFrameSize - sizeof (ETHERNET_TAGGED_HEADER); - generalAttributes.MaxXmitLinkSpeed = XENNET_MEDIA_MAX_SPEED; - generalAttributes.MaxRcvLinkSpeed = XENNET_MEDIA_MAX_SPEED; - generalAttributes.XmitLinkSpeed = XENNET_MEDIA_MAX_SPEED; - generalAttributes.RcvLinkSpeed = XENNET_MEDIA_MAX_SPEED; - generalAttributes.MediaConnectState = MediaConnectStateConnected; - generalAttributes.MediaDuplexState = MediaDuplexStateFull; - generalAttributes.LookaheadSize = Adapter->MaximumFrameSize; - generalAttributes.PowerManagementCapabilities = &Adapter->Capabilities; - generalAttributes.MacOptions = XENNET_MAC_OPTIONS; - - generalAttributes.SupportedPacketFilters = XENNET_SUPPORTED_PACKET_FILTERS; - - generalAttributes.MaxMulticastListSize = 32; - generalAttributes.MacAddressLength = ETHERNET_ADDRESS_LENGTH; + Attribs.MtuSize = Adapter->MaximumFrameSize - sizeof (ETHERNET_TAGGED_HEADER); + Attribs.MaxXmitLinkSpeed = XENNET_MEDIA_MAX_SPEED; + Attribs.MaxRcvLinkSpeed = XENNET_MEDIA_MAX_SPEED; + Attribs.XmitLinkSpeed = XENNET_MEDIA_MAX_SPEED; + Attribs.RcvLinkSpeed = XENNET_MEDIA_MAX_SPEED; + Attribs.MediaConnectState = MediaConnectStateConnected; + Attribs.MediaDuplexState = MediaDuplexStateFull; + Attribs.LookaheadSize = Adapter->MaximumFrameSize; + Attribs.PowerManagementCapabilities = &Adapter->Capabilities; + Attribs.MacOptions = XENNET_MAC_OPTIONS; + Attribs.SupportedPacketFilters = XENNET_SUPPORTED_PACKET_FILTERS; + Attribs.MaxMulticastListSize = 32; + Attribs.MacAddressLength = ETHERNET_ADDRESS_LENGTH; XENVIF_VIF(MacQueryPermanentAddress, &Adapter->VifInterface, - (PETHERNET_ADDRESS)&generalAttributes.PermanentMacAddress); + (PETHERNET_ADDRESS)&Attribs.PermanentMacAddress); XENVIF_VIF(MacQueryCurrentAddress, &Adapter->VifInterface, - (PETHERNET_ADDRESS)&generalAttributes.CurrentMacAddress); - - generalAttributes.PhysicalMediumType = NdisPhysicalMedium802_3; - generalAttributes.RecvScaleCapabilities = NULL; - generalAttributes.AccessType = NET_IF_ACCESS_BROADCAST; - generalAttributes.DirectionType = NET_IF_DIRECTION_SENDRECEIVE; - generalAttributes.ConnectionType = NET_IF_CONNECTION_DEDICATED; - generalAttributes.IfType = IF_TYPE_ETHERNET_CSMACD; - generalAttributes.IfConnectorPresent = TRUE; - - generalAttributes.SupportedStatistics = NDIS_STATISTICS_XMIT_OK_SUPPORTED | - NDIS_STATISTICS_XMIT_ERROR_SUPPORTED | - NDIS_STATISTICS_DIRECTED_BYTES_XMIT_SUPPORTED | - NDIS_STATISTICS_DIRECTED_FRAMES_XMIT_SUPPORTED | - NDIS_STATISTICS_MULTICAST_BYTES_XMIT_SUPPORTED | - NDIS_STATISTICS_MULTICAST_FRAMES_XMIT_SUPPORTED | - NDIS_STATISTICS_BROADCAST_BYTES_XMIT_SUPPORTED | - NDIS_STATISTICS_BROADCAST_FRAMES_XMIT_SUPPORTED | - NDIS_STATISTICS_RCV_OK_SUPPORTED | - NDIS_STATISTICS_RCV_ERROR_SUPPORTED | - NDIS_STATISTICS_DIRECTED_BYTES_RCV_SUPPORTED | - NDIS_STATISTICS_DIRECTED_FRAMES_RCV_SUPPORTED | - NDIS_STATISTICS_MULTICAST_BYTES_RCV_SUPPORTED | - NDIS_STATISTICS_MULTICAST_FRAMES_RCV_SUPPORTED | - NDIS_STATISTICS_BROADCAST_BYTES_RCV_SUPPORTED | - NDIS_STATISTICS_BROADCAST_FRAMES_RCV_SUPPORTED | - NDIS_STATISTICS_GEN_STATISTICS_SUPPORTED; + (PETHERNET_ADDRESS)&Attribs.CurrentMacAddress); + + Attribs.PhysicalMediumType = NdisPhysicalMedium802_3; + Attribs.RecvScaleCapabilities = NULL; + Attribs.AccessType = NET_IF_ACCESS_BROADCAST; + Attribs.DirectionType = NET_IF_DIRECTION_SENDRECEIVE; + Attribs.ConnectionType = NET_IF_CONNECTION_DEDICATED; + Attribs.IfType = IF_TYPE_ETHERNET_CSMACD; + Attribs.IfConnectorPresent = TRUE; + Attribs.SupportedStatistics = NDIS_STATISTICS_XMIT_OK_SUPPORTED | + NDIS_STATISTICS_XMIT_ERROR_SUPPORTED | + NDIS_STATISTICS_DIRECTED_BYTES_XMIT_SUPPORTED | + NDIS_STATISTICS_DIRECTED_FRAMES_XMIT_SUPPORTED | + NDIS_STATISTICS_MULTICAST_BYTES_XMIT_SUPPORTED | + NDIS_STATISTICS_MULTICAST_FRAMES_XMIT_SUPPORTED | + NDIS_STATISTICS_BROADCAST_BYTES_XMIT_SUPPORTED | + NDIS_STATISTICS_BROADCAST_FRAMES_XMIT_SUPPORTED | + NDIS_STATISTICS_RCV_OK_SUPPORTED | + NDIS_STATISTICS_RCV_ERROR_SUPPORTED | + NDIS_STATISTICS_DIRECTED_BYTES_RCV_SUPPORTED | + NDIS_STATISTICS_DIRECTED_FRAMES_RCV_SUPPORTED | + NDIS_STATISTICS_MULTICAST_BYTES_RCV_SUPPORTED | + NDIS_STATISTICS_MULTICAST_FRAMES_RCV_SUPPORTED | + NDIS_STATISTICS_BROADCAST_BYTES_RCV_SUPPORTED | + NDIS_STATISTICS_BROADCAST_FRAMES_RCV_SUPPORTED | + NDIS_STATISTICS_GEN_STATISTICS_SUPPORTED; - generalAttributes.SupportedOidList = XennetSupportedOids; - generalAttributes.SupportedOidListLength = sizeof(XennetSupportedOids); - adapterAttributes = - (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&generalAttributes; - + Attribs.SupportedOidList = XennetSupportedOids; + Attribs.SupportedOidListLength = sizeof(XennetSupportedOids); + ndisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle, - adapterAttributes); + (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs); return ndisStatus; } -#define DISPLAY_OFFLOAD(_Offload) \ - do { \ - if ((_Offload).Checksum.IPv4Receive.IpChecksum) \ - Info("Checksum.IPv4Receive.IpChecksum ON\n"); \ - else \ - Info("Checksum.IPv4Receive.IpChecksum OFF\n"); \ - \ - if ((_Offload).Checksum.IPv4Receive.TcpChecksum) \ - Info("Checksum.IPv4Receive.TcpChecksum ON\n"); \ - else \ - Info("Checksum.IPv4Receive.TcpChecksum OFF\n"); \ - \ - if ((_Offload).Checksum.IPv4Receive.UdpChecksum) \ - Info("Checksum.IPv4Receive.UdpChecksum ON\n"); \ - else \ - Info("Checksum.IPv4Receive.UdpChecksum OFF\n"); \ - \ - if ((_Offload).Checksum.IPv6Receive.TcpChecksum) \ - Info("Checksum.IPv6Receive.TcpChecksum ON\n"); \ - else \ - Info("Checksum.IPv6Receive.TcpChecksum OFF\n"); \ - \ - if ((_Offload).Checksum.IPv6Receive.UdpChecksum) \ - Info("Checksum.IPv6Receive.UdpChecksum ON\n"); \ - else \ - Info("Checksum.IPv6Receive.UdpChecksum OFF\n"); \ - \ - if ((_Offload).Checksum.IPv4Transmit.IpChecksum) \ - Info("Checksum.IPv4Transmit.IpChecksum ON\n"); \ - else \ - Info("Checksum.IPv4Transmit.IpChecksum OFF\n"); \ - \ - if ((_Offload).Checksum.IPv4Transmit.TcpChecksum) \ - Info("Checksum.IPv4Transmit.TcpChecksum ON\n"); \ - else \ - Info("Checksum.IPv4Transmit.TcpChecksum OFF\n"); \ - \ - if ((_Offload).Checksum.IPv4Transmit.UdpChecksum) \ - Info("Checksum.IPv4Transmit.UdpChecksum ON\n"); \ - else \ - Info("Checksum.IPv4Transmit.UdpChecksum OFF\n"); \ - \ - if ((_Offload).Checksum.IPv6Transmit.TcpChecksum) \ - Info("Checksum.IPv6Transmit.TcpChecksum ON\n"); \ - else \ - Info("Checksum.IPv6Transmit.TcpChecksum OFF\n"); \ - \ - if ((_Offload).Checksum.IPv6Transmit.UdpChecksum) \ - Info("Checksum.IPv6Transmit.UdpChecksum ON\n"); \ - else \ - Info("Checksum.IPv6Transmit.UdpChecksum OFF\n"); \ - \ - if ((_Offload).LsoV2.IPv4.MaxOffLoadSize != 0) \ - Info("LsoV2.IPv4.MaxOffLoadSize = %u\n", \ - (_Offload).LsoV2.IPv4.MaxOffLoadSize); \ - else \ - Info("LsoV2.IPv4 OFF\n"); \ - \ - if ((_Offload).LsoV2.IPv6.MaxOffLoadSize != 0) \ - Info("LsoV2.IPv6.MaxOffLoadSize = %u\n", \ - (_Offload).LsoV2.IPv6.MaxOffLoadSize); \ - else \ - Info("LsoV2.IPv6 OFF\n"); \ - } while (FALSE) - static NDIS_STATUS AdapterSetOffloadAttributes( - IN PADAPTER Adapter + IN PXENNET_ADAPTER Adapter ) { - PNDIS_MINIPORT_ADAPTER_ATTRIBUTES adapterAttributes; - NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES offloadAttributes; - XENVIF_VIF_OFFLOAD_OPTIONS Options; - NDIS_OFFLOAD current; - NDIS_OFFLOAD supported; - NDIS_STATUS ndisStatus; + NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES Attribs; + XENVIF_VIF_OFFLOAD_OPTIONS Options; + PXENVIF_VIF_OFFLOAD_OPTIONS RxOptions; + PXENVIF_VIF_OFFLOAD_OPTIONS TxOptions; + NDIS_OFFLOAD Default; + NDIS_OFFLOAD Supported; + NDIS_STATUS ndisStatus; + + TxOptions = TransmitterOffloadOptions(Adapter->Transmitter); + RxOptions = ReceiverOffloadOptions(Adapter->Receiver); - Adapter->Receiver.OffloadOptions.Value = 0; - Adapter->Receiver.OffloadOptions.OffloadTagManipulation = 1; + TxOptions->Value = 0; + TxOptions->OffloadTagManipulation = 1; + + RxOptions->Value = 0; + RxOptions->OffloadTagManipulation = 1; if (Adapter->Properties.need_csum_value) - Adapter->Receiver.OffloadOptions.NeedChecksumValue = 1; + RxOptions->NeedChecksumValue = 1; if (Adapter->Properties.lrov4) { - Adapter->Receiver.OffloadOptions.OffloadIpVersion4LargePacket = 1; - Adapter->Receiver.OffloadOptions.NeedLargePacketSplit = 1; + RxOptions->OffloadIpVersion4LargePacket = 1; + RxOptions->NeedLargePacketSplit = 1; } if (Adapter->Properties.lrov6) { - Adapter->Receiver.OffloadOptions.OffloadIpVersion6LargePacket = 1; - Adapter->Receiver.OffloadOptions.NeedLargePacketSplit = 1; + RxOptions->OffloadIpVersion6LargePacket = 1; + RxOptions->NeedLargePacketSplit = 1; } - Adapter->Transmitter->OffloadOptions.Value = 0; - Adapter->Transmitter->OffloadOptions.OffloadTagManipulation = 1; - - NdisZeroMemory(&offloadAttributes, sizeof(offloadAttributes)); - NdisZeroMemory(¤t, sizeof(current)); - NdisZeroMemory(&supported, sizeof(supported)); - XENVIF_VIF(ReceiverSetOffloadOptions, &Adapter->VifInterface, - Adapter->Receiver.OffloadOptions); + *RxOptions); - supported.Header.Type = NDIS_OBJECT_TYPE_OFFLOAD; - supported.Header.Revision = NDIS_OFFLOAD_REVISION_1; - supported.Header.Size = sizeof(supported); + XENVIF_VIF(TransmitterQueryOffloadOptions, + &Adapter->VifInterface, + &Options); - supported.Checksum.IPv4Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; + RtlZeroMemory(&Supported, sizeof(NDIS_OFFLOAD)); + Supported.Header.Type = NDIS_OBJECT_TYPE_OFFLOAD; + Supported.Header.Revision = NDIS_OFFLOAD_REVISION_1; + Supported.Header.Size = sizeof(NDIS_OFFLOAD); - supported.Checksum.IPv4Receive.IpChecksum = 1; - supported.Checksum.IPv4Receive.IpOptionsSupported = 1; + Supported.Checksum.IPv4Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; - supported.Checksum.IPv4Receive.TcpChecksum = 1; - supported.Checksum.IPv4Receive.TcpOptionsSupported = 1; + Supported.Checksum.IPv4Receive.IpChecksum = 1; + Supported.Checksum.IPv4Receive.IpOptionsSupported = 1; - supported.Checksum.IPv4Receive.UdpChecksum = 1; + Supported.Checksum.IPv4Receive.TcpChecksum = 1; + Supported.Checksum.IPv4Receive.TcpOptionsSupported = 1; - supported.Checksum.IPv6Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; + Supported.Checksum.IPv4Receive.UdpChecksum = 1; - supported.Checksum.IPv6Receive.IpExtensionHeadersSupported = 1; + Supported.Checksum.IPv6Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; - supported.Checksum.IPv6Receive.TcpChecksum = 1; - supported.Checksum.IPv6Receive.TcpOptionsSupported = 1; + Supported.Checksum.IPv6Receive.IpExtensionHeadersSupported = 1; - supported.Checksum.IPv6Receive.UdpChecksum = 1; + Supported.Checksum.IPv6Receive.TcpChecksum = 1; + Supported.Checksum.IPv6Receive.TcpOptionsSupported = 1; - XENVIF_VIF(TransmitterQueryOffloadOptions, - &Adapter->VifInterface, - &Options); + Supported.Checksum.IPv6Receive.UdpChecksum = 1; - supported.Checksum.IPv4Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; + Supported.Checksum.IPv4Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; if (Options.OffloadIpVersion4HeaderChecksum) { - supported.Checksum.IPv4Transmit.IpChecksum = 1; - supported.Checksum.IPv4Transmit.IpOptionsSupported = 1; + Supported.Checksum.IPv4Transmit.IpChecksum = 1; + Supported.Checksum.IPv4Transmit.IpOptionsSupported = 1; } if (Options.OffloadIpVersion4TcpChecksum) { - supported.Checksum.IPv4Transmit.TcpChecksum = 1; - supported.Checksum.IPv4Transmit.TcpOptionsSupported = 1; + Supported.Checksum.IPv4Transmit.TcpChecksum = 1; + Supported.Checksum.IPv4Transmit.TcpOptionsSupported = 1; } if (Options.OffloadIpVersion4UdpChecksum) - supported.Checksum.IPv4Transmit.UdpChecksum = 1; + Supported.Checksum.IPv4Transmit.UdpChecksum = 1; - supported.Checksum.IPv6Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; + Supported.Checksum.IPv6Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; - supported.Checksum.IPv6Transmit.IpExtensionHeadersSupported = 1; + Supported.Checksum.IPv6Transmit.IpExtensionHeadersSupported = 1; if (Options.OffloadIpVersion6TcpChecksum) { - supported.Checksum.IPv6Transmit.TcpChecksum = 1; - supported.Checksum.IPv6Transmit.TcpOptionsSupported = 1; + Supported.Checksum.IPv6Transmit.TcpChecksum = 1; + Supported.Checksum.IPv6Transmit.TcpOptionsSupported = 1; } if (Options.OffloadIpVersion6UdpChecksum) - supported.Checksum.IPv6Transmit.UdpChecksum = 1; + Supported.Checksum.IPv6Transmit.UdpChecksum = 1; if (Options.OffloadIpVersion4LargePacket) { - ULONG Size; - XENVIF_VIF(TransmitterQueryLargePacketSize, &Adapter->VifInterface, 4, - &Size); - - supported.LsoV2.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; - supported.LsoV2.IPv4.MaxOffLoadSize = Size; - supported.LsoV2.IPv4.MinSegmentCount = 2; + &Supported.LsoV2.IPv4.MaxOffLoadSize); + Supported.LsoV2.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; + Supported.LsoV2.IPv4.MinSegmentCount = 2; } if (Options.OffloadIpVersion6LargePacket) { - ULONG Size; - XENVIF_VIF(TransmitterQueryLargePacketSize, &Adapter->VifInterface, 6, - &Size); - - supported.LsoV2.IPv6.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; - supported.LsoV2.IPv6.MaxOffLoadSize = Size; - supported.LsoV2.IPv6.MinSegmentCount = 2; - supported.LsoV2.IPv6.IpExtensionHeadersSupported = 1; - supported.LsoV2.IPv6.TcpOptionsSupported = 1; + &Supported.LsoV2.IPv6.MaxOffLoadSize); + Supported.LsoV2.IPv6.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; + Supported.LsoV2.IPv6.MinSegmentCount = 2; + Supported.LsoV2.IPv6.IpExtensionHeadersSupported = 1; + Supported.LsoV2.IPv6.TcpOptionsSupported = 1; } - current = supported; + Default = Supported; if (!(Adapter->Properties.ipv4_csum & 2)) - current.Checksum.IPv4Receive.IpChecksum = 0; + Default.Checksum.IPv4Receive.IpChecksum = 0; if (!(Adapter->Properties.tcpv4_csum & 2)) - current.Checksum.IPv4Receive.TcpChecksum = 0; + Default.Checksum.IPv4Receive.TcpChecksum = 0; if (!(Adapter->Properties.udpv4_csum & 2)) - current.Checksum.IPv4Receive.UdpChecksum = 0; + Default.Checksum.IPv4Receive.UdpChecksum = 0; if (!(Adapter->Properties.tcpv6_csum & 2)) - current.Checksum.IPv6Receive.TcpChecksum = 0; + Default.Checksum.IPv6Receive.TcpChecksum = 0; if (!(Adapter->Properties.udpv6_csum & 2)) - current.Checksum.IPv6Receive.UdpChecksum = 0; + Default.Checksum.IPv6Receive.UdpChecksum = 0; if (!(Adapter->Properties.ipv4_csum & 1)) - current.Checksum.IPv4Transmit.IpChecksum = 0; + Default.Checksum.IPv4Transmit.IpChecksum = 0; if (!(Adapter->Properties.tcpv4_csum & 1)) - current.Checksum.IPv4Transmit.TcpChecksum = 0; + Default.Checksum.IPv4Transmit.TcpChecksum = 0; if (!(Adapter->Properties.udpv4_csum & 1)) - current.Checksum.IPv4Transmit.UdpChecksum = 0; + Default.Checksum.IPv4Transmit.UdpChecksum = 0; if (!(Adapter->Properties.tcpv6_csum & 1)) - current.Checksum.IPv6Transmit.TcpChecksum = 0; + Default.Checksum.IPv6Transmit.TcpChecksum = 0; if (!(Adapter->Properties.udpv6_csum & 1)) - current.Checksum.IPv6Transmit.UdpChecksum = 0; + Default.Checksum.IPv6Transmit.UdpChecksum = 0; if (!(Adapter->Properties.lsov4)) { - current.LsoV2.IPv4.MaxOffLoadSize = 0; - current.LsoV2.IPv4.MinSegmentCount = 0; + Default.LsoV2.IPv4.MaxOffLoadSize = 0; + Default.LsoV2.IPv4.MinSegmentCount = 0; } if (!(Adapter->Properties.lsov6)) { - current.LsoV2.IPv6.MaxOffLoadSize = 0; - current.LsoV2.IPv6.MinSegmentCount = 0; + Default.LsoV2.IPv6.MaxOffLoadSize = 0; + Default.LsoV2.IPv6.MinSegmentCount = 0; } - if (!RtlEqualMemory(&Adapter->Offload, ¤t, sizeof (NDIS_OFFLOAD))) { - Adapter->Offload = current; - - DISPLAY_OFFLOAD(current); + if (!RtlEqualMemory(&Adapter->Offload, &Default, sizeof (NDIS_OFFLOAD))) { + Adapter->Offload = Default; + //DISPLAY_OFFLOAD(Default); } - offloadAttributes.Header.Type = - NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES; - offloadAttributes.Header.Revision = - NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES_REVISION_1; - offloadAttributes.Header.Size = sizeof(offloadAttributes); - offloadAttributes.DefaultOffloadConfiguration = ¤t; - offloadAttributes.HardwareOffloadCapabilities = &supported; + RtlZeroMemory(&Attribs, sizeof(NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES)); + Attribs.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES; + Attribs.Header.Revision = NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES_REVISION_1; + Attribs.Header.Size = sizeof(Attribs); + Attribs.DefaultOffloadConfiguration = &Default; + Attribs.HardwareOffloadCapabilities = &Supported; - adapterAttributes = - (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&offloadAttributes; ndisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle, - adapterAttributes); - + (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs); return ndisStatus; } -static void -AdapterIndicateOffloadChanged ( - IN PADAPTER Adapter +NDIS_STATUS +AdapterInitialize( + IN NDIS_HANDLE Handle, + OUT PXENNET_ADAPTER *Adapter ) { - NDIS_STATUS_INDICATION indication; - NDIS_OFFLOAD offload; - - NdisZeroMemory(&offload, sizeof(offload)); - INITIALIZE_NDIS_OBJ_HEADER(offload, OFFLOAD); - - offload.Checksum.IPv4Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; - - if (Adapter->Receiver.OffloadOptions.OffloadIpVersion4HeaderChecksum) { - offload.Checksum.IPv4Receive.IpChecksum = 1; - offload.Checksum.IPv4Receive.IpOptionsSupported = 1; - } - - if (Adapter->Receiver.OffloadOptions.OffloadIpVersion4TcpChecksum) { - offload.Checksum.IPv4Receive.TcpChecksum = 1; - offload.Checksum.IPv4Receive.TcpOptionsSupported = 1; - } - - if (Adapter->Receiver.OffloadOptions.OffloadIpVersion4UdpChecksum) { - offload.Checksum.IPv4Receive.UdpChecksum = 1; - } - - offload.Checksum.IPv6Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; - - offload.Checksum.IPv6Receive.IpExtensionHeadersSupported = 1; - - if (Adapter->Receiver.OffloadOptions.OffloadIpVersion6TcpChecksum) { - offload.Checksum.IPv6Receive.TcpChecksum = 1; - offload.Checksum.IPv6Receive.TcpOptionsSupported = 1; - } - - if (Adapter->Receiver.OffloadOptions.OffloadIpVersion6UdpChecksum) { - offload.Checksum.IPv6Receive.UdpChecksum = 1; - } + NDIS_STATUS ndisStatus; + NTSTATUS status; + PDEVICE_OBJECT DeviceObject; + NDIS_SG_DMA_DESCRIPTION Dma; - XENVIF_VIF(ReceiverSetOffloadOptions, - &Adapter->VifInterface, - Adapter->Receiver.OffloadOptions); - - offload.Checksum.IPv4Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; - - if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion4HeaderChecksum) { - offload.Checksum.IPv4Transmit.IpChecksum = 1; - offload.Checksum.IPv4Transmit.IpOptionsSupported = 1; - } - - if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion4TcpChecksum) { - offload.Checksum.IPv4Transmit.TcpChecksum = 1; - offload.Checksum.IPv4Transmit.TcpOptionsSupported = 1; - } - - if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion4UdpChecksum) { - offload.Checksum.IPv4Transmit.UdpChecksum = 1; - } - - offload.Checksum.IPv6Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; - - offload.Checksum.IPv6Transmit.IpExtensionHeadersSupported = 1; - - if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion6TcpChecksum) { - offload.Checksum.IPv6Transmit.TcpChecksum = 1; - offload.Checksum.IPv6Transmit.TcpOptionsSupported = 1; - } - - if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion6UdpChecksum) { - offload.Checksum.IPv6Transmit.UdpChecksum = 1; - } - - if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion4LargePacket) { - ULONG Size; - - XENVIF_VIF(TransmitterQueryLargePacketSize, - &Adapter->VifInterface, - 4, - &Size); - - offload.LsoV2.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; - offload.LsoV2.IPv4.MaxOffLoadSize = Size; - offload.LsoV2.IPv4.MinSegmentCount = 2; - } - - if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion6LargePacket) { - ULONG Size; - - XENVIF_VIF(TransmitterQueryLargePacketSize, - &Adapter->VifInterface, - 6, - &Size); - - offload.LsoV2.IPv6.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; - offload.LsoV2.IPv6.MaxOffLoadSize = Size; - offload.LsoV2.IPv6.MinSegmentCount = 2; - offload.LsoV2.IPv6.IpExtensionHeadersSupported = 1; - offload.LsoV2.IPv6.TcpOptionsSupported = 1; - } - - if (!RtlEqualMemory(&Adapter->Offload, &offload, sizeof (NDIS_OFFLOAD))) { - Adapter->Offload = offload; - - DISPLAY_OFFLOAD(offload); - } + *Adapter = ExAllocatePoolWithTag(NonPagedPool, + sizeof(XENNET_ADAPTER), + ADAPTER_POOL_TAG); - NdisZeroMemory(&indication, sizeof(indication)); - INITIALIZE_NDIS_OBJ_HEADER(indication, STATUS_INDICATION); - indication.SourceHandle = Adapter->NdisAdapterHandle; - indication.StatusCode = NDIS_STATUS_TASK_OFFLOAD_CURRENT_CONFIG; - indication.StatusBuffer = &offload; - indication.StatusBufferSize = sizeof(offload); + ndisStatus = NDIS_STATUS_RESOURCES; + if (*Adapter == NULL) + goto fail1; - NdisMIndicateStatusEx(Adapter->NdisAdapterHandle, &indication); + RtlZeroMemory(*Adapter, sizeof (XENNET_ADAPTER)); -} + NdisMGetDeviceProperty(Handle, + &DeviceObject, + NULL, + NULL, + NULL, + NULL); -static NDIS_STATUS -SetMulticastAddresses(PADAPTER Adapter, PETHERNET_ADDRESS Address, ULONG Count) -{ - NTSTATUS status; + status = __QueryInterface(DeviceObject, + &GUID_XENVIF_VIF_INTERFACE, + XENVIF_VIF_INTERFACE_VERSION_MAX, + (PINTERFACE)&(*Adapter)->VifInterface, + sizeof(XENVIF_VIF_INTERFACE), + FALSE); - status = XENVIF_VIF(MacSetMulticastAddresses, - &Adapter->VifInterface, - Address, - Count); + ndisStatus = NDIS_STATUS_FAILURE; if (!NT_SUCCESS(status)) - return NDIS_STATUS_INVALID_DATA; - - return NDIS_STATUS_SUCCESS; -} - -static NDIS_STATUS -SetPacketFilter(PADAPTER Adapter, PULONG PacketFilter) -{ - XENVIF_MAC_FILTER_LEVEL UnicastFilterLevel; - XENVIF_MAC_FILTER_LEVEL MulticastFilterLevel; - XENVIF_MAC_FILTER_LEVEL BroadcastFilterLevel; - - if (*PacketFilter & ~XENNET_SUPPORTED_PACKET_FILTERS) - return NDIS_STATUS_INVALID_PARAMETER; + goto fail2; - if (*PacketFilter & NDIS_PACKET_TYPE_PROMISCUOUS) { - UnicastFilterLevel = XENVIF_MAC_FILTER_ALL; - MulticastFilterLevel = XENVIF_MAC_FILTER_ALL; - BroadcastFilterLevel = XENVIF_MAC_FILTER_ALL; - goto done; - } + status = XENVIF_VIF(Acquire, + &(*Adapter)->VifInterface); + if (!NT_SUCCESS(status)) + goto fail3; - if (*PacketFilter & NDIS_PACKET_TYPE_DIRECTED) - UnicastFilterLevel = XENVIF_MAC_FILTER_MATCHING; - else - UnicastFilterLevel = XENVIF_MAC_FILTER_NONE; + (*Adapter)->NdisAdapterHandle = Handle; - if (*PacketFilter & NDIS_PACKET_TYPE_ALL_MULTICAST) - MulticastFilterLevel = XENVIF_MAC_FILTER_ALL; - else if (*PacketFilter & NDIS_PACKET_TYPE_MULTICAST) - MulticastFilterLevel = XENVIF_MAC_FILTER_MATCHING; - else - MulticastFilterLevel = XENVIF_MAC_FILTER_NONE; + ndisStatus = TransmitterInitialize(*Adapter, &(*Adapter)->Transmitter); + if (ndisStatus != NDIS_STATUS_SUCCESS) + goto fail4; - if (*PacketFilter & NDIS_PACKET_TYPE_BROADCAST) - BroadcastFilterLevel = XENVIF_MAC_FILTER_ALL; - else - BroadcastFilterLevel = XENVIF_MAC_FILTER_NONE; + ndisStatus = ReceiverInitialize(*Adapter, &(*Adapter)->Receiver); + if (ndisStatus != NDIS_STATUS_SUCCESS) + goto fail5; -done: - XENVIF_VIF(MacSetFilterLevel, - &Adapter->VifInterface, - ETHERNET_ADDRESS_UNICAST, - UnicastFilterLevel); + ndisStatus = AdapterGetAdvancedSettings(*Adapter); + if (ndisStatus != NDIS_STATUS_SUCCESS) + goto fail6; + + ndisStatus = AdapterSetRegistrationAttributes(*Adapter); + if (ndisStatus != NDIS_STATUS_SUCCESS) + goto fail7; + + ndisStatus = AdapterSetGeneralAttributes(*Adapter); + if (ndisStatus != NDIS_STATUS_SUCCESS) + goto fail8; - XENVIF_VIF(MacSetFilterLevel, - &Adapter->VifInterface, - ETHERNET_ADDRESS_MULTICAST, - MulticastFilterLevel); + ndisStatus = AdapterSetOffloadAttributes(*Adapter); + if (ndisStatus != NDIS_STATUS_SUCCESS) + goto fail9; + + RtlZeroMemory(&Dma, sizeof(NDIS_SG_DMA_DESCRIPTION)); + Dma.Header.Type = NDIS_OBJECT_TYPE_SG_DMA_DESCRIPTION; + Dma.Header.Revision = NDIS_SG_DMA_DESCRIPTION_REVISION_1; + Dma.Header.Size = sizeof(NDIS_SG_DMA_DESCRIPTION); + Dma.Flags = NDIS_SG_DMA_64_BIT_ADDRESS; + Dma.MaximumPhysicalMapping = 65536; + Dma.ProcessSGListHandler = AdapterProcessSGList; + Dma.SharedMemAllocateCompleteHandler = AdapterAllocateComplete; + + ndisStatus = NdisMRegisterScatterGatherDma((*Adapter)->NdisAdapterHandle, + &Dma, + &(*Adapter)->NdisDmaHandle); + if (ndisStatus != NDIS_STATUS_SUCCESS) + (*Adapter)->NdisDmaHandle = NULL; - XENVIF_VIF(MacSetFilterLevel, - &Adapter->VifInterface, - ETHERNET_ADDRESS_BROADCAST, - BroadcastFilterLevel); + ndisStatus = AdapterEnable(*Adapter); + if (ndisStatus != NDIS_STATUS_SUCCESS) + goto fail10; return NDIS_STATUS_SUCCESS; -} - -// -// Set OID handler. -// -static NDIS_STATUS -AdapterSetInformation ( - IN PADAPTER Adapter, - IN PNDIS_OID_REQUEST NdisRequest - ) -{ - ULONG addressCount; - ULONG bytesNeeded = 0; - ULONG bytesRead = 0; - PVOID informationBuffer; - ULONG informationBufferLength; - NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS; - NDIS_OID oid; - BOOLEAN offloadChanged; - - informationBuffer = NdisRequest->DATA.SET_INFORMATION.InformationBuffer; - informationBufferLength = NdisRequest->DATA.SET_INFORMATION.InformationBufferLength; - oid = NdisRequest->DATA.QUERY_INFORMATION.Oid; - switch (oid) { - case OID_PNP_SET_POWER: - bytesNeeded = sizeof(NDIS_DEVICE_POWER_STATE); - if (informationBufferLength >= bytesNeeded) { - PNDIS_DEVICE_POWER_STATE state; - - state = (PNDIS_DEVICE_POWER_STATE)informationBuffer; - switch (*state) { - case NdisDeviceStateD0: - Info("SET_POWER: D0\n"); - break; - - case NdisDeviceStateD1: - Info("SET_POWER: D1\n"); - break; - - case NdisDeviceStateD2: - Info("SET_POWER: D2\n"); - break; - - case NdisDeviceStateD3: - Info("SET_POWER: D3\n"); - break; - } - } - break; - - case OID_GEN_MACHINE_NAME: - ndisStatus = NDIS_STATUS_NOT_SUPPORTED; - break; - - case OID_GEN_CURRENT_LOOKAHEAD: - bytesNeeded = sizeof(ULONG); - Adapter->CurrentLookahead = Adapter->MaximumFrameSize; - if (informationBufferLength == sizeof(ULONG)) { - Adapter->CurrentLookahead = *(PULONG)informationBuffer; - bytesRead = sizeof(ULONG); - } - - break; - - case OID_GEN_CURRENT_PACKET_FILTER: - bytesNeeded = sizeof(ULONG); - if (informationBufferLength == sizeof(ULONG)) { - ndisStatus = SetPacketFilter(Adapter, (PULONG)informationBuffer); - bytesRead = sizeof(ULONG); - } - - break; - - case OID_802_3_MULTICAST_LIST: - bytesNeeded = ETHERNET_ADDRESS_LENGTH; - if (informationBufferLength % ETHERNET_ADDRESS_LENGTH == 0) { - addressCount = informationBufferLength / ETHERNET_ADDRESS_LENGTH; - - ndisStatus = SetMulticastAddresses(Adapter, informationBuffer, addressCount); - if (ndisStatus == NDIS_STATUS_SUCCESS) - bytesRead = informationBufferLength; - } else { - ndisStatus = NDIS_STATUS_INVALID_LENGTH; - } - - break; - - case OID_GEN_INTERRUPT_MODERATION: - ndisStatus = NDIS_STATUS_INVALID_DATA; - break; - - case OID_OFFLOAD_ENCAPSULATION: { - PNDIS_OFFLOAD_ENCAPSULATION offloadEncapsulation; - - bytesNeeded = sizeof(*offloadEncapsulation); - if (informationBufferLength >= bytesNeeded) { - XENVIF_VIF_OFFLOAD_OPTIONS Options; - - bytesRead = bytesNeeded; - offloadEncapsulation = informationBuffer; - ndisStatus = NDIS_STATUS_SUCCESS; - - if (offloadEncapsulation->IPv4.Enabled == NDIS_OFFLOAD_SET_ON) { - if (offloadEncapsulation->IPv4.EncapsulationType != NDIS_ENCAPSULATION_IEEE_802_3) - ndisStatus = NDIS_STATUS_INVALID_PARAMETER; - } - - if (offloadEncapsulation->IPv6.Enabled == NDIS_OFFLOAD_SET_ON) { - if (offloadEncapsulation->IPv6.EncapsulationType != NDIS_ENCAPSULATION_IEEE_802_3) - ndisStatus = NDIS_STATUS_INVALID_PARAMETER; - } - - XENVIF_VIF(TransmitterQueryOffloadOptions, - &Adapter->VifInterface, - &Options); - - Adapter->Transmitter->OffloadOptions.Value = 0; - Adapter->Transmitter->OffloadOptions.OffloadTagManipulation = 1; - - if ((Adapter->Properties.lsov4) && (Options.OffloadIpVersion4LargePacket)) - Adapter->Transmitter->OffloadOptions.OffloadIpVersion4LargePacket = 1; - - if ((Adapter->Properties.lsov6) && (Options.OffloadIpVersion6LargePacket)) - Adapter->Transmitter->OffloadOptions.OffloadIpVersion6LargePacket = 1; - - if ((Adapter->Properties.ipv4_csum & 1) && Options.OffloadIpVersion4HeaderChecksum) - Adapter->Transmitter->OffloadOptions.OffloadIpVersion4HeaderChecksum = 1; - - if ((Adapter->Properties.tcpv4_csum & 1) && Options.OffloadIpVersion4TcpChecksum) - Adapter->Transmitter->OffloadOptions.OffloadIpVersion4TcpChecksum = 1; - - if ((Adapter->Properties.udpv4_csum & 1) && Options.OffloadIpVersion4UdpChecksum) - Adapter->Transmitter->OffloadOptions.OffloadIpVersion4UdpChecksum = 1; - - if ((Adapter->Properties.tcpv6_csum & 1) && Options.OffloadIpVersion6TcpChecksum) - Adapter->Transmitter->OffloadOptions.OffloadIpVersion6TcpChecksum = 1; - - if ((Adapter->Properties.udpv6_csum & 1) && Options.OffloadIpVersion6UdpChecksum) - Adapter->Transmitter->OffloadOptions.OffloadIpVersion6UdpChecksum = 1; - - Adapter->Receiver.OffloadOptions.Value = 0; - Adapter->Receiver.OffloadOptions.OffloadTagManipulation = 1; - - if (Adapter->Properties.need_csum_value) - Adapter->Receiver.OffloadOptions.NeedChecksumValue = 1; - - if (Adapter->Properties.lrov4) { - Adapter->Receiver.OffloadOptions.OffloadIpVersion4LargePacket = 1; - Adapter->Receiver.OffloadOptions.NeedLargePacketSplit = 1; - } - - if (Adapter->Properties.lrov6) { - Adapter->Receiver.OffloadOptions.OffloadIpVersion6LargePacket = 1; - Adapter->Receiver.OffloadOptions.NeedLargePacketSplit = 1; - } - - if (Adapter->Properties.ipv4_csum & 2) - Adapter->Receiver.OffloadOptions.OffloadIpVersion4HeaderChecksum = 1; - - if (Adapter->Properties.tcpv4_csum & 2) - Adapter->Receiver.OffloadOptions.OffloadIpVersion4TcpChecksum = 1; - - if (Adapter->Properties.udpv4_csum & 2) - Adapter->Receiver.OffloadOptions.OffloadIpVersion4UdpChecksum = 1; - - if (Adapter->Properties.tcpv6_csum & 2) - Adapter->Receiver.OffloadOptions.OffloadIpVersion6TcpChecksum = 1; - - if (Adapter->Properties.udpv6_csum & 2) - Adapter->Receiver.OffloadOptions.OffloadIpVersion6UdpChecksum = 1; - - AdapterIndicateOffloadChanged(Adapter); - } - break; - } - case OID_TCP_OFFLOAD_PARAMETERS: { - PNDIS_OFFLOAD_PARAMETERS offloadParameters; - - bytesNeeded = sizeof(*offloadParameters); - if (informationBufferLength >= bytesNeeded) { - bytesRead = bytesNeeded; - offloadParameters = informationBuffer; - ndisStatus = NDIS_STATUS_SUCCESS; - -#define no_change(x) ((x) == NDIS_OFFLOAD_PARAMETERS_NO_CHANGE) - - if (!no_change(offloadParameters->IPsecV1)) - ndisStatus = NDIS_STATUS_INVALID_PARAMETER; - - if (!no_change(offloadParameters->LsoV1)) - ndisStatus = NDIS_STATUS_INVALID_PARAMETER; - - if (!no_change(offloadParameters->TcpConnectionIPv4)) - ndisStatus = NDIS_STATUS_INVALID_PARAMETER; - - if (!no_change(offloadParameters->TcpConnectionIPv6)) - ndisStatus = NDIS_STATUS_INVALID_PARAMETER; - - if (!no_change(offloadParameters->LsoV2IPv4)) { - XENVIF_VIF_OFFLOAD_OPTIONS Options; - - XENVIF_VIF(TransmitterQueryOffloadOptions, - &Adapter->VifInterface, - &Options); - - if (!(Options.OffloadIpVersion4LargePacket)) - ndisStatus = NDIS_STATUS_INVALID_PARAMETER; - } - - if (!no_change(offloadParameters->LsoV2IPv6)) { - XENVIF_VIF_OFFLOAD_OPTIONS Options; - - XENVIF_VIF(TransmitterQueryOffloadOptions, - &Adapter->VifInterface, - &Options); - - if (!(Options.OffloadIpVersion6LargePacket)) - ndisStatus = NDIS_STATUS_INVALID_PARAMETER; - } - -#define rx_enabled(x) ((x) == NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED || \ - (x) == NDIS_OFFLOAD_PARAMETERS_RX_ENABLED_TX_DISABLED) -#define tx_enabled(x) ((x) == NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED || \ - (x) == NDIS_OFFLOAD_PARAMETERS_TX_ENABLED_RX_DISABLED) - - if (ndisStatus == NDIS_STATUS_SUCCESS) { - offloadChanged = FALSE; - - if (offloadParameters->LsoV2IPv4 == NDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED) { - if (!Adapter->Transmitter->OffloadOptions.OffloadIpVersion4LargePacket) { - Adapter->Transmitter->OffloadOptions.OffloadIpVersion4LargePacket = 1; - offloadChanged = TRUE; - } - } else if (offloadParameters->LsoV2IPv4 == NDIS_OFFLOAD_PARAMETERS_LSOV2_DISABLED) { - if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion4LargePacket) { - Adapter->Transmitter->OffloadOptions.OffloadIpVersion4LargePacket = 0; - offloadChanged = TRUE; - } - } - - if (offloadParameters->LsoV2IPv6 == NDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED) { - if (!Adapter->Transmitter->OffloadOptions.OffloadIpVersion6LargePacket) { - Adapter->Transmitter->OffloadOptions.OffloadIpVersion6LargePacket = 1; - offloadChanged = TRUE; - } - } else if (offloadParameters->LsoV2IPv6 == NDIS_OFFLOAD_PARAMETERS_LSOV2_DISABLED) { - if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion6LargePacket) { - Adapter->Transmitter->OffloadOptions.OffloadIpVersion6LargePacket = 0; - offloadChanged = TRUE; - } - } - - if (tx_enabled(offloadParameters->IPv4Checksum)) { - if (!Adapter->Transmitter->OffloadOptions.OffloadIpVersion4HeaderChecksum) { - Adapter->Transmitter->OffloadOptions.OffloadIpVersion4HeaderChecksum = 1; - offloadChanged = TRUE; - } - } else { - if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion4HeaderChecksum) { - Adapter->Transmitter->OffloadOptions.OffloadIpVersion4HeaderChecksum = 0; - offloadChanged = TRUE; - } - } - - if (tx_enabled(offloadParameters->TCPIPv4Checksum)) { - if (!Adapter->Transmitter->OffloadOptions.OffloadIpVersion4TcpChecksum) { - Adapter->Transmitter->OffloadOptions.OffloadIpVersion4TcpChecksum = 1; - offloadChanged = TRUE; - } - } else { - if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion4TcpChecksum) { - Adapter->Transmitter->OffloadOptions.OffloadIpVersion4TcpChecksum = 0; - offloadChanged = TRUE; - } - } - - if (tx_enabled(offloadParameters->UDPIPv4Checksum)) { - if (!Adapter->Transmitter->OffloadOptions.OffloadIpVersion4UdpChecksum) { - Adapter->Transmitter->OffloadOptions.OffloadIpVersion4UdpChecksum = 1; - offloadChanged = TRUE; - } - } else { - if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion4UdpChecksum) { - Adapter->Transmitter->OffloadOptions.OffloadIpVersion4UdpChecksum = 0; - offloadChanged = TRUE; - } - } - - if (tx_enabled(offloadParameters->TCPIPv6Checksum)) { - if (!Adapter->Transmitter->OffloadOptions.OffloadIpVersion6TcpChecksum) { - Adapter->Transmitter->OffloadOptions.OffloadIpVersion6TcpChecksum = 1; - offloadChanged = TRUE; - } - } else { - if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion6TcpChecksum) { - Adapter->Transmitter->OffloadOptions.OffloadIpVersion6TcpChecksum = 0; - offloadChanged = TRUE; - } - } - - if (tx_enabled(offloadParameters->UDPIPv6Checksum)) { - if (!Adapter->Transmitter->OffloadOptions.OffloadIpVersion6UdpChecksum) { - Adapter->Transmitter->OffloadOptions.OffloadIpVersion6UdpChecksum = 1; - offloadChanged = TRUE; - } - } else { - if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion6UdpChecksum) { - Adapter->Transmitter->OffloadOptions.OffloadIpVersion6UdpChecksum = 0; - offloadChanged = TRUE; - } - } - - if (rx_enabled(offloadParameters->IPv4Checksum)) { - if (!Adapter->Receiver.OffloadOptions.OffloadIpVersion4HeaderChecksum) { - Adapter->Receiver.OffloadOptions.OffloadIpVersion4HeaderChecksum = 1; - offloadChanged = TRUE; - } - } else { - if (Adapter->Receiver.OffloadOptions.OffloadIpVersion4HeaderChecksum) { - Adapter->Receiver.OffloadOptions.OffloadIpVersion4HeaderChecksum = 0; - offloadChanged = TRUE; - } - } - - if (rx_enabled(offloadParameters->TCPIPv4Checksum)) { - if (!Adapter->Receiver.OffloadOptions.OffloadIpVersion4TcpChecksum) { - Adapter->Receiver.OffloadOptions.OffloadIpVersion4TcpChecksum = 1; - offloadChanged = TRUE; - } - } else { - if (Adapter->Receiver.OffloadOptions.OffloadIpVersion4TcpChecksum) { - Adapter->Receiver.OffloadOptions.OffloadIpVersion4TcpChecksum = 0; - offloadChanged = TRUE; - } - } - - if (rx_enabled(offloadParameters->UDPIPv4Checksum)) { - if (!Adapter->Receiver.OffloadOptions.OffloadIpVersion4UdpChecksum) { - Adapter->Receiver.OffloadOptions.OffloadIpVersion4UdpChecksum = 1; - offloadChanged = TRUE; - } - } else { - if (Adapter->Receiver.OffloadOptions.OffloadIpVersion4UdpChecksum) { - Adapter->Receiver.OffloadOptions.OffloadIpVersion4UdpChecksum = 0; - offloadChanged = TRUE; - } - } - - if (rx_enabled(offloadParameters->TCPIPv6Checksum)) { - if (!Adapter->Receiver.OffloadOptions.OffloadIpVersion6TcpChecksum) { - Adapter->Receiver.OffloadOptions.OffloadIpVersion6TcpChecksum = 1; - offloadChanged = TRUE; - } - } else { - if (Adapter->Receiver.OffloadOptions.OffloadIpVersion6TcpChecksum) { - Adapter->Receiver.OffloadOptions.OffloadIpVersion6TcpChecksum = 0; - offloadChanged = TRUE; - } - } - - if (rx_enabled(offloadParameters->UDPIPv6Checksum)) { - if (!Adapter->Receiver.OffloadOptions.OffloadIpVersion6UdpChecksum) { - Adapter->Receiver.OffloadOptions.OffloadIpVersion6UdpChecksum = 1; - offloadChanged = TRUE; - } - } else { - if (Adapter->Receiver.OffloadOptions.OffloadIpVersion6UdpChecksum) { - Adapter->Receiver.OffloadOptions.OffloadIpVersion6UdpChecksum = 0; - offloadChanged = TRUE; - } - } - -#undef tx_enabled -#undef rx_enabled -#undef no_change - - if (offloadChanged) - AdapterIndicateOffloadChanged(Adapter); - } - } else { - ndisStatus = NDIS_STATUS_INVALID_LENGTH; - } - break; - } - default: - ndisStatus = NDIS_STATUS_NOT_SUPPORTED; - break; - }; - - NdisRequest->DATA.SET_INFORMATION.BytesNeeded = bytesNeeded; - if (ndisStatus == NDIS_STATUS_SUCCESS) { - NdisRequest->DATA.SET_INFORMATION.BytesRead = bytesRead; - } - - return ndisStatus; -} - -// -// Sets miniport registration attributes. -// -static NDIS_STATUS -AdapterSetRegistrationAttributes ( - IN PADAPTER Adapter - ) -{ - PNDIS_MINIPORT_ADAPTER_ATTRIBUTES adapterAttributes; - NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES registrationAttributes; - NDIS_STATUS ndisStatus; - - - NdisZeroMemory(®istrationAttributes, - sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES)); - - registrationAttributes.Header.Type = - NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES; - - registrationAttributes.Header.Revision = - NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1; - - registrationAttributes.Header.Size = - sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES); - - registrationAttributes.MiniportAdapterContext = (NDIS_HANDLE)Adapter; - registrationAttributes.AttributeFlags = NDIS_MINIPORT_ATTRIBUTES_BUS_MASTER | - NDIS_MINIPORT_ATTRIBUTES_NO_HALT_ON_SUSPEND; - - registrationAttributes.CheckForHangTimeInSeconds = 0; - registrationAttributes.InterfaceType = XENNET_INTERFACE_TYPE; - - adapterAttributes = - (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)®istrationAttributes; - - ndisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle, - adapterAttributes); +fail10: + if ((*Adapter)->NdisDmaHandle) + NdisMDeregisterScatterGatherDma((*Adapter)->NdisDmaHandle); + (*Adapter)->NdisDmaHandle = NULL; +fail9: +fail8: +fail7: +fail6: + ReceiverTeardown((*Adapter)->Receiver); + (*Adapter)->Receiver = NULL; +fail5: + TransmitterTeardown((*Adapter)->Transmitter); + (*Adapter)->Transmitter = NULL; +fail4: + (*Adapter)->NdisAdapterHandle = NULL; + + XENVIF_VIF(Release, &(*Adapter)->VifInterface); +fail3: + RtlZeroMemory(&(*Adapter)->VifInterface, sizeof(XENVIF_VIF_INTERFACE)); +fail2: + ExFreePoolWithTag(*Adapter, ADAPTER_POOL_TAG); +fail1: return ndisStatus; } -// -// Shuts down adapter. -// -VOID -AdapterShutdown ( - IN NDIS_HANDLE MiniportAdapterContext, - IN NDIS_SHUTDOWN_ACTION ShutdownAction +VOID +AdapterTeardown( + IN PXENNET_ADAPTER Adapter ) { - PADAPTER Adapter = (PADAPTER)MiniportAdapterContext; - - UNREFERENCED_PARAMETER(ShutdownAction); - - if (ShutdownAction != NdisShutdownBugCheck) - AdapterStop(Adapter); - - return; -} - -// -// Stops adapter. Waits for currently transmitted packets to complete. -// Stops transmission of new packets. -// Stops received packet indication to NDIS. -// -NDIS_STATUS -AdapterStop ( -IN PADAPTER Adapter -) -{ - Trace("====>\n"); + TransmitterTeardown(Adapter->Transmitter); + Adapter->Transmitter = NULL; - if (!Adapter->Enabled) - goto done; + ReceiverTeardown(Adapter->Receiver); + Adapter->Receiver = NULL; - XENVIF_VIF(Disable, - &Adapter->VifInterface); + if (Adapter->NdisDmaHandle != NULL) + NdisMDeregisterScatterGatherDma(Adapter->NdisDmaHandle); + Adapter->NdisDmaHandle = NULL; - Adapter->Enabled = FALSE; + XENVIF_VIF(Release, &Adapter->VifInterface); + RtlZeroMemory(&Adapter->VifInterface, sizeof(XENVIF_VIF_INTERFACE)); -done: - Trace("<====\n"); - return NDIS_STATUS_SUCCESS; + ExFreePoolWithTag(Adapter, ADAPTER_POOL_TAG); } diff --git a/src/xennet/adapter.h b/src/xennet/adapter.h index e64e40d..6c60aad 100644 --- a/src/xennet/adapter.h +++ b/src/xennet/adapter.h @@ -29,7 +29,10 @@ * SUCH DAMAGE. */ -#pragma once +#ifndef _XENNET_ADAPTER_H_ +#define _XENNET_ADAPTER_H_ + +#include <ndis.h> #define XENNET_INTERFACE_TYPE NdisInterfaceInternal @@ -41,6 +44,14 @@ NDIS_MAC_OPTION_8021P_PRIORITY | \ NDIS_MAC_OPTION_SUPPORTS_MAC_ADDRESS_OVERWRITE) +#define XENNET_MEDIA_MAX_SPEED 1000000000ull + +#define XENNET_SUPPORTED_PACKET_FILTERS (NDIS_PACKET_TYPE_DIRECTED | \ + NDIS_PACKET_TYPE_MULTICAST | \ + NDIS_PACKET_TYPE_ALL_MULTICAST | \ + NDIS_PACKET_TYPE_BROADCAST | \ + NDIS_PACKET_TYPE_PROMISCUOUS) + typedef struct _PROPERTIES { int ipv4_csum; int tcpv4_csum; @@ -54,120 +65,67 @@ typedef struct _PROPERTIES { int lrov6; } PROPERTIES, *PPROPERTIES; -struct _ADAPTER { - LIST_ENTRY ListEntry; - XENVIF_VIF_INTERFACE VifInterface; - BOOLEAN AcquiredInterfaces; - ULONG MaximumFrameSize; - ULONG CurrentLookahead; - NDIS_HANDLE NdisAdapterHandle; - NDIS_HANDLE NdisDmaHandle; - NDIS_PNP_CAPABILITIES Capabilities; - PROPERTIES Properties; - RECEIVER Receiver; - PTRANSMITTER Transmitter; - BOOLEAN Enabled; - NDIS_OFFLOAD Offload; -}; - -MINIPORT_CANCEL_OID_REQUEST AdapterCancelOidRequest; -VOID -AdapterCancelOidRequest ( - IN NDIS_HANDLE NdisHandle, - IN PVOID RequestId - ); +typedef struct _XENNET_ADAPTER XENNET_ADAPTER, *PXENNET_ADAPTER; -MINIPORT_CANCEL_SEND AdapterCancelSendNetBufferLists; -VOID -AdapterCancelSendNetBufferLists ( - IN NDIS_HANDLE NdisHandle, - IN PVOID CancelId +extern NDIS_STATUS +AdapterInitialize( + IN NDIS_HANDLE Handle, + OUT PXENNET_ADAPTER *Adapter ); -MINIPORT_CHECK_FOR_HANG AdapterCheckForHang; -BOOLEAN -AdapterCheckForHang ( - IN NDIS_HANDLE NdisHandle - ); - -VOID -AdapterCleanup ( - IN PADAPTER Adapter - ); - -NDIS_STATUS -AdapterInitialize ( - IN PADAPTER Adapter, - IN NDIS_HANDLE AdapterHandle +extern VOID +AdapterTeardown( + IN PXENNET_ADAPTER Adapter ); -MINIPORT_OID_REQUEST AdapterOidRequest; -NDIS_STATUS -AdapterOidRequest ( - IN NDIS_HANDLE NdisHandle, - IN PNDIS_OID_REQUEST NdisRequest +extern NDIS_HANDLE +AdapterGetHandle( + IN PXENNET_ADAPTER Adapter ); -MINIPORT_PAUSE AdapterPause; -NDIS_STATUS -AdapterPause ( - IN NDIS_HANDLE NdisHandle, - IN PNDIS_MINIPORT_PAUSE_PARAMETERS MiniportPauseParameters +#include <vif_interface.h> +extern PXENVIF_VIF_INTERFACE +AdapterGetVifInterface( + IN PXENNET_ADAPTER Adapter ); -MINIPORT_DEVICE_PNP_EVENT_NOTIFY AdapterPnPEventHandler; -VOID -AdapterPnPEventHandler ( - IN NDIS_HANDLE NdisHandle, - IN PNET_DEVICE_PNP_EVENT NetDevicePnPEvent +#include "transmitter.h" +extern PXENNET_TRANSMITTER +AdapterGetTransmitter( + IN PXENNET_ADAPTER Adapter ); -MINIPORT_RESET AdapterReset; -NDIS_STATUS -AdapterReset ( - IN NDIS_HANDLE MiniportAdapterContext, - OUT PBOOLEAN AddressingReset +#include "receiver.h" +extern PXENNET_RECEIVER +AdapterGetReceiver( + IN PXENNET_ADAPTER Adapter ); -MINIPORT_RESTART AdapterRestart; -NDIS_STATUS -AdapterRestart ( - IN NDIS_HANDLE MiniportAdapterContext, - IN PNDIS_MINIPORT_RESTART_PARAMETERS MiniportRestartParameters +extern NDIS_STATUS +AdapterEnable( + IN PXENNET_ADAPTER Adapter ); -MINIPORT_RETURN_NET_BUFFER_LISTS AdapterReturnNetBufferLists; -VOID -AdapterReturnNetBufferLists ( - IN NDIS_HANDLE MiniportAdapterContext, - IN PNET_BUFFER_LIST NetBufferLists, - IN ULONG ReturnFlags +extern BOOLEAN +AdapterDisable( + IN PXENNET_ADAPTER Adapter ); -MINIPORT_SEND_NET_BUFFER_LISTS AdapterSendNetBufferLists; -VOID -AdapterSendNetBufferLists ( - IN NDIS_HANDLE MiniportAdapterContext, - IN PNET_BUFFER_LIST NetBufferList, - IN NDIS_PORT_NUMBER PortNumber, - IN ULONG SendFlags +extern VOID +AdapterMediaStateChange( + IN PXENNET_ADAPTER Adapter ); -NDIS_STATUS -AdapterStop ( - IN PADAPTER Adapter +extern NDIS_STATUS +AdapterSetInformation( + IN PXENNET_ADAPTER Adapter, + IN PNDIS_OID_REQUEST Request ); -MINIPORT_SHUTDOWN AdapterShutdown; - -VOID -AdapterShutdown ( - IN NDIS_HANDLE MiniportAdapterContext, - IN NDIS_SHUTDOWN_ACTION ShutdownAction +extern NDIS_STATUS +AdapterQueryInformation( + IN PXENNET_ADAPTER Adapter, + IN PNDIS_OID_REQUEST Request ); -extern VOID -ReceiverReceivePackets( - IN PRECEIVER Receiver, - IN PLIST_ENTRY List - ); +#endif // _XENNET_ADAPTER_H_ diff --git a/src/xennet/common.h b/src/xennet/common.h deleted file mode 100644 index 4d4c04a..0000000 --- a/src/xennet/common.h +++ /dev/null @@ -1,36 +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. - */ -#pragma once - -#include "std.h" -#include "project.h" -#include "dbg_print.h" -#include "assert.h" diff --git a/src/xennet/main.c b/src/xennet/main.c deleted file mode 100644 index e193e0e..0000000 --- a/src/xennet/main.c +++ /dev/null @@ -1,348 +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. - */ - -#include <version.h> - -#include "common.h" - -#pragma NDIS_INIT_FUNCTION(DriverEntry) - -// -// Global miniport data. -// - -static NDIS_HANDLE MiniportDriverHandle; - -extern MINIPORT_INITIALIZE MiniportInitialize; - -extern NDIS_STATUS -MiniportInitialize ( - IN NDIS_HANDLE MiniportAdapterHandle, - IN NDIS_HANDLE MiniportDriverContext, - IN PNDIS_MINIPORT_INIT_PARAMETERS MiniportInitParameters - ); - -MINIPORT_HALT MiniportHalt; - -extern VOID -MiniportHalt ( - IN NDIS_HANDLE MiniportAdapterHandle, - IN NDIS_HALT_ACTION HaltAction - ); - -typedef struct _XENNET_CONTEXT { - PDEVICE_CAPABILITIES Capabilities; - PIO_COMPLETION_ROUTINE CompletionRoutine; - PVOID CompletionContext; - UCHAR CompletionControl; -} XENNET_CONTEXT, *PXENNET_CONTEXT; - -static NTSTATUS (*NdisDispatchPnp)(PDEVICE_OBJECT, PIRP); - -__drv_functionClass(IO_COMPLETION_ROUTINE) -static NTSTATUS -__QueryCapabilities( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PVOID _Context - ) -{ - PXENNET_CONTEXT Context = _Context; - NTSTATUS status; - - Trace("====>\n"); - - Context->Capabilities->SurpriseRemovalOK = 1; - - if (Context->CompletionRoutine != NULL && - (Context->CompletionControl & SL_INVOKE_ON_SUCCESS)) - status = Context->CompletionRoutine(DeviceObject, Irp, Context->CompletionContext); - else - status = STATUS_SUCCESS; - - ExFreePool(Context); - - Trace("<====\n"); - - return status; -} - -NTSTATUS -QueryCapabilities( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp - ) -{ - PIO_STACK_LOCATION StackLocation; - PXENNET_CONTEXT Context; - NTSTATUS status; - - Trace("====>\n"); - - Trace("%p\n", DeviceObject); - - StackLocation = IoGetCurrentIrpStackLocation(Irp); - - Context = ExAllocatePoolWithTag(NonPagedPool, sizeof (XENNET_CONTEXT), ' TEN'); - if (Context != NULL) { - Context->Capabilities = StackLocation->Parameters.DeviceCapabilities.Capabilities; - Context->CompletionRoutine = StackLocation->CompletionRoutine; - Context->CompletionContext = StackLocation->Context; - Context->CompletionControl = StackLocation->Control; - - StackLocation->CompletionRoutine = __QueryCapabilities; - StackLocation->Context = Context; - StackLocation->Control = SL_INVOKE_ON_SUCCESS; - } - - status = NdisDispatchPnp(DeviceObject, Irp); - - Trace("<====\n"); - - return status; -} - -DRIVER_DISPATCH DispatchPnp; - -NTSTATUS -DispatchPnp( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp - ) -{ - PIO_STACK_LOCATION StackLocation; - UCHAR MinorFunction; - NTSTATUS status; - - StackLocation = IoGetCurrentIrpStackLocation(Irp); - MinorFunction = StackLocation->MinorFunction; - - switch (StackLocation->MinorFunction) { - case IRP_MN_QUERY_CAPABILITIES: - status = QueryCapabilities(DeviceObject, Irp); - break; - - default: - status = NdisDispatchPnp(DeviceObject, Irp); - break; - } - - return status; -} - -DRIVER_DISPATCH DispatchFail; - -NTSTATUS -DispatchFail( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp - ) -{ - NTSTATUS status; - - UNREFERENCED_PARAMETER(DeviceObject); - - Trace("%p\n", Irp); - - status = STATUS_UNSUCCESSFUL; - - Irp->IoStatus.Status = status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return status; -} - -DRIVER_INITIALIZE DriverEntry; - -NTSTATUS -DriverEntry ( - IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegistryPath - ) -{ - NDIS_STATUS ndisStatus; - NDIS_MINIPORT_DRIVER_CHARACTERISTICS mpChars; - NDIS_CONFIGURATION_OBJECT ConfigurationObject; - NDIS_HANDLE ConfigurationHandle; - NDIS_STRING ParameterName; - PNDIS_CONFIGURATION_PARAMETER ParameterValue; - ULONG FailCreateClose; - ULONG FailDeviceControl; - - ExInitializeDriverRuntime(DrvRtPoolNxOptIn); - - Trace("====>\n"); - - if (*InitSafeBootMode > 0) - return NDIS_STATUS_SUCCESS; - - Info("XENNET %d.%d.%d (%d) (%02d.%02d.%04d)\n", - MAJOR_VERSION, - MINOR_VERSION, - MICRO_VERSION, - BUILD_NUMBER, - DAY, - MONTH, - YEAR); - - // - // Register miniport with NDIS. - // - - NdisZeroMemory(&mpChars, sizeof(mpChars)); - mpChars.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_DRIVER_CHARACTERISTICS, - mpChars.Header.Size = sizeof(NDIS_MINIPORT_DRIVER_CHARACTERISTICS); - mpChars.Header.Revision = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_1; - - mpChars.MajorNdisVersion = 6; - mpChars.MinorNdisVersion = 0; - mpChars.MajorDriverVersion = MAJOR_VERSION; - mpChars.MinorDriverVersion = MINOR_VERSION; - - mpChars.CancelOidRequestHandler = AdapterCancelOidRequest; - mpChars.CancelSendHandler = AdapterCancelSendNetBufferLists; - mpChars.CheckForHangHandlerEx = AdapterCheckForHang; - mpChars.InitializeHandlerEx = MiniportInitialize; - mpChars.HaltHandlerEx = MiniportHalt; - mpChars.OidRequestHandler = AdapterOidRequest; - mpChars.PauseHandler = AdapterPause; - mpChars.DevicePnPEventNotifyHandler = AdapterPnPEventHandler; - mpChars.ResetHandlerEx = AdapterReset; - mpChars.RestartHandler = AdapterRestart; - mpChars.ReturnNetBufferListsHandler = AdapterReturnNetBufferLists; - mpChars.SendNetBufferListsHandler = AdapterSendNetBufferLists; - mpChars.ShutdownHandlerEx = AdapterShutdown; - mpChars.UnloadHandler = DriverUnload; - - MiniportDriverHandle = NULL; - ndisStatus = NdisMRegisterMiniportDriver(DriverObject, - RegistryPath, - NULL, - &mpChars, - &MiniportDriverHandle); - if (ndisStatus != NDIS_STATUS_SUCCESS) { - Error("Failed (0x%08X) to register miniport.\n", ndisStatus); - goto fail; - } - - ConfigurationObject.Header.Type = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT; - ConfigurationObject.Header.Revision = NDIS_CONFIGURATION_OBJECT_REVISION_1; - ConfigurationObject.Header.Size = NDIS_SIZEOF_CONFIGURATION_OBJECT_REVISION_1; - ConfigurationObject.NdisHandle = MiniportDriverHandle; - ConfigurationObject.Flags = 0; - - ndisStatus = NdisOpenConfigurationEx(&ConfigurationObject, &ConfigurationHandle); - if (ndisStatus != NDIS_STATUS_SUCCESS) { - Error("Failed (0x%08X) to open driver configuration.\n", ndisStatus); - NdisMDeregisterMiniportDriver(MiniportDriverHandle); - goto fail; - } - - RtlInitUnicodeString(&ParameterName, L"FailCreateClose"); - - NdisReadConfiguration(&ndisStatus, - &ParameterValue, - ConfigurationHandle, - &ParameterName, - NdisParameterInteger); - if (ndisStatus == NDIS_STATUS_SUCCESS && - ParameterValue->ParameterType == NdisParameterInteger) - FailCreateClose = ParameterValue->ParameterData.IntegerData; - else - FailCreateClose = 0; - - RtlInitUnicodeString(&ParameterName, L"FailDeviceControl"); - - NdisReadConfiguration(&ndisStatus, - &ParameterValue, - ConfigurationHandle, - &ParameterName, - NdisParameterInteger); - if (ndisStatus == NDIS_STATUS_SUCCESS && - ParameterValue->ParameterType == NdisParameterInteger) - FailDeviceControl = ParameterValue->ParameterData.IntegerData; - else - FailDeviceControl = 0; - - NdisCloseConfiguration(ConfigurationHandle); - ndisStatus = NDIS_STATUS_SUCCESS; - - NdisDispatchPnp = DriverObject->MajorFunction[IRP_MJ_PNP]; -#pragma prefast(suppress:28168) // No matching __drv_dispatchType annotation - DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp; - - if (FailCreateClose != 0) { -#pragma prefast(suppress:28168) // No matching__drv_dispatchType annotation - DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchFail; -#pragma prefast(suppress:28168) // No matching __drv_dispatchType annotation - DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchFail; - } - - if (FailDeviceControl != 0) { -#pragma prefast(suppress:28168) // No matching __drv_dispatchType annotation - DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchFail; - } - - Trace("<====\n"); - return ndisStatus; - -fail: - Error("fail\n"); - return ndisStatus; -} - -VOID -DriverUnload ( - IN PDRIVER_OBJECT DriverObject - ) -{ - UNREFERENCED_PARAMETER(DriverObject); - - Trace("====>\n"); - - if (*InitSafeBootMode > 0) - goto done; - - if (MiniportDriverHandle) - NdisMDeregisterMiniportDriver(MiniportDriverHandle); - - Info("XENNET %d.%d.%d (%d) (%02d.%02d.%04d)\n", - MAJOR_VERSION, - MINOR_VERSION, - MICRO_VERSION, - BUILD_NUMBER, - DAY, - MONTH, - YEAR); - -done: - Trace("<====\n"); -} diff --git a/src/xennet/project.h b/src/xennet/project.h deleted file mode 100644 index 981cb0e..0000000 --- a/src/xennet/project.h +++ /dev/null @@ -1,66 +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. - */ - -#pragma once - -#include <util.h> -#include <ethernet.h> -#include <tcpip.h> -#include <vif_interface.h> - -typedef struct _ADAPTER ADAPTER, *PADAPTER; - -DRIVER_INITIALIZE DriverEntry; -NTSTATUS -DriverEntry ( - IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegistryPath - ); - -MINIPORT_UNLOAD DriverUnload; -VOID -DriverUnload ( - IN PDRIVER_OBJECT DriverObject - ); - -NDIS_STATUS -MpSetAdapterSettings( - IN PADAPTER Adapter - ); - -NDIS_STATUS -MpGetAdvancedSettings( - IN PADAPTER Adapter - ); - -#include "transmitter.h" -#include "receiver.h" -#include "adapter.h" diff --git a/src/xennet/receiver.c b/src/xennet/receiver.c index 54bdc15..49320a5 100644 --- a/src/xennet/receiver.c +++ b/src/xennet/receiver.c @@ -29,100 +29,35 @@ * SUCH DAMAGE. */ -#include "common.h" +#include "receiver.h" +#include "adapter.h" +#include <util.h> +#include "dbg_print.h" +#include "assert.h" + +struct _XENNET_RECEIVER { + PXENNET_ADAPTER Adapter; + NDIS_HANDLE NetBufferListPool; + PNET_BUFFER_LIST PutList; + PNET_BUFFER_LIST GetList[MAXIMUM_PROCESSORS]; + LONG InNDIS; + LONG InNDISMax; + XENVIF_VIF_OFFLOAD_OPTIONS OffloadOptions; +}; + +#define RECEIVER_POOL_TAG 'RteN' +#define IN_NDIS_MAX 1024 -#pragma warning(disable:4711) - -NDIS_STATUS -ReceiverInitialize ( - IN PRECEIVER Receiver - ) -{ - PADAPTER Adapter; - NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS; - NET_BUFFER_LIST_POOL_PARAMETERS poolParameters; - ULONG Cpu; - - Receiver->PutList = NULL; - for (Cpu = 0; Cpu < MAXIMUM_PROCESSORS; Cpu++) - Receiver->GetList[Cpu] = NULL; - - Adapter = CONTAINING_RECORD(Receiver, ADAPTER, Receiver); - - NdisZeroMemory(&poolParameters, sizeof(NET_BUFFER_LIST_POOL_PARAMETERS)); - poolParameters.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - poolParameters.Header.Revision = - NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1; - poolParameters.Header.Size = sizeof(poolParameters); - poolParameters.ProtocolId = 0; - poolParameters.ContextSize = 0; - poolParameters.fAllocateNetBuffer = TRUE; - poolParameters.PoolTag = ' TEN'; - - Receiver->NetBufferListPool = - NdisAllocateNetBufferListPool(Adapter->NdisAdapterHandle, - &poolParameters); - - if (!Receiver->NetBufferListPool) - ndisStatus = NDIS_STATUS_RESOURCES; - - return ndisStatus; -} - -VOID -ReceiverCleanup ( - IN PRECEIVER Receiver - ) -{ - ULONG Cpu; - PNET_BUFFER_LIST NetBufferList; - - ASSERT(Receiver != NULL); - - for (Cpu = 0; Cpu < MAXIMUM_PROCESSORS; Cpu++) { - NetBufferList = Receiver->GetList[Cpu]; - while (NetBufferList != NULL) { - PNET_BUFFER_LIST Next; - - Next = NET_BUFFER_LIST_NEXT_NBL(NetBufferList); - NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL; - - NdisFreeNetBufferList(NetBufferList); - - NetBufferList = Next; - } - } - - NetBufferList = Receiver->PutList; - while (NetBufferList != NULL) { - PNET_BUFFER_LIST Next; - - Next = NET_BUFFER_LIST_NEXT_NBL(NetBufferList); - NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL; - - NdisFreeNetBufferList(NetBufferList); - - NetBufferList = Next; - } - - if (Receiver->NetBufferListPool) { - NdisFreeNetBufferListPool(Receiver->NetBufferListPool); - Receiver->NetBufferListPool = NULL; - } - - return; -} - -PNET_BUFFER_LIST -ReceiverAllocateNetBufferList( - IN PRECEIVER Receiver, - IN PMDL Mdl, - IN ULONG Offset, - IN ULONG Length +static PNET_BUFFER_LIST +__ReceiverAllocateNetBufferList( + IN PXENNET_RECEIVER Receiver, + IN PMDL Mdl, + IN ULONG Offset, + IN ULONG Length ) { - ULONG Cpu; - PNET_BUFFER_LIST NetBufferList; + ULONG Cpu; + PNET_BUFFER_LIST NetBufferList; Cpu = KeGetCurrentProcessorNumber(); @@ -158,9 +93,9 @@ ReceiverAllocateNetBufferList( return NetBufferList; } -VOID -ReceiverReleaseNetBufferList( - IN PRECEIVER Receiver, +static VOID +__ReceiverReleaseNetBufferList( + IN PXENNET_RECEIVER Receiver, IN PNET_BUFFER_LIST NetBufferList, IN BOOLEAN Cache ) @@ -184,17 +119,16 @@ ReceiverReleaseNetBufferList( static FORCEINLINE ULONG __ReceiverReturnNetBufferLists( - IN PRECEIVER Receiver, + IN PXENNET_RECEIVER Receiver, IN PNET_BUFFER_LIST NetBufferList, IN BOOLEAN Cache ) { - PADAPTER Adapter; + PXENVIF_VIF_INTERFACE VifInterface; LIST_ENTRY List; ULONG Count; - Adapter = CONTAINING_RECORD(Receiver, ADAPTER, Receiver); - + VifInterface = AdapterGetVifInterface(Receiver->Adapter); InitializeListHead(&List); Count = 0; @@ -212,7 +146,7 @@ __ReceiverReturnNetBufferLists( Mdl = NET_BUFFER_FIRST_MDL(NetBuffer); - ReceiverReleaseNetBufferList(Receiver, NetBufferList, Cache); + __ReceiverReleaseNetBufferList(Receiver, NetBufferList, Cache); Packet = CONTAINING_RECORD(Mdl, XENVIF_RECEIVER_PACKET, Mdl); @@ -224,51 +158,33 @@ __ReceiverReturnNetBufferLists( if (Count != 0) XENVIF_VIF(ReceiverReturnPackets, - &Adapter->VifInterface, + VifInterface, &List); return Count; } -VOID -ReceiverReturnNetBufferLists( - IN PRECEIVER Receiver, - IN PNET_BUFFER_LIST HeadNetBufferList, - IN ULONG Flags - ) -{ - ULONG Count; - - UNREFERENCED_PARAMETER(Flags); - - Count = __ReceiverReturnNetBufferLists(Receiver, HeadNetBufferList, TRUE); - (VOID) __InterlockedSubtract(&Receiver->InNDIS, Count); -} - static PNET_BUFFER_LIST -ReceiverReceivePacket( - IN PRECEIVER Receiver, - IN PMDL Mdl, - IN ULONG Offset, - IN ULONG Length, - IN XENVIF_PACKET_CHECKSUM_FLAGS Flags, - IN USHORT TagControlInformation +__ReceiverReceivePacket( + IN PXENNET_RECEIVER Receiver, + IN PMDL Mdl, + IN ULONG Offset, + IN ULONG Length, + IN XENVIF_PACKET_CHECKSUM_FLAGS Flags, + IN USHORT TagControlInformation ) { - PADAPTER Adapter; PNET_BUFFER_LIST NetBufferList; NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO csumInfo; - Adapter = CONTAINING_RECORD(Receiver, ADAPTER, Receiver); - - NetBufferList = ReceiverAllocateNetBufferList(Receiver, - Mdl, - Offset, - Length); + NetBufferList = __ReceiverAllocateNetBufferList(Receiver, + Mdl, + Offset, + Length); if (NetBufferList == NULL) goto fail1; - NetBufferList->SourceHandle = Adapter->NdisAdapterHandle; + NetBufferList->SourceHandle = AdapterGetHandle(Receiver->Adapter); csumInfo.Value = 0; @@ -300,26 +216,23 @@ ReceiverReceivePacket( return NetBufferList; fail2: - ReceiverReleaseNetBufferList(Receiver, NetBufferList, TRUE); + __ReceiverReleaseNetBufferList(Receiver, NetBufferList, TRUE); fail1: return NULL; } static VOID -ReceiverPushPackets( - IN PRECEIVER Receiver, +__ReceiverPushPackets( + IN PXENNET_RECEIVER Receiver, IN PNET_BUFFER_LIST NetBufferList, IN ULONG Count, IN BOOLEAN LowResources ) { - PADAPTER Adapter; ULONG Flags; LONG InNDIS; - Adapter = CONTAINING_RECORD(Receiver, ADAPTER, Receiver); - InNDIS = Receiver->InNDIS; Flags = NDIS_RECEIVE_FLAGS_DISPATCH_LEVEL; @@ -342,7 +255,7 @@ ReceiverPushPackets( break; } - NdisMIndicateReceiveNetBufferLists(Adapter->NdisAdapterHandle, + NdisMIndicateReceiveNetBufferLists(AdapterGetHandle(Receiver->Adapter), NetBufferList, NDIS_DEFAULT_PORT_NUMBER, Count, @@ -352,21 +265,121 @@ ReceiverPushPackets( (VOID) __ReceiverReturnNetBufferLists(Receiver, NetBufferList, FALSE); } -#define IN_NDIS_MAX 1024 +NDIS_STATUS +ReceiverInitialize( + IN PXENNET_ADAPTER Adapter, + OUT PXENNET_RECEIVER *Receiver + ) +{ + NET_BUFFER_LIST_POOL_PARAMETERS Params; + NDIS_STATUS status; + + *Receiver = ExAllocatePoolWithTag(NonPagedPool, + sizeof(XENNET_RECEIVER), + RECEIVER_POOL_TAG); + + status = NDIS_STATUS_RESOURCES; + if (*Receiver == NULL) + goto fail1; + + RtlZeroMemory(*Receiver, sizeof(XENNET_RECEIVER)); + (*Receiver)->Adapter = Adapter; + + RtlZeroMemory(&Params, sizeof(NET_BUFFER_LIST_POOL_PARAMETERS)); + Params.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + Params.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1; + Params.Header.Size = sizeof(Params); + Params.ProtocolId = 0; + Params.ContextSize = 0; + Params.fAllocateNetBuffer = TRUE; + Params.PoolTag = 'PteN'; + + (*Receiver)->NetBufferListPool = NdisAllocateNetBufferListPool(AdapterGetHandle(Adapter), + &Params); + + status = NDIS_STATUS_RESOURCES; + if ((*Receiver)->NetBufferListPool == NULL) + goto fail2; + + return NDIS_STATUS_SUCCESS; + +fail2: +fail1: + return status; +} + +VOID +ReceiverTeardown( + IN PXENNET_RECEIVER Receiver + ) +{ + ULONG Cpu; + PNET_BUFFER_LIST NetBufferList; + + ASSERT(Receiver != NULL); + + for (Cpu = 0; Cpu < MAXIMUM_PROCESSORS; Cpu++) { + NetBufferList = Receiver->GetList[Cpu]; + while (NetBufferList != NULL) { + PNET_BUFFER_LIST Next; + + Next = NET_BUFFER_LIST_NEXT_NBL(NetBufferList); + NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL; + + NdisFreeNetBufferList(NetBufferList); + + NetBufferList = Next; + } + } + + NetBufferList = Receiver->PutList; + while (NetBufferList != NULL) { + PNET_BUFFER_LIST Next; + + Next = NET_BUFFER_LIST_NEXT_NBL(NetBufferList); + NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL; + + NdisFreeNetBufferList(NetBufferList); + + NetBufferList = Next; + } + + NdisFreeNetBufferListPool(Receiver->NetBufferListPool); + Receiver->NetBufferListPool = NULL; + + Receiver->Adapter = NULL; + + ExFreePoolWithTag(Receiver, RECEIVER_POOL_TAG); +} + +VOID +ReceiverReturnNetBufferLists( + IN PXENNET_RECEIVER Receiver, + IN PNET_BUFFER_LIST NetBufferList, + IN ULONG ReturnFlags + ) +{ + ULONG Count; + + UNREFERENCED_PARAMETER(ReturnFlags); + + Count = __ReceiverReturnNetBufferLists(Receiver, NetBufferList, TRUE); + (VOID) __InterlockedSubtract(&Receiver->InNDIS, Count); +} VOID ReceiverReceivePackets( - IN PRECEIVER Receiver, - IN PLIST_ENTRY List + IN PXENNET_RECEIVER Receiver, + IN PLIST_ENTRY List ) { - PADAPTER Adapter; - PNET_BUFFER_LIST HeadNetBufferList; - PNET_BUFFER_LIST *TailNetBufferList; - ULONG Count; - BOOLEAN LowResources; + PXENVIF_VIF_INTERFACE VifInterface; + PNET_BUFFER_LIST HeadNetBufferList; + PNET_BUFFER_LIST *TailNetBufferList; + ULONG Count; + BOOLEAN LowResources; - Adapter = CONTAINING_RECORD(Receiver, ADAPTER, Receiver); + VifInterface = AdapterGetVifInterface(Receiver->Adapter); LowResources = FALSE; again: @@ -404,28 +417,28 @@ again: TagControlInformation = Info->TagControlInformation; - NetBufferList = ReceiverReceivePacket(Receiver, Mdl, Offset, Length, Flags, TagControlInformation); + NetBufferList = __ReceiverReceivePacket(Receiver, Mdl, Offset, Length, Flags, TagControlInformation); if (NetBufferList != NULL) { *TailNetBufferList = NetBufferList; TailNetBufferList = &NET_BUFFER_LIST_NEXT_NBL(NetBufferList); Count++; } else { - LIST_ENTRY List; + LIST_ENTRY PacketList; - InitializeListHead(&List); - InsertTailList(&List, &Packet->ListEntry); + InitializeListHead(&PacketList); + InsertTailList(&PacketList, &Packet->ListEntry); XENVIF_VIF(ReceiverReturnPackets, - &Adapter->VifInterface, - &List); + VifInterface, + &PacketList); } } if (Count != 0) { ASSERT(HeadNetBufferList != NULL); - ReceiverPushPackets(Receiver, HeadNetBufferList, Count, LowResources); + __ReceiverPushPackets(Receiver, HeadNetBufferList, Count, LowResources); } if (!IsListEmpty(List)) { @@ -434,3 +447,12 @@ again: goto again; } } + +PXENVIF_VIF_OFFLOAD_OPTIONS +ReceiverOffloadOptions( + IN PXENNET_RECEIVER Receiver + ) +{ + return &Receiver->OffloadOptions; +} + diff --git a/src/xennet/receiver.h b/src/xennet/receiver.h index 1a58053..fb69b96 100644 --- a/src/xennet/receiver.h +++ b/src/xennet/receiver.h @@ -29,49 +29,41 @@ * SUCH DAMAGE. */ -#pragma once +#ifndef _XENNET_RECEIVER_H_ +#define _XENNET_RECEIVER_H_ -typedef struct _RECEIVER { - NDIS_HANDLE NetBufferListPool; - PNET_BUFFER_LIST PutList; - PNET_BUFFER_LIST GetList[MAXIMUM_PROCESSORS]; - LONG InNDIS; - LONG InNDISMax; - XENVIF_VIF_OFFLOAD_OPTIONS OffloadOptions; -} RECEIVER, *PRECEIVER; +#include <ndis.h> -VOID -ReceiverDebugDump ( - IN PRECEIVER Receiver - ); - -VOID -ReceiverCleanup ( - IN PRECEIVER Receiver - ); +typedef struct _XENNET_RECEIVER XENNET_RECEIVER, *PXENNET_RECEIVER; -VOID -ReceiverHandleNotification ( - IN PRECEIVER Receiver +#include "adapter.h" +extern NDIS_STATUS +ReceiverInitialize( + IN PXENNET_ADAPTER Adapter, + OUT PXENNET_RECEIVER *Receiver ); -NDIS_STATUS -ReceiverInitialize ( - IN PRECEIVER Receiver +extern VOID +ReceiverTeardown( + IN PXENNET_RECEIVER Receiver ); -VOID -ReceiverReturnNetBufferLists ( - IN PRECEIVER Receiver, +extern VOID +ReceiverReturnNetBufferLists( + IN PXENNET_RECEIVER Receiver, IN PNET_BUFFER_LIST NetBufferList, IN ULONG ReturnFlags ); -VOID -ReceiverWaitForPacketReturn( - IN PRECEIVER Receiver, - IN BOOLEAN Locked +extern VOID +ReceiverReceivePackets( + IN PXENNET_RECEIVER Receiver, + IN PLIST_ENTRY List + ); + +extern PXENVIF_VIF_OFFLOAD_OPTIONS +ReceiverOffloadOptions( + IN PXENNET_RECEIVER Receiver ); -void ReceiverPause(PRECEIVER receiver); -void ReceiverUnpause(PRECEIVER receiver); +#endif // _XENNET_RECEIVER_H_ diff --git a/src/xennet/std.h b/src/xennet/std.h deleted file mode 100644 index c72325a..0000000 --- a/src/xennet/std.h +++ /dev/null @@ -1,45 +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. - */ - -#pragma once - -#pragma warning(disable:4214) // bit field types other than int - -#pragma warning(disable:4201) // nameless struct/union -#pragma warning(disable:4115) // named type definition in parentheses -#pragma warning(disable:4127) // conditional expression is constant -#pragma warning(disable:4054) // cast of function pointer to PVOID -#pragma warning(disable:4206) // translation unit is empty - -#include <ndis.h> -#include <ntstrsafe.h> - -extern PULONG InitSafeBootMode; diff --git a/src/xennet/transmitter.c b/src/xennet/transmitter.c index 6a18a19..0c89f76 100644 --- a/src/xennet/transmitter.c +++ b/src/xennet/transmitter.c @@ -29,60 +29,78 @@ * SUCH DAMAGE. */ -#include "common.h" +#include <ndis.h> +#include "transmitter.h" +#include "adapter.h" +#include <vif_interface.h> +#include "dbg_print.h" +#include "assert.h" -#pragma warning(disable:4711) +struct _XENNET_TRANSMITTER { + PXENNET_ADAPTER Adapter; + XENVIF_VIF_OFFLOAD_OPTIONS OffloadOptions; +}; + +#define TRANSMITTER_POOL_TAG 'TteN' NDIS_STATUS -TransmitterInitialize( - IN PTRANSMITTER Transmitter, - IN PADAPTER Adapter +TransmitterInitialize ( + IN PXENNET_ADAPTER Adapter, + OUT PXENNET_TRANSMITTER *Transmitter ) { - Transmitter->Adapter = Adapter; - + *Transmitter = ExAllocatePoolWithTag(NonPagedPool, + sizeof(XENNET_TRANSMITTER), + TRANSMITTER_POOL_TAG); + if (*Transmitter == NULL) + goto fail1; + + RtlZeroMemory(*Transmitter, sizeof(XENNET_TRANSMITTER)); + (*Transmitter)->Adapter = Adapter; + return NDIS_STATUS_SUCCESS; + +fail1: + return NDIS_STATUS_FAILURE; +} + +VOID +TransmitterTeardown( + IN PXENNET_TRANSMITTER Transmitter + ) +{ + Transmitter->Adapter = NULL; + Transmitter->OffloadOptions.Value = 0; + + ExFreePoolWithTag(Transmitter, TRANSMITTER_POOL_TAG); } VOID TransmitterEnable( - IN PTRANSMITTER Transmitter + IN PXENNET_TRANSMITTER Transmitter ) { - PADAPTER Adapter = Transmitter->Adapter; + PXENVIF_VIF_INTERFACE VifInterface = AdapterGetVifInterface(Transmitter->Adapter); (VOID) XENVIF_VIF(TransmitterSetPacketOffset, - &Adapter->VifInterface, + VifInterface, XENVIF_TRANSMITTER_PACKET_OFFSET_OFFSET, (LONG_PTR)&NET_BUFFER_CURRENT_MDL_OFFSET((PNET_BUFFER)NULL) - (LONG_PTR)&NET_BUFFER_MINIPORT_RESERVED((PNET_BUFFER)NULL)); (VOID) XENVIF_VIF(TransmitterSetPacketOffset, - &Adapter->VifInterface, + VifInterface, XENVIF_TRANSMITTER_PACKET_LENGTH_OFFSET, (LONG_PTR)&NET_BUFFER_DATA_LENGTH((PNET_BUFFER)NULL) - (LONG_PTR)&NET_BUFFER_MINIPORT_RESERVED((PNET_BUFFER)NULL)); (VOID) XENVIF_VIF(TransmitterSetPacketOffset, - &Adapter->VifInterface, + VifInterface, XENVIF_TRANSMITTER_PACKET_MDL_OFFSET, (LONG_PTR)&NET_BUFFER_CURRENT_MDL((PNET_BUFFER)NULL) - (LONG_PTR)&NET_BUFFER_MINIPORT_RESERVED((PNET_BUFFER)NULL)); } -VOID -TransmitterDelete ( - IN OUT PTRANSMITTER *Transmitter - ) -{ - ASSERT(Transmitter != NULL); - - if (*Transmitter) { - ExFreePool(*Transmitter); - *Transmitter = NULL; - } -} - typedef struct _NET_BUFFER_LIST_RESERVED { LONG Reference; } NET_BUFFER_LIST_RESERVED, *PNET_BUFFER_LIST_RESERVED; @@ -97,24 +115,37 @@ typedef struct _NET_BUFFER_RESERVED { C_ASSERT(sizeof (NET_BUFFER_RESERVED) <= RTL_FIELD_SIZE(NET_BUFFER, MiniportReserved)); static VOID -TransmitterAbortNetBufferList( - IN PTRANSMITTER Transmitter, - IN PNET_BUFFER_LIST NetBufferList +__TransmitterCompleteNetBufferList( + IN PXENNET_TRANSMITTER Transmitter, + IN PNET_BUFFER_LIST NetBufferList, + IN NDIS_STATUS Status ) { ASSERT3P(NET_BUFFER_LIST_NEXT_NBL(NetBufferList), ==, NULL); - NET_BUFFER_LIST_STATUS(NetBufferList) = NDIS_STATUS_NOT_ACCEPTED; + NET_BUFFER_LIST_STATUS(NetBufferList) = Status; + + if (Status == NDIS_STATUS_SUCCESS) { + PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO LargeSendInfo; + + LargeSendInfo = (PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO) + &NET_BUFFER_LIST_INFO(NetBufferList, + TcpLargeSendNetBufferListInfo); + if (LargeSendInfo->LsoV2Transmit.MSS != 0) + LargeSendInfo->LsoV2TransmitComplete.Reserved = 0; + } - NdisMSendNetBufferListsComplete(Transmitter->Adapter->NdisAdapterHandle, + NdisMSendNetBufferListsComplete(AdapterGetHandle(Transmitter->Adapter), NetBufferList, NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL); } -VOID -TransmitterAbortPackets( - IN PTRANSMITTER Transmitter, - IN PXENVIF_TRANSMITTER_PACKET Packet + +static VOID +__TransmitterCompletePackets( + IN PXENNET_TRANSMITTER Transmitter, + IN PXENVIF_TRANSMITTER_PACKET Packet, + IN NDIS_STATUS Status ) { while (Packet != NULL) { @@ -135,21 +166,86 @@ TransmitterAbortPackets( ASSERT(ListReserved->Reference != 0); if (InterlockedDecrement(&ListReserved->Reference) == 0) - TransmitterAbortNetBufferList(Transmitter, NetBufferList); + __TransmitterCompleteNetBufferList(Transmitter, NetBufferList, Status); Packet = Next; + } +} + +static VOID +__TransmitterOffloadOptions( + IN PNET_BUFFER_LIST NetBufferList, + OUT PXENVIF_VIF_OFFLOAD_OPTIONS OffloadOptions, + OUT PUSHORT TagControlInformation, + OUT PUSHORT MaximumSegmentSize + ) +{ + PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO LargeSendInfo; + PNDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO ChecksumInfo; + PNDIS_NET_BUFFER_LIST_8021Q_INFO Ieee8021QInfo; + + LargeSendInfo = (PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO)&NET_BUFFER_LIST_INFO(NetBufferList, + TcpLargeSendNetBufferListInfo); + ChecksumInfo = (PNDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO)&NET_BUFFER_LIST_INFO(NetBufferList, + TcpIpChecksumNetBufferListInfo); + Ieee8021QInfo = (PNDIS_NET_BUFFER_LIST_8021Q_INFO)&NET_BUFFER_LIST_INFO(NetBufferList, + Ieee8021QNetBufferListInfo); + + OffloadOptions->Value = 0; + *TagControlInformation = 0; + *MaximumSegmentSize = 0; + + if (ChecksumInfo->Transmit.IsIPv4) { + if (ChecksumInfo->Transmit.IpHeaderChecksum) + OffloadOptions->OffloadIpVersion4HeaderChecksum = 1; + + if (ChecksumInfo->Transmit.TcpChecksum) + OffloadOptions->OffloadIpVersion4TcpChecksum = 1; + + if (ChecksumInfo->Transmit.UdpChecksum) + OffloadOptions->OffloadIpVersion4UdpChecksum = 1; + } + + if (ChecksumInfo->Transmit.IsIPv6) { + if (ChecksumInfo->Transmit.TcpChecksum) + OffloadOptions->OffloadIpVersion6TcpChecksum = 1; + + if (ChecksumInfo->Transmit.UdpChecksum) + OffloadOptions->OffloadIpVersion6UdpChecksum = 1; + } + + if (Ieee8021QInfo->TagHeader.UserPriority != 0) { + OffloadOptions->OffloadTagManipulation = 1; + + ASSERT3U(Ieee8021QInfo->TagHeader.CanonicalFormatId, ==, 0); + ASSERT3U(Ieee8021QInfo->TagHeader.VlanId, ==, 0); + + PACK_TAG_CONTROL_INFORMATION(*TagControlInformation, + Ieee8021QInfo->TagHeader.UserPriority, + Ieee8021QInfo->TagHeader.CanonicalFormatId, + Ieee8021QInfo->TagHeader.VlanId); + } + + if (LargeSendInfo->LsoV2Transmit.MSS != 0) { + if (LargeSendInfo->LsoV2Transmit.IPVersion == NDIS_TCP_LARGE_SEND_OFFLOAD_IPv4) + OffloadOptions->OffloadIpVersion4LargePacket = 1; + + if (LargeSendInfo->LsoV2Transmit.IPVersion == NDIS_TCP_LARGE_SEND_OFFLOAD_IPv6) + OffloadOptions->OffloadIpVersion6LargePacket = 1; + + ASSERT3U(LargeSendInfo->LsoV2Transmit.MSS >> 16, ==, 0); + *MaximumSegmentSize = (USHORT)LargeSendInfo->LsoV2Transmit.MSS; } } VOID TransmitterSendNetBufferLists( - IN PTRANSMITTER Transmitter, + IN PXENNET_TRANSMITTER Transmitter, IN PNET_BUFFER_LIST NetBufferList, IN NDIS_PORT_NUMBER PortNumber, IN ULONG SendFlags ) { - PADAPTER Adapter = Transmitter->Adapter; PXENVIF_TRANSMITTER_PACKET HeadPacket; PXENVIF_TRANSMITTER_PACKET *TailPacket; KIRQL Irql; @@ -167,26 +263,24 @@ TransmitterSendNetBufferLists( } while (NetBufferList != NULL) { - PNET_BUFFER_LIST ListNext; - PNET_BUFFER_LIST_RESERVED ListReserved; - PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO LargeSendInfo; - PNDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO ChecksumInfo; - PNDIS_NET_BUFFER_LIST_8021Q_INFO Ieee8021QInfo; - PNET_BUFFER NetBuffer; + PNET_BUFFER_LIST ListNext; + PNET_BUFFER_LIST_RESERVED ListReserved; + PNET_BUFFER NetBuffer; + XENVIF_VIF_OFFLOAD_OPTIONS OffloadOptions; + USHORT TagControlInformation; + USHORT MaximumSegmentSize; ListNext = NET_BUFFER_LIST_NEXT_NBL(NetBufferList); NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL; + __TransmitterOffloadOptions(NetBufferList, + &OffloadOptions, + &TagControlInformation, + &MaximumSegmentSize); + ListReserved = (PNET_BUFFER_LIST_RESERVED)NET_BUFFER_LIST_MINIPORT_RESERVED(NetBufferList); RtlZeroMemory(ListReserved, sizeof (NET_BUFFER_LIST_RESERVED)); - LargeSendInfo = (PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO)&NET_BUFFER_LIST_INFO(NetBufferList, - TcpLargeSendNetBufferListInfo); - ChecksumInfo = (PNDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO)&NET_BUFFER_LIST_INFO(NetBufferList, - TcpIpChecksumNetBufferListInfo); - Ieee8021QInfo = (PNDIS_NET_BUFFER_LIST_8021Q_INFO)&NET_BUFFER_LIST_INFO(NetBufferList, - Ieee8021QNetBufferListInfo); - NetBuffer = NET_BUFFER_LIST_FIRST_NB(NetBufferList); while (NetBuffer != NULL) { PNET_BUFFER_RESERVED Reserved; @@ -199,50 +293,9 @@ TransmitterSendNetBufferLists( ListReserved->Reference++; Packet = &Reserved->Packet; - - if (ChecksumInfo->Transmit.IsIPv4) { - if (ChecksumInfo->Transmit.IpHeaderChecksum) - Packet->Send.OffloadOptions.OffloadIpVersion4HeaderChecksum = 1; - - if (ChecksumInfo->Transmit.TcpChecksum) - Packet->Send.OffloadOptions.OffloadIpVersion4TcpChecksum = 1; - - if (ChecksumInfo->Transmit.UdpChecksum) - Packet->Send.OffloadOptions.OffloadIpVersion4UdpChecksum = 1; - } - - if (ChecksumInfo->Transmit.IsIPv6) { - if (ChecksumInfo->Transmit.TcpChecksum) - Packet->Send.OffloadOptions.OffloadIpVersion6TcpChecksum = 1; - - if (ChecksumInfo->Transmit.UdpChecksum) - Packet->Send.OffloadOptions.OffloadIpVersion6UdpChecksum = 1; - } - - if (Ieee8021QInfo->TagHeader.UserPriority != 0) { - Packet->Send.OffloadOptions.OffloadTagManipulation = 1; - - ASSERT3U(Ieee8021QInfo->TagHeader.CanonicalFormatId, ==, 0); - ASSERT3U(Ieee8021QInfo->TagHeader.VlanId, ==, 0); - - PACK_TAG_CONTROL_INFORMATION(Packet->Send.TagControlInformation, - Ieee8021QInfo->TagHeader.UserPriority, - Ieee8021QInfo->TagHeader.CanonicalFormatId, - Ieee8021QInfo->TagHeader.VlanId); - } - - if (LargeSendInfo->LsoV2Transmit.MSS != 0) { - if (LargeSendInfo->LsoV2Transmit.IPVersion == NDIS_TCP_LARGE_SEND_OFFLOAD_IPv4) - Packet->Send.OffloadOptions.OffloadIpVersion4LargePacket = 1; - - if (LargeSendInfo->LsoV2Transmit.IPVersion == NDIS_TCP_LARGE_SEND_OFFLOAD_IPv6) - Packet->Send.OffloadOptions.OffloadIpVersion6LargePacket = 1; - - ASSERT3U(LargeSendInfo->LsoV2Transmit.MSS >> 16, ==, 0); - Packet->Send.MaximumSegmentSize = (USHORT)LargeSendInfo->LsoV2Transmit.MSS; - } - - Packet->Send.OffloadOptions.Value &= Transmitter->OffloadOptions.Value; + Packet->Send.OffloadOptions.Value = OffloadOptions.Value & Transmitter->OffloadOptions.Value; + Packet->Send.MaximumSegmentSize = MaximumSegmentSize; + Packet->Send.TagControlInformation = TagControlInformation; ASSERT3P(Packet->Next, ==, NULL); *TailPacket = Packet; @@ -258,65 +311,29 @@ TransmitterSendNetBufferLists( NTSTATUS status; status = XENVIF_VIF(TransmitterQueuePackets, - &Adapter->VifInterface, + AdapterGetVifInterface(Transmitter->Adapter), HeadPacket); if (!NT_SUCCESS(status)) - TransmitterAbortPackets(Transmitter, HeadPacket); + __TransmitterCompletePackets(Transmitter, HeadPacket, NDIS_STATUS_NOT_ACCEPTED); } NDIS_LOWER_IRQL(Irql, DISPATCH_LEVEL); } -static VOID -TransmitterCompleteNetBufferList( - IN PTRANSMITTER Transmitter, - IN PNET_BUFFER_LIST NetBufferList - ) -{ - PADAPTER Adapter = Transmitter->Adapter; - PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO LargeSendInfo; - - ASSERT3P(NET_BUFFER_LIST_NEXT_NBL(NetBufferList), ==, NULL); - - LargeSendInfo = (PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO)&NET_BUFFER_LIST_INFO(NetBufferList, - TcpLargeSendNetBufferListInfo); - - if (LargeSendInfo->LsoV2Transmit.MSS != 0) - LargeSendInfo->LsoV2TransmitComplete.Reserved = 0; - - NET_BUFFER_LIST_STATUS(NetBufferList) = NDIS_STATUS_SUCCESS; - - NdisMSendNetBufferListsComplete(Adapter->NdisAdapterHandle, - NetBufferList, - NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL); -} - VOID TransmitterCompletePackets( - IN PTRANSMITTER Transmitter, + IN PXENNET_TRANSMITTER Transmitter, IN PXENVIF_TRANSMITTER_PACKET Packet ) { - while (Packet != NULL) { - PXENVIF_TRANSMITTER_PACKET Next; - PNET_BUFFER_RESERVED Reserved; - PNET_BUFFER_LIST NetBufferList; - PNET_BUFFER_LIST_RESERVED ListReserved; - - Next = Packet->Next; - Packet->Next = NULL; - - Reserved = CONTAINING_RECORD(Packet, NET_BUFFER_RESERVED, Packet); - - NetBufferList = Reserved->NetBufferList; - 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); + __TransmitterCompletePackets(Transmitter, Packet, NDIS_STATUS_SUCCESS); +} - Packet = Next; - } +PXENVIF_VIF_OFFLOAD_OPTIONS +TransmitterOffloadOptions( + IN PXENNET_TRANSMITTER Transmitter + ) +{ + return &Transmitter->OffloadOptions; } + diff --git a/src/xennet/transmitter.h b/src/xennet/transmitter.h index 8dc7e8d..f63a2a0 100644 --- a/src/xennet/transmitter.h +++ b/src/xennet/transmitter.h @@ -29,47 +29,47 @@ * SUCH DAMAGE. */ -#pragma once +#ifndef _XENNET_TRANSMITTER_H_ +#define _XENNET_TRANSMITTER_H_ -typedef struct _TRANSMITTER { - PADAPTER Adapter; - XENVIF_VIF_OFFLOAD_OPTIONS OffloadOptions; -} TRANSMITTER, *PTRANSMITTER; +#include <ndis.h> -VOID -TransmitterCleanup ( - IN OUT PTRANSMITTER* Transmitter - ); +typedef struct _XENNET_TRANSMITTER XENNET_TRANSMITTER, *PXENNET_TRANSMITTER; -NDIS_STATUS -TransmitterInitialize ( - IN PTRANSMITTER Transmitter, - IN PADAPTER Adapter +#include "adapter.h" +extern NDIS_STATUS +TransmitterInitialize( + IN PXENNET_ADAPTER Adapter, + OUT PXENNET_TRANSMITTER *Transmitter ); -VOID -TransmitterEnable ( - IN PTRANSMITTER Transmitter +extern VOID +TransmitterTeardown( + IN PXENNET_TRANSMITTER Transmitter ); -VOID -TransmitterDelete ( - IN OUT PTRANSMITTER* Transmitter +extern VOID +TransmitterEnable( + IN PXENNET_TRANSMITTER Transmitter ); -VOID +extern VOID TransmitterSendNetBufferLists ( - IN PTRANSMITTER Transmitter, + IN PXENNET_TRANSMITTER Transmitter, IN PNET_BUFFER_LIST NetBufferList, IN NDIS_PORT_NUMBER PortNumber, IN ULONG SendFlags ); -VOID +extern VOID TransmitterCompletePackets( - IN PTRANSMITTER Transmitter, + IN PXENNET_TRANSMITTER Transmitter, IN PXENVIF_TRANSMITTER_PACKET Packet ); -void TransmitterPause(PTRANSMITTER Transmitter); -void TransmitterUnpause(PTRANSMITTER Transmitter); +extern PXENVIF_VIF_OFFLOAD_OPTIONS +TransmitterOffloadOptions( + IN PXENNET_TRANSMITTER Transmitter + ); + +#endif // _XENNET_TRANSMITTER_H_ diff --git a/vs2012/xennet/xennet.vcxproj b/vs2012/xennet/xennet.vcxproj index aab91d2..03ddf91 100644 --- a/vs2012/xennet/xennet.vcxproj +++ b/vs2012/xennet/xennet.vcxproj @@ -84,8 +84,7 @@ </ItemGroup> <ItemGroup> <ClCompile Include="../../src/xennet/adapter.c" /> - <ClCompile Include="../../src/xennet/main.c" /> - <ClCompile Include="../../src/xennet/miniport.c" /> + <ClCompile Include="../../src/xennet/driver.c" /> <ClCompile Include="../../src/xennet/receiver.c" /> <ClCompile Include="../../src/xennet/transmitter.c" /> </ItemGroup> diff --git a/vs2013/xennet/xennet.vcxproj b/vs2013/xennet/xennet.vcxproj index 9401b99..60c79f7 100644 --- a/vs2013/xennet/xennet.vcxproj +++ b/vs2013/xennet/xennet.vcxproj @@ -115,8 +115,7 @@ </ItemGroup> <ItemGroup> <ClCompile Include="../../src/xennet/adapter.c" /> - <ClCompile Include="../../src/xennet/main.c" /> - <ClCompile Include="../../src/xennet/miniport.c" /> + <ClCompile Include="../../src/xennet/driver.c" /> <ClCompile Include="../../src/xennet/receiver.c" /> <ClCompile Include="../../src/xennet/transmitter.c" /> </ItemGroup> -- 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 |