#include <Copyright.h>

/********************************************************************************
* gtBrgVlan.c
*
* DESCRIPTION:
*       API definitions to handle port-based vlan configuration.
*
* DEPENDENCIES:
*
* FILE REVISION NUMBER:
*       $Revision: 5 $
*******************************************************************************/

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

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

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

    phyPort = GT_LPORT_2_PORT(port);

    /* check if device supports this feature */
    if((retVal = IS_VALID_API_CALL(dev,phyPort, DEV_TAGGING)) != GT_OK ) 
      return retVal;
    
    switch (mode)
    {
        case (GT_UNMODIFY_EGRESS):
            data = 0;
            break;

        case (GT_TAGGED_EGRESS):
            data = 2;
            break;

        case (GT_UNTAGGED_EGRESS):
            data = 1;
            break;

        case (GT_ADD_TAG):
            if(!IS_IN_DEV_GROUP(dev,DEV_EGRESS_DOUBLE_TAGGING))
            {
                DBG_INFO(("GT_NOT_SUPPORTED\n"));
                return GT_NOT_SUPPORTED;
            }
            data = 3;
            break;
        default:
            DBG_INFO(("Failed.\n"));
            return GT_FAIL;
    }

    retVal = hwSetPortRegField(dev,phyPort,QD_REG_PORT_CONTROL,12,2,data);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }

    DBG_INFO(("OK.\n"));
    return GT_OK;
}



/*******************************************************************************
* gprtGetEgressMode
*
* DESCRIPTION:
*       This routine get the egress mode.
*
* INPUTS:
*       port  - the logical port number.
*
* OUTPUTS:
*       mode - the egress mode.
*
* RETURNS:
*       GT_OK               - on success
*       GT_FAIL             - on error
*       GT_BAD_PARAM        - on bad parameters
*
* COMMENTS:
*       None.
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gprtGetEgressMode
(
    IN GT_QD_DEV       *dev,
    IN  GT_LPORT        port,
    OUT GT_EGRESS_MODE  *mode
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U16          data;           /* The register's read data.    */
    GT_U8           phyPort;        /* Physical port.               */

    if(mode == NULL)
        return GT_BAD_PARAM;

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

    phyPort = GT_LPORT_2_PORT(port);

    retVal = hwGetPortRegField(dev,phyPort,QD_REG_PORT_CONTROL,12,2,&data);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }

    switch (data)
    {
        case (0):
            *mode = GT_UNMODIFY_EGRESS;
            break;

        case (2):
            *mode = GT_TAGGED_EGRESS;
            break;

        case (1):
            *mode = GT_UNTAGGED_EGRESS;
            break;

        case (3):
            *mode = GT_ADD_TAG;
            break;
    }
    DBG_INFO(("OK.\n"));
    return GT_OK;
}



/*******************************************************************************
* gprtSetVlanTunnel
*
* DESCRIPTION:
*       This routine sets the vlan tunnel mode.
*
* INPUTS:
*       port - the logical port number.
*       mode - the vlan tunnel mode.
*
* OUTPUTS:
*       None.
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*
* COMMENTS:
*
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gprtSetVlanTunnel
(
    IN GT_QD_DEV *dev,
    IN GT_LPORT  port,
    IN GT_BOOL   mode
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U16          data;           /* Data to be set into the      */
                                    /* register.                    */
    GT_U8           phyPort;        /* Physical port.               */

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

    phyPort = GT_LPORT_2_PORT(port);
    BOOL_2_BIT(mode,data);

    retVal = hwSetPortRegField(dev,phyPort,QD_REG_PORT_CONTROL,7,1,data);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }

    DBG_INFO(("OK.\n"));
    return GT_OK;
}



