/** 
 * \fn     ifSlpMng_handleRxReady
 * \brief  Interface Sleep Manager state machine for Rx ready event
 * 
 * Processes receive ready event of Interface Sleep Manager state machine.
 * Any bytes received in sleep state are treated as awake indication and Rx buffer is cleared.
 * 
 */ 
EMcpfRes ifSlpMng_handleRxReady(handle_t hIfSlpMng) 
{
	TifSlpMngObj  * pIfSlpMng = (TifSlpMngObj *) hIfSlpMng;
	McpBool			stateChanged = MCP_FALSE;
    
	MCPF_ENTER_CRIT_SEC (pIfSlpMng->hMcpf);
	if (pIfSlpMng->eState == IFSLPMNG_STATE_ASLEEP)
	{
		pIfSlpMng->eState = IFSLPMNG_STATE_AWAKE;
		stateChanged = MCP_TRUE;
		pIfSlpMng->stat.AwakeInd_Rx++;
	}
	MCPF_EXIT_CRIT_SEC (pIfSlpMng->hMcpf);

	if (stateChanged)
	{
		MCPF_REPORT_DEBUG_TX(pIfSlpMng->hMcpf,IFSLPMNG_MODULE_LOG, ("ifSlpMng_handleRxReady: Awaking, state=%d\n", pIfSlpMng->eState));

		MCP_HAL_PM_TransportWakeup (pIfSlpMng->tChipId, pIfSlpMng->tTransId);

		busDrv_RxReset (pIfSlpMng->hBusDrv);

		/* Prepare and send SleepAck request */
		TXN_PARAM_SET_IFSLPMNG_OP (pIfSlpMng->pMngTxn, TXN_PARAM_IFSLPMNG_OP_AWAKE_ACK);
		txnQ_Transact (pIfSlpMng->hTxnQ, pIfSlpMng->pMngTxn);

		txnQ_Run (pIfSlpMng->hTxnQ, pIfSlpMng->uFuncId); 
		pIfSlpMng->stat.AwakeAck_Tx++;
		return RES_PENDING;         /* indicate the state was sleeping */
	}
	return RES_COMPLETE;
}
Exemple #2
0
/** 
 * \fn     twIf_HandleSmEvent
 * \brief  The TwIf SM implementation
 * 
 * Handle SM event.
 * Control the device awake/sleep states and the TxnQ run/stop states according to the event.
 *  
 * \note   
 * \param  hTwIf - The module's object
 * \return void
 * \sa     
 */ 
static void twIf_HandleSmEvent (TTwIfObj *pTwIf, ESmEvent eEvent)
{
	ESmState eState = pTwIf->eState;  /* The state before handling the event */

    /* Switch by current state and handle event */
    switch (eState)
    {
    case SM_STATE_AWAKE:
        /* SLEEP event:  AWAKE ==> SLEEP,  stop TxnQ and set ELP reg to sleep */
        if (eEvent == SM_EVENT_SLEEP)
        {
            pTwIf->eState = SM_STATE_SLEEP;
            txnQ_Stop (pTwIf->hTxnQ, TXN_FUNC_ID_WLAN);
            twIf_WriteElpReg (pTwIf, ELP_CTRL_REG_SLEEP);
        }
        break;
    case SM_STATE_SLEEP:
        /* START event:  SLEEP ==> WAIT_HW,  set ELP reg to wake-up */
        if (eEvent == SM_EVENT_START)
        {
            pTwIf->eState = SM_STATE_WAIT_HW;
            twIf_WriteElpReg (pTwIf, ELP_CTRL_REG_AWAKE);
        }
        /* HW_AVAILABLE event:  SLEEP ==> AWAKE,  set ELP reg to wake-up and run TxnQ */
        else if (eEvent == SM_EVENT_HW_AVAILABLE)
        {
            pTwIf->eState = SM_STATE_AWAKE;
            twIf_WriteElpReg (pTwIf, ELP_CTRL_REG_AWAKE);
            txnQ_Run (pTwIf->hTxnQ, TXN_FUNC_ID_WLAN);
        }
        break;
    case SM_STATE_WAIT_HW:
        /* HW_AVAILABLE event:  WAIT_HW ==> AWAKE,  run TxnQ */
        if (eEvent == SM_EVENT_HW_AVAILABLE)
        {
            pTwIf->eState = SM_STATE_AWAKE;
            txnQ_Run (pTwIf->hTxnQ, TXN_FUNC_ID_WLAN);
        }
        break;
    }

}
EMcpfRes ifSlpMng_Reinit (handle_t 		 	 hIfSlpMng)
{
    TifSlpMngObj  * pIfSlpMng = (TifSlpMngObj *) hIfSlpMng;
    McpHalPmHandler pmHandler = {pmEventHandler};

    MCPF_ENTER_CRIT_SEC (pIfSlpMng->hMcpf);
    pIfSlpMng->eState = IFSLPMNG_STATE_AWAKE;
    MCPF_EXIT_CRIT_SEC (pIfSlpMng->hMcpf);
    txnQ_Stop (pIfSlpMng->hTxnQ, pIfSlpMng->uFuncId);  
    txnQ_Run (pIfSlpMng->hTxnQ, pIfSlpMng->uFuncId);

	MCP_HAL_PM_RegisterTransport (pIfSlpMng->tChipId, pIfSlpMng->tTransId, &pmHandler);

	return RES_OK;
}
/** 
 * \fn     ifSlpMng_HandleRxEvent
 * \brief  Interface Sleep Manager state machine for Rx event
 * 
 * Process Rx event of Interface Sleep Manager state machine
 * 
 */ 
