/**
 *   @file  cppi_test.c
 *
 *   @brief   
 *      This is the CPPI Low Level Driver resources test file.
 *
 *  \par
 *  ============================================================================
 *  @n   (C) Copyright 2009-2012, 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/IHeap.h>
#include <xdc/runtime/System.h>
#include <xdc/runtime/Memory.h>
#include <xdc/runtime/Error.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/heaps/HeapBuf.h>
#include <ti/sysbios/heaps/HeapMem.h>
#include <xdc/cfg/global.h>
#include <string.h>

/* CPPI LLD include */
#include <ti/drv/cppi/cppi_drv.h>
#include <ti/drv/cppi/cppi_desc.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 <cppi_osal.h>
#include <qmss_osal.h>

/* Test specific includes */
#include <cppi_test.h>

/************************ GLOBAL VARIABLES ********************/
/* linking RAM */
#pragma DATA_ALIGN (linkingRAM0, 16)
UInt64              linkingRAM0[NUM_HOST_DESC + NUM_MONOLITHIC_DESC];

/* Descriptor pool [Size of descriptor * Number of descriptors] */
#pragma DATA_ALIGN (hostDesc, 16)
UInt8               hostDesc[SIZE_HOST_DESC * NUM_HOST_DESC];
#pragma DATA_ALIGN (monolithicDesc, 16)
UInt8               monolithicDesc[SIZE_MONOLITHIC_DESC * NUM_MONOLITHIC_DESC];
#pragma DATA_ALIGN (dataBuff, 16)
UInt8               dataBuff[SIZE_DATA_BUFFER * NUM_DATA_BUFFER];

/* Error counter */
UInt32              errorCount = 0, coreNum;
/* Handle to CPPI heap */
IHeap_Handle        cppiHeap;
/* Rx channel handles */
Cppi_ChHnd          rxChHnd[NUM_RX_CHANNELS];
/* Tx channel handles */
Cppi_ChHnd          txChHnd[NUM_TX_CHANNELS];
/* Rx flow handles */
Cppi_FlowHnd        rxFlowHnd[NUM_RX_FLOWS];
/* Host and monolithic descriptor queue handles */
Qmss_QueueHnd       freeHostQueHnd, freeMonoQueHnd;

#ifdef CONFIG_ACC
/* List address for accumulator - twice the number of entries for Ping and Pong page */
#pragma DATA_ALIGN (hiPrioList, 16)
Uint32                          hiPrioList[(NUM_PACKETS + 1) * 2];
#endif

/************************ EXTERN VARIABLES ********************/

/* QMSS device specific configuration */
extern Qmss_GlobalConfigParams  qmssGblCfgParams;
/* CPPI device specific configuration */
extern Cppi_GlobalConfigParams  cppiGblCfgParams[];

/************************** EXTERNS ***************************/
extern Void testHostDataTransfer (Void);
extern Void testMonoDataTransfer (Void);

/************************** FUNCTIONS *************************/
/**
 *  @b Description
 *  @n  
 *      The function is used to get the handle to the CPPI memory heap.
 *      If the application is run on a multiple cores then place the CPPI global 
 *      variables in shared memory.  
 *
 *  @retval
 *      None
 */
static Void cppiHeapInit ()
{
    cppiHeap = HeapMem_Handle_upCast (cppiLocalHeap);
}

/**
 *  @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
 */
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 testCpdmaGlobalConfig (Cppi_Handle cppiHnd)
{
    Cppi_Result         result;
    UInt32              origLoopback;
        
    System_printf ("~~~~~~~~~~~~~Core %d TESTING CPDMA Global CONFIGURATION ~~~~~~~~~~~~\n", coreNum);
    
    if ((result = Cppi_getCpdmaLoopback (cppiHnd)) < CPPI_SOK)
    {
        System_printf ("Error Core %d : Getting CPDMA loopback configuration on startup\n", coreNum);
        errorCount++;
        return;
    }
    else 
    {
        System_printf ("Core %d : CPDMA Loopback on startup is %d\n", coreNum, result);
        origLoopback = result;
    }
    if ((result = Cppi_setCpdmaLoopback (cppiHnd, 0)) != CPPI_SOK)
    {
        System_printf ("Error Core %d : Disabling CPDMA loopback\n", coreNum);
        errorCount++;
    }
    else 
    {
        if ((result = Cppi_getCpdmaLoopback (cppiHnd)) < CPPI_SOK)
        {
            System_printf ("Error Core %d : Getting CPDMA loopback configuration\n", coreNum);
            errorCount++;
        }
        else 
            System_printf ("Core %d : CPDMA loopback is %d\n", coreNum, result);
    }

    if ((result = Cppi_setCpdmaLoopback (cppiHnd, 1)) != CPPI_SOK)
    {
        System_printf ("Error Core %d : Enabling CPDMA loopback\n", coreNum);
        errorCount++;
    }
    else 
    {
        if ((result = Cppi_getCpdmaLoopback (cppiHnd)) < CPPI_SOK)
        {
            System_printf ("Error Core %d : Getting CPDMA loopback configuration\n", coreNum);
            errorCount++;
        }
        else 
            System_printf ("Core %d : CPDMA loopback is %d\n", coreNum, result);
    }

    if ((result = Cppi_setCpdmaLoopback (cppiHnd, origLoopback) != CPPI_SOK))
    {
        System_printf ("Error Core %d : Enabling CPDMA loopback\n", coreNum);
        errorCount++;
    }
    else 
    {
        if ((result = Cppi_getCpdmaLoopback (cppiHnd)) < CPPI_SOK)
        {
            System_printf ("Error Core %d : Getting CPDMA loopback configuration\n", coreNum);
            errorCount++;
        }
        else 
            System_printf ("Core %d : CPDMA loopback is %d\n", coreNum, result);
    }
}

Void testRxChannelConfig (Cppi_Handle cppiHnd)
{
    UInt8               isAllocated;
    Cppi_ChHnd          ChHnd;
    Cppi_RxChInitCfg    ChCfg;
    UInt32              ChNum;
    Cppi_Result         result;

    System_printf ("~~~~~~~~~~~~~Core %d TESTING RX CHANNEL CONFIGURATION ~~~~~~~~~~~~\n", coreNum);

    /* Don't specify channel number and let CPPI allocate the next available one */    
    ChCfg.channelNum = CPPI_PARAM_NOT_SPECIFIED;
    ChCfg.rxEnable = Cppi_ChState_CHANNEL_ENABLE;
    
    /* Open Channel */
    ChHnd = (Cppi_ChHnd) Cppi_rxChannelOpen (cppiHnd, &ChCfg, &isAllocated);
    if (ChHnd == NULL)
    {
        System_printf ("Error Core %d : Opening Rx channel : %d\n", coreNum, ChCfg.channelNum);
        errorCount++;
    }
    else
    {
        ChNum = Cppi_getChannelNumber (ChHnd);
        System_printf ("Core %d : Opened Rx channel : %d\n", coreNum, ChNum);
    }

    /* Disable channel */
    if (Cppi_channelDisable (ChHnd) != CPPI_SOK)
        System_printf ("Error Core %d : Disabling Rx channel : %d\n", coreNum, ChNum);
    else 
        System_printf ("Core %d : Disabled Rx channel : %d\n", coreNum, ChNum);

    /* Get channel status */
    if ((result = Cppi_channelStatus (ChHnd)) < 0)
    {
        System_printf ("Error Core %d : Obtaining Rx channel status: %d\n", coreNum, ChNum);
        errorCount++;
    }
    else 
    {
        if (result != Cppi_ChState_CHANNEL_DISABLE)
        {
            System_printf ("Error Core %d : Incorrect Rx channel status: %d\n", coreNum, ChNum);
            errorCount++;
        }
        else        
            System_printf ("Core %d : Rx Channel status : %d\n", coreNum, result);
    }

    /* Enable channel */
    if (Cppi_channelEnable (ChHnd) != CPPI_SOK)
    {
        System_printf ("Error Core %d : Enabling Rx channel : %d\n", coreNum, ChNum);
        errorCount++;
    }
    else 
        System_printf ("Core %d : Enabled Rx channel : %d\n", coreNum, ChNum);

    /* Get channel status */
    if ((result = Cppi_channelStatus (ChHnd)) < 0)
    {
        System_printf ("Error Core %d : Obtaining Rx channel status: %d\n", coreNum, ChNum);
        errorCount++;
    }
    else 
    {
        if (result != Cppi_ChState_CHANNEL_ENABLE)
        {
            System_printf ("Error Core %d : Incorrect Rx channel status: %d\n", coreNum, ChNum);
            errorCount++;
        }
        else        
            System_printf ("Core %d : Rx Channel status : %d\n", coreNum, result);
    }

    /* Pause channel */
    if (Cppi_channelPause (ChHnd) != CPPI_SOK)
    {
        System_printf ("Error Core %d : Pausing Rx channel : %d\n", coreNum, ChNum);
        errorCount++;
    }
    else 
        System_printf ("Core %d : Paused Rx channel : %d\n", coreNum, ChNum);

    /* Get channel status */
    if ((result = Cppi_channelStatus (ChHnd)) < 0)
    {
        System_printf ("Error Core %d : Obtaining Rx channel status: %d\n", coreNum, ChNum);
        errorCount++;
    }
    else 
    {
        if (result != Cppi_ChState_CHANNEL_ENABLE)
        {
            System_printf ("Error Core %d : Incorrect Rx channel status: %d\n", coreNum, ChNum);
            errorCount++;
        }
        else        
            System_printf ("Core %d : Rx Channel status : %d\n", coreNum, result);
    }

    /* Disable channel */
    if (Cppi_channelDisable (ChHnd) != CPPI_SOK)
    {
        System_printf ("Error Core %d : Disabling Rx channel : %d\n", coreNum, ChNum);
        errorCount++;
    }
    else 
        System_printf ("Core %d : Disabled Rx channel : %d\n", coreNum, ChNum);

    /* Close Channel */
    if ((result = Cppi_channelClose (ChHnd)) < 0)
    {
        System_printf ("Error Core %d : Closing Rx channel error code: %d\n", coreNum, result);
        errorCount++;
    }
    else
        System_printf ("Core %d : Rx Channel %d closed successfully. Ref count :%d\n", coreNum, ChNum, result);

    /* Testing teardown */
    /* Open Channel */
    ChHnd = (Cppi_ChHnd) Cppi_rxChannelOpen (cppiHnd, &ChCfg, &isAllocated);
    if (ChHnd == NULL)
    {
        System_printf ("Error Core %d : Opening Rx channel : %d\n", coreNum, ChCfg.channelNum);
        errorCount++;
    }
    else
    {
        ChNum = Cppi_getChannelNumber (ChHnd);
        System_printf ("Core %d : Opened Rx channel : %d\n", coreNum, ChNum);
    }

    /* Get channel status */
    if ((result = Cppi_channelStatus (ChHnd)) < 0)
    {
        System_printf ("Error Core %d : Obtaining Rx channel status: %d\n", coreNum, ChNum);
        errorCount++;
    }
    else 
    {
        if (result != Cppi_ChState_CHANNEL_ENABLE)
        {
            System_printf ("Error Core %d : Incorrect Rx channel status: %d\n", coreNum, ChNum);
            errorCount++;
        }
        else        
            System_printf ("Core %d : Rx Channel status : %d\n", coreNum, result);
    }

    /* Test blocking teardown */
    if (Cppi_channelTeardown (ChHnd, Cppi_Wait_WAIT) != CPPI_SOK)
    {
        System_printf ("Error Core %d : Tearing down Rx channel : %d\n", coreNum, ChNum);
        errorCount++;
    }
    else 
        System_printf ("Core %d : Torn down Rx channel : %d\n", coreNum, ChNum);

    /* Get channel status */
    if ((result = Cppi_channelStatus (ChHnd)) < 0)
    {
        System_printf ("Error Core %d : Obtaining Rx channel status: %d\n", coreNum, ChNum);
        errorCount++;
    }
    else 
    {
        if (result == Cppi_ChState_CHANNEL_ENABLE)
        {
            System_printf ("Error Core %d : Incorrect Rx channel status: %d\n", coreNum, ChNum);
            errorCount++;
        }
        else        
            System_printf ("Core %d : Rx Channel status : %d\n", coreNum, result);
    }

    /* Close Channel */
    if ((result = Cppi_channelClose (ChHnd)) < 0)
    {
        System_printf ("Error Core %d : Closing Rx channel error code: %d\n", coreNum, result);
        errorCount++;
    }
    else
        System_printf ("Core %d : Rx Channel %d closed successfully. Ref count :%d\n", coreNum, ChNum, result);

    /* Open Channel */
    ChHnd = (Cppi_ChHnd) Cppi_rxChannelOpen (cppiHnd, &ChCfg, &isAllocated);
    if (ChHnd == NULL)
    {
        System_printf ("Error Core %d : Opening Rx channel : %d\n", coreNum, ChCfg.channelNum);
        errorCount++;
    }
    else
    {
        ChNum = Cppi_getChannelNumber (ChHnd);
        System_printf ("Core %d : Opened Rx channel : %d\n", coreNum, ChNum);
    }

    /* Get channel status */
    if ((result = Cppi_channelStatus (ChHnd)) < 0)
    {
        System_printf ("Error Core %d : Obtaining Rx channel status: %d\n", coreNum, ChNum);
        errorCount++;
    }
    else 
    {
        if (result != Cppi_ChState_CHANNEL_ENABLE)
        {
            System_printf ("Error Core %d : Incorrect Rx channel status: %d\n", coreNum, ChNum);
            errorCount++;
        }
        else        
            System_printf ("Core %d : Rx Channel status : %d\n", coreNum, result);
    }

    /* Test non-blocking teardown */
    if (Cppi_channelTeardown (ChHnd, Cppi_Wait_NO_WAIT) != CPPI_SOK)
    {
        System_printf ("Error Core %d : Tearing down Rx channel : %d\n", coreNum, ChNum);
        errorCount++;
    }
    else 
        System_printf ("Core %d : Torn down Rx channel : %d\n", coreNum, ChNum);

    do{
        /* Get channel status */
        if ((result = Cppi_channelStatus (ChHnd)) < 0)
        {
            System_printf ("Error Core %d : Obtaining Rx channel status: %d\n", coreNum, ChNum);
            errorCount++;
        }
    }while (result == Cppi_ChState_CHANNEL_ENABLE);

    /* Close Channel */
    if ((result = Cppi_channelClose (ChHnd)) < 0)
    {
        System_printf ("Error Core %d : Closing Rx channel error code: %d\n", coreNum, result);
        errorCount++;
    }
    else
        System_printf ("Core %d : Rx Channel %d closed successfully. Ref count :%d\n", coreNum, ChNum, result);

    System_printf ("~~~~~~~~~~~~~Core %d RX CHANNEL CONFIGURATION DONE~~~~~~~~~~~~~~~~\n", coreNum);
}

