#include <Copyright.h>
/*******************************************************************************
* gtVct.c
*
* DESCRIPTION:
*       API for Marvell Virtual Cable Tester.
*
* DEPENDENCIES:
*       None.
*
* FILE REVISION NUMBER:
*       $Revision: 1 $
*******************************************************************************/
#include <msApi.h>
#include <gtVct.h>
#include <gtDrvConfig.h>
#include <gtDrvSwRegs.h>
#include <gtHwCntl.h>
#include <gtSem.h>



/*******************************************************************************
* analizePhy100MVCTResult
*
* DESCRIPTION:
*       This routine analize the virtual cable test result for 10/100M Phy
*
* INPUTS:
*       regValue - test result
*
* OUTPUTS:
*       cableStatus - analized test result.
*       cableLen    - cable length or the distance where problem occurs.
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*
* COMMENTS:
*       None.
*
* GalTis:
*
*******************************************************************************/
static
GT_STATUS analizePhy100MVCTResult
(
    IN  GT_QD_DEV *dev,
    IN  GT_U16 regValue, 
    OUT GT_TEST_STATUS *cableStatus,
    OUT GT_CABLE_LEN *cableLen
)
{
	int len;

	GT_UNUSED_PARAM(dev);

	switch((regValue & 0x6000) >> 13)
	{
		case 0:
			/* test passed. No problem found. */
			/* check if there is impedance mismatch */
			if ((regValue & 0xFF) == 0xFF)
			{
				*cableStatus = GT_NORMAL_CABLE;
				cableLen->normCableLen = GT_UNKNOWN_LEN;
			}
			else
			{
				*cableStatus = GT_IMPEDANCE_MISMATCH;
				len = (int)FORMULA_PHY100M(regValue & 0xFF);
				if(len <= 0)
					cableLen->errCableLen = 0;
				else
					cableLen->errCableLen = (GT_U8)len;
			}
				
			break;
		case 1:
			/* test passed. Cable is short. */
			*cableStatus = GT_SHORT_CABLE;
			len = (int)FORMULA_PHY100M(regValue & 0xFF);
			if(len <= 0)
				cableLen->errCableLen = 0;
			else
				cableLen->errCableLen = (GT_U8)len;
			break;
		case 2:
			/* test passed. Cable is open. */
			*cableStatus = GT_OPEN_CABLE;
			len = (int)FORMULA_PHY100M(regValue & 0xFF);
			if(len <= 0)
				cableLen->errCableLen = 0;
			else
				cableLen->errCableLen = (GT_U8)len;
			break;
		case 3:
		default:
			/* test failed. No result is valid. */
			*cableStatus = GT_TEST_FAIL;
			break;
	}

	return GT_OK;
}


/*******************************************************************************
* getCableStatus_Phy100M
*
* DESCRIPTION:
*       This routine perform the virtual cable test for the 10/100Mbps phy,
*       and returns the the status per Rx/Tx pair.
*
* INPUTS:
*       port - logical port number.
*
* OUTPUTS:
*       cableStatus - the port copper cable status.
*       cableLen    - the port copper cable length.
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*
* COMMENTS:
*       None.
*
* GalTis:
*
*******************************************************************************/
static 
GT_STATUS getCableStatus_Phy100M
(
    IN  GT_QD_DEV *dev,
    IN  GT_U8            hwPort,
    OUT GT_CABLE_STATUS *cableStatus
)
{
	GT_STATUS status;
	GT_U16 reg26, reg27;

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

	/* 
	 * 	phy should be in 100 Full Duplex.
	 */
	if((status= hwWritePhyReg(dev,hwPort,0,QD_PHY_RESET | QD_PHY_SPEED | QD_PHY_DUPLEX)) != GT_OK)
	{
		return status;
	}

	/* 
	 * start Virtual Cable Tester
	 */
	if((status= hwWritePhyReg(dev,hwPort,26,0x8000)) != GT_OK)
	{
		return status;
	}

	do
	{
		if((status= hwReadPhyReg(dev,hwPort,26,&reg26)) != GT_OK)
		{
			return status;
		}
		
	} while(reg26 & 0x8000);

	/*
	 * read the test result for RX Pair
	 */
	if((status= hwReadPhyReg(dev,hwPort,26,&reg26)) != GT_OK)
	{
		return status;
	}
		
	/*
	 * read the test result for TX Pair
	 */
	if((status= hwReadPhyReg(dev,hwPort,27,&reg27)) != GT_OK)
	{
		return status;
	}
		
	cableStatus->phyType = PHY_100M;

	/*
	 * analyze the test result for RX Pair
	 */
	analizePhy100MVCTResult(dev, reg26, &cableStatus->cableStatus[MDI_RX_PAIR], 
							&cableStatus->cableLen[MDI_RX_PAIR]);

	/*
	 * analyze the test result for TX Pair
	 */
	analizePhy100MVCTResult(dev, reg27, &cableStatus->cableStatus[MDI_TX_PAIR], 
							&cableStatus->cableLen[MDI_TX_PAIR]);

	return status;
}

