#include <Copyright.h>

/********************************************************************************
* gtEvents.c
*
* DESCRIPTION:
*       API definitions for system interrupt events handling.
*
* DEPENDENCIES:
*
* FILE REVISION NUMBER:
*       $Revision: 3 $
*******************************************************************************/

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

/*******************************************************************************
* eventSetActive
*
* DESCRIPTION:
*       This routine enables/disables the receive of an hardware driven event.
*
* INPUTS:
*       eventType - the event type. any combination of the folowing:
*           GT_STATS_DONE, GT_VTU_PROB, GT_VTU_DONE, GT_ATU_FULL(or GT_ATU_PROB),
*           GT_ATU_DONE, GT_PHY_INTERRUPT, GT_EE_INTERRUPT, GT_DEVICE_INT,
*            and GT_AVB_INTERRUPT
*
* OUTPUTS:
*       None.
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*
* COMMENTS:
*       Each switch device has its own set of event Types. Please refer to the
*        device datasheet for the list of event types that the device supports.
*
*******************************************************************************/
GT_STATUS eventSetActive
(
    IN GT_QD_DEV *dev,
    IN GT_U32      eventType
)
{
    GT_STATUS   retVal;
    GT_U16     data;
    GT_U16    intMask;
    GT_U8     len;

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

    data = (GT_U16) eventType;
    len = 9;

    if ((IS_IN_DEV_GROUP(dev,DEV_EXTERNAL_PHY_ONLY)) ||
        (IS_IN_DEV_GROUP(dev,DEV_DEV_PHY_INTERRUPT)))
    {
        intMask = GT_NO_INTERNAL_PHY_INT_MASK;
    }
    else
    {
        intMask = GT_INT_MASK;
    }

    if (!IS_IN_DEV_GROUP(dev,DEV_AVB_INTERRUPT))
    {
        intMask &= ~GT_AVB_INT;
        len = 8;
    }

    if (!IS_IN_DEV_GROUP(dev,DEV_DEVICE_INTERRUPT))
    {
        intMask &= ~GT_DEVICE_INT;
        len = 7;
    }


    if(data & ~intMask)
    {
        DBG_INFO(("Invalid event type.\n"));
        return GT_FAIL;
    }

    /* Set the IntEn bit.               */
    retVal = hwSetGlobalRegField(dev,QD_REG_GLOBAL_CONTROL,0,len,data);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }
    DBG_INFO(("OK.\n"));
    return GT_OK;
}

