Lines Matching +full:asym +full:- +full:pause

1 // SPDX-License-Identifier: GPL-2.0
4 * technologies such as SFP cages where the PHY is hot-pluggable.
23 #include "phy-caps.h"
45 * struct phylink - internal data type for phylink
62 u8 link_port; /* The current non-phy ethtool port */
105 if ((pl)->config->type == PHYLINK_NETDEV) \
106 netdev_printk(level, (pl)->netdev, fmt, ##__VA_ARGS__); \
107 else if ((pl)->config->type == PHYLINK_DEV) \
108 dev_printk(level, (pl)->dev, fmt, ##__VA_ARGS__); \
120 if ((pl)->config->type == PHYLINK_NETDEV) \
121 netdev_dbg((pl)->netdev, fmt, ##__VA_ARGS__); \
122 else if ((pl)->config->type == PHYLINK_DEV) \
123 dev_dbg((pl)->dev, fmt, ##__VA_ARGS__); \
150 * phylink_set_port_modes() - set the port type modes in the ethtool mask
173 phylink_set(tmp, Pause); in phylink_is_empty_linkmode()
200 return "inband,an-enabled"; in phylink_pcs_mode_str()
202 return "inband,an-disabled"; in phylink_pcs_mode_str()
226 * phylink_interface_max_speed() - get the maximum speed of a phy interface
322 * phylink_caps_to_link_caps() - Convert a set of MAC capabilities LINK caps
325 * Returns: The corresponding set of LINK_CAPA as defined in phy-caps.h
352 * phylink_caps_to_linkmodes() - Convert capabilities to ethtool link modes
356 * Set all possible pause, speed and duplex linkmodes in @linkmodes that are
374 * phylink_limit_mac_speed - limit the phylink_config to a maximum speed
387 config->mac_capabilities &= ~phylink_caps_params[i].mask; in phylink_limit_mac_speed()
392 * phylink_cap_from_speed_duplex - Get mac capability from speed/duplex
416 * phylink_get_capabilities() - get capabilities for a given MAC
443 /* The MAC must support asymmetric pause towards the local in phylink_get_capabilities()
444 * device for this. We could allow just symmetric pause, but in phylink_get_capabilities()
446 * doesn't support pause. This is because there's no way to in phylink_get_capabilities()
447 * accept pause frames without transmitting them if we only in phylink_get_capabilities()
448 * support symmetric pause. in phylink_get_capabilities()
478 * phylink_validate_mask_caps() - Restrict link modes based on caps
496 caps = phylink_get_capabilities(state->interface, mac_capabilities, in phylink_validate_mask_caps()
497 state->rate_matching); in phylink_validate_mask_caps()
501 linkmode_and(state->advertising, state->advertising, mask); in phylink_validate_mask_caps()
513 if (pl->mac_ops->mac_select_pcs) { in phylink_validate_mac_and_pcs()
514 pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface); in phylink_validate_mac_and_pcs()
524 if (!pcs->ops) { in phylink_validate_mac_and_pcs()
526 phy_modes(state->interface)); in phylink_validate_mac_and_pcs()
528 return -EINVAL; in phylink_validate_mac_and_pcs()
535 if (!phy_interface_empty(pcs->supported_interfaces) && in phylink_validate_mac_and_pcs()
536 !test_bit(state->interface, pcs->supported_interfaces)) { in phylink_validate_mac_and_pcs()
538 phy_modes(state->interface)); in phylink_validate_mac_and_pcs()
539 return -EINVAL; in phylink_validate_mac_and_pcs()
543 if (pcs->ops->pcs_validate) { in phylink_validate_mac_and_pcs()
544 ret = pcs->ops->pcs_validate(pcs, supported, state); in phylink_validate_mac_and_pcs()
546 return -EINVAL; in phylink_validate_mac_and_pcs()
551 linkmode_and(state->advertising, state->advertising, in phylink_validate_mac_and_pcs()
557 if (pl->mac_ops->mac_get_caps) in phylink_validate_mac_and_pcs()
558 capabilities = pl->mac_ops->mac_get_caps(pl->config, in phylink_validate_mac_and_pcs()
559 state->interface); in phylink_validate_mac_and_pcs()
561 capabilities = pl->config->mac_capabilities; in phylink_validate_mac_and_pcs()
565 return phylink_is_empty_linkmode(supported) ? -EINVAL : 0; in phylink_validate_mac_and_pcs()
612 linkmode_copy(state->advertising, all_adv); in phylink_validate_mask()
614 return phylink_is_empty_linkmode(supported) ? -EINVAL : 0; in phylink_validate_mask()
620 const unsigned long *interfaces = pl->config->supported_interfaces; in phylink_validate()
622 if (state->interface == PHY_INTERFACE_MODE_NA) in phylink_validate()
626 if (!test_bit(state->interface, interfaces)) in phylink_validate()
627 return -EINVAL; in phylink_validate()
656 fixed_node = fwnode_get_named_child_node(fwnode, "fixed-link"); in phylink_parse_fixedlink()
660 pl->link_config.speed = speed; in phylink_parse_fixedlink()
661 pl->link_config.duplex = DUPLEX_HALF; in phylink_parse_fixedlink()
663 if (fwnode_property_read_bool(fixed_node, "full-duplex")) in phylink_parse_fixedlink()
664 pl->link_config.duplex = DUPLEX_FULL; in phylink_parse_fixedlink()
666 /* We treat the "pause" and "asym-pause" terminology as in phylink_parse_fixedlink()
669 if (fwnode_property_read_bool(fixed_node, "pause")) in phylink_parse_fixedlink()
671 pl->link_config.lp_advertising); in phylink_parse_fixedlink()
672 if (fwnode_property_read_bool(fixed_node, "asym-pause")) in phylink_parse_fixedlink()
674 pl->link_config.lp_advertising); in phylink_parse_fixedlink()
681 pl->link_gpio = desc; in phylink_parse_fixedlink()
682 else if (desc == ERR_PTR(-EPROBE_DEFER)) in phylink_parse_fixedlink()
683 ret = -EPROBE_DEFER; in phylink_parse_fixedlink()
692 ret = fwnode_property_read_u32_array(fwnode, "fixed-link", in phylink_parse_fixedlink()
695 phylink_err(pl, "broken fixed-link?\n"); in phylink_parse_fixedlink()
696 return -EINVAL; in phylink_parse_fixedlink()
699 ret = fwnode_property_read_u32_array(fwnode, "fixed-link", in phylink_parse_fixedlink()
702 pl->link_config.duplex = prop[1] ? in phylink_parse_fixedlink()
704 pl->link_config.speed = prop[2]; in phylink_parse_fixedlink()
707 pl->link_config.lp_advertising); in phylink_parse_fixedlink()
710 pl->link_config.lp_advertising); in phylink_parse_fixedlink()
714 if (pl->link_config.speed > SPEED_1000 && in phylink_parse_fixedlink()
715 pl->link_config.duplex != DUPLEX_FULL) in phylink_parse_fixedlink()
717 pl->link_config.speed); in phylink_parse_fixedlink()
719 linkmode_zero(pl->supported); in phylink_parse_fixedlink()
720 phylink_fill_fixedlink_supported(pl->supported); in phylink_parse_fixedlink()
722 linkmode_copy(pl->link_config.advertising, pl->supported); in phylink_parse_fixedlink()
723 phylink_validate(pl, pl->supported, &pl->link_config); in phylink_parse_fixedlink()
725 c = phy_caps_lookup(pl->link_config.speed, pl->link_config.duplex, in phylink_parse_fixedlink()
726 pl->supported, true); in phylink_parse_fixedlink()
728 linkmode_and(match, pl->supported, c->linkmodes); in phylink_parse_fixedlink()
733 linkmode_and(pl->supported, pl->supported, mask); in phylink_parse_fixedlink()
735 phylink_set(pl->supported, MII); in phylink_parse_fixedlink()
738 linkmode_or(pl->supported, pl->supported, match); in phylink_parse_fixedlink()
739 linkmode_or(pl->link_config.lp_advertising, in phylink_parse_fixedlink()
740 pl->link_config.lp_advertising, match); in phylink_parse_fixedlink()
743 pl->link_config.duplex == DUPLEX_FULL ? "full" : "half", in phylink_parse_fixedlink()
744 pl->link_config.speed); in phylink_parse_fixedlink()
747 linkmode_and(pl->link_config.advertising, pl->link_config.advertising, in phylink_parse_fixedlink()
748 pl->supported); in phylink_parse_fixedlink()
750 pl->link_config.link = 1; in phylink_parse_fixedlink()
751 pl->link_config.an_complete = 1; in phylink_parse_fixedlink()
763 if (pl->config->default_an_inband) in phylink_parse_mode()
764 pl->cfg_link_an_mode = MLO_AN_INBAND; in phylink_parse_mode()
766 dn = fwnode_get_named_child_node(fwnode, "fixed-link"); in phylink_parse_mode()
767 if (dn || fwnode_property_present(fwnode, "fixed-link")) in phylink_parse_mode()
768 pl->cfg_link_an_mode = MLO_AN_FIXED; in phylink_parse_mode()
772 strcmp(managed, "in-band-status") == 0)) { in phylink_parse_mode()
773 if (pl->cfg_link_an_mode == MLO_AN_FIXED) { in phylink_parse_mode()
775 "can't use both fixed-link and in-band-status\n"); in phylink_parse_mode()
776 return -EINVAL; in phylink_parse_mode()
779 pl->cfg_link_an_mode = MLO_AN_INBAND; in phylink_parse_mode()
782 if (pl->cfg_link_an_mode == MLO_AN_INBAND) { in phylink_parse_mode()
783 linkmode_zero(pl->supported); in phylink_parse_mode()
784 phylink_set(pl->supported, MII); in phylink_parse_mode()
785 phylink_set(pl->supported, Autoneg); in phylink_parse_mode()
786 phylink_set(pl->supported, Asym_Pause); in phylink_parse_mode()
787 phylink_set(pl->supported, Pause); in phylink_parse_mode()
789 switch (pl->link_config.interface) { in phylink_parse_mode()
809 caps = phylink_get_capabilities(pl->link_config.interface, caps, in phylink_parse_mode()
811 phylink_caps_to_linkmodes(pl->supported, caps); in phylink_parse_mode()
816 "incorrect link mode %s for in-band status\n", in phylink_parse_mode()
817 phy_modes(pl->link_config.interface)); in phylink_parse_mode()
818 return -EINVAL; in phylink_parse_mode()
821 linkmode_copy(pl->link_config.advertising, pl->supported); in phylink_parse_mode()
823 if (phylink_validate(pl, pl->supported, &pl->link_config)) { in phylink_parse_mode()
825 "failed to validate link configuration for in-band status\n"); in phylink_parse_mode()
826 return -EINVAL; in phylink_parse_mode()
836 /* If autoneg is disabled, pause AN is also disabled */ in phylink_apply_manual_flow()
838 state->advertising)) in phylink_apply_manual_flow()
839 state->pause &= ~MLO_PAUSE_AN; in phylink_apply_manual_flow()
841 /* Manual configuration of pause modes */ in phylink_apply_manual_flow()
842 if (!(pl->link_config.pause & MLO_PAUSE_AN)) in phylink_apply_manual_flow()
843 state->pause = pl->link_config.pause; in phylink_apply_manual_flow()
850 if (state->duplex == DUPLEX_FULL) { in phylink_resolve_an_pause()
851 linkmode_resolve_pause(state->advertising, in phylink_resolve_an_pause()
852 state->lp_advertising, in phylink_resolve_an_pause()
855 state->pause |= MLO_PAUSE_TX; in phylink_resolve_an_pause()
857 state->pause |= MLO_PAUSE_RX; in phylink_resolve_an_pause()
864 if (pcs && pcs->ops->pcs_inband_caps) in phylink_pcs_inband_caps()
865 return pcs->ops->pcs_inband_caps(pcs, interface); in phylink_pcs_inband_caps()
873 if (pcs && pcs->ops->pcs_pre_config) in phylink_pcs_pre_config()
874 pcs->ops->pcs_pre_config(pcs, interface); in phylink_pcs_pre_config()
882 if (pcs && pcs->ops->pcs_post_config) in phylink_pcs_post_config()
883 err = pcs->ops->pcs_post_config(pcs, interface); in phylink_pcs_post_config()
890 if (pcs && pcs->ops->pcs_disable) in phylink_pcs_disable()
891 pcs->ops->pcs_disable(pcs); in phylink_pcs_disable()
898 if (pcs && pcs->ops->pcs_enable) in phylink_pcs_enable()
899 err = pcs->ops->pcs_enable(pcs); in phylink_pcs_enable()
911 return pcs->ops->pcs_config(pcs, neg_mode, state->interface, in phylink_pcs_config()
912 state->advertising, permit_pause_to_mac); in phylink_pcs_config()
919 if (pcs && pcs->ops->pcs_link_up) in phylink_pcs_link_up()
920 pcs->ops->pcs_link_up(pcs, neg_mode, interface, speed, duplex); in phylink_pcs_link_up()
925 if (pcs && pcs->ops->pcs_disable_eee) in phylink_pcs_disable_eee()
926 pcs->ops->pcs_disable_eee(pcs); in phylink_pcs_disable_eee()
931 if (pcs && pcs->ops->pcs_enable_eee) in phylink_pcs_enable_eee()
932 pcs->ops->pcs_enable_eee(pcs); in phylink_pcs_enable_eee()
943 if (!pl->mac_ops->mac_select_pcs) in phylink_inband_caps()
946 pcs = pl->mac_ops->mac_select_pcs(pl->config, interface); in phylink_inband_caps()
955 if (pl->cfg_link_an_mode == MLO_AN_INBAND) in phylink_pcs_poll_stop()
956 timer_delete(&pl->link_poll); in phylink_pcs_poll_stop()
961 if (pl->pcs && pl->pcs->poll && pl->cfg_link_an_mode == MLO_AN_INBAND) in phylink_pcs_poll_start()
962 mod_timer(&pl->link_poll, jiffies + HZ); in phylink_pcs_poll_start()
970 if (pl->config->mac_requires_rxc) in phylink_pcs_pre_init()
971 pcs->rxc_always_on = true; in phylink_pcs_pre_init()
973 if (pcs->ops->pcs_pre_init) in phylink_pcs_pre_init()
974 ret = pcs->ops->pcs_pre_init(pcs); in phylink_pcs_pre_init()
993 "%s: mode=%s/%s/%s adv=%*pb pause=%02x\n", in phylink_mac_config()
994 __func__, phylink_an_mode_str(pl->act_link_an_mode), in phylink_mac_config()
998 st.pause); in phylink_mac_config()
1000 pl->mac_ops->mac_config(pl->config, pl->act_link_an_mode, &st); in phylink_mac_config()
1005 if (pl->pcs && linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, in phylink_pcs_an_restart()
1006 pl->link_config.advertising) && in phylink_pcs_an_restart()
1007 phy_interface_mode_is_8023z(pl->link_config.interface) && in phylink_pcs_an_restart()
1008 phylink_autoneg_inband(pl->act_link_an_mode)) in phylink_pcs_an_restart()
1009 pl->pcs->ops->pcs_an_restart(pl->pcs); in phylink_pcs_an_restart()
1013 * phylink_pcs_neg_mode() - helper to determine PCS inband mode
1022 * - %PHYLINK_PCS_NEG_NONE: interface mode does not support inband
1023 * - %PHYLINK_PCS_NEG_OUTBAND: an out of band mode (e.g. reading the PHY)
1025 * - %PHYLINK_PCS_NEG_INBAND_DISABLED: inband mode selected but autoneg
1027 * - %PHYLINK_PCS_NEG_INBAND_ENABLED: inband mode selected and autoneg enabled
1044 mode = pl->req_link_an_mode; in phylink_pcs_neg_mode()
1046 pl->phy_ib_mode = 0; in phylink_pcs_neg_mode()
1064 /* 1000base-X is designed for use media-side for Fibre in phylink_pcs_neg_mode()
1066 * taken into account. We also do this for 2500base-X in phylink_pcs_neg_mode()
1074 pl->pcs_neg_mode = PHYLINK_PCS_NEG_NONE; in phylink_pcs_neg_mode()
1075 pl->act_link_an_mode = mode; in phylink_pcs_neg_mode()
1082 if (pl->phydev) in phylink_pcs_neg_mode()
1083 phy_ib_caps = phy_inband_caps(pl->phydev, interface); in phylink_pcs_neg_mode()
1093 /* PCS supports reporting in-band capabilities, and in phylink_pcs_neg_mode()
1103 /* PHY supports in-band capabilities, and supports in phylink_pcs_neg_mode()
1107 pl->phy_ib_mode = LINK_INBAND_DISABLE; in phylink_pcs_neg_mode()
1109 pl->phy_ib_mode = LINK_INBAND_BYPASS; in phylink_pcs_neg_mode()
1127 } else if (type == INBAND_CISCO_SGMII || pl->phydev) { in phylink_pcs_neg_mode()
1129 * Base-X with a PHY, we try to use in-band mode where-ever in phylink_pcs_neg_mode()
1131 * do not support in-band. in phylink_pcs_neg_mode()
1158 /* In-band supported or unknown at both ends. Enable in phylink_pcs_neg_mode()
1159 * in-band mode with or without bypass at the PHY. in phylink_pcs_neg_mode()
1162 pl->phy_ib_mode = LINK_INBAND_ENABLE; in phylink_pcs_neg_mode()
1164 pl->phy_ib_mode = LINK_INBAND_BYPASS; in phylink_pcs_neg_mode()
1169 /* Either in-band not supported at at least one end. in phylink_pcs_neg_mode()
1170 * In-band bypass at the other end is possible. in phylink_pcs_neg_mode()
1173 pl->phy_ib_mode = LINK_INBAND_DISABLE; in phylink_pcs_neg_mode()
1175 pl->phy_ib_mode = LINK_INBAND_BYPASS; in phylink_pcs_neg_mode()
1178 if (pl->phydev) in phylink_pcs_neg_mode()
1182 phylink_warn(pl, "%s: incompatible in-band capabilities, trying in-band", in phylink_pcs_neg_mode()
1187 /* For Base-X without a PHY */ in phylink_pcs_neg_mode()
1205 pl->pcs_neg_mode = neg_mode; in phylink_pcs_neg_mode()
1206 pl->act_link_an_mode = mode; in phylink_pcs_neg_mode()
1218 phylink_an_mode_str(pl->req_link_an_mode), in phylink_major_config()
1219 phy_modes(state->interface)); in phylink_major_config()
1221 pl->major_config_failed = false; in phylink_major_config()
1223 if (pl->mac_ops->mac_select_pcs) { in phylink_major_config()
1224 pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface); in phylink_major_config()
1230 pl->major_config_failed = true; in phylink_major_config()
1234 pcs_changed = pl->pcs != pcs; in phylink_major_config()
1237 phylink_pcs_neg_mode(pl, pcs, state->interface, state->advertising); in phylink_major_config()
1240 phylink_an_mode_str(pl->act_link_an_mode), in phylink_major_config()
1241 phylink_pcs_mode_str(pl->pcs_neg_mode), in phylink_major_config()
1242 phy_modes(state->interface)); in phylink_major_config()
1246 if (pl->mac_ops->mac_prepare) { in phylink_major_config()
1247 err = pl->mac_ops->mac_prepare(pl->config, pl->act_link_an_mode, in phylink_major_config()
1248 state->interface); in phylink_major_config()
1252 pl->major_config_failed = true; in phylink_major_config()
1261 phylink_pcs_disable(pl->pcs); in phylink_major_config()
1263 if (pl->pcs) in phylink_major_config()
1264 pl->pcs->phylink = NULL; in phylink_major_config()
1266 pcs->phylink = pl; in phylink_major_config()
1268 pl->pcs = pcs; in phylink_major_config()
1271 if (pl->pcs) in phylink_major_config()
1272 phylink_pcs_pre_config(pl->pcs, state->interface); in phylink_major_config()
1276 if (pl->pcs) { in phylink_major_config()
1277 err = phylink_pcs_post_config(pl->pcs, state->interface); in phylink_major_config()
1282 pl->major_config_failed = true; in phylink_major_config()
1286 if (pl->pcs_state == PCS_STATE_STARTING || pcs_changed) in phylink_major_config()
1287 phylink_pcs_enable(pl->pcs); in phylink_major_config()
1289 err = phylink_pcs_config(pl->pcs, pl->pcs_neg_mode, state, in phylink_major_config()
1290 !!(pl->link_config.pause & MLO_PAUSE_AN)); in phylink_major_config()
1293 pl->major_config_failed = true; in phylink_major_config()
1301 if (pl->mac_ops->mac_finish) { in phylink_major_config()
1302 err = pl->mac_ops->mac_finish(pl->config, pl->act_link_an_mode, in phylink_major_config()
1303 state->interface); in phylink_major_config()
1308 pl->major_config_failed = true; in phylink_major_config()
1312 if (pl->phydev && pl->phy_ib_mode) { in phylink_major_config()
1313 err = phy_config_inband(pl->phydev, pl->phy_ib_mode); in phylink_major_config()
1318 pl->major_config_failed = true; in phylink_major_config()
1322 if (pl->sfp_bus) { in phylink_major_config()
1323 rate_kbd = phylink_interface_signal_rate(state->interface); in phylink_major_config()
1325 sfp_upstream_set_signal_rate(pl->sfp_bus, rate_kbd); in phylink_major_config()
1341 if (test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) in phylink_change_inband_advert()
1344 phylink_dbg(pl, "%s: mode=%s/%s adv=%*pb pause=%02x\n", __func__, in phylink_change_inband_advert()
1345 phylink_an_mode_str(pl->req_link_an_mode), in phylink_change_inband_advert()
1346 phy_modes(pl->link_config.interface), in phylink_change_inband_advert()
1347 __ETHTOOL_LINK_MODE_MASK_NBITS, pl->link_config.advertising, in phylink_change_inband_advert()
1348 pl->link_config.pause); in phylink_change_inband_advert()
1351 phylink_pcs_neg_mode(pl, pl->pcs, pl->link_config.interface, in phylink_change_inband_advert()
1352 pl->link_config.advertising); in phylink_change_inband_advert()
1354 /* Modern PCS-based method; update the advert at the PCS, and in phylink_change_inband_advert()
1358 ret = phylink_pcs_config(pl->pcs, pl->pcs_neg_mode, &pl->link_config, in phylink_change_inband_advert()
1359 !!(pl->link_config.pause & MLO_PAUSE_AN)); in phylink_change_inband_advert()
1375 linkmode_copy(state->advertising, pl->link_config.advertising); in phylink_mac_pcs_get_state()
1376 linkmode_zero(state->lp_advertising); in phylink_mac_pcs_get_state()
1377 state->interface = pl->link_config.interface; in phylink_mac_pcs_get_state()
1378 state->rate_matching = pl->link_config.rate_matching; in phylink_mac_pcs_get_state()
1379 state->an_complete = 0; in phylink_mac_pcs_get_state()
1380 state->link = 1; in phylink_mac_pcs_get_state()
1382 autoneg = pl->pcs_neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED; in phylink_mac_pcs_get_state()
1384 state->speed = SPEED_UNKNOWN; in phylink_mac_pcs_get_state()
1385 state->duplex = DUPLEX_UNKNOWN; in phylink_mac_pcs_get_state()
1386 state->pause = MLO_PAUSE_NONE; in phylink_mac_pcs_get_state()
1388 state->speed = pl->link_config.speed; in phylink_mac_pcs_get_state()
1389 state->duplex = pl->link_config.duplex; in phylink_mac_pcs_get_state()
1390 state->pause = pl->link_config.pause; in phylink_mac_pcs_get_state()
1393 pcs = pl->pcs; in phylink_mac_pcs_get_state()
1395 pcs->ops->pcs_get_state(pcs, pl->pcs_neg_mode, state); in phylink_mac_pcs_get_state()
1397 state->link = 0; in phylink_mac_pcs_get_state()
1406 *state = pl->link_config; in phylink_get_fixed_state()
1407 if (pl->config->get_fixed_state) in phylink_get_fixed_state()
1408 pl->config->get_fixed_state(pl->config, state); in phylink_get_fixed_state()
1409 else if (pl->link_gpio) in phylink_get_fixed_state()
1410 state->link = !!gpiod_get_value_cansleep(pl->link_gpio); in phylink_get_fixed_state()
1412 state->pause = MLO_PAUSE_NONE; in phylink_get_fixed_state()
1420 switch (pl->req_link_an_mode) { in phylink_mac_initial_config()
1422 link_state = pl->phy_state; in phylink_mac_initial_config()
1430 link_state = pl->link_config; in phylink_mac_initial_config()
1432 link_state.pause = MLO_PAUSE_NONE; in phylink_mac_initial_config()
1445 static const char *phylink_pause_to_str(int pause) in phylink_pause_to_str() argument
1447 switch (pause & MLO_PAUSE_TXRX_MASK) { in phylink_pause_to_str()
1461 if (pl->mac_enable_tx_lpi) { in phylink_deactivate_lpi()
1462 pl->mac_enable_tx_lpi = false; in phylink_deactivate_lpi()
1466 pl->mac_ops->mac_disable_tx_lpi(pl->config); in phylink_deactivate_lpi()
1468 phylink_pcs_disable_eee(pl->pcs); in phylink_deactivate_lpi()
1476 if (!test_bit(pl->cur_interface, pl->config->lpi_interfaces)) { in phylink_activate_lpi()
1478 phy_modes(pl->cur_interface)); in phylink_activate_lpi()
1483 pl->mac_tx_lpi_timer, pl->mac_tx_clk_stop); in phylink_activate_lpi()
1485 phylink_pcs_enable_eee(pl->pcs); in phylink_activate_lpi()
1487 err = pl->mac_ops->mac_enable_tx_lpi(pl->config, pl->mac_tx_lpi_timer, in phylink_activate_lpi()
1488 pl->mac_tx_clk_stop); in phylink_activate_lpi()
1490 phylink_pcs_disable_eee(pl->pcs); in phylink_activate_lpi()
1492 pl->mac_ops->mac_enable_tx_lpi, ERR_PTR(err)); in phylink_activate_lpi()
1496 pl->mac_enable_tx_lpi = true; in phylink_activate_lpi()
1502 struct net_device *ndev = pl->netdev; in phylink_link_up()
1508 rx_pause = !!(link_state.pause & MLO_PAUSE_RX); in phylink_link_up()
1514 * pause frames to the MAC to limit its transmission speed. in phylink_link_up()
1531 pl->cur_interface = link_state.interface; in phylink_link_up()
1533 phylink_pcs_link_up(pl->pcs, pl->pcs_neg_mode, pl->cur_interface, speed, in phylink_link_up()
1536 pl->mac_ops->mac_link_up(pl->config, pl->phydev, pl->act_link_an_mode, in phylink_link_up()
1537 pl->cur_interface, speed, duplex, in phylink_link_up()
1538 !!(link_state.pause & MLO_PAUSE_TX), rx_pause); in phylink_link_up()
1540 if (pl->mac_supports_eee && pl->phy_enable_tx_lpi) in phylink_link_up()
1547 "Link is Up - %s/%s - flow control %s\n", in phylink_link_up()
1550 phylink_pause_to_str(link_state.pause)); in phylink_link_up()
1555 struct net_device *ndev = pl->netdev; in phylink_link_down()
1562 pl->mac_ops->mac_link_down(pl->config, pl->act_link_an_mode, in phylink_link_down()
1563 pl->cur_interface); in phylink_link_down()
1569 return pl->netdev ? netif_carrier_ok(pl->netdev) : pl->old_link_state; in phylink_link_is_up()
1580 mutex_lock(&pl->state_mutex); in phylink_resolve()
1583 if (pl->phylink_disable_state) { in phylink_resolve()
1584 pl->link_failed = false; in phylink_resolve()
1586 } else if (pl->link_failed) { in phylink_resolve()
1589 } else if (pl->act_link_an_mode == MLO_AN_FIXED) { in phylink_resolve()
1592 } else if (pl->act_link_an_mode == MLO_AN_PHY) { in phylink_resolve()
1593 link_state = pl->phy_state; in phylink_resolve()
1598 /* The PCS may have a latching link-fail indicator. If the link in phylink_resolve()
1599 * was up, bring the link down and re-trigger the resolve. in phylink_resolve()
1600 * Otherwise, re-read the PCS state to get the current status in phylink_resolve()
1613 if (pl->phydev) in phylink_resolve()
1614 link_state.link &= pl->phy_state.link; in phylink_resolve()
1617 if (pl->phydev && pl->phy_state.link) { in phylink_resolve()
1619 * event if the link isn't already down, and re-resolve. in phylink_resolve()
1621 if (link_state.interface != pl->phy_state.interface) { in phylink_resolve()
1626 link_state.interface = pl->phy_state.interface; in phylink_resolve()
1631 if (pl->phy_state.rate_matching) { in phylink_resolve()
1633 pl->phy_state.rate_matching; in phylink_resolve()
1634 link_state.speed = pl->phy_state.speed; in phylink_resolve()
1635 link_state.duplex = pl->phy_state.duplex; in phylink_resolve()
1641 link_state.pause = pl->phy_state.pause; in phylink_resolve()
1646 if (pl->act_link_an_mode != MLO_AN_FIXED) in phylink_resolve()
1650 if (link_state.interface != pl->link_config.interface) { in phylink_resolve()
1659 pl->link_config.interface = link_state.interface; in phylink_resolve()
1666 if (pl->major_config_failed) in phylink_resolve()
1670 pl->old_link_state = link_state.link; in phylink_resolve()
1677 pl->link_failed = false; in phylink_resolve()
1678 queue_work(system_power_efficient_wq, &pl->resolve); in phylink_resolve()
1680 mutex_unlock(&pl->state_mutex); in phylink_resolve()
1685 if (!pl->phylink_disable_state) in phylink_run_resolve()
1686 queue_work(system_power_efficient_wq, &pl->resolve); in phylink_run_resolve()
1691 unsigned long state = pl->phylink_disable_state; in phylink_run_resolve_and_disable()
1693 set_bit(bit, &pl->phylink_disable_state); in phylink_run_resolve_and_disable()
1695 queue_work(system_power_efficient_wq, &pl->resolve); in phylink_run_resolve_and_disable()
1696 flush_work(&pl->resolve); in phylink_run_resolve_and_disable()
1702 clear_bit(bit, &pl->phylink_disable_state); in phylink_enable_and_run_resolve()
1732 pl->sfp_bus = bus; in phylink_register_sfp()
1741 * phylink_set_fixed_link() - set the fixed link
1756 if (pl->cfg_link_an_mode != MLO_AN_PHY || !state || in phylink_set_fixed_link()
1757 !test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) in phylink_set_fixed_link()
1758 return -EINVAL; in phylink_set_fixed_link()
1760 c = phy_caps_lookup(state->speed, state->duplex, in phylink_set_fixed_link()
1761 pl->supported, true); in phylink_set_fixed_link()
1763 return -EINVAL; in phylink_set_fixed_link()
1765 adv = pl->link_config.advertising; in phylink_set_fixed_link()
1766 linkmode_and(adv, pl->supported, c->linkmodes); in phylink_set_fixed_link()
1769 pl->link_config.speed = state->speed; in phylink_set_fixed_link()
1770 pl->link_config.duplex = state->duplex; in phylink_set_fixed_link()
1771 pl->link_config.link = 1; in phylink_set_fixed_link()
1772 pl->link_config.an_complete = 1; in phylink_set_fixed_link()
1774 pl->cfg_link_an_mode = MLO_AN_FIXED; in phylink_set_fixed_link()
1775 pl->req_link_an_mode = pl->cfg_link_an_mode; in phylink_set_fixed_link()
1782 * phylink_create() - create a phylink instance
1790 * This will parse in-band modes, fixed-link or SFP configuration.
1794 * Returns a pointer to a &struct phylink, or an error-pointer value. Users
1806 if (phy_interface_empty(config->supported_interfaces)) { in phylink_create()
1807 dev_err(config->dev, in phylink_create()
1809 return ERR_PTR(-EINVAL); in phylink_create()
1814 return ERR_PTR(-ENOMEM); in phylink_create()
1816 mutex_init(&pl->state_mutex); in phylink_create()
1817 INIT_WORK(&pl->resolve, phylink_resolve); in phylink_create()
1819 pl->config = config; in phylink_create()
1820 if (config->type == PHYLINK_NETDEV) { in phylink_create()
1821 pl->netdev = to_net_dev(config->dev); in phylink_create()
1822 netif_carrier_off(pl->netdev); in phylink_create()
1823 } else if (config->type == PHYLINK_DEV) { in phylink_create()
1824 pl->dev = config->dev; in phylink_create()
1827 return ERR_PTR(-EINVAL); in phylink_create()
1830 pl->mac_supports_eee_ops = phylink_mac_implements_lpi(mac_ops); in phylink_create()
1831 pl->mac_supports_eee = pl->mac_supports_eee_ops && in phylink_create()
1832 pl->config->lpi_capabilities && in phylink_create()
1833 !phy_interface_empty(pl->config->lpi_interfaces); in phylink_create()
1836 pl->eee_cfg.eee_enabled = pl->config->eee_enabled_default; in phylink_create()
1837 pl->eee_cfg.tx_lpi_enabled = pl->eee_cfg.eee_enabled; in phylink_create()
1838 pl->eee_cfg.tx_lpi_timer = pl->config->lpi_timer_default; in phylink_create()
1840 pl->phy_state.interface = iface; in phylink_create()
1841 pl->link_interface = iface; in phylink_create()
1843 pl->link_port = PORT_BNC; in phylink_create()
1845 pl->link_port = PORT_MII; in phylink_create()
1846 pl->link_config.interface = iface; in phylink_create()
1847 pl->link_config.pause = MLO_PAUSE_AN; in phylink_create()
1848 pl->link_config.speed = SPEED_UNKNOWN; in phylink_create()
1849 pl->link_config.duplex = DUPLEX_UNKNOWN; in phylink_create()
1850 pl->pcs_state = PCS_STATE_DOWN; in phylink_create()
1851 pl->mac_ops = mac_ops; in phylink_create()
1852 __set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); in phylink_create()
1853 timer_setup(&pl->link_poll, phylink_fixed_poll, 0); in phylink_create()
1855 linkmode_fill(pl->supported); in phylink_create()
1856 linkmode_copy(pl->link_config.advertising, pl->supported); in phylink_create()
1857 phylink_validate(pl, pl->supported, &pl->link_config); in phylink_create()
1865 if (pl->cfg_link_an_mode == MLO_AN_FIXED) { in phylink_create()
1873 pl->req_link_an_mode = pl->cfg_link_an_mode; in phylink_create()
1886 * phylink_destroy() - cleanup and destroy the phylink instance
1896 sfp_bus_del_upstream(pl->sfp_bus); in phylink_destroy()
1897 if (pl->link_gpio) in phylink_destroy()
1898 gpiod_put(pl->link_gpio); in phylink_destroy()
1900 cancel_work_sync(&pl->resolve); in phylink_destroy()
1906 * phylink_expects_phy() - Determine if phylink expects a phy to be attached
1909 * When using fixed-link mode, or in-band mode with 1000base-X or 2500base-X,
1916 if (pl->cfg_link_an_mode == MLO_AN_FIXED || in phylink_expects_phy()
1917 (pl->cfg_link_an_mode == MLO_AN_INBAND && in phylink_expects_phy()
1918 phy_interface_mode_is_8023z(pl->link_interface))) in phylink_expects_phy()
1926 struct phylink *pl = phydev->phylink; in phylink_phy_change()
1931 mutex_lock(&pl->state_mutex); in phylink_phy_change()
1932 pl->phy_state.speed = phydev->speed; in phylink_phy_change()
1933 pl->phy_state.duplex = phydev->duplex; in phylink_phy_change()
1934 pl->phy_state.rate_matching = phydev->rate_matching; in phylink_phy_change()
1935 pl->phy_state.pause = MLO_PAUSE_NONE; in phylink_phy_change()
1937 pl->phy_state.pause |= MLO_PAUSE_TX; in phylink_phy_change()
1939 pl->phy_state.pause |= MLO_PAUSE_RX; in phylink_phy_change()
1940 pl->phy_state.interface = phydev->interface; in phylink_phy_change()
1941 pl->phy_state.link = up; in phylink_phy_change()
1943 pl->link_failed = true; in phylink_phy_change()
1946 pl->phy_enable_tx_lpi = phydev->enable_tx_lpi; in phylink_phy_change()
1947 pl->mac_tx_lpi_timer = phydev->eee_cfg.tx_lpi_timer; in phylink_phy_change()
1948 mutex_unlock(&pl->state_mutex); in phylink_phy_change()
1954 phy_modes(phydev->interface), in phylink_phy_change()
1955 phy_speed_to_str(phydev->speed), in phylink_phy_change()
1956 phy_duplex_to_str(phydev->duplex), in phylink_phy_change()
1957 phy_rate_matching_to_str(phydev->rate_matching), in phylink_phy_change()
1958 phylink_pause_to_str(pl->phy_state.pause), in phylink_phy_change()
1959 phydev->enable_tx_lpi ? "" : "no"); in phylink_phy_change()
1972 if (!phy_interface_empty(phy->possible_interfaces)) { in phylink_validate_phy()
1976 phy_interface_and(interfaces, phy->possible_interfaces, in phylink_validate_phy()
1977 pl->config->supported_interfaces); in phylink_validate_phy()
1981 return -EINVAL; in phylink_validate_phy()
1993 return -EINVAL; in phylink_validate_phy()
2000 phy->possible_interfaces, in phylink_validate_phy()
2013 state->rate_matching = phy_get_rate_matching(phy, state->interface); in phylink_validate_phy()
2015 /* Clause 45 PHYs may switch their Serdes lane between, e.g. 10GBASE-R, in phylink_validate_phy()
2016 * 5GBASE-R, 2500BASE-X and SGMII if they are not using rate matching. in phylink_validate_phy()
2022 * linkmodes can be supported. For now, as a work-around, we validate in phylink_validate_phy()
2026 if (phy->is_c45 && state->rate_matching == RATE_MATCH_NONE && in phylink_validate_phy()
2027 state->interface != PHY_INTERFACE_MODE_RXAUI && in phylink_validate_phy()
2028 state->interface != PHY_INTERFACE_MODE_XAUI && in phylink_validate_phy()
2029 state->interface != PHY_INTERFACE_MODE_USXGMII) in phylink_validate_phy()
2030 state->interface = PHY_INTERFACE_MODE_NA; in phylink_validate_phy()
2046 * phy drivers should not set SUPPORTED_[Asym_]Pause") except in phylink_bringup_phy()
2053 linkmode_copy(supported, phy->supported); in phylink_bringup_phy()
2054 linkmode_copy(config.advertising, phy->advertising); in phylink_bringup_phy()
2061 __ETHTOOL_LINK_MODE_MASK_NBITS, phy->supported, in phylink_bringup_phy()
2067 phy->phylink = pl; in phylink_bringup_phy()
2068 phy->phy_link_change = phylink_phy_change; in phylink_bringup_phy()
2073 dev_name(&phy->mdio.dev), phy->drv->name, irq_str); in phylink_bringup_phy()
2076 mutex_lock(&phy->lock); in phylink_bringup_phy()
2077 mutex_lock(&pl->state_mutex); in phylink_bringup_phy()
2078 pl->phydev = phy; in phylink_bringup_phy()
2079 pl->phy_state.interface = interface; in phylink_bringup_phy()
2080 pl->phy_state.pause = MLO_PAUSE_NONE; in phylink_bringup_phy()
2081 pl->phy_state.speed = SPEED_UNKNOWN; in phylink_bringup_phy()
2082 pl->phy_state.duplex = DUPLEX_UNKNOWN; in phylink_bringup_phy()
2083 pl->phy_state.rate_matching = RATE_MATCH_NONE; in phylink_bringup_phy()
2084 linkmode_copy(pl->supported, supported); in phylink_bringup_phy()
2085 linkmode_copy(pl->link_config.advertising, config.advertising); in phylink_bringup_phy()
2088 linkmode_copy(phy->advertising, config.advertising); in phylink_bringup_phy()
2093 if (pl->mac_supports_eee) { in phylink_bringup_phy()
2098 if (pl->eee_cfg.eee_enabled) in phylink_bringup_phy()
2101 phy->eee_cfg.tx_lpi_enabled = pl->eee_cfg.tx_lpi_enabled; in phylink_bringup_phy()
2102 phy->eee_cfg.tx_lpi_timer = pl->eee_cfg.tx_lpi_timer; in phylink_bringup_phy()
2105 linkmode_zero(pl->supported_lpi); in phylink_bringup_phy()
2106 phylink_caps_to_linkmodes(pl->supported_lpi, in phylink_bringup_phy()
2107 pl->config->lpi_capabilities); in phylink_bringup_phy()
2112 linkmode_and(phy->advertising_eee, phy->advertising_eee, in phylink_bringup_phy()
2113 pl->supported_lpi); in phylink_bringup_phy()
2114 } else if (pl->mac_supports_eee_ops) { in phylink_bringup_phy()
2119 mutex_unlock(&pl->state_mutex); in phylink_bringup_phy()
2120 mutex_unlock(&phy->lock); in phylink_bringup_phy()
2125 __ETHTOOL_LINK_MODE_MASK_NBITS, pl->supported, in phylink_bringup_phy()
2126 __ETHTOOL_LINK_MODE_MASK_NBITS, phy->advertising); in phylink_bringup_phy()
2131 if (pl->config->mac_managed_pm) in phylink_bringup_phy()
2132 phy->mac_managed_pm = true; in phylink_bringup_phy()
2135 pl->mac_tx_clk_stop = phy_eee_tx_clock_stop_capable(phy) > 0; in phylink_bringup_phy()
2137 if (pl->mac_supports_eee_ops) { in phylink_bringup_phy()
2142 pl->config->eee_rx_clk_stop_enable); in phylink_bringup_phy()
2143 if (ret == -EOPNOTSUPP) in phylink_bringup_phy()
2155 if (WARN_ON(pl->cfg_link_an_mode == MLO_AN_FIXED || in phylink_attach_phy()
2156 (pl->cfg_link_an_mode == MLO_AN_INBAND && in phylink_attach_phy()
2157 phy_interface_mode_is_8023z(interface) && !pl->sfp_bus))) in phylink_attach_phy()
2158 return -EINVAL; in phylink_attach_phy()
2160 if (pl->phydev) in phylink_attach_phy()
2161 return -EBUSY; in phylink_attach_phy()
2163 if (pl->config->mac_requires_rxc) in phylink_attach_phy()
2166 return phy_attach_direct(pl->netdev, phy, flags, interface); in phylink_attach_phy()
2170 * phylink_connect_phy() - connect a PHY to the phylink instance
2189 if (pl->link_interface == PHY_INTERFACE_MODE_NA) { in phylink_connect_phy()
2190 pl->link_interface = phy->interface; in phylink_connect_phy()
2191 pl->link_config.interface = pl->link_interface; in phylink_connect_phy()
2194 ret = phylink_attach_phy(pl, phy, pl->link_interface); in phylink_connect_phy()
2198 ret = phylink_bringup_phy(pl, phy, pl->link_config.interface); in phylink_connect_phy()
2207 * phylink_of_phy_connect() - connect the PHY specified in the DT mode.
2210 * @flags: PHY-specific flags to communicate to the PHY device driver
2226 * phylink_fwnode_phy_connect() - connect the PHY specified in the fwnode.
2229 * @flags: PHY-specific flags to communicate to the PHY device driver
2245 if (pl->cfg_link_an_mode == MLO_AN_FIXED || in phylink_fwnode_phy_connect()
2246 (pl->cfg_link_an_mode == MLO_AN_INBAND && in phylink_fwnode_phy_connect()
2247 phy_interface_mode_is_8023z(pl->link_interface))) in phylink_fwnode_phy_connect()
2252 if (pl->cfg_link_an_mode == MLO_AN_PHY) in phylink_fwnode_phy_connect()
2253 return -ENODEV; in phylink_fwnode_phy_connect()
2261 return -ENODEV; in phylink_fwnode_phy_connect()
2264 if (pl->link_interface == PHY_INTERFACE_MODE_NA) { in phylink_fwnode_phy_connect()
2265 pl->link_interface = phy_dev->interface; in phylink_fwnode_phy_connect()
2266 pl->link_config.interface = pl->link_interface; in phylink_fwnode_phy_connect()
2269 if (pl->config->mac_requires_rxc) in phylink_fwnode_phy_connect()
2272 ret = phy_attach_direct(pl->netdev, phy_dev, flags, in phylink_fwnode_phy_connect()
2273 pl->link_interface); in phylink_fwnode_phy_connect()
2278 ret = phylink_bringup_phy(pl, phy_dev, pl->link_config.interface); in phylink_fwnode_phy_connect()
2287 * phylink_disconnect_phy() - disconnect any PHY attached to the phylink
2299 phy = pl->phydev; in phylink_disconnect_phy()
2301 mutex_lock(&phy->lock); in phylink_disconnect_phy()
2302 mutex_lock(&pl->state_mutex); in phylink_disconnect_phy()
2303 pl->phydev = NULL; in phylink_disconnect_phy()
2304 pl->phy_enable_tx_lpi = false; in phylink_disconnect_phy()
2305 pl->mac_tx_clk_stop = false; in phylink_disconnect_phy()
2306 mutex_unlock(&pl->state_mutex); in phylink_disconnect_phy()
2307 mutex_unlock(&phy->lock); in phylink_disconnect_phy()
2308 flush_work(&pl->resolve); in phylink_disconnect_phy()
2318 pl->link_failed = true; in phylink_link_changed()
2324 * phylink_mac_change() - notify phylink of a change in MAC state
2338 * phylink_pcs_change() - notify phylink of a change to PCS link state
2346 * the latched link-down state, otherwise pass false.
2350 struct phylink *pl = pcs->phylink; in phylink_pcs_change()
2367 * phylink_start() - start a phylink instance
2381 phylink_an_mode_str(pl->req_link_an_mode), in phylink_start()
2382 phy_modes(pl->link_config.interface)); in phylink_start()
2385 if (pl->netdev) in phylink_start()
2386 netif_carrier_off(pl->netdev); in phylink_start()
2388 pl->pcs_state = PCS_STATE_STARTING; in phylink_start()
2391 * a fixed-link to start with the correct parameters, and also in phylink_start()
2400 pl->pcs_state = PCS_STATE_STARTED; in phylink_start()
2404 if (pl->cfg_link_an_mode == MLO_AN_FIXED && pl->link_gpio) { in phylink_start()
2405 int irq = gpiod_to_irq(pl->link_gpio); in phylink_start()
2412 pl->link_irq = irq; in phylink_start()
2420 if (pl->cfg_link_an_mode == MLO_AN_FIXED) in phylink_start()
2421 poll |= pl->config->poll_fixed_state; in phylink_start()
2424 mod_timer(&pl->link_poll, jiffies + HZ); in phylink_start()
2425 if (pl->phydev) in phylink_start()
2426 phy_start(pl->phydev); in phylink_start()
2427 if (pl->sfp_bus) in phylink_start()
2428 sfp_upstream_start(pl->sfp_bus); in phylink_start()
2433 * phylink_stop() - stop a phylink instance
2448 if (pl->sfp_bus) in phylink_stop()
2449 sfp_upstream_stop(pl->sfp_bus); in phylink_stop()
2450 if (pl->phydev) in phylink_stop()
2451 phy_stop(pl->phydev); in phylink_stop()
2452 timer_delete_sync(&pl->link_poll); in phylink_stop()
2453 if (pl->link_irq) { in phylink_stop()
2454 free_irq(pl->link_irq, pl); in phylink_stop()
2455 pl->link_irq = 0; in phylink_stop()
2460 pl->pcs_state = PCS_STATE_DOWN; in phylink_stop()
2462 phylink_pcs_disable(pl->pcs); in phylink_stop()
2467 * phylink_rx_clk_stop_block() - block PHY ability to stop receive clock in LPI
2478 if (pl->mac_rx_clk_stop_blocked == U8_MAX) { in phylink_rx_clk_stop_block()
2479 phylink_warn(pl, "%s called too many times - ignoring\n", in phylink_rx_clk_stop_block()
2486 * function has been called and clock-stop was previously enabled. in phylink_rx_clk_stop_block()
2488 if (pl->mac_rx_clk_stop_blocked++ == 0 && in phylink_rx_clk_stop_block()
2489 pl->mac_supports_eee_ops && pl->phydev && in phylink_rx_clk_stop_block()
2490 pl->config->eee_rx_clk_stop_enable) in phylink_rx_clk_stop_block()
2491 phy_eee_rx_clock_stop(pl->phydev, false); in phylink_rx_clk_stop_block()
2496 * phylink_rx_clk_stop_unblock() - unblock PHY ability to stop receive clock
2507 if (pl->mac_rx_clk_stop_blocked == 0) { in phylink_rx_clk_stop_unblock()
2508 phylink_warn(pl, "%s called too many times - ignoring\n", in phylink_rx_clk_stop_unblock()
2514 /* Re-enable PHY receive clock stop if the number of unblocks matches in phylink_rx_clk_stop_unblock()
2517 if (--pl->mac_rx_clk_stop_blocked == 0 && in phylink_rx_clk_stop_unblock()
2518 pl->mac_supports_eee_ops && pl->phydev && in phylink_rx_clk_stop_unblock()
2519 pl->config->eee_rx_clk_stop_enable) in phylink_rx_clk_stop_unblock()
2520 phy_eee_rx_clock_stop(pl->phydev, true); in phylink_rx_clk_stop_unblock()
2525 * phylink_suspend() - handle a network device suspend event
2527 * @mac_wol: true if the MAC needs to receive packets for Wake-on-Lan
2531 * - If Wake-on-Lan is not active, we can bring down the link between
2533 * - If Wake-on-Lan is active, and being handled only by the PHY, we
2535 * - If Wake-on-Lan is active, but being handled by the MAC, the MAC
2542 if (mac_wol && (!pl->netdev || pl->netdev->ethtool->wol_enabled)) { in phylink_suspend()
2543 /* Wake-on-Lan enabled, MAC handling */ in phylink_suspend()
2544 mutex_lock(&pl->state_mutex); in phylink_suspend()
2547 __set_bit(PHYLINK_DISABLE_MAC_WOL, &pl->phylink_disable_state); in phylink_suspend()
2549 pl->suspend_link_up = phylink_link_is_up(pl); in phylink_suspend()
2550 if (pl->suspend_link_up) { in phylink_suspend()
2555 if (pl->netdev) in phylink_suspend()
2556 netif_carrier_off(pl->netdev); in phylink_suspend()
2557 pl->old_link_state = false; in phylink_suspend()
2563 mutex_unlock(&pl->state_mutex); in phylink_suspend()
2571 * phylink_prepare_resume() - prepare to resume a network device
2580 struct phy_device *phydev = pl->phydev; in phylink_prepare_resume()
2590 if (pl->config->mac_requires_rxc && phydev && phydev->suspended) in phylink_prepare_resume()
2596 * phylink_resume() - handle a network device resume event
2606 if (test_bit(PHYLINK_DISABLE_MAC_WOL, &pl->phylink_disable_state)) { in phylink_resume()
2607 /* Wake-on-Lan enabled, MAC handling */ in phylink_resume()
2609 if (pl->suspend_link_up) { in phylink_resume()
2613 * to be printed during resume, which is harmless - in phylink_resume()
2617 mutex_lock(&pl->state_mutex); in phylink_resume()
2619 mutex_unlock(&pl->state_mutex); in phylink_resume()
2622 /* Re-apply the link parameters so that all the settings get in phylink_resume()
2627 /* Re-enable and re-resolve the link parameters */ in phylink_resume()
2636 * phylink_ethtool_get_wol() - get the wake on lan parameters for the PHY
2648 wol->supported = 0; in phylink_ethtool_get_wol()
2649 wol->wolopts = 0; in phylink_ethtool_get_wol()
2651 if (pl->phydev) in phylink_ethtool_get_wol()
2652 phy_ethtool_get_wol(pl->phydev, wol); in phylink_ethtool_get_wol()
2657 * phylink_ethtool_set_wol() - set wake on lan parameters
2669 int ret = -EOPNOTSUPP; in phylink_ethtool_set_wol()
2673 if (pl->phydev) in phylink_ethtool_set_wol()
2674 ret = phy_ethtool_set_wol(pl->phydev, wol); in phylink_ethtool_set_wol()
2685 interface = sfp_select_interface(pl->sfp_bus, link_modes); in phylink_sfp_select_interface()
2694 if (!test_bit(interface, pl->config->supported_interfaces)) { in phylink_sfp_select_interface()
2699 pl->config->supported_interfaces); in phylink_sfp_select_interface()
2720 phylink_merge_link_mode(kset->link_modes.advertising, state->advertising); in phylink_get_ksettings()
2721 linkmode_copy(kset->link_modes.lp_advertising, state->lp_advertising); in phylink_get_ksettings()
2722 if (kset->base.rate_matching == RATE_MATCH_NONE) { in phylink_get_ksettings()
2723 kset->base.speed = state->speed; in phylink_get_ksettings()
2724 kset->base.duplex = state->duplex; in phylink_get_ksettings()
2726 kset->base.autoneg = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, in phylink_get_ksettings()
2727 state->advertising) ? in phylink_get_ksettings()
2732 * phylink_ethtool_ksettings_get() - get the current link settings
2747 if (pl->phydev) in phylink_ethtool_ksettings_get()
2748 phy_ethtool_ksettings_get(pl->phydev, kset); in phylink_ethtool_ksettings_get()
2750 kset->base.port = pl->link_port; in phylink_ethtool_ksettings_get()
2752 linkmode_copy(kset->link_modes.supported, pl->supported); in phylink_ethtool_ksettings_get()
2754 switch (pl->act_link_an_mode) { in phylink_ethtool_ksettings_get()
2757 * current link settings - and note that these also in phylink_ethtool_ksettings_get()
2758 * represent the supported speeds/duplex/pause modes. in phylink_ethtool_ksettings_get()
2768 if (pl->phydev) in phylink_ethtool_ksettings_get()
2774 * layer via in-band status. Report these as the current in phylink_ethtool_ksettings_get()
2806 * phylink_ethtool_ksettings_set() - set the link settings
2819 if (pl->phydev) { in phylink_ethtool_ksettings_set()
2824 pl->supported); in phylink_ethtool_ksettings_set()
2827 * to update the pl->link_config settings: in phylink_ethtool_ksettings_set()
2828 * - the configuration returned via ksettings_get() will come in phylink_ethtool_ksettings_set()
2830 * - link_config.interface will be updated by the PHY calling in phylink_ethtool_ksettings_set()
2832 * - initial link configuration for PHY mode comes from the in phylink_ethtool_ksettings_set()
2834 * - other configuration changes (e.g. pause modes) are in phylink_ethtool_ksettings_set()
2836 * - if in in-band mode with a PHY, the link configuration in phylink_ethtool_ksettings_set()
2838 * link_config.{speed,duplex,an_enabled,pause} are not used. in phylink_ethtool_ksettings_set()
2839 * - the only possible use would be link_config.advertising in phylink_ethtool_ksettings_set()
2840 * pause modes when in 1000base-X mode with a PHY, but in in phylink_ethtool_ksettings_set()
2844 return phy_ethtool_ksettings_set(pl->phydev, &phy_kset); in phylink_ethtool_ksettings_set()
2847 config = pl->link_config; in phylink_ethtool_ksettings_set()
2849 linkmode_and(config.advertising, kset->link_modes.advertising, in phylink_ethtool_ksettings_set()
2850 pl->supported); in phylink_ethtool_ksettings_set()
2853 switch (kset->base.autoneg) { in phylink_ethtool_ksettings_set()
2858 c = phy_caps_lookup(kset->base.speed, kset->base.duplex, in phylink_ethtool_ksettings_set()
2859 pl->supported, false); in phylink_ethtool_ksettings_set()
2861 return -EINVAL; in phylink_ethtool_ksettings_set()
2866 if (pl->req_link_an_mode == MLO_AN_FIXED) { in phylink_ethtool_ksettings_set()
2867 if (c->speed != pl->link_config.speed || in phylink_ethtool_ksettings_set()
2868 c->duplex != pl->link_config.duplex) in phylink_ethtool_ksettings_set()
2869 return -EINVAL; in phylink_ethtool_ksettings_set()
2873 config.speed = c->speed; in phylink_ethtool_ksettings_set()
2874 config.duplex = c->duplex; in phylink_ethtool_ksettings_set()
2882 if (pl->req_link_an_mode == MLO_AN_FIXED) { in phylink_ethtool_ksettings_set()
2884 pl->link_config.advertising)) in phylink_ethtool_ksettings_set()
2885 return -EINVAL; in phylink_ethtool_ksettings_set()
2894 return -EINVAL; in phylink_ethtool_ksettings_set()
2898 * fixed-link cases. All that is left are in-band links. in phylink_ethtool_ksettings_set()
2901 kset->base.autoneg == AUTONEG_ENABLE); in phylink_ethtool_ksettings_set()
2907 if (pl->sfp_bus) { in phylink_ethtool_ksettings_set()
2911 return -EINVAL; in phylink_ethtool_ksettings_set()
2914 linkmode_copy(support, pl->supported); in phylink_ethtool_ksettings_set()
2917 phylink_an_mode_str(pl->req_link_an_mode), in phylink_ethtool_ksettings_set()
2920 return -EINVAL; in phylink_ethtool_ksettings_set()
2924 linkmode_copy(support, pl->supported); in phylink_ethtool_ksettings_set()
2926 return -EINVAL; in phylink_ethtool_ksettings_set()
2933 return -EINVAL; in phylink_ethtool_ksettings_set()
2936 * situation, so the PCS is the media-facing entity. in phylink_ethtool_ksettings_set()
2940 return -EINVAL; in phylink_ethtool_ksettings_set()
2942 mutex_lock(&pl->state_mutex); in phylink_ethtool_ksettings_set()
2943 pl->link_config.speed = config.speed; in phylink_ethtool_ksettings_set()
2944 pl->link_config.duplex = config.duplex; in phylink_ethtool_ksettings_set()
2946 if (pl->link_config.interface != config.interface) { in phylink_ethtool_ksettings_set()
2947 /* The interface changed, e.g. 1000base-X <-> 2500base-X */ in phylink_ethtool_ksettings_set()
2949 if (pl->old_link_state) { in phylink_ethtool_ksettings_set()
2951 pl->old_link_state = false; in phylink_ethtool_ksettings_set()
2954 &pl->phylink_disable_state)) in phylink_ethtool_ksettings_set()
2956 pl->link_config.interface = config.interface; in phylink_ethtool_ksettings_set()
2957 linkmode_copy(pl->link_config.advertising, config.advertising); in phylink_ethtool_ksettings_set()
2958 } else if (!linkmode_equal(pl->link_config.advertising, in phylink_ethtool_ksettings_set()
2960 linkmode_copy(pl->link_config.advertising, config.advertising); in phylink_ethtool_ksettings_set()
2963 mutex_unlock(&pl->state_mutex); in phylink_ethtool_ksettings_set()
2970 * phylink_ethtool_nway_reset() - restart negotiation
2986 if (pl->phydev) in phylink_ethtool_nway_reset()
2987 ret = phy_restart_aneg(pl->phydev); in phylink_ethtool_nway_reset()
2995 * phylink_ethtool_get_pauseparam() - get the current pause parameters
2997 * @pause: a pointer to a &struct ethtool_pauseparam
3000 struct ethtool_pauseparam *pause) in phylink_ethtool_get_pauseparam() argument
3004 pause->autoneg = !!(pl->link_config.pause & MLO_PAUSE_AN); in phylink_ethtool_get_pauseparam()
3005 pause->rx_pause = !!(pl->link_config.pause & MLO_PAUSE_RX); in phylink_ethtool_get_pauseparam()
3006 pause->tx_pause = !!(pl->link_config.pause & MLO_PAUSE_TX); in phylink_ethtool_get_pauseparam()
3011 * phylink_ethtool_set_pauseparam() - set the current pause parameters
3013 * @pause: a pointer to a &struct ethtool_pauseparam
3016 struct ethtool_pauseparam *pause) in phylink_ethtool_set_pauseparam() argument
3018 struct phylink_link_state *config = &pl->link_config; in phylink_ethtool_set_pauseparam()
3024 if (pl->req_link_an_mode == MLO_AN_FIXED) in phylink_ethtool_set_pauseparam()
3025 return -EOPNOTSUPP; in phylink_ethtool_set_pauseparam()
3027 if (!phylink_test(pl->supported, Pause) && in phylink_ethtool_set_pauseparam()
3028 !phylink_test(pl->supported, Asym_Pause)) in phylink_ethtool_set_pauseparam()
3029 return -EOPNOTSUPP; in phylink_ethtool_set_pauseparam()
3031 if (!phylink_test(pl->supported, Asym_Pause) && in phylink_ethtool_set_pauseparam()
3032 pause->rx_pause != pause->tx_pause) in phylink_ethtool_set_pauseparam()
3033 return -EINVAL; in phylink_ethtool_set_pauseparam()
3036 if (pause->autoneg) in phylink_ethtool_set_pauseparam()
3038 if (pause->rx_pause) in phylink_ethtool_set_pauseparam()
3040 if (pause->tx_pause) in phylink_ethtool_set_pauseparam()
3043 mutex_lock(&pl->state_mutex); in phylink_ethtool_set_pauseparam()
3049 * rx tx Pause AsymDir in phylink_ethtool_set_pauseparam()
3055 * rx/tx pause resolution. in phylink_ethtool_set_pauseparam()
3057 linkmode_set_pause(config->advertising, pause->tx_pause, in phylink_ethtool_set_pauseparam()
3058 pause->rx_pause); in phylink_ethtool_set_pauseparam()
3060 manual_changed = (config->pause ^ pause_state) & MLO_PAUSE_AN || in phylink_ethtool_set_pauseparam()
3062 (config->pause ^ pause_state) & MLO_PAUSE_TXRX_MASK); in phylink_ethtool_set_pauseparam()
3064 config->pause = pause_state; in phylink_ethtool_set_pauseparam()
3066 /* Update our in-band advertisement, triggering a renegotiation if in phylink_ethtool_set_pauseparam()
3069 if (!pl->phydev) in phylink_ethtool_set_pauseparam()
3072 mutex_unlock(&pl->state_mutex); in phylink_ethtool_set_pauseparam()
3074 /* If we have a PHY, a change of the pause frame advertisement will in phylink_ethtool_set_pauseparam()
3079 if (pl->phydev) in phylink_ethtool_set_pauseparam()
3080 phy_set_asym_pause(pl->phydev, pause->rx_pause, in phylink_ethtool_set_pauseparam()
3081 pause->tx_pause); in phylink_ethtool_set_pauseparam()
3083 /* If the manual pause settings changed, make sure we trigger a in phylink_ethtool_set_pauseparam()
3088 pl->link_failed = true; in phylink_ethtool_set_pauseparam()
3097 * phylink_get_eee_err() - read the energy efficient ethernet error
3112 if (pl->phydev) in phylink_get_eee_err()
3113 ret = phy_get_eee_err(pl->phydev); in phylink_get_eee_err()
3120 * phylink_ethtool_get_eee() - read the energy efficient ethernet parameters
3126 int ret = -EOPNOTSUPP; in phylink_ethtool_get_eee()
3130 if (pl->mac_supports_eee_ops && !pl->mac_supports_eee) in phylink_ethtool_get_eee()
3133 if (pl->phydev) { in phylink_ethtool_get_eee()
3134 ret = phy_ethtool_get_eee(pl->phydev, eee); in phylink_ethtool_get_eee()
3136 if (ret == 0 && pl->mac_supports_eee_ops) in phylink_ethtool_get_eee()
3137 linkmode_and(eee->supported, eee->supported, in phylink_ethtool_get_eee()
3138 pl->supported_lpi); in phylink_ethtool_get_eee()
3146 * phylink_ethtool_set_eee() - set the energy efficient ethernet parameters
3152 bool mac_eee = pl->mac_supports_eee; in phylink_ethtool_set_eee()
3153 int ret = -EOPNOTSUPP; in phylink_ethtool_set_eee()
3159 eee->eee_enabled ? ", enabled" : "", in phylink_ethtool_set_eee()
3160 __ETHTOOL_LINK_MODE_MASK_NBITS, eee->advertised, in phylink_ethtool_set_eee()
3161 eee->tx_lpi_enabled ? " enabled" : "", eee->tx_lpi_timer); in phylink_ethtool_set_eee()
3163 if (pl->mac_supports_eee_ops && !mac_eee) in phylink_ethtool_set_eee()
3166 if (pl->phydev) { in phylink_ethtool_set_eee()
3168 if (pl->mac_supports_eee_ops) in phylink_ethtool_set_eee()
3169 linkmode_and(eee->advertised, eee->advertised, in phylink_ethtool_set_eee()
3170 pl->supported_lpi); in phylink_ethtool_set_eee()
3171 ret = phy_ethtool_set_eee(pl->phydev, eee); in phylink_ethtool_set_eee()
3173 eee_to_eeecfg(&pl->eee_cfg, eee); in phylink_ethtool_set_eee()
3180 /* This emulates MII registers for a fixed-mode phy operating as per the
3189 unsigned long *lpa = state->lp_advertising; in phylink_mii_emul_read()
3192 fs.link = state->link; in phylink_mii_emul_read()
3193 fs.speed = state->speed; in phylink_mii_emul_read()
3194 fs.duplex = state->duplex; in phylink_mii_emul_read()
3195 fs.pause = test_bit(ETHTOOL_LINK_MODE_Pause_BIT, lpa); in phylink_mii_emul_read()
3200 if (!state->an_complete) in phylink_mii_emul_read()
3209 struct phy_device *phydev = pl->phydev; in phylink_phy_read()
3215 return mdiobus_c45_read(pl->phydev->mdio.bus, prtad, devad, in phylink_phy_read()
3219 if (phydev->is_c45) { in phylink_phy_read()
3225 devad = __ffs(phydev->c45_ids.mmds_present); in phylink_phy_read()
3229 if (!(phydev->c45_ids.mmds_present & MDIO_DEVS_AN)) in phylink_phy_read()
3230 return -EINVAL; in phylink_phy_read()
3238 return -EINVAL; in phylink_phy_read()
3241 return mdiobus_c45_read(pl->phydev->mdio.bus, prtad, devad, in phylink_phy_read()
3245 return mdiobus_read(pl->phydev->mdio.bus, phy_id, reg); in phylink_phy_read()
3251 struct phy_device *phydev = pl->phydev; in phylink_phy_write()
3257 return mdiobus_c45_write(pl->phydev->mdio.bus, prtad, devad, in phylink_phy_write()
3261 if (phydev->is_c45) { in phylink_phy_write()
3267 devad = __ffs(phydev->c45_ids.mmds_present); in phylink_phy_write()
3271 if (!(phydev->c45_ids.mmds_present & MDIO_DEVS_AN)) in phylink_phy_write()
3272 return -EINVAL; in phylink_phy_write()
3280 return -EINVAL; in phylink_phy_write()
3282 return mdiobus_c45_write(pl->phydev->mdio.bus, phy_id, devad, in phylink_phy_write()
3286 return mdiobus_write(phydev->mdio.bus, phy_id, reg, val); in phylink_phy_write()
3295 switch (pl->act_link_an_mode) { in phylink_mii_read()
3304 return -EOPNOTSUPP; in phylink_mii_read()
3320 switch (pl->act_link_an_mode) { in phylink_mii_write()
3325 return -EOPNOTSUPP; in phylink_mii_write()
3335 * phylink_mii_ioctl() - generic mii ioctl interface
3359 if (pl->phydev) { in phylink_mii_ioctl()
3363 mii->phy_id = pl->phydev->mdio.addr; in phylink_mii_ioctl()
3367 ret = phylink_phy_read(pl, mii->phy_id, mii->reg_num); in phylink_mii_ioctl()
3369 mii->val_out = ret; in phylink_mii_ioctl()
3375 ret = phylink_phy_write(pl, mii->phy_id, mii->reg_num, in phylink_mii_ioctl()
3376 mii->val_in); in phylink_mii_ioctl()
3380 ret = phy_mii_ioctl(pl->phydev, ifr, cmd); in phylink_mii_ioctl()
3386 mii->phy_id = 0; in phylink_mii_ioctl()
3390 ret = phylink_mii_read(pl, mii->phy_id, mii->reg_num); in phylink_mii_ioctl()
3392 mii->val_out = ret; in phylink_mii_ioctl()
3398 ret = phylink_mii_write(pl, mii->phy_id, mii->reg_num, in phylink_mii_ioctl()
3399 mii->val_in); in phylink_mii_ioctl()
3403 ret = -EOPNOTSUPP; in phylink_mii_ioctl()
3413 * phylink_speed_down() - set the non-SFP PHY to lowest speed supported by both
3430 if (!pl->sfp_bus && pl->phydev) in phylink_speed_down()
3431 ret = phy_speed_down(pl->phydev, sync); in phylink_speed_down()
3438 * phylink_speed_up() - restore the advertised speeds prior to the call to
3453 if (!pl->sfp_bus && pl->phydev) in phylink_speed_up()
3454 ret = phy_speed_up(pl->phydev); in phylink_speed_up()
3464 pl->netdev->sfp_bus = bus; in phylink_sfp_attach()
3471 pl->netdev->sfp_bus = NULL; in phylink_sfp_detach()
3497 phylink_an_mode_str(mode), phy_modes(state->interface), in phylink_sfp_set_config()
3500 if (!linkmode_equal(pl->supported, supported)) { in phylink_sfp_set_config()
3501 linkmode_copy(pl->supported, supported); in phylink_sfp_set_config()
3505 if (!linkmode_equal(pl->link_config.advertising, state->advertising)) { in phylink_sfp_set_config()
3506 linkmode_copy(pl->link_config.advertising, state->advertising); in phylink_sfp_set_config()
3510 if (pl->req_link_an_mode != mode || in phylink_sfp_set_config()
3511 pl->link_config.interface != state->interface) { in phylink_sfp_set_config()
3512 pl->req_link_an_mode = mode; in phylink_sfp_set_config()
3513 pl->link_config.interface = state->interface; in phylink_sfp_set_config()
3519 phy_modes(state->interface)); in phylink_sfp_set_config()
3523 &pl->phylink_disable_state)) in phylink_sfp_set_config()
3533 linkmode_copy(support, phy->supported); in phylink_sfp_config_phy()
3536 linkmode_copy(config.advertising, phy->advertising); in phylink_sfp_config_phy()
3540 config.pause = MLO_PAUSE_AN; in phylink_sfp_config_phy()
3553 return -EINVAL; in phylink_sfp_config_phy()
3569 pl->link_port = pl->sfp_port; in phylink_sfp_config_phy()
3586 pl->config->supported_interfaces, in phylink_sfp_config_optical()
3588 pl->sfp_interfaces); in phylink_sfp_config_optical()
3593 phy_interface_and(interfaces, pl->config->supported_interfaces, in phylink_sfp_config_optical()
3594 pl->sfp_interfaces); in phylink_sfp_config_optical()
3597 return -EINVAL; in phylink_sfp_config_optical()
3601 linkmode_copy(support, pl->sfp_support); in phylink_sfp_config_optical()
3602 linkmode_copy(config.advertising, pl->sfp_support); in phylink_sfp_config_optical()
3605 config.pause = MLO_PAUSE_AN; in phylink_sfp_config_optical()
3610 ret = phylink_validate_mask(pl, NULL, pl->sfp_support, &config, in phylink_sfp_config_optical()
3621 return -EINVAL; in phylink_sfp_config_optical()
3630 return -EINVAL; in phylink_sfp_config_optical()
3644 pl->link_port = pl->sfp_port; in phylink_sfp_config_optical()
3646 phylink_sfp_set_config(pl, pl->sfp_support, &config, false); in phylink_sfp_config_optical()
3658 linkmode_zero(pl->sfp_support); in phylink_sfp_module_insert()
3659 phy_interface_zero(pl->sfp_interfaces); in phylink_sfp_module_insert()
3660 sfp_parse_support(pl->sfp_bus, id, pl->sfp_support, pl->sfp_interfaces); in phylink_sfp_module_insert()
3661 pl->sfp_port = sfp_parse_port(pl->sfp_bus, id, pl->sfp_support); in phylink_sfp_module_insert()
3664 pl->sfp_may_have_phy = sfp_may_have_phy(pl->sfp_bus, id); in phylink_sfp_module_insert()
3665 if (pl->sfp_may_have_phy) in phylink_sfp_module_insert()
3676 if (pl->phydev) { in phylink_sfp_module_start()
3677 phy_start(pl->phydev); in phylink_sfp_module_start()
3684 if (!pl->sfp_may_have_phy) in phylink_sfp_module_start()
3695 if (pl->phydev) in phylink_sfp_module_stop()
3696 phy_stop(pl->phydev); in phylink_sfp_module_stop()
3721 if (!phy->drv) { in phylink_sfp_connect_phy()
3723 phydev_name(phy), (unsigned long)phy->phy_id); in phylink_sfp_connect_phy()
3725 return -EINVAL; in phylink_sfp_connect_phy()
3731 * phy drivers should not set SUPPORTED_[Asym_]Pause") except in phylink_sfp_connect_phy()
3738 phy_interface_and(phy->host_interfaces, phylink_sfp_interfaces, in phylink_sfp_connect_phy()
3739 pl->config->supported_interfaces); in phylink_sfp_connect_phy()
3771 /* 100GBASE-KP4 and 100GBASE-CR10 not supported */
3776 /* 5GBASE-KR not supported */
3787 if (linkmode_test_bit(bit, state->advertising) && in phylink_resolve_c73()
3788 linkmode_test_bit(bit, state->lp_advertising)) in phylink_resolve_c73()
3793 state->speed = phylink_c73_priority_resolution[i].speed; in phylink_resolve_c73()
3794 state->duplex = DUPLEX_FULL; in phylink_resolve_c73()
3797 state->link = false; in phylink_resolve_c73()
3814 mii_lpa_mod_linkmode_x(state->lp_advertising, config_reg, fd_bit); in phylink_decode_c37_word()
3816 if (linkmode_test_bit(fd_bit, state->advertising) && in phylink_decode_c37_word()
3817 linkmode_test_bit(fd_bit, state->lp_advertising)) { in phylink_decode_c37_word()
3818 state->speed = speed; in phylink_decode_c37_word()
3819 state->duplex = DUPLEX_FULL; in phylink_decode_c37_word()
3822 state->link = false; in phylink_decode_c37_word()
3832 state->link = false; in phylink_decode_sgmii_word()
3838 state->speed = SPEED_10; in phylink_decode_sgmii_word()
3841 state->speed = SPEED_100; in phylink_decode_sgmii_word()
3844 state->speed = SPEED_1000; in phylink_decode_sgmii_word()
3847 state->link = false; in phylink_decode_sgmii_word()
3851 state->duplex = DUPLEX_FULL; in phylink_decode_sgmii_word()
3853 state->duplex = DUPLEX_HALF; in phylink_decode_sgmii_word()
3857 * phylink_decode_usxgmii_word() - decode the USXGMII word from a MAC PCS
3859 * @lpa: a 16 bit value which stores the USXGMII auto-negotiation word
3861 * Helper for MAC PCS supporting the USXGMII protocol and the auto-negotiation
3870 state->speed = SPEED_10; in phylink_decode_usxgmii_word()
3873 state->speed = SPEED_100; in phylink_decode_usxgmii_word()
3876 state->speed = SPEED_1000; in phylink_decode_usxgmii_word()
3879 state->speed = SPEED_2500; in phylink_decode_usxgmii_word()
3882 state->speed = SPEED_5000; in phylink_decode_usxgmii_word()
3885 state->speed = SPEED_10000; in phylink_decode_usxgmii_word()
3888 state->link = false; in phylink_decode_usxgmii_word()
3893 state->duplex = DUPLEX_FULL; in phylink_decode_usxgmii_word()
3895 state->duplex = DUPLEX_HALF; in phylink_decode_usxgmii_word()
3900 * phylink_decode_usgmii_word() - decode the USGMII word from a MAC PCS
3902 * @lpa: a 16 bit value which stores the USGMII auto-negotiation word
3904 * Helper for MAC PCS supporting the USGMII protocol and the auto-negotiation
3915 state->speed = SPEED_10; in phylink_decode_usgmii_word()
3918 state->speed = SPEED_100; in phylink_decode_usgmii_word()
3921 state->speed = SPEED_1000; in phylink_decode_usgmii_word()
3924 state->link = false; in phylink_decode_usgmii_word()
3929 state->duplex = DUPLEX_FULL; in phylink_decode_usgmii_word()
3931 state->duplex = DUPLEX_HALF; in phylink_decode_usgmii_word()
3935 * phylink_mii_c22_pcs_decode_state() - Decode MAC PCS state from MII registers
3952 state->link = !!(bmsr & BMSR_LSTATUS); in phylink_mii_c22_pcs_decode_state()
3953 state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE); in phylink_mii_c22_pcs_decode_state()
3956 if (!state->link) in phylink_mii_c22_pcs_decode_state()
3959 switch (state->interface) { in phylink_mii_c22_pcs_decode_state()
3964 state->speed = SPEED_1000; in phylink_mii_c22_pcs_decode_state()
3965 state->duplex = DUPLEX_FULL; in phylink_mii_c22_pcs_decode_state()
3966 state->pause |= MLO_PAUSE_TX | MLO_PAUSE_RX; in phylink_mii_c22_pcs_decode_state()
3974 state->speed = SPEED_2500; in phylink_mii_c22_pcs_decode_state()
3975 state->duplex = DUPLEX_FULL; in phylink_mii_c22_pcs_decode_state()
3976 state->pause |= MLO_PAUSE_TX | MLO_PAUSE_RX; in phylink_mii_c22_pcs_decode_state()
3992 state->link = false; in phylink_mii_c22_pcs_decode_state()
3999 * phylink_mii_c22_pcs_get_state() - read the MAC PCS state
4022 state->link = false; in phylink_mii_c22_pcs_get_state()
4031 * phylink_mii_c22_pcs_encode_advertisement() - configure the clause 37 PCS
4042 * Return: The new value for @adv, or ``-EINVAL`` if it should not be changed.
4065 return -EINVAL; in phylink_mii_c22_pcs_encode_advertisement()
4071 * phylink_mii_c22_pcs_config() - configure clause 22 PCS
4093 ret = mdiobus_modify_changed(pcs->bus, pcs->addr, in phylink_mii_c22_pcs_config()
4115 * phylink_mii_c22_pcs_an_restart() - restart 802.3z autonegotiation
4140 struct mii_bus *bus = pcs->bus; in phylink_mii_c45_pcs_get_state()
4141 int addr = pcs->addr; in phylink_mii_c45_pcs_get_state()
4146 state->link = false; in phylink_mii_c45_pcs_get_state()
4150 state->link = !!(stat & MDIO_STAT1_LSTATUS); in phylink_mii_c45_pcs_get_state()
4151 if (!state->link) in phylink_mii_c45_pcs_get_state()
4154 switch (state->interface) { in phylink_mii_c45_pcs_get_state()
4156 state->speed = SPEED_10000; in phylink_mii_c45_pcs_get_state()
4157 state->duplex = DUPLEX_FULL; in phylink_mii_c45_pcs_get_state()