/*******************************************************************************
* gprtGetVlanTunnel
*
* DESCRIPTION:
*       This routine get the vlan tunnel mode.
*
* INPUTS:
*       port  - the logical port number.
*
* OUTPUTS:
*       mode - the vlan tunnel mode..
*
* RETURNS:
*       GT_OK               - on success
*       GT_FAIL             - on error
*       GT_BAD_PARAM        - on bad parameters
*
* COMMENTS:
*
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gprtGetVlanTunnel
(
    IN GT_QD_DEV *dev,
    IN  GT_LPORT port,
    OUT GT_BOOL  *mode
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U16          data;           /* The register's read data.    */
    GT_U8           phyPort;        /* Physical port.               */

    DBG_INFO(("gprtGetVlanTunnel Called.\n"));
    if(mode == NULL)
    {
        DBG_INFO(("Failed.\n"));
        return GT_BAD_PARAM;
    }

    phyPort = GT_LPORT_2_PORT(port);

    retVal = hwGetPortRegField(dev,phyPort,QD_REG_PORT_CONTROL,7,1,&data);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }

    BIT_2_BOOL(data,*mode);
    DBG_INFO(("OK.\n"));
    return GT_OK;
}



/*******************************************************************************
* gvlnSetPortVlanPorts
*
* DESCRIPTION:
*       This routine sets the port VLAN group port membership list.
*
* INPUTS:
*       port        - logical port number to set.
*       memPorts    - array of logical ports in the same vlan.
*       memPortsLen - number of members in memPorts array
*
* OUTPUTS:
*       None.
*
* RETURNS:
*       GT_OK               - on success
*       GT_FAIL             - on error
*       GT_BAD_PARAM        - on bad parameters
*
* COMMENTS:
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gvlnSetPortVlanPorts
(
    IN GT_QD_DEV *dev,
    IN GT_LPORT  port,
    IN GT_LPORT  memPorts[],
    IN GT_U8     memPortsLen
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U16          data;           /* Data to be set into the      */
                                    /* register.                    */
    GT_U8           phyPort;        /* Physical port.               */
    GT_U8           i;

    DBG_INFO(("gvlnSetPortVlanPorts Called.\n"));
    if(memPorts == NULL)
    {
        DBG_INFO(("Failed.\n"));
        return GT_BAD_PARAM;
    }

    phyPort = GT_LPORT_2_PORT(port);
    data = 0;

    if(memPortsLen > dev->numOfPorts)
    {
        DBG_INFO(("Failed (PortsLen Too Big).\n"));
        return GT_BAD_PARAM;
    }

    for(i = 0; i < memPortsLen; i++)
        data |= (1 << GT_LPORT_2_PORT(memPorts[i]));

    /* numOfPorts = 3 for fullsail, = 10 for octane, = 7 for others */
    retVal = hwSetPortRegField(dev,phyPort,QD_REG_PORT_VLAN_MAP,0,dev->maxPorts,data);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }

    DBG_INFO(("OK.\n"));
    return GT_OK;
}



/*******************************************************************************
* gvlnGetPortVlanPorts
*
* DESCRIPTION:
*       This routine gets the port VLAN group port membership list.
*
* INPUTS:
*       port        - logical port number to set.
*
* OUTPUTS:
*       memPorts    - array of logical ports in the same vlan.
*       memPortsLen - number of members in memPorts array
*
* RETURNS:
*       GT_OK               - on success
*       GT_FAIL             - on error
*       GT_BAD_PARAM        - on bad parameters
*
* COMMENTS:
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gvlnGetPortVlanPorts
(
    IN GT_QD_DEV *dev,
    IN  GT_LPORT port,
    OUT GT_LPORT memPorts[],
    OUT GT_U8    *memPortsLen
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U16          data;           /* The register's read data.    */
    GT_U8           phyPort;        /* Physical port.               */
    GT_U8           i;

    DBG_INFO(("gvlnGetPortVlanPorts Called.\n"));
    if((memPorts == NULL) || (memPortsLen == NULL))
    {
        DBG_INFO(("Failed.\n"));
        return GT_BAD_PARAM;
    }

    phyPort = GT_LPORT_2_PORT(port);

    /* memPortsLen = 3 for fullsail, =7 for others */
    retVal = hwGetPortRegField(dev,phyPort,QD_REG_PORT_VLAN_MAP,0,dev->maxPorts,&data);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }

    i = 0;
    for(phyPort = 0; phyPort < dev->maxPorts; phyPort++)
    {
        if(!GT_IS_PORT_SET(dev->validPortVec, phyPort))
            continue;

        if(((1 << phyPort) & data) != 0)
        {
            memPorts[i] = GT_PORT_2_LPORT(phyPort);
            i++;
        }
    }
    *memPortsLen = i;

    DBG_INFO(("OK.\n"));
    return GT_OK;
}