static
GT_STATUS  enable1stWorkAround_Phy100M
(
    IN  GT_QD_DEV *dev,
    IN  GT_U8     hwPort
)
{
    GT_U16      value;
    GT_STATUS   status;

    /* enable 1st work-around */
    if ((status = hwWritePhyReg(dev, hwPort, 29, 3)) != GT_OK)
       return status;

    value = 0x6440;
    if ((status = hwWritePhyReg(dev, hwPort, 30, value)) != GT_OK)
       return status;

    return GT_OK;
}

static
GT_STATUS  disable1stWorkAround_Phy100M
(
    IN  GT_QD_DEV *dev,
    IN  GT_U8     hwPort
)
{
    GT_STATUS status;

    /* disable 1st work-around */
    if ((status = hwWritePhyReg(dev, hwPort, 29, 3)) != GT_OK)
       return status;

    if ((status = hwWritePhyReg(dev, hwPort, 30, 0)) != GT_OK)
       return status;

    return GT_OK;
}

static
GT_STATUS workAround_Phy100M
(
    IN  GT_QD_DEV *dev,
    IN  GT_U8            hwPort,
    OUT GT_CABLE_STATUS *cableStatus
)
{
	GT_STATUS status = GT_OK;

	/* 
	 * If Cable Status is OPEN and the length is less than 15m,
	 * then apply Work Around.
	 */

	if((cableStatus->cableStatus[MDI_RX_PAIR] == GT_OPEN_CABLE) ||
		(cableStatus->cableStatus[MDI_TX_PAIR] == GT_OPEN_CABLE))
	{
		/* must be disabled first and then enable again */
        disable1stWorkAround_Phy100M(dev,hwPort);

        enable1stWorkAround_Phy100M(dev,hwPort);

		if((status= hwWritePhyReg(dev,hwPort,29,0x000A)) != GT_OK)
		{
			return status;
		}
		if((status= hwWritePhyReg(dev,hwPort,30,0x0002)) != GT_OK)
		{
			return status;
		}

		if((status = getCableStatus_Phy100M(dev,hwPort,cableStatus)) != GT_OK)
		{
			return status;
		}
		
		if((status= hwWritePhyReg(dev,hwPort,29,0x000A)) != GT_OK)
		{
			return status;
		}
		if((status= hwWritePhyReg(dev,hwPort,30,0x0000)) != GT_OK)
		{
			return status;
		}
	}

	return status;
}


static
GT_STATUS  enable1stWorkAround_Phy1000M
(
    IN  GT_QD_DEV *dev,
    IN  GT_U8     hwPort
)
{
    GT_STATUS   status;

    /* enable 1st work-around */
    if ((status = hwWritePhyReg(dev, hwPort, 29, 0x0018)) != GT_OK)
       return status;

    if ((status = hwWritePhyReg(dev, hwPort, 30, 0x00c2)) != GT_OK)
       return status;

    if ((status = hwWritePhyReg(dev, hwPort, 30, 0x00ca)) != GT_OK)
       return status;

    if ((status = hwWritePhyReg(dev, hwPort, 30, 0x00c2)) != GT_OK)
       return status;

    return GT_OK;
}

