mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-30 10:39:04 +00:00
131 lines
4.8 KiB
Diff
131 lines
4.8 KiB
Diff
|
From 83a3ceb39b2495171aabe9446271b94c678354f3 Mon Sep 17 00:00:00 2001
|
||
|
From: Ansuel Smith <ansuelsmth@gmail.com>
|
||
|
Date: Fri, 14 May 2021 23:00:01 +0200
|
||
|
Subject: [PATCH] net: dsa: qca8k: add priority tweak to qca8337 switch
|
||
|
|
||
|
The port 5 of the qca8337 have some problem in flood condition. The
|
||
|
original legacy driver had some specific buffer and priority settings
|
||
|
for the different port suggested by the QCA switch team. Add this
|
||
|
missing settings to improve switch stability under load condition.
|
||
|
The packet priority tweak is only needed for the qca8337 switch and
|
||
|
other qca8k switch are not affected.
|
||
|
|
||
|
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
|
||
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||
|
---
|
||
|
drivers/net/dsa/qca8k.c | 47 +++++++++++++++++++++++++++++++++++++++++
|
||
|
drivers/net/dsa/qca8k.h | 25 ++++++++++++++++++++++
|
||
|
2 files changed, 72 insertions(+)
|
||
|
|
||
|
--- a/drivers/net/dsa/qca8k.c
|
||
|
+++ b/drivers/net/dsa/qca8k.c
|
||
|
@@ -779,6 +779,7 @@ qca8k_setup(struct dsa_switch *ds)
|
||
|
{
|
||
|
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
|
||
|
int ret, i;
|
||
|
+ u32 mask;
|
||
|
|
||
|
/* Make sure that port 0 is the cpu port */
|
||
|
if (!dsa_is_cpu_port(ds, 0)) {
|
||
|
@@ -884,6 +885,51 @@ qca8k_setup(struct dsa_switch *ds)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+ /* The port 5 of the qca8337 have some problem in flood condition. The
|
||
|
+ * original legacy driver had some specific buffer and priority settings
|
||
|
+ * for the different port suggested by the QCA switch team. Add this
|
||
|
+ * missing settings to improve switch stability under load condition.
|
||
|
+ * This problem is limited to qca8337 and other qca8k switch are not affected.
|
||
|
+ */
|
||
|
+ if (priv->switch_id == QCA8K_ID_QCA8337) {
|
||
|
+ for (i = 0; i < QCA8K_NUM_PORTS; i++) {
|
||
|
+ switch (i) {
|
||
|
+ /* The 2 CPU port and port 5 requires some different
|
||
|
+ * priority than any other ports.
|
||
|
+ */
|
||
|
+ case 0:
|
||
|
+ case 5:
|
||
|
+ case 6:
|
||
|
+ mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) |
|
||
|
+ QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) |
|
||
|
+ QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x4) |
|
||
|
+ QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x4) |
|
||
|
+ QCA8K_PORT_HOL_CTRL0_EG_PRI4(0x6) |
|
||
|
+ QCA8K_PORT_HOL_CTRL0_EG_PRI5(0x8) |
|
||
|
+ QCA8K_PORT_HOL_CTRL0_EG_PORT(0x1e);
|
||
|
+ break;
|
||
|
+ default:
|
||
|
+ mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) |
|
||
|
+ QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) |
|
||
|
+ QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x6) |
|
||
|
+ QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x8) |
|
||
|
+ QCA8K_PORT_HOL_CTRL0_EG_PORT(0x19);
|
||
|
+ }
|
||
|
+ qca8k_write(priv, QCA8K_REG_PORT_HOL_CTRL0(i), mask);
|
||
|
+
|
||
|
+ mask = QCA8K_PORT_HOL_CTRL1_ING(0x6) |
|
||
|
+ QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN |
|
||
|
+ QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN |
|
||
|
+ QCA8K_PORT_HOL_CTRL1_WRED_EN;
|
||
|
+ qca8k_rmw(priv, QCA8K_REG_PORT_HOL_CTRL1(i),
|
||
|
+ QCA8K_PORT_HOL_CTRL1_ING_BUF |
|
||
|
+ QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN |
|
||
|
+ QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN |
|
||
|
+ QCA8K_PORT_HOL_CTRL1_WRED_EN,
|
||
|
+ mask);
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
/* Setup our port MTUs to match power on defaults */
|
||
|
for (i = 0; i < QCA8K_NUM_PORTS; i++)
|
||
|
priv->port_mtu[i] = ETH_FRAME_LEN + ETH_FCS_LEN;
|
||
|
@@ -1578,6 +1624,7 @@ qca8k_sw_probe(struct mdio_device *mdiod
|
||
|
return -ENODEV;
|
||
|
}
|
||
|
|
||
|
+ priv->switch_id = id;
|
||
|
priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL);
|
||
|
if (!priv->ds)
|
||
|
return -ENOMEM;
|
||
|
--- a/drivers/net/dsa/qca8k.h
|
||
|
+++ b/drivers/net/dsa/qca8k.h
|
||
|
@@ -168,6 +168,30 @@
|
||
|
#define QCA8K_PORT_LOOKUP_STATE GENMASK(18, 16)
|
||
|
#define QCA8K_PORT_LOOKUP_LEARN BIT(20)
|
||
|
|
||
|
+#define QCA8K_REG_PORT_HOL_CTRL0(_i) (0x970 + (_i) * 0x8)
|
||
|
+#define QCA8K_PORT_HOL_CTRL0_EG_PRI0_BUF GENMASK(3, 0)
|
||
|
+#define QCA8K_PORT_HOL_CTRL0_EG_PRI0(x) ((x) << 0)
|
||
|
+#define QCA8K_PORT_HOL_CTRL0_EG_PRI1_BUF GENMASK(7, 4)
|
||
|
+#define QCA8K_PORT_HOL_CTRL0_EG_PRI1(x) ((x) << 4)
|
||
|
+#define QCA8K_PORT_HOL_CTRL0_EG_PRI2_BUF GENMASK(11, 8)
|
||
|
+#define QCA8K_PORT_HOL_CTRL0_EG_PRI2(x) ((x) << 8)
|
||
|
+#define QCA8K_PORT_HOL_CTRL0_EG_PRI3_BUF GENMASK(15, 12)
|
||
|
+#define QCA8K_PORT_HOL_CTRL0_EG_PRI3(x) ((x) << 12)
|
||
|
+#define QCA8K_PORT_HOL_CTRL0_EG_PRI4_BUF GENMASK(19, 16)
|
||
|
+#define QCA8K_PORT_HOL_CTRL0_EG_PRI4(x) ((x) << 16)
|
||
|
+#define QCA8K_PORT_HOL_CTRL0_EG_PRI5_BUF GENMASK(23, 20)
|
||
|
+#define QCA8K_PORT_HOL_CTRL0_EG_PRI5(x) ((x) << 20)
|
||
|
+#define QCA8K_PORT_HOL_CTRL0_EG_PORT_BUF GENMASK(29, 24)
|
||
|
+#define QCA8K_PORT_HOL_CTRL0_EG_PORT(x) ((x) << 24)
|
||
|
+
|
||
|
+#define QCA8K_REG_PORT_HOL_CTRL1(_i) (0x974 + (_i) * 0x8)
|
||
|
+#define QCA8K_PORT_HOL_CTRL1_ING_BUF GENMASK(3, 0)
|
||
|
+#define QCA8K_PORT_HOL_CTRL1_ING(x) ((x) << 0)
|
||
|
+#define QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN BIT(6)
|
||
|
+#define QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN BIT(7)
|
||
|
+#define QCA8K_PORT_HOL_CTRL1_WRED_EN BIT(8)
|
||
|
+#define QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN BIT(16)
|
||
|
+
|
||
|
/* Pkt edit registers */
|
||
|
#define QCA8K_EGRESS_VLAN(x) (0x0c70 + (4 * (x / 2)))
|
||
|
|
||
|
@@ -220,6 +244,7 @@ struct qca8k_match_data {
|
||
|
};
|
||
|
|
||
|
struct qca8k_priv {
|
||
|
+ u8 switch_id;
|
||
|
struct regmap *regmap;
|
||
|
struct mii_bus *bus;
|
||
|
struct ar8xxx_port_status port_sts[QCA8K_NUM_PORTS];
|