/*
@func ret_t | rtl8367b_getAsicPowerSaving | Get power saving mode
@parm rtk_uint32 | port | The port number
@parm rtk_uint32* | enable | enable power saving mode.
@rvalue RT_ERR_OK | Success.
@rvalue RT_ERR_SMI | SMI access error. 
@rvalue RT_ERR_PORT_ID | Invalid port number.
@comm
    The API can get power saving mode per phy.
*/
ret_t rtl8367b_getAsicPowerSaving(rtk_uint32 phy, rtk_uint32* enable)
{
    rtk_api_ret_t retVal;
    rtk_uint32 phyData;

    if(phy > RTL8367B_PHYIDMAX)
        return RT_ERR_PORT_ID;

    if ((retVal = rtl8367b_setAsicPHYReg(phy,RTL8367B_PHY_PAGE_ADDRESS,0))!=RT_ERR_OK)
        return retVal;  
    
    if ((retVal = rtl8367b_getAsicPHYReg(phy,PHY_POWERSAVING_REG,&phyData))!=RT_ERR_OK)
        return retVal;

    if ((phyData & PHY_POWERSAVING_MASK) > 0)
        *enable = 1;
    else 
        *enable = 0;
    
    return RT_ERR_OK;
}
/*
@func ret_t | rtl8367b_setAsicPowerSaving | Set power saving mode
@parm rtk_uint32 | phy | phy number
@parm rtk_uint32 | enable | enable power saving mode.
@rvalue RT_ERR_OK | Success.
@rvalue RT_ERR_SMI | SMI access error. 
@rvalue RT_ERR_PORT_ID | Invalid port number.
@comm
    The API can set power saving mode per phy.
*/
ret_t rtl8367b_setAsicPowerSaving(rtk_uint32 phy, rtk_uint32 enable)
{
    rtk_api_ret_t retVal;
    rtk_uint32 phyData;

    if(phy > RTL8367B_PHYIDMAX)
        return RT_ERR_PORT_ID;
    if (enable > 1)
        return RT_ERR_INPUT;

    if ((retVal = rtl8367b_setAsicPHYReg(phy,RTL8367B_PHY_PAGE_ADDRESS,0))!=RT_ERR_OK)
        return retVal;  
    
    if ((retVal = rtl8367b_getAsicPHYReg(phy,PHY_POWERSAVING_REG,&phyData))!=RT_ERR_OK)
        return retVal;

    phyData = (phyData & (~PHY_POWERSAVING_MASK)) | (enable<<PHY_POWERSAVING_OFFSET) ;

    if ((retVal = rtl8367b_setAsicPHYReg(phy,PHY_POWERSAVING_REG,phyData))!=RT_ERR_OK)
        return retVal;

    return RT_ERR_OK;
}
/* Function Name:
 *      rtl8367b_getAsicPortRTCTResult
 * Description:
 *      Get RTCT result
 * Input:
 *      port 	- Port ID of RTCT result
 * Output:
 *      pResult - The result of port ID
 * Return:
 *      RT_ERR_OK 		            - Success
 *      RT_ERR_SMI  	            - SMI access error
 *      RT_ERR_PORT_MASK            - Invalid port mask
 *      RT_ERR_PHY_RTCT_NOT_FINISH  - RTCT test doesn't finish.
 * Note:
 *      RTCT test takes 4.8 seconds at most.
 *      If this API returns RT_ERR_PHY_RTCT_NOT_FINISH,
 *      users should wait a whole then read it again.
 */
ret_t rtl8367b_getAsicPortRTCTResult(rtk_uint32 port, rtl8367b_port_rtct_result_t *pResult)
{
    ret_t       retVal;
    rtk_uint32  regData, finish = 1;

    if(port >= RTL8367B_PHYNO)
		return RT_ERR_PORT_ID;

    if((retVal = rtl8367b_setAsicPHYReg(port, RTL8367B_PHY_PAGE_ADDRESS, RTL8367B_RTCT_PAGE)) != RT_ERR_OK)
        return retVal;

    if((retVal = rtl8367b_getAsicPHYReg(port, RTL8367B_RTCT_RESULT_A_REG, &regData)) != RT_ERR_OK)
        return retVal;

    if((regData & 0x4000) == 0x4000)
    {
        pResult->channelALen = regData & 0x1FFF;

        if((retVal = rtl8367b_getAsicPHYReg(port, RTL8367B_RTCT_RESULT_B_REG, &regData)) != RT_ERR_OK)
            return retVal;

        pResult->channelBLen = regData & 0x1FFF;

        if((retVal = rtl8367b_getAsicPHYReg(port, RTL8367B_RTCT_RESULT_C_REG, &regData)) != RT_ERR_OK)
            return retVal;

        pResult->channelCLen = regData & 0x1FFF;

        if((retVal = rtl8367b_getAsicPHYReg(port, RTL8367B_RTCT_RESULT_D_REG, &regData)) != RT_ERR_OK)
            return retVal;

        pResult->channelDLen = regData & 0x1FFF;

        if((retVal = rtl8367b_getAsicPHYReg(port, RTL8367B_RTCT_STATUS_REG, &regData)) != RT_ERR_OK)
            return retVal;

        pResult->channelALinedriver = (regData & 0x0001);
        pResult->channelBLinedriver = (regData & 0x0002);
        pResult->channelCLinedriver = (regData & 0x0004);
        pResult->channelDLinedriver = (regData & 0x0008);

        pResult->channelAMismatch   = (regData & 0x0010);
        pResult->channelBMismatch   = (regData & 0x0020);
        pResult->channelCMismatch   = (regData & 0x0040);
        pResult->channelDMismatch   = (regData & 0x0080);

        pResult->channelAOpen       = (regData & 0x0100);
        pResult->channelBOpen       = (regData & 0x0200);
        pResult->channelCOpen       = (regData & 0x0400);
        pResult->channelDOpen       = (regData & 0x0800);

        pResult->channelAShort      = (regData & 0x1000);
        pResult->channelBShort      = (regData & 0x2000);
        pResult->channelCShort      = (regData & 0x4000);
        pResult->channelDShort      = (regData & 0x8000);
    }
    else
        finish = 0;

    if((retVal = rtl8367b_setAsicPHYReg(port, RTL8367B_PHY_PAGE_ADDRESS, 0)) != RT_ERR_OK)
        return retVal;

    if(finish == 0)
        return RT_ERR_PHY_RTCT_NOT_FINISH;
    else
        return RT_ERR_OK;
}