#include <Copyright.h>

/********************************************************************************
* gtPhyCtrl.h
* 
* DESCRIPTION:
* API definitions for PHY control facility.
*
* DEPENDENCIES:
* None.
*
* FILE REVISION NUMBER:
* $Revision: 10 $
*******************************************************************************/

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

#include <linux/module.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/delay.h>
/*
 * This routine set Auto-Negotiation Ad Register for Fast Ethernet Phy
*/
static 
GT_STATUS feSetAutoMode
(
	IN GT_QD_DEV *dev,
	IN GT_U8 	 hwPort,
	IN GT_PHY_INFO	 *phyInfo,
	IN GT_PHY_AUTO_MODE mode
)
{
    GT_U16 			u16Data;

	GT_UNUSED_PARAM(phyInfo);

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

    if(hwReadPhyReg(dev,hwPort,QD_PHY_AUTONEGO_AD_REG,&u16Data) != GT_OK)
	{
        DBG_INFO(("Not able to read Phy Reg(port:%d,offset:%d).\n",hwPort,QD_PHY_AUTONEGO_AD_REG));
   	    return GT_FAIL;
	}

	/* Mask out all auto mode related bits. */
	u16Data &= ~QD_PHY_MODE_AUTO_AUTO;

	switch(mode)
	{
		case SPEED_AUTO_DUPLEX_AUTO:
				u16Data |= QD_PHY_MODE_AUTO_AUTO;
				break;
		case SPEED_100_DUPLEX_AUTO:
				u16Data |= QD_PHY_MODE_100_AUTO;
				break;
		case SPEED_10_DUPLEX_AUTO:
				u16Data |= QD_PHY_MODE_10_AUTO;
				break;
		case SPEED_AUTO_DUPLEX_FULL:
				u16Data |= QD_PHY_MODE_AUTO_FULL;
				break;
		case SPEED_AUTO_DUPLEX_HALF:
				u16Data |= QD_PHY_MODE_AUTO_HALF;
				break;
		case SPEED_100_DUPLEX_FULL:
				u16Data |= QD_PHY_100_FULL;
				break;
		case SPEED_100_DUPLEX_HALF:
				u16Data |= QD_PHY_100_HALF;
				break;
		case SPEED_10_DUPLEX_FULL:
				u16Data |= QD_PHY_10_FULL;
				break;
		case SPEED_10_DUPLEX_HALF:
				u16Data |= QD_PHY_10_HALF;
				break;
		default:
	 	        DBG_INFO(("Unknown Auto Mode (%d)\n",mode));
				return GT_BAD_PARAM;
	}

    /* Write to Phy AutoNegotiation Advertisement Register.  */
    if(hwWritePhyReg(dev,hwPort,QD_PHY_AUTONEGO_AD_REG,u16Data) != GT_OK)
	{
        DBG_INFO(("Not able to write Phy Reg(port:%d,offset:%d,data:%#x).\n",hwPort,QD_PHY_AUTONEGO_AD_REG,u16Data));
   	    return GT_FAIL;
	}

	return GT_OK;
}

/*
 * This routine get Auto-Negotiation Ad Register for Fast Ethernet Phy
*/
static 
GT_STATUS feGetAutoMode
(
    IN  GT_QD_DEV        *dev,
    IN  GT_U8            hwPort,
    IN  GT_PHY_INFO      *phyInfo,
    OUT GT_PHY_AUTO_MODE *mode
)
{
    GT_U16  u16Data;

    GT_UNUSED_PARAM(phyInfo);

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

    if(hwReadPhyReg(dev,hwPort,QD_PHY_AUTONEGO_AD_REG,&u16Data) != GT_OK)
    {
        DBG_INFO(("Not able to read Phy Reg(port:%d,offset:%d).\n",hwPort,QD_PHY_AUTONEGO_AD_REG));
           return GT_FAIL;
    }

    /* Pick out all auto mode related bits. */
    u16Data &= QD_PHY_MODE_AUTO_AUTO;

    switch(u16Data)
    {
        case QD_PHY_MODE_10_HALF:
                *mode = SPEED_10_DUPLEX_HALF;
                break;
        case QD_PHY_MODE_10_FULL:
                *mode = SPEED_10_DUPLEX_FULL;
                break;
        case QD_PHY_MODE_100_HALF:
                *mode = SPEED_100_DUPLEX_HALF;
                break;
        case QD_PHY_MODE_100_FULL:
                *mode = SPEED_100_DUPLEX_FULL;
                break;
        case QD_PHY_MODE_AUTO_HALF:
                *mode = SPEED_AUTO_DUPLEX_HALF;
                break;
        case QD_PHY_MODE_AUTO_FULL:
                *mode = SPEED_AUTO_DUPLEX_FULL;
                break;
        case QD_PHY_MODE_10_AUTO:
                *mode = SPEED_10_DUPLEX_AUTO;
                break;
        case QD_PHY_MODE_100_AUTO:
                *mode = SPEED_100_DUPLEX_AUTO;
                break;
        case QD_PHY_MODE_AUTO_AUTO:
                *mode = SPEED_AUTO_DUPLEX_AUTO;
                break;
        default:
                DBG_INFO(("Unknown Auto Mode (%d)\n", u16Data));
                *mode = SPEED_AUTO_DUPLEX_AUTO;
                break;
    }

    return GT_OK;
}

/*
 * This routine set Auto-Negotiation Ad Register for Copper
*/
static 
GT_STATUS gigCopperSetAutoMode
(
	IN GT_QD_DEV *dev,
	IN GT_U8 hwPort,
	IN GT_PHY_INFO	 *phyInfo,
	IN GT_PHY_AUTO_MODE mode
)
{
    GT_U16 			u16Data,u16Data1;

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

    if(hwReadPagedPhyReg(dev,hwPort,0,QD_PHY_AUTONEGO_AD_REG,phyInfo->anyPage,&u16Data) != GT_OK)
	{
        DBG_INFO(("Not able to read Phy Reg(port:%d,offset:%d).\n",hwPort,QD_PHY_AUTONEGO_AD_REG));
   	    return GT_FAIL;
	}

	/* Mask out all auto mode related bits. */
	u16Data &= ~QD_PHY_MODE_AUTO_AUTO;

    if(hwReadPagedPhyReg(dev,hwPort,0,QD_PHY_AUTONEGO_1000AD_REG,phyInfo->anyPage,&u16Data1) != GT_OK)
	{
        DBG_INFO(("Not able to read Phy Reg(port:%d,offset:%d).\n",hwPort,QD_PHY_AUTONEGO_AD_REG));
   	    return GT_FAIL;
	}

	/* Mask out all auto mode related bits. */
	u16Data1 &= ~(QD_GIGPHY_1000T_FULL|QD_GIGPHY_1000T_HALF);

	switch(mode)
	{
		case SPEED_AUTO_DUPLEX_AUTO:
				u16Data |= QD_PHY_MODE_AUTO_AUTO;
		case SPEED_1000_DUPLEX_AUTO:
				u16Data1 |= QD_GIGPHY_1000T_FULL|QD_GIGPHY_1000T_HALF;
				break;
		case SPEED_AUTO_DUPLEX_FULL:
				u16Data  |= QD_PHY_MODE_AUTO_FULL;
				u16Data1 |= QD_GIGPHY_1000T_FULL;
				break;
		case SPEED_1000_DUPLEX_FULL:
				u16Data1 |= QD_GIGPHY_1000T_FULL;
				break;
		case SPEED_1000_DUPLEX_HALF:
				u16Data1 |= QD_GIGPHY_1000T_HALF;
				break;
		case SPEED_AUTO_DUPLEX_HALF:
				u16Data  |= QD_PHY_MODE_AUTO_HALF;
				u16Data1 |= QD_GIGPHY_1000T_HALF;
				break;
		case SPEED_100_DUPLEX_AUTO:
				u16Data |= QD_PHY_MODE_100_AUTO;
				break;
		case SPEED_10_DUPLEX_AUTO:
				u16Data |= QD_PHY_MODE_10_AUTO;
				break;
		case SPEED_100_DUPLEX_FULL:
				u16Data |= QD_PHY_100_FULL;
				break;
		case SPEED_100_DUPLEX_HALF:
				u16Data |= QD_PHY_100_HALF;
				break;
		case SPEED_10_DUPLEX_FULL:
				u16Data |= QD_PHY_10_FULL;
				break;
		case SPEED_10_DUPLEX_HALF:
				u16Data |= QD_PHY_10_HALF;
				break;
		default:
				DBG_INFO(("Unknown Auto Mode (%d)\n",mode));
				return GT_BAD_PARAM;
	}

    /* Write to Phy AutoNegotiation Advertisement Register.  */
    if(hwWritePagedPhyReg(dev,hwPort,0,QD_PHY_AUTONEGO_AD_REG,phyInfo->anyPage,u16Data) != GT_OK)
	{
        DBG_INFO(("Not able to write Phy Reg(port:%d,offset:%d,data:%#x).\n",hwPort,QD_PHY_AUTONEGO_AD_REG,u16Data));
   	    return GT_FAIL;
	}

    /* Write to Phy AutoNegotiation 1000B Advertisement Register.  */
    if(hwWritePagedPhyReg(dev,hwPort,0,QD_PHY_AUTONEGO_1000AD_REG,phyInfo->anyPage,u16Data1) != GT_OK)
	{
        DBG_INFO(("Not able to read Phy Reg(port:%d,offset:%d).\n",hwPort,QD_PHY_AUTONEGO_AD_REG));
   	    return GT_FAIL;
	}

	return GT_OK;
}

/*
 * This routine get Auto-Negotiation Ad Register for Copper
*/
static 
GT_STATUS gigCopperGetAutoMode
(
    IN GT_QD_DEV        *dev,
    IN GT_U8            hwPort,
    IN GT_PHY_INFO      *phyInfo,
    IN GT_PHY_AUTO_MODE *mode
)
{
    GT_U16 u16Data, u16Data1;
    GT_U32 u32Data;

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

    if(hwReadPagedPhyReg(dev,hwPort,0,QD_PHY_AUTONEGO_AD_REG,phyInfo->anyPage,&u16Data) != GT_OK)
    {
        DBG_INFO(("Not able to read Phy Reg(port:%d,offset:%d).\n",hwPort,QD_PHY_AUTONEGO_AD_REG));
           return GT_FAIL;
    }

    /* Pick out all auto mode related bits. */
    u16Data &= QD_PHY_MODE_AUTO_AUTO;

    if(hwReadPagedPhyReg(dev,hwPort,0,QD_PHY_AUTONEGO_1000AD_REG,phyInfo->anyPage,&u16Data1) != GT_OK)
    {
        DBG_INFO(("Not able to read Phy Reg(port:%d,offset:%d).\n",hwPort,QD_PHY_AUTONEGO_AD_REG));
           return GT_FAIL;
    }

    /* Pick out all auto mode related bits. */
    u16Data1 &= (QD_GIGPHY_1000T_FULL|QD_GIGPHY_1000T_HALF);

    u32Data  = (u16Data&0xffff)|((u16Data1&0xffff)<<16);

    switch(u32Data)
    {
        case QD_PHY_MODE_10_HALF:
                *mode = SPEED_10_DUPLEX_HALF;
                break;
        case QD_PHY_MODE_10_FULL:
                *mode = SPEED_10_DUPLEX_FULL;
                break;
        case QD_PHY_MODE_100_HALF:
                *mode = SPEED_100_DUPLEX_HALF;
                break;
        case QD_PHY_MODE_100_FULL:
                *mode = SPEED_100_DUPLEX_FULL;
                break;
        case (QD_GIGPHY_1000T_HALF<<16):
                *mode = SPEED_1000_DUPLEX_HALF;
                break;
        case (QD_GIGPHY_1000T_FULL<<16):
                *mode = SPEED_1000_DUPLEX_FULL;
                break;                
        case QD_PHY_MODE_AUTO_HALF|(QD_GIGPHY_1000T_HALF<<16):
                *mode = SPEED_AUTO_DUPLEX_HALF;
                break;
        case QD_PHY_MODE_AUTO_FULL|(QD_GIGPHY_1000T_FULL<<16):
                *mode = SPEED_AUTO_DUPLEX_FULL;
                break;
        case QD_PHY_MODE_10_AUTO:
                *mode = SPEED_10_DUPLEX_AUTO;
                break;
        case QD_PHY_MODE_100_AUTO:
                *mode = SPEED_100_DUPLEX_AUTO;
                break;
        case ((QD_GIGPHY_1000T_FULL|QD_GIGPHY_1000T_HALF)<<16):
                *mode = SPEED_1000_DUPLEX_AUTO;
                break;                
        case QD_PHY_MODE_AUTO_AUTO|((QD_GIGPHY_1000T_FULL|QD_GIGPHY_1000T_HALF)<<16):
                *mode = SPEED_AUTO_DUPLEX_AUTO;
                break;
        default:
                *mode = SPEED_AUTO_DUPLEX_AUTO;
                DBG_INFO(("Unknown Auto Mode (%08x)\n", u32Data));
                break;
    }

    return GT_OK;
}

/*
 * This routine set Auto-Negotiation Ad Register for Fiber
*/
static 
GT_STATUS gigFiberSetAutoMode
(
	IN GT_QD_DEV *dev,
	IN GT_U8 hwPort,
	IN GT_PHY_INFO	 *phyInfo,
	IN GT_PHY_AUTO_MODE mode
)
{
    GT_U16 			u16Data;

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

    if(hwReadPagedPhyReg(dev,hwPort,1,QD_PHY_AUTONEGO_AD_REG,phyInfo->anyPage,&u16Data) != GT_OK)
	{
        DBG_INFO(("Not able to read Phy Reg(port:%d,offset:%d).\n",hwPort,QD_PHY_AUTONEGO_AD_REG));
   	    return GT_FAIL;
	}

	/* Mask out all auto mode related bits. */
	u16Data &= ~(QD_GIGPHY_1000X_FULL|QD_GIGPHY_1000X_HALF);

	switch(mode)
	{
		case SPEED_AUTO_DUPLEX_AUTO:
		case SPEED_1000_DUPLEX_AUTO:
				u16Data |= QD_GIGPHY_1000X_FULL|QD_GIGPHY_1000X_HALF;
				break;
		case SPEED_AUTO_DUPLEX_FULL:
		case SPEED_1000_DUPLEX_FULL:
				u16Data |= QD_GIGPHY_1000X_FULL;
				break;
		case SPEED_AUTO_DUPLEX_HALF:
		case SPEED_1000_DUPLEX_HALF:
				u16Data |= QD_GIGPHY_1000X_HALF;
				break;
		default:
	 	       	DBG_INFO(("Unknown Auto Mode (%d)\n",mode));
				return GT_BAD_PARAM;
	}

    /* Write to Phy AutoNegotiation Advertisement Register.  */
    if(hwWritePagedPhyReg(dev,hwPort,1,QD_PHY_AUTONEGO_AD_REG,phyInfo->anyPage,u16Data) != GT_OK)
	{
        DBG_INFO(("Not able to write Phy Reg(port:%d,offset:%d,data:%#x).\n",hwPort,QD_PHY_AUTONEGO_AD_REG,u16Data));
   	    return GT_FAIL;
	}

	return GT_OK;
}