static
GT_STATUS  disable1stWorkAround_Phy1000M
(
    IN  GT_QD_DEV *dev,
    IN  GT_U8     hwPort
)
{
    GT_STATUS status;

    /* disable 1st work-around */
    if ((status = hwWritePhyReg(dev, hwPort, 29, 0x0018)) != GT_OK)
       return status;

    if ((status = hwWritePhyReg(dev, hwPort, 30, 0x0042)) != GT_OK)
       return status;

    return GT_OK;
}

/*******************************************************************************
* analizePhy1000MVCTResult
*
* DESCRIPTION:
*       This routine analize the virtual cable test result for a Gigabit Phy
*
* INPUTS:
*       reg17 - original value of register 17
*       regValue - test result
*
* OUTPUTS:
*       cableStatus - analized test result.
*       cableLen    - cable length or the distance where problem occurs.
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*
* COMMENTS:
*       None.
*
* GalTis:
*
*******************************************************************************/
static
GT_STATUS analizePhy1000MVCTResult
(
    IN  GT_QD_DEV *dev,
    IN  GT_U16 reg17,
    IN  GT_U16 regValue, 
    OUT GT_TEST_STATUS *cableStatus,
    OUT GT_CABLE_LEN *cableLen
)
{
	GT_U16 u16Data;
	int len;

	GT_UNUSED_PARAM(dev);

	switch((regValue & 0x6000) >> 13)
	{
		case 0:

			/* Check Impedance Mismatch */
			if ((regValue & 0xFF) < 0xFF)
			{
				/*  if the reflected amplitude is low it is good cable too.
					for this registers values it is a good cable:
					0xE23, 0xE24, 0xE25, 0xE26, 0xE27 */
				if ((regValue < 0xE23) || (regValue > 0xE27))
				{
					*cableStatus = GT_IMPEDANCE_MISMATCH;
					len = (int)FORMULA_PHY1000M(regValue & 0xFF);
					if(len <= 0)
						cableLen->errCableLen = 0;
					else
						cableLen->errCableLen = (GT_U8)len;
					break;
				}
			}

			/* test passed. No problem found. */
			*cableStatus = GT_NORMAL_CABLE;

			u16Data = reg17;

			/* To get Cable Length, Link should be on and Speed should be 100M or 1000M */
			if(!(u16Data & 0x0400))
			{
				cableLen->normCableLen = GT_UNKNOWN_LEN;
				break;
			}

			if((u16Data & 0xC000) != 0x8000)
			{
				cableLen->normCableLen = GT_UNKNOWN_LEN;
				break;
			}

			/*
			 * read the test result for the selected MDI Pair
			 */

			u16Data = ((u16Data >> 7) & 0x7);

			switch(u16Data)
			{
				case 0:
					cableLen->normCableLen = GT_LESS_THAN_50M;
					break;
				case 1:
					cableLen->normCableLen = GT_50M_80M;
					break;
				case 2:
					cableLen->normCableLen = GT_80M_110M;
					break;
				case 3:
					cableLen->normCableLen = GT_110M_140M;
					break;
				case 4:
					cableLen->normCableLen = GT_MORE_THAN_140;
					break;
				default:
					cableLen->normCableLen = GT_UNKNOWN_LEN;
					break;
			}
			break;
		case 1:
			/* test passed. Cable is short. */
			*cableStatus = GT_SHORT_CABLE;
			len = (int)FORMULA_PHY1000M(regValue & 0xFF);
			if(len <= 0)
				cableLen->errCableLen = 0;
			else
				cableLen->errCableLen = (GT_U8)len;
			break;
		case 2:
			/* test passed. Cable is open. */
			*cableStatus = GT_OPEN_CABLE;
			len = (int)FORMULA_PHY1000M(regValue & 0xFF);
			if(len <= 0)
				cableLen->errCableLen = 0;
			else
				cableLen->errCableLen = (GT_U8)len;
			break;
		case 3:
		default:
			/* test failed. No result is valid. */
			*cableStatus = GT_TEST_FAIL;
			break;
	}

	return GT_OK;
}


