#include <Copyright.h>

/*******************************************************************************
* gtPortCounter.c
*
* DESCRIPTION:
*       API definitions for RMON counters
*
* DEPENDENCIES:
*
* FILE REVISION NUMBER:
*******************************************************************************/

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

/****************************************************************************/
/* STATS operation function declaration.                                    */
/****************************************************************************/
static GT_STATUS statsOperationPerform
(
    IN   GT_QD_DEV            *dev,
    IN   GT_STATS_OPERATION   statsOp,
    IN   GT_U8                port,
    IN   GT_STATS_COUNTERS    counter,
    OUT  GT_VOID              *statsData
);

static GT_STATUS statsCapture
(
    IN GT_QD_DEV  *dev,
    IN GT_U8      port
);

static GT_STATUS statsReadCounter
(
    IN   GT_QD_DEV        *dev,
    IN   GT_U32            counter,
    OUT  GT_U32            *statsData
);

static GT_STATUS statsReadRealtimeCounter
(
    IN   GT_QD_DEV      *dev,
    IN   GT_U8             port,
    IN   GT_U32            counter,
    OUT  GT_U32            *statsData
);


/*******************************************************************************
* gstatsFlushAll
*
* DESCRIPTION:
*       Flush All counters for all ports.
*
* INPUTS:
*       None.
*
* OUTPUTS:
*       None.
*
* RETURNS:
*       GT_OK      - on success
*       GT_FAIL    - on error
*
* COMMENTS:
*       None
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gstatsFlushAll
(
        IN GT_QD_DEV  *dev
)
{
    GT_STATUS           retVal;

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

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

    retVal = statsOperationPerform(dev,STATS_FLUSH_ALL,0,0,NULL);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed (statsOperationPerform returned GT_FAIL).\n"));
        return retVal;
    }

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

}


/*******************************************************************************
* gstatsFlushPort
*
* DESCRIPTION:
*       Flush All counters for a given port.
*
* INPUTS:
*       port - the logical port number.
*
* OUTPUTS:
*       None.
*
* RETURNS:
*       GT_OK      - on success
*       GT_FAIL    - on error
*
* COMMENTS:
*       None
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gstatsFlushPort
(
    IN GT_QD_DEV  *dev,
    IN GT_LPORT      port
)
{
    GT_STATUS    retVal;
    GT_U8        hwPort;         /* physical port number         */

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

    /* translate logical port to physical port */
    hwPort = GT_LPORT_2_PORT(port);

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

    retVal = statsOperationPerform(dev,STATS_FLUSH_PORT,hwPort,0,NULL);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed (statsOperationPerform returned GT_FAIL).\n"));
        return retVal;
    }

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

}

/*******************************************************************************
* gstatsGetPortCounter
*
* DESCRIPTION:
*        This routine gets a specific counter of the given port
*
* INPUTS:
*        port - the logical port number.
*        counter - the counter which will be read
*
* OUTPUTS:
*        statsData - points to 32bit data storage for the MIB counter
*
* RETURNS:
*        GT_OK      - on success
*        GT_FAIL    - on error
*
* COMMENTS:
*        None
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gstatsGetPortCounter
(
    IN  GT_QD_DEV        *dev,
    IN  GT_LPORT        port,
    IN  GT_STATS_COUNTERS    counter,
    OUT GT_U32            *statsData
)
{
    GT_STATUS    retVal;
    GT_U8        hwPort;         /* physical port number         */

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

    /* translate logical port to physical port */
    hwPort = GT_LPORT_2_PORT(port);

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

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

    retVal = statsOperationPerform(dev,STATS_READ_COUNTER,hwPort,counter,(GT_VOID*)statsData);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed (statsOperationPerform returned GT_FAIL).\n"));
        return retVal;
    }

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

}


/*******************************************************************************
* gstatsGetPortAllCounters
*
* DESCRIPTION:
*       This routine gets all counters of the given port
*
* INPUTS:
*       port - the logical port number.
*
* OUTPUTS:
*       statsCounterSet - points to GT_STATS_COUNTER_SET for the MIB counters
*
* RETURNS:
*       GT_OK      - on success
*       GT_FAIL    - on error
*
* COMMENTS:
*       None
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gstatsGetPortAllCounters
(
    IN  GT_QD_DEV               *dev,
    IN  GT_LPORT        port,
    OUT GT_STATS_COUNTER_SET    *statsCounterSet
)
{
    GT_STATUS    retVal;
    GT_U8        hwPort;         /* physical port number         */

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

    /* translate logical port to physical port */
    hwPort = GT_LPORT_2_PORT(port);

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

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

    retVal = statsOperationPerform(dev,STATS_READ_ALL,hwPort,0,(GT_VOID*)statsCounterSet);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed (statsOperationPerform returned GT_FAIL).\n"));
        return retVal;
    }

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

}

