1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Marvell 88x2222 dual-port multi-speed ethernet transceiver.
4  *
5  * Supports:
6  *	XAUI on the host side.
7  *	1000Base-X or 10GBase-R on the line side.
8  *	SGMII over 1000Base-X.
9  */
10 #include <linux/module.h>
11 #include <linux/phy.h>
12 #include <linux/gpio.h>
13 #include <linux/delay.h>
14 #include <linux/mdio.h>
15 #include <linux/marvell_phy.h>
16 #include <linux/of.h>
17 #include <linux/of_device.h>
18 #include <linux/of_gpio.h>
19 #include <linux/sfp.h>
20 #include <linux/netdevice.h>
21 
22 /* Port PCS Configuration */
23 #define	MV_PCS_CONFIG		0xF002
24 #define	MV_PCS_HOST_XAUI	0x73
25 #define	MV_PCS_LINE_10GBR	(0x71 << 8)
26 #define	MV_PCS_LINE_1GBX_AN	(0x7B << 8)
27 #define	MV_PCS_LINE_SGMII_AN	(0x7F << 8)
28 
29 /* Port Reset and Power Down */
30 #define	MV_PORT_RST	0xF003
31 #define	MV_LINE_RST_SW	BIT(15)
32 #define	MV_HOST_RST_SW	BIT(7)
33 #define	MV_PORT_RST_SW	(MV_LINE_RST_SW | MV_HOST_RST_SW)
34 
35 /* PMD Receive Signal Detect */
36 #define	MV_RX_SIGNAL_DETECT		0x000A
37 #define	MV_RX_SIGNAL_DETECT_GLOBAL	BIT(0)
38 
39 /* 1000Base-X/SGMII Control Register */
40 #define	MV_1GBX_CTRL		(0x2000 + MII_BMCR)
41 
42 /* 1000BASE-X/SGMII Status Register */
43 #define	MV_1GBX_STAT		(0x2000 + MII_BMSR)
44 
45 /* 1000Base-X Auto-Negotiation Advertisement Register */
46 #define	MV_1GBX_ADVERTISE	(0x2000 + MII_ADVERTISE)
47 
48 /* 1000Base-X PHY Specific Status Register */
49 #define	MV_1GBX_PHY_STAT		0xA003
50 #define	MV_1GBX_PHY_STAT_AN_RESOLVED	BIT(11)
51 #define	MV_1GBX_PHY_STAT_DUPLEX		BIT(13)
52 #define	MV_1GBX_PHY_STAT_SPEED100	BIT(14)
53 #define	MV_1GBX_PHY_STAT_SPEED1000	BIT(15)
54 
55 struct mv2222_data {
56 	phy_interface_t line_interface;
57 	__ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
58 	bool sfp_link;
59 };
60 
61 /* SFI PMA transmit enable */
62 static int mv2222_tx_enable(struct phy_device *phydev)
63 {
64 	return phy_clear_bits_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_TXDIS,
65 				  MDIO_PMD_TXDIS_GLOBAL);
66 }
67 
68 /* SFI PMA transmit disable */
69 static int mv2222_tx_disable(struct phy_device *phydev)
70 {
71 	return phy_set_bits_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_TXDIS,
72 				MDIO_PMD_TXDIS_GLOBAL);
73 }
74 
75 static int mv2222_soft_reset(struct phy_device *phydev)
76 {
77 	int val, ret;
78 
79 	ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, MV_PORT_RST,
80 			    MV_PORT_RST_SW);
81 	if (ret < 0)
82 		return ret;
83 
84 	return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND2, MV_PORT_RST,
85 					 val, !(val & MV_PORT_RST_SW),
86 					 5000, 1000000, true);
87 }
88 
89 /* Returns negative on error, 0 if link is down, 1 if link is up */
90 static int mv2222_read_status_10g(struct phy_device *phydev)
91 {
92 	int val, link = 0;
93 
94 	val = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_STAT1);
95 	if (val < 0)
96 		return val;
97 
98 	if (val & MDIO_STAT1_LSTATUS) {
99 		link = 1;
100 
101 		/* 10GBASE-R do not support auto-negotiation */
102 		phydev->autoneg = AUTONEG_DISABLE;
103 		phydev->speed = SPEED_10000;
104 		phydev->duplex = DUPLEX_FULL;
105 	}
106 
107 	return link;
108 }
109 
110 /* Returns negative on error, 0 if link is down, 1 if link is up */
111 static int mv2222_read_status_1g(struct phy_device *phydev)
112 {
113 	int val, link = 0;
114 
115 	val = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_1GBX_STAT);
116 	if (val < 0)
117 		return val;
118 
119 	if (!(val & BMSR_LSTATUS) ||
120 	    (phydev->autoneg == AUTONEG_ENABLE &&
121 	     !(val & BMSR_ANEGCOMPLETE)))
122 		return 0;
123 
124 	link = 1;
125 
126 	val = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_1GBX_PHY_STAT);
127 	if (val < 0)
128 		return val;
129 
130 	if (val & MV_1GBX_PHY_STAT_AN_RESOLVED) {
131 		if (val & MV_1GBX_PHY_STAT_DUPLEX)
132 			phydev->duplex = DUPLEX_FULL;
133 		else
134 			phydev->duplex = DUPLEX_HALF;
135 
136 		if (val & MV_1GBX_PHY_STAT_SPEED1000)
137 			phydev->speed = SPEED_1000;
138 		else if (val & MV_1GBX_PHY_STAT_SPEED100)
139 			phydev->speed = SPEED_100;
140 		else
141 			phydev->speed = SPEED_10;
142 	}
143 
144 	return link;
145 }
146 
147 static bool mv2222_link_is_operational(struct phy_device *phydev)
148 {
149 	struct mv2222_data *priv = phydev->priv;
150 	int val;
151 
152 	val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MV_RX_SIGNAL_DETECT);
153 	if (val < 0 || !(val & MV_RX_SIGNAL_DETECT_GLOBAL))
154 		return false;
155 
156 	if (phydev->sfp_bus && !priv->sfp_link)
157 		return false;
158 
159 	return true;
160 }
161 
162 static int mv2222_read_status(struct phy_device *phydev)
163 {
164 	struct mv2222_data *priv = phydev->priv;
165 	int link;
166 
167 	phydev->link = 0;
168 	phydev->speed = SPEED_UNKNOWN;
169 	phydev->duplex = DUPLEX_UNKNOWN;
170 
171 	if (!mv2222_link_is_operational(phydev))
172 		return 0;
173 
174 	if (priv->line_interface == PHY_INTERFACE_MODE_10GBASER)
175 		link = mv2222_read_status_10g(phydev);
176 	else
177 		link = mv2222_read_status_1g(phydev);
178 
179 	if (link < 0)
180 		return link;
181 
182 	phydev->link = link;
183 
184 	return 0;
185 }
186 
187 static int mv2222_disable_aneg(struct phy_device *phydev)
188 {
189 	int ret = phy_clear_bits_mmd(phydev, MDIO_MMD_PCS, MV_1GBX_CTRL,
190 				     BMCR_ANENABLE | BMCR_ANRESTART);
191 	if (ret < 0)
192 		return ret;
193 
194 	return mv2222_soft_reset(phydev);
195 }
196 
197 static int mv2222_enable_aneg(struct phy_device *phydev)
198 {
199 	int ret = phy_set_bits_mmd(phydev, MDIO_MMD_PCS, MV_1GBX_CTRL,
200 				   BMCR_ANENABLE | BMCR_RESET);
201 	if (ret < 0)
202 		return ret;
203 
204 	return mv2222_soft_reset(phydev);
205 }
206 
207 static int mv2222_set_sgmii_speed(struct phy_device *phydev)
208 {
209 	struct mv2222_data *priv = phydev->priv;
210 
211 	switch (phydev->speed) {
212 	default:
213 	case SPEED_1000:
214 		if ((linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
215 				       priv->supported) ||
216 		     linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
217 				       priv->supported)))
218 			return phy_modify_mmd(phydev, MDIO_MMD_PCS,
219 					      MV_1GBX_CTRL,
220 					      BMCR_SPEED1000 | BMCR_SPEED100,
221 					      BMCR_SPEED1000);
222 
223 		fallthrough;
224 	case SPEED_100:
225 		if ((linkmode_test_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
226 				       priv->supported) ||
227 		     linkmode_test_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT,
228 				       priv->supported)))
229 			return phy_modify_mmd(phydev, MDIO_MMD_PCS,
230 					      MV_1GBX_CTRL,
231 					      BMCR_SPEED1000 | BMCR_SPEED100,
232 					      BMCR_SPEED100);
233 		fallthrough;
234 	case SPEED_10:
235 		if ((linkmode_test_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT,
236 				       priv->supported) ||
237 		     linkmode_test_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT,
238 				       priv->supported)))
239 			return phy_modify_mmd(phydev, MDIO_MMD_PCS,
240 					      MV_1GBX_CTRL,
241 					      BMCR_SPEED1000 | BMCR_SPEED100,
242 					      BMCR_SPEED10);
243 
244 		return -EINVAL;
245 	}
246 }
247 
248 static bool mv2222_is_10g_capable(struct phy_device *phydev)
249 {
250 	struct mv2222_data *priv = phydev->priv;
251 
252 	return (linkmode_test_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
253 				  priv->supported) ||
254 		linkmode_test_bit(ETHTOOL_LINK_MODE_10000baseCR_Full_BIT,
255 				  priv->supported) ||
256 		linkmode_test_bit(ETHTOOL_LINK_MODE_10000baseSR_Full_BIT,
257 				  priv->supported) ||
258 		linkmode_test_bit(ETHTOOL_LINK_MODE_10000baseLR_Full_BIT,
259 				  priv->supported) ||
260 		linkmode_test_bit(ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT,
261 				  priv->supported) ||
262 		linkmode_test_bit(ETHTOOL_LINK_MODE_10000baseER_Full_BIT,
263 				  priv->supported));
264 }
265 
266 static bool mv2222_is_1gbx_capable(struct phy_device *phydev)
267 {
268 	struct mv2222_data *priv = phydev->priv;
269 
270 	return linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
271 				 priv->supported);
272 }
273 
274 static int mv2222_config_line(struct phy_device *phydev)
275 {
276 	struct mv2222_data *priv = phydev->priv;
277 
278 	switch (priv->line_interface) {
279 	case PHY_INTERFACE_MODE_10GBASER:
280 		return phy_write_mmd(phydev, MDIO_MMD_VEND2, MV_PCS_CONFIG,
281 				     MV_PCS_HOST_XAUI | MV_PCS_LINE_10GBR);
282 	case PHY_INTERFACE_MODE_1000BASEX:
283 		return phy_write_mmd(phydev, MDIO_MMD_VEND2, MV_PCS_CONFIG,
284 				     MV_PCS_HOST_XAUI | MV_PCS_LINE_1GBX_AN);
285 	case PHY_INTERFACE_MODE_SGMII:
286 		return phy_write_mmd(phydev, MDIO_MMD_VEND2, MV_PCS_CONFIG,
287 				     MV_PCS_HOST_XAUI | MV_PCS_LINE_SGMII_AN);
288 	default:
289 		return -EINVAL;
290 	}
291 }
292 
293 static int mv2222_setup_forced(struct phy_device *phydev)
294 {
295 	struct mv2222_data *priv = phydev->priv;
296 	bool changed = false;
297 	int ret;
298 
299 	switch (priv->line_interface) {
300 	case PHY_INTERFACE_MODE_10GBASER:
301 		if (phydev->speed == SPEED_1000 &&
302 		    mv2222_is_1gbx_capable(phydev)) {
303 			priv->line_interface = PHY_INTERFACE_MODE_1000BASEX;
304 			changed = true;
305 		}
306 
307 		break;
308 	case PHY_INTERFACE_MODE_1000BASEX:
309 		if (phydev->speed == SPEED_10000 &&
310 		    mv2222_is_10g_capable(phydev)) {
311 			priv->line_interface = PHY_INTERFACE_MODE_10GBASER;
312 			changed = true;
313 		}
314 
315 		break;
316 	case PHY_INTERFACE_MODE_SGMII:
317 		ret = mv2222_set_sgmii_speed(phydev);
318 		if (ret < 0)
319 			return ret;
320 
321 		break;
322 	default:
323 		return -EINVAL;
324 	}
325 
326 	if (changed) {
327 		ret = mv2222_config_line(phydev);
328 		if (ret < 0)
329 			return ret;
330 	}
331 
332 	return mv2222_disable_aneg(phydev);
333 }
334 
335 static int mv2222_config_aneg(struct phy_device *phydev)
336 {
337 	struct mv2222_data *priv = phydev->priv;
338 	int ret, adv;
339 
340 	/* SFP is not present, do nothing */
341 	if (priv->line_interface == PHY_INTERFACE_MODE_NA)
342 		return 0;
343 
344 	if (phydev->autoneg == AUTONEG_DISABLE ||
345 	    phydev->speed == SPEED_10000)
346 		return mv2222_setup_forced(phydev);
347 
348 	if (priv->line_interface == PHY_INTERFACE_MODE_10GBASER &&
349 	    mv2222_is_1gbx_capable(phydev)) {
350 		priv->line_interface = PHY_INTERFACE_MODE_1000BASEX;
351 		ret = mv2222_config_line(phydev);
352 		if (ret < 0)
353 			return ret;
354 	}
355 
356 	adv = linkmode_adv_to_mii_adv_x(priv->supported,
357 					ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
358 
359 	ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, MV_1GBX_ADVERTISE,
360 			     ADVERTISE_1000XFULL |
361 			     ADVERTISE_1000XPAUSE | ADVERTISE_1000XPSE_ASYM,
362 			     adv);
363 	if (ret < 0)
364 		return ret;
365 
366 	return mv2222_enable_aneg(phydev);
367 }
368 
369 static int mv2222_aneg_done(struct phy_device *phydev)
370 {
371 	int ret;
372 
373 	if (mv2222_is_10g_capable(phydev)) {
374 		ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_STAT1);
375 		if (ret < 0)
376 			return ret;
377 
378 		if (ret & MDIO_STAT1_LSTATUS)
379 			return 1;
380 	}
381 
382 	ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_1GBX_STAT);
383 	if (ret < 0)
384 		return ret;
385 
386 	return (ret & BMSR_ANEGCOMPLETE);
387 }
388 
389 static int mv2222_resume(struct phy_device *phydev)
390 {
391 	return mv2222_tx_enable(phydev);
392 }
393 
394 static int mv2222_suspend(struct phy_device *phydev)
395 {
396 	return mv2222_tx_disable(phydev);
397 }
398 
399 static int mv2222_get_features(struct phy_device *phydev)
400 {
401 	/* All supported linkmodes are set at probe */
402 
403 	return 0;
404 }
405 
406 static int mv2222_config_init(struct phy_device *phydev)
407 {
408 	if (phydev->interface != PHY_INTERFACE_MODE_XAUI)
409 		return -EINVAL;
410 
411 	phydev->autoneg = AUTONEG_DISABLE;
412 
413 	return 0;
414 }
415 
416 static int mv2222_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
417 {
418 	struct phy_device *phydev = upstream;
419 	phy_interface_t sfp_interface;
420 	struct mv2222_data *priv;
421 	struct device *dev;
422 	int ret;
423 
424 	__ETHTOOL_DECLARE_LINK_MODE_MASK(sfp_supported) = { 0, };
425 
426 	priv = (struct mv2222_data *)phydev->priv;
427 	dev = &phydev->mdio.dev;
428 
429 	sfp_parse_support(phydev->sfp_bus, id, sfp_supported);
430 	sfp_interface = sfp_select_interface(phydev->sfp_bus, sfp_supported);
431 
432 	dev_info(dev, "%s SFP module inserted\n", phy_modes(sfp_interface));
433 
434 	if (sfp_interface != PHY_INTERFACE_MODE_10GBASER &&
435 	    sfp_interface != PHY_INTERFACE_MODE_1000BASEX &&
436 	    sfp_interface != PHY_INTERFACE_MODE_SGMII) {
437 		dev_err(dev, "Incompatible SFP module inserted\n");
438 
439 		return -EINVAL;
440 	}
441 
442 	priv->line_interface = sfp_interface;
443 	linkmode_and(priv->supported, phydev->supported, sfp_supported);
444 
445 	ret = mv2222_config_line(phydev);
446 	if (ret < 0)
447 		return ret;
448 
449 	if (mutex_trylock(&phydev->lock)) {
450 		if (priv->line_interface == PHY_INTERFACE_MODE_10GBASER)
451 			ret = mv2222_setup_forced(phydev);
452 		else
453 			ret = mv2222_config_aneg(phydev);
454 
455 		mutex_unlock(&phydev->lock);
456 	}
457 
458 	return ret;
459 }
460 
461 static void mv2222_sfp_remove(void *upstream)
462 {
463 	struct phy_device *phydev = upstream;
464 	struct mv2222_data *priv;
465 
466 	priv = (struct mv2222_data *)phydev->priv;
467 
468 	priv->line_interface = PHY_INTERFACE_MODE_NA;
469 	linkmode_zero(priv->supported);
470 }
471 
472 static void mv2222_sfp_link_up(void *upstream)
473 {
474 	struct phy_device *phydev = upstream;
475 	struct mv2222_data *priv;
476 
477 	priv = phydev->priv;
478 	priv->sfp_link = true;
479 }
480 
481 static void mv2222_sfp_link_down(void *upstream)
482 {
483 	struct phy_device *phydev = upstream;
484 	struct mv2222_data *priv;
485 
486 	priv = phydev->priv;
487 	priv->sfp_link = false;
488 }
489 
490 static const struct sfp_upstream_ops sfp_phy_ops = {
491 	.module_insert = mv2222_sfp_insert,
492 	.module_remove = mv2222_sfp_remove,
493 	.link_up = mv2222_sfp_link_up,
494 	.link_down = mv2222_sfp_link_down,
495 	.attach = phy_sfp_attach,
496 	.detach = phy_sfp_detach,
497 };
498 
499 static int mv2222_probe(struct phy_device *phydev)
500 {
501 	struct device *dev = &phydev->mdio.dev;
502 	struct mv2222_data *priv = NULL;
503 
504 	__ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, };
505 
506 	linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, supported);
507 	linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, supported);
508 	linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, supported);
509 	linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, supported);
510 	linkmode_set_bit(ETHTOOL_LINK_MODE_TP_BIT, supported);
511 	linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, supported);
512 	linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, supported);
513 	linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, supported);
514 	linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, supported);
515 	linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, supported);
516 	linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, supported);
517 	linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, supported);
518 	linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT, supported);
519 	linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseCR_Full_BIT, supported);
520 	linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseSR_Full_BIT, supported);
521 	linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseLR_Full_BIT, supported);
522 	linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT, supported);
523 	linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseER_Full_BIT, supported);
524 
525 	linkmode_copy(phydev->supported, supported);
526 
527 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
528 	if (!priv)
529 		return -ENOMEM;
530 
531 	priv->line_interface = PHY_INTERFACE_MODE_NA;
532 	phydev->priv = priv;
533 
534 	return phy_sfp_probe(phydev, &sfp_phy_ops);
535 }
536 
537 static struct phy_driver mv2222_drivers[] = {
538 	{
539 		.phy_id = MARVELL_PHY_ID_88X2222,
540 		.phy_id_mask = MARVELL_PHY_ID_MASK,
541 		.name = "Marvell 88X2222",
542 		.get_features = mv2222_get_features,
543 		.soft_reset = mv2222_soft_reset,
544 		.config_init = mv2222_config_init,
545 		.config_aneg = mv2222_config_aneg,
546 		.aneg_done = mv2222_aneg_done,
547 		.probe = mv2222_probe,
548 		.suspend = mv2222_suspend,
549 		.resume = mv2222_resume,
550 		.read_status = mv2222_read_status,
551 	},
552 };
553 module_phy_driver(mv2222_drivers);
554 
555 static struct mdio_device_id __maybe_unused mv2222_tbl[] = {
556 	{ MARVELL_PHY_ID_88X2222, MARVELL_PHY_ID_MASK },
557 	{ }
558 };
559 MODULE_DEVICE_TABLE(mdio, mv2222_tbl);
560 
561 MODULE_DESCRIPTION("Marvell 88x2222 ethernet transceiver driver");
562 MODULE_LICENSE("GPL");
563