/*******************************************************************************
* getCableStatus_Phy1000M
*
* DESCRIPTION:
*       This routine perform the virtual cable test for the 10/100Mbps phy,
*       and returns the the status per Rx/Tx pair.
*
* INPUTS:
*       port - logical port number.
*		reg17 - original value of reg17.
*
* OUTPUTS:
*       cableStatus - the port copper cable status.
*       cableLen    - the port copper cable length.
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*
* COMMENTS:
*       None.
*
* GalTis:
*
*******************************************************************************/
static 
GT_STATUS getCableStatus_Phy1000M
(	
    IN  GT_QD_DEV *dev,
    IN  GT_U8			hwPort,
    IN  GT_U16 			reg17,
    OUT GT_CABLE_STATUS *cableStatus
)
{
	GT_STATUS status;
	GT_U16 reg28;
	int i;

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

	/* 
	 * start Virtual Cable Tester
	 */
	if((status= hwWritePagedPhyReg(dev,hwPort,0,28,0,0x8000)) != GT_OK)
	{
		return status;
	}

	do
	{
		if((status= hwReadPhyReg(dev,hwPort,28,&reg28)) != GT_OK)
		{
			return status;
		}
		
	} while(reg28 & 0x8000);

	cableStatus->phyType = PHY_1000M;

    DBG_INFO(("Reg28 after test : %0#x.\n", reg28));

	for (i=0; i<GT_MDI_PAIR_NUM; i++)
	{
		/*
		 * read the test result for the selected MDI Pair
		 */
		if((status= hwReadPagedPhyReg(dev,hwPort,(GT_U8)i,28,0,&reg28)) != GT_OK)
		{
			return status;
		}
		
		/*
		 * analyze the test result for RX Pair
		 */
		if((status = analizePhy1000MVCTResult(dev, reg17, reg28, 
								&cableStatus->cableStatus[i], 
								&cableStatus->cableLen[i])) != GT_OK)
		{
			return status;
		}
	}

	return GT_OK;
}

static
GT_STATUS workAround_Phy1000M
(
  GT_QD_DEV *dev,
  GT_U8 hwPort
)
{
	GT_STATUS status;

    DBG_INFO(("workAround for Gigabit Phy Called.\n"));

	if((status = hwWritePhyReg(dev,hwPort,29,0x1e)) != GT_OK)
	{
		return status;
	}
		
	if((status = hwWritePhyReg(dev,hwPort,30,0xcc00)) != GT_OK)
	{
		return status;
	}

	if((status = hwWritePhyReg(dev,hwPort,30,0xc800)) != GT_OK)
	{
		return status;
	}
	if((status = hwWritePhyReg(dev,hwPort,30,0xc400)) != GT_OK)
	{
		return status;
	}
	if((status = hwWritePhyReg(dev,hwPort,30,0xc000)) != GT_OK)
	{
		return status;
	}
	if((status = hwWritePhyReg(dev,hwPort,30,0xc100)) != GT_OK)
	{
		return status;
	}

    DBG_INFO(("workAround for Gigabit Phy completed.\n"));
	return GT_OK;
}


