Esempio n. 1
0
BOOLEAN
NICEvtInterruptIsr(
    IN WDFINTERRUPT Interrupt,
    IN ULONG        MessageID
    )
/*++
Routine Description:

    Interrupt handler for the device.

Arguments:

    Interupt - Address of the framework interrupt object
    MessageID -

Return Value:

     TRUE if our device is interrupting, FALSE otherwise.

--*/
{
    BOOLEAN    InterruptRecognized = FALSE;
    PFDO_DATA  FdoData = NULL;
    USHORT     IntStatus;

    UNREFERENCED_PARAMETER( MessageID );

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_INTERRUPT, "--> NICEvtInterruptIsr\n");

    FdoData = FdoGetData(WdfInterruptGetDevice(Interrupt));

    //
    // We process the interrupt if it's not disabled and it's active
    //
    if (!NIC_INTERRUPT_DISABLED(FdoData) && NIC_INTERRUPT_ACTIVE(FdoData))
    {
        InterruptRecognized = TRUE;

        //
        // Disable the interrupt (will be re-enabled in NICEvtInterruptDpc
        //
        NICDisableInterrupt(FdoData);

        //
        // Acknowledge the interrupt(s) and get the interrupt status
        //

        NIC_ACK_INTERRUPT(FdoData, IntStatus);

        WdfInterruptQueueDpcForIsr( Interrupt );

    }

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_INTERRUPT, "<-- NICEvtInterruptIsr\n");

    return InterruptRecognized;
}
Esempio n. 2
0
NTSTATUS
NICEvtInterruptDisable(
    IN WDFINTERRUPT  Interrupt,
    IN WDFDEVICE     AssociatedDevice
    )
/*++

Routine Description:

    This event is called before the Framework moves the device to D1, D2 or D3
    and before EvtDeviceD0Exit.  The driver should disable its interrupt here.

    This function will be called at the device's assigned interrupt
    IRQL (DIRQL.)

Arguments:

    Interrupt - Handle to a Framework interrupt object.

    AssociatedDevice - Handle to a Framework device object.

Return Value:

    STATUS_SUCCESS -  indicates success.

--*/
{
    PFDO_DATA           fdoData;

    UNREFERENCED_PARAMETER(Interrupt);
    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP, "--> NICEvtInterruptDisable\n");

    fdoData = FdoGetData(AssociatedDevice);
    NICDisableInterrupt(fdoData);

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP, "<-- NICEvtInterruptDisable\n");

    return STATUS_SUCCESS;
}
Esempio n. 3
0
int rt28xx_close(IN PNET_DEV dev)
{
	struct net_device * net_dev = (struct net_device *)dev;
    RTMP_ADAPTER	*pAd = net_dev->ml_priv;
	BOOLEAN 		Cancelled = FALSE;
	UINT32			i = 0;
#ifdef RT2870
	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(unlink_wakeup);
	DECLARE_WAITQUEUE(wait, current);

	
#endif 


    DBGPRINT(RT_DEBUG_TRACE, ("===> rt28xx_close\n"));

	
	if (pAd == NULL)
		return 0; 

	{
		
		
#ifdef RT2860
		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) ||
			RTMP_SET_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND) ||
			RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))
#endif
#ifdef RT2870
		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
#endif
        {
#ifdef RT2860
		    AsicForceWakeup(pAd, RTMP_HALT);
#endif
#ifdef RT2870
		    AsicForceWakeup(pAd, TRUE);
#endif
        }

		if (INFRA_ON(pAd) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
		{
			MLME_DISASSOC_REQ_STRUCT	DisReq;
			MLME_QUEUE_ELEM *MsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);

			COPY_MAC_ADDR(DisReq.Addr, pAd->CommonCfg.Bssid);
			DisReq.Reason =  REASON_DEAUTH_STA_LEAVING;

			MsgElem->Machine = ASSOC_STATE_MACHINE;
			MsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
			MsgElem->MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
			NdisMoveMemory(MsgElem->Msg, &DisReq, sizeof(MLME_DISASSOC_REQ_STRUCT));

			
			pAd->MlmeAux.AutoReconnectSsidLen= 32;
			NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);

			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
			MlmeDisassocReqAction(pAd, MsgElem);
			kfree(MsgElem);

			RTMPusecDelay(1000);
		}

