示例#1
0
/*
========================================================================
Routine Description:
    MLME kernel thread.

Arguments:
	*Context			the pAd, driver control block pointer

Return Value:
    0					close the thread

Note:
========================================================================
*/
INT MlmeThread(
    IN ULONG Context)
{
    RTMP_ADAPTER *pAd;
    RTMP_OS_TASK *pTask;
    int status;
    status = 0;

    pTask = (RTMP_OS_TASK *)Context;
    pAd = (PRTMP_ADAPTER)pTask->priv;

    RtmpOSTaskCustomize(pTask);

    while(!pTask->task_killed)
    {
#ifdef KTHREAD_SUPPORT
        RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask);
#else
        RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status);

        /* unlock the device pointers */
        if (status != 0)
        {
            RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
            break;
        }
#endif

        /* lock the device pointers , need to check if required*/
        //down(&(pAd->usbdev_semaphore));

        if (!pAd->PM_FlgSuspend)
            MlmeHandler(pAd);
    }

    /* notify the exit routine that we're actually exiting now
     *
     * complete()/wait_for_completion() is similar to up()/down(),
     * except that complete() is safe in the case where the structure
     * is getting deleted in a parallel mode of execution (i.e. just
     * after the down() -- that's necessary for the thread-shutdown
     * case.
     *
     * complete_and_exit() goes even further than this -- it is safe in
     * the case that the thread of the caller is going away (not just
     * the structure) -- this is necessary for the module-remove case.
     * This is important in preemption kernels, which transfer the flow
     * of execution immediately upon a complete().
     */
    DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__FUNCTION__));
#ifndef KTHREAD_SUPPORT
    pTask->taskPID = THREAD_PID_INIT_VALUE;
    complete_and_exit (&pTask->taskComplete, 0);
#endif
    return 0;

}
/*
	========================================================================

	Routine Description: Read 8-bit BBP register via firmware

	Arguments:

	Return Value:

	IRQL =

	Note:

	========================================================================
*/
NTSTATUS	RTUSBReadBBPRegister(
	IN	PRTMP_ADAPTER	pAd,
	IN	UCHAR			Id,
	IN	PUCHAR			pValue)
{
	BBP_CSR_CFG_STRUC BbpCsr;
	int i, k, ret;


	RTMP_SEM_EVENT_WAIT(&pAd->reg_atomic, ret);
	if (ret != 0)
	{
		DBGPRINT(RT_DEBUG_ERROR, ("reg_atomic get failed(ret=%d)\n", ret));
		return STATUS_UNSUCCESSFUL;
	}

	for (i=0; i<MAX_BUSY_COUNT; i++)
	{
		RTUSBReadMACRegister(pAd, H2M_BBP_AGENT, &BbpCsr.word);
		if (BbpCsr.field.Busy == BUSY)
			continue;

		BbpCsr.word = 0;
		BbpCsr.field.fRead = 1;
		BbpCsr.field.BBP_RW_MODE = 1;
		BbpCsr.field.Busy = 1;
		BbpCsr.field.RegNum = Id;
		RTUSBWriteMACRegister(pAd, H2M_BBP_AGENT, BbpCsr.word, FALSE);
		AsicSendCommandToMcu(pAd, 0x80, 0xff, 0x0, 0x0, TRUE);
		for (k=0; k<MAX_BUSY_COUNT; k++)
		{
			RTUSBReadMACRegister(pAd, H2M_BBP_AGENT, &BbpCsr.word);
			if (BbpCsr.field.Busy == IDLE)
				break;
		}
		if ((BbpCsr.field.Busy == IDLE) &&
			(BbpCsr.field.RegNum == Id))
		{
			*pValue = (UCHAR)BbpCsr.field.Value;
			break;
		}
	}

	RTMP_SEM_EVENT_UP(&pAd->reg_atomic);
	
	if (BbpCsr.field.Busy == BUSY)
	{
		DBGPRINT_ERR(("BBP read R%d=0x%x fail\n", Id, BbpCsr.word));
		*pValue = pAd->BbpWriteLatch[Id];
		return STATUS_UNSUCCESSFUL;
	}
	return STATUS_SUCCESS;
}
/*
	========================================================================
	
	Routine Description: Write 8-bit BBP register

	Arguments:

	Return Value:
	
	IRQL = 
	
	Note:
	
	========================================================================
*/
NTSTATUS	RTUSBWriteBBPRegister(
	IN	PRTMP_ADAPTER	pAd,
	IN	UCHAR			Id,
	IN	UCHAR			Value)
{
	BBP_CSR_CFG_STRUC	BbpCsr;
	UINT			i = 0;
	NTSTATUS		status;
	int				RET = 0;

	RTMP_SEM_EVENT_WAIT(&(pAd->UsbVendorReq_semaphore2), RET);
	
	/* Verify the busy condition*/
	do
	{
		status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word);
		if (status >= 0)
		{
		if (!(BbpCsr.field.Busy == BUSY))
			break;
		}
		DBGPRINT(RT_DEBUG_TRACE, ("RTUSBWriteBBPRegister(BBP_CSR_CFG):retry count=%d!\n", i));
		i++;
	}
	while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
	
	if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
	{
		DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
		RTMP_SEM_EVENT_UP(&(pAd->UsbVendorReq_semaphore2));
		return STATUS_UNSUCCESSFUL;
	}

	/* Prepare for write material*/
	BbpCsr.word 				= 0;
	BbpCsr.field.fRead			= 0;
	BbpCsr.field.Value			= Value;
	BbpCsr.field.Busy			= 1;
	BbpCsr.field.RegNum 		= Id;
	RTUSBWriteMACRegister(pAd, BBP_CSR_CFG, BbpCsr.word);
	
	pAd->BbpWriteLatch[Id] = Value;
	RTMP_SEM_EVENT_UP(&(pAd->UsbVendorReq_semaphore2));

	return STATUS_SUCCESS;
}
/*
	========================================================================

	Routine Description: Write RF register through MAC

	Arguments:

	Return Value:

	IRQL =

	Note:

	========================================================================
*/
NTSTATUS	RTUSBWriteRFRegister(
	IN	PRTMP_ADAPTER	pAd,
	IN	UINT32			Value)
{
	PHY_CSR4_STRUC	PhyCsr4;
	UINT			i = 0;
	NTSTATUS		status;

	NdisZeroMemory(&PhyCsr4, sizeof(PHY_CSR4_STRUC));

	RTMP_SEM_EVENT_WAIT(&pAd->reg_atomic, status);
	if (status != 0) {
		DBGPRINT(RT_DEBUG_ERROR, ("reg_atomic get failed(ret=%d)\n", status));
		return STATUS_UNSUCCESSFUL;
	}

	status = STATUS_UNSUCCESSFUL;
	do
	{
		status = RTUSBReadMACRegister(pAd, RF_CSR_CFG0, &PhyCsr4.word);
		if (status >= 0)
		{
		if (!(PhyCsr4.field.Busy))
			break;
		}
		DBGPRINT(RT_DEBUG_TRACE, ("RTUSBWriteRFRegister(RF_CSR_CFG0):retry count=%d!\n", i));
		i++;
	}
	while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));

	if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
	{
		DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
		goto done;
	}

	RTUSBWriteMACRegister(pAd, RF_CSR_CFG0, Value, FALSE);
	status = STATUS_SUCCESS;

