Example #1
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);
		}

		/* 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) {
				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;
}
Example #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 uPriorityQueueBitMap = 0;
    TI_UINT32 *pFreeBlocks = (TI_UINT32 *)pFwStatus->txReleasedBlks;
    TI_UINT32 uTempFwCounters;
    FwStatCntrs_t *pFwStatusCounters;
    TI_UINT32 uNewTxTotal = (TI_UINT32)pFwStatus->txTotal;

    pTxHwQueue->iTxTotaldiff += (uNewTxTotal - pTxHwQueue->uNumTotalBlks) ;

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

    /* Update Total blocks*/
    pTxHwQueue->uNumTotalBlks = uNewTxTotal;
    if(pTxHwQueue->iTxTotaldiff > 0)
    {
        /* In case we have possitive difference we can add the blocks to TX poll */
        pTxHwQueue->uNumTotalBlksFree += pTxHwQueue->iTxTotaldiff;
    }
    /*
     * 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]/*, &txTotalDiff*/);
        if(pQueueInfo->uNumBlksUsed > pQueueInfo->uNumBlksQuota)
        {
            SET_QUEUE_LOW_PRIORITY(uPriorityQueueBitMap, uQueueId);
        }
        else
        {
            SET_QUEUE_HIGH_PRIORITY(uPriorityQueueBitMap, uQueueId);
        }
    }
    if((pTxHwQueue->uPriorityBitMap != uPriorityQueueBitMap) && (pTxHwQueue->fUpdatePriorityMapCb != NULL))
    {
        pTxHwQueue->fUpdatePriorityMapCb(pTxHwQueue->hUpdatePriorityMapHndl, uPriorityQueueBitMap);
        pTxHwQueue->uPriorityBitMap = uPriorityQueueBitMap;
    }
    if(pTxHwQueue->iTxTotaldiff > 0)
    {
        pTxHwQueue->iTxTotaldiff = 0;
    }
    /*
     * 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;
}