The link was previously configured via firmware, but this approach
resulted in unstable link behavior. To resolve the issue, re-add the
PHY configuration flow directly into the driver.

Fixes: ead3616f630d ("net/txgbe: support PHY configuration via SW-FW mailbox")
Cc: [email protected]

Signed-off-by: Zaiyu Wang <[email protected]>
---
 drivers/net/txgbe/base/meson.build    |    1 +
 drivers/net/txgbe/base/txgbe.h        |    2 +
 drivers/net/txgbe/base/txgbe_aml.c    |   65 +-
 drivers/net/txgbe/base/txgbe_aml40.c  |   43 +-
 drivers/net/txgbe/base/txgbe_e56.c    |   22 +-
 drivers/net/txgbe/base/txgbe_e56.h    |    2 +
 drivers/net/txgbe/base/txgbe_e56_bp.c | 2593 +++++++++++++++++++++++++
 drivers/net/txgbe/base/txgbe_e56_bp.h |    3 +
 drivers/net/txgbe/base/txgbe_hw.c     |    6 +
 drivers/net/txgbe/base/txgbe_hw.h     |    4 +-
 drivers/net/txgbe/base/txgbe_osdep.h  |    4 +
 drivers/net/txgbe/base/txgbe_phy.c    |   21 +
 drivers/net/txgbe/base/txgbe_phy.h    |   22 +
 drivers/net/txgbe/base/txgbe_type.h   |   25 +-
 drivers/net/txgbe/txgbe_ethdev.c      |  109 +-
 drivers/net/txgbe/txgbe_ethdev.h      |    2 +-
 16 files changed, 2894 insertions(+), 30 deletions(-)
 create mode 100644 drivers/net/txgbe/base/txgbe_e56_bp.c

diff --git a/drivers/net/txgbe/base/meson.build 
b/drivers/net/txgbe/base/meson.build
index 305c0291e3..a9a02577ce 100644
--- a/drivers/net/txgbe/base/meson.build
+++ b/drivers/net/txgbe/base/meson.build
@@ -13,4 +13,5 @@ base_sources = files(
         'txgbe_phy.c',
         'txgbe_vf.c',
         'txgbe_e56.c',
+        'txgbe_e56_bp.c',
 )
diff --git a/drivers/net/txgbe/base/txgbe.h b/drivers/net/txgbe/base/txgbe.h
index 673a299860..27c3e3be38 100644
--- a/drivers/net/txgbe/base/txgbe.h
+++ b/drivers/net/txgbe/base/txgbe.h
@@ -13,5 +13,7 @@
 #include "txgbe_hw.h"
 #include "txgbe_vf.h"
 #include "txgbe_dcb.h"
+#include "txgbe_e56.h"
+#include "txgbe_e56_bp.h"
 
 #endif /* _TXGBE_H_ */
diff --git a/drivers/net/txgbe/base/txgbe_aml.c 
b/drivers/net/txgbe/base/txgbe_aml.c
index 008b0245e5..a5b9d951ea 100644
--- a/drivers/net/txgbe/base/txgbe_aml.c
+++ b/drivers/net/txgbe/base/txgbe_aml.c
@@ -13,6 +13,7 @@
 #include "txgbe_hw.h"
 #include "txgbe_aml.h"
 #include "txgbe_e56.h"
+#include "txgbe_e56_bp.h"
 
 void txgbe_init_ops_aml(struct txgbe_hw *hw)
 {
@@ -84,6 +85,13 @@ s32 txgbe_check_mac_link_aml(struct txgbe_hw *hw, u32 *speed,
                *speed = TXGBE_LINK_SPEED_UNKNOWN;
        }
 
+       if (txgbe_xpcs_an_enabled(hw)) {
+               if (!hw->an_done) {
+                       *link_up = false;
+                       *speed = TXGBE_LINK_SPEED_UNKNOWN;
+               }
+       }
+
        return 0;
 }
 
@@ -95,23 +103,41 @@ s32 txgbe_get_link_capabilities_aml(struct txgbe_hw *hw,
                *speed = TXGBE_LINK_SPEED_10GB_FULL |
                         TXGBE_LINK_SPEED_25GB_FULL;
                *autoneg = true;
+       } else if (hw->phy.sfp_type == txgbe_sfp_type_da_cu_core0 ||
+                  hw->phy.sfp_type == txgbe_sfp_type_da_cu_core1) {
+               if (hw->phy.fiber_suppport_speed ==
+                   TXGBE_LINK_SPEED_10GB_FULL) {
+                       hw->devarg.auto_neg = false;
+                       *autoneg = false;
+               } else {
+                       *autoneg = true;
+               }
+               *speed = hw->phy.fiber_suppport_speed;
        } else if (hw->phy.sfp_type == txgbe_sfp_type_25g_sr_core0 ||
                hw->phy.sfp_type == txgbe_sfp_type_25g_sr_core1 ||
                hw->phy.sfp_type == txgbe_sfp_type_25g_lr_core0 ||
-               hw->phy.sfp_type == txgbe_sfp_type_25g_lr_core1) {
+               hw->phy.sfp_type == txgbe_sfp_type_25g_lr_core1 ||
+               hw->phy.sfp_type == txgbe_sfp_type_25g_aoc_core0 ||
+               hw->phy.sfp_type == txgbe_sfp_type_25g_aoc_core1) {
                *speed = TXGBE_LINK_SPEED_25GB_FULL;
                *autoneg = false;
-       } else if (hw->phy.sfp_type == txgbe_sfp_type_25g_aoc_core0 ||
-                  hw->phy.sfp_type == txgbe_sfp_type_25g_aoc_core1) {
-               *speed = TXGBE_LINK_SPEED_25GB_FULL;
+       } else if (hw->phy.media_type == txgbe_media_type_backplane) {
+               /* Backplane */
+               *speed = TXGBE_LINK_SPEED_10GB_FULL |
+                        TXGBE_LINK_SPEED_25GB_FULL;
+               /* Backplane supports autonegotiation */
+               *autoneg = hw->devarg.auto_neg;
+       } else if (hw->phy.media_type == txgbe_media_type_fiber) {
+               /* Fiber */
+               *speed = TXGBE_LINK_SPEED_10GB_FULL |
+                        TXGBE_LINK_SPEED_25GB_FULL;
                *autoneg = false;
        } else {
-               /* SFP */
-               if (hw->phy.sfp_type == txgbe_sfp_type_not_present)
-                       *speed = TXGBE_LINK_SPEED_25GB_FULL;
-               else
-                       *speed = TXGBE_LINK_SPEED_10GB_FULL;
-               *autoneg = true;
+               /* Unknown */
+               *speed = TXGBE_LINK_SPEED_UNKNOWN;
+               *autoneg = false;
+               PMD_DRV_LOG(DEBUG, "GET link capabilities failed");
+               return TXGBE_ERR_LINK_SETUP;
        }
 
        return 0;
