#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"));
		return GT_BAD_PARAM;
    }
    
    /* 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"));
		return GT_BAD_PARAM;
    }
    
    /* 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;
}



