xref: /linux/drivers/net/pcs/pcs-xpcs.c (revision 3ed8d344e061f382069c27705543c1882aca468a)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2020 Synopsys, Inc. and/or its affiliates.
4  * Synopsys DesignWare XPCS helpers
5  *
6  * Author: Jose Abreu <Jose.Abreu@synopsys.com>
7  */
8 
9 #include <linux/clk.h>
10 #include <linux/delay.h>
11 #include <linux/pcs/pcs-xpcs.h>
12 #include <linux/mdio.h>
13 #include <linux/phy.h>
14 #include <linux/phylink.h>
15 #include <linux/property.h>
16 
17 #include "pcs-xpcs.h"
18 
19 #define phylink_pcs_to_xpcs(pl_pcs) \
20 	container_of((pl_pcs), struct dw_xpcs, pcs)
21 
22 static const int xpcs_usxgmii_features[] = {
23 	ETHTOOL_LINK_MODE_Pause_BIT,
24 	ETHTOOL_LINK_MODE_Asym_Pause_BIT,
25 	ETHTOOL_LINK_MODE_Autoneg_BIT,
26 	ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
27 	ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
28 	ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
29 	ETHTOOL_LINK_MODE_2500baseX_Full_BIT,
30 	__ETHTOOL_LINK_MODE_MASK_NBITS,
31 };
32 
33 static const int xpcs_10gkr_features[] = {
34 	ETHTOOL_LINK_MODE_Pause_BIT,
35 	ETHTOOL_LINK_MODE_Asym_Pause_BIT,
36 	ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
37 	__ETHTOOL_LINK_MODE_MASK_NBITS,
38 };
39 
40 static const int xpcs_xlgmii_features[] = {
41 	ETHTOOL_LINK_MODE_Pause_BIT,
42 	ETHTOOL_LINK_MODE_Asym_Pause_BIT,
43 	ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
44 	ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
45 	ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
46 	ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
47 	ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT,
48 	ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT,
49 	ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT,
50 	ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT,
51 	ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT,
52 	ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT,
53 	ETHTOOL_LINK_MODE_50000baseKR_Full_BIT,
54 	ETHTOOL_LINK_MODE_50000baseSR_Full_BIT,
55 	ETHTOOL_LINK_MODE_50000baseCR_Full_BIT,
56 	ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT,
57 	ETHTOOL_LINK_MODE_50000baseDR_Full_BIT,
58 	ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
59 	ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT,
60 	ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
61 	ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT,
62 	ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT,
63 	ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT,
64 	ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT,
65 	ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT,
66 	ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT,
67 	__ETHTOOL_LINK_MODE_MASK_NBITS,
68 };
69 
70 static const int xpcs_10gbaser_features[] = {
71 	ETHTOOL_LINK_MODE_Pause_BIT,
72 	ETHTOOL_LINK_MODE_Asym_Pause_BIT,
73 	ETHTOOL_LINK_MODE_10000baseSR_Full_BIT,
74 	ETHTOOL_LINK_MODE_10000baseLR_Full_BIT,
75 	ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT,
76 	ETHTOOL_LINK_MODE_10000baseER_Full_BIT,
77 	__ETHTOOL_LINK_MODE_MASK_NBITS,
78 };
79 
80 static const int xpcs_sgmii_features[] = {
81 	ETHTOOL_LINK_MODE_Pause_BIT,
82 	ETHTOOL_LINK_MODE_Asym_Pause_BIT,
83 	ETHTOOL_LINK_MODE_Autoneg_BIT,
84 	ETHTOOL_LINK_MODE_10baseT_Half_BIT,
85 	ETHTOOL_LINK_MODE_10baseT_Full_BIT,
86 	ETHTOOL_LINK_MODE_100baseT_Half_BIT,
87 	ETHTOOL_LINK_MODE_100baseT_Full_BIT,
88 	ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
89 	ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
90 	__ETHTOOL_LINK_MODE_MASK_NBITS,
91 };
92 
93 static const int xpcs_1000basex_features[] = {
94 	ETHTOOL_LINK_MODE_Pause_BIT,
95 	ETHTOOL_LINK_MODE_Asym_Pause_BIT,
96 	ETHTOOL_LINK_MODE_Autoneg_BIT,
97 	ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
98 	__ETHTOOL_LINK_MODE_MASK_NBITS,
99 };
100 
101 static const int xpcs_2500basex_features[] = {
102 	ETHTOOL_LINK_MODE_Pause_BIT,
103 	ETHTOOL_LINK_MODE_Asym_Pause_BIT,
104 	ETHTOOL_LINK_MODE_Autoneg_BIT,
105 	ETHTOOL_LINK_MODE_2500baseX_Full_BIT,
106 	ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
107 	__ETHTOOL_LINK_MODE_MASK_NBITS,
108 };
109 
110 static const phy_interface_t xpcs_usxgmii_interfaces[] = {
111 	PHY_INTERFACE_MODE_USXGMII,
112 };
113 
114 static const phy_interface_t xpcs_10gkr_interfaces[] = {
115 	PHY_INTERFACE_MODE_10GKR,
116 };
117 
118 static const phy_interface_t xpcs_xlgmii_interfaces[] = {
119 	PHY_INTERFACE_MODE_XLGMII,
120 };
121 
122 static const phy_interface_t xpcs_10gbaser_interfaces[] = {
123 	PHY_INTERFACE_MODE_10GBASER,
124 };
125 
126 static const phy_interface_t xpcs_sgmii_interfaces[] = {
127 	PHY_INTERFACE_MODE_SGMII,
128 };
129 
130 static const phy_interface_t xpcs_1000basex_interfaces[] = {
131 	PHY_INTERFACE_MODE_1000BASEX,
132 };
133 
134 static const phy_interface_t xpcs_2500basex_interfaces[] = {
135 	PHY_INTERFACE_MODE_2500BASEX,
136 };
137 
138 enum {
139 	DW_XPCS_USXGMII,
140 	DW_XPCS_10GKR,
141 	DW_XPCS_XLGMII,
142 	DW_XPCS_10GBASER,
143 	DW_XPCS_SGMII,
144 	DW_XPCS_1000BASEX,
145 	DW_XPCS_2500BASEX,
146 	DW_XPCS_INTERFACE_MAX,
147 };
148 
149 struct dw_xpcs_compat {
150 	const int *supported;
151 	const phy_interface_t *interface;
152 	int num_interfaces;
153 	int an_mode;
154 	int (*pma_config)(struct dw_xpcs *xpcs);
155 };
156 
157 struct dw_xpcs_desc {
158 	u32 id;
159 	u32 mask;
160 	const struct dw_xpcs_compat *compat;
161 };
162 
163 static const struct dw_xpcs_compat *
164 xpcs_find_compat(const struct dw_xpcs_desc *desc, phy_interface_t interface)
165 {
166 	int i, j;
167 
168 	for (i = 0; i < DW_XPCS_INTERFACE_MAX; i++) {
169 		const struct dw_xpcs_compat *compat = &desc->compat[i];
170 
171 		for (j = 0; j < compat->num_interfaces; j++)
172 			if (compat->interface[j] == interface)
173 				return compat;
174 	}
175 
176 	return NULL;
177 }
178 
179 int xpcs_get_an_mode(struct dw_xpcs *xpcs, phy_interface_t interface)
180 {
181 	const struct dw_xpcs_compat *compat;
182 
183 	compat = xpcs_find_compat(xpcs->desc, interface);
184 	if (!compat)
185 		return -ENODEV;
186 
187 	return compat->an_mode;
188 }
189 EXPORT_SYMBOL_GPL(xpcs_get_an_mode);
190 
191 static bool __xpcs_linkmode_supported(const struct dw_xpcs_compat *compat,
192 				      enum ethtool_link_mode_bit_indices linkmode)
193 {
194 	int i;
195 
196 	for (i = 0; compat->supported[i] != __ETHTOOL_LINK_MODE_MASK_NBITS; i++)
197 		if (compat->supported[i] == linkmode)
198 			return true;
199 
200 	return false;
201 }
202 
203 #define xpcs_linkmode_supported(compat, mode) \
204 	__xpcs_linkmode_supported(compat, ETHTOOL_LINK_MODE_ ## mode ## _BIT)
205 
206 int xpcs_read(struct dw_xpcs *xpcs, int dev, u32 reg)
207 {
208 	return mdiodev_c45_read(xpcs->mdiodev, dev, reg);
209 }
210 
211 int xpcs_write(struct dw_xpcs *xpcs, int dev, u32 reg, u16 val)
212 {
213 	return mdiodev_c45_write(xpcs->mdiodev, dev, reg, val);
214 }
215 
216 static int xpcs_modify_changed(struct dw_xpcs *xpcs, int dev, u32 reg,
217 			       u16 mask, u16 set)
218 {
219 	return mdiodev_c45_modify_changed(xpcs->mdiodev, dev, reg, mask, set);
220 }
221 
222 static int xpcs_read_vendor(struct dw_xpcs *xpcs, int dev, u32 reg)
223 {
224 	return xpcs_read(xpcs, dev, DW_VENDOR | reg);
225 }
226 
227 static int xpcs_write_vendor(struct dw_xpcs *xpcs, int dev, int reg,
228 			     u16 val)
229 {
230 	return xpcs_write(xpcs, dev, DW_VENDOR | reg, val);
231 }
232 
233 int xpcs_read_vpcs(struct dw_xpcs *xpcs, int reg)
234 {
235 	return xpcs_read_vendor(xpcs, MDIO_MMD_PCS, reg);
236 }
237 
238 int xpcs_write_vpcs(struct dw_xpcs *xpcs, int reg, u16 val)
239 {
240 	return xpcs_write_vendor(xpcs, MDIO_MMD_PCS, reg, val);
241 }
242 
243 static int xpcs_poll_reset(struct dw_xpcs *xpcs, int dev)
244 {
245 	/* Poll until the reset bit clears (50ms per retry == 0.6 sec) */
246 	unsigned int retries = 12;
247 	int ret;
248 
249 	do {
250 		msleep(50);
251 		ret = xpcs_read(xpcs, dev, MDIO_CTRL1);
252 		if (ret < 0)
253 			return ret;
254 	} while (ret & MDIO_CTRL1_RESET && --retries);
255 
256 	return (ret & MDIO_CTRL1_RESET) ? -ETIMEDOUT : 0;
257 }
258 
259 static int xpcs_soft_reset(struct dw_xpcs *xpcs,
260 			   const struct dw_xpcs_compat *compat)
261 {
262 	int ret, dev;
263 
264 	switch (compat->an_mode) {
265 	case DW_AN_C73:
266 	case DW_10GBASER:
267 		dev = MDIO_MMD_PCS;
268 		break;
269 	case DW_AN_C37_SGMII:
270 	case DW_2500BASEX:
271 	case DW_AN_C37_1000BASEX:
272 		dev = MDIO_MMD_VEND2;
273 		break;
274 	default:
275 		return -EINVAL;
276 	}
277 
278 	ret = xpcs_write(xpcs, dev, MDIO_CTRL1, MDIO_CTRL1_RESET);
279 	if (ret < 0)
280 		return ret;
281 
282 	return xpcs_poll_reset(xpcs, dev);
283 }
284 
285 #define xpcs_warn(__xpcs, __state, __args...) \
286 ({ \
287 	if ((__state)->link) \
288 		dev_warn(&(__xpcs)->mdiodev->dev, ##__args); \
289 })
290 
291 static int xpcs_read_fault_c73(struct dw_xpcs *xpcs,
292 			       struct phylink_link_state *state,
293 			       u16 pcs_stat1)
294 {
295 	int ret;
296 
297 	if (pcs_stat1 & MDIO_STAT1_FAULT) {
298 		xpcs_warn(xpcs, state, "Link fault condition detected!\n");
299 		return -EFAULT;
300 	}
301 
302 	ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_STAT2);
303 	if (ret < 0)
304 		return ret;
305 
306 	if (ret & MDIO_STAT2_RXFAULT)
307 		xpcs_warn(xpcs, state, "Receiver fault detected!\n");
308 	if (ret & MDIO_STAT2_TXFAULT)
309 		xpcs_warn(xpcs, state, "Transmitter fault detected!\n");
310 
311 	ret = xpcs_read_vendor(xpcs, MDIO_MMD_PCS, DW_VR_XS_PCS_DIG_STS);
312 	if (ret < 0)
313 		return ret;
314 
315 	if (ret & DW_RXFIFO_ERR) {
316 		xpcs_warn(xpcs, state, "FIFO fault condition detected!\n");
317 		return -EFAULT;
318 	}
319 
320 	ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_PCS_10GBRT_STAT1);
321 	if (ret < 0)
322 		return ret;
323 
324 	if (!(ret & MDIO_PCS_10GBRT_STAT1_BLKLK))
325 		xpcs_warn(xpcs, state, "Link is not locked!\n");
326 
327 	ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_PCS_10GBRT_STAT2);
328 	if (ret < 0)
329 		return ret;
330 
331 	if (ret & MDIO_PCS_10GBRT_STAT2_ERR) {
332 		xpcs_warn(xpcs, state, "Link has errors!\n");
333 		return -EFAULT;
334 	}
335 
336 	return 0;
337 }
338 
339 static void xpcs_config_usxgmii(struct dw_xpcs *xpcs, int speed)
340 {
341 	int ret, speed_sel;
342 
343 	switch (speed) {
344 	case SPEED_10:
345 		speed_sel = DW_USXGMII_10;
346 		break;
347 	case SPEED_100:
348 		speed_sel = DW_USXGMII_100;
349 		break;
350 	case SPEED_1000:
351 		speed_sel = DW_USXGMII_1000;
352 		break;
353 	case SPEED_2500:
354 		speed_sel = DW_USXGMII_2500;
355 		break;
356 	case SPEED_5000:
357 		speed_sel = DW_USXGMII_5000;
358 		break;
359 	case SPEED_10000:
360 		speed_sel = DW_USXGMII_10000;
361 		break;
362 	default:
363 		/* Nothing to do here */
364 		return;
365 	}
366 
367 	ret = xpcs_read_vpcs(xpcs, MDIO_CTRL1);
368 	if (ret < 0)
369 		goto out;
370 
371 	ret = xpcs_write_vpcs(xpcs, MDIO_CTRL1, ret | DW_USXGMII_EN);
372 	if (ret < 0)
373 		goto out;
374 
375 	ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1);
376 	if (ret < 0)
377 		goto out;
378 
379 	ret &= ~DW_USXGMII_SS_MASK;
380 	ret |= speed_sel | DW_USXGMII_FULL;
381 
382 	ret = xpcs_write(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1, ret);
383 	if (ret < 0)
384 		goto out;
385 
386 	ret = xpcs_read_vpcs(xpcs, MDIO_CTRL1);
387 	if (ret < 0)
388 		goto out;
389 
390 	ret = xpcs_write_vpcs(xpcs, MDIO_CTRL1, ret | DW_USXGMII_RST);
391 	if (ret < 0)
392 		goto out;
393 
394 	return;
395 
396 out:
397 	pr_err("%s: XPCS access returned %pe\n", __func__, ERR_PTR(ret));
398 }
399 
400 static int _xpcs_config_aneg_c73(struct dw_xpcs *xpcs,
401 				 const struct dw_xpcs_compat *compat)
402 {
403 	int ret, adv;
404 
405 	/* By default, in USXGMII mode XPCS operates at 10G baud and
406 	 * replicates data to achieve lower speeds. Hereby, in this
407 	 * default configuration we need to advertise all supported
408 	 * modes and not only the ones we want to use.
409 	 */
410 
411 	/* SR_AN_ADV3 */
412 	adv = 0;
413 	if (xpcs_linkmode_supported(compat, 2500baseX_Full))
414 		adv |= DW_C73_2500KX;
415 
416 	/* TODO: 5000baseKR */
417 
418 	ret = xpcs_write(xpcs, MDIO_MMD_AN, DW_SR_AN_ADV3, adv);
419 	if (ret < 0)
420 		return ret;
421 
422 	/* SR_AN_ADV2 */
423 	adv = 0;
424 	if (xpcs_linkmode_supported(compat, 1000baseKX_Full))
425 		adv |= DW_C73_1000KX;
426 	if (xpcs_linkmode_supported(compat, 10000baseKX4_Full))
427 		adv |= DW_C73_10000KX4;
428 	if (xpcs_linkmode_supported(compat, 10000baseKR_Full))
429 		adv |= DW_C73_10000KR;
430 
431 	ret = xpcs_write(xpcs, MDIO_MMD_AN, DW_SR_AN_ADV2, adv);
432 	if (ret < 0)
433 		return ret;
434 
435 	/* SR_AN_ADV1 */
436 	adv = DW_C73_AN_ADV_SF;
437 	if (xpcs_linkmode_supported(compat, Pause))
438 		adv |= DW_C73_PAUSE;
439 	if (xpcs_linkmode_supported(compat, Asym_Pause))
440 		adv |= DW_C73_ASYM_PAUSE;
441 
442 	return xpcs_write(xpcs, MDIO_MMD_AN, DW_SR_AN_ADV1, adv);
443 }
444 
445 static int xpcs_config_aneg_c73(struct dw_xpcs *xpcs,
446 				const struct dw_xpcs_compat *compat)
447 {
448 	int ret;
449 
450 	ret = _xpcs_config_aneg_c73(xpcs, compat);
451 	if (ret < 0)
452 		return ret;
453 
454 	ret = xpcs_read(xpcs, MDIO_MMD_AN, MDIO_CTRL1);
455 	if (ret < 0)
456 		return ret;
457 
458 	ret |= MDIO_AN_CTRL1_ENABLE | MDIO_AN_CTRL1_RESTART;
459 
460 	return xpcs_write(xpcs, MDIO_MMD_AN, MDIO_CTRL1, ret);
461 }
462 
463 static int xpcs_aneg_done_c73(struct dw_xpcs *xpcs,
464 			      struct phylink_link_state *state,
465 			      const struct dw_xpcs_compat *compat, u16 an_stat1)
466 {
467 	int ret;
468 
469 	if (an_stat1 & MDIO_AN_STAT1_COMPLETE) {
470 		ret = xpcs_read(xpcs, MDIO_MMD_AN, MDIO_AN_LPA);
471 		if (ret < 0)
472 			return ret;
473 
474 		/* Check if Aneg outcome is valid */
475 		if (!(ret & DW_C73_AN_ADV_SF)) {
476 			xpcs_config_aneg_c73(xpcs, compat);
477 			return 0;
478 		}
479 
480 		return 1;
481 	}
482 
483 	return 0;
484 }
485 
486 static int xpcs_read_lpa_c73(struct dw_xpcs *xpcs,
487 			     struct phylink_link_state *state, u16 an_stat1)
488 {
489 	u16 lpa[3];
490 	int i, ret;
491 
492 	if (!(an_stat1 & MDIO_AN_STAT1_LPABLE)) {
493 		phylink_clear(state->lp_advertising, Autoneg);
494 		return 0;
495 	}
496 
497 	phylink_set(state->lp_advertising, Autoneg);
498 
499 	/* Read Clause 73 link partner advertisement */
500 	for (i = ARRAY_SIZE(lpa); --i >= 0; ) {
501 		ret = xpcs_read(xpcs, MDIO_MMD_AN, MDIO_AN_LPA + i);
502 		if (ret < 0)
503 			return ret;
504 
505 		lpa[i] = ret;
506 	}
507 
508 	mii_c73_mod_linkmode(state->lp_advertising, lpa);
509 
510 	return 0;
511 }
512 
513 static int xpcs_get_max_xlgmii_speed(struct dw_xpcs *xpcs,
514 				     struct phylink_link_state *state)
515 {
516 	unsigned long *adv = state->advertising;
517 	int speed = SPEED_UNKNOWN;
518 	int bit;
519 
520 	for_each_set_bit(bit, adv, __ETHTOOL_LINK_MODE_MASK_NBITS) {
521 		int new_speed = SPEED_UNKNOWN;
522 
523 		switch (bit) {
524 		case ETHTOOL_LINK_MODE_25000baseCR_Full_BIT:
525 		case ETHTOOL_LINK_MODE_25000baseKR_Full_BIT:
526 		case ETHTOOL_LINK_MODE_25000baseSR_Full_BIT:
527 			new_speed = SPEED_25000;
528 			break;
529 		case ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT:
530 		case ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT:
531 		case ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT:
532 		case ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT:
533 			new_speed = SPEED_40000;
534 			break;
535 		case ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT:
536 		case ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT:
537 		case ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT:
538 		case ETHTOOL_LINK_MODE_50000baseKR_Full_BIT:
539 		case ETHTOOL_LINK_MODE_50000baseSR_Full_BIT:
540 		case ETHTOOL_LINK_MODE_50000baseCR_Full_BIT:
541 		case ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT:
542 		case ETHTOOL_LINK_MODE_50000baseDR_Full_BIT:
543 			new_speed = SPEED_50000;
544 			break;
545 		case ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT:
546 		case ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT:
547 		case ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT:
548 		case ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT:
549 		case ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT:
550 		case ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT:
551 		case ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT:
552 		case ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT:
553 		case ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT:
554 			new_speed = SPEED_100000;
555 			break;
556 		default:
557 			continue;
558 		}
559 
560 		if (new_speed > speed)
561 			speed = new_speed;
562 	}
563 
564 	return speed;
565 }
566 
567 static void xpcs_resolve_pma(struct dw_xpcs *xpcs,
568 			     struct phylink_link_state *state)
569 {
570 	state->pause = MLO_PAUSE_TX | MLO_PAUSE_RX;
571 	state->duplex = DUPLEX_FULL;
572 
573 	switch (state->interface) {
574 	case PHY_INTERFACE_MODE_10GKR:
575 		state->speed = SPEED_10000;
576 		break;
577 	case PHY_INTERFACE_MODE_XLGMII:
578 		state->speed = xpcs_get_max_xlgmii_speed(xpcs, state);
579 		break;
580 	default:
581 		state->speed = SPEED_UNKNOWN;
582 		break;
583 	}
584 }
585 
586 static int xpcs_validate(struct phylink_pcs *pcs, unsigned long *supported,
587 			 const struct phylink_link_state *state)
588 {
589 	__ETHTOOL_DECLARE_LINK_MODE_MASK(xpcs_supported) = { 0, };
590 	const struct dw_xpcs_compat *compat;
591 	struct dw_xpcs *xpcs;
592 	int i;
593 
594 	xpcs = phylink_pcs_to_xpcs(pcs);
595 	compat = xpcs_find_compat(xpcs->desc, state->interface);
596 	if (!compat)
597 		return -EINVAL;
598 
599 	/* Populate the supported link modes for this PHY interface type.
600 	 * FIXME: what about the port modes and autoneg bit? This masks
601 	 * all those away.
602 	 */
603 	for (i = 0; compat->supported[i] != __ETHTOOL_LINK_MODE_MASK_NBITS; i++)
604 		set_bit(compat->supported[i], xpcs_supported);
605 
606 	linkmode_and(supported, supported, xpcs_supported);
607 
608 	return 0;
609 }
610 
611 void xpcs_get_interfaces(struct dw_xpcs *xpcs, unsigned long *interfaces)
612 {
613 	int i, j;
614 
615 	for (i = 0; i < DW_XPCS_INTERFACE_MAX; i++) {
616 		const struct dw_xpcs_compat *compat = &xpcs->desc->compat[i];
617 
618 		for (j = 0; j < compat->num_interfaces; j++)
619 			__set_bit(compat->interface[j], interfaces);
620 	}
621 }
622 EXPORT_SYMBOL_GPL(xpcs_get_interfaces);
623 
624 int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int enable)
625 {
626 	int ret;
627 
628 	ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL0);
629 	if (ret < 0)
630 		return ret;
631 
632 	if (enable) {
633 	/* Enable EEE */
634 		ret = DW_VR_MII_EEE_LTX_EN | DW_VR_MII_EEE_LRX_EN |
635 		      DW_VR_MII_EEE_TX_QUIET_EN | DW_VR_MII_EEE_RX_QUIET_EN |
636 		      DW_VR_MII_EEE_TX_EN_CTRL | DW_VR_MII_EEE_RX_EN_CTRL |
637 		      mult_fact_100ns << DW_VR_MII_EEE_MULT_FACT_100NS_SHIFT;
638 	} else {
639 		ret &= ~(DW_VR_MII_EEE_LTX_EN | DW_VR_MII_EEE_LRX_EN |
640 		       DW_VR_MII_EEE_TX_QUIET_EN | DW_VR_MII_EEE_RX_QUIET_EN |
641 		       DW_VR_MII_EEE_TX_EN_CTRL | DW_VR_MII_EEE_RX_EN_CTRL |
642 		       DW_VR_MII_EEE_MULT_FACT_100NS);
643 	}
644 
645 	ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL0, ret);
646 	if (ret < 0)
647 		return ret;
648 
649 	ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL1);
650 	if (ret < 0)
651 		return ret;
652 
653 	if (enable)
654 		ret |= DW_VR_MII_EEE_TRN_LPI;
655 	else
656 		ret &= ~DW_VR_MII_EEE_TRN_LPI;
657 
658 	return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL1, ret);
659 }
660 EXPORT_SYMBOL_GPL(xpcs_config_eee);
661 
662 static void xpcs_pre_config(struct phylink_pcs *pcs, phy_interface_t interface)
663 {
664 	struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs);
665 	const struct dw_xpcs_compat *compat;
666 	int ret;
667 
668 	if (!xpcs->need_reset)
669 		return;
670 
671 	compat = xpcs_find_compat(xpcs->desc, interface);
672 	if (!compat) {
673 		dev_err(&xpcs->mdiodev->dev, "unsupported interface %s\n",
674 			phy_modes(interface));
675 		return;
676 	}
677 
678 	ret = xpcs_soft_reset(xpcs, compat);
679 	if (ret)
680 		dev_err(&xpcs->mdiodev->dev, "soft reset failed: %pe\n",
681 			ERR_PTR(ret));
682 
683 	xpcs->need_reset = false;
684 }
685 
686 static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs,
687 				      unsigned int neg_mode)
688 {
689 	int ret, mdio_ctrl, tx_conf;
690 
691 	if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID)
692 		xpcs_write_vpcs(xpcs, DW_VR_XS_PCS_DIG_CTRL1, DW_CL37_BP | DW_EN_VSMMD1);
693 
694 	/* For AN for C37 SGMII mode, the settings are :-
695 	 * 1) VR_MII_MMD_CTRL Bit(12) [AN_ENABLE] = 0b (Disable SGMII AN in case
696 	      it is already enabled)
697 	 * 2) VR_MII_AN_CTRL Bit(2:1)[PCS_MODE] = 10b (SGMII AN)
698 	 * 3) VR_MII_AN_CTRL Bit(3) [TX_CONFIG] = 0b (MAC side SGMII)
699 	 *    DW xPCS used with DW EQoS MAC is always MAC side SGMII.
700 	 * 4) VR_MII_DIG_CTRL1 Bit(9) [MAC_AUTO_SW] = 1b (Automatic
701 	 *    speed/duplex mode change by HW after SGMII AN complete)
702 	 * 5) VR_MII_MMD_CTRL Bit(12) [AN_ENABLE] = 1b (Enable SGMII AN)
703 	 *
704 	 * Note: Since it is MAC side SGMII, there is no need to set
705 	 *	 SR_MII_AN_ADV. MAC side SGMII receives AN Tx Config from
706 	 *	 PHY about the link state change after C28 AN is completed
707 	 *	 between PHY and Link Partner. There is also no need to
708 	 *	 trigger AN restart for MAC-side SGMII.
709 	 */
710 	mdio_ctrl = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL);
711 	if (mdio_ctrl < 0)
712 		return mdio_ctrl;
713 
714 	if (mdio_ctrl & AN_CL37_EN) {
715 		ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL,
716 				 mdio_ctrl & ~AN_CL37_EN);
717 		if (ret < 0)
718 			return ret;
719 	}
720 
721 	ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL);
722 	if (ret < 0)
723 		return ret;
724 
725 	ret &= ~(DW_VR_MII_PCS_MODE_MASK | DW_VR_MII_TX_CONFIG_MASK);
726 	ret |= (DW_VR_MII_PCS_MODE_C37_SGMII <<
727 		DW_VR_MII_AN_CTRL_PCS_MODE_SHIFT &
728 		DW_VR_MII_PCS_MODE_MASK);
729 	if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID) {
730 		ret |= DW_VR_MII_AN_CTRL_8BIT;
731 		/* Hardware requires it to be PHY side SGMII */
732 		tx_conf = DW_VR_MII_TX_CONFIG_PHY_SIDE_SGMII;
733 	} else {
734 		tx_conf = DW_VR_MII_TX_CONFIG_MAC_SIDE_SGMII;
735 	}
736 	ret |= tx_conf << DW_VR_MII_AN_CTRL_TX_CONFIG_SHIFT &
737 		DW_VR_MII_TX_CONFIG_MASK;
738 	ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL, ret);
739 	if (ret < 0)
740 		return ret;
741 
742 	ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1);
743 	if (ret < 0)
744 		return ret;
745 
746 	if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
747 		ret |= DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW;
748 	else
749 		ret &= ~DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW;
750 
751 	if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID)
752 		ret |= DW_VR_MII_DIG_CTRL1_PHY_MODE_CTRL;
753 
754 	ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret);
755 	if (ret < 0)
756 		return ret;
757 
758 	if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
759 		ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL,
760 				 mdio_ctrl | AN_CL37_EN);
761 
762 	return ret;
763 }
764 
765 static int xpcs_config_aneg_c37_1000basex(struct dw_xpcs *xpcs,
766 					  unsigned int neg_mode,
767 					  const unsigned long *advertising)
768 {
769 	phy_interface_t interface = PHY_INTERFACE_MODE_1000BASEX;
770 	int ret, mdio_ctrl, adv;
771 	bool changed = 0;
772 
773 	if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID)
774 		xpcs_write_vpcs(xpcs, DW_VR_XS_PCS_DIG_CTRL1, DW_CL37_BP | DW_EN_VSMMD1);
775 
776 	/* According to Chap 7.12, to set 1000BASE-X C37 AN, AN must
777 	 * be disabled first:-
778 	 * 1) VR_MII_MMD_CTRL Bit(12)[AN_ENABLE] = 0b
779 	 * 2) VR_MII_AN_CTRL Bit(2:1)[PCS_MODE] = 00b (1000BASE-X C37)
780 	 */
781 	mdio_ctrl = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL);
782 	if (mdio_ctrl < 0)
783 		return mdio_ctrl;
784 
785 	if (mdio_ctrl & AN_CL37_EN) {
786 		ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL,
787 				 mdio_ctrl & ~AN_CL37_EN);
788 		if (ret < 0)
789 			return ret;
790 	}
791 
792 	ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL);
793 	if (ret < 0)
794 		return ret;
795 
796 	ret &= ~DW_VR_MII_PCS_MODE_MASK;
797 	if (!xpcs->pcs.poll)
798 		ret |= DW_VR_MII_AN_INTR_EN;
799 	ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL, ret);
800 	if (ret < 0)
801 		return ret;
802 
803 	/* Check for advertising changes and update the C45 MII ADV
804 	 * register accordingly.
805 	 */
806 	adv = phylink_mii_c22_pcs_encode_advertisement(interface,
807 						       advertising);
808 	if (adv >= 0) {
809 		ret = xpcs_modify_changed(xpcs, MDIO_MMD_VEND2,
810 					  MII_ADVERTISE, 0xffff, adv);
811 		if (ret < 0)
812 			return ret;
813 
814 		changed = ret;
815 	}
816 
817 	/* Clear CL37 AN complete status */
818 	ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_INTR_STS, 0);
819 	if (ret < 0)
820 		return ret;
821 
822 	if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
823 		ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL,
824 				 mdio_ctrl | AN_CL37_EN);
825 		if (ret < 0)
826 			return ret;
827 	}
828 
829 	return changed;
830 }
831 
832 static int xpcs_config_2500basex(struct dw_xpcs *xpcs)
833 {
834 	int ret;
835 
836 	ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1);
837 	if (ret < 0)
838 		return ret;
839 	ret |= DW_VR_MII_DIG_CTRL1_2G5_EN;
840 	ret &= ~DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW;
841 	ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret);
842 	if (ret < 0)
843 		return ret;
844 
845 	ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL);
846 	if (ret < 0)
847 		return ret;
848 	ret &= ~AN_CL37_EN;
849 	ret |= SGMII_SPEED_SS6;
850 	ret &= ~SGMII_SPEED_SS13;
851 	return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL, ret);
852 }
853 
854 static int xpcs_do_config(struct dw_xpcs *xpcs, phy_interface_t interface,
855 			  const unsigned long *advertising,
856 			  unsigned int neg_mode)
857 {
858 	const struct dw_xpcs_compat *compat;
859 	int ret;
860 
861 	compat = xpcs_find_compat(xpcs->desc, interface);
862 	if (!compat)
863 		return -ENODEV;
864 
865 	if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID) {
866 		ret = txgbe_xpcs_switch_mode(xpcs, interface);
867 		if (ret)
868 			return ret;
869 	}
870 
871 	switch (compat->an_mode) {
872 	case DW_10GBASER:
873 		break;
874 	case DW_AN_C73:
875 		if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
876 			ret = xpcs_config_aneg_c73(xpcs, compat);
877 			if (ret)
878 				return ret;
879 		}
880 		break;
881 	case DW_AN_C37_SGMII:
882 		ret = xpcs_config_aneg_c37_sgmii(xpcs, neg_mode);
883 		if (ret)
884 			return ret;
885 		break;
886 	case DW_AN_C37_1000BASEX:
887 		ret = xpcs_config_aneg_c37_1000basex(xpcs, neg_mode,
888 						     advertising);
889 		if (ret)
890 			return ret;
891 		break;
892 	case DW_2500BASEX:
893 		ret = xpcs_config_2500basex(xpcs);
894 		if (ret)
895 			return ret;
896 		break;
897 	default:
898 		return -EINVAL;
899 	}
900 
901 	if (compat->pma_config) {
902 		ret = compat->pma_config(xpcs);
903 		if (ret)
904 			return ret;
905 	}
906 
907 	return 0;
908 }
909 
910 static int xpcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
911 		       phy_interface_t interface,
912 		       const unsigned long *advertising,
913 		       bool permit_pause_to_mac)
914 {
915 	struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs);
916 
917 	return xpcs_do_config(xpcs, interface, advertising, neg_mode);
918 }
919 
920 static int xpcs_get_state_c73(struct dw_xpcs *xpcs,
921 			      struct phylink_link_state *state,
922 			      const struct dw_xpcs_compat *compat)
923 {
924 	bool an_enabled;
925 	int pcs_stat1;
926 	int an_stat1;
927 	int ret;
928 
929 	/* The link status bit is latching-low, so it is important to
930 	 * avoid unnecessary re-reads of this register to avoid missing
931 	 * a link-down event.
932 	 */
933 	pcs_stat1 = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_STAT1);
934 	if (pcs_stat1 < 0) {
935 		state->link = false;
936 		return pcs_stat1;
937 	}
938 
939 	/* Link needs to be read first ... */
940 	state->link = !!(pcs_stat1 & MDIO_STAT1_LSTATUS);
941 
942 	/* ... and then we check the faults. */
943 	ret = xpcs_read_fault_c73(xpcs, state, pcs_stat1);
944 	if (ret) {
945 		ret = xpcs_soft_reset(xpcs, compat);
946 		if (ret)
947 			return ret;
948 
949 		state->link = 0;
950 
951 		return xpcs_do_config(xpcs, state->interface, NULL,
952 				      PHYLINK_PCS_NEG_INBAND_ENABLED);
953 	}
954 
955 	/* There is no point doing anything else if the link is down. */
956 	if (!state->link)
957 		return 0;
958 
959 	an_enabled = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
960 				       state->advertising);
961 	if (an_enabled) {
962 		/* The link status bit is latching-low, so it is important to
963 		 * avoid unnecessary re-reads of this register to avoid missing
964 		 * a link-down event.
965 		 */
966 		an_stat1 = xpcs_read(xpcs, MDIO_MMD_AN, MDIO_STAT1);
967 		if (an_stat1 < 0) {
968 			state->link = false;
969 			return an_stat1;
970 		}
971 
972 		state->an_complete = xpcs_aneg_done_c73(xpcs, state, compat,
973 							an_stat1);
974 		if (!state->an_complete) {
975 			state->link = false;
976 			return 0;
977 		}
978 
979 		ret = xpcs_read_lpa_c73(xpcs, state, an_stat1);
980 		if (ret < 0) {
981 			state->link = false;
982 			return ret;
983 		}
984 
985 		phylink_resolve_c73(state);
986 	} else {
987 		xpcs_resolve_pma(xpcs, state);
988 	}
989 
990 	return 0;
991 }
992 
993 static int xpcs_get_state_c37_sgmii(struct dw_xpcs *xpcs,
994 				    struct phylink_link_state *state)
995 {
996 	int ret;
997 
998 	/* Reset link_state */
999 	state->link = false;
1000 	state->speed = SPEED_UNKNOWN;
1001 	state->duplex = DUPLEX_UNKNOWN;
1002 	state->pause = 0;
1003 
1004 	/* For C37 SGMII mode, we check DW_VR_MII_AN_INTR_STS for link
1005 	 * status, speed and duplex.
1006 	 */
1007 	ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_INTR_STS);
1008 	if (ret < 0)
1009 		return ret;
1010 
1011 	if (ret & DW_VR_MII_C37_ANSGM_SP_LNKSTS) {
1012 		int speed_value;
1013 
1014 		state->link = true;
1015 
1016 		speed_value = (ret & DW_VR_MII_AN_STS_C37_ANSGM_SP) >>
1017 			      DW_VR_MII_AN_STS_C37_ANSGM_SP_SHIFT;
1018 		if (speed_value == DW_VR_MII_C37_ANSGM_SP_1000)
1019 			state->speed = SPEED_1000;
1020 		else if (speed_value == DW_VR_MII_C37_ANSGM_SP_100)
1021 			state->speed = SPEED_100;
1022 		else
1023 			state->speed = SPEED_10;
1024 
1025 		if (ret & DW_VR_MII_AN_STS_C37_ANSGM_FD)
1026 			state->duplex = DUPLEX_FULL;
1027 		else
1028 			state->duplex = DUPLEX_HALF;
1029 	} else if (ret == DW_VR_MII_AN_STS_C37_ANCMPLT_INTR) {
1030 		int speed, duplex;
1031 
1032 		state->link = true;
1033 
1034 		speed = xpcs_read(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1);
1035 		if (speed < 0)
1036 			return speed;
1037 
1038 		speed &= SGMII_SPEED_SS13 | SGMII_SPEED_SS6;
1039 		if (speed == SGMII_SPEED_SS6)
1040 			state->speed = SPEED_1000;
1041 		else if (speed == SGMII_SPEED_SS13)
1042 			state->speed = SPEED_100;
1043 		else if (speed == 0)
1044 			state->speed = SPEED_10;
1045 
1046 		duplex = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_ADVERTISE);
1047 		if (duplex < 0)
1048 			return duplex;
1049 
1050 		if (duplex & DW_FULL_DUPLEX)
1051 			state->duplex = DUPLEX_FULL;
1052 		else if (duplex & DW_HALF_DUPLEX)
1053 			state->duplex = DUPLEX_HALF;
1054 
1055 		xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_INTR_STS, 0);
1056 	}
1057 
1058 	return 0;
1059 }
1060 
1061 static int xpcs_get_state_c37_1000basex(struct dw_xpcs *xpcs,
1062 					struct phylink_link_state *state)
1063 {
1064 	int lpa, bmsr;
1065 
1066 	if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
1067 			      state->advertising)) {
1068 		/* Reset link state */
1069 		state->link = false;
1070 
1071 		lpa = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_LPA);
1072 		if (lpa < 0 || lpa & LPA_RFAULT)
1073 			return lpa;
1074 
1075 		bmsr = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_BMSR);
1076 		if (bmsr < 0)
1077 			return bmsr;
1078 
1079 		/* Clear AN complete interrupt */
1080 		if (!xpcs->pcs.poll) {
1081 			int an_intr;
1082 
1083 			an_intr = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_INTR_STS);
1084 			if (an_intr & DW_VR_MII_AN_STS_C37_ANCMPLT_INTR) {
1085 				an_intr &= ~DW_VR_MII_AN_STS_C37_ANCMPLT_INTR;
1086 				xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_INTR_STS, an_intr);
1087 			}
1088 		}
1089 
1090 		phylink_mii_c22_pcs_decode_state(state, bmsr, lpa);
1091 	}
1092 
1093 	return 0;
1094 }
1095 
1096 static int xpcs_get_state_2500basex(struct dw_xpcs *xpcs,
1097 				    struct phylink_link_state *state)
1098 {
1099 	int ret;
1100 
1101 	ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_STS);
1102 	if (ret < 0) {
1103 		state->link = 0;
1104 		return ret;
1105 	}
1106 
1107 	state->link = !!(ret & DW_VR_MII_MMD_STS_LINK_STS);
1108 	if (!state->link)
1109 		return 0;
1110 
1111 	state->speed = SPEED_2500;
1112 	state->pause |= MLO_PAUSE_TX | MLO_PAUSE_RX;
1113 	state->duplex = DUPLEX_FULL;
1114 
1115 	return 0;
1116 }
1117 
1118 static void xpcs_get_state(struct phylink_pcs *pcs,
1119 			   struct phylink_link_state *state)
1120 {
1121 	struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs);
1122 	const struct dw_xpcs_compat *compat;
1123 	int ret;
1124 
1125 	compat = xpcs_find_compat(xpcs->desc, state->interface);
1126 	if (!compat)
1127 		return;
1128 
1129 	switch (compat->an_mode) {
1130 	case DW_10GBASER:
1131 		phylink_mii_c45_pcs_get_state(xpcs->mdiodev, state);
1132 		break;
1133 	case DW_AN_C73:
1134 		ret = xpcs_get_state_c73(xpcs, state, compat);
1135 		if (ret) {
1136 			pr_err("xpcs_get_state_c73 returned %pe\n",
1137 			       ERR_PTR(ret));
1138 			return;
1139 		}
1140 		break;
1141 	case DW_AN_C37_SGMII:
1142 		ret = xpcs_get_state_c37_sgmii(xpcs, state);
1143 		if (ret) {
1144 			pr_err("xpcs_get_state_c37_sgmii returned %pe\n",
1145 			       ERR_PTR(ret));
1146 		}
1147 		break;
1148 	case DW_AN_C37_1000BASEX:
1149 		ret = xpcs_get_state_c37_1000basex(xpcs, state);
1150 		if (ret) {
1151 			pr_err("xpcs_get_state_c37_1000basex returned %pe\n",
1152 			       ERR_PTR(ret));
1153 		}
1154 		break;
1155 	case DW_2500BASEX:
1156 		ret = xpcs_get_state_2500basex(xpcs, state);
1157 		if (ret) {
1158 			pr_err("xpcs_get_state_2500basex returned %pe\n",
1159 			       ERR_PTR(ret));
1160 		}
1161 		break;
1162 	default:
1163 		return;
1164 	}
1165 }
1166 
1167 static void xpcs_link_up_sgmii(struct dw_xpcs *xpcs, unsigned int neg_mode,
1168 			       int speed, int duplex)
1169 {
1170 	int val, ret;
1171 
1172 	if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
1173 		return;
1174 
1175 	val = mii_bmcr_encode_fixed(speed, duplex);
1176 	ret = xpcs_write(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1, val);
1177 	if (ret)
1178 		pr_err("%s: xpcs_write returned %pe\n", __func__, ERR_PTR(ret));
1179 }
1180 
1181 static void xpcs_link_up_1000basex(struct dw_xpcs *xpcs, unsigned int neg_mode,
1182 				   int speed, int duplex)
1183 {
1184 	int val, ret;
1185 
1186 	if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
1187 		return;
1188 
1189 	switch (speed) {
1190 	case SPEED_1000:
1191 		val = BMCR_SPEED1000;
1192 		break;
1193 	case SPEED_100:
1194 	case SPEED_10:
1195 	default:
1196 		pr_err("%s: speed = %d\n", __func__, speed);
1197 		return;
1198 	}
1199 
1200 	if (duplex == DUPLEX_FULL)
1201 		val |= BMCR_FULLDPLX;
1202 	else
1203 		pr_err("%s: half duplex not supported\n", __func__);
1204 
1205 	ret = xpcs_write(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1, val);
1206 	if (ret)
1207 		pr_err("%s: xpcs_write returned %pe\n", __func__, ERR_PTR(ret));
1208 }
1209 
1210 static void xpcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode,
1211 			 phy_interface_t interface, int speed, int duplex)
1212 {
1213 	struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs);
1214 
1215 	if (interface == PHY_INTERFACE_MODE_USXGMII)
1216 		return xpcs_config_usxgmii(xpcs, speed);
1217 	if (interface == PHY_INTERFACE_MODE_SGMII)
1218 		return xpcs_link_up_sgmii(xpcs, neg_mode, speed, duplex);
1219 	if (interface == PHY_INTERFACE_MODE_1000BASEX)
1220 		return xpcs_link_up_1000basex(xpcs, neg_mode, speed, duplex);
1221 }
1222 
1223 static void xpcs_an_restart(struct phylink_pcs *pcs)
1224 {
1225 	struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs);
1226 	int ret;
1227 
1228 	ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1);
1229 	if (ret >= 0) {
1230 		ret |= BMCR_ANRESTART;
1231 		xpcs_write(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1, ret);
1232 	}
1233 }
1234 
1235 static int xpcs_get_id(struct dw_xpcs *xpcs)
1236 {
1237 	int ret;
1238 	u32 id;
1239 
1240 	/* First, search C73 PCS using PCS MMD 3. Return ENODEV if communication
1241 	 * failed indicating that device couldn't be reached.
1242 	 */
1243 	ret = xpcs_read(xpcs, MDIO_MMD_PCS, MII_PHYSID1);
1244 	if (ret < 0)
1245 		return -ENODEV;
1246 
1247 	id = ret << 16;
1248 
1249 	ret = xpcs_read(xpcs, MDIO_MMD_PCS, MII_PHYSID2);
1250 	if (ret < 0)
1251 		return ret;
1252 
1253 	id |= ret;
1254 
1255 	/* If Device IDs are not all zeros or ones, then 10GBase-X/R or C73
1256 	 * KR/KX4 PCS found. Otherwise fallback to detecting 1000Base-X or C37
1257 	 * PCS in MII MMD 31.
1258 	 */
1259 	if (!id || id == 0xffffffff) {
1260 		ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_PHYSID1);
1261 		if (ret < 0)
1262 			return ret;
1263 
1264 		id = ret << 16;
1265 
1266 		ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_PHYSID2);
1267 		if (ret < 0)
1268 			return ret;
1269 
1270 		id |= ret;
1271 	}
1272 
1273 	/* Set the PCS ID if it hasn't been pre-initialized */
1274 	if (xpcs->info.pcs == DW_XPCS_ID_NATIVE)
1275 		xpcs->info.pcs = id;
1276 
1277 	/* Find out PMA/PMD ID from MMD 1 device ID registers */
1278 	ret = xpcs_read(xpcs, MDIO_MMD_PMAPMD, MDIO_DEVID1);
1279 	if (ret < 0)
1280 		return ret;
1281 
1282 	id = ret;
1283 
1284 	ret = xpcs_read(xpcs, MDIO_MMD_PMAPMD, MDIO_DEVID2);
1285 	if (ret < 0)
1286 		return ret;
1287 
1288 	/* Note the inverted dword order and masked out Model/Revision numbers
1289 	 * with respect to what is done with the PCS ID...
1290 	 */
1291 	ret = (ret >> 10) & 0x3F;
1292 	id |= ret << 16;
1293 
1294 	/* Set the PMA ID if it hasn't been pre-initialized */
1295 	if (xpcs->info.pma == DW_XPCS_PMA_ID_NATIVE)
1296 		xpcs->info.pma = id;
1297 
1298 	return 0;
1299 }
1300 
1301 static const struct dw_xpcs_compat synopsys_xpcs_compat[DW_XPCS_INTERFACE_MAX] = {
1302 	[DW_XPCS_USXGMII] = {
1303 		.supported = xpcs_usxgmii_features,
1304 		.interface = xpcs_usxgmii_interfaces,
1305 		.num_interfaces = ARRAY_SIZE(xpcs_usxgmii_interfaces),
1306 		.an_mode = DW_AN_C73,
1307 	},
1308 	[DW_XPCS_10GKR] = {
1309 		.supported = xpcs_10gkr_features,
1310 		.interface = xpcs_10gkr_interfaces,
1311 		.num_interfaces = ARRAY_SIZE(xpcs_10gkr_interfaces),
1312 		.an_mode = DW_AN_C73,
1313 	},
1314 	[DW_XPCS_XLGMII] = {
1315 		.supported = xpcs_xlgmii_features,
1316 		.interface = xpcs_xlgmii_interfaces,
1317 		.num_interfaces = ARRAY_SIZE(xpcs_xlgmii_interfaces),
1318 		.an_mode = DW_AN_C73,
1319 	},
1320 	[DW_XPCS_10GBASER] = {
1321 		.supported = xpcs_10gbaser_features,
1322 		.interface = xpcs_10gbaser_interfaces,
1323 		.num_interfaces = ARRAY_SIZE(xpcs_10gbaser_interfaces),
1324 		.an_mode = DW_10GBASER,
1325 	},
1326 	[DW_XPCS_SGMII] = {
1327 		.supported = xpcs_sgmii_features,
1328 		.interface = xpcs_sgmii_interfaces,
1329 		.num_interfaces = ARRAY_SIZE(xpcs_sgmii_interfaces),
1330 		.an_mode = DW_AN_C37_SGMII,
1331 	},
1332 	[DW_XPCS_1000BASEX] = {
1333 		.supported = xpcs_1000basex_features,
1334 		.interface = xpcs_1000basex_interfaces,
1335 		.num_interfaces = ARRAY_SIZE(xpcs_1000basex_interfaces),
1336 		.an_mode = DW_AN_C37_1000BASEX,
1337 	},
1338 	[DW_XPCS_2500BASEX] = {
1339 		.supported = xpcs_2500basex_features,
1340 		.interface = xpcs_2500basex_interfaces,
1341 		.num_interfaces = ARRAY_SIZE(xpcs_2500basex_interfaces),
1342 		.an_mode = DW_2500BASEX,
1343 	},
1344 };
1345 
1346 static const struct dw_xpcs_compat nxp_sja1105_xpcs_compat[DW_XPCS_INTERFACE_MAX] = {
1347 	[DW_XPCS_SGMII] = {
1348 		.supported = xpcs_sgmii_features,
1349 		.interface = xpcs_sgmii_interfaces,
1350 		.num_interfaces = ARRAY_SIZE(xpcs_sgmii_interfaces),
1351 		.an_mode = DW_AN_C37_SGMII,
1352 		.pma_config = nxp_sja1105_sgmii_pma_config,
1353 	},
1354 };
1355 
1356 static const struct dw_xpcs_compat nxp_sja1110_xpcs_compat[DW_XPCS_INTERFACE_MAX] = {
1357 	[DW_XPCS_SGMII] = {
1358 		.supported = xpcs_sgmii_features,
1359 		.interface = xpcs_sgmii_interfaces,
1360 		.num_interfaces = ARRAY_SIZE(xpcs_sgmii_interfaces),
1361 		.an_mode = DW_AN_C37_SGMII,
1362 		.pma_config = nxp_sja1110_sgmii_pma_config,
1363 	},
1364 	[DW_XPCS_2500BASEX] = {
1365 		.supported = xpcs_2500basex_features,
1366 		.interface = xpcs_2500basex_interfaces,
1367 		.num_interfaces = ARRAY_SIZE(xpcs_2500basex_interfaces),
1368 		.an_mode = DW_2500BASEX,
1369 		.pma_config = nxp_sja1110_2500basex_pma_config,
1370 	},
1371 };
1372 
1373 static const struct dw_xpcs_desc xpcs_desc_list[] = {
1374 	{
1375 		.id = DW_XPCS_ID,
1376 		.mask = DW_XPCS_ID_MASK,
1377 		.compat = synopsys_xpcs_compat,
1378 	}, {
1379 		.id = NXP_SJA1105_XPCS_ID,
1380 		.mask = DW_XPCS_ID_MASK,
1381 		.compat = nxp_sja1105_xpcs_compat,
1382 	}, {
1383 		.id = NXP_SJA1110_XPCS_ID,
1384 		.mask = DW_XPCS_ID_MASK,
1385 		.compat = nxp_sja1110_xpcs_compat,
1386 	},
1387 };
1388 
1389 static const struct phylink_pcs_ops xpcs_phylink_ops = {
1390 	.pcs_validate = xpcs_validate,
1391 	.pcs_pre_config = xpcs_pre_config,
1392 	.pcs_config = xpcs_config,
1393 	.pcs_get_state = xpcs_get_state,
1394 	.pcs_an_restart = xpcs_an_restart,
1395 	.pcs_link_up = xpcs_link_up,
1396 };
1397 
1398 static struct dw_xpcs *xpcs_create_data(struct mdio_device *mdiodev)
1399 {
1400 	struct dw_xpcs *xpcs;
1401 
1402 	xpcs = kzalloc(sizeof(*xpcs), GFP_KERNEL);
1403 	if (!xpcs)
1404 		return ERR_PTR(-ENOMEM);
1405 
1406 	mdio_device_get(mdiodev);
1407 	xpcs->mdiodev = mdiodev;
1408 	xpcs->pcs.ops = &xpcs_phylink_ops;
1409 	xpcs->pcs.neg_mode = true;
1410 	xpcs->pcs.poll = true;
1411 
1412 	return xpcs;
1413 }
1414 
1415 static void xpcs_free_data(struct dw_xpcs *xpcs)
1416 {
1417 	mdio_device_put(xpcs->mdiodev);
1418 	kfree(xpcs);
1419 }
1420 
1421 static int xpcs_init_clks(struct dw_xpcs *xpcs)
1422 {
1423 	static const char *ids[DW_XPCS_NUM_CLKS] = {
1424 		[DW_XPCS_CORE_CLK] = "core",
1425 		[DW_XPCS_PAD_CLK] = "pad",
1426 	};
1427 	struct device *dev = &xpcs->mdiodev->dev;
1428 	int ret, i;
1429 
1430 	for (i = 0; i < DW_XPCS_NUM_CLKS; ++i)
1431 		xpcs->clks[i].id = ids[i];
1432 
1433 	ret = clk_bulk_get_optional(dev, DW_XPCS_NUM_CLKS, xpcs->clks);
1434 	if (ret)
1435 		return dev_err_probe(dev, ret, "Failed to get clocks\n");
1436 
1437 	ret = clk_bulk_prepare_enable(DW_XPCS_NUM_CLKS, xpcs->clks);
1438 	if (ret)
1439 		return dev_err_probe(dev, ret, "Failed to enable clocks\n");
1440 
1441 	return 0;
1442 }
1443 
1444 static void xpcs_clear_clks(struct dw_xpcs *xpcs)
1445 {
1446 	clk_bulk_disable_unprepare(DW_XPCS_NUM_CLKS, xpcs->clks);
1447 
1448 	clk_bulk_put(DW_XPCS_NUM_CLKS, xpcs->clks);
1449 }
1450 
1451 static int xpcs_init_id(struct dw_xpcs *xpcs)
1452 {
1453 	const struct dw_xpcs_info *info;
1454 	int i, ret;
1455 
1456 	info = dev_get_platdata(&xpcs->mdiodev->dev);
1457 	if (!info) {
1458 		xpcs->info.pcs = DW_XPCS_ID_NATIVE;
1459 		xpcs->info.pma = DW_XPCS_PMA_ID_NATIVE;
1460 	} else {
1461 		xpcs->info = *info;
1462 	}
1463 
1464 	ret = xpcs_get_id(xpcs);
1465 	if (ret < 0)
1466 		return ret;
1467 
1468 	for (i = 0; i < ARRAY_SIZE(xpcs_desc_list); i++) {
1469 		const struct dw_xpcs_desc *desc = &xpcs_desc_list[i];
1470 
1471 		if ((xpcs->info.pcs & desc->mask) != desc->id)
1472 			continue;
1473 
1474 		xpcs->desc = desc;
1475 
1476 		break;
1477 	}
1478 
1479 	if (!xpcs->desc)
1480 		return -ENODEV;
1481 
1482 	return 0;
1483 }
1484 
1485 static struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev)
1486 {
1487 	struct dw_xpcs *xpcs;
1488 	int ret;
1489 
1490 	xpcs = xpcs_create_data(mdiodev);
1491 	if (IS_ERR(xpcs))
1492 		return xpcs;
1493 
1494 	ret = xpcs_init_clks(xpcs);
1495 	if (ret)
1496 		goto out_free_data;
1497 
1498 	ret = xpcs_init_id(xpcs);
1499 	if (ret)
1500 		goto out_clear_clks;
1501 
1502 	if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID)
1503 		xpcs->pcs.poll = false;
1504 	else
1505 		xpcs->need_reset = true;
1506 
1507 	return xpcs;
1508 
1509 out_clear_clks:
1510 	xpcs_clear_clks(xpcs);
1511 
1512 out_free_data:
1513 	xpcs_free_data(xpcs);
1514 
1515 	return ERR_PTR(ret);
1516 }
1517 
1518 /**
1519  * xpcs_create_mdiodev() - create a DW xPCS instance with the MDIO @addr
1520  * @bus: pointer to the MDIO-bus descriptor for the device to be looked at
1521  * @addr: device MDIO-bus ID
1522  *
1523  * Return: a pointer to the DW XPCS handle if successful, otherwise -ENODEV if
1524  * the PCS device couldn't be found on the bus and other negative errno related
1525  * to the data allocation and MDIO-bus communications.
1526  */
1527 struct dw_xpcs *xpcs_create_mdiodev(struct mii_bus *bus, int addr)
1528 {
1529 	struct mdio_device *mdiodev;
1530 	struct dw_xpcs *xpcs;
1531 
1532 	mdiodev = mdio_device_create(bus, addr);
1533 	if (IS_ERR(mdiodev))
1534 		return ERR_CAST(mdiodev);
1535 
1536 	xpcs = xpcs_create(mdiodev);
1537 
1538 	/* xpcs_create() has taken a refcount on the mdiodev if it was
1539 	 * successful. If xpcs_create() fails, this will free the mdio
1540 	 * device here. In any case, we don't need to hold our reference
1541 	 * anymore, and putting it here will allow mdio_device_put() in
1542 	 * xpcs_destroy() to automatically free the mdio device.
1543 	 */
1544 	mdio_device_put(mdiodev);
1545 
1546 	return xpcs;
1547 }
1548 EXPORT_SYMBOL_GPL(xpcs_create_mdiodev);
1549 
1550 struct phylink_pcs *xpcs_create_pcs_mdiodev(struct mii_bus *bus, int addr)
1551 {
1552 	struct dw_xpcs *xpcs;
1553 
1554 	xpcs = xpcs_create_mdiodev(bus, addr);
1555 	if (IS_ERR(xpcs))
1556 		return ERR_CAST(xpcs);
1557 
1558 	return &xpcs->pcs;
1559 }
1560 EXPORT_SYMBOL_GPL(xpcs_create_pcs_mdiodev);
1561 
1562 /**
1563  * xpcs_create_fwnode() - Create a DW xPCS instance from @fwnode
1564  * @fwnode: fwnode handle poining to the DW XPCS device
1565  *
1566  * Return: a pointer to the DW XPCS handle if successful, otherwise -ENODEV if
1567  * the fwnode device is unavailable or the PCS device couldn't be found on the
1568  * bus, -EPROBE_DEFER if the respective MDIO-device instance couldn't be found,
1569  * other negative errno related to the data allocations and MDIO-bus
1570  * communications.
1571  */
1572 struct dw_xpcs *xpcs_create_fwnode(struct fwnode_handle *fwnode)
1573 {
1574 	struct mdio_device *mdiodev;
1575 	struct dw_xpcs *xpcs;
1576 
1577 	if (!fwnode_device_is_available(fwnode))
1578 		return ERR_PTR(-ENODEV);
1579 
1580 	mdiodev = fwnode_mdio_find_device(fwnode);
1581 	if (!mdiodev)
1582 		return ERR_PTR(-EPROBE_DEFER);
1583 
1584 	xpcs = xpcs_create(mdiodev);
1585 
1586 	/* xpcs_create() has taken a refcount on the mdiodev if it was
1587 	 * successful. If xpcs_create() fails, this will free the mdio
1588 	 * device here. In any case, we don't need to hold our reference
1589 	 * anymore, and putting it here will allow mdio_device_put() in
1590 	 * xpcs_destroy() to automatically free the mdio device.
1591 	 */
1592 	mdio_device_put(mdiodev);
1593 
1594 	return xpcs;
1595 }
1596 EXPORT_SYMBOL_GPL(xpcs_create_fwnode);
1597 
1598 void xpcs_destroy(struct dw_xpcs *xpcs)
1599 {
1600 	if (!xpcs)
1601 		return;
1602 
1603 	xpcs_clear_clks(xpcs);
1604 
1605 	xpcs_free_data(xpcs);
1606 }
1607 EXPORT_SYMBOL_GPL(xpcs_destroy);
1608 
1609 void xpcs_destroy_pcs(struct phylink_pcs *pcs)
1610 {
1611 	xpcs_destroy(phylink_pcs_to_xpcs(pcs));
1612 }
1613 EXPORT_SYMBOL_GPL(xpcs_destroy_pcs);
1614 
1615 MODULE_DESCRIPTION("Synopsys DesignWare XPCS library");
1616 MODULE_LICENSE("GPL v2");
1617