/**
 * @file test_common_utils.c
 * @brief Contains utility APIs used by icss_emac unit tests. 
 *
 */

/* Copyright (C) {2016} Texas Instruments Incorporated - http://www.ti.com/ 
*
*   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.
*
*/
/* ========================================================================== */
/*                             Include Files                                  */
/* ========================================================================== */
#include <stdlib.h>
#include <assert.h>

#ifdef __LINUX_USER_SPACE
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <semaphore.h>
#include "mmap_helper.h"
#else
#include <ti/sysbios/knl/Task.h>

#ifdef _TMS320C6X
#include <ti/sysbios/family/c64p/Hwi.h>
#include <ti/sysbios/family/c64p/EventCombiner.h>
#endif

#include <xdc/std.h>
#endif

#include <ti/csl/hw_types.h>
#include <ti/csl/cslr_device.h>
#include <ti/csl/src/ip/icss/V1/cslr_icss_iep.h>

#ifndef __LINUX_USER_SPACE
#include <ti/drv/uart/UART_stdio.h>
#endif

#include <ti/drv/icss_emac/icss_emacDrv.h>
#include <ti/drv/icss_emac/test/src/test_common_utils.h>

#ifdef SOC_AM335x
#include <ti/starterware/include/hw/soc_am335x.h>
#endif

#ifdef SOC_AM437x
#include <ti/starterware/include/hw/hw_control_am43xx.h>
#include <ti/starterware/include/hw/am437x.h>
#endif

extern ICSS_EmacBaseAddrCfgParams icss_EmacBaseAddrCfgParams[];

extern uint32_t ICSS_EMAC_testPgVersion;
extern uint8_t ICSS_EMAC_testEvmType;

#ifdef __LINUX_USER_SPACE
static inline void linux_sleep_ms(int ms) {
	struct timespec ts;
	ts.tv_sec = (ms)/1000; \
    ts.tv_nsec = (ms*1000000)%1000000000; \
    nanosleep(&ts, NULL);
}
#define SLEEP(t) linux_sleep_ms(t)
#define PRINT printf

#else
#define SLEEP Task_sleep
#define PRINT UART_printf
#endif

/* total number of packets received on all interfaces being tested, cummulative account */
uint32_t ICSS_EMAC_testTotalPktRcvd = 0;

#ifdef __LINUX_USER_SPACE
#include <ti/drv/pruss/soc/pruicss_v1.h>
tprussdrv *pruss_drv_handle;
tprussdrv *pruss_drv_handle2;
PRUICSS_HwAttrs linux_prussHwAttrs[PRUICCSS_INSTANCE_MAX-1];
PRUICSS_V1_Object linux_prussObjects[PRUICCSS_INSTANCE_MAX-1];
PRUICSS_Config linux_pruss_config[PRUICCSS_INSTANCE_MAX] = {
		{
			&(linux_prussObjects[0]),
			&(linux_prussHwAttrs[0])
		},
		{
			&(linux_prussObjects[1]),
			&(linux_prussHwAttrs[1])
		},
		{NULL, NULL}
	};
#endif

ICSS_EmacHandle ICSS_EMAC_testHandle = NULL; 
ICSS_EmacHandle ICSS_EMAC_testHandle1 = NULL;
ICSS_EmacHandle ICSS_EMAC_testHandle2 = NULL;
ICSS_EmacHandle ICSS_EMAC_testHandle3 = NULL;


/*    TTS Global Variables    */
uint8_t    ICSS_EMAC_testTtsModePort1 = 0;
uint8_t    ICSS_EMAC_testTtsModePort2 = 0;
uint8_t    ICSS_EMAC_testTtsStartPort1 = 0;
uint8_t    ICSS_EMAC_testTtsStartPort2 = 0;

uint8_t ICSS_EMAC_testTtsRecvPktPort1[ICSS_EMAC_MAXMTU] = {0};
uint8_t ICSS_EMAC_testTtsRecvPktPort2[ICSS_EMAC_MAXMTU] = {0};


uint32_t ICSS_EMAC_testRecv_Q1PktCntPort1 = 0;
uint32_t ICSS_EMAC_testRecv_Q2PktCntPort1 = 0;
uint32_t ICSS_EMAC_testRecv_Q1PktCntPort2 = 0;
uint32_t ICSS_EMAC_testRecv_Q2PktCntPort2 = 0;


uint32_t ICSS_EMAC_testPacketRcvdPort0 = 0;
uint32_t ICSS_EMAC_testPacketRcvdPort1 = 0;
uint32_t ICSS_EMAC_testPacketRcvdPort2 = 0;
uint32_t ICSS_EMAC_testPacketRcvdPort3 = 0;


uint32_t ICSS_EMAC_testLinkIsrPru1Eth0 = 0;
uint32_t ICSS_EMAC_testLinkIsrPru1Eth1 = 0;
uint32_t ICSS_EMAC_testLinkIsrPru2Eth0 = 0;
uint32_t ICSS_EMAC_testLinkIsrPru2Eth1 = 0;


SemaphoreP_Handle    ICSS_EMAC_testTtsP1TxSem = NULL;
SemaphoreP_Handle    ICSS_EMAC_testTtsP2TxSem = NULL;
SemaphoreP_Handle    ICSS_EMAC_testTtsP1TimeSem = NULL;
SemaphoreP_Handle    ICSS_EMAC_testTtsP2TimeSem = NULL;
SemaphoreP_Handle    ICSS_EMAC_testTtsP1ResultSem = NULL;
SemaphoreP_Handle    ICSS_EMAC_testTtsP2ResultSem = NULL;


uint8_t ICSS_EMAC_testLclMac[6] = {0x01, 0xb2, 0xc1, 0xd4, 0xe4, 0xff};
uint8_t ICSS_EMAC_testLclMac1[6]= {0x01, 0xb3, 0xc2, 0xd4, 0xe4, 0xff};;
uint8_t ICSS_EMAC_testLclMac2[6] = {0x01, 0xb4, 0xc3, 0xdd, 0xee, 0xff};
uint8_t ICSS_EMAC_testLclMac3[6] = {0x01, 0xb5, 0xc4, 0xd4, 0xe4, 0xff};


uint8_t ICSS_EMAC_testPacketArrayInstance1[256] = {0};
uint8_t ICSS_EMAC_testPacketArrayInstance1_1[256] = {0};
uint8_t ICSS_EMAC_testPacketArrayInstance2[256] = {0};
uint8_t ICSS_EMAC_testPacketArrayInstance2_1[256] = {0};

uint32_t ICSS_EMAC_testPacketTxCompletePort0 = 0;
uint32_t ICSS_EMAC_testPacketTxCompletePort1 = 0;
uint32_t ICSS_EMAC_testPacketTxCompletePort2 = 0;
uint32_t ICSS_EMAC_testPacketTxCompletePort3 = 0;