/*******************************************************************************
* gvlnSetPortUserPriLsb
*
* DESCRIPTION:
*       This routine Set the user priority (VPT) LSB bit, to be added to the
*       user priority on the egress.
*
* INPUTS:
*       port       - logical port number to set.
*       userPriLsb - GT_TRUE for 1, GT_FALSE for 0.
*
* OUTPUTS:
*       None.
*
* RETURNS:
*       GT_OK               - on success
*       GT_FAIL             - on error
*       GT_BAD_PARAM        - on bad parameters
*
* COMMENTS:
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gvlnSetPortUserPriLsb
(
    IN GT_QD_DEV *dev,
    IN GT_LPORT  port,
    IN GT_BOOL   userPriLsb
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U16          data;           /* Data to be set into the      */
                                    /* register.                    */
    GT_U8           phyPort;        /* Physical port.               */

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

    /* Gigabit Switch does not support this status. */
    if ((IS_IN_DEV_GROUP(dev,DEV_GIGABIT_SWITCH)) ||
        (IS_IN_DEV_GROUP(dev,DEV_ENHANCED_FE_SWITCH)) ||
        (IS_IN_DEV_GROUP(dev,DEV_FE_AVB_FAMILY)))
    {
        DBG_INFO(("GT_NOT_SUPPORTED\n"));
        return GT_NOT_SUPPORTED;
    }

    phyPort = GT_LPORT_2_PORT(port);
    BOOL_2_BIT(userPriLsb,data);

    retVal = hwSetPortRegField(dev,phyPort,QD_REG_PVID,13,1,data);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }
    DBG_INFO(("OK.\n"));
    return GT_OK;
}



/*******************************************************************************
* gvlnGetPortUserPriLsb
*
* DESCRIPTION:
*       This routine gets the user priority (VPT) LSB bit.
*
* INPUTS:
*       port       - logical port number to set.
*
* OUTPUTS:
*       userPriLsb - GT_TRUE for 1, GT_FALSE for 0.
*
* RETURNS:
*       GT_OK               - on success
*       GT_FAIL             - on error
*       GT_BAD_PARAM        - on bad parameters
*
* COMMENTS:
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gvlnGetPortUserPriLsb
(
    IN GT_QD_DEV    *dev,
    IN  GT_LPORT    port,
    OUT GT_BOOL     *userPriLsb
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U16          data;           /* The register's read data.    */
    GT_U8           phyPort;        /* Physical port.               */

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

    /* Gigabit Switch does not support this status. */
    if ((IS_IN_DEV_GROUP(dev,DEV_GIGABIT_SWITCH)) ||
        (IS_IN_DEV_GROUP(dev,DEV_ENHANCED_FE_SWITCH)) ||
        (IS_IN_DEV_GROUP(dev,DEV_FE_AVB_FAMILY)))
    {
        DBG_INFO(("GT_NOT_SUPPORTED\n"));
        return GT_NOT_SUPPORTED;
    }

    if(userPriLsb == NULL)
    {
        DBG_INFO(("Failed.\n"));
        return GT_BAD_PARAM;
    }

    phyPort = GT_LPORT_2_PORT(port);

    retVal = hwGetPortRegField(dev,phyPort,QD_REG_PVID,13,1,&data);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }

    BIT_2_BOOL(data,*userPriLsb);
    DBG_INFO(("OK.\n"));
    return GT_OK;
}


