diff options
-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 5e19e08b691b..926100626d60 100644 --- a/drivers/net/ethernet/atheros/alx/ethtool.c +++ b/drivers/net/ethernet/atheros/alx/ethtool.c | |||
@@ -46,21 +46,37 @@ | |||
46 | #include "reg.h" | 46 | #include "reg.h" |
47 | #include "hw.h" | 47 | #include "hw.h" |
48 | 48 | ||
49 | static u32 alx_get_supported_speeds(struct alx_hw *hw) | ||
50 | { | ||
51 | u32 supported = SUPPORTED_10baseT_Half | | ||
52 | SUPPORTED_10baseT_Full | | ||
53 | SUPPORTED_100baseT_Half | | ||
54 | SUPPORTED_100baseT_Full; | ||
55 | |||
56 | if (alx_hw_giga(hw)) | ||
57 | supported |= SUPPORTED_1000baseT_Full; | ||
58 | |||
59 | BUILD_BUG_ON(SUPPORTED_10baseT_Half != ADVERTISED_10baseT_Half); | ||
60 | BUILD_BUG_ON(SUPPORTED_10baseT_Full != ADVERTISED_10baseT_Full); | ||
61 | BUILD_BUG_ON(SUPPORTED_100baseT_Half != ADVERTISED_100baseT_Half); | ||
62 | BUILD_BUG_ON(SUPPORTED_100baseT_Full != ADVERTISED_100baseT_Full); | ||
63 | BUILD_BUG_ON(SUPPORTED_1000baseT_Full != ADVERTISED_1000baseT_Full); | ||
64 | |||
65 | return supported; | ||
66 | } | ||
49 | 67 | ||
50 | static int alx_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | 68 | static int alx_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) |
51 | { | 69 | { |
52 | struct alx_priv *alx = netdev_priv(netdev); | 70 | struct alx_priv *alx = netdev_priv(netdev); |
53 | struct alx_hw *hw = &alx->hw; | 71 | struct alx_hw *hw = &alx->hw; |
54 | 72 | ||
55 | ecmd->supported = SUPPORTED_10baseT_Half | | 73 | ecmd->supported = SUPPORTED_Autoneg | |
56 | SUPPORTED_10baseT_Full | | ||
57 | SUPPORTED_100baseT_Half | | ||
58 | SUPPORTED_100baseT_Full | | ||
59 | SUPPORTED_Autoneg | | ||
60 | SUPPORTED_TP | | 74 | SUPPORTED_TP | |
61 | SUPPORTED_Pause; | 75 | SUPPORTED_Pause | |
76 | SUPPORTED_Asym_Pause; | ||
62 | if (alx_hw_giga(hw)) | 77 | if (alx_hw_giga(hw)) |
63 | ecmd->supported |= SUPPORTED_1000baseT_Full; | 78 | ecmd->supported |= SUPPORTED_1000baseT_Full; |
79 | ecmd->supported |= alx_get_supported_speeds(hw); | ||
64 | 80 | ||
65 | ecmd->advertising = ADVERTISED_TP; | 81 | ecmd->advertising = ADVERTISED_TP; |
66 | if (hw->adv_cfg & ADVERTISED_Autoneg) | 82 | if (hw->adv_cfg & ADVERTISED_Autoneg) |
@@ -68,6 +84,7 @@ static int alx_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | |||
68 | 84 | ||
69 | ecmd->port = PORT_TP; | 85 | ecmd->port = PORT_TP; |
70 | ecmd->phy_address = 0; | 86 | ecmd->phy_address = 0; |
87 | |||
71 | if (hw->adv_cfg & ADVERTISED_Autoneg) | 88 | if (hw->adv_cfg & ADVERTISED_Autoneg) |
72 | ecmd->autoneg = AUTONEG_ENABLE; | 89 | ecmd->autoneg = AUTONEG_ENABLE; |
73 | else | 90 | else |
@@ -100,7 +117,7 @@ static int alx_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | |||
100 | ASSERT_RTNL(); | 117 | ASSERT_RTNL(); |
101 | 118 | ||
102 | if (ecmd->autoneg == AUTONEG_ENABLE) { | 119 | if (ecmd->autoneg == AUTONEG_ENABLE) { |
103 | if (ecmd->advertising & ADVERTISED_1000baseT_Half) | 120 | if (ecmd->advertising & ~alx_get_supported_speeds(hw)) |
104 | return -EINVAL; | 121 | return -EINVAL; |
105 | adv_cfg = ecmd->advertising | ADVERTISED_Autoneg; | 122 | adv_cfg = ecmd->advertising | ADVERTISED_Autoneg; |
106 | } else { | 123 | } else { |
@@ -121,21 +138,10 @@ static void alx_get_pauseparam(struct net_device *netdev, | |||
121 | struct alx_priv *alx = netdev_priv(netdev); | 138 | struct alx_priv *alx = netdev_priv(netdev); |
122 | struct alx_hw *hw = &alx->hw; | 139 | struct alx_hw *hw = &alx->hw; |
123 | 140 | ||
124 | if (hw->flowctrl & ALX_FC_ANEG && | 141 | pause->autoneg = !!(hw->flowctrl & ALX_FC_ANEG && |
125 | hw->adv_cfg & ADVERTISED_Autoneg) | 142 | hw->adv_cfg & ADVERTISED_Autoneg); |
126 | pause->autoneg = AUTONEG_ENABLE; | 143 | pause->tx_pause = !!(hw->flowctrl & ALX_FC_TX); |
127 | else | 144 | pause->rx_pause = !!(hw->flowctrl & ALX_FC_RX); |
128 | pause->autoneg = AUTONEG_DISABLE; | ||
129 | |||
130 | if (hw->flowctrl & ALX_FC_TX) | ||
131 | pause->tx_pause = 1; | ||
132 | else | ||
133 | pause->tx_pause = 0; | ||
134 | |||
135 | if (hw->flowctrl & ALX_FC_RX) | ||
136 | pause->rx_pause = 1; | ||
137 | else | ||
138 | pause->rx_pause = 0; | ||
139 | } | 145 | } |
140 | 146 | ||
141 | 147 | ||
@@ -214,8 +220,7 @@ static int alx_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) | |||
214 | struct alx_priv *alx = netdev_priv(netdev); | 220 | struct alx_priv *alx = netdev_priv(netdev); |
215 | struct alx_hw *hw = &alx->hw; | 221 | struct alx_hw *hw = &alx->hw; |
216 | 222 | ||
217 | if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE | | 223 | if (wol->wolopts & ~(WAKE_MAGIC | WAKE_PHY)) |
218 | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST)) | ||
219 | return -EOPNOTSUPP; | 224 | return -EOPNOTSUPP; |
220 | 225 | ||
221 | hw->sleep_ctrl = 0; | 226 | hw->sleep_ctrl = 0; |
@@ -230,22 +235,11 @@ static int alx_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) | |||
230 | return 0; | 235 | return 0; |
231 | } | 236 | } |
232 | 237 | ||
233 | static void alx_get_drvinfo(struct net_device *netdev, | ||
234 | struct ethtool_drvinfo *drvinfo) | ||
235 | { | ||
236 | struct alx_priv *alx = netdev_priv(netdev); | ||
237 | |||
238 | strlcpy(drvinfo->driver, alx_drv_name, sizeof(drvinfo->driver)); | ||
239 | strlcpy(drvinfo->bus_info, pci_name(alx->hw.pdev), | ||
240 | sizeof(drvinfo->bus_info)); | ||
241 | } | ||
242 | |||
243 | const struct ethtool_ops alx_ethtool_ops = { | 238 | const struct ethtool_ops alx_ethtool_ops = { |
244 | .get_settings = alx_get_settings, | 239 | .get_settings = alx_get_settings, |
245 | .set_settings = alx_set_settings, | 240 | .set_settings = alx_set_settings, |
246 | .get_pauseparam = alx_get_pauseparam, | 241 | .get_pauseparam = alx_get_pauseparam, |
247 | .set_pauseparam = alx_set_pauseparam, | 242 | .set_pauseparam = alx_set_pauseparam, |
248 | .get_drvinfo = alx_get_drvinfo, | ||
249 | .get_msglevel = alx_get_msglevel, | 243 | .get_msglevel = alx_get_msglevel, |
250 | .set_msglevel = alx_set_msglevel, | 244 | .set_msglevel = alx_set_msglevel, |
251 | .get_wol = alx_get_wol, | 245 | .get_wol = alx_get_wol, |