diff options
| author | Adonais Romero González <[email protected]> | 2024-05-06 16:21:31 -0700 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-05-06 16:21:31 -0700 |
| commit | a74a241c664c4e1d7c0838287b34076c19d9858a (patch) | |
| tree | 6ff7562612967b122acf8acf8a69c4dcfd5905db /network/wwan/cxwmbclass/rxqueue.cpp | |
| parent | def8e8e34ed2b7b1deb2fc9112ac4255f1a0f2ba (diff) | |
| parent | 15477ce52bbb6b42ca591ecdfb484cac089f89ab (diff) | |
Merge develop changes prior to upcoming WDK release (May 2024)
Diffstat (limited to 'network/wwan/cxwmbclass/rxqueue.cpp')
| -rw-r--r-- | network/wwan/cxwmbclass/rxqueue.cpp | 602 |
1 files changed, 602 insertions, 0 deletions
diff --git a/network/wwan/cxwmbclass/rxqueue.cpp b/network/wwan/cxwmbclass/rxqueue.cpp new file mode 100644 index 00000000..836201a5 --- /dev/null +++ b/network/wwan/cxwmbclass/rxqueue.cpp @@ -0,0 +1,602 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// + +#include "precomp.h" + +#include "device.h" +#include "rxqueue.h" + +#define MBB_NTH_GET_FIRST_NDP_OFFSET(IS32BIT, NTH) \ + ((IS32BIT) ? MBB_NTH32_GET_FIRST_NDP_OFFSET((PNCM_NTH32)NTH) : MBB_NTH16_GET_FIRST_NDP_OFFSET((PNCM_NTH16)NTH)) + +void MbbNotifyRxReady(_In_ NETPACKETQUEUE RxQueue) +{ + PMBB_RXQUEUE_CONTEXT rxQueueContext = MbbGetRxQueueContext(RxQueue); + if (InterlockedExchange(&rxQueueContext->NotificationEnabled, FALSE) == TRUE) + { + NetRxQueueNotifyMoreReceivedPacketsAvailable(RxQueue); + } +} + +VOID MbbRecvCleanup(_In_ PMBB_NDIS_RECEIVE_CONTEXT Receive) +{ + MbbBusReturnReceiveBuffer(Receive->BusHandle, Receive->BusContext, Receive->Mdl); + + WdfObjectDelete(Receive->ReceiveLookasideBufferMemory); +} + +VOID MbbRecvReturnNdp(_In_ PMBB_NDIS_RECEIVE_CONTEXT ReceiveContext, _In_opt_ PMBB_RECEIVE_NDP_CONTEXT ReceiveNdpContext) +{ + LONG newCompletedCount = InterlockedIncrement(&ReceiveContext->CompletedNdpCount); + if (newCompletedCount == ReceiveContext->TotalNdpCount) + { + MbbRecvCleanup(ReceiveContext); + } + if (ReceiveNdpContext != NULL) + { + WdfObjectDelete(ReceiveNdpContext->ReceiveNdpLookasideBufferMemory); + } +} + +_Use_decl_annotations_ VOID MbbRecvCancelNdps(PWMBCLASS_DEVICE_CONTEXT DeviceContext, ULONG SessionId) +{ + LIST_ENTRY tempList; + PLIST_ENTRY listEntry; + PLIST_ENTRY nextEntry; + PMBB_RECEIVE_NDP_CONTEXT receiveNdpContext = NULL; + PWMBCLASS_NETADAPTER_CONTEXT netAdapterContext = DeviceContext->Sessions[SessionId].NetAdapterContext; + + InitializeListHead(&tempList); + + WdfSpinLockAcquire(DeviceContext->Sessions[SessionId].WdfRecvSpinLock); + InsertHeadList(&netAdapterContext->ReceiveNdpList, &tempList); + RemoveEntryList(&netAdapterContext->ReceiveNdpList); + InitializeListHead(&netAdapterContext->ReceiveNdpList); + // Cannot cache the received Ndps anymore + netAdapterContext->AllowRxTraffic = FALSE; + WdfSpinLockRelease(DeviceContext->Sessions[SessionId].WdfRecvSpinLock); + + for (listEntry = tempList.Flink; listEntry != &tempList; listEntry = nextEntry) + { + nextEntry = listEntry->Flink; + receiveNdpContext = CONTAINING_RECORD(listEntry, MBB_RECEIVE_NDP_CONTEXT, ReceiveNdpNode); + MbbRecvReturnNdp(receiveNdpContext->ReceiveContext, receiveNdpContext); + } +} + +void MbbReceiveDssData(__in PWMBCLASS_DEVICE_CONTEXT DeviceContext, __in ULONG SessionId, __in_bcount_opt(InBufferSize) PUCHAR InBuffer, __in ULONG InBufferSize) +{ + NTSTATUS status; + WDFMEMORY data; + + status = WdfMemoryCreatePreallocated(WDF_NO_OBJECT_ATTRIBUTES, InBuffer, InBufferSize, &data); + + if (NT_SUCCESS(status)) + { + DeviceContext->DSSPacketsReceivedCount++; + + MbbDeviceReceiveDeviceServiceSessionData(DeviceContext->WdfDevice, SessionId, data); + WdfObjectDelete(data); + } +} + +NTSTATUS +MbbRecvNdpUnpackDss32(_In_ PMBB_NDIS_RECEIVE_CONTEXT ReceiveContext, _In_ PNCM_NTH32 Nth, _In_ PNCM_NDP32 Ndp) +{ + UNREFERENCED_PARAMETER(Nth); + NTSTATUS status = STATUS_SUCCESS; + ULONG datagramCount = MBB_NDP32_GET_DATAGRAM_COUNT(Ndp); + ULONG sessionId = MBB_NDP32_GET_SESSIONID(Ndp); + for (ULONG index = 0; index < datagramCount; index++) + { + if (MBB_NTB32_IS_END_DATAGRAM(Nth, Ndp, index)) + break; + + // Forward to the dss receive handler + MbbReceiveDssData( + ReceiveContext->WmbDeviceContext, sessionId, (PUCHAR)MBB_NDP32_GET_DATAGRAM(Nth, Ndp, index), MBB_NDP32_GET_DATAGRAM_LENGTH(Ndp, index)); + } + + MbbRecvReturnNdp(ReceiveContext, NULL); + return status; +} + +NTSTATUS +MbbRecvNdpUnpackDss16(_In_ PMBB_NDIS_RECEIVE_CONTEXT ReceiveContext, _In_ PNCM_NTH16 Nth, _In_ PNCM_NDP16 Ndp) +{ + UNREFERENCED_PARAMETER(Nth); + NTSTATUS status = STATUS_SUCCESS; + ULONG datagramCount = MBB_NDP16_GET_DATAGRAM_COUNT(Ndp); + ULONG sessionId = MBB_NDP16_GET_SESSIONID(Ndp); + for (ULONG index = 0; index < datagramCount; index++) + { + if (MBB_NTB16_IS_END_DATAGRAM(Nth, Ndp, index)) + break; + + // Forward to the dss receive handler + MbbReceiveDssData( + ReceiveContext->WmbDeviceContext, sessionId, (PUCHAR)MBB_NDP16_GET_DATAGRAM(Nth, Ndp, index), MBB_NDP16_GET_DATAGRAM_LENGTH(Ndp, index)); + } + MbbRecvReturnNdp(ReceiveContext, NULL); + return status; +} + +NTSTATUS +MbbRecvAddNdp(_In_ PMBB_NDIS_RECEIVE_CONTEXT ReceiveContext, _In_ PVOID Nth, _In_ PVOID Ndp, _In_ ULONG SessionId) +{ + NTSTATUS status = STATUS_SUCCESS; + PWMBCLASS_DEVICE_CONTEXT deviceContext = ReceiveContext->WmbDeviceContext; + PWMBCLASS_NETADAPTER_CONTEXT netAdapterContext = NULL; + WDFMEMORY ndpContextMemory; + PMBB_RECEIVE_NDP_CONTEXT ndpContext = NULL; + size_t ndpContextSize; + BOOLEAN returnNdp = FALSE; + + WdfSpinLockAcquire(deviceContext->Sessions[SessionId].WdfRecvSpinLock); + do + { + netAdapterContext = deviceContext->Sessions[SessionId].NetAdapterContext; + if (netAdapterContext == NULL) + { + returnNdp = TRUE; + break; + } + + if (!NT_SUCCESS(status = WdfMemoryCreateFromLookaside(netAdapterContext->ReceiveNdpLookasideList, &ndpContextMemory))) + { + returnNdp = TRUE; + break; + } + + ndpContext = (PMBB_RECEIVE_NDP_CONTEXT)WdfMemoryGetBuffer(ndpContextMemory, &ndpContextSize); + RtlZeroMemory(ndpContext, ndpContextSize); + ndpContext->Nth = Nth; + ndpContext->Ndp = Ndp; + ndpContext->ReceiveContext = ReceiveContext; + ndpContext->ReceiveNdpLookasideBufferMemory = ndpContextMemory; + ndpContext->NetAdapterContext = netAdapterContext; + if (netAdapterContext->AllowRxTraffic) + { + InsertTailList(&netAdapterContext->ReceiveNdpList, &ndpContext->ReceiveNdpNode); + } + else + { + returnNdp = TRUE; + break; + } + + // If RxQueueCreate hasn't completed yet, we only queue the received Ndp and don't need notify RxReady + if (netAdapterContext->RxQueue) + { + MbbNotifyRxReady(netAdapterContext->RxQueue); + } + } while (FALSE); + WdfSpinLockRelease(deviceContext->Sessions[SessionId].WdfRecvSpinLock); + + if (returnNdp) + { + MbbRecvReturnNdp(ReceiveContext, ndpContext); + } + return status; +} + +VOID MbbRecvNtbParse(_In_ PMBB_NDIS_RECEIVE_CONTEXT ReceiveContext) +{ + NTSTATUS status = STATUS_SUCCESS; + PNCM_NTH32 nth32; + PNCM_NTH16 nth16; + PNCM_NDP32 ndp32; + PNCM_NDP16 ndp16; + PVOID nth = ReceiveContext->ReceiveNtbBuffer; + + if (MBB_NTB_IS_32BIT(nth)) + { + nth32 = (PNCM_NTH32)nth; + for (ndp32 = MBB_NTH32_GET_FIRST_NDP(nth32); ndp32 != NULL; ndp32 = MBB_NDP32_GET_NEXT_NDP(nth32, ndp32)) + { + if (MBB_NDP32_GET_SIGNATURE_TYPE(ndp32) == NCM_NDP32_VENDOR) + { + status = MbbRecvNdpUnpackDss32(ReceiveContext, nth32, ndp32); + if (!NT_SUCCESS(status)) + { + } + } + else if (MBB_NDP32_GET_SIGNATURE_TYPE(ndp32) == NCM_NDP32_IPS) + { + status = MbbRecvAddNdp(ReceiveContext, nth32, ndp32, MBB_NDP32_GET_SESSIONID(ndp32)); + if (!NT_SUCCESS(status)) + { + } + } + else + { + MbbRecvReturnNdp(ReceiveContext, NULL); + } + } + } + else if (MBB_NTB_IS_16BIT(nth)) + { + nth16 = (PNCM_NTH16)nth; + for (ndp16 = MBB_NTH16_GET_FIRST_NDP(nth16); ndp16 != NULL; ndp16 = MBB_NDP16_GET_NEXT_NDP(nth16, ndp16)) + { + if (MBB_NDP16_GET_SIGNATURE_TYPE(ndp16) == NCM_NDP16_VENDOR) + { + status = MbbRecvNdpUnpackDss16(ReceiveContext, nth16, ndp16); + if (!NT_SUCCESS(status)) + { + } + } + else if (MBB_NDP16_GET_SIGNATURE_TYPE(ndp16) == NCM_NDP16_IPS) + { + status = MbbRecvAddNdp(ReceiveContext, nth16, ndp16, MBB_NDP32_GET_SESSIONID(ndp16)); + if (!NT_SUCCESS(status)) + { + } + } + else + { + MbbRecvReturnNdp(ReceiveContext, NULL); + } + } + } +} + +NTSTATUS +MbbRecvNtbUnpackIpNdp32(_In_ PMBB_RECEIVE_NDP_CONTEXT ReceiveNdpContext, _In_ PNCM_NTH32 Nth32, _In_ PNCM_NDP32 Ndp32, _Inout_ ULONG* IncompletedDatagramIndex, _In_ PMBB_RXQUEUE_CONTEXT RxQueueContext) +{ + PCHAR incompletedDatagram; + ULONG incompletedDatagramLength; + NET_PACKET* packet; + NET_FRAGMENT* fragment; + NET_FRAGMENT_RETURN_CONTEXT* returnContext; + NET_FRAGMENT_VIRTUAL_ADDRESS* virtualAddress; + NTSTATUS status = STATUS_SUCCESS; + ULONG datagramCount = MBB_NDP32_GET_DATAGRAM_COUNT(Ndp32); + + NET_RING * pr = NetRingCollectionGetPacketRing(RxQueueContext->DatapathDescriptor); + NET_RING * fr = NetRingCollectionGetFragmentRing(RxQueueContext->DatapathDescriptor); + + while ((incompletedDatagram = MBB_NDP32_GET_DATAGRAM(Nth32, Ndp32, *IncompletedDatagramIndex)) != NULL) + { + if (*IncompletedDatagramIndex >= datagramCount) + { + break; + } + + if (fr->BeginIndex == fr->EndIndex) + { + status = STATUS_BUFFER_OVERFLOW; + break; + } + + incompletedDatagramLength = MBB_NDP32_GET_DATAGRAM_LENGTH(Ndp32, *IncompletedDatagramIndex); + + UINT32 const fragmentIndex = fr->BeginIndex; + fragment = NetRingGetFragmentAtIndex(fr, fragmentIndex); + fragment->Capacity = incompletedDatagramLength; + fragment->ValidLength = incompletedDatagramLength; + fragment->Offset = 0; + + returnContext = NetExtensionGetFragmentReturnContext(&RxQueueContext->ReturnContextExtension, fragmentIndex); + virtualAddress = + NetExtensionGetFragmentVirtualAddress(&RxQueueContext->VirtualAddressExtension, fragmentIndex); + + + returnContext->Handle = (NET_FRAGMENT_RETURN_CONTEXT_HANDLE)ReceiveNdpContext; + virtualAddress->VirtualAddress = incompletedDatagram; + + (ReceiveNdpContext->IndicatedPackets)++; + (*IncompletedDatagramIndex)++; + + UINT32 const packetIndex = pr->BeginIndex; + packet = NetRingGetPacketAtIndex(pr, packetIndex); + packet->FragmentIndex = fragmentIndex; + packet->FragmentCount = 1; + packet->Layout = {}; + + pr->BeginIndex = NetRingIncrementIndex(pr, pr->BeginIndex); + fr->BeginIndex = NetRingIncrementIndex(fr, fr->BeginIndex); + } + return status; +} + +NTSTATUS +MbbRecvNtbUnpackIpNdp16(_In_ PMBB_RECEIVE_NDP_CONTEXT ReceiveNdpContext, _In_ PNCM_NTH16 Nth16, _In_ PNCM_NDP16 Ndp16, _Inout_ ULONG* IncompletedDatagramIndex, _In_ PMBB_RXQUEUE_CONTEXT RxQueueContext) +{ + PCHAR incompletedDatagram; + ULONG incompletedDatagramLength; + NET_PACKET* packet; + NET_FRAGMENT* fragment; + NET_FRAGMENT_RETURN_CONTEXT* returnContext; + NET_FRAGMENT_VIRTUAL_ADDRESS* virtualAddress; + NTSTATUS status = STATUS_SUCCESS; + ULONG datagramCount = MBB_NDP16_GET_DATAGRAM_COUNT(Ndp16); + + NET_RING * pr = NetRingCollectionGetPacketRing(RxQueueContext->DatapathDescriptor); + NET_RING * fr = NetRingCollectionGetFragmentRing(RxQueueContext->DatapathDescriptor); + + while ((incompletedDatagram = MBB_NDP16_GET_DATAGRAM(Nth16, Ndp16, *IncompletedDatagramIndex)) != NULL) + { + if (*IncompletedDatagramIndex >= datagramCount) + { + break; + } + + if (fr->BeginIndex == fr->EndIndex) + { + status = STATUS_BUFFER_OVERFLOW; + break; + } + + incompletedDatagramLength = MBB_NDP16_GET_DATAGRAM_LENGTH(Ndp16, *IncompletedDatagramIndex); + + UINT32 const fragmentIndex = fr->BeginIndex; + fragment = NetRingGetFragmentAtIndex(fr, fragmentIndex); + fragment->Capacity = incompletedDatagramLength; + fragment->ValidLength = incompletedDatagramLength; + fragment->Offset = 0; + + returnContext = NetExtensionGetFragmentReturnContext(&RxQueueContext->ReturnContextExtension, fragmentIndex); + virtualAddress = + NetExtensionGetFragmentVirtualAddress(&RxQueueContext->VirtualAddressExtension, fragmentIndex); + + returnContext->Handle = (NET_FRAGMENT_RETURN_CONTEXT_HANDLE)ReceiveNdpContext; + virtualAddress->VirtualAddress = incompletedDatagram; + + (ReceiveNdpContext->IndicatedPackets)++; + (*IncompletedDatagramIndex)++; + + UINT32 const packetIndex = pr->BeginIndex; + packet = NetRingGetPacketAtIndex(pr, packetIndex); + packet->FragmentIndex = fragmentIndex; + packet->FragmentCount = 1; + packet->Layout = {}; + + pr->BeginIndex = NetRingIncrementIndex(pr, pr->BeginIndex); + fr->BeginIndex = NetRingIncrementIndex(fr, fr->BeginIndex); + } + + return status; +} + +NTSTATUS +MbbRecvNdpUnpackIps(_In_ PMBB_RECEIVE_NDP_CONTEXT ReceiveNdpContext, _In_ PMBB_RXQUEUE_CONTEXT RxQueueContext) +{ + NTSTATUS status = STATUS_SUCCESS; + PNCM_NTH32 nth32; + PNCM_NTH16 nth16; + PNCM_NDP32 ndp32; + PNCM_NDP16 ndp16; + PMBB_NDIS_RECEIVE_CONTEXT receiveContext = ReceiveNdpContext->ReceiveContext; + PVOID nth = receiveContext->ReceiveNtbBuffer; + + if (MBB_NTB_IS_32BIT(nth)) + { + nth32 = (PNCM_NTH32)nth; + ndp32 = (PNCM_NDP32)ReceiveNdpContext->Ndp; + status = MbbRecvNtbUnpackIpNdp32(ReceiveNdpContext, nth32, ndp32, &ReceiveNdpContext->CurrentDatagramIndex, RxQueueContext); + } + else if (MBB_NTB_IS_16BIT(nth)) + { + nth16 = (PNCM_NTH16)nth; + ndp16 = (PNCM_NDP16)ReceiveNdpContext->Ndp; + status = MbbRecvNtbUnpackIpNdp16(ReceiveNdpContext, nth16, ndp16, &ReceiveNdpContext->CurrentDatagramIndex, RxQueueContext); + } + + return status; +} + +PMBB_NDIS_RECEIVE_CONTEXT +MbbRecvQQueueReceive(_In_ PWMBCLASS_DEVICE_CONTEXT DeviceContext, _In_ MBB_RECEIVE_CONTEXT BusContext, _In_ PMDL Mdl, _In_reads_(sizeof(NCM_NTH32)) PUCHAR ReceiveNtbBuffer) +{ + PMBB_NDIS_RECEIVE_CONTEXT receiveContext = NULL; + WDFMEMORY receiveContextMemory; + size_t receiveContextSize; + NTSTATUS status = STATUS_SUCCESS; + + do + { + if (!NT_SUCCESS(status = WdfMemoryCreateFromLookaside(DeviceContext->ReceiveLookasideList, &receiveContextMemory))) + { + break; + } + + receiveContext = (PMBB_NDIS_RECEIVE_CONTEXT)WdfMemoryGetBuffer(receiveContextMemory, &receiveContextSize); + RtlZeroMemory(receiveContext, receiveContextSize); + + receiveContext->Mdl = Mdl; + receiveContext->WmbDeviceContext = DeviceContext; + receiveContext->BusHandle = DeviceContext->BusHandle; + receiveContext->BusContext = BusContext; + receiveContext->ReceiveLookasideList = DeviceContext->ReceiveLookasideList; + receiveContext->ReceiveLookasideBufferMemory = receiveContextMemory; + receiveContext->ReceiveNtbBuffer = ReceiveNtbBuffer; + receiveContext->NtbSequence = MBB_NTB_GET_SEQUENCE(ReceiveNtbBuffer); + } while (FALSE); + + return receiveContext; +} + +VOID MbbNdisReceiveCallback(_In_ MBB_PROTOCOL_HANDLE ProtocolHandle, _In_ MBB_RECEIVE_CONTEXT ReceiveContext, _In_ PMDL Mdl) +{ + PUCHAR dataBuffer; + ULONG dataLength; + PVOID nth; + BOOLEAN returnBuffer = TRUE; + PWMBCLASS_DEVICE_CONTEXT deviceContext = (PWMBCLASS_DEVICE_CONTEXT)ProtocolHandle; + PMBB_NDIS_RECEIVE_CONTEXT receive = NULL; + ULONG ndpCount = 1; + NTSTATUS status = STATUS_SUCCESS; + do + { + if ((dataBuffer = (PUCHAR)MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority | MdlMappingNoExecute)) == NULL) + { + status = STATUS_RESOURCE_DATA_NOT_FOUND; + break; + } + dataLength = MmGetMdlByteCount(Mdl); + + nth = dataBuffer; + + if (!NT_SUCCESS(status = MbbNtbValidate(nth, dataLength, deviceContext->BusParams.CurrentMode32Bit, &ndpCount))) + { + { + ULONG i; + ULONG j; + + PUCHAR buffer = (PUCHAR)nth; + + for (i = 0; i < dataLength; i += 16) + { + UCHAR numString[16 * 3 + 1]; + UCHAR asciiBuffer[40]; + UCHAR value = 0; + const char translateTable[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + + RtlZeroMemory(numString, sizeof(numString)); + RtlZeroMemory(asciiBuffer, sizeof(asciiBuffer)); + + for (j = 0; j < 16; j++) + { + if (i + j >= dataLength) + { + // + // past the end, just put spaces + // + numString[j * 3] = ' '; + numString[j * 3 + 1] = ' '; + numString[j * 3 + 2] = ' '; + } + else + { + value = buffer[i + j]; + + numString[j * 3] = translateTable[value >> 4]; + numString[j * 3 + 1] = translateTable[value & 0xf]; + numString[j * 3 + 2] = ' '; + + if ((buffer[i + j] >= 32) && (buffer[i + j] < 128)) + { + asciiBuffer[j] = value; + } + else + { + asciiBuffer[j] = '.'; + } + } + } + } + } + break; + } + + if ((receive = MbbRecvQQueueReceive(deviceContext, ReceiveContext, Mdl, (PUCHAR)nth)) == NULL) + { + status = STATUS_INSUFFICIENT_RESOURCES; + break; + } + + returnBuffer = FALSE; + receive->TotalNdpCount = ndpCount; + + // Receive DSS, IPs will be received in EvtRxQueueAdvance + MbbRecvNtbParse(receive); + } while (FALSE); + + if (returnBuffer) + { + if (receive != NULL) + { + MbbRecvCleanup(receive); + } + else + { + MbbBusReturnReceiveBuffer(deviceContext->BusHandle, ReceiveContext, Mdl); + } + } +} + +void EvtRxQueueDestroy(_In_ WDFOBJECT RxQueue) +{ + PMBB_RXQUEUE_CONTEXT rxQueueContext = MbbGetRxQueueContext(RxQueue); + PWMBCLASS_NETADAPTER_CONTEXT netAdapterContext = rxQueueContext->NetAdapterContext; + netAdapterContext->RxQueue = NULL; +} + +VOID EvtRxQueueSetNotificationEnabled(_In_ NETPACKETQUEUE RxQueue, _In_ BOOLEAN NotificationEnabled) +{ + PMBB_RXQUEUE_CONTEXT txQueueContext = MbbGetRxQueueContext(RxQueue); + InterlockedExchange(&txQueueContext->NotificationEnabled, NotificationEnabled); +} + +void EvtRxQueueAdvance(_In_ NETPACKETQUEUE RxQueue) +{ + PMBB_RXQUEUE_CONTEXT rxQueueContext = MbbGetRxQueueContext(RxQueue); + PWMBCLASS_NETADAPTER_CONTEXT netAdapterContext = rxQueueContext->NetAdapterContext; + WDFSPINLOCK wdfRecvSpinLock = netAdapterContext->WmbDeviceContext->Sessions[netAdapterContext->SessionId].WdfRecvSpinLock; + PMBB_RECEIVE_NDP_CONTEXT receiveNdpContext; + NTSTATUS status = STATUS_SUCCESS; + + WdfSpinLockAcquire(wdfRecvSpinLock); + while (!IsListEmpty(&netAdapterContext->ReceiveNdpList)) + { + receiveNdpContext = CONTAINING_RECORD(RemoveHeadList(&netAdapterContext->ReceiveNdpList), MBB_RECEIVE_NDP_CONTEXT, ReceiveNdpNode); + receiveNdpContext->ReceiveNdpNode.Flink = receiveNdpContext->ReceiveNdpNode.Blink = NULL; + WdfSpinLockRelease(wdfRecvSpinLock); + + status = MbbRecvNdpUnpackIps(receiveNdpContext, rxQueueContext); + if (status == STATUS_BUFFER_OVERFLOW) + { + WdfSpinLockAcquire(wdfRecvSpinLock); + InsertHeadList(&netAdapterContext->ReceiveNdpList, &receiveNdpContext->ReceiveNdpNode); + break; + } + else + { + if (!NT_SUCCESS(status)) + { + } + } + + WdfSpinLockAcquire(wdfRecvSpinLock); + } + WdfSpinLockRelease(wdfRecvSpinLock); +} + +void EvtRxQueueCancel(_In_ NETPACKETQUEUE RxQueue) +{ + PMBB_RXQUEUE_CONTEXT rxQueueContext = MbbGetRxQueueContext(RxQueue); + PWMBCLASS_NETADAPTER_CONTEXT netAdapterContext = rxQueueContext->NetAdapterContext; + PWMBCLASS_DEVICE_CONTEXT deviceContext = netAdapterContext->WmbDeviceContext; + NET_RING_COLLECTION const* rings = rxQueueContext->DatapathDescriptor; + + NET_RING * pr = NetRingCollectionGetPacketRing(rings); + + while (pr->BeginIndex != pr->EndIndex) + { + NET_PACKET * packet = NetRingGetPacketAtIndex(pr, pr->BeginIndex); + packet->Ignore = 1; + pr->BeginIndex = NetRingIncrementIndex(pr, pr->BeginIndex); + } + + NET_RING * fr = NetRingCollectionGetFragmentRing(rings); + fr->BeginIndex = fr->EndIndex; + + // Cancel received Ndps which may be received after EvtRxQueueCancel started, these Ndps may never be processed by EvtRxQueueAdvance + MbbRecvCancelNdps(deviceContext, netAdapterContext->SessionId); +} + +VOID EvtAdapterReturnRxBuffer(_In_ NETADAPTER Adapter, _In_ NET_FRAGMENT_RETURN_CONTEXT_HANDLE RxBufferReturnContext) +{ + PMBB_RECEIVE_NDP_CONTEXT receiveNdpContext = (PMBB_RECEIVE_NDP_CONTEXT)RxBufferReturnContext; + UNREFERENCED_PARAMETER(Adapter); + NT_ASSERT(receiveNdpContext->IndicatedPackets); + + receiveNdpContext->IndicatedPackets--; + if ((receiveNdpContext->IndicatedPackets == 0) && (receiveNdpContext->ReceiveNdpNode.Blink == NULL) && + (receiveNdpContext->ReceiveNdpNode.Flink == NULL)) + { + MbbRecvReturnNdp(receiveNdpContext->ReceiveContext, receiveNdpContext); + } +} |
