#include <Copyright.h>

/*******************************************************************************
* gtPIRL.c
*
* DESCRIPTION:
*       API definitions for PIRL Resources
*
* DEPENDENCIES:
*
* FILE REVISION NUMBER:
*******************************************************************************/

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

/****************************************************************************/
/* STATS operation function declaration.                                    */
/****************************************************************************/
static GT_STATUS pirlOperationPerform
(
    IN   GT_QD_DEV            *dev,
    IN   GT_PIRL_OPERATION    pirlOp,
    INOUT GT_PIRL_OP_DATA     *opData
);

static GT_STATUS pirlInitialize
(
    IN  GT_QD_DEV              *dev
);

static GT_STATUS pirlInitIRLUnit
(
    IN  GT_QD_DEV              *dev,
    IN    GT_U32                irlUnit
);

static GT_STATUS pirlDataToResource
(
    IN  GT_QD_DEV              *dev,
    IN  GT_PIRL_DATA        *pirlData,
    OUT GT_PIRL_RESOURCE    *res
);

static GT_STATUS pirlResourceToData
(
    IN  GT_QD_DEV              *dev,
    IN  GT_PIRL_RESOURCE    *res,
    OUT GT_PIRL_DATA        *pirlData
);

static GT_STATUS pirlWriteResource
(
    IN  GT_QD_DEV              *dev,
    IN    GT_U32                irlUnit,
    IN  GT_PIRL_RESOURCE    *res
);

static GT_STATUS pirlReadResource
(
    IN  GT_QD_DEV              *dev,
    IN    GT_U32                irlUnit,
    OUT GT_PIRL_RESOURCE    *res
);

static GT_STATUS pirlSetPortVec
(
    IN  GT_QD_DEV    *dev,
    IN  GT_U32        irlUnit,
    IN  GT_U32        portVec
);

static GT_STATUS pirlGetPortVec
(
    IN  GT_QD_DEV    *dev,
    IN  GT_U32        irlUnit,
    OUT GT_U32        *portVec
);

static GT_STATUS pirlSetFcMode
(
    IN  GT_QD_DEV    *dev,
    IN  GT_LPORT    port,
    IN  GT_PIRL_FC_DEASSERT        mode
);

/*******************************************************************************
* gpirlActivate
*
* DESCRIPTION:
*       This routine activates Ingress Rate Limiting for the given ports by 
*        initializing a resource bucket, assigning ports, and configuring
*        Bucket Parameters.
*
* INPUTS:
*        irlUnit  - bucket to be used (0 ~ 11).
*       portVec  - the list of ports that share the bucket.
*        pirlData - PIRL resource parameters.
*
* OUTPUTS:
*       None.
*
* RETURNS:
*       GT_OK      - on success
*       GT_FAIL    - on error
*        GT_BAD_PARAM - if invalid parameter is given
*       GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*       None
*
*******************************************************************************/
GT_STATUS gpirlActivate
(
    IN  GT_QD_DEV     *dev,
    IN  GT_U32        irlUnit,
    IN  GT_U32        portVec,
    IN  GT_PIRL_DATA    *pirlData
)
{
    GT_STATUS           retVal;
    GT_PORT_STP_STATE    pState[MAX_SWITCH_PORTS];
    GT_LPORT            port;
    GT_PIRL_OPERATION    op;
    GT_PIRL_OP_DATA        opData;
    GT_PIRL_RESOURCE    pirlRes;

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

    /* check if the given bucket number is valid */
    if (!GT_IS_IRLUNIT_VALID(dev,irlUnit))
    {
        DBG_INFO(("GT_BAD_PARAM irlUnit\n"));
        return GT_BAD_PARAM;
    }

    /* check if the given portVec is valid */
    if ((!portVec) || (portVec >= (GT_U32)(1<<dev->numOfPorts)))
    {
        DBG_INFO(("GT_BAD_PARAM portVec\n"));
        return GT_BAD_PARAM;
    }

    /* set or reset port's ingress resource bit based on the portVec */
    retVal = pirlSetPortVec(dev, irlUnit, portVec);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Getting Port State failed\n"));
        return retVal;
    }

    /* Disable ports that share the bucket */
    for(port=0; port<dev->numOfPorts; port++)
    {
        if(!GT_IS_PORT_SET(portVec,port))
            continue;

        retVal = gstpGetPortState(dev, port, &pState[port]);
        if(retVal != GT_OK)
        {
            DBG_INFO(("Getting Port State failed\n"));
            return retVal;
        }

        retVal = gstpSetPortState(dev, port, GT_PORT_DISABLE);
        if(retVal != GT_OK)
        {
            DBG_INFO(("Getting Port State failed\n"));
            return retVal;
        }
    }

    /* Program Tuning register */
    op = PIRL_WRITE_RESOURCE;
    opData.irlUnit = irlUnit;
    opData.irlReg = 0xF;
    opData.irlData = 0x7;
    retVal = pirlOperationPerform(dev,op,&opData);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed (statsOperationPerform returned GT_FAIL).\n"));
        return retVal;
    }

    /* Program the Ingress Rate Resource Parameters */
    retVal = pirlDataToResource(dev,pirlData,&pirlRes);
    if(retVal != GT_OK)
    {
        DBG_INFO(("PIRL Data to PIRL Resource conversion failed.\n"));
        return retVal;
    }

    retVal = pirlWriteResource(dev,irlUnit,&pirlRes);
    if(retVal != GT_OK)
    {
        DBG_INFO(("PIRL Write Resource failed.\n"));
        return retVal;
    }

    /* Initialize internal counters */
    retVal = pirlInitIRLUnit(dev,irlUnit);
    if(retVal != GT_OK)
    {
        DBG_INFO(("PIRL Write Resource failed.\n"));
        return retVal;
    }

    /* Program PirlFCMode for each port that shares Bucket */
    if (pirlRes.ebsLimitAction == ESB_LIMIT_ACTION_FC)
    {
        for(port=0; port<dev->numOfPorts; port++)
        {
            if(!GT_IS_PORT_SET(portVec,port))
                continue;

            retVal = pirlSetFcMode(dev,port,pirlData->fcDeassertMode[port]);
            if(retVal != GT_OK)
            {
                DBG_INFO(("PIRL FC Mode set failed.\n"));
                return retVal;
            }
        }
    }

    /* Set the ports in their original state */
    for(port=0; port<dev->numOfPorts; port++)
    {
        if(!GT_IS_PORT_SET(portVec,port))
            continue;

        retVal = gstpSetPortState(dev, port, pState[port]);
        if(retVal != GT_OK)
        {
            DBG_INFO(("Getting Port State failed\n"));
            return retVal;
        }
    }

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

}