Void testRxChannelAllocate (Cppi_Handle cppiHnd)
{
    UInt8               isAllocated;
    UInt32              i;
    Cppi_Result         result;
    /* Rx channel configuration */
    Cppi_RxChInitCfg    rxChCfg;

    /* Don't specify channel number and let CPPI allocate the next available one */

    System_printf ("*************Core %d TESTING RX CHANNEL ***************\n", coreNum);
    
    System_printf ("~~~~~~~~~~~~~Core %d RX CHANNEL LLD ALLOCATE~~~~~~~~~~~\n", coreNum);
    rxChCfg.channelNum = CPPI_PARAM_NOT_SPECIFIED;
    rxChCfg.rxEnable = Cppi_ChState_CHANNEL_ENABLE;
    
    /* Open Rx Channel */
    for (i = 0; i < NUM_RX_CHANNELS; i++)
    {
        rxChHnd[i] = (Cppi_ChHnd) Cppi_rxChannelOpen (cppiHnd, &rxChCfg, &isAllocated);
        if (rxChHnd[i] == NULL)
        {
            System_printf ("Error Core %d : Opening Rx channel : %d\n", coreNum, rxChCfg.channelNum);
            errorCount++;
        }
        else 
            System_printf ("Core %d : Opened Rx channel : %d\n", coreNum, Cppi_getChannelNumber (rxChHnd[i]));
    }

    System_printf ("~~~~~~~~~~~~~Core %d TESTING RX CHANNEL CLOSE~~~~~~~~~~\n", coreNum);
    /* Close Rx Channel */
    for (i = 0; i < NUM_RX_CHANNELS; i++)
    {
        UInt32 temp =  Cppi_getChannelNumber (rxChHnd[i]);
           
        if ((result = Cppi_channelClose (rxChHnd[i])) < 0)
        {
            System_printf ("Error Core %d : Closing Rx channel error code: %d\n", coreNum, result);
            errorCount++;
        }
        else
            System_printf ("Core %d : Rx Channel %d closed successfully. Ref count :%d\n", 
                            coreNum, temp, result);
    }

    System_printf ("~~~~~~~~~~~~~Core %d RX CHANNEL SPECIFY~~~~~~~~~~~~~~~~\n", coreNum);

    /* Open Rx Channel */
    for (i = 0; i < NUM_RX_CHANNELS; i++)
    {
        rxChCfg.channelNum = i;
        rxChHnd[i] = (Cppi_ChHnd) Cppi_rxChannelOpen (cppiHnd, &rxChCfg, &isAllocated);
        if (rxChHnd[i] == NULL)
        {
            System_printf ("Error Core %d : Opening Rx channel : %d\n", coreNum, rxChCfg.channelNum);
            errorCount++;
        }
        else 
            System_printf ("Core %d : Opened Rx channel : %d\n", coreNum, Cppi_getChannelNumber (rxChHnd[i]));

    }

    /* Open Rx Channel the 2nd time */
    for (i = 0; i < NUM_RX_CHANNELS; i++)
    {
        rxChCfg.channelNum = i;
        rxChHnd[i] = (Cppi_ChHnd) Cppi_rxChannelOpen (cppiHnd, &rxChCfg, &isAllocated);
        if (rxChHnd[i] == NULL)
        {
            System_printf ("Error Core %d : Opening Rx channel : %d\n", coreNum, rxChCfg.channelNum);
            errorCount++;
        }
        else 
            System_printf ("Core %d : Opened Rx channel : %d\n", coreNum, Cppi_getChannelNumber (rxChHnd[i]));

    }

    System_printf ("~~~~~~~~~~~~~Core %d Testing Rx Channel close with multiple opens~~~~~~~~~~\n", coreNum);

    /* Close Rx Channel */
    for (i = 0; i < NUM_RX_CHANNELS; i++)
    {
        UInt32 temp =  Cppi_getChannelNumber (rxChHnd[i]);

        if ((result = Cppi_channelClose (rxChHnd[i])) < 0)
        {
            System_printf ("Error Core %d : Closing Rx channel error code: %d\n", coreNum, result);
            errorCount++;
        }
        else
            System_printf ("Core %d : Rx Channel %d closed successfully. Ref count :%d\n", 
                            coreNum, temp, result);
    }

    System_printf ("~~~~~~~~~~~~~Core %d Testing Rx Channel close for last open~~~~~~~~~~\n", coreNum);

    /* Close Rx Channel */
    for (i = 0; i < NUM_RX_CHANNELS; i++)
    {
        UInt32 temp =  Cppi_getChannelNumber (rxChHnd[i]);

        if ((result = Cppi_channelClose (rxChHnd[i])) < 0)
        {
            System_printf ("Error Core %d : Closing Rx channel error code: %d\n", coreNum, result);
            errorCount++;
        }
        else
            System_printf ("Core %d : Rx Channel %d closed successfully. Ref count :%d\n", 
                            coreNum, temp, result);
    }

    System_printf ("~~~~~~~~~~~~~Core %d Testing Rx Channel open for odd channels~~~~~~~~~~\n", coreNum);

    for (i = 0; i < NUM_RX_CHANNELS; i++)
    {
        rxChCfg.channelNum = i;
        if (i%2)
        {
            rxChHnd[i] = (Cppi_ChHnd) Cppi_rxChannelOpen (cppiHnd, &rxChCfg, &isAllocated);
            if (rxChHnd[i] == NULL)
            {
                System_printf ("Error Core %d : Opening Rx channel : %d\n", coreNum, rxChCfg.channelNum);
                errorCount++;
            }
            else 
                System_printf ("Core %d : Opened Rx channel : %d\n", coreNum, Cppi_getChannelNumber (rxChHnd[i]));
        }
    }

    System_printf ("~~~~~~~~~~~~~Core %d Testing Rx Channel open for remaining channels~~~~~~~~~~\n", coreNum);

    rxChCfg.channelNum = CPPI_PARAM_NOT_SPECIFIED;
    for (i = 0; i < NUM_RX_CHANNELS; i++)
    {
        if (!(i%2))
        {
            rxChHnd[i] = (Cppi_ChHnd) Cppi_rxChannelOpen (cppiHnd, &rxChCfg, &isAllocated);
            if (rxChHnd[i] == NULL)
            {
                System_printf ("Error Core %d : Opening Rx channel : %d\n", coreNum, rxChCfg.channelNum);
                errorCount++;
            }
            else 
                System_printf ("Core %d : Opened Rx channel : %d\n", coreNum, Cppi_getChannelNumber (rxChHnd[i]));
        }
    }
    /* Close Rx Channel */
    for (i = 0; i < NUM_RX_CHANNELS; i++)
    {
        UInt32 temp =  Cppi_getChannelNumber (rxChHnd[i]);

        if ((result = Cppi_channelClose (rxChHnd[i])) < 0)
        {
            System_printf ("Error Core %d : Closing Rx channel error code: %d\n", coreNum, result);
            errorCount++;
        }
        else
            System_printf ("Core %d : Rx Channel %d closed successfully. Ref count :%d\n", 
                            coreNum, temp, result);
    }

    System_printf ("~~~~~~~~~~~~~Core %d Testing Rx Channel open for even channels~~~~~~~~~~\n", coreNum);

    for (i = 0; i < NUM_RX_CHANNELS; i++)
    {
        rxChCfg.channelNum = i;
        if (!(i%2))
        {
            rxChHnd[i] = (Cppi_ChHnd) Cppi_rxChannelOpen (cppiHnd, &rxChCfg, &isAllocated);
            if (rxChHnd[i] == NULL)
            {
                System_printf ("Error Core %d : Opening Rx channel : %d\n", coreNum, rxChCfg.channelNum);
                errorCount++;
            }
            else 
                System_printf ("Core %d : Opened Rx channel : %d\n", coreNum, Cppi_getChannelNumber (rxChHnd[i]));
        }
    }

    System_printf ("~~~~~~~~~~~~~Core %d Testing Rx Channel open for remaining channels~~~~~~~~~~\n", coreNum);
    rxChCfg.channelNum = CPPI_PARAM_NOT_SPECIFIED;
    for (i = 0; i < NUM_RX_CHANNELS; i++)
    {
        if (i%2)
        {
            rxChHnd[i] = (Cppi_ChHnd) Cppi_rxChannelOpen (cppiHnd, &rxChCfg, &isAllocated);
            if (rxChHnd[i] == NULL)
            {
                System_printf ("Error Core %d : Opening Rx channel : %d\n", coreNum, rxChCfg.channelNum);
                errorCount++;
            }
            else 
                System_printf ("Core %d : Opened Rx channel : %d\n", coreNum, Cppi_getChannelNumber (rxChHnd[i]));
        }
    }
    /* Close Rx Channel */
    for (i = 0; i < NUM_RX_CHANNELS; i++)
    {
        UInt32 temp =  Cppi_getChannelNumber (rxChHnd[i]);

        if ((result = Cppi_channelClose (rxChHnd[i])) < 0)
        {
            System_printf ("Error Core %d : Closing Rx channel error code: %d\n", coreNum, result);
            errorCount++;
        }
        else
            System_printf ("Core %d : Rx Channel %d closed successfully. Ref count :%d\n", 
                            coreNum, temp, result);
    }
}

