From: Andrew Lunn When the conduit interface comes up, try to enable the RMU. Failing to enable the remote management unit is not fatal, not all chips support it, and some boards have chips which do support RMU, but with wrong port is connected to the CPU. When the conduit interface goes down, disable the RMU. Keep track of the conduit interface, so that RMU frames can be sent to it. Co-developed: Mattias Forsblad Signed-off-by: Mattias Forsblad Signed-off-by: Andrew Lunn --- drivers/net/dsa/mv88e6xxx/Makefile | 1 + drivers/net/dsa/mv88e6xxx/chip.c | 2 ++ drivers/net/dsa/mv88e6xxx/chip.h | 3 +++ drivers/net/dsa/mv88e6xxx/rmu.c | 50 ++++++++++++++++++++++++++++++++++++++ drivers/net/dsa/mv88e6xxx/rmu.h | 15 ++++++++++++ 5 files changed, 71 insertions(+) diff --git a/drivers/net/dsa/mv88e6xxx/Makefile b/drivers/net/dsa/mv88e6xxx/Makefile index b0b08c6f159c6..1f3571061a550 100644 --- a/drivers/net/dsa/mv88e6xxx/Makefile +++ b/drivers/net/dsa/mv88e6xxx/Makefile @@ -17,6 +17,7 @@ mv88e6xxx-objs += phy.o mv88e6xxx-objs += port.o mv88e6xxx-objs += port_hidden.o mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_PTP) += ptp.o +mv88e6xxx-objs += rmu.o mv88e6xxx-objs += serdes.o mv88e6xxx-objs += smi.o mv88e6xxx-objs += switchdev.o diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index dbfbdb982fc00..d6c6834cca2cb 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -41,6 +41,7 @@ #include "phy.h" #include "port.h" #include "ptp.h" +#include "rmu.h" #include "serdes.h" #include "smi.h" #include "tcam.h" @@ -7265,6 +7266,7 @@ static const struct dsa_switch_ops mv88e6xxx_switch_ops = { .crosschip_lag_change = mv88e6xxx_crosschip_lag_change, .crosschip_lag_join = mv88e6xxx_crosschip_lag_join, .crosschip_lag_leave = mv88e6xxx_crosschip_lag_leave, + .conduit_state_change = mv88e6xxx_rmu_conduit_state_change, }; static int mv88e6xxx_register_switch(struct mv88e6xxx_chip *chip) diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h index 12fdcb63252eb..76958b588a908 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.h +++ b/drivers/net/dsa/mv88e6xxx/chip.h @@ -457,6 +457,9 @@ struct mv88e6xxx_chip { /* Global2 scratch register config data3 */ u8 g2_scratch_config3; + + /* Remote Management Unit state. */ + struct net_device *rmu_conduit; }; #define TCAM_MATCH_SIZE 96 diff --git a/drivers/net/dsa/mv88e6xxx/rmu.c b/drivers/net/dsa/mv88e6xxx/rmu.c new file mode 100644 index 0000000000000..64e93e2eaf550 --- /dev/null +++ b/drivers/net/dsa/mv88e6xxx/rmu.c @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Marvell 88E6xxx Switch Remote Management Unit Support + * + * Copyright (c) 2022 Mattias Forsblad + * + */ + +#include +#include "chip.h" +#include "global1.h" +#include "rmu.h" + +void mv88e6xxx_rmu_conduit_state_change(struct dsa_switch *ds, + const struct net_device *conduit, + bool operational) +{ + struct dsa_port *cpu_dp = conduit->dsa_ptr; + struct mv88e6xxx_chip *chip = ds->priv; + int port; + int ret; + + port = dsa_towards_port(ds, cpu_dp->ds->index, cpu_dp->index); + + mv88e6xxx_reg_lock(chip); + + if (operational && chip->info->ops->rmu_enable) { + ret = chip->info->ops->rmu_enable(chip, port); + if (ret == -EOPNOTSUPP) { + dev_info(chip->dev, "RMU: not usable on this board"); + goto out; + } else if (ret < 0) { + dev_err(chip->dev, "RMU: unable to enable on port %d %pe", + port, ERR_PTR(ret)); + goto out; + } + + WRITE_ONCE(chip->rmu_conduit, (struct net_device *)conduit); + + dev_dbg(chip->dev, "RMU: Enabled on port %d", port); + } else { + if (chip->info->ops->rmu_disable) + chip->info->ops->rmu_disable(chip); + + WRITE_ONCE(chip->rmu_conduit, NULL); + } + +out: + mv88e6xxx_reg_unlock(chip); +} diff --git a/drivers/net/dsa/mv88e6xxx/rmu.h b/drivers/net/dsa/mv88e6xxx/rmu.h new file mode 100644 index 0000000000000..71c4fc1d4113f --- /dev/null +++ b/drivers/net/dsa/mv88e6xxx/rmu.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Marvell 88E6xxx Switch Remote Management Unit Support + * + * Copyright (c) 2022 Mattias Forsblad + * + */ + +#ifndef _MV88E6XXX_RMU_H_ +#define _MV88E6XXX_RMU_H_ + +void mv88e6xxx_rmu_conduit_state_change(struct dsa_switch *ds, + const struct net_device *conduit, + bool operational); +#endif /* _MV88E6XXX_RMU_H_ */ -- 2.43.0