/*******************************************************************************
* gpirlDeactivate
*
* DESCRIPTION:
*       This routine deactivates Ingress Rate Limiting for the given bucket.
*        It simply removes every ports from the Ingress Rate Resource.
*        It is assumed that gpirlActivate has been successfully called with
*        the irlUnit before this function is called.
*
* INPUTS:
*        irlUnit  - bucket to be used (0 ~ 11).
*
* OUTPUTS:
*       None.
*
* RETURNS:
*       GT_OK      - on success
*       GT_FAIL    - on error
*        GT_BAD_PARAM - if invalid parameter is given
*       GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*       None
*
*******************************************************************************/
GT_STATUS gpirlDeactivate
(
    IN  GT_QD_DEV     *dev,
    IN  GT_U32        irlUnit
)
{
    GT_STATUS           retVal;

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

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

    /* check if the given bucket number is valid */
    if (!GT_IS_IRLUNIT_VALID(dev,irlUnit))
    {
        DBG_INFO(("GT_BAD_PARAM\n"));
        return GT_BAD_PARAM;
    }

    /* reset port's ingress resource bit */
    retVal = pirlSetPortVec(dev, irlUnit, 0);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Getting Port State failed\n"));
        return retVal;
    }

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


/*******************************************************************************
* gpirlUpdateParam
*
* DESCRIPTION:
*       This routine updates IRL Parameter.
*        It is assumed that gpirlActivate has been successfully called with
*        the given irlUnit before this function is called.
*
* INPUTS:
*        irlUnit  - bucket to be used (0 ~ 11).
*        pirlData - PIRL resource parameters.
*
* OUTPUTS:
*       None.
*
* RETURNS:
*       GT_OK      - on success
*       GT_FAIL    - on error
*        GT_BAD_PARAM - if invalid parameter is given
*       GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*       None
*
*******************************************************************************/
GT_STATUS gpirlUpdateParam
(
    IN  GT_QD_DEV     *dev,
    IN  GT_U32        irlUnit,
    IN  GT_PIRL_DATA    *pirlData
)
{
    GT_STATUS           retVal;
    GT_PORT_STP_STATE    pState[MAX_SWITCH_PORTS];
    GT_LPORT            port;
    GT_PIRL_RESOURCE    pirlRes;
    GT_U32                portVec;

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

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

    /* check if the given bucket number is valid */
    if (!GT_IS_IRLUNIT_VALID(dev,irlUnit))
    {
        DBG_INFO(("GT_BAD_PARAM\n"));
        return GT_BAD_PARAM;
    }

    /* get port list that share ingress resource */
    retVal = pirlGetPortVec(dev, irlUnit, &portVec);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Getting Port State failed\n"));
        return retVal;
    }

    /* check if the given portVec is valid */
    if (!portVec)
    {
        DBG_INFO(("IRL Unit not Activated\n"));
        return GT_FAIL;
    }

    /* Disable ports that share the bucket */
    for(port=0; port<dev->numOfPorts; port++)
    {
        if(!GT_IS_PORT_SET(portVec,port))
            continue;

        retVal = gstpGetPortState(dev, port, &pState[port]);
        if(retVal != GT_OK)
        {
            DBG_INFO(("Getting Port State failed\n"));
            return retVal;
        }

        retVal = gstpSetPortState(dev, port, GT_PORT_DISABLE);
        if(retVal != GT_OK)
        {
            DBG_INFO(("Getting Port State failed\n"));
            return retVal;
        }
    }

    /* Program the Ingress Rate Resource Parameters */
    retVal = pirlDataToResource(dev,pirlData,&pirlRes);
    if(retVal != GT_OK)
    {
        DBG_INFO(("PIRL Data to PIRL Resource conversion failed.\n"));
        return retVal;
    }

    retVal = pirlWriteResource(dev,irlUnit,&pirlRes);
    if(retVal != GT_OK)
    {
        DBG_INFO(("PIRL Write Resource failed.\n"));
        return retVal;
    }

    /* Initialize internal counrters for the bucket */
    retVal = pirlInitIRLUnit(dev,irlUnit);
    if(retVal != GT_OK)
    {
        DBG_INFO(("PIRL Write Resource failed.\n"));
        return retVal;
    }

    /* Program PirlFCMode for each port that shares Bucket */
    if (pirlRes.ebsLimitAction == ESB_LIMIT_ACTION_FC)
    {
        for(port=0; port<dev->numOfPorts; port++)
        {
            if(!GT_IS_PORT_SET(portVec,port))
                continue;

            retVal = pirlSetFcMode(dev,port,pirlData->fcDeassertMode[port]);
            if(retVal != GT_OK)
            {
                DBG_INFO(("PIRL FC Mode set failed.\n"));
                return retVal;
            }
        }
    }

    /* Set the ports in their original state */
    for(port=0; port<dev->numOfPorts; port++)
    {
        if(!GT_IS_PORT_SET(portVec,port))
            continue;

        retVal = gstpSetPortState(dev, port, pState[port]);
        if(retVal != GT_OK)
        {
            DBG_INFO(("Getting Port State failed\n"));
            return retVal;
        }
    }

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

}