Void testTxChannelConfig (Cppi_Handle cppiHnd)
{
    UInt8               isAllocated;
    Cppi_ChHnd          ChHnd;
    Cppi_TxChInitCfg    ChCfg;
    UInt32              ChNum;
    Cppi_Result         result;

    System_printf ("~~~~~~~~~~~~~Core %d TESTING TX CHANNEL CONFIGURATION ~~~~~~~~~~~~\n", coreNum);

    /* Don't specify channel number and let CPPI allocate the next available one */    
    ChCfg.channelNum = CPPI_PARAM_NOT_SPECIFIED;
    ChCfg.priority = 2;
    ChCfg.filterEPIB = 1;
    ChCfg.filterPS = 1;
    ChCfg.aifMonoMode = 1;
    ChCfg.txEnable = Cppi_ChState_CHANNEL_ENABLE;
    
    /* Open Channel */
    ChHnd = (Cppi_ChHnd) Cppi_txChannelOpen (cppiHnd, &ChCfg, &isAllocated);
    if (ChHnd == NULL)
    {
        System_printf ("Error Core %d : Opening Tx channel : %d\n", coreNum, ChCfg.channelNum);
        errorCount++;
    }
    else
    {
        ChNum = Cppi_getChannelNumber (ChHnd);
        System_printf ("Core %d : Opened Tx channel : %d\n", coreNum, ChNum);
    }

    /* Disable channel */
    if (Cppi_channelDisable (ChHnd) != CPPI_SOK)
    {
        System_printf ("Error Core %d : Disabling Tx channel : %d\n", coreNum, ChNum);
        errorCount++;
    }
    else 
        System_printf ("Core %d : Disabled Tx channel : %d\n", coreNum, ChNum);

    /* Get channel status */
    if ((result = Cppi_channelStatus (ChHnd)) < 0)
    {
        System_printf ("Error Core %d : Obtaining Tx channel status: %d\n", coreNum, ChNum);
        errorCount++;
    }
    else 
    {
        if (result != Cppi_ChState_CHANNEL_DISABLE)
        {
            System_printf ("Error Core %d : Incorrect Tx channel status: %d\n", coreNum, ChNum);
            errorCount++;
        }
        else        
            System_printf ("Core %d : Tx Channel status : %d\n", coreNum, result);
    }

    /* Enable channel */
    if (Cppi_channelEnable (ChHnd) != CPPI_SOK)
    {
        System_printf ("Error Core %d : Enabling Tx channel : %d\n", coreNum, ChNum);
        errorCount++;
    }
    else 
        System_printf ("Core %d : Enabled Tx channel : %d\n", coreNum, ChNum);

    /* Get channel status */
    if ((result = Cppi_channelStatus (ChHnd)) < 0)
    {
        System_printf ("Error Core %d : Obtaining Tx channel status: %d\n", coreNum, ChNum);
        errorCount++;
    }
    else 
    {
        if (result != Cppi_ChState_CHANNEL_ENABLE)
        {
            System_printf ("Error Core %d : Incorrect Tx channel status: %d\n", coreNum, ChNum);
            errorCount++;
        }
        else        
            System_printf ("Core %d : Tx Channel status : %d\n", coreNum, result);
    }

    /* Pause channel */
    if (Cppi_channelPause (ChHnd) != CPPI_SOK)
    {
        System_printf ("Error Core %d : Pausing Tx channel : %d\n", coreNum, ChNum);
        errorCount++;
    }
    else 
        System_printf ("Core %d : Paused Tx channel : %d\n", coreNum, ChNum);

    /* Get channel status */
    if ((result = Cppi_channelStatus (ChHnd)) < 0)
    {
        System_printf ("Error Core %d : Obtaining Tx channel status: %d\n", coreNum, ChNum);
        errorCount++;
    }
    else 
    {
        if (result != Cppi_ChState_CHANNEL_ENABLE)
        {
            System_printf ("Error Core %d : Incorrect Tx channel status: %d\n", coreNum, ChNum);
            errorCount++;
        }
        else        
            System_printf ("Core %d : Tx Channel status : %d\n", coreNum, result);
    }

    /* Disable channel */
    if (Cppi_channelDisable (ChHnd) != CPPI_SOK)
    {
        System_printf ("Error Core %d : Disabling Tx channel : %d\n", coreNum, ChNum);
        errorCount++;
    }
    else 
        System_printf ("Core %d : Disabled Tx channel : %d\n", coreNum, ChNum);

    /* Close Channel */
    if ((result = Cppi_channelClose (ChHnd)) < 0)
    {
        System_printf ("Error Core %d : Closing Tx channel error code: %d\n", coreNum, result);
        errorCount++;
    }
    else
        System_printf ("Core %d : Tx Channel %d closed successfully. Ref count :%d\n", coreNum, ChNum, result);

    /* Testing teardown */
    /* Open Channel */
    ChHnd = (Cppi_ChHnd) Cppi_txChannelOpen (cppiHnd, &ChCfg, &isAllocated);
    if (ChHnd == NULL)
    {
        System_printf ("Error Core %d : Opening Tx channel : %d\n", coreNum, ChCfg.channelNum);
        errorCount++;
    }
    else
    {
        ChNum = Cppi_getChannelNumber (ChHnd);
        System_printf ("Core %d : Opened Tx channel : %d\n", coreNum, ChNum);
    }

    /* Get channel status */
    if ((result = Cppi_channelStatus (ChHnd)) < 0)
    {
        System_printf ("Error Core %d : Obtaining Tx channel status: %d\n", coreNum, ChNum);
        errorCount++;
    }
    else 
    {
        if (result != Cppi_ChState_CHANNEL_ENABLE)
        {
            System_printf ("Error Core %d : Incorrect Tx channel status: %d\n", coreNum, ChNum);
            errorCount++;
        }
        else        
            System_printf ("Core %d : Tx Channel status : %d\n", coreNum, result);
    }

    /* Test blocking teardown */
    if (Cppi_channelTeardown (ChHnd, Cppi_Wait_WAIT) != CPPI_SOK)
    {
        System_printf ("Error Core %d : Tearing down Tx channel : %d\n", coreNum, ChNum);
        errorCount++;
    }
    else 
        System_printf ("Core %d : Torn down Tx channel : %d\n", coreNum, ChNum);

    /* Get channel status */
    if ((result = Cppi_channelStatus (ChHnd)) < 0)
    {
        System_printf ("Error Core %d : Obtaining Tx channel status: %d\n", coreNum, ChNum);
        errorCount++;
    }
    else 
    {
        if (result == Cppi_ChState_CHANNEL_ENABLE)
        {
            System_printf ("Error Core %d : Incorrect Tx channel status: %d\n", coreNum, ChNum);
            errorCount++;
        }
        else        
            System_printf ("Core %d : Tx Channel status : %d\n", coreNum, result);
    }

    /* Close Channel */
    if ((result = Cppi_channelClose (ChHnd)) < 0)
    {
        System_printf ("Error Core %d : Closing Tx channel error code: %d\n", coreNum, result);
        errorCount++;
    }
    else
        System_printf ("Core %d : Tx Channel %d closed successfully. Ref count :%d\n", coreNum, ChNum, result);

    /* Open Channel */
    ChHnd = (Cppi_ChHnd) Cppi_txChannelOpen (cppiHnd, &ChCfg, &isAllocated);
    if (ChHnd == NULL)
    {
        System_printf ("Error Core %d : Opening Tx channel : %d\n", coreNum, ChCfg.channelNum);
        errorCount++;
    }
    else
    {
        ChNum = Cppi_getChannelNumber (ChHnd);
        System_printf ("Core %d : Opened Tx channel : %d\n", coreNum, ChNum);
    }

    /* Get channel status */
    if ((result = Cppi_channelStatus (ChHnd)) < 0)
    {
        System_printf ("Error Core %d : Obtaining Tx channel status: %d\n", coreNum, ChNum);
        errorCount++;
    }
    else 
    {
        if (result != Cppi_ChState_CHANNEL_ENABLE)
        {
            System_printf ("Error Core %d : Incorrect Tx channel status: %d\n", coreNum, ChNum);
            errorCount++;
        }
        else        
            System_printf ("Core %d : Tx Channel status : %d\n", coreNum, result);
    }

    /* Test non-blocking teardown */
    if (Cppi_channelTeardown (ChHnd, Cppi_Wait_NO_WAIT) != CPPI_SOK)
    {
        System_printf ("Error Core %d : Tearing down Tx channel : %d\n", coreNum, ChNum);
        errorCount++;
    }
    else 
        System_printf ("Core %d : Torn down Tx channel : %d\n", coreNum, ChNum);

    do{
        /* Get channel status */
        if ((result = Cppi_channelStatus (ChHnd)) < 0)
        {
            System_printf ("Error Core %d : Obtaining Tx channel status: %d\n", coreNum, ChNum);
            errorCount++;
        }
    }while (result == Cppi_ChState_CHANNEL_ENABLE);

    /* Close Channel */
    if ((result = Cppi_channelClose (ChHnd)) < 0)
    {
        System_printf ("Error Core %d : Closing Tx channel error code: %d\n", coreNum, result);
        errorCount++;
    }
    else
        System_printf ("Core %d : Tx Channel %d closed successfully. Ref count :%d\n", coreNum, ChNum, result);

    System_printf ("~~~~~~~~~~~~~Core %d TX CHANNEL CONFIGURATION DONE~~~~~~~~~~~~~~~~\n", coreNum);
}

Void testTxChannelAllocate (Cppi_Handle cppiHnd)
{
    UInt8               isAllocated;
    UInt32              i;
    Cppi_Result         result;
    /* Tx channel configuration */
    Cppi_TxChInitCfg    txChCfg;

    /* Don't specify channel number and let CPPI allocate the next available one */

    System_printf ("*************Core %d TESTING Tx CHANNEL ***************\n", coreNum);
    
    System_printf ("~~~~~~~~~~~~~Core %d Tx CHANNEL LLD ALLOCATE~~~~~~~~~~~\n", coreNum);
        
    /* Don't specify channel number and let CPPI allocate the next available one */
    txChCfg.channelNum = CPPI_PARAM_NOT_SPECIFIED;
    txChCfg.priority = 2;
    txChCfg.filterEPIB = 0;
    txChCfg.filterPS = 0;
    txChCfg.aifMonoMode = 0;
    txChCfg.txEnable = Cppi_ChState_CHANNEL_ENABLE;
    
    /* Open Tx Channel */
    for (i = 0; i < NUM_TX_CHANNELS; i++)
    {
        txChHnd[i] = (Cppi_ChHnd) Cppi_txChannelOpen (cppiHnd, &txChCfg, &isAllocated);
        if (txChHnd[i] == NULL)
        {
            System_printf ("Error Core %d : Opening Tx channel : %d\n", coreNum, txChCfg.channelNum);
            errorCount++;
        }
        else 
            System_printf ("Core %d : Opened Tx channel : %d\n", coreNum, Cppi_getChannelNumber (txChHnd[i]));

    }

    System_printf ("~~~~~~~~~~~~~Core %d TESTING Tx CHANNEL CLOSE~~~~~~~~~~\n", coreNum);
    
    /* Close Tx Channel */
    for (i = 0; i < NUM_TX_CHANNELS; i++)
    {
        UInt32 temp =  Cppi_getChannelNumber (txChHnd[i]);
           
        if ((result = Cppi_channelClose (txChHnd[i])) < 0)
        {
            System_printf ("Error Core %d : Closing Tx channel error code: %d\n", coreNum, result);
            errorCount++;
        }
        else
            System_printf ("Core %d : Tx Channel %d closed successfully. Ref count :%d\n", 
                            coreNum, temp, result);
    }

    System_printf ("~~~~~~~~~~~~~Core %d Tx CHANNEL SPECIFY~~~~~~~~~~~~~~~~\n", coreNum);

    /* Open Tx Channel */
    for (i = 0; i < NUM_TX_CHANNELS; i++)
    {
        txChCfg.channelNum = i;
        txChHnd[i] = (Cppi_ChHnd) Cppi_txChannelOpen (cppiHnd, &txChCfg, &isAllocated);
        if (txChHnd[i] == NULL)
        {
            System_printf ("Error Core %d : Opening Tx channel : %d\n", coreNum, txChCfg.channelNum);
            errorCount++;
        }
        else 
            System_printf ("Core %d : Opened Tx channel : %d\n", coreNum, Cppi_getChannelNumber (txChHnd[i]));

    }

    /* Open Tx Channel the 2nd time */
    for (i = 0; i < NUM_TX_CHANNELS; i++)
    {
        txChCfg.channelNum = i;
        txChHnd[i] = (Cppi_ChHnd) Cppi_txChannelOpen (cppiHnd, &txChCfg, &isAllocated);
        if (txChHnd[i] == NULL)
        {
            System_printf ("Error Core %d : Opening Tx channel : %d\n", coreNum, txChCfg.channelNum);
            errorCount++;
        }
        else 
            System_printf ("Core %d : Opened Tx channel : %d\n", coreNum, Cppi_getChannelNumber (txChHnd[i]));

    }

    System_printf ("~~~~~~~~~~~~~Core %d Testing Tx Channel close with multiple opens~~~~~~~~~~\n", coreNum);
    /* Close Tx Channel */
    for (i = 0; i < NUM_TX_CHANNELS; i++)
    {
        UInt32 temp =  Cppi_getChannelNumber (txChHnd[i]);

        if ((result = Cppi_channelClose (txChHnd[i])) < 0)
        {
            System_printf ("Error Core %d : Closing Tx channel error code: %d\n", coreNum, result);
            errorCount++;
        }
        else
            System_printf ("Core %d : Tx Channel %d closed successfully. Ref count :%d\n", 
                            coreNum, temp, result);
    }

    System_printf ("~~~~~~~~~~~~~Core %d Testing Tx Channel close for last open~~~~~~~~~~\n", coreNum);

    /* Close Tx Channel */
    for (i = 0; i < NUM_TX_CHANNELS; i++)
    {
        UInt32 temp =  Cppi_getChannelNumber (txChHnd[i]);

        if ((result = Cppi_channelClose (txChHnd[i])) < 0)
        {
            System_printf ("Error Core %d : Closing Tx channel error code: %d\n", coreNum, result);
            errorCount++;
        }
        else
            System_printf ("Core %d : Tx Channel %d closed successfully. Ref count :%d\n", 
                            coreNum, temp, result);
    }

    System_printf ("~~~~~~~~~~~~~Core %d Testing Tx Channel open for odd channels~~~~~~~~~~\n", coreNum);

    for (i = 0; i < NUM_TX_CHANNELS; i++)
    {
        txChCfg.channelNum = i;
        if (i%2)
        {
            txChHnd[i] = (Cppi_ChHnd) Cppi_txChannelOpen (cppiHnd, &txChCfg, &isAllocated);
            if (txChHnd[i] == NULL)
            {
                System_printf ("Error Core %d : Opening Tx channel : %d\n", coreNum, txChCfg.channelNum);
                errorCount++;
            }
            else 
                System_printf ("Core %d : Opened Tx channel : %d\n", coreNum, Cppi_getChannelNumber (txChHnd[i]));
        }
    }

    System_printf ("~~~~~~~~~~~~~Core %d Testing Tx Channel open for remaining channels~~~~~~~~~~\n", coreNum);
    txChCfg.channelNum = CPPI_PARAM_NOT_SPECIFIED;
    for (i = 0; i < NUM_TX_CHANNELS; i++)
    {
        if (!(i%2))
        {
            txChHnd[i] = (Cppi_ChHnd) Cppi_txChannelOpen (cppiHnd, &txChCfg, &isAllocated);
            if (txChHnd[i] == NULL)
            {
                System_printf ("Error Core %d : Opening Tx channel : %d\n", coreNum, txChCfg.channelNum);
                errorCount++;
            }
            else 
                System_printf ("Core %d : Opened Tx channel : %d\n", coreNum, Cppi_getChannelNumber (txChHnd[i]));
        }
    }
    /* Close Tx Channel */
    for (i = 0; i < NUM_TX_CHANNELS; i++)
    {
        UInt32 temp =  Cppi_getChannelNumber (txChHnd[i]);

        if ((result = Cppi_channelClose (txChHnd[i])) < 0)
        {
            System_printf ("Error Core %d : Closing Tx channel error code: %d\n", coreNum, result);
            errorCount++;
        }
        else
            System_printf ("Core %d : Tx Channel %d closed successfully. Ref count :%d\n", 
                            coreNum, temp, result);
    }

    System_printf ("~~~~~~~~~~~~~Core %d Testing Tx Channel open for even channels~~~~~~~~~~\n", coreNum);

    for (i = 0; i < NUM_TX_CHANNELS; i++)
    {
        txChCfg.channelNum = i;
        if (!(i%2))
        {
            txChHnd[i] = (Cppi_ChHnd) Cppi_txChannelOpen (cppiHnd, &txChCfg, &isAllocated);
            if (txChHnd[i] == NULL)
            {
                System_printf ("Error Core %d : Opening Tx channel : %d\n", coreNum, txChCfg.channelNum);
                errorCount++;
            }
            else 
                System_printf ("Core %d : Opened Tx channel : %d\n", coreNum, Cppi_getChannelNumber (txChHnd[i]));
        }
    }

    System_printf ("~~~~~~~~~~~~~Core %d Testing Tx Channel open for remaining channels~~~~~~~~~~\n", coreNum);
    txChCfg.channelNum = CPPI_PARAM_NOT_SPECIFIED;
    for (i = 0; i < NUM_TX_CHANNELS; i++)
    {
        if (i%2)
        {
            txChHnd[i] = (Cppi_ChHnd) Cppi_txChannelOpen (cppiHnd, &txChCfg, &isAllocated);
            if (txChHnd[i] == NULL)
            {
                System_printf ("Error Core %d : Opening Tx channel : %d\n", coreNum, txChCfg.channelNum);
                errorCount++;
            }
            else 
                System_printf ("Core %d : Opened Tx channel : %d\n", coreNum, Cppi_getChannelNumber (txChHnd[i]));
        }
    }
    /* Close Tx Channel */
    for (i = 0; i < NUM_TX_CHANNELS; i++)
    {
        UInt32 temp =  Cppi_getChannelNumber (txChHnd[i]);

        if ((result = Cppi_channelClose (txChHnd[i])) < 0)
        {
            System_printf ("Error Core %d : Closing Tx channel error code: %d\n", coreNum, result);
            errorCount++;
        }
        else
            System_printf ("Core %d : Tx Channel %d closed successfully. Ref count :%d\n", 
                            coreNum, temp, result);
    }
}

