#include <Copyright.h>

/********************************************************************************
* gtBrgFdb.c
*
* DESCRIPTION:
*       API definitions for Multiple Forwarding Databases
*
* DEPENDENCIES:
*
* FILE REVISION NUMBER:
*       $Revision: 9 $
*******************************************************************************/

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

/****************************************************************************/
/* Forward function declaration.                                            */
/****************************************************************************/
static GT_STATUS atuOperationPerform
(
    IN      GT_QD_DEV           *dev,
    IN      GT_ATU_OPERATION    atuOp,
    INOUT    GT_EXTRA_OP_DATA    *opData,
    INOUT     GT_ATU_ENTRY        *atuEntry
);

static GT_STATUS atuStateAppToDev
(
    IN  GT_QD_DEV    *dev,
    IN  GT_BOOL        unicast,
    IN  GT_U32        state,
    OUT GT_U32        *newOne
);

static GT_STATUS atuStateDevToApp
(
    IN  GT_QD_DEV    *dev,
    IN  GT_BOOL        unicast,
    IN  GT_U32        state,
    OUT GT_U32        *newOne
);

static GT_STATUS atuGetStats
(
    IN  GT_QD_DEV    *dev,
    IN  GT_ATU_STAT    *atuStat,
    OUT GT_U32        *count
);


/*******************************************************************************
* gfdbSetPortAtuLearnLimit
*
* DESCRIPTION:
*       Port's auto learning limit. When the limit is non-zero value, the number
*        of MAC addresses that can be learned on this port are limited to the value
*        specified in this API. When the learn limit has been reached any frame
*        that ingresses this port with a source MAC address not already in the
*        address database that is associated with this port will be discarded.
*        Normal auto-learning will resume on the port as soon as the number of
*        active unicast MAC addresses associated to this port is less than the
*        learn limit.
*        CPU directed ATU Load, Purge, or Move will not have any effect on the
*        learn limit.
*        This feature is disabled when the limit is zero.
*        The following care is needed when enabling this feature:
*            1) dsable learning on the ports
*            2) flush all non-static addresses in the ATU
*            3) define the desired limit for the ports
*            4) re-enable learing on the ports
*
* INPUTS:
*       port  - logical port number
*       limit - auto learning limit ( 0 ~ 255 )
*
* OUTPUTS:
*       None.
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*        GT_BAD_PARAM - if limit > 0xFF
*       GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*       None.
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gfdbSetPortAtuLearnLimit
(
    IN  GT_QD_DEV     *dev,
    IN  GT_LPORT      port,
    IN  GT_U32       limit
)
{
    GT_U16          data, mask;
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U8           hwPort;         /* the physical port number     */

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

    /* translate LPORT to hardware port */
    hwPort = GT_LPORT_2_PORT(port);

    /* Check device if it has fixed ATU Size. */
    if (!IS_IN_DEV_GROUP(dev,DEV_ATU_LIMIT))
    {
        return GT_NOT_SUPPORTED;
    }

    if (limit > 0xFF)
    {
        DBG_INFO(("Bad Parameter\n"));
        return GT_BAD_PARAM;
    }

    mask = 0x80FF;

    if (IS_IN_DEV_GROUP(dev,DEV_ATU_LIMIT_READ))
        mask |= 0x1000;

    data = (GT_U16) limit;

    /* Set the learn limit bits.                  */
    retVal = hwSetPortRegBits(dev,hwPort, QD_REG_PORT_ATU_CONTROL, mask, data);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }

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


/*******************************************************************************
* gfdbGetPortAtuLearnLimit
*
* DESCRIPTION:
*      Port's auto learning limit. When the limit is non-zero value, the number
*        of MAC addresses that can be learned on this port are limited to the value
*        specified in this API. When the learn limit has been reached any frame
*        that ingresses this port with a source MAC address not already in the
*        address database that is associated with this port will be discarded.
*        Normal auto-learning will resume on the port as soon as the number of
*        active unicast MAC addresses associated to this port is less than the
*        learn limit.
*        CPU directed ATU Load, Purge, or Move will not have any effect on the
*        learn limit.
*        This feature is disabled when the limit is zero.
*        The following care is needed when enabling this feature:
*            1) dsable learning on the ports
*            2) flush all non-static addresses in the ATU
*            3) define the desired limit for the ports
*            4) re-enable learing on the ports
*
* INPUTS:
*        port  - logical port number
*
* OUTPUTS:
*        limit - auto learning limit ( 0 ~ 255 )
*
* RETURNS:
*        GT_OK   - on success
*        GT_FAIL - on error
*        GT_BAD_PARAM - if limit > 0xFF
*        GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*       None.
*
*******************************************************************************/
GT_STATUS gfdbGetPortAtuLearnLimit
(
    IN  GT_QD_DEV     *dev,
    IN  GT_LPORT      port,
    OUT GT_U32       *limit
)
{
    GT_U16          data, mask;
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U8           hwPort;         /* the physical port number     */

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

    /* translate LPORT to hardware port */
    hwPort = GT_LPORT_2_PORT(port);

    /* Check device if it has fixed ATU Size. */
    if (!IS_IN_DEV_GROUP(dev,DEV_ATU_LIMIT_READ))
    {
        return GT_NOT_SUPPORTED;
    }

    mask = 0x9000;
    data = (GT_U16) 0x1000;

    /* Set the learn limit bits.                  */
    retVal = hwSetPortRegBits(dev,hwPort, QD_REG_PORT_ATU_CONTROL, mask, data);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }

    /* Get the ReadLearnLimit bit. */
    retVal = hwGetPortRegField(dev,hwPort, QD_REG_PORT_ATU_CONTROL, 0, 8, &data);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }

    *limit = (GT_U32)data;

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



/*******************************************************************************
* gfdbGetPortAtuLearnCnt
*
* DESCRIPTION:
*       Read the current number of active unicast MAC addresses associated with
*        the given port. This counter (LearnCnt) is held at zero if learn limit
*        (gfdbSetPortAtuLearnLimit API) is set to zero.
*
* INPUTS:
*       port  - logical port number
*
* OUTPUTS:
*       count - current auto learning count
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*       GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*       None.
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gfdbGetPortAtuLearnCnt
(
    IN  GT_QD_DEV     *dev,
    IN  GT_LPORT      port,
    IN  GT_U32       *count
)
{
    GT_U16          data;
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U8           hwPort;         /* the physical port number     */

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

    /* translate LPORT to hardware port */
    hwPort = GT_LPORT_2_PORT(port);

    /* Check device if this feature is supported. */
    if (!IS_IN_DEV_GROUP(dev,DEV_ATU_LIMIT))
    {
        return GT_NOT_SUPPORTED;
    }

    /* Get the ReadLearnCnt bit. */
    retVal = hwGetPortRegField(dev,hwPort, QD_REG_PORT_ATU_CONTROL, 15, 1, &data);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }

    if(data == 0)
    {
        /* Set the ReadLearnCnt bit. */
        retVal = hwSetPortRegField(dev,hwPort, QD_REG_PORT_ATU_CONTROL, 15, 1, 1);
        if(retVal != GT_OK)
        {
            DBG_INFO(("Failed.\n"));
            return retVal;
        }
    }

    /* Get the LearnCnt bits. */
    retVal = hwGetPortRegField(dev,hwPort, QD_REG_PORT_ATU_CONTROL, 0, 8, &data);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }

    *count = (GT_U32)data;

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


/*******************************************************************************
* gfdbGetAtuAllCount
*
* DESCRIPTION:
*       Counts all entries in the Address Translation Unit.
*
* INPUTS:
*       None.
*
* OUTPUTS:
*       count - number of valid entries.
*
* RETURNS:
*       GT_OK      - on success
*       GT_FAIL    - on error
*       GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*       None
*
*******************************************************************************/
GT_STATUS gfdbGetAtuAllCount
(
    IN  GT_QD_DEV     *dev,
    OUT GT_U32         *count
)
{
    GT_U32          dbNum, maxDbNum, numOfEntries;
    GT_STATUS       retVal;
    GT_ATU_ENTRY    entry;
    GT_ATU_STAT        atuStat;

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

    if(IS_IN_DEV_GROUP(dev,DEV_ATU_STATS))
    {
        atuStat.op = GT_ATU_STATS_ALL;
        return atuGetStats(dev,&atuStat,count);
    }

    numOfEntries = 0;

    if (IS_IN_DEV_GROUP(dev,DEV_DBNUM_FULL))
        maxDbNum = 16;
    else if(IS_IN_DEV_GROUP(dev,DEV_DBNUM_64))
        maxDbNum = 64;
    else if(IS_IN_DEV_GROUP(dev,DEV_DBNUM_256))
        maxDbNum = 256;
    else if(IS_IN_DEV_GROUP(dev,DEV_DBNUM_4096))
        maxDbNum = 4096;
    else
        maxDbNum = 1;

    for(dbNum=0; dbNum<maxDbNum; dbNum++)
    {
        entry.DBNum = (GT_U16)dbNum;

        if(IS_IN_DEV_GROUP(dev,DEV_BROADCAST_INVALID))
            gtMemSet(entry.macAddr.arEther,0,sizeof(GT_ETHERADDR));
        else
            gtMemSet(entry.macAddr.arEther,0xFF,sizeof(GT_ETHERADDR));

        while(1)
        {
            retVal = atuOperationPerform(dev,GET_NEXT_ENTRY,NULL,&entry);
            if(retVal != GT_OK)
            {
                DBG_INFO(("Failed.\n"));
                return retVal;
            }

            if(IS_BROADCAST_MAC(entry.macAddr))
            {
                if(IS_IN_DEV_GROUP(dev,DEV_BROADCAST_INVALID))
                    break;
                else if(entry.entryState.ucEntryState == 0)
                    break;
                numOfEntries++;
                break;
            }

            numOfEntries++;
        }
    }

    *count = numOfEntries;
    DBG_INFO(("OK.\n"));
    return GT_OK;
}


/*******************************************************************************
* gfdbGetAtuAllCountInDBNum
*
* DESCRIPTION:
*       Counts all entries in the defined FID (or DBNum).
*
* INPUTS:
*       dbNum -
*
* OUTPUTS:
*       count - number of valid entries in FID (or DBNum).
*
* RETURNS:
*       GT_OK      - on success
*       GT_FAIL    - on error
*       GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*       None
*
*******************************************************************************/
GT_STATUS gfdbGetAtuAllCountInDBNum
(
    IN  GT_QD_DEV     *dev,
    IN  GT_U32         dbNum,
    OUT GT_U32         *count
)
{
    GT_U32          numOfEntries;
    GT_STATUS       retVal;
    GT_ATU_ENTRY    entry;
    GT_ATU_STAT        atuStat;

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

    if(IS_IN_DEV_GROUP(dev,DEV_ATU_STATS))
    {
        atuStat.op = GT_ATU_STATS_ALL_FID;
        atuStat.DBNum = dbNum;
        return atuGetStats(dev,&atuStat,count);
    }

    numOfEntries = 0;

    entry.DBNum = (GT_U16)dbNum;

    if(IS_IN_DEV_GROUP(dev,DEV_BROADCAST_INVALID))
        gtMemSet(entry.macAddr.arEther,0,sizeof(GT_ETHERADDR));
    else
        gtMemSet(entry.macAddr.arEther,0xFF,sizeof(GT_ETHERADDR));

    while(1)
    {
        retVal = atuOperationPerform(dev,GET_NEXT_ENTRY,NULL,&entry);
        if(retVal != GT_OK)
        {
            DBG_INFO(("Failed.\n"));
            return retVal;
        }

        if(IS_BROADCAST_MAC(entry.macAddr))
        {
            if(IS_IN_DEV_GROUP(dev,DEV_BROADCAST_INVALID))
                break;
            else if(entry.entryState.ucEntryState == 0)
                break;
            numOfEntries++;
            break;
        }

        numOfEntries++;
    }

    *count = numOfEntries;
    DBG_INFO(("OK.\n"));
    return GT_OK;
}


/*******************************************************************************
* gfdbGetAtuDynamicCountInDBNum
*
* DESCRIPTION:
*       Counts all non-static entries in the defined FID (or DBNum).
*
* INPUTS:
*       dbNum -
*
* OUTPUTS:
*       count - number of valid non-static entries in FID (or DBNum).
*
* RETURNS:
*       GT_OK      - on success
*       GT_FAIL    - on error
*       GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*       None
*
*******************************************************************************/
GT_STATUS gfdbGetAtuDynamicCountInDBNum
(
    IN  GT_QD_DEV     *dev,
    IN  GT_U32         dbNum,
    OUT GT_U32         *count
)
{
    GT_U32          numOfEntries, tmpState;
    GT_STATUS       retVal;
    GT_ATU_ENTRY    entry;
    GT_ATU_UC_STATE    state;
    GT_ATU_STAT        atuStat;

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

    if(IS_IN_DEV_GROUP(dev,DEV_ATU_STATS))
    {
        atuStat.op = GT_ATU_STATS_NON_STATIC_FID;
        atuStat.DBNum = dbNum;
        return atuGetStats(dev,&atuStat,count);
    }

    numOfEntries = 0;

    entry.DBNum = (GT_U16)dbNum;

    if(IS_IN_DEV_GROUP(dev,DEV_BROADCAST_INVALID))
        gtMemSet(entry.macAddr.arEther,0,sizeof(GT_ETHERADDR));
    else
        gtMemSet(entry.macAddr.arEther,0xFF,sizeof(GT_ETHERADDR));

    while(1)
    {
        retVal = atuOperationPerform(dev,GET_NEXT_ENTRY,NULL,&entry);
        if(retVal != GT_OK)
        {
            DBG_INFO(("Failed.\n"));
            return retVal;
        }

        if(IS_BROADCAST_MAC(entry.macAddr))
            break;

        if(IS_MULTICAST_MAC(entry.macAddr))
        {
            continue;
        }

        atuStateDevToApp(dev,GT_TRUE,entry.entryState.ucEntryState,&tmpState);
        state = (GT_ATU_UC_STATE)tmpState;
        if (state == GT_UC_DYNAMIC)
        {
            numOfEntries++;
        }
    }

    *count = numOfEntries;
    DBG_INFO(("OK.\n"));
    return GT_OK;
}



/*******************************************************************************
* gfdbSetAtuSize
*
* DESCRIPTION:
*       Sets the Mac address table size.
*
* INPUTS:
*       size    - Mac address table size.
*
* OUTPUTS:
*       None.
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*
* COMMENTS:
*       None.
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gfdbSetAtuSize
(
    IN GT_QD_DEV    *dev,
    IN ATU_SIZE     size
)
{
    GT_U16          data;
    GT_STATUS       retVal;         /* Functions return value.      */

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

    switch(size)
    {
        case ATU_SIZE_256:
            if (IS_IN_DEV_GROUP(dev,DEV_ATU_256_2048))
                data = 0;
            else
                return GT_NOT_SUPPORTED;
            break;
        case ATU_SIZE_512:
        case ATU_SIZE_1024:
        case ATU_SIZE_2048:
            if (IS_IN_DEV_GROUP(dev,DEV_ATU_256_2048))
                data = (GT_U16)size;
            else
                data = (GT_U16)size - 1;
            break;

        case ATU_SIZE_4096:
            if ((IS_IN_DEV_GROUP(dev,DEV_ATU_256_2048))||(IS_IN_DEV_GROUP(dev,DEV_ATU_562_2048)))
                return GT_NOT_SUPPORTED;
            else
                data = 3;
            break;
        default:
            return GT_NOT_SUPPORTED;
    }

    /* Check device if it has fixed ATU Size. */
    if (IS_IN_DEV_GROUP(dev,DEV_ATU_SIZE_FIXED))
    {
        return GT_NOT_SUPPORTED;
    }

    /* Set the Software reset bit.                  */
    retVal = hwSetGlobalRegField(dev,QD_REG_ATU_CONTROL,12,2,data);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }

    /* Make sure the reset operation is completed.  */
#ifdef GT_RMGMT_ACCESS
    /*    if (IS_IN_DEV_GROUP(dev,DEV_RMGMT)) */
    {
      HW_DEV_REG_ACCESS regAccess;

      regAccess.entries = 1;

      regAccess.rw_reg_list[0].cmd = HW_REG_WAIT_TILL_1;
      regAccess.rw_reg_list[0].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL_REG_ACCESS);
      regAccess.rw_reg_list[0].reg = QD_REG_GLOBAL_STATUS;
      regAccess.rw_reg_list[0].data = 11;

      retVal = hwAccessMultiRegs(dev, &regAccess);
      if(retVal != GT_OK)
      {
        gtSemGive(dev,dev->atuRegsSem);
        return retVal;
      }
    }
#else
    {
    data = 0;
    while(data == 0)
    {
        retVal = hwGetGlobalRegField(dev,QD_REG_GLOBAL_STATUS,11,1,&data);
        if(retVal != GT_OK)
        {
            DBG_INFO(("Failed.\n"));
            return retVal;
        }
    }
    }
#endif

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


/*******************************************************************************
* gfdbGetAgingTimeRange
*
* DESCRIPTION:
*       Gets the maximal and minimum age times that the hardware can support.
*
* INPUTS:
*       None.
*
* OUTPUTS:
*       maxTimeout - max aging time in secounds.
*       minTimeout - min aging time in secounds.
*
* RETURNS:
*       GT_OK           - on success
*       GT_BAD_PARAM    - on bad parameter
*       GT_FAIL         - on error
*
* COMMENTS:
*       None.
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gfdbGetAgingTimeRange
(
    IN GT_QD_DEV    *dev,
    OUT GT_U32 *maxTimeout,
    OUT GT_U32 *minTimeout
)
{
    DBG_INFO(("gfdbGetAgingTimeRange Called.\n"));
    if((maxTimeout == NULL) || (minTimeout == NULL))
    {
        DBG_INFO(("Failed.\n"));
        return GT_BAD_PARAM;
    }

    if (IS_IN_DEV_GROUP(dev,DEV_ATU_15SEC_AGING))
    {
        *minTimeout = 15;
        *maxTimeout = 3825;
    }
    else
    {
        *minTimeout = 16;
        *maxTimeout = 4080;
    }
    DBG_INFO(("OK.\n"));
    return GT_OK;
}


/*******************************************************************************
* gfdbGetAgingTimeout
*
* DESCRIPTION:
*       Gets the timeout period in seconds for aging out dynamically learned
*       forwarding information. The returned value may not be the same as the value
*        programmed with <gfdbSetAgingTimeout>. Please refer to the description of
*        <gfdbSetAgingTimeout>.
*
* INPUTS:
*       None.
*
* OUTPUTS:
*       timeout - aging time in seconds.
*
* RETURNS:
*       GT_OK           - on success
*       GT_FAIL         - on error
*
* COMMENTS:
*       None.
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gfdbGetAgingTimeout
(
    IN  GT_QD_DEV    *dev,
    OUT GT_U32       *timeout
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U16          data;           /* The register's read data.    */
    GT_U16            timeBase;

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

    if (IS_IN_DEV_GROUP(dev,DEV_ATU_15SEC_AGING))
        timeBase = 15;
    else
        timeBase = 16;

    /* Get the Time Out value.              */
    retVal = hwGetGlobalRegField(dev,QD_REG_ATU_CONTROL,4,8,&data);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }

    *timeout = data*timeBase;

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


/*******************************************************************************
* gfdbSetAgingTimeout
*
* DESCRIPTION:
*       Sets the timeout period in seconds for aging out dynamically learned
*       forwarding information. The standard recommends 300 sec.
*        Supported aging timeout values are multiple of time-base, where time-base
*        is either 15 or 16 seconds, depending on the Switch device. For example,
*        88E6063 uses time-base 16, and so supported aging timeouts are 0,16,32,
*        48,..., and 4080. If unsupported timeout value (bigger than 16) is used,
*        the value will be rounded to the nearest supported value smaller than the
*        given timeout. If the given timeout is less than 16, minimum timeout value
*        16 will be used instead. E.g.) 35 becomes 32 and 5 becomes 16.
*        <gfdbGetAgingTimeRange> function can be used to find the time-base.
*
* INPUTS:
*       timeout - aging time in seconds.
*
* OUTPUTS:
*       None.
*
* RETURNS:
*       GT_OK           - on success
*       GT_FAIL         - on error
*
* COMMENTS:
*       None.
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gfdbSetAgingTimeout
(
    IN GT_QD_DEV    *dev,
    IN GT_U32 timeout
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U16          data;           /* The register's read data.    */
    GT_U16            timeBase;

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

    if (IS_IN_DEV_GROUP(dev,DEV_ATU_15SEC_AGING))
        timeBase = 15;
    else
        timeBase = 16;

    if((timeout < timeBase) && (timeout != 0))
    {
        data = 1;
    }
    else
    {
        data = (GT_U16)(timeout/timeBase);
       if (data & 0xFF00)
            data = 0xFF;
    }

    /* Set the Time Out value.              */
    retVal = hwSetGlobalRegField(dev,QD_REG_ATU_CONTROL,4,8,data);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }

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