/*******************************************************************************
* eventgetActive
*
* DESCRIPTION:
*       This routine gets the enable/disable status of the receive of an hardware driven event.
*
* OUTPUTS:
*       eventType - the event type. any combination of the folowing:
*           GT_STATS_DONE, GT_VTU_PROB, GT_VTU_DONE, GT_ATU_FULL(or GT_ATU_PROB),
*           GT_ATU_DONE, GT_PHY_INTERRUPT, GT_EE_INTERRUPT, GT_DEVICE_INT,
*            and GT_AVB_INTERRUPT
*
* INPUTS:
*       None.
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*
* COMMENTS:
*       Each switch device has its own set of event Types. Please refer to the
*        device datasheet for the list of event types that the device supports.
*
*******************************************************************************/
GT_STATUS eventGetActive(IN GT_QD_DEV * dev, IN GT_U32 * eventType)
{
	GT_STATUS   retVal;
	GT_U16      data;
	GT_U16      intMask;
	GT_U8       len;

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

	len = 9;

	if ((IS_IN_DEV_GROUP(dev, DEV_EXTERNAL_PHY_ONLY)) ||
		(IS_IN_DEV_GROUP(dev, DEV_DEV_PHY_INTERRUPT))) {
		intMask = GT_NO_INTERNAL_PHY_INT_MASK;
	} else {
		intMask = GT_INT_MASK;
	}

	if (!IS_IN_DEV_GROUP(dev, DEV_AVB_INTERRUPT)) {
		intMask &= ~GT_AVB_INT;
		len = 8;
	}

	if (!IS_IN_DEV_GROUP(dev, DEV_DEVICE_INTERRUPT)) {
		intMask &= ~GT_DEVICE_INT;
		len = 7;
	}

	/* Get the IntEn bit.               */
	retVal = hwGetGlobalRegField(dev, QD_REG_GLOBAL_CONTROL, 0, len, &data);
	if (retVal != GT_OK) {
		DBG_INFO(("Failed.\n"));
		return retVal;
	}

	*eventType = data;

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

/*******************************************************************************
* eventGetIntStatus
*
* DESCRIPTION:
*       This routine reads an hardware driven event status.
*
* INPUTS:
*       None.
*
* OUTPUTS:
*       intCause - It provides the source of interrupt of the following:
*               GT_STATS_DONE, GT_VTU_PROB, GT_VTU_DONE, GT_ATU_FULL,
*               GT_ATU_DONE, GT_PHY_INTERRUPT, GT_EE_INTERRUPT, GT_DEVICE_INT,
*                and GT_AVB_INTERRUPT
*                For Gigabit Switch, GT_ATU_FULL is replaced with GT_ATU_PROB and
*                if there is no internal phy, GT_PHY_INTERRUPT is not supported.
*
* RETURNS:
*       GT_OK   - read success.
*       GT_FAIL - otherwise
*
* COMMENTS:
*       Each switch device has its own set of event Types. Please refer to the
*        device datasheet for the list of event types that the device supports.
*
*******************************************************************************/
GT_STATUS eventGetIntStatus
(
    IN GT_QD_DEV *dev,
    OUT GT_U16   *intCause
)
{
    GT_STATUS     retVal;         /* Function calls return value.     */
    GT_U8         len;

    if (IS_IN_DEV_GROUP(dev,DEV_AVB_INTERRUPT))
        len = 9;
    else if (IS_IN_DEV_GROUP(dev,DEV_DEVICE_INTERRUPT))
        len = 8;
    else
        len = 7;

    retVal = hwGetGlobalRegField(dev,QD_REG_GLOBAL_STATUS,0,len,intCause);

    return retVal;
}


/*******************************************************************************
* gvtuGetIntStatus
*
* DESCRIPTION:
* Check to see if a specific type of VTU interrupt occured
*
* INPUTS:
*       intType - the type of interrupt which causes an interrupt.
*            any combination of
*            GT_MEMEBER_VIOLATION,
*            GT_MISS_VIOLATION,
*            GT_FULL_VIOLATION
*
* OUTPUTS:
*         None.
*
* RETURNS:
*         GT_OK - on success
*         GT_FAIL - on error
*
* COMMENTS:
*     FULL_VIOLATION is not supported by all switch devices.
*    Please refer to the device datasheet.
*
*******************************************************************************/
GT_STATUS gvtuGetIntStatus
(
    IN GT_QD_DEV          *dev,
    OUT GT_VTU_INT_STATUS *vtuIntStatus
)
{
    GT_STATUS       retVal;

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

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

    if (IS_IN_DEV_GROUP(dev,DEV_GIGABIT_SWITCH))
    {
        retVal = gvtuGetViolation2(dev,vtuIntStatus);
    }
    else if ((IS_IN_DEV_GROUP(dev,DEV_ENHANCED_FE_SWITCH)) ||
              (IS_IN_DEV_GROUP(dev,DEV_FE_AVB_FAMILY)))
    {
        retVal = gvtuGetViolation3(dev,vtuIntStatus);
    }
    else
    {
        retVal = gvtuGetViolation(dev,vtuIntStatus);
    }

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

    return retVal;
}

/*******************************************************************************
* gatuGetIntStatus
*
* DESCRIPTION:
* Check to see if a specific type of ATU interrupt occured
*
* INPUTS:
*          intType - the type of interrupt which causes an interrupt.
*            any combination of
*            GT_AGE_OUT_VIOLATION,
*            GT_AGE_VIOLATION,
*            GT_MEMEBER_VIOLATION,
*            GT_MISS_VIOLATION,
*            GT_FULL_VIOLATION
*
* OUTPUTS:
*         None.
*
* RETURNS:
*         GT_OK - on success
*         GT_FAIL - on error
*
* COMMENTS:
*
*******************************************************************************/

GT_STATUS gatuGetIntStatus
(
    IN GT_QD_DEV          *dev,
    OUT GT_ATU_INT_STATUS *atuIntStatus
)
{
    GT_STATUS       retVal;

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

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

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

    return retVal;
}


/*******************************************************************************
* geventGetDevIntStatus
*
* DESCRIPTION:
*         Check to see which device interrupts (WatchDog, JamLimit, Duplex Mismatch,
*        SERDES Link Int, and Phy Int) have occurred.
*
* INPUTS:
*       intType - the type of interrupt which causes an interrupt.
*                  any combination of
*                    GT_DEV_INT_WATCHDOG,
*                    GT_DEV_INT_JAMLIMIT,
*                    GT_DEV_INT_DUPLEX_MISMATCH,
*                    GT_DEV_INT_SERDES_LINK
*                    GT_DEV_INT_WAKE_EVENT
*                    GT_DEV_INT_PHY
*        port    - logical port where GT_DEV_INT_DUPLEX_MISMATCH occurred.
*                  valid only if GT_DEV_INT_DUPLEX_MISMATCH is set in intType.
*        linkInt - SERDES port list where GT_DEV_INT_SERDES_LINK interrupt is
*                  asserted. It's in vector format, Bit 10 is for port 10,
*                  Bit 9 is for port 9, etc.
*                  valid only if GT_DEV_INT_SERDES_LINK bit is set in intType.
*                  These bits are only valid of the port that is in 1000Base-X mode.
*        phyInt  - port list where GT_DEV_INT_PHY interrupt is asserted.
*                  It's in vector format, Bit 0 is for port 0, Bit 1 is for port 1, etc.
*                  valid only if GT_DEV_INT_PHY bit is set in intType.
*
* OUTPUTS:
*         None.
*
* RETURNS:
*         GT_OK - on success
*         GT_FAIL - on error
*
* COMMENTS:
*
*******************************************************************************/

GT_STATUS geventGetDevIntStatus
(
    IN  GT_QD_DEV             *dev,
    OUT GT_DEV_INT_STATUS    *devIntStatus
)
{
    GT_STATUS       retVal;
    GT_U16            data, hwPort;

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

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

    devIntStatus->devIntCause = 0;

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

    /* check SERDES Link Int and Phy Int, if applicable */
    if (IS_IN_DEV_GROUP(dev,DEV_DEVICE_INT_TYPE1))
    {
        /* check SERDES Link Int */
        if (data & (0x7 << 8))
        {
            devIntStatus->devIntCause |= GT_DEV_INT_SERDES_LINK;
            devIntStatus->linkInt = GT_PORTVEC_2_LPORTVEC((data & (7<<8)));
        }
    }
    else  if (IS_IN_DEV_GROUP(dev,DEV_DEVICE_INT_TYPE2))  /* DEV_DEVICE_INT_TYPE2 */
    {
        if (data & (0x3 << 11))
        {
            devIntStatus->devIntCause |= GT_DEV_INT_SERDES_LINK;
            devIntStatus->linkInt = GT_PORTVEC_2_LPORTVEC((data & (0x3 << 11)) >> 7);
        }

        if (data & 0x1F)
        {
            devIntStatus->devIntCause |= GT_DEV_INT_PHY;
            devIntStatus->phyInt = GT_PORTVEC_2_LPORTVEC((data & 0x1F));
        }
    }
    else /* DEV_DEVICE_INT_TYPE3 */
    {
      if (IS_IN_DEV_GROUP(dev,DEV_DEVICE_INT_TYPE3))  /* DEV_DEVICE_INT_TYPE3 */
      {
        if (data & QD_DEV_INT_WAKE_EVENT)
        {
            devIntStatus->devIntCause |= GT_DEV_INT_WAKE_EVENT;
        }
      }

        if (data & 0x1F)
        {
            devIntStatus->devIntCause |= GT_DEV_INT_PHY;
            devIntStatus->phyInt = GT_PORTVEC_2_LPORTVEC((data & 0x1F));
        }
    }

    if (data & QD_DEV_INT_DUPLEX_MISMATCH)
    {
        devIntStatus->devIntCause |= GT_DEV_INT_DUPLEX_MISMATCH;

        /* read port that causes the interrupt */
        retVal = hwGetGlobal2RegField(dev, QD_REG_WD_CONTROL, 12, 4, &hwPort);
        if(retVal != GT_OK)
        {
            DBG_INFO(("Failed.\n"));
            return retVal;
        }

        /* re-arm the interrupt event */
        retVal = hwSetGlobal2RegField(dev, QD_REG_WD_CONTROL, 12, 4, 0xF);
        if(retVal != GT_OK)
        {
            DBG_INFO(("Failed.\n"));
            return retVal;
        }

        devIntStatus->port = GT_PORT_2_LPORT((GT_U8)hwPort);
    }

    if (data & QD_DEV_INT_WATCHDOG)
    {
        devIntStatus->devIntCause |= GT_DEV_INT_WATCHDOG;
    }

    if (data & QD_DEV_INT_JAMLIMIT)
    {
        devIntStatus->devIntCause |= GT_DEV_INT_JAMLIMIT;
    }

    return retVal;
}


/*******************************************************************************
* geventSetAgeIntEn
*
* DESCRIPTION:
*        This routine enables/disables Age Interrupt for a port.
*        When it's enabled, ATU Age Violation interrupts from this port are enabled.
*        An Age Violation will occur anytime a port is Locked(gprtSetLockedPort)
*        and the ingressing frame's SA is contained in the ATU as a non-Static
*        entry with a EntryState less than 0x4.
*
* INPUTS:
*        port - the logical port number
*        mode - GT_TRUE to enable Age Interrupt,
*               GT_FALUSE to disable
*
* 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 geventSetAgeIntEn
(
    IN  GT_QD_DEV    *dev,
    IN  GT_LPORT    port,
    IN  GT_BOOL        mode
)
{
    GT_U16          data;
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U8           hwPort;         /* the physical port number     */

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

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

    if (!IS_IN_DEV_GROUP(dev,DEV_PORT_BASED_AGE_INT))
    {
        DBG_INFO(("GT_NOT_SUPPORTED\n"));
        return GT_NOT_SUPPORTED;
    }

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

    /* Set Age Interrupt Enable Mode.            */
    retVal = hwSetPortRegField(dev,hwPort, QD_REG_PORT_ASSOCIATION,11,1,data);

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

/*******************************************************************************
* geventGetAgeIntEn
*
* DESCRIPTION:
*        This routine gets Age Interrupt Enable for the port.
*        When it's enabled, ATU Age Violation interrupts from this port are enabled.
*        An Age Violation will occur anytime a port is Locked(gprtSetLockedPort)
*        and the ingressing frame's SA is contained in the ATU as a non-Static
*        entry with a EntryState less than 0x4.
*
* INPUTS:
*        port - the logical port number
*        mode - GT_TRUE to enable Age Interrupt,
*               GT_FALUSE to disable
*
* 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 geventGetAgeIntEn
(
    IN  GT_QD_DEV    *dev,
    IN  GT_LPORT    port,
    OUT GT_BOOL        *mode
)
{
    GT_U16          data;
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U8           hwPort;         /* the physical port number     */

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

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

    if (!IS_IN_DEV_GROUP(dev,DEV_PORT_BASED_AGE_INT))
    {
        DBG_INFO(("GT_NOT_SUPPORTED\n"));
        return GT_NOT_SUPPORTED;
    }

    /* Get Age Interrupt Enable Mode.            */
    retVal = hwGetPortRegField(dev,hwPort, QD_REG_PORT_ASSOCIATION,11,1,&data);

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

    BIT_2_BOOL(data, *mode);

    return retVal;
}