Void testRxFlowConfig (Cppi_Handle cppiHnd)
{
    UInt8               isAllocated;
    Cppi_FlowHnd        rxFlowHnd;
    Cppi_RxFlowCfg      rxFlowCfg;
    UInt32              temp;
    Cppi_Result         result;

    System_printf ("***********Core %d TESTING RX FLOW CONFIGURATION*************\n", coreNum);
    
    memset ((Void *) &rxFlowCfg, 0, sizeof (Cppi_RxFlowCfg));

    /* Request flow number 0 */
    rxFlowCfg.flowIdNum = 0;
    rxFlowCfg.rx_dest_qnum = 100;
    rxFlowCfg.rx_dest_qmgr = 0;
    rxFlowCfg.rx_sop_offset= 16;
    rxFlowCfg.rx_ps_location = Cppi_PSLoc_PS_IN_SOP;
    rxFlowCfg.rx_desc_type = Cppi_DescType_HOST;
    rxFlowCfg.rx_error_handling = 1;
    rxFlowCfg.rx_psinfo_present = 1;
    rxFlowCfg.rx_einfo_present = 1;
    rxFlowCfg.rx_dest_tag_lo = 0xf1;
    rxFlowCfg.rx_dest_tag_hi = 0xf4;
    rxFlowCfg.rx_src_tag_lo = 0x60;
    rxFlowCfg.rx_src_tag_hi = 0x48;
    rxFlowCfg.rx_size_thresh0_en = 1;
    rxFlowCfg.rx_size_thresh1_en = 1;
    rxFlowCfg.rx_size_thresh2_en = 0;
    rxFlowCfg.rx_dest_tag_lo_sel = 2;
    rxFlowCfg.rx_dest_tag_hi_sel = 3;
    rxFlowCfg.rx_src_tag_lo_sel = 4;
    rxFlowCfg.rx_src_tag_hi_sel = 5;
    rxFlowCfg.rx_fdq1_qnum = 1000;
    rxFlowCfg.rx_fdq1_qmgr = 0;
    rxFlowCfg.rx_fdq0_sz0_qnum = 2687;
    rxFlowCfg.rx_fdq0_sz0_qmgr = 0;
    rxFlowCfg.rx_fdq3_qnum = 5000;
    rxFlowCfg.rx_fdq3_qmgr = 1;
    rxFlowCfg.rx_fdq2_qnum = 7800;
    rxFlowCfg.rx_fdq2_qmgr = 1;
    rxFlowCfg.rx_size_thresh1 = 512;
    rxFlowCfg.rx_size_thresh0 = 256;
    rxFlowCfg.rx_fdq0_sz1_qnum = 1;
    rxFlowCfg.rx_fdq0_sz1_qmgr = 0;
    rxFlowCfg.rx_size_thresh2 = 1024;
    rxFlowCfg.rx_fdq0_sz3_qnum = 721;
    rxFlowCfg.rx_fdq0_sz3_qmgr= 0;
    rxFlowCfg.rx_fdq0_sz2_qnum = 32;
    rxFlowCfg.rx_fdq0_sz2_qmgr = 0;

    /* Open Rx Flow */

    rxFlowHnd = (Cppi_FlowHnd) Cppi_configureRxFlow (cppiHnd, &rxFlowCfg, &isAllocated);
    if (rxFlowHnd == NULL)
    {
        System_printf ("Error Core %d : Opening Rx flow : %d\n", coreNum, rxFlowCfg.flowIdNum);
        errorCount++;
    }
    else 
        System_printf ("Core %d : Opened Rx flow : %d\n", coreNum, Cppi_getFlowId (rxFlowHnd));

    /* Close Rx Flow */
    
    temp = Cppi_getFlowId (rxFlowHnd);
           
    if ((result = Cppi_closeRxFlow (rxFlowHnd)) < 0)
    {
        System_printf ("Error Core %d : Closing Rx flow error code: %d\n", coreNum, result);
        errorCount++;
    }
    else
        System_printf ("Core %d : Rx Flow %d closed successfully. Ref count :%d\n", 
                            coreNum, temp, result);
    System_printf ("***********Core %d TESTING RX FLOW CONFIGURATION DONE*************\n", coreNum);
}

Void testRxFlowAllocate (Cppi_Handle cppiHnd)
{
    UInt8               isAllocated;
    UInt32              i;
    Cppi_Result         result;
    Cppi_RxFlowCfg      rxFlowCfg;

    System_printf ("*************Core %d TESTING RX FLOW ***************\n", coreNum);
    
    System_printf ("~~~~~~~~~~~~~Core %d RX FLOW LLD ALLOCATE~~~~~~~~~~~\n", coreNum);
    
    memset ((Void *) &rxFlowCfg, 0, sizeof (Cppi_RxFlowCfg));

    /* Don't specify flow number and let CPPI allocate the next available one */
    rxFlowCfg.flowIdNum = CPPI_PARAM_NOT_SPECIFIED;
    
    /* Open Rx Flow */
    for (i = 0; i < NUM_RX_FLOWS; i++)
    {
        rxFlowHnd[i] = (Cppi_FlowHnd) Cppi_configureRxFlow (cppiHnd, &rxFlowCfg, &isAllocated);
        if (rxFlowHnd[i] == NULL)
        {
            System_printf ("Error Core %d : Opening Rx flow : %d\n", coreNum, rxFlowCfg.flowIdNum);
            errorCount++;
        }
        else 
            System_printf ("Core %d : Opened Rx flow : %d\n", coreNum, Cppi_getFlowId (rxFlowHnd[i]));

    }

    System_printf ("~~~~~~~~~~~~~Core %d TESTING RX FLOW CLOSE~~~~~~~~~~\n", coreNum);

    /* Close Rx Flow */
    for (i = 0; i < NUM_RX_FLOWS; i++)
    {
        UInt32 temp =  Cppi_getFlowId (rxFlowHnd[i]);
           
        if ((result = Cppi_closeRxFlow (rxFlowHnd[i])) < 0)
        {
            System_printf ("Error Core %d : Closing Rx flow error code: %d\n", coreNum, result);
            errorCount++;
        }
        else
            System_printf ("Core %d : Rx Flow %d closed successfully. Ref count :%d\n", 
                            coreNum, temp, result);
    }

    System_printf ("~~~~~~~~~~~~~Core %d RX FLOW SPECIFY~~~~~~~~~~~~~~~~\n", coreNum);

    /* Open Rx Flow */
    for (i = 0; i < NUM_RX_FLOWS; i++)
    {
        rxFlowCfg.flowIdNum = i;
        rxFlowHnd[i] = (Cppi_FlowHnd) Cppi_configureRxFlow (cppiHnd, &rxFlowCfg, &isAllocated);
        if (rxFlowHnd[i] == NULL)
        {
            System_printf ("Error Core %d : Opening Rx flow : %d\n", coreNum, rxFlowCfg.flowIdNum);
            errorCount++;
        }
        else 
            System_printf ("Core %d : Opened Rx flow : %d\n", coreNum, Cppi_getFlowId (rxFlowHnd[i]));

    }

    /* Open Rx Flow the 2nd time */
    for (i = 0; i < NUM_RX_FLOWS; i++)
    {
        rxFlowCfg.flowIdNum = i;
        rxFlowHnd[i] = (Cppi_FlowHnd) Cppi_configureRxFlow (cppiHnd, &rxFlowCfg, &isAllocated);
        if (rxFlowHnd[i] == NULL)
        {
            System_printf ("Error Core %d : Opening Rx flow : %d\n", coreNum, rxFlowCfg.flowIdNum);
            errorCount++;
        }
        else 
            System_printf ("Core %d : Opened Rx flow : %d\n", coreNum, Cppi_getFlowId (rxFlowHnd[i]));

    }

    System_printf ("~~~~~~~~~~~~~Core %d Testing Rx Flow close with multiple opens~~~~~~~~~~\n", coreNum);

    /* Close Rx Flow */
    for (i = 0; i < NUM_RX_FLOWS; i++)
    {
        UInt32 temp =  Cppi_getFlowId (rxFlowHnd[i]);

        if ((result = Cppi_closeRxFlow (rxFlowHnd[i])) < 0)
        {
            System_printf ("Error Core %d : Closing Rx flow error code: %d\n", coreNum, result);
            errorCount++;
        }
        else
            System_printf ("Core %d : Rx Flow %d closed successfully. Ref count :%d\n", 
                            coreNum, temp, result);
    }

    System_printf ("~~~~~~~~~~~~~Core %d Testing Rx Flow close for last open~~~~~~~~~~\n", coreNum);

    /* Close Rx Flow */
    for (i = 0; i < NUM_RX_FLOWS; i++)
    {
        UInt32 temp =  Cppi_getFlowId (rxFlowHnd[i]);

        if ((result = Cppi_closeRxFlow (rxFlowHnd[i])) < 0)
        {
            System_printf ("Error Core %d : Closing Rx flow error code: %d\n", coreNum, result);
            errorCount++;
        }
        else
            System_printf ("Core %d : Rx Flow %d closed successfully. Ref count :%d\n", 
                            coreNum, temp, result);
    }

    System_printf ("~~~~~~~~~~~~~Core %d Testing Rx Flow open for odd flows~~~~~~~~~~\n", coreNum);

    for (i = 0; i < NUM_RX_FLOWS; i++)
    {
        rxFlowCfg.flowIdNum = i;
        if (i%2)
        {
            rxFlowHnd[i] = (Cppi_FlowHnd) Cppi_configureRxFlow (cppiHnd, &rxFlowCfg, &isAllocated);
            if (rxFlowHnd[i] == NULL)
            {
                System_printf ("Error Core %d : Opening Rx flow : %d\n", coreNum, rxFlowCfg.flowIdNum);
                errorCount++;
            }
            else 
                System_printf ("Core %d : Opened Rx flow : %d\n", coreNum, Cppi_getFlowId (rxFlowHnd[i]));
        }
    }

    System_printf ("~~~~~~~~~~~~~Core %d Testing Rx Flow open for remaining flows~~~~~~~~~~\n", coreNum);

    rxFlowCfg.flowIdNum = CPPI_PARAM_NOT_SPECIFIED;
    for (i = 0; i < NUM_RX_FLOWS; i++)
    {
        if (!(i%2))
        {
            rxFlowHnd[i] = (Cppi_FlowHnd) Cppi_configureRxFlow (cppiHnd, &rxFlowCfg, &isAllocated);
            if (rxFlowHnd[i] == NULL)
            {
                System_printf ("Error Core %d : Opening Rx flow : %d\n", coreNum, rxFlowCfg.flowIdNum);
                errorCount++;
            }
            else 
                System_printf ("Core %d : Opened Rx flow : %d\n", coreNum, Cppi_getFlowId (rxFlowHnd[i]));
        }
    }
    /* Close Rx Flow */
    for (i = 0; i < NUM_RX_FLOWS; i++)
    {
        UInt32 temp =  Cppi_getFlowId (rxFlowHnd[i]);

        if ((result = Cppi_closeRxFlow (rxFlowHnd[i])) < 0)
        {
            System_printf ("Error Core %d : Closing Rx flow error code: %d\n", coreNum, result);
            errorCount++;
        }
        else
            System_printf ("Core %d : Rx Flow %d closed successfully. Ref count :%d\n", 
                            coreNum, temp, result);
    }

    System_printf ("~~~~~~~~~~~~~Core %d Testing Rx Flow open for even flows~~~~~~~~~~\n", coreNum);

    for (i = 0; i < NUM_RX_FLOWS; i++)
    {
        rxFlowCfg.flowIdNum = i;
        if (!(i%2))
        {
            rxFlowHnd[i] = (Cppi_FlowHnd) Cppi_configureRxFlow (cppiHnd, &rxFlowCfg, &isAllocated);
            if (rxFlowHnd[i] == NULL)
            {
                System_printf ("Error Core %d : Opening Rx flow : %d\n", coreNum, rxFlowCfg.flowIdNum);
                errorCount++;
            }
            else 
                System_printf ("Core %d : Opened Rx flow : %d\n", coreNum, Cppi_getFlowId (rxFlowHnd[i]));
        }
    }

    System_printf ("~~~~~~~~~~~~~Core %d Testing Rx Flow open for remaining flows~~~~~~~~~~\n", coreNum);
    
    rxFlowCfg.flowIdNum = CPPI_PARAM_NOT_SPECIFIED;
    for (i = 0; i < NUM_RX_FLOWS; i++)
    {
        if (i%2)
        {
            rxFlowHnd[i] = (Cppi_FlowHnd) Cppi_configureRxFlow (cppiHnd, &rxFlowCfg, &isAllocated);
            if (rxFlowHnd[i] == NULL)
            {
                System_printf ("Error Core %d : Opening Rx flow : %d\n", coreNum, rxFlowCfg.flowIdNum);
                errorCount++;
            }
            else 
                System_printf ("Core %d : Opened Rx flow : %d\n", coreNum, Cppi_getFlowId (rxFlowHnd[i]));
        }
    }
    /* Close Rx Flow */
    for (i = 0; i < NUM_RX_FLOWS; i++)
    {
        UInt32 temp =  Cppi_getFlowId (rxFlowHnd[i]);

        if ((result = Cppi_closeRxFlow (rxFlowHnd[i])) < 0)
        {
            System_printf ("Error Core %d : Closing Rx flow error code: %d\n", coreNum, result);
            errorCount++;
        }
        else
            System_printf ("Core %d : Rx Flow %d closed successfully. Ref count :%d\n", 
                            coreNum, temp, result);
    }
}

