| /* |
| * 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 ACX_SET_DCO_ITRIM_PARAMS: return " (ACX_SET_DCO_ITRIM_PARAMS) "; |
| 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 */ |
| |
| |