/*******************************************************************************
* geventSetAgeOutIntEn
*
* DESCRIPTION:
*        Interrupt on Age Out. When aging is enabled, all non-static address
*        entries in the ATU's address database are periodically aged.
*        When this feature is set to GT_TRUE and an entry associated with this
*        port is aged out, an AgeOutViolation will be captured for that entry.
*
* INPUTS:
*        port - the logical port number
*        mode - GT_TRUE to enable Age Out Interrupt,
*               GT_FALUSE to disable
*
* 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 geventSetAgeOutIntEn
(
    IN  GT_QD_DEV    *dev,
    IN  GT_LPORT    port,
    IN  GT_BOOL        mode
)
{
    GT_U16          data;
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U8           hwPort;         /* the physical port number     */

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

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

    if (!IS_IN_DEV_GROUP(dev,DEV_AGE_OUT_INT))
    {
        DBG_INFO(("GT_NOT_SUPPORTED\n"));
        return GT_NOT_SUPPORTED;
    }

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

    /* Set Age Out Interrupt Enable Mode. */
    retVal = hwSetPortRegField(dev,hwPort, QD_REG_PORT_ASSOCIATION,14,1,data);

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

/*******************************************************************************
* geventGetAgeOutIntEn
*
* DESCRIPTION:
*        Interrupt on Age Out. When aging is enabled, all non-static address
*        entries in the ATU's address database are periodically aged.
*        When this feature is set to GT_TRUE and an entry associated with this
*        port is aged out, an AgeOutViolation will be captured for that entry.
*
* INPUTS:
*        port - the logical port number
*
* OUTPUTS:
*        mode - GT_TRUE, if Age Out Interrupt is enabled
*               GT_FALUSE, otherwise
*
* RETURNS:
*        GT_OK   - on success
*        GT_FAIL - on error
*        GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*
*******************************************************************************/
GT_STATUS geventGetAgeOutIntEn
(
    IN  GT_QD_DEV    *dev,
    IN  GT_LPORT    port,
    OUT GT_BOOL        *mode
)
{
    GT_U16          data;
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U8           hwPort;         /* the physical port number     */

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

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

    if (!IS_IN_DEV_GROUP(dev,DEV_AGE_OUT_INT))
    {
        DBG_INFO(("GT_NOT_SUPPORTED\n"));
        return GT_NOT_SUPPORTED;
    }

    /* Get Age Out Interrupt Enable Mode.            */
    retVal = hwGetPortRegField(dev,hwPort, QD_REG_PORT_ASSOCIATION,14,1,&data);

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

    BIT_2_BOOL(data, *mode);

    return retVal;
}