EIfSlpMngStatus ifSlpMng_HandleRxEvent (handle_t hIfSlpMng, TTxnStruct *pTxn) 
{
	TifSlpMngObj  * pIfSlpMng = (TifSlpMngObj *) hIfSlpMng;
	EIfSlpMngStatus eRes = IfSlpMng_ERR;
	McpBool			stateChanged = MCP_FALSE;

	if (TXN_PARAM_GET_SINGLE_STEP (pTxn))
	{
		/* IfSlpMng transaction is always single step, 
		 * get IfSlpMng opcode from transaction structure
		 */
		eRes = IfSlpMng_SLP_PKT_TYPE;

		switch (TXN_PARAM_GET_IFSLPMNG_OP (pTxn))
		{

		case TXN_PARAM_IFSLPMNG_OP_SLEEP:

			MCPF_REPORT_DEBUG_RX(pIfSlpMng->hMcpf, IFSLPMNG_MODULE_LOG, ("ifSlpMng_HandleRxEvent: SLEEP_IND, state=%d\n",pIfSlpMng->eState));

			MCPF_ENTER_CRIT_SEC (pIfSlpMng->hMcpf);
			if (pIfSlpMng->eState == IFSLPMNG_STATE_AWAKE)
			{
				pIfSlpMng->eState = IFSLPMNG_STATE_WAIT_FOR_SLEEPACK_TX_COMPL;
				stateChanged = MCP_TRUE;
			}
			pIfSlpMng->stat.SleepInd_Rx++;
			MCPF_EXIT_CRIT_SEC (pIfSlpMng->hMcpf);

			if (stateChanged)
			{
				txnQ_Stop (pIfSlpMng->hTxnQ, pIfSlpMng->uFuncId); 

				/* Prepare and send SleepAck request */
				TXN_PARAM_SET_IFSLPMNG_OP (pIfSlpMng->pMngTxn, TXN_PARAM_IFSLPMNG_OP_SLEEP_ACK);
				txnQ_Transact (pIfSlpMng->hTxnQ, pIfSlpMng->pMngTxn);
				pIfSlpMng->stat.SleepAck_Tx++;
			}
			break;

		case TXN_PARAM_IFSLPMNG_OP_SLEEP_ACK:
			MCPF_REPORT_ERROR (pIfSlpMng->hMcpf, IFSLPMNG_MODULE_LOG, 
							  ("%s: Not expected SleepAck received\n", __FUNCTION__));
			pIfSlpMng->stat.SleepAck_Rx++;
			break;

		case TXN_PARAM_IFSLPMNG_OP_AWAKE:
			{
				EIfSlpMngState  oldState;

				MCPF_REPORT_DEBUG_RX(pIfSlpMng->hMcpf, IFSLPMNG_MODULE_LOG, ("ifSlpMng_HandleRxEvent: AWAKE_IND, state=%d\n",pIfSlpMng->eState));

				MCPF_ENTER_CRIT_SEC (pIfSlpMng->hMcpf);
				oldState = pIfSlpMng->eState;
				if ((pIfSlpMng->eState == IFSLPMNG_STATE_ASLEEP) ||
					(pIfSlpMng->eState == IFSLPMNG_STATE_WAIT_FOR_AWAKE_ACK))
				{
					pIfSlpMng->eState = IFSLPMNG_STATE_AWAKE;
					stateChanged = MCP_TRUE;
				}
				pIfSlpMng->stat.AwakeInd_Rx++;
				MCPF_EXIT_CRIT_SEC (pIfSlpMng->hMcpf);
	
				if (stateChanged)
				{
					switch (oldState)
					{
					case IFSLPMNG_STATE_ASLEEP:
	
						/* Prepare and send SleepAck request */
						TXN_PARAM_SET_IFSLPMNG_OP (pIfSlpMng->pMngTxn, TXN_PARAM_IFSLPMNG_OP_AWAKE_ACK);
						txnQ_Transact (pIfSlpMng->hTxnQ, pIfSlpMng->pMngTxn);
						txnQ_Run (pIfSlpMng->hTxnQ, pIfSlpMng->uFuncId); 
						pIfSlpMng->stat.AwakeAck_Tx++;
						break;
	
					case IFSLPMNG_STATE_WAIT_FOR_AWAKE_ACK:
	
						txnQ_Run (pIfSlpMng->hTxnQ, pIfSlpMng->uFuncId); 
						break;

                    default:
                       break;
					}
				}
			}
			break;

		case TXN_PARAM_IFSLPMNG_OP_AWAKE_ACK:

			MCPF_REPORT_DEBUG_RX(pIfSlpMng->hMcpf, IFSLPMNG_MODULE_LOG, ("ifSlpMng_HandleRxEvent: AWAKE_ACK, state=%d\n",pIfSlpMng->eState));

			MCPF_ENTER_CRIT_SEC (pIfSlpMng->hMcpf);
			if (pIfSlpMng->eState == IFSLPMNG_STATE_WAIT_FOR_AWAKE_ACK)
			{
				pIfSlpMng->eState =  IFSLPMNG_STATE_AWAKE;
				stateChanged = MCP_TRUE;
			}
			pIfSlpMng->stat.AwakeAck_Rx++;
			MCPF_EXIT_CRIT_SEC (pIfSlpMng->hMcpf);

			if (stateChanged)
			{
				txnQ_Run (pIfSlpMng->hTxnQ, pIfSlpMng->uFuncId);
			}
			break;

		default:
			MCPF_REPORT_ERROR (pIfSlpMng->hMcpf, IFSLPMNG_MODULE_LOG, 
							  ("%s: Invalid IfSlpMng opcode=%u\n", __FUNCTION__, TXN_PARAM_GET_IFSLPMNG_OP (pTxn)));
			eRes = IfSlpMng_ERR;
			break;
		} /* Rx IFSLPMNG_OP */
	}
	else
	{
		/* Normal packet received */
		MCPF_ENTER_CRIT_SEC (pIfSlpMng->hMcpf);
		if (pIfSlpMng->eState == IFSLPMNG_STATE_ASLEEP)
		{
			pIfSlpMng->eState = IFSLPMNG_STATE_AWAKE;
			stateChanged = MCP_TRUE;
			pIfSlpMng->stat.AwakeAck_Tx++;
		}
		MCPF_EXIT_CRIT_SEC (pIfSlpMng->hMcpf);

		if (stateChanged)
		{
			/* Prepare and send SleepAck request */
			TXN_PARAM_SET_IFSLPMNG_OP (pIfSlpMng->pMngTxn, TXN_PARAM_IFSLPMNG_OP_AWAKE_ACK);
			txnQ_Transact (pIfSlpMng->hTxnQ, pIfSlpMng->pMngTxn);

			txnQ_Run (pIfSlpMng->hTxnQ, pIfSlpMng->uFuncId);

			MCPF_REPORT_DEBUG_RX(pIfSlpMng->hMcpf, IFSLPMNG_MODULE_LOG, ("ifSlpMng_HandleRxEvent: Normal RX, state=%d\n",pIfSlpMng->eState));
		}

		eRes = IfSlpMng_OK;
	}
	return eRes;
}