/**
 * \fn     twIf_WriteElpReg
 * \brief  write ELP register
 *
 * \note
 * \param  pTwIf   - The module's object
 * \param  uValue  - ELP_CTRL_REG_SLEEP or ELP_CTRL_REG_AWAKE
 * \return void
 * \sa
 */
static void twIf_WriteElpReg (TTwIfObj *pTwIf, TI_UINT32 uValue)
{
	TRACE1(pTwIf->hReport, REPORT_SEVERITY_INFORMATION, "twIf_WriteElpReg:  ELP Txn data = 0x%x\n", uValue);

	/* Send ELP (awake or sleep) transaction to TxnQ */
	if (uValue == ELP_CTRL_REG_AWAKE) {
		txnQ_Transact (pTwIf->hTxnQ, &(pTwIf->tElpTxnAwake.tHdr));
	} else {
		txnQ_Transact (pTwIf->hTxnQ, &(pTwIf->tElpTxnSleep.tHdr));
	}
}
Esempio n. 2
0
/** 
 * \fn     twIf_WriteElpReg
 * \brief  write ELP register
 * 
 * \note   
 * \param  pTwIf   - The module's object
 * \param  uValue  - ELP_CTRL_REG_SLEEP or ELP_CTRL_REG_AWAKE
 * \return void
 * \sa     
 */ 
static void twIf_WriteElpReg (TTwIfObj *pTwIf, TI_UINT32 uValue)
{

    /* Send ELP (awake or sleep) transaction to TxnQ */
    if (uValue == ELP_CTRL_REG_AWAKE)
    {
        txnQ_Transact (pTwIf->hTxnQ, &(pTwIf->tElpTxnAwake.tHdr));
    }
    else
    {
        txnQ_Transact (pTwIf->hTxnQ, &(pTwIf->tElpTxnSleep.tHdr));
    }
}
/** 
 * \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;
}
/** 
 * \fn     ifSlpMng_HandleTxEvent
 * \brief  Interface Sleep Manager state machine for Tx event
 * 
 * Process Tx event of Interface Sleep Manager state machine
 * 
 */ 
EMcpfRes ifSlpMng_HandleTxEvent (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_WAIT_FOR_AWAKE_ACK;
		stateChanged = MCP_TRUE;
		pIfSlpMng->stat.AwakeInd_Tx++;
	}
    MCPF_EXIT_CRIT_SEC (pIfSlpMng->hMcpf);

	if (stateChanged)
	{
		MCP_HAL_PM_TransportWakeup (pIfSlpMng->tChipId, pIfSlpMng->tTransId);

		/* Prepare and send AwakeInd request */
		TXN_PARAM_SET_IFSLPMNG_OP (pIfSlpMng->pMngTxn, TXN_PARAM_IFSLPMNG_OP_AWAKE);
		MCPF_REPORT_DEBUG_TX(pIfSlpMng->hMcpf, IFSLPMNG_MODULE_LOG, ("ifSlpMng_HandleTxEvent: Send Awake, pIfSlpMng=%p, state=%d\n", 
												pIfSlpMng, pIfSlpMng->eState));
		txnQ_Transact (pIfSlpMng->hTxnQ, pIfSlpMng->pMngTxn);
	}

	return RES_OK;
}
/** 
 * \fn     ifSlpMng_HandleTxComplEvent
 * \brief  Interface Sleep Manager state machine for Tx complete event
 * 
 * Process transaction sending complete event of Interface Sleep Manager state machine
 * 
 */ 
EMcpfRes ifSlpMng_HandleTxComplEvent (handle_t hIfSlpMng) 
{
	TifSlpMngObj  * pIfSlpMng = (TifSlpMngObj *) hIfSlpMng;
	McpBool			stateChanged  = MCP_FALSE;
	McpBool			awakeRequired = MCP_FALSE;
    
	MCPF_ENTER_CRIT_SEC (pIfSlpMng->hMcpf);
	if (pIfSlpMng->eState == IFSLPMNG_STATE_WAIT_FOR_SLEEPACK_TX_COMPL)
	{
		stateChanged = MCP_TRUE;
		pIfSlpMng->stat.SleepAckTxCompl++;

		if (txnQ_IsQueueEmpty (pIfSlpMng->hTxnQ, pIfSlpMng->uFuncId))
		{
			pIfSlpMng->eState = IFSLPMNG_STATE_ASLEEP;
		}
		else
		{
			pIfSlpMng->eState = IFSLPMNG_STATE_WAIT_FOR_AWAKE_ACK;
			awakeRequired = MCP_TRUE;
			pIfSlpMng->stat.AwakeInd_Tx++;
		}
	}
	MCPF_EXIT_CRIT_SEC (pIfSlpMng->hMcpf);

	if (stateChanged)
	{
		if (!awakeRequired)
		{
			MCP_HAL_PM_TransportSleep (pIfSlpMng->tChipId, pIfSlpMng->tTransId);

			MCPF_REPORT_DEBUG_TX(pIfSlpMng->hMcpf, IFSLPMNG_MODULE_LOG, ("ifSlpMng_HandleTxComplEvent: going to sleep, pIfSlpMng=%p, state=%d\n", 
													pIfSlpMng, pIfSlpMng->eState));
		}
		else
		{
			/* Prepare and send AwakeInd request */
			TXN_PARAM_SET_IFSLPMNG_OP (pIfSlpMng->pMngTxn, TXN_PARAM_IFSLPMNG_OP_AWAKE);
			txnQ_Transact (pIfSlpMng->hTxnQ, pIfSlpMng->pMngTxn);

			MCPF_REPORT_DEBUG_TX(pIfSlpMng->hMcpf, IFSLPMNG_MODULE_LOG, ("ifSlpMng_HandleTxComplEvent: Send Awake, pIfSlpMng=%p, state=%d\n", 
													pIfSlpMng, pIfSlpMng->eState));
		}
	}

	return RES_OK;
}
Esempio n. 6
0
/** 
 * \fn     twIf_SendTransaction
 * \brief  Send a transaction to the device
 * 
 * This method is used by the Xfer modules and the TwIf to send all transaction types to the device.
 * Send the transaction to the TxnQ and update the SM if needed.
 * 
 * \note   
 * \param  pTwIf - The module's object
 * \param  pTxn  - The transaction object 
 * \return COMPLETE if the transaction was completed in this context, PENDING if not, ERROR if failed
 * \sa     
 */
static ETxnStatus twIf_SendTransaction(TTwIfObj * pTwIf, TTxnStruct * pTxn)
{
	ETxnStatus eStatus;
#ifdef TI_DBG
	TI_UINT32 data = 0;

	/* Verify that the Txn HW-Address is 4-bytes aligned */
	if (pTxn->uHwAddr & 0x3) {
		TRACE2(pTwIf->hReport, REPORT_SEVERITY_ERROR,
		       "twIf_SendTransaction: Unaligned HwAddr! HwAddr=0x%x, Params=0x%x\n",
		       pTxn->uHwAddr, pTxn->uTxnParams);
		return TXN_STATUS_ERROR;
	}
#endif

	context_EnterCriticalSection(pTwIf->hContext);
	/* increment pending Txn counter */
	pTwIf->uPendingTxnCount++;
	context_LeaveCriticalSection(pTwIf->hContext);

	/* Send transaction to TxnQ */
	eStatus = txnQ_Transact(pTwIf->hTxnQ, pTxn);

#ifdef TI_DBG
	pTwIf->uDbgCountTxn++;
	if (eStatus == TXN_STATUS_COMPLETE) {
		pTwIf->uDbgCountTxnComplete++;
	} else if (eStatus == TXN_STATUS_PENDING) {
		pTwIf->uDbgCountTxnPending++;
	}

	COPY_WLAN_LONG(&data, &(pTxn->aBuf[0]));
	TRACE8(pTwIf->hReport, REPORT_SEVERITY_INFORMATION,
	       "twIf_SendTransaction: Status = %d, Params=0x%x, HwAddr=0x%x, Len0=%d, Len1=%d, Len2=%d, Len3=%d, Data=0x%x \n",
	       eStatus, pTxn->uTxnParams, pTxn->uHwAddr, pTxn->aLen[0],
	       pTxn->aLen[1], pTxn->aLen[2], pTxn->aLen[3], data);
#endif

	/* If Txn status is PENDING issue Start event to the SM */
	if (eStatus == TXN_STATUS_PENDING) {
		twIf_HandleSmEvent(pTwIf, SM_EVENT_START);
	}

	/* Else (COMPLETE or ERROR) */
	else {
		context_EnterCriticalSection(pTwIf->hContext);
		/* decrement pending Txn counter in case of sync transact */
		pTwIf->uPendingTxnCount--;
		context_LeaveCriticalSection(pTwIf->hContext);

		/* If Awake not required and no pending transactions in TxnQ, issue Sleep event to SM */
		if ((pTwIf->uAwakeReqCount == 0)
		    && (pTwIf->uPendingTxnCount == 0)) {
			twIf_HandleSmEvent(pTwIf, SM_EVENT_SLEEP);
		}

		/* If Txn failed and error CB available, call it to initiate recovery */
		if (eStatus == TXN_STATUS_ERROR) {
			TRACE6(pTwIf->hReport, REPORT_SEVERITY_ERROR,
			       "twIf_SendTransaction: Txn failed!!  Params=0x%x, HwAddr=0x%x, Len0=%d, Len1=%d, Len2=%d, Len3=%d\n",
			       pTxn->uTxnParams, pTxn->uHwAddr, pTxn->aLen[0],
			       pTxn->aLen[1], pTxn->aLen[2], pTxn->aLen[3]);

			if (pTwIf->fErrCb) {
				pTwIf->fErrCb(pTwIf->hErrCb, BUS_FAILURE);
			}
		}
	}

	/* Return the Txn status (COMPLETE if completed in this context, PENDING if not, ERROR if failed) */
	return eStatus;
}
Esempio n. 7
0
/** 
 * \fn     twIf_SendTransaction
 * \brief  Send a transaction to the device
 * 
 * This method is used by the Xfer modules and the TwIf to send all transaction types to the device.
 * Send the transaction to the TxnQ and update the SM if needed.
 * 
 * \note   
 * \param  pTwIf - The module's object
 * \param  pTxn  - The transaction object 
 * \return COMPLETE if the transaction was completed in this context, PENDING if not, ERROR if failed
 * \sa     
 */ 
