/* * \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, (param) ? *((TI_UINT16 *) param) : 0 ); 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 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)); /* 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 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) { 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")); }
/* * \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 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 if (pHead->cmdType == CMD_NOP) { /* NOP command is used for synchronizaiton purpose only, no FW transaction */ eCmdQueueEvent = CMDQUEUE_EVENT_COMPLETE; break; } 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 */ if (pHead->cmdType != CMD_NOP) { status = cmdMbox_GetStatus (pCmdQueue->hCmdMBox, &cmdStatus); } else { /* NOP command is used for synchronizaiton purpose only, no FW transaction */ status = TI_OK; } 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; }