BOOLEAN HelperPortShouldPerformScan( _In_ PMP_HELPER_PORT HelperPort, _In_ PMP_SCAN_PARAMETERS ScanParameters ) { ULONGLONG currentSystemTime; ULONGLONG scanGapSeconds = HelperPort->RegInfo->InterScanTime; ULONGLONG acceptableScanTime; if (MP_TEST_PORT_STATUS(HELPPORT_GET_MP_PORT(HelperPort), MP_PORT_CANNOT_SCAN_MASK)) { // Cannot scan when in this state return FALSE; } if ((ScanParameters->CancelScan) || (ScanParameters->State != SCAN_QUEUED_FOR_PROCESSING)) { // Scan cancelled return FALSE; } if (MP_TEST_FLAG(ScanParameters->PortScanRequest->Dot11ScanRequest->dot11ScanType, dot11_scan_type_forced)) { // Forced scan. We will do it return TRUE; } if (MP_TEST_FLAG(ScanParameters->PortScanRequest->ScanRequestFlags, MP_SCAN_REQUEST_OS_ISSUED)) { // OS issued scan, we will do it return TRUE; } // Potentially, we should check if this scan request has a non-zero SSID // // To avoid too many scans, lets check if we have scanned recently. // NdisGetCurrentSystemTime((PLARGE_INTEGER)¤tSystemTime); acceptableScanTime = HelperPort->ScanContext.LastScanTime + scanGapSeconds * 10000000; // Convert seconds to 100nS if (acceptableScanTime > currentSystemTime) { // // Scanned recently. Dont scan again // return FALSE; } else { return TRUE; } }
NDIS_STATUS BasePortGetPortStatus( __in PMP_PORT Port ) { NDIS_STATUS ndisStatus; if (MP_TEST_PORT_STATUS(Port, MP_PORT_PAUSED)) ndisStatus = NDIS_STATUS_PAUSED; else if (MP_TEST_PORT_STATUS(Port, MP_PORT_PAUSING)) ndisStatus = NDIS_STATUS_PAUSED; else if (MP_TEST_PORT_STATUS(Port, MP_PORT_IN_RESET)) ndisStatus = NDIS_STATUS_RESET_IN_PROGRESS; else if (MP_TEST_PORT_STATUS(Port, MP_PORT_HALTING)) ndisStatus = NDIS_STATUS_CLOSING; else ndisStatus = NDIS_STATUS_FAILURE; // return a generic error return ndisStatus; }
VOID BasePortTransmitQueuedPackets( __in PMP_PORT Port, __in ULONG SendFlags ) { PMP_TX_MSDU currentPacket, prevPacketToForward = NULL, packetListToForward = NULL; ULONG count = 0, numPktToFwd = 0; NDIS_STATUS ndisStatus; PMP_TX_MSDU packetListToFail = NULL; // PORT_LOCK must be held // If I am pausing, this flag is set. We would not // be processing any pending packets. These packets get flushed on a pause // then not process these pending packets if (MP_TEST_PORT_STATUS(Port, MP_PORT_CANNOT_SEND_MASK)) { // // We dont do anything // MpTrace(COMP_SEND, DBG_NORMAL, ("Dropping sends as port should not be sending\n")); return; } while ((!MpPacketQueueIsEmpty(&Port->PendingTxQueue) && (count < MAX_SEND_MSDU_TO_PROCESS))) { // // Dequeue the first packet from the list // currentPacket = MP_MSDU_FROM_QUEUE_ENTRY(MpDequeuePacket(&Port->PendingTxQueue)); count++; // // Let the port pre-process the packets. We only let one // packet to get processed at a time // MP_TX_MSDU_NEXT_MSDU(currentPacket) = NULL; MP_TX_MSDU_STATUS(currentPacket) = NDIS_STATUS_SUCCESS; ndisStatus = Port11NotifySend(Port, currentPacket, SendFlags); if (ndisStatus == NDIS_STATUS_SUCCESS) { // // Look at the per-packet status values // ndisStatus = MP_TX_MSDU_STATUS(currentPacket); if (ndisStatus == NDIS_STATUS_SUCCESS) { // // Port is fine with processing these packets. Let us check if we can // continue sending this down. We only check with the VNIC // if (VNic11CanTransmit(PORT_GET_VNIC(Port)) == FALSE) { // // Some reason we cannot submit this packet to the // HW yet. Queue it in the pending Tx queue // ndisStatus = NDIS_STATUS_PENDING; // // In this case we indicate the packet to the Port again // the next time we attempt to send. Ensure that the port // can handle that // } } } else { // // Port returned PENDING or FAILURE for the packet list. We wont // be sending any of these packets // } // // All the above processing would give us one of the following status codes // // NDIS_STATUS_SUCCESS - The packets can be processed furthers. In this case // we forward the packet to the lower layer // NDIS_STATUS_PENDING - This packet should not be sent now, but can be sent later // In this case we requeue the packet and stop processing // further packets // NDIS_STATUS_FAILURE or anything other failure status // - The packet is not sent and we continue processing // other packets if (ndisStatus == NDIS_STATUS_SUCCESS) { numPktToFwd++; // Add this to the end of the chain we are forwarding to the HW if (packetListToForward == NULL) { packetListToForward = currentPacket; } else { MP_TX_MSDU_NEXT_MSDU(prevPacketToForward) = currentPacket; } prevPacketToForward = currentPacket; // // Increment the counter for the number of packets we have submitted // to the hardware. This would block the port from pausing, etc // PORT_INCREMENT_PNP_REFCOUNT(Port); } else if (ndisStatus == NDIS_STATUS_PENDING) { // // Put the packet back at the head of the packet queue. To avoid out of // order delivery we dont go forward and give any more packets to the // lower layer // MpQueuePacketPriority(&Port->PendingTxQueue, QUEUE_ENTRY_FROM_MP_MSDU(currentPacket)); break; } else { // // Put this packet in the list of packets to be failed // MpTrace(COMP_SEND, DBG_NORMAL, ("Port or VNic failed sends with status 0x%08x\n", ndisStatus)); MP_TX_MSDU_STATUS(currentPacket) = ndisStatus; MP_TX_MSDU_NEXT_MSDU(currentPacket) = packetListToFail; packetListToFail = currentPacket; } } if ((packetListToForward != NULL) || (packetListToFail != NULL)) { // Forward this list to the VNIC MP_RELEASE_PORT_LOCK(Port, NDIS_TEST_SEND_AT_DISPATCH_LEVEL(SendFlags)); if (packetListToForward != NULL) { VNic11SendPackets(PORT_GET_VNIC(Port), packetListToForward, numPktToFwd, SendFlags); } // // Complete the failed packets // if (packetListToFail != NULL) { BasePortCompleteFailedPackets(Port, packetListToFail, NDIS_TEST_SEND_AT_DISPATCH_LEVEL(SendFlags) ? NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL : 0 ); } MP_ACQUIRE_PORT_LOCK(Port, NDIS_TEST_SEND_AT_DISPATCH_LEVEL(SendFlags)); } }