/*******************************************************************************
* geventSetOverLimitInt
*
* DESCRIPTION:
*        This routine enables/disables Over Limit Interrupt for a port.
*        If it's enabled, an ATU Miss violation will be generated when port auto
*        learn reached the limit(refer to gfdbGetPortAtuLimitReached API).
*
* INPUTS:
*        port - the logical port number
*        mode - GT_TRUE to enable Over Limit Interrupt,
*               GT_FALUSE to disable
*
* 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 geventSetOverLimitInt
(
    IN  GT_QD_DEV    *dev,
    IN  GT_LPORT    port,
    IN  GT_BOOL        mode
)
{
    GT_U16          data;
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U8           hwPort;         /* the physical port number     */

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

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

    if (!IS_IN_DEV_GROUP(dev,DEV_ATU_LIMIT))
    {
        DBG_INFO(("GT_NOT_SUPPORTED\n"));
        return GT_NOT_SUPPORTED;
    }

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

    /* Set Over Limit Interrupt Enable Mode.            */
    retVal = hwSetPortRegField(dev,hwPort, QD_REG_PORT_ATU_CONTROL, 13, 1, data);

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

/*******************************************************************************
* geventGetOverLimitInt
*
* DESCRIPTION:
*        This routine enables/disables Over Limit Interrupt for a port.
*        If it's enabled, an ATU Miss violation will be generated when port auto
*        learn reached the limit(refer to gfdbSetPortAtuLearnLimit API).
*
* INPUTS:
*        port - the logical port number
*
* OUTPUTS:
*        mode - GT_TRUE to enable Over Limit Interrupt,
*               GT_FALUSE to disable
*
* RETURNS:
*        GT_OK   - on success
*        GT_FAIL - on error
*        GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*
*******************************************************************************/
GT_STATUS geventGetOverLimitInt
(
    IN  GT_QD_DEV    *dev,
    IN  GT_LPORT    port,
    OUT GT_BOOL        *mode
)
{
    GT_U16          data;
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U8           hwPort;         /* the physical port number     */

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

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

    if (!IS_IN_DEV_GROUP(dev,DEV_ATU_LIMIT))
    {
        DBG_INFO(("GT_NOT_SUPPORTED\n"));
        return GT_NOT_SUPPORTED;
    }

    /* Set Over Limit Interrupt Enable Mode.            */
    retVal = hwGetPortRegField(dev,hwPort, QD_REG_PORT_ATU_CONTROL, 13, 1, &data);

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

    BIT_2_BOOL(data, *mode);

    return retVal;
}

