コード例 #1
0
ファイル: TWDriver.c プロジェクト: bluewater-cn/ti_wilink
void TWD_EnableExternalEvents (TI_HANDLE hTWD)
{
    TTwd        *pTWD = (TTwd *)hTWD;


    /*
     * Enable sleep after all firmware initializations completed
     * The awake was in the TWD_initHw phase
     */
    twIf_Sleep (pTWD->hTwIf);

    fwEvent_EnableExternalEvents (pTWD->hFwEvent);
}
コード例 #2
0
ファイル: FwEvent.c プロジェクト: Achotjan/FreeXperia
/*
 * \brief	FW-Event state machine
 * 
 * \param  hFwEvent  - FwEvent Driver handle
 * \return void
 * 
 * \par Description
 * 
 * Process the current FW events in a sequence that may progress in the same context,
 *     or exit if pending an Async transaction, which will call back the SM when finished.
 *
 * \sa
 */
static void fwEvent_StateMachine (TfwEvent *pFwEvent)
{
    ETxnStatus  eStatus = TXN_STATUS_ERROR; /* Set to error to detect if used uninitialized */
    CL_TRACE_START_L3();

	/* 
	 * Loop through the states sequence as long as the process is synchronous.
	 * Exit when finished or if an Asynchronous process is required. 
     * In this case the SM will be called back upon Async operation completion. 
	 */
	while (1)
	{
		switch (pFwEvent->eSmState)
		{
            /* IDLE: Update TwIf and read interrupt info from FW */
            case FWEVENT_STATE_IDLE:
            {
                CL_TRACE_START_L5();
                twIf_Awake(pFwEvent->hTwIf);
                eStatus = fwEvent_SmReadIntrInfo (pFwEvent);
                pFwEvent->eSmState = FWEVENT_STATE_WAIT_INTR_INFO;
                CL_TRACE_END_L5("tiwlan_drv.ko", "CONTEXT", "FwEvent", ".ReadInfo");
                break;
            }
            /* WAIT_INTR_INFO: We have the interrupt info so call the handlers accordingly */
            case FWEVENT_STATE_WAIT_INTR_INFO:
            {
                CL_TRACE_START_L5();
                eStatus = fwEvent_SmHandleEvents (pFwEvent);
                /* If state was changed to IDLE by recovery or stop process, exit (process terminated) */
                if (pFwEvent->eSmState == FWEVENT_STATE_IDLE) 
                {
                    CL_TRACE_END_L5("tiwlan_drv.ko", "CONTEXT", "FwEvent", ".HndlEvents");
                    CL_TRACE_END_L3("tiwlan_drv.ko", "CONTEXT", "FwEvent", "");
                    return;
                }
                pFwEvent->eSmState = FWEVENT_STATE_WAIT_HANDLE_COMPLT;
                CL_TRACE_END_L5("tiwlan_drv.ko", "CONTEXT", "FwEvent", ".HndlEvents");
                break;
            }
            /* WAIT_HANDLE_COMPLT: Current handling is completed. */
            case FWEVENT_STATE_WAIT_HANDLE_COMPLT:
            {
                /* If pending interrupt, read interrupt info (back to WAIT_INTR_INFO state) */
                if (pFwEvent->bIntrPending) 
                {
                    CL_TRACE_START_L5();
                    pFwEvent->bIntrPending = TI_FALSE;
                    eStatus = fwEvent_SmReadIntrInfo (pFwEvent);
                    pFwEvent->eSmState = FWEVENT_STATE_WAIT_INTR_INFO;
                    CL_TRACE_END_L5("tiwlan_drv.ko", "CONTEXT", "FwEvent", ".HndlCmplt");
                }
                /* Else - all done so release TwIf to sleep and exit */
                else 
                {
                    twIf_Sleep(pFwEvent->hTwIf);
                    pFwEvent->eSmState = FWEVENT_STATE_IDLE;

                    TRACE3(pFwEvent->hReport, REPORT_SEVERITY_INFORMATION, "fwEvent_StateMachine: Completed, NewState=%d, Status=%d, IntrPending=%d\n", pFwEvent->eSmState, eStatus, pFwEvent->bIntrPending);
                    CL_TRACE_END_L3("tiwlan_drv.ko", "CONTEXT", "FwEvent", "");

                    /**** Finished all current events handling so exit ****/
                    return;
                }
                break;
            }

        }  /* switch */

        TRACE3(pFwEvent->hReport, REPORT_SEVERITY_INFORMATION, "fwEvent_StateMachine: NewState=%d, Status=%d, IntrPending=%d\n", pFwEvent->eSmState, eStatus, pFwEvent->bIntrPending);
        
		/* If last status is Pending, exit the SM (to be called back upon Async operation completion) */
		if (eStatus == TXN_STATUS_PENDING)
		{
            CL_TRACE_END_L3("tiwlan_drv.ko", "CONTEXT", "FwEvent", "");
			return;
		}

        /* If error occured, stop the process and exit (should be cleaned by recovery process) */
		else if (eStatus == TXN_STATUS_ERROR)
		{
            TRACE5(pFwEvent->hReport, REPORT_SEVERITY_ERROR, "fwEvent_StateMachine: NewState=%d, Status=%d, IntrPending=%d, EventVector=0x%x, EventMask=0x%x\n", pFwEvent->eSmState, eStatus, pFwEvent->bIntrPending, pFwEvent->uEventVector, pFwEvent->uEventMask);
            CL_TRACE_END_L3("tiwlan_drv.ko", "CONTEXT", "FwEvent", "");
            fwEvent_Stop ((TI_HANDLE)pFwEvent);
			return;
		}

        /* If we got here the status is COMPLETE so continue in the while loop to the next state */

	}  /* while */
}
コード例 #3
0
ファイル: CmdQueue.c プロジェクト: chambejp/hardware
/*
 * \brief	Configure the CmdQueue object
 * 
 * \param  hCmdQueue - Handle to CmdQueue
 * \param  eCmdQueueEvent - The event that triggered the SM
 * \return TI_OK on success or TI_NOK on failure
 * 
 * \par Description
 * Handles the CmdQueue SM.
 * 
 * \sa cmdQueue_Push, cmdQueue_ResultReceived
 */