done:
	RTMP_SEM_EVENT_UP(&pAd->reg_atomic);
	
	return status;
}
NTSTATUS	RTUSBWriteBBPRegister(
	IN	PRTMP_ADAPTER	pAd,
	IN	UCHAR			Id,
	IN	UCHAR			Value)

{
	BBP_CSR_CFG_STRUC BbpCsr;
	int BusyCnt;
	int ret;

	RTMP_SEM_EVENT_WAIT(&pAd->reg_atomic, ret);
	if (ret != 0)
	{
		DBGPRINT(RT_DEBUG_ERROR, ("reg_atomic get failed(ret=%d)\n", ret));
		return STATUS_UNSUCCESSFUL;
	}

	for (BusyCnt=0; BusyCnt<MAX_BUSY_COUNT; BusyCnt++)
	{
		RTMP_IO_READ32(pAd, H2M_BBP_AGENT, &BbpCsr.word);
		if (BbpCsr.field.Busy == BUSY)
			continue;
		BbpCsr.word = 0;
		BbpCsr.field.fRead = 0;
		BbpCsr.field.BBP_RW_MODE = 1;
		BbpCsr.field.Busy = 1;
		BbpCsr.field.Value = Value;
		BbpCsr.field.RegNum = Id;
		RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, BbpCsr.word);
		AsicSendCommandToMcu(pAd, 0x80, 0xff, 0x0, 0x0, TRUE);
		pAd->BbpWriteLatch[Id] = Value;
		break;
	}

	RTMP_SEM_EVENT_UP(&pAd->reg_atomic);
	
	if (BusyCnt == MAX_BUSY_COUNT)
	{
		DBGPRINT_ERR(("BBP write R%d=0x%x fail\n", Id, BbpCsr.word));
		return STATUS_UNSUCCESSFUL;
	}
	return STATUS_SUCCESS;
}
示例#6
0
static void RtmpTimerQHandle(RTMP_ADAPTER *pAd)
{
#ifndef KTHREAD_SUPPORT
	int status;
#endif
	RALINK_TIMER_STRUCT	*pTimer;
	RTMP_TIMER_TASK_ENTRY	*pEntry;
	unsigned long	irqFlag;
	RTMP_OS_TASK *pTask;


	pTask = &pAd->timerTask;
	while(!pTask->task_killed)
	{
		pTimer = NULL;

#ifdef KTHREAD_SUPPORT
		RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask);
#else
		RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status);
#endif

		if (pAd->TimerQ.status == RTMP_TASK_STAT_STOPED)
			break;
		
		// event happened.
		while(pAd->TimerQ.pQHead)
		{
			RTMP_INT_LOCK(&pAd->TimerQLock, irqFlag);
			pEntry = pAd->TimerQ.pQHead;
			if (pEntry)
			{
				pTimer = pEntry->pRaTimer;

				// update pQHead
				pAd->TimerQ.pQHead = pEntry->pNext;
				if (pEntry == pAd->TimerQ.pQTail)
					pAd->TimerQ.pQTail = NULL;
			
				// return this queue entry to timerQFreeList.
				pEntry->pNext = pAd->TimerQ.pQPollFreeList;
				pAd->TimerQ.pQPollFreeList = pEntry;
			}
			RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlag);

			if (pTimer)
			{
				if ((pTimer->handle != NULL) && (!pAd->PM_FlgSuspend))
					pTimer->handle(NULL, (PVOID) pTimer->cookie, NULL, pTimer);
				if ((pTimer->Repeat) && (pTimer->State == FALSE))
					RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue);
			}
		}
		