/*******************************************************************************
* geventGetPortAtuLimitReached
*
* DESCRIPTION:
*       This routine checks if learn limit has been reached.
*        When it reached, the port can no longer auto learn any more MAC addresses
*        because the address learn limit set on this port has been reached.
*
* INPUTS:
*       port  - logical port number
*
* OUTPUTS:
*       limit - GT_TRUE, if limit has been reached
*                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 geventGetPortAtuLimitReached
(
    IN  GT_QD_DEV     *dev,
    IN  GT_LPORT      port,
    IN  GT_BOOL       *limit
)
{
    GT_U16          data;
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U8           hwPort;         /* the physical port number     */

    DBG_INFO(("geventGetPortAtuLimitReached 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 LimitReached bit. */
    retVal = hwGetPortRegField(dev,hwPort, QD_REG_PORT_ATU_CONTROL, 14, 1, &data);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }

    BIT_2_BOOL(data, *limit);

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

/*******************************************************************************
* eventSetDevInt
*
* DESCRIPTION:
*        Device Interrupt.
*        The following device interrupts are supported:
*            GT_DEV_INT_WATCHDOG    -
*                WatchDog event interrupt (WatchDog event can be configured with
*                gwdSetEvent API)
*            GT_DEV_INT_JAMLIMIT    -
*                any of the ports detect an Ingress Jam Limit violation
*                (see gprtSetPauseLimitIn API)
*            GT_DEV_INT_DUPLEX_MISMATCH -
*                any of the ports detect a duplex mismatch (i.e., the local port is
*                in half duplex mode while the link partner is in full duplex mode)
*            GT_DEV_INT_WAKE_EVENT -
*                any of the ports detect a Wake event interrupt
*            GT_DEV_INT_SERDES_LINK -
*                SERDES link change interrupt.
*                An interrupt occurs when a SERDES port changes link status
*                (link up or link down)
*            GT_DEV_INT_PHY - Phy interrupt.
*
*        If any of the above events is enabled, GT_DEVICE_INT interrupt will
*        be asserted by the enabled event when GT_DEV_INT is enabled with
*        eventSetActive API.
*
* INPUTS:
*        devInt - GT_DEV_INT
*
* 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 eventSetDevInt
(
    IN  GT_QD_DEV    *dev,
    IN  GT_DEV_EVENT    *devInt
)
{
    GT_U16          data, event;
    GT_U16            serdesMask=0, phyMask=0, mask=0;
    GT_U32            pList;
    GT_STATUS       retVal;         /* Functions return value.      */

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

    if (!IS_IN_DEV_GROUP(dev,DEV_DEVICE_INTERRUPT))
    {
        DBG_INFO(("GT_NOT_SUPPORTED\n"));
        return GT_NOT_SUPPORTED;
    }

    event = (GT_U16)devInt->event;

    if (IS_IN_DEV_GROUP(dev,DEV_DEVICE_INT_TYPE1))
    {
        serdesMask = mask = 7 << 8;    /* SERDES Port List */
        phyMask = 0;
    }
    else if (IS_IN_DEV_GROUP(dev,DEV_DEVICE_INT_TYPE2))
    {
        serdesMask = mask = 3 << 11;    /* SERDES Port List */
        mask |= 0x1F;    /* Phy list */
        phyMask = 0x1F;
    }
    else
    {
        mask |= 0x1F;    /* Phy list */
        phyMask = 0x1F;
    }
    mask |= QD_DEV_INT_WATCHDOG | QD_DEV_INT_JAMLIMIT | QD_DEV_INT_DUPLEX_MISMATCH | QD_DEV_INT_WAKE_EVENT ;

    data = 0;

     if (event & GT_DEV_INT_SERDES_LINK)
     {
        /* check for valid SERDES Port List */
        if (IS_IN_DEV_GROUP(dev,DEV_DEVICE_INT_TYPE1))
        {
            pList = GT_LPORTVEC_2_PORTVEC(devInt->portList);
            if ((GT_U16)pList & (~serdesMask))
            {
                DBG_INFO(("GT_BAD_PARAM portList\n"));
                return GT_BAD_PARAM;
            }
            data = (GT_U16)pList;
        }
        else
        {
            pList = GT_LPORTVEC_2_PORTVEC(devInt->portList);
            pList <<= 7;
            if ((GT_U16)pList & (~serdesMask))
            {
                DBG_INFO(("GT_BAD_PARAM portList\n"));
                return GT_BAD_PARAM;
            }
            data = (GT_U16)pList;
        }
    }

    if (event & GT_DEV_INT_PHY)
    {
        /* check for valid Phy List */
        if (IS_IN_DEV_GROUP(dev,DEV_DEVICE_INT_TYPE1))
         {
            DBG_INFO(("GT_BAD_PARAM: PHY Int not supported.\n"));
             return GT_BAD_PARAM;
         }
        else
        {
            pList = GT_LPORTVEC_2_PORTVEC(devInt->phyList);
            if ((GT_U16)pList & (~phyMask))
            {
                DBG_INFO(("GT_BAD_PARAM phyList\n"));
                return GT_BAD_PARAM;
            }

            data |= (GT_U16)pList;
        }
     }

    if (event & GT_DEV_INT_WATCHDOG)
    {
        data |= QD_DEV_INT_WATCHDOG;
    }

    if (event & GT_DEV_INT_JAMLIMIT)
    {
        data |= QD_DEV_INT_JAMLIMIT;
    }

    if (event & GT_DEV_INT_DUPLEX_MISMATCH)
    {
        data |= QD_DEV_INT_DUPLEX_MISMATCH;
    }

    if (event & GT_DEV_INT_WAKE_EVENT)
    {
        data |= QD_DEV_INT_WAKE_EVENT;
    }

    if (data & (~mask))
    {
        DBG_INFO(("GT_BAD_PARAM portList\n"));
        return GT_BAD_PARAM;
    }

    if (data & GT_DEV_INT_DUPLEX_MISMATCH)
    {
        retVal = hwSetGlobal2RegField(dev, QD_REG_WD_CONTROL, 12, 4, 0xF);
        if(retVal != GT_OK)
        {
            DBG_INFO(("Failed.\n"));
            return retVal;
        }
    }

    /* Set the related bit. */
    retVal = hwSetGlobal2RegBits(dev,QD_REG_DEVINT_MASK, mask, data);

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

    return retVal;
}


