Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c1915300 authored by Philippe Reynes's avatar Philippe Reynes Committed by Jeff Kirsher
Browse files

igb: use new API ethtool_{get|set}_link_ksettings



The ethtool API {get|set}_settings is deprecated.
We move this driver to new API {get|set}_link_ksettings.

As I don't have the hardware, I'd be very pleased if
someone may test this patch.

Signed-off-by: default avatarPhilippe Reynes <tremyfr@gmail.com>
Tested-by: default avatarAaron Brown <aaron.f.brown@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent fb052fdd
Loading
Loading
Loading
Loading
+73 −65
Original line number Original line Diff line number Diff line
@@ -151,7 +151,8 @@ static const char igb_priv_flags_strings[][ETH_GSTRING_LEN] = {


#define IGB_PRIV_FLAGS_STR_LEN ARRAY_SIZE(igb_priv_flags_strings)
#define IGB_PRIV_FLAGS_STR_LEN ARRAY_SIZE(igb_priv_flags_strings)


static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
static int igb_get_link_ksettings(struct net_device *netdev,
				  struct ethtool_link_ksettings *cmd)
{
{
	struct igb_adapter *adapter = netdev_priv(netdev);
	struct igb_adapter *adapter = netdev_priv(netdev);
	struct e1000_hw *hw = &adapter->hw;
	struct e1000_hw *hw = &adapter->hw;
@@ -159,11 +160,12 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
	struct e1000_sfp_flags *eth_flags = &dev_spec->eth_flags;
	struct e1000_sfp_flags *eth_flags = &dev_spec->eth_flags;
	u32 status;
	u32 status;
	u32 speed;
	u32 speed;
	u32 supported, advertising;


	status = rd32(E1000_STATUS);
	status = rd32(E1000_STATUS);
	if (hw->phy.media_type == e1000_media_type_copper) {
	if (hw->phy.media_type == e1000_media_type_copper) {


		ecmd->supported = (SUPPORTED_10baseT_Half |
		supported = (SUPPORTED_10baseT_Half |
			     SUPPORTED_10baseT_Full |
			     SUPPORTED_10baseT_Full |
			     SUPPORTED_100baseT_Half |
			     SUPPORTED_100baseT_Half |
			     SUPPORTED_100baseT_Full |
			     SUPPORTED_100baseT_Full |
@@ -171,63 +173,59 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
			     SUPPORTED_Autoneg |
			     SUPPORTED_Autoneg |
			     SUPPORTED_TP |
			     SUPPORTED_TP |
			     SUPPORTED_Pause);
			     SUPPORTED_Pause);
		ecmd->advertising = ADVERTISED_TP;
		advertising = ADVERTISED_TP;


		if (hw->mac.autoneg == 1) {
		if (hw->mac.autoneg == 1) {
			ecmd->advertising |= ADVERTISED_Autoneg;
			advertising |= ADVERTISED_Autoneg;
			/* the e1000 autoneg seems to match ethtool nicely */
			/* the e1000 autoneg seems to match ethtool nicely */
			ecmd->advertising |= hw->phy.autoneg_advertised;
			advertising |= hw->phy.autoneg_advertised;
		}
		}


		ecmd->port = PORT_TP;
		cmd->base.port = PORT_TP;
		ecmd->phy_address = hw->phy.addr;
		cmd->base.phy_address = hw->phy.addr;
		ecmd->transceiver = XCVR_INTERNAL;
	} else {
	} else {
		ecmd->supported = (SUPPORTED_FIBRE |
		supported = (SUPPORTED_FIBRE |
			     SUPPORTED_1000baseKX_Full |
			     SUPPORTED_1000baseKX_Full |
			     SUPPORTED_Autoneg |
			     SUPPORTED_Autoneg |
			     SUPPORTED_Pause);
			     SUPPORTED_Pause);
		ecmd->advertising = (ADVERTISED_FIBRE |
		advertising = (ADVERTISED_FIBRE |
			       ADVERTISED_1000baseKX_Full);
			       ADVERTISED_1000baseKX_Full);
		if (hw->mac.type == e1000_i354) {
		if (hw->mac.type == e1000_i354) {
			if ((hw->device_id ==
			if ((hw->device_id ==
			     E1000_DEV_ID_I354_BACKPLANE_2_5GBPS) &&
			     E1000_DEV_ID_I354_BACKPLANE_2_5GBPS) &&
			    !(status & E1000_STATUS_2P5_SKU_OVER)) {
			    !(status & E1000_STATUS_2P5_SKU_OVER)) {
				ecmd->supported |= SUPPORTED_2500baseX_Full;
				supported |= SUPPORTED_2500baseX_Full;
				ecmd->supported &=
				supported &= ~SUPPORTED_1000baseKX_Full;
					~SUPPORTED_1000baseKX_Full;
				advertising |= ADVERTISED_2500baseX_Full;
				ecmd->advertising |= ADVERTISED_2500baseX_Full;
				advertising &= ~ADVERTISED_1000baseKX_Full;
				ecmd->advertising &=
					~ADVERTISED_1000baseKX_Full;
			}
			}
		}
		}
		if (eth_flags->e100_base_fx) {
		if (eth_flags->e100_base_fx) {
			ecmd->supported |= SUPPORTED_100baseT_Full;
			supported |= SUPPORTED_100baseT_Full;
			ecmd->advertising |= ADVERTISED_100baseT_Full;
			advertising |= ADVERTISED_100baseT_Full;
		}
		}
		if (hw->mac.autoneg == 1)
		if (hw->mac.autoneg == 1)
			ecmd->advertising |= ADVERTISED_Autoneg;
			advertising |= ADVERTISED_Autoneg;


		ecmd->port = PORT_FIBRE;
		cmd->base.port = PORT_FIBRE;
		ecmd->transceiver = XCVR_EXTERNAL;
	}
	}
	if (hw->mac.autoneg != 1)
	if (hw->mac.autoneg != 1)
		ecmd->advertising &= ~(ADVERTISED_Pause |
		advertising &= ~(ADVERTISED_Pause |
				 ADVERTISED_Asym_Pause);
				 ADVERTISED_Asym_Pause);


	switch (hw->fc.requested_mode) {
	switch (hw->fc.requested_mode) {
	case e1000_fc_full:
	case e1000_fc_full:
		ecmd->advertising |= ADVERTISED_Pause;
		advertising |= ADVERTISED_Pause;
		break;
		break;
	case e1000_fc_rx_pause:
	case e1000_fc_rx_pause:
		ecmd->advertising |= (ADVERTISED_Pause |
		advertising |= (ADVERTISED_Pause |
				ADVERTISED_Asym_Pause);
				ADVERTISED_Asym_Pause);
		break;
		break;
	case e1000_fc_tx_pause:
	case e1000_fc_tx_pause:
		ecmd->advertising |=  ADVERTISED_Asym_Pause;
		advertising |=  ADVERTISED_Asym_Pause;
		break;
		break;
	default:
	default:
		ecmd->advertising &= ~(ADVERTISED_Pause |
		advertising &= ~(ADVERTISED_Pause |
				 ADVERTISED_Asym_Pause);
				 ADVERTISED_Asym_Pause);
	}
	}
	if (status & E1000_STATUS_LU) {
	if (status & E1000_STATUS_LU) {
@@ -243,39 +241,46 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
		}
		}
		if ((status & E1000_STATUS_FD) ||
		if ((status & E1000_STATUS_FD) ||
		    hw->phy.media_type != e1000_media_type_copper)
		    hw->phy.media_type != e1000_media_type_copper)
			ecmd->duplex = DUPLEX_FULL;
			cmd->base.duplex = DUPLEX_FULL;
		else
		else
			ecmd->duplex = DUPLEX_HALF;
			cmd->base.duplex = DUPLEX_HALF;
	} else {
	} else {
		speed = SPEED_UNKNOWN;
		speed = SPEED_UNKNOWN;
		ecmd->duplex = DUPLEX_UNKNOWN;
		cmd->base.duplex = DUPLEX_UNKNOWN;
	}
	}
	ethtool_cmd_speed_set(ecmd, speed);
	cmd->base.speed = speed;
	if ((hw->phy.media_type == e1000_media_type_fiber) ||
	if ((hw->phy.media_type == e1000_media_type_fiber) ||
	    hw->mac.autoneg)
	    hw->mac.autoneg)
		ecmd->autoneg = AUTONEG_ENABLE;
		cmd->base.autoneg = AUTONEG_ENABLE;
	else
	else
		ecmd->autoneg = AUTONEG_DISABLE;
		cmd->base.autoneg = AUTONEG_DISABLE;


	/* MDI-X => 2; MDI =>1; Invalid =>0 */
	/* MDI-X => 2; MDI =>1; Invalid =>0 */
	if (hw->phy.media_type == e1000_media_type_copper)
	if (hw->phy.media_type == e1000_media_type_copper)
		ecmd->eth_tp_mdix = hw->phy.is_mdix ? ETH_TP_MDI_X :
		cmd->base.eth_tp_mdix = hw->phy.is_mdix ? ETH_TP_MDI_X :
						      ETH_TP_MDI;
						      ETH_TP_MDI;
	else
	else
		ecmd->eth_tp_mdix = ETH_TP_MDI_INVALID;
		cmd->base.eth_tp_mdix = ETH_TP_MDI_INVALID;


	if (hw->phy.mdix == AUTO_ALL_MODES)
	if (hw->phy.mdix == AUTO_ALL_MODES)
		ecmd->eth_tp_mdix_ctrl = ETH_TP_MDI_AUTO;
		cmd->base.eth_tp_mdix_ctrl = ETH_TP_MDI_AUTO;
	else
	else
		ecmd->eth_tp_mdix_ctrl = hw->phy.mdix;
		cmd->base.eth_tp_mdix_ctrl = hw->phy.mdix;

	ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported,
						supported);
	ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising,
						advertising);


	return 0;
	return 0;
}
}


