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>
44 * struct phylink - internal data type for phylink
60 u8 link_port; /* The current non-phy ethtool port */
93 if ((pl)->config->type == PHYLINK_NETDEV) \
94 netdev_printk(level, (pl)->netdev, fmt, ##__VA_ARGS__); \
95 else if ((pl)->config->type == PHYLINK_DEV) \
96 dev_printk(level, (pl)->dev, fmt, ##__VA_ARGS__); \
108 if ((pl)->config->type == PHYLINK_NETDEV) \
109 netdev_dbg((pl)->netdev, fmt, ##__VA_ARGS__); \
110 else if ((pl)->config->type == PHYLINK_DEV) \
111 dev_dbg((pl)->dev, fmt, ##__VA_ARGS__); \
138 * phylink_set_port_modes() - set the port type modes in the ethtool mask
170 [MLO_AN_PHY] = "phy", in phylink_an_mode_str()
196 * phylink_interface_max_speed() - get the maximum speed of a phy interface
197 * @interface: phy interface mode defined by &typedef phy_interface_t
199 * Determine the maximum speed of a phy interface. This is intended to help
200 * determine the correct speed to pass to the MAC when the phy is performing
267 * phylink_caps_to_linkmodes() - Convert capabilities to ethtool link modes
444 * phylink_limit_mac_speed - limit the phylink_config to a maximum speed
448 * Mask off MAC capabilities for speeds higher than the @max_speed parameter.
455 for (i = 0; i < ARRAY_SIZE(phylink_caps_params) && in phylink_limit_mac_speed()
457 config->mac_capabilities &= ~phylink_caps_params[i].mask; in phylink_limit_mac_speed()
462 * phylink_cap_from_speed_duplex - Get mac capability from speed/duplex
463 * @speed: the speed to search for
464 * @duplex: the duplex to search for
466 * Find the mac capability for a given speed and duplex.
476 for (i = 0; i < ARRAY_SIZE(phylink_caps_params); i++) { in phylink_cap_from_speed_duplex()
486 * phylink_get_capabilities() - get capabilities for a given MAC
487 * @interface: phy interface mode defined by &typedef phy_interface_t
588 * device for this. We could allow just symmetric pause, but in phylink_get_capabilities()
603 /* Although a duplex-matching phy might exist, we in phylink_get_capabilities()
605 * will not be aware of the half-duplex nature of the in phylink_get_capabilities()
629 * phylink_validate_mask_caps() - Restrict link modes based on caps
630 * @supported: ethtool bitmask for supported link modes.
647 caps = phylink_get_capabilities(state->interface, mac_capabilities, in phylink_validate_mask_caps()
648 state->rate_matching); in phylink_validate_mask_caps()
652 linkmode_and(state->advertising, state->advertising, mask); in phylink_validate_mask_caps()
663 /* Get the PCS for this interface mode */ in phylink_validate_mac_and_pcs()
664 if (pl->using_mac_select_pcs) { in phylink_validate_mac_and_pcs()
665 pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface); in phylink_validate_mac_and_pcs()
669 pcs = pl->pcs; in phylink_validate_mac_and_pcs()
677 if (!pcs->ops) { in phylink_validate_mac_and_pcs()
679 phy_modes(state->interface)); in phylink_validate_mac_and_pcs()
681 return -EINVAL; in phylink_validate_mac_and_pcs()
685 if (pcs->ops->pcs_validate) { in phylink_validate_mac_and_pcs()
686 ret = pcs->ops->pcs_validate(pcs, supported, state); in phylink_validate_mac_and_pcs()
688 return -EINVAL; in phylink_validate_mac_and_pcs()
693 linkmode_and(state->advertising, state->advertising, in phylink_validate_mac_and_pcs()
699 if (pl->mac_ops->mac_get_caps) in phylink_validate_mac_and_pcs()
700 capabilities = pl->mac_ops->mac_get_caps(pl->config, in phylink_validate_mac_and_pcs()
701 state->interface); in phylink_validate_mac_and_pcs()
703 capabilities = pl->config->mac_capabilities; in phylink_validate_mac_and_pcs()
707 return phylink_is_empty_linkmode(supported) ? -EINVAL : 0; in phylink_validate_mac_and_pcs()
710 static void phylink_validate_one(struct phylink *pl, struct phy_device *phy, in phylink_validate_one() argument
725 if (phy) in phylink_validate_one()
726 tmp_state.rate_matching = phy_get_rate_matching(phy, interface); in phylink_validate_one()
740 static int phylink_validate_mask(struct phylink *pl, struct phy_device *phy, in phylink_validate_mask() argument
750 phylink_validate_one(pl, phy, supported, state, interface, in phylink_validate_mask()
754 linkmode_copy(state->advertising, all_adv); in phylink_validate_mask()
756 return phylink_is_empty_linkmode(supported) ? -EINVAL : 0; in phylink_validate_mask()
762 const unsigned long *interfaces = pl->config->supported_interfaces; in phylink_validate()
764 if (state->interface == PHY_INTERFACE_MODE_NA) in phylink_validate()
768 if (!test_bit(state->interface, interfaces)) in phylink_validate()
769 return -EINVAL; in phylink_validate()
784 fixed_node = fwnode_get_named_child_node(fwnode, "fixed-link"); in phylink_parse_fixedlink()
788 pl->link_config.speed = speed; in phylink_parse_fixedlink()
789 pl->link_config.duplex = DUPLEX_HALF; in phylink_parse_fixedlink()
791 if (fwnode_property_read_bool(fixed_node, "full-duplex")) in phylink_parse_fixedlink()
792 pl->link_config.duplex = DUPLEX_FULL; in phylink_parse_fixedlink()
794 /* We treat the "pause" and "asym-pause" terminology as in phylink_parse_fixedlink()
799 pl->link_config.lp_advertising); in phylink_parse_fixedlink()
800 if (fwnode_property_read_bool(fixed_node, "asym-pause")) in phylink_parse_fixedlink()
802 pl->link_config.lp_advertising); in phylink_parse_fixedlink()
809 pl->link_gpio = desc; in phylink_parse_fixedlink()
810 else if (desc == ERR_PTR(-EPROBE_DEFER)) in phylink_parse_fixedlink()
811 ret = -EPROBE_DEFER; in phylink_parse_fixedlink()
820 ret = fwnode_property_read_u32_array(fwnode, "fixed-link", in phylink_parse_fixedlink()
823 phylink_err(pl, "broken fixed-link?\n"); in phylink_parse_fixedlink()
824 return -EINVAL; in phylink_parse_fixedlink()
827 ret = fwnode_property_read_u32_array(fwnode, "fixed-link", in phylink_parse_fixedlink()
830 pl->link_config.duplex = prop[1] ? in phylink_parse_fixedlink()
832 pl->link_config.speed = prop[2]; in phylink_parse_fixedlink()
835 pl->link_config.lp_advertising); in phylink_parse_fixedlink()
838 pl->link_config.lp_advertising); in phylink_parse_fixedlink()
842 if (pl->link_config.speed > SPEED_1000 && in phylink_parse_fixedlink()
843 pl->link_config.duplex != DUPLEX_FULL) in phylink_parse_fixedlink()
844 phylink_warn(pl, "fixed link specifies half duplex for %dMbps link?\n", in phylink_parse_fixedlink()
845 pl->link_config.speed); in phylink_parse_fixedlink()
847 linkmode_fill(pl->supported); in phylink_parse_fixedlink()
848 linkmode_copy(pl->link_config.advertising, pl->supported); in phylink_parse_fixedlink()
849 phylink_validate(pl, pl->supported, &pl->link_config); in phylink_parse_fixedlink()
851 pause = phylink_test(pl->supported, Pause); in phylink_parse_fixedlink()
852 asym_pause = phylink_test(pl->supported, Asym_Pause); in phylink_parse_fixedlink()
853 autoneg = phylink_test(pl->supported, Autoneg); in phylink_parse_fixedlink()
854 s = phy_lookup_setting(pl->link_config.speed, pl->link_config.duplex, in phylink_parse_fixedlink()
855 pl->supported, true); in phylink_parse_fixedlink()
856 linkmode_zero(pl->supported); in phylink_parse_fixedlink()
857 phylink_set(pl->supported, MII); in phylink_parse_fixedlink()
860 phylink_set(pl->supported, Pause); in phylink_parse_fixedlink()
863 phylink_set(pl->supported, Asym_Pause); in phylink_parse_fixedlink()
866 phylink_set(pl->supported, Autoneg); in phylink_parse_fixedlink()
869 __set_bit(s->bit, pl->supported); in phylink_parse_fixedlink()
870 __set_bit(s->bit, pl->link_config.lp_advertising); in phylink_parse_fixedlink()
873 pl->link_config.duplex == DUPLEX_FULL ? "full" : "half", in phylink_parse_fixedlink()
874 pl->link_config.speed); in phylink_parse_fixedlink()
877 linkmode_and(pl->link_config.advertising, pl->link_config.advertising, in phylink_parse_fixedlink()
878 pl->supported); in phylink_parse_fixedlink()
880 pl->link_config.link = 1; in phylink_parse_fixedlink()
881 pl->link_config.an_complete = 1; in phylink_parse_fixedlink()
893 if (pl->config->default_an_inband) in phylink_parse_mode()
894 pl->cfg_link_an_mode = MLO_AN_INBAND; in phylink_parse_mode()
896 dn = fwnode_get_named_child_node(fwnode, "fixed-link"); in phylink_parse_mode()
897 if (dn || fwnode_property_present(fwnode, "fixed-link")) in phylink_parse_mode()
898 pl->cfg_link_an_mode = MLO_AN_FIXED; in phylink_parse_mode()
902 strcmp(managed, "in-band-status") == 0)) { in phylink_parse_mode()
903 if (pl->cfg_link_an_mode == MLO_AN_FIXED) { in phylink_parse_mode()
905 "can't use both fixed-link and in-band-status\n"); in phylink_parse_mode()
906 return -EINVAL; in phylink_parse_mode()
909 pl->cfg_link_an_mode = MLO_AN_INBAND; in phylink_parse_mode()
912 if (pl->cfg_link_an_mode == MLO_AN_INBAND) { in phylink_parse_mode()
913 linkmode_zero(pl->supported); in phylink_parse_mode()
914 phylink_set(pl->supported, MII); in phylink_parse_mode()
915 phylink_set(pl->supported, Autoneg); in phylink_parse_mode()
916 phylink_set(pl->supported, Asym_Pause); in phylink_parse_mode()
917 phylink_set(pl->supported, Pause); in phylink_parse_mode()
919 switch (pl->link_config.interface) { in phylink_parse_mode()
939 caps = phylink_get_capabilities(pl->link_config.interface, caps, in phylink_parse_mode()
941 phylink_caps_to_linkmodes(pl->supported, caps); in phylink_parse_mode()
946 "incorrect link mode %s for in-band status\n", in phylink_parse_mode()
947 phy_modes(pl->link_config.interface)); in phylink_parse_mode()
948 return -EINVAL; in phylink_parse_mode()
951 linkmode_copy(pl->link_config.advertising, pl->supported); in phylink_parse_mode()
953 if (phylink_validate(pl, pl->supported, &pl->link_config)) { in phylink_parse_mode()
955 "failed to validate link configuration for in-band status\n"); in phylink_parse_mode()
956 return -EINVAL; in phylink_parse_mode()
968 state->advertising)) in phylink_apply_manual_flow()
969 state->pause &= ~MLO_PAUSE_AN; in phylink_apply_manual_flow()
972 if (!(pl->link_config.pause & MLO_PAUSE_AN)) in phylink_apply_manual_flow()
973 state->pause = pl->link_config.pause; in phylink_apply_manual_flow()
980 if (state->duplex == DUPLEX_FULL) { in phylink_resolve_an_pause()
981 linkmode_resolve_pause(state->advertising, in phylink_resolve_an_pause()
982 state->lp_advertising, in phylink_resolve_an_pause()
985 state->pause |= MLO_PAUSE_TX; in phylink_resolve_an_pause()
987 state->pause |= MLO_PAUSE_RX; in phylink_resolve_an_pause()
994 if (pcs && pcs->ops->pcs_pre_config) in phylink_pcs_pre_config()
995 pcs->ops->pcs_pre_config(pcs, interface); in phylink_pcs_pre_config()
1003 if (pcs && pcs->ops->pcs_post_config) in phylink_pcs_post_config()
1004 err = pcs->ops->pcs_post_config(pcs, interface); in phylink_pcs_post_config()
1011 if (pcs && pcs->ops->pcs_disable) in phylink_pcs_disable()
1012 pcs->ops->pcs_disable(pcs); in phylink_pcs_disable()
1019 if (pcs && pcs->ops->pcs_enable) in phylink_pcs_enable()
1020 err = pcs->ops->pcs_enable(pcs); in phylink_pcs_enable()
1032 return pcs->ops->pcs_config(pcs, neg_mode, state->interface, in phylink_pcs_config()
1033 state->advertising, permit_pause_to_mac); in phylink_pcs_config()
1040 if (pcs && pcs->ops->pcs_link_up) in phylink_pcs_link_up()
1041 pcs->ops->pcs_link_up(pcs, neg_mode, interface, speed, duplex); in phylink_pcs_link_up()
1046 if (pl->cfg_link_an_mode == MLO_AN_INBAND) in phylink_pcs_poll_stop()
1047 del_timer(&pl->link_poll); in phylink_pcs_poll_stop()
1052 if (pl->pcs && pl->pcs->poll && pl->cfg_link_an_mode == MLO_AN_INBAND) in phylink_pcs_poll_start()
1053 mod_timer(&pl->link_poll, jiffies + HZ); in phylink_pcs_poll_start()
1060 /* Signal to PCS driver that MAC requires RX clock for init */ in phylink_pcs_pre_init()
1061 if (pl->config->mac_requires_rxc) in phylink_pcs_pre_init()
1062 pcs->rxc_always_on = true; in phylink_pcs_pre_init()
1064 if (pcs->ops->pcs_pre_init) in phylink_pcs_pre_init()
1065 ret = pcs->ops->pcs_pre_init(pcs); in phylink_pcs_pre_init()
1085 __func__, phylink_an_mode_str(pl->cur_link_an_mode), in phylink_mac_config()
1091 pl->mac_ops->mac_config(pl->config, pl->cur_link_an_mode, &st); in phylink_mac_config()
1096 if (pl->pcs && linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, in phylink_pcs_an_restart()
1097 pl->link_config.advertising) && in phylink_pcs_an_restart()
1098 phy_interface_mode_is_8023z(pl->link_config.interface) && in phylink_pcs_an_restart()
1099 phylink_autoneg_inband(pl->cur_link_an_mode)) in phylink_pcs_an_restart()
1100 pl->pcs->ops->pcs_an_restart(pl->pcs); in phylink_pcs_an_restart()
1104 * phylink_pcs_neg_mode() - helper to determine PCS inband mode
1112 * - %PHYLINK_PCS_NEG_NONE: interface mode does not support inband
1113 * - %PHYLINK_PCS_NEG_OUTBAND: an out of band mode (e.g. reading the PHY)
1115 * - %PHYLINK_PCS_NEG_INBAND_DISABLED: inband mode selected but autoneg
1117 * - %PHYLINK_PCS_NEG_INBAND_ENABLED: inband mode selected and autoneg enabled
1119 * Note: this is for cases where the PCS itself is involved in negotiation
1134 /* These protocols are designed for use with a PHY which in phylink_pcs_neg_mode()
1147 /* 1000base-X is designed for use media-side for Fibre in phylink_pcs_neg_mode()
1149 * taken into account. We also do this for 2500base-X in phylink_pcs_neg_mode()
1151 * need to override this. in phylink_pcs_neg_mode()
1179 phylink_dbg(pl, "major config %s\n", phy_modes(state->interface)); in phylink_major_config()
1181 pl->pcs_neg_mode = phylink_pcs_neg_mode(pl->cur_link_an_mode, in phylink_major_config()
1182 state->interface, in phylink_major_config()
1183 state->advertising); in phylink_major_config()
1185 if (pl->using_mac_select_pcs) { in phylink_major_config()
1186 pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface); in phylink_major_config()
1194 pcs_changed = pcs && pl->pcs != pcs; in phylink_major_config()
1199 if (pl->mac_ops->mac_prepare) { in phylink_major_config()
1200 err = pl->mac_ops->mac_prepare(pl->config, pl->cur_link_an_mode, in phylink_major_config()
1201 state->interface); in phylink_major_config()
1210 * for the change. in phylink_major_config()
1213 phylink_pcs_disable(pl->pcs); in phylink_major_config()
1215 if (pl->pcs) in phylink_major_config()
1216 pl->pcs->phylink = NULL; in phylink_major_config()
1218 pcs->phylink = pl; in phylink_major_config()
1220 pl->pcs = pcs; in phylink_major_config()
1223 if (pl->pcs) in phylink_major_config()
1224 phylink_pcs_pre_config(pl->pcs, state->interface); in phylink_major_config()
1228 if (pl->pcs) in phylink_major_config()
1229 phylink_pcs_post_config(pl->pcs, state->interface); in phylink_major_config()
1231 if (pl->pcs_state == PCS_STATE_STARTING || pcs_changed) in phylink_major_config()
1232 phylink_pcs_enable(pl->pcs); in phylink_major_config()
1234 neg_mode = pl->cur_link_an_mode; in phylink_major_config()
1235 if (pl->pcs && pl->pcs->neg_mode) in phylink_major_config()
1236 neg_mode = pl->pcs_neg_mode; in phylink_major_config()
1238 err = phylink_pcs_config(pl->pcs, neg_mode, state, in phylink_major_config()
1239 !!(pl->link_config.pause & MLO_PAUSE_AN)); in phylink_major_config()
1249 if (pl->mac_ops->mac_finish) { in phylink_major_config()
1250 err = pl->mac_ops->mac_finish(pl->config, pl->cur_link_an_mode, in phylink_major_config()
1251 state->interface); in phylink_major_config()
1257 if (pl->sfp_bus) { in phylink_major_config()
1258 rate_kbd = phylink_interface_signal_rate(state->interface); in phylink_major_config()
1260 sfp_upstream_set_signal_rate(pl->sfp_bus, rate_kbd); in phylink_major_config()
1267 * Reconfigure for a change of inband advertisement.
1268 * If we have a separate PCS, we only need to call its pcs_config() method,
1277 if (test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) in phylink_change_inband_advert()
1281 phylink_an_mode_str(pl->cur_link_an_mode), in phylink_change_inband_advert()
1282 phy_modes(pl->link_config.interface), in phylink_change_inband_advert()
1283 __ETHTOOL_LINK_MODE_MASK_NBITS, pl->link_config.advertising, in phylink_change_inband_advert()
1284 pl->link_config.pause); in phylink_change_inband_advert()
1287 pl->pcs_neg_mode = phylink_pcs_neg_mode(pl->cur_link_an_mode, in phylink_change_inband_advert()
1288 pl->link_config.interface, in phylink_change_inband_advert()
1289 pl->link_config.advertising); in phylink_change_inband_advert()
1291 neg_mode = pl->cur_link_an_mode; in phylink_change_inband_advert()
1292 if (pl->pcs->neg_mode) in phylink_change_inband_advert()
1293 neg_mode = pl->pcs_neg_mode; in phylink_change_inband_advert()
1295 /* Modern PCS-based method; update the advert at the PCS, and in phylink_change_inband_advert()
1299 ret = phylink_pcs_config(pl->pcs, neg_mode, &pl->link_config, in phylink_change_inband_advert()
1300 !!(pl->link_config.pause & MLO_PAUSE_AN)); in phylink_change_inband_advert()
1313 linkmode_copy(state->advertising, pl->link_config.advertising); in phylink_mac_pcs_get_state()
1314 linkmode_zero(state->lp_advertising); in phylink_mac_pcs_get_state()
1315 state->interface = pl->link_config.interface; in phylink_mac_pcs_get_state()
1316 state->rate_matching = pl->link_config.rate_matching; in phylink_mac_pcs_get_state()
1318 state->advertising)) { in phylink_mac_pcs_get_state()
1319 state->speed = SPEED_UNKNOWN; in phylink_mac_pcs_get_state()
1320 state->duplex = DUPLEX_UNKNOWN; in phylink_mac_pcs_get_state()
1321 state->pause = MLO_PAUSE_NONE; in phylink_mac_pcs_get_state()
1323 state->speed = pl->link_config.speed; in phylink_mac_pcs_get_state()
1324 state->duplex = pl->link_config.duplex; in phylink_mac_pcs_get_state()
1325 state->pause = pl->link_config.pause; in phylink_mac_pcs_get_state()
1327 state->an_complete = 0; in phylink_mac_pcs_get_state()
1328 state->link = 1; in phylink_mac_pcs_get_state()
1330 if (pl->pcs) in phylink_mac_pcs_get_state()
1331 pl->pcs->ops->pcs_get_state(pl->pcs, state); in phylink_mac_pcs_get_state()
1333 state->link = 0; in phylink_mac_pcs_get_state()
1336 /* The fixed state is... fixed except for the link state,
1342 *state = pl->link_config; in phylink_get_fixed_state()
1343 if (pl->config->get_fixed_state) in phylink_get_fixed_state()
1344 pl->config->get_fixed_state(pl->config, state); in phylink_get_fixed_state()
1345 else if (pl->link_gpio) in phylink_get_fixed_state()
1346 state->link = !!gpiod_get_value_cansleep(pl->link_gpio); in phylink_get_fixed_state()
1348 state->pause = MLO_PAUSE_NONE; in phylink_get_fixed_state()
1356 switch (pl->cur_link_an_mode) { in phylink_mac_initial_config()
1358 link_state = pl->phy_state; in phylink_mac_initial_config()
1366 link_state = pl->link_config; in phylink_mac_initial_config()
1398 struct net_device *ndev = pl->netdev; in phylink_link_up()
1409 /* The PHY is doing rate matchion from the media rate (in in phylink_link_up()
1419 /* The PHY is doing rate matchion from the media rate (in in phylink_link_up()
1428 pl->cur_interface = link_state.interface; in phylink_link_up()
1430 neg_mode = pl->cur_link_an_mode; in phylink_link_up()
1431 if (pl->pcs && pl->pcs->neg_mode) in phylink_link_up()
1432 neg_mode = pl->pcs_neg_mode; in phylink_link_up()
1434 phylink_pcs_link_up(pl->pcs, neg_mode, pl->cur_interface, speed, in phylink_link_up()
1437 pl->mac_ops->mac_link_up(pl->config, pl->phydev, pl->cur_link_an_mode, in phylink_link_up()
1438 pl->cur_interface, speed, duplex, in phylink_link_up()
1445 "Link is Up - %s/%s - flow control %s\n", in phylink_link_up()
1453 struct net_device *ndev = pl->netdev; in phylink_link_down()
1457 pl->mac_ops->mac_link_down(pl->config, pl->cur_link_an_mode, in phylink_link_down()
1458 pl->cur_interface); in phylink_link_down()
1466 struct net_device *ndev = pl->netdev; in phylink_resolve()
1471 mutex_lock(&pl->state_mutex); in phylink_resolve()
1472 if (pl->netdev) in phylink_resolve()
1475 cur_link_state = pl->old_link_state; in phylink_resolve()
1477 if (pl->phylink_disable_state) { in phylink_resolve()
1478 pl->link_failed = false; in phylink_resolve()
1480 } else if (pl->link_failed) { in phylink_resolve()
1484 switch (pl->cur_link_an_mode) { in phylink_resolve()
1486 link_state = pl->phy_state; in phylink_resolve()
1499 /* The PCS may have a latching link-fail indicator. in phylink_resolve()
1501 * re-trigger the resolve. Otherwise, re-read the in phylink_resolve()
1512 /* If we have a phy, the "up" state is the union of in phylink_resolve()
1513 * both the PHY and the MAC in phylink_resolve()
1515 if (pl->phydev) in phylink_resolve()
1516 link_state.link &= pl->phy_state.link; in phylink_resolve()
1518 /* Only update if the PHY link is up */ in phylink_resolve()
1519 if (pl->phydev && pl->phy_state.link) { in phylink_resolve()
1522 * down, and re-resolve. in phylink_resolve()
1525 pl->phy_state.interface) { in phylink_resolve()
1529 link_state.interface = pl->phy_state.interface; in phylink_resolve()
1532 * link speed/duplex comes from the PHY in phylink_resolve()
1534 if (pl->phy_state.rate_matching) { in phylink_resolve()
1536 pl->phy_state.rate_matching; in phylink_resolve()
1537 link_state.speed = pl->phy_state.speed; in phylink_resolve()
1539 pl->phy_state.duplex; in phylink_resolve()
1542 /* If we have a PHY, we need to update with in phylink_resolve()
1543 * the PHY flow control bits. in phylink_resolve()
1545 link_state.pause = pl->phy_state.pause; in phylink_resolve()
1554 if (link_state.interface != pl->link_config.interface) { in phylink_resolve()
1563 pl->link_config.interface = link_state.interface; in phylink_resolve()
1568 pl->old_link_state = link_state.link; in phylink_resolve()
1575 pl->link_failed = false; in phylink_resolve()
1576 queue_work(system_power_efficient_wq, &pl->resolve); in phylink_resolve()
1578 mutex_unlock(&pl->state_mutex); in phylink_resolve()
1583 if (!pl->phylink_disable_state) in phylink_run_resolve()
1584 queue_work(system_power_efficient_wq, &pl->resolve); in phylink_run_resolve()
1589 unsigned long state = pl->phylink_disable_state; in phylink_run_resolve_and_disable()
1591 set_bit(bit, &pl->phylink_disable_state); in phylink_run_resolve_and_disable()
1593 queue_work(system_power_efficient_wq, &pl->resolve); in phylink_run_resolve_and_disable()
1594 flush_work(&pl->resolve); in phylink_run_resolve_and_disable()
1600 clear_bit(bit, &pl->phylink_disable_state); in phylink_enable_and_run_resolve()
1630 pl->sfp_bus = bus; in phylink_register_sfp()
1639 * phylink_set_fixed_link() - set the fixed link
1644 * making it suitable for certain types of network connections.
1654 if (pl->cfg_link_an_mode != MLO_AN_PHY || !state || in phylink_set_fixed_link()
1655 !test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) in phylink_set_fixed_link()
1656 return -EINVAL; in phylink_set_fixed_link()
1658 s = phy_lookup_setting(state->speed, state->duplex, in phylink_set_fixed_link()
1659 pl->supported, true); in phylink_set_fixed_link()
1661 return -EINVAL; in phylink_set_fixed_link()
1663 adv = pl->link_config.advertising; in phylink_set_fixed_link()
1665 linkmode_set_bit(s->bit, adv); in phylink_set_fixed_link()
1668 pl->link_config.speed = state->speed; in phylink_set_fixed_link()
1669 pl->link_config.duplex = state->duplex; in phylink_set_fixed_link()
1670 pl->link_config.link = 1; in phylink_set_fixed_link()
1671 pl->link_config.an_complete = 1; in phylink_set_fixed_link()
1673 pl->cfg_link_an_mode = MLO_AN_FIXED; in phylink_set_fixed_link()
1674 pl->cur_link_an_mode = pl->cfg_link_an_mode; in phylink_set_fixed_link()
1681 * phylink_create() - create a phylink instance
1686 * @mac_ops: a pointer to a &struct phylink_mac_ops for the MAC.
1689 * This will parse in-band modes, fixed-link or SFP configuration.
1693 * Returns a pointer to a &struct phylink, or an error-pointer value. Users
1694 * must use IS_ERR() to check for errors from this function.
1706 if (phy_interface_empty(config->supported_interfaces)) { in phylink_create()
1707 dev_err(config->dev, in phylink_create()
1709 return ERR_PTR(-EINVAL); in phylink_create()
1712 if (mac_ops->mac_select_pcs && in phylink_create()
1713 mac_ops->mac_select_pcs(config, PHY_INTERFACE_MODE_NA) != in phylink_create()
1714 ERR_PTR(-EOPNOTSUPP)) in phylink_create()
1719 return ERR_PTR(-ENOMEM); in phylink_create()
1721 mutex_init(&pl->state_mutex); in phylink_create()
1722 INIT_WORK(&pl->resolve, phylink_resolve); in phylink_create()
1724 pl->config = config; in phylink_create()
1725 if (config->type == PHYLINK_NETDEV) { in phylink_create()
1726 pl->netdev = to_net_dev(config->dev); in phylink_create()
1727 netif_carrier_off(pl->netdev); in phylink_create()
1728 } else if (config->type == PHYLINK_DEV) { in phylink_create()
1729 pl->dev = config->dev; in phylink_create()
1732 return ERR_PTR(-EINVAL); in phylink_create()
1735 pl->using_mac_select_pcs = using_mac_select_pcs; in phylink_create()
1736 pl->phy_state.interface = iface; in phylink_create()
1737 pl->link_interface = iface; in phylink_create()
1739 pl->link_port = PORT_BNC; in phylink_create()
1741 pl->link_port = PORT_MII; in phylink_create()
1742 pl->link_config.interface = iface; in phylink_create()
1743 pl->link_config.pause = MLO_PAUSE_AN; in phylink_create()
1744 pl->link_config.speed = SPEED_UNKNOWN; in phylink_create()
1745 pl->link_config.duplex = DUPLEX_UNKNOWN; in phylink_create()
1746 pl->pcs_state = PCS_STATE_DOWN; in phylink_create()
1747 pl->mac_ops = mac_ops; in phylink_create()
1748 __set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); in phylink_create()
1749 timer_setup(&pl->link_poll, phylink_fixed_poll, 0); in phylink_create()
1751 linkmode_fill(pl->supported); in phylink_create()
1752 linkmode_copy(pl->link_config.advertising, pl->supported); in phylink_create()
1753 phylink_validate(pl, pl->supported, &pl->link_config); in phylink_create()
1761 if (pl->cfg_link_an_mode == MLO_AN_FIXED) { in phylink_create()
1769 pl->cur_link_an_mode = pl->cfg_link_an_mode; in phylink_create()
1782 * phylink_destroy() - cleanup and destroy the phylink instance
1785 * Destroy a phylink instance. Any PHY that has been attached must have been
1792 sfp_bus_del_upstream(pl->sfp_bus); in phylink_destroy()
1793 if (pl->link_gpio) in phylink_destroy()
1794 gpiod_put(pl->link_gpio); in phylink_destroy()
1796 cancel_work_sync(&pl->resolve); in phylink_destroy()
1802 * phylink_expects_phy() - Determine if phylink expects a phy to be attached
1805 * When using fixed-link mode, or in-band mode with 1000base-X or 2500base-X,
1806 * no PHY is needed.
1808 * Returns true if phylink will be expecting a PHY.
1812 if (pl->cfg_link_an_mode == MLO_AN_FIXED || in phylink_expects_phy()
1813 (pl->cfg_link_an_mode == MLO_AN_INBAND && in phylink_expects_phy()
1814 phy_interface_mode_is_8023z(pl->link_config.interface))) in phylink_expects_phy()
1822 struct phylink *pl = phydev->phylink; in phylink_phy_change()
1827 mutex_lock(&pl->state_mutex); in phylink_phy_change()
1828 pl->phy_state.speed = phydev->speed; in phylink_phy_change()
1829 pl->phy_state.duplex = phydev->duplex; in phylink_phy_change()
1830 pl->phy_state.rate_matching = phydev->rate_matching; in phylink_phy_change()
1831 pl->phy_state.pause = MLO_PAUSE_NONE; in phylink_phy_change()
1833 pl->phy_state.pause |= MLO_PAUSE_TX; in phylink_phy_change()
1835 pl->phy_state.pause |= MLO_PAUSE_RX; in phylink_phy_change()
1836 pl->phy_state.interface = phydev->interface; in phylink_phy_change()
1837 pl->phy_state.link = up; in phylink_phy_change()
1839 pl->link_failed = true; in phylink_phy_change()
1840 mutex_unlock(&pl->state_mutex); in phylink_phy_change()
1844 phylink_dbg(pl, "phy link %s %s/%s/%s/%s/%s\n", up ? "up" : "down", in phylink_phy_change()
1845 phy_modes(phydev->interface), in phylink_phy_change()
1846 phy_speed_to_str(phydev->speed), in phylink_phy_change()
1847 phy_duplex_to_str(phydev->duplex), in phylink_phy_change()
1848 phy_rate_matching_to_str(phydev->rate_matching), in phylink_phy_change()
1849 phylink_pause_to_str(pl->phy_state.pause)); in phylink_phy_change()
1852 static int phylink_validate_phy(struct phylink *pl, struct phy_device *phy, in phylink_validate_phy() argument
1858 /* If the PHY provides a bitmap of the interfaces it will be using in phylink_validate_phy()
1862 if (!phy_interface_empty(phy->possible_interfaces)) { in phylink_validate_phy()
1863 /* We only care about the union of the PHY's interfaces and in phylink_validate_phy()
1866 phy_interface_and(interfaces, phy->possible_interfaces, in phylink_validate_phy()
1867 pl->config->supported_interfaces); in phylink_validate_phy()
1870 phylink_err(pl, "PHY has no common interfaces\n"); in phylink_validate_phy()
1871 return -EINVAL; in phylink_validate_phy()
1874 if (phy_on_sfp(phy)) { in phylink_validate_phy()
1875 /* If the PHY is on a SFP, limit the interfaces to in phylink_validate_phy()
1882 phylink_err(pl, "SFP PHY's possible interfaces becomes empty\n"); in phylink_validate_phy()
1883 return -EINVAL; in phylink_validate_phy()
1887 phylink_dbg(pl, "PHY %s uses interfaces %*pbl, validating %*pbl\n", in phylink_validate_phy()
1888 phydev_name(phy), in phylink_validate_phy()
1890 phy->possible_interfaces, in phylink_validate_phy()
1893 return phylink_validate_mask(pl, phy, supported, state, in phylink_validate_phy()
1897 phylink_dbg(pl, "PHY %s doesn't supply possible interfaces\n", in phylink_validate_phy()
1898 phydev_name(phy)); in phylink_validate_phy()
1900 /* Check whether we would use rate matching for the proposed interface in phylink_validate_phy()
1903 state->rate_matching = phy_get_rate_matching(phy, state->interface); in phylink_validate_phy()
1905 /* Clause 45 PHYs may switch their Serdes lane between, e.g. 10GBASE-R, in phylink_validate_phy()
1906 * 5GBASE-R, 2500BASE-X and SGMII if they are not using rate matching. in phylink_validate_phy()
1907 * For some interface modes (e.g. RXAUI, XAUI and USXGMII) switching in phylink_validate_phy()
1910 * For these which switch interface modes, we really need to know which in phylink_validate_phy()
1911 * interface modes the PHY supports to properly work out which ethtool in phylink_validate_phy()
1912 * linkmodes can be supported. For now, as a work-around, we validate in phylink_validate_phy()
1916 if (phy->is_c45 && state->rate_matching == RATE_MATCH_NONE && in phylink_validate_phy()
1917 state->interface != PHY_INTERFACE_MODE_RXAUI && in phylink_validate_phy()
1918 state->interface != PHY_INTERFACE_MODE_XAUI && in phylink_validate_phy()
1919 state->interface != PHY_INTERFACE_MODE_USXGMII) in phylink_validate_phy()
1920 state->interface = PHY_INTERFACE_MODE_NA; in phylink_validate_phy()
1925 static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy, in phylink_bringup_phy() argument
1934 * This is the new way of dealing with flow control for PHYs, in phylink_bringup_phy()
1935 * as described by Timur Tabi in commit 529ed1275263 ("net: phy: in phylink_bringup_phy()
1936 * phy drivers should not set SUPPORTED_[Asym_]Pause") except in phylink_bringup_phy()
1940 phy_support_asym_pause(phy); in phylink_bringup_phy()
1943 linkmode_copy(supported, phy->supported); in phylink_bringup_phy()
1944 linkmode_copy(config.advertising, phy->advertising); in phylink_bringup_phy()
1947 ret = phylink_validate_phy(pl, phy, supported, &config); in phylink_bringup_phy()
1951 __ETHTOOL_LINK_MODE_MASK_NBITS, phy->supported, in phylink_bringup_phy()
1957 phy->phylink = pl; in phylink_bringup_phy()
1958 phy->phy_link_change = phylink_phy_change; in phylink_bringup_phy()
1960 irq_str = phy_attached_info_irq(phy); in phylink_bringup_phy()
1962 "PHY [%s] driver [%s] (irq=%s)\n", in phylink_bringup_phy()
1963 dev_name(&phy->mdio.dev), phy->drv->name, irq_str); in phylink_bringup_phy()
1966 mutex_lock(&phy->lock); in phylink_bringup_phy()
1967 mutex_lock(&pl->state_mutex); in phylink_bringup_phy()
1968 pl->phydev = phy; in phylink_bringup_phy()
1969 pl->phy_state.interface = interface; in phylink_bringup_phy()
1970 pl->phy_state.pause = MLO_PAUSE_NONE; in phylink_bringup_phy()
1971 pl->phy_state.speed = SPEED_UNKNOWN; in phylink_bringup_phy()
1972 pl->phy_state.duplex = DUPLEX_UNKNOWN; in phylink_bringup_phy()
1973 pl->phy_state.rate_matching = RATE_MATCH_NONE; in phylink_bringup_phy()
1974 linkmode_copy(pl->supported, supported); in phylink_bringup_phy()
1975 linkmode_copy(pl->link_config.advertising, config.advertising); in phylink_bringup_phy()
1977 /* Restrict the phy advertisement according to the MAC support. */ in phylink_bringup_phy()
1978 linkmode_copy(phy->advertising, config.advertising); in phylink_bringup_phy()
1979 mutex_unlock(&pl->state_mutex); in phylink_bringup_phy()
1980 mutex_unlock(&phy->lock); in phylink_bringup_phy()
1983 "phy: %s setting supported %*pb advertising %*pb\n", in phylink_bringup_phy()
1985 __ETHTOOL_LINK_MODE_MASK_NBITS, pl->supported, in phylink_bringup_phy()
1986 __ETHTOOL_LINK_MODE_MASK_NBITS, phy->advertising); in phylink_bringup_phy()
1988 if (phy_interrupt_is_valid(phy)) in phylink_bringup_phy()
1989 phy_request_interrupt(phy); in phylink_bringup_phy()
1991 if (pl->config->mac_managed_pm) in phylink_bringup_phy()
1992 phy->mac_managed_pm = true; in phylink_bringup_phy()
1997 static int phylink_attach_phy(struct phylink *pl, struct phy_device *phy, in phylink_attach_phy() argument
2002 if (WARN_ON(pl->cfg_link_an_mode == MLO_AN_FIXED || in phylink_attach_phy()
2003 (pl->cfg_link_an_mode == MLO_AN_INBAND && in phylink_attach_phy()
2004 phy_interface_mode_is_8023z(interface) && !pl->sfp_bus))) in phylink_attach_phy()
2005 return -EINVAL; in phylink_attach_phy()
2007 if (pl->phydev) in phylink_attach_phy()
2008 return -EBUSY; in phylink_attach_phy()
2010 if (pl->config->mac_requires_rxc) in phylink_attach_phy()
2013 return phy_attach_direct(pl->netdev, phy, flags, interface); in phylink_attach_phy()
2017 * phylink_connect_phy() - connect a PHY to the phylink instance
2019 * @phy: a pointer to a &struct phy_device.
2021 * Connect @phy to the phylink instance specified by @pl by calling
2022 * phy_attach_direct(). Configure the @phy according to the MAC driver's
2024 * that the PHY supports.
2031 int phylink_connect_phy(struct phylink *pl, struct phy_device *phy) in phylink_connect_phy() argument
2035 /* Use PHY device/driver interface */ in phylink_connect_phy()
2036 if (pl->link_interface == PHY_INTERFACE_MODE_NA) { in phylink_connect_phy()
2037 pl->link_interface = phy->interface; in phylink_connect_phy()
2038 pl->link_config.interface = pl->link_interface; in phylink_connect_phy()
2041 ret = phylink_attach_phy(pl, phy, pl->link_interface); in phylink_connect_phy()
2045 ret = phylink_bringup_phy(pl, phy, pl->link_config.interface); in phylink_connect_phy()
2047 phy_detach(phy); in phylink_connect_phy()
2054 * phylink_of_phy_connect() - connect the PHY specified in the DT mode.
2057 * @flags: PHY-specific flags to communicate to the PHY device driver
2059 * Connect the phy specified in the device node @dn to the phylink instance
2073 * phylink_fwnode_phy_connect() - connect the PHY specified in the fwnode.
2076 * @flags: PHY-specific flags to communicate to the PHY device driver
2078 * Connect the phy specified @fwnode to the phylink instance specified
2091 /* Fixed links and 802.3z are handled without needing a PHY */ in phylink_fwnode_phy_connect()
2092 if (pl->cfg_link_an_mode == MLO_AN_FIXED || in phylink_fwnode_phy_connect()
2093 (pl->cfg_link_an_mode == MLO_AN_INBAND && in phylink_fwnode_phy_connect()
2094 phy_interface_mode_is_8023z(pl->link_interface))) in phylink_fwnode_phy_connect()
2099 if (pl->cfg_link_an_mode == MLO_AN_PHY) in phylink_fwnode_phy_connect()
2100 return -ENODEV; in phylink_fwnode_phy_connect()
2108 return -ENODEV; in phylink_fwnode_phy_connect()
2110 /* Use PHY device/driver interface */ in phylink_fwnode_phy_connect()
2111 if (pl->link_interface == PHY_INTERFACE_MODE_NA) { in phylink_fwnode_phy_connect()
2112 pl->link_interface = phy_dev->interface; in phylink_fwnode_phy_connect()
2113 pl->link_config.interface = pl->link_interface; in phylink_fwnode_phy_connect()
2116 if (pl->config->mac_requires_rxc) in phylink_fwnode_phy_connect()
2119 ret = phy_attach_direct(pl->netdev, phy_dev, flags, in phylink_fwnode_phy_connect()
2120 pl->link_interface); in phylink_fwnode_phy_connect()
2125 ret = phylink_bringup_phy(pl, phy_dev, pl->link_config.interface); in phylink_fwnode_phy_connect()
2134 * phylink_disconnect_phy() - disconnect any PHY attached to the phylink
2138 * Disconnect any current PHY from the phylink instance described by @pl.
2142 struct phy_device *phy; in phylink_disconnect_phy() local
2146 phy = pl->phydev; in phylink_disconnect_phy()
2147 if (phy) { in phylink_disconnect_phy()
2148 mutex_lock(&phy->lock); in phylink_disconnect_phy()
2149 mutex_lock(&pl->state_mutex); in phylink_disconnect_phy()
2150 pl->phydev = NULL; in phylink_disconnect_phy()
2151 mutex_unlock(&pl->state_mutex); in phylink_disconnect_phy()
2152 mutex_unlock(&phy->lock); in phylink_disconnect_phy()
2153 flush_work(&pl->resolve); in phylink_disconnect_phy()
2155 phy_disconnect(phy); in phylink_disconnect_phy()
2163 pl->link_failed = true; in phylink_link_changed()
2169 * phylink_mac_change() - notify phylink of a change in MAC state
2183 * phylink_pcs_change() - notify phylink of a change to PCS link state
2191 * the latched link-down state, otherwise pass false.
2195 struct phylink *pl = pcs->phylink; in phylink_pcs_change()
2212 * phylink_start() - start a phylink instance
2215 * Start the phylink instance specified by @pl, configuring the MAC for the
2225 phylink_info(pl, "configuring for %s/%s link mode\n", in phylink_start()
2226 phylink_an_mode_str(pl->cur_link_an_mode), in phylink_start()
2227 phy_modes(pl->link_config.interface)); in phylink_start()
2230 if (pl->netdev) in phylink_start()
2231 netif_carrier_off(pl->netdev); in phylink_start()
2233 pl->pcs_state = PCS_STATE_STARTING; in phylink_start()
2236 * a fixed-link to start with the correct parameters, and also in phylink_start()
2237 * ensures that we set the appropriate advertisement for Serdes links. in phylink_start()
2240 * parameters are properly negotiated. This is necessary for DSA in phylink_start()
2245 pl->pcs_state = PCS_STATE_STARTED; in phylink_start()
2249 if (pl->cfg_link_an_mode == MLO_AN_FIXED && pl->link_gpio) { in phylink_start()
2250 int irq = gpiod_to_irq(pl->link_gpio); in phylink_start()
2257 pl->link_irq = irq; in phylink_start()
2265 if (pl->cfg_link_an_mode == MLO_AN_FIXED) in phylink_start()
2266 poll |= pl->config->poll_fixed_state; in phylink_start()
2269 mod_timer(&pl->link_poll, jiffies + HZ); in phylink_start()
2270 if (pl->phydev) in phylink_start()
2271 phy_start(pl->phydev); in phylink_start()
2272 if (pl->sfp_bus) in phylink_start()
2273 sfp_upstream_start(pl->sfp_bus); in phylink_start()
2278 * phylink_stop() - stop a phylink instance
2293 if (pl->sfp_bus) in phylink_stop()
2294 sfp_upstream_stop(pl->sfp_bus); in phylink_stop()
2295 if (pl->phydev) in phylink_stop()
2296 phy_stop(pl->phydev); in phylink_stop()
2297 del_timer_sync(&pl->link_poll); in phylink_stop()
2298 if (pl->link_irq) { in phylink_stop()
2299 free_irq(pl->link_irq, pl); in phylink_stop()
2300 pl->link_irq = 0; in phylink_stop()
2305 pl->pcs_state = PCS_STATE_DOWN; in phylink_stop()
2307 phylink_pcs_disable(pl->pcs); in phylink_stop()
2312 * phylink_suspend() - handle a network device suspend event
2314 * @mac_wol: true if the MAC needs to receive packets for Wake-on-Lan
2318 * - If Wake-on-Lan is not active, we can bring down the link between
2319 * the MAC and PHY by calling phylink_stop().
2320 * - If Wake-on-Lan is active, and being handled only by the PHY, we
2321 * can also bring down the link between the MAC and PHY.
2322 * - If Wake-on-Lan is active, but being handled by the MAC, the MAC
2329 if (mac_wol && (!pl->netdev || pl->netdev->ethtool->wol_enabled)) { in phylink_suspend()
2330 /* Wake-on-Lan enabled, MAC handling */ in phylink_suspend()
2331 mutex_lock(&pl->state_mutex); in phylink_suspend()
2334 __set_bit(PHYLINK_DISABLE_MAC_WOL, &pl->phylink_disable_state); in phylink_suspend()
2340 if (pl->netdev) in phylink_suspend()
2341 netif_carrier_off(pl->netdev); in phylink_suspend()
2343 pl->old_link_state = false; in phylink_suspend()
2348 mutex_unlock(&pl->state_mutex); in phylink_suspend()
2356 * phylink_resume() - handle a network device resume event
2366 if (test_bit(PHYLINK_DISABLE_MAC_WOL, &pl->phylink_disable_state)) { in phylink_resume()
2367 /* Wake-on-Lan enabled, MAC handling */ in phylink_resume()
2370 * Do this under the state_mutex lock for consistency. This in phylink_resume()
2372 * resume, which is harmless - the true link state will be in phylink_resume()
2375 mutex_lock(&pl->state_mutex); in phylink_resume()
2377 mutex_unlock(&pl->state_mutex); in phylink_resume()
2379 /* Re-apply the link parameters so that all the settings get in phylink_resume()
2384 /* Re-enable and re-resolve the link parameters */ in phylink_resume()
2393 * phylink_ethtool_get_wol() - get the wake on lan parameters for the PHY
2397 * Read the wake on lan parameters from the PHY attached to the phylink
2398 * instance specified by @pl. If no PHY is currently attached, report no
2399 * support for wake on lan.
2405 wol->supported = 0; in phylink_ethtool_get_wol()
2406 wol->wolopts = 0; in phylink_ethtool_get_wol()
2408 if (pl->phydev) in phylink_ethtool_get_wol()
2409 phy_ethtool_get_wol(pl->phydev, wol); in phylink_ethtool_get_wol()
2414 * phylink_ethtool_set_wol() - set wake on lan parameters
2416 * @wol: a pointer to &struct ethtool_wolinfo for the desired parameters
2418 * Set the wake on lan parameters for the PHY attached to the phylink
2419 * instance specified by @pl. If no PHY is attached, returns %EOPNOTSUPP
2426 int ret = -EOPNOTSUPP; in phylink_ethtool_set_wol()
2430 if (pl->phydev) in phylink_ethtool_set_wol()
2431 ret = phy_ethtool_set_wol(pl->phydev, wol); in phylink_ethtool_set_wol()
2451 phylink_merge_link_mode(kset->link_modes.advertising, state->advertising); in phylink_get_ksettings()
2452 linkmode_copy(kset->link_modes.lp_advertising, state->lp_advertising); in phylink_get_ksettings()
2453 if (kset->base.rate_matching == RATE_MATCH_NONE) { in phylink_get_ksettings()
2454 kset->base.speed = state->speed; in phylink_get_ksettings()
2455 kset->base.duplex = state->duplex; in phylink_get_ksettings()
2457 kset->base.autoneg = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, in phylink_get_ksettings()
2458 state->advertising) ? in phylink_get_ksettings()
2463 * phylink_ethtool_ksettings_get() - get the current link settings
2467 * Read the current link settings for the phylink instance specified by @pl.
2468 * This will be the link settings read from the MAC, PHY or fixed link
2478 if (pl->phydev) in phylink_ethtool_ksettings_get()
2479 phy_ethtool_ksettings_get(pl->phydev, kset); in phylink_ethtool_ksettings_get()
2481 kset->base.port = pl->link_port; in phylink_ethtool_ksettings_get()
2483 linkmode_copy(kset->link_modes.supported, pl->supported); in phylink_ethtool_ksettings_get()
2485 switch (pl->cur_link_an_mode) { in phylink_ethtool_ksettings_get()
2488 * current link settings - and note that these also in phylink_ethtool_ksettings_get()
2496 /* If there is a phy attached, then use the reported in phylink_ethtool_ksettings_get()
2497 * settings from the phy with no modification. in phylink_ethtool_ksettings_get()
2499 if (pl->phydev) in phylink_ethtool_ksettings_get()
2505 * layer via in-band status. Report these as the current in phylink_ethtool_ksettings_get()
2517 * phylink_ethtool_ksettings_set() - set the link settings
2519 * @kset: a pointer to a &struct ethtool_link_ksettings for the desired modes
2530 if (pl->phydev) { in phylink_ethtool_ksettings_set()
2535 pl->supported); in phylink_ethtool_ksettings_set()
2537 /* We can rely on phylib for this update; we also do not need in phylink_ethtool_ksettings_set()
2538 * to update the pl->link_config settings: in phylink_ethtool_ksettings_set()
2539 * - the configuration returned via ksettings_get() will come in phylink_ethtool_ksettings_set()
2540 * from phylib whenever a PHY is present. in phylink_ethtool_ksettings_set()
2541 * - link_config.interface will be updated by the PHY calling in phylink_ethtool_ksettings_set()
2543 * - initial link configuration for PHY mode comes from the in phylink_ethtool_ksettings_set()
2544 * last phy state updated via phylink_phy_change(). in phylink_ethtool_ksettings_set()
2545 * - other configuration changes (e.g. pause modes) are in phylink_ethtool_ksettings_set()
2547 * - if in in-band mode with a PHY, the link configuration in phylink_ethtool_ksettings_set()
2548 * is passed on the link from the PHY, and all of in phylink_ethtool_ksettings_set()
2550 * - the only possible use would be link_config.advertising in phylink_ethtool_ksettings_set()
2551 * pause modes when in 1000base-X mode with a PHY, but in in phylink_ethtool_ksettings_set()
2552 * the presence of a PHY, this should not be changed as that in phylink_ethtool_ksettings_set()
2555 return phy_ethtool_ksettings_set(pl->phydev, &phy_kset); in phylink_ethtool_ksettings_set()
2558 config = pl->link_config; in phylink_ethtool_ksettings_set()
2560 linkmode_and(config.advertising, kset->link_modes.advertising, in phylink_ethtool_ksettings_set()
2561 pl->supported); in phylink_ethtool_ksettings_set()
2563 /* FIXME: should we reject autoneg if phy/mac does not support it? */ in phylink_ethtool_ksettings_set()
2564 switch (kset->base.autoneg) { in phylink_ethtool_ksettings_set()
2569 s = phy_lookup_setting(kset->base.speed, kset->base.duplex, in phylink_ethtool_ksettings_set()
2570 pl->supported, false); in phylink_ethtool_ksettings_set()
2572 return -EINVAL; in phylink_ethtool_ksettings_set()
2577 if (pl->cur_link_an_mode == MLO_AN_FIXED) { in phylink_ethtool_ksettings_set()
2578 if (s->speed != pl->link_config.speed || in phylink_ethtool_ksettings_set()
2579 s->duplex != pl->link_config.duplex) in phylink_ethtool_ksettings_set()
2580 return -EINVAL; in phylink_ethtool_ksettings_set()
2584 config.speed = s->speed; in phylink_ethtool_ksettings_set()
2585 config.duplex = s->duplex; in phylink_ethtool_ksettings_set()
2593 if (pl->cur_link_an_mode == MLO_AN_FIXED) { in phylink_ethtool_ksettings_set()
2595 pl->link_config.advertising)) in phylink_ethtool_ksettings_set()
2596 return -EINVAL; in phylink_ethtool_ksettings_set()
2605 return -EINVAL; in phylink_ethtool_ksettings_set()
2608 /* We have ruled out the case with a PHY attached, and the in phylink_ethtool_ksettings_set()
2609 * fixed-link cases. All that is left are in-band links. in phylink_ethtool_ksettings_set()
2612 kset->base.autoneg == AUTONEG_ENABLE); in phylink_ethtool_ksettings_set()
2618 if (pl->sfp_bus) { in phylink_ethtool_ksettings_set()
2619 config.interface = sfp_select_interface(pl->sfp_bus, in phylink_ethtool_ksettings_set()
2626 return -EINVAL; in phylink_ethtool_ksettings_set()
2630 linkmode_copy(support, pl->supported); in phylink_ethtool_ksettings_set()
2633 phylink_an_mode_str(pl->cur_link_an_mode), in phylink_ethtool_ksettings_set()
2636 return -EINVAL; in phylink_ethtool_ksettings_set()
2640 linkmode_copy(support, pl->supported); in phylink_ethtool_ksettings_set()
2642 return -EINVAL; in phylink_ethtool_ksettings_set()
2649 return -EINVAL; in phylink_ethtool_ksettings_set()
2651 mutex_lock(&pl->state_mutex); in phylink_ethtool_ksettings_set()
2652 pl->link_config.speed = config.speed; in phylink_ethtool_ksettings_set()
2653 pl->link_config.duplex = config.duplex; in phylink_ethtool_ksettings_set()
2655 if (pl->link_config.interface != config.interface) { in phylink_ethtool_ksettings_set()
2656 /* The interface changed, e.g. 1000base-X <-> 2500base-X */ in phylink_ethtool_ksettings_set()
2657 /* We need to force the link down, then change the interface */ in phylink_ethtool_ksettings_set()
2658 if (pl->old_link_state) { in phylink_ethtool_ksettings_set()
2660 pl->old_link_state = false; in phylink_ethtool_ksettings_set()
2663 &pl->phylink_disable_state)) in phylink_ethtool_ksettings_set()
2665 pl->link_config.interface = config.interface; in phylink_ethtool_ksettings_set()
2666 linkmode_copy(pl->link_config.advertising, config.advertising); in phylink_ethtool_ksettings_set()
2667 } else if (!linkmode_equal(pl->link_config.advertising, in phylink_ethtool_ksettings_set()
2669 linkmode_copy(pl->link_config.advertising, config.advertising); in phylink_ethtool_ksettings_set()
2672 mutex_unlock(&pl->state_mutex); in phylink_ethtool_ksettings_set()
2679 * phylink_ethtool_nway_reset() - restart negotiation
2682 * Restart negotiation for the phylink instance specified by @pl. This will
2683 * cause any attached phy to restart negotiation with the link partner, and
2695 if (pl->phydev) in phylink_ethtool_nway_reset()
2696 ret = phy_restart_aneg(pl->phydev); in phylink_ethtool_nway_reset()
2704 * phylink_ethtool_get_pauseparam() - get the current pause parameters
2713 pause->autoneg = !!(pl->link_config.pause & MLO_PAUSE_AN); in phylink_ethtool_get_pauseparam()
2714 pause->rx_pause = !!(pl->link_config.pause & MLO_PAUSE_RX); in phylink_ethtool_get_pauseparam()
2715 pause->tx_pause = !!(pl->link_config.pause & MLO_PAUSE_TX); in phylink_ethtool_get_pauseparam()
2720 * phylink_ethtool_set_pauseparam() - set the current pause parameters
2727 struct phylink_link_state *config = &pl->link_config; in phylink_ethtool_set_pauseparam()
2733 if (pl->cur_link_an_mode == MLO_AN_FIXED) in phylink_ethtool_set_pauseparam()
2734 return -EOPNOTSUPP; in phylink_ethtool_set_pauseparam()
2736 if (!phylink_test(pl->supported, Pause) && in phylink_ethtool_set_pauseparam()
2737 !phylink_test(pl->supported, Asym_Pause)) in phylink_ethtool_set_pauseparam()
2738 return -EOPNOTSUPP; in phylink_ethtool_set_pauseparam()
2740 if (!phylink_test(pl->supported, Asym_Pause) && in phylink_ethtool_set_pauseparam()
2741 pause->rx_pause != pause->tx_pause) in phylink_ethtool_set_pauseparam()
2742 return -EINVAL; in phylink_ethtool_set_pauseparam()
2745 if (pause->autoneg) in phylink_ethtool_set_pauseparam()
2747 if (pause->rx_pause) in phylink_ethtool_set_pauseparam()
2749 if (pause->tx_pause) in phylink_ethtool_set_pauseparam()
2752 mutex_lock(&pl->state_mutex); in phylink_ethtool_set_pauseparam()
2754 * See the comments for linkmode_set_pause(), wrt the deficiencies in phylink_ethtool_set_pauseparam()
2766 linkmode_set_pause(config->advertising, pause->tx_pause, in phylink_ethtool_set_pauseparam()
2767 pause->rx_pause); in phylink_ethtool_set_pauseparam()
2769 manual_changed = (config->pause ^ pause_state) & MLO_PAUSE_AN || in phylink_ethtool_set_pauseparam()
2771 (config->pause ^ pause_state) & MLO_PAUSE_TXRX_MASK); in phylink_ethtool_set_pauseparam()
2773 config->pause = pause_state; in phylink_ethtool_set_pauseparam()
2775 /* Update our in-band advertisement, triggering a renegotiation if in phylink_ethtool_set_pauseparam()
2778 if (!pl->phydev) in phylink_ethtool_set_pauseparam()
2781 mutex_unlock(&pl->state_mutex); in phylink_ethtool_set_pauseparam()
2783 /* If we have a PHY, a change of the pause frame advertisement will in phylink_ethtool_set_pauseparam()
2788 if (pl->phydev) in phylink_ethtool_set_pauseparam()
2789 phy_set_asym_pause(pl->phydev, pause->rx_pause, in phylink_ethtool_set_pauseparam()
2790 pause->tx_pause); in phylink_ethtool_set_pauseparam()
2797 pl->link_failed = true; in phylink_ethtool_set_pauseparam()
2806 * phylink_get_eee_err() - read the energy efficient ethernet error
2810 * Read the Energy Efficient Ethernet error counter from the PHY associated
2821 if (pl->phydev) in phylink_get_eee_err()
2822 ret = phy_get_eee_err(pl->phydev); in phylink_get_eee_err()
2829 * phylink_init_eee() - init and check the EEE features
2831 * @clk_stop_enable: allow PHY to stop receive clock
2837 int ret = -EOPNOTSUPP; in phylink_init_eee()
2839 if (pl->phydev) in phylink_init_eee()
2840 ret = phy_init_eee(pl->phydev, clk_stop_enable); in phylink_init_eee()
2847 * phylink_ethtool_get_eee() - read the energy efficient ethernet parameters
2849 * @eee: a pointer to a &struct ethtool_keee for the read parameters
2853 int ret = -EOPNOTSUPP; in phylink_ethtool_get_eee()
2857 if (pl->phydev) in phylink_ethtool_get_eee()
2858 ret = phy_ethtool_get_eee(pl->phydev, eee); in phylink_ethtool_get_eee()
2865 * phylink_ethtool_set_eee() - set the energy efficient ethernet parameters
2867 * @eee: a pointer to a &struct ethtool_keee for the desired parameters
2871 int ret = -EOPNOTSUPP; in phylink_ethtool_set_eee()
2875 if (pl->phydev) in phylink_ethtool_set_eee()
2876 ret = phy_ethtool_set_eee(pl->phydev, eee); in phylink_ethtool_set_eee()
2882 /* This emulates MII registers for a fixed-mode phy operating as per the
2891 unsigned long *lpa = state->lp_advertising; in phylink_mii_emul_read()
2894 fs.link = state->link; in phylink_mii_emul_read()
2895 fs.speed = state->speed; in phylink_mii_emul_read()
2896 fs.duplex = state->duplex; in phylink_mii_emul_read()
2902 if (!state->an_complete) in phylink_mii_emul_read()
2911 struct phy_device *phydev = pl->phydev; in phylink_phy_read()
2917 return mdiobus_c45_read(pl->phydev->mdio.bus, prtad, devad, in phylink_phy_read()
2921 if (phydev->is_c45) { in phylink_phy_read()
2927 devad = __ffs(phydev->c45_ids.mmds_present); in phylink_phy_read()
2931 if (!(phydev->c45_ids.mmds_present & MDIO_DEVS_AN)) in phylink_phy_read()
2932 return -EINVAL; in phylink_phy_read()
2940 return -EINVAL; in phylink_phy_read()
2943 return mdiobus_c45_read(pl->phydev->mdio.bus, prtad, devad, in phylink_phy_read()
2947 return mdiobus_read(pl->phydev->mdio.bus, phy_id, reg); in phylink_phy_read()
2953 struct phy_device *phydev = pl->phydev; in phylink_phy_write()
2959 return mdiobus_c45_write(pl->phydev->mdio.bus, prtad, devad, in phylink_phy_write()
2963 if (phydev->is_c45) { in phylink_phy_write()
2969 devad = __ffs(phydev->c45_ids.mmds_present); in phylink_phy_write()
2973 if (!(phydev->c45_ids.mmds_present & MDIO_DEVS_AN)) in phylink_phy_write()
2974 return -EINVAL; in phylink_phy_write()
2982 return -EINVAL; in phylink_phy_write()
2984 return mdiobus_c45_write(pl->phydev->mdio.bus, phy_id, devad, in phylink_phy_write()
2988 return mdiobus_write(phydev->mdio.bus, phy_id, reg, val); in phylink_phy_write()
2997 switch (pl->cur_link_an_mode) { in phylink_mii_read()
3006 return -EOPNOTSUPP; in phylink_mii_read()
3022 switch (pl->cur_link_an_mode) { in phylink_mii_write()
3027 return -EOPNOTSUPP; in phylink_mii_write()
3037 * phylink_mii_ioctl() - generic mii ioctl interface
3039 * @ifr: a pointer to a &struct ifreq for socket ioctls
3042 * Perform the specified MII ioctl on the PHY attached to the phylink instance
3043 * specified by @pl. If no PHY is attached, emulate the presence of the PHY.
3048 * read register from the current PHY.
3050 * read register from the specified PHY.
3052 * set a register on the specified PHY.
3061 if (pl->phydev) { in phylink_mii_ioctl()
3062 /* PHYs only exist for MLO_AN_PHY and SGMII */ in phylink_mii_ioctl()
3065 mii->phy_id = pl->phydev->mdio.addr; in phylink_mii_ioctl()
3069 ret = phylink_phy_read(pl, mii->phy_id, mii->reg_num); in phylink_mii_ioctl()
3071 mii->val_out = ret; in phylink_mii_ioctl()
3077 ret = phylink_phy_write(pl, mii->phy_id, mii->reg_num, in phylink_mii_ioctl()
3078 mii->val_in); in phylink_mii_ioctl()
3082 ret = phy_mii_ioctl(pl->phydev, ifr, cmd); in phylink_mii_ioctl()
3088 mii->phy_id = 0; in phylink_mii_ioctl()
3092 ret = phylink_mii_read(pl, mii->phy_id, mii->reg_num); in phylink_mii_ioctl()
3094 mii->val_out = ret; in phylink_mii_ioctl()
3100 ret = phylink_mii_write(pl, mii->phy_id, mii->reg_num, in phylink_mii_ioctl()
3101 mii->val_in); in phylink_mii_ioctl()
3105 ret = -EOPNOTSUPP; in phylink_mii_ioctl()
3115 * phylink_speed_down() - set the non-SFP PHY to lowest speed supported by both
3120 * If we have a PHY that is not part of a SFP module, then set the speed
3122 * for a description of the @sync parameter.
3124 * Returns zero if there is no PHY, otherwise as per phy_speed_down().
3132 if (!pl->sfp_bus && pl->phydev) in phylink_speed_down()
3133 ret = phy_speed_down(pl->phydev, sync); in phylink_speed_down()
3140 * phylink_speed_up() - restore the advertised speeds prior to the call to
3144 * If we have a PHY that is not part of a SFP module, then restore the
3145 * PHY speeds as per phy_speed_up().
3147 * Returns zero if there is no PHY, otherwise as per phy_speed_up().
3155 if (!pl->sfp_bus && pl->phydev) in phylink_speed_up()
3156 ret = phy_speed_up(pl->phydev); in phylink_speed_up()
3166 pl->netdev->sfp_bus = bus; in phylink_sfp_attach()
3173 pl->netdev->sfp_bus = NULL; in phylink_sfp_detach()
3183 for (i = 0; i < ARRAY_SIZE(phylink_sfp_interface_preference); i++) in phylink_choose_sfp_interface()
3199 phylink_an_mode_str(mode), phy_modes(state->interface), in phylink_sfp_set_config()
3202 if (!linkmode_equal(pl->supported, supported)) { in phylink_sfp_set_config()
3203 linkmode_copy(pl->supported, supported); in phylink_sfp_set_config()
3207 if (!linkmode_equal(pl->link_config.advertising, state->advertising)) { in phylink_sfp_set_config()
3208 linkmode_copy(pl->link_config.advertising, state->advertising); in phylink_sfp_set_config()
3212 if (pl->cur_link_an_mode != mode || in phylink_sfp_set_config()
3213 pl->link_config.interface != state->interface) { in phylink_sfp_set_config()
3214 pl->cur_link_an_mode = mode; in phylink_sfp_set_config()
3215 pl->link_config.interface = state->interface; in phylink_sfp_set_config()
3221 phy_modes(state->interface)); in phylink_sfp_set_config()
3225 &pl->phylink_disable_state)) in phylink_sfp_set_config()
3230 struct phy_device *phy) in phylink_sfp_config_phy() argument
3238 linkmode_copy(support, phy->supported); in phylink_sfp_config_phy()
3241 linkmode_copy(config.advertising, phy->advertising); in phylink_sfp_config_phy()
3247 /* Ignore errors if we're expecting a PHY to attach later */ in phylink_sfp_config_phy()
3256 iface = sfp_select_interface(pl->sfp_bus, config.advertising); in phylink_sfp_config_phy()
3261 return -EINVAL; in phylink_sfp_config_phy()
3277 pl->link_port = pl->sfp_port; in phylink_sfp_config_phy()
3294 pl->config->supported_interfaces, in phylink_sfp_config_optical()
3296 pl->sfp_interfaces); in phylink_sfp_config_optical()
3301 phy_interface_and(interfaces, pl->config->supported_interfaces, in phylink_sfp_config_optical()
3302 pl->sfp_interfaces); in phylink_sfp_config_optical()
3305 return -EINVAL; in phylink_sfp_config_optical()
3309 linkmode_copy(support, pl->sfp_support); in phylink_sfp_config_optical()
3310 linkmode_copy(config.advertising, pl->sfp_support); in phylink_sfp_config_optical()
3315 /* For all the interfaces that are supported, reduce the sfp_support in phylink_sfp_config_optical()
3318 ret = phylink_validate_mask(pl, NULL, pl->sfp_support, &config, in phylink_sfp_config_optical()
3329 return -EINVAL; in phylink_sfp_config_optical()
3337 /* Ignore errors if we're expecting a PHY to attach later */ in phylink_sfp_config_optical()
3346 pl->link_port = pl->sfp_port; in phylink_sfp_config_optical()
3348 phylink_sfp_set_config(pl, MLO_AN_INBAND, pl->sfp_support, &config); in phylink_sfp_config_optical()
3360 linkmode_zero(pl->sfp_support); in phylink_sfp_module_insert()
3361 phy_interface_zero(pl->sfp_interfaces); in phylink_sfp_module_insert()
3362 sfp_parse_support(pl->sfp_bus, id, pl->sfp_support, pl->sfp_interfaces); in phylink_sfp_module_insert()
3363 pl->sfp_port = sfp_parse_port(pl->sfp_bus, id, pl->sfp_support); in phylink_sfp_module_insert()
3365 /* If this module may have a PHY connecting later, defer until later */ in phylink_sfp_module_insert()
3366 pl->sfp_may_have_phy = sfp_may_have_phy(pl->sfp_bus, id); in phylink_sfp_module_insert()
3367 if (pl->sfp_may_have_phy) in phylink_sfp_module_insert()
3377 /* If this SFP module has a PHY, start the PHY now. */ in phylink_sfp_module_start()
3378 if (pl->phydev) { in phylink_sfp_module_start()
3379 phy_start(pl->phydev); in phylink_sfp_module_start()
3383 /* If the module may have a PHY but we didn't detect one we in phylink_sfp_module_start()
3384 * need to configure the MAC here. in phylink_sfp_module_start()
3386 if (!pl->sfp_may_have_phy) in phylink_sfp_module_start()
3396 /* If this SFP module has a PHY, stop it. */ in phylink_sfp_module_stop()
3397 if (pl->phydev) in phylink_sfp_module_stop()
3398 phy_stop(pl->phydev); in phylink_sfp_module_stop()
3422 static bool phylink_phy_no_inband(struct phy_device *phy) in phylink_phy_no_inband() argument
3424 return phy->is_c45 && phy_id_compare(phy->c45_ids.device_ids[1], in phylink_phy_no_inband()
3428 static int phylink_sfp_connect_phy(void *upstream, struct phy_device *phy) in phylink_sfp_connect_phy() argument
3436 * This is the new way of dealing with flow control for PHYs, in phylink_sfp_connect_phy()
3437 * as described by Timur Tabi in commit 529ed1275263 ("net: phy: in phylink_sfp_connect_phy()
3438 * phy drivers should not set SUPPORTED_[Asym_]Pause") except in phylink_sfp_connect_phy()
3442 phy_support_asym_pause(phy); in phylink_sfp_connect_phy()
3444 if (phylink_phy_no_inband(phy)) in phylink_sfp_connect_phy()
3449 /* Set the PHY's host supported interfaces */ in phylink_sfp_connect_phy()
3450 phy_interface_and(phy->host_interfaces, phylink_sfp_interfaces, in phylink_sfp_connect_phy()
3451 pl->config->supported_interfaces); in phylink_sfp_connect_phy()
3454 ret = phylink_sfp_config_phy(pl, mode, phy); in phylink_sfp_connect_phy()
3458 interface = pl->link_config.interface; in phylink_sfp_connect_phy()
3459 ret = phylink_attach_phy(pl, phy, interface); in phylink_sfp_connect_phy()
3463 ret = phylink_bringup_phy(pl, phy, interface); in phylink_sfp_connect_phy()
3465 phy_detach(phy); in phylink_sfp_connect_phy()
3488 /* Helpers for MAC drivers */
3496 /* 100GBASE-KP4 and 100GBASE-CR10 not supported */
3501 /* 5GBASE-KR not supported */
3510 for (i = 0; i < ARRAY_SIZE(phylink_c73_priority_resolution); i++) { in phylink_resolve_c73()
3512 if (linkmode_test_bit(bit, state->advertising) && in phylink_resolve_c73()
3513 linkmode_test_bit(bit, state->lp_advertising)) in phylink_resolve_c73()
3518 state->speed = phylink_c73_priority_resolution[i].speed; in phylink_resolve_c73()
3519 state->duplex = DUPLEX_FULL; in phylink_resolve_c73()
3522 state->link = false; in phylink_resolve_c73()
3539 mii_lpa_mod_linkmode_x(state->lp_advertising, config_reg, fd_bit); in phylink_decode_c37_word()
3541 if (linkmode_test_bit(fd_bit, state->advertising) && in phylink_decode_c37_word()
3542 linkmode_test_bit(fd_bit, state->lp_advertising)) { in phylink_decode_c37_word()
3543 state->speed = speed; in phylink_decode_c37_word()
3544 state->duplex = DUPLEX_FULL; in phylink_decode_c37_word()
3547 state->link = false; in phylink_decode_c37_word()
3557 state->link = false; in phylink_decode_sgmii_word()
3563 state->speed = SPEED_10; in phylink_decode_sgmii_word()
3566 state->speed = SPEED_100; in phylink_decode_sgmii_word()
3569 state->speed = SPEED_1000; in phylink_decode_sgmii_word()
3572 state->link = false; in phylink_decode_sgmii_word()
3576 state->duplex = DUPLEX_FULL; in phylink_decode_sgmii_word()
3578 state->duplex = DUPLEX_HALF; in phylink_decode_sgmii_word()
3582 * phylink_decode_usxgmii_word() - decode the USXGMII word from a MAC PCS
3584 * @lpa: a 16 bit value which stores the USXGMII auto-negotiation word
3586 * Helper for MAC PCS supporting the USXGMII protocol and the auto-negotiation
3595 state->speed = SPEED_10; in phylink_decode_usxgmii_word()
3598 state->speed = SPEED_100; in phylink_decode_usxgmii_word()
3601 state->speed = SPEED_1000; in phylink_decode_usxgmii_word()
3604 state->speed = SPEED_2500; in phylink_decode_usxgmii_word()
3607 state->speed = SPEED_5000; in phylink_decode_usxgmii_word()
3610 state->speed = SPEED_10000; in phylink_decode_usxgmii_word()
3613 state->link = false; in phylink_decode_usxgmii_word()
3618 state->duplex = DUPLEX_FULL; in phylink_decode_usxgmii_word()
3620 state->duplex = DUPLEX_HALF; in phylink_decode_usxgmii_word()
3625 * phylink_decode_usgmii_word() - decode the USGMII word from a MAC PCS
3627 * @lpa: a 16 bit value which stores the USGMII auto-negotiation word
3629 * Helper for MAC PCS supporting the USGMII protocol and the auto-negotiation
3631 * (speed, duplex) into the phylink_link_state structure. The structure for this
3640 state->speed = SPEED_10; in phylink_decode_usgmii_word()
3643 state->speed = SPEED_100; in phylink_decode_usgmii_word()
3646 state->speed = SPEED_1000; in phylink_decode_usgmii_word()
3649 state->link = false; in phylink_decode_usgmii_word()
3654 state->duplex = DUPLEX_FULL; in phylink_decode_usgmii_word()
3656 state->duplex = DUPLEX_HALF; in phylink_decode_usgmii_word()
3660 * phylink_mii_c22_pcs_decode_state() - Decode MAC PCS state from MII registers
3665 * Helper for MAC PCS supporting the 802.3 clause 22 register set for
3669 * the phylink @state structure. This is suitable to be used for implementing
3676 state->link = !!(bmsr & BMSR_LSTATUS); in phylink_mii_c22_pcs_decode_state()
3677 state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE); in phylink_mii_c22_pcs_decode_state()
3681 if (!state->link || !linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, in phylink_mii_c22_pcs_decode_state()
3682 state->advertising)) in phylink_mii_c22_pcs_decode_state()
3685 switch (state->interface) { in phylink_mii_c22_pcs_decode_state()
3703 state->link = false; in phylink_mii_c22_pcs_decode_state()
3710 * phylink_mii_c22_pcs_get_state() - read the MAC PCS state
3714 * Helper for MAC PCS supporting the 802.3 clause 22 register set for
3731 state->link = false; in phylink_mii_c22_pcs_get_state()
3740 * phylink_mii_c22_pcs_encode_advertisement() - configure the clause 37 PCS
3742 * @interface: the PHY interface mode being configured
3745 * Helper for MAC PCS supporting the 802.3 clause 22 register set for
3751 * Return: The new value for @adv, or ``-EINVAL`` if it should not be changed.
3773 /* Nothing to do for other modes */ in phylink_mii_c22_pcs_encode_advertisement()
3774 return -EINVAL; in phylink_mii_c22_pcs_encode_advertisement()
3780 * phylink_mii_c22_pcs_config() - configure clause 22 PCS
3782 * @interface: the PHY interface mode being configured
3786 * Configure a Clause 22 PCS PHY with the appropriate negotiation
3787 * parameters for the @mode, @interface and @advertising parameters.
3802 ret = mdiobus_modify_changed(pcs->bus, pcs->addr, in phylink_mii_c22_pcs_config()
3824 * phylink_mii_c22_pcs_an_restart() - restart 802.3z autonegotiation
3827 * Helper for MAC PCS supporting the 802.3 clause 22 register set for
3849 struct mii_bus *bus = pcs->bus; in phylink_mii_c45_pcs_get_state()
3850 int addr = pcs->addr; in phylink_mii_c45_pcs_get_state()
3855 state->link = false; in phylink_mii_c45_pcs_get_state()
3859 state->link = !!(stat & MDIO_STAT1_LSTATUS); in phylink_mii_c45_pcs_get_state()
3860 if (!state->link) in phylink_mii_c45_pcs_get_state()
3863 switch (state->interface) { in phylink_mii_c45_pcs_get_state()
3865 state->speed = SPEED_10000; in phylink_mii_c45_pcs_get_state()
3866 state->duplex = DUPLEX_FULL; in phylink_mii_c45_pcs_get_state()
3877 for (int i = 0; i < ARRAY_SIZE(phylink_sfp_interface_preference); ++i) in phylink_init()
3887 MODULE_DESCRIPTION("phylink models the MAC to optional PHY connection");