diff options
Diffstat (limited to 'wilink_6_1/TWD/Ctrl/CmdQueue.c')
-rw-r--r-- | wilink_6_1/TWD/Ctrl/CmdQueue.c | 1099 |
1 files changed, 1099 insertions, 0 deletions
diff --git a/wilink_6_1/TWD/Ctrl/CmdQueue.c b/wilink_6_1/TWD/Ctrl/CmdQueue.c new file mode 100644 index 0000000..ef6b5e5 --- /dev/null +++ b/wilink_6_1/TWD/Ctrl/CmdQueue.c @@ -0,0 +1,1099 @@ +/* + * CmdQueue.c + * + * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Texas Instruments nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +/** \file CmdQueue.c + * \brief Handle the wlan command queue + * + * \see CmdQueue.h, CmdQueue_api.h, CmdMBox.c + */ + + +#define __FILE_ID__ FILE_ID_97 +#include "tidef.h" +#include "osApi.h" +#include "report.h" +#include "TwIf.h" +#include "public_commands.h" +#include "CmdQueue_api.h" +#include "CmdMBox_api.h" +#include "CmdQueue.h" + +/***************************************************************************** + ** Internal functions prototypes ** + *****************************************************************************/ + +static TI_STATUS cmdQueue_SM (TI_HANDLE hCmdQueue, ECmdQueueSmEvents event); +static TI_STATUS cmdQueue_Push (TI_HANDLE hCmdQueue, + Command_e cmdType, + TI_UINT8 *pParamsBuf, + TI_UINT32 uParamsLen, + void *fCb, + TI_HANDLE hCb, + void *pCb); +#ifdef TI_DBG +static void cmdQueue_PrintQueue(TCmdQueue *pCmdQueue); +#ifdef REPORT_LOG +static char * cmdQueue_GetIEString (TI_INT32 MboxCmdType, TI_UINT16 id); +static char * cmdQueue_GetCmdString (TI_INT32 MboxCmdType); +#endif +#endif /* TI_DBG */ + + + + +/* + * \brief Create the TCmdQueue object + * + * \param hOs - OS module object handle + * \return Handle to the created object + * + * \par Description + * Calling this function creates a CmdQueue object + * + * \sa cmdQueue_Destroy + */ +TI_HANDLE cmdQueue_Create (TI_HANDLE hOs) +{ + TCmdQueue *pCmdQueue; + + pCmdQueue = os_memoryAlloc (hOs, sizeof(TCmdQueue)); + if (pCmdQueue == NULL) + { + WLAN_OS_REPORT(("FATAL ERROR: cmdQueue_Create(): Error Creating aCmdQueue - Aborting\n")); + return NULL; + } + + /* reset control module control block */ + os_memoryZero (hOs, pCmdQueue, sizeof(TCmdQueue)); + pCmdQueue->hOs = hOs; + + return pCmdQueue; +} + + +/* + * \brief Destroys the cmdQueue object + * + * \param hCmdMbox - The object to free + * \return TI_OK + * + * \par Description + * Calling this function destroys the cmdQueue object + * + * \sa cmdQueue_Create + */ +TI_STATUS cmdQueue_Destroy (TI_HANDLE hCmdQueue) +{ + TCmdQueue* pCmdQueue = (TCmdQueue*)hCmdQueue; + + /* Free context */ + os_memoryFree (pCmdQueue->hOs, pCmdQueue, sizeof(TCmdQueue)); + + return TI_OK; +} + + +/* + * \brief Configure the CmdQueue object + * + * \param hCmdQueue - Handle to CmdQueue + * \param hCmdMbox - Handle to CmdMbox + * \param hReport - Handle to report module + * \param hTwIf - Handle to TwIf + * \param hTimer - Handle to os timer + * \return TI_OK on success or TI_NOK on failure + * + * \par Description + * + * \sa + */ +TI_STATUS cmdQueue_Init (TI_HANDLE hCmdQueue, + TI_HANDLE hCmdMbox, + TI_HANDLE hReport, + TI_HANDLE hTwIf, + TI_HANDLE hTimer) +{ + TCmdQueue* pCmdQueue = (TCmdQueue*) hCmdQueue; + + pCmdQueue->head = 0; + pCmdQueue->tail = 0; + pCmdQueue->uNumberOfCommandInQueue = 0; + pCmdQueue->uMaxNumberOfCommandInQueue = 0; + pCmdQueue->state = CMDQUEUE_STATE_IDLE; + pCmdQueue->fCmdCompleteCb = NULL; + pCmdQueue->hCmdCompleteCb = NULL; + pCmdQueue->fFailureCb = NULL; + pCmdQueue->hFailureCb = NULL; + pCmdQueue->hReport = hReport; + pCmdQueue->hCmdMBox = hCmdMbox; + pCmdQueue->hTwIf = hTwIf; + pCmdQueue->bErrorFlag = TI_FALSE; + pCmdQueue->bMboxEnabled = TI_FALSE; + pCmdQueue->bAwake = TI_FALSE; + + /* Configure Command Mailbox */ + cmdMbox_Init (hCmdMbox, hReport, hTwIf, + hTimer, hCmdQueue, + cmdQueue_Error); + + /* + * NOTE: don't set uNumberOfRecoveryNodes = 0; + * its value is used by recovery process + */ + + return TI_OK; +} + + +/* + * \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 /* 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 */ + status = cmdMbox_GetStatus (pCmdQueue->hCmdMBox, &cmdStatus); + 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; +} + + +/* + * \brief Sends the command to the cmdMbox + * + * \param hCmdQueue - Handle to CmdQueue + * \param eMboxCmdType - The command type + * \param pMboxBuf - The command itself (parameters) + * \param uParamsLen - The command's length + * \param fCb - The command's Cb function + * \param hCb - The command's Cb handle + * \param pCb - Pointer to the results buffer (for interrogate commands) + * \return TI_OK on success or TI_NOK on failure + * + * \par Description + * Pushes the command to the command queue, which triggers the + * CmdQueue SM. + * + * \sa cmdQueue_Push + */ +TI_STATUS cmdQueue_SendCommand (TI_HANDLE hCmdQueue, + Command_e eMboxCmdType, + void *pMboxBuf, + TI_UINT32 uParamsLen, + void *fCb, + TI_HANDLE hCb, + void *pCb) +{ + TCmdQueue *pCmdQueue = (TCmdQueue*)hCmdQueue; + TI_STATUS status; + + if (pCmdQueue->bErrorFlag) + return TI_NOK; + + status = cmdQueue_Push (pCmdQueue, + eMboxCmdType, + (TI_UINT8*)pMboxBuf, + uParamsLen, + fCb, + hCb, + (TI_UINT8*)pCb); + + return RC_CONVERT (status); +} + + +/* + * \brief Push the command Node to the Queue with its information element parameter + * + * \param hCmdQueue - Handle to CmdQueue + * \param cmdType - The command type + * \param pParamsBuf - The command itself (parameters) + * \param uParamsLen - The command's length + * \param fCb - The command's Cb function + * \param hCb - The command's Cb handle + * \param pCb - Pointer to the results buffer (for interrogate commands) + * \return TI_OK on success or TI_NOK on failure + * + * \par Description + * + * \sa cmdQueue_SendCommand, cmdQueue_SM + */ +static TI_STATUS cmdQueue_Push (TI_HANDLE hCmdQueue, + Command_e cmdType, + TI_UINT8 *pParamsBuf, + TI_UINT32 uParamsLen, + void *fCb, + TI_HANDLE hCb, + void *pCb) +{ + TCmdQueue *pCmdQueue = (TCmdQueue*)hCmdQueue; + + /* If command type is NOT CMD_INTERROGATE, enter Push only if Mailbox is enabled */ + if (!pCmdQueue->bMboxEnabled) + return TI_OK; + + #ifdef TI_DBG + /* + * Check if Queue is Full + */ + if (pCmdQueue->uNumberOfCommandInQueue == CMDQUEUE_QUEUE_DEPTH) + { + TRACE0(pCmdQueue->hReport, REPORT_SEVERITY_ERROR, "cmdQueue_Push: ** ERROR ** The Queue is full\n"); + + return TI_NOK; + } + #endif /* TI_DBG*/ + + /* Initializes the last Node in the Queue with the arrgs */ + pCmdQueue->aCmdQueue[pCmdQueue->tail].cmdType = cmdType; + pCmdQueue->aCmdQueue[pCmdQueue->tail].uParamsLen = uParamsLen; + pCmdQueue->aCmdQueue[pCmdQueue->tail].fCb = fCb; + pCmdQueue->aCmdQueue[pCmdQueue->tail].hCb = hCb; + + os_memoryCopy (pCmdQueue->hOs, + pCmdQueue->aCmdQueue[pCmdQueue->tail].aParamsBuf, + pParamsBuf, + uParamsLen); + + pCmdQueue->aCmdQueue[pCmdQueue->tail].pInterrogateBuf = (TI_UINT8 *)pCb; + + /* Advance the queue tail*/ + pCmdQueue->tail++; + if (pCmdQueue->tail == CMDQUEUE_QUEUE_DEPTH) + pCmdQueue->tail = 0; + + /* Update counters */ + pCmdQueue->uNumberOfCommandInQueue++; + + #ifdef TI_DBG + if (pCmdQueue->uMaxNumberOfCommandInQueue < pCmdQueue->uNumberOfCommandInQueue) + { + pCmdQueue->uMaxNumberOfCommandInQueue = pCmdQueue->uNumberOfCommandInQueue; + } + #endif /* TI_DBG*/ + + #ifdef CMDQUEUE_DEBUG_PRINT + WLAN_OS_REPORT(("cmdQueue_Push: CmdType = %s (%s(%d))" + "Len = %d, NumOfCmd = %d \n", + cmdQueue_GetCmdString(cmdType), + (pParamsBuf) ? cmdQueue_GetIEString(cmdType,*(TI_UINT16 *)pParamsBuf):"", + (pParamsBuf) ? *(TI_UINT16 *)pParamsBuf:0, + uParamsLen, pCmdQueue->uNumberOfCommandInQueue)); + #endif + + /* If queue has only one command trigger the send command from queue */ + if (pCmdQueue->uNumberOfCommandInQueue == 1) + { + return cmdQueue_SM (pCmdQueue, CMDQUEUE_EVENT_RUN); + } + else + { + return TI_OK; + } +} + + +/* + * \brief Notify the CmdQueue SM on the result received. + * + * \param hCmdQueue - Handle to CmdQueue + * \return TI_OK on success or TI_NOK on failure + * + * \par Description + * Call the CmdQueue SM with CMDQUEUE_EVENT_COMPLETE + * + * \sa cmdQueue_SM + */ +TI_STATUS cmdQueue_ResultReceived(TI_HANDLE hCmdQueue) +{ + TCmdQueue *pCmdQueue = (TCmdQueue*)hCmdQueue; + + return cmdQueue_SM (pCmdQueue, CMDQUEUE_EVENT_COMPLETE); +} + + +/* + * \brief Prepere the command queue for recovery. + * + * \param hCmdQueue - Handle to CmdQueue + * \return TI_OK + * + * \par Description + * Copy the queue nodes to a recovery list, in order handle + * the commands CB's after recovery has finished + * + * \sa cmdQueue_EndReconfig + */ +TI_STATUS cmdQueue_Restart (TI_HANDLE hCmdQueue) +{ + TCmdQueue* pCmdQueue = (TCmdQueue*) hCmdQueue; + TI_UINT32 uCurrentCmdIndex; + TI_UINT32 first = pCmdQueue->head; + TCmdQueueNode *pHead; + TCmdQueueRecoveryNode *pRecoveryNode; + + /* + * Stop the SM + */ + pCmdQueue->state = CMDQUEUE_STATE_IDLE; + pCmdQueue->bAwake = TI_FALSE; + +TRACE0(pCmdQueue->hReport, REPORT_SEVERITY_INFORMATION, "cmdQueue_Clean: Cleaning aCmdQueue Queue"); + + /* + * Save The Call Back Function in the Queue in order the return them after the recovery + * with an error status + */ + + /* Clean The Command Call Back Counter */ + pCmdQueue->uNumberOfRecoveryNodes = 0; + pRecoveryNode = &pCmdQueue->aRecoveryQueue[pCmdQueue->uNumberOfRecoveryNodes]; + + for (uCurrentCmdIndex = 0; + uCurrentCmdIndex < pCmdQueue->uNumberOfCommandInQueue; + uCurrentCmdIndex++) + { + pHead = &pCmdQueue->aCmdQueue[first]; + + if (pHead->fCb != NULL) + { + /*Copy the interrogate CB and the interrogate data buffer pointer */ + pRecoveryNode->fCb = pHead->fCb; + pRecoveryNode->hCb = pHead->hCb; + pRecoveryNode->pInterrogateBuf = pHead->pInterrogateBuf; + pCmdQueue->uNumberOfRecoveryNodes++; + pRecoveryNode = &pCmdQueue->aRecoveryQueue[pCmdQueue->uNumberOfRecoveryNodes]; + } + first++; + if (first == CMDQUEUE_QUEUE_DEPTH) + first = 0; + } + + /* + * Init the queue + */ + pCmdQueue->head = 0; + pCmdQueue->tail = 0; + pCmdQueue->uNumberOfCommandInQueue = 0; + + return TI_OK; +} + + +/* + * \brief Call the stored CB to end the recovery of the MBox queue + * + * \param hCmdQueue - Handle to CmdQueue + * \return TI_OK + * + * \par Description + * Call the stored CB's with an error status + * + * \sa cmdQueue_StartReconfig + */ +TI_STATUS cmdQueue_EndReconfig (TI_HANDLE hCmdQueue) +{ + TCmdQueue* pCmdQueue = (TCmdQueue*) hCmdQueue; + TI_UINT32 uCbIndex; + TCmdQueueRecoveryNode *pHead; + + for (uCbIndex = 0; uCbIndex < pCmdQueue->uNumberOfRecoveryNodes; uCbIndex++) + { + pHead = &pCmdQueue->aRecoveryQueue[uCbIndex]; + + if (pHead->pInterrogateBuf) + { + ((TCmdQueueInterrogateCb)pHead->fCb)(pHead->hCb, CMD_STATUS_FW_RESET, pHead->pInterrogateBuf); + } + else + { + ((TCmdQueueCb)pHead->fCb)(pHead->hCb, CMD_STATUS_FW_RESET); + } + } + + pCmdQueue->uNumberOfRecoveryNodes = 0; + + return TI_OK; +} + + +/* + * \brief Register for a call back to be called when Command Complete occured and the CmdMboxCB was NULL + * + * \param hCmdQueue - Handle to CmdQueue + * \param fCb - The command's Cb function + * \param hCb - The command's Cb handle + * \return TI_OK + * + * \par Description + * + * \sa + */ +TI_STATUS cmdQueue_RegisterCmdCompleteGenericCb (TI_HANDLE hCmdQueue, void *fCb, TI_HANDLE hCb) +{ + TCmdQueue* pCmdQueue = (TCmdQueue*)hCmdQueue; + + if (fCb == NULL || hCb == NULL) + { +TRACE0(pCmdQueue->hReport, REPORT_SEVERITY_ERROR, "cmdQueue_RegisterCmdCompleteGenericCB: NULL parameter\n"); + return TI_NOK; + } + + pCmdQueue->fCmdCompleteCb = (TCmdQueueGenericCb)fCb; + pCmdQueue->hCmdCompleteCb = hCb; + + return TI_OK; +} + + +/* + * \brief Register for a call back to be called when an Error (Timeout) occurs + * + * \param hCmdQueue - Handle to CmdQueue + * \param fCb - The command's Cb function + * \param hCb - The command's Cb handle + * \return TI_OK + * + * \par Description + * + * \sa + */ +TI_STATUS cmdQueue_RegisterForErrorCb (TI_HANDLE hCmdQueue, void *fCb, TI_HANDLE hCb) +{ + TCmdQueue* pCmdQueue = (TCmdQueue*)hCmdQueue; + + if (fCb == NULL || hCb == NULL) + { +TRACE0(pCmdQueue->hReport, REPORT_SEVERITY_ERROR, "cmdQueue_RegisterForErrorCB: NULL parameters\n"); + return TI_NOK; + } + + pCmdQueue->hFailureCb = hCb; + pCmdQueue->fFailureCb = (TCmdQueueCb)fCb; + + return TI_OK; +} + + +/* + * \brief Enables the CmdMbox (on exit from init mode) + * + * \param hCmdQueue - Handle to CmdQueue + * \return TI_OK + * + * \par Description + * + * \sa cmdQueue_DisableMbox + */ +TI_STATUS cmdQueue_EnableMbox (TI_HANDLE hCmdQueue) +{ + TCmdQueue* pCmdQueue = (TCmdQueue*)hCmdQueue; + + pCmdQueue->bMboxEnabled = TI_TRUE; + + return TI_OK; +} + + +/* + * \brief Disables the CmdMbox (when stopping the driver) + * + * \param hCmdQueue - Handle to CmdQueue + * \return TI_OK + * + * \par Description + * + * \sa cmdQueue_EnableMbox + */ +TI_STATUS cmdQueue_DisableMbox (TI_HANDLE hCmdQueue) +{ + TCmdQueue* pCmdQueue = (TCmdQueue*)hCmdQueue; + + pCmdQueue->bMboxEnabled = TI_FALSE; + + return TI_OK; +} + + +/* + * \brief Called when a command timeout occur + * + * \param hCmdQueue - Handle to CmdQueue + * \return TI_OK + * + * \par Description + * + * \sa cmdQueue_Init, cmdMbox_TimeOut + */ +TI_STATUS cmdQueue_Error (TI_HANDLE hCmdQueue, TI_UINT32 command, TI_UINT32 status, void *param) +{ + TCmdQueue* pCmdQueue = (TCmdQueue*)hCmdQueue; + + if (status == CMD_STATUS_UNKNOWN_CMD) + { + TRACE1(pCmdQueue->hReport, REPORT_SEVERITY_ERROR , "cmdQueue_Error: Unknown Cmd (%d)\n", command); + } + else if (status == CMD_STATUS_UNKNOWN_IE) + { + TRACE4(pCmdQueue->hReport, REPORT_SEVERITY_CONSOLE,"cmdQueue_Error: Unknown IE, cmdType : %d (%d) IE: %d (%d)\n", command, command, (param) ? *(TI_UINT16 *) param : 0, *((TI_UINT16 *) param)); + + WLAN_OS_REPORT(("cmdQueue_Error: Unknown IE, cmdType : %s (%d) IE: %s (%d)\n", + cmdQueue_GetCmdString (command), + command, + (param) ? cmdQueue_GetIEString (command, *((TI_UINT16 *) param)) : "", + *((TI_UINT16 *) param))); + } + else + { + TRACE1(pCmdQueue->hReport, REPORT_SEVERITY_ERROR , "cmdQueue_Error: CmdMbox status is %d\n", status); + } + + if (status != CMD_STATUS_UNKNOWN_CMD && status != CMD_STATUS_UNKNOWN_IE) + { +#ifdef TI_DBG +#ifdef REPORT_LOG + TCmdQueueNode* pHead = &pCmdQueue->aCmdQueue[pCmdQueue->head]; + TI_UINT32 TimeStamp = os_timeStampMs(pCmdQueue->hOs); + + WLAN_OS_REPORT(("cmdQueue_Error: **ERROR** Command Occured \n" + " Cmd = %s %s, Len = %d \n" + " NumOfCmd = %d\n" + " MAC TimeStamp on timeout = %d\n", + cmdQueue_GetCmdString(pHead->cmdType), + (pHead->aParamsBuf) ? cmdQueue_GetIEString(pHead->cmdType, *(TI_UINT16 *)pHead->aParamsBuf) : "", + pHead->uParamsLen, + pCmdQueue->uNumberOfCommandInQueue, + TimeStamp)); +#endif + /* Print The command that was sent before the timeout occur */ + cmdQueue_PrintHistory(pCmdQueue, CMDQUEUE_HISTORY_DEPTH); + +#endif /* TI_DBG */ + + /* preform Recovery */ + if (pCmdQueue->fFailureCb) + { + pCmdQueue->fFailureCb (pCmdQueue->hFailureCb, TI_NOK); + } + } + + return TI_OK; +} + + +/* + * \brief Returns maximum number of commands (ever) in TCmdQueue queue + * + * \param hCmdQueue - Handle to CmdQueue + * \return maximum number of commands (ever) in mailbox queue + * + * \par Description + * Used for debugging purposes + * + * \sa cmdQueue_Error + */ +TI_UINT32 cmdQueue_GetMaxNumberOfCommands (TI_HANDLE hCmdQueue) +{ + TCmdQueue* pCmdQueue = (TCmdQueue*)hCmdQueue; + + return pCmdQueue->uMaxNumberOfCommandInQueue; +} + + + +/******************************************************************************** +* DEBUG FUNCTIONS * +*********************************************************************************/ + +#ifdef TI_DBG + +/* + * \brief Print the command queue & statistics + * + * \param hCmdQueue - Handle to CmdQueue + * \return void + * + * \par Description + * Used for debugging purposes + * + * \sa cmdQueue_PrintQueue + */ +void cmdQueue_Print (TI_HANDLE hCmdQueue) +{ + TCmdQueue* pCmdQueue = (TCmdQueue*)hCmdQueue; + + WLAN_OS_REPORT(("------------- aCmdQueue Queue -------------------\n")); + + WLAN_OS_REPORT(("state = %d\n", pCmdQueue->state)); + WLAN_OS_REPORT(("cmdQueue_Print:The Max NumOfCmd in Queue was = %d\n", + pCmdQueue->uMaxNumberOfCommandInQueue)); + WLAN_OS_REPORT(("cmdQueue_Print:The Current NumOfCmd in Queue = %d\n", + pCmdQueue->uNumberOfCommandInQueue)); + WLAN_OS_REPORT(("cmdQueue_Print:The Total number of Cmd send from Queue= %d\n", + pCmdQueue->uCmdSendCounter)); + WLAN_OS_REPORT(("cmdQueue_Print:The Total number of Cmd Completed interrupt= %d\n", + pCmdQueue->uCmdCompltCounter)); + + cmdQueue_PrintQueue (pCmdQueue); +} + + +/* + * \brief Print the command queue + * + * \param pCmdQueue - Pointer to TCmdQueue + * \return void + * + * \par Description + * Used for debugging purposes + * + * \sa cmdQueue_Print, cmdQueue_GetCmdString, cmdQueue_GetIEString + */ +static void cmdQueue_PrintQueue (TCmdQueue *pCmdQueue) +{ + TI_UINT32 uCurrentCmdIndex; + TI_UINT32 first = pCmdQueue->head; + TCmdQueueNode* pHead; + TI_UINT32 NumberOfCommand = pCmdQueue->uNumberOfCommandInQueue; + + for(uCurrentCmdIndex = 0 ; uCurrentCmdIndex < NumberOfCommand ; uCurrentCmdIndex++) + { + pHead = &pCmdQueue->aCmdQueue[first]; + + WLAN_OS_REPORT(("Cmd index %d CmdType = %s %s, Len = %d, Place in Queue = %d \n", + uCurrentCmdIndex, + cmdQueue_GetCmdString(pHead->cmdType), + cmdQueue_GetIEString(pHead->cmdType, (((pHead->cmdType == CMD_INTERROGATE)||(pHead->cmdType == CMD_CONFIGURE)) ? *(TI_UINT16 *)pHead->aParamsBuf : 0)), + pHead->uParamsLen, + first)); + + first++; + if (first == CMDQUEUE_QUEUE_DEPTH) + { + first = 0; + } + } +} + + +/* + * \brief print the last uNumOfCmd commands + * + * \param hCmdQueue - Handle to CmdQueue + * \param uNumOfCmd - Number of commands to print + * \return void + * + * \par Description + * Used for debugging purposes + * + * \sa cmdQueue_Error + */ +void cmdQueue_PrintHistory (TI_HANDLE hCmdQueue, TI_UINT32 uNumOfCmd) +{ +#ifdef REPORT_LOG + TCmdQueue* pCmdQueue = (TCmdQueue*)hCmdQueue; + TI_UINT32 uCurrentCmdIndex; + TI_UINT32 first = pCmdQueue->head; + TCmdQueueNode* pHead; + + WLAN_OS_REPORT(("--------------- cmdQueue_PrintHistory of %d -------------------\n",uNumOfCmd)); + + for (uCurrentCmdIndex = 0; uCurrentCmdIndex < uNumOfCmd; uCurrentCmdIndex++) + { + pHead = &pCmdQueue->aCmdQueue[first]; + + WLAN_OS_REPORT(("Cmd index %d CmdType = %s %s, Len = %d, Place in Queue = %d \n", + uCurrentCmdIndex, + cmdQueue_GetCmdString(pHead->cmdType), + cmdQueue_GetIEString(pHead->cmdType, (((pHead->cmdType == CMD_INTERROGATE)||(pHead->cmdType == CMD_CONFIGURE)) ? *(TI_UINT16 *)pHead->aParamsBuf : 0)), + pHead->uParamsLen, + first)); + + if (first == 0) + { + first = CMDQUEUE_QUEUE_DEPTH - 1; + } + else + { + first--; + } + } + + WLAN_OS_REPORT(("-----------------------------------------------------------------------\n")); +#endif +} + +#ifdef REPORT_LOG +/* + * \brief Interperts the command's type to the command's name + * + * \param MboxCmdType - The command type + * \return The command name + * + * \par Description + * Used for debugging purposes + * + * \sa + */ +static char* cmdQueue_GetCmdString (TI_INT32 MboxCmdType) + { + switch (MboxCmdType) + { + case 0: return "CMD_RESET"; + case 1: return "CMD_INTERROGATE"; + case 2: return "CMD_CONFIGURE"; + case 3: return "CMD_ENABLE_RX"; + case 4: return "CMD_ENABLE_TX"; + case 5: return "CMD_DISABLE_RX"; + case 6: return "CMD_DISABLE_TX"; + case 8: return "CMD_SCAN"; + case 9: return "CMD_STOP_SCAN"; + case 10: return "CMD_VBM"; + case 11: return "CMD_START_JOIN"; + case 12: return "CMD_SET_KEYS"; + case 13: return "CMD_READ_MEMORY"; + case 14: return "CMD_WRITE_MEMORY"; + case 19: return "CMD_SET_TEMPLATE"; + case 23: return "CMD_TEST"; + case 27: return "CMD_ENABLE_RX_PATH"; + case 28: return "CMD_NOISE_HIST"; + case 29: return "CMD_RX_RESET"; + case 32: return "CMD_LNA_CONTROL"; + case 33: return "CMD_SET_BCN_MODE"; + case 34: return "CMD_MEASUREMENT"; + case 35: return "CMD_STOP_MEASUREMENT"; + case 36: return "CMD_DISCONNECT"; + case 37: return "CMD_SET_PS_MODE"; + case 38: return "CMD_CHANNEL_SWITCH"; + case 39: return "CMD_STOP_CHANNEL_SWICTH"; + case 40: return "CMD_AP_DISCOVERY"; + case 41: return "CMD_STOP_AP_DISCOVERY"; + case 42: return "CMD_SPS_SCAN"; + case 43: return "CMD_STOP_SPS_SCAN"; + case 45: return "CMD_HEALTH_CHECK"; + case 48: return "CMD_CONNECTION_SCAN_CFG"; + case 49: return "CMD_CONNECTION_SCAN_SSID_CFG"; + case 50: return "CMD_START_PERIODIC_SCAN"; + case 51: return "CMD_STOP_PERIODIC_SCAN"; + case 52: return "CMD_SET_STATUS"; + default: return " *** Error No Such CMD **** "; + } + } + +/* + * \brief Interperts the command's IE to the command's IE name + * + * \param MboxCmdType - The command IE number + * \return The command IE name + * + * \par Description + * Used for debugging purposes + * + * \sa + */ +static char * cmdQueue_GetIEString (TI_INT32 MboxCmdType, TI_UINT16 Id) +{ + if( MboxCmdType== CMD_INTERROGATE || MboxCmdType == CMD_CONFIGURE) + { + switch (Id) + { + case ACX_WAKE_UP_CONDITIONS: return " (ACX_WAKE_UP_CONDITIONS)"; + case ACX_MEM_CFG: return " (ACX_MEM_CFG)"; + case ACX_SLOT: return " (ACX_SLOT) "; + case ACX_AC_CFG: return " (ACX_AC_CFG) "; + case ACX_MEM_MAP: return " (ACX_MEM_MAP)"; + case ACX_AID: return " (ACX_AID)"; + case ACX_MEDIUM_USAGE: return " (ACX_MEDIUM_USAGE) "; + case ACX_RX_CFG: return " (ACX_RX_CFG) "; + case ACX_STATISTICS: return " (ACX_STATISTICS) "; + case ACX_FEATURE_CFG: return " (ACX_FEATURE_CFG) "; + case ACX_TID_CFG: return " (ACX_TID_CFG) "; + case ACX_BEACON_FILTER_OPT: return " (ACX_BEACON_FILTER_OPT) "; + case ACX_NOISE_HIST: return " (ACX_NOISE_HIST)"; + case ACX_PD_THRESHOLD: return " (ACX_PD_THRESHOLD) "; + case ACX_TX_CONFIG_OPT: return " (ACX_TX_CONFIG_OPT) "; + case ACX_CCA_THRESHOLD: return " (ACX_CCA_THRESHOLD)"; + case ACX_EVENT_MBOX_MASK: return " (ACX_EVENT_MBOX_MASK) "; + case ACX_CONN_MONIT_PARAMS: return " (ACX_CONN_MONIT_PARAMS) "; + case ACX_CONS_TX_FAILURE: return " (ACX_CONS_TX_FAILURE) "; + case ACX_BCN_DTIM_OPTIONS: return " (ACX_BCN_DTIM_OPTIONS) "; + case ACX_SG_ENABLE: return " (ACX_SG_ENABLE) "; + case ACX_SG_CFG: return " (ACX_SG_CFG) "; + case ACX_FM_COEX_CFG: return " (ACX_FM_COEX_CFG) "; + case ACX_BEACON_FILTER_TABLE: return " (ACX_BEACON_FILTER_TABLE) "; + case ACX_ARP_IP_FILTER: return " (ACX_ARP_IP_FILTER) "; + case ACX_ROAMING_STATISTICS_TBL: return " (ACX_ROAMING_STATISTICS_TBL) "; + case ACX_RATE_POLICY: return " (ACX_RATE_POLICY) "; + case ACX_CTS_PROTECTION: return " (ACX_CTS_PROTECTION) "; + case ACX_SLEEP_AUTH: return " (ACX_SLEEP_AUTH) "; + case ACX_PREAMBLE_TYPE: return " (ACX_PREAMBLE_TYPE) "; + case ACX_ERROR_CNT: return " (ACX_ERROR_CNT) "; + case ACX_IBSS_FILTER: return " (ACX_IBSS_FILTER) "; + case ACX_SERVICE_PERIOD_TIMEOUT: return " (ACX_SERVICE_PERIOD_TIMEOUT) "; + case ACX_TSF_INFO: return " (ACX_TSF_INFO) "; + case ACX_CONFIG_PS_WMM: return " (ACX_CONFIG_PS_WMM) "; + case ACX_ENABLE_RX_DATA_FILTER: return " (ACX_ENABLE_RX_DATA_FILTER) "; + case ACX_SET_RX_DATA_FILTER: return " (ACX_SET_RX_DATA_FILTER) "; + case ACX_GET_DATA_FILTER_STATISTICS:return " (ACX_GET_DATA_FILTER_STATISTICS) "; + case ACX_RX_CONFIG_OPT: return " (ACX_RX_CONFIG_OPT) "; + case ACX_FRAG_CFG: return " (ACX_FRAG_CFG) "; + case ACX_BET_ENABLE: return " (ACX_BET_ENABLE) "; + case ACX_RSSI_SNR_TRIGGER: return " (ACX_RSSI_SNR_TRIGGER) "; + case ACX_RSSI_SNR_WEIGHTS: return " (ACX_RSSI_SNR_WEIGHTS) "; + case ACX_KEEP_ALIVE_MODE: return " (ACX_KEEP_ALIVE_MODE) "; + case ACX_SET_KEEP_ALIVE_CONFIG: return " (ACX_SET_KEEP_ALIVE_CONFIG) "; + case DOT11_RX_MSDU_LIFE_TIME: return " (DOT11_RX_MSDU_LIFE_TIME) "; + case DOT11_CUR_TX_PWR: return " (DOT11_CUR_TX_PWR) "; + case DOT11_RTS_THRESHOLD: return " (DOT11_RTS_THRESHOLD) "; + case DOT11_GROUP_ADDRESS_TBL: return " (DOT11_GROUP_ADDRESS_TBL) "; + + default: return " *** Error No Such IE **** "; + } + } + return ""; +} +#endif +#endif /* TI_DBG */ + + |