Message ID | E1tVuFh-000BXQ-D7@rmk-PC.armlinux.org.uk (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | net: phylink: fix PCS without autoneg | expand |
On Thu, Jan 09, 2025 at 03:15:17PM +0000, Russell King (Oracle) wrote: > As in-band AN no longer just depends on MLO_AN_INBAND + Autoneg bit, > we need to take account of the pcs_neg_mode when deciding how to > initialise the speed, duplex and pause state members before calling > into the .pcs_neg_mode() method. Add this. > > Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> > --- > drivers/net/phy/phylink.c | 22 ++++++++++++++++------ > 1 file changed, 16 insertions(+), 6 deletions(-) > > diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c > index 31754d5fd659..d08cdbbbbc1e 100644 > --- a/drivers/net/phy/phylink.c > +++ b/drivers/net/phy/phylink.c > @@ -1492,12 +1492,24 @@ static int phylink_change_inband_advert(struct phylink *pl) > static void phylink_mac_pcs_get_state(struct phylink *pl, > struct phylink_link_state *state) > { > + struct phylink_pcs *pcs; > + bool autoneg; > + > linkmode_copy(state->advertising, pl->link_config.advertising); > linkmode_zero(state->lp_advertising); > state->interface = pl->link_config.interface; > state->rate_matching = pl->link_config.rate_matching; > - if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, > - state->advertising)) { > + state->an_complete = 0; > + state->link = 1; > + > + pcs = pl->pcs; > + if (pcs->neg_mode) > + autoneg = pl->pcs_neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED; > + else > + autoneg = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, > + state->advertising); > + > + if (autoneg) { > state->speed = SPEED_UNKNOWN; > state->duplex = DUPLEX_UNKNOWN; > state->pause = MLO_PAUSE_NONE; > @@ -1506,11 +1518,9 @@ static void phylink_mac_pcs_get_state(struct phylink *pl, > state->duplex = pl->link_config.duplex; > state->pause = pl->link_config.pause; > } > - state->an_complete = 0; > - state->link = 1; > > - if (pl->pcs) > - pl->pcs->ops->pcs_get_state(pl->pcs, state); > + if (pcs) > + pcs->ops->pcs_get_state(pcs, state); > else > state->link = 0; Hi Russell, Here it is assumed that pcs may be NULL. But it is dereferenced unconditionally immediately after it is assigned above. This seems inconsistent. Flagged by Smatch. > } > -- > 2.30.2 > >
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index 31754d5fd659..d08cdbbbbc1e 100644 --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c @@ -1492,12 +1492,24 @@ static int phylink_change_inband_advert(struct phylink *pl) static void phylink_mac_pcs_get_state(struct phylink *pl, struct phylink_link_state *state) { + struct phylink_pcs *pcs; + bool autoneg; + linkmode_copy(state->advertising, pl->link_config.advertising); linkmode_zero(state->lp_advertising); state->interface = pl->link_config.interface; state->rate_matching = pl->link_config.rate_matching; - if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, - state->advertising)) { + state->an_complete = 0; + state->link = 1; + + pcs = pl->pcs; + if (pcs->neg_mode) + autoneg = pl->pcs_neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED; + else + autoneg = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, + state->advertising); + + if (autoneg) { state->speed = SPEED_UNKNOWN; state->duplex = DUPLEX_UNKNOWN; state->pause = MLO_PAUSE_NONE; @@ -1506,11 +1518,9 @@ static void phylink_mac_pcs_get_state(struct phylink *pl, state->duplex = pl->link_config.duplex; state->pause = pl->link_config.pause; } - state->an_complete = 0; - state->link = 1; - if (pl->pcs) - pl->pcs->ops->pcs_get_state(pl->pcs, state); + if (pcs) + pcs->ops->pcs_get_state(pcs, state); else state->link = 0; }
As in-band AN no longer just depends on MLO_AN_INBAND + Autoneg bit, we need to take account of the pcs_neg_mode when deciding how to initialise the speed, duplex and pause state members before calling into the .pcs_neg_mode() method. Add this. Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> --- drivers/net/phy/phylink.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-)