#include <Copyright.h>
/*******************************************************************************
* gtAdvVct.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>

#define GT_LOOKUP_TABLE_ENTRY  128  /* 73 */

#define GT_ADV_VCT_ACCEPTABLE_SHORT_CABLE  11

static  GT_U8 tbl_1181[GT_LOOKUP_TABLE_ENTRY] = 
                    {  2,  4,  8, 14, 18, 20, 25, 30, 33, 36,
                      39, 42, 46, 48, 51, 54, 57, 59, 62, 64,
                      66, 69, 71, 73, 75, 77, 80, 81, 83, 85,
                      87, 88, 90, 93, 95, 97, 98,100,101,103,
                     104,106,106,107,109,110,111,113,114,115,
                     116,118,119,120,121,122,124,125,126,127,
                     128,129,130,131,132,133,134,135,136,137,
                     138,139,140};

static  GT_U8 tbl_1111[GT_LOOKUP_TABLE_ENTRY] = 
                    {  0,  2,  4, 5, 6, 9, 13, 17, 20, 23,
                      27, 30, 33, 35, 38, 41, 43, 46, 48, 51,
                      53, 55, 58, 60, 62, 64, 66, 68, 70, 72,
                      73, 75, 77, 79, 80, 82, 84, 85, 87, 88,
                      90, 91, 93, 94, 96, 97, 98,100,101,102,
                     104,105,106,107,109,110,111,112,113,114,
                     116,117,118,119,120,121,122,123,124,125,
                     126,127,128,129,130,131,132,133,134,134};

static  GT_U8 tbl_1112[GT_LOOKUP_TABLE_ENTRY] =   /* from 17*/
                    {  0,  4,  8, 11, 14, 18, 21, 24, 28, 31, 
					  34, 37, 39, 42, 44, 47, 49, 52, 54, 56, 
					  58, 60, 62, 64, 66, 68, 70, 72, 74, 75, 
					  77, 79, 80, 82, 83, 85, 87, 88, 89, 91, 
					  92, 94, 95, 96, 98, 99,100,101,103,104,
					  105,106,107,108,109,111,112,113,114,115,
					  116,117,118,119,120,121,122,123,124,124,
					  125,126,127,128,129,130,131,131,132,133,
					  134,135,135,136,137,138,139,139,140,141,
					  142,142,143,144,144,145,146,147,147,148};

static  GT_U8 tbl_1116[GT_LOOKUP_TABLE_ENTRY] =   /* from 16*/
                    {  2,  4,  8, 14, 18, 20, 25, 30, 33, 36, 
					  39, 42, 46, 48, 51, 54, 57, 59, 62, 64, 
					  66, 69, 71, 73, 75, 77, 80, 81, 83, 85, 
					  87, 88, 90, 93, 95, 97, 98, 100, 101, 103, 
					  104,106,106,107,109,110,111,113,114,115,
					  116,118,119,120,121,122,124,125,126,127,
					  128,129,130,131,132,133,134,135,136,137,
					  138,139,140};

static  GT_U8 tbl_1240[GT_LOOKUP_TABLE_ENTRY] = 
                    {  1,  2,  5, 10, 13, 15, 18, 22, 26, 30, 
                      33, 35, 38, 40, 43, 45, 48, 51, 53, 55, 
                      58, 60, 63, 65, 68, 69, 70, 71, 73, 75, 
                      77, 79, 80, 81, 82, 83, 85, 87, 88, 90, 
                      91, 92, 93, 95, 97, 98,100,101,102,103,
                     105,106,107,108,109,110,111,112,113,114,
                     115,116,117,118,119,120,121,122,123,124,
                     125,126,127,128,129,130};


/*******************************************************************************
* getDetailedAdvVCTResult
*
* DESCRIPTION:
*		This routine differenciate Open/Short from Impedance mismatch.
*
* INPUTS:
*		amp - amplitude
*		len - distance to fault
*		vctResult - test result 
*					(Impedance mismatch, either > 115 ohms, or < 85 ohms)
*
* OUTPUTS:
*
* RETURNS:
*       GT_ADV_VCT_STATUS
*
* COMMENTS:
*       This routine assumes test result is not normal nor cross pair short.
*
*******************************************************************************/
static
GT_ADV_VCT_STATUS getDetailedAdvVCTResult
(
	IN  GT_U32  devType,
	IN  GT_U32  amp,
	IN  GT_U32  len,
	IN  GT_ADV_VCT_STATUS result
)
{
	GT_ADV_VCT_STATUS vctResult;
	GT_BOOL    update = GT_FALSE;

	DBG_INFO(("getDetailedAdvVCTResult Called.\n"));

	if (devType == GT_PHY_ADV_VCT_TYPE2)
	{
		if(len < 10)
		{
			if(amp > 54)  /* 90 x 0.6 */
				update = GT_TRUE;
		}
		else if(len < 50)
		{
			if(amp > 42) /* 70 x 0.6 */
				update = GT_TRUE;
		}
		else if(len < 110)
		{
			if(amp > 30)  /* 50 x 0.6 */
				update = GT_TRUE;
		}
		else if(len < 140)
		{
			if(amp > 24)  /* 40 x 0.6 */
				update = GT_TRUE;
		}
		else
		{
			if(amp > 18) /* 30 x 0.6 */
				update = GT_TRUE;
		}
	}
	else
	{
		if(len < 10)
		{
			if(amp > 90)  
				update = GT_TRUE;
		}
		else if(len < 50)
		{
			if(amp > 70) 
				update = GT_TRUE;
		}
		else if(len < 110)
		{
			if(amp > 50)  
				update = GT_TRUE;
		}
		else if(len < 140)
		{
			if(amp > 40)  
				update = GT_TRUE;
		}
		else
		{
			if(amp > 30) 
				update = GT_TRUE;
		}
	}


	switch (result)
	{
		case GT_ADV_VCT_IMP_GREATER_THAN_115:
				if(update)
					vctResult = GT_ADV_VCT_OPEN;
				else
					vctResult = result;
				break;
		case GT_ADV_VCT_IMP_LESS_THAN_85:
				if(update)
					vctResult = GT_ADV_VCT_SHORT;
				else
					vctResult = result;
				break;
		default:
				vctResult = result;
				break;
	}

	return vctResult;
}