/*******************************************************************************
* getCableStatus_Phy1000MPage
*
* DESCRIPTION:
*       This routine perform the virtual cable test for the 10/100Mbps phy with
*       multiple page mode and returns the the status per MDIP/N.
*
* INPUTS:
*       port - logical port number.
*
* OUTPUTS:
*       cableStatus - the port copper cable status.
*       cableLen    - the port copper cable length.
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*
* COMMENTS:
*       None.
*
* GalTis:
*
*******************************************************************************/
static 
GT_STATUS getCableStatus_Phy1000MPage
(	
    IN  GT_QD_DEV *dev,
    IN  GT_U8			hwPort,
	IN  GT_PHY_INFO		*phyInfo,
    OUT GT_CABLE_STATUS *cableStatus
)
{
	GT_STATUS status;
	GT_U16 u16Data;
	GT_U16 reg17 = 0;
	int i;

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

	/*
	 * If Fiber is used, simply return with test fail.
	 */
	if(phyInfo->flag & GT_PHY_FIBER)
	{
		if((status= hwReadPagedPhyReg(dev,hwPort,1,17,phyInfo->anyPage,&u16Data)) != GT_OK)
		{
			return status;
		}

		if(u16Data & 0x400)
		{
			for (i=0; i<GT_MDI_PAIR_NUM; i++)
			{
				cableStatus->cableStatus[i] = GT_TEST_FAIL;
			}
			return GT_OK;
		}
	}

	/*
	 * If Copper is used and Link is on, get DSP Distance and put it in the
	 * old reg17 format.(bit9:7 with DSP Distance)
	 */
	if((status= hwReadPagedPhyReg(dev,hwPort,0,17,phyInfo->anyPage,&u16Data)) != GT_OK)
	{
		return status;
	}

	if(u16Data & 0x400)
	{
		reg17 = (u16Data & 0xC000) | 0x400;

		if((status= hwReadPagedPhyReg(dev,hwPort,5,26,phyInfo->anyPage,&u16Data)) != GT_OK)
		{
			return status;
		}
		reg17 |= ((u16Data & 0x7) << 7);
	}

	/* 
	 * start Virtual Cable Tester
	 */
	if((status= hwWritePagedPhyReg(dev,hwPort,5,16,phyInfo->anyPage,0x8000)) != GT_OK)
	{
		return status;
	}

	do
	{
		if((status= hwReadPagedPhyReg(dev,hwPort,5,16,phyInfo->anyPage,&u16Data)) != GT_OK)
		{
			return status;
		}
		
	} while(u16Data & 0x8000);

	cableStatus->phyType = PHY_1000M;

    DBG_INFO(("Page 5 of Reg16 after test : %0#x.\n", u16Data));

	for (i=0; i<GT_MDI_PAIR_NUM; i++)
	{
		/*
		 * read the test result for the selected MDI Pair
		 */
		if((status= hwReadPagedPhyReg(dev,hwPort,5,(GT_U8)(16+i),phyInfo->anyPage,&u16Data)) != GT_OK)
		{
			return status;
		}
		
		/*
		 * analyze the test result for RX Pair
		 */
		if((status = analizePhy1000MVCTResult(dev, reg17, u16Data, 
								&cableStatus->cableStatus[i], 
								&cableStatus->cableLen[i])) != GT_OK)
		{
			return status;
		}
	}

	return GT_OK;
}



