1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2020 Synopsys, Inc. and/or its affiliates.
4 * Synopsys DesignWare XPCS helpers
6 * Author: Jose Abreu <Jose.Abreu@synopsys.com>
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>
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
21 /* Vendor regs access */
22 #define DW_VENDOR BIT(15)
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)
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)
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
48 /* Clause 73 Defines */
50 #define DW_C73_PAUSE BIT(10)
51 #define DW_C73_ASYM_PAUSE BIT(11)
52 #define DW_C73_AN_ADV_SF 0x1
54 #define DW_C73_1000KX BIT(5)
55 #define DW_C73_10000KX4 BIT(6)
56 #define DW_C73_10000KR BIT(7)
58 #define DW_C73_2500KX BIT(0)
59 #define DW_C73_5000KR BIT(1)
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
67 /* VR_MII_DIG_CTRL1 */
68 #define DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW BIT(9)
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
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)
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,
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,
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,
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,
147 static const phy_interface_t xpcs_usxgmii_interfaces[] = {
148 PHY_INTERFACE_MODE_USXGMII,
149 PHY_INTERFACE_MODE_MAX,
152 static const phy_interface_t xpcs_10gkr_interfaces[] = {
153 PHY_INTERFACE_MODE_10GKR,
154 PHY_INTERFACE_MODE_MAX,
157 static const phy_interface_t xpcs_xlgmii_interfaces[] = {
158 PHY_INTERFACE_MODE_XLGMII,
159 PHY_INTERFACE_MODE_MAX,
162 static const phy_interface_t xpcs_sgmii_interfaces[] = {
163 PHY_INTERFACE_MODE_SGMII,
164 PHY_INTERFACE_MODE_MAX,
167 static struct xpcs_id {
170 const int *supported;
171 const phy_interface_t *interface;
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,
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,
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,
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,
201 static int xpcs_read(struct mdio_xpcs_args *xpcs, int dev, u32 reg)
203 u32 reg_addr = MII_ADDR_C45 | dev << 16 | reg;
205 return mdiobus_read(xpcs->bus, xpcs->addr, reg_addr);
208 static int xpcs_write(struct mdio_xpcs_args *xpcs, int dev, u32 reg, u16 val)
210 u32 reg_addr = MII_ADDR_C45 | dev << 16 | reg;
212 return mdiobus_write(xpcs->bus, xpcs->addr, reg_addr, val);
215 static int xpcs_read_vendor(struct mdio_xpcs_args *xpcs, int dev, u32 reg)
217 return xpcs_read(xpcs, dev, DW_VENDOR | reg);
220 static int xpcs_write_vendor(struct mdio_xpcs_args *xpcs, int dev, int reg,
223 return xpcs_write(xpcs, dev, DW_VENDOR | reg, val);
226 static int xpcs_read_vpcs(struct mdio_xpcs_args *xpcs, int reg)
228 return xpcs_read_vendor(xpcs, MDIO_MMD_PCS, reg);
231 static int xpcs_write_vpcs(struct mdio_xpcs_args *xpcs, int reg, u16 val)
233 return xpcs_write_vendor(xpcs, MDIO_MMD_PCS, reg, val);
236 static int xpcs_poll_reset(struct mdio_xpcs_args *xpcs, int dev)
238 /* Poll until the reset bit clears (50ms per retry == 0.6 sec) */
239 unsigned int retries = 12;
244 ret = xpcs_read(xpcs, dev, MDIO_CTRL1);
247 } while (ret & MDIO_CTRL1_RESET && --retries);
249 return (ret & MDIO_CTRL1_RESET) ? -ETIMEDOUT : 0;
252 static int xpcs_soft_reset(struct mdio_xpcs_args *xpcs)
256 switch (xpcs->an_mode) {
260 case DW_AN_C37_SGMII:
261 dev = MDIO_MMD_VEND2;
267 ret = xpcs_write(xpcs, dev, MDIO_CTRL1, MDIO_CTRL1_RESET);
271 return xpcs_poll_reset(xpcs, dev);
274 #define xpcs_warn(__xpcs, __state, __args...) \
276 if ((__state)->link) \
277 dev_warn(&(__xpcs)->bus->dev, ##__args); \
280 static int xpcs_read_fault_c73(struct mdio_xpcs_args *xpcs,
281 struct phylink_link_state *state)
285 ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_STAT1);
289 if (ret & MDIO_STAT1_FAULT) {
290 xpcs_warn(xpcs, state, "Link fault condition detected!\n");
294 ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_STAT2);
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");
303 ret = xpcs_read_vendor(xpcs, MDIO_MMD_PCS, DW_VR_XS_PCS_DIG_STS);
307 if (ret & DW_RXFIFO_ERR) {
308 xpcs_warn(xpcs, state, "FIFO fault condition detected!\n");
312 ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_PCS_10GBRT_STAT1);
316 if (!(ret & MDIO_PCS_10GBRT_STAT1_BLKLK))
317 xpcs_warn(xpcs, state, "Link is not locked!\n");
319 ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_PCS_10GBRT_STAT2);
323 if (ret & MDIO_PCS_10GBRT_STAT2_ERR) {
324 xpcs_warn(xpcs, state, "Link has errors!\n");
331 static int xpcs_read_link_c73(struct mdio_xpcs_args *xpcs, bool an)
336 ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_STAT1);
340 if (!(ret & MDIO_STAT1_LSTATUS))
344 ret = xpcs_read(xpcs, MDIO_MMD_AN, MDIO_STAT1);
348 if (!(ret & MDIO_STAT1_LSTATUS))
355 static int xpcs_get_max_usxgmii_speed(const unsigned long *supported)
357 int max = SPEED_UNKNOWN;
359 if (phylink_test(supported, 1000baseKX_Full))
361 if (phylink_test(supported, 2500baseX_Full))
363 if (phylink_test(supported, 10000baseKX4_Full))
365 if (phylink_test(supported, 10000baseKR_Full))
371 static int xpcs_config_usxgmii(struct mdio_xpcs_args *xpcs, int speed)
377 speed_sel = DW_USXGMII_10;
380 speed_sel = DW_USXGMII_100;
383 speed_sel = DW_USXGMII_1000;
386 speed_sel = DW_USXGMII_2500;
389 speed_sel = DW_USXGMII_5000;
392 speed_sel = DW_USXGMII_10000;
395 /* Nothing to do here */
399 ret = xpcs_read_vpcs(xpcs, MDIO_CTRL1);
403 ret = xpcs_write_vpcs(xpcs, MDIO_CTRL1, ret | DW_USXGMII_EN);
407 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1);
411 ret &= ~DW_USXGMII_SS_MASK;
412 ret |= speed_sel | DW_USXGMII_FULL;
414 ret = xpcs_write(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1, ret);
418 ret = xpcs_read_vpcs(xpcs, MDIO_CTRL1);
422 return xpcs_write_vpcs(xpcs, MDIO_CTRL1, ret | DW_USXGMII_RST);
425 static int _xpcs_config_aneg_c73(struct mdio_xpcs_args *xpcs)
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.
437 if (phylink_test(xpcs->supported, 2500baseX_Full))
438 adv |= DW_C73_2500KX;
440 /* TODO: 5000baseKR */
442 ret = xpcs_write(xpcs, MDIO_MMD_AN, DW_SR_AN_ADV3, adv);
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;
455 ret = xpcs_write(xpcs, MDIO_MMD_AN, DW_SR_AN_ADV2, adv);
460 adv = DW_C73_AN_ADV_SF;
461 if (phylink_test(xpcs->supported, Pause))
463 if (phylink_test(xpcs->supported, Asym_Pause))
464 adv |= DW_C73_ASYM_PAUSE;
466 return xpcs_write(xpcs, MDIO_MMD_AN, DW_SR_AN_ADV1, adv);
469 static int xpcs_config_aneg_c73(struct mdio_xpcs_args *xpcs)
473 ret = _xpcs_config_aneg_c73(xpcs);
477 ret = xpcs_read(xpcs, MDIO_MMD_AN, MDIO_CTRL1);
481 ret |= MDIO_AN_CTRL1_ENABLE | MDIO_AN_CTRL1_RESTART;
483 return xpcs_write(xpcs, MDIO_MMD_AN, MDIO_CTRL1, ret);
486 static int xpcs_aneg_done_c73(struct mdio_xpcs_args *xpcs,
487 struct phylink_link_state *state)
491 ret = xpcs_read(xpcs, MDIO_MMD_AN, MDIO_STAT1);
495 if (ret & MDIO_AN_STAT1_COMPLETE) {
496 ret = xpcs_read(xpcs, MDIO_MMD_AN, DW_SR_AN_LP_ABL1);
500 /* Check if Aneg outcome is valid */
501 if (!(ret & DW_C73_AN_ADV_SF)) {
502 xpcs_config_aneg_c73(xpcs);
512 static int xpcs_read_lpa_c73(struct mdio_xpcs_args *xpcs,
513 struct phylink_link_state *state)
517 ret = xpcs_read(xpcs, MDIO_MMD_AN, MDIO_STAT1);
521 if (!(ret & MDIO_AN_STAT1_LPABLE)) {
522 phylink_clear(state->lp_advertising, Autoneg);
526 phylink_set(state->lp_advertising, Autoneg);
528 /* Clause 73 outcome */
529 ret = xpcs_read(xpcs, MDIO_MMD_AN, DW_SR_AN_LP_ABL3);
533 if (ret & DW_C73_2500KX)
534 phylink_set(state->lp_advertising, 2500baseX_Full);
536 ret = xpcs_read(xpcs, MDIO_MMD_AN, DW_SR_AN_LP_ABL2);
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);
547 ret = xpcs_read(xpcs, MDIO_MMD_AN, DW_SR_AN_LP_ABL1);
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);
556 linkmode_and(state->lp_advertising, state->lp_advertising,
561 static void xpcs_resolve_lpa_c73(struct mdio_xpcs_args *xpcs,
562 struct phylink_link_state *state)
564 int max_speed = xpcs_get_max_usxgmii_speed(state->lp_advertising);
566 state->pause = MLO_PAUSE_TX | MLO_PAUSE_RX;
567 state->speed = max_speed;
568 state->duplex = DUPLEX_FULL;
571 static int xpcs_get_max_xlgmii_speed(struct mdio_xpcs_args *xpcs,
572 struct phylink_link_state *state)
574 unsigned long *adv = state->advertising;
575 int speed = SPEED_UNKNOWN;
578 for_each_set_bit(bit, adv, __ETHTOOL_LINK_MODE_MASK_NBITS) {
579 int new_speed = SPEED_UNKNOWN;
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;
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;
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;
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;
618 if (new_speed > speed)
625 static void xpcs_resolve_pma(struct mdio_xpcs_args *xpcs,
626 struct phylink_link_state *state)
628 state->pause = MLO_PAUSE_TX | MLO_PAUSE_RX;
629 state->duplex = DUPLEX_FULL;
631 switch (state->interface) {
632 case PHY_INTERFACE_MODE_10GKR:
633 state->speed = SPEED_10000;
635 case PHY_INTERFACE_MODE_XLGMII:
636 state->speed = xpcs_get_max_xlgmii_speed(xpcs, state);
639 state->speed = SPEED_UNKNOWN;
644 static int xpcs_validate(struct mdio_xpcs_args *xpcs,
645 unsigned long *supported,
646 struct phylink_link_state *state)
648 linkmode_and(supported, supported, xpcs->supported);
649 linkmode_and(state->advertising, state->advertising, xpcs->supported);
653 static int xpcs_config_aneg_c37_sgmii(struct mdio_xpcs_args *xpcs)
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)
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.
670 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL);
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);
685 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1);
689 ret |= DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW;
691 return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret);
694 static int xpcs_config(struct mdio_xpcs_args *xpcs,
695 const struct phylink_link_state *state)
699 switch (xpcs->an_mode) {
701 if (state->an_enabled) {
702 ret = xpcs_config_aneg_c73(xpcs);
707 case DW_AN_C37_SGMII:
708 ret = xpcs_config_aneg_c37_sgmii(xpcs);
719 static int xpcs_get_state_c73(struct mdio_xpcs_args *xpcs,
720 struct phylink_link_state *state)
724 /* Link needs to be read first ... */
725 state->link = xpcs_read_link_c73(xpcs, state->an_enabled) > 0 ? 1 : 0;
727 /* ... and then we check the faults. */
728 ret = xpcs_read_fault_c73(xpcs, state);
730 ret = xpcs_soft_reset(xpcs);
736 return xpcs_config(xpcs, state);
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) {
745 } else if (state->link) {
746 xpcs_resolve_pma(xpcs, state);
752 static int xpcs_get_state_c37_sgmii(struct mdio_xpcs_args *xpcs,
753 struct phylink_link_state *state)
757 /* Reset link_state */
759 state->speed = SPEED_UNKNOWN;
760 state->duplex = DUPLEX_UNKNOWN;
763 /* For C37 SGMII mode, we check DW_VR_MII_AN_INTR_STS for link
764 * status, speed and duplex.
766 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_INTR_STS);
770 if (ret & DW_VR_MII_C37_ANSGM_SP_LNKSTS) {
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;
782 state->speed = SPEED_10;
784 if (ret & DW_VR_MII_AN_STS_C37_ANSGM_FD)
785 state->duplex = DUPLEX_FULL;
787 state->duplex = DUPLEX_HALF;
793 static int xpcs_get_state(struct mdio_xpcs_args *xpcs,
794 struct phylink_link_state *state)
798 switch (xpcs->an_mode) {
800 ret = xpcs_get_state_c73(xpcs, state);
804 case DW_AN_C37_SGMII:
805 ret = xpcs_get_state_c37_sgmii(xpcs, state);
816 static int xpcs_link_up(struct mdio_xpcs_args *xpcs, int speed,
817 phy_interface_t interface)
819 if (interface == PHY_INTERFACE_MODE_USXGMII)
820 return xpcs_config_usxgmii(xpcs, speed);
825 static u32 xpcs_get_id(struct mdio_xpcs_args *xpcs)
830 /* First, search C73 PCS using PCS MMD */
831 ret = xpcs_read(xpcs, MDIO_MMD_PCS, MII_PHYSID1);
837 ret = xpcs_read(xpcs, MDIO_MMD_PCS, MII_PHYSID2);
841 /* If Device IDs are not all zeros, we found C73 AN-type device */
845 /* Next, search C37 PCS using Vendor-Specific MII MMD */
846 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_PHYSID1);
852 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_PHYSID2);
856 /* If Device IDs are not all zeros, we found C37 AN-type device */
863 static bool xpcs_check_features(struct mdio_xpcs_args *xpcs,
864 struct xpcs_id *match,
865 phy_interface_t interface)
869 for (i = 0; match->interface[i] != PHY_INTERFACE_MODE_MAX; i++) {
870 if (match->interface[i] == interface)
874 if (match->interface[i] == PHY_INTERFACE_MODE_MAX)
877 for (i = 0; match->supported[i] != __ETHTOOL_LINK_MODE_MASK_NBITS; i++)
878 set_bit(match->supported[i], xpcs->supported);
880 xpcs->an_mode = match->an_mode;
885 static int xpcs_probe(struct mdio_xpcs_args *xpcs, phy_interface_t interface)
887 u32 xpcs_id = xpcs_get_id(xpcs);
888 struct xpcs_id *match = NULL;
891 for (i = 0; i < ARRAY_SIZE(xpcs_id_list); i++) {
892 struct xpcs_id *entry = &xpcs_id_list[i];
894 if ((xpcs_id & entry->mask) == entry->id) {
897 if (xpcs_check_features(xpcs, match, interface))
898 return xpcs_soft_reset(xpcs);
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,
913 struct mdio_xpcs_ops *mdio_xpcs_get_ops(void)
917 EXPORT_SYMBOL_GPL(mdio_xpcs_get_ops);
919 MODULE_LICENSE("GPL v2");