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
10int 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
35int 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
52int 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
97int 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
136enum 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
143static 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
152static 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
169static 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
193static 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
208static 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
230static 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
246static 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
258static 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
296out_put_np:
297	of_node_put(np);
298
299	return rc;
300}
301
302static 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
312static 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
352out_put_np:
353	of_node_put(np);
354
355	return rc;
356}
357
358static 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
368static 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
425out_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
440static 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
461int 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
492out_put_mdio_node:
493	of_node_put(mdio_node);
494
495	return 0;
496
497err_free_base_tx_mdiobus:
498	sja1105_mdiobus_base_tx_unregister(priv);
499err_put_mdio_node:
500	of_node_put(mdio_node);
501	sja1105_mdiobus_pcs_unregister(priv);
502
503	return rc;
504}
505
506void 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