/*******************************************************************************
* analizeAdvVCTResult
*
* DESCRIPTION:
*		This routine analize the Advanced VCT result.
*
* INPUTS:
*		channel - channel number where test was run
*		crossChannelReg - register values after the test is completed
*		mode    - use formula for normal cable case
*
* OUTPUTS:
*		cableStatus - analized test result.
*
* RETURNS:
*		-1, or distance to fault
*
* COMMENTS:
*		None.
*
*******************************************************************************/
static
GT_16 analizeAdvVCTNoCrosspairResult
(
	IN  GT_U32  devType,
	IN  int     channel, 
	IN  GT_U16 *crossChannelReg, 
	IN  GT_BOOL isShort,
	OUT GT_ADV_CABLE_STATUS *cableStatus
)
{
	int len;
	GT_16 dist2fault;
	GT_ADV_VCT_STATUS vctResult = GT_ADV_VCT_NORMAL;

	DBG_INFO(("analizeAdvVCTNoCrosspairResult Called.\n"));
	DBG_INFO(("analizeAdvVCTNoCrosspairResult chan %d reg data %x\n", channel, crossChannelReg[channel]));

	dist2fault = -1;

	/* check if test is failed */
	if(IS_VCT_FAILED(crossChannelReg[channel]))
	{
		cableStatus->cableStatus[channel] = GT_ADV_VCT_FAIL;
		return dist2fault;
	}

	/* Check if fault detected */
	if(IS_ZERO_AMPLITUDE(crossChannelReg[channel]))
	{
		cableStatus->cableStatus[channel] = GT_ADV_VCT_NORMAL;
		return dist2fault;
	}

	/* find out test result by reading Amplitude */
	if(IS_POSITIVE_AMPLITUDE(crossChannelReg[channel]))
	{
		vctResult = GT_ADV_VCT_IMP_GREATER_THAN_115;
	}
	else
	{
		vctResult = GT_ADV_VCT_IMP_LESS_THAN_85;
	}

	/* 
	 * now, calculate the distance for GT_ADV_VCT_IMP_GREATER_THAN_115 and
	 * GT_ADV_VCT_IMP_LESS_THAN_85
	 */
	switch (vctResult)
	{
		case GT_ADV_VCT_IMP_GREATER_THAN_115:
		case GT_ADV_VCT_IMP_LESS_THAN_85:
			if(!isShort)
			{
				len = (int)GT_ADV_VCT_CALC(crossChannelReg[channel] & 0xFF);
			}
			else
			{
				len = (int)GT_ADV_VCT_CALC_SHORT(crossChannelReg[channel] & 0xFF);
			}
			DBG_INFO(("@@@@ no cross len %d\n", len));

			if (len < 0)
				len = 0;
			cableStatus->u[channel].dist2fault = (GT_16)len;
			vctResult = getDetailedAdvVCTResult(
									devType,
									GET_AMPLITUDE(crossChannelReg[channel]),
									len,
									vctResult);
			dist2fault = (GT_16)len;
			break;
		default:
			break;
	}

	cableStatus->cableStatus[channel] = vctResult;

	return dist2fault;
}


static
GT_16 analizeAdvVCTResult
(
	IN  GT_U32  devType,
	IN  int     channel, 
	IN  GT_U16 *crossChannelReg, 
	IN  GT_BOOL isShort,
	OUT GT_ADV_CABLE_STATUS *cableStatus
)
{
	int i, len;
	GT_16 dist2fault;
	GT_ADV_VCT_STATUS vctResult = GT_ADV_VCT_NORMAL;

	DBG_INFO(("analizeAdvVCTResult(Crosspair) chan %d reg data %x\n", channel, crossChannelReg[channel]));
	DBG_INFO(("analizeAdvVCTResult Called.\n"));

	dist2fault = -1;

	/* check if test is failed */
	for (i=0; i<GT_MDI_PAIR_NUM; i++)
	{
		if(IS_VCT_FAILED(crossChannelReg[i]))
		{
			cableStatus->cableStatus[channel] = GT_ADV_VCT_FAIL;
			return dist2fault;
		}
	}

	/* find out test result by reading Amplitude */
	for (i=0; i<GT_MDI_PAIR_NUM; i++)
	{
		if (i == channel)
		{
			if(!IS_ZERO_AMPLITUDE(crossChannelReg[i]))
			{
				if(IS_POSITIVE_AMPLITUDE(crossChannelReg[i]))
				{
					vctResult = GT_ADV_VCT_IMP_GREATER_THAN_115;
				}
				else
				{
					vctResult = GT_ADV_VCT_IMP_LESS_THAN_85;
				}
			}
			continue;
		}

		if(IS_ZERO_AMPLITUDE(crossChannelReg[i]))
			continue;

		vctResult = GT_ADV_VCT_CROSS_PAIR_SHORT;
		break;
	}

	/* if it is cross pair short, check the distance for each channel */
	if(vctResult == GT_ADV_VCT_CROSS_PAIR_SHORT)
	{
		cableStatus->cableStatus[channel] = GT_ADV_VCT_CROSS_PAIR_SHORT;
		for (i=0; i<GT_MDI_PAIR_NUM; i++)
		{
			if(IS_ZERO_AMPLITUDE(crossChannelReg[i]))
			{
				cableStatus->u[channel].crossShort.channel[i] = GT_FALSE;
				cableStatus->u[channel].crossShort.dist2fault[i] = 0;
				continue;
			}
            
			cableStatus->u[channel].crossShort.channel[i] = GT_TRUE;
			if(!isShort)
				len = (int)GT_ADV_VCT_CALC(crossChannelReg[i] & 0xFF);
			else
				len = (int)GT_ADV_VCT_CALC_SHORT(crossChannelReg[i] & 0xFF);
			DBG_INFO(("@@@@ len %d\n", len));

			if (len < 0)
				len = 0;
			cableStatus->u[channel].crossShort.dist2fault[i] = (GT_16)len;
			dist2fault = (GT_16)len;
		}

		return dist2fault;
	}

	/* 
	 * now, calculate the distance for GT_ADV_VCT_IMP_GREATER_THAN_115 and
	 * GT_ADV_VCT_IMP_LESS_THAN_85
	 */
	switch (vctResult)
	{
		case GT_ADV_VCT_IMP_GREATER_THAN_115:
		case GT_ADV_VCT_IMP_LESS_THAN_85:
			if(isShort)
				len = (int)GT_ADV_VCT_CALC(crossChannelReg[channel] & 0xFF);
			else
				len = (int)GT_ADV_VCT_CALC_SHORT(crossChannelReg[channel] & 0xFF);
			if (len < 0)
				len = 0;
			cableStatus->u[channel].dist2fault = (GT_16)len;
			vctResult = getDetailedAdvVCTResult(
									devType,
									GET_AMPLITUDE(crossChannelReg[channel]),
									len,
									vctResult);
			dist2fault = (GT_16)len;
			break;
		default:
			break;
	}

	cableStatus->cableStatus[channel] = vctResult;

	return dist2fault;
}