/*******************************************************************************
* gwdSetEvent
*
* DESCRIPTION:
*        Watch Dog Event.
*        The following Watch Dog events are supported:
*            GT_WD_QC  - Queue Controller Watch Dog enable.
*                        When enabled, the QC's watch dog circuit checks for link
*                        list errors and any errors found in the QC.
*            GT_WD_EGRESS - Egress Watch Dog enable.
*                        When enabled, each port's egress circuit checks for problems
*                        between the port and the Queue Controller.
*            GT_WD_FORCE - Force a Watch Dog event.
*
*        If any of the above events is enabled, GT_DEVICE_INT interrupt will
*        be asserted by the enabled WatchDog event when GT_DEV_INT_WATCHDOG is
*        enabled with eventSetDevActive API and GT_DEV_INT is enabled with
*        eventSetActive API.
*
* INPUTS:
*        wdEvent - Watch Dog Events
*
* 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 gwdSetEvent
(
    IN  GT_QD_DEV    *dev,
    IN  GT_U32        wdEvent
)
{
    GT_U16          data, mask;
    GT_STATUS       retVal;         /* Functions return value.      */

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

    if (!IS_IN_DEV_GROUP(dev,DEV_WATCHDOG_EVENT))
    {
        DBG_INFO(("GT_NOT_SUPPORTED\n"));
        return GT_NOT_SUPPORTED;
    }

    mask = (1 << 5) | (1 << 3) | (1 << 2);
    data = 0;

    if (wdEvent & GT_WD_QC)
    {
        data |= (1 << 5);
    }

    if (wdEvent & GT_WD_EGRESS)
    {
        data |= (1 << 3);
    }

    if (wdEvent & GT_WD_FORCE)
    {
        data |= (1 << 2);
    }

    /* Set the related bit. */
    retVal = hwSetGlobal2RegBits(dev,QD_REG_WD_CONTROL, mask, data);

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

    return retVal;
}


