From 4bd0875b7e571eeeed45fdab52672b850c1845a5 Mon Sep 17 00:00:00 2001 From: Can Guo Date: Thu, 25 Jun 2026 05:13:04 -0700 Subject: [PATCH] scsi: ufs: core: Tolerate RX_FOM read failures in TX EQTR ufshcd_get_rx_fom() aborted TX EQTR when a per-lane RX_FOM DME read failed. That makes the whole training flow fragile even though these reads can be treated as best effort. Keep TX EQTR running by logging RX_FOM read failures and continuing. Make failed lanes deterministic by initializing each lane FOM to 0 before reading and only updating it when the DME read succeeds. This avoids propagating stale or uninitialized values into EQTR evaluation. Also update the kerneldoc return description to match behavior: RX_FOM DME read failures are handled as warnings, while get_rx_fom() vops failures are still propagated to the caller. Signed-off-by: Can Guo Reviewed-by: Peter Wang Reviewed-by: Bean Huo Reviewed-by: Ziqi Chen Link: https://patch.msgid.link/20260625121306.1655467-3-can.guo@oss.qualcomm.com Signed-off-by: Martin K. Petersen --- drivers/ufs/core/ufs-txeq.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/ufs/core/ufs-txeq.c b/drivers/ufs/core/ufs-txeq.c index a083094a0465..dda1079540f9 100644 --- a/drivers/ufs/core/ufs-txeq.c +++ b/drivers/ufs/core/ufs-txeq.c @@ -482,7 +482,8 @@ static void ufshcd_evaluate_tx_eqtr_fom(struct ufs_hba *hba, * @h_iter: host TX EQTR iterator data structure * @d_iter: device TX EQTR iterator data structure * - * Returns 0 on success, negative error code otherwise + * Returns 0 on success, negative error code if get_rx_fom vops fails. + * RX_FOM DME get failures are logged and treated as 0 FOM for that lane. */ static int ufshcd_get_rx_fom(struct ufs_hba *hba, struct ufs_pa_layer_attr *pwr_mode, @@ -497,8 +498,12 @@ static int ufshcd_get_rx_fom(struct ufs_hba *hba, ret = ufshcd_dme_peer_get(hba, UIC_ARG_MIB_SEL(RX_FOM, UIC_ARG_MPHY_RX_GEN_SEL_INDEX(lane)), &fom); - if (ret) - return ret; + if (ret) { + h_iter->fom[lane] = 0; + dev_dbg(hba->dev, "Failed to get FOM for Host TX Lane %d: %d\n", + lane, ret); + continue; + } h_iter->fom[lane] = (u8)fom; } @@ -508,8 +513,12 @@ static int ufshcd_get_rx_fom(struct ufs_hba *hba, ret = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(RX_FOM, UIC_ARG_MPHY_RX_GEN_SEL_INDEX(lane)), &fom); - if (ret) - return ret; + if (ret) { + d_iter->fom[lane] = 0; + dev_dbg(hba->dev, "Failed to get FOM for Device TX Lane %d: %d\n", + lane, ret); + continue; + } d_iter->fom[lane] = (u8)fom; }