/*******************************************************************************
* gpirlReadParam
*
* DESCRIPTION:
*       This routine retrieves IRL Parameter.
*        It is assumed that gpirlActivate has been successfully called with
*        the given irlUnit before this function is called.
*
* INPUTS:
*        irlUnit  - bucket to be used (0 ~ 11).
*
* OUTPUTS:
*        pirlData - PIRL resource parameters.
*
* RETURNS:
*       GT_OK      - on success
*       GT_FAIL    - on error
*        GT_BAD_PARAM - if invalid parameter is given
*       GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*       None
*
*******************************************************************************/
GT_STATUS gpirlReadParam
(
    IN  GT_QD_DEV     *dev,
    IN  GT_U32        irlUnit,
    OUT GT_PIRL_DATA    *pirlData
)
{
    GT_STATUS           retVal;
    GT_LPORT            port;
    GT_PIRL_RESOURCE    pirlRes;
    GT_U32                portVec;

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

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

    /* check if the given bucket number is valid */
    if (!GT_IS_IRLUNIT_VALID(dev,irlUnit))
    {
        DBG_INFO(("GT_BAD_PARAM\n"));
        return GT_BAD_PARAM;
    }

    /* get port list that share ingress resource */
    retVal = pirlGetPortVec(dev, irlUnit, &portVec);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Getting Port State failed\n"));
        return retVal;
    }

    /* check if the given portVec is valid */
    if (!portVec)
    {
        DBG_INFO(("IRL Unit not Activated\n"));
        return GT_FAIL;
    }

    /* Read the Ingress Rate Resource Parameters */
    retVal = pirlReadResource(dev,irlUnit,&pirlRes);
    if(retVal != GT_OK)
    {
        DBG_INFO(("PIRL Read Resource failed.\n"));
        return retVal;
    }

    retVal = pirlResourceToData(dev,&pirlRes,pirlData);
    if(retVal != GT_OK)
    {
        DBG_INFO(("PIRL Resource to PIRL Data conversion failed.\n"));
        return retVal;
    }

    /* Program PirlFCMode for each port that shares Bucket */
    if (pirlRes.ebsLimitAction == ESB_LIMIT_ACTION_FC)
    {
        for(port=0; port<dev->numOfPorts; port++)
        {
            if(!GT_IS_PORT_SET(portVec,port))
                continue;
        
            retVal = grcGetPirlFcMode(dev,port,&pirlData->fcDeassertMode[port]);
            if(retVal != GT_OK)
            {
                DBG_INFO(("PIRL FC Mode get failed.\n"));
                return retVal;
            }
        }
    }

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

}



/*******************************************************************************
* gpirlUpdatePortVec
*
* DESCRIPTION:
*       This routine updates port list that share the bucket.
*        It is assumed that gpirlActivate has been successfully called with
*        the given irlUnit before this function is called.
*
* INPUTS:
*        irlUnit  - bucket to be used (0 ~ 11).
*       portVec  - the list of ports that share the bucket.
*
* OUTPUTS:
*       None.
*
* RETURNS:
*       GT_OK      - on success
*       GT_FAIL    - on error
*        GT_BAD_PARAM - if invalid parameter is given
*       GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*       None
*
*******************************************************************************/
GT_STATUS gpirlUpdatePortVec
(
    IN  GT_QD_DEV     *dev,
    IN  GT_U32        irlUnit,
    IN  GT_U32        portVec
)
{
    GT_STATUS       retVal;
    GT_U32            tmpVec;

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

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

    /* check if the given bucket number is valid */
    if (!GT_IS_IRLUNIT_VALID(dev,irlUnit))
    {
        DBG_INFO(("GT_BAD_PARAM\n"));
        return GT_BAD_PARAM;
    }

    /* check if the given portVec is valid */
    if ((!portVec) || (portVec > (GT_U32)(1<<dev->numOfPorts)))
    {
        DBG_INFO(("GT_BAD_PARAM\n"));
        return GT_BAD_PARAM;
    }

    /* get port list that share ingress resource */
    retVal = pirlGetPortVec(dev, irlUnit, &tmpVec);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Getting Port State failed\n"));
        return retVal;
    }

    /* check if the given portVec is valid */
    if (!tmpVec)
    {
        DBG_INFO(("IRL Unit not Activated\n"));
        return GT_FAIL;
    }

    /* set or reset port's ingress resource bit based on the portVec */
    retVal = pirlSetPortVec(dev, irlUnit, portVec);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Getting Port State failed\n"));
        return retVal;
    }

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

}


/*******************************************************************************
* gpirlReadPortVec
*
* DESCRIPTION:
*       This routine retrieves port list that share the bucket.
*        It is assumed that gpirlActivate has been successfully called with
*        the given irlUnit before this function is called.
*
* INPUTS:
*        irlUnit  - bucket to be used (0 ~ 11).
*
* OUTPUTS:
*       portVec  - the list of ports that share the bucket.
*
* RETURNS:
*       GT_OK      - on success
*       GT_FAIL    - on error
*        GT_BAD_PARAM - if invalid parameter is given
*       GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*       None
*
*******************************************************************************/
GT_STATUS gpirlReadPortVec
(
    IN  GT_QD_DEV     *dev,
    IN  GT_U32        irlUnit,
    OUT GT_U32        *portVec
)
{
    GT_STATUS       retVal;

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

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

    /* check if the given bucket number is valid */
    if (!GT_IS_IRLUNIT_VALID(dev,irlUnit))
    {
        DBG_INFO(("GT_BAD_PARAM\n"));
        return GT_BAD_PARAM;
    }

    /* get port list that share ingress resource */
    retVal = pirlGetPortVec(dev, irlUnit, portVec);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Getting Port State failed\n"));
        return retVal;
    }

    /* check if the given portVec is valid */
    if (!*portVec)
    {
        DBG_INFO(("IRL Unit not Activated\n"));
        return GT_FAIL;
    }

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

}



