net: dsa: sja1105: fix use-after-free after calling of_find_compatible_node, or worse
[linux-2.6-microblaze.git] / drivers / net / dsa / sja1105 / sja1105_mdio.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright 2021, NXP Semiconductors
3  */
4 #include <linux/pcs/pcs-xpcs.h>
5 #include <linux/of_mdio.h>
6 #include "sja1105.h"
7
8 #define SJA1110_PCS_BANK_REG            SJA1110_SPI_ADDR(0x3fc)
9
10 int sja1105_pcs_mdio_read(struct mii_bus *bus, int phy, int reg)
11 {
12         struct sja1105_mdio_private *mdio_priv = bus->priv;
13         struct sja1105_private *priv = mdio_priv->priv;
14         u64 addr;
15         u32 tmp;
16         u16 mmd;
17         int rc;
18
19         if (!(reg & MII_ADDR_C45))
20                 return -EINVAL;
21
22         mmd = (reg >> MII_DEVADDR_C45_SHIFT) & 0x1f;
23         addr = (mmd << 16) | (reg & GENMASK(15, 0));
24
25         if (mmd != MDIO_MMD_VEND1 && mmd != MDIO_MMD_VEND2)
26                 return 0xffff;
27
28         if (mmd == MDIO_MMD_VEND2 && (reg & GENMASK(15, 0)) == MII_PHYSID1)
29                 return NXP_SJA1105_XPCS_ID >> 16;
30         if (mmd == MDIO_MMD_VEND2 && (reg & GENMASK(15, 0)) == MII_PHYSID2)
31                 return NXP_SJA1105_XPCS_ID & GENMASK(15, 0);
32
33         rc = sja1105_xfer_u32(priv, SPI_READ, addr, &tmp, NULL);
34         if (rc < 0)
35                 return rc;
36
37         return tmp & 0xffff;
38 }
39
40 int sja1105_pcs_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val)
41 {
42         struct sja1105_mdio_private *mdio_priv = bus->priv;
43         struct sja1105_private *priv = mdio_priv->priv;
44         u64 addr;
45         u32 tmp;
46         u16 mmd;
47
48         if (!(reg & MII_ADDR_C45))
49                 return -EINVAL;
50
51         mmd = (reg >> MII_DEVADDR_C45_SHIFT) & 0x1f;
52         addr = (mmd << 16) | (reg & GENMASK(15, 0));
53         tmp = val;
54
55         if (mmd != MDIO_MMD_VEND1 && mmd != MDIO_MMD_VEND2)
56                 return -EINVAL;
57
58         return sja1105_xfer_u32(priv, SPI_WRITE, addr, &tmp, NULL);
59 }
60
61 int sja1110_pcs_mdio_read(struct mii_bus *bus, int phy, int reg)
62 {
63         struct sja1105_mdio_private *mdio_priv = bus->priv;
64         struct sja1105_private *priv = mdio_priv->priv;
65         const struct sja1105_regs *regs = priv->info->regs;
66         int offset, bank;
67         u64 addr;
68         u32 tmp;
69         u16 mmd;
70         int rc;
71
72         if (!(reg & MII_ADDR_C45))
73                 return -EINVAL;
74
75         if (regs->pcs_base[phy] == SJA1105_RSV_ADDR)
76                 return -ENODEV;
77
78         mmd = (reg >> MII_DEVADDR_C45_SHIFT) & 0x1f;
79         addr = (mmd << 16) | (reg & GENMASK(15, 0));
80
81         if (mmd == MDIO_MMD_VEND2 && (reg & GENMASK(15, 0)) == MII_PHYSID1)
82                 return NXP_SJA1110_XPCS_ID >> 16;
83         if (mmd == MDIO_MMD_VEND2 && (reg & GENMASK(15, 0)) == MII_PHYSID2)
84                 return NXP_SJA1110_XPCS_ID & GENMASK(15, 0);
85
86         bank = addr >> 8;
87         offset = addr & GENMASK(7, 0);
88
89         /* This addressing scheme reserves register 0xff for the bank address
90          * register, so that can never be addressed.
91          */
92         if (WARN_ON(offset == 0xff))
93                 return -ENODEV;
94
95         tmp = bank;
96
97         rc = sja1105_xfer_u32(priv, SPI_WRITE,
98                               regs->pcs_base[phy] + SJA1110_PCS_BANK_REG,
99                               &tmp, NULL);
100         if (rc < 0)
101                 return rc;
102
103         rc = sja1105_xfer_u32(priv, SPI_READ, regs->pcs_base[phy] + offset,
104                               &tmp, NULL);
105         if (rc < 0)
106                 return rc;
107
108         return tmp & 0xffff;
109 }
110
111 int sja1110_pcs_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val)
112 {
113         struct sja1105_mdio_private *mdio_priv = bus->priv;
114         struct sja1105_private *priv = mdio_priv->priv;
115         const struct sja1105_regs *regs = priv->info->regs;
116         int offset, bank;
117         u64 addr;
118         u32 tmp;
119         u16 mmd;
120         int rc;
121
122         if (!(reg & MII_ADDR_C45))
123                 return -EINVAL;
124
125         if (regs->pcs_base[phy] == SJA1105_RSV_ADDR)
126                 return -ENODEV;
127
128         mmd = (reg >> MII_DEVADDR_C45_SHIFT) & 0x1f;
129         addr = (mmd << 16) | (reg & GENMASK(15, 0));
130
131         bank = addr >> 8;
132         offset = addr & GENMASK(7, 0);
133
134         /* This addressing scheme reserves register 0xff for the bank address
135          * register, so that can never be addressed.
136          */
137         if (WARN_ON(offset == 0xff))
138                 return -ENODEV;
139
140         tmp = bank;
141
142         rc = sja1105_xfer_u32(priv, SPI_WRITE,
143                               regs->pcs_base[phy] + SJA1110_PCS_BANK_REG,
144                               &tmp, NULL);
145         if (rc < 0)
146                 return rc;
147
148         tmp = val;
149
150         return sja1105_xfer_u32(priv, SPI_WRITE, regs->pcs_base[phy] + offset,
151                                 &tmp, NULL);
152 }
153
154 enum sja1105_mdio_opcode {
155         SJA1105_C45_ADDR = 0,
156         SJA1105_C22 = 1,
157         SJA1105_C45_DATA = 2,
158         SJA1105_C45_DATA_AUTOINC = 3,
159 };
160
161 static u64 sja1105_base_t1_encode_addr(struct sja1105_private *priv,
162                                        int phy, enum sja1105_mdio_opcode op,
163                                        int xad)
164 {
165         const struct sja1105_regs *regs = priv->info->regs;
166
167         return regs->mdio_100base_t1 | (phy << 7) | (op << 5) | (xad << 0);
168 }
169
170 static int sja1105_base_t1_mdio_read(struct mii_bus *bus, int phy, int reg)
171 {
172         struct sja1105_mdio_private *mdio_priv = bus->priv;
173         struct sja1105_private *priv = mdio_priv->priv;
174         u64 addr;
175         u32 tmp;
176         int rc;
177
178         if (reg & MII_ADDR_C45) {
179                 u16 mmd = (reg >> MII_DEVADDR_C45_SHIFT) & 0x1f;
180
181                 addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C45_ADDR,
182                                                    mmd);
183
184                 tmp = reg & MII_REGADDR_C45_MASK;
185
186                 rc = sja1105_xfer_u32(priv, SPI_WRITE, addr, &tmp, NULL);
187                 if (rc < 0)
188                         return rc;
189
190                 addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C45_DATA,
191                                                    mmd);
192
193                 rc = sja1105_xfer_u32(priv, SPI_READ, addr, &tmp, NULL);
194                 if (rc < 0)
195                         return rc;
196
197                 return tmp & 0xffff;
198         }
199
200         /* Clause 22 read */
201         addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C22, reg & 0x1f);
202
203         rc = sja1105_xfer_u32(priv, SPI_READ, addr, &tmp, NULL);
204         if (rc < 0)
205                 return rc;
206
207         return tmp & 0xffff;
208 }
209
210 static int sja1105_base_t1_mdio_write(struct mii_bus *bus, int phy, int reg,
211                                       u16 val)
212 {
213         struct sja1105_mdio_private *mdio_priv = bus->priv;
214         struct sja1105_private *priv = mdio_priv->priv;
215         u64 addr;
216         u32 tmp;
217         int rc;
218
219         if (reg & MII_ADDR_C45) {
220                 u16 mmd = (reg >> MII_DEVADDR_C45_SHIFT) & 0x1f;
221
222                 addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C45_ADDR,
223                                                    mmd);
224
225                 tmp = reg & MII_REGADDR_C45_MASK;
226
227                 rc = sja1105_xfer_u32(priv, SPI_WRITE, addr, &tmp, NULL);
228                 if (rc < 0)
229                         return rc;
230
231                 addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C45_DATA,
232                                                    mmd);
233
234                 tmp = val & 0xffff;
235
236                 rc = sja1105_xfer_u32(priv, SPI_WRITE, addr, &tmp, NULL);
237                 if (rc < 0)
238                         return rc;
239
240                 return 0;
241         }
242
243         /* Clause 22 write */
244         addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C22, reg & 0x1f);
245
246         tmp = val & 0xffff;
247
248         return sja1105_xfer_u32(priv, SPI_WRITE, addr, &tmp, NULL);
249 }
250
251 static int sja1105_base_tx_mdio_read(struct mii_bus *bus, int phy, int reg)
252 {
253         struct sja1105_mdio_private *mdio_priv = bus->priv;
254         struct sja1105_private *priv = mdio_priv->priv;
255         const struct sja1105_regs *regs = priv->info->regs;
256         u32 tmp;
257         int rc;
258
259         rc = sja1105_xfer_u32(priv, SPI_READ, regs->mdio_100base_tx + reg,
260                               &tmp, NULL);
261         if (rc < 0)
262                 return rc;
263
264         return tmp & 0xffff;
265 }
266
267 static int sja1105_base_tx_mdio_write(struct mii_bus *bus, int phy, int reg,
268                                       u16 val)
269 {
270         struct sja1105_mdio_private *mdio_priv = bus->priv;
271         struct sja1105_private *priv = mdio_priv->priv;
272         const struct sja1105_regs *regs = priv->info->regs;
273         u32 tmp = val;
274
275         return sja1105_xfer_u32(priv, SPI_WRITE, regs->mdio_100base_tx + reg,
276                                 &tmp, NULL);
277 }
278
279 static int sja1105_mdiobus_base_tx_register(struct sja1105_private *priv,
280                                             struct device_node *mdio_node)
281 {
282         struct sja1105_mdio_private *mdio_priv;
283         struct device_node *np;
284         struct mii_bus *bus;
285         int rc = 0;
286
287         np = of_get_compatible_child(mdio_node, "nxp,sja1110-base-tx-mdio");
288         if (!np)
289                 return 0;
290
291         if (!of_device_is_available(np))
292                 goto out_put_np;
293
294         bus = mdiobus_alloc_size(sizeof(*mdio_priv));
295         if (!bus) {
296                 rc = -ENOMEM;
297                 goto out_put_np;
298         }
299
300         bus->name = "SJA1110 100base-TX MDIO bus";
301         snprintf(bus->id, MII_BUS_ID_SIZE, "%s-base-tx",
302                  dev_name(priv->ds->dev));
303         bus->read = sja1105_base_tx_mdio_read;
304         bus->write = sja1105_base_tx_mdio_write;
305         bus->parent = priv->ds->dev;
306         mdio_priv = bus->priv;
307         mdio_priv->priv = priv;
308
309         rc = of_mdiobus_register(bus, np);
310         if (rc) {
311                 mdiobus_free(bus);
312                 goto out_put_np;
313         }
314
315         priv->mdio_base_tx = bus;
316
317 out_put_np:
318         of_node_put(np);
319
320         return rc;
321 }
322
323 static void sja1105_mdiobus_base_tx_unregister(struct sja1105_private *priv)
324 {
325         if (!priv->mdio_base_tx)
326                 return;
327
328         mdiobus_unregister(priv->mdio_base_tx);
329         mdiobus_free(priv->mdio_base_tx);
330         priv->mdio_base_tx = NULL;
331 }
332
333 static int sja1105_mdiobus_base_t1_register(struct sja1105_private *priv,
334                                             struct device_node *mdio_node)
335 {
336         struct sja1105_mdio_private *mdio_priv;
337         struct device_node *np;
338         struct mii_bus *bus;
339         int rc = 0;
340
341         np = of_get_compatible_child(mdio_node, "nxp,sja1110-base-t1-mdio");
342         if (!np)
343                 return 0;
344
345         if (!of_device_is_available(np))
346                 goto out_put_np;
347
348         bus = mdiobus_alloc_size(sizeof(*mdio_priv));
349         if (!bus) {
350                 rc = -ENOMEM;
351                 goto out_put_np;
352         }
353
354         bus->name = "SJA1110 100base-T1 MDIO bus";
355         snprintf(bus->id, MII_BUS_ID_SIZE, "%s-base-t1",
356                  dev_name(priv->ds->dev));
357         bus->read = sja1105_base_t1_mdio_read;
358         bus->write = sja1105_base_t1_mdio_write;
359         bus->parent = priv->ds->dev;
360         mdio_priv = bus->priv;
361         mdio_priv->priv = priv;
362
363         rc = of_mdiobus_register(bus, np);
364         if (rc) {
365                 mdiobus_free(bus);
366                 goto out_put_np;
367         }
368
369         priv->mdio_base_t1 = bus;
370
371 out_put_np:
372         of_node_put(np);
373
374         return rc;
375 }
376
377 static void sja1105_mdiobus_base_t1_unregister(struct sja1105_private *priv)
378 {
379         if (!priv->mdio_base_t1)
380                 return;
381
382         mdiobus_unregister(priv->mdio_base_t1);
383         mdiobus_free(priv->mdio_base_t1);
384         priv->mdio_base_t1 = NULL;
385 }
386
387 static int sja1105_mdiobus_pcs_register(struct sja1105_private *priv)
388 {
389         struct sja1105_mdio_private *mdio_priv;
390         struct dsa_switch *ds = priv->ds;
391         struct mii_bus *bus;
392         int rc = 0;
393         int port;
394
395         if (!priv->info->pcs_mdio_read || !priv->info->pcs_mdio_write)
396                 return 0;
397
398         bus = mdiobus_alloc_size(sizeof(*mdio_priv));
399         if (!bus)
400                 return -ENOMEM;
401
402         bus->name = "SJA1105 PCS MDIO bus";
403         snprintf(bus->id, MII_BUS_ID_SIZE, "%s-pcs",
404                  dev_name(ds->dev));
405         bus->read = priv->info->pcs_mdio_read;
406         bus->write = priv->info->pcs_mdio_write;
407         bus->parent = ds->dev;
408         /* There is no PHY on this MDIO bus => mask out all PHY addresses
409          * from auto probing.
410          */
411         bus->phy_mask = ~0;
412         mdio_priv = bus->priv;
413         mdio_priv->priv = priv;
414
415         rc = mdiobus_register(bus);
416         if (rc) {
417                 mdiobus_free(bus);
418                 return rc;
419         }
420
421         for (port = 0; port < ds->num_ports; port++) {
422                 struct mdio_device *mdiodev;
423                 struct dw_xpcs *xpcs;
424
425                 if (dsa_is_unused_port(ds, port))
426                         continue;
427
428                 if (priv->phy_mode[port] != PHY_INTERFACE_MODE_SGMII &&
429                     priv->phy_mode[port] != PHY_INTERFACE_MODE_2500BASEX)
430                         continue;
431
432                 mdiodev = mdio_device_create(bus, port);
433                 if (IS_ERR(mdiodev)) {
434                         rc = PTR_ERR(mdiodev);
435                         goto out_pcs_free;
436                 }
437
438                 xpcs = xpcs_create(mdiodev, priv->phy_mode[port]);
439                 if (IS_ERR(xpcs)) {
440                         rc = PTR_ERR(xpcs);
441                         goto out_pcs_free;
442                 }
443
444                 priv->xpcs[port] = xpcs;
445         }
446
447         priv->mdio_pcs = bus;
448
449         return 0;
450
451 out_pcs_free:
452         for (port = 0; port < ds->num_ports; port++) {
453                 if (!priv->xpcs[port])
454                         continue;
455
456                 mdio_device_free(priv->xpcs[port]->mdiodev);
457                 xpcs_destroy(priv->xpcs[port]);
458                 priv->xpcs[port] = NULL;
459         }
460
461         mdiobus_unregister(bus);
462         mdiobus_free(bus);
463
464         return rc;
465 }
466
467 static void sja1105_mdiobus_pcs_unregister(struct sja1105_private *priv)
468 {
469         struct dsa_switch *ds = priv->ds;
470         int port;
471
472         if (!priv->mdio_pcs)
473                 return;
474
475         for (port = 0; port < ds->num_ports; port++) {
476                 if (!priv->xpcs[port])
477                         continue;
478
479                 mdio_device_free(priv->xpcs[port]->mdiodev);
480                 xpcs_destroy(priv->xpcs[port]);
481                 priv->xpcs[port] = NULL;
482         }
483
484         mdiobus_unregister(priv->mdio_pcs);
485         mdiobus_free(priv->mdio_pcs);
486         priv->mdio_pcs = NULL;
487 }
488
489 int sja1105_mdiobus_register(struct dsa_switch *ds)
490 {
491         struct sja1105_private *priv = ds->priv;
492         const struct sja1105_regs *regs = priv->info->regs;
493         struct device_node *switch_node = ds->dev->of_node;
494         struct device_node *mdio_node;
495         int rc;
496
497         rc = sja1105_mdiobus_pcs_register(priv);
498         if (rc)
499                 return rc;
500
501         mdio_node = of_get_child_by_name(switch_node, "mdios");
502         if (!mdio_node)
503                 return 0;
504
505         if (!of_device_is_available(mdio_node))
506                 goto out_put_mdio_node;
507
508         if (regs->mdio_100base_tx != SJA1105_RSV_ADDR) {
509                 rc = sja1105_mdiobus_base_tx_register(priv, mdio_node);
510                 if (rc)
511                         goto err_put_mdio_node;
512         }
513
514         if (regs->mdio_100base_t1 != SJA1105_RSV_ADDR) {
515                 rc = sja1105_mdiobus_base_t1_register(priv, mdio_node);
516                 if (rc)
517                         goto err_free_base_tx_mdiobus;
518         }
519
520 out_put_mdio_node:
521         of_node_put(mdio_node);
522
523         return 0;
524
525 err_free_base_tx_mdiobus:
526         sja1105_mdiobus_base_tx_unregister(priv);
527 err_put_mdio_node:
528         of_node_put(mdio_node);
529         sja1105_mdiobus_pcs_unregister(priv);
530
531         return rc;
532 }
533
534 void sja1105_mdiobus_unregister(struct dsa_switch *ds)
535 {
536         struct sja1105_private *priv = ds->priv;
537
538         sja1105_mdiobus_base_t1_unregister(priv);
539         sja1105_mdiobus_base_tx_unregister(priv);
540         sja1105_mdiobus_pcs_unregister(priv);
541 }