Void testHostDescConfig (Void)
{
    Cppi_Result         result;
    UInt32              i, destLen, hostPktSize = 0, size; 
    Cppi_Desc           *hostDesc, *hostDesc1, *hostDesc2, *nextBD, *tempBD;
    Cppi_DescType       descType;
    Qmss_Queue          sQueue, gQueue;
    UInt8               *dataBuffPtr;
    UInt32              timestamp, refCount, newRefCount;
    Cppi_DescTag        txTag, rxTag;

    System_printf ("\n~~~~~~~~~~~~~Core %d Testing Host descriptor fields~~~~~~~~~~~\n", coreNum);

    hostDesc = (Cppi_Desc *) Qmss_queuePop (freeHostQueHnd);
    descType = Cppi_getDescType (hostDesc);
    if (descType != Cppi_DescType_HOST)
    {
        System_printf ("Error Core %d : Incorrect descriptor type : %d\n", coreNum, descType);
        errorCount++;
    }

    Cppi_setDescType (hostDesc, Cppi_DescType_MONOLITHIC);
    descType = Cppi_getDescType (hostDesc);
    if (descType != Cppi_DescType_MONOLITHIC)
    {
        System_printf ("Error Core %d : Incorrect descriptor type : %d\n", coreNum, descType);
        errorCount++;
    }

    Cppi_setDescType (hostDesc, Cppi_DescType_HOST);
    descType = Cppi_getDescType (hostDesc);
    if (descType != Cppi_DescType_HOST)
    {
        System_printf ("Error Core %d : Incorrect descriptor type : %d\n", coreNum, descType);
        errorCount++;
    }

    nextBD = (Cppi_Desc *) Qmss_queuePop (freeHostQueHnd);
   
    Cppi_linkNextBD (Cppi_DescType_HOST, hostDesc, nextBD);

    tempBD = Cppi_getNextBD (Cppi_DescType_HOST, hostDesc);

    if (nextBD != tempBD)
    {
        System_printf ("Error Core %d : Linking next BD is incorrect HostDesc : 0x%p Next BD linked: 0x%p, Next BD read: 0x%p\n", 
                        coreNum, hostDesc, nextBD, tempBD);
        errorCount++;
    }

    Cppi_linkNextBD (Cppi_DescType_HOST, hostDesc, NULL);

    tempBD = Cppi_getNextBD (Cppi_DescType_HOST, hostDesc);

    if (tempBD != NULL)
    {
        System_printf ("Error Core %d : NULL Linking is incorrect HostDesc : 0x%p\n", coreNum, hostDesc);
        errorCount++;
    }
    
    /* Fill in some data */
    for (i = 0; i < SIZE_DATA_BUFFER; i++) 
        dataBuff[i] = i;

    /* Add data buffer */
    Cppi_setData (Cppi_DescType_HOST, hostDesc, (UInt8 *) l2_global_address ((UInt32) dataBuff), SIZE_DATA_BUFFER);

    /* Save original buffer information */
    Cppi_setOriginalBufInfo (Cppi_DescType_HOST, hostDesc, (UInt8 *) l2_global_address ((UInt32) dataBuff), SIZE_DATA_BUFFER);

    /* Set packet length */
    Cppi_setPacketLen (Cppi_DescType_HOST, hostDesc, SIZE_DATA_BUFFER);
    
    if ((result = Cppi_getPacketLen (Cppi_DescType_HOST, hostDesc)) != SIZE_DATA_BUFFER)
    {
        System_printf ("Error Core %d : Set packet len %d Get packet len %d HostDesc : 0x%p\n", 
                        coreNum, SIZE_DATA_BUFFER, result, hostDesc);
        errorCount++;
    }

    /* Get data buffer */
    Cppi_getData (Cppi_DescType_HOST, hostDesc, &dataBuffPtr, &destLen);
    
    if (dataBuffPtr != ((UInt8 *) l2_global_address ((UInt32) dataBuff)))
    {
        System_printf ("Error Core %d : Set data buff 0x%p Get data buff 0x%p HostDesc : 0x%p\n", 
                        coreNum, l2_global_address ((UInt32) dataBuff), dataBuffPtr, hostDesc);
        errorCount++;
    }

    if (destLen != SIZE_DATA_BUFFER)
    {
        System_printf ("Error Core %d : Set data buff Len %d Get data buff Len %d HostDesc : 0x%p\n", 
                        coreNum, SIZE_DATA_BUFFER, destLen, hostDesc);
        errorCount++;
    }
    /* Get original buffer info */
    dataBuffPtr = 0;
    destLen = 0;
    Cppi_getOriginalBufInfo (Cppi_DescType_HOST, hostDesc, &dataBuffPtr, &destLen);

    if (dataBuffPtr != ((UInt8 *) l2_global_address ((UInt32) dataBuff)))
    {
        System_printf ("Error Core %d : Set original data buff 0x%p Get data buff 0x%p HostDesc : 0x%p\n", 
                        coreNum, l2_global_address ((UInt32) dataBuff), dataBuffPtr, hostDesc);
        errorCount++;
    }

    if (destLen != SIZE_DATA_BUFFER)
    {
        System_printf ("Error Core %d : Set original data buff Len %d Get data buff Len %d HostDesc : 0x%p\n", 
                        coreNum, SIZE_DATA_BUFFER, destLen, hostDesc);
        errorCount++;
    }

    /* Test optional fields */
    Cppi_setTimeStamp (Cppi_DescType_HOST, hostDesc, 0x7E3B0C8A);

    result = Cppi_getTimeStamp (Cppi_DescType_HOST, hostDesc, &timestamp);
    if (result != CPPI_SOK)
    {
        System_printf ("Error Core %d : Timestamp - EPIB not set HostDesc : 0x%p\n", coreNum, hostDesc);
        errorCount++;
    }

    /* Set software info */
    Cppi_setSoftwareInfo (Cppi_DescType_HOST, hostDesc, dataBuff);

    dataBuffPtr = 0;
    Cppi_getSoftwareInfo (Cppi_DescType_HOST, hostDesc, &dataBuffPtr);
    if (result != CPPI_SOK)
    {
        System_printf ("Error Core %d : Software Info - EPIB not set HostDesc : 0x%p\n", coreNum, hostDesc);
        errorCount++;
    }

    for (i=0; i < 12; i++)
    {
        if (dataBuff[i] != dataBuffPtr[i])
        {
            System_printf ("Error Core %d : In software info set: %02X - get: %02X \n", coreNum, dataBuff[i], dataBuffPtr[i]);
            errorCount++;
            break;
        }
    }

    /* Set software info 0 */
    Cppi_setSoftwareInfo0 (Cppi_DescType_HOST, hostDesc, 0xF0);

    result  = Cppi_getSoftwareInfo0 (Cppi_DescType_HOST, hostDesc);
    if (result != 0xF0)
    {
        System_printf ("Error Core %d : Software Info0 - Value %d is incorrect in HostDesc : 0x%p\n", coreNum, result, hostDesc);
        errorCount++;
    }

    /* Set software info 1 */
    Cppi_setSoftwareInfo1 (Cppi_DescType_HOST, hostDesc, 0x83546);

    result  = Cppi_getSoftwareInfo1 (Cppi_DescType_HOST, hostDesc);
    if (result != 0x83546)
    {
        System_printf ("Error Core %d : Software Info1 - Value %d is incorrect in HostDesc : 0x%p\n", coreNum, result, hostDesc);
        errorCount++;
    }

    /* Set software info 2 */
    Cppi_setSoftwareInfo2 (Cppi_DescType_HOST, hostDesc, 0xFFF0FFFF);

    result  = Cppi_getSoftwareInfo2 (Cppi_DescType_HOST, hostDesc);
    if (result != 0xFFF0FFFF)
    {
        System_printf ("Error Core %d : Software Info2 - Value %d is incorrect in HostDesc : 0x%p\n", coreNum, result, hostDesc);
        errorCount++;
    }

    /* Test return policy */

    Cppi_setReturnPolicy (Cppi_DescType_HOST, hostDesc, Cppi_ReturnPolicy_RETURN_BUFFER);

    if (Cppi_getReturnPolicy (Cppi_DescType_HOST, hostDesc) != Cppi_ReturnPolicy_RETURN_BUFFER)
    {
        System_printf ("Error Core %d : Incorrect return policy HostDesc : 0x%p\n", coreNum, hostDesc);
        errorCount++;
    }

    Cppi_setReturnPolicy (Cppi_DescType_HOST, hostDesc, Cppi_ReturnPolicy_RETURN_ENTIRE_PACKET);

    if (Cppi_getReturnPolicy (Cppi_DescType_HOST, hostDesc) != Cppi_ReturnPolicy_RETURN_ENTIRE_PACKET)
    {
        System_printf ("Error Core %d : Incorrect return policy HostDesc : 0x%p\n", coreNum, hostDesc);
        errorCount++;
    }

    /* Test return push policy */ 
    Cppi_setReturnPushPolicy (Cppi_DescType_HOST, hostDesc, Qmss_Location_HEAD);

    if (Cppi_getReturnPushPolicy (Cppi_DescType_HOST, hostDesc) != Qmss_Location_HEAD)
    {
        System_printf ("Error Core %d : Incorrect return push policy HostDesc : 0x%p\n", coreNum, hostDesc);
        errorCount++;
    }

    Cppi_setReturnPushPolicy (Cppi_DescType_HOST, hostDesc, Qmss_Location_TAIL);

    if (Cppi_getReturnPushPolicy (Cppi_DescType_HOST, hostDesc) != Qmss_Location_TAIL)
    {
        System_printf ("Error Core %d : Incorrect return push policy HostDesc : 0x%p\n", coreNum, hostDesc);
        errorCount++;
    }

    /* Test return queue */
    sQueue.qMgr = 1;
    sQueue.qNum = 3648;
    Cppi_setReturnQueue (Cppi_DescType_HOST, hostDesc, sQueue);
    gQueue = Cppi_getReturnQueue (Cppi_DescType_HOST, hostDesc);

    if (sQueue.qMgr != gQueue.qMgr || sQueue.qNum != gQueue.qNum) 
    {
        System_printf ("Error Core %d : Incorrect return queue HostDesc : 0x%p\n", coreNum, hostDesc);
        errorCount++;
    }

    /* Test original buffer pool index settings */
    Cppi_setOrigBufferpooIndex (Cppi_DescType_HOST, hostDesc, 5);
    if (Cppi_getOrigBufferpooIndex (Cppi_DescType_HOST, hostDesc) != 5)
    {
        System_printf ("Error Core %d : Incorrect original buffer pool index HostDesc : 0x%p\n", coreNum, hostDesc);
        errorCount++;
    }

    Cppi_setOrigBufferpooIndex (Cppi_DescType_HOST, hostDesc, 0xF);
    if (Cppi_getOrigBufferpooIndex (Cppi_DescType_HOST, hostDesc) != 0xF)
    {
        System_printf ("Error Core %d : Incorrect original buffer pool index HostDesc : 0x%p\n", coreNum, hostDesc);
        errorCount++;
    }

    
    /* Test reference count */
    refCount = Cppi_getRefCount (Cppi_DescType_HOST, hostDesc);
    
    System_printf ("Core %d : Original reference count HostDesc : 0x%p ref Count : %d\n", coreNum, hostDesc, refCount);
    
    Cppi_incrementRefCount (Cppi_DescType_HOST, hostDesc);

    newRefCount = Cppi_getRefCount (Cppi_DescType_HOST, hostDesc);
    if (newRefCount != refCount + 1)
    {
        System_printf ("Error Core %d : Incorrect reference count HostDesc : 0x%p ref Count : %d New ref Count : %d\n", coreNum, 
                        hostDesc, refCount, newRefCount);
        errorCount++;
    }

    Cppi_decrementRefCount (Cppi_DescType_HOST, hostDesc);

    newRefCount = Cppi_getRefCount (Cppi_DescType_HOST, hostDesc);
    if (newRefCount != refCount)
    {
        System_printf ("Error Core %d : Incorrect reference count HostDesc : 0x%p ref Count : %d New ref Count : %d\n", coreNum, 
                        hostDesc, refCount, newRefCount);
        errorCount++;
    }

    /* Test PS location */
    Cppi_setPSLocation (Cppi_DescType_HOST, hostDesc, Cppi_PSLoc_PS_IN_SOP);
    if (Cppi_getPSLocation (Cppi_DescType_HOST, hostDesc) != Cppi_PSLoc_PS_IN_SOP)
    {
        System_printf ("Error Core %d : Incorrect PS location HostDesc : 0x%p\n", coreNum, hostDesc);
        errorCount++;
    }

    Cppi_setPSLocation (Cppi_DescType_HOST, hostDesc, Cppi_PSLoc_PS_IN_DESC);
    if (Cppi_getPSLocation (Cppi_DescType_HOST, hostDesc) != Cppi_PSLoc_PS_IN_DESC)
    {
        System_printf ("Error Core %d : Incorrect PS location HostDesc : 0x%p\n", coreNum, hostDesc);
        errorCount++;
    }
    /* Test PS data with optional fields */
    /* Fill in some data */
    dataBuff[0] = 0xAB;
    dataBuff[1] = 0xCD;
    dataBuff[2] = 0xEF;
    dataBuff[3] = 0xDC;

    /* Add PS data */
    Cppi_setPSData (Cppi_DescType_HOST, hostDesc, (UInt8 *) dataBuff, 8);

    dataBuffPtr = 0;
    destLen = 0;
    /* Get PS data */
    if (Cppi_getPSData (Cppi_DescType_HOST, Cppi_PSLoc_PS_IN_DESC, hostDesc, &dataBuffPtr, &destLen) != CPPI_SOK)
    {
        System_printf ("Error Core %d : Getting PS data HostDesc : 0x%p\n", coreNum, hostDesc);
        errorCount++;
    }
    
    for (i=0; i < destLen; i++)
    {
        if (dataBuff[i] != dataBuffPtr[i])
        {
            System_printf ("Error Core %d : In PS data Tx: %02X - Rx: %02X \n", coreNum, dataBuff[i], dataBuffPtr[i]);
            errorCount++;
            break;
        }
    }
    if (Cppi_getPSLen (Cppi_DescType_HOST, hostDesc) != destLen)
    {
        System_printf ("Error Core %d : PS data Len HostDesc : 0x%p\n", coreNum, hostDesc);
        errorCount++;
    }

    /* Test PS data without optional fields */
    hostDesc = (Cppi_Desc *) Qmss_queuePop (freeHostQueHnd);
    
    Cppi_setPSLocation (Cppi_DescType_HOST, hostDesc, Cppi_PSLoc_PS_IN_DESC);
    if (Cppi_getPSLocation (Cppi_DescType_HOST, hostDesc) != Cppi_PSLoc_PS_IN_DESC)
    {
        System_printf ("Error Core %d : Incorrect PS location HostDesc : 0x%p\n", coreNum, hostDesc);
        errorCount++;
    }

        /* Fill in some data */
    dataBuff[0] = 0xAB;
    dataBuff[1] = 0xCD;
    dataBuff[2] = 0xEF;
    dataBuff[3] = 0xDC;

    /* Add PS data */
    Cppi_setPSData (Cppi_DescType_HOST, hostDesc, (UInt8 *) dataBuff, 8);

    dataBuffPtr = 0;
    destLen = 0;
    /* Get PS data */
    if (Cppi_getPSData (Cppi_DescType_HOST, Cppi_PSLoc_PS_IN_DESC, hostDesc, &dataBuffPtr, &destLen) != CPPI_SOK)
    {
        System_printf ("Error Core %d : Getting PS data HostDesc : 0x%p\n", coreNum, hostDesc);
        errorCount++;
    }
    
    for (i=0; i < destLen; i++)
    {
        if (dataBuff[i] != dataBuffPtr[i])
        {
            System_printf ("Error Core %d : In PS data Tx: %02X - Rx: %02X \n", coreNum, dataBuff[i], dataBuffPtr[i]);
            errorCount++;
            break;
        }
    }
    if (Cppi_getPSLen (Cppi_DescType_HOST, hostDesc) != destLen)
    {
        System_printf ("Error Core %d : PS data Len HostDesc : 0x%p\n", coreNum, hostDesc);
        errorCount++;
    }

    /* Set Tags */
    txTag.destTagLo = 128;
    txTag.destTagHi = 6;
    txTag.srcTagLo = 32;
    txTag.srcTagHi = 223;

    Cppi_setTag (Cppi_DescType_HOST, hostDesc, &txTag);

    /*Get Tag */
    rxTag = Cppi_getTag (Cppi_DescType_HOST, hostDesc);

    if (txTag.destTagLo != rxTag.destTagLo)
    {
        System_printf ("Error Core %d : Incorrect destination Low tag Tx %d Rx %d\n", coreNum, txTag.destTagLo, rxTag.destTagLo);
        errorCount++;
    }
    else
        System_printf ("Core %d : Correct destination Low tag\n", coreNum);

    if (txTag.destTagHi != rxTag.destTagHi)
    {
        System_printf ("Error Core %d : Incorrect destination High tag Tx %d Rx %d\n", coreNum, txTag.destTagHi, rxTag.destTagHi);
        errorCount++;
    }
    else
        System_printf ("Core %d : Correct destination High tag\n", coreNum);

    if (txTag.srcTagLo != rxTag.srcTagLo)
    {
        System_printf ("Error Core %d : Incorrect source Low tag Tx %d Rx %d\n", coreNum, txTag.srcTagLo, rxTag.srcTagLo);
        errorCount++;
    }
    else
        System_printf ("Core %d : Correct source Low tag\n", coreNum);

    if (txTag.srcTagHi != rxTag.srcTagHi)
    {
        System_printf ("Error Core %d : Incorrect source High tag Tx %d Rx %d\n", coreNum, txTag.srcTagHi, rxTag.srcTagHi);
        errorCount++;
    }
    else
        System_printf ("Core %d : Correct source High tag\n", coreNum);

    /* Test pop address and size */
    hostDesc = (Cppi_Desc *) Qmss_queuePop (freeHostQueHnd);
    System_printf ("Core %d : Descriptor address : 0x%p\n", coreNum, hostDesc);

    Qmss_queuePush (freeHostQueHnd, (Ptr) hostDesc, SIZE_DATA_BUFFER, SIZE_HOST_DESC, Qmss_Location_HEAD);
    
    Qmss_queuePopDescSize (freeHostQueHnd, (Ptr) &hostDesc1, &hostPktSize);

    if (hostPktSize != SIZE_DATA_BUFFER)
    {
        System_printf ("Error Core %d : Descriptor address : 0x%p Incorrect packet size %d\n", 
                       coreNum, hostDesc1, hostPktSize);
        errorCount++;
    }
    else
        System_printf ("Core %d : Descriptor address : 0x%p of packet size : %d\n", 
                        coreNum, hostDesc1, hostPktSize);

    Qmss_queuePush (freeHostQueHnd, (Ptr) hostDesc1, SIZE_DATA_BUFFER * 4, SIZE_HOST_DESC, Qmss_Location_HEAD);
    
    Qmss_queuePopDescSize (freeHostQueHnd, (Ptr) &hostDesc2, &hostPktSize);
    
    if (hostPktSize != SIZE_DATA_BUFFER * 4)
    {
        System_printf ("Error Core %d : Descriptor address : 0x%p Incorrect packet size %d\n", 
                       coreNum, hostDesc2, hostPktSize);
        errorCount++;
    }
    else
        System_printf ("Core %d : Descriptor address : 0x%p of packet size : %d\n", 
                        coreNum, hostDesc2, hostPktSize);

    System_printf ("Core %d : Descriptor address : 0x%p of packet size : %d\n", 
                        coreNum, hostDesc2, hostPktSize);
    size = QMSS_DESC_SIZE (hostDesc2);
    System_printf ("Core %d : Descriptor address : 0x%p of desc size : %d\n", 
                        coreNum, hostDesc2, size);
    hostDesc2 = (Cppi_Desc *) QMSS_DESC_PTR (hostDesc2);
    System_printf ("Core %d : Descriptor address : 0x%p of packet size : %d\n", 
                        coreNum, hostDesc2, hostPktSize);
    return;
}