/*******************************************************************************
* gfdbGetLearn2All
*
* DESCRIPTION:
*        When more than one Marvell device is used to form a single 'switch', it
*        may be desirable for all devices in the 'switch' to learn any address this
*        device learns. When this bit is set to a one all other devices in the
*        'switch' learn the same addresses this device learns. When this bit is
*        cleared to a zero, only the devices that actually receive frames will learn
*        from those frames. This mode typically supports more active MAC addresses
*        at one time as each device in the switch does not need to learn addresses
*        it may nerver use.
*
* INPUTS:
*        None.
*
* OUTPUTS:
*        mode  - GT_TRUE if Learn2All is enabled, GT_FALSE otherwise
*
* RETURNS:
*        GT_OK           - on success
*        GT_FAIL         - on error
*        GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*        None.
*
*
*******************************************************************************/
GT_STATUS gfdbGetLearn2All
(
    IN  GT_QD_DEV    *dev,
    OUT GT_BOOL     *mode
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U16          data;           /* to keep the read valve       */

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

    /* check if the given Switch supports this feature. */
    if ((!IS_IN_DEV_GROUP(dev,DEV_88E6093_FAMILY)) ||
        (IS_IN_DEV_GROUP(dev,DEV_88EC000_FAMILY)) ||
        (IS_IN_DEV_GROUP(dev,DEV_88ESPANNAK_FAMILY)))
    {
        DBG_INFO(("GT_NOT_SUPPORTED\n"));
        return GT_NOT_SUPPORTED;
    }

    /* Get the Learn2All. */
    retVal = hwGetGlobalRegField(dev,QD_REG_ATU_CONTROL, 3, 1, &data);

    BIT_2_BOOL(data, *mode);

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

    return retVal;
}

/*******************************************************************************
* gfdbSetLearn2All
*
* DESCRIPTION:
*        Enable or disable Learn2All mode.
*
* INPUTS:
*        mode - GT_TRUE to set Learn2All, GT_FALSE otherwise
*
* OUTPUTS:
*        None.
*
* RETURNS:
*        GT_OK   - on success
*        GT_FAIL - on error
*        GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gfdbSetLearn2All
(
    IN GT_QD_DEV    *dev,
    IN GT_BOOL        mode
)
{
    GT_U16          data;           /* Used to poll the SWReset bit */
    GT_STATUS       retVal;         /* Functions return value.      */

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

    /* check if the given Switch supports this feature. */
    if ((!IS_IN_DEV_GROUP(dev,DEV_88E6093_FAMILY)) ||
        (IS_IN_DEV_GROUP(dev,DEV_88EC000_FAMILY)) ||
        (IS_IN_DEV_GROUP(dev,DEV_88ESPANNAK_FAMILY)))
    {
        DBG_INFO(("GT_NOT_SUPPORTED\n"));
        return GT_NOT_SUPPORTED;
    }

    /* translate BOOL to binary */
    BOOL_2_BIT(mode, data);

    /* Set Learn2All. */
    retVal = hwSetGlobalRegField(dev,QD_REG_ATU_CONTROL, 3, 1, data);

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


/*******************************************************************************
* gfdbGetMacAvb
*
* DESCRIPTION:
*        ATU MAC entry in AVB mode.
*        When enabled, ATU entries operate in AVB mode:
*
*        GT_ATU_UC_STATE - support
*            GT_UC_NO_PRI_STATIC_AVB_ENTRY, and
*            GT_UC_STATIC_AVB_ENTRY
*
*        GT_ATU_MC_STATE - support
*            GT_MC_STATIC_AVB_ENTRY, and
*            GT_MC_PRIO_STATIC_AVB_ENTRY
*
*        When disabled, ATU entries operate in non-AVB mode:
*
*        GT_ATU_UC_STATE - support
*            GT_UC_NO_PRI_STATIC_NRL, and
*            GT_UC_STATIC_NRL
*
*        GT_ATU_MC_STATE - support
*            GT_MC_STATIC_UNLIMITED_RATE, and
*            GT_MC_PRIO_STATIC_UNLIMITED_RATE
*
* INPUTS:
*        None.
*
* OUTPUTS:
*        mode  - GT_TRUE if MacAvb is enabled, GT_FALSE otherwise
*
* RETURNS:
*        GT_OK           - on success
*        GT_FAIL         - on error
*        GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*        None.
*
*
*******************************************************************************/
GT_STATUS gfdbGetMacAvb
(
    IN  GT_QD_DEV    *dev,
    OUT GT_BOOL     *mode
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U16          data;           /* to keep the read valve       */

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

    /* check if the given Switch supports this feature. */
    if (!IS_IN_DEV_GROUP(dev,DEV_MAC_AVB))
    {
        DBG_INFO(("GT_NOT_SUPPORTED\n"));
        return GT_NOT_SUPPORTED;
    }

    /* Get the bit. */
    retVal = hwGetGlobalRegField(dev,QD_REG_ATU_CONTROL, 15, 1, &data);

    BIT_2_BOOL(data, *mode);

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

    return retVal;
}

/*******************************************************************************
* gfdbSetMacAvb
*
* DESCRIPTION:
*        ATU MAC entry in AVB mode.
*        When enabled, ATU entries operate in AVB mode:
*
*        GT_ATU_UC_STATE - support
*            GT_UC_NO_PRI_STATIC_AVB_ENTRY, and
*            GT_UC_STATIC_AVB_ENTRY
*
*        GT_ATU_MC_STATE - support
*            GT_MC_STATIC_AVB_ENTRY, and
*            GT_MC_PRIO_STATIC_AVB_ENTRY
*
*        When disabled, ATU entries operate in non-AVB mode:
*
*        GT_ATU_UC_STATE - support
*            GT_UC_NO_PRI_STATIC_NRL, and
*            GT_UC_STATIC_NRL
*
*        GT_ATU_MC_STATE - support
*            GT_MC_STATIC_UNLIMITED_RATE, and
*            GT_MC_PRIO_STATIC_UNLIMITED_RATE
*
* INPUTS:
*        mode - GT_TRUE to enable MacAvb, GT_FALSE 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 gfdbSetMacAvb
(
    IN GT_QD_DEV    *dev,
    IN GT_BOOL        mode
)
{
    GT_U16          data;           /* Used to poll the SWReset bit */
    GT_STATUS       retVal;         /* Functions return value.      */

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

    /* check if the given Switch supports this feature. */
    if (!IS_IN_DEV_GROUP(dev,DEV_MAC_AVB))
    {
        DBG_INFO(("GT_NOT_SUPPORTED\n"));
        return GT_NOT_SUPPORTED;
    }

    /* translate BOOL to binary */
    BOOL_2_BIT(mode, data);

    /* Set the bit */
    retVal = hwSetGlobalRegField(dev,QD_REG_ATU_CONTROL, 15, 1, data);

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


/*******************************************************************************
* gfdbGetAtuDynamicCount
*
* DESCRIPTION:
*       Gets the current number of dynamic unicast (non-static) entries in this
*       Filtering Database.
*
* INPUTS:
*       None.
*
* OUTPUTS:
*       numDynEntries - number of dynamic entries.
*
* RETURNS:
*       GT_OK      - on success
*       GT_FAIL    - on error
*       GT_NO_SUCH - vlan does not exist.
*
* COMMENTS:
*       None
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gfdbGetAtuDynamicCount
(
    IN  GT_QD_DEV     *dev,
    OUT GT_U32         *numDynEntries
)
{
    GT_U32          dbNum, maxDbNum, numOfEntries, tmpState;
    GT_STATUS       retVal;
    GT_ATU_ENTRY    entry;
    GT_ATU_UC_STATE    state;
    GT_ATU_STAT        atuStat;

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

    if(IS_IN_DEV_GROUP(dev,DEV_ATU_STATS))
    {
        atuStat.op = GT_ATU_STATS_NON_STATIC;
        return atuGetStats(dev,&atuStat,numDynEntries);
    }

    numOfEntries = 0;

    if (IS_IN_DEV_GROUP(dev,DEV_DBNUM_FULL))
        maxDbNum = 16;
    else if(IS_IN_DEV_GROUP(dev,DEV_DBNUM_64))
        maxDbNum = 64;
    else if(IS_IN_DEV_GROUP(dev,DEV_DBNUM_256))
        maxDbNum = 256;
    else if(IS_IN_DEV_GROUP(dev,DEV_DBNUM_4096))
        maxDbNum = 4096;
    else
        maxDbNum = 1;

    for(dbNum=0; dbNum<maxDbNum; dbNum++)
    {
        entry.DBNum = (GT_U16)dbNum;

        if(IS_IN_DEV_GROUP(dev,DEV_BROADCAST_INVALID))
            gtMemSet(entry.macAddr.arEther,0,sizeof(GT_ETHERADDR));
        else
            gtMemSet(entry.macAddr.arEther,0xFF,sizeof(GT_ETHERADDR));

        while(1)
        {
            retVal = atuOperationPerform(dev,GET_NEXT_ENTRY,NULL,&entry);
            if(retVal != GT_OK)
            {
                DBG_INFO(("Failed.\n"));
                return retVal;
            }

            if(IS_BROADCAST_MAC(entry.macAddr))
                break;

            if(IS_MULTICAST_MAC(entry.macAddr))
            {
                continue;
            }

            atuStateDevToApp(dev,GT_TRUE,(GT_U32)entry.entryState.ucEntryState,&tmpState);
            state = (GT_ATU_UC_STATE)tmpState;
            if (state == GT_UC_DYNAMIC)
            {
                numOfEntries++;
            }
        }
    }

    *numDynEntries = numOfEntries;
    DBG_INFO(("OK.\n"));
    return GT_OK;
}


/*******************************************************************************
* gfdbGetAtuEntryFirst
*
* DESCRIPTION:
*       Gets first lexicographic MAC address entry from the ATU.
*
* INPUTS:
*       None.
*
* OUTPUTS:
*       atuEntry - match Address translate unit entry.
*
* RETURNS:
*       GT_OK      - on success
*       GT_FAIL    - on error
*       GT_NO_SUCH - table is empty.
*
* COMMENTS:
*       Search starts from Mac[00:00:00:00:00:00]
*
*        DBNum in atuEntry -
*            ATU MAC Address Database number. If multiple address
*            databases are not being used, DBNum should be zero.
*            If multiple address databases are being used, this value
*            should be set to the desired address database number.
*
*******************************************************************************/
GT_STATUS gfdbGetAtuEntryFirst
(
    IN GT_QD_DEV    *dev,
    OUT GT_ATU_ENTRY    *atuEntry
)
{
    GT_STATUS       retVal;
    GT_ATU_ENTRY    entry;
    GT_U32 data;

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

    if(IS_IN_DEV_GROUP(dev,DEV_BROADCAST_INVALID))
        gtMemSet(entry.macAddr.arEther,0,sizeof(GT_ETHERADDR));
    else
        gtMemSet(entry.macAddr.arEther,0xFF,sizeof(GT_ETHERADDR));

    entry.DBNum = atuEntry->DBNum;

    DBG_INFO(("DBNum : %i\n",entry.DBNum));

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

    if(IS_BROADCAST_MAC(entry.macAddr))
    {
        if(IS_IN_DEV_GROUP(dev,DEV_BROADCAST_INVALID))
        {
            DBG_INFO(("Failed (Invalid Mac).\n"));
            return GT_NO_SUCH;
        }
        else if(entry.entryState.ucEntryState == 0)
        {
            DBG_INFO(("Failed (Invalid Mac).\n"));
            return GT_NO_SUCH;
        }
    }

    gtMemCpy(atuEntry->macAddr.arEther,entry.macAddr.arEther,6);
    atuEntry->portVec   = GT_PORTVEC_2_LPORTVEC(entry.portVec);
    atuEntry->prio      = entry.prio;
    atuEntry->trunkMember = entry.trunkMember;
    atuEntry->exPrio.useMacFPri = entry.exPrio.useMacFPri;
    atuEntry->exPrio.macFPri = entry.exPrio.macFPri;
    atuEntry->exPrio.macQPri = entry.exPrio.macQPri;

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

        atuStateDevToApp(dev,GT_FALSE,entry.entryState.ucEntryState,
                        &data);
        atuEntry->entryState.mcEntryState = data;
    }
    else
    {
        atuStateDevToApp(dev,GT_TRUE,entry.entryState.ucEntryState,
                        &data);
        atuEntry->entryState.ucEntryState = data;
    }

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



