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.
14 #include <linux/phy.h>
38 * struct phylink - internal data type for phylink
55 u8 link_port; /* The current non-phy ethtool port */
84 if ((pl)->config->type == PHYLINK_NETDEV) \
85 netdev_printk(level, (pl)->netdev, fmt, ##__VA_ARGS__); \
86 else if ((pl)->config->type == PHYLINK_DEV) \
87 dev_printk(level, (pl)->dev, fmt, ##__VA_ARGS__); \
99 if ((pl)->config->type == PHYLINK_NETDEV) \
100 netdev_dbg((pl)->netdev, fmt, ##__VA_ARGS__); \
101 else if ((pl)->config->type == PHYLINK_DEV) \
102 dev_dbg((pl)->dev, fmt, ##__VA_ARGS__); \
116 * phylink_set_port_modes() - set the port type modes in the ethtool mask
148 [MLO_AN_PHY] = "phy", in phylink_an_mode_str()
159 pl->mac_ops->validate(pl->config, supported, state); in phylink_validate()
161 return phylink_is_empty_linkmode(supported) ? -EINVAL : 0; in phylink_validate()
173 fixed_node = fwnode_get_named_child_node(fwnode, "fixed-link"); in phylink_parse_fixedlink()
177 pl->link_config.speed = speed; in phylink_parse_fixedlink()
178 pl->link_config.duplex = DUPLEX_HALF; in phylink_parse_fixedlink()
180 if (fwnode_property_read_bool(fixed_node, "full-duplex")) in phylink_parse_fixedlink()
181 pl->link_config.duplex = DUPLEX_FULL; in phylink_parse_fixedlink()
183 /* We treat the "pause" and "asym-pause" terminology as in phylink_parse_fixedlink()
187 pl->link_config.lp_advertising); in phylink_parse_fixedlink()
188 if (fwnode_property_read_bool(fixed_node, "asym-pause")) in phylink_parse_fixedlink()
190 pl->link_config.lp_advertising); in phylink_parse_fixedlink()
197 pl->link_gpio = desc; in phylink_parse_fixedlink()
198 else if (desc == ERR_PTR(-EPROBE_DEFER)) in phylink_parse_fixedlink()
199 ret = -EPROBE_DEFER; in phylink_parse_fixedlink()
208 ret = fwnode_property_read_u32_array(fwnode, "fixed-link", in phylink_parse_fixedlink()
211 phylink_err(pl, "broken fixed-link?\n"); in phylink_parse_fixedlink()
212 return -EINVAL; in phylink_parse_fixedlink()
215 ret = fwnode_property_read_u32_array(fwnode, "fixed-link", in phylink_parse_fixedlink()
218 pl->link_config.duplex = prop[1] ? in phylink_parse_fixedlink()
220 pl->link_config.speed = prop[2]; in phylink_parse_fixedlink()
223 pl->link_config.lp_advertising); in phylink_parse_fixedlink()
226 pl->link_config.lp_advertising); in phylink_parse_fixedlink()
230 if (pl->link_config.speed > SPEED_1000 && in phylink_parse_fixedlink()
231 pl->link_config.duplex != DUPLEX_FULL) in phylink_parse_fixedlink()
232 phylink_warn(pl, "fixed link specifies half duplex for %dMbps link?\n", in phylink_parse_fixedlink()
233 pl->link_config.speed); in phylink_parse_fixedlink()
235 bitmap_fill(pl->supported, __ETHTOOL_LINK_MODE_MASK_NBITS); in phylink_parse_fixedlink()
236 linkmode_copy(pl->link_config.advertising, pl->supported); in phylink_parse_fixedlink()
237 phylink_validate(pl, pl->supported, &pl->link_config); in phylink_parse_fixedlink()
239 s = phy_lookup_setting(pl->link_config.speed, pl->link_config.duplex, in phylink_parse_fixedlink()
240 pl->supported, true); in phylink_parse_fixedlink()
241 linkmode_zero(pl->supported); in phylink_parse_fixedlink()
242 phylink_set(pl->supported, MII); in phylink_parse_fixedlink()
243 phylink_set(pl->supported, Pause); in phylink_parse_fixedlink()
244 phylink_set(pl->supported, Asym_Pause); in phylink_parse_fixedlink()
245 phylink_set(pl->supported, Autoneg); in phylink_parse_fixedlink()
247 __set_bit(s->bit, pl->supported); in phylink_parse_fixedlink()
248 __set_bit(s->bit, pl->link_config.lp_advertising); in phylink_parse_fixedlink()
251 pl->link_config.duplex == DUPLEX_FULL ? "full" : "half", in phylink_parse_fixedlink()
252 pl->link_config.speed); in phylink_parse_fixedlink()
255 linkmode_and(pl->link_config.advertising, pl->link_config.advertising, in phylink_parse_fixedlink()
256 pl->supported); in phylink_parse_fixedlink()
258 pl->link_config.link = 1; in phylink_parse_fixedlink()
259 pl->link_config.an_complete = 1; in phylink_parse_fixedlink()
269 dn = fwnode_get_named_child_node(fwnode, "fixed-link"); in phylink_parse_mode()
270 if (dn || fwnode_property_present(fwnode, "fixed-link")) in phylink_parse_mode()
271 pl->cfg_link_an_mode = MLO_AN_FIXED; in phylink_parse_mode()
275 strcmp(managed, "in-band-status") == 0) { in phylink_parse_mode()
276 if (pl->cfg_link_an_mode == MLO_AN_FIXED) { in phylink_parse_mode()
278 "can't use both fixed-link and in-band-status\n"); in phylink_parse_mode()
279 return -EINVAL; in phylink_parse_mode()
282 linkmode_zero(pl->supported); in phylink_parse_mode()
283 phylink_set(pl->supported, MII); in phylink_parse_mode()
284 phylink_set(pl->supported, Autoneg); in phylink_parse_mode()
285 phylink_set(pl->supported, Asym_Pause); in phylink_parse_mode()
286 phylink_set(pl->supported, Pause); in phylink_parse_mode()
287 pl->link_config.an_enabled = true; in phylink_parse_mode()
288 pl->cfg_link_an_mode = MLO_AN_INBAND; in phylink_parse_mode()
290 switch (pl->link_config.interface) { in phylink_parse_mode()
293 phylink_set(pl->supported, 10baseT_Half); in phylink_parse_mode()
294 phylink_set(pl->supported, 10baseT_Full); in phylink_parse_mode()
295 phylink_set(pl->supported, 100baseT_Half); in phylink_parse_mode()
296 phylink_set(pl->supported, 100baseT_Full); in phylink_parse_mode()
297 phylink_set(pl->supported, 1000baseT_Half); in phylink_parse_mode()
298 phylink_set(pl->supported, 1000baseT_Full); in phylink_parse_mode()
302 phylink_set(pl->supported, 1000baseX_Full); in phylink_parse_mode()
306 phylink_set(pl->supported, 2500baseX_Full); in phylink_parse_mode()
312 phylink_set(pl->supported, 10baseT_Half); in phylink_parse_mode()
313 phylink_set(pl->supported, 10baseT_Full); in phylink_parse_mode()
314 phylink_set(pl->supported, 100baseT_Half); in phylink_parse_mode()
315 phylink_set(pl->supported, 100baseT_Full); in phylink_parse_mode()
316 phylink_set(pl->supported, 1000baseT_Half); in phylink_parse_mode()
317 phylink_set(pl->supported, 1000baseT_Full); in phylink_parse_mode()
318 phylink_set(pl->supported, 1000baseX_Full); in phylink_parse_mode()
319 phylink_set(pl->supported, 1000baseKX_Full); in phylink_parse_mode()
320 phylink_set(pl->supported, 2500baseT_Full); in phylink_parse_mode()
321 phylink_set(pl->supported, 2500baseX_Full); in phylink_parse_mode()
322 phylink_set(pl->supported, 5000baseT_Full); in phylink_parse_mode()
323 phylink_set(pl->supported, 10000baseT_Full); in phylink_parse_mode()
324 phylink_set(pl->supported, 10000baseKR_Full); in phylink_parse_mode()
325 phylink_set(pl->supported, 10000baseKX4_Full); in phylink_parse_mode()
326 phylink_set(pl->supported, 10000baseCR_Full); in phylink_parse_mode()
327 phylink_set(pl->supported, 10000baseSR_Full); in phylink_parse_mode()
328 phylink_set(pl->supported, 10000baseLR_Full); in phylink_parse_mode()
329 phylink_set(pl->supported, 10000baseLRM_Full); in phylink_parse_mode()
330 phylink_set(pl->supported, 10000baseER_Full); in phylink_parse_mode()
334 phylink_set(pl->supported, 25000baseCR_Full); in phylink_parse_mode()
335 phylink_set(pl->supported, 25000baseKR_Full); in phylink_parse_mode()
336 phylink_set(pl->supported, 25000baseSR_Full); in phylink_parse_mode()
337 phylink_set(pl->supported, 40000baseKR4_Full); in phylink_parse_mode()
338 phylink_set(pl->supported, 40000baseCR4_Full); in phylink_parse_mode()
339 phylink_set(pl->supported, 40000baseSR4_Full); in phylink_parse_mode()
340 phylink_set(pl->supported, 40000baseLR4_Full); in phylink_parse_mode()
341 phylink_set(pl->supported, 50000baseCR2_Full); in phylink_parse_mode()
342 phylink_set(pl->supported, 50000baseKR2_Full); in phylink_parse_mode()
343 phylink_set(pl->supported, 50000baseSR2_Full); in phylink_parse_mode()
344 phylink_set(pl->supported, 50000baseKR_Full); in phylink_parse_mode()
345 phylink_set(pl->supported, 50000baseSR_Full); in phylink_parse_mode()
346 phylink_set(pl->supported, 50000baseCR_Full); in phylink_parse_mode()
347 phylink_set(pl->supported, 50000baseLR_ER_FR_Full); in phylink_parse_mode()
348 phylink_set(pl->supported, 50000baseDR_Full); in phylink_parse_mode()
349 phylink_set(pl->supported, 100000baseKR4_Full); in phylink_parse_mode()
350 phylink_set(pl->supported, 100000baseSR4_Full); in phylink_parse_mode()
351 phylink_set(pl->supported, 100000baseCR4_Full); in phylink_parse_mode()
352 phylink_set(pl->supported, 100000baseLR4_ER4_Full); in phylink_parse_mode()
353 phylink_set(pl->supported, 100000baseKR2_Full); in phylink_parse_mode()
354 phylink_set(pl->supported, 100000baseSR2_Full); in phylink_parse_mode()
355 phylink_set(pl->supported, 100000baseCR2_Full); in phylink_parse_mode()
356 phylink_set(pl->supported, 100000baseLR2_ER2_FR2_Full); in phylink_parse_mode()
357 phylink_set(pl->supported, 100000baseDR2_Full); in phylink_parse_mode()
362 "incorrect link mode %s for in-band status\n", in phylink_parse_mode()
363 phy_modes(pl->link_config.interface)); in phylink_parse_mode()
364 return -EINVAL; in phylink_parse_mode()
367 linkmode_copy(pl->link_config.advertising, pl->supported); in phylink_parse_mode()
369 if (phylink_validate(pl, pl->supported, &pl->link_config)) { in phylink_parse_mode()
371 "failed to validate link configuration for in-band status\n"); in phylink_parse_mode()
372 return -EINVAL; in phylink_parse_mode()
376 pl->link_config.an_enabled = phylink_test(pl->supported, Autoneg); in phylink_parse_mode()
386 if (!state->an_enabled) in phylink_apply_manual_flow()
387 state->pause &= ~MLO_PAUSE_AN; in phylink_apply_manual_flow()
390 if (!(pl->link_config.pause & MLO_PAUSE_AN)) in phylink_apply_manual_flow()
391 state->pause = pl->link_config.pause; in phylink_apply_manual_flow()
398 state->pause = MLO_PAUSE_NONE; in phylink_resolve_flow()
399 if (state->duplex == DUPLEX_FULL) { in phylink_resolve_flow()
400 linkmode_resolve_pause(state->advertising, in phylink_resolve_flow()
401 state->lp_advertising, in phylink_resolve_flow()
404 state->pause |= MLO_PAUSE_TX; in phylink_resolve_flow()
406 state->pause |= MLO_PAUSE_RX; in phylink_resolve_flow()
415 __func__, phylink_an_mode_str(pl->cur_link_an_mode), in phylink_mac_config()
416 phy_modes(state->interface), in phylink_mac_config()
417 phy_speed_to_str(state->speed), in phylink_mac_config()
418 phy_duplex_to_str(state->duplex), in phylink_mac_config()
419 __ETHTOOL_LINK_MODE_MASK_NBITS, state->advertising, in phylink_mac_config()
420 state->pause, state->link, state->an_enabled); in phylink_mac_config()
422 pl->mac_ops->mac_config(pl->config, pl->cur_link_an_mode, state); in phylink_mac_config()
427 if (pl->link_config.an_enabled && in phylink_mac_pcs_an_restart()
428 phy_interface_mode_is_8023z(pl->link_config.interface) && in phylink_mac_pcs_an_restart()
429 phylink_autoneg_inband(pl->cur_link_an_mode)) { in phylink_mac_pcs_an_restart()
430 if (pl->pcs_ops) in phylink_mac_pcs_an_restart()
431 pl->pcs_ops->pcs_an_restart(pl->pcs); in phylink_mac_pcs_an_restart()
433 pl->mac_ops->mac_an_restart(pl->config); in phylink_mac_pcs_an_restart()
442 phylink_dbg(pl, "major config %s\n", phy_modes(state->interface)); in phylink_major_config()
444 if (pl->mac_ops->mac_prepare) { in phylink_major_config()
445 err = pl->mac_ops->mac_prepare(pl->config, pl->cur_link_an_mode, in phylink_major_config()
446 state->interface); in phylink_major_config()
456 if (pl->pcs_ops) { in phylink_major_config()
457 err = pl->pcs_ops->pcs_config(pl->pcs, pl->cur_link_an_mode, in phylink_major_config()
458 state->interface, in phylink_major_config()
459 state->advertising, in phylink_major_config()
460 !!(pl->link_config.pause & in phylink_major_config()
471 if (pl->mac_ops->mac_finish) { in phylink_major_config()
472 err = pl->mac_ops->mac_finish(pl->config, pl->cur_link_an_mode, in phylink_major_config()
473 state->interface); in phylink_major_config()
481 * Reconfigure for a change of inband advertisement.
482 * If we have a separate PCS, we only need to call its pcs_config() method,
490 if (test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) in phylink_change_inband_advert()
493 if (!pl->pcs_ops) { in phylink_change_inband_advert()
495 phylink_mac_config(pl, &pl->link_config); in phylink_change_inband_advert()
501 phylink_an_mode_str(pl->cur_link_an_mode), in phylink_change_inband_advert()
502 phy_modes(pl->link_config.interface), in phylink_change_inband_advert()
503 __ETHTOOL_LINK_MODE_MASK_NBITS, pl->link_config.advertising, in phylink_change_inband_advert()
504 pl->link_config.pause); in phylink_change_inband_advert()
506 /* Modern PCS-based method; update the advert at the PCS, and in phylink_change_inband_advert()
510 ret = pl->pcs_ops->pcs_config(pl->pcs, pl->cur_link_an_mode, in phylink_change_inband_advert()
511 pl->link_config.interface, in phylink_change_inband_advert()
512 pl->link_config.advertising, in phylink_change_inband_advert()
513 !!(pl->link_config.pause & MLO_PAUSE_AN)); in phylink_change_inband_advert()
526 linkmode_copy(state->advertising, pl->link_config.advertising); in phylink_mac_pcs_get_state()
527 linkmode_zero(state->lp_advertising); in phylink_mac_pcs_get_state()
528 state->interface = pl->link_config.interface; in phylink_mac_pcs_get_state()
529 state->an_enabled = pl->link_config.an_enabled; in phylink_mac_pcs_get_state()
530 state->speed = SPEED_UNKNOWN; in phylink_mac_pcs_get_state()
531 state->duplex = DUPLEX_UNKNOWN; in phylink_mac_pcs_get_state()
532 state->pause = MLO_PAUSE_NONE; in phylink_mac_pcs_get_state()
533 state->an_complete = 0; in phylink_mac_pcs_get_state()
534 state->link = 1; in phylink_mac_pcs_get_state()
536 if (pl->pcs_ops) in phylink_mac_pcs_get_state()
537 pl->pcs_ops->pcs_get_state(pl->pcs, state); in phylink_mac_pcs_get_state()
538 else if (pl->mac_ops->mac_pcs_get_state) in phylink_mac_pcs_get_state()
539 pl->mac_ops->mac_pcs_get_state(pl->config, state); in phylink_mac_pcs_get_state()
541 state->link = 0; in phylink_mac_pcs_get_state()
544 /* The fixed state is... fixed except for the link state,
550 *state = pl->link_config; in phylink_get_fixed_state()
551 if (pl->config->get_fixed_state) in phylink_get_fixed_state()
552 pl->config->get_fixed_state(pl->config, state); in phylink_get_fixed_state()
553 else if (pl->link_gpio) in phylink_get_fixed_state()
554 state->link = !!gpiod_get_value_cansleep(pl->link_gpio); in phylink_get_fixed_state()
563 switch (pl->cur_link_an_mode) { in phylink_mac_initial_config()
565 link_state = pl->phy_state; in phylink_mac_initial_config()
573 link_state = pl->link_config; in phylink_mac_initial_config()
605 struct net_device *ndev = pl->netdev; in phylink_link_up()
607 pl->cur_interface = link_state.interface; in phylink_link_up()
609 if (pl->pcs_ops && pl->pcs_ops->pcs_link_up) in phylink_link_up()
610 pl->pcs_ops->pcs_link_up(pl->pcs, pl->cur_link_an_mode, in phylink_link_up()
611 pl->cur_interface, in phylink_link_up()
614 pl->mac_ops->mac_link_up(pl->config, pl->phydev, in phylink_link_up()
615 pl->cur_link_an_mode, pl->cur_interface, in phylink_link_up()
624 "Link is Up - %s/%s - flow control %s\n", in phylink_link_up()
632 struct net_device *ndev = pl->netdev; in phylink_link_down()
636 pl->mac_ops->mac_link_down(pl->config, pl->cur_link_an_mode, in phylink_link_down()
637 pl->cur_interface); in phylink_link_down()
645 struct net_device *ndev = pl->netdev; in phylink_resolve()
649 mutex_lock(&pl->state_mutex); in phylink_resolve()
650 if (pl->netdev) in phylink_resolve()
653 cur_link_state = pl->old_link_state; in phylink_resolve()
655 if (pl->phylink_disable_state) { in phylink_resolve()
656 pl->mac_link_dropped = false; in phylink_resolve()
658 } else if (pl->mac_link_dropped) { in phylink_resolve()
661 switch (pl->cur_link_an_mode) { in phylink_resolve()
663 link_state = pl->phy_state; in phylink_resolve()
676 /* If we have a phy, the "up" state is the union of in phylink_resolve()
677 * both the PHY and the MAC */ in phylink_resolve()
678 if (pl->phydev) in phylink_resolve()
679 link_state.link &= pl->phy_state.link; in phylink_resolve()
681 /* Only update if the PHY link is up */ in phylink_resolve()
682 if (pl->phydev && pl->phy_state.link) { in phylink_resolve()
683 link_state.interface = pl->phy_state.interface; in phylink_resolve()
685 /* If we have a PHY, we need to update with in phylink_resolve()
686 * the PHY flow control bits. */ in phylink_resolve()
687 link_state.pause = pl->phy_state.pause; in phylink_resolve()
696 if (link_state.interface != pl->link_config.interface) { in phylink_resolve()
705 pl->link_config.interface = link_state.interface; in phylink_resolve()
706 } else if (!pl->pcs_ops) { in phylink_resolve()
718 pl->old_link_state = link_state.link; in phylink_resolve()
724 if (!link_state.link && pl->mac_link_dropped) { in phylink_resolve()
725 pl->mac_link_dropped = false; in phylink_resolve()
726 queue_work(system_power_efficient_wq, &pl->resolve); in phylink_resolve()
728 mutex_unlock(&pl->state_mutex); in phylink_resolve()
733 if (!pl->phylink_disable_state) in phylink_run_resolve()
734 queue_work(system_power_efficient_wq, &pl->resolve); in phylink_run_resolve()
739 unsigned long state = pl->phylink_disable_state; in phylink_run_resolve_and_disable()
741 set_bit(bit, &pl->phylink_disable_state); in phylink_run_resolve_and_disable()
743 queue_work(system_power_efficient_wq, &pl->resolve); in phylink_run_resolve_and_disable()
744 flush_work(&pl->resolve); in phylink_run_resolve_and_disable()
775 pl->sfp_bus = bus; in phylink_register_sfp()
784 * phylink_create() - create a phylink instance
789 * @mac_ops: a pointer to a &struct phylink_mac_ops for the MAC.
792 * This will parse in-band modes, fixed-link or SFP configuration.
796 * Returns a pointer to a &struct phylink, or an error-pointer value. Users
797 * must use IS_ERR() to check for errors from this function.
809 return ERR_PTR(-ENOMEM); in phylink_create()
811 mutex_init(&pl->state_mutex); in phylink_create()
812 INIT_WORK(&pl->resolve, phylink_resolve); in phylink_create()
814 pl->config = config; in phylink_create()
815 if (config->type == PHYLINK_NETDEV) { in phylink_create()
816 pl->netdev = to_net_dev(config->dev); in phylink_create()
817 } else if (config->type == PHYLINK_DEV) { in phylink_create()
818 pl->dev = config->dev; in phylink_create()
821 return ERR_PTR(-EINVAL); in phylink_create()
824 pl->phy_state.interface = iface; in phylink_create()
825 pl->link_interface = iface; in phylink_create()
827 pl->link_port = PORT_BNC; in phylink_create()
829 pl->link_port = PORT_MII; in phylink_create()
830 pl->link_config.interface = iface; in phylink_create()
831 pl->link_config.pause = MLO_PAUSE_AN; in phylink_create()
832 pl->link_config.speed = SPEED_UNKNOWN; in phylink_create()
833 pl->link_config.duplex = DUPLEX_UNKNOWN; in phylink_create()
834 pl->link_config.an_enabled = true; in phylink_create()
835 pl->mac_ops = mac_ops; in phylink_create()
836 __set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); in phylink_create()
837 timer_setup(&pl->link_poll, phylink_fixed_poll, 0); in phylink_create()
839 bitmap_fill(pl->supported, __ETHTOOL_LINK_MODE_MASK_NBITS); in phylink_create()
840 linkmode_copy(pl->link_config.advertising, pl->supported); in phylink_create()
841 phylink_validate(pl, pl->supported, &pl->link_config); in phylink_create()
849 if (pl->cfg_link_an_mode == MLO_AN_FIXED) { in phylink_create()
857 pl->cur_link_an_mode = pl->cfg_link_an_mode; in phylink_create()
870 * phylink_set_pcs() - set the current PCS for phylink to use
885 pl->pcs = pcs; in phylink_set_pcs()
886 pl->pcs_ops = pcs->ops; in phylink_set_pcs()
891 * phylink_destroy() - cleanup and destroy the phylink instance
894 * Destroy a phylink instance. Any PHY that has been attached must have been
901 sfp_bus_del_upstream(pl->sfp_bus); in phylink_destroy()
902 if (pl->link_gpio) in phylink_destroy()
903 gpiod_put(pl->link_gpio); in phylink_destroy()
905 cancel_work_sync(&pl->resolve); in phylink_destroy()
912 struct phylink *pl = phydev->phylink; in phylink_phy_change()
917 mutex_lock(&pl->state_mutex); in phylink_phy_change()
918 pl->phy_state.speed = phydev->speed; in phylink_phy_change()
919 pl->phy_state.duplex = phydev->duplex; in phylink_phy_change()
920 pl->phy_state.pause = MLO_PAUSE_NONE; in phylink_phy_change()
922 pl->phy_state.pause |= MLO_PAUSE_TX; in phylink_phy_change()
924 pl->phy_state.pause |= MLO_PAUSE_RX; in phylink_phy_change()
925 pl->phy_state.interface = phydev->interface; in phylink_phy_change()
926 pl->phy_state.link = up; in phylink_phy_change()
927 mutex_unlock(&pl->state_mutex); in phylink_phy_change()
931 phylink_dbg(pl, "phy link %s %s/%s/%s\n", up ? "up" : "down", in phylink_phy_change()
932 phy_modes(phydev->interface), in phylink_phy_change()
933 phy_speed_to_str(phydev->speed), in phylink_phy_change()
934 phy_duplex_to_str(phydev->duplex)); in phylink_phy_change()
937 static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy, in phylink_bringup_phy() argument
946 * This is the new way of dealing with flow control for PHYs, in phylink_bringup_phy()
947 * as described by Timur Tabi in commit 529ed1275263 ("net: phy: in phylink_bringup_phy()
948 * phy drivers should not set SUPPORTED_[Asym_]Pause") except in phylink_bringup_phy()
952 phy_support_asym_pause(phy); in phylink_bringup_phy()
955 linkmode_copy(supported, phy->supported); in phylink_bringup_phy()
956 linkmode_copy(config.advertising, phy->advertising); in phylink_bringup_phy()
959 * modes, normally 10GBASE-R, SGMII. Some use 2500BASE-X for 2.5G in phylink_bringup_phy()
960 * speeds. We really need to know which interface modes the PHY and in phylink_bringup_phy()
963 if (phy->is_c45 && in phylink_bringup_phy()
975 __ETHTOOL_LINK_MODE_MASK_NBITS, phy->supported, in phylink_bringup_phy()
981 phy->phylink = pl; in phylink_bringup_phy()
982 phy->phy_link_change = phylink_phy_change; in phylink_bringup_phy()
984 irq_str = phy_attached_info_irq(phy); in phylink_bringup_phy()
986 "PHY [%s] driver [%s] (irq=%s)\n", in phylink_bringup_phy()
987 dev_name(&phy->mdio.dev), phy->drv->name, irq_str); in phylink_bringup_phy()
990 mutex_lock(&phy->lock); in phylink_bringup_phy()
991 mutex_lock(&pl->state_mutex); in phylink_bringup_phy()
992 pl->phydev = phy; in phylink_bringup_phy()
993 pl->phy_state.interface = interface; in phylink_bringup_phy()
994 pl->phy_state.pause = MLO_PAUSE_NONE; in phylink_bringup_phy()
995 pl->phy_state.speed = SPEED_UNKNOWN; in phylink_bringup_phy()
996 pl->phy_state.duplex = DUPLEX_UNKNOWN; in phylink_bringup_phy()
997 linkmode_copy(pl->supported, supported); in phylink_bringup_phy()
998 linkmode_copy(pl->link_config.advertising, config.advertising); in phylink_bringup_phy()
1000 /* Restrict the phy advertisement according to the MAC support. */ in phylink_bringup_phy()
1001 linkmode_copy(phy->advertising, config.advertising); in phylink_bringup_phy()
1002 mutex_unlock(&pl->state_mutex); in phylink_bringup_phy()
1003 mutex_unlock(&phy->lock); in phylink_bringup_phy()
1006 "phy: setting supported %*pb advertising %*pb\n", in phylink_bringup_phy()
1007 __ETHTOOL_LINK_MODE_MASK_NBITS, pl->supported, in phylink_bringup_phy()
1008 __ETHTOOL_LINK_MODE_MASK_NBITS, phy->advertising); in phylink_bringup_phy()
1010 if (phy_interrupt_is_valid(phy)) in phylink_bringup_phy()
1011 phy_request_interrupt(phy); in phylink_bringup_phy()
1016 static int phylink_attach_phy(struct phylink *pl, struct phy_device *phy, in phylink_attach_phy() argument
1019 if (WARN_ON(pl->cfg_link_an_mode == MLO_AN_FIXED || in phylink_attach_phy()
1020 (pl->cfg_link_an_mode == MLO_AN_INBAND && in phylink_attach_phy()
1022 return -EINVAL; in phylink_attach_phy()
1024 if (pl->phydev) in phylink_attach_phy()
1025 return -EBUSY; in phylink_attach_phy()
1027 return phy_attach_direct(pl->netdev, phy, 0, interface); in phylink_attach_phy()
1031 * phylink_connect_phy() - connect a PHY to the phylink instance
1033 * @phy: a pointer to a &struct phy_device.
1035 * Connect @phy to the phylink instance specified by @pl by calling
1036 * phy_attach_direct(). Configure the @phy according to the MAC driver's
1038 * that the PHY supports.
1045 int phylink_connect_phy(struct phylink *pl, struct phy_device *phy) in phylink_connect_phy() argument
1049 /* Use PHY device/driver interface */ in phylink_connect_phy()
1050 if (pl->link_interface == PHY_INTERFACE_MODE_NA) { in phylink_connect_phy()
1051 pl->link_interface = phy->interface; in phylink_connect_phy()
1052 pl->link_config.interface = pl->link_interface; in phylink_connect_phy()
1055 ret = phylink_attach_phy(pl, phy, pl->link_interface); in phylink_connect_phy()
1059 ret = phylink_bringup_phy(pl, phy, pl->link_config.interface); in phylink_connect_phy()
1061 phy_detach(phy); in phylink_connect_phy()
1068 * phylink_of_phy_connect() - connect the PHY specified in the DT mode.
1071 * @flags: PHY-specific flags to communicate to the PHY device driver
1073 * Connect the phy specified in the device node @dn to the phylink instance
1086 /* Fixed links and 802.3z are handled without needing a PHY */ in phylink_of_phy_connect()
1087 if (pl->cfg_link_an_mode == MLO_AN_FIXED || in phylink_of_phy_connect()
1088 (pl->cfg_link_an_mode == MLO_AN_INBAND && in phylink_of_phy_connect()
1089 phy_interface_mode_is_8023z(pl->link_interface))) in phylink_of_phy_connect()
1092 phy_node = of_parse_phandle(dn, "phy-handle", 0); in phylink_of_phy_connect()
1094 phy_node = of_parse_phandle(dn, "phy", 0); in phylink_of_phy_connect()
1096 phy_node = of_parse_phandle(dn, "phy-device", 0); in phylink_of_phy_connect()
1099 if (pl->cfg_link_an_mode == MLO_AN_PHY) in phylink_of_phy_connect()
1100 return -ENODEV; in phylink_of_phy_connect()
1108 return -ENODEV; in phylink_of_phy_connect()
1110 ret = phy_attach_direct(pl->netdev, phy_dev, flags, in phylink_of_phy_connect()
1111 pl->link_interface); in phylink_of_phy_connect()
1115 ret = phylink_bringup_phy(pl, phy_dev, pl->link_config.interface); in phylink_of_phy_connect()
1124 * phylink_disconnect_phy() - disconnect any PHY attached to the phylink
1128 * Disconnect any current PHY from the phylink instance described by @pl.
1132 struct phy_device *phy; in phylink_disconnect_phy() local
1136 phy = pl->phydev; in phylink_disconnect_phy()
1137 if (phy) { in phylink_disconnect_phy()
1138 mutex_lock(&phy->lock); in phylink_disconnect_phy()
1139 mutex_lock(&pl->state_mutex); in phylink_disconnect_phy()
1140 pl->phydev = NULL; in phylink_disconnect_phy()
1141 mutex_unlock(&pl->state_mutex); in phylink_disconnect_phy()
1142 mutex_unlock(&phy->lock); in phylink_disconnect_phy()
1143 flush_work(&pl->resolve); in phylink_disconnect_phy()
1145 phy_disconnect(phy); in phylink_disconnect_phy()
1151 * phylink_mac_change() - notify phylink of a change in MAC state
1161 pl->mac_link_dropped = true; in phylink_mac_change()
1177 * phylink_start() - start a phylink instance
1180 * Start the phylink instance specified by @pl, configuring the MAC for the
1190 phylink_info(pl, "configuring for %s/%s link mode\n", in phylink_start()
1191 phylink_an_mode_str(pl->cur_link_an_mode), in phylink_start()
1192 phy_modes(pl->link_config.interface)); in phylink_start()
1195 if (pl->netdev) in phylink_start()
1196 netif_carrier_off(pl->netdev); in phylink_start()
1199 * a fixed-link to start with the correct parameters, and also in phylink_start()
1200 * ensures that we set the appropriate advertisement for Serdes links. in phylink_start()
1203 * parameters are properly negotiated. This is necessary for DSA in phylink_start()
1208 clear_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); in phylink_start()
1211 if (pl->cfg_link_an_mode == MLO_AN_FIXED && pl->link_gpio) { in phylink_start()
1212 int irq = gpiod_to_irq(pl->link_gpio); in phylink_start()
1219 pl->link_irq = irq; in phylink_start()
1227 switch (pl->cfg_link_an_mode) { in phylink_start()
1229 poll |= pl->config->poll_fixed_state; in phylink_start()
1232 poll |= pl->config->pcs_poll; in phylink_start()
1233 if (pl->pcs) in phylink_start()
1234 poll |= pl->pcs->poll; in phylink_start()
1238 mod_timer(&pl->link_poll, jiffies + HZ); in phylink_start()
1239 if (pl->phydev) in phylink_start()
1240 phy_start(pl->phydev); in phylink_start()
1241 if (pl->sfp_bus) in phylink_start()
1242 sfp_upstream_start(pl->sfp_bus); in phylink_start()
1247 * phylink_stop() - stop a phylink instance
1259 if (pl->sfp_bus) in phylink_stop()
1260 sfp_upstream_stop(pl->sfp_bus); in phylink_stop()
1261 if (pl->phydev) in phylink_stop()
1262 phy_stop(pl->phydev); in phylink_stop()
1263 del_timer_sync(&pl->link_poll); in phylink_stop()
1264 if (pl->link_irq) { in phylink_stop()
1265 free_irq(pl->link_irq, pl); in phylink_stop()
1266 pl->link_irq = 0; in phylink_stop()
1274 * phylink_ethtool_get_wol() - get the wake on lan parameters for the PHY
1278 * Read the wake on lan parameters from the PHY attached to the phylink
1279 * instance specified by @pl. If no PHY is currently attached, report no
1280 * support for wake on lan.
1286 wol->supported = 0; in phylink_ethtool_get_wol()
1287 wol->wolopts = 0; in phylink_ethtool_get_wol()
1289 if (pl->phydev) in phylink_ethtool_get_wol()
1290 phy_ethtool_get_wol(pl->phydev, wol); in phylink_ethtool_get_wol()
1295 * phylink_ethtool_set_wol() - set wake on lan parameters
1297 * @wol: a pointer to &struct ethtool_wolinfo for the desired parameters
1299 * Set the wake on lan parameters for the PHY attached to the phylink
1300 * instance specified by @pl. If no PHY is attached, returns %EOPNOTSUPP
1307 int ret = -EOPNOTSUPP; in phylink_ethtool_set_wol()
1311 if (pl->phydev) in phylink_ethtool_set_wol()
1312 ret = phy_ethtool_set_wol(pl->phydev, wol); in phylink_ethtool_set_wol()
1332 phylink_merge_link_mode(kset->link_modes.advertising, state->advertising); in phylink_get_ksettings()
1333 linkmode_copy(kset->link_modes.lp_advertising, state->lp_advertising); in phylink_get_ksettings()
1334 kset->base.speed = state->speed; in phylink_get_ksettings()
1335 kset->base.duplex = state->duplex; in phylink_get_ksettings()
1336 kset->base.autoneg = state->an_enabled ? AUTONEG_ENABLE : in phylink_get_ksettings()
1341 * phylink_ethtool_ksettings_get() - get the current link settings
1345 * Read the current link settings for the phylink instance specified by @pl.
1346 * This will be the link settings read from the MAC, PHY or fixed link
1356 if (pl->phydev) { in phylink_ethtool_ksettings_get()
1357 phy_ethtool_ksettings_get(pl->phydev, kset); in phylink_ethtool_ksettings_get()
1359 kset->base.port = pl->link_port; in phylink_ethtool_ksettings_get()
1362 linkmode_copy(kset->link_modes.supported, pl->supported); in phylink_ethtool_ksettings_get()
1364 switch (pl->cur_link_an_mode) { in phylink_ethtool_ksettings_get()
1367 * current link settings - and note that these also in phylink_ethtool_ksettings_get()
1375 /* If there is a phy attached, then use the reported in phylink_ethtool_ksettings_get()
1376 * settings from the phy with no modification. in phylink_ethtool_ksettings_get()
1378 if (pl->phydev) in phylink_ethtool_ksettings_get()
1384 * layer via in-band status. Report these as the current in phylink_ethtool_ksettings_get()
1396 * phylink_ethtool_ksettings_set() - set the link settings
1398 * @kset: a pointer to a &struct ethtool_link_ksettings for the desired modes
1409 if (pl->phydev) { in phylink_ethtool_ksettings_set()
1410 /* We can rely on phylib for this update; we also do not need in phylink_ethtool_ksettings_set()
1411 * to update the pl->link_config settings: in phylink_ethtool_ksettings_set()
1412 * - the configuration returned via ksettings_get() will come in phylink_ethtool_ksettings_set()
1413 * from phylib whenever a PHY is present. in phylink_ethtool_ksettings_set()
1414 * - link_config.interface will be updated by the PHY calling in phylink_ethtool_ksettings_set()
1416 * - initial link configuration for PHY mode comes from the in phylink_ethtool_ksettings_set()
1417 * last phy state updated via phylink_phy_change(). in phylink_ethtool_ksettings_set()
1418 * - other configuration changes (e.g. pause modes) are in phylink_ethtool_ksettings_set()
1420 * - if in in-band mode with a PHY, the link configuration in phylink_ethtool_ksettings_set()
1421 * is passed on the link from the PHY, and all of in phylink_ethtool_ksettings_set()
1423 * - the only possible use would be link_config.advertising in phylink_ethtool_ksettings_set()
1424 * pause modes when in 1000base-X mode with a PHY, but in in phylink_ethtool_ksettings_set()
1425 * the presence of a PHY, this should not be changed as that in phylink_ethtool_ksettings_set()
1428 return phy_ethtool_ksettings_set(pl->phydev, kset); in phylink_ethtool_ksettings_set()
1431 linkmode_copy(support, pl->supported); in phylink_ethtool_ksettings_set()
1432 config = pl->link_config; in phylink_ethtool_ksettings_set()
1433 config.an_enabled = kset->base.autoneg == AUTONEG_ENABLE; in phylink_ethtool_ksettings_set()
1436 linkmode_and(config.advertising, kset->link_modes.advertising, in phylink_ethtool_ksettings_set()
1441 /* FIXME: should we reject autoneg if phy/mac does not support it? */ in phylink_ethtool_ksettings_set()
1442 switch (kset->base.autoneg) { in phylink_ethtool_ksettings_set()
1447 s = phy_lookup_setting(kset->base.speed, kset->base.duplex, in phylink_ethtool_ksettings_set()
1450 return -EINVAL; in phylink_ethtool_ksettings_set()
1455 if (pl->cur_link_an_mode == MLO_AN_FIXED) { in phylink_ethtool_ksettings_set()
1456 if (s->speed != pl->link_config.speed || in phylink_ethtool_ksettings_set()
1457 s->duplex != pl->link_config.duplex) in phylink_ethtool_ksettings_set()
1458 return -EINVAL; in phylink_ethtool_ksettings_set()
1462 config.speed = s->speed; in phylink_ethtool_ksettings_set()
1463 config.duplex = s->duplex; in phylink_ethtool_ksettings_set()
1471 if (pl->cur_link_an_mode == MLO_AN_FIXED) { in phylink_ethtool_ksettings_set()
1473 pl->link_config.advertising)) in phylink_ethtool_ksettings_set()
1474 return -EINVAL; in phylink_ethtool_ksettings_set()
1483 return -EINVAL; in phylink_ethtool_ksettings_set()
1486 /* We have ruled out the case with a PHY attached, and the in phylink_ethtool_ksettings_set()
1487 * fixed-link cases. All that is left are in-band links. in phylink_ethtool_ksettings_set()
1490 return -EINVAL; in phylink_ethtool_ksettings_set()
1494 return -EINVAL; in phylink_ethtool_ksettings_set()
1496 mutex_lock(&pl->state_mutex); in phylink_ethtool_ksettings_set()
1497 pl->link_config.speed = config.speed; in phylink_ethtool_ksettings_set()
1498 pl->link_config.duplex = config.duplex; in phylink_ethtool_ksettings_set()
1499 pl->link_config.an_enabled = config.an_enabled; in phylink_ethtool_ksettings_set()
1501 if (pl->link_config.interface != config.interface) { in phylink_ethtool_ksettings_set()
1502 /* The interface changed, e.g. 1000base-X <-> 2500base-X */ in phylink_ethtool_ksettings_set()
1503 /* We need to force the link down, then change the interface */ in phylink_ethtool_ksettings_set()
1504 if (pl->old_link_state) { in phylink_ethtool_ksettings_set()
1506 pl->old_link_state = false; in phylink_ethtool_ksettings_set()
1509 &pl->phylink_disable_state)) in phylink_ethtool_ksettings_set()
1511 pl->link_config.interface = config.interface; in phylink_ethtool_ksettings_set()
1512 linkmode_copy(pl->link_config.advertising, config.advertising); in phylink_ethtool_ksettings_set()
1513 } else if (!linkmode_equal(pl->link_config.advertising, in phylink_ethtool_ksettings_set()
1515 linkmode_copy(pl->link_config.advertising, config.advertising); in phylink_ethtool_ksettings_set()
1518 mutex_unlock(&pl->state_mutex); in phylink_ethtool_ksettings_set()
1525 * phylink_ethtool_nway_reset() - restart negotiation
1528 * Restart negotiation for the phylink instance specified by @pl. This will
1529 * cause any attached phy to restart negotiation with the link partner, and
1541 if (pl->phydev) in phylink_ethtool_nway_reset()
1542 ret = phy_restart_aneg(pl->phydev); in phylink_ethtool_nway_reset()
1550 * phylink_ethtool_get_pauseparam() - get the current pause parameters
1559 pause->autoneg = !!(pl->link_config.pause & MLO_PAUSE_AN); in phylink_ethtool_get_pauseparam()
1560 pause->rx_pause = !!(pl->link_config.pause & MLO_PAUSE_RX); in phylink_ethtool_get_pauseparam()
1561 pause->tx_pause = !!(pl->link_config.pause & MLO_PAUSE_TX); in phylink_ethtool_get_pauseparam()
1566 * phylink_ethtool_set_pauseparam() - set the current pause parameters
1573 struct phylink_link_state *config = &pl->link_config; in phylink_ethtool_set_pauseparam()
1579 if (pl->cur_link_an_mode == MLO_AN_FIXED) in phylink_ethtool_set_pauseparam()
1580 return -EOPNOTSUPP; in phylink_ethtool_set_pauseparam()
1582 if (!phylink_test(pl->supported, Pause) && in phylink_ethtool_set_pauseparam()
1583 !phylink_test(pl->supported, Asym_Pause)) in phylink_ethtool_set_pauseparam()
1584 return -EOPNOTSUPP; in phylink_ethtool_set_pauseparam()
1586 if (!phylink_test(pl->supported, Asym_Pause) && in phylink_ethtool_set_pauseparam()
1587 !pause->autoneg && pause->rx_pause != pause->tx_pause) in phylink_ethtool_set_pauseparam()
1588 return -EINVAL; in phylink_ethtool_set_pauseparam()
1591 if (pause->autoneg) in phylink_ethtool_set_pauseparam()
1593 if (pause->rx_pause) in phylink_ethtool_set_pauseparam()
1595 if (pause->tx_pause) in phylink_ethtool_set_pauseparam()
1598 mutex_lock(&pl->state_mutex); in phylink_ethtool_set_pauseparam()
1600 * See the comments for linkmode_set_pause(), wrt the deficiencies in phylink_ethtool_set_pauseparam()
1612 linkmode_set_pause(config->advertising, pause->tx_pause, in phylink_ethtool_set_pauseparam()
1613 pause->rx_pause); in phylink_ethtool_set_pauseparam()
1615 manual_changed = (config->pause ^ pause_state) & MLO_PAUSE_AN || in phylink_ethtool_set_pauseparam()
1617 (config->pause ^ pause_state) & MLO_PAUSE_TXRX_MASK); in phylink_ethtool_set_pauseparam()
1619 config->pause = pause_state; in phylink_ethtool_set_pauseparam()
1621 /* Update our in-band advertisement, triggering a renegotiation if in phylink_ethtool_set_pauseparam()
1624 if (!pl->phydev) in phylink_ethtool_set_pauseparam()
1627 mutex_unlock(&pl->state_mutex); in phylink_ethtool_set_pauseparam()
1629 /* If we have a PHY, a change of the pause frame advertisement will in phylink_ethtool_set_pauseparam()
1634 if (pl->phydev) in phylink_ethtool_set_pauseparam()
1635 phy_set_asym_pause(pl->phydev, pause->rx_pause, in phylink_ethtool_set_pauseparam()
1636 pause->tx_pause); in phylink_ethtool_set_pauseparam()
1643 pl->mac_link_dropped = true; in phylink_ethtool_set_pauseparam()
1652 * phylink_ethtool_get_eee_err() - read the energy efficient ethernet error
1656 * Read the Energy Efficient Ethernet error counter from the PHY associated
1667 if (pl->phydev) in phylink_get_eee_err()
1668 ret = phy_get_eee_err(pl->phydev); in phylink_get_eee_err()
1675 * phylink_init_eee() - init and check the EEE features
1677 * @clk_stop_enable: allow PHY to stop receive clock
1683 int ret = -EOPNOTSUPP; in phylink_init_eee()
1685 if (pl->phydev) in phylink_init_eee()
1686 ret = phy_init_eee(pl->phydev, clk_stop_enable); in phylink_init_eee()
1693 * phylink_ethtool_get_eee() - read the energy efficient ethernet parameters
1695 * @eee: a pointer to a &struct ethtool_eee for the read parameters
1699 int ret = -EOPNOTSUPP; in phylink_ethtool_get_eee()
1703 if (pl->phydev) in phylink_ethtool_get_eee()
1704 ret = phy_ethtool_get_eee(pl->phydev, eee); in phylink_ethtool_get_eee()
1711 * phylink_ethtool_set_eee() - set the energy efficient ethernet parameters
1713 * @eee: a pointer to a &struct ethtool_eee for the desired parameters
1717 int ret = -EOPNOTSUPP; in phylink_ethtool_set_eee()
1721 if (pl->phydev) in phylink_ethtool_set_eee()
1722 ret = phy_ethtool_set_eee(pl->phydev, eee); in phylink_ethtool_set_eee()
1728 /* This emulates MII registers for a fixed-mode phy operating as per the
1737 unsigned long *lpa = state->lp_advertising; in phylink_mii_emul_read()
1740 fs.link = state->link; in phylink_mii_emul_read()
1741 fs.speed = state->speed; in phylink_mii_emul_read()
1742 fs.duplex = state->duplex; in phylink_mii_emul_read()
1748 if (!state->an_complete) in phylink_mii_emul_read()
1757 struct phy_device *phydev = pl->phydev; in phylink_phy_read()
1764 } else if (phydev->is_c45) { in phylink_phy_read()
1770 devad = __ffs(phydev->c45_ids.mmds_present); in phylink_phy_read()
1774 if (!(phydev->c45_ids.mmds_present & MDIO_DEVS_AN)) in phylink_phy_read()
1775 return -EINVAL; in phylink_phy_read()
1783 return -EINVAL; in phylink_phy_read()
1791 return mdiobus_read(pl->phydev->mdio.bus, prtad, devad); in phylink_phy_read()
1797 struct phy_device *phydev = pl->phydev; in phylink_phy_write()
1804 } else if (phydev->is_c45) { in phylink_phy_write()
1810 devad = __ffs(phydev->c45_ids.mmds_present); in phylink_phy_write()
1814 if (!(phydev->c45_ids.mmds_present & MDIO_DEVS_AN)) in phylink_phy_write()
1815 return -EINVAL; in phylink_phy_write()
1823 return -EINVAL; in phylink_phy_write()
1832 return mdiobus_write(phydev->mdio.bus, prtad, devad, val); in phylink_phy_write()
1841 switch (pl->cur_link_an_mode) { in phylink_mii_read()
1850 return -EOPNOTSUPP; in phylink_mii_read()
1866 switch (pl->cur_link_an_mode) { in phylink_mii_write()
1871 return -EOPNOTSUPP; in phylink_mii_write()
1881 * phylink_mii_ioctl() - generic mii ioctl interface
1883 * @ifr: a pointer to a &struct ifreq for socket ioctls
1886 * Perform the specified MII ioctl on the PHY attached to the phylink instance
1887 * specified by @pl. If no PHY is attached, emulate the presence of the PHY.
1892 * read register from the current PHY.
1894 * read register from the specified PHY.
1896 * set a register on the specified PHY.
1905 if (pl->phydev) { in phylink_mii_ioctl()
1906 /* PHYs only exist for MLO_AN_PHY and SGMII */ in phylink_mii_ioctl()
1909 mii->phy_id = pl->phydev->mdio.addr; in phylink_mii_ioctl()
1913 ret = phylink_phy_read(pl, mii->phy_id, mii->reg_num); in phylink_mii_ioctl()
1915 mii->val_out = ret; in phylink_mii_ioctl()
1921 ret = phylink_phy_write(pl, mii->phy_id, mii->reg_num, in phylink_mii_ioctl()
1922 mii->val_in); in phylink_mii_ioctl()
1926 ret = phy_mii_ioctl(pl->phydev, ifr, cmd); in phylink_mii_ioctl()
1932 mii->phy_id = 0; in phylink_mii_ioctl()
1936 ret = phylink_mii_read(pl, mii->phy_id, mii->reg_num); in phylink_mii_ioctl()
1938 mii->val_out = ret; in phylink_mii_ioctl()
1944 ret = phylink_mii_write(pl, mii->phy_id, mii->reg_num, in phylink_mii_ioctl()
1945 mii->val_in); in phylink_mii_ioctl()
1949 ret = -EOPNOTSUPP; in phylink_mii_ioctl()
1959 * phylink_speed_down() - set the non-SFP PHY to lowest speed supported by both
1964 * If we have a PHY that is not part of a SFP module, then set the speed
1966 * for a description of the @sync parameter.
1968 * Returns zero if there is no PHY, otherwise as per phy_speed_down().
1976 if (!pl->sfp_bus && pl->phydev) in phylink_speed_down()
1977 ret = phy_speed_down(pl->phydev, sync); in phylink_speed_down()
1984 * phylink_speed_up() - restore the advertised speeds prior to the call to
1988 * If we have a PHY that is not part of a SFP module, then restore the
1989 * PHY speeds as per phy_speed_up().
1991 * Returns zero if there is no PHY, otherwise as per phy_speed_up().
1999 if (!pl->sfp_bus && pl->phydev) in phylink_speed_up()
2000 ret = phy_speed_up(pl->phydev); in phylink_speed_up()
2010 pl->netdev->sfp_bus = bus; in phylink_sfp_attach()
2017 pl->netdev->sfp_bus = NULL; in phylink_sfp_detach()
2039 config.an_enabled = pl->link_config.an_enabled; in phylink_sfp_config()
2041 /* Ignore errors if we're expecting a PHY to attach later */ in phylink_sfp_config()
2049 iface = sfp_select_interface(pl->sfp_bus, config.advertising); in phylink_sfp_config()
2054 return -EINVAL; in phylink_sfp_config()
2072 if (phy_interface_mode_is_8023z(iface) && pl->phydev) in phylink_sfp_config()
2073 return -EINVAL; in phylink_sfp_config()
2075 changed = !linkmode_equal(pl->supported, support); in phylink_sfp_config()
2077 linkmode_copy(pl->supported, support); in phylink_sfp_config()
2078 linkmode_copy(pl->link_config.advertising, config.advertising); in phylink_sfp_config()
2081 if (pl->cur_link_an_mode != mode || in phylink_sfp_config()
2082 pl->link_config.interface != config.interface) { in phylink_sfp_config()
2083 pl->link_config.interface = config.interface; in phylink_sfp_config()
2084 pl->cur_link_an_mode = mode; in phylink_sfp_config()
2093 pl->link_port = pl->sfp_port; in phylink_sfp_config()
2096 &pl->phylink_disable_state)) in phylink_sfp_config()
2106 unsigned long *support = pl->sfp_support; in phylink_sfp_module_insert()
2111 sfp_parse_support(pl->sfp_bus, id, support); in phylink_sfp_module_insert()
2112 pl->sfp_port = sfp_parse_port(pl->sfp_bus, id, support); in phylink_sfp_module_insert()
2114 /* If this module may have a PHY connecting later, defer until later */ in phylink_sfp_module_insert()
2115 pl->sfp_may_have_phy = sfp_may_have_phy(pl->sfp_bus, id); in phylink_sfp_module_insert()
2116 if (pl->sfp_may_have_phy) in phylink_sfp_module_insert()
2126 /* If this SFP module has a PHY, start the PHY now. */ in phylink_sfp_module_start()
2127 if (pl->phydev) { in phylink_sfp_module_start()
2128 phy_start(pl->phydev); in phylink_sfp_module_start()
2132 /* If the module may have a PHY but we didn't detect one we in phylink_sfp_module_start()
2133 * need to configure the MAC here. in phylink_sfp_module_start()
2135 if (!pl->sfp_may_have_phy) in phylink_sfp_module_start()
2139 pl->sfp_support, pl->sfp_support); in phylink_sfp_module_start()
2146 /* If this SFP module has a PHY, stop it. */ in phylink_sfp_module_stop()
2147 if (pl->phydev) in phylink_sfp_module_stop()
2148 phy_stop(pl->phydev); in phylink_sfp_module_stop()
2166 clear_bit(PHYLINK_DISABLE_LINK, &pl->phylink_disable_state); in phylink_sfp_link_up()
2173 static bool phylink_phy_no_inband(struct phy_device *phy) in phylink_phy_no_inband() argument
2175 return phy->is_c45 && in phylink_phy_no_inband()
2176 (phy->c45_ids.device_ids[1] & 0xfffffff0) == 0xae025150; in phylink_phy_no_inband()
2179 static int phylink_sfp_connect_phy(void *upstream, struct phy_device *phy) in phylink_sfp_connect_phy() argument
2187 * This is the new way of dealing with flow control for PHYs, in phylink_sfp_connect_phy()
2188 * as described by Timur Tabi in commit 529ed1275263 ("net: phy: in phylink_sfp_connect_phy()
2189 * phy drivers should not set SUPPORTED_[Asym_]Pause") except in phylink_sfp_connect_phy()
2193 phy_support_asym_pause(phy); in phylink_sfp_connect_phy()
2195 if (phylink_phy_no_inband(phy)) in phylink_sfp_connect_phy()
2201 ret = phylink_sfp_config(pl, mode, phy->supported, phy->advertising); in phylink_sfp_connect_phy()
2205 interface = pl->link_config.interface; in phylink_sfp_connect_phy()
2206 ret = phylink_attach_phy(pl, phy, interface); in phylink_sfp_connect_phy()
2210 ret = phylink_bringup_phy(pl, phy, interface); in phylink_sfp_connect_phy()
2212 phy_detach(phy); in phylink_sfp_connect_phy()
2234 /* Helpers for MAC drivers */
2237 * phylink_helper_basex_speed() - 1000BaseX/2500BaseX helper
2242 * the interface mode to suit. @state->interface is appropriately
2248 if (phy_interface_mode_is_8023z(state->interface)) { in phylink_helper_basex_speed()
2249 bool want_2500 = state->an_enabled ? in phylink_helper_basex_speed()
2250 phylink_test(state->advertising, 2500baseX_Full) : in phylink_helper_basex_speed()
2251 state->speed == SPEED_2500; in phylink_helper_basex_speed()
2254 phylink_clear(state->advertising, 1000baseX_Full); in phylink_helper_basex_speed()
2255 state->interface = PHY_INTERFACE_MODE_2500BASEX; in phylink_helper_basex_speed()
2257 phylink_clear(state->advertising, 2500baseX_Full); in phylink_helper_basex_speed()
2258 state->interface = PHY_INTERFACE_MODE_1000BASEX; in phylink_helper_basex_speed()
2275 mii_lpa_mod_linkmode_x(state->lp_advertising, config_reg, fd_bit); in phylink_decode_c37_word()
2277 if (linkmode_test_bit(fd_bit, state->advertising) && in phylink_decode_c37_word()
2278 linkmode_test_bit(fd_bit, state->lp_advertising)) { in phylink_decode_c37_word()
2279 state->speed = speed; in phylink_decode_c37_word()
2280 state->duplex = DUPLEX_FULL; in phylink_decode_c37_word()
2283 state->link = false; in phylink_decode_c37_word()
2286 linkmode_resolve_pause(state->advertising, state->lp_advertising, in phylink_decode_c37_word()
2290 state->pause |= MLO_PAUSE_TX; in phylink_decode_c37_word()
2292 state->pause |= MLO_PAUSE_RX; in phylink_decode_c37_word()
2299 state->link = false; in phylink_decode_sgmii_word()
2305 state->speed = SPEED_10; in phylink_decode_sgmii_word()
2308 state->speed = SPEED_100; in phylink_decode_sgmii_word()
2311 state->speed = SPEED_1000; in phylink_decode_sgmii_word()
2314 state->link = false; in phylink_decode_sgmii_word()
2318 state->duplex = DUPLEX_FULL; in phylink_decode_sgmii_word()
2320 state->duplex = DUPLEX_HALF; in phylink_decode_sgmii_word()
2324 * phylink_decode_usxgmii_word() - decode the USXGMII word from a MAC PCS
2326 * @lpa: a 16 bit value which stores the USXGMII auto-negotiation word
2328 * Helper for MAC PCS supporting the USXGMII protocol and the auto-negotiation
2337 state->speed = SPEED_10; in phylink_decode_usxgmii_word()
2340 state->speed = SPEED_100; in phylink_decode_usxgmii_word()
2343 state->speed = SPEED_1000; in phylink_decode_usxgmii_word()
2346 state->speed = SPEED_2500; in phylink_decode_usxgmii_word()
2349 state->speed = SPEED_5000; in phylink_decode_usxgmii_word()
2352 state->speed = SPEED_10000; in phylink_decode_usxgmii_word()
2355 state->link = false; in phylink_decode_usxgmii_word()
2360 state->duplex = DUPLEX_FULL; in phylink_decode_usxgmii_word()
2362 state->duplex = DUPLEX_HALF; in phylink_decode_usxgmii_word()
2367 * phylink_mii_c22_pcs_get_state() - read the MAC PCS state
2371 * Helper for MAC PCS supporting the 802.3 clause 22 register set for
2383 struct mii_bus *bus = pcs->bus; in phylink_mii_c22_pcs_get_state()
2384 int addr = pcs->addr; in phylink_mii_c22_pcs_get_state()
2390 state->link = false; in phylink_mii_c22_pcs_get_state()
2394 state->link = !!(bmsr & BMSR_LSTATUS); in phylink_mii_c22_pcs_get_state()
2395 state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE); in phylink_mii_c22_pcs_get_state()
2396 if (!state->link) in phylink_mii_c22_pcs_get_state()
2399 switch (state->interface) { in phylink_mii_c22_pcs_get_state()
2414 state->link = false; in phylink_mii_c22_pcs_get_state()
2421 * phylink_mii_c22_pcs_set_advertisement() - configure the clause 37 PCS
2424 * @interface: the PHY interface mode being configured
2427 * Helper for MAC PCS supporting the 802.3 clause 22 register set for
2441 struct mii_bus *bus = pcs->bus; in phylink_mii_c22_pcs_set_advertisement()
2442 int addr = pcs->addr; in phylink_mii_c22_pcs_set_advertisement()
2485 /* Nothing to do for other modes */ in phylink_mii_c22_pcs_set_advertisement()
2492 * phylink_mii_c22_pcs_config() - configure clause 22 PCS
2495 * @interface: the PHY interface mode being configured
2498 * Configure a Clause 22 PCS PHY with the appropriate negotiation
2499 * parameters for the @mode, @interface and @advertising parameters.
2519 ret = mdiobus_modify(pcs->bus, pcs->addr, MII_BMCR, in phylink_mii_c22_pcs_config()
2529 * phylink_mii_c22_pcs_an_restart() - restart 802.3z autonegotiation
2532 * Helper for MAC PCS supporting the 802.3 clause 22 register set for
2541 struct mii_bus *bus = pcs->bus; in phylink_mii_c22_pcs_an_restart()
2542 int val, addr = pcs->addr; in phylink_mii_c22_pcs_an_restart()
2556 struct mii_bus *bus = pcs->bus; in phylink_mii_c45_pcs_get_state()
2557 int addr = pcs->addr; in phylink_mii_c45_pcs_get_state()
2562 state->link = false; in phylink_mii_c45_pcs_get_state()
2566 state->link = !!(stat & MDIO_STAT1_LSTATUS); in phylink_mii_c45_pcs_get_state()
2567 if (!state->link) in phylink_mii_c45_pcs_get_state()
2570 switch (state->interface) { in phylink_mii_c45_pcs_get_state()
2572 state->speed = SPEED_10000; in phylink_mii_c45_pcs_get_state()
2573 state->duplex = DUPLEX_FULL; in phylink_mii_c45_pcs_get_state()