/*******************************************************************************
* runAdvCableTest_1181
*
* DESCRIPTION:
*		This routine performs the advanced virtual cable test for the PHY with
*		multiple page mode and returns the the status per MDIP/N.
*
* INPUTS:
*		port - logical port number.
*		mode - GT_TRUE, if short cable detect is required
*			   GT_FALSE, otherwise
*
* OUTPUTS:
*		cableStatus - the port copper cable status.
*		tooShort    - if known distance to fault is too short
*
* RETURNS:
*		GT_OK   - on success
*		GT_FAIL - on error
*
* COMMENTS:
*		None.
*
*******************************************************************************/
static 
GT_STATUS runAdvCableTest_1181
(	
	IN  GT_QD_DEV       *dev,
	IN  GT_U8           hwPort,
	IN	GT_PHY_INFO		*phyInfo,
	IN  GT_BOOL         mode,
	OUT GT_ADV_CABLE_STATUS *cableStatus,
	OUT GT_BOOL         *tooShort
)
{
	GT_STATUS retVal;
	GT_U16 u16Data;
	GT_U16 crossChannelReg[GT_MDI_PAIR_NUM];
	int i,j;
	GT_16  dist2fault;

	VCT_REGISTER regList[GT_MDI_PAIR_NUM][GT_MDI_PAIR_NUM] = {
							{{8,16},{8,17},{8,18},{8,19}},  /* channel 0 */
							{{8,24},{8,25},{8,26},{8,27}},  /* channel 1 */
							{{9,16},{9,17},{9,18},{9,19}},  /* channel 2 */
							{{9,24},{9,25},{9,26},{9,27}}   /* channel 3 */
							};

	DBG_INFO(("runAdvCableTest_1181 Called.\n"));

	if (mode)
		*tooShort = GT_FALSE;

	/* 
	 * start Advanced Virtual Cable Tester
	 */
	if((retVal = hwSetPagedPhyRegField(
						dev,hwPort,8,QD_REG_ADV_VCT_CONTROL_8,15,1,phyInfo->anyPage,1)) != GT_OK)
	{
		DBG_INFO(("Writing to paged phy reg failed.\n"));
		return retVal;
	}

	/* 
	 * loop until test completion and result is valid
	 */
	do
	{
		if((retVal = hwReadPagedPhyReg(
							dev,hwPort,8,QD_REG_ADV_VCT_CONTROL_8,phyInfo->anyPage,&u16Data)) != GT_OK)
		{
			DBG_INFO(("Reading from paged phy reg failed.\n"));
			return retVal;
		}
	} while(u16Data & 0x8000);

	DBG_INFO(("Page 8 of Reg20 after test : %0#x.\n", u16Data));

	for (i=0; i<GT_MDI_PAIR_NUM; i++)
	{
		/*
		 * read the test result for the cross pair against selected MDI Pair
		 */
		for (j=0; j<GT_MDI_PAIR_NUM; j++)
		{
			if((retVal = hwReadPagedPhyReg(
								dev,hwPort,
								regList[i][j].page,
								regList[i][j].regOffset,
								phyInfo->anyPage,
								&crossChannelReg[j])) != GT_OK)
			{
				DBG_INFO(("Reading from paged phy reg failed.\n"));
				return retVal;
			}
		}

		/*
		 * analyze the test result for RX Pair
		 */
		dist2fault = analizeAdvVCTResult(phyInfo->vctType, i, crossChannelReg, mode, cableStatus);

		if(mode)
		{
			if ((dist2fault>=0) && (dist2fault<GT_ADV_VCT_ACCEPTABLE_SHORT_CABLE))
			{
				DBG_INFO(("Distance to Fault is too Short. So, rerun after changing pulse width\n"));
				*tooShort = GT_TRUE;
				break;
			}
		}
	}

	return GT_OK;
}



/*******************************************************************************
* getAdvCableStatus_1181
*
* DESCRIPTION:
*		This routine performs the virtual cable test for the PHY with
*		multiple page mode and returns the the status per MDIP/N.
*
* INPUTS:
*		port - logical port number.
*		mode - advance VCT mode (either First Peak or Maximum Peak)
*
* OUTPUTS:
*		cableStatus - the port copper cable status.
*
* RETURNS:
*		GT_OK   - on success
*		GT_FAIL - on error
*
* COMMENTS:
*		None.
*
*******************************************************************************/
static 
GT_STATUS getAdvCableStatus_1181
(	
	IN  GT_QD_DEV          *dev,
	IN  GT_U8           hwPort,
	IN	GT_PHY_INFO		*phyInfo,
	IN  GT_ADV_VCT_MODE mode,
	OUT GT_ADV_CABLE_STATUS *cableStatus
)
{
	GT_STATUS retVal;
	GT_U16 orgPulse, u16Data;
	GT_BOOL flag, tooShort;

	flag = GT_TRUE;

	/*
	 * set Adv VCT Mode
	 */
	switch (mode.mode)
	{
		case GT_ADV_VCT_FIRST_PEAK:
			break;
		case GT_ADV_VCT_MAX_PEAK:
			break;
		default:
			DBG_INFO(("Unknown Advanced VCT Mode.\n"));
			return GT_BAD_PARAM;
	}

	u16Data = (mode.mode<<6) | (mode.peakDetHyst) | (mode.sampleAvg<<8);
	if((retVal = hwSetPagedPhyRegField(
						dev,hwPort,8,QD_REG_ADV_VCT_CONTROL_8,0,11,phyInfo->anyPage,u16Data)) != GT_OK)
	{
		DBG_INFO(("Writing to paged phy reg failed.\n"));
		return retVal;
	}

	if (flag)
	{
		/* save original Pulse Width */
		if((retVal = hwGetPagedPhyRegField(
							dev,hwPort,9,23,10,2,phyInfo->anyPage,&orgPulse)) != GT_OK)
		{
			DBG_INFO(("Reading paged phy reg failed.\n"));
			return retVal;
		}

		/* set the Pulse Width with default value */
		if (orgPulse != 0)
		{
			if((retVal = hwSetPagedPhyRegField(
								dev,hwPort,9,23,10,2,phyInfo->anyPage,0)) != GT_OK)
			{
				DBG_INFO(("Writing to paged phy reg failed.\n"));
				return retVal;
			}
		}
	}

	if((retVal=runAdvCableTest_1181(dev,hwPort,phyInfo,flag,cableStatus,&tooShort)) != GT_OK)
	{
		DBG_INFO(("Running advanced VCT failed.\n"));
		return retVal;
	}

	if (flag)
	{
		if(tooShort)
		{
			/* set the Pulse Width with minimum width */
			if((retVal = hwSetPagedPhyRegField(
								dev,hwPort,9,23,10,2,phyInfo->anyPage,3)) != GT_OK)
			{
				DBG_INFO(("Writing to paged phy reg failed.\n"));
				return retVal;
			}

			/* run the Adv VCT again */
			if((retVal=runAdvCableTest_1181(dev,hwPort,phyInfo,GT_FALSE,cableStatus,&tooShort)) != GT_OK)
			{
				DBG_INFO(("Running advanced VCT failed.\n"));
				return retVal;
			}

		}

		/* set the Pulse Width back to the original value */
		if((retVal = hwSetPagedPhyRegField(
							dev,hwPort,9,23,10,2,phyInfo->anyPage,orgPulse)) != GT_OK)
		{
			DBG_INFO(("Writing to paged phy reg failed.\n"));
			return retVal;
		}

	}

	return GT_OK;
}