/*******************************************************************************
* gfdbGetAtuEntryNext
*
* DESCRIPTION:
*       Gets next lexicographic MAC address from the specified Mac Addr.
*
* INPUTS:
*       atuEntry - the Mac Address to start the search.
*
* OUTPUTS:
*       atuEntry - match Address translate unit 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 atu.macAddr[xx:xx:xx:xx:xx:xx] specified by the
*       user.
*
*        DBNum in atuEntry -
*            ATU MAC Address Database number. If multiple address
*            databases are not being used, DBNum should be zero.
*            If multiple address databases are being used, this value
*            should be set to the desired address database number.
*
*******************************************************************************/
GT_STATUS gfdbGetAtuEntryNext
(
    IN GT_QD_DEV    *dev,
    INOUT GT_ATU_ENTRY  *atuEntry
)
{
    GT_STATUS       retVal;
    GT_ATU_ENTRY    entry;
    GT_U32 data;

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

    if(IS_BROADCAST_MAC(atuEntry->macAddr))
    {
           return GT_NO_SUCH;
    }

    gtMemCpy(entry.macAddr.arEther,atuEntry->macAddr.arEther,6);

    entry.DBNum = atuEntry->DBNum;
    DBG_INFO(("DBNum : %i\n",entry.DBNum));

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

    if(IS_BROADCAST_MAC(entry.macAddr))
    {
        if(IS_IN_DEV_GROUP(dev,DEV_BROADCAST_INVALID))
        {
            DBG_INFO(("Failed (Invalid Mac).\n"));
            return GT_NO_SUCH;
        }
        else if(entry.entryState.ucEntryState == 0)
        {
            DBG_INFO(("Failed (Invalid Mac).\n"));
            return GT_NO_SUCH;
        }
    }

    gtMemCpy(atuEntry->macAddr.arEther,entry.macAddr.arEther,6);
    atuEntry->portVec   = GT_PORTVEC_2_LPORTVEC(entry.portVec);
    atuEntry->prio      = entry.prio;
    atuEntry->trunkMember = entry.trunkMember;
    atuEntry->exPrio.useMacFPri = entry.exPrio.useMacFPri;
    atuEntry->exPrio.macFPri = entry.exPrio.macFPri;
    atuEntry->exPrio.macQPri = entry.exPrio.macQPri;

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

        atuStateDevToApp(dev,GT_FALSE,(GT_U32)entry.entryState.ucEntryState,
                        &data);
        atuEntry->entryState.mcEntryState = data;
    }
    else
    {
        atuStateDevToApp(dev,GT_TRUE,(GT_U32)entry.entryState.ucEntryState,
                        &data);
        atuEntry->entryState.ucEntryState = data;
    }

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



/*******************************************************************************
* gfdbFindAtuMacEntry
*
* DESCRIPTION:
*       Find FDB entry for specific MAC address from the ATU.
*
* INPUTS:
*       atuEntry - the Mac address to search.
*
* OUTPUTS:
*       found    - GT_TRUE, if the appropriate entry exists.
*       atuEntry - the entry parameters.
*
* RETURNS:
*       GT_OK      - on success.
*       GT_FAIL    - on error or entry does not exist.
*       GT_NO_SUCH - no more entries.
*       GT_BAD_PARAM    - on bad parameter
*
* COMMENTS:
*        DBNum in atuEntry -
*            ATU MAC Address Database number. If multiple address
*            databases are not being used, DBNum should be zero.
*            If multiple address databases are being used, this value
*            should be set to the desired address database number.
*
*******************************************************************************/
GT_STATUS gfdbFindAtuMacEntry
(
    IN GT_QD_DEV    *dev,
    INOUT GT_ATU_ENTRY  *atuEntry,
    OUT GT_BOOL         *found
)
{
    GT_STATUS       retVal;
    GT_ATU_ENTRY    entry;
    int           i;
    GT_U32 data;

    DBG_INFO(("gfdbFindAtuMacEntry Called.\n"));
    *found = GT_FALSE;
    gtMemCpy(entry.macAddr.arEther,atuEntry->macAddr.arEther,6);
    entry.DBNum = atuEntry->DBNum;
    /* Decrement 1 from mac address.    */
    for(i=5; i >= 0; i--)
    {
        if(entry.macAddr.arEther[i] != 0)
        {
            entry.macAddr.arEther[i] -= 1;
            break;
        }
        else
            entry.macAddr.arEther[i] = 0xFF;
    }

    /* Check if the given mac equals zero   */
    if((i == -1) && IS_IN_DEV_GROUP(dev,DEV_BROADCAST_INVALID))
    {
        DBG_INFO(("Address should not be all zeros.\n"));
        return GT_BAD_PARAM;
    }

    retVal = atuOperationPerform(dev,GET_NEXT_ENTRY,NULL,&entry);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }

    if(IS_BROADCAST_MAC(entry.macAddr))
    {
        if(IS_IN_DEV_GROUP(dev,DEV_BROADCAST_INVALID))
        {
            DBG_INFO(("Failed (Broadcast addr is not valid).\n"));
            return GT_NO_SUCH;
        }
        else if(entry.entryState.ucEntryState == 0)
        {
            DBG_INFO(("Failed (Invalid Mac).\n"));
            return GT_NO_SUCH;
        }
    }
    if(gtMemCmp((char*)atuEntry->macAddr.arEther,(char*)entry.macAddr.arEther,ETHERNET_HEADER_SIZE))
    {
#ifdef __KERNELL__
      DBG_INFO(("@@@@@@@@@@@@@  error gfdbFindAtuMacEntry:check: %02x:%02x:%02x:%02x:%02x:%02x get: %02x:%02x:%02x:%02x:%02x:%02x\n",
      atuEntry->macAddr.arEther[0],
      atuEntry->macAddr.arEther[1],
      atuEntry->macAddr.arEther[2],
      atuEntry->macAddr.arEther[3],
      atuEntry->macAddr.arEther[4],
      atuEntry->macAddr.arEther[5],
      entry.macAddr.arEther[0],
      entry.macAddr.arEther[1],
      entry.macAddr.arEther[2],
      entry.macAddr.arEther[3],
      entry.macAddr.arEther[4],
      entry.macAddr.arEther[5]
      ));
#endif
        DBG_INFO(("Failed.\n"));
        return GT_NO_SUCH;
    }

    atuEntry->portVec   = GT_PORTVEC_2_LPORTVEC(entry.portVec);
    atuEntry->prio      = entry.prio;
    atuEntry->trunkMember = entry.trunkMember;
    atuEntry->exPrio.useMacFPri = entry.exPrio.useMacFPri;
    atuEntry->exPrio.macFPri = entry.exPrio.macFPri;
    atuEntry->exPrio.macQPri = entry.exPrio.macQPri;

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

        atuStateDevToApp(dev,GT_FALSE,(GT_U32)entry.entryState.ucEntryState,
                        &data);
        atuEntry->entryState.mcEntryState = data;
    }
    else
    {
        atuStateDevToApp(dev,GT_TRUE,(GT_U32)entry.entryState.ucEntryState,
                        &data);
        atuEntry->entryState.ucEntryState = data;
    }

    *found = GT_TRUE;
    DBG_INFO(("OK.\n"));
    return GT_OK;
}



/*******************************************************************************
* gfdbFlush
*
* DESCRIPTION:
*       This routine flush all or unblocked addresses from the MAC Address
*       Table.
*
* INPUTS:
*       flushCmd - the flush operation type.
*
* OUTPUTS:
*       None
*
* RETURNS:
*       GT_OK           - on success
*       GT_FAIL         - on error
*       GT_NO_RESOURCE  - failed to allocate a t2c struct
*
* COMMENTS:
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gfdbFlush
(
    IN GT_QD_DEV    *dev,
    IN GT_FLUSH_CMD flushCmd
)
{
    GT_STATUS       retVal;
    GT_ATU_ENTRY    entry;

    DBG_INFO(("gfdbFlush Called.\n"));
    /* check if device supports this feature */
    if (!IS_IN_DEV_GROUP(dev,DEV_STATIC_ADDR))
    {
        DBG_INFO(("GT_NOT_SUPPORTED\n"));
        return GT_NOT_SUPPORTED;
    }

    entry.DBNum = 0;
    entry.entryState.ucEntryState = 0;

    if(flushCmd == GT_FLUSH_ALL)
        retVal = atuOperationPerform(dev,FLUSH_ALL,NULL,&entry);
    else
        retVal = atuOperationPerform(dev,FLUSH_UNLOCKED,NULL,&entry);

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

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


/*******************************************************************************
* gfdbFlushInDB
*
* DESCRIPTION:
*       This routine flush all or unblocked addresses from the particular
*       ATU Database (DBNum). If multiple address databases are being used, this
*        API can be used to flush entries in a particular DBNum database.
*
* INPUTS:
*       flushCmd - the flush operation type.
*        DBNum     - ATU MAC Address Database Number.
*
* OUTPUTS:
*       None
*
* RETURNS:
*       GT_OK           - on success
*       GT_FAIL         - on error
*       GT_NOT_SUPPORTED- if current device does not support this feature.
*
* COMMENTS:
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gfdbFlushInDB
(
    IN GT_QD_DEV    *dev,
    IN GT_FLUSH_CMD flushCmd,
    IN GT_U32 DBNum
)
{
    GT_STATUS       retVal;
    GT_ATU_ENTRY    entry;

    DBG_INFO(("gfdbFlush Called.\n"));
    DBG_INFO(("gfdbFush: dev=%x, dev->atuRegsSem=%d \n",dev, dev->atuRegsSem));

    /* check if device supports this feature */
    if ((!IS_IN_DEV_GROUP(dev,DEV_DBNUM_FULL)) &&
        (!IS_IN_DEV_GROUP(dev,DEV_DBNUM_64)) &&
        (!IS_IN_DEV_GROUP(dev,DEV_DBNUM_4096)) &&
        (!IS_IN_DEV_GROUP(dev,DEV_DBNUM_256)))
    {
        DBG_INFO(("GT_NOT_SUPPORTED\n"));
        return GT_NOT_SUPPORTED;
    }

    entry.DBNum = (GT_U16)DBNum;
    entry.entryState.ucEntryState = 0;

    if(flushCmd == GT_FLUSH_ALL)
        retVal = atuOperationPerform(dev,FLUSH_ALL_IN_DB,NULL,&entry);
    else
        retVal = atuOperationPerform(dev,FLUSH_UNLOCKED_IN_DB,NULL,&entry);

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

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