static int igb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
static int igb_set_link_ksettings(struct net_device *netdev,
				  const struct ethtool_link_ksettings *cmd)
{
{
	struct igb_adapter *adapter = netdev_priv(netdev);
	struct igb_adapter *adapter = netdev_priv(netdev);
	struct e1000_hw *hw = &adapter->hw;
	struct e1000_hw *hw = &adapter->hw;
	u32 advertising;


	/* When SoL/IDER sessions are active, autoneg/speed/duplex
	/* When SoL/IDER sessions are active, autoneg/speed/duplex
	 * cannot be changed
	 * cannot be changed
@@ -290,12 +295,12 @@ static int igb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
	 * some hardware doesn't allow MDI setting when speed or
	 * some hardware doesn't allow MDI setting when speed or
	 * duplex is forced.
	 * duplex is forced.
	 */
	 */
	if (ecmd->eth_tp_mdix_ctrl) {
	if (cmd->base.eth_tp_mdix_ctrl) {
		if (hw->phy.media_type != e1000_media_type_copper)
		if (hw->phy.media_type != e1000_media_type_copper)
			return -EOPNOTSUPP;
			return -EOPNOTSUPP;


		if ((ecmd->eth_tp_mdix_ctrl != ETH_TP_MDI_AUTO) &&
		if ((cmd->base.eth_tp_mdix_ctrl != ETH_TP_MDI_AUTO) &&
		    (ecmd->autoneg != AUTONEG_ENABLE)) {
		    (cmd->base.autoneg != AUTONEG_ENABLE)) {
			dev_err(&adapter->pdev->dev, "forcing MDI/MDI-X state is not supported when link speed and/or duplex are forced\n");
			dev_err(&adapter->pdev->dev, "forcing MDI/MDI-X state is not supported when link speed and/or duplex are forced\n");
			return -EINVAL;
			return -EINVAL;
		}
		}
@@ -304,10 +309,13 @@ static int igb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
	while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
	while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
		usleep_range(1000, 2000);
		usleep_range(1000, 2000);


	if (ecmd->autoneg == AUTONEG_ENABLE) {
	ethtool_convert_link_mode_to_legacy_u32(&advertising,
						cmd->link_modes.advertising);

	if (cmd->base.autoneg == AUTONEG_ENABLE) {
		hw->mac.autoneg = 1;
		hw->mac.autoneg = 1;
		if (hw->phy.media_type == e1000_media_type_fiber) {
		if (hw->phy.media_type == e1000_media_type_fiber) {
			hw->phy.autoneg_advertised = ecmd->advertising |
			hw->phy.autoneg_advertised = advertising |
						     ADVERTISED_FIBRE |
						     ADVERTISED_FIBRE |
						     ADVERTISED_Autoneg;
						     ADVERTISED_Autoneg;
			switch (adapter->link_speed) {
			switch (adapter->link_speed) {
@@ -327,31 +335,31 @@ static int igb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
				break;
				break;
			}
			}
		} else {
		} else {
			hw->phy.autoneg_advertised = ecmd->advertising |
			hw->phy.autoneg_advertised = advertising |
						     ADVERTISED_TP |
						     ADVERTISED_TP |
						     ADVERTISED_Autoneg;
						     ADVERTISED_Autoneg;
		}
		}
		ecmd->advertising = hw->phy.autoneg_advertised;
		advertising = hw->phy.autoneg_advertised;
		if (adapter->fc_autoneg)
		if (adapter->fc_autoneg)
			hw->fc.requested_mode = e1000_fc_default;
			hw->fc.requested_mode = e1000_fc_default;
	} else {
	} else {
		u32 speed = ethtool_cmd_speed(ecmd);
		u32 speed = cmd->base.speed;
		/* calling this overrides forced MDI setting */
		/* calling this overrides forced MDI setting */
		if (igb_set_spd_dplx(adapter, speed, ecmd->duplex)) {
		if (igb_set_spd_dplx(adapter, speed, cmd->base.duplex)) {
			clear_bit(__IGB_RESETTING, &adapter->state);
			clear_bit(__IGB_RESETTING, &adapter->state);
			return -EINVAL;
			return -EINVAL;
		}
		}
	}
	}


	/* MDI-X => 2; MDI => 1; Auto => 3 */
	/* MDI-X => 2; MDI => 1; Auto => 3 */
	if (ecmd->eth_tp_mdix_ctrl) {
	if (cmd->base.eth_tp_mdix_ctrl) {
		/* fix up the value for auto (3 => 0) as zero is mapped
		/* fix up the value for auto (3 => 0) as zero is mapped
		 * internally to auto
		 * internally to auto
		 */
		 */
		if (ecmd->eth_tp_mdix_ctrl == ETH_TP_MDI_AUTO)
		if (cmd->base.eth_tp_mdix_ctrl == ETH_TP_MDI_AUTO)
			hw->phy.mdix = AUTO_ALL_MODES;
			hw->phy.mdix = AUTO_ALL_MODES;
		else
		else
			hw->phy.mdix = ecmd->eth_tp_mdix_ctrl;
			hw->phy.mdix = cmd->base.eth_tp_mdix_ctrl;
	}
	}


	/* reset the link */
	/* reset the link */
@@ -3444,8 +3452,6 @@ static int igb_set_priv_flags(struct net_device *netdev, u32 priv_flags)
}
}


static const struct ethtool_ops igb_ethtool_ops = {
static const struct ethtool_ops igb_ethtool_ops = {
	.get_settings		= igb_get_settings,
	.set_settings		= igb_set_settings,
	.get_drvinfo		= igb_get_drvinfo,
	.get_drvinfo		= igb_get_drvinfo,
	.get_regs_len		= igb_get_regs_len,
	.get_regs_len		= igb_get_regs_len,
	.get_regs		= igb_get_regs,
	.get_regs		= igb_get_regs,
@@ -3485,6 +3491,8 @@ static const struct ethtool_ops igb_ethtool_ops = {
	.set_priv_flags		= igb_set_priv_flags,
	.set_priv_flags		= igb_set_priv_flags,
	.begin			= igb_ethtool_begin,
	.begin			= igb_ethtool_begin,
	.complete		= igb_ethtool_complete,
	.complete		= igb_ethtool_complete,
	.get_link_ksettings	= igb_get_link_ksettings,
	.set_link_ksettings	= igb_set_link_ksettings,
};
};


void igb_set_ethtool_ops(struct net_device *netdev)
void igb_set_ethtool_ops(struct net_device *netdev)