/*******************************************************************************
* gvlnSetPortVid
*
* DESCRIPTION:
*       This routine Set the port default vlan id.
*
* INPUTS:
*       port - logical port number to set.
*       vid  - the port vlan id.
*
* OUTPUTS:
*       None.
*
* RETURNS:
*       GT_OK               - on success
*       GT_FAIL             - on error
*       GT_BAD_PARAM        - on bad parameters
*
* COMMENTS:
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gvlnSetPortVid
(
    IN GT_QD_DEV    *dev,
    IN GT_LPORT     port,
    IN GT_U16       vid
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U8           phyPort;        /* Physical port.               */

    DBG_INFO(("gvlnSetPortVid Called.\n"));
    phyPort = GT_LPORT_2_PORT(port);

    retVal = hwSetPortRegField(dev,phyPort,QD_REG_PVID,0,12, vid);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }
    DBG_INFO(("OK.\n"));
    return GT_OK;
}


/*******************************************************************************
* gvlnGetPortVid
*
* DESCRIPTION:
*       This routine Get the port default vlan id.
*
* INPUTS:
*       port - logical port number to set.
*
* OUTPUTS:
*       vid  - the port vlan id.
*
* RETURNS:
*       GT_OK               - on success
*       GT_FAIL             - on error
*       GT_BAD_PARAM        - on bad parameters
*
* COMMENTS:
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gvlnGetPortVid
(
    IN GT_QD_DEV *dev,
    IN  GT_LPORT port,
    OUT GT_U16   *vid
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U16          data;           /* The register's read data.    */
    GT_U8           phyPort;        /* Physical port.               */

    DBG_INFO(("gvlnGetPortVid Called.\n"));
    if(vid == NULL)
    {
        DBG_INFO(("Failed.\n"));
        return GT_BAD_PARAM;
    }

    phyPort = GT_LPORT_2_PORT(port);

    retVal = hwGetPortRegField(dev,phyPort,QD_REG_PVID,0,12, &data);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }

    *vid = data;
    DBG_INFO(("OK.\n"));
    return GT_OK;
}


/*******************************************************************************
* gvlnSetPortVlanDBNum
*
* DESCRIPTION:
*       This routine sets the port's default VLAN database number (DBNum or 
*        FID, Forwarding Information Database).
*
* INPUTS:
*       port    - logical port number to set.
*       DBNum     - database number for this port (or FID)
*
* OUTPUTS:
*       None.
*
* RETURNS:IN GT_INGRESS_MODE mode
*       GT_OK               - on success
*       GT_FAIL             - on error
*       GT_BAD_PARAM        - on bad parameters
*
* COMMENTS: 
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gvlnSetPortVlanDBNum
(
    IN GT_QD_DEV *dev,
    IN GT_LPORT  port,
    IN GT_U32    DBNum
)
{

    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U8           phyPort;        /* Physical port.               */

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

    phyPort = GT_LPORT_2_PORT(port);

    if(IS_IN_DEV_GROUP(dev,DEV_DBNUM_4096))
    {
        if(DBNum > 4095)
        {
            return GT_BAD_PARAM;
        }
        retVal = hwSetPortRegField(dev,phyPort,QD_REG_PORT_CONTROL1,0,8,(GT_U16)((DBNum & 0xFF0) >> 4));
        retVal = hwSetPortRegField(dev,phyPort,QD_REG_PORT_VLAN_MAP,12,4,(GT_U16)(DBNum & 0x000F));
    }
    else if(IS_IN_DEV_GROUP(dev,DEV_DBNUM_256))
    {
        if(DBNum > 255)
        {
            return GT_BAD_PARAM;
        }
        retVal = hwSetPortRegField(dev,phyPort,QD_REG_PORT_CONTROL1,0,4,(GT_U16)((DBNum & 0xF0) >> 4));
        retVal = hwSetPortRegField(dev,phyPort,QD_REG_PORT_VLAN_MAP,12,4,(GT_U16)(DBNum & 0x0F));
    }
    else if(IS_IN_DEV_GROUP(dev,DEV_DBNUM_64))
    {
        if(DBNum > 63)
        {
            return GT_BAD_PARAM;
        }
        if(IS_IN_DEV_GROUP(dev,DEV_FE_AVB_FAMILY))
        {
          retVal = hwSetPortRegField(dev,phyPort,QD_REG_PORT_CONTROL1,0,2,(GT_U16)((DBNum & 0x30) >> 4));
          retVal = hwSetPortRegField(dev,phyPort,QD_REG_PORT_VLAN_MAP,12,4,(GT_U16)(DBNum & 0x0F));
        }
        else
        {
          retVal = hwSetPortRegField(dev,phyPort,QD_REG_PORT_VLAN_MAP,6,2,(GT_U16)((DBNum & 0x30) >> 4));
          retVal = hwSetPortRegField(dev,phyPort,QD_REG_PORT_VLAN_MAP,12,4,(GT_U16)(DBNum & 0x0F));
        }
    }
    else
    {
        if(DBNum > 15)
        {
            return GT_BAD_PARAM;
        }
        retVal = hwSetPortRegField(dev,phyPort,QD_REG_PORT_VLAN_MAP,12,4,(GT_U16)(DBNum & 0x0F));
    }

    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }
    DBG_INFO(("OK.\n"));
    return GT_OK;
}