/*******************************************************************************
* gfdbMove
*
* DESCRIPTION:
*       This routine moves all or unblocked addresses from a port to another.
*
* INPUTS:
*         moveCmd  - the move operation type.
*        moveFrom - port where moving from
*        moveTo   - port where moving to
*
* OUTPUTS:
*       None
*
* RETURNS:
*       GT_OK           - on success
*       GT_FAIL         - on error
*       GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gfdbMove
(
    IN GT_QD_DEV    *dev,
    IN GT_MOVE_CMD  moveCmd,
    IN GT_LPORT        moveFrom,
    IN GT_LPORT        moveTo
)
{
    GT_STATUS       retVal;
    GT_ATU_ENTRY    entry;
    GT_EXTRA_OP_DATA    opData;

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

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

    entry.DBNum = 0;
    entry.entryState.ucEntryState = 0xF;
    if (moveTo == 0xF)
        opData.moveTo = moveTo;
    else
        opData.moveTo = (GT_U32)GT_LPORT_2_PORT(moveTo);
    opData.moveFrom = (GT_U32)GT_LPORT_2_PORT(moveFrom);

    if((opData.moveTo == 0xFF) || (opData.moveFrom == 0xFF))
        return GT_BAD_PARAM;

    if(moveCmd == GT_MOVE_ALL)
        retVal = atuOperationPerform(dev,FLUSH_ALL,&opData,&entry);
    else
        retVal = atuOperationPerform(dev,FLUSH_UNLOCKED,&opData,&entry);

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

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


/*******************************************************************************
* gfdbMoveInDB
*
* DESCRIPTION:
*       This routine move all or unblocked addresses which are in the particular
*       ATU Database (DBNum) from a port to another.
*
* INPUTS:
*       moveCmd  - the move operation type.
*        DBNum     - ATU MAC Address Database Number.
*        moveFrom - port where moving from
*        moveTo   - port where moving to
*
* OUTPUTS:
*       None
*
* RETURNS:
*       GT_OK           - on success
*       GT_FAIL         - on error
*       GT_NOT_SUPPORTED- if current device does not support this feature.
*
* COMMENTS:
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gfdbMoveInDB
(
    IN GT_QD_DEV    *dev,
    IN GT_MOVE_CMD     moveCmd,
    IN GT_U32         DBNum,
    IN GT_LPORT        moveFrom,
    IN GT_LPORT        moveTo
)
{
    GT_STATUS       retVal;
    GT_ATU_ENTRY    entry;
    GT_EXTRA_OP_DATA    opData;

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

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

    entry.DBNum = (GT_U16)DBNum;
    entry.entryState.ucEntryState = 0xF;

    if (moveTo == 0xF)
        opData.moveTo = moveTo;
    else
        opData.moveTo = (GT_U32)GT_LPORT_2_PORT(moveTo);
    opData.moveFrom = (GT_U32)GT_LPORT_2_PORT(moveFrom);

    if((opData.moveTo == 0xFF) || (opData.moveFrom == 0xFF))
        return GT_BAD_PARAM;

    if(moveCmd == GT_MOVE_ALL)
        retVal = atuOperationPerform(dev,FLUSH_ALL_IN_DB,&opData,&entry);
    else
        retVal = atuOperationPerform(dev,FLUSH_UNLOCKED_IN_DB,&opData,&entry);

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

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


/*******************************************************************************
* gfdbRemovePort
*
* DESCRIPTION:
*       This routine deassociages all or unblocked addresses from a port.
*
* INPUTS:
*       moveCmd - the move operation type.
*       port - the logical port number.
*
* OUTPUTS:
*       None
*
* RETURNS:
*       GT_OK           - on success
*       GT_FAIL         - on error
*       GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gfdbRemovePort
(
    IN GT_QD_DEV    *dev,
    IN GT_MOVE_CMD     moveCmd,
    IN GT_LPORT        port
)
{
    DBG_INFO(("gfdbRemovePort Called.\n"));

    return gfdbMove(dev,moveCmd,port,(GT_LPORT)0xF);
}


/*******************************************************************************
* gfdbRemovePortInDB
*
* DESCRIPTION:
*       This routine deassociages all or unblocked addresses from a port in the
*       particular ATU Database (DBNum).
*
* INPUTS:
*       moveCmd  - the move operation type.
*       port - the logical port number.
*        DBNum     - ATU MAC Address Database Number.
*
* OUTPUTS:
*       None
*
* RETURNS:
*       GT_OK           - on success
*       GT_FAIL         - on error
*       GT_NOT_SUPPORTED- if current device does not support this feature.
*
* COMMENTS:
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gfdbRemovePortInDB
(
    IN GT_QD_DEV    *dev,
    IN GT_MOVE_CMD     moveCmd,
    IN GT_LPORT        port,
    IN GT_U32         DBNum
)
{
    DBG_INFO(("gfdbRemovePortInDB Called.\n"));

    return gfdbMoveInDB(dev,moveCmd,DBNum,port,(GT_LPORT)0xF);
}


/*******************************************************************************
* gfdbAddMacEntry
*
* DESCRIPTION:
*       Creates the new entry in MAC address table.
*
* INPUTS:
*       macEntry    - mac address entry to insert to the ATU.
*
* OUTPUTS:
*       None
*
* RETURNS:
*       GT_OK          - on success
*       GT_FAIL        - on error
*       GT_BAD_PARAM   - on invalid port vector
*
* COMMENTS:
*        DBNum in atuEntry -
*            ATU MAC Address Database number. If multiple address
*            databases are not being used, DBNum should be zero.
*            If multiple address databases are being used, this value
*            should be set to the desired address database number.
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gfdbAddMacEntry
(
    IN GT_QD_DEV    *dev,
    IN GT_ATU_ENTRY *macEntry
)
{
    GT_STATUS       retVal;
    GT_ATU_ENTRY    entry;
    GT_U32 data;

    DBG_INFO(("gfdbAddMacEntry Called.\n"));
    /* check if device supports this feature */
    if (!IS_IN_DEV_GROUP(dev,DEV_STATIC_ADDR))
    {
        DBG_INFO(("GT_NOT_SUPPORTED\n"));
        return GT_NOT_SUPPORTED;
    }

    gtMemCpy(entry.macAddr.arEther,macEntry->macAddr.arEther,6);
    entry.DBNum        = macEntry->DBNum;
    entry.portVec     = GT_LPORTVEC_2_PORTVEC(macEntry->portVec);
    if(entry.portVec == GT_INVALID_PORT_VEC)
    {
        return GT_BAD_PARAM;
    }

    if(IS_IN_DEV_GROUP(dev,DEV_ATU_EXT_PRI))
    {
        if(IS_IN_DEV_GROUP(dev,DEV_FQPRI_IN_TABLE))
        {
            entry.exPrio.useMacFPri = macEntry->exPrio.useMacFPri;
            entry.exPrio.macFPri = macEntry->exPrio.macFPri;
            entry.exPrio.macQPri = macEntry->exPrio.macQPri;
        }
        else
        {
            entry.exPrio.useMacFPri = 0;
            entry.exPrio.macFPri = macEntry->exPrio.macQPri;
            entry.exPrio.macQPri = macEntry->exPrio.macQPri;
        }
        entry.prio        = 0;
    }
    else
    {
        entry.exPrio.useMacFPri = 0;
        entry.exPrio.macFPri = 0;
        entry.exPrio.macQPri = 0;
        entry.prio        = macEntry->prio;
    }

    if (IS_IN_DEV_GROUP(dev,DEV_TRUNK))
    {
        entry.trunkMember = macEntry->trunkMember;
    }
    else
    {
        entry.trunkMember = GT_FALSE;
    }

    if(IS_MULTICAST_MAC(entry.macAddr))
    {
        atuStateAppToDev(dev,GT_FALSE,(GT_U32)macEntry->entryState.mcEntryState,
                        &data);
        entry.entryState.ucEntryState = data;
    }
    else
    {
        atuStateAppToDev(dev,GT_TRUE,(GT_U32)macEntry->entryState.ucEntryState,
                        &data);
        entry.entryState.ucEntryState = data;
    }

    if (entry.entryState.ucEntryState == 0)
    {
        DBG_INFO(("Entry State should not be ZERO.\n"));
        return GT_BAD_PARAM;
    }

    retVal = atuOperationPerform(dev,LOAD_PURGE_ENTRY,NULL,&entry);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }

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

/*******************************************************************************
* gfdbDelMacEntry
*
* DESCRIPTION:
*       Deletes MAC address entry. If DBNum or FID is used, gfdbDelAtuEntry API
*        would be the better choice to delete an entry in ATU.
*
* INPUTS:
*       macAddress - mac address.
*
* OUTPUTS:
*       None.
*
* RETURNS:
*       GT_OK           - on success
*       GT_FAIL         - on error
*       GT_NO_RESOURCE  - failed to allocate a t2c struct
*       GT_NO_SUCH      - if specified address entry does not exist
*
* COMMENTS:
*
*******************************************************************************/
GT_STATUS gfdbDelMacEntry
(
    IN GT_QD_DEV    *dev,
    IN GT_ETHERADDR  *macAddress
)
{
    GT_STATUS retVal;
    GT_ATU_ENTRY    entry;

    DBG_INFO(("gfdbDelMacEntry Called.\n"));
    /* check if device supports this feature */
    if (!IS_IN_DEV_GROUP(dev,DEV_STATIC_ADDR))
    {
        DBG_INFO(("GT_NOT_SUPPORTED\n"));
        return GT_NOT_SUPPORTED;
    }

    gtMemCpy(entry.macAddr.arEther,macAddress->arEther,6);
    entry.DBNum = 0;
    entry.prio = 0;
    entry.portVec = 0;
    entry.entryState.ucEntryState = 0;
    entry.trunkMember = GT_FALSE;
    entry.exPrio.useMacFPri = GT_FALSE;
    entry.exPrio.macFPri = 0;
    entry.exPrio.macQPri = 0;

    retVal = atuOperationPerform(dev,LOAD_PURGE_ENTRY,NULL,&entry);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }
    DBG_INFO(("OK.\n"));
    return GT_OK;
}


