mv88e6352_pcs_link_check() ignores errors returned by
port_get_cmode(). If the port status register read fails,
mv88e6352_port_get_cmode() returns without setting cmode. The link check
then compares an uninitialized value and may incorrectly treat the PCS
as active.
Save the return value and fail the link check after releasing the
register lock. marvell_c22_pcs_get_state() initializes the reported link
state to down before calling the check, so a read failure is handled
safely until a later poll succeeds.
This issue was found by a static analysis checker and confirmed by manual
source review.
Fixes: 85764555442f ("net: dsa: mv88e6xxx: convert 88e6352 to phylink_pcs")
Signed-off-by: Ruoyu Wang <redacted>
---
drivers/net/dsa/mv88e6xxx/pcs-6352.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/dsa/mv88e6xxx/pcs-6352.c b/drivers/net/dsa/mv88e6xxx/pcs-6352.c
index 4228ae5bb9db0f..437054711a2d8b 100644
--- a/drivers/net/dsa/mv88e6xxx/pcs-6352.c
+++ b/drivers/net/dsa/mv88e6xxx/pcs-6352.c
@@ -305,13 +305,16 @@ static bool mv88e6352_pcs_link_check(struct marvell_c22_pcs *mpcs)
struct mv88e6xxx_port *port = mpcs->port;
struct mv88e6xxx_chip *chip = port->chip;
u8 cmode;
+ int err;
/* Port 4 can be in auto-media mode. Check that the port is
* associated with the mpcs.
*/
mv88e6xxx_reg_lock(chip);
- chip->info->ops->port_get_cmode(chip, port->port, &cmode);
+ err = chip->info->ops->port_get_cmode(chip, port->port, &cmode);
mv88e6xxx_reg_unlock(chip);
+ if (err)
+ return false;
return cmode == MV88E6XXX_PORT_STS_CMODE_100BASEX ||
cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
--
2.51.0