static TI_STATUS cmdQueue_SM (TI_HANDLE hCmdQueue, ECmdQueueSmEvents eCmdQueueEvent)
{   
    TCmdQueue     *pCmdQueue = (TCmdQueue*)hCmdQueue;
    TI_BOOL        bBreakWhile = TI_FALSE;
    TI_STATUS      rc = TI_OK, status;
    TCmdQueueNode *pHead;
    TI_UINT32      uReadLen, uWriteLen;

    while(!bBreakWhile)
    {
        switch (pCmdQueue->state)
        {
            case CMDQUEUE_STATE_IDLE:
                switch(eCmdQueueEvent)
                {
                    case CMDQUEUE_EVENT_RUN:
                        pCmdQueue->state = CMDQUEUE_STATE_WAIT_FOR_COMPLETION;

                        pHead = &pCmdQueue->aCmdQueue[pCmdQueue->head];

                        #ifdef CMDQUEUE_DEBUG_PRINT
                        TRACE4(pCmdQueue->hReport, REPORT_SEVERITY_CONSOLE, "cmdQueue_SM: Send Cmd: CmdType = %d(%d) Len = %d, NumOfCmd = %d", pHead->cmdType, (pHead->aParamsBuf) ?  *(TI_UINT16 *)pHead->aParamsBuf:0, pHead->uParamsLen, pCmdQueue->uNumberOfCommandInQueue);

                        WLAN_OS_REPORT(("cmdQueue_SM: Send Cmd: CmdType = %s(%s)\n"
                                        "Len = %d, NumOfCmd = %d \n",
                                        cmdQueue_GetCmdString(pHead->cmdType),
                                        (pHead->aParamsBuf) ?  cmdQueue_GetIEString(pHead->cmdType,*(TI_UINT16 *)pHead->aParamsBuf):"",
                                        pHead->uParamsLen, pCmdQueue->uNumberOfCommandInQueue));
                        #endif
                
                        #ifdef TI_DBG
                            pCmdQueue->uCmdSendCounter++;
                        #endif 

                        /* 
                         * if bAwake is true, then we reached here because there were more commands 
                         * in the queue after sending a previous command.
                         * There is no need to send another awake command to TwIf. 
                         */
                        if (pCmdQueue->bAwake == TI_FALSE)
                        {
                            /* Keep the device awake for the entire Cmd transaction */
                            twIf_Awake(pCmdQueue->hTwIf);
                            pCmdQueue->bAwake = TI_TRUE;
                        }

                        if (pHead->cmdType == CMD_INTERROGATE)
                        {
                            uWriteLen = CMDQUEUE_INFO_ELEM_HEADER_LEN;
                            /* Will be updated by CmdMbox to count the status response */
                            uReadLen = pHead->uParamsLen;
                        }
                        else if(pHead->cmdType == CMD_TEST)
                        {
                            /* CMD_TEST has configure & interrogate abillities together */
                            uWriteLen = pHead->uParamsLen;
                            /* Will be updated by CmdMbox to count the status response */
                            uReadLen = pHead->uParamsLen;
                        }
                        else if (pHead->cmdType == CMD_NOP)
                        {
                            /* NOP command is used for synchronizaiton purpose only, no FW transaction */
                            eCmdQueueEvent = CMDQUEUE_EVENT_COMPLETE;
                            break;
                        }
                        else /* CMD_CONFIGURE or others */
                        {
                            uWriteLen = pHead->uParamsLen;
                            /* Will be updated by CmdMbox to count the status response */
                            uReadLen = 0;

                        }
                        /* send the command to TNET */
                        rc = cmdMbox_SendCommand (pCmdQueue->hCmdMBox, 
                                              pHead->cmdType, 
                                              pHead->aParamsBuf, 
                                              uWriteLen,
                                              uReadLen);

                        bBreakWhile = TI_TRUE;

                        /* end of CMDQUEUE_EVENT_RUN */
                        break;

                    default:
                        TRACE1(pCmdQueue->hReport, REPORT_SEVERITY_ERROR, "cmdQueue_SM: ** ERROR **  No such event (%d) for state CMDQUEUE_STATE_IDLE\n",eCmdQueueEvent);
                        bBreakWhile = TI_TRUE;
                        rc =  TI_NOK;

                        break;
                }
                break;
            
            case CMDQUEUE_STATE_WAIT_FOR_COMPLETION:
                switch(eCmdQueueEvent)
                {
                    case CMDQUEUE_EVENT_RUN:
                        /* We are in the middle of other command transaction so there is nothing top be done */
                        bBreakWhile = TI_TRUE;
                        rc = TXN_STATUS_PENDING;
                        break;

                    case CMDQUEUE_EVENT_COMPLETE:
                        {
                            Command_e cmdType;
                            TI_UINT16        uParam;
                            void *fCb, *hCb, *pCb;
                            CommandStatus_e cmdStatus;

                            pHead = &pCmdQueue->aCmdQueue[pCmdQueue->head];
            
                            /* Keep callback parameters in temporary variables */
                            cmdType = pHead->cmdType;
                            uParam  = *(TI_UINT16 *)pHead->aParamsBuf;
                            fCb = pHead->fCb;
                            hCb = pHead->hCb;
                            pCb = pHead->pInterrogateBuf;
                            
                            /* 
                             * Delete the command from the queue before calling a callback 
                             * because there may be nested calls inside a callback
                             */
                            pCmdQueue->head ++;
                            if (pCmdQueue->head >= CMDQUEUE_QUEUE_DEPTH)
                                pCmdQueue->head = 0;                
                            pCmdQueue->uNumberOfCommandInQueue --;                
                
                        #ifdef TI_DBG
                            pCmdQueue->uCmdCompltCounter++;
                        #endif 

                            /* Read the latest command return status */
                            if (pHead->cmdType != CMD_NOP)
                            {
                                status = cmdMbox_GetStatus (pCmdQueue->hCmdMBox, &cmdStatus);
                            }
                            else
                            {
                                /* NOP command is used for synchronizaiton purpose only, no FW transaction */
                                status = TI_OK;
                            }
                            if (status != TI_OK)
                            {
                                if (cmdStatus == CMD_STATUS_REJECT_MEAS_SG_ACTIVE)
                                {
                                    /* return reject status in the callback */
                                    status = SG_REJECT_MEAS_SG_ACTIVE;
                                    pCmdQueue->bErrorFlag = TI_FALSE;
                                }
                                else
                                {
                                    WLAN_OS_REPORT(("cmdQueue_SM: ** ERROR **  Mbox status error %d, set bErrorFlag !!!!!\n", cmdStatus));
                                    TRACE1(pCmdQueue->hReport, REPORT_SEVERITY_ERROR, "cmdQueue_SM: ** ERROR **  Mbox status error %d, set bErrorFlag !!!!!\n", cmdStatus);
                                    pCmdQueue->bErrorFlag = TI_TRUE;
                                }
                            }
                            else
                            {
                                pCmdQueue->bErrorFlag = TI_FALSE;
                            }

                            /* If the command had a CB, then call it with the proper results buffer */
                            if (fCb)
                            {   
                                if (pCb)
                                {
                                    /* If pInterrogateBuf isn't NULL we need to copy the results */
                                    cmdMbox_GetCmdParams(pCmdQueue->hCmdMBox, pCb);
                                    /* Call the CB with the result buffer and the returned status */
                                    ((TCmdQueueInterrogateCb)fCb) (hCb, status, pCb); 
                                }
                                else
                                {
                                    /* Call the CB with only the returned status */
                                    ((TCmdQueueCb)fCb) (hCb, status);
                                }
                            }
                            else
                            {
                                /* Call the generic callback */
                                if (pCmdQueue->fCmdCompleteCb)
                                {
                                    pCmdQueue->fCmdCompleteCb (pCmdQueue->hCmdCompleteCb, cmdType, uParam, status);
                                }
                            }

                            /* Check if there are any more commands in queue */
                            if (pCmdQueue->uNumberOfCommandInQueue > 0)               
                            {
                                /* If queue isn't empty, send the next command */
                                pCmdQueue->state = CMDQUEUE_STATE_IDLE;
                                eCmdQueueEvent = CMDQUEUE_EVENT_RUN;
                            }
                            else	
                            {   
                                /* If queue is empty, we can permit TwIf to send sleep a command if neccesary */
                                twIf_Sleep(pCmdQueue->hTwIf);
                                pCmdQueue->bAwake = TI_FALSE;
                                pCmdQueue->state = CMDQUEUE_STATE_IDLE;

                                bBreakWhile = TI_TRUE;
                            }
                        /* end of CMDQUEUE_EVENT_COMPLETE */
                        }            
                        break;

                    default:
                        TRACE1(pCmdQueue->hReport, REPORT_SEVERITY_ERROR, "cmdQueue_SM: ** ERROR **  No such event (%d) for state CMDQUEUE_STATE_IDLE\n",eCmdQueueEvent);
                        bBreakWhile = TI_TRUE;
                        rc =  TI_NOK;

                        break;

                /* end of switch event */
                } 
                break;
        /* end of switch state */
        }
    /* end of while */
    }

    return rc;
}
コード例 #4
0
ファイル: FwEvent.c プロジェクト: IdeosDev/vendor_ti_wlan
/*
 * \brief	FW-Event state machine
 *
 * \param  hFwEvent  - FwEvent Driver handle
 * \return void
 *
 * \par Description
 *
 * Process the current FW events in a sequence that may progress in the same context,
 *     or exit if pending an Async transaction, which will call back the SM when finished.
 *
 * \sa
 */
