Commit bf0a3750 authored by Cyril Novikov's avatar Cyril Novikov Committed by Tony Nguyen

ixgbe: set X550 MDIO speed before talking to PHY

The MDIO bus speed must be initialized before talking to the PHY the first
time in order to avoid talking to it using a speed that the PHY doesn't
support.

This fixes HW initialization error -17 (IXGBE_ERR_PHY_ADDR_INVALID) on
Denverton CPUs (a.k.a. the Atom C3000 family) on ports with a 10Gb network
plugged in. On those devices, HLREG0[MDCSPD] resets to 1, which combined
with the 10Gb network results in a 24MHz MDIO speed, which is apparently
too fast for the connected PHY. PHY register reads over MDIO bus return
garbage, leading to initialization failure.

Reproduced with Linux kernel 4.19 and 5.15-rc7. Can be reproduced using
the following setup:

* Use an Atom C3000 family system with at least one X552 LAN on the SoC
* Disable PXE or other BIOS network initialization if possible
  (the interface must not be initialized before Linux boots)
* Connect a live 10Gb Ethernet cable to an X550 port
* Power cycle (not reset, doesn't always work) the system and boot Linux
* Observe: ixgbe interfaces w/ 10GbE cables plugged in fail with error -17

Fixes: e84db727 ("ixgbe: Introduce function to control MDIO speed")
Signed-off-by: default avatarCyril Novikov <cnovikov@lynx.com>
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent 271225fd
...@@ -3405,6 +3405,9 @@ static s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw) ...@@ -3405,6 +3405,9 @@ static s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw)
/* flush pending Tx transactions */ /* flush pending Tx transactions */
ixgbe_clear_tx_pending(hw); ixgbe_clear_tx_pending(hw);
/* set MDIO speed before talking to the PHY in case it's the 1st time */
ixgbe_set_mdio_speed(hw);
/* PHY ops must be identified and initialized prior to reset */ /* PHY ops must be identified and initialized prior to reset */
status = hw->phy.ops.init(hw); status = hw->phy.ops.init(hw);
if (status == IXGBE_ERR_SFP_NOT_SUPPORTED || if (status == IXGBE_ERR_SFP_NOT_SUPPORTED ||
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment