7afa5be3d4e1b05c60fc1ffe0c855725dd7a6ab5
[librecmc/librecmc.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 @@ -25,6 +25,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 @@ -2792,12 +2797,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 @@ -2823,6 +2827,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 @@ -2898,9 +2905,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 @@ -2957,6 +2965,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 @@ -3018,17 +3044,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 @@ -3038,16 +3053,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 @@ -3060,8 +3072,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 @@ -3139,6 +3149,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 @@ -3178,16 +3190,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 @@ -3214,8 +3223,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 @@ -3257,32 +3264,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 @@ -3295,6 +3319,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 @@ -3356,9 +3387,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 @@ -3368,36 +3398,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 @@ -3455,7 +3483,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 @@ -773,6 +773,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 @@ -784,18 +790,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 @@ -806,15 +808,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 @@ -856,6 +852,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;