예제 #1
0
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;
}
예제 #2
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);
}
예제 #3
0
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;
}
예제 #4
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;
}
예제 #5
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;
}
예제 #6
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;
}
예제 #7
0
파일: hns3_ethtool.c 프로젝트: Lyude/linux
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;
}