[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[win-pv-devel] [PATCH 3/6] Refactor for more maintainability.



Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx>
---
 src/xennet/adapter.c         | 3515 ++++++++++++++++++------------------------
 src/xennet/adapter.h         |  148 +-
 src/xennet/common.h          |   36 -
 src/xennet/main.c            |  348 -----
 src/xennet/project.h         |   66 -
 src/xennet/receiver.c        |  328 ++--
 src/xennet/receiver.h        |   58 +-
 src/xennet/std.h             |   45 -
 src/xennet/transmitter.c     |  301 ++--
 src/xennet/transmitter.h     |   50 +-
 vs2012/xennet/xennet.vcxproj |    3 +-
 vs2013/xennet/xennet.vcxproj |    3 +-
 12 files changed, 1963 insertions(+), 2938 deletions(-)
 delete mode 100644 src/xennet/common.h
 delete mode 100644 src/xennet/main.c
 delete mode 100644 src/xennet/project.h
 delete mode 100644 src/xennet/std.h

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


_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
http://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.