Commit e432ffc1 authored by Russell King (Oracle)'s avatar Russell King (Oracle) Committed by Jakub Kicinski
Browse files

net: phylink: provide fixed state for 1000base-X and 2500base-X



When decoding clause 22 state, if in-band is disabled and using either
1000base-X or 2500base-X, rather than reporting link-down, we know the
speed, and we only support full duplex. Pause modes taken from XPCS.

This fixes a problem reported by Eric Woudstra.

Signed-off-by: default avatarRussell King (Oracle) <rmk+kernel@armlinux.org.uk>
Reviewed-by: default avatarMaxime Chevallier <maxime.chevallier@bootlin.com>
Tested-by: default avatarMaxime Chevallier <maxime.chevallier@bootlin.com>
Link: https://patch.msgid.link/E1tXGei-000EtL-Fn@rmk-PC.armlinux.org.uk


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 60a331ff
Loading
Loading
Loading
Loading
+19 −10
Original line number Diff line number Diff line
@@ -3882,26 +3882,35 @@ void phylink_mii_c22_pcs_decode_state(struct phylink_link_state *state,
	if (!state->link)
		return;

	/* If in-band is disabled, then the advertisement data is not
	 * meaningful.
	 */
	if (neg_mode != PHYLINK_PCS_NEG_INBAND_ENABLED)
		return;

	switch (state->interface) {
	case PHY_INTERFACE_MODE_1000BASEX:
		if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
			phylink_decode_c37_word(state, lpa, SPEED_1000);
		} else {
			state->speed = SPEED_1000;
			state->duplex = DUPLEX_FULL;
			state->pause |= MLO_PAUSE_TX | MLO_PAUSE_RX;
		}
		break;

	case PHY_INTERFACE_MODE_2500BASEX:
		if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
			phylink_decode_c37_word(state, lpa, SPEED_2500);
		} else {
			state->speed = SPEED_2500;
			state->duplex = DUPLEX_FULL;
			state->pause |= MLO_PAUSE_TX | MLO_PAUSE_RX;
		}
		break;

	case PHY_INTERFACE_MODE_SGMII:
	case PHY_INTERFACE_MODE_QSGMII:
		if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
			phylink_decode_sgmii_word(state, lpa);
		break;

	case PHY_INTERFACE_MODE_QUSGMII:
		if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
			phylink_decode_usgmii_word(state, lpa);
		break;