Beispiel #1
0
TI_STATUS TWD_Stop (TI_HANDLE hTWD)
{
    TTwd        *pTWD = (TTwd *)hTWD;
    ETxnStatus   status;


    fwEvent_Stop (pTWD->hFwEvent);


    /* close all BA sessions */
    TWD_CloseAllBaSessions(hTWD);

    cmdMbox_Restart (pTWD->hCmdMbox);
    cmdQueue_Restart (pTWD->hCmdQueue);
    cmdQueue_DisableMbox (pTWD->hCmdQueue);
    eventMbox_Stop (pTWD->hEventMbox);
    MacServices_restart (pTWD->hMacServices);

    status = twIf_Restart(pTWD->hTwIf);

    /* Call user stop callback */
    if (status != TXN_STATUS_PENDING)
    {
        TWD_StopComplete (hTWD);
    }

    return TI_OK;
}
Beispiel #2
0
/*
 * \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 */
}
Beispiel #3
0
/*
 * \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 */
}