Commit 7ada7ca5 authored by David S. Miller's avatar David S. Miller

Merge branch '1GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue

Jeff Kirsher says:

====================
Intel Wired LAN Driver Updates 2017-03-21

This series contains updates to e1000, e1000e, igb, igbvf and ixgb.

This finishes up the work Philippe Reynes did to update the Intel drivers
to the new API for ethtool (get|set)_link_ksettings.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 592d42ac f22913d0
......@@ -103,104 +103,104 @@ static const char e1000_gstrings_test[][ETH_GSTRING_LEN] = {
#define E1000_TEST_LEN ARRAY_SIZE(e1000_gstrings_test)
static int e1000_get_settings(struct net_device *netdev,
struct ethtool_cmd *ecmd)
static int e1000_get_link_ksettings(struct net_device *netdev,
struct ethtool_link_ksettings *cmd)
{
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
u32 supported, advertising;
if (hw->media_type == e1000_media_type_copper) {
ecmd->supported = (SUPPORTED_10baseT_Half |
SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half |
SUPPORTED_100baseT_Full |
SUPPORTED_1000baseT_Full|
SUPPORTED_Autoneg |
SUPPORTED_TP);
ecmd->advertising = ADVERTISED_TP;
supported = (SUPPORTED_10baseT_Half |
SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half |
SUPPORTED_100baseT_Full |
SUPPORTED_1000baseT_Full|
SUPPORTED_Autoneg |
SUPPORTED_TP);
advertising = ADVERTISED_TP;
if (hw->autoneg == 1) {
ecmd->advertising |= ADVERTISED_Autoneg;
advertising |= ADVERTISED_Autoneg;
/* the e1000 autoneg seems to match ethtool nicely */
ecmd->advertising |= hw->autoneg_advertised;
advertising |= hw->autoneg_advertised;
}
ecmd->port = PORT_TP;
ecmd->phy_address = hw->phy_addr;
if (hw->mac_type == e1000_82543)
ecmd->transceiver = XCVR_EXTERNAL;
else
ecmd->transceiver = XCVR_INTERNAL;
cmd->base.port = PORT_TP;
cmd->base.phy_address = hw->phy_addr;
} else {
ecmd->supported = (SUPPORTED_1000baseT_Full |
SUPPORTED_FIBRE |
SUPPORTED_Autoneg);
supported = (SUPPORTED_1000baseT_Full |
SUPPORTED_FIBRE |
SUPPORTED_Autoneg);
ecmd->advertising = (ADVERTISED_1000baseT_Full |
ADVERTISED_FIBRE |
ADVERTISED_Autoneg);
advertising = (ADVERTISED_1000baseT_Full |
ADVERTISED_FIBRE |
ADVERTISED_Autoneg);
ecmd->port = PORT_FIBRE;
if (hw->mac_type >= e1000_82545)
ecmd->transceiver = XCVR_INTERNAL;
else
ecmd->transceiver = XCVR_EXTERNAL;
cmd->base.port = PORT_FIBRE;
}
if (er32(STATUS) & E1000_STATUS_LU) {
e1000_get_speed_and_duplex(hw, &adapter->link_speed,
&adapter->link_duplex);
ethtool_cmd_speed_set(ecmd, adapter->link_speed);
cmd->base.speed = adapter->link_speed;
/* unfortunately FULL_DUPLEX != DUPLEX_FULL
* and HALF_DUPLEX != DUPLEX_HALF
*/
if (adapter->link_duplex == FULL_DUPLEX)
ecmd->duplex = DUPLEX_FULL;
cmd->base.duplex = DUPLEX_FULL;
else
ecmd->duplex = DUPLEX_HALF;
cmd->base.duplex = DUPLEX_HALF;
} else {
ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN);
ecmd->duplex = DUPLEX_UNKNOWN;
cmd->base.speed = SPEED_UNKNOWN;
cmd->base.duplex = DUPLEX_UNKNOWN;
}
ecmd->autoneg = ((hw->media_type == e1000_media_type_fiber) ||
cmd->base.autoneg = ((hw->media_type == e1000_media_type_fiber) ||
hw->autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE;
/* MDI-X => 1; MDI => 0 */
if ((hw->media_type == e1000_media_type_copper) &&
netif_carrier_ok(netdev))
ecmd->eth_tp_mdix = (!!adapter->phy_info.mdix_mode ?
cmd->base.eth_tp_mdix = (!!adapter->phy_info.mdix_mode ?
ETH_TP_MDI_X : ETH_TP_MDI);
else
ecmd->eth_tp_mdix = ETH_TP_MDI_INVALID;
cmd->base.eth_tp_mdix = ETH_TP_MDI_INVALID;
if (hw->mdix == AUTO_ALL_MODES)
ecmd->eth_tp_mdix_ctrl = ETH_TP_MDI_AUTO;
cmd->base.eth_tp_mdix_ctrl = ETH_TP_MDI_AUTO;
else
ecmd->eth_tp_mdix_ctrl = hw->mdix;
cmd->base.eth_tp_mdix_ctrl = hw->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;
}
static int e1000_set_settings(struct net_device *netdev,
struct ethtool_cmd *ecmd)
static int e1000_set_link_ksettings(struct net_device *netdev,
const struct ethtool_link_ksettings *cmd)
{
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
u32 advertising;
ethtool_convert_link_mode_to_legacy_u32(&advertising,
cmd->link_modes.advertising);
/* MDI setting is only allowed when autoneg enabled because
* some hardware doesn't allow MDI setting when speed or
* duplex is forced.
*/
if (ecmd->eth_tp_mdix_ctrl) {
if (cmd->base.eth_tp_mdix_ctrl) {
if (hw->media_type != e1000_media_type_copper)
return -EOPNOTSUPP;
if ((ecmd->eth_tp_mdix_ctrl != ETH_TP_MDI_AUTO) &&
(ecmd->autoneg != AUTONEG_ENABLE)) {
if ((cmd->base.eth_tp_mdix_ctrl != ETH_TP_MDI_AUTO) &&
(cmd->base.autoneg != AUTONEG_ENABLE)) {
e_err(drv, "forcing MDI/MDI-X state is not supported when link speed and/or duplex are forced\n");
return -EINVAL;
}
......@@ -209,32 +209,31 @@ static int e1000_set_settings(struct net_device *netdev,
while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
msleep(1);
if (ecmd->autoneg == AUTONEG_ENABLE) {
if (cmd->base.autoneg == AUTONEG_ENABLE) {
hw->autoneg = 1;
if (hw->media_type == e1000_media_type_fiber)
hw->autoneg_advertised = ADVERTISED_1000baseT_Full |
ADVERTISED_FIBRE |
ADVERTISED_Autoneg;
ADVERTISED_FIBRE |
ADVERTISED_Autoneg;
else
hw->autoneg_advertised = ecmd->advertising |
hw->autoneg_advertised = advertising |
ADVERTISED_TP |
ADVERTISED_Autoneg;
ecmd->advertising = hw->autoneg_advertised;
} else {
u32 speed = ethtool_cmd_speed(ecmd);
u32 speed = cmd->base.speed;
/* calling this overrides forced MDI setting */
if (e1000_set_spd_dplx(adapter, speed, ecmd->duplex)) {
if (e1000_set_spd_dplx(adapter, speed, cmd->base.duplex)) {
clear_bit(__E1000_RESETTING, &adapter->flags);
return -EINVAL;
}
}
/* MDI-X => 2; MDI => 1; Auto => 3 */
if (ecmd->eth_tp_mdix_ctrl) {
if (ecmd->eth_tp_mdix_ctrl == ETH_TP_MDI_AUTO)
if (cmd->base.eth_tp_mdix_ctrl) {
if (cmd->base.eth_tp_mdix_ctrl == ETH_TP_MDI_AUTO)
hw->mdix = AUTO_ALL_MODES;
else
hw->mdix = ecmd->eth_tp_mdix_ctrl;
hw->mdix = cmd->base.eth_tp_mdix_ctrl;
}
/* reset the link */
......@@ -1875,8 +1874,6 @@ static void e1000_get_strings(struct net_device *netdev, u32 stringset,
}
static const struct ethtool_ops e1000_ethtool_ops = {
.get_settings = e1000_get_settings,
.set_settings = e1000_set_settings,
.get_drvinfo = e1000_get_drvinfo,
.get_regs_len = e1000_get_regs_len,
.get_regs = e1000_get_regs,
......@@ -1901,6 +1898,8 @@ static const struct ethtool_ops e1000_ethtool_ops = {
.get_coalesce = e1000_get_coalesce,
.set_coalesce = e1000_set_coalesce,
.get_ts_info = ethtool_op_get_ts_info,
.get_link_ksettings = e1000_get_link_ksettings,
.set_link_ksettings = e1000_set_link_ksettings,
};
void e1000_set_ethtool_ops(struct net_device *netdev)
......
......@@ -117,55 +117,52 @@ static const char e1000_gstrings_test[][ETH_GSTRING_LEN] = {
#define E1000_TEST_LEN ARRAY_SIZE(e1000_gstrings_test)
static int e1000_get_settings(struct net_device *netdev,
struct ethtool_cmd *ecmd)
static int e1000_get_link_ksettings(struct net_device *netdev,
struct ethtool_link_ksettings *cmd)
{
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
u32 speed;
u32 speed, supported, advertising;
if (hw->phy.media_type == e1000_media_type_copper) {
ecmd->supported = (SUPPORTED_10baseT_Half |
SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half |
SUPPORTED_100baseT_Full |
SUPPORTED_1000baseT_Full |
SUPPORTED_Autoneg |
SUPPORTED_TP);
supported = (SUPPORTED_10baseT_Half |
SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half |
SUPPORTED_100baseT_Full |
SUPPORTED_1000baseT_Full |
SUPPORTED_Autoneg |
SUPPORTED_TP);
if (hw->phy.type == e1000_phy_ife)
ecmd->supported &= ~SUPPORTED_1000baseT_Full;
ecmd->advertising = ADVERTISED_TP;
supported &= ~SUPPORTED_1000baseT_Full;
advertising = ADVERTISED_TP;
if (hw->mac.autoneg == 1) {
ecmd->advertising |= ADVERTISED_Autoneg;
advertising |= ADVERTISED_Autoneg;
/* the e1000 autoneg seems to match ethtool nicely */
ecmd->advertising |= hw->phy.autoneg_advertised;
advertising |= hw->phy.autoneg_advertised;
}
ecmd->port = PORT_TP;
ecmd->phy_address = hw->phy.addr;
ecmd->transceiver = XCVR_INTERNAL;
cmd->base.port = PORT_TP;
cmd->base.phy_address = hw->phy.addr;
} else {
ecmd->supported = (SUPPORTED_1000baseT_Full |
SUPPORTED_FIBRE |
SUPPORTED_Autoneg);
supported = (SUPPORTED_1000baseT_Full |
SUPPORTED_FIBRE |
SUPPORTED_Autoneg);
ecmd->advertising = (ADVERTISED_1000baseT_Full |
ADVERTISED_FIBRE |
ADVERTISED_Autoneg);
advertising = (ADVERTISED_1000baseT_Full |
ADVERTISED_FIBRE |
ADVERTISED_Autoneg);
ecmd->port = PORT_FIBRE;
ecmd->transceiver = XCVR_EXTERNAL;
cmd->base.port = PORT_FIBRE;
}
speed = SPEED_UNKNOWN;
ecmd->duplex = DUPLEX_UNKNOWN;
cmd->base.duplex = DUPLEX_UNKNOWN;
if (netif_running(netdev)) {
if (netif_carrier_ok(netdev)) {
speed = adapter->link_speed;
ecmd->duplex = adapter->link_duplex - 1;
cmd->base.duplex = adapter->link_duplex - 1;
}
} else if (!pm_runtime_suspended(netdev->dev.parent)) {
u32 status = er32(STATUS);
......@@ -179,30 +176,36 @@ static int e1000_get_settings(struct net_device *netdev,
speed = SPEED_10;
if (status & E1000_STATUS_FD)
ecmd->duplex = DUPLEX_FULL;
cmd->base.duplex = DUPLEX_FULL;
else
ecmd->duplex = DUPLEX_HALF;
cmd->base.duplex = DUPLEX_HALF;
}
}
ethtool_cmd_speed_set(ecmd, speed);
ecmd->autoneg = ((hw->phy.media_type == e1000_media_type_fiber) ||
cmd->base.speed = speed;
cmd->base.autoneg = ((hw->phy.media_type == e1000_media_type_fiber) ||
hw->mac.autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE;
/* MDI-X => 2; MDI =>1; Invalid =>0 */
if ((hw->phy.media_type == e1000_media_type_copper) &&
netif_carrier_ok(netdev))
ecmd->eth_tp_mdix = hw->phy.is_mdix ? ETH_TP_MDI_X : ETH_TP_MDI;
cmd->base.eth_tp_mdix = hw->phy.is_mdix ?
ETH_TP_MDI_X : ETH_TP_MDI;
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)
ecmd->eth_tp_mdix_ctrl = ETH_TP_MDI_AUTO;
cmd->base.eth_tp_mdix_ctrl = ETH_TP_MDI_AUTO;
else
ecmd->eth_tp_mdix_ctrl = hw->phy.mdix;
cmd->base.eth_tp_mdix_ctrl = hw->phy.mdix;
if (hw->phy.media_type != e1000_media_type_copper)
ecmd->eth_tp_mdix_ctrl = ETH_TP_MDI_INVALID;
cmd->base.eth_tp_mdix_ctrl = ETH_TP_MDI_INVALID;
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;
}
......@@ -262,12 +265,16 @@ static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u32 spd, u8 dplx)
return -EINVAL;
}
static int e1000_set_settings(struct net_device *netdev,
struct ethtool_cmd *ecmd)
static int e1000_set_link_ksettings(struct net_device *netdev,
const struct ethtool_link_ksettings *cmd)
{
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
int ret_val = 0;
u32 advertising;
ethtool_convert_link_mode_to_legacy_u32(&advertising,
cmd->link_modes.advertising);
pm_runtime_get_sync(netdev->dev.parent);
......@@ -285,14 +292,14 @@ static int e1000_set_settings(struct net_device *netdev,
* some hardware doesn't allow MDI setting when speed or
* 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) {
ret_val = -EOPNOTSUPP;
goto out;
}
if ((ecmd->eth_tp_mdix_ctrl != ETH_TP_MDI_AUTO) &&
(ecmd->autoneg != AUTONEG_ENABLE)) {
if ((cmd->base.eth_tp_mdix_ctrl != ETH_TP_MDI_AUTO) &&
(cmd->base.autoneg != AUTONEG_ENABLE)) {
e_err("forcing MDI/MDI-X state is not supported when link speed and/or duplex are forced\n");
ret_val = -EINVAL;
goto out;
......@@ -302,35 +309,35 @@ static int e1000_set_settings(struct net_device *netdev,
while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
usleep_range(1000, 2000);
if (ecmd->autoneg == AUTONEG_ENABLE) {
if (cmd->base.autoneg == AUTONEG_ENABLE) {
hw->mac.autoneg = 1;
if (hw->phy.media_type == e1000_media_type_fiber)
hw->phy.autoneg_advertised = ADVERTISED_1000baseT_Full |
ADVERTISED_FIBRE | ADVERTISED_Autoneg;
else
hw->phy.autoneg_advertised = ecmd->advertising |
hw->phy.autoneg_advertised = advertising |
ADVERTISED_TP | ADVERTISED_Autoneg;
ecmd->advertising = hw->phy.autoneg_advertised;
advertising = hw->phy.autoneg_advertised;
if (adapter->fc_autoneg)
hw->fc.requested_mode = e1000_fc_default;
} else {
u32 speed = ethtool_cmd_speed(ecmd);
u32 speed = cmd->base.speed;
/* calling this overrides forced MDI setting */
if (e1000_set_spd_dplx(adapter, speed, ecmd->duplex)) {
if (e1000_set_spd_dplx(adapter, speed, cmd->base.duplex)) {
ret_val = -EINVAL;
goto out;
}
}
/* 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
* 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;
else
hw->phy.mdix = ecmd->eth_tp_mdix_ctrl;
hw->phy.mdix = cmd->base.eth_tp_mdix_ctrl;
}
/* reset the link */
......@@ -2313,8 +2320,6 @@ static int e1000e_get_ts_info(struct net_device *netdev,
}
static const struct ethtool_ops e1000_ethtool_ops = {
.get_settings = e1000_get_settings,
.set_settings = e1000_set_settings,
.get_drvinfo = e1000_get_drvinfo,
.get_regs_len = e1000_get_regs_len,
.get_regs = e1000_get_regs,
......@@ -2342,6 +2347,8 @@ static const struct ethtool_ops e1000_ethtool_ops = {
.get_ts_info = e1000e_get_ts_info,
.get_eee = e1000e_get_eee,
.set_eee = e1000e_set_eee,
.get_link_ksettings = e1000_get_link_ksettings,
.set_link_ksettings = e1000_set_link_ksettings,
};
void e1000e_set_ethtool_ops(struct net_device *netdev)
......
......@@ -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)
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 e1000_hw *hw = &adapter->hw;
......@@ -159,76 +160,73 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
struct e1000_sfp_flags *eth_flags = &dev_spec->eth_flags;
u32 status;
u32 speed;
u32 supported, advertising;
status = rd32(E1000_STATUS);
if (hw->phy.media_type == e1000_media_type_copper) {
ecmd->supported = (SUPPORTED_10baseT_Half |
SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half |
SUPPORTED_100baseT_Full |
SUPPORTED_1000baseT_Full|
SUPPORTED_Autoneg |
SUPPORTED_TP |
SUPPORTED_Pause);
ecmd->advertising = ADVERTISED_TP;
supported = (SUPPORTED_10baseT_Half |
SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half |
SUPPORTED_100baseT_Full |
SUPPORTED_1000baseT_Full|
SUPPORTED_Autoneg |
SUPPORTED_TP |
SUPPORTED_Pause);
advertising = ADVERTISED_TP;
if (hw->mac.autoneg == 1) {
ecmd->advertising |= ADVERTISED_Autoneg;
advertising |= ADVERTISED_Autoneg;
/* the e1000 autoneg seems to match ethtool nicely */
ecmd->advertising |= hw->phy.autoneg_advertised;
advertising |= hw->phy.autoneg_advertised;
}
ecmd->port = PORT_TP;
ecmd->phy_address = hw->phy.addr;
ecmd->transceiver = XCVR_INTERNAL;
cmd->base.port = PORT_TP;
cmd->base.phy_address = hw->phy.addr;
} else {
ecmd->supported = (SUPPORTED_FIBRE |
SUPPORTED_1000baseKX_Full |
SUPPORTED_Autoneg |
SUPPORTED_Pause);
ecmd->advertising = (ADVERTISED_FIBRE |
ADVERTISED_1000baseKX_Full);
supported = (SUPPORTED_FIBRE |
SUPPORTED_1000baseKX_Full |
SUPPORTED_Autoneg |
SUPPORTED_Pause);
advertising = (ADVERTISED_FIBRE |
ADVERTISED_1000baseKX_Full);
if (hw->mac.type == e1000_i354) {
if ((hw->device_id ==
E1000_DEV_ID_I354_BACKPLANE_2_5GBPS) &&
!(status & E1000_STATUS_2P5_SKU_OVER)) {
ecmd->supported |= SUPPORTED_2500baseX_Full;
ecmd->supported &=
~SUPPORTED_1000baseKX_Full;
ecmd->advertising |= ADVERTISED_2500baseX_Full;
ecmd->advertising &=
~ADVERTISED_1000baseKX_Full;
supported |= SUPPORTED_2500baseX_Full;
supported &= ~SUPPORTED_1000baseKX_Full;
advertising |= ADVERTISED_2500baseX_Full;
advertising &= ~ADVERTISED_1000baseKX_Full;
}
}
if (eth_flags->e100_base_fx) {
ecmd->supported |= SUPPORTED_100baseT_Full;
ecmd->advertising |= ADVERTISED_100baseT_Full;
supported |= SUPPORTED_100baseT_Full;
advertising |= ADVERTISED_100baseT_Full;
}
if (hw->mac.autoneg == 1)
ecmd->advertising |= ADVERTISED_Autoneg;
advertising |= ADVERTISED_Autoneg;
ecmd->port = PORT_FIBRE;
ecmd->transceiver = XCVR_EXTERNAL;
cmd->base.port = PORT_FIBRE;
}
if (hw->mac.autoneg != 1)
ecmd->advertising &= ~(ADVERTISED_Pause |
ADVERTISED_Asym_Pause);
advertising &= ~(ADVERTISED_Pause |
ADVERTISED_Asym_Pause);
switch (hw->fc.requested_mode) {
case e1000_fc_full:
ecmd->advertising |= ADVERTISED_Pause;
advertising |= ADVERTISED_Pause;
break;
case e1000_fc_rx_pause:
ecmd->advertising |= (ADVERTISED_Pause |
ADVERTISED_Asym_Pause);
advertising |= (ADVERTISED_Pause |
ADVERTISED_Asym_Pause);
break;
case e1000_fc_tx_pause:
ecmd->advertising |= ADVERTISED_Asym_Pause;
advertising |= ADVERTISED_Asym_Pause;
break;
default:
ecmd->advertising &= ~(ADVERTISED_Pause |
ADVERTISED_Asym_Pause);
advertising &= ~(ADVERTISED_Pause |
ADVERTISED_Asym_Pause);
}
if (status & E1000_STATUS_LU) {
if ((status & E1000_STATUS_2P5_SKU) &&
......@@ -243,39 +241,46 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
}
if ((status & E1000_STATUS_FD) ||
hw->phy.media_type != e1000_media_type_copper)
ecmd->duplex = DUPLEX_FULL;
cmd->base.duplex = DUPLEX_FULL;
else
ecmd->duplex = DUPLEX_HALF;
cmd->base.duplex = DUPLEX_HALF;
} else {
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) ||
hw->mac.autoneg)
ecmd->autoneg = AUTONEG_ENABLE;
cmd->base.autoneg = AUTONEG_ENABLE;
else
ecmd->autoneg = AUTONEG_DISABLE;
cmd->base.autoneg = AUTONEG_DISABLE;
/* MDI-X => 2; MDI =>1; Invalid =>0 */
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;
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)
ecmd->eth_tp_mdix_ctrl = ETH_TP_MDI_AUTO;
cmd->base.eth_tp_mdix_ctrl = ETH_TP_MDI_AUTO;
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;
}
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 e1000_hw *hw = &adapter->hw;
u32 advertising;
/* When SoL/IDER sessions are active, autoneg/speed/duplex
* 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
* 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)
return -EOPNOTSUPP;
if ((ecmd->eth_tp_mdix_ctrl != ETH_TP_MDI_AUTO) &&
(ecmd->autoneg != AUTONEG_ENABLE)) {
if ((cmd->base.eth_tp_mdix_ctrl != ETH_TP_MDI_AUTO) &&
(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");
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))
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;
if (hw->phy.media_type == e1000_media_type_fiber) {
hw->phy.autoneg_advertised = ecmd->advertising |
hw->phy.autoneg_advertised = advertising |
ADVERTISED_FIBRE |
ADVERTISED_Autoneg;
switch (adapter->link_speed) {
......@@ -327,31 +335,31 @@ static int igb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
break;
}
} else {
hw->phy.autoneg_advertised = ecmd->advertising |
hw->phy.autoneg_advertised = advertising |
ADVERTISED_TP |
ADVERTISED_Autoneg;
}
ecmd->advertising = hw->phy.autoneg_advertised;
advertising = hw->phy.autoneg_advertised;
if (adapter->fc_autoneg)
hw->fc.requested_mode = e1000_fc_default;
} else {
u32 speed = ethtool_cmd_speed(ecmd);
u32 speed = cmd->base.speed;
/* 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);
return -EINVAL;
}
}
/* 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
* 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;
else
hw->phy.mdix = ecmd->eth_tp_mdix_ctrl;
hw->phy.mdix = cmd->base.eth_tp_mdix_ctrl;
}
/* 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 = {
.get_settings = igb_get_settings,
.set_settings = igb_set_settings,
.get_drvinfo = igb_get_drvinfo,
.get_regs_len = igb_get_regs_len,
.get_regs = igb_get_regs,
......@@ -3485,6 +3491,8 @@ static const struct ethtool_ops igb_ethtool_ops = {
.set_priv_flags = igb_set_priv_flags,
.begin = igb_ethtool_begin,
.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)
......
......@@ -71,45 +71,45 @@ static const char igbvf_gstrings_test[][ETH_GSTRING_LEN] = {
#define IGBVF_TEST_LEN ARRAY_SIZE(igbvf_gstrings_test)
static int igbvf_get_settings(struct net_device *netdev,
struct ethtool_cmd *ecmd)
static int igbvf_get_link_ksettings(struct net_device *netdev,
struct ethtool_link_ksettings *cmd)
{
struct igbvf_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
u32 status;
ecmd->supported = SUPPORTED_1000baseT_Full;
ethtool_link_ksettings_zero_link_mode(cmd, supported);
ethtool_link_ksettings_add_link_mode(cmd, supported, 1000baseT_Full);
ethtool_link_ksettings_zero_link_mode(cmd, advertising);
ethtool_link_ksettings_add_link_mode(cmd, advertising, 1000baseT_Full);
ecmd->advertising = ADVERTISED_1000baseT_Full;
ecmd->port = -1;
ecmd->transceiver = XCVR_DUMMY1;
cmd->base.port = -1;
status = er32(STATUS);
if (status & E1000_STATUS_LU) {
if (status & E1000_STATUS_SPEED_1000)
ethtool_cmd_speed_set(ecmd, SPEED_1000);
cmd->base.speed = SPEED_1000;
else if (status & E1000_STATUS_SPEED_100)
ethtool_cmd_speed_set(ecmd, SPEED_100);
cmd->base.speed = SPEED_100;
else
ethtool_cmd_speed_set(ecmd, SPEED_10);
cmd->base.speed = SPEED_10;
if (status & E1000_STATUS_FD)
ecmd->duplex = DUPLEX_FULL;
cmd->base.duplex = DUPLEX_FULL;
else
ecmd->duplex = DUPLEX_HALF;
cmd->base.duplex = DUPLEX_HALF;
} else {
ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN);
ecmd->duplex = DUPLEX_UNKNOWN;
cmd->base.speed = SPEED_UNKNOWN;
cmd->base.duplex = DUPLEX_UNKNOWN;
}
ecmd->autoneg = AUTONEG_DISABLE;
cmd->base.autoneg = AUTONEG_DISABLE;
return 0;
}
static int igbvf_set_settings(struct net_device *netdev,
struct ethtool_cmd *ecmd)
static int igbvf_set_link_ksettings(struct net_device *netdev,
const struct ethtool_link_ksettings *cmd)
{
return -EOPNOTSUPP;
}
......@@ -443,8 +443,6 @@ static void igbvf_get_strings(struct net_device *netdev, u32 stringset,
}
static const struct ethtool_ops igbvf_ethtool_ops = {
.get_settings = igbvf_get_settings,
.set_settings = igbvf_set_settings,
.get_drvinfo = igbvf_get_drvinfo,
.get_regs_len = igbvf_get_regs_len,
.get_regs = igbvf_get_regs,
......@@ -467,6 +465,8 @@ static const struct ethtool_ops igbvf_ethtool_ops = {
.get_ethtool_stats = igbvf_get_ethtool_stats,
.get_coalesce = igbvf_get_coalesce,
.set_coalesce = igbvf_set_coalesce,
.get_link_ksettings = igbvf_get_link_ksettings,
.set_link_ksettings = igbvf_set_link_ksettings,
};
void igbvf_set_ethtool_ops(struct net_device *netdev)
......
......@@ -94,24 +94,30 @@ static struct ixgb_stats ixgb_gstrings_stats[] = {
#define IXGB_STATS_LEN ARRAY_SIZE(ixgb_gstrings_stats)
static int
ixgb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
ixgb_get_link_ksettings(struct net_device *netdev,
struct ethtool_link_ksettings *cmd)
{
struct ixgb_adapter *adapter = netdev_priv(netdev);
ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE);
ecmd->advertising = (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE);
ecmd->port = PORT_FIBRE;
ecmd->transceiver = XCVR_EXTERNAL;
ethtool_link_ksettings_zero_link_mode(cmd, supported);
ethtool_link_ksettings_add_link_mode(cmd, supported, 10000baseT_Full);
ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE);
ethtool_link_ksettings_zero_link_mode(cmd, advertising);
ethtool_link_ksettings_add_link_mode(cmd, advertising, 10000baseT_Full);
ethtool_link_ksettings_add_link_mode(cmd, advertising, FIBRE);
cmd->base.port = PORT_FIBRE;
if (netif_carrier_ok(adapter->netdev)) {
ethtool_cmd_speed_set(ecmd, SPEED_10000);
ecmd->duplex = DUPLEX_FULL;
cmd->base.speed = SPEED_10000;
cmd->base.duplex = DUPLEX_FULL;
} else {
ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN);
ecmd->duplex = DUPLEX_UNKNOWN;
cmd->base.speed = SPEED_UNKNOWN;
cmd->base.duplex = DUPLEX_UNKNOWN;
}
ecmd->autoneg = AUTONEG_DISABLE;
cmd->base.autoneg = AUTONEG_DISABLE;
return 0;
}
......@@ -126,13 +132,14 @@ void ixgb_set_speed_duplex(struct net_device *netdev)
}
static int
ixgb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
ixgb_set_link_ksettings(struct net_device *netdev,
const struct ethtool_link_ksettings *cmd)
{
struct ixgb_adapter *adapter = netdev_priv(netdev);
u32 speed = ethtool_cmd_speed(ecmd);
u32 speed = cmd->base.speed;
if (ecmd->autoneg == AUTONEG_ENABLE ||
(speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL))
if (cmd->base.autoneg == AUTONEG_ENABLE ||
(speed + cmd->base.duplex != SPEED_10000 + DUPLEX_FULL))
return -EINVAL;
if (netif_running(adapter->netdev)) {
......@@ -630,8 +637,6 @@ ixgb_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
}
static const struct ethtool_ops ixgb_ethtool_ops = {
.get_settings = ixgb_get_settings,
.set_settings = ixgb_set_settings,
.get_drvinfo = ixgb_get_drvinfo,
.get_regs_len = ixgb_get_regs_len,
.get_regs = ixgb_get_regs,
......@@ -649,6 +654,8 @@ static const struct ethtool_ops ixgb_ethtool_ops = {
.set_phys_id = ixgb_set_phys_id,
.get_sset_count = ixgb_get_sset_count,
.get_ethtool_stats = ixgb_get_ethtool_stats,
.get_link_ksettings = ixgb_get_link_ksettings,
.set_link_ksettings = ixgb_set_link_ksettings,
};
void ixgb_set_ethtool_ops(struct net_device *netdev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment