Lines Matching +full:need +full:- +full:phy +full:- +full:for +full:- +full:wake
1 // SPDX-License-Identifier: GPL-2.0
3 * phylink models the MAC to optional PHY connection, supporting
4 * technologies such as SFP cages where the PHY is hot-pluggable.
15 #include <linux/phy.h>
40 * struct phylink - internal data type for phylink
56 u8 link_port; /* The current non-phy ethtool port */
87 if ((pl)->config->type == PHYLINK_NETDEV) \
88 netdev_printk(level, (pl)->netdev, fmt, ##__VA_ARGS__); \
89 else if ((pl)->config->type == PHYLINK_DEV) \
90 dev_printk(level, (pl)->dev, fmt, ##__VA_ARGS__); \
102 if ((pl)->config->type == PHYLINK_NETDEV) \
103 netdev_dbg((pl)->netdev, fmt, ##__VA_ARGS__); \
104 else if ((pl)->config->type == PHYLINK_DEV) \
105 dev_dbg((pl)->dev, fmt, ##__VA_ARGS__); \
119 * phylink_set_port_modes() - set the port type modes in the ethtool mask
151 [MLO_AN_PHY] = "phy", in phylink_an_mode_str()
160 * phylink_interface_max_speed() - get the maximum speed of a phy interface
161 * @interface: phy interface mode defined by &typedef phy_interface_t
163 * Determine the maximum speed of a phy interface. This is intended to help
164 * determine the correct speed to pass to the MAC when the phy is performing
229 * phylink_caps_to_linkmodes() - Convert capabilities to ethtool link modes
402 * phylink_cap_from_speed_duplex - Get mac capability from speed/duplex
403 * @speed: the speed to search for
404 * @duplex: the duplex to search for
406 * Find the mac capability for a given speed and duplex.
416 for (i = 0; i < ARRAY_SIZE(phylink_caps_params); i++) { in phylink_cap_from_speed_duplex()
426 * phylink_get_capabilities() - get capabilities for a given MAC
427 * @interface: phy interface mode defined by &typedef phy_interface_t
523 * device for this. We could allow just symmetric pause, but in phylink_get_capabilities()
538 /* Although a duplex-matching phy might exist, we in phylink_get_capabilities()
540 * will not be aware of the half-duplex nature of the in phylink_get_capabilities()
565 * phylink_generic_validate() - generic validate() callback implementation
567 * @supported: ethtool bitmask for supported link modes.
583 caps = phylink_get_capabilities(state->interface, in phylink_generic_validate()
584 config->mac_capabilities, in phylink_generic_validate()
585 state->rate_matching); in phylink_generic_validate()
589 linkmode_and(state->advertising, state->advertising, mask); in phylink_generic_validate()
600 /* Get the PCS for this interface mode */ in phylink_validate_mac_and_pcs()
601 if (pl->using_mac_select_pcs) { in phylink_validate_mac_and_pcs()
602 pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface); in phylink_validate_mac_and_pcs()
606 pcs = pl->pcs; in phylink_validate_mac_and_pcs()
614 if (!pcs->ops) { in phylink_validate_mac_and_pcs()
616 phy_modes(state->interface)); in phylink_validate_mac_and_pcs()
618 return -EINVAL; in phylink_validate_mac_and_pcs()
622 if (pcs->ops->pcs_validate) { in phylink_validate_mac_and_pcs()
623 ret = pcs->ops->pcs_validate(pcs, supported, state); in phylink_validate_mac_and_pcs()
625 return -EINVAL; in phylink_validate_mac_and_pcs()
630 linkmode_and(state->advertising, state->advertising, in phylink_validate_mac_and_pcs()
636 pl->mac_ops->validate(pl->config, supported, state); in phylink_validate_mac_and_pcs()
638 return phylink_is_empty_linkmode(supported) ? -EINVAL : 0; in phylink_validate_mac_and_pcs()
651 for (intf = 0; intf < PHY_INTERFACE_MODE_MAX; intf++) { in phylink_validate_mask()
665 linkmode_copy(state->advertising, all_adv); in phylink_validate_mask()
667 return phylink_is_empty_linkmode(supported) ? -EINVAL : 0; in phylink_validate_mask()
673 const unsigned long *interfaces = pl->config->supported_interfaces; in phylink_validate()
676 if (state->interface == PHY_INTERFACE_MODE_NA) in phylink_validate()
680 if (!test_bit(state->interface, interfaces)) in phylink_validate()
681 return -EINVAL; in phylink_validate()
696 fixed_node = fwnode_get_named_child_node(fwnode, "fixed-link"); in phylink_parse_fixedlink()
700 pl->link_config.speed = speed; in phylink_parse_fixedlink()
701 pl->link_config.duplex = DUPLEX_HALF; in phylink_parse_fixedlink()
703 if (fwnode_property_read_bool(fixed_node, "full-duplex")) in phylink_parse_fixedlink()
704 pl->link_config.duplex = DUPLEX_FULL; in phylink_parse_fixedlink()
706 /* We treat the "pause" and "asym-pause" terminology as in phylink_parse_fixedlink()
711 pl->link_config.lp_advertising); in phylink_parse_fixedlink()
712 if (fwnode_property_read_bool(fixed_node, "asym-pause")) in phylink_parse_fixedlink()
714 pl->link_config.lp_advertising); in phylink_parse_fixedlink()
721 pl->link_gpio = desc; in phylink_parse_fixedlink()
722 else if (desc == ERR_PTR(-EPROBE_DEFER)) in phylink_parse_fixedlink()
723 ret = -EPROBE_DEFER; in phylink_parse_fixedlink()
732 ret = fwnode_property_read_u32_array(fwnode, "fixed-link", in phylink_parse_fixedlink()
735 phylink_err(pl, "broken fixed-link?\n"); in phylink_parse_fixedlink()
736 return -EINVAL; in phylink_parse_fixedlink()
739 ret = fwnode_property_read_u32_array(fwnode, "fixed-link", in phylink_parse_fixedlink()
742 pl->link_config.duplex = prop[1] ? in phylink_parse_fixedlink()
744 pl->link_config.speed = prop[2]; in phylink_parse_fixedlink()
747 pl->link_config.lp_advertising); in phylink_parse_fixedlink()
750 pl->link_config.lp_advertising); in phylink_parse_fixedlink()
754 if (pl->link_config.speed > SPEED_1000 && in phylink_parse_fixedlink()
755 pl->link_config.duplex != DUPLEX_FULL) in phylink_parse_fixedlink()
756 phylink_warn(pl, "fixed link specifies half duplex for %dMbps link?\n", in phylink_parse_fixedlink()
757 pl->link_config.speed); in phylink_parse_fixedlink()
759 bitmap_fill(pl->supported, __ETHTOOL_LINK_MODE_MASK_NBITS); in phylink_parse_fixedlink()
760 linkmode_copy(pl->link_config.advertising, pl->supported); in phylink_parse_fixedlink()
761 phylink_validate(pl, pl->supported, &pl->link_config); in phylink_parse_fixedlink()
763 s = phy_lookup_setting(pl->link_config.speed, pl->link_config.duplex, in phylink_parse_fixedlink()
764 pl->supported, true); in phylink_parse_fixedlink()
765 linkmode_zero(pl->supported); in phylink_parse_fixedlink()
766 phylink_set(pl->supported, MII); in phylink_parse_fixedlink()
767 phylink_set(pl->supported, Pause); in phylink_parse_fixedlink()
768 phylink_set(pl->supported, Asym_Pause); in phylink_parse_fixedlink()
769 phylink_set(pl->supported, Autoneg); in phylink_parse_fixedlink()
771 __set_bit(s->bit, pl->supported); in phylink_parse_fixedlink()
772 __set_bit(s->bit, pl->link_config.lp_advertising); in phylink_parse_fixedlink()
775 pl->link_config.duplex == DUPLEX_FULL ? "full" : "half", in phylink_parse_fixedlink()
776 pl->link_config.speed); in phylink_parse_fixedlink()
779 linkmode_and(pl->link_config.advertising, pl->link_config.advertising, in phylink_parse_fixedlink()
780 pl->supported); in phylink_parse_fixedlink()
782 pl->link_config.link = 1; in phylink_parse_fixedlink()
783 pl->link_config.an_complete = 1; in phylink_parse_fixedlink()
793 dn = fwnode_get_named_child_node(fwnode, "fixed-link"); in phylink_parse_mode()
794 if (dn || fwnode_property_present(fwnode, "fixed-link")) in phylink_parse_mode()
795 pl->cfg_link_an_mode = MLO_AN_FIXED; in phylink_parse_mode()
799 strcmp(managed, "in-band-status") == 0) || in phylink_parse_mode()
800 pl->config->ovr_an_inband) { in phylink_parse_mode()
801 if (pl->cfg_link_an_mode == MLO_AN_FIXED) { in phylink_parse_mode()
803 "can't use both fixed-link and in-band-status\n"); in phylink_parse_mode()
804 return -EINVAL; in phylink_parse_mode()
807 linkmode_zero(pl->supported); in phylink_parse_mode()
808 phylink_set(pl->supported, MII); in phylink_parse_mode()
809 phylink_set(pl->supported, Autoneg); in phylink_parse_mode()
810 phylink_set(pl->supported, Asym_Pause); in phylink_parse_mode()
811 phylink_set(pl->supported, Pause); in phylink_parse_mode()
812 pl->link_config.an_enabled = true; in phylink_parse_mode()
813 pl->cfg_link_an_mode = MLO_AN_INBAND; in phylink_parse_mode()
815 switch (pl->link_config.interface) { in phylink_parse_mode()
824 phylink_set(pl->supported, 10baseT_Half); in phylink_parse_mode()
825 phylink_set(pl->supported, 10baseT_Full); in phylink_parse_mode()
826 phylink_set(pl->supported, 100baseT_Half); in phylink_parse_mode()
827 phylink_set(pl->supported, 100baseT_Full); in phylink_parse_mode()
828 phylink_set(pl->supported, 1000baseT_Half); in phylink_parse_mode()
829 phylink_set(pl->supported, 1000baseT_Full); in phylink_parse_mode()
833 phylink_set(pl->supported, 1000baseX_Full); in phylink_parse_mode()
837 phylink_set(pl->supported, 2500baseX_Full); in phylink_parse_mode()
841 phylink_set(pl->supported, 5000baseT_Full); in phylink_parse_mode()
845 phylink_set(pl->supported, 25000baseCR_Full); in phylink_parse_mode()
846 phylink_set(pl->supported, 25000baseKR_Full); in phylink_parse_mode()
847 phylink_set(pl->supported, 25000baseSR_Full); in phylink_parse_mode()
852 phylink_set(pl->supported, 10baseT_Half); in phylink_parse_mode()
853 phylink_set(pl->supported, 10baseT_Full); in phylink_parse_mode()
854 phylink_set(pl->supported, 100baseT_Half); in phylink_parse_mode()
855 phylink_set(pl->supported, 100baseT_Full); in phylink_parse_mode()
856 phylink_set(pl->supported, 1000baseT_Half); in phylink_parse_mode()
857 phylink_set(pl->supported, 1000baseT_Full); in phylink_parse_mode()
858 phylink_set(pl->supported, 1000baseX_Full); in phylink_parse_mode()
859 phylink_set(pl->supported, 1000baseKX_Full); in phylink_parse_mode()
860 phylink_set(pl->supported, 2500baseT_Full); in phylink_parse_mode()
861 phylink_set(pl->supported, 2500baseX_Full); in phylink_parse_mode()
862 phylink_set(pl->supported, 5000baseT_Full); in phylink_parse_mode()
863 phylink_set(pl->supported, 10000baseT_Full); in phylink_parse_mode()
864 phylink_set(pl->supported, 10000baseKR_Full); in phylink_parse_mode()
865 phylink_set(pl->supported, 10000baseKX4_Full); in phylink_parse_mode()
866 phylink_set(pl->supported, 10000baseCR_Full); in phylink_parse_mode()
867 phylink_set(pl->supported, 10000baseSR_Full); in phylink_parse_mode()
868 phylink_set(pl->supported, 10000baseLR_Full); in phylink_parse_mode()
869 phylink_set(pl->supported, 10000baseLRM_Full); in phylink_parse_mode()
870 phylink_set(pl->supported, 10000baseER_Full); in phylink_parse_mode()
874 phylink_set(pl->supported, 25000baseCR_Full); in phylink_parse_mode()
875 phylink_set(pl->supported, 25000baseKR_Full); in phylink_parse_mode()
876 phylink_set(pl->supported, 25000baseSR_Full); in phylink_parse_mode()
877 phylink_set(pl->supported, 40000baseKR4_Full); in phylink_parse_mode()
878 phylink_set(pl->supported, 40000baseCR4_Full); in phylink_parse_mode()
879 phylink_set(pl->supported, 40000baseSR4_Full); in phylink_parse_mode()
880 phylink_set(pl->supported, 40000baseLR4_Full); in phylink_parse_mode()
881 phylink_set(pl->supported, 50000baseCR2_Full); in phylink_parse_mode()
882 phylink_set(pl->supported, 50000baseKR2_Full); in phylink_parse_mode()
883 phylink_set(pl->supported, 50000baseSR2_Full); in phylink_parse_mode()
884 phylink_set(pl->supported, 50000baseKR_Full); in phylink_parse_mode()
885 phylink_set(pl->supported, 50000baseSR_Full); in phylink_parse_mode()
886 phylink_set(pl->supported, 50000baseCR_Full); in phylink_parse_mode()
887 phylink_set(pl->supported, 50000baseLR_ER_FR_Full); in phylink_parse_mode()
888 phylink_set(pl->supported, 50000baseDR_Full); in phylink_parse_mode()
889 phylink_set(pl->supported, 100000baseKR4_Full); in phylink_parse_mode()
890 phylink_set(pl->supported, 100000baseSR4_Full); in phylink_parse_mode()
891 phylink_set(pl->supported, 100000baseCR4_Full); in phylink_parse_mode()
892 phylink_set(pl->supported, 100000baseLR4_ER4_Full); in phylink_parse_mode()
893 phylink_set(pl->supported, 100000baseKR2_Full); in phylink_parse_mode()
894 phylink_set(pl->supported, 100000baseSR2_Full); in phylink_parse_mode()
895 phylink_set(pl->supported, 100000baseCR2_Full); in phylink_parse_mode()
896 phylink_set(pl->supported, 100000baseLR2_ER2_FR2_Full); in phylink_parse_mode()
897 phylink_set(pl->supported, 100000baseDR2_Full); in phylink_parse_mode()
902 "incorrect link mode %s for in-band status\n", in phylink_parse_mode()
903 phy_modes(pl->link_config.interface)); in phylink_parse_mode()
904 return -EINVAL; in phylink_parse_mode()
907 linkmode_copy(pl->link_config.advertising, pl->supported); in phylink_parse_mode()
909 if (phylink_validate(pl, pl->supported, &pl->link_config)) { in phylink_parse_mode()
911 "failed to validate link configuration for in-band status\n"); in phylink_parse_mode()
912 return -EINVAL; in phylink_parse_mode()
916 pl->link_config.an_enabled = phylink_test(pl->supported, Autoneg); in phylink_parse_mode()
926 if (!state->an_enabled) in phylink_apply_manual_flow()
927 state->pause &= ~MLO_PAUSE_AN; in phylink_apply_manual_flow()
930 if (!(pl->link_config.pause & MLO_PAUSE_AN)) in phylink_apply_manual_flow()
931 state->pause = pl->link_config.pause; in phylink_apply_manual_flow()
938 state->pause = MLO_PAUSE_NONE; in phylink_resolve_flow()
939 if (state->duplex == DUPLEX_FULL) { in phylink_resolve_flow()
940 linkmode_resolve_pause(state->advertising, in phylink_resolve_flow()
941 state->lp_advertising, in phylink_resolve_flow()
944 state->pause |= MLO_PAUSE_TX; in phylink_resolve_flow()
946 state->pause |= MLO_PAUSE_RX; in phylink_resolve_flow()
952 if (pl->cfg_link_an_mode == MLO_AN_INBAND) in phylink_pcs_poll_stop()
953 del_timer(&pl->link_poll); in phylink_pcs_poll_stop()
958 if (pl->pcs && pl->pcs->poll && pl->cfg_link_an_mode == MLO_AN_INBAND) in phylink_pcs_poll_start()
959 mod_timer(&pl->link_poll, jiffies + HZ); in phylink_pcs_poll_start()
967 __func__, phylink_an_mode_str(pl->cur_link_an_mode), in phylink_mac_config()
968 phy_modes(state->interface), in phylink_mac_config()
969 phy_speed_to_str(state->speed), in phylink_mac_config()
970 phy_duplex_to_str(state->duplex), in phylink_mac_config()
971 phy_rate_matching_to_str(state->rate_matching), in phylink_mac_config()
972 __ETHTOOL_LINK_MODE_MASK_NBITS, state->advertising, in phylink_mac_config()
973 state->pause, state->link, state->an_enabled); in phylink_mac_config()
975 pl->mac_ops->mac_config(pl->config, pl->cur_link_an_mode, state); in phylink_mac_config()
980 if (pl->link_config.an_enabled && in phylink_mac_pcs_an_restart()
981 phy_interface_mode_is_8023z(pl->link_config.interface) && in phylink_mac_pcs_an_restart()
982 phylink_autoneg_inband(pl->cur_link_an_mode)) { in phylink_mac_pcs_an_restart()
983 if (pl->pcs) in phylink_mac_pcs_an_restart()
984 pl->pcs->ops->pcs_an_restart(pl->pcs); in phylink_mac_pcs_an_restart()
985 else if (pl->config->legacy_pre_march2020) in phylink_mac_pcs_an_restart()
986 pl->mac_ops->mac_an_restart(pl->config); in phylink_mac_pcs_an_restart()
997 phylink_dbg(pl, "major config %s\n", phy_modes(state->interface)); in phylink_major_config()
999 if (pl->using_mac_select_pcs) { in phylink_major_config()
1000 pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface); in phylink_major_config()
1008 pcs_changed = pcs && pl->pcs != pcs; in phylink_major_config()
1013 if (pl->mac_ops->mac_prepare) { in phylink_major_config()
1014 err = pl->mac_ops->mac_prepare(pl->config, pl->cur_link_an_mode, in phylink_major_config()
1015 state->interface); in phylink_major_config()
1024 * for the change. in phylink_major_config()
1027 pl->pcs = pcs; in phylink_major_config()
1031 if (pl->pcs) { in phylink_major_config()
1032 err = pl->pcs->ops->pcs_config(pl->pcs, pl->cur_link_an_mode, in phylink_major_config()
1033 state->interface, in phylink_major_config()
1034 state->advertising, in phylink_major_config()
1035 !!(pl->link_config.pause & in phylink_major_config()
1046 if (pl->mac_ops->mac_finish) { in phylink_major_config()
1047 err = pl->mac_ops->mac_finish(pl->config, pl->cur_link_an_mode, in phylink_major_config()
1048 state->interface); in phylink_major_config()
1058 * Reconfigure for a change of inband advertisement.
1059 * If we have a separate PCS, we only need to call its pcs_config() method,
1067 if (test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) in phylink_change_inband_advert()
1070 if (!pl->pcs && pl->config->legacy_pre_march2020) { in phylink_change_inband_advert()
1072 phylink_mac_config(pl, &pl->link_config); in phylink_change_inband_advert()
1078 phylink_an_mode_str(pl->cur_link_an_mode), in phylink_change_inband_advert()
1079 phy_modes(pl->link_config.interface), in phylink_change_inband_advert()
1080 __ETHTOOL_LINK_MODE_MASK_NBITS, pl->link_config.advertising, in phylink_change_inband_advert()
1081 pl->link_config.pause); in phylink_change_inband_advert()
1083 /* Modern PCS-based method; update the advert at the PCS, and in phylink_change_inband_advert()
1087 ret = pl->pcs->ops->pcs_config(pl->pcs, pl->cur_link_an_mode, in phylink_change_inband_advert()
1088 pl->link_config.interface, in phylink_change_inband_advert()
1089 pl->link_config.advertising, in phylink_change_inband_advert()
1090 !!(pl->link_config.pause & in phylink_change_inband_advert()
1104 linkmode_copy(state->advertising, pl->link_config.advertising); in phylink_mac_pcs_get_state()
1105 linkmode_zero(state->lp_advertising); in phylink_mac_pcs_get_state()
1106 state->interface = pl->link_config.interface; in phylink_mac_pcs_get_state()
1107 state->an_enabled = pl->link_config.an_enabled; in phylink_mac_pcs_get_state()
1108 state->rate_matching = pl->link_config.rate_matching; in phylink_mac_pcs_get_state()
1109 if (state->an_enabled) { in phylink_mac_pcs_get_state()
1110 state->speed = SPEED_UNKNOWN; in phylink_mac_pcs_get_state()
1111 state->duplex = DUPLEX_UNKNOWN; in phylink_mac_pcs_get_state()
1112 state->pause = MLO_PAUSE_NONE; in phylink_mac_pcs_get_state()
1114 state->speed = pl->link_config.speed; in phylink_mac_pcs_get_state()
1115 state->duplex = pl->link_config.duplex; in phylink_mac_pcs_get_state()
1116 state->pause = pl->link_config.pause; in phylink_mac_pcs_get_state()
1118 state->an_complete = 0; in phylink_mac_pcs_get_state()
1119 state->link = 1; in phylink_mac_pcs_get_state()
1121 if (pl->pcs) in phylink_mac_pcs_get_state()
1122 pl->pcs->ops->pcs_get_state(pl->pcs, state); in phylink_mac_pcs_get_state()
1123 else if (pl->mac_ops->mac_pcs_get_state && in phylink_mac_pcs_get_state()
1124 pl->config->legacy_pre_march2020) in phylink_mac_pcs_get_state()
1125 pl->mac_ops->mac_pcs_get_state(pl->config, state); in phylink_mac_pcs_get_state()
1127 state->link = 0; in phylink_mac_pcs_get_state()
1130 /* The fixed state is... fixed except for the link state,
1136 *state = pl->link_config; in phylink_get_fixed_state()
1137 if (pl->config->get_fixed_state) in phylink_get_fixed_state()
1138 pl->config->get_fixed_state(pl->config, state); in phylink_get_fixed_state()
1139 else if (pl->link_gpio) in phylink_get_fixed_state()
1140 state->link = !!gpiod_get_value_cansleep(pl->link_gpio); in phylink_get_fixed_state()
1149 switch (pl->cur_link_an_mode) { in phylink_mac_initial_config()
1151 link_state = pl->phy_state; in phylink_mac_initial_config()
1159 link_state = pl->link_config; in phylink_mac_initial_config()
1191 struct net_device *ndev = pl->netdev; in phylink_link_up()
1201 /* The PHY is doing rate matchion from the media rate (in in phylink_link_up()
1211 /* The PHY is doing rate matchion from the media rate (in in phylink_link_up()
1220 pl->cur_interface = link_state.interface; in phylink_link_up()
1222 if (pl->pcs && pl->pcs->ops->pcs_link_up) in phylink_link_up()
1223 pl->pcs->ops->pcs_link_up(pl->pcs, pl->cur_link_an_mode, in phylink_link_up()
1224 pl->cur_interface, speed, duplex); in phylink_link_up()
1226 pl->mac_ops->mac_link_up(pl->config, pl->phydev, pl->cur_link_an_mode, in phylink_link_up()
1227 pl->cur_interface, speed, duplex, in phylink_link_up()
1234 "Link is Up - %s/%s - flow control %s\n", in phylink_link_up()
1242 struct net_device *ndev = pl->netdev; in phylink_link_down()
1246 pl->mac_ops->mac_link_down(pl->config, pl->cur_link_an_mode, in phylink_link_down()
1247 pl->cur_interface); in phylink_link_down()
1255 struct net_device *ndev = pl->netdev; in phylink_resolve()
1260 mutex_lock(&pl->state_mutex); in phylink_resolve()
1261 if (pl->netdev) in phylink_resolve()
1264 cur_link_state = pl->old_link_state; in phylink_resolve()
1266 if (pl->phylink_disable_state) { in phylink_resolve()
1267 pl->mac_link_dropped = false; in phylink_resolve()
1269 } else if (pl->mac_link_dropped) { in phylink_resolve()
1273 switch (pl->cur_link_an_mode) { in phylink_resolve()
1275 link_state = pl->phy_state; in phylink_resolve()
1288 /* The PCS may have a latching link-fail indicator. in phylink_resolve()
1290 * re-trigger the resolve. Otherwise, re-read the in phylink_resolve()
1301 /* If we have a phy, the "up" state is the union of in phylink_resolve()
1302 * both the PHY and the MAC in phylink_resolve()
1304 if (pl->phydev) in phylink_resolve()
1305 link_state.link &= pl->phy_state.link; in phylink_resolve()
1307 /* Only update if the PHY link is up */ in phylink_resolve()
1308 if (pl->phydev && pl->phy_state.link) { in phylink_resolve()
1311 * down, and re-resolve. in phylink_resolve()
1314 pl->phy_state.interface) { in phylink_resolve()
1318 link_state.interface = pl->phy_state.interface; in phylink_resolve()
1321 * link speed/duplex comes from the PHY in phylink_resolve()
1323 if (pl->phy_state.rate_matching) { in phylink_resolve()
1325 pl->phy_state.rate_matching; in phylink_resolve()
1326 link_state.speed = pl->phy_state.speed; in phylink_resolve()
1328 pl->phy_state.duplex; in phylink_resolve()
1331 /* If we have a PHY, we need to update with in phylink_resolve()
1332 * the PHY flow control bits. in phylink_resolve()
1334 link_state.pause = pl->phy_state.pause; in phylink_resolve()
1343 if (link_state.interface != pl->link_config.interface) { in phylink_resolve()
1352 pl->link_config.interface = link_state.interface; in phylink_resolve()
1353 } else if (!pl->pcs && pl->config->legacy_pre_march2020) { in phylink_resolve()
1364 pl->old_link_state = link_state.link; in phylink_resolve()
1371 pl->mac_link_dropped = false; in phylink_resolve()
1372 queue_work(system_power_efficient_wq, &pl->resolve); in phylink_resolve()
1374 mutex_unlock(&pl->state_mutex); in phylink_resolve()
1379 if (!pl->phylink_disable_state) in phylink_run_resolve()
1380 queue_work(system_power_efficient_wq, &pl->resolve); in phylink_run_resolve()
1385 unsigned long state = pl->phylink_disable_state; in phylink_run_resolve_and_disable()
1387 set_bit(bit, &pl->phylink_disable_state); in phylink_run_resolve_and_disable()
1389 queue_work(system_power_efficient_wq, &pl->resolve); in phylink_run_resolve_and_disable()
1390 flush_work(&pl->resolve); in phylink_run_resolve_and_disable()
1396 clear_bit(bit, &pl->phylink_disable_state); in phylink_enable_and_run_resolve()
1426 pl->sfp_bus = bus; in phylink_register_sfp()
1435 * phylink_create() - create a phylink instance
1440 * @mac_ops: a pointer to a &struct phylink_mac_ops for the MAC.
1443 * This will parse in-band modes, fixed-link or SFP configuration.
1447 * Returns a pointer to a &struct phylink, or an error-pointer value. Users
1448 * must use IS_ERR() to check for errors from this function.
1459 if (mac_ops->mac_select_pcs && in phylink_create()
1460 mac_ops->mac_select_pcs(config, PHY_INTERFACE_MODE_NA) != in phylink_create()
1461 ERR_PTR(-EOPNOTSUPP)) in phylink_create()
1466 phy_interface_empty(config->supported_interfaces)) { in phylink_create()
1467 dev_err(config->dev, in phylink_create()
1469 return ERR_PTR(-EINVAL); in phylink_create()
1474 return ERR_PTR(-ENOMEM); in phylink_create()
1476 mutex_init(&pl->state_mutex); in phylink_create()
1477 INIT_WORK(&pl->resolve, phylink_resolve); in phylink_create()
1479 pl->config = config; in phylink_create()
1480 if (config->type == PHYLINK_NETDEV) { in phylink_create()
1481 pl->netdev = to_net_dev(config->dev); in phylink_create()
1482 } else if (config->type == PHYLINK_DEV) { in phylink_create()
1483 pl->dev = config->dev; in phylink_create()
1486 return ERR_PTR(-EINVAL); in phylink_create()
1489 pl->using_mac_select_pcs = using_mac_select_pcs; in phylink_create()
1490 pl->phy_state.interface = iface; in phylink_create()
1491 pl->link_interface = iface; in phylink_create()
1493 pl->link_port = PORT_BNC; in phylink_create()
1495 pl->link_port = PORT_MII; in phylink_create()
1496 pl->link_config.interface = iface; in phylink_create()
1497 pl->link_config.pause = MLO_PAUSE_AN; in phylink_create()
1498 pl->link_config.speed = SPEED_UNKNOWN; in phylink_create()
1499 pl->link_config.duplex = DUPLEX_UNKNOWN; in phylink_create()
1500 pl->link_config.an_enabled = true; in phylink_create()
1501 pl->mac_ops = mac_ops; in phylink_create()
1502 __set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); in phylink_create()
1503 timer_setup(&pl->link_poll, phylink_fixed_poll, 0); in phylink_create()
1505 bitmap_fill(pl->supported, __ETHTOOL_LINK_MODE_MASK_NBITS); in phylink_create()
1506 linkmode_copy(pl->link_config.advertising, pl->supported); in phylink_create()
1507 phylink_validate(pl, pl->supported, &pl->link_config); in phylink_create()
1515 if (pl->cfg_link_an_mode == MLO_AN_FIXED) { in phylink_create()
1523 pl->cur_link_an_mode = pl->cfg_link_an_mode; in phylink_create()
1536 * phylink_destroy() - cleanup and destroy the phylink instance
1539 * Destroy a phylink instance. Any PHY that has been attached must have been
1546 sfp_bus_del_upstream(pl->sfp_bus); in phylink_destroy()
1547 if (pl->link_gpio) in phylink_destroy()
1548 gpiod_put(pl->link_gpio); in phylink_destroy()
1550 cancel_work_sync(&pl->resolve); in phylink_destroy()
1557 struct phylink *pl = phydev->phylink; in phylink_phy_change()
1562 mutex_lock(&pl->state_mutex); in phylink_phy_change()
1563 pl->phy_state.speed = phydev->speed; in phylink_phy_change()
1564 pl->phy_state.duplex = phydev->duplex; in phylink_phy_change()
1565 pl->phy_state.rate_matching = phydev->rate_matching; in phylink_phy_change()
1566 pl->phy_state.pause = MLO_PAUSE_NONE; in phylink_phy_change()
1568 pl->phy_state.pause |= MLO_PAUSE_TX; in phylink_phy_change()
1570 pl->phy_state.pause |= MLO_PAUSE_RX; in phylink_phy_change()
1571 pl->phy_state.interface = phydev->interface; in phylink_phy_change()
1572 pl->phy_state.link = up; in phylink_phy_change()
1573 mutex_unlock(&pl->state_mutex); in phylink_phy_change()
1577 phylink_dbg(pl, "phy link %s %s/%s/%s/%s/%s\n", up ? "up" : "down", in phylink_phy_change()
1578 phy_modes(phydev->interface), in phylink_phy_change()
1579 phy_speed_to_str(phydev->speed), in phylink_phy_change()
1580 phy_duplex_to_str(phydev->duplex), in phylink_phy_change()
1581 phy_rate_matching_to_str(phydev->rate_matching), in phylink_phy_change()
1582 phylink_pause_to_str(pl->phy_state.pause)); in phylink_phy_change()
1585 static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy, in phylink_bringup_phy() argument
1594 * This is the new way of dealing with flow control for PHYs, in phylink_bringup_phy()
1595 * as described by Timur Tabi in commit 529ed1275263 ("net: phy: in phylink_bringup_phy()
1596 * phy drivers should not set SUPPORTED_[Asym_]Pause") except in phylink_bringup_phy()
1600 phy_support_asym_pause(phy); in phylink_bringup_phy()
1603 linkmode_copy(supported, phy->supported); in phylink_bringup_phy()
1604 linkmode_copy(config.advertising, phy->advertising); in phylink_bringup_phy()
1606 /* Check whether we would use rate matching for the proposed interface in phylink_bringup_phy()
1609 config.rate_matching = phy_get_rate_matching(phy, interface); in phylink_bringup_phy()
1611 /* Clause 45 PHYs may switch their Serdes lane between, e.g. 10GBASE-R, in phylink_bringup_phy()
1612 * 5GBASE-R, 2500BASE-X and SGMII if they are not using rate matching. in phylink_bringup_phy()
1613 * For some interface modes (e.g. RXAUI, XAUI and USXGMII) switching in phylink_bringup_phy()
1616 * For these which switch interface modes, we really need to know which in phylink_bringup_phy()
1617 * interface modes the PHY supports to properly work out which ethtool in phylink_bringup_phy()
1618 * linkmodes can be supported. For now, as a work-around, we validate in phylink_bringup_phy()
1622 if (phy->is_c45 && config.rate_matching == RATE_MATCH_NONE && in phylink_bringup_phy()
1634 __ETHTOOL_LINK_MODE_MASK_NBITS, phy->supported, in phylink_bringup_phy()
1640 phy->phylink = pl; in phylink_bringup_phy()
1641 phy->phy_link_change = phylink_phy_change; in phylink_bringup_phy()
1643 irq_str = phy_attached_info_irq(phy); in phylink_bringup_phy()
1645 "PHY [%s] driver [%s] (irq=%s)\n", in phylink_bringup_phy()
1646 dev_name(&phy->mdio.dev), phy->drv->name, irq_str); in phylink_bringup_phy()
1649 mutex_lock(&phy->lock); in phylink_bringup_phy()
1650 mutex_lock(&pl->state_mutex); in phylink_bringup_phy()
1651 pl->phydev = phy; in phylink_bringup_phy()
1652 pl->phy_state.interface = interface; in phylink_bringup_phy()
1653 pl->phy_state.pause = MLO_PAUSE_NONE; in phylink_bringup_phy()
1654 pl->phy_state.speed = SPEED_UNKNOWN; in phylink_bringup_phy()
1655 pl->phy_state.duplex = DUPLEX_UNKNOWN; in phylink_bringup_phy()
1656 pl->phy_state.rate_matching = RATE_MATCH_NONE; in phylink_bringup_phy()
1657 linkmode_copy(pl->supported, supported); in phylink_bringup_phy()
1658 linkmode_copy(pl->link_config.advertising, config.advertising); in phylink_bringup_phy()
1660 /* Restrict the phy advertisement according to the MAC support. */ in phylink_bringup_phy()
1661 linkmode_copy(phy->advertising, config.advertising); in phylink_bringup_phy()
1662 mutex_unlock(&pl->state_mutex); in phylink_bringup_phy()
1663 mutex_unlock(&phy->lock); in phylink_bringup_phy()
1666 "phy: %s setting supported %*pb advertising %*pb\n", in phylink_bringup_phy()
1668 __ETHTOOL_LINK_MODE_MASK_NBITS, pl->supported, in phylink_bringup_phy()
1669 __ETHTOOL_LINK_MODE_MASK_NBITS, phy->advertising); in phylink_bringup_phy()
1671 if (phy_interrupt_is_valid(phy)) in phylink_bringup_phy()
1672 phy_request_interrupt(phy); in phylink_bringup_phy()
1674 if (pl->config->mac_managed_pm) in phylink_bringup_phy()
1675 phy->mac_managed_pm = true; in phylink_bringup_phy()
1680 static int phylink_attach_phy(struct phylink *pl, struct phy_device *phy, in phylink_attach_phy() argument
1683 if (WARN_ON(pl->cfg_link_an_mode == MLO_AN_FIXED || in phylink_attach_phy()
1684 (pl->cfg_link_an_mode == MLO_AN_INBAND && in phylink_attach_phy()
1685 phy_interface_mode_is_8023z(interface) && !pl->sfp_bus))) in phylink_attach_phy()
1686 return -EINVAL; in phylink_attach_phy()
1688 if (pl->phydev) in phylink_attach_phy()
1689 return -EBUSY; in phylink_attach_phy()
1691 return phy_attach_direct(pl->netdev, phy, 0, interface); in phylink_attach_phy()
1695 * phylink_connect_phy() - connect a PHY to the phylink instance
1697 * @phy: a pointer to a &struct phy_device.
1699 * Connect @phy to the phylink instance specified by @pl by calling
1700 * phy_attach_direct(). Configure the @phy according to the MAC driver's
1702 * that the PHY supports.
1709 int phylink_connect_phy(struct phylink *pl, struct phy_device *phy) in phylink_connect_phy() argument
1713 /* Use PHY device/driver interface */ in phylink_connect_phy()
1714 if (pl->link_interface == PHY_INTERFACE_MODE_NA) { in phylink_connect_phy()
1715 pl->link_interface = phy->interface; in phylink_connect_phy()
1716 pl->link_config.interface = pl->link_interface; in phylink_connect_phy()
1719 ret = phylink_attach_phy(pl, phy, pl->link_interface); in phylink_connect_phy()
1723 ret = phylink_bringup_phy(pl, phy, pl->link_config.interface); in phylink_connect_phy()
1725 phy_detach(phy); in phylink_connect_phy()
1732 * phylink_of_phy_connect() - connect the PHY specified in the DT mode.
1735 * @flags: PHY-specific flags to communicate to the PHY device driver
1737 * Connect the phy specified in the device node @dn to the phylink instance
1751 * phylink_fwnode_phy_connect() - connect the PHY specified in the fwnode.
1754 * @flags: PHY-specific flags to communicate to the PHY device driver
1756 * Connect the phy specified @fwnode to the phylink instance specified
1769 /* Fixed links and 802.3z are handled without needing a PHY */ in phylink_fwnode_phy_connect()
1770 if (pl->cfg_link_an_mode == MLO_AN_FIXED || in phylink_fwnode_phy_connect()
1771 (pl->cfg_link_an_mode == MLO_AN_INBAND && in phylink_fwnode_phy_connect()
1772 phy_interface_mode_is_8023z(pl->link_interface))) in phylink_fwnode_phy_connect()
1777 if (pl->cfg_link_an_mode == MLO_AN_PHY) in phylink_fwnode_phy_connect()
1778 return -ENODEV; in phylink_fwnode_phy_connect()
1786 return -ENODEV; in phylink_fwnode_phy_connect()
1788 /* Use PHY device/driver interface */ in phylink_fwnode_phy_connect()
1789 if (pl->link_interface == PHY_INTERFACE_MODE_NA) { in phylink_fwnode_phy_connect()
1790 pl->link_interface = phy_dev->interface; in phylink_fwnode_phy_connect()
1791 pl->link_config.interface = pl->link_interface; in phylink_fwnode_phy_connect()
1794 ret = phy_attach_direct(pl->netdev, phy_dev, flags, in phylink_fwnode_phy_connect()
1795 pl->link_interface); in phylink_fwnode_phy_connect()
1801 ret = phylink_bringup_phy(pl, phy_dev, pl->link_config.interface); in phylink_fwnode_phy_connect()
1810 * phylink_disconnect_phy() - disconnect any PHY attached to the phylink
1814 * Disconnect any current PHY from the phylink instance described by @pl.
1818 struct phy_device *phy; in phylink_disconnect_phy() local
1822 phy = pl->phydev; in phylink_disconnect_phy()
1823 if (phy) { in phylink_disconnect_phy()
1824 mutex_lock(&phy->lock); in phylink_disconnect_phy()
1825 mutex_lock(&pl->state_mutex); in phylink_disconnect_phy()
1826 pl->phydev = NULL; in phylink_disconnect_phy()
1827 mutex_unlock(&pl->state_mutex); in phylink_disconnect_phy()
1828 mutex_unlock(&phy->lock); in phylink_disconnect_phy()
1829 flush_work(&pl->resolve); in phylink_disconnect_phy()
1831 phy_disconnect(phy); in phylink_disconnect_phy()
1837 * phylink_mac_change() - notify phylink of a change in MAC state
1847 pl->mac_link_dropped = true; in phylink_mac_change()
1863 * phylink_start() - start a phylink instance
1866 * Start the phylink instance specified by @pl, configuring the MAC for the
1876 phylink_info(pl, "configuring for %s/%s link mode\n", in phylink_start()
1877 phylink_an_mode_str(pl->cur_link_an_mode), in phylink_start()
1878 phy_modes(pl->link_config.interface)); in phylink_start()
1881 if (pl->netdev) in phylink_start()
1882 netif_carrier_off(pl->netdev); in phylink_start()
1885 * a fixed-link to start with the correct parameters, and also in phylink_start()
1886 * ensures that we set the appropriate advertisement for Serdes links. in phylink_start()
1889 * parameters are properly negotiated. This is necessary for DSA in phylink_start()
1896 if (pl->cfg_link_an_mode == MLO_AN_FIXED && pl->link_gpio) { in phylink_start()
1897 int irq = gpiod_to_irq(pl->link_gpio); in phylink_start()
1904 pl->link_irq = irq; in phylink_start()
1912 switch (pl->cfg_link_an_mode) { in phylink_start()
1914 poll |= pl->config->poll_fixed_state; in phylink_start()
1917 if (pl->pcs) in phylink_start()
1918 poll |= pl->pcs->poll; in phylink_start()
1922 mod_timer(&pl->link_poll, jiffies + HZ); in phylink_start()
1923 if (pl->phydev) in phylink_start()
1924 phy_start(pl->phydev); in phylink_start()
1925 if (pl->sfp_bus) in phylink_start()
1926 sfp_upstream_start(pl->sfp_bus); in phylink_start()
1931 * phylink_stop() - stop a phylink instance
1946 if (pl->sfp_bus) in phylink_stop()
1947 sfp_upstream_stop(pl->sfp_bus); in phylink_stop()
1948 if (pl->phydev) in phylink_stop()
1949 phy_stop(pl->phydev); in phylink_stop()
1950 del_timer_sync(&pl->link_poll); in phylink_stop()
1951 if (pl->link_irq) { in phylink_stop()
1952 free_irq(pl->link_irq, pl); in phylink_stop()
1953 pl->link_irq = 0; in phylink_stop()
1961 * phylink_suspend() - handle a network device suspend event
1963 * @mac_wol: true if the MAC needs to receive packets for Wake-on-Lan
1967 * - If Wake-on-Lan is not active, we can bring down the link between
1968 * the MAC and PHY by calling phylink_stop().
1969 * - If Wake-on-Lan is active, and being handled only by the PHY, we
1970 * can also bring down the link between the MAC and PHY.
1971 * - If Wake-on-Lan is active, but being handled by the MAC, the MAC
1978 if (mac_wol && (!pl->netdev || pl->netdev->wol_enabled)) { in phylink_suspend()
1979 /* Wake-on-Lan enabled, MAC handling */ in phylink_suspend()
1980 mutex_lock(&pl->state_mutex); in phylink_suspend()
1983 __set_bit(PHYLINK_DISABLE_MAC_WOL, &pl->phylink_disable_state); in phylink_suspend()
1989 if (pl->netdev) in phylink_suspend()
1990 netif_carrier_off(pl->netdev); in phylink_suspend()
1992 pl->old_link_state = false; in phylink_suspend()
1997 mutex_unlock(&pl->state_mutex); in phylink_suspend()
2005 * phylink_resume() - handle a network device resume event
2015 if (test_bit(PHYLINK_DISABLE_MAC_WOL, &pl->phylink_disable_state)) { in phylink_resume()
2016 /* Wake-on-Lan enabled, MAC handling */ in phylink_resume()
2019 * Do this under the state_mutex lock for consistency. This in phylink_resume()
2021 * resume, which is harmless - the true link state will be in phylink_resume()
2024 mutex_lock(&pl->state_mutex); in phylink_resume()
2026 mutex_unlock(&pl->state_mutex); in phylink_resume()
2028 /* Re-apply the link parameters so that all the settings get in phylink_resume()
2033 /* Re-enable and re-resolve the link parameters */ in phylink_resume()
2042 * phylink_ethtool_get_wol() - get the wake on lan parameters for the PHY
2046 * Read the wake on lan parameters from the PHY attached to the phylink
2047 * instance specified by @pl. If no PHY is currently attached, report no
2048 * support for wake on lan.
2054 wol->supported = 0; in phylink_ethtool_get_wol()
2055 wol->wolopts = 0; in phylink_ethtool_get_wol()
2057 if (pl->phydev) in phylink_ethtool_get_wol()
2058 phy_ethtool_get_wol(pl->phydev, wol); in phylink_ethtool_get_wol()
2063 * phylink_ethtool_set_wol() - set wake on lan parameters
2065 * @wol: a pointer to &struct ethtool_wolinfo for the desired parameters
2067 * Set the wake on lan parameters for the PHY attached to the phylink
2068 * instance specified by @pl. If no PHY is attached, returns %EOPNOTSUPP
2075 int ret = -EOPNOTSUPP; in phylink_ethtool_set_wol()
2079 if (pl->phydev) in phylink_ethtool_set_wol()
2080 ret = phy_ethtool_set_wol(pl->phydev, wol); in phylink_ethtool_set_wol()
2100 phylink_merge_link_mode(kset->link_modes.advertising, state->advertising); in phylink_get_ksettings()
2101 linkmode_copy(kset->link_modes.lp_advertising, state->lp_advertising); in phylink_get_ksettings()
2102 if (kset->base.rate_matching == RATE_MATCH_NONE) { in phylink_get_ksettings()
2103 kset->base.speed = state->speed; in phylink_get_ksettings()
2104 kset->base.duplex = state->duplex; in phylink_get_ksettings()
2106 kset->base.autoneg = state->an_enabled ? AUTONEG_ENABLE : in phylink_get_ksettings()
2111 * phylink_ethtool_ksettings_get() - get the current link settings
2115 * Read the current link settings for the phylink instance specified by @pl.
2116 * This will be the link settings read from the MAC, PHY or fixed link
2126 if (pl->phydev) in phylink_ethtool_ksettings_get()
2127 phy_ethtool_ksettings_get(pl->phydev, kset); in phylink_ethtool_ksettings_get()
2129 kset->base.port = pl->link_port; in phylink_ethtool_ksettings_get()
2131 linkmode_copy(kset->link_modes.supported, pl->supported); in phylink_ethtool_ksettings_get()
2133 switch (pl->cur_link_an_mode) { in phylink_ethtool_ksettings_get()
2136 * current link settings - and note that these also in phylink_ethtool_ksettings_get()
2144 /* If there is a phy attached, then use the reported in phylink_ethtool_ksettings_get()
2145 * settings from the phy with no modification. in phylink_ethtool_ksettings_get()
2147 if (pl->phydev) in phylink_ethtool_ksettings_get()
2153 * layer via in-band status. Report these as the current in phylink_ethtool_ksettings_get()
2165 * phylink_ethtool_ksettings_set() - set the link settings
2167 * @kset: a pointer to a &struct ethtool_link_ksettings for the desired modes
2178 if (pl->phydev) { in phylink_ethtool_ksettings_set()
2179 /* We can rely on phylib for this update; we also do not need in phylink_ethtool_ksettings_set()
2180 * to update the pl->link_config settings: in phylink_ethtool_ksettings_set()
2181 * - the configuration returned via ksettings_get() will come in phylink_ethtool_ksettings_set()
2182 * from phylib whenever a PHY is present. in phylink_ethtool_ksettings_set()
2183 * - link_config.interface will be updated by the PHY calling in phylink_ethtool_ksettings_set()
2185 * - initial link configuration for PHY mode comes from the in phylink_ethtool_ksettings_set()
2186 * last phy state updated via phylink_phy_change(). in phylink_ethtool_ksettings_set()
2187 * - other configuration changes (e.g. pause modes) are in phylink_ethtool_ksettings_set()
2189 * - if in in-band mode with a PHY, the link configuration in phylink_ethtool_ksettings_set()
2190 * is passed on the link from the PHY, and all of in phylink_ethtool_ksettings_set()
2192 * - the only possible use would be link_config.advertising in phylink_ethtool_ksettings_set()
2193 * pause modes when in 1000base-X mode with a PHY, but in in phylink_ethtool_ksettings_set()
2194 * the presence of a PHY, this should not be changed as that in phylink_ethtool_ksettings_set()
2197 return phy_ethtool_ksettings_set(pl->phydev, kset); in phylink_ethtool_ksettings_set()
2200 config = pl->link_config; in phylink_ethtool_ksettings_set()
2203 linkmode_and(config.advertising, kset->link_modes.advertising, in phylink_ethtool_ksettings_set()
2204 pl->supported); in phylink_ethtool_ksettings_set()
2206 /* FIXME: should we reject autoneg if phy/mac does not support it? */ in phylink_ethtool_ksettings_set()
2207 switch (kset->base.autoneg) { in phylink_ethtool_ksettings_set()
2212 s = phy_lookup_setting(kset->base.speed, kset->base.duplex, in phylink_ethtool_ksettings_set()
2213 pl->supported, false); in phylink_ethtool_ksettings_set()
2215 return -EINVAL; in phylink_ethtool_ksettings_set()
2220 if (pl->cur_link_an_mode == MLO_AN_FIXED) { in phylink_ethtool_ksettings_set()
2221 if (s->speed != pl->link_config.speed || in phylink_ethtool_ksettings_set()
2222 s->duplex != pl->link_config.duplex) in phylink_ethtool_ksettings_set()
2223 return -EINVAL; in phylink_ethtool_ksettings_set()
2227 config.speed = s->speed; in phylink_ethtool_ksettings_set()
2228 config.duplex = s->duplex; in phylink_ethtool_ksettings_set()
2236 if (pl->cur_link_an_mode == MLO_AN_FIXED) { in phylink_ethtool_ksettings_set()
2238 pl->link_config.advertising)) in phylink_ethtool_ksettings_set()
2239 return -EINVAL; in phylink_ethtool_ksettings_set()
2248 return -EINVAL; in phylink_ethtool_ksettings_set()
2251 /* We have ruled out the case with a PHY attached, and the in phylink_ethtool_ksettings_set()
2252 * fixed-link cases. All that is left are in-band links. in phylink_ethtool_ksettings_set()
2254 config.an_enabled = kset->base.autoneg == AUTONEG_ENABLE; in phylink_ethtool_ksettings_set()
2262 if (pl->sfp_bus) { in phylink_ethtool_ksettings_set()
2263 config.interface = sfp_select_interface(pl->sfp_bus, in phylink_ethtool_ksettings_set()
2270 return -EINVAL; in phylink_ethtool_ksettings_set()
2274 linkmode_copy(support, pl->supported); in phylink_ethtool_ksettings_set()
2277 phylink_an_mode_str(pl->cur_link_an_mode), in phylink_ethtool_ksettings_set()
2280 return -EINVAL; in phylink_ethtool_ksettings_set()
2284 linkmode_copy(support, pl->supported); in phylink_ethtool_ksettings_set()
2286 return -EINVAL; in phylink_ethtool_ksettings_set()
2291 return -EINVAL; in phylink_ethtool_ksettings_set()
2293 mutex_lock(&pl->state_mutex); in phylink_ethtool_ksettings_set()
2294 pl->link_config.speed = config.speed; in phylink_ethtool_ksettings_set()
2295 pl->link_config.duplex = config.duplex; in phylink_ethtool_ksettings_set()
2296 pl->link_config.an_enabled = config.an_enabled; in phylink_ethtool_ksettings_set()
2298 if (pl->link_config.interface != config.interface) { in phylink_ethtool_ksettings_set()
2299 /* The interface changed, e.g. 1000base-X <-> 2500base-X */ in phylink_ethtool_ksettings_set()
2300 /* We need to force the link down, then change the interface */ in phylink_ethtool_ksettings_set()
2301 if (pl->old_link_state) { in phylink_ethtool_ksettings_set()
2303 pl->old_link_state = false; in phylink_ethtool_ksettings_set()
2306 &pl->phylink_disable_state)) in phylink_ethtool_ksettings_set()
2308 pl->link_config.interface = config.interface; in phylink_ethtool_ksettings_set()
2309 linkmode_copy(pl->link_config.advertising, config.advertising); in phylink_ethtool_ksettings_set()
2310 } else if (!linkmode_equal(pl->link_config.advertising, in phylink_ethtool_ksettings_set()
2312 linkmode_copy(pl->link_config.advertising, config.advertising); in phylink_ethtool_ksettings_set()
2315 mutex_unlock(&pl->state_mutex); in phylink_ethtool_ksettings_set()
2322 * phylink_ethtool_nway_reset() - restart negotiation
2325 * Restart negotiation for the phylink instance specified by @pl. This will
2326 * cause any attached phy to restart negotiation with the link partner, and
2338 if (pl->phydev) in phylink_ethtool_nway_reset()
2339 ret = phy_restart_aneg(pl->phydev); in phylink_ethtool_nway_reset()
2347 * phylink_ethtool_get_pauseparam() - get the current pause parameters
2356 pause->autoneg = !!(pl->link_config.pause & MLO_PAUSE_AN); in phylink_ethtool_get_pauseparam()
2357 pause->rx_pause = !!(pl->link_config.pause & MLO_PAUSE_RX); in phylink_ethtool_get_pauseparam()
2358 pause->tx_pause = !!(pl->link_config.pause & MLO_PAUSE_TX); in phylink_ethtool_get_pauseparam()
2363 * phylink_ethtool_set_pauseparam() - set the current pause parameters
2370 struct phylink_link_state *config = &pl->link_config; in phylink_ethtool_set_pauseparam()
2376 if (pl->cur_link_an_mode == MLO_AN_FIXED) in phylink_ethtool_set_pauseparam()
2377 return -EOPNOTSUPP; in phylink_ethtool_set_pauseparam()
2379 if (!phylink_test(pl->supported, Pause) && in phylink_ethtool_set_pauseparam()
2380 !phylink_test(pl->supported, Asym_Pause)) in phylink_ethtool_set_pauseparam()
2381 return -EOPNOTSUPP; in phylink_ethtool_set_pauseparam()
2383 if (!phylink_test(pl->supported, Asym_Pause) && in phylink_ethtool_set_pauseparam()
2384 pause->rx_pause != pause->tx_pause) in phylink_ethtool_set_pauseparam()
2385 return -EINVAL; in phylink_ethtool_set_pauseparam()
2388 if (pause->autoneg) in phylink_ethtool_set_pauseparam()
2390 if (pause->rx_pause) in phylink_ethtool_set_pauseparam()
2392 if (pause->tx_pause) in phylink_ethtool_set_pauseparam()
2395 mutex_lock(&pl->state_mutex); in phylink_ethtool_set_pauseparam()
2397 * See the comments for linkmode_set_pause(), wrt the deficiencies in phylink_ethtool_set_pauseparam()
2409 linkmode_set_pause(config->advertising, pause->tx_pause, in phylink_ethtool_set_pauseparam()
2410 pause->rx_pause); in phylink_ethtool_set_pauseparam()
2412 manual_changed = (config->pause ^ pause_state) & MLO_PAUSE_AN || in phylink_ethtool_set_pauseparam()
2414 (config->pause ^ pause_state) & MLO_PAUSE_TXRX_MASK); in phylink_ethtool_set_pauseparam()
2416 config->pause = pause_state; in phylink_ethtool_set_pauseparam()
2418 /* Update our in-band advertisement, triggering a renegotiation if in phylink_ethtool_set_pauseparam()
2421 if (!pl->phydev) in phylink_ethtool_set_pauseparam()
2424 mutex_unlock(&pl->state_mutex); in phylink_ethtool_set_pauseparam()
2426 /* If we have a PHY, a change of the pause frame advertisement will in phylink_ethtool_set_pauseparam()
2431 if (pl->phydev) in phylink_ethtool_set_pauseparam()
2432 phy_set_asym_pause(pl->phydev, pause->rx_pause, in phylink_ethtool_set_pauseparam()
2433 pause->tx_pause); in phylink_ethtool_set_pauseparam()
2440 pl->mac_link_dropped = true; in phylink_ethtool_set_pauseparam()
2449 * phylink_get_eee_err() - read the energy efficient ethernet error
2453 * Read the Energy Efficient Ethernet error counter from the PHY associated
2464 if (pl->phydev) in phylink_get_eee_err()
2465 ret = phy_get_eee_err(pl->phydev); in phylink_get_eee_err()
2472 * phylink_init_eee() - init and check the EEE features
2474 * @clk_stop_enable: allow PHY to stop receive clock
2480 int ret = -EOPNOTSUPP; in phylink_init_eee()
2482 if (pl->phydev) in phylink_init_eee()
2483 ret = phy_init_eee(pl->phydev, clk_stop_enable); in phylink_init_eee()
2490 * phylink_ethtool_get_eee() - read the energy efficient ethernet parameters
2492 * @eee: a pointer to a &struct ethtool_eee for the read parameters
2496 int ret = -EOPNOTSUPP; in phylink_ethtool_get_eee()
2500 if (pl->phydev) in phylink_ethtool_get_eee()
2501 ret = phy_ethtool_get_eee(pl->phydev, eee); in phylink_ethtool_get_eee()
2508 * phylink_ethtool_set_eee() - set the energy efficient ethernet parameters
2510 * @eee: a pointer to a &struct ethtool_eee for the desired parameters
2514 int ret = -EOPNOTSUPP; in phylink_ethtool_set_eee()
2518 if (pl->phydev) in phylink_ethtool_set_eee()
2519 ret = phy_ethtool_set_eee(pl->phydev, eee); in phylink_ethtool_set_eee()
2525 /* This emulates MII registers for a fixed-mode phy operating as per the
2534 unsigned long *lpa = state->lp_advertising; in phylink_mii_emul_read()
2537 fs.link = state->link; in phylink_mii_emul_read()
2538 fs.speed = state->speed; in phylink_mii_emul_read()
2539 fs.duplex = state->duplex; in phylink_mii_emul_read()
2545 if (!state->an_complete) in phylink_mii_emul_read()
2554 struct phy_device *phydev = pl->phydev; in phylink_phy_read()
2560 return mdiobus_c45_read(pl->phydev->mdio.bus, prtad, devad, in phylink_phy_read()
2564 if (phydev->is_c45) { in phylink_phy_read()
2570 devad = __ffs(phydev->c45_ids.mmds_present); in phylink_phy_read()
2574 if (!(phydev->c45_ids.mmds_present & MDIO_DEVS_AN)) in phylink_phy_read()
2575 return -EINVAL; in phylink_phy_read()
2583 return -EINVAL; in phylink_phy_read()
2586 return mdiobus_c45_read(pl->phydev->mdio.bus, prtad, devad, in phylink_phy_read()
2590 return mdiobus_read(pl->phydev->mdio.bus, phy_id, reg); in phylink_phy_read()
2596 struct phy_device *phydev = pl->phydev; in phylink_phy_write()
2602 return mdiobus_c45_write(pl->phydev->mdio.bus, prtad, devad, in phylink_phy_write()
2606 if (phydev->is_c45) { in phylink_phy_write()
2612 devad = __ffs(phydev->c45_ids.mmds_present); in phylink_phy_write()
2616 if (!(phydev->c45_ids.mmds_present & MDIO_DEVS_AN)) in phylink_phy_write()
2617 return -EINVAL; in phylink_phy_write()
2625 return -EINVAL; in phylink_phy_write()
2627 return mdiobus_c45_write(pl->phydev->mdio.bus, phy_id, devad, in phylink_phy_write()
2631 return mdiobus_write(phydev->mdio.bus, phy_id, reg, val); in phylink_phy_write()
2640 switch (pl->cur_link_an_mode) { in phylink_mii_read()
2649 return -EOPNOTSUPP; in phylink_mii_read()
2665 switch (pl->cur_link_an_mode) { in phylink_mii_write()
2670 return -EOPNOTSUPP; in phylink_mii_write()
2680 * phylink_mii_ioctl() - generic mii ioctl interface
2682 * @ifr: a pointer to a &struct ifreq for socket ioctls
2685 * Perform the specified MII ioctl on the PHY attached to the phylink instance
2686 * specified by @pl. If no PHY is attached, emulate the presence of the PHY.
2691 * read register from the current PHY.
2693 * read register from the specified PHY.
2695 * set a register on the specified PHY.
2704 if (pl->phydev) { in phylink_mii_ioctl()
2705 /* PHYs only exist for MLO_AN_PHY and SGMII */ in phylink_mii_ioctl()
2708 mii->phy_id = pl->phydev->mdio.addr; in phylink_mii_ioctl()
2712 ret = phylink_phy_read(pl, mii->phy_id, mii->reg_num); in phylink_mii_ioctl()
2714 mii->val_out = ret; in phylink_mii_ioctl()
2720 ret = phylink_phy_write(pl, mii->phy_id, mii->reg_num, in phylink_mii_ioctl()
2721 mii->val_in); in phylink_mii_ioctl()
2725 ret = phy_mii_ioctl(pl->phydev, ifr, cmd); in phylink_mii_ioctl()
2731 mii->phy_id = 0; in phylink_mii_ioctl()
2735 ret = phylink_mii_read(pl, mii->phy_id, mii->reg_num); in phylink_mii_ioctl()
2737 mii->val_out = ret; in phylink_mii_ioctl()
2743 ret = phylink_mii_write(pl, mii->phy_id, mii->reg_num, in phylink_mii_ioctl()
2744 mii->val_in); in phylink_mii_ioctl()
2748 ret = -EOPNOTSUPP; in phylink_mii_ioctl()
2758 * phylink_speed_down() - set the non-SFP PHY to lowest speed supported by both
2763 * If we have a PHY that is not part of a SFP module, then set the speed
2765 * for a description of the @sync parameter.
2767 * Returns zero if there is no PHY, otherwise as per phy_speed_down().
2775 if (!pl->sfp_bus && pl->phydev) in phylink_speed_down()
2776 ret = phy_speed_down(pl->phydev, sync); in phylink_speed_down()
2783 * phylink_speed_up() - restore the advertised speeds prior to the call to
2787 * If we have a PHY that is not part of a SFP module, then restore the
2788 * PHY speeds as per phy_speed_up().
2790 * Returns zero if there is no PHY, otherwise as per phy_speed_up().
2798 if (!pl->sfp_bus && pl->phydev) in phylink_speed_up()
2799 ret = phy_speed_up(pl->phydev); in phylink_speed_up()
2809 pl->netdev->sfp_bus = bus; in phylink_sfp_attach()
2816 pl->netdev->sfp_bus = NULL; in phylink_sfp_detach()
2839 for (i = 0; i < ARRAY_SIZE(phylink_sfp_interface_preference); i++) in phylink_choose_sfp_interface()
2855 phylink_an_mode_str(mode), phy_modes(state->interface), in phylink_sfp_set_config()
2858 if (!linkmode_equal(pl->supported, supported)) { in phylink_sfp_set_config()
2859 linkmode_copy(pl->supported, supported); in phylink_sfp_set_config()
2863 if (!linkmode_equal(pl->link_config.advertising, state->advertising)) { in phylink_sfp_set_config()
2864 linkmode_copy(pl->link_config.advertising, state->advertising); in phylink_sfp_set_config()
2868 if (pl->cur_link_an_mode != mode || in phylink_sfp_set_config()
2869 pl->link_config.interface != state->interface) { in phylink_sfp_set_config()
2870 pl->cur_link_an_mode = mode; in phylink_sfp_set_config()
2871 pl->link_config.interface = state->interface; in phylink_sfp_set_config()
2877 phy_modes(state->interface)); in phylink_sfp_set_config()
2881 &pl->phylink_disable_state)) in phylink_sfp_set_config()
2886 struct phy_device *phy) in phylink_sfp_config_phy() argument
2894 linkmode_copy(support, phy->supported); in phylink_sfp_config_phy()
2897 linkmode_copy(config.advertising, phy->advertising); in phylink_sfp_config_phy()
2902 config.an_enabled = pl->link_config.an_enabled; in phylink_sfp_config_phy()
2904 /* Ignore errors if we're expecting a PHY to attach later */ in phylink_sfp_config_phy()
2913 iface = sfp_select_interface(pl->sfp_bus, config.advertising); in phylink_sfp_config_phy()
2918 return -EINVAL; in phylink_sfp_config_phy()
2934 pl->link_port = pl->sfp_port; in phylink_sfp_config_phy()
2951 pl->config->supported_interfaces, in phylink_sfp_config_optical()
2953 pl->sfp_interfaces); in phylink_sfp_config_optical()
2958 phy_interface_and(interfaces, pl->config->supported_interfaces, in phylink_sfp_config_optical()
2959 pl->sfp_interfaces); in phylink_sfp_config_optical()
2962 return -EINVAL; in phylink_sfp_config_optical()
2966 linkmode_copy(support, pl->sfp_support); in phylink_sfp_config_optical()
2967 linkmode_copy(config.advertising, pl->sfp_support); in phylink_sfp_config_optical()
2973 /* For all the interfaces that are supported, reduce the sfp_support in phylink_sfp_config_optical()
2976 ret = phylink_validate_mask(pl, pl->sfp_support, &config, interfaces); in phylink_sfp_config_optical()
2986 return -EINVAL; in phylink_sfp_config_optical()
2994 /* Ignore errors if we're expecting a PHY to attach later */ in phylink_sfp_config_optical()
3003 pl->link_port = pl->sfp_port; in phylink_sfp_config_optical()
3005 phylink_sfp_set_config(pl, MLO_AN_INBAND, pl->sfp_support, &config); in phylink_sfp_config_optical()
3017 linkmode_zero(pl->sfp_support); in phylink_sfp_module_insert()
3018 phy_interface_zero(pl->sfp_interfaces); in phylink_sfp_module_insert()
3019 sfp_parse_support(pl->sfp_bus, id, pl->sfp_support, pl->sfp_interfaces); in phylink_sfp_module_insert()
3020 pl->sfp_port = sfp_parse_port(pl->sfp_bus, id, pl->sfp_support); in phylink_sfp_module_insert()
3022 /* If this module may have a PHY connecting later, defer until later */ in phylink_sfp_module_insert()
3023 pl->sfp_may_have_phy = sfp_may_have_phy(pl->sfp_bus, id); in phylink_sfp_module_insert()
3024 if (pl->sfp_may_have_phy) in phylink_sfp_module_insert()
3034 /* If this SFP module has a PHY, start the PHY now. */ in phylink_sfp_module_start()
3035 if (pl->phydev) { in phylink_sfp_module_start()
3036 phy_start(pl->phydev); in phylink_sfp_module_start()
3040 /* If the module may have a PHY but we didn't detect one we in phylink_sfp_module_start()
3041 * need to configure the MAC here. in phylink_sfp_module_start()
3043 if (!pl->sfp_may_have_phy) in phylink_sfp_module_start()
3053 /* If this SFP module has a PHY, stop it. */ in phylink_sfp_module_stop()
3054 if (pl->phydev) in phylink_sfp_module_stop()
3055 phy_stop(pl->phydev); in phylink_sfp_module_stop()
3079 static bool phylink_phy_no_inband(struct phy_device *phy) in phylink_phy_no_inband() argument
3081 return phy->is_c45 && in phylink_phy_no_inband()
3082 (phy->c45_ids.device_ids[1] & 0xfffffff0) == 0xae025150; in phylink_phy_no_inband()
3085 static int phylink_sfp_connect_phy(void *upstream, struct phy_device *phy) in phylink_sfp_connect_phy() argument
3093 * This is the new way of dealing with flow control for PHYs, in phylink_sfp_connect_phy()
3094 * as described by Timur Tabi in commit 529ed1275263 ("net: phy: in phylink_sfp_connect_phy()
3095 * phy drivers should not set SUPPORTED_[Asym_]Pause") except in phylink_sfp_connect_phy()
3099 phy_support_asym_pause(phy); in phylink_sfp_connect_phy()
3101 if (phylink_phy_no_inband(phy)) in phylink_sfp_connect_phy()
3106 /* Set the PHY's host supported interfaces */ in phylink_sfp_connect_phy()
3107 phy_interface_and(phy->host_interfaces, phylink_sfp_interfaces, in phylink_sfp_connect_phy()
3108 pl->config->supported_interfaces); in phylink_sfp_connect_phy()
3111 ret = phylink_sfp_config_phy(pl, mode, phy); in phylink_sfp_connect_phy()
3115 interface = pl->link_config.interface; in phylink_sfp_connect_phy()
3116 ret = phylink_attach_phy(pl, phy, interface); in phylink_sfp_connect_phy()
3120 ret = phylink_bringup_phy(pl, phy, interface); in phylink_sfp_connect_phy()
3122 phy_detach(phy); in phylink_sfp_connect_phy()
3144 /* Helpers for MAC drivers */
3157 mii_lpa_mod_linkmode_x(state->lp_advertising, config_reg, fd_bit); in phylink_decode_c37_word()
3159 if (linkmode_test_bit(fd_bit, state->advertising) && in phylink_decode_c37_word()
3160 linkmode_test_bit(fd_bit, state->lp_advertising)) { in phylink_decode_c37_word()
3161 state->speed = speed; in phylink_decode_c37_word()
3162 state->duplex = DUPLEX_FULL; in phylink_decode_c37_word()
3165 state->link = false; in phylink_decode_c37_word()
3168 linkmode_resolve_pause(state->advertising, state->lp_advertising, in phylink_decode_c37_word()
3172 state->pause |= MLO_PAUSE_TX; in phylink_decode_c37_word()
3174 state->pause |= MLO_PAUSE_RX; in phylink_decode_c37_word()
3181 state->link = false; in phylink_decode_sgmii_word()
3187 state->speed = SPEED_10; in phylink_decode_sgmii_word()
3190 state->speed = SPEED_100; in phylink_decode_sgmii_word()
3193 state->speed = SPEED_1000; in phylink_decode_sgmii_word()
3196 state->link = false; in phylink_decode_sgmii_word()
3200 state->duplex = DUPLEX_FULL; in phylink_decode_sgmii_word()
3202 state->duplex = DUPLEX_HALF; in phylink_decode_sgmii_word()
3206 * phylink_decode_usxgmii_word() - decode the USXGMII word from a MAC PCS
3208 * @lpa: a 16 bit value which stores the USXGMII auto-negotiation word
3210 * Helper for MAC PCS supporting the USXGMII protocol and the auto-negotiation
3219 state->speed = SPEED_10; in phylink_decode_usxgmii_word()
3222 state->speed = SPEED_100; in phylink_decode_usxgmii_word()
3225 state->speed = SPEED_1000; in phylink_decode_usxgmii_word()
3228 state->speed = SPEED_2500; in phylink_decode_usxgmii_word()
3231 state->speed = SPEED_5000; in phylink_decode_usxgmii_word()
3234 state->speed = SPEED_10000; in phylink_decode_usxgmii_word()
3237 state->link = false; in phylink_decode_usxgmii_word()
3242 state->duplex = DUPLEX_FULL; in phylink_decode_usxgmii_word()
3244 state->duplex = DUPLEX_HALF; in phylink_decode_usxgmii_word()
3249 * phylink_mii_c22_pcs_decode_state() - Decode MAC PCS state from MII registers
3254 * Helper for MAC PCS supporting the 802.3 clause 22 register set for
3258 * the phylink @state structure. This is suitable to be used for implementing
3265 state->link = !!(bmsr & BMSR_LSTATUS); in phylink_mii_c22_pcs_decode_state()
3266 state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE); in phylink_mii_c22_pcs_decode_state()
3270 if (!state->link || !state->an_enabled) in phylink_mii_c22_pcs_decode_state()
3273 switch (state->interface) { in phylink_mii_c22_pcs_decode_state()
3289 state->link = false; in phylink_mii_c22_pcs_decode_state()
3296 * phylink_mii_c22_pcs_get_state() - read the MAC PCS state
3300 * Helper for MAC PCS supporting the 802.3 clause 22 register set for
3317 state->link = false; in phylink_mii_c22_pcs_get_state()
3326 * phylink_mii_c22_pcs_encode_advertisement() - configure the clause 37 PCS
3328 * @interface: the PHY interface mode being configured
3331 * Helper for MAC PCS supporting the 802.3 clause 22 register set for
3337 * Return: The new value for @adv, or ``-EINVAL`` if it should not be changed.
3359 /* Nothing to do for other modes */ in phylink_mii_c22_pcs_encode_advertisement()
3360 return -EINVAL; in phylink_mii_c22_pcs_encode_advertisement()
3366 * phylink_mii_c22_pcs_config() - configure clause 22 PCS
3369 * @interface: the PHY interface mode being configured
3372 * Configure a Clause 22 PCS PHY with the appropriate negotiation
3373 * parameters for the @mode, @interface and @advertising parameters.
3387 ret = mdiobus_modify_changed(pcs->bus, pcs->addr, in phylink_mii_c22_pcs_config()
3412 * phylink_mii_c22_pcs_an_restart() - restart 802.3z autonegotiation
3415 * Helper for MAC PCS supporting the 802.3 clause 22 register set for
3437 struct mii_bus *bus = pcs->bus; in phylink_mii_c45_pcs_get_state()
3438 int addr = pcs->addr; in phylink_mii_c45_pcs_get_state()
3443 state->link = false; in phylink_mii_c45_pcs_get_state()
3447 state->link = !!(stat & MDIO_STAT1_LSTATUS); in phylink_mii_c45_pcs_get_state()
3448 if (!state->link) in phylink_mii_c45_pcs_get_state()
3451 switch (state->interface) { in phylink_mii_c45_pcs_get_state()
3453 state->speed = SPEED_10000; in phylink_mii_c45_pcs_get_state()
3454 state->duplex = DUPLEX_FULL; in phylink_mii_c45_pcs_get_state()
3465 for (int i = 0; i < ARRAY_SIZE(phylink_sfp_interface_preference); ++i) in phylink_init()