예제 #1
0
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)&currentSystemTime);
    acceptableScanTime = HelperPort->ScanContext.LastScanTime +             
         scanGapSeconds * 10000000; // Convert seconds to 100nS

    if (acceptableScanTime > currentSystemTime)
    {
        //
        // Scanned recently. Dont scan again
        //
        return FALSE;
    }
    else
    {
        return TRUE;
    }
}
예제 #2
0
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;
}
예제 #3
0
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));
    }
}