/*******************************************************************************
* gvlnGetPortVlanDBNum
*
* DESCRIPTION:
*       This routine gets the port's default VLAN database number (DBNum or
*        FID, Forwarding Information Database).
*
* INPUTS:
*       port     - logical port number to get.
*
* OUTPUTS:
*       DBNum     - database number for this port (or FID)
*
* RETURNS:
*       GT_OK               - on success
*       GT_FAIL             - on error
*       GT_BAD_PARAM        - on bad parameters
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gvlnGetPortVlanDBNum
(
    IN GT_QD_DEV *dev,
    IN  GT_LPORT port,
    OUT GT_U32   *DBNum
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U16          data,dataH;           /* The register's read data.    */
    GT_U8           phyPort;        /* Physical port.               */

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

    if(DBNum == NULL)
    {
        DBG_INFO(("Failed.\n"));
        return GT_BAD_PARAM;
    }

    phyPort = GT_LPORT_2_PORT(port);

    if(IS_IN_DEV_GROUP(dev,DEV_DBNUM_4096))
    {
        retVal = hwGetPortRegField(dev,phyPort,QD_REG_PORT_CONTROL1,0,8, &dataH);
        retVal = hwGetPortRegField(dev,phyPort,QD_REG_PORT_VLAN_MAP,12,4, &data);
    }
    else if(IS_IN_DEV_GROUP(dev,DEV_DBNUM_256))
    {
        retVal = hwGetPortRegField(dev,phyPort,QD_REG_PORT_CONTROL1,0,4, &dataH);
        retVal = hwGetPortRegField(dev,phyPort,QD_REG_PORT_VLAN_MAP,12,4, &data);
    }
    else if(IS_IN_DEV_GROUP(dev,DEV_DBNUM_64))
    {
        if(IS_IN_DEV_GROUP(dev,DEV_FE_AVB_FAMILY))
        {
          retVal = hwGetPortRegField(dev,phyPort,QD_REG_PORT_CONTROL1,0,2, &dataH);
          retVal = hwGetPortRegField(dev,phyPort,QD_REG_PORT_VLAN_MAP,12,4, &data);
        }
        else
        {
          retVal = hwGetPortRegField(dev,phyPort,QD_REG_PORT_VLAN_MAP,6,2, &dataH);
          retVal = hwGetPortRegField(dev,phyPort,QD_REG_PORT_VLAN_MAP,12,4, &data);
        }
    }
    else
    {
        dataH = 0;
        retVal = hwGetPortRegField(dev,phyPort,QD_REG_PORT_VLAN_MAP,12,4, &data);
    }

    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }

    *DBNum = (GT_U32)(data | (dataH << 4));
    DBG_INFO(("OK.\n"));
    return GT_OK;
}

