aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAkeem G. Abodunrin <akeem.g.abodunrin@intel.com>2013-04-05 12:49:06 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2013-04-18 17:03:15 -0400
commitf502ef7d77dd09bad9c93ee854fcb61d6fc29815 (patch)
tree75efb858370a22c504064e624ff6b79275c0cd45
parent33243fb08678d6bdbe3f442dd72ed50b45efd474 (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.h3
-rw-r--r--drivers/net/ethernet/intel/igb/igb_ethtool.c48
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c18
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 {
98enum e1000_media_type { 98enum 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: