net: pcs: xpcs: correct lp_advertising contents
authorRussell King (Oracle) <rmk+kernel@armlinux.org.uk>
Tue, 23 May 2023 10:16:13 +0000 (11:16 +0100)
committerJakub Kicinski <kuba@kernel.org>
Wed, 24 May 2023 16:13:22 +0000 (09:13 -0700)
lp_advertising is supposed to reflect the link partner's advertisement
unmodified by the local advertisement, but xpcs bitwise ands it with
the local advertisement prior to calculating the resolution of the
negotiation.

Fix this by moving the bitwise and to xpcs_resolve_lpa_c73() so it can
place the results in a temporary bitmap before passing that to
ixpcs_get_max_usxgmii_speed().

Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/pcs/pcs-xpcs.c

index 2165859a063cf2551c6c13e9891d870afd49c326..90920a7ba136a5b56b4b415c38559ca1610ac350 100644 (file)
@@ -531,18 +531,19 @@ static int xpcs_read_lpa_c73(struct dw_xpcs *xpcs,
 
        mii_c73_mod_linkmode(state->lp_advertising, lpa);
 
-       linkmode_and(state->lp_advertising, state->lp_advertising,
-                    state->advertising);
        return 0;
 }
 
 static void xpcs_resolve_lpa_c73(struct dw_xpcs *xpcs,
                                 struct phylink_link_state *state)
 {
-       int max_speed = xpcs_get_max_usxgmii_speed(state->lp_advertising);
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(res);
+
+       /* Calculate the union of the advertising masks */
+       linkmode_and(res, state->lp_advertising, state->advertising);
 
        state->pause = MLO_PAUSE_TX | MLO_PAUSE_RX;
-       state->speed = max_speed;
+       state->speed = xpcs_get_max_usxgmii_speed(res);
        state->duplex = DUPLEX_FULL;
 }