/*
 * This routine sets Auto Mode and Reset the phy
*/
static 
GT_STATUS phySetAutoMode
(
	IN GT_QD_DEV *dev,
	IN GT_U8 hwPort,
	IN GT_PHY_INFO *phyInfo,
	IN GT_PHY_AUTO_MODE mode
)
{
	GT_U16 		u16Data;
	GT_STATUS	status;
	GT_BOOL		autoOn;
	GT_U16		pageReg;

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

	if (!(phyInfo->flag & GT_PHY_GIGABIT))
	{
		if((status=feSetAutoMode(dev,hwPort,phyInfo,mode)) != GT_OK)
		{
   		    return status;
		}

		if (hwReadPhyReg(dev, hwPort, QD_PHY_CONTROL_REG, &u16Data) != GT_OK)
			return GT_FAIL;

		u16Data = (u16Data & (QD_PHY_SPEED | QD_PHY_DUPLEX)) | QD_PHY_AUTONEGO;

		DBG_INFO(("Write to phy(%d) register: regAddr 0x%x, data %#x",
			 hwPort,QD_PHY_CONTROL_REG,u16Data));

		/* soft reset */
		return hwPhyReset(dev,hwPort,u16Data);
	}

	if(driverPagedAccessStart(dev,hwPort,phyInfo->pageType,&autoOn,&pageReg) != GT_OK)
	{
		return GT_FAIL;
	}

	/* Read to Phy Control Register.  */
	if(hwReadPagedPhyReg(dev, hwPort, 0, QD_PHY_CONTROL_REG, phyInfo->anyPage, &u16Data) != GT_OK)
		return GT_FAIL;

	if(phyInfo->flag & GT_PHY_COPPER)
	{
		if((status=gigCopperSetAutoMode(dev,hwPort,phyInfo,mode)) != GT_OK)
		{
   		    return status;
		}

		u16Data = (u16Data & (QD_PHY_SPEED_MSB | QD_PHY_SPEED | QD_PHY_DUPLEX)) | QD_PHY_AUTONEGO;

		DBG_INFO(("Write to phy(%d) register: regAddr 0x%x, data %#x",
			 hwPort,QD_PHY_CONTROL_REG,u16Data));

		/* Write to Phy Control Register.  */
		if(hwWritePagedPhyReg(dev,hwPort,0,QD_PHY_CONTROL_REG,phyInfo->anyPage,u16Data) != GT_OK)
			return GT_FAIL;
	}
	else if(phyInfo->flag & GT_PHY_FIBER)
	{
		if((status=gigFiberSetAutoMode(dev,hwPort,phyInfo,mode)) != GT_OK)
		{
   		    return status;
		}
		u16Data = (u16Data & (QD_PHY_SPEED_MSB | QD_PHY_SPEED | QD_PHY_DUPLEX)) | QD_PHY_AUTONEGO;

		DBG_INFO(("Write to phy(%d) register: regAddr 0x%x, data %#x",
			 hwPort,QD_PHY_CONTROL_REG,u16Data));

		/* Write to Phy Control Register.  */
		if(hwWritePagedPhyReg(dev,hwPort,1,QD_PHY_CONTROL_REG,phyInfo->anyPage,u16Data) != GT_OK)
			return GT_FAIL;
	}

	if(driverPagedAccessStop(dev,hwPort,phyInfo->pageType,autoOn,pageReg) != GT_OK)
	{
		return GT_FAIL;
	}

	return hwPhyReset(dev,hwPort,0xFF);
}

/*
 * This routine gets Auto Mode
*/
static 
GT_STATUS phyGetAutoMode
(
    IN  GT_QD_DEV        *dev,
    IN  GT_U8            hwPort,
    IN  GT_PHY_INFO      *phyInfo,
    OUT GT_PHY_AUTO_MODE *mode
)
{
    GT_STATUS    status;
    GT_BOOL      autoOn;
    GT_U16       pageReg;

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

    if (!(phyInfo->flag & GT_PHY_GIGABIT))
    {
        if((status=feGetAutoMode(dev,hwPort,phyInfo,mode)) != GT_OK)
        {
               return status;
        }
        return status;
    }

    if(driverPagedAccessStart(dev,hwPort,phyInfo->pageType,&autoOn,&pageReg) != GT_OK)
    {
        return GT_FAIL;
    }

    if(phyInfo->flag & GT_PHY_COPPER)
    {
        if((status=gigCopperGetAutoMode(dev,hwPort,phyInfo,mode)) != GT_OK)
        {
               return status;
        }
    }
    else if(phyInfo->flag & GT_PHY_FIBER)
    {
        return GT_NOT_SUPPORTED;
    }

    if(driverPagedAccessStop(dev,hwPort,phyInfo->pageType,autoOn,pageReg) != GT_OK)
    {
        return GT_FAIL;
    }

    return status;
}

/*******************************************************************************
* gprtPhyReset
*
* DESCRIPTION:
*       This routine preforms PHY reset.
*		After reset, phy will be in Autonegotiation mode.
*
* INPUTS:
* port - The logical port number, unless SERDES device is accessed
*        The physical address, if SERDES device is accessed
*
* OUTPUTS:
*       None.
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
* COMMENTS:
* data sheet register 0.15 - Reset
* data sheet register 0.13 - Speed
* data sheet register 0.12 - Autonegotiation
* data sheet register 0.8  - Duplex Mode
*******************************************************************************/

