Commit 7ec56894 authored by Johannes Berg's avatar Johannes Berg Committed by David S. Miller

alx: fix ethtool support code

A number of places treated features wrongly, listing not-supported
features instead of supported ones. Also, the get_drvinfo ethtool
callback isn't needed, and alx_get_pauseparam can be simplified.
Reported-by: default avatarBen Hutchings <ben@decadent.org.uk>
Signed-off-by: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 46ab9b34
...@@ -46,21 +46,37 @@ ...@@ -46,21 +46,37 @@
#include "reg.h" #include "reg.h"
#include "hw.h" #include "hw.h"
static u32 alx_get_supported_speeds(struct alx_hw *hw)
{
u32 supported = SUPPORTED_10baseT_Half |
SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half |
SUPPORTED_100baseT_Full;
if (alx_hw_giga(hw))
supported |= SUPPORTED_1000baseT_Full;
BUILD_BUG_ON(SUPPORTED_10baseT_Half != ADVERTISED_10baseT_Half);
BUILD_BUG_ON(SUPPORTED_10baseT_Full != ADVERTISED_10baseT_Full);
BUILD_BUG_ON(SUPPORTED_100baseT_Half != ADVERTISED_100baseT_Half);
BUILD_BUG_ON(SUPPORTED_100baseT_Full != ADVERTISED_100baseT_Full);
BUILD_BUG_ON(SUPPORTED_1000baseT_Full != ADVERTISED_1000baseT_Full);
return supported;
}
static int alx_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) static int alx_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
{ {
struct alx_priv *alx = netdev_priv(netdev); struct alx_priv *alx = netdev_priv(netdev);
struct alx_hw *hw = &alx->hw; struct alx_hw *hw = &alx->hw;
ecmd->supported = SUPPORTED_10baseT_Half | ecmd->supported = SUPPORTED_Autoneg |
SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half |
SUPPORTED_100baseT_Full |
SUPPORTED_Autoneg |
SUPPORTED_TP | SUPPORTED_TP |
SUPPORTED_Pause; SUPPORTED_Pause |
SUPPORTED_Asym_Pause;
if (alx_hw_giga(hw)) if (alx_hw_giga(hw))
ecmd->supported |= SUPPORTED_1000baseT_Full; ecmd->supported |= SUPPORTED_1000baseT_Full;
ecmd->supported |= alx_get_supported_speeds(hw);
ecmd->advertising = ADVERTISED_TP; ecmd->advertising = ADVERTISED_TP;
if (hw->adv_cfg & ADVERTISED_Autoneg) if (hw->adv_cfg & ADVERTISED_Autoneg)
...@@ -68,6 +84,7 @@ static int alx_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) ...@@ -68,6 +84,7 @@ static int alx_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
ecmd->port = PORT_TP; ecmd->port = PORT_TP;
ecmd->phy_address = 0; ecmd->phy_address = 0;
if (hw->adv_cfg & ADVERTISED_Autoneg) if (hw->adv_cfg & ADVERTISED_Autoneg)
ecmd->autoneg = AUTONEG_ENABLE; ecmd->autoneg = AUTONEG_ENABLE;
else else
...@@ -100,7 +117,7 @@ static int alx_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) ...@@ -100,7 +117,7 @@ static int alx_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
ASSERT_RTNL(); ASSERT_RTNL();
if (ecmd->autoneg == AUTONEG_ENABLE) { if (ecmd->autoneg == AUTONEG_ENABLE) {
if (ecmd->advertising & ADVERTISED_1000baseT_Half) if (ecmd->advertising & ~alx_get_supported_speeds(hw))
return -EINVAL; return -EINVAL;
adv_cfg = ecmd->advertising | ADVERTISED_Autoneg; adv_cfg = ecmd->advertising | ADVERTISED_Autoneg;
} else { } else {
...@@ -121,21 +138,10 @@ static void alx_get_pauseparam(struct net_device *netdev, ...@@ -121,21 +138,10 @@ static void alx_get_pauseparam(struct net_device *netdev,
struct alx_priv *alx = netdev_priv(netdev); struct alx_priv *alx = netdev_priv(netdev);
struct alx_hw *hw = &alx->hw; struct alx_hw *hw = &alx->hw;
if (hw->flowctrl & ALX_FC_ANEG && pause->autoneg = !!(hw->flowctrl & ALX_FC_ANEG &&
hw->adv_cfg & ADVERTISED_Autoneg) hw->adv_cfg & ADVERTISED_Autoneg);
pause->autoneg = AUTONEG_ENABLE; pause->tx_pause = !!(hw->flowctrl & ALX_FC_TX);
else pause->rx_pause = !!(hw->flowctrl & ALX_FC_RX);
pause->autoneg = AUTONEG_DISABLE;
if (hw->flowctrl & ALX_FC_TX)
pause->tx_pause = 1;
else
pause->tx_pause = 0;
if (hw->flowctrl & ALX_FC_RX)
pause->rx_pause = 1;
else
pause->rx_pause = 0;
} }
...@@ -214,8 +220,7 @@ static int alx_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) ...@@ -214,8 +220,7 @@ static int alx_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
struct alx_priv *alx = netdev_priv(netdev); struct alx_priv *alx = netdev_priv(netdev);
struct alx_hw *hw = &alx->hw; struct alx_hw *hw = &alx->hw;
if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE | if (wol->wolopts & ~(WAKE_MAGIC | WAKE_PHY))
WAKE_UCAST | WAKE_BCAST | WAKE_MCAST))
return -EOPNOTSUPP; return -EOPNOTSUPP;
hw->sleep_ctrl = 0; hw->sleep_ctrl = 0;
...@@ -230,22 +235,11 @@ static int alx_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) ...@@ -230,22 +235,11 @@ static int alx_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
return 0; return 0;
} }
static void alx_get_drvinfo(struct net_device *netdev,
struct ethtool_drvinfo *drvinfo)
{
struct alx_priv *alx = netdev_priv(netdev);
strlcpy(drvinfo->driver, alx_drv_name, sizeof(drvinfo->driver));
strlcpy(drvinfo->bus_info, pci_name(alx->hw.pdev),
sizeof(drvinfo->bus_info));
}
const struct ethtool_ops alx_ethtool_ops = { const struct ethtool_ops alx_ethtool_ops = {
.get_settings = alx_get_settings, .get_settings = alx_get_settings,
.set_settings = alx_set_settings, .set_settings = alx_set_settings,
.get_pauseparam = alx_get_pauseparam, .get_pauseparam = alx_get_pauseparam,
.set_pauseparam = alx_set_pauseparam, .set_pauseparam = alx_set_pauseparam,
.get_drvinfo = alx_get_drvinfo,
.get_msglevel = alx_get_msglevel, .get_msglevel = alx_get_msglevel,
.set_msglevel = alx_set_msglevel, .set_msglevel = alx_set_msglevel,
.get_wol = alx_get_wol, .get_wol = alx_get_wol,
......
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