#ifndef KTHREAD_SUPPORT
		if (status != 0)
		{
			pAd->TimerQ.status = RTMP_TASK_STAT_STOPED;
			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
			break;
		}
#endif
	}
}
示例#7
0
/*
========================================================================
Routine Description:
    USB command kernel thread.

Arguments:
	*Context			the pAd, driver control block pointer

Return Value:
    0					close the thread

Note:
========================================================================
*/
INT RTUSBCmdThread(
    IN ULONG Context)
{
    RTMP_ADAPTER *pAd;
    RTMP_OS_TASK *pTask;
    int status;
    status = 0;

    pTask = (RTMP_OS_TASK *)Context;
    pAd = (PRTMP_ADAPTER)pTask->priv;

    RtmpOSTaskCustomize(pTask);

    NdisAcquireSpinLock(&pAd->CmdQLock);
    pAd->CmdQ.CmdQState = RTMP_TASK_STAT_RUNNING;
    NdisReleaseSpinLock(&pAd->CmdQLock);

    while (pAd && pAd->CmdQ.CmdQState == RTMP_TASK_STAT_RUNNING)
    {
#ifdef KTHREAD_SUPPORT
        RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask);
#else
        /* lock the device pointers */
        RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status);

        if (status != 0)
        {
            RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
            break;
        }
#endif

        if (pAd->CmdQ.CmdQState == RTMP_TASK_STAT_STOPED)
            break;

        if (!pAd->PM_FlgSuspend)
            CMDHandler(pAd);
    }

    if (pAd && !pAd->PM_FlgSuspend)
    {   // Clear the CmdQElements.
        CmdQElmt	*pCmdQElmt = NULL;

        NdisAcquireSpinLock(&pAd->CmdQLock);
        pAd->CmdQ.CmdQState = RTMP_TASK_STAT_STOPED;
        while(pAd->CmdQ.size)
        {
            RTThreadDequeueCmd(&pAd->CmdQ, &pCmdQElmt);
            if (pCmdQElmt)
            {
                if (pCmdQElmt->CmdFromNdis == TRUE)
                {
                    if (pCmdQElmt->buffer != NULL)
                        os_free_mem(pAd, pCmdQElmt->buffer);
                    os_free_mem(pAd, (PUCHAR)pCmdQElmt);
                }
                else
                {
                    if ((pCmdQElmt->buffer != NULL) && (pCmdQElmt->bufferlength != 0))
                        os_free_mem(pAd, pCmdQElmt->buffer);
                    os_free_mem(pAd, (PUCHAR)pCmdQElmt);
                }
            }
        }

        NdisReleaseSpinLock(&pAd->CmdQLock);
    }
    /* notify the exit routine that we're actually exiting now
     *
     * complete()/wait_for_completion() is similar to up()/down(),
     * except that complete() is safe in the case where the structure
     * is getting deleted in a parallel mode of execution (i.e. just
     * after the down() -- that's necessary for the thread-shutdown
     * case.
     *
     * complete_and_exit() goes even further than this -- it is safe in
     * the case that the thread of the caller is going away (not just
     * the structure) -- this is necessary for the module-remove case.
     * This is important in preemption kernels, which transfer the flow
     * of execution immediately upon a complete().
     */
    DBGPRINT(RT_DEBUG_TRACE,( "<---RTUSBCmdThread\n"));

#ifndef KTHREAD_SUPPORT
    pTask->taskPID = THREAD_PID_INIT_VALUE;
    complete_and_exit (&pTask->taskComplete, 0);
