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