Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bba6ec7e authored by David S. Miller's avatar David S. Miller
Browse files


Jeff Kirsher says:

====================
This series contains updates to ethtool.h, e1000, e1000e, and igb to
implement MDI/MDIx control.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 1304a734 8376dad0
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
@@ -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)) {
+4 −0
Original line number Diff line number Diff line
@@ -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:
+39 −2
Original line number Diff line number Diff line
@@ -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;
+29 −2
Original line number Diff line number Diff line
@@ -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);
}

+27 −2
Original line number Diff line number Diff line
@@ -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)
Loading