1/* 2 * CmdQueue.c 3 * 4 * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name Texas Instruments nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 35/** \file CmdQueue.c 36 * \brief Handle the wlan command queue 37 * 38 * \see CmdQueue.h, CmdQueue_api.h, CmdMBox.c 39 */ 40 41 42#define __FILE_ID__ FILE_ID_97 43#include "tidef.h" 44#include "osApi.h" 45#include "report.h" 46#include "TwIf.h" 47#include "public_commands.h" 48#include "CmdQueue_api.h" 49#include "CmdMBox_api.h" 50#include "CmdQueue.h" 51 52/***************************************************************************** 53 ** Internal functions prototypes ** 54 *****************************************************************************/ 55 56static TI_STATUS cmdQueue_SM (TI_HANDLE hCmdQueue, ECmdQueueSmEvents event); 57static TI_STATUS cmdQueue_Push (TI_HANDLE hCmdQueue, 58 Command_e cmdType, 59 TI_UINT8 *pParamsBuf, 60 TI_UINT32 uParamsLen, 61 void *fCb, 62 TI_HANDLE hCb, 63 void *pCb); 64#ifdef TI_DBG 65static void cmdQueue_PrintQueue(TCmdQueue *pCmdQueue); 66#ifdef REPORT_LOG 67static char * cmdQueue_GetIEString (TI_INT32 MboxCmdType, TI_UINT16 id); 68static char * cmdQueue_GetCmdString (TI_INT32 MboxCmdType); 69#endif 70#endif /* TI_DBG */ 71 72 73 74 75/* 76 * \brief Create the TCmdQueue object 77 * 78 * \param hOs - OS module object handle 79 * \return Handle to the created object 80 * 81 * \par Description 82 * Calling this function creates a CmdQueue object 83 * 84 * \sa cmdQueue_Destroy 85 */ 86TI_HANDLE cmdQueue_Create (TI_HANDLE hOs) 87{ 88 TCmdQueue *pCmdQueue; 89 90 pCmdQueue = os_memoryAlloc (hOs, sizeof(TCmdQueue)); 91 if (pCmdQueue == NULL) 92 { 93 WLAN_OS_REPORT(("FATAL ERROR: cmdQueue_Create(): Error Creating aCmdQueue - Aborting\n")); 94 return NULL; 95 } 96 97 /* reset control module control block */ 98 os_memoryZero (hOs, pCmdQueue, sizeof(TCmdQueue)); 99 pCmdQueue->hOs = hOs; 100 101 return pCmdQueue; 102} 103 104 105/* 106 * \brief Destroys the cmdQueue object 107 * 108 * \param hCmdMbox - The object to free 109 * \return TI_OK 110 * 111 * \par Description 112 * Calling this function destroys the cmdQueue object 113 * 114 * \sa cmdQueue_Create 115 */ 116TI_STATUS cmdQueue_Destroy (TI_HANDLE hCmdQueue) 117{ 118 TCmdQueue* pCmdQueue = (TCmdQueue*)hCmdQueue; 119 120 /* Free context */ 121 os_memoryFree (pCmdQueue->hOs, pCmdQueue, sizeof(TCmdQueue)); 122 123 return TI_OK; 124} 125 126 127/* 128 * \brief Configure the CmdQueue object 129 * 130 * \param hCmdQueue - Handle to CmdQueue 131 * \param hCmdMbox - Handle to CmdMbox 132 * \param hReport - Handle to report module 133 * \param hTwIf - Handle to TwIf 134 * \param hTimer - Handle to os timer 135 * \return TI_OK on success or TI_NOK on failure 136 * 137 * \par Description 138 * 139 * \sa 140 */ 141TI_STATUS cmdQueue_Init (TI_HANDLE hCmdQueue, 142 TI_HANDLE hCmdMbox, 143 TI_HANDLE hReport, 144 TI_HANDLE hTwIf, 145 TI_HANDLE hTimer) 146{ 147 TCmdQueue* pCmdQueue = (TCmdQueue*) hCmdQueue; 148 149 pCmdQueue->head = 0; 150 pCmdQueue->tail = 0; 151 pCmdQueue->uNumberOfCommandInQueue = 0; 152 pCmdQueue->uMaxNumberOfCommandInQueue = 0; 153 pCmdQueue->state = CMDQUEUE_STATE_IDLE; 154 pCmdQueue->fCmdCompleteCb = NULL; 155 pCmdQueue->hCmdCompleteCb = NULL; 156 pCmdQueue->fFailureCb = NULL; 157 pCmdQueue->hFailureCb = NULL; 158 pCmdQueue->hReport = hReport; 159 pCmdQueue->hCmdMBox = hCmdMbox; 160 pCmdQueue->hTwIf = hTwIf; 161 pCmdQueue->bErrorFlag = TI_FALSE; 162 pCmdQueue->bMboxEnabled = TI_FALSE; 163 pCmdQueue->bAwake = TI_FALSE; 164 165 /* Configure Command Mailbox */ 166 cmdMbox_Init (hCmdMbox, hReport, hTwIf, 167 hTimer, hCmdQueue, 168 cmdQueue_Error); 169 170 /* 171 * NOTE: don't set uNumberOfRecoveryNodes = 0; 172 * its value is used by recovery process 173 */ 174 175 return TI_OK; 176} 177 178 179/* 180 * \brief Configure the CmdQueue object 181 * 182 * \param hCmdQueue - Handle to CmdQueue 183 * \param eCmdQueueEvent - The event that triggered the SM 184 * \return TI_OK on success or TI_NOK on failure 185 * 186 * \par Description 187 * Handles the CmdQueue SM. 188 * 189 * \sa cmdQueue_Push, cmdQueue_ResultReceived 190 */ 191static TI_STATUS cmdQueue_SM (TI_HANDLE hCmdQueue, ECmdQueueSmEvents eCmdQueueEvent) 192{ 193 TCmdQueue *pCmdQueue = (TCmdQueue*)hCmdQueue; 194 TI_BOOL bBreakWhile = TI_FALSE; 195 TI_STATUS rc = TI_OK, status; 196 TCmdQueueNode *pHead; 197 TI_UINT32 uReadLen, uWriteLen; 198 199 while(!bBreakWhile) 200 { 201 switch (pCmdQueue->state) 202 { 203 case CMDQUEUE_STATE_IDLE: 204 switch(eCmdQueueEvent) 205 { 206 case CMDQUEUE_EVENT_RUN: 207 pCmdQueue->state = CMDQUEUE_STATE_WAIT_FOR_COMPLETION; 208 209 pHead = &pCmdQueue->aCmdQueue[pCmdQueue->head]; 210 211 #ifdef CMDQUEUE_DEBUG_PRINT 212 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)); 213 214 WLAN_OS_REPORT(("cmdQueue_SM: Send Cmd: CmdType = %s(%s)\n" 215 "Len = %d, NumOfCmd = %d \n", 216 cmdQueue_GetCmdString(pHead->cmdType), 217 (pHead->aParamsBuf) ? cmdQueue_GetIEString(pHead->cmdType,*(TI_UINT16 *)pHead->aParamsBuf):"", 218 pHead->uParamsLen, pCmdQueue->uNumberOfCommandInQueue)); 219 #endif 220 221 #ifdef TI_DBG 222 pCmdQueue->uCmdSendCounter++; 223 #endif 224 225 /* 226 * if bAwake is true, then we reached here because there were more commands 227 * in the queue after sending a previous command. 228 * There is no need to send another awake command to TwIf. 229 */ 230 if (pCmdQueue->bAwake == TI_FALSE) 231 { 232 /* Keep the device awake for the entire Cmd transaction */ 233 twIf_Awake(pCmdQueue->hTwIf); 234 pCmdQueue->bAwake = TI_TRUE; 235 } 236 237 if (pHead->cmdType == CMD_INTERROGATE) 238 { 239 uWriteLen = CMDQUEUE_INFO_ELEM_HEADER_LEN; 240 /* Will be updated by CmdMbox to count the status response */ 241 uReadLen = pHead->uParamsLen; 242 } 243 else if(pHead->cmdType == CMD_TEST) 244 { 245 /* CMD_TEST has configure & interrogate abillities together */ 246 uWriteLen = pHead->uParamsLen; 247 /* Will be updated by CmdMbox to count the status response */ 248 uReadLen = pHead->uParamsLen; 249 } 250 else /* CMD_CONFIGURE or others */ 251 { 252 uWriteLen = pHead->uParamsLen; 253 /* Will be updated by CmdMbox to count the status response */ 254 uReadLen = 0; 255 256 } 257 /* send the command to TNET */ 258 rc = cmdMbox_SendCommand (pCmdQueue->hCmdMBox, 259 pHead->cmdType, 260 pHead->aParamsBuf, 261 uWriteLen, 262 uReadLen); 263 264 bBreakWhile = TI_TRUE; 265 266 /* end of CMDQUEUE_EVENT_RUN */ 267 break; 268 269 default: 270 TRACE1(pCmdQueue->hReport, REPORT_SEVERITY_ERROR, "cmdQueue_SM: ** ERROR ** No such event (%d) for state CMDQUEUE_STATE_IDLE\n",eCmdQueueEvent); 271 bBreakWhile = TI_TRUE; 272 rc = TI_NOK; 273 274 break; 275 } 276 break; 277 278 case CMDQUEUE_STATE_WAIT_FOR_COMPLETION: 279 switch(eCmdQueueEvent) 280 { 281 case CMDQUEUE_EVENT_RUN: 282 /* We are in the middle of other command transaction so there is nothing top be done */ 283 bBreakWhile = TI_TRUE; 284 rc = TXN_STATUS_PENDING; 285 break; 286 287 case CMDQUEUE_EVENT_COMPLETE: 288 { 289 Command_e cmdType; 290 TI_UINT16 uParam; 291 void *fCb, *hCb, *pCb; 292 CommandStatus_e cmdStatus; 293 294 pHead = &pCmdQueue->aCmdQueue[pCmdQueue->head]; 295 296 /* Keep callback parameters in temporary variables */ 297 cmdType = pHead->cmdType; 298 uParam = *(TI_UINT16 *)pHead->aParamsBuf; 299 fCb = pHead->fCb; 300 hCb = pHead->hCb; 301 pCb = pHead->pInterrogateBuf; 302 303 /* 304 * Delete the command from the queue before calling a callback 305 * because there may be nested calls inside a callback 306 */ 307 pCmdQueue->head ++; 308 if (pCmdQueue->head >= CMDQUEUE_QUEUE_DEPTH) 309 pCmdQueue->head = 0; 310 pCmdQueue->uNumberOfCommandInQueue --; 311 312 #ifdef TI_DBG 313 pCmdQueue->uCmdCompltCounter++; 314 #endif 315 316 /* Read the latest command return status */ 317 status = cmdMbox_GetStatus (pCmdQueue->hCmdMBox, &cmdStatus); 318 if (status != TI_OK) 319 { 320 if (cmdStatus == CMD_STATUS_REJECT_MEAS_SG_ACTIVE) 321 { 322 /* return reject status in the callback */ 323 status = SG_REJECT_MEAS_SG_ACTIVE; 324 pCmdQueue->bErrorFlag = TI_FALSE; 325 } 326 else 327 { 328 WLAN_OS_REPORT(("cmdQueue_SM: ** ERROR ** Mbox status error %d, set bErrorFlag !!!!!\n", cmdStatus)); 329 TRACE1(pCmdQueue->hReport, REPORT_SEVERITY_ERROR, "cmdQueue_SM: ** ERROR ** Mbox status error %d, set bErrorFlag !!!!!\n", cmdStatus); 330 pCmdQueue->bErrorFlag = TI_TRUE; 331 } 332 } 333 else 334 { 335 pCmdQueue->bErrorFlag = TI_FALSE; 336 } 337 338 /* If the command had a CB, then call it with the proper results buffer */ 339 if (fCb) 340 { 341 if (pCb) 342 { 343 /* If pInterrogateBuf isn't NULL we need to copy the results */ 344 cmdMbox_GetCmdParams(pCmdQueue->hCmdMBox, pCb); 345 /* Call the CB with the result buffer and the returned status */ 346 ((TCmdQueueInterrogateCb)fCb) (hCb, status, pCb); 347 } 348 else 349 { 350 /* Call the CB with only the returned status */ 351 ((TCmdQueueCb)fCb) (hCb, status); 352 } 353 } 354 else 355 { 356 /* Call the generic callback */ 357 if (pCmdQueue->fCmdCompleteCb) 358 { 359 pCmdQueue->fCmdCompleteCb (pCmdQueue->hCmdCompleteCb, cmdType, uParam, status); 360 } 361 } 362 363 /* Check if there are any more commands in queue */ 364 if (pCmdQueue->uNumberOfCommandInQueue > 0) 365 { 366 /* If queue isn't empty, send the next command */ 367 pCmdQueue->state = CMDQUEUE_STATE_IDLE; 368 eCmdQueueEvent = CMDQUEUE_EVENT_RUN; 369 } 370 else 371 { 372 /* If queue is empty, we can permit TwIf to send sleep a command if neccesary */ 373 twIf_Sleep(pCmdQueue->hTwIf); 374 pCmdQueue->bAwake = TI_FALSE; 375 pCmdQueue->state = CMDQUEUE_STATE_IDLE; 376 377 bBreakWhile = TI_TRUE; 378 } 379 /* end of CMDQUEUE_EVENT_COMPLETE */ 380 } 381 break; 382 383 default: 384 TRACE1(pCmdQueue->hReport, REPORT_SEVERITY_ERROR, "cmdQueue_SM: ** ERROR ** No such event (%d) for state CMDQUEUE_STATE_IDLE\n",eCmdQueueEvent); 385 bBreakWhile = TI_TRUE; 386 rc = TI_NOK; 387 388 break; 389 390 /* end of switch event */ 391 } 392 break; 393 /* end of switch state */ 394 } 395 /* end of while */ 396 } 397 398 return rc; 399} 400 401 402/* 403 * \brief Sends the command to the cmdMbox 404 * 405 * \param hCmdQueue - Handle to CmdQueue 406 * \param eMboxCmdType - The command type 407 * \param pMboxBuf - The command itself (parameters) 408 * \param uParamsLen - The command's length 409 * \param fCb - The command's Cb function 410 * \param hCb - The command's Cb handle 411 * \param pCb - Pointer to the results buffer (for interrogate commands) 412 * \return TI_OK on success or TI_NOK on failure 413 * 414 * \par Description 415 * Pushes the command to the command queue, which triggers the 416 * CmdQueue SM. 417 * 418 * \sa cmdQueue_Push 419 */ 420TI_STATUS cmdQueue_SendCommand (TI_HANDLE hCmdQueue, 421 Command_e eMboxCmdType, 422 void *pMboxBuf, 423 TI_UINT32 uParamsLen, 424 void *fCb, 425 TI_HANDLE hCb, 426 void *pCb) 427{ 428 TCmdQueue *pCmdQueue = (TCmdQueue*)hCmdQueue; 429 TI_STATUS status; 430 431 if (pCmdQueue->bErrorFlag) 432 return TI_NOK; 433 434 status = cmdQueue_Push (pCmdQueue, 435 eMboxCmdType, 436 (TI_UINT8*)pMboxBuf, 437 uParamsLen, 438 fCb, 439 hCb, 440 (TI_UINT8*)pCb); 441 442 return RC_CONVERT (status); 443} 444 445 446/* 447 * \brief Push the command Node to the Queue with its information element parameter 448 * 449 * \param hCmdQueue - Handle to CmdQueue 450 * \param cmdType - The command type 451 * \param pParamsBuf - The command itself (parameters) 452 * \param uParamsLen - The command's length 453 * \param fCb - The command's Cb function 454 * \param hCb - The command's Cb handle 455 * \param pCb - Pointer to the results buffer (for interrogate commands) 456 * \return TI_OK on success or TI_NOK on failure 457 * 458 * \par Description 459 * 460 * \sa cmdQueue_SendCommand, cmdQueue_SM 461 */ 462static TI_STATUS cmdQueue_Push (TI_HANDLE hCmdQueue, 463 Command_e cmdType, 464 TI_UINT8 *pParamsBuf, 465 TI_UINT32 uParamsLen, 466 void *fCb, 467 TI_HANDLE hCb, 468 void *pCb) 469{ 470 TCmdQueue *pCmdQueue = (TCmdQueue*)hCmdQueue; 471 472 /* If command type is NOT CMD_INTERROGATE, enter Push only if Mailbox is enabled */ 473 if (!pCmdQueue->bMboxEnabled) 474 return TI_OK; 475 476 #ifdef TI_DBG 477 /* 478 * Check if Queue is Full 479 */ 480 if (pCmdQueue->uNumberOfCommandInQueue == CMDQUEUE_QUEUE_DEPTH) 481 { 482 TRACE0(pCmdQueue->hReport, REPORT_SEVERITY_ERROR, "cmdQueue_Push: ** ERROR ** The Queue is full\n"); 483 484 return TI_NOK; 485 } 486 #endif /* TI_DBG*/ 487 488 /* Initializes the last Node in the Queue with the arrgs */ 489 pCmdQueue->aCmdQueue[pCmdQueue->tail].cmdType = cmdType; 490 pCmdQueue->aCmdQueue[pCmdQueue->tail].uParamsLen = uParamsLen; 491 pCmdQueue->aCmdQueue[pCmdQueue->tail].fCb = fCb; 492 pCmdQueue->aCmdQueue[pCmdQueue->tail].hCb = hCb; 493 494 os_memoryCopy (pCmdQueue->hOs, 495 pCmdQueue->aCmdQueue[pCmdQueue->tail].aParamsBuf, 496 pParamsBuf, 497 uParamsLen); 498 499 pCmdQueue->aCmdQueue[pCmdQueue->tail].pInterrogateBuf = (TI_UINT8 *)pCb; 500 501 /* Advance the queue tail*/ 502 pCmdQueue->tail++; 503 if (pCmdQueue->tail == CMDQUEUE_QUEUE_DEPTH) 504 pCmdQueue->tail = 0; 505 506 /* Update counters */ 507 pCmdQueue->uNumberOfCommandInQueue++; 508 509 #ifdef TI_DBG 510 if (pCmdQueue->uMaxNumberOfCommandInQueue < pCmdQueue->uNumberOfCommandInQueue) 511 { 512 pCmdQueue->uMaxNumberOfCommandInQueue = pCmdQueue->uNumberOfCommandInQueue; 513 } 514 #endif /* TI_DBG*/ 515 516 #ifdef CMDQUEUE_DEBUG_PRINT 517 WLAN_OS_REPORT(("cmdQueue_Push: CmdType = %s (%s(%d))" 518 "Len = %d, NumOfCmd = %d \n", 519 cmdQueue_GetCmdString(cmdType), 520 (pParamsBuf) ? cmdQueue_GetIEString(cmdType,*(TI_UINT16 *)pParamsBuf):"", 521 (pParamsBuf) ? *(TI_UINT16 *)pParamsBuf:0, 522 uParamsLen, pCmdQueue->uNumberOfCommandInQueue)); 523 #endif 524 525 /* If queue has only one command trigger the send command from queue */ 526 if (pCmdQueue->uNumberOfCommandInQueue == 1) 527 { 528 return cmdQueue_SM (pCmdQueue, CMDQUEUE_EVENT_RUN); 529 } 530 else 531 { 532 return TI_OK; 533 } 534} 535 536 537/* 538 * \brief Notify the CmdQueue SM on the result received. 539 * 540 * \param hCmdQueue - Handle to CmdQueue 541 * \return TI_OK on success or TI_NOK on failure 542 * 543 * \par Description 544 * Call the CmdQueue SM with CMDQUEUE_EVENT_COMPLETE 545 * 546 * \sa cmdQueue_SM 547 */ 548TI_STATUS cmdQueue_ResultReceived(TI_HANDLE hCmdQueue) 549{ 550 TCmdQueue *pCmdQueue = (TCmdQueue*)hCmdQueue; 551 552 return cmdQueue_SM (pCmdQueue, CMDQUEUE_EVENT_COMPLETE); 553} 554 555 556/* 557 * \brief Prepere the command queue for recovery. 558 * 559 * \param hCmdQueue - Handle to CmdQueue 560 * \return TI_OK 561 * 562 * \par Description 563 * Copy the queue nodes to a recovery list, in order handle 564 * the commands CB's after recovery has finished 565 * 566 * \sa cmdQueue_EndReconfig 567 */ 568TI_STATUS cmdQueue_Restart (TI_HANDLE hCmdQueue) 569{ 570 TCmdQueue* pCmdQueue = (TCmdQueue*) hCmdQueue; 571 TI_UINT32 uCurrentCmdIndex; 572 TI_UINT32 first = pCmdQueue->head; 573 TCmdQueueNode *pHead; 574 TCmdQueueRecoveryNode *pRecoveryNode; 575 576 /* 577 * Stop the SM 578 */ 579 pCmdQueue->state = CMDQUEUE_STATE_IDLE; 580 pCmdQueue->bAwake = TI_FALSE; 581 582TRACE0(pCmdQueue->hReport, REPORT_SEVERITY_INFORMATION, "cmdQueue_Clean: Cleaning aCmdQueue Queue"); 583 584 /* 585 * Save The Call Back Function in the Queue in order the return them after the recovery 586 * with an error status 587 */ 588 589 /* Clean The Command Call Back Counter */ 590 pCmdQueue->uNumberOfRecoveryNodes = 0; 591 pRecoveryNode = &pCmdQueue->aRecoveryQueue[pCmdQueue->uNumberOfRecoveryNodes]; 592 593 for (uCurrentCmdIndex = 0; 594 uCurrentCmdIndex < pCmdQueue->uNumberOfCommandInQueue; 595 uCurrentCmdIndex++) 596 { 597 pHead = &pCmdQueue->aCmdQueue[first]; 598 599 if (pHead->fCb != NULL) 600 { 601 /*Copy the interrogate CB and the interrogate data buffer pointer */ 602 pRecoveryNode->fCb = pHead->fCb; 603 pRecoveryNode->hCb = pHead->hCb; 604 pRecoveryNode->pInterrogateBuf = pHead->pInterrogateBuf; 605 pCmdQueue->uNumberOfRecoveryNodes++; 606 pRecoveryNode = &pCmdQueue->aRecoveryQueue[pCmdQueue->uNumberOfRecoveryNodes]; 607 } 608 first++; 609 if (first == CMDQUEUE_QUEUE_DEPTH) 610 first = 0; 611 } 612 613 /* 614 * Init the queue 615 */ 616 pCmdQueue->head = 0; 617 pCmdQueue->tail = 0; 618 pCmdQueue->uNumberOfCommandInQueue = 0; 619 620 return TI_OK; 621} 622 623 624/* 625 * \brief Call the stored CB to end the recovery of the MBox queue 626 * 627 * \param hCmdQueue - Handle to CmdQueue 628 * \return TI_OK 629 * 630 * \par Description 631 * Call the stored CB's with an error status 632 * 633 * \sa cmdQueue_StartReconfig 634 */ 635TI_STATUS cmdQueue_EndReconfig (TI_HANDLE hCmdQueue) 636{ 637 TCmdQueue* pCmdQueue = (TCmdQueue*) hCmdQueue; 638 TI_UINT32 uCbIndex; 639 TCmdQueueRecoveryNode *pHead; 640 641 for (uCbIndex = 0; uCbIndex < pCmdQueue->uNumberOfRecoveryNodes; uCbIndex++) 642 { 643 pHead = &pCmdQueue->aRecoveryQueue[uCbIndex]; 644 645 if (pHead->pInterrogateBuf) 646 { 647 ((TCmdQueueInterrogateCb)pHead->fCb)(pHead->hCb, CMD_STATUS_FW_RESET, pHead->pInterrogateBuf); 648 } 649 else 650 { 651 ((TCmdQueueCb)pHead->fCb)(pHead->hCb, CMD_STATUS_FW_RESET); 652 } 653 } 654 655 pCmdQueue->uNumberOfRecoveryNodes = 0; 656 657 return TI_OK; 658} 659 660 661/* 662 * \brief Register for a call back to be called when Command Complete occured and the CmdMboxCB was NULL 663 * 664 * \param hCmdQueue - Handle to CmdQueue 665 * \param fCb - The command's Cb function 666 * \param hCb - The command's Cb handle 667 * \return TI_OK 668 * 669 * \par Description 670 * 671 * \sa 672 */ 673TI_STATUS cmdQueue_RegisterCmdCompleteGenericCb (TI_HANDLE hCmdQueue, void *fCb, TI_HANDLE hCb) 674{ 675 TCmdQueue* pCmdQueue = (TCmdQueue*)hCmdQueue; 676 677 if (fCb == NULL || hCb == NULL) 678 { 679TRACE0(pCmdQueue->hReport, REPORT_SEVERITY_ERROR, "cmdQueue_RegisterCmdCompleteGenericCB: NULL parameter\n"); 680 return TI_NOK; 681 } 682 683 pCmdQueue->fCmdCompleteCb = (TCmdQueueGenericCb)fCb; 684 pCmdQueue->hCmdCompleteCb = hCb; 685 686 return TI_OK; 687} 688 689 690/* 691 * \brief Register for a call back to be called when an Error (Timeout) occurs 692 * 693 * \param hCmdQueue - Handle to CmdQueue 694 * \param fCb - The command's Cb function 695 * \param hCb - The command's Cb handle 696 * \return TI_OK 697 * 698 * \par Description 699 * 700 * \sa 701 */ 702TI_STATUS cmdQueue_RegisterForErrorCb (TI_HANDLE hCmdQueue, void *fCb, TI_HANDLE hCb) 703{ 704 TCmdQueue* pCmdQueue = (TCmdQueue*)hCmdQueue; 705 706 if (fCb == NULL || hCb == NULL) 707 { 708TRACE0(pCmdQueue->hReport, REPORT_SEVERITY_ERROR, "cmdQueue_RegisterForErrorCB: NULL parameters\n"); 709 return TI_NOK; 710 } 711 712 pCmdQueue->hFailureCb = hCb; 713 pCmdQueue->fFailureCb = (TCmdQueueCb)fCb; 714 715 return TI_OK; 716} 717 718 719/* 720 * \brief Enables the CmdMbox (on exit from init mode) 721 * 722 * \param hCmdQueue - Handle to CmdQueue 723 * \return TI_OK 724 * 725 * \par Description 726 * 727 * \sa cmdQueue_DisableMbox 728 */ 729TI_STATUS cmdQueue_EnableMbox (TI_HANDLE hCmdQueue) 730{ 731 TCmdQueue* pCmdQueue = (TCmdQueue*)hCmdQueue; 732 733 pCmdQueue->bMboxEnabled = TI_TRUE; 734 735 return TI_OK; 736} 737 738 739/* 740 * \brief Disables the CmdMbox (when stopping the driver) 741 * 742 * \param hCmdQueue - Handle to CmdQueue 743 * \return TI_OK 744 * 745 * \par Description 746 * 747 * \sa cmdQueue_EnableMbox 748 */ 749TI_STATUS cmdQueue_DisableMbox (TI_HANDLE hCmdQueue) 750{ 751 TCmdQueue* pCmdQueue = (TCmdQueue*)hCmdQueue; 752 753 pCmdQueue->bMboxEnabled = TI_FALSE; 754 755 return TI_OK; 756} 757 758 759/* 760 * \brief Called when a command timeout occur 761 * 762 * \param hCmdQueue - Handle to CmdQueue 763 * \return TI_OK 764 * 765 * \par Description 766 * 767 * \sa cmdQueue_Init, cmdMbox_TimeOut 768 */ 769TI_STATUS cmdQueue_Error (TI_HANDLE hCmdQueue, TI_UINT32 command, TI_UINT32 status, void *param) 770{ 771 TCmdQueue* pCmdQueue = (TCmdQueue*)hCmdQueue; 772 773 if (status == CMD_STATUS_UNKNOWN_CMD) 774 { 775 TRACE1(pCmdQueue->hReport, REPORT_SEVERITY_ERROR , "cmdQueue_Error: Unknown Cmd (%d)\n", command); 776 } 777 else if (status == CMD_STATUS_UNKNOWN_IE) 778 { 779 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)); 780 781 WLAN_OS_REPORT(("cmdQueue_Error: Unknown IE, cmdType : %s (%d) IE: %s (%d)\n", 782 cmdQueue_GetCmdString (command), 783 command, 784 (param) ? cmdQueue_GetIEString (command, *((TI_UINT16 *) param)) : "", 785 *((TI_UINT16 *) param))); 786 } 787 else 788 { 789 TRACE1(pCmdQueue->hReport, REPORT_SEVERITY_ERROR , "cmdQueue_Error: CmdMbox status is %d\n", status); 790 } 791 792 if (status != CMD_STATUS_UNKNOWN_CMD && status != CMD_STATUS_UNKNOWN_IE) 793 { 794#ifdef TI_DBG 795#ifdef REPORT_LOG 796 TCmdQueueNode* pHead = &pCmdQueue->aCmdQueue[pCmdQueue->head]; 797 TI_UINT32 TimeStamp = os_timeStampMs(pCmdQueue->hOs); 798 799 WLAN_OS_REPORT(("cmdQueue_Error: **ERROR** Command Occured \n" 800 " Cmd = %s %s, Len = %d \n" 801 " NumOfCmd = %d\n" 802 " MAC TimeStamp on timeout = %d\n", 803 cmdQueue_GetCmdString(pHead->cmdType), 804 (pHead->aParamsBuf) ? cmdQueue_GetIEString(pHead->cmdType, *(TI_UINT16 *)pHead->aParamsBuf) : "", 805 pHead->uParamsLen, 806 pCmdQueue->uNumberOfCommandInQueue, 807 TimeStamp)); 808#endif 809 /* Print The command that was sent before the timeout occur */ 810 cmdQueue_PrintHistory(pCmdQueue, CMDQUEUE_HISTORY_DEPTH); 811 812#endif /* TI_DBG */ 813 814 /* preform Recovery */ 815 if (pCmdQueue->fFailureCb) 816 { 817 pCmdQueue->fFailureCb (pCmdQueue->hFailureCb, TI_NOK); 818 } 819 } 820 821 return TI_OK; 822} 823 824 825/* 826 * \brief Returns maximum number of commands (ever) in TCmdQueue queue 827 * 828 * \param hCmdQueue - Handle to CmdQueue 829 * \return maximum number of commands (ever) in mailbox queue 830 * 831 * \par Description 832 * Used for debugging purposes 833 * 834 * \sa cmdQueue_Error 835 */ 836TI_UINT32 cmdQueue_GetMaxNumberOfCommands (TI_HANDLE hCmdQueue) 837{ 838 TCmdQueue* pCmdQueue = (TCmdQueue*)hCmdQueue; 839 840 return pCmdQueue->uMaxNumberOfCommandInQueue; 841} 842 843 844 845/******************************************************************************** 846* DEBUG FUNCTIONS * 847*********************************************************************************/ 848 849#ifdef TI_DBG 850 851/* 852 * \brief Print the command queue & statistics 853 * 854 * \param hCmdQueue - Handle to CmdQueue 855 * \return void 856 * 857 * \par Description 858 * Used for debugging purposes 859 * 860 * \sa cmdQueue_PrintQueue 861 */ 862void cmdQueue_Print (TI_HANDLE hCmdQueue) 863{ 864 TCmdQueue* pCmdQueue = (TCmdQueue*)hCmdQueue; 865 866 WLAN_OS_REPORT(("------------- aCmdQueue Queue -------------------\n")); 867 868 WLAN_OS_REPORT(("state = %d\n", pCmdQueue->state)); 869 WLAN_OS_REPORT(("cmdQueue_Print:The Max NumOfCmd in Queue was = %d\n", 870 pCmdQueue->uMaxNumberOfCommandInQueue)); 871 WLAN_OS_REPORT(("cmdQueue_Print:The Current NumOfCmd in Queue = %d\n", 872 pCmdQueue->uNumberOfCommandInQueue)); 873 WLAN_OS_REPORT(("cmdQueue_Print:The Total number of Cmd send from Queue= %d\n", 874 pCmdQueue->uCmdSendCounter)); 875 WLAN_OS_REPORT(("cmdQueue_Print:The Total number of Cmd Completed interrupt= %d\n", 876 pCmdQueue->uCmdCompltCounter)); 877 878 cmdQueue_PrintQueue (pCmdQueue); 879} 880 881 882/* 883 * \brief Print the command queue 884 * 885 * \param pCmdQueue - Pointer to TCmdQueue 886 * \return void 887 * 888 * \par Description 889 * Used for debugging purposes 890 * 891 * \sa cmdQueue_Print, cmdQueue_GetCmdString, cmdQueue_GetIEString 892 */ 893static void cmdQueue_PrintQueue (TCmdQueue *pCmdQueue) 894{ 895 TI_UINT32 uCurrentCmdIndex; 896 TI_UINT32 first = pCmdQueue->head; 897 TCmdQueueNode* pHead; 898 TI_UINT32 NumberOfCommand = pCmdQueue->uNumberOfCommandInQueue; 899 900 for(uCurrentCmdIndex = 0 ; uCurrentCmdIndex < NumberOfCommand ; uCurrentCmdIndex++) 901 { 902 pHead = &pCmdQueue->aCmdQueue[first]; 903 904 WLAN_OS_REPORT(("Cmd index %d CmdType = %s %s, Len = %d, Place in Queue = %d \n", 905 uCurrentCmdIndex, 906 cmdQueue_GetCmdString(pHead->cmdType), 907 cmdQueue_GetIEString(pHead->cmdType, (((pHead->cmdType == CMD_INTERROGATE)||(pHead->cmdType == CMD_CONFIGURE)) ? *(TI_UINT16 *)pHead->aParamsBuf : 0)), 908 pHead->uParamsLen, 909 first)); 910 911 first++; 912 if (first == CMDQUEUE_QUEUE_DEPTH) 913 { 914 first = 0; 915 } 916 } 917} 918 919 920/* 921 * \brief print the last uNumOfCmd commands 922 * 923 * \param hCmdQueue - Handle to CmdQueue 924 * \param uNumOfCmd - Number of commands to print 925 * \return void 926 * 927 * \par Description 928 * Used for debugging purposes 929 * 930 * \sa cmdQueue_Error 931 */ 932void cmdQueue_PrintHistory (TI_HANDLE hCmdQueue, TI_UINT32 uNumOfCmd) 933{ 934#ifdef REPORT_LOG 935 TCmdQueue* pCmdQueue = (TCmdQueue*)hCmdQueue; 936 TI_UINT32 uCurrentCmdIndex; 937 TI_UINT32 first = pCmdQueue->head; 938 TCmdQueueNode* pHead; 939 940 WLAN_OS_REPORT(("--------------- cmdQueue_PrintHistory of %d -------------------\n",uNumOfCmd)); 941 942 for (uCurrentCmdIndex = 0; uCurrentCmdIndex < uNumOfCmd; uCurrentCmdIndex++) 943 { 944 pHead = &pCmdQueue->aCmdQueue[first]; 945 946 WLAN_OS_REPORT(("Cmd index %d CmdType = %s %s, Len = %d, Place in Queue = %d \n", 947 uCurrentCmdIndex, 948 cmdQueue_GetCmdString(pHead->cmdType), 949 cmdQueue_GetIEString(pHead->cmdType, (((pHead->cmdType == CMD_INTERROGATE)||(pHead->cmdType == CMD_CONFIGURE)) ? *(TI_UINT16 *)pHead->aParamsBuf : 0)), 950 pHead->uParamsLen, 951 first)); 952 953 if (first == 0) 954 { 955 first = CMDQUEUE_QUEUE_DEPTH - 1; 956 } 957 else 958 { 959 first--; 960 } 961 } 962 963 WLAN_OS_REPORT(("-----------------------------------------------------------------------\n")); 964#endif 965} 966 967#ifdef REPORT_LOG 968/* 969 * \brief Interperts the command's type to the command's name 970 * 971 * \param MboxCmdType - The command type 972 * \return The command name 973 * 974 * \par Description 975 * Used for debugging purposes 976 * 977 * \sa 978 */ 979static char* cmdQueue_GetCmdString (TI_INT32 MboxCmdType) 980 { 981 switch (MboxCmdType) 982 { 983 case 0: return "CMD_RESET"; 984 case 1: return "CMD_INTERROGATE"; 985 case 2: return "CMD_CONFIGURE"; 986 case 3: return "CMD_ENABLE_RX"; 987 case 4: return "CMD_ENABLE_TX"; 988 case 5: return "CMD_DISABLE_RX"; 989 case 6: return "CMD_DISABLE_TX"; 990 case 8: return "CMD_SCAN"; 991 case 9: return "CMD_STOP_SCAN"; 992 case 10: return "CMD_VBM"; 993 case 11: return "CMD_START_JOIN"; 994 case 12: return "CMD_SET_KEYS"; 995 case 13: return "CMD_READ_MEMORY"; 996 case 14: return "CMD_WRITE_MEMORY"; 997 case 19: return "CMD_SET_TEMPLATE"; 998 case 23: return "CMD_TEST"; 999 case 27: return "CMD_ENABLE_RX_PATH"; 1000 case 28: return "CMD_NOISE_HIST"; 1001 case 29: return "CMD_RX_RESET"; 1002 case 32: return "CMD_LNA_CONTROL"; 1003 case 33: return "CMD_SET_BCN_MODE"; 1004 case 34: return "CMD_MEASUREMENT"; 1005 case 35: return "CMD_STOP_MEASUREMENT"; 1006 case 36: return "CMD_DISCONNECT"; 1007 case 37: return "CMD_SET_PS_MODE"; 1008 case 38: return "CMD_CHANNEL_SWITCH"; 1009 case 39: return "CMD_STOP_CHANNEL_SWICTH"; 1010 case 40: return "CMD_AP_DISCOVERY"; 1011 case 41: return "CMD_STOP_AP_DISCOVERY"; 1012 case 42: return "CMD_SPS_SCAN"; 1013 case 43: return "CMD_STOP_SPS_SCAN"; 1014 case 45: return "CMD_HEALTH_CHECK"; 1015 case 48: return "CMD_CONNECTION_SCAN_CFG"; 1016 case 49: return "CMD_CONNECTION_SCAN_SSID_CFG"; 1017 case 50: return "CMD_START_PERIODIC_SCAN"; 1018 case 51: return "CMD_STOP_PERIODIC_SCAN"; 1019 case 52: return "CMD_SET_STATUS"; 1020 default: return " *** Error No Such CMD **** "; 1021 } 1022 } 1023 1024/* 1025 * \brief Interperts the command's IE to the command's IE name 1026 * 1027 * \param MboxCmdType - The command IE number 1028 * \return The command IE name 1029 * 1030 * \par Description 1031 * Used for debugging purposes 1032 * 1033 * \sa 1034 */ 1035static char * cmdQueue_GetIEString (TI_INT32 MboxCmdType, TI_UINT16 Id) 1036{ 1037 if( MboxCmdType== CMD_INTERROGATE || MboxCmdType == CMD_CONFIGURE) 1038 { 1039 switch (Id) 1040 { 1041 case ACX_WAKE_UP_CONDITIONS: return " (ACX_WAKE_UP_CONDITIONS)"; 1042 case ACX_MEM_CFG: return " (ACX_MEM_CFG)"; 1043 case ACX_SLOT: return " (ACX_SLOT) "; 1044 case ACX_AC_CFG: return " (ACX_AC_CFG) "; 1045 case ACX_MEM_MAP: return " (ACX_MEM_MAP)"; 1046 case ACX_AID: return " (ACX_AID)"; 1047 case ACX_MEDIUM_USAGE: return " (ACX_MEDIUM_USAGE) "; 1048 case ACX_RX_CFG: return " (ACX_RX_CFG) "; 1049 case ACX_STATISTICS: return " (ACX_STATISTICS) "; 1050 case ACX_FEATURE_CFG: return " (ACX_FEATURE_CFG) "; 1051 case ACX_TID_CFG: return " (ACX_TID_CFG) "; 1052 case ACX_BEACON_FILTER_OPT: return " (ACX_BEACON_FILTER_OPT) "; 1053 case ACX_NOISE_HIST: return " (ACX_NOISE_HIST)"; 1054 case ACX_PD_THRESHOLD: return " (ACX_PD_THRESHOLD) "; 1055 case ACX_TX_CONFIG_OPT: return " (ACX_TX_CONFIG_OPT) "; 1056 case ACX_CCA_THRESHOLD: return " (ACX_CCA_THRESHOLD)"; 1057 case ACX_EVENT_MBOX_MASK: return " (ACX_EVENT_MBOX_MASK) "; 1058 case ACX_CONN_MONIT_PARAMS: return " (ACX_CONN_MONIT_PARAMS) "; 1059 case ACX_CONS_TX_FAILURE: return " (ACX_CONS_TX_FAILURE) "; 1060 case ACX_BCN_DTIM_OPTIONS: return " (ACX_BCN_DTIM_OPTIONS) "; 1061 case ACX_SG_ENABLE: return " (ACX_SG_ENABLE) "; 1062 case ACX_SG_CFG: return " (ACX_SG_CFG) "; 1063 case ACX_FM_COEX_CFG: return " (ACX_FM_COEX_CFG) "; 1064 case ACX_BEACON_FILTER_TABLE: return " (ACX_BEACON_FILTER_TABLE) "; 1065 case ACX_ARP_IP_FILTER: return " (ACX_ARP_IP_FILTER) "; 1066 case ACX_ROAMING_STATISTICS_TBL: return " (ACX_ROAMING_STATISTICS_TBL) "; 1067 case ACX_RATE_POLICY: return " (ACX_RATE_POLICY) "; 1068 case ACX_CTS_PROTECTION: return " (ACX_CTS_PROTECTION) "; 1069 case ACX_SLEEP_AUTH: return " (ACX_SLEEP_AUTH) "; 1070 case ACX_PREAMBLE_TYPE: return " (ACX_PREAMBLE_TYPE) "; 1071 case ACX_ERROR_CNT: return " (ACX_ERROR_CNT) "; 1072 case ACX_IBSS_FILTER: return " (ACX_IBSS_FILTER) "; 1073 case ACX_SERVICE_PERIOD_TIMEOUT: return " (ACX_SERVICE_PERIOD_TIMEOUT) "; 1074 case ACX_TSF_INFO: return " (ACX_TSF_INFO) "; 1075 case ACX_CONFIG_PS_WMM: return " (ACX_CONFIG_PS_WMM) "; 1076 case ACX_ENABLE_RX_DATA_FILTER: return " (ACX_ENABLE_RX_DATA_FILTER) "; 1077 case ACX_SET_RX_DATA_FILTER: return " (ACX_SET_RX_DATA_FILTER) "; 1078 case ACX_GET_DATA_FILTER_STATISTICS:return " (ACX_GET_DATA_FILTER_STATISTICS) "; 1079 case ACX_RX_CONFIG_OPT: return " (ACX_RX_CONFIG_OPT) "; 1080 case ACX_FRAG_CFG: return " (ACX_FRAG_CFG) "; 1081 case ACX_BET_ENABLE: return " (ACX_BET_ENABLE) "; 1082 case ACX_RSSI_SNR_TRIGGER: return " (ACX_RSSI_SNR_TRIGGER) "; 1083 case ACX_RSSI_SNR_WEIGHTS: return " (ACX_RSSI_SNR_WEIGHTS) "; 1084 case ACX_KEEP_ALIVE_MODE: return " (ACX_KEEP_ALIVE_MODE) "; 1085 case ACX_SET_KEEP_ALIVE_CONFIG: return " (ACX_SET_KEEP_ALIVE_CONFIG) "; 1086 case DOT11_RX_MSDU_LIFE_TIME: return " (DOT11_RX_MSDU_LIFE_TIME) "; 1087 case DOT11_CUR_TX_PWR: return " (DOT11_CUR_TX_PWR) "; 1088 case DOT11_RTS_THRESHOLD: return " (DOT11_RTS_THRESHOLD) "; 1089 case DOT11_GROUP_ADDRESS_TBL: return " (DOT11_GROUP_ADDRESS_TBL) "; 1090 1091 default: return " *** Error No Such IE **** "; 1092 } 1093 } 1094 return ""; 1095} 1096#endif 1097#endif /* TI_DBG */ 1098 1099 1100