Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net: dsa: mv88e6xxx: Avoid EEPROM timeout when EEPROM is absent

Since commit 23d775f12dcd ("net: dsa: mv88e6xxx: Wait for EEPROM done
before HW reset") the following error is seen on a imx8mn board with
a 88E6320 switch:

mv88e6085 30be0000.ethernet-1:00: Timeout waiting for EEPROM done

This board does not have an EEPROM attached to the switch though.

This problem is well explained by Andrew Lunn:

"If there is an EEPROM, and the EEPROM contains a lot of data, it could
be that when we perform a hardware reset towards the end of probe, it
interrupts an I2C bus transaction, leaving the I2C bus in a bad state,
and future reads of the EEPROM do not work.

The work around for this was to poll the EEInt status and wait for it
to go true before performing the hardware reset.

However, we have discovered that for some boards which do not have an
EEPROM, EEInt never indicates complete. As a result,
mv88e6xxx_g1_wait_eeprom_done() spins for a second and then prints a
warning.

We probably need a different solution than calling
mv88e6xxx_g1_wait_eeprom_done(). The datasheet for 6352 documents the
EEPROM Command register:

bit 15 is:

EEPROM Unit Busy. This bit must be set to a one to start an EEPROM
operation (see EEOp below). Only one EEPROM operation can be
executing at one time so this bit must be zero before setting it to
a one. When the requested EEPROM operation completes this bit will
automatically be cleared to a zero. The transition of this bit from
a one to a zero can be used to generate an interrupt (the EEInt in
Global 1, offset 0x00).

and more interesting is bit 11:

Register Loader Running. This bit is set to one whenever the
register loader is busy executing instructions contained in the
EEPROM."

Change to using mv88e6xxx_g2_eeprom_wait() to fix the timeout error
when the EEPROM chip is not present.

Fixes: 23d775f12dcd ("net: dsa: mv88e6xxx: Wait for EEPROM done before HW reset")
Suggested-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Fabio Estevam <festevam@denx.de>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Fabio Estevam and committed by
David S. Miller
6ccf50d4 caa0578c

+6 -35
+4 -2
drivers/net/dsa/mv88e6xxx/chip.c
··· 2958 2958 * from the wrong location resulting in the switch booting 2959 2959 * to wrong mode and inoperable. 2960 2960 */ 2961 - mv88e6xxx_g1_wait_eeprom_done(chip); 2961 + if (chip->info->ops->get_eeprom) 2962 + mv88e6xxx_g2_eeprom_wait(chip); 2962 2963 2963 2964 gpiod_set_value_cansleep(gpiod, 1); 2964 2965 usleep_range(10000, 20000); 2965 2966 gpiod_set_value_cansleep(gpiod, 0); 2966 2967 usleep_range(10000, 20000); 2967 2968 2968 - mv88e6xxx_g1_wait_eeprom_done(chip); 2969 + if (chip->info->ops->get_eeprom) 2970 + mv88e6xxx_g2_eeprom_wait(chip); 2969 2971 } 2970 2972 } 2971 2973
-31
drivers/net/dsa/mv88e6xxx/global1.c
··· 75 75 return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_STS, bit, 1); 76 76 } 77 77 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 - 109 78 /* Offset 0x01: Switch MAC Address Register Bytes 0 & 1 110 79 * Offset 0x02: Switch MAC Address Register Bytes 2 & 3 111 80 * Offset 0x03: Switch MAC Address Register Bytes 4 & 5
-1
drivers/net/dsa/mv88e6xxx/global1.h
··· 282 282 int mv88e6185_g1_reset(struct mv88e6xxx_chip *chip); 283 283 int mv88e6352_g1_reset(struct mv88e6xxx_chip *chip); 284 284 int mv88e6250_g1_reset(struct mv88e6xxx_chip *chip); 285 - void mv88e6xxx_g1_wait_eeprom_done(struct mv88e6xxx_chip *chip); 286 285 287 286 int mv88e6185_g1_ppu_enable(struct mv88e6xxx_chip *chip); 288 287 int mv88e6185_g1_ppu_disable(struct mv88e6xxx_chip *chip);
+1 -1
drivers/net/dsa/mv88e6xxx/global2.c
··· 340 340 * Offset 0x15: EEPROM Addr (for 8-bit data access) 341 341 */ 342 342 343 - static int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip) 343 + int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip) 344 344 { 345 345 int bit = __bf_shf(MV88E6XXX_G2_EEPROM_CMD_BUSY); 346 346 int err;
+1
drivers/net/dsa/mv88e6xxx/global2.h
··· 365 365 366 366 int mv88e6xxx_g2_device_mapping_write(struct mv88e6xxx_chip *chip, int target, 367 367 int port); 368 + int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip); 368 369 369 370 extern const struct mv88e6xxx_irq_ops mv88e6097_watchdog_ops; 370 371 extern const struct mv88e6xxx_irq_ops mv88e6250_watchdog_ops;