#include <Copyright.h>
/********************************************************************************
* ptp.c
*
* DESCRIPTION:
*       Setup PTP for 88E6165 device family.
*
* DEPENDENCIES:   None.
*
* FILE REVISION NUMBER:
*
*******************************************************************************/
#include "msSample.h"


/*
 *  PTP Init routine
 *
 *    1) Setup each port to forward PTP frame to CPU port
 *    2) Enable PTP Interrupt (assumes that no other interrupt is used, but PTP)
 *    3) Configure PTP
 *    4) Enable PTP
 *
 *    Notes: This sample uses the following configuration
 *    1) Enables only PTP interrupt
 *    2) Assumes PTP Ethernet Type is 0x88F7
 *    3) Time Stamp is enabled only for Message ID 0, 2, and 3
 *    4) Message ID 0 and 2 use Arr0 pointer and ID 3 uses Arr1 pointer
 *    5) PTP interrtups are enabled on Port 0 ~ 5
 *
 *    Notes: Forwarding PTP fram to CPU port is based on Ether Type DSA Tag (8 bytes).
 *    Therefore, Ethernet device driver, that actually rx/tx the PTP frame,
 *    should expect/insert Ether Type DSA Tag.
*/

GT_STATUS samplePTPInit(GT_QD_DEV *dev)
{
     GT_PTP_CONFIG ptpCfg;
    GT_LPORT port;
    GT_STATUS status;


    /*
     *    1) Setup each port to forward PTP frame to CPU port
    */

    /* setup EtypeType and Policy */
    for(port=0; port<dev->numOfPorts; port++)
    {
        if ((status = gprtSetPortEType(dev, port, (GT_ETYPE)0x88F7)) != GT_OK)
        {
            MSG_PRINT(("gprtSetPortEType returned not OK\n"));
            return status;
        }

        if (port == dev->cpuPortNum)
            continue;

        if ((status = gprtSetPolicy(dev, port, POLICY_TYPE_ETYPE, FRAME_POLICY_TRAP)) != GT_OK)
        {
            MSG_PRINT(("gprtSetPolicy returned not OK\n"));
            return status;
        }
    }

    /* setup Frame Mode for CPU port */
    if ((status = gprtSetFrameMode(dev, dev->cpuPortNum, GT_FRAME_MODE_ETHER_TYPE_DSA)) != GT_OK)
    {
        MSG_PRINT(("gprtSetFrameMode return failed\n"));
        return status;
    }

    /*
     *    2) Enable PTP Interrupt
    */
    eventSetActive(dev, GT_AVB_INT);


    /*
     *    3) Configure PTP
    */
    ptpCfg.ptpEType = 0x88F7;
    ptpCfg.msgIdTSEn = 0xd;        /* id 0, 2, and 3 */
    ptpCfg.tsArrPtr = 0x8;        /* id 0 and 2 for ARR0, id 3 for ARR1 */

    /* Transport specific bits present in PTP Common Header */
    ptpCfg.transSpec = 1;

    /* starting bit location for the Message ID field in the PTP Common Header */
    ptpCfg.msgIdStartBit = 4;

    ptpCfg.ptpArrIntEn = 0x3F;
    ptpCfg.ptpDepIntEn = 0x3F;
    ptpCfg.disTSOverwrite = 0;


    if ((status = gptpSetConfig(dev, &ptpCfg)) != GT_OK)
    {
        MSG_PRINT(("gptpSetConfig return failed\n"));
        return status;
    }
    if ((status = gptpSetPTPEn(dev, GT_TRUE)) != GT_OK)
    {
        MSG_PRINT(("gptpSetPTPEn return failed\n"));
        return status;
    }

    return GT_OK;
}


/*
 *  PTP Interrupt Handler
 *
 *    1) for each port that causes PTP interrup, do the followings
 *    2) check Arrival 0 Time Stamp
 *    3) check Arrival 1 Time Stamp
 *    4) check Departure Time Stamp
*/

