mirror of
git://nv-tegra.nvidia.com/kernel/nvethernetrm.git
synced 2025-12-22 09:12:10 +03:00
osi: Add RX_EQ training via SW override method
Add RX_EQ training after mgbe link up to overcome insertion loss Bug 5277708 Bug 5017313 Change-Id: I19270c68cc570b3320c1db24298439cfbf412170 Signed-off-by: Revanth Kumar Uppala <ruppala@nvidia.com> (cherry picked from commit ac35e507b220de89de9d856e2ba0cdae59656b1f) Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/3383664 Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Narayana Reddy P <narayanr@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: svcacv <svcacv@nvidia.com>
This commit is contained in:
committed by
Amulya Yarlagadda
parent
53c6e3ffc4
commit
8a43cf10fb
@@ -776,6 +776,16 @@ typedef my_lint_64 nvel64_t;
|
||||
/** @} */
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @addtogroup RX EQ related information
|
||||
*
|
||||
* @brief RX EQ Software override
|
||||
* @{
|
||||
*/
|
||||
/** @brief RX EQ Software override is enabled */
|
||||
#define OSI_RX_EQ_SW_OVRD 1U
|
||||
/** @} */
|
||||
|
||||
struct osi_core_priv_data;
|
||||
|
||||
/**
|
||||
@@ -1892,6 +1902,8 @@ struct osi_core_priv_data {
|
||||
nveu32_t skip_usxgmii_an;
|
||||
/** MAC common interrupt received */
|
||||
nveu32_t mac_common_intr_rcvd;
|
||||
/** Flag to enable pcs RX EQ SW override logic */
|
||||
nveu32_t pcs_rx_eq_sw_ovrd_en;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -613,15 +613,18 @@ static inline nveu64_t osi_update_stats_counter(nveu64_t last_value,
|
||||
*/
|
||||
#define RETRY_COUNT 1000U
|
||||
#define RETRY_DELAY 1U
|
||||
#define OSI_DELAY_2US 2U
|
||||
#define OSI_DELAY_4US 4U
|
||||
#define OSI_DELAY_10US 10U
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
#define OSI_DELAY_100US 100U
|
||||
#endif
|
||||
#define OSI_DELAY_200US 200U
|
||||
#define OSI_DELAY_500US 500U
|
||||
#define OSI_DELAY_1000US 1000U
|
||||
#define OSI_DELAY_10000US 10000U
|
||||
#define OSI_DELAY_30000US 30000U
|
||||
#define OSI_DELAY_1000000US 1000000U
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
137
osi/core/xpcs.c
137
osi/core/xpcs.c
@@ -575,6 +575,136 @@ fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief xpcs_rx_eq_sw_override - Execute RX EQ training
|
||||
*
|
||||
* Algorithm: This routine executes RX EQ training through
|
||||
* sw override method.
|
||||
*
|
||||
* @param[in] osi_core: OSI core data structure.
|
||||
*
|
||||
* @retval 0 on success
|
||||
* @retval -1 on failure.
|
||||
*/
|
||||
nve32_t xpcs_rx_eq_sw_override(struct osi_core_priv_data *osi_core)
|
||||
{
|
||||
nveu32_t val = 0;
|
||||
nve32_t ret = 0;
|
||||
nveu32_t count;
|
||||
nve32_t cond;
|
||||
nveu32_t rx_eq_retry = RETRY_COUNT;
|
||||
|
||||
osi_writela(osi_core, XPCS_WRAP_UPHY_RX_CTRL_12_0_SLEEP_DLY,
|
||||
(nveu8_t *)osi_core->xpcs_base +
|
||||
T26X_XPCS_WRAP_UPHY_RX_CTRL_12_0);
|
||||
|
||||
val = osi_readla(osi_core,
|
||||
(nveu8_t *)osi_core->xpcs_base +
|
||||
T26X_XPCS_WRAP_UPHY_RX_CTRL_12_0);
|
||||
if (val != XPCS_WRAP_UPHY_RX_CTRL_12_0_SLEEP_DLY) {
|
||||
ret = -1;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
val = osi_readla(osi_core,
|
||||
(nveu8_t *)osi_core->xpcs_base +
|
||||
T26X_XPCS_WRAP_UPHY_RX_CTRL_0_0);
|
||||
|
||||
val |= XPCS_WRAP_UPHY_RX_CTRL_0_0_PRE_RX_EQ_MASK_1;
|
||||
|
||||
val &= ~(XPCS_WRAP_UPHY_RX_CTRL_0_0_PRE_RX_EQ_MASK_2);
|
||||
|
||||
osi_writela(osi_core, val,
|
||||
(nveu8_t *)osi_core->xpcs_base +
|
||||
T26X_XPCS_WRAP_UPHY_RX_CTRL_0_0);
|
||||
|
||||
val = osi_readla(osi_core,
|
||||
(nveu8_t *)osi_core->xpcs_base +
|
||||
T26X_XPCS_WRAP_UPHY_RX_CTRL_0_0);
|
||||
/* Enable RX_SW_OVRD */
|
||||
val |= XPCS_WRAP_UPHY_RX_CTRL_0_0_RX_SW_OVRD;
|
||||
osi_writela(osi_core, val,
|
||||
(nveu8_t *)osi_core->xpcs_base +
|
||||
T26X_XPCS_WRAP_UPHY_RX_CTRL_0_0);
|
||||
|
||||
/* wait 1 second */
|
||||
osi_core->osd_ops.usleep(OSI_DELAY_1000000US);
|
||||
|
||||
val = osi_readla(osi_core,
|
||||
(nveu8_t *)osi_core->xpcs_base +
|
||||
T26X_XPCS_WRAP_UPHY_RX_CTRL_0_0);
|
||||
/* RX_EQ_RESET */
|
||||
val |= XPCS_WRAP_UPHY_RX_CTRL_0_0_RX_EQ_RESET;
|
||||
osi_writela(osi_core, val,
|
||||
(nveu8_t *)osi_core->xpcs_base +
|
||||
T26X_XPCS_WRAP_UPHY_RX_CTRL_0_0);
|
||||
|
||||
cond = COND_NOT_MET;
|
||||
count = 0;
|
||||
while (cond == COND_NOT_MET) {
|
||||
val = osi_readla(osi_core,
|
||||
(nveu8_t *)osi_core->xpcs_base +
|
||||
T26X_XPCS_WRAP_UPHY_RX_CTRL_0_0);
|
||||
|
||||
if ((val & XPCS_WRAP_UPHY_RX_CTRL_0_0_RX_EQ_RESET) != 0) {
|
||||
if (count > rx_eq_retry) {
|
||||
ret = -1;
|
||||
OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_HW_FAIL,
|
||||
"RX_EQ_RESET failed\n", 0ULL);
|
||||
goto fail; // RX_EQ_RESET failed
|
||||
}
|
||||
count++;
|
||||
osi_core->osd_ops.udelay(OSI_DELAY_2US);
|
||||
} else {
|
||||
cond = COND_MET;
|
||||
}
|
||||
}
|
||||
|
||||
/* wait 1 second */
|
||||
osi_core->osd_ops.usleep(OSI_DELAY_1000000US);
|
||||
|
||||
/* RX_EQ_TRAIN_EN */
|
||||
val |= XPCS_WRAP_UPHY_RX_CTRL_0_0_RX_EQ_TRAIN_EN;
|
||||
osi_writela(osi_core, val,
|
||||
(nveu8_t *)osi_core->xpcs_base +
|
||||
T26X_XPCS_WRAP_UPHY_RX_CTRL_0_0);
|
||||
|
||||
/* Poll until bit 11 clears or timeout */
|
||||
|
||||
cond = COND_NOT_MET;
|
||||
count = 0;
|
||||
while (cond == COND_NOT_MET) {
|
||||
val = osi_readla(osi_core,
|
||||
(nveu8_t *)osi_core->xpcs_base +
|
||||
T26X_XPCS_WRAP_UPHY_RX_CTRL_0_0);
|
||||
|
||||
if ((val & XPCS_WRAP_UPHY_RX_CTRL_0_0_RX_EQ_TRAIN_EN) != 0) {
|
||||
if (count > rx_eq_retry) {
|
||||
ret = -1;
|
||||
OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_HW_FAIL,
|
||||
"RX_EQ_TRAIN_EN failed\n", 0ULL);
|
||||
goto fail; // RX_EQ_TRAIN_EN failed
|
||||
}
|
||||
count++;
|
||||
osi_core->osd_ops.usleep(OSI_DELAY_500US);
|
||||
} else {
|
||||
cond = COND_MET;
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable RX_SW_OVRD */
|
||||
val &= ~XPCS_WRAP_UPHY_RX_CTRL_0_0_RX_SW_OVRD;
|
||||
osi_writela(osi_core, val,
|
||||
(nveu8_t *)osi_core->xpcs_base +
|
||||
T26X_XPCS_WRAP_UPHY_RX_CTRL_0_0);
|
||||
|
||||
/* wait 2 micro seconds */
|
||||
osi_core->osd_ops.udelay(OSI_DELAY_2US);
|
||||
|
||||
fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief xpcs_lane_bring_up - Bring up UPHY Tx/Rx lanes
|
||||
*
|
||||
@@ -769,6 +899,13 @@ step10:
|
||||
OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_HW_FAIL,
|
||||
"PCS block lock SUCCESS\n", 0ULL);
|
||||
}
|
||||
|
||||
if (osi_core->pcs_rx_eq_sw_ovrd_en == OSI_RX_EQ_SW_OVRD) {
|
||||
if (xpcs_rx_eq_sw_override(osi_core)) {
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -71,6 +71,8 @@
|
||||
#define T26X_XPCS_WRAP_UPHY_RX_CTRL_2 0x8040
|
||||
#define T26X_XPCS_WRAP_UPHY_RX_CTRL_3 0x8044
|
||||
#define T26X_XPCS_WRAP_UPHY_TIMEOUT_CONTROL_0_0 0x8070
|
||||
#define T26X_XPCS_WRAP_UPHY_RX_CTRL_0_0 0x8034
|
||||
#define T26X_XPCS_WRAP_UPHY_RX_CTRL_12_0 0x8058
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -195,6 +197,13 @@
|
||||
#define XPCS_SR_PMA_KR_FEC_CTRL_FEC_EN OSI_BIT(0)
|
||||
#define XPCS_SR_PMA_KR_FEC_CTRL_EN_ERR_IND OSI_BIT(1)
|
||||
|
||||
#define XPCS_WRAP_UPHY_RX_CTRL_0_0_PRE_RX_EQ_MASK_1 OSI_BIT(0) | OSI_BIT(10)
|
||||
#define XPCS_WRAP_UPHY_RX_CTRL_0_0_PRE_RX_EQ_MASK_2 OSI_BIT(4) | OSI_BIT(5) | OSI_BIT(6) | OSI_BIT(7)
|
||||
#define XPCS_WRAP_UPHY_RX_CTRL_0_0_RX_EQ_TRAIN_EN OSI_BIT(11)
|
||||
#define XPCS_WRAP_UPHY_RX_CTRL_0_0_RX_EQ_RESET OSI_BIT(12)
|
||||
#define XPCS_WRAP_UPHY_RX_CTRL_0_0_RX_SW_OVRD OSI_BIT(31)
|
||||
#define XPCS_WRAP_UPHY_RX_CTRL_12_0_SLEEP_DLY 0x200U
|
||||
|
||||
#ifdef HSI_SUPPORT
|
||||
#define XPCS_WRAP_INTERRUPT_CONTROL 0x8048
|
||||
#define T26X_XPCS_WRAP_INTERRUPT_CONTROL 0x8084
|
||||
@@ -327,4 +336,31 @@ static inline nve32_t xpcs_write_safety(struct osi_core_priv_data *osi_core,
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Description: Execute RX EQ training through SW Override method.
|
||||
*
|
||||
* @param[in] osi_core: A pointer to the osi_core_priv_data structure
|
||||
* * Range: A non-null pointer to NVETHERNETRM_PIF$osi_core_priv_data structure.
|
||||
* * Refer NVETHERNETRM_PIF$osi_core_priv_data
|
||||
*
|
||||
* @usage
|
||||
* - Allowed context for the API call
|
||||
* - Interrupt handler: No
|
||||
* - Signal handler: No
|
||||
* - Thread safe: No
|
||||
* - Async/Sync: Sync
|
||||
* - Required Privileges: None
|
||||
* - API Group:
|
||||
* - Initialization: Yes
|
||||
* - Run time: No
|
||||
* - De-initialization: No
|
||||
*
|
||||
* @return
|
||||
* 0 on success
|
||||
* -1 on failure
|
||||
*
|
||||
*/
|
||||
nve32_t xpcs_rx_eq_sw_override(struct osi_core_priv_data *osi_core);
|
||||
#endif /* INCLUDED_XPCS_H_ */
|
||||
|
||||
Reference in New Issue
Block a user