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