static 
GT_STATUS runAdvCableTest_1116_set
(	
	IN  GT_QD_DEV          *dev,
	IN  GT_U8           hwPort,
	IN	GT_PHY_INFO		*phyInfo,
	IN  GT_32           channel,
	IN  GT_ADV_VCT_TRANS_CHAN_SEL		crosspair
)
{
	GT_STATUS retVal;

	DBG_INFO(("runAdvCableTest_1116_set Called.\n"));

	/* 
	 * start Advanced Virtual Cable Tester
	 */
	if((retVal = hwSetPagedPhyRegField(
						dev,hwPort,5,QD_REG_ADV_VCT_CONTROL_5,15,1,phyInfo->anyPage,1)) != GT_OK)
	{
		DBG_INFO(("Writing to paged phy reg failed.\n"));
		return retVal;
	}

	return GT_OK;
}

static 
GT_STATUS runAdvCableTest_1116_check
(	
	IN  GT_QD_DEV       *dev,
	IN  GT_U8           hwPort,
	IN	GT_PHY_INFO		*phyInfo
)
{
	GT_STATUS retVal;
	GT_U16 u16Data;

	/* 
	 * loop until test completion and result is valid
	 */
	do {
		if((retVal = hwReadPagedPhyReg(
							dev,hwPort,5,QD_REG_ADV_VCT_CONTROL_5,phyInfo->anyPage,&u16Data)) != GT_OK)
		{
			DBG_INFO(("Reading from paged phy reg failed.\n"));
			return retVal;
		}
	} while (u16Data & 0x8000);

	return GT_OK;
}

static 
GT_STATUS runAdvCableTest_1116_get
(	
	IN  GT_QD_DEV          *dev,
	IN  GT_U8           hwPort,
	IN	GT_PHY_INFO		*phyInfo,
	IN  GT_ADV_VCT_TRANS_CHAN_SEL	crosspair,
	IN  GT_32			channel,
	OUT GT_ADV_CABLE_STATUS *cableStatus,
	OUT GT_BOOL         *tooShort
)
{
	GT_STATUS retVal;
	GT_U16 u16Data;
	GT_U16 crossChannelReg[GT_MDI_PAIR_NUM];
	int j;
	GT_16  dist2fault;
	GT_BOOL         mode;
	GT_BOOL         localTooShort[GT_MDI_PAIR_NUM];

	VCT_REGISTER regList[GT_MDI_PAIR_NUM] = { {5,16},{5,17},{5,18},{5,19} };

	mode = GT_TRUE;

	DBG_INFO(("runAdvCableTest_1116_get Called.\n"));

	if ((retVal = hwReadPagedPhyReg(
						dev,hwPort,5,QD_REG_ADV_VCT_CONTROL_5,phyInfo->anyPage,&u16Data)) != GT_OK)
	{
		DBG_INFO(("Reading from paged phy reg failed.\n"));
		return retVal;
	}

	DBG_INFO(("Page 5 of Reg23 after test : %0#x.\n", u16Data));

	/*
	 * read the test result for the cross pair against selected MDI Pair
	 */
	for (j=0; j<GT_MDI_PAIR_NUM; j++)
	{
		if((retVal = hwReadPagedPhyReg(
								dev,hwPort,
								regList[j].page,
								regList[j].regOffset,
								phyInfo->anyPage,
								&crossChannelReg[j])) != GT_OK)
		{
			DBG_INFO(("Reading from paged phy reg failed.\n"));
			return retVal;
		}
		DBG_INFO(("@@@@@ reg channel %d is %x \n", j, crossChannelReg[j]));
	}

	/*
	 * analyze the test result for RX Pair
	 */
	for (j=0; j<GT_MDI_PAIR_NUM; j++)
	{
		if (crosspair!=GT_ADV_VCT_TCS_NO_CROSSPAIR)
			dist2fault = analizeAdvVCTResult(phyInfo->vctType, j, crossChannelReg, mode&(*tooShort), cableStatus);
		else
			dist2fault = analizeAdvVCTNoCrosspairResult(phyInfo->vctType, j, crossChannelReg, mode&(*tooShort), cableStatus);

		localTooShort[j]=GT_FALSE;
		if((mode)&&(*tooShort==GT_FALSE))
		{
			if ((dist2fault>=0) && (dist2fault<GT_ADV_VCT_ACCEPTABLE_SHORT_CABLE))
			{
				DBG_INFO(("@@@#@@@@ it is too short dist2fault %d\n", dist2fault));
				DBG_INFO(("Distance to Fault is too Short. So, rerun after changing pulse width\n"));
				localTooShort[j]=GT_TRUE;
			}
		}
	}

	/* check and decide if length is too short */
	for (j=0; j<GT_MDI_PAIR_NUM; j++)
	{
		if (localTooShort[j]==GT_FALSE) break;
	}

	if (j==GT_MDI_PAIR_NUM)
		*tooShort = GT_TRUE;

	return GT_OK;
}