static ETxnStatus twIf_SendTransaction (TTwIfObj *pTwIf, TTxnStruct *pTxn)
{
    ETxnStatus eStatus;
	TI_UINT32  data=0;

#ifdef TI_DBG
    /* Verify that the Txn HW-Address is 4-bytes aligned */
	if (pTxn->uHwAddr & 0x3)
	{
		return TXN_STATUS_ERROR;
	}	
  
#endif

    context_EnterCriticalSection (pTwIf->hContext);
    /* increment pending Txn counter */
    pTwIf->uPendingTxnCount++;
    context_LeaveCriticalSection (pTwIf->hContext);

    /* Send transaction to TxnQ */
    eStatus = txnQ_Transact(pTwIf->hTxnQ, pTxn);

#ifdef TI_DBG
    pTwIf->uDbgCountTxn++;
    if      (eStatus == TXN_STATUS_COMPLETE) { pTwIf->uDbgCountTxnComplete++; }
    else if (eStatus == TXN_STATUS_PENDING ) { pTwIf->uDbgCountTxnPending++;  }

	COPY_WLAN_LONG(&data,&(pTxn->aBuf[0]));
#endif

    /* If Txn status is PENDING issue Start event to the SM */
    if (eStatus == TXN_STATUS_PENDING)
    {
        twIf_HandleSmEvent (pTwIf, SM_EVENT_START);
    }

    /* Else (COMPLETE or ERROR) */
    else
    {
        context_EnterCriticalSection (pTwIf->hContext);
        /* decrement pending Txn counter in case of sync transact*/
        pTwIf->uPendingTxnCount--;
        context_LeaveCriticalSection (pTwIf->hContext);

        /* If Awake not required and no pending transactions in TxnQ, issue Sleep event to SM */
        if ((pTwIf->uAwakeReqCount == 0) && (pTwIf->uPendingTxnCount == 0))
        {
            twIf_HandleSmEvent (pTwIf, SM_EVENT_SLEEP);
        }

        /* If Txn failed and error CB available, call it to initiate recovery */
        if (eStatus == TXN_STATUS_ERROR)
        {

            if (pTwIf->fErrCb)
            {
                pTwIf->fErrCb (pTwIf->hErrCb, BUS_FAILURE);
            }
        }
    }

    /* Return the Txn status (COMPLETE if completed in this context, PENDING if not, ERROR if failed) */
    return eStatus;
}
/** 
 * \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;
}