Home | History | Annotate | Download | only in Tx_Result
      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  ****************************************************************************/
     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  ****************************************************************************/
    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  ****************************************************************************/
    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  ****************************************************************************/
    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  ****************************************************************************/
    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 
    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  ****************************************************************************/
    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  ***************************************************************************/
    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  ***************************************************************************/
    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  ****************************************************************************/
    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  ****************************************************************************/
    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  ****************************************************************************/
    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