/**
 *   @file  qmss_test.c
 *
 *   @brief   
 *      This is the QMSS unit test code.
 *
 *  \par
 *  ============================================================================
 *  @n   (C) Copyright 2009-2011, Texas Instruments, Inc.
 * 
 *  Redistribution and use in source and binary forms, with or without 
 *  modification, are permitted provided that the following conditions 
 *  are met:
 *
 *    Redistributions of source code must retain the above copyright 
 *    notice, this list of conditions and the following disclaimer.
 *
 *    Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the 
 *    documentation and/or other materials provided with the   
 *    distribution.
 *
 *    Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *  \par
*/

#include <xdc/std.h>
#include <xdc/runtime/System.h>
#include <string.h>

/* QMSS LLD include */
#include <ti/drv/qmss/qmss_drv.h>
#include <ti/drv/qmss/qmss_firmware.h>

/* CSL RL includes */
#include <ti/csl/csl_chip.h>

/* OSAL includes */
#include <qmss_osal.h>

/************************ USER DEFINES ********************/
#define NUM_MONOLITHIC_DESC         64
#define SIZE_MONOLITHIC_DESC        64

#define NUM_MISC_DESC               32 
#define SIZE_MISC_DESC              16


/************************ GLOBAL VARIABLES ********************/

#pragma DATA_ALIGN (linkingRAM0, 16)
UInt64                  linkingRAM0[NUM_MONOLITHIC_DESC + NUM_MISC_DESC];

/* Descriptor pool [Size of descriptor * Number of descriptors] */
#pragma DATA_ALIGN (monolithicDesc, 16)
UInt8                   monolithicDesc[SIZE_MONOLITHIC_DESC * NUM_MONOLITHIC_DESC];
#pragma DATA_ALIGN (miscDesc, 16)
UInt8                   miscDesc[SIZE_MISC_DESC * NUM_MISC_DESC];

/* Global variable common to all test cases */

/* QMSS configuration */
Qmss_InitCfg            qmssInitConfig;
/* Memory region configuration information */
Qmss_MemRegInfo         memInfo;
/* Memory region configuration status */
Qmss_MemRegCfg          memRegStatus;
/* QM descriptor configuration */
Qmss_DescCfg            descCfg;
/* Store the queue handle for destination queues on which allocated descriptors are stored */
Qmss_QueueHnd           QueHnd[QMSS_MAX_MEM_REGIONS];

/************************ EXTERN VARIABLES ********************/
/* Error counter */
extern UInt32                   errorCount;
/* QMSS device specific configuration */
extern Qmss_GlobalConfigParams  qmssGblCfgParams;

/**
 *  @b Description
 *  @n  
 *      Utility function which converts a local GEM L2 memory address 
 *      to global memory address.
 *
 *  @param[in]  addr
 *      Local address to be converted
 *
 *  @retval
 *      Computed L2 global Address
 */
static UInt32 l2_global_address (UInt32 addr)
{
	UInt32 corenum;

	/* Get the core number. */
	corenum = CSL_chipReadReg (CSL_CHIP_DNUM); 

	/* Compute the global address. */
	return (addr + (0x10000000 + (corenum * 0x1000000)));
}

