diff options
Diffstat (limited to 'network/wwan/cxwmbclass/adapter.cpp')
| -rw-r--r-- | network/wwan/cxwmbclass/adapter.cpp | 197 |
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; +} |
