#include <Copyright.h>

/*******************************************************************************
* gtBrgVtu.c
*
* DESCRIPTION:
*       API definitions for Vlan Translation Unit for 802.1Q.
*
* DEPENDENCIES:
*
* FILE REVISION NUMBER:
*       $Revision: 9 $
*******************************************************************************/

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

/****************************************************************************/
/* Forward function declaration.                                            */
/****************************************************************************/
#define MEMBER_TAG_CONV_FOR_APP(_dev,_tag)    memberTagConversionForApp(_dev,_tag)
#define MEMBER_TAG_CONV_FOR_DEV(_dev,_tag)    memberTagConversionForDev(_dev,_tag)

static GT_U8 memberTagConversionForApp
(
    IN    GT_QD_DEV           *dev,
    IN    GT_U8               tag
)
{
    GT_U8 convTag;

    /* check if memberTag needs to be converted */
    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))))
        return tag;

    switch(tag)
    {
        case 0:
                convTag = MEMBER_EGRESS_UNMODIFIED;
                break;
        case 1:
                convTag = MEMBER_EGRESS_UNTAGGED;
                break;
        case 2:
                convTag = MEMBER_EGRESS_TAGGED;
                break;
        case 3:
                convTag = NOT_A_MEMBER;
                break;
        default:
                DBG_INFO(("Unknown Tag (%#x) from Device !!!.\n",tag));
                convTag = 0xFF;
                break;

    }

    return convTag;
}

static GT_U8 memberTagConversionForDev
(
    IN    GT_QD_DEV           *dev,
    IN    GT_U8               tag
)
{
    GT_U8 convTag;

    /* check if memberTag needs to be converted */
    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))))
        return tag;

    switch(tag)
    {
        case MEMBER_EGRESS_UNMODIFIED:
                convTag = 0;
                break;
        case NOT_A_MEMBER:
                convTag = 3;
                break;
        case MEMBER_EGRESS_UNTAGGED:
                convTag = 1;
                break;
        case MEMBER_EGRESS_TAGGED:
                convTag = 2;
                break;
        default:
                DBG_INFO(("Unknown Tag (%#x) from App. !!!.\n",tag));
                convTag = 0xFF;
                break;

    }

    return convTag;
}

static GT_STATUS vtuOperationPerform
(
    IN        GT_QD_DEV           *dev,
    IN      GT_VTU_OPERATION    vtuOp,
    INOUT   GT_U8               *valid,
    INOUT     GT_VTU_ENTRY        *vtuEntry
);

/*******************************************************************************
* gvtuGetEntryCount
*
* DESCRIPTION:
*       Gets the current number of valid entries in the VTU table
*
* INPUTS:
*       None.
*
* OUTPUTS:
*       numEntries - number of VTU entries.
*
* RETURNS:
*       GT_OK      - on success
*       GT_FAIL    - on error
*       GT_NO_SUCH - vlan does not exist.
*
* COMMENTS:
*       None
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gvtuGetEntryCount
(
    IN  GT_QD_DEV *dev,
    OUT GT_U32    *numEntries
)
{
    GT_U8               valid;
    GT_U32        numOfEntries;
    GT_STATUS           retVal;
    GT_VTU_ENTRY        entry;

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

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

    entry.vid = 0xFFF;
    entry.DBNum = 0;

    numOfEntries = 0;
    while(1)
    {
        retVal = vtuOperationPerform(dev,GET_NEXT_ENTRY,&valid,&entry);
        if(retVal != GT_OK)
        {
            DBG_INFO(("Failed (vtuOperationPerform returned GT_FAIL).\n"));
            return retVal;
        }

        if( entry.vid==0xFFF )
        {
            if (valid==1) numOfEntries++;
            break;
        }

        numOfEntries++;
    }

    *numEntries = numOfEntries;

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

}


/*******************************************************************************
* gvtuGetEntryFirst
*
* DESCRIPTION:
*       Gets first lexicographic entry from the VTU.
*
* INPUTS:
*       None.
*
* OUTPUTS:
*       vtuEntry - match VTU entry.
*
* RETURNS:
*       GT_OK      - on success
*       GT_FAIL    - on error
*       GT_NO_SUCH - table is empty.
*
* COMMENTS:
*       Search starts from vid of all one's
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gvtuGetEntryFirst
(
    IN  GT_QD_DEV       *dev,
    OUT GT_VTU_ENTRY    *vtuEntry
)
{
    GT_U8               valid;
    GT_STATUS           retVal;
    GT_U8               port;
    GT_LPORT               lport;
    GT_VTU_ENTRY        entry;

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

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

    entry.vid = 0xFFF;
    entry.DBNum = 0;

    retVal = vtuOperationPerform(dev,GET_NEXT_ENTRY,&valid, &entry);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed (vtuOperationPerform returned GT_FAIL).\n"));
        return retVal;
    }

    /* retrive the value from the operation */

    if((entry.vid == 0xFFF) && (valid == 0))
        return GT_NO_SUCH;

    vtuEntry->DBNum = entry.DBNum;
    vtuEntry->vid   = entry.vid;

    vtuEntry->vidPriOverride = entry.vidPriOverride;
    vtuEntry->vidPriority = entry.vidPriority;

    vtuEntry->vidPolicy = entry.vidPolicy;
    vtuEntry->sid = entry.sid;

    vtuEntry->vidExInfo.useVIDFPri = entry.vidExInfo.useVIDFPri;
    vtuEntry->vidExInfo.vidFPri = entry.vidExInfo.vidFPri;
    vtuEntry->vidExInfo.useVIDQPri = entry.vidExInfo.useVIDQPri;
    vtuEntry->vidExInfo.vidQPri = entry.vidExInfo.vidQPri;
    vtuEntry->vidExInfo.vidNRateLimit = entry.vidExInfo.vidNRateLimit;

    for(lport=0; lport<dev->numOfPorts; lport++)
    {
        port = GT_LPORT_2_PORT(lport);
        vtuEntry->vtuData.memberTagP[lport]=MEMBER_TAG_CONV_FOR_APP(dev,entry.vtuData.memberTagP[port]);
        vtuEntry->vtuData.portStateP[lport]=entry.vtuData.portStateP[port];
    }

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