/*******************************************************************************
* grcGetPirlFcMode
*
* DESCRIPTION:
*       This routine gets Port Ingress Rate Limit Flow Control mode.
*        When EBSLimitAction is programmed to generate a flow control message, 
*        the deassertion of flow control is controlled by this mode.
*            GT_PIRL_FC_DEASSERT_EMPTY:
*                De-assert when the ingress rate resource has become empty
*            GT_PIRL_FC_DEASSERT_CBS_LIMIT
*                De-assert when the ingress rate resource has enough room as
*                specified by the CBSLimit.
*        Please refer to GT_PIRL_RESOURCE structure for EBSLimitAction and
*        CBSLimit.
*
* INPUTS:
*       port - logical port number
*
* OUTPUTS:
*        mode - GT_PIRL_FC_DEASSERT enum type
*
* RETURNS:
*       GT_OK               - on success
*       GT_FAIL             - on error
*        GT_NOT_SUPPORTED    - if current device does not support this feature.
*
* COMMENTS: 
*
*******************************************************************************/
GT_STATUS grcGetPirlFcMode
(
    IN  GT_QD_DEV    *dev,
    IN  GT_LPORT    port,
    OUT GT_PIRL_FC_DEASSERT        *mode
)
{
    GT_U16          data;           
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U8           hwPort;        /* Physical port.               */

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

    hwPort = GT_LPORT_2_PORT(port);

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

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

    *mode = (GT_PIRL_FC_DEASSERT)data;
    DBG_INFO(("OK.\n"));

    return GT_OK;
}

/*******************************************************************************
* gpirlGetIngressRateResource
*
* DESCRIPTION:
*       This routine gets Ingress Rate Limiting Resources assigned to the port.
*        This vector is used to attach specific counter resources to the physical
*        port. And the same counter resource can be attached to more than one port.
*
* INPUTS:
*       port   - logical port number
*
* OUTPUTS:
*        resVec - resource vector (bit 11:0, since there is 12 resources)
*
* RETURNS:
*       GT_OK               - on success
*       GT_FAIL             - on error
*        GT_NOT_SUPPORTED    - if current device does not support this feature.
*
* COMMENTS: 
*
*******************************************************************************/
GT_STATUS gpirlGetIngressRateResource
(
    IN  GT_QD_DEV    *dev,
    IN  GT_LPORT    port,
    OUT GT_U32        *resVec
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U8           hwPort;        /* Physical port.               */
    GT_U16            data;

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

    hwPort = GT_LPORT_2_PORT(port);

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

    /* Get the resource vector.            */
    retVal = hwGetPortRegField(dev,hwPort, QD_REG_INGRESS_RATE_CTRL,0,12,&data);
    if(retVal != GT_OK)
       {
        DBG_INFO(("Failed.\n"));
           return retVal;
    }

    *resVec = (GT_U32)data;

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

    return GT_OK;
}

/*******************************************************************************
* gpirlSetCurTimeUpInt
*
* DESCRIPTION:
*       This function sets the current time update interval.
*        Please contact FAE for detailed information.
*
* INPUTS:
*       upInt - updata interval (0 ~ 7)
*
* OUTPUTS:
*       None.
*
* RETURNS:
*       GT_OK      - on success
*       GT_FAIL    - on error
*        GT_BAD_PARAM - if invalid parameter is given
*       GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*
*******************************************************************************/
GT_STATUS gpirlSetCurTimeUpInt
(
    IN  GT_QD_DEV              *dev,
    IN    GT_U32                upInt
)
{
    GT_STATUS       retVal;        /* Functions return value */
    GT_PIRL_OPERATION    op;
    GT_PIRL_OP_DATA        opData;

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

    if (upInt > 0x7)
        return GT_BAD_PARAM;

    op = PIRL_READ_RESOURCE;

    opData.irlUnit = 0xF;
    opData.irlReg = 1;
    opData.irlData = 0;

    retVal = pirlOperationPerform(dev, op, &opData);
    if (retVal != GT_OK)
    {
           DBG_INFO(("PIRL OP Failed.\n"));
           return retVal;
    }

    op = PIRL_WRITE_RESOURCE;
    opData.irlData = (opData.irlData & 0xFFF8) | (GT_U16)upInt;

    retVal = pirlOperationPerform(dev, op, &opData);
    if (retVal != GT_OK)
    {
           DBG_INFO(("PIRL OP Failed.\n"));
           return retVal;
    }

    return GT_OK;    
}

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

/*******************************************************************************
* gpirlInitialize
*
* DESCRIPTION:
*       This routine initializes PIRL Resources.
*
* INPUTS:
*       None
*
* OUTPUTS:
*       None
*
* RETURNS:
*       None
*
* COMMENTS:
*       None
*
*******************************************************************************/
GT_STATUS gpirlInitialize
(
    IN  GT_QD_DEV              *dev
)
{
    GT_STATUS           retVal;
    GT_LPORT        port;
    GT_U8           hwPort;        /* Physical port.               */

    /* reset port's ingress resource bit */
    for(port=0; port<dev->numOfPorts; port++)
    {
        hwPort = GT_LPORT_2_PORT(port);

        /* Set the resource vector.            */
        retVal = hwSetPortRegField(dev,hwPort, QD_REG_INGRESS_RATE_CTRL,0,12,0);
        if(retVal != GT_OK)
           {
            DBG_INFO(("Failed.\n"));
               return retVal;
        }
    }

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

    return GT_OK;
}