/*******************************************************************************
* gstatsGetPortCounter2
*
* DESCRIPTION:
*        This routine gets a specific counter of the given port
*
* INPUTS:
*        port - the logical port number.
*        counter - the counter which will be read
*
* OUTPUTS:
*        statsData - points to 32bit data storage for the MIB counter
*
* RETURNS:
*        GT_OK      - on success
*        GT_FAIL    - on error
*
* COMMENTS:
*
*******************************************************************************/
GT_STATUS gstatsGetPortCounter2
(
    IN  GT_QD_DEV        *dev,
    IN  GT_LPORT        port,
    IN  GT_STATS_COUNTERS2    counter,
    OUT GT_U32            *statsData
)
{
    GT_STATUS    retVal;
    GT_U8        hwPort;         /* physical port number         */

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

    /* translate logical port to physical port */
    hwPort = GT_LPORT_2_PORT(port);

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

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

    retVal = statsOperationPerform(dev,STATS_READ_COUNTER,hwPort,counter,(GT_VOID*)statsData);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed (statsOperationPerform returned GT_FAIL).\n"));
        return retVal;
    }

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

}


/*******************************************************************************
* gstatsGetPortAllCounters2
*
* DESCRIPTION:
*        This routine gets all counters of the given port
*
* INPUTS:
*        port - the logical port number.
*
* OUTPUTS:
*        statsCounterSet - points to GT_STATS_COUNTER_SET for the MIB counters
*
* RETURNS:
*        GT_OK      - on success
*        GT_FAIL    - on error
*
* COMMENTS:
*
*******************************************************************************/
GT_STATUS gstatsGetPortAllCounters2
(
    IN  GT_QD_DEV        *dev,
    IN  GT_LPORT        port,
    OUT GT_STATS_COUNTER_SET2    *statsCounterSet
)
{
    GT_STATUS    retVal;
    GT_U8        hwPort;         /* physical port number         */

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

    /* translate logical port to physical port */
    hwPort = GT_LPORT_2_PORT(port);

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

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

    retVal = statsOperationPerform(dev,STATS_READ_ALL,hwPort,0,(GT_VOID*)statsCounterSet);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed (statsOperationPerform returned GT_FAIL).\n"));
        return retVal;
    }

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

}

/*******************************************************************************
* gstatsGetPortCounter3
*
* DESCRIPTION:
*        This routine gets a specific counter of the given port
*
* INPUTS:
*        port - the logical port number.
*        counter - the counter which will be read
*
* OUTPUTS:
*        statsData - points to 32bit data storage for the MIB counter
*
* RETURNS:
*        GT_OK      - on success
*        GT_FAIL    - on error
*
* COMMENTS:
*        This function supports Gigabit Switch and Spinnaker family
*
*******************************************************************************/
GT_STATUS gstatsGetPortCounter3
(
    IN  GT_QD_DEV        *dev,
    IN  GT_LPORT        port,
    IN  GT_STATS_COUNTERS3    counter,
    OUT GT_U32            *statsData
)
{
    GT_STATUS    retVal;
    GT_U8        hwPort;         /* physical port number         */

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

    /* translate logical port to physical port */
    hwPort = GT_LPORT_2_PORT(port);

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

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

    retVal = statsOperationPerform(dev,STATS_READ_COUNTER,hwPort,counter,(GT_VOID*)statsData);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed (statsOperationPerform returned GT_FAIL).\n"));
        return retVal;
    }

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

}


/*******************************************************************************
* gstatsGetPortAllCounters3
*
* DESCRIPTION:
*        This routine gets all counters of the given port
*
* INPUTS:
*        port - the logical port number.
*
* OUTPUTS:
*        statsCounterSet - points to GT_STATS_COUNTER_SET for the MIB counters
*
* RETURNS:
*        GT_OK      - on success
*        GT_FAIL    - on error
*
* COMMENTS:
*        This function supports Gigabit Switch and Spinnaker family
*
*******************************************************************************/
GT_STATUS gstatsGetPortAllCounters3
(
    IN  GT_QD_DEV        *dev,
    IN  GT_LPORT        port,
    OUT GT_STATS_COUNTER_SET3    *statsCounterSet
)
{
    GT_STATUS    retVal;
    GT_U8        hwPort;         /* physical port number         */

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

    /* translate logical port to physical port */
    hwPort = GT_LPORT_2_PORT(port);

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

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

    retVal = statsOperationPerform(dev,STATS_READ_ALL,hwPort,0,(GT_VOID*)statsCounterSet);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed (statsOperationPerform returned GT_FAIL).\n"));
        return retVal;
    }

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

}