Void testMonoDescConfig (Void)
{
    Cppi_Result         result;
    UInt32              i, destLen; 
    Cppi_Desc           *monoDesc;
    Cppi_DescType       descType;
    Qmss_Queue          sQueue, gQueue;
    UInt8               *dataBuffPtr;
    UInt32              timestamp;

    System_printf ("\n~~~~~~~~~~Core %d Testing Monolithic descriptor fields~~~~~~~~\n", coreNum);

    monoDesc = (Cppi_Desc *) Qmss_queuePop (freeMonoQueHnd);
    descType = Cppi_getDescType (monoDesc);
    if (descType != Cppi_DescType_MONOLITHIC)
    {
        System_printf ("Error Core %d : Incorrect descriptor type : %d\n", coreNum, descType);
        errorCount++;
    }

    Cppi_setDescType (monoDesc, Cppi_DescType_HOST);
    descType = Cppi_getDescType (monoDesc);
    if (descType != Cppi_DescType_HOST)
    {
        System_printf ("Error Core %d : Incorrect descriptor type : %d\n", coreNum, descType);
        errorCount++;
    }

    Cppi_setDescType (monoDesc, Cppi_DescType_MONOLITHIC);
    descType = Cppi_getDescType (monoDesc);
    if (descType != Cppi_DescType_MONOLITHIC)
    {
        System_printf ("Error Core %d : Incorrect descriptor type : %d\n", coreNum, descType);
        errorCount++;
    }

    /* Fill in some data */
    for (i = 0; i < SIZE_DATA_BUFFER; i++) 
        dataBuff[i] = i;

    if (Cppi_getDataOffset (Cppi_DescType_MONOLITHIC, monoDesc) != 12)
    {
        System_printf ("Error Core %d : Incorrect data offset MonoDesc : 0x%p\n", 
                        coreNum, SIZE_DATA_BUFFER, monoDesc);
        errorCount++;
    }

    Cppi_setDataOffset (Cppi_DescType_MONOLITHIC, monoDesc, DATA_OFFSET);

    /* Add data buffer */
    Cppi_setData (Cppi_DescType_MONOLITHIC, monoDesc, (UInt8 *) &dataBuff, SIZE_DATA_BUFFER);

    /* Get packet length. Should already be set */
    if ((result = Cppi_getPacketLen (Cppi_DescType_MONOLITHIC, monoDesc)) != SIZE_DATA_BUFFER)
    {
        System_printf ("Error Core %d : Set packet len %d Get packet len %d MonoDesc : 0x%p\n", 
                        coreNum, SIZE_DATA_BUFFER, result, monoDesc);
        errorCount++;
    }

    /* Get data buffer */
    Cppi_getData (Cppi_DescType_MONOLITHIC, monoDesc, &dataBuffPtr, &destLen);
    
    if (dataBuffPtr != ((UInt8 *) monoDesc + DATA_OFFSET))
    {
        System_printf ("Error Core %d : Set data buff 0x%p Get data buff 0x%p MonoDesc : 0x%p\n", 
                        coreNum, l2_global_address ((UInt32) dataBuff), dataBuffPtr, monoDesc);
        errorCount++;
    }

    if (destLen != SIZE_DATA_BUFFER)
    {
        System_printf ("Error Core %d : Set data buff Len %d Get data buff Len %d MonoDesc : 0x%p\n", 
                        coreNum, SIZE_DATA_BUFFER, destLen, monoDesc);
        errorCount++;
    }

    /* Test optional fields */
    Cppi_setTimeStamp (Cppi_DescType_MONOLITHIC, monoDesc, 0x7E3B0C8A);

    result = Cppi_getTimeStamp (Cppi_DescType_MONOLITHIC, monoDesc, &timestamp);
    if (result != CPPI_SOK)
    {
        System_printf ("Error Core %d : Timestamp - EPIB not set MonoDesc : 0x%p\n", coreNum, monoDesc);
        errorCount++;
    }

    /* Set software info */
    Cppi_setSoftwareInfo (Cppi_DescType_MONOLITHIC, monoDesc, dataBuff);

    dataBuffPtr = 0;
    Cppi_getSoftwareInfo (Cppi_DescType_MONOLITHIC, monoDesc, &dataBuffPtr);
    if (result != CPPI_SOK)
    {
        System_printf ("Error Core %d : Software Info - EPIB not set MonoDesc : 0x%p\n", coreNum, monoDesc);
        errorCount++;
    }

    for (i=0; i < 12; i++)
    {
        if (dataBuff[i] != dataBuffPtr[i])
        {
            System_printf ("Error Core %d : In software info set: %02X - get: %02X \n", coreNum, dataBuff[i], dataBuffPtr[i]);
            errorCount++;
            break;
        }
    }

    /* Set software info 0 */
    Cppi_setSoftwareInfo0 (Cppi_DescType_MONOLITHIC, monoDesc, 0xFF);

    result  = Cppi_getSoftwareInfo0 (Cppi_DescType_MONOLITHIC, monoDesc);
    if (result != 0xFF)
    {
        System_printf ("Error Core %d : Software Info0 - Value %d is incorrect in MonoDesc : 0x%p\n", coreNum, result, monoDesc);
        errorCount++;
    }

    /* Set software info 1 */
    Cppi_setSoftwareInfo1 (Cppi_DescType_MONOLITHIC, monoDesc, 0x6389);

    result  = Cppi_getSoftwareInfo1 (Cppi_DescType_MONOLITHIC, monoDesc);
    if (result != 0x6389)
    {
        System_printf ("Error Core %d : Software Info1 - Value %d is incorrect in MonoDesc : 0x%p\n", coreNum, result, monoDesc);
        errorCount++;
    }

    /* Set software info 2 */
    Cppi_setSoftwareInfo2 (Cppi_DescType_MONOLITHIC, monoDesc, 0x1FFFFFFF);

    result  = Cppi_getSoftwareInfo2 (Cppi_DescType_MONOLITHIC, monoDesc);
    if (result != 0x1FFFFFFF)
    {
        System_printf ("Error Core %d : Software Info2 - Value %d is incorrect in MonoDesc : 0x%p\n", coreNum, result, monoDesc);
        errorCount++;
    }

    /* Test return push policy */ 
    Cppi_setReturnPushPolicy (Cppi_DescType_MONOLITHIC, monoDesc, Qmss_Location_HEAD);

    if (Cppi_getReturnPushPolicy (Cppi_DescType_MONOLITHIC, monoDesc) != Qmss_Location_HEAD)
    {
        System_printf ("Error Core %d : Incorrect return push policy monoDesc : 0x%p\n", coreNum, monoDesc);
        errorCount++;
    }

    Cppi_setReturnPushPolicy (Cppi_DescType_MONOLITHIC, monoDesc, Qmss_Location_TAIL);

    if (Cppi_getReturnPushPolicy (Cppi_DescType_MONOLITHIC, monoDesc) != Qmss_Location_TAIL)
    {
        System_printf ("Error Core %d : Incorrect return push policy monoDesc : 0x%p\n", coreNum, monoDesc);
        errorCount++;
    }

    /* Test return queue */
    sQueue.qMgr = 1;
    sQueue.qNum = 3648;
    Cppi_setReturnQueue (Cppi_DescType_MONOLITHIC, monoDesc, sQueue);
    gQueue = Cppi_getReturnQueue (Cppi_DescType_MONOLITHIC, monoDesc);

    if (sQueue.qMgr != gQueue.qMgr || sQueue.qNum != gQueue.qNum) 
    {
        System_printf ("Error Core %d : Incorrect return queue MonoDesc : 0x%p\n", coreNum, monoDesc);
        errorCount++;
    }

    /* Test PS data with optional fields */
    /* Fill in some data */
    dataBuff[0] = 0xAB;
    dataBuff[1] = 0xCD;
    dataBuff[2] = 0xEF;
    dataBuff[3] = 0xDC;

    /* Add PS data */
    Cppi_setPSData (Cppi_DescType_MONOLITHIC, monoDesc, (UInt8 *) dataBuff, 8);

    dataBuffPtr = 0;
    destLen = 0;
    /* Get PS data */
    if (Cppi_getPSData (Cppi_DescType_MONOLITHIC, Cppi_PSLoc_PS_IN_DESC, monoDesc, &dataBuffPtr, &destLen) != CPPI_SOK)
    {
        System_printf ("Error Core %d : Getting PS data MonoDesc : 0x%p\n", coreNum, monoDesc);
        errorCount++;
    }
    
    for (i=0; i < destLen; i++)
    {
        if (dataBuff[i] != dataBuffPtr[i])
        {
            System_printf ("Error Core %d : In PS data Tx: %02X - Rx: %02X \n", coreNum, dataBuff[i], dataBuffPtr[i]);
            errorCount++;
            break;
        }
    }
    if (Cppi_getPSLen (Cppi_DescType_MONOLITHIC, monoDesc) != destLen)
    {
        System_printf ("Error Core %d : PS data Len MonoDesc : 0x%p\n", coreNum, monoDesc);
        errorCount++;
    }

    /* Test PS data without optional fields */
    monoDesc = (Cppi_Desc *) Qmss_queuePop (freeMonoQueHnd);
    
    /* Fill in some data */
    dataBuff[0] = 0xAB;
    dataBuff[1] = 0xCD;
    dataBuff[2] = 0xEF;
    dataBuff[3] = 0xDC;

    /* Add PS data */
    Cppi_setPSData (Cppi_DescType_MONOLITHIC, monoDesc, (UInt8 *) dataBuff, 8);

    dataBuffPtr = 0;
    destLen = 0;
    /* Get PS data */
    if (Cppi_getPSData (Cppi_DescType_MONOLITHIC, Cppi_PSLoc_PS_IN_DESC, monoDesc, &dataBuffPtr, &destLen) != CPPI_SOK)
    {
        System_printf ("Error Core %d : Getting PS data MonoDesc : 0x%p\n", coreNum, monoDesc);
        errorCount++;
    }
    
    for (i=0; i < destLen; i++)
    {
        if (dataBuff[i] != dataBuffPtr[i])
        {
            System_printf ("Error Core %d : In PS data Tx: %02X - Rx: %02X \n", coreNum, dataBuff[i], dataBuffPtr[i]);
            errorCount++;
            break;
        }
    }
    if (Cppi_getPSLen (Cppi_DescType_MONOLITHIC, monoDesc) != destLen)
    {
        System_printf ("Error Core %d : PS data Len MonoDesc : 0x%p\n", coreNum, monoDesc);
        errorCount++;
    }

    return;
}