#ifdef RT2870
	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
#endif 

#ifdef CCX_SUPPORT
		RTMPCancelTimer(&pAd->StaCfg.LeapAuthTimer, &Cancelled);
#endif

		RTMPCancelTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, &Cancelled);
		RTMPCancelTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, &Cancelled);

		MlmeRadioOff(pAd);
#ifdef RT2860
		pAd->bPCIclkOff = FALSE;
#endif
	}

	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);

	for (i = 0 ; i < NUM_OF_TX_RING; i++)
	{
		while (pAd->DeQueueRunning[i] == TRUE)
		{
			printk("Waiting for TxQueue[%d] done..........\n", i);
			RTMPusecDelay(1000);
		}
	}

#ifdef RT2870
	
	add_wait_queue (&unlink_wakeup, &wait);
	pAd->wait = &unlink_wakeup;

	
	i = 0;
	
	while(i < 25)
	{
		unsigned long IrqFlags;

		RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
		if (pAd->PendingRx == 0)
		{
			RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
			break;
		}
		RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);

		msleep(UNLINK_TIMEOUT_MS);	
		i++;
	}
	pAd->wait = NULL;
	remove_wait_queue (&unlink_wakeup, &wait);
#endif 

#ifdef RT2870
	
	RT2870_TimerQ_Exit(pAd);
	
	RT28xxThreadTerminate(pAd);
#endif 

	
	MlmeHalt(pAd);

	
	kill_thread_task(pAd);

	MacTableReset(pAd);

	MeasureReqTabExit(pAd);
	TpcReqTabExit(pAd);

#ifdef RT2860
	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE))
	{
		NICDisableInterrupt(pAd);
	}

	
	NICIssueReset(pAd);

	
	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
	{
		
		RT28XX_IRQ_RELEASE(net_dev)
		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
	}
#endif

	
	RTMPFreeTxRxRingMemory(pAd);

	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);

	
	ba_reordering_resource_release(pAd);

	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_START_UP);

	return 0; 
} 
Esempio n. 4
0
static int rt28xx_init(IN struct net_device *net_dev)
{
#ifdef RT2860
	PRTMP_ADAPTER 			pAd = (PRTMP_ADAPTER)net_dev->ml_priv;
#endif
#ifdef RT2870
	PRTMP_ADAPTER 			pAd = net_dev->ml_priv;
#endif
	UINT					index;
	UCHAR					TmpPhy;
	NDIS_STATUS				Status;
	UINT32 		MacCsr0 = 0;

	
	ba_reordering_resource_init(pAd, MAX_REORDERING_MPDU_NUM);

	
	index = 0;
	do
	{
		RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
		pAd->MACVersion = MacCsr0;

		if ((pAd->MACVersion != 0x00) && (pAd->MACVersion != 0xFFFFFFFF))
			break;

		RTMPusecDelay(10);
	} while (index++ < 100);

	DBGPRINT(RT_DEBUG_TRACE, ("MAC_CSR0  [ Ver:Rev=0x%08x]\n", pAd->MACVersion));


	
	RT28XXDMADisable(pAd);

	
	Status = NICLoadFirmware(pAd);
	if (Status != NDIS_STATUS_SUCCESS)
	{
		DBGPRINT_ERR(("NICLoadFirmware failed, Status[=0x%08x]\n", Status));
		goto err1;
	}

	NICLoadRateSwitchingParams(pAd);

	
	
#ifdef RT2860
	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE))
	{
		NICDisableInterrupt(pAd);
	}
#endif

	Status = RTMPAllocTxRxRingMemory(pAd);
	if (Status != NDIS_STATUS_SUCCESS)
	{
		DBGPRINT_ERR(("RTMPAllocDMAMemory failed, Status[=0x%08x]\n", Status));
		goto err1;
	}

	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);

	
	

	Status = MlmeInit(pAd);
	if (Status != NDIS_STATUS_SUCCESS)
	{
		DBGPRINT_ERR(("MlmeInit failed, Status[=0x%08x]\n", Status));
		goto err2;
	}

	
	
	UserCfgInit(pAd);