/********************************************************************
* gvlnSetPortVlanDot1qMode
*
* DESCRIPTION:
*       This routine sets the IEEE 802.1q mode for this port (11:10) 
*
* INPUTS:
*       port    - logical port number to set.
*       mode     - 802.1q mode for this port 
*
* OUTPUTS:
*       None.
*
* RETURNS:IN GT_INGRESS_MODE mode
*       GT_OK               - on success
*       GT_FAIL             - on error
*       GT_BAD_PARAM        - on bad parameters
*
* COMMENTS: 
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gvlnSetPortVlanDot1qMode
(
    IN GT_QD_DEV        *dev,
    IN GT_LPORT     port,
    IN GT_DOT1Q_MODE    mode
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U8           phyPort;        /* Physical port.               */

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

    phyPort = GT_LPORT_2_PORT(port);

    /* check if device supports this feature */
    if((retVal = IS_VALID_API_CALL(dev,phyPort, DEV_802_1Q)) != GT_OK ) 
      return retVal;

    if ((IS_IN_DEV_GROUP(dev,DEV_GIGABIT_SWITCH)) ||
        (IS_IN_DEV_GROUP(dev,DEV_ENHANCED_FE_SWITCH)) ||
        (IS_IN_DEV_GROUP(dev,DEV_FE_AVB_FAMILY)))
    {
        retVal = hwSetPortRegField(dev,phyPort,QD_REG_PORT_CONTROL2,10,2,(GT_U16)mode );
    }
    else
    {
        retVal = hwSetPortRegField(dev,phyPort,QD_REG_PORT_VLAN_MAP,10,2,(GT_U16)mode );
    }

    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }
    DBG_INFO(("OK.\n"));
    return GT_OK;
}

/*******************************************************************************
* gvlnGetPortVlanDot1qMode
*
* DESCRIPTION:
*       This routine gets the IEEE 802.1q mode for this (bit 11:10).
*
* INPUTS:
*       port     - logical port number to get.
*
* OUTPUTS:
*       mode     - 802.1q mode for this port 
*
* RETURNS:
*       GT_OK               - on success
*       GT_FAIL             - on error
*       GT_BAD_PARAM        - on bad parameters
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gvlnGetPortVlanDot1qMode
(
    IN GT_QD_DEV        *dev,
    IN  GT_LPORT        port,
    OUT GT_DOT1Q_MODE   *mode
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U16          data;           /* The register's read data.    */
    GT_U8           phyPort;        /* Physical port.               */

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

    phyPort = GT_LPORT_2_PORT(port);

    /* check if device supports this feature */
    if((retVal = IS_VALID_API_CALL(dev,phyPort, DEV_802_1Q)) != GT_OK ) 
      return retVal;

    if(mode == NULL)
    {
        DBG_INFO(("Failed.\n"));
        return GT_BAD_PARAM;
    }

    if ((IS_IN_DEV_GROUP(dev,DEV_GIGABIT_SWITCH)) ||
        (IS_IN_DEV_GROUP(dev,DEV_ENHANCED_FE_SWITCH)) ||
        (IS_IN_DEV_GROUP(dev,DEV_FE_AVB_FAMILY)))
    {
        retVal = hwGetPortRegField(dev,phyPort,QD_REG_PORT_CONTROL2,10,2, &data);
    }
    else
    {
        retVal = hwGetPortRegField(dev,phyPort,QD_REG_PORT_VLAN_MAP,10,2, &data);
    }

    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }

    *mode = data;
    DBG_INFO(("OK.\n"));
    return GT_OK;
}


