/** * \fn twIf_HwAvailable * \brief The device is awake * * This is an indication from the FwEvent that the device is awake. * Issue HW_AVAILABLE event to the SM. * * \note * \param hTwIf - The module's object * \return void * \sa */ void twIf_HwAvailable (TI_HANDLE hTwIf) { TTwIfObj *pTwIf = (TTwIfObj*) hTwIf; /* Issue HW_AVAILABLE event to the SM */ twIf_HandleSmEvent (pTwIf, SM_EVENT_HW_AVAILABLE); }
/** * \fn twIf_HwAvailable * \brief The device is awake * * This is an indication from the FwEvent that the device is awake. * Issue HW_AVAILABLE event to the SM. * * \note * \param hTwIf - The module's object * \return void * \sa */ void twIf_HwAvailable (TI_HANDLE hTwIf) { TTwIfObj *pTwIf = (TTwIfObj*) hTwIf; TRACE0(pTwIf->hReport, REPORT_SEVERITY_INFORMATION, "twIf_HwAvailable: HW is Available\n"); /* Issue HW_AVAILABLE event to the SM */ twIf_HandleSmEvent (pTwIf, SM_EVENT_HW_AVAILABLE); }
/** * \fn twIf_Sleep * \brief Remove request to keep the device awake * * Each call to this function decrements AwakeReq counter. * Once this counter is zeroed, if the TxnQ is empty (no WLAN transactions), the TwIf SM is * invoked to stop the TxnQ and enable the device to sleep (write 0 to ELP register). * * \note * \param hTwIf - The module's object * \return void * \sa twIf_Awake */ void twIf_Sleep(TI_HANDLE hTwIf) { TTwIfObj *pTwIf = (TTwIfObj *) hTwIf; /* Decrement awake requests counter */ if (pTwIf->uAwakeReqCount > 0) { /* in case of redundant call after recovery */ pTwIf->uAwakeReqCount--; } #ifdef TI_DBG pTwIf->uDbgCountSleep++; TRACE1(pTwIf->hReport, REPORT_SEVERITY_INFORMATION, "twIf_Sleep: uAwakeReqCount = %d\n", pTwIf->uAwakeReqCount); #endif /* 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); } }
/** * \fn twIf_Sleep * \brief Remove request to keep the device awake * * Each call to this function decrements AwakeReq counter. * Once this counter is zeroed, if the TxnQ is empty (no WLAN transactions), the TwIf SM is * invoked to stop the TxnQ and enable the device to sleep (write 0 to ELP register). * * \note * \param hTwIf - The module's object * \return void * \sa twIf_Awake */ void twIf_Sleep (TI_HANDLE hTwIf) { TTwIfObj *pTwIf = (TTwIfObj*) hTwIf; /* Decrement awake requests counter */ if (pTwIf->uAwakeReqCount > 0) /* in case of redundant call after recovery */ { pTwIf->uAwakeReqCount--; } #ifdef TI_DBG pTwIf->uDbgCountSleep++; #endif /* 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); } }
/** * \fn twIf_HandleTxnDone * \brief Completed transactions handler * * The completed transactions handler, called upon TxnDone event, either from the context engine * or directly from twIf_TxnDoneCb() if we are already in the WLAN driver's context. * Dequeue all completed transactions in critical section, and call their callbacks if available. * If awake is not required and no pending transactions in TxnQ, issue Sleep event to SM. * * \note * \param hTwIf - The module's object * \return void * \sa */ static void twIf_HandleTxnDone(TI_HANDLE hTwIf) { TTwIfObj *pTwIf = (TTwIfObj *) hTwIf; TTxnStruct *pTxn; /* In case of recovery, call the recovery callback and exit */ if (pTwIf->bTxnDoneInRecovery) { TRACE0(pTwIf->hReport, REPORT_SEVERITY_INFORMATION, "twIf_HandleTxnDone: call RecoveryCb\n"); pTwIf->bTxnDoneInRecovery = TI_FALSE; if (pTwIf->bPendRestartTimerRunning) { tmr_StopTimer(pTwIf->hPendRestartTimer); pTwIf->bPendRestartTimerRunning = TI_FALSE; } pTwIf->fRecoveryCb(pTwIf->hRecoveryCb); return; } /* Loop while there are completed transactions to handle */ while (1) { /* In critical section, dequeue completed transaction from the TxnDoneQ. */ context_EnterCriticalSection(pTwIf->hContext); pTxn = (TTxnStruct *) que_Dequeue(pTwIf->hTxnDoneQueue); context_LeaveCriticalSection(pTwIf->hContext); /* If no more transactions to handle, exit */ if (pTxn != NULL) { context_EnterCriticalSection(pTwIf->hContext); /* Decrement pending Txn counter */ if (pTwIf->uPendingTxnCount > 0) { /* in case of callback on recovery after restart */ pTwIf->uPendingTxnCount--; } context_LeaveCriticalSection(pTwIf->hContext); TRACE4(pTwIf->hReport, REPORT_SEVERITY_INFORMATION, "twIf_HandleTxnDone: Completed-Txn: Params=0x%x, HwAddr=0x%x, Len0=%d, fTxnDoneCb=0x%x\n", pTxn->uTxnParams, pTxn->uHwAddr, pTxn->aLen[0], pTxn->fTxnDoneCb); /* If Txn failed and error CB available, call it to initiate recovery */ if (TXN_PARAM_GET_STATUS(pTxn) == TXN_PARAM_STATUS_ERROR) { TRACE6(pTwIf->hReport, REPORT_SEVERITY_ERROR, "twIf_HandleTxnDone: 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); } /* in error do not continue */ return; } /* If Txn specific CB available, call it (may free Txn resources and issue new Txns) */ if (pTxn->fTxnDoneCb != NULL) { ((TTxnDoneCb) (pTxn->fTxnDoneCb)) (pTxn-> hCbHandle, pTxn); } } /*If uPendingTxnCount == 0 and awake not required, issue Sleep event to SM */ if ((pTwIf->uAwakeReqCount == 0) && (pTwIf->uPendingTxnCount == 0)) { twIf_HandleSmEvent(pTwIf, SM_EVENT_SLEEP); } if (pTxn == NULL) { return; } } }
/** * \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; }
/** * \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; }