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.
44 * struct phylink - internal data type for phylink
60 u8 link_port; /* The current non-phy ethtool port */
93 if ((pl)->config->type == PHYLINK_NETDEV) \
94 netdev_printk(level, (pl)->netdev, fmt, ##__VA_ARGS__); \
95 else if ((pl)->config->type == PHYLINK_DEV) \
96 dev_printk(level, (pl)->dev, fmt, ##__VA_ARGS__); \
108 if ((pl)->config->type == PHYLINK_NETDEV) \
109 netdev_dbg((pl)->netdev, fmt, ##__VA_ARGS__); \
110 else if ((pl)->config->type == PHYLINK_DEV) \
111 dev_dbg((pl)->dev, fmt, ##__VA_ARGS__); \
125 * phylink_set_port_modes() - set the port type modes in the ethtool mask
148 phylink_set(tmp, Pause); in phylink_is_empty_linkmode()
183 * phylink_interface_max_speed() - get the maximum speed of a phy interface
253 * phylink_caps_to_linkmodes() - Convert capabilities to ethtool link modes
257 * Set all possible pause, speed and duplex linkmodes in @linkmodes that are
430 * phylink_limit_mac_speed - limit the phylink_config to a maximum speed
443 config->mac_capabilities &= ~phylink_caps_params[i].mask; in phylink_limit_mac_speed()
448 * phylink_cap_from_speed_duplex - Get mac capability from speed/duplex
472 * phylink_get_capabilities() - get capabilities for a given MAC
569 /* The MAC must support asymmetric pause towards the local in phylink_get_capabilities()
570 * device for this. We could allow just symmetric pause, but in phylink_get_capabilities()
572 * doesn't support pause. This is because there's no way to in phylink_get_capabilities()
573 * accept pause frames without transmitting them if we only in phylink_get_capabilities()
574 * support symmetric pause. in phylink_get_capabilities()
585 /* Although a duplex-matching phy might exist, we in phylink_get_capabilities()
587 * will not be aware of the half-duplex nature of the in phylink_get_capabilities()
612 * phylink_validate_mask_caps() - Restrict link modes based on caps
630 caps = phylink_get_capabilities(state->interface, mac_capabilities, in phylink_validate_mask_caps()
631 state->rate_matching); in phylink_validate_mask_caps()
635 linkmode_and(state->advertising, state->advertising, mask); in phylink_validate_mask_caps()
640 * phylink_generic_validate() - generic validate() callback implementation
652 phylink_validate_mask_caps(supported, state, config->mac_capabilities); in phylink_generic_validate()
664 if (pl->using_mac_select_pcs) { in phylink_validate_mac_and_pcs()
665 pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface); in phylink_validate_mac_and_pcs()
669 pcs = pl->pcs; in phylink_validate_mac_and_pcs()
677 if (!pcs->ops) { in phylink_validate_mac_and_pcs()
679 phy_modes(state->interface)); in phylink_validate_mac_and_pcs()
681 return -EINVAL; in phylink_validate_mac_and_pcs()
685 if (pcs->ops->pcs_validate) { in phylink_validate_mac_and_pcs()
686 ret = pcs->ops->pcs_validate(pcs, supported, state); in phylink_validate_mac_and_pcs()
688 return -EINVAL; in phylink_validate_mac_and_pcs()
693 linkmode_and(state->advertising, state->advertising, in phylink_validate_mac_and_pcs()
699 if (pl->mac_ops->validate) in phylink_validate_mac_and_pcs()
700 pl->mac_ops->validate(pl->config, supported, state); in phylink_validate_mac_and_pcs()
702 phylink_generic_validate(pl->config, supported, state); in phylink_validate_mac_and_pcs()
704 return phylink_is_empty_linkmode(supported) ? -EINVAL : 0; in phylink_validate_mac_and_pcs()
731 linkmode_copy(state->advertising, all_adv); in phylink_validate_mask()
733 return phylink_is_empty_linkmode(supported) ? -EINVAL : 0; in phylink_validate_mask()
739 const unsigned long *interfaces = pl->config->supported_interfaces; in phylink_validate()
741 if (state->interface == PHY_INTERFACE_MODE_NA) in phylink_validate()
744 if (!test_bit(state->interface, interfaces)) in phylink_validate()
745 return -EINVAL; in phylink_validate()
754 bool pause, asym_pause, autoneg; in phylink_parse_fixedlink() local
760 fixed_node = fwnode_get_named_child_node(fwnode, "fixed-link"); in phylink_parse_fixedlink()
764 pl->link_config.speed = speed; in phylink_parse_fixedlink()
765 pl->link_config.duplex = DUPLEX_HALF; in phylink_parse_fixedlink()
767 if (fwnode_property_read_bool(fixed_node, "full-duplex")) in phylink_parse_fixedlink()
768 pl->link_config.duplex = DUPLEX_FULL; in phylink_parse_fixedlink()
770 /* We treat the "pause" and "asym-pause" terminology as in phylink_parse_fixedlink()
773 if (fwnode_property_read_bool(fixed_node, "pause")) in phylink_parse_fixedlink()
775 pl->link_config.lp_advertising); in phylink_parse_fixedlink()
776 if (fwnode_property_read_bool(fixed_node, "asym-pause")) in phylink_parse_fixedlink()
778 pl->link_config.lp_advertising); in phylink_parse_fixedlink()
785 pl->link_gpio = desc; in phylink_parse_fixedlink()
786 else if (desc == ERR_PTR(-EPROBE_DEFER)) in phylink_parse_fixedlink()
787 ret = -EPROBE_DEFER; in phylink_parse_fixedlink()
796 ret = fwnode_property_read_u32_array(fwnode, "fixed-link", in phylink_parse_fixedlink()
799 phylink_err(pl, "broken fixed-link?\n"); in phylink_parse_fixedlink()
800 return -EINVAL; in phylink_parse_fixedlink()
803 ret = fwnode_property_read_u32_array(fwnode, "fixed-link", in phylink_parse_fixedlink()
806 pl->link_config.duplex = prop[1] ? in phylink_parse_fixedlink()
808 pl->link_config.speed = prop[2]; in phylink_parse_fixedlink()
811 pl->link_config.lp_advertising); in phylink_parse_fixedlink()
814 pl->link_config.lp_advertising); in phylink_parse_fixedlink()
818 if (pl->link_config.speed > SPEED_1000 && in phylink_parse_fixedlink()
819 pl->link_config.duplex != DUPLEX_FULL) in phylink_parse_fixedlink()
821 pl->link_config.speed); in phylink_parse_fixedlink()
823 bitmap_fill(pl->supported, __ETHTOOL_LINK_MODE_MASK_NBITS); in phylink_parse_fixedlink()
824 linkmode_copy(pl->link_config.advertising, pl->supported); in phylink_parse_fixedlink()
825 phylink_validate(pl, pl->supported, &pl->link_config); in phylink_parse_fixedlink()
827 pause = phylink_test(pl->supported, Pause); in phylink_parse_fixedlink()
828 asym_pause = phylink_test(pl->supported, Asym_Pause); in phylink_parse_fixedlink()
829 autoneg = phylink_test(pl->supported, Autoneg); in phylink_parse_fixedlink()
830 s = phy_lookup_setting(pl->link_config.speed, pl->link_config.duplex, in phylink_parse_fixedlink()
831 pl->supported, true); in phylink_parse_fixedlink()
832 linkmode_zero(pl->supported); in phylink_parse_fixedlink()
833 phylink_set(pl->supported, MII); in phylink_parse_fixedlink()
835 if (pause) in phylink_parse_fixedlink()
836 phylink_set(pl->supported, Pause); in phylink_parse_fixedlink()
839 phylink_set(pl->supported, Asym_Pause); in phylink_parse_fixedlink()
842 phylink_set(pl->supported, Autoneg); in phylink_parse_fixedlink()
845 __set_bit(s->bit, pl->supported); in phylink_parse_fixedlink()
846 __set_bit(s->bit, pl->link_config.lp_advertising); in phylink_parse_fixedlink()
849 pl->link_config.duplex == DUPLEX_FULL ? "full" : "half", in phylink_parse_fixedlink()
850 pl->link_config.speed); in phylink_parse_fixedlink()
853 linkmode_and(pl->link_config.advertising, pl->link_config.advertising, in phylink_parse_fixedlink()
854 pl->supported); in phylink_parse_fixedlink()
856 pl->link_config.link = 1; in phylink_parse_fixedlink()
857 pl->link_config.an_complete = 1; in phylink_parse_fixedlink()
868 dn = fwnode_get_named_child_node(fwnode, "fixed-link"); in phylink_parse_mode()
869 if (dn || fwnode_property_present(fwnode, "fixed-link")) in phylink_parse_mode()
870 pl->cfg_link_an_mode = MLO_AN_FIXED; in phylink_parse_mode()
874 strcmp(managed, "in-band-status") == 0) || in phylink_parse_mode()
875 pl->config->ovr_an_inband) { in phylink_parse_mode()
876 if (pl->cfg_link_an_mode == MLO_AN_FIXED) { in phylink_parse_mode()
878 "can't use both fixed-link and in-band-status\n"); in phylink_parse_mode()
879 return -EINVAL; in phylink_parse_mode()
882 linkmode_zero(pl->supported); in phylink_parse_mode()
883 phylink_set(pl->supported, MII); in phylink_parse_mode()
884 phylink_set(pl->supported, Autoneg); in phylink_parse_mode()
885 phylink_set(pl->supported, Asym_Pause); in phylink_parse_mode()
886 phylink_set(pl->supported, Pause); in phylink_parse_mode()
887 pl->cfg_link_an_mode = MLO_AN_INBAND; in phylink_parse_mode()
889 switch (pl->link_config.interface) { in phylink_parse_mode()
899 phylink_set(pl->supported, 10baseT_Half); in phylink_parse_mode()
900 phylink_set(pl->supported, 10baseT_Full); in phylink_parse_mode()
901 phylink_set(pl->supported, 100baseT_Half); in phylink_parse_mode()
902 phylink_set(pl->supported, 100baseT_Full); in phylink_parse_mode()
903 phylink_set(pl->supported, 1000baseT_Half); in phylink_parse_mode()
904 phylink_set(pl->supported, 1000baseT_Full); in phylink_parse_mode()
908 phylink_set(pl->supported, 1000baseX_Full); in phylink_parse_mode()
912 phylink_set(pl->supported, 2500baseX_Full); in phylink_parse_mode()
916 phylink_set(pl->supported, 5000baseT_Full); in phylink_parse_mode()
920 phylink_set(pl->supported, 25000baseCR_Full); in phylink_parse_mode()
921 phylink_set(pl->supported, 25000baseKR_Full); in phylink_parse_mode()
922 phylink_set(pl->supported, 25000baseSR_Full); in phylink_parse_mode()
927 phylink_set(pl->supported, 10baseT_Half); in phylink_parse_mode()
928 phylink_set(pl->supported, 10baseT_Full); in phylink_parse_mode()
929 phylink_set(pl->supported, 100baseT_Half); in phylink_parse_mode()
930 phylink_set(pl->supported, 100baseT_Full); in phylink_parse_mode()
931 phylink_set(pl->supported, 1000baseT_Half); in phylink_parse_mode()
932 phylink_set(pl->supported, 1000baseT_Full); in phylink_parse_mode()
933 phylink_set(pl->supported, 1000baseX_Full); in phylink_parse_mode()
934 phylink_set(pl->supported, 1000baseKX_Full); in phylink_parse_mode()
935 phylink_set(pl->supported, 2500baseT_Full); in phylink_parse_mode()
936 phylink_set(pl->supported, 2500baseX_Full); in phylink_parse_mode()
937 phylink_set(pl->supported, 5000baseT_Full); in phylink_parse_mode()
938 phylink_set(pl->supported, 10000baseT_Full); in phylink_parse_mode()
939 phylink_set(pl->supported, 10000baseKR_Full); in phylink_parse_mode()
940 phylink_set(pl->supported, 10000baseKX4_Full); in phylink_parse_mode()
941 phylink_set(pl->supported, 10000baseCR_Full); in phylink_parse_mode()
942 phylink_set(pl->supported, 10000baseSR_Full); in phylink_parse_mode()
943 phylink_set(pl->supported, 10000baseLR_Full); in phylink_parse_mode()
944 phylink_set(pl->supported, 10000baseLRM_Full); in phylink_parse_mode()
945 phylink_set(pl->supported, 10000baseER_Full); in phylink_parse_mode()
949 phylink_set(pl->supported, 25000baseCR_Full); in phylink_parse_mode()
950 phylink_set(pl->supported, 25000baseKR_Full); in phylink_parse_mode()
951 phylink_set(pl->supported, 25000baseSR_Full); in phylink_parse_mode()
952 phylink_set(pl->supported, 40000baseKR4_Full); in phylink_parse_mode()
953 phylink_set(pl->supported, 40000baseCR4_Full); in phylink_parse_mode()
954 phylink_set(pl->supported, 40000baseSR4_Full); in phylink_parse_mode()
955 phylink_set(pl->supported, 40000baseLR4_Full); in phylink_parse_mode()
956 phylink_set(pl->supported, 50000baseCR2_Full); in phylink_parse_mode()
957 phylink_set(pl->supported, 50000baseKR2_Full); in phylink_parse_mode()
958 phylink_set(pl->supported, 50000baseSR2_Full); in phylink_parse_mode()
959 phylink_set(pl->supported, 50000baseKR_Full); in phylink_parse_mode()
960 phylink_set(pl->supported, 50000baseSR_Full); in phylink_parse_mode()
961 phylink_set(pl->supported, 50000baseCR_Full); in phylink_parse_mode()
962 phylink_set(pl->supported, 50000baseLR_ER_FR_Full); in phylink_parse_mode()
963 phylink_set(pl->supported, 50000baseDR_Full); in phylink_parse_mode()
964 phylink_set(pl->supported, 100000baseKR4_Full); in phylink_parse_mode()
965 phylink_set(pl->supported, 100000baseSR4_Full); in phylink_parse_mode()
966 phylink_set(pl->supported, 100000baseCR4_Full); in phylink_parse_mode()
967 phylink_set(pl->supported, 100000baseLR4_ER4_Full); in phylink_parse_mode()
968 phylink_set(pl->supported, 100000baseKR2_Full); in phylink_parse_mode()
969 phylink_set(pl->supported, 100000baseSR2_Full); in phylink_parse_mode()
970 phylink_set(pl->supported, 100000baseCR2_Full); in phylink_parse_mode()
971 phylink_set(pl->supported, 100000baseLR2_ER2_FR2_Full); in phylink_parse_mode()
972 phylink_set(pl->supported, 100000baseDR2_Full); in phylink_parse_mode()
977 "incorrect link mode %s for in-band status\n", in phylink_parse_mode()
978 phy_modes(pl->link_config.interface)); in phylink_parse_mode()
979 return -EINVAL; in phylink_parse_mode()
982 linkmode_copy(pl->link_config.advertising, pl->supported); in phylink_parse_mode()
984 if (phylink_validate(pl, pl->supported, &pl->link_config)) { in phylink_parse_mode()
986 "failed to validate link configuration for in-band status\n"); in phylink_parse_mode()
987 return -EINVAL; in phylink_parse_mode()
997 /* If autoneg is disabled, pause AN is also disabled */ in phylink_apply_manual_flow()
999 state->advertising)) in phylink_apply_manual_flow()
1000 state->pause &= ~MLO_PAUSE_AN; in phylink_apply_manual_flow()
1002 /* Manual configuration of pause modes */ in phylink_apply_manual_flow()
1003 if (!(pl->link_config.pause & MLO_PAUSE_AN)) in phylink_apply_manual_flow()
1004 state->pause = pl->link_config.pause; in phylink_apply_manual_flow()
1011 if (state->duplex == DUPLEX_FULL) { in phylink_resolve_an_pause()
1012 linkmode_resolve_pause(state->advertising, in phylink_resolve_an_pause()
1013 state->lp_advertising, in phylink_resolve_an_pause()
1016 state->pause |= MLO_PAUSE_TX; in phylink_resolve_an_pause()
1018 state->pause |= MLO_PAUSE_RX; in phylink_resolve_an_pause()
1025 if (pcs && pcs->ops->pcs_pre_config) in phylink_pcs_pre_config()
1026 pcs->ops->pcs_pre_config(pcs, interface); in phylink_pcs_pre_config()
1034 if (pcs && pcs->ops->pcs_post_config) in phylink_pcs_post_config()
1035 err = pcs->ops->pcs_post_config(pcs, interface); in phylink_pcs_post_config()
1042 if (pcs && pcs->ops->pcs_disable) in phylink_pcs_disable()
1043 pcs->ops->pcs_disable(pcs); in phylink_pcs_disable()
1050 if (pcs && pcs->ops->pcs_enable) in phylink_pcs_enable()
1051 err = pcs->ops->pcs_enable(pcs); in phylink_pcs_enable()
1063 return pcs->ops->pcs_config(pcs, neg_mode, state->interface, in phylink_pcs_config()
1064 state->advertising, permit_pause_to_mac); in phylink_pcs_config()
1071 if (pcs && pcs->ops->pcs_link_up) in phylink_pcs_link_up()
1072 pcs->ops->pcs_link_up(pcs, neg_mode, interface, speed, duplex); in phylink_pcs_link_up()
1077 if (pl->cfg_link_an_mode == MLO_AN_INBAND) in phylink_pcs_poll_stop()
1078 del_timer(&pl->link_poll); in phylink_pcs_poll_stop()
1083 if (pl->pcs && pl->pcs->poll && pl->cfg_link_an_mode == MLO_AN_INBAND) in phylink_pcs_poll_start()
1084 mod_timer(&pl->link_poll, jiffies + HZ); in phylink_pcs_poll_start()
1100 "%s: mode=%s/%s/%s adv=%*pb pause=%02x\n", in phylink_mac_config()
1101 __func__, phylink_an_mode_str(pl->cur_link_an_mode), in phylink_mac_config()
1105 st.pause); in phylink_mac_config()
1107 pl->mac_ops->mac_config(pl->config, pl->cur_link_an_mode, &st); in phylink_mac_config()
1112 if (pl->pcs && linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, in phylink_pcs_an_restart()
1113 pl->link_config.advertising) && in phylink_pcs_an_restart()
1114 phy_interface_mode_is_8023z(pl->link_config.interface) && in phylink_pcs_an_restart()
1115 phylink_autoneg_inband(pl->cur_link_an_mode)) in phylink_pcs_an_restart()
1116 pl->pcs->ops->pcs_an_restart(pl->pcs); in phylink_pcs_an_restart()
1128 phylink_dbg(pl, "major config %s\n", phy_modes(state->interface)); in phylink_major_config()
1130 pl->pcs_neg_mode = phylink_pcs_neg_mode(pl->cur_link_an_mode, in phylink_major_config()
1131 state->interface, in phylink_major_config()
1132 state->advertising); in phylink_major_config()
1134 if (pl->using_mac_select_pcs) { in phylink_major_config()
1135 pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface); in phylink_major_config()
1143 pcs_changed = pcs && pl->pcs != pcs; in phylink_major_config()
1148 if (pl->mac_ops->mac_prepare) { in phylink_major_config()
1149 err = pl->mac_ops->mac_prepare(pl->config, pl->cur_link_an_mode, in phylink_major_config()
1150 state->interface); in phylink_major_config()
1162 phylink_pcs_disable(pl->pcs); in phylink_major_config()
1164 if (pl->pcs) in phylink_major_config()
1165 pl->pcs->phylink = NULL; in phylink_major_config()
1167 pcs->phylink = pl; in phylink_major_config()
1169 pl->pcs = pcs; in phylink_major_config()
1172 if (pl->pcs) in phylink_major_config()
1173 phylink_pcs_pre_config(pl->pcs, state->interface); in phylink_major_config()
1177 if (pl->pcs) in phylink_major_config()
1178 phylink_pcs_post_config(pl->pcs, state->interface); in phylink_major_config()
1180 if (pl->pcs_state == PCS_STATE_STARTING || pcs_changed) in phylink_major_config()
1181 phylink_pcs_enable(pl->pcs); in phylink_major_config()
1183 neg_mode = pl->cur_link_an_mode; in phylink_major_config()
1184 if (pl->pcs && pl->pcs->neg_mode) in phylink_major_config()
1185 neg_mode = pl->pcs_neg_mode; in phylink_major_config()
1187 err = phylink_pcs_config(pl->pcs, neg_mode, state, in phylink_major_config()
1188 !!(pl->link_config.pause & MLO_PAUSE_AN)); in phylink_major_config()
1198 if (pl->mac_ops->mac_finish) { in phylink_major_config()
1199 err = pl->mac_ops->mac_finish(pl->config, pl->cur_link_an_mode, in phylink_major_config()
1200 state->interface); in phylink_major_config()
1206 if (pl->sfp_bus) { in phylink_major_config()
1207 rate_kbd = phylink_interface_signal_rate(state->interface); in phylink_major_config()
1209 sfp_upstream_set_signal_rate(pl->sfp_bus, rate_kbd); in phylink_major_config()
1226 if (test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) in phylink_change_inband_advert()
1229 phylink_dbg(pl, "%s: mode=%s/%s adv=%*pb pause=%02x\n", __func__, in phylink_change_inband_advert()
1230 phylink_an_mode_str(pl->cur_link_an_mode), in phylink_change_inband_advert()
1231 phy_modes(pl->link_config.interface), in phylink_change_inband_advert()
1232 __ETHTOOL_LINK_MODE_MASK_NBITS, pl->link_config.advertising, in phylink_change_inband_advert()
1233 pl->link_config.pause); in phylink_change_inband_advert()
1236 pl->pcs_neg_mode = phylink_pcs_neg_mode(pl->cur_link_an_mode, in phylink_change_inband_advert()
1237 pl->link_config.interface, in phylink_change_inband_advert()
1238 pl->link_config.advertising); in phylink_change_inband_advert()
1240 neg_mode = pl->cur_link_an_mode; in phylink_change_inband_advert()
1241 if (pl->pcs->neg_mode) in phylink_change_inband_advert()
1242 neg_mode = pl->pcs_neg_mode; in phylink_change_inband_advert()
1244 /* Modern PCS-based method; update the advert at the PCS, and in phylink_change_inband_advert()
1248 ret = phylink_pcs_config(pl->pcs, neg_mode, &pl->link_config, in phylink_change_inband_advert()
1249 !!(pl->link_config.pause & MLO_PAUSE_AN)); in phylink_change_inband_advert()
1262 linkmode_copy(state->advertising, pl->link_config.advertising); in phylink_mac_pcs_get_state()
1263 linkmode_zero(state->lp_advertising); in phylink_mac_pcs_get_state()
1264 state->interface = pl->link_config.interface; in phylink_mac_pcs_get_state()
1265 state->rate_matching = pl->link_config.rate_matching; in phylink_mac_pcs_get_state()
1267 state->advertising)) { in phylink_mac_pcs_get_state()
1268 state->speed = SPEED_UNKNOWN; in phylink_mac_pcs_get_state()
1269 state->duplex = DUPLEX_UNKNOWN; in phylink_mac_pcs_get_state()
1270 state->pause = MLO_PAUSE_NONE; in phylink_mac_pcs_get_state()
1272 state->speed = pl->link_config.speed; in phylink_mac_pcs_get_state()
1273 state->duplex = pl->link_config.duplex; in phylink_mac_pcs_get_state()
1274 state->pause = pl->link_config.pause; in phylink_mac_pcs_get_state()
1276 state->an_complete = 0; in phylink_mac_pcs_get_state()
1277 state->link = 1; in phylink_mac_pcs_get_state()
1279 if (pl->pcs) in phylink_mac_pcs_get_state()
1280 pl->pcs->ops->pcs_get_state(pl->pcs, state); in phylink_mac_pcs_get_state()
1282 state->link = 0; in phylink_mac_pcs_get_state()
1291 *state = pl->link_config; in phylink_get_fixed_state()
1292 if (pl->config->get_fixed_state) in phylink_get_fixed_state()
1293 pl->config->get_fixed_state(pl->config, state); in phylink_get_fixed_state()
1294 else if (pl->link_gpio) in phylink_get_fixed_state()
1295 state->link = !!gpiod_get_value_cansleep(pl->link_gpio); in phylink_get_fixed_state()
1297 state->pause = MLO_PAUSE_NONE; in phylink_get_fixed_state()
1305 switch (pl->cur_link_an_mode) { in phylink_mac_initial_config()
1307 link_state = pl->phy_state; in phylink_mac_initial_config()
1315 link_state = pl->link_config; in phylink_mac_initial_config()
1317 link_state.pause = MLO_PAUSE_NONE; in phylink_mac_initial_config()
1330 static const char *phylink_pause_to_str(int pause) in phylink_pause_to_str() argument
1332 switch (pause & MLO_PAUSE_TXRX_MASK) { in phylink_pause_to_str()
1347 struct net_device *ndev = pl->netdev; in phylink_link_up()
1354 rx_pause = !!(link_state.pause & MLO_PAUSE_RX); in phylink_link_up()
1360 * pause frames to the MAC to limit its transmission speed. in phylink_link_up()
1377 pl->cur_interface = link_state.interface; in phylink_link_up()
1379 neg_mode = pl->cur_link_an_mode; in phylink_link_up()
1380 if (pl->pcs && pl->pcs->neg_mode) in phylink_link_up()
1381 neg_mode = pl->pcs_neg_mode; in phylink_link_up()
1383 phylink_pcs_link_up(pl->pcs, neg_mode, pl->cur_interface, speed, in phylink_link_up()
1386 pl->mac_ops->mac_link_up(pl->config, pl->phydev, pl->cur_link_an_mode, in phylink_link_up()
1387 pl->cur_interface, speed, duplex, in phylink_link_up()
1388 !!(link_state.pause & MLO_PAUSE_TX), rx_pause); in phylink_link_up()
1394 "Link is Up - %s/%s - flow control %s\n", in phylink_link_up()
1397 phylink_pause_to_str(link_state.pause)); in phylink_link_up()
1402 struct net_device *ndev = pl->netdev; in phylink_link_down()
1406 pl->mac_ops->mac_link_down(pl->config, pl->cur_link_an_mode, in phylink_link_down()
1407 pl->cur_interface); in phylink_link_down()
1415 struct net_device *ndev = pl->netdev; in phylink_resolve()
1420 mutex_lock(&pl->state_mutex); in phylink_resolve()
1421 if (pl->netdev) in phylink_resolve()
1424 cur_link_state = pl->old_link_state; in phylink_resolve()
1426 if (pl->phylink_disable_state) { in phylink_resolve()
1427 pl->mac_link_dropped = false; in phylink_resolve()
1429 } else if (pl->mac_link_dropped) { in phylink_resolve()
1433 switch (pl->cur_link_an_mode) { in phylink_resolve()
1435 link_state = pl->phy_state; in phylink_resolve()
1448 /* The PCS may have a latching link-fail indicator. in phylink_resolve()
1450 * re-trigger the resolve. Otherwise, re-read the in phylink_resolve()
1464 if (pl->phydev) in phylink_resolve()
1465 link_state.link &= pl->phy_state.link; in phylink_resolve()
1468 if (pl->phydev && pl->phy_state.link) { in phylink_resolve()
1471 * down, and re-resolve. in phylink_resolve()
1474 pl->phy_state.interface) { in phylink_resolve()
1478 link_state.interface = pl->phy_state.interface; in phylink_resolve()
1483 if (pl->phy_state.rate_matching) { in phylink_resolve()
1485 pl->phy_state.rate_matching; in phylink_resolve()
1486 link_state.speed = pl->phy_state.speed; in phylink_resolve()
1488 pl->phy_state.duplex; in phylink_resolve()
1494 link_state.pause = pl->phy_state.pause; in phylink_resolve()
1503 if (link_state.interface != pl->link_config.interface) { in phylink_resolve()
1512 pl->link_config.interface = link_state.interface; in phylink_resolve()
1517 pl->old_link_state = link_state.link; in phylink_resolve()
1524 pl->mac_link_dropped = false; in phylink_resolve()
1525 queue_work(system_power_efficient_wq, &pl->resolve); in phylink_resolve()
1527 mutex_unlock(&pl->state_mutex); in phylink_resolve()
1532 if (!pl->phylink_disable_state) in phylink_run_resolve()
1533 queue_work(system_power_efficient_wq, &pl->resolve); in phylink_run_resolve()
1538 unsigned long state = pl->phylink_disable_state; in phylink_run_resolve_and_disable()
1540 set_bit(bit, &pl->phylink_disable_state); in phylink_run_resolve_and_disable()
1542 queue_work(system_power_efficient_wq, &pl->resolve); in phylink_run_resolve_and_disable()
1543 flush_work(&pl->resolve); in phylink_run_resolve_and_disable()
1549 clear_bit(bit, &pl->phylink_disable_state); in phylink_enable_and_run_resolve()
1579 pl->sfp_bus = bus; in phylink_register_sfp()
1588 * phylink_create() - create a phylink instance
1596 * This will parse in-band modes, fixed-link or SFP configuration.
1600 * Returns a pointer to a &struct phylink, or an error-pointer value. Users
1613 if (phy_interface_empty(config->supported_interfaces)) { in phylink_create()
1614 dev_err(config->dev, in phylink_create()
1616 return ERR_PTR(-EINVAL); in phylink_create()
1619 if (mac_ops->mac_select_pcs && in phylink_create()
1620 mac_ops->mac_select_pcs(config, PHY_INTERFACE_MODE_NA) != in phylink_create()
1621 ERR_PTR(-EOPNOTSUPP)) in phylink_create()
1626 return ERR_PTR(-ENOMEM); in phylink_create()
1628 mutex_init(&pl->state_mutex); in phylink_create()
1629 INIT_WORK(&pl->resolve, phylink_resolve); in phylink_create()
1631 pl->config = config; in phylink_create()
1632 if (config->type == PHYLINK_NETDEV) { in phylink_create()
1633 pl->netdev = to_net_dev(config->dev); in phylink_create()
1634 } else if (config->type == PHYLINK_DEV) { in phylink_create()
1635 pl->dev = config->dev; in phylink_create()
1638 return ERR_PTR(-EINVAL); in phylink_create()
1641 pl->using_mac_select_pcs = using_mac_select_pcs; in phylink_create()
1642 pl->phy_state.interface = iface; in phylink_create()
1643 pl->link_interface = iface; in phylink_create()
1645 pl->link_port = PORT_BNC; in phylink_create()
1647 pl->link_port = PORT_MII; in phylink_create()
1648 pl->link_config.interface = iface; in phylink_create()
1649 pl->link_config.pause = MLO_PAUSE_AN; in phylink_create()
1650 pl->link_config.speed = SPEED_UNKNOWN; in phylink_create()
1651 pl->link_config.duplex = DUPLEX_UNKNOWN; in phylink_create()
1652 pl->pcs_state = PCS_STATE_DOWN; in phylink_create()
1653 pl->mac_ops = mac_ops; in phylink_create()
1654 __set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); in phylink_create()
1655 timer_setup(&pl->link_poll, phylink_fixed_poll, 0); in phylink_create()
1657 bitmap_fill(pl->supported, __ETHTOOL_LINK_MODE_MASK_NBITS); in phylink_create()
1658 linkmode_copy(pl->link_config.advertising, pl->supported); in phylink_create()
1659 phylink_validate(pl, pl->supported, &pl->link_config); in phylink_create()
1667 if (pl->cfg_link_an_mode == MLO_AN_FIXED) { in phylink_create()
1675 pl->cur_link_an_mode = pl->cfg_link_an_mode; in phylink_create()
1688 * phylink_destroy() - cleanup and destroy the phylink instance
1698 sfp_bus_del_upstream(pl->sfp_bus); in phylink_destroy()
1699 if (pl->link_gpio) in phylink_destroy()
1700 gpiod_put(pl->link_gpio); in phylink_destroy()
1702 cancel_work_sync(&pl->resolve); in phylink_destroy()
1708 * phylink_expects_phy() - Determine if phylink expects a phy to be attached
1711 * When using fixed-link mode, or in-band mode with 1000base-X or 2500base-X,
1718 if (pl->cfg_link_an_mode == MLO_AN_FIXED || in phylink_expects_phy()
1719 (pl->cfg_link_an_mode == MLO_AN_INBAND && in phylink_expects_phy()
1720 phy_interface_mode_is_8023z(pl->link_config.interface))) in phylink_expects_phy()
1728 struct phylink *pl = phydev->phylink; in phylink_phy_change()
1733 mutex_lock(&pl->state_mutex); in phylink_phy_change()
1734 pl->phy_state.speed = phydev->speed; in phylink_phy_change()
1735 pl->phy_state.duplex = phydev->duplex; in phylink_phy_change()
1736 pl->phy_state.rate_matching = phydev->rate_matching; in phylink_phy_change()
1737 pl->phy_state.pause = MLO_PAUSE_NONE; in phylink_phy_change()
1739 pl->phy_state.pause |= MLO_PAUSE_TX; in phylink_phy_change()
1741 pl->phy_state.pause |= MLO_PAUSE_RX; in phylink_phy_change()
1742 pl->phy_state.interface = phydev->interface; in phylink_phy_change()
1743 pl->phy_state.link = up; in phylink_phy_change()
1744 mutex_unlock(&pl->state_mutex); in phylink_phy_change()
1749 phy_modes(phydev->interface), in phylink_phy_change()
1750 phy_speed_to_str(phydev->speed), in phylink_phy_change()
1751 phy_duplex_to_str(phydev->duplex), in phylink_phy_change()
1752 phy_rate_matching_to_str(phydev->rate_matching), in phylink_phy_change()
1753 phylink_pause_to_str(pl->phy_state.pause)); in phylink_phy_change()
1767 * phy drivers should not set SUPPORTED_[Asym_]Pause") except in phylink_bringup_phy()
1774 linkmode_copy(supported, phy->supported); in phylink_bringup_phy()
1775 linkmode_copy(config.advertising, phy->advertising); in phylink_bringup_phy()
1782 /* Clause 45 PHYs may switch their Serdes lane between, e.g. 10GBASE-R, in phylink_bringup_phy()
1783 * 5GBASE-R, 2500BASE-X and SGMII if they are not using rate matching. in phylink_bringup_phy()
1789 * linkmodes can be supported. For now, as a work-around, we validate in phylink_bringup_phy()
1793 if (phy->is_c45 && config.rate_matching == RATE_MATCH_NONE && in phylink_bringup_phy()
1805 __ETHTOOL_LINK_MODE_MASK_NBITS, phy->supported, in phylink_bringup_phy()
1811 phy->phylink = pl; in phylink_bringup_phy()
1812 phy->phy_link_change = phylink_phy_change; in phylink_bringup_phy()
1817 dev_name(&phy->mdio.dev), phy->drv->name, irq_str); in phylink_bringup_phy()
1820 mutex_lock(&phy->lock); in phylink_bringup_phy()
1821 mutex_lock(&pl->state_mutex); in phylink_bringup_phy()
1822 pl->phydev = phy; in phylink_bringup_phy()
1823 pl->phy_state.interface = interface; in phylink_bringup_phy()
1824 pl->phy_state.pause = MLO_PAUSE_NONE; in phylink_bringup_phy()
1825 pl->phy_state.speed = SPEED_UNKNOWN; in phylink_bringup_phy()
1826 pl->phy_state.duplex = DUPLEX_UNKNOWN; in phylink_bringup_phy()
1827 pl->phy_state.rate_matching = RATE_MATCH_NONE; in phylink_bringup_phy()
1828 linkmode_copy(pl->supported, supported); in phylink_bringup_phy()
1829 linkmode_copy(pl->link_config.advertising, config.advertising); in phylink_bringup_phy()
1832 linkmode_copy(phy->advertising, config.advertising); in phylink_bringup_phy()
1833 mutex_unlock(&pl->state_mutex); in phylink_bringup_phy()
1834 mutex_unlock(&phy->lock); in phylink_bringup_phy()
1839 __ETHTOOL_LINK_MODE_MASK_NBITS, pl->supported, in phylink_bringup_phy()
1840 __ETHTOOL_LINK_MODE_MASK_NBITS, phy->advertising); in phylink_bringup_phy()
1845 if (pl->config->mac_managed_pm) in phylink_bringup_phy()
1846 phy->mac_managed_pm = true; in phylink_bringup_phy()
1854 if (WARN_ON(pl->cfg_link_an_mode == MLO_AN_FIXED || in phylink_attach_phy()
1855 (pl->cfg_link_an_mode == MLO_AN_INBAND && in phylink_attach_phy()
1856 phy_interface_mode_is_8023z(interface) && !pl->sfp_bus))) in phylink_attach_phy()
1857 return -EINVAL; in phylink_attach_phy()
1859 if (pl->phydev) in phylink_attach_phy()
1860 return -EBUSY; in phylink_attach_phy()
1862 return phy_attach_direct(pl->netdev, phy, 0, interface); in phylink_attach_phy()
1866 * phylink_connect_phy() - connect a PHY to the phylink instance
1885 if (pl->link_interface == PHY_INTERFACE_MODE_NA) { in phylink_connect_phy()
1886 pl->link_interface = phy->interface; in phylink_connect_phy()
1887 pl->link_config.interface = pl->link_interface; in phylink_connect_phy()
1890 ret = phylink_attach_phy(pl, phy, pl->link_interface); in phylink_connect_phy()
1894 ret = phylink_bringup_phy(pl, phy, pl->link_config.interface); in phylink_connect_phy()
1903 * phylink_of_phy_connect() - connect the PHY specified in the DT mode.
1906 * @flags: PHY-specific flags to communicate to the PHY device driver
1922 * phylink_fwnode_phy_connect() - connect the PHY specified in the fwnode.
1925 * @flags: PHY-specific flags to communicate to the PHY device driver
1941 if (pl->cfg_link_an_mode == MLO_AN_FIXED || in phylink_fwnode_phy_connect()
1942 (pl->cfg_link_an_mode == MLO_AN_INBAND && in phylink_fwnode_phy_connect()
1943 phy_interface_mode_is_8023z(pl->link_interface))) in phylink_fwnode_phy_connect()
1948 if (pl->cfg_link_an_mode == MLO_AN_PHY) in phylink_fwnode_phy_connect()
1949 return -ENODEV; in phylink_fwnode_phy_connect()
1957 return -ENODEV; in phylink_fwnode_phy_connect()
1960 if (pl->link_interface == PHY_INTERFACE_MODE_NA) { in phylink_fwnode_phy_connect()
1961 pl->link_interface = phy_dev->interface; in phylink_fwnode_phy_connect()
1962 pl->link_config.interface = pl->link_interface; in phylink_fwnode_phy_connect()
1965 ret = phy_attach_direct(pl->netdev, phy_dev, flags, in phylink_fwnode_phy_connect()
1966 pl->link_interface); in phylink_fwnode_phy_connect()
1971 ret = phylink_bringup_phy(pl, phy_dev, pl->link_config.interface); in phylink_fwnode_phy_connect()
1980 * phylink_disconnect_phy() - disconnect any PHY attached to the phylink
1992 phy = pl->phydev; in phylink_disconnect_phy()
1994 mutex_lock(&phy->lock); in phylink_disconnect_phy()
1995 mutex_lock(&pl->state_mutex); in phylink_disconnect_phy()
1996 pl->phydev = NULL; in phylink_disconnect_phy()
1997 mutex_unlock(&pl->state_mutex); in phylink_disconnect_phy()
1998 mutex_unlock(&phy->lock); in phylink_disconnect_phy()
1999 flush_work(&pl->resolve); in phylink_disconnect_phy()
2009 pl->mac_link_dropped = true; in phylink_link_changed()
2015 * phylink_mac_change() - notify phylink of a change in MAC state
2029 * phylink_pcs_change() - notify phylink of a change to PCS link state
2037 * the latched link-down state, otherwise pass false.
2041 struct phylink *pl = pcs->phylink; in phylink_pcs_change()
2058 * phylink_start() - start a phylink instance
2072 phylink_an_mode_str(pl->cur_link_an_mode), in phylink_start()
2073 phy_modes(pl->link_config.interface)); in phylink_start()
2076 if (pl->netdev) in phylink_start()
2077 netif_carrier_off(pl->netdev); in phylink_start()
2079 pl->pcs_state = PCS_STATE_STARTING; in phylink_start()
2082 * a fixed-link to start with the correct parameters, and also in phylink_start()
2091 pl->pcs_state = PCS_STATE_STARTED; in phylink_start()
2095 if (pl->cfg_link_an_mode == MLO_AN_FIXED && pl->link_gpio) { in phylink_start()
2096 int irq = gpiod_to_irq(pl->link_gpio); in phylink_start()
2103 pl->link_irq = irq; in phylink_start()
2111 if (pl->cfg_link_an_mode == MLO_AN_FIXED) in phylink_start()
2112 poll |= pl->config->poll_fixed_state; in phylink_start()
2115 mod_timer(&pl->link_poll, jiffies + HZ); in phylink_start()
2116 if (pl->phydev) in phylink_start()
2117 phy_start(pl->phydev); in phylink_start()
2118 if (pl->sfp_bus) in phylink_start()
2119 sfp_upstream_start(pl->sfp_bus); in phylink_start()
2124 * phylink_stop() - stop a phylink instance
2139 if (pl->sfp_bus) in phylink_stop()
2140 sfp_upstream_stop(pl->sfp_bus); in phylink_stop()
2141 if (pl->phydev) in phylink_stop()
2142 phy_stop(pl->phydev); in phylink_stop()
2143 del_timer_sync(&pl->link_poll); in phylink_stop()
2144 if (pl->link_irq) { in phylink_stop()
2145 free_irq(pl->link_irq, pl); in phylink_stop()
2146 pl->link_irq = 0; in phylink_stop()
2151 pl->pcs_state = PCS_STATE_DOWN; in phylink_stop()
2153 phylink_pcs_disable(pl->pcs); in phylink_stop()
2158 * phylink_suspend() - handle a network device suspend event
2160 * @mac_wol: true if the MAC needs to receive packets for Wake-on-Lan
2164 * - If Wake-on-Lan is not active, we can bring down the link between
2166 * - If Wake-on-Lan is active, and being handled only by the PHY, we
2168 * - If Wake-on-Lan is active, but being handled by the MAC, the MAC
2175 if (mac_wol && (!pl->netdev || pl->netdev->wol_enabled)) { in phylink_suspend()
2176 /* Wake-on-Lan enabled, MAC handling */ in phylink_suspend()
2177 mutex_lock(&pl->state_mutex); in phylink_suspend()
2180 __set_bit(PHYLINK_DISABLE_MAC_WOL, &pl->phylink_disable_state); in phylink_suspend()
2186 if (pl->netdev) in phylink_suspend()
2187 netif_carrier_off(pl->netdev); in phylink_suspend()
2189 pl->old_link_state = false; in phylink_suspend()
2194 mutex_unlock(&pl->state_mutex); in phylink_suspend()
2202 * phylink_resume() - handle a network device resume event
2212 if (test_bit(PHYLINK_DISABLE_MAC_WOL, &pl->phylink_disable_state)) { in phylink_resume()
2213 /* Wake-on-Lan enabled, MAC handling */ in phylink_resume()
2218 * resume, which is harmless - the true link state will be in phylink_resume()
2221 mutex_lock(&pl->state_mutex); in phylink_resume()
2223 mutex_unlock(&pl->state_mutex); in phylink_resume()
2225 /* Re-apply the link parameters so that all the settings get in phylink_resume()
2230 /* Re-enable and re-resolve the link parameters */ in phylink_resume()
2239 * phylink_ethtool_get_wol() - get the wake on lan parameters for the PHY
2251 wol->supported = 0; in phylink_ethtool_get_wol()
2252 wol->wolopts = 0; in phylink_ethtool_get_wol()
2254 if (pl->phydev) in phylink_ethtool_get_wol()
2255 phy_ethtool_get_wol(pl->phydev, wol); in phylink_ethtool_get_wol()
2260 * phylink_ethtool_set_wol() - set wake on lan parameters
2272 int ret = -EOPNOTSUPP; in phylink_ethtool_set_wol()
2276 if (pl->phydev) in phylink_ethtool_set_wol()
2277 ret = phy_ethtool_set_wol(pl->phydev, wol); in phylink_ethtool_set_wol()
2297 phylink_merge_link_mode(kset->link_modes.advertising, state->advertising); in phylink_get_ksettings()
2298 linkmode_copy(kset->link_modes.lp_advertising, state->lp_advertising); in phylink_get_ksettings()
2299 if (kset->base.rate_matching == RATE_MATCH_NONE) { in phylink_get_ksettings()
2300 kset->base.speed = state->speed; in phylink_get_ksettings()
2301 kset->base.duplex = state->duplex; in phylink_get_ksettings()
2303 kset->base.autoneg = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, in phylink_get_ksettings()
2304 state->advertising) ? in phylink_get_ksettings()
2309 * phylink_ethtool_ksettings_get() - get the current link settings
2324 if (pl->phydev) in phylink_ethtool_ksettings_get()
2325 phy_ethtool_ksettings_get(pl->phydev, kset); in phylink_ethtool_ksettings_get()
2327 kset->base.port = pl->link_port; in phylink_ethtool_ksettings_get()
2329 linkmode_copy(kset->link_modes.supported, pl->supported); in phylink_ethtool_ksettings_get()
2331 switch (pl->cur_link_an_mode) { in phylink_ethtool_ksettings_get()
2334 * current link settings - and note that these also in phylink_ethtool_ksettings_get()
2335 * represent the supported speeds/duplex/pause modes. in phylink_ethtool_ksettings_get()
2345 if (pl->phydev) in phylink_ethtool_ksettings_get()
2351 * layer via in-band status. Report these as the current in phylink_ethtool_ksettings_get()
2363 * phylink_ethtool_ksettings_set() - set the link settings
2376 if (pl->phydev) { in phylink_ethtool_ksettings_set()
2381 pl->supported); in phylink_ethtool_ksettings_set()
2384 * to update the pl->link_config settings: in phylink_ethtool_ksettings_set()
2385 * - the configuration returned via ksettings_get() will come in phylink_ethtool_ksettings_set()
2387 * - link_config.interface will be updated by the PHY calling in phylink_ethtool_ksettings_set()
2389 * - initial link configuration for PHY mode comes from the in phylink_ethtool_ksettings_set()
2391 * - other configuration changes (e.g. pause modes) are in phylink_ethtool_ksettings_set()
2393 * - if in in-band mode with a PHY, the link configuration in phylink_ethtool_ksettings_set()
2395 * link_config.{speed,duplex,an_enabled,pause} are not used. in phylink_ethtool_ksettings_set()
2396 * - the only possible use would be link_config.advertising in phylink_ethtool_ksettings_set()
2397 * pause modes when in 1000base-X mode with a PHY, but in in phylink_ethtool_ksettings_set()
2401 return phy_ethtool_ksettings_set(pl->phydev, &phy_kset); in phylink_ethtool_ksettings_set()
2404 config = pl->link_config; in phylink_ethtool_ksettings_set()
2406 linkmode_and(config.advertising, kset->link_modes.advertising, in phylink_ethtool_ksettings_set()
2407 pl->supported); in phylink_ethtool_ksettings_set()
2410 switch (kset->base.autoneg) { in phylink_ethtool_ksettings_set()
2415 s = phy_lookup_setting(kset->base.speed, kset->base.duplex, in phylink_ethtool_ksettings_set()
2416 pl->supported, false); in phylink_ethtool_ksettings_set()
2418 return -EINVAL; in phylink_ethtool_ksettings_set()
2423 if (pl->cur_link_an_mode == MLO_AN_FIXED) { in phylink_ethtool_ksettings_set()
2424 if (s->speed != pl->link_config.speed || in phylink_ethtool_ksettings_set()
2425 s->duplex != pl->link_config.duplex) in phylink_ethtool_ksettings_set()
2426 return -EINVAL; in phylink_ethtool_ksettings_set()
2430 config.speed = s->speed; in phylink_ethtool_ksettings_set()
2431 config.duplex = s->duplex; in phylink_ethtool_ksettings_set()
2439 if (pl->cur_link_an_mode == MLO_AN_FIXED) { in phylink_ethtool_ksettings_set()
2441 pl->link_config.advertising)) in phylink_ethtool_ksettings_set()
2442 return -EINVAL; in phylink_ethtool_ksettings_set()
2451 return -EINVAL; in phylink_ethtool_ksettings_set()
2455 * fixed-link cases. All that is left are in-band links. in phylink_ethtool_ksettings_set()
2458 kset->base.autoneg == AUTONEG_ENABLE); in phylink_ethtool_ksettings_set()
2464 if (pl->sfp_bus) { in phylink_ethtool_ksettings_set()
2465 config.interface = sfp_select_interface(pl->sfp_bus, in phylink_ethtool_ksettings_set()
2472 return -EINVAL; in phylink_ethtool_ksettings_set()
2476 linkmode_copy(support, pl->supported); in phylink_ethtool_ksettings_set()
2479 phylink_an_mode_str(pl->cur_link_an_mode), in phylink_ethtool_ksettings_set()
2482 return -EINVAL; in phylink_ethtool_ksettings_set()
2486 linkmode_copy(support, pl->supported); in phylink_ethtool_ksettings_set()
2488 return -EINVAL; in phylink_ethtool_ksettings_set()
2495 return -EINVAL; in phylink_ethtool_ksettings_set()
2497 mutex_lock(&pl->state_mutex); in phylink_ethtool_ksettings_set()
2498 pl->link_config.speed = config.speed; in phylink_ethtool_ksettings_set()
2499 pl->link_config.duplex = config.duplex; in phylink_ethtool_ksettings_set()
2501 if (pl->link_config.interface != config.interface) { in phylink_ethtool_ksettings_set()
2502 /* The interface changed, e.g. 1000base-X <-> 2500base-X */ in phylink_ethtool_ksettings_set()
2504 if (pl->old_link_state) { in phylink_ethtool_ksettings_set()
2506 pl->old_link_state = false; in phylink_ethtool_ksettings_set()
2509 &pl->phylink_disable_state)) in phylink_ethtool_ksettings_set()
2511 pl->link_config.interface = config.interface; in phylink_ethtool_ksettings_set()
2512 linkmode_copy(pl->link_config.advertising, config.advertising); in phylink_ethtool_ksettings_set()
2513 } else if (!linkmode_equal(pl->link_config.advertising, in phylink_ethtool_ksettings_set()
2515 linkmode_copy(pl->link_config.advertising, config.advertising); in phylink_ethtool_ksettings_set()
2518 mutex_unlock(&pl->state_mutex); in phylink_ethtool_ksettings_set()
2525 * phylink_ethtool_nway_reset() - restart negotiation
2541 if (pl->phydev) in phylink_ethtool_nway_reset()
2542 ret = phy_restart_aneg(pl->phydev); in phylink_ethtool_nway_reset()
2550 * phylink_ethtool_get_pauseparam() - get the current pause parameters
2552 * @pause: a pointer to a &struct ethtool_pauseparam
2555 struct ethtool_pauseparam *pause) in phylink_ethtool_get_pauseparam() argument
2559 pause->autoneg = !!(pl->link_config.pause & MLO_PAUSE_AN); in phylink_ethtool_get_pauseparam()
2560 pause->rx_pause = !!(pl->link_config.pause & MLO_PAUSE_RX); in phylink_ethtool_get_pauseparam()
2561 pause->tx_pause = !!(pl->link_config.pause & MLO_PAUSE_TX); in phylink_ethtool_get_pauseparam()
2566 * phylink_ethtool_set_pauseparam() - set the current pause parameters
2568 * @pause: a pointer to a &struct ethtool_pauseparam
2571 struct ethtool_pauseparam *pause) in phylink_ethtool_set_pauseparam() argument
2573 struct phylink_link_state *config = &pl->link_config; in phylink_ethtool_set_pauseparam()
2579 if (pl->cur_link_an_mode == MLO_AN_FIXED) in phylink_ethtool_set_pauseparam()
2580 return -EOPNOTSUPP; in phylink_ethtool_set_pauseparam()
2582 if (!phylink_test(pl->supported, Pause) && in phylink_ethtool_set_pauseparam()
2583 !phylink_test(pl->supported, Asym_Pause)) in phylink_ethtool_set_pauseparam()
2584 return -EOPNOTSUPP; in phylink_ethtool_set_pauseparam()
2586 if (!phylink_test(pl->supported, Asym_Pause) && in phylink_ethtool_set_pauseparam()
2587 pause->rx_pause != pause->tx_pause) in phylink_ethtool_set_pauseparam()
2588 return -EINVAL; in phylink_ethtool_set_pauseparam()
2591 if (pause->autoneg) in phylink_ethtool_set_pauseparam()
2593 if (pause->rx_pause) in phylink_ethtool_set_pauseparam()
2595 if (pause->tx_pause) in phylink_ethtool_set_pauseparam()
2598 mutex_lock(&pl->state_mutex); in phylink_ethtool_set_pauseparam()
2604 * rx tx Pause AsymDir in phylink_ethtool_set_pauseparam()
2610 * rx/tx pause resolution. in phylink_ethtool_set_pauseparam()
2612 linkmode_set_pause(config->advertising, pause->tx_pause, in phylink_ethtool_set_pauseparam()
2613 pause->rx_pause); in phylink_ethtool_set_pauseparam()
2615 manual_changed = (config->pause ^ pause_state) & MLO_PAUSE_AN || in phylink_ethtool_set_pauseparam()
2617 (config->pause ^ pause_state) & MLO_PAUSE_TXRX_MASK); in phylink_ethtool_set_pauseparam()
2619 config->pause = pause_state; in phylink_ethtool_set_pauseparam()
2621 /* Update our in-band advertisement, triggering a renegotiation if in phylink_ethtool_set_pauseparam()
2624 if (!pl->phydev) in phylink_ethtool_set_pauseparam()
2627 mutex_unlock(&pl->state_mutex); in phylink_ethtool_set_pauseparam()
2629 /* If we have a PHY, a change of the pause frame advertisement will in phylink_ethtool_set_pauseparam()
2634 if (pl->phydev) in phylink_ethtool_set_pauseparam()
2635 phy_set_asym_pause(pl->phydev, pause->rx_pause, in phylink_ethtool_set_pauseparam()
2636 pause->tx_pause); in phylink_ethtool_set_pauseparam()
2638 /* If the manual pause settings changed, make sure we trigger a in phylink_ethtool_set_pauseparam()
2643 pl->mac_link_dropped = true; in phylink_ethtool_set_pauseparam()
2652 * phylink_get_eee_err() - read the energy efficient ethernet error
2667 if (pl->phydev) in phylink_get_eee_err()
2668 ret = phy_get_eee_err(pl->phydev); in phylink_get_eee_err()
2675 * phylink_init_eee() - init and check the EEE features
2683 int ret = -EOPNOTSUPP; in phylink_init_eee()
2685 if (pl->phydev) in phylink_init_eee()
2686 ret = phy_init_eee(pl->phydev, clk_stop_enable); in phylink_init_eee()
2693 * phylink_ethtool_get_eee() - read the energy efficient ethernet parameters
2699 int ret = -EOPNOTSUPP; in phylink_ethtool_get_eee()
2703 if (pl->phydev) in phylink_ethtool_get_eee()
2704 ret = phy_ethtool_get_eee(pl->phydev, eee); in phylink_ethtool_get_eee()
2711 * phylink_ethtool_set_eee() - set the energy efficient ethernet parameters
2717 int ret = -EOPNOTSUPP; in phylink_ethtool_set_eee()
2721 if (pl->phydev) in phylink_ethtool_set_eee()
2722 ret = phy_ethtool_set_eee(pl->phydev, eee); in phylink_ethtool_set_eee()
2728 /* This emulates MII registers for a fixed-mode phy operating as per the
2737 unsigned long *lpa = state->lp_advertising; in phylink_mii_emul_read()
2740 fs.link = state->link; in phylink_mii_emul_read()
2741 fs.speed = state->speed; in phylink_mii_emul_read()
2742 fs.duplex = state->duplex; in phylink_mii_emul_read()
2743 fs.pause = test_bit(ETHTOOL_LINK_MODE_Pause_BIT, lpa); in phylink_mii_emul_read()
2748 if (!state->an_complete) in phylink_mii_emul_read()
2757 struct phy_device *phydev = pl->phydev; in phylink_phy_read()
2763 return mdiobus_c45_read(pl->phydev->mdio.bus, prtad, devad, in phylink_phy_read()
2767 if (phydev->is_c45) { in phylink_phy_read()
2773 devad = __ffs(phydev->c45_ids.mmds_present); in phylink_phy_read()
2777 if (!(phydev->c45_ids.mmds_present & MDIO_DEVS_AN)) in phylink_phy_read()
2778 return -EINVAL; in phylink_phy_read()
2786 return -EINVAL; in phylink_phy_read()
2789 return mdiobus_c45_read(pl->phydev->mdio.bus, prtad, devad, in phylink_phy_read()
2793 return mdiobus_read(pl->phydev->mdio.bus, phy_id, reg); in phylink_phy_read()
2799 struct phy_device *phydev = pl->phydev; in phylink_phy_write()
2805 return mdiobus_c45_write(pl->phydev->mdio.bus, prtad, devad, in phylink_phy_write()
2809 if (phydev->is_c45) { in phylink_phy_write()
2815 devad = __ffs(phydev->c45_ids.mmds_present); in phylink_phy_write()
2819 if (!(phydev->c45_ids.mmds_present & MDIO_DEVS_AN)) in phylink_phy_write()
2820 return -EINVAL; in phylink_phy_write()
2828 return -EINVAL; in phylink_phy_write()
2830 return mdiobus_c45_write(pl->phydev->mdio.bus, phy_id, devad, in phylink_phy_write()
2834 return mdiobus_write(phydev->mdio.bus, phy_id, reg, val); in phylink_phy_write()
2843 switch (pl->cur_link_an_mode) { in phylink_mii_read()
2852 return -EOPNOTSUPP; in phylink_mii_read()
2868 switch (pl->cur_link_an_mode) { in phylink_mii_write()
2873 return -EOPNOTSUPP; in phylink_mii_write()
2883 * phylink_mii_ioctl() - generic mii ioctl interface
2907 if (pl->phydev) { in phylink_mii_ioctl()
2911 mii->phy_id = pl->phydev->mdio.addr; in phylink_mii_ioctl()
2915 ret = phylink_phy_read(pl, mii->phy_id, mii->reg_num); in phylink_mii_ioctl()
2917 mii->val_out = ret; in phylink_mii_ioctl()
2923 ret = phylink_phy_write(pl, mii->phy_id, mii->reg_num, in phylink_mii_ioctl()
2924 mii->val_in); in phylink_mii_ioctl()
2928 ret = phy_mii_ioctl(pl->phydev, ifr, cmd); in phylink_mii_ioctl()
2934 mii->phy_id = 0; in phylink_mii_ioctl()
2938 ret = phylink_mii_read(pl, mii->phy_id, mii->reg_num); in phylink_mii_ioctl()
2940 mii->val_out = ret; in phylink_mii_ioctl()
2946 ret = phylink_mii_write(pl, mii->phy_id, mii->reg_num, in phylink_mii_ioctl()
2947 mii->val_in); in phylink_mii_ioctl()
2951 ret = -EOPNOTSUPP; in phylink_mii_ioctl()
2961 * phylink_speed_down() - set the non-SFP PHY to lowest speed supported by both
2978 if (!pl->sfp_bus && pl->phydev) in phylink_speed_down()
2979 ret = phy_speed_down(pl->phydev, sync); in phylink_speed_down()
2986 * phylink_speed_up() - restore the advertised speeds prior to the call to
3001 if (!pl->sfp_bus && pl->phydev) in phylink_speed_up()
3002 ret = phy_speed_up(pl->phydev); in phylink_speed_up()
3012 pl->netdev->sfp_bus = bus; in phylink_sfp_attach()
3019 pl->netdev->sfp_bus = NULL; in phylink_sfp_detach()
3058 phylink_an_mode_str(mode), phy_modes(state->interface), in phylink_sfp_set_config()
3061 if (!linkmode_equal(pl->supported, supported)) { in phylink_sfp_set_config()
3062 linkmode_copy(pl->supported, supported); in phylink_sfp_set_config()
3066 if (!linkmode_equal(pl->link_config.advertising, state->advertising)) { in phylink_sfp_set_config()
3067 linkmode_copy(pl->link_config.advertising, state->advertising); in phylink_sfp_set_config()
3071 if (pl->cur_link_an_mode != mode || in phylink_sfp_set_config()
3072 pl->link_config.interface != state->interface) { in phylink_sfp_set_config()
3073 pl->cur_link_an_mode = mode; in phylink_sfp_set_config()
3074 pl->link_config.interface = state->interface; in phylink_sfp_set_config()
3080 phy_modes(state->interface)); in phylink_sfp_set_config()
3084 &pl->phylink_disable_state)) in phylink_sfp_set_config()
3097 linkmode_copy(support, phy->supported); in phylink_sfp_config_phy()
3100 linkmode_copy(config.advertising, phy->advertising); in phylink_sfp_config_phy()
3104 config.pause = MLO_PAUSE_AN; in phylink_sfp_config_phy()
3115 iface = sfp_select_interface(pl->sfp_bus, config.advertising); in phylink_sfp_config_phy()
3120 return -EINVAL; in phylink_sfp_config_phy()
3136 pl->link_port = pl->sfp_port; in phylink_sfp_config_phy()
3153 pl->config->supported_interfaces, in phylink_sfp_config_optical()
3155 pl->sfp_interfaces); in phylink_sfp_config_optical()
3160 phy_interface_and(interfaces, pl->config->supported_interfaces, in phylink_sfp_config_optical()
3161 pl->sfp_interfaces); in phylink_sfp_config_optical()
3164 return -EINVAL; in phylink_sfp_config_optical()
3168 linkmode_copy(support, pl->sfp_support); in phylink_sfp_config_optical()
3169 linkmode_copy(config.advertising, pl->sfp_support); in phylink_sfp_config_optical()
3172 config.pause = MLO_PAUSE_AN; in phylink_sfp_config_optical()
3177 ret = phylink_validate_mask(pl, pl->sfp_support, &config, interfaces); in phylink_sfp_config_optical()
3187 return -EINVAL; in phylink_sfp_config_optical()
3204 pl->link_port = pl->sfp_port; in phylink_sfp_config_optical()
3206 phylink_sfp_set_config(pl, MLO_AN_INBAND, pl->sfp_support, &config); in phylink_sfp_config_optical()
3218 linkmode_zero(pl->sfp_support); in phylink_sfp_module_insert()
3219 phy_interface_zero(pl->sfp_interfaces); in phylink_sfp_module_insert()
3220 sfp_parse_support(pl->sfp_bus, id, pl->sfp_support, pl->sfp_interfaces); in phylink_sfp_module_insert()
3221 pl->sfp_port = sfp_parse_port(pl->sfp_bus, id, pl->sfp_support); in phylink_sfp_module_insert()
3224 pl->sfp_may_have_phy = sfp_may_have_phy(pl->sfp_bus, id); in phylink_sfp_module_insert()
3225 if (pl->sfp_may_have_phy) in phylink_sfp_module_insert()
3236 if (pl->phydev) { in phylink_sfp_module_start()
3237 phy_start(pl->phydev); in phylink_sfp_module_start()
3244 if (!pl->sfp_may_have_phy) in phylink_sfp_module_start()
3255 if (pl->phydev) in phylink_sfp_module_stop()
3256 phy_stop(pl->phydev); in phylink_sfp_module_stop()
3282 return phy->is_c45 && phy_id_compare(phy->c45_ids.device_ids[1], in phylink_phy_no_inband()
3296 * phy drivers should not set SUPPORTED_[Asym_]Pause") except in phylink_sfp_connect_phy()
3308 phy_interface_and(phy->host_interfaces, phylink_sfp_interfaces, in phylink_sfp_connect_phy()
3309 pl->config->supported_interfaces); in phylink_sfp_connect_phy()
3316 interface = pl->link_config.interface; in phylink_sfp_connect_phy()
3353 /* 100GBASE-KP4 and 100GBASE-CR10 not supported */
3358 /* 5GBASE-KR not supported */
3369 if (linkmode_test_bit(bit, state->advertising) && in phylink_resolve_c73()
3370 linkmode_test_bit(bit, state->lp_advertising)) in phylink_resolve_c73()
3375 state->speed = phylink_c73_priority_resolution[i].speed; in phylink_resolve_c73()
3376 state->duplex = DUPLEX_FULL; in phylink_resolve_c73()
3379 state->link = false; in phylink_resolve_c73()
3396 mii_lpa_mod_linkmode_x(state->lp_advertising, config_reg, fd_bit); in phylink_decode_c37_word()
3398 if (linkmode_test_bit(fd_bit, state->advertising) && in phylink_decode_c37_word()
3399 linkmode_test_bit(fd_bit, state->lp_advertising)) { in phylink_decode_c37_word()
3400 state->speed = speed; in phylink_decode_c37_word()
3401 state->duplex = DUPLEX_FULL; in phylink_decode_c37_word()
3404 state->link = false; in phylink_decode_c37_word()
3414 state->link = false; in phylink_decode_sgmii_word()
3420 state->speed = SPEED_10; in phylink_decode_sgmii_word()
3423 state->speed = SPEED_100; in phylink_decode_sgmii_word()
3426 state->speed = SPEED_1000; in phylink_decode_sgmii_word()
3429 state->link = false; in phylink_decode_sgmii_word()
3433 state->duplex = DUPLEX_FULL; in phylink_decode_sgmii_word()
3435 state->duplex = DUPLEX_HALF; in phylink_decode_sgmii_word()
3439 * phylink_decode_usxgmii_word() - decode the USXGMII word from a MAC PCS
3441 * @lpa: a 16 bit value which stores the USXGMII auto-negotiation word
3443 * Helper for MAC PCS supporting the USXGMII protocol and the auto-negotiation
3452 state->speed = SPEED_10; in phylink_decode_usxgmii_word()
3455 state->speed = SPEED_100; in phylink_decode_usxgmii_word()
3458 state->speed = SPEED_1000; in phylink_decode_usxgmii_word()
3461 state->speed = SPEED_2500; in phylink_decode_usxgmii_word()
3464 state->speed = SPEED_5000; in phylink_decode_usxgmii_word()
3467 state->speed = SPEED_10000; in phylink_decode_usxgmii_word()
3470 state->link = false; in phylink_decode_usxgmii_word()
3475 state->duplex = DUPLEX_FULL; in phylink_decode_usxgmii_word()
3477 state->duplex = DUPLEX_HALF; in phylink_decode_usxgmii_word()
3482 * phylink_decode_usgmii_word() - decode the USGMII word from a MAC PCS
3484 * @lpa: a 16 bit value which stores the USGMII auto-negotiation word
3486 * Helper for MAC PCS supporting the USGMII protocol and the auto-negotiation
3497 state->speed = SPEED_10; in phylink_decode_usgmii_word()
3500 state->speed = SPEED_100; in phylink_decode_usgmii_word()
3503 state->speed = SPEED_1000; in phylink_decode_usgmii_word()
3506 state->link = false; in phylink_decode_usgmii_word()
3511 state->duplex = DUPLEX_FULL; in phylink_decode_usgmii_word()
3513 state->duplex = DUPLEX_HALF; in phylink_decode_usgmii_word()
3517 * phylink_mii_c22_pcs_decode_state() - Decode MAC PCS state from MII registers
3533 state->link = !!(bmsr & BMSR_LSTATUS); in phylink_mii_c22_pcs_decode_state()
3534 state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE); in phylink_mii_c22_pcs_decode_state()
3538 if (!state->link || !linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, in phylink_mii_c22_pcs_decode_state()
3539 state->advertising)) in phylink_mii_c22_pcs_decode_state()
3542 switch (state->interface) { in phylink_mii_c22_pcs_decode_state()
3560 state->link = false; in phylink_mii_c22_pcs_decode_state()
3567 * phylink_mii_c22_pcs_get_state() - read the MAC PCS state
3588 state->link = false; in phylink_mii_c22_pcs_get_state()
3597 * phylink_mii_c22_pcs_encode_advertisement() - configure the clause 37 PCS
3608 * Return: The new value for @adv, or ``-EINVAL`` if it should not be changed.
3631 return -EINVAL; in phylink_mii_c22_pcs_encode_advertisement()
3637 * phylink_mii_c22_pcs_config() - configure clause 22 PCS
3659 ret = mdiobus_modify_changed(pcs->bus, pcs->addr, in phylink_mii_c22_pcs_config()
3681 * phylink_mii_c22_pcs_an_restart() - restart 802.3z autonegotiation
3706 struct mii_bus *bus = pcs->bus; in phylink_mii_c45_pcs_get_state()
3707 int addr = pcs->addr; in phylink_mii_c45_pcs_get_state()
3712 state->link = false; in phylink_mii_c45_pcs_get_state()
3716 state->link = !!(stat & MDIO_STAT1_LSTATUS); in phylink_mii_c45_pcs_get_state()
3717 if (!state->link) in phylink_mii_c45_pcs_get_state()
3720 switch (state->interface) { in phylink_mii_c45_pcs_get_state()
3722 state->speed = SPEED_10000; in phylink_mii_c45_pcs_get_state()
3723 state->duplex = DUPLEX_FULL; in phylink_mii_c45_pcs_get_state()