/*******************************************************************************
* statsOperationPerform
*
* DESCRIPTION:
*       This function accesses Ingress Rate Command Register and Data Register.
*
* INPUTS:
*       pirlOp       - 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:
*       pirlData   - points to the data storage where the MIB counter will be saved.
*
* RETURNS:
*       GT_OK on success,
*       GT_FAIL otherwise.
*
* COMMENTS:
*
*******************************************************************************/
static GT_STATUS pirlOperationPerform
(
    IN    GT_QD_DEV           *dev,
    IN    GT_PIRL_OPERATION   pirlOp,
    INOUT GT_PIRL_OP_DATA     *opData
)
{
    GT_STATUS       retVal;    /* Functions return value */
    GT_U16          data;     /* temporary Data storage */

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

    /* Wait until the pirl 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, GLOBAL2_REG_ACCESS);
      regAccess.rw_reg_list[0].reg = QD_REG_INGRESS_RATE_COMMAND;
      regAccess.rw_reg_list[0].data = 15;
      retVal = hwAccessMultiRegs(dev, &regAccess);
      if(retVal != GT_OK)
      {
        gtSemGive(dev,dev->pirlRegsSem);
        return retVal;
      }
    }
#else
    data = 1;
    while(data == 1)
    {
        retVal = hwGetGlobal2RegField(dev,QD_REG_INGRESS_RATE_COMMAND,15,1,&data);
        if(retVal != GT_OK)
        {
            gtSemGive(dev,dev->pirlRegsSem);
            return retVal;
        }
    }
#endif

    /* Set the PIRL Operation register */
    switch (pirlOp)
    {
        case PIRL_INIT_ALL_RESOURCE:
            data = (1 << 15) | (PIRL_INIT_ALL_RESOURCE << 12);
            retVal = hwWriteGlobal2Reg(dev,QD_REG_INGRESS_RATE_COMMAND,data);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->pirlRegsSem);
                return retVal;
            }
            break;
        case PIRL_INIT_RESOURCE:
            data = (GT_U16)((1 << 15) | (PIRL_INIT_RESOURCE << 12) | 
                    ((opData->irlUnit&0xF)<< 4));
            retVal = hwWriteGlobal2Reg(dev,QD_REG_INGRESS_RATE_COMMAND,data);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->pirlRegsSem);
                return retVal;
            }
            break;

        case PIRL_WRITE_RESOURCE:
            data = (GT_U16)opData->irlData;
            retVal = hwWriteGlobal2Reg(dev,QD_REG_INGRESS_RATE_DATA,data);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->pirlRegsSem);
                return retVal;
            }

            data = (GT_U16)((1 << 15) | (PIRL_WRITE_RESOURCE << 12) | 
                    ((opData->irlUnit&0xF) << 4) | (opData->irlReg & 0xF));
            retVal = hwWriteGlobal2Reg(dev,QD_REG_INGRESS_RATE_COMMAND,data);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->pirlRegsSem);
                return retVal;
            }
            break;

        case PIRL_READ_RESOURCE:
            data = (GT_U16)((1 << 15) | (PIRL_READ_RESOURCE << 12) | 
                    ((opData->irlUnit&0xF) << 4) | (opData->irlReg & 0xF));
            retVal = hwWriteGlobal2Reg(dev,QD_REG_INGRESS_RATE_COMMAND,data);
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->pirlRegsSem);
                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, GLOBAL2_REG_ACCESS);
              regAccess.rw_reg_list[0].reg = QD_REG_INGRESS_RATE_COMMAND;
              regAccess.rw_reg_list[0].data = 15;
              retVal = hwAccessMultiRegs(dev, &regAccess);
              if(retVal != GT_OK)
              {
                gtSemGive(dev,dev->pirlRegsSem);
                return retVal;
              }
            }
#else
            data = 1;
            while(data == 1)
            {
                retVal = hwGetGlobal2RegField(dev,QD_REG_INGRESS_RATE_COMMAND,15,1,&data);
                if(retVal != GT_OK)
                {
                    gtSemGive(dev,dev->pirlRegsSem);
                    return retVal;
                }
            }
#endif

            retVal = hwReadGlobal2Reg(dev,QD_REG_INGRESS_RATE_DATA,&data);
            opData->irlData = (GT_U32)data;
            if(retVal != GT_OK)
            {
                gtSemGive(dev,dev->pirlRegsSem);
                return retVal;
            }
            gtSemGive(dev,dev->pirlRegsSem);
            return retVal;

        default:
            
            gtSemGive(dev,dev->pirlRegsSem);
            return GT_FAIL;
    }

    /* Wait until the pirl 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, GLOBAL2_REG_ACCESS);
      regAccess.rw_reg_list[0].reg = QD_REG_INGRESS_RATE_COMMAND;
      regAccess.rw_reg_list[0].data = 15;
      retVal = hwAccessMultiRegs(dev, &regAccess);
      if(retVal != GT_OK)
      {
        gtSemGive(dev,dev->pirlRegsSem);
        return retVal;
      }
    }
#else
    data = 1;
    while(data == 1)
    {
        retVal = hwGetGlobal2RegField(dev,QD_REG_INGRESS_RATE_COMMAND,15,1,&data);
        if(retVal != GT_OK)
        {
            gtSemGive(dev,dev->pirlRegsSem);
            return retVal;
        }
    }
#endif

    gtSemGive(dev,dev->pirlRegsSem);
    return retVal;
}

/*
 * Initialize all PIRL resources to the inital state.
*/
static GT_STATUS pirlInitialize
(
    IN  GT_QD_DEV              *dev
)
{
    GT_STATUS       retVal;    /* Functions return value */
    GT_PIRL_OPERATION    op;

    op = PIRL_INIT_ALL_RESOURCE;

    retVal = pirlOperationPerform(dev, op, NULL);
    if (retVal != GT_OK)
    {
           DBG_INFO(("PIRL OP Failed.\n"));
           return retVal;
    }

    retVal = gpirlSetCurTimeUpInt(dev,7);
    if (retVal != GT_OK)
    {
           DBG_INFO(("PIRL OP Failed.\n"));
    }

    return retVal;
}