/*******************************************************************************
* gfdbDelAtuEntry
*
* DESCRIPTION:
*       Deletes ATU entry.
*
* INPUTS:
*       atuEntry - the ATU entry to be deleted.
*
* OUTPUTS:
*       None.
*
* RETURNS:
*       GT_OK           - on success
*       GT_FAIL         - on error
*       GT_NO_RESOURCE  - failed to allocate a t2c struct
*       GT_NO_SUCH      - if specified address entry does not exist
*
* COMMENTS:
*        DBNum in atuEntry -
*            ATU MAC Address Database number. If multiple address
*            databases are not being used, DBNum should be zero.
*            If multiple address databases are being used, this value
*            should be set to the desired address database number.
*
*******************************************************************************/
GT_STATUS gfdbDelAtuEntry
(
    IN GT_QD_DEV    *dev,
    IN GT_ATU_ENTRY  *atuEntry
)
{
    GT_ATU_ENTRY    entry;
    GT_STATUS retVal;

    DBG_INFO(("gfdbDelMacEntry Called.\n"));
    /* check if device supports this feature */
    if (!IS_IN_DEV_GROUP(dev,DEV_STATIC_ADDR))
    {
        DBG_INFO(("GT_NOT_SUPPORTED\n"));
        return GT_NOT_SUPPORTED;
    }

    gtMemCpy(entry.macAddr.arEther,atuEntry->macAddr.arEther,6);
    entry.DBNum = atuEntry->DBNum;
    entry.prio = 0;
    entry.portVec = 0;
    entry.entryState.ucEntryState = 0;
    entry.trunkMember = GT_FALSE;
    entry.exPrio.useMacFPri = GT_FALSE;
    entry.exPrio.macFPri = 0;
    entry.exPrio.macQPri = 0;

    retVal = atuOperationPerform(dev,LOAD_PURGE_ENTRY,NULL,&entry);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }
    DBG_INFO(("OK.\n"));
    return GT_OK;
}

/*******************************************************************************
* gfdbLearnEnable
*
* DESCRIPTION:
*       Enable/disable automatic learning of new source MAC addresses on port
*       ingress.
*
* INPUTS:
*       en - GT_TRUE for enable  or GT_FALSE otherwise
*
* OUTPUTS:
*       None
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*
* COMMENTS:
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gfdbLearnEnable
(
    IN GT_QD_DEV    *dev,
    IN GT_BOOL  en
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U16          data;           /* Data to be set into the      */
                                    /* register.                    */
    GT_LPORT    port;
    GT_BOOL        mode;

    DBG_INFO(("gfdbLearnEnable Called.\n"));
    BOOL_2_BIT(en,data);
    data = 1 - data;

    if (IS_IN_DEV_GROUP(dev,DEV_GIGABIT_SWITCH))
    {
        mode = (en)?GT_FALSE:GT_TRUE;

        for (port=0; port<dev->numOfPorts; port++)
        {
            retVal = gprtSetLearnDisable(dev,port,mode);
            if(retVal != GT_OK)
            {
                DBG_INFO(("Failed.\n"));
                return retVal;
            }
        }
    }
    else
    {
        /* Set the Learn Enable bit.            */
        retVal = hwSetGlobalRegField(dev,QD_REG_ATU_CONTROL,14,1,data);
        if(retVal != GT_OK)
        {
            DBG_INFO(("Failed.\n"));
            return retVal;
        }
    }
    DBG_INFO(("OK.\n"));
    return GT_OK;
}


/*******************************************************************************
* gfdbGetLearnEnable
*
* DESCRIPTION:
*       Get automatic learning status of new source MAC addresses on port ingress.
*
* INPUTS:
*       None
*
* OUTPUTS:
*       en - GT_TRUE if enabled  or GT_FALSE otherwise
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*        GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gfdbGetLearnEnable
(
    IN GT_QD_DEV    *dev,
    OUT GT_BOOL  *en
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U16          data;           /* Data to be set into the      */
                                    /* register.                    */
    DBG_INFO(("gfdbGetLearnEnable Called.\n"));

    if (IS_IN_DEV_GROUP(dev,DEV_GIGABIT_SWITCH))
    {
        return GT_NOT_SUPPORTED;
    }
    else
    {
        /* Get the Learn Enable bit.            */
        retVal = hwGetGlobalRegField(dev,QD_REG_ATU_CONTROL,14,1,&data);
        if(retVal != GT_OK)
        {
            DBG_INFO(("Failed.\n"));
            return retVal;
        }
    }

    data = 1 - data;
    BOOL_2_BIT(data, *en);

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

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

/*******************************************************************************
* gatuGetViolation
*
* DESCRIPTION:
*       Get ATU Violation data
*
* INPUTS:
*       None.
*
* OUTPUTS:
*       atuIntStatus - 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 gatuGetViolation
(
    IN  GT_QD_DEV         *dev,
    OUT GT_ATU_INT_STATUS *atuIntStatus
)
{
    GT_U16              intCause;
    GT_STATUS           retVal;
    GT_ATU_ENTRY        entry;
    GT_EXTRA_OP_DATA    opData;
    GT_BOOL                found, ageInt;

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

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

    if (!intCause)
    {
        /* No Violation occurred. */
        atuIntStatus->atuIntCause = 0;
        return GT_OK;
    }

    entry.DBNum = 0;

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

    gtMemCpy(atuIntStatus->macAddr.arEther,entry.macAddr.arEther,6);

    atuIntStatus->atuIntCause = (GT_U16)opData.intCause;
    atuIntStatus->spid = entry.entryState.ucEntryState;
    atuIntStatus->dbNum = qdShort2Char(entry.DBNum);

    if(atuIntStatus->spid != 0xF)
        atuIntStatus->spid = (GT_U8)GT_PORT_2_LPORT(atuIntStatus->spid);

    if (IS_IN_DEV_GROUP(dev,DEV_AGE_OUT_INT))
    {
        if (opData.intCause == GT_AGE_VIOLATION)
        {
            atuIntStatus->atuIntCause = GT_AGE_OUT_VIOLATION;
        }
        else if (opData.intCause == GT_MISS_VIOLATION)
        {
            /* check if it's AGE Violation */
            if((retVal = gsysGetAgeInt(dev, &ageInt)) != GT_OK)
                return retVal;

            if(ageInt)
            {
                gfdbFindAtuMacEntry(dev, &entry, &found);
                if ((found) && (entry.entryState.ucEntryState <= 4))
                    atuIntStatus->atuIntCause = GT_AGE_VIOLATION;
            }

        }
    }

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


/*******************************************************************************
* atuOperationPerform
*
* DESCRIPTION:
*       This function is used by all ATU control functions, and is responsible
*       to write the required operation into the ATU registers.
*
* INPUTS:
*       atuOp       - The ATU operation bits to be written into the ATU
*                     operation register.
*       DBNum       - ATU Database Number for CPU accesses
*       entryPri    - The EntryPri field in the ATU Data register.
*       portVec     - The portVec field in the ATU Data register.
*       entryState  - The EntryState field in the ATU Data register.
*       atuMac      - The Mac address to be written to the ATU Mac registers.
*
* OUTPUTS:
*       entryPri    - The EntryPri field in case the atuOp is GetNext.
*       portVec     - The portVec field in case the atuOp is GetNext.
*       entryState  - The EntryState field in case the atuOp is GetNext.
*       atuMac      - The returned Mac address in case the atuOp is GetNext.
*
* RETURNS:
*       GT_OK on success,
*       GT_FAIL otherwise.
*
* COMMENTS:
*       1.  if atuMac == NULL, nothing needs to be written to ATU Mac registers.
*
*******************************************************************************/
static GT_STATUS atuOperationPerform
(
    IN      GT_QD_DEV           *dev,
    IN      GT_ATU_OPERATION    atuOp,
    INOUT    GT_EXTRA_OP_DATA    *opData,
    INOUT     GT_ATU_ENTRY        *entry
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U16          data;           /* Data to be set into the      */
                                    /* register.                    */
    GT_U16          opcodeData;           /* Data to be set into the      */
                                    /* register.                    */
    GT_U8           i;
    GT_U16            portMask;

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

    portMask = (1 << dev->maxPorts) - 1;

    /* Wait until the ATU 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_ATU_OPERATION;
      regAccess.rw_reg_list[0].data = 15;
      retVal = hwAccessMultiRegs(dev, &regAccess);
      if(retVal != GT_OK)
      {
        gtSemGive(dev,dev->atuRegsSem);
        return retVal;
      }
    }
#else
    data = 1;
    while(data == 1)
    {
        retVal = hwGetGlobalRegField(dev,QD_REG_ATU_OPERATION,15,1,&data);
        if(retVal != GT_OK)
        {
            gtSemGive(dev,dev->atuRegsSem);
            return retVal;
        }
    }
#endif

    opcodeData = 0;

    switch (atuOp)
    {
        case LOAD_PURGE_ENTRY:
                if ((IS_IN_DEV_GROUP(dev,DEV_88E6093_FAMILY) &&
                    (!((IS_IN_DEV_GROUP(dev,DEV_88EC000_FAMILY))||
                       (IS_IN_DEV_GROUP(dev,DEV_88ESPANNAK_FAMILY))))) ||
                    IS_IN_DEV_GROUP(dev,DEV_TRUNK))
                {
                    if (IS_IN_DEV_GROUP(dev,DEV_TRUNK) && entry->trunkMember)
                    {
                        /* portVec represents trunk ID */
                        data = (GT_U16)( 0x8000 | (((entry->portVec) & 0xF) << 4) |
                             (((entry->entryState.ucEntryState) & 0xF)) );
                    }
                    else
                    {
                        data = (GT_U16)( (((entry->portVec) & portMask) << 4) |
                             (((entry->entryState.ucEntryState) & 0xF)) );
                    }
                    opcodeData |= (entry->prio & 0x7) << 8;
                }
                else if(IS_IN_DEV_GROUP(dev,DEV_ATU_EXT_PRI))
                {
                  if(IS_IN_DEV_GROUP(dev,DEV_MACPRI_IN_TABLE))
                  {
                    data = (GT_U16)( (((entry->portVec) & portMask) << 4) |
                             ((entry->entryState.ucEntryState) & 0xF) );
                    data |= ((entry->prio & 0x7) << 13);
                  }
                  else
                  {
                    data = (GT_U16)( (((entry->portVec) & portMask) << 4) |
                             (((entry->entryState.ucEntryState) & 0xF)) |
                             (((entry->exPrio.macQPri) & 0x3) << 14) );
                    if(entry->exPrio.useMacFPri == GT_TRUE)
                        data |= ((1 << 13) | ((entry->exPrio.macFPri & 0x7) << 10));
                  }
                }
                else
                {
                    data = (GT_U16)( (((entry->prio) & 0x3) << 14) |
                            (((entry->portVec) & portMask) << 4) |
                            (((entry->entryState.ucEntryState) & 0xF)) );
                }
                retVal = hwWriteGlobalReg(dev,QD_REG_ATU_DATA_REG,data);
                if(retVal != GT_OK)
                {
                    gtSemGive(dev,dev->atuRegsSem);
                    return retVal;
                }
                /* pass thru */

        case GET_NEXT_ENTRY:
#ifdef GT_RMGMT_ACCESS
    {
      HW_DEV_REG_ACCESS regAccess;

      regAccess.entries = 3;

      for(i = 0; i < 3; i++)
      {
        data=(entry->macAddr.arEther[2*i] << 8)|(entry->macAddr.arEther[1 + 2*i]);
        regAccess.rw_reg_list[i].cmd = HW_REG_WRITE;
        regAccess.rw_reg_list[i].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL_REG_ACCESS);
        regAccess.rw_reg_list[i].reg = QD_REG_ATU_MAC_BASE+i;
        regAccess.rw_reg_list[i].data = data;
      }
      retVal = hwAccessMultiRegs(dev, &regAccess);
      if(retVal != GT_OK)
      {
        gtSemGive(dev,dev->atuRegsSem);
        return retVal;
      }
    }
#else
                for(i = 0; i < 3; i++)
                {
                    data=(entry->macAddr.arEther[2*i] << 8)|(entry->macAddr.arEther[1 + 2*i]);
                    retVal = hwWriteGlobalReg(dev,(GT_U8)(QD_REG_ATU_MAC_BASE+i),data);
                    if(retVal != GT_OK)
                    {
                        gtSemGive(dev,dev->atuRegsSem);
                        return retVal;
                    }
                }
#endif
                break;

        case FLUSH_ALL:
        case FLUSH_UNLOCKED:
        case FLUSH_ALL_IN_DB:
        case FLUSH_UNLOCKED_IN_DB:
                if (entry->entryState.ucEntryState == 0xF)
                {
                    data = (GT_U16)(0xF | ((opData->moveFrom & 0xF) << 4) | ((opData->moveTo & 0xF) << 8));
                }
                else
                {
                    data = 0;
                }
                retVal = hwWriteGlobalReg(dev,QD_REG_ATU_DATA_REG,data);
                   if(retVal != GT_OK)
                {
                       gtSemGive(dev,dev->atuRegsSem);
                    return retVal;
                   }
                break;

        case SERVICE_VIOLATIONS:

                break;

        default :
                return GT_FAIL;
    }

    /* Set DBNum */
    if(IS_IN_DEV_GROUP(dev,DEV_FID_REG))
    {
        retVal = hwSetGlobalRegField(dev,QD_REG_ATU_FID_REG,0,12,(GT_U16)(entry->DBNum & 0xFFF));
        if(retVal != GT_OK)
        {
            gtSemGive(dev,dev->atuRegsSem);
            return retVal;
        }
    }
    else if (IS_IN_DEV_GROUP(dev,DEV_DBNUM_256))
    {
        retVal = hwSetGlobalRegField(dev,QD_REG_ATU_CONTROL,12,4,(GT_U16)((entry->DBNum & 0xF0) >> 4));
        if(retVal != GT_OK)
        {
            gtSemGive(dev,dev->atuRegsSem);
            return retVal;
        }
    }
    else if (IS_IN_DEV_GROUP(dev,DEV_DBNUM_64))
    {
        opcodeData |= ((entry->DBNum & 0x30) << 4);    /* Op Reg bit 9:8 */
    }

    /* Set the ATU Operation register in addtion to DBNum setup  */

    if(IS_IN_DEV_GROUP(dev,DEV_FID_REG))
        opcodeData |= ((1 << 15) | (atuOp << 12));
    else
    {
        opcodeData |= ((1 << 15) | (atuOp << 12) | (entry->DBNum & 0xF));
    }

    retVal = hwWriteGlobalReg(dev,QD_REG_ATU_OPERATION,opcodeData);
    if(retVal != GT_OK)
    {
        gtSemGive(dev,dev->atuRegsSem);
        return retVal;
    }

    /* If the operation is to service violation operation wait for the response   */
    if(atuOp == SERVICE_VIOLATIONS)
    {
        /* 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_ATU_OPERATION;
          regAccess.rw_reg_list[0].data = 15;
          retVal = hwAccessMultiRegs(dev, &regAccess);
          if(retVal != GT_OK)
          {
            gtSemGive(dev,dev->atuRegsSem);
          return retVal;
          }
        }
#else
        data = 1;
        while(data == 1)
        {
            retVal = hwGetGlobalRegField(dev,QD_REG_ATU_OPERATION,15,1,&data);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->atuRegsSem);
                return retVal;
            }
        }
#endif

        /* get the Interrupt Cause */
        retVal = hwGetGlobalRegField(dev,QD_REG_ATU_OPERATION,4,4,&data);
        if(retVal != GT_OK)
        {
            gtSemGive(dev,dev->atuRegsSem);
            return retVal;
        }
        if (!IS_IN_DEV_GROUP(dev,DEV_AGE_OUT_INT))
        {
            data &= 0x7;    /* only 3 bits are valid for non age_out_int group */
        }

        switch (data)
        {
            case 8:    /* Age Interrupt */
                opData->intCause = GT_AGE_VIOLATION;
                break;
            case 4:    /* Member Violation */
                opData->intCause = GT_MEMBER_VIOLATION;
                break;
            case 2:    /* Miss Violation */
                opData->intCause = GT_MISS_VIOLATION;
                break;
            case 1:    /* Full Violation */
                opData->intCause = GT_FULL_VIOLATION;
                break;
            default:
                opData->intCause = 0;
                gtSemGive(dev,dev->atuRegsSem);
                return GT_OK;
        }

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

        entry->DBNum = 0;

        if(IS_IN_DEV_GROUP(dev,DEV_FID_REG))
        {
            retVal = hwGetGlobalRegField(dev,QD_REG_ATU_FID_REG,0,12,&data);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->atuRegsSem);
                return retVal;
            }
            entry->DBNum = (GT_U16)data;
        }
        else if (IS_IN_DEV_GROUP(dev,DEV_DBNUM_256))
        {
            retVal = hwGetGlobalRegField(dev,QD_REG_ATU_CONTROL,12,4,&data);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->atuRegsSem);
                return retVal;
            }
            entry->DBNum = (GT_U16)data << 4;
        }
        else if (IS_IN_DEV_GROUP(dev,DEV_DBNUM_64))
        {
            retVal = hwGetGlobalRegField(dev,QD_REG_ATU_OPERATION,8,2,&data);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->atuRegsSem);
                return retVal;
            }
            entry->DBNum = (GT_U16)data << 4;
        }

        if(!IS_IN_DEV_GROUP(dev,DEV_FID_REG))
        {
            retVal = hwGetGlobalRegField(dev,QD_REG_ATU_OPERATION,0,4,&data);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->atuRegsSem);
                return retVal;
            }

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

        /* get the Source Port ID that was involved in the violation */

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

        entry->entryState.ucEntryState = data & 0xF;

        /* Get the Mac address  */
#ifdef GT_RMGMT_ACCESS
        {
          HW_DEV_REG_ACCESS regAccess;

          regAccess.entries = 3;

          for(i = 0; i < 3; i++)
          {
            regAccess.rw_reg_list[i].cmd = HW_REG_READ;
            regAccess.rw_reg_list[i].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL_REG_ACCESS);
            regAccess.rw_reg_list[i].reg = QD_REG_ATU_MAC_BASE+i;
            regAccess.rw_reg_list[i].data = 0;
          }
          retVal = hwAccessMultiRegs(dev, &regAccess);
          if(retVal != GT_OK)
          {
            gtSemGive(dev,dev->atuRegsSem);
            return retVal;
          }
          for(i = 0; i < 3; i++)
          {
            entry->macAddr.arEther[2*i] = qdLong2Char(regAccess.rw_reg_list[i].data >> 8);
            entry->macAddr.arEther[1 + 2*i] = qdLong2Char(regAccess.rw_reg_list[i].data & 0xFF);
          }
        }
#else
        for(i = 0; i < 3; i++)
        {
            retVal = hwReadGlobalReg(dev,(GT_U8)(QD_REG_ATU_MAC_BASE+i),&data);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->atuRegsSem);
                return retVal;
            }
            entry->macAddr.arEther[2*i] = data >> 8;
            entry->macAddr.arEther[1 + 2*i] = data & 0xFF;
        }
#endif


    } /* end of service violations */
    /* If the operation is a gen next operation wait for the response   */
    if(atuOp == GET_NEXT_ENTRY)
    {
        entry->trunkMember = GT_FALSE;
        entry->exPrio.useMacFPri = GT_FALSE;
        entry->exPrio.macFPri = 0;
        entry->exPrio.macQPri = 0;

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

          regAccess.entries = 5;

          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_ATU_OPERATION;
          regAccess.rw_reg_list[0].data = 15;

          for(i = 1; i < 4; i++)
          {
            regAccess.rw_reg_list[i].cmd = HW_REG_READ;
            regAccess.rw_reg_list[i].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL_REG_ACCESS);
            regAccess.rw_reg_list[i].reg = QD_REG_ATU_MAC_BASE+i-1;
            regAccess.rw_reg_list[i].data = 0;
          }

          regAccess.rw_reg_list[4].cmd = HW_REG_READ;
          regAccess.rw_reg_list[4].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL_REG_ACCESS);
          regAccess.rw_reg_list[4].reg = QD_REG_ATU_DATA_REG;
          regAccess.rw_reg_list[4].data = 0;

          retVal = hwAccessMultiRegs(dev, &regAccess);
          if(retVal != GT_OK)
          {
            gtSemGive(dev,dev->atuRegsSem);
            return retVal;
          }
          for(i = 0; i < 3; i++)
          {
            entry->macAddr.arEther[2*i] = qdLong2Char(regAccess.rw_reg_list[i+1].data >> 8);
            entry->macAddr.arEther[1 + 2*i] = qdLong2Char(regAccess.rw_reg_list[i+1].data & 0xFF);
          }
          data = qdLong2Short(regAccess.rw_reg_list[4].data);
        }
#else
        data = 1;
        while(data == 1)
        {
            retVal = hwGetGlobalRegField(dev,QD_REG_ATU_OPERATION,15,1,&data);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->atuRegsSem);
                return retVal;
            }
        }

        /* Get the Mac address  */
        for(i = 0; i < 3; i++)
        {
            retVal = hwReadGlobalReg(dev,(GT_U8)(QD_REG_ATU_MAC_BASE+i),&data);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->atuRegsSem);
                return retVal;
            }
            entry->macAddr.arEther[2*i] = data >> 8;
            entry->macAddr.arEther[1 + 2*i] = data & 0xFF;
        }

        retVal = hwReadGlobalReg(dev,QD_REG_ATU_DATA_REG,&data);
        if(retVal != GT_OK)
        {
            gtSemGive(dev,dev->atuRegsSem);
            return retVal;
        }
