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
56 static TI_STATUS cmdQueue_SM (TI_HANDLE hCmdQueue, ECmdQueueSmEvents event);
57 static 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
65 static void cmdQueue_PrintQueue(TCmdQueue *pCmdQueue);
66 #ifdef REPORT_LOG
67 static char * cmdQueue_GetIEString (TI_INT32 MboxCmdType, TI_UINT16 id);
68 static 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 */
cmdQueue_Create(TI_HANDLE hOs)86 TI_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 */
cmdQueue_Destroy(TI_HANDLE hCmdQueue)116 TI_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 */
cmdQueue_Init(TI_HANDLE hCmdQueue,TI_HANDLE hCmdMbox,TI_HANDLE hReport,TI_HANDLE hTwIf,TI_HANDLE hTimer)141 TI_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 */
cmdQueue_SM(TI_HANDLE hCmdQueue,ECmdQueueSmEvents eCmdQueueEvent)191 static 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 */
cmdQueue_SendCommand(TI_HANDLE hCmdQueue,Command_e eMboxCmdType,void * pMboxBuf,TI_UINT32 uParamsLen,void * fCb,TI_HANDLE hCb,void * pCb)420 TI_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 */
cmdQueue_Push(TI_HANDLE hCmdQueue,Command_e cmdType,TI_UINT8 * pParamsBuf,TI_UINT32 uParamsLen,void * fCb,TI_HANDLE hCb,void * pCb)462 static 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 */
cmdQueue_ResultReceived(TI_HANDLE hCmdQueue)548 TI_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 */
cmdQueue_Restart(TI_HANDLE hCmdQueue)568 TI_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
582 TRACE0(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 */
cmdQueue_EndReconfig(TI_HANDLE hCmdQueue)635 TI_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 */
cmdQueue_RegisterCmdCompleteGenericCb(TI_HANDLE hCmdQueue,void * fCb,TI_HANDLE hCb)673 TI_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 {
679 TRACE0(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 */
cmdQueue_RegisterForErrorCb(TI_HANDLE hCmdQueue,void * fCb,TI_HANDLE hCb)702 TI_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 {
708 TRACE0(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 */
cmdQueue_EnableMbox(TI_HANDLE hCmdQueue)729 TI_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 */
cmdQueue_DisableMbox(TI_HANDLE hCmdQueue)749 TI_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 */
cmdQueue_Error(TI_HANDLE hCmdQueue,TI_UINT32 command,TI_UINT32 status,void * param)769 TI_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 */
cmdQueue_GetMaxNumberOfCommands(TI_HANDLE hCmdQueue)836 TI_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 */
cmdQueue_Print(TI_HANDLE hCmdQueue)862 void 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 */
cmdQueue_PrintQueue(TCmdQueue * pCmdQueue)893 static 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 */
cmdQueue_PrintHistory(TI_HANDLE hCmdQueue,TI_UINT32 uNumOfCmd)932 void 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 */
cmdQueue_GetCmdString(TI_INT32 MboxCmdType)979 static 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 */
cmdQueue_GetIEString(TI_INT32 MboxCmdType,TI_UINT16 Id)1035 static 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 ACX_SET_DCO_ITRIM_PARAMS: return " (ACX_SET_DCO_ITRIM_PARAMS) ";
1087 case DOT11_RX_MSDU_LIFE_TIME: return " (DOT11_RX_MSDU_LIFE_TIME) ";
1088 case DOT11_CUR_TX_PWR: return " (DOT11_CUR_TX_PWR) ";
1089 case DOT11_RTS_THRESHOLD: return " (DOT11_RTS_THRESHOLD) ";
1090 case DOT11_GROUP_ADDRESS_TBL: return " (DOT11_GROUP_ADDRESS_TBL) ";
1091
1092 default: return " *** Error No Such IE **** ";
1093 }
1094 }
1095 return "";
1096 }
1097 #endif
1098 #endif /* TI_DBG */
1099
1100
1101