#endif
    return 0;

}
示例#8
0
NDIS_STATUS rlt_rf_write(
    IN PRTMP_ADAPTER pAd,
    IN UCHAR bank,
    IN UCHAR regID,
    IN UCHAR value)
{
    RF_CSR_CFG_STRUC rfcsr = { { 0 } };
    NDIS_STATUS	 ret;

#ifdef RTMP_MAC_PCI
    if ((pAd->bPCIclkOff == TRUE) || (pAd->LastMCUCmd == SLEEP_MCU_CMD))
    {
        DBGPRINT_ERR(("rlt_rf_write. Not allow to write RF 0x%x : fail\n",  regID));
        return STATUS_UNSUCCESSFUL;
    }
#endif /* RTMP_MAC_PCI */

#ifdef RLT_MAC
    // TODO: shiang-usw, why we need to check this for MT7601?? Get these code from MT7601!
    if (pAd->chipCap.hif_type == HIF_RLT) {
        if (pAd->WlanFunCtrl.field.WLAN_EN == 0)
        {
            DBGPRINT_ERR(("rlt_rf_write. Not allow to write RF 0x%x : fail\n",  regID));
            return STATUS_UNSUCCESSFUL;
        }
    }
#endif /* RLT_MAC */

#ifdef RTMP_MAC_USB
    if (IS_USB_INF(pAd)) {
        RTMP_SEM_EVENT_WAIT(&pAd->reg_atomic, ret);
        if (ret != 0) {
            DBGPRINT(RT_DEBUG_ERROR, ("reg_atomic get failed(ret=%d)\n", ret));
            return STATUS_UNSUCCESSFUL;
        }
    }
#endif /* RTMP_MAC_USB */

    ASSERT((regID <= pAd->chipCap.MaxNumOfRfId));

    ret = STATUS_UNSUCCESSFUL;
    if (rf_csr_poll_idle(pAd, &rfcsr.word) != IDLE)
        goto done;

#ifdef RT6352
    if (IS_RT6352(pAd))
    {
        rfcsr.bank_6352.RF_CSR_WR = 1;
        rfcsr.bank_6352.RF_CSR_KICK = 1;
        rfcsr.bank_6352.TESTCSR_RFACC_REGNUM = (regID | (bank << 6));
        rfcsr.bank_6352.RF_CSR_DATA = value;
    }
    else
#endif /* RT6352 */
#ifdef RT65xx
        if (IS_RT65XX(pAd)) {
            rfcsr.bank_65xx.RF_CSR_WR = 1;
            rfcsr.bank_65xx.RF_CSR_KICK = 1;
            rfcsr.bank_65xx.RF_CSR_REG_BANK = bank;
            rfcsr.bank_65xx.RF_CSR_REG_ID = regID;
            rfcsr.bank_65xx.RF_CSR_DATA = value;
        }
        else
#endif /* RT65xx */
        {
            DBGPRINT_ERR(("%s():RF write with wrong handler!\n", __FUNCTION__));
            goto done;
        }
    RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);

    ret = NDIS_STATUS_SUCCESS;

done:
#ifdef RTMP_MAC_USB
    if (IS_USB_INF(pAd)) {
        RTMP_SEM_EVENT_UP(&pAd->reg_atomic);
    }
#endif /* RTMP_MAC_USB */

    return ret;
}
示例#9
0
/*
	========================================================================

	Routine Description: Read RF register through MAC

	Arguments:

	Return Value:

	IRQL =

	Note:

	========================================================================
*/
NDIS_STATUS rlt_rf_read(
    IN RTMP_ADAPTER *pAd,
    IN UCHAR bank,
    IN UCHAR regID,
    IN UCHAR *pValue)
{
    RF_CSR_CFG_STRUC rfcsr = { { 0 } };
    UINT i=0, k=0;
    BOOLEAN rf_status;
    NDIS_STATUS	 ret = STATUS_UNSUCCESSFUL;

#ifdef MT76x0
    if (IS_MT7610U(pAd)) {
        BANK_RF_REG_PAIR reg;
        reg.Bank = bank;
        reg.Register = regID;
        RF_RANDOM_READ(pAd, &reg, 1);

        *pValue = reg.Value;
        return NDIS_STATUS_SUCCESS;
    }
#endif /* MT76x0 */

#ifdef RTMP_MAC_PCI
    if ((pAd->bPCIclkOff == TRUE) || (pAd->LastMCUCmd == SLEEP_MCU_CMD))
    {
        DBGPRINT_ERR(("RT30xxReadRFRegister. Not allow to read RF 0x%x : fail\n",  regID));
        return STATUS_UNSUCCESSFUL;
    }
#endif /* RTMP_MAC_PCI */

#ifdef RTMP_MAC_USB
    if (IS_USB_INF(pAd)) {
        RTMP_SEM_EVENT_WAIT(&pAd->reg_atomic, i);
        if (i != 0) {
            DBGPRINT(RT_DEBUG_ERROR, ("reg_atomic get failed(ret=%d)\n", i));
            return STATUS_UNSUCCESSFUL;
        }
    }
#endif /* RTMP_MAC_USB */

    ASSERT((regID <= pAd->chipCap.MaxNumOfRfId));

    rfcsr.word = 0;

    for (i=0; i<MAX_BUSY_COUNT; i++)
    {
        if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
            goto done;

        rf_status = rf_csr_poll_idle(pAd, &rfcsr.word);
        if ( rf_status == BUSY)
            break;

        rfcsr.word = 0;
#ifdef RT6352
        if (IS_RT6352(pAd))
        {
            rfcsr.bank_6352.RF_CSR_WR = 0;
            rfcsr.bank_6352.RF_CSR_KICK = 1;
            rfcsr.bank_6352.TESTCSR_RFACC_REGNUM = (regID | (bank << 6));
        }
        else
#endif /* RT6352 */
#ifdef RT65xx
            if (IS_RT65XX(pAd)) {
                rfcsr.bank_65xx.RF_CSR_WR = 0;
                rfcsr.bank_65xx.RF_CSR_KICK = 1;
                rfcsr.bank_65xx.RF_CSR_REG_ID = regID;
                rfcsr.bank_65xx.RF_CSR_REG_BANK = bank;
            }
            else
#endif /* RT65xx */
            {
                DBGPRINT_ERR(("RF[%d] read function for non-supported chip[0x%x]\n", regID, pAd->MACVersion));
                break;
            }

        RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);

        rf_status = rf_csr_poll_idle(pAd, &rfcsr.word);
        if (rf_status == IDLE)
        {
#ifdef RT6352
            if (IS_RT6352(pAd) && ((rfcsr.bank_6352.TESTCSR_RFACC_REGNUM & 0x3F) == regID))
            {
                *pValue = (UCHAR)(rfcsr.bank_6352.RF_CSR_DATA);
                break;
            }
#endif /* RT6352 */
#ifdef RT65xx
            if (IS_RT65XX(pAd) && (rfcsr.bank_65xx.RF_CSR_REG_ID == regID) &&
                    (rfcsr.bank_65xx.RF_CSR_REG_BANK == bank))
            {
                *pValue = (UCHAR)(rfcsr.bank_65xx.RF_CSR_DATA);
                break;
            }
#endif /* RT65xx */
        }
    }

    if (rf_status == BUSY)
    {
        DBGPRINT_ERR(("RF read R%d=0x%X fail, i[%d], k[%d]\n", regID, rfcsr.word,i,k));
        goto done;
    }
    ret = STATUS_SUCCESS;
