Commit 0fdd27b9 authored by Matthias Schiffer's avatar Matthias Schiffer Committed by David S. Miller
Browse files

net: dsa: mv88e6xxx: Add support for model-specific pre- and post-reset handlers



Instead of calling mv88e6xxx_g2_eeprom_wait() directly from
mv88e6xxx_hardware_reset(), add configurable pre- and post-reset hard
reset handlers. Initially, the handlers are set to
mv88e6xxx_g2_eeprom_wait() for all families that have get/set_eeprom()
to match the existing behavior. No functional change intended (except
for additional error messages on failure).

Fixes: 6ccf50d4 ("net: dsa: mv88e6xxx: Avoid EEPROM timeout when EEPROM is absent")
Signed-off-by: default avatarMatthias Schiffer <matthias.schiffer@ew.tq-group.com>
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 369dac68
Loading
Loading
Loading
Loading
+46 −4
Original line number Diff line number Diff line
@@ -3086,6 +3086,7 @@ static int mv88e6xxx_software_reset(struct mv88e6xxx_chip *chip)
static void mv88e6xxx_hardware_reset(struct mv88e6xxx_chip *chip)
{
	struct gpio_desc *gpiod = chip->reset;
	int err;

	/* If there is a GPIO connected to the reset pin, toggle it */
	if (gpiod) {
@@ -3094,17 +3095,26 @@ static void mv88e6xxx_hardware_reset(struct mv88e6xxx_chip *chip)
		 * mid-byte, causing the first EEPROM read after the reset
		 * from the wrong location resulting in the switch booting
		 * to wrong mode and inoperable.
		 * For this reason, switch families with EEPROM support
		 * generally wait for EEPROM loads to complete as their pre-
		 * and post-reset handlers.
		 */
		if (chip->info->ops->get_eeprom)
			mv88e6xxx_g2_eeprom_wait(chip);
		if (chip->info->ops->hardware_reset_pre) {
			err = chip->info->ops->hardware_reset_pre(chip);
			if (err)
				dev_err(chip->dev, "pre-reset error: %d\n", err);
		}

		gpiod_set_value_cansleep(gpiod, 1);
		usleep_range(10000, 20000);
		gpiod_set_value_cansleep(gpiod, 0);
		usleep_range(10000, 20000);

		if (chip->info->ops->get_eeprom)
			mv88e6xxx_g2_eeprom_wait(chip);
		if (chip->info->ops->hardware_reset_post) {
			err = chip->info->ops->hardware_reset_post(chip);
			if (err)
				dev_err(chip->dev, "post-reset error: %d\n", err);
		}
	}
}

