1 /****************************************************************************
2 **+-----------------------------------------------------------------------+**
3 **| |**
4 **| Copyright(c) 1998 - 2008 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
36 /****************************************************************************
37 *
38 * MODULE: txResult.c
39 *
40 * PURPOSE: Handle packets Tx results upon Tx-complete from the FW.
41 *
42 * DESCRIPTION:
43 * ============
44 * This module is called upon Tx-complete from FW.
45 * It retrieves the transmitted packets results from the FW TxResult table and
46 * calls the upper layer callback function for each packet with its results.
47 *
48 ****************************************************************************/
49
50 #include "osTIType.h"
51 #include "whalCommon.h"
52 #include "TNETWIF.h"
53 #include "whalHwDefs.h"
54 #include "txResult_api.h"
55 #include "TNETW_Driver_types.h"
56 #include "FwEvent_api.h"
57 #include "txResult.h" /* Local definitions */
58
59 /****************** static function decleration *****************************************/
60 static void txResult_handleNewEntries(txResultObj_t *pTxResult);
61 static void txResult_StateMachine(TI_HANDLE hTxResult,UINT8 module_id ,TI_STATUS status);
62 static TI_STATUS txResult_writeNewEntries(txResultObj_t *pTxResult,UINT8 currBuffer);
63
64
65 /****************************************************************************
66 * txResult_Create()
67 ****************************************************************************
68 * DESCRIPTION: Create the Tx-Result object
69 *
70 * INPUTS: hOs
71 *
72 * OUTPUT: None
73 *
74 * RETURNS: The Created object
75 ****************************************************************************/
txResult_Create(TI_HANDLE hOs)76 TI_HANDLE txResult_Create(TI_HANDLE hOs)
77 {
78 txResultObj_t *pTxResult;
79
80 pTxResult = os_memoryAlloc(hOs, sizeof(txResultObj_t));
81 if (pTxResult == NULL)
82 return NULL;
83
84 os_memoryZero(hOs, pTxResult, sizeof(txResultObj_t));
85
86 pTxResult->hOs = hOs;
87
88 return( (TI_HANDLE)pTxResult );
89 }
90
91
92 /****************************************************************************
93 * txResult_Destroy()
94 ****************************************************************************
95 * DESCRIPTION: Destroy the Tx-Result object
96 *
97 * INPUTS: hTxResult - The object to free
98 *
99 * OUTPUT: None
100 *
101 * RETURNS: OK or NOK
102 ****************************************************************************/
txResult_Destroy(TI_HANDLE hTxResult)103 TI_STATUS txResult_Destroy(TI_HANDLE hTxResult)
104 {
105 txResultObj_t *pTxResult = (txResultObj_t *)hTxResult;
106
107 if (pTxResult)
108 os_memoryFree(pTxResult->hOs, pTxResult, sizeof(txResultObj_t));
109
110 return OK;
111 }
112
113
114 /****************************************************************************
115 * txResult_init()
116 ****************************************************************************
117 DESCRIPTION:
118 ============
119 Initialize the txResult module.
120 ****************************************************************************/
txResult_init(TI_HANDLE hTxResult,TI_HANDLE hReport,TI_HANDLE hTNETWIF,TI_HANDLE hFwEvent)121 TI_STATUS txResult_init(TI_HANDLE hTxResult, TI_HANDLE hReport, TI_HANDLE hTNETWIF, TI_HANDLE hFwEvent)
122 {
123 txResultObj_t *pTxResult = (txResultObj_t *)hTxResult;
124
125 pTxResult->hReport = hReport;
126 pTxResult->hTNETWIF = hTNETWIF;
127 pTxResult->hFwEvent = hFwEvent;
128
129 txResult_restart(pTxResult);
130
131 #ifdef TI_DBG
132 os_memoryZero( pTxResult->hOs, &(pTxResult->txCompleteDepthHistogram), sizeof(UINT32) * FW_TX_CMPLT_BLOCK_SIZE );
133 #endif
134
135 FwEvent_Enable(pTxResult->hFwEvent, ACX_INTR_TX_RESULT);
136
137 return OK;
138 }
139
140
141 /****************************************************************************
142 * txResult_restart()
143 ****************************************************************************
144 DESCRIPTION:
145 ============
146 Restarts the Tx-Result module.
147 Should be called upon init and recovery!!
148 Shouldn't be called upon disconnect, since the FW provides Tx-Complete
149 for all pending packets in FW!!
150 ****************************************************************************/
txResult_restart(TI_HANDLE hTxResult)151 TI_STATUS txResult_restart(TI_HANDLE hTxResult)
152 {
153 txResultObj_t *pTxResult = (txResultObj_t *)hTxResult;
154
155 pTxResult->TxCmpltStartPointIterator = 0;
156
157 return OK;
158 }
159
160
161 /****************************************************************************
162 * txResult_setHwInfo()
163 ****************************************************************************
164 * DESCRIPTION:
165 * Called after the HW configuration upon init or recovery.
166 * Store the Tx-result table HW address.
167 *
168 * INPUTS:
169 * hTxXfer The object
170 * pDataPathParams Pointer to the HW Addresses
171 *
172 * OUTPUT: None
173 *
174 * RETURNS: None
175 ****************************************************************************/
txResult_setHwInfo(TI_HANDLE hTxResult,ACXDataPathParamsResp_t * pDataPathParams)176 void txResult_setHwInfo(TI_HANDLE hTxResult, ACXDataPathParamsResp_t *pDataPathParams)
177 {
178 txResultObj_t *pTxResult = (txResultObj_t *)hTxResult;
179
180 pTxResult->txResultTableAddr = pDataPathParams->txCompleteAddr;
181
182 /* Print of the Tx Result Table address */
183 WLAN_REPORT_INFORMATION(pTxResult->hReport, TX_RESULT_MODULE_LOG,
184 ("Get Tx-Result-Table HW-Addr: 0x%x\n", pTxResult->txResultTableAddr));
185 }
186
187
188 /****************************************************************************
189 * txResult_TxCmpltIntrCB()
190 ****************************************************************************
191 * DESCRIPTION:
192 * ============
193 * Called upon Tx-complete interrupt from the FW.
194 *
195 * INPUTS: TI_HANDLE hTxResult - the txResult object handle.
196 *
197 * OUTPUT: None
198 *
199 * RETURNS: TNETWIF_OK in Synch mode or TNETWIF_PENDING on Asynch mode.
200 ***************************************************************************/
201
202 #if FW_TX_CMPLT_BLOCK_SIZE & (FW_TX_CMPLT_BLOCK_SIZE - 1)
203 #error "FW_TX_CMPLT_BLOCK_SIZE must be power of 2"
204 #endif
205
txResult_TxCmpltIntrCB(TI_HANDLE hTxResult)206 TI_STATUS txResult_TxCmpltIntrCB (TI_HANDLE hTxResult)
207 {
208 txResultObj_t *pTxResult = (txResultObj_t *)hTxResult;
209
210 if (TX_RESULT_STATE_IDLE != pTxResult->state)
211 {
212 WLAN_REPORT_ERROR(pTxResult->hReport,TX_RESULT_MODULE_LOG,
213 ("rxXfer_RxEvent called in state %d !!!\n",pTxResult->state));
214 return TNETWIF_ERROR;
215 }
216
217 /* assume that we are in synch bus until otherwise is proven */
218 pTxResult->bSync = TRUE;
219
220 /* 0,OK has no meaning */
221 txResult_StateMachine(hTxResult,0,OK);
222
223 return pTxResult->returnValue;
224 }
225
226
227 /****************************************************************************
228 * txResult_StateMachine()
229 ****************************************************************************
230 * DESCRIPTION: main SM of the module.called in IDLE state by txResult_TxCmpltIntrCB() on
231 * Tx Complete interrupt from the FW.
232 * Reads all Tx-Result cyclic table from the FW.
233 * Goes over the valid entries (containing unread Tx-results) and calls the
234 * upper layer callback function for each packet with its results.
235 * At the end - writes all new results back to the FW
236 * The flow of the SM is by that order:
237 * IDLE -> READING -> WRITING1 -> WRITING2 -> EXIT
238 * On synch mode - each state is called in the same context in the while loop.
239 * On Asynch mode - each state returns TNETWIF_PENDING and exits the SM.The CB of
240 * each Asynch is the SM, that will continue the handling.
241 *
242 *
243 *
244 * INPUTS: module_id - not used (for prototype only).
245 * status - not used (for prototype only).
246 *
247 * OUTPUT: returnValue - This parameter is used to indicate the FwEvent mosule about the status of
248 * the client.if (returnValue == TNETWIF_OK) than client finished working (synch mode)
249 * if (returnValue == TNETWIF_PENDING) than FwEvent module is waiting to be notified
250 * that client finished the handling (Asynch mode)
251 *
252 * RETURNS: None
253 ****************************************************************************/
txResult_StateMachine(TI_HANDLE hTxResult,UINT8 module_id,TI_STATUS status)254 static void txResult_StateMachine(TI_HANDLE hTxResult,UINT8 module_id ,TI_STATUS status)
255 {
256 txResultObj_t *pTxResult = (txResultObj_t *)hTxResult;
257
258 pTxResult->returnValue = OK;
259
260 /* this while loop will continue till the exit or when waiting for the CB due to
261 memory transfer operation pending for DMA to complete */
262 while (TNETWIF_PENDING != pTxResult->returnValue)
263 {
264 WLAN_REPORT_INFORMATION(pTxResult->hReport,TX_RESULT_MODULE_LOG,
265 ("txResult SM: state = %d, rc = %d, Buffers = %d\n",
266 pTxResult->state,pTxResult->returnValue,pTxResult->numOfBuffers));
267
268 switch(pTxResult->state)
269 {
270 case TX_RESULT_STATE_IDLE:
271 /* Read all Tx-Result table from the FW (Synch or Asynch) */
272 pTxResult->returnValue = TNETWIF_ReadMemOpt (pTxResult->hTNETWIF,
273 pTxResult->txResultTableAddr,
274 PADREAD (pTxResult->TxCmpltAttr),
275 FW_TX_CMPLT_BLOCK_SIZE * sizeof(TxResultDescriptor_t),
276 FW_EVENT_MODULE_ID,
277 txResult_StateMachine,hTxResult);
278
279 pTxResult->state = TX_RESULT_STATE_READING;
280 break;
281
282 case TX_RESULT_STATE_READING:
283 /* process the new table and call the upper layers to handle results.
284 Also update numOfBuffers & entry (from, to) */
285 txResult_handleNewEntries(pTxResult);
286
287 if (TX_RESULT_NO_BUFFER == pTxResult->numOfBuffers)
288 { /* no need to write to FW - exit SM */
289 pTxResult->state = TX_RESULT_STATE_EXIT;
290 }
291 else
292 {
293 pTxResult->state = TX_RESULT_STATE_WRITING1;
294 }
295 break;
296 case TX_RESULT_STATE_WRITING1:
297
298 pTxResult->returnValue = txResult_writeNewEntries(pTxResult,0);
299 if (TX_RESULT_ONE_BUFFER == pTxResult->numOfBuffers)
300 { /* only one write was needed - exit SM */
301 pTxResult->state = TX_RESULT_STATE_EXIT;
302 }
303 else
304 {
305 pTxResult->state = TX_RESULT_STATE_WRITING2;
306 }
307 break;
308
309 case TX_RESULT_STATE_WRITING2:
310
311 pTxResult->returnValue = txResult_writeNewEntries(pTxResult,1);
312
313 pTxResult->state = TX_RESULT_STATE_EXIT;
314 break;
315
316 case TX_RESULT_STATE_EXIT:
317
318 if (FALSE == pTxResult->bSync)
319 { /* Async bus - call FwEvent for notifying the completion */
320 FwEvent_EventComplete(pTxResult->hFwEvent, TNETWIF_OK);
321 }
322 else /* This is the synch case - we should return TNETWIF_OK */
323 {
324 pTxResult->returnValue = TNETWIF_OK;
325 }
326 pTxResult->state = TX_RESULT_STATE_IDLE;
327
328 return;
329
330 default:
331 WLAN_REPORT_ERROR(pTxResult->hReport,HAL_TX_MODULE_LOG,("rxXfer_StateMachine Unknown state = %d\n",
332 pTxResult->state));
333 }
334 }
335
336 /* if we are here - we got TNETWIF_PENDING, so we are in Async mode */
337 pTxResult->bSync = FALSE;
338
339 if (TNETWIF_ERROR == pTxResult->returnValue)
340 {
341 WLAN_REPORT_ERROR(pTxResult->hReport,TX_RESULT_MODULE_LOG,
342 ("txResult_StateMachine returning TNETWIF_ERROR in state %d !!!\n",pTxResult->state));
343 }
344 }
345
346
347 /****************************************************************************
348 * txResult_handleNewEntries()
349 ****************************************************************************
350 * DESCRIPTION:
351 * ============
352 * Goes over the valid entries (containing unread Tx-results) and calls the
353 * upper layer callback function for each packet with its results.
354 *
355 * INPUTS: TI_HANDLE hTxResult - the txResult object handle.
356 *
357 * OUTPUT: 1) number of buffers to write on . (The case of 2 buffers can happen
358 * in case of wrap around - and we need 2 different writes to FW)
359 *
360 * 2) start-end address of the buffers to be written
361 *
362 * RETURNS:
363 ***************************************************************************/
txResult_handleNewEntries(txResultObj_t * pTxResult)364 static void txResult_handleNewEntries(txResultObj_t *pTxResult)
365 {
366 TxResultDescriptor_t *pCurrentEntry; /* Points to the current table entry */
367 UINT32 uIndex; /* The current table entry */
368 UINT32 uNumOfTxComplete; /* Counts contiguous valid entries (i.e. waiting for host read) */
369 UINT32 uLoopCount; /* Used only to prevent endless loop */
370
371 uIndex = pTxResult->TxCmpltStartPointIterator;
372 uNumOfTxComplete = 0;
373
374 /* Begin the loop only from the point where the last Tx Complete was received before */
375 for (uLoopCount = uNumOfTxComplete = 0; uLoopCount < FW_TX_CMPLT_BLOCK_SIZE; uLoopCount ++)
376 {
377 /*
378 * Update current entry.
379 * Take into account that uIndex may be 16, so make & 0xf
380 */
381 pCurrentEntry = &pTxResult->TxCmpltAttr[uIndex & (FW_TX_CMPLT_BLOCK_SIZE - 1)];
382
383 WLAN_REPORT_INFORMATION(pTxResult->hReport, TX_RESULT_MODULE_LOG,
384 ("Tx Result Entry %d: Done1/2=%d/%d, DescID=%d, Status=%d, Rate=%d, Duration=%d, Retries=%d, HandleTime=%d, SecurNum=%d\n",
385 uIndex, pCurrentEntry->done1, pCurrentEntry->done2, pCurrentEntry->descID, pCurrentEntry->status,
386 pCurrentEntry->actualRate, pCurrentEntry->mediumUsage, pCurrentEntry->ackFailures,
387 pCurrentEntry->fwHandlingTime, pCurrentEntry->lsbSecuritySequenceNumber));
388
389 /* If the current entry contains fresh Tx-result information */
390 if (pCurrentEntry->done1 == 1 && pCurrentEntry->done2 == 1)
391 {
392 /* Call GWSI Tx-complete callback with current entry pointer. */
393 /* It is assumed that the entry is only accessed in this context and only for reading. */
394 pTxResult->sendPacketCompleteCB (pTxResult->sendPacketCompleteHandle, pCurrentEntry);
395
396 /* Clear entry */
397 pCurrentEntry->done1 = 0;
398 pCurrentEntry->done2 = 0;
399
400 /* Increment the index to point to next entry (wrap around is handled below) */
401 if (uIndex >= FW_TX_CMPLT_BLOCK_SIZE)
402 uIndex = 1;
403 else
404 uIndex ++;
405
406 uNumOfTxComplete ++;
407 }
408 else
409 break;
410 }
411
412 #ifdef TI_DBG
413 /* Update the TX result depth histogram */
414 pTxResult->txCompleteDepthHistogram [uNumOfTxComplete] ++;
415 #endif
416
417 /* Copy the handled entries back to FW to clear them */
418 if (uNumOfTxComplete)
419 {
420 /* No wrap. Make only 1 write */
421 if (uIndex > pTxResult->TxCmpltStartPointIterator)
422 {
423 pTxResult->entry[0].from = pTxResult->TxCmpltStartPointIterator;
424 pTxResult->entry[0].to = uIndex;
425 pTxResult->numOfBuffers = TX_RESULT_ONE_BUFFER;
426 }
427 /* Wrap. Make 2 writes */
428 else if (uIndex < pTxResult->TxCmpltStartPointIterator)
429 {
430 pTxResult->entry[0].from = pTxResult->TxCmpltStartPointIterator;
431 pTxResult->entry[0].to = FW_TX_CMPLT_BLOCK_SIZE;
432 pTxResult->entry[1].from = 0;
433 pTxResult->entry[1].to = uIndex;
434 pTxResult->numOfBuffers = TX_RESULT_TWO_BUFFERS;
435 }
436 /* Wrap, all 16 descriptors are filled. Make 1 write from index 0 */
437 else
438 {
439 pTxResult->entry[0].from = 0;
440 pTxResult->entry[0].to = FW_TX_CMPLT_BLOCK_SIZE;
441 pTxResult->numOfBuffers = TX_RESULT_ONE_BUFFER;
442 }
443
444 }
445 else /* no new entry - no need to write buffers */
446 {
447 pTxResult->numOfBuffers = TX_RESULT_NO_BUFFER;
448 }
449 /*
450 * Update start point iterator.
451 * Take into account that uIndex may be 16, so make & 0xf
452 */
453 pTxResult->TxCmpltStartPointIterator = uIndex & (FW_TX_CMPLT_BLOCK_SIZE - 1);
454 }
455
456
457 /****************************************************************************
458 * txResult_writeNewEntries()
459 ****************************************************************************
460 * DESCRIPTION:
461 * ============
462 * Clears the read entries in the FW.
463 *
464 *
465 * INPUTS: pTxResult - the txResult object handle.
466 * currBuffer - number of buffer to write on (0 or 1)
467 *
468 * OUTPUT: None
469 *
470 * RETURNS: TNETWIF_OK in case of Synch call, TNETWIF_PENDING in case of Asynch call
471 *
472 * NOTE: please note that we are running over the last WORD before the first entry
473 * since we need to save this place for the bus handling
474 ***************************************************************************/
txResult_writeNewEntries(txResultObj_t * pTxResult,UINT8 currBuffer)475 static TI_STATUS txResult_writeNewEntries(txResultObj_t *pTxResult,UINT8 currBuffer)
476 {
477 /*
478 * Write to firmware - NOTE: that we are running over the last WORD before the first entry
479 * since we need to save this place for the bus handling
480 */
481 return TNETWIF_WriteMemOpt (pTxResult->hTNETWIF,
482 pTxResult->txResultTableAddr + pTxResult->entry[currBuffer].from * sizeof(TxResultDescriptor_t),
483 PADWRITE (&pTxResult->TxCmpltAttr[pTxResult->entry[currBuffer].from]),
484 (pTxResult->entry[currBuffer].to - pTxResult->entry[currBuffer].from) * sizeof(TxResultDescriptor_t),
485 FW_EVENT_MODULE_ID,
486 txResult_StateMachine,
487 (TI_HANDLE)pTxResult);
488
489 }
490
491 /****************************************************************************
492 * txResult_RegisterCB()
493 ****************************************************************************
494 * DESCRIPTION: Register the upper driver Tx-Result callback functions.
495 ****************************************************************************/
txResult_RegisterCB(TI_HANDLE hTxResult,tiUINT32 CallBackID,void * CBFunc,TI_HANDLE CBObj)496 void txResult_RegisterCB(TI_HANDLE hTxResult, tiUINT32 CallBackID, void *CBFunc, TI_HANDLE CBObj)
497 {
498 txResultObj_t* pTxResult = (txResultObj_t*)hTxResult;
499
500 switch(CallBackID)
501 {
502 /* Set Tx-Complete callback */
503 case TX_RESULT_SEND_PKT_COMPLETE:
504 pTxResult->sendPacketCompleteCB = (SendPacketCompleteCB_t)CBFunc;
505 pTxResult->sendPacketCompleteHandle = CBObj;
506 break;
507
508 default:
509 WLAN_REPORT_ERROR(pTxResult->hReport, TX_RESULT_MODULE_LOG, ("txResult_RegisterCB - Illegal value\n"));
510 return;
511 }
512 }
513
514
515 /****************************************************************************
516 * txResult_RegisterCB()
517 ****************************************************************************
518 * DESCRIPTION: Prints TX result debig information.
519 ****************************************************************************/
txResult_printInfo(TI_HANDLE hTxResult)520 void txResult_printInfo(TI_HANDLE hTxResult)
521 {
522 #ifdef TI_DBG
523 txResultObj_t* pTxResult = (txResultObj_t*)hTxResult;
524
525 WLAN_OS_REPORT(("Tx-Result Module Information:\n"));
526 WLAN_OS_REPORT(("=============================\n\n"));
527
528 WLAN_OS_REPORT((" FW result array depth histogram:\n"));
529 WLAN_OS_REPORT((" --------------------------------\n\n"));
530 WLAN_OS_REPORT((" depth: %8d %8d %8d %8d %8d %8d\n", 0, 1, 2, 3, 4, 5));
531 WLAN_OS_REPORT((" INTR: %8d %8d %8d %8d %8d %8d\n\n",
532 pTxResult->txCompleteDepthHistogram[ 0 ],
533 pTxResult->txCompleteDepthHistogram[ 1 ],
534 pTxResult->txCompleteDepthHistogram[ 2 ],
535 pTxResult->txCompleteDepthHistogram[ 3 ],
536 pTxResult->txCompleteDepthHistogram[ 4 ],
537 pTxResult->txCompleteDepthHistogram[ 5 ]));
538 WLAN_OS_REPORT((" depth: %8d %8d %8d %8d %8d %8d\n", 6, 7, 8, 9, 10, 11));
539 WLAN_OS_REPORT((" INTR: %8d %8d %8d %8d %8d %8d\n\n",
540 pTxResult->txCompleteDepthHistogram[ 6 ],
541 pTxResult->txCompleteDepthHistogram[ 7 ],
542 pTxResult->txCompleteDepthHistogram[ 8 ],
543 pTxResult->txCompleteDepthHistogram[ 9 ],
544 pTxResult->txCompleteDepthHistogram[ 10 ],
545 pTxResult->txCompleteDepthHistogram[ 11 ]));
546 WLAN_OS_REPORT((" depth: %8d %8d %8d %8d %8d\n", 12, 13, 14, 15, 16));
547 WLAN_OS_REPORT((" INTR: %8d %8d %8d %8d %8d\n\n",
548 pTxResult->txCompleteDepthHistogram[ 12 ],
549 pTxResult->txCompleteDepthHistogram[ 13 ],
550 pTxResult->txCompleteDepthHistogram[ 14 ],
551 pTxResult->txCompleteDepthHistogram[ 15 ],
552 pTxResult->txCompleteDepthHistogram[ 16 ]));
553 #endif
554 }
555
556 /****************************************************************************
557 * txResult_RegisterCB()
558 ****************************************************************************
559 * DESCRIPTION: Prints TX result debig information.
560 ****************************************************************************/
txResult_clearInfo(TI_HANDLE hTxResult)561 void txResult_clearInfo(TI_HANDLE hTxResult)
562 {
563 #ifdef TI_DBG
564 txResultObj_t* pTxResult = (txResultObj_t*)hTxResult;
565
566 os_memoryZero( pTxResult->hOs, pTxResult->txCompleteDepthHistogram, sizeof(UINT32) * FW_TX_CMPLT_BLOCK_SIZE );
567 #endif
568 }
569
570