/* * 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 */