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
15 #define SYNOPSYS_XPCS_USXGMII_ID 0x7996ced0
16 #define SYNOPSYS_XPCS_10GKR_ID 0x7996ced0
17 #define SYNOPSYS_XPCS_XLGMII_ID 0x7996ced0
18 #define SYNOPSYS_XPCS_SGMII_ID 0x7996ced0
19 #define SYNOPSYS_XPCS_MASK 0xffffffff
20
21 /* Vendor regs access */
22 #define DW_VENDOR BIT(15)
23
24 /* VR_XS_PCS */
25 #define DW_USXGMII_RST BIT(10)
26 #define DW_USXGMII_EN BIT(9)
27 #define DW_VR_XS_PCS_DIG_STS 0x0010
28 #define DW_RXFIFO_ERR GENMASK(6, 5)
29
30 /* SR_MII */
31 #define DW_USXGMII_FULL BIT(8)
32 #define DW_USXGMII_SS_MASK (BIT(13) | BIT(6) | BIT(5))
33 #define DW_USXGMII_10000 (BIT(13) | BIT(6))
34 #define DW_USXGMII_5000 (BIT(13) | BIT(5))
35 #define DW_USXGMII_2500 (BIT(5))
36 #define DW_USXGMII_1000 (BIT(6))
37 #define DW_USXGMII_100 (BIT(13))
38 #define DW_USXGMII_10 (0)
39
40 /* SR_AN */
41 #define DW_SR_AN_ADV1 0x10
42 #define DW_SR_AN_ADV2 0x11
43 #define DW_SR_AN_ADV3 0x12
44 #define DW_SR_AN_LP_ABL1 0x13
45 #define DW_SR_AN_LP_ABL2 0x14
46 #define DW_SR_AN_LP_ABL3 0x15
47
48 /* Clause 73 Defines */
49 /* AN_LP_ABL1 */
50 #define DW_C73_PAUSE BIT(10)
51 #define DW_C73_ASYM_PAUSE BIT(11)
52 #define DW_C73_AN_ADV_SF 0x1
53 /* AN_LP_ABL2 */
54 #define DW_C73_1000KX BIT(5)
55 #define DW_C73_10000KX4 BIT(6)
56 #define DW_C73_10000KR BIT(7)
57 /* AN_LP_ABL3 */
58 #define DW_C73_2500KX BIT(0)
59 #define DW_C73_5000KR BIT(1)
60
61 /* Clause 37 Defines */
62 /* VR MII MMD registers offsets */
63 #define DW_VR_MII_DIG_CTRL1 0x8000
64 #define DW_VR_MII_AN_CTRL 0x8001
65 #define DW_VR_MII_AN_INTR_STS 0x8002
66
67 /* VR_MII_DIG_CTRL1 */
68 #define DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW BIT(9)
69
70 /* VR_MII_AN_CTRL */
71 #define DW_VR_MII_AN_CTRL_TX_CONFIG_SHIFT 3
72 #define DW_VR_MII_TX_CONFIG_MASK BIT(3)
73 #define DW_VR_MII_TX_CONFIG_PHY_SIDE_SGMII 0x1
74 #define DW_VR_MII_TX_CONFIG_MAC_SIDE_SGMII 0x0
75 #define DW_VR_MII_AN_CTRL_PCS_MODE_SHIFT 1
76 #define DW_VR_MII_PCS_MODE_MASK GENMASK(2, 1)
77 #define DW_VR_MII_PCS_MODE_C37_1000BASEX 0x0
78 #define DW_VR_MII_PCS_MODE_C37_SGMII 0x2
79
80 /* VR_MII_AN_INTR_STS */
81 #define DW_VR_MII_AN_STS_C37_ANSGM_FD BIT(1)
82 #define DW_VR_MII_AN_STS_C37_ANSGM_SP_SHIFT 2
83 #define DW_VR_MII_AN_STS_C37_ANSGM_SP GENMASK(3, 2)
84 #define DW_VR_MII_C37_ANSGM_SP_10 0x0
85 #define DW_VR_MII_C37_ANSGM_SP_100 0x1
86 #define DW_VR_MII_C37_ANSGM_SP_1000 0x2
87 #define DW_VR_MII_C37_ANSGM_SP_LNKSTS BIT(4)
88
89 static const int xpcs_usxgmii_features[] = {
90 ETHTOOL_LINK_MODE_Pause_BIT,
91 ETHTOOL_LINK_MODE_Asym_Pause_BIT,
92 ETHTOOL_LINK_MODE_Autoneg_BIT,
93 ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
94 ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
95 ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
96 ETHTOOL_LINK_MODE_2500baseX_Full_BIT,
97 __ETHTOOL_LINK_MODE_MASK_NBITS,
98 };
99
100 static const int xpcs_10gkr_features[] = {
101 ETHTOOL_LINK_MODE_Pause_BIT,
102 ETHTOOL_LINK_MODE_Asym_Pause_BIT,
103 ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
104 __ETHTOOL_LINK_MODE_MASK_NBITS,
105 };
106
107 static const int xpcs_xlgmii_features[] = {
108 ETHTOOL_LINK_MODE_Pause_BIT,
109 ETHTOOL_LINK_MODE_Asym_Pause_BIT,
110 ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
111 ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
112 ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
113 ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
114 ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT,
115 ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT,
116 ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT,
117 ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT,
118 ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT,
119 ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT,
120 ETHTOOL_LINK_MODE_50000baseKR_Full_BIT,
121 ETHTOOL_LINK_MODE_50000baseSR_Full_BIT,
122 ETHTOOL_LINK_MODE_50000baseCR_Full_BIT,
123 ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT,
124 ETHTOOL_LINK_MODE_50000baseDR_Full_BIT,
125 ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
126 ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT,
127 ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
128 ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT,
129 ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT,
130 ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT,
131 ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT,
132 ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT,
133 ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT,
134 __ETHTOOL_LINK_MODE_MASK_NBITS,
135 };
136
137 static const int xpcs_sgmii_features[] = {
138 ETHTOOL_LINK_MODE_10baseT_Half_BIT,
139 ETHTOOL_LINK_MODE_10baseT_Full_BIT,
140 ETHTOOL_LINK_MODE_100baseT_Half_BIT,
141 ETHTOOL_LINK_MODE_100baseT_Full_BIT,
142 ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
143 ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
144 __ETHTOOL_LINK_MODE_MASK_NBITS,
145 };
146
147 static const phy_interface_t xpcs_usxgmii_interfaces[] = {
148 PHY_INTERFACE_MODE_USXGMII,
149 PHY_INTERFACE_MODE_MAX,
150 };
151
152 static const phy_interface_t xpcs_10gkr_interfaces[] = {
153 PHY_INTERFACE_MODE_10GKR,
154 PHY_INTERFACE_MODE_MAX,
155 };
156
157 static const phy_interface_t xpcs_xlgmii_interfaces[] = {
158 PHY_INTERFACE_MODE_XLGMII,
159 PHY_INTERFACE_MODE_MAX,
160 };
161
162 static const phy_interface_t xpcs_sgmii_interfaces[] = {
163 PHY_INTERFACE_MODE_SGMII,
164 PHY_INTERFACE_MODE_MAX,
165 };
166
167 static struct xpcs_id {
168 u32 id;
169 u32 mask;
170 const int *supported;
171 const phy_interface_t *interface;
172 int an_mode;
173 } xpcs_id_list[] = {
174 {
175 .id = SYNOPSYS_XPCS_USXGMII_ID,
176 .mask = SYNOPSYS_XPCS_MASK,
177 .supported = xpcs_usxgmii_features,
178 .interface = xpcs_usxgmii_interfaces,
179 .an_mode = DW_AN_C73,
180 }, {
181 .id = SYNOPSYS_XPCS_10GKR_ID,
182 .mask = SYNOPSYS_XPCS_MASK,
183 .supported = xpcs_10gkr_features,
184 .interface = xpcs_10gkr_interfaces,
185 .an_mode = DW_AN_C73,
186 }, {
187 .id = SYNOPSYS_XPCS_XLGMII_ID,
188 .mask = SYNOPSYS_XPCS_MASK,
189 .supported = xpcs_xlgmii_features,
190 .interface = xpcs_xlgmii_interfaces,
191 .an_mode = DW_AN_C73,
192 }, {
193 .id = SYNOPSYS_XPCS_SGMII_ID,
194 .mask = SYNOPSYS_XPCS_MASK,
195 .supported = xpcs_sgmii_features,
196 .interface = xpcs_sgmii_interfaces,
197 .an_mode = DW_AN_C37_SGMII,
198 },
199 };
200
xpcs_read(struct mdio_xpcs_args * xpcs,int dev,u32 reg)201 static int xpcs_read(struct mdio_xpcs_args *xpcs, int dev, u32 reg)
202 {
203 u32 reg_addr = MII_ADDR_C45 | dev << 16 | reg;
204
205 return mdiobus_read(xpcs->bus, xpcs->addr, reg_addr);
206 }
207
xpcs_write(struct mdio_xpcs_args * xpcs,int dev,u32 reg,u16 val)208 static int xpcs_write(struct mdio_xpcs_args *xpcs, int dev, u32 reg, u16 val)
209 {
210 u32 reg_addr = MII_ADDR_C45 | dev << 16 | reg;
211
212 return mdiobus_write(xpcs->bus, xpcs->addr, reg_addr, val);
213 }
214
xpcs_read_vendor(struct mdio_xpcs_args * xpcs,int dev,u32 reg)215 static int xpcs_read_vendor(struct mdio_xpcs_args *xpcs, int dev, u32 reg)
216 {
217 return xpcs_read(xpcs, dev, DW_VENDOR | reg);
218 }
219
xpcs_write_vendor(struct mdio_xpcs_args * xpcs,int dev,int reg,u16 val)220 static int xpcs_write_vendor(struct mdio_xpcs_args *xpcs, int dev, int reg,
221 u16 val)
222 {
223 return xpcs_write(xpcs, dev, DW_VENDOR | reg, val);
224 }
225
xpcs_read_vpcs(struct mdio_xpcs_args * xpcs,int reg)226 static int xpcs_read_vpcs(struct mdio_xpcs_args *xpcs, int reg)
227 {
228 return xpcs_read_vendor(xpcs, MDIO_MMD_PCS, reg);
229 }
230
xpcs_write_vpcs(struct mdio_xpcs_args * xpcs,int reg,u16 val)231 static int xpcs_write_vpcs(struct mdio_xpcs_args *xpcs, int reg, u16 val)
232 {
233 return xpcs_write_vendor(xpcs, MDIO_MMD_PCS, reg, val);
234 }
235
xpcs_poll_reset(struct mdio_xpcs_args * xpcs,int dev)236 static int xpcs_poll_reset(struct mdio_xpcs_args *xpcs, int dev)
237 {
238 /* Poll until the reset bit clears (50ms per retry == 0.6 sec) */
239 unsigned int retries = 12;
240 int ret;
241
242 do {
243 msleep(50);
244 ret = xpcs_read(xpcs, dev, MDIO_CTRL1);
245 if (ret < 0)
246 return ret;
247 } while (ret & MDIO_CTRL1_RESET && --retries);
248
249 return (ret & MDIO_CTRL1_RESET) ? -ETIMEDOUT : 0;
250 }
251
xpcs_soft_reset(struct mdio_xpcs_args * xpcs)252 static int xpcs_soft_reset(struct mdio_xpcs_args *xpcs)
253 {
254 int ret, dev;
255
256 switch (xpcs->an_mode) {
257 case DW_AN_C73:
258 dev = MDIO_MMD_PCS;
259 break;
260 case DW_AN_C37_SGMII:
261 dev = MDIO_MMD_VEND2;
262 break;
263 default:
264 return -1;
265 }
266
267 ret = xpcs_write(xpcs, dev, MDIO_CTRL1, MDIO_CTRL1_RESET);
268 if (ret < 0)
269 return ret;
270
271 return xpcs_poll_reset(xpcs, dev);
272 }
273
274 #define xpcs_warn(__xpcs, __state, __args...) \
275 ({ \
276 if ((__state)->link) \
277 dev_warn(&(__xpcs)->bus->dev, ##__args); \
278 })
279
xpcs_read_fault_c73(struct mdio_xpcs_args * xpcs,struct phylink_link_state * state)280 static int xpcs_read_fault_c73(struct mdio_xpcs_args *xpcs,
281 struct phylink_link_state *state)
282 {
283 int ret;
284
285 ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_STAT1);
286 if (ret < 0)
287 return ret;
288
289 if (ret & MDIO_STAT1_FAULT) {
290 xpcs_warn(xpcs, state, "Link fault condition detected!\n");
291 return -EFAULT;
292 }
293
294 ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_STAT2);
295 if (ret < 0)
296 return ret;
297
298 if (ret & MDIO_STAT2_RXFAULT)
299 xpcs_warn(xpcs, state, "Receiver fault detected!\n");
300 if (ret & MDIO_STAT2_TXFAULT)
301 xpcs_warn(xpcs, state, "Transmitter fault detected!\n");
302
303 ret = xpcs_read_vendor(xpcs, MDIO_MMD_PCS, DW_VR_XS_PCS_DIG_STS);
304 if (ret < 0)
305 return ret;
306
307 if (ret & DW_RXFIFO_ERR) {
308 xpcs_warn(xpcs, state, "FIFO fault condition detected!\n");
309 return -EFAULT;
310 }
311
312 ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_PCS_10GBRT_STAT1);
313 if (ret < 0)
314 return ret;
315
316 if (!(ret & MDIO_PCS_10GBRT_STAT1_BLKLK))
317 xpcs_warn(xpcs, state, "Link is not locked!\n");
318
319 ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_PCS_10GBRT_STAT2);
320 if (ret < 0)
321 return ret;
322
323 if (ret & MDIO_PCS_10GBRT_STAT2_ERR) {
324 xpcs_warn(xpcs, state, "Link has errors!\n");
325 return -EFAULT;
326 }
327
328 return 0;
329 }
330
xpcs_read_link_c73(struct mdio_xpcs_args * xpcs,bool an)331 static int xpcs_read_link_c73(struct mdio_xpcs_args *xpcs, bool an)
332 {
333 bool link = true;
334 int ret;
335
336 ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_STAT1);
337 if (ret < 0)
338 return ret;
339
340 if (!(ret & MDIO_STAT1_LSTATUS))
341 link = false;
342
343 if (an) {
344 ret = xpcs_read(xpcs, MDIO_MMD_AN, MDIO_STAT1);
345 if (ret < 0)
346 return ret;
347
348 if (!(ret & MDIO_STAT1_LSTATUS))
349 link = false;
350 }
351
352 return link;
353 }
354
xpcs_get_max_usxgmii_speed(const unsigned long * supported)355 static int xpcs_get_max_usxgmii_speed(const unsigned long *supported)
356 {
357 int max = SPEED_UNKNOWN;
358
359 if (phylink_test(supported, 1000baseKX_Full))
360 max = SPEED_1000;
361 if (phylink_test(supported, 2500baseX_Full))
362 max = SPEED_2500;
363 if (phylink_test(supported, 10000baseKX4_Full))
364 max = SPEED_10000;
365 if (phylink_test(supported, 10000baseKR_Full))
366 max = SPEED_10000;
367
368 return max;
369 }
370
xpcs_config_usxgmii(struct mdio_xpcs_args * xpcs,int speed)371 static int xpcs_config_usxgmii(struct mdio_xpcs_args *xpcs, int speed)
372 {
373 int ret, speed_sel;
374
375 switch (speed) {
376 case SPEED_10:
377 speed_sel = DW_USXGMII_10;
378 break;
379 case SPEED_100:
380 speed_sel = DW_USXGMII_100;
381 break;
382 case SPEED_1000:
383 speed_sel = DW_USXGMII_1000;
384 break;
385 case SPEED_2500:
386 speed_sel = DW_USXGMII_2500;
387 break;
388 case SPEED_5000:
389 speed_sel = DW_USXGMII_5000;
390 break;
391 case SPEED_10000:
392 speed_sel = DW_USXGMII_10000;
393 break;
394 default:
395 /* Nothing to do here */
396 return -EINVAL;
397 }
398
399 ret = xpcs_read_vpcs(xpcs, MDIO_CTRL1);
400 if (ret < 0)
401 return ret;
402
403 ret = xpcs_write_vpcs(xpcs, MDIO_CTRL1, ret | DW_USXGMII_EN);
404 if (ret < 0)
405 return ret;
406
407 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1);
408 if (ret < 0)
409 return ret;
410
411 ret &= ~DW_USXGMII_SS_MASK;
412 ret |= speed_sel | DW_USXGMII_FULL;
413
414 ret = xpcs_write(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1, ret);
415 if (ret < 0)
416 return ret;
417
418 ret = xpcs_read_vpcs(xpcs, MDIO_CTRL1);
419 if (ret < 0)
420 return ret;
421
422 return xpcs_write_vpcs(xpcs, MDIO_CTRL1, ret | DW_USXGMII_RST);
423 }
424
_xpcs_config_aneg_c73(struct mdio_xpcs_args * xpcs)425 static int _xpcs_config_aneg_c73(struct mdio_xpcs_args *xpcs)
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 (phylink_test(xpcs->supported, 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 (phylink_test(xpcs->supported, 1000baseKX_Full))
449 adv |= DW_C73_1000KX;
450 if (phylink_test(xpcs->supported, 10000baseKX4_Full))
451 adv |= DW_C73_10000KX4;
452 if (phylink_test(xpcs->supported, 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 (phylink_test(xpcs->supported, Pause))
462 adv |= DW_C73_PAUSE;
463 if (phylink_test(xpcs->supported, 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 mdio_xpcs_args * xpcs)469 static int xpcs_config_aneg_c73(struct mdio_xpcs_args *xpcs)
470 {
471 int ret;
472
473 ret = _xpcs_config_aneg_c73(xpcs);
474 if (ret < 0)
475 return ret;
476
477 ret = xpcs_read(xpcs, MDIO_MMD_AN, MDIO_CTRL1);
478 if (ret < 0)
479 return ret;
480
481 ret |= MDIO_AN_CTRL1_ENABLE | MDIO_AN_CTRL1_RESTART;
482
483 return xpcs_write(xpcs, MDIO_MMD_AN, MDIO_CTRL1, ret);
484 }
485
xpcs_aneg_done_c73(struct mdio_xpcs_args * xpcs,struct phylink_link_state * state)486 static int xpcs_aneg_done_c73(struct mdio_xpcs_args *xpcs,
487 struct phylink_link_state *state)
488 {
489 int ret;
490
491 ret = xpcs_read(xpcs, MDIO_MMD_AN, MDIO_STAT1);
492 if (ret < 0)
493 return ret;
494
495 if (ret & MDIO_AN_STAT1_COMPLETE) {
496 ret = xpcs_read(xpcs, MDIO_MMD_AN, DW_SR_AN_LP_ABL1);
497 if (ret < 0)
498 return ret;
499
500 /* Check if Aneg outcome is valid */
501 if (!(ret & DW_C73_AN_ADV_SF)) {
502 xpcs_config_aneg_c73(xpcs);
503 return 0;
504 }
505
506 return 1;
507 }
508
509 return 0;
510 }
511
xpcs_read_lpa_c73(struct mdio_xpcs_args * xpcs,struct phylink_link_state * state)512 static int xpcs_read_lpa_c73(struct mdio_xpcs_args *xpcs,
513 struct phylink_link_state *state)
514 {
515 int ret;
516
517 ret = xpcs_read(xpcs, MDIO_MMD_AN, MDIO_STAT1);
518 if (ret < 0)
519 return ret;
520
521 if (!(ret & MDIO_AN_STAT1_LPABLE)) {
522 phylink_clear(state->lp_advertising, Autoneg);
523 return 0;
524 }
525
526 phylink_set(state->lp_advertising, Autoneg);
527
528 /* Clause 73 outcome */
529 ret = xpcs_read(xpcs, MDIO_MMD_AN, DW_SR_AN_LP_ABL3);
530 if (ret < 0)
531 return ret;
532
533 if (ret & DW_C73_2500KX)
534 phylink_set(state->lp_advertising, 2500baseX_Full);
535
536 ret = xpcs_read(xpcs, MDIO_MMD_AN, DW_SR_AN_LP_ABL2);
537 if (ret < 0)
538 return ret;
539
540 if (ret & DW_C73_1000KX)
541 phylink_set(state->lp_advertising, 1000baseKX_Full);
542 if (ret & DW_C73_10000KX4)
543 phylink_set(state->lp_advertising, 10000baseKX4_Full);
544 if (ret & DW_C73_10000KR)
545 phylink_set(state->lp_advertising, 10000baseKR_Full);
546
547 ret = xpcs_read(xpcs, MDIO_MMD_AN, DW_SR_AN_LP_ABL1);
548 if (ret < 0)
549 return ret;
550
551 if (ret & DW_C73_PAUSE)
552 phylink_set(state->lp_advertising, Pause);
553 if (ret & DW_C73_ASYM_PAUSE)
554 phylink_set(state->lp_advertising, Asym_Pause);
555
556 linkmode_and(state->lp_advertising, state->lp_advertising,
557 state->advertising);
558 return 0;
559 }
560
xpcs_resolve_lpa_c73(struct mdio_xpcs_args * xpcs,struct phylink_link_state * state)561 static void xpcs_resolve_lpa_c73(struct mdio_xpcs_args *xpcs,
562 struct phylink_link_state *state)
563 {
564 int max_speed = xpcs_get_max_usxgmii_speed(state->lp_advertising);
565
566 state->pause = MLO_PAUSE_TX | MLO_PAUSE_RX;
567 state->speed = max_speed;
568 state->duplex = DUPLEX_FULL;
569 }
570
xpcs_get_max_xlgmii_speed(struct mdio_xpcs_args * xpcs,struct phylink_link_state * state)571 static int xpcs_get_max_xlgmii_speed(struct mdio_xpcs_args *xpcs,
572 struct phylink_link_state *state)
573 {
574 unsigned long *adv = state->advertising;
575 int speed = SPEED_UNKNOWN;
576 int bit;
577
578 for_each_set_bit(bit, adv, __ETHTOOL_LINK_MODE_MASK_NBITS) {
579 int new_speed = SPEED_UNKNOWN;
580
581 switch (bit) {
582 case ETHTOOL_LINK_MODE_25000baseCR_Full_BIT:
583 case ETHTOOL_LINK_MODE_25000baseKR_Full_BIT:
584 case ETHTOOL_LINK_MODE_25000baseSR_Full_BIT:
585 new_speed = SPEED_25000;
586 break;
587 case ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT:
588 case ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT:
589 case ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT:
590 case ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT:
591 new_speed = SPEED_40000;
592 break;
593 case ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT:
594 case ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT:
595 case ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT:
596 case ETHTOOL_LINK_MODE_50000baseKR_Full_BIT:
597 case ETHTOOL_LINK_MODE_50000baseSR_Full_BIT:
598 case ETHTOOL_LINK_MODE_50000baseCR_Full_BIT:
599 case ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT:
600 case ETHTOOL_LINK_MODE_50000baseDR_Full_BIT:
601 new_speed = SPEED_50000;
602 break;
603 case ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT:
604 case ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT:
605 case ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT:
606 case ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT:
607 case ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT:
608 case ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT:
609 case ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT:
610 case ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT:
611 case ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT:
612 new_speed = SPEED_100000;
613 break;
614 default:
615 continue;
616 }
617
618 if (new_speed > speed)
619 speed = new_speed;
620 }
621
622 return speed;
623 }
624
xpcs_resolve_pma(struct mdio_xpcs_args * xpcs,struct phylink_link_state * state)625 static void xpcs_resolve_pma(struct mdio_xpcs_args *xpcs,
626 struct phylink_link_state *state)
627 {
628 state->pause = MLO_PAUSE_TX | MLO_PAUSE_RX;
629 state->duplex = DUPLEX_FULL;
630
631 switch (state->interface) {
632 case PHY_INTERFACE_MODE_10GKR:
633 state->speed = SPEED_10000;
634 break;
635 case PHY_INTERFACE_MODE_XLGMII:
636 state->speed = xpcs_get_max_xlgmii_speed(xpcs, state);
637 break;
638 default:
639 state->speed = SPEED_UNKNOWN;
640 break;
641 }
642 }
643
xpcs_validate(struct mdio_xpcs_args * xpcs,unsigned long * supported,struct phylink_link_state * state)644 static int xpcs_validate(struct mdio_xpcs_args *xpcs,
645 unsigned long *supported,
646 struct phylink_link_state *state)
647 {
648 linkmode_and(supported, supported, xpcs->supported);
649 linkmode_and(state->advertising, state->advertising, xpcs->supported);
650 return 0;
651 }
652
xpcs_config_aneg_c37_sgmii(struct mdio_xpcs_args * xpcs)653 static int xpcs_config_aneg_c37_sgmii(struct mdio_xpcs_args *xpcs)
654 {
655 int ret;
656
657 /* For AN for C37 SGMII mode, the settings are :-
658 * 1) VR_MII_AN_CTRL Bit(2:1)[PCS_MODE] = 10b (SGMII AN)
659 * 2) VR_MII_AN_CTRL Bit(3) [TX_CONFIG] = 0b (MAC side SGMII)
660 * DW xPCS used with DW EQoS MAC is always MAC side SGMII.
661 * 3) VR_MII_DIG_CTRL1 Bit(9) [MAC_AUTO_SW] = 1b (Automatic
662 * speed/duplex mode change by HW after SGMII AN complete)
663 *
664 * Note: Since it is MAC side SGMII, there is no need to set
665 * SR_MII_AN_ADV. MAC side SGMII receives AN Tx Config from
666 * PHY about the link state change after C28 AN is completed
667 * between PHY and Link Partner. There is also no need to
668 * trigger AN restart for MAC-side SGMII.
669 */
670 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL);
671 if (ret < 0)
672 return ret;
673
674 ret &= ~(DW_VR_MII_PCS_MODE_MASK | DW_VR_MII_TX_CONFIG_MASK);
675 ret |= (DW_VR_MII_PCS_MODE_C37_SGMII <<
676 DW_VR_MII_AN_CTRL_PCS_MODE_SHIFT &
677 DW_VR_MII_PCS_MODE_MASK);
678 ret |= (DW_VR_MII_TX_CONFIG_MAC_SIDE_SGMII <<
679 DW_VR_MII_AN_CTRL_TX_CONFIG_SHIFT &
680 DW_VR_MII_TX_CONFIG_MASK);
681 ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL, ret);
682 if (ret < 0)
683 return ret;
684
685 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1);
686 if (ret < 0)
687 return ret;
688
689 ret |= DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW;
690
691 return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret);
692 }
693
xpcs_config(struct mdio_xpcs_args * xpcs,const struct phylink_link_state * state)694 static int xpcs_config(struct mdio_xpcs_args *xpcs,
695 const struct phylink_link_state *state)
696 {
697 int ret;
698
699 switch (xpcs->an_mode) {
700 case DW_AN_C73:
701 if (state->an_enabled) {
702 ret = xpcs_config_aneg_c73(xpcs);
703 if (ret)
704 return ret;
705 }
706 break;
707 case DW_AN_C37_SGMII:
708 ret = xpcs_config_aneg_c37_sgmii(xpcs);
709 if (ret)
710 return ret;
711 break;
712 default:
713 return -1;
714 }
715
716 return 0;
717 }
718
xpcs_get_state_c73(struct mdio_xpcs_args * xpcs,struct phylink_link_state * state)719 static int xpcs_get_state_c73(struct mdio_xpcs_args *xpcs,
720 struct phylink_link_state *state)
721 {
722 int ret;
723
724 /* Link needs to be read first ... */
725 state->link = xpcs_read_link_c73(xpcs, state->an_enabled) > 0 ? 1 : 0;
726
727 /* ... and then we check the faults. */
728 ret = xpcs_read_fault_c73(xpcs, state);
729 if (ret) {
730 ret = xpcs_soft_reset(xpcs);
731 if (ret)
732 return ret;
733
734 state->link = 0;
735
736 return xpcs_config(xpcs, state);
737 }
738
739 if (state->an_enabled && xpcs_aneg_done_c73(xpcs, state)) {
740 state->an_complete = true;
741 xpcs_read_lpa_c73(xpcs, state);
742 xpcs_resolve_lpa_c73(xpcs, state);
743 } else if (state->an_enabled) {
744 state->link = 0;
745 } else if (state->link) {
746 xpcs_resolve_pma(xpcs, state);
747 }
748
749 return 0;
750 }
751
xpcs_get_state_c37_sgmii(struct mdio_xpcs_args * xpcs,struct phylink_link_state * state)752 static int xpcs_get_state_c37_sgmii(struct mdio_xpcs_args *xpcs,
753 struct phylink_link_state *state)
754 {
755 int ret;
756
757 /* Reset link_state */
758 state->link = false;
759 state->speed = SPEED_UNKNOWN;
760 state->duplex = DUPLEX_UNKNOWN;
761 state->pause = 0;
762
763 /* For C37 SGMII mode, we check DW_VR_MII_AN_INTR_STS for link
764 * status, speed and duplex.
765 */
766 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_INTR_STS);
767 if (ret < 0)
768 return false;
769
770 if (ret & DW_VR_MII_C37_ANSGM_SP_LNKSTS) {
771 int speed_value;
772
773 state->link = true;
774
775 speed_value = (ret & DW_VR_MII_AN_STS_C37_ANSGM_SP) >>
776 DW_VR_MII_AN_STS_C37_ANSGM_SP_SHIFT;
777 if (speed_value == DW_VR_MII_C37_ANSGM_SP_1000)
778 state->speed = SPEED_1000;
779 else if (speed_value == DW_VR_MII_C37_ANSGM_SP_100)
780 state->speed = SPEED_100;
781 else
782 state->speed = SPEED_10;
783
784 if (ret & DW_VR_MII_AN_STS_C37_ANSGM_FD)
785 state->duplex = DUPLEX_FULL;
786 else
787 state->duplex = DUPLEX_HALF;
788 }
789
790 return 0;
791 }
792
xpcs_get_state(struct mdio_xpcs_args * xpcs,struct phylink_link_state * state)793 static int xpcs_get_state(struct mdio_xpcs_args *xpcs,
794 struct phylink_link_state *state)
795 {
796 int ret;
797
798 switch (xpcs->an_mode) {
799 case DW_AN_C73:
800 ret = xpcs_get_state_c73(xpcs, state);
801 if (ret)
802 return ret;
803 break;
804 case DW_AN_C37_SGMII:
805 ret = xpcs_get_state_c37_sgmii(xpcs, state);
806 if (ret)
807 return ret;
808 break;
809 default:
810 return -1;
811 }
812
813 return 0;
814 }
815
xpcs_link_up(struct mdio_xpcs_args * xpcs,int speed,phy_interface_t interface)816 static int xpcs_link_up(struct mdio_xpcs_args *xpcs, int speed,
817 phy_interface_t interface)
818 {
819 if (interface == PHY_INTERFACE_MODE_USXGMII)
820 return xpcs_config_usxgmii(xpcs, speed);
821
822 return 0;
823 }
824
xpcs_get_id(struct mdio_xpcs_args * xpcs)825 static u32 xpcs_get_id(struct mdio_xpcs_args *xpcs)
826 {
827 int ret;
828 u32 id;
829
830 /* First, search C73 PCS using PCS MMD */
831 ret = xpcs_read(xpcs, MDIO_MMD_PCS, MII_PHYSID1);
832 if (ret < 0)
833 return 0xffffffff;
834
835 id = ret << 16;
836
837 ret = xpcs_read(xpcs, MDIO_MMD_PCS, MII_PHYSID2);
838 if (ret < 0)
839 return 0xffffffff;
840
841 /* If Device IDs are not all zeros, we found C73 AN-type device */
842 if (id | ret)
843 return id | ret;
844
845 /* Next, search C37 PCS using Vendor-Specific MII MMD */
846 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_PHYSID1);
847 if (ret < 0)
848 return 0xffffffff;
849
850 id = ret << 16;
851
852 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_PHYSID2);
853 if (ret < 0)
854 return 0xffffffff;
855
856 /* If Device IDs are not all zeros, we found C37 AN-type device */
857 if (id | ret)
858 return id | ret;
859
860 return 0xffffffff;
861 }
862
xpcs_check_features(struct mdio_xpcs_args * xpcs,struct xpcs_id * match,phy_interface_t interface)863 static bool xpcs_check_features(struct mdio_xpcs_args *xpcs,
864 struct xpcs_id *match,
865 phy_interface_t interface)
866 {
867 int i;
868
869 for (i = 0; match->interface[i] != PHY_INTERFACE_MODE_MAX; i++) {
870 if (match->interface[i] == interface)
871 break;
872 }
873
874 if (match->interface[i] == PHY_INTERFACE_MODE_MAX)
875 return false;
876
877 for (i = 0; match->supported[i] != __ETHTOOL_LINK_MODE_MASK_NBITS; i++)
878 set_bit(match->supported[i], xpcs->supported);
879
880 xpcs->an_mode = match->an_mode;
881
882 return true;
883 }
884
xpcs_probe(struct mdio_xpcs_args * xpcs,phy_interface_t interface)885 static int xpcs_probe(struct mdio_xpcs_args *xpcs, phy_interface_t interface)
886 {
887 u32 xpcs_id = xpcs_get_id(xpcs);
888 struct xpcs_id *match = NULL;
889 int i;
890
891 for (i = 0; i < ARRAY_SIZE(xpcs_id_list); i++) {
892 struct xpcs_id *entry = &xpcs_id_list[i];
893
894 if ((xpcs_id & entry->mask) == entry->id) {
895 match = entry;
896
897 if (xpcs_check_features(xpcs, match, interface))
898 return xpcs_soft_reset(xpcs);
899 }
900 }
901
902 return -ENODEV;
903 }
904
905 static struct mdio_xpcs_ops xpcs_ops = {
906 .validate = xpcs_validate,
907 .config = xpcs_config,
908 .get_state = xpcs_get_state,
909 .link_up = xpcs_link_up,
910 .probe = xpcs_probe,
911 };
912
mdio_xpcs_get_ops(void)913 struct mdio_xpcs_ops *mdio_xpcs_get_ops(void)
914 {
915 return &xpcs_ops;
916 }
917 EXPORT_SYMBOL_GPL(mdio_xpcs_get_ops);
918
919 MODULE_LICENSE("GPL v2");
920