cd3050ef7196983143190b975bab30982a446f96
[openwrt/openwrt.git] /
1 From 83a3ceb39b2495171aabe9446271b94c678354f3 Mon Sep 17 00:00:00 2001
2 From: Ansuel Smith <ansuelsmth@gmail.com>
3 Date: Fri, 14 May 2021 23:00:01 +0200
4 Subject: [PATCH] net: dsa: qca8k: add priority tweak to qca8337 switch
5
6 The port 5 of the qca8337 have some problem in flood condition. The
7 original legacy driver had some specific buffer and priority settings
8 for the different port suggested by the QCA switch team. Add this
9 missing settings to improve switch stability under load condition.
10 The packet priority tweak is only needed for the qca8337 switch and
11 other qca8k switch are not affected.
12
13 Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
14 Signed-off-by: David S. Miller <davem@davemloft.net>
15 ---
16 drivers/net/dsa/qca8k.c | 47 +++++++++++++++++++++++++++++++++++++++++
17 drivers/net/dsa/qca8k.h | 25 ++++++++++++++++++++++
18 2 files changed, 72 insertions(+)
19
20 --- a/drivers/net/dsa/qca8k.c
21 +++ b/drivers/net/dsa/qca8k.c
22 @@ -779,6 +779,7 @@ qca8k_setup(struct dsa_switch *ds)
23 {
24 struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
25 int ret, i;
26 + u32 mask;
27
28 /* Make sure that port 0 is the cpu port */
29 if (!dsa_is_cpu_port(ds, 0)) {
30 @@ -884,6 +885,51 @@ qca8k_setup(struct dsa_switch *ds)
31 }
32 }
33
34 + /* The port 5 of the qca8337 have some problem in flood condition. The
35 + * original legacy driver had some specific buffer and priority settings
36 + * for the different port suggested by the QCA switch team. Add this
37 + * missing settings to improve switch stability under load condition.
38 + * This problem is limited to qca8337 and other qca8k switch are not affected.
39 + */
40 + if (priv->switch_id == QCA8K_ID_QCA8337) {
41 + for (i = 0; i < QCA8K_NUM_PORTS; i++) {
42 + switch (i) {
43 + /* The 2 CPU port and port 5 requires some different
44 + * priority than any other ports.
45 + */
46 + case 0:
47 + case 5:
48 + case 6:
49 + mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) |
50 + QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) |
51 + QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x4) |
52 + QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x4) |
53 + QCA8K_PORT_HOL_CTRL0_EG_PRI4(0x6) |
54 + QCA8K_PORT_HOL_CTRL0_EG_PRI5(0x8) |
55 + QCA8K_PORT_HOL_CTRL0_EG_PORT(0x1e);
56 + break;
57 + default:
58 + mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) |
59 + QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) |
60 + QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x6) |
61 + QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x8) |
62 + QCA8K_PORT_HOL_CTRL0_EG_PORT(0x19);
63 + }
64 + qca8k_write(priv, QCA8K_REG_PORT_HOL_CTRL0(i), mask);
65 +
66 + mask = QCA8K_PORT_HOL_CTRL1_ING(0x6) |
67 + QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN |
68 + QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN |
69 + QCA8K_PORT_HOL_CTRL1_WRED_EN;
70 + qca8k_rmw(priv, QCA8K_REG_PORT_HOL_CTRL1(i),
71 + QCA8K_PORT_HOL_CTRL1_ING_BUF |
72 + QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN |
73 + QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN |
74 + QCA8K_PORT_HOL_CTRL1_WRED_EN,
75 + mask);
76 + }
77 + }
78 +
79 /* Setup our port MTUs to match power on defaults */
80 for (i = 0; i < QCA8K_NUM_PORTS; i++)
81 priv->port_mtu[i] = ETH_FRAME_LEN + ETH_FCS_LEN;
82 @@ -1578,6 +1624,7 @@ qca8k_sw_probe(struct mdio_device *mdiod
83 return -ENODEV;
84 }
85
86 + priv->switch_id = id;
87 priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL);
88 if (!priv->ds)
89 return -ENOMEM;
90 --- a/drivers/net/dsa/qca8k.h
91 +++ b/drivers/net/dsa/qca8k.h
92 @@ -168,6 +168,30 @@
93 #define QCA8K_PORT_LOOKUP_STATE GENMASK(18, 16)
94 #define QCA8K_PORT_LOOKUP_LEARN BIT(20)
95
96 +#define QCA8K_REG_PORT_HOL_CTRL0(_i) (0x970 + (_i) * 0x8)
97 +#define QCA8K_PORT_HOL_CTRL0_EG_PRI0_BUF GENMASK(3, 0)
98 +#define QCA8K_PORT_HOL_CTRL0_EG_PRI0(x) ((x) << 0)
99 +#define QCA8K_PORT_HOL_CTRL0_EG_PRI1_BUF GENMASK(7, 4)
100 +#define QCA8K_PORT_HOL_CTRL0_EG_PRI1(x) ((x) << 4)
101 +#define QCA8K_PORT_HOL_CTRL0_EG_PRI2_BUF GENMASK(11, 8)
102 +#define QCA8K_PORT_HOL_CTRL0_EG_PRI2(x) ((x) << 8)
103 +#define QCA8K_PORT_HOL_CTRL0_EG_PRI3_BUF GENMASK(15, 12)
104 +#define QCA8K_PORT_HOL_CTRL0_EG_PRI3(x) ((x) << 12)
105 +#define QCA8K_PORT_HOL_CTRL0_EG_PRI4_BUF GENMASK(19, 16)
106 +#define QCA8K_PORT_HOL_CTRL0_EG_PRI4(x) ((x) << 16)
107 +#define QCA8K_PORT_HOL_CTRL0_EG_PRI5_BUF GENMASK(23, 20)
108 +#define QCA8K_PORT_HOL_CTRL0_EG_PRI5(x) ((x) << 20)
109 +#define QCA8K_PORT_HOL_CTRL0_EG_PORT_BUF GENMASK(29, 24)
110 +#define QCA8K_PORT_HOL_CTRL0_EG_PORT(x) ((x) << 24)
111 +
112 +#define QCA8K_REG_PORT_HOL_CTRL1(_i) (0x974 + (_i) * 0x8)
113 +#define QCA8K_PORT_HOL_CTRL1_ING_BUF GENMASK(3, 0)
114 +#define QCA8K_PORT_HOL_CTRL1_ING(x) ((x) << 0)
115 +#define QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN BIT(6)
116 +#define QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN BIT(7)
117 +#define QCA8K_PORT_HOL_CTRL1_WRED_EN BIT(8)
118 +#define QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN BIT(16)
119 +
120 /* Pkt edit registers */
121 #define QCA8K_EGRESS_VLAN(x) (0x0c70 + (4 * (x / 2)))
122
123 @@ -220,6 +244,7 @@ struct qca8k_match_data {
124 };
125
126 struct qca8k_priv {
127 + u8 switch_id;
128 struct regmap *regmap;
129 struct mii_bus *bus;
130 struct ar8xxx_port_status port_sts[QCA8K_NUM_PORTS];