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