/*******************************************************************************
* gvtuGetEntryNext
*
* DESCRIPTION:
*       Gets next lexicographic VTU entry from the specified VID.
*
* INPUTS:
*       vtuEntry - the VID to start the search.
*
* OUTPUTS:
*       vtuEntry - match VTU  entry.
*
* RETURNS:
*       GT_OK      - on success.
*       GT_FAIL    - on error or entry does not exist.
*       GT_NO_SUCH - no more entries.
*
* COMMENTS:
*       Search starts from the VID specified by the user.
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gvtuGetEntryNext
(
    IN  GT_QD_DEV       *dev,
    INOUT GT_VTU_ENTRY  *vtuEntry
)
{
    GT_U8               valid;
    GT_STATUS           retVal;
    GT_U8               port;
    GT_LPORT               lport;
    GT_VTU_ENTRY        entry;

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

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

    entry.DBNum = vtuEntry->DBNum;
    entry.vid   = vtuEntry->vid;
    valid = 0;

    retVal = vtuOperationPerform(dev,GET_NEXT_ENTRY,&valid, &entry);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed (vtuOperationPerform returned GT_FAIL).\n"));
        return retVal;
    }

    /* retrieve the value from the operation */

    if((entry.vid == 0xFFF) && (valid == 0))
        return GT_NO_SUCH;

    vtuEntry->DBNum = entry.DBNum;
    vtuEntry->vid   = entry.vid;

    vtuEntry->vidPriOverride = entry.vidPriOverride;
    vtuEntry->vidPriority = entry.vidPriority;

    vtuEntry->vidPolicy = entry.vidPolicy;
    vtuEntry->sid = entry.sid;

    vtuEntry->vidExInfo.useVIDFPri = entry.vidExInfo.useVIDFPri;
    vtuEntry->vidExInfo.vidFPri = entry.vidExInfo.vidFPri;
    vtuEntry->vidExInfo.useVIDQPri = entry.vidExInfo.useVIDQPri;
    vtuEntry->vidExInfo.vidQPri = entry.vidExInfo.vidQPri;
    vtuEntry->vidExInfo.vidNRateLimit = entry.vidExInfo.vidNRateLimit;

    for(lport=0; lport<dev->numOfPorts; lport++)
    {
        port = GT_LPORT_2_PORT(lport);
        vtuEntry->vtuData.memberTagP[lport]=MEMBER_TAG_CONV_FOR_APP(dev,entry.vtuData.memberTagP[port]);
        vtuEntry->vtuData.portStateP[lport]=entry.vtuData.portStateP[port];
    }

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



/*******************************************************************************
* gvtuFindVidEntry
*
* DESCRIPTION:
*       Find VTU entry for a specific VID, it will return the entry, if found,
*       along with its associated data
*
* INPUTS:
*       vtuEntry - contains the VID to searche for
*
* OUTPUTS:
*       found    - GT_TRUE, if the appropriate entry exists.
*       vtuEntry - the entry parameters.
*
* RETURNS:
*       GT_OK      - on success.
*       GT_FAIL    - on error or entry does not exist.
*       GT_NO_SUCH - no more entries.
*
* COMMENTS:
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gvtuFindVidEntry
(
    IN  GT_QD_DEV       *dev,
    INOUT GT_VTU_ENTRY  *vtuEntry,
    OUT GT_BOOL         *found
)
{
    GT_U8               valid;
    GT_STATUS           retVal;
    GT_U8               port;
    GT_LPORT            lport;
    GT_VTU_ENTRY        entry;

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

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

    *found = GT_FALSE;

    /* Decrement 1 from vid    */
    entry.vid   = vtuEntry->vid-1;
    valid = 0; /* valid is not used as input in this operation */
    entry.DBNum = vtuEntry->DBNum;

    retVal = vtuOperationPerform(dev,GET_NEXT_ENTRY,&valid, &entry);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed (vtuOperationPerform returned GT_FAIL).\n"));
        return retVal;
    }

    /* retrive the value from the operation */

    if( (entry.vid !=vtuEntry->vid) | (valid !=1) )
    {
          DBG_INFO(("Failed.\n"));
          return GT_NO_SUCH;
    }

    vtuEntry->DBNum = entry.DBNum;

    vtuEntry->vidPriOverride = entry.vidPriOverride;
    vtuEntry->vidPriority = entry.vidPriority;

    vtuEntry->vidPolicy = entry.vidPolicy;
    vtuEntry->sid = entry.sid;

    vtuEntry->vidExInfo.useVIDFPri = entry.vidExInfo.useVIDFPri;
    vtuEntry->vidExInfo.vidFPri = entry.vidExInfo.vidFPri;
    vtuEntry->vidExInfo.useVIDQPri = entry.vidExInfo.useVIDQPri;
    vtuEntry->vidExInfo.vidQPri = entry.vidExInfo.vidQPri;
    vtuEntry->vidExInfo.vidNRateLimit = entry.vidExInfo.vidNRateLimit;

    for(lport=0; lport<dev->numOfPorts; lport++)
    {
        port = GT_LPORT_2_PORT(lport);
        vtuEntry->vtuData.memberTagP[lport]=MEMBER_TAG_CONV_FOR_APP(dev,entry.vtuData.memberTagP[port]);
        vtuEntry->vtuData.portStateP[lport]=entry.vtuData.portStateP[port];
    }

    *found = GT_TRUE;

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



