Coverity reports multiple issues (INTEGER_OVERFLOW and BAD_SHIFT)
in the e56 backplane code. The root cause is that 'lane_num' is
initialized to 0 and only set in the switch statement based on
the link speed. The default case simply logs and breaks, leaving
lane_num as 0 for unsupported speeds.

This leads to unsigned underflow when evaluating 'lane_num - 1'
in GENMASK(lane_num - 1, 0), and undefined behavior when the
resulting mask is used in shift operations.

Fix by returning -EINVAL immediately in the default case of
txgbe_e56_cl72_training(), preventing any invalid speed from
proceeding further. Also add error handling at the call site
txgbe_handle_e56_bkp_an73_flow() to check the return value and
propagate the error.

For txgbe_e56_rxs_osc_init_for_temp_track_range(), no additional
check is added because:
1. It is called from txgbe_e56_cl72_training() after lane_num
   has been validated to one of the legal values (1, 2, 4, or 8).
2. The other caller, txgbe_e56_set_phy_link_mode(), passes a
   fixed speed of 10 (lane_num = 1), which is also valid.

Coverity issue: 504598, 504602, 504613
Fixes: 234ce0d1fa9d ("net/txgbe: fix link stability for Amber-Lite backplane 
mode")
Cc: [email protected]

Signed-off-by: Zaiyu Wang <[email protected]>
---
 drivers/net/txgbe/base/txgbe_e56_bp.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/txgbe/base/txgbe_e56_bp.c 
b/drivers/net/txgbe/base/txgbe_e56_bp.c
index f8b39a0c7e..d376d918df 100644
--- a/drivers/net/txgbe/base/txgbe_e56_bp.c
+++ b/drivers/net/txgbe/base/txgbe_e56_bp.c
@@ -2432,7 +2432,7 @@ static int txgbe_e56_cl72_training(struct txgbe_hw *hw)
                break;
        default:
                BP_LOG("%s %d :Invalid speed\n", __func__, __LINE__);
-               break;
+               return -EINVAL;
        }
 
        BP_LOG("2.3 Wait %dG KR phy mode init ....\n", bylinkmode);
@@ -2583,6 +2583,10 @@ int txgbe_handle_e56_bkp_an73_flow(struct txgbe_hw *hw)
        }
 
        status = txgbe_e56_cl72_training(hw);
+       if (status) {
+               BP_LOG("CL72 training failed, status = %d\n", status);
+               return status;
+       }
 
        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);
-- 
2.21.0.windows.1

Reply via email to