Void testDescAllocation (Void)
{
    Qmss_Result             result;
    UInt32                  numAllocated, corenum, i; 
    Qmss_QueueHnd           freeQueHnd, txFreeQueHnd, miscQueHnd;
#ifdef TEST_QOS
    UInt32                  baseQueue;
    Qmss_QosQueueCfg        queueCfg;
    Qmss_QosClusterCfg      clusterCfg;
    Qmss_QosClusterCfgRR   *clusterCfgRR;
    Qmss_QosClusterCfgTB   *clusterCfgTB;
#if QMSS_MAX_TRAFFIC_SHAPING_QUEUE < 64
    Qmss_QueueHnd           queueHnds[64];
#endif
#endif

    /* Get the core number. */
	corenum = CSL_chipReadReg(CSL_CHIP_DNUM); 
    System_printf ("**********Core %d TESTING DESCRIPTOR ALLOCATION ************\n", corenum);

    memset ((Void *) &qmssInitConfig, 0, sizeof (Qmss_InitCfg));
    memset ((Void *) &linkingRAM0, 0, sizeof (linkingRAM0));

    /* Set up the linking RAM. Use external Linking RAM. 
     * LLD will configure the internal linking RAM address and default size if a value of zero is specified.
     * Linking RAM1 is not used */
    qmssInitConfig.linkingRAM0Base = l2_global_address ((UInt32) linkingRAM0);
    qmssInitConfig.linkingRAM0Size = NUM_MONOLITHIC_DESC + NUM_MISC_DESC;
    qmssInitConfig.linkingRAM1Base = 0x0;
    qmssInitConfig.maxDescNum      = NUM_MONOLITHIC_DESC + NUM_MISC_DESC;

#ifdef TEST_QOS /* Not supported on simulator */
#ifdef xdc_target__bigEndian
    qmssInitConfig.pdspFirmware[0].pdspId = Qmss_PdspId_PDSP2;
    qmssInitConfig.pdspFirmware[0].firmware = &qos_be;
    qmssInitConfig.pdspFirmware[0].size = sizeof (qos_be);
#else
    qmssInitConfig.pdspFirmware[0].pdspId = Qmss_PdspId_PDSP2;
    qmssInitConfig.pdspFirmware[0].firmware = &qos_le;
    qmssInitConfig.pdspFirmware[0].size = sizeof (qos_le);
#endif
#endif
    /* Initialize Queue Manager SubSystem */
    result = Qmss_init (&qmssInitConfig, &qmssGblCfgParams);
    if (result != QMSS_SOK)
    {
        System_printf ("Error Core %d : Initializing Queue Manager SubSystem error code : %d\n", corenum, result);
        errorCount++;
        return;
    }

    /* Start Queue Manager SubSystem */
    result = Qmss_start ();
    if (result != QMSS_SOK)
    {
        System_printf ("Core %d : Error starting Queue Manager error code : %d\n", corenum, result);
    }

    /* Setup memory region for monolithic descriptors */
    memset ((Void *) &monolithicDesc, 0, SIZE_MONOLITHIC_DESC * NUM_MONOLITHIC_DESC);
    memInfo.descBase = (UInt32 *) l2_global_address ((UInt32) monolithicDesc);
    memInfo.descSize = SIZE_MONOLITHIC_DESC;
    memInfo.descNum = NUM_MONOLITHIC_DESC;
    memInfo.manageDescFlag = Qmss_ManageDesc_MANAGE_DESCRIPTOR;
    memInfo.memRegion = Qmss_MemRegion_MEMORY_REGION_NOT_SPECIFIED;
    memInfo.startIndex = 0;

    result = Qmss_insertMemoryRegion (&memInfo);
    if (result < QMSS_SOK)
    {
        System_printf ("Error Core %d : Inserting memory region %d error code : %d\n", corenum, memInfo.memRegion, result);
        errorCount++;
    }

    /* Setup memory region for teardown descriptors */
    memset ((Void *) &miscDesc, 0, SIZE_MISC_DESC * NUM_MISC_DESC);
    memInfo.descBase = (UInt32 *) l2_global_address ((UInt32) miscDesc);
    memInfo.descSize = SIZE_MISC_DESC;
    memInfo.descNum = NUM_MISC_DESC;
    memInfo.manageDescFlag = Qmss_ManageDesc_MANAGE_DESCRIPTOR;
    memInfo.memRegion = Qmss_MemRegion_MEMORY_REGION_NOT_SPECIFIED;
    memInfo.startIndex = 0;

    result = Qmss_insertMemoryRegion (&memInfo);
    if (result < QMSS_SOK)
    {
        System_printf ("Error Core %d : Inserting memory region %d error code : %d\n", corenum, memInfo.memRegion, result);
        errorCount++;
    }

    System_printf ("\n~~~~~~~~~~Core %d Memory region Configuration~~~~~~~~~~~~\n", corenum);
    result = Qmss_getMemoryRegionCfg (&memRegStatus);
    if (result != QMSS_SOK)
    {
        System_printf ("Error Core %d : Getting memory region configuration info error code : %d\n", corenum, result);
        errorCount++;
    }

    System_printf ("Current Desc count  : %d\n", memRegStatus.currDescCnt);
    for (i = 0; i < QMSS_MAX_MEM_REGIONS; i++)
    {
        if (memRegStatus.memRegInfo[i].descBase != 0)
        {
            System_printf ("\nMemory Region Index : %d\n", memRegStatus.memRegInfo[i].memRegion);
            System_printf ("Start Index         : %d\n", memRegStatus.memRegInfo[i].startIndex);
            System_printf ("Descriptor Size     : %d\n", memRegStatus.memRegInfo[i].descSize);
            System_printf ("Descriptor Num      : %d\n", memRegStatus.memRegInfo[i].descNum);
            System_printf ("Descriptor Base     : 0x%p\n", memRegStatus.memRegInfo[i].descBase);
            System_printf ("Managed Descriptor  : %d\n", memRegStatus.memRegInfo[i].manageDescFlag);
        }
    }

    descCfg.memRegion = Qmss_MemRegion_MEMORY_REGION0;
    descCfg.descNum = NUM_MONOLITHIC_DESC / 2;
    descCfg.destQueueNum = QMSS_PARAM_NOT_SPECIFIED;
    descCfg.queueType = Qmss_QueueType_STARVATION_COUNTER_QUEUE;
    
    /* Initialize the descriptors and push to free Queue */
    if ((txFreeQueHnd = Qmss_initDescriptor (&descCfg, &numAllocated)) < 0)
	{
        System_printf ("Error Core %d : Initializing Tx descriptor error code: %d \n", corenum, txFreeQueHnd);
        errorCount++;
	}
    else
    {
        if (descCfg.descNum != numAllocated)
        {
            errorCount++;
        }
            
        System_printf ("Core %d : Number of Tx descriptors requested : %d. Number of descriptors allocated : %d \n", 
            corenum, descCfg.descNum, numAllocated);
    }
    /* Setup the descriptors for receive free queue */
    descCfg.memRegion = Qmss_MemRegion_MEMORY_REGION0;
    descCfg.descNum = NUM_MONOLITHIC_DESC / 2;
    descCfg.destQueueNum = QMSS_PARAM_NOT_SPECIFIED;
    descCfg.queueType = Qmss_QueueType_STARVATION_COUNTER_QUEUE;
   
    /* Initialize the descriptors and push to free Queue */
    if ((freeQueHnd = Qmss_initDescriptor (&descCfg, &numAllocated)) < 0)
	{
        System_printf ("Error Core %d : Initializing Rx descriptor error code: %d \n", corenum, freeQueHnd);
        errorCount++;
	}
    else
    {
        if (descCfg.descNum != numAllocated)
        {
            errorCount++;
        }
        System_printf ("Core %d : Number of Rx descriptors requested : %d. Number of descriptors allocated : %d \n", 
            corenum, descCfg.descNum, numAllocated);
    }


    /* Setup the teardown free queue */
    descCfg.memRegion = Qmss_MemRegion_MEMORY_REGION1;
    descCfg.descNum = NUM_MISC_DESC;
    descCfg.destQueueNum = QMSS_PARAM_NOT_SPECIFIED;
    descCfg.queueType = Qmss_QueueType_GENERAL_PURPOSE_QUEUE;
    
    /* Initialize the descriptors and push to free Queue */
    if ((miscQueHnd = Qmss_initDescriptor (&descCfg, &numAllocated)) < 0)
	{
        System_printf ("Error Core %d : Initializing misc descriptor error code: %d \n", corenum, miscQueHnd);
        errorCount++;
	}
    else
    {
        if (descCfg.descNum != numAllocated)
        {
            errorCount++;
        }
        System_printf ("Core %d : Number of misc descriptors requested : %d. Number of descriptors allocated : %d \n", 
                corenum, descCfg.descNum, numAllocated);
    }

    /* Test setting EOI vector for high priority interrupt number 1 */
    Qmss_setEoiVector (Qmss_IntdInterruptType_HIGH, 1);
    /* Test setting EOI vector for low priority interrupt number 2 */
    Qmss_setEoiVector (Qmss_IntdInterruptType_LOW, 2);
    /* Test setting EOI vector for CDMA interrupt number 0 */
    Qmss_setEoiVector (Qmss_IntdInterruptType_CDMA, 0);

#ifdef TEST_QOS
#if QMSS_MAX_TRAFFIC_SHAPING_QUEUE < 64
    {
        int queueNum;
        uint8_t isAllocated;
        int foundBase = -1;

        /* Need 64 queues for RR cluster so reserve 64 general purpose queues */
        /* Find first queue aligned to 32 */
	/* This is necessary so other calls to Qmss_queueOpen with 
	 * QMSS_PARAM_NOT_SPECIFIED would re-allocate the queues taken
	 * by QoS
	 */
        for (baseQueue = ((QMSS_GENERAL_PURPOSE_QUEUE_BASE + 31) / 32) * 32;
             baseQueue < (QMSS_GENERAL_PURPOSE_QUEUE_BASE + QMSS_MAX_GENERAL_PURPOSE_QUEUE - 64);
             baseQueue += 32) {
            for (queueNum = 0; queueNum < 64; queueNum++) {
                queueHnds[queueNum] = 
                  Qmss_queueOpen (Qmss_QueueType_GENERAL_PURPOSE_QUEUE, 
                                  baseQueue + queueNum, &isAllocated);
                if (queueHnds[queueNum] < 0) {
                    errorCount++;
                    System_printf("Core %d : queue open failed: %d\n", corenum, queueHnds[queueNum]);
		    break;
                }
                if (! isAllocated) {
                    /* Somebody else got the queue. Close what we got, and try next range */
                    for (queueNum--; queueNum >= 0; queueNum--) {
                        Qmss_queueClose (queueHnds[queueNum]);
                    }
                    break;
                }
            }
            if (queueNum == 64) {
                foundBase = baseQueue;
		break;
            }
        }
        if (foundBase >= 0) {
            baseQueue = foundBase;
            System_printf ("Core %d : Found range of 64 queues for QoS at %d\n", corenum, baseQueue);
        } else {
            System_printf ("Core %d : Failed to find range of 64 queues for QoS\n", corenum);
	    errorCount++;
        }
    }
#else
    baseQueue = QMSS_TRAFFIC_SHAPING_QUEUE_BASE;
#endif
    if ((result = Qmss_setQosQueueBase (baseQueue)) != QCMD_RETCODE_SUCCESS)
	{
        System_printf ("Error Core %d : Setting QoS queue base address error code: %d \n", corenum, result);
        errorCount++;
	}
    else
    {
        System_printf ("Core %d : Set QoS queue base address return code: %d \n", corenum, result);
    }

    if ((result = Qmss_getQosQueueBase (&baseQueue)) != QCMD_RETCODE_SUCCESS)
	{
        System_printf ("Error Core %d : Getting QoS queue base address error code: %d \n", corenum, result);
        errorCount++;
	}
    else
    {
        System_printf ("Core %d : Get QoS queue base address queue number : %d return code: %d \n", corenum, baseQueue, result);
    }
    if ((result = Qmss_configureQosTimer (0x1234)) != QCMD_RETCODE_SUCCESS)
	{
        System_printf ("Error Core %d : Setting QoS timer error code: %d \n", corenum, result);
        errorCount++;
	}
    else
    {
        System_printf ("Core %d : Set QoS timer return code: %d \n", corenum, result);
    }

    queueCfg.egressQueNum = 123;
    queueCfg.iterationCredit = 10;
    queueCfg.maxCredit = 15;
    queueCfg.congestionThreshold = 255;
    
    baseQueue = 0;
    if ((result = Qmss_configureQosQueue (baseQueue, &queueCfg)) != QCMD_RETCODE_SUCCESS)
	{
        System_printf ("Error Core %d : Configuring QoS queue %d error code: %d \n", corenum, baseQueue, result);
        errorCount++;
	}
    else
    {
        System_printf ("Core %d : Configured QoS queue %d return code: %d \n", corenum, baseQueue, result);
    }

    queueCfg.egressQueNum = 124;
    queueCfg.iterationCredit = 16;
    queueCfg.maxCredit = 32;
    queueCfg.congestionThreshold = 254;
    
    baseQueue = 1;

    if ((result = Qmss_configureQosQueue (baseQueue, &queueCfg)) != QCMD_RETCODE_SUCCESS)
	{
        System_printf ("Error Core %d : Configuring QoS queue %d error code: %d \n", corenum, baseQueue, result);
        errorCount++;
	}
    else
    {
        System_printf ("Core %d : Configured QoS queue %d return code: %d \n", corenum, baseQueue, result);
    }

    clusterCfgTB = &clusterCfg.u.cfgTB;
    clusterCfg.mode = Qmss_QosMode_TokenBucket;
    clusterCfgTB->maxGlobalCredit = 32;
    clusterCfgTB->qosQueCnt = 2;
    clusterCfgTB->qosQueNum[0] = 0;
    clusterCfgTB->qosQueNum[1] = 1;
    clusterCfgTB->qosQueRTFlags = 3;
    clusterCfgTB->egressQueCnt = 2;
    clusterCfgTB->egressQueNum[0].qMgr = 0;
    clusterCfgTB->egressQueNum[0].qNum = 124;
    clusterCfgTB->egressQueNum[1].qMgr = 0;
    clusterCfgTB->egressQueNum[1].qNum = 640;
    clusterCfgTB->egressCongestionThreshold1 = 8;
    clusterCfgTB->egressCongestionThreshold2 = 16;
    clusterCfgTB->egressCongestionThreshold3 = 32;
    clusterCfgTB->egressCongestionThreshold4 = 64;

    if ((result = Qmss_configureQosCluster (0, &clusterCfg)) != QCMD_RETCODE_SUCCESS)
	{
        System_printf ("Error Core %d : Configuring QoS cluster error code: %d \n", corenum, result);
        errorCount++;
	}
    else
    {
        System_printf ("Core %d : Configured QoS cluster return code: %d \n", corenum, result);
    }

    baseQueue = 0;
    if ((result = Qmss_getQosQueueForwardPktStats (baseQueue)) == QMSS_QCMD_INVALID_INDEX)
	{
        System_printf ("Error Core %d : Get forwarded packet count for queue %d error code: %d \n", corenum, baseQueue, result);
        errorCount++;
	}
    else
    {
        System_printf ("Core %d : Get forwarded packet count for queue %d is : %d \n", corenum, baseQueue, result);
    }

    baseQueue = 1;
    if ((result = Qmss_getQosQueueForwardPktStats (baseQueue)) == QMSS_QCMD_INVALID_INDEX)
	{
        System_printf ("Error Core %d : Get forwarded packet count for queue %d error code: %d \n", corenum, baseQueue, result);
        errorCount++;
	}
    else
    {
        System_printf ("Core %d : Get forwarded packet count for queue %d is : %d \n", corenum, baseQueue, result);
    }

    baseQueue = 0;
    if ((result = Qmss_getQosQueueDroppedPktStats (baseQueue)) == QMSS_QCMD_INVALID_INDEX)
	{
        System_printf ("Error Core %d : Get dropped packet count for queue %d error code: %d \n", corenum, baseQueue, result);
        errorCount++;
	}
    else
    {
        System_printf ("Core %d : Get dropped packet count for queue %d is : %d \n", corenum, baseQueue, result);
    }

    baseQueue = 1;
    if ((result = Qmss_getQosQueueDroppedPktStats (baseQueue)) == QMSS_QCMD_INVALID_INDEX)
	{
        System_printf ("Error Core %d : Get dropped packet count for queue %d error code: %d \n", corenum, baseQueue, result);
        errorCount++;
	}
    else
    {
        System_printf ("Core %d : Get dropped packet count for queue %d is : %d \n", corenum, baseQueue, result);
    }

    baseQueue = 0;
    if ((result = Qmss_resetQosQueueStats (baseQueue)) == QMSS_QCMD_INVALID_INDEX)
	{
        System_printf ("Error Core %d : Reset stats for queue %d error code: %d \n", corenum, baseQueue, result);
        errorCount++;
	}
    else
    {
        System_printf ("Core %d : Reset stats for queue %d is : %d \n", corenum, baseQueue, result);
    }

    if ((result = Qmss_enableQosCluster (0)) != QCMD_RETCODE_SUCCESS)
	{
        System_printf ("Error Core %d : Enabling QoS cluster error code: %d \n", corenum, result);
        errorCount++;
	}
    else
    {
        System_printf ("Core %d : Enabled QoS cluster return code: %d \n", corenum, result);
    }

    if ((result = Qmss_disableQosCluster (0)) != QCMD_RETCODE_SUCCESS)
	{
        System_printf ("Error Core %d : Disabling QoS cluster error code: %d \n", corenum, result);
        errorCount++;
	}
    else
    {
        System_printf ("Core %d : Disabled QoS cluster return code: %d \n", corenum, result);
    }

    /* Set up a Round Robin cluster */
    queueCfg.egressQueNum = 125;
    queueCfg.iterationCredit = 10;
    queueCfg.maxCredit = 15;
    queueCfg.congestionThreshold = 255;

    /* Set up input queues */
    for (baseQueue = 56; baseQueue < 64; baseQueue++) 
    {
        if ((result = Qmss_configureQosQueue (baseQueue, &queueCfg)) != QCMD_RETCODE_SUCCESS) 
        {
            System_printf ("Error Core %d : Configuring RR cluster QoS queue %d error code: %d \n", corenum, baseQueue, result);
            errorCount++;
        }
    }

    /* Set up cluster */
    memset (&clusterCfg, 0, sizeof(clusterCfg));
    clusterCfgRR                       = &clusterCfg.u.cfgRR;
    clusterCfg.mode                    = Qmss_QosMode_RoundRobin;
    clusterCfgRR->maxGlobalCredit      = 32;
    clusterCfgRR->qosQueHighCnt        = 4;
    clusterCfgRR->qosQueNumHigh[0]     = 56;
    clusterCfgRR->qosQueNumHigh[1]     = 57;
    clusterCfgRR->qosQueNumHigh[2]     = 58;
    clusterCfgRR->qosQueNumHigh[3]     = 59;
    clusterCfgRR->qosQueLowCnt         = 4;
    clusterCfgRR->qosQueNumLow[0]      = 60;
    clusterCfgRR->qosQueNumLow[1]      = 61;
    clusterCfgRR->qosQueNumLow[2]      = 62;
    clusterCfgRR->qosQueNumLow[3]      = 63;
    clusterCfgRR->sizeAdjust           = 24;
    clusterCfgRR->egressQueCnt         = 1;
    clusterCfgTB->egressQueNum[0].qMgr = 0;
    clusterCfgTB->egressQueNum[0].qNum = 125;
    clusterCfgRR->iterationCredit      = 10;
    clusterCfgRR->maxEgressBacklog     = 64;
    clusterCfgRR->queueDisableMask     = 0;
    
    /* Negative tests */
    if ((result = Qmss_configureQosCluster (0, &clusterCfg)) != QMSS_QCMD_INVALID_INDEX) {
        /* Should fail, only cluster 7 supports RR */
        System_printf ("Error Core %d : Configuring RR cluster 0 didn't fail: error code: %d \n", 
                       corenum, result);
        errorCount++;
    }

    clusterCfgRR->qosQueHighCnt        = 0;
    if ((result = Qmss_configureQosCluster (7, &clusterCfg)) != QMSS_QCMD_INVALID_RR_HIGH_Q) {
        /* Should fail, must have 4 high priority queues */
        System_printf ("Error Core %d : Configuring RR cluster didn't fail qosQueHighCnt: error code: %d \n", 
                       corenum, result);
        errorCount++;
    }

    clusterCfgRR->qosQueHighCnt        = 4;
    clusterCfgRR->qosQueLowCnt         = 0;
    if ((result = Qmss_configureQosCluster (7, &clusterCfg)) != QMSS_QCMD_INVALID_RR_LOW_Q) {
        /* Should fail, must have 4 high priority queues */
        System_printf ("Error Core %d : Configuring RR cluster didn't fail qosQueLowCnt: error code: %d \n", 
                       corenum, result);
        errorCount++;
    }

    clusterCfgRR->qosQueLowCnt         = 4;
    clusterCfgRR->egressQueCnt         = 0;
    if ((result = Qmss_configureQosCluster (7, &clusterCfg)) != QMSS_QCMD_INVALID_RR_EGRESS_Q) {
        /* Should fail, must have 4 high priority queues */
        System_printf ("Error Core %d : Configuring RR cluster didn't fail egressQueCnt: error code: %d \n", 
                       corenum, result);
        errorCount++;
    }

    clusterCfgRR->egressQueCnt         = 1;
    clusterCfgRR->qosQueNumHigh[3]     = 0;
    if ((result = Qmss_configureQosCluster (7, &clusterCfg)) != QMSS_QCMD_INVALID_RR_HIGH_Q) {
        /* Should fail, must have 4 high priority queues */
        System_printf ("Error Core %d : Configuring RR cluster didn't fail qosQueueNumHigh[]: error code: %d \n", 
                       corenum, result);
        errorCount++;
    }

    clusterCfgRR->qosQueNumHigh[3]     = 59;
    clusterCfgRR->qosQueNumLow[3]      = 0;
    if ((result = Qmss_configureQosCluster (7, &clusterCfg)) != QMSS_QCMD_INVALID_RR_LOW_Q) {
        /* Should fail, must have 4 high priority queues */
        System_printf ("Error Core %d : Configuring RR cluster didn't fail qosQueueNumLow[]: error code: %d \n", 
                       corenum, result);
        errorCount++;
    }

    /* Positive test case */
    clusterCfgRR->qosQueNumLow[3]      = 63;
    if ((result = Qmss_configureQosCluster (7, &clusterCfg)) != QCMD_RETCODE_SUCCESS) {
        /* Should succeed */
        System_printf ("Error Core %d : Correctly onfiguring RR cluster failed: error code: %d \n", 
                       corenum, result);
        errorCount++;
    }

    if ((result = Qmss_enableQosCluster (7)) != QCMD_RETCODE_SUCCESS)
    {
        System_printf ("Error Core %d : Enabling QoS RR cluster error code: %d \n", corenum, result);
        errorCount++;
    }
    else
    {
        System_printf ("Core %d : Enabled QoS RR cluster return code: %d \n", corenum, result);
    }
#endif

    if (errorCount == 0)
        System_printf ("\nCore %d : Descriptor allocation tests Passed\n");
}

Void run_test (Void)
{
    testDescAllocation ();
}


