2019-05-02 23:23:30 +03:00
|
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
2021-09-17 14:17:35 +03:00
|
|
|
/* Copyright 2016-2018 NXP
|
2019-05-02 23:23:30 +03:00
|
|
|
* Copyright (c) 2018-2019, Vladimir Oltean <olteanv@gmail.com>
|
|
|
|
*/
|
|
|
|
#include <linux/packing.h>
|
|
|
|
#include "sja1105.h"
|
|
|
|
|
|
|
|
#define SJA1105_SIZE_CGU_CMD 4
|
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>
2021-06-18 14:52:54 +03:00
|
|
|
#define SJA1110_BASE_MCSS_CLK SJA1110_CGU_ADDR(0x70)
|
net: dsa: sja1105: add support for the SJA1110 switch family
The SJA1110 is basically an SJA1105 with more ports, some integrated
PHYs (100base-T1 and 100base-TX) and an embedded microcontroller which
can be disabled, and the switch core can be controlled by a host running
Linux, over SPI.
This patch contains:
- the static and dynamic config packing functions, for the tables that
are common with SJA1105
- one more static config tables which is "unique" to the SJA1110
(actually it is a rehash of stuff that was placed somewhere else in
SJA1105): the PCP Remapping Table
- a reset and clock configuration procedure for the SJA1110 switch.
This resets just the switch subsystem, and gates off the clock which
powers on the embedded microcontroller.
- an RGMII delay configuration procedure for SJA1110, which is very
similar to SJA1105, but different enough for us to be unable to reuse
it (this is a pattern that repeats itself)
- some adaptations to dynamic config table entries which are no longer
programmed in the same way. For example, to delete a VLAN, you used to
write an entry through the dynamic reconfiguration interface with the
desired VLAN ID, and with the VALIDENT bit set to false. Now, the VLAN
table entries contain a TYPE_ENTRY field, which must be set to zero
(in a backwards-incompatible way) in order for the entry to be deleted,
or to some other entry for the VLAN to match "inner tagged" or "outer
tagged" packets.
- a similar thing for the static config: the xMII Mode Parameters Table
encoding for SGMII and MII (the latter just when attached to a
100base-TX PHY) just isn't what it used to be in SJA1105. They are
identical, except there is an extra "special" bit which needs to be
set. Set it.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-06-08 12:25:36 +03:00
|
|
|
#define SJA1110_BASE_TIMER_CLK SJA1110_CGU_ADDR(0x74)
|
2019-05-02 23:23:30 +03:00
|
|
|
|
net: dsa: sja1105: enable internal pull-down for RX_DV/CRS_DV/RX_CTL and RX_ER
Some boards do not have the RX_ER MII signal connected. Normally in such
situation, those pins would be grounded, but then again, some boards
left it electrically floating.
When sending traffic to those switch ports, one can see that the
N_SOFERR statistics counter is incrementing once per each packet. The
user manual states for this counter that it may count the number of
frames "that have the MII error input being asserted prior to or
up to the SOF delimiter byte". So the switch MAC is sampling an
electrically floating signal, and preventing proper traffic reception
because of that.
As a workaround, enable the internal weak pull-downs on the input pads
for the MII control signals. This way, a floating signal would be
internally tied to ground.
The logic levels of signals which _are_ externally driven should not be
bothered by this 40-50 KOhm internal resistor. So it is not an issue to
enable the internal pull-down unconditionally, irrespective of PHY
interface type (MII, RMII, RGMII, SGMII) and of board layout.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-04-17 22:50:52 +03:00
|
|
|
/* Common structure for CFG_PAD_MIIx_RX and CFG_PAD_MIIx_TX */
|
|
|
|
struct sja1105_cfg_pad_mii {
|
2019-05-02 23:23:30 +03:00
|
|
|
u64 d32_os;
|
net: dsa: sja1105: enable internal pull-down for RX_DV/CRS_DV/RX_CTL and RX_ER
Some boards do not have the RX_ER MII signal connected. Normally in such
situation, those pins would be grounded, but then again, some boards
left it electrically floating.
When sending traffic to those switch ports, one can see that the
N_SOFERR statistics counter is incrementing once per each packet. The
user manual states for this counter that it may count the number of
frames "that have the MII error input being asserted prior to or
up to the SOF delimiter byte". So the switch MAC is sampling an
electrically floating signal, and preventing proper traffic reception
because of that.
As a workaround, enable the internal weak pull-downs on the input pads
for the MII control signals. This way, a floating signal would be
internally tied to ground.
The logic levels of signals which _are_ externally driven should not be
bothered by this 40-50 KOhm internal resistor. So it is not an issue to
enable the internal pull-down unconditionally, irrespective of PHY
interface type (MII, RMII, RGMII, SGMII) and of board layout.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-04-17 22:50:52 +03:00
|
|
|
u64 d32_ih;
|
2019-05-02 23:23:30 +03:00
|
|
|
u64 d32_ipud;
|
net: dsa: sja1105: enable internal pull-down for RX_DV/CRS_DV/RX_CTL and RX_ER
Some boards do not have the RX_ER MII signal connected. Normally in such
situation, those pins would be grounded, but then again, some boards
left it electrically floating.
When sending traffic to those switch ports, one can see that the
N_SOFERR statistics counter is incrementing once per each packet. The
user manual states for this counter that it may count the number of
frames "that have the MII error input being asserted prior to or
up to the SOF delimiter byte". So the switch MAC is sampling an
electrically floating signal, and preventing proper traffic reception
because of that.
As a workaround, enable the internal weak pull-downs on the input pads
for the MII control signals. This way, a floating signal would be
internally tied to ground.
The logic levels of signals which _are_ externally driven should not be
bothered by this 40-50 KOhm internal resistor. So it is not an issue to
enable the internal pull-down unconditionally, irrespective of PHY
interface type (MII, RMII, RGMII, SGMII) and of board layout.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-04-17 22:50:52 +03:00
|
|
|
u64 d10_ih;
|
2019-05-02 23:23:30 +03:00
|
|
|
u64 d10_os;
|
|
|
|
u64 d10_ipud;
|
|
|
|
u64 ctrl_os;
|
net: dsa: sja1105: enable internal pull-down for RX_DV/CRS_DV/RX_CTL and RX_ER
Some boards do not have the RX_ER MII signal connected. Normally in such
situation, those pins would be grounded, but then again, some boards
left it electrically floating.
When sending traffic to those switch ports, one can see that the
N_SOFERR statistics counter is incrementing once per each packet. The
user manual states for this counter that it may count the number of
frames "that have the MII error input being asserted prior to or
up to the SOF delimiter byte". So the switch MAC is sampling an
electrically floating signal, and preventing proper traffic reception
because of that.
As a workaround, enable the internal weak pull-downs on the input pads
for the MII control signals. This way, a floating signal would be
internally tied to ground.
The logic levels of signals which _are_ externally driven should not be
bothered by this 40-50 KOhm internal resistor. So it is not an issue to
enable the internal pull-down unconditionally, irrespective of PHY
interface type (MII, RMII, RGMII, SGMII) and of board layout.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-04-17 22:50:52 +03:00
|
|
|
u64 ctrl_ih;
|
2019-05-02 23:23:30 +03:00
|
|
|
u64 ctrl_ipud;
|
|
|
|
u64 clk_os;
|
|
|
|
u64 clk_ih;
|
|
|
|
u64 clk_ipud;
|
|
|
|
};
|
|
|
|
|
2019-06-08 19:12:28 +03:00
|
|
|
struct sja1105_cfg_pad_mii_id {
|
|
|
|
u64 rxc_stable_ovr;
|
|
|
|
u64 rxc_delay;
|
|
|
|
u64 rxc_bypass;
|
|
|
|
u64 rxc_pd;
|
|
|
|
u64 txc_stable_ovr;
|
|
|
|
u64 txc_delay;
|
|
|
|
u64 txc_bypass;
|
|
|
|
u64 txc_pd;
|
|
|
|
};
|
|
|
|
|
2019-05-02 23:23:30 +03:00
|
|
|
/* UM10944 Table 82.
|
|
|
|
* IDIV_0_C to IDIV_4_C control registers
|
|
|
|
* (addr. 10000Bh to 10000Fh)
|
|
|
|
*/
|
|
|
|
struct sja1105_cgu_idiv {
|
|
|
|
u64 clksrc;
|
|
|
|
u64 autoblock;
|
|
|
|
u64 idiv;
|
|
|
|
u64 pd;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* PLL_1_C control register
|
|
|
|
*
|
|
|
|
* SJA1105 E/T: UM10944 Table 81 (address 10000Ah)
|
|
|
|
* SJA1105 P/Q/R/S: UM11040 Table 116 (address 10000Ah)
|
|
|
|
*/
|
|
|
|
struct sja1105_cgu_pll_ctrl {
|
|
|
|
u64 pllclksrc;
|
|
|
|
u64 msel;
|
|
|
|
u64 autoblock;
|
|
|
|
u64 psel;
|
|
|
|
u64 direct;
|
|
|
|
u64 fbsel;
|
|
|
|
u64 bypass;
|
|
|
|
u64 pd;
|
|
|
|
};
|
|
|
|
|
net: dsa: sja1105: add support for the SJA1110 switch family
The SJA1110 is basically an SJA1105 with more ports, some integrated
PHYs (100base-T1 and 100base-TX) and an embedded microcontroller which
can be disabled, and the switch core can be controlled by a host running
Linux, over SPI.
This patch contains:
- the static and dynamic config packing functions, for the tables that
are common with SJA1105
- one more static config tables which is "unique" to the SJA1110
(actually it is a rehash of stuff that was placed somewhere else in
SJA1105): the PCP Remapping Table
- a reset and clock configuration procedure for the SJA1110 switch.
This resets just the switch subsystem, and gates off the clock which
powers on the embedded microcontroller.
- an RGMII delay configuration procedure for SJA1110, which is very
similar to SJA1105, but different enough for us to be unable to reuse
it (this is a pattern that repeats itself)
- some adaptations to dynamic config table entries which are no longer
programmed in the same way. For example, to delete a VLAN, you used to
write an entry through the dynamic reconfiguration interface with the
desired VLAN ID, and with the VALIDENT bit set to false. Now, the VLAN
table entries contain a TYPE_ENTRY field, which must be set to zero
(in a backwards-incompatible way) in order for the entry to be deleted,
or to some other entry for the VLAN to match "inner tagged" or "outer
tagged" packets.
- a similar thing for the static config: the xMII Mode Parameters Table
encoding for SGMII and MII (the latter just when attached to a
100base-TX PHY) just isn't what it used to be in SJA1105. They are
identical, except there is an extra "special" bit which needs to be
set. Set it.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-06-08 12:25:36 +03:00
|
|
|
struct sja1110_cgu_outclk {
|
|
|
|
u64 clksrc;
|
|
|
|
u64 autoblock;
|
|
|
|
u64 pd;
|
|
|
|
};
|
|
|
|
|
2019-05-02 23:23:30 +03:00
|
|
|
enum {
|
|
|
|
CLKSRC_MII0_TX_CLK = 0x00,
|
|
|
|
CLKSRC_MII0_RX_CLK = 0x01,
|
|
|
|
CLKSRC_MII1_TX_CLK = 0x02,
|
|
|
|
CLKSRC_MII1_RX_CLK = 0x03,
|
|
|
|
CLKSRC_MII2_TX_CLK = 0x04,
|
|
|
|
CLKSRC_MII2_RX_CLK = 0x05,
|
|
|
|
CLKSRC_MII3_TX_CLK = 0x06,
|
|
|
|
CLKSRC_MII3_RX_CLK = 0x07,
|
|
|
|
CLKSRC_MII4_TX_CLK = 0x08,
|
|
|
|
CLKSRC_MII4_RX_CLK = 0x09,
|
|
|
|
CLKSRC_PLL0 = 0x0B,
|
|
|
|
CLKSRC_PLL1 = 0x0E,
|
|
|
|
CLKSRC_IDIV0 = 0x11,
|
|
|
|
CLKSRC_IDIV1 = 0x12,
|
|
|
|
CLKSRC_IDIV2 = 0x13,
|
|
|
|
CLKSRC_IDIV3 = 0x14,
|
|
|
|
CLKSRC_IDIV4 = 0x15,
|
|
|
|
};
|
|
|
|
|
|
|
|
/* UM10944 Table 83.
|
|
|
|
* MIIx clock control registers 1 to 30
|
|
|
|
* (addresses 100013h to 100035h)
|
|
|
|
*/
|
|
|
|
struct sja1105_cgu_mii_ctrl {
|
|
|
|
u64 clksrc;
|
|
|
|
u64 autoblock;
|
|
|
|
u64 pd;
|
|
|
|
};
|
|
|
|
|
|
|
|
static void sja1105_cgu_idiv_packing(void *buf, struct sja1105_cgu_idiv *idiv,
|
|
|
|
enum packing_op op)
|
|
|
|
{
|
|
|
|
const int size = 4;
|
|
|
|
|
|
|
|
sja1105_packing(buf, &idiv->clksrc, 28, 24, size, op);
|
|
|
|
sja1105_packing(buf, &idiv->autoblock, 11, 11, size, op);
|
|
|
|
sja1105_packing(buf, &idiv->idiv, 5, 2, size, op);
|
|
|
|
sja1105_packing(buf, &idiv->pd, 0, 0, size, op);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int sja1105_cgu_idiv_config(struct sja1105_private *priv, int port,
|
|
|
|
bool enabled, int factor)
|
|
|
|
{
|
|
|
|
const struct sja1105_regs *regs = priv->info->regs;
|
|
|
|
struct device *dev = priv->ds->dev;
|
|
|
|
struct sja1105_cgu_idiv idiv;
|
|
|
|
u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
|
|
|
|
|
2021-05-24 16:14:17 +03:00
|
|
|
if (regs->cgu_idiv[port] == SJA1105_RSV_ADDR)
|
|
|
|
return 0;
|
|
|
|
|
2019-05-02 23:23:30 +03:00
|
|
|
if (enabled && factor != 1 && factor != 10) {
|
|
|
|
dev_err(dev, "idiv factor must be 1 or 10\n");
|
|
|
|
return -ERANGE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Payload for packed_buf */
|
|
|
|
idiv.clksrc = 0x0A; /* 25MHz */
|
|
|
|
idiv.autoblock = 1; /* Block clk automatically */
|
|
|
|
idiv.idiv = factor - 1; /* Divide by 1 or 10 */
|
|
|
|
idiv.pd = enabled ? 0 : 1; /* Power down? */
|
|
|
|
sja1105_cgu_idiv_packing(packed_buf, &idiv, PACK);
|
|
|
|
|
2019-10-01 22:18:01 +03:00
|
|
|
return sja1105_xfer_buf(priv, SPI_WRITE, regs->cgu_idiv[port],
|
|
|
|
packed_buf, SJA1105_SIZE_CGU_CMD);
|
2019-05-02 23:23:30 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
sja1105_cgu_mii_control_packing(void *buf, struct sja1105_cgu_mii_ctrl *cmd,
|
|
|
|
enum packing_op op)
|
|
|
|
{
|
|
|
|
const int size = 4;
|
|
|
|
|
|
|
|
sja1105_packing(buf, &cmd->clksrc, 28, 24, size, op);
|
|
|
|
sja1105_packing(buf, &cmd->autoblock, 11, 11, size, op);
|
|
|
|
sja1105_packing(buf, &cmd->pd, 0, 0, size, op);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int sja1105_cgu_mii_tx_clk_config(struct sja1105_private *priv,
|
|
|
|
int port, sja1105_mii_role_t role)
|
|
|
|
{
|
|
|
|
const struct sja1105_regs *regs = priv->info->regs;
|
|
|
|
struct sja1105_cgu_mii_ctrl mii_tx_clk;
|
2023-09-19 10:36:06 +01:00
|
|
|
static const int mac_clk_sources[] = {
|
2019-05-02 23:23:30 +03:00
|
|
|
CLKSRC_MII0_TX_CLK,
|
|
|
|
CLKSRC_MII1_TX_CLK,
|
|
|
|
CLKSRC_MII2_TX_CLK,
|
|
|
|
CLKSRC_MII3_TX_CLK,
|
|
|
|
CLKSRC_MII4_TX_CLK,
|
|
|
|
};
|
2023-09-19 10:36:06 +01:00
|
|
|
static const int phy_clk_sources[] = {
|
2019-05-02 23:23:30 +03:00
|
|
|
CLKSRC_IDIV0,
|
|
|
|
CLKSRC_IDIV1,
|
|
|
|
CLKSRC_IDIV2,
|
|
|
|
CLKSRC_IDIV3,
|
|
|
|
CLKSRC_IDIV4,
|
|
|
|
};
|
|
|
|
u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
|
|
|
|
int clksrc;
|
|
|
|
|
2021-05-24 16:14:17 +03:00
|
|
|
if (regs->mii_tx_clk[port] == SJA1105_RSV_ADDR)
|
|
|
|
return 0;
|
|
|
|
|
2019-05-02 23:23:30 +03:00
|
|
|
if (role == XMII_MAC)
|
|
|
|
clksrc = mac_clk_sources[port];
|
|
|
|
else
|
|
|
|
clksrc = phy_clk_sources[port];
|
|
|
|
|
|
|
|
/* Payload for packed_buf */
|
|
|
|
mii_tx_clk.clksrc = clksrc;
|
|
|
|
mii_tx_clk.autoblock = 1; /* Autoblock clk while changing clksrc */
|
|
|
|
mii_tx_clk.pd = 0; /* Power Down off => enabled */
|
|
|
|
sja1105_cgu_mii_control_packing(packed_buf, &mii_tx_clk, PACK);
|
|
|
|
|
2019-10-01 22:18:01 +03:00
|
|
|
return sja1105_xfer_buf(priv, SPI_WRITE, regs->mii_tx_clk[port],
|
|
|
|
packed_buf, SJA1105_SIZE_CGU_CMD);
|
2019-05-02 23:23:30 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
sja1105_cgu_mii_rx_clk_config(struct sja1105_private *priv, int port)
|
|
|
|
{
|
|
|
|
const struct sja1105_regs *regs = priv->info->regs;
|
|
|
|
struct sja1105_cgu_mii_ctrl mii_rx_clk;
|
|
|
|
u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
|
2023-09-19 10:36:06 +01:00
|
|
|
static const int clk_sources[] = {
|
2019-05-02 23:23:30 +03:00
|
|
|
CLKSRC_MII0_RX_CLK,
|
|
|
|
CLKSRC_MII1_RX_CLK,
|
|
|
|
CLKSRC_MII2_RX_CLK,
|
|
|
|
CLKSRC_MII3_RX_CLK,
|
|
|
|
CLKSRC_MII4_RX_CLK,
|
|
|
|
};
|
|
|
|
|
2021-05-24 16:14:17 +03:00
|
|
|
if (regs->mii_rx_clk[port] == SJA1105_RSV_ADDR)
|
|
|
|
return 0;
|
|
|
|
|
2019-05-02 23:23:30 +03:00
|
|
|
/* Payload for packed_buf */
|
|
|
|
mii_rx_clk.clksrc = clk_sources[port];
|
|
|
|
mii_rx_clk.autoblock = 1; /* Autoblock clk while changing clksrc */
|
|
|
|
mii_rx_clk.pd = 0; /* Power Down off => enabled */
|
|
|
|
sja1105_cgu_mii_control_packing(packed_buf, &mii_rx_clk, PACK);
|
|
|
|
|
2019-10-01 22:18:01 +03:00
|
|
|
return sja1105_xfer_buf(priv, SPI_WRITE, regs->mii_rx_clk[port],
|
|
|
|
packed_buf, SJA1105_SIZE_CGU_CMD);
|
2019-05-02 23:23:30 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
sja1105_cgu_mii_ext_tx_clk_config(struct sja1105_private *priv, int port)
|
|
|
|
{
|
|
|
|
const struct sja1105_regs *regs = priv->info->regs;
|
|
|
|
struct sja1105_cgu_mii_ctrl mii_ext_tx_clk;
|
|
|
|
u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
|
2023-09-19 10:36:06 +01:00
|
|
|
static const int clk_sources[] = {
|
2019-05-02 23:23:30 +03:00
|
|
|
CLKSRC_IDIV0,
|
|
|
|
CLKSRC_IDIV1,
|
|
|
|
CLKSRC_IDIV2,
|
|
|
|
CLKSRC_IDIV3,
|
|
|
|
CLKSRC_IDIV4,
|
|
|
|
};
|
|
|
|
|
2021-05-24 16:14:17 +03:00
|
|
|
if (regs->mii_ext_tx_clk[port] == SJA1105_RSV_ADDR)
|
|
|
|
return 0;
|
|
|
|
|
2019-05-02 23:23:30 +03:00
|
|
|
/* Payload for packed_buf */
|
|
|
|
mii_ext_tx_clk.clksrc = clk_sources[port];
|
|
|
|
mii_ext_tx_clk.autoblock = 1; /* Autoblock clk while changing clksrc */
|
|
|
|
mii_ext_tx_clk.pd = 0; /* Power Down off => enabled */
|
|
|
|
sja1105_cgu_mii_control_packing(packed_buf, &mii_ext_tx_clk, PACK);
|
|
|
|
|
2019-10-01 22:18:01 +03:00
|
|
|
return sja1105_xfer_buf(priv, SPI_WRITE, regs->mii_ext_tx_clk[port],
|
|
|
|
packed_buf, SJA1105_SIZE_CGU_CMD);
|
2019-05-02 23:23:30 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
sja1105_cgu_mii_ext_rx_clk_config(struct sja1105_private *priv, int port)
|
|
|
|
{
|
|
|
|
const struct sja1105_regs *regs = priv->info->regs;
|
|
|
|
struct sja1105_cgu_mii_ctrl mii_ext_rx_clk;
|
|
|
|
u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
|
2023-09-19 10:36:06 +01:00
|
|
|
static const int clk_sources[] = {
|
2019-05-02 23:23:30 +03:00
|
|
|
CLKSRC_IDIV0,
|
|
|
|
CLKSRC_IDIV1,
|
|
|
|
CLKSRC_IDIV2,
|
|
|
|
CLKSRC_IDIV3,
|
|
|
|
CLKSRC_IDIV4,
|
|
|
|
};
|
|
|
|
|
2021-05-24 16:14:17 +03:00
|
|
|
if (regs->mii_ext_rx_clk[port] == SJA1105_RSV_ADDR)
|
|
|
|
return 0;
|
|
|
|
|
2019-05-02 23:23:30 +03:00
|
|
|
/* Payload for packed_buf */
|
|
|
|
mii_ext_rx_clk.clksrc = clk_sources[port];
|
|
|
|
mii_ext_rx_clk.autoblock = 1; /* Autoblock clk while changing clksrc */
|
|
|
|
mii_ext_rx_clk.pd = 0; /* Power Down off => enabled */
|
|
|
|
sja1105_cgu_mii_control_packing(packed_buf, &mii_ext_rx_clk, PACK);
|
|
|
|
|
2019-10-01 22:18:01 +03:00
|
|
|
return sja1105_xfer_buf(priv, SPI_WRITE, regs->mii_ext_rx_clk[port],
|
|
|
|
packed_buf, SJA1105_SIZE_CGU_CMD);
|
2019-05-02 23:23:30 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static int sja1105_mii_clocking_setup(struct sja1105_private *priv, int port,
|
|
|
|
sja1105_mii_role_t role)
|
|
|
|
{
|
|
|
|
struct device *dev = priv->ds->dev;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
dev_dbg(dev, "Configuring MII-%s clocking\n",
|
|
|
|
(role == XMII_MAC) ? "MAC" : "PHY");
|
|
|
|
/* If role is MAC, disable IDIV
|
|
|
|
* If role is PHY, enable IDIV and configure for 1/1 divider
|
|
|
|
*/
|
|
|
|
rc = sja1105_cgu_idiv_config(priv, port, (role == XMII_PHY), 1);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
/* Configure CLKSRC of MII_TX_CLK_n
|
|
|
|
* * If role is MAC, select TX_CLK_n
|
|
|
|
* * If role is PHY, select IDIV_n
|
|
|
|
*/
|
|
|
|
rc = sja1105_cgu_mii_tx_clk_config(priv, port, role);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
/* Configure CLKSRC of MII_RX_CLK_n
|
|
|
|
* Select RX_CLK_n
|
|
|
|
*/
|
|
|
|
rc = sja1105_cgu_mii_rx_clk_config(priv, port);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
if (role == XMII_PHY) {
|
|
|
|
/* Per MII spec, the PHY (which is us) drives the TX_CLK pin */
|
|
|
|
|
|
|
|
/* Configure CLKSRC of EXT_TX_CLK_n
|
|
|
|
* Select IDIV_n
|
|
|
|
*/
|
|
|
|
rc = sja1105_cgu_mii_ext_tx_clk_config(priv, port);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
/* Configure CLKSRC of EXT_RX_CLK_n
|
|
|
|
* Select IDIV_n
|
|
|
|
*/
|
|
|
|
rc = sja1105_cgu_mii_ext_rx_clk_config(priv, port);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
sja1105_cgu_pll_control_packing(void *buf, struct sja1105_cgu_pll_ctrl *cmd,
|
|
|
|
enum packing_op op)
|
|
|
|
{
|
|
|
|
const int size = 4;
|
|
|
|
|
|
|
|
sja1105_packing(buf, &cmd->pllclksrc, 28, 24, size, op);
|
|
|
|
sja1105_packing(buf, &cmd->msel, 23, 16, size, op);
|
|
|
|
sja1105_packing(buf, &cmd->autoblock, 11, 11, size, op);
|
|
|
|
sja1105_packing(buf, &cmd->psel, 9, 8, size, op);
|
|
|
|
sja1105_packing(buf, &cmd->direct, 7, 7, size, op);
|
|
|
|
sja1105_packing(buf, &cmd->fbsel, 6, 6, size, op);
|
|
|
|
sja1105_packing(buf, &cmd->bypass, 1, 1, size, op);
|
|
|
|
sja1105_packing(buf, &cmd->pd, 0, 0, size, op);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int sja1105_cgu_rgmii_tx_clk_config(struct sja1105_private *priv,
|
2021-05-31 01:59:37 +03:00
|
|
|
int port, u64 speed)
|
2019-05-02 23:23:30 +03:00
|
|
|
{
|
|
|
|
const struct sja1105_regs *regs = priv->info->regs;
|
|
|
|
struct sja1105_cgu_mii_ctrl txc;
|
|
|
|
u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
|
|
|
|
int clksrc;
|
|
|
|
|
2021-05-24 16:14:17 +03:00
|
|
|
if (regs->rgmii_tx_clk[port] == SJA1105_RSV_ADDR)
|
|
|
|
return 0;
|
|
|
|
|
2021-05-31 01:59:37 +03:00
|
|
|
if (speed == priv->info->port_speed[SJA1105_SPEED_1000MBPS]) {
|
2019-05-02 23:23:30 +03:00
|
|
|
clksrc = CLKSRC_PLL0;
|
|
|
|
} else {
|
2023-09-19 10:36:06 +01:00
|
|
|
static const int clk_sources[] = {
|
|
|
|
CLKSRC_IDIV0,
|
|
|
|
CLKSRC_IDIV1,
|
|
|
|
CLKSRC_IDIV2,
|
|
|
|
CLKSRC_IDIV3,
|
|
|
|
CLKSRC_IDIV4,
|
|
|
|
};
|
2019-05-02 23:23:30 +03:00
|
|
|
clksrc = clk_sources[port];
|
|
|
|
}
|
|
|
|
|
|
|
|
/* RGMII: 125MHz for 1000, 25MHz for 100, 2.5MHz for 10 */
|
|
|
|
txc.clksrc = clksrc;
|
|
|
|
/* Autoblock clk while changing clksrc */
|
|
|
|
txc.autoblock = 1;
|
|
|
|
/* Power Down off => enabled */
|
|
|
|
txc.pd = 0;
|
|
|
|
sja1105_cgu_mii_control_packing(packed_buf, &txc, PACK);
|
|
|
|
|
2019-10-01 22:18:01 +03:00
|
|
|
return sja1105_xfer_buf(priv, SPI_WRITE, regs->rgmii_tx_clk[port],
|
|
|
|
packed_buf, SJA1105_SIZE_CGU_CMD);
|
2019-05-02 23:23:30 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* AGU */
|
|
|
|
static void
|
net: dsa: sja1105: enable internal pull-down for RX_DV/CRS_DV/RX_CTL and RX_ER
Some boards do not have the RX_ER MII signal connected. Normally in such
situation, those pins would be grounded, but then again, some boards
left it electrically floating.
When sending traffic to those switch ports, one can see that the
N_SOFERR statistics counter is incrementing once per each packet. The
user manual states for this counter that it may count the number of
frames "that have the MII error input being asserted prior to or
up to the SOF delimiter byte". So the switch MAC is sampling an
electrically floating signal, and preventing proper traffic reception
because of that.
As a workaround, enable the internal weak pull-downs on the input pads
for the MII control signals. This way, a floating signal would be
internally tied to ground.
The logic levels of signals which _are_ externally driven should not be
bothered by this 40-50 KOhm internal resistor. So it is not an issue to
enable the internal pull-down unconditionally, irrespective of PHY
interface type (MII, RMII, RGMII, SGMII) and of board layout.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-04-17 22:50:52 +03:00
|
|
|
sja1105_cfg_pad_mii_packing(void *buf, struct sja1105_cfg_pad_mii *cmd,
|
|
|
|
enum packing_op op)
|
2019-05-02 23:23:30 +03:00
|
|
|
{
|
|
|
|
const int size = 4;
|
|
|
|
|
|
|
|
sja1105_packing(buf, &cmd->d32_os, 28, 27, size, op);
|
net: dsa: sja1105: enable internal pull-down for RX_DV/CRS_DV/RX_CTL and RX_ER
Some boards do not have the RX_ER MII signal connected. Normally in such
situation, those pins would be grounded, but then again, some boards
left it electrically floating.
When sending traffic to those switch ports, one can see that the
N_SOFERR statistics counter is incrementing once per each packet. The
user manual states for this counter that it may count the number of
frames "that have the MII error input being asserted prior to or
up to the SOF delimiter byte". So the switch MAC is sampling an
electrically floating signal, and preventing proper traffic reception
because of that.
As a workaround, enable the internal weak pull-downs on the input pads
for the MII control signals. This way, a floating signal would be
internally tied to ground.
The logic levels of signals which _are_ externally driven should not be
bothered by this 40-50 KOhm internal resistor. So it is not an issue to
enable the internal pull-down unconditionally, irrespective of PHY
interface type (MII, RMII, RGMII, SGMII) and of board layout.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-04-17 22:50:52 +03:00
|
|
|
sja1105_packing(buf, &cmd->d32_ih, 26, 26, size, op);
|
2019-05-02 23:23:30 +03:00
|
|
|
sja1105_packing(buf, &cmd->d32_ipud, 25, 24, size, op);
|
|
|
|
sja1105_packing(buf, &cmd->d10_os, 20, 19, size, op);
|
net: dsa: sja1105: enable internal pull-down for RX_DV/CRS_DV/RX_CTL and RX_ER
Some boards do not have the RX_ER MII signal connected. Normally in such
situation, those pins would be grounded, but then again, some boards
left it electrically floating.
When sending traffic to those switch ports, one can see that the
N_SOFERR statistics counter is incrementing once per each packet. The
user manual states for this counter that it may count the number of
frames "that have the MII error input being asserted prior to or
up to the SOF delimiter byte". So the switch MAC is sampling an
electrically floating signal, and preventing proper traffic reception
because of that.
As a workaround, enable the internal weak pull-downs on the input pads
for the MII control signals. This way, a floating signal would be
internally tied to ground.
The logic levels of signals which _are_ externally driven should not be
bothered by this 40-50 KOhm internal resistor. So it is not an issue to
enable the internal pull-down unconditionally, irrespective of PHY
interface type (MII, RMII, RGMII, SGMII) and of board layout.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-04-17 22:50:52 +03:00
|
|
|
sja1105_packing(buf, &cmd->d10_ih, 18, 18, size, op);
|
2019-05-02 23:23:30 +03:00
|
|
|
sja1105_packing(buf, &cmd->d10_ipud, 17, 16, size, op);
|
|
|
|
sja1105_packing(buf, &cmd->ctrl_os, 12, 11, size, op);
|
net: dsa: sja1105: enable internal pull-down for RX_DV/CRS_DV/RX_CTL and RX_ER
Some boards do not have the RX_ER MII signal connected. Normally in such
situation, those pins would be grounded, but then again, some boards
left it electrically floating.
When sending traffic to those switch ports, one can see that the
N_SOFERR statistics counter is incrementing once per each packet. The
user manual states for this counter that it may count the number of
frames "that have the MII error input being asserted prior to or
up to the SOF delimiter byte". So the switch MAC is sampling an
electrically floating signal, and preventing proper traffic reception
because of that.
As a workaround, enable the internal weak pull-downs on the input pads
for the MII control signals. This way, a floating signal would be
internally tied to ground.
The logic levels of signals which _are_ externally driven should not be
bothered by this 40-50 KOhm internal resistor. So it is not an issue to
enable the internal pull-down unconditionally, irrespective of PHY
interface type (MII, RMII, RGMII, SGMII) and of board layout.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-04-17 22:50:52 +03:00
|
|
|
sja1105_packing(buf, &cmd->ctrl_ih, 10, 10, size, op);
|
2019-05-02 23:23:30 +03:00
|
|
|
sja1105_packing(buf, &cmd->ctrl_ipud, 9, 8, size, op);
|
|
|
|
sja1105_packing(buf, &cmd->clk_os, 4, 3, size, op);
|
|
|
|
sja1105_packing(buf, &cmd->clk_ih, 2, 2, size, op);
|
|
|
|
sja1105_packing(buf, &cmd->clk_ipud, 1, 0, size, op);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int sja1105_rgmii_cfg_pad_tx_config(struct sja1105_private *priv,
|
|
|
|
int port)
|
|
|
|
{
|
|
|
|
const struct sja1105_regs *regs = priv->info->regs;
|
net: dsa: sja1105: enable internal pull-down for RX_DV/CRS_DV/RX_CTL and RX_ER
Some boards do not have the RX_ER MII signal connected. Normally in such
situation, those pins would be grounded, but then again, some boards
left it electrically floating.
When sending traffic to those switch ports, one can see that the
N_SOFERR statistics counter is incrementing once per each packet. The
user manual states for this counter that it may count the number of
frames "that have the MII error input being asserted prior to or
up to the SOF delimiter byte". So the switch MAC is sampling an
electrically floating signal, and preventing proper traffic reception
because of that.
As a workaround, enable the internal weak pull-downs on the input pads
for the MII control signals. This way, a floating signal would be
internally tied to ground.
The logic levels of signals which _are_ externally driven should not be
bothered by this 40-50 KOhm internal resistor. So it is not an issue to
enable the internal pull-down unconditionally, irrespective of PHY
interface type (MII, RMII, RGMII, SGMII) and of board layout.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-04-17 22:50:52 +03:00
|
|
|
struct sja1105_cfg_pad_mii pad_mii_tx = {0};
|
2019-05-02 23:23:30 +03:00
|
|
|
u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
|
|
|
|
|
2021-05-24 16:14:17 +03:00
|
|
|
if (regs->pad_mii_tx[port] == SJA1105_RSV_ADDR)
|
|
|
|
return 0;
|
|
|
|
|
2019-05-02 23:23:30 +03:00
|
|
|
/* Payload */
|
|
|
|
pad_mii_tx.d32_os = 3; /* TXD[3:2] output stage: */
|
|
|
|
/* high noise/high speed */
|
|
|
|
pad_mii_tx.d10_os = 3; /* TXD[1:0] output stage: */
|
|
|
|
/* high noise/high speed */
|
|
|
|
pad_mii_tx.d32_ipud = 2; /* TXD[3:2] input stage: */
|
|
|
|
/* plain input (default) */
|
|
|
|
pad_mii_tx.d10_ipud = 2; /* TXD[1:0] input stage: */
|
|
|
|
/* plain input (default) */
|
|
|
|
pad_mii_tx.ctrl_os = 3; /* TX_CTL / TX_ER output stage */
|
|
|
|
pad_mii_tx.ctrl_ipud = 2; /* TX_CTL / TX_ER input stage (default) */
|
|
|
|
pad_mii_tx.clk_os = 3; /* TX_CLK output stage */
|
|
|
|
pad_mii_tx.clk_ih = 0; /* TX_CLK input hysteresis (default) */
|
|
|
|
pad_mii_tx.clk_ipud = 2; /* TX_CLK input stage (default) */
|
net: dsa: sja1105: enable internal pull-down for RX_DV/CRS_DV/RX_CTL and RX_ER
Some boards do not have the RX_ER MII signal connected. Normally in such
situation, those pins would be grounded, but then again, some boards
left it electrically floating.
When sending traffic to those switch ports, one can see that the
N_SOFERR statistics counter is incrementing once per each packet. The
user manual states for this counter that it may count the number of
frames "that have the MII error input being asserted prior to or
up to the SOF delimiter byte". So the switch MAC is sampling an
electrically floating signal, and preventing proper traffic reception
because of that.
As a workaround, enable the internal weak pull-downs on the input pads
for the MII control signals. This way, a floating signal would be
internally tied to ground.
The logic levels of signals which _are_ externally driven should not be
bothered by this 40-50 KOhm internal resistor. So it is not an issue to
enable the internal pull-down unconditionally, irrespective of PHY
interface type (MII, RMII, RGMII, SGMII) and of board layout.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-04-17 22:50:52 +03:00
|
|
|
sja1105_cfg_pad_mii_packing(packed_buf, &pad_mii_tx, PACK);
|
2019-05-02 23:23:30 +03:00
|
|
|
|
2019-10-01 22:18:01 +03:00
|
|
|
return sja1105_xfer_buf(priv, SPI_WRITE, regs->pad_mii_tx[port],
|
|
|
|
packed_buf, SJA1105_SIZE_CGU_CMD);
|
2019-05-02 23:23:30 +03:00
|
|
|
}
|
|
|
|
|
net: dsa: sja1105: enable internal pull-down for RX_DV/CRS_DV/RX_CTL and RX_ER
Some boards do not have the RX_ER MII signal connected. Normally in such
situation, those pins would be grounded, but then again, some boards
left it electrically floating.
When sending traffic to those switch ports, one can see that the
N_SOFERR statistics counter is incrementing once per each packet. The
user manual states for this counter that it may count the number of
frames "that have the MII error input being asserted prior to or
up to the SOF delimiter byte". So the switch MAC is sampling an
electrically floating signal, and preventing proper traffic reception
because of that.
As a workaround, enable the internal weak pull-downs on the input pads
for the MII control signals. This way, a floating signal would be
internally tied to ground.
The logic levels of signals which _are_ externally driven should not be
bothered by this 40-50 KOhm internal resistor. So it is not an issue to
enable the internal pull-down unconditionally, irrespective of PHY
interface type (MII, RMII, RGMII, SGMII) and of board layout.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-04-17 22:50:52 +03:00
|
|
|
static int sja1105_cfg_pad_rx_config(struct sja1105_private *priv, int port)
|
|
|
|
{
|
|
|
|
const struct sja1105_regs *regs = priv->info->regs;
|
|
|
|
struct sja1105_cfg_pad_mii pad_mii_rx = {0};
|
|
|
|
u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
|
|
|
|
|
2021-05-24 16:14:17 +03:00
|
|
|
if (regs->pad_mii_rx[port] == SJA1105_RSV_ADDR)
|
|
|
|
return 0;
|
|
|
|
|
net: dsa: sja1105: enable internal pull-down for RX_DV/CRS_DV/RX_CTL and RX_ER
Some boards do not have the RX_ER MII signal connected. Normally in such
situation, those pins would be grounded, but then again, some boards
left it electrically floating.
When sending traffic to those switch ports, one can see that the
N_SOFERR statistics counter is incrementing once per each packet. The
user manual states for this counter that it may count the number of
frames "that have the MII error input being asserted prior to or
up to the SOF delimiter byte". So the switch MAC is sampling an
electrically floating signal, and preventing proper traffic reception
because of that.
As a workaround, enable the internal weak pull-downs on the input pads
for the MII control signals. This way, a floating signal would be
internally tied to ground.
The logic levels of signals which _are_ externally driven should not be
bothered by this 40-50 KOhm internal resistor. So it is not an issue to
enable the internal pull-down unconditionally, irrespective of PHY
interface type (MII, RMII, RGMII, SGMII) and of board layout.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-04-17 22:50:52 +03:00
|
|
|
/* Payload */
|
|
|
|
pad_mii_rx.d32_ih = 0; /* RXD[3:2] input stage hysteresis: */
|
|
|
|
/* non-Schmitt (default) */
|
|
|
|
pad_mii_rx.d32_ipud = 2; /* RXD[3:2] input weak pull-up/down */
|
|
|
|
/* plain input (default) */
|
|
|
|
pad_mii_rx.d10_ih = 0; /* RXD[1:0] input stage hysteresis: */
|
|
|
|
/* non-Schmitt (default) */
|
|
|
|
pad_mii_rx.d10_ipud = 2; /* RXD[1:0] input weak pull-up/down */
|
|
|
|
/* plain input (default) */
|
|
|
|
pad_mii_rx.ctrl_ih = 0; /* RX_DV/CRS_DV/RX_CTL and RX_ER */
|
|
|
|
/* input stage hysteresis: */
|
|
|
|
/* non-Schmitt (default) */
|
|
|
|
pad_mii_rx.ctrl_ipud = 3; /* RX_DV/CRS_DV/RX_CTL and RX_ER */
|
|
|
|
/* input stage weak pull-up/down: */
|
|
|
|
/* pull-down */
|
|
|
|
pad_mii_rx.clk_os = 2; /* RX_CLK/RXC output stage: */
|
|
|
|
/* medium noise/fast speed (default) */
|
|
|
|
pad_mii_rx.clk_ih = 0; /* RX_CLK/RXC input hysteresis: */
|
|
|
|
/* non-Schmitt (default) */
|
|
|
|
pad_mii_rx.clk_ipud = 2; /* RX_CLK/RXC input pull-up/down: */
|
|
|
|
/* plain input (default) */
|
|
|
|
sja1105_cfg_pad_mii_packing(packed_buf, &pad_mii_rx, PACK);
|
|
|
|
|
|
|
|
return sja1105_xfer_buf(priv, SPI_WRITE, regs->pad_mii_rx[port],
|
|
|
|
packed_buf, SJA1105_SIZE_CGU_CMD);
|
|
|
|
}
|
|
|
|
|
2019-06-08 19:12:28 +03:00
|
|
|
static void
|
|
|
|
sja1105_cfg_pad_mii_id_packing(void *buf, struct sja1105_cfg_pad_mii_id *cmd,
|
|
|
|
enum packing_op op)
|
|
|
|
{
|
|
|
|
const int size = SJA1105_SIZE_CGU_CMD;
|
|
|
|
|
|
|
|
sja1105_packing(buf, &cmd->rxc_stable_ovr, 15, 15, size, op);
|
|
|
|
sja1105_packing(buf, &cmd->rxc_delay, 14, 10, size, op);
|
|
|
|
sja1105_packing(buf, &cmd->rxc_bypass, 9, 9, size, op);
|
|
|
|
sja1105_packing(buf, &cmd->rxc_pd, 8, 8, size, op);
|
|
|
|
sja1105_packing(buf, &cmd->txc_stable_ovr, 7, 7, size, op);
|
|
|
|
sja1105_packing(buf, &cmd->txc_delay, 6, 2, size, op);
|
|
|
|
sja1105_packing(buf, &cmd->txc_bypass, 1, 1, size, op);
|
|
|
|
sja1105_packing(buf, &cmd->txc_pd, 0, 0, size, op);
|
|
|
|
}
|
|
|
|
|
net: dsa: sja1105: add support for the SJA1110 switch family
The SJA1110 is basically an SJA1105 with more ports, some integrated
PHYs (100base-T1 and 100base-TX) and an embedded microcontroller which
can be disabled, and the switch core can be controlled by a host running
Linux, over SPI.
This patch contains:
- the static and dynamic config packing functions, for the tables that
are common with SJA1105
- one more static config tables which is "unique" to the SJA1110
(actually it is a rehash of stuff that was placed somewhere else in
SJA1105): the PCP Remapping Table
- a reset and clock configuration procedure for the SJA1110 switch.
This resets just the switch subsystem, and gates off the clock which
powers on the embedded microcontroller.
- an RGMII delay configuration procedure for SJA1110, which is very
similar to SJA1105, but different enough for us to be unable to reuse
it (this is a pattern that repeats itself)
- some adaptations to dynamic config table entries which are no longer
programmed in the same way. For example, to delete a VLAN, you used to
write an entry through the dynamic reconfiguration interface with the
desired VLAN ID, and with the VALIDENT bit set to false. Now, the VLAN
table entries contain a TYPE_ENTRY field, which must be set to zero
(in a backwards-incompatible way) in order for the entry to be deleted,
or to some other entry for the VLAN to match "inner tagged" or "outer
tagged" packets.
- a similar thing for the static config: the xMII Mode Parameters Table
encoding for SGMII and MII (the latter just when attached to a
100base-TX PHY) just isn't what it used to be in SJA1105. They are
identical, except there is an extra "special" bit which needs to be
set. Set it.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-06-08 12:25:36 +03:00
|
|
|
static void
|
|
|
|
sja1110_cfg_pad_mii_id_packing(void *buf, struct sja1105_cfg_pad_mii_id *cmd,
|
|
|
|
enum packing_op op)
|
|
|
|
{
|
|
|
|
const int size = SJA1105_SIZE_CGU_CMD;
|
|
|
|
u64 range = 4;
|
|
|
|
|
|
|
|
/* Fields RXC_RANGE and TXC_RANGE select the input frequency range:
|
|
|
|
* 0 = 2.5MHz
|
|
|
|
* 1 = 25MHz
|
|
|
|
* 2 = 50MHz
|
|
|
|
* 3 = 125MHz
|
|
|
|
* 4 = Automatically determined by port speed.
|
|
|
|
* There's no point in defining a structure different than the one for
|
|
|
|
* SJA1105, so just hardcode the frequency range to automatic, just as
|
|
|
|
* before.
|
|
|
|
*/
|
|
|
|
sja1105_packing(buf, &cmd->rxc_stable_ovr, 26, 26, size, op);
|
|
|
|
sja1105_packing(buf, &cmd->rxc_delay, 25, 21, size, op);
|
|
|
|
sja1105_packing(buf, &range, 20, 18, size, op);
|
|
|
|
sja1105_packing(buf, &cmd->rxc_bypass, 17, 17, size, op);
|
|
|
|
sja1105_packing(buf, &cmd->rxc_pd, 16, 16, size, op);
|
|
|
|
sja1105_packing(buf, &cmd->txc_stable_ovr, 10, 10, size, op);
|
|
|
|
sja1105_packing(buf, &cmd->txc_delay, 9, 5, size, op);
|
|
|
|
sja1105_packing(buf, &range, 4, 2, size, op);
|
|
|
|
sja1105_packing(buf, &cmd->txc_bypass, 1, 1, size, op);
|
|
|
|
sja1105_packing(buf, &cmd->txc_pd, 0, 0, size, op);
|
|
|
|
}
|
|
|
|
|
2019-06-08 19:12:28 +03:00
|
|
|
/* The RGMII delay setup procedure is 2-step and gets called upon each
|
|
|
|
* .phylink_mac_config. Both are strategic.
|
|
|
|
* The reason is that the RX Tunable Delay Line of the SJA1105 MAC has issues
|
|
|
|
* with recovering from a frequency change of the link partner's RGMII clock.
|
|
|
|
* The easiest way to recover from this is to temporarily power down the TDL,
|
|
|
|
* as it will re-lock at the new frequency afterwards.
|
|
|
|
*/
|
|
|
|
int sja1105pqrs_setup_rgmii_delay(const void *ctx, int port)
|
|
|
|
{
|
|
|
|
const struct sja1105_private *priv = ctx;
|
|
|
|
const struct sja1105_regs *regs = priv->info->regs;
|
|
|
|
struct sja1105_cfg_pad_mii_id pad_mii_id = {0};
|
net: dsa: sja1105: parse {rx, tx}-internal-delay-ps properties for RGMII delays
This change does not fix any functional issue or address any real life
use case that wasn't possible before. It is just a small step in the
process of standardizing the way in which Ethernet MAC drivers may apply
RGMII delays (traditionally these have been applied by PHYs, with no
clear definition of what to do in the case of a fixed-link).
The sja1105 driver used to apply MAC-level RGMII delays on the RX data
lines when in fixed-link mode and using a phy-mode of "rgmii-rxid" or
"rgmii-id" and on the TX data lines when using "rgmii-txid" or "rgmii-id".
But the standard definitions don't say anything about behaving
differently when the port is in fixed-link vs when it isn't, and the new
device tree bindings are about having a way of applying the delays in a
way that is independent of the phy-mode and of the fixed-link property.
When the {rx,tx}-internal-delay-ps properties are present, use them,
otherwise fall back to the old behavior and warn.
One other thing to note is that the SJA1105 hardware applies a delay
value in degrees rather than in picoseconds (the delay in ps changes
depending on the frequency of the RGMII clock - 125 MHz at 1G, 25 MHz at
100M, 2.5MHz at 10M). I assume that is fine, we calculate the phase
shift of the internal delay lines assuming that the device tree meant
gigabit, and we let the hardware scale those according to the link speed.
Link: https://patchwork.kernel.org/project/netdevbpf/patch/20210723173108.459770-6-prasanna.vengateshan@microchip.com/
Link: https://patchwork.ozlabs.org/project/netdev/patch/20200616074955.GA9092@laureti-dev/#2461123
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-10-18 22:29:52 +03:00
|
|
|
int rx_delay = priv->rgmii_rx_delay_ps[port];
|
|
|
|
int tx_delay = priv->rgmii_tx_delay_ps[port];
|
2019-06-08 19:12:28 +03:00
|
|
|
u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
|
|
|
|
int rc;
|
|
|
|
|
net: dsa: sja1105: parse {rx, tx}-internal-delay-ps properties for RGMII delays
This change does not fix any functional issue or address any real life
use case that wasn't possible before. It is just a small step in the
process of standardizing the way in which Ethernet MAC drivers may apply
RGMII delays (traditionally these have been applied by PHYs, with no
clear definition of what to do in the case of a fixed-link).
The sja1105 driver used to apply MAC-level RGMII delays on the RX data
lines when in fixed-link mode and using a phy-mode of "rgmii-rxid" or
"rgmii-id" and on the TX data lines when using "rgmii-txid" or "rgmii-id".
But the standard definitions don't say anything about behaving
differently when the port is in fixed-link vs when it isn't, and the new
device tree bindings are about having a way of applying the delays in a
way that is independent of the phy-mode and of the fixed-link property.
When the {rx,tx}-internal-delay-ps properties are present, use them,
otherwise fall back to the old behavior and warn.
One other thing to note is that the SJA1105 hardware applies a delay
value in degrees rather than in picoseconds (the delay in ps changes
depending on the frequency of the RGMII clock - 125 MHz at 1G, 25 MHz at
100M, 2.5MHz at 10M). I assume that is fine, we calculate the phase
shift of the internal delay lines assuming that the device tree meant
gigabit, and we let the hardware scale those according to the link speed.
Link: https://patchwork.kernel.org/project/netdevbpf/patch/20210723173108.459770-6-prasanna.vengateshan@microchip.com/
Link: https://patchwork.ozlabs.org/project/netdev/patch/20200616074955.GA9092@laureti-dev/#2461123
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-10-18 22:29:52 +03:00
|
|
|
if (rx_delay)
|
|
|
|
pad_mii_id.rxc_delay = SJA1105_RGMII_DELAY_PS_TO_HW(rx_delay);
|
|
|
|
if (tx_delay)
|
|
|
|
pad_mii_id.txc_delay = SJA1105_RGMII_DELAY_PS_TO_HW(tx_delay);
|
2019-06-08 19:12:28 +03:00
|
|
|
|
|
|
|
/* Stage 1: Turn the RGMII delay lines off. */
|
|
|
|
pad_mii_id.rxc_bypass = 1;
|
|
|
|
pad_mii_id.rxc_pd = 1;
|
|
|
|
pad_mii_id.txc_bypass = 1;
|
|
|
|
pad_mii_id.txc_pd = 1;
|
|
|
|
sja1105_cfg_pad_mii_id_packing(packed_buf, &pad_mii_id, PACK);
|
|
|
|
|
2019-10-01 22:18:01 +03:00
|
|
|
rc = sja1105_xfer_buf(priv, SPI_WRITE, regs->pad_mii_id[port],
|
|
|
|
packed_buf, SJA1105_SIZE_CGU_CMD);
|
2019-06-08 19:12:28 +03:00
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
/* Stage 2: Turn the RGMII delay lines on. */
|
net: dsa: sja1105: parse {rx, tx}-internal-delay-ps properties for RGMII delays
This change does not fix any functional issue or address any real life
use case that wasn't possible before. It is just a small step in the
process of standardizing the way in which Ethernet MAC drivers may apply
RGMII delays (traditionally these have been applied by PHYs, with no
clear definition of what to do in the case of a fixed-link).
The sja1105 driver used to apply MAC-level RGMII delays on the RX data
lines when in fixed-link mode and using a phy-mode of "rgmii-rxid" or
"rgmii-id" and on the TX data lines when using "rgmii-txid" or "rgmii-id".
But the standard definitions don't say anything about behaving
differently when the port is in fixed-link vs when it isn't, and the new
device tree bindings are about having a way of applying the delays in a
way that is independent of the phy-mode and of the fixed-link property.
When the {rx,tx}-internal-delay-ps properties are present, use them,
otherwise fall back to the old behavior and warn.
One other thing to note is that the SJA1105 hardware applies a delay
value in degrees rather than in picoseconds (the delay in ps changes
depending on the frequency of the RGMII clock - 125 MHz at 1G, 25 MHz at
100M, 2.5MHz at 10M). I assume that is fine, we calculate the phase
shift of the internal delay lines assuming that the device tree meant
gigabit, and we let the hardware scale those according to the link speed.
Link: https://patchwork.kernel.org/project/netdevbpf/patch/20210723173108.459770-6-prasanna.vengateshan@microchip.com/
Link: https://patchwork.ozlabs.org/project/netdev/patch/20200616074955.GA9092@laureti-dev/#2461123
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-10-18 22:29:52 +03:00
|
|
|
if (rx_delay) {
|
2019-06-08 19:12:28 +03:00
|
|
|
pad_mii_id.rxc_bypass = 0;
|
|
|
|
pad_mii_id.rxc_pd = 0;
|
|
|
|
}
|
net: dsa: sja1105: parse {rx, tx}-internal-delay-ps properties for RGMII delays
This change does not fix any functional issue or address any real life
use case that wasn't possible before. It is just a small step in the
process of standardizing the way in which Ethernet MAC drivers may apply
RGMII delays (traditionally these have been applied by PHYs, with no
clear definition of what to do in the case of a fixed-link).
The sja1105 driver used to apply MAC-level RGMII delays on the RX data
lines when in fixed-link mode and using a phy-mode of "rgmii-rxid" or
"rgmii-id" and on the TX data lines when using "rgmii-txid" or "rgmii-id".
But the standard definitions don't say anything about behaving
differently when the port is in fixed-link vs when it isn't, and the new
device tree bindings are about having a way of applying the delays in a
way that is independent of the phy-mode and of the fixed-link property.
When the {rx,tx}-internal-delay-ps properties are present, use them,
otherwise fall back to the old behavior and warn.
One other thing to note is that the SJA1105 hardware applies a delay
value in degrees rather than in picoseconds (the delay in ps changes
depending on the frequency of the RGMII clock - 125 MHz at 1G, 25 MHz at
100M, 2.5MHz at 10M). I assume that is fine, we calculate the phase
shift of the internal delay lines assuming that the device tree meant
gigabit, and we let the hardware scale those according to the link speed.
Link: https://patchwork.kernel.org/project/netdevbpf/patch/20210723173108.459770-6-prasanna.vengateshan@microchip.com/
Link: https://patchwork.ozlabs.org/project/netdev/patch/20200616074955.GA9092@laureti-dev/#2461123
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-10-18 22:29:52 +03:00
|
|
|
if (tx_delay) {
|
2019-06-08 19:12:28 +03:00
|
|
|
pad_mii_id.txc_bypass = 0;
|
|
|
|
pad_mii_id.txc_pd = 0;
|
|
|
|
}
|
|
|
|
sja1105_cfg_pad_mii_id_packing(packed_buf, &pad_mii_id, PACK);
|
|
|
|
|
2019-10-01 22:18:01 +03:00
|
|
|
return sja1105_xfer_buf(priv, SPI_WRITE, regs->pad_mii_id[port],
|
|
|
|
packed_buf, SJA1105_SIZE_CGU_CMD);
|
2019-06-08 19:12:28 +03:00
|
|
|
}
|
|
|
|
|
net: dsa: sja1105: add support for the SJA1110 switch family
The SJA1110 is basically an SJA1105 with more ports, some integrated
PHYs (100base-T1 and 100base-TX) and an embedded microcontroller which
can be disabled, and the switch core can be controlled by a host running
Linux, over SPI.
This patch contains:
- the static and dynamic config packing functions, for the tables that
are common with SJA1105
- one more static config tables which is "unique" to the SJA1110
(actually it is a rehash of stuff that was placed somewhere else in
SJA1105): the PCP Remapping Table
- a reset and clock configuration procedure for the SJA1110 switch.
This resets just the switch subsystem, and gates off the clock which
powers on the embedded microcontroller.
- an RGMII delay configuration procedure for SJA1110, which is very
similar to SJA1105, but different enough for us to be unable to reuse
it (this is a pattern that repeats itself)
- some adaptations to dynamic config table entries which are no longer
programmed in the same way. For example, to delete a VLAN, you used to
write an entry through the dynamic reconfiguration interface with the
desired VLAN ID, and with the VALIDENT bit set to false. Now, the VLAN
table entries contain a TYPE_ENTRY field, which must be set to zero
(in a backwards-incompatible way) in order for the entry to be deleted,
or to some other entry for the VLAN to match "inner tagged" or "outer
tagged" packets.
- a similar thing for the static config: the xMII Mode Parameters Table
encoding for SGMII and MII (the latter just when attached to a
100base-TX PHY) just isn't what it used to be in SJA1105. They are
identical, except there is an extra "special" bit which needs to be
set. Set it.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-06-08 12:25:36 +03:00
|
|
|
int sja1110_setup_rgmii_delay(const void *ctx, int port)
|
|
|
|
{
|
|
|
|
const struct sja1105_private *priv = ctx;
|
|
|
|
const struct sja1105_regs *regs = priv->info->regs;
|
|
|
|
struct sja1105_cfg_pad_mii_id pad_mii_id = {0};
|
net: dsa: sja1105: parse {rx, tx}-internal-delay-ps properties for RGMII delays
This change does not fix any functional issue or address any real life
use case that wasn't possible before. It is just a small step in the
process of standardizing the way in which Ethernet MAC drivers may apply
RGMII delays (traditionally these have been applied by PHYs, with no
clear definition of what to do in the case of a fixed-link).
The sja1105 driver used to apply MAC-level RGMII delays on the RX data
lines when in fixed-link mode and using a phy-mode of "rgmii-rxid" or
"rgmii-id" and on the TX data lines when using "rgmii-txid" or "rgmii-id".
But the standard definitions don't say anything about behaving
differently when the port is in fixed-link vs when it isn't, and the new
device tree bindings are about having a way of applying the delays in a
way that is independent of the phy-mode and of the fixed-link property.
When the {rx,tx}-internal-delay-ps properties are present, use them,
otherwise fall back to the old behavior and warn.
One other thing to note is that the SJA1105 hardware applies a delay
value in degrees rather than in picoseconds (the delay in ps changes
depending on the frequency of the RGMII clock - 125 MHz at 1G, 25 MHz at
100M, 2.5MHz at 10M). I assume that is fine, we calculate the phase
shift of the internal delay lines assuming that the device tree meant
gigabit, and we let the hardware scale those according to the link speed.
Link: https://patchwork.kernel.org/project/netdevbpf/patch/20210723173108.459770-6-prasanna.vengateshan@microchip.com/
Link: https://patchwork.ozlabs.org/project/netdev/patch/20200616074955.GA9092@laureti-dev/#2461123
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-10-18 22:29:52 +03:00
|
|
|
int rx_delay = priv->rgmii_rx_delay_ps[port];
|
|
|
|
int tx_delay = priv->rgmii_tx_delay_ps[port];
|
net: dsa: sja1105: add support for the SJA1110 switch family
The SJA1110 is basically an SJA1105 with more ports, some integrated
PHYs (100base-T1 and 100base-TX) and an embedded microcontroller which
can be disabled, and the switch core can be controlled by a host running
Linux, over SPI.
This patch contains:
- the static and dynamic config packing functions, for the tables that
are common with SJA1105
- one more static config tables which is "unique" to the SJA1110
(actually it is a rehash of stuff that was placed somewhere else in
SJA1105): the PCP Remapping Table
- a reset and clock configuration procedure for the SJA1110 switch.
This resets just the switch subsystem, and gates off the clock which
powers on the embedded microcontroller.
- an RGMII delay configuration procedure for SJA1110, which is very
similar to SJA1105, but different enough for us to be unable to reuse
it (this is a pattern that repeats itself)
- some adaptations to dynamic config table entries which are no longer
programmed in the same way. For example, to delete a VLAN, you used to
write an entry through the dynamic reconfiguration interface with the
desired VLAN ID, and with the VALIDENT bit set to false. Now, the VLAN
table entries contain a TYPE_ENTRY field, which must be set to zero
(in a backwards-incompatible way) in order for the entry to be deleted,
or to some other entry for the VLAN to match "inner tagged" or "outer
tagged" packets.
- a similar thing for the static config: the xMII Mode Parameters Table
encoding for SGMII and MII (the latter just when attached to a
100base-TX PHY) just isn't what it used to be in SJA1105. They are
identical, except there is an extra "special" bit which needs to be
set. Set it.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-06-08 12:25:36 +03:00
|
|
|
u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
|
|
|
|
|
|
|
|
pad_mii_id.rxc_pd = 1;
|
|
|
|
pad_mii_id.txc_pd = 1;
|
|
|
|
|
net: dsa: sja1105: parse {rx, tx}-internal-delay-ps properties for RGMII delays
This change does not fix any functional issue or address any real life
use case that wasn't possible before. It is just a small step in the
process of standardizing the way in which Ethernet MAC drivers may apply
RGMII delays (traditionally these have been applied by PHYs, with no
clear definition of what to do in the case of a fixed-link).
The sja1105 driver used to apply MAC-level RGMII delays on the RX data
lines when in fixed-link mode and using a phy-mode of "rgmii-rxid" or
"rgmii-id" and on the TX data lines when using "rgmii-txid" or "rgmii-id".
But the standard definitions don't say anything about behaving
differently when the port is in fixed-link vs when it isn't, and the new
device tree bindings are about having a way of applying the delays in a
way that is independent of the phy-mode and of the fixed-link property.
When the {rx,tx}-internal-delay-ps properties are present, use them,
otherwise fall back to the old behavior and warn.
One other thing to note is that the SJA1105 hardware applies a delay
value in degrees rather than in picoseconds (the delay in ps changes
depending on the frequency of the RGMII clock - 125 MHz at 1G, 25 MHz at
100M, 2.5MHz at 10M). I assume that is fine, we calculate the phase
shift of the internal delay lines assuming that the device tree meant
gigabit, and we let the hardware scale those according to the link speed.
Link: https://patchwork.kernel.org/project/netdevbpf/patch/20210723173108.459770-6-prasanna.vengateshan@microchip.com/
Link: https://patchwork.ozlabs.org/project/netdev/patch/20200616074955.GA9092@laureti-dev/#2461123
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-10-18 22:29:52 +03:00
|
|
|
if (rx_delay) {
|
|
|
|
pad_mii_id.rxc_delay = SJA1105_RGMII_DELAY_PS_TO_HW(rx_delay);
|
net: dsa: sja1105: add support for the SJA1110 switch family
The SJA1110 is basically an SJA1105 with more ports, some integrated
PHYs (100base-T1 and 100base-TX) and an embedded microcontroller which
can be disabled, and the switch core can be controlled by a host running
Linux, over SPI.
This patch contains:
- the static and dynamic config packing functions, for the tables that
are common with SJA1105
- one more static config tables which is "unique" to the SJA1110
(actually it is a rehash of stuff that was placed somewhere else in
SJA1105): the PCP Remapping Table
- a reset and clock configuration procedure for the SJA1110 switch.
This resets just the switch subsystem, and gates off the clock which
powers on the embedded microcontroller.
- an RGMII delay configuration procedure for SJA1110, which is very
similar to SJA1105, but different enough for us to be unable to reuse
it (this is a pattern that repeats itself)
- some adaptations to dynamic config table entries which are no longer
programmed in the same way. For example, to delete a VLAN, you used to
write an entry through the dynamic reconfiguration interface with the
desired VLAN ID, and with the VALIDENT bit set to false. Now, the VLAN
table entries contain a TYPE_ENTRY field, which must be set to zero
(in a backwards-incompatible way) in order for the entry to be deleted,
or to some other entry for the VLAN to match "inner tagged" or "outer
tagged" packets.
- a similar thing for the static config: the xMII Mode Parameters Table
encoding for SGMII and MII (the latter just when attached to a
100base-TX PHY) just isn't what it used to be in SJA1105. They are
identical, except there is an extra "special" bit which needs to be
set. Set it.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-06-08 12:25:36 +03:00
|
|
|
/* The "BYPASS" bit in SJA1110 is actually a "don't bypass" */
|
|
|
|
pad_mii_id.rxc_bypass = 1;
|
|
|
|
pad_mii_id.rxc_pd = 0;
|
|
|
|
}
|
|
|
|
|
net: dsa: sja1105: parse {rx, tx}-internal-delay-ps properties for RGMII delays
This change does not fix any functional issue or address any real life
use case that wasn't possible before. It is just a small step in the
process of standardizing the way in which Ethernet MAC drivers may apply
RGMII delays (traditionally these have been applied by PHYs, with no
clear definition of what to do in the case of a fixed-link).
The sja1105 driver used to apply MAC-level RGMII delays on the RX data
lines when in fixed-link mode and using a phy-mode of "rgmii-rxid" or
"rgmii-id" and on the TX data lines when using "rgmii-txid" or "rgmii-id".
But the standard definitions don't say anything about behaving
differently when the port is in fixed-link vs when it isn't, and the new
device tree bindings are about having a way of applying the delays in a
way that is independent of the phy-mode and of the fixed-link property.
When the {rx,tx}-internal-delay-ps properties are present, use them,
otherwise fall back to the old behavior and warn.
One other thing to note is that the SJA1105 hardware applies a delay
value in degrees rather than in picoseconds (the delay in ps changes
depending on the frequency of the RGMII clock - 125 MHz at 1G, 25 MHz at
100M, 2.5MHz at 10M). I assume that is fine, we calculate the phase
shift of the internal delay lines assuming that the device tree meant
gigabit, and we let the hardware scale those according to the link speed.
Link: https://patchwork.kernel.org/project/netdevbpf/patch/20210723173108.459770-6-prasanna.vengateshan@microchip.com/
Link: https://patchwork.ozlabs.org/project/netdev/patch/20200616074955.GA9092@laureti-dev/#2461123
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-10-18 22:29:52 +03:00
|
|
|
if (tx_delay) {
|
|
|
|
pad_mii_id.txc_delay = SJA1105_RGMII_DELAY_PS_TO_HW(tx_delay);
|
net: dsa: sja1105: add support for the SJA1110 switch family
The SJA1110 is basically an SJA1105 with more ports, some integrated
PHYs (100base-T1 and 100base-TX) and an embedded microcontroller which
can be disabled, and the switch core can be controlled by a host running
Linux, over SPI.
This patch contains:
- the static and dynamic config packing functions, for the tables that
are common with SJA1105
- one more static config tables which is "unique" to the SJA1110
(actually it is a rehash of stuff that was placed somewhere else in
SJA1105): the PCP Remapping Table
- a reset and clock configuration procedure for the SJA1110 switch.
This resets just the switch subsystem, and gates off the clock which
powers on the embedded microcontroller.
- an RGMII delay configuration procedure for SJA1110, which is very
similar to SJA1105, but different enough for us to be unable to reuse
it (this is a pattern that repeats itself)
- some adaptations to dynamic config table entries which are no longer
programmed in the same way. For example, to delete a VLAN, you used to
write an entry through the dynamic reconfiguration interface with the
desired VLAN ID, and with the VALIDENT bit set to false. Now, the VLAN
table entries contain a TYPE_ENTRY field, which must be set to zero
(in a backwards-incompatible way) in order for the entry to be deleted,
or to some other entry for the VLAN to match "inner tagged" or "outer
tagged" packets.
- a similar thing for the static config: the xMII Mode Parameters Table
encoding for SGMII and MII (the latter just when attached to a
100base-TX PHY) just isn't what it used to be in SJA1105. They are
identical, except there is an extra "special" bit which needs to be
set. Set it.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-06-08 12:25:36 +03:00
|
|
|
pad_mii_id.txc_bypass = 1;
|
|
|
|
pad_mii_id.txc_pd = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
sja1110_cfg_pad_mii_id_packing(packed_buf, &pad_mii_id, PACK);
|
|
|
|
|
|
|
|
return sja1105_xfer_buf(priv, SPI_WRITE, regs->pad_mii_id[port],
|
|
|
|
packed_buf, SJA1105_SIZE_CGU_CMD);
|
|
|
|
}
|
|
|
|
|
2019-06-08 19:12:28 +03:00
|
|
|
static int sja1105_rgmii_clocking_setup(struct sja1105_private *priv, int port,
|
|
|
|
sja1105_mii_role_t role)
|
2019-05-02 23:23:30 +03:00
|
|
|
{
|
|
|
|
struct device *dev = priv->ds->dev;
|
|
|
|
struct sja1105_mac_config_entry *mac;
|
2021-05-31 01:59:37 +03:00
|
|
|
u64 speed;
|
2019-05-02 23:23:30 +03:00
|
|
|
int rc;
|
|
|
|
|
|
|
|
mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries;
|
|
|
|
speed = mac[port].speed;
|
|
|
|
|
2021-05-31 01:59:37 +03:00
|
|
|
dev_dbg(dev, "Configuring port %d RGMII at speed %lldMbps\n",
|
2019-05-02 23:23:30 +03:00
|
|
|
port, speed);
|
|
|
|
|
2021-05-31 01:59:37 +03:00
|
|
|
if (speed == priv->info->port_speed[SJA1105_SPEED_1000MBPS]) {
|
2019-05-02 23:23:30 +03:00
|
|
|
/* 1000Mbps, IDIV disabled (125 MHz) */
|
|
|
|
rc = sja1105_cgu_idiv_config(priv, port, false, 1);
|
2021-05-31 01:59:37 +03:00
|
|
|
} else if (speed == priv->info->port_speed[SJA1105_SPEED_100MBPS]) {
|
2019-05-02 23:23:30 +03:00
|
|
|
/* 100Mbps, IDIV enabled, divide by 1 (25 MHz) */
|
|
|
|
rc = sja1105_cgu_idiv_config(priv, port, true, 1);
|
2021-05-31 01:59:37 +03:00
|
|
|
} else if (speed == priv->info->port_speed[SJA1105_SPEED_10MBPS]) {
|
2019-05-02 23:23:30 +03:00
|
|
|
/* 10Mbps, IDIV enabled, divide by 10 (2.5 MHz) */
|
|
|
|
rc = sja1105_cgu_idiv_config(priv, port, true, 10);
|
2021-05-31 01:59:37 +03:00
|
|
|
} else if (speed == priv->info->port_speed[SJA1105_SPEED_AUTO]) {
|
2019-05-02 23:23:30 +03:00
|
|
|
/* Skip CGU configuration if there is no speed available
|
|
|
|
* (e.g. link is not established yet)
|
|
|
|
*/
|
|
|
|
dev_dbg(dev, "Speed not available, skipping CGU config\n");
|
|
|
|
return 0;
|
2021-05-31 01:59:37 +03:00
|
|
|
} else {
|
2019-05-02 23:23:30 +03:00
|
|
|
rc = -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rc < 0) {
|
|
|
|
dev_err(dev, "Failed to configure idiv\n");
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
rc = sja1105_cgu_rgmii_tx_clk_config(priv, port, speed);
|
|
|
|
if (rc < 0) {
|
|
|
|
dev_err(dev, "Failed to configure RGMII Tx clock\n");
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
rc = sja1105_rgmii_cfg_pad_tx_config(priv, port);
|
|
|
|
if (rc < 0) {
|
|
|
|
dev_err(dev, "Failed to configure Tx pad registers\n");
|
|
|
|
return rc;
|
|
|
|
}
|
net: dsa: sja1105: always keep RGMII ports in the MAC role
In SJA1105, the xMII Mode Parameters Table field called PHY_MAC denotes
the 'role' of the port, be it a PHY or a MAC. This makes a difference in
the MII and RMII protocols, but RGMII is symmetric, so either PHY or MAC
settings result in the same hardware behavior.
The SJA1110 is different, and the RGMII ports only work when configured
in MAC mode, so keep the port roles in MAC mode unconditionally.
Why we had an RGMII port in the PHY role in the first place was because
we wanted to have a way in the driver to denote whether RGMII delays
should be applied based on the phy-mode property or not. This is already
done in sja1105_parse_rgmii_delays() based on an intermediary
struct sja1105_dt_port (which contains the port role). So it is a
logical fallacy to use the hardware configuration as a scratchpad for
driver data, it isn't necessary.
We can also remove the gating condition for applying RGMII delays only
for ports in the PHY role. The .setup_rgmii_delay() method looks at
the priv->rgmii_rx_delay[port] and priv->rgmii_tx_delay[port] properties
which are already populated properly (in the case of a port in the MAC
role they are false). Removing this condition generates a few more SPI
writes for these ports (clearing the RGMII delays) which are perhaps
useless for SJA1105P/Q/R/S, where we know that the delays are disabled
by default. But for SJA1110, the firmware on the embedded microcontroller
might have done something funny, so it's always a good idea to clear the
RGMII delays if that's what Linux expects.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2021-05-31 01:59:38 +03:00
|
|
|
|
net: dsa: sja1105: Error out if RGMII delays are requested in DT
Documentation/devicetree/bindings/net/ethernet.txt is confusing because
it says what the MAC should not do, but not what it *should* do:
* "rgmii-rxid" (RGMII with internal RX delay provided by the PHY, the MAC
should not add an RX delay in this case)
The gap in semantics is threefold:
1. Is it illegal for the MAC to apply the Rx internal delay by itself,
and simplify the phy_mode (mask off "rgmii-rxid" into "rgmii") before
passing it to of_phy_connect? The documentation would suggest yes.
1. For "rgmii-rxid", while the situation with the Rx clock skew is more
or less clear (needs to be added by the PHY), what should the MAC
driver do about the Tx delays? Is it an implicit wild card for the
MAC to apply delays in the Tx direction if it can? What if those were
already added as serpentine PCB traces, how could that be made more
obvious through DT bindings so that the MAC doesn't attempt to add
them twice and again potentially break the link?
3. If the interface is a fixed-link and therefore the PHY object is
fixed (a purely software entity that obviously cannot add clock
skew), what is the meaning of the above property?
So an interpretation of the RGMII bindings was chosen that hopefully
does not contradict their intention but also makes them more applied.
The SJA1105 driver understands to act upon "rgmii-*id" phy-mode bindings
if the port is in the PHY role (either explicitly, or if it is a
fixed-link). Otherwise it always passes the duty of setting up delays to
the PHY driver.
The error behavior that this patch adds is required on SJA1105E/T where
the MAC really cannot apply internal delays. If the other end of the
fixed-link cannot apply RGMII delays either (this would be specified
through its own DT bindings), then the situation requires PCB delays.
For SJA1105P/Q/R/S, this is however hardware supported and the error is
thus only temporary. I created a stub function pointer for configuring
delays per-port on RXC and TXC, and will implement it when I have access
to a board with this hardware setup.
Meanwhile do not allow the user to select an invalid configuration.
Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-05-02 23:23:32 +03:00
|
|
|
if (!priv->info->setup_rgmii_delay)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return priv->info->setup_rgmii_delay(priv, port);
|
2019-05-02 23:23:30 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static int sja1105_cgu_rmii_ref_clk_config(struct sja1105_private *priv,
|
|
|
|
int port)
|
|
|
|
{
|
|
|
|
const struct sja1105_regs *regs = priv->info->regs;
|
|
|
|
struct sja1105_cgu_mii_ctrl ref_clk;
|
|
|
|
u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
|
2023-09-19 10:36:06 +01:00
|
|
|
static const int clk_sources[] = {
|
2019-05-02 23:23:30 +03:00
|
|
|
CLKSRC_MII0_TX_CLK,
|
|
|
|
CLKSRC_MII1_TX_CLK,
|
|
|
|
CLKSRC_MII2_TX_CLK,
|
|
|
|
CLKSRC_MII3_TX_CLK,
|
|
|
|
CLKSRC_MII4_TX_CLK,
|
|
|
|
};
|
|
|
|
|
2021-05-24 16:14:17 +03:00
|
|
|
if (regs->rmii_ref_clk[port] == SJA1105_RSV_ADDR)
|
|
|
|
return 0;
|
|
|
|
|
2019-05-02 23:23:30 +03:00
|
|
|
/* Payload for packed_buf */
|
|
|
|
ref_clk.clksrc = clk_sources[port];
|
|
|
|
ref_clk.autoblock = 1; /* Autoblock clk while changing clksrc */
|
|
|
|
ref_clk.pd = 0; /* Power Down off => enabled */
|
|
|
|
sja1105_cgu_mii_control_packing(packed_buf, &ref_clk, PACK);
|
|
|
|
|
2019-10-01 22:18:01 +03:00
|
|
|
return sja1105_xfer_buf(priv, SPI_WRITE, regs->rmii_ref_clk[port],
|
|
|
|
packed_buf, SJA1105_SIZE_CGU_CMD);
|
2019-05-02 23:23:30 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
sja1105_cgu_rmii_ext_tx_clk_config(struct sja1105_private *priv, int port)
|
|
|
|
{
|
|
|
|
const struct sja1105_regs *regs = priv->info->regs;
|
|
|
|
struct sja1105_cgu_mii_ctrl ext_tx_clk;
|
|
|
|
u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
|
|
|
|
|
2021-05-24 16:14:17 +03:00
|
|
|
if (regs->rmii_ext_tx_clk[port] == SJA1105_RSV_ADDR)
|
|
|
|
return 0;
|
|
|
|
|
2019-05-02 23:23:30 +03:00
|
|
|
/* Payload for packed_buf */
|
|
|
|
ext_tx_clk.clksrc = CLKSRC_PLL1;
|
|
|
|
ext_tx_clk.autoblock = 1; /* Autoblock clk while changing clksrc */
|
|
|
|
ext_tx_clk.pd = 0; /* Power Down off => enabled */
|
|
|
|
sja1105_cgu_mii_control_packing(packed_buf, &ext_tx_clk, PACK);
|
|
|
|
|
2019-10-01 22:18:01 +03:00
|
|
|
return sja1105_xfer_buf(priv, SPI_WRITE, regs->rmii_ext_tx_clk[port],
|
|
|
|
packed_buf, SJA1105_SIZE_CGU_CMD);
|
2019-05-02 23:23:30 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static int sja1105_cgu_rmii_pll_config(struct sja1105_private *priv)
|
|
|
|
{
|
|
|
|
const struct sja1105_regs *regs = priv->info->regs;
|
|
|
|
u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
|
|
|
|
struct sja1105_cgu_pll_ctrl pll = {0};
|
|
|
|
struct device *dev = priv->ds->dev;
|
|
|
|
int rc;
|
|
|
|
|
2021-05-24 16:14:17 +03:00
|
|
|
if (regs->rmii_pll1 == SJA1105_RSV_ADDR)
|
|
|
|
return 0;
|
|
|
|
|
2019-05-02 23:23:30 +03:00
|
|
|
/* PLL1 must be enabled and output 50 Mhz.
|
|
|
|
* This is done by writing first 0x0A010941 to
|
|
|
|
* the PLL_1_C register and then deasserting
|
|
|
|
* power down (PD) 0x0A010940.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Step 1: PLL1 setup for 50Mhz */
|
|
|
|
pll.pllclksrc = 0xA;
|
|
|
|
pll.msel = 0x1;
|
|
|
|
pll.autoblock = 0x1;
|
|
|
|
pll.psel = 0x1;
|
|
|
|
pll.direct = 0x0;
|
|
|
|
pll.fbsel = 0x1;
|
|
|
|
pll.bypass = 0x0;
|
|
|
|
pll.pd = 0x1;
|
|
|
|
|
|
|
|
sja1105_cgu_pll_control_packing(packed_buf, &pll, PACK);
|
2019-10-01 22:18:01 +03:00
|
|
|
rc = sja1105_xfer_buf(priv, SPI_WRITE, regs->rmii_pll1, packed_buf,
|
|
|
|
SJA1105_SIZE_CGU_CMD);
|
2019-05-02 23:23:30 +03:00
|
|
|
if (rc < 0) {
|
|
|
|
dev_err(dev, "failed to configure PLL1 for 50MHz\n");
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Step 2: Enable PLL1 */
|
|
|
|
pll.pd = 0x0;
|
|
|
|
|
|
|
|
sja1105_cgu_pll_control_packing(packed_buf, &pll, PACK);
|
2019-10-01 22:18:01 +03:00
|
|
|
rc = sja1105_xfer_buf(priv, SPI_WRITE, regs->rmii_pll1, packed_buf,
|
|
|
|
SJA1105_SIZE_CGU_CMD);
|
2019-05-02 23:23:30 +03:00
|
|
|
if (rc < 0) {
|
|
|
|
dev_err(dev, "failed to enable PLL1\n");
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int sja1105_rmii_clocking_setup(struct sja1105_private *priv, int port,
|
|
|
|
sja1105_mii_role_t role)
|
|
|
|
{
|
|
|
|
struct device *dev = priv->ds->dev;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
dev_dbg(dev, "Configuring RMII-%s clocking\n",
|
|
|
|
(role == XMII_MAC) ? "MAC" : "PHY");
|
|
|
|
/* AH1601.pdf chapter 2.5.1. Sources */
|
|
|
|
if (role == XMII_MAC) {
|
|
|
|
/* Configure and enable PLL1 for 50Mhz output */
|
|
|
|
rc = sja1105_cgu_rmii_pll_config(priv);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
/* Disable IDIV for this port */
|
|
|
|
rc = sja1105_cgu_idiv_config(priv, port, false, 1);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
|
|
|
/* Source to sink mappings */
|
|
|
|
rc = sja1105_cgu_rmii_ref_clk_config(priv, port);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
|
|
|
if (role == XMII_MAC) {
|
|
|
|
rc = sja1105_cgu_rmii_ext_tx_clk_config(priv, port);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sja1105_clocking_setup_port(struct sja1105_private *priv, int port)
|
|
|
|
{
|
|
|
|
struct sja1105_xmii_params_entry *mii;
|
|
|
|
struct device *dev = priv->ds->dev;
|
|
|
|
sja1105_phy_interface_t phy_mode;
|
|
|
|
sja1105_mii_role_t role;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
mii = priv->static_config.tables[BLK_IDX_XMII_PARAMS].entries;
|
|
|
|
|
|
|
|
/* RGMII etc */
|
|
|
|
phy_mode = mii->xmii_mode[port];
|
|
|
|
/* MAC or PHY, for applicable types (not RGMII) */
|
|
|
|
role = mii->phy_mac[port];
|
|
|
|
|
|
|
|
switch (phy_mode) {
|
|
|
|
case XMII_MODE_MII:
|
|
|
|
rc = sja1105_mii_clocking_setup(priv, port, role);
|
|
|
|
break;
|
|
|
|
case XMII_MODE_RMII:
|
|
|
|
rc = sja1105_rmii_clocking_setup(priv, port, role);
|
|
|
|
break;
|
|
|
|
case XMII_MODE_RGMII:
|
2019-06-08 19:12:28 +03:00
|
|
|
rc = sja1105_rgmii_clocking_setup(priv, port, role);
|
2019-05-02 23:23:30 +03:00
|
|
|
break;
|
2020-03-20 13:29:37 +02:00
|
|
|
case XMII_MODE_SGMII:
|
|
|
|
/* Nothing to do in the CGU for SGMII */
|
|
|
|
rc = 0;
|
|
|
|
break;
|
2019-05-02 23:23:30 +03:00
|
|
|
default:
|
|
|
|
dev_err(dev, "Invalid interface mode specified: %d\n",
|
|
|
|
phy_mode);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
net: dsa: sja1105: enable internal pull-down for RX_DV/CRS_DV/RX_CTL and RX_ER
Some boards do not have the RX_ER MII signal connected. Normally in such
situation, those pins would be grounded, but then again, some boards
left it electrically floating.
When sending traffic to those switch ports, one can see that the
N_SOFERR statistics counter is incrementing once per each packet. The
user manual states for this counter that it may count the number of
frames "that have the MII error input being asserted prior to or
up to the SOF delimiter byte". So the switch MAC is sampling an
electrically floating signal, and preventing proper traffic reception
because of that.
As a workaround, enable the internal weak pull-downs on the input pads
for the MII control signals. This way, a floating signal would be
internally tied to ground.
The logic levels of signals which _are_ externally driven should not be
bothered by this 40-50 KOhm internal resistor. So it is not an issue to
enable the internal pull-down unconditionally, irrespective of PHY
interface type (MII, RMII, RGMII, SGMII) and of board layout.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-04-17 22:50:52 +03:00
|
|
|
if (rc) {
|
2019-05-02 23:23:30 +03:00
|
|
|
dev_err(dev, "Clocking setup for port %d failed: %d\n",
|
|
|
|
port, rc);
|
net: dsa: sja1105: enable internal pull-down for RX_DV/CRS_DV/RX_CTL and RX_ER
Some boards do not have the RX_ER MII signal connected. Normally in such
situation, those pins would be grounded, but then again, some boards
left it electrically floating.
When sending traffic to those switch ports, one can see that the
N_SOFERR statistics counter is incrementing once per each packet. The
user manual states for this counter that it may count the number of
frames "that have the MII error input being asserted prior to or
up to the SOF delimiter byte". So the switch MAC is sampling an
electrically floating signal, and preventing proper traffic reception
because of that.
As a workaround, enable the internal weak pull-downs on the input pads
for the MII control signals. This way, a floating signal would be
internally tied to ground.
The logic levels of signals which _are_ externally driven should not be
bothered by this 40-50 KOhm internal resistor. So it is not an issue to
enable the internal pull-down unconditionally, irrespective of PHY
interface type (MII, RMII, RGMII, SGMII) and of board layout.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-04-17 22:50:52 +03:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Internally pull down the RX_DV/CRS_DV/RX_CTL and RX_ER inputs */
|
|
|
|
return sja1105_cfg_pad_rx_config(priv, port);
|
2019-05-02 23:23:30 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
int sja1105_clocking_setup(struct sja1105_private *priv)
|
|
|
|
{
|
2021-05-24 16:14:13 +03:00
|
|
|
struct dsa_switch *ds = priv->ds;
|
2019-05-02 23:23:30 +03:00
|
|
|
int port, rc;
|
|
|
|
|
2021-05-24 16:14:13 +03:00
|
|
|
for (port = 0; port < ds->num_ports; port++) {
|
2019-05-02 23:23:30 +03:00
|
|
|
rc = sja1105_clocking_setup_port(priv, port);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
net: dsa: sja1105: add support for the SJA1110 switch family
The SJA1110 is basically an SJA1105 with more ports, some integrated
PHYs (100base-T1 and 100base-TX) and an embedded microcontroller which
can be disabled, and the switch core can be controlled by a host running
Linux, over SPI.
This patch contains:
- the static and dynamic config packing functions, for the tables that
are common with SJA1105
- one more static config tables which is "unique" to the SJA1110
(actually it is a rehash of stuff that was placed somewhere else in
SJA1105): the PCP Remapping Table
- a reset and clock configuration procedure for the SJA1110 switch.
This resets just the switch subsystem, and gates off the clock which
powers on the embedded microcontroller.
- an RGMII delay configuration procedure for SJA1110, which is very
similar to SJA1105, but different enough for us to be unable to reuse
it (this is a pattern that repeats itself)
- some adaptations to dynamic config table entries which are no longer
programmed in the same way. For example, to delete a VLAN, you used to
write an entry through the dynamic reconfiguration interface with the
desired VLAN ID, and with the VALIDENT bit set to false. Now, the VLAN
table entries contain a TYPE_ENTRY field, which must be set to zero
(in a backwards-incompatible way) in order for the entry to be deleted,
or to some other entry for the VLAN to match "inner tagged" or "outer
tagged" packets.
- a similar thing for the static config: the xMII Mode Parameters Table
encoding for SGMII and MII (the latter just when attached to a
100base-TX PHY) just isn't what it used to be in SJA1105. They are
identical, except there is an extra "special" bit which needs to be
set. Set it.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-06-08 12:25:36 +03:00
|
|
|
|
|
|
|
static void
|
|
|
|
sja1110_cgu_outclk_packing(void *buf, struct sja1110_cgu_outclk *outclk,
|
|
|
|
enum packing_op op)
|
|
|
|
{
|
|
|
|
const int size = 4;
|
|
|
|
|
|
|
|
sja1105_packing(buf, &outclk->clksrc, 27, 24, size, op);
|
|
|
|
sja1105_packing(buf, &outclk->autoblock, 11, 11, size, op);
|
|
|
|
sja1105_packing(buf, &outclk->pd, 0, 0, size, op);
|
|
|
|
}
|
|
|
|
|
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>
2021-06-18 14:52:54 +03:00
|
|
|
int sja1110_disable_microcontroller(struct sja1105_private *priv)
|
net: dsa: sja1105: add support for the SJA1110 switch family
The SJA1110 is basically an SJA1105 with more ports, some integrated
PHYs (100base-T1 and 100base-TX) and an embedded microcontroller which
can be disabled, and the switch core can be controlled by a host running
Linux, over SPI.
This patch contains:
- the static and dynamic config packing functions, for the tables that
are common with SJA1105
- one more static config tables which is "unique" to the SJA1110
(actually it is a rehash of stuff that was placed somewhere else in
SJA1105): the PCP Remapping Table
- a reset and clock configuration procedure for the SJA1110 switch.
This resets just the switch subsystem, and gates off the clock which
powers on the embedded microcontroller.
- an RGMII delay configuration procedure for SJA1110, which is very
similar to SJA1105, but different enough for us to be unable to reuse
it (this is a pattern that repeats itself)
- some adaptations to dynamic config table entries which are no longer
programmed in the same way. For example, to delete a VLAN, you used to
write an entry through the dynamic reconfiguration interface with the
desired VLAN ID, and with the VALIDENT bit set to false. Now, the VLAN
table entries contain a TYPE_ENTRY field, which must be set to zero
(in a backwards-incompatible way) in order for the entry to be deleted,
or to some other entry for the VLAN to match "inner tagged" or "outer
tagged" packets.
- a similar thing for the static config: the xMII Mode Parameters Table
encoding for SGMII and MII (the latter just when attached to a
100base-TX PHY) just isn't what it used to be in SJA1105. They are
identical, except there is an extra "special" bit which needs to be
set. Set it.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-06-08 12:25:36 +03:00
|
|
|
{
|
|
|
|
u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
|
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>
2021-06-18 14:52:54 +03:00
|
|
|
struct sja1110_cgu_outclk outclk_6_c = {
|
|
|
|
.clksrc = 0x3,
|
|
|
|
.pd = true,
|
|
|
|
};
|
net: dsa: sja1105: add support for the SJA1110 switch family
The SJA1110 is basically an SJA1105 with more ports, some integrated
PHYs (100base-T1 and 100base-TX) and an embedded microcontroller which
can be disabled, and the switch core can be controlled by a host running
Linux, over SPI.
This patch contains:
- the static and dynamic config packing functions, for the tables that
are common with SJA1105
- one more static config tables which is "unique" to the SJA1110
(actually it is a rehash of stuff that was placed somewhere else in
SJA1105): the PCP Remapping Table
- a reset and clock configuration procedure for the SJA1110 switch.
This resets just the switch subsystem, and gates off the clock which
powers on the embedded microcontroller.
- an RGMII delay configuration procedure for SJA1110, which is very
similar to SJA1105, but different enough for us to be unable to reuse
it (this is a pattern that repeats itself)
- some adaptations to dynamic config table entries which are no longer
programmed in the same way. For example, to delete a VLAN, you used to
write an entry through the dynamic reconfiguration interface with the
desired VLAN ID, and with the VALIDENT bit set to false. Now, the VLAN
table entries contain a TYPE_ENTRY field, which must be set to zero
(in a backwards-incompatible way) in order for the entry to be deleted,
or to some other entry for the VLAN to match "inner tagged" or "outer
tagged" packets.
- a similar thing for the static config: the xMII Mode Parameters Table
encoding for SGMII and MII (the latter just when attached to a
100base-TX PHY) just isn't what it used to be in SJA1105. They are
identical, except there is an extra "special" bit which needs to be
set. Set it.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-06-08 12:25:36 +03:00
|
|
|
struct sja1110_cgu_outclk outclk_7_c = {
|
|
|
|
.clksrc = 0x5,
|
|
|
|
.pd = true,
|
|
|
|
};
|
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>
2021-06-18 14:52:54 +03:00
|
|
|
int rc;
|
net: dsa: sja1105: add support for the SJA1110 switch family
The SJA1110 is basically an SJA1105 with more ports, some integrated
PHYs (100base-T1 and 100base-TX) and an embedded microcontroller which
can be disabled, and the switch core can be controlled by a host running
Linux, over SPI.
This patch contains:
- the static and dynamic config packing functions, for the tables that
are common with SJA1105
- one more static config tables which is "unique" to the SJA1110
(actually it is a rehash of stuff that was placed somewhere else in
SJA1105): the PCP Remapping Table
- a reset and clock configuration procedure for the SJA1110 switch.
This resets just the switch subsystem, and gates off the clock which
powers on the embedded microcontroller.
- an RGMII delay configuration procedure for SJA1110, which is very
similar to SJA1105, but different enough for us to be unable to reuse
it (this is a pattern that repeats itself)
- some adaptations to dynamic config table entries which are no longer
programmed in the same way. For example, to delete a VLAN, you used to
write an entry through the dynamic reconfiguration interface with the
desired VLAN ID, and with the VALIDENT bit set to false. Now, the VLAN
table entries contain a TYPE_ENTRY field, which must be set to zero
(in a backwards-incompatible way) in order for the entry to be deleted,
or to some other entry for the VLAN to match "inner tagged" or "outer
tagged" packets.
- a similar thing for the static config: the xMII Mode Parameters Table
encoding for SGMII and MII (the latter just when attached to a
100base-TX PHY) just isn't what it used to be in SJA1105. They are
identical, except there is an extra "special" bit which needs to be
set. Set it.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-06-08 12:25:36 +03:00
|
|
|
|
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>
2021-06-18 14:52:54 +03:00
|
|
|
/* Power down the BASE_TIMER_CLK to disable the watchdog timer */
|
net: dsa: sja1105: add support for the SJA1110 switch family
The SJA1110 is basically an SJA1105 with more ports, some integrated
PHYs (100base-T1 and 100base-TX) and an embedded microcontroller which
can be disabled, and the switch core can be controlled by a host running
Linux, over SPI.
This patch contains:
- the static and dynamic config packing functions, for the tables that
are common with SJA1105
- one more static config tables which is "unique" to the SJA1110
(actually it is a rehash of stuff that was placed somewhere else in
SJA1105): the PCP Remapping Table
- a reset and clock configuration procedure for the SJA1110 switch.
This resets just the switch subsystem, and gates off the clock which
powers on the embedded microcontroller.
- an RGMII delay configuration procedure for SJA1110, which is very
similar to SJA1105, but different enough for us to be unable to reuse
it (this is a pattern that repeats itself)
- some adaptations to dynamic config table entries which are no longer
programmed in the same way. For example, to delete a VLAN, you used to
write an entry through the dynamic reconfiguration interface with the
desired VLAN ID, and with the VALIDENT bit set to false. Now, the VLAN
table entries contain a TYPE_ENTRY field, which must be set to zero
(in a backwards-incompatible way) in order for the entry to be deleted,
or to some other entry for the VLAN to match "inner tagged" or "outer
tagged" packets.
- a similar thing for the static config: the xMII Mode Parameters Table
encoding for SGMII and MII (the latter just when attached to a
100base-TX PHY) just isn't what it used to be in SJA1105. They are
identical, except there is an extra "special" bit which needs to be
set. Set it.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-06-08 12:25:36 +03:00
|
|
|
sja1110_cgu_outclk_packing(packed_buf, &outclk_7_c, PACK);
|
|
|
|
|
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>
2021-06-18 14:52:54 +03:00
|
|
|
rc = sja1105_xfer_buf(priv, SPI_WRITE, SJA1110_BASE_TIMER_CLK,
|
|
|
|
packed_buf, SJA1105_SIZE_CGU_CMD);
|
|
|
|
if (rc)
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
/* Power down the BASE_MCSS_CLOCK to gate the microcontroller off */
|
|
|
|
sja1110_cgu_outclk_packing(packed_buf, &outclk_6_c, PACK);
|
|
|
|
|
|
|
|
return sja1105_xfer_buf(priv, SPI_WRITE, SJA1110_BASE_MCSS_CLK,
|
net: dsa: sja1105: add support for the SJA1110 switch family
The SJA1110 is basically an SJA1105 with more ports, some integrated
PHYs (100base-T1 and 100base-TX) and an embedded microcontroller which
can be disabled, and the switch core can be controlled by a host running
Linux, over SPI.
This patch contains:
- the static and dynamic config packing functions, for the tables that
are common with SJA1105
- one more static config tables which is "unique" to the SJA1110
(actually it is a rehash of stuff that was placed somewhere else in
SJA1105): the PCP Remapping Table
- a reset and clock configuration procedure for the SJA1110 switch.
This resets just the switch subsystem, and gates off the clock which
powers on the embedded microcontroller.
- an RGMII delay configuration procedure for SJA1110, which is very
similar to SJA1105, but different enough for us to be unable to reuse
it (this is a pattern that repeats itself)
- some adaptations to dynamic config table entries which are no longer
programmed in the same way. For example, to delete a VLAN, you used to
write an entry through the dynamic reconfiguration interface with the
desired VLAN ID, and with the VALIDENT bit set to false. Now, the VLAN
table entries contain a TYPE_ENTRY field, which must be set to zero
(in a backwards-incompatible way) in order for the entry to be deleted,
or to some other entry for the VLAN to match "inner tagged" or "outer
tagged" packets.
- a similar thing for the static config: the xMII Mode Parameters Table
encoding for SGMII and MII (the latter just when attached to a
100base-TX PHY) just isn't what it used to be in SJA1105. They are
identical, except there is an extra "special" bit which needs to be
set. Set it.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-06-08 12:25:36 +03:00
|
|
|
packed_buf, SJA1105_SIZE_CGU_CMD);
|
|
|
|
}
|