Lines Matching +full:eee +full:- +full:pcs

1 // SPDX-License-Identifier: GPL-2.0
4 * technologies such as SFP cages where the PHY is hot-pluggable.
23 #include "phy-caps.h"
38 * struct phylink - internal data type for phylink
45 struct phylink_pcs *pcs; member
55 u8 link_port; /* The current non-phy ethtool port */
70 /* Serialize updates to pl->phydev with phylink_resolve() */
100 if ((pl)->config->type == PHYLINK_NETDEV) \
101 netdev_printk(level, (pl)->netdev, fmt, ##__VA_ARGS__); \
102 else if ((pl)->config->type == PHYLINK_DEV) \
103 dev_printk(level, (pl)->dev, fmt, ##__VA_ARGS__); \
115 if ((pl)->config->type == PHYLINK_NETDEV) \
116 netdev_dbg((pl)->netdev, fmt, ##__VA_ARGS__); \
117 else if ((pl)->config->type == PHYLINK_DEV) \
118 dev_dbg((pl)->dev, fmt, ##__VA_ARGS__); \
148 * phylink_set_port_modes() - set the port type modes in the ethtool mask
198 return "inband,an-enabled"; in phylink_pcs_mode_str()
200 return "inband,an-disabled"; in phylink_pcs_mode_str()
224 * phylink_interface_max_speed() - get the maximum speed of a phy interface
328 * phylink_caps_to_link_caps() - Convert a set of MAC capabilities LINK caps
331 * Returns: The corresponding set of LINK_CAPA as defined in phy-caps.h
358 * phylink_caps_to_linkmodes() - Convert capabilities to ethtool link modes
380 * phylink_limit_mac_speed - limit the phylink_config to a maximum speed
393 config->mac_capabilities &= ~phylink_caps_params[i].mask; in phylink_limit_mac_speed()
398 * phylink_cap_from_speed_duplex - Get mac capability from speed/duplex
422 * phylink_get_capabilities() - get capabilities for a given MAC
484 * phylink_validate_mask_caps() - Restrict link modes based on caps
502 caps = phylink_get_capabilities(state->interface, mac_capabilities, in phylink_validate_mask_caps()
503 state->rate_matching); in phylink_validate_mask_caps()
507 linkmode_and(state->advertising, state->advertising, mask); in phylink_validate_mask_caps()
514 struct phylink_pcs *pcs = NULL; in phylink_validate_mac_and_pcs() local
518 /* Get the PCS for this interface mode */ in phylink_validate_mac_and_pcs()
519 if (pl->mac_ops->mac_select_pcs) { in phylink_validate_mac_and_pcs()
520 pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface); in phylink_validate_mac_and_pcs()
521 if (IS_ERR(pcs)) in phylink_validate_mac_and_pcs()
522 return PTR_ERR(pcs); in phylink_validate_mac_and_pcs()
525 if (pcs) { in phylink_validate_mac_and_pcs()
526 /* The PCS, if present, must be setup before phylink_create() in phylink_validate_mac_and_pcs()
530 if (!pcs->ops) { in phylink_validate_mac_and_pcs()
531 phylink_err(pl, "interface %s: uninitialised PCS\n", in phylink_validate_mac_and_pcs()
532 phy_modes(state->interface)); in phylink_validate_mac_and_pcs()
534 return -EINVAL; in phylink_validate_mac_and_pcs()
537 /* Ensure that this PCS supports the interface which the MAC in phylink_validate_mac_and_pcs()
538 * returned it for. It is an error for the MAC to return a PCS in phylink_validate_mac_and_pcs()
541 if (!phy_interface_empty(pcs->supported_interfaces) && in phylink_validate_mac_and_pcs()
542 !test_bit(state->interface, pcs->supported_interfaces)) { in phylink_validate_mac_and_pcs()
543 phylink_err(pl, "MAC returned PCS which does not support %s\n", in phylink_validate_mac_and_pcs()
544 phy_modes(state->interface)); in phylink_validate_mac_and_pcs()
545 return -EINVAL; in phylink_validate_mac_and_pcs()
548 /* Validate the link parameters with the PCS */ in phylink_validate_mac_and_pcs()
549 if (pcs->ops->pcs_validate) { in phylink_validate_mac_and_pcs()
550 ret = pcs->ops->pcs_validate(pcs, supported, state); in phylink_validate_mac_and_pcs()
552 return -EINVAL; in phylink_validate_mac_and_pcs()
557 linkmode_and(state->advertising, state->advertising, in phylink_validate_mac_and_pcs()
563 if (pl->mac_ops->mac_get_caps) in phylink_validate_mac_and_pcs()
564 capabilities = pl->mac_ops->mac_get_caps(pl->config, in phylink_validate_mac_and_pcs()
565 state->interface); in phylink_validate_mac_and_pcs()
567 capabilities = pl->config->mac_capabilities; in phylink_validate_mac_and_pcs()
571 return phylink_is_empty_linkmode(supported) ? -EINVAL : 0; in phylink_validate_mac_and_pcs()
618 linkmode_copy(state->advertising, all_adv); in phylink_validate_mask()
620 return phylink_is_empty_linkmode(supported) ? -EINVAL : 0; in phylink_validate_mask()
626 const unsigned long *interfaces = pl->config->supported_interfaces; in phylink_validate()
628 if (state->interface == PHY_INTERFACE_MODE_NA) in phylink_validate()
632 if (!test_bit(state->interface, interfaces)) in phylink_validate()
633 return -EINVAL; in phylink_validate()
662 fixed_node = fwnode_get_named_child_node(fwnode, "fixed-link"); in phylink_parse_fixedlink()
666 pl->link_config.speed = speed; in phylink_parse_fixedlink()
667 pl->link_config.duplex = DUPLEX_HALF; in phylink_parse_fixedlink()
669 if (fwnode_property_read_bool(fixed_node, "full-duplex")) in phylink_parse_fixedlink()
670 pl->link_config.duplex = DUPLEX_FULL; in phylink_parse_fixedlink()
672 /* We treat the "pause" and "asym-pause" terminology as in phylink_parse_fixedlink()
677 pl->link_config.lp_advertising); in phylink_parse_fixedlink()
678 if (fwnode_property_read_bool(fixed_node, "asym-pause")) in phylink_parse_fixedlink()
680 pl->link_config.lp_advertising); in phylink_parse_fixedlink()
687 pl->link_gpio = desc; in phylink_parse_fixedlink()
688 else if (desc == ERR_PTR(-EPROBE_DEFER)) in phylink_parse_fixedlink()
689 ret = -EPROBE_DEFER; in phylink_parse_fixedlink()
698 ret = fwnode_property_read_u32_array(fwnode, "fixed-link", in phylink_parse_fixedlink()
701 phylink_err(pl, "broken fixed-link?\n"); in phylink_parse_fixedlink()
702 return -EINVAL; in phylink_parse_fixedlink()
705 phylink_warn(pl, "%pfw uses deprecated array-style fixed-link binding!\n", in phylink_parse_fixedlink()
708 ret = fwnode_property_read_u32_array(fwnode, "fixed-link", in phylink_parse_fixedlink()
711 pl->link_config.duplex = prop[1] ? in phylink_parse_fixedlink()
713 pl->link_config.speed = prop[2]; in phylink_parse_fixedlink()
716 pl->link_config.lp_advertising); in phylink_parse_fixedlink()
719 pl->link_config.lp_advertising); in phylink_parse_fixedlink()
723 if (pl->link_config.speed > SPEED_1000 && in phylink_parse_fixedlink()
724 pl->link_config.duplex != DUPLEX_FULL) in phylink_parse_fixedlink()
726 pl->link_config.speed); in phylink_parse_fixedlink()
728 linkmode_zero(pl->supported); in phylink_parse_fixedlink()
729 phylink_fill_fixedlink_supported(pl->supported); in phylink_parse_fixedlink()
731 linkmode_copy(pl->link_config.advertising, pl->supported); in phylink_parse_fixedlink()
732 phylink_validate(pl, pl->supported, &pl->link_config); in phylink_parse_fixedlink()
734 c = phy_caps_lookup(pl->link_config.speed, pl->link_config.duplex, in phylink_parse_fixedlink()
735 pl->supported, true); in phylink_parse_fixedlink()
737 linkmode_and(match, pl->supported, c->linkmodes); in phylink_parse_fixedlink()
742 linkmode_and(pl->supported, pl->supported, mask); in phylink_parse_fixedlink()
744 phylink_set(pl->supported, MII); in phylink_parse_fixedlink()
747 linkmode_or(pl->supported, pl->supported, match); in phylink_parse_fixedlink()
748 linkmode_or(pl->link_config.lp_advertising, in phylink_parse_fixedlink()
749 pl->link_config.lp_advertising, match); in phylink_parse_fixedlink()
752 pl->link_config.duplex == DUPLEX_FULL ? "full" : "half", in phylink_parse_fixedlink()
753 pl->link_config.speed); in phylink_parse_fixedlink()
756 linkmode_and(pl->link_config.advertising, pl->link_config.advertising, in phylink_parse_fixedlink()
757 pl->supported); in phylink_parse_fixedlink()
759 pl->link_config.link = 1; in phylink_parse_fixedlink()
760 pl->link_config.an_complete = 1; in phylink_parse_fixedlink()
772 if (pl->config->default_an_inband) in phylink_parse_mode()
773 pl->cfg_link_an_mode = MLO_AN_INBAND; in phylink_parse_mode()
775 dn = fwnode_get_named_child_node(fwnode, "fixed-link"); in phylink_parse_mode()
776 if (dn || fwnode_property_present(fwnode, "fixed-link")) in phylink_parse_mode()
777 pl->cfg_link_an_mode = MLO_AN_FIXED; in phylink_parse_mode()
781 strcmp(managed, "in-band-status") == 0)) { in phylink_parse_mode()
782 if (pl->cfg_link_an_mode == MLO_AN_FIXED) { in phylink_parse_mode()
784 "can't use both fixed-link and in-band-status\n"); in phylink_parse_mode()
785 return -EINVAL; in phylink_parse_mode()
788 pl->cfg_link_an_mode = MLO_AN_INBAND; in phylink_parse_mode()
791 if (pl->cfg_link_an_mode == MLO_AN_INBAND) { in phylink_parse_mode()
792 linkmode_zero(pl->supported); in phylink_parse_mode()
793 phylink_set(pl->supported, MII); in phylink_parse_mode()
794 phylink_set(pl->supported, Autoneg); in phylink_parse_mode()
795 phylink_set(pl->supported, Asym_Pause); in phylink_parse_mode()
796 phylink_set(pl->supported, Pause); in phylink_parse_mode()
798 switch (pl->link_config.interface) { in phylink_parse_mode()
821 caps = phylink_get_capabilities(pl->link_config.interface, caps, in phylink_parse_mode()
823 phylink_caps_to_linkmodes(pl->supported, caps); in phylink_parse_mode()
828 "incorrect link mode %s for in-band status\n", in phylink_parse_mode()
829 phy_modes(pl->link_config.interface)); in phylink_parse_mode()
830 return -EINVAL; in phylink_parse_mode()
833 linkmode_copy(pl->link_config.advertising, pl->supported); in phylink_parse_mode()
835 if (phylink_validate(pl, pl->supported, &pl->link_config)) { in phylink_parse_mode()
837 "failed to validate link configuration for in-band status\n"); in phylink_parse_mode()
838 return -EINVAL; in phylink_parse_mode()
850 state->advertising)) in phylink_apply_manual_flow()
851 state->pause &= ~MLO_PAUSE_AN; in phylink_apply_manual_flow()
854 if (!(pl->link_config.pause & MLO_PAUSE_AN)) in phylink_apply_manual_flow()
855 state->pause = pl->link_config.pause; in phylink_apply_manual_flow()
862 if (state->duplex == DUPLEX_FULL) { in phylink_resolve_an_pause()
863 linkmode_resolve_pause(state->advertising, in phylink_resolve_an_pause()
864 state->lp_advertising, in phylink_resolve_an_pause()
867 state->pause |= MLO_PAUSE_TX; in phylink_resolve_an_pause()
869 state->pause |= MLO_PAUSE_RX; in phylink_resolve_an_pause()
873 static unsigned int phylink_pcs_inband_caps(struct phylink_pcs *pcs, in phylink_pcs_inband_caps() argument
876 if (pcs && pcs->ops->pcs_inband_caps) in phylink_pcs_inband_caps()
877 return pcs->ops->pcs_inband_caps(pcs, interface); in phylink_pcs_inband_caps()
882 static void phylink_pcs_pre_config(struct phylink_pcs *pcs, in phylink_pcs_pre_config() argument
885 if (pcs && pcs->ops->pcs_pre_config) in phylink_pcs_pre_config()
886 pcs->ops->pcs_pre_config(pcs, interface); in phylink_pcs_pre_config()
889 static int phylink_pcs_post_config(struct phylink_pcs *pcs, in phylink_pcs_post_config() argument
894 if (pcs && pcs->ops->pcs_post_config) in phylink_pcs_post_config()
895 err = pcs->ops->pcs_post_config(pcs, interface); in phylink_pcs_post_config()
900 static void phylink_pcs_disable(struct phylink_pcs *pcs) in phylink_pcs_disable() argument
902 if (pcs && pcs->ops->pcs_disable) in phylink_pcs_disable()
903 pcs->ops->pcs_disable(pcs); in phylink_pcs_disable()
906 static int phylink_pcs_enable(struct phylink_pcs *pcs) in phylink_pcs_enable() argument
910 if (pcs && pcs->ops->pcs_enable) in phylink_pcs_enable()
911 err = pcs->ops->pcs_enable(pcs); in phylink_pcs_enable()
916 static int phylink_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode, in phylink_pcs_config() argument
920 if (!pcs) in phylink_pcs_config()
923 return pcs->ops->pcs_config(pcs, neg_mode, state->interface, in phylink_pcs_config()
924 state->advertising, permit_pause_to_mac); in phylink_pcs_config()
927 static void phylink_pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode, in phylink_pcs_link_up() argument
931 if (pcs && pcs->ops->pcs_link_up) in phylink_pcs_link_up()
932 pcs->ops->pcs_link_up(pcs, neg_mode, interface, speed, duplex); in phylink_pcs_link_up()
935 static void phylink_pcs_disable_eee(struct phylink_pcs *pcs) in phylink_pcs_disable_eee() argument
937 if (pcs && pcs->ops->pcs_disable_eee) in phylink_pcs_disable_eee()
938 pcs->ops->pcs_disable_eee(pcs); in phylink_pcs_disable_eee()
941 static void phylink_pcs_enable_eee(struct phylink_pcs *pcs) in phylink_pcs_enable_eee() argument
943 if (pcs && pcs->ops->pcs_enable_eee) in phylink_pcs_enable_eee()
944 pcs->ops->pcs_enable_eee(pcs); in phylink_pcs_enable_eee()
948 * PCS which will be used to handle the interface mode.
953 struct phylink_pcs *pcs; in phylink_inband_caps() local
955 if (!pl->mac_ops->mac_select_pcs) in phylink_inband_caps()
958 pcs = pl->mac_ops->mac_select_pcs(pl->config, interface); in phylink_inband_caps()
959 if (!pcs) in phylink_inband_caps()
962 return phylink_pcs_inband_caps(pcs, interface); in phylink_inband_caps()
967 if (pl->cfg_link_an_mode == MLO_AN_INBAND) in phylink_pcs_poll_stop()
968 timer_delete(&pl->link_poll); in phylink_pcs_poll_stop()
973 if (pl->pcs && pl->pcs->poll && pl->cfg_link_an_mode == MLO_AN_INBAND) in phylink_pcs_poll_start()
974 mod_timer(&pl->link_poll, jiffies + HZ); in phylink_pcs_poll_start()
977 int phylink_pcs_pre_init(struct phylink *pl, struct phylink_pcs *pcs) in phylink_pcs_pre_init() argument
981 /* Signal to PCS driver that MAC requires RX clock for init */ in phylink_pcs_pre_init()
982 if (pl->config->mac_requires_rxc) in phylink_pcs_pre_init()
983 pcs->rxc_always_on = true; in phylink_pcs_pre_init()
985 if (pcs->ops->pcs_pre_init) in phylink_pcs_pre_init()
986 ret = pcs->ops->pcs_pre_init(pcs); in phylink_pcs_pre_init()
1006 __func__, phylink_an_mode_str(pl->act_link_an_mode), in phylink_mac_config()
1012 pl->mac_ops->mac_config(pl->config, pl->act_link_an_mode, &st); in phylink_mac_config()
1017 if (pl->pcs && linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, in phylink_pcs_an_restart()
1018 pl->link_config.advertising) && in phylink_pcs_an_restart()
1019 phy_interface_mode_is_8023z(pl->link_config.interface) && in phylink_pcs_an_restart()
1020 phylink_autoneg_inband(pl->act_link_an_mode)) in phylink_pcs_an_restart()
1021 pl->pcs->ops->pcs_an_restart(pl->pcs); in phylink_pcs_an_restart()
1047 /* 1000base-X is designed for use media-side for Fibre in phylink_get_inband_type()
1049 * taken into account. We also do this for 2500base-X in phylink_get_inband_type()
1061 * phylink_pcs_neg_mode() - helper to determine PCS inband mode
1063 * @pcs: a pointer to &struct phylink_pcs
1067 * Determines the negotiation mode to be used by the PCS, and returns
1070 * - %PHYLINK_PCS_NEG_NONE: interface mode does not support inband
1071 * - %PHYLINK_PCS_NEG_OUTBAND: an out of band mode (e.g. reading the PHY)
1073 * - %PHYLINK_PCS_NEG_INBAND_DISABLED: inband mode selected but autoneg
1075 * - %PHYLINK_PCS_NEG_INBAND_ENABLED: inband mode selected and autoneg enabled
1077 * Note: this is for cases where the PCS itself is involved in negotiation
1080 static void phylink_pcs_neg_mode(struct phylink *pl, struct phylink_pcs *pcs, in phylink_pcs_neg_mode() argument
1091 pl->pcs_neg_mode = PHYLINK_PCS_NEG_NONE; in phylink_pcs_neg_mode()
1092 pl->act_link_an_mode = pl->req_link_an_mode; in phylink_pcs_neg_mode()
1096 mode = pl->req_link_an_mode; in phylink_pcs_neg_mode()
1098 pl->phy_ib_mode = 0; in phylink_pcs_neg_mode()
1100 if (pcs) in phylink_pcs_neg_mode()
1101 pcs_ib_caps = phylink_pcs_inband_caps(pcs, interface); in phylink_pcs_neg_mode()
1103 if (pl->phydev) in phylink_pcs_neg_mode()
1104 phy_ib_caps = phy_inband_caps(pl->phydev, interface); in phylink_pcs_neg_mode()
1106 phylink_dbg(pl, "interface %s inband modes: pcs=%02x phy=%02x\n", in phylink_pcs_neg_mode()
1114 /* PCS supports reporting in-band capabilities, and in phylink_pcs_neg_mode()
1124 /* PHY supports in-band capabilities, and supports in phylink_pcs_neg_mode()
1128 pl->phy_ib_mode = LINK_INBAND_DISABLE; in phylink_pcs_neg_mode()
1130 pl->phy_ib_mode = LINK_INBAND_BYPASS; in phylink_pcs_neg_mode()
1135 /* If either the PCS or PHY requires inband to be enabled, in phylink_pcs_neg_mode()
1143 pcs_ib_only ? "PCS" : "", in phylink_pcs_neg_mode()
1148 } else if (type == INBAND_CISCO_SGMII || pl->phydev) { in phylink_pcs_neg_mode()
1150 * Base-X with a PHY, we try to use in-band mode where-ever in phylink_pcs_neg_mode()
1152 * do not support in-band. in phylink_pcs_neg_mode()
1158 /* PCS PHY in phylink_pcs_neg_mode()
1161 * 1 0 0 0 pcs doesn't support outband in phylink_pcs_neg_mode()
1162 * 0 1 0 0 pcs required inband enabled in phylink_pcs_neg_mode()
1163 * 1 1 0 0 pcs optional inband enabled in phylink_pcs_neg_mode()
1165 * 1 0 1 0 pcs+phy doesn't support outband in phylink_pcs_neg_mode()
1166 * 0 1 1 0 pcs required, phy doesn't support, invalid in phylink_pcs_neg_mode()
1167 * 1 1 1 0 pcs optional, phy doesn't support, outband in phylink_pcs_neg_mode()
1169 * 1 0 0 1 pcs doesn't support, phy required, invalid in phylink_pcs_neg_mode()
1170 * 0 1 0 1 pcs+phy required inband enabled in phylink_pcs_neg_mode()
1171 * 1 1 0 1 pcs optional, phy required inband enabled in phylink_pcs_neg_mode()
1173 * 1 0 1 1 pcs doesn't support, phy optional, outband in phylink_pcs_neg_mode()
1174 * 0 1 1 1 pcs required, phy optional inband enabled in phylink_pcs_neg_mode()
1175 * 1 1 1 1 pcs+phy optional inband enabled in phylink_pcs_neg_mode()
1179 /* In-band supported or unknown at both ends. Enable in phylink_pcs_neg_mode()
1180 * in-band mode with or without bypass at the PHY. in phylink_pcs_neg_mode()
1183 pl->phy_ib_mode = LINK_INBAND_ENABLE; in phylink_pcs_neg_mode()
1185 pl->phy_ib_mode = LINK_INBAND_BYPASS; in phylink_pcs_neg_mode()
1190 /* Either in-band not supported at at least one end. in phylink_pcs_neg_mode()
1191 * In-band bypass at the other end is possible. in phylink_pcs_neg_mode()
1194 pl->phy_ib_mode = LINK_INBAND_DISABLE; in phylink_pcs_neg_mode()
1196 pl->phy_ib_mode = LINK_INBAND_BYPASS; in phylink_pcs_neg_mode()
1199 if (pl->phydev) in phylink_pcs_neg_mode()
1203 phylink_warn(pl, "%s: incompatible in-band capabilities, trying in-band", in phylink_pcs_neg_mode()
1208 /* For Base-X without a PHY */ in phylink_pcs_neg_mode()
1210 /* If the PCS doesn't support inband, then inband must in phylink_pcs_neg_mode()
1215 /* If the PCS requires inband, then inband must always in phylink_pcs_neg_mode()
1226 pl->pcs_neg_mode = neg_mode; in phylink_pcs_neg_mode()
1227 pl->act_link_an_mode = mode; in phylink_pcs_neg_mode()
1233 struct phylink_pcs *pcs = NULL; in phylink_major_config() local
1239 phylink_an_mode_str(pl->req_link_an_mode), in phylink_major_config()
1240 phy_modes(state->interface)); in phylink_major_config()
1242 pl->major_config_failed = false; in phylink_major_config()
1244 if (pl->mac_ops->mac_select_pcs) { in phylink_major_config()
1245 pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface); in phylink_major_config()
1246 if (IS_ERR(pcs)) { in phylink_major_config()
1249 pcs); in phylink_major_config()
1251 pl->major_config_failed = true; in phylink_major_config()
1255 pcs_changed = pl->pcs != pcs; in phylink_major_config()
1258 phylink_pcs_neg_mode(pl, pcs, state->interface, state->advertising); in phylink_major_config()
1261 phylink_an_mode_str(pl->act_link_an_mode), in phylink_major_config()
1262 phylink_pcs_mode_str(pl->pcs_neg_mode), in phylink_major_config()
1263 phy_modes(state->interface)); in phylink_major_config()
1267 if (pl->mac_ops->mac_prepare) { in phylink_major_config()
1268 err = pl->mac_ops->mac_prepare(pl->config, pl->act_link_an_mode, in phylink_major_config()
1269 state->interface); in phylink_major_config()
1273 pl->major_config_failed = true; in phylink_major_config()
1278 /* If we have a new PCS, switch to the new PCS after preparing the MAC in phylink_major_config()
1282 phylink_pcs_disable(pl->pcs); in phylink_major_config()
1284 if (pl->pcs) in phylink_major_config()
1285 pl->pcs->phylink = NULL; in phylink_major_config()
1287 pcs->phylink = pl; in phylink_major_config()
1289 pl->pcs = pcs; in phylink_major_config()
1292 if (pl->pcs) in phylink_major_config()
1293 phylink_pcs_pre_config(pl->pcs, state->interface); in phylink_major_config()
1297 if (pl->pcs) { in phylink_major_config()
1298 err = phylink_pcs_post_config(pl->pcs, state->interface); in phylink_major_config()
1303 pl->major_config_failed = true; in phylink_major_config()
1307 if (pl->pcs_state == PCS_STATE_STARTING || pcs_changed) in phylink_major_config()
1308 phylink_pcs_enable(pl->pcs); in phylink_major_config()
1310 err = phylink_pcs_config(pl->pcs, pl->pcs_neg_mode, state, in phylink_major_config()
1311 !!(pl->link_config.pause & MLO_PAUSE_AN)); in phylink_major_config()
1314 pl->major_config_failed = true; in phylink_major_config()
1322 if (pl->mac_ops->mac_finish) { in phylink_major_config()
1323 err = pl->mac_ops->mac_finish(pl->config, pl->act_link_an_mode, in phylink_major_config()
1324 state->interface); in phylink_major_config()
1329 pl->major_config_failed = true; in phylink_major_config()
1333 if (pl->phydev && pl->phy_ib_mode) { in phylink_major_config()
1334 err = phy_config_inband(pl->phydev, pl->phy_ib_mode); in phylink_major_config()
1339 pl->major_config_failed = true; in phylink_major_config()
1343 if (pl->sfp_bus) { in phylink_major_config()
1344 rate_kbd = phylink_interface_signal_rate(state->interface); in phylink_major_config()
1346 sfp_upstream_set_signal_rate(pl->sfp_bus, rate_kbd); in phylink_major_config()
1354 * If we have a separate PCS, we only need to call its pcs_config() method,
1362 if (test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) in phylink_change_inband_advert()
1366 phylink_an_mode_str(pl->req_link_an_mode), in phylink_change_inband_advert()
1367 phy_modes(pl->link_config.interface), in phylink_change_inband_advert()
1368 __ETHTOOL_LINK_MODE_MASK_NBITS, pl->link_config.advertising, in phylink_change_inband_advert()
1369 pl->link_config.pause); in phylink_change_inband_advert()
1371 /* Recompute the PCS neg mode */ in phylink_change_inband_advert()
1372 phylink_pcs_neg_mode(pl, pl->pcs, pl->link_config.interface, in phylink_change_inband_advert()
1373 pl->link_config.advertising); in phylink_change_inband_advert()
1375 /* Modern PCS-based method; update the advert at the PCS, and in phylink_change_inband_advert()
1379 ret = phylink_pcs_config(pl->pcs, pl->pcs_neg_mode, &pl->link_config, in phylink_change_inband_advert()
1380 !!(pl->link_config.pause & MLO_PAUSE_AN)); in phylink_change_inband_advert()
1393 struct phylink_pcs *pcs; in phylink_mac_pcs_get_state() local
1396 linkmode_copy(state->advertising, pl->link_config.advertising); in phylink_mac_pcs_get_state()
1397 linkmode_zero(state->lp_advertising); in phylink_mac_pcs_get_state()
1398 state->interface = pl->link_config.interface; in phylink_mac_pcs_get_state()
1399 state->rate_matching = pl->link_config.rate_matching; in phylink_mac_pcs_get_state()
1400 state->an_complete = 0; in phylink_mac_pcs_get_state()
1401 state->link = 1; in phylink_mac_pcs_get_state()
1403 autoneg = pl->pcs_neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED; in phylink_mac_pcs_get_state()
1405 state->speed = SPEED_UNKNOWN; in phylink_mac_pcs_get_state()
1406 state->duplex = DUPLEX_UNKNOWN; in phylink_mac_pcs_get_state()
1407 state->pause = MLO_PAUSE_NONE; in phylink_mac_pcs_get_state()
1409 state->speed = pl->link_config.speed; in phylink_mac_pcs_get_state()
1410 state->duplex = pl->link_config.duplex; in phylink_mac_pcs_get_state()
1411 state->pause = pl->link_config.pause; in phylink_mac_pcs_get_state()
1414 pcs = pl->pcs; in phylink_mac_pcs_get_state()
1415 if (pcs) in phylink_mac_pcs_get_state()
1416 pcs->ops->pcs_get_state(pcs, pl->pcs_neg_mode, state); in phylink_mac_pcs_get_state()
1418 state->link = 0; in phylink_mac_pcs_get_state()
1427 *state = pl->link_config; in phylink_get_fixed_state()
1428 if (pl->config->get_fixed_state) in phylink_get_fixed_state()
1429 pl->config->get_fixed_state(pl->config, state); in phylink_get_fixed_state()
1430 else if (pl->link_gpio) in phylink_get_fixed_state()
1431 state->link = !!gpiod_get_value_cansleep(pl->link_gpio); in phylink_get_fixed_state()
1433 state->pause = MLO_PAUSE_NONE; in phylink_get_fixed_state()
1440 struct phy_device *phy = pl->phydev; in phylink_mac_initial_config()
1442 switch (pl->req_link_an_mode) { in phylink_mac_initial_config()
1444 link_state = pl->phy_state; in phylink_mac_initial_config()
1452 link_state = pl->link_config; in phylink_mac_initial_config()
1465 mutex_lock(&phy->lock); in phylink_mac_initial_config()
1468 mutex_unlock(&phy->lock); in phylink_mac_initial_config()
1487 if (pl->mac_enable_tx_lpi) { in phylink_deactivate_lpi()
1488 pl->mac_enable_tx_lpi = false; in phylink_deactivate_lpi()
1492 pl->mac_ops->mac_disable_tx_lpi(pl->config); in phylink_deactivate_lpi()
1494 phylink_pcs_disable_eee(pl->pcs); in phylink_deactivate_lpi()
1502 if (!test_bit(pl->cur_interface, pl->config->lpi_interfaces)) { in phylink_activate_lpi()
1504 phy_modes(pl->cur_interface)); in phylink_activate_lpi()
1509 pl->mac_tx_lpi_timer, pl->mac_tx_clk_stop); in phylink_activate_lpi()
1511 phylink_pcs_enable_eee(pl->pcs); in phylink_activate_lpi()
1513 err = pl->mac_ops->mac_enable_tx_lpi(pl->config, pl->mac_tx_lpi_timer, in phylink_activate_lpi()
1514 pl->mac_tx_clk_stop); in phylink_activate_lpi()
1516 phylink_pcs_disable_eee(pl->pcs); in phylink_activate_lpi()
1518 pl->mac_ops->mac_enable_tx_lpi, ERR_PTR(err)); in phylink_activate_lpi()
1522 pl->mac_enable_tx_lpi = true; in phylink_activate_lpi()
1528 struct net_device *ndev = pl->netdev; in phylink_link_up()
1557 pl->cur_interface = link_state.interface; in phylink_link_up()
1559 phylink_pcs_link_up(pl->pcs, pl->pcs_neg_mode, pl->cur_interface, speed, in phylink_link_up()
1562 pl->mac_ops->mac_link_up(pl->config, pl->phydev, pl->act_link_an_mode, in phylink_link_up()
1563 pl->cur_interface, speed, duplex, in phylink_link_up()
1566 if (pl->mac_supports_eee && pl->phy_enable_tx_lpi) in phylink_link_up()
1573 "Link is Up - %s/%s - flow control %s\n", in phylink_link_up()
1581 struct net_device *ndev = pl->netdev; in phylink_link_down()
1588 pl->mac_ops->mac_link_down(pl->config, pl->act_link_an_mode, in phylink_link_down()
1589 pl->cur_interface); in phylink_link_down()
1595 return pl->netdev ? netif_carrier_ok(pl->netdev) : pl->old_link_state; in phylink_link_is_up()
1607 mutex_lock(&pl->phydev_mutex); in phylink_resolve()
1608 phy = pl->phydev; in phylink_resolve()
1610 mutex_lock(&phy->lock); in phylink_resolve()
1611 mutex_lock(&pl->state_mutex); in phylink_resolve()
1614 if (pl->phylink_disable_state) { in phylink_resolve()
1615 pl->link_failed = false; in phylink_resolve()
1617 } else if (pl->link_failed) { in phylink_resolve()
1620 } else if (pl->act_link_an_mode == MLO_AN_FIXED) { in phylink_resolve()
1623 } else if (pl->act_link_an_mode == MLO_AN_PHY) { in phylink_resolve()
1624 link_state = pl->phy_state; in phylink_resolve()
1629 /* The PCS may have a latching link-fail indicator. If the link in phylink_resolve()
1630 * was up, bring the link down and re-trigger the resolve. in phylink_resolve()
1631 * Otherwise, re-read the PCS state to get the current status in phylink_resolve()
1645 link_state.link &= pl->phy_state.link; in phylink_resolve()
1648 if (phy && pl->phy_state.link) { in phylink_resolve()
1650 * event if the link isn't already down, and re-resolve. in phylink_resolve()
1652 if (link_state.interface != pl->phy_state.interface) { in phylink_resolve()
1657 link_state.interface = pl->phy_state.interface; in phylink_resolve()
1662 if (pl->phy_state.rate_matching) { in phylink_resolve()
1664 pl->phy_state.rate_matching; in phylink_resolve()
1665 link_state.speed = pl->phy_state.speed; in phylink_resolve()
1666 link_state.duplex = pl->phy_state.duplex; in phylink_resolve()
1672 link_state.pause = pl->phy_state.pause; in phylink_resolve()
1677 if (pl->act_link_an_mode != MLO_AN_FIXED) in phylink_resolve()
1681 if (link_state.interface != pl->link_config.interface) { in phylink_resolve()
1690 pl->link_config.interface = link_state.interface; in phylink_resolve()
1697 if (pl->major_config_failed) in phylink_resolve()
1701 pl->old_link_state = link_state.link; in phylink_resolve()
1708 pl->link_failed = false; in phylink_resolve()
1709 queue_work(system_power_efficient_wq, &pl->resolve); in phylink_resolve()
1711 mutex_unlock(&pl->state_mutex); in phylink_resolve()
1713 mutex_unlock(&phy->lock); in phylink_resolve()
1714 mutex_unlock(&pl->phydev_mutex); in phylink_resolve()
1719 if (!pl->phylink_disable_state) in phylink_run_resolve()
1720 queue_work(system_power_efficient_wq, &pl->resolve); in phylink_run_resolve()
1725 unsigned long state = pl->phylink_disable_state; in phylink_run_resolve_and_disable()
1727 set_bit(bit, &pl->phylink_disable_state); in phylink_run_resolve_and_disable()
1729 queue_work(system_power_efficient_wq, &pl->resolve); in phylink_run_resolve_and_disable()
1730 flush_work(&pl->resolve); in phylink_run_resolve_and_disable()
1736 clear_bit(bit, &pl->phylink_disable_state); in phylink_enable_and_run_resolve()
1766 pl->sfp_bus = bus; in phylink_register_sfp()
1775 * phylink_set_fixed_link() - set the fixed link
1790 if (pl->cfg_link_an_mode != MLO_AN_PHY || !state || in phylink_set_fixed_link()
1791 !test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) in phylink_set_fixed_link()
1792 return -EINVAL; in phylink_set_fixed_link()
1794 c = phy_caps_lookup(state->speed, state->duplex, in phylink_set_fixed_link()
1795 pl->supported, true); in phylink_set_fixed_link()
1797 return -EINVAL; in phylink_set_fixed_link()
1799 adv = pl->link_config.advertising; in phylink_set_fixed_link()
1800 linkmode_and(adv, pl->supported, c->linkmodes); in phylink_set_fixed_link()
1803 pl->link_config.speed = state->speed; in phylink_set_fixed_link()
1804 pl->link_config.duplex = state->duplex; in phylink_set_fixed_link()
1805 pl->link_config.link = 1; in phylink_set_fixed_link()
1806 pl->link_config.an_complete = 1; in phylink_set_fixed_link()
1808 pl->cfg_link_an_mode = MLO_AN_FIXED; in phylink_set_fixed_link()
1809 pl->req_link_an_mode = pl->cfg_link_an_mode; in phylink_set_fixed_link()
1816 * phylink_create() - create a phylink instance
1824 * This will parse in-band modes, fixed-link or SFP configuration.
1828 * Returns a pointer to a &struct phylink, or an error-pointer value. Users
1840 if (phy_interface_empty(config->supported_interfaces)) { in phylink_create()
1841 dev_err(config->dev, in phylink_create()
1843 return ERR_PTR(-EINVAL); in phylink_create()
1848 return ERR_PTR(-ENOMEM); in phylink_create()
1850 mutex_init(&pl->phydev_mutex); in phylink_create()
1851 mutex_init(&pl->state_mutex); in phylink_create()
1852 INIT_WORK(&pl->resolve, phylink_resolve); in phylink_create()
1854 pl->config = config; in phylink_create()
1855 if (config->type == PHYLINK_NETDEV) { in phylink_create()
1856 pl->netdev = to_net_dev(config->dev); in phylink_create()
1857 netif_carrier_off(pl->netdev); in phylink_create()
1858 } else if (config->type == PHYLINK_DEV) { in phylink_create()
1859 pl->dev = config->dev; in phylink_create()
1862 return ERR_PTR(-EINVAL); in phylink_create()
1865 pl->mac_supports_eee_ops = phylink_mac_implements_lpi(mac_ops); in phylink_create()
1866 pl->mac_supports_eee = pl->mac_supports_eee_ops && in phylink_create()
1867 pl->config->lpi_capabilities && in phylink_create()
1868 !phy_interface_empty(pl->config->lpi_interfaces); in phylink_create()
1870 /* Set the default EEE configuration */ in phylink_create()
1871 pl->eee_cfg.eee_enabled = pl->config->eee_enabled_default; in phylink_create()
1872 pl->eee_cfg.tx_lpi_enabled = pl->eee_cfg.eee_enabled; in phylink_create()
1873 pl->eee_cfg.tx_lpi_timer = pl->config->lpi_timer_default; in phylink_create()
1875 pl->phy_state.interface = iface; in phylink_create()
1876 pl->link_interface = iface; in phylink_create()
1878 pl->link_port = PORT_BNC; in phylink_create()
1880 pl->link_port = PORT_MII; in phylink_create()
1881 pl->link_config.interface = iface; in phylink_create()
1882 pl->link_config.pause = MLO_PAUSE_AN; in phylink_create()
1883 pl->link_config.speed = SPEED_UNKNOWN; in phylink_create()
1884 pl->link_config.duplex = DUPLEX_UNKNOWN; in phylink_create()
1885 pl->pcs_state = PCS_STATE_DOWN; in phylink_create()
1886 pl->mac_ops = mac_ops; in phylink_create()
1887 __set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); in phylink_create()
1888 timer_setup(&pl->link_poll, phylink_fixed_poll, 0); in phylink_create()
1890 linkmode_fill(pl->supported); in phylink_create()
1891 linkmode_copy(pl->link_config.advertising, pl->supported); in phylink_create()
1892 phylink_validate(pl, pl->supported, &pl->link_config); in phylink_create()
1900 if (pl->cfg_link_an_mode == MLO_AN_FIXED) { in phylink_create()
1908 pl->req_link_an_mode = pl->cfg_link_an_mode; in phylink_create()
1921 * phylink_destroy() - cleanup and destroy the phylink instance
1931 sfp_bus_del_upstream(pl->sfp_bus); in phylink_destroy()
1932 if (pl->link_gpio) in phylink_destroy()
1933 gpiod_put(pl->link_gpio); in phylink_destroy()
1935 cancel_work_sync(&pl->resolve); in phylink_destroy()
1941 * phylink_expects_phy() - Determine if phylink expects a phy to be attached
1944 * When using fixed-link mode, or in-band mode with 1000base-X or 2500base-X,
1951 if (pl->cfg_link_an_mode == MLO_AN_FIXED || in phylink_expects_phy()
1952 (pl->cfg_link_an_mode == MLO_AN_INBAND && in phylink_expects_phy()
1953 phy_interface_mode_is_8023z(pl->link_interface))) in phylink_expects_phy()
1961 struct phylink *pl = phydev->phylink; in phylink_phy_change()
1966 mutex_lock(&pl->state_mutex); in phylink_phy_change()
1967 pl->phy_state.speed = phydev->speed; in phylink_phy_change()
1968 pl->phy_state.duplex = phydev->duplex; in phylink_phy_change()
1969 pl->phy_state.rate_matching = phydev->rate_matching; in phylink_phy_change()
1970 pl->phy_state.pause = MLO_PAUSE_NONE; in phylink_phy_change()
1972 pl->phy_state.pause |= MLO_PAUSE_TX; in phylink_phy_change()
1974 pl->phy_state.pause |= MLO_PAUSE_RX; in phylink_phy_change()
1975 pl->phy_state.interface = phydev->interface; in phylink_phy_change()
1976 pl->phy_state.link = up; in phylink_phy_change()
1978 pl->link_failed = true; in phylink_phy_change()
1981 pl->phy_enable_tx_lpi = phydev->enable_tx_lpi; in phylink_phy_change()
1982 pl->mac_tx_lpi_timer = phydev->eee_cfg.tx_lpi_timer; in phylink_phy_change()
1983 mutex_unlock(&pl->state_mutex); in phylink_phy_change()
1989 phy_modes(phydev->interface), in phylink_phy_change()
1990 phy_speed_to_str(phydev->speed), in phylink_phy_change()
1991 phy_duplex_to_str(phydev->duplex), in phylink_phy_change()
1992 phy_rate_matching_to_str(phydev->rate_matching), in phylink_phy_change()
1993 phylink_pause_to_str(pl->phy_state.pause), in phylink_phy_change()
1994 phydev->enable_tx_lpi ? "" : "no"); in phylink_phy_change()
2007 if (!phy_interface_empty(phy->possible_interfaces)) { in phylink_validate_phy()
2011 phy_interface_and(interfaces, phy->possible_interfaces, in phylink_validate_phy()
2012 pl->config->supported_interfaces); in phylink_validate_phy()
2016 return -EINVAL; in phylink_validate_phy()
2028 return -EINVAL; in phylink_validate_phy()
2035 phy->possible_interfaces, in phylink_validate_phy()
2048 state->rate_matching = phy_get_rate_matching(phy, state->interface); in phylink_validate_phy()
2050 /* Clause 45 PHYs may switch their Serdes lane between, e.g. 10GBASE-R, in phylink_validate_phy()
2051 * 5GBASE-R, 2500BASE-X and SGMII if they are not using rate matching. in phylink_validate_phy()
2057 * linkmodes can be supported. For now, as a work-around, we validate in phylink_validate_phy()
2061 if (phy->is_c45 && state->rate_matching == RATE_MATCH_NONE && in phylink_validate_phy()
2062 state->interface != PHY_INTERFACE_MODE_RXAUI && in phylink_validate_phy()
2063 state->interface != PHY_INTERFACE_MODE_XAUI && in phylink_validate_phy()
2064 state->interface != PHY_INTERFACE_MODE_USXGMII) in phylink_validate_phy()
2065 state->interface = PHY_INTERFACE_MODE_NA; in phylink_validate_phy()
2088 linkmode_copy(supported, phy->supported); in phylink_bringup_phy()
2089 linkmode_copy(config.advertising, phy->advertising); in phylink_bringup_phy()
2096 __ETHTOOL_LINK_MODE_MASK_NBITS, phy->supported, in phylink_bringup_phy()
2102 phy->phylink = pl; in phylink_bringup_phy()
2103 phy->phy_link_change = phylink_phy_change; in phylink_bringup_phy()
2108 dev_name(&phy->mdio.dev), phy->drv->name, irq_str); in phylink_bringup_phy()
2111 mutex_lock(&pl->phydev_mutex); in phylink_bringup_phy()
2112 mutex_lock(&phy->lock); in phylink_bringup_phy()
2113 mutex_lock(&pl->state_mutex); in phylink_bringup_phy()
2114 pl->phydev = phy; in phylink_bringup_phy()
2115 pl->phy_state.interface = interface; in phylink_bringup_phy()
2116 pl->phy_state.pause = MLO_PAUSE_NONE; in phylink_bringup_phy()
2117 pl->phy_state.speed = SPEED_UNKNOWN; in phylink_bringup_phy()
2118 pl->phy_state.duplex = DUPLEX_UNKNOWN; in phylink_bringup_phy()
2119 pl->phy_state.rate_matching = RATE_MATCH_NONE; in phylink_bringup_phy()
2120 linkmode_copy(pl->supported, supported); in phylink_bringup_phy()
2121 linkmode_copy(pl->link_config.advertising, config.advertising); in phylink_bringup_phy()
2124 linkmode_copy(phy->advertising, config.advertising); in phylink_bringup_phy()
2126 /* If the MAC supports phylink managed EEE, restrict the EEE in phylink_bringup_phy()
2129 if (pl->mac_supports_eee) { in phylink_bringup_phy()
2130 /* If EEE is enabled, then we need to call phy_support_eee() in phylink_bringup_phy()
2132 * This also enables EEE at the PHY. in phylink_bringup_phy()
2134 if (pl->eee_cfg.eee_enabled) in phylink_bringup_phy()
2137 phy->eee_cfg.tx_lpi_enabled = pl->eee_cfg.tx_lpi_enabled; in phylink_bringup_phy()
2138 phy->eee_cfg.tx_lpi_timer = pl->eee_cfg.tx_lpi_timer; in phylink_bringup_phy()
2141 linkmode_zero(pl->supported_lpi); in phylink_bringup_phy()
2142 phylink_caps_to_linkmodes(pl->supported_lpi, in phylink_bringup_phy()
2143 pl->config->lpi_capabilities); in phylink_bringup_phy()
2145 /* Restrict the PHYs EEE support/advertisement to the modes in phylink_bringup_phy()
2148 linkmode_and(phy->advertising_eee, phy->advertising_eee, in phylink_bringup_phy()
2149 pl->supported_lpi); in phylink_bringup_phy()
2150 } else if (pl->mac_supports_eee_ops) { in phylink_bringup_phy()
2151 /* MAC supports phylink EEE, but wants EEE always disabled. */ in phylink_bringup_phy()
2155 mutex_unlock(&pl->state_mutex); in phylink_bringup_phy()
2156 mutex_unlock(&phy->lock); in phylink_bringup_phy()
2157 mutex_unlock(&pl->phydev_mutex); in phylink_bringup_phy()
2162 __ETHTOOL_LINK_MODE_MASK_NBITS, pl->supported, in phylink_bringup_phy()
2163 __ETHTOOL_LINK_MODE_MASK_NBITS, phy->advertising); in phylink_bringup_phy()
2165 if (pl->config->mac_managed_pm) in phylink_bringup_phy()
2166 phy->mac_managed_pm = true; in phylink_bringup_phy()
2169 pl->mac_tx_clk_stop = phy_eee_tx_clock_stop_capable(phy) > 0; in phylink_bringup_phy()
2171 if (pl->mac_supports_eee_ops) { in phylink_bringup_phy()
2176 pl->config->eee_rx_clk_stop_enable); in phylink_bringup_phy()
2177 if (ret == -EOPNOTSUPP) in phylink_bringup_phy()
2192 if (WARN_ON(pl->cfg_link_an_mode == MLO_AN_FIXED || in phylink_attach_phy()
2193 (pl->cfg_link_an_mode == MLO_AN_INBAND && in phylink_attach_phy()
2194 phy_interface_mode_is_8023z(interface) && !pl->sfp_bus))) in phylink_attach_phy()
2195 return -EINVAL; in phylink_attach_phy()
2197 if (pl->phydev) in phylink_attach_phy()
2198 return -EBUSY; in phylink_attach_phy()
2200 if (pl->config->mac_requires_rxc) in phylink_attach_phy()
2203 return phy_attach_direct(pl->netdev, phy, flags, interface); in phylink_attach_phy()
2207 * phylink_connect_phy() - connect a PHY to the phylink instance
2226 if (pl->link_interface == PHY_INTERFACE_MODE_NA) { in phylink_connect_phy()
2227 pl->link_interface = phy->interface; in phylink_connect_phy()
2228 pl->link_config.interface = pl->link_interface; in phylink_connect_phy()
2231 ret = phylink_attach_phy(pl, phy, pl->link_interface); in phylink_connect_phy()
2235 ret = phylink_bringup_phy(pl, phy, pl->link_config.interface); in phylink_connect_phy()
2244 * phylink_of_phy_connect() - connect the PHY specified in the DT mode.
2247 * @flags: PHY-specific flags to communicate to the PHY device driver
2263 * phylink_fwnode_phy_connect() - connect the PHY specified in the fwnode.
2266 * @flags: PHY-specific flags to communicate to the PHY device driver
2282 if (pl->cfg_link_an_mode == MLO_AN_FIXED || in phylink_fwnode_phy_connect()
2283 (pl->cfg_link_an_mode == MLO_AN_INBAND && in phylink_fwnode_phy_connect()
2284 phy_interface_mode_is_8023z(pl->link_interface))) in phylink_fwnode_phy_connect()
2289 if (pl->cfg_link_an_mode == MLO_AN_PHY) in phylink_fwnode_phy_connect()
2290 return -ENODEV; in phylink_fwnode_phy_connect()
2298 return -ENODEV; in phylink_fwnode_phy_connect()
2301 if (pl->link_interface == PHY_INTERFACE_MODE_NA) { in phylink_fwnode_phy_connect()
2302 pl->link_interface = phy_dev->interface; in phylink_fwnode_phy_connect()
2303 pl->link_config.interface = pl->link_interface; in phylink_fwnode_phy_connect()
2306 if (pl->config->mac_requires_rxc) in phylink_fwnode_phy_connect()
2309 ret = phy_attach_direct(pl->netdev, phy_dev, flags, in phylink_fwnode_phy_connect()
2310 pl->link_interface); in phylink_fwnode_phy_connect()
2315 ret = phylink_bringup_phy(pl, phy_dev, pl->link_config.interface); in phylink_fwnode_phy_connect()
2324 * phylink_disconnect_phy() - disconnect any PHY attached to the phylink
2336 mutex_lock(&pl->phydev_mutex); in phylink_disconnect_phy()
2337 phy = pl->phydev; in phylink_disconnect_phy()
2339 mutex_lock(&phy->lock); in phylink_disconnect_phy()
2340 mutex_lock(&pl->state_mutex); in phylink_disconnect_phy()
2341 pl->phydev = NULL; in phylink_disconnect_phy()
2342 pl->phy_enable_tx_lpi = false; in phylink_disconnect_phy()
2343 pl->mac_tx_clk_stop = false; in phylink_disconnect_phy()
2344 mutex_unlock(&pl->state_mutex); in phylink_disconnect_phy()
2345 mutex_unlock(&phy->lock); in phylink_disconnect_phy()
2347 mutex_unlock(&pl->phydev_mutex); in phylink_disconnect_phy()
2350 flush_work(&pl->resolve); in phylink_disconnect_phy()
2359 pl->link_failed = true; in phylink_link_changed()
2365 * phylink_mac_change() - notify phylink of a change in MAC state
2379 * phylink_pcs_change() - notify phylink of a change to PCS link state
2380 * @pcs: pointer to &struct phylink_pcs
2383 * The PCS driver should call this when the state of its link changes
2387 * the latched link-down state, otherwise pass false.
2389 void phylink_pcs_change(struct phylink_pcs *pcs, bool up) in phylink_pcs_change() argument
2391 struct phylink *pl = pcs->phylink; in phylink_pcs_change()
2394 phylink_link_changed(pl, up, "pcs"); in phylink_pcs_change()
2408 * phylink_start() - start a phylink instance
2422 phylink_an_mode_str(pl->req_link_an_mode), in phylink_start()
2423 phy_modes(pl->link_config.interface)); in phylink_start()
2426 if (pl->netdev) in phylink_start()
2427 netif_carrier_off(pl->netdev); in phylink_start()
2429 pl->pcs_state = PCS_STATE_STARTING; in phylink_start()
2432 * a fixed-link to start with the correct parameters, and also in phylink_start()
2441 pl->pcs_state = PCS_STATE_STARTED; in phylink_start()
2445 if (pl->cfg_link_an_mode == MLO_AN_FIXED && pl->link_gpio) { in phylink_start()
2446 int irq = gpiod_to_irq(pl->link_gpio); in phylink_start()
2453 pl->link_irq = irq; in phylink_start()
2461 if (pl->cfg_link_an_mode == MLO_AN_FIXED) in phylink_start()
2462 poll |= pl->config->poll_fixed_state; in phylink_start()
2465 mod_timer(&pl->link_poll, jiffies + HZ); in phylink_start()
2466 if (pl->phydev) in phylink_start()
2467 phy_start(pl->phydev); in phylink_start()
2468 if (pl->sfp_bus) in phylink_start()
2469 sfp_upstream_start(pl->sfp_bus); in phylink_start()
2474 * phylink_stop() - stop a phylink instance
2489 if (pl->sfp_bus) in phylink_stop()
2490 sfp_upstream_stop(pl->sfp_bus); in phylink_stop()
2491 if (pl->phydev) in phylink_stop()
2492 phy_stop(pl->phydev); in phylink_stop()
2493 timer_delete_sync(&pl->link_poll); in phylink_stop()
2494 if (pl->link_irq) { in phylink_stop()
2495 free_irq(pl->link_irq, pl); in phylink_stop()
2496 pl->link_irq = 0; in phylink_stop()
2501 pl->pcs_state = PCS_STATE_DOWN; in phylink_stop()
2503 phylink_pcs_disable(pl->pcs); in phylink_stop()
2508 * phylink_rx_clk_stop_block() - block PHY ability to stop receive clock in LPI
2512 * is in EEE LPI state, until the number of calls to phylink_rx_clk_stop_block()
2519 if (pl->mac_rx_clk_stop_blocked == U8_MAX) { in phylink_rx_clk_stop_block()
2520 phylink_warn(pl, "%s called too many times - ignoring\n", in phylink_rx_clk_stop_block()
2527 * function has been called and clock-stop was previously enabled. in phylink_rx_clk_stop_block()
2529 if (pl->mac_rx_clk_stop_blocked++ == 0 && in phylink_rx_clk_stop_block()
2530 pl->mac_supports_eee_ops && pl->phydev && in phylink_rx_clk_stop_block()
2531 pl->config->eee_rx_clk_stop_enable) in phylink_rx_clk_stop_block()
2532 phy_eee_rx_clock_stop(pl->phydev, false); in phylink_rx_clk_stop_block()
2537 * phylink_rx_clk_stop_unblock() - unblock PHY ability to stop receive clock
2542 * ability to stop the receive clock when the receive path is in EEE LPI mode.
2548 if (pl->mac_rx_clk_stop_blocked == 0) { in phylink_rx_clk_stop_unblock()
2549 phylink_warn(pl, "%s called too many times - ignoring\n", in phylink_rx_clk_stop_unblock()
2555 /* Re-enable PHY receive clock stop if the number of unblocks matches in phylink_rx_clk_stop_unblock()
2558 if (--pl->mac_rx_clk_stop_blocked == 0 && in phylink_rx_clk_stop_unblock()
2559 pl->mac_supports_eee_ops && pl->phydev && in phylink_rx_clk_stop_unblock()
2560 pl->config->eee_rx_clk_stop_enable) in phylink_rx_clk_stop_unblock()
2561 phy_eee_rx_clock_stop(pl->phydev, true); in phylink_rx_clk_stop_unblock()
2566 * phylink_suspend() - handle a network device suspend event
2568 * @mac_wol: true if the MAC needs to receive packets for Wake-on-Lan
2572 * - If Wake-on-Lan is not active, we can bring down the link between
2574 * - If Wake-on-Lan is active, and being handled only by the PHY, we
2576 * - If Wake-on-Lan is active, but being handled by the MAC, the MAC
2583 if (mac_wol && (!pl->netdev || pl->netdev->ethtool->wol_enabled)) { in phylink_suspend()
2584 /* Wake-on-Lan enabled, MAC handling */ in phylink_suspend()
2585 mutex_lock(&pl->state_mutex); in phylink_suspend()
2588 __set_bit(PHYLINK_DISABLE_MAC_WOL, &pl->phylink_disable_state); in phylink_suspend()
2590 pl->suspend_link_up = phylink_link_is_up(pl); in phylink_suspend()
2591 if (pl->suspend_link_up) { in phylink_suspend()
2596 if (pl->netdev) in phylink_suspend()
2597 netif_carrier_off(pl->netdev); in phylink_suspend()
2598 pl->old_link_state = false; in phylink_suspend()
2604 mutex_unlock(&pl->state_mutex); in phylink_suspend()
2612 * phylink_prepare_resume() - prepare to resume a network device
2621 struct phy_device *phydev = pl->phydev; in phylink_prepare_resume()
2631 if (pl->config->mac_requires_rxc && phydev && phydev->suspended) in phylink_prepare_resume()
2637 * phylink_resume() - handle a network device resume event
2647 if (test_bit(PHYLINK_DISABLE_MAC_WOL, &pl->phylink_disable_state)) { in phylink_resume()
2648 /* Wake-on-Lan enabled, MAC handling */ in phylink_resume()
2650 if (pl->suspend_link_up) { in phylink_resume()
2654 * to be printed during resume, which is harmless - in phylink_resume()
2658 mutex_lock(&pl->state_mutex); in phylink_resume()
2660 mutex_unlock(&pl->state_mutex); in phylink_resume()
2663 /* Re-apply the link parameters so that all the settings get in phylink_resume()
2668 /* Re-enable and re-resolve the link parameters */ in phylink_resume()
2677 * phylink_ethtool_get_wol() - get the wake on lan parameters for the PHY
2689 wol->supported = 0; in phylink_ethtool_get_wol()
2690 wol->wolopts = 0; in phylink_ethtool_get_wol()
2692 if (pl->phydev) in phylink_ethtool_get_wol()
2693 phy_ethtool_get_wol(pl->phydev, wol); in phylink_ethtool_get_wol()
2698 * phylink_ethtool_set_wol() - set wake on lan parameters
2710 int ret = -EOPNOTSUPP; in phylink_ethtool_set_wol()
2714 if (pl->phydev) in phylink_ethtool_set_wol()
2715 ret = phy_ethtool_set_wol(pl->phydev, wol); in phylink_ethtool_set_wol()
2726 interface = sfp_select_interface(pl->sfp_bus, link_modes); in phylink_sfp_select_interface()
2735 if (!test_bit(interface, pl->config->supported_interfaces)) { in phylink_sfp_select_interface()
2740 pl->config->supported_interfaces); in phylink_sfp_select_interface()
2757 if (!test_bit(interface, pl->sfp_interfaces)) in phylink_sfp_select_interface_speed()
2794 phylink_merge_link_mode(kset->link_modes.advertising, state->advertising); in phylink_get_ksettings()
2795 linkmode_copy(kset->link_modes.lp_advertising, state->lp_advertising); in phylink_get_ksettings()
2796 if (kset->base.rate_matching == RATE_MATCH_NONE) { in phylink_get_ksettings()
2797 kset->base.speed = state->speed; in phylink_get_ksettings()
2798 kset->base.duplex = state->duplex; in phylink_get_ksettings()
2800 kset->base.autoneg = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, in phylink_get_ksettings()
2801 state->advertising) ? in phylink_get_ksettings()
2806 * phylink_ethtool_ksettings_get() - get the current link settings
2821 if (pl->phydev) in phylink_ethtool_ksettings_get()
2822 phy_ethtool_ksettings_get(pl->phydev, kset); in phylink_ethtool_ksettings_get()
2824 kset->base.port = pl->link_port; in phylink_ethtool_ksettings_get()
2826 linkmode_copy(kset->link_modes.supported, pl->supported); in phylink_ethtool_ksettings_get()
2828 switch (pl->act_link_an_mode) { in phylink_ethtool_ksettings_get()
2831 * current link settings - and note that these also in phylink_ethtool_ksettings_get()
2842 if (pl->phydev) in phylink_ethtool_ksettings_get()
2847 /* The MAC is reporting the link results from its own PCS in phylink_ethtool_ksettings_get()
2848 * layer via in-band status. Report these as the current in phylink_ethtool_ksettings_get()
2866 /* If the PCS doesn't implement inband support, be permissive. */ in phylink_validate_pcs_inband_autoneg()
2875 /* Check whether the PCS implements the required mode */ in phylink_validate_pcs_inband_autoneg()
2880 * phylink_ethtool_ksettings_set() - set the link settings
2893 if (pl->phydev) { in phylink_ethtool_ksettings_set()
2898 pl->supported); in phylink_ethtool_ksettings_set()
2901 * to update the pl->link_config settings: in phylink_ethtool_ksettings_set()
2902 * - the configuration returned via ksettings_get() will come in phylink_ethtool_ksettings_set()
2904 * - link_config.interface will be updated by the PHY calling in phylink_ethtool_ksettings_set()
2906 * - initial link configuration for PHY mode comes from the in phylink_ethtool_ksettings_set()
2908 * - other configuration changes (e.g. pause modes) are in phylink_ethtool_ksettings_set()
2910 * - if in in-band mode with a PHY, the link configuration in phylink_ethtool_ksettings_set()
2913 * - the only possible use would be link_config.advertising in phylink_ethtool_ksettings_set()
2914 * pause modes when in 1000base-X mode with a PHY, but in in phylink_ethtool_ksettings_set()
2918 return phy_ethtool_ksettings_set(pl->phydev, &phy_kset); in phylink_ethtool_ksettings_set()
2921 config = pl->link_config; in phylink_ethtool_ksettings_set()
2923 linkmode_and(config.advertising, kset->link_modes.advertising, in phylink_ethtool_ksettings_set()
2924 pl->supported); in phylink_ethtool_ksettings_set()
2927 switch (kset->base.autoneg) { in phylink_ethtool_ksettings_set()
2932 c = phy_caps_lookup(kset->base.speed, kset->base.duplex, in phylink_ethtool_ksettings_set()
2933 pl->supported, false); in phylink_ethtool_ksettings_set()
2935 return -EINVAL; in phylink_ethtool_ksettings_set()
2940 if (pl->req_link_an_mode == MLO_AN_FIXED) { in phylink_ethtool_ksettings_set()
2941 if (c->speed != pl->link_config.speed || in phylink_ethtool_ksettings_set()
2942 c->duplex != pl->link_config.duplex) in phylink_ethtool_ksettings_set()
2943 return -EINVAL; in phylink_ethtool_ksettings_set()
2947 config.speed = c->speed; in phylink_ethtool_ksettings_set()
2948 config.duplex = c->duplex; in phylink_ethtool_ksettings_set()
2956 if (pl->req_link_an_mode == MLO_AN_FIXED) { in phylink_ethtool_ksettings_set()
2958 pl->link_config.advertising)) in phylink_ethtool_ksettings_set()
2959 return -EINVAL; in phylink_ethtool_ksettings_set()
2968 return -EINVAL; in phylink_ethtool_ksettings_set()
2972 * fixed-link cases. All that is left are in-band links. in phylink_ethtool_ksettings_set()
2975 kset->base.autoneg == AUTONEG_ENABLE); in phylink_ethtool_ksettings_set()
2981 if (pl->sfp_bus) { in phylink_ethtool_ksettings_set()
2982 if (kset->base.autoneg == AUTONEG_ENABLE) in phylink_ethtool_ksettings_set()
2991 return -EINVAL; in phylink_ethtool_ksettings_set()
2994 linkmode_copy(support, pl->supported); in phylink_ethtool_ksettings_set()
2997 phylink_an_mode_str(pl->req_link_an_mode), in phylink_ethtool_ksettings_set()
3000 return -EINVAL; in phylink_ethtool_ksettings_set()
3004 linkmode_copy(support, pl->supported); in phylink_ethtool_ksettings_set()
3006 return -EINVAL; in phylink_ethtool_ksettings_set()
3013 return -EINVAL; in phylink_ethtool_ksettings_set()
3016 * situation, so the PCS is the media-facing entity. in phylink_ethtool_ksettings_set()
3020 return -EINVAL; in phylink_ethtool_ksettings_set()
3022 mutex_lock(&pl->state_mutex); in phylink_ethtool_ksettings_set()
3023 pl->link_config.speed = config.speed; in phylink_ethtool_ksettings_set()
3024 pl->link_config.duplex = config.duplex; in phylink_ethtool_ksettings_set()
3026 if (pl->link_config.interface != config.interface) { in phylink_ethtool_ksettings_set()
3027 /* The interface changed, e.g. 1000base-X <-> 2500base-X */ in phylink_ethtool_ksettings_set()
3029 if (pl->old_link_state) { in phylink_ethtool_ksettings_set()
3031 pl->old_link_state = false; in phylink_ethtool_ksettings_set()
3034 &pl->phylink_disable_state)) in phylink_ethtool_ksettings_set()
3036 pl->link_config.interface = config.interface; in phylink_ethtool_ksettings_set()
3037 linkmode_copy(pl->link_config.advertising, config.advertising); in phylink_ethtool_ksettings_set()
3038 } else if (!linkmode_equal(pl->link_config.advertising, in phylink_ethtool_ksettings_set()
3040 linkmode_copy(pl->link_config.advertising, config.advertising); in phylink_ethtool_ksettings_set()
3043 mutex_unlock(&pl->state_mutex); in phylink_ethtool_ksettings_set()
3050 * phylink_ethtool_nway_reset() - restart negotiation
3066 if (pl->phydev) in phylink_ethtool_nway_reset()
3067 ret = phy_restart_aneg(pl->phydev); in phylink_ethtool_nway_reset()
3075 * phylink_ethtool_get_pauseparam() - get the current pause parameters
3084 pause->autoneg = !!(pl->link_config.pause & MLO_PAUSE_AN); in phylink_ethtool_get_pauseparam()
3085 pause->rx_pause = !!(pl->link_config.pause & MLO_PAUSE_RX); in phylink_ethtool_get_pauseparam()
3086 pause->tx_pause = !!(pl->link_config.pause & MLO_PAUSE_TX); in phylink_ethtool_get_pauseparam()
3091 * phylink_ethtool_set_pauseparam() - set the current pause parameters
3098 struct phylink_link_state *config = &pl->link_config; in phylink_ethtool_set_pauseparam()
3104 if (pl->req_link_an_mode == MLO_AN_FIXED) in phylink_ethtool_set_pauseparam()
3105 return -EOPNOTSUPP; in phylink_ethtool_set_pauseparam()
3107 if (!phylink_test(pl->supported, Pause) && in phylink_ethtool_set_pauseparam()
3108 !phylink_test(pl->supported, Asym_Pause)) in phylink_ethtool_set_pauseparam()
3109 return -EOPNOTSUPP; in phylink_ethtool_set_pauseparam()
3111 if (!phylink_test(pl->supported, Asym_Pause) && in phylink_ethtool_set_pauseparam()
3112 pause->rx_pause != pause->tx_pause) in phylink_ethtool_set_pauseparam()
3113 return -EINVAL; in phylink_ethtool_set_pauseparam()
3116 if (pause->autoneg) in phylink_ethtool_set_pauseparam()
3118 if (pause->rx_pause) in phylink_ethtool_set_pauseparam()
3120 if (pause->tx_pause) in phylink_ethtool_set_pauseparam()
3123 mutex_lock(&pl->state_mutex); in phylink_ethtool_set_pauseparam()
3137 linkmode_set_pause(config->advertising, pause->tx_pause, in phylink_ethtool_set_pauseparam()
3138 pause->rx_pause); in phylink_ethtool_set_pauseparam()
3140 manual_changed = (config->pause ^ pause_state) & MLO_PAUSE_AN || in phylink_ethtool_set_pauseparam()
3142 (config->pause ^ pause_state) & MLO_PAUSE_TXRX_MASK); in phylink_ethtool_set_pauseparam()
3144 config->pause = pause_state; in phylink_ethtool_set_pauseparam()
3146 /* Update our in-band advertisement, triggering a renegotiation if in phylink_ethtool_set_pauseparam()
3149 if (!pl->phydev) in phylink_ethtool_set_pauseparam()
3152 mutex_unlock(&pl->state_mutex); in phylink_ethtool_set_pauseparam()
3159 if (pl->phydev) in phylink_ethtool_set_pauseparam()
3160 phy_set_asym_pause(pl->phydev, pause->rx_pause, in phylink_ethtool_set_pauseparam()
3161 pause->tx_pause); in phylink_ethtool_set_pauseparam()
3168 pl->link_failed = true; in phylink_ethtool_set_pauseparam()
3177 * phylink_get_eee_err() - read the energy efficient ethernet error
3192 if (pl->phydev) in phylink_get_eee_err()
3193 ret = phy_get_eee_err(pl->phydev); in phylink_get_eee_err()
3200 * phylink_ethtool_get_eee() - read the energy efficient ethernet parameters
3202 * @eee: a pointer to a &struct ethtool_keee for the read parameters
3204 int phylink_ethtool_get_eee(struct phylink *pl, struct ethtool_keee *eee) in phylink_ethtool_get_eee() argument
3206 int ret = -EOPNOTSUPP; in phylink_ethtool_get_eee()
3210 if (pl->mac_supports_eee_ops && !pl->mac_supports_eee) in phylink_ethtool_get_eee()
3213 if (pl->phydev) { in phylink_ethtool_get_eee()
3214 ret = phy_ethtool_get_eee(pl->phydev, eee); in phylink_ethtool_get_eee()
3216 if (ret == 0 && pl->mac_supports_eee_ops) in phylink_ethtool_get_eee()
3217 linkmode_and(eee->supported, eee->supported, in phylink_ethtool_get_eee()
3218 pl->supported_lpi); in phylink_ethtool_get_eee()
3226 * phylink_ethtool_set_eee() - set the energy efficient ethernet parameters
3228 * @eee: a pointer to a &struct ethtool_keee for the desired parameters
3230 int phylink_ethtool_set_eee(struct phylink *pl, struct ethtool_keee *eee) in phylink_ethtool_set_eee() argument
3232 bool mac_eee = pl->mac_supports_eee; in phylink_ethtool_set_eee()
3233 int ret = -EOPNOTSUPP; in phylink_ethtool_set_eee()
3237 phylink_dbg(pl, "mac %s phylink EEE%s, adv %*pbl, LPI%s timer %uus\n", in phylink_ethtool_set_eee()
3239 eee->eee_enabled ? ", enabled" : "", in phylink_ethtool_set_eee()
3240 __ETHTOOL_LINK_MODE_MASK_NBITS, eee->advertised, in phylink_ethtool_set_eee()
3241 eee->tx_lpi_enabled ? " enabled" : "", eee->tx_lpi_timer); in phylink_ethtool_set_eee()
3243 if (pl->mac_supports_eee_ops && !mac_eee) in phylink_ethtool_set_eee()
3246 if (pl->phydev) { in phylink_ethtool_set_eee()
3248 if (pl->mac_supports_eee_ops) in phylink_ethtool_set_eee()
3249 linkmode_and(eee->advertised, eee->advertised, in phylink_ethtool_set_eee()
3250 pl->supported_lpi); in phylink_ethtool_set_eee()
3251 ret = phy_ethtool_set_eee(pl->phydev, eee); in phylink_ethtool_set_eee()
3253 eee_to_eeecfg(&pl->eee_cfg, eee); in phylink_ethtool_set_eee()
3260 /* This emulates MII registers for a fixed-mode phy operating as per the
3269 unsigned long *lpa = state->lp_advertising; in phylink_mii_emul_read()
3272 fs.link = state->link; in phylink_mii_emul_read()
3273 fs.speed = state->speed; in phylink_mii_emul_read()
3274 fs.duplex = state->duplex; in phylink_mii_emul_read()
3280 if (!state->an_complete) in phylink_mii_emul_read()
3289 struct phy_device *phydev = pl->phydev; in phylink_phy_read()
3295 return mdiobus_c45_read(pl->phydev->mdio.bus, prtad, devad, in phylink_phy_read()
3299 if (phydev->is_c45) { in phylink_phy_read()
3305 devad = __ffs(phydev->c45_ids.mmds_present); in phylink_phy_read()
3309 if (!(phydev->c45_ids.mmds_present & MDIO_DEVS_AN)) in phylink_phy_read()
3310 return -EINVAL; in phylink_phy_read()
3318 return -EINVAL; in phylink_phy_read()
3321 return mdiobus_c45_read(pl->phydev->mdio.bus, prtad, devad, in phylink_phy_read()
3325 return mdiobus_read(pl->phydev->mdio.bus, phy_id, reg); in phylink_phy_read()
3331 struct phy_device *phydev = pl->phydev; in phylink_phy_write()
3337 return mdiobus_c45_write(pl->phydev->mdio.bus, prtad, devad, in phylink_phy_write()
3341 if (phydev->is_c45) { in phylink_phy_write()
3347 devad = __ffs(phydev->c45_ids.mmds_present); in phylink_phy_write()
3351 if (!(phydev->c45_ids.mmds_present & MDIO_DEVS_AN)) in phylink_phy_write()
3352 return -EINVAL; in phylink_phy_write()
3360 return -EINVAL; in phylink_phy_write()
3362 return mdiobus_c45_write(pl->phydev->mdio.bus, phy_id, devad, in phylink_phy_write()
3366 return mdiobus_write(phydev->mdio.bus, phy_id, reg, val); in phylink_phy_write()
3375 switch (pl->act_link_an_mode) { in phylink_mii_read()
3384 return -EOPNOTSUPP; in phylink_mii_read()
3400 switch (pl->act_link_an_mode) { in phylink_mii_write()
3405 return -EOPNOTSUPP; in phylink_mii_write()
3415 * phylink_mii_ioctl() - generic mii ioctl interface
3439 if (pl->phydev) { in phylink_mii_ioctl()
3443 mii->phy_id = pl->phydev->mdio.addr; in phylink_mii_ioctl()
3447 ret = phylink_phy_read(pl, mii->phy_id, mii->reg_num); in phylink_mii_ioctl()
3449 mii->val_out = ret; in phylink_mii_ioctl()
3455 ret = phylink_phy_write(pl, mii->phy_id, mii->reg_num, in phylink_mii_ioctl()
3456 mii->val_in); in phylink_mii_ioctl()
3460 ret = phy_mii_ioctl(pl->phydev, ifr, cmd); in phylink_mii_ioctl()
3466 mii->phy_id = 0; in phylink_mii_ioctl()
3470 ret = phylink_mii_read(pl, mii->phy_id, mii->reg_num); in phylink_mii_ioctl()
3472 mii->val_out = ret; in phylink_mii_ioctl()
3478 ret = phylink_mii_write(pl, mii->phy_id, mii->reg_num, in phylink_mii_ioctl()
3479 mii->val_in); in phylink_mii_ioctl()
3483 ret = -EOPNOTSUPP; in phylink_mii_ioctl()
3493 * phylink_speed_down() - set the non-SFP PHY to lowest speed supported by both
3510 if (!pl->sfp_bus && pl->phydev) in phylink_speed_down()
3511 ret = phy_speed_down(pl->phydev, sync); in phylink_speed_down()
3518 * phylink_speed_up() - restore the advertised speeds prior to the call to
3533 if (!pl->sfp_bus && pl->phydev) in phylink_speed_up()
3534 ret = phy_speed_up(pl->phydev); in phylink_speed_up()
3544 pl->netdev->sfp_bus = bus; in phylink_sfp_attach()
3551 pl->netdev->sfp_bus = NULL; in phylink_sfp_detach()
3577 phylink_an_mode_str(mode), phy_modes(state->interface), in phylink_sfp_set_config()
3580 if (!linkmode_equal(pl->supported, supported)) { in phylink_sfp_set_config()
3581 linkmode_copy(pl->supported, supported); in phylink_sfp_set_config()
3585 if (!linkmode_equal(pl->link_config.advertising, state->advertising)) { in phylink_sfp_set_config()
3586 linkmode_copy(pl->link_config.advertising, state->advertising); in phylink_sfp_set_config()
3590 if (pl->req_link_an_mode != mode || in phylink_sfp_set_config()
3591 pl->link_config.interface != state->interface) { in phylink_sfp_set_config()
3592 pl->req_link_an_mode = mode; in phylink_sfp_set_config()
3593 pl->link_config.interface = state->interface; in phylink_sfp_set_config()
3599 phy_modes(state->interface)); in phylink_sfp_set_config()
3603 &pl->phylink_disable_state)) in phylink_sfp_set_config()
3613 /* We're not using pl->sfp_interfaces, so clear it. */ in phylink_sfp_config_phy()
3614 phy_interface_zero(pl->sfp_interfaces); in phylink_sfp_config_phy()
3615 linkmode_copy(support, phy->supported); in phylink_sfp_config_phy()
3618 linkmode_copy(config.advertising, phy->advertising); in phylink_sfp_config_phy()
3635 return -EINVAL; in phylink_sfp_config_phy()
3651 pl->link_port = pl->sfp_port; in phylink_sfp_config_phy()
3668 pl->config->supported_interfaces, in phylink_sfp_config_optical()
3670 pl->sfp_interfaces); in phylink_sfp_config_optical()
3672 /* Find the union of the supported interfaces by the PCS/MAC and in phylink_sfp_config_optical()
3675 phy_interface_and(pl->sfp_interfaces, pl->config->supported_interfaces, in phylink_sfp_config_optical()
3676 pl->sfp_interfaces); in phylink_sfp_config_optical()
3677 if (phy_interface_empty(pl->sfp_interfaces)) { in phylink_sfp_config_optical()
3679 return -EINVAL; in phylink_sfp_config_optical()
3683 linkmode_copy(support, pl->sfp_support); in phylink_sfp_config_optical()
3684 linkmode_copy(config.advertising, pl->sfp_support); in phylink_sfp_config_optical()
3692 ret = phylink_validate_mask(pl, NULL, pl->sfp_support, &config, in phylink_sfp_config_optical()
3693 pl->sfp_interfaces); in phylink_sfp_config_optical()
3700 interface = phylink_choose_sfp_interface(pl, pl->sfp_interfaces); in phylink_sfp_config_optical()
3703 return -EINVAL; in phylink_sfp_config_optical()
3716 if (phy_interface_weight(pl->sfp_interfaces) == 1) { in phylink_sfp_config_optical()
3718 pl->sfp_support); in phylink_sfp_config_optical()
3728 phylink_err(pl, "autoneg setting not compatible with PCS"); in phylink_sfp_config_optical()
3729 return -EINVAL; in phylink_sfp_config_optical()
3743 pl->link_port = pl->sfp_port; in phylink_sfp_config_optical()
3745 phylink_sfp_set_config(pl, pl->sfp_support, &config, false); in phylink_sfp_config_optical()
3758 caps = sfp_get_module_caps(pl->sfp_bus); in phylink_sfp_module_insert()
3759 phy_interface_copy(pl->sfp_interfaces, caps->interfaces); in phylink_sfp_module_insert()
3760 linkmode_copy(pl->sfp_support, caps->link_modes); in phylink_sfp_module_insert()
3761 pl->sfp_may_have_phy = caps->may_have_phy; in phylink_sfp_module_insert()
3762 pl->sfp_port = caps->port; in phylink_sfp_module_insert()
3765 if (pl->sfp_may_have_phy) in phylink_sfp_module_insert()
3775 phy_interface_zero(pl->sfp_interfaces); in phylink_sfp_module_remove()
3783 if (pl->phydev) { in phylink_sfp_module_start()
3784 phy_start(pl->phydev); in phylink_sfp_module_start()
3791 if (!pl->sfp_may_have_phy) in phylink_sfp_module_start()
3802 if (pl->phydev) in phylink_sfp_module_stop()
3803 phy_stop(pl->phydev); in phylink_sfp_module_stop()
3828 if (!phy->drv) { in phylink_sfp_connect_phy()
3830 phydev_name(phy), (unsigned long)phy->phy_id); in phylink_sfp_connect_phy()
3832 return -EINVAL; in phylink_sfp_connect_phy()
3845 phy_interface_and(phy->host_interfaces, phylink_sfp_interfaces, in phylink_sfp_connect_phy()
3846 pl->config->supported_interfaces); in phylink_sfp_connect_phy()
3879 /* 100GBASE-KP4 and 100GBASE-CR10 not supported */
3884 /* 5GBASE-KR not supported */
3895 if (linkmode_test_bit(bit, state->advertising) && in phylink_resolve_c73()
3896 linkmode_test_bit(bit, state->lp_advertising)) in phylink_resolve_c73()
3901 state->speed = phylink_c73_priority_resolution[i].speed; in phylink_resolve_c73()
3902 state->duplex = DUPLEX_FULL; in phylink_resolve_c73()
3905 state->link = false; in phylink_resolve_c73()
3922 mii_lpa_mod_linkmode_x(state->lp_advertising, config_reg, fd_bit); in phylink_decode_c37_word()
3924 if (linkmode_test_bit(fd_bit, state->advertising) && in phylink_decode_c37_word()
3925 linkmode_test_bit(fd_bit, state->lp_advertising)) { in phylink_decode_c37_word()
3926 state->speed = speed; in phylink_decode_c37_word()
3927 state->duplex = DUPLEX_FULL; in phylink_decode_c37_word()
3930 state->link = false; in phylink_decode_c37_word()
3940 state->link = false; in phylink_decode_sgmii_word()
3946 state->speed = SPEED_10; in phylink_decode_sgmii_word()
3949 state->speed = SPEED_100; in phylink_decode_sgmii_word()
3952 state->speed = SPEED_1000; in phylink_decode_sgmii_word()
3955 state->link = false; in phylink_decode_sgmii_word()
3959 state->duplex = DUPLEX_FULL; in phylink_decode_sgmii_word()
3961 state->duplex = DUPLEX_HALF; in phylink_decode_sgmii_word()
3965 * phylink_decode_usxgmii_word() - decode the USXGMII word from a MAC PCS
3967 * @lpa: a 16 bit value which stores the USXGMII auto-negotiation word
3969 * Helper for MAC PCS supporting the USXGMII protocol and the auto-negotiation
3978 state->speed = SPEED_10; in phylink_decode_usxgmii_word()
3981 state->speed = SPEED_100; in phylink_decode_usxgmii_word()
3984 state->speed = SPEED_1000; in phylink_decode_usxgmii_word()
3987 state->speed = SPEED_2500; in phylink_decode_usxgmii_word()
3990 state->speed = SPEED_5000; in phylink_decode_usxgmii_word()
3993 state->speed = SPEED_10000; in phylink_decode_usxgmii_word()
3996 state->link = false; in phylink_decode_usxgmii_word()
4001 state->duplex = DUPLEX_FULL; in phylink_decode_usxgmii_word()
4003 state->duplex = DUPLEX_HALF; in phylink_decode_usxgmii_word()
4008 * phylink_decode_usgmii_word() - decode the USGMII word from a MAC PCS
4010 * @lpa: a 16 bit value which stores the USGMII auto-negotiation word
4012 * Helper for MAC PCS supporting the USGMII protocol and the auto-negotiation
4023 state->speed = SPEED_10; in phylink_decode_usgmii_word()
4026 state->speed = SPEED_100; in phylink_decode_usgmii_word()
4029 state->speed = SPEED_1000; in phylink_decode_usgmii_word()
4032 state->link = false; in phylink_decode_usgmii_word()
4037 state->duplex = DUPLEX_FULL; in phylink_decode_usgmii_word()
4039 state->duplex = DUPLEX_HALF; in phylink_decode_usgmii_word()
4043 * phylink_mii_c22_pcs_decode_state() - Decode MAC PCS state from MII registers
4049 * Helper for MAC PCS supporting the 802.3 clause 22 register set for
4060 state->link = !!(bmsr & BMSR_LSTATUS); in phylink_mii_c22_pcs_decode_state()
4061 state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE); in phylink_mii_c22_pcs_decode_state()
4064 if (!state->link) in phylink_mii_c22_pcs_decode_state()
4067 switch (state->interface) { in phylink_mii_c22_pcs_decode_state()
4072 state->speed = SPEED_1000; in phylink_mii_c22_pcs_decode_state()
4073 state->duplex = DUPLEX_FULL; in phylink_mii_c22_pcs_decode_state()
4074 state->pause |= MLO_PAUSE_TX | MLO_PAUSE_RX; in phylink_mii_c22_pcs_decode_state()
4082 state->speed = SPEED_2500; in phylink_mii_c22_pcs_decode_state()
4083 state->duplex = DUPLEX_FULL; in phylink_mii_c22_pcs_decode_state()
4084 state->pause |= MLO_PAUSE_TX | MLO_PAUSE_RX; in phylink_mii_c22_pcs_decode_state()
4100 state->link = false; in phylink_mii_c22_pcs_decode_state()
4107 * phylink_mii_c22_pcs_get_state() - read the MAC PCS state
4108 * @pcs: a pointer to a &struct mdio_device.
4112 * Helper for MAC PCS supporting the 802.3 clause 22 register set for
4115 * Read the MAC PCS state from the MII device configured in @config and
4121 void phylink_mii_c22_pcs_get_state(struct mdio_device *pcs, in phylink_mii_c22_pcs_get_state() argument
4127 bmsr = mdiodev_read(pcs, MII_BMSR); in phylink_mii_c22_pcs_get_state()
4128 lpa = mdiodev_read(pcs, MII_LPA); in phylink_mii_c22_pcs_get_state()
4130 state->link = false; in phylink_mii_c22_pcs_get_state()
4139 * phylink_mii_c22_pcs_encode_advertisement() - configure the clause 37 PCS
4144 * Helper for MAC PCS supporting the 802.3 clause 22 register set for
4147 * Encode the clause 37 PCS advertisement as specified by @interface and
4150 * Return: The new value for @adv, or ``-EINVAL`` if it should not be changed.
4173 return -EINVAL; in phylink_mii_c22_pcs_encode_advertisement()
4179 * phylink_mii_c22_pcs_config() - configure clause 22 PCS
4180 * @pcs: a pointer to a &struct mdio_device.
4183 * @neg_mode: PCS negotiation mode
4185 * Configure a Clause 22 PCS PHY with the appropriate negotiation
4190 int phylink_mii_c22_pcs_config(struct mdio_device *pcs, in phylink_mii_c22_pcs_config() argument
4201 ret = mdiobus_modify_changed(pcs->bus, pcs->addr, in phylink_mii_c22_pcs_config()
4214 ret = mdiodev_modify(pcs, MII_BMCR, BMCR_ANENABLE | BMCR_ISOLATE, bmcr); in phylink_mii_c22_pcs_config()
4223 * phylink_mii_c22_pcs_an_restart() - restart 802.3z autonegotiation
4224 * @pcs: a pointer to a &struct mdio_device.
4226 * Helper for MAC PCS supporting the 802.3 clause 22 register set for
4233 void phylink_mii_c22_pcs_an_restart(struct mdio_device *pcs) in phylink_mii_c22_pcs_an_restart() argument
4235 int val = mdiodev_read(pcs, MII_BMCR); in phylink_mii_c22_pcs_an_restart()
4240 mdiodev_write(pcs, MII_BMCR, val); in phylink_mii_c22_pcs_an_restart()
4245 void phylink_mii_c45_pcs_get_state(struct mdio_device *pcs, in phylink_mii_c45_pcs_get_state() argument
4248 struct mii_bus *bus = pcs->bus; in phylink_mii_c45_pcs_get_state()
4249 int addr = pcs->addr; in phylink_mii_c45_pcs_get_state()
4254 state->link = false; in phylink_mii_c45_pcs_get_state()
4258 state->link = !!(stat & MDIO_STAT1_LSTATUS); in phylink_mii_c45_pcs_get_state()
4259 if (!state->link) in phylink_mii_c45_pcs_get_state()
4262 switch (state->interface) { in phylink_mii_c45_pcs_get_state()
4264 state->speed = SPEED_10000; in phylink_mii_c45_pcs_get_state()
4265 state->duplex = DUPLEX_FULL; in phylink_mii_c45_pcs_get_state()