/********************************************************************
* gvlnSetPortVlanForceDefaultVID
*
* DESCRIPTION:
*       This routine sets the mode for forcing to use default VID
*
* INPUTS:
*       port    - logical port number to set.
*       mode    - GT_TRUE, force to use default VID
*                 GT_FAULSE, otherwise 
*
* OUTPUTS:
*       None.
*
* RETURNS:
*       GT_OK               - on success
*       GT_FAIL             - on error
*       GT_BAD_PARAM        - on bad parameters
*
* COMMENTS: 
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gvlnSetPortVlanForceDefaultVID
(
    IN GT_QD_DEV        *dev,
    IN GT_LPORT     port,
    IN GT_BOOL      mode
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U8           phyPort;        /* Physical port.               */
    GT_U16          data;           /* Data to be set into the      */

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

    phyPort = GT_LPORT_2_PORT(port);

    /* check if device supports this feature */
    if((retVal = IS_VALID_API_CALL(dev,phyPort, DEV_802_1Q)) != GT_OK ) 
      return retVal;

    BOOL_2_BIT(mode,data);

    retVal = hwSetPortRegField(dev,phyPort,QD_REG_PVID,12,1,data );
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }
    DBG_INFO(("OK.\n"));
    return GT_OK;
}



/*******************************************************************************
* gvlnGetPortVlanForceDefaultVID
*
* DESCRIPTION:
*       This routine gets the port mode for ForceDefaultVID (bit 12).
*
* INPUTS:
*       port     - logical port number to get.
*
* OUTPUTS:
*       mode     - ForceDefaultVID mode for this port 
*
* RETURNS:
*       GT_OK               - on success
*       GT_FAIL             - on error
*       GT_BAD_PARAM        - on bad parameters
*
* COMMENTS: 
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gvlnGetPortVlanForceDefaultVID
(
    IN GT_QD_DEV        *dev,
    IN  GT_LPORT     port,
    OUT GT_BOOL        *mode
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U16          data;           /* The register's read data.    */
    GT_U8           phyPort;        /* Physical port.               */


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

    phyPort = GT_LPORT_2_PORT(port);

    /* check if device supports this feature */
    if((retVal = IS_VALID_API_CALL(dev,phyPort, DEV_802_1Q)) != GT_OK ) 
      return retVal;

    if(mode == NULL)
    {
        DBG_INFO(("Failed.\n"));
        return GT_BAD_PARAM;
    }

    retVal = hwGetPortRegField(dev,phyPort,QD_REG_PVID,12,1, &data);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }

    BIT_2_BOOL(data,*mode);
    DBG_INFO(("OK.\n"));
    return GT_OK;
}


/********************************************************************
* gvlnSetForceMap
*
* DESCRIPTION:
*       This routine enables/disables Force Map feature.
*        When Force Map feature is enabled, all received frames will be
*        considered MGMT and they are mapped to the port or ports defined
*        in the VLAN Table overriding the mapping from the address database.
*
* INPUTS:
*       port    - logical port number to set.
*       mode    - GT_TRUE, to enable force map feature
*                 GT_FAULSE, otherwise 
*
* OUTPUTS:
*       None.
*
* RETURNS:
*       GT_OK               - on success
*       GT_FAIL             - on error
*       GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS: 
*
*******************************************************************************/
GT_STATUS gvlnSetForceMap
(
    IN  GT_QD_DEV   *dev,
    IN  GT_LPORT     port,
    IN  GT_BOOL      mode
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U8           phyPort;        /* Physical port.               */
    GT_U16          data;           /* Data to be set into the reg  */

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

    phyPort = GT_LPORT_2_PORT(port);

    /* check if device supports this feature */
    if (!IS_IN_DEV_GROUP(dev,DEV_FORCE_MAP))
    {
        return GT_NOT_SUPPORTED;
    }

    BOOL_2_BIT(mode,data);

    retVal = hwSetPortRegField(dev,phyPort, QD_REG_PORT_VLAN_MAP, 8, 1, data);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }

    DBG_INFO(("OK.\n"));

    return GT_OK;
}


