Exemple #1
0
NDIS_STATUS 
HelperPortReceiveEventHandler(
    __in  PMP_PORT                Port,
    __in  PMP_RX_MSDU             PacketList,
    __in  ULONG                   ReceiveFlags
    )
{
    NDIS_STATUS         ndisStatus = NDIS_STATUS_SUCCESS;
    PDOT11_MAC_HEADER   packetHeader;
    PMP_RX_MPDU         rxFragment;
    USHORT              fragmentSize;
    PMP_RX_MSDU         currentPacket = PacketList;

    UNREFERENCED_PARAMETER(ReceiveFlags);
    
    // Process each of the packets internally
    while (currentPacket != NULL)
    {
        // We only accept 1 fragment
        rxFragment = MP_RX_MSDU_MPDU_AT(currentPacket, 0);    
        packetHeader = MP_RX_MPDU_DATA(rxFragment);
        fragmentSize = (USHORT)MP_RX_MPDU_LENGTH(rxFragment);
        
        switch(packetHeader->FrameControl.Type)
        {
            case DOT11_FRAME_TYPE_MANAGEMENT:
                //
                // Process management packet
                //
                ndisStatus = HelperPortReceiveMgmtPacket(
                    MP_GET_HELPPORT(Port),
                    rxFragment,
                    fragmentSize
                    );
                break;
                
            default:
                break;
        }

        //
        // Set the status. This determines if this packet should
        // be forwarded up or not
        //
        MP_RX_MSDU_STATUS(currentPacket) = ndisStatus;

        // Next packet
        currentPacket = MP_RX_MSDU_NEXT_MSDU(currentPacket);
    }

    return NDIS_STATUS_SUCCESS;
Exemple #2
0
NDIS_STATUS 
HelperPortScanCompleteCallback(
    _In_  PMP_PORT                Port,
    _In_  PVOID                   Data
    )
{
    PMP_HELPER_PORT             helperPort = MP_GET_HELPPORT(Port);
    NDIS_STATUS                 completionStatus = *((PNDIS_STATUS)Data);
    PMP_SCAN_PARAMETERS         scanParameters 
                                    = helperPort->ScanContext.ActiveScanParameters;
     // Complete the partial scan
    HelperPortCompletePartialScan(helperPort, scanParameters, &completionStatus);

    return NDIS_STATUS_SUCCESS;
}
Exemple #3
0
PMP_BSS_LIST
HelperPortQueryAndRefBSSList(
    __in  PMP_PORT                Port,
    __in  PMP_PORT                RequestingPort,
    __in  PMP_RW_LOCK_STATE       LockState
    )
{
    PMP_HELPER_PORT     HelperPort = MP_GET_HELPPORT(Port);

    UNREFERENCED_PARAMETER(RequestingPort);

    // Acquire read lock on the BSS list
    MP_ACQUIRE_READ_LOCK(&(HelperPort->BSSList.ListLock), LockState);

    return &(HelperPort->BSSList);
Exemple #4
0
NDIS_STATUS
HelperPortScanExAccessCallback(
    _In_  PMP_PORT                Port, 
    _In_  PVOID                   Ctx
    )
{
    PMP_SCAN_PARAMETERS         scanParameters = (PMP_SCAN_PARAMETERS)Ctx;
    PMP_HELPER_PORT             helperPort = MP_GET_HELPPORT(Port);
    BOOLEAN                     performScan = TRUE;
    
    // The cancellation here is handled specially. Since we cannot abort
    // a request for exclusive access, its possible that our exclusive
    // access request gets honored after we have cancelled a scan

    HelperPortExclusiveAccessGranted(helperPort);
    
    MP_ACQUIRE_PORT_LOCK(HELPPORT_GET_MP_PORT(helperPort), FALSE);
    if ((scanParameters->State != SCAN_EXCLUSIVE_ACCESS_QUEUED) ||
        (scanParameters->CancelScan))
    {
        // The request has been cancelled and would get completed
        MpTrace(COMP_SCAN, DBG_NORMAL, ("Ignored exclusive access for cancelled/old scan request %p\n", scanParameters));
        performScan = FALSE;
    }
    else
    {
        // Move forward with the scan
        scanParameters->State = SCAN_EXCLUSIVE_ACCESS_ACQUIRED;
    }
    MP_RELEASE_PORT_LOCK(HELPPORT_GET_MP_PORT(helperPort), FALSE);

    if (performScan)
    {
        HelperPortStartPartialScan(helperPort, scanParameters);
    }
    else
    {
        // Release exclusive access back to the HW
        HelperPortReleaseExclusiveAccess(helperPort);

        // Free the scan request
        HelperPortScanParametersReleaseRef(helperPort, scanParameters);
    }
    return NDIS_STATUS_SUCCESS;
}
Exemple #5
0
VOID
HelperPortNotify(
    _In_  PMP_PORT        Port,
    PVOID               Notif
    )
{
    PMP_HELPER_PORT             helperPort = MP_GET_HELPPORT(Port);
    PNOTIFICATION_DATA_HEADER   notifyHeader = (PNOTIFICATION_DATA_HEADER)Notif;

    switch (notifyHeader->Type)
    {
        case NotificationOpLinkState:
        {
            POP_LINK_STATE_NOTIFICATION pMediaNotif = (POP_LINK_STATE_NOTIFICATION)Notif;
            
            MP_ACQUIRE_PORT_LOCK(Port, FALSE);
            
            if (pMediaNotif->MediaConnected)
            {
                MpTrace(COMP_SCAN, DBG_NORMAL, ("Incrementing connect count for CONNECT. current = %d\n", helperPort->ScanContext.MediaConnectedCount));
                MPASSERT(helperPort->ScanContext.MediaConnectedCount < MP_MAX_NUMBER_OF_PORT);
                helperPort->ScanContext.MediaConnectedCount++;
            }
            else
            {
                MpTrace(COMP_SCAN, DBG_NORMAL, ("Decrementing connect count for DISCONNECT. current = %d\n", helperPort->ScanContext.MediaConnectedCount));
                MPASSERT(helperPort->ScanContext.MediaConnectedCount > 0);
                helperPort->ScanContext.MediaConnectedCount--;
            }
            
            MP_RELEASE_PORT_LOCK(Port, FALSE);
            break;
        }
        default:
            break;
    }
}
Exemple #6
0
NDIS_STATUS
HelperPortFlushBSSList(
    __in PMP_PORT                 Port
    )
{
    MP_RW_LOCK_STATE          LockState;
    PLIST_ENTRY         pListEntry;
    PMP_BSS_ENTRY      pBSSEntry = NULL;
    LONG                APRefCount;
    LIST_ENTRY          TempList;
    PMP_HELPER_PORT     HelperPort = MP_GET_HELPPORT(Port);
    PMP_BSS_LIST       pDiscoveredBSSList = &(HelperPort->BSSList);

    //
    // Entries that are currently in use (eg for connection)
    // we cannot flush and instead would put in the temporary queue
    //
    InitializeListHead(&TempList);
    
    MP_ACQUIRE_WRITE_LOCK(&(HelperPort->BSSList.ListLock), &LockState);
        
    while (!IsListEmpty(&(pDiscoveredBSSList->List)))
    {
        pListEntry = RemoveHeadList(&(pDiscoveredBSSList->List));
        pBSSEntry = CONTAINING_RECORD(pListEntry, MP_BSS_ENTRY, Link);

        APRefCount = NdisInterlockedDecrement(&(pBSSEntry->RefCount));
        if (APRefCount == 0)
        {        
            NdisAcquireSpinLock(&(pBSSEntry->Lock));
            MPASSERT(pBSSEntry->pAssocRequest == NULL);
            MPASSERT(pBSSEntry->pAssocResponse == NULL);
            
            if (pBSSEntry->pDot11BeaconFrame != NULL)
            {
                MP_FREE_MEMORY(pBSSEntry->pDot11BeaconFrame);
                pBSSEntry->pDot11BeaconFrame = NULL;
                pBSSEntry->BeaconFrameSize = 0;
                pBSSEntry->MaxBeaconFrameSize= 0;
            }

            if (pBSSEntry->pDot11ProbeFrame != NULL)
            {
                MP_FREE_MEMORY(pBSSEntry->pDot11ProbeFrame);
                pBSSEntry->pDot11ProbeFrame = NULL;
                pBSSEntry->ProbeFrameSize = 0;
                pBSSEntry->MaxProbeFrameSize= 0;
            }
            
            pBSSEntry->pDot11InfoElemBlob = NULL;
            pBSSEntry->InfoElemBlobSize = 0;            
            NdisReleaseSpinLock(&(pBSSEntry->Lock));
            
            MP_FREE_MEMORY(pBSSEntry);        
        }
        else
        {
            // Restore refcount and save for adding back to list
            NdisInterlockedIncrement(&(pBSSEntry->RefCount));
            InsertTailList(&TempList, pListEntry);
        }
    }
    pDiscoveredBSSList->NumOfBSSEntries = 0;

    //
    // Restore entries that are in use
    //
    while (!IsListEmpty(&TempList))
    {
        pListEntry = RemoveHeadList(&TempList);

        InsertTailList(&(pDiscoveredBSSList->List), pListEntry);
        pDiscoveredBSSList->NumOfBSSEntries++;
    }

    // Since our scan list is flushed, also clear the last scan time
    HelperPort->ScanContext.LastScanTime = 0;
    
    MP_RELEASE_WRITE_LOCK(&(HelperPort->BSSList.ListLock), &LockState);

    return NDIS_STATUS_SUCCESS;
Exemple #7
0
VOID
HelperPortCancelScan(
    _In_  PMP_PORT                Port,
    _In_  PMP_PORT                RequestingPort
    )
{
    ULONG                       i;
    PMP_HELPER_PORT             helperPort = MP_GET_HELPPORT(Port);
    PMP_SCAN_PARAMETERS         scanParameters = NULL;
    MP_SCAN_STATE               preCancelState = SCAN_EMPTY_REQUEST;
    NDIS_STATUS                 ndisStatus;
    BOOLEAN                     timerCancelled = FALSE;

    // Add this scan request to the list
    MP_ACQUIRE_PORT_LOCK(Port, FALSE);

    // Search for the scan request in our list
    for (i = 0; i < MP_MAX_NUMBER_OF_PORT; i++)
    {
        if ((helperPort->ScanContext.ScanParameters[i].State != SCAN_EMPTY_REQUEST) && 
            (helperPort->ScanContext.ScanParameters[i].State != SCAN_COMPLETED) && 
            (helperPort->ScanContext.ScanParameters[i].RequestingPort == RequestingPort))
        {
            // The scan request from this port is in the queue
            scanParameters = &helperPort->ScanContext.ScanParameters[i];
            scanParameters->CancelScan = TRUE;

            // Add a refcount to ensure that the structure does not get deleted on us
            MP_INCREMENT_SCAN_PARAMETER_REF(scanParameters);

            preCancelState = scanParameters->State;

            // Save the previous state (for tracking)
            scanParameters->TrackingPreCancelState = preCancelState;
            
            if (preCancelState == SCAN_QUEUED_FOR_PROCESSING)
            {
                // This request is not yet activated for processing.
                // Remove the request from the pending scan list. This is done right now
                // with the lock held so that the request does not get requeued
                scanParameters->State = SCAN_REQUEST_IN_USE;
                MpTrace(COMP_SCAN, DBG_NORMAL, ("Canceling unprocessed scan request\n"));
            }
            else if (preCancelState == SCAN_EXCLUSIVE_ACCESS_QUEUED)
            {
                // We are unsure if the exclusive access request would
                // be granted or not. It would be granted if the cancel was part of
                // a pause or something. It would not be granted if this was
                // a halt
                MpTrace(COMP_SCAN, DBG_NORMAL, ("Canceling scan request waiting for exclusive access\n"));
            }

            break;
        }
    }

    MP_RELEASE_PORT_LOCK(Port, FALSE);

    if (scanParameters == NULL)
    {
        // No scan to cancel.
        return;
    }

    if (preCancelState != SCAN_QUEUED_FOR_PROCESSING)
    {
        // NOTE: Since we added the ref, we know that the ScanParameters buffer is available

        // If we have the timer running, force fire the timer
        timerCancelled = NdisCancelTimerObject(helperPort->ScanContext.Timer_Scan);
        if (timerCancelled == TRUE)
        {
            // We cancelled the timer, so we would need to invoke the complete ourselves
            MpTrace(COMP_SCAN, DBG_NORMAL, ("Canceling scan request waiting for scan timer\n"));
            HelperPortScanTimerCallback(helperPort);
        }
        else
        {
            // We could be waiting for exclusive access
            if (preCancelState == SCAN_EXCLUSIVE_ACCESS_QUEUED)
            {
                // We would complete the scan here. Because of the cancel flag, the
                // exclusive access routine would not proceed with the scan 
                // if it got called
                ndisStatus = NDIS_STATUS_REQUEST_ABORTED;

                MP_ACQUIRE_PORT_LOCK(HELPPORT_GET_MP_PORT(helperPort), FALSE);
                
                // Clear the active pointer
                helperPort->ScanContext.ActiveScanParameters = NULL;
                scanParameters->State = SCAN_COMPLETED;

                MP_RELEASE_PORT_LOCK(HELPPORT_GET_MP_PORT(helperPort), FALSE);

                // Now perform the indication
                HelperPortIndicateScanCompletion(helperPort, scanParameters, &ndisStatus);

                // We dont remove the reference here. We wait for the ex or the scan
                // to do it
            }

            // Ask the HW to cancel the scan (if it has it)
            VNic11CancelScan(HELPPORT_GET_VNIC(helperPort));
        }

        // Now wait for the scan complete to get indicated
        while (scanParameters->State != SCAN_COMPLETED)
        {
            MpTrace(COMP_SCAN, DBG_NORMAL, ("Waiting for scan operation to complete\n"));
            NdisMSleep(20 * 1000);
        }

        // This lock is acquired to ensure that the free here does not conflict with an
        // in progress scan completion
        MP_ACQUIRE_PORT_LOCK(Port, FALSE);
        HelperPortScanParametersReleaseRef(helperPort, scanParameters);
        MP_RELEASE_PORT_LOCK(Port, FALSE);

        // If there is a different second scan pending, process it
        HelperPortProcessPendingScans(helperPort);
    }
    else
    {
        // This scan was never started, we need to complete the scan request & we are done
        ndisStatus = NDIS_STATUS_REQUEST_ABORTED;
        HelperPortIndicateScanCompletion(helperPort, scanParameters, &ndisStatus);

        MP_ACQUIRE_PORT_LOCK(Port, FALSE);        
        scanParameters->State = SCAN_COMPLETED;        
        HelperPortScanParametersReleaseRef(helperPort, scanParameters);
        MP_RELEASE_PORT_LOCK(Port, FALSE);        
    }

}
Exemple #8
0
NDIS_STATUS
HelperPortHandleScan(
    _In_  PMP_PORT                Port,
    _In_  PMP_PORT                RequestingPort,
    _In_  PMP_SCAN_REQUEST        ScanRequest,
    _In_  PORT11_GENERIC_CALLBACK_FUNC    CompletionHandler
    )
{
    PMP_SCAN_PARAMETERS         scanParameters = NULL;
    // If we cannot find an empty slot, we return media in use
    NDIS_STATUS                 ndisStatus = NDIS_STATUS_DOT11_MEDIA_IN_USE; 
    PMP_HELPER_PORT             helperPort = MP_GET_HELPPORT(Port);
    ULONG                       i;

    do
    {
        // Add this scan request to the pending scan list
        MP_ACQUIRE_PORT_LOCK(Port, FALSE);

        // Find a structure we can use
        for (i = 0; i < MP_MAX_NUMBER_OF_PORT; i++)
        {
            if (helperPort->ScanContext.ScanParameters[i].State == SCAN_EMPTY_REQUEST)
            {
                scanParameters = &helperPort->ScanContext.ScanParameters[i];
                helperPort->ScanContext.ParametersCount++;

                MP_INCREMENT_SCAN_PARAMETER_REF(scanParameters);
                
                // Save the passed in information
                scanParameters->RequestingPort = RequestingPort;
                scanParameters->PortScanRequest = ScanRequest;
                scanParameters->CompletionHandler = CompletionHandler;

                // Scan would start at the first channel of the first phy
                scanParameters->NextChannelIndex = 0;
                scanParameters->CurrentPhyIndex = 0;

                // Queue it for processing
                scanParameters->CancelScan = 0;
                scanParameters->State = SCAN_QUEUED_FOR_PROCESSING;
                
                ndisStatus = NDIS_STATUS_SUCCESS;
                break;
            }
        }
        MP_RELEASE_PORT_LOCK(Port, FALSE);

        if (ndisStatus != NDIS_STATUS_SUCCESS)
        {
            MpTrace(COMP_SCAN, DBG_SERIOUS, ("Unable to save scan parameters\n"));    
            break;
        }

        // Let the scan request proceed
        HelperPortProcessPendingScans(helperPort);
    }while (FALSE);

    if (ndisStatus != NDIS_STATUS_SUCCESS)
    {
        // Free stuff that we may have allocated
        if (scanParameters != NULL)
        {
            // This cannot be left in our list
            HelperPortScanParametersReleaseRef(helperPort, scanParameters);
        }
    }
    
    return ndisStatus;
}