/*******************************************************************************
* gstatsGetHistogramMode
*
* DESCRIPTION:
*        This routine gets the Histogram Counters Mode.
*
* INPUTS:
*        None.
*
* OUTPUTS:
*        mode - Histogram Mode (GT_COUNT_RX_ONLY, GT_COUNT_TX_ONLY,
*                    and GT_COUNT_RX_TX)
*
* RETURNS:
*        GT_OK           - on success
*        GT_BAD_PARAM    - on bad parameter
*        GT_FAIL         - on error
*        GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*
*******************************************************************************/
GT_STATUS gstatsGetHistogramMode
(
    IN  GT_QD_DEV                *dev,
    OUT GT_HISTOGRAM_MODE    *mode
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U16          data;           /* The register's read data.    */

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

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

    /* Get the Histogram mode bit.                */
    retVal = hwGetGlobalRegField(dev,QD_REG_STATS_OPERATION,10,2,&data);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }

    *mode = data - 1; /* Software definition starts from 0 ~ 2,
                        while hardware supports the values from 1 to 3 */

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

/*******************************************************************************
* gstatsSetHistogramMode
*
* DESCRIPTION:
*        This routine sets the Histogram Counters Mode.
*
* INPUTS:
*        mode - Histogram Mode (GT_COUNT_RX_ONLY, GT_COUNT_TX_ONLY,
*                    and GT_COUNT_RX_TX)
*
* OUTPUTS:
*        None.
*
* RETURNS:
*        GT_OK           - on success
*        GT_BAD_PARAM    - on bad parameter
*        GT_FAIL         - on error
*        GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*
*******************************************************************************/
GT_STATUS gstatsSetHistogramMode
(
    IN GT_QD_DEV                 *dev,
    IN GT_HISTOGRAM_MODE        mode
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U16          data;           /* The register's read data.    */

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

    switch (mode)
    {
        case GT_COUNT_RX_ONLY:
        case GT_COUNT_TX_ONLY:
        case GT_COUNT_RX_TX:
            break;
        default:
            DBG_INFO(("Failed.\n"));
            return GT_BAD_PARAM;
    }

    data = (GT_U16)mode + 1;

    /* Set the Histogram mode bit.                */
    retVal = hwSetGlobalRegField(dev,QD_REG_STATS_OPERATION,10,2,data);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }

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


/*******************************************************************************
* gstatsGetRealtimePortCounter
*
* DESCRIPTION:
*        This routine gets a specific realtime counter of the given port
*
* INPUTS:
*        port - the logical port number.
*        counter - the counter which will be read
*
* OUTPUTS:
*        statsData - points to 32bit data storage for the MIB counter
*
* RETURNS:
*        GT_OK      - on success
*        GT_FAIL    - on error
*
* COMMENTS:
*
*******************************************************************************/
GT_STATUS gstatsGetRealtimePortCounter
(
    IN  GT_QD_DEV        *dev,
    IN  GT_LPORT        port,
    IN  GT_STATS_COUNTERS3    counter,
    OUT GT_U32            *statsData
)
{
    GT_STATUS    retVal;
    GT_U8        hwPort;         /* physical port number         */

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

    /* translate logical port to physical port */
    hwPort = GT_LPORT_2_PORT(port);

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

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

    retVal = statsOperationPerform(dev,STATS_READ_REALTIME_COUNTER,hwPort,counter,(GT_VOID*)statsData);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed (statsOperationPerform returned GT_FAIL).\n"));
        return retVal;
    }

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

}


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

/*******************************************************************************
* statsOperationPerform
*
* DESCRIPTION:
*       This function is used by all stats control functions, and is responsible
*       to write the required operation into the stats registers.
*
* INPUTS:
*       statsOp       - The stats operation bits to be written into the stats
*                     operation register.
*       port        - port number
*       counter     - counter to be read if it's read operation
*
* OUTPUTS:
*       statsData   - points to the data storage where the MIB counter will be saved.
*
* RETURNS:
*       GT_OK on success,
*       GT_FAIL otherwise.
*
* COMMENTS:
*
*******************************************************************************/