static void fwEvent_StateMachine (TfwEvent *pFwEvent)
{
	ETxnStatus  eStatus = TXN_STATUS_ERROR; /* Set to error to detect if used uninitialized */

	/*
	 * Loop through the states sequence as long as the process is synchronous.
	 * Exit when finished or if an Asynchronous process is required.
	 * In this case the SM will be called back upon Async operation completion.
	 */
	while (1) {
		switch (pFwEvent->eSmState) {
			/* IDLE: Update TwIf and read interrupt info from FW */
		case FWEVENT_STATE_IDLE: {
			twIf_Awake(pFwEvent->hTwIf);
			eStatus = fwEvent_SmReadIntrInfo (pFwEvent);
			pFwEvent->eSmState = FWEVENT_STATE_WAIT_INTR_INFO;
			break;
		}
		/* WAIT_INTR_INFO: We have the interrupt info so call the handlers accordingly */
		case FWEVENT_STATE_WAIT_INTR_INFO: {
			eStatus = fwEvent_SmHandleEvents (pFwEvent);
			/* If state was changed to IDLE by recovery or stop process, exit (process terminated) */
			if (pFwEvent->eSmState == FWEVENT_STATE_IDLE) {
				return;
			}
			pFwEvent->eSmState = FWEVENT_STATE_WAIT_HANDLE_COMPLT;
			break;
		}
		/* WAIT_HANDLE_COMPLT: Current handling is completed. */
		case FWEVENT_STATE_WAIT_HANDLE_COMPLT: {
			/* If pending interrupt, read interrupt info (back to WAIT_INTR_INFO state) */
			if (pFwEvent->bIntrPending) {
				pFwEvent->bIntrPending = TI_FALSE;
				eStatus = fwEvent_SmReadIntrInfo (pFwEvent);
				pFwEvent->eSmState = FWEVENT_STATE_WAIT_INTR_INFO;
			}
			/* Else - all done so release TwIf to sleep and exit */
			else {
				twIf_Sleep(pFwEvent->hTwIf);
				pFwEvent->eSmState = FWEVENT_STATE_IDLE;


				/**** Finished all current events handling so exit ****/
				return;
			}
			break;
		}

		}  /* switch */


		/* If last status is Pending, exit the SM (to be called back upon Async operation completion) */
		if (eStatus == TXN_STATUS_PENDING) {
			return;
		}

		/* If error occured, stop the process and exit (should be cleaned by recovery process) */
		else if (eStatus == TXN_STATUS_ERROR) {
			fwEvent_Stop ((TI_HANDLE)pFwEvent);
			return;
		}

		/* If we got here the status is COMPLETE so continue in the while loop to the next state */

	}  /* while */
}