/*******************************************************************************
* gvtuFlush
*
* DESCRIPTION:
*       This routine removes all entries from VTU Table.
*
* INPUTS:
*       None
*
* OUTPUTS:
*       None
*
* RETURNS:
*       GT_OK           - on success
*       GT_FAIL         - on error
*
* COMMENTS:
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gvtuFlush
(
    IN  GT_QD_DEV       *dev
)
{
    GT_STATUS       retVal;

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

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

    retVal = vtuOperationPerform(dev,FLUSH_ALL,NULL,NULL);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }

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

/*******************************************************************************
* gvtuAddEntry
*
* DESCRIPTION:
*       Creates the new entry in VTU table based on user input.
*
* INPUTS:
*       vtuEntry    - vtu entry to insert to the VTU.
*
* OUTPUTS:
*       None
*
* RETURNS:
*       GT_OK             - on success
*       GT_FAIL           - on error
*       GT_FULL              - vtu table is full
*
* COMMENTS:
*       None.
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gvtuAddEntry
(
    IN  GT_QD_DEV   *dev,
    IN GT_VTU_ENTRY *vtuEntry
)
{
    GT_U8               valid;
    GT_STATUS           retVal;
    GT_U8           port;
    GT_LPORT           lport;
    GT_VTU_ENTRY     tmpVtuEntry;
    GT_BOOL             found;
    int                count = 5000;
    GT_VTU_ENTRY        entry;

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

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

    entry.DBNum = vtuEntry->DBNum;
    entry.vid   = vtuEntry->vid;

    if(IS_IN_DEV_GROUP(dev,DEV_VTU_EXT_INFO))
    {
        entry.vidPriOverride = 0;
        entry.vidPriority = 0;

        entry.vidPolicy = GT_FALSE;
        entry.sid = 0;

        if(IS_IN_DEV_GROUP(dev,DEV_FQPRI_IN_TABLE))
        {
            entry.vidExInfo.useVIDFPri = vtuEntry->vidExInfo.useVIDFPri;
            entry.vidExInfo.vidFPri = vtuEntry->vidExInfo.vidFPri;
            entry.vidExInfo.useVIDQPri = vtuEntry->vidExInfo.useVIDQPri;
            entry.vidExInfo.vidQPri = vtuEntry->vidExInfo.vidQPri;
            entry.vidExInfo.vidNRateLimit = vtuEntry->vidExInfo.vidNRateLimit;
        }
        else
        {
            entry.vidExInfo.useVIDFPri = 0;
            entry.vidExInfo.vidFPri = 0;
            entry.vidExInfo.useVIDQPri = 0;
            entry.vidExInfo.vidQPri = 0;
            entry.vidExInfo.vidNRateLimit = vtuEntry->vidExInfo.vidNRateLimit;
        }
    }
    else
    {
        entry.vidPriOverride = vtuEntry->vidPriOverride;
        entry.vidPriority = vtuEntry->vidPriority;

        if(IS_IN_DEV_GROUP(dev,DEV_POLICY))
        {
            entry.vidPolicy = vtuEntry->vidPolicy;
        }
        else
        {
            entry.vidPolicy = GT_FALSE;
        }

        if(IS_IN_DEV_GROUP(dev,DEV_802_1S_STU))
        {
            entry.sid = vtuEntry->sid;
        }
        else
        {
            entry.sid = 0;
        }

        entry.vidExInfo.useVIDFPri = 0;
        entry.vidExInfo.vidFPri = 0;
        entry.vidExInfo.useVIDQPri = 0;
        entry.vidExInfo.vidQPri = 0;
        entry.vidExInfo.vidNRateLimit = 0;
    }

    valid = 1; /* for load operation */

    for(port=0; port<dev->maxPorts; port++)
    {
        lport = GT_PORT_2_LPORT(port);
        if(lport == GT_INVALID_PORT)
        {
            entry.vtuData.memberTagP[port] = MEMBER_TAG_CONV_FOR_DEV(dev,NOT_A_MEMBER);
            entry.vtuData.portStateP[port] = 0;
        }
        else
        {
            entry.vtuData.memberTagP[port] = MEMBER_TAG_CONV_FOR_DEV(dev,vtuEntry->vtuData.memberTagP[lport]);
            if (IS_IN_DEV_GROUP(dev,DEV_802_1S))
                entry.vtuData.portStateP[port] = vtuEntry->vtuData.portStateP[lport];
            else
                entry.vtuData.portStateP[port] = 0;
        }
    }

    retVal = vtuOperationPerform(dev,LOAD_PURGE_ENTRY,&valid, &entry);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed (vtuOperationPerform returned GT_FAIL).\n"));
        return retVal;
    }

    /* verify that the given entry has been added */
    tmpVtuEntry.vid = vtuEntry->vid;
    tmpVtuEntry.DBNum = vtuEntry->DBNum;

    if((retVal = gvtuFindVidEntry(dev,&tmpVtuEntry,&found)) != GT_OK)
    {
        while(count--);
        if((retVal = gvtuFindVidEntry(dev,&tmpVtuEntry,&found)) != GT_OK)
        {
            DBG_INFO(("Added entry cannot be found\n"));
            return retVal;
        }
    }
    if(found == GT_FALSE)
    {
        DBG_INFO(("Added entry cannot be found\n"));
        return GT_FAIL;
    }

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

