Esempio n. 1
0
/****************************************************************************
 *                  txHwQueue_UpdateFreeBlocks()
 ****************************************************************************
 * DESCRIPTION:
   ===========
    This function is called per queue after reading the freed blocks counters from the FwStatus.
    It updates the queue's blocks status according to the freed blocks.
 ****************************************************************************/
static void txHwQueue_UpdateFreeBlocks (TTxHwQueue *pTxHwQueue, TI_UINT32 uQueueId, TI_UINT32 uFreeBlocks)
{
    TTxHwQueueInfo *pQueueInfo = &(pTxHwQueue->aTxHwQueueInfo[uQueueId]);
    TI_UINT32 lowThreshold;  /* Minimum blocks that are guaranteed for this Queue. */
    TI_UINT32 newUsedBlks;   /* Blocks that are used by this Queue after updating free blocks. */
    TI_UINT32 newReserved;   /* How many blocks are reserved to this Queue after freeing. */
    TI_UINT32 numBlksToFree; /* The number of blocks freed in the current queue. */

    /* If the FW free blocks counter didn't change, exit */
    uFreeBlocks = ENDIAN_HANDLE_LONG(uFreeBlocks);
    if (uFreeBlocks == pQueueInfo->uFwFreedBlksCntr)
    {
        return;
    }

    pQueueInfo->uFwFreedBlksCntr = uFreeBlocks;

    /* The uFreeBlocks is the accumulated number of blocks freed by the FW for the uQueueId.
     * Subtracting it from the accumulated number of blocks allocated by the driver should
     *   give the current number of used blocks in this queue.
     * Since the difference is always a small positive number, a simple subtraction should work
     *   also for wrap around.
     */
    newUsedBlks = pQueueInfo->uAllocatedBlksCntr - uFreeBlocks;

    numBlksToFree = pQueueInfo->uNumBlksUsed - newUsedBlks;

#ifdef TI_DBG   /* Sanity check: make sure we don't free more than is allocated. */
    if (numBlksToFree > pQueueInfo->uNumBlksUsed)
    {
        TRACE5(pTxHwQueue->hReport, REPORT_SEVERITY_ERROR, ":  Try to free more blks than used: Queue %d, ToFree %d, Used %d, HostAlloc=0x%x, FwFree=0x%x\n", uQueueId, numBlksToFree, pQueueInfo->uNumBlksUsed, pQueueInfo->uAllocatedBlksCntr, uFreeBlocks);
    }
#endif

    /* Update total free blocks and Queue used blocks with the freed blocks number. */
    pTxHwQueue->uNumTotalBlksFree += numBlksToFree;
    pQueueInfo->uNumBlksUsed = newUsedBlks;

    lowThreshold = pQueueInfo->uNumBlksThresh;

    /* If after freeing the blocks we are using less than the low threshold,
        update total reserved blocks number as follows:
       (note: if we are above the low threshold after freeing the blocks we still have no reservation.)
    */
    if (newUsedBlks < lowThreshold)
    {
        newReserved = lowThreshold - newUsedBlks;
        pQueueInfo->uNumBlksReserved = newReserved;


        /* If freeing the blocks reduces the used blocks from above to below the low-threshold,
            only the part from the low-threshold to the new used number is added to the
            reserved blocks (because blocks are reserved for the Queue only up to its low-threshold):

              0        new used               low            old used         high
              |###########|####################|################|             |
              |###########|####################|################|             |
                           <-------------- freed -------------->
                           <-- new reserved -->
                             old reserved = 0
        */
        if (numBlksToFree > newReserved)
            pTxHwQueue->uNumTotalBlksReserved += newReserved; /* Add change to total reserved.*/


        /* Else, if we were under the low-threshold before freeing these blocks,
            all freed blocks are added to the reserved blocks:

              0             new used          old used             low               high
              |################|#################|                  |                  |
              |################|#################|                  |                  |
                                <---- freed ---->
                                                  <- old reserved ->
                                <---------- new reserved ---------->
        */
        else
            pTxHwQueue->uNumTotalBlksReserved += numBlksToFree; /* Add change to total reserved.*/
    }

    TRACE5(pTxHwQueue->hReport, REPORT_SEVERITY_INFORMATION, ":  Queue %d, ToFree %d, Used %d, HostAlloc=0x%x, FwFree=0x%x\n", uQueueId, numBlksToFree, pQueueInfo->uNumBlksUsed, pQueueInfo->uAllocatedBlksCntr, uFreeBlocks);
}
Esempio n. 2
0
/****************************************************************************
 *                  txHwQueue_UpdateFreeResources()
 ****************************************************************************
 * DESCRIPTION:
   ===========
   Called by FwEvent upon Data interrupt to update freed HW-Queue resources as follows:
    1) For all queues, update blocks and descriptors numbers according to FwStatus information.
    2) For each busy queue, if now available indicate it in the backpressure bitmap.
 ****************************************************************************/
