/**************************************************************************** * 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); }
/**************************************************************************** * 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; }
/**************************************************************************** * 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; }