/*******************************************************************************
* gvtuDelEntry
*
* DESCRIPTION:
*       Deletes VTU entry specified by user.
*
* INPUTS:
*       vtuEntry - the VTU entry to be deleted
*
* OUTPUTS:
*       None.
*
* RETURNS:
*       GT_OK           - on success
*       GT_FAIL         - on error
*       GT_NO_SUCH      - if specified address entry does not exist
*
* COMMENTS:
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gvtuDelEntry
(
    IN  GT_QD_DEV   *dev,
    IN GT_VTU_ENTRY *vtuEntry
)
{
    GT_U8               valid;
    GT_STATUS           retVal;
    GT_VTU_ENTRY        entry;

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

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

    entry.DBNum = vtuEntry->DBNum;
    entry.vid   = vtuEntry->vid;
    valid = 0; /* for delete operation */

    retVal = vtuOperationPerform(dev,LOAD_PURGE_ENTRY,&valid, &entry);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed (vtuOperationPerform returned GT_FAIL).\n"));
        return retVal;
    }
    DBG_INFO(("OK.\n"));
    return GT_OK;
}

/****************************************************************************/
/* Internal use functions.                                                  */
/****************************************************************************/

/*******************************************************************************
* gvtuGetViolation
*
* DESCRIPTION:
*       Get VTU Violation data
*
* INPUTS:
*       None.
*
* OUTPUTS:
*       vtuIntStatus - interrupt cause, source portID, and vid.
*
* RETURNS:
*       GT_OK           - on success
*       GT_FAIL         - on error
*       GT_NOT_SUPPORT  - if current device does not support this feature.
*
* COMMENTS:
*        This is an internal function. No user should call this function.
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gvtuGetViolation
(
    IN  GT_QD_DEV         *dev,
    OUT GT_VTU_INT_STATUS *vtuIntStatus
)
{
    GT_U8               spid;
    GT_U16               vid;
    GT_U16               intCause;
    GT_STATUS           retVal;
    GT_VTU_ENTRY        entry;

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

    /* check which Violation occurred */
    retVal = hwGetGlobalRegField(dev,QD_REG_VTU_OPERATION,4,3,&intCause);
    if(retVal != GT_OK)
    {
        DBG_INFO(("ERROR to read VTU OPERATION Register.\n"));
        return retVal;
    }

    if (intCause == 0)
    {
        /* No Violation occurred. */
        vtuIntStatus->vtuIntCause = 0;
        return GT_OK;
    }

    entry.DBNum = 0;

    retVal = vtuOperationPerform(dev,SERVICE_VIOLATIONS,NULL, &entry);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed (vtuOperationPerform returned GT_FAIL).\n"));
        return retVal;
    }

    spid = entry.DBNum & 0xF;
    vid = entry.vid;

    if(spid == 0xF)
    {
        vtuIntStatus->vtuIntCause = GT_VTU_FULL_VIOLATION;
        vtuIntStatus->spid = spid;
        vtuIntStatus->vid = 0;
    }
    else
    {
        vtuIntStatus->vtuIntCause = intCause & (GT_MEMBER_VIOLATION | GT_MISS_VIOLATION);
        vtuIntStatus->spid = spid;
        vtuIntStatus->vid = vid;
    }

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

/*******************************************************************************
* gvtuGetViolation2
*
* DESCRIPTION:
*       Get VTU Violation data (for Gigabit Device)
*
* INPUTS:
*       None.
*
* OUTPUTS:
*       vtuIntStatus - interrupt cause, source portID, and vid.
*
* RETURNS:
*       GT_OK           - on success
*       GT_FAIL         - on error
*       GT_NOT_SUPPORT  - if current device does not support this feature.
*
* COMMENTS:
*        This is an internal function. No user should call this function.
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gvtuGetViolation2
(
    IN  GT_QD_DEV         *dev,
    OUT GT_VTU_INT_STATUS *vtuIntStatus
)
{
    GT_U16               intCause;
    GT_STATUS           retVal;
    GT_VTU_ENTRY        entry;

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

    /* check if Violation occurred */
    retVal = hwGetGlobalRegField(dev,QD_REG_GLOBAL_STATUS,5,1,&intCause);
    if(retVal != GT_OK)
    {
        DBG_INFO(("ERROR to read VTU OPERATION Register.\n"));
        return retVal;
    }

    if (intCause == 0)
    {
        /* No Violation occurred. */
        vtuIntStatus->vtuIntCause = 0;
        return GT_OK;
    }

    entry.DBNum = 0;

    retVal = vtuOperationPerform(dev,SERVICE_VIOLATIONS,NULL, &entry);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed (vtuOperationPerform returned GT_FAIL).\n"));
        return retVal;
    }

    /* check which Violation occurred */
    retVal = hwGetGlobalRegField(dev,QD_REG_VTU_OPERATION,5,2,&intCause);
    if(retVal != GT_OK)
    {
        DBG_INFO(("ERROR to read VTU OPERATION Register.\n"));
        return retVal;
    }

    switch (intCause)
    {
        case 0:
            /* No Violation occurred. */
            vtuIntStatus->vtuIntCause = 0;
            return GT_OK;
        case 1:
            /* Miss Violation */
            vtuIntStatus->vtuIntCause = GT_MISS_VIOLATION;
            break;
        case 2:
            /* Member Violation */
            vtuIntStatus->vtuIntCause = GT_MEMBER_VIOLATION;
            break;
        default :
            return GT_FAIL;
    }

    vtuIntStatus->spid = entry.DBNum & 0xF;
    vtuIntStatus->vid = entry.vid;

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

