#include <Copyright.h>

/********************************************************************************
* gtPhyInt.h
*
* DESCRIPTION:
* API definitions for PHY interrupt handling
*
* DEPENDENCIES:
* None.
*
* FILE REVISION NUMBER:
* $Revision: 10 $
*******************************************************************************/

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

#ifdef GT_USE_MAD
#include <gtMad.h>
#endif

#ifdef GT_USE_MAD
#include "gtPhyInt_mad.c"
#endif
/*******************************************************************************
* gprtPhyIntEnable
*
* DESCRIPTION:
* Enable/Disable one PHY Interrupt
* This register determines whether the INT# pin is asserted when an interrupt
* event occurs. When an interrupt occurs, the corresponding bit is set and
* remains set until register 19 is read via the SMI. When interrupt enable
* bits are not set in register 18, interrupt status bits in register 19 are
* still set when the corresponding interrupt events occur. However, the INT#
* is not asserted.
*
* INPUTS:
* port -   The logical port number, unless SERDES device is accessed
*          The physical address, if SERDES device is accessed
* intType - the type of interrupt to enable/disable. any combination of
*            GT_SPEED_CHANGED,
*            GT_DUPLEX_CHANGED,
*            GT_PAGE_RECEIVED,
*            GT_AUTO_NEG_COMPLETED,
*            GT_LINK_STATUS_CHANGED,
*            GT_SYMBOL_ERROR,
*            GT_FALSE_CARRIER,
*            GT_FIFO_FLOW,
*            GT_CROSSOVER_CHANGED,    ( Copper only )
*            GT_DOWNSHIFT_DETECT,    ( for 1000M Copper only )
*            GT_ENERGY_DETECT,        ( for 1000M Copper only )
*            GT_POLARITY_CHANGED, and ( Copper only )
*            GT_JABBER                (Copper only )
*
*
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
*
* COMMENTS:
* For 88E6131, 88E6122, and 88E6108 devices, Serdes port can be accessed using
* logical port number.
* For 88E6161 88E6165 and 88E6352 devices, Serdes port 5 (address 0xD/0xF) can be accessed
* using logical port number, but not port 4 (since port 4 could be an internal
* PHY.)
*******************************************************************************/


GT_STATUS gprtPhyIntEnable
(
IN GT_QD_DEV    *dev,
IN GT_LPORT    port,
IN GT_U16    intType
)
{
    GT_STATUS       retVal;
    GT_U8           hwPort;         /* the physical port number     */

/*
#ifdef GT_USE_MAD
    if (dev->use_mad==GT_TRUE)
        return gprtPhyIntEnable_mad(dev, port, intType);
#endif
*/
    DBG_INFO(("gprtPhyIntEnable Called.\n"));

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

    if((IS_IN_DEV_GROUP(dev,DEV_SERDES_CORE)) && (hwPort > 3))
    {
        if(!(dev->validSerdesVec & (1 << hwPort)))
        {
            if(!((IS_IN_DEV_GROUP(dev,DEV_SERDES_ACCESS_CONFIG)) && (hwPort == 4)))
                GT_GET_SERDES_PORT(dev,&hwPort);
        }
        if(hwPort >= dev->maxPhyNum)
        {
            return GT_NOT_SUPPORTED;
        }
    }

    /* check if the port is configurable */
    if(!IS_CONFIGURABLE_PHY(dev,hwPort))
    {
        return GT_NOT_SUPPORTED;
    }

    retVal = hwWritePhyReg(dev,hwPort, QD_PHY_INT_ENABLE_REG, intType);

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

    return retVal;

}

/*******************************************************************************
* gprtGetPhyIntStatus
*
* DESCRIPTION:
* Check to see if a specific type of interrupt occured
*
* INPUTS:
* port -   The logical port number, unless SERDES device is accessed
*          The physical address, if SERDES device is accessed
* intType - the type of interrupt which causes an interrupt.
*            any combination of
*            GT_SPEED_CHANGED,
*            GT_DUPLEX_CHANGED,
*            GT_PAGE_RECEIVED,
*            GT_AUTO_NEG_COMPLETED,
*            GT_LINK_STATUS_CHANGED,
*            GT_SYMBOL_ERROR,
*            GT_FALSE_CARRIER,
*            GT_FIFO_FLOW,
*            GT_CROSSOVER_CHANGED,    ( Copper only )
*            GT_DOWNSHIFT_DETECT,    ( for 1000M Copper only )
*            GT_ENERGY_DETECT,        ( for 1000M Copper only )
*            GT_POLARITY_CHANGED, and ( Copper only )
*            GT_JABBER                (Copper only )
*
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
*
* COMMENTS:
* For 88E6131, 88E6122, and 88E6108 devices, Serdes port can be accessed using
* logical port number.
* For 88E6161 88E6165 and 88E6352 devices, Serdes port 5 (address 0xD/0xF) can be accessed
* using logical port number, but not port 4 (since port 4 could be an internal
* PHY.)
*
*******************************************************************************/