/*******************************************************************************
* gwdSetSWResetOnWD
*
* DESCRIPTION:
*        SWReset on Watch Dog Event.
*        When this feature is enabled, any enabled watch dog event (gwdSetEvent API)
*        will automatically reset the switch core's datapath just as if gsysSwReset
*        API is called.
*
*        The Watch Dog History (gwdGetHistory API) won't be cleared by this
*        automatic SWReset. This allows the user to know if any watch dog event
*        ever occurred even if the swich is configured to automatically recover
*        from a watch dog.
*
*        When this feature is disabled, enabled watch dog events will not cause a
*        SWReset.
*
* INPUTS:
*        en   - GT_TRUE to enable SWReset on WD
*               GT_FALUSE to disable
*
* 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 gwdSetSWResetOnWD
(
    IN  GT_QD_DEV    *dev,
    IN  GT_BOOL        en
)
{
    GT_U16          data;
    GT_STATUS       retVal;         /* Functions return value.      */

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

    if (!IS_IN_DEV_GROUP(dev,DEV_WATCHDOG_EVENT))
    {
        DBG_INFO(("GT_NOT_SUPPORTED\n"));
        return GT_NOT_SUPPORTED;
    }

    BOOL_2_BIT(en,data);

    /* Set the related bit. */
    retVal = hwSetGlobal2RegField(dev,QD_REG_WD_CONTROL, 0, 1, data);

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

    return retVal;
}


/*******************************************************************************
* gwdGetSWResetOnWD
*
* DESCRIPTION:
*        SWReset on Watch Dog Event.
*        When this feature is enabled, any enabled watch dog event (gwdSetEvent API)
*        will automatically reset the switch core's datapath just as if gsysSwReset
*        API is called.
*
*        The Watch Dog History (gwdGetHistory API) won't be cleared by this
*        automatic SWReset. This allows the user to know if any watch dog event
*        ever occurred even if the swich is configured to automatically recover
*        from a watch dog.
*
*        When this feature is disabled, enabled watch dog events will not cause a
*        SWReset.
*
* INPUTS:
*        None.
*
* OUTPUTS:
*        en   - GT_TRUE, if SWReset on WD is enabled
*               GT_FALUSE, otherwise
*
* RETURNS:
*        GT_OK   - on success
*        GT_FAIL - on error
*        GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*
*******************************************************************************/
GT_STATUS gwdGetSWResetOnWD
(
    IN  GT_QD_DEV    *dev,
    OUT GT_BOOL        *en
)
{
    GT_U16          data;
    GT_STATUS       retVal;         /* Functions return value.      */

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

    if (!IS_IN_DEV_GROUP(dev,DEV_WATCHDOG_EVENT))
    {
        DBG_INFO(("GT_NOT_SUPPORTED\n"));
        return GT_NOT_SUPPORTED;
    }

    /* Get the related bit. */
    retVal = hwGetGlobal2RegField(dev,QD_REG_WD_CONTROL, 0, 1, &data);

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

    BIT_2_BOOL(data, *en);

    return retVal;
}


/*******************************************************************************
* gwdGetHistory
*
* DESCRIPTION:
*        This routine retrieves Watch Dog history. They are
*
*        wdEvent -
*            When it's set to GT_TRUE, some enabled Watch Dog event occurred.
*            The following events are possible:
*                QC WatchDog Event (GT_WD_QC)
*                Egress WatchDog Event (GT_WD_EGRESS)
*                Forced WatchDog Event (GT_WD_FORCE)
*        egressEvent -
*            If any port's egress logic detects an egress watch dog issue,
*            this field is set to GT_TRUE, regardless of the enabling GT_WD_EGRESS
*            event.
*
* INPUTS:
*        None.
*
* OUTPUTS:
*        history - GT_WD_EVENT_HISTORY structure
*
* RETURNS:
*        GT_OK   - on success
*        GT_FAIL - on error
*        GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*
*******************************************************************************/
GT_STATUS gwdGetHistory
(
    IN  GT_QD_DEV            *dev,
    OUT GT_WD_EVENT_HISTORY    *history
)
{
    GT_U16          data;
    GT_STATUS       retVal;         /* Functions return value.      */

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

    if (!IS_IN_DEV_GROUP(dev,DEV_WATCHDOG_EVENT))
    {
        DBG_INFO(("GT_NOT_SUPPORTED\n"));
        return GT_NOT_SUPPORTED;
    }

    /* Get the related bit. */
    retVal = hwReadGlobal2Reg(dev,QD_REG_WD_CONTROL,&data);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
        return retVal;
    }

    if (data & (1 << 4))
    {
        history->egressEvent = GT_TRUE;
    }
    else
    {
        history->egressEvent = GT_FALSE;
    }

    if (data & (1 << 1))
    {
        history->wdEvent = GT_TRUE;
    }
    else
    {
        history->wdEvent = GT_FALSE;
    }

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