@@ -193,7 +219,7 @@ s32 txgbe_setup_phy_link_aml(struct txgbe_hw *hw,
 
        *need_reset = false;
 
-       if (hw->phy.sfp_type == txgbe_sfp_type_not_present) {
+       if (hw->phy.sfp_type == txgbe_sfp_type_not_present && 
!txgbe_is_backplane(hw)) {
                DEBUGOUT("SFP not detected, skip setup mac link");
                return 0;
        }
@@ -216,6 +242,23 @@ s32 txgbe_setup_phy_link_aml(struct txgbe_hw *hw,
        if (speed == TXGBE_LINK_SPEED_UNKNOWN)
                return TXGBE_ERR_LINK_SETUP;
 
+       if (txgbe_xpcs_an_enabled(hw)) {
+               txgbe_e56_check_phy_link(hw, &link_speed, &link_up);
+               if (link_up && hw->an_done && !autoneg_wait_to_complete)
+                       return status;
+               rte_spinlock_lock(&hw->phy_lock);
+               txgbe_e56_set_phy_link_mode(hw, speed, 
autoneg_wait_to_complete);
+               rte_spinlock_unlock(&hw->phy_lock);
+               return 0;
+       }
+
+       if (txgbe_is_backplane(hw) || txgbe_is_dac_cable(hw) ||
+           hw->phy.ffe_set) {
+               rte_spinlock_lock(&hw->phy_lock);
+               txgbe_e56_tx_ffe_cfg(hw, speed);
+               rte_spinlock_unlock(&hw->phy_lock);
+       }
+
        if (txgbe_gpio_ext_check(hw, TXGBE_SFP1_MOD_ABS_LS |
                                 TXGBE_SFP1_RX_LOS_LS)) {
                DEBUGOUT("RX LOS");
diff --git a/drivers/net/txgbe/base/txgbe_aml40.c 
b/drivers/net/txgbe/base/txgbe_aml40.c
index 84c130704a..d350f18c4b 100644
--- a/drivers/net/txgbe/base/txgbe_aml40.c
+++ b/drivers/net/txgbe/base/txgbe_aml40.c
@@ -14,6 +14,7 @@
 #include "txgbe_aml.h"
 #include "txgbe_aml40.h"
 #include "txgbe_e56.h"
+#include "txgbe_e56_bp.h"
 
 void txgbe_init_ops_aml40(struct txgbe_hw *hw)
 {
@@ -98,7 +99,10 @@ s32 txgbe_get_link_capabilities_aml40(struct txgbe_hw *hw,
        if (hw->phy.sfp_type == txgbe_qsfp_type_40g_cu_core0 ||
            hw->phy.sfp_type == txgbe_qsfp_type_40g_cu_core1) {
                *speed = TXGBE_LINK_SPEED_40GB_FULL;
-               *autoneg = false;
+               *autoneg = true;
+       } else if (txgbe_is_backplane(hw)) {
+               *speed = TXGBE_LINK_SPEED_40GB_FULL;
+               *autoneg = true;
        } else {
                /*
                 * Temporary workaround: set speed to 40G even if sfp not 
present
@@ -115,8 +119,22 @@ s32 txgbe_get_link_capabilities_aml40(struct txgbe_hw *hw,
 
 u32 txgbe_get_media_type_aml40(struct txgbe_hw *hw)
 {
-       UNREFERENCED_PARAMETER(hw);
-       return txgbe_media_type_fiber_qsfp;
+       u8 device_type = hw->subsystem_device_id & 0xF0;
+       enum txgbe_media_type media_type;
+
+       switch (device_type) {
+       case TXGBE_DEV_ID_KR_KX_KX4:
+               media_type = txgbe_media_type_backplane;
+               break;
+       case TXGBE_DEV_ID_SFP:
+               media_type = txgbe_media_type_fiber_qsfp;
+               break;
+       default:
+               media_type = txgbe_media_type_unknown;
+               break;
+       }
+
+       return media_type;
 }
 
 s32 txgbe_setup_phy_link_aml40(struct txgbe_hw *hw,
@@ -135,7 +153,7 @@ s32 txgbe_setup_phy_link_aml40(struct txgbe_hw *hw,
 
        *need_reset = false;
 
-       if (hw->phy.sfp_type == txgbe_sfp_type_not_present)
+       if (hw->phy.sfp_type == txgbe_sfp_type_not_present && 
!txgbe_is_backplane(hw))
                hw->phy.identify_sfp(hw);
 
        /* Check to see if speed passed in is supported. */
@@ -148,6 +166,23 @@ s32 txgbe_setup_phy_link_aml40(struct txgbe_hw *hw,
        if (speed == TXGBE_LINK_SPEED_UNKNOWN)
                return TXGBE_ERR_LINK_SETUP;
 
+       if (txgbe_xpcs_an_enabled(hw)) {
+               txgbe_e56_check_phy_link(hw, &link_speed, &link_up);
+               if (link_up && hw->an_done && !autoneg_wait_to_complete)
+                       return status;
+               rte_spinlock_lock(&hw->phy_lock);
+               txgbe_e56_set_phy_link_mode(hw, 40, autoneg_wait_to_complete);
+               rte_spinlock_unlock(&hw->phy_lock);
+               return status;
+       }
+
+       if (txgbe_is_backplane(hw) || txgbe_is_dac_cable(hw) ||
+           hw->phy.ffe_set) {
+               rte_spinlock_lock(&hw->phy_lock);
+               txgbe_e56_tx_ffe_cfg(hw, speed);
+               rte_spinlock_unlock(&hw->phy_lock);
+       }
+
        for (i = 0; i < 4; i++) {
                txgbe_e56_check_phy_link(hw, &link_speed, &link_up);
                if (link_up)
diff --git a/drivers/net/txgbe/base/txgbe_e56.c 
b/drivers/net/txgbe/base/txgbe_e56.c
index ebeae16e34..7ebd910823 100644
--- a/drivers/net/txgbe/base/txgbe_e56.c
+++ b/drivers/net/txgbe/base/txgbe_e56.c
@@ -49,7 +49,7 @@ int txgbe_e56_int_cmp(const void *a, const void *b)
 }
 
 s32 txgbe_e56_check_phy_link(struct txgbe_hw *hw, u32 *speed,
-                               bool *link_up)
+                                   bool *link_up)
 {
        u32 rdata = 0;
        u32 links_reg = 0;
@@ -97,7 +97,8 @@ u32 txgbe_e56_tx_ffe_cfg(struct txgbe_hw *hw, u32 speed)
                post = S10G_TX_FFE_CFG_POST;
        } else if (speed == TXGBE_LINK_SPEED_25GB_FULL) {
                if (hw->phy.sfp_type == txgbe_sfp_type_da_cu_core0 ||
-                   hw->phy.sfp_type == txgbe_sfp_type_da_cu_core1) {
+                   hw->phy.sfp_type == txgbe_sfp_type_da_cu_core1 ||
+                   txgbe_is_backplane(hw)) {
                        ffe_main = S25G_TX_FFE_CFG_DAC_MAIN;
                        pre1 = S25G_TX_FFE_CFG_DAC_PRE1;
                        pre2 = S25G_TX_FFE_CFG_DAC_PRE2;
@@ -115,7 +116,8 @@ u32 txgbe_e56_tx_ffe_cfg(struct txgbe_hw *hw, u32 speed)
                post = S10G_TX_FFE_CFG_POST;
 
                if (hw->phy.sfp_type == txgbe_qsfp_type_40g_cu_core0 ||
-                   hw->phy.sfp_type == txgbe_qsfp_type_40g_cu_core1) {
+                   hw->phy.sfp_type == txgbe_qsfp_type_40g_cu_core1 ||
+                   txgbe_is_backplane(hw)) {
                        ffe_main = S40G_TX_FFE_CFG_MAIN;
                        pre1 = S40G_TX_FFE_CFG_PRE1;
                        pre2 = S40G_TX_FFE_CFG_PRE2;
@@ -1504,7 +1506,7 @@ txgbe_e56_rxs_osc_init_for_temp_track_range(struct 
txgbe_hw *hw, u32 speed)
                        rdata = rd32_ephy(hw, addr);
 
                        if (timer++ > PHYINIT_TIMEOUT) {
-                               DEBUGOUT("ERROR: Wait 
E56PHY_CTRL_FSM_RX_STAT_0_ADDR Timeout!\n");
+                               DEBUGOUT("ERROR: Wait 
E56PHY_CTRL_FSM_RX_STAT_0_ADDR Timeout!");
                                break;
                                return -1;
                        }
@@ -1539,7 +1541,7 @@ txgbe_e56_rxs_osc_init_for_temp_track_range(struct 
txgbe_hw *hw, u32 speed)
                        if (((rdata >> (i * 8)) & 0x3f) == 0x21)
                                break;
                        if (timer++ > PHYINIT_TIMEOUT) {
-                               DEBUGOUT("ERROR: Wait 
E56PHY_CTRL_FSM_RX_STAT_0_ADDR Timeout!\n");
+                               DEBUGOUT("ERROR: Wait 
E56PHY_CTRL_FSM_RX_STAT_0_ADDR Timeout!");
                                break;
                                return -1;
                        }
@@ -1616,7 +1618,7 @@ txgbe_e56_rxs_osc_init_for_temp_track_range(struct 
txgbe_hw *hw, u32 speed)
                        addr  = E56PHY_CTRL_FSM_RX_STAT_0_ADDR;
                        rdata = rd32_ephy(hw, addr);
                        if (timer++ > PHYINIT_TIMEOUT) {
-                               DEBUGOUT("ERROR: Wait 
E56PHY_CTRL_FSM_RX_STAT_0_ADDR Timeout!\n");
+                               DEBUGOUT("ERROR: Wait 
E56PHY_CTRL_FSM_RX_STAT_0_ADDR Timeout!");
                                break;
                                return -1;
                        }
@@ -1663,7 +1665,7 @@ txgbe_e56_rxs_osc_init_for_temp_track_range(struct 
txgbe_hw *hw, u32 speed)
                        if (((rdata  >> (i * 8)) & 0x3f) == 0x21)
                                break;
                        if (timer++ > PHYINIT_TIMEOUT) {
-                               DEBUGOUT("ERROR: Wait 
E56PHY_CTRL_FSM_RX_STAT_0_ADDR Timeout!\n");
+                               DEBUGOUT("ERROR: Wait 
E56PHY_CTRL_FSM_RX_STAT_0_ADDR Timeout!");
                                break;
                                return -1;
                        }
@@ -1932,7 +1934,7 @@ int txgbe_temp_track_seq_40g(struct txgbe_hw *hw, u32 
speed)
                        CMVAR_UFINE_FMIN_WRAP = S25G_CMVAR_UFINE_FMIN_WRAP;
                        CMVAR_FINE_FMIN_WRAP = S25G_CMVAR_FINE_FMIN_WRAP;
                } else {
-                       DEBUGOUT("Error Speed\n");
+                       DEBUGOUT("Error Speed");
                        return 0;
                }
 
@@ -3191,7 +3193,7 @@ static int txgbe_e56_disable_rx40G(struct txgbe_hw *hw)
                rdata = rd32_ephy(hw, addr);
                usec_delay(100);
                if (timer++ > PHYINIT_TIMEOUT) {
-                       DEBUGOUT("ERROR: Wait E56PHY_CTRL_FSM_RX_STAT_0_ADDR 
Timeout!\n");
+                       DEBUGOUT("ERROR: Wait E56PHY_CTRL_FSM_RX_STAT_0_ADDR 
Timeout!");
                        break;
                }
        }
@@ -3297,7 +3299,7 @@ static int txgbe_e56_disable_rx(struct txgbe_hw *hw)
                        break;
                usec_delay(100);
                if (timer++ > PHYINIT_TIMEOUT) {
-                       DEBUGOUT("ERROR: Wait E56PHY_CTRL_FSM_RX_STAT_0_ADDR 
Timeout!\n");
+                       DEBUGOUT("ERROR: Wait E56PHY_CTRL_FSM_RX_STAT_0_ADDR 
Timeout!");
                        break;
                }
        }
diff --git a/drivers/net/txgbe/base/txgbe_e56.h 
b/drivers/net/txgbe/base/txgbe_e56.h
index eaa3ea5085..67ccdc8c7c 100644
--- a/drivers/net/txgbe/base/txgbe_e56.h
+++ b/drivers/net/txgbe/base/txgbe_e56.h
@@ -1735,6 +1735,8 @@ int txgbe_temp_track_seq(struct txgbe_hw *hw, u32 speed);
 int txgbe_e56_get_temp(struct txgbe_hw *hw, int *temp);
 int txgbe_set_link_to_amlite(struct txgbe_hw *hw, u32 speed);
 int txgbe_e56_reconfig_rx(struct txgbe_hw *hw, u32 speed);
+s32 txgbe_e56_check_phy_link(struct txgbe_hw *hw, u32 *speed,
+                                   bool *link_up);
 s32 txgbe_e56_fec_set(struct txgbe_hw *hw);
 s32 txgbe_e56_fec_polling(struct txgbe_hw *hw, bool *link_up);
 u32 txgbe_e56_tx_ffe_cfg(struct txgbe_hw *hw, u32 speed);
diff --git a/drivers/net/txgbe/base/txgbe_e56_bp.c 
b/drivers/net/txgbe/base/txgbe_e56_bp.c
new file mode 100644
index 0000000000..4928c888bb
--- /dev/null
+++ b/drivers/net/txgbe/base/txgbe_e56_bp.c
@@ -0,0 +1,2593 @@
+#include "txgbe_e56.h"
+#include "txgbe_hw.h"
+#include "txgbe_osdep.h"
+#include "txgbe_phy.h"
+#include "txgbe_e56_bp.h"
+#include "txgbe.h"
+#include "../txgbe_logs.h"
+
+static int
+txgbe_e56_set_rxs_ufine_le_max(struct txgbe_hw *hw, u32 speed)
+{
+       u32 rdata, addr;
+       u32 ULTRAFINE_CODE[4] = {0};
+       int lane_num = 0, lane_idx = 0;
+       u32 CMVAR_UFINE_MAX = 0;
+
+       switch (speed) {
+       case 10:
+               CMVAR_UFINE_MAX = S10G_CMVAR_UFINE_MAX;
+               lane_num = 1;
+               break;
+       case 40:
+               CMVAR_UFINE_MAX = S10G_CMVAR_UFINE_MAX;
+               lane_num = 4;
+               break;
+       case 25:
+               CMVAR_UFINE_MAX = S25G_CMVAR_UFINE_MAX;
+               lane_num = 1;
+               break;
+       default:
+               BP_LOG("%s %d :Invalid speed\n", __func__, __LINE__);
+               break;
+       }
+
+       for (lane_idx = 0; lane_idx < lane_num; lane_idx++) {
+               /* ii get rx ana_bbcdr_ultrafine_i[14, 12] per lane */
+               addr = E56G__RXS0_ANA_OVRDVAL_5_ADDR + (E56PHY_RXS_OFFSET * 
lane_idx);
+               rdata = rd32_ephy(hw, addr);
+               ULTRAFINE_CODE[lane_idx] = FIELD_GET_M(GENMASK(14, 12), rdata);
+               BP_LOG("ULTRAFINE_CODE[%d] = %d, CMVAR_UFINE_MAX: %x\n",
+                      lane_idx, ULTRAFINE_CODE[lane_idx], CMVAR_UFINE_MAX);
+       }
+
+       for (lane_idx = 0; lane_idx < lane_num; lane_idx++) {
+               /* b. Perform the below logic sequence */
+               while (ULTRAFINE_CODE[lane_idx] > CMVAR_UFINE_MAX) {
+                       ULTRAFINE_CODE[lane_idx] -= 1;
+                       addr = E56G__RXS0_ANA_OVRDVAL_5_ADDR +
+                              (E56PHY_RXS_OFFSET * lane_idx);
+                       rdata = rd32_ephy(hw, addr);
+                       set_fields_e56(&rdata, 14, 12, 
ULTRAFINE_CODE[lane_idx]);
+                       wr32_ephy(hw, addr, rdata);
+
+                       /* ovrd_en_ana_bbcdr_ultrafine=1 override ASIC value */
+                       addr = E56G__RXS0_ANA_OVRDEN_1_ADDR +
+                              (E56PHY_RXS_OFFSET * lane_idx);
+                       rdata = rd32_ephy(hw, addr);
+                       wr32_ephy(hw, addr, rdata | BIT(3));
+
+                       /* Wait until 1milliseconds or greater */
+                       usec_delay(1000);
+               }
+       }
+       return 0;
+}
+
+static int txgbe_e56_rxs_osc_init_for_temp_track_range(struct txgbe_hw *hw,
+               u32 speed)
+{
+       int OFFSET_CENTRE_RANGE_H[4] = {0}, OFFSET_CENTRE_RANGE_L[4] = {}, 
RANGE_FINAL[4] = {};
+       int RX_COARSE_MID_TD, CMVAR_RANGE_H = 0, CMVAR_RANGE_L = 0;
+       int status = 0, lane_num = 0;
+       int T = 40, lane_id = 0;
+       u32 addr, rdata;
+
+       /* Set CMVAR_RANGE_H/L based on the link speed mode */
+       switch (speed) {
+       case 10:
+               CMVAR_RANGE_H = S10G_CMVAR_RANGE_H;
+               CMVAR_RANGE_L = S10G_CMVAR_RANGE_L;
+               lane_num = 1;
+               break;
+       case 40:
+               CMVAR_RANGE_H = S10G_CMVAR_RANGE_H;
+               CMVAR_RANGE_L = S10G_CMVAR_RANGE_L;
+               lane_num = 4;
+               break;
+       case 25:
+               CMVAR_RANGE_H = S25G_CMVAR_RANGE_H;
+               CMVAR_RANGE_L = S25G_CMVAR_RANGE_L;
+               lane_num = 1;
+               break;
+       default:
+               BP_LOG("%s %d :Invalid speed\n", __func__, __LINE__);
+               break;
+       }
+
+       /* 1. Read the temperature T just before RXS is enabled. */
+       txgbe_e56_get_temp(hw, &T);
+
+       /* 2. Define software variable RX_COARSE_MID_TD */
+       if (T < -5)
+               RX_COARSE_MID_TD = 10;
+       else if (T < 30)
+               RX_COARSE_MID_TD = 9;
+       else if (T < 65)
+               RX_COARSE_MID_TD = 8;
+       else if (T < 100)
+               RX_COARSE_MID_TD = 7;
+       else
+               RX_COARSE_MID_TD = 6;
+
+       for (lane_id = 0; lane_id < lane_num; lane_id++) {
+               addr  = 0x0b4 + (0x200 * lane_id);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 1, 0, CMVAR_RANGE_H);
+               wr32_ephy(hw, addr, rdata);
+
+               addr  = 0x08c + (0x200 * lane_id);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 29, 29, 0x1);
+               wr32_ephy(hw, addr, rdata);
+
+               addr = 0x1540 + (0x02c * lane_id);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 22, 22, 0x0);
+               wr32_ephy(hw, addr, rdata);
+
+               addr  = 0x1530 + (0x02c * lane_id);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 27, 27, 0x1);
+               wr32_ephy(hw, addr, rdata);
+       }
+       rdata = rd32_ephy(hw, 0x1400);
+       set_fields_e56(&rdata, 19, 16, GENMASK(lane_num - 1, 0));
+       wr32_ephy(hw, 0x1400, rdata);
+       status |= kr_read_poll(rd32_ephy, rdata,
+                 (((rdata & 0x3f3f3f3f) & GENMASK(8 * lane_num - 1, 0))
+                 == (0x09090909 & GENMASK(8 * lane_num - 1, 0))),
+                 100, 2000, hw,
+                 E56PHY_CTRL_FSM_RX_STAT_0_ADDR);
+       if (status)
+               BP_LOG("Wait fsm_rx_sts 1 = %x : %d, Wait rx_sts %s.\n",
+                      rdata, status, status ? "FAILED" : "SUCCESS");
+
+       for (lane_id = 0; lane_id < lane_num; lane_id++) {
+               addr  = 0x0b4 + (0x0200 * lane_id);
+               rdata = rd32_ephy(hw, addr);
+               OFFSET_CENTRE_RANGE_H[lane_id] = (rdata >> 4) & 0xf;
+               if (OFFSET_CENTRE_RANGE_H[lane_id] > RX_COARSE_MID_TD)
+                       OFFSET_CENTRE_RANGE_H[lane_id] = 
OFFSET_CENTRE_RANGE_H[lane_id] -
+                                                        RX_COARSE_MID_TD;
+               else
+                       OFFSET_CENTRE_RANGE_H[lane_id] = RX_COARSE_MID_TD -
+                                                        
OFFSET_CENTRE_RANGE_H[lane_id];
+       }
+
+       /* 7. Do SEQ::RX_DISABLE to disable RXS. */
+       rdata = rd32_ephy(hw, 0x1400);
+       set_fields_e56(&rdata, 19, 16, 0x0);
+       wr32_ephy(hw, 0x1400, rdata);
+       status |= kr_read_poll(rd32_ephy, rdata,
+                 (((rdata & 0x3f3f3f3f) & GENMASK(8 * lane_num - 1, 0))
+                 == (0x21212121 & GENMASK(8 * lane_num - 1, 0))),
+                 100, 2000, hw,
+                 E56PHY_CTRL_FSM_RX_STAT_0_ADDR);
+       if (status)
+               BP_LOG("Wait fsm_rx_sts 2 = %x : %d, Wait rx_sts %s.\n",
+                      rdata, status, status ? "FAILED" : "SUCCESS");
+       rdata = rd32_ephy(hw, 0x15ec);
+       wr32_ephy(hw, 0x15ec, rdata);
+
+       for (lane_id = 0; lane_id < lane_num; lane_id++) {
+               addr  = 0x0b4 + (0x200 * lane_id);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 1, 0, CMVAR_RANGE_L);
+               wr32_ephy(hw, addr, rdata);
+
+               addr  = 0x08c + (0x200 * lane_id);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 29, 29, 0x1);
+               wr32_ephy(hw, addr, rdata);
+
+               addr = 0x1540 + (0x02c * lane_id);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 22, 22, 0x0);
+               wr32_ephy(hw, addr, rdata);
+
+               addr  = 0x1530 + (0x02c * lane_id);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 27, 27, 0x1);
+               wr32_ephy(hw, addr, rdata);
+       }
+       rdata = rd32_ephy(hw, 0x1400);
+       set_fields_e56(&rdata, 19, 16, 0xf);
+       wr32_ephy(hw, 0x1400, rdata);
+       status |= kr_read_poll(rd32_ephy, rdata,
+                 (((rdata & 0x3f3f3f3f) & GENMASK(8 * lane_num - 1, 0))
+                 == (0x09090909 & GENMASK(8 * lane_num - 1, 0))),
+                 100, 2000, hw,
+                 E56PHY_CTRL_FSM_RX_STAT_0_ADDR);
+       if (status)
+               BP_LOG("Wait fsm_rx_sts 3 = %x : %d, Wait rx_sts %s.\n",
+                      rdata, status, status ? "FAILED" : "SUCCESS");
+       for (lane_id = 0; lane_id < lane_num; lane_id++) {
+               addr  = 0x0b4 + (0x0200 * lane_id);
+               rdata = rd32_ephy(hw, addr);
+               OFFSET_CENTRE_RANGE_L[lane_id] = (rdata >> 4) & 0xf;
+               if (OFFSET_CENTRE_RANGE_L[lane_id] > RX_COARSE_MID_TD)
+                       OFFSET_CENTRE_RANGE_L[lane_id] = 
OFFSET_CENTRE_RANGE_L[lane_id] -
+                                                        RX_COARSE_MID_TD;
+               else
+                       OFFSET_CENTRE_RANGE_L[lane_id] = RX_COARSE_MID_TD -
+                                                        
OFFSET_CENTRE_RANGE_L[lane_id];
+               }
+       for (lane_id = 0; lane_id < lane_num; lane_id++) {
+               RANGE_FINAL[lane_id] = OFFSET_CENTRE_RANGE_L[lane_id] <
+                                      OFFSET_CENTRE_RANGE_H[lane_id] ?
+                                      CMVAR_RANGE_L : CMVAR_RANGE_H;
+               BP_LOG("lane_id:%d-RANGE_L:%x-RANGE_H:%x-RANGE_FINAL:%x\n",
+                      lane_id, OFFSET_CENTRE_RANGE_L[lane_id],
+                      OFFSET_CENTRE_RANGE_H[lane_id], RANGE_FINAL[lane_id]);
+       }
+
+       /* 7. Do SEQ::RX_DISABLE to disable RXS. */
+       rdata = rd32_ephy(hw, 0x1400);
+       set_fields_e56(&rdata, 19, 16, 0x0);
+       wr32_ephy(hw, 0x1400, rdata);
+       status |= kr_read_poll(rd32_ephy, rdata,
+                 (((rdata & 0x3f3f3f3f) & GENMASK(8 * lane_num - 1, 0))
+                 == (0x21212121 & GENMASK(8 * lane_num - 1, 0))),
+                 100, 2000, hw,
+                 E56PHY_CTRL_FSM_RX_STAT_0_ADDR);
+       if (status)
+               BP_LOG("Wait fsm_rx_sts 4 = %x : %d, Wait rx_sts %s.\n",
+                      rdata, status, status ? "FAILED" : "SUCCESS");
+       rdata = rd32_ephy(hw, 0x15ec);
+       wr32_ephy(hw, 0x15ec, rdata);
+
+       for (lane_id = 0; lane_id < lane_num; lane_id++) {
+               addr  = 0x0b4 + (0x0200 * lane_id);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 1, 0, RANGE_FINAL[lane_id]);
+               wr32_ephy(hw, addr, rdata);
+
+               rdata = 0x0000;
+               addr  = 0x1544 + (lane_id * E56PHY_PMD_RX_OFFSET);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 25, 25, 0x0);
+               wr32_ephy(hw, addr, rdata);
+
+               addr  = 0x1538 + (lane_id * E56PHY_PMD_RX_OFFSET);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 0, 0, 0x1);
+               wr32_ephy(hw, addr, rdata);
+
+               addr  = 0x1544 + (lane_id * E56PHY_PMD_RX_OFFSET);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 28, 28, 0x0);
+               wr32_ephy(hw, addr, rdata);
+
+               addr  = 0x1538 + (lane_id * E56PHY_PMD_RX_OFFSET);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 3, 3, 0x1);
+               wr32_ephy(hw, addr, rdata);
+
+               rdata = 0x0000;
+               addr  = 0x1544 + (lane_id * E56PHY_PMD_RX_OFFSET);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 16, 16, 0x0);
+               wr32_ephy(hw, addr, rdata);
+
+               addr  = 0x1534 + (lane_id * E56PHY_PMD_RX_OFFSET);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 23, 23, 0x1);
+               wr32_ephy(hw, addr, rdata);
+
+               addr  = 0x1544 + (lane_id * E56PHY_PMD_RX_OFFSET);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 17, 17, 0x1);
+               wr32_ephy(hw, addr, rdata);
+
+               addr  = 0x1534 + (lane_id * E56PHY_PMD_RX_OFFSET);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 24, 24, 0x1);
+               wr32_ephy(hw, addr, rdata);
+
+               addr  = 0x1544 + (lane_id * E56PHY_PMD_RX_OFFSET);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 31, 31, 0x0);
+               wr32_ephy(hw, addr, rdata);
+
+               addr  = 0x1538 + (lane_id * E56PHY_PMD_RX_OFFSET);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 6, 6, 0x1);
+               wr32_ephy(hw, addr, rdata);
+
+               addr  = 0x1530 + (0x02c * lane_id);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 27, 27, 0x0);
+               wr32_ephy(hw, addr, rdata);
+       }
+
+       /* Do SEQ::RX_ENABLE */
+       rdata = rd32_ephy(hw, 0x1400);
+       set_fields_e56(&rdata, E56PHY_PMD_CFG_0_RX_EN_CFG, GENMASK(lane_num - 
1, 0));
+       wr32_ephy(hw, 0x1400, rdata);
+
+       return status;
+}
+
+static int txgbe_e56_rxs_post_cdr_lock_temp_track_seq(struct txgbe_hw *hw,
+               u32 speed)
+{
+       int status = 0;
+       u32 rdata;
+       int SECOND_CODE;
+       int COARSE_CODE;
+       int FINE_CODE;
+       int ULTRAFINE_CODE;
+
+       int CMVAR_SEC_LOW_TH = 0;
+       int CMVAR_UFINE_MAX = 0;
+       int CMVAR_FINE_MAX = 0;
+       int CMVAR_UFINE_UMAX_WRAP = 0;
+       int CMVAR_COARSE_MAX = 0;
+       int CMVAR_UFINE_FMAX_WRAP = 0;
+       int CMVAR_FINE_FMAX_WRAP = 0;
+       int CMVAR_SEC_HIGH_TH = 0;
+       int CMVAR_UFINE_MIN = 0;
+       int CMVAR_FINE_MIN = 0;
+       int CMVAR_UFINE_UMIN_WRAP = 0;
+       int CMVAR_COARSE_MIN = 0;
+       int CMVAR_UFINE_FMIN_WRAP = 0;
+       int CMVAR_FINE_FMIN_WRAP = 0;
+
+       if (speed == 10) {
+               CMVAR_SEC_LOW_TH = S10G_CMVAR_SEC_LOW_TH;
+               CMVAR_UFINE_MAX = S10G_CMVAR_UFINE_MAX;
+               CMVAR_FINE_MAX = S10G_CMVAR_FINE_MAX;
+               CMVAR_UFINE_UMAX_WRAP = S10G_CMVAR_UFINE_UMAX_WRAP;
+               CMVAR_COARSE_MAX = S10G_CMVAR_COARSE_MAX;
+               CMVAR_UFINE_FMAX_WRAP = S10G_CMVAR_UFINE_FMAX_WRAP;
+               CMVAR_FINE_FMAX_WRAP = S10G_CMVAR_FINE_FMAX_WRAP;
+               CMVAR_SEC_HIGH_TH = S10G_CMVAR_SEC_HIGH_TH;
+               CMVAR_UFINE_MIN = S10G_CMVAR_UFINE_MIN;
+               CMVAR_FINE_MIN = S10G_CMVAR_FINE_MIN;
+               CMVAR_UFINE_UMIN_WRAP = S10G_CMVAR_UFINE_UMIN_WRAP;
+               CMVAR_COARSE_MIN = S10G_CMVAR_COARSE_MIN;
+               CMVAR_UFINE_FMIN_WRAP = S10G_CMVAR_UFINE_FMIN_WRAP;
+               CMVAR_FINE_FMIN_WRAP = S10G_CMVAR_FINE_FMIN_WRAP;
+       } else if (speed == 25) {
+               CMVAR_SEC_LOW_TH = S25G_CMVAR_SEC_LOW_TH;
+               CMVAR_UFINE_MAX = S25G_CMVAR_UFINE_MAX;
+               CMVAR_FINE_MAX = S25G_CMVAR_FINE_MAX;
+               CMVAR_UFINE_UMAX_WRAP = S25G_CMVAR_UFINE_UMAX_WRAP;
+               CMVAR_COARSE_MAX = S25G_CMVAR_COARSE_MAX;
+               CMVAR_UFINE_FMAX_WRAP = S25G_CMVAR_UFINE_FMAX_WRAP;
+               CMVAR_FINE_FMAX_WRAP = S25G_CMVAR_FINE_FMAX_WRAP;
+               CMVAR_SEC_HIGH_TH = S25G_CMVAR_SEC_HIGH_TH;
+               CMVAR_UFINE_MIN = S25G_CMVAR_UFINE_MIN;
+               CMVAR_FINE_MIN = S25G_CMVAR_FINE_MIN;
+               CMVAR_UFINE_UMIN_WRAP = S25G_CMVAR_UFINE_UMIN_WRAP;
+               CMVAR_COARSE_MIN = S25G_CMVAR_COARSE_MIN;
+               CMVAR_UFINE_FMIN_WRAP = S25G_CMVAR_UFINE_FMIN_WRAP;
+               CMVAR_FINE_FMIN_WRAP = S25G_CMVAR_FINE_FMIN_WRAP;
+       }
+
+       status |= txgbe_e56_rx_rd_second_code(hw, &SECOND_CODE);
+
+       EPHY_RREG(E56G__RXS0_ANA_OVRDVAL_5);
+       COARSE_CODE = EPHY_XFLD(E56G__RXS0_ANA_OVRDVAL_5, ana_bbcdr_coarse_i);
+       FINE_CODE = EPHY_XFLD(E56G__RXS0_ANA_OVRDVAL_5, ana_bbcdr_fine_i);
+       ULTRAFINE_CODE = EPHY_XFLD(E56G__RXS0_ANA_OVRDVAL_5, 
ana_bbcdr_ultrafine_i);
+
+       if (SECOND_CODE <= CMVAR_SEC_LOW_TH) {
+               if (ULTRAFINE_CODE < CMVAR_UFINE_MAX) {
+                       txgbe_e56_ephy_config(E56G__RXS0_ANA_OVRDVAL_5, 
ana_bbcdr_ultrafine_i,
+                                             ULTRAFINE_CODE + 1);
+                       EPHY_RREG(E56G__RXS0_ANA_OVRDEN_1);
+                       EPHY_XFLD(E56G__RXS0_ANA_OVRDEN_1, 
ovrd_en_ana_bbcdr_ultrafine_i) = 1;
+                       EPHY_WREG(E56G__RXS0_ANA_OVRDEN_1);
+               } else if (FINE_CODE < CMVAR_FINE_MAX) {
+                       EPHY_RREG(E56G__RXS0_ANA_OVRDVAL_5);
+                       EPHY_XFLD(E56G__RXS0_ANA_OVRDVAL_5,
+                                 ana_bbcdr_ultrafine_i) = 
CMVAR_UFINE_UMAX_WRAP;
+                       EPHY_XFLD(E56G__RXS0_ANA_OVRDVAL_5, ana_bbcdr_fine_i) = 
FINE_CODE + 1;
+                       EPHY_WREG(E56G__RXS0_ANA_OVRDVAL_5);
+                       EPHY_RREG(E56G__RXS0_ANA_OVRDEN_1);
+                       EPHY_XFLD(E56G__RXS0_ANA_OVRDEN_1, 
ovrd_en_ana_bbcdr_fine_i) = 1;
+                       EPHY_XFLD(E56G__RXS0_ANA_OVRDEN_1, 
ovrd_en_ana_bbcdr_ultrafine_i) = 1;
+                       EPHY_WREG(E56G__RXS0_ANA_OVRDEN_1);
+               } else if (COARSE_CODE < CMVAR_COARSE_MAX) {
+                       EPHY_RREG(E56G__RXS0_ANA_OVRDVAL_5);
+                       EPHY_XFLD(E56G__RXS0_ANA_OVRDVAL_5,
+                                 ana_bbcdr_ultrafine_i) = 
CMVAR_UFINE_FMAX_WRAP;
+                       EPHY_XFLD(E56G__RXS0_ANA_OVRDVAL_5,
+                                 ana_bbcdr_fine_i) = CMVAR_FINE_FMAX_WRAP;
+                       EPHY_XFLD(E56G__RXS0_ANA_OVRDVAL_5, ana_bbcdr_coarse_i) 
= COARSE_CODE + 1;
+                       EPHY_WREG(E56G__RXS0_ANA_OVRDVAL_5);
+                       EPHY_RREG(E56G__RXS0_ANA_OVRDEN_1);
+                       EPHY_XFLD(E56G__RXS0_ANA_OVRDEN_1, 
ovrd_en_ana_bbcdr_coarse_i) = 1;
+                       EPHY_XFLD(E56G__RXS0_ANA_OVRDEN_1, 
ovrd_en_ana_bbcdr_fine_i) = 1;
+                       EPHY_XFLD(E56G__RXS0_ANA_OVRDEN_1, 
ovrd_en_ana_bbcdr_ultrafine_i) = 1;
+                       EPHY_WREG(E56G__RXS0_ANA_OVRDEN_1);
+               } else {
+                       BP_LOG("ERROR: (SECOND_CODE <= CMVAR_SEC_LOW_TH) 
temperature tracking occurs Error condition\n");
+               }
+       } else if (SECOND_CODE >= CMVAR_SEC_HIGH_TH) {
+               if (ULTRAFINE_CODE > CMVAR_UFINE_MIN) {
+                       txgbe_e56_ephy_config(E56G__RXS0_ANA_OVRDVAL_5, 
ana_bbcdr_ultrafine_i,
+                                             ULTRAFINE_CODE - 1);
+                       EPHY_RREG(E56G__RXS0_ANA_OVRDEN_1);
+                       EPHY_XFLD(E56G__RXS0_ANA_OVRDEN_1, 
ovrd_en_ana_bbcdr_ultrafine_i) = 1;
+                       EPHY_WREG(E56G__RXS0_ANA_OVRDEN_1);
+               } else if (FINE_CODE > CMVAR_FINE_MIN) {
+                       EPHY_RREG(E56G__RXS0_ANA_OVRDVAL_5);
+                       EPHY_XFLD(E56G__RXS0_ANA_OVRDVAL_5,
+                                 ana_bbcdr_ultrafine_i) = 
CMVAR_UFINE_UMIN_WRAP;
+                       EPHY_XFLD(E56G__RXS0_ANA_OVRDVAL_5, ana_bbcdr_fine_i) = 
FINE_CODE - 1;
+                       EPHY_WREG(E56G__RXS0_ANA_OVRDVAL_5);
+                       EPHY_RREG(E56G__RXS0_ANA_OVRDEN_1);
+                       EPHY_XFLD(E56G__RXS0_ANA_OVRDEN_1, 
ovrd_en_ana_bbcdr_fine_i) = 1;
+                       EPHY_XFLD(E56G__RXS0_ANA_OVRDEN_1, 
ovrd_en_ana_bbcdr_ultrafine_i) = 1;
+                       EPHY_WREG(E56G__RXS0_ANA_OVRDEN_1);
+               } else if (COARSE_CODE > CMVAR_COARSE_MIN) {
+                       EPHY_RREG(E56G__RXS0_ANA_OVRDVAL_5);
+                       EPHY_XFLD(E56G__RXS0_ANA_OVRDVAL_5,
+                                 ana_bbcdr_ultrafine_i) = 
CMVAR_UFINE_FMIN_WRAP;
+                       EPHY_XFLD(E56G__RXS0_ANA_OVRDVAL_5,
+                                 ana_bbcdr_fine_i) = CMVAR_FINE_FMIN_WRAP;
+                       EPHY_XFLD(E56G__RXS0_ANA_OVRDVAL_5, ana_bbcdr_coarse_i) 
= COARSE_CODE - 1;
+                       EPHY_WREG(E56G__RXS0_ANA_OVRDVAL_5);
+                       EPHY_RREG(E56G__RXS0_ANA_OVRDEN_1);
+                       EPHY_XFLD(E56G__RXS0_ANA_OVRDEN_1, 
ovrd_en_ana_bbcdr_coarse_i) = 1;
+                       EPHY_XFLD(E56G__RXS0_ANA_OVRDEN_1, 
ovrd_en_ana_bbcdr_fine_i) = 1;
+                       EPHY_XFLD(E56G__RXS0_ANA_OVRDEN_1, 
ovrd_en_ana_bbcdr_ultrafine_i) = 1;
+                       EPHY_WREG(E56G__RXS0_ANA_OVRDEN_1);
+               } else {
+                       BP_LOG("ERROR: (SECOND_CODE >= CMVAR_SEC_HIGH_TH) 
temperature tracking occurs Error condition\n");
+               }
+       }
+
+       return status;
+}
+
+static int txgbe_e56_ctle_bypass_seq(struct txgbe_hw *hw, u8 bp_link_mode)
+{
+       u32 rdata;
+
+       txgbe_e56_ephy_config(E56G__RXS0_ANA_OVRDVAL_0, ana_ctle_bypass_i, 1);
+       txgbe_e56_ephy_config(E56G__RXS0_ANA_OVRDEN_0, 
ovrd_en_ana_ctle_bypass_i, 1);
+
+       txgbe_e56_ephy_config(E56G__RXS0_ANA_OVRDVAL_3, ana_ctle_cz_cstm_i, 0);
+       txgbe_e56_ephy_config(E56G__RXS0_ANA_OVRDEN_0, 
ovrd_en_ana_ctle_cz_cstm_i, 1);
+
+       EPHY_RREG(E56G__PMD_RXS0_OVRDVAL_1);
+       EPHY_XFLD(E56G__PMD_RXS0_OVRDVAL_1, rxs0_rx0_ctle_train_en_i) = 0;
+       EPHY_XFLD(E56G__PMD_RXS0_OVRDVAL_1, rxs0_rx0_ctle_train_done_o) = 1;
+       EPHY_WREG(E56G__PMD_RXS0_OVRDVAL_1);
+
+       EPHY_RREG(E56G__PMD_RXS0_OVRDEN_1);
+       EPHY_XFLD(E56G__PMD_RXS0_OVRDEN_1, ovrd_en_rxs0_rx0_ctle_train_en_i) = 
1;
+       EPHY_XFLD(E56G__PMD_RXS0_OVRDEN_1, ovrd_en_rxs0_rx0_ctle_train_done_o) 
= 1;
+       EPHY_WREG(E56G__PMD_RXS0_OVRDEN_1);
+
+       if (bp_link_mode == 40) {
+               txgbe_e56_ephy_config(E56G__RXS1_ANA_OVRDVAL_0, 
ana_ctle_bypass_i, 1);
+               txgbe_e56_ephy_config(E56G__RXS1_ANA_OVRDEN_0, 
ovrd_en_ana_ctle_bypass_i, 1);
+               txgbe_e56_ephy_config(E56G__RXS2_ANA_OVRDVAL_0, 
ana_ctle_bypass_i, 1);
+               txgbe_e56_ephy_config(E56G__RXS2_ANA_OVRDEN_0, 
ovrd_en_ana_ctle_bypass_i, 1);
+               txgbe_e56_ephy_config(E56G__RXS3_ANA_OVRDVAL_0, 
ana_ctle_bypass_i, 1);
+               txgbe_e56_ephy_config(E56G__RXS3_ANA_OVRDEN_0, 
ovrd_en_ana_ctle_bypass_i, 1);
+
+               txgbe_e56_ephy_config(E56G__RXS1_ANA_OVRDVAL_3, 
ana_ctle_cz_cstm_i, 0);
+               txgbe_e56_ephy_config(E56G__RXS1_ANA_OVRDEN_0, 
ovrd_en_ana_ctle_cz_cstm_i, 1);
+               txgbe_e56_ephy_config(E56G__RXS2_ANA_OVRDVAL_3, 
ana_ctle_cz_cstm_i, 0);
+               txgbe_e56_ephy_config(E56G__RXS2_ANA_OVRDEN_0, 
ovrd_en_ana_ctle_cz_cstm_i, 1);
+               txgbe_e56_ephy_config(E56G__RXS3_ANA_OVRDVAL_3, 
ana_ctle_cz_cstm_i, 0);
+               txgbe_e56_ephy_config(E56G__RXS3_ANA_OVRDEN_0, 
ovrd_en_ana_ctle_cz_cstm_i, 1);
+
+               EPHY_RREG(E56G__PMD_RXS1_OVRDVAL_1);
+               EPHY_XFLD(E56G__PMD_RXS1_OVRDVAL_1, rxs1_rx0_ctle_train_en_i) = 
0;
+               EPHY_XFLD(E56G__PMD_RXS1_OVRDVAL_1, rxs1_rx0_ctle_train_done_o) 
= 1;
+               EPHY_WREG(E56G__PMD_RXS1_OVRDVAL_1);
+               EPHY_RREG(E56G__PMD_RXS2_OVRDVAL_1);
+               EPHY_XFLD(E56G__PMD_RXS2_OVRDVAL_1, rxs2_rx0_ctle_train_en_i) = 
0;
+               EPHY_XFLD(E56G__PMD_RXS2_OVRDVAL_1, rxs2_rx0_ctle_train_done_o) 
= 1;
+               EPHY_WREG(E56G__PMD_RXS2_OVRDVAL_1);
+               EPHY_RREG(E56G__PMD_RXS3_OVRDVAL_1);
+               EPHY_XFLD(E56G__PMD_RXS3_OVRDVAL_1, rxs3_rx0_ctle_train_en_i) = 
0;
+               EPHY_XFLD(E56G__PMD_RXS3_OVRDVAL_1, rxs3_rx0_ctle_train_done_o) 
= 1;
+               EPHY_WREG(E56G__PMD_RXS3_OVRDVAL_1);
+
+               EPHY_RREG(E56G__PMD_RXS1_OVRDEN_1);
+               EPHY_XFLD(E56G__PMD_RXS1_OVRDEN_1, 
ovrd_en_rxs1_rx0_ctle_train_en_i) = 1;
+               EPHY_XFLD(E56G__PMD_RXS1_OVRDEN_1, 
ovrd_en_rxs1_rx0_ctle_train_done_o) = 1;
+               EPHY_WREG(E56G__PMD_RXS1_OVRDEN_1);
+               EPHY_RREG(E56G__PMD_RXS2_OVRDEN_1);
+               EPHY_XFLD(E56G__PMD_RXS2_OVRDEN_1, 
ovrd_en_rxs2_rx0_ctle_train_en_i) = 1;
+               EPHY_XFLD(E56G__PMD_RXS2_OVRDEN_1, 
ovrd_en_rxs2_rx0_ctle_train_done_o) = 1;
+               EPHY_WREG(E56G__PMD_RXS2_OVRDEN_1);
+               EPHY_RREG(E56G__PMD_RXS3_OVRDEN_1);
+               EPHY_XFLD(E56G__PMD_RXS3_OVRDEN_1, 
ovrd_en_rxs3_rx0_ctle_train_en_i) = 1;
+               EPHY_XFLD(E56G__PMD_RXS3_OVRDEN_1, 
ovrd_en_rxs3_rx0_ctle_train_done_o) = 1;
+               EPHY_WREG(E56G__PMD_RXS3_OVRDEN_1);
+       }
+       return 0;
+}
+
+static int txgbe_e56_rxs_adc_adapt_seq(struct txgbe_hw *hw, u32 bypass_ctle)
+{
+       int lane_num = 0, lane_idx = 0;
+       u32 rdata = 0, addr = 0;
+       int status = 0;
+
+       int timer = 0, j = 0;
+
+       switch (hw->bp_link_mode) {
+       case 10:
+               lane_num = 1;
+               break;
+       case 40:
+               lane_num = 4;
+               break;
+       case 25:
+               lane_num = 1;
+               break;
+       default:
+               BP_LOG("%s %d :Invalid speed\n", __func__, __LINE__);
+               break;
+       }
+
+       for (lane_idx = 0; lane_idx < lane_num; lane_idx++) {
+               addr = 0x1544 + (E56PHY_PMD_RX_OFFSET * lane_idx);
+               /* Wait RXS0-3_OVRDVAL[1]::rxs0-3_rx0_cdr_rdy_o = 1 */
+               status = kr_read_poll(rd32_ephy, rdata, (rdata & BIT(12)),
+                                     100, 2000, hw, 0x1544);
+               if (status)
+                       BP_LOG("rxs%d_rx0_cdr_rdy_o = %x, %s.\n",
+                              lane_idx, rdata,
+                              status ? "FAILED" : "SUCCESS");
+       }
+
+       for (lane_idx = 0; lane_idx < lane_num; lane_idx++) {
+               /* 4. Disable VGA and CTLE training so they don't interfere 
with ADC calibration */
+               /* a. Set ALIAS::RXS::VGA_TRAIN_EN = 0b0 */
+               addr  = 0x1544 + (E56PHY_PMD_RX_OFFSET * lane_idx);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 7, 7, 0x0);
+               wr32_ephy(hw, addr, rdata);
+
+               addr  = 0x1534 + (E56PHY_PMD_RX_OFFSET * lane_idx);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 14, 14, 0x1);
+               wr32_ephy(hw, addr, rdata);
+
+               /* b. Set ALIAS::RXS::CTLE_TRAIN_EN = 0b0 */
+               addr  = 0x1544 + (E56PHY_PMD_RX_OFFSET * lane_idx);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 9, 9, 0x0);
+               wr32_ephy(hw, addr, rdata);
+
+               addr  = 0x1534 + (E56PHY_PMD_RX_OFFSET * lane_idx);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 16, 16, 0x1);
+               wr32_ephy(hw, addr, rdata);
+
+               /* 5. Perform ADC interleaver calibration */
+               /* a. Remove the OVERRIDE on ALIAS::RXS::ADC_INTL_CAL_DONE */
+               addr  = 0x1534 + (E56PHY_PMD_RX_OFFSET * lane_idx);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 24, 24, 0x0);
+               wr32_ephy(hw, addr, rdata);
+
+               addr  = 0x1544 + (E56PHY_PMD_RX_OFFSET * lane_idx);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 16, 16, 0x1);
+               wr32_ephy(hw, addr, rdata);
+
+               addr = 0x1544 + (E56PHY_PMD_RX_OFFSET * lane_idx);
+               /* Wait rxs0_rx0_adc_intl_cal_done_o bit17 = 1 */
+               status = kr_read_poll(rd32_ephy, rdata, (rdata & BIT(17)),
+                                     100, 2000, hw, addr);
+               if (status)
+                       BP_LOG("rxs0_rx0_adc_intl_cal_done_o = %x, %s.\n", 
rdata,
+                               status ? "FAILED" : "SUCCESS");
+
+               /* 6. Perform ADC offset adaptation and ADC gain adaptation,
+                * repeat them a few times and after that keep it disabled.
+                */
+               for (j = 0; j < 16; j++) {
+                       /* a. ALIAS::RXS::ADC_OFST_ADAPT_EN = 0b1 */
+                       addr  = 0x1544 + (E56PHY_PMD_RX_OFFSET * lane_idx);
+                       rdata = rd32_ephy(hw, addr);
+                       set_fields_e56(&rdata, 25, 25, 0x1);
+                       wr32_ephy(hw, addr, rdata);
+
+                       /* b. Wait for 1ms or greater */
+                       /* usec_delay(1000); */
+                       /* set ovrd_en_rxs0_rx0_adc_ofst_adapt_done_o bit1=0 */
+                       addr = 0x1538 + (E56PHY_PMD_RX_OFFSET * lane_idx);
+                       rdata = rd32_ephy(hw, addr);
+                       set_fields_e56(&rdata, 1, 1, 0);
+                       wr32_ephy(hw, addr, rdata);
+
+                       addr = 0x1544 + (E56PHY_PMD_RX_OFFSET * lane_idx);
+                       /* Wait rxs0_rx0_adc_ofst_adapt_done_o bit26 = 0 */
+                       status = kr_read_poll(rd32_ephy, rdata,
+                                                  !(rdata & BIT(26)),
+                                                  100, 2000, hw, addr);
+                       if (status)
+                               BP_LOG("rxs0_rx0_adc_ofst_adapt_done_o %d = %x, 
%s.\n",
+                                      j, rdata, status ? "FAILED" : "SUCCESS");
+
+                       /* c. ALIAS::RXS::ADC_OFST_ADAPT_EN = 0b0 */
+                       rdata = 0x0000;
+                       addr  = 0x1544 + (E56PHY_PMD_RX_OFFSET * lane_idx);
+                       rdata = rd32_ephy(hw, addr);
+                       set_fields_e56(&rdata, 25, 25, 0x0);
+                       wr32_ephy(hw, addr, rdata);
+
+                       /* d. ALIAS::RXS::ADC_GAIN_ADAPT_EN = 0b1 */
+                       rdata = 0x0000;
+                       addr  = 0x1544 + (E56PHY_PMD_RX_OFFSET * lane_idx);
+                       rdata = rd32_ephy(hw, addr);
+                       set_fields_e56(&rdata, 28, 28, 0x1);
+                       wr32_ephy(hw, addr, rdata);
+
+                       /* e. Wait for 1ms or greater */
+                       /* usec_delay(1000); */
+                       /* set ovrd_en_rxs0_rx0_adc_ofst_adapt_done_o bit1=0 */
+                       addr = 0x1538 + (E56PHY_PMD_RX_OFFSET * lane_idx);
+                       rdata = rd32_ephy(hw, addr);
+                       set_fields_e56(&rdata, 1, 1, 0);
+                       wr32_ephy(hw, addr, rdata);
+
+                       addr = 0x1544 + (E56PHY_PMD_RX_OFFSET * lane_idx);
+                       /* Wait rxs0_rx0_adc_gain_adapt_done_o bit29 = 0 */
+                       status = kr_read_poll(rd32_ephy, rdata, !(rdata & 
BIT(29)),
+                                             100, 2000, hw, addr);
+                       if (status)
+                               BP_LOG("rxs0_rx0_adc_gain_adapt_done_o %d = %x, 
%s.\n",
+                                      j, rdata, status ? "FAILED" : "SUCCESS");
+
+                       /* f. ALIAS::RXS::ADC_GAIN_ADAPT_EN = 0b0 */
+                       addr  = 0x1544 + (E56PHY_PMD_RX_OFFSET * lane_idx);
+                       rdata = rd32_ephy(hw, addr);
+                       set_fields_e56(&rdata, 28, 28, 0x0);
+                       wr32_ephy(hw, addr, rdata);
+               }
+               /* g. Repeat #a to #f total 16 times */
+
+               /* 7. Perform ADC interleaver adaptation for 10ms or greater,
+                * and after that disable it
+                */
+               /* a. ALIAS::RXS::ADC_INTL_ADAPT_EN = 0b1 */
+               addr  = 0x1544 + (E56PHY_PMD_RX_OFFSET * lane_idx);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 31, 31, 0x1);
+               wr32_ephy(hw, addr, rdata);
+               /* b. Wait for 10ms or greater */
+               msleep(20);
+
+               /* c. ALIAS::RXS::ADC_INTL_ADAPT_EN = 0b0 */
+               /* set ovrd_en_rxs0_rx0_adc_intl_adapt_en_i=0 */
+               addr = 0x1538 + (E56PHY_PMD_RX_OFFSET * lane_idx);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 6, 6, 0);
+               wr32_ephy(hw, addr, rdata);
+
+               /* 8. Now re-enable VGA and CTLE trainings, so that it continues
+                * to adapt tracking changes in temperature or voltage
+                * <1>Set ALIAS::RXS::VGA_TRAIN_EN = 0b1
+                */
+               /* set rxs0_rx0_vga_train_en_i=1 */
+               addr = 0x1544 + (E56PHY_PMD_RX_OFFSET * lane_idx);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 7, 7, 0x1);
+               if (bypass_ctle == 0)
+                       EPHY_XFLD(E56G__PMD_RXS0_OVRDVAL_1, 
rxs0_rx0_ctle_train_en_i) = 1;
+               wr32_ephy(hw, addr, rdata);
+
+               /* <2>wait for ALIAS::RXS::VGA_TRAIN_DONE = 1 */
+               /* set ovrd_en_rxs0_rx0_vga_train_done_o = 0 */
+               addr = 0x1534 + (E56PHY_PMD_RX_OFFSET * lane_idx);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 15, 15, 0x0);
+               wr32_ephy(hw, addr, rdata);
+
+               /* Wait rxs0_rx0_vga_train_done_o bit8 = 0 */
+               addr = 0x1544 + (E56PHY_PMD_RX_OFFSET * lane_idx);
+               status = kr_read_poll(rd32_ephy, rdata, (rdata & BIT(8)),
+                                          100, 3000, hw, addr);
+               if (status)
+                       BP_LOG("rxs0_rx0_vga_train_done_o = %x, %s.\n", rdata,
+                              status ? "FAILED" : "SUCCESS");
+
+               if (bypass_ctle == 0) {
+                       addr = 0x1534 + (E56PHY_PMD_RX_OFFSET * lane_idx);
+                       rdata = rd32_ephy(hw, addr);
+                       EPHY_XFLD(E56G__PMD_RXS0_OVRDEN_1,
+                                 ovrd_en_rxs0_rx0_ctle_train_done_o) = 0;
+                       wr32_ephy(hw, addr, rdata);
+
+                       rdata = 0;
+                       timer = 0;
+                       addr = 0x1544 + (E56PHY_PMD_RX_OFFSET * lane_idx);
+                       while (EPHY_XFLD(E56G__PMD_RXS0_OVRDVAL_1,
+                              rxs0_rx0_ctle_train_done_o) != 1) {
+                               rdata = rd32_ephy(hw, addr);
+                               usec_delay(500);
+
+                               if (timer++ > PHYINIT_TIMEOUT)
+                                       break;
+                       }
+               }
+
+               /* a. Remove the OVERRIDE on ALIAS::RXS::VGA_TRAIN_EN */
+               addr = 0x1534 + (E56PHY_PMD_RX_OFFSET * lane_idx);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 15, 15, 0);
+               /* b. Remove the OVERRIDE on ALIAS::RXS::CTLE_TRAIN_EN */
+               if (bypass_ctle == 0)
+                       EPHY_XFLD(E56G__PMD_RXS0_OVRDEN_1,
+                                 ovrd_en_rxs0_rx0_ctle_train_en_i) = 0;
+               wr32_ephy(hw, addr, rdata);
+       }
+
+       return status;
+}
+
+static int txgbe_e56_phy_rxs_calib_adapt_seq(struct txgbe_hw *hw,
+               u8 bp_link_mode, u32 bypass_ctle)
+{
+       int lane_num = 0, lane_idx = 0;
+       int status = 0;
+       u32 rdata, addr;
+
+       switch (bp_link_mode) {
+       case 10:
+               lane_num = 1;
+               break;
+       case 40:
+               lane_num = 4;
+               break;
+       case 25:
+               lane_num = 1;
+               break;
+       default:
+               BP_LOG("%s %d :Invalid speed\n", __func__, __LINE__);
+               break;
+       }
+
+       for (lane_idx = 0; lane_idx < lane_num; lane_idx++) {
+               rdata = 0x0000;
+               addr  = 0x1544 + (lane_idx * E56PHY_PMD_RX_OFFSET);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 25, 25, 0x0);
+               wr32_ephy(hw, addr, rdata);
+
+               addr  = 0x1538 + (lane_idx * E56PHY_PMD_RX_OFFSET);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 0, 0, 0x1);
+               wr32_ephy(hw, addr, rdata);
+
+               addr  = 0x1544 + (lane_idx * E56PHY_PMD_RX_OFFSET);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 28, 28, 0x0);
+               wr32_ephy(hw, addr, rdata);
+
+               addr  = 0x1538 + (lane_idx * E56PHY_PMD_RX_OFFSET);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 3, 3, 0x1);
+               wr32_ephy(hw, addr, rdata);
+
+               rdata = 0x0000;
+               addr  = 0x1544 + (lane_idx * E56PHY_PMD_RX_OFFSET);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 16, 16, 0x0);
+               wr32_ephy(hw, addr, rdata);
+
+               addr  = 0x1534 + (lane_idx * E56PHY_PMD_RX_OFFSET);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 23, 23, 0x1);
+               wr32_ephy(hw, addr, rdata);
+
+               addr  = 0x1544 + (lane_idx * E56PHY_PMD_RX_OFFSET);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 17, 17, 0x1);
+               wr32_ephy(hw, addr, rdata);
+
+               addr  = 0x1534 + (lane_idx * E56PHY_PMD_RX_OFFSET);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 24, 24, 0x1);
+               wr32_ephy(hw, addr, rdata);
+
+               addr  = 0x1544 + (lane_idx * E56PHY_PMD_RX_OFFSET);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 31, 31, 0x0);
+               wr32_ephy(hw, addr, rdata);
+
+               addr  = 0x1538 + (lane_idx * E56PHY_PMD_RX_OFFSET);
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 6, 6, 0x1);
+               wr32_ephy(hw, addr, rdata);
+       }
+       if (bypass_ctle != 0)
+               status |= txgbe_e56_ctle_bypass_seq(hw, bp_link_mode);
+
+       status |= txgbe_e56_rxs_osc_init_for_temp_track_range(hw, bp_link_mode);
+
+       /* Wait an fsm_rx_sts 25G */
+       BP_LOG("Wait CTRL_FSM_RX_STAT[0]::ctrl_fsm_rx0_st to be ready ...\n");
+
+       status |= kr_read_poll(rd32_ephy, rdata,
+                 (((rdata & 0x3f3f3f3f) & GENMASK(8 * lane_num - 1, 0))
+                 == (0x1b1b1b1b & GENMASK(8 * lane_num - 1, 0))),
+                 1000, 300, hw,
+                 E56PHY_CTRL_FSM_RX_STAT_0_ADDR);
+       BP_LOG("wait ctrl_fsm_rx0_st = %x, %s.\n",
+              rdata, status ? "FAILED" : "SUCCESS");
+
+       return status;
+}
+
+static int txgbe_e56_cms_cfg_for_temp_track_range(struct txgbe_hw *hw)
+{
+       int status = 0, T = 40;
+       u32 addr, rdata;
+
+       status = txgbe_e56_get_temp(hw, &T);
+       if (T < 40) {
+               rdata = 0x0000;
+               addr = E56PHY_CMS_ANA_OVRDEN_0_ADDR;
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata,
+                       
E56PHY_CMS_ANA_OVRDEN_0_OVRD_EN_ANA_LCPLL_HF_LPF_SETCODE_CALIB_I, 0x1);
+               wr32_ephy(hw, addr, rdata);
+               rdata = 0x0000;
+               addr = E56PHY_CMS_ANA_OVRDVAL_2_ADDR;
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata,
+                              
E56PHY_CMS_ANA_OVRDVAL_2_ANA_LCPLL_HF_LPF_SETCODE_CALIB_I, 0x1);
+               wr32_ephy(hw, addr, rdata);
+               rdata = 0x0000;
+               addr = E56PHY_CMS_ANA_OVRDEN_1_ADDR;
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata,
+                       
E56PHY_CMS_ANA_OVRDEN_1_OVRD_EN_ANA_LCPLL_LF_LPF_SETCODE_CALIB_I, 0x1);
+               wr32_ephy(hw, addr, rdata);
+               rdata = 0x0000;
+               addr = E56PHY_CMS_ANA_OVRDVAL_7_ADDR;
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata,
+                       
E56PHY_CMS_ANA_OVRDVAL_7_ANA_LCPLL_LF_LPF_SETCODE_CALIB_I, 0x1);
+               wr32_ephy(hw, addr, rdata);
+       } else if (T > 70) {
+               rdata = 0x0000;
+               addr = E56PHY_CMS_ANA_OVRDEN_0_ADDR;
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata,
+                       
E56PHY_CMS_ANA_OVRDEN_0_OVRD_EN_ANA_LCPLL_HF_LPF_SETCODE_CALIB_I, 0x1);
+               wr32_ephy(hw, addr, rdata);
+
+               rdata = 0x0000;
+               addr = E56PHY_CMS_ANA_OVRDVAL_2_ADDR;
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata,
+                              
E56PHY_CMS_ANA_OVRDVAL_2_ANA_LCPLL_HF_LPF_SETCODE_CALIB_I, 0x3);
+               wr32_ephy(hw, addr, rdata);
+               rdata = 0x0000;
+               addr = E56PHY_CMS_ANA_OVRDEN_1_ADDR;
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata,
+                       
E56PHY_CMS_ANA_OVRDEN_1_OVRD_EN_ANA_LCPLL_LF_LPF_SETCODE_CALIB_I, 0x1);
+               wr32_ephy(hw, addr, rdata);
+               rdata = 0x0000;
+               addr = E56PHY_CMS_ANA_OVRDVAL_7_ADDR;
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata,
+                              
E56PHY_CMS_ANA_OVRDVAL_7_ANA_LCPLL_LF_LPF_SETCODE_CALIB_I, 0x3);
+               wr32_ephy(hw, addr, rdata);
+       } else {
+               rdata = 0x0000;
+               addr = E56PHY_CMS_ANA_OVRDEN_1_ADDR;
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 
E56PHY_CMS_ANA_OVRDEN_1_OVRD_EN_ANA_LCPLL_HF_TEST_IN_I,
+                              0x1);
+               wr32_ephy(hw, addr, rdata);
+
+               rdata = 0x0000;
+               addr = E56PHY_CMS_ANA_OVRDVAL_4_ADDR;
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 24, 24, 0x1);
+               set_fields_e56(&rdata, 31, 29, 0x4);
+               wr32_ephy(hw, addr, rdata);
+
+               rdata = 0x0000;
+               addr = E56PHY_CMS_ANA_OVRDVAL_5_ADDR;
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 1, 0, 0x0);
+               wr32_ephy(hw, addr, rdata);
+               rdata = 0x0000;
+               addr = E56PHY_CMS_ANA_OVRDEN_1_ADDR;
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 
E56PHY_CMS_ANA_OVRDEN_1_OVRD_EN_ANA_LCPLL_LF_TEST_IN_I,
+                              0x1);
+               wr32_ephy(hw, addr, rdata);
+
+               rdata = 0x0000;
+               addr = E56PHY_CMS_ANA_OVRDVAL_9_ADDR;
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 24, 24, 0x1);
+               set_fields_e56(&rdata, 31, 29, 0x4);
+               wr32_ephy(hw, addr, rdata);
+
+               rdata = 0x0000;
+               addr = E56PHY_CMS_ANA_OVRDVAL_10_ADDR;
+               rdata = rd32_ephy(hw, addr);
+               set_fields_e56(&rdata, 1, 0, 0x0);
+               wr32_ephy(hw, addr, rdata);
+       }
+       return status;
+}
+
+static int txgbe_e56_bp_cfg_25g(struct txgbe_hw *hw)
+{
+       u32 addr, rdata;
+
+       rdata = 0x0000;
+       addr = E56PHY_CMS_PIN_OVRDVAL_0_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, 
E56PHY_CMS_PIN_OVRDVAL_0_INT_PLL0_TX_SIGNAL_TYPE_I, 0x0);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CMS_PIN_OVRDEN_0_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, 
E56PHY_CMS_PIN_OVRDEN_0_OVRD_EN_PLL0_TX_SIGNAL_TYPE_I,
+                      0x0);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CMS_ANA_OVRDVAL_2_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, 
E56PHY_CMS_ANA_OVRDVAL_2_ANA_LCPLL_HF_VCO_SWING_CTRL_I,
+                      0xf);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CMS_ANA_OVRDEN_0_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata,
+                      
E56PHY_CMS_ANA_OVRDEN_0_OVRD_EN_ANA_LCPLL_HF_VCO_SWING_CTRL_I, 0x1);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CMS_ANA_OVRDVAL_4_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, 23, 0, 0x260000);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr  = E56PHY_CMS_ANA_OVRDEN_1_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, 
E56PHY_CMS_ANA_OVRDEN_1_OVRD_EN_ANA_LCPLL_HF_TEST_IN_I,
+                      0x1);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_TXS_TXS_CFG_1_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_TXS_TXS_CFG_1_ADAPTATION_WAIT_CNT_X256, 
0xf);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_TXS_WKUP_CNT_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_TXS_WKUP_CNTLDO_WKUP_CNT_X32, 0xff);
+       set_fields_e56(&rdata, E56PHY_TXS_WKUP_CNTDCC_WKUP_CNT_X32, 0xff);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_TXS_PIN_OVRDVAL_6_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, 27, 24, 0x5);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_TXS_PIN_OVRDEN_0_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, 
E56PHY_TXS_PIN_OVRDEN_0_OVRD_EN_TX0_EFUSE_BITS_I, 0x1);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_TXS_ANA_OVRDVAL_1_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_TXS_ANA_OVRDVAL_1_ANA_TEST_DAC_I, 0x1);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_TXS_ANA_OVRDEN_0_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_TXS_ANA_OVRDEN_0_OVRD_EN_ANA_TEST_DAC_I, 
0x1);
+       wr32_ephy(hw, addr, rdata);
+
+       txgbe_e56_tx_ffe_cfg(hw, TXGBE_LINK_SPEED_25GB_FULL);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_RXS_CFG_0_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_RXS_CFG_0_DSER_DATA_SEL, 0x0);
+       set_fields_e56(&rdata, E56PHY_RXS_RXS_CFG_0_TRAIN_CLK_GATE_BYPASS_EN, 
0x1fff);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr  = E56PHY_RXS_OSC_CAL_N_CDR_1_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_OSC_CAL_N_CDR_1_PREDIV1, 0x700);
+       set_fields_e56(&rdata, E56PHY_RXS_OSC_CAL_N_CDR_1_TARGET_CNT1, 0x2418);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_OSC_CAL_N_CDR_4_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_OSC_CAL_N_CDR_4_OSC_RANGE_SEL1, 0x1);
+       set_fields_e56(&rdata, E56PHY_RXS_OSC_CAL_N_CDR_4_VCO_CODE_INIT, 0x7fb);
+       set_fields_e56(&rdata, 
E56PHY_RXS_OSC_CAL_N_CDR_4_OSC_CURRENT_BOOST_EN1, 0x0);
+       set_fields_e56(&rdata, E56PHY_RXS_OSC_CAL_N_CDR_4_BBCDR_CURRENT_BOOST1, 
0x0);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_OSC_CAL_N_CDR_5_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_OSC_CAL_N_CDR_5_SDM_WIDTH, 0x3);
+       set_fields_e56(&rdata, 
E56PHY_RXS_OSC_CAL_N_CDR_5_BB_CDR_PROP_STEP_PRELOCK,
+                      0xf);
+       set_fields_e56(&rdata, 
E56PHY_RXS_OSC_CAL_N_CDR_5_BB_CDR_PROP_STEP_POSTLOCK,
+                      0x3);
+       set_fields_e56(&rdata, 
E56PHY_RXS_OSC_CAL_N_CDR_5_BB_CDR_GAIN_CTRL_POSTLOCK,
+                      0xa);
+       set_fields_e56(&rdata, 
E56PHY_RXS_OSC_CAL_N_CDR_5_BB_CDR_GAIN_CTRL_PRELOCK,
+                      0xf);
+       set_fields_e56(&rdata, E56PHY_RXS_OSC_CAL_N_CDR_5_BBCDR_RDY_CNT, 0x3);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_OSC_CAL_N_CDR_6_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_OSC_CAL_N_CDR_6_PI_GAIN_CTRL_PRELOCK, 
0x7);
+       set_fields_e56(&rdata, 
E56PHY_RXS_OSC_CAL_N_CDR_6_PI_GAIN_CTRL_POSTLOCK, 0x5);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_INTL_CONFIG_0_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_INTL_CONFIG_0_ADC_INTL2SLICE_DELAY1, 
0x3333);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_INTL_CONFIG_2_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, 
E56PHY_RXS_INTL_CONFIG_2_INTERLEAVER_HBW_DISABLE1, 0x0);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_TXFFE_TRAINING_0_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_TXFFE_TRAINING_0_ADC_DATA_PEAK_LTH, 
0x56);
+       set_fields_e56(&rdata, E56PHY_RXS_TXFFE_TRAINING_0_ADC_DATA_PEAK_UTH, 
0x6a);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_TXFFE_TRAINING_1_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_TXFFE_TRAINING_1_C1_LTH, 0x1f8);
+       set_fields_e56(&rdata, E56PHY_RXS_TXFFE_TRAINING_1_C1_UTH, 0xf0);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_TXFFE_TRAINING_2_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_TXFFE_TRAINING_2_CM1_LTH, 0x100);
+       set_fields_e56(&rdata, E56PHY_RXS_TXFFE_TRAINING_2_CM1_UTH, 0xff);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_TXFFE_TRAINING_3_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_TXFFE_TRAINING_3_CM2_LTH, 0x4);
+       set_fields_e56(&rdata, E56PHY_RXS_TXFFE_TRAINING_3_CM2_UTH, 0x37);
+       set_fields_e56(&rdata, 
E56PHY_RXS_TXFFE_TRAINING_3_TXFFE_TRAIN_MOD_TYPE, 0x38);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56G__RXS0_FOM_18__ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56G__RXS0_FOM_18__DFE_COEFFL_HINT__MSB,
+                      E56G__RXS0_FOM_18__DFE_COEFFL_HINT__LSB, 0x0);
+       set_fields_e56(&rdata, E56G__RXS0_FOM_18__DFE_COEFFH_HINT__MSB,
+                      E56G__RXS0_FOM_18__DFE_COEFFH_HINT__LSB, 0x0);
+       set_fields_e56(&rdata, E56G__RXS0_FOM_18__DFE_COEFF_HINT_LOAD__MSB,
+                      E56G__RXS0_FOM_18__DFE_COEFF_HINT_LOAD__LSB, 0x1);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_VGA_TRAINING_0_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_VGA_TRAINING_0_VGA_TARGET, 0x34);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_VGA_TRAINING_1_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_VGA_TRAINING_1_VGA1_CODE_INIT0, 0xa);
+       set_fields_e56(&rdata, E56PHY_RXS_VGA_TRAINING_1_VGA2_CODE_INIT0, 0xa);
+       set_fields_e56(&rdata, E56PHY_RXS_VGA_TRAINING_1_VGA1_CODE_INIT123, 
0xa);
+       set_fields_e56(&rdata, E56PHY_RXS_VGA_TRAINING_1_VGA2_CODE_INIT123, 
0xa);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_CTLE_TRAINING_0_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_CTLE_TRAINING_0_CTLE_CODE_INIT0, 0x9);
+       set_fields_e56(&rdata, E56PHY_RXS_CTLE_TRAINING_0_CTLE_CODE_INIT123, 
0x9);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_CTLE_TRAINING_1_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_CTLE_TRAINING_1_LFEQ_LUT, 0x1ffffea);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_CTLE_TRAINING_2_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_CTLE_TRAINING_2_ISI_TH_FRAC_P1, 18);
+       set_fields_e56(&rdata, E56PHY_RXS_CTLE_TRAINING_2_ISI_TH_FRAC_P2, 0);
+       set_fields_e56(&rdata, E56PHY_RXS_CTLE_TRAINING_2_ISI_TH_FRAC_P3, 0);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_CTLE_TRAINING_3_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_CTLE_TRAINING_3_TAP_WEIGHT_P1, 1);
+       set_fields_e56(&rdata, E56PHY_RXS_CTLE_TRAINING_3_TAP_WEIGHT_P2, 0);
+       set_fields_e56(&rdata, E56PHY_RXS_CTLE_TRAINING_3_TAP_WEIGHT_P3, 0);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_OFFSET_N_GAIN_CAL_0_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, 
E56PHY_RXS_OFFSET_N_GAIN_CAL_0_ADC_SLICE_DATA_AVG_CNT,
+                      0x3);
+       set_fields_e56(&rdata, E56PHY_RXS_OFFSET_N_GAIN_CAL_0_ADC_DATA_AVG_CNT, 
0x3);
+       set_fields_e56(&rdata, 
E56PHY_RXS_OFFSET_N_GAIN_CAL_0_FE_OFFSET_DAC_CLK_CNT_X8,
+                      0xc);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_OFFSET_N_GAIN_CAL_1_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_OFFSET_N_GAIN_CAL_1_SAMP_ADAPT_CFG, 
0x5);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_FFE_TRAINING_0_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_FFE_TRAINING_0_FFE_TAP_EN, 0xf9ff);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_IDLE_DETECT_1_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_IDLE_DETECT_1_IDLE_TH_ADC_PEAK_MAX, 
0xa);
+       set_fields_e56(&rdata, E56PHY_RXS_IDLE_DETECT_1_IDLE_TH_ADC_PEAK_MIN, 
0x5);
+       wr32_ephy(hw, addr, rdata);
+
+       addr = 0x6cc;
+       rdata = 0x8020000;
+       wr32_ephy(hw, addr, rdata);
+       addr = 0x94;
+       rdata = 0;
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_ANA_OVRDVAL_0_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_ANA_OVRDVAL_0_ANA_EN_RTERM_I, 0x1);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_ANA_OVRDEN_0_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_ANA_OVRDEN_0_OVRD_EN_ANA_EN_RTERM_I, 
0x1);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_ANA_OVRDVAL_6_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, 4, 0, 0x0);
+       set_fields_e56(&rdata, 14, 13, 0x0);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_ANA_OVRDEN_1_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, 
E56PHY_RXS_ANA_OVRDEN_1_OVRD_EN_ANA_BBCDR_VCOFILT_BYP_I,
+                      0x1);
+       set_fields_e56(&rdata, 
E56PHY_RXS_ANA_OVRDEN_1_OVRD_EN_ANA_TEST_BBCDR_I, 0x1);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_ANA_OVRDVAL_15_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, 2, 0, 0x1);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_ANA_OVRDVAL_17_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_ANA_OVRDVAL_17_ANA_VGA2_BOOST_CSTM_I, 
0x0);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_ANA_OVRDEN_3_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, 
E56PHY_RXS_ANA_OVRDEN_3_OVRD_EN_ANA_ANABS_CONFIG_I, 0x1);
+       set_fields_e56(&rdata, 
E56PHY_RXS_ANA_OVRDEN_3_OVRD_EN_ANA_VGA2_BOOST_CSTM_I,
+                      0x1);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_ANA_OVRDVAL_14_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, 13, 13, 0x0);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_ANA_OVRDEN_4_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, 13, 13, 0x1);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_EYE_SCAN_1_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_EYE_SCAN_1_EYE_SCAN_REF_TIMER, 0x400);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_RINGO_0_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, 21, 12, 0x366);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_PMD_CFG_3_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_PMD_CFG_3_CTRL_FSM_TIMEOUT_X64K, 0x80);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_PMD_CFG_4_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_PMD_CFG_4_TRAIN_DC_ON_PERIOD_X64K, 0x18);
+       set_fields_e56(&rdata, E56PHY_PMD_CFG_4_TRAIN_DC_PERIOD_X512K, 0x3e);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_PMD_CFG_5_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_PMD_CFG_5_USE_RECENT_MARKER_OFFSET, 0x1);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CTRL_FSM_CFG_0_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_0_CONT_ON_ADC_GAIN_CAL_ERR, 
0x1);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_0_DO_RX_ADC_OFST_CAL, 0x3);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_0_RX_ERR_ACTION_EN, 0x40);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CTRL_FSM_CFG_1_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_1_TRAIN_ST0_WAIT_CNT_X4096, 
0xff);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_1_TRAIN_ST1_WAIT_CNT_X4096, 
0xff);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_1_TRAIN_ST2_WAIT_CNT_X4096, 
0xff);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_1_TRAIN_ST3_WAIT_CNT_X4096, 
0xff);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CTRL_FSM_CFG_2_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_2_TRAIN_ST4_WAIT_CNT_X4096, 
0x1);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_2_TRAIN_ST5_WAIT_CNT_X4096, 
0x4);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_2_TRAIN_ST6_WAIT_CNT_X4096, 
0x4);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_2_TRAIN_ST7_WAIT_CNT_X4096, 
0x4);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CTRL_FSM_CFG_3_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_3_TRAIN_ST8_WAIT_CNT_X4096, 
0x4);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_3_TRAIN_ST9_WAIT_CNT_X4096, 
0x4);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_3_TRAIN_ST10_WAIT_CNT_X4096, 
0x4);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_3_TRAIN_ST11_WAIT_CNT_X4096, 
0x4);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CTRL_FSM_CFG_4_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_4_TRAIN_ST12_WAIT_CNT_X4096, 
0x4);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_4_TRAIN_ST13_WAIT_CNT_X4096, 
0x4);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_4_TRAIN_ST14_WAIT_CNT_X4096, 
0x4);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_4_TRAIN_ST15_WAIT_CNT_X4096, 
0x4);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CTRL_FSM_CFG_7_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_7_TRAIN_ST4_EN, 0x4bf);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_7_TRAIN_ST5_EN, 0xc4bf);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CTRL_FSM_CFG_8_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_8_TRAIN_ST7_EN, 0x47ff);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CTRL_FSM_CFG_12_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_12_TRAIN_ST15_EN, 0x67ff);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CTRL_FSM_CFG_13_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_13_TRAIN_ST0_DONE_EN, 
0x8001);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_13_TRAIN_ST1_DONE_EN, 
0x8002);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CTRL_FSM_CFG_14_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_14_TRAIN_ST3_DONE_EN, 
0x8008);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CTRL_FSM_CFG_15_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_15_TRAIN_ST4_DONE_EN, 
0x8004);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CTRL_FSM_CFG_17_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_17_TRAIN_ST8_DONE_EN, 
0x20c0);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CTRL_FSM_CFG_18_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_18_TRAIN_ST10_DONE_EN, 0x0);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CTRL_FSM_CFG_29_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_29_TRAIN_ST15_DC_EN, 0x3f6d);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CTRL_FSM_CFG_33_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_33_TRAIN0_RATE_SEL, 0x8000);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_33_TRAIN1_RATE_SEL, 0x8000);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CTRL_FSM_CFG_34_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_34_TRAIN2_RATE_SEL, 0x8000);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_34_TRAIN3_RATE_SEL, 0x8000);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_KRT_TFSM_CFG_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, 
E56PHY_KRT_TFSM_CFGKRT_TFSM_MAX_WAIT_TIMER_X1000K, 0x49);
+       set_fields_e56(&rdata, 
E56PHY_KRT_TFSM_CFGKRT_TFSM_MAX_WAIT_TIMER_X8000K, 0x37);
+       set_fields_e56(&rdata, E56PHY_KRT_TFSM_CFGKRT_TFSM_HOLDOFF_TIMER_X256K, 
0x2f);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_FETX_FFE_TRAIN_CFG_0_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, 
E56PHY_FETX_FFE_TRAIN_CFG_0_KRT_FETX_INIT_FFE_CFG_2,
+                      0x2);
+       wr32_ephy(hw, addr, rdata);
+
+       return 0;
+}
+
+static int txgbe_e56_bp_cfg_10g(struct txgbe_hw *hw)
+{
+       u32 addr, rdata;
+
+       rdata = 0x0000;
+       addr = E56G__CMS_ANA_OVRDVAL_7_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       ((E56G__CMS_ANA_OVRDVAL_7 *)&rdata)->ana_lcpll_lf_vco_swing_ctrl_i = 
0xf;
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56G__CMS_ANA_OVRDEN_1_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       ((E56G__CMS_ANA_OVRDEN_1 
*)&rdata)->ovrd_en_ana_lcpll_lf_vco_swing_ctrl_i = 0x1;
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56G__CMS_ANA_OVRDVAL_9_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, 23, 0, 0x260000);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr  = E56G__CMS_ANA_OVRDEN_1_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       ((E56G__CMS_ANA_OVRDEN_1 *)&rdata)->ovrd_en_ana_lcpll_lf_test_in_i = 
0x1;
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_TXS_TXS_CFG_1_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_TXS_TXS_CFG_1_ADAPTATION_WAIT_CNT_X256, 
0xf);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_TXS_WKUP_CNT_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_TXS_WKUP_CNTLDO_WKUP_CNT_X32, 0xff);
+       set_fields_e56(&rdata, E56PHY_TXS_WKUP_CNTDCC_WKUP_CNT_X32, 0xff);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_TXS_PIN_OVRDVAL_6_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, 19, 16, 0x6);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_TXS_PIN_OVRDEN_0_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, 
E56PHY_TXS_PIN_OVRDEN_0_OVRD_EN_TX0_EFUSE_BITS_I, 0x1);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_TXS_ANA_OVRDVAL_1_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_TXS_ANA_OVRDVAL_1_ANA_TEST_DAC_I, 0x1);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_TXS_ANA_OVRDEN_0_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_TXS_ANA_OVRDEN_0_OVRD_EN_ANA_TEST_DAC_I, 
0x1);
+       wr32_ephy(hw, addr, rdata);
+
+       txgbe_e56_tx_ffe_cfg(hw, TXGBE_LINK_SPEED_10GB_FULL);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_RXS_CFG_0_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_RXS_CFG_0_DSER_DATA_SEL, 0x0);
+       set_fields_e56(&rdata, E56PHY_RXS_RXS_CFG_0_TRAIN_CLK_GATE_BYPASS_EN, 
0x1fff);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr  = E56PHY_RXS_OSC_CAL_N_CDR_1_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       ((E56G_RXS0_OSC_CAL_N_CDR_0 *)&rdata)->prediv0 = 0xfa0;
+       ((E56G_RXS0_OSC_CAL_N_CDR_0 *)&rdata)->target_cnt0 = 0x203a;
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_OSC_CAL_N_CDR_4_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       ((E56G_RXS0_OSC_CAL_N_CDR_4 *)&rdata)->osc_range_sel0 = 0x2;
+       ((E56G_RXS0_OSC_CAL_N_CDR_4 *)&rdata)->vco_code_init = 0x7ff;
+       ((E56G_RXS0_OSC_CAL_N_CDR_4 *)&rdata)->osc_current_boost_en0 = 0x1;
+       ((E56G_RXS0_OSC_CAL_N_CDR_4 *)&rdata)->bbcdr_current_boost0 = 0x0;
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_OSC_CAL_N_CDR_5_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_OSC_CAL_N_CDR_5_SDM_WIDTH, 0x3);
+       set_fields_e56(&rdata, 
E56PHY_RXS_OSC_CAL_N_CDR_5_BB_CDR_PROP_STEP_PRELOCK,
+                      0xf);
+       set_fields_e56(&rdata, 
E56PHY_RXS_OSC_CAL_N_CDR_5_BB_CDR_PROP_STEP_POSTLOCK,
+                      0xf);
+       set_fields_e56(&rdata, 
E56PHY_RXS_OSC_CAL_N_CDR_5_BB_CDR_GAIN_CTRL_POSTLOCK,
+                      0xc);
+       set_fields_e56(&rdata, 
E56PHY_RXS_OSC_CAL_N_CDR_5_BB_CDR_GAIN_CTRL_PRELOCK,
+                      0xf);
+       set_fields_e56(&rdata, E56PHY_RXS_OSC_CAL_N_CDR_5_BBCDR_RDY_CNT, 0x3);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_OSC_CAL_N_CDR_6_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_OSC_CAL_N_CDR_6_PI_GAIN_CTRL_PRELOCK, 
0x7);
+       set_fields_e56(&rdata, 
E56PHY_RXS_OSC_CAL_N_CDR_6_PI_GAIN_CTRL_POSTLOCK, 0x5);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_INTL_CONFIG_0_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       ((E56G_RXS0_INTL_CONFIG_0 *)&rdata)->adc_intl2slice_delay0 = 0x5555;
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_INTL_CONFIG_2_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       ((E56G_RXS0_INTL_CONFIG_2 *)&rdata)->interleaver_hbw_disable0 = 0x1;
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_TXFFE_TRAINING_0_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_TXFFE_TRAINING_0_ADC_DATA_PEAK_LTH, 
0x56);
+       set_fields_e56(&rdata, E56PHY_RXS_TXFFE_TRAINING_0_ADC_DATA_PEAK_UTH, 
0x6a);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_TXFFE_TRAINING_1_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_TXFFE_TRAINING_1_C1_LTH, 0x1e8);
+       set_fields_e56(&rdata, E56PHY_RXS_TXFFE_TRAINING_1_C1_UTH, 0x78);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_TXFFE_TRAINING_2_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_TXFFE_TRAINING_2_CM1_LTH, 0x100);
+       set_fields_e56(&rdata, E56PHY_RXS_TXFFE_TRAINING_2_CM1_UTH, 0xff);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_TXFFE_TRAINING_3_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_TXFFE_TRAINING_3_CM2_LTH, 0x4);
+       set_fields_e56(&rdata, E56PHY_RXS_TXFFE_TRAINING_3_CM2_UTH, 0x37);
+       set_fields_e56(&rdata, 
E56PHY_RXS_TXFFE_TRAINING_3_TXFFE_TRAIN_MOD_TYPE, 0x38);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_VGA_TRAINING_0_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_VGA_TRAINING_0_VGA_TARGET, 0x34);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_VGA_TRAINING_1_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_VGA_TRAINING_1_VGA1_CODE_INIT0, 0xa);
+       set_fields_e56(&rdata, E56PHY_RXS_VGA_TRAINING_1_VGA2_CODE_INIT0, 0xa);
+       set_fields_e56(&rdata, E56PHY_RXS_VGA_TRAINING_1_VGA1_CODE_INIT123, 
0xa);
+       set_fields_e56(&rdata, E56PHY_RXS_VGA_TRAINING_1_VGA2_CODE_INIT123, 
0xa);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_CTLE_TRAINING_0_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_CTLE_TRAINING_0_CTLE_CODE_INIT0, 0x9);
+       set_fields_e56(&rdata, E56PHY_RXS_CTLE_TRAINING_0_CTLE_CODE_INIT123, 
0x9);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_CTLE_TRAINING_1_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_CTLE_TRAINING_1_LFEQ_LUT, 0x1ffffea);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_CTLE_TRAINING_2_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_CTLE_TRAINING_2_ISI_TH_FRAC_P1, 0x18);
+       set_fields_e56(&rdata, E56PHY_RXS_CTLE_TRAINING_2_ISI_TH_FRAC_P2, 0);
+       set_fields_e56(&rdata, E56PHY_RXS_CTLE_TRAINING_2_ISI_TH_FRAC_P3, 0);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_CTLE_TRAINING_3_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_CTLE_TRAINING_3_TAP_WEIGHT_P1, 1);
+       set_fields_e56(&rdata, E56PHY_RXS_CTLE_TRAINING_3_TAP_WEIGHT_P2, 0);
+       set_fields_e56(&rdata, E56PHY_RXS_CTLE_TRAINING_3_TAP_WEIGHT_P3, 0);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_OFFSET_N_GAIN_CAL_0_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, 
E56PHY_RXS_OFFSET_N_GAIN_CAL_0_ADC_SLICE_DATA_AVG_CNT,
+                      0x3);
+       set_fields_e56(&rdata, E56PHY_RXS_OFFSET_N_GAIN_CAL_0_ADC_DATA_AVG_CNT, 
0x3);
+       set_fields_e56(&rdata, 
E56PHY_RXS_OFFSET_N_GAIN_CAL_0_FE_OFFSET_DAC_CLK_CNT_X8,
+                      0xc);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_OFFSET_N_GAIN_CAL_1_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_OFFSET_N_GAIN_CAL_1_SAMP_ADAPT_CFG, 
0x5);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_FFE_TRAINING_0_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_FFE_TRAINING_0_FFE_TAP_EN, 0xf9ff);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_IDLE_DETECT_1_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_IDLE_DETECT_1_IDLE_TH_ADC_PEAK_MAX, 
0xa);
+       set_fields_e56(&rdata, E56PHY_RXS_IDLE_DETECT_1_IDLE_TH_ADC_PEAK_MIN, 
0x5);
+       wr32_ephy(hw, addr, rdata);
+
+       addr = 0x6cc;
+       rdata = 0x8020000;
+       wr32_ephy(hw, addr, rdata);
+       addr = 0x94;
+       rdata = 0;
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_ANA_OVRDVAL_0_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_ANA_OVRDVAL_0_ANA_EN_RTERM_I, 0x1);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_ANA_OVRDEN_0_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_ANA_OVRDEN_0_OVRD_EN_ANA_EN_RTERM_I, 
0x1);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_ANA_OVRDVAL_6_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, 4, 0, 0x6);
+       set_fields_e56(&rdata, 14, 13, 0x2);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_ANA_OVRDEN_1_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, 
E56PHY_RXS_ANA_OVRDEN_1_OVRD_EN_ANA_BBCDR_VCOFILT_BYP_I,
+                      0x1);
+       set_fields_e56(&rdata, 
E56PHY_RXS_ANA_OVRDEN_1_OVRD_EN_ANA_TEST_BBCDR_I, 0x1);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_ANA_OVRDVAL_15_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, 2, 0, 0x1);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_ANA_OVRDVAL_17_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_ANA_OVRDVAL_17_ANA_VGA2_BOOST_CSTM_I, 
0x0);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_ANA_OVRDEN_3_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, 
E56PHY_RXS_ANA_OVRDEN_3_OVRD_EN_ANA_ANABS_CONFIG_I, 0x1);
+       set_fields_e56(&rdata, 
E56PHY_RXS_ANA_OVRDEN_3_OVRD_EN_ANA_VGA2_BOOST_CSTM_I,
+                      0x1);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_ANA_OVRDVAL_14_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, 13, 13, 0x1);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_ANA_OVRDEN_4_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, 13, 13, 0x1);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_EYE_SCAN_1_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_RXS_EYE_SCAN_1_EYE_SCAN_REF_TIMER, 0x400);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_RXS_RINGO_0_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, 21, 12, 0x366);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_PMD_CFG_3_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_PMD_CFG_3_CTRL_FSM_TIMEOUT_X64K, 0x80);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_PMD_CFG_4_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_PMD_CFG_4_TRAIN_DC_ON_PERIOD_X64K, 0x18);
+       set_fields_e56(&rdata, E56PHY_PMD_CFG_4_TRAIN_DC_PERIOD_X512K, 0x3e);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_PMD_CFG_5_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_PMD_CFG_5_USE_RECENT_MARKER_OFFSET, 0x1);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CTRL_FSM_CFG_0_ADDR;
+       rdata = rd32_ephy(hw, addr);
+
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_0_CONT_ON_ADC_GAIN_CAL_ERR, 
0x1);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_0_DO_RX_ADC_OFST_CAL, 0x3);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_0_RX_ERR_ACTION_EN, 0x40);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CTRL_FSM_CFG_1_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_1_TRAIN_ST0_WAIT_CNT_X4096, 
0xff);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_1_TRAIN_ST1_WAIT_CNT_X4096, 
0xff);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_1_TRAIN_ST2_WAIT_CNT_X4096, 
0xff);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_1_TRAIN_ST3_WAIT_CNT_X4096, 
0xff);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CTRL_FSM_CFG_2_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_2_TRAIN_ST4_WAIT_CNT_X4096, 
0x1);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_2_TRAIN_ST5_WAIT_CNT_X4096, 
0x4);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_2_TRAIN_ST6_WAIT_CNT_X4096, 
0x4);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_2_TRAIN_ST7_WAIT_CNT_X4096, 
0x4);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CTRL_FSM_CFG_3_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_3_TRAIN_ST8_WAIT_CNT_X4096, 
0x4);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_3_TRAIN_ST9_WAIT_CNT_X4096, 
0x4);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_3_TRAIN_ST10_WAIT_CNT_X4096, 
0x4);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_3_TRAIN_ST11_WAIT_CNT_X4096, 
0x4);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CTRL_FSM_CFG_4_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_4_TRAIN_ST12_WAIT_CNT_X4096, 
0x4);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_4_TRAIN_ST13_WAIT_CNT_X4096, 
0x4);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_4_TRAIN_ST14_WAIT_CNT_X4096, 
0x4);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_4_TRAIN_ST15_WAIT_CNT_X4096, 
0x4);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CTRL_FSM_CFG_7_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_7_TRAIN_ST4_EN, 0x4bf);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_7_TRAIN_ST5_EN, 0xc4bf);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CTRL_FSM_CFG_8_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_8_TRAIN_ST7_EN, 0x47ff);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CTRL_FSM_CFG_12_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_12_TRAIN_ST15_EN, 0x67ff);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CTRL_FSM_CFG_13_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_13_TRAIN_ST0_DONE_EN, 
0x8001);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_13_TRAIN_ST1_DONE_EN, 
0x8002);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CTRL_FSM_CFG_14_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_14_TRAIN_ST3_DONE_EN, 
0x8008);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CTRL_FSM_CFG_15_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_15_TRAIN_ST4_DONE_EN, 
0x8004);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CTRL_FSM_CFG_17_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_17_TRAIN_ST8_DONE_EN, 
0x20c0);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CTRL_FSM_CFG_18_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_18_TRAIN_ST10_DONE_EN, 0x0);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CTRL_FSM_CFG_29_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_29_TRAIN_ST15_DC_EN, 0x3f6d);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CTRL_FSM_CFG_33_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_33_TRAIN0_RATE_SEL, 0x8000);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_33_TRAIN1_RATE_SEL, 0x8000);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_CTRL_FSM_CFG_34_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_34_TRAIN2_RATE_SEL, 0x8000);
+       set_fields_e56(&rdata, E56PHY_CTRL_FSM_CFG_34_TRAIN3_RATE_SEL, 0x8000);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_KRT_TFSM_CFG_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, 
E56PHY_KRT_TFSM_CFGKRT_TFSM_MAX_WAIT_TIMER_X1000K, 0x49);
+       set_fields_e56(&rdata, 
E56PHY_KRT_TFSM_CFGKRT_TFSM_MAX_WAIT_TIMER_X8000K, 0x37);
+       set_fields_e56(&rdata, E56PHY_KRT_TFSM_CFGKRT_TFSM_HOLDOFF_TIMER_X256K, 
0x2f);
+       wr32_ephy(hw, addr, rdata);
+
+       rdata = 0x0000;
+       addr = E56PHY_FETX_FFE_TRAIN_CFG_0_ADDR;
+       rdata = rd32_ephy(hw, addr);
+       set_fields_e56(&rdata, 
E56PHY_FETX_FFE_TRAIN_CFG_0_KRT_FETX_INIT_FFE_CFG_2,
+                      0x2);
+       wr32_ephy(hw, addr, rdata);
+
+       return 0;
+}
+
+static int txgbe_set_phy_link_mode(struct txgbe_hw *hw,
+                                  u8 bp_link_mode)
+{
+       int status = 0;
+       u32 rdata = 0;
+
+       u32 speed_select = 0;
+       u32 pcs_type_sel = 0;
+       u32 cns_en = 0;
+       u32 rsfec_en = 0;
+       u32 pma_type = 0;
+       u32 an0_rate_select = 0;
+
+       switch (bp_link_mode) {
+       case 10:
+               bp_link_mode = 10;
+               speed_select = 0; /* 10 Gb/s */
+               pcs_type_sel = 0; /* 10GBASE-R PCS Type */
+               cns_en = 0; /* CNS_EN disable */
+               rsfec_en = 0; /* RS-FEC disable */
+               pma_type = 0xb; /* 10GBASE-KR PMA/PMD type */
+               an0_rate_select = 2; /* 10G-KR */
+               break;
+       case 40:
+               bp_link_mode = 40;
+               speed_select = 3; /* 40 Gb/s */
+               pcs_type_sel = 4; /* 40GBASE-R PCS Type */
+               cns_en = 0; /* CNS_EN disable */
+               rsfec_en = 0; /* RS-FEC disable */
+               pma_type = 0b0100001; /* 40GBASE-CR PMA/PMD type */
+               an0_rate_select = 4; /* 40G-KR: 3 40G-CR: 4 */
+               break;
+       case 25:
+               bp_link_mode = 25;
+               speed_select = 5; /* 25 Gb/s */
+               pcs_type_sel = 7; /* 25GBASE-R PCS Type */
+               cns_en = 1; /* CNS_EN */
+               rsfec_en = 1; /* RS-FEC enable*/
+               pma_type = 0b0111001; /* 25GBASE-KR PMA/PMD type */
+               an0_rate_select = 9; /* 9/10/17 25GK/CR-S or 25GK/CR */
+               break;
+       default:
+               BP_LOG("%s %d :Invalid bp_link_mode\n", __func__, __LINE__);
+               break;
+       }
+
+       hw->curbp_link_mode = bp_link_mode;
+       /* To switch to the 40G mode Ethernet operation, complete the following 
steps:*/
+       /* 1. Initiate the vendor-specific software reset by programming
+        * the VR_RST field (bit [15]) of the VR_PCS_DIG_CTRL1 register to 1.
+        */
+       rdata = rd32_epcs(hw, 0x038000);
+       wr32_epcs(hw, 0x038000, rdata | BIT(15));
+
+       /* 2. Wait for the hardware to clear the value for the VR_RST
+        * field (bit [15]) of the VR_PCS_DIG_CTRL1 register.
+        */
+       BP_LOG("Wait for the bit [15] (VR_RST) to get cleared.\n");
+       status = kr_read_poll(rd32_ephy, rdata,
+                                 FIELD_GET_M(BIT(15), rdata) == 0, 100,
+                                  2000, hw, 0x038000);
+       BP_LOG("Wait PHY VR_RST = %x, Wait VR_RST %s.\n",
+              rdata, status ? "FAILED" : "SUCCESS");
+
+       /* wait rx/tx/cm powerdn_st  according pmd 50   2.0.5 */
+       status = kr_read_poll(rd32_ephy, rdata,
+                            (rdata & GENMASK(3, 0)) == 0x9, 100,
+                             2000, hw, 0x14d4);
+       BP_LOG("wait ctrl_fsm_cm_st = %x, %s.\n",
+              rdata, status ? "FAILED" : "SUCCESS");
+
+       /* 3. Write 4'b0011 to bits [5:2] of the SR_PCS_CTRL1 register.
+        * 10G: 0 25G: 5 40G: 3
+        */
+       rdata = rd32_epcs(hw, 0x030000);
+       set_fields_e56(&rdata, 5, 2, speed_select);
+       wr32_epcs(hw, 0x030000, rdata);
+
+       /* 4. Write pcs mode sel to bits [3:0] of the SR_PCS_CTRL2 register.
+        * 10G: 0 25G: 4'b0111 40G: 4'b0100
+        */
+       rdata = rd32_epcs(hw, 0x030007);
+       set_fields_e56(&rdata, 3, 0, pcs_type_sel);
+       wr32_epcs(hw, 0x030007, rdata);
+
+       /* 0 1 1 1 0 0 1 : 25GBASE-KR or 25GBASE-KR-S PMA/PMD type
+        * 0 1 1 1 0 0 0 : 25GBASE-CR or 25GBASE-CR-S PMA/PMD type
+        * 0 1 0 0 0 0 1 : 40GBASE-CR4 PMA/PMD type
+        * 0 1 0 0 0 0 0 : 40GBASE-KR4 PMA/PMD type
+        * 0 0 0 1 0 1 1 : 10GBASE-KR PMA/PMD type
+        */
+       rdata = rd32_epcs(hw, 0x010007);
+       set_fields_e56(&rdata, 6, 0, pma_type);
+       wr32_epcs(hw, 0x010007, rdata);
+
+       /* 5. Write only 25g en to Bits [1:0] of VR_PCS_DIG_CTRL3 register. */
+       rdata = rd32_epcs(hw, 0x38003);
+       set_fields_e56(&rdata, 1, 0, cns_en);
+       wr32_epcs(hw, 0x38003, rdata);
+
+       /* 6. Program PCS_AM_CNT field of VR_PCS_AM_CNT register to 'd16383 to
+        * configure the alignment marker interval. To speed-up simulation,
+        * program a smaller value to this field.
+        */
+       if (bp_link_mode == 40)
+               wr32_epcs(hw, 0x38018, 16383);
+
+       /* 7. Program bit [2] of SR_PMA_RS_FEC_CTRL register to 0
+        * if previously 1 (as RS-FEC is supported in 25G Mode).
+        */
+
+       rdata = rd32_epcs(hw, 0x100c8);
+       set_fields_e56(&rdata, 2, 2, rsfec_en);
+       wr32_epcs(hw, 0x100c8, rdata);
+
+       /* 8. To enable BASE-R FEC (if desired), set bit [0].
+        * in SR_PMA_KR_FEC_CTRL register
+        */
+
+       /* 4. set phy an status to 0 */
+       rdata = rd32_ephy(hw, 0x1434);
+       set_fields_e56(&rdata, 7, 4, 0xe);
+       wr32_ephy(hw, 0x1434, rdata);
+
+       /* 9. Program Enterprise 56G PHY regs through its own APB interface:
+        * a. Program PHY registers as mentioned in Table 6-6 on page 1197 to
+        *    configure the PHY to 40G
+        *    Mode. For fast-simulation mode, additionally program,
+        *    the registers shown in the Table 6-7 on page 1199
+        * b. Enable the PMD by setting pmd_en field in PMD_CFG[0] (0x1400)
+        *    register
+        */
+
+       rdata = 0x0000;
+       rdata = rd32_ephy(hw, ANA_OVRDVAL0);
+       set_fields_e56(&rdata, 29, 29, 0x1);
+       set_fields_e56(&rdata, 1, 1, 0x1);
+       wr32_ephy(hw, ANA_OVRDVAL0, rdata);
+
+       rdata = 0x0000;
+       rdata =  rd32_ephy(hw, ANA_OVRDVAL5);
+       set_fields_e56(&rdata, 24, 24, 0x1);
+       wr32_ephy(hw, ANA_OVRDVAL5, rdata);
+
+       rdata = 0x0000;
+       rdata =  rd32_ephy(hw, ANA_OVRDEN0);
+       set_fields_e56(&rdata, 1, 1, 0x1);
+       wr32_ephy(hw, ANA_OVRDEN0, rdata);
+
+       rdata = 0x0000;
+       rdata =  rd32_ephy(hw, ANA_OVRDEN1);
+       set_fields_e56(&rdata, 30, 30, 0x1);
+       set_fields_e56(&rdata, 25, 25, 0x1);
+       wr32_ephy(hw, ANA_OVRDEN1, rdata);
+
+       rdata = 0x0000;
+       rdata =  rd32_ephy(hw, PLL0_CFG0);
+       set_fields_e56(&rdata, 25, 24, 0x1);
+       set_fields_e56(&rdata, 17, 16, 0x3);
+       wr32_ephy(hw, PLL0_CFG0, rdata);
+
+       rdata = 0x0000;
+       rdata =  rd32_ephy(hw, PLL0_CFG2);
+       set_fields_e56(&rdata, 12, 8, 0x4);
+       wr32_ephy(hw, PLL0_CFG2, rdata);
+
+       rdata = 0x0000;
+       rdata =  rd32_ephy(hw, PLL1_CFG0);
+       set_fields_e56(&rdata, 25, 24, 0x1);
+       set_fields_e56(&rdata, 17, 16, 0x3);
+       wr32_ephy(hw, PLL1_CFG0, rdata);
+
+       rdata = 0x0000;
+       rdata =  rd32_ephy(hw, PLL1_CFG2);
+       set_fields_e56(&rdata, 12, 8, 0x8);
+       wr32_ephy(hw, PLL1_CFG2, rdata);
+
+       rdata = 0x0000;
+       rdata = rd32_ephy(hw, PLL0_DIV_CFG0);
+       set_fields_e56(&rdata, 18, 8, 0x294);
+       set_fields_e56(&rdata, 4, 0, 0x8);
+       wr32_ephy(hw, PLL0_DIV_CFG0, rdata);
+
+       rdata = 0x0000;
+       rdata = rd32_ephy(hw, DATAPATH_CFG0);
+       set_fields_e56(&rdata, 30, 28, 0x7);
+       set_fields_e56(&rdata, 26, 24, 0x5);
+       if (bp_link_mode == 10 || bp_link_mode == 40)
+               set_fields_e56(&rdata, 18, 16, 0x5);
+       else if (bp_link_mode == 25)
+               set_fields_e56(&rdata, 18, 16, 0x3);
+       set_fields_e56(&rdata, 14, 12, 0x5);
+       set_fields_e56(&rdata, 10, 8, 0x5);
+       wr32_ephy(hw, DATAPATH_CFG0, rdata);
+
+       rdata = 0x0000;
+       rdata = rd32_ephy(hw, DATAPATH_CFG1);
+       set_fields_e56(&rdata, 26, 24, 0x5);
+       set_fields_e56(&rdata, 10, 8, 0x5);
+       if (bp_link_mode == 10 || bp_link_mode == 40) {
+               set_fields_e56(&rdata, 18, 16, 0x5);
+               set_fields_e56(&rdata, 2, 0, 0x5);
+       } else if (bp_link_mode == 25) {
+               set_fields_e56(&rdata, 18, 16, 0x3);
+               set_fields_e56(&rdata, 2, 0, 0x3);
+       }
+       wr32_ephy(hw, DATAPATH_CFG1, rdata);
+
+       rdata = rd32_ephy(hw, AN_CFG1);
+       set_fields_e56(&rdata, 4, 0, an0_rate_select);
+       wr32_ephy(hw, AN_CFG1, rdata);
+
+       status = txgbe_e56_cms_cfg_for_temp_track_range(hw);
+
+       if (bp_link_mode == 10)
+               txgbe_e56_bp_cfg_10g(hw);
+       else if (bp_link_mode == 25)
+               txgbe_e56_bp_cfg_25g(hw);
+       else if (bp_link_mode == 40)
+               txgbe_e56_cfg_40g(hw);
+
+       return status;
+}
+
+int txgbe_e56_set_phy_link_mode(struct txgbe_hw *hw,
+                            u8 bp_link_mode, u32 need_restart)
+{
+       int status = 0;
+       u32 rdata;
+
+       UNREFERENCED_PARAMETER(bp_link_mode);
+
+       hw->an_done = false;
+       if (hw->curbp_link_mode == 10 && !need_restart)
+               return 0;
+       BP_LOG("Setup to backplane mode ==========\n");
+
+       u32 backplane_mode = 0;
+       u32 fec_advertise = 0;
+
+       hw->an_done = false;
+       /* pcs + phy rst */
+       rdata = rd32(hw, 0x1000c);
+       if (hw->bus.lan_id == 1)
+               rdata |= BIT(16);
+       else
+               rdata |= BIT(19);
+       wr32(hw, 0x1000c, rdata);
+       msleep(20);
+
+       /* clear interrupt */
+       wr32_epcs(hw, 0x070000, 0);
+       wr32_epcs(hw, 0x030000, 0x8000);
+       rdata = rd32_epcs(hw, 0x070000);
+       set_fields_e56(&rdata, 12, 12, 0x1);
+       wr32_epcs(hw, 0x070000, rdata);
+       wr32_epcs(hw, 0x078002, 0x0000);
+       /* pcs case fec en to work around first */
+       wr32_epcs(hw, 0x100ab, 1);
+
+       if (txgbe_is_backplane(hw)) {
+               /* backplane 10G/25G/40G */
+               /* 10GKR:7-25KR:14/15-40GKR:8-40GCR:9 */
+               /* default all speed */
+               if ((hw->device_id & 0xFF) == 0x10) {
+                       backplane_mode |= BIT(7);
+                       fec_advertise |= TXGBE_10G_FEC_ABL;
+               } else if ((hw->device_id & 0xFF) == 0x25) {
+                       backplane_mode |= BIT(14) | BIT(15);
+                       fec_advertise |= TXGBE_25G_RS_FEC_REQ |
+                                        TXGBE_25G_BASE_FEC_REQ;
+               } else if ((hw->device_id & 0xFF) == 0x40) {
+                       if (hw->phy.bp_capa == 0)
+                               /* original configure: KR4 + CR4 */
+                               backplane_mode |= BIT(9) | BIT(8);
+                       else if (hw->phy.bp_capa == 1)
+                               /* only 40GBASE-KR4 */
+                               backplane_mode |= BIT(8);
+                       else if (hw->phy.bp_capa == 2)
+                               /* only 40GBASE-CR4 */
+                               backplane_mode |= BIT(9);
+                       fec_advertise |= TXGBE_10G_FEC_ABL;
+                       BP_LOG("Advertised abilities: %d\n", backplane_mode);
+               }
+       } else {
+               if ((hw->phy.fiber_suppport_speed & TXGBE_LINK_SPEED_10GB_FULL)
+                    == TXGBE_LINK_SPEED_10GB_FULL) {
+                       backplane_mode |= 0x80;
+                       fec_advertise |= TXGBE_10G_FEC_ABL;
+               }
+
+               if ((hw->phy.fiber_suppport_speed & TXGBE_LINK_SPEED_25GB_FULL)
+                   == TXGBE_LINK_SPEED_25GB_FULL) {
+                       backplane_mode |= 0xc000;
+                       fec_advertise |= TXGBE_25G_RS_FEC_REQ |
+                                        TXGBE_25G_BASE_FEC_REQ;
+               }
+
+               if ((hw->phy.fiber_suppport_speed & TXGBE_LINK_SPEED_40GB_FULL)
+                   == TXGBE_LINK_SPEED_40GB_FULL) {
+                       backplane_mode |= BIT(9) | BIT(8);
+                       fec_advertise |= TXGBE_10G_FEC_ABL;
+               }
+       }
+
+       wr32_epcs(hw, 0x070010, 0x0001);
+
+       /* 10GKR:7-25KR:14/15-40GKR:8-40GCR:9 */
+       wr32_epcs(hw, 0x070011, backplane_mode | 0x11);
+
+       /* BASE-R FEC */
+       rdata = rd32_epcs(hw, 0x70012);
+       wr32_epcs(hw, 0x70012, fec_advertise);
+
+       wr32_epcs(hw, 0x070016, 0x0000);
+       wr32_epcs(hw, 0x070017, 0x0);
+       wr32_epcs(hw, 0x070018, 0x0);
+
+       /* config timer */
+       wr32_epcs(hw, 0x078004, 0x003c);
+       wr32_epcs(hw, 0x078005, CL74_KRTR_TRAINNING_TIMEOUT);
+       wr32_epcs(hw, 0x078006, 25);
+       wr32_epcs(hw, 0x078000, 0x0008 | BIT(2));
+
+       BP_LOG("1.2 Wait 10G KR phy/pcs mode init ....\n");
+       status = txgbe_set_phy_link_mode(hw, 10);
+       BP_LOG("Wait 10g phy/pcs mode init = %x, %s.\n", rdata,
+       /* wait rx/tx/cm powerdn_st  according pmd 50   2.0.5 */
+              status ? "FAILED" : "SUCCESS");
+
+       /* 5. CM_ENABLE */
+       rdata = rd32_ephy(hw, 0x1400);
+       set_fields_e56(&rdata, 21, 20, 0x3);    /* pll en */
+       set_fields_e56(&rdata, 19, 12, 0x0);    /* tx disable */
+       set_fields_e56(&rdata, 8, 8, 0x0);      /* pmd mode */
+       set_fields_e56(&rdata, 1, 1, 0x1);      /* pmd en */
+       wr32_ephy(hw, 0x1400, rdata);
+
+       /* 6, TX_ENABLE */
+       rdata = rd32_ephy(hw, 0x1400);
+       set_fields_e56(&rdata, 19, 12, 0x1);    /* tx en */
+       wr32_ephy(hw, 0x1400, rdata);
+
+       BP_LOG("1.3 Wait 10G PHY RXS....\n");
+       status = txgbe_e56_rxs_osc_init_for_temp_track_range(hw, 10);
+       BP_LOG("Wait 10G PHY/RXS mode init = %x, %s.\n", rdata,
+              status ? "FAILED" : "SUCCESS");
+
+       /* Wait an 10g fsm_rx_sts */
+       status = kr_read_poll(rd32_ephy, rdata,
+                               ((rdata & 0x3f) == 0xb), 1000,
+                               200, hw,
+                               E56PHY_CTRL_FSM_RX_STAT_0_ADDR);
+       BP_LOG("Wait 10g fsm_rx_sts = %x, Wait rx_sts %s.\n", rdata,
+               status ? "FAILED" : "SUCCESS");
+       rdata = rd32_epcs(hw, 0x070000);
+       set_fields_e56(&rdata, 12, 12, 0x1);
+       wr32_epcs(hw, 0x070000, rdata);
+       BP_LOG("Setup the backplane mode========end ==\n");
+
+       return status;
+}
+
+static void txgbe_e56_print_page_status(struct txgbe_hw *hw,
+       struct txgbe_backplane_ability *local_ability,
+       struct txgbe_backplane_ability *lp_ability)
+{
+       u32 rdata = 0;
+
+       /* Read the local AN73 Base Page Ability Registers */
+       BP_LOG("Read the local Base Page Ability Registers\n");
+       rdata = rd32_epcs(hw, SR_AN_MMD_ADV_REG1);
+       local_ability->next_page = (rdata & BIT(15)) ? 1 : 0;
+       BP_LOG("\tread 70010 data %0x\n", rdata);
+       rdata = rd32_epcs(hw, SR_AN_MMD_ADV_REG2);
+       BP_LOG("\tread 70011 data %0x\n", rdata);
+       local_ability->link_ability = (rdata >> 5) & GENMASK(10, 0);
+       /* amber-lite only support 10GKR - 25GKR/CR - 25GKR-S/CR-S */
+       BP_LOG("\t10GKR : %x\t25GKR-S/CR-S: %x\t25GKR/CR : %x\n",
+              local_ability->link_ability & BIT(ABILITY_10GBASE_KR) ? 1 : 0,
+              local_ability->link_ability & BIT(ABILITY_25GBASE_KRCR_S) ? 1 : 
0,
+              local_ability->link_ability & BIT(ABILITY_25GBASE_KRCR) ? 1 : 0);
+       BP_LOG("\t40GCR4 : %x\t40GKR4 : %x\n",
+              local_ability->link_ability & BIT(ABILITY_40GBASE_CR4) ? 1 : 0,
+              local_ability->link_ability & BIT(ABILITY_40GBASE_KR4) ? 1 : 0);
+       rdata = rd32_epcs(hw, SR_AN_MMD_ADV_REG3);
+       BP_LOG("\tF1:FEC Req\tF0:FEC Sup\tF3:25GFEC\tF2:25GRS\n");
+       BP_LOG("\tF1: %d\t\tF0: %d\t\tF3: %d\t\tF2: %d\n",
+             ((rdata >> 15) & 0x01), ((rdata >> 14) & 0x01),
+             ((rdata >> 13) & 0x01), ((rdata >> 12) & 0x01));
+       local_ability->fec_ability = rdata;
+       BP_LOG("\tread 70012 data %0x\n", rdata);
+
+       /* Read the link partner AN73 Base Page Ability Registers */
+       BP_LOG("Read the link partner Base Page Ability Registers\n");
+       rdata = rd32_epcs(hw, SR_AN_MMD_LP_ABL1);
+       lp_ability->next_page = (rdata & BIT(15)) ? 1 : 0;
+       BP_LOG("\tread 70013 data %0x\n", rdata);
+       rdata = rd32_epcs(hw, SR_AN_MMD_LP_ABL2);
+       lp_ability->link_ability = (rdata >> 5) & GENMASK(10, 0);
+       BP_LOG("\tread 70014 data %0x\n", rdata);
+       BP_LOG("\tKX : %x\tKX4 : %x\n",
+              lp_ability->link_ability & BIT(ABILITY_1000BASE_KX) ? 1 : 0,
+              lp_ability->link_ability & BIT(ABILITY_10GBASE_KX4) ? 1 : 0);
+       BP_LOG("\t10GKR : %x\t25GKR-S/CR-S: %x\t25GKR/CR : %x\n",
+              lp_ability->link_ability & BIT(ABILITY_10GBASE_KR) ? 1 : 0,
+              lp_ability->link_ability & BIT(ABILITY_25GBASE_KRCR_S) ? 1 : 0,
+              lp_ability->link_ability & BIT(ABILITY_25GBASE_KRCR) ? 1 : 0);
+       BP_LOG("\t40GCR4 : %x\t40GKR4 : %x\n",
+              lp_ability->link_ability & BIT(ABILITY_40GBASE_CR4) ? 1 : 0,
+              lp_ability->link_ability & BIT(ABILITY_40GBASE_KR4) ? 1 : 0);
+       rdata = rd32_epcs(hw, SR_AN_MMD_LP_ABL3);
+       BP_LOG("\tF1:FEC Req\tF0:FEC Sup\tF3:25GFEC\tF2:25GRS\n");
+       BP_LOG("\tF1: %d\t\tF0: %d\t\tF3: %d\t\tF2: %d\n",
+             ((rdata >> 15) & 0x01), ((rdata >> 14) & 0x01),
+             ((rdata >> 13) & 0x01), ((rdata >> 12) & 0x01));
+       lp_ability->fec_ability = rdata;
+
+       hw->phy.fec_mode = 0;
+       if (rdata & TXGBE_25G_RS_FEC_REQ)
+               hw->phy.fec_mode |= TXGBE_25G_RS_FEC_REQ;
+       if (rdata & TXGBE_25G_BASE_FEC_REQ)
+               hw->phy.fec_mode |= TXGBE_25G_BASE_FEC_REQ;
+       if (rdata & TXGBE_10G_FEC_ABL)
+               hw->phy.fec_mode |= TXGBE_10G_FEC_ABL;
+       if (rdata & TXGBE_10G_FEC_REQ)
+               hw->phy.fec_mode |= TXGBE_10G_FEC_REQ;
+       BP_LOG("\tread 70015 data %0x\n", rdata);
+
+       BP_LOG("\tread 70016 data %0x\n", rd32_epcs(hw, 0x70016));
+       BP_LOG("\tread 70017 data %0x\n", rd32_epcs(hw, 0x70017));
+       BP_LOG("\tread 70018 data %0x\n", rd32_epcs(hw, 0x70018));
+       BP_LOG("\tread 70019 data %0x\n", rd32_epcs(hw, 0x70019));
+       BP_LOG("\tread 7001a data %0x\n", rd32_epcs(hw, 0x7001a));
+       BP_LOG("\tread 7001b data %0x\n", rd32_epcs(hw, 0x7001b));
+}
+
+static int chk_bkp_ability(struct txgbe_hw *hw,
+       struct txgbe_backplane_ability local_ability,
+       struct txgbe_backplane_ability lp_ability)
+{
+       unsigned int com_link_ability;
+
+       BP_LOG("CheckBkpAn73Ability():\n");
+       /* Check the common link ability and take action based on the result*/
+       com_link_ability = local_ability.link_ability &
+                        lp_ability.link_ability;
+       BP_LOG("comAbility= 0x%x, Ability= 0x%x, lpAbility= 0x%x\n",
+               com_link_ability, local_ability.link_ability,
+               lp_ability.link_ability);
+
+       if (com_link_ability == 0) {
+               hw->bp_link_mode = 0;
+               BP_LOG("Do not support any compatible speed mode!\n");
+               return -EINVAL;
+       } else if (com_link_ability & BIT(ABILITY_40GBASE_KR4)) {
+               BP_LOG("Link mode is [ABILITY_40GBASE_KR4].\n");
+               hw->bp_link_mode = 40;
+       } else if (com_link_ability & BIT(ABILITY_40GBASE_CR4)) {
+               BP_LOG("Link mode is [ABILITY_40GBASE_CR4].\n");
+               hw->bp_link_mode = 40;
+       } else if (com_link_ability & BIT(ABILITY_25GBASE_KRCR_S)) {
+               BP_LOG("Link mode is [ABILITY_25GBASE_KRCR_S].\n");
+               hw->fec_mode = TXGBE_25G_RS_FEC_REQ;
+               hw->bp_link_mode = 25;
+       } else if (com_link_ability & BIT(ABILITY_25GBASE_KRCR)) {
+               BP_LOG("Link mode is [ABILITY_25GBASE_KRCR].\n");
+               hw->bp_link_mode = 25;
+       } else if (com_link_ability & BIT(ABILITY_10GBASE_KR)) {
+               BP_LOG("Link mode is [ABILITY_10GBASE_KR].\n");
+               hw->bp_link_mode = 10;
+       } else if (com_link_ability & BIT(ABILITY_10GBASE_KX4)) {
+               BP_LOG("Link mode is [ABILITY_10GBASE_KX4].\n");
+               hw->bp_link_mode = 10;
+       } else if (com_link_ability & BIT(ABILITY_1000BASE_KX)) {
+               BP_LOG("Link mode is [ABILITY_1000BASE_KX].\n");
+               hw->bp_link_mode = 1;
+       } else {
+               BP_LOG("No compatible link mode found!\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int txgbe_e56_exchange_page(struct txgbe_hw *hw)
+{
+       struct txgbe_backplane_ability local_ability = {0}, lp_ability = {0};
+       u32 an_int, base_page = 0;
+       int count = 0;
+
+       an_int = rd32_epcs(hw, 0x78002);
+       /* 500ms timeout */
+       if (!(an_int & VR_AN_INTR_PG_RCV))
+               return -EINVAL;
+
+       for (count = 0; count < 500; count++) {
+               u32 fsm = rd32_epcs(hw, 0x78010);
+               u32 rdata = rd32_epcs(hw, 0x78002);
+
+               BP_LOG("-----count----- %d - fsm: %x\n", count, fsm);
+               BP_LOG("read 78002 data %0x and clear pacv\n", rdata);
+               an_int = rdata;
+               set_fields_e56(&rdata, 2, 2, 0x0);
+               wr32_epcs(hw, 0x78002, rdata);
+               if (an_int & VR_AN_INTR_PG_RCV) {
+                       u32 addr;
+
+                       txgbe_e56_print_page_status(hw, &local_ability, 
&lp_ability);
+                       addr = base_page == 0 ? 0x70013 : 0x70019;
+                       rdata = rd32_epcs(hw, addr);
+                       if (rdata & BIT(14)) {
+                               if (rdata & BIT(15)) {
+                                       /* always set null message */
+                                       wr32_epcs(hw, 0x70016, 0x2001);
+                                       BP_LOG("write 70016 0x%0x\n",
+                                              0x2001);
+                               }
+                               base_page = 1;
+                       }
+               }
+               if ((fsm & 0x8) == 0x8) {
+                       hw->fsm = 0x8;
+                       goto check_ability;
+               }
+               usec_delay(100);
+       }
+
+check_ability:
+       return chk_bkp_ability(hw, local_ability, lp_ability);
+}
+
+static int txgbe_e56_cl72_trainning(struct txgbe_hw *hw)
+{
+       u32 bylinkmode = hw->bp_link_mode;
+       u8 bypass_ctle = hw->bypass_ctle;
+       int status = 0, temp_data = 0;
+       u32 lane_num = 0, lane_idx = 0;
+       u32 __rte_unused pmd_ctrl = 0, txffe = 0;
+       int ret = 0;
+       u32 rdata;
+
+       u8 pll_en_cfg = 0;
+       u8 pmd_mode = 0;
+
+       switch (bylinkmode) {
+       case 10:
+               bylinkmode = 10;
+               lane_num = 1;
+               pll_en_cfg = 3;
+               pmd_mode = 0;
+               break;
+       case 40:
+               bylinkmode = 40;
+               lane_num = 4;
+               pll_en_cfg = 0; /* pll_en_cfg : single link to 0 */
+               pmd_mode = 1; /* pmd mode : 1 - single link */
+               break;
+       case 25:
+               bylinkmode = 25;
+               lane_num = 1;
+               pll_en_cfg = 3;
+               pmd_mode = 0;
+               break;
+       default:
+               BP_LOG("%s %d :Invalid speed\n", __func__, __LINE__);
+               break;
+       }
+
+       BP_LOG("2.3 Wait %dG KR phy mode init ....\n", bylinkmode);
+       status = txgbe_set_phy_link_mode(hw, bylinkmode);
+
+       /* 13. set phy an status to 1 - AN_CFG[0]: 4-7 lane0-lane3 */
+       rdata = rd32_ephy(hw, 0x1434);
+       set_fields_e56(&rdata, 7, 4, GENMASK(lane_num - 1, 0));
+       wr32_ephy(hw, 0x1434, rdata);
+
+       /* 14 and 15. kr training: set BASER_PMD_CONTROL[0, 7] for lane0-4 */
+       rdata = rd32_ephy(hw, 0x1640);
+       set_fields_e56(&rdata, 7, 0, GENMASK(2 * lane_num - 1, 0));
+       wr32_ephy(hw, 0x1640, rdata);
+
+       /* 16. enable CMS and its internal PLL */
+       rdata = rd32_ephy(hw, 0x1400);
+       set_fields_e56(&rdata, 21, 20, pll_en_cfg);
+       set_fields_e56(&rdata, 19, 12, 0); /* tx/rx off */
+       set_fields_e56(&rdata, 8, 8, pmd_mode);
+       set_fields_e56(&rdata, 1, 1, 0x1); /* pmd en */
+       wr32_ephy(hw, 0x1400, rdata);
+
+       /* 17. tx enable PMD_CFG[0] */
+       rdata = rd32_ephy(hw, 0x1400);
+       set_fields_e56(&rdata, 15, 12, GENMASK(lane_num - 1, 0)); /* tx en */
+       wr32_ephy(hw, 0x1400, rdata);
+
+       /* 18 */
+       /* 19. rxs calibration and adaotation sequeence */
+       BP_LOG("2.4 Wait %dG RXS.... fsm: %x\n",
+              bylinkmode, rd32_epcs(hw, 0x78010));
+       status = txgbe_e56_phy_rxs_calib_adapt_seq(hw, bylinkmode, bypass_ctle);
+       ret |= status;
+       /* 20 */
+       BP_LOG("2.5 Wait %dG phy calibration.... fsm: %x\n",
+              bylinkmode, rd32_epcs(hw, 0x78010));
+       txgbe_e56_set_rxs_ufine_le_max(hw, bylinkmode);
+       status = txgbe_e56_get_temp(hw, &temp_data);
+       if (bylinkmode == 40)
+               status = txgbe_temp_track_seq_40g(hw, 
TXGBE_LINK_SPEED_40GB_FULL);
+       else
+               status = txgbe_e56_rxs_post_cdr_lock_temp_track_seq(hw, 
bylinkmode);
+       /* 21 */
+       BP_LOG("2.6 Wait %dG phy kr training check.... fsm: %x\n",
+              bylinkmode, rd32_epcs(hw, 0x78010));
+       status = kr_read_poll(rd32_ephy, rdata,
+                                 ((rdata & 0xe) & GENMASK(lane_num, 1)) ==
+                                 (0xe & GENMASK(lane_num, 1)), 100,
+                                  10000, hw, 0x163c);
+       pmd_ctrl = rd32_ephy(hw, 0x1644);
+       BP_LOG("KR TRAINNING CHECK = %x, %s. pmd_ctrl:%lx-%lx-%lx-%lx\n",
+              rdata, status ? "FAILED" : "SUCCESS",
+              FIELD_GET_M(GENMASK(3, 0), pmd_ctrl),
+              FIELD_GET_M(GENMASK(7, 4), pmd_ctrl),
+              FIELD_GET_M(GENMASK(11, 8), pmd_ctrl),
+              FIELD_GET_M(GENMASK(15, 12), pmd_ctrl));
+       ret |= status;
+       BP_LOG("before: %x-%x-%x-%x\n",
+              rd32_ephy(hw, 0x141c), rd32_ephy(hw, 0x1420),
+              rd32_ephy(hw, 0x1424), rd32_ephy(hw, 0x1428));
+
+       for (lane_idx = 0; lane_idx < lane_num; lane_idx++) {
+               txffe = rd32_ephy(hw, 0x828 + lane_idx * 0x100);
+               BP_LOG("after[%x]: %lx-%lx-%lx-%lx\n", lane_idx,
+                      FIELD_GET_M(GENMASK(6, 0), txffe),
+                      FIELD_GET_M(GENMASK(21, 16), txffe),
+                      FIELD_GET_M(GENMASK(29, 24), txffe),
+                      FIELD_GET_M(GENMASK(13, 8), txffe));
+       }
+
+       /* 22 */
+       BP_LOG("2.7 Wait %dG phy Rx adc.... fsm:%x\n",
+              bylinkmode, rd32_epcs(hw, 0x78010));
+       status = txgbe_e56_rxs_adc_adapt_seq(hw, bypass_ctle);
+
+       return ret;
+}
+
+int handle_e56_bkp_an73_flow(struct txgbe_hw *hw)
+{
+       int status = 0;
+       u32 rdata;
+
+       BP_LOG("2.1 Wait page changed ....\n");
+       status = txgbe_e56_exchange_page(hw);
+       if (status) {
+               BP_LOG("Exchange page failed\n");
+               return status;
+       }
+
+       BP_LOG("2.2 Wait page changed ..done..\n");
+       wr32_epcs(hw, 0x100ab, 0);
+       if (AN_TRAINNING_MODE) {
+               rdata = rd32_epcs(hw, 0x70000);
+               BP_LOG("read 0x70000 data %0x\n", rdata);
+               wr32_epcs(hw, 0x70000, 0);
+               BP_LOG("write 0x70000 0x%0x\n", 0);
+       }
+
+       rdata = rd32_epcs(hw, 0x78002);
+       BP_LOG("read 78002 data %0x and clear page int\n", rdata);
+       set_fields_e56(&rdata, 2, 2, 0x0);
+       wr32_epcs(hw, 0x78002, rdata);
+
+       /* dis phy tx/rx lane */
+       rdata = rd32_ephy(hw, 0x1400);
+       set_fields_e56(&rdata, 19, 16, 0x0);
+       set_fields_e56(&rdata, 15, 12, 0x0);
+       set_fields_e56(&rdata, 1, 1, 0x0);
+       wr32_ephy(hw, 0x1400, rdata);
+       BP_LOG("Ephy Write A: 0x%x, D: 0x%x\n", 0x1400, rdata);
+
+       /* wait rx/tx/cm powerdn_st */
+       status = kr_read_poll(rd32_ephy, rdata,
+                                  (rdata & GENMASK(3, 0)) == 0x9, 100,
+                                  2000, hw, 0x14d4);
+       BP_LOG("wait ctrl_fsm_cm_st = %x, %s.\n",
+              rdata, status ? "FAILED" : "SUCCESS");
+
+       if (hw->phy.fec_mode & TXGBE_25G_RS_FEC_REQ) {
+               wr32_epcs(hw, 0x180a3, 0x68c1);
+               wr32_epcs(hw, 0x180a4, 0x3321);
+               wr32_epcs(hw, 0x180a5, 0x973e);
+               wr32_epcs(hw, 0x180a6, 0xccde);
+
+               wr32_epcs(hw, 0x38018, 1024);
+               rdata = rd32_epcs(hw, 0x100c8);
+               set_fields_e56(&rdata, 2, 2, 1);
+               wr32_epcs(hw, 0x100c8, rdata);
+               BP_LOG("Advertised FEC modes : %s\n", "RS-FEC");
+               hw->cur_fec_link = TXGBE_PHY_FEC_RS;
+       } else if (hw->phy.fec_mode & TXGBE_25G_BASE_FEC_REQ) {
+               /* FEC: FC-FEC/BASE-R */
+               wr32_epcs(hw, 0x100ab, BIT(0));
+               BP_LOG("Epcs Write A: 0x%x,  D: 0x%x\n", 0x100ab, 1);
+               PMD_DRV_LOG(INFO, "Advertised FEC modes : %s", "25GBASE-R");
+               hw->cur_fec_link = TXGBE_PHY_FEC_BASER;
+       } else if (hw->fec_mode & (TXGBE_10G_FEC_REQ)) {
+               /* FEC: FC-FEC/BASE-R */
+               wr32_epcs(hw, 0x100ab, BIT(0));
+               BP_LOG("Epcs Write A: 0x%x,  D: 0x%x\n", 0x100ab, 1);
+               PMD_DRV_LOG(INFO, "Advertised FEC modes : %s", "BASE-R");
+               hw->cur_fec_link = TXGBE_PHY_FEC_BASER;
+       } else {
+               PMD_DRV_LOG(INFO, "Advertised FEC modes : %s", "NONE");
+               hw->cur_fec_link = TXGBE_PHY_FEC_OFF;
+       }
+
+       status = txgbe_e56_cl72_trainning(hw);
+
+       rdata = rd32_ephy(hw, E56PHY_RXS_IDLE_DETECT_1_ADDR);
+       set_fields_e56(&rdata, E56PHY_RXS_IDLE_DETECT_1_IDLE_TH_ADC_PEAK_MAX, 
0x28);
+       set_fields_e56(&rdata, E56PHY_RXS_IDLE_DETECT_1_IDLE_TH_ADC_PEAK_MIN, 
0xa);
+       wr32_ephy(hw, E56PHY_RXS_IDLE_DETECT_1_ADDR, rdata);
+       wr32_ephy(hw, E56PHY_INTR_0_ADDR, E56PHY_INTR_0_IDLE_ENTRY1);
+       wr32_ephy(hw, E56PHY_INTR_1_ADDR, E56PHY_INTR_1_IDLE_EXIT1);
+       wr32_ephy(hw, E56PHY_INTR_0_ENABLE_ADDR, E56PHY_INTR_0_IDLE_ENTRY1);
+       wr32_ephy(hw, E56PHY_INTR_1_ENABLE_ADDR, E56PHY_INTR_1_IDLE_EXIT1);
+
+       return status;
+}
diff --git a/drivers/net/txgbe/base/txgbe_e56_bp.h 
b/drivers/net/txgbe/base/txgbe_e56_bp.h
index c58c061ea1..3e08d68545 100644
--- a/drivers/net/txgbe/base/txgbe_e56_bp.h
+++ b/drivers/net/txgbe/base/txgbe_e56_bp.h
@@ -272,4 +272,7 @@ typedef union {
 #define E56PHY_CMS_ANA_OVRDVAL_10_ADDR   (E56PHY_CMS_BASE_ADDR + 0xD8)
 #define E56PHY_CMS_ANA_OVRDVAL_7_ANA_LCPLL_LF_LPF_SETCODE_CALIB_I      8, 4
 
+int txgbe_e56_set_phy_link_mode(struct txgbe_hw *hw,
+                               u8 bp_link_mode, u32 need_restart);
+int handle_e56_bkp_an73_flow(struct txgbe_hw *hw);
 #endif
diff --git a/drivers/net/txgbe/base/txgbe_hw.c 
b/drivers/net/txgbe/base/txgbe_hw.c
index 0c6a74c562..6d76b4854c 100644
--- a/drivers/net/txgbe/base/txgbe_hw.c
+++ b/drivers/net/txgbe/base/txgbe_hw.c
@@ -4071,6 +4071,12 @@ s32 txgbe_reset_pipeline_raptor(struct txgbe_hw *hw)
        return err;
 }
 
+bool txgbe_is_backplane(struct txgbe_hw *hw)
+{
+       return hw->phy.get_media_type(hw) == txgbe_media_type_backplane ?
+                                                true : false;
+}
+
 bool txgbe_gpio_ext_check(struct txgbe_hw *hw, u8 gpio_ext_mask)
 {
        u32 gpio_ext = rd32(hw, TXGBE_GPIOEXT);
diff --git a/drivers/net/txgbe/base/txgbe_hw.h 
b/drivers/net/txgbe/base/txgbe_hw.h
index bc34d639eb..b44190bc34 100644
--- a/drivers/net/txgbe/base/txgbe_hw.h
+++ b/drivers/net/txgbe/base/txgbe_hw.h
@@ -118,6 +118,6 @@ s32 txgbe_reinit_fdir_tables(struct txgbe_hw *hw);
 bool txgbe_verify_lesm_fw_enabled_raptor(struct txgbe_hw *hw);
 s32 txgbe_fmgr_cmd_op(struct txgbe_hw *hw, u32 cmd, u32 cmd_addr);
 s32 txgbe_flash_read_dword(struct txgbe_hw *hw, u32 addr, u32 *data);
-s32 txgbe_e56_check_phy_link(struct txgbe_hw *hw, u32 *speed,
-                               bool *link_up);
+bool txgbe_is_backplane(struct txgbe_hw *hw);
+bool txgbe_gpio_ext_check(struct txgbe_hw *hw, u8 gpio_ext_mask);
 #endif /* _TXGBE_HW_H_ */
diff --git a/drivers/net/txgbe/base/txgbe_osdep.h 
b/drivers/net/txgbe/base/txgbe_osdep.h
index f4282b3241..da069e94f6 100644
--- a/drivers/net/txgbe/base/txgbe_osdep.h
+++ b/drivers/net/txgbe/base/txgbe_osdep.h
@@ -162,6 +162,10 @@ static inline u64 REVERT_BIT_MASK64(u64 mask)
               ((mask & 0xFFFFFFFF00000000) >> 32);
 }
 
+#define BITS_PER_LONG  (__SIZEOF_LONG__ * 8)
+#define GENMASK(h, l) \
+       (((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
+
 #define IOMEM
 
 #define BIT(nr)         (1UL << (nr))
diff --git a/drivers/net/txgbe/base/txgbe_phy.c 
b/drivers/net/txgbe/base/txgbe_phy.c
index bf7260a295..f3e3491b30 100644
--- a/drivers/net/txgbe/base/txgbe_phy.c
+++ b/drivers/net/txgbe/base/txgbe_phy.c
@@ -2503,6 +2503,27 @@ void txgbe_set_phy_temp(struct txgbe_hw *hw)
        }
 }
 
+int txgbe_is_dac_cable(struct txgbe_hw *hw)
+{
+       if (hw->phy.sfp_type == txgbe_sfp_type_da_cu_core0 ||
+           hw->phy.sfp_type == txgbe_sfp_type_da_cu_core1 ||
+           hw->phy.sfp_type == txgbe_sfp_type_da_act_lmt_core0 ||
+           hw->phy.sfp_type == txgbe_sfp_type_da_act_lmt_core1 ||
+           hw->phy.sfp_type == txgbe_qsfp_type_40g_cu_core0 ||
+           hw->phy.sfp_type == txgbe_qsfp_type_40g_cu_core1)
+               return true;
+
+       return false;
+}
+
+int txgbe_xpcs_an_enabled(struct txgbe_hw *hw)
+{
+       if (!(txgbe_is_dac_cable(hw) || txgbe_is_backplane(hw)))
+               return false;
+
+       return hw->devarg.auto_neg ? true : false;
+}
+
 /**
  * txgbe_kr_handle - Handle the interrupt of auto-negotiation
  * @hw: pointer to hardware structure
diff --git a/drivers/net/txgbe/base/txgbe_phy.h 
b/drivers/net/txgbe/base/txgbe_phy.h
index c02be3cc34..3fe7a34409 100644
--- a/drivers/net/txgbe/base/txgbe_phy.h
+++ b/drivers/net/txgbe/base/txgbe_phy.h
@@ -105,6 +105,8 @@
 #define   VR_AN_INTR_CMPLT               MS16(0, 0x1)
 #define   VR_AN_INTR_LINK                MS16(1, 0x1)
 #define   VR_AN_INTR_PG_RCV              MS16(2, 0x1)
+#define   TXGBE_E56_AN_TXDIS              MS16(3, 0x1)
+#define   TXGBE_E56_AN_PG_RCV             MS16(4, 0x1)
 #define VR_AN_KR_MODE_CL                  0x078003
 #define   VR_AN_KR_MODE_CL_PDET                  MS16(0, 0x1)
 #define VR_XS_OR_PCS_MMD_DIGI_CTL1        0x038000
@@ -428,6 +430,24 @@
 #define TXGBE_BP_M_NAUTO                     0
 #define TXGBE_BP_M_AUTO                      1
 
+#define kr_read_poll(op, val, cond, sleep_us, \
+                    times, args...) \
+({ \
+       unsigned long __sleep_us = (sleep_us); \
+       u32 __times = (times); \
+       u32 i; \
+       int __cond = 0; \
+       for (i = 0; i < __times; i++) { \
+               (val) = op(args); \
+               if (cond) { \
+                       __cond = 1; \
+                       break; \
+               } \
+               usleep(__sleep_us);\
+       } \
+       (__cond) ? 0 : -1; \
+})
+
 #ifndef CL72_KRTR_PRBS_MODE_EN
 #define CL72_KRTR_PRBS_MODE_EN 0xFFFF  /* open kr prbs check */
 #endif
@@ -490,6 +510,8 @@ void txgbe_autoc_write(struct txgbe_hw *hw, u64 value);
 void txgbe_bp_mode_set(struct txgbe_hw *hw);
 void txgbe_set_phy_temp(struct txgbe_hw *hw);
 void txgbe_bp_down_event(struct txgbe_hw *hw);
+int txgbe_is_dac_cable(struct txgbe_hw *hw);
+int txgbe_xpcs_an_enabled(struct txgbe_hw *hw);
 s32 txgbe_kr_handle(struct txgbe_hw *hw);
 
 #endif /* _TXGBE_PHY_H_ */
diff --git a/drivers/net/txgbe/base/txgbe_type.h 
b/drivers/net/txgbe/base/txgbe_type.h
index 7fb4bcc513..47629aa9e0 100644
--- a/drivers/net/txgbe/base/txgbe_type.h
+++ b/drivers/net/txgbe/base/txgbe_type.h
@@ -719,6 +719,7 @@ struct txgbe_phy_info {
        u32 addr;
        u32 id;
        enum txgbe_sfp_type sfp_type;
+       u32 fiber_suppport_speed;
        bool sfp_setup_needed;
        u32 revision;
        u32 media_type;
@@ -740,6 +741,7 @@ struct txgbe_phy_info {
        u16 ffe_pre2;
        u16 ffe_post;
        u16 fec_mode;
+       u16 bp_capa;
 };
 
 #define TXGBE_DEVARG_BP_AUTO           "auto_neg"
@@ -899,7 +901,28 @@ struct txgbe_hw {
        u32 cur_fec_link;
        int temperature;
        u32 bp_link_mode;
-};
+       bool dac_sfp;
+       bool bypass_ctle;
+       u32 curbp_link_mode;
+       bool an_done;
+       u32 fsm;
+       u64 bp_event_interval;
+};
+
+typedef enum {
+       ABILITY_1000BASE_KX,
+       ABILITY_10GBASE_KX4,
+       ABILITY_10GBASE_KR,
+       ABILITY_40GBASE_KR4,
+       ABILITY_40GBASE_CR4,
+       ABILITY_100GBASE_CR10,
+       ABILITY_100GBASE_KP4,
+       ABILITY_100GBASE_KR4,
+       ABILITY_100GBASE_CR4,
+       ABILITY_25GBASE_KRCR_S,
+       ABILITY_25GBASE_KRCR,
+       ABILITY_MAX,
+} ability_filed_encding;
 
 struct txgbe_backplane_ability {
        u32 next_page;    /* Next Page (bit0) */
diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c
index 02c3305712..56987ae028 100644
--- a/drivers/net/txgbe/txgbe_ethdev.c
+++ b/drivers/net/txgbe/txgbe_ethdev.c
@@ -2010,6 +2010,10 @@ txgbe_dev_start(struct rte_eth_dev *dev)
        txgbe_l2_tunnel_conf(dev);
        txgbe_filter_restore(dev);
 
+       hw->bp_event_interval = 100 * 1000;
+       if (hw->mac.type == txgbe_mac_aml || hw->mac.type == txgbe_mac_aml40)
+               rte_eal_alarm_set(hw->bp_event_interval, 
txgbe_dev_e56_check_bp_event, dev);
+
        if (tm_conf->root && !tm_conf->committed)
                PMD_DRV_LOG(WARNING,
                            "please call hierarchy_commit() "
@@ -2054,8 +2058,10 @@ txgbe_dev_stop(struct rte_eth_dev *dev)
 
        PMD_INIT_FUNC_TRACE();
 
-       if (hw->mac.type == txgbe_mac_aml || hw->mac.type == txgbe_mac_aml40)
+       if (hw->mac.type == txgbe_mac_aml || hw->mac.type == txgbe_mac_aml40) {
+               rte_eal_alarm_cancel(txgbe_dev_e56_check_bp_event, dev);
                rte_eal_alarm_cancel(txgbe_dev_setup_link_alarm_handler_aml, 
hw);
+       }
 
        rte_eal_alarm_cancel(txgbe_dev_detect_sfp, dev);
        rte_eal_alarm_cancel(txgbe_tx_queue_clear_error, dev);
@@ -2926,6 +2932,107 @@ txgbe_dev_supported_ptypes_get(struct rte_eth_dev *dev, 
size_t *no_of_elements)
        return NULL;
 }
 
+void txgbe_dev_e56_check_bp_event(void *param)
+{
+       struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
+       struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
+       u32 an_int1 = 0, value = 0, fsm = 0;
+       u32 __rte_unused an_int = 0;
+       int ret = 0;
+       bool need_link_update = false;
+
+       if (!hw)
+               return;
+
+       if (!(txgbe_xpcs_an_enabled(hw)))
+               return;
+
+       if (!hw->devarg.auto_neg)
+               return;
+
+       /* only continue if link is down */
+       if (dev->data->dev_link.link_status)
+               goto out;
+
+       value = rd32_epcs(hw, VR_AN_INTR);
+       an_int = value;
+       if (value & 0xF)
+               hw->bp_event_interval = 100 * 1000;
+
+       if (value & VR_AN_INTR_CMPLT) {
+               hw->an_done = true;
+               need_link_update = true;
+               value &= ~VR_AN_INTR_CMPLT;
+               wr32_epcs(hw, VR_AN_INTR, value);
+       }
+
+       if (value & VR_AN_INTR_LINK) {
+               value &= ~VR_AN_INTR_LINK;
+               wr32_epcs(hw, VR_AN_INTR, value);
+       }
+
+       if (value & TXGBE_E56_AN_TXDIS) {
+               value &= ~TXGBE_E56_AN_TXDIS;
+               wr32_epcs(hw, VR_AN_INTR, value);
+               rte_spinlock_lock(&hw->phy_lock);
+               txgbe_e56_set_phy_link_mode(hw, 10, hw->bypass_ctle);
+               rte_spinlock_unlock(&hw->phy_lock);
+               goto an_status;
+       }
+
+       if (value & VR_AN_INTR_PG_RCV) {
+               BP_LOG("%d Enter training\n", hw->port_id);
+               ret = handle_e56_bkp_an73_flow(hw);
+               if (!AN_TRAINNING_MODE) {
+                       fsm = rd32_epcs(hw, 0x78010);
+                       if (fsm & 0x8)
+                               goto an_status;
+                       if (ret) {
+                               BP_LOG("Training FAILED, do reset\n");
+                               rte_spinlock_lock(&hw->phy_lock);
+                               txgbe_e56_set_phy_link_mode(hw, 10, 
hw->bypass_ctle);
+                               rte_spinlock_unlock(&hw->phy_lock);
+                       } else {
+                               BP_LOG("ALL SUCCEEDED\n");
+                       }
+               } else {
+                       if (ret) {
+                               BP_LOG("Training FAILED, do reset\n");
+                               rte_spinlock_lock(&hw->phy_lock);
+                               txgbe_e56_set_phy_link_mode(hw, 10, 
hw->bypass_ctle);
+                               rte_spinlock_unlock(&hw->phy_lock);
+                       } else {
+                               hw->an_done = true;
+                       }
+               }
+       }
+
+an_status:
+       an_int1 = rd32_epcs(hw, 0x78002);
+       if (an_int1 & VR_AN_INTR_CMPLT) {
+               hw->an_done = true;
+               need_link_update = true;
+       }
+
+       BP_LOG("%d RLU:%x MLU:%x INT:%x-%x CTL:%x fsm:%x pmd_cfg0:%x 
an_done:%d\n",
+               hw->port_id, rd32_epcs(hw, 0x30001), rd32(hw, 0x14404),
+               an_int, an_int1,
+               rd32_epcs(hw, 0x70000),
+               rd32_epcs(hw, 0x78010),
+               rd32_ephy(hw, 0x1400),
+               hw->an_done);
+
+       if (need_link_update)
+               txgbe_dev_link_update(dev, 0);
+
+       if (dev->data->dev_link.link_status)
+               hw->bp_event_interval = 2000 * 1000;
+
+out:
+       if (hw->mac.type == txgbe_mac_aml || hw->mac.type == txgbe_mac_aml40)
+               rte_eal_alarm_set(hw->bp_event_interval, 
txgbe_dev_e56_check_bp_event, dev);
+}
+
 static void
 txgbe_dev_detect_sfp(void *param)
 {
diff --git a/drivers/net/txgbe/txgbe_ethdev.h b/drivers/net/txgbe/txgbe_ethdev.h
index 1ec8e096cc..309db3bfe9 100644
--- a/drivers/net/txgbe/txgbe_ethdev.h
+++ b/drivers/net/txgbe/txgbe_ethdev.h
@@ -747,5 +747,5 @@ void txgbe_vlan_hw_strip_bitmap_set(struct rte_eth_dev *dev,
                uint16_t queue, bool on);
 void txgbe_config_vlan_strip_on_all_queues(struct rte_eth_dev *dev,
                                                  int mask);
-
+void txgbe_dev_e56_check_bp_event(void *param);
 #endif /* _TXGBE_ETHDEV_H_ */
-- 
2.21.0.windows.1

Reply via email to