return Adapter->Receiver;
}
-NDIS_STATUS
-AdapterEnable(
- IN PXENNET_ADAPTER Adapter
+static FORCEINLINE PVOID
+__AdapterAllocate(
+ IN ULONG Length
)
{
- NTSTATUS status;
-
- if (Adapter->Enabled)
- return NDIS_STATUS_SUCCESS;
-
- status = XENVIF_VIF(Enable,
- &Adapter->VifInterface,
- AdapterVifCallback,
- Adapter);
- if (!NT_SUCCESS(status))
- goto fail1;
-
- Adapter->Enabled = TRUE;
-
- return NDIS_STATUS_SUCCESS;
+ return __AllocateNonPagedPoolWithTag(Length, ADAPTER_POOL_TAG);
+}
-fail1:
- return NDIS_STATUS_FAILURE;
+static FORCEINLINE VOID
+__AdapterFree(
+ IN PVOID Buffer
+ )
+{
+ __FreePoolWithTag(Buffer, ADAPTER_POOL_TAG);
}
-BOOLEAN
-AdapterDisable(
- IN PXENNET_ADAPTER Adapter
+static FORCEINLINE PANSI_STRING
+__AdapterMultiSzToUpcaseAnsi(
+ IN PCHAR Buffer
)
{
- if (!Adapter->Enabled)
- return FALSE;
+ PANSI_STRING Ansi;
+ LONG Index;
+ LONG Count;
+ NTSTATUS status;
- XENVIF_VIF(Disable,
- &Adapter->VifInterface);
+ Index = 0;
+ Count = 0;
+ for (;;) {
+ if (Buffer[Index] == '\0') {
+ Count++;
+ Index++;
- AdapterMediaStateChange(Adapter);
+ // Check for double NUL
+ if (Buffer[Index] == '\0')
+ break;
+ } else {
+ Buffer[Index] = (CHAR)toupper(Buffer[Index]);
+ Index++;
+ }
+ }
- Adapter->Enabled = FALSE;
+ Ansi = __AdapterAllocate(sizeof (ANSI_STRING) * (Count + 1));
- return TRUE;
-}
+ status = STATUS_NO_MEMORY;
+ if (Ansi == NULL)
+ goto fail1;
-VOID
-AdapterMediaStateChange(
- IN PXENNET_ADAPTER Adapter
- )
-{
- NDIS_LINK_STATE LinkState;
- NDIS_STATUS_INDICATION StatusIndication;
+ for (Index = 0; Index < Count; Index++) {
+ ULONG Length;
- 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);
+ Length = (ULONG)strlen(Buffer);
+ Ansi[Index].MaximumLength = (USHORT)(Length + 1);
+ Ansi[Index].Buffer = __AdapterAllocate(Ansi[Index].MaximumLength);
- XENVIF_VIF(MacQueryState,
- &Adapter->VifInterface,
- &LinkState.MediaConnectState,
- &LinkState.RcvLinkSpeed,
- &LinkState.MediaDuplexState);
+ status = STATUS_NO_MEMORY;
+ if (Ansi[Index].Buffer == NULL)
+ goto fail2;
- if (LinkState.MediaConnectState == MediaConnectStateUnknown) {
- Info("LINK: STATE UNKNOWN\n");
- } else if (LinkState.MediaConnectState == MediaConnectStateDisconnected) {
- Info("LINK: DOWN\n");
- } else {
- ASSERT3U(LinkState.MediaConnectState, ==, MediaConnectStateConnected);
+ RtlCopyMemory(Ansi[Index].Buffer, Buffer, Length);
+ Ansi[Index].Length = (USHORT)Length;
- 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);
+ Buffer += Length + 1;
}
- LinkState.XmitLinkSpeed = LinkState.RcvLinkSpeed;
+ return Ansi;
- 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);
+fail2:
+ Error("fail2\n");
- StatusIndication.SourceHandle = Adapter->NdisAdapterHandle;
- StatusIndication.StatusCode = NDIS_STATUS_LINK_STATE;
- StatusIndication.StatusBuffer = &LinkState;
- StatusIndication.StatusBufferSize = sizeof (NDIS_LINK_STATE);
+ while (--Index >= 0)
+ __AdapterFree(Ansi[Index].Buffer);
- NdisMIndicateStatusEx(Adapter->NdisAdapterHandle, &StatusIndication);
+ __AdapterFree(Ansi);
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ return NULL;
}
-NDIS_STATUS
-AdapterSetInformation(
- IN PXENNET_ADAPTER Adapter,
- IN PNDIS_OID_REQUEST Request
+static FORCEINLINE VOID
+__AdapterFreeAnsi(
+ IN PANSI_STRING Ansi
)
{
- PVOID Buffer;
- ULONG BufferLength;
- ULONG BytesNeeded;
- ULONG BytesRead;
- BOOLEAN Warn;
- NDIS_STATUS ndisStatus;
+ ULONG Index;
- Buffer = Request->DATA.SET_INFORMATION.InformationBuffer;
- BufferLength = Request->DATA.SET_INFORMATION.InformationBufferLength;
- BytesNeeded = BytesRead = 0;
- Warn = TRUE;
- ndisStatus = NDIS_STATUS_SUCCESS;
+ for (Index = 0; Ansi[Index].Buffer != NULL; Index++)
+ __AdapterFree(Ansi[Index].Buffer);
- switch (Request->DATA.SET_INFORMATION.Oid) {
- case OID_PNP_SET_POWER:
- BytesNeeded = sizeof(NDIS_DEVICE_POWER_STATE);
- // do nothing
- break;
+ __AdapterFree(Ansi);
+}
- case OID_GEN_CURRENT_LOOKAHEAD:
- BytesNeeded = sizeof(ULONG);
- Adapter->CurrentLookahead = Adapter->MaximumFrameSize;
- if (BufferLength == BytesNeeded) {
- Adapter->CurrentLookahead = *(PULONG)Buffer;
- BytesRead = sizeof(ULONG);
- }
- break;
+static FORCEINLINE BOOLEAN
+__AdapterMatchDistribution(
+ IN PXENNET_ADAPTER Adapter,
+ IN PCHAR Buffer
+ )
+{
+ PCHAR Vendor;
+ PCHAR Product;
+ PCHAR Context;
+ const CHAR *Text;
+ BOOLEAN Match;
+ ULONG Index;
+ NTSTATUS status;
- case OID_GEN_CURRENT_PACKET_FILTER:
- BytesNeeded = sizeof(ULONG);
- if (BufferLength == BytesNeeded) {
- ndisStatus = AdapterSetPacketFilter(Adapter,
- (PULONG)Buffer);
- BytesRead = sizeof(ULONG);
- }
- break;
+ UNREFERENCED_PARAMETER(Adapter);
- 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;
+ status = STATUS_INVALID_PARAMETER;
- 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;
+ Vendor = __strtok_r(Buffer, " ", &Context);
+ if (Vendor == NULL)
+ goto fail1;
- 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);
- }
- break;
+ Product = __strtok_r(NULL, " ", &Context);
+ if (Product == NULL)
+ goto fail2;
- case OID_GEN_HD_SPLIT_PARAMETERS:
- BytesNeeded = sizeof(NDIS_HD_SPLIT_PARAMETERS);
- if (BufferLength >= BytesNeeded) {
- ndisStatus = AdapterGetHeaderDataSplitParameters(Adapter,
- (PNDIS_HD_SPLIT_PARAMETERS)Buffer);
- if (ndisStatus == NDIS_STATUS_SUCCESS)
- BytesRead = sizeof(NDIS_HD_SPLIT_PARAMETERS);
- }
- break;
+ Match = TRUE;
- case OID_GEN_INTERRUPT_MODERATION:
- case OID_GEN_MACHINE_NAME:
- Warn = FALSE;
- /*FALLTHRU*/
- default:
- if (Warn)
- Warning("UNSUPPORTED OID %08x\n", Request->DATA.QUERY_INFORMATION.Oid);
+ Text = VENDOR_NAME_STR;
- ndisStatus = NDIS_STATUS_NOT_SUPPORTED;
- break;
+ for (Index = 0; Text[Index] != 0; Index++) {
+ if (!isalnum((UCHAR)Text[Index])) {
+ if (Vendor[Index] != '_') {
+ Match = FALSE;
+ break;
+ }
+ } else {
+ if (Vendor[Index] != Text[Index]) {
+ Match = FALSE;
+ break;
+ }
+ }
}
- Request->DATA.SET_INFORMATION.BytesNeeded = BytesNeeded;
- if (ndisStatus == NDIS_STATUS_SUCCESS)
- Request->DATA.SET_INFORMATION.BytesRead = BytesRead;
+ Text = "XENNET";
- return ndisStatus;
-}
+ if (_stricmp(Product, Text) != 0)
+ Match = FALSE;
-static FORCEINLINE NDIS_STATUS
-__CopyBuffer(
- IN PVOID Destination,
- IN ULONG DestinationLength,
- IN PVOID Source,
- IN ULONG SourceLength,
- OUT PULONG CopyLength
- )
-{
- *CopyLength = __min(SourceLength, DestinationLength);
- RtlCopyMemory(Destination, Source, *CopyLength);
+ return Match;
- return (DestinationLength >= SourceLength) ?
- NDIS_STATUS_SUCCESS :
- NDIS_STATUS_BUFFER_TOO_SHORT;
-}
+fail2:
+ Error("fail2\n");
-static FORCEINLINE NDIS_STATUS
-__SetUlong(
- IN PVOID Destination,
- IN ULONG DestinationLength,
- IN ULONG Source,
- OUT PULONG CopyLength
- )
-{
- return __CopyBuffer(Destination,
- DestinationLength & ~3,
- &Source,
- sizeof (ULONG),
- CopyLength);
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ return FALSE;
}
-static FORCEINLINE NDIS_STATUS
-__SetUlong64(
- IN PVOID Destination,
- IN ULONG DestinationLength,
- IN ULONG64 Source,
- OUT PULONG CopyLength
+static FORCEINLINE VOID
+__AdapterClearDistribution(
+ IN PXENNET_ADAPTER Adapter
)
{
- NDIS_STATUS ndisStatus;
+ PCHAR Buffer;
+ PANSI_STRING Distributions;
+ ULONG Index;
+ NTSTATUS status;
- ndisStatus = __CopyBuffer(Destination,
- DestinationLength & ~3,
- &Source,
- sizeof (ULONG64),
- CopyLength);
- if (DestinationLength >= 4)
- ndisStatus = NDIS_STATUS_SUCCESS;
+ Trace("====>\n");
- return ndisStatus;
-}
+ status = XENBUS_STORE(Directory,
+ &Adapter->StoreInterface,
+ NULL,
+ NULL,
+ "drivers",
+ &Buffer);
+ if (NT_SUCCESS(status)) {
+ Distributions = __AdapterMultiSzToUpcaseAnsi(Buffer);
-NDIS_STATUS
-AdapterQueryInformation(
- IN PXENNET_ADAPTER Adapter,
- IN PNDIS_OID_REQUEST Request
- )
-{
- PVOID Buffer;
- ULONG BufferLength;
- ULONG BytesNeeded;
- ULONG BytesWritten;
- ULONG Value32;
- ULONGLONG Value64;
- ETHERNET_ADDRESS EthernetAddress;
- BOOLEAN Warn;
- NDIS_STATUS ndisStatus;
+ XENBUS_STORE(Free,
+ &Adapter->StoreInterface,
+ Buffer);
+ } else {
+ Distributions = NULL;
+ }
- Buffer = Request->DATA.QUERY_INFORMATION.InformationBuffer;
- BufferLength = Request->DATA.QUERY_INFORMATION.InformationBufferLength;
- BytesNeeded = BytesWritten = 0;
- Warn = TRUE;
- ndisStatus = NDIS_STATUS_SUCCESS;
+ if (Distributions == NULL)
+ goto done;
- switch (Request->DATA.QUERY_INFORMATION.Oid) {
- case OID_PNP_CAPABILITIES:
- BytesNeeded = sizeof(Adapter->Capabilities);
- ndisStatus = __CopyBuffer(Buffer,
- BufferLength,
- &Adapter->Capabilities,
- BytesNeeded,
- &BytesWritten);
- break;
+ for (Index = 0; Distributions[Index].Buffer != NULL; Index++) {
+ PANSI_STRING Distribution = &Distributions[Index];
- case OID_PNP_QUERY_POWER:
- BytesNeeded = sizeof(NDIS_DEVICE_POWER_STATE);
- BytesWritten = 0;
- // do nothing
- break;
+ status = XENBUS_STORE(Read,
+ &Adapter->StoreInterface,
+ NULL,
+ "drivers",
+ Distribution->Buffer,
+ &Buffer);
+ if (!NT_SUCCESS(status))
+ continue;
- case OID_GEN_SUPPORTED_LIST:
- BytesNeeded = sizeof(XennetSupportedOids);
- ndisStatus = __CopyBuffer(Buffer,
- BufferLength,
- &XennetSupportedOids[0],
- BytesNeeded,
- &BytesWritten);
- break;
+ if (__AdapterMatchDistribution(Adapter, Buffer))
+ (VOID) XENBUS_STORE(Remove,
+ &Adapter->StoreInterface,
+ NULL,
+ "drivers",
+ Distribution->Buffer);
- case OID_GEN_HARDWARE_STATUS:
- BytesNeeded = sizeof(ULONG);
- ndisStatus = __SetUlong(Buffer,
- BufferLength,
- NdisHardwareStatusReady,
- &BytesWritten);
- break;
+ XENBUS_STORE(Free,
+ &Adapter->StoreInterface,
+ Buffer);
+ }
- case OID_GEN_MEDIA_SUPPORTED:
- case OID_GEN_MEDIA_IN_USE:
- BytesNeeded = sizeof(ULONG);
- ndisStatus = __SetUlong(Buffer,
- BufferLength,
- XENNET_MEDIA_TYPE,
- &BytesWritten);
- break;
+ __AdapterFreeAnsi(Distributions);
- case OID_GEN_MAXIMUM_LOOKAHEAD:
- case OID_GEN_TRANSMIT_BLOCK_SIZE:
- case OID_GEN_RECEIVE_BLOCK_SIZE:
- BytesNeeded = sizeof(ULONG);
- ndisStatus = __SetUlong(Buffer,
- BufferLength,
- Adapter->MaximumFrameSize,
- &BytesWritten);
- break;
+done:
+ Trace("<====\n");
+}
- case OID_GEN_TRANSMIT_BUFFER_SPACE:
- case OID_GEN_RECEIVE_BUFFER_SPACE:
- XENVIF_VIF(TransmitterQueryRingSize,
- &Adapter->VifInterface,
- (PULONG)&Value32);
- Value32 *= Adapter->MaximumFrameSize;
- BytesNeeded = sizeof(ULONG);
- ndisStatus = __SetUlong(Buffer,
- BufferLength,
- Value32,
- &BytesWritten);
- break;
+#define MAXIMUM_INDEX 255
- case OID_GEN_VENDOR_DESCRIPTION:
- BytesNeeded = (ULONG)strlen(VENDOR_NAME_STR) + 1;
- ndisStatus = __CopyBuffer(Buffer,
- BufferLength,
- VENDOR_NAME_STR,
- BytesNeeded,
- &BytesWritten);
- break;
+static FORCEINLINE NTSTATUS
+__AdapterSetDistribution(
+ IN PXENNET_ADAPTER Adapter
+ )
+{
+ ULONG Index;
+ CHAR Distribution[MAXNAMELEN];
+ CHAR Vendor[MAXNAMELEN];
+ const CHAR *Product;
+ NTSTATUS status;
- case OID_GEN_VENDOR_DRIVER_VERSION:
- BytesNeeded = sizeof(ULONG);
- ndisStatus = __SetUlong(Buffer,
- BufferLength,
- ((MAJOR_VERSION << 8) | MINOR_VERSION) << 8,
- &BytesWritten);
- break;
+ Trace("====>\n");
- case OID_GEN_DRIVER_VERSION:
- BytesNeeded = sizeof(ULONG);
- ndisStatus = __SetUlong(Buffer,
- BufferLength,
- (6 << 8) | 0, // NDIS 6.0
- &BytesWritten);
- break;
+ Index = 0;
+ while (Index <= MAXIMUM_INDEX) {
+ PCHAR Buffer;
- case OID_GEN_MAC_OPTIONS:
- BytesNeeded = sizeof(ULONG);
- ndisStatus = __SetUlong(Buffer,
- BufferLength,
- XENNET_MAC_OPTIONS,
- &BytesWritten);
- break;
+ status = RtlStringCbPrintfA(Distribution,
+ MAXNAMELEN,
+ "%u",
+ Index);
+ ASSERT(NT_SUCCESS(status));
- case OID_GEN_STATISTICS:
- BytesNeeded = sizeof(NDIS_STATISTICS_INFO);
- ndisStatus = AdapterQueryGeneralStatistics(Adapter,
- (PNDIS_STATISTICS_INFO)Buffer,
- BufferLength,
- &BytesWritten);
- break;
+ status = XENBUS_STORE(Read,
+ &Adapter->StoreInterface,
+ NULL,
+ "drivers",
+ Distribution,
+ &Buffer);
+ if (!NT_SUCCESS(status)) {
+ if (status == STATUS_OBJECT_NAME_NOT_FOUND)
+ goto update;
- case OID_802_3_MULTICAST_LIST:
- ndisStatus = AdapterQueryMulticastList(Adapter,
- Buffer,
- BufferLength,
- &BytesNeeded,
- &BytesWritten);
- break;
+ goto fail1;
+ }
- case OID_802_3_PERMANENT_ADDRESS:
- XENVIF_VIF(MacQueryPermanentAddress,
- &Adapter->VifInterface,
- &EthernetAddress);
- BytesNeeded = sizeof(ETHERNET_ADDRESS);
- ndisStatus = __CopyBuffer(Buffer,
- BufferLength,
- &EthernetAddress,
- BytesNeeded,
- &BytesWritten);
- break;
+ XENBUS_STORE(Free,
+ &Adapter->StoreInterface,
+ Buffer);
- case OID_802_3_CURRENT_ADDRESS:
- XENVIF_VIF(MacQueryCurrentAddress,
- &Adapter->VifInterface,
- &EthernetAddress);
- BytesNeeded = sizeof(ETHERNET_ADDRESS);
- ndisStatus = __CopyBuffer(Buffer,
- BufferLength,
- &EthernetAddress,
- BytesNeeded,
- &BytesWritten);
- break;
+ Index++;
+ }
- case OID_GEN_MAXIMUM_FRAME_SIZE:
- BytesNeeded = sizeof(ULONG);
- ndisStatus = __SetUlong(Buffer,
- BufferLength,
- Adapter->MaximumFrameSize -
- sizeof(ETHERNET_TAGGED_HEADER),
- &BytesWritten);
- break;
+ status = STATUS_UNSUCCESSFUL;
+ goto fail2;
- case OID_GEN_MAXIMUM_TOTAL_SIZE:
- BytesNeeded = sizeof(ULONG);
- ndisStatus = __SetUlong(Buffer,
- BufferLength,
- Adapter->MaximumFrameSize -
- sizeof(ETHERNET_TAGGED_HEADER) +
- sizeof (ETHERNET_UNTAGGED_HEADER),
- &BytesWritten);
- break;
+update:
+ status = RtlStringCbPrintfA(Vendor,
+ MAXNAMELEN,
+ "%s",
+ VENDOR_NAME_STR);
+ ASSERT(NT_SUCCESS(status));
- case OID_GEN_CURRENT_LOOKAHEAD:
- BytesNeeded = sizeof(ULONG);
- ndisStatus = __SetUlong(Buffer,
- BufferLength,
- Adapter->CurrentLookahead,
- &BytesWritten);
- break;
+ for (Index = 0; Vendor[Index] != '\0'; Index++)
+ if (!isalnum((UCHAR)Vendor[Index]))
+ Vendor[Index] = '_';
- case OID_GEN_VENDOR_ID:
- BytesNeeded = sizeof(ULONG);
- ndisStatus = __SetUlong(Buffer,
- BufferLength,
- 0x5853,
- &BytesWritten);
- break;
+ Product = "XENNET";
- case OID_GEN_LINK_SPEED:
- XENVIF_VIF(MacQueryState,
- &Adapter->VifInterface,
- NULL,
- &Value64,
- NULL);
- BytesNeeded = sizeof(ULONG);
- ndisStatus = __SetUlong(Buffer,
- BufferLength,
- (ULONG)(Value64 / 100),
- &BytesWritten);
- break;
+#if DBG
+#define ATTRIBUTES "(DEBUG)"
+#else
+#define ATTRIBUTES ""
+#endif
- case OID_GEN_MEDIA_CONNECT_STATUS:
- XENVIF_VIF(MacQueryState,
- &Adapter->VifInterface,
- (PNET_IF_MEDIA_CONNECT_STATE)&Value32,
- NULL,
- NULL);
- BytesNeeded = sizeof(ULONG);
- ndisStatus = __SetUlong(Buffer,
- BufferLength,
- Value32,
- &BytesWritten);
- break;
+ (VOID) XENBUS_STORE(Printf,
+ &Adapter->StoreInterface,
+ NULL,
+ "drivers",
+ Distribution,
+ "%s %s %u.%u.%u %s",
+ Vendor,
+ Product,
+ MAJOR_VERSION,
+ MINOR_VERSION,
+ MICRO_VERSION,
+ ATTRIBUTES
+ );
- case OID_GEN_MAXIMUM_SEND_PACKETS:
- BytesNeeded = sizeof(ULONG);
- ndisStatus = __SetUlong(Buffer,
- BufferLength,
- 16,
- &BytesWritten);
- break;
+#undef ATTRIBUTES
- case OID_GEN_CURRENT_PACKET_FILTER:
- AdapterGetPacketFilter(Adapter, &Value32);
- BytesNeeded = sizeof(ULONG);
- ndisStatus = __SetUlong(Buffer,
- BufferLength,
- Value32,
- &BytesWritten);
- break;
+ Trace("<====\n");
+ return STATUS_SUCCESS;
- case OID_GEN_XMIT_OK:
- AdapterGetXmitOk(Adapter, &Value64);
- BytesNeeded = sizeof(ULONG64);
- ndisStatus = __SetUlong64(Buffer,
- BufferLength,
- Value64,
- &BytesWritten);
- break;
+fail2:
+ Error("fail2\n");
- case OID_GEN_RCV_OK:
- AdapterGetRcvOk(Adapter, &Value64);
- BytesNeeded = sizeof(ULONG64);
- ndisStatus = __SetUlong64(Buffer,
- BufferLength,
- Value64,
- &BytesWritten);
- break;
+fail1:
+ Error("fail1 (%08x)\n", status);
- case OID_GEN_XMIT_ERROR:
- AdapterGetXmitError(Adapter, &Value32);
- BytesNeeded = sizeof(ULONG);
- ndisStatus = __SetUlong(Buffer,
- BufferLength,
- Value32,
- &BytesWritten);
- break;
+ return status;
+}
- case OID_GEN_RCV_ERROR:
- AdapterGetRcvError(Adapter, &Value32);
- BytesNeeded = sizeof(ULONG);
- ndisStatus = __SetUlong(Buffer,
- BufferLength,
- Value32,
- &BytesWritten);
- break;
+static DECLSPEC_NOINLINE VOID
+AdapterSuspendCallbackLate(
+ IN PVOID Argument
+ )
+{
+ PXENNET_ADAPTER Adapter = Argument;
- 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:
- BytesNeeded = sizeof(ULONG);
- ndisStatus = __SetUlong(Buffer,
- BufferLength,
- 0,
- &BytesWritten);
- break;
+ (VOID) __AdapterSetDistribution(Adapter);
+}
- case OID_802_3_MAXIMUM_LIST_SIZE:
- BytesNeeded = sizeof(ULONG);
- ndisStatus = __SetUlong(Buffer,
- BufferLength,
- 32,
- &BytesWritten);
- break;
+static NTSTATUS
+AdapterSetDistribution(
+ IN PXENNET_ADAPTER Adapter
+ )
+{
+ LONG Count;
+ NTSTATUS status;
- case OID_GEN_DIRECTED_BYTES_XMIT:
- XENVIF_VIF(QueryStatistic,
- &Adapter->VifInterface,
- XENVIF_TRANSMITTER_UNICAST_OCTETS,
- &Value64);
- BytesNeeded = sizeof(ULONG);
- ndisStatus = __SetUlong(Buffer,
- BufferLength,
- (ULONG)Value64,
- &BytesWritten);
- break;
+ Trace("====>\n");
- case OID_GEN_DIRECTED_FRAMES_XMIT:
- XENVIF_VIF(QueryStatistic,
- &Adapter->VifInterface,
- XENVIF_TRANSMITTER_UNICAST_PACKETS,
- &Value64);
- BytesNeeded = sizeof(ULONG);
- ndisStatus = __SetUlong(Buffer,
- BufferLength,
- (ULONG)Value64,
- &BytesWritten);
- break;
+ Count = InterlockedIncrement(&AdapterCount);
+ ASSERT(Count != 0);
- case OID_GEN_MULTICAST_BYTES_XMIT:
- XENVIF_VIF(QueryStatistic,
- &Adapter->VifInterface,
- XENVIF_TRANSMITTER_MULTICAST_OCTETS,
- &Value64);
- BytesNeeded = sizeof(ULONG);
- ndisStatus = __SetUlong(Buffer,
- BufferLength,
- (ULONG)Value64,
- &BytesWritten);
- break;
+ if (Count != 1)
+ goto done;
- case OID_GEN_MULTICAST_FRAMES_XMIT:
- XENVIF_VIF(QueryStatistic,
- &Adapter->VifInterface,
- XENVIF_TRANSMITTER_MULTICAST_PACKETS,
- &Value64);
- BytesNeeded = sizeof(ULONG);
- ndisStatus = __SetUlong(Buffer,
- BufferLength,
- (ULONG)Value64,
- &BytesWritten);
- break;
+ status = __AdapterSetDistribution(Adapter);
+ if (!NT_SUCCESS(status))
+ goto fail1;
+
+ status = XENBUS_SUSPEND(Register,
+ &Adapter->SuspendInterface,
+ SUSPEND_CALLBACK_LATE,
+ AdapterSuspendCallbackLate,
+ Adapter,
+ &Adapter->SuspendCallbackLate);
+ if (!NT_SUCCESS(status))
+ goto fail2;
+
+done:
+ Trace("<====\n");
+ return STATUS_SUCCESS;
+
+fail2:
+ Error("fail2\n");
+
+ __AdapterClearDistribution(Adapter);
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ return status;
+}
+
+static VOID
+AdapterClearDistribution(
+ IN PXENNET_ADAPTER Adapter
+ )
+{
+ LONG Count;
+
+ Trace("====>\n");
+
+ Count = InterlockedDecrement(&AdapterCount);
+
+ if (Count != 0)
+ goto done;
+
+ XENBUS_SUSPEND(Deregister,
+ &Adapter->SuspendInterface,
+ Adapter->SuspendCallbackLate);
+ Adapter->SuspendCallbackLate = NULL;
+
+ __AdapterClearDistribution(Adapter);
+
+done:
+ Trace("<====\n");
+}
+
+NDIS_STATUS
+AdapterEnable(
+ IN PXENNET_ADAPTER Adapter
+ )
+{
+ NTSTATUS status;
+ NDIS_STATUS ndisStatus;
+
+ ASSERT(!Adapter->Enabled);
+
+ status = XENBUS_CACHE(Acquire,
+ &Adapter->CacheInterface);
+ if (!NT_SUCCESS(status))
+ goto fail1;
+
+ status = XENBUS_STORE(Acquire,
+ &Adapter->StoreInterface);
+ if (!NT_SUCCESS(status))
+ goto fail2;
+
+ status = XENBUS_SUSPEND(Acquire,
+ &Adapter->SuspendInterface);
+ if (!NT_SUCCESS(status))
+ goto fail3;
+
+ (VOID) AdapterSetDistribution(Adapter);
+
+ ndisStatus = TransmitterEnable(Adapter->Transmitter);
+ if (ndisStatus != NDIS_STATUS_SUCCESS)
+ goto fail4;
+
+ ndisStatus = ReceiverEnable(Adapter->Receiver);
+ if (ndisStatus != NDIS_STATUS_SUCCESS)
+ goto fail5;
+
+ status = XENVIF_VIF(Enable,
+ &Adapter->VifInterface,
+ AdapterVifCallback,
+ Adapter);
+ if (!NT_SUCCESS(status))
+ goto fail6;
+
+ AdapterMediaStateChange(Adapter);
+
+ Adapter->Enabled = TRUE;
+
+ return NDIS_STATUS_SUCCESS;
+
+fail6:
+ ReceiverDisable(Adapter->Receiver);
+
+fail5:
+ TransmitterDisable(Adapter->Transmitter);
+
+fail4:
+ AdapterClearDistribution(Adapter);
+
+ XENBUS_SUSPEND(Release, &Adapter->SuspendInterface);
+
+fail3:
+ XENBUS_STORE(Release, &Adapter->StoreInterface);
+
+fail2:
+ XENBUS_CACHE(Release, &Adapter->CacheInterface);
+
+fail1:
+ return NDIS_STATUS_FAILURE;
+}
- case OID_GEN_BROADCAST_BYTES_XMIT:
- XENVIF_VIF(QueryStatistic,
- &Adapter->VifInterface,
- XENVIF_TRANSMITTER_BROADCAST_OCTETS,
- &Value64);
- BytesNeeded = sizeof(ULONG);
- ndisStatus = __SetUlong(Buffer,
- BufferLength,
- (ULONG)Value64,
- &BytesWritten);
- break;
+VOID
+AdapterDisable(
+ IN PXENNET_ADAPTER Adapter
+ )
+{
+ ASSERT(Adapter->Enabled);
+ Adapter->Enabled = FALSE;
- case OID_GEN_BROADCAST_FRAMES_XMIT:
- XENVIF_VIF(QueryStatistic,
- &Adapter->VifInterface,
- XENVIF_TRANSMITTER_BROADCAST_PACKETS,
- &Value64);
- BytesNeeded = sizeof(ULONG);
- ndisStatus = __SetUlong(Buffer,
- BufferLength,
- (ULONG)Value64,
- &BytesWritten);
- break;
+ XENVIF_VIF(Disable,
+ &Adapter->VifInterface);
- case OID_GEN_DIRECTED_BYTES_RCV:
- XENVIF_VIF(QueryStatistic,
- &Adapter->VifInterface,
- XENVIF_RECEIVER_UNICAST_OCTETS,
- &Value64);
- BytesNeeded = sizeof(ULONG);
- ndisStatus = __SetUlong(Buffer,
- BufferLength,
- (ULONG)Value64,
- &BytesWritten);
- break;
+ AdapterMediaStateChange(Adapter);
- case OID_GEN_DIRECTED_FRAMES_RCV:
- XENVIF_VIF(QueryStatistic,
- &Adapter->VifInterface,
- XENVIF_RECEIVER_UNICAST_PACKETS,
- &Value64);
- BytesNeeded = sizeof(ULONG);
- ndisStatus = __SetUlong(Buffer,
- BufferLength,
- (ULONG)Value64,
- &BytesWritten);
- break;
+ ReceiverDisable(Adapter->Receiver);
+ TransmitterDisable(Adapter->Transmitter);
- case OID_GEN_MULTICAST_BYTES_RCV:
- XENVIF_VIF(QueryStatistic,
- &Adapter->VifInterface,
- XENVIF_RECEIVER_MULTICAST_OCTETS,
- &Value64);
- BytesNeeded = sizeof(ULONG);
- ndisStatus = __SetUlong(Buffer,
- BufferLength,
- (ULONG)Value64,
- &BytesWritten);
- break;
+ AdapterClearDistribution(Adapter);
- case OID_GEN_MULTICAST_FRAMES_RCV:
- XENVIF_VIF(QueryStatistic,
- &Adapter->VifInterface,
- XENVIF_RECEIVER_MULTICAST_PACKETS,
- &Value64);
- BytesNeeded = sizeof(ULONG);
- ndisStatus = __SetUlong(Buffer,
- BufferLength,
- (ULONG)Value64,
- &BytesWritten);
- break;
+ XENBUS_SUSPEND(Release, &Adapter->SuspendInterface);
+ XENBUS_STORE(Release, &Adapter->StoreInterface);
+ XENBUS_CACHE(Release, &Adapter->CacheInterface);
+}
- case OID_GEN_BROADCAST_BYTES_RCV:
- XENVIF_VIF(QueryStatistic,
- &Adapter->VifInterface,
- XENVIF_RECEIVER_BROADCAST_OCTETS,
- &Value64);
- BytesNeeded = sizeof(ULONG);
- ndisStatus = __SetUlong(Buffer,
- BufferLength,
- (ULONG)Value64,
- &BytesWritten);
- break;
+VOID
+AdapterMediaStateChange(
+ IN PXENNET_ADAPTER Adapter
+ )
+{
+ NDIS_LINK_STATE LinkState;
+ NDIS_STATUS_INDICATION StatusIndication;
- case OID_GEN_BROADCAST_FRAMES_RCV:
- XENVIF_VIF(QueryStatistic,
- &Adapter->VifInterface,
- XENVIF_RECEIVER_BROADCAST_PACKETS,
- &Value64);
- BytesNeeded = sizeof(ULONG);
- ndisStatus = __SetUlong(Buffer,
- BufferLength,
- (ULONG)Value64,
- &BytesWritten);
- break;
+ 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);
- case OID_GEN_INTERRUPT_MODERATION:
- BytesNeeded = sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS);
- ndisStatus = AdapterInterruptModeration(Adapter,
- (PNDIS_INTERRUPT_MODERATION_PARAMETERS)Buffer,
- BufferLength,
- &BytesWritten);
- break;
+ XENVIF_VIF(MacQueryState,
+ &Adapter->VifInterface,
+ &LinkState.MediaConnectState,
+ &LinkState.RcvLinkSpeed,
+ &LinkState.MediaDuplexState);
- 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:
- // ignore these common unwanted OIDs
- case OID_GEN_INIT_TIME_MS:
- case OID_GEN_RESET_COUNTS:
- case OID_GEN_MEDIA_SENSE_COUNTS:
- Warn = FALSE;
- /*FALLTHRU*/
- default:
- if (Warn)
- Warning("UNSUPPORTED OID %08x\n", Request->DATA.QUERY_INFORMATION.Oid);
+ if (LinkState.MediaConnectState == MediaConnectStateUnknown) {
+ Info("LINK: STATE UNKNOWN\n");
+ } else if (LinkState.MediaConnectState == MediaConnectStateDisconnected) {
+ Info("LINK: DOWN\n");
+ } else {
+ ASSERT3U(LinkState.MediaConnectState, ==, MediaConnectStateConnected);
- ndisStatus = NDIS_STATUS_NOT_SUPPORTED;
- break;
+ 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);
}
- Request->DATA.QUERY_INFORMATION.BytesWritten = BytesWritten;
- Request->DATA.QUERY_INFORMATION.BytesNeeded = BytesNeeded;
+ LinkState.XmitLinkSpeed = LinkState.RcvLinkSpeed;
- return ndisStatus;
+ 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);
}
-static NTSTATUS
-__QueryInterface(
- IN PDEVICE_OBJECT DeviceObject,
- IN const GUID *Guid,
- IN ULONG Version,
- OUT PINTERFACE Interface,
- IN ULONG Size,
- IN BOOLEAN Optional
+NDIS_STATUS
+AdapterSetInformation(
+ IN PXENNET_ADAPTER Adapter,
+ IN PNDIS_OID_REQUEST Request
)
{
- KEVENT Event;
- IO_STATUS_BLOCK StatusBlock;
- PIRP Irp;
- PIO_STACK_LOCATION StackLocation;
- NTSTATUS status;
+ PVOID Buffer;
+ ULONG BufferLength;
+ ULONG BytesNeeded;
+ ULONG BytesRead;
+ BOOLEAN Warn;
+ NDIS_STATUS ndisStatus;
- ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+ Buffer = Request->DATA.SET_INFORMATION.InformationBuffer;
+ BufferLength = Request->DATA.SET_INFORMATION.InformationBufferLength;
+ BytesNeeded = BytesRead = 0;
+ Warn = TRUE;
+ ndisStatus = NDIS_STATUS_SUCCESS;
- KeInitializeEvent(&Event, NotificationEvent, FALSE);
- RtlZeroMemory(&StatusBlock, sizeof(IO_STATUS_BLOCK));
+ switch (Request->DATA.SET_INFORMATION.Oid) {
+ case OID_PNP_SET_POWER:
+ BytesNeeded = sizeof(NDIS_DEVICE_POWER_STATE);
+ if (BufferLength >= BytesNeeded) {
+ PNDIS_DEVICE_POWER_STATE PowerState;
- Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
- DeviceObject,
- NULL,
- 0,
- NULL,
- &Event,
- &StatusBlock);
+ PowerState = (PNDIS_DEVICE_POWER_STATE)Buffer;
+ switch (*PowerState) {
+ case NdisDeviceStateD0:
+ Info("SET_POWER: D0\n");
+ break;
- status = STATUS_UNSUCCESSFUL;
- if (Irp == NULL)
- goto fail1;
+ case NdisDeviceStateD1:
+ Info("SET_POWER: D1\n");
+ break;
- StackLocation = IoGetNextIrpStackLocation(Irp);
- StackLocation->MinorFunction = IRP_MN_QUERY_INTERFACE;
+ case NdisDeviceStateD2:
+ Info("SET_POWER: D2\n");
+ break;
- StackLocation->Parameters.QueryInterface.InterfaceType = Guid;
- StackLocation->Parameters.QueryInterface.Size = (USHORT)Size;
- StackLocation->Parameters.QueryInterface.Version = (USHORT)Version;
- StackLocation->Parameters.QueryInterface.Interface = Interface;
+ case NdisDeviceStateD3:
+ Info("SET_POWER: D3\n");
+ break;
+ }
+ }
+ // do nothing
+ break;
- Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+ case OID_GEN_CURRENT_LOOKAHEAD:
+ BytesNeeded = sizeof(ULONG);
+ Adapter->CurrentLookahead = Adapter->MaximumFrameSize;
+ if (BufferLength == BytesNeeded) {
+ Adapter->CurrentLookahead = *(PULONG)Buffer;
+ BytesRead = sizeof(ULONG);
+ }
+ break;
- status = IoCallDriver(DeviceObject, Irp);
- if (status == STATUS_PENDING) {
- (VOID) KeWaitForSingleObject(&Event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- status = StatusBlock.Status;
- }
+ case OID_GEN_CURRENT_PACKET_FILTER:
+ BytesNeeded = sizeof(ULONG);
+ if (BufferLength == BytesNeeded) {
+ ndisStatus = AdapterSetPacketFilter(Adapter,
+ (PULONG)Buffer);
+ BytesRead = sizeof(ULONG);
+ }
+ break;
- if (!NT_SUCCESS(status)) {
- if (status == STATUS_NOT_SUPPORTED && Optional)
- goto done;
+ 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;
- goto fail2;
- }
+ 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;
-done:
- return STATUS_SUCCESS;
+ 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);
+ }
+ break;
-fail2:
- Error("fail2\n");
+ case OID_GEN_HD_SPLIT_PARAMETERS:
+ BytesNeeded = sizeof(NDIS_HD_SPLIT_PARAMETERS);
+ if (BufferLength >= BytesNeeded) {
+ ndisStatus = AdapterGetHeaderDataSplitParameters(Adapter,
+ (PNDIS_HD_SPLIT_PARAMETERS)Buffer);
+ if (ndisStatus == NDIS_STATUS_SUCCESS)
+ BytesRead = sizeof(NDIS_HD_SPLIT_PARAMETERS);
+ }
+ break;
-fail1:
- Error("fail1 (%08x)\n", status);
+ case OID_GEN_INTERRUPT_MODERATION:
+ case OID_GEN_MACHINE_NAME:
+ Warn = FALSE;
+ /*FALLTHRU*/
+ default:
+ if (Warn)
+ Warning("UNSUPPORTED OID %08x\n", Request->DATA.QUERY_INFORMATION.Oid);
- return status;
-}
+ ndisStatus = NDIS_STATUS_NOT_SUPPORTED;
+ break;
+ }
-#pragma prefast(push)
-#pragma prefast(disable:6102)
+ Request->DATA.SET_INFORMATION.BytesNeeded = BytesNeeded;
+ if (ndisStatus == NDIS_STATUS_SUCCESS)
+ Request->DATA.SET_INFORMATION.BytesRead = BytesRead;
-#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);
+ return ndisStatus;
+}
-static NDIS_STATUS
-AdapterGetAdvancedSettings(
- IN PXENNET_ADAPTER Adapter
+static FORCEINLINE NDIS_STATUS
+__CopyBuffer(
+ IN PVOID Destination,
+ IN ULONG DestinationLength,
+ IN PVOID Source,
+ IN ULONG SourceLength,
+ OUT PULONG CopyLength
)
{
- 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;
-
- 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);
- READ_PROPERTY(Adapter->Properties.HeaderDataSplit, L"*HeaderDataSplit", 1, Handle);
-
- NdisCloseConfiguration(Handle);
-
- return NDIS_STATUS_SUCCESS;
+ *CopyLength = __min(SourceLength, DestinationLength);
+ RtlCopyMemory(Destination, Source, *CopyLength);
-fail1:
- return NDIS_STATUS_FAILURE;
+ return (DestinationLength >= SourceLength) ?
+ NDIS_STATUS_SUCCESS :
+ NDIS_STATUS_BUFFER_TOO_SHORT;
}
-#undef READ_PROPERTY
-
-#pragma prefast(pop)
-
-static NDIS_STATUS
-AdapterSetRegistrationAttributes(
- IN PXENNET_ADAPTER Adapter
+static FORCEINLINE NDIS_STATUS
+__SetUlong(
+ IN PVOID Destination,
+ IN ULONG DestinationLength,
+ IN ULONG Source,
+ OUT PULONG CopyLength
)
{
- NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES Attribs;
- NDIS_STATUS ndisStatus;
+ return __CopyBuffer(Destination,
+ DestinationLength & ~3,
+ &Source,
+ sizeof (ULONG),
+ CopyLength);
+}
- 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;
+static FORCEINLINE NDIS_STATUS
+__SetUlong64(
+ IN PVOID Destination,
+ IN ULONG DestinationLength,
+ IN ULONG64 Source,
+ OUT PULONG CopyLength
+ )
+{
+ NDIS_STATUS ndisStatus;
- ndisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle,
- (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs);
+ ndisStatus = __CopyBuffer(Destination,
+ DestinationLength & ~3,
+ &Source,
+ sizeof (ULONG64),
+ CopyLength);
+ if (DestinationLength >= 4)
+ ndisStatus = NDIS_STATUS_SUCCESS;
return ndisStatus;
}
-static NDIS_STATUS
-AdapterSetGeneralAttributes(
- IN PXENNET_ADAPTER Adapter
+NDIS_STATUS
+AdapterQueryInformation(
+ IN PXENNET_ADAPTER Adapter,
+ IN PNDIS_OID_REQUEST Request
)
{
- NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES Attribs;
- NDIS_STATUS ndisStatus;
-
- 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);
-
- 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)&Attribs.PermanentMacAddress);
- XENVIF_VIF(MacQueryCurrentAddress,
- &Adapter->VifInterface,
- (PETHERNET_ADDRESS)&Attribs.CurrentMacAddress);
+ PVOID Buffer;
+ ULONG BufferLength;
+ ULONG BytesNeeded;
+ ULONG BytesWritten;
+ ULONG Value32;
+ ULONGLONG Value64;
+ ETHERNET_ADDRESS EthernetAddress;
+ BOOLEAN Warn;
+ NDIS_STATUS ndisStatus;
- Attribs.PhysicalMediumType = NdisPhysicalMedium802_3;
- Attribs.RecvScaleCapabilities = NULL;
- Attribs.AccessType = NET_IF_ACCESS_BROADCAST;
- Attribs.DirectionType = NET_IF_DIRECTION_SENDRECEIVE;
- Attribs.ConnectionType = NET_IF_CONNECTION_DEDICATED;
- Attribs.IfType = IF_TYPE_ETHERNET_CSMACD;
- Attribs.IfConnectorPresent = TRUE;
- Attribs.SupportedStatistics = NDIS_STATISTICS_XMIT_OK_SUPPORTED |
- NDIS_STATISTICS_XMIT_ERROR_SUPPORTED |
- NDIS_STATISTICS_DIRECTED_BYTES_XMIT_SUPPORTED |
- NDIS_STATISTICS_DIRECTED_FRAMES_XMIT_SUPPORTED |
- NDIS_STATISTICS_MULTICAST_BYTES_XMIT_SUPPORTED |
- NDIS_STATISTICS_MULTICAST_FRAMES_XMIT_SUPPORTED |
- NDIS_STATISTICS_BROADCAST_BYTES_XMIT_SUPPORTED |
- NDIS_STATISTICS_BROADCAST_FRAMES_XMIT_SUPPORTED |
- NDIS_STATISTICS_RCV_OK_SUPPORTED |
- NDIS_STATISTICS_RCV_ERROR_SUPPORTED |
- NDIS_STATISTICS_DIRECTED_BYTES_RCV_SUPPORTED |
- NDIS_STATISTICS_DIRECTED_FRAMES_RCV_SUPPORTED |
- NDIS_STATISTICS_MULTICAST_BYTES_RCV_SUPPORTED |
- NDIS_STATISTICS_MULTICAST_FRAMES_RCV_SUPPORTED |
- NDIS_STATISTICS_BROADCAST_BYTES_RCV_SUPPORTED |
- NDIS_STATISTICS_BROADCAST_FRAMES_RCV_SUPPORTED |
- NDIS_STATISTICS_GEN_STATISTICS_SUPPORTED;
-
- Attribs.SupportedOidList = XennetSupportedOids;
- Attribs.SupportedOidListLength = sizeof(XennetSupportedOids);
+ Buffer = Request->DATA.QUERY_INFORMATION.InformationBuffer;
+ BufferLength = Request->DATA.QUERY_INFORMATION.InformationBufferLength;
+ BytesNeeded = BytesWritten = 0;
+ Warn = TRUE;
+ ndisStatus = NDIS_STATUS_SUCCESS;
- ndisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle,
- (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs);
+ switch (Request->DATA.QUERY_INFORMATION.Oid) {
+ case OID_PNP_CAPABILITIES:
+ BytesNeeded = sizeof(Adapter->Capabilities);
+ ndisStatus = __CopyBuffer(Buffer,
+ BufferLength,
+ &Adapter->Capabilities,
+ BytesNeeded,
+ &BytesWritten);
+ break;
- return ndisStatus;
-}
+ case OID_PNP_QUERY_POWER:
+ BytesNeeded = sizeof(NDIS_DEVICE_POWER_STATE);
-static NDIS_STATUS
-AdapterSetOffloadAttributes(
- IN PXENNET_ADAPTER Adapter
- )
-{
- 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;
+ if (BufferLength >= BytesNeeded) {
+ PNDIS_DEVICE_POWER_STATE PowerState;
- TxOptions = TransmitterOffloadOptions(Adapter->Transmitter);
- RxOptions = ReceiverOffloadOptions(Adapter->Receiver);
+ PowerState = (PNDIS_DEVICE_POWER_STATE)Buffer;
+ switch (*PowerState) {
+ case NdisDeviceStateD0:
+ Info("QUERY_POWER: D0\n");
+ break;
- TxOptions->Value = 0;
- TxOptions->OffloadTagManipulation = 1;
+ case NdisDeviceStateD1:
+ Info("QUERY_POWER: D1\n");
+ break;
- RxOptions->Value = 0;
- RxOptions->OffloadTagManipulation = 1;
+ case NdisDeviceStateD2:
+ Info("QUERY_POWER: D2\n");
+ break;
- if (Adapter->Properties.need_csum_value)
- RxOptions->NeedChecksumValue = 1;
+ case NdisDeviceStateD3:
+ Info("QUERY_POWER: D3\n");
+ break;
+ }
+ }
- if (Adapter->Properties.lrov4) {
- RxOptions->OffloadIpVersion4LargePacket = 1;
- RxOptions->NeedLargePacketSplit = 1;
- }
+ BytesWritten = 0;
+ // do nothing
+ break;
- if (Adapter->Properties.lrov6) {
- RxOptions->OffloadIpVersion6LargePacket = 1;
- RxOptions->NeedLargePacketSplit = 1;
- }
+ case OID_GEN_SUPPORTED_LIST:
+ BytesNeeded = sizeof(XennetSupportedOids);
+ ndisStatus = __CopyBuffer(Buffer,
+ BufferLength,
+ &XennetSupportedOids[0],
+ BytesNeeded,
+ &BytesWritten);
+ break;
- XENVIF_VIF(ReceiverSetOffloadOptions,
- &Adapter->VifInterface,
- *RxOptions);
+ case OID_GEN_HARDWARE_STATUS:
+ BytesNeeded = sizeof(ULONG);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ NdisHardwareStatusReady,
+ &BytesWritten);
+ break;
- XENVIF_VIF(TransmitterQueryOffloadOptions,
- &Adapter->VifInterface,
- &Options);
+ case OID_GEN_MEDIA_SUPPORTED:
+ case OID_GEN_MEDIA_IN_USE:
+ BytesNeeded = sizeof(ULONG);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ XENNET_MEDIA_TYPE,
+ &BytesWritten);
+ break;
- 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);
+ case OID_GEN_MAXIMUM_LOOKAHEAD:
+ case OID_GEN_TRANSMIT_BLOCK_SIZE:
+ case OID_GEN_RECEIVE_BLOCK_SIZE:
+ BytesNeeded = sizeof(ULONG);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ Adapter->MaximumFrameSize,
+ &BytesWritten);
+ break;
- Supported.Checksum.IPv4Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
+ case OID_GEN_TRANSMIT_BUFFER_SPACE:
+ case OID_GEN_RECEIVE_BUFFER_SPACE:
+ XENVIF_VIF(TransmitterQueryRingSize,
+ &Adapter->VifInterface,
+ (PULONG)&Value32);
+ Value32 *= Adapter->MaximumFrameSize;
+ BytesNeeded = sizeof(ULONG);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ Value32,
+ &BytesWritten);
+ break;
- Supported.Checksum.IPv4Receive.IpChecksum = 1;
- Supported.Checksum.IPv4Receive.IpOptionsSupported = 1;
+ case OID_GEN_VENDOR_DESCRIPTION:
+ BytesNeeded = (ULONG)strlen(VENDOR_NAME_STR) + 1;
+ ndisStatus = __CopyBuffer(Buffer,
+ BufferLength,
+ VENDOR_NAME_STR,
+ BytesNeeded,
+ &BytesWritten);
+ break;
- Supported.Checksum.IPv4Receive.TcpChecksum = 1;
- Supported.Checksum.IPv4Receive.TcpOptionsSupported = 1;
+ case OID_GEN_VENDOR_DRIVER_VERSION:
+ BytesNeeded = sizeof(ULONG);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ ((MAJOR_VERSION << 8) | MINOR_VERSION) << 8,
+ &BytesWritten);
+ break;
- Supported.Checksum.IPv4Receive.UdpChecksum = 1;
+ case OID_GEN_DRIVER_VERSION:
+ BytesNeeded = sizeof(ULONG);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ (6 << 8) | 0, // NDIS 6.0
+ &BytesWritten);
+ break;
- Supported.Checksum.IPv6Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
+ case OID_GEN_MAC_OPTIONS:
+ BytesNeeded = sizeof(ULONG);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ XENNET_MAC_OPTIONS,
+ &BytesWritten);
+ break;
- Supported.Checksum.IPv6Receive.IpExtensionHeadersSupported = 1;
+ case OID_GEN_STATISTICS:
+ BytesNeeded = sizeof(NDIS_STATISTICS_INFO);
+ ndisStatus = AdapterQueryGeneralStatistics(Adapter,
+ (PNDIS_STATISTICS_INFO)Buffer,
+ BufferLength,
+ &BytesWritten);
+ break;
- Supported.Checksum.IPv6Receive.TcpChecksum = 1;
- Supported.Checksum.IPv6Receive.TcpOptionsSupported = 1;
+ case OID_802_3_MULTICAST_LIST:
+ ndisStatus = AdapterQueryMulticastList(Adapter,
+ Buffer,
+ BufferLength,
+ &BytesNeeded,
+ &BytesWritten);
+ break;
- Supported.Checksum.IPv6Receive.UdpChecksum = 1;
+ case OID_802_3_PERMANENT_ADDRESS:
+ XENVIF_VIF(MacQueryPermanentAddress,
+ &Adapter->VifInterface,
+ &EthernetAddress);
+ BytesNeeded = sizeof(ETHERNET_ADDRESS);
+ ndisStatus = __CopyBuffer(Buffer,
+ BufferLength,
+ &EthernetAddress,
+ BytesNeeded,
+ &BytesWritten);
+ break;
- Supported.Checksum.IPv4Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
+ case OID_802_3_CURRENT_ADDRESS:
+ XENVIF_VIF(MacQueryCurrentAddress,
+ &Adapter->VifInterface,
+ &EthernetAddress);
+ BytesNeeded = sizeof(ETHERNET_ADDRESS);
+ ndisStatus = __CopyBuffer(Buffer,
+ BufferLength,
+ &EthernetAddress,
+ BytesNeeded,
+ &BytesWritten);
+ break;
+
+ case OID_GEN_MAXIMUM_FRAME_SIZE:
+ BytesNeeded = sizeof(ULONG);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ Adapter->MaximumFrameSize -
+ sizeof(ETHERNET_TAGGED_HEADER),
+ &BytesWritten);
+ break;
+
+ case OID_GEN_MAXIMUM_TOTAL_SIZE:
+ BytesNeeded = sizeof(ULONG);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ Adapter->MaximumFrameSize -
+ sizeof(ETHERNET_TAGGED_HEADER) +
+ sizeof (ETHERNET_UNTAGGED_HEADER),
+ &BytesWritten);
+ break;
+
+ case OID_GEN_CURRENT_LOOKAHEAD:
+ BytesNeeded = sizeof(ULONG);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ Adapter->CurrentLookahead,
+ &BytesWritten);
+ break;
+
+ case OID_GEN_VENDOR_ID:
+ BytesNeeded = sizeof(ULONG);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ 0x5853,
+ &BytesWritten);
+ break;
+
+ case OID_GEN_LINK_SPEED:
+ XENVIF_VIF(MacQueryState,
+ &Adapter->VifInterface,
+ NULL,
+ &Value64,
+ NULL);
+ BytesNeeded = sizeof(ULONG);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ (ULONG)(Value64 / 100),
+ &BytesWritten);
+ break;
+
+ case OID_GEN_MEDIA_CONNECT_STATUS:
+ XENVIF_VIF(MacQueryState,
+ &Adapter->VifInterface,
+ (PNET_IF_MEDIA_CONNECT_STATE)&Value32,
+ NULL,
+ NULL);
+ BytesNeeded = sizeof(ULONG);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ Value32,
+ &BytesWritten);
+ break;
+
+ case OID_GEN_MAXIMUM_SEND_PACKETS:
+ BytesNeeded = sizeof(ULONG);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ 16,
+ &BytesWritten);
+ break;
- if (Options.OffloadIpVersion4HeaderChecksum) {
- Supported.Checksum.IPv4Transmit.IpChecksum = 1;
- Supported.Checksum.IPv4Transmit.IpOptionsSupported = 1;
- }
+ case OID_GEN_CURRENT_PACKET_FILTER:
+ AdapterGetPacketFilter(Adapter, &Value32);
+ BytesNeeded = sizeof(ULONG);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ Value32,
+ &BytesWritten);
+ break;
- if (Options.OffloadIpVersion4TcpChecksum) {
- Supported.Checksum.IPv4Transmit.TcpChecksum = 1;
- Supported.Checksum.IPv4Transmit.TcpOptionsSupported = 1;
- }
+ case OID_GEN_XMIT_OK:
+ AdapterGetXmitOk(Adapter, &Value64);
+ BytesNeeded = sizeof(ULONG64);
+ ndisStatus = __SetUlong64(Buffer,
+ BufferLength,
+ Value64,
+ &BytesWritten);
+ break;
- if (Options.OffloadIpVersion4UdpChecksum)
- Supported.Checksum.IPv4Transmit.UdpChecksum = 1;
+ case OID_GEN_RCV_OK:
+ AdapterGetRcvOk(Adapter, &Value64);
+ BytesNeeded = sizeof(ULONG64);
+ ndisStatus = __SetUlong64(Buffer,
+ BufferLength,
+ Value64,
+ &BytesWritten);
+ break;
- Supported.Checksum.IPv6Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
+ case OID_GEN_XMIT_ERROR:
+ AdapterGetXmitError(Adapter, &Value32);
+ BytesNeeded = sizeof(ULONG);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ Value32,
+ &BytesWritten);
+ break;
- Supported.Checksum.IPv6Transmit.IpExtensionHeadersSupported = 1;
+ case OID_GEN_RCV_ERROR:
+ AdapterGetRcvError(Adapter, &Value32);
+ BytesNeeded = sizeof(ULONG);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ Value32,
+ &BytesWritten);
+ break;
- if (Options.OffloadIpVersion6TcpChecksum) {
- Supported.Checksum.IPv6Transmit.TcpChecksum = 1;
- Supported.Checksum.IPv6Transmit.TcpOptionsSupported = 1;
- }
+ 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:
+ BytesNeeded = sizeof(ULONG);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ 0,
+ &BytesWritten);
+ break;
- if (Options.OffloadIpVersion6UdpChecksum)
- Supported.Checksum.IPv6Transmit.UdpChecksum = 1;
+ case OID_802_3_MAXIMUM_LIST_SIZE:
+ BytesNeeded = sizeof(ULONG);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ 32,
+ &BytesWritten);
+ break;
- if (Options.OffloadIpVersion4LargePacket) {
- XENVIF_VIF(TransmitterQueryLargePacketSize,
+ case OID_GEN_DIRECTED_BYTES_XMIT:
+ XENVIF_VIF(QueryStatistic,
&Adapter->VifInterface,
- 4,
- &Supported.LsoV2.IPv4.MaxOffLoadSize);
- Supported.LsoV2.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
- Supported.LsoV2.IPv4.MinSegmentCount = 2;
- }
+ XENVIF_TRANSMITTER_UNICAST_OCTETS,
+ &Value64);
+ BytesNeeded = sizeof(ULONG);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ (ULONG)Value64,
+ &BytesWritten);
+ break;
- if (Options.OffloadIpVersion6LargePacket) {
- XENVIF_VIF(TransmitterQueryLargePacketSize,
+ case OID_GEN_DIRECTED_FRAMES_XMIT:
+ XENVIF_VIF(QueryStatistic,
&Adapter->VifInterface,
- 6,
- &Supported.LsoV2.IPv6.MaxOffLoadSize);
- Supported.LsoV2.IPv6.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
- Supported.LsoV2.IPv6.MinSegmentCount = 2;
- Supported.LsoV2.IPv6.IpExtensionHeadersSupported = 1;
- Supported.LsoV2.IPv6.TcpOptionsSupported = 1;
- }
-
- Default = Supported;
+ XENVIF_TRANSMITTER_UNICAST_PACKETS,
+ &Value64);
+ BytesNeeded = sizeof(ULONG);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ (ULONG)Value64,
+ &BytesWritten);
+ break;
- if (!(Adapter->Properties.ipv4_csum & 2))
- Default.Checksum.IPv4Receive.IpChecksum = 0;
+ case OID_GEN_MULTICAST_BYTES_XMIT:
+ XENVIF_VIF(QueryStatistic,
+ &Adapter->VifInterface,
+ XENVIF_TRANSMITTER_MULTICAST_OCTETS,
+ &Value64);
+ BytesNeeded = sizeof(ULONG);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ (ULONG)Value64,
+ &BytesWritten);
+ break;
- if (!(Adapter->Properties.tcpv4_csum & 2))
- Default.Checksum.IPv4Receive.TcpChecksum = 0;
+ case OID_GEN_MULTICAST_FRAMES_XMIT:
+ XENVIF_VIF(QueryStatistic,
+ &Adapter->VifInterface,
+ XENVIF_TRANSMITTER_MULTICAST_PACKETS,
+ &Value64);
+ BytesNeeded = sizeof(ULONG);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ (ULONG)Value64,
+ &BytesWritten);
+ break;
- if (!(Adapter->Properties.udpv4_csum & 2))
- Default.Checksum.IPv4Receive.UdpChecksum = 0;
+ case OID_GEN_BROADCAST_BYTES_XMIT:
+ XENVIF_VIF(QueryStatistic,
+ &Adapter->VifInterface,
+ XENVIF_TRANSMITTER_BROADCAST_OCTETS,
+ &Value64);
+ BytesNeeded = sizeof(ULONG);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ (ULONG)Value64,
+ &BytesWritten);
+ break;
- if (!(Adapter->Properties.tcpv6_csum & 2))
- Default.Checksum.IPv6Receive.TcpChecksum = 0;
+ case OID_GEN_BROADCAST_FRAMES_XMIT:
+ XENVIF_VIF(QueryStatistic,
+ &Adapter->VifInterface,
+ XENVIF_TRANSMITTER_BROADCAST_PACKETS,
+ &Value64);
+ BytesNeeded = sizeof(ULONG);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ (ULONG)Value64,
+ &BytesWritten);
+ break;
- if (!(Adapter->Properties.udpv6_csum & 2))
- Default.Checksum.IPv6Receive.UdpChecksum = 0;
+ case OID_GEN_DIRECTED_BYTES_RCV:
+ XENVIF_VIF(QueryStatistic,
+ &Adapter->VifInterface,
+ XENVIF_RECEIVER_UNICAST_OCTETS,
+ &Value64);
+ BytesNeeded = sizeof(ULONG);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ (ULONG)Value64,
+ &BytesWritten);
+ break;
- if (!(Adapter->Properties.ipv4_csum & 1))
- Default.Checksum.IPv4Transmit.IpChecksum = 0;
+ case OID_GEN_DIRECTED_FRAMES_RCV:
+ XENVIF_VIF(QueryStatistic,
+ &Adapter->VifInterface,
+ XENVIF_RECEIVER_UNICAST_PACKETS,
+ &Value64);
+ BytesNeeded = sizeof(ULONG);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ (ULONG)Value64,
+ &BytesWritten);
+ break;
- if (!(Adapter->Properties.tcpv4_csum & 1))
- Default.Checksum.IPv4Transmit.TcpChecksum = 0;
+ case OID_GEN_MULTICAST_BYTES_RCV:
+ XENVIF_VIF(QueryStatistic,
+ &Adapter->VifInterface,
+ XENVIF_RECEIVER_MULTICAST_OCTETS,
+ &Value64);
+ BytesNeeded = sizeof(ULONG);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ (ULONG)Value64,
+ &BytesWritten);
+ break;
- if (!(Adapter->Properties.udpv4_csum & 1))
- Default.Checksum.IPv4Transmit.UdpChecksum = 0;
+ case OID_GEN_MULTICAST_FRAMES_RCV:
+ XENVIF_VIF(QueryStatistic,
+ &Adapter->VifInterface,
+ XENVIF_RECEIVER_MULTICAST_PACKETS,
+ &Value64);
+ BytesNeeded = sizeof(ULONG);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ (ULONG)Value64,
+ &BytesWritten);
+ break;
- if (!(Adapter->Properties.tcpv6_csum & 1))
- Default.Checksum.IPv6Transmit.TcpChecksum = 0;
+ case OID_GEN_BROADCAST_BYTES_RCV:
+ XENVIF_VIF(QueryStatistic,
+ &Adapter->VifInterface,
+ XENVIF_RECEIVER_BROADCAST_OCTETS,
+ &Value64);
+ BytesNeeded = sizeof(ULONG);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ (ULONG)Value64,
+ &BytesWritten);
+ break;
- if (!(Adapter->Properties.udpv6_csum & 1))
- Default.Checksum.IPv6Transmit.UdpChecksum = 0;
+ case OID_GEN_BROADCAST_FRAMES_RCV:
+ XENVIF_VIF(QueryStatistic,
+ &Adapter->VifInterface,
+ XENVIF_RECEIVER_BROADCAST_PACKETS,
+ &Value64);
+ BytesNeeded = sizeof(ULONG);
+ ndisStatus = __SetUlong(Buffer,
+ BufferLength,
+ (ULONG)Value64,
+ &BytesWritten);
+ break;
- if (!(Adapter->Properties.lsov4)) {
- Default.LsoV2.IPv4.MaxOffLoadSize = 0;
- Default.LsoV2.IPv4.MinSegmentCount = 0;
- }
+ case OID_GEN_INTERRUPT_MODERATION:
+ BytesNeeded = sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS);
+ ndisStatus = AdapterInterruptModeration(Adapter,
+ (PNDIS_INTERRUPT_MODERATION_PARAMETERS)Buffer,
+ BufferLength,
+ &BytesWritten);
+ break;
- if (!(Adapter->Properties.lsov6)) {
- Default.LsoV2.IPv6.MaxOffLoadSize = 0;
- Default.LsoV2.IPv6.MinSegmentCount = 0;
- }
+ 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:
+ // ignore these common unwanted OIDs
+ case OID_GEN_INIT_TIME_MS:
+ case OID_GEN_RESET_COUNTS:
+ case OID_GEN_MEDIA_SENSE_COUNTS:
+ Warn = FALSE;
+ /*FALLTHRU*/
+ default:
+ if (Warn)
+ Warning("UNSUPPORTED OID %08x\n", Request->DATA.QUERY_INFORMATION.Oid);
- if (!RtlEqualMemory(&Adapter->Offload, &Default, sizeof (NDIS_OFFLOAD))) {
- Adapter->Offload = Default;
- DISPLAY_OFFLOAD(Default);
+ ndisStatus = NDIS_STATUS_NOT_SUPPORTED;
+ break;
}
- 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;
+ Request->DATA.QUERY_INFORMATION.BytesWritten = BytesWritten;
+ Request->DATA.QUERY_INFORMATION.BytesNeeded = BytesNeeded;
- ndisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle,
- (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs);
return ndisStatus;
}
-static NDIS_STATUS
-AdapterSetHeaderDataSplitAttributes(
- IN PXENNET_ADAPTER Adapter
+static NTSTATUS
+__QueryInterface(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN const GUID *Guid,
+ IN ULONG Version,
+ OUT PINTERFACE Interface,
+ IN ULONG Size,
+ IN BOOLEAN Optional
)
{
- NDIS_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES Attribs;
- NDIS_HD_SPLIT_ATTRIBUTES Split;
- NDIS_STATUS NdisStatus;
-
- RtlZeroMemory(&Attribs, sizeof(Attribs));
+ KEVENT Event;
+ IO_STATUS_BLOCK StatusBlock;
+ PIRP Irp;
+ PIO_STACK_LOCATION StackLocation;
+ NTSTATUS status;
- Attribs.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES;
- Attribs.Header.Revision = NDIS_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES_REVISION_1;
- Attribs.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES_REVISION_1;
+ ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
- RtlZeroMemory(&Split, sizeof(Split));
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ RtlZeroMemory(&StatusBlock, sizeof(IO_STATUS_BLOCK));
- Split.Header.Type = NDIS_OBJECT_TYPE_HD_SPLIT_ATTRIBUTES;
- Split.Header.Revision = NDIS_HD_SPLIT_ATTRIBUTES_REVISION_1;
- Split.Header.Size = NDIS_SIZEOF_HD_SPLIT_ATTRIBUTES_REVISION_1;
- Split.HardwareCapabilities =
- NDIS_HD_SPLIT_CAPS_SUPPORTS_HEADER_DATA_SPLIT |
- NDIS_HD_SPLIT_CAPS_SUPPORTS_IPV4_OPTIONS |
- NDIS_HD_SPLIT_CAPS_SUPPORTS_IPV6_EXTENSION_HEADERS |
- NDIS_HD_SPLIT_CAPS_SUPPORTS_TCP_OPTIONS;
+ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
+ DeviceObject,
+ NULL,
+ 0,
+ NULL,
+ &Event,
+ &StatusBlock);
- if (Adapter->Properties.HeaderDataSplit != 0)
- Split.CurrentCapabilities = Split.HardwareCapabilities;
+ status = STATUS_UNSUCCESSFUL;
+ if (Irp == NULL)
+ goto fail1;
- Attribs.HDSplitAttributes = &Split;
+ StackLocation = IoGetNextIrpStackLocation(Irp);
+ StackLocation->MinorFunction = IRP_MN_QUERY_INTERFACE;
- NdisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle,
- (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs);
- if (NdisStatus != NDIS_STATUS_SUCCESS)
- goto fail1;
+ StackLocation->Parameters.QueryInterface.InterfaceType = Guid;
+ StackLocation->Parameters.QueryInterface.Size = (USHORT)Size;
+ StackLocation->Parameters.QueryInterface.Version = (USHORT)Version;
+ StackLocation->Parameters.QueryInterface.Interface = Interface;
- if (Split.HDSplitFlags == NDIS_HD_SPLIT_ENABLE_HEADER_DATA_SPLIT) {
- ASSERT(Split.CurrentCapabilities & NDIS_HD_SPLIT_CAPS_SUPPORTS_HEADER_DATA_SPLIT);
+ Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
- Info("BackfillSize = %u\n", Split.BackfillSize);
- Info("MaxHeaderSize = %u\n", Split.MaxHeaderSize);
+ status = IoCallDriver(DeviceObject, Irp);
+ if (status == STATUS_PENDING) {
+ (VOID) KeWaitForSingleObject(&Event,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ status = StatusBlock.Status;
+ }
- XENVIF_VIF(ReceiverSetBackfillSize,
- &Adapter->VifInterface,
- Split.BackfillSize);
+ if (!NT_SUCCESS(status)) {
+ if (status == STATUS_NOT_SUPPORTED && Optional)
+ goto done;
- ReceiverSplitHeaderData(Adapter->Receiver, Split.MaxHeaderSize);
+ goto fail2;
}
- return NDIS_STATUS_SUCCESS;
+done:
+ return STATUS_SUCCESS;
+
+fail2:
+ Error("fail2\n");
fail1:
- Error("fail1 (%08x)\n", NdisStatus);
+ Error("fail1 (%08x)\n", status);
- return NdisStatus;
+ return status;
}
-static FORCEINLINE PVOID
-__AdapterAllocate(
- IN ULONG Length
- )
-{
- return __AllocateNonPagedPoolWithTag(Length, ADAPTER_POOL_TAG);
-}
+#pragma prefast(push)
+#pragma prefast(disable:6102)
-static FORCEINLINE VOID
-__AdapterFree(
- IN PVOID Buffer
- )
-{
- __FreePoolWithTag(Buffer, ADAPTER_POOL_TAG);
-}
+#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 FORCEINLINE PANSI_STRING
-__AdapterMultiSzToUpcaseAnsi(
- IN PCHAR Buffer
+static NDIS_STATUS
+AdapterGetAdvancedSettings(
+ IN PXENNET_ADAPTER Adapter
)
{
- PANSI_STRING Ansi;
- LONG Index;
- LONG Count;
- NTSTATUS status;
-
- Index = 0;
- Count = 0;
- for (;;) {
- if (Buffer[Index] == '\0') {
- Count++;
- Index++;
-
- // Check for double NUL
- if (Buffer[Index] == '\0')
- break;
- } else {
- Buffer[Index] = (CHAR)toupper(Buffer[Index]);
- Index++;
- }
- }
+ NDIS_CONFIGURATION_OBJECT Config;
+ NDIS_HANDLE Handle;
+ NDIS_STATUS ndisStatus;
- Ansi = __AdapterAllocate(sizeof (ANSI_STRING) * (Count + 1));
+ 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;
- status = STATUS_NO_MEMORY;
- if (Ansi == NULL)
+ ndisStatus = NdisOpenConfigurationEx(&Config, &Handle);
+ if (ndisStatus != NDIS_STATUS_SUCCESS)
goto fail1;
- for (Index = 0; Index < Count; Index++) {
- ULONG Length;
-
- Length = (ULONG)strlen(Buffer);
- Ansi[Index].MaximumLength = (USHORT)(Length + 1);
- Ansi[Index].Buffer = __AdapterAllocate(Ansi[Index].MaximumLength);
-
- status = STATUS_NO_MEMORY;
- if (Ansi[Index].Buffer == NULL)
- goto fail2;
-
- RtlCopyMemory(Ansi[Index].Buffer, Buffer, Length);
- Ansi[Index].Length = (USHORT)Length;
-
- Buffer += Length + 1;
- }
-
- return Ansi;
-
-fail2:
- Error("fail2\n");
+ 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);
+ READ_PROPERTY(Adapter->Properties.HeaderDataSplit, L"*HeaderDataSplit", 1, Handle);
- while (--Index >= 0)
- __AdapterFree(Ansi[Index].Buffer);
+ NdisCloseConfiguration(Handle);
- __AdapterFree(Ansi);
+ return NDIS_STATUS_SUCCESS;
fail1:
- Error("fail1 (%08x)\n", status);
-
- return NULL;
+ return NDIS_STATUS_FAILURE;
}
-static FORCEINLINE VOID
-__AdapterFreeAnsi(
- IN PANSI_STRING Ansi
+#undef READ_PROPERTY
+
+#pragma prefast(pop)
+
+static NDIS_STATUS
+AdapterSetRegistrationAttributes(
+ IN PXENNET_ADAPTER Adapter
)
{
- ULONG Index;
+ 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;
- for (Index = 0; Ansi[Index].Buffer != NULL; Index++)
- __AdapterFree(Ansi[Index].Buffer);
+ ndisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle,
+ (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs);
- __AdapterFree(Ansi);
+ return ndisStatus;
}
-static FORCEINLINE BOOLEAN
-__AdapterMatchDistribution(
- IN PXENNET_ADAPTER Adapter,
- IN PCHAR Buffer
+static NDIS_STATUS
+AdapterSetGeneralAttributes(
+ IN PXENNET_ADAPTER Adapter
)
{
- PCHAR Vendor;
- PCHAR Product;
- PCHAR Context;
- const CHAR *Text;
- BOOLEAN Match;
- ULONG Index;
- NTSTATUS status;
+ NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES Attribs;
+ NDIS_STATUS ndisStatus;
- UNREFERENCED_PARAMETER(Adapter);
+ 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;
- status = STATUS_INVALID_PARAMETER;
+ XENVIF_VIF(MacQueryMaximumFrameSize,
+ &Adapter->VifInterface,
+ (PULONG)&Adapter->MaximumFrameSize);
- Vendor = __strtok_r(Buffer, " ", &Context);
- if (Vendor == NULL)
- goto fail1;
+ 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;
- Product = __strtok_r(NULL, " ", &Context);
- if (Product == NULL)
- goto fail2;
+ XENVIF_VIF(MacQueryPermanentAddress,
+ &Adapter->VifInterface,
+ (PETHERNET_ADDRESS)&Attribs.PermanentMacAddress);
+ XENVIF_VIF(MacQueryCurrentAddress,
+ &Adapter->VifInterface,
+ (PETHERNET_ADDRESS)&Attribs.CurrentMacAddress);
- Match = TRUE;
+ Attribs.PhysicalMediumType = NdisPhysicalMedium802_3;
+ Attribs.RecvScaleCapabilities = NULL;
+ Attribs.AccessType = NET_IF_ACCESS_BROADCAST;
+ Attribs.DirectionType = NET_IF_DIRECTION_SENDRECEIVE;
+ Attribs.ConnectionType = NET_IF_CONNECTION_DEDICATED;
+ Attribs.IfType = IF_TYPE_ETHERNET_CSMACD;
+ Attribs.IfConnectorPresent = TRUE;
+ Attribs.SupportedStatistics = NDIS_STATISTICS_XMIT_OK_SUPPORTED |
+ NDIS_STATISTICS_XMIT_ERROR_SUPPORTED |
+ NDIS_STATISTICS_DIRECTED_BYTES_XMIT_SUPPORTED |
+ NDIS_STATISTICS_DIRECTED_FRAMES_XMIT_SUPPORTED |
+ NDIS_STATISTICS_MULTICAST_BYTES_XMIT_SUPPORTED |
+ NDIS_STATISTICS_MULTICAST_FRAMES_XMIT_SUPPORTED |
+ NDIS_STATISTICS_BROADCAST_BYTES_XMIT_SUPPORTED |
+ NDIS_STATISTICS_BROADCAST_FRAMES_XMIT_SUPPORTED |
+ NDIS_STATISTICS_RCV_OK_SUPPORTED |
+ NDIS_STATISTICS_RCV_ERROR_SUPPORTED |
+ NDIS_STATISTICS_DIRECTED_BYTES_RCV_SUPPORTED |
+ NDIS_STATISTICS_DIRECTED_FRAMES_RCV_SUPPORTED |
+ NDIS_STATISTICS_MULTICAST_BYTES_RCV_SUPPORTED |
+ NDIS_STATISTICS_MULTICAST_FRAMES_RCV_SUPPORTED |
+ NDIS_STATISTICS_BROADCAST_BYTES_RCV_SUPPORTED |
+ NDIS_STATISTICS_BROADCAST_FRAMES_RCV_SUPPORTED |
+ NDIS_STATISTICS_GEN_STATISTICS_SUPPORTED;
+
+ Attribs.SupportedOidList = XennetSupportedOids;
+ Attribs.SupportedOidListLength = sizeof(XennetSupportedOids);
- Text = VENDOR_NAME_STR;
+ ndisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle,
+ (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs);
- for (Index = 0; Text[Index] != 0; Index++) {
- if (!isalnum((UCHAR)Text[Index])) {
- if (Vendor[Index] != '_') {
- Match = FALSE;
- break;
- }
- } else {
- if (Vendor[Index] != Text[Index]) {
- Match = FALSE;
- break;
- }
- }
- }
+ return ndisStatus;
+}
- Text = "XENNET";
+static NDIS_STATUS
+AdapterSetOffloadAttributes(
+ IN PXENNET_ADAPTER Adapter
+ )
+{
+ 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;
- if (_stricmp(Product, Text) != 0)
- Match = FALSE;
+ TxOptions = TransmitterOffloadOptions(Adapter->Transmitter);
+ RxOptions = ReceiverOffloadOptions(Adapter->Receiver);
- return Match;
+ TxOptions->Value = 0;
+ TxOptions->OffloadTagManipulation = 1;
-fail2:
- Error("fail2\n");
+ RxOptions->Value = 0;
+ RxOptions->OffloadTagManipulation = 1;
-fail1:
- Error("fail1 (%08x)\n", status);
+ if (Adapter->Properties.need_csum_value)
+ RxOptions->NeedChecksumValue = 1;
- return FALSE;
-}
+ if (Adapter->Properties.lrov4) {
+ RxOptions->OffloadIpVersion4LargePacket = 1;
+ RxOptions->NeedLargePacketSplit = 1;
+ }
-static FORCEINLINE VOID
-__AdapterClearDistribution(
- IN PXENNET_ADAPTER Adapter
- )
-{
- PCHAR Buffer;
- PANSI_STRING Distributions;
- ULONG Index;
- NTSTATUS status;
+ if (Adapter->Properties.lrov6) {
+ RxOptions->OffloadIpVersion6LargePacket = 1;
+ RxOptions->NeedLargePacketSplit = 1;
+ }
- Trace("====>\n");
+ XENVIF_VIF(ReceiverSetOffloadOptions,
+ &Adapter->VifInterface,
+ *RxOptions);
- status = XENBUS_STORE(Directory,
- &Adapter->StoreInterface,
- NULL,
- NULL,
- "drivers",
- &Buffer);
- if (NT_SUCCESS(status)) {
- Distributions = __AdapterMultiSzToUpcaseAnsi(Buffer);
+ XENVIF_VIF(TransmitterQueryOffloadOptions,
+ &Adapter->VifInterface,
+ &Options);
- XENBUS_STORE(Free,
- &Adapter->StoreInterface,
- Buffer);
- } else {
- Distributions = NULL;
- }
+ 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);
- if (Distributions == NULL)
- goto done;
+ Supported.Checksum.IPv4Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
- for (Index = 0; Distributions[Index].Buffer != NULL; Index++) {
- PANSI_STRING Distribution = &Distributions[Index];
+ Supported.Checksum.IPv4Receive.IpChecksum = 1;
+ Supported.Checksum.IPv4Receive.IpOptionsSupported = 1;
- status = XENBUS_STORE(Read,
- &Adapter->StoreInterface,
- NULL,
- "drivers",
- Distribution->Buffer,
- &Buffer);
- if (!NT_SUCCESS(status))
- continue;
+ Supported.Checksum.IPv4Receive.TcpChecksum = 1;
+ Supported.Checksum.IPv4Receive.TcpOptionsSupported = 1;
- if (__AdapterMatchDistribution(Adapter, Buffer))
- (VOID) XENBUS_STORE(Remove,
- &Adapter->StoreInterface,
- NULL,
- "drivers",
- Distribution->Buffer);
+ Supported.Checksum.IPv4Receive.UdpChecksum = 1;
- XENBUS_STORE(Free,
- &Adapter->StoreInterface,
- Buffer);
- }
+ Supported.Checksum.IPv6Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
- __AdapterFreeAnsi(Distributions);
+ Supported.Checksum.IPv6Receive.IpExtensionHeadersSupported = 1;
-done:
- Trace("<====\n");
-}
+ Supported.Checksum.IPv6Receive.TcpChecksum = 1;
+ Supported.Checksum.IPv6Receive.TcpOptionsSupported = 1;
-#define MAXIMUM_INDEX 255
+ Supported.Checksum.IPv6Receive.UdpChecksum = 1;
-static FORCEINLINE NTSTATUS
-__AdapterSetDistribution(
- IN PXENNET_ADAPTER Adapter
- )
-{
- ULONG Index;
- CHAR Distribution[MAXNAMELEN];
- CHAR Vendor[MAXNAMELEN];
- const CHAR *Product;
- NTSTATUS status;
+ Supported.Checksum.IPv4Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
- Trace("====>\n");
+ if (Options.OffloadIpVersion4HeaderChecksum) {
+ Supported.Checksum.IPv4Transmit.IpChecksum = 1;
+ Supported.Checksum.IPv4Transmit.IpOptionsSupported = 1;
+ }
- Index = 0;
- while (Index <= MAXIMUM_INDEX) {
- PCHAR Buffer;
+ if (Options.OffloadIpVersion4TcpChecksum) {
+ Supported.Checksum.IPv4Transmit.TcpChecksum = 1;
+ Supported.Checksum.IPv4Transmit.TcpOptionsSupported = 1;
+ }
- status = RtlStringCbPrintfA(Distribution,
- MAXNAMELEN,
- "%u",
- Index);
- ASSERT(NT_SUCCESS(status));
+ if (Options.OffloadIpVersion4UdpChecksum)
+ Supported.Checksum.IPv4Transmit.UdpChecksum = 1;
- status = XENBUS_STORE(Read,
- &Adapter->StoreInterface,
- NULL,
- "drivers",
- Distribution,
- &Buffer);
- if (!NT_SUCCESS(status)) {
- if (status == STATUS_OBJECT_NAME_NOT_FOUND)
- goto update;
+ Supported.Checksum.IPv6Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
+
+ Supported.Checksum.IPv6Transmit.IpExtensionHeadersSupported = 1;
- goto fail1;
- }
+ if (Options.OffloadIpVersion6TcpChecksum) {
+ Supported.Checksum.IPv6Transmit.TcpChecksum = 1;
+ Supported.Checksum.IPv6Transmit.TcpOptionsSupported = 1;
+ }
- XENBUS_STORE(Free,
- &Adapter->StoreInterface,
- Buffer);
+ if (Options.OffloadIpVersion6UdpChecksum)
+ Supported.Checksum.IPv6Transmit.UdpChecksum = 1;
- Index++;
+ if (Options.OffloadIpVersion4LargePacket) {
+ XENVIF_VIF(TransmitterQueryLargePacketSize,
+ &Adapter->VifInterface,
+ 4,
+ &Supported.LsoV2.IPv4.MaxOffLoadSize);
+ Supported.LsoV2.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
+ Supported.LsoV2.IPv4.MinSegmentCount = 2;
}
- status = STATUS_UNSUCCESSFUL;
- goto fail2;
+ if (Options.OffloadIpVersion6LargePacket) {
+ XENVIF_VIF(TransmitterQueryLargePacketSize,
+ &Adapter->VifInterface,
+ 6,
+ &Supported.LsoV2.IPv6.MaxOffLoadSize);
+ Supported.LsoV2.IPv6.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
+ Supported.LsoV2.IPv6.MinSegmentCount = 2;
+ Supported.LsoV2.IPv6.IpExtensionHeadersSupported = 1;
+ Supported.LsoV2.IPv6.TcpOptionsSupported = 1;
+ }
-update:
- status = RtlStringCbPrintfA(Vendor,
- MAXNAMELEN,
- "%s",
- VENDOR_NAME_STR);
- ASSERT(NT_SUCCESS(status));
+ Default = Supported;
- for (Index = 0; Vendor[Index] != '\0'; Index++)
- if (!isalnum((UCHAR)Vendor[Index]))
- Vendor[Index] = '_';
+ if (!(Adapter->Properties.ipv4_csum & 2))
+ Default.Checksum.IPv4Receive.IpChecksum = 0;
- Product = "XENNET";
+ if (!(Adapter->Properties.tcpv4_csum & 2))
+ Default.Checksum.IPv4Receive.TcpChecksum = 0;
-#if DBG
-#define ATTRIBUTES "(DEBUG)"
-#else
-#define ATTRIBUTES ""
-#endif
+ if (!(Adapter->Properties.udpv4_csum & 2))
+ Default.Checksum.IPv4Receive.UdpChecksum = 0;
- (VOID) XENBUS_STORE(Printf,
- &Adapter->StoreInterface,
- NULL,
- "drivers",
- Distribution,
- "%s %s %u.%u.%u %s",
- Vendor,
- Product,
- MAJOR_VERSION,
- MINOR_VERSION,
- MICRO_VERSION,
- ATTRIBUTES
- );
+ if (!(Adapter->Properties.tcpv6_csum & 2))
+ Default.Checksum.IPv6Receive.TcpChecksum = 0;
-#undef ATTRIBUTES
+ if (!(Adapter->Properties.udpv6_csum & 2))
+ Default.Checksum.IPv6Receive.UdpChecksum = 0;
- Trace("<====\n");
- return STATUS_SUCCESS;
+ if (!(Adapter->Properties.ipv4_csum & 1))
+ Default.Checksum.IPv4Transmit.IpChecksum = 0;
-fail2:
- Error("fail2\n");
+ if (!(Adapter->Properties.tcpv4_csum & 1))
+ Default.Checksum.IPv4Transmit.TcpChecksum = 0;
-fail1:
- Error("fail1 (%08x)\n", status);
+ if (!(Adapter->Properties.udpv4_csum & 1))
+ Default.Checksum.IPv4Transmit.UdpChecksum = 0;
- return status;
-}
+ if (!(Adapter->Properties.tcpv6_csum & 1))
+ Default.Checksum.IPv6Transmit.TcpChecksum = 0;
-static DECLSPEC_NOINLINE VOID
-AdapterSuspendCallbackLate(
- IN PVOID Argument
- )
-{
- PXENNET_ADAPTER Adapter = Argument;
+ if (!(Adapter->Properties.udpv6_csum & 1))
+ Default.Checksum.IPv6Transmit.UdpChecksum = 0;
- (VOID) __AdapterSetDistribution(Adapter);
-}
+ if (!(Adapter->Properties.lsov4)) {
+ Default.LsoV2.IPv4.MaxOffLoadSize = 0;
+ Default.LsoV2.IPv4.MinSegmentCount = 0;
+ }
-static NTSTATUS
-AdapterSetDistribution(
- IN PXENNET_ADAPTER Adapter
- )
-{
- LONG Count;
- NTSTATUS status;
+ if (!(Adapter->Properties.lsov6)) {
+ Default.LsoV2.IPv6.MaxOffLoadSize = 0;
+ Default.LsoV2.IPv6.MinSegmentCount = 0;
+ }
- Trace("====>\n");
+ if (!RtlEqualMemory(&Adapter->Offload, &Default, sizeof (NDIS_OFFLOAD))) {
+ Adapter->Offload = Default;
+ DISPLAY_OFFLOAD(Default);
+ }
- Count = InterlockedIncrement(&AdapterCount);
- ASSERT(Count != 0);
+ 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;
- if (Count != 1)
- goto done;
+ ndisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle,
+ (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs);
+ return ndisStatus;
+}
- status = __AdapterSetDistribution(Adapter);
- if (!NT_SUCCESS(status))
- goto fail1;
+static NDIS_STATUS
+AdapterSetHeaderDataSplitAttributes(
+ IN PXENNET_ADAPTER Adapter
+ )
+{
+ NDIS_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES Attribs;
+ NDIS_HD_SPLIT_ATTRIBUTES Split;
+ NDIS_STATUS NdisStatus;
- status = XENBUS_SUSPEND(Register,
- &Adapter->SuspendInterface,
- SUSPEND_CALLBACK_LATE,
- AdapterSuspendCallbackLate,
- Adapter,
- &Adapter->SuspendCallbackLate);
- if (!NT_SUCCESS(status))
- goto fail2;
+ RtlZeroMemory(&Attribs, sizeof(Attribs));
-done:
- Trace("<====\n");
- return STATUS_SUCCESS;
+ Attribs.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES;
+ Attribs.Header.Revision = NDIS_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES_REVISION_1;
+ Attribs.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES_REVISION_1;
-fail2:
- Error("fail2\n");
+ RtlZeroMemory(&Split, sizeof(Split));
- __AdapterClearDistribution(Adapter);
+ Split.Header.Type = NDIS_OBJECT_TYPE_HD_SPLIT_ATTRIBUTES;
+ Split.Header.Revision = NDIS_HD_SPLIT_ATTRIBUTES_REVISION_1;
+ Split.Header.Size = NDIS_SIZEOF_HD_SPLIT_ATTRIBUTES_REVISION_1;
+ Split.HardwareCapabilities =
+ NDIS_HD_SPLIT_CAPS_SUPPORTS_HEADER_DATA_SPLIT |
+ NDIS_HD_SPLIT_CAPS_SUPPORTS_IPV4_OPTIONS |
+ NDIS_HD_SPLIT_CAPS_SUPPORTS_IPV6_EXTENSION_HEADERS |
+ NDIS_HD_SPLIT_CAPS_SUPPORTS_TCP_OPTIONS;
-fail1:
- Error("fail1 (%08x)\n", status);
+ if (Adapter->Properties.HeaderDataSplit != 0)
+ Split.CurrentCapabilities = Split.HardwareCapabilities;
- return status;
-}
+ Attribs.HDSplitAttributes = &Split;
-static VOID
-AdapterClearDistribution(
- IN PXENNET_ADAPTER Adapter
- )
-{
- LONG Count;
+ NdisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle,
+ (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs);
+ if (NdisStatus != NDIS_STATUS_SUCCESS)
+ goto fail1;
- Trace("====>\n");
+ if (Split.HDSplitFlags == NDIS_HD_SPLIT_ENABLE_HEADER_DATA_SPLIT) {
+ ASSERT(Split.CurrentCapabilities & NDIS_HD_SPLIT_CAPS_SUPPORTS_HEADER_DATA_SPLIT);
- Count = InterlockedDecrement(&AdapterCount);
+ Info("BackfillSize = %u\n", Split.BackfillSize);
+ Info("MaxHeaderSize = %u\n", Split.MaxHeaderSize);
- if (Count != 0)
- goto done;
+ XENVIF_VIF(ReceiverSetBackfillSize,
+ &Adapter->VifInterface,
+ Split.BackfillSize);
- XENBUS_SUSPEND(Deregister,
- &Adapter->SuspendInterface,
- Adapter->SuspendCallbackLate);
- Adapter->SuspendCallbackLate = NULL;
+ ReceiverSplitHeaderData(Adapter->Receiver, Split.MaxHeaderSize);
+ }
- __AdapterClearDistribution(Adapter);
+ return NDIS_STATUS_SUCCESS;
-done:
- Trace("<====\n");
+fail1:
+ Error("fail1 (%08x)\n", NdisStatus);
+
+ return NdisStatus;
}
NDIS_STATUS
if (!NT_SUCCESS(status))
goto fail6;
- status = XENBUS_CACHE(Acquire,
- &(*Adapter)->CacheInterface);
- if (!NT_SUCCESS(status))
- goto fail7;
-
- status = XENBUS_STORE(Acquire,
- &(*Adapter)->StoreInterface);
- if (!NT_SUCCESS(status))
- goto fail8;
-
- status = XENBUS_SUSPEND(Acquire,
- &(*Adapter)->SuspendInterface);
- if (!NT_SUCCESS(status))
- goto fail9;
-
- (VOID) AdapterSetDistribution(*Adapter);
-
(*Adapter)->NdisAdapterHandle = Handle;
ndisStatus = TransmitterInitialize(*Adapter, &(*Adapter)->Transmitter);
if (ndisStatus != NDIS_STATUS_SUCCESS)
- goto fail10;
+ goto fail7;
ndisStatus = ReceiverInitialize(*Adapter, &(*Adapter)->Receiver);
if (ndisStatus != NDIS_STATUS_SUCCESS)
- goto fail11;
+ goto fail8;
ndisStatus = AdapterGetAdvancedSettings(*Adapter);
if (ndisStatus != NDIS_STATUS_SUCCESS)
- goto fail12;
+ goto fail9;
ndisStatus = AdapterSetRegistrationAttributes(*Adapter);
if (ndisStatus != NDIS_STATUS_SUCCESS)
- goto fail13;
+ goto fail10;
ndisStatus = AdapterSetGeneralAttributes(*Adapter);
if (ndisStatus != NDIS_STATUS_SUCCESS)
- goto fail14;
+ goto fail11;
ndisStatus = AdapterSetOffloadAttributes(*Adapter);
if (ndisStatus != NDIS_STATUS_SUCCESS)
- goto fail15;
+ goto fail12;
ndisStatus = AdapterSetHeaderDataSplitAttributes(*Adapter);
if (ndisStatus != NDIS_STATUS_SUCCESS)
- goto fail16;
+ goto fail13;
RtlZeroMemory(&Dma, sizeof(NDIS_SG_DMA_DESCRIPTION));
Dma.Header.Type = NDIS_OBJECT_TYPE_SG_DMA_DESCRIPTION;
if (ndisStatus != NDIS_STATUS_SUCCESS)
(*Adapter)->NdisDmaHandle = NULL;
- ndisStatus = AdapterEnable(*Adapter);
- if (ndisStatus != NDIS_STATUS_SUCCESS)
- goto fail17;
-
return NDIS_STATUS_SUCCESS;
-fail17:
- if ((*Adapter)->NdisDmaHandle)
- NdisMDeregisterScatterGatherDma((*Adapter)->NdisDmaHandle);
- (*Adapter)->NdisDmaHandle = NULL;
-
-fail16:
-fail15:
-fail14:
fail13:
fail12:
+fail11:
+fail10:
+fail9:
ReceiverTeardown((*Adapter)->Receiver);
(*Adapter)->Receiver = NULL;
-fail11:
+fail8:
TransmitterTeardown((*Adapter)->Transmitter);
(*Adapter)->Transmitter = NULL;
-fail10:
+fail7:
(*Adapter)->NdisAdapterHandle = NULL;
- AdapterClearDistribution(*Adapter);
-
- XENBUS_SUSPEND(Release, &(*Adapter)->SuspendInterface);
-
-fail9:
- XENBUS_STORE(Release, &(*Adapter)->StoreInterface);
-
-fail8:
- XENBUS_CACHE(Release, &(*Adapter)->CacheInterface);
-
-fail7:
XENVIF_VIF(Release, &(*Adapter)->VifInterface);
fail6:
AdapterClearDistribution(Adapter);
- XENBUS_SUSPEND(Release, &Adapter->SuspendInterface);
- XENBUS_STORE(Release, &Adapter->StoreInterface);
- XENBUS_CACHE(Release, &Adapter->CacheInterface);
XENVIF_VIF(Release, &Adapter->VifInterface);
RtlZeroMemory(&Adapter->SuspendInterface, sizeof(XENBUS_SUSPEND_INTERFACE));