static int xgene_get_link_ksettings(struct net_device *ndev, struct ethtool_link_ksettings *cmd) { struct xgene_enet_pdata *pdata = netdev_priv(ndev); struct phy_device *phydev = ndev->phydev; u32 supported; if (phy_interface_mode_is_rgmii(pdata->phy_mode)) { if (phydev == NULL) return -ENODEV; phy_ethtool_ksettings_get(phydev, cmd); return 0; } else if (pdata->phy_mode == PHY_INTERFACE_MODE_SGMII) { if (pdata->mdio_driver) { if (!phydev) return -ENODEV; phy_ethtool_ksettings_get(phydev, cmd); return 0; } supported = SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_MII; ethtool_convert_legacy_u32_to_link_mode( cmd->link_modes.supported, supported); ethtool_convert_legacy_u32_to_link_mode( cmd->link_modes.advertising, supported); cmd->base.speed = SPEED_1000; cmd->base.duplex = DUPLEX_FULL; cmd->base.port = PORT_MII; cmd->base.autoneg = AUTONEG_ENABLE; } else { supported = SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE; ethtool_convert_legacy_u32_to_link_mode( cmd->link_modes.supported, supported); ethtool_convert_legacy_u32_to_link_mode( cmd->link_modes.advertising, supported); cmd->base.speed = SPEED_10000; cmd->base.duplex = DUPLEX_FULL; cmd->base.port = PORT_FIBRE; cmd->base.autoneg = AUTONEG_DISABLE; } return 0; }
static int uec_get_ksettings(struct net_device *netdev, struct ethtool_link_ksettings *cmd) { struct ucc_geth_private *ugeth = netdev_priv(netdev); struct phy_device *phydev = ugeth->phydev; if (!phydev) return -ENODEV; return phy_ethtool_ksettings_get(phydev, cmd); }
static int dpaa_get_link_ksettings(struct net_device *net_dev, struct ethtool_link_ksettings *cmd) { if (!net_dev->phydev) { netdev_dbg(net_dev, "phy device not initialized\n"); return 0; } phy_ethtool_ksettings_get(net_dev->phydev, cmd); return 0; }
static int hns3_get_link_ksettings(struct net_device *netdev, struct ethtool_link_ksettings *cmd) { struct hnae3_handle *h = hns3_get_handle(netdev); const struct hnae3_ae_ops *ops; u8 media_type; u8 link_stat; if (!h->ae_algo || !h->ae_algo->ops) return -EOPNOTSUPP; ops = h->ae_algo->ops; if (ops->get_media_type) ops->get_media_type(h, &media_type); else return -EOPNOTSUPP; switch (media_type) { case HNAE3_MEDIA_TYPE_NONE: cmd->base.port = PORT_NONE; hns3_get_ksettings(h, cmd); break; case HNAE3_MEDIA_TYPE_FIBER: cmd->base.port = PORT_FIBRE; hns3_get_ksettings(h, cmd); break; case HNAE3_MEDIA_TYPE_COPPER: cmd->base.port = PORT_TP; if (!netdev->phydev) hns3_get_ksettings(h, cmd); else phy_ethtool_ksettings_get(netdev->phydev, cmd); break; default: netdev_warn(netdev, "Unknown media type"); return 0; } /* mdio_support */ cmd->base.mdio_support = ETH_MDIO_SUPPORTS_C22; link_stat = hns3_get_link(netdev); if (!link_stat) { cmd->base.speed = SPEED_UNKNOWN; cmd->base.duplex = DUPLEX_UNKNOWN; } return 0; }
int phylink_ethtool_ksettings_get(struct phylink *pl, struct ethtool_link_ksettings *kset) { struct phylink_link_state link_state; WARN_ON(!lockdep_rtnl_is_held()); if (pl->phydev) { phy_ethtool_ksettings_get(pl->phydev, kset); } else { kset->base.port = pl->link_port; } linkmode_copy(kset->link_modes.supported, pl->supported); switch (pl->link_an_mode) { case MLO_AN_FIXED: /* We are using fixed settings. Report these as the * current link settings - and note that these also * represent the supported speeds/duplex/pause modes. */ phylink_get_fixed_state(pl, &link_state); phylink_get_ksettings(&link_state, kset); break; case MLO_AN_SGMII: /* If there is a phy attached, then use the reported * settings from the phy with no modification. */ if (pl->phydev) break; case MLO_AN_8023Z: phylink_get_mac_state(pl, &link_state); /* The MAC is reporting the link results from its own PCS * layer via in-band status. Report these as the current * link settings. */ phylink_get_ksettings(&link_state, kset); break; } return 0; }
/** *hns_nic_get_link_ksettings - implement ethtool get link ksettings *@net_dev: net_device *@cmd: ethtool_link_ksettings *retuen 0 - success , negative --fail */ static int hns_nic_get_link_ksettings(struct net_device *net_dev, struct ethtool_link_ksettings *cmd) { struct hns_nic_priv *priv = netdev_priv(net_dev); struct hnae_handle *h; u32 link_stat; int ret; u8 duplex; u16 speed; u32 supported, advertising; if (!priv || !priv->ae_handle) return -ESRCH; h = priv->ae_handle; if (!h->dev || !h->dev->ops || !h->dev->ops->get_info) return -ESRCH; ret = h->dev->ops->get_info(h, NULL, &speed, &duplex); if (ret < 0) { netdev_err(net_dev, "%s get_info error!\n", __func__); return -EINVAL; } ethtool_convert_link_mode_to_legacy_u32(&supported, cmd->link_modes.supported); ethtool_convert_link_mode_to_legacy_u32(&advertising, cmd->link_modes.advertising); /* When there is no phy, autoneg is off. */ cmd->base.autoneg = false; cmd->base.cmd = speed; cmd->base.duplex = duplex; if (net_dev->phydev) (void)phy_ethtool_ksettings_get(net_dev->phydev, cmd); link_stat = hns_nic_get_link(net_dev); if (!link_stat) { cmd->base.speed = (u32)SPEED_UNKNOWN; cmd->base.duplex = DUPLEX_UNKNOWN; } if (cmd->base.autoneg) advertising |= ADVERTISED_Autoneg; supported |= h->if_support; if (h->phy_if == PHY_INTERFACE_MODE_SGMII) { supported |= SUPPORTED_TP; advertising |= ADVERTISED_1000baseT_Full; } else if (h->phy_if == PHY_INTERFACE_MODE_XGMII) { supported |= SUPPORTED_FIBRE; advertising |= ADVERTISED_10000baseKR_Full; } switch (h->media_type) { case HNAE_MEDIA_TYPE_FIBER: cmd->base.port = PORT_FIBRE; break; case HNAE_MEDIA_TYPE_COPPER: cmd->base.port = PORT_TP; break; case HNAE_MEDIA_TYPE_UNKNOWN: default: break; } if (!(AE_IS_VER1(priv->enet_ver) && h->port_type == HNAE_PORT_DEBUG)) supported |= SUPPORTED_Pause; ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported, supported); ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising, advertising); cmd->base.mdio_support = ETH_MDIO_SUPPORTS_C45 | ETH_MDIO_SUPPORTS_C22; hns_get_mdix_mode(net_dev, cmd); return 0; }
static int hns3_get_link_ksettings(struct net_device *netdev, struct ethtool_link_ksettings *cmd) { struct hnae3_handle *h = hns3_get_handle(netdev); u32 flowctrl_adv = 0; u8 link_stat; if (!h->ae_algo || !h->ae_algo->ops) return -EOPNOTSUPP; /* 1.auto_neg & speed & duplex from cmd */ if (netdev->phydev) { phy_ethtool_ksettings_get(netdev->phydev, cmd); return 0; } if (h->ae_algo->ops->get_ksettings_an_result) h->ae_algo->ops->get_ksettings_an_result(h, &cmd->base.autoneg, &cmd->base.speed, &cmd->base.duplex); else return -EOPNOTSUPP; link_stat = hns3_get_link(netdev); if (!link_stat) { cmd->base.speed = SPEED_UNKNOWN; cmd->base.duplex = DUPLEX_UNKNOWN; } /* 2.get link mode and port type*/ if (h->ae_algo->ops->get_link_mode) h->ae_algo->ops->get_link_mode(h, cmd->link_modes.supported, cmd->link_modes.advertising); cmd->base.port = PORT_NONE; if (h->ae_algo->ops->get_port_type) h->ae_algo->ops->get_port_type(h, &cmd->base.port); /* 3.mdix_ctrl&mdix get from phy reg */ if (h->ae_algo->ops->get_mdix_mode) h->ae_algo->ops->get_mdix_mode(h, &cmd->base.eth_tp_mdix_ctrl, &cmd->base.eth_tp_mdix); /* 4.mdio_support */ cmd->base.mdio_support = ETH_MDIO_SUPPORTS_C22; /* 5.get flow control setttings */ if (h->ae_algo->ops->get_flowctrl_adv) h->ae_algo->ops->get_flowctrl_adv(h, &flowctrl_adv); if (flowctrl_adv & ADVERTISED_Pause) ethtool_link_ksettings_add_link_mode(cmd, advertising, Pause); if (flowctrl_adv & ADVERTISED_Asym_Pause) ethtool_link_ksettings_add_link_mode(cmd, advertising, Asym_Pause); return 0; }