diff options
author | Akeem G. Abodunrin <akeem.g.abodunrin@intel.com> | 2013-04-05 12:49:06 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2013-04-18 17:03:15 -0400 |
commit | f502ef7d77dd09bad9c93ee854fcb61d6fc29815 (patch) | |
tree | 75efb858370a22c504064e624ff6b79275c0cd45 | |
parent | 33243fb08678d6bdbe3f442dd72ed50b45efd474 (diff) |
igb: Support for 100base-fx SFP
This patch adds support for 100base-fx SFP and report proper link speed/duplex
via Ethtool.
v2: fix smatch warnings
CC: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Akeem G Abodunrin <akeem.g.abodunrin@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r-- | drivers/net/ethernet/intel/igb/e1000_hw.h | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/igb/igb_ethtool.c | 48 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/igb/igb_main.c | 18 |
3 files changed, 50 insertions, 19 deletions
diff --git a/drivers/net/ethernet/intel/igb/e1000_hw.h b/drivers/net/ethernet/intel/igb/e1000_hw.h index 0d5cf9c63d0d..f8cd124dcf1d 100644 --- a/drivers/net/ethernet/intel/igb/e1000_hw.h +++ b/drivers/net/ethernet/intel/igb/e1000_hw.h | |||
@@ -98,7 +98,8 @@ enum e1000_mac_type { | |||
98 | enum e1000_media_type { | 98 | enum e1000_media_type { |
99 | e1000_media_type_unknown = 0, | 99 | e1000_media_type_unknown = 0, |
100 | e1000_media_type_copper = 1, | 100 | e1000_media_type_copper = 1, |
101 | e1000_media_type_internal_serdes = 2, | 101 | e1000_media_type_fiber = 2, |
102 | e1000_media_type_internal_serdes = 3, | ||
102 | e1000_num_media_types | 103 | e1000_num_media_types |
103 | }; | 104 | }; |
104 | 105 | ||
diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c index a3830a8ba4c1..8499c48090c6 100644 --- a/drivers/net/ethernet/intel/igb/igb_ethtool.c +++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c | |||
@@ -178,27 +178,33 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | |||
178 | 178 | ||
179 | ecmd->port = PORT_TP; | 179 | ecmd->port = PORT_TP; |
180 | ecmd->phy_address = hw->phy.addr; | 180 | ecmd->phy_address = hw->phy.addr; |
181 | ecmd->transceiver = XCVR_INTERNAL; | ||
181 | } else { | 182 | } else { |
182 | ecmd->supported = (SUPPORTED_1000baseT_Full | | 183 | ecmd->supported = (SUPPORTED_1000baseT_Full | |
184 | SUPPORTED_100baseT_Full | | ||
185 | SUPPORTED_Autoneg | | ||
183 | SUPPORTED_FIBRE | | 186 | SUPPORTED_FIBRE | |
184 | SUPPORTED_Autoneg); | 187 | SUPPORTED_Pause); |
185 | 188 | ||
186 | ecmd->advertising = (ADVERTISED_1000baseT_Full | | 189 | ecmd->advertising = ADVERTISED_FIBRE; |
187 | ADVERTISED_FIBRE | | 190 | |
188 | ADVERTISED_Autoneg | | 191 | if (adapter->link_speed == SPEED_100) |
189 | ADVERTISED_Pause); | 192 | ecmd->advertising = ADVERTISED_100baseT_Full; |
193 | else if (adapter->link_speed == SPEED_1000) | ||
194 | ecmd->advertising = ADVERTISED_1000baseT_Full; | ||
195 | |||
196 | if (hw->mac.autoneg == 1) | ||
197 | ecmd->advertising |= ADVERTISED_Autoneg; | ||
190 | 198 | ||
191 | ecmd->port = PORT_FIBRE; | 199 | ecmd->port = PORT_FIBRE; |
200 | ecmd->transceiver = XCVR_EXTERNAL; | ||
192 | } | 201 | } |
193 | 202 | ||
194 | ecmd->transceiver = XCVR_INTERNAL; | ||
195 | |||
196 | status = rd32(E1000_STATUS); | 203 | status = rd32(E1000_STATUS); |
197 | 204 | ||
198 | if (status & E1000_STATUS_LU) { | 205 | if (status & E1000_STATUS_LU) { |
199 | 206 | ||
200 | if ((status & E1000_STATUS_SPEED_1000) || | 207 | if (status & E1000_STATUS_SPEED_1000) |
201 | hw->phy.media_type != e1000_media_type_copper) | ||
202 | ethtool_cmd_speed_set(ecmd, SPEED_1000); | 208 | ethtool_cmd_speed_set(ecmd, SPEED_1000); |
203 | else if (status & E1000_STATUS_SPEED_100) | 209 | else if (status & E1000_STATUS_SPEED_100) |
204 | ethtool_cmd_speed_set(ecmd, SPEED_100); | 210 | ethtool_cmd_speed_set(ecmd, SPEED_100); |
@@ -215,7 +221,11 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | |||
215 | ecmd->duplex = -1; | 221 | ecmd->duplex = -1; |
216 | } | 222 | } |
217 | 223 | ||
218 | ecmd->autoneg = hw->mac.autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE; | 224 | if ((hw->phy.media_type == e1000_media_type_fiber) || |
225 | hw->mac.autoneg) | ||
226 | ecmd->autoneg = AUTONEG_ENABLE; | ||
227 | else | ||
228 | ecmd->autoneg = AUTONEG_DISABLE; | ||
219 | 229 | ||
220 | /* MDI-X => 2; MDI =>1; Invalid =>0 */ | 230 | /* MDI-X => 2; MDI =>1; Invalid =>0 */ |
221 | if (hw->phy.media_type == e1000_media_type_copper) | 231 | if (hw->phy.media_type == e1000_media_type_copper) |
@@ -266,9 +276,21 @@ static int igb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | |||
266 | 276 | ||
267 | if (ecmd->autoneg == AUTONEG_ENABLE) { | 277 | if (ecmd->autoneg == AUTONEG_ENABLE) { |
268 | hw->mac.autoneg = 1; | 278 | hw->mac.autoneg = 1; |
269 | hw->phy.autoneg_advertised = ecmd->advertising | | 279 | if (hw->phy.media_type == e1000_media_type_fiber) { |
270 | ADVERTISED_TP | | 280 | hw->phy.autoneg_advertised = ecmd->advertising | |
271 | ADVERTISED_Autoneg; | 281 | ADVERTISED_FIBRE | |
282 | ADVERTISED_Autoneg; | ||
283 | if (adapter->link_speed == SPEED_1000) | ||
284 | hw->phy.autoneg_advertised = | ||
285 | ADVERTISED_1000baseT_Full; | ||
286 | else if (adapter->link_speed == SPEED_100) | ||
287 | hw->phy.autoneg_advertised = | ||
288 | ADVERTISED_100baseT_Full; | ||
289 | } else { | ||
290 | hw->phy.autoneg_advertised = ecmd->advertising | | ||
291 | ADVERTISED_TP | | ||
292 | ADVERTISED_Autoneg; | ||
293 | } | ||
272 | ecmd->advertising = hw->phy.autoneg_advertised; | 294 | ecmd->advertising = hw->phy.autoneg_advertised; |
273 | if (adapter->fc_autoneg) | 295 | if (adapter->fc_autoneg) |
274 | hw->fc.requested_mode = e1000_fc_default; | 296 | hw->fc.requested_mode = e1000_fc_default; |
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 8496adfc6a68..0a465ae1cdfa 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c | |||
@@ -7008,11 +7008,19 @@ int igb_set_spd_dplx(struct igb_adapter *adapter, u32 spd, u8 dplx) | |||
7008 | if ((spd & 1) || (dplx & ~1)) | 7008 | if ((spd & 1) || (dplx & ~1)) |
7009 | goto err_inval; | 7009 | goto err_inval; |
7010 | 7010 | ||
7011 | /* Fiber NIC's only allow 1000 Gbps Full duplex */ | 7011 | /* Fiber NIC's only allow 1000 gbps Full duplex |
7012 | if ((adapter->hw.phy.media_type == e1000_media_type_internal_serdes) && | 7012 | * and 100Mbps Full duplex for 100baseFx sfp |
7013 | spd != SPEED_1000 && | 7013 | */ |
7014 | dplx != DUPLEX_FULL) | 7014 | if (adapter->hw.phy.media_type == e1000_media_type_internal_serdes) { |
7015 | goto err_inval; | 7015 | switch (spd + dplx) { |
7016 | case SPEED_10 + DUPLEX_HALF: | ||
7017 | case SPEED_10 + DUPLEX_FULL: | ||
7018 | case SPEED_100 + DUPLEX_HALF: | ||
7019 | goto err_inval; | ||
7020 | default: | ||
7021 | break; | ||
7022 | } | ||
7023 | } | ||
7016 | 7024 | ||
7017 | switch (spd + dplx) { | 7025 | switch (spd + dplx) { |
7018 | case SPEED_10 + DUPLEX_HALF: | 7026 | case SPEED_10 + DUPLEX_HALF: |