Commit 23d775f1 authored by Alfred Lee's avatar Alfred Lee Committed by Jakub Kicinski

net: dsa: mv88e6xxx: Wait for EEPROM done before HW reset

If the switch is reset during active EEPROM transactions, as in
just after an SoC reset after power up, the I2C bus transaction
may be cut short leaving the EEPROM internal I2C state machine
in the wrong state.  When the switch is reset again, the bad
state machine state may result in data being read from the wrong
memory location causing the switch to enter unexpected mode
rendering it inoperational.

Fixes: a3dcb3e7 ("net: dsa: mv88e6xxx: Wait for EEPROM done after HW reset")
Signed-off-by: default avatarAlfred Lee <l00g33k@gmail.com>
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Link: https://lore.kernel.org/r/20230815001323.24739-1-l00g33k@gmail.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent de4c5efe
...@@ -3034,6 +3034,14 @@ static void mv88e6xxx_hardware_reset(struct mv88e6xxx_chip *chip) ...@@ -3034,6 +3034,14 @@ static void mv88e6xxx_hardware_reset(struct mv88e6xxx_chip *chip)
/* If there is a GPIO connected to the reset pin, toggle it */ /* If there is a GPIO connected to the reset pin, toggle it */
if (gpiod) { if (gpiod) {
/* If the switch has just been reset and not yet completed
* loading EEPROM, the reset may interrupt the I2C transaction
* mid-byte, causing the first EEPROM read after the reset
* from the wrong location resulting in the switch booting
* to wrong mode and inoperable.
*/
mv88e6xxx_g1_wait_eeprom_done(chip);
gpiod_set_value_cansleep(gpiod, 1); gpiod_set_value_cansleep(gpiod, 1);
usleep_range(10000, 20000); usleep_range(10000, 20000);
gpiod_set_value_cansleep(gpiod, 0); gpiod_set_value_cansleep(gpiod, 0);
......
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