/*******************************************************************************
* gvtuGetViolation3
*
* DESCRIPTION:
*       Get VTU Violation data
*
* INPUTS:
*       None.
*
* OUTPUTS:
*       vtuIntStatus - interrupt cause, source portID, and vid.
*
* RETURNS:
*       GT_OK           - on success
*       GT_FAIL         - on error
*       GT_NOT_SUPPORT  - if current device does not support this feature.
*
* COMMENTS:
*        This is an internal function. No user should call this function.
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gvtuGetViolation3
(
    IN  GT_QD_DEV         *dev,
    OUT GT_VTU_INT_STATUS *vtuIntStatus
)
{
    GT_U16               intCause;
    GT_STATUS           retVal;
    GT_VTU_ENTRY        entry;

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

    /* check if Violation occurred */
    retVal = hwGetGlobalRegField(dev,QD_REG_GLOBAL_STATUS,5,1,&intCause);
    if(retVal != GT_OK)
    {
        DBG_INFO(("ERROR to read VTU OPERATION Register.\n"));
        return retVal;
    }

    if (intCause == 0)
    {
        /* No Violation occurred. */
        vtuIntStatus->vtuIntCause = 0;
        return GT_OK;
    }

    entry.DBNum = 0;

    retVal = vtuOperationPerform(dev,SERVICE_VIOLATIONS,NULL, &entry);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed (vtuOperationPerform returned GT_FAIL).\n"));
        return retVal;
    }

    /* check which Violation occurred */
    retVal = hwGetGlobalRegField(dev,QD_REG_VTU_OPERATION,4,3,&intCause);
    if(retVal != GT_OK)
    {
        DBG_INFO(("ERROR to read VTU OPERATION Register.\n"));
        return retVal;
    }

    vtuIntStatus->vtuIntCause = 0;

    if(intCause & 0x1)
    {
        vtuIntStatus->vtuIntCause |= GT_VTU_FULL_VIOLATION;
    }

    if(intCause & 0x2)
    {
        vtuIntStatus->vtuIntCause |= GT_MISS_VIOLATION;
    }

    if(intCause & 0x4)
    {
        vtuIntStatus->vtuIntCause |= GT_MEMBER_VIOLATION;
    }

    vtuIntStatus->spid = entry.DBNum & 0xF;
    vtuIntStatus->vid = entry.vid;

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


/*******************************************************************************
* vtuOperationPerform
*
* DESCRIPTION:
*       This function is used by all VTU control functions, and is responsible
*       to write the required operation into the VTU registers.
*
* INPUTS:
*       vtuOp       - The VTU operation bits to be written into the VTU
*                     operation register.
*       DBNum       - DBNum where the given vid belongs to
*       vid         - vlan id
*       valid       - valid bit
*       vtuData     - VTU Data with memberTag information
*
* OUTPUTS:
*       DBNum       - DBNum where the given vid belongs to
*       vid         - vlan id
*       valid       - valid bit
*       vtuData     - VTU Data with memberTag information
*
* RETURNS:
*       GT_OK on success,
*       GT_FAIL otherwise.
*
* COMMENTS:
*
*******************************************************************************/

static GT_STATUS vtuOperationPerform
(
    IN        GT_QD_DEV           *dev,
    IN      GT_VTU_OPERATION    vtuOp,
    INOUT   GT_U8               *valid,
    INOUT    GT_VTU_ENTRY        *entry
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U16          data;           /* Data to be set into the      */
                                /* register.                    */

    gtSemTake(dev,dev->vtuRegsSem,OS_WAIT_FOREVER);

    /* Wait until the VTU in ready. */
#ifdef GT_RMGMT_ACCESS
    {
      HW_DEV_REG_ACCESS regAccess;

      regAccess.entries = 1;

      regAccess.rw_reg_list[0].cmd = HW_REG_WAIT_TILL_0;
      regAccess.rw_reg_list[0].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL_REG_ACCESS);
      regAccess.rw_reg_list[0].reg = QD_REG_VTU_OPERATION;
      regAccess.rw_reg_list[0].data = 15;
      retVal = hwAccessMultiRegs(dev, &regAccess);
      if(retVal != GT_OK)
      {
        gtSemGive(dev,dev->vtuRegsSem);
        return retVal;
      }
    }
#else
    data = 1;
    while(data == 1)
    {
        retVal = hwGetGlobalRegField(dev,QD_REG_VTU_OPERATION,15,1,&data);
        if(retVal != GT_OK)
        {
            gtSemGive(dev,dev->vtuRegsSem);
            return retVal;
        }
    }