#ifdef RT2870
	
	RT2870_TimerQ_Init(pAd);
#endif 

	RT28XX_TASK_THREAD_INIT(pAd, Status);
	if (Status != NDIS_STATUS_SUCCESS)
		goto err1;

	CfgInitHook(pAd);

	NdisAllocateSpinLock(&pAd->MacTabLock);

	MeasureReqTabInit(pAd);
	TpcReqTabInit(pAd);

	
	
	
	Status = NICInitializeAdapter(pAd, TRUE);
	if (Status != NDIS_STATUS_SUCCESS)
	{
		DBGPRINT_ERR(("NICInitializeAdapter failed, Status[=0x%08x]\n", Status));
		if (Status != NDIS_STATUS_SUCCESS)
		goto err3;
	}

	
	Status = RTMPReadParametersHook(pAd);

	printk("1. Phy Mode = %d\n", pAd->CommonCfg.PhyMode);
	if (Status != NDIS_STATUS_SUCCESS)
	{
		DBGPRINT_ERR(("NICReadRegParameters failed, Status[=0x%08x]\n",Status));
		goto err4;
	}

#ifdef RT2870
	pAd->CommonCfg.bMultipleIRP = FALSE;

	if (pAd->CommonCfg.bMultipleIRP)
		pAd->CommonCfg.NumOfBulkInIRP = RX_RING_SIZE;
	else
		pAd->CommonCfg.NumOfBulkInIRP = 1;
#endif 


   	
	pAd->CommonCfg.DesiredHtPhy.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
	pAd->CommonCfg.DesiredHtPhy.AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable;
	pAd->CommonCfg.DesiredHtPhy.AmsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
	pAd->CommonCfg.DesiredHtPhy.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
	
	pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
	pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
	pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;

	printk("2. Phy Mode = %d\n", pAd->CommonCfg.PhyMode);

	
	NICReadEEPROMParameters(pAd, mac);

	printk("3. Phy Mode = %d\n", pAd->CommonCfg.PhyMode);

	NICInitAsicFromEEPROM(pAd); 

	
	TmpPhy = pAd->CommonCfg.PhyMode;
	pAd->CommonCfg.PhyMode = 0xff;
	RTMPSetPhyMode(pAd, TmpPhy);
	SetCommonHT(pAd);

	
	if (pAd->ChannelListNum == 0)
	{
		printk("Wrong configuration. No valid channel found. Check \"ContryCode\" and \"ChannelGeography\" setting.\n");
		goto err4;
	}

	printk("MCS Set = %02x %02x %02x %02x %02x\n", pAd->CommonCfg.HtCapability.MCSSet[0],
           pAd->CommonCfg.HtCapability.MCSSet[1], pAd->CommonCfg.HtCapability.MCSSet[2],
           pAd->CommonCfg.HtCapability.MCSSet[3], pAd->CommonCfg.HtCapability.MCSSet[4]);

#ifdef RT2870
    
	NICInitRT30xxRFRegisters(pAd);
#endif 


		
	
	
	AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
	AsicLockChannel(pAd, pAd->CommonCfg.Channel);

#ifndef RT2870
	
	AsicSendCommandToMcu(pAd, 0x72, 0xFF, 0x00, 0x00);
#endif

	if (pAd && (Status != NDIS_STATUS_SUCCESS))
	{
		
		
		
		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
		{
			RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
		}
	}
	else if (pAd)
	{
		
		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
		RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE);

		DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event B!\n"));


#ifdef RT2870
		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS);
		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);

		
		
		
		
		for(index=0; index<pAd->CommonCfg.NumOfBulkInIRP; index++)
		{
			RTUSBBulkReceive(pAd);
			DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkReceive!\n" ));
		}
#endif 
	}


	DBGPRINT_S(Status, ("<==== RTMPInitialize, Status=%x\n", Status));

	return TRUE;


err4:
err3:
	MlmeHalt(pAd);
err2:
	RTMPFreeTxRxRingMemory(pAd);
err1:
	os_free_mem(pAd, pAd->mpdu_blk_pool.mem); 
	RT28XX_IRQ_RELEASE(net_dev);

	
	

	printk("!!! %s Initialized fail !!!\n", RT28xx_CHIP_NAME);
	return FALSE;
} 
Esempio n. 5
0
BOOLEAN
MPSetPowerLowPrivate(
    PVOID Context
    )
