Lines Matching +full:asym +full:- +full:pause
3 * technologies such as SFP cages where the PHY is hot-pluggable.
41 * struct phylink - internal data type for phylink
52 u8 link_port; /* The current non-phy ethtool port */
103 * phylink_set_port_modes() - set the port type modes in the ethtool mask
126 phylink_set(tmp, Pause); in phylink_is_empty_linkmode()
148 pl->ops->validate(pl->netdev, supported, state); in phylink_validate()
150 return phylink_is_empty_linkmode(supported) ? -EINVAL : 0; in phylink_validate()
162 fixed_node = fwnode_get_named_child_node(fwnode, "fixed-link"); in phylink_parse_fixedlink()
166 pl->link_config.speed = speed; in phylink_parse_fixedlink()
167 pl->link_config.duplex = DUPLEX_HALF; in phylink_parse_fixedlink()
169 if (fwnode_property_read_bool(fixed_node, "full-duplex")) in phylink_parse_fixedlink()
170 pl->link_config.duplex = DUPLEX_FULL; in phylink_parse_fixedlink()
172 /* We treat the "pause" and "asym-pause" terminology as in phylink_parse_fixedlink()
174 if (fwnode_property_read_bool(fixed_node, "pause")) in phylink_parse_fixedlink()
175 pl->link_config.pause |= MLO_PAUSE_SYM; in phylink_parse_fixedlink()
176 if (fwnode_property_read_bool(fixed_node, "asym-pause")) in phylink_parse_fixedlink()
177 pl->link_config.pause |= MLO_PAUSE_ASYM; in phylink_parse_fixedlink()
180 desc = fwnode_get_named_gpiod(fixed_node, "link-gpios", in phylink_parse_fixedlink()
184 pl->link_gpio = desc; in phylink_parse_fixedlink()
185 else if (desc == ERR_PTR(-EPROBE_DEFER)) in phylink_parse_fixedlink()
186 ret = -EPROBE_DEFER; in phylink_parse_fixedlink()
195 ret = fwnode_property_read_u32_array(fwnode, "fixed-link", in phylink_parse_fixedlink()
198 netdev_err(pl->netdev, "broken fixed-link?\n"); in phylink_parse_fixedlink()
199 return -EINVAL; in phylink_parse_fixedlink()
202 ret = fwnode_property_read_u32_array(fwnode, "fixed-link", in phylink_parse_fixedlink()
205 pl->link_config.duplex = prop[1] ? in phylink_parse_fixedlink()
207 pl->link_config.speed = prop[2]; in phylink_parse_fixedlink()
209 pl->link_config.pause |= MLO_PAUSE_SYM; in phylink_parse_fixedlink()
211 pl->link_config.pause |= MLO_PAUSE_ASYM; in phylink_parse_fixedlink()
215 if (pl->link_config.speed > SPEED_1000 && in phylink_parse_fixedlink()
216 pl->link_config.duplex != DUPLEX_FULL) in phylink_parse_fixedlink()
217 netdev_warn(pl->netdev, "fixed link specifies half duplex for %dMbps link?\n", in phylink_parse_fixedlink()
218 pl->link_config.speed); in phylink_parse_fixedlink()
220 bitmap_fill(pl->supported, __ETHTOOL_LINK_MODE_MASK_NBITS); in phylink_parse_fixedlink()
221 linkmode_copy(pl->link_config.advertising, pl->supported); in phylink_parse_fixedlink()
222 phylink_validate(pl, pl->supported, &pl->link_config); in phylink_parse_fixedlink()
224 s = phy_lookup_setting(pl->link_config.speed, pl->link_config.duplex, in phylink_parse_fixedlink()
225 pl->supported, in phylink_parse_fixedlink()
227 linkmode_zero(pl->supported); in phylink_parse_fixedlink()
228 phylink_set(pl->supported, MII); in phylink_parse_fixedlink()
229 phylink_set(pl->supported, Pause); in phylink_parse_fixedlink()
230 phylink_set(pl->supported, Asym_Pause); in phylink_parse_fixedlink()
232 __set_bit(s->bit, pl->supported); in phylink_parse_fixedlink()
234 netdev_warn(pl->netdev, "fixed link %s duplex %dMbps not recognised\n", in phylink_parse_fixedlink()
235 pl->link_config.duplex == DUPLEX_FULL ? "full" : "half", in phylink_parse_fixedlink()
236 pl->link_config.speed); in phylink_parse_fixedlink()
239 linkmode_and(pl->link_config.advertising, pl->link_config.advertising, in phylink_parse_fixedlink()
240 pl->supported); in phylink_parse_fixedlink()
242 pl->link_config.link = 1; in phylink_parse_fixedlink()
243 pl->link_config.an_complete = 1; in phylink_parse_fixedlink()
253 dn = fwnode_get_named_child_node(fwnode, "fixed-link"); in phylink_parse_mode()
254 if (dn || fwnode_property_present(fwnode, "fixed-link")) in phylink_parse_mode()
255 pl->link_an_mode = MLO_AN_FIXED; in phylink_parse_mode()
259 strcmp(managed, "in-band-status") == 0) { in phylink_parse_mode()
260 if (pl->link_an_mode == MLO_AN_FIXED) { in phylink_parse_mode()
261 netdev_err(pl->netdev, in phylink_parse_mode()
262 "can't use both fixed-link and in-band-status\n"); in phylink_parse_mode()
263 return -EINVAL; in phylink_parse_mode()
266 linkmode_zero(pl->supported); in phylink_parse_mode()
267 phylink_set(pl->supported, MII); in phylink_parse_mode()
268 phylink_set(pl->supported, Autoneg); in phylink_parse_mode()
269 phylink_set(pl->supported, Asym_Pause); in phylink_parse_mode()
270 phylink_set(pl->supported, Pause); in phylink_parse_mode()
271 pl->link_config.an_enabled = true; in phylink_parse_mode()
272 pl->link_an_mode = MLO_AN_INBAND; in phylink_parse_mode()
274 switch (pl->link_config.interface) { in phylink_parse_mode()
276 phylink_set(pl->supported, 10baseT_Half); in phylink_parse_mode()
277 phylink_set(pl->supported, 10baseT_Full); in phylink_parse_mode()
278 phylink_set(pl->supported, 100baseT_Half); in phylink_parse_mode()
279 phylink_set(pl->supported, 100baseT_Full); in phylink_parse_mode()
280 phylink_set(pl->supported, 1000baseT_Half); in phylink_parse_mode()
281 phylink_set(pl->supported, 1000baseT_Full); in phylink_parse_mode()
285 phylink_set(pl->supported, 1000baseX_Full); in phylink_parse_mode()
289 phylink_set(pl->supported, 2500baseX_Full); 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()
299 phylink_set(pl->supported, 1000baseX_Full); in phylink_parse_mode()
300 phylink_set(pl->supported, 10000baseKR_Full); in phylink_parse_mode()
301 phylink_set(pl->supported, 10000baseCR_Full); in phylink_parse_mode()
302 phylink_set(pl->supported, 10000baseSR_Full); in phylink_parse_mode()
303 phylink_set(pl->supported, 10000baseLR_Full); in phylink_parse_mode()
304 phylink_set(pl->supported, 10000baseLRM_Full); in phylink_parse_mode()
305 phylink_set(pl->supported, 10000baseER_Full); in phylink_parse_mode()
309 netdev_err(pl->netdev, in phylink_parse_mode()
310 "incorrect link mode %s for in-band status\n", in phylink_parse_mode()
311 phy_modes(pl->link_config.interface)); in phylink_parse_mode()
312 return -EINVAL; in phylink_parse_mode()
315 linkmode_copy(pl->link_config.advertising, pl->supported); in phylink_parse_mode()
317 if (phylink_validate(pl, pl->supported, &pl->link_config)) { in phylink_parse_mode()
318 netdev_err(pl->netdev, in phylink_parse_mode()
319 "failed to validate link configuration for in-band status\n"); in phylink_parse_mode()
320 return -EINVAL; in phylink_parse_mode()
330 netdev_dbg(pl->netdev, in phylink_mac_config()
331 "%s: mode=%s/%s/%s/%s adv=%*pb pause=%02x link=%u an=%u\n", in phylink_mac_config()
332 __func__, phylink_an_mode_str(pl->link_an_mode), in phylink_mac_config()
333 phy_modes(state->interface), in phylink_mac_config()
334 phy_speed_to_str(state->speed), in phylink_mac_config()
335 phy_duplex_to_str(state->duplex), in phylink_mac_config()
336 __ETHTOOL_LINK_MODE_MASK_NBITS, state->advertising, in phylink_mac_config()
337 state->pause, state->link, state->an_enabled); in phylink_mac_config()
339 pl->ops->mac_config(pl->netdev, pl->link_an_mode, state); in phylink_mac_config()
344 if (pl->link_config.an_enabled && in phylink_mac_an_restart()
345 phy_interface_mode_is_8023z(pl->link_config.interface)) in phylink_mac_an_restart()
346 pl->ops->mac_an_restart(pl->netdev); in phylink_mac_an_restart()
351 struct net_device *ndev = pl->netdev; in phylink_get_mac_state()
353 linkmode_copy(state->advertising, pl->link_config.advertising); in phylink_get_mac_state()
354 linkmode_zero(state->lp_advertising); in phylink_get_mac_state()
355 state->interface = pl->link_config.interface; in phylink_get_mac_state()
356 state->an_enabled = pl->link_config.an_enabled; in phylink_get_mac_state()
357 state->speed = SPEED_UNKNOWN; in phylink_get_mac_state()
358 state->duplex = DUPLEX_UNKNOWN; in phylink_get_mac_state()
359 state->pause = MLO_PAUSE_NONE; in phylink_get_mac_state()
360 state->an_complete = 0; in phylink_get_mac_state()
361 state->link = 1; in phylink_get_mac_state()
363 return pl->ops->mac_link_state(ndev, state); in phylink_get_mac_state()
371 *state = pl->link_config; in phylink_get_fixed_state()
372 if (pl->get_fixed_state) in phylink_get_fixed_state()
373 pl->get_fixed_state(pl->netdev, state); in phylink_get_fixed_state()
374 else if (pl->link_gpio) in phylink_get_fixed_state()
375 state->link = !!gpiod_get_value_cansleep(pl->link_gpio); in phylink_get_fixed_state()
381 * Pause AsymDir Pause AsymDir Result
391 if (pl->link_config.pause & MLO_PAUSE_AN) { in phylink_resolve_flow()
392 int pause = 0; in phylink_resolve_flow() local
394 if (phylink_test(pl->link_config.advertising, Pause)) in phylink_resolve_flow()
395 pause |= MLO_PAUSE_SYM; in phylink_resolve_flow()
396 if (phylink_test(pl->link_config.advertising, Asym_Pause)) in phylink_resolve_flow()
397 pause |= MLO_PAUSE_ASYM; in phylink_resolve_flow()
399 pause &= state->pause; in phylink_resolve_flow()
401 if (pause & MLO_PAUSE_SYM) in phylink_resolve_flow()
403 else if (pause & MLO_PAUSE_ASYM) in phylink_resolve_flow()
404 new_pause = state->pause & MLO_PAUSE_SYM ? in phylink_resolve_flow()
407 new_pause = pl->link_config.pause & MLO_PAUSE_TXRX_MASK; in phylink_resolve_flow()
410 state->pause &= ~MLO_PAUSE_TXRX_MASK; in phylink_resolve_flow()
411 state->pause |= new_pause; in phylink_resolve_flow()
414 static const char *phylink_pause_to_str(int pause) in phylink_pause_to_str() argument
416 switch (pause & MLO_PAUSE_TXRX_MASK) { in phylink_pause_to_str()
432 struct net_device *ndev = pl->netdev; in phylink_resolve()
434 mutex_lock(&pl->state_mutex); in phylink_resolve()
435 if (pl->phylink_disable_state) { in phylink_resolve()
436 pl->mac_link_dropped = false; in phylink_resolve()
438 } else if (pl->mac_link_dropped) { in phylink_resolve()
441 switch (pl->link_an_mode) { in phylink_resolve()
443 link_state = pl->phy_state; in phylink_resolve()
455 if (pl->phydev) { in phylink_resolve()
459 pl->phy_state.link; in phylink_resolve()
461 if (pl->phy_state.interface != in phylink_resolve()
463 link_state.interface = pl->phy_state.interface; in phylink_resolve()
471 if (pl->phy_state.link || changed) { in phylink_resolve()
472 link_state.pause |= pl->phy_state.pause; in phylink_resolve()
485 pl->ops->mac_link_down(ndev, pl->link_an_mode, in phylink_resolve()
486 pl->cur_interface); in phylink_resolve()
489 pl->cur_interface = link_state.interface; in phylink_resolve()
490 pl->ops->mac_link_up(ndev, pl->link_an_mode, in phylink_resolve()
491 pl->cur_interface, pl->phydev); in phylink_resolve()
496 "Link is Up - %s/%s - flow control %s\n", in phylink_resolve()
499 phylink_pause_to_str(link_state.pause)); in phylink_resolve()
502 if (!link_state.link && pl->mac_link_dropped) { in phylink_resolve()
503 pl->mac_link_dropped = false; in phylink_resolve()
504 queue_work(system_power_efficient_wq, &pl->resolve); in phylink_resolve()
506 mutex_unlock(&pl->state_mutex); in phylink_resolve()
511 if (!pl->phylink_disable_state) in phylink_run_resolve()
512 queue_work(system_power_efficient_wq, &pl->resolve); in phylink_run_resolve()
517 unsigned long state = pl->phylink_disable_state; in phylink_run_resolve_and_disable()
519 set_bit(bit, &pl->phylink_disable_state); in phylink_run_resolve_and_disable()
521 queue_work(system_power_efficient_wq, &pl->resolve); in phylink_run_resolve_and_disable()
522 flush_work(&pl->resolve); in phylink_run_resolve_and_disable()
549 if (ret == -ENOENT) in phylink_register_sfp()
552 netdev_err(pl->netdev, "unable to parse \"sfp\" node: %d\n", in phylink_register_sfp()
557 pl->sfp_bus = sfp_register_upstream(ref.fwnode, pl->netdev, pl, in phylink_register_sfp()
559 if (!pl->sfp_bus) in phylink_register_sfp()
560 return -ENOMEM; in phylink_register_sfp()
566 * phylink_create() - create a phylink instance
574 * This will parse in-band modes, fixed-link or SFP configuration.
576 * Returns a pointer to a &struct phylink, or an error-pointer value. Users
589 return ERR_PTR(-ENOMEM); in phylink_create()
591 mutex_init(&pl->state_mutex); in phylink_create()
592 INIT_WORK(&pl->resolve, phylink_resolve); in phylink_create()
593 pl->netdev = ndev; in phylink_create()
594 pl->phy_state.interface = iface; in phylink_create()
595 pl->link_interface = iface; in phylink_create()
597 pl->link_port = PORT_BNC; in phylink_create()
599 pl->link_port = PORT_MII; in phylink_create()
600 pl->link_config.interface = iface; in phylink_create()
601 pl->link_config.pause = MLO_PAUSE_AN; in phylink_create()
602 pl->link_config.speed = SPEED_UNKNOWN; in phylink_create()
603 pl->link_config.duplex = DUPLEX_UNKNOWN; in phylink_create()
604 pl->link_config.an_enabled = true; in phylink_create()
605 pl->ops = ops; in phylink_create()
606 __set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); in phylink_create()
607 timer_setup(&pl->link_poll, phylink_fixed_poll, 0); in phylink_create()
609 bitmap_fill(pl->supported, __ETHTOOL_LINK_MODE_MASK_NBITS); in phylink_create()
610 linkmode_copy(pl->link_config.advertising, pl->supported); in phylink_create()
611 phylink_validate(pl, pl->supported, &pl->link_config); in phylink_create()
619 if (pl->link_an_mode == MLO_AN_FIXED) { in phylink_create()
638 * phylink_destroy() - cleanup and destroy the phylink instance
646 if (pl->sfp_bus) in phylink_destroy()
647 sfp_unregister_upstream(pl->sfp_bus); in phylink_destroy()
648 if (!IS_ERR_OR_NULL(pl->link_gpio)) in phylink_destroy()
649 gpiod_put(pl->link_gpio); in phylink_destroy()
651 cancel_work_sync(&pl->resolve); in phylink_destroy()
659 struct phylink *pl = phydev->phylink; in phylink_phy_change()
661 mutex_lock(&pl->state_mutex); in phylink_phy_change()
662 pl->phy_state.speed = phydev->speed; in phylink_phy_change()
663 pl->phy_state.duplex = phydev->duplex; in phylink_phy_change()
664 pl->phy_state.pause = MLO_PAUSE_NONE; in phylink_phy_change()
665 if (phydev->pause) in phylink_phy_change()
666 pl->phy_state.pause |= MLO_PAUSE_SYM; in phylink_phy_change()
667 if (phydev->asym_pause) in phylink_phy_change()
668 pl->phy_state.pause |= MLO_PAUSE_ASYM; in phylink_phy_change()
669 pl->phy_state.interface = phydev->interface; in phylink_phy_change()
670 pl->phy_state.link = up; in phylink_phy_change()
671 mutex_unlock(&pl->state_mutex); in phylink_phy_change()
675 netdev_dbg(pl->netdev, "phy link %s %s/%s/%s\n", up ? "up" : "down", in phylink_phy_change()
676 phy_modes(phydev->interface), in phylink_phy_change()
677 phy_speed_to_str(phydev->speed), in phylink_phy_change()
678 phy_duplex_to_str(phydev->duplex)); in phylink_phy_change()
689 ethtool_convert_legacy_u32_to_link_mode(supported, phy->supported); in phylink_bringup_phy()
691 phy->advertising); in phylink_bringup_phy()
692 config.interface = pl->link_config.interface; in phylink_bringup_phy()
697 * phy drivers should not set SUPPORTED_[Asym_]Pause") except in phylink_bringup_phy()
701 if (phylink_test(supported, Pause)) in phylink_bringup_phy()
702 phylink_set(config.advertising, Pause); in phylink_bringup_phy()
710 phy->phylink = pl; in phylink_bringup_phy()
711 phy->phy_link_change = phylink_phy_change; in phylink_bringup_phy()
713 netdev_info(pl->netdev, in phylink_bringup_phy()
714 "PHY [%s] driver [%s]\n", dev_name(&phy->mdio.dev), in phylink_bringup_phy()
715 phy->drv->name); in phylink_bringup_phy()
717 mutex_lock(&phy->lock); in phylink_bringup_phy()
718 mutex_lock(&pl->state_mutex); in phylink_bringup_phy()
719 pl->phydev = phy; in phylink_bringup_phy()
720 linkmode_copy(pl->supported, supported); in phylink_bringup_phy()
721 linkmode_copy(pl->link_config.advertising, config.advertising); in phylink_bringup_phy()
725 phy->advertising = advertising; in phylink_bringup_phy()
726 mutex_unlock(&pl->state_mutex); in phylink_bringup_phy()
727 mutex_unlock(&phy->lock); in phylink_bringup_phy()
729 netdev_dbg(pl->netdev, in phylink_bringup_phy()
731 __ETHTOOL_LINK_MODE_MASK_NBITS, pl->supported, in phylink_bringup_phy()
732 phy->advertising); in phylink_bringup_phy()
735 if (phy->irq > 0) in phylink_bringup_phy()
746 if (WARN_ON(pl->link_an_mode == MLO_AN_FIXED || in __phylink_connect_phy()
747 (pl->link_an_mode == MLO_AN_INBAND && in __phylink_connect_phy()
749 return -EINVAL; in __phylink_connect_phy()
751 if (pl->phydev) in __phylink_connect_phy()
752 return -EBUSY; in __phylink_connect_phy()
754 ret = phy_attach_direct(pl->netdev, phy, 0, interface); in __phylink_connect_phy()
766 * phylink_connect_phy() - connect a PHY to the phylink instance
783 if (pl->link_interface == PHY_INTERFACE_MODE_NA) { in phylink_connect_phy()
784 pl->link_interface = phy->interface; in phylink_connect_phy()
785 pl->link_config.interface = pl->link_interface; in phylink_connect_phy()
788 return __phylink_connect_phy(pl, phy, pl->link_interface); in phylink_connect_phy()
793 * phylink_of_phy_connect() - connect the PHY specified in the DT mode.
796 * @flags: PHY-specific flags to communicate to the PHY device driver
812 if (pl->link_an_mode == MLO_AN_FIXED || in phylink_of_phy_connect()
813 (pl->link_an_mode == MLO_AN_INBAND && in phylink_of_phy_connect()
814 phy_interface_mode_is_8023z(pl->link_interface))) in phylink_of_phy_connect()
817 phy_node = of_parse_phandle(dn, "phy-handle", 0); in phylink_of_phy_connect()
821 phy_node = of_parse_phandle(dn, "phy-device", 0); in phylink_of_phy_connect()
824 if (pl->link_an_mode == MLO_AN_PHY) in phylink_of_phy_connect()
825 return -ENODEV; in phylink_of_phy_connect()
829 phy_dev = of_phy_attach(pl->netdev, phy_node, flags, in phylink_of_phy_connect()
830 pl->link_interface); in phylink_of_phy_connect()
835 return -ENODEV; in phylink_of_phy_connect()
846 * phylink_disconnect_phy() - disconnect any PHY attached to the phylink
858 phy = pl->phydev; in phylink_disconnect_phy()
860 mutex_lock(&phy->lock); in phylink_disconnect_phy()
861 mutex_lock(&pl->state_mutex); in phylink_disconnect_phy()
862 pl->phydev = NULL; in phylink_disconnect_phy()
863 mutex_unlock(&pl->state_mutex); in phylink_disconnect_phy()
864 mutex_unlock(&phy->lock); in phylink_disconnect_phy()
865 flush_work(&pl->resolve); in phylink_disconnect_phy()
873 * phylink_fixed_state_cb() - allow setting a fixed link callback
887 if (pl->link_an_mode != MLO_AN_FIXED) in phylink_fixed_state_cb()
888 return -EINVAL; in phylink_fixed_state_cb()
890 mutex_lock(&pl->state_mutex); in phylink_fixed_state_cb()
891 pl->get_fixed_state = cb; in phylink_fixed_state_cb()
892 mutex_unlock(&pl->state_mutex); in phylink_fixed_state_cb()
899 * phylink_mac_change() - notify phylink of a change in MAC state
909 pl->mac_link_dropped = true; in phylink_mac_change()
911 netdev_dbg(pl->netdev, "mac link %s\n", up ? "up" : "down"); in phylink_mac_change()
916 * phylink_start() - start a phylink instance
927 netdev_info(pl->netdev, "configuring for %s/%s link mode\n", in phylink_start()
928 phylink_an_mode_str(pl->link_an_mode), in phylink_start()
929 phy_modes(pl->link_config.interface)); in phylink_start()
932 netif_carrier_off(pl->netdev); in phylink_start()
935 * a fixed-link to start with the correct parameters, and also in phylink_start()
938 phylink_resolve_flow(pl, &pl->link_config); in phylink_start()
939 phylink_mac_config(pl, &pl->link_config); in phylink_start()
947 clear_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); in phylink_start()
950 if (pl->link_an_mode == MLO_AN_FIXED && !IS_ERR(pl->link_gpio)) in phylink_start()
951 mod_timer(&pl->link_poll, jiffies + HZ); in phylink_start()
952 if (pl->sfp_bus) in phylink_start()
953 sfp_upstream_start(pl->sfp_bus); in phylink_start()
954 if (pl->phydev) in phylink_start()
955 phy_start(pl->phydev); in phylink_start()
960 * phylink_stop() - stop a phylink instance
972 if (pl->phydev) in phylink_stop()
973 phy_stop(pl->phydev); in phylink_stop()
974 if (pl->sfp_bus) in phylink_stop()
975 sfp_upstream_stop(pl->sfp_bus); in phylink_stop()
976 if (pl->link_an_mode == MLO_AN_FIXED && !IS_ERR(pl->link_gpio)) in phylink_stop()
977 del_timer_sync(&pl->link_poll); in phylink_stop()
984 * phylink_ethtool_get_wol() - get the wake on lan parameters for the PHY
996 wol->supported = 0; in phylink_ethtool_get_wol()
997 wol->wolopts = 0; in phylink_ethtool_get_wol()
999 if (pl->phydev) in phylink_ethtool_get_wol()
1000 phy_ethtool_get_wol(pl->phydev, wol); in phylink_ethtool_get_wol()
1005 * phylink_ethtool_set_wol() - set wake on lan parameters
1017 int ret = -EOPNOTSUPP; in phylink_ethtool_set_wol()
1021 if (pl->phydev) in phylink_ethtool_set_wol()
1022 ret = phy_ethtool_set_wol(pl->phydev, wol); in phylink_ethtool_set_wol()
1042 phylink_merge_link_mode(kset->link_modes.advertising, state->advertising); in phylink_get_ksettings()
1043 linkmode_copy(kset->link_modes.lp_advertising, state->lp_advertising); in phylink_get_ksettings()
1044 kset->base.speed = state->speed; in phylink_get_ksettings()
1045 kset->base.duplex = state->duplex; in phylink_get_ksettings()
1046 kset->base.autoneg = state->an_enabled ? AUTONEG_ENABLE : in phylink_get_ksettings()
1051 * phylink_ethtool_ksettings_get() - get the current link settings
1066 if (pl->phydev) { in phylink_ethtool_ksettings_get()
1067 phy_ethtool_ksettings_get(pl->phydev, kset); in phylink_ethtool_ksettings_get()
1069 kset->base.port = pl->link_port; in phylink_ethtool_ksettings_get()
1072 linkmode_copy(kset->link_modes.supported, pl->supported); in phylink_ethtool_ksettings_get()
1074 switch (pl->link_an_mode) { in phylink_ethtool_ksettings_get()
1077 * current link settings - and note that these also in phylink_ethtool_ksettings_get()
1078 * represent the supported speeds/duplex/pause modes. in phylink_ethtool_ksettings_get()
1088 if (pl->phydev) in phylink_ethtool_ksettings_get()
1094 * layer via in-band status. Report these as the current in phylink_ethtool_ksettings_get()
1106 * phylink_ethtool_ksettings_set() - set the link settings
1119 if (kset->base.autoneg != AUTONEG_DISABLE && in phylink_ethtool_ksettings_set()
1120 kset->base.autoneg != AUTONEG_ENABLE) in phylink_ethtool_ksettings_set()
1121 return -EINVAL; in phylink_ethtool_ksettings_set()
1123 config = pl->link_config; in phylink_ethtool_ksettings_set()
1126 linkmode_and(config.advertising, kset->link_modes.advertising, in phylink_ethtool_ksettings_set()
1127 pl->supported); in phylink_ethtool_ksettings_set()
1130 if (kset->base.autoneg == AUTONEG_DISABLE) { in phylink_ethtool_ksettings_set()
1136 s = phy_lookup_setting(kset->base.speed, kset->base.duplex, in phylink_ethtool_ksettings_set()
1137 pl->supported, in phylink_ethtool_ksettings_set()
1140 return -EINVAL; in phylink_ethtool_ksettings_set()
1145 if (pl->link_an_mode == MLO_AN_FIXED && in phylink_ethtool_ksettings_set()
1146 (s->speed != pl->link_config.speed || in phylink_ethtool_ksettings_set()
1147 s->duplex != pl->link_config.duplex)) in phylink_ethtool_ksettings_set()
1148 return -EINVAL; in phylink_ethtool_ksettings_set()
1150 config.speed = s->speed; in phylink_ethtool_ksettings_set()
1151 config.duplex = s->duplex; in phylink_ethtool_ksettings_set()
1157 if (pl->link_an_mode == MLO_AN_FIXED) in phylink_ethtool_ksettings_set()
1158 return -EINVAL; in phylink_ethtool_ksettings_set()
1167 if (phylink_validate(pl, pl->supported, &config)) in phylink_ethtool_ksettings_set()
1168 return -EINVAL; in phylink_ethtool_ksettings_set()
1172 return -EINVAL; in phylink_ethtool_ksettings_set()
1180 if (pl->phydev) { in phylink_ethtool_ksettings_set()
1181 ret = phy_ethtool_ksettings_set(pl->phydev, &our_kset); in phylink_ethtool_ksettings_set()
1186 mutex_lock(&pl->state_mutex); in phylink_ethtool_ksettings_set()
1188 linkmode_copy(pl->link_config.advertising, our_kset.link_modes.advertising); in phylink_ethtool_ksettings_set()
1189 pl->link_config.interface = config.interface; in phylink_ethtool_ksettings_set()
1190 pl->link_config.speed = our_kset.base.speed; in phylink_ethtool_ksettings_set()
1191 pl->link_config.duplex = our_kset.base.duplex; in phylink_ethtool_ksettings_set()
1192 pl->link_config.an_enabled = our_kset.base.autoneg != AUTONEG_DISABLE; in phylink_ethtool_ksettings_set()
1194 if (!test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) { in phylink_ethtool_ksettings_set()
1195 phylink_mac_config(pl, &pl->link_config); in phylink_ethtool_ksettings_set()
1198 mutex_unlock(&pl->state_mutex); in phylink_ethtool_ksettings_set()
1205 * phylink_ethtool_nway_reset() - restart negotiation
1221 if (pl->phydev) in phylink_ethtool_nway_reset()
1222 ret = phy_restart_aneg(pl->phydev); in phylink_ethtool_nway_reset()
1230 * phylink_ethtool_get_pauseparam() - get the current pause parameters
1232 * @pause: a pointer to a &struct ethtool_pauseparam
1235 struct ethtool_pauseparam *pause) in phylink_ethtool_get_pauseparam() argument
1239 pause->autoneg = !!(pl->link_config.pause & MLO_PAUSE_AN); in phylink_ethtool_get_pauseparam()
1240 pause->rx_pause = !!(pl->link_config.pause & MLO_PAUSE_RX); in phylink_ethtool_get_pauseparam()
1241 pause->tx_pause = !!(pl->link_config.pause & MLO_PAUSE_TX); in phylink_ethtool_get_pauseparam()
1246 * phylink_ethtool_set_pauseparam() - set the current pause parameters
1248 * @pause: a pointer to a &struct ethtool_pauseparam
1251 struct ethtool_pauseparam *pause) in phylink_ethtool_set_pauseparam() argument
1253 struct phylink_link_state *config = &pl->link_config; in phylink_ethtool_set_pauseparam()
1257 if (!phylink_test(pl->supported, Pause) && in phylink_ethtool_set_pauseparam()
1258 !phylink_test(pl->supported, Asym_Pause)) in phylink_ethtool_set_pauseparam()
1259 return -EOPNOTSUPP; in phylink_ethtool_set_pauseparam()
1261 if (!phylink_test(pl->supported, Asym_Pause) && in phylink_ethtool_set_pauseparam()
1262 !pause->autoneg && pause->rx_pause != pause->tx_pause) in phylink_ethtool_set_pauseparam()
1263 return -EINVAL; in phylink_ethtool_set_pauseparam()
1265 config->pause &= ~(MLO_PAUSE_AN | MLO_PAUSE_TXRX_MASK); in phylink_ethtool_set_pauseparam()
1267 if (pause->autoneg) in phylink_ethtool_set_pauseparam()
1268 config->pause |= MLO_PAUSE_AN; in phylink_ethtool_set_pauseparam()
1269 if (pause->rx_pause) in phylink_ethtool_set_pauseparam()
1270 config->pause |= MLO_PAUSE_RX; in phylink_ethtool_set_pauseparam()
1271 if (pause->tx_pause) in phylink_ethtool_set_pauseparam()
1272 config->pause |= MLO_PAUSE_TX; in phylink_ethtool_set_pauseparam()
1274 if (!test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) { in phylink_ethtool_set_pauseparam()
1275 switch (pl->link_an_mode) { in phylink_ethtool_set_pauseparam()
1278 netif_carrier_off(pl->netdev); in phylink_ethtool_set_pauseparam()
1300 * phylink_ethtool_get_eee_err() - read the energy efficient ethernet error
1315 if (pl->phydev) in phylink_get_eee_err()
1316 ret = phy_get_eee_err(pl->phydev); in phylink_get_eee_err()
1323 * phylink_ethtool_get_eee() - read the energy efficient ethernet parameters
1329 int ret = -EOPNOTSUPP; in phylink_ethtool_get_eee()
1333 if (pl->phydev) in phylink_ethtool_get_eee()
1334 ret = phy_ethtool_get_eee(pl->phydev, eee); in phylink_ethtool_get_eee()
1341 * phylink_ethtool_set_eee() - set the energy efficient ethernet parameters
1347 int ret = -EOPNOTSUPP; in phylink_ethtool_set_eee()
1351 if (pl->phydev) in phylink_ethtool_set_eee()
1352 ret = phy_ethtool_set_eee(pl->phydev, eee); in phylink_ethtool_set_eee()
1358 /* This emulates MII registers for a fixed-mode phy operating as per the
1369 fs.link = state->link; in phylink_mii_emul_read()
1370 fs.speed = state->speed; in phylink_mii_emul_read()
1371 fs.duplex = state->duplex; in phylink_mii_emul_read()
1372 fs.pause = state->pause & MLO_PAUSE_SYM; in phylink_mii_emul_read()
1373 fs.asym_pause = state->pause & MLO_PAUSE_ASYM; in phylink_mii_emul_read()
1377 if (!state->an_complete) in phylink_mii_emul_read()
1388 struct phy_device *phydev = pl->phydev; in phylink_phy_read()
1395 } else if (phydev->is_c45) { in phylink_phy_read()
1401 devad = __ffs(phydev->c45_ids.devices_in_package); in phylink_phy_read()
1405 if (!(phydev->c45_ids.devices_in_package & MDIO_DEVS_AN)) in phylink_phy_read()
1406 return -EINVAL; in phylink_phy_read()
1414 return -EINVAL; in phylink_phy_read()
1422 return mdiobus_read(pl->phydev->mdio.bus, prtad, devad); in phylink_phy_read()
1428 struct phy_device *phydev = pl->phydev; in phylink_phy_write()
1435 } else if (phydev->is_c45) { in phylink_phy_write()
1441 devad = __ffs(phydev->c45_ids.devices_in_package); in phylink_phy_write()
1445 if (!(phydev->c45_ids.devices_in_package & MDIO_DEVS_AN)) in phylink_phy_write()
1446 return -EINVAL; in phylink_phy_write()
1454 return -EINVAL; in phylink_phy_write()
1463 return mdiobus_write(phydev->mdio.bus, prtad, devad, val); in phylink_phy_write()
1472 switch (pl->link_an_mode) { in phylink_mii_read()
1476 val = phylink_mii_emul_read(pl->netdev, reg, &state, in phylink_mii_read()
1482 return -EOPNOTSUPP; in phylink_mii_read()
1490 val = phylink_mii_emul_read(pl->netdev, reg, &state, in phylink_mii_read()
1502 switch (pl->link_an_mode) { in phylink_mii_write()
1507 return -EOPNOTSUPP; in phylink_mii_write()
1517 * phylink_mii_ioctl() - generic mii ioctl interface
1541 if (pl->phydev) { in phylink_mii_ioctl()
1545 mii->phy_id = pl->phydev->mdio.addr; in phylink_mii_ioctl()
1549 ret = phylink_phy_read(pl, mii->phy_id, mii->reg_num); in phylink_mii_ioctl()
1551 mii->val_out = ret; in phylink_mii_ioctl()
1557 ret = phylink_phy_write(pl, mii->phy_id, mii->reg_num, in phylink_mii_ioctl()
1558 mii->val_in); in phylink_mii_ioctl()
1562 ret = phy_mii_ioctl(pl->phydev, ifr, cmd); in phylink_mii_ioctl()
1568 mii->phy_id = 0; in phylink_mii_ioctl()
1572 ret = phylink_mii_read(pl, mii->phy_id, mii->reg_num); in phylink_mii_ioctl()
1574 mii->val_out = ret; in phylink_mii_ioctl()
1580 ret = phylink_mii_write(pl, mii->phy_id, mii->reg_num, in phylink_mii_ioctl()
1581 mii->val_in); in phylink_mii_ioctl()
1585 ret = -EOPNOTSUPP; in phylink_mii_ioctl()
1607 sfp_parse_support(pl->sfp_bus, id, support); in phylink_sfp_module_insert()
1608 port = sfp_parse_port(pl->sfp_bus, id, support); in phylink_sfp_module_insert()
1615 config.pause = MLO_PAUSE_AN; in phylink_sfp_module_insert()
1616 config.an_enabled = pl->link_config.an_enabled; in phylink_sfp_module_insert()
1621 netdev_err(pl->netdev, "validation with support %*pb failed: %d\n", in phylink_sfp_module_insert()
1626 iface = sfp_select_interface(pl->sfp_bus, id, config.advertising); in phylink_sfp_module_insert()
1628 netdev_err(pl->netdev, in phylink_sfp_module_insert()
1631 return -EINVAL; in phylink_sfp_module_insert()
1637 netdev_err(pl->netdev, "validation of %s/%s with support %*pb failed: %d\n", in phylink_sfp_module_insert()
1644 netdev_dbg(pl->netdev, "requesting link mode %s/%s with support %*pb\n", in phylink_sfp_module_insert()
1649 if (phy_interface_mode_is_8023z(iface) && pl->phydev) in phylink_sfp_module_insert()
1650 return -EINVAL; in phylink_sfp_module_insert()
1652 changed = !bitmap_equal(pl->supported, support, in phylink_sfp_module_insert()
1655 linkmode_copy(pl->supported, support); in phylink_sfp_module_insert()
1656 linkmode_copy(pl->link_config.advertising, config.advertising); in phylink_sfp_module_insert()
1659 if (pl->link_an_mode != MLO_AN_INBAND || in phylink_sfp_module_insert()
1660 pl->link_config.interface != config.interface) { in phylink_sfp_module_insert()
1661 pl->link_config.interface = config.interface; in phylink_sfp_module_insert()
1662 pl->link_an_mode = MLO_AN_INBAND; in phylink_sfp_module_insert()
1666 netdev_info(pl->netdev, "switched to %s/%s link mode\n", in phylink_sfp_module_insert()
1671 pl->link_port = port; in phylink_sfp_module_insert()
1674 &pl->phylink_disable_state)) in phylink_sfp_module_insert()
1675 phylink_mac_config(pl, &pl->link_config); in phylink_sfp_module_insert()
1695 clear_bit(PHYLINK_DISABLE_LINK, &pl->phylink_disable_state); in phylink_sfp_link_up()
1703 return __phylink_connect_phy(upstream, phy, pl->link_config.interface); in phylink_sfp_connect_phy()
1722 * phylink_helper_basex_speed() - 1000BaseX/2500BaseX helper
1727 * the interface mode to suit. @state->interface is appropriately
1733 if (phy_interface_mode_is_8023z(state->interface)) { in phylink_helper_basex_speed()
1734 bool want_2500 = state->an_enabled ? in phylink_helper_basex_speed()
1735 phylink_test(state->advertising, 2500baseX_Full) : in phylink_helper_basex_speed()
1736 state->speed == SPEED_2500; in phylink_helper_basex_speed()
1739 phylink_clear(state->advertising, 1000baseX_Full); in phylink_helper_basex_speed()
1740 state->interface = PHY_INTERFACE_MODE_2500BASEX; in phylink_helper_basex_speed()
1742 phylink_clear(state->advertising, 2500baseX_Full); in phylink_helper_basex_speed()
1743 state->interface = PHY_INTERFACE_MODE_1000BASEX; in phylink_helper_basex_speed()