/********************************************************************
* gvlnGetForceMap
*
* DESCRIPTION:
*       This routine checks if Force Map feature is enabled.
*        When Force Map feature is enabled, all received frames will be
*        considered MGMT and they are mapped to the port or ports defined
*        in the VLAN Table overriding the mapping from the address database.
*
* INPUTS:
*       port    - logical port number to set.
*
* OUTPUTS:
*       mode    - GT_TRUE, to enable force map feature
*                 GT_FAULSE, otherwise 
*
* RETURNS:
*       GT_OK               - on success
*       GT_FAIL             - on error
*       GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS: 
*
*******************************************************************************/
GT_STATUS gvlnGetForceMap
(
    IN  GT_QD_DEV   *dev,
    IN  GT_LPORT     port,
    OUT GT_BOOL      *mode
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U8           phyPort;        /* Physical port.               */
    GT_U16          data;           /* Data to be set into the reg  */

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

    phyPort = GT_LPORT_2_PORT(port);

    /* check if device supports this feature */
    if (!IS_IN_DEV_GROUP(dev,DEV_FORCE_MAP))
    {
        return GT_NOT_SUPPORTED;
    }

    retVal = hwGetPortRegField(dev,phyPort, QD_REG_PORT_VLAN_MAP, 8, 1, &data);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }

    BIT_2_BOOL(data, *mode);

    DBG_INFO(("OK.\n"));

    return GT_OK;
}


/*******************************************************************************
* gvlnSetNoEgrPolicy
*
* DESCRIPTION:
*        No Egress Policy. When this bit is set to a one Egress 802.1Q Secure and
*        Check discards are not performed. This mode allowsa non-802.1Q enabled 
*        port to send a frame to an 802.1Q enabled port that is configured in the
*        Secure or Check 802.1Q mode. In this situation the frames will egress 
*        even if the VID assigned to the frame is not found in the VTU.
*
* INPUTS:
*        mode - no egress policy mode
*
* OUTPUTS:
*        None.
*
* RETURNS:
*        GT_OK   - on success
*        GT_FAIL - on error
*        GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*        None.
*
*******************************************************************************/
GT_STATUS gvlnSetNoEgrPolicy
(
    IN GT_QD_DEV    *dev,
    IN GT_BOOL        mode
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U16          data;           /* Data to be set into the      */

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

    /* Check if Switch supports this status. */
    if (!IS_IN_DEV_GROUP(dev,DEV_NO_EGRESS_POLICY))
    {
        DBG_INFO(("GT_NOT_SUPPORTED\n"));
        return GT_NOT_SUPPORTED;
    }

    BOOL_2_BIT(mode,data);

    /* Set related register */
    retVal = hwSetGlobal2RegField(dev,QD_REG_SDET_POLARITY,13,1,data);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }

    DBG_INFO(("OK.\n"));
    return GT_OK;
}

/*******************************************************************************
* gvlnGetNoEgrPolicy
*
* DESCRIPTION:
*        No Egress Policy. When this bit is set to a one Egress 802.1Q Secure and
*        Check discards are not performed. This mode allowsa non-802.1Q enabled 
*        port to send a frame to an 802.1Q enabled port that is configured in the
*        Secure or Check 802.1Q mode. In this situation the frames will egress 
*        even if the VID assigned to the frame is not found in the VTU.
*
* INPUTS:
*        None.
*
* OUTPUTS:
*        mode - no egress policy mode
*
* RETURNS:
*        GT_OK   - on success
*        GT_FAIL - on error
*        GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*        None.
*
*******************************************************************************/
GT_STATUS gvlnGetNoEgrPolicy
(
    IN  GT_QD_DEV    *dev,
    OUT GT_BOOL        *mode
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U16          data;           /* The register's read data.    */

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

    /* Check if Switch supports this status. */
    if (!IS_IN_DEV_GROUP(dev,DEV_NO_EGRESS_POLICY))
    {
        DBG_INFO(("GT_NOT_SUPPORTED\n"));
        return GT_NOT_SUPPORTED;
    }

    /* Get related register */
    retVal = hwGetGlobal2RegField(dev,QD_REG_SDET_POLARITY,13,1,&data);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }

    BIT_2_BOOL(data,*mode);

    DBG_INFO(("OK.\n"));
    return GT_OK;
}

