Lines Matching +full:asym +full:- +full:pause

1 // SPDX-License-Identifier: GPL-2.0
4 * technologies such as SFP cages where the PHY is hot-pluggable.
38 * struct phylink - internal data type for phylink
52 u8 link_port; /* The current non-phy ethtool port */
78 if ((pl)->config->type == PHYLINK_NETDEV) \
79 netdev_printk(level, (pl)->netdev, fmt, ##__VA_ARGS__); \
80 else if ((pl)->config->type == PHYLINK_DEV) \
81 dev_printk(level, (pl)->dev, fmt, ##__VA_ARGS__); \
93 if ((pl)->config->type == PHYLINK_NETDEV) \
94 netdev_dbg((pl)->netdev, fmt, ##__VA_ARGS__); \
95 else if ((pl)->config->type == PHYLINK_DEV) \
96 dev_dbg((pl)->dev, fmt, ##__VA_ARGS__); \
110 * phylink_set_port_modes() - set the port type modes in the ethtool mask
133 phylink_set(tmp, Pause); in phylink_is_empty_linkmode()
155 pl->ops->validate(pl->config, supported, state); in phylink_validate()
157 return phylink_is_empty_linkmode(supported) ? -EINVAL : 0; in phylink_validate()
169 fixed_node = fwnode_get_named_child_node(fwnode, "fixed-link"); in phylink_parse_fixedlink()
173 pl->link_config.speed = speed; in phylink_parse_fixedlink()
174 pl->link_config.duplex = DUPLEX_HALF; in phylink_parse_fixedlink()
176 if (fwnode_property_read_bool(fixed_node, "full-duplex")) in phylink_parse_fixedlink()
177 pl->link_config.duplex = DUPLEX_FULL; in phylink_parse_fixedlink()
179 /* We treat the "pause" and "asym-pause" terminology as in phylink_parse_fixedlink()
181 if (fwnode_property_read_bool(fixed_node, "pause")) in phylink_parse_fixedlink()
182 pl->link_config.pause |= MLO_PAUSE_SYM; in phylink_parse_fixedlink()
183 if (fwnode_property_read_bool(fixed_node, "asym-pause")) in phylink_parse_fixedlink()
184 pl->link_config.pause |= MLO_PAUSE_ASYM; in phylink_parse_fixedlink()
187 desc = fwnode_get_named_gpiod(fixed_node, "link-gpios", in phylink_parse_fixedlink()
191 pl->link_gpio = desc; in phylink_parse_fixedlink()
192 else if (desc == ERR_PTR(-EPROBE_DEFER)) in phylink_parse_fixedlink()
193 ret = -EPROBE_DEFER; in phylink_parse_fixedlink()
202 ret = fwnode_property_read_u32_array(fwnode, "fixed-link", in phylink_parse_fixedlink()
205 phylink_err(pl, "broken fixed-link?\n"); in phylink_parse_fixedlink()
206 return -EINVAL; in phylink_parse_fixedlink()
209 ret = fwnode_property_read_u32_array(fwnode, "fixed-link", in phylink_parse_fixedlink()
212 pl->link_config.duplex = prop[1] ? in phylink_parse_fixedlink()
214 pl->link_config.speed = prop[2]; in phylink_parse_fixedlink()
216 pl->link_config.pause |= MLO_PAUSE_SYM; in phylink_parse_fixedlink()
218 pl->link_config.pause |= MLO_PAUSE_ASYM; in phylink_parse_fixedlink()
222 if (pl->link_config.speed > SPEED_1000 && in phylink_parse_fixedlink()
223 pl->link_config.duplex != DUPLEX_FULL) in phylink_parse_fixedlink()
225 pl->link_config.speed); in phylink_parse_fixedlink()
227 bitmap_fill(pl->supported, __ETHTOOL_LINK_MODE_MASK_NBITS); in phylink_parse_fixedlink()
228 linkmode_copy(pl->link_config.advertising, pl->supported); in phylink_parse_fixedlink()
229 phylink_validate(pl, pl->supported, &pl->link_config); in phylink_parse_fixedlink()
231 s = phy_lookup_setting(pl->link_config.speed, pl->link_config.duplex, in phylink_parse_fixedlink()
232 pl->supported, true); in phylink_parse_fixedlink()
233 linkmode_zero(pl->supported); in phylink_parse_fixedlink()
234 phylink_set(pl->supported, MII); in phylink_parse_fixedlink()
235 phylink_set(pl->supported, Pause); in phylink_parse_fixedlink()
236 phylink_set(pl->supported, Asym_Pause); in phylink_parse_fixedlink()
238 __set_bit(s->bit, pl->supported); in phylink_parse_fixedlink()
241 pl->link_config.duplex == DUPLEX_FULL ? "full" : "half", in phylink_parse_fixedlink()
242 pl->link_config.speed); in phylink_parse_fixedlink()
245 linkmode_and(pl->link_config.advertising, pl->link_config.advertising, in phylink_parse_fixedlink()
246 pl->supported); in phylink_parse_fixedlink()
248 pl->link_config.link = 1; in phylink_parse_fixedlink()
249 pl->link_config.an_complete = 1; in phylink_parse_fixedlink()
259 dn = fwnode_get_named_child_node(fwnode, "fixed-link"); in phylink_parse_mode()
260 if (dn || fwnode_property_present(fwnode, "fixed-link")) in phylink_parse_mode()
261 pl->link_an_mode = MLO_AN_FIXED; in phylink_parse_mode()
265 strcmp(managed, "in-band-status") == 0) { in phylink_parse_mode()
266 if (pl->link_an_mode == MLO_AN_FIXED) { in phylink_parse_mode()
268 "can't use both fixed-link and in-band-status\n"); in phylink_parse_mode()
269 return -EINVAL; in phylink_parse_mode()
272 linkmode_zero(pl->supported); in phylink_parse_mode()
273 phylink_set(pl->supported, MII); in phylink_parse_mode()
274 phylink_set(pl->supported, Autoneg); in phylink_parse_mode()
275 phylink_set(pl->supported, Asym_Pause); in phylink_parse_mode()
276 phylink_set(pl->supported, Pause); in phylink_parse_mode()
277 pl->link_config.an_enabled = true; in phylink_parse_mode()
278 pl->link_an_mode = MLO_AN_INBAND; in phylink_parse_mode()
280 switch (pl->link_config.interface) { in phylink_parse_mode()
282 phylink_set(pl->supported, 10baseT_Half); in phylink_parse_mode()
283 phylink_set(pl->supported, 10baseT_Full); in phylink_parse_mode()
284 phylink_set(pl->supported, 100baseT_Half); in phylink_parse_mode()
285 phylink_set(pl->supported, 100baseT_Full); in phylink_parse_mode()
286 phylink_set(pl->supported, 1000baseT_Half); in phylink_parse_mode()
287 phylink_set(pl->supported, 1000baseT_Full); in phylink_parse_mode()
291 phylink_set(pl->supported, 1000baseX_Full); in phylink_parse_mode()
295 phylink_set(pl->supported, 2500baseX_Full); in phylink_parse_mode()
299 phylink_set(pl->supported, 10baseT_Half); in phylink_parse_mode()
300 phylink_set(pl->supported, 10baseT_Full); in phylink_parse_mode()
301 phylink_set(pl->supported, 100baseT_Half); in phylink_parse_mode()
302 phylink_set(pl->supported, 100baseT_Full); in phylink_parse_mode()
303 phylink_set(pl->supported, 1000baseT_Half); in phylink_parse_mode()
304 phylink_set(pl->supported, 1000baseT_Full); in phylink_parse_mode()
305 phylink_set(pl->supported, 1000baseX_Full); in phylink_parse_mode()
306 phylink_set(pl->supported, 10000baseKR_Full); in phylink_parse_mode()
307 phylink_set(pl->supported, 10000baseCR_Full); in phylink_parse_mode()
308 phylink_set(pl->supported, 10000baseSR_Full); in phylink_parse_mode()
309 phylink_set(pl->supported, 10000baseLR_Full); in phylink_parse_mode()
310 phylink_set(pl->supported, 10000baseLRM_Full); in phylink_parse_mode()
311 phylink_set(pl->supported, 10000baseER_Full); in phylink_parse_mode()
316 "incorrect link mode %s for in-band status\n", in phylink_parse_mode()
317 phy_modes(pl->link_config.interface)); in phylink_parse_mode()
318 return -EINVAL; in phylink_parse_mode()
321 linkmode_copy(pl->link_config.advertising, pl->supported); in phylink_parse_mode()
323 if (phylink_validate(pl, pl->supported, &pl->link_config)) { in phylink_parse_mode()
325 "failed to validate link configuration for in-band status\n"); in phylink_parse_mode()
326 return -EINVAL; in phylink_parse_mode()
337 "%s: mode=%s/%s/%s/%s adv=%*pb pause=%02x link=%u an=%u\n", in phylink_mac_config()
338 __func__, phylink_an_mode_str(pl->link_an_mode), in phylink_mac_config()
339 phy_modes(state->interface), in phylink_mac_config()
340 phy_speed_to_str(state->speed), in phylink_mac_config()
341 phy_duplex_to_str(state->duplex), in phylink_mac_config()
342 __ETHTOOL_LINK_MODE_MASK_NBITS, state->advertising, in phylink_mac_config()
343 state->pause, state->link, state->an_enabled); in phylink_mac_config()
345 pl->ops->mac_config(pl->config, pl->link_an_mode, state); in phylink_mac_config()
351 if (state->link) in phylink_mac_config_up()
357 if (pl->link_config.an_enabled && in phylink_mac_an_restart()
358 phy_interface_mode_is_8023z(pl->link_config.interface)) in phylink_mac_an_restart()
359 pl->ops->mac_an_restart(pl->config); in phylink_mac_an_restart()
365 linkmode_copy(state->advertising, pl->link_config.advertising); in phylink_get_mac_state()
366 linkmode_zero(state->lp_advertising); in phylink_get_mac_state()
367 state->interface = pl->link_config.interface; in phylink_get_mac_state()
368 state->an_enabled = pl->link_config.an_enabled; in phylink_get_mac_state()
369 state->speed = SPEED_UNKNOWN; in phylink_get_mac_state()
370 state->duplex = DUPLEX_UNKNOWN; in phylink_get_mac_state()
371 state->pause = MLO_PAUSE_NONE; in phylink_get_mac_state()
372 state->an_complete = 0; in phylink_get_mac_state()
373 state->link = 1; in phylink_get_mac_state()
375 return pl->ops->mac_link_state(pl->config, state); in phylink_get_mac_state()
383 *state = pl->link_config; in phylink_get_fixed_state()
384 if (pl->get_fixed_state) in phylink_get_fixed_state()
385 pl->get_fixed_state(pl->netdev, state); in phylink_get_fixed_state()
386 else if (pl->link_gpio) in phylink_get_fixed_state()
387 state->link = !!gpiod_get_value_cansleep(pl->link_gpio); in phylink_get_fixed_state()
393 * Pause AsymDir Pause AsymDir Result
403 if (pl->link_config.pause & MLO_PAUSE_AN) { in phylink_resolve_flow()
404 int pause = 0; in phylink_resolve_flow() local
406 if (phylink_test(pl->link_config.advertising, Pause)) in phylink_resolve_flow()
407 pause |= MLO_PAUSE_SYM; in phylink_resolve_flow()
408 if (phylink_test(pl->link_config.advertising, Asym_Pause)) in phylink_resolve_flow()
409 pause |= MLO_PAUSE_ASYM; in phylink_resolve_flow()
411 pause &= state->pause; in phylink_resolve_flow()
413 if (pause & MLO_PAUSE_SYM) in phylink_resolve_flow()
415 else if (pause & MLO_PAUSE_ASYM) in phylink_resolve_flow()
416 new_pause = state->pause & MLO_PAUSE_SYM ? in phylink_resolve_flow()
419 new_pause = pl->link_config.pause & MLO_PAUSE_TXRX_MASK; in phylink_resolve_flow()
422 state->pause &= ~MLO_PAUSE_TXRX_MASK; in phylink_resolve_flow()
423 state->pause |= new_pause; in phylink_resolve_flow()
426 static const char *phylink_pause_to_str(int pause) in phylink_pause_to_str() argument
428 switch (pause & MLO_PAUSE_TXRX_MASK) { in phylink_pause_to_str()
443 struct net_device *ndev = pl->netdev; in phylink_mac_link_up()
445 pl->cur_interface = link_state.interface; in phylink_mac_link_up()
446 pl->ops->mac_link_up(pl->config, pl->link_an_mode, in phylink_mac_link_up()
447 pl->phy_state.interface, in phylink_mac_link_up()
448 pl->phydev); in phylink_mac_link_up()
454 "Link is Up - %s/%s - flow control %s\n", in phylink_mac_link_up()
457 phylink_pause_to_str(link_state.pause)); in phylink_mac_link_up()
462 struct net_device *ndev = pl->netdev; in phylink_mac_link_down()
466 pl->ops->mac_link_down(pl->config, pl->link_an_mode, in phylink_mac_link_down()
467 pl->cur_interface); in phylink_mac_link_down()
475 struct net_device *ndev = pl->netdev; in phylink_resolve()
478 mutex_lock(&pl->state_mutex); in phylink_resolve()
479 if (pl->phylink_disable_state) { in phylink_resolve()
480 pl->mac_link_dropped = false; in phylink_resolve()
482 } else if (pl->mac_link_dropped) { in phylink_resolve()
485 switch (pl->link_an_mode) { in phylink_resolve()
487 link_state = pl->phy_state; in phylink_resolve()
502 if (pl->phydev) in phylink_resolve()
503 link_state.link &= pl->phy_state.link; in phylink_resolve()
506 if (pl->phydev && pl->phy_state.link) { in phylink_resolve()
507 link_state.interface = pl->phy_state.interface; in phylink_resolve()
510 * the pause mode bits. */ in phylink_resolve()
511 link_state.pause |= pl->phy_state.pause; in phylink_resolve()
519 if (pl->netdev) in phylink_resolve()
522 link_changed = (link_state.link != pl->old_link_state); in phylink_resolve()
525 pl->old_link_state = link_state.link; in phylink_resolve()
531 if (!link_state.link && pl->mac_link_dropped) { in phylink_resolve()
532 pl->mac_link_dropped = false; in phylink_resolve()
533 queue_work(system_power_efficient_wq, &pl->resolve); in phylink_resolve()
535 mutex_unlock(&pl->state_mutex); in phylink_resolve()
540 if (!pl->phylink_disable_state) in phylink_run_resolve()
541 queue_work(system_power_efficient_wq, &pl->resolve); in phylink_run_resolve()
546 unsigned long state = pl->phylink_disable_state; in phylink_run_resolve_and_disable()
548 set_bit(bit, &pl->phylink_disable_state); in phylink_run_resolve_and_disable()
550 queue_work(system_power_efficient_wq, &pl->resolve); in phylink_run_resolve_and_disable()
551 flush_work(&pl->resolve); in phylink_run_resolve_and_disable()
578 if (ret == -ENOENT) in phylink_register_sfp()
586 pl->sfp_bus = sfp_register_upstream(ref.fwnode, pl, &sfp_phylink_ops); in phylink_register_sfp()
587 if (!pl->sfp_bus) in phylink_register_sfp()
588 return -ENOMEM; in phylink_register_sfp()
594 * phylink_create() - create a phylink instance
602 * This will parse in-band modes, fixed-link or SFP configuration.
606 * Returns a pointer to a &struct phylink, or an error-pointer value. Users
619 return ERR_PTR(-ENOMEM); in phylink_create()
621 mutex_init(&pl->state_mutex); in phylink_create()
622 INIT_WORK(&pl->resolve, phylink_resolve); in phylink_create()
624 pl->config = config; in phylink_create()
625 if (config->type == PHYLINK_NETDEV) { in phylink_create()
626 pl->netdev = to_net_dev(config->dev); in phylink_create()
627 } else if (config->type == PHYLINK_DEV) { in phylink_create()
628 pl->dev = config->dev; in phylink_create()
631 return ERR_PTR(-EINVAL); in phylink_create()
634 pl->phy_state.interface = iface; in phylink_create()
635 pl->link_interface = iface; in phylink_create()
637 pl->link_port = PORT_BNC; in phylink_create()
639 pl->link_port = PORT_MII; in phylink_create()
640 pl->link_config.interface = iface; in phylink_create()
641 pl->link_config.pause = MLO_PAUSE_AN; in phylink_create()
642 pl->link_config.speed = SPEED_UNKNOWN; in phylink_create()
643 pl->link_config.duplex = DUPLEX_UNKNOWN; in phylink_create()
644 pl->link_config.an_enabled = true; in phylink_create()
645 pl->ops = ops; in phylink_create()
646 __set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); in phylink_create()
647 timer_setup(&pl->link_poll, phylink_fixed_poll, 0); in phylink_create()
649 bitmap_fill(pl->supported, __ETHTOOL_LINK_MODE_MASK_NBITS); in phylink_create()
650 linkmode_copy(pl->link_config.advertising, pl->supported); in phylink_create()
651 phylink_validate(pl, pl->supported, &pl->link_config); in phylink_create()
659 if (pl->link_an_mode == MLO_AN_FIXED) { in phylink_create()
678 * phylink_destroy() - cleanup and destroy the phylink instance
688 if (pl->sfp_bus) in phylink_destroy()
689 sfp_unregister_upstream(pl->sfp_bus); in phylink_destroy()
690 if (pl->link_gpio) in phylink_destroy()
691 gpiod_put(pl->link_gpio); in phylink_destroy()
693 cancel_work_sync(&pl->resolve); in phylink_destroy()
701 struct phylink *pl = phydev->phylink; in phylink_phy_change()
703 mutex_lock(&pl->state_mutex); in phylink_phy_change()
704 pl->phy_state.speed = phydev->speed; in phylink_phy_change()
705 pl->phy_state.duplex = phydev->duplex; in phylink_phy_change()
706 pl->phy_state.pause = MLO_PAUSE_NONE; in phylink_phy_change()
707 if (phydev->pause) in phylink_phy_change()
708 pl->phy_state.pause |= MLO_PAUSE_SYM; in phylink_phy_change()
709 if (phydev->asym_pause) in phylink_phy_change()
710 pl->phy_state.pause |= MLO_PAUSE_ASYM; in phylink_phy_change()
711 pl->phy_state.interface = phydev->interface; in phylink_phy_change()
712 pl->phy_state.link = up; in phylink_phy_change()
713 mutex_unlock(&pl->state_mutex); in phylink_phy_change()
718 phy_modes(phydev->interface), in phylink_phy_change()
719 phy_speed_to_str(phydev->speed), in phylink_phy_change()
720 phy_duplex_to_str(phydev->duplex)); in phylink_phy_change()
730 linkmode_copy(supported, phy->supported); in phylink_bringup_phy()
731 linkmode_copy(config.advertising, phy->advertising); in phylink_bringup_phy()
732 config.interface = pl->link_config.interface; in phylink_bringup_phy()
737 * phy drivers should not set SUPPORTED_[Asym_]Pause") except in phylink_bringup_phy()
741 if (phylink_test(supported, Pause)) in phylink_bringup_phy()
742 phylink_set(config.advertising, Pause); in phylink_bringup_phy()
750 phy->phylink = pl; in phylink_bringup_phy()
751 phy->phy_link_change = phylink_phy_change; in phylink_bringup_phy()
754 "PHY [%s] driver [%s]\n", dev_name(&phy->mdio.dev), in phylink_bringup_phy()
755 phy->drv->name); in phylink_bringup_phy()
757 mutex_lock(&phy->lock); in phylink_bringup_phy()
758 mutex_lock(&pl->state_mutex); in phylink_bringup_phy()
759 pl->phydev = phy; in phylink_bringup_phy()
760 linkmode_copy(pl->supported, supported); in phylink_bringup_phy()
761 linkmode_copy(pl->link_config.advertising, config.advertising); in phylink_bringup_phy()
764 linkmode_copy(phy->advertising, config.advertising); in phylink_bringup_phy()
765 mutex_unlock(&pl->state_mutex); in phylink_bringup_phy()
766 mutex_unlock(&phy->lock); in phylink_bringup_phy()
770 __ETHTOOL_LINK_MODE_MASK_NBITS, pl->supported, in phylink_bringup_phy()
771 __ETHTOOL_LINK_MODE_MASK_NBITS, phy->advertising); in phylink_bringup_phy()
784 if (WARN_ON(pl->link_an_mode == MLO_AN_FIXED || in __phylink_connect_phy()
785 (pl->link_an_mode == MLO_AN_INBAND && in __phylink_connect_phy()
787 return -EINVAL; in __phylink_connect_phy()
789 if (pl->phydev) in __phylink_connect_phy()
790 return -EBUSY; in __phylink_connect_phy()
792 ret = phy_attach_direct(pl->netdev, phy, 0, interface); in __phylink_connect_phy()
804 * phylink_connect_phy() - connect a PHY to the phylink instance
821 if (pl->link_interface == PHY_INTERFACE_MODE_NA) { in phylink_connect_phy()
822 pl->link_interface = phy->interface; in phylink_connect_phy()
823 pl->link_config.interface = pl->link_interface; in phylink_connect_phy()
826 return __phylink_connect_phy(pl, phy, pl->link_interface); in phylink_connect_phy()
831 * phylink_of_phy_connect() - connect the PHY specified in the DT mode.
834 * @flags: PHY-specific flags to communicate to the PHY device driver
850 if (pl->link_an_mode == MLO_AN_FIXED || in phylink_of_phy_connect()
851 (pl->link_an_mode == MLO_AN_INBAND && in phylink_of_phy_connect()
852 phy_interface_mode_is_8023z(pl->link_interface))) in phylink_of_phy_connect()
855 phy_node = of_parse_phandle(dn, "phy-handle", 0); in phylink_of_phy_connect()
859 phy_node = of_parse_phandle(dn, "phy-device", 0); in phylink_of_phy_connect()
862 if (pl->link_an_mode == MLO_AN_PHY) in phylink_of_phy_connect()
863 return -ENODEV; in phylink_of_phy_connect()
867 phy_dev = of_phy_attach(pl->netdev, phy_node, flags, in phylink_of_phy_connect()
868 pl->link_interface); in phylink_of_phy_connect()
873 return -ENODEV; in phylink_of_phy_connect()
884 * phylink_disconnect_phy() - disconnect any PHY attached to the phylink
896 phy = pl->phydev; in phylink_disconnect_phy()
898 mutex_lock(&phy->lock); in phylink_disconnect_phy()
899 mutex_lock(&pl->state_mutex); in phylink_disconnect_phy()
900 pl->phydev = NULL; in phylink_disconnect_phy()
901 mutex_unlock(&pl->state_mutex); in phylink_disconnect_phy()
902 mutex_unlock(&phy->lock); in phylink_disconnect_phy()
903 flush_work(&pl->resolve); in phylink_disconnect_phy()
911 * phylink_fixed_state_cb() - allow setting a fixed link callback
925 if (pl->link_an_mode != MLO_AN_FIXED) in phylink_fixed_state_cb()
926 return -EINVAL; in phylink_fixed_state_cb()
928 mutex_lock(&pl->state_mutex); in phylink_fixed_state_cb()
929 pl->get_fixed_state = cb; in phylink_fixed_state_cb()
930 mutex_unlock(&pl->state_mutex); in phylink_fixed_state_cb()
937 * phylink_mac_change() - notify phylink of a change in MAC state
947 pl->mac_link_dropped = true; in phylink_mac_change()
963 * phylink_start() - start a phylink instance
975 phylink_an_mode_str(pl->link_an_mode), in phylink_start()
976 phy_modes(pl->link_config.interface)); in phylink_start()
979 if (pl->netdev) in phylink_start()
980 netif_carrier_off(pl->netdev); in phylink_start()
983 * a fixed-link to start with the correct parameters, and also in phylink_start()
986 phylink_resolve_flow(pl, &pl->link_config); in phylink_start()
987 phylink_mac_config(pl, &pl->link_config); in phylink_start()
995 clear_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); in phylink_start()
998 if (pl->link_an_mode == MLO_AN_FIXED && pl->link_gpio) { in phylink_start()
999 int irq = gpiod_to_irq(pl->link_gpio); in phylink_start()
1006 pl->link_irq = irq; in phylink_start()
1011 mod_timer(&pl->link_poll, jiffies + HZ); in phylink_start()
1013 if (pl->link_an_mode == MLO_AN_FIXED && pl->get_fixed_state) in phylink_start()
1014 mod_timer(&pl->link_poll, jiffies + HZ); in phylink_start()
1015 if (pl->phydev) in phylink_start()
1016 phy_start(pl->phydev); in phylink_start()
1017 if (pl->sfp_bus) in phylink_start()
1018 sfp_upstream_start(pl->sfp_bus); in phylink_start()
1023 * phylink_stop() - stop a phylink instance
1035 if (pl->sfp_bus) in phylink_stop()
1036 sfp_upstream_stop(pl->sfp_bus); in phylink_stop()
1037 if (pl->phydev) in phylink_stop()
1038 phy_stop(pl->phydev); in phylink_stop()
1039 del_timer_sync(&pl->link_poll); in phylink_stop()
1040 if (pl->link_irq) { in phylink_stop()
1041 free_irq(pl->link_irq, pl); in phylink_stop()
1042 pl->link_irq = 0; in phylink_stop()
1050 * phylink_ethtool_get_wol() - get the wake on lan parameters for the PHY
1062 wol->supported = 0; in phylink_ethtool_get_wol()
1063 wol->wolopts = 0; in phylink_ethtool_get_wol()
1065 if (pl->phydev) in phylink_ethtool_get_wol()
1066 phy_ethtool_get_wol(pl->phydev, wol); in phylink_ethtool_get_wol()
1071 * phylink_ethtool_set_wol() - set wake on lan parameters
1083 int ret = -EOPNOTSUPP; in phylink_ethtool_set_wol()
1087 if (pl->phydev) in phylink_ethtool_set_wol()
1088 ret = phy_ethtool_set_wol(pl->phydev, wol); in phylink_ethtool_set_wol()
1108 phylink_merge_link_mode(kset->link_modes.advertising, state->advertising); in phylink_get_ksettings()
1109 linkmode_copy(kset->link_modes.lp_advertising, state->lp_advertising); in phylink_get_ksettings()
1110 kset->base.speed = state->speed; in phylink_get_ksettings()
1111 kset->base.duplex = state->duplex; in phylink_get_ksettings()
1112 kset->base.autoneg = state->an_enabled ? AUTONEG_ENABLE : in phylink_get_ksettings()
1117 * phylink_ethtool_ksettings_get() - get the current link settings
1132 if (pl->phydev) { in phylink_ethtool_ksettings_get()
1133 phy_ethtool_ksettings_get(pl->phydev, kset); in phylink_ethtool_ksettings_get()
1135 kset->base.port = pl->link_port; in phylink_ethtool_ksettings_get()
1138 linkmode_copy(kset->link_modes.supported, pl->supported); in phylink_ethtool_ksettings_get()
1140 switch (pl->link_an_mode) { in phylink_ethtool_ksettings_get()
1143 * current link settings - and note that these also in phylink_ethtool_ksettings_get()
1144 * represent the supported speeds/duplex/pause modes. in phylink_ethtool_ksettings_get()
1154 if (pl->phydev) in phylink_ethtool_ksettings_get()
1160 * layer via in-band status. Report these as the current in phylink_ethtool_ksettings_get()
1172 * phylink_ethtool_ksettings_set() - set the link settings
1186 if (kset->base.autoneg != AUTONEG_DISABLE && in phylink_ethtool_ksettings_set()
1187 kset->base.autoneg != AUTONEG_ENABLE) in phylink_ethtool_ksettings_set()
1188 return -EINVAL; in phylink_ethtool_ksettings_set()
1190 linkmode_copy(support, pl->supported); in phylink_ethtool_ksettings_set()
1191 config = pl->link_config; in phylink_ethtool_ksettings_set()
1194 linkmode_and(config.advertising, kset->link_modes.advertising, in phylink_ethtool_ksettings_set()
1198 if (kset->base.autoneg == AUTONEG_DISABLE) { in phylink_ethtool_ksettings_set()
1204 s = phy_lookup_setting(kset->base.speed, kset->base.duplex, in phylink_ethtool_ksettings_set()
1207 return -EINVAL; in phylink_ethtool_ksettings_set()
1212 if (pl->link_an_mode == MLO_AN_FIXED && in phylink_ethtool_ksettings_set()
1213 (s->speed != pl->link_config.speed || in phylink_ethtool_ksettings_set()
1214 s->duplex != pl->link_config.duplex)) in phylink_ethtool_ksettings_set()
1215 return -EINVAL; in phylink_ethtool_ksettings_set()
1217 config.speed = s->speed; in phylink_ethtool_ksettings_set()
1218 config.duplex = s->duplex; in phylink_ethtool_ksettings_set()
1224 if (pl->link_an_mode == MLO_AN_FIXED) in phylink_ethtool_ksettings_set()
1225 return -EINVAL; in phylink_ethtool_ksettings_set()
1235 return -EINVAL; in phylink_ethtool_ksettings_set()
1239 return -EINVAL; in phylink_ethtool_ksettings_set()
1247 if (pl->phydev) { in phylink_ethtool_ksettings_set()
1248 ret = phy_ethtool_ksettings_set(pl->phydev, &our_kset); in phylink_ethtool_ksettings_set()
1253 mutex_lock(&pl->state_mutex); in phylink_ethtool_ksettings_set()
1255 linkmode_copy(pl->link_config.advertising, our_kset.link_modes.advertising); in phylink_ethtool_ksettings_set()
1256 pl->link_config.interface = config.interface; in phylink_ethtool_ksettings_set()
1257 pl->link_config.speed = our_kset.base.speed; in phylink_ethtool_ksettings_set()
1258 pl->link_config.duplex = our_kset.base.duplex; in phylink_ethtool_ksettings_set()
1259 pl->link_config.an_enabled = our_kset.base.autoneg != AUTONEG_DISABLE; in phylink_ethtool_ksettings_set()
1266 if (pl->link_an_mode == MLO_AN_INBAND && in phylink_ethtool_ksettings_set()
1267 !test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) { in phylink_ethtool_ksettings_set()
1268 phylink_mac_config(pl, &pl->link_config); in phylink_ethtool_ksettings_set()
1271 mutex_unlock(&pl->state_mutex); in phylink_ethtool_ksettings_set()
1278 * phylink_ethtool_nway_reset() - restart negotiation
1294 if (pl->phydev) in phylink_ethtool_nway_reset()
1295 ret = phy_restart_aneg(pl->phydev); in phylink_ethtool_nway_reset()
1303 * phylink_ethtool_get_pauseparam() - get the current pause parameters
1305 * @pause: a pointer to a &struct ethtool_pauseparam
1308 struct ethtool_pauseparam *pause) in phylink_ethtool_get_pauseparam() argument
1312 pause->autoneg = !!(pl->link_config.pause & MLO_PAUSE_AN); in phylink_ethtool_get_pauseparam()
1313 pause->rx_pause = !!(pl->link_config.pause & MLO_PAUSE_RX); in phylink_ethtool_get_pauseparam()
1314 pause->tx_pause = !!(pl->link_config.pause & MLO_PAUSE_TX); in phylink_ethtool_get_pauseparam()
1319 * phylink_ethtool_set_pauseparam() - set the current pause parameters
1321 * @pause: a pointer to a &struct ethtool_pauseparam
1324 struct ethtool_pauseparam *pause) in phylink_ethtool_set_pauseparam() argument
1326 struct phylink_link_state *config = &pl->link_config; in phylink_ethtool_set_pauseparam()
1330 if (!phylink_test(pl->supported, Pause) && in phylink_ethtool_set_pauseparam()
1331 !phylink_test(pl->supported, Asym_Pause)) in phylink_ethtool_set_pauseparam()
1332 return -EOPNOTSUPP; in phylink_ethtool_set_pauseparam()
1334 if (!phylink_test(pl->supported, Asym_Pause) && in phylink_ethtool_set_pauseparam()
1335 !pause->autoneg && pause->rx_pause != pause->tx_pause) in phylink_ethtool_set_pauseparam()
1336 return -EINVAL; in phylink_ethtool_set_pauseparam()
1338 config->pause &= ~(MLO_PAUSE_AN | MLO_PAUSE_TXRX_MASK); in phylink_ethtool_set_pauseparam()
1340 if (pause->autoneg) in phylink_ethtool_set_pauseparam()
1341 config->pause |= MLO_PAUSE_AN; in phylink_ethtool_set_pauseparam()
1342 if (pause->rx_pause) in phylink_ethtool_set_pauseparam()
1343 config->pause |= MLO_PAUSE_RX; in phylink_ethtool_set_pauseparam()
1344 if (pause->tx_pause) in phylink_ethtool_set_pauseparam()
1345 config->pause |= MLO_PAUSE_TX; in phylink_ethtool_set_pauseparam()
1351 if (pl->phydev) { in phylink_ethtool_set_pauseparam()
1352 phy_set_asym_pause(pl->phydev, pause->rx_pause, in phylink_ethtool_set_pauseparam()
1353 pause->tx_pause); in phylink_ethtool_set_pauseparam()
1355 &pl->phylink_disable_state)) { in phylink_ethtool_set_pauseparam()
1356 switch (pl->link_an_mode) { in phylink_ethtool_set_pauseparam()
1375 * phylink_ethtool_get_eee_err() - read the energy efficient ethernet error
1390 if (pl->phydev) in phylink_get_eee_err()
1391 ret = phy_get_eee_err(pl->phydev); in phylink_get_eee_err()
1398 * phylink_init_eee() - init and check the EEE features
1406 int ret = -EOPNOTSUPP; in phylink_init_eee()
1408 if (pl->phydev) in phylink_init_eee()
1409 ret = phy_init_eee(pl->phydev, clk_stop_enable); in phylink_init_eee()
1416 * phylink_ethtool_get_eee() - read the energy efficient ethernet parameters
1422 int ret = -EOPNOTSUPP; in phylink_ethtool_get_eee()
1426 if (pl->phydev) in phylink_ethtool_get_eee()
1427 ret = phy_ethtool_get_eee(pl->phydev, eee); in phylink_ethtool_get_eee()
1434 * phylink_ethtool_set_eee() - set the energy efficient ethernet parameters
1440 int ret = -EOPNOTSUPP; in phylink_ethtool_set_eee()
1444 if (pl->phydev) in phylink_ethtool_set_eee()
1445 ret = phy_ethtool_set_eee(pl->phydev, eee); in phylink_ethtool_set_eee()
1451 /* This emulates MII registers for a fixed-mode phy operating as per the
1462 fs.link = state->link; in phylink_mii_emul_read()
1463 fs.speed = state->speed; in phylink_mii_emul_read()
1464 fs.duplex = state->duplex; in phylink_mii_emul_read()
1465 fs.pause = state->pause & MLO_PAUSE_SYM; in phylink_mii_emul_read()
1466 fs.asym_pause = state->pause & MLO_PAUSE_ASYM; in phylink_mii_emul_read()
1470 if (!state->an_complete) in phylink_mii_emul_read()
1479 struct phy_device *phydev = pl->phydev; in phylink_phy_read()
1486 } else if (phydev->is_c45) { in phylink_phy_read()
1492 devad = __ffs(phydev->c45_ids.devices_in_package); in phylink_phy_read()
1496 if (!(phydev->c45_ids.devices_in_package & MDIO_DEVS_AN)) in phylink_phy_read()
1497 return -EINVAL; in phylink_phy_read()
1505 return -EINVAL; in phylink_phy_read()
1513 return mdiobus_read(pl->phydev->mdio.bus, prtad, devad); in phylink_phy_read()
1519 struct phy_device *phydev = pl->phydev; in phylink_phy_write()
1526 } else if (phydev->is_c45) { in phylink_phy_write()
1532 devad = __ffs(phydev->c45_ids.devices_in_package); in phylink_phy_write()
1536 if (!(phydev->c45_ids.devices_in_package & MDIO_DEVS_AN)) in phylink_phy_write()
1537 return -EINVAL; in phylink_phy_write()
1545 return -EINVAL; in phylink_phy_write()
1554 return mdiobus_write(phydev->mdio.bus, prtad, devad, val); in phylink_phy_write()
1563 switch (pl->link_an_mode) { in phylink_mii_read()
1572 return -EOPNOTSUPP; in phylink_mii_read()
1591 switch (pl->link_an_mode) { in phylink_mii_write()
1596 return -EOPNOTSUPP; in phylink_mii_write()
1606 * phylink_mii_ioctl() - generic mii ioctl interface
1630 if (pl->phydev) { in phylink_mii_ioctl()
1634 mii->phy_id = pl->phydev->mdio.addr; in phylink_mii_ioctl()
1638 ret = phylink_phy_read(pl, mii->phy_id, mii->reg_num); in phylink_mii_ioctl()
1640 mii->val_out = ret; in phylink_mii_ioctl()
1646 ret = phylink_phy_write(pl, mii->phy_id, mii->reg_num, in phylink_mii_ioctl()
1647 mii->val_in); in phylink_mii_ioctl()
1651 ret = phy_mii_ioctl(pl->phydev, ifr, cmd); in phylink_mii_ioctl()
1657 mii->phy_id = 0; in phylink_mii_ioctl()
1661 ret = phylink_mii_read(pl, mii->phy_id, mii->reg_num); in phylink_mii_ioctl()
1663 mii->val_out = ret; in phylink_mii_ioctl()
1669 ret = phylink_mii_write(pl, mii->phy_id, mii->reg_num, in phylink_mii_ioctl()
1670 mii->val_in); in phylink_mii_ioctl()
1674 ret = -EOPNOTSUPP; in phylink_mii_ioctl()
1687 pl->netdev->sfp_bus = bus; in phylink_sfp_attach()
1694 pl->netdev->sfp_bus = NULL; in phylink_sfp_detach()
1711 sfp_parse_support(pl->sfp_bus, id, support); in phylink_sfp_module_insert()
1712 port = sfp_parse_port(pl->sfp_bus, id, support); in phylink_sfp_module_insert()
1719 config.pause = MLO_PAUSE_AN; in phylink_sfp_module_insert()
1720 config.an_enabled = pl->link_config.an_enabled; in phylink_sfp_module_insert()
1732 iface = sfp_select_interface(pl->sfp_bus, id, config.advertising); in phylink_sfp_module_insert()
1737 return -EINVAL; in phylink_sfp_module_insert()
1755 if (phy_interface_mode_is_8023z(iface) && pl->phydev) in phylink_sfp_module_insert()
1756 return -EINVAL; in phylink_sfp_module_insert()
1758 changed = !bitmap_equal(pl->supported, support, in phylink_sfp_module_insert()
1761 linkmode_copy(pl->supported, support); in phylink_sfp_module_insert()
1762 linkmode_copy(pl->link_config.advertising, config.advertising); in phylink_sfp_module_insert()
1765 if (pl->link_an_mode != MLO_AN_INBAND || in phylink_sfp_module_insert()
1766 pl->link_config.interface != config.interface) { in phylink_sfp_module_insert()
1767 pl->link_config.interface = config.interface; in phylink_sfp_module_insert()
1768 pl->link_an_mode = MLO_AN_INBAND; in phylink_sfp_module_insert()
1777 pl->link_port = port; in phylink_sfp_module_insert()
1780 &pl->phylink_disable_state)) in phylink_sfp_module_insert()
1781 phylink_mac_config(pl, &pl->link_config); in phylink_sfp_module_insert()
1801 clear_bit(PHYLINK_DISABLE_LINK, &pl->phylink_disable_state); in phylink_sfp_link_up()
1809 return __phylink_connect_phy(upstream, phy, pl->link_config.interface); in phylink_sfp_connect_phy()
1830 * phylink_helper_basex_speed() - 1000BaseX/2500BaseX helper
1835 * the interface mode to suit. @state->interface is appropriately
1841 if (phy_interface_mode_is_8023z(state->interface)) { in phylink_helper_basex_speed()
1842 bool want_2500 = state->an_enabled ? in phylink_helper_basex_speed()
1843 phylink_test(state->advertising, 2500baseX_Full) : in phylink_helper_basex_speed()
1844 state->speed == SPEED_2500; in phylink_helper_basex_speed()
1847 phylink_clear(state->advertising, 1000baseX_Full); in phylink_helper_basex_speed()
1848 state->interface = PHY_INTERFACE_MODE_2500BASEX; in phylink_helper_basex_speed()
1850 phylink_clear(state->advertising, 2500baseX_Full); in phylink_helper_basex_speed()
1851 state->interface = PHY_INTERFACE_MODE_1000BASEX; in phylink_helper_basex_speed()