/*
 * Initialize the selected PIRL resource to the inital state.
 * This function initializes only the BSM structure for the IRL Unit.
*/
static GT_STATUS pirlInitIRLUnit
(
    IN  GT_QD_DEV              *dev,
    IN    GT_U32                irlUnit
)
{
    GT_STATUS       retVal;    /* Functions return value */
    GT_PIRL_OPERATION    op;
    GT_PIRL_OP_DATA        opData;

    op = PIRL_INIT_RESOURCE;
    opData.irlUnit = irlUnit;

    retVal = pirlOperationPerform(dev, op, &opData);
    if (retVal != GT_OK)
    {
           DBG_INFO(("PIRL OP Failed.\n"));
           return retVal;
    }

    return retVal;
}

/*
 * convert PIRL Data structure to PIRL Resource structure.
 * if PIRL Data is not valid, return GT_BAD_PARARM;
*/
static GT_STATUS pirlDataToResource
(
    IN  GT_QD_DEV              *dev,
    IN  GT_PIRL_DATA        *pirlData,
    OUT GT_PIRL_RESOURCE    *res
)
{
    GT_U16 typeMask;
 
    switch(pirlData->accountQConf)
    {
        case GT_FALSE:
        case GT_TRUE:
            res->accountQConf = pirlData->accountQConf;
            break;
        default:
            return GT_BAD_PARAM;
    }

    switch(pirlData->accountFiltered)
    {
        case GT_FALSE:
        case GT_TRUE:
            res->accountFiltered = pirlData->accountFiltered;
            break;
        default:
            return GT_BAD_PARAM;
    }

    switch(pirlData->ebsLimitAction)
    {
        case ESB_LIMIT_ACTION_DROP:
        case ESB_LIMIT_ACTION_FC:
            res->ebsLimitAction = pirlData->ebsLimitAction;
            break;
        default:
            return GT_BAD_PARAM;
    }

    if(pirlData->customSetup.isValid == GT_TRUE)
    {
        res->ebsLimit = pirlData->customSetup.ebsLimit;
        res->cbsLimit = pirlData->customSetup.cbsLimit;
        res->bktIncrement = pirlData->customSetup.bktIncrement;
        res->bktRateFactor = pirlData->customSetup.bktRateFactor;
    }
    else
    {
        if(pirlData->ingressRate == 0)
            return GT_BAD_PARAM;

        if(pirlData->ingressRate < 1000)    /* less than 1Mbps */
        {
            /* it should be divided by 64 */
            if(pirlData->ingressRate % 64)
                return GT_BAD_PARAM;
            res->bktRateFactor = pirlData->ingressRate/64;
        }
        else if(pirlData->ingressRate <= 100000)    /* less than or equal to 100Mbps */
        {
            /* it should be divided by 1000 */
            if(pirlData->ingressRate % 1000)
                return GT_BAD_PARAM;
            res->bktRateFactor = pirlData->ingressRate/64 + ((pirlData->ingressRate % 64)?1:0);
        }
        else if(pirlData->ingressRate <= 200000)    /* less than or equal to 200Mbps */
        {
            /* it should be divided by 10000 */
            if(pirlData->ingressRate % 10000)
                return GT_BAD_PARAM;
            res->bktRateFactor = pirlData->ingressRate/64 + ((pirlData->ingressRate % 64)?1:0);
        }
        else
            return GT_BAD_PARAM;

        res->ebsLimit = RECOMMENDED_ESB_LIMIT(dev, pirlData->ingressRate);
        res->cbsLimit = RECOMMENDED_CBS_LIMIT(dev, pirlData->ingressRate);
        res->bktIncrement = RECOMMENDED_BUCKET_INCREMENT(dev, pirlData->ingressRate);
    }

    switch(pirlData->bktRateType)
    {
        case BUCKET_TYPE_TRAFFIC_BASED:
            res->bktRateType = pirlData->bktRateType;

            if (IS_IN_DEV_GROUP(dev,DEV_RESTRICTED_PIRL_RESOURCE))
            {
                typeMask = 0xF;
            }
            else
            {
                typeMask = 0x7F;
            }

            if (pirlData->bktTypeMask > typeMask)
            {
                return GT_BAD_PARAM;
            }
            else
            {
                res->bktTypeMask = pirlData->bktTypeMask;
            }

            break;

        case BUCKET_TYPE_RATE_BASED:
            if (IS_IN_DEV_GROUP(dev,DEV_RESTRICTED_PIRL_RESOURCE))
                return GT_BAD_PARAM;
            res->bktRateType = pirlData->bktRateType;
            res->bktTypeMask = 0;
            break;

        default:
            return GT_BAD_PARAM;
    }

    switch(pirlData->byteTobeCounted)
    {
        case GT_PIRL_COUNT_ALL_LAYER1:
            res->byteTobeCounted = 1;
            break;
        case GT_PIRL_COUNT_ALL_LAYER2:
            res->byteTobeCounted = 2;
            break;
        case GT_PIRL_COUNT_ALL_LAYER3:
            res->byteTobeCounted = 6;
            break;
        default:
            return GT_BAD_PARAM;
    }

    return GT_OK;            
}

/*
 * convert PIRL Resource structure to PIRL Data structure.
*/
static GT_STATUS pirlResourceToData
(
    IN  GT_QD_DEV              *dev,
    IN  GT_PIRL_RESOURCE    *res,
    OUT GT_PIRL_DATA        *pirlData
)
{
    GT_U32    rate;
    GT_U32    factor;

    pirlData->accountQConf = res->accountQConf;
    pirlData->accountFiltered = res->accountFiltered;
    pirlData->ebsLimitAction = res->ebsLimitAction;

    pirlData->customSetup.isValid = GT_FALSE;

    FACTOR_FROM_BUCKET_INCREMENT(dev,res->bktIncrement,factor);

    rate = res->bktRateFactor * factor;
    if(rate == 0)
    {
        pirlData->ingressRate = 0;
        pirlData->customSetup.isValid = GT_TRUE;
        pirlData->customSetup.ebsLimit = res->ebsLimit;
        pirlData->customSetup.cbsLimit = res->cbsLimit;
        pirlData->customSetup.bktIncrement = res->bktIncrement;
        pirlData->customSetup.bktRateFactor = res->bktRateFactor;
    }
    else if(rate < 1000)
    {
        pirlData->ingressRate = rate;
    }
    else if(rate < 100000)
    {
        pirlData->ingressRate = rate - (rate % 1000);
    }
    else
    {
        pirlData->ingressRate = rate - (rate % 10000);
    }

    pirlData->bktRateType = res->bktRateType;
    pirlData->bktTypeMask = res->bktTypeMask;

    switch(res->byteTobeCounted)
    {
        case 1:
            pirlData->byteTobeCounted = GT_PIRL_COUNT_ALL_LAYER1;
            break;
        case 2:
            pirlData->byteTobeCounted = GT_PIRL_COUNT_ALL_LAYER2;
            break;
        case 6:
            pirlData->byteTobeCounted = GT_PIRL_COUNT_ALL_LAYER3;
            break;
        default:
            return GT_BAD_PARAM;
    }

    return GT_OK;            
}