#endif

    /* Set the VTU data register    */
    /* There is no need to setup data reg. on flush, get next, or service violation */
    if((vtuOp != FLUSH_ALL) && (vtuOp != GET_NEXT_ENTRY) && (vtuOp != SERVICE_VIOLATIONS))
    {

        /****************** VTU DATA 1 REG *******************/

        /* get data and wirte to QD_REG_VTU_DATA1_REG (ports 0 to 3) */

        data =  (entry->vtuData.memberTagP[0] & 3)     |
                ((entry->vtuData.memberTagP[1] & 3)<<4) |
                ((entry->vtuData.memberTagP[2] & 3)<<8);

        if (IS_IN_DEV_GROUP(dev,DEV_802_1S))
            data |= ((entry->vtuData.portStateP[0] & 3)<<2)    |
                    ((entry->vtuData.portStateP[1] & 3)<<6) |
                    ((entry->vtuData.portStateP[2] & 3)<<10);

        if(dev->maxPorts > 3)
        {
            data |= ((entry->vtuData.memberTagP[3] & 3)<<12) ;
            if (IS_IN_DEV_GROUP(dev,DEV_802_1S))
                data |= ((entry->vtuData.portStateP[3] & 3)<<14) ;
        }

        retVal = hwWriteGlobalReg(dev,QD_REG_VTU_DATA1_REG,data);
        if(retVal != GT_OK)
        {
            gtSemGive(dev,dev->vtuRegsSem);
            return retVal;
        }

        /****************** VTU DATA 2 REG *******************/

        /* get data and wirte to QD_REG_VTU_DATA2_REG (ports 4 to 7) */

        if(dev->maxPorts > 4)
        {
            /* also need to set data register  ports 4 to 6 */

            data =  (entry->vtuData.memberTagP[4] & 3)   |
                    ((entry->vtuData.memberTagP[5] & 3) << 4);

            if (IS_IN_DEV_GROUP(dev,DEV_802_1S))
                data |= ((entry->vtuData.portStateP[4] & 3) << 2) |
                        ((entry->vtuData.portStateP[5] & 3) << 6);

            if(dev->maxPorts > 6)
            {
                data |= ((entry->vtuData.memberTagP[6] & 3)<<8) ;
                if (IS_IN_DEV_GROUP(dev,DEV_802_1S))
                    data |= ((entry->vtuData.portStateP[6] & 3)<<10) ;
            }

            if(dev->maxPorts > 7)
            {
                data |= ((entry->vtuData.memberTagP[7] & 3)<<12) ;
                if (IS_IN_DEV_GROUP(dev,DEV_802_1S))
                    data |= ((entry->vtuData.portStateP[7] & 3)<<14) ;
            }

            if (IS_IN_DEV_GROUP(dev,DEV_VTU_EXT_INFO))
            {
                if(entry->vidExInfo.useVIDFPri == GT_TRUE)
                    data |= ((1 << 15) | ((entry->vidExInfo.vidFPri & 0x7) << 12));
                if(entry->vidExInfo.useVIDQPri == GT_TRUE)
                    data |= ((1 << 11) | ((entry->vidExInfo.vidQPri & 0x3) << 9));
                if(entry->vidExInfo.vidNRateLimit == GT_TRUE)
                    data |= (1 << 8);
            }

            retVal = hwWriteGlobalReg(dev,QD_REG_VTU_DATA2_REG,data);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->vtuRegsSem);
                return retVal;
            }
        }


        /****************** VTU DATA 3 REG *******************/

        /* get data and wirte to QD_REG_VTU_DATA3_REG (ports 8 to 10) */

        if(dev->maxPorts > 7)
        {
            /* also need to set data register  ports 8 to 9 */

            data =  (entry->vtuData.memberTagP[8] & 3)   |
                    ((entry->vtuData.memberTagP[9] & 3) << 4);

            if (IS_IN_DEV_GROUP(dev,DEV_802_1S))
                data |= ((entry->vtuData.portStateP[8] & 3) << 2)    |
                        ((entry->vtuData.portStateP[9] & 3) << 6);

            if(dev->maxPorts > 10)
            {
                data |= (entry->vtuData.memberTagP[10] & 3) << 8;

                if (IS_IN_DEV_GROUP(dev,DEV_802_1S))
                    data |= (entry->vtuData.portStateP[10] & 3) << 10;
            }

            if (IS_IN_DEV_GROUP(dev,DEV_GIGABIT_SWITCH))
            {
                if(entry->vidPriOverride == GT_TRUE)
                    data |= ((1 << 15) | ((entry->vidPriority & 0x7) << 12));
            }

            retVal = hwWriteGlobalReg(dev,QD_REG_VTU_DATA3_REG,data);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->vtuRegsSem);
                return retVal;
            }
        }
        else if (IS_IN_DEV_GROUP(dev,DEV_GIGABIT_SWITCH))
        {
            if(entry->vidPriOverride == GT_TRUE)
                data = ((1 << 15) | ((entry->vidPriority & 0x7) << 12));
            else
                data = 0;

            retVal = hwWriteGlobalReg(dev,QD_REG_VTU_DATA3_REG,data);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->vtuRegsSem);
                return retVal;
            }
        }
    }

    /* Set the VID register (QD_REG_VTU_VID_REG) */
    /* There is no need to setup VID reg. on flush and service violation */
    if((vtuOp != FLUSH_ALL) && (vtuOp != SERVICE_VIOLATIONS) )
    {
        data= ( (entry->vid) & 0xFFF ) | ( (*valid) << 12 );
        retVal = hwWriteGlobalReg(dev,(GT_U8)(QD_REG_VTU_VID_REG),data);
        if(retVal != GT_OK)
        {
            gtSemGive(dev,dev->vtuRegsSem);
            return retVal;
        }
    }

    /* Set SID, FID, VIDPolicy, if it's Load operation */
    if((vtuOp == LOAD_PURGE_ENTRY) && (*valid == 1))
    {
        if(IS_IN_DEV_GROUP(dev,DEV_802_1S_STU))
        {
            data= (entry->sid) & 0x3F;
            retVal = hwWriteGlobalReg(dev,(GT_U8)(QD_REG_STU_SID_REG),data);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->vtuRegsSem);
                return retVal;
            }
        }

        data = 0;

        if(IS_IN_DEV_GROUP(dev,DEV_FID_REG))
        {
            if(IS_IN_DEV_GROUP(dev,DEV_POLICY))
            {
                data= entry->vidPolicy << 12;
            }

            data |= (entry->DBNum & 0xFFF);

            retVal = hwWriteGlobalReg(dev,(GT_U8)(QD_REG_VTU_FID_REG),data);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->vtuRegsSem);
                return retVal;
            }
        }


    }

    /* Start the VTU Operation by defining the DBNum, vtuOp and VTUBusy    */
    /*
     * Flush operation will skip the above two setup (for data and vid), and
     * come to here directly
     */

    if(vtuOp == FLUSH_ALL)
        data = (1 << 15) | (vtuOp << 12);
    else
    {
        if(IS_IN_DEV_GROUP(dev,DEV_FID_REG))
        {
            data = (1 << 15) | (vtuOp << 12);
        }
        else if (IS_IN_DEV_GROUP(dev,DEV_DBNUM_256))
        {
            /* Since DBNum is defined as GT_U8, it cannot be >= 256. */
            #if 0
            if(entry->DBNum >= 256)
            {
                gtSemGive(dev,dev->vtuRegsSem);
                return GT_BAD_PARAM;
            }
            #endif
            data = (1 << 15) | (vtuOp << 12) | ((entry->DBNum & 0xF0) << 4) | (entry->DBNum & 0x0F);
        }
        else if (IS_IN_DEV_GROUP(dev,DEV_DBNUM_64))
        {
            if(entry->DBNum >= 64)
            {
                gtSemGive(dev,dev->vtuRegsSem);
                return GT_BAD_PARAM;
            }
            data = (1 << 15) | (vtuOp << 12) | ((entry->DBNum & 0x30) << 4) | (entry->DBNum & 0x0F);
        }
        else
        {
            if(entry->DBNum >= 16)
            {
                gtSemGive(dev,dev->vtuRegsSem);
                return GT_BAD_PARAM;
            }
            data = (1 << 15) | (vtuOp << 12) | entry->DBNum;
        }
    }

    retVal = hwWriteGlobalReg(dev,QD_REG_VTU_OPERATION,data);
    if(retVal != GT_OK)
    {
        gtSemGive(dev,dev->vtuRegsSem);
        return retVal;
    }

    /* only two operations need to go through the mess below to get some data
     * after the operations -  service violation and get next entry
     */

    /* If the operation is to service violation operation wait for the response   */
    if(vtuOp == SERVICE_VIOLATIONS)
    {
#ifdef GT_RMGMT_ACCESS
        {
          HW_DEV_REG_ACCESS regAccess;

          regAccess.entries = 1;

          regAccess.rw_reg_list[0].cmd = HW_REG_WAIT_TILL_0;
          regAccess.rw_reg_list[0].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL_REG_ACCESS);
          regAccess.rw_reg_list[0].reg = QD_REG_VTU_OPERATION;
          regAccess.rw_reg_list[0].data = 15;
          retVal = hwAccessMultiRegs(dev, &regAccess);
          if(retVal != GT_OK)
          {
            gtSemGive(dev,dev->vtuRegsSem);
            return retVal;
          }
        }
