#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>

#ifdef GT_USE_MAD
#include <gtMad.h>
#endif

#ifdef GT_USE_MAD
#include "gtVct_mad.c"
#endif

/*******************************************************************************
* 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"));


    /* Wait until the Table is ready. */
    /*
     *     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"));

    /* 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,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;

#ifdef GT_USE_MAD
    if (dev->use_mad==GT_TRUE)
    {
        return gvctGetCableDiag_mad(dev, port, cableStatus);
    }
#endif

    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;
}
