[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH 1/4] Refactor for maintainability/coding style
Removes common headers and the disabling of warnings via #pragmas Fits code into driver.c (DriverEntry/Dispatch overrides), adapter.c (NDIS miniport). Resolves differences in receiver/transmitter implementations. Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx> --- src/xennet/adapter.c | 3833 +++++++++++++++++++----------------------- src/xennet/adapter.h | 154 +- src/xennet/common.h | 36 - src/xennet/driver.c | 550 ++++++ src/xennet/main.c | 361 ---- src/xennet/miniport.c | 297 ---- src/xennet/project.h | 66 - src/xennet/receiver.c | 393 +++-- src/xennet/receiver.h | 59 +- src/xennet/std.h | 45 - src/xennet/transmitter.c | 330 ++-- src/xennet/transmitter.h | 61 +- vs2012/xennet/xennet.vcxproj | 3 +- vs2013/xennet/xennet.vcxproj | 3 +- 14 files changed, 2770 insertions(+), 3421 deletions(-) delete mode 100644 src/xennet/common.h create mode 100644 src/xennet/driver.c delete mode 100644 src/xennet/main.c delete mode 100644 src/xennet/miniport.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..6b32d1a 100644 --- a/src/xennet/adapter.c +++ b/src/xennet/adapter.c @@ -28,51 +28,44 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ +#define INITGUID +#include <ndis.h> +#include <ntstrsafe.h> #include <version.h> -#include "common.h" -#pragma warning(disable:4711) +#include "adapter.h" +#include "registry.h" +#include "dbg_print.h" +#include "assert.h" -// -// List of supported OIDs. -// +struct _XENNET_ADAPTER { + XENVIF_VIF_INTERFACE VifInterface; -static NDIS_STATUS -AdapterSetRegistrationAttributes ( - IN PADAPTER Adapter - ); + BOOLEAN Enabled; + ULONG MaximumFrameSize; + ULONG CurrentLookahead; -static NDIS_STATUS -AdapterSetGeneralAttributes ( - IN PADAPTER Adapter - ); + NDIS_HANDLE NdisHandle; + NDIS_HANDLE NdisDmaHandle; + NDIS_PNP_CAPABILITIES Capabilities; + NDIS_OFFLOAD Offload; + XENNET_PROPERTIES Properties; -static NDIS_STATUS -AdapterSetOffloadAttributes ( - IN PADAPTER Adapter - ); + PXENNET_RECEIVER Receiver; + PXENNET_TRANSMITTER Transmitter; +}; -static MINIPORT_PROCESS_SG_LIST AdapterProcessSGList; -static VOID -AdapterProcessSGList ( - IN PDEVICE_OBJECT DeviceObject, - IN PVOID Reserved, - IN PSCATTER_GATHER_LIST SGL, - IN PVOID Context - ); +#define XENNET_POOL_TAG 'tenX' -static NDIS_STATUS -AdapterSetInformation ( - IN PADAPTER Adapter, - IN PNDIS_OID_REQUEST NdisRequest - ); +#define XENNET_MEDIA_MAX_SPEED 1000000000ull -static NDIS_STATUS -AdapterQueryInformation ( - IN PADAPTER Adapter, - IN PNDIS_OID_REQUEST NdisRequest - ); +#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) static NDIS_OID XennetSupportedOids[] = { @@ -129,31 +122,9 @@ 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) - -NTSTATUS AllocAdapter(OUT PADAPTER *Adapter) -{ - if (Adapter == NULL) - return STATUS_INVALID_PARAMETER; - - *Adapter = (PADAPTER)ExAllocatePoolWithTag(NonPagedPool, sizeof (ADAPTER), ' TEN'); - if (*Adapter == NULL) - return STATUS_INSUFFICIENT_RESOURCES; - - return STATUS_SUCCESS; -} - -// -// Scatter gather allocate handler callback. -// Should never get called. -// __drv_functionClass(MINIPORT_ALLOCATE_SHARED_MEM_COMPLETE) static VOID -AdapterAllocateComplete ( +AdapterAllocateComplete( IN NDIS_HANDLE MiniportAdapterContext, IN PVOID VirtualAddress, IN PNDIS_PHYSICAL_ADDRESS PhysicalAddress, @@ -168,139 +139,33 @@ 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; } +__drv_functionClass(MINIPORT_PROCESS_SG_LIST) static VOID -AdapterMediaStateChange( - IN PADAPTER Adapter +AdapterProcessSGList( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Reserved, + IN PSCATTER_GATHER_LIST SGL, + IN PVOID Context ) { - 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); + UNREFERENCED_PARAMETER(DeviceObject); + UNREFERENCED_PARAMETER(Reserved); + UNREFERENCED_PARAMETER(SGL); + UNREFERENCED_PARAMETER(Context); - NdisMIndicateStatusEx(Adapter->NdisAdapterHandle, &StatusIndication); + ASSERT(FALSE); } - -// -// 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; + PXENNET_ADAPTER Adapter = Context; va_list Arguments; va_start(Arguments, Type); @@ -319,7 +184,7 @@ AdapterVifCallback( List = va_arg(Arguments, PLIST_ENTRY); - ReceiverReceivePackets(&Adapter->Receiver, List); + ReceiverReceivePackets(Adapter->Receiver, List); break; } case XENVIF_MAC_STATE_CHANGE: { @@ -331,39 +196,220 @@ AdapterVifCallback( va_end(Arguments); } -NDIS_STATUS -AdapterGetAdvancedSettings( - IN PADAPTER pAdapter +#define SERVICES_KEY L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services" + +static FORCEINLINE NTSTATUS +__QueryInterface( + IN PDEVICE_OBJECT DeviceObject, + IN const WCHAR *ProviderName, + IN const CHAR *InterfaceName, + IN const GUID *Guid, + IN ULONG Version, + OUT PINTERFACE Interface, + IN ULONG Size, + IN BOOLEAN Optional ) { - NDIS_CONFIGURATION_OBJECT configObject; - NDIS_HANDLE hConfigurationHandle; - NDIS_STRING ndisValue; - PNDIS_CONFIGURATION_PARAMETER pNdisData; - NDIS_STATUS ndisStatus; - NTSTATUS status; + UNICODE_STRING Unicode; + HANDLE InterfacesKey; + HANDLE SubscriberKey; + KEVENT Event; + IO_STATUS_BLOCK StatusBlock; + PIRP Irp; + PIO_STACK_LOCATION StackLocation; + NTSTATUS status; + + ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL); + + Unicode.MaximumLength = (USHORT)((wcslen(SERVICES_KEY) + + 1 + + wcslen(ProviderName) + + 1 + + wcslen(L"Interfaces") + + 1) * sizeof (WCHAR)); + + Unicode.Buffer = ExAllocatePoolWithTag(NonPagedPool, + Unicode.MaximumLength, + 'TEN'); + + status = STATUS_NO_MEMORY; + if (Unicode.Buffer == NULL) + goto fail1; + + status = RtlStringCbPrintfW(Unicode.Buffer, + Unicode.MaximumLength, + SERVICES_KEY L"\\%ws\\Interfaces", + ProviderName); + ASSERT(NT_SUCCESS(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; + Unicode.Length = (USHORT)(wcslen(Unicode.Buffer) * sizeof (WCHAR)); - ndisStatus = NdisOpenConfigurationEx(&configObject, &hConfigurationHandle); + status = RegistryOpenKey(NULL, &Unicode, KEY_READ, &InterfacesKey); + if (!NT_SUCCESS(status)) + goto fail2; + + status = RegistryCreateSubKey(InterfacesKey, + "XENNET", + REG_OPTION_NON_VOLATILE, + &SubscriberKey); + if (!NT_SUCCESS(status)) + goto fail3; + + KeInitializeEvent(&Event, NotificationEvent, FALSE); + RtlZeroMemory(&StatusBlock, sizeof(IO_STATUS_BLOCK)); + + Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, + DeviceObject, + NULL, + 0, + NULL, + &Event, + &StatusBlock); status = STATUS_UNSUCCESSFUL; - if (ndisStatus != NDIS_STATUS_SUCCESS) + if (Irp == NULL) + goto fail4; + + StackLocation = IoGetNextIrpStackLocation(Irp); + StackLocation->MinorFunction = IRP_MN_QUERY_INTERFACE; + + 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; + } + + if (!NT_SUCCESS(status)) { + if (status == STATUS_NOT_SUPPORTED && Optional) + goto done; + + goto fail5; + } + + status = RegistryUpdateDwordValue(SubscriberKey, + (PCHAR)InterfaceName, + Version); + if (!NT_SUCCESS(status)) + goto fail6; + +done: + RegistryCloseKey(SubscriberKey); + + RegistryCloseKey(InterfacesKey); + + ExFreePool(Unicode.Buffer); + + return STATUS_SUCCESS; + +fail6: + Error("fail6\n"); + +fail5: + Error("fail5\n"); + +fail4: + Error("fail4\n"); + + RegistryCloseKey(SubscriberKey); + +fail3: + Error("fail3\n"); + + RegistryCloseKey(InterfacesKey); + +fail2: + Error("fail2\n"); + + ExFreePool(Unicode.Buffer); + +fail1: + Error("fail1 (%08x)\n", status); + + return status; +} + +#define QUERY_INTERFACE( \ + _DeviceObject, \ + _ProviderName, \ + _InterfaceName, \ + _Version, \ + _Interface, \ + _Size, \ + _Optional) \ + __QueryInterface((_DeviceObject), \ + L ## #_ProviderName, \ + #_InterfaceName, \ + &GUID_ ## _ProviderName ## _ ## _InterfaceName ## _INTERFACE, \ + (_Version), \ + (_Interface), \ + (_Size), \ + (_Optional)) + +static FORCEINLINE NDIS_STATUS +AdapterSetRegistrationAttributes( + IN PXENNET_ADAPTER Adapter + ) +{ + NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES Attribs; + NDIS_STATUS status; + + RtlZeroMemory(&Attribs, sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES)); + Attribs.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES; + Attribs.Header.Size = sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES); + Attribs.Header.Revision = NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1; + 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; + + status = NdisMSetMiniportAttributes(Adapter->NdisHandle, + (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs); + return status; +} + +static FORCEINLINE NDIS_STATUS +AdapterGetAdvancedSettings( + IN PXENNET_ADAPTER Adapter + ) +{ + NDIS_CONFIGURATION_OBJECT Config; + NDIS_HANDLE Handle; + NDIS_STRING Value; + PNDIS_CONFIGURATION_PARAMETER Data; + NDIS_STATUS NdisStatus; + + RtlZeroMemory(&Config, sizeof(NDIS_CONFIGURATION_OBJECT)); + Config.Header.Type = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT; + Config.Header.Size = NDIS_SIZEOF_CONFIGURATION_OBJECT_REVISION_1; + Config.Header.Revision = NDIS_CONFIGURATION_OBJECT_REVISION_1; + Config.NdisHandle = Adapter->NdisHandle; + Config.Flags = 0; + + NdisStatus = NdisOpenConfigurationEx(&Config, &Handle); + 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; \ - } \ +#define read_property(_field, _name, _default_val) \ + do { \ + RtlInitUnicodeString(&Value, _name); \ + NdisReadConfiguration(&NdisStatus, &Data, Handle, &Value, NdisParameterInteger); \ + if (NdisStatus == NDIS_STATUS_SUCCESS) { \ + Adapter->Properties._field = Data->ParameterData.IntegerData; \ + } else { \ + Adapter->Properties._field = _default_val; \ + } \ } while (FALSE); read_property(ipv4_csum, L"*IPChecksumOffloadIPv4", 3); @@ -377,465 +423,827 @@ AdapterGetAdvancedSettings( read_property(lrov6, L"LROIPv6", 1); read_property(need_csum_value, L"NeedChecksumValue", 1); - NdisCloseConfiguration(hConfigurationHandle); - + NdisCloseConfiguration(Handle); return NDIS_STATUS_SUCCESS; fail1: - Error("fail1\n"); - return NDIS_STATUS_FAILURE; + Error("fail1 (%08x)\n", NdisStatus); + return NdisStatus; } -NDIS_STATUS -AdapterInitialize ( - IN PADAPTER Adapter, - IN NDIS_HANDLE AdapterHandle +static FORCEINLINE NDIS_STATUS +AdapterSetGeneralAttributes( + IN PXENNET_ADAPTER Adapter ) { - NDIS_STATUS ndisStatus; - NDIS_SG_DMA_DESCRIPTION DmaDescription; - NTSTATUS status; - - status = XENVIF_VIF(Acquire, &Adapter->VifInterface); - if (!NT_SUCCESS(status)) - return NDIS_STATUS_FAILURE; + NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES Attribs; - Adapter->AcquiredInterfaces = TRUE; + XENVIF_VIF(MacQueryMaximumFrameSize, + &Adapter->VifInterface, + (PULONG)&Adapter->MaximumFrameSize); - Trace("====>\n"); + RtlZeroMemory(&Attribs, sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES)); + + Attribs.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES; + Attribs.Header.Size = sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES); + Attribs.Header.Revision = NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_1; + Attribs.MediaType = XENNET_MEDIA_TYPE; + 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; + 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; + Attribs.SupportedOidList = XennetSupportedOids; + Attribs.SupportedOidListLength = sizeof(XennetSupportedOids); - Adapter->NdisAdapterHandle = AdapterHandle; + XENVIF_VIF(MacQueryPermanentAddress, + &Adapter->VifInterface, + (PETHERNET_ADDRESS)&Attribs.PermanentMacAddress); + XENVIF_VIF(MacQueryCurrentAddress, + &Adapter->VifInterface, + (PETHERNET_ADDRESS)&Attribs.CurrentMacAddress); - RtlZeroMemory(&Adapter->Capabilities, sizeof (Adapter->Capabilities)); + return NdisMSetMiniportAttributes(Adapter->NdisHandle, + (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs); +} - Adapter->Transmitter = (PTRANSMITTER)ExAllocatePoolWithTag(NonPagedPool, sizeof(TRANSMITTER), ' TEN'); - if (!Adapter->Transmitter) { - ndisStatus = NDIS_STATUS_RESOURCES; - goto exit; +static FORCEINLINE NDIS_STATUS +AdapterSetOffloadAttributes( + IN PXENNET_ADAPTER Adapter + ) +{ + NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES Attribs; + PXENVIF_VIF_OFFLOAD_OPTIONS RxOptions; + PXENVIF_VIF_OFFLOAD_OPTIONS TxOptions; + NDIS_OFFLOAD Default; + NDIS_OFFLOAD Supported; + + RxOptions = ReceiverOffloadOptions(Adapter->Receiver); + RxOptions->Value = 0; + RxOptions->OffloadTagManipulation = 1; + + if (Adapter->Properties.need_csum_value) { + RxOptions->NeedChecksumValue = 1; } - - RtlZeroMemory(Adapter->Transmitter, sizeof (TRANSMITTER)); - - ndisStatus = ReceiverInitialize(&Adapter->Receiver); - if (ndisStatus != NDIS_STATUS_SUCCESS) { - goto exit; + if (Adapter->Properties.lrov4) { + RxOptions->OffloadIpVersion4LargePacket = 1; + RxOptions->NeedLargePacketSplit = 1; } - - ndisStatus = TransmitterInitialize(Adapter->Transmitter, Adapter); - if (ndisStatus != NDIS_STATUS_SUCCESS) { - goto exit; + if (Adapter->Properties.lrov6) { + RxOptions->OffloadIpVersion6LargePacket = 1; + RxOptions->NeedLargePacketSplit = 1; } + XENVIF_VIF(ReceiverSetOffloadOptions, + &Adapter->VifInterface, + *RxOptions); - ndisStatus = AdapterGetAdvancedSettings(Adapter); - if (ndisStatus != NDIS_STATUS_SUCCESS) { - goto exit; + TxOptions = TransmitterOffloadOptions(Adapter->Transmitter); + XENVIF_VIF(TransmitterQueryOffloadOptions, + &Adapter->VifInterface, + TxOptions); + + RtlZeroMemory(&Supported, sizeof(NDIS_OFFLOAD)); + Supported.Header.Type = NDIS_OBJECT_TYPE_OFFLOAD; + Supported.Header.Size = sizeof(NDIS_OFFLOAD); + Supported.Header.Revision = NDIS_OFFLOAD_REVISION_1; + + Supported.Checksum.IPv4Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; + Supported.Checksum.IPv4Receive.IpChecksum = 1; + Supported.Checksum.IPv4Receive.IpOptionsSupported = 1; + Supported.Checksum.IPv4Receive.TcpChecksum = 1; + Supported.Checksum.IPv4Receive.TcpOptionsSupported = 1; + Supported.Checksum.IPv4Receive.UdpChecksum = 1; + + Supported.Checksum.IPv6Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; + Supported.Checksum.IPv6Receive.IpExtensionHeadersSupported = 1; + Supported.Checksum.IPv6Receive.TcpChecksum = 1; + Supported.Checksum.IPv6Receive.TcpOptionsSupported = 1; + Supported.Checksum.IPv6Receive.UdpChecksum = 1; + + Supported.Checksum.IPv4Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; + if (TxOptions->OffloadIpVersion4HeaderChecksum) { + Supported.Checksum.IPv4Transmit.IpChecksum = 1; + Supported.Checksum.IPv4Transmit.IpOptionsSupported = 1; } - - ndisStatus = AdapterSetRegistrationAttributes(Adapter); - if (ndisStatus != NDIS_STATUS_SUCCESS) { - goto exit; + if (TxOptions->OffloadIpVersion4TcpChecksum) { + Supported.Checksum.IPv4Transmit.TcpChecksum = 1; + Supported.Checksum.IPv4Transmit.TcpOptionsSupported = 1; + } + if (TxOptions->OffloadIpVersion4UdpChecksum) { + Supported.Checksum.IPv4Transmit.UdpChecksum = 1; } - ndisStatus = AdapterSetGeneralAttributes(Adapter); - if (ndisStatus != NDIS_STATUS_SUCCESS) { - goto exit; + Supported.Checksum.IPv6Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; + Supported.Checksum.IPv6Transmit.IpExtensionHeadersSupported = 1; + if (TxOptions->OffloadIpVersion6TcpChecksum) { + Supported.Checksum.IPv6Transmit.TcpChecksum = 1; + Supported.Checksum.IPv6Transmit.TcpOptionsSupported = 1; + } + if (TxOptions->OffloadIpVersion6UdpChecksum) { + Supported.Checksum.IPv6Transmit.UdpChecksum = 1; } - ndisStatus = AdapterSetOffloadAttributes(Adapter); - if (ndisStatus != NDIS_STATUS_SUCCESS) { - goto exit; + if (TxOptions->OffloadIpVersion4LargePacket) { + XENVIF_VIF(TransmitterQueryLargePacketSize, + &Adapter->VifInterface, + 4, + &Supported.LsoV2.IPv4.MaxOffLoadSize); + Supported.LsoV2.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; + Supported.LsoV2.IPv4.MinSegmentCount = 2; } - NdisZeroMemory(&DmaDescription, sizeof(DmaDescription)); + if (TxOptions->OffloadIpVersion6LargePacket) { + XENVIF_VIF(TransmitterQueryLargePacketSize, + &Adapter->VifInterface, + 6, + &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; + } - 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; + Default = Supported; - ndisStatus = NdisMRegisterScatterGatherDma(Adapter->NdisAdapterHandle, - &DmaDescription, - &Adapter->NdisDmaHandle); - if (ndisStatus != NDIS_STATUS_SUCCESS) - Adapter->NdisDmaHandle = NULL; + if (!(Adapter->Properties.ipv4_csum & 2)) + Default.Checksum.IPv4Receive.IpChecksum = 0; + if (!(Adapter->Properties.tcpv4_csum & 2)) + Default.Checksum.IPv4Receive.TcpChecksum = 0; + if (!(Adapter->Properties.udpv4_csum & 2)) + Default.Checksum.IPv4Receive.UdpChecksum = 0; + if (!(Adapter->Properties.tcpv6_csum & 2)) + Default.Checksum.IPv6Receive.TcpChecksum = 0; + if (!(Adapter->Properties.udpv6_csum & 2)) + Default.Checksum.IPv6Receive.UdpChecksum = 0; + if (!(Adapter->Properties.ipv4_csum & 1)) + Default.Checksum.IPv4Transmit.IpChecksum = 0; + if (!(Adapter->Properties.tcpv4_csum & 1)) + Default.Checksum.IPv4Transmit.TcpChecksum = 0; + if (!(Adapter->Properties.udpv4_csum & 1)) + Default.Checksum.IPv4Transmit.UdpChecksum = 0; + if (!(Adapter->Properties.tcpv6_csum & 1)) + Default.Checksum.IPv6Transmit.TcpChecksum = 0; + if (!(Adapter->Properties.udpv6_csum & 1)) + Default.Checksum.IPv6Transmit.UdpChecksum = 0; + if (!(Adapter->Properties.lsov4)) { + Default.LsoV2.IPv4.MaxOffLoadSize = 0; + Default.LsoV2.IPv4.MinSegmentCount = 0; + } + if (!(Adapter->Properties.lsov6)) { + Default.LsoV2.IPv6.MaxOffLoadSize = 0; + Default.LsoV2.IPv6.MinSegmentCount = 0; + } - 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, &Default, sizeof(NDIS_OFFLOAD))) { + Adapter->Offload = Default; + //DISPLAY_OFFLOAD(Default); } -exit: - if (ndisStatus != NDIS_STATUS_SUCCESS) - XENVIF_VIF(Release, &Adapter->VifInterface); + RtlZeroMemory(&Attribs, sizeof(Attribs)); + Attribs.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES; + Attribs.Header.Size = sizeof(Attribs); + Attribs.Header.Revision = NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES_REVISION_1; + Attribs.DefaultOffloadConfiguration = &Default; + Attribs.HardwareOffloadCapabilities = &Supported; - Trace("<==== (%08x)\n", ndisStatus); - return ndisStatus; + return NdisMSetMiniportAttributes(Adapter->NdisHandle, + (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs); } -// -// 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 +AdapterIndicateOffloadChanged( + IN PXENNET_ADAPTER Adapter ) { - UNREFERENCED_PARAMETER(DeviceObject); - UNREFERENCED_PARAMETER(Reserved); - UNREFERENCED_PARAMETER(SGL); - UNREFERENCED_PARAMETER(Context); - - ASSERT(FALSE); - - return; -} + NDIS_STATUS_INDICATION Indication; + NDIS_OFFLOAD Offload; + PXENVIF_VIF_OFFLOAD_OPTIONS RxOptions; + PXENVIF_VIF_OFFLOAD_OPTIONS TxOptions; -// -// Get\Set OID handler. -// -NDIS_STATUS -AdapterOidRequest ( - IN NDIS_HANDLE NdisHandle, - IN PNDIS_OID_REQUEST NdisRequest - ) -{ - NDIS_STATUS ndisStatus; - PADAPTER Adapter = (PADAPTER)NdisHandle; + RxOptions = ReceiverOffloadOptions(Adapter->Receiver); - switch (NdisRequest->RequestType) { - case NdisRequestSetInformation: - ndisStatus = AdapterSetInformation(Adapter, NdisRequest); - break; - - case NdisRequestQueryInformation: - case NdisRequestQueryStatistics: - ndisStatus = AdapterQueryInformation(Adapter, NdisRequest); - break; + RtlZeroMemory(&Offload, sizeof(NDIS_OFFLOAD)); + Offload.Header.Type = NDIS_OBJECT_TYPE_OFFLOAD; + Offload.Header.Size = sizeof(NDIS_OFFLOAD); + Offload.Header.Revision = NDIS_OFFLOAD_REVISION_1; + + Offload.Checksum.IPv4Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; + 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; + } - default: - ndisStatus = NDIS_STATUS_NOT_SUPPORTED; - break; - }; + Offload.Checksum.IPv6Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; + Offload.Checksum.IPv6Receive.IpExtensionHeadersSupported = 1; + if (RxOptions->OffloadIpVersion6TcpChecksum) { + Offload.Checksum.IPv6Receive.TcpChecksum = 1; + Offload.Checksum.IPv6Receive.TcpOptionsSupported = 1; + } + if (RxOptions->OffloadIpVersion6UdpChecksum) { + Offload.Checksum.IPv6Receive.UdpChecksum = 1; + } - return ndisStatus; -} + XENVIF_VIF(ReceiverSetOffloadOptions, + &Adapter->VifInterface, + *RxOptions); -// -// Temporarily pauses adapter. -// -NDIS_STATUS -AdapterPause ( - IN NDIS_HANDLE NdisHandle, - IN PNDIS_MINIPORT_PAUSE_PARAMETERS MiniportPauseParameters - ) -{ - PADAPTER Adapter = (PADAPTER)NdisHandle; - UNREFERENCED_PARAMETER(MiniportPauseParameters); + TxOptions = TransmitterOffloadOptions(Adapter->Transmitter); - Trace("====>\n"); + Offload.Checksum.IPv4Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; + if (TxOptions->OffloadIpVersion4HeaderChecksum) { + Offload.Checksum.IPv4Transmit.IpChecksum = 1; + Offload.Checksum.IPv4Transmit.IpOptionsSupported = 1; + } + if (TxOptions->OffloadIpVersion4TcpChecksum) { + Offload.Checksum.IPv4Transmit.TcpChecksum = 1; + Offload.Checksum.IPv4Transmit.TcpOptionsSupported = 1; + } + if (TxOptions->OffloadIpVersion4UdpChecksum) { + Offload.Checksum.IPv4Transmit.UdpChecksum = 1; + } - if (!Adapter->Enabled) - goto done; + Offload.Checksum.IPv6Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; + Offload.Checksum.IPv6Transmit.IpExtensionHeadersSupported = 1; + if (TxOptions->OffloadIpVersion6TcpChecksum) { + Offload.Checksum.IPv6Transmit.TcpChecksum = 1; + Offload.Checksum.IPv6Transmit.TcpOptionsSupported = 1; + } + if (TxOptions->OffloadIpVersion6UdpChecksum) { + Offload.Checksum.IPv6Transmit.UdpChecksum = 1; + } - XENVIF_VIF(Disable, - &Adapter->VifInterface); + 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; + } + 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; + } - AdapterMediaStateChange(Adapter); + if (!RtlEqualMemory(&Adapter->Offload, &Offload, sizeof (NDIS_OFFLOAD))) { + Adapter->Offload = Offload; + //DISPLAY_OFFLOAD(Offload); + } - Adapter->Enabled = FALSE; + RtlZeroMemory(&Indication, sizeof(Indication)); + Indication.Header.Type = NDIS_OBJECT_TYPE_STATUS_INDICATION; + Indication.Header.Size = sizeof(Indication); + Indication.Header.Revision = NDIS_STATUS_INDICATION_REVISION_1; + Indication.SourceHandle = Adapter->NdisHandle; + Indication.StatusCode = NDIS_STATUS_TASK_OFFLOAD_CURRENT_CONFIG; + Indication.StatusBuffer = &Offload; + Indication.StatusBufferSize = sizeof(Offload); -done: - Trace("<====\n"); - return NDIS_STATUS_SUCCESS; + NdisMIndicateStatusEx(Adapter->NdisHandle, &Indication); } -// -// Handles PNP and Power events. NOP. -// -VOID -AdapterPnPEventHandler ( - IN NDIS_HANDLE NdisHandle, - IN PNET_DEVICE_PNP_EVENT NetDevicePnPEvent +static NDIS_STATUS +AdapterSetPacketFilter( + IN PXENNET_ADAPTER Adapter, + IN PULONG PacketFilter ) { - UNREFERENCED_PARAMETER(NdisHandle); + 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; - switch (NetDevicePnPEvent->DevicePnPEvent) { - case NdisDevicePnPEventQueryRemoved: - break; + if (*PacketFilter & NDIS_PACKET_TYPE_PROMISCUOUS) { + UnicastFilterLevel = XENVIF_MAC_FILTER_ALL; + MulticastFilterLevel = XENVIF_MAC_FILTER_ALL; + BroadcastFilterLevel = XENVIF_MAC_FILTER_ALL; + goto done; + } - case NdisDevicePnPEventRemoved: - break; + if (*PacketFilter & NDIS_PACKET_TYPE_DIRECTED) + UnicastFilterLevel = XENVIF_MAC_FILTER_MATCHING; + else + UnicastFilterLevel = XENVIF_MAC_FILTER_NONE; - case NdisDevicePnPEventSurpriseRemoved: - break; + 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; - case NdisDevicePnPEventQueryStopped: - break; + if (*PacketFilter & NDIS_PACKET_TYPE_BROADCAST) + BroadcastFilterLevel = XENVIF_MAC_FILTER_ALL; + else + BroadcastFilterLevel = XENVIF_MAC_FILTER_NONE; - case NdisDevicePnPEventStopped: - break; - - case NdisDevicePnPEventPowerProfileChanged: - break; - - default: - break; - }; +done: + 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; + return NDIS_STATUS_SUCCESS; } -// -// Reports general statistics to NDIS. -// -static NDIS_STATUS -AdapterQueryGeneralStatistics ( - IN PADAPTER Adapter, - IN PNDIS_STATISTICS_INFO NdisStatisticsInfo +static NDIS_STATUS +AdapterSetMulticastAddresses( + IN PXENNET_ADAPTER Adapter, + IN PETHERNET_ADDRESS Address, + IN ULONG Count ) { - NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS; - ULONGLONG Value; - - 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); + NTSTATUS status; - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_RCV_ERROR; + status = XENVIF_VIF(MacSetMulticastAddresses, + &Adapter->VifInterface, + Address, + Count); + if (!NT_SUCCESS(status)) + return NDIS_STATUS_INVALID_DATA; - (VOID) XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_RECEIVER_BACKEND_ERRORS, - &Value); + return NDIS_STATUS_SUCCESS; +} - NdisStatisticsInfo->ifInErrors = Value; +static NDIS_STATUS +AdapterSetOffloadEncapsulation( + IN PXENNET_ADAPTER Adapter, + IN PNDIS_OFFLOAD_ENCAPSULATION Encapsulation + ) +{ + XENVIF_VIF_OFFLOAD_OPTIONS Options; + PXENVIF_VIF_OFFLOAD_OPTIONS TxOptions; + PXENVIF_VIF_OFFLOAD_OPTIONS RxOptions; - (VOID) XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_RECEIVER_FRONTEND_ERRORS, - &Value); + if (Encapsulation->IPv4.Enabled == NDIS_OFFLOAD_SET_ON && + Encapsulation->IPv4.EncapsulationType != NDIS_ENCAPSULATION_IEEE_802_3) + goto fail1; + if (Encapsulation->IPv6.Enabled == NDIS_OFFLOAD_SET_ON && + Encapsulation->IPv6.EncapsulationType != NDIS_ENCAPSULATION_IEEE_802_3) + goto fail2; - NdisStatisticsInfo->ifInErrors += Value; + XENVIF_VIF(TransmitterQueryOffloadOptions, + &Adapter->VifInterface, + &Options); - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_RCV_DISCARDS; + 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; - (VOID) XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_RECEIVER_PACKETS_DROPPED, - &Value); + if (Adapter->Properties.need_csum_value) + RxOptions->NeedChecksumValue = 1; + if (Adapter->Properties.lrov4) { + RxOptions->OffloadIpVersion4LargePacket = 1; + RxOptions->NeedLargePacketSplit = 1; + } + if (Adapter->Properties.lrov6) { + RxOptions->OffloadIpVersion6LargePacket = 1; + 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; - NdisStatisticsInfo->ifInDiscards = Value; +fail2: + Error("fail2\n"); +fail1: + Error("fail1 (%08x)\n", NDIS_STATUS_INVALID_PARAMETER); + return NDIS_STATUS_INVALID_PARAMETER; +} - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BYTES_RCV; +static NDIS_STATUS +AdapterSetTcpOffloadParameters( + IN PXENNET_ADAPTER Adapter, + IN PNDIS_OFFLOAD_PARAMETERS Parameters + ) +{ + BOOLEAN Changed = FALSE; + PXENVIF_VIF_OFFLOAD_OPTIONS TxOptions; + PXENVIF_VIF_OFFLOAD_OPTIONS RxOptions; + + if (Parameters->IPsecV1 != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE || + Parameters->LsoV1 != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE || + Parameters->TcpConnectionIPv4 != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE || + Parameters->TcpConnectionIPv6 != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE) { + goto fail1; + } + if (Parameters->LsoV2IPv4 != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE) { + XENVIF_VIF_OFFLOAD_OPTIONS Options; - (VOID) XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_RECEIVER_UNICAST_OCTETS, - &Value); + XENVIF_VIF(TransmitterQueryOffloadOptions, + &Adapter->VifInterface, + &Options); - NdisStatisticsInfo->ifHCInOctets = Value; + if (!(Options.OffloadIpVersion4LargePacket)) + goto fail2; + } + if (Parameters->LsoV2IPv6 != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE) { + XENVIF_VIF_OFFLOAD_OPTIONS Options; - (VOID) XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_RECEIVER_MULTICAST_OCTETS, - &Value); + XENVIF_VIF(TransmitterQueryOffloadOptions, + &Adapter->VifInterface, + &Options); - NdisStatisticsInfo->ifHCInOctets += Value; + if (!(Options.OffloadIpVersion6LargePacket)) + goto fail3; + } - (VOID) XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_RECEIVER_BROADCAST_OCTETS, - &Value); + TxOptions = TransmitterOffloadOptions(Adapter->Transmitter); + RxOptions = ReceiverOffloadOptions(Adapter->Receiver); - NdisStatisticsInfo->ifHCInOctets += Value; +#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 set_value(x, y) ((x) == (y)) ? FALSE : ( ((x) = (y)) == (y) ) - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_RCV; + if (Parameters->LsoV2IPv4 == NDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED) { + Changed |= set_value(TxOptions->OffloadIpVersion4LargePacket, 1); + } else if (Parameters->LsoV2IPv4 == NDIS_OFFLOAD_PARAMETERS_LSOV2_DISABLED) { + Changed |= set_value(TxOptions->OffloadIpVersion4LargePacket, 0); + } - (VOID) XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_RECEIVER_UNICAST_OCTETS, - &Value); + if (Parameters->LsoV2IPv6 == NDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED) { + Changed |= set_value(TxOptions->OffloadIpVersion6LargePacket, 1); + } else if (Parameters->LsoV2IPv6 == NDIS_OFFLOAD_PARAMETERS_LSOV2_DISABLED) { + Changed |= set_value(TxOptions->OffloadIpVersion6LargePacket, 0); + } - NdisStatisticsInfo->ifHCInUcastOctets = Value; + if (tx_enabled(Parameters->IPv4Checksum)) { + Changed |= set_value(TxOptions->OffloadIpVersion4HeaderChecksum, 1); + } else { + Changed |= set_value(TxOptions->OffloadIpVersion4HeaderChecksum, 0); + } - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_RCV; + if (tx_enabled(Parameters->TCPIPv4Checksum)) { + Changed |= set_value(TxOptions->OffloadIpVersion4TcpChecksum, 1); + } else { + Changed |= set_value(TxOptions->OffloadIpVersion4TcpChecksum, 0); + } - (VOID) XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_RECEIVER_UNICAST_PACKETS, - &Value); + if (tx_enabled(Parameters->UDPIPv4Checksum)) { + Changed |= set_value(TxOptions->OffloadIpVersion4UdpChecksum, 1); + } else { + Changed |= set_value(TxOptions->OffloadIpVersion4UdpChecksum, 0); + } - NdisStatisticsInfo->ifHCInUcastPkts = Value; + if (tx_enabled(Parameters->TCPIPv6Checksum)) { + Changed |= set_value(TxOptions->OffloadIpVersion6TcpChecksum, 1); + } else { + Changed |= set_value(TxOptions->OffloadIpVersion6TcpChecksum, 0); + } - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_RCV; + if (tx_enabled(Parameters->UDPIPv6Checksum)) { + Changed |= set_value(TxOptions->OffloadIpVersion6UdpChecksum, 1); + } else { + Changed |= set_value(TxOptions->OffloadIpVersion6UdpChecksum, 0); + } - (VOID) XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_RECEIVER_MULTICAST_OCTETS, - &Value); + if (rx_enabled(Parameters->IPv4Checksum)) { + Changed |= set_value(RxOptions->OffloadIpVersion4HeaderChecksum, 1); + } else { + Changed |= set_value(RxOptions->OffloadIpVersion4HeaderChecksum, 0); + } - NdisStatisticsInfo->ifHCInMulticastOctets = Value; + if (rx_enabled(Parameters->TCPIPv4Checksum)) { + Changed |= set_value(RxOptions->OffloadIpVersion4TcpChecksum, 1); + } else { + Changed |= set_value(RxOptions->OffloadIpVersion4TcpChecksum, 0); + } - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_MULTICAST_FRAMES_RCV; + if (rx_enabled(Parameters->UDPIPv4Checksum)) { + Changed |= set_value(RxOptions->OffloadIpVersion4UdpChecksum, 1); + } else { + Changed |= set_value(RxOptions->OffloadIpVersion4UdpChecksum, 0); + } - (VOID) XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_RECEIVER_MULTICAST_PACKETS, - &Value); + if (rx_enabled(Parameters->TCPIPv6Checksum)) { + Changed |= set_value(RxOptions->OffloadIpVersion6TcpChecksum, 1); + } else { + Changed |= set_value(RxOptions->OffloadIpVersion6TcpChecksum, 0); + } - NdisStatisticsInfo->ifHCInMulticastPkts = Value; + if (rx_enabled(Parameters->UDPIPv6Checksum)) { + Changed |= set_value(RxOptions->OffloadIpVersion6UdpChecksum, 1); + } else { + Changed |= set_value(RxOptions->OffloadIpVersion6UdpChecksum, 0); + } - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_RCV; +#undef tx_enabled +#undef rx_enabled +#undef set_value - (VOID) XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_RECEIVER_BROADCAST_OCTETS, - &Value); + if (Changed) + AdapterIndicateOffloadChanged(Adapter); - NdisStatisticsInfo->ifHCInBroadcastOctets = Value; + return NDIS_STATUS_SUCCESS; - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BROADCAST_FRAMES_RCV; +fail3: + Error("fail3\n"); +fail2: + Error("fail2\n"); +fail1: + Error("fail1 (%08x)\n", NDIS_STATUS_INVALID_PARAMETER); + return NDIS_STATUS_INVALID_PARAMETER; +} - (VOID) XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_RECEIVER_BROADCAST_PACKETS, - &Value); +static NDIS_STATUS +AdapterSetInformation( + IN PXENNET_ADAPTER Adapter, + IN PNDIS_OID_REQUEST Request + ) +{ + PVOID Buffer; + ULONG BufferLength; + ULONG BytesNeeded = 0; + ULONG BytesRead = 0; + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - NdisStatisticsInfo->ifHCInBroadcastPkts = Value; + Buffer = Request->DATA.SET_INFORMATION.InformationBuffer; + BufferLength = Request->DATA.SET_INFORMATION.InformationBufferLength; - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_XMIT_ERROR; + switch (Request->DATA.QUERY_INFORMATION.Oid) { + case OID_PNP_SET_POWER: + BytesNeeded = sizeof(NDIS_DEVICE_POWER_STATE); + break; - (VOID) XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_TRANSMITTER_BACKEND_ERRORS, - &Value); + case OID_GEN_CURRENT_LOOKAHEAD: + BytesNeeded = sizeof(ULONG); + Adapter->CurrentLookahead = Adapter->MaximumFrameSize; + if (BufferLength == sizeof(ULONG)) { + Adapter->CurrentLookahead = *(PULONG)Buffer; + BytesRead = sizeof(ULONG); + } + break; - NdisStatisticsInfo->ifOutErrors = Value; + case OID_GEN_CURRENT_PACKET_FILTER: + BytesNeeded = sizeof(ULONG); + if (BufferLength == sizeof(ULONG)) { + NdisStatus = AdapterSetPacketFilter(Adapter, (PULONG)Buffer); + BytesRead = sizeof(ULONG); + } + break; - (VOID) XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_TRANSMITTER_FRONTEND_ERRORS, - &Value); + case OID_802_3_MULTICAST_LIST: + BytesNeeded = ETHERNET_ADDRESS_LENGTH; + if (BufferLength % ETHERNET_ADDRESS_LENGTH == 0) { + ULONG Count = BufferLength / ETHERNET_ADDRESS_LENGTH; + NdisStatus = AdapterSetMulticastAddresses(Adapter, Buffer, Count); + BytesRead = BufferLength; + } else { + NdisStatus = NDIS_STATUS_INVALID_LENGTH; + } + break; - NdisStatisticsInfo->ifOutErrors += Value; + case OID_OFFLOAD_ENCAPSULATION: + BytesNeeded = sizeof(NDIS_OFFLOAD_ENCAPSULATION); + if (BufferLength == sizeof(NDIS_OFFLOAD_ENCAPSULATION)) { + NdisStatus = AdapterSetOffloadEncapsulation(Adapter, Buffer); + BytesRead = sizeof(NDIS_OFFLOAD_ENCAPSULATION); + } else { + NdisStatus = NDIS_STATUS_INVALID_LENGTH; + } + break; - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BYTES_XMIT; + case OID_TCP_OFFLOAD_PARAMETERS: + BytesNeeded = sizeof(NDIS_OFFLOAD_PARAMETERS); + if (BufferLength == sizeof(NDIS_OFFLOAD_PARAMETERS)) { + NdisStatus = AdapterSetTcpOffloadParameters(Adapter, Buffer); + BytesRead = sizeof(NDIS_OFFLOAD_PARAMETERS); + } else { + NdisStatus = NDIS_STATUS_INVALID_LENGTH; + } + break; - (VOID) XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_TRANSMITTER_UNICAST_OCTETS, - &Value); + case OID_GEN_INTERRUPT_MODERATION: + NdisStatus = NDIS_STATUS_INVALID_DATA; + break; - NdisStatisticsInfo->ifHCOutOctets = Value; + case OID_GEN_MACHINE_NAME: + default: + NdisStatus = NDIS_STATUS_NOT_SUPPORTED; + break; + }; - (VOID) XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_TRANSMITTER_MULTICAST_OCTETS, - &Value); + Request->DATA.SET_INFORMATION.BytesNeeded = BytesNeeded; + if (NdisStatus == NDIS_STATUS_SUCCESS) { + Request->DATA.SET_INFORMATION.BytesRead = BytesRead; + } - NdisStatisticsInfo->ifHCOutOctets += Value; + return NdisStatus; +} - (VOID) XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_TRANSMITTER_BROADCAST_OCTETS, - &Value); +static FORCEINLINE ULONG64 +AdapterGetXmitOk( + IN PXENNET_ADAPTER Adapter + ) +{ + ULONGLONG Value; + ULONG64 Result = 0; + + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_TRANSMITTER_UNICAST_PACKETS, + &Value); + Result = Value; + + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_TRANSMITTER_MULTICAST_PACKETS, + &Value); + Result += Value; + + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_TRANSMITTER_BROADCAST_PACKETS, + &Value); + Result += Value; + + return Result; +} - NdisStatisticsInfo->ifHCOutOctets += Value; +static FORCEINLINE ULONG64 +AdapterGetRcvOk( + IN PXENNET_ADAPTER Adapter + ) +{ + ULONGLONG Value; + ULONG64 Result = 0; + + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_UNICAST_PACKETS, + &Value); + Result = Value; + + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_MULTICAST_PACKETS, + &Value); + Result += Value; + + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_BROADCAST_PACKETS, + &Value); + Result += Value; + + return Result; +} - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_XMIT; +static FORCEINLINE ULONG64 +AdapterGetXmitError( + IN PXENNET_ADAPTER Adapter + ) +{ + ULONGLONG Value; + ULONG64 Result = 0; - (VOID) XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_TRANSMITTER_UNICAST_OCTETS, - &Value); + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_TRANSMITTER_BACKEND_ERRORS, + &Value); + Result = Value; - NdisStatisticsInfo->ifHCOutUcastOctets = Value; + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_TRANSMITTER_FRONTEND_ERRORS, + &Value); + Result += Value; - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_XMIT; + return Result; +} - (VOID) XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_TRANSMITTER_UNICAST_PACKETS, - &Value); +static FORCEINLINE ULONG64 +AdapterGetRcvError( + IN PXENNET_ADAPTER Adapter + ) +{ + ULONGLONG Value; + ULONG64 Result = 0; - NdisStatisticsInfo->ifHCOutUcastPkts = Value; + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_BACKEND_ERRORS, + &Value); + Result = Value; - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_XMIT; + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_FRONTEND_ERRORS, + &Value); + Result += Value; - (VOID) XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_TRANSMITTER_MULTICAST_OCTETS, - &Value); + return Result; +} - NdisStatisticsInfo->ifHCOutMulticastOctets = Value; +static VOID +AdapterGetPacketFilter( + IN PXENNET_ADAPTER Adapter, + OUT PULONG PacketFilter + ) +{ + XENVIF_MAC_FILTER_LEVEL UnicastFilterLevel; + XENVIF_MAC_FILTER_LEVEL MulticastFilterLevel; + XENVIF_MAC_FILTER_LEVEL BroadcastFilterLevel; - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_MULTICAST_FRAMES_XMIT; + XENVIF_VIF(MacQueryFilterLevel, + &Adapter->VifInterface, + ETHERNET_ADDRESS_UNICAST, + &UnicastFilterLevel); - (VOID) XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_TRANSMITTER_MULTICAST_PACKETS, - &Value); - - NdisStatisticsInfo->ifHCOutMulticastPkts = Value; - - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_XMIT; - - (VOID) XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_TRANSMITTER_BROADCAST_OCTETS, - &Value); - - NdisStatisticsInfo->ifHCOutBroadcastOctets = Value; - - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BROADCAST_FRAMES_XMIT; - - (VOID) XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_TRANSMITTER_BROADCAST_PACKETS, - &Value); - - NdisStatisticsInfo->ifHCOutBroadcastPkts = Value; - - NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_XMIT_DISCARDS; - NdisStatisticsInfo->ifOutDiscards = 0; - - return ndisStatus; -} - -static VOID -GetPacketFilter(PADAPTER Adapter, PULONG PacketFilter) -{ - XENVIF_MAC_FILTER_LEVEL UnicastFilterLevel; - XENVIF_MAC_FILTER_LEVEL MulticastFilterLevel; - XENVIF_MAC_FILTER_LEVEL BroadcastFilterLevel; - - XENVIF_VIF(MacQueryFilterLevel, - &Adapter->VifInterface, - ETHERNET_ADDRESS_UNICAST, - &UnicastFilterLevel); - - XENVIF_VIF(MacQueryFilterLevel, - &Adapter->VifInterface, - ETHERNET_ADDRESS_MULTICAST, - &MulticastFilterLevel); + XENVIF_VIF(MacQueryFilterLevel, + &Adapter->VifInterface, + ETHERNET_ADDRESS_MULTICAST, + &MulticastFilterLevel); XENVIF_VIF(MacQueryFilterLevel, &Adapter->VifInterface, @@ -863,1715 +1271,934 @@ GetPacketFilter(PADAPTER Adapter, PULONG PacketFilter) *PacketFilter |= NDIS_PACKET_TYPE_BROADCAST; } -#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 +AdapterQueryGeneralStatistics ( + IN PXENNET_ADAPTER Adapter, + IN PNDIS_STATISTICS_INFO Stats ) { - 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"); + ULONGLONG Value; - info = &Adapter->Capabilities; - bytesAvailable = sizeof(Adapter->Capabilities); - break; + RtlZeroMemory(Stats, sizeof(NDIS_STATISTICS_INFO)); + Stats->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + Stats->Header.Size = sizeof(NDIS_STATISTICS_INFO); + Stats->Header.Revision = NDIS_OBJECT_REVISION_1; - case OID_PNP_QUERY_POWER: - Trace("QUERY_POWER\n"); + Stats->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_RCV_ERROR; + (VOID) XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_BACKEND_ERRORS, + &Value); + Stats->ifInErrors = Value; + (VOID) XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_FRONTEND_ERRORS, + &Value); + Stats->ifInErrors += Value; + + Stats->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_RCV_DISCARDS; + (VOID) XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_PACKETS_DROPPED, + &Value); + Stats->ifInDiscards = Value; + + Stats->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BYTES_RCV; + (VOID) XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_UNICAST_OCTETS, + &Value); + Stats->ifHCInOctets = Value; + (VOID) XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_MULTICAST_OCTETS, + &Value); + Stats->ifHCInOctets += Value; + (VOID) XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_BROADCAST_OCTETS, + &Value); + Stats->ifHCInOctets += Value; + + Stats->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_RCV; + (VOID) XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_UNICAST_OCTETS, + &Value); + Stats->ifHCInUcastOctets = Value; - bytesNeeded = sizeof(NDIS_DEVICE_POWER_STATE); - if (informationBufferLength >= bytesNeeded) { - PNDIS_DEVICE_POWER_STATE state; + Stats->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_RCV; + (VOID) XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_UNICAST_PACKETS, + &Value); + Stats->ifHCInUcastPkts = Value; + + Stats->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_RCV; + (VOID) XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_MULTICAST_OCTETS, + &Value); + Stats->ifHCInMulticastOctets = Value; - state = (PNDIS_DEVICE_POWER_STATE)informationBuffer; - switch (*state) { - case NdisDeviceStateD0: - Trace("D0\n"); - break; + Stats->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_MULTICAST_FRAMES_RCV; + (VOID) XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_MULTICAST_PACKETS, + &Value); + Stats->ifHCInMulticastPkts = Value; - case NdisDeviceStateD1: - Trace("D1\n"); - break; + Stats->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_RCV; + (VOID) XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_BROADCAST_OCTETS, + &Value); + Stats->ifHCInBroadcastOctets = Value; - case NdisDeviceStateD2: - Trace("D2\n"); - break; + Stats->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BROADCAST_FRAMES_RCV; + (VOID) XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_BROADCAST_PACKETS, + &Value); + Stats->ifHCInBroadcastPkts = Value; - case NdisDeviceStateD3: - Trace("D3\n"); - break; - } - } + Stats->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_XMIT_ERROR; + (VOID) XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_TRANSMITTER_BACKEND_ERRORS, + &Value); + Stats->ifOutErrors = Value; + (VOID) XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_TRANSMITTER_FRONTEND_ERRORS, + &Value); + Stats->ifOutErrors += Value; + + Stats->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BYTES_XMIT; + (VOID) XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_TRANSMITTER_UNICAST_OCTETS, + &Value); + Stats->ifHCOutOctets = Value; + (VOID) XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_TRANSMITTER_MULTICAST_OCTETS, + &Value); + Stats->ifHCOutOctets += Value; + (VOID) XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_TRANSMITTER_BROADCAST_OCTETS, + &Value); + Stats->ifHCOutOctets += Value; + + Stats->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_XMIT; + (VOID) XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_TRANSMITTER_UNICAST_OCTETS, + &Value); + Stats->ifHCOutUcastOctets = Value; + + Stats->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_XMIT; + (VOID) XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_TRANSMITTER_UNICAST_PACKETS, + &Value); + Stats->ifHCOutUcastPkts = Value; + + Stats->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_XMIT; + (VOID) XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_TRANSMITTER_MULTICAST_OCTETS, + &Value); + Stats->ifHCOutMulticastOctets = Value; + + Stats->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_MULTICAST_FRAMES_XMIT; + (VOID) XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_TRANSMITTER_MULTICAST_PACKETS, + &Value); + Stats->ifHCOutMulticastPkts = Value; + + Stats->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_XMIT; + (VOID) XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_TRANSMITTER_BROADCAST_OCTETS, + &Value); + Stats->ifHCOutBroadcastOctets = Value; + + Stats->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BROADCAST_FRAMES_XMIT; + (VOID) XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_TRANSMITTER_BROADCAST_PACKETS, + &Value); + Stats->ifHCOutBroadcastPkts = Value; + + Stats->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_XMIT_DISCARDS; + Stats->ifOutDiscards = 0; + + return NDIS_STATUS_SUCCESS; +} + +static FORCEINLINE VOID +AdapterGetInterruptModeration( + IN PXENNET_ADAPTER Adapter, + OUT PNDIS_INTERRUPT_MODERATION_PARAMETERS Parameters + ) +{ + UNREFERENCED_PARAMETER(Adapter); + + RtlZeroMemory(Parameters, sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS)); + Parameters->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + Parameters->Header.Size = sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS); + Parameters->Header.Revision = NDIS_INTERRUPT_MODERATION_PARAMETERS_REVISION_1; + Parameters->Flags = 0; + Parameters->InterruptModeration = NdisInterruptModerationNotSupported; +} + +static NDIS_STATUS +AdapterQueryInformation( + IN PXENNET_ADAPTER Adapter, + IN PNDIS_OID_REQUEST Request + ) +{ + ULONG Value32; + ULONG64 Value64; + PVOID Buffer; + ULONG BufferLength; + BOOLEAN DoCopy = TRUE; + ULONG BytesAvailable = 0; + PVOID BytesToCopy = NULL; + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + + Buffer = Request->DATA.QUERY_INFORMATION.InformationBuffer; + BufferLength = Request->DATA.QUERY_INFORMATION.InformationBufferLength; + + switch (Request->DATA.QUERY_INFORMATION.Oid) { + case OID_PNP_CAPABILITIES: + BytesToCopy = &Adapter->Capabilities; + BytesAvailable = sizeof(Adapter->Capabilities); break; case OID_GEN_SUPPORTED_LIST: - info = &XennetSupportedOids[0]; - bytesAvailable = sizeof(XennetSupportedOids); + BytesToCopy = &XennetSupportedOids[0]; + BytesAvailable = sizeof(XennetSupportedOids); break; case OID_GEN_HARDWARE_STATUS: - infoData = NdisHardwareStatusReady; - info = &infoData; - bytesAvailable = sizeof(ULONG); + Value32 = NdisHardwareStatusReady; + BytesToCopy = &Value32; + BytesAvailable = sizeof(ULONG); break; case OID_GEN_MEDIA_SUPPORTED: case OID_GEN_MEDIA_IN_USE: - infoData = XENNET_MEDIA_TYPE; - info = &infoData; - bytesAvailable = sizeof(ULONG); + Value32 = XENNET_MEDIA_TYPE; + BytesToCopy = &Value32; + 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); + Value32 = Adapter->MaximumFrameSize; + BytesToCopy = &Value32; + BytesAvailable = sizeof(ULONG); break; case OID_GEN_VENDOR_DESCRIPTION: - info = COMPANY_NAME_STR; - bytesAvailable = (ULONG)strlen(info) + 1; + BytesToCopy = COMPANY_NAME_STR; + BytesAvailable = (ULONG)strlen(BytesToCopy) + 1; break; case OID_GEN_VENDOR_DRIVER_VERSION: - infoData = ((MAJOR_VERSION << 8) | MINOR_VERSION) << 8; - info = &infoData; - bytesAvailable = sizeof(ULONG); + Value32 = ((MAJOR_VERSION << 8) | MINOR_VERSION) << 8; + BytesToCopy = &Value32; + BytesAvailable = sizeof(ULONG); break; case OID_GEN_DRIVER_VERSION: - infoData = (6 << 8) | 0; - info = &infoData; - bytesAvailable = sizeof(ULONG); + Value32 = (6 << 8) | 0; + BytesToCopy = &Value32; + 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); - - } - + Value32 = XENNET_MAC_OPTIONS; + BytesToCopy = &Value32; + BytesAvailable = sizeof(ULONG); break; - case OID_802_3_MULTICAST_LIST: { - ULONG Count; - - doCopy = FALSE; - - XENVIF_VIF(MacQueryMulticastAddresses, + case OID_GEN_TRANSMIT_BUFFER_SPACE: + case OID_GEN_RECEIVE_BUFFER_SPACE: + XENVIF_VIF(TransmitterQueryRingSize, &Adapter->VifInterface, - NULL, - &Count); - bytesAvailable = Count * ETHERNET_ADDRESS_LENGTH; - - if (informationBufferLength >= bytesAvailable) { - NTSTATUS status; - - status = XENVIF_VIF(MacQueryMulticastAddresses, - &Adapter->VifInterface, - informationBuffer, - &Count); - if (!NT_SUCCESS(status)) - ndisStatus = NDIS_STATUS_FAILURE; - } - + (PULONG)&Value32); + Value32 *= Adapter->MaximumFrameSize; + BytesToCopy = &Value32; + BytesAvailable = sizeof(ULONG); break; - } + case OID_802_3_PERMANENT_ADDRESS: XENVIF_VIF(MacQueryPermanentAddress, &Adapter->VifInterface, - (PETHERNET_ADDRESS)&infoData); - info = &infoData; - bytesAvailable = sizeof (ETHERNET_ADDRESS); + (PETHERNET_ADDRESS)&Value32); + BytesToCopy = &Value32; + BytesAvailable = sizeof(ULONG); break; case OID_802_3_CURRENT_ADDRESS: XENVIF_VIF(MacQueryCurrentAddress, &Adapter->VifInterface, - (PETHERNET_ADDRESS)&infoData); - info = &infoData; - bytesAvailable = sizeof (ETHERNET_ADDRESS); + (PETHERNET_ADDRESS)&Value32); + BytesToCopy = &Value32; + BytesAvailable = sizeof(ULONG); break; case OID_GEN_MAXIMUM_FRAME_SIZE: - infoData = Adapter->MaximumFrameSize - + Value32 = Adapter->MaximumFrameSize - sizeof (ETHERNET_TAGGED_HEADER); - info = &infoData; - bytesAvailable = sizeof(ULONG); + BytesToCopy = &Value32; + BytesAvailable = sizeof(ULONG); break; case OID_GEN_MAXIMUM_TOTAL_SIZE: - infoData = Adapter->MaximumFrameSize - + Value32 = Adapter->MaximumFrameSize - sizeof (ETHERNET_TAGGED_HEADER) + sizeof (ETHERNET_UNTAGGED_HEADER); - - info = &infoData; - bytesAvailable = sizeof(ULONG); + BytesToCopy = &Value32; + BytesAvailable = sizeof(ULONG); break; case OID_GEN_CURRENT_LOOKAHEAD: - infoData = Adapter->CurrentLookahead; - info = &infoData; - bytesAvailable = sizeof(ULONG); + Value32 = Adapter->CurrentLookahead; + BytesToCopy = &Value32; + BytesAvailable = sizeof(ULONG); break; case OID_GEN_VENDOR_ID: - infoData = 0x5853; - info = &infoData; - bytesAvailable = sizeof(ULONG); + Value32 = 0x5853; + BytesToCopy = &Value32; + BytesAvailable = sizeof(ULONG); break; - case OID_GEN_LINK_SPEED: { - ULONG64 LinkSpeed; - - XENVIF_VIF(MacQueryState, - &Adapter->VifInterface, - NULL, - &LinkSpeed, - NULL); - - infoData = (ULONG)(LinkSpeed / 100); - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - } - case OID_GEN_MEDIA_CONNECT_STATUS: + case OID_GEN_LINK_SPEED: XENVIF_VIF(MacQueryState, &Adapter->VifInterface, - (PNET_IF_MEDIA_CONNECT_STATE)&infoData, NULL, + &Value64, 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); - - infoData = Value; - - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_TRANSMITTER_MULTICAST_PACKETS, - &Value); - - infoData += Value; - - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_TRANSMITTER_BROADCAST_PACKETS, - &Value); - - infoData += Value; - - info = &infoData; - bytesAvailable = sizeof(ULONGLONG); - break; - } - case OID_GEN_RCV_OK: { - ULONGLONG Value; - - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_RECEIVER_UNICAST_PACKETS, - &Value); - - infoData = Value; - - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_RECEIVER_MULTICAST_PACKETS, - &Value); - - infoData += Value; - - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_RECEIVER_BROADCAST_PACKETS, - &Value); - - infoData += Value; - - info = &infoData; - bytesAvailable = sizeof(ULONGLONG); + Value32 = (ULONG)(Value64 / 100); + BytesToCopy = &Value32; + BytesAvailable = sizeof(ULONG); break; - } - case OID_GEN_XMIT_ERROR: { - ULONGLONG Value; - - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_TRANSMITTER_BACKEND_ERRORS, - &Value); - - infoData = Value; - - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_TRANSMITTER_FRONTEND_ERRORS, - &Value); - - infoData += Value; - - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - } - case OID_GEN_RCV_ERROR: { - ULONGLONG Value; - - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_RECEIVER_BACKEND_ERRORS, - &Value); - - infoData = Value; - - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_RECEIVER_FRONTEND_ERRORS, - &Value); - - infoData += Value; - - 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); - - infoData = Value; - - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - } - case OID_GEN_DIRECTED_FRAMES_XMIT: { - ULONGLONG Value; - - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_TRANSMITTER_UNICAST_PACKETS, - &Value); - - infoData = Value; - - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - } - case OID_GEN_MULTICAST_BYTES_XMIT: { - ULONGLONG Value; - - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_TRANSMITTER_MULTICAST_OCTETS, - &Value); - - infoData = Value; - - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - } - case OID_GEN_MULTICAST_FRAMES_XMIT: { - ULONGLONG Value; - - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_TRANSMITTER_MULTICAST_PACKETS, - &Value); - - infoData = Value; - - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - } - case OID_GEN_BROADCAST_BYTES_XMIT: { - ULONGLONG Value; - - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_TRANSMITTER_BROADCAST_OCTETS, - &Value); - - infoData = Value; - - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - } - case OID_GEN_BROADCAST_FRAMES_XMIT: { - ULONGLONG Value; - - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_TRANSMITTER_BROADCAST_PACKETS, - &Value); - - infoData = Value; - - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - } - case OID_GEN_DIRECTED_BYTES_RCV: { - ULONGLONG Value; - - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_RECEIVER_UNICAST_OCTETS, - &Value); - - infoData = Value; - - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - } - case OID_GEN_DIRECTED_FRAMES_RCV: { - ULONGLONG Value; - - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_RECEIVER_UNICAST_PACKETS, - &Value); - - infoData = Value; - - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - } - case OID_GEN_MULTICAST_BYTES_RCV: { - ULONGLONG Value; - - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_RECEIVER_MULTICAST_OCTETS, - &Value); - - infoData = Value; - - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - } - case OID_GEN_MULTICAST_FRAMES_RCV: { - ULONGLONG Value; - - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_RECEIVER_MULTICAST_PACKETS, - &Value); - - infoData = Value; - - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - } - case OID_GEN_BROADCAST_BYTES_RCV: { - ULONGLONG Value; - - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_RECEIVER_BROADCAST_OCTETS, - &Value); - - infoData = Value; - - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - } - case OID_GEN_BROADCAST_FRAMES_RCV: { - ULONGLONG Value; - - XENVIF_VIF(QueryStatistic, - &Adapter->VifInterface, - XENVIF_RECEIVER_BROADCAST_PACKETS, - &Value); - - infoData = Value; - - info = &infoData; - bytesAvailable = sizeof(ULONG); - break; - } - 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; - - // 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; - } - - if (bytesWritten && doCopy) { - NdisMoveMemory(informationBuffer, info, bytesWritten); - - if (oid == OID_GEN_XMIT_OK || oid == OID_GEN_RCV_OK) - ndisStatus = NDIS_STATUS_SUCCESS; - } - } - - NdisRequest->DATA.QUERY_INFORMATION.BytesWritten = bytesWritten; - NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded = bytesNeeded; - return ndisStatus; -} -#pragma warning(pop) - -NDIS_STATUS -AdapterReset ( - IN NDIS_HANDLE MiniportAdapterContext, - OUT PBOOLEAN AddressingReset - ) -{ - UNREFERENCED_PARAMETER(MiniportAdapterContext); - - - *AddressingReset = FALSE; - - return NDIS_STATUS_SUCCESS; -} - -// -// 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; - - UNREFERENCED_PARAMETER(MiniportRestartParameters); - - Trace("====>\n"); - - if (Adapter->Enabled) { - ndisStatus = NDIS_STATUS_SUCCESS; - goto done; - } - - 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; - } - -done: - Trace("<====\n"); - return ndisStatus; -} - -// -// Recycle of received net buffer lists. -// -VOID -AdapterReturnNetBufferLists ( - IN NDIS_HANDLE MiniportAdapterContext, - IN PNET_BUFFER_LIST NetBufferLists, - IN ULONG ReturnFlags - ) -{ - PADAPTER Adapter = (PADAPTER)MiniportAdapterContext; - - ReceiverReturnNetBufferLists(&Adapter->Receiver, - NetBufferLists, - ReturnFlags); - - return; -} - -// -// 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 - ) -{ - PADAPTER Adapter = (PADAPTER)MiniportAdapterContext; - - TransmitterSendNetBufferLists(Adapter->Transmitter, - NetBufferList, - PortNumber, - SendFlags); -} - -#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) - -// -// Sets general adapter attributes. -// -static NDIS_STATUS -AdapterSetGeneralAttributes ( - IN PADAPTER Adapter - ) -{ - PNDIS_MINIPORT_ADAPTER_ATTRIBUTES adapterAttributes; - NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES generalAttributes; - NDIS_STATUS ndisStatus; - - NdisZeroMemory(&generalAttributes, - sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES)); - - generalAttributes.Header.Type = - NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES; - - generalAttributes.Header.Revision = - NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_1; - - generalAttributes.Header.Size = - sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES); - - generalAttributes.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; - - XENVIF_VIF(MacQueryPermanentAddress, - &Adapter->VifInterface, - (PETHERNET_ADDRESS)&generalAttributes.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; - - generalAttributes.SupportedOidList = XennetSupportedOids; - generalAttributes.SupportedOidListLength = sizeof(XennetSupportedOids); - adapterAttributes = - (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&generalAttributes; - - ndisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle, - adapterAttributes); - - 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 - ) -{ - 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; - - 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; - } - - 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); - - supported.Header.Type = NDIS_OBJECT_TYPE_OFFLOAD; - supported.Header.Revision = NDIS_OFFLOAD_REVISION_1; - supported.Header.Size = sizeof(supported); - - supported.Checksum.IPv4Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; - - supported.Checksum.IPv4Receive.IpChecksum = 1; - supported.Checksum.IPv4Receive.IpOptionsSupported = 1; - - supported.Checksum.IPv4Receive.TcpChecksum = 1; - supported.Checksum.IPv4Receive.TcpOptionsSupported = 1; - - supported.Checksum.IPv4Receive.UdpChecksum = 1; - - supported.Checksum.IPv6Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; - - supported.Checksum.IPv6Receive.IpExtensionHeadersSupported = 1; - - supported.Checksum.IPv6Receive.TcpChecksum = 1; - supported.Checksum.IPv6Receive.TcpOptionsSupported = 1; - - supported.Checksum.IPv6Receive.UdpChecksum = 1; - - XENVIF_VIF(TransmitterQueryOffloadOptions, - &Adapter->VifInterface, - &Options); - - supported.Checksum.IPv4Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; - - if (Options.OffloadIpVersion4HeaderChecksum) { - supported.Checksum.IPv4Transmit.IpChecksum = 1; - supported.Checksum.IPv4Transmit.IpOptionsSupported = 1; - } - - if (Options.OffloadIpVersion4TcpChecksum) { - supported.Checksum.IPv4Transmit.TcpChecksum = 1; - supported.Checksum.IPv4Transmit.TcpOptionsSupported = 1; - } - - if (Options.OffloadIpVersion4UdpChecksum) - supported.Checksum.IPv4Transmit.UdpChecksum = 1; - - supported.Checksum.IPv6Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; - - supported.Checksum.IPv6Transmit.IpExtensionHeadersSupported = 1; - - if (Options.OffloadIpVersion6TcpChecksum) { - supported.Checksum.IPv6Transmit.TcpChecksum = 1; - supported.Checksum.IPv6Transmit.TcpOptionsSupported = 1; - } - - if (Options.OffloadIpVersion6UdpChecksum) - 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; - } - - 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; - } - - current = supported; - - if (!(Adapter->Properties.ipv4_csum & 2)) - current.Checksum.IPv4Receive.IpChecksum = 0; - - if (!(Adapter->Properties.tcpv4_csum & 2)) - current.Checksum.IPv4Receive.TcpChecksum = 0; - - if (!(Adapter->Properties.udpv4_csum & 2)) - current.Checksum.IPv4Receive.UdpChecksum = 0; - - if (!(Adapter->Properties.tcpv6_csum & 2)) - current.Checksum.IPv6Receive.TcpChecksum = 0; - - if (!(Adapter->Properties.udpv6_csum & 2)) - current.Checksum.IPv6Receive.UdpChecksum = 0; - - if (!(Adapter->Properties.ipv4_csum & 1)) - current.Checksum.IPv4Transmit.IpChecksum = 0; - - if (!(Adapter->Properties.tcpv4_csum & 1)) - current.Checksum.IPv4Transmit.TcpChecksum = 0; - - if (!(Adapter->Properties.udpv4_csum & 1)) - current.Checksum.IPv4Transmit.UdpChecksum = 0; - - if (!(Adapter->Properties.tcpv6_csum & 1)) - current.Checksum.IPv6Transmit.TcpChecksum = 0; - - if (!(Adapter->Properties.udpv6_csum & 1)) - current.Checksum.IPv6Transmit.UdpChecksum = 0; - - if (!(Adapter->Properties.lsov4)) { - current.LsoV2.IPv4.MaxOffLoadSize = 0; - current.LsoV2.IPv4.MinSegmentCount = 0; - } - - if (!(Adapter->Properties.lsov6)) { - current.LsoV2.IPv6.MaxOffLoadSize = 0; - current.LsoV2.IPv6.MinSegmentCount = 0; - } - - if (!RtlEqualMemory(&Adapter->Offload, ¤t, sizeof (NDIS_OFFLOAD))) { - Adapter->Offload = current; - - DISPLAY_OFFLOAD(current); - } - - 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; - - adapterAttributes = - (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&offloadAttributes; - ndisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle, - adapterAttributes); - - return ndisStatus; -} - -static void -AdapterIndicateOffloadChanged ( - IN PADAPTER 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; - } - - 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); - } - - 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); - - NdisMIndicateStatusEx(Adapter->NdisAdapterHandle, &indication); - -} - -static NDIS_STATUS -SetMulticastAddresses(PADAPTER Adapter, PETHERNET_ADDRESS Address, ULONG Count) -{ - NTSTATUS status; - - status = XENVIF_VIF(MacSetMulticastAddresses, - &Adapter->VifInterface, - Address, - Count); - 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; - - if (*PacketFilter & NDIS_PACKET_TYPE_PROMISCUOUS) { - UnicastFilterLevel = XENVIF_MAC_FILTER_ALL; - MulticastFilterLevel = XENVIF_MAC_FILTER_ALL; - BroadcastFilterLevel = XENVIF_MAC_FILTER_ALL; - goto done; - } - - if (*PacketFilter & NDIS_PACKET_TYPE_DIRECTED) - UnicastFilterLevel = XENVIF_MAC_FILTER_MATCHING; - else - UnicastFilterLevel = XENVIF_MAC_FILTER_NONE; - - 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; - if (*PacketFilter & NDIS_PACKET_TYPE_BROADCAST) - BroadcastFilterLevel = XENVIF_MAC_FILTER_ALL; - else - BroadcastFilterLevel = XENVIF_MAC_FILTER_NONE; + case OID_GEN_MEDIA_CONNECT_STATUS: + XENVIF_VIF(MacQueryState, + &Adapter->VifInterface, + (PNET_IF_MEDIA_CONNECT_STATE)&Value32, + NULL, + NULL); + BytesToCopy = &Value32; + BytesAvailable = sizeof(ULONG); + break; -done: - XENVIF_VIF(MacSetFilterLevel, - &Adapter->VifInterface, - ETHERNET_ADDRESS_UNICAST, - UnicastFilterLevel); + case OID_GEN_MAXIMUM_SEND_PACKETS: + Value32 = 16; + BytesToCopy = &Value32; + BytesAvailable = sizeof(ULONG); + break; - XENVIF_VIF(MacSetFilterLevel, - &Adapter->VifInterface, - ETHERNET_ADDRESS_MULTICAST, - MulticastFilterLevel); + 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: + Value32 = 0; + BytesToCopy = &Value32; + BytesAvailable = sizeof(ULONG); + break; - XENVIF_VIF(MacSetFilterLevel, - &Adapter->VifInterface, - ETHERNET_ADDRESS_BROADCAST, - BroadcastFilterLevel); + case OID_802_3_MAXIMUM_LIST_SIZE: + Value32 = 32; + BytesToCopy = &Value32; + BytesAvailable = sizeof(ULONG); + break; - return NDIS_STATUS_SUCCESS; -} + case OID_GEN_STATISTICS: + DoCopy = FALSE; + BytesAvailable = sizeof(NDIS_STATISTICS_INFO); + if (BufferLength >= sizeof(NDIS_STATISTICS_INFO)) + NdisStatus = AdapterQueryGeneralStatistics(Adapter, Buffer); + break; -// -// 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; + case OID_802_3_MULTICAST_LIST: + DoCopy = FALSE; + XENVIF_VIF(MacQueryMulticastAddresses, + &Adapter->VifInterface, + NULL, + &Value32); + BytesAvailable = Value32 * ETHERNET_ADDRESS_LENGTH; + if (BufferLength >= BytesAvailable) { + if (!NT_SUCCESS(XENVIF_VIF(MacQueryMulticastAddresses, + &Adapter->VifInterface, + Buffer, + &Value32))) { + NdisStatus = NDIS_STATUS_FAILURE; } } break; - case OID_GEN_MACHINE_NAME: - ndisStatus = NDIS_STATUS_NOT_SUPPORTED; + case OID_GEN_CURRENT_PACKET_FILTER: + AdapterGetPacketFilter(Adapter, &Value32); + BytesToCopy = &Value32; + BytesAvailable = sizeof(ULONG); break; - case OID_GEN_CURRENT_LOOKAHEAD: - bytesNeeded = sizeof(ULONG); - Adapter->CurrentLookahead = Adapter->MaximumFrameSize; - if (informationBufferLength == sizeof(ULONG)) { - Adapter->CurrentLookahead = *(PULONG)informationBuffer; - bytesRead = sizeof(ULONG); - } - + case OID_GEN_XMIT_OK: + Value64 = AdapterGetXmitOk(Adapter); + BytesToCopy = &Value64; + BytesAvailable = sizeof(ULONG64); break; - case OID_GEN_CURRENT_PACKET_FILTER: - bytesNeeded = sizeof(ULONG); - if (informationBufferLength == sizeof(ULONG)) { - ndisStatus = SetPacketFilter(Adapter, (PULONG)informationBuffer); - bytesRead = sizeof(ULONG); - } - + case OID_GEN_RCV_OK: + Value64 = AdapterGetRcvOk(Adapter); + BytesToCopy = &Value64; + BytesAvailable = sizeof(ULONG64); break; - case OID_802_3_MULTICAST_LIST: - bytesNeeded = ETHERNET_ADDRESS_LENGTH; - if (informationBufferLength % ETHERNET_ADDRESS_LENGTH == 0) { - addressCount = informationBufferLength / ETHERNET_ADDRESS_LENGTH; + case OID_GEN_XMIT_ERROR: + Value64 = AdapterGetXmitError(Adapter); + BytesToCopy = &Value64; + BytesAvailable = sizeof(ULONG64); + break; - ndisStatus = SetMulticastAddresses(Adapter, informationBuffer, addressCount); - if (ndisStatus == NDIS_STATUS_SUCCESS) - bytesRead = informationBufferLength; - } else { - ndisStatus = NDIS_STATUS_INVALID_LENGTH; - } + case OID_GEN_RCV_ERROR: + Value64 = AdapterGetRcvError(Adapter); + BytesToCopy = &Value64; + BytesAvailable = sizeof(ULONG64); + break; + case OID_GEN_DIRECTED_BYTES_XMIT: + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_TRANSMITTER_UNICAST_OCTETS, + &Value64); + Value32 = (ULONG)Value64; + BytesToCopy = &Value32; + BytesAvailable = sizeof(ULONG); break; - case OID_GEN_INTERRUPT_MODERATION: - ndisStatus = NDIS_STATUS_INVALID_DATA; + case OID_GEN_DIRECTED_FRAMES_XMIT: + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_TRANSMITTER_UNICAST_PACKETS, + &Value64); + Value32 = (ULONG)Value64; + BytesToCopy = &Value32; + BytesAvailable = sizeof(ULONG); break; - case OID_OFFLOAD_ENCAPSULATION: { - PNDIS_OFFLOAD_ENCAPSULATION offloadEncapsulation; + case OID_GEN_MULTICAST_BYTES_XMIT: + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_TRANSMITTER_MULTICAST_OCTETS, + &Value64); + Value32 = (ULONG)Value64; + BytesToCopy = &Value32; + BytesAvailable = sizeof(ULONG); + break; - bytesNeeded = sizeof(*offloadEncapsulation); - if (informationBufferLength >= bytesNeeded) { - XENVIF_VIF_OFFLOAD_OPTIONS Options; + case OID_GEN_MULTICAST_FRAMES_XMIT: + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_TRANSMITTER_MULTICAST_PACKETS, + &Value64); + Value32 = (ULONG)Value64; + BytesToCopy = &Value32; + BytesAvailable = sizeof(ULONG); + break; - bytesRead = bytesNeeded; - offloadEncapsulation = informationBuffer; - ndisStatus = NDIS_STATUS_SUCCESS; + case OID_GEN_BROADCAST_BYTES_XMIT: + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_TRANSMITTER_BROADCAST_OCTETS, + &Value64); + Value32 = (ULONG)Value64; + BytesToCopy = &Value32; + BytesAvailable = sizeof(ULONG); + break; - if (offloadEncapsulation->IPv4.Enabled == NDIS_OFFLOAD_SET_ON) { - if (offloadEncapsulation->IPv4.EncapsulationType != NDIS_ENCAPSULATION_IEEE_802_3) - ndisStatus = NDIS_STATUS_INVALID_PARAMETER; - } + case OID_GEN_BROADCAST_FRAMES_XMIT: + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_TRANSMITTER_BROADCAST_PACKETS, + &Value64); + Value32 = (ULONG)Value64; + BytesToCopy = &Value32; + BytesAvailable = sizeof(ULONG); + break; - if (offloadEncapsulation->IPv6.Enabled == NDIS_OFFLOAD_SET_ON) { - if (offloadEncapsulation->IPv6.EncapsulationType != NDIS_ENCAPSULATION_IEEE_802_3) - ndisStatus = NDIS_STATUS_INVALID_PARAMETER; - } + case OID_GEN_DIRECTED_BYTES_RCV: + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_UNICAST_OCTETS, + &Value64); + Value32 = (ULONG)Value64; + BytesToCopy = &Value32; + BytesAvailable = sizeof(ULONG); + break; - XENVIF_VIF(TransmitterQueryOffloadOptions, - &Adapter->VifInterface, - &Options); - - Adapter->Transmitter->OffloadOptions.Value = 0; - Adapter->Transmitter->OffloadOptions.OffloadTagManipulation = 1; + case OID_GEN_DIRECTED_FRAMES_RCV: + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_UNICAST_PACKETS, + &Value64); + Value32 = (ULONG)Value64; + BytesToCopy = &Value32; + BytesAvailable = sizeof(ULONG); + break; - if ((Adapter->Properties.lsov4) && (Options.OffloadIpVersion4LargePacket)) - Adapter->Transmitter->OffloadOptions.OffloadIpVersion4LargePacket = 1; + case OID_GEN_MULTICAST_BYTES_RCV: + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_MULTICAST_OCTETS, + &Value64); + Value32 = (ULONG)Value64; + BytesToCopy = &Value32; + BytesAvailable = sizeof(ULONG); + break; - if ((Adapter->Properties.lsov6) && (Options.OffloadIpVersion6LargePacket)) - Adapter->Transmitter->OffloadOptions.OffloadIpVersion6LargePacket = 1; + case OID_GEN_MULTICAST_FRAMES_RCV: + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_MULTICAST_PACKETS, + &Value64); + Value32 = (ULONG)Value64; + BytesToCopy = &Value32; + BytesAvailable = sizeof(ULONG); + break; - if ((Adapter->Properties.ipv4_csum & 1) && Options.OffloadIpVersion4HeaderChecksum) - Adapter->Transmitter->OffloadOptions.OffloadIpVersion4HeaderChecksum = 1; + case OID_GEN_BROADCAST_BYTES_RCV: + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_BROADCAST_OCTETS, + &Value64); + Value32 = (ULONG)Value64; + BytesToCopy = &Value32; + BytesAvailable = sizeof(ULONG); + break; - if ((Adapter->Properties.tcpv4_csum & 1) && Options.OffloadIpVersion4TcpChecksum) - Adapter->Transmitter->OffloadOptions.OffloadIpVersion4TcpChecksum = 1; + case OID_GEN_BROADCAST_FRAMES_RCV: + XENVIF_VIF(QueryStatistic, + &Adapter->VifInterface, + XENVIF_RECEIVER_BROADCAST_PACKETS, + &Value64); + Value32 = (ULONG)Value64; + BytesToCopy = &Value32; + BytesAvailable = sizeof(ULONG); + break; - if ((Adapter->Properties.udpv4_csum & 1) && Options.OffloadIpVersion4UdpChecksum) - Adapter->Transmitter->OffloadOptions.OffloadIpVersion4UdpChecksum = 1; + case OID_GEN_INTERRUPT_MODERATION: + DoCopy = FALSE; + BytesAvailable = sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS); + if (BufferLength >= BytesAvailable) + AdapterGetInterruptModeration(Adapter, Buffer); + else + NdisStatus = NDIS_STATUS_FAILURE; + break; - if ((Adapter->Properties.tcpv6_csum & 1) && Options.OffloadIpVersion6TcpChecksum) - Adapter->Transmitter->OffloadOptions.OffloadIpVersion6TcpChecksum = 1; + case OID_PNP_QUERY_POWER: + // do nothing! + break; - if ((Adapter->Properties.udpv6_csum & 1) && Options.OffloadIpVersion6UdpChecksum) - Adapter->Transmitter->OffloadOptions.OffloadIpVersion6UdpChecksum = 1; + case OID_GEN_MAC_ADDRESS: + case OID_GEN_MAX_LINK_SPEED: + case OID_IP4_OFFLOAD_STATS: + case OID_IP6_OFFLOAD_STATS: + case OID_GEN_SUPPORTED_GUIDS: + case OID_GEN_INIT_TIME_MS: + case OID_GEN_RESET_COUNTS: + case OID_GEN_MEDIA_SENSE_COUNTS: + default: + NdisStatus = NDIS_STATUS_NOT_SUPPORTED; + break; - Adapter->Receiver.OffloadOptions.Value = 0; - Adapter->Receiver.OffloadOptions.OffloadTagManipulation = 1; + } - if (Adapter->Properties.need_csum_value) - Adapter->Receiver.OffloadOptions.NeedChecksumValue = 1; + if (NdisStatus == NDIS_STATUS_SUCCESS) { + Request->DATA.QUERY_INFORMATION.BytesNeeded = BytesAvailable; + if (BytesAvailable <= BufferLength) { + Request->DATA.QUERY_INFORMATION.BytesWritten = BytesAvailable; + } else { + Request->DATA.QUERY_INFORMATION.BytesWritten = BufferLength; + NdisStatus = NDIS_STATUS_BUFFER_TOO_SHORT; + } + if (Request->DATA.QUERY_INFORMATION.BytesWritten && DoCopy) { + RtlMoveMemory(Buffer, BytesToCopy, Request->DATA.QUERY_INFORMATION.BytesWritten); - if (Adapter->Properties.lrov4) { - Adapter->Receiver.OffloadOptions.OffloadIpVersion4LargePacket = 1; - Adapter->Receiver.OffloadOptions.NeedLargePacketSplit = 1; - } + // Its Ok to short transfers on these Oids + if (Request->DATA.QUERY_INFORMATION.Oid == OID_GEN_XMIT_OK || + Request->DATA.QUERY_INFORMATION.Oid == OID_GEN_RCV_OK) + NdisStatus = NDIS_STATUS_SUCCESS; + } + } - if (Adapter->Properties.lrov6) { - Adapter->Receiver.OffloadOptions.OffloadIpVersion6LargePacket = 1; - Adapter->Receiver.OffloadOptions.NeedLargePacketSplit = 1; - } + return NdisStatus; +} - if (Adapter->Properties.ipv4_csum & 2) - Adapter->Receiver.OffloadOptions.OffloadIpVersion4HeaderChecksum = 1; +NDIS_STATUS +AdapterOidRequest( + IN PXENNET_ADAPTER Adapter, + IN PNDIS_OID_REQUEST Request + ) +{ + NDIS_STATUS NdisStatus; + + switch (Request->RequestType) { + case NdisRequestSetInformation: + NdisStatus = AdapterSetInformation(Adapter, Request); + break; + + case NdisRequestQueryInformation: + case NdisRequestQueryStatistics: + NdisStatus = AdapterQueryInformation(Adapter, Request); + break; - if (Adapter->Properties.tcpv4_csum & 2) - Adapter->Receiver.OffloadOptions.OffloadIpVersion4TcpChecksum = 1; + default: + NdisStatus = NDIS_STATUS_NOT_SUPPORTED; + break; + }; - if (Adapter->Properties.udpv4_csum & 2) - Adapter->Receiver.OffloadOptions.OffloadIpVersion4UdpChecksum = 1; + return NdisStatus; +} - if (Adapter->Properties.tcpv6_csum & 2) - Adapter->Receiver.OffloadOptions.OffloadIpVersion6TcpChecksum = 1; +NTSTATUS +AdapterEnable( + IN PXENNET_ADAPTER Adapter + ) +{ + NTSTATUS status; - if (Adapter->Properties.udpv6_csum & 2) - Adapter->Receiver.OffloadOptions.OffloadIpVersion6UdpChecksum = 1; + if (Adapter->Enabled) + goto done; - AdapterIndicateOffloadChanged(Adapter); - } - break; - } - case OID_TCP_OFFLOAD_PARAMETERS: { - PNDIS_OFFLOAD_PARAMETERS offloadParameters; + status = XENVIF_VIF(Enable, + &Adapter->VifInterface, + AdapterVifCallback, + Adapter); + if (!NT_SUCCESS(status)) + goto fail1; + + TransmitterEnable(Adapter->Transmitter); + Adapter->Enabled = TRUE; - bytesNeeded = sizeof(*offloadParameters); - if (informationBufferLength >= bytesNeeded) { - bytesRead = bytesNeeded; - offloadParameters = informationBuffer; - ndisStatus = NDIS_STATUS_SUCCESS; +done: + return STATUS_SUCCESS; -#define no_change(x) ((x) == NDIS_OFFLOAD_PARAMETERS_NO_CHANGE) +fail1: + Error("fail1 (%08x)\n", status); + return status; +} - if (!no_change(offloadParameters->IPsecV1)) - ndisStatus = NDIS_STATUS_INVALID_PARAMETER; - - if (!no_change(offloadParameters->LsoV1)) - ndisStatus = NDIS_STATUS_INVALID_PARAMETER; +BOOLEAN +AdapterDisable( + IN PXENNET_ADAPTER Adapter + ) +{ + if (!Adapter->Enabled) + return FALSE; - if (!no_change(offloadParameters->TcpConnectionIPv4)) - ndisStatus = NDIS_STATUS_INVALID_PARAMETER; + XENVIF_VIF(Disable, &Adapter->VifInterface); + Adapter->Enabled = FALSE; + return TRUE; +} - if (!no_change(offloadParameters->TcpConnectionIPv6)) - ndisStatus = NDIS_STATUS_INVALID_PARAMETER; +VOID +AdapterMediaStateChange( + IN PXENNET_ADAPTER Adapter + ) +{ + NDIS_LINK_STATE LinkState; + NDIS_STATUS_INDICATION StatusIndication; - if (!no_change(offloadParameters->LsoV2IPv4)) { - XENVIF_VIF_OFFLOAD_OPTIONS Options; + RtlZeroMemory(&LinkState, sizeof (NDIS_LINK_STATE)); + LinkState.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + LinkState.Header.Size = sizeof(NDIS_LINK_STATE); + LinkState.Header.Revision = NDIS_LINK_STATE_REVISION_1; - XENVIF_VIF(TransmitterQueryOffloadOptions, - &Adapter->VifInterface, - &Options); + XENVIF_VIF(MacQueryState, + &Adapter->VifInterface, + &LinkState.MediaConnectState, + &LinkState.RcvLinkSpeed, + &LinkState.MediaDuplexState); - if (!(Options.OffloadIpVersion4LargePacket)) - ndisStatus = NDIS_STATUS_INVALID_PARAMETER; - } + if (LinkState.MediaConnectState == MediaConnectStateUnknown) { + Info("LINK: STATE UNKNOWN\n"); + } else if (LinkState.MediaConnectState == MediaConnectStateDisconnected) { + Info("LINK: DOWN\n"); + } else { + ASSERT3U(LinkState.MediaConnectState, ==, MediaConnectStateConnected); - if (!no_change(offloadParameters->LsoV2IPv6)) { - XENVIF_VIF_OFFLOAD_OPTIONS Options; + 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); + } - XENVIF_VIF(TransmitterQueryOffloadOptions, - &Adapter->VifInterface, - &Options); + LinkState.XmitLinkSpeed = LinkState.RcvLinkSpeed; - if (!(Options.OffloadIpVersion6LargePacket)) - ndisStatus = NDIS_STATUS_INVALID_PARAMETER; - } + RtlZeroMemory(&StatusIndication, sizeof (NDIS_STATUS_INDICATION)); + StatusIndication.Header.Type = NDIS_OBJECT_TYPE_STATUS_INDICATION; + StatusIndication.Header.Size = sizeof (NDIS_STATUS_INDICATION); + StatusIndication.Header.Revision = NDIS_STATUS_INDICATION_REVISION_1; + StatusIndication.SourceHandle = Adapter->NdisHandle; + StatusIndication.StatusCode = NDIS_STATUS_LINK_STATE; + StatusIndication.StatusBuffer = &LinkState; + StatusIndication.StatusBufferSize = sizeof (NDIS_LINK_STATE); -#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; - } - } + NdisMIndicateStatusEx(Adapter->NdisHandle, &StatusIndication); +} -#undef tx_enabled -#undef rx_enabled -#undef no_change +PXENNET_RECEIVER +AdapterGetReceiver( + IN PXENNET_ADAPTER Adapter + ) +{ + return Adapter->Receiver; +} - if (offloadChanged) - AdapterIndicateOffloadChanged(Adapter); - } - } else { - ndisStatus = NDIS_STATUS_INVALID_LENGTH; - } - break; - } - default: - ndisStatus = NDIS_STATUS_NOT_SUPPORTED; - break; - }; +PXENNET_TRANSMITTER +AdapterGetTransmitter( + IN PXENNET_ADAPTER Adapter + ) +{ + return Adapter->Transmitter; +} - NdisRequest->DATA.SET_INFORMATION.BytesNeeded = bytesNeeded; - if (ndisStatus == NDIS_STATUS_SUCCESS) { - NdisRequest->DATA.SET_INFORMATION.BytesRead = bytesRead; - } +PXENVIF_VIF_INTERFACE +AdapterGetVifInterface( + IN PXENNET_ADAPTER Adapter + ) +{ + return &Adapter->VifInterface; +} - return ndisStatus; +NDIS_HANDLE +AdapterGetHandle( + IN PXENNET_ADAPTER Adapter + ) +{ + return Adapter->NdisHandle; } -// -// Sets miniport registration attributes. -// -static NDIS_STATUS -AdapterSetRegistrationAttributes ( - IN PADAPTER Adapter +NTSTATUS +AdapterInitialize( + IN NDIS_HANDLE NdisHandle, + OUT PXENNET_ADAPTER *Adapter ) { - PNDIS_MINIPORT_ADAPTER_ATTRIBUTES adapterAttributes; - NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES registrationAttributes; - NDIS_STATUS ndisStatus; + PDEVICE_OBJECT DeviceObject; + NTSTATUS status; + NDIS_SG_DMA_DESCRIPTION DmaDescription; + NDIS_STATUS NdisStatus; + + status = STATUS_NO_MEMORY; + *Adapter = ExAllocatePoolWithTag(NonPagedPool, sizeof(XENNET_ADAPTER), XENNET_POOL_TAG); + if (*Adapter == NULL) + goto fail1; + RtlZeroMemory(*Adapter, sizeof(XENNET_ADAPTER)); + (*Adapter)->NdisHandle = NdisHandle; + + DeviceObject = NULL; + NdisMGetDeviceProperty(NdisHandle, + &DeviceObject, + NULL, + NULL, + NULL, + NULL); + + status = QUERY_INTERFACE(DeviceObject, + XENVIF, + VIF, + XENVIF_VIF_INTERFACE_VERSION_MAX, + (PINTERFACE)&(*Adapter)->VifInterface, + sizeof ((*Adapter)->VifInterface), + FALSE); + if (!NT_SUCCESS(status)) + goto fail2; - NdisZeroMemory(®istrationAttributes, - sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES)); + status = XENVIF_VIF(Acquire, &(*Adapter)->VifInterface); + if (!NT_SUCCESS(status)) + goto fail3; - registrationAttributes.Header.Type = - NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES; + status = TransmitterInitialize(*Adapter, &(*Adapter)->Transmitter); + if (!NT_SUCCESS(status)) + goto fail4; - registrationAttributes.Header.Revision = - NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1; + status = ReceiverInitialize(*Adapter, &(*Adapter)->Receiver); + if (!NT_SUCCESS(status)) + goto fail5; - registrationAttributes.Header.Size = - sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES); + NdisStatus = AdapterGetAdvancedSettings(*Adapter); + if (NdisStatus != NDIS_STATUS_SUCCESS) + goto fail6; - 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; + NdisStatus = AdapterSetRegistrationAttributes(*Adapter); + if (NdisStatus != NDIS_STATUS_SUCCESS) + goto fail7; - adapterAttributes = - (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)®istrationAttributes; + NdisStatus = AdapterSetGeneralAttributes(*Adapter); + if (NdisStatus != NDIS_STATUS_SUCCESS) + goto fail8; - ndisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle, - adapterAttributes); + NdisStatus = AdapterSetOffloadAttributes(*Adapter); + if (NdisStatus != NDIS_STATUS_SUCCESS) + goto fail9; - return ndisStatus; -} + NdisZeroMemory(&DmaDescription, sizeof(DmaDescription)); + DmaDescription.Header.Type = NDIS_OBJECT_TYPE_SG_DMA_DESCRIPTION; + DmaDescription.Header.Size = sizeof(NDIS_SG_DMA_DESCRIPTION); + DmaDescription.Header.Revision = NDIS_SG_DMA_DESCRIPTION_REVISION_1; + DmaDescription.Flags = NDIS_SG_DMA_64_BIT_ADDRESS; + DmaDescription.MaximumPhysicalMapping = 65536; + DmaDescription.ProcessSGListHandler = AdapterProcessSGList; + DmaDescription.SharedMemAllocateCompleteHandler = AdapterAllocateComplete; -// -// Shuts down adapter. -// -VOID -AdapterShutdown ( - IN NDIS_HANDLE MiniportAdapterContext, - IN NDIS_SHUTDOWN_ACTION ShutdownAction - ) -{ - PADAPTER Adapter = (PADAPTER)MiniportAdapterContext; + NdisStatus = NdisMRegisterScatterGatherDma((*Adapter)->NdisHandle, + &DmaDescription, + &(*Adapter)->NdisDmaHandle); + if (NdisStatus != NDIS_STATUS_SUCCESS) + (*Adapter)->NdisDmaHandle = NULL; - UNREFERENCED_PARAMETER(ShutdownAction); + status = AdapterEnable(*Adapter); + if (!NT_SUCCESS(status)) + goto fail10; - if (ShutdownAction != NdisShutdownBugCheck) - AdapterStop(Adapter); + return STATUS_SUCCESS; - return; +fail10: + Error("fail10 (%08x)\n", status); + if ((*Adapter)->NdisDmaHandle) + NdisMDeregisterScatterGatherDma((*Adapter)->NdisDmaHandle); + (*Adapter)->NdisDmaHandle = NULL; +fail9: + Error("fail9\n"); +fail8: + Error("fail8\n"); +fail7: + Error("fail7\n"); +fail6: + Error("fail6 (%08x)\n", NdisStatus); + if (NT_SUCCESS(status)) + status = STATUS_UNSUCCESSFUL; + ReceiverTeardown((*Adapter)->Receiver); + (*Adapter)->Receiver = NULL; +fail5: + Error("fail5\n"); + TransmitterTeardown((*Adapter)->Transmitter); + (*Adapter)->Transmitter = NULL; +fail4: + Error("fail4\n"); + XENVIF_VIF(Release, &(*Adapter)->VifInterface); +fail3: + Error("fail3\n"); + RtlZeroMemory(&(*Adapter)->VifInterface, sizeof(XENVIF_VIF_INTERFACE)); +fail2: + Error("fail2\n"); + ExFreePoolWithTag(*Adapter, XENNET_POOL_TAG); +fail1: + Error("fail1 (%08x)\n", status); + return status; } -// -// 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 -) +VOID +AdapterTeardown( + IN PXENNET_ADAPTER Adapter + ) { - Trace("====>\n"); + if (Adapter->NdisDmaHandle) + NdisMDeregisterScatterGatherDma(Adapter->NdisDmaHandle); + Adapter->NdisDmaHandle = NULL; - if (!Adapter->Enabled) - goto done; + ReceiverTeardown(Adapter->Receiver); + Adapter->Receiver = NULL; - XENVIF_VIF(Disable, - &Adapter->VifInterface); + TransmitterTeardown(Adapter->Transmitter); + Adapter->Transmitter = 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, XENNET_POOL_TAG); } + +// +//#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) +// diff --git a/src/xennet/adapter.h b/src/xennet/adapter.h index e64e40d..a1f4b85 100644 --- a/src/xennet/adapter.h +++ b/src/xennet/adapter.h @@ -29,19 +29,20 @@ * SUCH DAMAGE. */ -#pragma once +#ifndef _XENNET_ADAPTER_H_ +#define _XENNET_ADAPTER_H_ -#define XENNET_INTERFACE_TYPE NdisInterfaceInternal +#define XENNET_INTERFACE_TYPE NdisInterfaceInternal -#define XENNET_MEDIA_TYPE NdisMedium802_3 +#define XENNET_MEDIA_TYPE NdisMedium802_3 -#define XENNET_MAC_OPTIONS (NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | \ - NDIS_MAC_OPTION_TRANSFERS_NOT_PEND | \ - NDIS_MAC_OPTION_NO_LOOPBACK | \ - NDIS_MAC_OPTION_8021P_PRIORITY | \ - NDIS_MAC_OPTION_SUPPORTS_MAC_ADDRESS_OVERWRITE) +#define XENNET_MAC_OPTIONS (NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | \ + NDIS_MAC_OPTION_TRANSFERS_NOT_PEND | \ + NDIS_MAC_OPTION_NO_LOOPBACK | \ + NDIS_MAC_OPTION_8021P_PRIORITY | \ + NDIS_MAC_OPTION_SUPPORTS_MAC_ADDRESS_OVERWRITE) -typedef struct _PROPERTIES { +typedef struct _XENNET_PROPERTIES { int ipv4_csum; int tcpv4_csum; int udpv4_csum; @@ -52,122 +53,63 @@ typedef struct _PROPERTIES { int lsov6; int lrov4; 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 - ); - -MINIPORT_CANCEL_SEND AdapterCancelSendNetBufferLists; -VOID -AdapterCancelSendNetBufferLists ( - IN NDIS_HANDLE NdisHandle, - IN PVOID CancelId - ); +} XENNET_PROPERTIES, *PXENNET_PROPERTIES; -MINIPORT_CHECK_FOR_HANG AdapterCheckForHang; -BOOLEAN -AdapterCheckForHang ( - IN NDIS_HANDLE NdisHandle - ); - -VOID -AdapterCleanup ( - IN PADAPTER Adapter - ); +typedef struct _XENNET_ADAPTER XENNET_ADAPTER, *PXENNET_ADAPTER; -NDIS_STATUS -AdapterInitialize ( - IN PADAPTER Adapter, - IN NDIS_HANDLE AdapterHandle +extern NDIS_STATUS +AdapterOidRequest( + IN PXENNET_ADAPTER Adapter, + IN PNDIS_OID_REQUEST Request ); -MINIPORT_OID_REQUEST AdapterOidRequest; -NDIS_STATUS -AdapterOidRequest ( - IN NDIS_HANDLE NdisHandle, - IN PNDIS_OID_REQUEST NdisRequest +extern NTSTATUS +AdapterEnable( + IN PXENNET_ADAPTER Adapter ); -MINIPORT_PAUSE AdapterPause; -NDIS_STATUS -AdapterPause ( - IN NDIS_HANDLE NdisHandle, - IN PNDIS_MINIPORT_PAUSE_PARAMETERS MiniportPauseParameters +extern BOOLEAN +AdapterDisable( + IN PXENNET_ADAPTER Adapter ); -MINIPORT_DEVICE_PNP_EVENT_NOTIFY AdapterPnPEventHandler; -VOID -AdapterPnPEventHandler ( - IN NDIS_HANDLE NdisHandle, - IN PNET_DEVICE_PNP_EVENT NetDevicePnPEvent +extern VOID +AdapterMediaStateChange( + 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 +#include "transmitter.h" +extern PXENNET_TRANSMITTER +AdapterGetTransmitter( + IN PXENNET_ADAPTER Adapter ); -MINIPORT_RETURN_NET_BUFFER_LISTS AdapterReturnNetBufferLists; -VOID -AdapterReturnNetBufferLists ( - IN NDIS_HANDLE MiniportAdapterContext, - IN PNET_BUFFER_LIST NetBufferLists, - IN ULONG ReturnFlags +#include <vif_interface.h> +extern PXENVIF_VIF_INTERFACE +AdapterGetVifInterface( + 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 NDIS_HANDLE +AdapterGetHandle( + IN PXENNET_ADAPTER Adapter ); -NDIS_STATUS -AdapterStop ( - IN PADAPTER Adapter - ); - -MINIPORT_SHUTDOWN AdapterShutdown; - -VOID -AdapterShutdown ( - IN NDIS_HANDLE MiniportAdapterContext, - IN NDIS_SHUTDOWN_ACTION ShutdownAction +extern NTSTATUS +AdapterInitialize( + IN NDIS_HANDLE NdisHandle, + OUT PXENNET_ADAPTER *Adapter ); extern VOID -ReceiverReceivePackets( - IN PRECEIVER Receiver, - IN PLIST_ENTRY List +AdapterTeardown( + IN PXENNET_ADAPTER Adapter ); + +#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/driver.c b/src/xennet/driver.c new file mode 100644 index 0000000..66aff1d --- /dev/null +++ b/src/xennet/driver.c @@ -0,0 +1,550 @@ +/* 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 <ndis.h> +#include <ntstrsafe.h> +#include <version.h> + +#include "adapter.h" +#include "transmitter.h" +#include "receiver.h" +#include "registry.h" +#include "dbg_print.h" +#include "assert.h" + +extern PULONG InitSafeBootMode; + +typedef struct _XENNET_DRIVER { + PDRIVER_OBJECT DriverObject; + NDIS_HANDLE MiniportHandle; + NTSTATUS (*NdisDispatchPnp)(PDEVICE_OBJECT, PIRP); +} XENNET_DRIVER; + +static XENNET_DRIVER Driver; + +MINIPORT_CANCEL_OID_REQUEST DriverCancelOidRequest; +VOID +DriverCancelOidRequest( + IN NDIS_HANDLE NdisHandle, + IN PVOID RequestId + ) +{ + UNREFERENCED_PARAMETER(NdisHandle); + UNREFERENCED_PARAMETER(RequestId); +} + +MINIPORT_CANCEL_SEND DriverCancelSendNetBufferLists; +VOID +DriverCancelSendNetBufferLists( + IN NDIS_HANDLE NdisHandle, + IN PVOID CancelId + ) +{ + UNREFERENCED_PARAMETER(NdisHandle); + UNREFERENCED_PARAMETER(CancelId); +} + +MINIPORT_CHECK_FOR_HANG DriverCheckForHang; +BOOLEAN +DriverCheckForHang( + IN NDIS_HANDLE NdisHandle + ) +{ + UNREFERENCED_PARAMETER(NdisHandle); + return FALSE; +} + +MINIPORT_DEVICE_PNP_EVENT_NOTIFY DriverPnPEventHandler; +VOID +DriverPnPEventHandler( + IN NDIS_HANDLE NdisHandle, + IN PNET_DEVICE_PNP_EVENT NetDevicePnPEvent + ) +{ + UNREFERENCED_PARAMETER(NdisHandle); + UNREFERENCED_PARAMETER(NetDevicePnPEvent); +} + +MINIPORT_RESET DriverReset; +NDIS_STATUS +DriverReset( + IN NDIS_HANDLE NdisHandle, + OUT PBOOLEAN AddressingReset + ) +{ + UNREFERENCED_PARAMETER(NdisHandle); + *AddressingReset = FALSE; + return NDIS_STATUS_SUCCESS; +} + +MINIPORT_OID_REQUEST DriverOidRequest; +NDIS_STATUS +DriverOidRequest( + IN NDIS_HANDLE NdisHandle, + IN PNDIS_OID_REQUEST NdisRequest + ) +{ + return AdapterOidRequest((PXENNET_ADAPTER)NdisHandle, NdisRequest); +} + +MINIPORT_PAUSE DriverPause; +NDIS_STATUS +DriverPause( + IN NDIS_HANDLE NdisHandle, + IN PNDIS_MINIPORT_PAUSE_PARAMETERS MiniportPauseParameters + ) +{ + UNREFERENCED_PARAMETER(MiniportPauseParameters); + + if (AdapterDisable((PXENNET_ADAPTER)NdisHandle)) + AdapterMediaStateChange((PXENNET_ADAPTER)NdisHandle); + + return NDIS_STATUS_SUCCESS; +} + +MINIPORT_RESTART DriverRestart; +NDIS_STATUS +DriverRestart( + IN NDIS_HANDLE NdisHandle, + IN PNDIS_MINIPORT_RESTART_PARAMETERS MiniportRestartParameters + ) +{ + NTSTATUS status; + + UNREFERENCED_PARAMETER(MiniportRestartParameters); + + status = AdapterEnable((PXENNET_ADAPTER)NdisHandle); + if (!NT_SUCCESS(status)) + goto fail1; + + return NDIS_STATUS_SUCCESS; + +fail1: + Error("fail1 (%08x)\n", status); + return NDIS_STATUS_FAILURE; +} + +MINIPORT_RETURN_NET_BUFFER_LISTS DriverReturnNetBufferLists; +VOID +DriverReturnNetBufferLists( + IN NDIS_HANDLE NdisHandle, + IN PNET_BUFFER_LIST NetBufferLists, + IN ULONG ReturnFlags + ) +{ + PXENNET_RECEIVER Receiver; + Receiver = AdapterGetReceiver((PXENNET_ADAPTER)NdisHandle); + ReceiverReturnNetBufferLists(Receiver, + NetBufferLists, + ReturnFlags); +} + +MINIPORT_SEND_NET_BUFFER_LISTS DriverSendNetBufferLists; +VOID +DriverSendNetBufferLists( + IN NDIS_HANDLE NdisHandle, + IN PNET_BUFFER_LIST NetBufferList, + IN NDIS_PORT_NUMBER PortNumber, + IN ULONG SendFlags + ) +{ + PXENNET_TRANSMITTER Transmitter; + Transmitter = AdapterGetTransmitter((PXENNET_ADAPTER)NdisHandle); + TransmitterSendNetBufferLists(Transmitter, + NetBufferList, + PortNumber, + SendFlags); +} + +MINIPORT_SHUTDOWN DriverShutdown; +VOID +DriverShutdown( + IN NDIS_HANDLE NdisHandle, + IN NDIS_SHUTDOWN_ACTION ShutdownAction + ) +{ + UNREFERENCED_PARAMETER(ShutdownAction); + + if (ShutdownAction != NdisShutdownBugCheck) + (VOID)AdapterDisable((PXENNET_ADAPTER)NdisHandle); +} + +MINIPORT_INITIALIZE DriverInitialize; +NDIS_STATUS +DriverInitialize( + IN NDIS_HANDLE NdisHandle, + IN NDIS_HANDLE DriverContext, + IN PNDIS_MINIPORT_INIT_PARAMETERS Parameters + ) +{ + NTSTATUS status; + PXENNET_ADAPTER Adapter; + + UNREFERENCED_PARAMETER(DriverContext); + UNREFERENCED_PARAMETER(Parameters); + + status = AdapterInitialize(NdisHandle, &Adapter); + if (!NT_SUCCESS(status)) + goto fail1; + + return NDIS_STATUS_SUCCESS; + +fail1: + Error("fail1 (%08x)\n", status); + return NDIS_STATUS_ADAPTER_NOT_FOUND; +} + +MINIPORT_HALT DriverHalt; +VOID +DriverHalt( + IN NDIS_HANDLE NdisHandle, + IN NDIS_HALT_ACTION HaltAction + ) +{ + if (NdisHandle == NULL) + return; + + UNREFERENCED_PARAMETER(HaltAction); + + (VOID)AdapterDisable((PXENNET_ADAPTER)NdisHandle); + AdapterTeardown((PXENNET_ADAPTER)NdisHandle); +} + +typedef struct _XENNET_CONTEXT { + PDEVICE_CAPABILITIES Capabilities; + PIO_COMPLETION_ROUTINE CompletionRoutine; + PVOID CompletionContext; + UCHAR CompletionControl; +} XENNET_CONTEXT, *PXENNET_CONTEXT; + +__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 = Driver.NdisDispatchPnp(DeviceObject, Irp); + + Trace("<====\n"); + + return status; +} + +_Dispatch_type_(IRP_MJ_PNP) +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 = Driver.NdisDispatchPnp(DeviceObject, Irp); + break; + } + + return status; +} + +_Dispatch_type_(IRP_MJ_CREATE) +_Dispatch_type_(IRP_MJ_CLOSE) +_Dispatch_type_(IRP_MJ_DEVICE_CONTROL) +DRIVER_DISPATCH DispatchFail; + +NTSTATUS +DispatchFail( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ) +{ + UNREFERENCED_PARAMETER(DeviceObject); + + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_UNSUCCESSFUL; +} + +MINIPORT_UNLOAD DriverUnload; + +VOID +DriverUnload( + IN PDRIVER_OBJECT DriverObject + ) +{ + Trace("====>\n"); + + if (*InitSafeBootMode > 0) + goto done; + + ASSERT3P(Driver.DriverObject, ==, DriverObject); + Driver.DriverObject = NULL; + + if (Driver.MiniportHandle) + NdisMDeregisterMiniportDriver(Driver.MiniportHandle); + Driver.MiniportHandle = NULL; + + Driver.NdisDispatchPnp = NULL; + + RegistryTeardown(); + + Info("XENNET %d.%d.%d (%d) (%02d.%02d.%04d)\n", + MAJOR_VERSION, + MINOR_VERSION, + MICRO_VERSION, + BUILD_NUMBER, + DAY, + MONTH, + YEAR); + +done: + Trace("<====\n"); +} + +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; + NTSTATUS status; + + ExInitializeDriverRuntime(DrvRtPoolNxOptIn); + + Trace("====>\n"); + + if (*InitSafeBootMode > 0) + return NDIS_STATUS_SUCCESS; + + ASSERT3P(Driver.DriverObject, ==, NULL); + Driver.DriverObject = DriverObject; + + Info("XENNET %d.%d.%d (%d) (%02d.%02d.%04d)\n", + MAJOR_VERSION, + MINOR_VERSION, + MICRO_VERSION, + BUILD_NUMBER, + DAY, + MONTH, + YEAR); + + status = RegistryInitialize(RegistryPath); + + ndisStatus = (NT_SUCCESS(status)) ? + NDIS_STATUS_SUCCESS : + NDIS_STATUS_FAILURE; + + if (ndisStatus != NDIS_STATUS_SUCCESS) + goto fail1; + + // + // Register miniport with NDIS. + // + + RtlZeroMemory(&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 = DriverCancelOidRequest; + mpChars.CancelSendHandler = DriverCancelSendNetBufferLists; + mpChars.CheckForHangHandlerEx = DriverCheckForHang; + mpChars.InitializeHandlerEx = DriverInitialize; + mpChars.HaltHandlerEx = DriverHalt; + mpChars.OidRequestHandler = DriverOidRequest; + mpChars.PauseHandler = DriverPause; + mpChars.DevicePnPEventNotifyHandler = DriverPnPEventHandler; + mpChars.ResetHandlerEx = DriverReset; + mpChars.RestartHandler = DriverRestart; + mpChars.ReturnNetBufferListsHandler = DriverReturnNetBufferLists; + mpChars.SendNetBufferListsHandler = DriverSendNetBufferLists; + mpChars.ShutdownHandlerEx = DriverShutdown; + mpChars.UnloadHandler = DriverUnload; + + Driver.MiniportHandle = NULL; + ndisStatus = NdisMRegisterMiniportDriver(DriverObject, + RegistryPath, + NULL, + &mpChars, + &Driver.MiniportHandle); + if (ndisStatus != NDIS_STATUS_SUCCESS) + goto fail2; + + RtlZeroMemory(&ConfigurationObject, sizeof(ConfigurationObject)); + ConfigurationObject.Header.Type = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT; + ConfigurationObject.Header.Size = NDIS_SIZEOF_CONFIGURATION_OBJECT_REVISION_1; + ConfigurationObject.Header.Revision = NDIS_CONFIGURATION_OBJECT_REVISION_1; + ConfigurationObject.NdisHandle = Driver.MiniportHandle; + ConfigurationObject.Flags = 0; + + ndisStatus = NdisOpenConfigurationEx(&ConfigurationObject, &ConfigurationHandle); + if (ndisStatus != NDIS_STATUS_SUCCESS) + goto fail3; + + 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); + + Driver.NdisDispatchPnp = DriverObject->MajorFunction[IRP_MJ_PNP]; + DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp; + + if (FailCreateClose != 0) { + DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchFail; + DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchFail; + } + + if (FailDeviceControl != 0) { + DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchFail; + } + + Trace("<====\n"); + return NDIS_STATUS_SUCCESS; + +fail3: + Error("fail3\n"); + + NdisMDeregisterMiniportDriver(Driver.MiniportHandle); + Driver.MiniportHandle = NULL; + +fail2: + Error("fail2\n"); + + RegistryTeardown(); + +fail1: + Error("fail1\n"); + + Driver.DriverObject = NULL; + return ndisStatus; +} + diff --git a/src/xennet/main.c b/src/xennet/main.c deleted file mode 100644 index 6622e82..0000000 --- a/src/xennet/main.c +++ /dev/null @@ -1,361 +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" -#include "registry.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; - NTSTATUS status; - - 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); - - status = RegistryInitialize(RegistryPath); - - ndisStatus = (NT_SUCCESS(status)) ? - NDIS_STATUS_SUCCESS : - NDIS_STATUS_FAILURE; - - if (ndisStatus != NDIS_STATUS_SUCCESS) - goto fail; - - // - // 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); - - RegistryTeardown(); - - 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/miniport.c b/src/xennet/miniport.c deleted file mode 100644 index a1d605f..0000000 --- a/src/xennet/miniport.c +++ /dev/null @@ -1,297 +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. - */ - -#define INITGUID 1 - -#include "common.h" -#include "registry.h" - -#pragma warning( disable : 4098 ) - -extern NTSTATUS AllocAdapter(PADAPTER *Adapter); - -#define SERVICES_KEY L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services" - -static FORCEINLINE NTSTATUS -__QueryInterface( - IN PDEVICE_OBJECT DeviceObject, - IN const WCHAR *ProviderName, - IN const CHAR *InterfaceName, - IN const GUID *Guid, - IN ULONG Version, - OUT PINTERFACE Interface, - IN ULONG Size, - IN BOOLEAN Optional - ) -{ - UNICODE_STRING Unicode; - HANDLE InterfacesKey; - HANDLE SubscriberKey; - KEVENT Event; - IO_STATUS_BLOCK StatusBlock; - PIRP Irp; - PIO_STACK_LOCATION StackLocation; - NTSTATUS status; - - ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL); - - Unicode.MaximumLength = (USHORT)((wcslen(SERVICES_KEY) + - 1 + - wcslen(ProviderName) + - 1 + - wcslen(L"Interfaces") + - 1) * sizeof (WCHAR)); - - Unicode.Buffer = ExAllocatePoolWithTag(NonPagedPool, - Unicode.MaximumLength, - 'TEN'); - - status = STATUS_NO_MEMORY; - if (Unicode.Buffer == NULL) - goto fail1; - - status = RtlStringCbPrintfW(Unicode.Buffer, - Unicode.MaximumLength, - SERVICES_KEY L"\\%ws\\Interfaces", - ProviderName); - ASSERT(NT_SUCCESS(status)); - - Unicode.Length = (USHORT)(wcslen(Unicode.Buffer) * sizeof (WCHAR)); - - status = RegistryOpenKey(NULL, &Unicode, KEY_READ, &InterfacesKey); - if (!NT_SUCCESS(status)) - goto fail2; - - status = RegistryCreateSubKey(InterfacesKey, - "XENNET", - REG_OPTION_NON_VOLATILE, - &SubscriberKey); - if (!NT_SUCCESS(status)) - goto fail3; - - KeInitializeEvent(&Event, NotificationEvent, FALSE); - RtlZeroMemory(&StatusBlock, sizeof(IO_STATUS_BLOCK)); - - Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, - DeviceObject, - NULL, - 0, - NULL, - &Event, - &StatusBlock); - - status = STATUS_UNSUCCESSFUL; - if (Irp == NULL) - goto fail4; - - StackLocation = IoGetNextIrpStackLocation(Irp); - StackLocation->MinorFunction = IRP_MN_QUERY_INTERFACE; - - 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; - } - - if (!NT_SUCCESS(status)) { - if (status == STATUS_NOT_SUPPORTED && Optional) - goto done; - - goto fail5; - } - - status = RegistryUpdateDwordValue(SubscriberKey, - (PCHAR)InterfaceName, - Version); - if (!NT_SUCCESS(status)) - goto fail6; - -done: - RegistryCloseKey(SubscriberKey); - - RegistryCloseKey(InterfacesKey); - - ExFreePool(Unicode.Buffer); - - return STATUS_SUCCESS; - -fail6: - Error("fail6\n"); - -fail5: - Error("fail5\n"); - -fail4: - Error("fail4\n"); - - RegistryCloseKey(SubscriberKey); - -fail3: - Error("fail3\n"); - - RegistryCloseKey(InterfacesKey); - -fail2: - Error("fail2\n"); - - ExFreePool(Unicode.Buffer); - -fail1: - Error("fail1 (%08x)\n", status); - - return status; -} - -#define QUERY_INTERFACE( \ - _DeviceObject, \ - _ProviderName, \ - _InterfaceName, \ - _Version, \ - _Interface, \ - _Size, \ - _Optional) \ - __QueryInterface((_DeviceObject), \ - L ## #_ProviderName, \ - #_InterfaceName, \ - &GUID_ ## _ProviderName ## _ ## _InterfaceName ## _INTERFACE, \ - (_Version), \ - (_Interface), \ - (_Size), \ - (_Optional)) - -NDIS_STATUS -MiniportInitialize ( - IN NDIS_HANDLE MiniportAdapterHandle, - IN NDIS_HANDLE MiniportDriverContext, - IN PNDIS_MINIPORT_INIT_PARAMETERS MiniportInitParameters - ) -{ - PADAPTER Adapter = NULL; - NDIS_STATUS ndisStatus; - PDEVICE_OBJECT DeviceObject; - NTSTATUS status; - - UNREFERENCED_PARAMETER(MiniportDriverContext); - UNREFERENCED_PARAMETER(MiniportInitParameters); - - Trace("====>\n"); - - status = AllocAdapter(&Adapter); - - if (!NT_SUCCESS(status) || Adapter == NULL) { - ndisStatus = NDIS_STATUS_RESOURCES; - goto fail1; - } - - RtlZeroMemory(Adapter, sizeof (ADAPTER)); - - DeviceObject = NULL; - NdisMGetDeviceProperty(MiniportAdapterHandle, - &DeviceObject, - NULL, - NULL, - NULL, - NULL); - - status = QUERY_INTERFACE(DeviceObject, - XENVIF, - VIF, - XENVIF_VIF_INTERFACE_VERSION_MAX, - (PINTERFACE)&Adapter->VifInterface, - sizeof (Adapter->VifInterface), - FALSE); - - if (!NT_SUCCESS(status)) { - ndisStatus = NDIS_STATUS_ADAPTER_NOT_FOUND; - goto fail2; - } - - ndisStatus = AdapterInitialize(Adapter, MiniportAdapterHandle); - if (ndisStatus != NDIS_STATUS_SUCCESS) { - goto fail3; - } - - Trace("<====\n"); - return ndisStatus; - -fail3: - Error("fail3\n"); - - RtlZeroMemory(&Adapter->VifInterface, - sizeof (XENVIF_VIF_INTERFACE)); - -fail2: - Error("fail2\n"); - - ExFreePool(Adapter); - -fail1: - Error("fail1\n"); - - return ndisStatus; -} - -// -// Stops adapter and frees all resources. -// -VOID -MiniportHalt ( - IN NDIS_HANDLE MiniportAdapterHandle, - IN NDIS_HALT_ACTION HaltAction - ) -{ - PADAPTER Adapter = (PADAPTER)MiniportAdapterHandle; - - UNREFERENCED_PARAMETER(HaltAction); - - if (Adapter == NULL) - return; - - (VOID) AdapterStop(Adapter); - - AdapterCleanup(Adapter); - - RtlZeroMemory(&Adapter->VifInterface, - sizeof (XENVIF_VIF_INTERFACE)); - - ExFreePool(Adapter); -} 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..ee01a18 100644 --- a/src/xennet/receiver.c +++ b/src/xennet/receiver.c @@ -29,103 +29,38 @@ * SUCH DAMAGE. */ -#include "common.h" - -#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; -} +#include <ndis.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 'teNX' +#define IN_NDIS_MAX 1024 -PNET_BUFFER_LIST +static PNET_BUFFER_LIST ReceiverAllocateNetBufferList( - IN PRECEIVER Receiver, - IN PMDL Mdl, - IN ULONG Offset, - IN ULONG Length + 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(); - NetBufferList = Receiver->GetList[Cpu]; if (NetBufferList == NULL) @@ -158,16 +93,16 @@ ReceiverAllocateNetBufferList( return NetBufferList; } -VOID +static VOID ReceiverReleaseNetBufferList( - IN PRECEIVER Receiver, - IN PNET_BUFFER_LIST NetBufferList, - IN BOOLEAN Cache + IN PXENNET_RECEIVER Receiver, + IN PNET_BUFFER_LIST NetBufferList, + IN BOOLEAN Cache ) { if (Cache) { - PNET_BUFFER_LIST Old; - PNET_BUFFER_LIST New; + PNET_BUFFER_LIST Old; + PNET_BUFFER_LIST New; ASSERT3P(NET_BUFFER_LIST_NEXT_NBL(NetBufferList), ==, NULL); @@ -182,72 +117,9 @@ ReceiverReleaseNetBufferList( } } -static FORCEINLINE ULONG -__ReceiverReturnNetBufferLists( - IN PRECEIVER Receiver, - IN PNET_BUFFER_LIST NetBufferList, - IN BOOLEAN Cache - ) -{ - PADAPTER Adapter; - LIST_ENTRY List; - ULONG Count; - - Adapter = CONTAINING_RECORD(Receiver, ADAPTER, Receiver); - - InitializeListHead(&List); - - Count = 0; - while (NetBufferList != NULL) { - PNET_BUFFER_LIST Next; - PNET_BUFFER NetBuffer; - PMDL Mdl; - PXENVIF_RECEIVER_PACKET Packet; - - Next = NET_BUFFER_LIST_NEXT_NBL(NetBufferList); - NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL; - - NetBuffer = NET_BUFFER_LIST_FIRST_NB(NetBufferList); - ASSERT3P(NET_BUFFER_NEXT_NB(NetBuffer), ==, NULL); - - Mdl = NET_BUFFER_FIRST_MDL(NetBuffer); - - ReceiverReleaseNetBufferList(Receiver, NetBufferList, Cache); - - Packet = CONTAINING_RECORD(Mdl, XENVIF_RECEIVER_PACKET, Mdl); - - InsertTailList(&List, &Packet->ListEntry); - - Count++; - NetBufferList = Next; - } - - if (Count != 0) - XENVIF_VIF(ReceiverReturnPackets, - &Adapter->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 PXENNET_RECEIVER Receiver, IN PMDL Mdl, IN ULONG Offset, IN ULONG Length, @@ -255,11 +127,11 @@ ReceiverReceivePacket( IN USHORT TagControlInformation ) { - PADAPTER Adapter; + PXENNET_ADAPTER Adapter; PNET_BUFFER_LIST NetBufferList; NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO csumInfo; - Adapter = CONTAINING_RECORD(Receiver, ADAPTER, Receiver); + Adapter = Receiver->Adapter; NetBufferList = ReceiverAllocateNetBufferList(Receiver, Mdl, @@ -268,7 +140,7 @@ ReceiverReceivePacket( if (NetBufferList == NULL) goto fail1; - NetBufferList->SourceHandle = Adapter->NdisAdapterHandle; + NetBufferList->SourceHandle = AdapterGetHandle(Adapter); csumInfo.Value = 0; @@ -281,8 +153,8 @@ ReceiverReceivePacket( csumInfo.Receive.UdpChecksumSucceeded = Flags.UdpChecksumSucceeded; csumInfo.Receive.UdpChecksumFailed = Flags.UdpChecksumFailed; - NET_BUFFER_LIST_INFO(NetBufferList, TcpIpChecksumNetBufferListInfo) = (PVOID)(ULONG_PTR)csumInfo.Value; - + NET_BUFFER_LIST_INFO(NetBufferList, TcpIpChecksumNetBufferListInfo) = + (PVOID)(ULONG_PTR)csumInfo.Value; if (TagControlInformation != 0) { NDIS_NET_BUFFER_LIST_8021Q_INFO Ieee8021QInfo; @@ -306,20 +178,67 @@ fail1: return NULL; } +static FORCEINLINE ULONG +__ReceiverReturnNetBufferLists( + IN PXENNET_RECEIVER Receiver, + IN PNET_BUFFER_LIST NetBufferList, + IN BOOLEAN Cache + ) +{ + PXENNET_ADAPTER Adapter; + LIST_ENTRY List; + ULONG Count; + + Adapter = Receiver->Adapter; + + InitializeListHead(&List); + + Count = 0; + while (NetBufferList != NULL) { + PNET_BUFFER_LIST Next; + PNET_BUFFER NetBuffer; + PMDL Mdl; + PXENVIF_RECEIVER_PACKET Packet; + + Next = NET_BUFFER_LIST_NEXT_NBL(NetBufferList); + NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL; + + NetBuffer = NET_BUFFER_LIST_FIRST_NB(NetBufferList); + ASSERT3P(NET_BUFFER_NEXT_NB(NetBuffer), ==, NULL); + + Mdl = NET_BUFFER_FIRST_MDL(NetBuffer); + + ReceiverReleaseNetBufferList(Receiver, NetBufferList, Cache); + + Packet = CONTAINING_RECORD(Mdl, XENVIF_RECEIVER_PACKET, Mdl); + + InsertTailList(&List, &Packet->ListEntry); + + Count++; + NetBufferList = Next; + } + + if (Count != 0) { + XENVIF_VIF(ReceiverReturnPackets, + AdapterGetVifInterface(Adapter), + &List); + } + return Count; +} + static VOID ReceiverPushPackets( - IN PRECEIVER Receiver, + IN PXENNET_RECEIVER Receiver, IN PNET_BUFFER_LIST NetBufferList, IN ULONG Count, IN BOOLEAN LowResources ) { - PADAPTER Adapter; + PXENNET_ADAPTER Adapter; ULONG Flags; LONG InNDIS; - Adapter = CONTAINING_RECORD(Receiver, ADAPTER, Receiver); - + Adapter = Receiver->Adapter; InNDIS = Receiver->InNDIS; Flags = NDIS_RECEIVE_FLAGS_DISPATCH_LEVEL; @@ -342,7 +261,7 @@ ReceiverPushPackets( break; } - NdisMIndicateReceiveNetBufferLists(Adapter->NdisAdapterHandle, + NdisMIndicateReceiveNetBufferLists(AdapterGetHandle(Adapter), NetBufferList, NDIS_DEFAULT_PORT_NUMBER, Count, @@ -352,21 +271,34 @@ ReceiverPushPackets( (VOID) __ReceiverReturnNetBufferLists(Receiver, NetBufferList, FALSE); } -#define IN_NDIS_MAX 1024 +VOID +ReceiverReturnNetBufferLists( + IN PXENNET_RECEIVER Receiver, + IN PNET_BUFFER_LIST NetBufferLists, + IN ULONG ReturnFlags + ) +{ + ULONG Count; + + UNREFERENCED_PARAMETER(ReturnFlags); + + Count = __ReceiverReturnNetBufferLists(Receiver, NetBufferLists, 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; + PXENNET_ADAPTER Adapter; PNET_BUFFER_LIST HeadNetBufferList; PNET_BUFFER_LIST *TailNetBufferList; ULONG Count; BOOLEAN LowResources; - Adapter = CONTAINING_RECORD(Receiver, ADAPTER, Receiver); + Adapter = Receiver->Adapter; LowResources = FALSE; again: @@ -404,21 +336,26 @@ 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); + AdapterGetVifInterface(Adapter), + &PacketList); } } @@ -434,3 +371,95 @@ again: goto again; } } + +PXENVIF_VIF_OFFLOAD_OPTIONS +ReceiverOffloadOptions( + IN PXENNET_RECEIVER Receiver + ) +{ + return &Receiver->OffloadOptions; +} + +NTSTATUS +ReceiverInitialize( + IN PXENNET_ADAPTER Adapter, + OUT PXENNET_RECEIVER *Receiver + ) +{ + NTSTATUS status; + NET_BUFFER_LIST_POOL_PARAMETERS Pool; + + status = STATUS_NO_MEMORY; + *Receiver = ExAllocatePoolWithTag(NonPagedPool, sizeof(XENNET_RECEIVER), RECEIVER_POOL_TAG); + if (*Receiver == NULL) + goto fail1; + + RtlZeroMemory(*Receiver, sizeof(XENNET_RECEIVER)); + (*Receiver)->Adapter = Adapter; + + RtlZeroMemory(&Pool, sizeof(NET_BUFFER_LIST_POOL_PARAMETERS)); + Pool.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + Pool.Header.Size = sizeof(NET_BUFFER_LIST_POOL_PARAMETERS); + Pool.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1; + Pool.ProtocolId = 0; + Pool.ContextSize = 0; + Pool.fAllocateNetBuffer = TRUE; + Pool.PoolTag = RECEIVER_POOL_TAG; + + (*Receiver)->NetBufferListPool = NdisAllocateNetBufferListPool(AdapterGetHandle(Adapter), + &Pool); + if ((*Receiver)->NetBufferListPool == NULL) + goto fail2; + + return STATUS_SUCCESS; + +fail2: + Error("fail2\n"); + ExFreePoolWithTag(*Receiver, RECEIVER_POOL_TAG); +fail1: + Error("fail1 (%08x)\n", status); + 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; + + ExFreePoolWithTag(Receiver, RECEIVER_POOL_TAG); +} + diff --git a/src/xennet/receiver.h b/src/xennet/receiver.h index 1a58053..715f02e 100644 --- a/src/xennet/receiver.h +++ b/src/xennet/receiver.h @@ -29,49 +29,42 @@ * 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; +typedef struct _XENNET_RECEIVER XENNET_RECEIVER, *PXENNET_RECEIVER; -VOID -ReceiverDebugDump ( - IN PRECEIVER Receiver - ); +#include <vif_interface.h> -VOID -ReceiverCleanup ( - IN PRECEIVER Receiver +extern VOID +ReceiverReturnNetBufferLists( + IN PXENNET_RECEIVER Receiver, + IN PNET_BUFFER_LIST NetBufferLists, + IN ULONG ReturnFlags ); -VOID -ReceiverHandleNotification ( - IN PRECEIVER Receiver +extern VOID +ReceiverReceivePackets( + IN PXENNET_RECEIVER Receiver, + IN PLIST_ENTRY List ); -NDIS_STATUS -ReceiverInitialize ( - IN PRECEIVER Receiver +extern PXENVIF_VIF_OFFLOAD_OPTIONS +ReceiverOffloadOptions( + IN PXENNET_RECEIVER Receiver ); -VOID -ReceiverReturnNetBufferLists ( - IN PRECEIVER Receiver, - IN PNET_BUFFER_LIST NetBufferList, - IN ULONG ReturnFlags +#include "adapter.h" +extern NTSTATUS +ReceiverInitialize( + IN PXENNET_ADAPTER Adapter, + OUT PXENNET_RECEIVER *Receiver ); -VOID -ReceiverWaitForPacketReturn( - IN PRECEIVER Receiver, - IN BOOLEAN Locked +extern VOID +ReceiverTeardown( + 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..be07458 100644 --- a/src/xennet/transmitter.c +++ b/src/xennet/transmitter.c @@ -29,59 +29,18 @@ * SUCH DAMAGE. */ -#include "common.h" +#include <ndis.h> +#include "transmitter.h" +#include "adapter.h" +#include "dbg_print.h" +#include "assert.h" -#pragma warning(disable:4711) +struct _XENNET_TRANSMITTER { + PXENNET_ADAPTER Adapter; + XENVIF_VIF_OFFLOAD_OPTIONS OffloadOptions; +}; -NDIS_STATUS -TransmitterInitialize( - IN PTRANSMITTER Transmitter, - IN PADAPTER Adapter - ) -{ - Transmitter->Adapter = Adapter; - - return NDIS_STATUS_SUCCESS; -} - -VOID -TransmitterEnable( - IN PTRANSMITTER Transmitter - ) -{ - PADAPTER Adapter = Transmitter->Adapter; - - (VOID) XENVIF_VIF(TransmitterSetPacketOffset, - &Adapter->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, - 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, - 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; - } -} +#define TRANSMITTER_POOL_TAG 'teNX' typedef struct _NET_BUFFER_LIST_RESERVED { LONG Reference; @@ -97,24 +56,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 NdisStatus ) { + PXENNET_ADAPTER Adapter = Transmitter->Adapter; + ASSERT3P(NET_BUFFER_LIST_NEXT_NBL(NetBufferList), ==, NULL); - NET_BUFFER_LIST_STATUS(NetBufferList) = NDIS_STATUS_NOT_ACCEPTED; + if (NdisStatus == 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; + } + NET_BUFFER_LIST_STATUS(NetBufferList) = NdisStatus; - NdisMSendNetBufferListsComplete(Transmitter->Adapter->NdisAdapterHandle, + NdisMSendNetBufferListsComplete(AdapterGetHandle(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 NdisStatus ) { while (Packet != NULL) { @@ -135,21 +107,85 @@ TransmitterAbortPackets( ASSERT(ListReserved->Reference != 0); if (InterlockedDecrement(&ListReserved->Reference) == 0) - TransmitterAbortNetBufferList(Transmitter, NetBufferList); + TransmitterCompleteNetBufferList(Transmitter, NetBufferList, NdisStatus); Packet = Next; } } + +static FORCEINLINE VOID +__OffloadOptions( + IN PNET_BUFFER_LIST NetBufferList, + OUT PXENVIF_VIF_OFFLOAD_OPTIONS Offload, + 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); + + Offload->Value = 0; + *TagControlInformation = 0; + *MaximumSegmentSize = 0; + + if (ChecksumInfo->Transmit.IsIPv4) { + if (ChecksumInfo->Transmit.IpHeaderChecksum) + Offload->OffloadIpVersion4HeaderChecksum = 1; + if (ChecksumInfo->Transmit.TcpChecksum) + Offload->OffloadIpVersion4TcpChecksum = 1; + if (ChecksumInfo->Transmit.UdpChecksum) + Offload->OffloadIpVersion4UdpChecksum = 1; + } + + if (ChecksumInfo->Transmit.IsIPv6) { + if (ChecksumInfo->Transmit.TcpChecksum) + Offload->OffloadIpVersion6TcpChecksum = 1; + if (ChecksumInfo->Transmit.UdpChecksum) + Offload->OffloadIpVersion6UdpChecksum = 1; + } + + if (Ieee8021QInfo->TagHeader.UserPriority != 0) { + Offload->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) + Offload->OffloadIpVersion4LargePacket = 1; + if (LargeSendInfo->LsoV2Transmit.IPVersion == NDIS_TCP_LARGE_SEND_OFFLOAD_IPv6) + Offload->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; + PXENNET_ADAPTER Adapter = Transmitter->Adapter; PXENVIF_TRANSMITTER_PACKET HeadPacket; PXENVIF_TRANSMITTER_PACKET *TailPacket; KIRQL Irql; @@ -158,21 +194,21 @@ TransmitterSendNetBufferLists( HeadPacket = NULL; TailPacket = &HeadPacket; - + if (!NDIS_TEST_SEND_AT_DISPATCH_LEVEL(SendFlags)) { ASSERT3U(NDIS_CURRENT_IRQL(), <=, DISPATCH_LEVEL); NDIS_RAISE_IRQL_TO_DISPATCH(&Irql); } else { Irql = DISPATCH_LEVEL; } - + 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; + XENVIF_VIF_OFFLOAD_OPTIONS Options; + USHORT TagControlInformation; + USHORT MaximumSegmentSize; + PNET_BUFFER NetBuffer; ListNext = NET_BUFFER_LIST_NEXT_NBL(NetBufferList); NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL; @@ -180,12 +216,7 @@ TransmitterSendNetBufferLists( 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); + __OffloadOptions(NetBufferList, &Options, &TagControlInformation, &MaximumSegmentSize); NetBuffer = NET_BUFFER_LIST_FIRST_NB(NetBufferList); while (NetBuffer != NULL) { @@ -199,50 +230,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 = Options.Value & Transmitter->OffloadOptions.Value; + Packet->Send.TagControlInformation = TagControlInformation; + Packet->Send.MaximumSegmentSize = MaximumSegmentSize; ASSERT3P(Packet->Next, ==, NULL); *TailPacket = Packet; @@ -258,65 +248,89 @@ TransmitterSendNetBufferLists( NTSTATUS status; status = XENVIF_VIF(TransmitterQueuePackets, - &Adapter->VifInterface, + AdapterGetVifInterface(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 +VOID +TransmitterCompletePackets( + IN PXENNET_TRANSMITTER Transmitter, + IN PXENVIF_TRANSMITTER_PACKET Packet ) { - PADAPTER Adapter = Transmitter->Adapter; - PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO LargeSendInfo; + __TransmitterCompletePackets(Transmitter, + Packet, + NDIS_STATUS_SUCCESS); +} - ASSERT3P(NET_BUFFER_LIST_NEXT_NBL(NetBufferList), ==, NULL); +VOID +TransmitterEnable( + IN PXENNET_TRANSMITTER Transmitter + ) +{ + PXENVIF_VIF_INTERFACE Vif = AdapterGetVifInterface(Transmitter->Adapter); - LargeSendInfo = (PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO)&NET_BUFFER_LIST_INFO(NetBufferList, - TcpLargeSendNetBufferListInfo); + (VOID) XENVIF_VIF(TransmitterSetPacketOffset, + Vif, + XENVIF_TRANSMITTER_PACKET_OFFSET_OFFSET, + (LONG_PTR)&NET_BUFFER_CURRENT_MDL_OFFSET((PNET_BUFFER)NULL) - + (LONG_PTR)&NET_BUFFER_MINIPORT_RESERVED((PNET_BUFFER)NULL)); - if (LargeSendInfo->LsoV2Transmit.MSS != 0) - LargeSendInfo->LsoV2TransmitComplete.Reserved = 0; + (VOID) XENVIF_VIF(TransmitterSetPacketOffset, + Vif, + XENVIF_TRANSMITTER_PACKET_LENGTH_OFFSET, + (LONG_PTR)&NET_BUFFER_DATA_LENGTH((PNET_BUFFER)NULL) - + (LONG_PTR)&NET_BUFFER_MINIPORT_RESERVED((PNET_BUFFER)NULL)); - NET_BUFFER_LIST_STATUS(NetBufferList) = NDIS_STATUS_SUCCESS; + (VOID) XENVIF_VIF(TransmitterSetPacketOffset, + Vif, + XENVIF_TRANSMITTER_PACKET_MDL_OFFSET, + (LONG_PTR)&NET_BUFFER_CURRENT_MDL((PNET_BUFFER)NULL) - + (LONG_PTR)&NET_BUFFER_MINIPORT_RESERVED((PNET_BUFFER)NULL)); +} - NdisMSendNetBufferListsComplete(Adapter->NdisAdapterHandle, - NetBufferList, - NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL); +PXENVIF_VIF_OFFLOAD_OPTIONS +TransmitterOffloadOptions( + IN PXENNET_TRANSMITTER Transmitter + ) +{ + return &Transmitter->OffloadOptions; } -VOID -TransmitterCompletePackets( - IN PTRANSMITTER Transmitter, - IN PXENVIF_TRANSMITTER_PACKET Packet +NTSTATUS +TransmitterInitialize( + IN PXENNET_ADAPTER Adapter, + OUT PXENNET_TRANSMITTER *Transmitter ) { - while (Packet != NULL) { - PXENVIF_TRANSMITTER_PACKET Next; - PNET_BUFFER_RESERVED Reserved; - PNET_BUFFER_LIST NetBufferList; - PNET_BUFFER_LIST_RESERVED ListReserved; + NTSTATUS status; - Next = Packet->Next; - Packet->Next = NULL; + status = STATUS_NO_MEMORY; + *Transmitter = ExAllocatePoolWithTag(NonPagedPool, sizeof(XENNET_TRANSMITTER), TRANSMITTER_POOL_TAG); + if (*Transmitter == NULL) + goto fail1; - Reserved = CONTAINING_RECORD(Packet, NET_BUFFER_RESERVED, Packet); + RtlZeroMemory(*Transmitter, sizeof(XENNET_TRANSMITTER)); + (*Transmitter)->Adapter = Adapter; - NetBufferList = Reserved->NetBufferList; - ASSERT(NetBufferList != NULL); + return STATUS_SUCCESS; - ListReserved = (PNET_BUFFER_LIST_RESERVED)NET_BUFFER_LIST_MINIPORT_RESERVED(NetBufferList); +fail1: + Error("fail1 (%08x)\n", status); + return status; - ASSERT(ListReserved->Reference != 0); - if (InterlockedDecrement(&ListReserved->Reference) == 0) - TransmitterCompleteNetBufferList(Transmitter, NetBufferList); +} - Packet = Next; - } +VOID +TransmitterTeardown( + IN PXENNET_TRANSMITTER Transmitter + ) +{ + ExFreePoolWithTag(Transmitter, TRANSMITTER_POOL_TAG); } + diff --git a/src/xennet/transmitter.h b/src/xennet/transmitter.h index 8dc7e8d..f99ffd3 100644 --- a/src/xennet/transmitter.h +++ b/src/xennet/transmitter.h @@ -29,47 +29,48 @@ * SUCH DAMAGE. */ -#pragma once +#ifndef _XENNET_TRANSMITTER_H_ +#define _XENNET_TRANSMITTER_H_ -typedef struct _TRANSMITTER { - PADAPTER Adapter; - XENVIF_VIF_OFFLOAD_OPTIONS OffloadOptions; -} TRANSMITTER, *PTRANSMITTER; +typedef struct _XENNET_TRANSMITTER XENNET_TRANSMITTER, *PXENNET_TRANSMITTER; -VOID -TransmitterCleanup ( - IN OUT PTRANSMITTER* Transmitter +#include <vif_interface.h> + +extern VOID +TransmitterSendNetBufferLists( + IN PXENNET_TRANSMITTER Transmitter, + IN PNET_BUFFER_LIST NetBufferList, + IN NDIS_PORT_NUMBER PortNumber, + IN ULONG SendFlags ); -NDIS_STATUS -TransmitterInitialize ( - IN PTRANSMITTER Transmitter, - IN PADAPTER Adapter +extern VOID +TransmitterCompletePackets( + IN PXENNET_TRANSMITTER Transmitter, + IN PXENVIF_TRANSMITTER_PACKET Packet ); -VOID -TransmitterEnable ( - IN PTRANSMITTER Transmitter +extern VOID +TransmitterEnable( + IN PXENNET_TRANSMITTER Transmitter ); -VOID -TransmitterDelete ( - IN OUT PTRANSMITTER* Transmitter +extern PXENVIF_VIF_OFFLOAD_OPTIONS +TransmitterOffloadOptions( + IN PXENNET_TRANSMITTER Transmitter ); -VOID -TransmitterSendNetBufferLists ( - IN PTRANSMITTER Transmitter, - IN PNET_BUFFER_LIST NetBufferList, - IN NDIS_PORT_NUMBER PortNumber, - IN ULONG SendFlags +#include "adapter.h" +extern NTSTATUS +TransmitterInitialize( + IN PXENNET_ADAPTER Adapter, + OUT PXENNET_TRANSMITTER *Transmitter ); -VOID -TransmitterCompletePackets( - IN PTRANSMITTER Transmitter, - IN PXENVIF_TRANSMITTER_PACKET Packet +extern VOID +TransmitterTeardown( + IN PXENNET_TRANSMITTER Transmitter ); -void TransmitterPause(PTRANSMITTER Transmitter); -void TransmitterUnpause(PTRANSMITTER Transmitter); +#endif // _XENNET_TRANSMITTER_H_ + diff --git a/vs2012/xennet/xennet.vcxproj b/vs2012/xennet/xennet.vcxproj index db07e9b..4b6e780 100644 --- a/vs2012/xennet/xennet.vcxproj +++ b/vs2012/xennet/xennet.vcxproj @@ -84,9 +84,8 @@ </ItemGroup> <ItemGroup> <ClCompile Include="../../src/xennet/registry.c" /> + <ClCompile Include="../../src/xennet/driver.c" /> <ClCompile Include="../../src/xennet/adapter.c" /> - <ClCompile Include="../../src/xennet/main.c" /> - <ClCompile Include="../../src/xennet/miniport.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 908bc2d..d890878 100644 --- a/vs2013/xennet/xennet.vcxproj +++ b/vs2013/xennet/xennet.vcxproj @@ -115,9 +115,8 @@ </ItemGroup> <ItemGroup> <ClCompile Include="../../src/xennet/registry.c" /> + <ClCompile Include="../../src/xennet/driver.c" /> <ClCompile Include="../../src/xennet/adapter.c" /> - <ClCompile Include="../../src/xennet/main.c" /> - <ClCompile Include="../../src/xennet/miniport.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 |