/*++
Routine Description:

    The section follows the steps mentioned in
    Section C.2.6.2 of the Reference Manual.


Arguments:

    Adapter     Pointer to our adapter

Return Value:

--*/
{
    CSR_FILTER_STRUC    Filter;
    USHORT              IntStatus;
    MP_PMCSR            PMCSR = {0};
    ULONG               ulResult;
    PFDO_DATA FdoData = Context;

    DebugPrint(TRACE, DBG_POWER, "-->MPSetPowerLowPrivate\n");
    RtlZeroMemory (&Filter, sizeof (Filter));

    do
    {

        //
        // Before issue the command to low power state, we should disable the
        // interrup and ack all the pending interrupts, then set the adapter's power to
        // low state.
        //
        NICDisableInterrupt(FdoData);
        NIC_ACK_INTERRUPT(FdoData, IntStatus);

        //
        // If the driver should wake up the machine
        //
        if (FdoData->AllowWakeArming)
        {
            //
            // Send the WakeUp Patter to the nic
            MPIssueScbPoMgmtCommand(FdoData, &Filter, TRUE);


            //
            // Section C.2.6.2 - The driver needs to wait for the CU to idle
            // The above function already waits for the CU to idle
            //
            ASSERT ((FdoData->CSRAddress->ScbStatus & SCB_CUS_MASK) == SCB_CUS_IDLE);
        }
        else
        {

            ulResult = FdoData->BusInterface.GetBusData(
                                    FdoData->BusInterface.Context,
                                    PCI_WHICHSPACE_CONFIG,
                                    (PVOID)&PMCSR,
                                    FIELD_OFFSET(MP_PM_PCI_SPACE, PMCSR),
                                    sizeof(PMCSR));

            if(ulResult != sizeof(PMCSR)){
                ASSERT(ulResult == sizeof(PMCSR));
                DebugPrint(ERROR, DBG_POWER, "GetBusData for PMCSR failed\n");
                return FALSE;
            }
            if (PMCSR.PME_En == 1)
            {
                //
                // PME is enabled. Clear the PME_En bit.
                // So that it is not asserted
                //
                MpClearPME_En (FdoData,PMCSR);

            }

            //
            // Set the driver to lower power state by OS
            //
        }



    } while (FALSE);

    DebugPrint(TRACE, DBG_POWER, "<--MPSetPowerLowPrivate\n");

    return TRUE;
}
Esempio n. 6
0
NTSTATUS
NICReset(
    IN PFDO_DATA FdoData
    )
