kernel: fix mtk_eth_soc throughput regressions on gigabit PHY ports
[openwrt/openwrt.git] / target / linux / generic / backport-5.15 / 771-v6.0-09-net-dsa-qca8k-move-set-age-MTU-port-enable-disable-f.patch
1 From b3a302b171f73425b41de8d3357fae3fa7057322 Mon Sep 17 00:00:00 2001
2 From: Christian Marangi <ansuelsmth@gmail.com>
3 Date: Wed, 27 Jul 2022 13:35:18 +0200
4 Subject: [PATCH 09/14] net: dsa: qca8k: move set age/MTU/port enable/disable
5 functions to common code
6
7 The same set age, MTU and port enable/disable function are used by
8 driver based on qca8k family switch.
9 Move them to common code to make them accessible also by other drivers.
10 While at it also drop unnecessary qca8k_priv cast for void pointers.
11
12 Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
13 Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
14 Signed-off-by: Jakub Kicinski <kuba@kernel.org>
15 ---
16 drivers/net/dsa/qca/qca8k-8xxx.c | 88 ------------------------------
17 drivers/net/dsa/qca/qca8k-common.c | 85 +++++++++++++++++++++++++++++
18 drivers/net/dsa/qca/qca8k.h | 12 ++++
19 3 files changed, 97 insertions(+), 88 deletions(-)
20
21 --- a/drivers/net/dsa/qca/qca8k-8xxx.c
22 +++ b/drivers/net/dsa/qca/qca8k-8xxx.c
23 @@ -2059,94 +2059,6 @@ qca8k_port_fast_age(struct dsa_switch *d
24 }
25
26 static int
27 -qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs)
28 -{
29 - struct qca8k_priv *priv = ds->priv;
30 - unsigned int secs = msecs / 1000;
31 - u32 val;
32 -
33 - /* AGE_TIME reg is set in 7s step */
34 - val = secs / 7;
35 -
36 - /* Handle case with 0 as val to NOT disable
37 - * learning
38 - */
39 - if (!val)
40 - val = 1;
41 -
42 - return regmap_update_bits(priv->regmap, QCA8K_REG_ATU_CTRL, QCA8K_ATU_AGE_TIME_MASK,
43 - QCA8K_ATU_AGE_TIME(val));
44 -}
45 -
46 -static int
47 -qca8k_port_enable(struct dsa_switch *ds, int port,
48 - struct phy_device *phy)
49 -{
50 - struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
51 -
52 - qca8k_port_set_status(priv, port, 1);
53 - priv->port_enabled_map |= BIT(port);
54 -
55 - if (dsa_is_user_port(ds, port))
56 - phy_support_asym_pause(phy);
57 -
58 - return 0;
59 -}
60 -
61 -static void
62 -qca8k_port_disable(struct dsa_switch *ds, int port)
63 -{
64 - struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
65 -
66 - qca8k_port_set_status(priv, port, 0);
67 - priv->port_enabled_map &= ~BIT(port);
68 -}
69 -
70 -static int
71 -qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
72 -{
73 - struct qca8k_priv *priv = ds->priv;
74 - int ret;
75 -
76 - /* We have only have a general MTU setting.
77 - * DSA always set the CPU port's MTU to the largest MTU of the slave
78 - * ports.
79 - * Setting MTU just for the CPU port is sufficient to correctly set a
80 - * value for every port.
81 - */
82 - if (!dsa_is_cpu_port(ds, port))
83 - return 0;
84 -
85 - /* To change the MAX_FRAME_SIZE the cpu ports must be off or
86 - * the switch panics.
87 - * Turn off both cpu ports before applying the new value to prevent
88 - * this.
89 - */
90 - if (priv->port_enabled_map & BIT(0))
91 - qca8k_port_set_status(priv, 0, 0);
92 -
93 - if (priv->port_enabled_map & BIT(6))
94 - qca8k_port_set_status(priv, 6, 0);
95 -
96 - /* Include L2 header / FCS length */
97 - ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, new_mtu + ETH_HLEN + ETH_FCS_LEN);
98 -
99 - if (priv->port_enabled_map & BIT(0))
100 - qca8k_port_set_status(priv, 0, 1);
101 -
102 - if (priv->port_enabled_map & BIT(6))
103 - qca8k_port_set_status(priv, 6, 1);
104 -
105 - return ret;
106 -}
107 -
108 -static int
109 -qca8k_port_max_mtu(struct dsa_switch *ds, int port)
110 -{
111 - return QCA8K_MAX_MTU;
112 -}
113 -
114 -static int
115 qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr,
116 u16 port_mask, u16 vid)
117 {
118 --- a/drivers/net/dsa/qca/qca8k-common.c
119 +++ b/drivers/net/dsa/qca/qca8k-common.c
120 @@ -367,3 +367,88 @@ void qca8k_port_bridge_leave(struct dsa_
121 qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
122 QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port));
123 }
124 +
125 +int qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs)
126 +{
127 + struct qca8k_priv *priv = ds->priv;
128 + unsigned int secs = msecs / 1000;
129 + u32 val;
130 +
131 + /* AGE_TIME reg is set in 7s step */
132 + val = secs / 7;
133 +
134 + /* Handle case with 0 as val to NOT disable
135 + * learning
136 + */
137 + if (!val)
138 + val = 1;
139 +
140 + return regmap_update_bits(priv->regmap, QCA8K_REG_ATU_CTRL,
141 + QCA8K_ATU_AGE_TIME_MASK,
142 + QCA8K_ATU_AGE_TIME(val));
143 +}
144 +
145 +int qca8k_port_enable(struct dsa_switch *ds, int port,
146 + struct phy_device *phy)
147 +{
148 + struct qca8k_priv *priv = ds->priv;
149 +
150 + qca8k_port_set_status(priv, port, 1);
151 + priv->port_enabled_map |= BIT(port);
152 +
153 + if (dsa_is_user_port(ds, port))
154 + phy_support_asym_pause(phy);
155 +
156 + return 0;
157 +}
158 +
159 +void qca8k_port_disable(struct dsa_switch *ds, int port)
160 +{
161 + struct qca8k_priv *priv = ds->priv;
162 +
163 + qca8k_port_set_status(priv, port, 0);
164 + priv->port_enabled_map &= ~BIT(port);
165 +}
166 +
167 +int qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
168 +{
169 + struct qca8k_priv *priv = ds->priv;
170 + int ret;
171 +
172 + /* We have only have a general MTU setting.
173 + * DSA always set the CPU port's MTU to the largest MTU of the slave
174 + * ports.
175 + * Setting MTU just for the CPU port is sufficient to correctly set a
176 + * value for every port.
177 + */
178 + if (!dsa_is_cpu_port(ds, port))
179 + return 0;
180 +
181 + /* To change the MAX_FRAME_SIZE the cpu ports must be off or
182 + * the switch panics.
183 + * Turn off both cpu ports before applying the new value to prevent
184 + * this.
185 + */
186 + if (priv->port_enabled_map & BIT(0))
187 + qca8k_port_set_status(priv, 0, 0);
188 +
189 + if (priv->port_enabled_map & BIT(6))
190 + qca8k_port_set_status(priv, 6, 0);
191 +
192 + /* Include L2 header / FCS length */
193 + ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, new_mtu +
194 + ETH_HLEN + ETH_FCS_LEN);
195 +
196 + if (priv->port_enabled_map & BIT(0))
197 + qca8k_port_set_status(priv, 0, 1);
198 +
199 + if (priv->port_enabled_map & BIT(6))
200 + qca8k_port_set_status(priv, 6, 1);
201 +
202 + return ret;
203 +}
204 +
205 +int qca8k_port_max_mtu(struct dsa_switch *ds, int port)
206 +{
207 + return QCA8K_MAX_MTU;
208 +}
209 --- a/drivers/net/dsa/qca/qca8k.h
210 +++ b/drivers/net/dsa/qca/qca8k.h
211 @@ -453,4 +453,16 @@ int qca8k_port_bridge_join(struct dsa_sw
212 void qca8k_port_bridge_leave(struct dsa_switch *ds, int port,
213 struct net_device *br);
214
215 +/* Common port enable/disable function */
216 +int qca8k_port_enable(struct dsa_switch *ds, int port,
217 + struct phy_device *phy);
218 +void qca8k_port_disable(struct dsa_switch *ds, int port);
219 +
220 +/* Common MTU function */
221 +int qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu);
222 +int qca8k_port_max_mtu(struct dsa_switch *ds, int port);
223 +
224 +/* Common fast age function */
225 +int qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs);
226 +
227 #endif /* __QCA8K_H */