• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/delay.h>
10 #include <linux/pcs/pcs-xpcs.h>
11 #include <linux/mdio.h>
12 #include <linux/phylink.h>
13 #include <linux/workqueue.h>
14 #include "pcs-xpcs.h"
15 
16 #define phylink_pcs_to_xpcs(pl_pcs) \
17 	container_of((pl_pcs), struct dw_xpcs, pcs)
18 
19 static const int xpcs_usxgmii_features[] = {
20 	ETHTOOL_LINK_MODE_Pause_BIT,
21 	ETHTOOL_LINK_MODE_Asym_Pause_BIT,
22 	ETHTOOL_LINK_MODE_Autoneg_BIT,
23 	ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
24 	ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
25 	ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
26 	ETHTOOL_LINK_MODE_2500baseX_Full_BIT,
27 	__ETHTOOL_LINK_MODE_MASK_NBITS,
28 };
29 
30 static const int xpcs_10gkr_features[] = {
31 	ETHTOOL_LINK_MODE_Pause_BIT,
32 	ETHTOOL_LINK_MODE_Asym_Pause_BIT,
33 	ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
34 	__ETHTOOL_LINK_MODE_MASK_NBITS,
35 };
36 
37 static const int xpcs_xlgmii_features[] = {
38 	ETHTOOL_LINK_MODE_Pause_BIT,
39 	ETHTOOL_LINK_MODE_Asym_Pause_BIT,
40 	ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
41 	ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
42 	ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
43 	ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
44 	ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT,
45 	ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT,
46 	ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT,
47 	ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT,
48 	ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT,
49 	ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT,
50 	ETHTOOL_LINK_MODE_50000baseKR_Full_BIT,
51 	ETHTOOL_LINK_MODE_50000baseSR_Full_BIT,
52 	ETHTOOL_LINK_MODE_50000baseCR_Full_BIT,
53 	ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT,
54 	ETHTOOL_LINK_MODE_50000baseDR_Full_BIT,
55 	ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
56 	ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT,
57 	ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
58 	ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT,
59 	ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT,
60 	ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT,
61 	ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT,
62 	ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT,
63 	ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT,
64 	__ETHTOOL_LINK_MODE_MASK_NBITS,
65 };
66 
67 static const int xpcs_sgmii_features[] = {
68 	ETHTOOL_LINK_MODE_Pause_BIT,
69 	ETHTOOL_LINK_MODE_Asym_Pause_BIT,
70 	ETHTOOL_LINK_MODE_Autoneg_BIT,
71 	ETHTOOL_LINK_MODE_10baseT_Half_BIT,
72 	ETHTOOL_LINK_MODE_10baseT_Full_BIT,
73 	ETHTOOL_LINK_MODE_100baseT_Half_BIT,
74 	ETHTOOL_LINK_MODE_100baseT_Full_BIT,
75 	ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
76 	ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
77 	__ETHTOOL_LINK_MODE_MASK_NBITS,
78 };
79 
80 static const int xpcs_1000basex_features[] = {
81 	ETHTOOL_LINK_MODE_Pause_BIT,
82 	ETHTOOL_LINK_MODE_Asym_Pause_BIT,
83 	ETHTOOL_LINK_MODE_Autoneg_BIT,
84 	ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
85 	__ETHTOOL_LINK_MODE_MASK_NBITS,
86 };
87 
88 static const int xpcs_2500basex_features[] = {
89 	ETHTOOL_LINK_MODE_Pause_BIT,
90 	ETHTOOL_LINK_MODE_Asym_Pause_BIT,
91 	ETHTOOL_LINK_MODE_Autoneg_BIT,
92 	ETHTOOL_LINK_MODE_2500baseX_Full_BIT,
93 	ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
94 	__ETHTOOL_LINK_MODE_MASK_NBITS,
95 };
96 
97 static const phy_interface_t xpcs_usxgmii_interfaces[] = {
98 	PHY_INTERFACE_MODE_USXGMII,
99 };
100 
101 static const phy_interface_t xpcs_10gkr_interfaces[] = {
102 	PHY_INTERFACE_MODE_10GKR,
103 };
104 
105 static const phy_interface_t xpcs_xlgmii_interfaces[] = {
106 	PHY_INTERFACE_MODE_XLGMII,
107 };
108 
109 static const phy_interface_t xpcs_sgmii_interfaces[] = {
110 	PHY_INTERFACE_MODE_SGMII,
111 };
112 
113 static const phy_interface_t xpcs_1000basex_interfaces[] = {
114 	PHY_INTERFACE_MODE_1000BASEX,
115 };
116 
117 static const phy_interface_t xpcs_2500basex_interfaces[] = {
118 	PHY_INTERFACE_MODE_2500BASEX,
119 	PHY_INTERFACE_MODE_MAX,
120 };
121 
122 enum {
123 	DW_XPCS_USXGMII,
124 	DW_XPCS_10GKR,
125 	DW_XPCS_XLGMII,
126 	DW_XPCS_SGMII,
127 	DW_XPCS_1000BASEX,
128 	DW_XPCS_2500BASEX,
129 	DW_XPCS_INTERFACE_MAX,
130 };
131 
132 struct xpcs_compat {
133 	const int *supported;
134 	const phy_interface_t *interface;
135 	int num_interfaces;
136 	int an_mode;
137 	int (*pma_config)(struct dw_xpcs *xpcs);
138 };
139 
140 struct xpcs_id {
141 	u32 id;
142 	u32 mask;
143 	const struct xpcs_compat *compat;
144 };
145 
xpcs_find_compat(const struct xpcs_id * id,phy_interface_t interface)146 static const struct xpcs_compat *xpcs_find_compat(const struct xpcs_id *id,
147 						  phy_interface_t interface)
148 {
149 	int i, j;
150 
151 	for (i = 0; i < DW_XPCS_INTERFACE_MAX; i++) {
152 		const struct xpcs_compat *compat = &id->compat[i];
153 
154 		for (j = 0; j < compat->num_interfaces; j++)
155 			if (compat->interface[j] == interface)
156 				return compat;
157 	}
158 
159 	return NULL;
160 }
161 
xpcs_get_an_mode(struct dw_xpcs * xpcs,phy_interface_t interface)162 int xpcs_get_an_mode(struct dw_xpcs *xpcs, phy_interface_t interface)
163 {
164 	const struct xpcs_compat *compat;
165 
166 	compat = xpcs_find_compat(xpcs->id, interface);
167 	if (!compat)
168 		return -ENODEV;
169 
170 	return compat->an_mode;
171 }
172 EXPORT_SYMBOL_GPL(xpcs_get_an_mode);
173 
__xpcs_linkmode_supported(const struct xpcs_compat * compat,enum ethtool_link_mode_bit_indices linkmode)174 static bool __xpcs_linkmode_supported(const struct xpcs_compat *compat,
175 				      enum ethtool_link_mode_bit_indices linkmode)
176 {
177 	int i;
178 
179 	for (i = 0; compat->supported[i] != __ETHTOOL_LINK_MODE_MASK_NBITS; i++)
180 		if (compat->supported[i] == linkmode)
181 			return true;
182 
183 	return false;
184 }
185 
186 #define xpcs_linkmode_supported(compat, mode) \
187 	__xpcs_linkmode_supported(compat, ETHTOOL_LINK_MODE_ ## mode ## _BIT)
188 
xpcs_read(struct dw_xpcs * xpcs,int dev,u32 reg)189 int xpcs_read(struct dw_xpcs *xpcs, int dev, u32 reg)
190 {
191 	struct mii_bus *bus = xpcs->mdiodev->bus;
192 	int addr = xpcs->mdiodev->addr;
193 
194 	return mdiobus_c45_read(bus, addr, dev, reg);
195 }
196 
xpcs_write(struct dw_xpcs * xpcs,int dev,u32 reg,u16 val)197 int xpcs_write(struct dw_xpcs *xpcs, int dev, u32 reg, u16 val)
198 {
199 	struct mii_bus *bus = xpcs->mdiodev->bus;
200 	int addr = xpcs->mdiodev->addr;
201 
202 	return mdiobus_c45_write(bus, addr, dev, reg, val);
203 }
204 
xpcs_modify_changed(struct dw_xpcs * xpcs,int dev,u32 reg,u16 mask,u16 set)205 static int xpcs_modify_changed(struct dw_xpcs *xpcs, int dev, u32 reg,
206 			       u16 mask, u16 set)
207 {
208 	u32 reg_addr = mdiobus_c45_addr(dev, reg);
209 
210 	return mdiodev_modify_changed(xpcs->mdiodev, reg_addr, mask, set);
211 }
212 
xpcs_read_vendor(struct dw_xpcs * xpcs,int dev,u32 reg)213 static int xpcs_read_vendor(struct dw_xpcs *xpcs, int dev, u32 reg)
214 {
215 	return xpcs_read(xpcs, dev, DW_VENDOR | reg);
216 }
217 
xpcs_write_vendor(struct dw_xpcs * xpcs,int dev,int reg,u16 val)218 static int xpcs_write_vendor(struct dw_xpcs *xpcs, int dev, int reg,
219 			     u16 val)
220 {
221 	return xpcs_write(xpcs, dev, DW_VENDOR | reg, val);
222 }
223 
xpcs_read_vpcs(struct dw_xpcs * xpcs,int reg)224 static int xpcs_read_vpcs(struct dw_xpcs *xpcs, int reg)
225 {
226 	return xpcs_read_vendor(xpcs, MDIO_MMD_PCS, reg);
227 }
228 
xpcs_write_vpcs(struct dw_xpcs * xpcs,int reg,u16 val)229 static int xpcs_write_vpcs(struct dw_xpcs *xpcs, int reg, u16 val)
230 {
231 	return xpcs_write_vendor(xpcs, MDIO_MMD_PCS, reg, val);
232 }
233 
xpcs_poll_reset(struct dw_xpcs * xpcs,int dev)234 static int xpcs_poll_reset(struct dw_xpcs *xpcs, int dev)
235 {
236 	/* Poll until the reset bit clears (50ms per retry == 0.6 sec) */
237 	unsigned int retries = 12;
238 	int ret;
239 
240 	do {
241 		msleep(50);
242 		ret = xpcs_read(xpcs, dev, MDIO_CTRL1);
243 		if (ret < 0)
244 			return ret;
245 	} while (ret & MDIO_CTRL1_RESET && --retries);
246 
247 	return (ret & MDIO_CTRL1_RESET) ? -ETIMEDOUT : 0;
248 }
249 
xpcs_soft_reset(struct dw_xpcs * xpcs,const struct xpcs_compat * compat)250 static int xpcs_soft_reset(struct dw_xpcs *xpcs,
251 			   const struct xpcs_compat *compat)
252 {
253 	int ret, dev;
254 
255 	switch (compat->an_mode) {
256 	case DW_AN_C73:
257 		dev = MDIO_MMD_PCS;
258 		break;
259 	case DW_AN_C37_SGMII:
260 	case DW_2500BASEX:
261 	case DW_AN_C37_1000BASEX:
262 		dev = MDIO_MMD_VEND2;
263 		break;
264 	default:
265 		return -1;
266 	}
267 
268 	ret = xpcs_write(xpcs, dev, MDIO_CTRL1, MDIO_CTRL1_RESET);
269 	if (ret < 0)
270 		return ret;
271 
272 	return xpcs_poll_reset(xpcs, dev);
273 }
274 
275 #define xpcs_warn(__xpcs, __state, __args...) \
276 ({ \
277 	if ((__state)->link) \
278 		dev_warn(&(__xpcs)->mdiodev->dev, ##__args); \
279 })
280 
xpcs_read_fault_c73(struct dw_xpcs * xpcs,struct phylink_link_state * state)281 static int xpcs_read_fault_c73(struct dw_xpcs *xpcs,
282 			       struct phylink_link_state *state)
283 {
284 	int ret;
285 
286 	ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_STAT1);
287 	if (ret < 0)
288 		return ret;
289 
290 	if (ret & MDIO_STAT1_FAULT) {
291 		xpcs_warn(xpcs, state, "Link fault condition detected!\n");
292 		return -EFAULT;
293 	}
294 
295 	ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_STAT2);
296 	if (ret < 0)
297 		return ret;
298 
299 	if (ret & MDIO_STAT2_RXFAULT)
300 		xpcs_warn(xpcs, state, "Receiver fault detected!\n");
301 	if (ret & MDIO_STAT2_TXFAULT)
302 		xpcs_warn(xpcs, state, "Transmitter fault detected!\n");
303 
304 	ret = xpcs_read_vendor(xpcs, MDIO_MMD_PCS, DW_VR_XS_PCS_DIG_STS);
305 	if (ret < 0)
306 		return ret;
307 
308 	if (ret & DW_RXFIFO_ERR) {
309 		xpcs_warn(xpcs, state, "FIFO fault condition detected!\n");
310 		return -EFAULT;
311 	}
312 
313 	ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_PCS_10GBRT_STAT1);
314 	if (ret < 0)
315 		return ret;
316 
317 	if (!(ret & MDIO_PCS_10GBRT_STAT1_BLKLK))
318 		xpcs_warn(xpcs, state, "Link is not locked!\n");
319 
320 	ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_PCS_10GBRT_STAT2);
321 	if (ret < 0)
322 		return ret;
323 
324 	if (ret & MDIO_PCS_10GBRT_STAT2_ERR) {
325 		xpcs_warn(xpcs, state, "Link has errors!\n");
326 		return -EFAULT;
327 	}
328 
329 	return 0;
330 }
331 
xpcs_read_link_c73(struct dw_xpcs * xpcs)332 static int xpcs_read_link_c73(struct dw_xpcs *xpcs)
333 {
334 	bool link = true;
335 	int ret;
336 
337 	ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_STAT1);
338 	if (ret < 0)
339 		return ret;
340 
341 	if (!(ret & MDIO_STAT1_LSTATUS))
342 		link = false;
343 
344 	return link;
345 }
346 
xpcs_get_max_usxgmii_speed(const unsigned long * supported)347 static int xpcs_get_max_usxgmii_speed(const unsigned long *supported)
348 {
349 	int max = SPEED_UNKNOWN;
350 
351 	if (phylink_test(supported, 1000baseKX_Full))
352 		max = SPEED_1000;
353 	if (phylink_test(supported, 2500baseX_Full))
354 		max = SPEED_2500;
355 	if (phylink_test(supported, 10000baseKX4_Full))
356 		max = SPEED_10000;
357 	if (phylink_test(supported, 10000baseKR_Full))
358 		max = SPEED_10000;
359 
360 	return max;
361 }
362 
xpcs_config_usxgmii(struct dw_xpcs * xpcs,int speed)363 static void xpcs_config_usxgmii(struct dw_xpcs *xpcs, int speed)
364 {
365 	int ret, speed_sel;
366 
367 	switch (speed) {
368 	case SPEED_10:
369 		speed_sel = DW_USXGMII_10;
370 		break;
371 	case SPEED_100:
372 		speed_sel = DW_USXGMII_100;
373 		break;
374 	case SPEED_1000:
375 		speed_sel = DW_USXGMII_1000;
376 		break;
377 	case SPEED_2500:
378 		speed_sel = DW_USXGMII_2500;
379 		break;
380 	case SPEED_5000:
381 		speed_sel = DW_USXGMII_5000;
382 		break;
383 	case SPEED_10000:
384 		speed_sel = DW_USXGMII_10000;
385 		break;
386 	default:
387 		/* Nothing to do here */
388 		return;
389 	}
390 
391 	ret = xpcs_read_vpcs(xpcs, MDIO_CTRL1);
392 	if (ret < 0)
393 		goto out;
394 
395 	ret = xpcs_write_vpcs(xpcs, MDIO_CTRL1, ret | DW_USXGMII_EN);
396 	if (ret < 0)
397 		goto out;
398 
399 	ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1);
400 	if (ret < 0)
401 		goto out;
402 
403 	ret &= ~DW_USXGMII_SS_MASK;
404 	ret |= speed_sel | DW_USXGMII_FULL;
405 
406 	ret = xpcs_write(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1, ret);
407 	if (ret < 0)
408 		goto out;
409 
410 	ret = xpcs_read_vpcs(xpcs, MDIO_CTRL1);
411 	if (ret < 0)
412 		goto out;
413 
414 	ret = xpcs_write_vpcs(xpcs, MDIO_CTRL1, ret | DW_USXGMII_RST);
415 	if (ret < 0)
416 		goto out;
417 
418 	return;
419 
420 out:
421 	pr_err("%s: XPCS access returned %pe\n", __func__, ERR_PTR(ret));
422 }
423 
_xpcs_config_aneg_c73(struct dw_xpcs * xpcs,const struct xpcs_compat * compat)424 static int _xpcs_config_aneg_c73(struct dw_xpcs *xpcs,
425 				 const struct xpcs_compat *compat)
426 {
427 	int ret, adv;
428 
429 	/* By default, in USXGMII mode XPCS operates at 10G baud and
430 	 * replicates data to achieve lower speeds. Hereby, in this
431 	 * default configuration we need to advertise all supported
432 	 * modes and not only the ones we want to use.
433 	 */
434 
435 	/* SR_AN_ADV3 */
436 	adv = 0;
437 	if (xpcs_linkmode_supported(compat, 2500baseX_Full))
438 		adv |= DW_C73_2500KX;
439 
440 	/* TODO: 5000baseKR */
441 
442 	ret = xpcs_write(xpcs, MDIO_MMD_AN, DW_SR_AN_ADV3, adv);
443 	if (ret < 0)
444 		return ret;
445 
446 	/* SR_AN_ADV2 */
447 	adv = 0;
448 	if (xpcs_linkmode_supported(compat, 1000baseKX_Full))
449 		adv |= DW_C73_1000KX;
450 	if (xpcs_linkmode_supported(compat, 10000baseKX4_Full))
451 		adv |= DW_C73_10000KX4;
452 	if (xpcs_linkmode_supported(compat, 10000baseKR_Full))
453 		adv |= DW_C73_10000KR;
454 
455 	ret = xpcs_write(xpcs, MDIO_MMD_AN, DW_SR_AN_ADV2, adv);
456 	if (ret < 0)
457 		return ret;
458 
459 	/* SR_AN_ADV1 */
460 	adv = DW_C73_AN_ADV_SF;
461 	if (xpcs_linkmode_supported(compat, Pause))
462 		adv |= DW_C73_PAUSE;
463 	if (xpcs_linkmode_supported(compat, Asym_Pause))
464 		adv |= DW_C73_ASYM_PAUSE;
465 
466 	return xpcs_write(xpcs, MDIO_MMD_AN, DW_SR_AN_ADV1, adv);
467 }
468 
xpcs_config_aneg_c73(struct dw_xpcs * xpcs,const struct xpcs_compat * compat)469 static int xpcs_config_aneg_c73(struct dw_xpcs *xpcs,
470 				const struct xpcs_compat *compat)
471 {
472 	int ret;
473 
474 	ret = _xpcs_config_aneg_c73(xpcs, compat);
475 	if (ret < 0)
476 		return ret;
477 
478 	ret = xpcs_read(xpcs, MDIO_MMD_AN, MDIO_CTRL1);
479 	if (ret < 0)
480 		return ret;
481 
482 	ret |= MDIO_AN_CTRL1_ENABLE | MDIO_AN_CTRL1_RESTART;
483 
484 	return xpcs_write(xpcs, MDIO_MMD_AN, MDIO_CTRL1, ret);
485 }
486 
xpcs_aneg_done_c73(struct dw_xpcs * xpcs,struct phylink_link_state * state,const struct xpcs_compat * compat)487 static int xpcs_aneg_done_c73(struct dw_xpcs *xpcs,
488 			      struct phylink_link_state *state,
489 			      const struct xpcs_compat *compat)
490 {
491 	int ret;
492 
493 	ret = xpcs_read(xpcs, MDIO_MMD_AN, MDIO_STAT1);
494 	if (ret < 0)
495 		return ret;
496 
497 	if (ret & MDIO_AN_STAT1_COMPLETE) {
498 		ret = xpcs_read(xpcs, MDIO_MMD_AN, DW_SR_AN_LP_ABL1);
499 		if (ret < 0)
500 			return ret;
501 
502 		/* Check if Aneg outcome is valid */
503 		if (!(ret & DW_C73_AN_ADV_SF)) {
504 			xpcs_config_aneg_c73(xpcs, compat);
505 			return 0;
506 		}
507 
508 		return 1;
509 	}
510 
511 	return 0;
512 }
513 
xpcs_read_lpa_c73(struct dw_xpcs * xpcs,struct phylink_link_state * state)514 static int xpcs_read_lpa_c73(struct dw_xpcs *xpcs,
515 			     struct phylink_link_state *state)
516 {
517 	int ret;
518 
519 	ret = xpcs_read(xpcs, MDIO_MMD_AN, MDIO_STAT1);
520 	if (ret < 0)
521 		return ret;
522 
523 	if (!(ret & MDIO_AN_STAT1_LPABLE)) {
524 		phylink_clear(state->lp_advertising, Autoneg);
525 		return 0;
526 	}
527 
528 	phylink_set(state->lp_advertising, Autoneg);
529 
530 	/* Clause 73 outcome */
531 	ret = xpcs_read(xpcs, MDIO_MMD_AN, DW_SR_AN_LP_ABL3);
532 	if (ret < 0)
533 		return ret;
534 
535 	if (ret & DW_C73_2500KX)
536 		phylink_set(state->lp_advertising, 2500baseX_Full);
537 
538 	ret = xpcs_read(xpcs, MDIO_MMD_AN, DW_SR_AN_LP_ABL2);
539 	if (ret < 0)
540 		return ret;
541 
542 	if (ret & DW_C73_1000KX)
543 		phylink_set(state->lp_advertising, 1000baseKX_Full);
544 	if (ret & DW_C73_10000KX4)
545 		phylink_set(state->lp_advertising, 10000baseKX4_Full);
546 	if (ret & DW_C73_10000KR)
547 		phylink_set(state->lp_advertising, 10000baseKR_Full);
548 
549 	ret = xpcs_read(xpcs, MDIO_MMD_AN, DW_SR_AN_LP_ABL1);
550 	if (ret < 0)
551 		return ret;
552 
553 	if (ret & DW_C73_PAUSE)
554 		phylink_set(state->lp_advertising, Pause);
555 	if (ret & DW_C73_ASYM_PAUSE)
556 		phylink_set(state->lp_advertising, Asym_Pause);
557 
558 	linkmode_and(state->lp_advertising, state->lp_advertising,
559 		     state->advertising);
560 	return 0;
561 }
562 
xpcs_resolve_lpa_c73(struct dw_xpcs * xpcs,struct phylink_link_state * state)563 static void xpcs_resolve_lpa_c73(struct dw_xpcs *xpcs,
564 				 struct phylink_link_state *state)
565 {
566 	int max_speed = xpcs_get_max_usxgmii_speed(state->lp_advertising);
567 
568 	state->pause = MLO_PAUSE_TX | MLO_PAUSE_RX;
569 	state->speed = max_speed;
570 	state->duplex = DUPLEX_FULL;
571 }
572 
xpcs_get_max_xlgmii_speed(struct dw_xpcs * xpcs,struct phylink_link_state * state)573 static int xpcs_get_max_xlgmii_speed(struct dw_xpcs *xpcs,
574 				     struct phylink_link_state *state)
575 {
576 	unsigned long *adv = state->advertising;
577 	int speed = SPEED_UNKNOWN;
578 	int bit;
579 
580 	for_each_set_bit(bit, adv, __ETHTOOL_LINK_MODE_MASK_NBITS) {
581 		int new_speed = SPEED_UNKNOWN;
582 
583 		switch (bit) {
584 		case ETHTOOL_LINK_MODE_25000baseCR_Full_BIT:
585 		case ETHTOOL_LINK_MODE_25000baseKR_Full_BIT:
586 		case ETHTOOL_LINK_MODE_25000baseSR_Full_BIT:
587 			new_speed = SPEED_25000;
588 			break;
589 		case ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT:
590 		case ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT:
591 		case ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT:
592 		case ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT:
593 			new_speed = SPEED_40000;
594 			break;
595 		case ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT:
596 		case ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT:
597 		case ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT:
598 		case ETHTOOL_LINK_MODE_50000baseKR_Full_BIT:
599 		case ETHTOOL_LINK_MODE_50000baseSR_Full_BIT:
600 		case ETHTOOL_LINK_MODE_50000baseCR_Full_BIT:
601 		case ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT:
602 		case ETHTOOL_LINK_MODE_50000baseDR_Full_BIT:
603 			new_speed = SPEED_50000;
604 			break;
605 		case ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT:
606 		case ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT:
607 		case ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT:
608 		case ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT:
609 		case ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT:
610 		case ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT:
611 		case ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT:
612 		case ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT:
613 		case ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT:
614 			new_speed = SPEED_100000;
615 			break;
616 		default:
617 			continue;
618 		}
619 
620 		if (new_speed > speed)
621 			speed = new_speed;
622 	}
623 
624 	return speed;
625 }
626 
xpcs_resolve_pma(struct dw_xpcs * xpcs,struct phylink_link_state * state)627 static void xpcs_resolve_pma(struct dw_xpcs *xpcs,
628 			     struct phylink_link_state *state)
629 {
630 	state->pause = MLO_PAUSE_TX | MLO_PAUSE_RX;
631 	state->duplex = DUPLEX_FULL;
632 
633 	switch (state->interface) {
634 	case PHY_INTERFACE_MODE_10GKR:
635 		state->speed = SPEED_10000;
636 		break;
637 	case PHY_INTERFACE_MODE_XLGMII:
638 		state->speed = xpcs_get_max_xlgmii_speed(xpcs, state);
639 		break;
640 	default:
641 		state->speed = SPEED_UNKNOWN;
642 		break;
643 	}
644 }
645 
xpcs_validate(struct phylink_pcs * pcs,unsigned long * supported,const struct phylink_link_state * state)646 static int xpcs_validate(struct phylink_pcs *pcs, unsigned long *supported,
647 			 const struct phylink_link_state *state)
648 {
649 	__ETHTOOL_DECLARE_LINK_MODE_MASK(xpcs_supported) = { 0, };
650 	const struct xpcs_compat *compat;
651 	struct dw_xpcs *xpcs;
652 	int i;
653 
654 	xpcs = phylink_pcs_to_xpcs(pcs);
655 	compat = xpcs_find_compat(xpcs->id, state->interface);
656 
657 	/* Populate the supported link modes for this PHY interface type.
658 	 * FIXME: what about the port modes and autoneg bit? This masks
659 	 * all those away.
660 	 */
661 	if (compat)
662 		for (i = 0; compat->supported[i] != __ETHTOOL_LINK_MODE_MASK_NBITS; i++)
663 			set_bit(compat->supported[i], xpcs_supported);
664 
665 	linkmode_and(supported, supported, xpcs_supported);
666 
667 	return 0;
668 }
669 
xpcs_get_interfaces(struct dw_xpcs * xpcs,unsigned long * interfaces)670 void xpcs_get_interfaces(struct dw_xpcs *xpcs, unsigned long *interfaces)
671 {
672 	int i, j;
673 
674 	for (i = 0; i < DW_XPCS_INTERFACE_MAX; i++) {
675 		const struct xpcs_compat *compat = &xpcs->id->compat[i];
676 
677 		for (j = 0; j < compat->num_interfaces; j++)
678 			if (compat->interface[j] < PHY_INTERFACE_MODE_MAX)
679 				__set_bit(compat->interface[j], interfaces);
680 	}
681 }
682 EXPORT_SYMBOL_GPL(xpcs_get_interfaces);
683 
xpcs_config_eee(struct dw_xpcs * xpcs,int mult_fact_100ns,int enable)684 int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int enable)
685 {
686 	int ret;
687 
688 	ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL0);
689 	if (ret < 0)
690 		return ret;
691 
692 	if (enable) {
693 	/* Enable EEE */
694 		ret = DW_VR_MII_EEE_LTX_EN | DW_VR_MII_EEE_LRX_EN |
695 		      DW_VR_MII_EEE_TX_QUIET_EN | DW_VR_MII_EEE_RX_QUIET_EN |
696 		      DW_VR_MII_EEE_TX_EN_CTRL | DW_VR_MII_EEE_RX_EN_CTRL |
697 		      mult_fact_100ns << DW_VR_MII_EEE_MULT_FACT_100NS_SHIFT;
698 	} else {
699 		ret &= ~(DW_VR_MII_EEE_LTX_EN | DW_VR_MII_EEE_LRX_EN |
700 		       DW_VR_MII_EEE_TX_QUIET_EN | DW_VR_MII_EEE_RX_QUIET_EN |
701 		       DW_VR_MII_EEE_TX_EN_CTRL | DW_VR_MII_EEE_RX_EN_CTRL |
702 		       DW_VR_MII_EEE_MULT_FACT_100NS);
703 	}
704 
705 	ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL0, ret);
706 	if (ret < 0)
707 		return ret;
708 
709 	ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL1);
710 	if (ret < 0)
711 		return ret;
712 
713 	if (enable)
714 		ret |= DW_VR_MII_EEE_TRN_LPI;
715 	else
716 		ret &= ~DW_VR_MII_EEE_TRN_LPI;
717 
718 	return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL1, ret);
719 }
720 EXPORT_SYMBOL_GPL(xpcs_config_eee);
721 
xpcs_config_aneg_c37_sgmii(struct dw_xpcs * xpcs,unsigned int mode)722 static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, unsigned int mode)
723 {
724 	int ret, mdio_ctrl;
725 
726 	/* For AN for C37 SGMII mode, the settings are :-
727 	 * 1) VR_MII_MMD_CTRL Bit(12) [AN_ENABLE] = 0b (Disable SGMII AN in case
728 	      it is already enabled)
729 	 * 2) VR_MII_AN_CTRL Bit(2:1)[PCS_MODE] = 10b (SGMII AN)
730 	 * 3) VR_MII_AN_CTRL Bit(3) [TX_CONFIG] = 0b (MAC side SGMII)
731 	 *    DW xPCS used with DW EQoS MAC is always MAC side SGMII.
732 	 * 4) VR_MII_DIG_CTRL1 Bit(9) [MAC_AUTO_SW] = 1b (Automatic
733 	 *    speed/duplex mode change by HW after SGMII AN complete)
734 	 * 5) VR_MII_MMD_CTRL Bit(12) [AN_ENABLE] = 1b (Enable SGMII AN)
735 	 *
736 	 * Note: Since it is MAC side SGMII, there is no need to set
737 	 *	 SR_MII_AN_ADV. MAC side SGMII receives AN Tx Config from
738 	 *	 PHY about the link state change after C28 AN is completed
739 	 *	 between PHY and Link Partner. There is also no need to
740 	 *	 trigger AN restart for MAC-side SGMII.
741 	 */
742 	mdio_ctrl = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL);
743 	if (mdio_ctrl < 0)
744 		return mdio_ctrl;
745 
746 	if (mdio_ctrl & AN_CL37_EN) {
747 		ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL,
748 				 mdio_ctrl & ~AN_CL37_EN);
749 		if (ret < 0)
750 			return ret;
751 	}
752 
753 	ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL);
754 	if (ret < 0)
755 		return ret;
756 
757 	ret &= ~(DW_VR_MII_PCS_MODE_MASK | DW_VR_MII_TX_CONFIG_MASK);
758 	ret |= (DW_VR_MII_PCS_MODE_C37_SGMII <<
759 		DW_VR_MII_AN_CTRL_PCS_MODE_SHIFT &
760 		DW_VR_MII_PCS_MODE_MASK);
761 	ret |= (DW_VR_MII_TX_CONFIG_MAC_SIDE_SGMII <<
762 		DW_VR_MII_AN_CTRL_TX_CONFIG_SHIFT &
763 		DW_VR_MII_TX_CONFIG_MASK);
764 	ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL, ret);
765 	if (ret < 0)
766 		return ret;
767 
768 	ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1);
769 	if (ret < 0)
770 		return ret;
771 
772 	if (phylink_autoneg_inband(mode))
773 		ret |= DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW;
774 	else
775 		ret &= ~DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW;
776 
777 	ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret);
778 	if (ret < 0)
779 		return ret;
780 
781 	if (phylink_autoneg_inband(mode))
782 		ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL,
783 				 mdio_ctrl | AN_CL37_EN);
784 
785 	return ret;
786 }
787 
xpcs_config_aneg_c37_1000basex(struct dw_xpcs * xpcs,unsigned int mode,const unsigned long * advertising)788 static int xpcs_config_aneg_c37_1000basex(struct dw_xpcs *xpcs, unsigned int mode,
789 					  const unsigned long *advertising)
790 {
791 	phy_interface_t interface = PHY_INTERFACE_MODE_1000BASEX;
792 	int ret, mdio_ctrl, adv;
793 	bool changed = 0;
794 
795 	/* According to Chap 7.12, to set 1000BASE-X C37 AN, AN must
796 	 * be disabled first:-
797 	 * 1) VR_MII_MMD_CTRL Bit(12)[AN_ENABLE] = 0b
798 	 * 2) VR_MII_AN_CTRL Bit(2:1)[PCS_MODE] = 00b (1000BASE-X C37)
799 	 */
800 	mdio_ctrl = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL);
801 	if (mdio_ctrl < 0)
802 		return mdio_ctrl;
803 
804 	if (mdio_ctrl & AN_CL37_EN) {
805 		ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL,
806 				 mdio_ctrl & ~AN_CL37_EN);
807 		if (ret < 0)
808 			return ret;
809 	}
810 
811 	ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL);
812 	if (ret < 0)
813 		return ret;
814 
815 	ret &= ~DW_VR_MII_PCS_MODE_MASK;
816 	ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL, ret);
817 	if (ret < 0)
818 		return ret;
819 
820 	/* Check for advertising changes and update the C45 MII ADV
821 	 * register accordingly.
822 	 */
823 	adv = phylink_mii_c22_pcs_encode_advertisement(interface,
824 						       advertising);
825 	if (adv >= 0) {
826 		ret = xpcs_modify_changed(xpcs, MDIO_MMD_VEND2,
827 					  MII_ADVERTISE, 0xffff, adv);
828 		if (ret < 0)
829 			return ret;
830 
831 		changed = ret;
832 	}
833 
834 	/* Clear CL37 AN complete status */
835 	ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_INTR_STS, 0);
836 	if (ret < 0)
837 		return ret;
838 
839 	if (phylink_autoneg_inband(mode) &&
840 	    linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, advertising)) {
841 		ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL,
842 				 mdio_ctrl | AN_CL37_EN);
843 		if (ret < 0)
844 			return ret;
845 	}
846 
847 	return changed;
848 }
849 
xpcs_config_2500basex(struct dw_xpcs * xpcs)850 static int xpcs_config_2500basex(struct dw_xpcs *xpcs)
851 {
852 	int ret;
853 
854 	ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1);
855 	if (ret < 0)
856 		return ret;
857 	ret |= DW_VR_MII_DIG_CTRL1_2G5_EN;
858 	ret &= ~DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW;
859 	ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret);
860 	if (ret < 0)
861 		return ret;
862 
863 	ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL);
864 	if (ret < 0)
865 		return ret;
866 	ret &= ~AN_CL37_EN;
867 	ret |= SGMII_SPEED_SS6;
868 	ret &= ~SGMII_SPEED_SS13;
869 	return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL, ret);
870 }
871 
xpcs_do_config(struct dw_xpcs * xpcs,phy_interface_t interface,unsigned int mode,const unsigned long * advertising)872 int xpcs_do_config(struct dw_xpcs *xpcs, phy_interface_t interface,
873 		   unsigned int mode, const unsigned long *advertising)
874 {
875 	const struct xpcs_compat *compat;
876 	int ret;
877 
878 	compat = xpcs_find_compat(xpcs->id, interface);
879 	if (!compat)
880 		return -ENODEV;
881 
882 	switch (compat->an_mode) {
883 	case DW_AN_C73:
884 		if (test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, advertising)) {
885 			ret = xpcs_config_aneg_c73(xpcs, compat);
886 			if (ret)
887 				return ret;
888 		}
889 		break;
890 	case DW_AN_C37_SGMII:
891 		ret = xpcs_config_aneg_c37_sgmii(xpcs, mode);
892 		if (ret)
893 			return ret;
894 		break;
895 	case DW_AN_C37_1000BASEX:
896 		ret = xpcs_config_aneg_c37_1000basex(xpcs, mode,
897 						     advertising);
898 		if (ret)
899 			return ret;
900 		break;
901 	case DW_2500BASEX:
902 		ret = xpcs_config_2500basex(xpcs);
903 		if (ret)
904 			return ret;
905 		break;
906 	default:
907 		return -1;
908 	}
909 
910 	if (compat->pma_config) {
911 		ret = compat->pma_config(xpcs);
912 		if (ret)
913 			return ret;
914 	}
915 
916 	return 0;
917 }
918 EXPORT_SYMBOL_GPL(xpcs_do_config);
919 
xpcs_config(struct phylink_pcs * pcs,unsigned int mode,phy_interface_t interface,const unsigned long * advertising,bool permit_pause_to_mac)920 static int xpcs_config(struct phylink_pcs *pcs, unsigned int mode,
921 		       phy_interface_t interface,
922 		       const unsigned long *advertising,
923 		       bool permit_pause_to_mac)
924 {
925 	struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs);
926 
927 	return xpcs_do_config(xpcs, interface, mode, advertising);
928 }
929 
xpcs_get_state_c73(struct dw_xpcs * xpcs,struct phylink_link_state * state,const struct xpcs_compat * compat)930 static int xpcs_get_state_c73(struct dw_xpcs *xpcs,
931 			      struct phylink_link_state *state,
932 			      const struct xpcs_compat *compat)
933 {
934 	int ret;
935 
936 	/* Link needs to be read first ... */
937 	state->link = xpcs_read_link_c73(xpcs) > 0 ? 1 : 0;
938 
939 	/* ... and then we check the faults. */
940 	ret = xpcs_read_fault_c73(xpcs, state);
941 	if (ret) {
942 		ret = xpcs_soft_reset(xpcs, compat);
943 		if (ret)
944 			return ret;
945 
946 		state->link = 0;
947 
948 		return xpcs_do_config(xpcs, state->interface, MLO_AN_INBAND, NULL);
949 	}
950 
951 	if (state->an_enabled && xpcs_aneg_done_c73(xpcs, state, compat)) {
952 		state->an_complete = true;
953 		xpcs_read_lpa_c73(xpcs, state);
954 		xpcs_resolve_lpa_c73(xpcs, state);
955 	} else if (state->an_enabled) {
956 		state->link = 0;
957 	} else if (state->link) {
958 		xpcs_resolve_pma(xpcs, state);
959 	}
960 
961 	return 0;
962 }
963 
xpcs_get_state_c37_sgmii(struct dw_xpcs * xpcs,struct phylink_link_state * state)964 static int xpcs_get_state_c37_sgmii(struct dw_xpcs *xpcs,
965 				    struct phylink_link_state *state)
966 {
967 	int ret;
968 
969 	/* Reset link_state */
970 	state->link = false;
971 	state->speed = SPEED_UNKNOWN;
972 	state->duplex = DUPLEX_UNKNOWN;
973 	state->pause = 0;
974 
975 	/* For C37 SGMII mode, we check DW_VR_MII_AN_INTR_STS for link
976 	 * status, speed and duplex.
977 	 */
978 	ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_INTR_STS);
979 	if (ret < 0)
980 		return ret;
981 
982 	if (ret & DW_VR_MII_C37_ANSGM_SP_LNKSTS) {
983 		int speed_value;
984 
985 		state->link = true;
986 
987 		speed_value = (ret & DW_VR_MII_AN_STS_C37_ANSGM_SP) >>
988 			      DW_VR_MII_AN_STS_C37_ANSGM_SP_SHIFT;
989 		if (speed_value == DW_VR_MII_C37_ANSGM_SP_1000)
990 			state->speed = SPEED_1000;
991 		else if (speed_value == DW_VR_MII_C37_ANSGM_SP_100)
992 			state->speed = SPEED_100;
993 		else
994 			state->speed = SPEED_10;
995 
996 		if (ret & DW_VR_MII_AN_STS_C37_ANSGM_FD)
997 			state->duplex = DUPLEX_FULL;
998 		else
999 			state->duplex = DUPLEX_HALF;
1000 	}
1001 
1002 	return 0;
1003 }
1004 
xpcs_get_state_c37_1000basex(struct dw_xpcs * xpcs,struct phylink_link_state * state)1005 static int xpcs_get_state_c37_1000basex(struct dw_xpcs *xpcs,
1006 					struct phylink_link_state *state)
1007 {
1008 	int lpa, bmsr;
1009 
1010 	if (state->an_enabled) {
1011 		/* Reset link state */
1012 		state->link = false;
1013 
1014 		lpa = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_LPA);
1015 		if (lpa < 0 || lpa & LPA_RFAULT)
1016 			return lpa;
1017 
1018 		bmsr = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_BMSR);
1019 		if (bmsr < 0)
1020 			return bmsr;
1021 
1022 		phylink_mii_c22_pcs_decode_state(state, bmsr, lpa);
1023 	}
1024 
1025 	return 0;
1026 }
1027 
xpcs_get_state(struct phylink_pcs * pcs,struct phylink_link_state * state)1028 static void xpcs_get_state(struct phylink_pcs *pcs,
1029 			   struct phylink_link_state *state)
1030 {
1031 	struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs);
1032 	const struct xpcs_compat *compat;
1033 	int ret;
1034 
1035 	compat = xpcs_find_compat(xpcs->id, state->interface);
1036 	if (!compat)
1037 		return;
1038 
1039 	switch (compat->an_mode) {
1040 	case DW_AN_C73:
1041 		ret = xpcs_get_state_c73(xpcs, state, compat);
1042 		if (ret) {
1043 			pr_err("xpcs_get_state_c73 returned %pe\n",
1044 			       ERR_PTR(ret));
1045 			return;
1046 		}
1047 		break;
1048 	case DW_AN_C37_SGMII:
1049 		ret = xpcs_get_state_c37_sgmii(xpcs, state);
1050 		if (ret) {
1051 			pr_err("xpcs_get_state_c37_sgmii returned %pe\n",
1052 			       ERR_PTR(ret));
1053 		}
1054 		break;
1055 	case DW_AN_C37_1000BASEX:
1056 		ret = xpcs_get_state_c37_1000basex(xpcs, state);
1057 		if (ret) {
1058 			pr_err("xpcs_get_state_c37_1000basex returned %pe\n",
1059 			       ERR_PTR(ret));
1060 		}
1061 		break;
1062 	default:
1063 		return;
1064 	}
1065 }
1066 
xpcs_link_up_sgmii(struct dw_xpcs * xpcs,unsigned int mode,int speed,int duplex)1067 static void xpcs_link_up_sgmii(struct dw_xpcs *xpcs, unsigned int mode,
1068 			       int speed, int duplex)
1069 {
1070 	int val, ret;
1071 
1072 	if (phylink_autoneg_inband(mode))
1073 		return;
1074 
1075 	val = mii_bmcr_encode_fixed(speed, duplex);
1076 	ret = xpcs_write(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1, val);
1077 	if (ret)
1078 		pr_err("%s: xpcs_write returned %pe\n", __func__, ERR_PTR(ret));
1079 }
1080 
xpcs_link_up_1000basex(struct dw_xpcs * xpcs,unsigned int mode,int speed,int duplex)1081 static void xpcs_link_up_1000basex(struct dw_xpcs *xpcs, unsigned int mode,
1082 				   int speed, int duplex)
1083 {
1084 	int val, ret;
1085 
1086 	if (phylink_autoneg_inband(mode))
1087 		return;
1088 
1089 	switch (speed) {
1090 	case SPEED_1000:
1091 		val = BMCR_SPEED1000;
1092 		break;
1093 	case SPEED_100:
1094 	case SPEED_10:
1095 	default:
1096 		pr_err("%s: speed = %d\n", __func__, speed);
1097 		return;
1098 	}
1099 
1100 	if (duplex == DUPLEX_FULL)
1101 		val |= BMCR_FULLDPLX;
1102 	else
1103 		pr_err("%s: half duplex not supported\n", __func__);
1104 
1105 	ret = xpcs_write(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1, val);
1106 	if (ret)
1107 		pr_err("%s: xpcs_write returned %pe\n", __func__, ERR_PTR(ret));
1108 }
1109 
xpcs_link_up(struct phylink_pcs * pcs,unsigned int mode,phy_interface_t interface,int speed,int duplex)1110 void xpcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
1111 		  phy_interface_t interface, int speed, int duplex)
1112 {
1113 	struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs);
1114 
1115 	if (interface == PHY_INTERFACE_MODE_USXGMII)
1116 		return xpcs_config_usxgmii(xpcs, speed);
1117 	if (interface == PHY_INTERFACE_MODE_SGMII)
1118 		return xpcs_link_up_sgmii(xpcs, mode, speed, duplex);
1119 	if (interface == PHY_INTERFACE_MODE_1000BASEX)
1120 		return xpcs_link_up_1000basex(xpcs, mode, speed, duplex);
1121 }
1122 EXPORT_SYMBOL_GPL(xpcs_link_up);
1123 
xpcs_an_restart(struct phylink_pcs * pcs)1124 static void xpcs_an_restart(struct phylink_pcs *pcs)
1125 {
1126 	struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs);
1127 	int ret;
1128 
1129 	ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1);
1130 	if (ret >= 0) {
1131 		ret |= BMCR_ANRESTART;
1132 		xpcs_write(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1, ret);
1133 	}
1134 }
1135 
xpcs_get_id(struct dw_xpcs * xpcs)1136 static u32 xpcs_get_id(struct dw_xpcs *xpcs)
1137 {
1138 	int ret;
1139 	u32 id;
1140 
1141 	/* First, search C73 PCS using PCS MMD */
1142 	ret = xpcs_read(xpcs, MDIO_MMD_PCS, MII_PHYSID1);
1143 	if (ret < 0)
1144 		return 0xffffffff;
1145 
1146 	id = ret << 16;
1147 
1148 	ret = xpcs_read(xpcs, MDIO_MMD_PCS, MII_PHYSID2);
1149 	if (ret < 0)
1150 		return 0xffffffff;
1151 
1152 	/* If Device IDs are not all zeros or all ones,
1153 	 * we found C73 AN-type device
1154 	 */
1155 	if ((id | ret) && (id | ret) != 0xffffffff)
1156 		return id | ret;
1157 
1158 	/* Next, search C37 PCS using Vendor-Specific MII MMD */
1159 	ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_PHYSID1);
1160 	if (ret < 0)
1161 		return 0xffffffff;
1162 
1163 	id = ret << 16;
1164 
1165 	ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_PHYSID2);
1166 	if (ret < 0)
1167 		return 0xffffffff;
1168 
1169 	/* If Device IDs are not all zeros, we found C37 AN-type device */
1170 	if (id | ret)
1171 		return id | ret;
1172 
1173 	return 0xffffffff;
1174 }
1175 
1176 static const struct xpcs_compat synopsys_xpcs_compat[DW_XPCS_INTERFACE_MAX] = {
1177 	[DW_XPCS_USXGMII] = {
1178 		.supported = xpcs_usxgmii_features,
1179 		.interface = xpcs_usxgmii_interfaces,
1180 		.num_interfaces = ARRAY_SIZE(xpcs_usxgmii_interfaces),
1181 		.an_mode = DW_AN_C73,
1182 	},
1183 	[DW_XPCS_10GKR] = {
1184 		.supported = xpcs_10gkr_features,
1185 		.interface = xpcs_10gkr_interfaces,
1186 		.num_interfaces = ARRAY_SIZE(xpcs_10gkr_interfaces),
1187 		.an_mode = DW_AN_C73,
1188 	},
1189 	[DW_XPCS_XLGMII] = {
1190 		.supported = xpcs_xlgmii_features,
1191 		.interface = xpcs_xlgmii_interfaces,
1192 		.num_interfaces = ARRAY_SIZE(xpcs_xlgmii_interfaces),
1193 		.an_mode = DW_AN_C73,
1194 	},
1195 	[DW_XPCS_SGMII] = {
1196 		.supported = xpcs_sgmii_features,
1197 		.interface = xpcs_sgmii_interfaces,
1198 		.num_interfaces = ARRAY_SIZE(xpcs_sgmii_interfaces),
1199 		.an_mode = DW_AN_C37_SGMII,
1200 	},
1201 	[DW_XPCS_1000BASEX] = {
1202 		.supported = xpcs_1000basex_features,
1203 		.interface = xpcs_1000basex_interfaces,
1204 		.num_interfaces = ARRAY_SIZE(xpcs_1000basex_interfaces),
1205 		.an_mode = DW_AN_C37_1000BASEX,
1206 	},
1207 	[DW_XPCS_2500BASEX] = {
1208 		.supported = xpcs_2500basex_features,
1209 		.interface = xpcs_2500basex_interfaces,
1210 		.num_interfaces = ARRAY_SIZE(xpcs_2500basex_features),
1211 		.an_mode = DW_2500BASEX,
1212 	},
1213 };
1214 
1215 static const struct xpcs_compat nxp_sja1105_xpcs_compat[DW_XPCS_INTERFACE_MAX] = {
1216 	[DW_XPCS_SGMII] = {
1217 		.supported = xpcs_sgmii_features,
1218 		.interface = xpcs_sgmii_interfaces,
1219 		.num_interfaces = ARRAY_SIZE(xpcs_sgmii_interfaces),
1220 		.an_mode = DW_AN_C37_SGMII,
1221 		.pma_config = nxp_sja1105_sgmii_pma_config,
1222 	},
1223 };
1224 
1225 static const struct xpcs_compat nxp_sja1110_xpcs_compat[DW_XPCS_INTERFACE_MAX] = {
1226 	[DW_XPCS_SGMII] = {
1227 		.supported = xpcs_sgmii_features,
1228 		.interface = xpcs_sgmii_interfaces,
1229 		.num_interfaces = ARRAY_SIZE(xpcs_sgmii_interfaces),
1230 		.an_mode = DW_AN_C37_SGMII,
1231 		.pma_config = nxp_sja1110_sgmii_pma_config,
1232 	},
1233 	[DW_XPCS_2500BASEX] = {
1234 		.supported = xpcs_2500basex_features,
1235 		.interface = xpcs_2500basex_interfaces,
1236 		.num_interfaces = ARRAY_SIZE(xpcs_2500basex_interfaces),
1237 		.an_mode = DW_2500BASEX,
1238 		.pma_config = nxp_sja1110_2500basex_pma_config,
1239 	},
1240 };
1241 
1242 static const struct xpcs_id xpcs_id_list[] = {
1243 	{
1244 		.id = SYNOPSYS_XPCS_ID,
1245 		.mask = SYNOPSYS_XPCS_MASK,
1246 		.compat = synopsys_xpcs_compat,
1247 	}, {
1248 		.id = NXP_SJA1105_XPCS_ID,
1249 		.mask = SYNOPSYS_XPCS_MASK,
1250 		.compat = nxp_sja1105_xpcs_compat,
1251 	}, {
1252 		.id = NXP_SJA1110_XPCS_ID,
1253 		.mask = SYNOPSYS_XPCS_MASK,
1254 		.compat = nxp_sja1110_xpcs_compat,
1255 	},
1256 };
1257 
1258 static const struct phylink_pcs_ops xpcs_phylink_ops = {
1259 	.pcs_validate = xpcs_validate,
1260 	.pcs_config = xpcs_config,
1261 	.pcs_get_state = xpcs_get_state,
1262 	.pcs_an_restart = xpcs_an_restart,
1263 	.pcs_link_up = xpcs_link_up,
1264 };
1265 
xpcs_create(struct mdio_device * mdiodev,phy_interface_t interface)1266 struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
1267 			    phy_interface_t interface)
1268 {
1269 	struct dw_xpcs *xpcs;
1270 	u32 xpcs_id;
1271 	int i, ret;
1272 
1273 	xpcs = kzalloc(sizeof(*xpcs), GFP_KERNEL);
1274 	if (!xpcs)
1275 		return ERR_PTR(-ENOMEM);
1276 
1277 	xpcs->mdiodev = mdiodev;
1278 
1279 	xpcs_id = xpcs_get_id(xpcs);
1280 
1281 	for (i = 0; i < ARRAY_SIZE(xpcs_id_list); i++) {
1282 		const struct xpcs_id *entry = &xpcs_id_list[i];
1283 		const struct xpcs_compat *compat;
1284 
1285 		if ((xpcs_id & entry->mask) != entry->id)
1286 			continue;
1287 
1288 		xpcs->id = entry;
1289 
1290 		compat = xpcs_find_compat(entry, interface);
1291 		if (!compat) {
1292 			ret = -ENODEV;
1293 			goto out;
1294 		}
1295 
1296 		xpcs->pcs.ops = &xpcs_phylink_ops;
1297 		xpcs->pcs.poll = true;
1298 
1299 		ret = xpcs_soft_reset(xpcs, compat);
1300 		if (ret)
1301 			goto out;
1302 
1303 		return xpcs;
1304 	}
1305 
1306 	ret = -ENODEV;
1307 
1308 out:
1309 	kfree(xpcs);
1310 
1311 	return ERR_PTR(ret);
1312 }
1313 EXPORT_SYMBOL_GPL(xpcs_create);
1314 
xpcs_destroy(struct dw_xpcs * xpcs)1315 void xpcs_destroy(struct dw_xpcs *xpcs)
1316 {
1317 	kfree(xpcs);
1318 }
1319 EXPORT_SYMBOL_GPL(xpcs_destroy);
1320 
1321 MODULE_LICENSE("GPL v2");
1322