/********************************************************** Required NDIS handler for RESET operation Never happens under normal condition, only if OID or other call returns PENDING and not completed or if ParaNdis6_CheckForHang returns true ***********************************************************/ static NDIS_STATUS ParaNdis6_Reset( NDIS_HANDLE miniportAdapterContext, PBOOLEAN pAddressingReset) { NDIS_STATUS status = NDIS_STATUS_FAILURE; PARANDIS_ADAPTER *pContext = (PARANDIS_ADAPTER *)miniportAdapterContext; NDIS_HANDLE hwo; tGeneralWorkItem *pwi; DEBUG_ENTRY(0); *pAddressingReset = TRUE; ParaNdis_DebugHistory(pContext, hopSysReset, NULL, 1, 0, 0); hwo = NdisAllocateIoWorkItem(pContext->MiniportHandle); pwi = ParaNdis_AllocateMemory(pContext, sizeof(tGeneralWorkItem)); if (pwi && hwo) { pwi->pContext = pContext; pwi->WorkItem = hwo; NdisQueueIoWorkItem(hwo, OnResetWorkItem, pwi); status = NDIS_STATUS_PENDING; } else { if (pwi) NdisFreeMemory(pwi, 0, 0); if (hwo) NdisFreeIoWorkItem(hwo); ParaNdis_DebugHistory(pContext, hopSysReset, NULL, 0, status, 0); } DEBUG_EXIT_STATUS(0, status); return status; }
/********************************************************** Pauses of restarts RX activity. Restart is immediate, pause may be delayed until NDIS returns all the indicated NBL Parameters: context bPause 1/0 - pause or restart ONPAUSECOMPLETEPROC Callback to be called when PAUSE finished Return value: SUCCESS if finished synchronously PENDING if not, then callback will be called ***********************************************************/ NDIS_STATUS ParaNdis6_ReceivePauseRestart( PARANDIS_ADAPTER *pContext, BOOLEAN bPause, ONPAUSECOMPLETEPROC Callback ) { NDIS_STATUS status = NDIS_STATUS_SUCCESS; if (bPause) { CNdisPassiveWriteAutoLock tLock(pContext->m_PauseLock); ParaNdis_DebugHistory(pContext, hopInternalReceivePause, NULL, 1, 0, 0); if (pContext->m_rxPacketsOutsideRing != 0) { pContext->ReceiveState = srsPausing; pContext->ReceivePauseCompletionProc = Callback; status = NDIS_STATUS_PENDING; } else { ParaNdis_DebugHistory(pContext, hopInternalReceivePause, NULL, 0, 0, 0); pContext->ReceiveState = srsDisabled; } } else { ParaNdis_DebugHistory(pContext, hopInternalReceiveResume, NULL, 0, 0, 0); pContext->ReceiveState = srsEnabled; } return status; }
/************************************************************* Required NDIS procedure Called when some procedure (like OID handler) returns PENDING and does not complete or when CheckForHang return TRUE *************************************************************/ static NDIS_STATUS ParaNdis5_Reset( OUT PBOOLEAN AddressingReset, IN NDIS_HANDLE MiniportAdapterContext) { NDIS_STATUS status; tGeneralWorkItem *pwi; PARANDIS_ADAPTER *pContext = (PARANDIS_ADAPTER *)MiniportAdapterContext; DEBUG_ENTRY(0); ParaNdis_DebugHistory(pContext, hopSysReset, NULL, 1, 0, 0); status = NDIS_STATUS_FAILURE; pwi = ParaNdis_AllocateMemory(pContext, sizeof(tGeneralWorkItem)); if (pwi) { pwi->pContext = pContext; NdisInitializeWorkItem(&pwi->wi, OnResetWorkItem, pwi); if (NdisScheduleWorkItem(&pwi->wi) == NDIS_STATUS_SUCCESS) { status = NDIS_STATUS_PENDING; } else { NdisFreeMemory(pwi, 0, 0); } } if (status != NDIS_STATUS_PENDING) { ParaNdis_DebugHistory(pContext, hopSysReset, NULL, 0, status, 0); } return status; }
/************************************************************* Required NDIS procedure Stops TX and RX path and finished the function of adapter *************************************************************/ static VOID ParaNdis5_Halt( IN NDIS_HANDLE MiniportAdapterContext) { NDIS_STATUS status = NDIS_STATUS_SUCCESS; BOOLEAN bUnused; PARANDIS_ADAPTER *pContext = (PARANDIS_ADAPTER *)MiniportAdapterContext; DEBUG_ENTRY(0); ParaNdis_DebugHistory(pContext, hopHalt, NULL, 1, 0, 0); NdisCancelTimer(&pContext->ConnectTimer, &bUnused); NdisResetEvent(&pContext->HaltEvent); if (NDIS_STATUS_PENDING != ParaNdis5_StopSend(pContext, TRUE, OnSendStopped)) NdisSetEvent(&pContext->HaltEvent); WaitHaltEvent(pContext, "Send"); NdisResetEvent(&pContext->HaltEvent); if (NDIS_STATUS_PENDING != ParaNdis5_StopReceive(pContext, TRUE, OnReceiveStopped)) NdisSetEvent(&pContext->HaltEvent); WaitHaltEvent(pContext, "Receive"); ParaNdis_CleanupContext(pContext); NdisCancelTimer(&pContext->DPCPostProcessTimer, &bUnused); ParaNdis_DebugHistory(pContext, hopHalt, NULL, 0, 0, 0); ParaNdis_DebugRegisterMiniport(pContext, FALSE); NdisFreeMemory(pContext, 0, 0); DEBUG_EXIT_STATUS(0, status); }
/********************************************************** Pauses of restarts RX activity. Restart is immediate, pause may be delayed until NDIS returns all the indicated NBL Parameters: context bPause 1/0 - pause or restart ONPAUSECOMPLETEPROC Callback to be called when PAUSE finished Return value: SUCCESS if finished synchronously PENDING if not, then callback will be called ***********************************************************/ NDIS_STATUS ParaNdis6_ReceivePauseRestart( PARANDIS_ADAPTER *pContext, BOOLEAN bPause, ONPAUSECOMPLETEPROC Callback ) { NDIS_STATUS status = NDIS_STATUS_SUCCESS; NdisAcquireSpinLock(&pContext->ReceiveLock); if (bPause) { ParaNdis_DebugHistory(pContext, hopInternalReceivePause, NULL, 1, 0, 0); if (!IsListEmpty(&pContext->NetReceiveBuffersWaiting)) { pContext->ReceiveState = srsPausing; pContext->ReceivePauseCompletionProc = Callback; status = NDIS_STATUS_PENDING; } else { ParaNdis_DebugHistory(pContext, hopInternalReceivePause, NULL, 0, 0, 0); pContext->ReceiveState = srsDisabled; } } else { ParaNdis_DebugHistory(pContext, hopInternalReceiveResume, NULL, 0, 0, 0); pContext->ReceiveState = srsEnabled; } NdisReleaseSpinLock(&pContext->ReceiveLock); return status; }
/********************************************************** called at IRQL = PASSIVE_LEVEL Called on disable, on removal, on standby (if required) ***********************************************************/ static VOID ParaNdis6_Halt(NDIS_HANDLE miniportAdapterContext, NDIS_HALT_ACTION haltAction) { PARANDIS_ADAPTER *pContext = (PARANDIS_ADAPTER *)miniportAdapterContext; DEBUG_ENTRY(0); ParaNdis_DebugHistory(pContext, hopHalt, NULL, 1, haltAction, 0); ParaNdis_CleanupContext(pContext); ParaNdis_DebugHistory(pContext, hopHalt, NULL, 0, 0, 0); ParaNdis_DebugRegisterMiniport(pContext, FALSE); NdisFreeMemory(pContext, 0, 0); DEBUG_EXIT_STATUS(2, 0); }
/********************************************************** callback from asynchronous RECEIVE PAUSE ***********************************************************/ static void OnReceivePauseComplete(PARANDIS_ADAPTER *pContext) { DEBUG_ENTRY(0); // pause exit ParaNdis_DebugHistory(pContext, hopSysPause, NULL, 0, 0, 0); NdisMPauseComplete(pContext->MiniportHandle); }
static VOID PostLinkState(PARANDIS_ADAPTER *pContext, NDIS_MEDIA_CONNECT_STATE connectState) { NDIS_STATUS_INDICATION indication; NDIS_LINK_STATE state; NdisZeroMemory(&state, sizeof(state)); state.Header.Revision = NDIS_LINK_STATE_REVISION_1; state.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; state.Header.Size = NDIS_SIZEOF_LINK_STATE_REVISION_1; state.MediaConnectState = connectState; state.MediaDuplexState = MediaDuplexStateFull; state.RcvLinkSpeed = state.XmitLinkSpeed = connectState == MediaConnectStateConnected ? PARANDIS_MAXIMUM_RECEIVE_SPEED : NDIS_LINK_SPEED_UNKNOWN; state.PauseFunctions = NdisPauseFunctionsUnsupported; NdisZeroMemory(&indication, sizeof(indication)); indication.Header.Type = NDIS_OBJECT_TYPE_STATUS_INDICATION; indication.Header.Revision = NDIS_STATUS_INDICATION_REVISION_1; indication.Header.Size = NDIS_SIZEOF_STATUS_INDICATION_REVISION_1; indication.SourceHandle = pContext->MiniportHandle; indication.StatusCode = NDIS_STATUS_LINK_STATE; indication.StatusBuffer = &state; indication.StatusBufferSize = sizeof(state); DPrintf(0, ("Indicating %s\n", ConnectStateName(connectState))); ParaNdis_DebugHistory(pContext, hopConnectIndication, NULL, connectState, 0, 0); NdisMIndicateStatusEx(pContext->MiniportHandle , &indication); }
BOOLEAN _Function_class_(MINIPORT_SYNCHRONIZE_INTERRUPT) CParaNdisRX::RestartQueueSynchronously(tSynchronizedContext *ctx) { CVirtQueue *queue = (CVirtQueue *) ctx->Parameter; bool res = queue->Restart(); ParaNdis_DebugHistory(ctx->pContext, hopDPC, (PVOID)ctx->Parameter, 0x20, res, 0); return !res; }
/********************************************************** NDIS required procedure of OID SET Just passes all the supported oids to common set procedure Return value: NDIS_STATUS as returned from set procedure NDIS_STATUS_NOT_SUPPORTED if support not defined in the table ***********************************************************/ NDIS_STATUS ParaNdis5_SetOID(IN NDIS_HANDLE MiniportAdapterContext, IN NDIS_OID Oid, IN PVOID InformationBuffer, IN ULONG InformationBufferLength, OUT PULONG BytesRead, OUT PULONG BytesNeeded) { NDIS_STATUS status = NDIS_STATUS_NOT_SUPPORTED; tOidWhatToDo Rules; PARANDIS_ADAPTER *pContext = (PARANDIS_ADAPTER *)MiniportAdapterContext; tOidDesc _oid; ParaNdis_GetOidSupportRules(Oid, &Rules, OidsDB); _oid.ulToDoFlags = Rules.Flags; *BytesRead = 0; *BytesNeeded = 0; ParaNdis_DebugHistory(pContext, hopOidRequest, NULL, Oid, 1, 1); DPrintf(Rules.nEntryLevel, ("[%s], id 0x%X(%s) of %d", __FUNCTION__, Oid, Rules.name, InformationBufferLength)); _oid.Oid = Oid; _oid.InformationBuffer = InformationBuffer; _oid.InformationBufferLength = InformationBufferLength; _oid.pBytesNeeded = BytesNeeded; _oid.pBytesRead = BytesRead; _oid.pBytesWritten = BytesRead; if (pContext->bSurprizeRemoved) status = NDIS_STATUS_NOT_ACCEPTED; else if (Rules.Flags & ohfSet) { if (Rules.OidSetProc) status = Rules.OidSetProc(pContext, &_oid); else { DPrintf(0, ("[%s] ERROR in OID redirection table", __FUNCTION__)); status = NDIS_STATUS_INVALID_OID; } } ParaNdis_DebugHistory(pContext, hopOidRequest, NULL, Oid, status, 0); if (status != NDIS_STATUS_PENDING) { DPrintf((status != NDIS_STATUS_SUCCESS) ? Rules.nExitFailLevel : Rules.nExitOKLevel, ("[%s] , id 0x%X(%s) (%X), read %d, needed %d", __FUNCTION__, Rules.oid, Rules.name, status, *BytesRead, *BytesNeeded)); } return status; }
/********************************************************** Pauses of restarts TX activity. Restart is immediate, pause may be delayed until we return all the NBLs to NDIS Parameters: context bPause 1/0 - pause or restart ONPAUSECOMPLETEPROC Callback to be called when PAUSE finished Return value: SUCCESS if finished synchronously PENDING if not, then callback will be called later ***********************************************************/ NDIS_STATUS ParaNdis6_SendPauseRestart( PARANDIS_ADAPTER *pContext, BOOLEAN bPause, ONPAUSECOMPLETEPROC Callback ) { NDIS_STATUS status = NDIS_STATUS_SUCCESS; DEBUG_ENTRY(4); if (bPause) { ParaNdis_DebugHistory(pContext, hopInternalSendPause, NULL, 1, 0, 0); if (pContext->SendState == srsEnabled) { { CNdisPassiveWriteAutoLock tLock(pContext->m_PauseLock); pContext->SendState = srsPausing; pContext->SendPauseCompletionProc = Callback; } for (UINT i = 0; i < pContext->nPathBundles; i++) { if (!pContext->pPathBundles[i].txPath.Pause()) { status = NDIS_STATUS_PENDING; } } if (status == NDIS_STATUS_SUCCESS) { pContext->SendState = srsDisabled; } } if (status == NDIS_STATUS_SUCCESS) { ParaNdis_DebugHistory(pContext, hopInternalSendPause, NULL, 0, 0, 0); } } else { pContext->SendState = srsEnabled; ParaNdis_DebugHistory(pContext, hopInternalSendResume, NULL, 0, 0, 0); } return status; }
/********************************************************** Required NDIS handler called at IRQL = PASSIVE_LEVEL Must pause RX and TX Called upon startup, on resume, upon protocols activation ***********************************************************/ static NDIS_STATUS ParaNdis6_Restart( NDIS_HANDLE miniportAdapterContext, PNDIS_MINIPORT_RESTART_PARAMETERS miniportRestartParameters) { NDIS_STATUS status = NDIS_STATUS_SUCCESS; PARANDIS_ADAPTER *pContext = (PARANDIS_ADAPTER *)miniportAdapterContext; DEBUG_ENTRY(0); UNREFERENCED_PARAMETER(miniportRestartParameters); ParaNdis_DebugHistory(pContext, hopSysResume, NULL, 1, 0, 0); ParaNdis6_SendPauseRestart(pContext, FALSE, NULL); ParaNdis6_ReceivePauseRestart(pContext, FALSE, NULL); ParaNdis_DebugHistory(pContext, hopSysResume, NULL, 0, 0, 0); DEBUG_EXIT_STATUS(2, status); return status; }
/********************************************************** NDIS required procedure of OID QUERY Just passes all the supported oids to common query procedure Return value: NDIS_STATUS as returned from common code NDIS_STATUS_NOT_SUPPORTED if suppressed in the table ***********************************************************/ NDIS_STATUS ParaNdis5_QueryOID(IN NDIS_HANDLE MiniportAdapterContext, IN NDIS_OID Oid, IN PVOID InformationBuffer, IN ULONG InformationBufferLength, OUT PULONG BytesWritten, OUT PULONG BytesNeeded) { NDIS_STATUS status = NDIS_STATUS_NOT_SUPPORTED; int debugLevel; tOidWhatToDo Rules; PARANDIS_ADAPTER *pContext = (PARANDIS_ADAPTER *)MiniportAdapterContext; tOidDesc _oid; ParaNdis_GetOidSupportRules(Oid, &Rules, OidsDB); _oid.ulToDoFlags = Rules.Flags; *BytesWritten = 0; *BytesNeeded = 0; ParaNdis_DebugHistory(pContext, hopOidRequest, NULL, Oid, 0, 1); DPrintf(Rules.nEntryLevel, ("[%s], id 0x%X(%s) of %d", __FUNCTION__, Oid, Rules.name, InformationBufferLength)); _oid.Oid = Oid; _oid.InformationBuffer = InformationBuffer; _oid.InformationBufferLength = InformationBufferLength; _oid.pBytesNeeded = BytesNeeded; _oid.pBytesRead = BytesWritten; _oid.pBytesWritten = BytesWritten; if (pContext->bSurprizeRemoved) status = NDIS_STATUS_NOT_ACCEPTED; else if (Rules.Flags & ohfQuery) status = ParaNdis_OidQuery(pContext, &_oid); ParaNdis_DebugHistory(pContext, hopOidRequest, NULL, Oid, status, 0); DPrintf((status != NDIS_STATUS_SUCCESS) ? Rules.nExitFailLevel : Rules.nExitOKLevel, ("[%s] , id 0x%X(%s) (%X), written %d, needed %d", __FUNCTION__, Rules.oid, Rules.name, status, *BytesWritten, *BytesNeeded)); return status; }
/********************************************************** callback from asynchronous SEND PAUSE ***********************************************************/ static void OnSendPauseComplete(PARANDIS_ADAPTER *pContext) { NDIS_STATUS status; DEBUG_ENTRY(0); status = ParaNdis6_ReceivePauseRestart(pContext, TRUE, OnReceivePauseComplete); if (status != NDIS_STATUS_PENDING) { // pause exit ParaNdis_DebugHistory(pContext, hopSysPause, NULL, 0, 0, 0); NdisMPauseComplete(pContext->MiniportHandle); } }
/********************************************************** Pauses of restarts TX activity. Restart is immediate, pause may be delayed until we return all the NBLs to NDIS Parameters: context bPause 1/0 - pause or restart ONPAUSECOMPLETEPROC Callback to be called when PAUSE finished Return value: SUCCESS if finished synchronously PENDING if not, then callback will be called later ***********************************************************/ NDIS_STATUS ParaNdis6_SendPauseRestart( PARANDIS_ADAPTER *pContext, BOOLEAN bPause, ONPAUSECOMPLETEPROC Callback ) { NDIS_STATUS status = NDIS_STATUS_SUCCESS; DEBUG_ENTRY(4); if (bPause) { ParaNdis_DebugHistory(pContext, hopInternalSendPause, NULL, 1, 0, 0); if (pContext->SendState == srsEnabled) { pContext->SendState = srsPausing; pContext->SendPauseCompletionProc = Callback; if (pContext->TXPath.Pause()) { pContext->SendState = srsDisabled; } else { status = NDIS_STATUS_PENDING; } } if (status == NDIS_STATUS_SUCCESS) { ParaNdis_DebugHistory(pContext, hopInternalSendPause, NULL, 0, 0, 0); } } else { pContext->SendState = srsEnabled; ParaNdis_DebugHistory(pContext, hopInternalSendResume, NULL, 0, 0, 0); } return status; }
static void OnResetWorkItem(NDIS_WORK_ITEM * pWorkItem, PVOID Context) { tGeneralWorkItem *pwi = (tGeneralWorkItem *)pWorkItem; PARANDIS_ADAPTER *pContext = pwi->pContext; DEBUG_ENTRY(0); ParaNdis_IndicateConnect(pContext, FALSE, FALSE); ParaNdis_Suspend(pContext); ParaNdis_Resume(pContext); ParaNdis_ReportLinkStatus(pContext); NdisFreeMemory(pwi, 0, 0); ParaNdis_DebugHistory(pContext, hopSysReset, NULL, 0, NDIS_STATUS_SUCCESS, 0); NdisMResetComplete(pContext->MiniportHandle, NDIS_STATUS_SUCCESS, TRUE); }
/********************************************************** Required NDIS handler called at IRQL = PASSIVE_LEVEL Must pause RX and TX Called before halt, on standby, upon protocols activation ***********************************************************/ static NDIS_STATUS ParaNdis6_Pause( NDIS_HANDLE miniportAdapterContext, PNDIS_MINIPORT_PAUSE_PARAMETERS miniportPauseParameters) { NDIS_STATUS status; PARANDIS_ADAPTER *pContext = (PARANDIS_ADAPTER *)miniportAdapterContext; DEBUG_ENTRY(0); UNREFERENCED_PARAMETER(miniportPauseParameters); ParaNdis_DebugHistory(pContext, hopSysPause, NULL, 1, 0, 0); status = ParaNdis6_SendPauseRestart(pContext, TRUE, OnSendPauseComplete); if (status != NDIS_STATUS_PENDING) { status = ParaNdis6_ReceivePauseRestart(pContext, TRUE, OnReceivePauseComplete); } DEBUG_EXIT_STATUS(0, status); if (status == STATUS_SUCCESS) { // pause exit ParaNdis_DebugHistory(pContext, hopSysPause, NULL, 0, 0, 0); } return status; }
static void OnSetPowerWorkItem(NDIS_WORK_ITEM * pWorkItem, PVOID Context) { tPowerWorkItem *pwi = (tPowerWorkItem *)pWorkItem; PARANDIS_ADAPTER *pContext = pwi->pContext; if (pwi->state == NetDeviceStateD0) { ParaNdis_PowerOn(pContext); } else { ParaNdis_PowerOff(pContext); } NdisFreeMemory(pwi, 0, 0); ParaNdis_DebugHistory(pContext, hopOidRequest, NULL, OID_PNP_SET_POWER, 0, 2); NdisMSetInformationComplete(pContext->MiniportHandle, NDIS_STATUS_SUCCESS); }
static void OnResetWorkItem(PVOID WorkItemContext, NDIS_HANDLE NdisIoWorkItemHandle) { if (WorkItemContext) { tGeneralWorkItem *pwi = (tGeneralWorkItem *)WorkItemContext; PARANDIS_ADAPTER *pContext = pwi->pContext; BOOLEAN bSendActive, bReceiveActive; DEBUG_ENTRY(0); bSendActive = pContext->SendState == srsEnabled; bReceiveActive = pContext->ReceiveState == srsEnabled; pContext->bResetInProgress = TRUE; ParaNdis_Suspend(pContext); ParaNdis_PowerOff(pContext); ParaNdis_PowerOn(pContext); if (bSendActive) ParaNdis6_SendPauseRestart(pContext, FALSE, NULL); if (bReceiveActive) ParaNdis6_ReceivePauseRestart(pContext, FALSE, NULL); pContext->bResetInProgress = FALSE; NdisFreeMemory(pwi, 0, 0); NdisFreeIoWorkItem(NdisIoWorkItemHandle); ParaNdis_DebugHistory(pContext, hopSysReset, NULL, 0, NDIS_STATUS_SUCCESS, 0); NdisMResetComplete(pContext->MiniportHandle, NDIS_STATUS_SUCCESS, TRUE); } }
/********************************************************** NDIS6 implementation of packet indication Parameters: context PVOID pBuffersDescriptor - VirtIO buffer descriptor of data buffer BOOLEAN bPrepareOnly - only return NBL for further indication in batch Return value: TRUE is packet indicated FALSE if not (in this case, the descriptor should be freed now) If priority header is in the packet. it will be removed and *pLength decreased ***********************************************************/ tPacketIndicationType ParaNdis_PrepareReceivedPacket( PARANDIS_ADAPTER *pContext, pRxNetDescriptor pBuffersDesc, PUINT pnCoalescedSegmentsCount) { PMDL pMDL = pBuffersDesc->Holder; PNET_BUFFER_LIST pNBL = NULL; *pnCoalescedSegmentsCount = 1; if (pMDL) { ULONG nBytesStripped = 0; PNET_PACKET_INFO pPacketInfo = &pBuffersDesc->PacketInfo; if (pContext->ulPriorityVlanSetting && pPacketInfo->hasVlanHeader) { nBytesStripped = ParaNdis_StripVlanHeaderMoveHead(pPacketInfo); } ParaNdis_PadPacketToMinimalLength(pPacketInfo); ParaNdis_AdjustRxBufferHolderLength(pBuffersDesc, nBytesStripped); pNBL = NdisAllocateNetBufferAndNetBufferList(pContext->BufferListsPool, 0, 0, pMDL, nBytesStripped, pPacketInfo->dataLength); if (pNBL) { virtio_net_hdr *pHeader = (virtio_net_hdr *) pBuffersDesc->PhysicalPages[0].Virtual; tChecksumCheckResult csRes; pNBL->SourceHandle = pContext->MiniportHandle; NBLSetRSSInfo(pContext, pNBL, pPacketInfo); NBLSet8021QInfo(pContext, pNBL, pPacketInfo); pNBL->MiniportReserved[0] = pBuffersDesc; #if PARANDIS_SUPPORT_RSC if(pHeader->gso_type != VIRTIO_NET_HDR_GSO_NONE) { *pnCoalescedSegmentsCount = PktGetTCPCoalescedSegmentsCount(pPacketInfo, pContext->MaxPacketSize.nMaxDataSize); NBLSetRSCInfo(pContext, pNBL, pPacketInfo, *pnCoalescedSegmentsCount); } else #endif { csRes = ParaNdis_CheckRxChecksum( pContext, pHeader->flags, &pBuffersDesc->PhysicalPages[PARANDIS_FIRST_RX_DATA_PAGE], pPacketInfo, nBytesStripped, TRUE); if (csRes.value) { NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO qCSInfo; qCSInfo.Value = NULL; qCSInfo.Receive.IpChecksumFailed = csRes.flags.IpFailed; qCSInfo.Receive.IpChecksumSucceeded = csRes.flags.IpOK; qCSInfo.Receive.TcpChecksumFailed = csRes.flags.TcpFailed; qCSInfo.Receive.TcpChecksumSucceeded = csRes.flags.TcpOK; qCSInfo.Receive.UdpChecksumFailed = csRes.flags.UdpFailed; qCSInfo.Receive.UdpChecksumSucceeded = csRes.flags.UdpOK; NET_BUFFER_LIST_INFO(pNBL, TcpIpChecksumNetBufferListInfo) = qCSInfo.Value; DPrintf(1, ("Reporting CS %X->%X\n", csRes.value, (ULONG)(ULONG_PTR)qCSInfo.Value)); } } pNBL->Status = NDIS_STATUS_SUCCESS; #if defined(ENABLE_HISTORY_LOG) { tTcpIpPacketParsingResult packetReview = ParaNdis_CheckSumVerify( RtlOffsetToPointer(pPacketInfo->headersBuffer, ETH_HEADER_SIZE), pPacketInfo->dataLength, pcrIpChecksum | pcrTcpChecksum | pcrUdpChecksum, __FUNCTION__ ); ParaNdis_DebugHistory(pContext, hopPacketReceived, pNBL, pPacketInfo->dataLength, (ULONG)(ULONG_PTR)qInfo.Value, packetReview.value); } #endif } } return pNBL; }