#include <Copyright.h>

/********************************************************************************
* gtBrgStp.c
*
* DESCRIPTION:
*       API definitions to handle port spanning tree state.
*
* DEPENDENCIES:
*
* FILE REVISION NUMBER:
*       $Revision: 5 $
*******************************************************************************/

#include <msApi.h>
#include <gtHwCntl.h>
#include <gtDrvSwRegs.h>

static GT_STATUS enhancedBPDUSet(GT_QD_DEV *dev,GT_BOOL en)
{
    GT_STATUS       retVal = GT_OK; /* Functions return value.      */
    GT_U16            enBits;

    /* If disable, reset the BPDU bit(bit0) from Rsvd2CpuEnables register */
       if(en == GT_FALSE)
    {
        if((retVal = gsysGetRsvd2CpuEnables(dev,&enBits)) != GT_OK)
        {
            DBG_INFO(("gsysGetRsvd2CpuEnables failed.\n"));
            return retVal;
        }
        enBits &= ~0x1;

        if((retVal = gsysSetRsvd2CpuEnables(dev,enBits)) != GT_OK)
        {
            DBG_INFO(("gsysSetRsvd2CpuEnables failed.\n"));
            return retVal;
        }

        return retVal;
    }

    /*
        If enable,
        1) Set MGMT Pri bits,
        2) Set BPDU bit(bit0) from Rsvd2CpuEnables register,
        3) Enable Rsvd2Cpu
    */
    if((retVal = gsysSetMGMTPri(dev,7)) != GT_OK)
    {
        DBG_INFO(("gsysSetMGMTPri failed.\n"));
        return retVal;
    }

    if((retVal = gsysGetRsvd2CpuEnables(dev,&enBits)) != GT_OK)
    {
        DBG_INFO(("gsysGetRsvd2CpuEnables failed.\n"));
        return retVal;
    }
    enBits |= 0x1;
    if((retVal = gsysSetRsvd2CpuEnables(dev,enBits)) != GT_OK)
    {
        DBG_INFO(("gsysSetRsvd2CpuEnables failed.\n"));
        return retVal;
    }

    if((retVal = gsysSetRsvd2Cpu(dev,GT_TRUE)) != GT_OK)
    {
        DBG_INFO(("gsysSetRsvd2Cpu failed.\n"));
        return retVal;
    }

    return retVal;
}


