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