#if 0
    if (bank >= RF_BANK4)
    {
        printk("TESTCSR_RFACC_REGNUM = %x, RF_CSR_DATA = %x !!!\n", rfcsr.field.TESTCSR_RFACC_REGNUM, rfcsr.field.RF_CSR_DATA);
    }
#endif

done:
#ifdef RTMP_MAC_USB
    if (IS_USB_INF(pAd)) {
        RTMP_SEM_EVENT_UP(&pAd->reg_atomic);
    }
#endif /* RTMP_MAC_USB */

    return ret;
}
示例#10
0
/*
    ========================================================================
 	Routine Description:
		RTUSB_VendorRequest - Builds a ralink specific request, sends it off to USB endpoint zero and waits for completion

	Arguments:
		@pAd:
	  	@TransferFlags:
	  	@RequestType: USB message request type value
	  	@Request: USB message request value
	  	@Value: USB message value
	  	@Index: USB message index value
	  	@TransferBuffer: USB data to be sent
	  	@TransferBufferLength: Lengths in bytes of the data to be sent

	Context: ! in atomic context

	Return Value:
		NDIS_STATUS_SUCCESS
		NDIS_STATUS_FAILURE

	Note:
		This function sends a simple control message to endpoint zero
		and waits for the message to complete, or CONTROL_TIMEOUT_JIFFIES timeout.
		Because it is synchronous transfer, so don't use this function within an atomic context,
		otherwise system will hang, do be careful.

		TransferBuffer may located in stack region which may not in DMA'able region in some embedded platforms,
		so need to copy TransferBuffer to UsbVendorReqBuf allocated by kmalloc to do DMA transfer.
		Use UsbVendorReq_semaphore to protect this region which may be accessed by multi task.
		Normally, coherent issue is resloved by low-level HC driver, so do not flush this zone by RTUSB_VendorRequest.

	========================================================================
*/
NTSTATUS RTUSB_VendorRequest(
	IN	PRTMP_ADAPTER	pAd,
	IN	UINT32			TransferFlags,
	IN	UCHAR			RequestType,
	IN	UCHAR			Request,
	IN	USHORT			Value,
	IN	USHORT			Index,
	IN	PVOID			TransferBuffer,
	IN	UINT32			TransferBufferLength)
{
	int				RET = 0;
	POS_COOKIE		pObj = (POS_COOKIE) pAd->OS_Cookie;

	if(in_interrupt())
	{
		MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("BUG: RTUSB_VendorRequest is called from invalid context\n"));
		return NDIS_STATUS_FAILURE;
	}


	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
	{
		/*MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("WIFI device has been disconnected\n"));*/
		return NDIS_STATUS_FAILURE;
	}
	else if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_MCU_SLEEP))
	{
		MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("MCU has entered sleep mode\n"));
		return NDIS_STATUS_FAILURE;
	}
	else
	{
		int RetryCount = 0; /* RTUSB_CONTROL_MSG retry counts*/
		ASSERT(TransferBufferLength <MAX_PARAM_BUFFER_SIZE);

		RTMP_SEM_EVENT_WAIT(&(pAd->UsbVendorReq_semaphore), RET);
		if (RET != 0)
		{
			MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("UsbVendorReq_semaphore get failed! (%d)\n",RET));
			return NDIS_STATUS_FAILURE;
		}

		if ((TransferBufferLength > 0) && ((RequestType == DEVICE_VENDOR_REQUEST_OUT) || (RequestType == DEVICE_CLASS_REQUEST_OUT)))
			NdisMoveMemory(pAd->UsbVendorReqBuf, TransferBuffer, TransferBufferLength);

		do {
			RTUSB_CONTROL_MSG(pObj->pUsb_Dev, 0, Request, RequestType, Value,
								Index, pAd->UsbVendorReqBuf, TransferBufferLength,
								CONTROL_TIMEOUT_JIFFIES, RET);

			if (RET < 0) {
				MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("#\n"));
				if (RET == RTMP_USB_CONTROL_MSG_ENODEV)
				{
					RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
					break;
				}
				RetryCount++;
				RtmpusecDelay(5000); /* wait for 5ms*/
			}
		} while((RET < 0) && (RetryCount < MAX_VENDOR_REQ_RETRY_COUNT));

	  	if ( (!(RET < 0)) && (TransferBufferLength > 0) && (RequestType == DEVICE_VENDOR_REQUEST_IN))
			NdisMoveMemory(TransferBuffer, pAd->UsbVendorReqBuf, TransferBufferLength);

	  	RTMP_SEM_EVENT_UP(&(pAd->UsbVendorReq_semaphore));

        	if (RET < 0) {
			MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("RTUSB_VendorRequest failed(%d),TxFlags=0x%x, ReqType=%s, Req=0x%x, Idx=0x%x,pAd->Flags=0x%lx\n",
						RET, TransferFlags, (RequestType == DEVICE_VENDOR_REQUEST_OUT ? "OUT" : "IN"), Request, Index, pAd->Flags));
			if (Request == 0x2)
				MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("\tRequest Value=0x%04x!\n", Value));

			if ((!TransferBuffer) && (TransferBufferLength > 0))
				hex_dump("Failed TransferBuffer value", TransferBuffer, TransferBufferLength);

			if (RET == RTMP_USB_CONTROL_MSG_ENODEV)
					RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);

		}

	}

	if (RET < 0)
		return NDIS_STATUS_FAILURE;
	else
		return NDIS_STATUS_SUCCESS;
}
示例#11
0
/*
    ========================================================================
	  RTUSB_CONTROL_MSG - Builds a control urb, sends it off and waits for completion
	  @dev: pointer to the usb device to send the message to
	  @pipe: endpoint "pipe" to send the message to
	  @request: USB message request value
	  @requesttype: USB message request type value
	  @value: USB message value
	  @index: USB message index value
	  @data: pointer to the data to send
	  @size: length in bytes of the data to send
	  @timeout: time in jiffies to wait for the message to complete before
			  timing out (if 0 the wait is forever)
	  Context: !in_interrupt ()

	  This function sends a simple control message to a specified endpoint
	  and waits for the message to complete, or timeout.
	  If successful, it returns the number of bytes transferred, otherwise a negative error number.

	 Don't use this function from within an interrupt context, like a
	  bottom half handler.	If you need an asynchronous message, or need to send
	  a message from within interrupt context, use usb_submit_urb()
	  If a thread in your driver uses this call, make sure your disconnect()
	  method can wait for it to complete.  Since you don't have a handle on
	  the URB used, you can't cancel the request.
  
	
	Routine Description:

	Arguments:

	Return Value:
	
	Note:
	
	========================================================================
*/
NTSTATUS    RTUSB_VendorRequest(
	IN	PRTMP_ADAPTER	pAd,
	IN	UINT32			TransferFlags,
	IN	UCHAR			RequestType,
	IN	UCHAR			Request,
	IN	USHORT			Value,
	IN	USHORT			Index,
	IN	PVOID			TransferBuffer,
	IN	UINT32			TransferBufferLength)
{
	int				ret = 0;
	POS_COOKIE		pObj = (POS_COOKIE) pAd->OS_Cookie;

	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
	{
		/*DBGPRINT(RT_DEBUG_ERROR, ("device disconnected\n"));*/
		return -1;
	}
	else if (in_interrupt())	
	{
		DBGPRINT(RT_DEBUG_ERROR, ("in_interrupt, RTUSB_VendorRequest Request%02x Value%04x Offset%04x\n",Request,Value,Index));
		return -1;
	}
	else
	{
#define MAX_RETRY_COUNT  10

		int retryCount = 0;
		void	*tmpBuf = TransferBuffer;

		RTMP_SEM_EVENT_WAIT(&(pAd->UsbVendorReq_semaphore), ret);
		if (pAd->UsbVendorReqBuf)
		{
			ASSERT(TransferBufferLength <MAX_PARAM_BUFFER_SIZE);
		   
		   	tmpBuf = (void *)pAd->UsbVendorReqBuf;
		   	NdisZeroMemory(pAd->UsbVendorReqBuf, TransferBufferLength);
		   
		   	if (RequestType == DEVICE_VENDOR_REQUEST_OUT)
		   	 NdisMoveMemory(tmpBuf, TransferBuffer, TransferBufferLength);  
		}

		do {
			RTUSB_CONTROL_MSG(pObj->pUsb_Dev, 0, Request, RequestType, Value, Index, tmpBuf, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES, ret);
			retryCount++;

			if (ret < 0) {
				DBGPRINT(RT_DEBUG_OFF, ("#\n"));
				if (ret == -ENODEV)				
				{					
					RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);					
					break;				
				}
				RTMPusecDelay(5000);
			}
		} while((ret < 0) && (retryCount < MAX_RETRY_COUNT));
		
	  	if ((pAd->UsbVendorReqBuf) && (RequestType == DEVICE_VENDOR_REQUEST_IN))
			NdisMoveMemory(TransferBuffer, tmpBuf, TransferBufferLength);
	  	RTMP_SEM_EVENT_UP(&(pAd->UsbVendorReq_semaphore));

        if (ret < 0) {
			DBGPRINT(RT_DEBUG_ERROR, ("RTUSB_VendorRequest failed(%d),TxFlags=0x%x, ReqType=%s, Req=0x%x, Idx=0x%x, pAd->Flags=0x%lx\n",
						ret, TransferFlags, (RequestType == DEVICE_VENDOR_REQUEST_OUT ? "OUT" : "IN"), Request, Index, pAd->Flags));
			if (Request == 0x2)
				DBGPRINT(RT_DEBUG_ERROR, ("\tRequest Value=0x%04x!\n", Value));
			
			if ((TransferBuffer!= NULL) && (TransferBufferLength > 0))
				hex_dump("Failed TransferBuffer value", TransferBuffer, TransferBufferLength);
        }
			

	}

	if (ret != -1)
		return STATUS_SUCCESS;
	else
		return STATUS_UNSUCCESSFUL;
}
示例#12
0
NDIS_STATUS MT7601_BBP_read(
	IN RTMP_ADAPTER *pAd,
	IN UCHAR regID,
	IN UCHAR *pValue)
{
	BBP_CSR_CFG_STRUC  BbpCsr = { { 0 } };
	UINT i=0, k=0;
	NDIS_STATUS	 ret = STATUS_UNSUCCESSFUL;


	if (pAd->WlanFunCtrl.field.WLAN_EN == 0)
	{
		DBGPRINT_ERR(("MT7601_BBP_read. Not allow to read BBP 0x%x : fail\n",  regID));	
		return STATUS_UNSUCCESSFUL;
	}

#ifdef RTMP_MAC_USB
	if (IS_USB_INF(pAd)) {
		RTMP_SEM_EVENT_WAIT(&pAd->reg_atomic, i);
		if (i != 0) {
			DBGPRINT(RT_DEBUG_ERROR, ("reg_atomic get failed(ret=%d)\n", i));
			return STATUS_UNSUCCESSFUL;
		}
	}
#endif /* RTMP_MAC_USB */

	ASSERT((regID <= pAd->chipCap.MaxNumOfBbpId));

	for (i=0; i<MAX_BUSY_COUNT; i++)
	{
		if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
			goto done;
			
		RTMP_IO_READ32(pAd, BBP_CSR_CFG, &BbpCsr.word);

		if (BbpCsr.field.Busy == BUSY)
				continue;
		
		BbpCsr.word = 0;
		BbpCsr.field.fRead = 1;
		BbpCsr.field.BBP_RW_MODE = 1;
		BbpCsr.field.Busy = 1;
		BbpCsr.field.RegNum = regID;

		
		RTMP_IO_WRITE32(pAd, BBP_CSR_CFG, BbpCsr.word);
		
		for (k=0; k<MAX_BUSY_COUNT; k++)
		{
			if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
				goto done;
				
			RTMP_IO_READ32(pAd, BBP_CSR_CFG, &BbpCsr.word);

			if (BbpCsr.field.Busy == IDLE)
				break;
		}
		
		if ((BbpCsr.field.Busy == IDLE) &&
			(BbpCsr.field.RegNum == regID) )
		{
			*pValue = (UCHAR)(BbpCsr.field.Value);
			break;
		}
	}

	if (BbpCsr.field.Busy == BUSY)
	{																	
		DBGPRINT_ERR(("BBP read R%d=0x%X fail, i[%d], k[%d]\n", regID, BbpCsr.word,i,k));
		goto done;
	}
	ret = STATUS_SUCCESS;

done:
#ifdef RTMP_MAC_USB
	if (IS_USB_INF(pAd)) {
		RTMP_SEM_EVENT_UP(&pAd->reg_atomic);
	}
#endif /* RTMP_MAC_USB */

	return ret;
}
示例#13
0
NDIS_STATUS MT7601_BBP_write(
	IN PRTMP_ADAPTER pAd,
	IN UCHAR regID,
	IN UCHAR value)
{
	BBP_CSR_CFG_STRUC  BbpCsr = { { 0 } };
	UINT i = 0;
	NDIS_STATUS	 ret;

#ifdef MT7601FPGA
	return;
#endif /*MT7601FPGA */


	if (pAd->WlanFunCtrl.field.WLAN_EN == 0)
	{
		DBGPRINT_ERR(("rlt_rf_write. Not allow to write BBP 0x%x : fail\n",  regID));	
		return STATUS_UNSUCCESSFUL;
	}

#ifdef RTMP_MAC_USB
	if (IS_USB_INF(pAd)) {
		RTMP_SEM_EVENT_WAIT(&pAd->reg_atomic, ret);
		if (ret != 0) {
			DBGPRINT(RT_DEBUG_ERROR, ("reg_atomic get failed(ret=%d)\n", ret));
			return STATUS_UNSUCCESSFUL;
		}
	}
#endif /* RTMP_MAC_USB */

	ASSERT((regID <= pAd->chipCap.MaxNumOfBbpId));

	ret = STATUS_UNSUCCESSFUL;
	do
	{
		RTMP_IO_READ32(pAd, BBP_CSR_CFG, &BbpCsr.word);

		if (!BbpCsr.field.Busy)
			break;
		i++;
	}
	while ((i < MAX_BUSY_COUNT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));

	if ((i == MAX_BUSY_COUNT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
	{
		DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
		goto done;
	}

	BbpCsr.word = 0;
	BbpCsr.field.fRead = 0;
	BbpCsr.field.BBP_RW_MODE = 1;
	BbpCsr.field.Busy = 1;
	BbpCsr.field.Value = value;
	BbpCsr.field.RegNum = regID;


	RTMP_IO_WRITE32(pAd, BBP_CSR_CFG, BbpCsr.word);

	ret = NDIS_STATUS_SUCCESS;
done:


#ifdef RTMP_MAC_USB
	if (IS_USB_INF(pAd)) {
		RTMP_SEM_EVENT_UP(&pAd->reg_atomic);
	}
#endif /* RTMP_MAC_USB */

	return ret;
}
示例#14
0
/*
	========================================================================
	
	Routine Description: Read RT30xx RF register through MAC

	Arguments:

	Return Value:

	IRQL = 
	
	Note:
	
	========================================================================
*/
NDIS_STATUS RT30xxReadRFRegister(
	IN	PRTMP_ADAPTER	pAd,
	IN	UCHAR			regID,
	IN	PUCHAR			pValue)
{
	RF_CSR_CFG_STRUC	rfcsr = { { 0 } };
	UINT				i=0, k=0;
	NDIS_STATUS	 ret = STATUS_UNSUCCESSFUL;


	ASSERT((regID <= pAd->chipCap.MaxNumOfRfId));

#ifdef RTMP_MAC_USB
	if (IS_USB_INF(pAd)) {
		RTMP_SEM_EVENT_WAIT(&pAd->reg_atomic, i);
		if (i != 0) {
			DBGPRINT(RT_DEBUG_ERROR, ("reg_atomic get failed(ret=%d)\n", i));
			return STATUS_UNSUCCESSFUL;
		}
	}
#endif /* RTMP_MAC_USB */

	for (i=0; i<MAX_BUSY_COUNT; i++)
	{
		if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
			goto done;
			
		RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);

		if (rfcsr.field.RF_CSR_KICK == BUSY)
				continue;
		
		rfcsr.word = 0;
		rfcsr.field.RF_CSR_WR = 0;
		rfcsr.field.RF_CSR_KICK = 1;
		rfcsr.field.TESTCSR_RFACC_REGNUM = regID;
		RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
		
		for (k=0; k<MAX_BUSY_COUNT; k++)
		{
			if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
				goto done;
				
			RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);

			if (rfcsr.field.RF_CSR_KICK == IDLE)
				break;
		}
		
		if ((rfcsr.field.RF_CSR_KICK == IDLE) &&
			(rfcsr.field.TESTCSR_RFACC_REGNUM == regID))
		{
			*pValue = (UCHAR)(rfcsr.field.RF_CSR_DATA);
			break;
		}
	}

	if (rfcsr.field.RF_CSR_KICK == BUSY)
	{																	
		DBGPRINT_ERR(("RF read R%d=0x%X fail, i[%d], k[%d]\n", regID, rfcsr.word,i,k));
		goto done;
	}
	ret = STATUS_SUCCESS;
	
done:
#ifdef RTMP_MAC_USB
	if (IS_USB_INF(pAd)) {
		RTMP_SEM_EVENT_UP(&pAd->reg_atomic);
	}
#endif /* RTMP_MAC_USB */
	
	return ret;
}
示例#15
0
/*
	========================================================================
	
	Routine Description: Write RT30xx RF register through MAC

	Arguments:

	Return Value:

	IRQL = 
	
	Note:
	
	========================================================================
*/
NDIS_STATUS RT30xxWriteRFRegister(
	IN	PRTMP_ADAPTER	pAd,
	IN	UCHAR			regID,
	IN	UCHAR			value)
{
	RF_CSR_CFG_STRUC	rfcsr = { { 0 } };
	UINT				i = 0;
	NDIS_STATUS	 ret;



	ASSERT((regID <= pAd->chipCap.MaxNumOfRfId));

#ifdef RTMP_MAC_USB
	if (IS_USB_INF(pAd)) {
		RTMP_SEM_EVENT_WAIT(&pAd->reg_atomic, ret);
		if (ret != 0) {
			DBGPRINT(RT_DEBUG_ERROR, ("reg_atomic get failed(ret=%d)\n", ret));
			return STATUS_UNSUCCESSFUL;
		}
	}
#endif /* RTMP_MAC_USB */

	ret = STATUS_UNSUCCESSFUL;
	do
	{
		RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);

		if (!rfcsr.field.RF_CSR_KICK)
			break;
		i++;
	}
	while ((i < MAX_BUSY_COUNT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));

	if ((i == MAX_BUSY_COUNT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
	{
		DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
		goto done;
	}

	rfcsr.field.RF_CSR_WR = 1;
	rfcsr.field.RF_CSR_KICK = 1;
	rfcsr.field.TESTCSR_RFACC_REGNUM = regID;

	if ((pAd->chipCap.RfReg17WtMethod == RF_REG_WT_METHOD_STEP_ON) && (regID == RF_R17))
	{
		UCHAR IdRf;
		UCHAR RfValue;
		BOOLEAN beAdd;

		RT30xxReadRFRegister(pAd, RF_R17, &RfValue);
		beAdd =  (RfValue < value) ? TRUE : FALSE;
		IdRf = RfValue;
		while(IdRf != value)
		{
			if (beAdd)
				IdRf++;
			else
				IdRf--;
			
				rfcsr.field.RF_CSR_DATA = IdRf;
				RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
				RtmpOsMsDelay(1);
		}
	}

	rfcsr.field.RF_CSR_DATA = value;
	RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);

	ret = NDIS_STATUS_SUCCESS;

done:
#ifdef RTMP_MAC_USB
	if (IS_USB_INF(pAd)) {
		RTMP_SEM_EVENT_UP(&pAd->reg_atomic);
	}
#endif /* RTMP_MAC_USB */

	return ret;
}