예제 #1
0
파일: hw_phy.c 프로젝트: 340211173/Driver
// Called at PASSIVE, DISPATCH & DIRQL
// Returns TRUE if at the end of the call, the new state of the RF is the requested
// state, returns FALSE otherwise
BOOLEAN
HwSetRFState(
    _In_  PHW                     Hw,
    _In_  UCHAR	                NewRFState
    )
{
    BOOLEAN                     result = TRUE;
    
    do
    {
        if (InterlockedIncrement(&Hw->PhyState.RadioAccessRef) == 1)
        {
            if (Hw->PhyState.RadioStateChangeInProgress)
            {
                // Radio state is being changed, dont proceed
                result = FALSE;
                break;
            }
            
            if ((NewRFState == RF_ON) || (NewRFState == RF_SLEEP))
            {
                if (Hw->PhyState.SoftwareRadioOff == TRUE)
                {
                    // Radio is OFF, dont change RF state
                    result = FALSE;
                    break;
                }
            }
            
            HalSetRFPowerState(Hw->Hal, NewRFState);
        }
        else
        {
            // Another thread is changing RF/Radio state,
            // dont modify. We bail out and the caller can decide if it wants to
            // reattempt (we dont wait since we may be called at high IRQL, etc)
            MpTrace(COMP_POWER, DBG_LOUD, ("Unable to set RF/Radio state as something else is updating it\n"));
            result = FALSE;
        }
    }while (FALSE);

    InterlockedDecrement(&Hw->PhyState.RadioAccessRef);
    
    return result;
}
예제 #2
0
파일: hw_phy.c 프로젝트: 340211173/Driver
NDIS_STATUS
HwSetNicPowerState(
    _In_  PHW                     Hw,
    _In_  ULONG                   PhyId,
    _In_  BOOLEAN                 PowerOn
    )
{
    NDIS_STATUS                 ndisStatus = NDIS_STATUS_SUCCESS;
    HW_HAL_RESET_PARAMETERS     resetParams;

    //
    // Our RF cannot be selectively turned on/off. We turn on or turn off all the phys
    // anytime this OID is set
    //
    UNREFERENCED_PARAMETER(PhyId);
    //
    // Check if we are already in the specified state.
    //
    if (Hw->PhyState.SoftwareRadioOff == !PowerOn)
    {
        // No need to take status indications if we are
        // already in the correct state
        return NDIS_STATUS_SUCCESS;
    }

    if (!PowerOn)
    {
        //
        // Going to power save. Get everything into a stable state
        //
        
        //
        // If a scan is in progress, cancel scan
        //
        if (Hw->ScanContext.ScanInProgress)
        {
            HwCancelScan(Hw);
        }

        //
        // Before we turn off the radio, we reset the h/w. 
        // This is to ensure that there isnt any pending operation sitting 
        // on the hardware
        //
        NdisZeroMemory(&resetParams, sizeof(HW_HAL_RESET_PARAMETERS));
        HwResetHAL(Hw, &resetParams, FALSE);

        //
        // Disable the interrupt
        //
        HwDisableInterruptWithSync(Hw, HW_ISR_TRACKING_RADIO_STATE);

        HW_ACQUIRE_HARDWARE_LOCK(Hw, FALSE);
        HW_SET_ADAPTER_STATUS(Hw, HW_ADAPTER_RADIO_OFF);
        HW_RELEASE_HARDWARE_LOCK(Hw, FALSE);
        
    }
    
    //
    // Update Radio state
    //

    // Set flag so other threads (power save, scan timer, etc) wont change
    // state behind us
    Hw->PhyState.RadioStateChangeInProgress = TRUE;

    // We wait for ever for other threads to not reach this state
    while (Hw->PhyState.RadioAccessRef != 0);

    //
    // Set the Radio state
    //
    if (PowerOn)
    {
        Hw->PhyState.Debug_SoftwareRadioOff = FALSE;
        HalSetRFPowerState(Hw->Hal, RF_ON);
        Hw->PhyState.SoftwareRadioOff = FALSE;        
    }
    else
    {
        Hw->PhyState.SoftwareRadioOff = TRUE;
        HalSetRFPowerState(Hw->Hal, RF_SHUT_DOWN);
        Hw->PhyState.Debug_SoftwareRadioOff = TRUE;
    }

    Hw->PhyState.RadioStateChangeInProgress = FALSE;

    if (PowerOn)
    {
        // Clear the radio off bit
        HW_ACQUIRE_HARDWARE_LOCK(Hw, FALSE);
        HW_CLEAR_ADAPTER_STATUS(Hw, HW_ADAPTER_RADIO_OFF);
        HW_RELEASE_HARDWARE_LOCK(Hw, FALSE);
    
        // Re-reset the H/W to get it into a good state
        NdisZeroMemory(&resetParams, sizeof(HW_HAL_RESET_PARAMETERS));
        resetParams.FullReset = TRUE;
        HwResetHAL(Hw, &resetParams, FALSE);

        //
        // Reenable the interrupt
        //
        HwEnableInterruptWithSync(Hw, HW_ISR_TRACKING_RADIO_STATE);
    }

    //
    // Save the new radio state in the registry
    //
    ndisStatus = HwPersistRadioPowerState(Hw, Hw->PhyState.SoftwareRadioOff);
    if (ndisStatus != NDIS_STATUS_SUCCESS)
    {
        MpTrace(COMP_OID, DBG_SERIOUS, ("Unable to persist new radio state in the registry\n"));
        return ndisStatus;
    }

    //
    // Report the new power state to the OS
    //    
    HwIndicatePhyPowerState(
        Hw,
        DOT11_PHY_ID_ANY
        );
    return ndisStatus;

}
예제 #3
0
파일: hw_main.c 프로젝트: kcrazy/winekit
NDIS_STATUS
Hw11Start(
    __in  PHW                     Hw,
    __out NDIS_ERROR_CODE*        ErrorCode,
    __out PULONG                  ErrorValue
    )
{
    NDIS_STATUS                 ndisStatus = NDIS_STATUS_SUCCESS;
    BOOLEAN                     interruptRegistered = FALSE, hardwareStarted = FALSE;
    
    //
    // Disable interrupts
    // We should disable interrupts before the are registered.
    // They will be enabled right at the end of Initialize
    //
    HwDisableInterrupt(Hw, HW_ISR_TRACKING_HWSTART);

    do
    {
        //
        // Register interrupt with NDIS
        //
        ndisStatus = HwRegisterInterrupt(
                        Hw,
                        ErrorCode, 
                        ErrorValue
                        );
        if (ndisStatus != NDIS_STATUS_SUCCESS)
        {
            MpTrace(COMP_INIT_PNP, DBG_SERIOUS, ("Failed to register interrupt with NDIS\n"));
            break;
        }
        interruptRegistered = TRUE;
        
        Hw->PhyState.Debug_SoftwareRadioOff = Hw->PhyState.SoftwareRadioOff;
        if (Hw->PhyState.SoftwareRadioOff)
        {
            HalSetRFPowerState(Hw->Hal, RF_SHUT_DOWN);
        }
        else
        {
            HalSetRFPowerState(Hw->Hal, RF_ON);
        }

        //
        // Start the HAL. If anything fails after this point,
        // we must issue a Halt to the HAL before returning
        // from initialize
        //
        ndisStatus = HalStart(Hw->Hal, FALSE);
        if(ndisStatus != NDIS_STATUS_SUCCESS)
        {
            MpTrace(COMP_INIT_PNP, DBG_SERIOUS, ("Failed to start HAL successfully.\n"));
            break;
        }
        hardwareStarted = TRUE;
        
        // Enable the interrupts on the hardware
        HwEnableInterrupt(Hw, HW_ISR_TRACKING_HWSTART);
                
    }while (FALSE);

    if (ndisStatus != NDIS_STATUS_SUCCESS)
    {
        // Disable interrupts and deregister them first
        HwDisableInterrupt(Hw, HW_ISR_TRACKING_HWSTART);
        
        if (interruptRegistered)
            HwDeregisterInterrupt(Hw);

        if (hardwareStarted)
        {
            HalStop(Hw->Hal);
            HalHaltNic(Hw->Hal);
        }
    }

    return ndisStatus;
}