GT_STATUS samplePTPIntHandler(GT_QD_DEV *dev)
{
    GT_U32 int_ports, i, int_status;
    GT_STATUS status;
    GT_PTP_TS_STATUS    ptpStatus;

    /* disable AVB Interrupt */
    eventSetActive(dev, 0);

    /* read interrupt cause */
    if((status=eventGetIntStatus(dev,(GT_U16*)&int_status))!=GT_OK)
    {
        return GT_FAIL;
    }


    if ((int_status & GT_AVB_INT) == 0)
    {
        MSG_PRINT(("eventGetIntStatus return No AVB Interrupt\n"));
        /* it's not PTP interrupt */
        goto ret_int;
    }

    /* read AVB Int status */
    if((status = gptpGetPTPInt(dev, &int_ports)) != GT_OK)
    {
        MSG_PRINT(("gptpGetPTPInt return failed\n"));
        goto ret_int;
    }

    /* for each port, get the timestamp information if necessary */
    i = 0;
    while(int_ports)
    {
        if(!(int_ports & 0x1))
        {
            i++;
            int_ports >>= 1;
            continue;
        }

        /* check Arrival0 Time Stamp */
        if((status = gptpGetTimeStamped(dev, i, PTP_ARR0_TIME, &ptpStatus)) != GT_OK)
        {
            MSG_PRINT(("gptpGetTimeStamped return failed\n"));
            goto ret_int;
        }

        if (ptpStatus.isValid == GT_TRUE)
        {
            switch(ptpStatus.status)
            {
                case PTP_INT_NORMAL:
                    /* To Do: No error condition occurred. So store the time stamp and seqId */
                    break;

                case PTP_INT_OVERWRITE:
                    /* To Do: PTP Logic received several PTP frames and only the last one is valid */
                    break;

                case PTP_INT_DROP:
                    /* To Do: PTP Logic received several PTP frames and only the first one is valid */
                    break;

                default:
                    MSG_PRINT(("unknown ptp status %i\n", ptpStatus.status));
                    status = GT_FAIL;
                    goto ret_int;

            }

            if((status = gptpResetTimeStamp(dev, i, PTP_ARR0_TIME)) != GT_OK)
            {
                MSG_PRINT(("gptpResetTimeStamp return failed\n"));
                goto ret_int;
            }
        }

        /* check Arrival1 Time Stamp */
        if((status = gptpGetTimeStamped(dev, i, PTP_ARR1_TIME, &ptpStatus)) != GT_OK)
        {
            MSG_PRINT(("gptpGetTimeStamped return failed\n"));
            goto ret_int;
        }

        if (ptpStatus.isValid == GT_TRUE)
        {
            switch(ptpStatus.status)
            {
                case PTP_INT_NORMAL:
                    /* To Do: No error condition occurred. So store the time stamp and seqId */
                    break;

                case PTP_INT_OVERWRITE:
                    /* To Do: PTP Logic received several PTP frames and only the last one is valid */
                    break;

                case PTP_INT_DROP:
                    /* To Do: PTP Logic received several PTP frames and only the first one is valid */
                    break;

                default:
                    MSG_PRINT(("unknown ptp status %i\n", ptpStatus.status));
                    status = GT_FAIL;
                    goto ret_int;
            }

            if((status = gptpResetTimeStamp(dev, i, PTP_ARR1_TIME)) != GT_OK)
            {
                MSG_PRINT(("gptpResetTimeStamp return failed\n"));
                goto ret_int;
            }

        }

        /* check Departure Time Stamp */
        if((status = gptpGetTimeStamped(dev, i, PTP_DEP_TIME, &ptpStatus)) != GT_OK)
        {
            MSG_PRINT(("gptpGetTimeStamped return failed\n"));
            goto ret_int;
        }

        if (ptpStatus.isValid == GT_TRUE)
        {
            switch(ptpStatus.status)
            {
                case PTP_INT_NORMAL:
                    /* To Do: No error condition occurred. So store the time stamp and seqId */
                    break;

                case PTP_INT_OVERWRITE:
                    /* To Do: PTP Logic received several PTP frames and only the last one is valid */
                    break;

                case PTP_INT_DROP:
                    /* To Do: PTP Logic received several PTP frames and only the first one is valid */
                    break;

                default:
                    MSG_PRINT(("unknown ptp status %i\n", ptpStatus.status));
                    status = GT_FAIL;
                    goto ret_int;
            }

            if((status = gptpResetTimeStamp(dev, i, PTP_DEP_TIME)) != GT_OK)
            {
                MSG_PRINT(("gptpResetTimeStamp return failed\n"));
                goto ret_int;
            }

        }

        int_ports >>= 1;

    }

ret_int:
    eventSetActive(dev, GT_AVB_INT);

    return status;
}
