|
@@ -174,6 +174,20 @@ static int e1000_get_settings(struct net_device *netdev,
|
|
|
|
|
|
ecmd->autoneg = ((hw->media_type == e1000_media_type_fiber) ||
|
|
|
hw->autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE;
|
|
|
+
|
|
|
+ /* MDI-X => 1; MDI => 0 */
|
|
|
+ if ((hw->media_type == e1000_media_type_copper) &&
|
|
|
+ netif_carrier_ok(netdev))
|
|
|
+ ecmd->eth_tp_mdix = (!!adapter->phy_info.mdix_mode ?
|
|
|
+ ETH_TP_MDI_X :
|
|
|
+ ETH_TP_MDI);
|
|
|
+ else
|
|
|
+ ecmd->eth_tp_mdix = ETH_TP_MDI_INVALID;
|
|
|
+
|
|
|
+ if (hw->mdix == AUTO_ALL_MODES)
|
|
|
+ ecmd->eth_tp_mdix_ctrl = ETH_TP_MDI_AUTO;
|
|
|
+ else
|
|
|
+ ecmd->eth_tp_mdix_ctrl = hw->mdix;
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -183,6 +197,22 @@ static int e1000_set_settings(struct net_device *netdev,
|
|
|
struct e1000_adapter *adapter = netdev_priv(netdev);
|
|
|
struct e1000_hw *hw = &adapter->hw;
|
|
|
|
|
|
+ /*
|
|
|
+ * 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->media_type != e1000_media_type_copper)
|
|
|
+ return -EOPNOTSUPP;
|
|
|
+
|
|
|
+ if ((ecmd->eth_tp_mdix_ctrl != ETH_TP_MDI_AUTO) &&
|
|
|
+ (ecmd->autoneg != AUTONEG_ENABLE)) {
|
|
|
+ e_err(drv, "forcing MDI/MDI-X state is not supported when link speed and/or duplex are forced\n");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
|
|
|
msleep(1);
|
|
|
|
|
@@ -199,12 +229,21 @@ static int e1000_set_settings(struct net_device *netdev,
|
|
|
ecmd->advertising = hw->autoneg_advertised;
|
|
|
} else {
|
|
|
u32 speed = ethtool_cmd_speed(ecmd);
|
|
|
+ /* calling this overrides forced MDI setting */
|
|
|
if (e1000_set_spd_dplx(adapter, speed, ecmd->duplex)) {
|
|
|
clear_bit(__E1000_RESETTING, &adapter->flags);
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /* MDI-X => 2; MDI => 1; Auto => 3 */
|
|
|
+ if (ecmd->eth_tp_mdix_ctrl) {
|
|
|
+ if (ecmd->eth_tp_mdix_ctrl == ETH_TP_MDI_AUTO)
|
|
|
+ hw->mdix = AUTO_ALL_MODES;
|
|
|
+ else
|
|
|
+ hw->mdix = ecmd->eth_tp_mdix_ctrl;
|
|
|
+ }
|
|
|
+
|
|
|
/* reset the link */
|
|
|
|
|
|
if (netif_running(adapter->netdev)) {
|