static GT_STATUS statsOperationPerform
(
    IN   GT_QD_DEV            *dev,
    IN   GT_STATS_OPERATION   statsOp,
    IN   GT_U8                port,
    IN   GT_STATS_COUNTERS    counter,
    OUT  GT_VOID              *statsData
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U16          data,histoData; /* Data to be set into the      */
                                    /* register.                    */
    GT_U32 statsCounter;
    GT_U32 lastCounter;
    GT_U16            portNum;

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

    if (!((IS_IN_DEV_GROUP(dev,DEV_GIGABIT_SWITCH)) ||
        (IS_IN_DEV_GROUP(dev,DEV_RMON_REALTIME_SUPPORT))))
    {
      if (IS_IN_DEV_GROUP(dev,DEV_MELODY_SWITCH))
        lastCounter = (GT_U32)STATS2_Late;
      else
        lastCounter = (GT_U32)STATS_OutDiscards;
    }
    else
    {
        lastCounter = (GT_U32)STATS3_Late;
    }

    if (IS_IN_DEV_GROUP(dev,DEV_RMON_PORT_BITS))
    {
        portNum = (port + 1) << 5;
    }
    else
    {
        portNum = (GT_U16)port;
    }

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

      regAccess.entries = 2;

      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_STATS_OPERATION;
      regAccess.rw_reg_list[0].data = 15;
      regAccess.rw_reg_list[1].cmd = HW_REG_READ;
      regAccess.rw_reg_list[1].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL_REG_ACCESS);
      regAccess.rw_reg_list[1].reg = QD_REG_STATS_OPERATION;
      regAccess.rw_reg_list[1].data = 0;
      retVal = hwAccessMultiRegs(dev, &regAccess);
      if(retVal != GT_OK)
      {
        gtSemGive(dev,dev->statsRegsSem);
        return retVal;
      }
      histoData = qdLong2Short(regAccess.rw_reg_list[1].data);
    }
#else
    data = 1;
    while(data == 1)
    {
        retVal = hwGetGlobalRegField(dev,QD_REG_STATS_OPERATION,15,1,&data);
        if(retVal != GT_OK)
        {
            gtSemGive(dev,dev->statsRegsSem);
            return retVal;
        }
    }

    /* Get the Histogram mode bit.                */
    retVal = hwReadGlobalReg(dev,QD_REG_STATS_OPERATION,&histoData);
    if(retVal != GT_OK)
    {
        gtSemGive(dev,dev->statsRegsSem);
        return retVal;
    }

#endif
    histoData &= 0xC00;

    /* Set the STAT Operation register */
    switch (statsOp)
    {
        case STATS_FLUSH_ALL:
            data = (1 << 15) | (GT_STATS_FLUSH_ALL << 12) | histoData;
            retVal = hwWriteGlobalReg(dev,QD_REG_STATS_OPERATION,data);
            gtSemGive(dev,dev->statsRegsSem);
            return retVal;

        case STATS_FLUSH_PORT:
            data = (1 << 15) | (GT_STATS_FLUSH_PORT << 12) | portNum | histoData;
            retVal = hwWriteGlobalReg(dev,QD_REG_STATS_OPERATION,data);
            gtSemGive(dev,dev->statsRegsSem);
            return retVal;

        case STATS_READ_COUNTER:
            retVal = statsCapture(dev,port);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->statsRegsSem);
                return retVal;
            }

            retVal = statsReadCounter(dev,counter,(GT_U32*)statsData);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->statsRegsSem);
                return retVal;
            }
            break;

        case STATS_READ_REALTIME_COUNTER:
            retVal = statsReadRealtimeCounter(dev,port,counter,(GT_U32*)statsData);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->statsRegsSem);
                return retVal;
            }

            break;

        case STATS_READ_ALL:
            retVal = statsCapture(dev,port);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->statsRegsSem);
                return retVal;
            }

            for(statsCounter=0; statsCounter<=lastCounter; statsCounter++)
            {
                retVal = statsReadCounter(dev,statsCounter,((GT_U32*)statsData + statsCounter));
                if(retVal != GT_OK)
                {
                    gtSemGive(dev,dev->statsRegsSem);
                    return retVal;
                }
            }
            break;

        default:

            gtSemGive(dev,dev->statsRegsSem);
            return GT_FAIL;
    }

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