ETxnStatus txHwQueue_UpdateFreeResources (TI_HANDLE hTxHwQueue, FwStatus_t *pFwStatus)
{
    TTxHwQueue *pTxHwQueue = (TTxHwQueue *)hTxHwQueue;
    TTxHwQueueInfo *pQueueInfo;
    TI_UINT32 uQueueId;
    TI_UINT32 uAvailableBlks; /* Max blocks available for current queue. */
    TI_UINT32 uNewNumUsedDescriptors;
    TI_UINT32 uBackpressure = 0;
    TI_UINT32 *pFreeBlocks = (TI_UINT32 *)pFwStatus->txReleasedBlks;
    TI_UINT32 uTempFwCounters;
    FwStatCntrs_t *pFwStatusCounters;

    /*
     * If TxResults counter changed in FwStatus, update descriptors number according to  information
     */
    uTempFwCounters = (ENDIAN_HANDLE_LONG(pFwStatus->counters));
    pFwStatusCounters = (FwStatCntrs_t *)&uTempFwCounters;
    if (pFwStatusCounters->txResultsCntr != pTxHwQueue->uFwTxResultsCntr)
    {
        pTxHwQueue->uFwTxResultsCntr = pFwStatusCounters->txResultsCntr;

        /* Calculate new number of used descriptors (the else is for wrap around case) */
        if (pTxHwQueue->uFwTxResultsCntr <= pTxHwQueue->uDrvTxPacketsCntr)
        {
            uNewNumUsedDescriptors = (TI_UINT32)(pTxHwQueue->uDrvTxPacketsCntr - pTxHwQueue->uFwTxResultsCntr);
        }
        else
        {
            uNewNumUsedDescriptors = 0x100 - (TI_UINT32)(pTxHwQueue->uFwTxResultsCntr - pTxHwQueue->uDrvTxPacketsCntr);
        }

#ifdef TI_DBG   /* Sanity check: make sure we don't free more descriptors than allocated. */
        if (uNewNumUsedDescriptors >= pTxHwQueue->uNumUsedDescriptors)
        {
            TRACE2(pTxHwQueue->hReport, REPORT_SEVERITY_ERROR, ":  Used descriptors number should decrease: UsedDesc %d, NewUsedDesc %d\n", pTxHwQueue->uNumUsedDescriptors, uNewNumUsedDescriptors);
        }
#endif

        /* Update number of packets left in FW (for descriptors allocation check). */
        pTxHwQueue->uNumUsedDescriptors = uNewNumUsedDescriptors;
    }

    /*
     * For all queues, update blocks numbers according to FwStatus information
     */
    for (uQueueId = 0; uQueueId < MAX_NUM_OF_AC; uQueueId++)
    {
        pQueueInfo = &(pTxHwQueue->aTxHwQueueInfo[uQueueId]);

        /* Update per queue number of used, free and reserved blocks. */
        txHwQueue_UpdateFreeBlocks (pTxHwQueue, uQueueId, pFreeBlocks[uQueueId]);
    }

    /*
     * For each busy queue, if now available indicate it in the backpressure bitmap
     */
    for (uQueueId = 0; uQueueId < MAX_NUM_OF_AC; uQueueId++)
    {
        pQueueInfo = &(pTxHwQueue->aTxHwQueueInfo[uQueueId]);

        /* If the queue was stopped */
        if (pQueueInfo->bQueueBusy)
        {
            /* Find max available blocks for this queue (0 could indicate no descriptors). */
            uAvailableBlks = txHwQueue_CheckResources (pTxHwQueue, pQueueInfo);

            /* If the required blocks and a descriptor are available,
                 set the queue's backpressure bit to indicate NOT-busy! */
            if (pQueueInfo->uNumBlksCausedBusy <= uAvailableBlks)
            {
                TRACE6(pTxHwQueue->hReport, REPORT_SEVERITY_INFORMATION, ": Queue Available, Queue=%d, ReqBlks=%d, FreeBlks=%d, UsedBlks=%d, AvailBlks=%d, UsedPkts=%d\n", uQueueId, pQueueInfo->uNumBlksCausedBusy, pTxHwQueue->uNumTotalBlksFree, pQueueInfo->uNumBlksUsed, uAvailableBlks, pTxHwQueue->uNumUsedDescriptors);
                SET_QUEUE_BACKPRESSURE(&uBackpressure, uQueueId); /* Start queue. */
                pQueueInfo->bQueueBusy = TI_FALSE;
            }
        }
    }

    /* If released queues map is not 0, send it to the upper layers (if CB available) */
    if ((uBackpressure > 0) && (pTxHwQueue->fUpdateBusyMapCb != NULL))
    {
        pTxHwQueue->fUpdateBusyMapCb (pTxHwQueue->hUpdateBusyMapHndl, uBackpressure);
    }

    return TXN_STATUS_COMPLETE;
}
Esempio n. 3
0
/****************************************************************************
 *                      TWD_StatisticsReadCB ()
 ****************************************************************************
 * DESCRIPTION: Interrogate Statistics from the wlan hardware
 *
 * INPUTS:  None
 *
 * OUTPUT:  None
 *
 * RETURNS: TI_OK or TI_NOK
 ****************************************************************************/