@@ -4334,6 +4344,8 @@ static const struct mv88e6xxx_ops mv88e6141_ops = {
	.watchdog_ops = &mv88e6390_watchdog_ops,
	.mgmt_rsvd2cpu =  mv88e6390_g1_mgmt_rsvd2cpu,
	.pot_clear = mv88e6xxx_g2_pot_clear,
	.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
	.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
	.reset = mv88e6352_g1_reset,
	.rmu_disable = mv88e6390_g1_rmu_disable,
	.atu_get_hash = mv88e6165_g1_atu_get_hash,
@@ -4524,6 +4536,8 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
	.watchdog_ops = &mv88e6097_watchdog_ops,
	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
	.pot_clear = mv88e6xxx_g2_pot_clear,
	.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
	.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
	.reset = mv88e6352_g1_reset,
	.rmu_disable = mv88e6352_g1_rmu_disable,
	.atu_get_hash = mv88e6165_g1_atu_get_hash,
@@ -4624,6 +4638,8 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
	.watchdog_ops = &mv88e6097_watchdog_ops,
	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
	.pot_clear = mv88e6xxx_g2_pot_clear,
	.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
	.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
	.reset = mv88e6352_g1_reset,
	.rmu_disable = mv88e6352_g1_rmu_disable,
	.atu_get_hash = mv88e6165_g1_atu_get_hash,
@@ -4718,6 +4734,8 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
	.watchdog_ops = &mv88e6390_watchdog_ops,
	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
	.pot_clear = mv88e6xxx_g2_pot_clear,
	.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
	.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
	.reset = mv88e6352_g1_reset,
	.rmu_disable = mv88e6390_g1_rmu_disable,
	.atu_get_hash = mv88e6165_g1_atu_get_hash,
@@ -4776,6 +4794,8 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
	.watchdog_ops = &mv88e6390_watchdog_ops,
	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
	.pot_clear = mv88e6xxx_g2_pot_clear,
	.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
	.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
	.reset = mv88e6352_g1_reset,
	.rmu_disable = mv88e6390_g1_rmu_disable,
	.atu_get_hash = mv88e6165_g1_atu_get_hash,
@@ -4832,6 +4852,8 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
	.watchdog_ops = &mv88e6390_watchdog_ops,
	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
	.pot_clear = mv88e6xxx_g2_pot_clear,
	.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
	.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
	.reset = mv88e6352_g1_reset,
	.rmu_disable = mv88e6390_g1_rmu_disable,
	.atu_get_hash = mv88e6165_g1_atu_get_hash,
@@ -4891,6 +4913,8 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
	.watchdog_ops = &mv88e6097_watchdog_ops,
	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
	.pot_clear = mv88e6xxx_g2_pot_clear,
	.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
	.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
	.reset = mv88e6352_g1_reset,
	.rmu_disable = mv88e6352_g1_rmu_disable,
	.atu_get_hash = mv88e6165_g1_atu_get_hash,
@@ -4944,6 +4968,8 @@ static const struct mv88e6xxx_ops mv88e6250_ops = {
	.watchdog_ops = &mv88e6250_watchdog_ops,
	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
	.pot_clear = mv88e6xxx_g2_pot_clear,
	.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
	.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
	.reset = mv88e6250_g1_reset,
	.vtu_getnext = mv88e6185_g1_vtu_getnext,
	.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
@@ -4991,6 +5017,8 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
	.watchdog_ops = &mv88e6390_watchdog_ops,
	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
	.pot_clear = mv88e6xxx_g2_pot_clear,
	.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
	.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
	.reset = mv88e6352_g1_reset,
	.rmu_disable = mv88e6390_g1_rmu_disable,
	.atu_get_hash = mv88e6165_g1_atu_get_hash,
@@ -5050,6 +5078,8 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
	.watchdog_ops = &mv88e6390_watchdog_ops,
	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
	.pot_clear = mv88e6xxx_g2_pot_clear,
	.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
	.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
	.reset = mv88e6352_g1_reset,
	.vtu_getnext = mv88e6185_g1_vtu_getnext,
	.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
@@ -5096,6 +5126,8 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
	.set_egress_port = mv88e6095_g1_set_egress_port,
	.watchdog_ops = &mv88e6390_watchdog_ops,
	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
	.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
	.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
	.reset = mv88e6352_g1_reset,
	.vtu_getnext = mv88e6185_g1_vtu_getnext,
	.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
@@ -5146,6 +5178,8 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {
	.watchdog_ops = &mv88e6390_watchdog_ops,
	.mgmt_rsvd2cpu =  mv88e6390_g1_mgmt_rsvd2cpu,
	.pot_clear = mv88e6xxx_g2_pot_clear,
	.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
	.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
	.reset = mv88e6352_g1_reset,
	.rmu_disable = mv88e6390_g1_rmu_disable,
	.atu_get_hash = mv88e6165_g1_atu_get_hash,
@@ -5301,6 +5335,8 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
	.watchdog_ops = &mv88e6097_watchdog_ops,
	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
	.pot_clear = mv88e6xxx_g2_pot_clear,
	.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
	.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
	.reset = mv88e6352_g1_reset,
	.rmu_disable = mv88e6352_g1_rmu_disable,
	.atu_get_hash = mv88e6165_g1_atu_get_hash,
@@ -5363,6 +5399,8 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
	.watchdog_ops = &mv88e6390_watchdog_ops,
	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
	.pot_clear = mv88e6xxx_g2_pot_clear,
	.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
	.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
	.reset = mv88e6352_g1_reset,
	.rmu_disable = mv88e6390_g1_rmu_disable,
	.atu_get_hash = mv88e6165_g1_atu_get_hash,
@@ -5425,6 +5463,8 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
	.watchdog_ops = &mv88e6390_watchdog_ops,
	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
	.pot_clear = mv88e6xxx_g2_pot_clear,
	.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
	.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
	.reset = mv88e6352_g1_reset,
	.rmu_disable = mv88e6390_g1_rmu_disable,
	.atu_get_hash = mv88e6165_g1_atu_get_hash,
@@ -5490,6 +5530,8 @@ static const struct mv88e6xxx_ops mv88e6393x_ops = {
	.watchdog_ops = &mv88e6393x_watchdog_ops,
	.mgmt_rsvd2cpu = mv88e6393x_port_mgmt_rsvd2cpu,
	.pot_clear = mv88e6xxx_g2_pot_clear,
	.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
	.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
	.reset = mv88e6352_g1_reset,
	.rmu_disable = mv88e6390_g1_rmu_disable,
	.atu_get_hash = mv88e6165_g1_atu_get_hash,
+6 −0
Original line number Diff line number Diff line
@@ -487,6 +487,12 @@ struct mv88e6xxx_ops {
	int (*ppu_enable)(struct mv88e6xxx_chip *chip);
	int (*ppu_disable)(struct mv88e6xxx_chip *chip);

	/* Additional handlers to run before and after hard reset, to make sure
	 * that the switch and EEPROM are in a good state.
	 */
	int (*hardware_reset_pre)(struct mv88e6xxx_chip *chip);
	int (*hardware_reset_post)(struct mv88e6xxx_chip *chip);

	/* Switch Software Reset */
	int (*reset)(struct mv88e6xxx_chip *chip);