• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
sja1105_pcs_mdio_read(struct mii_bus * bus,int phy,int reg)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 
sja1105_pcs_mdio_write(struct mii_bus * bus,int phy,int reg,u16 val)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 
sja1110_pcs_mdio_read(struct mii_bus * bus,int phy,int reg)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 
sja1110_pcs_mdio_write(struct mii_bus * bus,int phy,int reg,u16 val)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 
sja1105_base_t1_encode_addr(struct sja1105_private * priv,int phy,enum sja1105_mdio_opcode op,int xad)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 
sja1105_base_t1_mdio_read(struct mii_bus * bus,int phy,int reg)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 
sja1105_base_t1_mdio_write(struct mii_bus * bus,int phy,int reg,u16 val)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 
sja1105_base_tx_mdio_read(struct mii_bus * bus,int phy,int reg)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 	if (reg & MII_ADDR_C45)
260 		return -EOPNOTSUPP;
261 
262 	rc = sja1105_xfer_u32(priv, SPI_READ, regs->mdio_100base_tx + reg,
263 			      &tmp, NULL);
264 	if (rc < 0)
265 		return rc;
266 
267 	return tmp & 0xffff;
268 }
269 
sja1105_base_tx_mdio_write(struct mii_bus * bus,int phy,int reg,u16 val)270 static int sja1105_base_tx_mdio_write(struct mii_bus *bus, int phy, int reg,
271 				      u16 val)
272 {
273 	struct sja1105_mdio_private *mdio_priv = bus->priv;
274 	struct sja1105_private *priv = mdio_priv->priv;
275 	const struct sja1105_regs *regs = priv->info->regs;
276 	u32 tmp = val;
277 
278 	if (reg & MII_ADDR_C45)
279 		return -EOPNOTSUPP;
280 
281 	return sja1105_xfer_u32(priv, SPI_WRITE, regs->mdio_100base_tx + reg,
282 				&tmp, NULL);
283 }
284 
sja1105_mdiobus_base_tx_register(struct sja1105_private * priv,struct device_node * mdio_node)285 static int sja1105_mdiobus_base_tx_register(struct sja1105_private *priv,
286 					    struct device_node *mdio_node)
287 {
288 	struct sja1105_mdio_private *mdio_priv;
289 	struct device_node *np;
290 	struct mii_bus *bus;
291 	int rc = 0;
292 
293 	np = of_get_compatible_child(mdio_node, "nxp,sja1110-base-tx-mdio");
294 	if (!np)
295 		return 0;
296 
297 	if (!of_device_is_available(np))
298 		goto out_put_np;
299 
300 	bus = mdiobus_alloc_size(sizeof(*mdio_priv));
301 	if (!bus) {
302 		rc = -ENOMEM;
303 		goto out_put_np;
304 	}
305 
306 	bus->name = "SJA1110 100base-TX MDIO bus";
307 	snprintf(bus->id, MII_BUS_ID_SIZE, "%s-base-tx",
308 		 dev_name(priv->ds->dev));
309 	bus->read = sja1105_base_tx_mdio_read;
310 	bus->write = sja1105_base_tx_mdio_write;
311 	bus->parent = priv->ds->dev;
312 	mdio_priv = bus->priv;
313 	mdio_priv->priv = priv;
314 
315 	rc = of_mdiobus_register(bus, np);
316 	if (rc) {
317 		mdiobus_free(bus);
318 		goto out_put_np;
319 	}
320 
321 	priv->mdio_base_tx = bus;
322 
323 out_put_np:
324 	of_node_put(np);
325 
326 	return rc;
327 }
328 
sja1105_mdiobus_base_tx_unregister(struct sja1105_private * priv)329 static void sja1105_mdiobus_base_tx_unregister(struct sja1105_private *priv)
330 {
331 	if (!priv->mdio_base_tx)
332 		return;
333 
334 	mdiobus_unregister(priv->mdio_base_tx);
335 	mdiobus_free(priv->mdio_base_tx);
336 	priv->mdio_base_tx = NULL;
337 }
338 
sja1105_mdiobus_base_t1_register(struct sja1105_private * priv,struct device_node * mdio_node)339 static int sja1105_mdiobus_base_t1_register(struct sja1105_private *priv,
340 					    struct device_node *mdio_node)
341 {
342 	struct sja1105_mdio_private *mdio_priv;
343 	struct device_node *np;
344 	struct mii_bus *bus;
345 	int rc = 0;
346 
347 	np = of_get_compatible_child(mdio_node, "nxp,sja1110-base-t1-mdio");
348 	if (!np)
349 		return 0;
350 
351 	if (!of_device_is_available(np))
352 		goto out_put_np;
353 
354 	bus = mdiobus_alloc_size(sizeof(*mdio_priv));
355 	if (!bus) {
356 		rc = -ENOMEM;
357 		goto out_put_np;
358 	}
359 
360 	bus->name = "SJA1110 100base-T1 MDIO bus";
361 	snprintf(bus->id, MII_BUS_ID_SIZE, "%s-base-t1",
362 		 dev_name(priv->ds->dev));
363 	bus->read = sja1105_base_t1_mdio_read;
364 	bus->write = sja1105_base_t1_mdio_write;
365 	bus->parent = priv->ds->dev;
366 	mdio_priv = bus->priv;
367 	mdio_priv->priv = priv;
368 
369 	rc = of_mdiobus_register(bus, np);
370 	if (rc) {
371 		mdiobus_free(bus);
372 		goto out_put_np;
373 	}
374 
375 	priv->mdio_base_t1 = bus;
376 
377 out_put_np:
378 	of_node_put(np);
379 
380 	return rc;
381 }
382 
sja1105_mdiobus_base_t1_unregister(struct sja1105_private * priv)383 static void sja1105_mdiobus_base_t1_unregister(struct sja1105_private *priv)
384 {
385 	if (!priv->mdio_base_t1)
386 		return;
387 
388 	mdiobus_unregister(priv->mdio_base_t1);
389 	mdiobus_free(priv->mdio_base_t1);
390 	priv->mdio_base_t1 = NULL;
391 }
392 
sja1105_mdiobus_pcs_register(struct sja1105_private * priv)393 static int sja1105_mdiobus_pcs_register(struct sja1105_private *priv)
394 {
395 	struct sja1105_mdio_private *mdio_priv;
396 	struct dsa_switch *ds = priv->ds;
397 	struct mii_bus *bus;
398 	int rc = 0;
399 	int port;
400 
401 	if (!priv->info->pcs_mdio_read || !priv->info->pcs_mdio_write)
402 		return 0;
403 
404 	bus = mdiobus_alloc_size(sizeof(*mdio_priv));
405 	if (!bus)
406 		return -ENOMEM;
407 
408 	bus->name = "SJA1105 PCS MDIO bus";
409 	snprintf(bus->id, MII_BUS_ID_SIZE, "%s-pcs",
410 		 dev_name(ds->dev));
411 	bus->read = priv->info->pcs_mdio_read;
412 	bus->write = priv->info->pcs_mdio_write;
413 	bus->parent = ds->dev;
414 	/* There is no PHY on this MDIO bus => mask out all PHY addresses
415 	 * from auto probing.
416 	 */
417 	bus->phy_mask = ~0;
418 	mdio_priv = bus->priv;
419 	mdio_priv->priv = priv;
420 
421 	rc = mdiobus_register(bus);
422 	if (rc) {
423 		mdiobus_free(bus);
424 		return rc;
425 	}
426 
427 	for (port = 0; port < ds->num_ports; port++) {
428 		struct mdio_device *mdiodev;
429 		struct dw_xpcs *xpcs;
430 
431 		if (dsa_is_unused_port(ds, port))
432 			continue;
433 
434 		if (priv->phy_mode[port] != PHY_INTERFACE_MODE_SGMII &&
435 		    priv->phy_mode[port] != PHY_INTERFACE_MODE_2500BASEX)
436 			continue;
437 
438 		mdiodev = mdio_device_create(bus, port);
439 		if (IS_ERR(mdiodev)) {
440 			rc = PTR_ERR(mdiodev);
441 			goto out_pcs_free;
442 		}
443 
444 		xpcs = xpcs_create(mdiodev, priv->phy_mode[port]);
445 		if (IS_ERR(xpcs)) {
446 			rc = PTR_ERR(xpcs);
447 			goto out_pcs_free;
448 		}
449 
450 		priv->xpcs[port] = xpcs;
451 	}
452 
453 	priv->mdio_pcs = bus;
454 
455 	return 0;
456 
457 out_pcs_free:
458 	for (port = 0; port < ds->num_ports; port++) {
459 		if (!priv->xpcs[port])
460 			continue;
461 
462 		mdio_device_free(priv->xpcs[port]->mdiodev);
463 		xpcs_destroy(priv->xpcs[port]);
464 		priv->xpcs[port] = NULL;
465 	}
466 
467 	mdiobus_unregister(bus);
468 	mdiobus_free(bus);
469 
470 	return rc;
471 }
472 
sja1105_mdiobus_pcs_unregister(struct sja1105_private * priv)473 static void sja1105_mdiobus_pcs_unregister(struct sja1105_private *priv)
474 {
475 	struct dsa_switch *ds = priv->ds;
476 	int port;
477 
478 	if (!priv->mdio_pcs)
479 		return;
480 
481 	for (port = 0; port < ds->num_ports; port++) {
482 		if (!priv->xpcs[port])
483 			continue;
484 
485 		mdio_device_free(priv->xpcs[port]->mdiodev);
486 		xpcs_destroy(priv->xpcs[port]);
487 		priv->xpcs[port] = NULL;
488 	}
489 
490 	mdiobus_unregister(priv->mdio_pcs);
491 	mdiobus_free(priv->mdio_pcs);
492 	priv->mdio_pcs = NULL;
493 }
494 
sja1105_mdiobus_register(struct dsa_switch * ds)495 int sja1105_mdiobus_register(struct dsa_switch *ds)
496 {
497 	struct sja1105_private *priv = ds->priv;
498 	const struct sja1105_regs *regs = priv->info->regs;
499 	struct device_node *switch_node = ds->dev->of_node;
500 	struct device_node *mdio_node;
501 	int rc;
502 
503 	rc = sja1105_mdiobus_pcs_register(priv);
504 	if (rc)
505 		return rc;
506 
507 	mdio_node = of_get_child_by_name(switch_node, "mdios");
508 	if (!mdio_node)
509 		return 0;
510 
511 	if (!of_device_is_available(mdio_node))
512 		goto out_put_mdio_node;
513 
514 	if (regs->mdio_100base_tx != SJA1105_RSV_ADDR) {
515 		rc = sja1105_mdiobus_base_tx_register(priv, mdio_node);
516 		if (rc)
517 			goto err_put_mdio_node;
518 	}
519 
520 	if (regs->mdio_100base_t1 != SJA1105_RSV_ADDR) {
521 		rc = sja1105_mdiobus_base_t1_register(priv, mdio_node);
522 		if (rc)
523 			goto err_free_base_tx_mdiobus;
524 	}
525 
526 out_put_mdio_node:
527 	of_node_put(mdio_node);
528 
529 	return 0;
530 
531 err_free_base_tx_mdiobus:
532 	sja1105_mdiobus_base_tx_unregister(priv);
533 err_put_mdio_node:
534 	of_node_put(mdio_node);
535 	sja1105_mdiobus_pcs_unregister(priv);
536 
537 	return rc;
538 }
539 
sja1105_mdiobus_unregister(struct dsa_switch * ds)540 void sja1105_mdiobus_unregister(struct dsa_switch *ds)
541 {
542 	struct sja1105_private *priv = ds->priv;
543 
544 	sja1105_mdiobus_base_t1_unregister(priv);
545 	sja1105_mdiobus_base_tx_unregister(priv);
546 	sja1105_mdiobus_pcs_unregister(priv);
547 }
548