/*******************************************************************************
* gstpSetMode
*
* DESCRIPTION:
*       This routine Enable the Spanning tree.
*
* INPUTS:
*       en - GT_TRUE for enable, GT_FALSE for disable.
*
* OUTPUTS:
*       None.
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*
* COMMENTS:
*       when enabled, this function sets all port to blocking state, and inserts
*       the BPDU MAC into the ATU to be captured to CPU, on disable all port are
*       being modified to be in forwarding state.
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gstpSetMode
(
    IN GT_QD_DEV *dev,
    IN GT_BOOL  en
)
{
    GT_STATUS       retVal = GT_OK; /* Functions return value.      */
    GT_ATU_ENTRY        atuEntry;   /* The ATU entry data to be set */
    GT_U32          i, dbNum;

    DBG_INFO(("gstpSetMode Called.\n"));
    if(dev->deviceId == GT_88E6051)
    {
        DBG_INFO(("Failed.\n"));
        return GT_FAIL;
    }

    if((en == GT_TRUE) && (dev->stpMode == 1))
    {
        DBG_INFO(("OK.\n"));
        return GT_OK;
    }

    switch(dev->deviceId)
    {
        case GT_88E6051:
        case GT_88E6052:
            dbNum = 1;
            break;
        case GT_FF_HG:
        case GT_FF_EG:
        case GT_88E6021:
        case GT_88E6060:
        case GT_88E6031:
        case GT_88E6061:
        case GT_88E6063:
        case GT_FH_VPN:
        case GT_88E6083:
        case GT_88E6153:
        case GT_88E6181:
        case GT_88E6183:
        case GT_88E6093:
            dbNum = 16;
            break;
        case GT_88E6035:
        case GT_88E6055:
        case GT_88E6065:
            dbNum = 64;
            break;
        default:
            if (!IS_IN_DEV_GROUP(dev,DEV_ENHANCED_MULTICAST))
            {
                dbNum = 64;
            }
            else
            {
                dbNum = 0;
                retVal = enhancedBPDUSet(dev,en);
            }
            break;
    }

    for (i=0; i<dbNum; i++)
    {
        /* Set the Atu entry parameters.    */
        atuEntry.macAddr.arEther[0] = 0x01;
        atuEntry.macAddr.arEther[1] = 0x80;
        atuEntry.macAddr.arEther[2] = 0xC2;
        atuEntry.macAddr.arEther[3] = 0x00;
        atuEntry.macAddr.arEther[4] = 0x00;
        atuEntry.macAddr.arEther[5] = 0x00;
        atuEntry.portVec = GT_LPORTVEC_2_PORTVEC((1<<dev->cpuPortNum));
        if(IS_IN_DEV_GROUP(dev,DEV_ATU_EXT_PRI))
        {
            if(IS_IN_DEV_GROUP(dev,DEV_FQPRI_IN_TABLE))
            {
                atuEntry.exPrio.useMacFPri = GT_TRUE;
                atuEntry.exPrio.macFPri = 7;
            }
            else
            {
                atuEntry.exPrio.useMacFPri = 0;
                atuEntry.exPrio.macFPri = 0;
            }
            atuEntry.exPrio.macQPri = 3;
            atuEntry.prio    = 0;
        }
        else
        {
            atuEntry.prio    = 3;
            atuEntry.exPrio.useMacFPri = 0;
            atuEntry.exPrio.macFPri = 0;
            atuEntry.exPrio.macQPri = 0;
        }
        atuEntry.DBNum = (GT_U8)i;
        atuEntry.entryState.mcEntryState = GT_MC_PRIO_MGM_STATIC;

        if(en == GT_TRUE)
        {
            retVal = gfdbAddMacEntry(dev,&atuEntry);
        }
        else
        {
            if(dev->stpMode == 0)
                break;
            retVal = gfdbDelAtuEntry(dev,&atuEntry);
        }

        if (retVal != GT_OK)
            break;
    }

    if(retVal == GT_OK)
    {
        if(en == GT_TRUE)
            dev->stpMode = 1;
        else
            dev->stpMode = 2;
        DBG_INFO(("OK.\n"));
    }
    else
    {
           dev->stpMode = 0;
        DBG_INFO(("Failed.\n"));
    }


    return retVal;
}



/*******************************************************************************
* gstpSetPortState
*
* DESCRIPTION:
*       This routine set the port state.
*
* INPUTS:
*       port  - the logical port number.
*       state - the port state to set.
*
* OUTPUTS:
*       None.
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*
* COMMENTS:
*
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gstpSetPortState
(
    IN GT_QD_DEV *dev,
    IN GT_LPORT           port,
    IN GT_PORT_STP_STATE  state
)
{
    GT_U8           phyPort;        /* Physical port                */
    GT_U16          data;           /* Data to write to register.   */
    GT_STATUS       retVal;         /* Functions return value.      */

    DBG_INFO(("gstpSetPortState Called.\n"));

    phyPort = GT_LPORT_2_PORT(port);
    data    = state;

    /* Set the port state bits.             */
    retVal= hwSetPortRegField(dev,phyPort, QD_REG_PORT_CONTROL,0,2,data);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }
    DBG_INFO(("OK.\n"));
    return GT_OK;
}



/*******************************************************************************
* gstpGetPortState
*
* DESCRIPTION:
*       This routine returns the port state.
*
* INPUTS:
*       port  - the logical port number.
*
* OUTPUTS:
*       state - the current port state.
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*
* COMMENTS:
*       None.
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gstpGetPortState
(
    IN GT_QD_DEV *dev,
    IN  GT_LPORT           port,
    OUT GT_PORT_STP_STATE  *state
)
{
    GT_U8           phyPort;        /* Physical port                */
    GT_U16          data;           /* Data read from register.     */
    GT_STATUS       retVal;         /* Functions return value.      */

    DBG_INFO(("gstpGetPortState Called.\n"));

    phyPort = GT_LPORT_2_PORT(port);

    /* Get the port state bits.             */
    retVal = hwGetPortRegField(dev,phyPort, QD_REG_PORT_CONTROL,0,2,&data);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }

    *state = data & 0x3;
    DBG_INFO(("OK.\n"));
    return GT_OK;
}
