Skip to content

Commit a3dcb3e

Browse files
lunnkuba-moo
authored andcommitted
net: dsa: mv88e6xxx: Wait for EEPROM done after HW reset
When the switch is hardware reset, it reads the contents of the EEPROM. This can contain instructions for programming values into registers and to perform waits between such programming. Reading the EEPROM can take longer than the 100ms mv88e6xxx_hardware_reset() waits after deasserting the reset GPIO. So poll the EEPROM done bit to ensure it is complete. Signed-off-by: Andrew Lunn <[email protected]> Signed-off-by: Ruslan Sushko <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent fc2635b commit a3dcb3e

File tree

3 files changed

+34
-0
lines changed

3 files changed

+34
-0
lines changed

drivers/net/dsa/mv88e6xxx/chip.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2297,6 +2297,8 @@ static void mv88e6xxx_hardware_reset(struct mv88e6xxx_chip *chip)
22972297
usleep_range(10000, 20000);
22982298
gpiod_set_value_cansleep(gpiod, 0);
22992299
usleep_range(10000, 20000);
2300+
2301+
mv88e6xxx_g1_wait_eeprom_done(chip);
23002302
}
23012303
}
23022304

drivers/net/dsa/mv88e6xxx/global1.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,37 @@ static int mv88e6xxx_g1_wait_init_ready(struct mv88e6xxx_chip *chip)
7575
return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_STS, bit, 1);
7676
}
7777

78+
void mv88e6xxx_g1_wait_eeprom_done(struct mv88e6xxx_chip *chip)
79+
{
80+
const unsigned long timeout = jiffies + 1 * HZ;
81+
u16 val;
82+
int err;
83+
84+
/* Wait up to 1 second for the switch to finish reading the
85+
* EEPROM.
86+
*/
87+
while (time_before(jiffies, timeout)) {
88+
err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &val);
89+
if (err) {
90+
dev_err(chip->dev, "Error reading status");
91+
return;
92+
}
93+
94+
/* If the switch is still resetting, it may not
95+
* respond on the bus, and so MDIO read returns
96+
* 0xffff. Differentiate between that, and waiting for
97+
* the EEPROM to be done by bit 0 being set.
98+
*/
99+
if (val != 0xffff &&
100+
val & BIT(MV88E6XXX_G1_STS_IRQ_EEPROM_DONE))
101+
return;
102+
103+
usleep_range(1000, 2000);
104+
}
105+
106+
dev_err(chip->dev, "Timeout waiting for EEPROM done");
107+
}
108+
78109
/* Offset 0x01: Switch MAC Address Register Bytes 0 & 1
79110
* Offset 0x02: Switch MAC Address Register Bytes 2 & 3
80111
* Offset 0x03: Switch MAC Address Register Bytes 4 & 5

drivers/net/dsa/mv88e6xxx/global1.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ int mv88e6xxx_g1_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr);
278278
int mv88e6185_g1_reset(struct mv88e6xxx_chip *chip);
279279
int mv88e6352_g1_reset(struct mv88e6xxx_chip *chip);
280280
int mv88e6250_g1_reset(struct mv88e6xxx_chip *chip);
281+
void mv88e6xxx_g1_wait_eeprom_done(struct mv88e6xxx_chip *chip);
281282

282283
int mv88e6185_g1_ppu_enable(struct mv88e6xxx_chip *chip);
283284
int mv88e6185_g1_ppu_disable(struct mv88e6xxx_chip *chip);

0 commit comments

Comments
 (0)