mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-27 03:10:12 +00:00
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>
This commit is contained in:
parent
33243fb086
commit
f502ef7d77
3 changed files with 50 additions and 19 deletions
|
@ -98,7 +98,8 @@ enum e1000_mac_type {
|
||||||
enum e1000_media_type {
|
enum e1000_media_type {
|
||||||
e1000_media_type_unknown = 0,
|
e1000_media_type_unknown = 0,
|
||||||
e1000_media_type_copper = 1,
|
e1000_media_type_copper = 1,
|
||||||
e1000_media_type_internal_serdes = 2,
|
e1000_media_type_fiber = 2,
|
||||||
|
e1000_media_type_internal_serdes = 3,
|
||||||
e1000_num_media_types
|
e1000_num_media_types
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -178,27 +178,33 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
|
||||||
|
|
||||||
ecmd->port = PORT_TP;
|
ecmd->port = PORT_TP;
|
||||||
ecmd->phy_address = hw->phy.addr;
|
ecmd->phy_address = hw->phy.addr;
|
||||||
|
ecmd->transceiver = XCVR_INTERNAL;
|
||||||
} else {
|
} else {
|
||||||
ecmd->supported = (SUPPORTED_1000baseT_Full |
|
ecmd->supported = (SUPPORTED_1000baseT_Full |
|
||||||
|
SUPPORTED_100baseT_Full |
|
||||||
|
SUPPORTED_Autoneg |
|
||||||
SUPPORTED_FIBRE |
|
SUPPORTED_FIBRE |
|
||||||
SUPPORTED_Autoneg);
|
SUPPORTED_Pause);
|
||||||
|
|
||||||
ecmd->advertising = (ADVERTISED_1000baseT_Full |
|
ecmd->advertising = ADVERTISED_FIBRE;
|
||||||
ADVERTISED_FIBRE |
|
|
||||||
ADVERTISED_Autoneg |
|
if (adapter->link_speed == SPEED_100)
|
||||||
ADVERTISED_Pause);
|
ecmd->advertising = ADVERTISED_100baseT_Full;
|
||||||
|
else if (adapter->link_speed == SPEED_1000)
|
||||||
|
ecmd->advertising = ADVERTISED_1000baseT_Full;
|
||||||
|
|
||||||
|
if (hw->mac.autoneg == 1)
|
||||||
|
ecmd->advertising |= ADVERTISED_Autoneg;
|
||||||
|
|
||||||
ecmd->port = PORT_FIBRE;
|
ecmd->port = PORT_FIBRE;
|
||||||
|
ecmd->transceiver = XCVR_EXTERNAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ecmd->transceiver = XCVR_INTERNAL;
|
|
||||||
|
|
||||||
status = rd32(E1000_STATUS);
|
status = rd32(E1000_STATUS);
|
||||||
|
|
||||||
if (status & E1000_STATUS_LU) {
|
if (status & E1000_STATUS_LU) {
|
||||||
|
|
||||||
if ((status & E1000_STATUS_SPEED_1000) ||
|
if (status & E1000_STATUS_SPEED_1000)
|
||||||
hw->phy.media_type != e1000_media_type_copper)
|
|
||||||
ethtool_cmd_speed_set(ecmd, SPEED_1000);
|
ethtool_cmd_speed_set(ecmd, SPEED_1000);
|
||||||
else if (status & E1000_STATUS_SPEED_100)
|
else if (status & E1000_STATUS_SPEED_100)
|
||||||
ethtool_cmd_speed_set(ecmd, SPEED_100);
|
ethtool_cmd_speed_set(ecmd, SPEED_100);
|
||||||
|
@ -215,7 +221,11 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
|
||||||
ecmd->duplex = -1;
|
ecmd->duplex = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ecmd->autoneg = hw->mac.autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE;
|
if ((hw->phy.media_type == e1000_media_type_fiber) ||
|
||||||
|
hw->mac.autoneg)
|
||||||
|
ecmd->autoneg = AUTONEG_ENABLE;
|
||||||
|
else
|
||||||
|
ecmd->autoneg = AUTONEG_DISABLE;
|
||||||
|
|
||||||
/* MDI-X => 2; MDI =>1; Invalid =>0 */
|
/* MDI-X => 2; MDI =>1; Invalid =>0 */
|
||||||
if (hw->phy.media_type == e1000_media_type_copper)
|
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)
|
||||||
|
|
||||||
if (ecmd->autoneg == AUTONEG_ENABLE) {
|
if (ecmd->autoneg == AUTONEG_ENABLE) {
|
||||||
hw->mac.autoneg = 1;
|
hw->mac.autoneg = 1;
|
||||||
hw->phy.autoneg_advertised = ecmd->advertising |
|
if (hw->phy.media_type == e1000_media_type_fiber) {
|
||||||
ADVERTISED_TP |
|
hw->phy.autoneg_advertised = ecmd->advertising |
|
||||||
ADVERTISED_Autoneg;
|
ADVERTISED_FIBRE |
|
||||||
|
ADVERTISED_Autoneg;
|
||||||
|
if (adapter->link_speed == SPEED_1000)
|
||||||
|
hw->phy.autoneg_advertised =
|
||||||
|
ADVERTISED_1000baseT_Full;
|
||||||
|
else if (adapter->link_speed == SPEED_100)
|
||||||
|
hw->phy.autoneg_advertised =
|
||||||
|
ADVERTISED_100baseT_Full;
|
||||||
|
} else {
|
||||||
|
hw->phy.autoneg_advertised = ecmd->advertising |
|
||||||
|
ADVERTISED_TP |
|
||||||
|
ADVERTISED_Autoneg;
|
||||||
|
}
|
||||||
ecmd->advertising = hw->phy.autoneg_advertised;
|
ecmd->advertising = hw->phy.autoneg_advertised;
|
||||||
if (adapter->fc_autoneg)
|
if (adapter->fc_autoneg)
|
||||||
hw->fc.requested_mode = e1000_fc_default;
|
hw->fc.requested_mode = e1000_fc_default;
|
||||||
|
|
|
@ -7008,11 +7008,19 @@ int igb_set_spd_dplx(struct igb_adapter *adapter, u32 spd, u8 dplx)
|
||||||
if ((spd & 1) || (dplx & ~1))
|
if ((spd & 1) || (dplx & ~1))
|
||||||
goto err_inval;
|
goto err_inval;
|
||||||
|
|
||||||
/* Fiber NIC's only allow 1000 Gbps Full duplex */
|
/* Fiber NIC's only allow 1000 gbps Full duplex
|
||||||
if ((adapter->hw.phy.media_type == e1000_media_type_internal_serdes) &&
|
* and 100Mbps Full duplex for 100baseFx sfp
|
||||||
spd != SPEED_1000 &&
|
*/
|
||||||
dplx != DUPLEX_FULL)
|
if (adapter->hw.phy.media_type == e1000_media_type_internal_serdes) {
|
||||||
goto err_inval;
|
switch (spd + dplx) {
|
||||||
|
case SPEED_10 + DUPLEX_HALF:
|
||||||
|
case SPEED_10 + DUPLEX_FULL:
|
||||||
|
case SPEED_100 + DUPLEX_HALF:
|
||||||
|
goto err_inval;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (spd + dplx) {
|
switch (spd + dplx) {
|
||||||
case SPEED_10 + DUPLEX_HALF:
|
case SPEED_10 + DUPLEX_HALF:
|
||||||
|
|
Loading…
Reference in a new issue