/*******************************************************************************
* pirlWriteResource
*
* DESCRIPTION:
*       This function writes IRL Resource to BCM (Bucket Configuration Memory)
*
* INPUTS:
*        irlUnit - resource unit to be accessed
*       res     - IRL Resource data
*
* OUTPUTS:
*       Nont.
*
* RETURNS:
*       GT_OK on success,
*       GT_FAIL otherwise.
*
* COMMENTS:
*
*******************************************************************************/
static GT_STATUS pirlWriteResource
(
    IN  GT_QD_DEV              *dev,
    IN    GT_U32                irlUnit,
    IN  GT_PIRL_RESOURCE    *res
)
{
    GT_STATUS       retVal;            /* Functions return value */
    GT_U16          data[8];     /* temporary Data storage */
    GT_PIRL_OPERATION    op;
    GT_PIRL_OP_DATA        opData;
    int                i;

    op = PIRL_WRITE_RESOURCE;

    /* reg0 data */
    data[0] = (GT_U16)((res->bktRateType << 15) |    /* Bit[15] : Bucket Rate Type */
                      (res->bktTypeMask << 4 ) |        /* Bit[14:4] : Traffic Type   */
                      res->byteTobeCounted );            /* Bit[3:0] : Bytes to be counted */

    /* reg1 data */
    data[1] = (GT_U16)res->bktIncrement;    /* Bit[11:0] : Bucket Increment */

    /* reg2 data */
    data[2] = (GT_U16)res->bktRateFactor;    /* Bit[15:0] : Bucket Rate Factor */

    /* reg3 data */
    data[3] = (GT_U16)(res->cbsLimit & 0xFFF) << 4;    /* Bit[15:4] : CBS Limit[11:0] */

    /* reg4 data */
    data[4] = (GT_U16)(res->cbsLimit >> 12);        /* Bit[11:0] : CBS Limit[23:12] */

    /* reg5 data */
    data[5] = (GT_U16)(res->ebsLimit & 0xFFFF);        /* Bit[15:0] : EBS Limit[15:0] */

    /* reg6 data */
    data[6] = (GT_U16)((res->ebsLimit >> 16)    |    /* Bit[7:0] : EBS Limit[23:16] */
                    (res->ebsLimitAction << 12)    |    /* Bit[12] : EBS Limit Action */
                    (res->accountFiltered << 14)|    /* Bit[14] : Account Filtered */
                    (res->accountQConf << 15));        /* Bit[15] : Account QConf */
    /* reg7 data */
    data[7] = 0;    /* Reserved */

    for(i=0; i<8; i++)
    {
        opData.irlUnit = irlUnit;
        opData.irlReg = i;
        opData.irlData = data[i];

        retVal = pirlOperationPerform(dev, op, &opData);
        if (retVal != GT_OK)
        {
            DBG_INFO(("PIRL OP Failed.\n"));
            return retVal;
        }
    }

    return GT_OK;    
}


/*******************************************************************************
* pirlReadResource
*
* DESCRIPTION:
*       This function reads IRL Resource from BCM (Bucket Configuration Memory)
*
* INPUTS:
*        irlUnit - resource unit to be accessed
*
* OUTPUTS:
*       res - IRL Resource data
*
* RETURNS:
*       GT_OK on success,
*       GT_FAIL otherwise.
*
* COMMENTS:
*
*******************************************************************************/
static GT_STATUS pirlReadResource
(
    IN  GT_QD_DEV              *dev,
    IN    GT_U32                irlUnit,
    OUT GT_PIRL_RESOURCE    *res
)
{
    GT_STATUS       retVal;            /* Functions return value */
    GT_U16          data[8];     /* temporary Data storage */
    GT_PIRL_OPERATION    op;
    GT_PIRL_OP_DATA        opData;
    int                i;

    op = PIRL_READ_RESOURCE;

    for(i=0; i<8; i++)
    {
        opData.irlUnit = irlUnit;
        opData.irlReg = i;
        opData.irlData = 0;

        retVal = pirlOperationPerform(dev, op, &opData);
        if (retVal != GT_OK)
        {
            DBG_INFO(("PIRL OP Failed.\n"));
            return retVal;
        }

        data[i] = (GT_U16)opData.irlData;
    }
    

    /* reg0 data */
    res->bktRateType = (data[0] >> 15) & 0x1;
    res->bktTypeMask = (data[0] >> 4) & 0x7F;

    res->byteTobeCounted = data[0] & 0xF;

    /* reg1 data */
    res->bktIncrement = data[1] & 0xFFF;

    /* reg2 data */
    res->bktRateFactor = data[2] & 0xFFFF;

    /* reg3,4 data */
    res->cbsLimit = ((data[3] >> 4) & 0xFFF) | ((data[4] & 0xFFF) << 12);

    /* reg5,6 data */
    res->ebsLimit = data[5] | ((data[6] & 0xFF) << 16);
                                                       
    /* reg6 data */
    res->ebsLimitAction = (data[6] >> 12) & 0x1;
    res->accountFiltered = (data[6] >> 14) & 0x1;
    res->accountQConf = (data[6] >> 15) & 0x1;

    return GT_OK;
}

