kernel: 5.10: backport qca8k feature additions
Backport Ansuel Smith's various qca8k feature additions: - mac-power-sel support - SGMII PLL explicit enable - tx/rx clock phase to falling edge - power-on-sel and LED open drain mode - cpu port 6 - qca8328 support - sgmii internal delay - move port config to dedicated struct - convert to yaml schema Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com> Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
This commit is contained in:
parent
d888ef5668
commit
f97cafdd1d
16 changed files with 1991 additions and 0 deletions
|
@ -0,0 +1,80 @@
|
||||||
|
From d8b6f5bae6d3b648a67b6958cb98e4e97256d652 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
Date: Thu, 14 Oct 2021 00:39:06 +0200
|
||||||
|
Subject: dsa: qca8k: add mac_power_sel support
|
||||||
|
|
||||||
|
Add missing mac power sel support needed for ipq8064/5 SoC that require
|
||||||
|
1.8v for the internal regulator port instead of the default 1.5v.
|
||||||
|
If other device needs this, consider adding a dedicated binding to
|
||||||
|
support this.
|
||||||
|
|
||||||
|
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||||
|
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
|
||||||
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||||
|
---
|
||||||
|
drivers/net/dsa/qca8k.c | 31 +++++++++++++++++++++++++++++++
|
||||||
|
drivers/net/dsa/qca8k.h | 5 +++++
|
||||||
|
2 files changed, 36 insertions(+)
|
||||||
|
|
||||||
|
--- a/drivers/net/dsa/qca8k.c
|
||||||
|
+++ b/drivers/net/dsa/qca8k.c
|
||||||
|
@@ -951,6 +951,33 @@ qca8k_setup_of_rgmii_delay(struct qca8k_
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
+qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv)
|
||||||
|
+{
|
||||||
|
+ u32 mask = 0;
|
||||||
|
+ int ret = 0;
|
||||||
|
+
|
||||||
|
+ /* SoC specific settings for ipq8064.
|
||||||
|
+ * If more device require this consider adding
|
||||||
|
+ * a dedicated binding.
|
||||||
|
+ */
|
||||||
|
+ if (of_machine_is_compatible("qcom,ipq8064"))
|
||||||
|
+ mask |= QCA8K_MAC_PWR_RGMII0_1_8V;
|
||||||
|
+
|
||||||
|
+ /* SoC specific settings for ipq8065 */
|
||||||
|
+ if (of_machine_is_compatible("qcom,ipq8065"))
|
||||||
|
+ mask |= QCA8K_MAC_PWR_RGMII1_1_8V;
|
||||||
|
+
|
||||||
|
+ if (mask) {
|
||||||
|
+ ret = qca8k_rmw(priv, QCA8K_REG_MAC_PWR_SEL,
|
||||||
|
+ QCA8K_MAC_PWR_RGMII0_1_8V |
|
||||||
|
+ QCA8K_MAC_PWR_RGMII1_1_8V,
|
||||||
|
+ mask);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
qca8k_setup(struct dsa_switch *ds)
|
||||||
|
{
|
||||||
|
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
|
||||||
|
@@ -979,6 +1006,10 @@ qca8k_setup(struct dsa_switch *ds)
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
+ ret = qca8k_setup_mac_pwr_sel(priv);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
/* Enable CPU Port */
|
||||||
|
ret = qca8k_reg_set(priv, QCA8K_REG_GLOBAL_FW_CTRL0,
|
||||||
|
QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN);
|
||||||
|
--- a/drivers/net/dsa/qca8k.h
|
||||||
|
+++ b/drivers/net/dsa/qca8k.h
|
||||||
|
@@ -100,6 +100,11 @@
|
||||||
|
#define QCA8K_SGMII_MODE_CTRL_PHY (1 << 22)
|
||||||
|
#define QCA8K_SGMII_MODE_CTRL_MAC (2 << 22)
|
||||||
|
|
||||||
|
+/* MAC_PWR_SEL registers */
|
||||||
|
+#define QCA8K_REG_MAC_PWR_SEL 0x0e4
|
||||||
|
+#define QCA8K_MAC_PWR_RGMII1_1_8V BIT(18)
|
||||||
|
+#define QCA8K_MAC_PWR_RGMII0_1_8V BIT(19)
|
||||||
|
+
|
||||||
|
/* EEE control registers */
|
||||||
|
#define QCA8K_REG_EEE_CTRL 0x100
|
||||||
|
#define QCA8K_REG_EEE_CTRL_LPI_EN(_i) ((_i + 1) * 2)
|
|
@ -0,0 +1,30 @@
|
||||||
|
From fdbf35df9c091db9c46e57e9938e3f7a4f603a7c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
Date: Thu, 14 Oct 2021 00:39:07 +0200
|
||||||
|
Subject: dt-bindings: net: dsa: qca8k: Add SGMII clock phase properties
|
||||||
|
|
||||||
|
Add names and descriptions of additional PORT0_PAD_CTRL properties.
|
||||||
|
qca,sgmii-(rx|tx)clk-falling-edge are for setting the respective clock
|
||||||
|
phase to failling edge.
|
||||||
|
|
||||||
|
Co-developed-by: Matthew Hagan <mnhagan88@gmail.com>
|
||||||
|
Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
|
||||||
|
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||||
|
---
|
||||||
|
Documentation/devicetree/bindings/net/dsa/qca8k.txt | 4 ++++
|
||||||
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
|
--- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
|
||||||
|
+++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
|
||||||
|
@@ -37,6 +37,10 @@ A CPU port node has the following option
|
||||||
|
managed entity. See
|
||||||
|
Documentation/devicetree/bindings/net/fixed-link.txt
|
||||||
|
for details.
|
||||||
|
+- qca,sgmii-rxclk-falling-edge: Set the receive clock phase to falling edge.
|
||||||
|
+ Mostly used in qca8327 with CPU port 0 set to
|
||||||
|
+ sgmii.
|
||||||
|
+- qca,sgmii-txclk-falling-edge: Set the transmit clock phase to falling edge.
|
||||||
|
|
||||||
|
For QCA8K the 'fixed-link' sub-node supports only the following properties:
|
||||||
|
|
|
@ -0,0 +1,127 @@
|
||||||
|
From 6c43809bf1bee76c434e365a26546a92a5fbec14 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
Date: Thu, 14 Oct 2021 00:39:08 +0200
|
||||||
|
Subject: net: dsa: qca8k: add support for sgmii falling edge
|
||||||
|
|
||||||
|
Add support for this in the qca8k driver. Also add support for SGMII
|
||||||
|
rx/tx clock falling edge. This is only present for pad0, pad5 and
|
||||||
|
pad6 have these bit reserved from Documentation. Add a comment that this
|
||||||
|
is hardcoded to PAD0 as qca8327/28/34/37 have an unique sgmii line and
|
||||||
|
setting falling in port0 applies to both configuration with sgmii used
|
||||||
|
for port0 or port6.
|
||||||
|
|
||||||
|
Co-developed-by: Matthew Hagan <mnhagan88@gmail.com>
|
||||||
|
Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
|
||||||
|
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||||
|
---
|
||||||
|
drivers/net/dsa/qca8k.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
drivers/net/dsa/qca8k.h | 4 ++++
|
||||||
|
2 files changed, 67 insertions(+)
|
||||||
|
|
||||||
|
--- a/drivers/net/dsa/qca8k.c
|
||||||
|
+++ b/drivers/net/dsa/qca8k.c
|
||||||
|
@@ -978,6 +978,42 @@ qca8k_setup_mac_pwr_sel(struct qca8k_pri
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
+qca8k_parse_port_config(struct qca8k_priv *priv)
|
||||||
|
+{
|
||||||
|
+ struct device_node *port_dn;
|
||||||
|
+ phy_interface_t mode;
|
||||||
|
+ struct dsa_port *dp;
|
||||||
|
+ int port, ret;
|
||||||
|
+
|
||||||
|
+ /* We have 2 CPU port. Check them */
|
||||||
|
+ for (port = 0; port < QCA8K_NUM_PORTS; port++) {
|
||||||
|
+ /* Skip every other port */
|
||||||
|
+ if (port != 0 && port != 6)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ dp = dsa_to_port(priv->ds, port);
|
||||||
|
+ port_dn = dp->dn;
|
||||||
|
+
|
||||||
|
+ if (!of_device_is_available(port_dn))
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ ret = of_get_phy_mode(port_dn, &mode);
|
||||||
|
+ if (ret)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ if (mode == PHY_INTERFACE_MODE_SGMII) {
|
||||||
|
+ if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge"))
|
||||||
|
+ priv->sgmii_tx_clk_falling_edge = true;
|
||||||
|
+
|
||||||
|
+ if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge"))
|
||||||
|
+ priv->sgmii_rx_clk_falling_edge = true;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
qca8k_setup(struct dsa_switch *ds)
|
||||||
|
{
|
||||||
|
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
|
||||||
|
@@ -990,6 +1026,11 @@ qca8k_setup(struct dsa_switch *ds)
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /* Parse CPU port config to be later used in phy_link mac_config */
|
||||||
|
+ ret = qca8k_parse_port_config(priv);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
mutex_init(&priv->reg_mutex);
|
||||||
|
|
||||||
|
/* Start by setting up the register mapping */
|
||||||
|
@@ -1274,6 +1315,28 @@ qca8k_phylink_mac_config(struct dsa_swit
|
||||||
|
}
|
||||||
|
|
||||||
|
qca8k_write(priv, QCA8K_REG_SGMII_CTRL, val);
|
||||||
|
+
|
||||||
|
+ /* For qca8327/qca8328/qca8334/qca8338 sgmii is unique and
|
||||||
|
+ * falling edge is set writing in the PORT0 PAD reg
|
||||||
|
+ */
|
||||||
|
+ if (priv->switch_id == QCA8K_ID_QCA8327 ||
|
||||||
|
+ priv->switch_id == QCA8K_ID_QCA8337)
|
||||||
|
+ reg = QCA8K_REG_PORT0_PAD_CTRL;
|
||||||
|
+
|
||||||
|
+ val = 0;
|
||||||
|
+
|
||||||
|
+ /* SGMII Clock phase configuration */
|
||||||
|
+ if (priv->sgmii_rx_clk_falling_edge)
|
||||||
|
+ val |= QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE;
|
||||||
|
+
|
||||||
|
+ if (priv->sgmii_tx_clk_falling_edge)
|
||||||
|
+ val |= QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE;
|
||||||
|
+
|
||||||
|
+ if (val)
|
||||||
|
+ ret = qca8k_rmw(priv, reg,
|
||||||
|
+ QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE |
|
||||||
|
+ QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE,
|
||||||
|
+ val);
|
||||||
|
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
|
||||||
|
@@ -35,6 +35,8 @@
|
||||||
|
#define QCA8K_MASK_CTRL_DEVICE_ID_MASK GENMASK(15, 8)
|
||||||
|
#define QCA8K_MASK_CTRL_DEVICE_ID(x) ((x) >> 8)
|
||||||
|
#define QCA8K_REG_PORT0_PAD_CTRL 0x004
|
||||||
|
+#define QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE BIT(19)
|
||||||
|
+#define QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE BIT(18)
|
||||||
|
#define QCA8K_REG_PORT5_PAD_CTRL 0x008
|
||||||
|
#define QCA8K_REG_PORT6_PAD_CTRL 0x00c
|
||||||
|
#define QCA8K_PORT_PAD_RGMII_EN BIT(26)
|
||||||
|
@@ -260,6 +262,8 @@ struct qca8k_priv {
|
||||||
|
u8 switch_revision;
|
||||||
|
u8 rgmii_tx_delay;
|
||||||
|
u8 rgmii_rx_delay;
|
||||||
|
+ bool sgmii_rx_clk_falling_edge;
|
||||||
|
+ bool sgmii_tx_clk_falling_edge;
|
||||||
|
bool legacy_phy_port_mapping;
|
||||||
|
struct regmap *regmap;
|
||||||
|
struct mii_bus *bus;
|
|
@ -0,0 +1,29 @@
|
||||||
|
From 731d613338ec6de482053ffa3f71be2325b0f8eb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
Date: Thu, 14 Oct 2021 00:39:09 +0200
|
||||||
|
Subject: dt-bindings: net: dsa: qca8k: Document support for CPU port 6
|
||||||
|
|
||||||
|
The switch now support CPU port to be set 6 instead of be hardcoded to
|
||||||
|
0. Document support for it and describe logic selection.
|
||||||
|
|
||||||
|
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||||
|
---
|
||||||
|
Documentation/devicetree/bindings/net/dsa/qca8k.txt | 6 +++++-
|
||||||
|
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
|
||||||
|
+++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
|
||||||
|
@@ -29,7 +29,11 @@ the mdio MASTER is used as communication
|
||||||
|
Don't use mixed external and internal mdio-bus configurations, as this is
|
||||||
|
not supported by the hardware.
|
||||||
|
|
||||||
|
-The CPU port of this switch is always port 0.
|
||||||
|
+This switch support 2 CPU port. Normally and advised configuration is with
|
||||||
|
+CPU port set to port 0. It is also possible to set the CPU port to port 6
|
||||||
|
+if the device requires it. The driver will configure the switch to the defined
|
||||||
|
+port. With both CPU port declared the first CPU port is selected as primary
|
||||||
|
+and the secondary CPU ignored.
|
||||||
|
|
||||||
|
A CPU port node has the following optional node:
|
||||||
|
|
|
@ -0,0 +1,153 @@
|
||||||
|
From 3fcf734aa482487df83cf8f18608438fcf59127f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
Date: Thu, 14 Oct 2021 00:39:10 +0200
|
||||||
|
Subject: net: dsa: qca8k: add support for cpu port 6
|
||||||
|
|
||||||
|
Currently CPU port is always hardcoded to port 0. This switch have 2 CPU
|
||||||
|
ports. The original intention of this driver seems to be use the
|
||||||
|
mac06_exchange bit to swap MAC0 with MAC6 in the strange configuration
|
||||||
|
where device have connected only the CPU port 6. To skip the
|
||||||
|
introduction of a new binding, rework the driver to address the
|
||||||
|
secondary CPU port as primary and drop any reference of hardcoded port.
|
||||||
|
With configuration of mac06 exchange, just skip the definition of port0
|
||||||
|
and define the CPU port as a secondary. The driver will autoconfigure
|
||||||
|
the switch to use that as the primary CPU port.
|
||||||
|
|
||||||
|
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||||
|
---
|
||||||
|
drivers/net/dsa/qca8k.c | 51 ++++++++++++++++++++++++++++++++++---------------
|
||||||
|
drivers/net/dsa/qca8k.h | 2 --
|
||||||
|
2 files changed, 36 insertions(+), 17 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/dsa/qca8k.c
|
||||||
|
+++ b/drivers/net/dsa/qca8k.c
|
||||||
|
@@ -977,6 +977,22 @@ qca8k_setup_mac_pwr_sel(struct qca8k_pri
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int qca8k_find_cpu_port(struct dsa_switch *ds)
|
||||||
|
+{
|
||||||
|
+ struct qca8k_priv *priv = ds->priv;
|
||||||
|
+
|
||||||
|
+ /* Find the connected cpu port. Valid port are 0 or 6 */
|
||||||
|
+ if (dsa_is_cpu_port(ds, 0))
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ dev_dbg(priv->dev, "port 0 is not the CPU port. Checking port 6");
|
||||||
|
+
|
||||||
|
+ if (dsa_is_cpu_port(ds, 6))
|
||||||
|
+ return 6;
|
||||||
|
+
|
||||||
|
+ return -EINVAL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int
|
||||||
|
qca8k_parse_port_config(struct qca8k_priv *priv)
|
||||||
|
{
|
||||||
|
@@ -1017,13 +1033,13 @@ static int
|
||||||
|
qca8k_setup(struct dsa_switch *ds)
|
||||||
|
{
|
||||||
|
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
|
||||||
|
- int ret, i;
|
||||||
|
+ int cpu_port, ret, i;
|
||||||
|
u32 mask;
|
||||||
|
|
||||||
|
- /* Make sure that port 0 is the cpu port */
|
||||||
|
- if (!dsa_is_cpu_port(ds, 0)) {
|
||||||
|
- dev_err(priv->dev, "port 0 is not the CPU port");
|
||||||
|
- return -EINVAL;
|
||||||
|
+ cpu_port = qca8k_find_cpu_port(ds);
|
||||||
|
+ if (cpu_port < 0) {
|
||||||
|
+ dev_err(priv->dev, "No cpu port configured in both cpu port0 and port6");
|
||||||
|
+ return cpu_port;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse CPU port config to be later used in phy_link mac_config */
|
||||||
|
@@ -1065,7 +1081,7 @@ qca8k_setup(struct dsa_switch *ds)
|
||||||
|
dev_warn(priv->dev, "mib init failed");
|
||||||
|
|
||||||
|
/* Enable QCA header mode on the cpu port */
|
||||||
|
- ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(QCA8K_CPU_PORT),
|
||||||
|
+ ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(cpu_port),
|
||||||
|
QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_TX_S |
|
||||||
|
QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_RX_S);
|
||||||
|
if (ret) {
|
||||||
|
@@ -1087,10 +1103,10 @@ qca8k_setup(struct dsa_switch *ds)
|
||||||
|
|
||||||
|
/* Forward all unknown frames to CPU port for Linux processing */
|
||||||
|
ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1,
|
||||||
|
- BIT(0) << QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S |
|
||||||
|
- BIT(0) << QCA8K_GLOBAL_FW_CTRL1_BC_DP_S |
|
||||||
|
- BIT(0) << QCA8K_GLOBAL_FW_CTRL1_MC_DP_S |
|
||||||
|
- BIT(0) << QCA8K_GLOBAL_FW_CTRL1_UC_DP_S);
|
||||||
|
+ BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S |
|
||||||
|
+ BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_BC_DP_S |
|
||||||
|
+ BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_MC_DP_S |
|
||||||
|
+ BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_UC_DP_S);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
@@ -1098,7 +1114,7 @@ qca8k_setup(struct dsa_switch *ds)
|
||||||
|
for (i = 0; i < QCA8K_NUM_PORTS; i++) {
|
||||||
|
/* CPU port gets connected to all user ports of the switch */
|
||||||
|
if (dsa_is_cpu_port(ds, i)) {
|
||||||
|
- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(QCA8K_CPU_PORT),
|
||||||
|
+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(cpu_port),
|
||||||
|
QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds));
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
@@ -1110,7 +1126,7 @@ qca8k_setup(struct dsa_switch *ds)
|
||||||
|
|
||||||
|
ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
|
||||||
|
QCA8K_PORT_LOOKUP_MEMBER,
|
||||||
|
- BIT(QCA8K_CPU_PORT));
|
||||||
|
+ BIT(cpu_port));
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
@@ -1616,9 +1632,12 @@ static int
|
||||||
|
qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br)
|
||||||
|
{
|
||||||
|
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
|
||||||
|
- int port_mask = BIT(QCA8K_CPU_PORT);
|
||||||
|
+ int port_mask, cpu_port;
|
||||||
|
int i, ret;
|
||||||
|
|
||||||
|
+ cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
|
||||||
|
+ port_mask = BIT(cpu_port);
|
||||||
|
+
|
||||||
|
for (i = 1; i < QCA8K_NUM_PORTS; i++) {
|
||||||
|
if (dsa_to_port(ds, i)->bridge_dev != br)
|
||||||
|
continue;
|
||||||
|
@@ -1645,7 +1664,9 @@ static void
|
||||||
|
qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br)
|
||||||
|
{
|
||||||
|
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
|
||||||
|
- int i;
|
||||||
|
+ int cpu_port, i;
|
||||||
|
+
|
||||||
|
+ cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
|
||||||
|
|
||||||
|
for (i = 1; i < QCA8K_NUM_PORTS; i++) {
|
||||||
|
if (dsa_to_port(ds, i)->bridge_dev != br)
|
||||||
|
@@ -1662,7 +1683,7 @@ qca8k_port_bridge_leave(struct dsa_switc
|
||||||
|
* this port
|
||||||
|
*/
|
||||||
|
qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
|
||||||
|
- QCA8K_PORT_LOOKUP_MEMBER, BIT(QCA8K_CPU_PORT));
|
||||||
|
+ QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
--- a/drivers/net/dsa/qca8k.h
|
||||||
|
+++ b/drivers/net/dsa/qca8k.h
|
||||||
|
@@ -24,8 +24,6 @@
|
||||||
|
|
||||||
|
#define QCA8K_NUM_FDB_RECORDS 2048
|
||||||
|
|
||||||
|
-#define QCA8K_CPU_PORT 0
|
||||||
|
-
|
||||||
|
#define QCA8K_PORT_VID_DEF 1
|
||||||
|
|
||||||
|
/* Global control registers */
|
|
@ -0,0 +1,295 @@
|
||||||
|
From 5654ec78dd7e64b1e04777b24007344329e6a63b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
Date: Thu, 14 Oct 2021 00:39:11 +0200
|
||||||
|
Subject: net: dsa: qca8k: rework rgmii delay logic and scan for cpu port 6
|
||||||
|
|
||||||
|
Future proof commit. This switch have 2 CPU ports and one valid
|
||||||
|
configuration is first CPU port set to sgmii and second CPU port set to
|
||||||
|
rgmii-id. The current implementation detects delay only for CPU port
|
||||||
|
zero set to rgmii and doesn't count any delay set in a secondary CPU
|
||||||
|
port. Drop the current delay scan function and move it to the sgmii
|
||||||
|
parser function to generalize and implicitly add support for secondary
|
||||||
|
CPU port set to rgmii-id. Introduce new logic where delay is enabled
|
||||||
|
also with internal delay binding declared and rgmii set as PHY mode.
|
||||||
|
|
||||||
|
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||||
|
---
|
||||||
|
drivers/net/dsa/qca8k.c | 165 ++++++++++++++++++++++++------------------------
|
||||||
|
drivers/net/dsa/qca8k.h | 10 ++-
|
||||||
|
2 files changed, 89 insertions(+), 86 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/dsa/qca8k.c
|
||||||
|
+++ b/drivers/net/dsa/qca8k.c
|
||||||
|
@@ -889,68 +889,6 @@ qca8k_setup_mdio_bus(struct qca8k_priv *
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
-qca8k_setup_of_rgmii_delay(struct qca8k_priv *priv)
|
||||||
|
-{
|
||||||
|
- struct device_node *port_dn;
|
||||||
|
- phy_interface_t mode;
|
||||||
|
- struct dsa_port *dp;
|
||||||
|
- u32 val;
|
||||||
|
-
|
||||||
|
- /* CPU port is already checked */
|
||||||
|
- dp = dsa_to_port(priv->ds, 0);
|
||||||
|
-
|
||||||
|
- port_dn = dp->dn;
|
||||||
|
-
|
||||||
|
- /* Check if port 0 is set to the correct type */
|
||||||
|
- of_get_phy_mode(port_dn, &mode);
|
||||||
|
- if (mode != PHY_INTERFACE_MODE_RGMII_ID &&
|
||||||
|
- mode != PHY_INTERFACE_MODE_RGMII_RXID &&
|
||||||
|
- mode != PHY_INTERFACE_MODE_RGMII_TXID) {
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- switch (mode) {
|
||||||
|
- case PHY_INTERFACE_MODE_RGMII_ID:
|
||||||
|
- case PHY_INTERFACE_MODE_RGMII_RXID:
|
||||||
|
- if (of_property_read_u32(port_dn, "rx-internal-delay-ps", &val))
|
||||||
|
- val = 2;
|
||||||
|
- else
|
||||||
|
- /* Switch regs accept value in ns, convert ps to ns */
|
||||||
|
- val = val / 1000;
|
||||||
|
-
|
||||||
|
- if (val > QCA8K_MAX_DELAY) {
|
||||||
|
- dev_err(priv->dev, "rgmii rx delay is limited to a max value of 3ns, setting to the max value");
|
||||||
|
- val = 3;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- priv->rgmii_rx_delay = val;
|
||||||
|
- /* Stop here if we need to check only for rx delay */
|
||||||
|
- if (mode != PHY_INTERFACE_MODE_RGMII_ID)
|
||||||
|
- break;
|
||||||
|
-
|
||||||
|
- fallthrough;
|
||||||
|
- case PHY_INTERFACE_MODE_RGMII_TXID:
|
||||||
|
- if (of_property_read_u32(port_dn, "tx-internal-delay-ps", &val))
|
||||||
|
- val = 1;
|
||||||
|
- else
|
||||||
|
- /* Switch regs accept value in ns, convert ps to ns */
|
||||||
|
- val = val / 1000;
|
||||||
|
-
|
||||||
|
- if (val > QCA8K_MAX_DELAY) {
|
||||||
|
- dev_err(priv->dev, "rgmii tx delay is limited to a max value of 3ns, setting to the max value");
|
||||||
|
- val = 3;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- priv->rgmii_tx_delay = val;
|
||||||
|
- break;
|
||||||
|
- default:
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- return 0;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static int
|
||||||
|
qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv)
|
||||||
|
{
|
||||||
|
u32 mask = 0;
|
||||||
|
@@ -996,19 +934,21 @@ static int qca8k_find_cpu_port(struct ds
|
||||||
|
static int
|
||||||
|
qca8k_parse_port_config(struct qca8k_priv *priv)
|
||||||
|
{
|
||||||
|
+ int port, cpu_port_index = 0, ret;
|
||||||
|
struct device_node *port_dn;
|
||||||
|
phy_interface_t mode;
|
||||||
|
struct dsa_port *dp;
|
||||||
|
- int port, ret;
|
||||||
|
+ u32 delay;
|
||||||
|
|
||||||
|
/* We have 2 CPU port. Check them */
|
||||||
|
- for (port = 0; port < QCA8K_NUM_PORTS; port++) {
|
||||||
|
+ for (port = 0; port < QCA8K_NUM_PORTS && cpu_port_index < QCA8K_NUM_CPU_PORTS; port++) {
|
||||||
|
/* Skip every other port */
|
||||||
|
if (port != 0 && port != 6)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
dp = dsa_to_port(priv->ds, port);
|
||||||
|
port_dn = dp->dn;
|
||||||
|
+ cpu_port_index++;
|
||||||
|
|
||||||
|
if (!of_device_is_available(port_dn))
|
||||||
|
continue;
|
||||||
|
@@ -1017,12 +957,54 @@ qca8k_parse_port_config(struct qca8k_pri
|
||||||
|
if (ret)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
- if (mode == PHY_INTERFACE_MODE_SGMII) {
|
||||||
|
+ switch (mode) {
|
||||||
|
+ case PHY_INTERFACE_MODE_RGMII:
|
||||||
|
+ case PHY_INTERFACE_MODE_RGMII_ID:
|
||||||
|
+ case PHY_INTERFACE_MODE_RGMII_TXID:
|
||||||
|
+ case PHY_INTERFACE_MODE_RGMII_RXID:
|
||||||
|
+ delay = 0;
|
||||||
|
+
|
||||||
|
+ if (!of_property_read_u32(port_dn, "tx-internal-delay-ps", &delay))
|
||||||
|
+ /* Switch regs accept value in ns, convert ps to ns */
|
||||||
|
+ delay = delay / 1000;
|
||||||
|
+ else if (mode == PHY_INTERFACE_MODE_RGMII_ID ||
|
||||||
|
+ mode == PHY_INTERFACE_MODE_RGMII_TXID)
|
||||||
|
+ delay = 1;
|
||||||
|
+
|
||||||
|
+ if (delay > QCA8K_MAX_DELAY) {
|
||||||
|
+ dev_err(priv->dev, "rgmii tx delay is limited to a max value of 3ns, setting to the max value");
|
||||||
|
+ delay = 3;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ priv->rgmii_tx_delay[cpu_port_index] = delay;
|
||||||
|
+
|
||||||
|
+ delay = 0;
|
||||||
|
+
|
||||||
|
+ if (!of_property_read_u32(port_dn, "rx-internal-delay-ps", &delay))
|
||||||
|
+ /* Switch regs accept value in ns, convert ps to ns */
|
||||||
|
+ delay = delay / 1000;
|
||||||
|
+ else if (mode == PHY_INTERFACE_MODE_RGMII_ID ||
|
||||||
|
+ mode == PHY_INTERFACE_MODE_RGMII_RXID)
|
||||||
|
+ delay = 2;
|
||||||
|
+
|
||||||
|
+ if (delay > QCA8K_MAX_DELAY) {
|
||||||
|
+ dev_err(priv->dev, "rgmii rx delay is limited to a max value of 3ns, setting to the max value");
|
||||||
|
+ delay = 3;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ priv->rgmii_rx_delay[cpu_port_index] = delay;
|
||||||
|
+
|
||||||
|
+ break;
|
||||||
|
+ case PHY_INTERFACE_MODE_SGMII:
|
||||||
|
if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge"))
|
||||||
|
priv->sgmii_tx_clk_falling_edge = true;
|
||||||
|
|
||||||
|
if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge"))
|
||||||
|
priv->sgmii_rx_clk_falling_edge = true;
|
||||||
|
+
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1059,10 +1041,6 @@ qca8k_setup(struct dsa_switch *ds)
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
- ret = qca8k_setup_of_rgmii_delay(priv);
|
||||||
|
- if (ret)
|
||||||
|
- return ret;
|
||||||
|
-
|
||||||
|
ret = qca8k_setup_mac_pwr_sel(priv);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
@@ -1229,8 +1207,8 @@ qca8k_phylink_mac_config(struct dsa_swit
|
||||||
|
const struct phylink_link_state *state)
|
||||||
|
{
|
||||||
|
struct qca8k_priv *priv = ds->priv;
|
||||||
|
- u32 reg, val;
|
||||||
|
- int ret;
|
||||||
|
+ int cpu_port_index, ret;
|
||||||
|
+ u32 reg, val, delay;
|
||||||
|
|
||||||
|
switch (port) {
|
||||||
|
case 0: /* 1st CPU port */
|
||||||
|
@@ -1242,6 +1220,7 @@ qca8k_phylink_mac_config(struct dsa_swit
|
||||||
|
return;
|
||||||
|
|
||||||
|
reg = QCA8K_REG_PORT0_PAD_CTRL;
|
||||||
|
+ cpu_port_index = QCA8K_CPU_PORT0;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
@@ -1260,6 +1239,7 @@ qca8k_phylink_mac_config(struct dsa_swit
|
||||||
|
return;
|
||||||
|
|
||||||
|
reg = QCA8K_REG_PORT6_PAD_CTRL;
|
||||||
|
+ cpu_port_index = QCA8K_CPU_PORT6;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port);
|
||||||
|
@@ -1274,23 +1254,40 @@ qca8k_phylink_mac_config(struct dsa_swit
|
||||||
|
|
||||||
|
switch (state->interface) {
|
||||||
|
case PHY_INTERFACE_MODE_RGMII:
|
||||||
|
- /* RGMII mode means no delay so don't enable the delay */
|
||||||
|
- qca8k_write(priv, reg, QCA8K_PORT_PAD_RGMII_EN);
|
||||||
|
- break;
|
||||||
|
case PHY_INTERFACE_MODE_RGMII_ID:
|
||||||
|
case PHY_INTERFACE_MODE_RGMII_TXID:
|
||||||
|
case PHY_INTERFACE_MODE_RGMII_RXID:
|
||||||
|
- /* RGMII_ID needs internal delay. This is enabled through
|
||||||
|
- * PORT5_PAD_CTRL for all ports, rather than individual port
|
||||||
|
- * registers
|
||||||
|
+ 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;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Set RGMII delay based on the selected values */
|
||||||
|
+ qca8k_write(priv, reg, val);
|
||||||
|
+
|
||||||
|
+ /* QCA8337 requires to set rgmii rx delay for all ports.
|
||||||
|
+ * This is enabled through PORT5_PAD_CTRL for all ports,
|
||||||
|
+ * rather than individual port registers.
|
||||||
|
*/
|
||||||
|
- qca8k_write(priv, reg,
|
||||||
|
- QCA8K_PORT_PAD_RGMII_EN |
|
||||||
|
- QCA8K_PORT_PAD_RGMII_TX_DELAY(priv->rgmii_tx_delay) |
|
||||||
|
- QCA8K_PORT_PAD_RGMII_RX_DELAY(priv->rgmii_rx_delay) |
|
||||||
|
- QCA8K_PORT_PAD_RGMII_TX_DELAY_EN |
|
||||||
|
- QCA8K_PORT_PAD_RGMII_RX_DELAY_EN);
|
||||||
|
- /* QCA8337 requires to set rgmii rx delay */
|
||||||
|
if (priv->switch_id == QCA8K_ID_QCA8337)
|
||||||
|
qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL,
|
||||||
|
QCA8K_PORT_PAD_RGMII_RX_DELAY_EN);
|
||||||
|
--- a/drivers/net/dsa/qca8k.h
|
||||||
|
+++ b/drivers/net/dsa/qca8k.h
|
||||||
|
@@ -13,6 +13,7 @@
|
||||||
|
#include <linux/gpio.h>
|
||||||
|
|
||||||
|
#define QCA8K_NUM_PORTS 7
|
||||||
|
+#define QCA8K_NUM_CPU_PORTS 2
|
||||||
|
#define QCA8K_MAX_MTU 9000
|
||||||
|
|
||||||
|
#define PHY_ID_QCA8327 0x004dd034
|
||||||
|
@@ -255,13 +256,18 @@ struct qca8k_match_data {
|
||||||
|
u8 id;
|
||||||
|
};
|
||||||
|
|
||||||
|
+enum {
|
||||||
|
+ QCA8K_CPU_PORT0,
|
||||||
|
+ QCA8K_CPU_PORT6,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
struct qca8k_priv {
|
||||||
|
u8 switch_id;
|
||||||
|
u8 switch_revision;
|
||||||
|
- u8 rgmii_tx_delay;
|
||||||
|
- u8 rgmii_rx_delay;
|
||||||
|
bool sgmii_rx_clk_falling_edge;
|
||||||
|
bool sgmii_tx_clk_falling_edge;
|
||||||
|
+ u8 rgmii_rx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
|
||||||
|
+ u8 rgmii_tx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
|
||||||
|
bool legacy_phy_port_mapping;
|
||||||
|
struct regmap *regmap;
|
||||||
|
struct mii_bus *bus;
|
|
@ -0,0 +1,33 @@
|
||||||
|
From 13ad5ccc093ff448b99ac7e138e91e78796adb48 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
Date: Thu, 14 Oct 2021 00:39:12 +0200
|
||||||
|
Subject: dt-bindings: net: dsa: qca8k: Document qca,sgmii-enable-pll
|
||||||
|
|
||||||
|
Document qca,sgmii-enable-pll binding used in the CPU nodes to
|
||||||
|
enable SGMII PLL on MAC config.
|
||||||
|
|
||||||
|
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||||
|
---
|
||||||
|
Documentation/devicetree/bindings/net/dsa/qca8k.txt | 10 ++++++++++
|
||||||
|
1 file changed, 10 insertions(+)
|
||||||
|
|
||||||
|
--- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
|
||||||
|
+++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
|
||||||
|
@@ -45,6 +45,16 @@ A CPU port node has the following option
|
||||||
|
Mostly used in qca8327 with CPU port 0 set to
|
||||||
|
sgmii.
|
||||||
|
- qca,sgmii-txclk-falling-edge: Set the transmit clock phase to falling edge.
|
||||||
|
+- qca,sgmii-enable-pll : For SGMII CPU port, explicitly enable PLL, TX and RX
|
||||||
|
+ chain along with Signal Detection.
|
||||||
|
+ This should NOT be enabled for qca8327. If enabled with
|
||||||
|
+ qca8327 the sgmii port won't correctly init and an err
|
||||||
|
+ is printed.
|
||||||
|
+ This can be required for qca8337 switch with revision 2.
|
||||||
|
+ A warning is displayed when used with revision greater
|
||||||
|
+ 2.
|
||||||
|
+ With CPU port set to sgmii and qca8337 it is advised
|
||||||
|
+ to set this unless a communication problem is observed.
|
||||||
|
|
||||||
|
For QCA8K the 'fixed-link' sub-node supports only the following properties:
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
From bbc4799e8bb6c397e3b3fec13de68e179f5db9ff Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
Date: Thu, 14 Oct 2021 00:39:13 +0200
|
||||||
|
Subject: net: dsa: qca8k: add explicit SGMII PLL enable
|
||||||
|
|
||||||
|
Support enabling PLL on the SGMII CPU port. Some device require this
|
||||||
|
special configuration or no traffic is transmitted and the switch
|
||||||
|
doesn't work at all. A dedicated binding is added to the CPU node
|
||||||
|
port to apply the correct reg on mac config.
|
||||||
|
Fail to correctly configure sgmii with qca8327 switch and warn if pll is
|
||||||
|
used on qca8337 with a revision greater than 1.
|
||||||
|
|
||||||
|
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
|
||||||
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||||
|
---
|
||||||
|
drivers/net/dsa/qca8k.c | 19 +++++++++++++++++--
|
||||||
|
drivers/net/dsa/qca8k.h | 1 +
|
||||||
|
2 files changed, 18 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/dsa/qca8k.c
|
||||||
|
+++ b/drivers/net/dsa/qca8k.c
|
||||||
|
@@ -1002,6 +1002,18 @@ qca8k_parse_port_config(struct qca8k_pri
|
||||||
|
if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge"))
|
||||||
|
priv->sgmii_rx_clk_falling_edge = true;
|
||||||
|
|
||||||
|
+ if (of_property_read_bool(port_dn, "qca,sgmii-enable-pll")) {
|
||||||
|
+ priv->sgmii_enable_pll = true;
|
||||||
|
+
|
||||||
|
+ if (priv->switch_id == QCA8K_ID_QCA8327) {
|
||||||
|
+ dev_err(priv->dev, "SGMII PLL should NOT be enabled for qca8327. Aborting enabling");
|
||||||
|
+ priv->sgmii_enable_pll = false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (priv->switch_revision < 2)
|
||||||
|
+ dev_warn(priv->dev, "SGMII PLL should NOT be enabled for qca8337 with revision 2 or more.");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
|
@@ -1312,8 +1324,11 @@ qca8k_phylink_mac_config(struct dsa_swit
|
||||||
|
if (ret)
|
||||||
|
return;
|
||||||
|
|
||||||
|
- val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX |
|
||||||
|
- QCA8K_SGMII_EN_TX | QCA8K_SGMII_EN_SD;
|
||||||
|
+ val |= QCA8K_SGMII_EN_SD;
|
||||||
|
+
|
||||||
|
+ if (priv->sgmii_enable_pll)
|
||||||
|
+ val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX |
|
||||||
|
+ QCA8K_SGMII_EN_TX;
|
||||||
|
|
||||||
|
if (dsa_is_cpu_port(ds, port)) {
|
||||||
|
/* CPU port, we're talking to the CPU MAC, be a PHY */
|
||||||
|
--- a/drivers/net/dsa/qca8k.h
|
||||||
|
+++ b/drivers/net/dsa/qca8k.h
|
||||||
|
@@ -266,6 +266,7 @@ struct qca8k_priv {
|
||||||
|
u8 switch_revision;
|
||||||
|
bool sgmii_rx_clk_falling_edge;
|
||||||
|
bool sgmii_tx_clk_falling_edge;
|
||||||
|
+ bool sgmii_enable_pll;
|
||||||
|
u8 rgmii_rx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
|
||||||
|
u8 rgmii_tx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
|
||||||
|
bool legacy_phy_port_mapping;
|
|
@ -0,0 +1,37 @@
|
||||||
|
From 924087c5c3d41553700b0eb83ca2a53b91643dca Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
Date: Thu, 14 Oct 2021 00:39:14 +0200
|
||||||
|
Subject: dt-bindings: net: dsa: qca8k: Document qca,led-open-drain binding
|
||||||
|
|
||||||
|
Document new binding qca,ignore-power-on-sel used to ignore
|
||||||
|
power on strapping and use sw regs instead.
|
||||||
|
Document qca,led-open.drain to set led to open drain mode, the
|
||||||
|
qca,ignore-power-on-sel is mandatory with this enabled or an error will
|
||||||
|
be reported.
|
||||||
|
|
||||||
|
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||||
|
---
|
||||||
|
Documentation/devicetree/bindings/net/dsa/qca8k.txt | 11 +++++++++++
|
||||||
|
1 file changed, 11 insertions(+)
|
||||||
|
|
||||||
|
--- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
|
||||||
|
+++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
|
||||||
|
@@ -13,6 +13,17 @@ Required properties:
|
||||||
|
Optional properties:
|
||||||
|
|
||||||
|
- reset-gpios: GPIO to be used to reset the whole device
|
||||||
|
+- qca,ignore-power-on-sel: Ignore power on pin strapping to configure led open
|
||||||
|
+ drain or eeprom presence. This is needed for broken
|
||||||
|
+ devices that have wrong configuration or when the oem
|
||||||
|
+ decided to not use pin strapping and fallback to sw
|
||||||
|
+ regs.
|
||||||
|
+- qca,led-open-drain: Set leds to open-drain mode. This requires the
|
||||||
|
+ qca,ignore-power-on-sel to be set or the driver will fail
|
||||||
|
+ to probe. This is needed if the oem doesn't use pin
|
||||||
|
+ strapping to set this mode and prefers to set it using sw
|
||||||
|
+ regs. The pin strapping related to led open drain mode is
|
||||||
|
+ the pin B68 for QCA832x and B49 for QCA833x
|
||||||
|
|
||||||
|
Subnodes:
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
From 362bb238d8bf1470424214a8a5968d9c6cce68fa Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
Date: Thu, 14 Oct 2021 00:39:15 +0200
|
||||||
|
Subject: net: dsa: qca8k: add support for pws config reg
|
||||||
|
|
||||||
|
Some qca8327 switch require to force the ignore of power on sel
|
||||||
|
strapping. Some switch require to set the led open drain mode in regs
|
||||||
|
instead of using strapping. While most of the device implements this
|
||||||
|
using the correct way using pin strapping, there are still some broken
|
||||||
|
device that require to be set using sw regs.
|
||||||
|
Introduce a new binding and support these special configuration.
|
||||||
|
As led open drain require to ignore pin strapping to work, the probe
|
||||||
|
fails with EINVAL error with incorrect configuration.
|
||||||
|
|
||||||
|
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
|
||||||
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||||
|
---
|
||||||
|
drivers/net/dsa/qca8k.c | 39 +++++++++++++++++++++++++++++++++++++++
|
||||||
|
drivers/net/dsa/qca8k.h | 6 ++++++
|
||||||
|
2 files changed, 45 insertions(+)
|
||||||
|
|
||||||
|
--- a/drivers/net/dsa/qca8k.c
|
||||||
|
+++ b/drivers/net/dsa/qca8k.c
|
||||||
|
@@ -932,6 +932,41 @@ static int qca8k_find_cpu_port(struct ds
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
+qca8k_setup_of_pws_reg(struct qca8k_priv *priv)
|
||||||
|
+{
|
||||||
|
+ struct device_node *node = priv->dev->of_node;
|
||||||
|
+ u32 val = 0;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ /* QCA8327 require to set to the correct mode.
|
||||||
|
+ * His bigger brother QCA8328 have the 172 pin layout.
|
||||||
|
+ * Should be applied by default but we set this just to make sure.
|
||||||
|
+ */
|
||||||
|
+ if (priv->switch_id == QCA8K_ID_QCA8327) {
|
||||||
|
+ ret = qca8k_rmw(priv, QCA8K_REG_PWS, QCA8327_PWS_PACKAGE148_EN,
|
||||||
|
+ QCA8327_PWS_PACKAGE148_EN);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (of_property_read_bool(node, "qca,ignore-power-on-sel"))
|
||||||
|
+ val |= QCA8K_PWS_POWER_ON_SEL;
|
||||||
|
+
|
||||||
|
+ if (of_property_read_bool(node, "qca,led-open-drain")) {
|
||||||
|
+ if (!(val & QCA8K_PWS_POWER_ON_SEL)) {
|
||||||
|
+ dev_err(priv->dev, "qca,led-open-drain require qca,ignore-power-on-sel to be set.");
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ val |= QCA8K_PWS_LED_OPEN_EN_CSR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return qca8k_rmw(priv, QCA8K_REG_PWS,
|
||||||
|
+ QCA8K_PWS_LED_OPEN_EN_CSR | QCA8K_PWS_POWER_ON_SEL,
|
||||||
|
+ val);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
qca8k_parse_port_config(struct qca8k_priv *priv)
|
||||||
|
{
|
||||||
|
int port, cpu_port_index = 0, ret;
|
||||||
|
@@ -1053,6 +1088,10 @@ qca8k_setup(struct dsa_switch *ds)
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
+ ret = qca8k_setup_of_pws_reg(priv);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
ret = qca8k_setup_mac_pwr_sel(priv);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
--- a/drivers/net/dsa/qca8k.h
|
||||||
|
+++ b/drivers/net/dsa/qca8k.h
|
||||||
|
@@ -46,6 +46,12 @@
|
||||||
|
#define QCA8K_MAX_DELAY 3
|
||||||
|
#define QCA8K_PORT_PAD_SGMII_EN BIT(7)
|
||||||
|
#define QCA8K_REG_PWS 0x010
|
||||||
|
+#define QCA8K_PWS_POWER_ON_SEL BIT(31)
|
||||||
|
+/* This reg is only valid for QCA832x and toggle the package
|
||||||
|
+ * type from 176 pin (by default) to 148 pin used on QCA8327
|
||||||
|
+ */
|
||||||
|
+#define QCA8327_PWS_PACKAGE148_EN BIT(30)
|
||||||
|
+#define QCA8K_PWS_LED_OPEN_EN_CSR BIT(24)
|
||||||
|
#define QCA8K_PWS_SERDES_AEN_DIS BIT(7)
|
||||||
|
#define QCA8K_REG_MODULE_EN 0x030
|
||||||
|
#define QCA8K_MODULE_EN_MIB BIT(0)
|
|
@ -0,0 +1,32 @@
|
||||||
|
From ed7988d77fbfb79366b68f9e7fa60a6080da23d4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
Date: Thu, 14 Oct 2021 00:39:16 +0200
|
||||||
|
Subject: dt-bindings: net: dsa: qca8k: document support for qca8328
|
||||||
|
|
||||||
|
QCA8328 is the bigger brother of qca8327. Document the new compatible
|
||||||
|
binding and add some information to understand the various switch
|
||||||
|
compatible.
|
||||||
|
|
||||||
|
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
|
||||||
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||||
|
---
|
||||||
|
Documentation/devicetree/bindings/net/dsa/qca8k.txt | 7 ++++---
|
||||||
|
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
--- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
|
||||||
|
+++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
|
||||||
|
@@ -3,9 +3,10 @@
|
||||||
|
Required properties:
|
||||||
|
|
||||||
|
- compatible: should be one of:
|
||||||
|
- "qca,qca8327"
|
||||||
|
- "qca,qca8334"
|
||||||
|
- "qca,qca8337"
|
||||||
|
+ "qca,qca8328": referenced as AR8328(N)-AK1(A/B) QFN 176 pin package
|
||||||
|
+ "qca,qca8327": referenced as AR8327(N)-AL1A DR-QFN 148 pin package
|
||||||
|
+ "qca,qca8334": referenced as QCA8334-AL3C QFN 88 pin package
|
||||||
|
+ "qca,qca8337": referenced as QCA8337N-AL3(B/C) DR-QFN 148 pin package
|
||||||
|
|
||||||
|
- #size-cells: must be 0
|
||||||
|
- #address-cells: must be 1
|
|
@ -0,0 +1,78 @@
|
||||||
|
From f477d1c8bdbef4f400718238e350f16f521d2a3e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
Date: Thu, 14 Oct 2021 00:39:17 +0200
|
||||||
|
Subject: net: dsa: qca8k: add support for QCA8328
|
||||||
|
|
||||||
|
QCA8328 switch is the bigger brother of the qca8327. Same regs different
|
||||||
|
chip. Change the function to set the correct pin layout and introduce a
|
||||||
|
new match_data to differentiate the 2 switch as they have the same ID
|
||||||
|
and their internal PHY have the same ID.
|
||||||
|
|
||||||
|
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
|
||||||
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||||
|
---
|
||||||
|
drivers/net/dsa/qca8k.c | 19 ++++++++++++++++---
|
||||||
|
drivers/net/dsa/qca8k.h | 1 +
|
||||||
|
2 files changed, 17 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/dsa/qca8k.c
|
||||||
|
+++ b/drivers/net/dsa/qca8k.c
|
||||||
|
@@ -935,6 +935,7 @@ static int
|
||||||
|
qca8k_setup_of_pws_reg(struct qca8k_priv *priv)
|
||||||
|
{
|
||||||
|
struct device_node *node = priv->dev->of_node;
|
||||||
|
+ const struct qca8k_match_data *data;
|
||||||
|
u32 val = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
@@ -943,8 +944,14 @@ qca8k_setup_of_pws_reg(struct qca8k_priv
|
||||||
|
* Should be applied by default but we set this just to make sure.
|
||||||
|
*/
|
||||||
|
if (priv->switch_id == QCA8K_ID_QCA8327) {
|
||||||
|
+ data = of_device_get_match_data(priv->dev);
|
||||||
|
+
|
||||||
|
+ /* Set the correct package of 148 pin for QCA8327 */
|
||||||
|
+ if (data->reduced_package)
|
||||||
|
+ val |= QCA8327_PWS_PACKAGE148_EN;
|
||||||
|
+
|
||||||
|
ret = qca8k_rmw(priv, QCA8K_REG_PWS, QCA8327_PWS_PACKAGE148_EN,
|
||||||
|
- QCA8327_PWS_PACKAGE148_EN);
|
||||||
|
+ val);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
@@ -2098,7 +2105,12 @@ static int qca8k_resume(struct device *d
|
||||||
|
static SIMPLE_DEV_PM_OPS(qca8k_pm_ops,
|
||||||
|
qca8k_suspend, qca8k_resume);
|
||||||
|
|
||||||
|
-static const struct qca8k_match_data qca832x = {
|
||||||
|
+static const struct qca8k_match_data qca8327 = {
|
||||||
|
+ .id = QCA8K_ID_QCA8327,
|
||||||
|
+ .reduced_package = true,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static const struct qca8k_match_data qca8328 = {
|
||||||
|
.id = QCA8K_ID_QCA8327,
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -2107,7 +2119,8 @@ static const struct qca8k_match_data qca
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct of_device_id qca8k_of_match[] = {
|
||||||
|
- { .compatible = "qca,qca8327", .data = &qca832x },
|
||||||
|
+ { .compatible = "qca,qca8327", .data = &qca8327 },
|
||||||
|
+ { .compatible = "qca,qca8328", .data = &qca8328 },
|
||||||
|
{ .compatible = "qca,qca8334", .data = &qca833x },
|
||||||
|
{ .compatible = "qca,qca8337", .data = &qca833x },
|
||||||
|
{ /* sentinel */ },
|
||||||
|
--- a/drivers/net/dsa/qca8k.h
|
||||||
|
+++ b/drivers/net/dsa/qca8k.h
|
||||||
|
@@ -260,6 +260,7 @@ struct ar8xxx_port_status {
|
||||||
|
|
||||||
|
struct qca8k_match_data {
|
||||||
|
u8 id;
|
||||||
|
+ bool reduced_package;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
|
@ -0,0 +1,159 @@
|
||||||
|
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)
|
|
@ -0,0 +1,124 @@
|
||||||
|
From fd0bb28c547f7c8affb1691128cece38f5b626a1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
Date: Thu, 14 Oct 2021 00:39:19 +0200
|
||||||
|
Subject: net: dsa: qca8k: move port config to dedicated struct
|
||||||
|
|
||||||
|
Move ports related config to dedicated struct to keep things organized.
|
||||||
|
|
||||||
|
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
|
||||||
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||||
|
---
|
||||||
|
drivers/net/dsa/qca8k.c | 26 +++++++++++++-------------
|
||||||
|
drivers/net/dsa/qca8k.h | 10 +++++++---
|
||||||
|
2 files changed, 20 insertions(+), 16 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/dsa/qca8k.c
|
||||||
|
+++ b/drivers/net/dsa/qca8k.c
|
||||||
|
@@ -1019,7 +1019,7 @@ qca8k_parse_port_config(struct qca8k_pri
|
||||||
|
delay = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
- priv->rgmii_tx_delay[cpu_port_index] = delay;
|
||||||
|
+ priv->ports_config.rgmii_tx_delay[cpu_port_index] = delay;
|
||||||
|
|
||||||
|
delay = 0;
|
||||||
|
|
||||||
|
@@ -1035,7 +1035,7 @@ qca8k_parse_port_config(struct qca8k_pri
|
||||||
|
delay = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
- priv->rgmii_rx_delay[cpu_port_index] = delay;
|
||||||
|
+ priv->ports_config.rgmii_rx_delay[cpu_port_index] = delay;
|
||||||
|
|
||||||
|
/* Skip sgmii parsing for rgmii* mode */
|
||||||
|
if (mode == PHY_INTERFACE_MODE_RGMII ||
|
||||||
|
@@ -1045,17 +1045,17 @@ qca8k_parse_port_config(struct qca8k_pri
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge"))
|
||||||
|
- priv->sgmii_tx_clk_falling_edge = true;
|
||||||
|
+ priv->ports_config.sgmii_tx_clk_falling_edge = true;
|
||||||
|
|
||||||
|
if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge"))
|
||||||
|
- priv->sgmii_rx_clk_falling_edge = true;
|
||||||
|
+ priv->ports_config.sgmii_rx_clk_falling_edge = true;
|
||||||
|
|
||||||
|
if (of_property_read_bool(port_dn, "qca,sgmii-enable-pll")) {
|
||||||
|
- priv->sgmii_enable_pll = true;
|
||||||
|
+ priv->ports_config.sgmii_enable_pll = true;
|
||||||
|
|
||||||
|
if (priv->switch_id == QCA8K_ID_QCA8327) {
|
||||||
|
dev_err(priv->dev, "SGMII PLL should NOT be enabled for qca8327. Aborting enabling");
|
||||||
|
- priv->sgmii_enable_pll = false;
|
||||||
|
+ priv->ports_config.sgmii_enable_pll = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->switch_revision < 2)
|
||||||
|
@@ -1281,15 +1281,15 @@ qca8k_mac_config_setup_internal_delay(st
|
||||||
|
* 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];
|
||||||
|
+ if (priv->ports_config.rgmii_tx_delay[cpu_port_index]) {
|
||||||
|
+ delay = priv->ports_config.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];
|
||||||
|
+ if (priv->ports_config.rgmii_rx_delay[cpu_port_index]) {
|
||||||
|
+ delay = priv->ports_config.rgmii_rx_delay[cpu_port_index];
|
||||||
|
|
||||||
|
val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) |
|
||||||
|
QCA8K_PORT_PAD_RGMII_RX_DELAY_EN;
|
||||||
|
@@ -1397,7 +1397,7 @@ qca8k_phylink_mac_config(struct dsa_swit
|
||||||
|
|
||||||
|
val |= QCA8K_SGMII_EN_SD;
|
||||||
|
|
||||||
|
- if (priv->sgmii_enable_pll)
|
||||||
|
+ if (priv->ports_config.sgmii_enable_pll)
|
||||||
|
val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX |
|
||||||
|
QCA8K_SGMII_EN_TX;
|
||||||
|
|
||||||
|
@@ -1425,10 +1425,10 @@ qca8k_phylink_mac_config(struct dsa_swit
|
||||||
|
val = 0;
|
||||||
|
|
||||||
|
/* SGMII Clock phase configuration */
|
||||||
|
- if (priv->sgmii_rx_clk_falling_edge)
|
||||||
|
+ if (priv->ports_config.sgmii_rx_clk_falling_edge)
|
||||||
|
val |= QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE;
|
||||||
|
|
||||||
|
- if (priv->sgmii_tx_clk_falling_edge)
|
||||||
|
+ if (priv->ports_config.sgmii_tx_clk_falling_edge)
|
||||||
|
val |= QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE;
|
||||||
|
|
||||||
|
if (val)
|
||||||
|
--- a/drivers/net/dsa/qca8k.h
|
||||||
|
+++ b/drivers/net/dsa/qca8k.h
|
||||||
|
@@ -270,15 +270,19 @@ enum {
|
||||||
|
QCA8K_CPU_PORT6,
|
||||||
|
};
|
||||||
|
|
||||||
|
-struct qca8k_priv {
|
||||||
|
- u8 switch_id;
|
||||||
|
- u8 switch_revision;
|
||||||
|
+struct qca8k_ports_config {
|
||||||
|
bool sgmii_rx_clk_falling_edge;
|
||||||
|
bool sgmii_tx_clk_falling_edge;
|
||||||
|
bool sgmii_enable_pll;
|
||||||
|
u8 rgmii_rx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
|
||||||
|
u8 rgmii_tx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct qca8k_priv {
|
||||||
|
+ u8 switch_id;
|
||||||
|
+ u8 switch_revision;
|
||||||
|
bool legacy_phy_port_mapping;
|
||||||
|
+ struct qca8k_ports_config ports_config;
|
||||||
|
struct regmap *regmap;
|
||||||
|
struct mii_bus *bus;
|
||||||
|
struct ar8xxx_port_status port_sts[QCA8K_NUM_PORTS];
|
|
@ -0,0 +1,26 @@
|
||||||
|
From e52073a8e3086046a098b8a7cbeb282ff0cdb424 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
Date: Thu, 14 Oct 2021 00:39:20 +0200
|
||||||
|
Subject: dt-bindings: net: ipq8064-mdio: fix warning with new qca8k switch
|
||||||
|
|
||||||
|
Fix warning now that we have qca8k switch Documentation using yaml.
|
||||||
|
|
||||||
|
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||||
|
---
|
||||||
|
Documentation/devicetree/bindings/net/qcom,ipq8064-mdio.yaml | 5 ++++-
|
||||||
|
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/Documentation/devicetree/bindings/net/qcom,ipq8064-mdio.yaml
|
||||||
|
+++ b/Documentation/devicetree/bindings/net/qcom,ipq8064-mdio.yaml
|
||||||
|
@@ -51,6 +51,9 @@ examples:
|
||||||
|
switch@10 {
|
||||||
|
compatible = "qca,qca8337";
|
||||||
|
reg = <0x10>;
|
||||||
|
- /* ... */
|
||||||
|
+
|
||||||
|
+ ports {
|
||||||
|
+ /* ... */
|
||||||
|
+ };
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,631 @@
|
||||||
|
From d291fbb8245d5ba04979fed85575860a5cea7196 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Matthew Hagan <mnhagan88@gmail.com>
|
||||||
|
Date: Thu, 14 Oct 2021 00:39:21 +0200
|
||||||
|
Subject: dt-bindings: net: dsa: qca8k: convert to YAML schema
|
||||||
|
|
||||||
|
Convert the qca8k bindings to YAML format.
|
||||||
|
|
||||||
|
Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
|
||||||
|
Co-developed-by: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||||
|
---
|
||||||
|
.../devicetree/bindings/net/dsa/qca8k.txt | 245 --------------
|
||||||
|
.../devicetree/bindings/net/dsa/qca8k.yaml | 362 +++++++++++++++++++++
|
||||||
|
2 files changed, 362 insertions(+), 245 deletions(-)
|
||||||
|
delete mode 100644 Documentation/devicetree/bindings/net/dsa/qca8k.txt
|
||||||
|
create mode 100644 Documentation/devicetree/bindings/net/dsa/qca8k.yaml
|
||||||
|
|
||||||
|
--- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,245 +0,0 @@
|
||||||
|
-* Qualcomm Atheros QCA8xxx switch family
|
||||||
|
-
|
||||||
|
-Required properties:
|
||||||
|
-
|
||||||
|
-- compatible: should be one of:
|
||||||
|
- "qca,qca8328": referenced as AR8328(N)-AK1(A/B) QFN 176 pin package
|
||||||
|
- "qca,qca8327": referenced as AR8327(N)-AL1A DR-QFN 148 pin package
|
||||||
|
- "qca,qca8334": referenced as QCA8334-AL3C QFN 88 pin package
|
||||||
|
- "qca,qca8337": referenced as QCA8337N-AL3(B/C) DR-QFN 148 pin package
|
||||||
|
-
|
||||||
|
-- #size-cells: must be 0
|
||||||
|
-- #address-cells: must be 1
|
||||||
|
-
|
||||||
|
-Optional properties:
|
||||||
|
-
|
||||||
|
-- reset-gpios: GPIO to be used to reset the whole device
|
||||||
|
-- qca,ignore-power-on-sel: Ignore power on pin strapping to configure led open
|
||||||
|
- drain or eeprom presence. This is needed for broken
|
||||||
|
- devices that have wrong configuration or when the oem
|
||||||
|
- decided to not use pin strapping and fallback to sw
|
||||||
|
- regs.
|
||||||
|
-- qca,led-open-drain: Set leds to open-drain mode. This requires the
|
||||||
|
- qca,ignore-power-on-sel to be set or the driver will fail
|
||||||
|
- to probe. This is needed if the oem doesn't use pin
|
||||||
|
- strapping to set this mode and prefers to set it using sw
|
||||||
|
- regs. The pin strapping related to led open drain mode is
|
||||||
|
- the pin B68 for QCA832x and B49 for QCA833x
|
||||||
|
-
|
||||||
|
-Subnodes:
|
||||||
|
-
|
||||||
|
-The integrated switch subnode should be specified according to the binding
|
||||||
|
-described in dsa/dsa.txt. If the QCA8K switch is connect to a SoC's external
|
||||||
|
-mdio-bus each subnode describing a port needs to have a valid phandle
|
||||||
|
-referencing the internal PHY it is connected to. This is because there's no
|
||||||
|
-N:N mapping of port and PHY id.
|
||||||
|
-To declare the internal mdio-bus configuration, declare a mdio node in the
|
||||||
|
-switch node and declare the phandle for the port referencing the internal
|
||||||
|
-PHY is connected to. In this config a internal mdio-bus is registered and
|
||||||
|
-the mdio MASTER is used as communication.
|
||||||
|
-
|
||||||
|
-Don't use mixed external and internal mdio-bus configurations, as this is
|
||||||
|
-not supported by the hardware.
|
||||||
|
-
|
||||||
|
-This switch support 2 CPU port. Normally and advised configuration is with
|
||||||
|
-CPU port set to port 0. It is also possible to set the CPU port to port 6
|
||||||
|
-if the device requires it. The driver will configure the switch to the defined
|
||||||
|
-port. With both CPU port declared the first CPU port is selected as primary
|
||||||
|
-and the secondary CPU ignored.
|
||||||
|
-
|
||||||
|
-A CPU port node has the following optional node:
|
||||||
|
-
|
||||||
|
-- fixed-link : Fixed-link subnode describing a link to a non-MDIO
|
||||||
|
- managed entity. See
|
||||||
|
- Documentation/devicetree/bindings/net/fixed-link.txt
|
||||||
|
- for details.
|
||||||
|
-- qca,sgmii-rxclk-falling-edge: Set the receive clock phase to falling edge.
|
||||||
|
- Mostly used in qca8327 with CPU port 0 set to
|
||||||
|
- sgmii.
|
||||||
|
-- qca,sgmii-txclk-falling-edge: Set the transmit clock phase to falling edge.
|
||||||
|
-- qca,sgmii-enable-pll : For SGMII CPU port, explicitly enable PLL, TX and RX
|
||||||
|
- chain along with Signal Detection.
|
||||||
|
- This should NOT be enabled for qca8327. If enabled with
|
||||||
|
- qca8327 the sgmii port won't correctly init and an err
|
||||||
|
- is printed.
|
||||||
|
- This can be required for qca8337 switch with revision 2.
|
||||||
|
- A warning is displayed when used with revision greater
|
||||||
|
- 2.
|
||||||
|
- With CPU port set to sgmii and qca8337 it is advised
|
||||||
|
- to set this unless a communication problem is observed.
|
||||||
|
-
|
||||||
|
-For QCA8K the 'fixed-link' sub-node supports only the following properties:
|
||||||
|
-
|
||||||
|
-- 'speed' (integer, mandatory), to indicate the link speed. Accepted
|
||||||
|
- values are 10, 100 and 1000
|
||||||
|
-- 'full-duplex' (boolean, optional), to indicate that full duplex is
|
||||||
|
- used. When absent, half duplex is assumed.
|
||||||
|
-
|
||||||
|
-Examples:
|
||||||
|
-
|
||||||
|
-for the external mdio-bus configuration:
|
||||||
|
-
|
||||||
|
- &mdio0 {
|
||||||
|
- phy_port1: phy@0 {
|
||||||
|
- reg = <0>;
|
||||||
|
- };
|
||||||
|
-
|
||||||
|
- phy_port2: phy@1 {
|
||||||
|
- reg = <1>;
|
||||||
|
- };
|
||||||
|
-
|
||||||
|
- phy_port3: phy@2 {
|
||||||
|
- reg = <2>;
|
||||||
|
- };
|
||||||
|
-
|
||||||
|
- phy_port4: phy@3 {
|
||||||
|
- reg = <3>;
|
||||||
|
- };
|
||||||
|
-
|
||||||
|
- phy_port5: phy@4 {
|
||||||
|
- reg = <4>;
|
||||||
|
- };
|
||||||
|
-
|
||||||
|
- switch@10 {
|
||||||
|
- compatible = "qca,qca8337";
|
||||||
|
- #address-cells = <1>;
|
||||||
|
- #size-cells = <0>;
|
||||||
|
-
|
||||||
|
- reset-gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
|
||||||
|
- reg = <0x10>;
|
||||||
|
-
|
||||||
|
- ports {
|
||||||
|
- #address-cells = <1>;
|
||||||
|
- #size-cells = <0>;
|
||||||
|
- port@0 {
|
||||||
|
- reg = <0>;
|
||||||
|
- label = "cpu";
|
||||||
|
- ethernet = <&gmac1>;
|
||||||
|
- phy-mode = "rgmii";
|
||||||
|
- fixed-link {
|
||||||
|
- speed = 1000;
|
||||||
|
- full-duplex;
|
||||||
|
- };
|
||||||
|
- };
|
||||||
|
-
|
||||||
|
- port@1 {
|
||||||
|
- reg = <1>;
|
||||||
|
- label = "lan1";
|
||||||
|
- phy-handle = <&phy_port1>;
|
||||||
|
- };
|
||||||
|
-
|
||||||
|
- port@2 {
|
||||||
|
- reg = <2>;
|
||||||
|
- label = "lan2";
|
||||||
|
- phy-handle = <&phy_port2>;
|
||||||
|
- };
|
||||||
|
-
|
||||||
|
- port@3 {
|
||||||
|
- reg = <3>;
|
||||||
|
- label = "lan3";
|
||||||
|
- phy-handle = <&phy_port3>;
|
||||||
|
- };
|
||||||
|
-
|
||||||
|
- port@4 {
|
||||||
|
- reg = <4>;
|
||||||
|
- label = "lan4";
|
||||||
|
- phy-handle = <&phy_port4>;
|
||||||
|
- };
|
||||||
|
-
|
||||||
|
- port@5 {
|
||||||
|
- reg = <5>;
|
||||||
|
- label = "wan";
|
||||||
|
- phy-handle = <&phy_port5>;
|
||||||
|
- };
|
||||||
|
- };
|
||||||
|
- };
|
||||||
|
- };
|
||||||
|
-
|
||||||
|
-for the internal master mdio-bus configuration:
|
||||||
|
-
|
||||||
|
- &mdio0 {
|
||||||
|
- switch@10 {
|
||||||
|
- compatible = "qca,qca8337";
|
||||||
|
- #address-cells = <1>;
|
||||||
|
- #size-cells = <0>;
|
||||||
|
-
|
||||||
|
- reset-gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
|
||||||
|
- reg = <0x10>;
|
||||||
|
-
|
||||||
|
- ports {
|
||||||
|
- #address-cells = <1>;
|
||||||
|
- #size-cells = <0>;
|
||||||
|
-
|
||||||
|
- port@0 {
|
||||||
|
- reg = <0>;
|
||||||
|
- label = "cpu";
|
||||||
|
- ethernet = <&gmac1>;
|
||||||
|
- phy-mode = "rgmii";
|
||||||
|
- fixed-link {
|
||||||
|
- speed = 1000;
|
||||||
|
- full-duplex;
|
||||||
|
- };
|
||||||
|
- };
|
||||||
|
-
|
||||||
|
- port@1 {
|
||||||
|
- reg = <1>;
|
||||||
|
- label = "lan1";
|
||||||
|
- phy-mode = "internal";
|
||||||
|
- phy-handle = <&phy_port1>;
|
||||||
|
- };
|
||||||
|
-
|
||||||
|
- port@2 {
|
||||||
|
- reg = <2>;
|
||||||
|
- label = "lan2";
|
||||||
|
- phy-mode = "internal";
|
||||||
|
- phy-handle = <&phy_port2>;
|
||||||
|
- };
|
||||||
|
-
|
||||||
|
- port@3 {
|
||||||
|
- reg = <3>;
|
||||||
|
- label = "lan3";
|
||||||
|
- phy-mode = "internal";
|
||||||
|
- phy-handle = <&phy_port3>;
|
||||||
|
- };
|
||||||
|
-
|
||||||
|
- port@4 {
|
||||||
|
- reg = <4>;
|
||||||
|
- label = "lan4";
|
||||||
|
- phy-mode = "internal";
|
||||||
|
- phy-handle = <&phy_port4>;
|
||||||
|
- };
|
||||||
|
-
|
||||||
|
- port@5 {
|
||||||
|
- reg = <5>;
|
||||||
|
- label = "wan";
|
||||||
|
- phy-mode = "internal";
|
||||||
|
- phy-handle = <&phy_port5>;
|
||||||
|
- };
|
||||||
|
- };
|
||||||
|
-
|
||||||
|
- mdio {
|
||||||
|
- #address-cells = <1>;
|
||||||
|
- #size-cells = <0>;
|
||||||
|
-
|
||||||
|
- phy_port1: phy@0 {
|
||||||
|
- reg = <0>;
|
||||||
|
- };
|
||||||
|
-
|
||||||
|
- phy_port2: phy@1 {
|
||||||
|
- reg = <1>;
|
||||||
|
- };
|
||||||
|
-
|
||||||
|
- phy_port3: phy@2 {
|
||||||
|
- reg = <2>;
|
||||||
|
- };
|
||||||
|
-
|
||||||
|
- phy_port4: phy@3 {
|
||||||
|
- reg = <3>;
|
||||||
|
- };
|
||||||
|
-
|
||||||
|
- phy_port5: phy@4 {
|
||||||
|
- reg = <4>;
|
||||||
|
- };
|
||||||
|
- };
|
||||||
|
- };
|
||||||
|
- };
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/Documentation/devicetree/bindings/net/dsa/qca8k.yaml
|
||||||
|
@@ -0,0 +1,362 @@
|
||||||
|
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||||
|
+%YAML 1.2
|
||||||
|
+---
|
||||||
|
+$id: http://devicetree.org/schemas/net/dsa/qca8k.yaml#
|
||||||
|
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
+
|
||||||
|
+title: Qualcomm Atheros QCA83xx switch family
|
||||||
|
+
|
||||||
|
+maintainers:
|
||||||
|
+ - John Crispin <john@phrozen.org>
|
||||||
|
+
|
||||||
|
+description:
|
||||||
|
+ If the QCA8K switch is connect to an SoC's external mdio-bus, each subnode
|
||||||
|
+ describing a port needs to have a valid phandle referencing the internal PHY
|
||||||
|
+ it is connected to. This is because there is no N:N mapping of port and PHY
|
||||||
|
+ ID. To declare the internal mdio-bus configuration, declare an MDIO node in
|
||||||
|
+ the switch node and declare the phandle for the port, referencing the internal
|
||||||
|
+ PHY it is connected to. In this config, an internal mdio-bus is registered and
|
||||||
|
+ the MDIO master is used for communication. Mixed external and internal
|
||||||
|
+ mdio-bus configurations are not supported by the hardware.
|
||||||
|
+
|
||||||
|
+properties:
|
||||||
|
+ compatible:
|
||||||
|
+ oneOf:
|
||||||
|
+ - enum:
|
||||||
|
+ - qca,qca8327
|
||||||
|
+ - qca,qca8328
|
||||||
|
+ - qca,qca8334
|
||||||
|
+ - qca,qca8337
|
||||||
|
+ description: |
|
||||||
|
+ qca,qca8328: referenced as AR8328(N)-AK1(A/B) QFN 176 pin package
|
||||||
|
+ qca,qca8327: referenced as AR8327(N)-AL1A DR-QFN 148 pin package
|
||||||
|
+ qca,qca8334: referenced as QCA8334-AL3C QFN 88 pin package
|
||||||
|
+ qca,qca8337: referenced as QCA8337N-AL3(B/C) DR-QFN 148 pin package
|
||||||
|
+
|
||||||
|
+ reg:
|
||||||
|
+ maxItems: 1
|
||||||
|
+
|
||||||
|
+ reset-gpios:
|
||||||
|
+ description:
|
||||||
|
+ GPIO to be used to reset the whole device
|
||||||
|
+ maxItems: 1
|
||||||
|
+
|
||||||
|
+ qca,ignore-power-on-sel:
|
||||||
|
+ $ref: /schemas/types.yaml#/definitions/flag
|
||||||
|
+ description:
|
||||||
|
+ Ignore power-on pin strapping to configure LED open-drain or EEPROM
|
||||||
|
+ presence. This is needed for devices with incorrect configuration or when
|
||||||
|
+ the OEM has decided not to use pin strapping and falls back to SW regs.
|
||||||
|
+
|
||||||
|
+ qca,led-open-drain:
|
||||||
|
+ $ref: /schemas/types.yaml#/definitions/flag
|
||||||
|
+ description:
|
||||||
|
+ Set LEDs to open-drain mode. This requires the qca,ignore-power-on-sel to
|
||||||
|
+ be set, otherwise the driver will fail at probe. This is required if the
|
||||||
|
+ OEM does not use pin strapping to set this mode and prefers to set it
|
||||||
|
+ using SW regs. The pin strappings related to LED open-drain mode are
|
||||||
|
+ B68 on the QCA832x and B49 on the QCA833x.
|
||||||
|
+
|
||||||
|
+ mdio:
|
||||||
|
+ type: object
|
||||||
|
+ description: Qca8k switch have an internal mdio to access switch port.
|
||||||
|
+ If this is not present, the legacy mapping is used and the
|
||||||
|
+ internal mdio access is used.
|
||||||
|
+ With the legacy mapping the reg corresponding to the internal
|
||||||
|
+ mdio is the switch reg with an offset of -1.
|
||||||
|
+
|
||||||
|
+ properties:
|
||||||
|
+ '#address-cells':
|
||||||
|
+ const: 1
|
||||||
|
+ '#size-cells':
|
||||||
|
+ const: 0
|
||||||
|
+
|
||||||
|
+ patternProperties:
|
||||||
|
+ "^(ethernet-)?phy@[0-4]$":
|
||||||
|
+ type: object
|
||||||
|
+
|
||||||
|
+ allOf:
|
||||||
|
+ - $ref: "http://devicetree.org/schemas/net/mdio.yaml#"
|
||||||
|
+
|
||||||
|
+ properties:
|
||||||
|
+ reg:
|
||||||
|
+ maxItems: 1
|
||||||
|
+
|
||||||
|
+ required:
|
||||||
|
+ - reg
|
||||||
|
+
|
||||||
|
+patternProperties:
|
||||||
|
+ "^(ethernet-)?ports$":
|
||||||
|
+ type: object
|
||||||
|
+ properties:
|
||||||
|
+ '#address-cells':
|
||||||
|
+ const: 1
|
||||||
|
+ '#size-cells':
|
||||||
|
+ const: 0
|
||||||
|
+
|
||||||
|
+ patternProperties:
|
||||||
|
+ "^(ethernet-)?port@[0-6]$":
|
||||||
|
+ type: object
|
||||||
|
+ description: Ethernet switch ports
|
||||||
|
+
|
||||||
|
+ properties:
|
||||||
|
+ reg:
|
||||||
|
+ description: Port number
|
||||||
|
+
|
||||||
|
+ label:
|
||||||
|
+ description:
|
||||||
|
+ Describes the label associated with this port, which will become
|
||||||
|
+ the netdev name
|
||||||
|
+ $ref: /schemas/types.yaml#/definitions/string
|
||||||
|
+
|
||||||
|
+ link:
|
||||||
|
+ description:
|
||||||
|
+ Should be a list of phandles to other switch's DSA port. This
|
||||||
|
+ port is used as the outgoing port towards the phandle ports. The
|
||||||
|
+ full routing information must be given, not just the one hop
|
||||||
|
+ routes to neighbouring switches
|
||||||
|
+ $ref: /schemas/types.yaml#/definitions/phandle-array
|
||||||
|
+
|
||||||
|
+ ethernet:
|
||||||
|
+ description:
|
||||||
|
+ Should be a phandle to a valid Ethernet device node. This host
|
||||||
|
+ device is what the switch port is connected to
|
||||||
|
+ $ref: /schemas/types.yaml#/definitions/phandle
|
||||||
|
+
|
||||||
|
+ phy-handle: true
|
||||||
|
+
|
||||||
|
+ phy-mode: true
|
||||||
|
+
|
||||||
|
+ fixed-link: true
|
||||||
|
+
|
||||||
|
+ mac-address: true
|
||||||
|
+
|
||||||
|
+ sfp: true
|
||||||
|
+
|
||||||
|
+ qca,sgmii-rxclk-falling-edge:
|
||||||
|
+ $ref: /schemas/types.yaml#/definitions/flag
|
||||||
|
+ description:
|
||||||
|
+ Set the receive clock phase to falling edge. Mostly commonly used on
|
||||||
|
+ the QCA8327 with CPU port 0 set to SGMII.
|
||||||
|
+
|
||||||
|
+ qca,sgmii-txclk-falling-edge:
|
||||||
|
+ $ref: /schemas/types.yaml#/definitions/flag
|
||||||
|
+ description:
|
||||||
|
+ Set the transmit clock phase to falling edge.
|
||||||
|
+
|
||||||
|
+ qca,sgmii-enable-pll:
|
||||||
|
+ $ref: /schemas/types.yaml#/definitions/flag
|
||||||
|
+ description:
|
||||||
|
+ For SGMII CPU port, explicitly enable PLL, TX and RX chain along with
|
||||||
|
+ Signal Detection. On the QCA8327 this should not be enabled, otherwise
|
||||||
|
+ the SGMII port will not initialize. When used on the QCA8337, revision 3
|
||||||
|
+ or greater, a warning will be displayed. When the CPU port is set to
|
||||||
|
+ SGMII on the QCA8337, it is advised to set this unless a communication
|
||||||
|
+ issue is observed.
|
||||||
|
+
|
||||||
|
+ required:
|
||||||
|
+ - reg
|
||||||
|
+
|
||||||
|
+ additionalProperties: false
|
||||||
|
+
|
||||||
|
+oneOf:
|
||||||
|
+ - required:
|
||||||
|
+ - ports
|
||||||
|
+ - required:
|
||||||
|
+ - ethernet-ports
|
||||||
|
+
|
||||||
|
+required:
|
||||||
|
+ - compatible
|
||||||
|
+ - reg
|
||||||
|
+
|
||||||
|
+additionalProperties: true
|
||||||
|
+
|
||||||
|
+examples:
|
||||||
|
+ - |
|
||||||
|
+ #include <dt-bindings/gpio/gpio.h>
|
||||||
|
+
|
||||||
|
+ mdio {
|
||||||
|
+ #address-cells = <1>;
|
||||||
|
+ #size-cells = <0>;
|
||||||
|
+
|
||||||
|
+ external_phy_port1: ethernet-phy@0 {
|
||||||
|
+ reg = <0>;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ external_phy_port2: ethernet-phy@1 {
|
||||||
|
+ reg = <1>;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ external_phy_port3: ethernet-phy@2 {
|
||||||
|
+ reg = <2>;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ external_phy_port4: ethernet-phy@3 {
|
||||||
|
+ reg = <3>;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ external_phy_port5: ethernet-phy@4 {
|
||||||
|
+ reg = <4>;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ switch@10 {
|
||||||
|
+ compatible = "qca,qca8337";
|
||||||
|
+ #address-cells = <1>;
|
||||||
|
+ #size-cells = <0>;
|
||||||
|
+ reset-gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
|
||||||
|
+ reg = <0x10>;
|
||||||
|
+
|
||||||
|
+ ports {
|
||||||
|
+ #address-cells = <1>;
|
||||||
|
+ #size-cells = <0>;
|
||||||
|
+
|
||||||
|
+ port@0 {
|
||||||
|
+ reg = <0>;
|
||||||
|
+ label = "cpu";
|
||||||
|
+ ethernet = <&gmac1>;
|
||||||
|
+ phy-mode = "rgmii";
|
||||||
|
+
|
||||||
|
+ fixed-link {
|
||||||
|
+ speed = <1000>;
|
||||||
|
+ full-duplex;
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ port@1 {
|
||||||
|
+ reg = <1>;
|
||||||
|
+ label = "lan1";
|
||||||
|
+ phy-handle = <&external_phy_port1>;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ port@2 {
|
||||||
|
+ reg = <2>;
|
||||||
|
+ label = "lan2";
|
||||||
|
+ phy-handle = <&external_phy_port2>;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ port@3 {
|
||||||
|
+ reg = <3>;
|
||||||
|
+ label = "lan3";
|
||||||
|
+ phy-handle = <&external_phy_port3>;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ port@4 {
|
||||||
|
+ reg = <4>;
|
||||||
|
+ label = "lan4";
|
||||||
|
+ phy-handle = <&external_phy_port4>;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ port@5 {
|
||||||
|
+ reg = <5>;
|
||||||
|
+ label = "wan";
|
||||||
|
+ phy-handle = <&external_phy_port5>;
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
+ - |
|
||||||
|
+ #include <dt-bindings/gpio/gpio.h>
|
||||||
|
+
|
||||||
|
+ mdio {
|
||||||
|
+ #address-cells = <1>;
|
||||||
|
+ #size-cells = <0>;
|
||||||
|
+
|
||||||
|
+ switch@10 {
|
||||||
|
+ compatible = "qca,qca8337";
|
||||||
|
+ #address-cells = <1>;
|
||||||
|
+ #size-cells = <0>;
|
||||||
|
+ reset-gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
|
||||||
|
+ reg = <0x10>;
|
||||||
|
+
|
||||||
|
+ ports {
|
||||||
|
+ #address-cells = <1>;
|
||||||
|
+ #size-cells = <0>;
|
||||||
|
+
|
||||||
|
+ port@0 {
|
||||||
|
+ reg = <0>;
|
||||||
|
+ label = "cpu";
|
||||||
|
+ ethernet = <&gmac1>;
|
||||||
|
+ phy-mode = "rgmii";
|
||||||
|
+
|
||||||
|
+ fixed-link {
|
||||||
|
+ speed = <1000>;
|
||||||
|
+ full-duplex;
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ port@1 {
|
||||||
|
+ reg = <1>;
|
||||||
|
+ label = "lan1";
|
||||||
|
+ phy-mode = "internal";
|
||||||
|
+ phy-handle = <&internal_phy_port1>;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ port@2 {
|
||||||
|
+ reg = <2>;
|
||||||
|
+ label = "lan2";
|
||||||
|
+ phy-mode = "internal";
|
||||||
|
+ phy-handle = <&internal_phy_port2>;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ port@3 {
|
||||||
|
+ reg = <3>;
|
||||||
|
+ label = "lan3";
|
||||||
|
+ phy-mode = "internal";
|
||||||
|
+ phy-handle = <&internal_phy_port3>;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ port@4 {
|
||||||
|
+ reg = <4>;
|
||||||
|
+ label = "lan4";
|
||||||
|
+ phy-mode = "internal";
|
||||||
|
+ phy-handle = <&internal_phy_port4>;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ port@5 {
|
||||||
|
+ reg = <5>;
|
||||||
|
+ label = "wan";
|
||||||
|
+ phy-mode = "internal";
|
||||||
|
+ phy-handle = <&internal_phy_port5>;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ port@6 {
|
||||||
|
+ reg = <0>;
|
||||||
|
+ label = "cpu";
|
||||||
|
+ ethernet = <&gmac1>;
|
||||||
|
+ phy-mode = "sgmii";
|
||||||
|
+
|
||||||
|
+ qca,sgmii-rxclk-falling-edge;
|
||||||
|
+
|
||||||
|
+ fixed-link {
|
||||||
|
+ speed = <1000>;
|
||||||
|
+ full-duplex;
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ mdio {
|
||||||
|
+ #address-cells = <1>;
|
||||||
|
+ #size-cells = <0>;
|
||||||
|
+
|
||||||
|
+ internal_phy_port1: ethernet-phy@0 {
|
||||||
|
+ reg = <0>;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ internal_phy_port2: ethernet-phy@1 {
|
||||||
|
+ reg = <1>;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ internal_phy_port3: ethernet-phy@2 {
|
||||||
|
+ reg = <2>;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ internal_phy_port4: ethernet-phy@3 {
|
||||||
|
+ reg = <3>;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ internal_phy_port5: ethernet-phy@4 {
|
||||||
|
+ reg = <4>;
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
+ };
|
Loading…
Reference in a new issue