Void testDescFunctions (Void)
{
    /* Memory region configuration information */
    Qmss_MemRegInfo     memInfo;
    /* Memory region configuration status */
    Qmss_MemRegCfg      memRegStatus;
    /* Descriptor configuration */
    Cppi_DescCfg        descCfg;

    Cppi_Result         result;
    UInt32              i, numAllocated;

    System_printf ("**********Core %d TESTING DESCRIPTOR FUNCTIONS ************\n", coreNum);
    
    System_printf ("~~~~~~~~~~~~~~~Core %d Creating memory regions~~~~~~~~~~~~~\n", coreNum);

    memset ((Void *) &hostDesc, 0, SIZE_HOST_DESC * NUM_HOST_DESC);
    memset ((Void *) &monolithicDesc, 0, SIZE_MONOLITHIC_DESC * NUM_MONOLITHIC_DESC);

    /* Setup memory region for host descriptors */
    memInfo.descBase = (UInt32 *) l2_global_address ((UInt32)hostDesc);
    memInfo.descSize = SIZE_HOST_DESC;
    memInfo.descNum = NUM_HOST_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++;
    }
    else
        System_printf ("Core %d : Memory region %d inserted\n", coreNum, result);


    /* Setup memory region for monolithic descriptors */
    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++;
    }
    else
        System_printf ("Core %d : Memory region %d inserted\n", coreNum, result);

    System_printf ("~~~~~~~~~~Core %d Memory regions creation passed~~~~~~~~~~~\n", coreNum);

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

    System_printf ("\n~~~~~~~~~~~~~~~Core %d Initializing descriptors~~~~~~~~~~~~~~~\n", coreNum);
    
    /* Setup the descriptors */
    descCfg.memRegion = Qmss_MemRegion_MEMORY_REGION0;
    descCfg.descNum = NUM_HOST_DESC;
    descCfg.destQueueNum = QMSS_PARAM_NOT_SPECIFIED;
    descCfg.queueType = Qmss_QueueType_GENERAL_PURPOSE_QUEUE;
    descCfg.initDesc = Cppi_InitDesc_INIT_DESCRIPTOR;
    descCfg.descType = Cppi_DescType_HOST;
    descCfg.epibPresent = Cppi_EPIB_NO_EPIB_PRESENT;
    /* Descriptor should be recycled back to freeQue allocated since destQueueNum is < 0 */
    descCfg.returnQueue.qMgr = QMSS_PARAM_NOT_SPECIFIED;
    descCfg.returnQueue.qNum = QMSS_PARAM_NOT_SPECIFIED;
    descCfg.returnPushPolicy = Qmss_Location_TAIL;
    descCfg.cfg.host.returnPolicy = Cppi_ReturnPolicy_RETURN_ENTIRE_PACKET;
    descCfg.cfg.host.psLocation = Cppi_PSLoc_PS_IN_DESC;
    
    /* Initialize the descriptors and push to host free Queue */
    if ((freeHostQueHnd = Cppi_initDescriptor (&descCfg, &numAllocated)) < 0)
    {
        System_printf ("Error Core %d : Initializing host descriptor error code: %d \n", coreNum, freeHostQueHnd);
        errorCount++;
        return;
    }
    else
        System_printf ("Core %d : Number of host 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_REGION1;
    descCfg.descNum = NUM_MONOLITHIC_DESC;
    descCfg.destQueueNum = QMSS_PARAM_NOT_SPECIFIED;
    descCfg.queueType = Qmss_QueueType_STARVATION_COUNTER_QUEUE;
    descCfg.initDesc = Cppi_InitDesc_INIT_DESCRIPTOR;
    descCfg.descType = Cppi_DescType_MONOLITHIC;
    descCfg.epibPresent = Cppi_EPIB_NO_EPIB_PRESENT;
    descCfg.cfg.mono.dataOffset = 12;
    
    /* Initialize the descriptors and push to monolithic free Queue */
    if ((freeMonoQueHnd = Cppi_initDescriptor (&descCfg, &numAllocated)) < 0)
    {
        System_printf ("Error Core %d : Initializing monolithic descriptor error code: %d \n", coreNum, freeMonoQueHnd);
        errorCount++;
        return;
    }
    else
        System_printf ("Core %d : Number of monolithic descriptors requested : %d. Number of descriptors allocated : %d \n", 
            coreNum, descCfg.descNum, numAllocated);

    /* Test configuring host descriptor fields */
    testHostDescConfig ();

    /* Test configuring monolithic descriptor fields */
    testMonoDescConfig ();
    return;
}

/**
 *  @b Description
 *  @n Tests functionality in cppi_heap.c
 *
 *  Opens all channels and flows for this device, then closes them to check for leaks
 *
 *  @retval
 *      Not Applicable.
 */
void grab_all_chan_flows(void)
{
    int               i, chHndIdx, flowHndIdx, channel, flow;
    uint32_t          totalFlows = 0, totalChannels = 0;
    Cppi_Handle       cppiHnd[CPPI_MAX_CPDMA];
    Cppi_CpDmaInitCfg cpdmaCfg;
    UInt8             isAllocated;
    Cppi_TxChInitCfg  TxChCfg;
    Cppi_RxChInitCfg  RxChCfg;
    Cppi_Result       result;
    Cppi_FlowHnd     *flowHnds;
    Cppi_ChHnd       *chHnds;
    Cppi_RxFlowCfg    rxFlowCfg;

    /* Count the number of flows and channels */
    for (i = 0; i < CPPI_MAX_CPDMA; i++)
    {
        totalFlows += cppiGblCfgParams[i].maxRxFlow;
        totalChannels += cppiGblCfgParams[i].maxRxCh +
                             cppiGblCfgParams[i].maxTxCh;
    }

    /* Allocate arrays of flows and channels */
    flowHnds = Cppi_osalMalloc (totalFlows * sizeof(Cppi_FlowHnd));
    chHnds   = Cppi_osalMalloc (totalChannels * sizeof(Cppi_ChHnd));

    if (! flowHnds || ! chHnds)
    {
        System_printf ("Error Core %d : failed to allocate handle arrays\n", coreNum);
        errorCount ++;
        return;
    }

    memset (flowHnds, 0, totalFlows * sizeof(Cppi_FlowHnd));
    memset (chHnds, 0, totalChannels * sizeof(Cppi_ChHnd));

    /* Set up the TX channels */
    memset (&TxChCfg, 0, sizeof(TxChCfg));
    TxChCfg.channelNum = CPPI_PARAM_NOT_SPECIFIED;
    TxChCfg.priority = 2;
    TxChCfg.filterEPIB = 1;
    TxChCfg.filterPS = 1;
    TxChCfg.aifMonoMode = 1;
    TxChCfg.txEnable = Cppi_ChState_CHANNEL_ENABLE;
    
    /* Set up CPDMA configuration */
    memset ((Void *) &cpdmaCfg, 0, sizeof (Cppi_CpDmaInitCfg));
    cpdmaCfg.writeFifoDepth = 32;
    cpdmaCfg.timeoutCount = 0x7F;
    cpdmaCfg.qm0BaseAddress = 0x34020000;

    /* Set up the RX channels */
    memset (&RxChCfg, 0, sizeof(RxChCfg));
    RxChCfg.channelNum = CPPI_PARAM_NOT_SPECIFIED;
    RxChCfg.rxEnable = Cppi_ChState_CHANNEL_ENABLE;

    /* Set up the flow */
    memset ((Void *) &rxFlowCfg, 0, sizeof (Cppi_RxFlowCfg));
    rxFlowCfg.flowIdNum = CPPI_PARAM_NOT_SPECIFIED;
    rxFlowCfg.rx_dest_qnum = 100;
    rxFlowCfg.rx_dest_qmgr = 0;
    rxFlowCfg.rx_sop_offset= 16;
    rxFlowCfg.rx_ps_location = Cppi_PSLoc_PS_IN_SOP;
    rxFlowCfg.rx_desc_type = Cppi_DescType_HOST;
    rxFlowCfg.rx_error_handling = 1;
    rxFlowCfg.rx_psinfo_present = 1;
    rxFlowCfg.rx_einfo_present = 1;
    rxFlowCfg.rx_dest_tag_lo = 0xf1;
    rxFlowCfg.rx_dest_tag_hi = 0xf4;
    rxFlowCfg.rx_src_tag_lo = 0x60;
    rxFlowCfg.rx_src_tag_hi = 0x48;
    rxFlowCfg.rx_size_thresh0_en = 1;
    rxFlowCfg.rx_size_thresh1_en = 1;
    rxFlowCfg.rx_size_thresh2_en = 0;
    rxFlowCfg.rx_dest_tag_lo_sel = 2;
    rxFlowCfg.rx_dest_tag_hi_sel = 3;
    rxFlowCfg.rx_src_tag_lo_sel = 4;
    rxFlowCfg.rx_src_tag_hi_sel = 5;
    rxFlowCfg.rx_fdq1_qnum = 1000;
    rxFlowCfg.rx_fdq1_qmgr = 0;
    rxFlowCfg.rx_fdq0_sz0_qnum = 2687;
    rxFlowCfg.rx_fdq0_sz0_qmgr = 0;
    rxFlowCfg.rx_fdq3_qnum = 5000;
    rxFlowCfg.rx_fdq3_qmgr = 1;
    rxFlowCfg.rx_fdq2_qnum = 7800;
    rxFlowCfg.rx_fdq2_qmgr = 1;
    rxFlowCfg.rx_size_thresh1 = 512;
    rxFlowCfg.rx_size_thresh0 = 256;
    rxFlowCfg.rx_fdq0_sz1_qnum = 1;
    rxFlowCfg.rx_fdq0_sz1_qmgr = 0;
    rxFlowCfg.rx_size_thresh2 = 1024;
    rxFlowCfg.rx_fdq0_sz3_qnum = 721;
    rxFlowCfg.rx_fdq0_sz3_qmgr= 0;
    rxFlowCfg.rx_fdq0_sz2_qnum = 32;
    rxFlowCfg.rx_fdq0_sz2_qmgr = 0;

    chHndIdx = 0;
    flowHndIdx = 0;
    for (i = 0; i < CPPI_MAX_CPDMA; i++)
    {
        /* Open QMSS CPDMA */
        cpdmaCfg.dmaNum = (Cppi_CpDma)i;
        if ( (cppiHnd[i] = (Cppi_Handle) Cppi_open (&cpdmaCfg)) == NULL)
        {
            System_printf ("Error Core %d : Initializing CPDMA %d\n", coreNum, cpdmaCfg.dmaNum);
            errorCount++;
        }
        else
        {
            /* Open the TX channels */
            for (channel = 0; channel < cppiGblCfgParams[i].maxTxCh; channel++)
            {
                /* Open Channel */
                if ((chHnds[chHndIdx] = (Cppi_ChHnd) Cppi_txChannelOpen (cppiHnd[i], &TxChCfg, &isAllocated)) == NULL)
                {
                    System_printf ("Error Core %d : tx ch open %d\n", coreNum, channel);
                    errorCount++;
                    break;
                }
                chHndIdx++;
            }

            /* Open the RX channels */
            for (channel = 0; channel < cppiGblCfgParams[i].maxRxCh; channel++)
            {
                /* Open Channel */
                if ((chHnds[chHndIdx] = (Cppi_ChHnd) Cppi_rxChannelOpen (cppiHnd[i], &RxChCfg, &isAllocated)) == NULL)
                {
                    System_printf ("Error Core %d : rx ch open %d\n", coreNum, channel);
                    errorCount++;
                    break;
                }
                chHndIdx++;
            }

            /* Open the flows */
            for (flow = 0; flow < cppiGblCfgParams[i].maxRxFlow; flow++)
            {
                if ((flowHnds[flowHndIdx] = (Cppi_FlowHnd) Cppi_configureRxFlow (cppiHnd[i], &rxFlowCfg, &isAllocated)) == NULL)
                {
                    System_printf ("Error Core %d : flow open %d\n", coreNum, flow);
                    errorCount++;
                    break;
                }
                flowHndIdx++;
            }
        }
    }
    /* At this point, flowHndIdx and chHndIdx have the total number of flows and channels */
    /* Close the channels */
    for (channel = 0; channel < chHndIdx; channel++)
    {
        if (chHnds[channel] && ((result = Cppi_channelClose (chHnds[channel])) < 0))
        {
            System_printf ("Error Core %d : ch close %d\n", coreNum, channel);
            errorCount++;
            break;
        }
    }

    /* Close the flows */
    for (flow = 0; flow < flowHndIdx; flow++)
    {
        if (flowHnds[flow] && ((result = Cppi_closeRxFlow (flowHnds[flow])) < 0))
        {
            System_printf ("Error Core %d : flow close %d\n", coreNum, flow);
            errorCount++;
            break;
        }
    }

    /* Close the DMAs */
    for (i = 0; i < CPPI_MAX_CPDMA; i++)
    {
        if (cppiHnd[i] && (result = Cppi_close (cppiHnd[i])) != CPPI_SOK)
        {
            System_printf ("Error Core %d : Closing CPPI CPDMA error code : %d\n", coreNum, result);
            errorCount++;
        }
    }

    /* Free allocated memory */
    Cppi_osalFree (flowHnds, totalFlows * sizeof(void *));
    Cppi_osalFree (chHnds, totalChannels * sizeof(void *));
}