/*******************************************************************************
* statsCapture
*
* DESCRIPTION:
*       This function is used to capture all counters of a port.
*
* INPUTS:
*       port        - port number
*
* OUTPUTS:
*        None.
*
* RETURNS:
*       GT_OK on success,
*       GT_FAIL otherwise.
*
* COMMENTS:
*        If Semaphore is used, Semaphore should be acquired before this function call.
*******************************************************************************/
static GT_STATUS statsCapture
(
    IN GT_QD_DEV            *dev,
    IN GT_U8             port
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U16          data, histoData;/* Data to be set into the      */
                                    /* register.                    */
    GT_U16            portNum;

    if (IS_IN_DEV_GROUP(dev,DEV_RMON_PORT_BITS))
    {
        portNum = (port + 1) << 5;
    }
    else
    {
        portNum = (GT_U16)port;
    }

    /* Get the Histogram mode bit.                */
    retVal = hwReadGlobalReg(dev,QD_REG_STATS_OPERATION,&histoData);
    if(retVal != GT_OK)
    {
        return retVal;
    }

    histoData &= 0xC00;

#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_STATS_OPERATION;
      regAccess.rw_reg_list[0].data = 15;
      retVal = hwAccessMultiRegs(dev, &regAccess);
      if(retVal != GT_OK)
      {
        return retVal;
      }
    }
#else
    data = 1;
       while(data == 1)
    {
        retVal = hwGetGlobalRegField(dev,QD_REG_STATS_OPERATION,15,1,&data);
        if(retVal != GT_OK)
           {
               return retVal;
        }
       }
#endif

    data = (1 << 15) | (GT_STATS_CAPTURE_PORT << 12) | portNum | histoData;
    retVal = hwWriteGlobalReg(dev,QD_REG_STATS_OPERATION,data);
    if(retVal != GT_OK)
    {
        return retVal;
    }

    return GT_OK;

}


/*******************************************************************************
* statsReadCounter
*
* DESCRIPTION:
*       This function is used to read a captured counter.
*
* INPUTS:
*       counter     - counter to be read if it's read operation
*
* OUTPUTS:
*       statsData   - points to the data storage where the MIB counter will be saved.
*
* RETURNS:
*       GT_OK on success,
*       GT_FAIL otherwise.
*
* COMMENTS:
*        If Semaphore is used, Semaphore should be acquired before this function call.
*******************************************************************************/
static GT_STATUS statsReadCounter
(
    IN   GT_QD_DEV      *dev,
    IN   GT_U32            counter,
    OUT  GT_U32            *statsData
)
{
    GT_STATUS   retVal;         /* Functions return value.            */
    GT_U16      data, histoData;/* Data to be set into the  register. */
#ifndef GT_RMGMT_ACCESS
    GT_U16    counter3_2;     /* Counter Register Bytes 3 & 2       */
    GT_U16    counter1_0;     /* Counter Register Bytes 1 & 0       */
#endif

    /* Get the Histogram mode bit.                */
    retVal = hwReadGlobalReg(dev,QD_REG_STATS_OPERATION,&histoData);
    if(retVal != GT_OK)
    {
        return retVal;
    }

    histoData &= 0xC00;

#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_STATS_OPERATION;
      regAccess.rw_reg_list[0].data = 15;
      retVal = hwAccessMultiRegs(dev, &regAccess);
      if(retVal != GT_OK)
      {
        return retVal;
      }
    }
#else
    data = 1;
       while(data == 1)
    {
        retVal = hwGetGlobalRegField(dev,QD_REG_STATS_OPERATION,15,1,&data);
        if(retVal != GT_OK)
           {
               return retVal;
        }
       }
#endif

    data = (GT_U16)((1 << 15) | (GT_STATS_READ_COUNTER << 12) | counter | histoData);
    retVal = hwWriteGlobalReg(dev,QD_REG_STATS_OPERATION,data);
    if(retVal != GT_OK)
    {
        return retVal;
    }