static 
GT_STATUS runAdvCableTest_1116
(	
    IN  GT_QD_DEV          *dev,
    IN  GT_U8           hwPort,
	IN	GT_PHY_INFO		*phyInfo,
    IN  GT_BOOL         mode,
    IN  GT_ADV_VCT_TRANS_CHAN_SEL   crosspair,
    OUT GT_ADV_CABLE_STATUS *cableStatus,
    OUT GT_BOOL         *tooShort
)
{
	GT_STATUS retVal;
	GT_32  channel;

	DBG_INFO(("runAdvCableTest_1116 Called.\n"));

	if (crosspair!=GT_ADV_VCT_TCS_NO_CROSSPAIR)
	{
		channel = crosspair - GT_ADV_VCT_TCS_CROSSPAIR_0;
	}
	else
	{
		channel = 0;
	}

	/* Set transmit channel */
	if((retVal=runAdvCableTest_1116_set(dev,hwPort, phyInfo,channel, crosspair)) != GT_OK) 
	{
		DBG_INFO(("Running advanced VCT failed.\n"));
		return retVal;
	}

	/* 
	 * check test completion
	 */
	retVal = runAdvCableTest_1116_check(dev,hwPort,phyInfo);
	if (retVal != GT_OK)
	{
		DBG_INFO(("Running advanced VCT failed.\n"));
		return retVal;
	}

	/*
	 * read the test result for the cross pair against selected MDI Pair
	 */
	retVal = runAdvCableTest_1116_get(dev, hwPort, phyInfo, crosspair,
									channel,cableStatus,(GT_BOOL *)tooShort);

	if(retVal != GT_OK)
	{
		DBG_INFO(("Running advanced VCT get failed.\n"));
	}

	return retVal;
}

static 
GT_STATUS getAdvCableStatus_1116
(	
	IN  GT_QD_DEV       *dev,
	IN  GT_U8           hwPort,
	IN	GT_PHY_INFO		*phyInfo,
	IN  GT_ADV_VCT_MODE mode,
	OUT GT_ADV_CABLE_STATUS *cableStatus
)
{
	GT_STATUS retVal;
	GT_U16 orgPulse, u16Data;
	GT_BOOL flag, tooShort;
	GT_ADV_VCT_TRANS_CHAN_SEL crosspair;

	flag = GT_TRUE;
	crosspair = mode.transChanSel;

	/*
	 * Check Adv VCT Mode
	 */
	switch (mode.mode)
	{
		case GT_ADV_VCT_FIRST_PEAK:
		case GT_ADV_VCT_MAX_PEAK:
				break;

		default:
				DBG_INFO(("Unknown ADV VCT Mode.\n"));
				return GT_NOT_SUPPORTED;
	}

	if((retVal = hwGetPagedPhyRegField(
							dev,hwPort,5,QD_REG_ADV_VCT_CONTROL_5,0,13,phyInfo->anyPage,&u16Data)) != GT_OK)
	{
		DBG_INFO(("Reading paged phy reg failed.\n"));
		return retVal;
	}

	u16Data |= ((mode.mode<<6) | (mode.transChanSel<<11));
	if (mode.peakDetHyst) u16Data |= (mode.peakDetHyst);
	if (mode.sampleAvg) u16Data |= (mode.sampleAvg<<8) ;

	if((retVal = hwSetPagedPhyRegField(
						dev,hwPort,5,QD_REG_ADV_VCT_CONTROL_5,0,13,phyInfo->anyPage,u16Data)) != GT_OK)
	{
		DBG_INFO(("Writing to paged phy reg failed.\n"));
		return retVal;
	}

	if (flag)
	{
		/* save original Pulse Width */
		if((retVal = hwGetPagedPhyRegField(dev,hwPort,5,28,10,2,phyInfo->anyPage,&orgPulse)) != GT_OK)
		{
			DBG_INFO(("Reading paged phy reg failed.\n"));
			return retVal;
		}

		/* set the Pulse Width with default value */
		if (orgPulse != 0)
		{
			if((retVal = hwSetPagedPhyRegField(dev,hwPort,5,28,10,2,phyInfo->anyPage,0)) != GT_OK)
			{
				DBG_INFO(("Writing to paged phy reg failed.\n"));
				return retVal;
			}
		}
		tooShort=GT_FALSE;
	}

	if((retVal=runAdvCableTest_1116(dev,hwPort,phyInfo,flag,crosspair, 
									cableStatus,&tooShort)) != GT_OK)
	{
		DBG_INFO(("Running advanced VCT failed.\n"));
		return retVal;
	}

	if (flag)
	{
		if(tooShort)
		{
			/* set the Pulse Width with minimum width */
			if((retVal = hwSetPagedPhyRegField(
										dev,hwPort,5,28,10,2,phyInfo->anyPage,3)) != GT_OK)
			{
				DBG_INFO(("Writing to paged phy reg failed.\n"));
				return retVal;
			}

			/* run the Adv VCT again */
			if((retVal=runAdvCableTest_1116(dev,hwPort,phyInfo,GT_FALSE,crosspair,
										cableStatus,&tooShort)) != GT_OK)
			{
				DBG_INFO(("Running advanced VCT failed.\n"));
				return retVal;
			}

		}

		/* set the Pulse Width back to the original value */
		if((retVal = hwSetPagedPhyRegField(
								dev,hwPort,5,28,10,2,phyInfo->anyPage,orgPulse)) != GT_OK)
		{
			DBG_INFO(("Writing to paged phy reg failed.\n"));
			return retVal;
		}

	}

	return GT_OK;
}


