diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2013-06-29 17:23:19 (GMT) |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-07-01 20:18:19 (GMT) |
commit | 7ec5689461989fd80f1cf82ae084f5d50a5e63ee (patch) | |
tree | bc9c368f432204329568786aa0ef2b4c3a1126f0 /drivers/net/ethernet/atheros/alx | |
parent | 46ab9b347d677976b2b4072837cb4065839c0b80 (diff) | |
download | linux-7ec5689461989fd80f1cf82ae084f5d50a5e63ee.tar.xz |
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: Ben Hutchings <ben@decadent.org.uk>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/atheros/alx')
-rw-r--r-- | drivers/net/ethernet/atheros/alx/ethtool.c | 64 |
1 files changed, 29 insertions, 35 deletions
diff --git a/drivers/net/ethernet/atheros/alx/ethtool.c b/drivers/net/ethernet/atheros/alx/ethtool.c index 5e19e08..9261006 100644 --- a/drivers/net/ethernet/atheros/alx/ethtool.c +++ b/drivers/net/ethernet/atheros/alx/ethtool.c @@ -46,21 +46,37 @@ #include "reg.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) { struct alx_priv *alx = netdev_priv(netdev); struct alx_hw *hw = &alx->hw; - ecmd->supported = SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_Autoneg | + ecmd->supported = SUPPORTED_Autoneg | SUPPORTED_TP | - SUPPORTED_Pause; + SUPPORTED_Pause | + SUPPORTED_Asym_Pause; if (alx_hw_giga(hw)) ecmd->supported |= SUPPORTED_1000baseT_Full; + ecmd->supported |= alx_get_supported_speeds(hw); ecmd->advertising = ADVERTISED_TP; if (hw->adv_cfg & ADVERTISED_Autoneg) @@ -68,6 +84,7 @@ static int alx_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) ecmd->port = PORT_TP; ecmd->phy_address = 0; + if (hw->adv_cfg & ADVERTISED_Autoneg) ecmd->autoneg = AUTONEG_ENABLE; else @@ -100,7 +117,7 @@ static int alx_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) ASSERT_RTNL(); if (ecmd->autoneg == AUTONEG_ENABLE) { - if (ecmd->advertising & ADVERTISED_1000baseT_Half) + if (ecmd->advertising & ~alx_get_supported_speeds(hw)) return -EINVAL; adv_cfg = ecmd->advertising | ADVERTISED_Autoneg; } else { @@ -121,21 +138,10 @@ static void alx_get_pauseparam(struct net_device *netdev, struct alx_priv *alx = netdev_priv(netdev); struct alx_hw *hw = &alx->hw; - if (hw->flowctrl & ALX_FC_ANEG && - hw->adv_cfg & ADVERTISED_Autoneg) - pause->autoneg = AUTONEG_ENABLE; - else - 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; + pause->autoneg = !!(hw->flowctrl & ALX_FC_ANEG && + hw->adv_cfg & ADVERTISED_Autoneg); + pause->tx_pause = !!(hw->flowctrl & ALX_FC_TX); + pause->rx_pause = !!(hw->flowctrl & ALX_FC_RX); } @@ -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_hw *hw = &alx->hw; - if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE | - WAKE_UCAST | WAKE_BCAST | WAKE_MCAST)) + if (wol->wolopts & ~(WAKE_MAGIC | WAKE_PHY)) return -EOPNOTSUPP; hw->sleep_ctrl = 0; @@ -230,22 +235,11 @@ static int alx_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) 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 = { .get_settings = alx_get_settings, .set_settings = alx_set_settings, .get_pauseparam = alx_get_pauseparam, .set_pauseparam = alx_set_pauseparam, - .get_drvinfo = alx_get_drvinfo, .get_msglevel = alx_get_msglevel, .set_msglevel = alx_set_msglevel, .get_wol = alx_get_wol, |