GT_STATUS gprtPhyReset
(
	IN GT_QD_DEV *dev,
	IN GT_LPORT  port
)
{

    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U8           hwPort;         /* the physical port number     */
	GT_PHY_INFO		phyInfo;

    DBG_INFO(("gprtPhyReset Called.\n"));
    
    /* translate LPORT to hardware port */
    hwPort = GT_LPORT_2_PHY(port);

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

	/* check if the port is configurable */
	if((phyInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_NOT_SUPPORTED;
	}

	if(driverFindPhyInformation(dev,hwPort,&phyInfo) != GT_OK)
	{
	    DBG_INFO(("Unknown PHY device.\n"));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

	/* set Auto Negotiation AD Register */
	retVal = phySetAutoMode(dev,hwPort,&phyInfo,SPEED_AUTO_DUPLEX_AUTO);

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

	gtSemGive(dev,dev->phyRegsSem);

    return retVal;
}


/*******************************************************************************
* gprtSetPortLoopback
*
* DESCRIPTION:
* Enable/Disable Internal Port Loopback. 
* For 10/100 Fast Ethernet PHY, speed of Loopback is determined as follows:
*   If Auto-Negotiation is enabled, this routine disables Auto-Negotiation and 
*   forces speed to be 10Mbps.
*   If Auto-Negotiation is disabled, the forced speed is used.
*   Disabling Loopback simply clears bit 14 of control register(0.14). Therefore,
*   it is recommended to call gprtSetPortAutoMode for PHY configuration after 
*   Loopback test.
* For 10/100/1000 Gigagbit Ethernet PHY, speed of Loopback is determined as follows:
*   If Auto-Negotiation is enabled and Link is active, the current speed is used.
*   If Auto-Negotiation is disabled, the forced speed is used.
*   All other cases, default MAC Interface speed is used. Please refer to the data
*   sheet for the information of the default MAC Interface speed.
*   
*
* INPUTS:
* port - The logical port number, unless SERDES device is accessed
*        The physical address, if SERDES device is accessed
* enable - If GT_TRUE, enable loopback mode
* If GT_FALSE, disable loopback mode
*
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
*
* COMMENTS:
* data sheet register 0.14 - Loop_back
*
*******************************************************************************/

GT_STATUS gprtSetPortLoopback
(
	IN GT_QD_DEV *dev,
	IN GT_LPORT  port,
	IN GT_BOOL   enable
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U8           hwPort;         /* the physical port number     */
    GT_U16 			u16Data;
	GT_PHY_INFO		phyInfo;

    DBG_INFO(("gprtSetPortLoopback Called.\n"));
    
    /* translate LPORT to hardware port */
    hwPort = GT_LPORT_2_PHY(port);

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

	/* check if the port is configurable */
	if((phyInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_NOT_SUPPORTED;
	}

	if(driverFindPhyInformation(dev,hwPort,&phyInfo) != GT_OK)
	{
	    DBG_INFO(("Unknown PHY device.\n"));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

    if(hwReadPhyReg(dev,hwPort,QD_PHY_CONTROL_REG,&u16Data) != GT_OK)
	{
        DBG_INFO(("Not able to read Phy Reg(port:%d,offset:%d).\n",hwPort,QD_PHY_CONTROL_REG));
		gtSemGive(dev,dev->phyRegsSem);
        return GT_FAIL;
	}

	/* Is this Fast Ethernet Phy? */
	if (!(phyInfo.flag & GT_PHY_GIGABIT))
	{
		if(enable)
		{
			if(u16Data & QD_PHY_AUTONEGO)
			{
				/* Disable Auto-Neg*/
				u16Data &= ~QD_PHY_AUTONEGO;

				if((retVal=hwPhyReset(dev,hwPort,u16Data)) != GT_OK)
				{
					DBG_INFO(("Softreset failed.\n"));
					gtSemGive(dev,dev->phyRegsSem);
					return retVal;
				}
			}
		}
		else
		{
			if(!(u16Data & QD_PHY_AUTONEGO))
			{
				/* Enable Auto-Neg*/
				u16Data |= QD_PHY_RESET | QD_PHY_AUTONEGO;

				if((retVal=hwPhyReset(dev,hwPort,u16Data)) != GT_OK)
				{
					DBG_INFO(("Softreset failed.\n"));
					gtSemGive(dev,dev->phyRegsSem);
					return retVal;
				}
			}

		}
	}

	BOOL_2_BIT(enable,u16Data);

    /* Write to Phy Control Register.  */
    retVal = hwSetPhyRegField(dev,hwPort,QD_PHY_CONTROL_REG,14,1,u16Data);
    if(retVal != GT_OK)
	{
        DBG_INFO(("Failed.\n"));
	}
    else
	{
        DBG_INFO(("OK.\n"));
	}
	gtSemGive(dev,dev->phyRegsSem);
    return retVal;
}
/*******************************************************************************
* gprtGetPortLoopback
*
* DESCRIPTION:
* Get Internal Port Loopback state. 
* For 10/100 Fast Ethernet PHY, speed of Loopback is determined as follows:
*   If Auto-Negotiation is enabled, this routine disables Auto-Negotiation and 
*   forces speed to be 10Mbps.
*   If Auto-Negotiation is disabled, the forced speed is used.
*   Disabling Loopback simply clears bit 14 of control register(0.14). Therefore,
*   it is recommended to call gprtSetPortAutoMode for PHY configuration after 
*   Loopback test.
* For 10/100/1000 Gigagbit Ethernet PHY, speed of Loopback is determined as follows:
*   If Auto-Negotiation is enabled and Link is active, the current speed is used.
*   If Auto-Negotiation is disabled, the forced speed is used.
*   All other cases, default MAC Interface speed is used. Please refer to the data
*   sheet for the information of the default MAC Interface speed.
*   
*
* INPUTS:
* port - The logical port number, unless SERDES device is accessed
*        The physical address, if SERDES device is accessed
*
* OUTPUTS:
* enable - If GT_TRUE,  loopback mode is enabled
* If GT_FALSE,  loopback mode is disabled
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
*
* COMMENTS:
* data sheet register 0.14 - Loop_back
*
*******************************************************************************/
GT_STATUS gprtGetPortLoopback
(
	IN GT_QD_DEV *dev,
	IN GT_LPORT  port,
	OUT GT_BOOL   *enable
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U8           hwPort;         /* the physical port number     */
    GT_U16 			u16Data;
	GT_PHY_INFO		phyInfo;

    DBG_INFO(("gprtGetPortLoopback Called.\n"));
    
    /* translate LPORT to hardware port */
    hwPort = GT_LPORT_2_PHY(port);

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

	/* check if the port is configurable */
	if((phyInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_NOT_SUPPORTED;
	}

	if(driverFindPhyInformation(dev,hwPort,&phyInfo) != GT_OK)
	{
	    DBG_INFO(("Unknown PHY device.\n"));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

	/*get loopback state*/
	retVal = hwGetPhyRegField(dev,hwPort,QD_PHY_CONTROL_REG,14,1,&u16Data);
    if(retVal != GT_OK)
	{
        DBG_INFO(("Failed.\n"));
	}
    else
	{
        DBG_INFO(("OK.\n"));
        BIT_2_BOOL(u16Data, *enable);
	}

    return retVal;
}

/*******************************************************************************
* gprtSetPortLineLoopback
*
* DESCRIPTION:
* Enable/Disable Port Line Loopback. 
*   
*
* INPUTS:
* port - The logical port number, unless SERDES device is accessed
*        The physical address, if SERDES device is accessed
* enable - If GT_TRUE, enable loopback mode
* If GT_FALSE, disable loopback mode
*
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
*
* COMMENTS:
* data sheet register FE:28.4, GE:21_2.14  - Loop_back
*
*******************************************************************************/

GT_STATUS gprtSetPortLineLoopback
(
	IN GT_QD_DEV *dev,
	IN GT_LPORT  port,
	IN GT_BOOL   enable
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U8           hwPort;         /* the physical port number     */
    GT_U16 			u16Data;
    GT_PHY_INFO		phyInfo;
    GT_U16		    pageReg;
    
    DBG_INFO(("gprtSetPortLineLoopback Called.\n"));
    
    /* translate LPORT to hardware port */
    hwPort = GT_LPORT_2_PHY(port);
    
    gtSemTake(dev,dev->phyRegsSem,OS_WAIT_FOREVER);
    
    /* check if the port is configurable */
    if((phyInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
    {
        gtSemGive(dev,dev->phyRegsSem);
        return GT_NOT_SUPPORTED;
    }
    
    if(driverFindPhyInformation(dev,hwPort,&phyInfo) != GT_OK)
    {
        DBG_INFO(("Unknown PHY device.\n"));
        gtSemGive(dev,dev->phyRegsSem);
        return GT_FAIL;
    }

	BOOL_2_BIT(enable,u16Data);
		
	 /* GE Phy */
    if ((phyInfo.flag & GT_PHY_GIGABIT))
    {
        if(driverPagedAccessStart(dev,hwPort,phyInfo.pageType,0,&pageReg) != GT_OK)
        {
            return GT_FAIL;
        } 
        
		/* Write to GE PHY MAC specific control register.  */
		retVal = hwSetPagedPhyRegField(dev,hwPort, 2, QD_PHY_GE_LINE_LOOPBACK_REG,14,1,phyInfo.anyPage, u16Data);

    	if(driverPagedAccessStop(dev,hwPort,phyInfo.pageType,0,pageReg) != GT_OK)
    	{
    		return GT_FAIL;
    	}
    }
    else /* FE Phy */
    {
    	/* Write to FE PHY specific control register.  */
		retVal = hwSetPhyRegField(dev,hwPort,QD_PHY_FE_LINE_LOOPBACK_REG,4,1,u16Data);
    }

    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
    }
    else
    {
        DBG_INFO(("OK.\n"));
    }
    gtSemGive(dev,dev->phyRegsSem);
    return retVal;
}
/*******************************************************************************
* gprtGetPortLineLoopback
*
* DESCRIPTION:
* Get Port Line Loopback status. 
*   
*
* INPUTS:
* port - The logical port number, unless SERDES device is accessed
*        The physical address, if SERDES device is accessed
*
* OUTPUTS:
* enable - If GT_TRUE, enable loopback mode
* If GT_FALSE, disable loopback mode* enable - If GT_TRUE, enable loopback mode
* If GT_FALSE, disable loopback mode
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
*
* COMMENTS:
* data sheet register FE:28.4, GE:21_2.14  - Loop_back
*
*******************************************************************************/

GT_STATUS gprtGetPortLineLoopback
(
	IN GT_QD_DEV *dev,
	IN GT_LPORT  port,
	OUT GT_BOOL*   enable
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U8           hwPort;         /* the physical port number     */
    GT_U16 			u16Data;
    GT_PHY_INFO		phyInfo;
    GT_U16		    pageReg;
    
    DBG_INFO(("gprtGetPortLineLoopback Called.\n"));
    
    /* translate LPORT to hardware port */
    hwPort = GT_LPORT_2_PHY(port);
    
    gtSemTake(dev,dev->phyRegsSem,OS_WAIT_FOREVER);
    
    /* check if the port is configurable */
    if((phyInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
    {
        gtSemGive(dev,dev->phyRegsSem);
        return GT_NOT_SUPPORTED;
    }
    
    if(driverFindPhyInformation(dev,hwPort,&phyInfo) != GT_OK)
    {
        DBG_INFO(("Unknown PHY device.\n"));
        gtSemGive(dev,dev->phyRegsSem);
        return GT_FAIL;
    }
		
	 /* GE Phy */
    if ((phyInfo.flag & GT_PHY_GIGABIT))
    {
        if(driverPagedAccessStart(dev,hwPort,phyInfo.pageType,0,&pageReg) != GT_OK)
        {
            return GT_FAIL;
        } 
        
		/* Read to GE PHY MAC specific control register.  */
		retVal = hwGetPagedPhyRegField(dev,hwPort, 2, QD_PHY_GE_LINE_LOOPBACK_REG,14,1,phyInfo.anyPage,&u16Data);

    	if(driverPagedAccessStop(dev,hwPort,phyInfo.pageType,0,pageReg) != GT_OK)
    	{
    		return GT_FAIL;
    	}		
    }
    else /* FE Phy */
    {
    	/* Read to FE PHY specific control register.  */
		retVal = hwGetPhyRegField(dev,hwPort,QD_PHY_FE_LINE_LOOPBACK_REG,4,1,&u16Data);
    }

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

	BIT_2_BOOL(u16Data, *enable);
	
    gtSemGive(dev,dev->phyRegsSem);
    return retVal;
}

/*******************************************************************************
* gprtSetPortSpeed
*
* DESCRIPTION:
* 		Sets speed for a specific logical port. This function will keep the duplex 
*		mode and loopback mode to the previous value, but disable others, such as 
*		Autonegotiation.
*
* INPUTS:
*		port -	The logical port number, unless SERDES device is accessed
*				The physical address, if SERDES device is accessed
*		speed - port speed.
*				PHY_SPEED_10_MBPS for 10Mbps
*				PHY_SPEED_100_MBPS for 100Mbps
*				PHY_SPEED_1000_MBPS for 1000Mbps
*
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
*
* COMMENTS:
* data sheet register 0.13 - Speed Selection (LSB)
* data sheet register 0.6  - Speed Selection (MSB)
*
*******************************************************************************/

GT_STATUS gprtSetPortSpeed
(
IN GT_QD_DEV *dev,
IN GT_LPORT  port,
IN GT_PHY_SPEED speed
)
{
	GT_U8           hwPort;         /* the physical port number     */
	GT_U16 		u16Data;
	GT_PHY_INFO	phyInfo;
	GT_STATUS	retVal;

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

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

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

	/* check if the port is configurable */
	if((phyInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_NOT_SUPPORTED;
	}

	if(driverFindPhyInformation(dev,hwPort,&phyInfo) != GT_OK)
	{
	    DBG_INFO(("Unknown PHY device.\n"));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

	if(hwReadPhyReg(dev,hwPort,QD_PHY_CONTROL_REG,&u16Data) != GT_OK)
	{
		DBG_INFO(("Not able to read Phy Reg(port:%d,offset:%d).\n",hwPort,QD_PHY_CONTROL_REG));
		gtSemGive(dev,dev->phyRegsSem);
        	return GT_FAIL;
	}

	switch(speed)
	{
		case PHY_SPEED_10_MBPS:
			if ((phyInfo.flag & GT_PHY_GIGABIT) && !(phyInfo.flag & GT_PHY_COPPER))
			{
				gtSemGive(dev,dev->phyRegsSem);
				return GT_BAD_PARAM;
			}
			u16Data = u16Data & (QD_PHY_LOOPBACK | QD_PHY_DUPLEX);
			break;
		case PHY_SPEED_100_MBPS:
			u16Data = (u16Data & (QD_PHY_LOOPBACK | QD_PHY_DUPLEX)) | QD_PHY_SPEED;
			break;
		case PHY_SPEED_1000_MBPS:
			if (!(phyInfo.flag & GT_PHY_GIGABIT))
			{
				gtSemGive(dev,dev->phyRegsSem);
				return GT_BAD_PARAM;
			}
			u16Data = (u16Data & (QD_PHY_LOOPBACK | QD_PHY_DUPLEX)) | QD_PHY_SPEED_MSB;
			break;
		default:
			gtSemGive(dev,dev->phyRegsSem);
			return GT_FAIL;
	}

	DBG_INFO(("Write to phy(%d) register: regAddr 0x%x, data %#x",
		 hwPort,QD_PHY_CONTROL_REG,u16Data));

	retVal = hwPhyReset(dev,hwPort,u16Data);
  	gtSemGive(dev,dev->phyRegsSem);
	return retVal;
}

/*******************************************************************************
* gprtGetPortSpeed
*
* DESCRIPTION:
* 		Gets speed for a specific logical port. 
*
* INPUTS:
*		port -	The logical port number, unless SERDES device is accessed
*				The physical address, if SERDES device is accessed
*
* OUTPUTS:
* 		speed - port speed.
*				PHY_SPEED_10_MBPS for 10Mbps
*				PHY_SPEED_100_MBPS for 100Mbps
*				PHY_SPEED_1000_MBPS for 1000Mbps
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
*
* COMMENTS:
* data sheet register 0.13 - Speed Selection (LSB)
* data sheet register 0.6  - Speed Selection (MSB)
*
*******************************************************************************/
GT_STATUS gprtGetPortSpeed
(
IN GT_QD_DEV *dev,
IN GT_LPORT  port,
IN GT_PHY_SPEED *speed
)
{
    GT_U8         hwPort;  /* The physical port number */
    GT_U16 			u16Data;
    GT_PHY_INFO		phyInfo;

    DBG_INFO(("gprtGetPortSpeed Called.\n"));
    
    /* translate LPORT to hardware port */
    hwPort = GT_LPORT_2_PHY(port);

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

	/* check if the port is configurable */
	if((phyInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_NOT_SUPPORTED;
	}

	if(driverFindPhyInformation(dev,hwPort,&phyInfo) != GT_OK)
	{
	    DBG_INFO(("Unknown PHY device.\n"));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

    if(hwReadPhyReg(dev,hwPort,QD_PHY_CONTROL_REG,&u16Data) != GT_OK)
	{
        DBG_INFO(("Not able to read Phy Reg(port:%d,offset:%d).\n",hwPort,QD_PHY_CONTROL_REG));
		gtSemGive(dev,dev->phyRegsSem);
        return GT_FAIL;
	}

	if ((phyInfo.flag & GT_PHY_GIGABIT) && !(phyInfo.flag & GT_PHY_COPPER))
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_BAD_PARAM;
	}
	
	if ((phyInfo.flag & GT_PHY_GIGABIT) && (u16Data & QD_PHY_SPEED_MSB))
	{
		*speed = PHY_SPEED_1000_MBPS;
	}
	else
	{
		if (u16Data & QD_PHY_SPEED)
		{
			*speed = PHY_SPEED_100_MBPS;
		}
		else
		{
			*speed = PHY_SPEED_10_MBPS;
		}			
	}

    DBG_INFO(("Read phy(%d) register: regAddr 0x%x, data %#x, speed[%d] \r\n",
              hwPort,QD_PHY_CONTROL_REG,u16Data, *speed));

  	gtSemGive(dev,dev->phyRegsSem);
    return GT_OK;
}

/*******************************************************************************
* gprtPortAutoNegEnable
*
* DESCRIPTION:
* 		Enable/disable an Auto-Negotiation.
*		This routine simply sets Auto Negotiation bit (bit 12) of Control 
*		Register and reset the phy.
*		For Speed and Duplex selection, please use gprtSetPortAutoMode.
*
* INPUTS:
*		port -	The logical port number, unless SERDES device is accessed
*				The physical address, if SERDES device is accessed
* 		state - GT_TRUE for enable Auto-Negotiation,
*				GT_FALSE otherwise
*
* OUTPUTS:
* 		None.
*
* RETURNS:
* 		GT_OK 	- on success
* 		GT_FAIL 	- on error
*
* COMMENTS:
* 		data sheet register 0.12 - Auto-Negotiation Enable
* 		data sheet register 4.8, 4.7, 4.6, 4.5 - Auto-Negotiation Advertisement
*
*******************************************************************************/
GT_STATUS gprtPortAutoNegEnable
(
	IN GT_QD_DEV *dev,
	IN GT_LPORT  port,
	IN GT_BOOL   state
)
{
    GT_U8           hwPort;         /* the physical port number     */
    GT_U16 			u16Data;
	GT_STATUS		retVal;

    DBG_INFO(("gprtPortAutoNegEnable Called.\n"));
    
    /* translate LPORT to hardware port */
    hwPort = GT_LPORT_2_PHY(port);

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

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

    if(hwReadPhyReg(dev,hwPort,QD_PHY_CONTROL_REG,&u16Data) != GT_OK)
	{
        DBG_INFO(("Not able to read Phy Reg(port:%d,offset:%d).\n",hwPort,QD_PHY_CONTROL_REG));
		gtSemGive(dev,dev->phyRegsSem);
        return GT_FAIL;
	}

	if(state)
	{
		u16Data = (u16Data & (QD_PHY_SPEED_MSB | QD_PHY_SPEED | QD_PHY_DUPLEX)) | QD_PHY_AUTONEGO;
	}
	else
	{
		u16Data = u16Data & (QD_PHY_SPEED_MSB |QD_PHY_SPEED | QD_PHY_DUPLEX | QD_PHY_LOOPBACK);
	}


    DBG_INFO(("Write to phy(%d) register: regAddr 0x%x, data %#x",
              hwPort,QD_PHY_CONTROL_REG,u16Data));

	retVal = hwPhyReset(dev,hwPort,u16Data);
	gtSemGive(dev,dev->phyRegsSem);
	return retVal;
}
/*******************************************************************************
* gprtGetPortAutoNegState
*
* DESCRIPTION:
* 		Read the auto negotiation state of specific logical port.
*		This routine simply reads Auto Negotiation bit (bit 12) of Control 
*		Register.
*
* INPUTS:
*		port -	The logical port number, unless SERDES device is accessed
*				The physical address, if SERDES device is accessed
*
* OUTPUTS:
* 		state 	- GT_TRUE for enable Auto-Negotiation,
*				   GT_FALSE otherwise
*
* RETURNS:
* 		GT_OK 	- on success
* 		GT_FAIL 	- on error
*
* COMMENTS:
* 		data sheet register 0.12 - Auto-Negotiation Enable
* 		data sheet register 4.8, 4.7, 4.6, 4.5 - Auto-Negotiation Advertisement
*
*******************************************************************************/
GT_STATUS gprtGetPortAutoNegState
(
	IN GT_QD_DEV *dev,
	IN GT_LPORT  port,
	OUT GT_BOOL   *state
)
{
    GT_U8           hwPort;         /* the physical port number     */
    GT_U16 			u16Data;
    GT_STATUS		retVal;

    DBG_INFO(("gprtGetPortAutoNegState Called.\n"));
    
    /* translate LPORT to hardware port */
    hwPort = GT_LPORT_2_PHY(port);

    gtSemTake(dev,dev->phyRegsSem,OS_WAIT_FOREVER);
    
    /* check if the port is configurable */
    if(!IS_CONFIGURABLE_PHY(dev,hwPort))
    {
    	gtSemGive(dev,dev->phyRegsSem);
    	return GT_NOT_SUPPORTED;
    }

    /*read the auto negotiation state from bit 12 of PHY control register*/	
    if((retVal=hwGetPhyRegField(dev,hwPort,QD_PHY_CONTROL_REG,12,1,&u16Data)) != GT_OK)
    {
        	DBG_INFO(("Failed.\n"));
    	gtSemGive(dev,dev->phyRegsSem);
    	return retVal;
    }
    
    BIT_2_BOOL(u16Data, *state);
	
    gtSemGive(dev,dev->phyRegsSem);
    return retVal;
}

/*******************************************************************************
* gprtPortPowerDown
*
* DESCRIPTION:
* 		Enable/disable (power down) on specific logical port.
*		Phy configuration remains unchanged after Power down.
*
* INPUTS:
*		port -	The logical port number, unless SERDES device is accessed
*				The physical address, if SERDES device is accessed
* 		state -	GT_TRUE: power down
* 				GT_FALSE: normal operation
*
* OUTPUTS:
* 		None.
*
* RETURNS:
* 		GT_OK 	- on success
* 		GT_FAIL 	- on error
*
* COMMENTS:
* 		data sheet register 0.11 - Power Down
*
*******************************************************************************/

GT_STATUS gprtPortPowerDown
(
IN GT_QD_DEV *dev,
IN GT_LPORT  port,
IN GT_BOOL   state
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U8           hwPort;         /* the physical port number     */
    GT_U16 			u16Data;

    DBG_INFO(("gprtPortPowerDown Called.\n"));
    
    /* translate LPORT to hardware port */
    hwPort = GT_LPORT_2_PHY(port);

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

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

	BOOL_2_BIT(state,u16Data);

	if((retVal=hwSetPhyRegField(dev,hwPort,QD_PHY_CONTROL_REG,11,1,u16Data)) != GT_OK)
	{
        DBG_INFO(("Failed.\n"));
		gtSemGive(dev,dev->phyRegsSem);
		return retVal;
	}

	gtSemGive(dev,dev->phyRegsSem);
	return GT_OK;
}

/*******************************************************************************
* gprtGetPortPowerDown
*
* DESCRIPTION:
* 		Read Port state (power down/normal operation) on specific logical port.
*
* INPUTS:
*		port -	The logical port number, unless SERDES device is accessed
*				The physical address, if SERDES device is accessed
*
* OUTPUTS:
* 		state -	GT_TRUE: power down
* 				GT_FALSE: normal operation
*
* RETURNS:
* 		GT_OK 	- on success
* 		GT_FAIL 	- on error
*
* COMMENTS:
* 		data sheet register 0.11 - Power Down
*
*******************************************************************************/
GT_STATUS gprtGetPortPowerDown
(
IN GT_QD_DEV *dev,
IN GT_LPORT  port,
OUT GT_BOOL   *state
)
{
    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U8           hwPort;         /* the physical port number     */
    GT_U16 			u16Data;

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

    if(state == NULL)
    {
	DBG_INFO(("Input point state equals NULL which is illegal,  return\n"));
    }
    
    /* translate LPORT to hardware port */
    hwPort = GT_LPORT_2_PHY(port);

    gtSemTake(dev,dev->phyRegsSem,OS_WAIT_FOREVER);
    
    /* check if the port is configurable */
    if(!IS_CONFIGURABLE_PHY(dev,hwPort))
    {
    	gtSemGive(dev,dev->phyRegsSem);
    	return GT_NOT_SUPPORTED;
    }
    
    if((retVal=hwGetPhyRegField(dev,hwPort,QD_PHY_CONTROL_REG,11,1,&u16Data)) != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
    	gtSemGive(dev,dev->phyRegsSem);
    	return retVal;
    }
    
    BIT_2_BOOL(u16Data, *state);
    
    gtSemGive(dev,dev->phyRegsSem);
    return GT_OK;
}

/*******************************************************************************
* gprtPortRestartAutoNeg
*
* DESCRIPTION:
* 		Restart AutoNegotiation. If AutoNegotiation is not enabled, it'll enable 
*		it. Loopback and Power Down will be disabled by this routine.
*
* INPUTS:
*		port -	The logical port number, unless SERDES device is accessed
*				The physical address, if SERDES device is accessed
*
* OUTPUTS:
* 		None.
*
* RETURNS:
* 		GT_OK 	- on success
* 		GT_FAIL 	- on error
*
* COMMENTS:
* 		data sheet register 0.9 - Restart Auto-Negotiation
*
*******************************************************************************/

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

    DBG_INFO(("gprtPortRestartAutoNeg Called.\n"));
  
    /* translate LPORT to hardware port */
    hwPort = GT_LPORT_2_PHY(port);

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

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

    if(hwReadPhyReg(dev,hwPort,QD_PHY_CONTROL_REG,&u16Data) != GT_OK)
	{
        DBG_INFO(("Not able to read Phy Reg(port:%d,offset:%d).\n",hwPort,QD_PHY_CONTROL_REG));
		gtSemGive(dev,dev->phyRegsSem);
        return GT_FAIL;
	}

	u16Data &= (QD_PHY_DUPLEX | QD_PHY_SPEED | QD_PHY_SPEED_MSB);
	u16Data |= (QD_PHY_RESTART_AUTONEGO | QD_PHY_AUTONEGO);

    DBG_INFO(("Write to phy(%d) register: regAddr 0x%x, data %#x",
              hwPort,QD_PHY_CONTROL_REG,u16Data));

    /* Write to Phy Control Register.  */
    retVal = hwWritePhyReg(dev,hwPort,QD_PHY_CONTROL_REG,u16Data);
	gtSemGive(dev,dev->phyRegsSem);

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

/*******************************************************************************
* gprtSetPortDuplexMode
*
* DESCRIPTION:
* 		Sets duplex mode for a specific logical port. This function will keep 
*		the speed and loopback mode to the previous value, but disable others,
*		such as Autonegotiation.
*
* INPUTS:
*		port -	The logical port number, unless SERDES device is accessed
*				The physical address, if SERDES device is accessed
* 		dMode	- dulpex mode
*
* OUTPUTS:
* 		None.
*
* RETURNS:
* 		GT_OK 	- on success
* 		GT_FAIL 	- on error
*
* COMMENTS:
* 		data sheet register 0.8 - Duplex Mode
*
*******************************************************************************/
GT_STATUS gprtSetPortDuplexMode
(
IN GT_QD_DEV *dev,
IN GT_LPORT  port,
IN GT_BOOL   dMode
)
{
    GT_U8           hwPort;         /* the physical port number     */
    GT_U16 			u16Data;
	GT_STATUS		retVal;

    DBG_INFO(("gprtSetPortDuplexMode Called.\n"));
    
    /* translate LPORT to hardware port */
    hwPort = GT_LPORT_2_PHY(port);

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

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

    if(hwReadPhyReg(dev,hwPort,QD_PHY_CONTROL_REG,&u16Data) != GT_OK)
	{
        DBG_INFO(("Not able to read Phy Reg(port:%d,offset:%d).\n",hwPort,QD_PHY_CONTROL_REG));
		gtSemGive(dev,dev->phyRegsSem);
        return GT_FAIL;
	}

	if(dMode)
	{
		u16Data = (u16Data & (QD_PHY_LOOPBACK | QD_PHY_SPEED | QD_PHY_SPEED_MSB)) | QD_PHY_DUPLEX;
	}
	else
	{
		u16Data = u16Data & (QD_PHY_LOOPBACK | QD_PHY_SPEED | QD_PHY_SPEED_MSB);
	}


    DBG_INFO(("Write to phy(%d) register: regAddr 0x%x, data %#x",
              hwPort,QD_PHY_CONTROL_REG,u16Data));

    /* Write to Phy Control Register.  */
	retVal = hwPhyReset(dev,hwPort,u16Data);
	gtSemGive(dev,dev->phyRegsSem);
	return retVal;
}
/*******************************************************************************
* gprtPortGetDuplexMode
*
* DESCRIPTION:
* 		Gets duplex mode for a specific logical port. 
*
* INPUTS:
*		port -	The logical port number, unless SERDES device is accessed
*				The physical address, if SERDES device is accessed
*
* 		dMode	- dulpex mode
*
* RETURNS:
* 		GT_OK 	- on success
* 		GT_FAIL 	- on error
*
* COMMENTS:
* 		data sheet register 0.8 - duplex mode
*
*******************************************************************************/
GT_STATUS gprtGetPortDuplexMode
(
IN GT_QD_DEV *dev,
IN GT_LPORT  port,
OUT GT_BOOL*   dMode
)
{
    GT_STATUS   retVal;         /* Functions return value.      */
    GT_U8           hwPort;        /* the physical port number   */
    GT_U16 			u16Data;

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

    if(dMode == NULL)
    {
		DBG_INFO(("Input point state equals NULL which is illegal,  return\n"));
    }
    
    /* translate LPORT to hardware port */
    hwPort = GT_LPORT_2_PHY(port);

    gtSemTake(dev,dev->phyRegsSem,OS_WAIT_FOREVER);
    
    /* check if the port is configurable */
    if(!IS_CONFIGURABLE_PHY(dev,hwPort))
    {
    	gtSemGive(dev,dev->phyRegsSem);
    	return GT_NOT_SUPPORTED;
    }
    
    if((retVal=hwGetPhyRegField(dev,hwPort,QD_PHY_CONTROL_REG,8,1,&u16Data)) != GT_OK)
    {
		DBG_INFO(("Failed.\n"));
		gtSemGive(dev,dev->phyRegsSem);
		return retVal;
    }
    
    BIT_2_BOOL(u16Data, *dMode);
    
    gtSemGive(dev,dev->phyRegsSem);
    return GT_OK;
}

/*******************************************************************************
* gprtSetPortSpeedDuplexMode
*
* DESCRIPTION:
* 		Sets speed and duplex mode for a specific logical port. This function
*		will keep the loopback mode to the previous value, but disable others,
*		such as Autonegotiation.
*
* INPUTS:
*		port -	The logical port number, unless SERDES device is accessed
*				The physical address, if SERDES device is accessed
*		speed - port speed.
*				PHY_SPEED_10_MBPS for 10Mbps
*				PHY_SPEED_100_MBPS for 100Mbps
*				PHY_SPEED_1000_MBPS for 1000Mbps
*		dMode - Duplex mode
*
* OUTPUTS:
* None.
*
* RETURNS:
* GT_OK - on success
* GT_FAIL - on error
*
* COMMENTS:
* data sheet register 0.13 - Speed Selection (LSB)
* data sheet register 0.6  - Speed Selection (MSB)
* data sheet register 0.8  - Duplex mode
*******************************************************************************/
GT_STATUS gprtSetPortSpeedDuplexMode
(
IN GT_QD_DEV *dev,
IN GT_LPORT  port,
IN GT_PHY_SPEED speed,
IN GT_BOOL dMode
)
{
	GT_U8           hwPort;         /* the physical port number     */
	GT_U16 		u16Data;
	GT_PHY_INFO	phyInfo;
	GT_STATUS	retVal;

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

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

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

	/* check if the port is configurable */
	if((phyInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_NOT_SUPPORTED;
	}

	if(driverFindPhyInformation(dev,hwPort,&phyInfo) != GT_OK)
	{
	    DBG_INFO(("Unknown PHY device.\n"));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

	if(hwReadPhyReg(dev,hwPort,QD_PHY_CONTROL_REG,&u16Data) != GT_OK)
	{
		DBG_INFO(("Not able to read Phy Reg(port:%d,offset:%d).\n",hwPort,QD_PHY_CONTROL_REG));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

	/* Set Duplex mode */
	if (dMode)
		u16Data = u16Data | QD_PHY_DUPLEX;
	else
		u16Data = u16Data & (~QD_PHY_DUPLEX);

	switch(speed)
	{
		case PHY_SPEED_10_MBPS:
			if ((phyInfo.flag & GT_PHY_GIGABIT) && !(phyInfo.flag & GT_PHY_COPPER))
			{
				gtSemGive(dev,dev->phyRegsSem);
				return GT_BAD_PARAM;
			}
			u16Data = u16Data & (QD_PHY_LOOPBACK | QD_PHY_DUPLEX);
			break;
		case PHY_SPEED_100_MBPS:
			u16Data = (u16Data & (QD_PHY_LOOPBACK | QD_PHY_DUPLEX)) | QD_PHY_SPEED;
			break;
		case PHY_SPEED_1000_MBPS:
			if (!(phyInfo.flag & GT_PHY_GIGABIT))
			{
				gtSemGive(dev,dev->phyRegsSem);
				return GT_BAD_PARAM;
			}
			u16Data = (u16Data & (QD_PHY_LOOPBACK | QD_PHY_DUPLEX)) | QD_PHY_SPEED_MSB;
			break;
		default:
			gtSemGive(dev,dev->phyRegsSem);
			return GT_FAIL;
	}

	DBG_INFO(("Write to phy(%d) register: regAddr 0x%x, data %#x",
		 hwPort,QD_PHY_CONTROL_REG,u16Data));

	retVal = hwPhyReset(dev,hwPort,u16Data);
	gtSemGive(dev,dev->phyRegsSem);
	return retVal;
}

/*******************************************************************************
* gprtSetPortAutoMode
*
* DESCRIPTION:
* 		This routine sets up the port with given Auto Mode.
*		Supported mode is as follows:
*		- Auto for both speed and duplex.
*		- Auto for speed only and Full duplex.
*		- Auto for speed only and Half duplex.
*		- Auto for duplex only and speed 1000Mbps.
*		- Auto for duplex only and speed 100Mbps.
*		- Auto for duplex only and speed 10Mbps.
*		- Speed 1000Mbps and Full duplex.
*		- Speed 1000Mbps and Half duplex.
*		- Speed 100Mbps and Full duplex.
*		- Speed 100Mbps and Half duplex.
*		- Speed 10Mbps and Full duplex.
*		- Speed 10Mbps and Half duplex.
*		
*
* INPUTS:
*		port -	The logical port number, unless SERDES device is accessed
*				The physical address, if SERDES device is accessed
* 		mode - Auto Mode to be written
*
* OUTPUTS:
*		None.
*
* RETURNS:
*		GT_OK   - on success
*		GT_FAIL - on error
*		GT_NOT_SUPPORTED - on device without copper
*
* COMMENTS:
* 		data sheet register 4.8, 4.7, 4.6, and 4.5 Autonegotiation Advertisement
* 		data sheet register 4.6, 4.5 Autonegotiation Advertisement for 1000BX
* 		data sheet register 9.9, 9.8 Autonegotiation Advertisement for 1000BT
*******************************************************************************/

GT_STATUS gprtSetPortAutoMode
(
	IN GT_QD_DEV *dev,
	IN GT_LPORT  port,
	IN GT_PHY_AUTO_MODE mode
)
{

	GT_STATUS       retVal;         /* Functions return value.      */
	GT_U8           hwPort;         /* the physical port number     */
	GT_PHY_INFO		phyInfo;

	DBG_INFO(("gprtSetPortAutoMode Called.\n"));
    
	/* translate LPORT to hardware port */
	hwPort = GT_LPORT_2_PHY(port);

	retVal = GT_NOT_SUPPORTED;

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

	/* check if the port is configurable */
	if((phyInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_NOT_SUPPORTED;
	}

	if(driverFindPhyInformation(dev,hwPort,&phyInfo) != GT_OK)
	{
	    DBG_INFO(("Unknown PHY device.\n"));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

	retVal = phySetAutoMode(dev,hwPort,&phyInfo,mode);

	gtSemGive(dev,dev->phyRegsSem);
	return retVal;

}

/*******************************************************************************
* gprtGetPortAutoMode
*
* DESCRIPTION:
*         This routine get Auto Mode of specific port.
*        Supported mode is as follows:
*        - Auto for both speed and duplex.
*        - Auto for speed only and Full duplex.
*        - Auto for speed only and Half duplex.
*        - Auto for duplex only and speed 1000Mbps.
*        - Auto for duplex only and speed 100Mbps.
*        - Auto for duplex only and speed 10Mbps.
*        - Speed 1000Mbps and Full duplex.
*        - Speed 1000Mbps and Half duplex.
*        - Speed 100Mbps and Full duplex.
*        - Speed 100Mbps and Half duplex.
*        - Speed 10Mbps and Full duplex.
*        - Speed 10Mbps and Half duplex.
*        
*
* INPUTS:
*        port -    The logical port number, unless SERDES device is accessed
*                  The physical address, if SERDES device is accessed  
*
* OUTPUTS:
*        mode -    Auto Mode to be written
*
* RETURNS:
*        GT_OK   - on success
*        GT_FAIL - on error
*        GT_NOT_SUPPORTED - on device without copper
*
* COMMENTS:
*         data sheet register 4.8, 4.7, 4.6, and 4.5 Autonegotiation Advertisement
*         data sheet register 4.6, 4.5 Autonegotiation Advertisement for 1000BX
*         data sheet register 9.9, 9.8 Autonegotiation Advertisement for 1000BT
*******************************************************************************/

GT_STATUS gprtGetPortAutoMode
(
    IN  GT_QD_DEV        *dev,
    IN  GT_LPORT         port,
    OUT GT_PHY_AUTO_MODE *mode
)
{
    GT_STATUS       retVal; /* Functions return value.  */
    GT_U8           hwPort; /* the physical port number */
    GT_PHY_INFO     phyInfo;

    DBG_INFO(("gprtGetPortAutoMode Called.\n"));
    
    /* translate LPORT to hardware port */
    hwPort = GT_LPORT_2_PHY(port);

    retVal = GT_NOT_SUPPORTED;

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

    /* check if the port is configurable */
    if((phyInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
    {
        gtSemGive(dev,dev->phyRegsSem);
        return GT_NOT_SUPPORTED;
    }

    if(driverFindPhyInformation(dev,hwPort,&phyInfo) != GT_OK)
    {
        DBG_INFO(("Unknown PHY device.\n"));
        gtSemGive(dev,dev->phyRegsSem);
        return GT_FAIL;
    }

    retVal = phyGetAutoMode(dev,hwPort,&phyInfo,mode);

    gtSemGive(dev,dev->phyRegsSem);
    return retVal;

}

/*******************************************************************************
* gprtSetPause
*
* DESCRIPTION:
*       This routine will set the pause bit in Autonegotiation Advertisement
*		Register. And restart the autonegotiation.
*
* INPUTS:
*		port -	The logical port number, unless SERDES device is accessed
*				The physical address, if SERDES device is accessed
*		state - GT_PHY_PAUSE_MODE enum value.
*				GT_PHY_NO_PAUSE		- disable pause
* 				GT_PHY_PAUSE		- support pause
*				GT_PHY_ASYMMETRIC_PAUSE	- support asymmetric pause
*				GT_PHY_BOTH_PAUSE	- support both pause and asymmetric pause
*
* OUTPUTS:
*       None.
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
* COMMENTS:
* data sheet register 4.10 Autonegotiation Advertisement Register
*******************************************************************************/

GT_STATUS gprtSetPause
(
IN GT_QD_DEV *dev,
IN GT_LPORT  port,
IN GT_PHY_PAUSE_MODE state
)
{
	GT_U8           hwPort;         /* the physical port number     */
	GT_U16 			u16Data,regStart;
	GT_STATUS		retVal = GT_OK;
	GT_PHY_INFO		phyInfo;

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

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

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

	/* check if the port is configurable */
	if((phyInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_NOT_SUPPORTED;
	}

	regStart = 10;

	if(state & GT_PHY_ASYMMETRIC_PAUSE)
	{
		if(driverFindPhyInformation(dev,hwPort,&phyInfo) != GT_OK)
		{
	    	DBG_INFO(("Unknown PHY device.\n"));
			gtSemGive(dev,dev->phyRegsSem);
			return GT_FAIL;
		}

		if (!(phyInfo.flag & GT_PHY_GIGABIT))
		{
			DBG_INFO(("Not Supported\n"));
			gtSemGive(dev,dev->phyRegsSem);
			return GT_BAD_PARAM;
		}

		if(!(phyInfo.flag & GT_PHY_COPPER))
		{
			regStart = 7;
		}

	}

	u16Data = state;

	/* Write to Phy AutoNegotiation Advertisement Register.  */
	if((retVal=hwSetPhyRegField(dev,hwPort,QD_PHY_AUTONEGO_AD_REG,(GT_U8)regStart,2,u16Data)) != GT_OK)
	{
		DBG_INFO(("Not able to write Phy Reg(port:%d,offset:%d).\n",hwPort,QD_PHY_AUTONEGO_AD_REG));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

	/* Restart auto negotiation.  */
       if(hwReadPhyReg(dev,hwPort,QD_PHY_CONTROL_REG,&u16Data) != GT_OK)
	{
        	DBG_INFO(("Not able to read Phy Reg(port:%d,offset:%d).\n",hwPort,QD_PHY_CONTROL_REG));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

	u16Data |= (QD_PHY_RESTART_AUTONEGO);

    DBG_INFO(("Write to phy(%d) register: regAddr 0x%x, data %#x",
              hwPort,QD_PHY_CONTROL_REG,u16Data));

    /* Write to Phy Control Register.  */
    retVal = hwWritePhyReg(dev,hwPort,QD_PHY_CONTROL_REG,u16Data);
	gtSemGive(dev,dev->phyRegsSem);

    if(retVal != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
    }
    else
    {
        DBG_INFO(("OK.\n"));
    }
	
	gtSemGive(dev,dev->phyRegsSem);
	
	return retVal;
}

/*******************************************************************************
* gprtGetPause
*
* DESCRIPTION:
*       This routine will get the pause bit in Autonegotiation Advertisement
*		Register.
*
* INPUTS:
*		port -	The logical port number, unless SERDES device is accessed
*				The physical address, if SERDES device is accessed
*
*
* OUTPUTS:
*		state - GT_PHY_PAUSE_MODE enum value.
*				GT_PHY_NO_PAUSE		- disable pause
* 				GT_PHY_PAUSE		- support pause
*				GT_PHY_ASYMMETRIC_PAUSE	- support asymmetric pause
*				GT_PHY_BOTH_PAUSE	- support both pause and asymmetric pause
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
* COMMENTS:
* data sheet register 4.10 Autonegotiation Advertisement Register
*******************************************************************************/
GT_STATUS gprtGetPause
(
IN GT_QD_DEV *dev,
IN GT_LPORT  port,
OUT  GT_PHY_PAUSE_MODE *state
)
{
	GT_U8           hwPort;         /* the physical port number     */
	GT_U16 			u16Data,regStart;
	GT_STATUS		retVal = GT_OK;
	GT_PHY_INFO		phyInfo;

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

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

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

	/* check if the port is configurable */
	if((phyInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_NOT_SUPPORTED;
	}

	regStart = 10;

	/* Read Phy AutoNegotiation Advertisement Register.  */
	if((retVal=hwGetPhyRegField(dev,hwPort,QD_PHY_AUTONEGO_AD_REG,(GT_U8)regStart,2,&u16Data)) != GT_OK)
	{
		DBG_INFO(("Not able to write Phy Reg(port:%d,offset:%d).\n",hwPort,QD_PHY_AUTONEGO_AD_REG));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

	gtSemGive(dev,dev->phyRegsSem);

	*state = u16Data;
	
	return retVal;
}

static
GT_STATUS dteWorkAround_Phy100M
(
    IN  GT_QD_DEV *dev,
    IN  GT_U8            hwPort
)
{
	GT_STATUS status = GT_OK;
	GT_U32 threshold[] = {0x000B,0x0000,0x8780,0x0000,0x8F80,0x0000,
						  0x9780,0x0000,0x9F80,0x0000,0xA780,0x0000,
						  0xAF80,0x0000,0xB780,0x0000,0xBF80,0x0000,
						  0xC780,0x0000,0xCF80,0x0000,0xD780,0x0000,
						  0xDF80,0x0000,0xE780,0x0000,0xEF80,0x0000,
						  0xF780,0x0000,0xFF80,0x0000};
	int i, thresholdSize;

	/* force r125 clock */
	if((status= hwWritePhyReg(dev,hwPort,0x1D,0x0003)) != GT_OK)
	{
		return status;
	}
	if((status= hwWritePhyReg(dev,hwPort,0x1E,0x807f)) != GT_OK)
	{
		return status;
	}

	/* write thresholds */
	if((status= hwWritePhyReg(dev,hwPort,0x1D,0x000B)) != GT_OK)
	{
		return status;
	}

	thresholdSize = sizeof(threshold)/sizeof(GT_U32);

	for(i=0; i<thresholdSize; i++)
	{
		if((status= hwWritePhyReg(dev,hwPort,0x1E,(GT_U16)threshold[i])) != GT_OK)
		{
			return status;
		}
	}

	/* setting adc Masking */
	if((status= hwWritePhyReg(dev,hwPort,0x1D,0x0001)) != GT_OK)
	{
		return status;
	}
	if((status= hwWritePhyReg(dev,hwPort,0x1E,0x4000)) != GT_OK)
	{
		return status;
	}

	/* setting noise level */
	if((status= hwWritePhyReg(dev,hwPort,0x1D,0x0005)) != GT_OK)
	{
		return status;
	}
	if((status= hwWritePhyReg(dev,hwPort,0x1E,0xA000)) != GT_OK)
	{
		return status;
	}

	/* 
		offseting cable length measurement by 6.72m(2*4*0.84m)
		set 30_10.14:11 to 0x1001 for cable length measure.
	*/ 
	if((status= hwWritePhyReg(dev,hwPort,0x1D,0x000a)) != GT_OK)
	{
		return status;
	}
	if((status= hwWritePhyReg(dev,hwPort,0x1E,0x4840)) != GT_OK)
	{
		return status;
	}

	/* release force r125 clock */
	if((status= hwWritePhyReg(dev,hwPort,0x1D,0x0003)) != GT_OK)
	{
		return status;
	}
	if((status= hwWritePhyReg(dev,hwPort,0x1E,0x0000)) != GT_OK)
	{
		return status;
	}


	return status;
}

static
GT_STATUS dteWorkAround_Phy1000M
(
    IN  GT_QD_DEV *dev,
    IN  GT_U8            hwPort
)
{
	GT_STATUS status = GT_OK;
	GT_U32 threshold[] = {0x0000,0x8780,0x0000,0x8F80,0x0000,0x9780,
						  0x0000,0x9F80,0x0000,0xA780,0x0000,0xAF80,
						  0x0000,0xB780,0x0000,0xBF80,0x0000,0xC780,
						  0x0000,0xCF80,0x0000,0xD780,0x0000,0xDF80,
						  0x0000,0xE780,0x0000,0xEF80,0x0000,0xF780,
						  0x0000,0xFF80,0x0000};
	int i, thresholdSize;

	/*  */
	if((status= hwWritePhyReg(dev,hwPort,0x1D,0x001B)) != GT_OK)
	{
		return status;
	}
	if((status= hwWritePhyReg(dev,hwPort,0x1E,0x43FF)) != GT_OK)
	{
		return status;
	}

	/*  */
	if((status= hwWritePhyReg(dev,hwPort,0x1D,0x001C)) != GT_OK)
	{
		return status;
	}
	if((status= hwWritePhyReg(dev,hwPort,0x1E,0x9999)) != GT_OK)
	{
		return status;
	}

	/*  */
	if((status= hwWritePhyReg(dev,hwPort,0x1D,0x001F)) != GT_OK)
	{
		return status;
	}
	if((status= hwWritePhyReg(dev,hwPort,0x1E,0xE00C)) != GT_OK)
	{
		return status;
	}

	/*  */
	if((status= hwWritePhyReg(dev,hwPort,0x1D,0x0018)) != GT_OK)
	{
		return status;
	}
	if((status= hwWritePhyReg(dev,hwPort,0x1E,0xFFA1)) != GT_OK)
	{
		return status;
	}

	/* write thresholds */
	if((status= hwWritePhyReg(dev,hwPort,0x1D,0x0010)) != GT_OK)
	{
		return status;
	}

	thresholdSize = sizeof(threshold)/sizeof(GT_U32);

	for(i=0; i<thresholdSize; i++)
	{
		if((status= hwWritePhyReg(dev,hwPort,0x1E,(GT_U16)threshold[i])) != GT_OK)
		{
			return status;
		}
	}

	return status;
}

static
GT_STATUS feSetDTE
(
    IN  GT_QD_DEV *dev,
    IN  GT_U8     hwPort,
	IN  GT_BOOL   state
)
{
	GT_U16 			u16Data;
	GT_STATUS		retVal = GT_OK;

	if((retVal = hwReadPhyReg(dev,hwPort,0x10,&u16Data)) != GT_OK)
	{
		return retVal;
	}

	u16Data = state?(u16Data|0x8000):(u16Data&(~0x8000));

	if((retVal = hwWritePhyReg(dev,hwPort,0x10,u16Data)) != GT_OK)
	{
		return retVal;
	}

	/* soft reset */
	if((retVal = hwPhyReset(dev,hwPort,0xFF)) != GT_OK)
	{
		return retVal;
	}

	return retVal;
}

static
GT_STATUS gigSetDTE
(
    IN  GT_QD_DEV *dev,
    IN  GT_U8     hwPort,
	IN  GT_BOOL   state
)
{
	GT_U16 			u16Data;
	GT_STATUS		retVal = GT_OK;

	if((retVal = hwReadPhyReg(dev,hwPort,20,&u16Data)) != GT_OK)
	{
		return retVal;
	}

	u16Data = state?(u16Data|0x4):(u16Data&(~0x4));

	if((retVal = hwWritePhyReg(dev,hwPort,20,u16Data)) != GT_OK)
	{
		return retVal;
	}

	/* soft reset */
	if((retVal = hwPhyReset(dev,hwPort,0xFF)) != GT_OK)
	{
		return retVal;
	}

	return retVal;
}

static
GT_STATUS gigMPSetDTE
(
    IN  GT_QD_DEV *dev,
    IN  GT_U8     hwPort,
	IN  GT_BOOL   state
)
{
	GT_U16 			u16Data;
	GT_STATUS		retVal = GT_OK;

	if((retVal = hwReadPagedPhyReg(dev,hwPort,0,26,0,&u16Data)) != GT_OK)
	{
		return retVal;
	}

	u16Data = state?(u16Data|0x100):(u16Data&(~0x100));

	if((retVal = hwWritePagedPhyReg(dev,hwPort,0,26,0,u16Data)) != GT_OK)
	{
		return retVal;
	}

	/* soft reset */
	if((retVal = hwPhyReset(dev,hwPort,0xFF)) != GT_OK)
	{
		return retVal;
	}

	return retVal;
}

/*******************************************************************************
* gprtSetDTEDetect
*
* DESCRIPTION:
*       This routine enables/disables DTE.
*
* INPUTS:
* 		port - The logical port number
* 		mode - either GT_TRUE(for enable) or GT_FALSE(for disable)
*
* OUTPUTS:
*       None.
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*
* COMMENTS:
*
*******************************************************************************/

GT_STATUS gprtSetDTEDetect
(
	IN GT_QD_DEV *dev,
	IN GT_LPORT  port,
	IN GT_BOOL   state
)
{
	GT_U8           hwPort;         /* the physical port number     */
	GT_STATUS		retVal = GT_OK;
	GT_PHY_INFO	phyInfo;
	GT_BOOL			autoOn;
	GT_U16			pageReg;

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

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

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

	/* check if the port is configurable */
	if((phyInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_NOT_SUPPORTED;
	}

	/* check if the port supports DTE */
	if(driverFindPhyInformation(dev,hwPort,&phyInfo) != GT_OK)
	{
	    DBG_INFO(("Unknown PHY device.\n"));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

	if (!(phyInfo.flag & GT_PHY_DTE_CAPABLE))
	{
		DBG_INFO(("Not Supported\n"));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_NOT_SUPPORTED;
	}

	switch(phyInfo.dteType)
	{
		case GT_PHY_DTE_TYPE1:
			/* FE Phy needs work-around */
			if((retVal = feSetDTE(dev,hwPort,state)) != GT_OK)
			{
				gtSemGive(dev,dev->phyRegsSem);
				return retVal;
			}

			if(state == GT_FALSE)
				break;

			if((retVal = dteWorkAround_Phy100M(dev,hwPort)) != GT_OK)
			{
				gtSemGive(dev,dev->phyRegsSem);
				return retVal;
			}
			break;
		case GT_PHY_DTE_TYPE3:
			/* Gigabit Phy with work-around required */
			if((retVal = gigSetDTE(dev,hwPort,state)) != GT_OK)
			{
				gtSemGive(dev,dev->phyRegsSem);
				return retVal;
			}

			if(state == GT_FALSE)
				break;

			if((retVal = dteWorkAround_Phy1000M(dev,hwPort)) != GT_OK)
			{
				gtSemGive(dev,dev->phyRegsSem);
				return retVal;
			}
			break;

		case GT_PHY_DTE_TYPE2:
			/* no workaround required */
			if((retVal = gigSetDTE(dev,hwPort,state)) != GT_OK)
			{
				gtSemGive(dev,dev->phyRegsSem);
				return retVal;
			}

			break;
		case GT_PHY_DTE_TYPE4:
			/* no workaround required */
			if(driverPagedAccessStart(dev,hwPort,phyInfo.pageType,&autoOn,&pageReg) != GT_OK)
			{
				gtSemGive(dev,dev->phyRegsSem);
				return GT_FAIL;
			}

			if((retVal = gigMPSetDTE(dev,hwPort,state)) != GT_OK)
			{
				gtSemGive(dev,dev->phyRegsSem);
				return retVal;
			}

			if(driverPagedAccessStop(dev,hwPort,phyInfo.pageType,autoOn,pageReg) != GT_OK)
			{
				gtSemGive(dev,dev->phyRegsSem);
				return GT_FAIL;
			}
			break;
		case GT_PHY_DTE_TYPE5:
			/* FE Phy */
			if((retVal = feSetDTE(dev,hwPort,state)) != GT_OK)
			{
				gtSemGive(dev,dev->phyRegsSem);
				return retVal;
			}
			break;

		default:
			gtSemGive(dev,dev->phyRegsSem);
			return GT_NOT_SUPPORTED;
	}

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


/*******************************************************************************
* gprtGetDTEDetectStatus
*
* DESCRIPTION:
*       This routine gets DTE status.
*
* INPUTS:
* 		port - The logical port number
*
* OUTPUTS:
*       status - GT_TRUE, if link partner needs DTE power.
*				 GT_FALSE, otherwise.
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*
* COMMENTS:
*
*******************************************************************************/

GT_STATUS gprtGetDTEDetectStatus
(
	IN  GT_QD_DEV *dev,
	IN  GT_LPORT  port,
	OUT GT_BOOL   *state
)
{
	GT_U8           hwPort;         /* the physical port number     */
	GT_U16 			u16Data,pageReg;
	GT_STATUS		retVal = GT_OK;
	GT_PHY_INFO	phyInfo;
	GT_BOOL			autoOn;

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

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

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

	/* check if the port is configurable */
	if((phyInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_NOT_SUPPORTED;
	}

	/* check if the port supports DTE */
	if(driverFindPhyInformation(dev,hwPort,&phyInfo) != GT_OK)
	{
	    DBG_INFO(("Unknown PHY device.\n"));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

	if (!(phyInfo.flag & GT_PHY_DTE_CAPABLE))
	{
		DBG_INFO(("Not Supported\n"));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_NOT_SUPPORTED;
	}

	switch(phyInfo.dteType)
	{
		case GT_PHY_DTE_TYPE1:
			/* FE Phy needs work-around */
			if((retVal = hwReadPhyReg(dev,hwPort,17,&u16Data)) != GT_OK)
			{
				gtSemGive(dev,dev->phyRegsSem);
				return retVal;
			}
			*state = (u16Data & 0x8000)?GT_TRUE:GT_FALSE;

			break;
		case GT_PHY_DTE_TYPE2:
		case GT_PHY_DTE_TYPE3:
			if((retVal = hwReadPhyReg(dev,hwPort,27,&u16Data)) != GT_OK)
			{
				gtSemGive(dev,dev->phyRegsSem);
				return retVal;
			}
			*state = (u16Data & 0x10)?GT_TRUE:GT_FALSE;
			
			break;
		case GT_PHY_DTE_TYPE4:
			if(driverPagedAccessStart(dev,hwPort,phyInfo.pageType,&autoOn,&pageReg) != GT_OK)
			{
				gtSemGive(dev,dev->phyRegsSem);
				return GT_FAIL;
			}
				
			if((retVal = hwReadPagedPhyReg(dev,hwPort,0,17,phyInfo.anyPage,&u16Data)) != GT_OK)
			{
				gtSemGive(dev,dev->phyRegsSem);
				return retVal;
			}
			*state = (u16Data & 0x4)?GT_TRUE:GT_FALSE;

			if(driverPagedAccessStop(dev,hwPort,phyInfo.pageType,autoOn,pageReg) != GT_OK)
			{
				gtSemGive(dev,dev->phyRegsSem);
				return GT_FAIL;
			}

			break;
		default:
			gtSemGive(dev,dev->phyRegsSem);
			return GT_NOT_SUPPORTED;
	}

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


/*******************************************************************************
* gprtSetDTEDetectDropWait
*
* DESCRIPTION:
*       Once the PHY no longer detects that the link partner filter, the PHY
*		will wait a period of time before clearing the power over Ethernet 
*		detection status bit. The wait time is 5 seconds multiplied by the 
*		given value.
*
* INPUTS:
* 		port - The logical port number
*       waitTime - 0 ~ 15 (unit of 4 sec.)
*
* OUTPUTS:
*		None.
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*
* COMMENTS:
*
*******************************************************************************/

GT_STATUS gprtSetDTEDetectDropWait
(
	IN  GT_QD_DEV *dev,
	IN  GT_LPORT  port,
	IN  GT_U16    waitTime
)
{
	GT_U8           hwPort;         /* the physical port number     */
	GT_U16 			u16Data;
	GT_STATUS		retVal = GT_OK;
	GT_PHY_INFO	phyInfo;
	GT_BOOL			autoOn;
	GT_U16			pageReg;

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

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

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

	/* check if the port is configurable */
	if((phyInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_NOT_SUPPORTED;
	}

	/* check if the port supports DTE */
	if(driverFindPhyInformation(dev,hwPort,&phyInfo) != GT_OK)
	{
	    DBG_INFO(("Unknown PHY device.\n"));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

	if (!(phyInfo.flag & GT_PHY_DTE_CAPABLE))
	{
		DBG_INFO(("Not Supported\n"));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_NOT_SUPPORTED;
	}

	switch(phyInfo.dteType)
	{
		case GT_PHY_DTE_TYPE1:
			if((retVal = hwReadPhyReg(dev,hwPort,22,&u16Data)) != GT_OK)
			{
				gtSemGive(dev,dev->phyRegsSem);
				return retVal;
			}
			u16Data = (u16Data & ~(0xF<<12)) | ((waitTime & 0xF) << 12);

			if((retVal = hwWritePhyReg(dev,hwPort,22,u16Data)) != GT_OK)
			{
				gtSemGive(dev,dev->phyRegsSem);
				return retVal;
			}
			break;
		case GT_PHY_DTE_TYPE2:
		case GT_PHY_DTE_TYPE3:
			if((retVal = hwReadPhyReg(dev,hwPort,27,&u16Data)) != GT_OK)
			{
				gtSemGive(dev,dev->phyRegsSem);
				return retVal;
			}
			u16Data = (u16Data & ~(0xF<<5)) | ((waitTime & 0xF) << 5);

			if((retVal = hwWritePhyReg(dev,hwPort,27,u16Data)) != GT_OK)
			{
				gtSemGive(dev,dev->phyRegsSem);
				return retVal;
			}
			
			break;
		case GT_PHY_DTE_TYPE4:
			if(driverPagedAccessStart(dev,hwPort,phyInfo.pageType,&autoOn,&pageReg) != GT_OK)
			{
				gtSemGive(dev,dev->phyRegsSem);
				return GT_FAIL;
			}

			if((retVal = hwReadPagedPhyReg(dev,hwPort,0,26,phyInfo.anyPage,&u16Data)) != GT_OK)
			{
				gtSemGive(dev,dev->phyRegsSem);
				return retVal;
			}
			u16Data = (u16Data & ~(0xF<<4)) | ((waitTime & 0xF) << 4);
			if((retVal = hwWritePagedPhyReg(dev,hwPort,0,26,phyInfo.anyPage,u16Data)) != GT_OK)
			{
				gtSemGive(dev,dev->phyRegsSem);
				return retVal;
			}

			if(driverPagedAccessStop(dev,hwPort,phyInfo.pageType,autoOn,pageReg) != GT_OK)
			{
				gtSemGive(dev,dev->phyRegsSem);
				return GT_FAIL;
			}

			break;
		default:
			gtSemGive(dev,dev->phyRegsSem);
			return GT_NOT_SUPPORTED;
	}

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


/*******************************************************************************
* gprtGetDTEDetectDropWait
*
* DESCRIPTION:
*       Once the PHY no longer detects that the link partner filter, the PHY
*		will wait a period of time before clearing the power over Ethernet 
*		detection status bit. The wait time is 5 seconds multiplied by the 
*		returned value.
*
* INPUTS:
* 		port - The logical port number
*
* OUTPUTS:
*       waitTime - 0 ~ 15 (unit of 4 sec.)
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*
* COMMENTS:
*
*******************************************************************************/

GT_STATUS gprtGetDTEDetectDropWait
(
	IN  GT_QD_DEV *dev,
	IN  GT_LPORT  port,
	OUT GT_U16    *waitTime
)
{
	GT_U8           hwPort;         /* the physical port number     */
	GT_U16 			u16Data;
	GT_STATUS		retVal = GT_OK;
	GT_PHY_INFO	phyInfo;
	GT_BOOL			autoOn;
	GT_U16			pageReg;

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

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

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

	/* check if the port is configurable */
	if((phyInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_NOT_SUPPORTED;
	}

	if(driverFindPhyInformation(dev,hwPort,&phyInfo) != GT_OK)
	{
	    DBG_INFO(("Unknown PHY device.\n"));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

	if (!(phyInfo.flag & GT_PHY_DTE_CAPABLE))
	{
		DBG_INFO(("Not Supported\n"));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_NOT_SUPPORTED;
	}

	switch(phyInfo.dteType)
	{
		case GT_PHY_DTE_TYPE1:
			if((retVal = hwReadPhyReg(dev,hwPort,22,&u16Data)) != GT_OK)
			{
				gtSemGive(dev,dev->phyRegsSem);
				return retVal;
			}
			u16Data = (u16Data >> 12) & 0xF;

			break;
		case GT_PHY_DTE_TYPE2:
		case GT_PHY_DTE_TYPE3:
			if((retVal = hwReadPhyReg(dev,hwPort,27,&u16Data)) != GT_OK)
			{
				gtSemGive(dev,dev->phyRegsSem);
				return retVal;
			}
			u16Data = (u16Data >> 5) & 0xF;

			break;
		case GT_PHY_DTE_TYPE4:
			if(driverPagedAccessStart(dev,hwPort,phyInfo.pageType,&autoOn,&pageReg) != GT_OK)
			{
				gtSemGive(dev,dev->phyRegsSem);
				return GT_FAIL;
			}

			if((retVal = hwReadPagedPhyReg(dev,hwPort,0,26,phyInfo.anyPage,&u16Data)) != GT_OK)
			{
				gtSemGive(dev,dev->phyRegsSem);
				return retVal;
			}
			u16Data = (u16Data >> 4) & 0xF;

			if(driverPagedAccessStop(dev,hwPort,phyInfo.pageType,autoOn,pageReg) != GT_OK)
			{
				gtSemGive(dev,dev->phyRegsSem);
				return GT_FAIL;
			}
			break;
		default:
			gtSemGive(dev,dev->phyRegsSem);
			return GT_NOT_SUPPORTED;
	}

	*waitTime = u16Data;

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


/*******************************************************************************
* gprtSetEnergyDetect
*
* DESCRIPTION:
*       Energy Detect power down mode enables or disables the PHY to wake up on
*		its own by detecting activity on the CAT 5 cable. 
*
* INPUTS:
* 		port - The logical port number
*       mode - GT_EDETECT_MODE type
*
* 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 gprtSetEnergyDetect
(
	IN  GT_QD_DEV *dev,
	IN  GT_LPORT  port,
	IN  GT_EDETECT_MODE   mode
)
{
	GT_U8           hwPort;         /* the physical port number     */
	GT_U16 			u16Data;
	GT_STATUS		retVal = GT_OK;
	GT_PHY_INFO	phyInfo;
	GT_BOOL			autoOn;
	GT_U16			pageReg;

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

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

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

	/* check if the port is configurable */
	if((phyInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_NOT_SUPPORTED;
	}

	if(driverFindPhyInformation(dev,hwPort,&phyInfo) != GT_OK)
	{
	    DBG_INFO(("Unknown PHY device.\n"));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

	if (phyInfo.flag & GT_PHY_SERDES_CORE)
	{
	    DBG_INFO(("Not Supported.\n"));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_NOT_SUPPORTED;
	}
	else if (phyInfo.flag & GT_PHY_GIGABIT)
	{
		/* check if the mode is valid */
		switch (mode)
		{
			case GT_EDETECT_OFF:
				u16Data = 0;
				break;
			case GT_EDETECT_SENSE_PULSE:
				u16Data = 3;
				break;
			case GT_EDETECT_SENSE:
				u16Data = 2;
				break;
			default:
			    DBG_INFO(("Invalid paramerter.\n"));
				gtSemGive(dev,dev->phyRegsSem);
				return GT_BAD_PARAM;
		}

		if(driverPagedAccessStart(dev,hwPort,phyInfo.pageType,&autoOn,&pageReg) != GT_OK)
		{
			gtSemGive(dev,dev->phyRegsSem);
			return GT_FAIL;
		}

		if((retVal = hwSetPagedPhyRegField(dev,hwPort,0,0x10,8,2,phyInfo.anyPage,u16Data)) != GT_OK)
		{
			gtSemGive(dev,dev->phyRegsSem);
			return retVal;
		}

		if((retVal = hwPhyReset(dev,hwPort,0xFF)) != GT_OK)
		{
			gtSemGive(dev,dev->phyRegsSem);
			return retVal;
		}

		if(driverPagedAccessStop(dev,hwPort,phyInfo.pageType,autoOn,pageReg) != GT_OK)
		{
			gtSemGive(dev,dev->phyRegsSem);
			return GT_FAIL;
		}
	}
	else	/* it's a Fast Ethernet device */
	{
		/* check if the mode is valid */
		switch (mode)
		{
			case GT_EDETECT_OFF:
				u16Data = 0;
				break;
			case GT_EDETECT_SENSE_PULSE:
				u16Data = 1;
				break;
			case GT_EDETECT_SENSE:
			default:
			    DBG_INFO(("Invalid paramerter.\n"));
				gtSemGive(dev,dev->phyRegsSem);
				return GT_BAD_PARAM;
		}

		if((retVal = hwSetPhyRegField(dev,hwPort,0x10,14,1,u16Data)) != GT_OK)
		{
			gtSemGive(dev,dev->phyRegsSem);
			return retVal;
		}
	}

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


/*******************************************************************************
* gprtGetEnergyDetect
*
* DESCRIPTION:
*       Energy Detect power down mode enables or disables the PHY to wake up on
*		its own by detecting activity on the CAT 5 cable. 
*
* INPUTS:
* 		port - The logical port number
*
* OUTPUTS:
*       mode - GT_EDETECT_MODE type
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*       GT_NOT_SUPPORTED - if current device does not support this feature.
*
* COMMENTS:
*
*******************************************************************************/

GT_STATUS gprtGetEnergyDetect
(
	IN  GT_QD_DEV *dev,
	IN  GT_LPORT  port,
	OUT GT_EDETECT_MODE   *mode
)
{
	GT_U8           hwPort;         /* the physical port number     */
	GT_U16 			u16Data;
	GT_STATUS		retVal = GT_OK;
	GT_PHY_INFO	phyInfo;
	GT_BOOL			autoOn;
	GT_U16			pageReg;

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

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

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

	/* check if the port is configurable */
	if((phyInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_NOT_SUPPORTED;
	}

	if(driverFindPhyInformation(dev,hwPort,&phyInfo) != GT_OK)
	{
	    DBG_INFO(("Unknown PHY device.\n"));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

	if (phyInfo.flag & GT_PHY_SERDES_CORE)
	{
	    DBG_INFO(("Not Supported.\n"));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_NOT_SUPPORTED;
	}
	else if (phyInfo.flag & GT_PHY_GIGABIT)
	{
		/* read the mode */

		if(driverPagedAccessStart(dev,hwPort,phyInfo.pageType,&autoOn,&pageReg) != GT_OK)
		{
			gtSemGive(dev,dev->phyRegsSem);
			return GT_FAIL;
		}

		if((retVal = hwGetPagedPhyRegField(dev,hwPort,0,0x10,8,2,phyInfo.anyPage,&u16Data)) != GT_OK)
		{
			gtSemGive(dev,dev->phyRegsSem);
			return retVal;
		}

		if(driverPagedAccessStop(dev,hwPort,phyInfo.pageType,autoOn,pageReg) != GT_OK)
		{
			gtSemGive(dev,dev->phyRegsSem);
			return GT_FAIL;
		}

		switch (u16Data)
		{
			case 0:
			case 1:
				*mode = GT_EDETECT_OFF;
				break;
			case 2:
				*mode = GT_EDETECT_SENSE;
				break;
			case 3:
				*mode = GT_EDETECT_SENSE_PULSE;
				break;
			default:
			    DBG_INFO(("Unknown value (shouldn't happen).\n"));
				gtSemGive(dev,dev->phyRegsSem);
				return GT_FAIL;
		}

	}
	else	/* it's a Fast Ethernet device */
	{
		/* read the mode */
		if((retVal = hwGetPhyRegField(dev,hwPort,0x10,14,1,&u16Data)) != GT_OK)
		{
			gtSemGive(dev,dev->phyRegsSem);
			return retVal;
		}

		switch (u16Data)
		{
			case 0:
				*mode = GT_EDETECT_OFF;
				break;
			case 1:
				*mode = GT_EDETECT_SENSE_PULSE;
				break;
			default:
			    DBG_INFO(("Unknown value (shouldn't happen).\n"));
				gtSemGive(dev,dev->phyRegsSem);
				return GT_FAIL;
		}

	}


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


/*******************************************************************************
* gprtSet1000TMasterMode
*
* DESCRIPTION:
*       This routine sets the ports 1000Base-T Master mode and restart the Auto
*		negotiation.
*
* INPUTS:
*       port - the logical port number.
*       mode - GT_1000T_MASTER_SLAVE structure
*				autoConfig   - GT_TRUE for auto, GT_FALSE for manual setup.
*				masterPrefer - GT_TRUE if Master configuration is preferred.
*
* OUTPUTS:
*       None.
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*
* COMMENTS:
*
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gprtSet1000TMasterMode
(
    IN  GT_QD_DEV   *dev,
    IN  GT_LPORT     port,
    IN  GT_1000T_MASTER_SLAVE   *mode
)
{
	GT_STATUS	retVal;         /* Functions return value.      */
	GT_U8			hwPort;         /* the physical port number     */
	GT_U16		data;
	GT_PHY_INFO	phyInfo;
	GT_BOOL			autoOn;
	GT_U16			pageReg;

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

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

	if (!IS_IN_DEV_GROUP(dev,DEV_GIGABIT_SWITCH))
	{
		return GT_NOT_SUPPORTED;
	}

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

	/* check if the port is configurable */
	if((phyInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_NOT_SUPPORTED;
	}

	if(driverFindPhyInformation(dev,hwPort,&phyInfo) != GT_OK)
	{
	    DBG_INFO(("Unknown PHY device.\n"));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

	if (!(phyInfo.flag & GT_PHY_GIGABIT) || !(phyInfo.flag & GT_PHY_COPPER))
	{
		DBG_INFO(("Not Supported\n"));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_NOT_SUPPORTED;
	}

	if(mode->autoConfig == GT_TRUE)
	{
		if(mode->masterPrefer == GT_TRUE)
		{
			data = 0x1;
		}
		else
		{
			data = 0x0;
		}
	}
	else
	{
		if(mode->masterPrefer == GT_TRUE)
		{
			data = 0x6;
		}
		else
		{
			data = 0x4;
		}
	}

	if(driverPagedAccessStart(dev,hwPort,phyInfo.pageType,&autoOn,&pageReg) != GT_OK)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

	/* Set the Master Mode.    */
	retVal = hwSetPagedPhyRegField(dev,hwPort,0,9,10,3,phyInfo.anyPage,data);
	if(retVal != GT_OK)
	{
		DBG_INFO(("Failed.\n"));
		gtSemGive(dev,dev->phyRegsSem);
		return retVal;
	}
    else
	{
		DBG_INFO(("OK.\n"));
	}

	/* Restart Auto Negotiation */
	if((retVal=hwSetPhyRegField(dev,hwPort,QD_PHY_CONTROL_REG,9,1,1)) != GT_OK)
	{
		DBG_INFO(("Not able to write Phy Reg(port:%d,offset:%d,data:%#x).\n",hwPort,QD_PHY_CONTROL_REG,1));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

	if(driverPagedAccessStop(dev,hwPort,phyInfo.pageType,autoOn,pageReg) != GT_OK)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

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


/*******************************************************************************
* gprtGet1000TMasterMode
*
* DESCRIPTION:
*       This routine retrieves 1000Base-T Master Mode
*
* INPUTS:
*       port - the logical port number.
*
* OUTPUTS:
*       mode - GT_1000T_MASTER_SLAVE structure
*				autoConfig   - GT_TRUE for auto, GT_FALSE for manual setup.
*				masterPrefer - GT_TRUE if Master configuration is preferred.
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*
* COMMENTS:
*
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gprtGet1000TMasterMode
(
    IN  GT_QD_DEV   *dev,
    IN  GT_LPORT     port,
    OUT GT_1000T_MASTER_SLAVE   *mode
)
{
	GT_STATUS	retVal;         /* Functions return value.      */
	GT_U8			hwPort;         /* the physical port number     */
	GT_U16		data;
	GT_PHY_INFO	phyInfo;
	GT_BOOL			autoOn;
	GT_U16			pageReg;

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

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

	if (!IS_IN_DEV_GROUP(dev,DEV_GIGABIT_SWITCH))
	{
		return GT_NOT_SUPPORTED;
	}

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

	/* check if the port is configurable */
	if((phyInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_NOT_SUPPORTED;
	}

	if(driverFindPhyInformation(dev,hwPort,&phyInfo) != GT_OK)
	{
	    DBG_INFO(("Unknown PHY device.\n"));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

	if (!(phyInfo.flag & GT_PHY_GIGABIT) || !(phyInfo.flag & GT_PHY_COPPER))
	{
		DBG_INFO(("Not Supported\n"));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_NOT_SUPPORTED;
	}

	if(driverPagedAccessStart(dev,hwPort,phyInfo.pageType,&autoOn,&pageReg) != GT_OK)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

	/* Set the Master Mode.    */
	retVal = hwGetPagedPhyRegField(dev,hwPort,0,9,10,3,phyInfo.anyPage,&data);
	if(retVal != GT_OK)
	{
		DBG_INFO(("Failed.\n"));
		gtSemGive(dev,dev->phyRegsSem);
		return retVal;
	}
	else
	{
		DBG_INFO(("OK.\n"));
	}

	if(driverPagedAccessStop(dev,hwPort,phyInfo.pageType,autoOn,pageReg) != GT_OK)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

	if(data & 0x4)	/* Manual Mode */
	{
		mode->autoConfig = GT_FALSE;

		if(data & 0x2)
		{
			mode->masterPrefer = GT_TRUE;
		}
		else
		{
			mode->masterPrefer = GT_FALSE;
		}
	}
	else	/* Auto Mode */
	{
		mode->autoConfig = GT_TRUE;

		if(data & 0x1)
		{
			mode->masterPrefer = GT_TRUE;
		}
		else
		{
			mode->masterPrefer = GT_FALSE;
		}
	}

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

/*******************************************************************************
* gprtGetPhyLinkStatus
*
* DESCRIPTION:
*       This routine retrieves the Link status.
*
* INPUTS:
*		port -	The logical port number, unless SERDES device is accessed
*				The physical address, if SERDES device is accessed
*
* OUTPUTS:
*       linkStatus - GT_FALSE if link is not established,
*				     GT_TRUE if link is established.
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*		
*
* COMMENTS:
*
*******************************************************************************/
GT_STATUS gprtGetPhyLinkStatus
(
	IN GT_QD_DEV *dev,
	IN GT_LPORT  port,
    IN GT_BOOL 	 *linkStatus
)
{

    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U8           hwPort;         /* the physical port number     */
    GT_U16 			u16Data;
	GT_PHY_INFO		phyInfo;

    DBG_INFO(("gprtGetPhyLinkStatus Called.\n"));
    
    /* translate LPORT to hardware port */
    hwPort = GT_LPORT_2_PHY(port);

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

	/* check if the port is configurable */
	if((phyInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
	{
		gtSemGive(dev,dev->phyRegsSem);
	 	return GT_NOT_SUPPORTED;
	}

	if((retVal=hwGetPhyRegField(dev,hwPort,17,10,1,&u16Data)) != GT_OK)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return retVal;
	}

	BIT_2_BOOL(u16Data,*linkStatus);

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


/*******************************************************************************
* gprtSetPktGenEnable
*
* DESCRIPTION:
*       This routine enables or disables Packet Generator.
*       Link should be established first prior to enabling the packet generator,
*       and generator will generate packets at the speed of the established link.
*		When enables packet generator, the following information should be 
*       provided:
*           Payload Type:  either Random or 5AA55AA5
*           Packet Length: either 64 or 1514 bytes
*           Error Packet:  either Error packet or normal packet
*
* INPUTS:
*		port -	The logical port number, unless SERDES device is accessed
*				The physical address, if SERDES device is accessed
*       en      - GT_TRUE to enable, GT_FALSE to disable
*       pktInfo - packet information(GT_PG structure pointer), if en is GT_TRUE.
*                 ignored, if en is GT_FALSE
*
* OUTPUTS:
*       None.
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*		
*
* COMMENTS:
*
*******************************************************************************/
GT_STATUS gprtSetPktGenEnable
(
	IN GT_QD_DEV *dev,
	IN GT_LPORT  port,
    IN GT_BOOL   en,
    IN GT_PG     *pktInfo
)
{

    GT_STATUS       retVal;         /* Functions return value.      */
    GT_U8           hwPort;         /* the physical port number     */
    GT_U16 			data;
	GT_BOOL			link;
	GT_PHY_INFO		phyInfo;
	GT_U8			page,reg, offset, len;
	GT_BOOL			autoOn;
	GT_U16			pageReg;

    DBG_INFO(("gprtSetPktGenEnable Called.\n"));
    
    /* translate LPORT to hardware port */
    hwPort = GT_LPORT_2_PHY(port);

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

	/* check if the port is configurable */
	if((phyInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_NOT_SUPPORTED;
	}

	if(driverFindPhyInformation(dev,hwPort,&phyInfo) != GT_OK)
	{
	    DBG_INFO(("Unknown PHY device.\n"));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

	if(!(phyInfo.flag & GT_PHY_PKT_GENERATOR))
	{
	    DBG_INFO(("Not Supported.\n"));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_NOT_SUPPORTED;
	}

	switch (phyInfo.pktGenType)
	{
		case GT_PHY_PKTGEN_TYPE1:	/* 30_18.5:2 */
				page = 18;
				reg = 30;
				offset = 2;
				break;
		case GT_PHY_PKTGEN_TYPE2:	/* 16_6.3:0 */
				page = 6;
				reg = 16;
				offset = 0;
				break;
		case GT_PHY_PKTGEN_TYPE3:	/* 25.3:0 */
				page = 0;
				reg = 25;
				offset = 0;
				break;
		default:
			    DBG_INFO(("Unknown PKTGEN Type.\n"));
				gtSemGive(dev,dev->phyRegsSem);
				return GT_FAIL;
	}

	if (en)
	{
		if((retVal = gprtGetPhyLinkStatus(dev,port,&link)) != GT_OK)
		{
			gtSemGive(dev,dev->phyRegsSem);
			return GT_FAIL;
		}
	
		if (link == GT_FALSE)
		{
		    DBG_INFO(("Link should be on to run Packet Generator.\n"));
			gtSemGive(dev,dev->phyRegsSem);
			return GT_FAIL;
		}

		data = 0x8;

        if (pktInfo->payload == GT_PG_PAYLOAD_5AA5)
            data |= 0x4;

        if (pktInfo->length == GT_PG_LENGTH_1514)
            data |= 0x2;

        if (pktInfo->tx == GT_PG_TX_ERROR)
            data |= 0x1;

        len = 4;
	}
	else
	{
		data = 0;
		len = 1;
		offset += 3;
	}

	if(driverPagedAccessStart(dev,hwPort,phyInfo.pageType,&autoOn,&pageReg) != GT_OK)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

	if((retVal=hwSetPagedPhyRegField(dev,hwPort,
				page,reg,offset,len,phyInfo.anyPage,data)) != GT_OK)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return retVal;
	}

	if(driverPagedAccessStop(dev,hwPort,phyInfo.pageType,autoOn,pageReg) != GT_OK)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

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


/*******************************************************************************
* gprtGetSerdesMode
*
* DESCRIPTION:
*       This routine reads Serdes Interface Mode.
*
* INPUTS:
*		port -	The physical SERDES device address
*				(logical port number is also supported for backward comparibility)
*
* OUTPUTS:
*       mode    - Serdes Interface Mode
*
* RETURNS:
*       GT_OK           - on success
*       GT_FAIL         - on error
*
* COMMENTS:
*       logical port number is supported only for the devices made production 
*		before 2009. (88E6131, 88E6122, 88E6108, 88E6161, and 88E6165)
*
*******************************************************************************/
GT_STATUS gprtGetSerdesMode
(
    IN  GT_QD_DEV    *dev,
    IN  GT_LPORT     port,
	IN  GT_SERDES_MODE *mode
)
{
    GT_U16          u16Data;           /* The register's read data.    */
    GT_U8           hwPort;         /* the physical port number     */

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

	if(!IS_IN_DEV_GROUP(dev,DEV_SERDES_CORE))
	{
		return GT_NOT_SUPPORTED;
	}

	/* check if input is logical port number */	
    hwPort = GT_LPORT_2_PORT(port);
	GT_GET_SERDES_PORT(dev,&hwPort);

	if(hwPort > dev->maxPhyNum)
	{
		/* check if input is physical serdes address */	
		if(dev->validSerdesVec & (1<<port))
		{
			hwPort = (GT_U8)port;
		}
		else
			return GT_NOT_SUPPORTED;
	}

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

    /* Get Phy Register. */
    if(hwGetPhyRegField(dev,hwPort,16,0,2,&u16Data) != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
		gtSemGive(dev,dev->phyRegsSem);
        return GT_FAIL;
    }

	*mode = u16Data;

	gtSemGive(dev,dev->phyRegsSem);
    return GT_OK;
}


/*******************************************************************************
* gprtSetSerdesMode
*
* DESCRIPTION:
*       This routine sets Serdes Interface Mode.
*
* INPUTS:
*		port -	The physical SERDES device address
*				(logical port number is also supported for backward comparibility)
*       mode    - Serdes Interface Mode
*
* OUTPUTS:
*		None.
*
* RETURNS:
*       GT_OK           - on success
*       GT_FAIL         - on error
*
* COMMENTS:
*       logical port number is supported only for the devices made production 
*		before 2009. (88E6131, 88E6122, 88E6108, 88E6161, and 88E6165)
*
*******************************************************************************/
GT_STATUS gprtSetSerdesMode
(
    IN  GT_QD_DEV    *dev,
    IN  GT_LPORT     port,
	IN  GT_SERDES_MODE mode
)
{
    GT_U16          u16Data;           /* The register's read data.    */
    GT_U8           hwPort;         /* the physical port number     */
	GT_STATUS		retVal;

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

	if(!IS_IN_DEV_GROUP(dev,DEV_SERDES_CORE))
	{
		return GT_NOT_SUPPORTED;
	}
	
	/* check if input is logical port number */	
    hwPort = GT_LPORT_2_PORT(port);
	GT_GET_SERDES_PORT(dev,&hwPort);

	if(hwPort > dev->maxPhyNum)
	{
		/* check if input is physical serdes address */	
		if(dev->validSerdesVec & (1<<port))
		{
			hwPort = (GT_U8)port;
		}
		else
			return GT_NOT_SUPPORTED;
	}

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

	u16Data = mode;

    /* Get Phy Register. */
    if(hwSetPhyRegField(dev,hwPort,16,0,2,u16Data) != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
		gtSemGive(dev,dev->phyRegsSem);
        return GT_FAIL;
    }

	retVal = hwPhyReset(dev,hwPort,0xFF);
	gtSemGive(dev,dev->phyRegsSem);
	return retVal;
}


/*******************************************************************************
* gprtGetPhyReg
*
* DESCRIPTION:
*       This routine reads Phy Registers.
*
* INPUTS:
*		port -	The logical port number, unless SERDES device is accessed
*				The physical address, if SERDES device is accessed
*       regAddr - The register's address.
*
* OUTPUTS:
*       data    - The read register's data.
*
* RETURNS:
*       GT_OK           - on success
*       GT_FAIL         - on error
*
* COMMENTS:
*       None.
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gprtGetPhyReg
(
    IN  GT_QD_DEV    *dev,
    IN  GT_LPORT     port,
    IN  GT_U32	     regAddr,
    OUT GT_U16	     *data
)
{
    GT_U16          u16Data;           /* The register's read data.    */
    GT_U8           hwPort;         /* the physical port number     */

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

    hwPort = GT_LPORT_2_PHY(port);

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

    /* Get Phy Register. */
    if(hwReadPhyReg(dev,hwPort,(GT_U8)regAddr,&u16Data) != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
		gtSemGive(dev,dev->phyRegsSem);
        return GT_FAIL;
    }

	*data = u16Data;

	gtSemGive(dev,dev->phyRegsSem);
    return GT_OK;
}

/*******************************************************************************
* gprtSetPhyReg
*
* DESCRIPTION:
*       This routine writes Phy Registers.
*
* INPUTS:
*		port -	The logical port number, unless SERDES device is accessed
*				The physical address, if SERDES device is accessed
*       regAddr - The register's address.
*
* OUTPUTS:
*       data    - The read register's data.
*
* RETURNS:
*       GT_OK           - on success
*       GT_FAIL         - on error
*
* COMMENTS:
*       None.
*
* GalTis:
*
*******************************************************************************/
GT_STATUS gprtSetPhyReg
(
    IN  GT_QD_DEV		*dev,
    IN  GT_LPORT		port,
    IN  GT_U32			regAddr,
    IN  GT_U16			data
)
{
    GT_U8           hwPort;         /* the physical port number     */
    
    DBG_INFO(("gprtSetPhyReg Called.\n"));

    hwPort = GT_LPORT_2_PHY(port);

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

    /* Write to Phy Register */
    if(hwWritePhyReg(dev,hwPort,(GT_U8)regAddr,data) != GT_OK)
    {
        DBG_INFO(("Failed.\n"));
		gtSemGive(dev,dev->phyRegsSem);
        return GT_FAIL;
    }

	gtSemGive(dev,dev->phyRegsSem);
	return GT_OK;
}



/*******************************************************************************
* gprtGetPagedPhyReg
*
* DESCRIPTION:
*       This routine reads phy register of the given page
*
* INPUTS:
*		port 	- logical port to be read
*		regAddr	- register offset to be read
*		page	- page number to be read
*
* OUTPUTS:
*		data	- value of the read register
*
* RETURNS:
*       GT_OK   			- if read successed
*       GT_FAIL   			- if read failed
*
* COMMENTS:
*       None.
*
*******************************************************************************/
GT_STATUS gprtGetPagedPhyReg
(
    IN  GT_QD_DEV *dev,
    IN  GT_U32  port,
	IN	GT_U32  regAddr,
	IN	GT_U32  page,
    OUT GT_U16* data
)
{
	GT_PHY_INFO		phyInfo;
	GT_BOOL			autoOn;
	GT_U16			pageReg;
	GT_U8			hwPort;

    hwPort = GT_LPORT_2_PHY(port);
	
	gtSemTake(dev,dev->phyRegsSem,OS_WAIT_FOREVER);

	/* check if the port is configurable */
	if((phyInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_NOT_SUPPORTED;
	}

	if(driverFindPhyInformation(dev,hwPort,&phyInfo) != GT_OK)
	{
	    DBG_INFO(("Unknown PHY device.\n"));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

	if(driverPagedAccessStart(dev,hwPort,phyInfo.pageType,&autoOn,&pageReg) != GT_OK)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

	if(hwReadPagedPhyReg(dev,hwPort,(GT_U8)page,
								(GT_U8)regAddr,0,data) != GT_OK)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

	if(driverPagedAccessStop(dev,hwPort,phyInfo.pageType,autoOn,pageReg) != GT_OK)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

	gtSemGive(dev,dev->phyRegsSem);
	return GT_OK;
}

/*******************************************************************************
* gprtSetPagedPhyReg
*
* DESCRIPTION:
*       This routine writes a value to phy register of the given page
*
* INPUTS:
*		port 	- logical port to be read
*		regAddr	- register offset to be read
*		page	- page number to be read
*		data	- value of the read register
*
* OUTPUTS:
*		None
*
* RETURNS:
*       GT_OK   			- if read successed
*       GT_FAIL   			- if read failed
*
* COMMENTS:
*       None.
*
*******************************************************************************/
GT_STATUS gprtSetPagedPhyReg
(
    IN  GT_QD_DEV *dev,
    IN  GT_U32 port,
	IN	GT_U32 regAddr,
	IN	GT_U32 page,
    IN  GT_U16 data
)
{
	GT_PHY_INFO		phyInfo;
	GT_BOOL			autoOn;
	GT_U16			pageReg;
	GT_U8			hwPort;

    hwPort = GT_LPORT_2_PHY(port);

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

	/* check if the port is configurable */
	if((phyInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_NOT_SUPPORTED;
	}

	if(driverFindPhyInformation(dev,hwPort,&phyInfo) != GT_OK)
	{
	    DBG_INFO(("Unknown PHY device.\n"));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

	if(driverPagedAccessStart(dev,hwPort,phyInfo.pageType,&autoOn,&pageReg) != GT_OK)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

	if(hwWritePagedPhyReg(dev,hwPort,(GT_U8)page,
								(GT_U8)regAddr,0,data) != GT_OK)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

	if(driverPagedAccessStop(dev,hwPort,phyInfo.pageType,autoOn,pageReg) != GT_OK)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

	gtSemGive(dev,dev->phyRegsSem);
	return GT_OK;
}



