Commit 74766013 authored by Mallikarjuna R Chilakala's avatar Mallikarjuna R Chilakala Committed by David S. Miller

ixgbe: ethtool support to change advertised link modes of 82599 adapters

Add ethtool support to change advertised link modes/autoneg settings of
82599 multispeed fiber adapters.
Signed-off-by: default avatarMallikarjuna R Chilakala <mallikarjuna.chilakala@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 620fa036
...@@ -464,6 +464,15 @@ s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw, ...@@ -464,6 +464,15 @@ s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw,
hw->mac.ops.get_link_capabilities(hw, &phy_link_speed, &negotiation); hw->mac.ops.get_link_capabilities(hw, &phy_link_speed, &negotiation);
speed &= phy_link_speed; speed &= phy_link_speed;
/* Set autoneg_advertised value based on input link speed */
hw->phy.autoneg_advertised = 0;
if (speed & IXGBE_LINK_SPEED_10GB_FULL)
hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL;
if (speed & IXGBE_LINK_SPEED_1GB_FULL)
hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
/* /*
* When the driver changes the link speeds that it can support, * When the driver changes the link speeds that it can support,
* it sets autotry_restart to true to indicate that we need to * it sets autotry_restart to true to indicate that we need to
......
...@@ -136,11 +136,12 @@ static int ixgbe_get_settings(struct net_device *netdev, ...@@ -136,11 +136,12 @@ static int ixgbe_get_settings(struct net_device *netdev,
ecmd->supported = SUPPORTED_10000baseT_Full; ecmd->supported = SUPPORTED_10000baseT_Full;
ecmd->autoneg = AUTONEG_ENABLE; ecmd->autoneg = AUTONEG_ENABLE;
ecmd->transceiver = XCVR_EXTERNAL; ecmd->transceiver = XCVR_EXTERNAL;
if (hw->phy.media_type == ixgbe_media_type_copper) { if ((hw->phy.media_type == ixgbe_media_type_copper) ||
(hw->mac.type == ixgbe_mac_82599EB)) {
ecmd->supported |= (SUPPORTED_1000baseT_Full | ecmd->supported |= (SUPPORTED_1000baseT_Full |
SUPPORTED_TP | SUPPORTED_Autoneg); SUPPORTED_Autoneg);
ecmd->advertising = (ADVERTISED_TP | ADVERTISED_Autoneg); ecmd->advertising = ADVERTISED_Autoneg;
if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
ecmd->advertising |= ADVERTISED_10000baseT_Full; ecmd->advertising |= ADVERTISED_10000baseT_Full;
if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
...@@ -155,7 +156,15 @@ static int ixgbe_get_settings(struct net_device *netdev, ...@@ -155,7 +156,15 @@ static int ixgbe_get_settings(struct net_device *netdev,
ecmd->advertising |= (ADVERTISED_10000baseT_Full | ecmd->advertising |= (ADVERTISED_10000baseT_Full |
ADVERTISED_1000baseT_Full); ADVERTISED_1000baseT_Full);
ecmd->port = PORT_TP; if (hw->phy.media_type == ixgbe_media_type_copper) {
ecmd->supported |= SUPPORTED_TP;
ecmd->advertising |= ADVERTISED_TP;
ecmd->port = PORT_TP;
} else {
ecmd->supported |= SUPPORTED_FIBRE;
ecmd->advertising |= ADVERTISED_FIBRE;
ecmd->port = PORT_FIBRE;
}
} else if (hw->phy.media_type == ixgbe_media_type_backplane) { } else if (hw->phy.media_type == ixgbe_media_type_backplane) {
/* Set as FIBRE until SERDES defined in kernel */ /* Set as FIBRE until SERDES defined in kernel */
switch (hw->device_id) { switch (hw->device_id) {
...@@ -203,16 +212,10 @@ static int ixgbe_set_settings(struct net_device *netdev, ...@@ -203,16 +212,10 @@ static int ixgbe_set_settings(struct net_device *netdev,
struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
u32 advertised, old; u32 advertised, old;
s32 err; s32 err = 0;
switch (hw->phy.media_type) { if ((hw->phy.media_type == ixgbe_media_type_copper) ||
case ixgbe_media_type_fiber: (hw->mac.type == ixgbe_mac_82599EB)) {
if ((ecmd->autoneg == AUTONEG_ENABLE) ||
(ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL))
return -EINVAL;
/* in this case we currently only support 10Gb/FULL */
break;
case ixgbe_media_type_copper:
/* 10000/copper and 1000/copper must autoneg /* 10000/copper and 1000/copper must autoneg
* this function does not support any duplex forcing, but can * this function does not support any duplex forcing, but can
* limit the advertising of the adapter to only 10000 or 1000 */ * limit the advertising of the adapter to only 10000 or 1000 */
...@@ -228,20 +231,23 @@ static int ixgbe_set_settings(struct net_device *netdev, ...@@ -228,20 +231,23 @@ static int ixgbe_set_settings(struct net_device *netdev,
advertised |= IXGBE_LINK_SPEED_1GB_FULL; advertised |= IXGBE_LINK_SPEED_1GB_FULL;
if (old == advertised) if (old == advertised)
break; return err;
/* this sets the link speed and restarts auto-neg */ /* this sets the link speed and restarts auto-neg */
hw->mac.autotry_restart = true;
err = hw->mac.ops.setup_link_speed(hw, advertised, true, true); err = hw->mac.ops.setup_link_speed(hw, advertised, true, true);
if (err) { if (err) {
DPRINTK(PROBE, INFO, DPRINTK(PROBE, INFO,
"setup link failed with code %d\n", err); "setup link failed with code %d\n", err);
hw->mac.ops.setup_link_speed(hw, old, true, true); hw->mac.ops.setup_link_speed(hw, old, true, true);
} }
break; } else {
default: /* in this case we currently only support 10Gb/FULL */
break; if ((ecmd->autoneg == AUTONEG_ENABLE) ||
(ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL))
return -EINVAL;
} }
return 0; return err;
} }
static void ixgbe_get_pauseparam(struct net_device *netdev, static void ixgbe_get_pauseparam(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