Ejemplo n.º 1
0
//
// Reset Step 1 - Cleanup any "pending" operations
//
VOID
Hw11NdisResetStep1(
    __in  PHW                     Hw
    )
{
    NDIS_STATUS                 ndisStatus = NDIS_STATUS_SUCCESS;

    // if we are being reset because our sends are hung, we do not want to assert. however
    // if sends are not the cause, we do want to assert.
    if (!Hw11ArePktsPending(Hw))
    {
        MPASSERT(FALSE);
    }
        
    //
    // Set state as in reset
    //
    HW_ACQUIRE_HARDWARE_LOCK(Hw, FALSE);
    HW_SET_ADAPTER_STATUS(Hw, HW_ADAPTER_IN_RESET);
    HW_RELEASE_HARDWARE_LOCK(Hw, FALSE);

    //
    // Now cleanup everything
    //

    // Cancel scan (if it is running)
    HwCancelScan(Hw);
    
    // Wait for pending operations in the hardware to finish
    HW_WAIT_FOR_ACTIVE_OPERATIONS_TO_FINISH(Hw);

    // Wait for active sends to be finish
    HW_WAIT_FOR_ACTIVE_SENDS_TO_FINISH(Hw);

    // Disable interrupts
    HwDisableInterrupt(Hw, HW_ISR_TRACKING_NDIS_RESET);

    ndisStatus = HalResetStart(Hw->Hal);
    MPASSERT(ndisStatus == NDIS_STATUS_SUCCESS);

    HalStop(Hw->Hal);    

    HwFlushSendEngine(Hw, FALSE);
    
    // Dont wait for pending receives here. They may be stuck in protocols on
    // sends & the sends may be queued in the ports. That would cause a deadlock
}
Ejemplo n.º 2
0
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;

}