#else
        /* Wait until the VTU in ready. */
        data = 1;
        while(data == 1)
        {
            retVal = hwGetGlobalRegField(dev,QD_REG_VTU_OPERATION,15,1,&data);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->vtuRegsSem);
                return retVal;
            }
        }
#endif

        /* get the Source Port ID that was involved in the violation */
        retVal = hwGetGlobalRegField(dev,QD_REG_VTU_OPERATION,0,4,&data);
        if(retVal != GT_OK)
        {
            gtSemGive(dev,dev->vtuRegsSem);
            return retVal;
        }

        entry->DBNum = (GT_U8)(data & 0xF);

        /* get the VID that was involved in the violation */

        retVal = hwReadGlobalReg(dev,QD_REG_VTU_VID_REG,&data);
        if(retVal != GT_OK)
        {
            gtSemGive(dev,dev->vtuRegsSem);
            return retVal;
        }

        /* Get the vid - bits 0-11 */
        entry->vid   = data & 0xFFF;


    } /* end of service violations */

    /* If the operation is a get next operation wait for the response   */
    if(vtuOp == GET_NEXT_ENTRY)
    {
        entry->vidExInfo.useVIDFPri = GT_FALSE;
        entry->vidExInfo.vidFPri = 0;

        entry->vidExInfo.useVIDQPri = GT_FALSE;
        entry->vidExInfo.vidQPri = 0;

        entry->vidExInfo.vidNRateLimit = GT_FALSE;

        entry->sid = 0;
           entry->vidPolicy = GT_FALSE;

        /* Wait until the VTU in ready. */
#ifdef GT_RMGMT_ACCESS
        {
          HW_DEV_REG_ACCESS regAccess;

          regAccess.entries = 1;

          regAccess.rw_reg_list[0].cmd = HW_REG_WAIT_TILL_0;
          regAccess.rw_reg_list[0].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL_REG_ACCESS);
          regAccess.rw_reg_list[0].reg = QD_REG_VTU_OPERATION;
          regAccess.rw_reg_list[0].data = 15;
          retVal = hwAccessMultiRegs(dev, &regAccess);
          if(retVal != GT_OK)
          {
            gtSemGive(dev,dev->vtuRegsSem);
            return retVal;
          }
        }
#else
        data = 1;
        while(data == 1)
        {
            retVal = hwGetGlobalRegField(dev,QD_REG_VTU_OPERATION,15,1,&data);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->vtuRegsSem);
                return retVal;
            }
        }
