aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarolyn Wyborny <carolyn.wyborny@intel.com>2013-11-09 07:52:14 -0500
committerDavid S. Miller <davem@davemloft.net>2013-11-11 00:19:35 -0500
commit0123713957a1977fcb5fc93173122d8af58e0c2c (patch)
tree3c53fa83a1b7a8ffa2e04ae100385de383ede18c
parent6aafeef03b9d9ecf255f3a80ed85ee070260e1ae (diff)
igb: Update link modes display in ethtool
This patch fixes multiple problems in the link modes display in ethtool. Newer parts have more complicated methods to determine actual link capabilities. Older parts cannot communicate with their SFP modules. Finally, all the available defines are not displayed by ethtool. This updates the link modes to be as accurate as possible depending on what data is available to the driver at any given time. Signed-off-by: Carolyn Wyborny <carolyn.wyborny@intel.com> Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/intel/igb/igb_ethtool.c51
1 files changed, 27 insertions, 24 deletions
diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c
index b918ba3640f9..b0f3666b1d7f 100644
--- a/drivers/net/ethernet/intel/igb/igb_ethtool.c
+++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c
@@ -146,6 +146,7 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
146 struct e1000_sfp_flags *eth_flags = &dev_spec->eth_flags; 146 struct e1000_sfp_flags *eth_flags = &dev_spec->eth_flags;
147 u32 status; 147 u32 status;
148 148
149 status = rd32(E1000_STATUS);
149 if (hw->phy.media_type == e1000_media_type_copper) { 150 if (hw->phy.media_type == e1000_media_type_copper) {
150 151
151 ecmd->supported = (SUPPORTED_10baseT_Half | 152 ecmd->supported = (SUPPORTED_10baseT_Half |
@@ -169,13 +170,22 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
169 ecmd->transceiver = XCVR_INTERNAL; 170 ecmd->transceiver = XCVR_INTERNAL;
170 } else { 171 } else {
171 ecmd->supported = (SUPPORTED_FIBRE | 172 ecmd->supported = (SUPPORTED_FIBRE |
173 SUPPORTED_1000baseKX_Full |
172 SUPPORTED_Autoneg | 174 SUPPORTED_Autoneg |
173 SUPPORTED_Pause); 175 SUPPORTED_Pause);
174 ecmd->advertising = ADVERTISED_FIBRE; 176 ecmd->advertising = (ADVERTISED_FIBRE |
175 177 ADVERTISED_1000baseKX_Full);
176 if ((eth_flags->e1000_base_lx) || (eth_flags->e1000_base_sx)) { 178 if (hw->mac.type == e1000_i354) {
177 ecmd->supported |= SUPPORTED_1000baseT_Full; 179 if ((hw->device_id ==
178 ecmd->advertising |= ADVERTISED_1000baseT_Full; 180 E1000_DEV_ID_I354_BACKPLANE_2_5GBPS) &&
181 !(status & E1000_STATUS_2P5_SKU_OVER)) {
182 ecmd->supported |= SUPPORTED_2500baseX_Full;
183 ecmd->supported &=
184 ~SUPPORTED_1000baseKX_Full;
185 ecmd->advertising |= ADVERTISED_2500baseX_Full;
186 ecmd->advertising &=
187 ~ADVERTISED_1000baseKX_Full;
188 }
179 } 189 }
180 if (eth_flags->e100_base_fx) { 190 if (eth_flags->e100_base_fx) {
181 ecmd->supported |= SUPPORTED_100baseT_Full; 191 ecmd->supported |= SUPPORTED_100baseT_Full;
@@ -187,35 +197,29 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
187 ecmd->port = PORT_FIBRE; 197 ecmd->port = PORT_FIBRE;
188 ecmd->transceiver = XCVR_EXTERNAL; 198 ecmd->transceiver = XCVR_EXTERNAL;
189 } 199 }
190
191 if (hw->mac.autoneg != 1) 200 if (hw->mac.autoneg != 1)
192 ecmd->advertising &= ~(ADVERTISED_Pause | 201 ecmd->advertising &= ~(ADVERTISED_Pause |
193 ADVERTISED_Asym_Pause); 202 ADVERTISED_Asym_Pause);
194 203
195 if (hw->fc.requested_mode == e1000_fc_full) 204 switch (hw->fc.requested_mode) {
205 case e1000_fc_full:
196 ecmd->advertising |= ADVERTISED_Pause; 206 ecmd->advertising |= ADVERTISED_Pause;
197 else if (hw->fc.requested_mode == e1000_fc_rx_pause) 207 break;
208 case e1000_fc_rx_pause:
198 ecmd->advertising |= (ADVERTISED_Pause | 209 ecmd->advertising |= (ADVERTISED_Pause |
199 ADVERTISED_Asym_Pause); 210 ADVERTISED_Asym_Pause);
200 else if (hw->fc.requested_mode == e1000_fc_tx_pause) 211 break;
212 case e1000_fc_tx_pause:
201 ecmd->advertising |= ADVERTISED_Asym_Pause; 213 ecmd->advertising |= ADVERTISED_Asym_Pause;
202 else 214 break;
215 default:
203 ecmd->advertising &= ~(ADVERTISED_Pause | 216 ecmd->advertising &= ~(ADVERTISED_Pause |
204 ADVERTISED_Asym_Pause); 217 ADVERTISED_Asym_Pause);
205 218 }
206 status = rd32(E1000_STATUS);
207
208 if (status & E1000_STATUS_LU) { 219 if (status & E1000_STATUS_LU) {
209 if (hw->mac.type == e1000_i354) { 220 if ((status & E1000_STATUS_2P5_SKU) &&
210 if ((status & E1000_STATUS_2P5_SKU) && 221 !(status & E1000_STATUS_2P5_SKU_OVER)) {
211 !(status & E1000_STATUS_2P5_SKU_OVER)) { 222 ecmd->speed = SPEED_2500;
212 ecmd->supported = SUPPORTED_2500baseX_Full;
213 ecmd->advertising = ADVERTISED_2500baseX_Full;
214 ecmd->speed = SPEED_2500;
215 } else {
216 ecmd->supported = SUPPORTED_1000baseT_Full;
217 ecmd->advertising = ADVERTISED_1000baseT_Full;
218 }
219 } else if (status & E1000_STATUS_SPEED_1000) { 223 } else if (status & E1000_STATUS_SPEED_1000) {
220 ecmd->speed = SPEED_1000; 224 ecmd->speed = SPEED_1000;
221 } else if (status & E1000_STATUS_SPEED_100) { 225 } else if (status & E1000_STATUS_SPEED_100) {
@@ -232,7 +236,6 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
232 ecmd->speed = -1; 236 ecmd->speed = -1;
233 ecmd->duplex = -1; 237 ecmd->duplex = -1;
234 } 238 }
235
236 if ((hw->phy.media_type == e1000_media_type_fiber) || 239 if ((hw->phy.media_type == e1000_media_type_fiber) ||
237 hw->mac.autoneg) 240 hw->mac.autoneg)
238 ecmd->autoneg = AUTONEG_ENABLE; 241 ecmd->autoneg = AUTONEG_ENABLE;