aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/dsa/sja1105/sja1105_spi.c
diff options
context:
space:
mode:
authorVladimir Oltean <vladimir.oltean@nxp.com>2021-06-18 14:52:54 +0300
committerDavid S. Miller <davem@davemloft.net>2021-06-18 12:26:17 -0700
commitcb5a82d2b9aaca66ed74c424c9d79f0a5bfdbac4 (patch)
treed19cba85e6665fabb4c7ee8d51c0c11c5082388b /drivers/net/dsa/sja1105/sja1105_spi.c
parentqlcnic: remove redundant continue statement (diff)
downloadlinux-dev-cb5a82d2b9aaca66ed74c424c9d79f0a5bfdbac4.tar.xz
linux-dev-cb5a82d2b9aaca66ed74c424c9d79f0a5bfdbac4.zip
net: dsa: sja1105: properly power down the microcontroller clock for SJA1110
It turns out that powering down the BASE_TIMER_CLK does not turn off the microcontroller, just its timers, including the one for the watchdog. So the embedded microcontroller is still running, and potentially still doing things. To prevent unwanted interference, we should power down the BASE_MCSS_CLK as well (MCSS = microcontroller subsystem). The trouble is that currently we turn off the BASE_TIMER_CLK for SJA1110 from the .clocking_setup() method, mostly because this is a Clock Generation Unit (CGU) setting which was traditionally configured in that method for SJA1105. But in SJA1105, the CGU was used for bringing up the port clocks at the proper speeds, and in SJA1110 it's not (but rather for initial configuration), so it's best that we rebrand the sja1110_clocking_setup() method into what it really is - an implementation of the .disable_microcontroller() method. Since disabling the microcontroller only needs to be done once, at probe time, we can choose the best place to do that as being in sja1105_setup(), before we upload the static config to the device. This guarantees that the static config being used by the switch afterwards is really ours. Note that the procedure to upload a static config necessarily resets the switch. This already did not reset the microcontroller, only the switch core, so since the .disable_microcontroller() method is guaranteed to be called by that point, if it's disabled, it remains disabled. Add a comment to make that clear. With the code movement for SJA1110 from .clocking_setup() to .disable_microcontroller(), both methods are optional and are guarded by "if" conditions. Tested by enabling in the device tree the rev-mii switch port 0 that goes towards the microcontroller, and flashing a firmware that would have networking. Without this patch, the microcontroller can be pinged, with this patch it cannot. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/dsa/sja1105/sja1105_spi.c')
-rw-r--r--drivers/net/dsa/sja1105/sja1105_spi.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/drivers/net/dsa/sja1105/sja1105_spi.c b/drivers/net/dsa/sja1105/sja1105_spi.c
index 4aed16d23f21..08cc5dbf2fa6 100644
--- a/drivers/net/dsa/sja1105/sja1105_spi.c
+++ b/drivers/net/dsa/sja1105/sja1105_spi.c
@@ -199,7 +199,11 @@ static int sja1110_reset_cmd(struct dsa_switch *ds)
const struct sja1105_regs *regs = priv->info->regs;
u32 switch_reset = BIT(20);
- /* Switch core reset */
+ /* Only reset the switch core.
+ * A full cold reset would re-enable the BASE_MCSS_CLOCK PLL which
+ * would turn on the microcontroller, potentially letting it execute
+ * code which could interfere with our configuration.
+ */
return sja1105_xfer_u32(priv, SPI_WRITE, regs->rgu, &switch_reset, NULL);
}
@@ -796,7 +800,7 @@ const struct sja1105_info sja1110a_info = {
.ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing,
.rxtstamp = sja1110_rxtstamp,
.txtstamp = sja1110_txtstamp,
- .clocking_setup = sja1110_clocking_setup,
+ .disable_microcontroller = sja1110_disable_microcontroller,
.pcs_mdio_read = sja1110_pcs_mdio_read,
.pcs_mdio_write = sja1110_pcs_mdio_write,
.port_speed = {
@@ -847,7 +851,7 @@ const struct sja1105_info sja1110b_info = {
.ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing,
.rxtstamp = sja1110_rxtstamp,
.txtstamp = sja1110_txtstamp,
- .clocking_setup = sja1110_clocking_setup,
+ .disable_microcontroller = sja1110_disable_microcontroller,
.pcs_mdio_read = sja1110_pcs_mdio_read,
.pcs_mdio_write = sja1110_pcs_mdio_write,
.port_speed = {
@@ -898,7 +902,7 @@ const struct sja1105_info sja1110c_info = {
.ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing,
.rxtstamp = sja1110_rxtstamp,
.txtstamp = sja1110_txtstamp,
- .clocking_setup = sja1110_clocking_setup,
+ .disable_microcontroller = sja1110_disable_microcontroller,
.pcs_mdio_read = sja1110_pcs_mdio_read,
.pcs_mdio_write = sja1110_pcs_mdio_write,
.port_speed = {
@@ -949,7 +953,7 @@ const struct sja1105_info sja1110d_info = {
.ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing,
.rxtstamp = sja1110_rxtstamp,
.txtstamp = sja1110_txtstamp,
- .clocking_setup = sja1110_clocking_setup,
+ .disable_microcontroller = sja1110_disable_microcontroller,
.pcs_mdio_read = sja1110_pcs_mdio_read,
.pcs_mdio_write = sja1110_pcs_mdio_write,
.port_speed = {