xref: /linux/drivers/net/dsa/sja1105/sja1105_mdio.c (revision c532de5a67a70f8533d495f8f2aaa9a0491c3ad0)
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 mmd, int reg,
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 dw_xpcs *xpcs;
404 
405 		if (dsa_is_unused_port(ds, port))
406 			continue;
407 
408 		if (priv->phy_mode[port] != PHY_INTERFACE_MODE_SGMII &&
409 		    priv->phy_mode[port] != PHY_INTERFACE_MODE_2500BASEX)
410 			continue;
411 
412 		xpcs = xpcs_create_mdiodev(bus, port, priv->phy_mode[port]);
413 		if (IS_ERR(xpcs)) {
414 			rc = PTR_ERR(xpcs);
415 			goto out_pcs_free;
416 		}
417 
418 		priv->xpcs[port] = xpcs;
419 	}
420 
421 	priv->mdio_pcs = bus;
422 
423 	return 0;
424 
425 out_pcs_free:
426 	for (port = 0; port < ds->num_ports; port++) {
427 		if (!priv->xpcs[port])
428 			continue;
429 
430 		xpcs_destroy(priv->xpcs[port]);
431 		priv->xpcs[port] = NULL;
432 	}
433 
434 	mdiobus_unregister(bus);
435 	mdiobus_free(bus);
436 
437 	return rc;
438 }
439 
440 static void sja1105_mdiobus_pcs_unregister(struct sja1105_private *priv)
441 {
442 	struct dsa_switch *ds = priv->ds;
443 	int port;
444 
445 	if (!priv->mdio_pcs)
446 		return;
447 
448 	for (port = 0; port < ds->num_ports; port++) {
449 		if (!priv->xpcs[port])
450 			continue;
451 
452 		xpcs_destroy(priv->xpcs[port]);
453 		priv->xpcs[port] = NULL;
454 	}
455 
456 	mdiobus_unregister(priv->mdio_pcs);
457 	mdiobus_free(priv->mdio_pcs);
458 	priv->mdio_pcs = NULL;
459 }
460 
461 int sja1105_mdiobus_register(struct dsa_switch *ds)
462 {
463 	struct sja1105_private *priv = ds->priv;
464 	const struct sja1105_regs *regs = priv->info->regs;
465 	struct device_node *switch_node = ds->dev->of_node;
466 	struct device_node *mdio_node;
467 	int rc;
468 
469 	rc = sja1105_mdiobus_pcs_register(priv);
470 	if (rc)
471 		return rc;
472 
473 	mdio_node = of_get_child_by_name(switch_node, "mdios");
474 	if (!mdio_node)
475 		return 0;
476 
477 	if (!of_device_is_available(mdio_node))
478 		goto out_put_mdio_node;
479 
480 	if (regs->mdio_100base_tx != SJA1105_RSV_ADDR) {
481 		rc = sja1105_mdiobus_base_tx_register(priv, mdio_node);
482 		if (rc)
483 			goto err_put_mdio_node;
484 	}
485 
486 	if (regs->mdio_100base_t1 != SJA1105_RSV_ADDR) {
487 		rc = sja1105_mdiobus_base_t1_register(priv, mdio_node);
488 		if (rc)
489 			goto err_free_base_tx_mdiobus;
490 	}
491 
492 out_put_mdio_node:
493 	of_node_put(mdio_node);
494 
495 	return 0;
496 
497 err_free_base_tx_mdiobus:
498 	sja1105_mdiobus_base_tx_unregister(priv);
499 err_put_mdio_node:
500 	of_node_put(mdio_node);
501 	sja1105_mdiobus_pcs_unregister(priv);
502 
503 	return rc;
504 }
505 
506 void sja1105_mdiobus_unregister(struct dsa_switch *ds)
507 {
508 	struct sja1105_private *priv = ds->priv;
509 
510 	sja1105_mdiobus_base_t1_unregister(priv);
511 	sja1105_mdiobus_base_tx_unregister(priv);
512 	sja1105_mdiobus_pcs_unregister(priv);
513 }
514