#endif

        /* Get the Atu data register fields */
        if ((IS_IN_DEV_GROUP(dev,DEV_88E6093_FAMILY) &&
            (!((IS_IN_DEV_GROUP(dev,DEV_88EC000_FAMILY))||
               (IS_IN_DEV_GROUP(dev,DEV_88ESPANNAK_FAMILY))))) ||
            IS_IN_DEV_GROUP(dev,DEV_TRUNK))
        {
            if (IS_IN_DEV_GROUP(dev,DEV_TRUNK))
            {
                entry->trunkMember = (data & 0x8000)?GT_TRUE:GT_FALSE;
            }

            entry->portVec = (data >> 4) & portMask;
            entry->entryState.ucEntryState = data & 0xF;
            retVal = hwGetGlobalRegField(dev,QD_REG_ATU_OPERATION,8,3,&data);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->atuRegsSem);
                return retVal;
            }
            entry->prio = (GT_U8)data;
        }
        else if(IS_IN_DEV_GROUP(dev,DEV_ATU_EXT_PRI))
        {
          if(IS_IN_DEV_GROUP(dev,DEV_MACPRI_IN_TABLE))
          {
            entry->portVec = (data >> 4) & portMask;
            entry->entryState.ucEntryState = data & 0xF;
            entry->prio = (data >> 13) & 0x7;
            entry->exPrio.macFPri = entry->prio;
            entry->exPrio.macQPri = entry->prio;
            entry->prio = 0;
            entry->exPrio.useMacFPri = GT_FALSE; /* doesn't care */
          }
          else
          {
            entry->prio = 0;
            entry->portVec = (data >> 4) & portMask;
            entry->entryState.ucEntryState = data & 0xF;
            entry->exPrio.useMacFPri = (data & 0x2000)?GT_TRUE:GT_FALSE;
            entry->exPrio.macFPri = (data >> 10) & 0x7;
            entry->exPrio.macQPri = data >> 14;
          }
        }
        else
        {
            entry->prio = data >> 14;
            entry->portVec = (data >> 4) & portMask;
            entry->entryState.ucEntryState = data & 0xF;
        }
    }

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

static GT_STATUS atuStateAppToDev
(
    IN  GT_QD_DEV    *dev,
    IN  GT_BOOL        unicast,
    IN  GT_U32        state,
    OUT GT_U32        *newOne
)
{
    GT_U32    newState;
    GT_STATUS    retVal = GT_OK;

    if(unicast)
    {
        switch ((GT_ATU_UC_STATE)state)
        {
            case GT_UC_INVALID:
                newState = state;
                break;

            case GT_UC_DYNAMIC:
                if (IS_IN_DEV_GROUP(dev,DEV_UC_7_DYNAMIC))
                {
                    newState = 7;
                }
                else
                {
                    newState = 0xE;
                }
                break;

            case GT_UC_NO_PRI_TO_CPU_STATIC_NRL:
                if (IS_IN_DEV_GROUP(dev,DEV_UC_NO_PRI_TO_CPU_STATIC_NRL))
                {
                    newState = state;
                }
                else
                {
                    newState = (GT_U32)GT_UC_STATIC;
                    retVal = GT_BAD_PARAM;
                }
                break;

            case GT_UC_TO_CPU_STATIC_NRL:
                if (IS_IN_DEV_GROUP(dev,DEV_UC_TO_CPU_STATIC_NRL))
                {
                    newState = state;
                }
                else
                {
                    newState = (GT_U32)GT_UC_STATIC;
                    retVal = GT_BAD_PARAM;
                }
                break;

            case GT_UC_NO_PRI_STATIC_NRL:
                if (IS_IN_DEV_GROUP(dev,DEV_UC_NO_PRI_STATIC_NRL))
                {
                    newState = state;
                }
                else
                {
                    newState = (GT_U32)GT_UC_STATIC;
                    retVal = GT_BAD_PARAM;
                }
                break;

            case GT_UC_STATIC_NRL:
                if (IS_IN_DEV_GROUP(dev,DEV_UC_STATIC_NRL))
                {
                    newState = state;
                }
                else
                {
                    newState = (GT_U32)GT_UC_STATIC;
                    retVal = GT_BAD_PARAM;
                }
                break;

            case GT_UC_NO_PRI_TO_CPU_STATIC:
                if (IS_IN_DEV_GROUP(dev,DEV_UC_NO_PRI_TO_CPU_STATIC))
                {
                    newState = state;
                }
                else
                {
                    newState = (GT_U32)GT_UC_STATIC;
                    retVal = GT_BAD_PARAM;
                }
                break;

            case GT_UC_TO_CPU_STATIC:
                if (IS_IN_DEV_GROUP(dev,DEV_UC_TO_CPU_STATIC))
                {
                    newState = state;
                }
                else
                {
                    newState = (GT_U32)GT_UC_STATIC;
                    retVal = GT_BAD_PARAM;
                }
                break;

            case GT_UC_NO_PRI_STATIC:
                if (IS_IN_DEV_GROUP(dev,DEV_UC_NO_PRI_STATIC))
                {
                    newState = state;
                }
                else
                {
                    newState = (GT_U32)GT_UC_STATIC;
                    retVal = GT_BAD_PARAM;
                }
                break;

            case GT_UC_STATIC:
                if (IS_IN_DEV_GROUP(dev,DEV_UC_STATIC))
                {
                    newState = state;
                }
                else
                {
                    newState = (GT_U32)GT_UC_STATIC;
                    retVal = GT_BAD_PARAM;
                }
                break;

            default:
                if (IS_IN_DEV_GROUP(dev,DEV_UC_7_DYNAMIC))
                {
                    newState = 7;
                }
                else
                {
                    newState = 0xE;
                }
                retVal = GT_BAD_PARAM;
                break;

        }
    }
    else
    {
        switch ((GT_ATU_UC_STATE)state)
        {
            case GT_MC_INVALID:
                newState = state;
                break;

            case GT_MC_MGM_STATIC_UNLIMITED_RATE:
                if (IS_IN_DEV_GROUP(dev,DEV_MC_MGM_STATIC_UNLIMITED_RATE))
                {
                    newState = state;
                }
                else
                {
                    newState = (GT_U32)GT_MC_STATIC;
                    retVal = GT_BAD_PARAM;
                }
                break;

            case GT_MC_STATIC_UNLIMITED_RATE:
                if (IS_IN_DEV_GROUP(dev,DEV_MC_STATIC_UNLIMITED_RATE))
                {
                    newState = state;
                }
                else
                {
                    newState = (GT_U32)GT_MC_STATIC;
                    retVal = GT_BAD_PARAM;
                }
                break;

            case GT_MC_MGM_STATIC:
                if (IS_IN_DEV_GROUP(dev,DEV_MC_MGM_STATIC))
                {
                    newState = state;
                }
                else
                {
                    newState = (GT_U32)GT_MC_STATIC;
                    retVal = GT_BAD_PARAM;
                }
                break;

            case GT_MC_STATIC:
                if (IS_IN_DEV_GROUP(dev,DEV_MC_STATIC))
                {
                    newState = state;
                }
                else
                {
                    newState = (GT_U32)GT_MC_STATIC;
                    retVal = GT_BAD_PARAM;
                }
                break;

            case GT_MC_PRIO_MGM_STATIC_UNLIMITED_RATE:
                if (IS_IN_DEV_GROUP(dev,DEV_MC_PRIO_MGM_STATIC_UNLIMITED_RATE))
                {
                    newState = state;
                }
                else
                {
                    newState = (GT_U32)GT_MC_STATIC;
                    retVal = GT_BAD_PARAM;
                }
                break;

            case GT_MC_PRIO_STATIC_UNLIMITED_RATE:
                if (IS_IN_DEV_GROUP(dev,DEV_MC_PRIO_STATIC_UNLIMITED_RATE))
                {
                    newState = state;
                }
                else
                {
                    newState = (GT_U32)GT_MC_STATIC;
                    retVal = GT_BAD_PARAM;
                }
                break;

            case GT_MC_PRIO_MGM_STATIC:
                if (IS_IN_DEV_GROUP(dev,DEV_MC_PRIO_MGM_STATIC))
                {
                    newState = state;
                }
                else
                {
                    newState = (GT_U32)GT_MC_STATIC;
                    retVal = GT_BAD_PARAM;
                }
                break;

            case GT_MC_PRIO_STATIC:
                if (IS_IN_DEV_GROUP(dev,DEV_MC_PRIO_STATIC))
                {
                    newState = state;
                }
                else
                {
                    newState = (GT_U32)GT_MC_STATIC;
                    retVal = GT_BAD_PARAM;
                }
                break;

            default:
                newState = (GT_U32)GT_MC_STATIC;
                retVal = GT_BAD_PARAM;
                break;

        }
    }

    *newOne = newState;
    return retVal;
}

static GT_STATUS atuStateDevToApp
(
    IN  GT_QD_DEV    *dev,
    IN  GT_BOOL        unicast,
    IN  GT_U32        state,
    OUT GT_U32        *newOne
)
{
    GT_U32    newState;
    GT_STATUS    retVal = GT_OK;

    if(unicast)
    {
        if (state == 0)
        {
            newState = (GT_U32)GT_UC_INVALID;
        }
        else if (state <= 7)
        {
            newState = (GT_U32)GT_UC_DYNAMIC;
        }
        else if ((state <= 0xE) && (!IS_IN_DEV_GROUP(dev,DEV_UC_7_DYNAMIC)))
        {
            newState = (GT_U32)GT_UC_DYNAMIC;
        }
        else
        {
            newState = state;
        }
    }
    else
    {
        newState = state;
    }

    *newOne = newState;
    return retVal;
}


static GT_STATUS atuGetStats
(
    IN  GT_QD_DEV    *dev,
    IN  GT_ATU_STAT    *atuStat,
    OUT GT_U32        *count
)
{
    GT_U32          numOfEntries, dbNum;
    GT_ATU_ENTRY    entry;
    GT_U16            data,mode,bin;
    GT_STATUS       retVal;

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

    switch (atuStat->op)
    {
        case GT_ATU_STATS_ALL:
        case GT_ATU_STATS_NON_STATIC:
            dbNum = 0;
            break;
        case GT_ATU_STATS_ALL_FID:
        case GT_ATU_STATS_NON_STATIC_FID:
            dbNum = atuStat->DBNum;
            break;
        default:
            return GT_FALSE;
    }

    numOfEntries = 0;
    mode = atuStat->op;

    for(bin=0; bin<4; bin++)
    {
        data = (bin << 14) | (mode << 12);

        retVal = hwWriteGlobal2Reg(dev, QD_REG_ATU_STATS, data);
           if(retVal != GT_OK)
        {
               DBG_INFO(("Failed.\n"));
               return retVal;
        }

        entry.DBNum = (GT_U16)dbNum;
        gtMemSet(entry.macAddr.arEther,0,sizeof(GT_ETHERADDR));

        retVal = atuOperationPerform(dev,GET_NEXT_ENTRY,NULL,&entry);
           if(retVal == GT_FAIL)
        {
               DBG_INFO(("Failed.\n"));
               return retVal;
        }

        retVal = hwReadGlobal2Reg(dev, QD_REG_ATU_STATS, &data);
           if(retVal != GT_OK)
        {
               DBG_INFO(("Failed.\n"));
               return retVal;
        }

        numOfEntries += (data & 0xFFF);
    }

    *count = numOfEntries;

    return GT_OK;
}
