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

Commit 297e1cf2 authored by Ariel Levkovich's avatar Ariel Levkovich Committed by David S. Miller
Browse files

net/mlx4_en: Adding support of turning off link autonegotiation via ethtool



This feature will allow the user to disable auto negotiation
on the port for mlx4 devices while setting the speed is limited
to 1GbE speeds.
Other speeds will not be accepted in autoneg off mode.

This functionality is permitted providing that the firmware
is compatible with this feature.
The above is determined by querying a new dedicated capability
bit in the device.

Signed-off-by: default avatarAriel Levkovich <lariel@mellanox.com>
Signed-off-by: default avatarTariq Toukan <tariqt@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4b5e5b7e
Loading
Loading
Loading
Loading
+19 −5
Original line number Diff line number Diff line
@@ -902,6 +902,7 @@ mlx4_en_set_link_ksettings(struct net_device *dev,
	struct mlx4_en_priv *priv = netdev_priv(dev);
	struct mlx4_ptys_reg ptys_reg;
	__be32 proto_admin;
	u8 cur_autoneg;
	int ret;

	u32 ptys_adv = ethtool2ptys_link_modes(
@@ -931,10 +932,21 @@ mlx4_en_set_link_ksettings(struct net_device *dev,
		return 0;
	}

	proto_admin = link_ksettings->base.autoneg == AUTONEG_ENABLE ?
		cpu_to_be32(ptys_adv) :
		speed_set_ptys_admin(priv, speed,
	cur_autoneg = ptys_reg.flags & MLX4_PTYS_AN_DISABLE_ADMIN ?
				AUTONEG_DISABLE : AUTONEG_ENABLE;

	if (link_ksettings->base.autoneg == AUTONEG_DISABLE) {
		proto_admin = speed_set_ptys_admin(priv, speed,
						   ptys_reg.eth_proto_cap);
		if ((be32_to_cpu(proto_admin) &
		     (MLX4_PROT_MASK(MLX4_1000BASE_CX_SGMII) |
		      MLX4_PROT_MASK(MLX4_1000BASE_KX))) &&
		    (ptys_reg.flags & MLX4_PTYS_AN_DISABLE_CAP))
			ptys_reg.flags |= MLX4_PTYS_AN_DISABLE_ADMIN;
	} else {
		proto_admin = cpu_to_be32(ptys_adv);
		ptys_reg.flags &= ~MLX4_PTYS_AN_DISABLE_ADMIN;
	}

	proto_admin &= ptys_reg.eth_proto_cap;
	if (!proto_admin) {
@@ -942,7 +954,9 @@ mlx4_en_set_link_ksettings(struct net_device *dev,
		return -EINVAL; /* nothing to change due to bad input */
	}

	if (proto_admin == ptys_reg.eth_proto_admin)
	if ((proto_admin == ptys_reg.eth_proto_admin) &&
	    ((ptys_reg.flags & MLX4_PTYS_AN_DISABLE_CAP) &&
	     (link_ksettings->base.autoneg == cur_autoneg)))
		return 0; /* Nothing to change */

	en_dbg(DRV, priv, "mlx4_ACCESS_PTYS_REG SET: ptys_reg.eth_proto_admin = 0x%x\n",
+6 −1
Original line number Diff line number Diff line
@@ -1539,8 +1539,13 @@ enum mlx4_ptys_proto {
	MLX4_PTYS_EN = 1<<2,
};

enum mlx4_ptys_flags {
	MLX4_PTYS_AN_DISABLE_CAP   = 1 << 5,
	MLX4_PTYS_AN_DISABLE_ADMIN = 1 << 6,
};

struct mlx4_ptys_reg {
	u8 resrvd1;
	u8 flags;
	u8 local_port;
	u8 resrvd2;
	u8 proto_mask;