|
@@ -198,6 +198,19 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
|
|
|
}
|
|
|
|
|
|
ecmd->autoneg = hw->mac.autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE;
|
|
|
+
|
|
|
+ /* MDI-X => 2; MDI =>1; Invalid =>0 */
|
|
|
+ if (hw->phy.media_type == e1000_media_type_copper)
|
|
|
+ ecmd->eth_tp_mdix = hw->phy.is_mdix ? ETH_TP_MDI_X :
|
|
|
+ ETH_TP_MDI;
|
|
|
+ else
|
|
|
+ ecmd->eth_tp_mdix = ETH_TP_MDI_INVALID;
|
|
|
+
|
|
|
+ if (hw->phy.mdix == AUTO_ALL_MODES)
|
|
|
+ ecmd->eth_tp_mdix_ctrl = ETH_TP_MDI_AUTO;
|
|
|
+ else
|
|
|
+ ecmd->eth_tp_mdix_ctrl = hw->phy.mdix;
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -214,6 +227,22 @@ static int igb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ * MDI setting is only allowed when autoneg enabled because
|
|
|
+ * some hardware doesn't allow MDI setting when speed or
|
|
|
+ * duplex is forced.
|
|
|
+ */
|
|
|
+ if (ecmd->eth_tp_mdix_ctrl) {
|
|
|
+ if (hw->phy.media_type != e1000_media_type_copper)
|
|
|
+ return -EOPNOTSUPP;
|
|
|
+
|
|
|
+ if ((ecmd->eth_tp_mdix_ctrl != ETH_TP_MDI_AUTO) &&
|
|
|
+ (ecmd->autoneg != AUTONEG_ENABLE)) {
|
|
|
+ dev_err(&adapter->pdev->dev, "forcing MDI/MDI-X state is not supported when link speed and/or duplex are forced\n");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
|
|
|
msleep(1);
|
|
|
|
|
@@ -227,12 +256,25 @@ static int igb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
|
|
|
hw->fc.requested_mode = e1000_fc_default;
|
|
|
} else {
|
|
|
u32 speed = ethtool_cmd_speed(ecmd);
|
|
|
+ /* calling this overrides forced MDI setting */
|
|
|
if (igb_set_spd_dplx(adapter, speed, ecmd->duplex)) {
|
|
|
clear_bit(__IGB_RESETTING, &adapter->state);
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /* MDI-X => 2; MDI => 1; Auto => 3 */
|
|
|
+ if (ecmd->eth_tp_mdix_ctrl) {
|
|
|
+ /*
|
|
|
+ * fix up the value for auto (3 => 0) as zero is mapped
|
|
|
+ * internally to auto
|
|
|
+ */
|
|
|
+ if (ecmd->eth_tp_mdix_ctrl == ETH_TP_MDI_AUTO)
|
|
|
+ hw->phy.mdix = AUTO_ALL_MODES;
|
|
|
+ else
|
|
|
+ hw->phy.mdix = ecmd->eth_tp_mdix_ctrl;
|
|
|
+ }
|
|
|
+
|
|
|
/* reset the link */
|
|
|
if (netif_running(adapter->netdev)) {
|
|
|
igb_down(adapter);
|