/*++

Routine Description:

    Function to reset the device.

Arguments:

    FdoData  Pointer to our adapter


Return Value:

    NT Status code.

Note:
    NICReset is called at DPC. Take advantage of this fact
    when acquiring or releasing spinlocks

--*/
{
    NTSTATUS                status;

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_DPC, "---> MPReset\n");


    WdfSpinLockAcquire(FdoData->Lock);

    WdfSpinLockAcquire(FdoData->SendLock);

    WdfSpinLockAcquire(FdoData->RcvLock);

    do
    {
        //
        // Is this adapter already doing a reset?
        //
        if (MP_TEST_FLAG(FdoData, fMP_ADAPTER_RESET_IN_PROGRESS))
        {
            status = STATUS_SUCCESS;
            goto exit;
        }

        MP_SET_FLAG(FdoData, fMP_ADAPTER_RESET_IN_PROGRESS);

        //
        // Is this adapter doing link detection?
        //
        if (MP_TEST_FLAG(FdoData, fMP_ADAPTER_LINK_DETECTION))
        {
            TraceEvents(TRACE_LEVEL_WARNING, DBG_DPC, "Reset is pended...\n");
            status = STATUS_SUCCESS;
            goto exit;
        }
        //
        // Is this adapter going to be removed
        //
        if (MP_TEST_FLAG(FdoData, fMP_ADAPTER_NON_RECOVER_ERROR))
        {
           status = STATUS_DEVICE_DATA_ERROR;
           if (MP_TEST_FLAG(FdoData, fMP_ADAPTER_REMOVE_IN_PROGRESS))
           {
               goto exit;
           }

           // This is an unrecoverable hardware failure.
           // We need to tell NDIS to remove this miniport
           MP_SET_FLAG(FdoData, fMP_ADAPTER_REMOVE_IN_PROGRESS);
           MP_CLEAR_FLAG(FdoData, fMP_ADAPTER_RESET_IN_PROGRESS);


           WdfSpinLockRelease(FdoData->RcvLock);

            WdfSpinLockRelease(FdoData->SendLock);

            WdfSpinLockRelease(FdoData->Lock);

           // TODO: Log an entry into the eventlog
           WdfDeviceSetFailed(FdoData->WdfDevice, WdfDeviceFailedAttemptRestart);

           TraceEvents(TRACE_LEVEL_FATAL, DBG_DPC, "<--- MPReset, status=%x\n", status);

           return status;
        }


        //
        // Disable the interrupt and issue a reset to the NIC
        //
        NICDisableInterrupt(FdoData);
        NICIssueSelectiveReset(FdoData);


        //
        // Release all the locks and then acquire back the send lock
        // we are going to clean up the send queues
        // which may involve calling Ndis APIs
        // release all the locks before grabbing the send lock to
        // avoid deadlocks
        //


         WdfSpinLockRelease(FdoData->RcvLock);

        WdfSpinLockRelease(FdoData->SendLock);

        WdfSpinLockRelease(FdoData->Lock);


        WdfSpinLockAcquire(FdoData->SendLock);

        //
        // Free the packets on SendQueueList
        //
        NICFreeQueuedSendPackets(FdoData);

        //
        // Free the packets being actively sent & stopped
        //
        NICFreeBusySendPackets(FdoData);


        RtlZeroMemory(FdoData->MpTcbMem, FdoData->MpTcbMemSize);

        //
        // Re-initialize the send structures
        //
        NICInitSendBuffers(FdoData);


        WdfSpinLockRelease(FdoData->SendLock);

        //
        // get all the locks again in the right order
        //


        WdfSpinLockAcquire(FdoData->Lock);

        WdfSpinLockAcquire(FdoData->SendLock);

        WdfSpinLockAcquire(FdoData->RcvLock);

        //
        // Reset the RFD list and re-start RU
        //
        NICResetRecv(FdoData);
        status = NICStartRecv(FdoData);
        if (status != STATUS_SUCCESS)
        {
            // Are we having failures in a few consecutive resets?
            if (FdoData->HwErrCount < NIC_HARDWARE_ERROR_THRESHOLD)
            {
                // It's not over the threshold yet, let it to continue
                FdoData->HwErrCount++;
            }
            else
            {
                // This is an unrecoverable hardware failure.
                // We need to tell NDIS to remove this miniport
                MP_SET_FLAG(FdoData, fMP_ADAPTER_REMOVE_IN_PROGRESS);
                MP_CLEAR_FLAG(FdoData, fMP_ADAPTER_RESET_IN_PROGRESS);



                WdfSpinLockRelease(FdoData->RcvLock);

                WdfSpinLockRelease(FdoData->SendLock);

                WdfSpinLockRelease(FdoData->Lock);

                // TODO: Log an entry into the eventlog
                //
                // Tell the system that the device has failed.
                //
                WdfDeviceSetFailed(FdoData->WdfDevice, WdfDeviceFailedAttemptRestart);

                TraceEvents(TRACE_LEVEL_ERROR, DBG_DPC, "<--- MPReset, status=%x\n", status);
                return(status);
            }

            break;
        }

        FdoData->HwErrCount = 0;
        MP_CLEAR_FLAG(FdoData, fMP_ADAPTER_HARDWARE_ERROR);

        NICEnableInterrupt(FdoData->WdfInterrupt, FdoData);

    } WHILE (FALSE);

    MP_CLEAR_FLAG(FdoData, fMP_ADAPTER_RESET_IN_PROGRESS);

    exit:


        WdfSpinLockRelease(FdoData->RcvLock);

        WdfSpinLockRelease(FdoData->SendLock);

        WdfSpinLockRelease(FdoData->Lock);



    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_DPC, "<--- MPReset, status=%x\n", status);
    return(status);
}