/*******************************************************************************
* pirlSetPortVec
*
* DESCRIPTION:
*       This routine sets port list that share the bucket and resets ports that
*        do not share the bucket.
*
* INPUTS:
*        irlUnit  - bucket to be used.
*       portVec  - the list of ports that share the bucket.
*
* OUTPUTS:
*       None.
*
* RETURNS:
*       GT_OK               - on success
*       GT_FAIL             - on error
*
* COMMENTS: 
*
*******************************************************************************/
static GT_STATUS pirlSetPortVec
(
    IN  GT_QD_DEV    *dev,
    IN  GT_U32        irlUnit,
    IN  GT_U32        portVec
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_LPORT        port;
    GT_U8           hwPort;        /* Physical port.               */
    GT_U16            data;

    for(port=0; port<dev->numOfPorts; port++)
    {
        if(GT_IS_PORT_SET(portVec,port))
            data = 1;
        else
            data = 0;

        hwPort = GT_LPORT_2_PORT(port);

        /* Set the resource vector.            */
        retVal = hwSetPortRegField(dev,hwPort, QD_REG_INGRESS_RATE_CTRL,(GT_U8)irlUnit,1,data);
        if(retVal != GT_OK)
           {
            DBG_INFO(("Failed.\n"));
               return retVal;
        }
    }

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

    return GT_OK;
}


/*******************************************************************************
* pirlGetPortVec
*
* DESCRIPTION:
*       This routine gets port list that share the bucket.
*
* INPUTS:
*        irlUnit  - bucket to be used.
*
* OUTPUTS:
*       portVec  - the list of ports that share the bucket.
*
* RETURNS:
*       GT_OK               - on success
*       GT_FAIL             - on error
*
* COMMENTS: 
*
*******************************************************************************/
static GT_STATUS pirlGetPortVec
(
    IN  GT_QD_DEV    *dev,
    IN  GT_U32        irlUnit,
    OUT GT_U32        *portVec
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_LPORT        port;
    GT_U8           hwPort;        /* Physical port.               */
    GT_U16            data;

    *portVec = 0;

    for(port=0; port<dev->numOfPorts; port++)
    {
        hwPort = GT_LPORT_2_PORT(port);

        /* Set the resource vector.            */
        retVal = hwGetPortRegField(dev,hwPort, QD_REG_INGRESS_RATE_CTRL,(GT_U8)irlUnit,1,&data);
        if(retVal != GT_OK)
           {
            DBG_INFO(("Failed.\n"));
               return retVal;
        }

        if(data == 1)
            *portVec |= (1 << port);
    }

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

    return GT_OK;
}


/*******************************************************************************
* pirlSetFcMode
*
* DESCRIPTION:
*       This routine gets Port Ingress Rate Limit Flow Control mode.
*        When EBSLimitAction is programmed to generate a flow control message, 
*        the deassertion of flow control is controlled by this mode.
*            GT_PIRL_FC_DEASSERT_EMPTY:
*                De-assert when the ingress rate resource has become empty
*            GT_PIRL_FC_DEASSERT_CBS_LIMIT
*                De-assert when the ingress rate resource has enough room as
*                specified by the CBSLimit.
*        Please refer to GT_PIRL_RESOURCE structure for EBSLimitAction and
*        CBSLimit.
*
* INPUTS:
*       port - logical port number
*        mode - GT_PIRL_FC_DEASSERT enum type
*
* OUTPUTS:
*        None.
*
* RETURNS:
*       GT_OK               - on success
*       GT_FAIL             - on error
*        GT_NOT_SUPPORTED    - if current device does not support this feature.
*
* COMMENTS: 
*
*******************************************************************************/
static GT_STATUS pirlSetFcMode
(
    IN  GT_QD_DEV    *dev,
    IN  GT_LPORT    port,
    IN  GT_PIRL_FC_DEASSERT        mode
)
{
    GT_U16          data;           
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U8           hwPort;        /* Physical port.               */

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

    hwPort = GT_LPORT_2_PORT(port);

    data = (GT_U16) mode;

    /* Set the PirlFcMode.            */
    retVal = hwSetPortRegField(dev,hwPort, QD_REG_INGRESS_RATE_CTRL,12,1,data);
    if(retVal != GT_OK)
       {
        DBG_INFO(("Failed.\n"));
           return retVal;
    }

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

    return GT_OK;
}

#define PIRL_DEBUG
#ifdef PIRL_DEBUG
/*******************************************************************************
* pirlDumpResource
*
* DESCRIPTION:
*       This function dumps IRL Resource register values.
*
* INPUTS:
*        irlUnit  - resource unit to be accessed
*        dataLen  - data size.
*
* OUTPUTS:
*       data - IRL Resource data
*
* RETURNS:
*       GT_OK on success,
*       GT_FAIL otherwise.
*
* COMMENTS:
*
*******************************************************************************/
GT_STATUS pirlDumpResource
(
    IN  GT_QD_DEV              *dev,
    IN    GT_U32                irlUnit,
    IN    GT_U32                dataLen,
    OUT GT_U16                *data
)
{
    GT_STATUS       retVal;        /* Functions return value */
    GT_PIRL_OPERATION    op;
    GT_PIRL_OP_DATA        opData;
    GT_U32                i;

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

    op = PIRL_READ_RESOURCE;

    for(i=0; i<dataLen; i++)
    {
        opData.irlUnit = irlUnit;
        opData.irlReg = i;
        opData.irlData = 0;

        retVal = pirlOperationPerform(dev, op, &opData);
        if (retVal != GT_OK)
        {
            DBG_INFO(("PIRL OP Failed.\n"));
            return retVal;
        }

        data[i] = (GT_U16)opData.irlData;
    }

    return GT_OK;    
}
#endif /* PIRL_DEBUG */