/*******************************************************************************
* gvctGetAdvCableStatus
*
* DESCRIPTION:
*       This routine perform the advanced virtual cable test for the requested
*       port and returns the the status per MDI pair.
*
* INPUTS:
*       port - logical port number.
*       mode - advance VCT mode (either First Peak or Maximum Peak)
*
* OUTPUTS:
*       cableStatus - the port copper cable status.
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*
* COMMENTS:
*       Internal Gigabit Phys in 88E6165 family and 88E6351 family devices
*		are supporting this API.
*
*******************************************************************************/
GT_STATUS gvctGetAdvCableDiag
(
    IN  GT_QD_DEV *dev,
    IN  GT_LPORT        port,
    IN  GT_ADV_VCT_MODE mode,
    OUT GT_ADV_CABLE_STATUS *cableStatus
)
{
	GT_STATUS status;
	GT_U8 hwPort;
	GT_U16 u16Data, org0;
	GT_BOOL ppuEn;
	GT_PHY_INFO	phyInfo;
	GT_BOOL			autoOn, autoNeg;
	GT_U16			pageReg;
	int i;

    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_ADV_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;
	}

	/*
	 * 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_ADV_VCT_FAIL;
			}
			return GT_OK;
		}
	}

	/*
	 * Check the link
	 */
	if((status= hwReadPagedPhyReg(dev,hwPort,0,17,phyInfo.anyPage,&u16Data)) != GT_OK)
	{
	    DBG_INFO(("Not able to reset the Phy.\n"));
		return status;
	}

	autoNeg = GT_FALSE;
	org0 = 0;
	if (!(u16Data & 0x400))
	{
		/* link is down, so disable auto-neg if enabled */
		if((status= hwReadPagedPhyReg(dev,hwPort,0,0,phyInfo.anyPage,&u16Data)) != GT_OK)
		{
		    DBG_INFO(("Not able to reset the Phy.\n"));
			return status;
		}
		
		org0 = u16Data;

		if (u16Data & 0x1000)
		{
			u16Data = 0x140;

			/* link is down, so disable auto-neg if enabled */
			if((status= hwWritePagedPhyReg(dev,hwPort,0,0,phyInfo.anyPage,u16Data)) != GT_OK)
			{
			    DBG_INFO(("Not able to reset the Phy.\n"));
				return status;
			}

			if((status= hwPhyReset(dev,hwPort,0xFF)) != GT_OK)
			{
			    DBG_INFO(("Not able to reset the Phy.\n"));
				return status;
			}
			autoNeg = GT_TRUE;		
		}
	}

	switch(phyInfo.vctType)
	{
		case GT_PHY_ADV_VCT_TYPE1:
			status = getAdvCableStatus_1181(dev,hwPort,&phyInfo,mode,cableStatus);
			break;
		case GT_PHY_ADV_VCT_TYPE2:
			status = getAdvCableStatus_1116(dev,hwPort,&phyInfo,mode,cableStatus);
			break;
		default:
			status = GT_FAIL;
			break;
	}

	if (autoNeg)
	{
		if((status= hwPhyReset(dev,hwPort,org0)) != GT_OK)
		{
		    DBG_INFO(("Not able to reset the Phy.\n"));
			goto cableDiagCleanup;
			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;	
}


/*******************************************************************************
* dspLookup
*
* DESCRIPTION:
*       This routine returns cable length (meters) by reading DSP Lookup table.
*
* INPUTS:
*       regValue - register 21
*
* OUTPUTS:
*       cableLen - cable length (unit of meters).
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*
* COMMENTS:
*       None.
*
*******************************************************************************/
static
GT_STATUS dspLookup
(
	IN	GT_PHY_INFO		*phyInfo,
    IN  GT_U16 regValue, 
    OUT GT_32  *cableLen
)
{
    GT_U16 startEntry,tableEntry;
    GT_U8* tbl;
    switch(phyInfo->exStatusType)
    {
        case GT_PHY_EX_STATUS_TYPE1:	/* 88E1111/88E1141/E1145 */
            startEntry = 18-1;
            tableEntry = 80;
            tbl = tbl_1111;
            break;

        case GT_PHY_EX_STATUS_TYPE2:	/* 88E1112 */
            startEntry = 17;
            tableEntry = 100;
            tbl = tbl_1112;
            break;

        case GT_PHY_EX_STATUS_TYPE3:   /* 88E1149 has no reference constans*/
            startEntry = 16;
            tableEntry = 73;
            tbl = tbl_1181;
            break;

        case GT_PHY_EX_STATUS_TYPE4:   /* 88E1181 */
            startEntry = 16;
            tableEntry = 73;
            tbl = tbl_1181;
            break;

        case GT_PHY_EX_STATUS_TYPE5:   /* 88E1116 88E1121 */
            startEntry = 16;
            tableEntry = 73;
            tbl = tbl_1116;
            break;

        case GT_PHY_EX_STATUS_TYPE6:   /* 88E6165 Internal Phy */
			if ((phyInfo->phyId & PHY_MODEL_MASK) == DEV_G65G)
	            startEntry = 18;
			else
	            startEntry = 21;
            tableEntry = 76;
            tbl = tbl_1240;
            break;

		default:
			return GT_NOT_SUPPORTED;
    }

    if (tbl == NULL)
    {
        *cableLen = -1;
        return GT_OK;
    }

    if (regValue < startEntry)
    {
        *cableLen = 0;
        return GT_OK;
    }

    if (regValue >= (tableEntry+startEntry-1))
    {
        regValue = tableEntry-1;
    }
    else
    {
        regValue -= startEntry;
    }

    *cableLen = (GT_32)tbl[regValue];
    return GT_OK;
}

/*******************************************************************************
* getDSPDistance_1111
*
* DESCRIPTION:
*       This routine returns cable length (meters) from DSP method.
*       This routine is for the 88E1111 like devices.
*
* INPUTS:
*       mdi - pair of each MDI (0..3).
*
* OUTPUTS:
*       cableLen - cable length (unit of meters).
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*
* COMMENTS:
*       None.
*
*******************************************************************************/
static
GT_STATUS getDSPDistance_1111
(
    IN  GT_QD_DEV *dev,
    IN  GT_U8  hwPort,
	IN	GT_PHY_INFO		*phyInfo,
    IN  GT_U32 mdi,
    OUT GT_32 *cableLen
)
{
    GT_U16     data, pageNum;
    GT_STATUS  retVal;

    DBG_INFO(("getDSPDistance Called.\n"));

    pageNum = 0x8754 + (GT_U16)((mdi << 12)&0xf000);

    if((retVal = hwReadPagedPhyReg(dev,hwPort,(GT_U8)pageNum,31,phyInfo->anyPage,&data)) != GT_OK)
    {
        DBG_INFO(("Reading length of MDI pair failed.\n"));
        return retVal;
    }

    return dspLookup(phyInfo,data,cableLen);
}


/*******************************************************************************
* getDSPDistance_1181
*
* DESCRIPTION:
*       This routine returns cable length (meters) from DSP method.
*       This routine is for the 88E1181 like devices.
*
* INPUTS:
*       mdi - pair of each MDI (0..3).
*
* OUTPUTS:
*       cableLen - cable length (unit of meters).
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*
* COMMENTS:
*       None.
*
*******************************************************************************/
static
GT_STATUS getDSPDistance_1181
(
    IN  GT_QD_DEV *dev,
    IN  GT_U8  hwPort,
	IN	GT_PHY_INFO		*phyInfo,
    IN  GT_U32 mdi,
    OUT GT_32 *cableLen
)
{
    GT_U16     data, retryCount;
    GT_STATUS  retVal;

    DBG_INFO(("getDSPDistance Called.\n"));

    /* Set the required bits for Cable length register */
    if((retVal = hwWritePagedPhyReg(dev,hwPort,0xff,19,phyInfo->anyPage,(GT_U16)(0x1018+(0xff&mdi)))) != GT_OK)
    {
        DBG_INFO(("Writing to paged phy reg failed.\n"));
        return retVal;
    }

    retryCount = 1000;

    do
    {
        if(retryCount == 0)
        {
            DBG_INFO(("Ready bit of Cable length resiter is not set.\n"));
            return GT_FAIL;
        }

        /* Check the ready bit of Cable length register */
        if((retVal = hwGetPagedPhyRegField(dev,hwPort,0xff,19,15,1,phyInfo->anyPage,&data)) != GT_OK)
        {
            DBG_INFO(("Writing to paged phy reg failed.\n"));
            return retVal;
        }

        retryCount--;

    } while(!data);

    /* read length of MDI pair */
    if((retVal = hwReadPagedPhyReg(dev,hwPort,0xff,21,phyInfo->anyPage,&data)) != GT_OK)
    {
        DBG_INFO(("Reading length of MDI pair failed.\n"));
        return retVal;
    }

    return dspLookup(phyInfo,data,cableLen);
}


/*******************************************************************************
* getDSPDistance_1240
*
* DESCRIPTION:
*       This routine returns cable length (meters) from DSP method.
*       This routine is for the 88E1181 like devices.
*
* INPUTS:
*       mdi - pair of each MDI (0..3).
*
* OUTPUTS:
*       cableLen - cable length (unit of meters).
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*
* COMMENTS:
*       None.
*
*******************************************************************************/
static
GT_STATUS getDSPDistance_1240
(
    IN  GT_QD_DEV *dev,
    IN  GT_U8  hwPort,
	IN	GT_PHY_INFO		*phyInfo,
    IN  GT_U32 mdi,
    OUT GT_32 *cableLen
)
{
    GT_U16     data, retryCount;
    GT_STATUS  retVal;

    DBG_INFO(("getDSPDistance Called.\n"));

    /* Set the required bits for Cable length register */
    if((retVal = hwWritePagedPhyReg(dev,hwPort,0xff,16,phyInfo->anyPage,(GT_U16)(0x1118+(0xff&mdi)))) != GT_OK)
    {
        DBG_INFO(("Writing to paged phy reg failed.\n"));
        return retVal;
    }

    retryCount = 1000;

    do
    {
        if(retryCount == 0)
        {
            DBG_INFO(("Ready bit of Cable length resiter is not set.\n"));
            return GT_FAIL;
        }

        /* Check the ready bit of Cable length register */
        if((retVal = hwGetPagedPhyRegField(dev,hwPort,0xff,16,15,1,phyInfo->anyPage,&data)) != GT_OK)
        {
            DBG_INFO(("Writing to paged phy reg failed.\n"));
            return retVal;
        }

        retryCount--;

    } while(!data);

    /* read length of MDI pair */
    if((retVal = hwReadPagedPhyReg(dev,hwPort,0xff,18,phyInfo->anyPage,&data)) != GT_OK)
    {
        DBG_INFO(("Reading length of MDI pair failed.\n"));
        return retVal;
    }

    return dspLookup(phyInfo,data,cableLen);
}



/*******************************************************************************
* getExStatus_28
*
* 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 getExStatus_28
(
    IN  GT_QD_DEV 		*dev,
    IN  GT_U8	        hwPort,
	IN	GT_PHY_INFO		*phyInfo,
    OUT GT_ADV_EXTENDED_STATUS *extendedStatus
)
{
    GT_STATUS retVal;
    GT_U16 u16Data, i;

    extendedStatus->isValid = GT_FALSE;
    /* DSP based cable length */
    for (i=0; i<GT_MDI_PAIR_NUM; i++)
    {
        if((retVal = getDSPDistance_1111(dev,hwPort,phyInfo,i,&extendedStatus->cableLen[i])) != GT_OK)
        {
            DBG_INFO(("getDSPDistance failed.\n"));
            return retVal;
        }
    }


    /*
     * get data from 28_5 register for pair swap
     */
    if((retVal = hwReadPagedPhyReg(
                    dev,hwPort,5,28,phyInfo->anyPage,&u16Data)) != GT_OK)
    {
        DBG_INFO(("Reading from paged phy reg failed.\n"));
        return retVal;
    }

    /* if bit 6 is not set, it's not valid. */
    if (!(u16Data & 0x40))
    {
        DBG_INFO(("Valid Bit is not set (%0#x).\n", u16Data));
        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 Channel A and B */
    if (u16Data & 0x10)
    {
        extendedStatus->pairSwap[0] = GT_CHANNEL_A;
        extendedStatus->pairSwap[1] = GT_CHANNEL_B;
    }
    else
    {
        extendedStatus->pairSwap[0] = GT_CHANNEL_B;
        extendedStatus->pairSwap[1] = GT_CHANNEL_A;
    }

    /* get Pair Swap for Channel C and D */
    if (u16Data & 0x20)
    {
        extendedStatus->pairSwap[2] = GT_CHANNEL_C;
        extendedStatus->pairSwap[3] = GT_CHANNEL_D;
    }
    else
    {
        extendedStatus->pairSwap[2] = GT_CHANNEL_D;
        extendedStatus->pairSwap[3] = GT_CHANNEL_C;
    }

    /*
     * get data from 28_4 register for pair skew
     */
    if((retVal = hwReadPagedPhyReg(
                    dev,hwPort,4,28,phyInfo->anyPage,&u16Data)) != GT_OK)
    {
        DBG_INFO(("Reading from paged phy reg failed.\n"));
        return retVal;
    }

    /* get Pair Skew */
    for(i=0; i<GT_MDI_PAIR_NUM; i++)
    {
        extendedStatus->pairSkew[i] = ((u16Data >> i*4) & 0xF) * 8;
    }

    return GT_OK;
}


/*******************************************************************************
* getExStatus
*
* 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 getExStatus
(
    IN  GT_QD_DEV 		*dev,
    IN  GT_U8	        hwPort,
	IN	GT_PHY_INFO		*phyInfo,
    OUT GT_ADV_EXTENDED_STATUS *extendedStatus
)
{
    GT_STATUS retVal;
    GT_U16 u16Data, i;

    extendedStatus->isValid = GT_FALSE;
    /* DSP based cable length */
    switch(phyInfo->exStatusType)
    {
        case GT_PHY_EX_STATUS_TYPE1:
        case GT_PHY_EX_STATUS_TYPE2:
            for (i=0; i<GT_MDI_PAIR_NUM; i++)
            {
                if((retVal = getDSPDistance_1111(dev,hwPort,phyInfo,i,&extendedStatus->cableLen[i])) != GT_OK)
                {
                    DBG_INFO(("getDSPDistance failed.\n"));
                    return retVal;
                }
            }
            break;
        case GT_PHY_EX_STATUS_TYPE3:
        case GT_PHY_EX_STATUS_TYPE4:
        case GT_PHY_EX_STATUS_TYPE5:
            for (i=0; i<GT_MDI_PAIR_NUM; i++)
            {
                if((retVal = getDSPDistance_1181(dev,hwPort,phyInfo,i,&extendedStatus->cableLen[i])) != GT_OK)
                {
                    DBG_INFO(("getDSPDistance failed.\n"));
                    return retVal;
                }
            }
            break;

        case GT_PHY_EX_STATUS_TYPE6:
            for (i=0; i<GT_MDI_PAIR_NUM; i++)
            {
                if((retVal = getDSPDistance_1240(dev,hwPort,phyInfo,i,&extendedStatus->cableLen[i])) != GT_OK)
                {
                    DBG_INFO(("getDSPDistance failed.\n"));
                    return retVal;
                }
            }
            break;

        default:
			return GT_NOT_SUPPORTED;
    }

    /*
     * get data from 21_5 register for pair swap
     */
    if((retVal = hwReadPagedPhyReg(
                    dev,hwPort,5,QD_REG_PAIR_SWAP_STATUS,phyInfo->anyPage,&u16Data)) != GT_OK)
    {
        DBG_INFO(("Reading from paged phy reg failed.\n"));
        return retVal;
    }

    /* if bit 6 is not set, it's not valid. */
    if (!(u16Data & 0x40))
    {
        DBG_INFO(("Valid Bit is not set (%0#x).\n", u16Data));
        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 Channel A and B */
    if (u16Data & 0x10)
    {
        extendedStatus->pairSwap[0] = GT_CHANNEL_A;
        extendedStatus->pairSwap[1] = GT_CHANNEL_B;
    }
    else
    {
        extendedStatus->pairSwap[0] = GT_CHANNEL_B;
        extendedStatus->pairSwap[1] = GT_CHANNEL_A;
    }

    /* get Pair Swap for Channel C and D */
    if (u16Data & 0x20)
    {
        extendedStatus->pairSwap[2] = GT_CHANNEL_C;
        extendedStatus->pairSwap[3] = GT_CHANNEL_D;
    }
    else
    {
        extendedStatus->pairSwap[2] = GT_CHANNEL_D;
        extendedStatus->pairSwap[3] = GT_CHANNEL_C;
    }

    /*
     * get data from 20_5 register for pair skew
     */
    if((retVal = hwReadPagedPhyReg(
                    dev,hwPort,5,QD_REG_PAIR_SKEW_STATUS,phyInfo->anyPage,&u16Data)) != GT_OK)
    {
        DBG_INFO(("Reading from paged phy reg failed.\n"));
        return retVal;
    }

    /* get Pair Skew */
    for(i=0; i<GT_MDI_PAIR_NUM; i++)
    {
        extendedStatus->pairSkew[i] = ((u16Data >> i*4) & 0xF) * 8;
    }


    return GT_OK;
}


/*******************************************************************************
* gvctGetAdvExtendedStatus
*
* DESCRIPTION:
*       This routine retrieves extended cable status, such as Pair Poloarity,
*		Pair Swap, and Pair Skew. Note that this routine will be success only
*		if 1000Base-T Link is up.
*		Note: Since DSP based cable length in extended status is based on 
*             constants from test results. At present, only E1181, E1111, and
*             E1112 are available.
*
* INPUTS:
*       dev  - pointer to GT driver structure returned from mdLoadDriver
*       port - logical port number.
*
* OUTPUTS:
*       extendedStatus - the extended cable status.
*
* RETURNS:
*       GT_OK   - on success
*       GT_FAIL - on error
*
* COMMENTS:
*		Supporting Device list:
*       	88E1111, 88E1112, 88E1141~6, 88E1149, and Internal Gigabit Phys 
*			in 88E6165 family and 88E6351 family devices
*
*******************************************************************************/
GT_STATUS gvctGetAdvExtendedStatus
(
    IN  GT_QD_DEV     *dev,
    IN  GT_LPORT   port,
    OUT GT_ADV_EXTENDED_STATUS *extendedStatus
)
{
	GT_STATUS retVal;
	GT_U8 hwPort;
	GT_BOOL ppuEn;
	GT_PHY_INFO	phyInfo;
	GT_BOOL			autoOn;
	GT_U16			pageReg;

    DBG_INFO(("gvctGetAdvExtendedStatus 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((retVal = gsysSetPPUEn(dev,GT_FALSE)) != GT_OK)
		{
	    	DBG_INFO(("Not able to disable PPUEn.\n"));
			gtSemGive(dev,dev->phyRegsSem);
			return retVal;
		}
		gtDelay(250);
	}

	if(driverPagedAccessStart(dev,hwPort,phyInfo.pageType,&autoOn,&pageReg) != GT_OK)
	{
		gtSemGive(dev,dev->phyRegsSem);
		return GT_FAIL;
	}

    switch(phyInfo.exStatusType)
    {
        case GT_PHY_EX_STATUS_TYPE1:
            if((retVal = getExStatus_28(dev,hwPort,&phyInfo,extendedStatus)) != GT_OK)
            {
                DBG_INFO(("Getting Extanded Cable Status failed.\n"));
                break;
            }
            break;

        case GT_PHY_EX_STATUS_TYPE2:
        case GT_PHY_EX_STATUS_TYPE3:
        case GT_PHY_EX_STATUS_TYPE4:
        case GT_PHY_EX_STATUS_TYPE5:
        case GT_PHY_EX_STATUS_TYPE6:
            if((retVal = getExStatus(dev,hwPort,&phyInfo,extendedStatus)) != GT_OK)
            {
                DBG_INFO(("Getting Extanded Cable Status failed.\n"));
                break;
            }

            break;
        default:
			retVal = GT_NOT_SUPPORTED;
    }

	return retVal;
}