#ifdef GT_RMGMT_ACCESS
    {
      HW_DEV_REG_ACCESS regAccess;

      regAccess.entries = 3;

      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_STATS_OPERATION;
      regAccess.rw_reg_list[0].data = 15;
      regAccess.rw_reg_list[1].cmd = HW_REG_READ;
      regAccess.rw_reg_list[1].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL_REG_ACCESS);
      regAccess.rw_reg_list[1].reg = QD_REG_STATS_COUNTER3_2;
      regAccess.rw_reg_list[1].data = 0;
      regAccess.rw_reg_list[2].cmd = HW_REG_READ;
      regAccess.rw_reg_list[2].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL_REG_ACCESS);
      regAccess.rw_reg_list[2].reg = QD_REG_STATS_COUNTER1_0;
      regAccess.rw_reg_list[2].data = 0;
      retVal = hwAccessMultiRegs(dev, &regAccess);
      if(retVal != GT_OK)
      {
        return retVal;
      }
      *statsData = (regAccess.rw_reg_list[1].data << 16) | regAccess.rw_reg_list[2].data;
    }
#else
    data = 1;
       while(data == 1)
    {
        retVal = hwGetGlobalRegField(dev,QD_REG_STATS_OPERATION,15,1,&data);
        if(retVal != GT_OK)
           {
               return retVal;
        }
       }

    retVal = hwReadGlobalReg(dev,QD_REG_STATS_COUNTER3_2,&counter3_2);
    if(retVal != GT_OK)
    {
        return retVal;
    }

    retVal = hwReadGlobalReg(dev,QD_REG_STATS_COUNTER1_0,&counter1_0);
    if(retVal != GT_OK)
    {
        return retVal;
    }

    *statsData = (counter3_2 << 16) | counter1_0;
#endif

    return GT_OK;

}


/*******************************************************************************
* statsReadRealtimeCounter
*
* DESCRIPTION:
*       This function is used to read a realtime counter.
*
* INPUTS:
*       port     - port to be accessed
*       counter  - counter to be read if it's read operation
*
* OUTPUTS:
*       statsData   - points to the data storage where the MIB counter will be saved.
*
* RETURNS:
*       GT_OK on success,
*       GT_FAIL otherwise.
*
* COMMENTS:
*        If Semaphore is used, Semaphore should be acquired before this function call.
*******************************************************************************/
static GT_STATUS statsReadRealtimeCounter
(
    IN   GT_QD_DEV      *dev,
    IN   GT_U8             port,
    IN   GT_U32            counter,
    OUT  GT_U32            *statsData
)
{
    GT_STATUS   retVal;         /* Functions return value.            */
    GT_U16      data, histoData;/* Data to be set into the  register. */
    GT_U16    counter3_2;     /* Counter Register Bytes 3 & 2       */
    GT_U16    counter1_0;     /* Counter Register Bytes 1 & 0       */

    /* Get the Histogram mode bit.                */
    retVal = hwReadGlobalReg(dev,QD_REG_STATS_OPERATION,&histoData);
    if(retVal != GT_OK)
    {
        return retVal;
    }

    histoData &= 0xC00;

#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_STATS_OPERATION;
      regAccess.rw_reg_list[0].data = 15;
      retVal = hwAccessMultiRegs(dev, &regAccess);
      if(retVal != GT_OK)
      {
        return retVal;
      }
    }
#else
    data = 1;
       while(data == 1)
    {
        retVal = hwGetGlobalRegField(dev,QD_REG_STATS_OPERATION,15,1,&data);
        if(retVal != GT_OK)
           {
               return retVal;
        }
       }
#endif

    data = (GT_U16)((1 << 15) | (GT_STATS_READ_COUNTER << 12) | ((port+1) << 5) | counter | histoData);
    retVal = hwWriteGlobalReg(dev,QD_REG_STATS_OPERATION,data);
    if(retVal != GT_OK)
    {
        return retVal;
    }

#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_STATS_OPERATION;
      regAccess.rw_reg_list[0].data = 15;
      retVal = hwAccessMultiRegs(dev, &regAccess);
      if(retVal != GT_OK)
      {
        return retVal;
      }
    }
#else
    data = 1;
       while(data == 1)
    {
        retVal = hwGetGlobalRegField(dev,QD_REG_STATS_OPERATION,15,1,&data);
        if(retVal != GT_OK)
           {
               return retVal;
        }
       }
#endif

    retVal = hwReadGlobalReg(dev,QD_REG_STATS_COUNTER3_2,&counter3_2);
    if(retVal != GT_OK)
    {
        return retVal;
    }

    retVal = hwReadGlobalReg(dev,QD_REG_STATS_COUNTER1_0,&counter1_0);
    if(retVal != GT_OK)
    {
        return retVal;
    }

    *statsData = (counter3_2 << 16) | counter1_0;

    return GT_OK;

}
