xref: /linux/drivers/net/dsa/sja1105/sja1105_mdio.c (revision 0be3ff0c)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright 2021 NXP
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 }
542