forked from Openwrt/openwrt
9a038e7fd1
Copy config and patches from kernel 5.10 to kernel 5.15 Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
160 lines
5.6 KiB
Diff
160 lines
5.6 KiB
Diff
From cef08115846e581f80ff99abf7bf218da1840616 Mon Sep 17 00:00:00 2001
|
|
From: Ansuel Smith <ansuelsmth@gmail.com>
|
|
Date: Thu, 14 Oct 2021 00:39:18 +0200
|
|
Subject: net: dsa: qca8k: set internal delay also for sgmii
|
|
|
|
QCA original code report port instability and sa that SGMII also require
|
|
to set internal delay. Generalize the rgmii delay function and apply the
|
|
advised value if they are not defined in DT.
|
|
|
|
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
---
|
|
drivers/net/dsa/qca8k.c | 88 +++++++++++++++++++++++++++++++++----------------
|
|
drivers/net/dsa/qca8k.h | 2 ++
|
|
2 files changed, 62 insertions(+), 28 deletions(-)
|
|
|
|
--- a/drivers/net/dsa/qca8k.c
|
|
+++ b/drivers/net/dsa/qca8k.c
|
|
@@ -1004,6 +1004,7 @@ qca8k_parse_port_config(struct qca8k_pri
|
|
case PHY_INTERFACE_MODE_RGMII_ID:
|
|
case PHY_INTERFACE_MODE_RGMII_TXID:
|
|
case PHY_INTERFACE_MODE_RGMII_RXID:
|
|
+ case PHY_INTERFACE_MODE_SGMII:
|
|
delay = 0;
|
|
|
|
if (!of_property_read_u32(port_dn, "tx-internal-delay-ps", &delay))
|
|
@@ -1036,8 +1037,13 @@ qca8k_parse_port_config(struct qca8k_pri
|
|
|
|
priv->rgmii_rx_delay[cpu_port_index] = delay;
|
|
|
|
- break;
|
|
- case PHY_INTERFACE_MODE_SGMII:
|
|
+ /* Skip sgmii parsing for rgmii* mode */
|
|
+ if (mode == PHY_INTERFACE_MODE_RGMII ||
|
|
+ mode == PHY_INTERFACE_MODE_RGMII_ID ||
|
|
+ mode == PHY_INTERFACE_MODE_RGMII_TXID ||
|
|
+ mode == PHY_INTERFACE_MODE_RGMII_RXID)
|
|
+ break;
|
|
+
|
|
if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge"))
|
|
priv->sgmii_tx_clk_falling_edge = true;
|
|
|
|
@@ -1261,12 +1267,53 @@ qca8k_setup(struct dsa_switch *ds)
|
|
}
|
|
|
|
static void
|
|
+qca8k_mac_config_setup_internal_delay(struct qca8k_priv *priv, int cpu_port_index,
|
|
+ u32 reg)
|
|
+{
|
|
+ u32 delay, val = 0;
|
|
+ int ret;
|
|
+
|
|
+ /* Delay can be declared in 3 different way.
|
|
+ * Mode to rgmii and internal-delay standard binding defined
|
|
+ * rgmii-id or rgmii-tx/rx phy mode set.
|
|
+ * The parse logic set a delay different than 0 only when one
|
|
+ * of the 3 different way is used. In all other case delay is
|
|
+ * not enabled. With ID or TX/RXID delay is enabled and set
|
|
+ * to the default and recommended value.
|
|
+ */
|
|
+ if (priv->rgmii_tx_delay[cpu_port_index]) {
|
|
+ delay = priv->rgmii_tx_delay[cpu_port_index];
|
|
+
|
|
+ val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) |
|
|
+ QCA8K_PORT_PAD_RGMII_TX_DELAY_EN;
|
|
+ }
|
|
+
|
|
+ if (priv->rgmii_rx_delay[cpu_port_index]) {
|
|
+ delay = priv->rgmii_rx_delay[cpu_port_index];
|
|
+
|
|
+ val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) |
|
|
+ QCA8K_PORT_PAD_RGMII_RX_DELAY_EN;
|
|
+ }
|
|
+
|
|
+ /* Set RGMII delay based on the selected values */
|
|
+ ret = qca8k_rmw(priv, reg,
|
|
+ QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK |
|
|
+ QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK |
|
|
+ QCA8K_PORT_PAD_RGMII_TX_DELAY_EN |
|
|
+ QCA8K_PORT_PAD_RGMII_RX_DELAY_EN,
|
|
+ val);
|
|
+ if (ret)
|
|
+ dev_err(priv->dev, "Failed to set internal delay for CPU port%d",
|
|
+ cpu_port_index == QCA8K_CPU_PORT0 ? 0 : 6);
|
|
+}
|
|
+
|
|
+static void
|
|
qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
|
|
const struct phylink_link_state *state)
|
|
{
|
|
struct qca8k_priv *priv = ds->priv;
|
|
int cpu_port_index, ret;
|
|
- u32 reg, val, delay;
|
|
+ u32 reg, val;
|
|
|
|
switch (port) {
|
|
case 0: /* 1st CPU port */
|
|
@@ -1315,32 +1362,10 @@ qca8k_phylink_mac_config(struct dsa_swit
|
|
case PHY_INTERFACE_MODE_RGMII_ID:
|
|
case PHY_INTERFACE_MODE_RGMII_TXID:
|
|
case PHY_INTERFACE_MODE_RGMII_RXID:
|
|
- val = QCA8K_PORT_PAD_RGMII_EN;
|
|
-
|
|
- /* Delay can be declared in 3 different way.
|
|
- * Mode to rgmii and internal-delay standard binding defined
|
|
- * rgmii-id or rgmii-tx/rx phy mode set.
|
|
- * The parse logic set a delay different than 0 only when one
|
|
- * of the 3 different way is used. In all other case delay is
|
|
- * not enabled. With ID or TX/RXID delay is enabled and set
|
|
- * to the default and recommended value.
|
|
- */
|
|
- if (priv->rgmii_tx_delay[cpu_port_index]) {
|
|
- delay = priv->rgmii_tx_delay[cpu_port_index];
|
|
-
|
|
- val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) |
|
|
- QCA8K_PORT_PAD_RGMII_TX_DELAY_EN;
|
|
- }
|
|
-
|
|
- if (priv->rgmii_rx_delay[cpu_port_index]) {
|
|
- delay = priv->rgmii_rx_delay[cpu_port_index];
|
|
-
|
|
- val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) |
|
|
- QCA8K_PORT_PAD_RGMII_RX_DELAY_EN;
|
|
- }
|
|
+ qca8k_write(priv, reg, QCA8K_PORT_PAD_RGMII_EN);
|
|
|
|
- /* Set RGMII delay based on the selected values */
|
|
- qca8k_write(priv, reg, val);
|
|
+ /* Configure rgmii delay */
|
|
+ qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg);
|
|
|
|
/* QCA8337 requires to set rgmii rx delay for all ports.
|
|
* This is enabled through PORT5_PAD_CTRL for all ports,
|
|
@@ -1411,6 +1436,13 @@ qca8k_phylink_mac_config(struct dsa_swit
|
|
QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE |
|
|
QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE,
|
|
val);
|
|
+
|
|
+ /* From original code is reported port instability as SGMII also
|
|
+ * require delay set. Apply advised values here or take them from DT.
|
|
+ */
|
|
+ if (state->interface == PHY_INTERFACE_MODE_SGMII)
|
|
+ qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg);
|
|
+
|
|
break;
|
|
default:
|
|
dev_err(ds->dev, "xMII mode %s not supported for port %d\n",
|
|
--- a/drivers/net/dsa/qca8k.h
|
|
+++ b/drivers/net/dsa/qca8k.h
|
|
@@ -39,7 +39,9 @@
|
|
#define QCA8K_REG_PORT5_PAD_CTRL 0x008
|
|
#define QCA8K_REG_PORT6_PAD_CTRL 0x00c
|
|
#define QCA8K_PORT_PAD_RGMII_EN BIT(26)
|
|
+#define QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK GENMASK(23, 22)
|
|
#define QCA8K_PORT_PAD_RGMII_TX_DELAY(x) ((x) << 22)
|
|
+#define QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK GENMASK(21, 20)
|
|
#define QCA8K_PORT_PAD_RGMII_RX_DELAY(x) ((x) << 20)
|
|
#define QCA8K_PORT_PAD_RGMII_TX_DELAY_EN BIT(25)
|
|
#define QCA8K_PORT_PAD_RGMII_RX_DELAY_EN BIT(24)
|