#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>
#include <madApi.h>

/*******************************************************************************
* gprtPhyIntEnable_mad
*
* 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_mad
(
IN GT_QD_DEV    *dev,
IN GT_LPORT    port,
IN GT_U16    intType
)
{
    GT_U8           hwPort;         /* the physical port number     */
    MAD_INT_TYPE    mintType;

    DBG_INFO(("gprtPhyIntEnable_mad 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;
    }

	mintType.intGroup0 = 0;
	mintType.intGroup1 = 0;
	mintType.intGroup0 = intType;
    if(mdIntSetEnable(&(dev->mad_dev),hwPort,&mintType) != MAD_OK)
    {
        DBG_INFO(("Call mdIntSetEnable failed.\n"));
        return GT_FAIL;
    }

    return GT_OK;

}

/*******************************************************************************
* gprtGetPhyIntStatus_mad
*
* 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_mad
(
IN   GT_QD_DEV  *dev,
IN   GT_LPORT   port,
OUT  GT_U16*    intType
)
{
    GT_U8           hwPort;         /* the physical port number     */
    MAD_INT_TYPE    mintType;

    DBG_INFO(("gprtGetPhyIntStatus_mad 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;
    }

    if(mdIntGetStatus(&(dev->mad_dev),hwPort,&mintType) != MAD_OK)
    {
        DBG_INFO(("Call mdIntGetStatus failed.\n"));
        return GT_FAIL;
    }
	
	*intType = mintType.intGroup0;

    return GT_OK;
}

/*******************************************************************************
* gprtGetPhyIntPortSummary_mad
*
* 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_mad
(
IN  GT_QD_DEV  *dev,
OUT GT_U16     *intPortMask
)
{
    GT_STATUS       retVal;      
    GT_U8           hwPort;         /* the physical port number     */
    GT_U16          portVec;
    MAD_U32         mportVec;

    DBG_INFO(("gprtGetPhyIntPortSummary_mad 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 */
      if(mdIntGetPortSummary(&(dev->mad_dev), &mportVec) != MAD_OK)
	  {
        DBG_INFO(("Call mdIntGetPortSummary failed.\n"));
        return GT_FAIL;
	  }
      portVec = mportVec;
      *intPortMask = (GT_U16)GT_PORTVEC_2_LPORTVEC(portVec);
	}

    return GT_OK;

}