/**
 *  @b Description
 *  @n Tests functionality in cppi_heap.c
 *
 *  First, sets up with a "static" heap then opens all channels and flows to validate
 *  that the Cppi_getHeapReq returns the correct size.
 *
 *  Second, sets up with "dynamic" allocation, then opens all channels and flows
 *  and checks for leaks.
 *
 *  @retval
 *      Not Applicable.
 */
void test_internal_heap (void)
{
    Cppi_InitCfg initCfg;
    Cppi_Result  result;
    uint32_t        reqSize, reqSizePad;
    /* Check for memory leak */
    extern uint32_t cppiMallocCounter, cppiFreeCounter;
    uint32_t        saveMallocCounter;

    memset (&initCfg, 0, sizeof(initCfg));

    /* Get size of static heap */
    if ( (result = Cppi_getHeapReq (cppiGblCfgParams, &reqSize)) != CPPI_SOK)
    {
        System_printf ("Error Core %d : Get heap requirement error : %d\n", coreNum, result);
        errorCount ++;
        return;
    }

    /* Allocate one heap block to be used.  Add 2 cache lines of pad for beginning and end */
    initCfg.heapParams.heapAlignPow2 = 7; /* 128 bytes */
    reqSizePad = (2 << initCfg.heapParams.heapAlignPow2) + reqSize;
    initCfg.heapParams.staticHeapSize = reqSizePad;
    initCfg.heapParams.dynamicHeapBlockSize = 1024;
    if ( !(initCfg.heapParams.staticHeapBase = Cppi_osalMalloc (reqSizePad)))
    {
        System_printf ("Error Core %d : failed to allocate heap\n", coreNum);
        errorCount ++;
        return;
    }

    /* Save the malloc counter so we can make sure we didn't overflow */
    saveMallocCounter = cppiMallocCounter;

    /* Initialize the LLD with an internal static heap */
    if ( (result = Cppi_initCfg (cppiGblCfgParams, &initCfg)) != CPPI_SOK)
    {
        System_printf ("Error Core %d : Initializing CPPI LLD error code : %d\n", coreNum, result);
        errorCount ++;
        return;
    }

    /* Try allocating all the configured channels and flows */
    grab_all_chan_flows ();

    /* Make sure no overflow */
    if (cppiMallocCounter != (saveMallocCounter + 2))
    {
        System_printf ("Core %d : static heap overflowed\n", coreNum);
        errorCount ++;
    }

    /* Free memory */
    if ((result = Cppi_exit ()) != CPPI_SOK)
    {
        System_printf ("Error Core %d : Exiting CPPI error code : %d\n", coreNum, result);
        errorCount++;
    }
    Cppi_osalFree (initCfg.heapParams.staticHeapBase, reqSizePad);

    /* Check for leak */
    if (cppiMallocCounter != cppiFreeCounter)
    {
        System_printf ("Core %d : alloc mismatch : mallocs %d != frees %d\n",
                       coreNum, cppiMallocCounter, cppiFreeCounter);
        errorCount ++;
    }

    if (errorCount)
    {
        return;
    }
    System_printf ("Repeating test with dynamic memory\n");

    /* Repeat the test using dynamic memory */
    saveMallocCounter = cppiMallocCounter;
    if ( (result = Cppi_init (cppiGblCfgParams) != CPPI_SOK))
    {
        System_printf ("Error Core %d : Initializing CPPI LLD error code : %d\n", coreNum, result);
        errorCount ++;
        return;
    }

    /* Try allocating all the configured channels and flows */
    grab_all_chan_flows ();

    if ((result = Cppi_exit ()) != CPPI_SOK)
    {
        System_printf ("Error Core %d : Exiting CPPI error code : %d\n", coreNum, result);
        errorCount++;
    }

    /* Check for leak */
    if (cppiMallocCounter != cppiFreeCounter)
    {
        System_printf ("Core %d : alloc mismatch : mallocs %d != frees %d\n",
                       coreNum, cppiMallocCounter, cppiFreeCounter);
        errorCount ++;
    }
}

/**
 *  @b Description
 *  @n  
 *      Entry point for the test code.
 *      This is unit test code to test the following 
 *
 *      It performs the following
 *          - Initializes the Queue Manager low level driver.
 *          - Initializes the CPPI low level driver.
 *          - Opens the SRIO CPDMA
 *          - Test Rx channel allocation and freeing 
 *          - Test Tx channel allocation and freeing 
 *          - Test Rx flow allocation and freeing 
 *          - Test descriptor manipulation functions
 *          - Closes CPPI CPDMA
 *          - Deinitializes CPPI low level driver
 *          - Re-initializes and tests static heap and dynamic heap
 *
 *  @retval
 *      Not Applicable.
 */
Void main (Void)
{
    /* QMSS configuration */
    Qmss_InitCfg        qmssInitConfig;
    /* CPPI CPDMA configuration */
    Cppi_CpDmaInitCfg   cpdmaCfg;

    Cppi_Result         result;
    Cppi_Handle         cppiHnd;
    UInt32              totalErrorCount = 0;

    /* Check for memory leak */
    extern uint32_t     cppiMallocCounter, cppiFreeCounter;

    System_printf ("**************************************************\n");
    System_printf ("***************** CPPI LLD Testing ***************\n");
    System_printf ("**************************************************\n");

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

    /* Initialize the heap in shared memory for CPPI data structures */ 
    cppiHeapInit ();

    System_printf ("*******Test running on Core %d *******************\n", coreNum);
    memset ((Void *) &qmssInitConfig, 0, sizeof (Qmss_InitCfg));
    memset ((Void *) &linkingRAM0, 0, sizeof (linkingRAM0));

    /* Set up the linking RAM. Use the internal Linking RAM for host descriptors and external 
     * linking RAM for monolithic descriptors. 
     * LLD will configure the internal linking RAM address and default size if a value of zero is specified.
     *
     */

#ifdef INTERNAL_LINKING_RAM 
    qmssInitConfig.linkingRAM0Base = 0;
    qmssInitConfig.linkingRAM0Size = NUM_HOST_DESC + NUM_MONOLITHIC_DESC;
    qmssInitConfig.linkingRAM1Base = 0;
    qmssInitConfig.maxDescNum      = NUM_HOST_DESC + NUM_MONOLITHIC_DESC;
#else
    qmssInitConfig.linkingRAM0Base = l2_global_address ((UInt32) linkingRAM0);
    qmssInitConfig.linkingRAM0Size = NUM_HOST_DESC + NUM_MONOLITHIC_DESC;
    qmssInitConfig.linkingRAM1Base = 0;
    qmssInitConfig.maxDescNum      = NUM_HOST_DESC + NUM_MONOLITHIC_DESC;
#endif    

#ifdef xdc_target__bigEndian
    qmssInitConfig.pdspFirmware[0].pdspId = Qmss_PdspId_PDSP1;
    qmssInitConfig.pdspFirmware[0].firmware = &acc48_be;
    qmssInitConfig.pdspFirmware[0].size = sizeof (acc48_be);
#else
    qmssInitConfig.pdspFirmware[0].pdspId = Qmss_PdspId_PDSP1;
    qmssInitConfig.pdspFirmware[0].firmware = &acc48_le;
    qmssInitConfig.pdspFirmware[0].size = sizeof (acc48_le);
#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);
        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);
    }
 
    /* Initialize CPPI LLD */
    result = Cppi_init (cppiGblCfgParams);
    if (result != CPPI_SOK)
    {
        System_printf ("Error Core %d : Initializing CPPI LLD error code : %d\n", coreNum, result);
        return;
    }

    /* Set up QMSS CPDMA configuration */
    memset ((Void *) &cpdmaCfg, 0, sizeof (Cppi_CpDmaInitCfg));

    cpdmaCfg.dmaNum = Cppi_CpDma_QMSS_CPDMA;
    cpdmaCfg.writeFifoDepth = 32;
    cpdmaCfg.timeoutCount = 0x7F;
    cpdmaCfg.qm0BaseAddress = 0x34020000;

    /* Open QMSS CPDMA */
    cppiHnd = (Cppi_Handle) Cppi_open (&cpdmaCfg);
    if (cppiHnd == NULL)
    {
        System_printf ("Error Core %d : Initializing SRIO CPPI CPDMA %d\n", coreNum, cpdmaCfg.dmaNum);
        return;
    }

    /* Test CPDMA global configuration */
    testCpdmaGlobalConfig (cppiHnd);

    /* Test Rx Channels configuration */
    testRxChannelConfig (cppiHnd);

    if (errorCount == 0)
        System_printf ("\nCore %d : Receive Channel Configuration tests Passed\n", coreNum);
    else
        System_printf ("Error Core %d : Receive Channel Configuration tests failed %d\n", coreNum, errorCount);

    totalErrorCount += errorCount;
    errorCount = 0;
#ifdef RX_CH_ALLOCATION
    /* Test Rx Channels Allocation and free */
    testRxChannelAllocate (cppiHnd);

    if (errorCount == 0)
        System_printf ("\nCore %d : Receive Channel Allocation tests Passed\n", coreNum);
    else
        System_printf ("Error Core %d : Receive Channel Allocation %d tests failed\n", coreNum, errorCount);
    
    totalErrorCount += errorCount;
    errorCount = 0;
#endif
    /* Test Tx Channels configuration */
    testTxChannelConfig (cppiHnd);

    if (errorCount == 0)
        System_printf ("\nCore %d : Transmit Channel Configuration tests Passed\n", coreNum);
    else
        System_printf ("Error Core %d : Transmit Channel Configuration %d tests failed\n", coreNum, errorCount);
    
    totalErrorCount += errorCount;
    errorCount = 0;
#ifdef TX_CH_ALLOCATION
    /* Test Tx Channels Allocation and free */
    testTxChannelAllocate (cppiHnd);

    if (errorCount == 0)
        System_printf ("\nCore %d : Transmit Channel Allocation tests Passed %d\n", coreNum);
    else
        System_printf ("Error Core %d : Transmit Channel Allocation tests failed %d\n", coreNum, errorCount);
    
    totalErrorCount += errorCount;
    errorCount = 0;
#endif
    /* Test Rx flow configuration */
    testRxFlowConfig (cppiHnd);
    if (errorCount == 0)
        System_printf ("\nCore %d : Receive Flow Configuration tests Passed\n", coreNum);
    else
        System_printf ("Error Core %d : Receive Flow Configuration %d tests failed\n", coreNum, errorCount);

    totalErrorCount += errorCount;
    errorCount = 0;
#ifdef RX_FLOW_ALLOCATION
    /* Test Rx Flows Allocation and free */
    testRxFlowAllocate (cppiHnd);

    if (errorCount == 0)
        System_printf ("\nCore %d : Receive Flow Allocation tests Passed\n", coreNum);
    else
        System_printf ("Error Core %d : Receive Flow Allocation %d tests failed\n", coreNum, errorCount);

    totalErrorCount += errorCount;
    errorCount = 0;
#endif
    /* Test CPPI descriptor functions */
    testDescFunctions();

    if (errorCount == 0)
        System_printf ("\nCore %d : CPPI Descriptor Functions tests Passed\n", coreNum);
    else
        System_printf ("Error Core %d : CPPI Descriptor Functions %d tests failed\n", coreNum, errorCount);

    totalErrorCount += errorCount;
    errorCount = 0;

    /* Test data transfer using Host descriptor */
    testHostDataTransfer();

    if (errorCount == 0)
        System_printf ("\nCore %d : Data transfer tests using host descriptor Passed\n", coreNum);
    else
        System_printf ("Error Core %d : Data transfer tests using host descriptor %d tests failed\n", coreNum, errorCount);

    totalErrorCount += errorCount;
    errorCount = 0;

    /* Test data transfer using Monolithic descriptor*/
    testMonoDataTransfer();

    if (errorCount == 0)
        System_printf ("\nCore %d : Data transfer tests using monolithic descriptor Passed\n", coreNum);
    else
        System_printf ("Error Core %d : Data transfer tests using monolithic descriptor %d tests failed\n", coreNum, errorCount);

    totalErrorCount += errorCount;
    errorCount = 0;

    /* Close CPPI CPDMA instance */
    if ((result = Cppi_close (cppiHnd)) != CPPI_SOK)
    {
        System_printf ("Error Core %d : Closing CPPI CPDMA error code : %d\n", coreNum, result);
        errorCount++;
    }
    else 
        System_printf ("Core %d : CPPI CPDMA closed successfully\n", coreNum);

    /* Deinitialize CPPI LLD */
    if ((result = Cppi_exit ()) != CPPI_SOK)
    {
        System_printf ("Error Core %d : Exiting CPPI error code : %d\n", coreNum, result);
        errorCount++;
    }
    else 
        System_printf ("Core %d : CPPI exit successful\n", coreNum);
    
    totalErrorCount += errorCount;

    /* At this point everything should be free */
    if (cppiMallocCounter != cppiFreeCounter)
    {
        System_printf ("Core %d : alloc mismatch : mallocs %d != frees %d\n",
                       coreNum, cppiMallocCounter, cppiFreeCounter);
        totalErrorCount ++;
    }

    /* Now test internal heap explicitly (it has been used to this point passively) */
    if (! totalErrorCount)
    {
        System_printf ("Core %d : testing internal heap\n", coreNum);

        test_internal_heap();
        totalErrorCount += errorCount;
    }

    System_printf ("*******************************************************\n");
    System_printf ("***************** CPPI LLD Testing DONE ***************\n");
    System_printf ("*******************************************************\n");

    if (totalErrorCount == 0)
        System_printf ("\nCPPI LLD ALL TESTS PASSED\n");
    else
        System_printf ("\nCPPI LLD %d TESTS FAILED\n", totalErrorCount);

}