#endif

        /****************** get the vid *******************/

        retVal = hwReadGlobalReg(dev,QD_REG_VTU_VID_REG,&data);
        if(retVal != GT_OK)
        {
            gtSemGive(dev,dev->vtuRegsSem);
            return retVal;
        }

        /* the vid is bits 0-11 */
        entry->vid   = data & 0xFFF;

        /* the vid valid is bits 12 */
        *valid   = (data >> 12) & 1;

        if (*valid == 0)
        {
            gtSemGive(dev,dev->vtuRegsSem);
            return GT_OK;
        }

        /****************** get the SID *******************/
        if(IS_IN_DEV_GROUP(dev,DEV_802_1S_STU))
        {
            retVal = hwReadGlobalReg(dev,(GT_U8)(QD_REG_STU_SID_REG),&data);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->vtuRegsSem);
                return retVal;
            }
            entry->sid = data & 0x3F;
        }

        /****************** get the DBNum *******************/
        if(IS_IN_DEV_GROUP(dev,DEV_FID_REG))
        {
            retVal = hwReadGlobalReg(dev,(GT_U8)(QD_REG_VTU_FID_REG),&data);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->vtuRegsSem);
                return retVal;
            }

            if(IS_IN_DEV_GROUP(dev,DEV_POLICY))
            {
                entry->vidPolicy = (data >> 12) & 0x1;
            }

            entry->DBNum = data & 0xFFF;

        }
        else
        {
            retVal = hwGetGlobalRegField(dev,QD_REG_VTU_OPERATION,0,4,&data);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->vtuRegsSem);
                return retVal;
            }

            entry->DBNum = data & 0xF;

            if (IS_IN_DEV_GROUP(dev,DEV_DBNUM_256))
            {
                retVal = hwGetGlobalRegField(dev,QD_REG_VTU_OPERATION,8,4,&data);
                if(retVal != GT_OK)
                {
                    gtSemGive(dev,dev->vtuRegsSem);
                    return retVal;
                }

                entry->DBNum |= ((data & 0xF) << 4);
            }
            else if (IS_IN_DEV_GROUP(dev,DEV_DBNUM_64))
            {
                retVal = hwGetGlobalRegField(dev,QD_REG_VTU_OPERATION,8,2,&data);
                if(retVal != GT_OK)
                {
                    gtSemGive(dev,dev->vtuRegsSem);
                    return retVal;
                }

                entry->DBNum |= ((data & 0x3) << 4);
            }
        }


        /****************** get the MemberTagP *******************/
        retVal = hwReadGlobalReg(dev,QD_REG_VTU_DATA1_REG,&data);
        if(retVal != GT_OK)
        {
            gtSemGive(dev,dev->vtuRegsSem);
            return retVal;
        }

        /* get data from data register for ports 0 to 2 */
        entry->vtuData.memberTagP[0]  =  data & 3 ;
        entry->vtuData.memberTagP[1]  = (data >> 4) & 3 ;
        entry->vtuData.memberTagP[2]  = (data >> 8) & 3 ;
        entry->vtuData.portStateP[0]  = (data >> 2) & 3 ;
        entry->vtuData.portStateP[1]  = (data >> 6) & 3 ;
        entry->vtuData.portStateP[2]  = (data >> 10) & 3 ;

        /****************** for the switch more than 3 ports *****************/

        if(dev->maxPorts > 3)
        {
            /* fullsail has 3 ports, clippership has 7 prots */
            entry->vtuData.memberTagP[3]  = (data >>12) & 3 ;
            entry->vtuData.portStateP[3]  = (data >>14) & 3 ;

            /* get data from data register for ports 4 to 6 */
            retVal = hwReadGlobalReg(dev,QD_REG_VTU_DATA2_REG,&data);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->vtuRegsSem);
                return retVal;
            }
            entry->vtuData.memberTagP[4]  = data & 3 ;
            entry->vtuData.memberTagP[5]  = (data >> 4) & 3 ;
            entry->vtuData.portStateP[4]  = (data >> 2) & 3 ;
            entry->vtuData.portStateP[5]  = (data >> 6) & 3 ;

            if(dev->maxPorts > 6)
            {
                entry->vtuData.memberTagP[6]  = (data >> 8) & 3 ;
                entry->vtuData.portStateP[6]  = (data >> 10) & 3 ;
            }

            if (IS_IN_DEV_GROUP(dev,DEV_VTU_EXT_INFO))
            {
                entry->vidPriOverride = 0;
                entry->vidPriority = 0;

                entry->vidExInfo.useVIDFPri = (data & 0x8000)?GT_TRUE:GT_FALSE;
                entry->vidExInfo.vidFPri = (data >> 12) & 0x7;

                entry->vidExInfo.useVIDQPri = (data & 0x0800)?GT_TRUE:GT_FALSE;
                entry->vidExInfo.vidQPri = (data >> 9) & 0x3;

                entry->vidExInfo.vidNRateLimit = (data & 0x0100)?GT_TRUE:GT_FALSE;
            }
        }
        /****************** upto 7 port switch *******************/

        /****************** for the switch more than 7 ports *****************/

        if(dev->maxPorts > 7)
        {
            /* fullsail has 3 ports, clippership has 7 prots */
            entry->vtuData.memberTagP[7]  = (data >>12) & 3 ;
            entry->vtuData.portStateP[7]  = (data >>14) & 3 ;

            /* get data from data register for ports 4 to 6 */
            retVal = hwReadGlobalReg(dev,QD_REG_VTU_DATA3_REG,&data);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->vtuRegsSem);
                return retVal;
            }
            entry->vtuData.memberTagP[8]  = data & 3 ;
            entry->vtuData.memberTagP[9]  = (data >> 4) & 3 ;
            entry->vtuData.portStateP[8]  = (data >> 2) & 3 ;
            entry->vtuData.portStateP[9]  = (data >> 6) & 3 ;

            if(dev->maxPorts > 10)
            {
                entry->vtuData.memberTagP[10]  = (data >> 8) & 3 ;
                entry->vtuData.portStateP[10]  = (data >> 10) & 3 ;
            }

            if (IS_IN_DEV_GROUP(dev,DEV_GIGABIT_SWITCH))
            {
                if (data & 0x8000)
                {
                    entry->vidPriOverride = GT_TRUE;
                    entry->vidPriority = (data >> 12) & 0x7;
                }
                else
                {
                    entry->vidPriOverride = GT_FALSE;
                    entry->vidPriority = 0;
                }
            }

        }
        else if (IS_IN_DEV_GROUP(dev,DEV_GIGABIT_SWITCH))
        {
            /* get data from data register for ports 4 to 6 */
            retVal = hwReadGlobalReg(dev,QD_REG_VTU_DATA3_REG,&data);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->vtuRegsSem);
                return retVal;
            }

            if (data & 0x8000)
            {
                entry->vidPriOverride = GT_TRUE;
                entry->vidPriority = (data >> 12) & 0x7;
            }
            else
            {
                entry->vidPriOverride = GT_FALSE;
                entry->vidPriority = 0;
            }
        }

        /****************** upto 11 ports switch *******************/

    } /* end of get next entry */

    gtSemGive(dev,dev->vtuRegsSem);
    return GT_OK;
}
