/* * Copyright (C) 2019 Realtek Semiconductor Corp. * All Rights Reserved. * * This program is the proprietary software of Realtek Semiconductor * Corporation and/or its licensors, and only be used, duplicated, * modified or distributed under the authorized license from Realtek. * * ANY USE OF THE SOFTWARE OTHER THAN AS AUTHORIZED UNDER * THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. * * Purpose : PHY 8251b Driver * * Feature : PHY 8251b Driver * */ // #include // #include // #include // #include // #include // #include #include "rtl8251b_typedef.h" #include "nic_rtl8251b.h" #include "nic_rtl8251b_init.h" BOOLEAN Rtl8251b_phy_reset( IN HANDLE hDevice ) { BOOL status = FAILURE; UINT16 phydata0 = 0, phydata1 = 0; UINT16 waitcount = 0; status = MmdPhyRead(hDevice, MMD_PMAPMD, 0x0, &phydata0); if (status != SUCCESS) goto exit; phydata1 |= BIT_15; status = MmdPhyWrite(hDevice, MMD_PMAPMD, 0x0, phydata1); if (status != SUCCESS) goto exit; while(TRUE) { status = MmdPhyRead(hDevice, MMD_PMAPMD, 0x0, &phydata1); if (status != SUCCESS) goto exit; if (!(phydata1 & BIT_15)) break; if (++waitcount == 500) { status = FAILURE; goto exit; } } status = MmdPhyWrite(hDevice, MMD_PMAPMD, 0x0, phydata0); if (status != SUCCESS) goto exit; exit: return status; } BOOLEAN Rtl8251b_autoNegoEnable_get( IN HANDLE hDevice, OUT BOOL *pEnable ) { BOOL status = FAILURE; UINT16 phydata = 0; status = MmdPhyRead(hDevice, MMD_AN, 0, &phydata); if (status != SUCCESS) goto exit; *pEnable = (phydata & BIT_12) ? (TRUE) : (FALSE); exit: return status; } BOOLEAN Rtl8251b_autoNegoEnable_set( IN HANDLE hDevice, IN BOOL Enable ) { BOOL status = FAILURE; UINT16 phydata = 0; // AutoNegotiationEnable status = MmdPhyRead(hDevice, MMD_AN, 0, &phydata); if (status != SUCCESS) goto exit; if (Enable) phydata |= BIT_12; else phydata &= (~BIT_12); status = MmdPhyWrite(hDevice, MMD_AN, 0, phydata); if (status != SUCCESS) goto exit; // RestartAutoNegotiation status = MmdPhyRead(hDevice, MMD_VEND2, 0xA400, &phydata); if (status != SUCCESS) goto exit; phydata |= BIT_9; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA400, phydata); if (status != SUCCESS) goto exit; exit: return status; } BOOLEAN Rtl8251b_autoNegoRestart( IN HANDLE hDevice ) { BOOL status = FAILURE; UINT16 phydata = 0; // RestartAutoNegotiation status = MmdPhyRead(hDevice, MMD_VEND2, 0xA400, &phydata); if (status != SUCCESS) goto exit; phydata |= BIT_9; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA400, phydata); if (status != SUCCESS) goto exit; exit: return status; } BOOLEAN Rtl8251b_autoNegoAbility_get( IN HANDLE hDevice, OUT PHY_LINK_ABILITY *pPhyAbility ) { BOOL status = FAILURE; UINT16 phydata = 0; status = MmdPhyRead(hDevice, MMD_AN, 16, &phydata); if (status != SUCCESS) goto exit; // 10M pPhyAbility->Half_10 = (phydata & BIT_5) ? (1) : (0); pPhyAbility->Full_10 = (phydata & BIT_6) ? (1) : (0); // 100M pPhyAbility->Half_100 = (phydata & BIT_7) ? (1) : (0); pPhyAbility->Full_100 = (phydata & BIT_8) ? (1) : (0); pPhyAbility->FC = (phydata & BIT_10) ? (1) : (0); pPhyAbility->AsyFC = (phydata & BIT_11) ? (1) : (0); // 1G status = MmdPhyRead(hDevice, MMD_VEND2, 0xA412, &phydata); if (status != SUCCESS) goto exit; pPhyAbility->Full_1000 = (phydata & BIT_9) ? (1) : (0); // 2.5G status = MmdPhyRead(hDevice, MMD_AN, 32, &phydata); if (status != SUCCESS) goto exit; pPhyAbility->adv_2_5G = (phydata & BIT_7) ? (1) : (0); // 5G status = MmdPhyRead(hDevice, MMD_AN, 32, &phydata); if (status != SUCCESS) goto exit; pPhyAbility->adv_5G = (phydata & BIT_8) ? (1) : (0); exit: return status; } BOOLEAN Rtl8251b_autoNegoAbility_set( IN HANDLE hDevice, IN PHY_LINK_ABILITY *pPhyAbility ) { BOOL status = FAILURE; UINT16 phydata = 0; status = MmdPhyRead(hDevice, MMD_AN, 16, &phydata); if (status != SUCCESS) goto exit; phydata &= (~(BIT_5 | BIT_6 | BIT_7 | BIT_8 | BIT_10 | BIT_11)); // 10M phydata |= (pPhyAbility->Half_10 ? (BIT_5) : (0)); phydata |= (pPhyAbility->Full_10 ? (BIT_6) : (0)); // 100M phydata |= (pPhyAbility->Half_100 ? (BIT_7) : (0)); phydata |= (pPhyAbility->Full_100 ? (BIT_8) : (0)); phydata |= (pPhyAbility->FC ? (BIT_10) : (0)); phydata |= (pPhyAbility->AsyFC ? (BIT_11) : (0)); status = MmdPhyWrite(hDevice, MMD_AN, 16, phydata); if (status != SUCCESS) goto exit; // 1G status = MmdPhyRead(hDevice, MMD_VEND2, 0xA412, &phydata); if (status != SUCCESS) goto exit; phydata &= (~BIT_9); phydata |= (pPhyAbility->Full_1000 ? (BIT_9) : (0)); status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA412, phydata); if (status != SUCCESS) goto exit; // 2.5G status = MmdPhyRead(hDevice, MMD_AN, 32, &phydata); if (status != SUCCESS) goto exit; phydata &= (~BIT_7); phydata |= (pPhyAbility->adv_2_5G ? (BIT_7) : (0)); status = MmdPhyWrite(hDevice, MMD_AN, 32, phydata); if (status != SUCCESS) goto exit; // 5G status = MmdPhyRead(hDevice, MMD_AN, 32, &phydata); if (status != SUCCESS) goto exit; phydata &= (~BIT_8); phydata |= (pPhyAbility->adv_5G ? (BIT_8) : (0)); status = MmdPhyWrite(hDevice, MMD_AN, 32, phydata); if (status != SUCCESS) goto exit; if (MmdPhyRead(hDevice, MMD_AN, 0, &phydata) == SUCCESS) { if (phydata & BIT_12) /* AN_ENABLE */ { phydata |= BIT_9; /* RESTART_AN */ MmdPhyWrite(hDevice, MMD_AN, 0, phydata); } } SLEEP_1MS; exit: return status; } BOOLEAN Rtl8251b_duplex_get( IN HANDLE hDevice, OUT BOOL *pEnable ) { BOOL status = FAILURE; UINT16 phydata = 0; status = MmdPhyRead(hDevice, MMD_VEND2, 0xA434, &phydata); if (status != SUCCESS) goto exit; *pEnable = (phydata & BIT_3) ? (TRUE) : (FALSE); exit: return status; } BOOLEAN Rtl8251b_duplex_set( // christy add 0430 IN HANDLE hDevice, IN BOOL Enable ) { BOOL status = FAILURE; UINT16 phydata = 0; status = MmdPhyRead(hDevice, MMD_VEND2, 0xA400, &phydata); if (status != SUCCESS) goto exit; if (Enable) phydata |= BIT_8; else phydata &= (~BIT_8); status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA400, phydata); if (status != SUCCESS) goto exit; exit: return status; } BOOLEAN Rtl8251b_is_link( IN HANDLE hDevice, OUT BOOL *plinkOK ) { BOOL status = FAILURE; UINT16 phydata = 0; UINT8 i = 0; // must read twice for(i=0;i<2;i++) { status = MmdPhyRead(hDevice, MMD_VEND2, 0xA402, &phydata); if (status != SUCCESS) goto exit; } *plinkOK = (phydata & BIT_2) ? (TRUE) : (FALSE); exit: return status; } BOOLEAN Rtl8251b_speed_get( IN HANDLE hDevice, OUT UINT16 *pSpeed ) { BOOL status = FAILURE; UINT16 phydata = 0; UINT8 speed_grp = 0; UINT8 speed = NO_LINK; // int i = 0; BOOL linkOK = FALSE; status = Rtl8251b_is_link(hDevice, &linkOK); if (status != SUCCESS) goto exit; if (linkOK) { status = MmdPhyRead(hDevice, MMD_VEND2, 0xA434, &phydata); if (status != SUCCESS) goto exit; speed_grp = (phydata & (BIT_9 | BIT_10)) >> 9; speed = (phydata & (BIT_4 | BIT_5)) >> 4; switch(speed_grp) { case 0: { switch(speed) { case 0: *pSpeed = LINK_SPEED_10M; break; case 1: *pSpeed = LINK_SPEED_100M; break; case 2: *pSpeed = LINK_SPEED_1G; break; case 3: *pSpeed = LINK_SPEED_500M; break; default: status = FAILURE; break; } break; } case 1: { switch(speed) { case 1: *pSpeed = LINK_SPEED_2P5G; break; case 2: *pSpeed = LINK_SPEED_5G; //5G break; case 3: *pSpeed = LINK_SPEED_1G; // 2.5G lite break; default: status = FAILURE; break; } break; } default: status = FAILURE; break; } } else { *pSpeed = NO_LINK; } exit: return status; } BOOLEAN Rtl8251b_enable_set( IN HANDLE hDevice, IN BOOL Enable ) { BOOL status = FAILURE; UINT16 phydata = 0; status = MmdPhyRead(hDevice, MMD_PMAPMD, 0, &phydata); if (status != SUCCESS) goto exit; if (Enable) phydata &= (~BIT_11); // set as 0 else phydata |= BIT_11; // set as 1 status = MmdPhyWrite(hDevice, MMD_PMAPMD, 0, phydata); if (status != SUCCESS) goto exit; exit: return status; } BOOLEAN Rtl8251b_force_speed_set( IN HANDLE hDevice, IN UINT16 Speed ) { BOOL status = FAILURE; UINT16 phydata0 = 0, phydata1 = 0; BOOL support = 0; status = MmdPhyRead(hDevice, MMD_PMAPMD, 0, &phydata0); if (status != SUCCESS) goto exit; phydata0 &= (~(BIT_6 | BIT_13)); switch(Speed) { case 10: support = TRUE; phydata0 &= (~BIT_6); phydata0 &= (~BIT_13); break; case 100: support = TRUE; phydata0 &= (~BIT_6); phydata0 |= BIT_13; break; case 1000: support = TRUE; phydata0 |= BIT_6; phydata0 &= (~BIT_13); break; case 2500: support = TRUE; phydata0 &= (~(BIT_2 | BIT_3 | BIT_4 | BIT_5)); phydata0 |= BIT_6; phydata0 |= BIT_13; phydata0 &= (~BIT_2); // 0 phydata0 |= BIT_3; // 1 phydata0 |= BIT_4; // 1 phydata0 &= (~BIT_5); // 0 break; case 5000: support = TRUE; phydata0 &= (~(BIT_2 | BIT_3 | BIT_4 | BIT_5)); phydata0 |= BIT_6; phydata0 |= BIT_13; phydata0 |= BIT_2; // 1 phydata0 |= BIT_3; // 1 phydata0 |= BIT_4; // 1 phydata0 &= (~BIT_5); // 0 break; default: status = FAILURE; support = FALSE; break; } if (support) { status = MmdPhyRead(hDevice, MMD_VEND2, 0xA5B4, &phydata1); if (status != SUCCESS) goto exit; phydata1 |= (BIT_15); status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA5B4, phydata1); if (status != SUCCESS) goto exit; status = MmdPhyWrite(hDevice, MMD_PMAPMD, 0, phydata0); if (status != SUCCESS) goto exit; status = Rtl8251b_autoNegoEnable_set(hDevice, FALSE); if (status != SUCCESS) goto exit; } else status = FAILURE; exit: return status; } BOOLEAN Rtl8251b_greenEnable_get( IN HANDLE hDevice, OUT BOOL *pEnable ) { BOOL status = FAILURE; UINT16 phydata = 0; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA436, 0x8011); if (status != SUCCESS) goto exit; status = MmdPhyRead(hDevice, MMD_VEND2, 0xA438, &phydata); if (status != SUCCESS) goto exit; *pEnable = (phydata & BIT_15) ? (TRUE) : (FALSE); exit: return status; } BOOLEAN Rtl8251b_greenEnable_set( IN HANDLE hDevice, IN BOOL Enable ) { BOOL status = FAILURE; UINT16 phydata = 0; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA436, 0x8011); if (status != SUCCESS) goto exit; status = MmdPhyRead(hDevice, MMD_VEND2, 0xA438, &phydata); if (status != SUCCESS) goto exit; if (Enable) phydata |= (BIT_15); else phydata &= (~BIT_15); status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA438, phydata); if (status != SUCCESS) goto exit; exit: return status; } BOOLEAN Rtl8251b_eeeEnable_get( IN HANDLE hDevice, OUT PHY_EEE_ENABLE *pEeeEnable ) { BOOL status = FAILURE; UINT16 phydata = 0; status = MmdPhyRead(hDevice, MMD_AN, 60, &phydata); if (status != SUCCESS) goto exit; pEeeEnable->EEE_100 = (phydata & BIT_1) ? (TRUE) : (FALSE); pEeeEnable->EEE_1000 = (phydata & BIT_2) ? (TRUE) : (FALSE); status = MmdPhyRead(hDevice, MMD_AN, 62, &phydata); if (status != SUCCESS) goto exit; pEeeEnable->EEE_2_5G = (phydata & BIT_0) ? (TRUE) : (FALSE); pEeeEnable->EEE_5G = (phydata & BIT_1) ? (TRUE) : (FALSE); exit: return status; } BOOLEAN Rtl8251b_eeeEnable_set( IN HANDLE hDevice, IN PHY_EEE_ENABLE *pEeeEnable ) { BOOL status = FAILURE; UINT16 phydata = 0; BOOL AnEnable = 0; status = Rtl8251b_autoNegoEnable_get(hDevice, &AnEnable); if (status != SUCCESS) goto exit; // 100M/1G EEE status = MmdPhyRead(hDevice, MMD_AN, 60, &phydata); if (status != SUCCESS) goto exit; if (pEeeEnable->EEE_100) phydata |= BIT_1; else phydata &= (~BIT_1); if (pEeeEnable->EEE_1000) phydata |= BIT_2; else phydata &= (~BIT_2); status = MmdPhyWrite(hDevice, MMD_AN, 60, phydata); if (status != SUCCESS) goto exit; // 2.5G EEE status = MmdPhyRead(hDevice, MMD_AN, 62, &phydata); if (status != SUCCESS) goto exit; if (pEeeEnable->EEE_2_5G) phydata |= BIT_0; else phydata &= (~BIT_0); status = MmdPhyWrite(hDevice, MMD_AN, 62, phydata); if (status != SUCCESS) goto exit; // 5G EEE status = MmdPhyRead(hDevice, MMD_AN, 62, &phydata); if (status != SUCCESS) goto exit; if (pEeeEnable->EEE_5G) phydata |= BIT_1; else phydata &= (~BIT_1); status = MmdPhyWrite(hDevice, MMD_AN, 62, phydata); if (status != SUCCESS) goto exit; // RestartAutoNegotiation if (AnEnable) { status = MmdPhyRead(hDevice, MMD_VEND2, 0xA400, &phydata); if (status != SUCCESS) goto exit; phydata |= BIT_9; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA400, phydata); if (status != SUCCESS) goto exit; } exit: return status; } BOOLEAN Rtl8251b_crossOverMode_get( IN HANDLE hDevice, OUT PHY_CROSSPVER_MODE *CrossOverMode ) { BOOL status = FAILURE; UINT16 phydata = 0; status = MmdPhyRead(hDevice, MMD_VEND2, 0xA430, &phydata); if (status != SUCCESS) goto exit; if((phydata & BIT_9) >> 9) { switch((phydata & BIT_8) >> 8) { case 1: *CrossOverMode = PHY_CROSSPVER_MODE_MDI; break; case 0: *CrossOverMode = PHY_CROSSPVER_MODE_MDIX; break; default: status = FAILURE; break; } } else *CrossOverMode = PHY_CROSSPVER_MODE_AUTO; exit: return status; } BOOLEAN Rtl8251b_crossOverMode_set( IN HANDLE hDevice, IN PHY_CROSSPVER_MODE CrossOverMode ) { BOOL status = FAILURE; UINT16 phydata = 0; status = MmdPhyRead(hDevice, MMD_VEND2, 0xA430, &phydata); if (status != SUCCESS) goto exit; phydata &= (~(BIT_8 | BIT_9)); switch(CrossOverMode) { case PHY_CROSSPVER_MODE_MDI: phydata |= (BIT_8 | BIT_9); break; case PHY_CROSSPVER_MODE_MDIX: phydata |= BIT_9; break; case PHY_CROSSPVER_MODE_AUTO: break; default: status = FAILURE; goto exit; } status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA430, phydata); if (status != SUCCESS) goto exit; exit: return status; } BOOLEAN Rtl8251b_crossOverStatus_get( IN HANDLE hDevice, OUT PHY_CROSSPVER_STATUS *pCrossOverStatus ) { BOOL status = FAILURE; UINT16 phydata = 0; status = MmdPhyRead(hDevice, MMD_VEND2, 0xA434, &phydata); if (status != SUCCESS) goto exit; *pCrossOverStatus = (phydata & BIT_1) ? (PHY_CROSSPVER_STATUS_MDI) : (PHY_CROSSPVER_STATUS_MDIX); exit: return status; } BOOLEAN Rtl8251b_masterSlave_get( IN HANDLE hDevice, OUT PHY_MASTERSLAVE_MODE *MasterSlaveMode ) { BOOL status = FAILURE; UINT16 phydata = 0; status = MmdPhyRead(hDevice, MMD_AN, 33, &phydata); if (status != SUCCESS) goto exit; switch((phydata >> 14) & 0x3) { case 0: // 0:Slave, 1:Master *MasterSlaveMode = PHY_SLAVE_MODE; break; case 1: *MasterSlaveMode = PHY_MASTER_MODE; break; default: status = FAILURE; break; } exit: return status; } BOOLEAN Rtl8251b_masterSlave_set( IN HANDLE hDevice, IN PHY_MASTERSLAVE_MODE MasterSlaveMode ) { BOOL status = FAILURE; UINT16 phydata = 0; status = MmdPhyRead(hDevice, MMD_AN, 32, &phydata); if (status != SUCCESS) goto exit; phydata &= (~(BIT_14 | BIT_15)); switch(MasterSlaveMode) { case PHY_AUTO_MODE: break; case PHY_SLAVE_MODE: phydata |= BIT_15; break; case PHY_MASTER_MODE: phydata |= (BIT_14 | BIT_15); break; default: status = FAILURE; goto exit; } status = MmdPhyWrite(hDevice, MMD_AN, 32, phydata); if (status != SUCCESS) goto exit; exit: return status; } BOOLEAN Rtl8251b_loopback_get( IN HANDLE hDevice, OUT BOOL *pEnable ) { BOOL status = FAILURE; UINT16 phydata = 0; status = MmdPhyRead(hDevice, MMD_PCS, 0x0, &phydata); if (status != SUCCESS) goto exit; *pEnable = (phydata & BIT_14) ? (TRUE) : (FALSE); exit: return status; } BOOLEAN Rtl8251b_loopback_set( IN HANDLE hDevice, IN BOOL Enable ) { BOOL status = FAILURE; UINT16 phydata = 0; status = MmdPhyRead(hDevice, MMD_PCS, 0x0, &phydata); if (status != SUCCESS) goto exit; if (Enable) phydata |= BIT_14; else phydata &= (~BIT_14); status = MmdPhyWrite(hDevice, MMD_PCS, 0x0, phydata); if (status != SUCCESS) goto exit; exit: return status; } BOOLEAN Rtl8251b_PMA_loopback_get( IN HANDLE hDevice, OUT BOOL *pEnable ) { BOOL status = FAILURE; UINT16 phydata = 0; status = MmdPhyRead(hDevice, MMD_PMAPMD, 0x0, &phydata); if (status != SUCCESS) goto exit; *pEnable = (phydata & BIT_0) ? (TRUE) : (FALSE); exit: return status; } BOOLEAN Rtl8251b_PMA_loopback_set( IN HANDLE hDevice, IN BOOL Enable ) { BOOL status = FAILURE; UINT16 phydata = 0; status = MmdPhyRead(hDevice, MMD_PMAPMD, 0x0, &phydata); if (status != SUCCESS) goto exit; if (Enable) phydata |= BIT_0; else phydata &= (~BIT_0); status = MmdPhyWrite(hDevice, MMD_PMAPMD, 0x0, phydata); if (status != SUCCESS) goto exit; exit: return status; } BOOLEAN Rtl8251b_downSpeedEnable_get( IN HANDLE hDevice, OUT BOOL *pEnable ) { BOOL status = FAILURE; UINT16 phydata = 0; status = MmdPhyRead(hDevice, MMD_VEND2, 0xA442, &phydata); if (status != SUCCESS) goto exit; *pEnable = (phydata & BIT_3) ? (TRUE) : (FALSE); exit: return status; } BOOLEAN Rtl8251b_downSpeedEnable_set( IN HANDLE hDevice, IN BOOL Enable ) { BOOL status = FAILURE; UINT16 phydata = 0; status = MmdPhyRead(hDevice, MMD_VEND2, 0xA442, &phydata); if (status != SUCCESS) goto exit; phydata &= (~BIT_5); if (Enable) phydata |= BIT_3; else phydata &= (~BIT_3); status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA442, phydata); if (status != SUCCESS) goto exit; exit: return status; } BOOLEAN Rtl8251b_gigaLiteEnable_get( IN HANDLE hDevice, OUT BOOL *pEnable ) { BOOL status = FAILURE; UINT16 phydata = 0; status = MmdPhyRead(hDevice, MMD_VEND2, 0xA428, &phydata); if (status != SUCCESS) goto exit; *pEnable = (phydata & BIT_9) ? (TRUE) : (FALSE); exit: return status; } BOOLEAN Rtl8251b_gigaLiteEnable_set( IN HANDLE hDevice, IN BOOL Enable ) { BOOL status = FAILURE; UINT16 phydata0 = 0, phydata1 = 0; status = MmdPhyRead(hDevice, MMD_VEND2, 0xA442, &phydata0); if (status != SUCCESS) goto exit; status = MmdPhyRead(hDevice, MMD_VEND2, 0xA428, &phydata1); if (!status) goto exit; if (Enable) { phydata0 |= (BIT_2 | BIT_9); phydata1 |= BIT_9; } else { phydata0 &= (~(BIT_2 | BIT_9)); phydata1 &= (~BIT_9); } status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA442, phydata0); if (status != SUCCESS) goto exit; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA428, phydata1); if (status != SUCCESS) goto exit; exit: return status; } BOOLEAN Rtl8251b_mdiSwapEnable_get( IN HANDLE hDevice, OUT BOOL *pEnable ) { BOOL status = FAILURE; UINT16 phydata = 0; status = MmdPhyRead(hDevice, MMD_VEND1, 0x6A21, &phydata); if (status != SUCCESS) goto exit; *pEnable = (phydata & BIT_5) ? (TRUE) : (FALSE); exit: return status; } BOOLEAN Rtl8251b_mdiSwapEnable_set( IN HANDLE hDevice, IN BOOL Enable ) { BOOL status = FAILURE; BOOL Flag_mdi_swap = 0; UINT16 phydata = 0; UINT16 phydata0 = 0; UINT16 phydata1 = 0; UINT16 phydata2 = 0; UINT16 phydata3 = 0; UINT16 _6A21_5 = 0; UINT16 adccal_offset_p0 = 0; UINT16 adccal_offset_p1 = 0; UINT16 adccal_offset_p2 = 0; UINT16 adccal_offset_p3 = 0; UINT16 rg_lpf_cap_xg_p0 = 0; UINT16 rg_lpf_cap_xg_p1 = 0; UINT16 rg_lpf_cap_xg_p2 = 0; UINT16 rg_lpf_cap_xg_p3 = 0; UINT16 rg_lpf_cap_p0 = 0; UINT16 rg_lpf_cap_p1 = 0; UINT16 rg_lpf_cap_p2 = 0; UINT16 rg_lpf_cap_p3 = 0; status = MmdPhyRead(hDevice, MMD_VEND1, 0x6A21, &_6A21_5); if (status != SUCCESS) goto exit; status = MmdPhyRead(hDevice, MMD_VEND2, 0xD068, &phydata); if (status != SUCCESS) goto exit; Flag_mdi_swap = (phydata & 0x0002)? 1:0; if (!Flag_mdi_swap){ printf("MDI already swap \n"); goto exit; } phydata0 = phydata & 0xFFE0; phydata0 |= 0x0001; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xD068, phydata0); if (status != SUCCESS) goto exit; status = MmdPhyRead(hDevice, MMD_VEND2, 0xD06A, &adccal_offset_p0); if (status != SUCCESS) goto exit; phydata1 = phydata & 0xFFE0; phydata1 |= 0x0009; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xD068, phydata1); if (status != SUCCESS) goto exit; status = MmdPhyRead(hDevice, MMD_VEND2, 0xD06A, &adccal_offset_p1); if (status != SUCCESS) goto exit; phydata2 = phydata & 0xFFE0; phydata2 |= 0x0011; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xD068, phydata2); if (status != SUCCESS) goto exit; status = MmdPhyRead(hDevice, MMD_VEND2, 0xD06A, &adccal_offset_p2); if (status != SUCCESS) goto exit; phydata3 = phydata & 0xFFE0; phydata3 |= 0x0019; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xD068, phydata3); if (status != SUCCESS) goto exit; status = MmdPhyRead(hDevice, MMD_VEND2, 0xD06A, &adccal_offset_p3); if (status != SUCCESS) goto exit; status = MmdPhyRead(hDevice, MMD_VEND2, 0xBD5A, &phydata); if (status != SUCCESS) goto exit; rg_lpf_cap_xg_p0 = phydata & 0x001F; rg_lpf_cap_xg_p1 = phydata & 0x1F00; status = MmdPhyRead(hDevice, MMD_VEND2, 0xBD5C, &phydata); if (status != SUCCESS) goto exit; rg_lpf_cap_xg_p2 = phydata & 0x001F; rg_lpf_cap_xg_p3 = phydata & 0x1F00; status = MmdPhyRead(hDevice, MMD_VEND2, 0xBC18, &phydata); if (status != SUCCESS) goto exit; rg_lpf_cap_p0 = phydata & 0x001F; rg_lpf_cap_p1 = phydata & 0x1F00; status = MmdPhyRead(hDevice, MMD_VEND2, 0xBC1A, &phydata); if (status != SUCCESS) goto exit; rg_lpf_cap_p2 = phydata & 0x001F; rg_lpf_cap_p3 = phydata & 0x1F00; if (Enable) { _6A21_5 |= (BIT_5); status = MmdPhyWrite(hDevice, MMD_VEND1, 0x6A21, _6A21_5); if (status != SUCCESS) goto exit; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xD068, phydata0); if (status != SUCCESS) goto exit; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xD06A, adccal_offset_p3); if (status != SUCCESS) goto exit; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xD068, phydata1); if (status != SUCCESS) goto exit; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xD06A, adccal_offset_p2); if (status != SUCCESS) goto exit; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xD068, phydata2); if (status != SUCCESS) goto exit; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xD06A, adccal_offset_p1); if (status != SUCCESS) goto exit; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xD068, phydata3); if (status != SUCCESS) goto exit; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xD06A, adccal_offset_p0); if (status != SUCCESS) goto exit; status = MmdPhyRead(hDevice, MMD_VEND2, 0xBD5A, &phydata); if (status != SUCCESS) goto exit; phydata &= 0xE0E0; phydata = ( rg_lpf_cap_xg_p3 >>8 ) | (rg_lpf_cap_xg_p2 << 8) | phydata; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xBD5A, phydata); if (status != SUCCESS) goto exit; status = MmdPhyRead(hDevice, MMD_VEND2, 0xBD5C, &phydata); if (status != SUCCESS) goto exit; phydata &= 0xE0E0; phydata = (rg_lpf_cap_xg_p1 >>8) | (rg_lpf_cap_xg_p0 <<8)| phydata; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xBD5C, phydata); if (status != SUCCESS) goto exit; status = MmdPhyRead(hDevice, MMD_VEND2, 0xBC18, &phydata); if (status != SUCCESS) goto exit; phydata &= 0xE0E0; phydata = (rg_lpf_cap_p3 >>8) | (rg_lpf_cap_p2 <<8) | phydata; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xBC18, phydata); if (status != SUCCESS) goto exit; status = MmdPhyRead(hDevice, MMD_VEND2, 0xBC1A, &phydata); if (status != SUCCESS) goto exit; phydata &= 0xE0E0; phydata = (rg_lpf_cap_p1 >>8) | (rg_lpf_cap_p0 <<8) | phydata; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xBC1A, phydata); if (status != SUCCESS) goto exit; } /* else { _6A21_5 &= (~(BIT_5)); status = MmdPhyWrite(hDevice, MMD_VEND1, 0x6A21, _6A21_5); if (status != SUCCESS) goto exit; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xD068, phydata0); if (status != SUCCESS) goto exit; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xD06A, adccal_offset_p0); if (status != SUCCESS) goto exit; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xD068, phydata1); if (status != SUCCESS) goto exit; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xD06A, adccal_offset_p1); if (status != SUCCESS) goto exit; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xD068, phydata2); if (status != SUCCESS) goto exit; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xD06A, adccal_offset_p2); if (status != SUCCESS) goto exit; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xD068, phydata3); if (status != SUCCESS) goto exit; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xD06A, adccal_offset_p3); if (status != SUCCESS) goto exit; status = MmdPhyRead(hDevice, MMD_VEND2, 0xBD5A, &phydata); if (status != SUCCESS) goto exit; phydata &= 0xE0E0; phydata = rg_lpf_cap_xg_p1 | rg_lpf_cap_xg_p0 | phydata; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xBD5A, phydata); if (status != SUCCESS) goto exit; status = MmdPhyRead(hDevice, MMD_VEND2, 0xBD5C, &phydata); if (status != SUCCESS) goto exit; phydata &= 0xE0E0; phydata = rg_lpf_cap_xg_p2 | rg_lpf_cap_xg_p3 | phydata; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xBD5C, phydata); if (status != SUCCESS) goto exit; status = MmdPhyRead(hDevice, MMD_VEND2, 0xBC18, &phydata); if (status != SUCCESS) goto exit; phydata &= 0xE0E0; phydata = rg_lpf_cap_p1 | rg_lpf_cap_p0 | phydata; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xBC18, phydata); if (status != SUCCESS) goto exit; status = MmdPhyRead(hDevice, MMD_VEND2, 0xBC1A, &phydata); if (status != SUCCESS) goto exit; phydata &= 0xE0E0; phydata = rg_lpf_cap_p3 | rg_lpf_cap_p2 | phydata; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xBC1A, phydata); if (status != SUCCESS) goto exit; }*/ exit: return status; } BOOLEAN Rtl8251b_rtct_start( IN HANDLE hDevice ) { BOOL status = FAILURE; UINT16 phydata = 0; BOOL linkOK; UINT16 Speed; status = Rtl8251b_is_link(hDevice, &linkOK); if (status != SUCCESS) goto exit; if (linkOK) { status = Rtl8251b_speed_get(hDevice, &Speed); if (status != SUCCESS) goto exit; //RTCT is not supported when port link at 10M. if (Speed == 10) { printf("RTCT is not supported when port link at 10M.\n"); status = FAILURE; goto exit; } } else { // MMD 31.0xA422[15] = 0 // clear rtct_done status = MmdPhyRead(hDevice, MMD_VEND2, 0xA422, &phydata); if (status != SUCCESS) goto exit; phydata &= (~BIT_15); status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA442, phydata); if (status != SUCCESS) goto exit; // wait 1ms for chip reset the states SLEEP_1MS; // MMD 31.0xA422[4] = 1 // RTCT_CH_A status = MmdPhyRead(hDevice, MMD_VEND2, 0xA422, &phydata); if (status != SUCCESS) goto exit; phydata |= (BIT_4); status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA442, phydata); if (status != SUCCESS) goto exit; // MMD 31.0xA422[5] = 1 // RTCT_CH_B status = MmdPhyRead(hDevice, MMD_VEND2, 0xA422, &phydata); if (status != SUCCESS) goto exit; phydata |= (BIT_5); status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA442, phydata); if (status != SUCCESS) goto exit; // MMD 31.0xA422[6] = 1 // RTCT_CH_C status = MmdPhyRead(hDevice, MMD_VEND2, 0xA422, &phydata); if (status != SUCCESS) goto exit; phydata |= (BIT_6); status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA442, phydata); if (status != SUCCESS) goto exit; // MMD 31.0xA422[7] = 1 // RTCT_CH_D status = MmdPhyRead(hDevice, MMD_VEND2, 0xA422, &phydata); if (status != SUCCESS) goto exit; phydata |= (BIT_7); status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA442, phydata); if (status != SUCCESS) goto exit; // MMD 31.0xA422[0] = 1 // RTCT_ENABLE status = MmdPhyRead(hDevice, MMD_VEND2, 0xA422, &phydata); if (status != SUCCESS) goto exit; phydata |= (BIT_0); status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA442, phydata); if (status != SUCCESS) goto exit; } exit: return status; } BOOLEAN Rtl8251b_rtctResult_convert( IN UINT16 phydata, OUT PHY_RTCT_STATUS *pRtctStatus ) { BOOL status = SUCCESS; switch(phydata) { case 0x60: // Normal break; case 0x48: pRtctStatus->Open = TRUE; break; case 0x50: pRtctStatus->Short = TRUE; break; case 0x42: pRtctStatus->Mismatch = MIS_MATCH_OPEN; break; case 0x44: pRtctStatus->Mismatch = MIS_MATCH_SHORT; break; default: status = FAILURE; break; } return status; } BOOLEAN Rtl8251b_rtctResult_get( IN HANDLE hDevice, OUT PHY_RTCT_RESULT *pRtctResult ) { BOOL status = FAILURE; UINT16 phydata = 0; BOOL linkOK = FALSE; UINT16 Speed = NO_LINK; BOOL rtct_done; status = Rtl8251b_is_link(hDevice, &linkOK); if (status != SUCCESS) goto exit; if (linkOK) { status = Rtl8251b_speed_get(hDevice, &Speed); if (status != SUCCESS) goto exit; switch(Speed) { case LINK_SPEED_100M: // rxLen = MMD 31.0xA880[7:0] * 100 // unit is meter // txLen = MMD 31.0xA880[7:0] * 100 status = MmdPhyRead(hDevice, MMD_VEND2, 0xA880, &phydata); if (status != SUCCESS) goto exit; pRtctResult->rxLen = (phydata & 0xff) * 100; pRtctResult->txLen = (phydata & 0xff) * 100; break; case LINK_SPEED_1G: // channelALen = MMD 31.0xA880[7:0] * 100 // unit is meter // channelBLen = MMD 31.0xA880[7:0] * 100 // channelCLen = MMD 31.0xA880[7:0] * 100 // channelDLen = MMD 31.0xA880[7:0] * 100 status = MmdPhyRead(hDevice, MMD_VEND2, 0xA880, &phydata); if (status != SUCCESS) goto exit; pRtctResult->channelALen = (phydata & 0xff) * 100; pRtctResult->channelBLen = (phydata & 0xff) * 100; pRtctResult->channelCLen = (phydata & 0xff) * 100; pRtctResult->channelDLen = (phydata & 0xff) * 100; break; case LINK_SPEED_2P5G: //channelALen = MMD 31.0xAC58[11:4] * 100 // cablen for XG status = MmdPhyRead(hDevice, MMD_VEND2, 0xAC58, &phydata); if (status != SUCCESS) goto exit; pRtctResult->channelALen = ((phydata & 0xff0) >> 4 ) * 100; pRtctResult->channelBLen = ((phydata & 0xff0) >> 4 ) * 100; pRtctResult->channelCLen = ((phydata & 0xff0) >> 4 ) * 100; pRtctResult->channelDLen = ((phydata & 0xff0) >> 4 ) * 100; break; case LINK_SPEED_5G: //channelALen = MMD 31.0xAC58[11:4] * 100 // cablen for XG status = MmdPhyRead(hDevice, MMD_VEND2, 0xAC58, &phydata); if (status != SUCCESS) goto exit; pRtctResult->channelALen = ((phydata & 0xff0) >> 4 ) * 100; pRtctResult->channelBLen = ((phydata & 0xff0) >> 4 ) * 100; pRtctResult->channelCLen = ((phydata & 0xff0) >> 4 ) * 100; pRtctResult->channelDLen = ((phydata & 0xff0) >> 4 ) * 100; break; //RTCT is not supported when port link at 10M. default: status = FAILURE; break; } } else { status = MmdPhyRead(hDevice, MMD_VEND2, 0xA422, &phydata); if (status != SUCCESS) goto exit; rtct_done = (phydata & BIT_15) ? (TRUE) : (FALSE); if (!rtct_done) { status = FAILURE; goto exit; } // MMD 31.0A436[15:0] = 0x8029 // phyData = read MMD 31.0A438[15:0] // channelALen = phyData * 100 / 80 // channelALen (unit: cm) status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA436, 0x8029); if (status != SUCCESS) goto exit; status = MmdPhyRead(hDevice, MMD_VEND2, 0x0A438, &phydata); if (status != SUCCESS) goto exit; pRtctResult->channelALen = (phydata * 100) / 80; // MMD 31.0A436[15:0] = 0x802D // phyData = read MMD 31.0A438[15:0] // channelBLen = phyData * 100 / 80 // channelBLen (unit: cm) status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA436, 0x802D); if (status != SUCCESS) goto exit; status = MmdPhyRead(hDevice, MMD_VEND2, 0x0A438, &phydata); if (status != SUCCESS) goto exit; pRtctResult->channelBLen = (phydata * 100) / 80; // MMD 31.0A436[15:0] = 0x8031 // phyData = read MMD 31.0A438[15:0] // channelCLen = phyData * 100 / 80 // channelCLen (unit: cm) status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA436, 0x8031); if (status != SUCCESS) goto exit; status = MmdPhyRead(hDevice, MMD_VEND2, 0x0A438, &phydata); if (status != SUCCESS) goto exit; pRtctResult->channelCLen = (phydata * 100) / 80; // MMD 31.0A436[15:0] = 0x8035 // phyData = read MMD 31.0A438[15:0] // channelDLen = phyData * 100 / 80 // channelDLen (unit: cm) status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA436, 0x8035); if (status != SUCCESS) goto exit; status = MmdPhyRead(hDevice, MMD_VEND2, 0x0A438, &phydata); if (status != SUCCESS) goto exit; pRtctResult->channelDLen = (phydata * 100) / 80; // channelA status status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA436, 0x8027); if (status != SUCCESS) goto exit; status = MmdPhyRead(hDevice, MMD_VEND2, 0x0A438, &phydata); if (status != SUCCESS) goto exit; status = Rtl8251b_rtctResult_convert(phydata, &pRtctResult->channelAStatus); if (status != SUCCESS) goto exit; // channelA status status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA436, 0x802B); if (status != SUCCESS) goto exit; status = MmdPhyRead(hDevice, MMD_VEND2, 0x0A438, &phydata); if (status != SUCCESS) goto exit; status = Rtl8251b_rtctResult_convert(phydata, &pRtctResult->channelBStatus); if (status != SUCCESS) goto exit; // channelC status status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA436, 0x802F); if (status != SUCCESS) goto exit; status = MmdPhyRead(hDevice, MMD_VEND2, 0x0A438, &phydata); if (status != SUCCESS) goto exit; status = Rtl8251b_rtctResult_convert(phydata, &pRtctResult->channelCStatus); if (status != SUCCESS) goto exit; // channelD status status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA436, 0x8033); if (status != SUCCESS) goto exit; status = MmdPhyRead(hDevice, MMD_VEND2, 0x0A438, &phydata); if (status != SUCCESS) goto exit; status = Rtl8251b_rtctResult_convert(phydata, &pRtctResult->channelDStatus); if (status != SUCCESS) goto exit; } exit: return status; } BOOLEAN Rtl8251b_linkDownPowerSavingEnable_get( IN HANDLE hDevice, OUT BOOL *pEnable ) { BOOL status = FAILURE; UINT16 phydata = 0; status = MmdPhyRead(hDevice, MMD_VEND2, 0xA430, &phydata); if (status != SUCCESS) goto exit; *pEnable = (phydata & BIT_2) ? (TRUE) : (FALSE); exit: return status; } BOOLEAN Rtl8251b_linkDownPowerSavingEnable_set( IN HANDLE hDevice, IN BOOL Enable ) { BOOL status = FAILURE; UINT16 phydata = 0; status = MmdPhyRead(hDevice, MMD_VEND2, 0xA430, &phydata); if (status != SUCCESS) goto exit; if (Enable) phydata |= BIT_2; else phydata &= (~BIT_2); status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA430, phydata); if (status != SUCCESS) goto exit; exit: return status; } BOOLEAN Rtl8251b_2p5gLiteEnable_get( IN HANDLE hDevice, OUT BOOL *pEnable ) { BOOL status = FAILURE; UINT16 phydata = 0; status = MmdPhyRead(hDevice, MMD_VEND2, 0xA5EA, &phydata); if (status != SUCCESS) goto exit; *pEnable = (phydata & BIT_0) ? (TRUE) : (FALSE); exit: return status; } BOOLEAN Rtl8251b_2p5gLiteEnable_set( IN HANDLE hDevice, IN BOOL Enable ) { BOOL status = FAILURE; UINT16 phydata0 = 0, phydata1 = 0, phydata2 = 0; status = MmdPhyRead(hDevice, MMD_VEND2, 0xA442, &phydata0); if (status != SUCCESS) goto exit; status = MmdPhyRead(hDevice, MMD_VEND2, 0xA5FA, &phydata1); if (status != SUCCESS) goto exit; status = MmdPhyRead(hDevice, MMD_VEND2, 0xA5EA, &phydata2); if (status != SUCCESS) goto exit; phydata0 &= (~BIT_2); phydata1 &= (~BIT_1); phydata2 &= (~BIT_0); if (Enable) { phydata0 |= BIT_2; phydata1 |= BIT_1; phydata2 |= BIT_0; } status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA442, phydata0); if (status != SUCCESS) goto exit; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA5FA, phydata1); if (status != SUCCESS) goto exit; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA5EA, phydata2); if (status != SUCCESS) goto exit; exit: return status; } BOOLEAN Rtl8251b_ThermalSensorEnable_get( IN HANDLE hDevice, OUT BOOL *pEnable ) { BOOL status = FAILURE; UINT16 phydata = 0; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA436, 0x81A2); if (status != SUCCESS) goto exit; status = MmdPhyRead(hDevice, MMD_VEND2, 0xA438, &phydata); if (status != SUCCESS) goto exit; *pEnable = (phydata & BIT_8) ? (TRUE) : (FALSE); exit: return status; } BOOLEAN Rtl8251b_ThermalSensorEnable_set( IN HANDLE hDevice, IN BOOL Enable ) { BOOL status = FAILURE; UINT16 phydata = 0; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA436, 0x81A2); if (status != SUCCESS) goto exit; status = MmdPhyRead(hDevice, MMD_VEND2, 0xA438, &phydata); if (status != SUCCESS) goto exit; if (Enable) phydata |= BIT_8; else phydata &= (~BIT_8); status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA438, phydata); if (status != SUCCESS) goto exit; exit: return status; } BOOLEAN Rtl8251b_ieeeTestMode_set( IN HANDLE hDevice, IN UINT16 Speed, IN PHY_IEEE_TEST_MODE *pIEEEtestmode ) { BOOL status = FAILURE; UINT16 phydata = 0, phydata_w = 0, phydata2 = 0; switch(Speed) { case LINK_SPEED_1G: { // status = MmdPhyRead(hDevice, MMD_VEND2, 0xBD2C, &phydata); if (status != SUCCESS) goto exit; status = MmdPhyRead(hDevice, MMD_VEND2, 0xBD32, &phydata2); if (status != SUCCESS) goto exit; if(pIEEEtestmode -> channel == TESTMODE_CHANNEL_NONE){ phydata &= (~(BIT_10)); } else{ phydata |= BIT_10; if(pIEEEtestmode -> channel == TESTMODE_CHANNEL_A) phydata_w = 1 << 8; else if(pIEEEtestmode -> channel == TESTMODE_CHANNEL_B) phydata_w = 2 << 8; else if(pIEEEtestmode -> channel == TESTMODE_CHANNEL_C) phydata_w = 4 << 8; else if(pIEEEtestmode -> channel == TESTMODE_CHANNEL_D) phydata_w = 8 << 8; phydata2 &= (~(BIT_11 | BIT_10 | BIT_9 | BIT_8)); phydata2 |= phydata_w; } status = MmdPhyWrite(hDevice, MMD_VEND2, 0xBD32, phydata2); if (status != SUCCESS) goto exit; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xBD2C, phydata); if (status != SUCCESS) goto exit; if (pIEEEtestmode->TM1) { //printf("Giga TestMode 1 \n"); status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA412, 0x2000); if (status != SUCCESS) goto exit; } if (pIEEEtestmode->TM2) { status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA412, 0x4000); if (status != SUCCESS) goto exit; } if (pIEEEtestmode->TM4) { status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA412, 0x8000); if (status != SUCCESS) goto exit; } if (pIEEEtestmode->TMFINISH) { status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA412, 0x0000); if (status != SUCCESS) goto exit; status = MmdPhyRead(hDevice, MMD_VEND2, 0xBD2C, &phydata); if (status != SUCCESS) goto exit; phydata &= (~(BIT_10)); status = MmdPhyWrite(hDevice, MMD_VEND2, 0xBD2C, phydata); if (status != SUCCESS) goto exit; } break; } case LINK_SPEED_2P5G: { // status = MmdPhyRead(hDevice, MMD_VEND2, 0xBD2C, &phydata); if (status != SUCCESS) goto exit; status = MmdPhyRead(hDevice, MMD_VEND2, 0xBD32, &phydata2); if (status != SUCCESS) goto exit; if(pIEEEtestmode -> channel == TESTMODE_CHANNEL_NONE){ phydata &= (~(BIT_8)); } else{ phydata |= BIT_8; if(pIEEEtestmode -> channel == TESTMODE_CHANNEL_A) phydata_w = 1; else if(pIEEEtestmode -> channel == TESTMODE_CHANNEL_B) phydata_w = 2; else if(pIEEEtestmode -> channel == TESTMODE_CHANNEL_C) phydata_w = 4; else if(pIEEEtestmode -> channel == TESTMODE_CHANNEL_D) phydata_w = 8; phydata2 &= (~(BIT_3 | BIT_2 | BIT_1 | BIT_0)); phydata2 |= phydata_w; } status = MmdPhyWrite(hDevice, MMD_VEND2, 0xBD32, phydata2); if (status != SUCCESS) goto exit; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xBD2C, phydata); if (status != SUCCESS) goto exit; // 2.5G Test Mode // MMD 1.0.15:0 = 0x2058 status = MmdPhyWrite(hDevice, MMD_PMAPMD, 0, 0x2058); if (status != SUCCESS) goto exit; if (pIEEEtestmode->TM1) { status = MmdPhyWrite(hDevice, MMD_PMAPMD, 132, 0x2400); if (status != SUCCESS) goto exit; } if (pIEEEtestmode->TM2) { status = MmdPhyWrite(hDevice, MMD_PMAPMD, 132, 0x4400); if (status != SUCCESS) goto exit; } if (pIEEEtestmode->TM3) { status = MmdPhyWrite(hDevice, MMD_PMAPMD, 132, 0x6400); if (status != SUCCESS) goto exit; } if (pIEEEtestmode->TM4) { if (pIEEEtestmode->TONE1) { status = MmdPhyWrite(hDevice, MMD_PMAPMD, 132, 0x8400); if (status != SUCCESS) goto exit; } if (pIEEEtestmode->TONE2) { status = MmdPhyWrite(hDevice, MMD_PMAPMD, 132, 0x8800); if (status != SUCCESS) goto exit; } if (pIEEEtestmode->TONE3) { status = MmdPhyWrite(hDevice, MMD_PMAPMD, 132, 0x9000); if (status != SUCCESS) goto exit; } if (pIEEEtestmode->TONE4) { status = MmdPhyWrite(hDevice, MMD_PMAPMD, 132, 0x9400); if (status != SUCCESS) goto exit; } if (pIEEEtestmode->TONE5) { status = MmdPhyWrite(hDevice, MMD_PMAPMD, 132, 0x9800); if (status != SUCCESS) goto exit; } } if (pIEEEtestmode->TM5) { status = MmdPhyWrite(hDevice, MMD_PMAPMD, 132, 0xA400); if (status != SUCCESS) goto exit; } if (pIEEEtestmode->TM6) { status = MmdPhyWrite(hDevice, MMD_PMAPMD, 132, 0xC400); if (status != SUCCESS) goto exit; } if (pIEEEtestmode->TMFINISH) { status = MmdPhyRead(hDevice, MMD_VEND2, 0xBD2C, &phydata); if (status != SUCCESS) goto exit; phydata &= (~(BIT_8)); status = MmdPhyWrite(hDevice, MMD_VEND2, 0xBD2C, phydata); if (status != SUCCESS) goto exit; //re-nway and set phy_rst) status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA400, 0x9200); if (status != SUCCESS) goto exit; } break; } case LINK_SPEED_5G: { // status = MmdPhyRead(hDevice, MMD_VEND2, 0xBD2C, &phydata); if (status != SUCCESS) goto exit; status = MmdPhyRead(hDevice, MMD_VEND2, 0xBD32, &phydata2); if (status != SUCCESS) goto exit; if(pIEEEtestmode -> channel == TESTMODE_CHANNEL_NONE){ phydata &= (~(BIT_8)); } else{ phydata |= BIT_8; if(pIEEEtestmode -> channel == TESTMODE_CHANNEL_A) phydata_w = 1; else if(pIEEEtestmode -> channel == TESTMODE_CHANNEL_B) phydata_w = 2; else if(pIEEEtestmode -> channel == TESTMODE_CHANNEL_C) phydata_w = 4; else if(pIEEEtestmode -> channel == TESTMODE_CHANNEL_D) phydata_w = 8; phydata2 &= (~(BIT_3 | BIT_2 | BIT_1 | BIT_0)); phydata2 |= phydata_w; } status = MmdPhyWrite(hDevice, MMD_VEND2, 0xBD32, phydata2); if (status != SUCCESS) goto exit; status = MmdPhyWrite(hDevice, MMD_VEND2, 0xBD2C, phydata); if (status != SUCCESS) goto exit; // 5G Test Mode // MMD 1.0.15:0 = 0x205C status = MmdPhyWrite(hDevice, MMD_PMAPMD, 0, 0x205C); if (status != SUCCESS) goto exit; if (pIEEEtestmode->TM1) { status = MmdPhyWrite(hDevice, MMD_PMAPMD, 132, 0x2400); if (status != SUCCESS) goto exit; } if (pIEEEtestmode->TM2) { status = MmdPhyWrite(hDevice, MMD_PMAPMD, 132, 0x4400); if (status != SUCCESS) goto exit; } if (pIEEEtestmode->TM3) { status = MmdPhyWrite(hDevice, MMD_PMAPMD, 132, 0x6400); if (status != SUCCESS) goto exit; } if (pIEEEtestmode->TM4) { if (pIEEEtestmode->TONE1) { status = MmdPhyWrite(hDevice, MMD_PMAPMD, 132, 0x8400); if (status != SUCCESS) goto exit; } if (pIEEEtestmode->TONE2) { status = MmdPhyWrite(hDevice, MMD_PMAPMD, 132, 0x8800); if (status != SUCCESS) goto exit; } if (pIEEEtestmode->TONE3) { status = MmdPhyWrite(hDevice, MMD_PMAPMD, 132, 0x9000); if (status != SUCCESS) goto exit; } if (pIEEEtestmode->TONE4) { status = MmdPhyWrite(hDevice, MMD_PMAPMD, 132, 0x9400); if (status != SUCCESS) goto exit; } if (pIEEEtestmode->TONE5) { status = MmdPhyWrite(hDevice, MMD_PMAPMD, 132, 0x9800); if (status != SUCCESS) goto exit; } } if (pIEEEtestmode->TM5) { status = MmdPhyWrite(hDevice, MMD_PMAPMD, 132, 0xA400); if (status != SUCCESS) goto exit; } if (pIEEEtestmode->TM6) { status = MmdPhyWrite(hDevice, MMD_PMAPMD, 132, 0xC400); if (status != SUCCESS) goto exit; } if (pIEEEtestmode->TMFINISH) { status = MmdPhyRead(hDevice, MMD_VEND2, 0xBD2C, &phydata); if (status != SUCCESS) goto exit; phydata &= (~(BIT_8)); status = MmdPhyWrite(hDevice, MMD_VEND2, 0xBD2C, phydata); if (status != SUCCESS) goto exit; //re-nway and set phy_rst) status = MmdPhyWrite(hDevice, MMD_VEND2, 0xA400, 0x9200); if (status != SUCCESS) goto exit; } break; } // only support 1G or 2.5G. default: break; } exit: return status; } BOOLEAN Rtl8251b_serdes_rst( IN HANDLE hDevice ) { BOOL status = FAILURE; UINT16 phydata = 0; status = MmdPhyRead(hDevice, MMD_VEND1, 0x7581, &phydata); if (status != SUCCESS) goto exit; phydata &= (~BIT_4); status = MmdPhyWrite(hDevice, MMD_VEND1, 0x7581, phydata); if (status != SUCCESS) goto exit; // wait 10 us SLEEP_1MS; status = MmdPhyRead(hDevice, MMD_VEND1, 0x7581, &phydata); if (status != SUCCESS) goto exit; phydata |= BIT_4; status = MmdPhyWrite(hDevice, MMD_VEND1, 0x7581, phydata); if (status != SUCCESS) goto exit; // wait 10 us SLEEP_1MS; exit: return status; } BOOLEAN Rtl8251b_serdes_link_get( IN HANDLE hDevice, OUT BOOL *perdesLink, OUT PHY_SERDES_MODE *SerdesMode ) { BOOL status = FAILURE; UINT16 phydata = 0; UINT16 phydata1 = 0; // serdes link status = MmdPhyRead(hDevice, MMD_VEND1, 0x758D, &phydata); if (status != SUCCESS) goto exit; *perdesLink = (phydata & BIT_1) ? (TRUE) : (FALSE); status = MmdPhyRead(hDevice, MMD_VEND1, 0x758B, &phydata); if (status != SUCCESS) goto exit; phydata &= BIT_0; if (phydata == 1){ //serdes mode status = MmdPhyRead(hDevice, MMD_VEND1, 0x7580, &phydata); if (status != SUCCESS) goto exit; phydata1 = phydata; phydata &= (BIT_4 | BIT_3 | BIT_2 | BIT_1 | BIT_0); phydata1 &= (BIT_14 | BIT_13 | BIT_12 | BIT_11 | BIT_10); if(phydata == 2) *SerdesMode = PHY_SERDES_MODE_SGMII; else if(phydata == 21) *SerdesMode = PHY_SERDES_MODE_5000BASEX; else if(phydata == 13) *SerdesMode = PHY_SERDES_MODE_USXGMII; else if(phydata == 18) *SerdesMode = PHY_SERDES_MODE_HiSGMII; else if(phydata == 22) *SerdesMode = PHY_SERDES_MODE_2500BASEX; else if((phydata == 26)&&(phydata1 == 0)) *SerdesMode = PHY_SERDES_MODE_SFI_10GBASER; else if((phydata == 26)&&(phydata1 == 2)) *SerdesMode = PHY_SERDES_MODE_5000BASER; else if(phydata == 31) *SerdesMode = PHY_SERDES_MODE_NO_SDS; else *SerdesMode = PHY_SERDES_MODE_OTHER; } else{ *SerdesMode = PHY_SERDES_MODE_NO_SDS; } printf("Rtl8251b_serdes_link_get %d",*SerdesMode); exit: return status; } BOOLEAN Rtl8251b_serdes_option_set( IN HANDLE hDevice, IN UINT8 functioninput ) { /* The RTL8251B supports SERDES setting options related to Link_down_option, Rate_adaptor_en, and SERDES_speed at the different Ethernet speeds which is different from RTL8221. According to the Ethernet speed, use a specific address to set SERDES Setting Options*/ BOOL status = FAILURE; UINT16 phydata = 0; if ((functioninput >= 0) && (functioninput <= 7)) { /* 5G-Lite: 30.0x6973.15:8 */ status = MmdPhyRead(hDevice, MMD_VEND1, 0x6973, &phydata); if (status != SUCCESS) goto exit; phydata &= (~(BIT_11 | BIT_10 | BIT_9 | BIT_8 )); phydata |= functioninput; status = MmdPhyWrite(hDevice, MMD_VEND1, 0x6973, phydata); if (status != SUCCESS) goto exit; /* 5G: 30.0x6973.7:0 */ status = MmdPhyRead(hDevice, MMD_VEND1, 0x6973, &phydata); if (status != SUCCESS) goto exit; phydata &= (~(BIT_0 | BIT_1 | BIT_2 | BIT_3 )); phydata |= functioninput; status = MmdPhyWrite(hDevice, MMD_VEND1, 0x6973, phydata); if (status != SUCCESS) goto exit; /* 2.5G-Lite: 30.0x6974.15:8 */ status = MmdPhyRead(hDevice, MMD_VEND1, 0x6974, &phydata); if (status != SUCCESS) goto exit; phydata &= (~(BIT_11 | BIT_10 | BIT_9 | BIT_8 )); phydata |= functioninput; status = MmdPhyWrite(hDevice, MMD_VEND1, 0x6974, phydata); if (status != SUCCESS) goto exit; /* 2.5G: 30.0x6974.7:0 */ status = MmdPhyRead(hDevice, MMD_VEND1, 0x6974, &phydata); if (status != SUCCESS) goto exit; phydata &= (~(BIT_0 | BIT_1 | BIT_2 | BIT_3 )); phydata |= functioninput; status = MmdPhyWrite(hDevice, MMD_VEND1, 0x6974, phydata); if (status != SUCCESS) goto exit; /* 1G-Lite: 30.0x6975.15:8 */ status = MmdPhyRead(hDevice, MMD_VEND1, 0x6975, &phydata); if (status != SUCCESS) goto exit; phydata &= (~(BIT_11 | BIT_10 | BIT_9 | BIT_8 )); phydata |= functioninput; status = MmdPhyWrite(hDevice, MMD_VEND1, 0x6975, phydata); if (status != SUCCESS) goto exit; /* 1G: 30.0x6975.7:0 */ status = MmdPhyRead(hDevice, MMD_VEND1, 0x6975, &phydata); if (status != SUCCESS) goto exit; phydata &= (~(BIT_0 | BIT_1 | BIT_2 | BIT_3 )); phydata |= functioninput; status = MmdPhyWrite(hDevice, MMD_VEND1, 0x6975, phydata); if (status != SUCCESS) goto exit; /* 100M: 30.0x6976.7:0 */ status = MmdPhyRead(hDevice, MMD_VEND1, 0x6976, &phydata); if (status != SUCCESS) goto exit; phydata &= (~(BIT_0 | BIT_1 | BIT_2 | BIT_3 )); phydata |= functioninput; status = MmdPhyWrite(hDevice, MMD_VEND1, 0x6976, phydata); if (status != SUCCESS) goto exit; /* 10M: 30.0x6977.7:0 */ status = MmdPhyRead(hDevice, MMD_VEND1, 0x6977, &phydata); if (status != SUCCESS) goto exit; phydata &= (~(BIT_0 | BIT_1 | BIT_2 | BIT_3 )); phydata |= functioninput; status = MmdPhyWrite(hDevice, MMD_VEND1, 0x6977, phydata); if (status != SUCCESS) goto exit; } exit: return status; } BOOLEAN Rtl8251b_serdes_polarity_swap( IN HANDLE hDevice, IN PHY_SERDES_POLARITY_SWAP *ppolarityswap ) { BOOL status = FAILURE; UINT16 phydata = 0; status = MmdPhyWrite(hDevice, MMD_VEND1, 0x7588, 0x0); if (status != SUCCESS) goto exit; if (ppolarityswap->TX_SWAP && ppolarityswap->RX_SWAP) phydata = 0x1703; else if (ppolarityswap->TX_SWAP) phydata = 0x1503; else if (ppolarityswap->RX_SWAP) phydata = 0x1603; else phydata = 0x1403; status = MmdPhyWrite(hDevice, MMD_VEND1, 0x7589, phydata); if (status != SUCCESS) goto exit; status = MmdPhyWrite(hDevice, MMD_VEND1, 0x7587, 0x0003); if (status != SUCCESS) goto exit; exit: return status; } BOOLEAN Rtl8251b_serdes_autoNego_set( IN HANDLE hDevice, IN BOOL Enable ) { BOOL status = FAILURE; UINT16 phydata = 0; status = MmdPhyWrite(hDevice, MMD_VEND1, 0x7588, 0x00f1); if (status != SUCCESS) goto exit; /* Enable/Disable USXGMII Auto-Negotiation */ /* If you need to disable HiSGMII Auto-Negotiation, see 《SERDES Mode Setting Flow Application Note》 */ if (Enable) phydata = 0x854F; else phydata = 0x854E; status = MmdPhyWrite(hDevice, MMD_VEND1, 0x7589, phydata); if (status != SUCCESS) goto exit; status = MmdPhyWrite(hDevice, MMD_VEND1, 0x7587, 0x0003); if (status != SUCCESS) goto exit; exit: return status; }