GT_STATUS gprtGetPhyIntStatus
(
IN   GT_QD_DEV  *dev,
IN   GT_LPORT   port,
OUT  GT_U16*    intType
)
{
    GT_STATUS       retVal;
    GT_U8           hwPort;         /* the physical port number     */

#ifdef GT_USE_MAD
    if (dev->use_mad==GT_TRUE)
        return gprtGetPhyIntStatus_mad(dev, port, intType);
#endif

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

    /* translate LPORT to hardware port */
    hwPort = GT_LPORT_2_PHY(port);
    if((IS_IN_DEV_GROUP(dev,DEV_SERDES_CORE)) && (hwPort > 3))
    {
        if(!(dev->validSerdesVec & (1 << hwPort)))
        {
            if(!((IS_IN_DEV_GROUP(dev,DEV_SERDES_ACCESS_CONFIG)) && (hwPort == 4)))
                GT_GET_SERDES_PORT(dev,&hwPort);
        }
        if(hwPort >= dev->maxPhyNum)
        {
            return GT_NOT_SUPPORTED;
        }
    }

    /* check if the port is configurable */
    if(!IS_CONFIGURABLE_PHY(dev,hwPort))
    {
        return GT_NOT_SUPPORTED;
    }

    retVal = hwReadPhyReg(dev,hwPort, QD_PHY_INT_STATUS_REG, intType);
    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
    }
    else
    {
        DBG_INFO(("OK.\n"));
    }

    return retVal;
}

/*******************************************************************************
* gprtGetPhyIntPortSummary
*
* DESCRIPTION:
* Lists the ports that have active interrupts. It provides a quick way to
* isolate the interrupt so that the MAC or switch does not have to poll the
* interrupt status register (19) for all ports. Reading this register does not
* de-assert the INT# pin
*
* INPUTS:
* none
*
* OUTPUTS:
* GT_U8 *intPortMask - bit Mask with the bits set for the corresponding
* phys with active interrupt. E.g., the bit number 0 and 2 are set when
* port number 0 and 2 have active interrupt
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
*
* COMMENTS:
* 88E3081 data sheet register 20
* For 88E6165, 88E6375 devices, geventGetDevIntStatus should be used instead.
*
*******************************************************************************/

GT_STATUS gprtGetPhyIntPortSummary
(
IN  GT_QD_DEV  *dev,
OUT GT_U16     *intPortMask
)
{
    GT_STATUS       retVal;
    GT_U8           hwPort;         /* the physical port number     */
    GT_U16            portVec;

#ifdef GT_USE_MAD
    if (dev->use_mad==GT_TRUE)
        return gprtGetPhyIntPortSummary_mad(dev, intPortMask);
#endif

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

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

    *intPortMask=0;

    if (IS_IN_DEV_GROUP(dev,DEV_DEV_PHY_INTERRUPT))
    {
        return GT_NOT_SUPPORTED;
    }

    if (IS_IN_DEV_GROUP(dev,DEV_INTERNAL_GPHY))
    {
        /* get the interrupt port summary from global register */
        retVal = hwGetGlobal2RegField(dev,QD_REG_PHYINT_SOURCE,0,dev->maxPorts,&portVec);
        GT_GIG_PHY_INT_MASK(dev,portVec);
        *intPortMask = (GT_U16)GT_PORTVEC_2_LPORTVEC(portVec);
    }
    else
    {
        /* get the interrupt port summary from phy */
        retVal = hwReadPhyReg(dev,hwPort, QD_PHY_INT_PORT_SUMMARY_REG, &portVec);
        *intPortMask = (GT_U16)GT_PORTVEC_2_LPORTVEC(portVec);
    }

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

    return retVal;

}
