]> git.baikalelectronics.ru Git - kernel.git/commitdiff
net: dsa: sja1105: enable internal pull-down for RX_DV/CRS_DV/RX_CTL and RX_ER
authorVladimir Oltean <vladimir.oltean@nxp.com>
Fri, 17 Apr 2020 19:50:52 +0000 (22:50 +0300)
committerDavid S. Miller <davem@davemloft.net>
Mon, 20 Apr 2020 18:00:27 +0000 (11:00 -0700)
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>
drivers/net/dsa/sja1105/sja1105.h
drivers/net/dsa/sja1105/sja1105_clocking.c
drivers/net/dsa/sja1105/sja1105_spi.c

index 8b60dbd567f22e47b1f4c179f1c11b29ec85973a..2f62942692ec85063add4b908e63acde93aade17 100644 (file)
@@ -49,6 +49,7 @@ struct sja1105_regs {
        u64 ptpschtm;
        u64 ptpegr_ts[SJA1105_NUM_PORTS];
        u64 pad_mii_tx[SJA1105_NUM_PORTS];
+       u64 pad_mii_rx[SJA1105_NUM_PORTS];
        u64 pad_mii_id[SJA1105_NUM_PORTS];
        u64 cgu_idiv[SJA1105_NUM_PORTS];
        u64 mii_tx_clk[SJA1105_NUM_PORTS];
index 0fdc2d55fff6425dcba81d2d4247445a18a690c0..2a9b8a6a5306f984387cfaac9c22fcc860fc9804 100644 (file)
@@ -7,12 +7,16 @@
 
 #define SJA1105_SIZE_CGU_CMD   4
 
-struct sja1105_cfg_pad_mii_tx {
+/* Common structure for CFG_PAD_MIIx_RX and CFG_PAD_MIIx_TX */
+struct sja1105_cfg_pad_mii {
        u64 d32_os;
+       u64 d32_ih;
        u64 d32_ipud;
+       u64 d10_ih;
        u64 d10_os;
        u64 d10_ipud;
        u64 ctrl_os;
+       u64 ctrl_ih;
        u64 ctrl_ipud;
        u64 clk_os;
        u64 clk_ih;
@@ -338,16 +342,19 @@ static int sja1105_cgu_rgmii_tx_clk_config(struct sja1105_private *priv,
 
 /* AGU */
 static void
-sja1105_cfg_pad_mii_tx_packing(void *buf, struct sja1105_cfg_pad_mii_tx *cmd,
-                              enum packing_op op)
+sja1105_cfg_pad_mii_packing(void *buf, struct sja1105_cfg_pad_mii *cmd,
+                           enum packing_op op)
 {
        const int size = 4;
 
        sja1105_packing(buf, &cmd->d32_os,   28, 27, size, op);
+       sja1105_packing(buf, &cmd->d32_ih,   26, 26, size, op);
        sja1105_packing(buf, &cmd->d32_ipud, 25, 24, size, op);
        sja1105_packing(buf, &cmd->d10_os,   20, 19, size, op);
+       sja1105_packing(buf, &cmd->d10_ih,   18, 18, size, op);
        sja1105_packing(buf, &cmd->d10_ipud, 17, 16, size, op);
        sja1105_packing(buf, &cmd->ctrl_os,  12, 11, size, op);
+       sja1105_packing(buf, &cmd->ctrl_ih,  10, 10, size, op);
        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);
@@ -358,7 +365,7 @@ static int sja1105_rgmii_cfg_pad_tx_config(struct sja1105_private *priv,
                                           int port)
 {
        const struct sja1105_regs *regs = priv->info->regs;
-       struct sja1105_cfg_pad_mii_tx pad_mii_tx;
+       struct sja1105_cfg_pad_mii pad_mii_tx = {0};
        u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
 
        /* Payload */
@@ -375,12 +382,45 @@ static int sja1105_rgmii_cfg_pad_tx_config(struct sja1105_private *priv,
        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) */
-       sja1105_cfg_pad_mii_tx_packing(packed_buf, &pad_mii_tx, PACK);
+       sja1105_cfg_pad_mii_packing(packed_buf, &pad_mii_tx, PACK);
 
        return sja1105_xfer_buf(priv, SPI_WRITE, regs->pad_mii_tx[port],
                                packed_buf, SJA1105_SIZE_CGU_CMD);
 }
 
+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};
+
+       /* 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);
+}
+
 static void
 sja1105_cfg_pad_mii_id_packing(void *buf, struct sja1105_cfg_pad_mii_id *cmd,
                               enum packing_op op)
@@ -669,10 +709,14 @@ int sja1105_clocking_setup_port(struct sja1105_private *priv, int port)
                        phy_mode);
                return -EINVAL;
        }
-       if (rc)
+       if (rc) {
                dev_err(dev, "Clocking setup for port %d failed: %d\n",
                        port, rc);
-       return rc;
+               return rc;
+       }
+
+       /* Internally pull down the RX_DV/CRS_DV/RX_CTL and RX_ER inputs */
+       return sja1105_cfg_pad_rx_config(priv, port);
 }
 
 int sja1105_clocking_setup(struct sja1105_private *priv)
index 04bdb72ae6b6746f599aa65f13d614985c3f4180..43f14a5c2718d00fad9be55f3b97291d0cb08d39 100644 (file)
@@ -443,6 +443,7 @@ static struct sja1105_regs sja1105et_regs = {
        .rgu = 0x100440,
        /* UM10944.pdf, Table 86, ACU Register overview */
        .pad_mii_tx = {0x100800, 0x100802, 0x100804, 0x100806, 0x100808},
+       .pad_mii_rx = {0x100801, 0x100803, 0x100805, 0x100807, 0x100809},
        .rmii_pll1 = 0x10000A,
        .cgu_idiv = {0x10000B, 0x10000C, 0x10000D, 0x10000E, 0x10000F},
        .mac = {0x200, 0x202, 0x204, 0x206, 0x208},
@@ -475,6 +476,7 @@ static struct sja1105_regs sja1105pqrs_regs = {
        .rgu = 0x100440,
        /* UM10944.pdf, Table 86, ACU Register overview */
        .pad_mii_tx = {0x100800, 0x100802, 0x100804, 0x100806, 0x100808},
+       .pad_mii_rx = {0x100801, 0x100803, 0x100805, 0x100807, 0x100809},
        .pad_mii_id = {0x100810, 0x100811, 0x100812, 0x100813, 0x100814},
        .sgmii = 0x1F0000,
        .rmii_pll1 = 0x10000A,