Ejemplo n.º 1
0
VOID
Hw11Restart(
    __in  PHW                     Hw
    )
{
    //
    // Clear the paused flag
    //
    HW_CLEAR_ADAPTER_STATUS(Hw, HW_ADAPTER_PAUSED);

    //
    // Reenable the disabled interrupts
    //
    
    //
    // If receives are available, we would temporarily enable the
    // RDU interrupt to ensure that we get interrupt again. Keeping this
    // interrupt on all the time would cause problems with Reset/Pause 
    // scenarios where we cannot empty the receive descriptors, and
    // so may keep getting interrupted
    //
    if (HwIsReceiveAvailable(Hw, FALSE))
    {
        //
        // New receives are available, but we didnt indicate
        // them in this interrupt. Enable RDU in IntrMask. This would be 
        // reset by the ClearInterrupt routine
        //
        HalInterlockedOrIntrMask(Hw->Hal, HAL_ISR_RX_DS_UNAVAILABLE);
    }    
//    MpTrace(COMP_TESTING, DBG_SERIOUS, ("Hw11Restart \n"));
    HwEnableInterrupt(Hw, HW_ISR_TRACKING_PAUSE);
}
Ejemplo n.º 2
0
NDIS_STATUS
Hw11Pause(
    __in  PHW                     Hw
    )
{
    //
    // Set the in progress flag. This would stop any new receives
    // from getting processed.
    //
    HW_ACQUIRE_HARDWARE_LOCK(Hw, FALSE);
    HW_SET_ADAPTER_STATUS(Hw, HW_ADAPTER_PAUSING);
    HW_RELEASE_HARDWARE_LOCK(Hw, FALSE);

    // 
    // Wait for any current send/receive interrupt handlers to finish. New ones
    // may increment the counter but would abort once they find the above flag
    // set
    //
    HW_WAIT_FOR_ACTIVE_OPERATIONS_TO_FINISH(Hw);

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

    // For performance reason we also disable the interrupt
//    MpTrace(COMP_TESTING, DBG_SERIOUS, ("Hw11Pause \n"));    
    HwDisableInterrupt(Hw, HW_ISR_TRACKING_PAUSE);

    HW_SET_ADAPTER_STATUS(Hw, HW_ADAPTER_PAUSED);
    HW_CLEAR_ADAPTER_STATUS(Hw, HW_ADAPTER_PAUSING);

    return NDIS_STATUS_SUCCESS;
}
Ejemplo n.º 3
0
VOID
Hw11CtxSComplete(
    __in  PHW                     Hw
    )
{
    //
    // Clear the in progress flag. This would let receive 
    //
    MpTrace(COMP_MISC, DBG_SERIOUS, ("H/W context switch completed"));
    
    HW_CLEAR_ADAPTER_STATUS(Hw, HW_ADAPTER_IN_CONTEXT_SWITCH);    
    return;
}
Ejemplo n.º 4
0
NDIS_STATUS
HwSetChannel(
    _In_  PHW                     Hw,
    _In_  ULONG                   PhyId,
    _In_  UCHAR                   Channel
    )
{
    // Must only be called for the active phy
    MPASSERT(PhyId == Hw->PhyState.OperatingPhyId);

    // When setting the channel, we dont check if we are not already on that 
    // channel. This is because this may be called after setting a PhyID and
    // that does not necessarily set the channel

    HW_ACQUIRE_HARDWARE_LOCK(Hw, FALSE);
    HW_SET_ADAPTER_STATUS(Hw, HW_ADAPTER_IN_CHANNEL_SWITCH);
    HW_RELEASE_HARDWARE_LOCK(Hw, FALSE);

    // Wait for active send threads to finish. We dont wait
    // for anything else on an HAL reset since some of those
    // operations themselves may be causing the reset (Eg. channel
    // switch of a scan)
    HW_WAIT_FOR_ACTIVE_SENDS_TO_FINISH(Hw);
//    MpTrace(COMP_TESTING, DBG_SERIOUS, ("HwSetChannel \n"));    
    HwDisableInterrupt(Hw, HW_ISR_TRACKING_CHANNEL);

    // Flush the sends
    HwFlushSendEngine(Hw, FALSE);

    HalSwitchChannel(Hw->Hal, 
        PhyId,
        Channel, 
        FALSE
        );

    HwResetSendEngine(Hw, FALSE);
    HwResetReceiveEngine(Hw, FALSE);
    HalStartReceive(Hw->Hal);
//    MpTrace(COMP_TESTING, DBG_SERIOUS, ("HwSetChannel \n"));    
    HwEnableInterrupt(Hw, HW_ISR_TRACKING_CHANNEL);

    HW_CLEAR_ADAPTER_STATUS(Hw, HW_ADAPTER_IN_CHANNEL_SWITCH);

    return NDIS_STATUS_SUCCESS;
}
Ejemplo n.º 5
0
//
// Reset Step 3 - Restart the hardware
//
NDIS_STATUS
Hw11NdisResetStep3(
    __in  PHW                     Hw,
    __out PBOOLEAN                AddressingReset
    )
{
    *AddressingReset = FALSE;

    HalStart(Hw->Hal, TRUE);
    
    // Push the new state on the hardware
    HwSetNicState(Hw);

    HalResetEnd(Hw->Hal);
    
    // Renable the interrupts
    HwEnableInterrupt(Hw, HW_ISR_TRACKING_NDIS_RESET);
    
    HW_CLEAR_ADAPTER_STATUS(Hw, HW_ADAPTER_IN_RESET);

    // TODO: Should we return NDIS_STATUS_HARD_ERRORS if we are hung
    
    return NDIS_STATUS_SUCCESS;
}
Ejemplo n.º 6
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;

}
Ejemplo n.º 7
0
NDIS_STATUS
HwResetHAL(
    __in  PHW                     Hw,
    __in  PHW_HAL_RESET_PARAMETERS ResetParams,
    __in  BOOLEAN                 DispatchLevel
    )
{
    UNREFERENCED_PARAMETER(ResetParams);
    UNREFERENCED_PARAMETER(DispatchLevel);

    MPASSERT(!DispatchLevel);

    // Since we wait, we cannot be called at dispatch    
    HW_ACQUIRE_HARDWARE_LOCK(Hw, FALSE);
    HW_SET_ADAPTER_STATUS(Hw, HW_ADAPTER_HAL_IN_RESET);
    HW_RELEASE_HARDWARE_LOCK(Hw, FALSE);

    // Wait for active send threads to finish. We dont wait
    // for anything else on an HAL reset since some of those
    // operations themselves may be causing the reset (Eg. channel
    // switch of a scan)
    HW_WAIT_FOR_ACTIVE_SENDS_TO_FINISH(Hw);
    HwDisableInterrupt(Hw, HW_ISR_TRACKING_HAL_RESET);

    if (ResetParams->FullReset)
    {
        // Perform a full reset of the HW
        HalResetStart(Hw->Hal);

        HalStop(Hw->Hal);    

        // Reset the send and receive engine
        HwWaitForPendingReceives(Hw, NULL);
        HwResetSendEngine(Hw, FALSE);
        HwResetReceiveEngine(Hw, FALSE);
        // Remove old keys, etc
        HwClearNicState(Hw);
        
        // Reset our MAC & PHY state
        HwResetSoftwareMacState(Hw);
        HwResetSoftwarePhyState(Hw);

        HalStart(Hw->Hal, TRUE);
        
        // Push the new state on the hardware
        HwSetNicState(Hw);

        HalResetEnd(Hw->Hal);
    }
    else
    {
        // TODO: Currently we are overloading the HalSwitchChannel API for doing a HalReset
        HalSwitchChannel(Hw->Hal, 
            Hw->PhyState.OperatingPhyId,
            HalGetPhyMIB(Hw->Hal, Hw->PhyState.OperatingPhyId)->Channel, 
            FALSE
            );

        HwResetReceiveEngine(Hw, FALSE);
        HwResetSendEngine(Hw, FALSE);
        HalStartReceive(Hw->Hal);
    }
    HwEnableInterrupt(Hw, HW_ISR_TRACKING_HAL_RESET);

    HW_CLEAR_ADAPTER_STATUS(Hw, HW_ADAPTER_HAL_IN_RESET);

    return NDIS_STATUS_SUCCESS;
}