Lines Matching +full:5 +full:g +full:- +full:usxgmii
1 // SPDX-License-Identifier: GPL-2.0
11 #include <linux/pcs/pcs-xpcs.h>
17 #include "pcs-xpcs.h"
128 for (compat = xpcs->desc->compat; compat->supported; compat++) in xpcs_find_compat()
129 if (compat->interface == interface) in xpcs_find_compat()
137 return &xpcs->pcs; in xpcs_to_phylink_pcs()
147 return -ENODEV; in xpcs_get_an_mode()
149 return compat->an_mode; in xpcs_get_an_mode()
158 for (i = 0; compat->supported[i] != __ETHTOOL_LINK_MODE_MASK_NBITS; i++) in __xpcs_linkmode_supported()
159 if (compat->supported[i] == linkmode) in __xpcs_linkmode_supported()
170 return mdiodev_c45_read(xpcs->mdiodev, dev, reg); in xpcs_read()
175 return mdiodev_c45_write(xpcs->mdiodev, dev, reg, val); in xpcs_write()
180 return mdiodev_c45_modify(xpcs->mdiodev, dev, reg, mask, set); in xpcs_modify()
186 return mdiodev_c45_modify_changed(xpcs->mdiodev, dev, reg, mask, set); in xpcs_modify_changed()
239 switch (compat->an_mode) { in xpcs_soft_reset()
250 return -EINVAL; in xpcs_soft_reset()
262 if ((__state)->link) \
263 dev_warn(&(__xpcs)->mdiodev->dev, ##__args); \
274 return -EFAULT; in xpcs_read_fault_c73()
292 return -EFAULT; in xpcs_read_fault_c73()
308 return -EFAULT; in xpcs_read_fault_c73()
359 dev_err(&xpcs->mdiodev->dev, "%s: XPCS access returned %pe\n", in xpcs_link_up_usxgmii()
368 /* By default, in USXGMII mode XPCS operates at 10G baud and in _xpcs_config_aneg_c73()
452 phylink_clear(state->lp_advertising, Autoneg); in xpcs_read_lpa_c73()
456 phylink_set(state->lp_advertising, Autoneg); in xpcs_read_lpa_c73()
459 for (i = ARRAY_SIZE(lpa); --i >= 0; ) { in xpcs_read_lpa_c73()
467 mii_c73_mod_linkmode(state->lp_advertising, lpa); in xpcs_read_lpa_c73()
475 unsigned long *adv = state->advertising; in xpcs_get_max_xlgmii_speed()
529 state->pause = MLO_PAUSE_TX | MLO_PAUSE_RX; in xpcs_resolve_pma()
530 state->duplex = DUPLEX_FULL; in xpcs_resolve_pma()
532 switch (state->interface) { in xpcs_resolve_pma()
534 state->speed = SPEED_10000; in xpcs_resolve_pma()
537 state->speed = xpcs_get_max_xlgmii_speed(xpcs, state); in xpcs_resolve_pma()
540 state->speed = SPEED_UNKNOWN; in xpcs_resolve_pma()
554 compat = xpcs_find_compat(xpcs, state->interface); in xpcs_validate()
556 return -EINVAL; in xpcs_validate()
562 for (i = 0; compat->supported[i] != __ETHTOOL_LINK_MODE_MASK_NBITS; i++) in xpcs_validate()
563 set_bit(compat->supported[i], xpcs_supported); in xpcs_validate()
580 switch (compat->an_mode) { in xpcs_inband_caps()
601 for (compat = xpcs->desc->compat; compat->supported; compat++) in xpcs_get_interfaces()
602 __set_bit(compat->interface, interfaces); in xpcs_get_interfaces()
641 if (!xpcs->need_reset) in xpcs_pre_config()
646 dev_err(&xpcs->mdiodev->dev, "unsupported interface %s\n", in xpcs_pre_config()
653 dev_err(&xpcs->mdiodev->dev, "soft reset failed: %pe\n", in xpcs_pre_config()
656 xpcs->need_reset = false; in xpcs_pre_config()
665 /* For AN for C37 SGMII mode, the settings are :- in xpcs_config_aneg_c37_sgmii()
673 * 5) VR_MII_MMD_CTRL Bit(12) [AN_ENABLE] = 1b (Enable SGMII AN) in xpcs_config_aneg_c37_sgmii()
681 * trigger AN restart for MAC-side SGMII. in xpcs_config_aneg_c37_sgmii()
698 if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID) { in xpcs_config_aneg_c37_sgmii()
719 if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID) { in xpcs_config_aneg_c37_sgmii()
744 /* According to Chap 7.12, to set 1000BASE-X C37 AN, AN must in xpcs_config_aneg_c37_1000basex()
745 * be disabled first:- in xpcs_config_aneg_c37_1000basex()
747 * 2) VR_MII_AN_CTRL Bit(2:1)[PCS_MODE] = 00b (1000BASE-X C37) in xpcs_config_aneg_c37_1000basex()
766 if (!xpcs->pcs.poll) { in xpcs_config_aneg_c37_1000basex()
829 return -ENODEV; in xpcs_do_config()
831 if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID) { in xpcs_do_config()
837 * SGMII and 1000base-X in xpcs_do_config()
845 switch (compat->an_mode) { in xpcs_do_config()
872 return -EINVAL; in xpcs_do_config()
875 if (compat->pma_config) { in xpcs_do_config()
876 ret = compat->pma_config(xpcs); in xpcs_do_config()
903 /* The link status bit is latching-low, so it is important to in xpcs_get_state_c73()
904 * avoid unnecessary re-reads of this register to avoid missing in xpcs_get_state_c73()
905 * a link-down event. in xpcs_get_state_c73()
909 state->link = false; in xpcs_get_state_c73()
914 state->link = !!(pcs_stat1 & MDIO_STAT1_LSTATUS); in xpcs_get_state_c73()
923 state->link = 0; in xpcs_get_state_c73()
925 return xpcs_do_config(xpcs, state->interface, NULL, in xpcs_get_state_c73()
930 if (!state->link) in xpcs_get_state_c73()
934 state->advertising); in xpcs_get_state_c73()
936 /* The link status bit is latching-low, so it is important to in xpcs_get_state_c73()
937 * avoid unnecessary re-reads of this register to avoid missing in xpcs_get_state_c73()
938 * a link-down event. in xpcs_get_state_c73()
942 state->link = false; in xpcs_get_state_c73()
946 state->an_complete = xpcs_aneg_done_c73(xpcs, state, compat, in xpcs_get_state_c73()
948 if (!state->an_complete) { in xpcs_get_state_c73()
949 state->link = false; in xpcs_get_state_c73()
955 state->link = false; in xpcs_get_state_c73()
973 state->link = false; in xpcs_get_state_c37_sgmii()
974 state->speed = SPEED_UNKNOWN; in xpcs_get_state_c37_sgmii()
975 state->duplex = DUPLEX_UNKNOWN; in xpcs_get_state_c37_sgmii()
976 state->pause = 0; in xpcs_get_state_c37_sgmii()
988 state->link = true; in xpcs_get_state_c37_sgmii()
992 state->speed = SPEED_1000; in xpcs_get_state_c37_sgmii()
994 state->speed = SPEED_100; in xpcs_get_state_c37_sgmii()
996 state->speed = SPEED_10; in xpcs_get_state_c37_sgmii()
999 state->duplex = DUPLEX_FULL; in xpcs_get_state_c37_sgmii()
1001 state->duplex = DUPLEX_HALF; in xpcs_get_state_c37_sgmii()
1005 state->link = true; in xpcs_get_state_c37_sgmii()
1013 state->speed = SPEED_1000; in xpcs_get_state_c37_sgmii()
1015 state->speed = SPEED_100; in xpcs_get_state_c37_sgmii()
1017 state->speed = SPEED_10; in xpcs_get_state_c37_sgmii()
1024 state->duplex = DUPLEX_FULL; in xpcs_get_state_c37_sgmii()
1026 state->duplex = DUPLEX_HALF; in xpcs_get_state_c37_sgmii()
1041 state->advertising)) { in xpcs_get_state_c37_1000basex()
1043 state->link = false; in xpcs_get_state_c37_1000basex()
1054 if (!xpcs->pcs.poll) { in xpcs_get_state_c37_1000basex()
1077 state->link = 0; in xpcs_get_state_2500basex()
1081 state->link = !!(ret & BMSR_LSTATUS); in xpcs_get_state_2500basex()
1082 if (!state->link) in xpcs_get_state_2500basex()
1085 state->speed = SPEED_2500; in xpcs_get_state_2500basex()
1086 state->pause |= MLO_PAUSE_TX | MLO_PAUSE_RX; in xpcs_get_state_2500basex()
1087 state->duplex = DUPLEX_FULL; in xpcs_get_state_2500basex()
1099 compat = xpcs_find_compat(xpcs, state->interface); in xpcs_get_state()
1103 switch (compat->an_mode) { in xpcs_get_state()
1105 phylink_mii_c45_pcs_get_state(xpcs->mdiodev, state); in xpcs_get_state()
1110 dev_err(&xpcs->mdiodev->dev, "%s returned %pe\n", in xpcs_get_state()
1116 dev_err(&xpcs->mdiodev->dev, "%s returned %pe\n", in xpcs_get_state()
1122 dev_err(&xpcs->mdiodev->dev, "%s returned %pe\n", in xpcs_get_state()
1128 dev_err(&xpcs->mdiodev->dev, "%s returned %pe\n", in xpcs_get_state()
1148 dev_err(&xpcs->mdiodev->dev, in xpcs_link_up_sgmii_1000basex()
1155 dev_err(&xpcs->mdiodev->dev, in xpcs_link_up_sgmii_1000basex()
1163 dev_err(&xpcs->mdiodev->dev, "%s: xpcs_write returned %pe\n", in xpcs_link_up_sgmii_1000basex()
1206 return -ENODEV; in xpcs_read_ids()
1216 /* If Device IDs are not all zeros or ones, then 10GBase-X/R or C73 in xpcs_read_ids()
1217 * KR/KX4 PCS found. Otherwise fallback to detecting 1000Base-X or C37 in xpcs_read_ids()
1234 /* Set the PCS ID if it hasn't been pre-initialized */ in xpcs_read_ids()
1235 if (xpcs->info.pcs == DW_XPCS_ID_NATIVE) in xpcs_read_ids()
1236 xpcs->info.pcs = id; in xpcs_read_ids()
1255 /* Set the PMA ID if it hasn't been pre-initialized */ in xpcs_read_ids()
1256 if (xpcs->info.pma == DW_XPCS_PMA_ID_NATIVE) in xpcs_read_ids()
1257 xpcs->info.pma = id; in xpcs_read_ids()
1357 if ((xpcs->info.pcs & entry->mask) == entry->id) { in xpcs_identify()
1358 xpcs->desc = entry; in xpcs_identify()
1363 return -ENODEV; in xpcs_identify()
1372 return ERR_PTR(-ENOMEM); in xpcs_create_data()
1375 xpcs->mdiodev = mdiodev; in xpcs_create_data()
1376 xpcs->pcs.ops = &xpcs_phylink_ops; in xpcs_create_data()
1377 xpcs->pcs.neg_mode = true; in xpcs_create_data()
1378 xpcs->pcs.poll = true; in xpcs_create_data()
1385 mdio_device_put(xpcs->mdiodev); in xpcs_free_data()
1395 struct device *dev = &xpcs->mdiodev->dev; in xpcs_init_clks()
1399 xpcs->clks[i].id = ids[i]; in xpcs_init_clks()
1401 ret = clk_bulk_get_optional(dev, DW_XPCS_NUM_CLKS, xpcs->clks); in xpcs_init_clks()
1405 ret = clk_bulk_prepare_enable(DW_XPCS_NUM_CLKS, xpcs->clks); in xpcs_init_clks()
1414 clk_bulk_disable_unprepare(DW_XPCS_NUM_CLKS, xpcs->clks); in xpcs_clear_clks()
1416 clk_bulk_put(DW_XPCS_NUM_CLKS, xpcs->clks); in xpcs_clear_clks()
1423 info = dev_get_platdata(&xpcs->mdiodev->dev); in xpcs_init_id()
1425 xpcs->info.pcs = DW_XPCS_ID_NATIVE; in xpcs_init_id()
1426 xpcs->info.pma = DW_XPCS_PMA_ID_NATIVE; in xpcs_init_id()
1428 xpcs->info = *info; in xpcs_init_id()
1451 xpcs_get_interfaces(xpcs, xpcs->pcs.supported_interfaces); in xpcs_create()
1453 if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID) in xpcs_create()
1454 xpcs->pcs.poll = false; in xpcs_create()
1456 xpcs->need_reset = true; in xpcs_create()
1470 * xpcs_create_mdiodev() - create a DW xPCS instance with the MDIO @addr
1471 * @bus: pointer to the MDIO-bus descriptor for the device to be looked at
1472 * @addr: device MDIO-bus ID
1474 * Return: a pointer to the DW XPCS handle if successful, otherwise -ENODEV if
1476 * to the data allocation and MDIO-bus communications.
1509 return &xpcs->pcs; in xpcs_create_pcs_mdiodev()
1514 * xpcs_create_fwnode() - Create a DW xPCS instance from @fwnode
1517 * Return: a pointer to the DW XPCS handle if successful, otherwise -ENODEV if
1519 * bus, -EPROBE_DEFER if the respective MDIO-device instance couldn't be found,
1520 * other negative errno related to the data allocations and MDIO-bus
1529 return ERR_PTR(-ENODEV); in xpcs_create_fwnode()
1533 return ERR_PTR(-EPROBE_DEFER); in xpcs_create_fwnode()