static TI_STATUS TWD_StatisticsReadCB (TI_HANDLE hTWD, TI_UINT16 MboxStatus, ACXStatistics_t* pElem)
{
    if (MboxStatus != TI_OK)
    {
        return TI_NOK;
    }

    /* 
     *  Handle FW statistics endianess
     *  ==============================
     */

    /* Ring */
    pElem->ringStat.numOfTxProcs       = ENDIAN_HANDLE_LONG(pElem->ringStat.numOfTxProcs);
    pElem->ringStat.numOfPreparedDescs = ENDIAN_HANDLE_LONG(pElem->ringStat.numOfPreparedDescs);
    pElem->ringStat.numOfTxXfr         = ENDIAN_HANDLE_LONG(pElem->ringStat.numOfTxXfr);
    pElem->ringStat.numOfTxDma         = ENDIAN_HANDLE_LONG(pElem->ringStat.numOfTxDma);
    pElem->ringStat.numOfTxCmplt       = ENDIAN_HANDLE_LONG(pElem->ringStat.numOfTxCmplt);
    pElem->ringStat.numOfRxProcs       = ENDIAN_HANDLE_LONG(pElem->ringStat.numOfRxProcs);
    pElem->ringStat.numOfRxData        = ENDIAN_HANDLE_LONG(pElem->ringStat.numOfRxData);

    /* Debug */
    pElem->debug.debug1                = ENDIAN_HANDLE_LONG(pElem->debug.debug1);
    pElem->debug.debug2                = ENDIAN_HANDLE_LONG(pElem->debug.debug2);
    pElem->debug.debug3                = ENDIAN_HANDLE_LONG(pElem->debug.debug3);
    pElem->debug.debug4                = ENDIAN_HANDLE_LONG(pElem->debug.debug4);
    pElem->debug.debug5                = ENDIAN_HANDLE_LONG(pElem->debug.debug5);
    pElem->debug.debug6                = ENDIAN_HANDLE_LONG(pElem->debug.debug6);

    /* Isr */
    pElem->isr.IRQs                    = ENDIAN_HANDLE_LONG(pElem->isr.IRQs);

    /* Rx */
    pElem->rx.RxOutOfMem               = ENDIAN_HANDLE_LONG(pElem->rx.RxOutOfMem            );
    pElem->rx.RxHdrOverflow            = ENDIAN_HANDLE_LONG(pElem->rx.RxHdrOverflow         );
    pElem->rx.RxHWStuck                = ENDIAN_HANDLE_LONG(pElem->rx.RxHWStuck             );
    pElem->rx.RxDroppedFrame           = ENDIAN_HANDLE_LONG(pElem->rx.RxDroppedFrame        );
    pElem->rx.RxCompleteDroppedFrame   = ENDIAN_HANDLE_LONG(pElem->rx.RxCompleteDroppedFrame);
    pElem->rx.RxAllocFrame             = ENDIAN_HANDLE_LONG(pElem->rx.RxAllocFrame          );
    pElem->rx.RxDoneQueue              = ENDIAN_HANDLE_LONG(pElem->rx.RxDoneQueue           );
    pElem->rx.RxDone                   = ENDIAN_HANDLE_LONG(pElem->rx.RxDone                );
    pElem->rx.RxDefrag                 = ENDIAN_HANDLE_LONG(pElem->rx.RxDefrag              );
    pElem->rx.RxDefragEnd              = ENDIAN_HANDLE_LONG(pElem->rx.RxDefragEnd           );
    pElem->rx.RxMic                    = ENDIAN_HANDLE_LONG(pElem->rx.RxMic                 );
    pElem->rx.RxMicEnd                 = ENDIAN_HANDLE_LONG(pElem->rx.RxMicEnd              );
    pElem->rx.RxXfr                    = ENDIAN_HANDLE_LONG(pElem->rx.RxXfr                 );
    pElem->rx.RxXfrEnd                 = ENDIAN_HANDLE_LONG(pElem->rx.RxXfrEnd              );
    pElem->rx.RxCmplt                  = ENDIAN_HANDLE_LONG(pElem->rx.RxCmplt               );
    pElem->rx.RxPreCmplt               = ENDIAN_HANDLE_LONG(pElem->rx.RxPreCmplt            );
    pElem->rx.RxCmpltTask              = ENDIAN_HANDLE_LONG(pElem->rx.RxCmpltTask           );
    pElem->rx.RxPhyHdr                 = ENDIAN_HANDLE_LONG(pElem->rx.RxPhyHdr              );
    pElem->rx.RxTimeout                = ENDIAN_HANDLE_LONG(pElem->rx.RxTimeout             );

    /* Tx */
    pElem->tx.numOfTxTemplatePrepared  	= ENDIAN_HANDLE_LONG(pElem->tx.numOfTxTemplatePrepared);
	pElem->tx.numOfTxDataPrepared  		= ENDIAN_HANDLE_LONG(pElem->tx.numOfTxDataPrepared);
	pElem->tx.numOfTxTemplateProgrammed = ENDIAN_HANDLE_LONG(pElem->tx.numOfTxTemplateProgrammed);
	pElem->tx.numOfTxDataProgrammed  	= ENDIAN_HANDLE_LONG(pElem->tx.numOfTxDataProgrammed);
	pElem->tx.numOfTxBurstProgrammed  	= ENDIAN_HANDLE_LONG(pElem->tx.numOfTxBurstProgrammed);
	pElem->tx.numOfTxStarts  			= ENDIAN_HANDLE_LONG(pElem->tx.numOfTxStarts);
	pElem->tx.numOfTxImmResp  			= ENDIAN_HANDLE_LONG(pElem->tx.numOfTxImmResp);
	pElem->tx.numOfTxStartTempaltes  	= ENDIAN_HANDLE_LONG(pElem->tx.numOfTxStartTempaltes);
	pElem->tx.numOfTxStartIntTemplate  	= ENDIAN_HANDLE_LONG(pElem->tx.numOfTxStartIntTemplate);
	pElem->tx.numOfTxStartFwGen  		= ENDIAN_HANDLE_LONG(pElem->tx.numOfTxStartFwGen);
	pElem->tx.numOfTxStartData  		= ENDIAN_HANDLE_LONG(pElem->tx.numOfTxStartData);
	pElem->tx.numOfTxStartNullFrame  	= ENDIAN_HANDLE_LONG(pElem->tx.numOfTxStartNullFrame);
	pElem->tx.numOfTxExch  				= ENDIAN_HANDLE_LONG(pElem->tx.numOfTxExch);
	pElem->tx.numOfTxRetryTemplate  	= ENDIAN_HANDLE_LONG(pElem->tx.numOfTxRetryTemplate);
	pElem->tx.numOfTxRetryData  		= ENDIAN_HANDLE_LONG(pElem->tx.numOfTxRetryData);
	pElem->tx.numOfTxExchPending  		= ENDIAN_HANDLE_LONG(pElem->tx.numOfTxExchPending);
	pElem->tx.numOfTxExchExpiry  		= ENDIAN_HANDLE_LONG(pElem->tx.numOfTxExchExpiry);
	pElem->tx.numOfTxExchMismatch  		= ENDIAN_HANDLE_LONG(pElem->tx.numOfTxExchMismatch);
	pElem->tx.numOfTxDoneTemplate  		= ENDIAN_HANDLE_LONG(pElem->tx.numOfTxDoneTemplate);
	pElem->tx.numOfTxDoneData  			= ENDIAN_HANDLE_LONG(pElem->tx.numOfTxDoneData);
	pElem->tx.numOfTxDoneIntTemplate  	= ENDIAN_HANDLE_LONG(pElem->tx.numOfTxDoneIntTemplate);
	pElem->tx.numOfTxPreXfr  			= ENDIAN_HANDLE_LONG(pElem->tx.numOfTxPreXfr);
	pElem->tx.numOfTxXfr  				= ENDIAN_HANDLE_LONG(pElem->tx.numOfTxXfr);
	pElem->tx.numOfTxXfrOutOfMem  		= ENDIAN_HANDLE_LONG(pElem->tx.numOfTxXfrOutOfMem);
	pElem->tx.numOfTxDmaProgrammed  	= ENDIAN_HANDLE_LONG(pElem->tx.numOfTxDmaProgrammed);
	pElem->tx.numOfTxDmaDone  			= ENDIAN_HANDLE_LONG(pElem->tx.numOfTxDmaDone);

    /* Dma */
    pElem->dma.RxDMAErrors             = ENDIAN_HANDLE_LONG(pElem->dma.RxDMAErrors);
    pElem->dma.TxDMAErrors             = ENDIAN_HANDLE_LONG(pElem->dma.TxDMAErrors);

    /* Wep */
    pElem->wep.WepAddrKeyCount         = ENDIAN_HANDLE_LONG(pElem->wep.WepAddrKeyCount);
    pElem->wep.WepDefaultKeyCount      = ENDIAN_HANDLE_LONG(pElem->wep.WepDefaultKeyCount);
    pElem->wep.WepKeyNotFound          = ENDIAN_HANDLE_LONG(pElem->wep.WepKeyNotFound);
    pElem->wep.WepDecryptFail          = ENDIAN_HANDLE_LONG(pElem->wep.WepDecryptFail);
    
    /* AES */
    pElem->aes.AesEncryptFail          = ENDIAN_HANDLE_LONG(pElem->aes.AesEncryptFail);     
    pElem->aes.AesDecryptFail          = ENDIAN_HANDLE_LONG(pElem->aes.AesDecryptFail);     
    pElem->aes.AesEncryptPackets       = ENDIAN_HANDLE_LONG(pElem->aes.AesEncryptPackets);  
    pElem->aes.AesDecryptPackets       = ENDIAN_HANDLE_LONG(pElem->aes.AesDecryptPackets);  
    pElem->aes.AesEncryptInterrupt     = ENDIAN_HANDLE_LONG(pElem->aes.AesEncryptInterrupt);
    pElem->aes.AesDecryptInterrupt     = ENDIAN_HANDLE_LONG(pElem->aes.AesDecryptInterrupt);

    /* Events */
    pElem->event.calibration           = ENDIAN_HANDLE_LONG(pElem->event.calibration);
    pElem->event.rxMismatch            = ENDIAN_HANDLE_LONG(pElem->event.rxMismatch); 
    pElem->event.rxMemEmpty            = ENDIAN_HANDLE_LONG(pElem->event.rxMemEmpty); 

    /* PS */
    pElem->pwr.MissingBcnsCnt          	= ENDIAN_HANDLE_LONG(pElem->pwr.MissingBcnsCnt);
    pElem->pwr.RcvdBeaconsCnt          	= ENDIAN_HANDLE_LONG(pElem->pwr.RcvdBeaconsCnt);
    pElem->pwr.ConnectionOutOfSync     	= ENDIAN_HANDLE_LONG(pElem->pwr.ConnectionOutOfSync);
    pElem->pwr.ContMissBcnsSpread[0]   	= ENDIAN_HANDLE_LONG(pElem->pwr.ContMissBcnsSpread[0]);
    pElem->pwr.ContMissBcnsSpread[1]   	= ENDIAN_HANDLE_LONG(pElem->pwr.ContMissBcnsSpread[1]);
    pElem->pwr.ContMissBcnsSpread[2]   	= ENDIAN_HANDLE_LONG(pElem->pwr.ContMissBcnsSpread[2]);
    pElem->pwr.ContMissBcnsSpread[3]   	= ENDIAN_HANDLE_LONG(pElem->pwr.ContMissBcnsSpread[3]);
    pElem->pwr.ContMissBcnsSpread[4]   	= ENDIAN_HANDLE_LONG(pElem->pwr.ContMissBcnsSpread[4]);
    pElem->pwr.ContMissBcnsSpread[5]   	= ENDIAN_HANDLE_LONG(pElem->pwr.ContMissBcnsSpread[5]);
    pElem->pwr.ContMissBcnsSpread[6]   	= ENDIAN_HANDLE_LONG(pElem->pwr.ContMissBcnsSpread[6]);
    pElem->pwr.ContMissBcnsSpread[7]   	= ENDIAN_HANDLE_LONG(pElem->pwr.ContMissBcnsSpread[7]);
    pElem->pwr.ContMissBcnsSpread[8]   	= ENDIAN_HANDLE_LONG(pElem->pwr.ContMissBcnsSpread[8]);
    pElem->pwr.ContMissBcnsSpread[9]   	= ENDIAN_HANDLE_LONG(pElem->pwr.ContMissBcnsSpread[9]);

    pElem->ps.psPollTimeOuts           	= ENDIAN_HANDLE_LONG(pElem->ps.psPollTimeOuts);
    pElem->ps.upsdTimeOuts             	= ENDIAN_HANDLE_LONG(pElem->ps.upsdTimeOuts);
    pElem->ps.upsdMaxAPturn            	= ENDIAN_HANDLE_LONG(pElem->ps.upsdMaxAPturn); 
    pElem->ps.psPollMaxAPturn          	= ENDIAN_HANDLE_LONG(pElem->ps.psPollMaxAPturn);
    pElem->ps.psPollUtilization        	= ENDIAN_HANDLE_LONG(pElem->ps.psPollUtilization);
    pElem->ps.upsdUtilization          	= ENDIAN_HANDLE_LONG(pElem->ps.upsdUtilization);

	pElem->rxFilter.arpFilter		   	= ENDIAN_HANDLE_LONG(pElem->rxFilter.arpFilter);
	pElem->rxFilter.beaconFilter	   	= ENDIAN_HANDLE_LONG(pElem->rxFilter.beaconFilter);
	pElem->rxFilter.dataFilter		   	= ENDIAN_HANDLE_LONG(pElem->rxFilter.dataFilter);
	pElem->rxFilter.dupFilter		   	= ENDIAN_HANDLE_LONG(pElem->rxFilter.dupFilter);
	pElem->rxFilter.MCFilter		   	= ENDIAN_HANDLE_LONG(pElem->rxFilter.MCFilter);
	pElem->rxFilter.ibssFilter		   	= ENDIAN_HANDLE_LONG(pElem->rxFilter.ibssFilter);

	pElem->radioCal.calStateFail	   	= ENDIAN_HANDLE_LONG(pElem->radioCal.calStateFail);
	pElem->radioCal.initCalTotal	   	= ENDIAN_HANDLE_LONG(pElem->radioCal.initCalTotal);
	pElem->radioCal.initRadioBandsFail 	= ENDIAN_HANDLE_LONG(pElem->radioCal.initRadioBandsFail);
	pElem->radioCal.initRxIqMmFail		= ENDIAN_HANDLE_LONG(pElem->radioCal.initRxIqMmFail);
	pElem->radioCal.initSetParams		= ENDIAN_HANDLE_LONG(pElem->radioCal.initSetParams);
	pElem->radioCal.initTxClpcFail		= ENDIAN_HANDLE_LONG(pElem->radioCal.initTxClpcFail);
	pElem->radioCal.tuneCalTotal		= ENDIAN_HANDLE_LONG(pElem->radioCal.tuneCalTotal);
	pElem->radioCal.tuneDrpwChanTune	= ENDIAN_HANDLE_LONG(pElem->radioCal.tuneDrpwChanTune);
	pElem->radioCal.tuneDrpwLnaTank		= ENDIAN_HANDLE_LONG(pElem->radioCal.tuneDrpwLnaTank);
	pElem->radioCal.tuneDrpwPdBufFail	= ENDIAN_HANDLE_LONG(pElem->radioCal.tuneDrpwPdBufFail);
	pElem->radioCal.tuneDrpwRTrimFail	= ENDIAN_HANDLE_LONG(pElem->radioCal.tuneDrpwRTrimFail);
	pElem->radioCal.tuneDrpwRxDac		= ENDIAN_HANDLE_LONG(pElem->radioCal.tuneDrpwRxDac);
	pElem->radioCal.tuneDrpwRxIf2Gain	= ENDIAN_HANDLE_LONG(pElem->radioCal.tuneDrpwRxIf2Gain);
	pElem->radioCal.tuneDrpwRxTxLpf		= ENDIAN_HANDLE_LONG(pElem->radioCal.tuneDrpwRxTxLpf);
	pElem->radioCal.tuneDrpwTaCal		= ENDIAN_HANDLE_LONG(pElem->radioCal.tuneDrpwTaCal);
	pElem->radioCal.tuneDrpwTxMixFreqFail = ENDIAN_HANDLE_LONG(pElem->radioCal.tuneDrpwTxMixFreqFail);
	pElem->radioCal.tuneRxAnaDcFail		= ENDIAN_HANDLE_LONG(pElem->radioCal.tuneRxAnaDcFail);
	pElem->radioCal.tuneRxIqMmFail		= ENDIAN_HANDLE_LONG(pElem->radioCal.tuneRxIqMmFail);
	pElem->radioCal.tuneTxClpcFail		= ENDIAN_HANDLE_LONG(pElem->radioCal.tuneTxClpcFail);
	pElem->radioCal.tuneTxIqMmFail		= ENDIAN_HANDLE_LONG(pElem->radioCal.tuneTxIqMmFail);
	pElem->radioCal.tuneTxLOLeakFail	= ENDIAN_HANDLE_LONG(pElem->radioCal.tuneTxLOLeakFail);
	pElem->radioCal.tuneTxPdetFail		= ENDIAN_HANDLE_LONG(pElem->radioCal.tuneTxPdetFail);
	pElem->radioCal.tuneTxPPAFail		= ENDIAN_HANDLE_LONG(pElem->radioCal.tuneTxPPAFail);


    /* 
     *  Print FW statistics 
     *  ===================
     */
    return TI_OK;  
}