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.
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
142 phylink_set(tmp, Pause); in phylink_is_empty_linkmode()
160 * phylink_interface_max_speed() - get the maximum speed of a phy interface
229 * phylink_caps_to_linkmodes() - Convert capabilities to ethtool link modes
233 * Set all possible pause, speed and duplex linkmodes in @linkmodes that are
402 * phylink_cap_from_speed_duplex - Get mac capability from speed/duplex
426 * phylink_get_capabilities() - get capabilities for a given MAC
522 /* The MAC must support asymmetric pause towards the local in phylink_get_capabilities()
523 * device for this. We could allow just symmetric pause, but in phylink_get_capabilities()
525 * doesn't support pause. This is because there's no way to in phylink_get_capabilities()
526 * accept pause frames without transmitting them if we only in phylink_get_capabilities()
527 * support symmetric pause. 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
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()
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()
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()
709 if (fwnode_property_read_bool(fixed_node, "pause")) 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()
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()
925 /* If autoneg is disabled, pause AN is also disabled */ in phylink_apply_manual_flow()
926 if (!state->an_enabled) in phylink_apply_manual_flow()
927 state->pause &= ~MLO_PAUSE_AN; in phylink_apply_manual_flow()
929 /* Manual configuration of pause modes */ 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()
966 "%s: mode=%s/%s/%s/%s/%s adv=%*pb pause=%02x link=%u an=%u\n", in phylink_mac_config()
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()
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()
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()
1077 phylink_dbg(pl, "%s: mode=%s/%s adv=%*pb pause=%02x\n", __func__, 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()
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()
1161 link_state.pause = MLO_PAUSE_NONE; in phylink_mac_initial_config()
1174 static const char *phylink_pause_to_str(int pause) in phylink_pause_to_str() argument
1176 switch (pause & MLO_PAUSE_TXRX_MASK) { in phylink_pause_to_str()
1191 struct net_device *ndev = pl->netdev; in phylink_link_up()
1197 rx_pause = !!(link_state.pause & MLO_PAUSE_RX); in phylink_link_up()
1203 * pause frames to the MAC to limit its transmission speed. 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()
1228 !!(link_state.pause & MLO_PAUSE_TX), rx_pause); in phylink_link_up()
1234 "Link is Up - %s/%s - flow control %s\n", in phylink_link_up()
1237 phylink_pause_to_str(link_state.pause)); 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()
1304 if (pl->phydev) in phylink_resolve()
1305 link_state.link &= pl->phy_state.link; 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()
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()
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()
1355 * duplex or pause settings have changed. Call the 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
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
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
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()
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()
1596 * phy drivers should not set SUPPORTED_[Asym_]Pause") except 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()
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()
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()
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()
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()
1668 __ETHTOOL_LINK_MODE_MASK_NBITS, pl->supported, in phylink_bringup_phy()
1669 __ETHTOOL_LINK_MODE_MASK_NBITS, phy->advertising); 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()
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
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()
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
1751 * phylink_fwnode_phy_connect() - connect the PHY specified in the fwnode.
1754 * @flags: PHY-specific flags to communicate to the PHY device driver
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()
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
1822 phy = pl->phydev; 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()
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
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()
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
1969 * - If Wake-on-Lan is active, and being handled only by the PHY, we
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()
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
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
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
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()
2137 * represent the supported speeds/duplex/pause modes. 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
2178 if (pl->phydev) { 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()
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()
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()
2191 * link_config.{speed,duplex,an_enabled,pause} are not used. 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()
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()
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()
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()
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
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
2349 * @pause: a pointer to a &struct ethtool_pauseparam
2352 struct ethtool_pauseparam *pause) in phylink_ethtool_get_pauseparam() argument
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
2365 * @pause: a pointer to a &struct ethtool_pauseparam
2368 struct ethtool_pauseparam *pause) in phylink_ethtool_set_pauseparam() argument
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()
2401 * rx tx Pause AsymDir in phylink_ethtool_set_pauseparam()
2407 * rx/tx pause resolution. 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()
2435 /* If the manual pause settings changed, make sure we trigger a 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
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
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
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
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()
2540 fs.pause = test_bit(ETHTOOL_LINK_MODE_Pause_BIT, lpa); 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
2704 if (pl->phydev) { 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
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
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()
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()
2894 linkmode_copy(support, phy->supported); in phylink_sfp_config_phy()
2897 linkmode_copy(config.advertising, phy->advertising); in phylink_sfp_config_phy()
2901 config.pause = MLO_PAUSE_AN; in phylink_sfp_config_phy()
2902 config.an_enabled = pl->link_config.an_enabled; 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()
2970 config.pause = MLO_PAUSE_AN; 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()
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()
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()
3035 if (pl->phydev) { in phylink_sfp_module_start()
3036 phy_start(pl->phydev); in phylink_sfp_module_start()
3043 if (!pl->sfp_may_have_phy) in phylink_sfp_module_start()
3054 if (pl->phydev) in phylink_sfp_module_stop()
3055 phy_stop(pl->phydev); in phylink_sfp_module_stop()
3081 return phy->is_c45 && in phylink_phy_no_inband()
3082 (phy->c45_ids.device_ids[1] & 0xfffffff0) == 0xae025150; in phylink_phy_no_inband()
3095 * phy drivers should not set SUPPORTED_[Asym_]Pause") except 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()
3115 interface = pl->link_config.interface; in phylink_sfp_connect_phy()
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
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
3317 state->link = false; in phylink_mii_c22_pcs_get_state()
3326 * phylink_mii_c22_pcs_encode_advertisement() - configure the clause 37 PCS
3337 * Return: The new value for @adv, or ``-EINVAL`` if it should not be changed.
3360 return -EINVAL; in phylink_mii_c22_pcs_encode_advertisement()
3366 * phylink_mii_c22_pcs_config() - configure clause 22 PCS
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
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()