Lines Matching refs:pl

103 #define phylink_printk(level, pl, fmt, ...) \  argument
105 if ((pl)->config->type == PHYLINK_NETDEV) \
106 netdev_printk(level, (pl)->netdev, fmt, ##__VA_ARGS__); \
107 else if ((pl)->config->type == PHYLINK_DEV) \
108 dev_printk(level, (pl)->dev, fmt, ##__VA_ARGS__); \
111 #define phylink_err(pl, fmt, ...) \ argument
112 phylink_printk(KERN_ERR, pl, fmt, ##__VA_ARGS__)
113 #define phylink_warn(pl, fmt, ...) \ argument
114 phylink_printk(KERN_WARNING, pl, fmt, ##__VA_ARGS__)
115 #define phylink_info(pl, fmt, ...) \ argument
116 phylink_printk(KERN_INFO, pl, fmt, ##__VA_ARGS__)
118 #define phylink_dbg(pl, fmt, ...) \ argument
120 if ((pl)->config->type == PHYLINK_NETDEV) \
121 netdev_dbg((pl)->netdev, fmt, ##__VA_ARGS__); \
122 else if ((pl)->config->type == PHYLINK_DEV) \
123 dev_dbg((pl)->dev, fmt, ##__VA_ARGS__); \
126 #define phylink_dbg(pl, fmt, ...) \ argument
127 phylink_printk(KERN_DEBUG, pl, fmt, ##__VA_ARGS__)
129 #define phylink_dbg(pl, fmt, ...) \ argument
132 phylink_printk(KERN_DEBUG, pl, fmt, ##__VA_ARGS__); \
516 static int phylink_validate_mac_and_pcs(struct phylink *pl, in phylink_validate_mac_and_pcs() argument
525 if (pl->mac_ops->mac_select_pcs) { in phylink_validate_mac_and_pcs()
526 pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface); in phylink_validate_mac_and_pcs()
537 phylink_err(pl, "interface %s: uninitialised PCS\n", in phylink_validate_mac_and_pcs()
549 phylink_err(pl, "MAC returned PCS which does not support %s\n", in phylink_validate_mac_and_pcs()
569 if (pl->mac_ops->mac_get_caps) in phylink_validate_mac_and_pcs()
570 capabilities = pl->mac_ops->mac_get_caps(pl->config, in phylink_validate_mac_and_pcs()
573 capabilities = pl->config->mac_capabilities; in phylink_validate_mac_and_pcs()
580 static void phylink_validate_one(struct phylink *pl, struct phy_device *phy, in phylink_validate_one() argument
598 if (!phylink_validate_mac_and_pcs(pl, tmp_supported, &tmp_state)) { in phylink_validate_one()
599 phylink_dbg(pl, " interface %u (%s) rate match %s supports %*pbl\n", in phylink_validate_one()
610 static int phylink_validate_mask(struct phylink *pl, struct phy_device *phy, in phylink_validate_mask() argument
620 phylink_validate_one(pl, phy, supported, state, interface, in phylink_validate_mask()
629 static int phylink_validate(struct phylink *pl, unsigned long *supported, in phylink_validate() argument
632 const unsigned long *interfaces = pl->config->supported_interfaces; in phylink_validate()
635 return phylink_validate_mask(pl, NULL, supported, state, in phylink_validate()
641 return phylink_validate_mac_and_pcs(pl, supported, state); in phylink_validate()
660 static int phylink_parse_fixedlink(struct phylink *pl, in phylink_parse_fixedlink() argument
675 pl->link_config.speed = speed; in phylink_parse_fixedlink()
676 pl->link_config.duplex = DUPLEX_HALF; in phylink_parse_fixedlink()
679 pl->link_config.duplex = DUPLEX_FULL; in phylink_parse_fixedlink()
686 pl->link_config.lp_advertising); in phylink_parse_fixedlink()
689 pl->link_config.lp_advertising); in phylink_parse_fixedlink()
696 pl->link_gpio = desc; in phylink_parse_fixedlink()
710 phylink_err(pl, "broken fixed-link?\n"); in phylink_parse_fixedlink()
714 phylink_warn(pl, "%pfw uses deprecated array-style fixed-link binding!\n", in phylink_parse_fixedlink()
720 pl->link_config.duplex = prop[1] ? in phylink_parse_fixedlink()
722 pl->link_config.speed = prop[2]; in phylink_parse_fixedlink()
725 pl->link_config.lp_advertising); in phylink_parse_fixedlink()
728 pl->link_config.lp_advertising); in phylink_parse_fixedlink()
732 if (pl->link_config.speed > SPEED_1000 && in phylink_parse_fixedlink()
733 pl->link_config.duplex != DUPLEX_FULL) in phylink_parse_fixedlink()
734 phylink_warn(pl, "fixed link specifies half duplex for %dMbps link?\n", in phylink_parse_fixedlink()
735 pl->link_config.speed); in phylink_parse_fixedlink()
737 linkmode_zero(pl->supported); in phylink_parse_fixedlink()
738 phylink_fill_fixedlink_supported(pl->supported); in phylink_parse_fixedlink()
740 linkmode_copy(pl->link_config.advertising, pl->supported); in phylink_parse_fixedlink()
741 phylink_validate(pl, pl->supported, &pl->link_config); in phylink_parse_fixedlink()
743 c = phy_caps_lookup(pl->link_config.speed, pl->link_config.duplex, in phylink_parse_fixedlink()
744 pl->supported, true); in phylink_parse_fixedlink()
746 linkmode_and(match, pl->supported, c->linkmodes); in phylink_parse_fixedlink()
751 linkmode_and(pl->supported, pl->supported, mask); in phylink_parse_fixedlink()
753 phylink_set(pl->supported, MII); in phylink_parse_fixedlink()
756 linkmode_or(pl->supported, pl->supported, match); in phylink_parse_fixedlink()
757 linkmode_or(pl->link_config.lp_advertising, in phylink_parse_fixedlink()
758 pl->link_config.lp_advertising, match); in phylink_parse_fixedlink()
760 phylink_warn(pl, "fixed link %s duplex %dMbps not recognised\n", in phylink_parse_fixedlink()
761 pl->link_config.duplex == DUPLEX_FULL ? "full" : "half", in phylink_parse_fixedlink()
762 pl->link_config.speed); in phylink_parse_fixedlink()
765 linkmode_and(pl->link_config.advertising, pl->link_config.advertising, in phylink_parse_fixedlink()
766 pl->supported); in phylink_parse_fixedlink()
768 pl->link_config.link = 1; in phylink_parse_fixedlink()
769 pl->link_config.an_complete = 1; in phylink_parse_fixedlink()
774 static int phylink_parse_mode(struct phylink *pl, in phylink_parse_mode() argument
781 if (pl->config->default_an_inband) in phylink_parse_mode()
782 pl->cfg_link_an_mode = MLO_AN_INBAND; in phylink_parse_mode()
786 pl->cfg_link_an_mode = MLO_AN_FIXED; in phylink_parse_mode()
791 if (pl->cfg_link_an_mode == MLO_AN_FIXED) { in phylink_parse_mode()
792 phylink_err(pl, in phylink_parse_mode()
797 pl->cfg_link_an_mode = MLO_AN_INBAND; in phylink_parse_mode()
800 if (pl->cfg_link_an_mode == MLO_AN_INBAND) { in phylink_parse_mode()
801 linkmode_zero(pl->supported); in phylink_parse_mode()
802 phylink_set(pl->supported, MII); in phylink_parse_mode()
803 phylink_set(pl->supported, Autoneg); in phylink_parse_mode()
804 phylink_set(pl->supported, Asym_Pause); in phylink_parse_mode()
805 phylink_set(pl->supported, Pause); in phylink_parse_mode()
807 switch (pl->link_config.interface) { in phylink_parse_mode()
830 caps = phylink_get_capabilities(pl->link_config.interface, caps, in phylink_parse_mode()
832 phylink_caps_to_linkmodes(pl->supported, caps); in phylink_parse_mode()
836 phylink_err(pl, in phylink_parse_mode()
838 phy_modes(pl->link_config.interface)); in phylink_parse_mode()
842 linkmode_copy(pl->link_config.advertising, pl->supported); in phylink_parse_mode()
844 if (phylink_validate(pl, pl->supported, &pl->link_config)) { in phylink_parse_mode()
845 phylink_err(pl, in phylink_parse_mode()
854 static void phylink_apply_manual_flow(struct phylink *pl, in phylink_apply_manual_flow() argument
863 if (!(pl->link_config.pause & MLO_PAUSE_AN)) in phylink_apply_manual_flow()
864 state->pause = pl->link_config.pause; in phylink_apply_manual_flow()
959 static unsigned int phylink_inband_caps(struct phylink *pl, in phylink_inband_caps() argument
964 if (!pl->mac_ops->mac_select_pcs) in phylink_inband_caps()
967 pcs = pl->mac_ops->mac_select_pcs(pl->config, interface); in phylink_inband_caps()
974 static void phylink_pcs_poll_stop(struct phylink *pl) in phylink_pcs_poll_stop() argument
976 if (pl->cfg_link_an_mode == MLO_AN_INBAND) in phylink_pcs_poll_stop()
977 timer_delete(&pl->link_poll); in phylink_pcs_poll_stop()
980 static void phylink_pcs_poll_start(struct phylink *pl) in phylink_pcs_poll_start() argument
982 if (pl->pcs && pl->pcs->poll && pl->cfg_link_an_mode == MLO_AN_INBAND) in phylink_pcs_poll_start()
983 mod_timer(&pl->link_poll, jiffies + HZ); in phylink_pcs_poll_start()
986 int phylink_pcs_pre_init(struct phylink *pl, struct phylink_pcs *pcs) in phylink_pcs_pre_init() argument
991 if (pl->config->mac_requires_rxc) in phylink_pcs_pre_init()
1001 static void phylink_mac_config(struct phylink *pl, in phylink_mac_config() argument
1013 phylink_dbg(pl, in phylink_mac_config()
1015 __func__, phylink_an_mode_str(pl->act_link_an_mode), in phylink_mac_config()
1021 pl->mac_ops->mac_config(pl->config, pl->act_link_an_mode, &st); in phylink_mac_config()
1024 static void phylink_pcs_an_restart(struct phylink *pl) in phylink_pcs_an_restart() argument
1026 if (pl->pcs && linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, in phylink_pcs_an_restart()
1027 pl->link_config.advertising) && in phylink_pcs_an_restart()
1028 phy_interface_mode_is_8023z(pl->link_config.interface) && in phylink_pcs_an_restart()
1029 phylink_autoneg_inband(pl->act_link_an_mode)) in phylink_pcs_an_restart()
1030 pl->pcs->ops->pcs_an_restart(pl->pcs); in phylink_pcs_an_restart()
1089 static void phylink_pcs_neg_mode(struct phylink *pl, struct phylink_pcs *pcs, in phylink_pcs_neg_mode() argument
1100 pl->pcs_neg_mode = PHYLINK_PCS_NEG_NONE; in phylink_pcs_neg_mode()
1101 pl->act_link_an_mode = pl->req_link_an_mode; in phylink_pcs_neg_mode()
1105 mode = pl->req_link_an_mode; in phylink_pcs_neg_mode()
1107 pl->phy_ib_mode = 0; in phylink_pcs_neg_mode()
1112 if (pl->phydev) in phylink_pcs_neg_mode()
1113 phy_ib_caps = phy_inband_caps(pl->phydev, interface); in phylink_pcs_neg_mode()
1115 phylink_dbg(pl, "interface %s inband modes: pcs=%02x phy=%02x\n", in phylink_pcs_neg_mode()
1137 pl->phy_ib_mode = LINK_INBAND_DISABLE; in phylink_pcs_neg_mode()
1139 pl->phy_ib_mode = LINK_INBAND_BYPASS; in phylink_pcs_neg_mode()
1149 phylink_warn(pl, in phylink_pcs_neg_mode()
1157 } else if (type == INBAND_CISCO_SGMII || pl->phydev) { in phylink_pcs_neg_mode()
1192 pl->phy_ib_mode = LINK_INBAND_ENABLE; in phylink_pcs_neg_mode()
1194 pl->phy_ib_mode = LINK_INBAND_BYPASS; in phylink_pcs_neg_mode()
1203 pl->phy_ib_mode = LINK_INBAND_DISABLE; in phylink_pcs_neg_mode()
1205 pl->phy_ib_mode = LINK_INBAND_BYPASS; in phylink_pcs_neg_mode()
1208 if (pl->phydev) in phylink_pcs_neg_mode()
1212 phylink_warn(pl, "%s: incompatible in-band capabilities, trying in-band", in phylink_pcs_neg_mode()
1235 pl->pcs_neg_mode = neg_mode; in phylink_pcs_neg_mode()
1236 pl->act_link_an_mode = mode; in phylink_pcs_neg_mode()
1239 static void phylink_major_config(struct phylink *pl, bool restart, in phylink_major_config() argument
1247 phylink_dbg(pl, "major config, requested %s/%s\n", in phylink_major_config()
1248 phylink_an_mode_str(pl->req_link_an_mode), in phylink_major_config()
1251 pl->major_config_failed = false; in phylink_major_config()
1253 if (pl->mac_ops->mac_select_pcs) { in phylink_major_config()
1254 pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface); in phylink_major_config()
1256 phylink_err(pl, in phylink_major_config()
1260 pl->major_config_failed = true; in phylink_major_config()
1264 pcs_changed = pl->pcs != pcs; in phylink_major_config()
1267 phylink_pcs_neg_mode(pl, pcs, state->interface, state->advertising); in phylink_major_config()
1269 phylink_dbg(pl, "major config, active %s/%s/%s\n", in phylink_major_config()
1270 phylink_an_mode_str(pl->act_link_an_mode), in phylink_major_config()
1271 phylink_pcs_mode_str(pl->pcs_neg_mode), in phylink_major_config()
1274 phylink_pcs_poll_stop(pl); in phylink_major_config()
1276 if (pl->mac_ops->mac_prepare) { in phylink_major_config()
1277 err = pl->mac_ops->mac_prepare(pl->config, pl->act_link_an_mode, in phylink_major_config()
1280 phylink_err(pl, "mac_prepare failed: %pe\n", in phylink_major_config()
1282 pl->major_config_failed = true; in phylink_major_config()
1291 phylink_pcs_disable(pl->pcs); in phylink_major_config()
1293 if (pl->pcs) in phylink_major_config()
1294 pl->pcs->phylink = NULL; in phylink_major_config()
1297 pcs->phylink = pl; in phylink_major_config()
1299 pl->pcs = pcs; in phylink_major_config()
1302 if (pl->pcs) in phylink_major_config()
1303 phylink_pcs_pre_config(pl->pcs, state->interface); in phylink_major_config()
1305 phylink_mac_config(pl, state); in phylink_major_config()
1307 if (pl->pcs) { in phylink_major_config()
1308 err = phylink_pcs_post_config(pl->pcs, state->interface); in phylink_major_config()
1310 phylink_err(pl, "pcs_post_config failed: %pe\n", in phylink_major_config()
1313 pl->major_config_failed = true; in phylink_major_config()
1317 if (pl->pcs_state == PCS_STATE_STARTING || pcs_changed) in phylink_major_config()
1318 phylink_pcs_enable(pl->pcs); in phylink_major_config()
1320 err = phylink_pcs_config(pl->pcs, pl->pcs_neg_mode, state, in phylink_major_config()
1321 !!(pl->link_config.pause & MLO_PAUSE_AN)); in phylink_major_config()
1323 phylink_err(pl, "pcs_config failed: %pe\n", ERR_PTR(err)); in phylink_major_config()
1324 pl->major_config_failed = true; in phylink_major_config()
1330 phylink_pcs_an_restart(pl); in phylink_major_config()
1332 if (pl->mac_ops->mac_finish) { in phylink_major_config()
1333 err = pl->mac_ops->mac_finish(pl->config, pl->act_link_an_mode, in phylink_major_config()
1336 phylink_err(pl, "mac_finish failed: %pe\n", in phylink_major_config()
1339 pl->major_config_failed = true; in phylink_major_config()
1343 if (pl->phydev && pl->phy_ib_mode) { in phylink_major_config()
1344 err = phy_config_inband(pl->phydev, pl->phy_ib_mode); in phylink_major_config()
1346 phylink_err(pl, "phy_config_inband: %pe\n", in phylink_major_config()
1349 pl->major_config_failed = true; in phylink_major_config()
1353 if (pl->sfp_bus) { in phylink_major_config()
1356 sfp_upstream_set_signal_rate(pl->sfp_bus, rate_kbd); in phylink_major_config()
1359 phylink_pcs_poll_start(pl); in phylink_major_config()
1368 static int phylink_change_inband_advert(struct phylink *pl) in phylink_change_inband_advert() argument
1372 if (test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) in phylink_change_inband_advert()
1375 phylink_dbg(pl, "%s: mode=%s/%s adv=%*pb pause=%02x\n", __func__, in phylink_change_inband_advert()
1376 phylink_an_mode_str(pl->req_link_an_mode), in phylink_change_inband_advert()
1377 phy_modes(pl->link_config.interface), in phylink_change_inband_advert()
1378 __ETHTOOL_LINK_MODE_MASK_NBITS, pl->link_config.advertising, in phylink_change_inband_advert()
1379 pl->link_config.pause); in phylink_change_inband_advert()
1382 phylink_pcs_neg_mode(pl, pl->pcs, pl->link_config.interface, in phylink_change_inband_advert()
1383 pl->link_config.advertising); in phylink_change_inband_advert()
1389 ret = phylink_pcs_config(pl->pcs, pl->pcs_neg_mode, &pl->link_config, in phylink_change_inband_advert()
1390 !!(pl->link_config.pause & MLO_PAUSE_AN)); in phylink_change_inband_advert()
1395 phylink_pcs_an_restart(pl); in phylink_change_inband_advert()
1400 static void phylink_mac_pcs_get_state(struct phylink *pl, in phylink_mac_pcs_get_state() argument
1406 linkmode_copy(state->advertising, pl->link_config.advertising); in phylink_mac_pcs_get_state()
1408 state->interface = pl->link_config.interface; in phylink_mac_pcs_get_state()
1409 state->rate_matching = pl->link_config.rate_matching; in phylink_mac_pcs_get_state()
1413 autoneg = pl->pcs_neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED; in phylink_mac_pcs_get_state()
1419 state->speed = pl->link_config.speed; in phylink_mac_pcs_get_state()
1420 state->duplex = pl->link_config.duplex; in phylink_mac_pcs_get_state()
1421 state->pause = pl->link_config.pause; in phylink_mac_pcs_get_state()
1424 pcs = pl->pcs; in phylink_mac_pcs_get_state()
1426 pcs->ops->pcs_get_state(pcs, pl->pcs_neg_mode, state); in phylink_mac_pcs_get_state()
1434 static void phylink_get_fixed_state(struct phylink *pl, in phylink_get_fixed_state() argument
1437 *state = pl->link_config; in phylink_get_fixed_state()
1438 if (pl->config->get_fixed_state) in phylink_get_fixed_state()
1439 pl->config->get_fixed_state(pl->config, state); in phylink_get_fixed_state()
1440 else if (pl->link_gpio) in phylink_get_fixed_state()
1441 state->link = !!gpiod_get_value_cansleep(pl->link_gpio); in phylink_get_fixed_state()
1447 static void phylink_mac_initial_config(struct phylink *pl, bool force_restart) in phylink_mac_initial_config() argument
1450 struct phy_device *phy = pl->phydev; in phylink_mac_initial_config()
1452 switch (pl->req_link_an_mode) { in phylink_mac_initial_config()
1454 link_state = pl->phy_state; in phylink_mac_initial_config()
1458 phylink_get_fixed_state(pl, &link_state); in phylink_mac_initial_config()
1462 link_state = pl->link_config; in phylink_mac_initial_config()
1473 phylink_apply_manual_flow(pl, &link_state); in phylink_mac_initial_config()
1476 phylink_major_config(pl, force_restart, &link_state); in phylink_mac_initial_config()
1495 static void phylink_deactivate_lpi(struct phylink *pl) in phylink_deactivate_lpi() argument
1497 if (pl->mac_enable_tx_lpi) { in phylink_deactivate_lpi()
1498 pl->mac_enable_tx_lpi = false; in phylink_deactivate_lpi()
1500 phylink_dbg(pl, "disabling LPI\n"); in phylink_deactivate_lpi()
1502 pl->mac_ops->mac_disable_tx_lpi(pl->config); in phylink_deactivate_lpi()
1504 phylink_pcs_disable_eee(pl->pcs); in phylink_deactivate_lpi()
1508 static void phylink_activate_lpi(struct phylink *pl) in phylink_activate_lpi() argument
1512 if (!test_bit(pl->cur_interface, pl->config->lpi_interfaces)) { in phylink_activate_lpi()
1513 phylink_dbg(pl, "MAC does not support LPI with %s\n", in phylink_activate_lpi()
1514 phy_modes(pl->cur_interface)); in phylink_activate_lpi()
1518 phylink_dbg(pl, "LPI timer %uus, tx clock stop %u\n", in phylink_activate_lpi()
1519 pl->mac_tx_lpi_timer, pl->mac_tx_clk_stop); in phylink_activate_lpi()
1521 phylink_pcs_enable_eee(pl->pcs); in phylink_activate_lpi()
1523 err = pl->mac_ops->mac_enable_tx_lpi(pl->config, pl->mac_tx_lpi_timer, in phylink_activate_lpi()
1524 pl->mac_tx_clk_stop); in phylink_activate_lpi()
1526 phylink_pcs_disable_eee(pl->pcs); in phylink_activate_lpi()
1527 phylink_err(pl, "%ps() failed: %pe\n", in phylink_activate_lpi()
1528 pl->mac_ops->mac_enable_tx_lpi, ERR_PTR(err)); in phylink_activate_lpi()
1532 pl->mac_enable_tx_lpi = true; in phylink_activate_lpi()
1535 static void phylink_link_up(struct phylink *pl, in phylink_link_up() argument
1538 struct net_device *ndev = pl->netdev; in phylink_link_up()
1567 pl->cur_interface = link_state.interface; in phylink_link_up()
1569 phylink_pcs_link_up(pl->pcs, pl->pcs_neg_mode, pl->cur_interface, speed, in phylink_link_up()
1572 pl->mac_ops->mac_link_up(pl->config, pl->phydev, pl->act_link_an_mode, in phylink_link_up()
1573 pl->cur_interface, speed, duplex, in phylink_link_up()
1576 if (pl->mac_supports_eee && pl->phy_enable_tx_lpi) in phylink_link_up()
1577 phylink_activate_lpi(pl); in phylink_link_up()
1582 phylink_info(pl, in phylink_link_up()
1589 static void phylink_link_down(struct phylink *pl) in phylink_link_down() argument
1591 struct net_device *ndev = pl->netdev; in phylink_link_down()
1596 phylink_deactivate_lpi(pl); in phylink_link_down()
1598 pl->mac_ops->mac_link_down(pl->config, pl->act_link_an_mode, in phylink_link_down()
1599 pl->cur_interface); in phylink_link_down()
1600 phylink_info(pl, "Link is Down\n"); in phylink_link_down()
1603 static bool phylink_link_is_up(struct phylink *pl) in phylink_link_is_up() argument
1605 return pl->netdev ? netif_carrier_ok(pl->netdev) : pl->old_link_state; in phylink_link_is_up()
1610 struct phylink *pl = container_of(w, struct phylink, resolve); in phylink_resolve() local
1617 mutex_lock(&pl->phydev_mutex); in phylink_resolve()
1618 phy = pl->phydev; in phylink_resolve()
1621 mutex_lock(&pl->state_mutex); in phylink_resolve()
1622 cur_link_state = phylink_link_is_up(pl); in phylink_resolve()
1624 if (pl->phylink_disable_state) { in phylink_resolve()
1625 pl->link_failed = false; in phylink_resolve()
1627 } else if (pl->link_failed) { in phylink_resolve()
1630 } else if (pl->act_link_an_mode == MLO_AN_FIXED) { in phylink_resolve()
1631 phylink_get_fixed_state(pl, &link_state); in phylink_resolve()
1633 } else if (pl->act_link_an_mode == MLO_AN_PHY) { in phylink_resolve()
1634 link_state = pl->phy_state; in phylink_resolve()
1637 phylink_mac_pcs_get_state(pl, &link_state); in phylink_resolve()
1648 phylink_mac_pcs_get_state(pl, &link_state); in phylink_resolve()
1655 link_state.link &= pl->phy_state.link; in phylink_resolve()
1658 if (phy && pl->phy_state.link) { in phylink_resolve()
1662 if (link_state.interface != pl->phy_state.interface) { in phylink_resolve()
1667 link_state.interface = pl->phy_state.interface; in phylink_resolve()
1672 if (pl->phy_state.rate_matching) { in phylink_resolve()
1674 pl->phy_state.rate_matching; in phylink_resolve()
1675 link_state.speed = pl->phy_state.speed; in phylink_resolve()
1676 link_state.duplex = pl->phy_state.duplex; in phylink_resolve()
1682 link_state.pause = pl->phy_state.pause; in phylink_resolve()
1687 if (pl->act_link_an_mode != MLO_AN_FIXED) in phylink_resolve()
1688 phylink_apply_manual_flow(pl, &link_state); in phylink_resolve()
1690 if ((mac_config && link_state.interface != pl->link_config.interface) || in phylink_resolve()
1691 pl->force_major_config) { in phylink_resolve()
1696 phylink_link_down(pl); in phylink_resolve()
1699 phylink_major_config(pl, false, &link_state); in phylink_resolve()
1700 pl->link_config.interface = link_state.interface; in phylink_resolve()
1701 pl->force_major_config = false; in phylink_resolve()
1707 if (pl->major_config_failed) in phylink_resolve()
1711 pl->old_link_state = link_state.link; in phylink_resolve()
1713 phylink_link_down(pl); in phylink_resolve()
1715 phylink_link_up(pl, link_state); in phylink_resolve()
1718 pl->link_failed = false; in phylink_resolve()
1719 queue_work(system_power_efficient_wq, &pl->resolve); in phylink_resolve()
1721 mutex_unlock(&pl->state_mutex); in phylink_resolve()
1724 mutex_unlock(&pl->phydev_mutex); in phylink_resolve()
1727 static void phylink_run_resolve(struct phylink *pl) in phylink_run_resolve() argument
1729 if (!pl->phylink_disable_state) in phylink_run_resolve()
1730 queue_work(system_power_efficient_wq, &pl->resolve); in phylink_run_resolve()
1733 static void phylink_run_resolve_and_disable(struct phylink *pl, int bit) in phylink_run_resolve_and_disable() argument
1735 unsigned long state = pl->phylink_disable_state; in phylink_run_resolve_and_disable()
1737 set_bit(bit, &pl->phylink_disable_state); in phylink_run_resolve_and_disable()
1739 queue_work(system_power_efficient_wq, &pl->resolve); in phylink_run_resolve_and_disable()
1740 flush_work(&pl->resolve); in phylink_run_resolve_and_disable()
1744 static void phylink_enable_and_run_resolve(struct phylink *pl, int bit) in phylink_enable_and_run_resolve() argument
1746 clear_bit(bit, &pl->phylink_disable_state); in phylink_enable_and_run_resolve()
1747 phylink_run_resolve(pl); in phylink_enable_and_run_resolve()
1752 struct phylink *pl = container_of(t, struct phylink, link_poll); in phylink_fixed_poll() local
1756 phylink_run_resolve(pl); in phylink_fixed_poll()
1761 static int phylink_register_sfp(struct phylink *pl, in phylink_register_sfp() argument
1772 phylink_err(pl, "unable to attach SFP bus: %pe\n", bus); in phylink_register_sfp()
1776 pl->sfp_bus = bus; in phylink_register_sfp()
1778 ret = sfp_bus_add_upstream(bus, pl, &sfp_phylink_ops); in phylink_register_sfp()
1794 int phylink_set_fixed_link(struct phylink *pl, in phylink_set_fixed_link() argument
1800 if (pl->cfg_link_an_mode != MLO_AN_PHY || !state || in phylink_set_fixed_link()
1801 !test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) in phylink_set_fixed_link()
1805 pl->supported, true); in phylink_set_fixed_link()
1809 adv = pl->link_config.advertising; in phylink_set_fixed_link()
1810 linkmode_and(adv, pl->supported, c->linkmodes); in phylink_set_fixed_link()
1813 pl->link_config.speed = state->speed; in phylink_set_fixed_link()
1814 pl->link_config.duplex = state->duplex; in phylink_set_fixed_link()
1815 pl->link_config.link = 1; in phylink_set_fixed_link()
1816 pl->link_config.an_complete = 1; in phylink_set_fixed_link()
1818 pl->cfg_link_an_mode = MLO_AN_FIXED; in phylink_set_fixed_link()
1819 pl->req_link_an_mode = pl->cfg_link_an_mode; in phylink_set_fixed_link()
1846 struct phylink *pl; in phylink_create() local
1856 pl = kzalloc_obj(*pl); in phylink_create()
1857 if (!pl) in phylink_create()
1860 mutex_init(&pl->phydev_mutex); in phylink_create()
1861 mutex_init(&pl->state_mutex); in phylink_create()
1862 INIT_WORK(&pl->resolve, phylink_resolve); in phylink_create()
1864 pl->config = config; in phylink_create()
1866 pl->netdev = to_net_dev(config->dev); in phylink_create()
1867 netif_carrier_off(pl->netdev); in phylink_create()
1869 pl->dev = config->dev; in phylink_create()
1871 kfree(pl); in phylink_create()
1875 pl->mac_supports_eee_ops = phylink_mac_implements_lpi(mac_ops); in phylink_create()
1876 pl->mac_supports_eee = pl->mac_supports_eee_ops && in phylink_create()
1877 pl->config->lpi_capabilities && in phylink_create()
1878 !phy_interface_empty(pl->config->lpi_interfaces); in phylink_create()
1881 pl->eee_cfg.eee_enabled = pl->config->eee_enabled_default; in phylink_create()
1882 pl->eee_cfg.tx_lpi_enabled = pl->eee_cfg.eee_enabled; in phylink_create()
1883 pl->eee_cfg.tx_lpi_timer = pl->config->lpi_timer_default; in phylink_create()
1885 pl->phy_state.interface = iface; in phylink_create()
1886 pl->link_interface = iface; in phylink_create()
1888 pl->link_port = PORT_BNC; in phylink_create()
1890 pl->link_port = PORT_MII; in phylink_create()
1891 pl->link_config.interface = iface; in phylink_create()
1892 pl->link_config.pause = MLO_PAUSE_AN; in phylink_create()
1893 pl->link_config.speed = SPEED_UNKNOWN; in phylink_create()
1894 pl->link_config.duplex = DUPLEX_UNKNOWN; in phylink_create()
1895 pl->pcs_state = PCS_STATE_DOWN; in phylink_create()
1896 pl->mac_ops = mac_ops; in phylink_create()
1897 __set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); in phylink_create()
1898 timer_setup(&pl->link_poll, phylink_fixed_poll, 0); in phylink_create()
1900 linkmode_fill(pl->supported); in phylink_create()
1901 linkmode_copy(pl->link_config.advertising, pl->supported); in phylink_create()
1902 phylink_validate(pl, pl->supported, &pl->link_config); in phylink_create()
1904 ret = phylink_parse_mode(pl, fwnode); in phylink_create()
1906 kfree(pl); in phylink_create()
1910 if (pl->cfg_link_an_mode == MLO_AN_FIXED) { in phylink_create()
1911 ret = phylink_parse_fixedlink(pl, fwnode); in phylink_create()
1913 kfree(pl); in phylink_create()
1918 pl->req_link_an_mode = pl->cfg_link_an_mode; in phylink_create()
1920 ret = phylink_register_sfp(pl, fwnode); in phylink_create()
1922 kfree(pl); in phylink_create()
1926 return pl; in phylink_create()
1939 void phylink_destroy(struct phylink *pl) in phylink_destroy() argument
1941 sfp_bus_del_upstream(pl->sfp_bus); in phylink_destroy()
1942 if (pl->link_gpio) in phylink_destroy()
1943 gpiod_put(pl->link_gpio); in phylink_destroy()
1945 cancel_work_sync(&pl->resolve); in phylink_destroy()
1946 kfree(pl); in phylink_destroy()
1959 bool phylink_expects_phy(struct phylink *pl) in phylink_expects_phy() argument
1961 if (pl->cfg_link_an_mode == MLO_AN_FIXED || in phylink_expects_phy()
1962 (pl->cfg_link_an_mode == MLO_AN_INBAND && in phylink_expects_phy()
1963 phy_interface_mode_is_8023z(pl->link_interface))) in phylink_expects_phy()
1971 struct phylink *pl = phydev->phylink; in phylink_phy_change() local
1976 mutex_lock(&pl->state_mutex); in phylink_phy_change()
1977 pl->phy_state.speed = phydev->speed; in phylink_phy_change()
1978 pl->phy_state.duplex = phydev->duplex; in phylink_phy_change()
1979 pl->phy_state.rate_matching = phydev->rate_matching; in phylink_phy_change()
1980 pl->phy_state.pause = MLO_PAUSE_NONE; in phylink_phy_change()
1982 pl->phy_state.pause |= MLO_PAUSE_TX; in phylink_phy_change()
1984 pl->phy_state.pause |= MLO_PAUSE_RX; in phylink_phy_change()
1985 pl->phy_state.interface = phydev->interface; in phylink_phy_change()
1986 pl->phy_state.link = up; in phylink_phy_change()
1988 pl->link_failed = true; in phylink_phy_change()
1991 pl->phy_enable_tx_lpi = phydev->enable_tx_lpi; in phylink_phy_change()
1992 pl->mac_tx_lpi_timer = phydev->eee_cfg.tx_lpi_timer; in phylink_phy_change()
1993 mutex_unlock(&pl->state_mutex); in phylink_phy_change()
1995 phylink_run_resolve(pl); in phylink_phy_change()
1997 phylink_dbg(pl, "phy link %s %s/%s/%s/%s/%s/%slpi\n", in phylink_phy_change()
2003 phylink_pause_to_str(pl->phy_state.pause), in phylink_phy_change()
2007 static int phylink_validate_phy(struct phylink *pl, struct phy_device *phy, in phylink_validate_phy() argument
2022 pl->config->supported_interfaces); in phylink_validate_phy()
2025 phylink_err(pl, "PHY has no common interfaces\n"); in phylink_validate_phy()
2037 phylink_err(pl, "SFP PHY's possible interfaces becomes empty\n"); in phylink_validate_phy()
2042 phylink_dbg(pl, "PHY %s uses interfaces %*pbl, validating %*pbl\n", in phylink_validate_phy()
2048 return phylink_validate_mask(pl, phy, supported, state, in phylink_validate_phy()
2052 phylink_dbg(pl, "PHY %s doesn't supply possible interfaces\n", in phylink_validate_phy()
2077 return phylink_validate(pl, supported, state); in phylink_validate_phy()
2080 static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy, in phylink_bringup_phy() argument
2102 ret = phylink_validate_phy(pl, phy, supported, &config); in phylink_bringup_phy()
2104 phylink_warn(pl, "validation of %s with support %*pb and advertisement %*pb failed: %pe\n", in phylink_bringup_phy()
2112 phy->phylink = pl; in phylink_bringup_phy()
2116 phylink_info(pl, in phylink_bringup_phy()
2121 mutex_lock(&pl->phydev_mutex); in phylink_bringup_phy()
2123 mutex_lock(&pl->state_mutex); in phylink_bringup_phy()
2124 pl->phydev = phy; in phylink_bringup_phy()
2125 pl->phy_state.interface = interface; in phylink_bringup_phy()
2126 pl->phy_state.pause = MLO_PAUSE_NONE; in phylink_bringup_phy()
2127 pl->phy_state.speed = SPEED_UNKNOWN; in phylink_bringup_phy()
2128 pl->phy_state.duplex = DUPLEX_UNKNOWN; in phylink_bringup_phy()
2129 pl->phy_state.rate_matching = RATE_MATCH_NONE; in phylink_bringup_phy()
2130 linkmode_copy(pl->supported, supported); in phylink_bringup_phy()
2131 linkmode_copy(pl->link_config.advertising, config.advertising); in phylink_bringup_phy()
2139 if (pl->mac_supports_eee) { in phylink_bringup_phy()
2144 if (pl->eee_cfg.eee_enabled) in phylink_bringup_phy()
2147 phy->eee_cfg.tx_lpi_enabled = pl->eee_cfg.tx_lpi_enabled; in phylink_bringup_phy()
2148 phy->eee_cfg.tx_lpi_timer = pl->eee_cfg.tx_lpi_timer; in phylink_bringup_phy()
2151 linkmode_zero(pl->supported_lpi); in phylink_bringup_phy()
2152 phylink_caps_to_linkmodes(pl->supported_lpi, in phylink_bringup_phy()
2153 pl->config->lpi_capabilities); in phylink_bringup_phy()
2159 pl->supported_lpi); in phylink_bringup_phy()
2160 } else if (pl->mac_supports_eee_ops) { in phylink_bringup_phy()
2165 mutex_unlock(&pl->state_mutex); in phylink_bringup_phy()
2167 mutex_unlock(&pl->phydev_mutex); in phylink_bringup_phy()
2169 phylink_dbg(pl, in phylink_bringup_phy()
2172 __ETHTOOL_LINK_MODE_MASK_NBITS, pl->supported, in phylink_bringup_phy()
2175 if (pl->config->mac_managed_pm) in phylink_bringup_phy()
2179 pl->mac_tx_clk_stop = phy_eee_tx_clock_stop_capable(phy) > 0; in phylink_bringup_phy()
2181 if (pl->mac_supports_eee_ops) { in phylink_bringup_phy()
2186 pl->config->eee_rx_clk_stop_enable); in phylink_bringup_phy()
2197 static int phylink_attach_phy(struct phylink *pl, struct phy_device *phy, in phylink_attach_phy() argument
2202 if (WARN_ON(pl->cfg_link_an_mode == MLO_AN_FIXED || in phylink_attach_phy()
2203 (pl->cfg_link_an_mode == MLO_AN_INBAND && in phylink_attach_phy()
2204 phy_interface_mode_is_8023z(interface) && !pl->sfp_bus))) in phylink_attach_phy()
2207 if (pl->phydev) in phylink_attach_phy()
2210 if (pl->config->mac_requires_rxc) in phylink_attach_phy()
2213 return phy_attach_direct(pl->netdev, phy, flags, interface); in phylink_attach_phy()
2231 int phylink_connect_phy(struct phylink *pl, struct phy_device *phy) in phylink_connect_phy() argument
2236 if (pl->link_interface == PHY_INTERFACE_MODE_NA) { in phylink_connect_phy()
2237 pl->link_interface = phy->interface; in phylink_connect_phy()
2238 pl->link_config.interface = pl->link_interface; in phylink_connect_phy()
2241 ret = phylink_attach_phy(pl, phy, pl->link_interface); in phylink_connect_phy()
2245 ret = phylink_bringup_phy(pl, phy, pl->link_config.interface); in phylink_connect_phy()
2265 int phylink_of_phy_connect(struct phylink *pl, struct device_node *dn, in phylink_of_phy_connect() argument
2268 return phylink_fwnode_phy_connect(pl, of_fwnode_handle(dn), flags); in phylink_of_phy_connect()
2283 int phylink_fwnode_phy_connect(struct phylink *pl, in phylink_fwnode_phy_connect() argument
2292 if (pl->cfg_link_an_mode == MLO_AN_FIXED || in phylink_fwnode_phy_connect()
2293 (pl->cfg_link_an_mode == MLO_AN_INBAND && in phylink_fwnode_phy_connect()
2294 phy_interface_mode_is_8023z(pl->link_interface))) in phylink_fwnode_phy_connect()
2299 if (pl->cfg_link_an_mode == MLO_AN_PHY) in phylink_fwnode_phy_connect()
2311 if (pl->link_interface == PHY_INTERFACE_MODE_NA) { in phylink_fwnode_phy_connect()
2312 pl->link_interface = phy_dev->interface; in phylink_fwnode_phy_connect()
2313 pl->link_config.interface = pl->link_interface; in phylink_fwnode_phy_connect()
2316 if (pl->config->mac_requires_rxc) in phylink_fwnode_phy_connect()
2319 ret = phy_attach_direct(pl->netdev, phy_dev, flags, in phylink_fwnode_phy_connect()
2320 pl->link_interface); in phylink_fwnode_phy_connect()
2325 ret = phylink_bringup_phy(pl, phy_dev, pl->link_config.interface); in phylink_fwnode_phy_connect()
2340 void phylink_disconnect_phy(struct phylink *pl) in phylink_disconnect_phy() argument
2346 mutex_lock(&pl->phydev_mutex); in phylink_disconnect_phy()
2347 phy = pl->phydev; in phylink_disconnect_phy()
2350 mutex_lock(&pl->state_mutex); in phylink_disconnect_phy()
2351 pl->phydev = NULL; in phylink_disconnect_phy()
2352 pl->phy_enable_tx_lpi = false; in phylink_disconnect_phy()
2353 pl->mac_tx_clk_stop = false; in phylink_disconnect_phy()
2354 mutex_unlock(&pl->state_mutex); in phylink_disconnect_phy()
2357 mutex_unlock(&pl->phydev_mutex); in phylink_disconnect_phy()
2360 flush_work(&pl->resolve); in phylink_disconnect_phy()
2366 static void phylink_link_changed(struct phylink *pl, bool up, const char *what) in phylink_link_changed() argument
2369 pl->link_failed = true; in phylink_link_changed()
2370 phylink_run_resolve(pl); in phylink_link_changed()
2371 phylink_dbg(pl, "%s link %s\n", what, up ? "up" : "down"); in phylink_link_changed()
2382 void phylink_mac_change(struct phylink *pl, bool up) in phylink_mac_change() argument
2384 phylink_link_changed(pl, up, "mac"); in phylink_mac_change()
2401 struct phylink *pl = pcs->phylink; in phylink_pcs_change() local
2403 if (pl) in phylink_pcs_change()
2404 phylink_link_changed(pl, up, "pcs"); in phylink_pcs_change()
2410 struct phylink *pl = data; in phylink_link_handler() local
2412 phylink_run_resolve(pl); in phylink_link_handler()
2425 void phylink_start(struct phylink *pl) in phylink_start() argument
2431 phylink_info(pl, "configuring for %s/%s link mode\n", in phylink_start()
2432 phylink_an_mode_str(pl->req_link_an_mode), in phylink_start()
2433 phy_modes(pl->link_config.interface)); in phylink_start()
2436 if (pl->netdev) in phylink_start()
2437 netif_carrier_off(pl->netdev); in phylink_start()
2439 pl->pcs_state = PCS_STATE_STARTING; in phylink_start()
2449 phylink_mac_initial_config(pl, true); in phylink_start()
2451 pl->pcs_state = PCS_STATE_STARTED; in phylink_start()
2453 phylink_enable_and_run_resolve(pl, PHYLINK_DISABLE_STOPPED); in phylink_start()
2455 if (pl->cfg_link_an_mode == MLO_AN_FIXED && pl->link_gpio) { in phylink_start()
2456 int irq = gpiod_to_irq(pl->link_gpio); in phylink_start()
2462 "netdev link", pl)) in phylink_start()
2463 pl->link_irq = irq; in phylink_start()
2471 if (pl->cfg_link_an_mode == MLO_AN_FIXED) in phylink_start()
2472 poll |= pl->config->poll_fixed_state; in phylink_start()
2475 mod_timer(&pl->link_poll, jiffies + HZ); in phylink_start()
2476 if (pl->phydev) in phylink_start()
2477 phy_start(pl->phydev); in phylink_start()
2478 if (pl->sfp_bus) in phylink_start()
2479 sfp_upstream_start(pl->sfp_bus); in phylink_start()
2495 void phylink_stop(struct phylink *pl) in phylink_stop() argument
2499 if (pl->sfp_bus) in phylink_stop()
2500 sfp_upstream_stop(pl->sfp_bus); in phylink_stop()
2501 if (pl->phydev) in phylink_stop()
2502 phy_stop(pl->phydev); in phylink_stop()
2503 timer_delete_sync(&pl->link_poll); in phylink_stop()
2504 if (pl->link_irq) { in phylink_stop()
2505 free_irq(pl->link_irq, pl); in phylink_stop()
2506 pl->link_irq = 0; in phylink_stop()
2509 phylink_run_resolve_and_disable(pl, PHYLINK_DISABLE_STOPPED); in phylink_stop()
2511 pl->pcs_state = PCS_STATE_DOWN; in phylink_stop()
2513 phylink_pcs_disable(pl->pcs); in phylink_stop()
2525 void phylink_rx_clk_stop_block(struct phylink *pl) in phylink_rx_clk_stop_block() argument
2529 if (pl->mac_rx_clk_stop_blocked == U8_MAX) { in phylink_rx_clk_stop_block()
2530 phylink_warn(pl, "%s called too many times - ignoring\n", in phylink_rx_clk_stop_block()
2539 if (pl->mac_rx_clk_stop_blocked++ == 0 && in phylink_rx_clk_stop_block()
2540 pl->mac_supports_eee_ops && pl->phydev && in phylink_rx_clk_stop_block()
2541 pl->config->eee_rx_clk_stop_enable) in phylink_rx_clk_stop_block()
2542 phy_eee_rx_clock_stop(pl->phydev, false); in phylink_rx_clk_stop_block()
2554 void phylink_rx_clk_stop_unblock(struct phylink *pl) in phylink_rx_clk_stop_unblock() argument
2558 if (pl->mac_rx_clk_stop_blocked == 0) { in phylink_rx_clk_stop_unblock()
2559 phylink_warn(pl, "%s called too many times - ignoring\n", in phylink_rx_clk_stop_unblock()
2568 if (--pl->mac_rx_clk_stop_blocked == 0 && in phylink_rx_clk_stop_unblock()
2569 pl->mac_supports_eee_ops && pl->phydev && in phylink_rx_clk_stop_unblock()
2570 pl->config->eee_rx_clk_stop_enable) in phylink_rx_clk_stop_unblock()
2571 phy_eee_rx_clock_stop(pl->phydev, true); in phylink_rx_clk_stop_unblock()
2575 static bool phylink_mac_supports_wol(struct phylink *pl) in phylink_mac_supports_wol() argument
2577 return !!pl->mac_ops->mac_wol_set; in phylink_mac_supports_wol()
2580 static bool phylink_phy_supports_wol(struct phylink *pl, in phylink_phy_supports_wol() argument
2583 return phydev && (pl->config->wol_phy_legacy || phy_can_wakeup(phydev)); in phylink_phy_supports_wol()
2586 static bool phylink_phy_pm_speed_ctrl(struct phylink *pl) in phylink_phy_pm_speed_ctrl() argument
2588 return pl->config->wol_phy_speed_ctrl && !pl->wolopts_mac && in phylink_phy_pm_speed_ctrl()
2589 pl->phydev && phy_may_wakeup(pl->phydev); in phylink_phy_pm_speed_ctrl()
2609 void phylink_suspend(struct phylink *pl, bool mac_wol) in phylink_suspend() argument
2613 if (phylink_mac_supports_wol(pl)) in phylink_suspend()
2614 mac_wol = !!pl->wolopts_mac; in phylink_suspend()
2616 if (mac_wol && (!pl->netdev || pl->netdev->ethtool->wol_enabled)) { in phylink_suspend()
2618 mutex_lock(&pl->state_mutex); in phylink_suspend()
2621 __set_bit(PHYLINK_DISABLE_MAC_WOL, &pl->phylink_disable_state); in phylink_suspend()
2623 pl->suspend_link_up = phylink_link_is_up(pl); in phylink_suspend()
2624 if (pl->suspend_link_up) { in phylink_suspend()
2629 if (pl->netdev) in phylink_suspend()
2630 netif_carrier_off(pl->netdev); in phylink_suspend()
2631 pl->old_link_state = false; in phylink_suspend()
2637 mutex_unlock(&pl->state_mutex); in phylink_suspend()
2639 phylink_stop(pl); in phylink_suspend()
2642 if (phylink_phy_pm_speed_ctrl(pl)) in phylink_suspend()
2643 phylink_speed_down(pl, false); in phylink_suspend()
2655 void phylink_prepare_resume(struct phylink *pl) in phylink_prepare_resume() argument
2657 struct phy_device *phydev = pl->phydev; in phylink_prepare_resume()
2667 if (pl->config->mac_requires_rxc && phydev && phydev->suspended) in phylink_prepare_resume()
2679 void phylink_resume(struct phylink *pl) in phylink_resume() argument
2683 if (phylink_phy_pm_speed_ctrl(pl)) in phylink_resume()
2684 phylink_speed_up(pl); in phylink_resume()
2686 if (test_bit(PHYLINK_DISABLE_MAC_WOL, &pl->phylink_disable_state)) { in phylink_resume()
2689 if (pl->suspend_link_up) { in phylink_resume()
2697 mutex_lock(&pl->state_mutex); in phylink_resume()
2698 phylink_link_down(pl); in phylink_resume()
2699 mutex_unlock(&pl->state_mutex); in phylink_resume()
2705 phylink_mac_initial_config(pl, true); in phylink_resume()
2708 phylink_enable_and_run_resolve(pl, PHYLINK_DISABLE_MAC_WOL); in phylink_resume()
2710 phylink_start(pl); in phylink_resume()
2724 void phylink_ethtool_get_wol(struct phylink *pl, struct ethtool_wolinfo *wol) in phylink_ethtool_get_wol() argument
2731 if (phylink_mac_supports_wol(pl)) { in phylink_ethtool_get_wol()
2732 if (phylink_phy_supports_wol(pl, pl->phydev)) in phylink_ethtool_get_wol()
2733 phy_ethtool_get_wol(pl->phydev, wol); in phylink_ethtool_get_wol()
2738 if (~wol->wolopts & pl->wolopts_mac & WAKE_MAGICSECURE) in phylink_ethtool_get_wol()
2739 memcpy(wol->sopass, pl->wol_sopass, in phylink_ethtool_get_wol()
2742 wol->supported |= pl->config->wol_mac_support; in phylink_ethtool_get_wol()
2743 wol->wolopts |= pl->wolopts_mac; in phylink_ethtool_get_wol()
2746 if (pl->phydev) in phylink_ethtool_get_wol()
2747 phy_ethtool_get_wol(pl->phydev, wol); in phylink_ethtool_get_wol()
2763 int phylink_ethtool_set_wol(struct phylink *pl, struct ethtool_wolinfo *wol) in phylink_ethtool_set_wol() argument
2772 if (phylink_mac_supports_wol(pl)) { in phylink_ethtool_set_wol()
2775 if (phylink_phy_supports_wol(pl, pl->phydev)) { in phylink_ethtool_set_wol()
2776 ret = phy_ethtool_set_wol(pl->phydev, wol); in phylink_ethtool_set_wol()
2780 phy_ethtool_get_wol(pl->phydev, &w); in phylink_ethtool_set_wol()
2788 wolopts &= pl->config->wol_mac_support; in phylink_ethtool_set_wol()
2789 changed = pl->wolopts_mac != wolopts; in phylink_ethtool_set_wol()
2791 changed |= !!memcmp(wol->sopass, pl->wol_sopass, in phylink_ethtool_set_wol()
2793 memcpy(pl->wol_sopass, wol->sopass, sizeof(pl->wol_sopass)); in phylink_ethtool_set_wol()
2796 ret = pl->mac_ops->mac_wol_set(pl->config, wolopts, in phylink_ethtool_set_wol()
2799 pl->wolopts_mac = wolopts; in phylink_ethtool_set_wol()
2804 if (pl->phydev) in phylink_ethtool_set_wol()
2805 ret = phy_ethtool_set_wol(pl->phydev, wol); in phylink_ethtool_set_wol()
2812 static phy_interface_t phylink_sfp_select_interface(struct phylink *pl, in phylink_sfp_select_interface() argument
2817 interface = sfp_select_interface(pl->sfp_bus, link_modes); in phylink_sfp_select_interface()
2819 phylink_err(pl, in phylink_sfp_select_interface()
2826 if (!test_bit(interface, pl->config->supported_interfaces)) { in phylink_sfp_select_interface()
2827 phylink_err(pl, in phylink_sfp_select_interface()
2831 pl->config->supported_interfaces); in phylink_sfp_select_interface()
2838 static phy_interface_t phylink_sfp_select_interface_speed(struct phylink *pl, in phylink_sfp_select_interface_speed() argument
2848 if (!test_bit(interface, pl->sfp_interfaces)) in phylink_sfp_select_interface_speed()
2865 phylink_err(pl, "selection of interface failed, speed %u\n", in phylink_sfp_select_interface_speed()
2905 int phylink_ethtool_ksettings_get(struct phylink *pl, in phylink_ethtool_ksettings_get() argument
2912 if (pl->phydev) in phylink_ethtool_ksettings_get()
2913 phy_ethtool_ksettings_get(pl->phydev, kset); in phylink_ethtool_ksettings_get()
2915 kset->base.port = pl->link_port; in phylink_ethtool_ksettings_get()
2917 linkmode_copy(kset->link_modes.supported, pl->supported); in phylink_ethtool_ksettings_get()
2919 switch (pl->act_link_an_mode) { in phylink_ethtool_ksettings_get()
2925 phylink_get_fixed_state(pl, &link_state); in phylink_ethtool_ksettings_get()
2933 if (pl->phydev) in phylink_ethtool_ksettings_get()
2936 phylink_mac_pcs_get_state(pl, &link_state); in phylink_ethtool_ksettings_get()
2950 static bool phylink_validate_pcs_inband_autoneg(struct phylink *pl, in phylink_validate_pcs_inband_autoneg() argument
2954 unsigned int inband = phylink_inband_caps(pl, interface); in phylink_validate_pcs_inband_autoneg()
2975 int phylink_ethtool_ksettings_set(struct phylink *pl, in phylink_ethtool_ksettings_set() argument
2984 if (pl->phydev) { in phylink_ethtool_ksettings_set()
2989 pl->supported); in phylink_ethtool_ksettings_set()
3009 return phy_ethtool_ksettings_set(pl->phydev, &phy_kset); in phylink_ethtool_ksettings_set()
3012 config = pl->link_config; in phylink_ethtool_ksettings_set()
3015 pl->supported); in phylink_ethtool_ksettings_set()
3024 pl->supported, false); in phylink_ethtool_ksettings_set()
3031 if (pl->req_link_an_mode == MLO_AN_FIXED) { in phylink_ethtool_ksettings_set()
3032 if (c->speed != pl->link_config.speed || in phylink_ethtool_ksettings_set()
3033 c->duplex != pl->link_config.duplex) in phylink_ethtool_ksettings_set()
3047 if (pl->req_link_an_mode == MLO_AN_FIXED) { in phylink_ethtool_ksettings_set()
3049 pl->link_config.advertising)) in phylink_ethtool_ksettings_set()
3072 if (pl->sfp_bus) { in phylink_ethtool_ksettings_set()
3075 phylink_sfp_select_interface(pl, in phylink_ethtool_ksettings_set()
3079 phylink_sfp_select_interface_speed(pl, in phylink_ethtool_ksettings_set()
3085 linkmode_copy(support, pl->supported); in phylink_ethtool_ksettings_set()
3086 if (phylink_validate(pl, support, &config)) { in phylink_ethtool_ksettings_set()
3087 phylink_err(pl, "validation of %s/%s with support %*pb failed\n", in phylink_ethtool_ksettings_set()
3088 phylink_an_mode_str(pl->req_link_an_mode), in phylink_ethtool_ksettings_set()
3095 linkmode_copy(support, pl->supported); in phylink_ethtool_ksettings_set()
3096 if (phylink_validate(pl, support, &config)) in phylink_ethtool_ksettings_set()
3109 if (!phylink_validate_pcs_inband_autoneg(pl, config.interface, in phylink_ethtool_ksettings_set()
3113 mutex_lock(&pl->state_mutex); in phylink_ethtool_ksettings_set()
3114 pl->link_config.speed = config.speed; in phylink_ethtool_ksettings_set()
3115 pl->link_config.duplex = config.duplex; in phylink_ethtool_ksettings_set()
3117 if (pl->link_config.interface != config.interface) { in phylink_ethtool_ksettings_set()
3120 if (pl->old_link_state) { in phylink_ethtool_ksettings_set()
3121 phylink_link_down(pl); in phylink_ethtool_ksettings_set()
3122 pl->old_link_state = false; in phylink_ethtool_ksettings_set()
3125 &pl->phylink_disable_state)) in phylink_ethtool_ksettings_set()
3126 phylink_major_config(pl, false, &config); in phylink_ethtool_ksettings_set()
3127 pl->link_config.interface = config.interface; in phylink_ethtool_ksettings_set()
3128 linkmode_copy(pl->link_config.advertising, config.advertising); in phylink_ethtool_ksettings_set()
3129 } else if (!linkmode_equal(pl->link_config.advertising, in phylink_ethtool_ksettings_set()
3131 linkmode_copy(pl->link_config.advertising, config.advertising); in phylink_ethtool_ksettings_set()
3132 phylink_change_inband_advert(pl); in phylink_ethtool_ksettings_set()
3134 mutex_unlock(&pl->state_mutex); in phylink_ethtool_ksettings_set()
3151 int phylink_ethtool_nway_reset(struct phylink *pl) in phylink_ethtool_nway_reset() argument
3157 if (pl->phydev) in phylink_ethtool_nway_reset()
3158 ret = phy_restart_aneg(pl->phydev); in phylink_ethtool_nway_reset()
3159 phylink_pcs_an_restart(pl); in phylink_ethtool_nway_reset()
3170 void phylink_ethtool_get_pauseparam(struct phylink *pl, in phylink_ethtool_get_pauseparam() argument
3175 pause->autoneg = !!(pl->link_config.pause & MLO_PAUSE_AN); in phylink_ethtool_get_pauseparam()
3176 pause->rx_pause = !!(pl->link_config.pause & MLO_PAUSE_RX); in phylink_ethtool_get_pauseparam()
3177 pause->tx_pause = !!(pl->link_config.pause & MLO_PAUSE_TX); in phylink_ethtool_get_pauseparam()
3186 int phylink_ethtool_set_pauseparam(struct phylink *pl, in phylink_ethtool_set_pauseparam() argument
3189 struct phylink_link_state *config = &pl->link_config; in phylink_ethtool_set_pauseparam()
3195 if (pl->req_link_an_mode == MLO_AN_FIXED) in phylink_ethtool_set_pauseparam()
3198 if (!phylink_test(pl->supported, Pause) && in phylink_ethtool_set_pauseparam()
3199 !phylink_test(pl->supported, Asym_Pause)) in phylink_ethtool_set_pauseparam()
3202 if (!phylink_test(pl->supported, Asym_Pause) && in phylink_ethtool_set_pauseparam()
3214 mutex_lock(&pl->state_mutex); in phylink_ethtool_set_pauseparam()
3240 if (!pl->phydev) in phylink_ethtool_set_pauseparam()
3241 phylink_change_inband_advert(pl); in phylink_ethtool_set_pauseparam()
3243 mutex_unlock(&pl->state_mutex); in phylink_ethtool_set_pauseparam()
3250 if (pl->phydev) in phylink_ethtool_set_pauseparam()
3251 phy_set_asym_pause(pl->phydev, pause->rx_pause, in phylink_ethtool_set_pauseparam()
3259 pl->link_failed = true; in phylink_ethtool_set_pauseparam()
3260 phylink_run_resolve(pl); in phylink_ethtool_set_pauseparam()
3277 int phylink_get_eee_err(struct phylink *pl) in phylink_get_eee_err() argument
3283 if (pl->phydev) in phylink_get_eee_err()
3284 ret = phy_get_eee_err(pl->phydev); in phylink_get_eee_err()
3295 int phylink_ethtool_get_eee(struct phylink *pl, struct ethtool_keee *eee) in phylink_ethtool_get_eee() argument
3301 if (pl->mac_supports_eee_ops && !pl->mac_supports_eee) in phylink_ethtool_get_eee()
3304 if (pl->phydev) { in phylink_ethtool_get_eee()
3305 ret = phy_ethtool_get_eee(pl->phydev, eee); in phylink_ethtool_get_eee()
3307 if (ret == 0 && pl->mac_supports_eee_ops) in phylink_ethtool_get_eee()
3309 pl->supported_lpi); in phylink_ethtool_get_eee()
3321 int phylink_ethtool_set_eee(struct phylink *pl, struct ethtool_keee *eee) in phylink_ethtool_set_eee() argument
3323 bool mac_eee = pl->mac_supports_eee; in phylink_ethtool_set_eee()
3328 phylink_dbg(pl, "mac %s phylink EEE%s, adv %*pbl, LPI%s timer %uus\n", in phylink_ethtool_set_eee()
3334 if (pl->mac_supports_eee_ops && !mac_eee) in phylink_ethtool_set_eee()
3337 if (pl->phydev) { in phylink_ethtool_set_eee()
3339 if (pl->mac_supports_eee_ops) in phylink_ethtool_set_eee()
3341 pl->supported_lpi); in phylink_ethtool_set_eee()
3342 ret = phy_ethtool_set_eee(pl->phydev, eee); in phylink_ethtool_set_eee()
3344 eee_to_eeecfg(&pl->eee_cfg, eee); in phylink_ethtool_set_eee()
3377 static int phylink_phy_read(struct phylink *pl, unsigned int phy_id, in phylink_phy_read() argument
3380 struct phy_device *phydev = pl->phydev; in phylink_phy_read()
3386 return mdiobus_c45_read(pl->phydev->mdio.bus, prtad, devad, in phylink_phy_read()
3412 return mdiobus_c45_read(pl->phydev->mdio.bus, prtad, devad, in phylink_phy_read()
3416 return mdiobus_read(pl->phydev->mdio.bus, phy_id, reg); in phylink_phy_read()
3419 static int phylink_phy_write(struct phylink *pl, unsigned int phy_id, in phylink_phy_write() argument
3422 struct phy_device *phydev = pl->phydev; in phylink_phy_write()
3428 return mdiobus_c45_write(pl->phydev->mdio.bus, prtad, devad, in phylink_phy_write()
3453 return mdiobus_c45_write(pl->phydev->mdio.bus, phy_id, devad, in phylink_phy_write()
3460 static int phylink_mii_read(struct phylink *pl, unsigned int phy_id, in phylink_mii_read() argument
3466 switch (pl->act_link_an_mode) { in phylink_mii_read()
3469 phylink_get_fixed_state(pl, &state); in phylink_mii_read()
3479 phylink_mac_pcs_get_state(pl, &state); in phylink_mii_read()
3488 static int phylink_mii_write(struct phylink *pl, unsigned int phy_id, in phylink_mii_write() argument
3491 switch (pl->act_link_an_mode) { in phylink_mii_write()
3523 int phylink_mii_ioctl(struct phylink *pl, struct ifreq *ifr, int cmd) in phylink_mii_ioctl() argument
3530 if (pl->phydev) { in phylink_mii_ioctl()
3534 mii->phy_id = pl->phydev->mdio.addr; in phylink_mii_ioctl()
3538 ret = phylink_phy_read(pl, mii->phy_id, mii->reg_num); in phylink_mii_ioctl()
3546 ret = phylink_phy_write(pl, mii->phy_id, mii->reg_num, in phylink_mii_ioctl()
3551 ret = phy_mii_ioctl(pl->phydev, ifr, cmd); in phylink_mii_ioctl()
3561 ret = phylink_mii_read(pl, mii->phy_id, mii->reg_num); in phylink_mii_ioctl()
3569 ret = phylink_mii_write(pl, mii->phy_id, mii->reg_num, in phylink_mii_ioctl()
3595 int phylink_speed_down(struct phylink *pl, bool sync) in phylink_speed_down() argument
3601 if (!pl->sfp_bus && pl->phydev) in phylink_speed_down()
3602 ret = phy_speed_down(pl->phydev, sync); in phylink_speed_down()
3618 int phylink_speed_up(struct phylink *pl) in phylink_speed_up() argument
3624 if (!pl->sfp_bus && pl->phydev) in phylink_speed_up()
3625 ret = phy_speed_up(pl->phydev); in phylink_speed_up()
3633 struct phylink *pl = upstream; in phylink_sfp_attach() local
3635 pl->netdev->sfp_bus = bus; in phylink_sfp_attach()
3640 struct phylink *pl = upstream; in phylink_sfp_detach() local
3642 pl->netdev->sfp_bus = NULL; in phylink_sfp_detach()
3645 static phy_interface_t phylink_choose_sfp_interface(struct phylink *pl, in phylink_choose_sfp_interface() argument
3661 static void phylink_sfp_set_config(struct phylink *pl, unsigned long *supported, in phylink_sfp_set_config() argument
3667 phylink_dbg(pl, "requesting link mode %s/%s with support %*pb\n", in phylink_sfp_set_config()
3671 if (!linkmode_equal(pl->supported, supported)) { in phylink_sfp_set_config()
3672 linkmode_copy(pl->supported, supported); in phylink_sfp_set_config()
3676 if (!linkmode_equal(pl->link_config.advertising, state->advertising)) { in phylink_sfp_set_config()
3677 linkmode_copy(pl->link_config.advertising, state->advertising); in phylink_sfp_set_config()
3681 if (pl->req_link_an_mode != mode || in phylink_sfp_set_config()
3682 pl->link_config.interface != state->interface) { in phylink_sfp_set_config()
3683 pl->req_link_an_mode = mode; in phylink_sfp_set_config()
3684 pl->link_config.interface = state->interface; in phylink_sfp_set_config()
3688 phylink_info(pl, "switched to %s/%s link mode\n", in phylink_sfp_set_config()
3694 &pl->phylink_disable_state)) in phylink_sfp_set_config()
3695 phylink_mac_initial_config(pl, false); in phylink_sfp_set_config()
3698 static int phylink_sfp_config_phy(struct phylink *pl, struct phy_device *phy) in phylink_sfp_config_phy() argument
3705 phy_interface_zero(pl->sfp_interfaces); in phylink_sfp_config_phy()
3716 ret = phylink_validate(pl, support, &config); in phylink_sfp_config_phy()
3718 phylink_err(pl, "validation with support %*pb failed: %pe\n", in phylink_sfp_config_phy()
3724 config.interface = phylink_sfp_select_interface(pl, config.advertising); in phylink_sfp_config_phy()
3731 ret = phylink_attach_phy(pl, phy, config.interface); in phylink_sfp_config_phy()
3736 ret = phylink_bringup_phy(pl, phy, config.interface); in phylink_sfp_config_phy()
3742 pl->link_port = pl->sfp_port; in phylink_sfp_config_phy()
3744 phylink_sfp_set_config(pl, support, &config, true); in phylink_sfp_config_phy()
3749 static int phylink_sfp_config_optical(struct phylink *pl) in phylink_sfp_config_optical() argument
3757 phylink_dbg(pl, "optical SFP: interfaces=[mac=%*pbl, sfp=%*pbl]\n", in phylink_sfp_config_optical()
3759 pl->config->supported_interfaces, in phylink_sfp_config_optical()
3761 pl->sfp_interfaces); in phylink_sfp_config_optical()
3766 phy_interface_and(pl->sfp_interfaces, pl->config->supported_interfaces, in phylink_sfp_config_optical()
3767 pl->sfp_interfaces); in phylink_sfp_config_optical()
3768 if (phy_interface_empty(pl->sfp_interfaces)) { in phylink_sfp_config_optical()
3769 phylink_err(pl, "unsupported SFP module: no common interface modes\n"); in phylink_sfp_config_optical()
3774 linkmode_copy(support, pl->sfp_support); in phylink_sfp_config_optical()
3775 linkmode_copy(config.advertising, pl->sfp_support); in phylink_sfp_config_optical()
3783 ret = phylink_validate_mask(pl, NULL, pl->sfp_support, &config, in phylink_sfp_config_optical()
3784 pl->sfp_interfaces); in phylink_sfp_config_optical()
3786 phylink_err(pl, "unsupported SFP module: validation with support %*pb failed\n", in phylink_sfp_config_optical()
3791 interface = phylink_choose_sfp_interface(pl, pl->sfp_interfaces); in phylink_sfp_config_optical()
3793 phylink_err(pl, "failed to select SFP interface\n"); in phylink_sfp_config_optical()
3797 phylink_dbg(pl, "optical SFP: chosen %s interface\n", in phylink_sfp_config_optical()
3807 if (phy_interface_weight(pl->sfp_interfaces) == 1) { in phylink_sfp_config_optical()
3809 pl->sfp_support); in phylink_sfp_config_optical()
3817 if (!phylink_validate_pcs_inband_autoneg(pl, interface, in phylink_sfp_config_optical()
3819 phylink_err(pl, "autoneg setting not compatible with PCS"); in phylink_sfp_config_optical()
3826 ret = phylink_validate(pl, support, &config); in phylink_sfp_config_optical()
3828 phylink_err(pl, "validation with support %*pb failed: %pe\n", in phylink_sfp_config_optical()
3834 pl->link_port = pl->sfp_port; in phylink_sfp_config_optical()
3836 phylink_sfp_set_config(pl, pl->sfp_support, &config, false); in phylink_sfp_config_optical()
3845 struct phylink *pl = upstream; in phylink_sfp_module_insert() local
3849 caps = sfp_get_module_caps(pl->sfp_bus); in phylink_sfp_module_insert()
3850 phy_interface_copy(pl->sfp_interfaces, caps->interfaces); in phylink_sfp_module_insert()
3851 linkmode_copy(pl->sfp_support, caps->link_modes); in phylink_sfp_module_insert()
3852 pl->sfp_may_have_phy = caps->may_have_phy; in phylink_sfp_module_insert()
3853 pl->sfp_port = caps->port; in phylink_sfp_module_insert()
3856 if (pl->sfp_may_have_phy) in phylink_sfp_module_insert()
3859 return phylink_sfp_config_optical(pl); in phylink_sfp_module_insert()
3864 struct phylink *pl = upstream; in phylink_sfp_module_remove() local
3866 phy_interface_zero(pl->sfp_interfaces); in phylink_sfp_module_remove()
3871 struct phylink *pl = upstream; in phylink_sfp_module_start() local
3874 if (pl->phydev) { in phylink_sfp_module_start()
3875 phy_start(pl->phydev); in phylink_sfp_module_start()
3882 if (!pl->sfp_may_have_phy) in phylink_sfp_module_start()
3885 return phylink_sfp_config_optical(pl); in phylink_sfp_module_start()
3890 struct phylink *pl = upstream; in phylink_sfp_module_stop() local
3893 if (pl->phydev) in phylink_sfp_module_stop()
3894 phy_stop(pl->phydev); in phylink_sfp_module_stop()
3899 struct phylink *pl = upstream; in phylink_sfp_link_down() local
3903 phylink_run_resolve_and_disable(pl, PHYLINK_DISABLE_LINK); in phylink_sfp_link_down()
3908 struct phylink *pl = upstream; in phylink_sfp_link_up() local
3912 phylink_enable_and_run_resolve(pl, PHYLINK_DISABLE_LINK); in phylink_sfp_link_up()
3917 struct phylink *pl = upstream; in phylink_sfp_connect_phy() local
3920 phylink_err(pl, "PHY %s (id 0x%.8lx) has no driver loaded\n", in phylink_sfp_connect_phy()
3922 …phylink_err(pl, "Drivers which handle known common cases: CONFIG_BCM84881_PHY, CONFIG_MARVELL_PHY\… in phylink_sfp_connect_phy()
3937 pl->config->supported_interfaces); in phylink_sfp_connect_phy()
3940 return phylink_sfp_config_phy(pl, phy); in phylink_sfp_connect_phy()
4378 void phylink_replay_link_begin(struct phylink *pl) in phylink_replay_link_begin() argument
4382 phylink_run_resolve_and_disable(pl, PHYLINK_DISABLE_REPLAY); in phylink_replay_link_begin()
4401 void phylink_replay_link_end(struct phylink *pl) in phylink_replay_link_end() argument
4406 &pl->phylink_disable_state), in phylink_replay_link_end()
4410 pl->force_major_config = true; in phylink_replay_link_end()
4411 phylink_enable_and_run_resolve(pl, PHYLINK_DISABLE_REPLAY); in phylink_replay_link_end()
4412 flush_work(&pl->resolve); in phylink_replay_link_end()