static int phy_led_trigger_register(struct phy_device *phy, struct phy_led_trigger *plt, unsigned int speed) { plt->speed = speed; phy_led_trigger_format_name(phy, plt->name, sizeof(plt->name), phy_speed_to_str(speed)); plt->trigger.name = plt->name; return led_trigger_register(&plt->trigger); }
/** * phy_print_status - Convenience function to print out the current phy status * @phydev: the phy_device struct */ void phy_print_status(struct phy_device *phydev) { if (phydev->link) { netdev_info(phydev->attached_dev, "Link is Up - %s/%s - flow control %s\n", phy_speed_to_str(phydev->speed), DUPLEX_FULL == phydev->duplex ? "Full" : "Half", phydev->pause ? "rx/tx" : "off"); } else { netdev_info(phydev->attached_dev, "Link is Down\n"); } }
static void phylink_mac_config(struct phylink *pl, const struct phylink_link_state *state) { netdev_dbg(pl->netdev, "%s: mode=%s/%s/%s/%s adv=%*pb pause=%02x link=%u an=%u\n", __func__, phylink_an_mode_str(pl->link_an_mode), phy_modes(state->interface), phy_speed_to_str(state->speed), phy_duplex_to_str(state->duplex), __ETHTOOL_LINK_MODE_MASK_NBITS, state->advertising, state->pause, state->link, state->an_enabled); pl->ops->mac_config(pl->netdev, pl->link_an_mode, state); }
static void phylink_phy_change(struct phy_device *phydev, bool up, bool do_carrier) { struct phylink *pl = phydev->phylink; mutex_lock(&pl->state_mutex); pl->phy_state.speed = phydev->speed; pl->phy_state.duplex = phydev->duplex; pl->phy_state.pause = MLO_PAUSE_NONE; if (phydev->pause) pl->phy_state.pause |= MLO_PAUSE_SYM; if (phydev->asym_pause) pl->phy_state.pause |= MLO_PAUSE_ASYM; pl->phy_state.interface = phydev->interface; pl->phy_state.link = up; mutex_unlock(&pl->state_mutex); phylink_run_resolve(pl); netdev_dbg(pl->netdev, "phy link %s %s/%s/%s\n", up ? "up" : "down", phy_modes(phydev->interface), phy_speed_to_str(phydev->speed), phy_duplex_to_str(phydev->duplex)); }
static void phylink_resolve(struct work_struct *w) { struct phylink *pl = container_of(w, struct phylink, resolve); struct phylink_link_state link_state; struct net_device *ndev = pl->netdev; mutex_lock(&pl->state_mutex); if (pl->phylink_disable_state) { pl->mac_link_dropped = false; link_state.link = false; } else if (pl->mac_link_dropped) { link_state.link = false; } else { switch (pl->link_an_mode) { case MLO_AN_PHY: link_state = pl->phy_state; phylink_resolve_flow(pl, &link_state); phylink_mac_config(pl, &link_state); break; case MLO_AN_FIXED: phylink_get_fixed_state(pl, &link_state); phylink_mac_config(pl, &link_state); break; case MLO_AN_SGMII: phylink_get_mac_state(pl, &link_state); if (pl->phydev) { bool changed = false; link_state.link = link_state.link && pl->phy_state.link; if (pl->phy_state.interface != link_state.interface) { link_state.interface = pl->phy_state.interface; changed = true; } /* Propagate the flow control from the PHY * to the MAC. Also propagate the interface * if changed. */ if (pl->phy_state.link || changed) { link_state.pause |= pl->phy_state.pause; phylink_resolve_flow(pl, &link_state); phylink_mac_config(pl, &link_state); } } break; case MLO_AN_8023Z: phylink_get_mac_state(pl, &link_state); break; } } if (link_state.link != netif_carrier_ok(ndev)) { if (!link_state.link) { netif_carrier_off(ndev); pl->ops->mac_link_down(ndev, pl->link_an_mode); netdev_info(ndev, "Link is Down\n"); } else { pl->ops->mac_link_up(ndev, pl->link_an_mode, pl->phydev); netif_carrier_on(ndev); netdev_info(ndev, "Link is Up - %s/%s - flow control %s\n", phy_speed_to_str(link_state.speed), phy_duplex_to_str(link_state.duplex), phylink_pause_to_str(link_state.pause)); } } if (!link_state.link && pl->mac_link_dropped) { pl->mac_link_dropped = false; queue_work(system_power_efficient_wq, &pl->resolve); } mutex_unlock(&pl->state_mutex); }
static void phylink_resolve(struct work_struct *w) { struct phylink *pl = container_of(w, struct phylink, resolve); struct phylink_link_state link_state; struct net_device *ndev = pl->netdev; mutex_lock(&pl->state_mutex); if (pl->phylink_disable_state) { pl->mac_link_dropped = false; link_state.link = false; } else if (pl->mac_link_dropped) { link_state.link = false; } else { switch (pl->link_an_mode) { case MLO_AN_PHY: link_state = pl->phy_state; phylink_resolve_flow(pl, &link_state); phylink_mac_config_up(pl, &link_state); break; case MLO_AN_FIXED: phylink_get_fixed_state(pl, &link_state); phylink_mac_config_up(pl, &link_state); break; case MLO_AN_INBAND: phylink_get_mac_state(pl, &link_state); /* If we have a phy, the "up" state is the union of * both the PHY and the MAC */ if (pl->phydev) link_state.link &= pl->phy_state.link; /* Only update if the PHY link is up */ if (pl->phydev && pl->phy_state.link) { link_state.interface = pl->phy_state.interface; /* If we have a PHY, we need to update with * the pause mode bits. */ link_state.pause |= pl->phy_state.pause; phylink_resolve_flow(pl, &link_state); phylink_mac_config(pl, &link_state); } break; } } if (link_state.link != netif_carrier_ok(ndev)) { if (!link_state.link) { netif_carrier_off(ndev); pl->ops->mac_link_down(ndev, pl->link_an_mode, pl->phy_state.interface); netdev_info(ndev, "Link is Down\n"); } else { pl->ops->mac_link_up(ndev, pl->link_an_mode, pl->phy_state.interface, pl->phydev); netif_carrier_on(ndev); netdev_info(ndev, "Link is Up - %s/%s - flow control %s\n", phy_speed_to_str(link_state.speed), phy_duplex_to_str(link_state.duplex), phylink_pause_to_str(link_state.pause)); } } if (!link_state.link && pl->mac_link_dropped) { pl->mac_link_dropped = false; queue_work(system_power_efficient_wq, &pl->resolve); } mutex_unlock(&pl->state_mutex); }