/*******************************************************************************
* gvctGetCableStatus
*
* DESCRIPTION:
*       This routine perform the virtual cable test for the requested port,
*       and returns the the status per MDI pair.
*
* INPUTS:
*       port - logical port number.
*
* OUTPUTS:
*       cableStatus - the port copper cable status.
*       cableLen    - the port copper cable length.
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*
* COMMENTS:
*       Internal Gigabit Phys in 88E6165 family and 88E6351 family devices
*		are not supported by this API. For those devices, gvctGetAdvCableDiag 
*		API can be used, instead.
*
*******************************************************************************/
GT_STATUS gvctGetCableDiag
(
    IN  GT_QD_DEV *dev,
    IN  GT_LPORT        port,
    OUT GT_CABLE_STATUS *cableStatus
)
{
	GT_STATUS status;
	GT_U8 hwPort;
	GT_U16 orgReg0, orgReg17;
	GT_BOOL ppuEn;
	GT_PHY_INFO	phyInfo;
	GT_BOOL			autoOn;
	GT_U16			pageReg;

    DBG_INFO(("gvctGetCableDiag Called.\n"));
	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 VCT */
	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_VCT_CAPABLE))
	{
		DBG_INFO(("Not Supported\n"));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_NOT_SUPPORTED;
	}

	/* Need to disable PPUEn for safe. */
	if(gsysGetPPUEn(dev,&ppuEn) != GT_OK)
	{
		ppuEn = GT_FALSE;
	}

	if(ppuEn != GT_FALSE)
	{
		if((status= gsysSetPPUEn(dev,GT_FALSE)) != GT_OK)
		{
	    	DBG_INFO(("Not able to disable PPUEn.\n"));
			gtSemGive(dev,dev->phyRegsSem);
			return status;
		}
		gtDelay(250);
	}
		
	if(driverPagedAccessStart(dev,hwPort,phyInfo.pageType,&autoOn,&pageReg) != GT_OK)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

	/*
	 * save original register 17 value, which will be used later depending on
	 * test result.
	 */
	if((status= hwReadPagedPhyReg(dev,hwPort,0,17,phyInfo.anyPage,&orgReg17)) != GT_OK)
	{
	    DBG_INFO(("Not able to reset the Phy.\n"));
		goto cableDiagCleanup;
	}

	/*
	 * save Config Register data
	 */
	if((status= hwReadPagedPhyReg(dev,hwPort,0,0,phyInfo.anyPage,&orgReg0)) != GT_OK)
	{
	    DBG_INFO(("Not able to reset the Phy.\n"));
		goto cableDiagCleanup;
	}

	switch(phyInfo.vctType)
	{
		case GT_PHY_VCT_TYPE1:
			enable1stWorkAround_Phy100M(dev,hwPort);
			status = getCableStatus_Phy100M(dev,hwPort,cableStatus);
            /* every fast ethernet phy requires this work-around */
			workAround_Phy100M(dev,hwPort,cableStatus);
			disable1stWorkAround_Phy100M(dev,hwPort);
			break;
		case GT_PHY_VCT_TYPE2:
			enable1stWorkAround_Phy1000M(dev,hwPort);
			status = getCableStatus_Phy1000M(dev,hwPort,orgReg17,cableStatus);
			disable1stWorkAround_Phy1000M(dev,hwPort);
			break;
		case GT_PHY_VCT_TYPE3:
			enable1stWorkAround_Phy1000M(dev,hwPort);
			workAround_Phy1000M(dev,hwPort);
			status = getCableStatus_Phy1000M(dev,hwPort,orgReg17,cableStatus);
			disable1stWorkAround_Phy1000M(dev,hwPort);
			break;
		case GT_PHY_VCT_TYPE4:
			status = getCableStatus_Phy1000MPage(dev,hwPort,&phyInfo,cableStatus);
			break;
		default:
			status = GT_FAIL;
			break;
	}
	
	if (!(phyInfo.flag & GT_PHY_GIGABIT))
	{
		if((status = hwPhyReset(dev,hwPort,orgReg0)) != GT_OK)
		{
			gtSemGive(dev,dev->phyRegsSem);
			return status;
		}
	}
	else
	{
		/*
		 * restore Config Register Data
		 */
		if((status= hwWritePagedPhyReg(dev,hwPort,0,0,phyInfo.anyPage,orgReg0)) != GT_OK)
		{
			gtSemGive(dev,dev->phyRegsSem);
			return status;
		}

		/* soft reset */
		if((status = hwPhyReset(dev,hwPort,0xFF)) != GT_OK)
		{
			gtSemGive(dev,dev->phyRegsSem);
			return status;
		}
	}

cableDiagCleanup:

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

	if(ppuEn != GT_FALSE)
	{
		if(gsysSetPPUEn(dev,ppuEn) != GT_OK)
		{
	    	DBG_INFO(("Not able to enable PPUEn.\n"));
			status = GT_FAIL;
		}
	}

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