/*******************************************************************************
* gwdSetRMUTimeOut
*
* DESCRIPTION:
*        Remote Management Timeout. When this bit is set to a one the Remote
*        Management Unit(RMU) will timeout on Wait on Bit commands. If the bit that
*        is being tested has not gone to the specified value after 1 sec. has elapsed
*        the Wait on Bit command will be terminated and the Response frame will be
*        sent without any further processing.
*
*        When this bit is cleared to a zero the Wait on Bit command will wait
*        until the bit that is being tested has changed to the specified value.
*
* INPUTS:
*        en   - GT_TRUE to enable RMU Timeout
*               GT_FALUSE to disable
*
* 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 gwdSetRMUTimeOut
(
    IN  GT_QD_DEV    *dev,
    IN  GT_BOOL        en
)
{
    GT_U16          data;
    GT_STATUS       retVal;         /* Functions return value.      */

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

    if (!IS_IN_DEV_GROUP(dev,DEV_WATCHDOG_EVENT))
    {
        DBG_INFO(("GT_NOT_SUPPORTED\n"));
        return GT_NOT_SUPPORTED;
    }

    BOOL_2_BIT(en,data);

    /* Set the related bit. */
    retVal = hwSetGlobal2RegField(dev,QD_REG_WD_CONTROL, 6, 1, data);

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

    return retVal;
}


/*******************************************************************************
* gwdGetRMUTimeOut
*
* DESCRIPTION:
*        Remote Management Timeout. When this bit is set to a one the Remote
*        Management Unit(RMU) will timeout on Wait on Bit commands. If the bit that
*        is being tested has not gone to the specified value after 1 sec. has elapsed
*        the Wait on Bit command will be terminated and the Response frame will be
*        sent without any further processing.
*
*        When this bit is cleared to a zero the Wait on Bit command will wait
*        until the bit that is being tested has changed to the specified value.
*
* INPUTS:
*        None.
*
* OUTPUTS:
*        en   - GT_TRUE to enable RMU Timeout
*               GT_FALUSE, otherwise
*
* RETURNS:
*        GT_OK   - on success
*        GT_FAIL - on error
*        GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*
*******************************************************************************/
GT_STATUS gwdGetRMUTimeOut
(
    IN  GT_QD_DEV    *dev,
    OUT GT_BOOL        *en
)
{
    GT_U16          data;
    GT_STATUS       retVal;         /* Functions return value.      */

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

    if (!IS_IN_DEV_GROUP(dev,DEV_WATCHDOG_EVENT))
    {
        DBG_INFO(("GT_NOT_SUPPORTED\n"));
        return GT_NOT_SUPPORTED;
    }

    /* Get the related bit. */
    retVal = hwGetGlobal2RegField(dev,QD_REG_WD_CONTROL, 6, 1, &data);

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

    BIT_2_BOOL(data, *en);

    return retVal;
}


/*******************************************************************************
* gwdGetEgressWDEvent
*
* DESCRIPTION:
*        If any port's egress logic detects an egress watch dog issue, this bit
*        will be set to a one, regardless of the setting of the GT_WD_EGRESS in
*        gwdSetEvent function.
*
* INPUTS:
*        None.
*
* OUTPUTS:
*        event - GT_TRUE, if egress logic has detected any egress watch dog issue
*                GT_FALUSE, otherwise
*
*
* RETURNS:
*        GT_OK   - on success
*        GT_FAIL - on error
*        GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*
*******************************************************************************/
GT_STATUS gwdGetEgressWDEvent
(
    IN  GT_QD_DEV        *dev,
    OUT GT_BOOL            *event
)
{
    GT_U16          data;
    GT_STATUS       retVal;         /* Functions return value.      */

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

    if (!IS_IN_DEV_GROUP(dev,DEV_WATCHDOG_EVENT))
    {
        DBG_INFO(("GT_NOT_SUPPORTED\n"));
        return GT_NOT_SUPPORTED;
    }

    /* Get the related bit. */
    retVal = hwGetGlobal2RegField(dev,QD_REG_WD_CONTROL, 7, 1, &data);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
    }
    else
    {
        DBG_INFO(("OK.\n"));
    }

    BIT_2_BOOL(data, *event);

    return retVal;
}
