#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

/*******************************************************************************
* 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 and 88E6165 devices, Serdes port 5 (address 0xD) 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_88E6165_FAMILY)) && (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 and 88E6165 devices, Serdes port 5 (address 0xD) 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_88E6165_FAMILY)) && (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;

}