/*******************************************************************************
* getExStatus1000M
*
* DESCRIPTION:
*       This routine retrieves Pair Skew, Pair Swap, and Pair Polarity
*		for 1000M phy
*
* INPUTS:
*       dev - device context.
*       port - logical port number.
*
* OUTPUTS:
*       extendedStatus - extended cable status.
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*
* COMMENTS:
*       None.
*
*******************************************************************************/
static GT_STATUS getExStatus1000M
(
    IN  GT_QD_DEV 		*dev,
    IN  GT_U8           hwPort,
    OUT GT_1000BT_EXTENDED_STATUS *extendedStatus
)
{
	GT_STATUS status;
	GT_U16 u16Data, i;

	/*
	 * get data from 28_5 register
	 */
	if((status= hwReadPagedPhyReg(dev,hwPort,5,28,0,&u16Data)) != GT_OK)
	{
	    DBG_INFO(("Not able to read a Phy register.\n"));
		return status;
	}

	/* if bit 6 is not set, it's not valid. */
	if (!(u16Data & 0x0040))
	{
	    DBG_INFO(("Valid Bit is not set (%0#x).\n", u16Data));
		extendedStatus->isValid = GT_FALSE;
		return GT_OK;
	}

	extendedStatus->isValid = GT_TRUE;
	
	/* get Pair Polarity */
	for(i=0; i<GT_MDI_PAIR_NUM; i++)
	{
		switch((u16Data >> i) & 0x1)
		{
			case 0:
				extendedStatus->pairPolarity[i] = GT_POSITIVE;
				break;
			default:
				extendedStatus->pairPolarity[i] = GT_NEGATIVE;
				break;
		}
	}

	/* get Pair Swap */
	for(i=0; i<GT_CHANNEL_PAIR_NUM; i++)
	{
		switch((u16Data >> (i+4)) & 0x1)
		{
			case 0:
				extendedStatus->pairSwap[i] = GT_STRAIGHT_CABLE;
				break;
			default:
				extendedStatus->pairSwap[i] = GT_CROSSOVER_CABLE;
				break;
		}
	}

	/*
	 * get data from 28_4 register
	 */
	if((status= hwReadPagedPhyReg(dev,hwPort,4,28,0,&u16Data)) != GT_OK)
	{
	    DBG_INFO(("Not able to read a Phy register.\n"));
		return status;
	}

	/* get Pair Skew */
	for(i=0; i<GT_MDI_PAIR_NUM; i++)
	{
		extendedStatus->pairSkew[i] = ((u16Data >> i*4) & 0xF) * 8;
	}

	return GT_OK;
}


