summaryrefslogtreecommitdiff
path: root/network/wwan/cxwmbclass/adapter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'network/wwan/cxwmbclass/adapter.cpp')
-rw-r--r--network/wwan/cxwmbclass/adapter.cpp197
1 files changed, 197 insertions, 0 deletions
diff --git a/network/wwan/cxwmbclass/adapter.cpp b/network/wwan/cxwmbclass/adapter.cpp
new file mode 100644
index 00000000..ed60b427
--- /dev/null
+++ b/network/wwan/cxwmbclass/adapter.cpp
@@ -0,0 +1,197 @@
+//
+// Copyright (C) Microsoft. All rights reserved.
+//
+
+#include "precomp.h"
+
+#include "device.h"
+#include "txqueue.h"
+#include "rxqueue.h"
+
+_Use_decl_annotations_ NTSTATUS WmbClassAdapterStart(NETADAPTER netAdapter)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ PWMBCLASS_NETADAPTER_CONTEXT netAdapterContext = WmbClassGetNetAdapterContext(netAdapter);
+ PWMBCLASS_DEVICE_CONTEXT deviceContext = netAdapterContext->WmbDeviceContext;
+
+ ULONG64 maxXmitLinkSpeed = MBB_MEDIA_MAX_SPEED;
+ ULONG64 maxRcvLinkSpeed = MBB_MEDIA_MAX_SPEED;
+ DWORD maxPowerFilterSize = 0;
+
+ NET_ADAPTER_LINK_LAYER_CAPABILITIES linkLayerCapabilities;
+ NET_ADAPTER_LINK_LAYER_CAPABILITIES_INIT(&linkLayerCapabilities, maxXmitLinkSpeed, maxRcvLinkSpeed);
+
+ NetAdapterSetLinkLayerCapabilities(netAdapter, &linkLayerCapabilities);
+
+ if (deviceContext->BusParams.IsErrataDevice)
+ {
+ NetAdapterSetLinkLayerMtuSize(netAdapter, deviceContext->BusParams.MTU);
+ }
+ else
+ {
+ NetAdapterSetLinkLayerMtuSize(netAdapter, deviceContext->BusParams.MaxSegmentSize);
+ }
+
+ if (deviceContext->BusParams.PowerFiltersSupported > 0)
+ {
+ NET_ADAPTER_WAKE_BITMAP_CAPABILITIES bitmapCapabilities;
+ NET_ADAPTER_WAKE_BITMAP_CAPABILITIES_INIT(&bitmapCapabilities);
+
+ bitmapCapabilities.BitmapPattern = TRUE;
+ bitmapCapabilities.MaximumPatternCount = deviceContext->BusParams.PowerFiltersSupported;
+
+ if (deviceContext->BusParams.IsErrataDevice)
+ {
+ // For errata devices we will report the device specific max pattern size.
+ // 192 bytes is the maximum power filter size as per the MBIM spec.
+ // If a device reports more than 192 bytes as the power filter size, we
+ // normalize it here to 192 bytes. This will prevent erroneous devices
+ // from indicating arbitrary pattern size. This needs to change with any
+ // MBIM spec revision.
+
+ if (deviceContext->BusParams.MaxPowerFilterSize > WMBCLASS_MAX_MBIM_WOL_PATTERN)
+ {
+ maxPowerFilterSize = WMBCLASS_MAX_MBIM_WOL_PATTERN;
+ }
+ else
+ {
+ maxPowerFilterSize = deviceContext->BusParams.MaxPowerFilterSize;
+ }
+ }
+ else
+ {
+ // To maintain backward compatibility with Win8 devices, we continue
+ // reporting 256 bytes as the wake pattern size.
+ maxPowerFilterSize = WMBCLASS_MAX_WOL_PATTERN;
+ }
+
+ bitmapCapabilities.MaximumPatternSize = maxPowerFilterSize;
+
+ NetAdapterWakeSetBitmapCapabilities(netAdapter, &bitmapCapabilities);
+ }
+
+ NET_ADAPTER_WAKE_MEDIA_CHANGE_CAPABILITIES wakeMediaChangeCapabilities;
+ NET_ADAPTER_WAKE_MEDIA_CHANGE_CAPABILITIES_INIT(&wakeMediaChangeCapabilities);
+
+ wakeMediaChangeCapabilities.MediaConnect = TRUE;
+ wakeMediaChangeCapabilities.MediaDisconnect = TRUE;
+
+ NetAdapterWakeSetMediaChangeCapabilities(netAdapter, &wakeMediaChangeCapabilities);
+
+ if (deviceContext->BusParams.SelectiveSuspendSupported)
+ {
+ NET_ADAPTER_WAKE_PACKET_FILTER_CAPABILITIES wakePacketFilterCapabilities;
+ NET_ADAPTER_WAKE_PACKET_FILTER_CAPABILITIES_INIT(&wakePacketFilterCapabilities);
+ wakePacketFilterCapabilities.PacketFilterMatch = TRUE;
+
+ NetAdapterWakeSetPacketFilterCapabilities(netAdapter, &wakePacketFilterCapabilities);
+ }
+
+ NET_ADAPTER_TX_CAPABILITIES txCapabilities;
+ NET_ADAPTER_TX_CAPABILITIES_INIT(&txCapabilities, 1);
+ NET_ADAPTER_RX_CAPABILITIES rxCapabilities;
+ NET_ADAPTER_RX_CAPABILITIES_INIT_DRIVER_MANAGED(&rxCapabilities, EvtAdapterReturnRxBuffer, MBB_MAX_PACKET_SIZE, 1);
+
+ NetAdapterSetDataPathCapabilities(netAdapter, &txCapabilities, &rxCapabilities);
+
+ status = NetAdapterStart(netAdapter);
+
+ return status;
+}
+
+NTSTATUS
+EvtAdapterCreateTxQueue(_In_ NETADAPTER netAdapter, _Inout_ NETTXQUEUE_INIT* txQueueInit)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ PMBB_TXQUEUE_CONTEXT txQueueContext = NULL;
+ PWMBCLASS_NETADAPTER_CONTEXT netAdapterContext = WmbClassGetNetAdapterContext(netAdapter);
+ PWMBCLASS_DEVICE_CONTEXT deviceContext = netAdapterContext->WmbDeviceContext;
+ WDF_OBJECT_ATTRIBUTES txAttributes;
+ NET_EXTENSION_QUERY extension;
+
+ WDF_OBJECT_ATTRIBUTES_INIT(&txAttributes);
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&txAttributes, MBB_TXQUEUE_CONTEXT);
+
+ txAttributes.EvtDestroyCallback = EvtTxQueueDestroy;
+
+ NET_PACKET_QUEUE_CONFIG queueConfig;
+ NET_PACKET_QUEUE_CONFIG_INIT(&queueConfig, EvtTxQueueAdvance, EvtTxQueueSetNotificationEnabled, EvtTxQueueCancel);
+
+ NETPACKETQUEUE txQueue;
+ status = NetTxQueueCreate(txQueueInit, &txAttributes, &queueConfig, &txQueue);
+
+ if (!NT_SUCCESS(status))
+ {
+ goto Exit;
+ }
+
+ txQueueContext = MbbGetTxQueueContext(txQueue);
+
+
+ txQueueContext->NetAdapterContext = netAdapterContext;
+ txQueueContext->DatapathDescriptor = NetTxQueueGetRingCollection(txQueue);
+
+ // Try to use MaxOutDatagrams parameter as the tx completion batch size, but limit to half of the packet ring buffer
+ auto maxBatchSize = NetRingCollectionGetPacketRing(txQueueContext->DatapathDescriptor)->NumberOfElements / 2;
+ txQueueContext->CompletionBatchSize = min(deviceContext->BusParams.MaxOutDatagrams, maxBatchSize);
+
+ NET_EXTENSION_QUERY_INIT(&extension, NET_FRAGMENT_EXTENSION_MDL_NAME, NET_FRAGMENT_EXTENSION_MDL_VERSION_1, NetExtensionTypeFragment);
+
+ NetTxQueueGetExtension(txQueue, &extension, &txQueueContext->MdlExtension);
+
+ netAdapterContext->TxQueue = txQueue;
+Exit:
+ return status;
+}
+
+void EvtRxQueueStart(_In_ NETPACKETQUEUE rxQueue)
+{
+ MbbGetRxQueueContext(rxQueue)->NetAdapterContext->AllowRxTraffic = TRUE;
+}
+
+NTSTATUS
+EvtAdapterCreateRxQueue(_In_ NETADAPTER netAdapter, _Inout_ NETRXQUEUE_INIT* rxQueueInit)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+
+ PMBB_RXQUEUE_CONTEXT rxQueueContext = NULL;
+ WDF_OBJECT_ATTRIBUTES rxAttributes;
+ NET_EXTENSION_QUERY extension;
+ PWMBCLASS_NETADAPTER_CONTEXT netAdapterContext = WmbClassGetNetAdapterContext(netAdapter);
+
+ NET_PACKET_QUEUE_CONFIG rxConfig;
+ NET_PACKET_QUEUE_CONFIG_INIT(&rxConfig, EvtRxQueueAdvance, EvtRxQueueSetNotificationEnabled, EvtRxQueueCancel);
+ rxConfig.EvtStart = EvtRxQueueStart;
+
+ WDF_OBJECT_ATTRIBUTES_INIT(&rxAttributes);
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&rxAttributes, MBB_RXQUEUE_CONTEXT);
+ rxAttributes.EvtDestroyCallback = EvtRxQueueDestroy;
+
+ NETPACKETQUEUE rxQueue;
+ status = NetRxQueueCreate(rxQueueInit, &rxAttributes, &rxConfig, &rxQueue);
+
+ if (!NT_SUCCESS(status))
+ {
+ goto Exit;
+ }
+
+ rxQueueContext = MbbGetRxQueueContext(rxQueue);
+
+ NET_EXTENSION_QUERY_INIT(&extension, NET_FRAGMENT_EXTENSION_VIRTUAL_ADDRESS_NAME, NET_FRAGMENT_EXTENSION_VIRTUAL_ADDRESS_VERSION_1, NetExtensionTypeFragment);
+
+ NetRxQueueGetExtension(rxQueue, &extension, &rxQueueContext->VirtualAddressExtension);
+
+ rxQueueContext->NetAdapterContext = netAdapterContext;
+ rxQueueContext->DatapathDescriptor = NetRxQueueGetRingCollection(rxQueue);
+
+ NET_EXTENSION_QUERY_INIT(&extension, NET_FRAGMENT_EXTENSION_RETURN_CONTEXT_NAME, NET_FRAGMENT_EXTENSION_RETURN_CONTEXT_VERSION_1, NetExtensionTypeFragment);
+
+ NetRxQueueGetExtension(rxQueue, &extension, &rxQueueContext->ReturnContextExtension);
+
+ // Set netAdapterContext->RxQueue to mean EvtAdapterCreateRxQueue completed successfully
+ netAdapterContext->RxQueue = rxQueue;
+
+Exit:
+
+ return status;
+}