fdf2a964ccfce4fd193ed8c62310699574f46d17
[openwrt/staging/linusw.git] /
1 From fd993fd59d96d5e2d5972ec4ca1f9651025c987b Mon Sep 17 00:00:00 2001
2 From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
3 Date: Mon, 11 Apr 2022 10:46:27 +0100
4 Subject: [PATCH 07/13] net: dsa: mt7530: partially convert to phylink_pcs
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 Partially convert the mt7530 driver to use phylink's PCS support. This
10 is a partial implementation as we don't move anything into the
11 pcs_config method yet - this driver supports SGMII or 1000BASE-X
12 without in-band.
13
14 Tested-by: Marek BehĂșn <kabel@kernel.org>
15 Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
16 Signed-off-by: Paolo Abeni <pabeni@redhat.com>
17 ---
18 drivers/net/dsa/mt7530.c | 144 +++++++++++++++++++++++----------------
19 drivers/net/dsa/mt7530.h | 21 +++---
20 2 files changed, 95 insertions(+), 70 deletions(-)
21
22 --- a/drivers/net/dsa/mt7530.c
23 +++ b/drivers/net/dsa/mt7530.c
24 @@ -24,6 +24,11 @@
25
26 #include "mt7530.h"
27
28 +static struct mt753x_pcs *pcs_to_mt753x_pcs(struct phylink_pcs *pcs)
29 +{
30 + return container_of(pcs, struct mt753x_pcs, pcs);
31 +}
32 +
33 /* String, offset, and register size in bytes if different from 4 bytes */
34 static const struct mt7530_mib_desc mt7530_mib[] = {
35 MIB_DESC(1, 0x00, "TxDrop"),
36 @@ -2576,12 +2581,11 @@ static int mt7531_rgmii_setup(struct mt7
37 return 0;
38 }
39
40 -static void
41 -mt7531_sgmii_link_up_force(struct dsa_switch *ds, int port,
42 - unsigned int mode, phy_interface_t interface,
43 - int speed, int duplex)
44 +static void mt7531_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
45 + phy_interface_t interface, int speed, int duplex)
46 {
47 - struct mt7530_priv *priv = ds->priv;
48 + struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
49 + int port = pcs_to_mt753x_pcs(pcs)->port;
50 unsigned int val;
51
52 /* For adjusting speed and duplex of SGMII force mode. */
53 @@ -2607,6 +2611,9 @@ mt7531_sgmii_link_up_force(struct dsa_sw
54
55 /* MT7531 SGMII 1G force mode can only work in full duplex mode,
56 * no matter MT7531_SGMII_FORCE_HALF_DUPLEX is set or not.
57 + *
58 + * The speed check is unnecessary as the MAC capabilities apply
59 + * this restriction. --rmk
60 */
61 if ((speed == SPEED_10 || speed == SPEED_100) &&
62 duplex != DUPLEX_FULL)
63 @@ -2682,9 +2689,10 @@ static int mt7531_sgmii_setup_mode_an(st
64 return 0;
65 }
66
67 -static void mt7531_sgmii_restart_an(struct dsa_switch *ds, int port)
68 +static void mt7531_pcs_an_restart(struct phylink_pcs *pcs)
69 {
70 - struct mt7530_priv *priv = ds->priv;
71 + struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
72 + int port = pcs_to_mt753x_pcs(pcs)->port;
73 u32 val;
74
75 /* Only restart AN when AN is enabled */
76 @@ -2741,6 +2749,24 @@ mt753x_mac_config(struct dsa_switch *ds,
77 return priv->info->mac_port_config(ds, port, mode, state->interface);
78 }
79
80 +static struct phylink_pcs *
81 +mt753x_phylink_mac_select_pcs(struct dsa_switch *ds, int port,
82 + phy_interface_t interface)
83 +{
84 + struct mt7530_priv *priv = ds->priv;
85 +
86 + switch (interface) {
87 + case PHY_INTERFACE_MODE_TRGMII:
88 + case PHY_INTERFACE_MODE_SGMII:
89 + case PHY_INTERFACE_MODE_1000BASEX:
90 + case PHY_INTERFACE_MODE_2500BASEX:
91 + return &priv->pcs[port].pcs;
92 +
93 + default:
94 + return NULL;
95 + }
96 +}
97 +
98 static void
99 mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
100 const struct phylink_link_state *state)
101 @@ -2802,17 +2828,6 @@ unsupported:
102 mt7530_write(priv, MT7530_PMCR_P(port), mcr_new);
103 }
104
105 -static void
106 -mt753x_phylink_mac_an_restart(struct dsa_switch *ds, int port)
107 -{
108 - struct mt7530_priv *priv = ds->priv;
109 -
110 - if (!priv->info->mac_pcs_an_restart)
111 - return;
112 -
113 - priv->info->mac_pcs_an_restart(ds, port);
114 -}
115 -
116 static void mt753x_phylink_mac_link_down(struct dsa_switch *ds, int port,
117 unsigned int mode,
118 phy_interface_t interface)
119 @@ -2822,16 +2837,13 @@ static void mt753x_phylink_mac_link_down
120 mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK);
121 }
122
123 -static void mt753x_mac_pcs_link_up(struct dsa_switch *ds, int port,
124 - unsigned int mode, phy_interface_t interface,
125 - int speed, int duplex)
126 +static void mt753x_phylink_pcs_link_up(struct phylink_pcs *pcs,
127 + unsigned int mode,
128 + phy_interface_t interface,
129 + int speed, int duplex)
130 {
131 - struct mt7530_priv *priv = ds->priv;
132 -
133 - if (!priv->info->mac_pcs_link_up)
134 - return;
135 -
136 - priv->info->mac_pcs_link_up(ds, port, mode, interface, speed, duplex);
137 + if (pcs->ops->pcs_link_up)
138 + pcs->ops->pcs_link_up(pcs, mode, interface, speed, duplex);
139 }
140
141 static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port,
142 @@ -2844,8 +2856,6 @@ static void mt753x_phylink_mac_link_up(s
143 struct mt7530_priv *priv = ds->priv;
144 u32 mcr;
145
146 - mt753x_mac_pcs_link_up(ds, port, mode, interface, speed, duplex);
147 -
148 mcr = PMCR_RX_EN | PMCR_TX_EN | PMCR_FORCE_LNK;
149
150 /* MT753x MAC works in 1G full duplex mode for all up-clocked
151 @@ -2923,6 +2933,8 @@ mt7531_cpu_port_config(struct dsa_switch
152 return ret;
153 mt7530_write(priv, MT7530_PMCR_P(port),
154 PMCR_CPU_PORT_SETTING(priv->id));
155 + mt753x_phylink_pcs_link_up(&priv->pcs[port].pcs, MLO_AN_FIXED,
156 + interface, speed, DUPLEX_FULL);
157 mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED, interface, NULL,
158 speed, DUPLEX_FULL, true, true);
159
160 @@ -2962,16 +2974,13 @@ mt753x_phylink_validate(struct dsa_switc
161 linkmode_and(state->advertising, state->advertising, mask);
162 }
163
164 -static int
165 -mt7530_phylink_mac_link_state(struct dsa_switch *ds, int port,
166 - struct phylink_link_state *state)
167 +static void mt7530_pcs_get_state(struct phylink_pcs *pcs,
168 + struct phylink_link_state *state)
169 {
170 - struct mt7530_priv *priv = ds->priv;
171 + struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
172 + int port = pcs_to_mt753x_pcs(pcs)->port;
173 u32 pmsr;
174
175 - if (port < 0 || port >= MT7530_NUM_PORTS)
176 - return -EINVAL;
177 -
178 pmsr = mt7530_read(priv, MT7530_PMSR_P(port));
179
180 state->link = (pmsr & PMSR_LINK);
181 @@ -2998,8 +3007,6 @@ mt7530_phylink_mac_link_state(struct dsa
182 state->pause |= MLO_PAUSE_RX;
183 if (pmsr & PMSR_TX_FC)
184 state->pause |= MLO_PAUSE_TX;
185 -
186 - return 1;
187 }
188
189 static int
190 @@ -3041,32 +3048,49 @@ mt7531_sgmii_pcs_get_state_an(struct mt7
191 return 0;
192 }
193
194 -static int
195 -mt7531_phylink_mac_link_state(struct dsa_switch *ds, int port,
196 - struct phylink_link_state *state)
197 +static void mt7531_pcs_get_state(struct phylink_pcs *pcs,
198 + struct phylink_link_state *state)
199 {
200 - struct mt7530_priv *priv = ds->priv;
201 + struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
202 + int port = pcs_to_mt753x_pcs(pcs)->port;
203
204 if (state->interface == PHY_INTERFACE_MODE_SGMII)
205 - return mt7531_sgmii_pcs_get_state_an(priv, port, state);
206 -
207 - return -EOPNOTSUPP;
208 + mt7531_sgmii_pcs_get_state_an(priv, port, state);
209 + else
210 + state->link = false;
211 }
212
213 -static int
214 -mt753x_phylink_mac_link_state(struct dsa_switch *ds, int port,
215 - struct phylink_link_state *state)
216 +static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
217 + phy_interface_t interface,
218 + const unsigned long *advertising,
219 + bool permit_pause_to_mac)
220 {
221 - struct mt7530_priv *priv = ds->priv;
222 + return 0;
223 +}
224
225 - return priv->info->mac_port_get_state(ds, port, state);
226 +static void mt7530_pcs_an_restart(struct phylink_pcs *pcs)
227 +{
228 }
229
230 +static const struct phylink_pcs_ops mt7530_pcs_ops = {
231 + .pcs_get_state = mt7530_pcs_get_state,
232 + .pcs_config = mt753x_pcs_config,
233 + .pcs_an_restart = mt7530_pcs_an_restart,
234 +};
235 +
236 +static const struct phylink_pcs_ops mt7531_pcs_ops = {
237 + .pcs_get_state = mt7531_pcs_get_state,
238 + .pcs_config = mt753x_pcs_config,
239 + .pcs_an_restart = mt7531_pcs_an_restart,
240 + .pcs_link_up = mt7531_pcs_link_up,
241 +};
242 +
243 static int
244 mt753x_setup(struct dsa_switch *ds)
245 {
246 struct mt7530_priv *priv = ds->priv;
247 int ret = priv->info->sw_setup(ds);
248 + int i;
249
250 if (ret)
251 return ret;
252 @@ -3079,6 +3103,13 @@ mt753x_setup(struct dsa_switch *ds)
253 if (ret && priv->irq)
254 mt7530_free_irq_common(priv);
255
256 + /* Initialise the PCS devices */
257 + for (i = 0; i < priv->ds->num_ports; i++) {
258 + priv->pcs[i].pcs.ops = priv->info->pcs_ops;
259 + priv->pcs[i].priv = priv;
260 + priv->pcs[i].port = i;
261 + }
262 +
263 return ret;
264 }
265
266 @@ -3140,9 +3171,8 @@ static const struct dsa_switch_ops mt753
267 .port_mirror_del = mt753x_port_mirror_del,
268 .phylink_get_caps = mt753x_phylink_get_caps,
269 .phylink_validate = mt753x_phylink_validate,
270 - .phylink_mac_link_state = mt753x_phylink_mac_link_state,
271 + .phylink_mac_select_pcs = mt753x_phylink_mac_select_pcs,
272 .phylink_mac_config = mt753x_phylink_mac_config,
273 - .phylink_mac_an_restart = mt753x_phylink_mac_an_restart,
274 .phylink_mac_link_down = mt753x_phylink_mac_link_down,
275 .phylink_mac_link_up = mt753x_phylink_mac_link_up,
276 .get_mac_eee = mt753x_get_mac_eee,
277 @@ -3152,36 +3182,34 @@ static const struct dsa_switch_ops mt753
278 static const struct mt753x_info mt753x_table[] = {
279 [ID_MT7621] = {
280 .id = ID_MT7621,
281 + .pcs_ops = &mt7530_pcs_ops,
282 .sw_setup = mt7530_setup,
283 .phy_read = mt7530_phy_read,
284 .phy_write = mt7530_phy_write,
285 .pad_setup = mt7530_pad_clk_setup,
286 .mac_port_get_caps = mt7530_mac_port_get_caps,
287 - .mac_port_get_state = mt7530_phylink_mac_link_state,
288 .mac_port_config = mt7530_mac_config,
289 },
290 [ID_MT7530] = {
291 .id = ID_MT7530,
292 + .pcs_ops = &mt7530_pcs_ops,
293 .sw_setup = mt7530_setup,
294 .phy_read = mt7530_phy_read,
295 .phy_write = mt7530_phy_write,
296 .pad_setup = mt7530_pad_clk_setup,
297 .mac_port_get_caps = mt7530_mac_port_get_caps,
298 - .mac_port_get_state = mt7530_phylink_mac_link_state,
299 .mac_port_config = mt7530_mac_config,
300 },
301 [ID_MT7531] = {
302 .id = ID_MT7531,
303 + .pcs_ops = &mt7531_pcs_ops,
304 .sw_setup = mt7531_setup,
305 .phy_read = mt7531_ind_phy_read,
306 .phy_write = mt7531_ind_phy_write,
307 .pad_setup = mt7531_pad_setup,
308 .cpu_port_config = mt7531_cpu_port_config,
309 .mac_port_get_caps = mt7531_mac_port_get_caps,
310 - .mac_port_get_state = mt7531_phylink_mac_link_state,
311 .mac_port_config = mt7531_mac_config,
312 - .mac_pcs_an_restart = mt7531_sgmii_restart_an,
313 - .mac_pcs_link_up = mt7531_sgmii_link_up_force,
314 },
315 };
316
317 @@ -3239,7 +3267,7 @@ mt7530_probe(struct mdio_device *mdiodev
318 if (!priv->info->sw_setup || !priv->info->pad_setup ||
319 !priv->info->phy_read || !priv->info->phy_write ||
320 !priv->info->mac_port_get_caps ||
321 - !priv->info->mac_port_get_state || !priv->info->mac_port_config)
322 + !priv->info->mac_port_config)
323 return -EINVAL;
324
325 priv->id = priv->info->id;
326 --- a/drivers/net/dsa/mt7530.h
327 +++ b/drivers/net/dsa/mt7530.h
328 @@ -741,6 +741,12 @@ static const char *p5_intf_modes(unsigne
329
330 struct mt7530_priv;
331
332 +struct mt753x_pcs {
333 + struct phylink_pcs pcs;
334 + struct mt7530_priv *priv;
335 + int port;
336 +};
337 +
338 /* struct mt753x_info - This is the main data structure for holding the specific
339 * part for each supported device
340 * @sw_setup: Holding the handler to a device initialization
341 @@ -752,18 +758,14 @@ struct mt7530_priv;
342 * port
343 * @mac_port_validate: Holding the way to set addition validate type for a
344 * certan MAC port
345 - * @mac_port_get_state: Holding the way getting the MAC/PCS state for a certain
346 - * MAC port
347 * @mac_port_config: Holding the way setting up the PHY attribute to a
348 * certain MAC port
349 - * @mac_pcs_an_restart Holding the way restarting PCS autonegotiation for a
350 - * certain MAC port
351 - * @mac_pcs_link_up: Holding the way setting up the PHY attribute to the pcs
352 - * of the certain MAC port
353 */
354 struct mt753x_info {
355 enum mt753x_id id;
356
357 + const struct phylink_pcs_ops *pcs_ops;
358 +
359 int (*sw_setup)(struct dsa_switch *ds);
360 int (*phy_read)(struct mt7530_priv *priv, int port, int regnum);
361 int (*phy_write)(struct mt7530_priv *priv, int port, int regnum, u16 val);
362 @@ -774,15 +776,9 @@ struct mt753x_info {
363 void (*mac_port_validate)(struct dsa_switch *ds, int port,
364 phy_interface_t interface,
365 unsigned long *supported);
366 - int (*mac_port_get_state)(struct dsa_switch *ds, int port,
367 - struct phylink_link_state *state);
368 int (*mac_port_config)(struct dsa_switch *ds, int port,
369 unsigned int mode,
370 phy_interface_t interface);
371 - void (*mac_pcs_an_restart)(struct dsa_switch *ds, int port);
372 - void (*mac_pcs_link_up)(struct dsa_switch *ds, int port,
373 - unsigned int mode, phy_interface_t interface,
374 - int speed, int duplex);
375 };
376
377 /* struct mt7530_priv - This is the main data structure for holding the state
378 @@ -824,6 +820,7 @@ struct mt7530_priv {
379 u8 mirror_tx;
380
381 struct mt7530_port ports[MT7530_NUM_PORTS];
382 + struct mt753x_pcs pcs[MT7530_NUM_PORTS];
383 /* protect among processes for registers access*/
384 struct mutex reg_mutex;
385 int irq;