forked from Minki/linux
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next
Jeff Kirsher says: ==================== This series contains updates to ethtool.h, e1000, e1000e, and igb to implement MDI/MDIx control. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
bba6ec7e49
@ -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)) {
|
||||
|
@ -4939,6 +4939,10 @@ int e1000_set_spd_dplx(struct e1000_adapter *adapter, u32 spd, u8 dplx)
|
||||
default:
|
||||
goto err_inval;
|
||||
}
|
||||
|
||||
/* clear MDI, MDI(-X) override is only allowed when autoneg enabled */
|
||||
hw->mdix = AUTO_ALL_MODES;
|
||||
|
||||
return 0;
|
||||
|
||||
err_inval:
|
||||
|
@ -199,6 +199,11 @@ static int e1000_get_settings(struct net_device *netdev,
|
||||
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;
|
||||
}
|
||||
|
||||
@ -241,6 +246,10 @@ static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u32 spd, u8 dplx)
|
||||
default:
|
||||
goto err_inval;
|
||||
}
|
||||
|
||||
/* clear MDI, MDI(-X) override is only allowed when autoneg enabled */
|
||||
adapter->hw.phy.mdix = AUTO_ALL_MODES;
|
||||
|
||||
return 0;
|
||||
|
||||
err_inval:
|
||||
@ -264,6 +273,22 @@ static int e1000_set_settings(struct net_device *netdev,
|
||||
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)) {
|
||||
e_err("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->state))
|
||||
usleep_range(1000, 2000);
|
||||
|
||||
@ -282,20 +307,32 @@ static int e1000_set_settings(struct net_device *netdev,
|
||||
hw->fc.requested_mode = e1000_fc_default;
|
||||
} 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->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)) {
|
||||
e1000e_down(adapter);
|
||||
e1000e_up(adapter);
|
||||
} else {
|
||||
} else
|
||||
e1000e_reset(adapter);
|
||||
}
|
||||
|
||||
clear_bit(__E1000_RESETTING, &adapter->state);
|
||||
return 0;
|
||||
|
@ -84,8 +84,9 @@ static const u16 e1000_igp_2_cable_length_table[] = {
|
||||
#define I82577_PHY_STATUS2_SPEED_1000MBPS 0x0200
|
||||
|
||||
/* I82577 PHY Control 2 */
|
||||
#define I82577_PHY_CTRL2_AUTO_MDIX 0x0400
|
||||
#define I82577_PHY_CTRL2_FORCE_MDI_MDIX 0x0200
|
||||
#define I82577_PHY_CTRL2_MANUAL_MDIX 0x0200
|
||||
#define I82577_PHY_CTRL2_AUTO_MDI_MDIX 0x0400
|
||||
#define I82577_PHY_CTRL2_MDIX_CFG_MASK 0x0600
|
||||
|
||||
/* I82577 PHY Diagnostics Status */
|
||||
#define I82577_DSTATUS_CABLE_LENGTH 0x03FC
|
||||
@ -702,6 +703,32 @@ s32 e1000_copper_link_setup_82577(struct e1000_hw *hw)
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
/* Set MDI/MDIX mode */
|
||||
ret_val = e1e_rphy(hw, I82577_PHY_CTRL_2, &phy_data);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
phy_data &= ~I82577_PHY_CTRL2_MDIX_CFG_MASK;
|
||||
/*
|
||||
* Options:
|
||||
* 0 - Auto (default)
|
||||
* 1 - MDI mode
|
||||
* 2 - MDI-X mode
|
||||
*/
|
||||
switch (hw->phy.mdix) {
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
phy_data |= I82577_PHY_CTRL2_MANUAL_MDIX;
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
phy_data |= I82577_PHY_CTRL2_AUTO_MDI_MDIX;
|
||||
break;
|
||||
}
|
||||
ret_val = e1e_wphy(hw, I82577_PHY_CTRL_2, phy_data);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
return e1000_set_master_slave_mode(hw);
|
||||
}
|
||||
|
||||
|
@ -464,6 +464,32 @@ s32 igb_copper_link_setup_82580(struct e1000_hw *hw)
|
||||
phy_data |= I82580_CFG_ENABLE_DOWNSHIFT;
|
||||
|
||||
ret_val = phy->ops.write_reg(hw, I82580_CFG_REG, phy_data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
/* Set MDI/MDIX mode */
|
||||
ret_val = phy->ops.read_reg(hw, I82580_PHY_CTRL_2, &phy_data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
phy_data &= ~I82580_PHY_CTRL2_MDIX_CFG_MASK;
|
||||
/*
|
||||
* Options:
|
||||
* 0 - Auto (default)
|
||||
* 1 - MDI mode
|
||||
* 2 - MDI-X mode
|
||||
*/
|
||||
switch (hw->phy.mdix) {
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
phy_data |= I82580_PHY_CTRL2_MANUAL_MDIX;
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
phy_data |= I82580_PHY_CTRL2_AUTO_MDI_MDIX;
|
||||
break;
|
||||
}
|
||||
ret_val = hw->phy.ops.write_reg(hw, I82580_PHY_CTRL_2, phy_data);
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
@ -2246,8 +2272,7 @@ s32 igb_phy_force_speed_duplex_82580(struct e1000_hw *hw)
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
phy_data &= ~I82580_PHY_CTRL2_AUTO_MDIX;
|
||||
phy_data &= ~I82580_PHY_CTRL2_FORCE_MDI_MDIX;
|
||||
phy_data &= ~I82580_PHY_CTRL2_MDIX_CFG_MASK;
|
||||
|
||||
ret_val = phy->ops.write_reg(hw, I82580_PHY_CTRL_2, phy_data);
|
||||
if (ret_val)
|
||||
|
@ -111,8 +111,9 @@ s32 igb_check_polarity_m88(struct e1000_hw *hw);
|
||||
#define I82580_PHY_STATUS2_SPEED_100MBPS 0x0100
|
||||
|
||||
/* I82580 PHY Control 2 */
|
||||
#define I82580_PHY_CTRL2_AUTO_MDIX 0x0400
|
||||
#define I82580_PHY_CTRL2_FORCE_MDI_MDIX 0x0200
|
||||
#define I82580_PHY_CTRL2_MANUAL_MDIX 0x0200
|
||||
#define I82580_PHY_CTRL2_AUTO_MDI_MDIX 0x0400
|
||||
#define I82580_PHY_CTRL2_MDIX_CFG_MASK 0x0600
|
||||
|
||||
/* I82580 PHY Diagnostics Status */
|
||||
#define I82580_DSTATUS_CABLE_LENGTH 0x03FC
|
||||
|
@ -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);
|
||||
|
@ -6675,6 +6675,10 @@ int igb_set_spd_dplx(struct igb_adapter *adapter, u32 spd, u8 dplx)
|
||||
default:
|
||||
goto err_inval;
|
||||
}
|
||||
|
||||
/* clear MDI, MDI(-X) override is only allowed when autoneg enabled */
|
||||
adapter->hw.phy.mdix = AUTO_ALL_MODES;
|
||||
|
||||
return 0;
|
||||
|
||||
err_inval:
|
||||
|
@ -45,8 +45,10 @@ struct ethtool_cmd {
|
||||
* bits) in Mbps. Please use
|
||||
* ethtool_cmd_speed()/_set() to
|
||||
* access it */
|
||||
__u8 eth_tp_mdix;
|
||||
__u8 reserved2;
|
||||
__u8 eth_tp_mdix; /* twisted pair MDI-X status */
|
||||
__u8 eth_tp_mdix_ctrl; /* twisted pair MDI-X control, when set,
|
||||
* link should be renegotiated if necessary
|
||||
*/
|
||||
__u32 lp_advertising; /* Features the link partner advertises */
|
||||
__u32 reserved[2];
|
||||
};
|
||||
@ -1229,10 +1231,13 @@ struct ethtool_ops {
|
||||
#define AUTONEG_DISABLE 0x00
|
||||
#define AUTONEG_ENABLE 0x01
|
||||
|
||||
/* Mode MDI or MDI-X */
|
||||
#define ETH_TP_MDI_INVALID 0x00
|
||||
#define ETH_TP_MDI 0x01
|
||||
#define ETH_TP_MDI_X 0x02
|
||||
/* MDI or MDI-X status/control - if MDI/MDI_X/AUTO is set then
|
||||
* the driver is required to renegotiate link
|
||||
*/
|
||||
#define ETH_TP_MDI_INVALID 0x00 /* status: unknown; control: unsupported */
|
||||
#define ETH_TP_MDI 0x01 /* status: MDI; control: force MDI */
|
||||
#define ETH_TP_MDI_X 0x02 /* status: MDI-X; control: force MDI-X */
|
||||
#define ETH_TP_MDI_AUTO 0x03 /* control: auto-select */
|
||||
|
||||
/* Wake-On-Lan options. */
|
||||
#define WAKE_PHY (1 << 0)
|
||||
|
Loading…
Reference in New Issue
Block a user