* 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[] =
{
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 (
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);
List = va_arg(Arguments, PLIST_ENTRY);
- ReceiverReceivePackets(&Adapter->Receiver, List);
+ ReceiverReceivePackets(Adapter->Receiver, List);
break;
}
case XENVIF_MAC_STATE_CHANGE: {
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;
-
- ndisStatus = NdisOpenConfigurationEx(&configObject, &hConfigurationHandle);
+ NDIS_STATUS_INDICATION Status;
+ NDIS_OFFLOAD Offload;
+ PXENVIF_VIF_OFFLOAD_OPTIONS RxOptions;
+ PXENVIF_VIF_OFFLOAD_OPTIONS TxOptions;
- 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;
+ RxOptions = ReceiverOffloadOptions(Adapter->Receiver);
+ TxOptions = TransmitterOffloadOptions(Adapter->Transmitter);
-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;
-
- switch (NdisRequest->RequestType) {
- case NdisRequestSetInformation:
- ndisStatus = AdapterSetInformation(Adapter, NdisRequest);
- break;
-
- case NdisRequestQueryInformation:
- case NdisRequestQueryStatistics:
- ndisStatus = AdapterQueryInformation(Adapter, NdisRequest);
- break;
-
- default:
- ndisStatus = NDIS_STATUS_NOT_SUPPORTED;
- break;
- };
+ XENVIF_VIF(MacQueryFilterLevel,
+ &Adapter->VifInterface,
+ ETHERNET_ADDRESS_BROADCAST,
+ &BroadcastFilterLevel);
- return ndisStatus;
+ *PacketFilter = 0;
+
+ if (UnicastFilterLevel == XENVIF_MAC_FILTER_ALL) {
+ ASSERT3U(MulticastFilterLevel, ==, XENVIF_MAC_FILTER_ALL);
+ ASSERT3U(BroadcastFilterLevel, ==, XENVIF_MAC_FILTER_ALL);
+
+ *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);
+ }
+
+ 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;
- 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);
+invalid_parameter:
+ return NDIS_STATUS_INVALID_PARAMETER;
+}
+
+#undef NO_CHANGE
+#undef RX_ENABLED
+#undef TX_ENABLED
+#undef CHANGE
- NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_RCV_ERROR;
+static NDIS_STATUS
+AdapterQueryGeneralStatistics(
+ IN PXENNET_ADAPTER Adapter,
+ IN PNDIS_STATISTICS_INFO Info
+ )
+{
+ ULONGLONG Value;
+ 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);
+ Info->ifHCInUcastPkts = Value;
- NdisStatisticsInfo->ifHCInUcastPkts = Value;
-
- NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_RCV;
-
+ 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);
- if (MulticastFilterLevel == XENVIF_MAC_FILTER_ALL)
- *PacketFilter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
- else if (MulticastFilterLevel == XENVIF_MAC_FILTER_MATCHING)
- *PacketFilter |= NDIS_PACKET_TYPE_MULTICAST;
+ *Buffer += (ULONG)Value;
- if (BroadcastFilterLevel == XENVIF_MAC_FILTER_ALL)
- *PacketFilter |= NDIS_PACKET_TYPE_BROADCAST;
+ XENVIF_VIF(QueryStatistic,
+ &Adapter->VifInterface,
+ XENVIF_TRANSMITTER_BROADCAST_PACKETS,
+ &Value);
+
+ *Buffer += (ULONG)Value;
+
+ 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);
- 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;
+ *Buffer += (ULONG)Value;
- XENVIF_VIF(MacQueryState,
- &Adapter->VifInterface,
- NULL,
- &LinkSpeed,
- NULL);
+ XENVIF_VIF(QueryStatistic,
+ &Adapter->VifInterface,
+ XENVIF_RECEIVER_BROADCAST_PACKETS,
+ &Value);
- 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);
+ *Buffer += (ULONG)Value;
- infoData = Value;
+ return NDIS_STATUS_SUCCESS;
+}
- XENVIF_VIF(QueryStatistic,
- &Adapter->VifInterface,
- XENVIF_TRANSMITTER_MULTICAST_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_BROADCAST_PACKETS,
- &Value);
+ *Buffer = (ULONG)Value;
- infoData += Value;
+ XENVIF_VIF(QueryStatistic,
+ &Adapter->VifInterface,
+ XENVIF_TRANSMITTER_FRONTEND_ERRORS,
+ &Value);
- info = &infoData;
- bytesAvailable = sizeof(ULONGLONG);
- break;
- }
- case OID_GEN_RCV_OK: {
- ULONGLONG Value;
+ *Buffer += (ULONG)Value;
- XENVIF_VIF(QueryStatistic,
- &Adapter->VifInterface,
- XENVIF_RECEIVER_UNICAST_PACKETS,
- &Value);
+ return NDIS_STATUS_SUCCESS;
+}
- infoData = Value;
+static FORCEINLINE NDIS_STATUS
+AdapterGetRcvError(
+ IN PXENNET_ADAPTER Adapter,
+ OUT PULONG Buffer
+ )
+{
+ ULONGLONG Value;
- XENVIF_VIF(QueryStatistic,
- &Adapter->VifInterface,
- XENVIF_RECEIVER_MULTICAST_PACKETS,
- &Value);
+ XENVIF_VIF(QueryStatistic,
+ &Adapter->VifInterface,
+ XENVIF_RECEIVER_BACKEND_ERRORS,
+ &Value);
- infoData += Value;
+ *Buffer = (ULONG)Value;
- XENVIF_VIF(QueryStatistic,
- &Adapter->VifInterface,
- XENVIF_RECEIVER_BROADCAST_PACKETS,
- &Value);
+ XENVIF_VIF(QueryStatistic,
+ &Adapter->VifInterface,
+ XENVIF_RECEIVER_FRONTEND_ERRORS,
+ &Value);
- infoData += Value;
+ *Buffer += (ULONG)Value;
- 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);
+static FORCEINLINE NDIS_STATUS
+AdapterInterruptModeration(
+ IN PXENNET_ADAPTER Adapter,
+ IN PNDIS_INTERRUPT_MODERATION_PARAMETERS Params
+ )
+{
+ UNREFERENCED_PARAMETER(Adapter);
- infoData = 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);
- XENVIF_VIF(QueryStatistic,
- &Adapter->VifInterface,
- XENVIF_TRANSMITTER_FRONTEND_ERRORS,
- &Value);
+ Params->Flags = 0;
+ Params->InterruptModeration = NdisInterruptModerationNotSupported;
- infoData += Value;
+ return NDIS_STATUS_SUCCESS;
+}
- info = &infoData;
- bytesAvailable = sizeof(ULONG);
- break;
- }
- case OID_GEN_RCV_ERROR: {
- ULONGLONG Value;
+NDIS_HANDLE
+AdapterGetHandle(
+ IN PXENNET_ADAPTER Adapter
+ )
+{
+ return Adapter->NdisAdapterHandle;
+}
- XENVIF_VIF(QueryStatistic,
- &Adapter->VifInterface,
- XENVIF_RECEIVER_BACKEND_ERRORS,
- &Value);
+PXENVIF_VIF_INTERFACE
+AdapterGetVifInterface(
+ IN PXENNET_ADAPTER Adapter
+ )
+{
+ return &Adapter->VifInterface;
+}
- infoData = Value;
+PXENNET_TRANSMITTER
+AdapterGetTransmitter(
+ IN PXENNET_ADAPTER Adapter
+ )
+{
+ return Adapter->Transmitter;
+}
- XENVIF_VIF(QueryStatistic,
- &Adapter->VifInterface,
- XENVIF_RECEIVER_FRONTEND_ERRORS,
- &Value);
+PXENNET_RECEIVER
+AdapterGetReceiver(
+ IN PXENNET_ADAPTER Adapter
+ )
+{
+ return Adapter->Receiver;
+}
- infoData += Value;
+NDIS_STATUS
+AdapterEnable(
+ IN PXENNET_ADAPTER Adapter
+ )
+{
+ NTSTATUS status;
- 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);
+ if (Adapter->Enabled)
+ return NDIS_STATUS_SUCCESS;
- infoData = Value;
+ status = XENVIF_VIF(Enable,
+ &Adapter->VifInterface,
+ AdapterVifCallback,
+ Adapter);
+ if (!NT_SUCCESS(status))
+ goto fail1;
- info = &infoData;
- bytesAvailable = sizeof(ULONG);
- break;
- }
- case OID_GEN_DIRECTED_FRAMES_XMIT: {
- ULONGLONG Value;
+ TransmitterEnable(Adapter->Transmitter);
+ Adapter->Enabled = TRUE;
- XENVIF_VIF(QueryStatistic,
- &Adapter->VifInterface,
- XENVIF_TRANSMITTER_UNICAST_PACKETS,
- &Value);
+ return NDIS_STATUS_SUCCESS;
- infoData = Value;
+fail1:
+ return NDIS_STATUS_FAILURE;
+}
- info = &infoData;
- bytesAvailable = sizeof(ULONG);
- break;
- }
- case OID_GEN_MULTICAST_BYTES_XMIT: {
- ULONGLONG Value;
+BOOLEAN
+AdapterDisable(
+ IN PXENNET_ADAPTER Adapter
+ )
+{
+ if (!Adapter->Enabled)
+ return FALSE;
- XENVIF_VIF(QueryStatistic,
- &Adapter->VifInterface,
- XENVIF_TRANSMITTER_MULTICAST_OCTETS,
- &Value);
+ XENVIF_VIF(Disable,
+ &Adapter->VifInterface);
+
+ AdapterMediaStateChange(Adapter);
- infoData = Value;
+ Adapter->Enabled = FALSE;
- info = &infoData;
- bytesAvailable = sizeof(ULONG);
- break;
+ return TRUE;
+}
+
+VOID
+AdapterMediaStateChange(
+ IN PXENNET_ADAPTER Adapter
+ )
+{
+ NDIS_LINK_STATE LinkState;
+ NDIS_STATUS_INDICATION StatusIndication;
+
+ 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);
+
+ 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;
+
+ 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);
+
+ NdisMIndicateStatusEx(Adapter->NdisAdapterHandle, &StatusIndication);
+}
+
+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);
}
- case OID_GEN_MULTICAST_FRAMES_XMIT: {
- ULONGLONG Value;
+ break;
- XENVIF_VIF(QueryStatistic,
- &Adapter->VifInterface,
- XENVIF_TRANSMITTER_MULTICAST_PACKETS,
- &Value);
+ case OID_GEN_CURRENT_PACKET_FILTER:
+ BytesNeeded = sizeof(ULONG);
+ if (BufferLength == BytesNeeded) {
+ AdapterSetPacketFilter(Adapter,
+ (PULONG)Buffer);
+ BytesRead = sizeof(ULONG);
+ }
+ break;
+
+ 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_BROADCAST_BYTES_XMIT: {
- ULONGLONG Value;
+ break;
- XENVIF_VIF(QueryStatistic,
- &Adapter->VifInterface,
- XENVIF_TRANSMITTER_BROADCAST_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;
+
+ return ndisStatus;
+}
+
+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;
+ }
+}
- infoData = Value;
+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;
+ }
+}
- info = &infoData;
- bytesAvailable = sizeof(ULONG);
- break;
+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_BROADCAST_FRAMES_XMIT: {
- 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_TRANSMITTER_BROADCAST_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_DIRECTED_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_UNICAST_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_DIRECTED_FRAMES_RCV: {
- ULONGLONG Value;
+ break;
- XENVIF_VIF(QueryStatistic,
- &Adapter->VifInterface,
- XENVIF_RECEIVER_UNICAST_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_MULTICAST_BYTES_RCV: {
- ULONGLONG Value;
+ break;
- XENVIF_VIF(QueryStatistic,
- &Adapter->VifInterface,
- XENVIF_RECEIVER_MULTICAST_OCTETS,
- &Value);
+ case OID_GEN_RCV_ERROR:
+ if (BufferLength >= BytesNeeded) {
+ ndisStatus = AdapterGetRcvError(Adapter,
+ (PULONG)Buffer);
+ }
+ break;
- infoData = Value;
+ 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;
- info = &infoData;
- bytesAvailable = sizeof(ULONG);
- break;
- }
- case OID_GEN_MULTICAST_FRAMES_RCV: {
- ULONGLONG Value;
+ case OID_GEN_MULTICAST_FRAMES_XMIT:
+ XENVIF_VIF(QueryStatistic,
+ &Adapter->VifInterface,
+ XENVIF_TRANSMITTER_MULTICAST_PACKETS,
+ &Value64);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ (ULONG)Value64,
+ &BytesWritten);
+ break;
- XENVIF_VIF(QueryStatistic,
- &Adapter->VifInterface,
- XENVIF_RECEIVER_MULTICAST_PACKETS,
- &Value);
+ case OID_GEN_BROADCAST_BYTES_XMIT:
+ XENVIF_VIF(QueryStatistic,
+ &Adapter->VifInterface,
+ XENVIF_TRANSMITTER_BROADCAST_OCTETS,
+ &Value64);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ (ULONG)Value64,
+ &BytesWritten);
+ break;
- infoData = Value;
+ case OID_GEN_BROADCAST_FRAMES_XMIT:
+ XENVIF_VIF(QueryStatistic,
+ &Adapter->VifInterface,
+ XENVIF_TRANSMITTER_BROADCAST_PACKETS,
+ &Value64);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ (ULONG)Value64,
+ &BytesWritten);
+ break;
- info = &infoData;
- bytesAvailable = sizeof(ULONG);
- break;
- }
- case OID_GEN_BROADCAST_BYTES_RCV: {
- ULONGLONG Value;
+ case OID_GEN_DIRECTED_BYTES_RCV:
+ XENVIF_VIF(QueryStatistic,
+ &Adapter->VifInterface,
+ XENVIF_RECEIVER_UNICAST_OCTETS,
+ &Value64);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ (ULONG)Value64,
+ &BytesWritten);
+ break;
- XENVIF_VIF(QueryStatistic,
- &Adapter->VifInterface,
- XENVIF_RECEIVER_BROADCAST_OCTETS,
- &Value);
+ 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;
+ ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
- *AddressingReset = FALSE;
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ RtlZeroMemory(&StatusBlock, sizeof(IO_STATUS_BLOCK));
- return NDIS_STATUS_SUCCESS;
-}
+ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
+ DeviceObject,
+ NULL,
+ 0,
+ NULL,
+ &Event,
+ &StatusBlock);
-//
-// 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;
+ status = STATUS_UNSUCCESSFUL;
+ if (Irp == NULL)
+ goto fail1;
- UNREFERENCED_PARAMETER(MiniportRestartParameters);
+ StackLocation = IoGetNextIrpStackLocation(Irp);
+ StackLocation->MinorFunction = IRP_MN_QUERY_INTERFACE;
- Trace("====>\n");
+ StackLocation->Parameters.QueryInterface.InterfaceType = Guid;
+ StackLocation->Parameters.QueryInterface.Size = (USHORT)Size;
+ StackLocation->Parameters.QueryInterface.Version = (USHORT)Version;
+ StackLocation->Parameters.QueryInterface.Interface = Interface;
- if (Adapter->Enabled) {
- ndisStatus = NDIS_STATUS_SUCCESS;
- goto done;
+ 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);
-#define XENNET_MEDIA_MAX_SPEED 1000000000ull
+ NdisCloseConfiguration(Handle);
+
+ 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;
-
- NdisZeroMemory(&generalAttributes,
- sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES));
+ 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;
- 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;
- Adapter->Receiver.OffloadOptions.Value = 0;
- Adapter->Receiver.OffloadOptions.OffloadTagManipulation = 1;
+ TxOptions = TransmitterOffloadOptions(Adapter->Transmitter);
+ RxOptions = ReceiverOffloadOptions(Adapter->Receiver);
+
+ TxOptions->Value = 0;
+ TxOptions->OffloadTagManipulation = 1;
+
+ RxOptions->Value = 0;
+ RxOptions->OffloadTagManipulation = 1;
if (Adapter->Properties.need_csum_value)
- Adapter->Receiver.OffloadOptions.NeedChecksumValue = 1;
+ RxOptions->NeedChecksumValue = 1;
if (Adapter->Properties.lrov4) {
- Adapter->Receiver.OffloadOptions.OffloadIpVersion4LargePacket = 1;
- Adapter->Receiver.OffloadOptions.NeedLargePacketSplit = 1;
+ RxOptions->OffloadIpVersion4LargePacket = 1;
+ RxOptions->NeedLargePacketSplit = 1;
}
if (Adapter->Properties.lrov6) {
- Adapter->Receiver.OffloadOptions.OffloadIpVersion6LargePacket = 1;
- Adapter->Receiver.OffloadOptions.NeedLargePacketSplit = 1;
+ RxOptions->OffloadIpVersion6LargePacket = 1;
+ RxOptions->NeedLargePacketSplit = 1;
}
- Adapter->Transmitter->OffloadOptions.Value = 0;
- Adapter->Transmitter->OffloadOptions.OffloadTagManipulation = 1;
-
- NdisZeroMemory(&offloadAttributes, sizeof(offloadAttributes));
- NdisZeroMemory(¤t, sizeof(current));
- NdisZeroMemory(&supported, sizeof(supported));
-
XENVIF_VIF(ReceiverSetOffloadOptions,
&Adapter->VifInterface,
- Adapter->Receiver.OffloadOptions);
+ *RxOptions);
- supported.Header.Type = NDIS_OBJECT_TYPE_OFFLOAD;
- supported.Header.Revision = NDIS_OFFLOAD_REVISION_1;
- supported.Header.Size = sizeof(supported);
+ XENVIF_VIF(TransmitterQueryOffloadOptions,
+ &Adapter->VifInterface,
+ &Options);
- supported.Checksum.IPv4Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
+ RtlZeroMemory(&Supported, sizeof(NDIS_OFFLOAD));
+ Supported.Header.Type = NDIS_OBJECT_TYPE_OFFLOAD;
+ Supported.Header.Revision = NDIS_OFFLOAD_REVISION_1;
+ Supported.Header.Size = sizeof(NDIS_OFFLOAD);
- supported.Checksum.IPv4Receive.IpChecksum = 1;
- supported.Checksum.IPv4Receive.IpOptionsSupported = 1;
+ Supported.Checksum.IPv4Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
- supported.Checksum.IPv4Receive.TcpChecksum = 1;
- supported.Checksum.IPv4Receive.TcpOptionsSupported = 1;
+ Supported.Checksum.IPv4Receive.IpChecksum = 1;
+ Supported.Checksum.IPv4Receive.IpOptionsSupported = 1;
- supported.Checksum.IPv4Receive.UdpChecksum = 1;
+ Supported.Checksum.IPv4Receive.TcpChecksum = 1;
+ Supported.Checksum.IPv4Receive.TcpOptionsSupported = 1;
- supported.Checksum.IPv6Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
+ Supported.Checksum.IPv4Receive.UdpChecksum = 1;
- supported.Checksum.IPv6Receive.IpExtensionHeadersSupported = 1;
+ Supported.Checksum.IPv6Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
- supported.Checksum.IPv6Receive.TcpChecksum = 1;
- supported.Checksum.IPv6Receive.TcpOptionsSupported = 1;
+ Supported.Checksum.IPv6Receive.IpExtensionHeadersSupported = 1;
- supported.Checksum.IPv6Receive.UdpChecksum = 1;
+ Supported.Checksum.IPv6Receive.TcpChecksum = 1;
+ Supported.Checksum.IPv6Receive.TcpOptionsSupported = 1;
- XENVIF_VIF(TransmitterQueryOffloadOptions,
- &Adapter->VifInterface,
- &Options);
+ Supported.Checksum.IPv6Receive.UdpChecksum = 1;
- supported.Checksum.IPv4Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
+ Supported.Checksum.IPv4Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
if (Options.OffloadIpVersion4HeaderChecksum) {
- supported.Checksum.IPv4Transmit.IpChecksum = 1;
- supported.Checksum.IPv4Transmit.IpOptionsSupported = 1;
+ Supported.Checksum.IPv4Transmit.IpChecksum = 1;
+ Supported.Checksum.IPv4Transmit.IpOptionsSupported = 1;
}
if (Options.OffloadIpVersion4TcpChecksum) {
- supported.Checksum.IPv4Transmit.TcpChecksum = 1;
- supported.Checksum.IPv4Transmit.TcpOptionsSupported = 1;
+ Supported.Checksum.IPv4Transmit.TcpChecksum = 1;
+ Supported.Checksum.IPv4Transmit.TcpOptionsSupported = 1;
}
if (Options.OffloadIpVersion4UdpChecksum)
- supported.Checksum.IPv4Transmit.UdpChecksum = 1;
+ Supported.Checksum.IPv4Transmit.UdpChecksum = 1;
- supported.Checksum.IPv6Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
+ Supported.Checksum.IPv6Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
- supported.Checksum.IPv6Transmit.IpExtensionHeadersSupported = 1;
+ Supported.Checksum.IPv6Transmit.IpExtensionHeadersSupported = 1;
if (Options.OffloadIpVersion6TcpChecksum) {
- supported.Checksum.IPv6Transmit.TcpChecksum = 1;
- supported.Checksum.IPv6Transmit.TcpOptionsSupported = 1;
+ Supported.Checksum.IPv6Transmit.TcpChecksum = 1;
+ Supported.Checksum.IPv6Transmit.TcpOptionsSupported = 1;
}
if (Options.OffloadIpVersion6UdpChecksum)
- supported.Checksum.IPv6Transmit.UdpChecksum = 1;
+ Supported.Checksum.IPv6Transmit.UdpChecksum = 1;
if (Options.OffloadIpVersion4LargePacket) {
- ULONG Size;
-
XENVIF_VIF(TransmitterQueryLargePacketSize,
&Adapter->VifInterface,
4,
- &Size);
-
- supported.LsoV2.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
- supported.LsoV2.IPv4.MaxOffLoadSize = Size;
- supported.LsoV2.IPv4.MinSegmentCount = 2;
+ &Supported.LsoV2.IPv4.MaxOffLoadSize);
+ Supported.LsoV2.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
+ Supported.LsoV2.IPv4.MinSegmentCount = 2;
}
if (Options.OffloadIpVersion6LargePacket) {
- ULONG Size;
-
XENVIF_VIF(TransmitterQueryLargePacketSize,
&Adapter->VifInterface,
6,
- &Size);
-
- supported.LsoV2.IPv6.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
- supported.LsoV2.IPv6.MaxOffLoadSize = Size;
- supported.LsoV2.IPv6.MinSegmentCount = 2;
- supported.LsoV2.IPv6.IpExtensionHeadersSupported = 1;
- supported.LsoV2.IPv6.TcpOptionsSupported = 1;
+ &Supported.LsoV2.IPv6.MaxOffLoadSize);
+ Supported.LsoV2.IPv6.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
+ Supported.LsoV2.IPv6.MinSegmentCount = 2;
+ Supported.LsoV2.IPv6.IpExtensionHeadersSupported = 1;
+ Supported.LsoV2.IPv6.TcpOptionsSupported = 1;
}
- current = supported;
+ Default = Supported;
if (!(Adapter->Properties.ipv4_csum & 2))
- current.Checksum.IPv4Receive.IpChecksum = 0;
+ Default.Checksum.IPv4Receive.IpChecksum = 0;
if (!(Adapter->Properties.tcpv4_csum & 2))
- current.Checksum.IPv4Receive.TcpChecksum = 0;
+ Default.Checksum.IPv4Receive.TcpChecksum = 0;
if (!(Adapter->Properties.udpv4_csum & 2))
- current.Checksum.IPv4Receive.UdpChecksum = 0;
+ Default.Checksum.IPv4Receive.UdpChecksum = 0;
if (!(Adapter->Properties.tcpv6_csum & 2))
- current.Checksum.IPv6Receive.TcpChecksum = 0;
+ Default.Checksum.IPv6Receive.TcpChecksum = 0;
if (!(Adapter->Properties.udpv6_csum & 2))
- current.Checksum.IPv6Receive.UdpChecksum = 0;
+ Default.Checksum.IPv6Receive.UdpChecksum = 0;
if (!(Adapter->Properties.ipv4_csum & 1))
- current.Checksum.IPv4Transmit.IpChecksum = 0;
+ Default.Checksum.IPv4Transmit.IpChecksum = 0;
if (!(Adapter->Properties.tcpv4_csum & 1))
- current.Checksum.IPv4Transmit.TcpChecksum = 0;
+ Default.Checksum.IPv4Transmit.TcpChecksum = 0;
if (!(Adapter->Properties.udpv4_csum & 1))
- current.Checksum.IPv4Transmit.UdpChecksum = 0;
+ Default.Checksum.IPv4Transmit.UdpChecksum = 0;
if (!(Adapter->Properties.tcpv6_csum & 1))
- current.Checksum.IPv6Transmit.TcpChecksum = 0;
+ Default.Checksum.IPv6Transmit.TcpChecksum = 0;
if (!(Adapter->Properties.udpv6_csum & 1))
- current.Checksum.IPv6Transmit.UdpChecksum = 0;
+ Default.Checksum.IPv6Transmit.UdpChecksum = 0;
if (!(Adapter->Properties.lsov4)) {
- current.LsoV2.IPv4.MaxOffLoadSize = 0;
- current.LsoV2.IPv4.MinSegmentCount = 0;
+ Default.LsoV2.IPv4.MaxOffLoadSize = 0;
+ Default.LsoV2.IPv4.MinSegmentCount = 0;
}
if (!(Adapter->Properties.lsov6)) {
- current.LsoV2.IPv6.MaxOffLoadSize = 0;
- current.LsoV2.IPv6.MinSegmentCount = 0;
+ Default.LsoV2.IPv6.MaxOffLoadSize = 0;
+ Default.LsoV2.IPv6.MinSegmentCount = 0;
}
- if (!RtlEqualMemory(&Adapter->Offload, ¤t, sizeof (NDIS_OFFLOAD))) {
- Adapter->Offload = current;
-
- DISPLAY_OFFLOAD(current);
+ if (!RtlEqualMemory(&Adapter->Offload, &Default, sizeof (NDIS_OFFLOAD))) {
+ Adapter->Offload = Default;
+ //DISPLAY_OFFLOAD(Default);
}
- offloadAttributes.Header.Type =
- NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES;
- offloadAttributes.Header.Revision =
- NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES_REVISION_1;
- offloadAttributes.Header.Size = sizeof(offloadAttributes);
- offloadAttributes.DefaultOffloadConfiguration = ¤t;
- offloadAttributes.HardwareOffloadCapabilities = &supported;
+ RtlZeroMemory(&Attribs, sizeof(NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES));
+ Attribs.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES;
+ Attribs.Header.Revision = NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES_REVISION_1;
+ Attribs.Header.Size = sizeof(Attribs);
+ Attribs.DefaultOffloadConfiguration = &Default;
+ Attribs.HardwareOffloadCapabilities = &Supported;
- adapterAttributes =
- (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&offloadAttributes;
ndisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle,
- adapterAttributes);
-
+ (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs);
return ndisStatus;
}
-static void
-AdapterIndicateOffloadChanged (
- IN PADAPTER Adapter
+NDIS_STATUS
+AdapterInitialize(
+ IN NDIS_HANDLE Handle,
+ OUT PXENNET_ADAPTER *Adapter
)
{
- NDIS_STATUS_INDICATION indication;
- NDIS_OFFLOAD offload;
-
- NdisZeroMemory(&offload, sizeof(offload));
- INITIALIZE_NDIS_OBJ_HEADER(offload, OFFLOAD);
-
- offload.Checksum.IPv4Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
-
- if (Adapter->Receiver.OffloadOptions.OffloadIpVersion4HeaderChecksum) {
- offload.Checksum.IPv4Receive.IpChecksum = 1;
- offload.Checksum.IPv4Receive.IpOptionsSupported = 1;
- }
-
- if (Adapter->Receiver.OffloadOptions.OffloadIpVersion4TcpChecksum) {
- offload.Checksum.IPv4Receive.TcpChecksum = 1;
- offload.Checksum.IPv4Receive.TcpOptionsSupported = 1;
- }
-
- if (Adapter->Receiver.OffloadOptions.OffloadIpVersion4UdpChecksum) {
- offload.Checksum.IPv4Receive.UdpChecksum = 1;
- }
-
- offload.Checksum.IPv6Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
-
- offload.Checksum.IPv6Receive.IpExtensionHeadersSupported = 1;
-
- if (Adapter->Receiver.OffloadOptions.OffloadIpVersion6TcpChecksum) {
- offload.Checksum.IPv6Receive.TcpChecksum = 1;
- offload.Checksum.IPv6Receive.TcpOptionsSupported = 1;
- }
-
- if (Adapter->Receiver.OffloadOptions.OffloadIpVersion6UdpChecksum) {
- offload.Checksum.IPv6Receive.UdpChecksum = 1;
- }
-
- 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;
- }
+ NDIS_STATUS ndisStatus;
+ NTSTATUS status;
+ PDEVICE_OBJECT DeviceObject;
+ NDIS_SG_DMA_DESCRIPTION Dma;
- if (!RtlEqualMemory(&Adapter->Offload, &offload, sizeof (NDIS_OFFLOAD))) {
- Adapter->Offload = offload;
+ *Adapter = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(XENNET_ADAPTER),
+ ADAPTER_POOL_TAG);
- DISPLAY_OFFLOAD(offload);
- }
-
- NdisZeroMemory(&indication, sizeof(indication));
- INITIALIZE_NDIS_OBJ_HEADER(indication, STATUS_INDICATION);
- indication.SourceHandle = Adapter->NdisAdapterHandle;
- indication.StatusCode = NDIS_STATUS_TASK_OFFLOAD_CURRENT_CONFIG;
- indication.StatusBuffer = &offload;
- indication.StatusBufferSize = sizeof(offload);
+ 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;
+ goto fail2;
- 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;
+ status = XENVIF_VIF(Acquire,
+ &(*Adapter)->VifInterface);
+ if (!NT_SUCCESS(status))
+ goto fail3;
- if (*PacketFilter & ~XENNET_SUPPORTED_PACKET_FILTERS)
- return NDIS_STATUS_INVALID_PARAMETER;
+ (*Adapter)->NdisAdapterHandle = Handle;
- if (*PacketFilter & NDIS_PACKET_TYPE_PROMISCUOUS) {
- UnicastFilterLevel = XENVIF_MAC_FILTER_ALL;
- MulticastFilterLevel = XENVIF_MAC_FILTER_ALL;
- BroadcastFilterLevel = XENVIF_MAC_FILTER_ALL;
- goto done;
- }
+ ndisStatus = TransmitterInitialize(*Adapter, &(*Adapter)->Transmitter);
+ if (ndisStatus != NDIS_STATUS_SUCCESS)
+ goto fail4;
- if (*PacketFilter & NDIS_PACKET_TYPE_DIRECTED)
- UnicastFilterLevel = XENVIF_MAC_FILTER_MATCHING;
- else
- UnicastFilterLevel = XENVIF_MAC_FILTER_NONE;
+ ndisStatus = ReceiverInitialize(*Adapter, &(*Adapter)->Receiver);
+ if (ndisStatus != NDIS_STATUS_SUCCESS)
+ goto fail5;
- 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 = AdapterGetAdvancedSettings(*Adapter);
+ if (ndisStatus != NDIS_STATUS_SUCCESS)
+ goto fail6;
- if (*PacketFilter & NDIS_PACKET_TYPE_BROADCAST)
- BroadcastFilterLevel = XENVIF_MAC_FILTER_ALL;
- else
- BroadcastFilterLevel = XENVIF_MAC_FILTER_NONE;
+ ndisStatus = AdapterSetRegistrationAttributes(*Adapter);
+ if (ndisStatus != NDIS_STATUS_SUCCESS)
+ goto fail7;
-done:
- XENVIF_VIF(MacSetFilterLevel,
- &Adapter->VifInterface,
- ETHERNET_ADDRESS_UNICAST,
- UnicastFilterLevel);
+ ndisStatus = AdapterSetGeneralAttributes(*Adapter);
+ if (ndisStatus != NDIS_STATUS_SUCCESS)
+ goto fail8;
- XENVIF_VIF(MacSetFilterLevel,
- &Adapter->VifInterface,
- ETHERNET_ADDRESS_MULTICAST,
- MulticastFilterLevel);
+ ndisStatus = AdapterSetOffloadAttributes(*Adapter);
+ if (ndisStatus != NDIS_STATUS_SUCCESS)
+ goto fail9;
+
+ RtlZeroMemory(&Dma, sizeof(NDIS_SG_DMA_DESCRIPTION));
+ Dma.Header.Type = NDIS_OBJECT_TYPE_SG_DMA_DESCRIPTION;
+ Dma.Header.Revision = NDIS_SG_DMA_DESCRIPTION_REVISION_1;
+ Dma.Header.Size = sizeof(NDIS_SG_DMA_DESCRIPTION);
+ Dma.Flags = NDIS_SG_DMA_64_BIT_ADDRESS;
+ Dma.MaximumPhysicalMapping = 65536;
+ Dma.ProcessSGListHandler = AdapterProcessSGList;
+ Dma.SharedMemAllocateCompleteHandler = AdapterAllocateComplete;
+
+ ndisStatus = NdisMRegisterScatterGatherDma((*Adapter)->NdisAdapterHandle,
+ &Dma,
+ &(*Adapter)->NdisDmaHandle);
+ if (ndisStatus != NDIS_STATUS_SUCCESS)
+ (*Adapter)->NdisDmaHandle = NULL;
- XENVIF_VIF(MacSetFilterLevel,
- &Adapter->VifInterface,
- ETHERNET_ADDRESS_BROADCAST,
- BroadcastFilterLevel);
+ ndisStatus = AdapterEnable(*Adapter);
+ if (ndisStatus != NDIS_STATUS_SUCCESS)
+ goto fail10;
return NDIS_STATUS_SUCCESS;
-}
-
-//
-// Set OID handler.
-//
-static NDIS_STATUS
-AdapterSetInformation (
- IN PADAPTER Adapter,
- IN PNDIS_OID_REQUEST NdisRequest
- )
-{
- ULONG addressCount;
- ULONG bytesNeeded = 0;
- ULONG bytesRead = 0;
- PVOID informationBuffer;
- ULONG informationBufferLength;
- NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS;
- NDIS_OID oid;
- BOOLEAN offloadChanged;
-
- informationBuffer = NdisRequest->DATA.SET_INFORMATION.InformationBuffer;
- informationBufferLength = NdisRequest->DATA.SET_INFORMATION.InformationBufferLength;
- oid = NdisRequest->DATA.QUERY_INFORMATION.Oid;
- switch (oid) {
- case OID_PNP_SET_POWER:
- bytesNeeded = sizeof(NDIS_DEVICE_POWER_STATE);
- if (informationBufferLength >= bytesNeeded) {
- PNDIS_DEVICE_POWER_STATE state;
-
- state = (PNDIS_DEVICE_POWER_STATE)informationBuffer;
- switch (*state) {
- case NdisDeviceStateD0:
- Info("SET_POWER: D0\n");
- break;
-
- case NdisDeviceStateD1:
- Info("SET_POWER: D1\n");
- break;
-
- case NdisDeviceStateD2:
- Info("SET_POWER: D2\n");
- break;
-
- case NdisDeviceStateD3:
- Info("SET_POWER: D3\n");
- break;
- }
- }
- break;
-
- case OID_GEN_MACHINE_NAME:
- ndisStatus = NDIS_STATUS_NOT_SUPPORTED;
- break;
-
- case OID_GEN_CURRENT_LOOKAHEAD:
- bytesNeeded = sizeof(ULONG);
- Adapter->CurrentLookahead = Adapter->MaximumFrameSize;
- if (informationBufferLength == sizeof(ULONG)) {
- Adapter->CurrentLookahead = *(PULONG)informationBuffer;
- bytesRead = sizeof(ULONG);
- }
-
- break;
-
- case OID_GEN_CURRENT_PACKET_FILTER:
- bytesNeeded = sizeof(ULONG);
- if (informationBufferLength == sizeof(ULONG)) {
- ndisStatus = SetPacketFilter(Adapter, (PULONG)informationBuffer);
- bytesRead = sizeof(ULONG);
- }
-
- break;
-
- case OID_802_3_MULTICAST_LIST:
- bytesNeeded = ETHERNET_ADDRESS_LENGTH;
- if (informationBufferLength % ETHERNET_ADDRESS_LENGTH == 0) {
- addressCount = informationBufferLength / ETHERNET_ADDRESS_LENGTH;
-
- ndisStatus = SetMulticastAddresses(Adapter, informationBuffer, addressCount);
- if (ndisStatus == NDIS_STATUS_SUCCESS)
- bytesRead = informationBufferLength;
- } else {
- ndisStatus = NDIS_STATUS_INVALID_LENGTH;
- }
-
- break;
-
- case OID_GEN_INTERRUPT_MODERATION:
- ndisStatus = NDIS_STATUS_INVALID_DATA;
- break;
-
- case OID_OFFLOAD_ENCAPSULATION: {
- PNDIS_OFFLOAD_ENCAPSULATION offloadEncapsulation;
-
- bytesNeeded = sizeof(*offloadEncapsulation);
- if (informationBufferLength >= bytesNeeded) {
- XENVIF_VIF_OFFLOAD_OPTIONS Options;
-
- bytesRead = bytesNeeded;
- offloadEncapsulation = informationBuffer;
- ndisStatus = NDIS_STATUS_SUCCESS;
-
- if (offloadEncapsulation->IPv4.Enabled == NDIS_OFFLOAD_SET_ON) {
- if (offloadEncapsulation->IPv4.EncapsulationType != NDIS_ENCAPSULATION_IEEE_802_3)
- ndisStatus = NDIS_STATUS_INVALID_PARAMETER;
- }
-
- if (offloadEncapsulation->IPv6.Enabled == NDIS_OFFLOAD_SET_ON) {
- if (offloadEncapsulation->IPv6.EncapsulationType != NDIS_ENCAPSULATION_IEEE_802_3)
- ndisStatus = NDIS_STATUS_INVALID_PARAMETER;
- }
-
- XENVIF_VIF(TransmitterQueryOffloadOptions,
- &Adapter->VifInterface,
- &Options);
-
- Adapter->Transmitter->OffloadOptions.Value = 0;
- Adapter->Transmitter->OffloadOptions.OffloadTagManipulation = 1;
-
- if ((Adapter->Properties.lsov4) && (Options.OffloadIpVersion4LargePacket))
- Adapter->Transmitter->OffloadOptions.OffloadIpVersion4LargePacket = 1;
-
- if ((Adapter->Properties.lsov6) && (Options.OffloadIpVersion6LargePacket))
- Adapter->Transmitter->OffloadOptions.OffloadIpVersion6LargePacket = 1;
-
- if ((Adapter->Properties.ipv4_csum & 1) && Options.OffloadIpVersion4HeaderChecksum)
- Adapter->Transmitter->OffloadOptions.OffloadIpVersion4HeaderChecksum = 1;
-
- if ((Adapter->Properties.tcpv4_csum & 1) && Options.OffloadIpVersion4TcpChecksum)
- Adapter->Transmitter->OffloadOptions.OffloadIpVersion4TcpChecksum = 1;
-
- if ((Adapter->Properties.udpv4_csum & 1) && Options.OffloadIpVersion4UdpChecksum)
- Adapter->Transmitter->OffloadOptions.OffloadIpVersion4UdpChecksum = 1;
-
- if ((Adapter->Properties.tcpv6_csum & 1) && Options.OffloadIpVersion6TcpChecksum)
- Adapter->Transmitter->OffloadOptions.OffloadIpVersion6TcpChecksum = 1;
-
- if ((Adapter->Properties.udpv6_csum & 1) && Options.OffloadIpVersion6UdpChecksum)
- Adapter->Transmitter->OffloadOptions.OffloadIpVersion6UdpChecksum = 1;
-
- Adapter->Receiver.OffloadOptions.Value = 0;
- Adapter->Receiver.OffloadOptions.OffloadTagManipulation = 1;
-
- if (Adapter->Properties.need_csum_value)
- Adapter->Receiver.OffloadOptions.NeedChecksumValue = 1;
-
- if (Adapter->Properties.lrov4) {
- Adapter->Receiver.OffloadOptions.OffloadIpVersion4LargePacket = 1;
- Adapter->Receiver.OffloadOptions.NeedLargePacketSplit = 1;
- }
-
- if (Adapter->Properties.lrov6) {
- Adapter->Receiver.OffloadOptions.OffloadIpVersion6LargePacket = 1;
- Adapter->Receiver.OffloadOptions.NeedLargePacketSplit = 1;
- }
-
- if (Adapter->Properties.ipv4_csum & 2)
- Adapter->Receiver.OffloadOptions.OffloadIpVersion4HeaderChecksum = 1;
-
- if (Adapter->Properties.tcpv4_csum & 2)
- Adapter->Receiver.OffloadOptions.OffloadIpVersion4TcpChecksum = 1;
-
- if (Adapter->Properties.udpv4_csum & 2)
- Adapter->Receiver.OffloadOptions.OffloadIpVersion4UdpChecksum = 1;
-
- if (Adapter->Properties.tcpv6_csum & 2)
- Adapter->Receiver.OffloadOptions.OffloadIpVersion6TcpChecksum = 1;
-
- if (Adapter->Properties.udpv6_csum & 2)
- Adapter->Receiver.OffloadOptions.OffloadIpVersion6UdpChecksum = 1;
-
- AdapterIndicateOffloadChanged(Adapter);
- }
- break;
- }
- case OID_TCP_OFFLOAD_PARAMETERS: {
- PNDIS_OFFLOAD_PARAMETERS offloadParameters;
-
- bytesNeeded = sizeof(*offloadParameters);
- if (informationBufferLength >= bytesNeeded) {
- bytesRead = bytesNeeded;
- offloadParameters = informationBuffer;
- ndisStatus = NDIS_STATUS_SUCCESS;
-
-#define no_change(x) ((x) == NDIS_OFFLOAD_PARAMETERS_NO_CHANGE)
-
- if (!no_change(offloadParameters->IPsecV1))
- ndisStatus = NDIS_STATUS_INVALID_PARAMETER;
-
- if (!no_change(offloadParameters->LsoV1))
- ndisStatus = NDIS_STATUS_INVALID_PARAMETER;
-
- if (!no_change(offloadParameters->TcpConnectionIPv4))
- ndisStatus = NDIS_STATUS_INVALID_PARAMETER;
-
- if (!no_change(offloadParameters->TcpConnectionIPv6))
- ndisStatus = NDIS_STATUS_INVALID_PARAMETER;
-
- if (!no_change(offloadParameters->LsoV2IPv4)) {
- XENVIF_VIF_OFFLOAD_OPTIONS Options;
-
- XENVIF_VIF(TransmitterQueryOffloadOptions,
- &Adapter->VifInterface,
- &Options);
-
- if (!(Options.OffloadIpVersion4LargePacket))
- ndisStatus = NDIS_STATUS_INVALID_PARAMETER;
- }
-
- if (!no_change(offloadParameters->LsoV2IPv6)) {
- XENVIF_VIF_OFFLOAD_OPTIONS Options;
-
- XENVIF_VIF(TransmitterQueryOffloadOptions,
- &Adapter->VifInterface,
- &Options);
-
- if (!(Options.OffloadIpVersion6LargePacket))
- ndisStatus = NDIS_STATUS_INVALID_PARAMETER;
- }
-
-#define rx_enabled(x) ((x) == NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED || \
- (x) == NDIS_OFFLOAD_PARAMETERS_RX_ENABLED_TX_DISABLED)
-#define tx_enabled(x) ((x) == NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED || \
- (x) == NDIS_OFFLOAD_PARAMETERS_TX_ENABLED_RX_DISABLED)
-
- if (ndisStatus == NDIS_STATUS_SUCCESS) {
- offloadChanged = FALSE;
-
- if (offloadParameters->LsoV2IPv4 == NDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED) {
- if (!Adapter->Transmitter->OffloadOptions.OffloadIpVersion4LargePacket) {
- Adapter->Transmitter->OffloadOptions.OffloadIpVersion4LargePacket = 1;
- offloadChanged = TRUE;
- }
- } else if (offloadParameters->LsoV2IPv4 == NDIS_OFFLOAD_PARAMETERS_LSOV2_DISABLED) {
- if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion4LargePacket) {
- Adapter->Transmitter->OffloadOptions.OffloadIpVersion4LargePacket = 0;
- offloadChanged = TRUE;
- }
- }
-
- if (offloadParameters->LsoV2IPv6 == NDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED) {
- if (!Adapter->Transmitter->OffloadOptions.OffloadIpVersion6LargePacket) {
- Adapter->Transmitter->OffloadOptions.OffloadIpVersion6LargePacket = 1;
- offloadChanged = TRUE;
- }
- } else if (offloadParameters->LsoV2IPv6 == NDIS_OFFLOAD_PARAMETERS_LSOV2_DISABLED) {
- if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion6LargePacket) {
- Adapter->Transmitter->OffloadOptions.OffloadIpVersion6LargePacket = 0;
- offloadChanged = TRUE;
- }
- }
-
- if (tx_enabled(offloadParameters->IPv4Checksum)) {
- if (!Adapter->Transmitter->OffloadOptions.OffloadIpVersion4HeaderChecksum) {
- Adapter->Transmitter->OffloadOptions.OffloadIpVersion4HeaderChecksum = 1;
- offloadChanged = TRUE;
- }
- } else {
- if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion4HeaderChecksum) {
- Adapter->Transmitter->OffloadOptions.OffloadIpVersion4HeaderChecksum = 0;
- offloadChanged = TRUE;
- }
- }
-
- if (tx_enabled(offloadParameters->TCPIPv4Checksum)) {
- if (!Adapter->Transmitter->OffloadOptions.OffloadIpVersion4TcpChecksum) {
- Adapter->Transmitter->OffloadOptions.OffloadIpVersion4TcpChecksum = 1;
- offloadChanged = TRUE;
- }
- } else {
- if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion4TcpChecksum) {
- Adapter->Transmitter->OffloadOptions.OffloadIpVersion4TcpChecksum = 0;
- offloadChanged = TRUE;
- }
- }
-
- if (tx_enabled(offloadParameters->UDPIPv4Checksum)) {
- if (!Adapter->Transmitter->OffloadOptions.OffloadIpVersion4UdpChecksum) {
- Adapter->Transmitter->OffloadOptions.OffloadIpVersion4UdpChecksum = 1;
- offloadChanged = TRUE;
- }
- } else {
- if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion4UdpChecksum) {
- Adapter->Transmitter->OffloadOptions.OffloadIpVersion4UdpChecksum = 0;
- offloadChanged = TRUE;
- }
- }
-
- if (tx_enabled(offloadParameters->TCPIPv6Checksum)) {
- if (!Adapter->Transmitter->OffloadOptions.OffloadIpVersion6TcpChecksum) {
- Adapter->Transmitter->OffloadOptions.OffloadIpVersion6TcpChecksum = 1;
- offloadChanged = TRUE;
- }
- } else {
- if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion6TcpChecksum) {
- Adapter->Transmitter->OffloadOptions.OffloadIpVersion6TcpChecksum = 0;
- offloadChanged = TRUE;
- }
- }
-
- if (tx_enabled(offloadParameters->UDPIPv6Checksum)) {
- if (!Adapter->Transmitter->OffloadOptions.OffloadIpVersion6UdpChecksum) {
- Adapter->Transmitter->OffloadOptions.OffloadIpVersion6UdpChecksum = 1;
- offloadChanged = TRUE;
- }
- } else {
- if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion6UdpChecksum) {
- Adapter->Transmitter->OffloadOptions.OffloadIpVersion6UdpChecksum = 0;
- offloadChanged = TRUE;
- }
- }
-
- if (rx_enabled(offloadParameters->IPv4Checksum)) {
- if (!Adapter->Receiver.OffloadOptions.OffloadIpVersion4HeaderChecksum) {
- Adapter->Receiver.OffloadOptions.OffloadIpVersion4HeaderChecksum = 1;
- offloadChanged = TRUE;
- }
- } else {
- if (Adapter->Receiver.OffloadOptions.OffloadIpVersion4HeaderChecksum) {
- Adapter->Receiver.OffloadOptions.OffloadIpVersion4HeaderChecksum = 0;
- offloadChanged = TRUE;
- }
- }
-
- if (rx_enabled(offloadParameters->TCPIPv4Checksum)) {
- if (!Adapter->Receiver.OffloadOptions.OffloadIpVersion4TcpChecksum) {
- Adapter->Receiver.OffloadOptions.OffloadIpVersion4TcpChecksum = 1;
- offloadChanged = TRUE;
- }
- } else {
- if (Adapter->Receiver.OffloadOptions.OffloadIpVersion4TcpChecksum) {
- Adapter->Receiver.OffloadOptions.OffloadIpVersion4TcpChecksum = 0;
- offloadChanged = TRUE;
- }
- }
-
- if (rx_enabled(offloadParameters->UDPIPv4Checksum)) {
- if (!Adapter->Receiver.OffloadOptions.OffloadIpVersion4UdpChecksum) {
- Adapter->Receiver.OffloadOptions.OffloadIpVersion4UdpChecksum = 1;
- offloadChanged = TRUE;
- }
- } else {
- if (Adapter->Receiver.OffloadOptions.OffloadIpVersion4UdpChecksum) {
- Adapter->Receiver.OffloadOptions.OffloadIpVersion4UdpChecksum = 0;
- offloadChanged = TRUE;
- }
- }
-
- if (rx_enabled(offloadParameters->TCPIPv6Checksum)) {
- if (!Adapter->Receiver.OffloadOptions.OffloadIpVersion6TcpChecksum) {
- Adapter->Receiver.OffloadOptions.OffloadIpVersion6TcpChecksum = 1;
- offloadChanged = TRUE;
- }
- } else {
- if (Adapter->Receiver.OffloadOptions.OffloadIpVersion6TcpChecksum) {
- Adapter->Receiver.OffloadOptions.OffloadIpVersion6TcpChecksum = 0;
- offloadChanged = TRUE;
- }
- }
-
- if (rx_enabled(offloadParameters->UDPIPv6Checksum)) {
- if (!Adapter->Receiver.OffloadOptions.OffloadIpVersion6UdpChecksum) {
- Adapter->Receiver.OffloadOptions.OffloadIpVersion6UdpChecksum = 1;
- offloadChanged = TRUE;
- }
- } else {
- if (Adapter->Receiver.OffloadOptions.OffloadIpVersion6UdpChecksum) {
- Adapter->Receiver.OffloadOptions.OffloadIpVersion6UdpChecksum = 0;
- offloadChanged = TRUE;
- }
- }
-
-#undef tx_enabled
-#undef rx_enabled
-#undef no_change
-
- if (offloadChanged)
- AdapterIndicateOffloadChanged(Adapter);
- }
- } else {
- ndisStatus = NDIS_STATUS_INVALID_LENGTH;
- }
- break;
- }
- default:
- ndisStatus = NDIS_STATUS_NOT_SUPPORTED;
- break;
- };
-
- NdisRequest->DATA.SET_INFORMATION.BytesNeeded = bytesNeeded;
- if (ndisStatus == NDIS_STATUS_SUCCESS) {
- NdisRequest->DATA.SET_INFORMATION.BytesRead = bytesRead;
- }
-
- return ndisStatus;
-}
-
-//
-// Sets miniport registration attributes.
-//
-static NDIS_STATUS
-AdapterSetRegistrationAttributes (
- IN PADAPTER Adapter
- )
-{
- PNDIS_MINIPORT_ADAPTER_ATTRIBUTES adapterAttributes;
- NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES registrationAttributes;
- NDIS_STATUS ndisStatus;
-
-
- NdisZeroMemory(®istrationAttributes,
- sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES));
-
- registrationAttributes.Header.Type =
- NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES;
-
- registrationAttributes.Header.Revision =
- NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;
-
- registrationAttributes.Header.Size =
- sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES);
-
- registrationAttributes.MiniportAdapterContext = (NDIS_HANDLE)Adapter;
- registrationAttributes.AttributeFlags = NDIS_MINIPORT_ATTRIBUTES_BUS_MASTER |
- NDIS_MINIPORT_ATTRIBUTES_NO_HALT_ON_SUSPEND;
-
- registrationAttributes.CheckForHangTimeInSeconds = 0;
- registrationAttributes.InterfaceType = XENNET_INTERFACE_TYPE;
-
- adapterAttributes =
- (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)®istrationAttributes;
-
- ndisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle,
- adapterAttributes);
+fail10:
+ if ((*Adapter)->NdisDmaHandle)
+ NdisMDeregisterScatterGatherDma((*Adapter)->NdisDmaHandle);
+ (*Adapter)->NdisDmaHandle = NULL;
+fail9:
+fail8:
+fail7:
+fail6:
+ ReceiverTeardown((*Adapter)->Receiver);
+ (*Adapter)->Receiver = NULL;
+fail5:
+ TransmitterTeardown((*Adapter)->Transmitter);
+ (*Adapter)->Transmitter = NULL;
+fail4:
+ (*Adapter)->NdisAdapterHandle = NULL;
+
+ XENVIF_VIF(Release, &(*Adapter)->VifInterface);
+fail3:
+ RtlZeroMemory(&(*Adapter)->VifInterface, sizeof(XENVIF_VIF_INTERFACE));
+fail2:
+ ExFreePoolWithTag(*Adapter, ADAPTER_POOL_TAG);
+fail1:
return ndisStatus;
}
-//
-// Shuts down adapter.
-//
-VOID
-AdapterShutdown (
- IN NDIS_HANDLE MiniportAdapterContext,
- IN NDIS_SHUTDOWN_ACTION ShutdownAction
+VOID
+AdapterTeardown(
+ IN PXENNET_ADAPTER Adapter
)
{
- PADAPTER Adapter = (PADAPTER)MiniportAdapterContext;
-
- UNREFERENCED_PARAMETER(ShutdownAction);
-
- if (ShutdownAction != NdisShutdownBugCheck)
- AdapterStop(Adapter);
-
- return;
-}
-
-//
-// Stops adapter. Waits for currently transmitted packets to complete.
-// Stops transmission of new packets.
-// Stops received packet indication to NDIS.
-//
-NDIS_STATUS
-AdapterStop (
-IN PADAPTER Adapter
-)
-{
- Trace("====>\n");
+ TransmitterTeardown(Adapter->Transmitter);
+ Adapter->Transmitter = NULL;
- if (!Adapter->Enabled)
- goto done;
+ ReceiverTeardown(Adapter->Receiver);
+ Adapter->Receiver = NULL;
- XENVIF_VIF(Disable,
- &Adapter->VifInterface);
+ if (Adapter->NdisDmaHandle != NULL)
+ NdisMDeregisterScatterGatherDma(Adapter->NdisDmaHandle);
+ Adapter->NdisDmaHandle = NULL;
- Adapter->Enabled = FALSE;
+ XENVIF_VIF(Release, &Adapter->VifInterface);
+ RtlZeroMemory(&Adapter->VifInterface, sizeof(XENVIF_VIF_INTERFACE));
-done:
- Trace("<====\n");
- return NDIS_STATUS_SUCCESS;
+ ExFreePoolWithTag(Adapter, ADAPTER_POOL_TAG);
}