/*******************************************************************************
* getExStatus1000MPage
*
* DESCRIPTION:
*       This routine retrieves Pair Skew, Pair Swap, and Pair Polarity
*		for 1000M phy with multiple page mode
*
* INPUTS:
*       dev - device context.
*       port - logical port number.
*
* OUTPUTS:
*       extendedStatus - extended cable status.
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*
* COMMENTS:
*       None.
*
*******************************************************************************/
static GT_STATUS getExStatus1000MPage
(
    IN  GT_QD_DEV 		*dev,
    IN  GT_U8	        hwPort,
    OUT GT_1000BT_EXTENDED_STATUS *extendedStatus
)
{
	GT_STATUS status;
	GT_U16 u16Data, i;

	/*
	 * get data from 21_5 register for pair swap
	 */
	if((status= hwReadPagedPhyReg(dev,hwPort,5,21,0,&u16Data)) != GT_OK)
	{
	    DBG_INFO(("Not able to read a paged Phy register.\n"));
		return status;
	}

	/* if bit 6 is not set, it's not valid. */
	if (!(u16Data & 0x0040))
	{
	    DBG_INFO(("Valid Bit is not set (%0#x).\n", u16Data));
		extendedStatus->isValid = GT_FALSE;
		return GT_OK;
	}

	extendedStatus->isValid = GT_TRUE;
	
	/* get Pair Polarity */
	for(i=0; i<GT_MDI_PAIR_NUM; i++)
	{
		switch((u16Data >> i) & 0x1)
		{
			case 0:
				extendedStatus->pairPolarity[i] = GT_POSITIVE;
				break;
			default:
				extendedStatus->pairPolarity[i] = GT_NEGATIVE;
				break;
		}
	}

	/* get Pair Swap */
	for(i=0; i<GT_CHANNEL_PAIR_NUM; i++)
	{
		switch((u16Data >> (i+4)) & 0x1)
		{
			case 0:
				extendedStatus->pairSwap[i] = GT_STRAIGHT_CABLE;
				break;
			default:
				extendedStatus->pairSwap[i] = GT_CROSSOVER_CABLE;
				break;
		}
	}

	/*
	 * get data from 20_5 register for pair skew
	 */
	if((status= hwReadPagedPhyReg(dev,hwPort,5,20,0,&u16Data)) != GT_OK)
	{
	    DBG_INFO(("Not able to read a paged Phy register.\n"));
		return status;
	}

	/* get Pair Skew */
	for(i=0; i<GT_MDI_PAIR_NUM; i++)
	{
		extendedStatus->pairSkew[i] = ((u16Data >> i*4) & 0xF) * 8;
	}

	return GT_OK;
}


/*******************************************************************************
* gvctGet1000BTExtendedStatus
*
* DESCRIPTION:
*       This routine retrieves Pair Skew, Pair Swap, and Pair Polarity
*
* INPUTS:
*       dev - device context.
*       port - logical port number.
*
* OUTPUTS:
*       extendedStatus - extended cable status.
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*
* COMMENTS:
*       Internal Gigabit Phys in 88E6165 family and 88E6351 family devices
*		are not supported by this API. For those devices, gvctGetAdvExtendedStatus 
*		API can be used, instead.
*
*******************************************************************************/
GT_STATUS gvctGet1000BTExtendedStatus
(
    IN  GT_QD_DEV 		*dev,
    IN  GT_LPORT        port,
    OUT GT_1000BT_EXTENDED_STATUS *extendedStatus
)
{
	GT_STATUS status;
	GT_U8 hwPort;
	GT_BOOL ppuEn;
	GT_PHY_INFO	phyInfo;
	GT_BOOL			autoOn;
	GT_U16			pageReg;

    DBG_INFO(("gvctGetCableDiag Called.\n"));
	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 VCT */
	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_EX_CABLE_STATUS))
	{
		DBG_INFO(("Not Supported\n"));
		gtSemGive(dev,dev->phyRegsSem);
		return GT_NOT_SUPPORTED;
	}

	/* Need to disable PPUEn for safe. */
	if(gsysGetPPUEn(dev,&ppuEn) != GT_OK)
	{
		ppuEn = GT_FALSE;
	}

	if(ppuEn != GT_FALSE)
	{
		if((status= gsysSetPPUEn(dev,GT_FALSE)) != GT_OK)
		{
	    	DBG_INFO(("Not able to disable PPUEn.\n"));
			gtSemGive(dev,dev->phyRegsSem);
			return status;
		}
		gtDelay(250);
	}

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

	switch(phyInfo.vctType)
	{
		case GT_PHY_VCT_TYPE2:
			status = getExStatus1000M(dev,hwPort,extendedStatus);
			break;
		case GT_PHY_VCT_TYPE4:
			status = getExStatus1000MPage(dev,hwPort,extendedStatus);
			break;
		default:
	   		DBG_INFO(("Device is not supporting Extended Cable Status.\n"));
			status = GT_NOT_SUPPORTED;
	}

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

	if(ppuEn != GT_FALSE)
	{
		if(gsysSetPPUEn(dev,ppuEn) != GT_OK)
		{
	    	DBG_INFO(("Not able to enable PPUEn.\n"));
			status = GT_FAIL;
		}
	}

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