/* DO NOT CHANGE ICSS_EMAC_testPkt UNLESS ICSS_EMAC_ICSS_EMAC_TEST_PKT_SIZE IS UPDATED */
uint8_t ICSS_EMAC_testPkt[] = {
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* broadcast mac */
    0x01, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
    0x08, 0x06, 0x00, 0x01,
    0x08, 0x00, 0x06, 0x04, 0x00,0x01,
    0x01, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
    0xc0, 0xa8, 0x01, 0x16,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0xc0, 0xa8,0x01, 0x02
};
/* DO NOT CHANGE ICSS_EMAC_testArpPktPort1 size UNLESS ICSS_EMAC_TEST_ARP_PKT_SIZE_PORT1 IS UPDATED */
uint8_t ICSS_EMAC_testArpPktPort1[ICSS_EMAC_TEST_ARP_PKT_SIZE_PORT1] = {
    0xc4, 0xbe, 0x84, 0xcc, 0xff, 0x1f,
    0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
    0x81, 0x00, 0xe0, 0x00,
    0x08, 0x06, 0x00, 0x01,
    0x08, 0x00, 0x06, 0x04, 0x00, 0x01,
    0x01, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
    0xc0, 0xa8, 0x01, 0x16,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

/* DO NOT CHANGE ICSS_EMAC_testArpPktPort2 size UNLESS ICSS_EMAC_TEST_ARP_PKT_SIZE_PORT2 IS UPDATED */
uint8_t ICSS_EMAC_testArpPktPort2[ICSS_EMAC_TEST_ARP_PKT_SIZE_PORT2] = {
    0xc4, 0xbe, 0x84, 0xcc, 0xff, 0x1f,
    0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
    0x81, 0x00, 0xe0, 0x00,
    0x08, 0x06, 0x00, 0x01,
    0x08, 0x00, 0x06, 0x04, 0x00, 0x01,
    0x01, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
    0xc0, 0xa8, 0x01, 0x16,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
/* DO NOT CHANGE ICSS_EMAC_testUdpPktPort1 size UNLESS ICSS_EMAC_TEST_UDP_PKT_SIZE_PORT1 IS UPDATED */
uint8_t ICSS_EMAC_testUdpPktPort1[ICSS_EMAC_TEST_UDP_PKT_SIZE_PORT1] = {
    0xc4, 0xbe, 0x84, 0xcc, 0xff, 0x1f,
    0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
    0x81, 0x00, 0x20, 0x00,
    0x08, 0x00, 0x45, 0x00,
    0x00, 0x2E, 0x00, 0x00, 0x40, 0x00,
    0x40, 0x11, 0xB7, 0x56, 0xC0, 0xA8,
    0x01, 0x16, 0xC0, 0xA8,
    0x01, 0x02, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00
};

/* DO NOT CHANGE ICSS_EMAC_testUdpPktPort2 size UNLESS ICSS_EMAC_TEST_UDP_PKT_SIZE_PORT2 IS UPDATED */
uint8_t ICSS_EMAC_testUdpPktPort2[ICSS_EMAC_TEST_UDP_PKT_SIZE_PORT2] = {
    0xc4, 0xbe, 0x84, 0xcc, 0xff, 0x1f,
    0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
    0x81, 0x00, 0x20, 0x00,
    0x08, 0x00, 0x45, 0x00,
    0x00, 0x2E, 0x00, 0x00, 0x40, 0x00,
    0x40, 0x11, 0xB7, 0x56, 0xC0, 0xA8,
    0x01, 0x16, 0xC0, 0xA8,
    0x01, 0x02, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00
};


/* ========================================================================== */
/*                           Macros & Typedefs                                */
/* ========================================================================== */



/* ========================================================================== */
/*                          Function Definitions                              */
/* ========================================================================== */


bool ICSS_EMAC_testRxPktParser(ICSS_EmacHandle handle, void *pIcssRxPktInfo)
{
    char *pTemp = (char*) pIcssRxPktInfo;

    uint16_t ethType;
    ethType = *(uint16_t *)(pTemp  +  2 * ICSS_EMAC_TEST_ETH_ALEN);
    ethType = ICSS_EMAC_TEST_BYTESWAP16(ethType);
   
    
    if (ethType == ICSS_EMAC_TEST_ETHER_TYPE)
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }

}
int32_t ICSS_EMAC_testGetPruStats(uint8_t portNum, ICSS_EmacHandle icssEmacHandle)
{
    if (icssEmacHandle == ICSS_EMAC_testHandle)
    {
        PRINT("\nPRU-ICSS STATS for PRU1ETH0\n");
    }
    else if (icssEmacHandle == ICSS_EMAC_testHandle1)
    {
        PRINT("\nPRU-ICSS STATS for PRU1ETH1\n");
    }
    else if (icssEmacHandle == ICSS_EMAC_testHandle2)
    {
        PRINT("\nPRU-ICSS STATS for PRU2ETH0\n");
    }
    else if (icssEmacHandle == ICSS_EMAC_testHandle3)
    {
        PRINT("\nPRU-ICSS STATS for PRU2ETH1\n");
    }
    else
    {
        PRINT("ICSS_EMAC_testGetPruStats: Invalid ICSS_EmacHandle, returning without stats\n");
        return -1;
    }
        
    ICSS_EmacReadStats(portNum, icssEmacHandle);
    ICSS_EmacPruStatistics_t* pruStatsPtr = (ICSS_EmacPruStatistics_t *)(((ICSS_EmacObject *)icssEmacHandle->object)->pruStat);

    PRINT("txBcast:0x%x\n", pruStatsPtr->txBcast);
    PRINT("txMcast:0x%x\n", pruStatsPtr->txMcast);
    PRINT("txUcast:0x%x\n", pruStatsPtr->txUcast);
    PRINT("txOctets:0x%x\n", pruStatsPtr->txOctets);
    
    PRINT("rxBcast:0x%x\n", pruStatsPtr->rxBcast);
    PRINT("rxMcast:0x%x\n", pruStatsPtr->rxMcast);
    PRINT("rxUcast:0x%x\n", pruStatsPtr->rxUcast);
    PRINT("rxOctets:0x%x\n", pruStatsPtr->rxOctets);

    PRINT("tx64byte:0x%x\n", pruStatsPtr->tx64byte);
    PRINT("tx65_127byte:0x%x\n", pruStatsPtr->tx65_127byte);
    PRINT("tx128_255byte:0x%x\n", pruStatsPtr->tx128_255byte);
    PRINT("tx512_1023byte:0x%x\n", pruStatsPtr->tx512_1023byte);
    PRINT("tx1024byte:0x%x\n", pruStatsPtr->tx1024byte);

    PRINT("rx64byte:0x%x\n", pruStatsPtr->rx64byte);
    PRINT("rx65_127byte:0x%x\n", pruStatsPtr->rx65_127byte);
    PRINT("rx128_255byte:0x%x\n", pruStatsPtr->rx128_255byte);
    PRINT("rx512_1023byte:0x%x\n", pruStatsPtr->rx512_1023byte);
    PRINT("rx1024byte:0x%x\n", pruStatsPtr->rx1024byte);

    PRINT("lateColl:0x%x\n", pruStatsPtr->lateColl);
    PRINT("singleColl:0x%x\n", pruStatsPtr->singleColl);
    PRINT("multiColl:0x%x\n", pruStatsPtr->excessColl);
    PRINT("excessColl:0x%x\n", pruStatsPtr->excessColl);

    PRINT("rxMisAlignmentFrames:0x%x\n", pruStatsPtr->rxMisAlignmentFrames);
    PRINT("stormPrevCounter:0x%x\n", pruStatsPtr->stormPrevCounter);
    PRINT("macRxError:0x%x\n", pruStatsPtr->macRxError);
    PRINT("SFDError:0x%x\n", pruStatsPtr->SFDError);
    PRINT("defTx:0x%x\n", pruStatsPtr->defTx);
    PRINT("macTxError:0x%x\n", pruStatsPtr->macTxError);
    PRINT("rxOverSizedFrames:0x%x\n", pruStatsPtr->rxOverSizedFrames);
    PRINT("rxUnderSizedFrames:0x%x\n", pruStatsPtr->rxUnderSizedFrames);
    PRINT("rxCRCFrames:0x%x\n", pruStatsPtr->rxCRCFrames);
    PRINT("droppedPackets:0x%x\n", pruStatsPtr->droppedPackets);

/* Debug variables, these are not part of standard MIB. Useful for debugging
    Reserved for future Use 
 */
    PRINT("txOverFlow:0x%x\n", pruStatsPtr->txOverFlow);
    PRINT("txUnderFlow:0x%x\n", pruStatsPtr->txUnderFlow);
    PRINT("sqeTestError:0x%x\n", pruStatsPtr->sqeTestError);
    PRINT("TXqueueLevel:0x%x\n", pruStatsPtr->TXqueueLevel);
    PRINT("CSError:0x%x\n\n", pruStatsPtr->CSError);

    return 0;
    
}

void ICSS_EMAC_testDrvInit(ICSS_EmacHandle handle, uint8_t instance) 
{

    /* LLD attributes mallocs */
    handle->object = (ICSS_EmacObject*)malloc(sizeof(ICSS_EmacObject));
    handle->hwAttrs= (ICSS_EmacHwAttrs*)malloc(sizeof(ICSS_EmacHwAttrs));

    /* Callback mallocs */
    ICSS_EmacCallBackObject* callBackObj = (ICSS_EmacCallBackObject*)malloc(sizeof(ICSS_EmacCallBackObject));

    callBackObj->learningExCallBack=(ICSS_EmacCallBackConfig*)malloc(sizeof(ICSS_EmacCallBackConfig));
    callBackObj->rxRTCallBack=(ICSS_EmacCallBackConfig*)malloc(sizeof(ICSS_EmacCallBackConfig));
    callBackObj->rxCallBack=(ICSS_EmacCallBackConfig*)malloc(sizeof(ICSS_EmacCallBackConfig));
    callBackObj->txCallBack=(ICSS_EmacCallBackConfig*)malloc(sizeof(ICSS_EmacCallBackConfig));
    ((ICSS_EmacObject*)handle->object)->callBackHandle = callBackObj;

    /*Allocate memory for learning*/
    ((ICSS_EmacObject*)handle->object)->macTablePtr = (HashTable_t*)malloc(NUM_PORTS * sizeof(HashTable_t));

    /*Allocate memory for PRU Statistics*/
    ((ICSS_EmacObject*)handle->object)->pruStat = (ICSS_EmacPruStatistics_t*)malloc(NUM_PORTS * sizeof(ICSS_EmacPruStatistics_t));

    /*Allocate memory for Host Statistics*/
    ((ICSS_EmacObject*)handle->object)->hostStat = (ICSS_EmacHostStatistics_t*)malloc(NUM_PORTS * sizeof(ICSS_EmacHostStatistics_t));

    /*Allocate memory for Storm Prevention*/
    ((ICSS_EmacObject*)handle->object)->stormPrevPtr = (stormPrevention_t*)malloc(NUM_PORTS * sizeof(stormPrevention_t));

    /* Base address initialization */
    if(NULL == ((ICSS_EmacHwAttrs*)handle->hwAttrs)->emacBaseAddrCfg) {
        ((ICSS_EmacHwAttrs*)handle->hwAttrs)->emacBaseAddrCfg =
                        (ICSS_EmacBaseAddressHandle_T)malloc(sizeof(ICSS_EmacBaseAddrCfgParams));
    }
    ICSS_EmacBaseAddressHandle_T emacBaseAddr = ((ICSS_EmacHwAttrs*)handle->hwAttrs)->emacBaseAddrCfg;


#ifdef __LINUX_USER_SPACE
    tprussdrv *pruss_handle = (instance==1 ? pruss_drv_handle:pruss_drv_handle2);
    ((ICSS_EmacObject*)handle->object)->pruss_drv_handle = pruss_handle;

    emacBaseAddr->dataRam0BaseAddr          = (uint32_t) pruss_handle->pru0_dataram_base;
    emacBaseAddr->dataRam1BaseAddr          = (uint32_t) pruss_handle->pru1_dataram_base;
    emacBaseAddr->l3OcmcBaseAddr            = (uint32_t) pruss_handle->l3Ocmc_base;
    emacBaseAddr->prussCfgRegs              = (uint32_t) pruss_handle->pruss_cfg_base;
    emacBaseAddr->prussIepRegs              = (uint32_t) pruss_handle->pruss_iep_base;
    emacBaseAddr->prussIntcRegs             = (uint32_t) pruss_handle->intc_base;
    emacBaseAddr->prussMiiMdioRegs          = (uint32_t) pruss_handle->pruss_mdio_base;
    emacBaseAddr->prussMiiRtCfgRegsBaseAddr = (uint32_t) pruss_handle->pruss_miirt_base;
    emacBaseAddr->prussPru0CtrlRegs         = (uint32_t) pruss_handle->pru0_control_base;
    emacBaseAddr->prussPru1CtrlRegs         = (uint32_t) pruss_handle->pru1_control_base;
    emacBaseAddr->sharedDataRamBaseAddr     = (uint32_t) pruss_handle->pruss_sharedram_base;
    emacBaseAddr->l3OcmcBaseAddr_phys       = (uint32_t) ((pruss_handle->l3Ocmc_phy_base)&0xFFFF00|0x40000000);

    emacBaseAddr->sharedDataRamBaseAddr_phys = (uint32_t) icss_EmacBaseAddrCfgParams[instance-1].sharedDataRamBaseAddr;
#else
    /*For AM57x, chip DB is not used .here it is hard coded to PRUSS instance 2*/
    if(instance == 2)
    {
        emacBaseAddr->dataRam0BaseAddr = icss_EmacBaseAddrCfgParams[instance-1].dataRam0BaseAddr;
        emacBaseAddr->dataRam1BaseAddr = icss_EmacBaseAddrCfgParams[instance-1].dataRam1BaseAddr;
        /*    Restricting l3OcmcBaseAddr to 0x40xxxx00.
         *  This is done because L3 OCMC Base Address must be 256 byte aligned and to support OCMC memory usage for Linux Power Management.
         */
#ifdef SOC_K2G
        emacBaseAddr->l3OcmcBaseAddr =  icss_EmacBaseAddrCfgParams[instance-1].l3OcmcBaseAddr;
#else
        emacBaseAddr->l3OcmcBaseAddr =  (((icss_EmacBaseAddrCfgParams[instance-1].l3OcmcBaseAddr)&0xFFFF00)|0x40000000);
#endif
        emacBaseAddr->prussCfgRegs =  icss_EmacBaseAddrCfgParams[instance-1].prussCfgRegs;
        emacBaseAddr->prussIepRegs =  icss_EmacBaseAddrCfgParams[instance-1].prussIepRegs;
        emacBaseAddr->prussIntcRegs = icss_EmacBaseAddrCfgParams[instance-1].prussIntcRegs;
        emacBaseAddr->prussMiiMdioRegs = icss_EmacBaseAddrCfgParams[instance-1].prussMiiMdioRegs;
        emacBaseAddr->prussMiiRtCfgRegsBaseAddr = icss_EmacBaseAddrCfgParams[instance-1].prussMiiRtCfgRegsBaseAddr;
        emacBaseAddr->prussPru0CtrlRegs = icss_EmacBaseAddrCfgParams[instance-1].prussPru0CtrlRegs;
        emacBaseAddr->prussPru1CtrlRegs = icss_EmacBaseAddrCfgParams[instance-1].prussPru1CtrlRegs;
        emacBaseAddr->sharedDataRamBaseAddr = icss_EmacBaseAddrCfgParams[instance-1].sharedDataRamBaseAddr;
    }
    else
    {
        emacBaseAddr->dataRam0BaseAddr = icss_EmacBaseAddrCfgParams[instance-1].dataRam0BaseAddr;
        emacBaseAddr->dataRam1BaseAddr = icss_EmacBaseAddrCfgParams[instance-1].dataRam1BaseAddr;
        /*    Restricting l3OcmcBaseAddr to 0x40xxxx00.
         *  This is done because L3 OCMC Base Address must be 256 byte aligned and to support OCMC memory usage for Linux Power Management.
         */
#ifdef SOC_K2G
        emacBaseAddr->l3OcmcBaseAddr =  icss_EmacBaseAddrCfgParams[instance-1].l3OcmcBaseAddr;
#else
        emacBaseAddr->l3OcmcBaseAddr =  (((icss_EmacBaseAddrCfgParams[instance-1].l3OcmcBaseAddr)&0xFFFF00)|0x40000000);
#endif
        emacBaseAddr->prussCfgRegs =  icss_EmacBaseAddrCfgParams[instance-1].prussCfgRegs;
        emacBaseAddr->prussIepRegs =  icss_EmacBaseAddrCfgParams[instance-1].prussIepRegs;
        emacBaseAddr->prussIntcRegs = icss_EmacBaseAddrCfgParams[instance-1].prussIntcRegs;
        emacBaseAddr->prussMiiMdioRegs = icss_EmacBaseAddrCfgParams[instance-1].prussMiiMdioRegs;
        emacBaseAddr->prussMiiRtCfgRegsBaseAddr = icss_EmacBaseAddrCfgParams[instance-1].prussMiiRtCfgRegsBaseAddr;
        emacBaseAddr->prussPru0CtrlRegs = icss_EmacBaseAddrCfgParams[instance-1].prussPru0CtrlRegs;
        emacBaseAddr->prussPru1CtrlRegs = icss_EmacBaseAddrCfgParams[instance-1].prussPru1CtrlRegs;
        emacBaseAddr->sharedDataRamBaseAddr = icss_EmacBaseAddrCfgParams[instance-1].sharedDataRamBaseAddr;
    }
#endif
}

int32_t ICSS_EMAC_testCallbackTxComplete(void* ICSS_EmacSubSysHandle, void* queueNum)
{
    if(!(ICSS_EMAC_testTtsModePort1 | ICSS_EMAC_testTtsModePort2))
    {
        if((ICSS_EmacHandle)ICSS_EmacSubSysHandle ==  ICSS_EMAC_testHandle)
        {
            PRINT("packet transmission complete for packet(ICSS_EMAC_TEST_PRU1ETH0): %d\n", ICSS_EMAC_testPacketTxCompletePort0);
            ICSS_EMAC_testPacketTxCompletePort0++;
        }
        else if((ICSS_EmacHandle)ICSS_EmacSubSysHandle == ICSS_EMAC_testHandle1)
        {
            PRINT("packet transmission complete for packet(ICSS_EMAC_TEST_PRU1ETH1) %d\n", ICSS_EMAC_testPacketTxCompletePort1);
            ICSS_EMAC_testPacketTxCompletePort1++;
        }
        else if((ICSS_EmacHandle)ICSS_EmacSubSysHandle == ICSS_EMAC_testHandle2)
        {
            PRINT("packet transmission complete for packet(ICSS_EMAC_TEST_PRU2ETH0): %d\n", ICSS_EMAC_testPacketTxCompletePort2);
            ICSS_EMAC_testPacketTxCompletePort2++;
        }
         else if((ICSS_EmacHandle)ICSS_EmacSubSysHandle == ICSS_EMAC_testHandle3)
        {
            PRINT("packet transmission complete for packet(ICSS_EMAC_TEST_PRU2ETH1): %d\n", ICSS_EMAC_testPacketTxCompletePort3);
            ICSS_EMAC_testPacketTxCompletePort3++;
        }
    }
    return 0;
}
int32_t ICSS_EMAC_testCallbackRxPacket(void* queueNum, void* ICSS_EmacSubSysHandle)
{
    uint8_t         j;
    uint32_t        tmp;
    int32_t         packetLength;
    bool        etherType;
    ICSS_EmacRxArgument rxArgs;
    ICSS_EmacPktInfo rxPktInfo;
    ICSS_EmacHandle icssEmacHandle = (ICSS_EmacHandle) ICSS_EmacSubSysHandle;
    rxArgs.icssEmacHandle = ICSS_EMAC_testHandle;
    rxArgs.queueNumber = *((uint32_t *)(queueNum));
    rxArgs.more = 0;
    rxArgs.port = 0;

    if(ICSS_EMAC_testTtsModePort1)
    {
        rxArgs.destAddress =  (uint32_t)(&ICSS_EMAC_testTtsRecvPktPort1[0]);
        memset(ICSS_EMAC_testTtsRecvPktPort1, 0, ICSS_EMAC_MAXMTU);
        if(icssEmacHandle == ICSS_EMAC_testHandle)
        {
                packetLength = ICSS_EmacRxPktGet(&rxArgs, NULL);
                assert((packetLength != -1) && (packetLength != 0));
                /*    Extract packet number    */
                tmp = 0;
                for(j=0;j<4;j++)
                {
                    tmp = (tmp | (uint32_t)(ICSS_EMAC_testTtsRecvPktPort1[packetLength - j -1] << ((3-j)*8)));
                }

                if((*((uint32_t *)(queueNum))) == ICSS_EMAC_QUEUE1)
                {
                    if((tmp - ICSS_EMAC_testRecv_Q1PktCntPort1) != 1)
                    {
                         PRINT("\nTTS Port 1: Error in received cyclic pkt sequence.\nPrevious seq no.: %u\nNew seq no.:%u", ICSS_EMAC_testRecv_Q1PktCntPort1, tmp);
                    }
                    ICSS_EMAC_testRecv_Q1PktCntPort1 = tmp;
                    if (0 != (memcmp(&ICSS_EMAC_testTtsRecvPktPort1[0], &ICSS_EMAC_testArpPktPort1[0],ICSS_EMAC_TEST_ARP_PKT_SIZE_PORT1)))
                    {
                         PRINT("\nTTS Port 1: Error in received cyclic pkt content. Packet mismatch.");
                    }
                    /*    If interrupt is for cyclic packet completion, post semaphore    */
                    ICSS_EMAC_osalPostLock(ICSS_EMAC_testTtsP1TimeSem);
                }
                else if((*((uint32_t *)(queueNum))) == ICSS_EMAC_QUEUE2)
                {
                    if((tmp - ICSS_EMAC_testRecv_Q2PktCntPort1) != 1)
                    {
                         PRINT("\nTTS Port 1: Error in received acyclic pkt sequence.\nPrevious seq no.: %u\nNew seq no.:%u", ICSS_EMAC_testRecv_Q2PktCntPort1, tmp);
                    }
                    ICSS_EMAC_testRecv_Q2PktCntPort1 = tmp;
                    if (0 != (memcmp(&ICSS_EMAC_testTtsRecvPktPort1[0], &ICSS_EMAC_testUdpPktPort1[0],ICSS_EMAC_TEST_UDP_PKT_SIZE_PORT1)))
                    {
                         PRINT("\nTTS Port 1: Error in received acyclic pkt content. Packet mismatch.");
                    }
                }

                /*    Check if mac cyclic and acyclic packet count is reached    */
                /*    This means test is over and we can print results    */
                if((ICSS_EMAC_testRecv_Q1PktCntPort1 == ICSS_EMAC_TEST_TTS_MAX_CYC_PKT_COUNT) && (ICSS_EMAC_testRecv_Q2PktCntPort1 == ICSS_EMAC_TEST_TTS_MAX_ACYC_PKT_COUNT))
                {
                    /*    Post semaphore    */
                    ICSS_EMAC_osalPostLock(ICSS_EMAC_testTtsP1ResultSem);
                }
        }
    }
    else
    {
        rxArgs.destAddress =  (uint32_t)(&ICSS_EMAC_testPacketArrayInstance1[0]);
        if(icssEmacHandle == ICSS_EMAC_testHandle)
        {
            for (tmp = 1; tmp; )
            {
                memset(&rxPktInfo,0, sizeof(ICSS_EmacPktInfo));
                ICSS_EmacRxPktInfo2(icssEmacHandle, &rxPktInfo);
                etherType = ICSS_EMAC_testRxPktParser(icssEmacHandle, rxPktInfo.rdBufferL3Addr);
                if (etherType == TRUE)
                {
                    PRINT("parser returned correct value: rdBufferL3Addr 0x%x, port: 0x%x, queue: 0x%x\n",rxPktInfo.rdBufferL3Addr, rxPktInfo.portNumber, rxPktInfo.queueNumber);
                }
                else
                {
                    PRINT("parser returned incorect values: rdBufferL3Addr 0x%x, port: 0x%x, queue: 0x%x\n",rxPktInfo.rdBufferL3Addr, rxPktInfo.portNumber, rxPktInfo.queueNumber);
                    return 0;
                }
                packetLength = ICSS_EmacRxPktGet(&rxArgs, NULL);
                 if(rxArgs.more== 0)
                    tmp = 0;    // exit if there are no more packets
            }
            if(packetLength)
            {
                if (!(memcmp(&ICSS_EMAC_testPacketArrayInstance1[0], &ICSS_EMAC_testPkt[0],ICSS_EMAC_TEST_PKT_SIZE)))
                {
                    PRINT("ICSS_EMAC_testTaskPruss1(PRU1 ETH0): received pkt: %d\n", ICSS_EMAC_testTotalPktRcvd);
                    ICSS_EMAC_testTotalPktRcvd++;
                    ICSS_EMAC_testPacketRcvdPort0++; /* PRU1 ETH 0 */
                }
                else
                {
                    PRINT("Unit Test Failure, packet mismatch occured\n");
                 }
            }
        }
    }
    return 0;
}



int32_t ICSS_EMAC_testCallbackRxPacket1(void* queueNum, void* ICSS_EmacSubSysHandle)
{
    uint8_t         j;
    uint32_t        tmp;
    int32_t         packetLength;
    ICSS_EmacRxArgument rxArgs;
    ICSS_EmacPktInfo rxPktInfo;
    bool etherType;
    ICSS_EmacHandle icssEmacHandle = (ICSS_EmacHandle) ICSS_EmacSubSysHandle;
    rxArgs.icssEmacHandle = ICSS_EMAC_testHandle1;
    rxArgs.queueNumber = *((uint32_t *)(queueNum));
    rxArgs.more = 0;
    rxArgs.port = 0;
    
    if(ICSS_EMAC_testTtsModePort2)
    {
        rxArgs.destAddress =  (uint32_t)(&ICSS_EMAC_testTtsRecvPktPort2[0]);
        memset(ICSS_EMAC_testTtsRecvPktPort2, 0, ICSS_EMAC_MAXMTU);
        if(icssEmacHandle == ICSS_EMAC_testHandle1)
        {
                packetLength = ICSS_EmacRxPktGet(&rxArgs, NULL);
                assert((packetLength != -1) && (packetLength != 0));
                /*    Extract packet number    */
                tmp = 0;
                for(j=0;j<4;j++)
                {
                    tmp = (tmp | (uint32_t)(ICSS_EMAC_testTtsRecvPktPort2[packetLength - j -1] << ((3-j)*8)));
                }

                if((*((uint32_t *)(queueNum))) == ICSS_EMAC_QUEUE3)
                {
                    if((tmp - ICSS_EMAC_testRecv_Q1PktCntPort2) != 1)
                    {
                         PRINT("\nTTS Port 2: Error in received cyclic pkt sequence.\nPrevious seq no.: %u\nNew seq no.:%u", ICSS_EMAC_testRecv_Q1PktCntPort2, tmp);
                    }
                    ICSS_EMAC_testRecv_Q1PktCntPort2 = tmp;
                    if (0 != (memcmp(&ICSS_EMAC_testTtsRecvPktPort2[0], &ICSS_EMAC_testArpPktPort2[0],ICSS_EMAC_TEST_ARP_PKT_SIZE_PORT2)))
                    {
                         PRINT("\nTTS Port 2: Error in received cyclic pkt content. Packet mismatch.");
                    }
                    /*    If interrupt is for cyclic packet completion, post semaphore    */
                    ICSS_EMAC_osalPostLock(ICSS_EMAC_testTtsP2TimeSem);
                }
                else if((*((uint32_t *)(queueNum))) == ICSS_EMAC_QUEUE4)
                {
                    if((tmp - ICSS_EMAC_testRecv_Q2PktCntPort2) != 1)
                    {
                         PRINT("\nTTS Port 2: Error in received acyclic pkt sequence.\nPrevious seq no.: %u\nNew seq no.:%u", ICSS_EMAC_testRecv_Q2PktCntPort2, tmp);
                    }
                    ICSS_EMAC_testRecv_Q2PktCntPort2 = tmp;
                    if (0 != (memcmp(&ICSS_EMAC_testTtsRecvPktPort2[0], &ICSS_EMAC_testUdpPktPort2[0],ICSS_EMAC_TEST_UDP_PKT_SIZE_PORT2)))
                    {
                         PRINT("\nTTS Port 2: Error in received acyclic pkt content. Packet mismatch.");
                    }
                }

                /*    Check if mac cyclic and acyclic packet count is reached    */
                /*    This means test is over and we can print results    */
                if((ICSS_EMAC_testRecv_Q1PktCntPort2 == ICSS_EMAC_TEST_TTS_MAX_CYC_PKT_COUNT) && (ICSS_EMAC_testRecv_Q2PktCntPort2 == ICSS_EMAC_TEST_TTS_MAX_ACYC_PKT_COUNT))
                {
                    /*    Post semaphore    */
                    ICSS_EMAC_osalPostLock(ICSS_EMAC_testTtsP2ResultSem);
                }
        }
    }
    else
    {
        rxArgs.destAddress =  (uint32_t)(&ICSS_EMAC_testPacketArrayInstance1_1[0]);
        if(icssEmacHandle == ICSS_EMAC_testHandle1)
        {
            for (tmp = 1; tmp; )
            {
                memset(&rxPktInfo,0, sizeof(ICSS_EmacPktInfo));
                ICSS_EmacRxPktInfo2(icssEmacHandle, &rxPktInfo);
                etherType = ICSS_EMAC_testRxPktParser(icssEmacHandle, rxPktInfo.rdBufferL3Addr);
                if (etherType == TRUE)
                {
                    PRINT("parser returned correct value: rdBufferL3Addr 0x%x, port: 0x%x, queue: 0x%x\n",rxPktInfo.rdBufferL3Addr, rxPktInfo.portNumber, rxPktInfo.queueNumber);
                }
                else
                {
                    PRINT("parser returned incorect values: rdBufferL3Addr 0x%x, port: 0x%x, queue: 0x%x\n",rxPktInfo.rdBufferL3Addr, rxPktInfo.portNumber, rxPktInfo.queueNumber);
                    return 0;
                }
                packetLength = ICSS_EmacRxPktGet(&rxArgs, NULL);
                if(rxArgs.more== 0)
                    tmp = 0;    // exit if there are no more packets
            }
            if(packetLength)
            {
                if (!(memcmp(&ICSS_EMAC_testPacketArrayInstance1_1[0], &ICSS_EMAC_testPkt[0],ICSS_EMAC_TEST_PKT_SIZE)))
                {
                    PRINT("ICSS_EMAC_testTaskPruss1(PRU1 ETH1): received pkt: %d\n", ICSS_EMAC_testTotalPktRcvd);
                    ICSS_EMAC_testTotalPktRcvd++;
                    ICSS_EMAC_testPacketRcvdPort1++; /* PRU1 ETH 0 */
                }
                else
                {
                    PRINT("Unit Test Failure, packet mismatch occured\n");
                }
            }
        }
    }
    return 0;
}

int32_t ICSS_EMAC_testCallbackRxPacket2(void* queueNum, void* ICSS_EmacSubSysHandle)
{
    uint8_t         j;
    uint32_t        tmp;
    int32_t         packetLength;
    ICSS_EmacRxArgument rxArgs;
    ICSS_EmacPktInfo rxPktInfo;
    bool etherType;
     ICSS_EmacHandle icssEmacHandle = (ICSS_EmacHandle) ICSS_EmacSubSysHandle;
    rxArgs.icssEmacHandle = ICSS_EMAC_testHandle2;
    rxArgs.queueNumber = *((uint32_t *)(queueNum));
    rxArgs.more = 0;
    rxArgs.port = 0;

    if(ICSS_EMAC_testTtsModePort1)
    {
        rxArgs.destAddress =  (uint32_t)(&ICSS_EMAC_testTtsRecvPktPort1[0]);
        memset(ICSS_EMAC_testTtsRecvPktPort1, 0, ICSS_EMAC_MAXMTU);
        if(icssEmacHandle == ICSS_EMAC_testHandle2)
        {
                packetLength = ICSS_EmacRxPktGet(&rxArgs, NULL);
                assert((packetLength != -1) && (packetLength != 0));
                /*    Extract packet number    */
                tmp = 0;
                for(j=0;j<4;j++)
                {
                    tmp = (tmp | (uint32_t)(ICSS_EMAC_testTtsRecvPktPort1[packetLength - j -1] << ((3-j)*8)));
                }

                if((*((uint32_t *)(queueNum))) == ICSS_EMAC_QUEUE1)
                {
                    if((tmp - ICSS_EMAC_testRecv_Q1PktCntPort1) != 1)
                    {
                         PRINT("\nTTS Port 1: Error in received cyclic pkt sequence.\nPrevious seq no.: %u\nNew seq no.:%u", ICSS_EMAC_testRecv_Q1PktCntPort1, tmp);
                    }
                    ICSS_EMAC_testRecv_Q1PktCntPort1 = tmp;
                    if (0 != (memcmp(&ICSS_EMAC_testTtsRecvPktPort1[0], &ICSS_EMAC_testArpPktPort1[0],ICSS_EMAC_TEST_ARP_PKT_SIZE_PORT1)))
                    {
                         PRINT("\nTTS Port 1: Error in received cyclic pkt content. Packet mismatch.");
                    }
                    /*    If interrupt is for cyclic packet completion, post semaphore    */
                    ICSS_EMAC_osalPostLock(ICSS_EMAC_testTtsP1TimeSem);
                }
                else if((*((uint32_t *)(queueNum))) == ICSS_EMAC_QUEUE2)
                {
                    if((tmp - ICSS_EMAC_testRecv_Q2PktCntPort1) != 1)
                    {
                         PRINT("\nTTS Port 1: Error in received acyclic pkt sequence.\nPrevious seq no.: %u\nNew seq no.:%u", ICSS_EMAC_testRecv_Q2PktCntPort1, tmp);
                    }
                    ICSS_EMAC_testRecv_Q2PktCntPort1 = tmp;
                    if (0 != (memcmp(&ICSS_EMAC_testTtsRecvPktPort1[0], &ICSS_EMAC_testUdpPktPort1[0],ICSS_EMAC_TEST_UDP_PKT_SIZE_PORT1)))
                    {
                         PRINT("\nTTS Port 1: Error in received acyclic pkt content. Packet mismatch.");
                    }
                }

                /*    Check if mac cyclic and acyclic packet count is reached    */
                /*    This means test is over and we can print results    */
                if((ICSS_EMAC_testRecv_Q1PktCntPort1 == ICSS_EMAC_TEST_TTS_MAX_CYC_PKT_COUNT) && (ICSS_EMAC_testRecv_Q2PktCntPort1 == ICSS_EMAC_TEST_TTS_MAX_ACYC_PKT_COUNT))
                {
                    /*    Post semaphore    */
                    ICSS_EMAC_osalPostLock(ICSS_EMAC_testTtsP1ResultSem);
                }
        }
    }
    else
    {
        rxArgs.destAddress =  (uint32_t)(&ICSS_EMAC_testPacketArrayInstance2[0]);

        if(icssEmacHandle == ICSS_EMAC_testHandle2)
        {
            for (tmp = 1; tmp; )
            {
                memset(&rxPktInfo,0, sizeof(ICSS_EmacPktInfo));
                ICSS_EmacRxPktInfo2(icssEmacHandle, &rxPktInfo);
                etherType = ICSS_EMAC_testRxPktParser(icssEmacHandle, rxPktInfo.rdBufferL3Addr);
                if (etherType == TRUE)
                {
                    PRINT("parser returned correct value: rdBufferL3Addr 0x%x, port: 0x%x, queue: 0x%x\n",rxPktInfo.rdBufferL3Addr, rxPktInfo.portNumber, rxPktInfo.queueNumber);
                }
                else
                {
                    PRINT("parser returned incorect values: rdBufferL3Addr 0x%x, port: 0x%x, queue: 0x%x\n",rxPktInfo.rdBufferL3Addr, rxPktInfo.portNumber, rxPktInfo.queueNumber);
                    return 0;
                }
                packetLength = ICSS_EmacRxPktGet(&rxArgs, NULL);
                if(rxArgs.more== 0)
                    tmp = 0;    // exit if there are no more packets
            }
            if(packetLength)
            {
                if(!(memcmp(&ICSS_EMAC_testPacketArrayInstance2[0], &ICSS_EMAC_testPkt[0],ICSS_EMAC_TEST_PKT_SIZE)))
                {
                    PRINT("ICSS_EMAC_testTaskPruss1(PRU2 ETH0): received pkt: %d\n", ICSS_EMAC_testTotalPktRcvd);
                    ICSS_EMAC_testTotalPktRcvd++;
                    ICSS_EMAC_testPacketRcvdPort2++; /* PRU2 ETH 0 */
                }
                else
                {
                    PRINT("Unit Test Failure, packet mismatch occured\n");
                }
            }
        }
    }
    return 0;
}


int32_t ICSS_EMAC_testCallbackRxPacket3(void* queueNum, void* ICSS_EmacSubSysHandle)
{
    uint8_t         j;
    uint32_t        tmp;
    int32_t         packetLength;
    ICSS_EmacRxArgument rxArgs;
    ICSS_EmacPktInfo rxPktInfo;
    bool etherType;
    ICSS_EmacHandle icssEmacHandle = (ICSS_EmacHandle) ICSS_EmacSubSysHandle;

    rxArgs.icssEmacHandle = ICSS_EMAC_testHandle3;
    rxArgs.queueNumber = *((uint32_t *)(queueNum));
    rxArgs.more = 0;
    rxArgs.port = 0;

    if(ICSS_EMAC_testTtsModePort2)
    {
        rxArgs.destAddress =  (uint32_t)(&ICSS_EMAC_testTtsRecvPktPort2[0]);
        memset(ICSS_EMAC_testTtsRecvPktPort2, 0, ICSS_EMAC_MAXMTU);
        if(icssEmacHandle == ICSS_EMAC_testHandle3)
        {
                packetLength = ICSS_EmacRxPktGet(&rxArgs, NULL);
                assert((packetLength != -1) && (packetLength != 0));
                /*    Extract packet number    */
                tmp = 0;
                for(j=0;j<4;j++)
                {
                    tmp = (tmp | (uint32_t)(ICSS_EMAC_testTtsRecvPktPort2[packetLength - j -1] << ((3-j)*8)));
                }

                if((*((uint32_t *)(queueNum))) == ICSS_EMAC_QUEUE3)
                {
                    if((tmp - ICSS_EMAC_testRecv_Q1PktCntPort2) != 1)
                    {
                         PRINT("\nTTS Port 2: Error in received cyclic pkt sequence.\nPrevious seq no.: %u\nNew seq no.:%u", ICSS_EMAC_testRecv_Q1PktCntPort2, tmp);
                    }
                    ICSS_EMAC_testRecv_Q1PktCntPort2 = tmp;
                    if (0 != (memcmp(&ICSS_EMAC_testTtsRecvPktPort2[0], &ICSS_EMAC_testArpPktPort2[0],ICSS_EMAC_TEST_ARP_PKT_SIZE_PORT2)))
                    {
                         PRINT("\nTTS Port 2: Error in received cyclic pkt content. Packet mismatch.");
                    }
                    /*    If interrupt is for cyclic packet completion, post semaphore    */
                    ICSS_EMAC_osalPostLock(ICSS_EMAC_testTtsP2TimeSem);
                }
                else if((*((uint32_t *)(queueNum))) == ICSS_EMAC_QUEUE4)
                {
                    if((tmp - ICSS_EMAC_testRecv_Q2PktCntPort2) != 1)
                    {
                         PRINT("\nTTS Port 2: Error in received acyclic pkt sequence.\nPrevious seq no.: %u\nNew seq no.:%u", ICSS_EMAC_testRecv_Q2PktCntPort2, tmp);
                    }
                    ICSS_EMAC_testRecv_Q2PktCntPort2 = tmp;
                    if (0 != (memcmp(&ICSS_EMAC_testTtsRecvPktPort2[0], &ICSS_EMAC_testUdpPktPort2[0],ICSS_EMAC_TEST_UDP_PKT_SIZE_PORT2)))
                    {
                         PRINT("\nTTS Port 2: Error in received acyclic pkt content. Packet mismatch.");
                    }
                }

                /*    Check if mac cyclic and acyclic packet count is reached    */
                /*    This means test is over and we can print results    */
                if((ICSS_EMAC_testRecv_Q1PktCntPort2 == ICSS_EMAC_TEST_TTS_MAX_CYC_PKT_COUNT) && (ICSS_EMAC_testRecv_Q2PktCntPort2 == ICSS_EMAC_TEST_TTS_MAX_ACYC_PKT_COUNT))
                {
                    /*    Post semaphore    */
                    ICSS_EMAC_osalPostLock(ICSS_EMAC_testTtsP2ResultSem);
                }
        }
    }
    else
    {
        rxArgs.destAddress =  (uint32_t)(&ICSS_EMAC_testPacketArrayInstance2_1[0]);

        if(icssEmacHandle == ICSS_EMAC_testHandle3)
        {
            for (tmp = 1; tmp; )
            {
                memset(&rxPktInfo,0, sizeof(ICSS_EmacPktInfo));
                ICSS_EmacRxPktInfo2(icssEmacHandle, &rxPktInfo);
                etherType = ICSS_EMAC_testRxPktParser(icssEmacHandle, rxPktInfo.rdBufferL3Addr);
                if (etherType == TRUE)
                {
                    PRINT("parser returned correct value: rdBufferL3Addr 0x%x, port: 0x%x, queue: 0x%x\n",rxPktInfo.rdBufferL3Addr, rxPktInfo.portNumber, rxPktInfo.queueNumber);
                }
                else
                {
                    PRINT("parser returned incorect values: rdBufferL3Addr 0x%x, port: 0x%x, queue: 0x%x\n",rxPktInfo.rdBufferL3Addr, rxPktInfo.portNumber, rxPktInfo.queueNumber);
                    return 0;
                }
                packetLength = ICSS_EmacRxPktGet(&rxArgs, NULL);
                if(rxArgs.more== 0)
                    tmp = 0;    // exit if there are no more packets
            }
            if(packetLength)
            {
               if (!(memcmp(&ICSS_EMAC_testPacketArrayInstance2_1[0], &ICSS_EMAC_testPkt[0],ICSS_EMAC_TEST_PKT_SIZE)))
                {
                    PRINT("ICSS_EMAC_testTaskPruss1(PRU2 ETH1): received pkt: %d\n", ICSS_EMAC_testTotalPktRcvd);
                    ICSS_EMAC_testTotalPktRcvd++;
                    ICSS_EMAC_testPacketRcvdPort3++; /* PRU2 ETH 0 */
                }
                else
                {
                    PRINT("Unit Test Failure, packet mismatch occured\n");
                }
            }
        }
    }
    return 0;
}

/*
 * ---ICSS_EMAC Link Interrupt Service routine callback ---
 */
int32_t ICSS_EMAC_testLinkIsrCb(void* linkStatus, void* usrArg)
{
    uint32_t status = (uint32_t) linkStatus;
    uint32_t pruNum = (uint32_t)usrArg;


    if (pruNum < ICSS_EMAC_TEST_PRU1ETH0 || pruNum > ICSS_EMAC_TEST_PRU2ETH1)
    {
         PRINT("ICSS_EMAC_testLinkIsrCb: Invalid link Status/pruNum\n");
         return -1;
    }
    if ((status  == 1) && (pruNum == ICSS_EMAC_TEST_PRU1ETH0))
    {
        ICSS_EMAC_testLinkIsrPru1Eth0++;
    }
    else if ((status  == 1) && (pruNum == ICSS_EMAC_TEST_PRU1ETH1))
    {
        ICSS_EMAC_testLinkIsrPru1Eth1++;
    }
    else if ((status  == 1) && (pruNum == ICSS_EMAC_TEST_PRU2ETH0))
    {
        ICSS_EMAC_testLinkIsrPru2Eth0++;
    }
    else if ((status  == 1) && (pruNum == ICSS_EMAC_TEST_PRU2ETH1))
    {
        ICSS_EMAC_testLinkIsrPru2Eth1++;
    }
    else
    {
        PRINT("ICSS_EMAC_testLinkIsrCb: Link Down for pruNum : %d\n", pruNum);
        return -1;
    }
    return 0;
}


/*
 * ---TTS Cyclic Packet Insertion Interrupt Callback Port 1---
 */
void ICSS_EMAC_testTtsCycPort1Callback()
{
    ICSS_EMAC_osalPostLock(ICSS_EMAC_testTtsP1TxSem);
}

/*
 * ---TTS Cyclic Packet Insertion Interrupt Callback Port 2---
 */
void ICSS_EMAC_testTtsCycPort2Callback()
{
    ICSS_EMAC_osalPostLock(ICSS_EMAC_testTtsP2TxSem);
}

#if defined (__ARM_ARCH_7A__) || defined (__TI_ARM_V7M4__)
/**
* @internal
* @brief Registering Interrupts and Enabling global interrupts
*
* @param icssEmacHandle  icssEmacHandle handle to ICSS_EMAC Instance.
*
* @retval none
*/
void ICSS_EMAC_testInterruptInit(ICSS_EmacHandle icssEmacHandle)
{
    HwiP_Handle rxHwiHandle;
    HwiP_Handle linkHwiHandle;
    HwiP_Handle txHwiHandle;

    static uint32_t cookie = 0;
    uint32_t linkIntrN = (((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->linkIntNum;

    uint32_t rxIntrN =   (((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->rxIntNum;

    uint32_t txIntrN =   (((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->txIntNum;

    cookie = ICSS_EMAC_osalHardwareIntDisable();

    HwiP_Params hwiParams;

    ICSS_EMAC_osalHwiParamsInit(&hwiParams);

    hwiParams.arg = (uintptr_t)icssEmacHandle;
    hwiParams.evtId = 0;
    hwiParams.priority = 20;


#ifdef SOC_K2G
            hwiParams.triggerSensitivity =2; /* use trigger type edge */
#endif
    rxHwiHandle = ICSS_EMAC_osalRegisterInterrupt(rxIntrN, (HwiP_Fxn)ICSS_EmacRxInterruptHandler, &hwiParams);
    if (rxHwiHandle == NULL ){
        return;
    }


    hwiParams.arg = (uintptr_t)icssEmacHandle;
    hwiParams.evtId = 0;
    hwiParams.priority = 20;
    linkHwiHandle = ICSS_EMAC_osalRegisterInterrupt(linkIntrN, (HwiP_Fxn)ICSS_EmacLinkISR, &hwiParams);

    if (linkHwiHandle == NULL) {
        return;
    }

    hwiParams.arg = (uintptr_t)icssEmacHandle;
    hwiParams.evtId = 0;
    hwiParams.priority = 20;
    txHwiHandle = ICSS_EMAC_osalRegisterInterrupt(txIntrN, (HwiP_Fxn)ICSS_EmacTxInterruptHandler, &hwiParams);


    if (txHwiHandle == NULL) {
        return;
    }
    ((ICSS_EmacObject*)icssEmacHandle->object)->txintHandle = txHwiHandle;

    ((ICSS_EmacObject*)icssEmacHandle->object)->rxintHandle = rxHwiHandle;
    ((ICSS_EmacObject*)icssEmacHandle->object)->linkintHandle = linkHwiHandle;

    ICSS_EMAC_osalHardwareIntRestore(cookie);
}
/**
* @internal
* @brief De-registering the interrupts and disabling global interrupts
*
* @param icssEmacHandle  icssEmacHandle handle to ICSS_EMAC Instance.
*
* @retval none
*/
void ICSS_EMAC_testInterruptEnd(ICSS_EmacHandle icssEmacHandle)
{
    if (icssEmacHandle != NULL)
    {
        ICSS_EMAC_osalHardwareIntDestruct((HwiP_Handle)(((ICSS_EmacObject*)icssEmacHandle->object)->rxintHandle));
        ICSS_EMAC_osalHardwareIntDestruct((HwiP_Handle)(((ICSS_EmacObject*)icssEmacHandle->object)->linkintHandle));
        ICSS_EMAC_osalHardwareIntDestruct((HwiP_Handle)(((ICSS_EmacObject*)icssEmacHandle->object)->txintHandle));
    }
}
/**
* @internal
* @brief This function enables the EMAC interrupts
*
* @param icssEmacHandle  icssEmacHandle handle to ICSS_EMAC Instance.
*
* @retval none
*/
void ICSS_EMAC_testInterruptEnable(ICSS_EmacHandle icssEmacHandle)
{
    uint32_t key = 0;
    if (icssEmacHandle != NULL)
    {
        key = ICSS_EMAC_osalHardwareIntDisable();
        ICSS_EMAC_osalHardwareInterruptEnable((((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->linkIntNum);
        ICSS_EMAC_osalHardwareInterruptEnable((((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->rxIntNum);
        ICSS_EMAC_osalHardwareInterruptEnable((((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->txIntNum);
        ICSS_EMAC_osalHardwareIntRestore(key);
    }
}
/**
* @brief This function disables the EMAC interrupts
* @internal
* @param icssEmacHandle  icssEmacHandle handle to ICSS_EMAC Instance.
*
* @retval none
*/
void ICSS_EMAC_testInterruptDisable(ICSS_EmacHandle icssEmacHandle)
{
    uint32_t key;
    if (icssEmacHandle != NULL)
    {
        key = ICSS_EMAC_osalHardwareIntDisable();

        ICSS_EMAC_osalHardwareInterruptDisable((((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->linkIntNum);
        ICSS_EMAC_osalHardwareInterruptDisable((((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->rxIntNum);
        ICSS_EMAC_osalHardwareInterruptDisable((((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->txIntNum);

        ICSS_EMAC_osalHardwareIntRestore(key);
    }
}
#else

/**
* @internal
* @brief Registering Interrupts and Enabling global interrupts
*
* @param icssEmacHandle  icssEmacHandle handle to ICSS_EMAC Instance.
*
* @retval none
*/
void ICSS_EMAC_testInterruptInit(ICSS_EmacHandle icssEmacHandle)
{

#ifdef SOC_K2G
    static uint32_t cookie = 0;
    MuxIntcP_inParams       muxInParams;
    MuxIntcP_outParams      muxOutParams;
    HwiP_Handle hwiHandle;
    cookie = ICSS_EMAC_osalHardwareIntDisable();

    muxInParams.arg         = (uintptr_t)icssEmacHandle;
    muxInParams.muxNum      = (((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->intrMuxCfgLink.intcMuxNum;
    muxInParams.muxInEvent  = (((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->intrMuxCfgLink.intcMuxInEvent;
    muxInParams.muxOutEvent = (((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->intrMuxCfgLink.intcMuxOutEvent;
    muxInParams.muxIntcFxn  = (MuxIntcFxn)(&ICSS_EmacLinkISR);

     ICSS_EMAC_osalMuxIntcSetup(&muxInParams, &muxOutParams);

    EventCombiner_dispatchPlug ((((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->intrMuxCfgLink.eventId,
                                                (EventCombiner_FuncPtr)muxOutParams.muxIntcFxn, (UArg)muxOutParams.arg, TRUE);
    EventCombiner_enableEvent( (((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->intrMuxCfgLink.eventId);

    muxInParams.arg         = (uintptr_t)icssEmacHandle;
    muxInParams.muxNum      = (((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->intrMuxCfgRxPkt.intcMuxNum;
    muxInParams.muxInEvent  = (((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->intrMuxCfgRxPkt.intcMuxInEvent;
    muxInParams.muxOutEvent = (((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->intrMuxCfgRxPkt.intcMuxOutEvent;
    muxInParams.muxIntcFxn  = (MuxIntcFxn)(&ICSS_EmacRxInterruptHandler);

     ICSS_EMAC_osalMuxIntcSetup(&muxInParams, &muxOutParams);

    EventCombiner_dispatchPlug ((((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->intrMuxCfgRxPkt.eventId,
                                                (EventCombiner_FuncPtr)muxOutParams.muxIntcFxn, (UArg)muxOutParams.arg, TRUE);
    EventCombiner_enableEvent( (((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->intrMuxCfgRxPkt.eventId);

    muxInParams.arg         = (uintptr_t)icssEmacHandle;
    muxInParams.muxNum      = (((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->intrMuxCfgTxComplete.intcMuxNum;
    muxInParams.muxInEvent  = (((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->intrMuxCfgTxComplete.intcMuxInEvent;
    muxInParams.muxOutEvent = (((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->intrMuxCfgTxComplete.intcMuxOutEvent;
    muxInParams.muxIntcFxn  = (MuxIntcFxn)(&ICSS_EmacTxInterruptHandler);


     ICSS_EMAC_osalMuxIntcSetup(&muxInParams, &muxOutParams);

    EventCombiner_dispatchPlug ((((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->intrMuxCfgTxComplete.eventId,
                                                (EventCombiner_FuncPtr)muxOutParams.muxIntcFxn, (UArg)muxOutParams.arg, TRUE);
    EventCombiner_enableEvent( (((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->intrMuxCfgTxComplete.eventId);

#else

    static uint32_t cookie = 0;
    uint8_t linkIntrN = (((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->linkIntNum;

    uint8_t rxIntrN =   (((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->rxIntNum;

    uint8_t txIntrN =   (((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->txIntNum;

    cookie = ICSS_EMAC_osalHardwareIntDisable();

    EventCombiner_dispatchPlug (linkIntrN, (EventCombiner_FuncPtr)ICSS_EmacLinkISR, (UArg)icssEmacHandle, TRUE);
    EventCombiner_enableEvent(linkIntrN);


    EventCombiner_dispatchPlug (rxIntrN, (EventCombiner_FuncPtr)ICSS_EmacRxInterruptHandler, (UArg)icssEmacHandle, TRUE);
    EventCombiner_enableEvent(rxIntrN);

    EventCombiner_dispatchPlug (txIntrN, (EventCombiner_FuncPtr)ICSS_EmacTxInterruptHandler, (UArg)icssEmacHandle, TRUE);

    EventCombiner_enableEvent(txIntrN);
    ICSS_EMAC_osalHardwareIntRestore(cookie);

#endif

ICSS_EMAC_osalHardwareIntRestore(cookie);

}





/**
* @internal
* @brief This function enables the EMAC interrupts
*
* @param icssEmacHandle  icssEmacHandle handle to ICSS_EMAC Instance.
*
* @retval none
*/
void ICSS_EMAC_testInterruptEnable(ICSS_EmacHandle icssEmacHandle)
{
    uint32_t key = 0;
    if (icssEmacHandle != NULL)
    {
        key = ICSS_EMAC_osalHardwareIntDisable();
    
        ICSS_EMAC_osalHardwareInterruptEnable((((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->linkIntNum);
        ICSS_EMAC_osalHardwareInterruptEnable((((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->rxIntNum);
        ICSS_EMAC_osalHardwareInterruptEnable((((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->txIntNum);
    
        ICSS_EMAC_osalHardwareIntRestore(key);
    }
}
/**
* @brief This function disables the EMAC interrupts
* @internal
* @param icssEmacHandle  icssEmacHandle handle to ICSS_EMAC Instance.
*
* @retval none
*/
void ICSS_EMAC_testInterruptDisable(ICSS_EmacHandle icssEmacHandle)
{
    uint32_t key = 0;
    if (icssEmacHandle != NULL)
    {
        uint8_t linkIntrN = (((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->linkIntNum;
        uint8_t rxIntrN =   (((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->rxIntNum;

      
        uint8_t txIntrN =   (((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->txIntNum;

        key = ICSS_EMAC_osalHardwareIntDisable();

        EventCombiner_disableEvent(linkIntrN);
        EventCombiner_disableEvent(rxIntrN);
        EventCombiner_disableEvent(txIntrN);

        ICSS_EMAC_osalHardwareIntRestore(key);
    }
}
#endif


/*
 *     ---function to create TTS Semaphores---
 */
int8_t    ICSS_EMAC_testTtsSemCreate()
{
    SemaphoreP_Params semParams;

    /*    Creating semaphores for TTS Task Port 1    */

    ICSS_EMAC_osalSemParamsInit(&semParams);
    semParams.mode = SemaphoreP_Mode_COUNTING;
    semParams.name = "ttsPort1TxSemaphore";
    ICSS_EMAC_testTtsP1TxSem =  ICSS_EMAC_osalCreateBlockingLock(0, &semParams);
    if(ICSS_EMAC_testTtsP1TxSem == NULL)
    {
            return -1;
    }

    ICSS_EMAC_osalSemParamsInit(&semParams);
    semParams.mode = SemaphoreP_Mode_COUNTING;
    semParams.name = "ttsPort1TimestampSemaphore";
    ICSS_EMAC_testTtsP1TimeSem =  ICSS_EMAC_osalCreateBlockingLock(0, &semParams);
    if(ICSS_EMAC_testTtsP1TimeSem == NULL)
    {
            return -1;
    }

    ICSS_EMAC_osalSemParamsInit(&semParams);
    semParams.mode = SemaphoreP_Mode_COUNTING;
    semParams.name = "ttsPort1ResultSemaphore";
    ICSS_EMAC_testTtsP1ResultSem =  ICSS_EMAC_osalCreateBlockingLock(0, &semParams);
    if(ICSS_EMAC_testTtsP1ResultSem == NULL)
    {
            return -1;
    }

    /*    Creating semaphores for TTS Task Port 2    */

    ICSS_EMAC_osalSemParamsInit(&semParams);
    semParams.mode = SemaphoreP_Mode_COUNTING;
    semParams.name = "ttsPort2TxSemaphore";
    ICSS_EMAC_testTtsP2TxSem =  ICSS_EMAC_osalCreateBlockingLock(0, &semParams);
    if(ICSS_EMAC_testTtsP2TxSem == NULL)
    {
            return -1;
    }

    ICSS_EMAC_osalSemParamsInit(&semParams);
    semParams.mode = SemaphoreP_Mode_COUNTING;
    semParams.name = "ttsPort2TimestampSemaphore";
    ICSS_EMAC_testTtsP2TimeSem =  ICSS_EMAC_osalCreateBlockingLock(0, &semParams);
    if(ICSS_EMAC_testTtsP2TimeSem == NULL)
    {
            return -1;
    }

    ICSS_EMAC_osalSemParamsInit(&semParams);
    semParams.mode = SemaphoreP_Mode_COUNTING;
    semParams.name = "ttsPort2ResultSemaphore";
    ICSS_EMAC_testTtsP2ResultSem =  ICSS_EMAC_osalCreateBlockingLock(0, &semParams);
    if(ICSS_EMAC_testTtsP2ResultSem == NULL)
    {
            return -1;
    }

    return 0;
}

#ifndef __LINUX_USER_SPACE
/* Entry point for PollControlTask */
void ICSS_EMAC_testPollControlTask(UArg a0, UArg a1)
{
     while (1)
    {
        if (ICSS_EMAC_testHandle)
        {
            ICSS_EmacPollControl(ICSS_EMAC_testHandle, ICSS_EMAC_POLL_MODE_LINK | ICSS_EMAC_POLL_MODE_TX_COMPLETE | ICSS_EMAC_POLL_MODE_RX_PKT);
        }
        if (ICSS_EMAC_testHandle1)
        {
            ICSS_EmacPollControl(ICSS_EMAC_testHandle1, ICSS_EMAC_POLL_MODE_LINK | ICSS_EMAC_POLL_MODE_TX_COMPLETE | ICSS_EMAC_POLL_MODE_RX_PKT);
        }
        if (ICSS_EMAC_testHandle2)
        {
            ICSS_EmacPollControl(ICSS_EMAC_testHandle2, ICSS_EMAC_POLL_MODE_LINK | ICSS_EMAC_POLL_MODE_TX_COMPLETE | ICSS_EMAC_POLL_MODE_RX_PKT);
        }
        if (ICSS_EMAC_testHandle3)
        {
            ICSS_EmacPollControl(ICSS_EMAC_testHandle3, ICSS_EMAC_POLL_MODE_LINK | ICSS_EMAC_POLL_MODE_TX_COMPLETE | ICSS_EMAC_POLL_MODE_RX_PKT);
        }
        Task_yield();
    }
}
#endif
/*
 *     ---function to destryoy TTS Semaphores---
 */
void    ICSS_EMAC_testTtsSemDestroy()
{
    /*    Destroying semaphores for TTS Task Port 1    */
    ICSS_EMAC_osalDeleteBlockingLock(ICSS_EMAC_testTtsP1TxSem);
    ICSS_EMAC_osalDeleteBlockingLock(ICSS_EMAC_testTtsP1TimeSem);
    ICSS_EMAC_osalDeleteBlockingLock(ICSS_EMAC_testTtsP1ResultSem);
    /*    Destroying semaphores for TTS Task Port 2    */
    ICSS_EMAC_osalDeleteBlockingLock(ICSS_EMAC_testTtsP2TxSem);
    ICSS_EMAC_osalDeleteBlockingLock(ICSS_EMAC_testTtsP2TimeSem);
    ICSS_EMAC_osalDeleteBlockingLock(ICSS_EMAC_testTtsP2ResultSem);
}

#ifdef __LINUX_USER_SPACE
static void clear_TTS_int_if_set(ICSS_EmacHandle icssEmacHandle) {
    fd_set rfds;
    struct timeval tv;
    int retval;

    FD_ZERO(&rfds);
    FD_SET(((ICSS_EmacObject*)icssEmacHandle->object)->ttsCycInt_fd, &rfds);

    tv.tv_sec = 0;
    tv.tv_usec = 0;

    retval = select(((ICSS_EmacObject*)icssEmacHandle->object)->ttsCycInt_fd + 1, &rfds, NULL, NULL, &tv);

    if (retval == -1) {
        PRINT("In TTSInit(): Error calling select()\n");
    } else if (retval) {
        //PRINT("In TTSInit(): TTS int already set\n");
        wait_interrupt(((ICSS_EmacObject*)icssEmacHandle->object)->pruss_drv_handle,
                                             (((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->txIntNum,
                       ((ICSS_EmacObject*)icssEmacHandle->object)->ttsCycInt_fd);
    } else {
        //PRINT("In TTSInit(): TTS int not already set\n");
    }
}
#endif

//#define DEBUG_TIMING_PRUSS
#ifdef DEBUG_TIMING_PRUSS
uint32_t int_arr_drv_port1[10005];
uint32_t int_arr_drv_port2[10005];
uint32_t index_port1, index_port2;
#endif
/*
 *    --- TTS Unit Test Task Port 1---
 */
#ifdef __LINUX_USER_SPACE
void *ICSS_EMAC_testPort1TxTask(void *a0)
#else
void ICSS_EMAC_testPort1TxTask(UArg a0, UArg a1)
#endif
{
    uint32_t j = 0;
    uint32_t k = 0;
    //uint8_t ret = 0;
    int32_t ret = 0;

    uint8_t portNumber;
    uint32_t *addr = 0;
    uint32_t cyclePeriod;
    uint8_t tts_error = 0;
    uint32_t timestamp = 0;
    uint32_t max_jitter = 0;
    uint32_t q1_pkt_cnt = 0;
    uint32_t q2_pkt_cnt = 0;
    uint32_t t_delta_quo = 0;
    uint32_t t_delta_rem = 0;
    ICSS_EmacTTSQuery ttsQuery;
    ICSS_EmacTxArgument txArgs;
    uint32_t pkt_period_avg = 0;
    uint64_t pkt_period_sum = 0;
    uint32_t timestamp_prev = 0;
    uint32_t timestamp_delta = 0;
    ICSS_EmacTTSConfig ttsConfig;
    ICSSEMAC_IoctlCmd ioctlParams;
    ICSSEMAC_IoctlCmd ioctlParams2;
    ICSS_EmacHandle icssEmacHandle;
    uint32_t missed_cycle_count = 0;
    uint32_t pkt_missed_cycle_cnt = 0;

#ifdef DEBUG_TIMING_PRUSS
    uint32_t int_timestamp_pend[10000];
    uint32_t int_timestamp_arr[10000];
    uint32_t queue_timestamp_arr[10000];
    uint32_t acyclic_queue_timestamp_arr[10000];
    uint32_t send_timestamp_arr[10000];
    uint32_t rx_timestamp_arr[10000];

    uint32_t max_int = 0;
    uint32_t max_queue_cyclic = 0;
    uint32_t max_int_and_queue_cyclic = 0;
    uint32_t max_queue_acyclic = 0;
    uint32_t max_int_and_queue = 0;
    uint32_t max_pkt_rx = 0;
    uint32_t max_post_rx = 0;

    uint32_t min_int = 0xFFFFFFFF;
    uint32_t min_queue_cyclic = 0xFFFFFFFF;
    uint32_t min_queue_acyclic = 0xFFFFFFFF;
    uint32_t min_int_and_queue_cyclic = 0xFFFFFFFF;
    uint32_t min_int_and_queue = 0xFFFFFFFF;
    uint32_t min_pkt_rx = 0xFFFFFFFF;
    uint32_t min_post_rx = 0xFFFFFFFF;

    char timestamp_filename[50];
    char benchmark_filename[50];

    extern uint32_t cycle_period_port1;
    extern uint32_t config_time;
    extern uint32_t num_iteration;
    sprintf(timestamp_filename, "timestamps_port1_iter%d_cycle%d_cfg%d", num_iteration, cycle_period_port1, config_time);
    sprintf(benchmark_filename, "benchmark_port1_iter%d_cycle%d_cfg%d", num_iteration, cycle_period_port1, config_time);

    FILE *timestamp_file = fopen(timestamp_filename, "w+");
    FILE *benchmark_file = fopen(benchmark_filename, "w+");

    fprintf(benchmark_file, "index min_int_latency_drv max_int_latency_drv min_int max_int min_int_latency_diff max_int_latency_diff min_queue_cyclic max_queue_cyclic min_pkt_rx max_pkt_rx min_post_rx max_post_rx \n");

    index_port1 = 0;
#endif

    /*    Wait for TTS Test to be started    */
    while(!ICSS_EMAC_testTtsModePort1)
    {
        SLEEP(1);
    }

    /*    Initialize TTS Parameters    */
    if(ICSS_EMAC_testEvmType == ICSS_EMAC_TEST_BOARD_IDKAM571x)
    {
        icssEmacHandle = ICSS_EMAC_testHandle;
    }
     else if(ICSS_EMAC_testEvmType == ICSS_EMAC_TEST_BOARD_ICEV2AM335x)
    {
        icssEmacHandle = ICSS_EMAC_testHandle;
    }
    else
    {
        icssEmacHandle = ICSS_EMAC_testHandle2;
    }

    portNumber = ICSS_EMAC_PORT_1;

#ifdef __LINUX_USER_SPACE
    extern uint32_t cycle_period_port1;
    cyclePeriod = cycle_period_port1;
#else
    cyclePeriod = ICSS_EMAC_TEST_TTS_CYCLE_PERIOD_PORT1;
#endif

    assert((icssEmacHandle == ICSS_EMAC_testHandle) || (icssEmacHandle == ICSS_EMAC_testHandle2));

    ttsQuery.icssEmacHandle = icssEmacHandle;
    ttsQuery.portNumber = portNumber;
    ttsQuery.statusTTS = 0;
    ttsQuery.insertCycFrameNotification = 0;
    ttsQuery.cycTxSOFStatus = 0;
    ttsQuery.missedCycleCounter = 0;
    ttsQuery.cycTxSOF = 0;
    ioctlParams.command = 0;
    ioctlParams.ioctlVal = (void *)(&ttsQuery);

    txArgs.icssEmacHandle = icssEmacHandle;
    txArgs.portNumber = portNumber;

    /*    Test for multiple period values    */
#ifdef __LINUX_USER_SPACE
    extern uint32_t num_iteration;
    while(k < num_iteration)
#else
    while(k < 10)
#endif
    {
#ifdef __LINUX_USER_SPACE
        sem_init((sem_t*)ICSS_EMAC_testTtsP1TxSem, 0, 0);
#endif

        /*    Initialize time triggered send on PRU    */
        ICSS_EMAC_testTtsInit(icssEmacHandle, cyclePeriod);
        ICSS_EMAC_testTtsStartPort1 = 1;

        /*    Queueing packets    */
        while(j < ICSS_EMAC_TEST_TTS_MAX_CYC_PKT_COUNT)
        {
            j++;

#ifdef DEBUG_TIMING_PRUSS
            int_timestamp_pend[q1_pkt_cnt] = HW_RD_REG32((((ICSS_EmacHwAttrs*)icssEmacHandle->hwAttrs)->emacBaseAddrCfg)->prussIepRegs  + CSL_ICSSIEP_COUNT_REG0);
#endif
            /*    Wait for cyclic packet insertion interrupt from PRU    */
            ICSS_EMAC_osalPendLock(ICSS_EMAC_testTtsP1TxSem, SemaphoreP_WAIT_FOREVER);

#ifdef DEBUG_TIMING_PRUSS
            int_timestamp_arr[q1_pkt_cnt] = HW_RD_REG32((((ICSS_EmacHwAttrs*)icssEmacHandle->hwAttrs)->emacBaseAddrCfg)->prussIepRegs  + CSL_ICSSIEP_COUNT_REG0);
#endif

            /*    Inserting cyclic packet count in pkt and transmitting    */
            addr = (uint32_t *)&(ICSS_EMAC_testArpPktPort1[ICSS_EMAC_TEST_ARP_PKT_SIZE_PORT1 - 4]);
            *addr = (q1_pkt_cnt+1);
            txArgs.lengthOfPacket = ICSS_EMAC_TEST_ARP_PKT_SIZE_PORT1;
            txArgs.queuePriority = ICSS_EMAC_QUEUE1;
            txArgs.srcAddress = &ICSS_EMAC_testArpPktPort1[0];
            ret = ICSS_EmacTxPacket(&txArgs, NULL);
            assert(ret != -1);
            q1_pkt_cnt++;

#ifdef DEBUG_TIMING_PRUSS
            queue_timestamp_arr[q1_pkt_cnt-1] = HW_RD_REG32((((ICSS_EmacHwAttrs*)icssEmacHandle->hwAttrs)->emacBaseAddrCfg)->prussIepRegs  + CSL_ICSSIEP_COUNT_REG0);
#endif

            /*    Inserting acyclic packet count in pkt and transmitting    */
            /*    Acyclic packet is sent after every few cycles    */
            if(q1_pkt_cnt%(ICSS_EMAC_TEST_TTS_MAX_CYC_PKT_COUNT/ICSS_EMAC_TEST_TTS_MAX_ACYC_PKT_COUNT) == 0)
            {
                addr = (uint32_t *)&(ICSS_EMAC_testUdpPktPort1[ICSS_EMAC_TEST_UDP_PKT_SIZE_PORT1 - 4]);
                *addr = (q2_pkt_cnt+1);
                txArgs.lengthOfPacket = ICSS_EMAC_TEST_UDP_PKT_SIZE_PORT1;
                txArgs.queuePriority = ICSS_EMAC_QUEUE2;
                txArgs.srcAddress = &ICSS_EMAC_testUdpPktPort1[0];
                ret = ICSS_EmacTxPacket(&txArgs, NULL);
                if(ret != -1)
                    q2_pkt_cnt++;
            }

#ifdef DEBUG_TIMING_PRUSS
            acyclic_queue_timestamp_arr[q1_pkt_cnt-1] = HW_RD_REG32((((ICSS_EmacHwAttrs*)icssEmacHandle->hwAttrs)->emacBaseAddrCfg)->prussIepRegs  + CSL_ICSSIEP_COUNT_REG0);
#endif

            /*    Wait for RX interrupt from PRU    */
            ICSS_EMAC_osalPendLock(ICSS_EMAC_testTtsP1TimeSem, SemaphoreP_WAIT_FOREVER);

#ifdef DEBUG_TIMING_PRUSS
            rx_timestamp_arr[q1_pkt_cnt-1] = HW_RD_REG32((((ICSS_EmacHwAttrs*)icssEmacHandle->hwAttrs)->emacBaseAddrCfg)->prussIepRegs  + CSL_ICSSIEP_COUNT_REG0);
#endif

            /*    Query TTS status and timestamp from PRU    */
            ret = ICSS_EmacIoctl(icssEmacHandle, ICSS_EMAC_IOCTL_TTS_STATUS_CTRL, portNumber, &ioctlParams);
            assert(ret == 0);
            timestamp = ttsQuery.cycTxSOF;
            assert(timestamp_prev != timestamp);
#ifdef DEBUG_TIMING_PRUSS
            send_timestamp_arr[q1_pkt_cnt-1] = timestamp;
#endif


            if(1 != q1_pkt_cnt)
            {
                /*    Process cyclic packet timestamp    */
                /*    For second cyclic pkt onwards, start processing    */
#if defined(SOC_AM572x)
                if(ICSS_EMAC_testPgVersion >= 2)    /* 64-bit IEP    */
                {
                    timestamp_delta = timestamp - timestamp_prev;
                }
                else
                {
                    if(timestamp < timestamp_prev)    /* 32-bit IEP    */
                    {
                        timestamp_delta = (ICSS_EMAC_TTS_IEP_MAX_VAL - timestamp_prev) + timestamp;
                    }
                    else
                    {
                        timestamp_delta = timestamp - timestamp_prev;
                    }
                }
#elif defined(SOC_AM571x)
                timestamp_delta = timestamp - timestamp_prev;
#elif defined(SOC_AM437x) || defined(SOC_AM335x)

                 /*Process cyclic packet timestamp */
                /*      For second cyclic pkt onwards, start processing */
                if(timestamp < timestamp_prev)  /* 32-bit IEP   */
                {
                    timestamp_delta = (ICSS_EMAC_TTS_IEP_MAX_VAL - timestamp_prev) + timestamp;
                }
                else
                {
                    timestamp_delta = timestamp - timestamp_prev;
                 }
#endif

                /*    Check if delta is acceptable    */
                if(abs(timestamp_delta - cyclePeriod) <= ICSS_EMAC_TEST_TTS_PERIOD_MARGIN)
                {
                    pkt_period_sum += timestamp_delta;
                    pkt_period_avg = (uint32_t)(pkt_period_sum/(q1_pkt_cnt - 1));
                    if(abs(timestamp_delta - cyclePeriod) > max_jitter)
                        max_jitter = abs(timestamp_delta - cyclePeriod);
                }
                else
                {
                    t_delta_rem = timestamp_delta % cyclePeriod;
                    t_delta_quo = timestamp_delta / cyclePeriod;
                    if((t_delta_rem <= ICSS_EMAC_TEST_TTS_PERIOD_MARGIN) || (t_delta_rem >= (cyclePeriod - ICSS_EMAC_TEST_TTS_PERIOD_MARGIN)))
                    {
                        pkt_missed_cycle_cnt += t_delta_quo;
                        pkt_period_sum += cyclePeriod;
                        pkt_period_avg = (uint32_t)(pkt_period_sum/q1_pkt_cnt);
                    }
                    else
                    {
                        PRINT("\n============================================================");
                        PRINT("\nTTS Port 1: Packet cyclic timestamp error.");
                        PRINT("\nProgrammed Cycle Period: %u ns", cyclePeriod);
                        PRINT("\nTimestamp_prev: %u ns\nTimestamp: %u ns\nDelta: %u ns", timestamp_prev, timestamp, timestamp_delta);
                        PRINT("\nCyclic Packet Number: %u", q1_pkt_cnt);
                        tts_error = 1;
                        break;
                    }
                }
            }
            timestamp_prev = timestamp;
        }

        if(!tts_error)
        {
            /*    Wait for any queued packets to be received    */
            ICSS_EMAC_osalPendLock(ICSS_EMAC_testTtsP1ResultSem, SemaphoreP_WAIT_FOREVER);

            /*    Setting tts status to disable (Port 1)    */
            ttsConfig.icssEmacHandle = icssEmacHandle;
            ttsConfig.statusTTS = ICSS_EMAC_TTS_DISABLE;
            ttsConfig.cyclePeriod = 0;
            ttsConfig.configTime = 0;
            ttsConfig.cycleStartTime = 0;
            ttsConfig.cycTxSOFStatus = ICSS_EMAC_TTS_CYC_TXSOF_DISABLE;
            ttsConfig.portNumber = portNumber;
            ioctlParams2.command = 0;
            ioctlParams2.ioctlVal = (void *)(&ttsConfig);

            /*    Disabling time triggered send on PORT 1 (PRU0).    */
            ret = ICSS_EmacIoctl(icssEmacHandle, ICSS_EMAC_IOCTL_TTS_CTRL, portNumber, &ioctlParams2);
            assert(ret == 0);

            ret = ICSS_EmacIoctl(icssEmacHandle, ICSS_EMAC_IOCTL_TTS_STATUS_CTRL, portNumber, &ioctlParams);
            assert(ret == 0);

            missed_cycle_count = ttsQuery.missedCycleCounter;

            /*    Wait for any packets to be received and for test to be finished on other PRU    */
            while((!((q1_pkt_cnt == ICSS_EMAC_testRecv_Q1PktCntPort1) && (q2_pkt_cnt == ICSS_EMAC_testRecv_Q2PktCntPort1) && ((missed_cycle_count - pkt_missed_cycle_cnt) <= 20))) || ICSS_EMAC_testTtsStartPort2)
            {
                SLEEP(1);
            }

            /*    Printing results now.    */
            if((q1_pkt_cnt == ICSS_EMAC_testRecv_Q1PktCntPort1) && (q2_pkt_cnt == ICSS_EMAC_testRecv_Q2PktCntPort1) && ((missed_cycle_count - pkt_missed_cycle_cnt) <= 20))
            {
                PRINT("\n============================================================");
                PRINT("\nTTS Port 1: Test Passed!!");
                PRINT("\nProgrammed Cycle Period: %u ns", cyclePeriod);
                PRINT("\nAverage Cycle Period: %u ns", pkt_period_avg);
                PRINT("\nMaximum Jitter: %u ns", max_jitter);
            }
            else
            {
                PRINT("\n============================================================");
                PRINT("\nTTS Port 1: Test Failed!!");
                PRINT("\nProgrammed Cycle Period: %u ns", cyclePeriod);
                PRINT("\nDisplaying results:");
                PRINT("\nNote: Missed cycles is permitted to be within a range of +/- 20.");

                PRINT("\n\nTransmit Information:");
                PRINT("\nCyclic Packets: %u", q1_pkt_cnt);
                PRINT("\nAcyclic Packets: %u", q2_pkt_cnt);
                PRINT("\nMissed Cycles: %u", pkt_missed_cycle_cnt);

                PRINT("\n\nReceive Information:");
                PRINT("\nCyclic Packets: %u", ICSS_EMAC_testRecv_Q1PktCntPort1);
                PRINT("\nAcyclic Packets: %u", ICSS_EMAC_testRecv_Q2PktCntPort1);
                PRINT("\nMissed Cycles: %u", missed_cycle_count);
            }
        }
        else
        {
            /*    Setting tts status to disable (Port 1)    */
            ttsConfig.icssEmacHandle = icssEmacHandle;
            ttsConfig.statusTTS = ICSS_EMAC_TTS_DISABLE;
            ttsConfig.cyclePeriod = 0;
            ttsConfig.configTime = 0;
            ttsConfig.cycleStartTime = 0;
            ttsConfig.cycTxSOFStatus = ICSS_EMAC_TTS_CYC_TXSOF_DISABLE;
            ttsConfig.portNumber = portNumber;
            ioctlParams2.command = 0;
            ioctlParams2.ioctlVal = (void *)(&ttsConfig);

            /*    Disabling time triggered send on PORT 1 (PRU0).    */
            ret = ICSS_EmacIoctl(icssEmacHandle, ICSS_EMAC_IOCTL_TTS_CTRL, portNumber, &ioctlParams2);
            assert(ret == 0);

            /* Wait for test to be finished on other PRU */
            while(ICSS_EMAC_testTtsStartPort2)
            {
                SLEEP(1);
            }
        }

#ifdef DEBUG_TIMING_PRUSS
    {
                int wcnt;
                fprintf(benchmark_file, "%d ", k);
                uint32_t int_from_fw, int_latency, cyclic_queue, acyclic_queue, int_and_queue, int_and_queue_cyclic;
                uint32_t pkt_rx;
                uint32_t post_rx;
                uint32_t tx_complete, min_tx_complete=0xFFFFFFFF, max_tx_complete=0;
                uint32_t int_latency_drv, min_int_latency_drv=0xFFFFFFFF, max_int_latency_drv=0;
                uint32_t int_latency_diff, min_int_latency_diff=0xFFFFFFFF, max_int_latency_diff=0;

                max_int = 0;
                max_queue_cyclic = 0;
                max_queue_acyclic = 0;
                max_int_and_queue_cyclic = 0;
                max_int_and_queue = 0;
                max_pkt_rx = 0;
                max_post_rx = 0;

                min_int = 0xFFFFFFFF;
                min_queue_cyclic = 0xFFFFFFFF;
                min_queue_acyclic = 0xFFFFFFFF;
                min_int_and_queue_cyclic = 0xFFFFFFFF;
                min_int_and_queue = 0xFFFFFFFF;
                min_pkt_rx = 0xFFFFFFFF;
                min_post_rx = 0xFFFFFFFF;

                if(k<10) fprintf(timestamp_file, "int_timestamp_pend int_from_fw int_arr_drv_port1 int_timestamp_arr queue_timestamp_arr send_timestamp_arr rx_timestamp_arr int_latency_drv int_latency int_latency_diff cyclic_queue pkt_rx post_rx\n");
                for (wcnt = 1; wcnt < 10000; wcnt++) {

                    int_from_fw = send_timestamp_arr[wcnt] - config_time;
                    int_latency = int_timestamp_arr[wcnt] - int_from_fw;
                    cyclic_queue = queue_timestamp_arr[wcnt] - int_timestamp_arr[wcnt];
                    acyclic_queue = acyclic_queue_timestamp_arr[wcnt] - queue_timestamp_arr[wcnt];
                    int_and_queue_cyclic = int_latency + cyclic_queue;

                    if(int_latency > max_int) max_int = int_latency;
                    if(cyclic_queue > max_queue_cyclic) max_queue_cyclic = cyclic_queue;
                    if(acyclic_queue > max_queue_acyclic) max_queue_acyclic = acyclic_queue;
                    if(int_and_queue_cyclic > max_int_and_queue_cyclic) max_int_and_queue_cyclic = int_and_queue_cyclic;

                    if(int_latency < min_int) min_int = int_latency;
                    if(cyclic_queue < min_queue_cyclic) min_queue_cyclic = cyclic_queue;
                    if(acyclic_queue < min_queue_acyclic) min_queue_acyclic = acyclic_queue;
                    if(int_and_queue_cyclic < min_int_and_queue_cyclic) min_int_and_queue_cyclic = int_and_queue_cyclic;

                    int_latency_drv = int_arr_drv_port1[wcnt] - int_from_fw;
                    if (int_latency_drv < min_int_latency_drv) min_int_latency_drv = int_latency_drv;
                    if (int_latency_drv > max_int_latency_drv) max_int_latency_drv = int_latency_drv;

                    int_latency_diff = int_timestamp_arr[wcnt] -  int_arr_drv_port1[wcnt];
                    if (int_latency_diff < min_int_latency_diff) min_int_latency_diff = int_latency_diff;
                    if (int_latency_diff > max_int_latency_diff) max_int_latency_diff = int_latency_diff;

                    pkt_rx = rx_timestamp_arr[wcnt] - send_timestamp_arr[wcnt];
                    if(pkt_rx > max_pkt_rx)  max_pkt_rx = pkt_rx;
                    if(pkt_rx < min_pkt_rx) min_pkt_rx = pkt_rx;

                    if (wcnt>0)
                    {
                       post_rx = int_timestamp_pend[wcnt] - rx_timestamp_arr[wcnt-1];
                       if (post_rx > max_post_rx) max_post_rx = post_rx;
                       if (post_rx < min_post_rx) min_post_rx = post_rx;
                    }
                    if(k<10) fprintf(timestamp_file, "%u %u %u %u %u %u %u %u %u %u %u %u %u\n", int_timestamp_pend[wcnt], int_from_fw, int_arr_drv_port1[wcnt], int_timestamp_arr[wcnt], queue_timestamp_arr[wcnt], send_timestamp_arr[wcnt], rx_timestamp_arr[wcnt], int_latency_drv, int_latency, int_latency_diff, cyclic_queue, pkt_rx, post_rx);
                }

                if(!tts_error) {
                    fprintf(benchmark_file, "%u %u %u %u %u %u %u %u %u %u %u %u\n", min_int_latency_drv, max_int_latency_drv, min_int, max_int, min_int_latency_diff, max_int_latency_diff, min_queue_cyclic, max_queue_cyclic, min_pkt_rx, max_pkt_rx, min_post_rx, max_post_rx);
                } else {
                    fprintf(benchmark_file, "Test Failed!!!\n");
                }
       index_port1 = 0;
    }
#endif

        /*    Init next round of testing    */
        k++;
#ifndef __LINUX_USER_SPACE
        cyclePeriod +=    ICSS_EMAC_TEST_TTS_CYCLE_PERIOD_PORT1;
#endif
        q1_pkt_cnt = 0;
        q2_pkt_cnt = 0;
        j = 0;
        pkt_period_avg = 0;
        pkt_period_sum = 0;
        timestamp_delta = 0;
        t_delta_quo = 0;
        t_delta_rem = 0;
        max_jitter = 0;
        pkt_missed_cycle_cnt = 0;
        timestamp = 0;
        timestamp_prev = 0;
        missed_cycle_count = 0;
        ret = 0;
        tts_error = 0;

        /*    Signal PRU1 to print the results    */
        ICSS_EMAC_testTtsStartPort1 = 0;

        /*    Wait for results to be printed for the PRU1    */
        SLEEP(1);
    }
    ICSS_EMAC_testTtsModePort1 = 0;
}


/*
 *    --- TTS Unit Test Task Port 2---
 */
#ifdef __LINUX_USER_SPACE
void *ICSS_EMAC_testPort2TxTask(void *a0)
#else
void ICSS_EMAC_testPort2TxTask(UArg a0, UArg a1)
#endif
{
    uint32_t j = 0;
    uint32_t k = 0;
    int32_t ret = 0;
    uint8_t portNumber;
    uint32_t *addr = 0;
    uint32_t cyclePeriod;
    uint8_t tts_error = 0;
    uint32_t timestamp = 0;
    uint32_t max_jitter = 0;
    uint32_t q1_pkt_cnt = 0;
    uint32_t q2_pkt_cnt = 0;
    uint32_t t_delta_quo = 0;
    uint32_t t_delta_rem = 0;
    ICSS_EmacTTSQuery ttsQuery;
    ICSS_EmacTxArgument txArgs;
    uint32_t pkt_period_avg = 0;
    uint64_t pkt_period_sum = 0;
    uint32_t timestamp_prev = 0;
    uint32_t timestamp_delta = 0;
    ICSS_EmacTTSConfig ttsConfig;
    ICSSEMAC_IoctlCmd ioctlParams;
    ICSSEMAC_IoctlCmd ioctlParams2;
    ICSS_EmacHandle icssEmacHandle;
    uint32_t missed_cycle_count = 0;
    uint32_t pkt_missed_cycle_cnt = 0;


#ifdef DEBUG_TIMING_PRUSS
    uint32_t int_timestamp_pend[10000];
    uint32_t int_timestamp_arr[10000];
    uint32_t queue_timestamp_arr[10000];
    uint32_t acyclic_queue_timestamp_arr[10000];
    uint32_t send_timestamp_arr[10000];
    uint32_t rx_timestamp_arr[10000];

    uint32_t max_int = 0;
    uint32_t max_queue_cyclic = 0;
    uint32_t max_int_and_queue_cyclic = 0;
    uint32_t max_queue_acyclic = 0;
    uint32_t max_int_and_queue = 0;
    uint32_t max_pkt_rx = 0;
    uint32_t max_post_rx = 0;

    uint32_t min_int = 0xFFFFFFFF;
    uint32_t min_queue_cyclic = 0xFFFFFFFF;
    uint32_t min_queue_acyclic = 0xFFFFFFFF;
    uint32_t min_int_and_queue_cyclic = 0xFFFFFFFF;
    uint32_t min_int_and_queue = 0xFFFFFFFF;
    uint32_t min_pkt_rx = 0xFFFFFFFF;
    uint32_t min_post_rx = 0xFFFFFFFF;

    char timestamp_filename[50];
    char benchmark_filename[50];

    extern uint32_t cycle_period_port2;
    extern uint32_t config_time;
    extern uint32_t num_iteration;

    sprintf(timestamp_filename, "timestamps_port2_iter%d_cycle%d_cfg%d", num_iteration, cycle_period_port2, config_time);
    sprintf(benchmark_filename, "benchmark_port2_iter%d_cycle%d_cfg%d", num_iteration, cycle_period_port2, config_time);

    FILE *timestamp_file = fopen(timestamp_filename, "w+");
    FILE *benchmark_file = fopen(benchmark_filename, "w+");

    fprintf(benchmark_file, "index min_int_latency_drv max_int_latency_drv min_int max_int min_int_latency_diff max_int_latency_diff min_queue_cyclic max_queue_cyclic min_pkt_rx max_pkt_rx min_post_rx max_post_rx \n");

    index_port2 = 0;
#endif
    /*    Wait for TTS Test to be started    */
    while(!ICSS_EMAC_testTtsModePort2)
    {
        SLEEP(1);
    }

    /*    Initialize TTS Parameters    */
    if(ICSS_EMAC_testEvmType == ICSS_EMAC_TEST_BOARD_IDKAM571x)
    {
        icssEmacHandle = ICSS_EMAC_testHandle1;
    }
     else if(ICSS_EMAC_testEvmType == ICSS_EMAC_TEST_BOARD_ICEV2AM335x)
    {
        icssEmacHandle = ICSS_EMAC_testHandle1;
    }
    else
    {
        icssEmacHandle = ICSS_EMAC_testHandle3;
    }
    portNumber = ICSS_EMAC_PORT_2;

#ifdef __LINUX_USER_SPACE
    extern uint32_t cycle_period_port2;
    cyclePeriod = cycle_period_port2;
#else
    cyclePeriod = ICSS_EMAC_TEST_TTS_CYCLE_PERIOD_PORT2;
#endif
    assert((icssEmacHandle == ICSS_EMAC_testHandle1) || (icssEmacHandle == ICSS_EMAC_testHandle3));

    ttsQuery.icssEmacHandle = icssEmacHandle;
    ttsQuery.portNumber = portNumber;
    ttsQuery.statusTTS = 0;
    ttsQuery.insertCycFrameNotification = 0;
    ttsQuery.cycTxSOFStatus = 0;
    ttsQuery.missedCycleCounter = 0;
    ttsQuery.cycTxSOF = 0;
    ioctlParams.command = 0;
    ioctlParams.ioctlVal = (void *)(&ttsQuery);

    txArgs.icssEmacHandle = icssEmacHandle;
    txArgs.portNumber = portNumber;

    /*    Test for multiple period values    */
#ifdef __LINUX_USER_SPACE
    extern uint32_t num_iteration;
    while(k < num_iteration)
#else
    while(k < 10)
#endif
    {
        /*    Wait for Port 1 TTS Init    */
        while(ICSS_EMAC_testTtsStartPort1 == 0)
        {
            SLEEP(1);
        }

#ifdef __LINUX_USER_SPACE
        sem_init((sem_t*)ICSS_EMAC_testTtsP2TxSem, 0, 0);
#endif

        /*    Initialize time triggered send on PRU    */
        ICSS_EMAC_testTtsInit(icssEmacHandle, cyclePeriod);
        ICSS_EMAC_testTtsStartPort2 = 1;

        /*    Queueing packets    */
        while(j < ICSS_EMAC_TEST_TTS_MAX_CYC_PKT_COUNT)
        {
            j++;

#ifdef DEBUG_TIMING_PRUSS
            int_timestamp_pend[q1_pkt_cnt] = HW_RD_REG32((((ICSS_EmacHwAttrs*)icssEmacHandle->hwAttrs)->emacBaseAddrCfg)->prussIepRegs  + CSL_ICSSIEP_COUNT_REG0);
#endif
            /*    Wait for cyclic packet insertion interrupt from PRU    */
            ICSS_EMAC_osalPendLock(ICSS_EMAC_testTtsP2TxSem, SemaphoreP_WAIT_FOREVER);

#ifdef DEBUG_TIMING_PRUSS
            int_timestamp_arr[q1_pkt_cnt] = HW_RD_REG32((((ICSS_EmacHwAttrs*)icssEmacHandle->hwAttrs)->emacBaseAddrCfg)->prussIepRegs  + CSL_ICSSIEP_COUNT_REG0);
#endif

            /*    Inserting cyclic packet count in pkt and transmitting    */
            addr = (uint32_t *)&(ICSS_EMAC_testArpPktPort2[ICSS_EMAC_TEST_ARP_PKT_SIZE_PORT2 - 4]);
            *addr = (q1_pkt_cnt+1);
            txArgs.lengthOfPacket = ICSS_EMAC_TEST_ARP_PKT_SIZE_PORT2;
            txArgs.queuePriority = ICSS_EMAC_QUEUE1;
            txArgs.srcAddress = &ICSS_EMAC_testArpPktPort2[0];
            ret = ICSS_EmacTxPacket(&txArgs, NULL);
            assert(ret != -1);
            q1_pkt_cnt++;

#ifdef DEBUG_TIMING_PRUSS
            queue_timestamp_arr[q1_pkt_cnt-1] = HW_RD_REG32((((ICSS_EmacHwAttrs*)icssEmacHandle->hwAttrs)->emacBaseAddrCfg)->prussIepRegs  + CSL_ICSSIEP_COUNT_REG0);
#endif

            /*    Inserting acyclic packet count in pkt and transmitting    */
            /*    Acyclic packet is sent after every few cycles    */
            if(q1_pkt_cnt%(ICSS_EMAC_TEST_TTS_MAX_CYC_PKT_COUNT/ICSS_EMAC_TEST_TTS_MAX_ACYC_PKT_COUNT) == 0)
            {
                addr = (uint32_t *)&(ICSS_EMAC_testUdpPktPort2[ICSS_EMAC_TEST_UDP_PKT_SIZE_PORT2 - 4]);
                *addr = (q2_pkt_cnt+1);
                txArgs.lengthOfPacket = ICSS_EMAC_TEST_UDP_PKT_SIZE_PORT2;
                txArgs.queuePriority = ICSS_EMAC_QUEUE2;
                txArgs.srcAddress = &ICSS_EMAC_testUdpPktPort2[0];
                ret = ICSS_EmacTxPacket(&txArgs, NULL);
                if(ret != -1)
                    q2_pkt_cnt++;
            }

#ifdef DEBUG_TIMING_PRUSS
            acyclic_queue_timestamp_arr[q1_pkt_cnt-1] = HW_RD_REG32((((ICSS_EmacHwAttrs*)icssEmacHandle->hwAttrs)->emacBaseAddrCfg)->prussIepRegs  + CSL_ICSSIEP_COUNT_REG0);
#endif

            /*    Wait for RX interrupt from PRU    */
            ICSS_EMAC_osalPendLock(ICSS_EMAC_testTtsP2TimeSem, SemaphoreP_WAIT_FOREVER);

#ifdef DEBUG_TIMING_PRUSS
            rx_timestamp_arr[q1_pkt_cnt-1] = HW_RD_REG32((((ICSS_EmacHwAttrs*)icssEmacHandle->hwAttrs)->emacBaseAddrCfg)->prussIepRegs  + CSL_ICSSIEP_COUNT_REG0);
#endif

            /*    Query TTS status and timestamp from PRU    */
            ret = ICSS_EmacIoctl(icssEmacHandle, ICSS_EMAC_IOCTL_TTS_STATUS_CTRL, portNumber, &ioctlParams);
            assert(ret == 0);
            timestamp = ttsQuery.cycTxSOF;
            assert(timestamp_prev != timestamp);

#ifdef DEBUG_TIMING_PRUSS
            send_timestamp_arr[q1_pkt_cnt-1] = timestamp;
#endif

            if(1 != q1_pkt_cnt)
            {
                /*    Process cyclic packet timestamp    */
                /*    For second cyclic pkt onwards, start processing    */
#ifdef SOC_AM572x
                if(ICSS_EMAC_testPgVersion >= 2)    /* 64-bit IEP    */
                {
                    timestamp_delta = timestamp - timestamp_prev;
                }
                else
                {
                    if(timestamp < timestamp_prev)    /* 32-bit IEP    */
                    {
                        timestamp_delta = (ICSS_EMAC_TTS_IEP_MAX_VAL - timestamp_prev) + timestamp;
                    }
                    else
                    {
                        timestamp_delta = timestamp - timestamp_prev;
                    }
                }
#else
                //timestamp_delta = timestamp - timestamp_prev;
#endif

#ifdef SOC_AM437x
 /*      Process cyclic packet timestamp */
                                /*      For second cyclic pkt onwards, start processing */
                                if(timestamp < timestamp_prev)  /* 32-bit IEP   */
                                {
                                        timestamp_delta = (ICSS_EMAC_TTS_IEP_MAX_VAL - timestamp_prev) + timestamp;
                                }
                                else
                                {
                                        timestamp_delta = timestamp - timestamp_prev;
                                }

#endif
                /*    Check if delta is acceptable    */
                if(abs(timestamp_delta - cyclePeriod) <= ICSS_EMAC_TEST_TTS_PERIOD_MARGIN)
                {
                    pkt_period_sum += timestamp_delta;
                    pkt_period_avg = (uint32_t)(pkt_period_sum/(q1_pkt_cnt - 1));
                    if(abs(timestamp_delta - cyclePeriod) > max_jitter)
                        max_jitter = abs(timestamp_delta - cyclePeriod);
                }
                else
                {
                    t_delta_rem = timestamp_delta % cyclePeriod;
                    t_delta_quo = timestamp_delta / cyclePeriod;
                    if((t_delta_rem <= ICSS_EMAC_TEST_TTS_PERIOD_MARGIN) || (t_delta_rem >= (cyclePeriod - ICSS_EMAC_TEST_TTS_PERIOD_MARGIN)))
                    {
                        pkt_missed_cycle_cnt += t_delta_quo;
                        pkt_period_sum += cyclePeriod;
                        pkt_period_avg = (uint32_t)(pkt_period_sum/q1_pkt_cnt);
                    }
                    else
                    {
                        PRINT("\n============================================================");
                        PRINT("\nTTS Port 2: Packet cyclic timestamp error.");
                        PRINT("\nProgrammed Cycle Period: %u ns", cyclePeriod);
                        PRINT("\nTimestamp_prev: %u ns\nTimestamp: %u ns\nDelta: %u ns", timestamp_prev, timestamp, timestamp_delta);
                        PRINT("\nCyclic Packet Number: %u", q1_pkt_cnt);
                        tts_error = 1;
                        break;
                    }
                }
            }
            timestamp_prev = timestamp;
        }

        if(!tts_error)
        {
            /*    Wait for any queued packets to be received    */
            ICSS_EMAC_osalPendLock(ICSS_EMAC_testTtsP2ResultSem, SemaphoreP_WAIT_FOREVER);

            /*    Setting tts status to disable (Port 2)    */
            ttsConfig.icssEmacHandle = icssEmacHandle;
            ttsConfig.statusTTS = ICSS_EMAC_TTS_DISABLE;
            ttsConfig.cyclePeriod = 0;
            ttsConfig.configTime = 0;
            ttsConfig.cycleStartTime = 0;
            ttsConfig.cycTxSOFStatus = ICSS_EMAC_TTS_CYC_TXSOF_DISABLE;
            ttsConfig.portNumber = portNumber;
            ioctlParams2.command = 0;
            ioctlParams2.ioctlVal = (void *)(&ttsConfig);

            /*    Disabling time triggered send on PORT 2 (PRU1).    */
            ret = ICSS_EmacIoctl(icssEmacHandle, ICSS_EMAC_IOCTL_TTS_CTRL, portNumber, &ioctlParams2);
            assert(ret == 0);

            ret = ICSS_EmacIoctl(icssEmacHandle, ICSS_EMAC_IOCTL_TTS_STATUS_CTRL, portNumber, &ioctlParams);
            assert(ret == 0);

            missed_cycle_count = ttsQuery.missedCycleCounter;

            /*    Signal PRU0 to print the results    */
            ICSS_EMAC_testTtsStartPort2 = 0;

            /*    Wait for PRU0 results to be printed    */
            /*    This is also sufficient time for any remaining packets to be recieved    */
            while(ICSS_EMAC_testTtsStartPort1)
            {
                SLEEP(1);
            }

            /*    Printing results now.    */
            if((q1_pkt_cnt == ICSS_EMAC_testRecv_Q1PktCntPort2) && (q2_pkt_cnt == ICSS_EMAC_testRecv_Q2PktCntPort2) && ((missed_cycle_count - pkt_missed_cycle_cnt) <= 20))
            {
                PRINT("\n============================================================");
                PRINT("\nTTS Port 2: Test Passed!!");
                PRINT("\nProgrammed Cycle Period: %u ns", cyclePeriod);
                PRINT("\nAverage Cycle Period: %u ns", pkt_period_avg);
                PRINT("\nMaximum Jitter: %u ns", max_jitter);
            }
            else
            {
                PRINT("\n============================================================");
                PRINT("\nTTS Port 2: Test Failed!!");
                PRINT("\nProgrammed Cycle Period: %u ns", cyclePeriod);
                PRINT("\nDisplaying results:");
                PRINT("\nNote: Missed cycles is permitted to be within a range of +/- 20.");

                PRINT("\n\nTransmit Information:");
                PRINT("\nCyclic Packets: %u", q1_pkt_cnt);
                PRINT("\nAcyclic Packets: %u", q2_pkt_cnt);
                PRINT("\nMissed Cycles: %u", pkt_missed_cycle_cnt);

                PRINT("\n\nReceive Information:");
                PRINT("\nCyclic Packets: %u", ICSS_EMAC_testRecv_Q1PktCntPort2);
                PRINT("\nAcyclic Packets: %u", ICSS_EMAC_testRecv_Q2PktCntPort2);
                PRINT("\nMissed Cycles: %u", missed_cycle_count);
            }
        }
        else
        {
            /*    Setting tts status to disable (Port 2)    */
            ttsConfig.icssEmacHandle = icssEmacHandle;
            ttsConfig.statusTTS = ICSS_EMAC_TTS_DISABLE;
            ttsConfig.cyclePeriod = 0;
            ttsConfig.configTime = 0;
            ttsConfig.cycleStartTime = 0;
            ttsConfig.cycTxSOFStatus = ICSS_EMAC_TTS_CYC_TXSOF_DISABLE;
            ttsConfig.portNumber = portNumber;
            ioctlParams2.command = 0;
            ioctlParams2.ioctlVal = (void *)(&ttsConfig);

            /*    Disabling time triggered send on PORT 2 (PRU1).    */
            ret = ICSS_EmacIoctl(icssEmacHandle, ICSS_EMAC_IOCTL_TTS_CTRL, portNumber, &ioctlParams2);
            assert(ret == 0);

            /* Signal PRU0 to print the results */
            ICSS_EMAC_testTtsStartPort2 = 0;
            /* Wait for PRU0 results to be printed	*/
            while(ICSS_EMAC_testTtsStartPort1)
            {
                SLEEP(1);
            }
        }


#ifdef DEBUG_TIMING_PRUSS
    {
                int wcnt;
                fprintf(benchmark_file, "%d ", k);
                uint32_t int_from_fw, int_latency, cyclic_queue, acyclic_queue, int_and_queue, int_and_queue_cyclic;
                uint32_t pkt_rx;
                uint32_t post_rx;
                uint32_t int_latency_drv, min_int_latency_drv=0xFFFFFFFF, max_int_latency_drv=0;
                uint32_t int_latency_diff, min_int_latency_diff=0xFFFFFFFF, max_int_latency_diff=0;

                max_int = 0;
                max_queue_cyclic = 0;
                max_queue_acyclic = 0;
                max_int_and_queue_cyclic = 0;
                max_int_and_queue = 0;
                max_pkt_rx = 0;
                max_post_rx = 0;

                min_int = 0xFFFFFFFF;
                min_queue_cyclic = 0xFFFFFFFF;
                min_queue_acyclic = 0xFFFFFFFF;
                min_int_and_queue_cyclic = 0xFFFFFFFF;
                min_int_and_queue = 0xFFFFFFFF;
                min_pkt_rx = 0xFFFFFFFF;
                min_post_rx = 0xFFFFFFFF;

                if(k<10) fprintf(timestamp_file, "int_timestamp_pend int_from_fw int_arr_drv_port2 int_timestamp_arr queue_timestamp_arr send_timestamp_arr rx_timestamp_arr int_latency_drv int_latency int_latency_diff cyclic_queue pkt_rx post_rx\n");
                for (wcnt = 1; wcnt < 10000; wcnt++) {

                    int_from_fw = send_timestamp_arr[wcnt] - config_time;
                    int_latency = int_timestamp_arr[wcnt] - int_from_fw;
                    cyclic_queue = queue_timestamp_arr[wcnt] - int_timestamp_arr[wcnt];
                    acyclic_queue = acyclic_queue_timestamp_arr[wcnt] - queue_timestamp_arr[wcnt];
                    int_and_queue_cyclic = int_latency + cyclic_queue;

                    if(int_latency > max_int) max_int = int_latency;
                    if(cyclic_queue > max_queue_cyclic) max_queue_cyclic = cyclic_queue;
                    if(acyclic_queue > max_queue_acyclic) max_queue_acyclic = acyclic_queue;
                    if(int_and_queue_cyclic > max_int_and_queue_cyclic) max_int_and_queue_cyclic = int_and_queue_cyclic;

                    if(int_latency < min_int) min_int = int_latency;
                    if(cyclic_queue < min_queue_cyclic) min_queue_cyclic = cyclic_queue;
                    if(acyclic_queue < min_queue_acyclic) min_queue_acyclic = acyclic_queue;
                    if(int_and_queue_cyclic < min_int_and_queue_cyclic) min_int_and_queue_cyclic = int_and_queue_cyclic;

                    int_latency_drv = int_arr_drv_port2[wcnt] - int_from_fw;
                    if (int_latency_drv < min_int_latency_drv) min_int_latency_drv = int_latency_drv;
                    if (int_latency_drv > max_int_latency_drv) max_int_latency_drv = int_latency_drv;

                    int_latency_diff = int_timestamp_arr[wcnt] -  int_arr_drv_port2[wcnt];
                    if (int_latency_diff < min_int_latency_diff) min_int_latency_diff = int_latency_diff;
                    if (int_latency_diff > max_int_latency_diff) max_int_latency_diff = int_latency_diff;

                    pkt_rx = rx_timestamp_arr[wcnt] - send_timestamp_arr[wcnt];
                    if(pkt_rx > max_pkt_rx)  max_pkt_rx = pkt_rx;
                    if(pkt_rx < min_pkt_rx) min_pkt_rx = pkt_rx;

                    if (wcnt>0)
                    {
                       post_rx = int_timestamp_pend[wcnt] - rx_timestamp_arr[wcnt-1];
                       if (post_rx > max_post_rx) max_post_rx = post_rx;
                       if (post_rx < min_post_rx) min_post_rx = post_rx;
                    }
                    if(k<10) fprintf(timestamp_file, "%u %u %u %u %u %u %u %u %u %u %u %u %u\n", int_timestamp_pend[wcnt], int_from_fw, int_arr_drv_port2[wcnt], int_timestamp_arr[wcnt], queue_timestamp_arr[wcnt], send_timestamp_arr[wcnt], rx_timestamp_arr[wcnt], int_latency_drv, int_latency, int_latency_diff, cyclic_queue, pkt_rx, post_rx);
                }

                if(!tts_error) {
                    fprintf(benchmark_file, "%u %u %u %u %u %u %u %u %u %u %u %u\n", min_int_latency_drv, max_int_latency_drv, min_int, max_int,  min_int_latency_diff, max_int_latency_diff, min_queue_cyclic, max_queue_cyclic, min_pkt_rx, max_pkt_rx, min_post_rx, max_post_rx);
                } else {
                    fprintf(benchmark_file, "Test Failed!!!\n");
                }
        index_port2 = 0;
    }
#endif


        /*    Init next round of testing    */
        k++;
#ifndef __LINUX_USER_SPACE
        cyclePeriod +=    ICSS_EMAC_TEST_TTS_CYCLE_PERIOD_PORT2;
#endif
        q1_pkt_cnt = 0;
        q2_pkt_cnt = 0;
        j = 0;
        pkt_period_avg = 0;
        pkt_period_sum = 0;
        timestamp_delta = 0;
        t_delta_quo = 0;
        t_delta_rem = 0;
        max_jitter = 0;
        pkt_missed_cycle_cnt = 0;
        timestamp = 0;
        timestamp_prev = 0;
        missed_cycle_count = 0;
        ret = 0;

        /*    Wait for PRU0 TTS Init    */
        SLEEP(1);
    }
    ICSS_EMAC_testTtsModePort2 = 0;
}



/*
 *    ---function to initialize time triggered send---
 */
int8_t ICSS_EMAC_testTtsInit(ICSS_EmacHandle icssEmacHandle, uint32_t cyclePeriod)
{
    uint8_t j;
    int8_t ret;
    uint8_t portNumber;
    uint32_t iepRegsBase;
    uint64_t iepCounterVal;
    ICSSEMAC_IoctlCmd ioctlParams;
    ICSS_EmacTTSConfig ttsConfig;

    /*    Update Destination MAC address in sample frames    */
    if(icssEmacHandle == ICSS_EMAC_testHandle)
    {
        portNumber = ICSS_EMAC_PORT_1;

        /*    Re-init received pkt count for each TTS test    */
        ICSS_EMAC_testRecv_Q1PktCntPort1 = 0;
        ICSS_EMAC_testRecv_Q2PktCntPort1 = 0;

        for(j=0; j<6; j++)
        {
            ICSS_EMAC_testArpPktPort1[j] = ICSS_EMAC_testLclMac[j];
            ICSS_EMAC_testUdpPktPort1[j] = ICSS_EMAC_testLclMac[j];
        }
    }
    else if(icssEmacHandle == ICSS_EMAC_testHandle1)
    {
        portNumber = ICSS_EMAC_PORT_2;

        /*    Re-init received pkt count for each TTS test    */
        ICSS_EMAC_testRecv_Q1PktCntPort2 = 0;
        ICSS_EMAC_testRecv_Q2PktCntPort2 = 0;

        for(j=0; j<6; j++)
        {
            ICSS_EMAC_testArpPktPort2[j] = ICSS_EMAC_testLclMac1[j];
            ICSS_EMAC_testUdpPktPort2[j] = ICSS_EMAC_testLclMac1[j];
        }
    }
    else if(icssEmacHandle == ICSS_EMAC_testHandle2)
    {
        portNumber = ICSS_EMAC_PORT_1;

        /*    Re-init received pkt count for each TTS test    */
        ICSS_EMAC_testRecv_Q1PktCntPort1 = 0;
        ICSS_EMAC_testRecv_Q2PktCntPort1 = 0;

        for(j=0; j<6; j++)
        {
            ICSS_EMAC_testArpPktPort1[j] = ICSS_EMAC_testLclMac2[j];
            ICSS_EMAC_testUdpPktPort1[j] = ICSS_EMAC_testLclMac2[j];
        }
    }
    else if(icssEmacHandle == ICSS_EMAC_testHandle3)
    {
        portNumber = ICSS_EMAC_PORT_2;

        /*    Re-init received pkt count for each TTS test    */
        ICSS_EMAC_testRecv_Q1PktCntPort2 = 0;
        ICSS_EMAC_testRecv_Q2PktCntPort2 = 0;

        for(j=0; j<6; j++)
        {
            ICSS_EMAC_testArpPktPort2[j] = ICSS_EMAC_testLclMac3[j];
            ICSS_EMAC_testUdpPktPort2[j] = ICSS_EMAC_testLclMac3[j];
        }
    }
    else
    {
        return -1;
    }

    /*    Init TTS Parameters    */
    ioctlParams.command = 0;
    iepRegsBase = (((ICSS_EmacHwAttrs*)icssEmacHandle->hwAttrs)->emacBaseAddrCfg)->prussIepRegs;

    ioctlParams.ioctlVal = (void *)(&ttsConfig);

    ttsConfig.icssEmacHandle = icssEmacHandle;
    ttsConfig.cycTxSOFStatus = ICSS_EMAC_TTS_CYC_TXSOF_ENABLE;
    ttsConfig.portNumber = portNumber;
#ifdef __LINUX_USER_SPACE
    extern uint32_t config_time;
    ttsConfig.configTime = config_time;
#else
    ttsConfig.configTime = ICSS_EMAC_TEST_TTS_CONFIG_TIME;
#endif
    ttsConfig.cyclePeriod = cyclePeriod;
    ttsConfig.statusTTS = ICSS_EMAC_TTS_ENABLE;

    /*    Reading IEP Counter Value.    */
    iepCounterVal = (*((uint64_t*)(iepRegsBase + CSL_ICSSIEP_COUNT_REG0)));

    /*    Calculating cycle start value by adding 100us to counter value.    */
#ifdef __LINUX_USER_SPACE
    /* Linux seems to need more time before starting or may miss first cycle trigger */
    ttsConfig.cycleStartTime = (uint64_t)(iepCounterVal + 500000);
    clear_TTS_int_if_set(icssEmacHandle);
#else
    ttsConfig.cycleStartTime = (uint64_t)(iepCounterVal + 100000);
#endif

    /*    Enabling time triggered send.    */
    ret = ICSS_EmacIoctl(icssEmacHandle, ICSS_EMAC_IOCTL_TTS_CTRL, portNumber, &ioctlParams);
    assert(ret == 0);

    return 0;
}

/*
 *    ---function to setup Timer for Receive Packet pacing---
 */

int32_t ICSS_EMAC_testTimerSetup(ICSS_EmacHandle icssEmacHandle)
{
    void * timerHandle = NULL;
    TimerP_Params timerParams;

#if (defined (SOC_AM437x) || defined (SOC_AM335x))
    *(unsigned int*)CM_DPLL_CLKSEL_TIMER3_CLK = 0x1; /* high frequency input clock */

    // enable the TIMER
    *(unsigned int*)CM_PER_TIMER3_CLKCTRL = 0x2; /* Module is explicitly enabled */
#endif


    memset(&timerParams, 0, sizeof(TimerP_Params));
    ICSS_EMAC_osalTimerParamsInit(&timerParams);

    timerParams.runMode = TimerP_RunMode_CONTINUOUS;
    timerParams.startMode = TimerP_StartMode_USER;
    timerParams.periodType = TimerP_PeriodType_MICROSECS;
    timerParams.period = ICSS_EMAC_TEST_TIMER_PERIOD;

    timerParams.arg = (void*)icssEmacHandle;

    /*Create Interrupt Pacing Timer*/
    timerHandle = ICSS_EMAC_osalTimerCreate(ICSS_EMAC_TEST_TIMER_ID, (TimerP_Fxn)ICSS_EmacInterruptPacingISR, &timerParams);

    if ( timerHandle == NULL)
    {
       return -1;
    }
    else
    {
        ((ICSS_EmacObject*)icssEmacHandle->object)->rxPacingTimerHandle = timerHandle;
        return 0;
    }
}

#if defined (SOC_AM572x) || defined  (SOC_AM571x)
void ICSS_EMAC_testSocCtrlGetPortMacAddr(uint32_t portNum, uint8_t *pMacAddr)
{
    if(portNum == 0)
    {
        pMacAddr[5U] =  (((CSL_control_coreRegs *) CSL_MPU_CTRL_MODULE_CORE_CORE_REGISTERS_REGS)->MAC_ID_SW_0
                       >> 16U) & 0xFFU;
        pMacAddr[4U] =  (((CSL_control_coreRegs *) CSL_MPU_CTRL_MODULE_CORE_CORE_REGISTERS_REGS)->MAC_ID_SW_0
                       >> 8U) & 0xFFU;
        pMacAddr[3U] =  (((CSL_control_coreRegs *) CSL_MPU_CTRL_MODULE_CORE_CORE_REGISTERS_REGS)->MAC_ID_SW_0)
                      & 0xFFU;
        pMacAddr[2U] =  (((CSL_control_coreRegs *) CSL_MPU_CTRL_MODULE_CORE_CORE_REGISTERS_REGS)->MAC_ID_SW_1
                       >> 16U) & 0xFFU;
        pMacAddr[1U] =  (((CSL_control_coreRegs *) CSL_MPU_CTRL_MODULE_CORE_CORE_REGISTERS_REGS)->MAC_ID_SW_1
                       >> 8U) & 0xFFU;
        pMacAddr[0U] =  (((CSL_control_coreRegs *) CSL_MPU_CTRL_MODULE_CORE_CORE_REGISTERS_REGS)->MAC_ID_SW_1)
                      & 0xFF;

    }
    else
    {
        pMacAddr[5U] =  (((CSL_control_coreRegs *) CSL_MPU_CTRL_MODULE_CORE_CORE_REGISTERS_REGS)->MAC_ID_SW_2
                       >> 16U) & 0xFFU;
        pMacAddr[4U] =  (((CSL_control_coreRegs *) CSL_MPU_CTRL_MODULE_CORE_CORE_REGISTERS_REGS)->MAC_ID_SW_2
                       >> 8U) & 0xFFU;
        pMacAddr[3U] =  (((CSL_control_coreRegs *) CSL_MPU_CTRL_MODULE_CORE_CORE_REGISTERS_REGS)->MAC_ID_SW_2)
                      & 0xFFU;
        pMacAddr[2U] =  (((CSL_control_coreRegs *) CSL_MPU_CTRL_MODULE_CORE_CORE_REGISTERS_REGS)->MAC_ID_SW_3
                       >> 16U) & 0xFFU;
        pMacAddr[1U] =  (((CSL_control_coreRegs *) CSL_MPU_CTRL_MODULE_CORE_CORE_REGISTERS_REGS)->MAC_ID_SW_3
                       >> 8U) & 0xFFU;
        pMacAddr[0U] =  (((CSL_control_coreRegs *) CSL_MPU_CTRL_MODULE_CORE_CORE_REGISTERS_REGS)->MAC_ID_SW_3)
                      & 0xFF;
    }
}
#endif

#ifdef SOC_AM335x
void ICSS_EMAC_testSocCtrlGetPortMacAddr(uint32_t portNum, uint8_t *pMacAddr)
{
    uint32_t slavePortNum = portNum - 1U;

    pMacAddr[5U] =  (HW_RD_REG32(SOC_CONTROL_REGS + ICSS_EMAC_TEST_CONTROL_MAC_ID_LO(slavePortNum))
                   >> 8U) & 0xFFU;
    pMacAddr[4U] =  (HW_RD_REG32(SOC_CONTROL_REGS + ICSS_EMAC_TEST_CONTROL_MAC_ID_LO(slavePortNum)))
                  & 0xFF;
    pMacAddr[3U] =  (HW_RD_REG32(SOC_CONTROL_REGS + ICSS_EMAC_TEST_CONTROL_MAC_ID_HI(slavePortNum))
                   >> 24U) & 0xFFU;
    pMacAddr[2U] =  (HW_RD_REG32(SOC_CONTROL_REGS + ICSS_EMAC_TEST_CONTROL_MAC_ID_HI(slavePortNum))
                   >> 16U) & 0xFFU;
    pMacAddr[1U] =  (HW_RD_REG32(SOC_CONTROL_REGS + ICSS_EMAC_TEST_CONTROL_MAC_ID_HI(slavePortNum))
                   >> 8U) & 0xFFU;
    pMacAddr[0U] =  (HW_RD_REG32(SOC_CONTROL_REGS + ICSS_EMAC_TEST_CONTROL_MAC_ID_HI(slavePortNum)))
                  & 0xFFU;
}
#endif


#ifdef SOC_AM437x
void ICSS_EMAC_testSocCtrlGetPortMacAddr(uint32_t portNum, uint8_t *pMacAddr)
{
    switch(portNum)
    {
        case 1U:
            pMacAddr[5U] = HW_RD_FIELD32(SOC_CONTROL_MODULE_REG + ICSS_EMAC_TEST_CONTROL_MAC_ID_LO(0),
                CTRL_MAC_ID0_LO_MACADDR_7_0);
            pMacAddr[4U] = HW_RD_FIELD32(SOC_CONTROL_MODULE_REG + ICSS_EMAC_TEST_CONTROL_MAC_ID_LO(0),
                CTRL_MAC_ID0_LO_MACADDR_15_8);
            pMacAddr[3U] = HW_RD_FIELD32(SOC_CONTROL_MODULE_REG + ICSS_EMAC_TEST_CONTROL_MAC_ID_HI(0),
                CTRL_MAC_ID0_HI_MACADDR_23_16);
            pMacAddr[2U] = HW_RD_FIELD32(SOC_CONTROL_MODULE_REG + ICSS_EMAC_TEST_CONTROL_MAC_ID_HI(0),
                CTRL_MAC_ID0_HI_MACADDR_31_24);
            pMacAddr[1U] = HW_RD_FIELD32(SOC_CONTROL_MODULE_REG + ICSS_EMAC_TEST_CONTROL_MAC_ID_HI(0),
                CTRL_MAC_ID0_HI_MACADDR_39_32);
            pMacAddr[0U] = HW_RD_FIELD32(SOC_CONTROL_MODULE_REG + ICSS_EMAC_TEST_CONTROL_MAC_ID_HI(0),
                CTRL_MAC_ID0_HI_MACADDR_47_40);
            break;

        case 2U:
            pMacAddr[5U] = HW_RD_FIELD32(SOC_CONTROL_MODULE_REG + ICSS_EMAC_TEST_CONTROL_MAC_ID_LO(1),
                CTRL_MAC_ID0_LO_MACADDR_7_0);
            pMacAddr[4U] = HW_RD_FIELD32(SOC_CONTROL_MODULE_REG + ICSS_EMAC_TEST_CONTROL_MAC_ID_LO(1),
                CTRL_MAC_ID0_LO_MACADDR_15_8);
            pMacAddr[3U] = HW_RD_FIELD32(SOC_CONTROL_MODULE_REG +  ICSS_EMAC_TEST_CONTROL_MAC_ID_HI(1),
                CTRL_MAC_ID1_HI_MACADDR_23_16);
            pMacAddr[2U] = HW_RD_FIELD32(SOC_CONTROL_MODULE_REG +  ICSS_EMAC_TEST_CONTROL_MAC_ID_HI(1),
                CTRL_MAC_ID1_HI_MACADDR_31_24);
            pMacAddr[1U] = HW_RD_FIELD32(SOC_CONTROL_MODULE_REG +  ICSS_EMAC_TEST_CONTROL_MAC_ID_HI(1),
                CTRL_MAC_ID1_HI_MACADDR_39_32);
            pMacAddr[0U] = HW_RD_FIELD32(SOC_CONTROL_MODULE_REG +  ICSS_EMAC_TEST_CONTROL_MAC_ID_HI(1),
                CTRL_MAC_ID1_HI_MACADDR_47_40);
            break;

        default:
            break;
    }
}
#endif
