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

Merge tag 'mlx5-updates-2019-02-19' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux



Saeed Mahameed says:

====================
mlx5-updates-2019-02-19

This series includes misc updates to mlx5 drivers and one ethtool update.

1) From Aya Levin:
   - ethtool: Define 50Gbps per lane link modes
   - add support for 50Gbps per lane link modes in mlx5 driver

2) From Tariq Toukan,
   - Add a helper function to unify mlx5 resource reloading

3) From Vlad Buslov,
   - Remove wrong and superfluous tc pedit header type check

4) From Tonghao Zhang,
   - Some refactoring in en_tc.c to simplify the mlx5e_tc_add_fdb_flow

5) From Leon Romanovsky & Saeed,
   - Compilation warning fixes

6) From Bodong wang,
   - E-Switch fixes that are related to the SmarNIC series
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 51dcb69d 1c50d369
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -858,7 +858,7 @@ void mlx5e_close_channels(struct mlx5e_channels *chs);
 * switching channels
 */
typedef int (*mlx5e_fp_hw_modify)(struct mlx5e_priv *priv);
void mlx5e_switch_priv_channels(struct mlx5e_priv *priv,
int mlx5e_safe_switch_channels(struct mlx5e_priv *priv,
			       struct mlx5e_channels *new_chs,
			       mlx5e_fp_hw_modify hw_modify);
void mlx5e_activate_priv_channels(struct mlx5e_priv *priv);
+1 −1
Original line number Diff line number Diff line
@@ -66,7 +66,7 @@ static int mlx5e_monitor_event_handler(struct notifier_block *nb,
	return NOTIFY_OK;
}

void mlx5e_monitor_counter_start(struct mlx5e_priv *priv)
static void mlx5e_monitor_counter_start(struct mlx5e_priv *priv)
{
	MLX5_NB_INIT(&priv->monitor_counters_nb, mlx5e_monitor_event_handler,
		     MONITOR_COUNTER);
+1 −3
Original line number Diff line number Diff line
@@ -1126,9 +1126,7 @@ static void mlx5e_trust_update_sq_inline_mode(struct mlx5e_priv *priv)
	    priv->channels.params.tx_min_inline_mode)
		goto out;

	if (mlx5e_open_channels(priv, &new_channels))
		goto out;
	mlx5e_switch_priv_channels(priv, &new_channels, NULL);
	mlx5e_safe_switch_channels(priv, &new_channels, NULL);

out:
	mutex_unlock(&priv->state_lock);
+193 −104
Original line number Diff line number Diff line
@@ -63,76 +63,147 @@ struct ptys2ethtool_config {
	__ETHTOOL_DECLARE_LINK_MODE_MASK(advertised);
};

static struct ptys2ethtool_config ptys2ethtool_table[MLX5E_LINK_MODES_NUMBER];
static
struct ptys2ethtool_config ptys2legacy_ethtool_table[MLX5E_LINK_MODES_NUMBER];
static
struct ptys2ethtool_config ptys2ext_ethtool_table[MLX5E_EXT_LINK_MODES_NUMBER];

#define MLX5_BUILD_PTYS2ETHTOOL_CONFIG(reg_, ...)                       \
#define MLX5_BUILD_PTYS2ETHTOOL_CONFIG(reg_, table, ...)                  \
	({                                                              \
		struct ptys2ethtool_config *cfg;                        \
		const unsigned int modes[] = { __VA_ARGS__ };           \
		unsigned int i;                                         \
		cfg = &ptys2ethtool_table[reg_];                        \
		unsigned int i, bit, idx;                               \
		cfg = &ptys2##table##_ethtool_table[reg_];		\
		bitmap_zero(cfg->supported,                             \
			    __ETHTOOL_LINK_MODE_MASK_NBITS);            \
		bitmap_zero(cfg->advertised,                            \
			    __ETHTOOL_LINK_MODE_MASK_NBITS);            \
		for (i = 0 ; i < ARRAY_SIZE(modes) ; ++i) {             \
			__set_bit(modes[i], cfg->supported);            \
			__set_bit(modes[i], cfg->advertised);           \
			bit = modes[i] % 64;                            \
			idx = modes[i] / 64;                            \
			__set_bit(bit, &cfg->supported[idx]);           \
			__set_bit(bit, &cfg->advertised[idx]);          \
		}                                                       \
	})

void mlx5e_build_ptys2ethtool_map(void)
{
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_1000BASE_CX_SGMII,
	memset(ptys2legacy_ethtool_table, 0, sizeof(ptys2legacy_ethtool_table));
	memset(ptys2ext_ethtool_table, 0, sizeof(ptys2ext_ethtool_table));
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_1000BASE_CX_SGMII, legacy,
				       ETHTOOL_LINK_MODE_1000baseKX_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_1000BASE_KX,
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_1000BASE_KX, legacy,
				       ETHTOOL_LINK_MODE_1000baseKX_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_CX4,
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_CX4, legacy,
				       ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_KX4,
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_KX4, legacy,
				       ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_KR,
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_KR, legacy,
				       ETHTOOL_LINK_MODE_10000baseKR_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_20GBASE_KR2,
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_20GBASE_KR2, legacy,
				       ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_40GBASE_CR4,
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_40GBASE_CR4, legacy,
				       ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_40GBASE_KR4,
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_40GBASE_KR4, legacy,
				       ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_56GBASE_R4,
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_56GBASE_R4, legacy,
				       ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_CR,
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_CR, legacy,
				       ETHTOOL_LINK_MODE_10000baseKR_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_SR,
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_SR, legacy,
				       ETHTOOL_LINK_MODE_10000baseKR_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_ER,
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_ER, legacy,
				       ETHTOOL_LINK_MODE_10000baseKR_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_40GBASE_SR4,
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_40GBASE_SR4, legacy,
				       ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_40GBASE_LR4,
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_40GBASE_LR4, legacy,
				       ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_50GBASE_SR2,
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_50GBASE_SR2, legacy,
				       ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_100GBASE_CR4,
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_100GBASE_CR4, legacy,
				       ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_100GBASE_SR4,
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_100GBASE_SR4, legacy,
				       ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_100GBASE_KR4,
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_100GBASE_KR4, legacy,
				       ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_100GBASE_LR4,
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_100GBASE_LR4, legacy,
				       ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_T,
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_T, legacy,
				       ETHTOOL_LINK_MODE_10000baseT_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_25GBASE_CR,
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_25GBASE_CR, legacy,
				       ETHTOOL_LINK_MODE_25000baseCR_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_25GBASE_KR,
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_25GBASE_KR, legacy,
				       ETHTOOL_LINK_MODE_25000baseKR_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_25GBASE_SR,
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_25GBASE_SR, legacy,
				       ETHTOOL_LINK_MODE_25000baseSR_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_50GBASE_CR2,
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_50GBASE_CR2, legacy,
				       ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_50GBASE_KR2,
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_50GBASE_KR2, legacy,
				       ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_SGMII_100M, ext,
				       ETHTOOL_LINK_MODE_100baseT_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_1000BASE_X_SGMII, ext,
				       ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
				       ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
				       ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_5GBASE_R, ext,
				       ETHTOOL_LINK_MODE_5000baseT_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_XFI_XAUI_1, ext,
				       ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
				       ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
				       ETHTOOL_LINK_MODE_10000baseR_FEC_BIT,
				       ETHTOOL_LINK_MODE_10000baseCR_Full_BIT,
				       ETHTOOL_LINK_MODE_10000baseSR_Full_BIT,
				       ETHTOOL_LINK_MODE_10000baseLR_Full_BIT,
				       ETHTOOL_LINK_MODE_10000baseER_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_40GBASE_XLAUI_4_XLPPI_4, ext,
				       ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
				       ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT,
				       ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT,
				       ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_25GAUI_1_25GBASE_CR_KR, ext,
				       ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
				       ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
				       ETHTOOL_LINK_MODE_25000baseSR_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_50GAUI_2_LAUI_2_50GBASE_CR2_KR2,
				       ext,
				       ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT,
				       ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT,
				       ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_50GAUI_1_LAUI_1_50GBASE_CR_KR, ext,
				       ETHTOOL_LINK_MODE_50000baseKR_Full_BIT,
				       ETHTOOL_LINK_MODE_50000baseSR_Full_BIT,
				       ETHTOOL_LINK_MODE_50000baseCR_Full_BIT,
				       ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT,
				       ETHTOOL_LINK_MODE_50000baseDR_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_CAUI_4_100GBASE_CR4_KR4, ext,
				       ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
				       ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT,
				       ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
				       ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_100GAUI_2_100GBASE_CR2_KR2, ext,
				       ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT,
				       ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT,
				       ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT,
				       ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT,
				       ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT);
	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_200GAUI_4_200GBASE_CR4_KR4, ext,
				       ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT,
				       ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT,
				       ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT,
				       ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT,
				       ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT);
}

static void mlx5e_ethtool_get_speed_arr(struct mlx5_core_dev *mdev,
					struct ptys2ethtool_config **arr,
					u32 *size)
{
	bool ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet);

	*arr = ext ? ptys2ext_ethtool_table : ptys2legacy_ethtool_table;
	*size = ext ? ARRAY_SIZE(ptys2ext_ethtool_table) :
		      ARRAY_SIZE(ptys2legacy_ethtool_table);
}

typedef int (*mlx5e_pflag_handler)(struct net_device *netdev, bool enable);
@@ -298,11 +369,7 @@ int mlx5e_ethtool_set_ringparam(struct mlx5e_priv *priv,
		goto unlock;
	}

	err = mlx5e_open_channels(priv, &new_channels);
	if (err)
		goto unlock;

	mlx5e_switch_priv_channels(priv, &new_channels, NULL);
	err = mlx5e_safe_switch_channels(priv, &new_channels, NULL);

unlock:
	mutex_unlock(&priv->state_lock);
@@ -360,11 +427,6 @@ int mlx5e_ethtool_set_channels(struct mlx5e_priv *priv,
		goto out;
	}

	/* Create fresh channels with new parameters */
	err = mlx5e_open_channels(priv, &new_channels);
	if (err)
		goto out;

	arfs_enabled = priv->netdev->features & NETIF_F_NTUPLE;
	if (arfs_enabled)
		mlx5e_arfs_disable(priv);
@@ -374,13 +436,14 @@ int mlx5e_ethtool_set_channels(struct mlx5e_priv *priv,
					      MLX5E_INDIR_RQT_SIZE, count);

	/* Switch to new channels, set new parameters and close old ones */
	mlx5e_switch_priv_channels(priv, &new_channels, NULL);
	err = mlx5e_safe_switch_channels(priv, &new_channels, NULL);

	if (arfs_enabled) {
		err = mlx5e_arfs_enable(priv);
		if (err)
		int err2 = mlx5e_arfs_enable(priv);

		if (err2)
			netdev_err(priv->netdev, "%s: mlx5e_arfs_enable failed: %d\n",
				   __func__, err);
				   __func__, err2);
	}

out:
@@ -506,12 +569,7 @@ int mlx5e_ethtool_set_coalesce(struct mlx5e_priv *priv,
		goto out;
	}

	/* open fresh channels with new coal parameters */
	err = mlx5e_open_channels(priv, &new_channels);
	if (err)
		goto out;

	mlx5e_switch_priv_channels(priv, &new_channels, NULL);
	err = mlx5e_safe_switch_channels(priv, &new_channels, NULL);

out:
	mutex_unlock(&priv->state_lock);
@@ -526,27 +584,35 @@ static int mlx5e_set_coalesce(struct net_device *netdev,
	return mlx5e_ethtool_set_coalesce(priv, coal);
}

static void ptys2ethtool_supported_link(unsigned long *supported_modes,
static void ptys2ethtool_supported_link(struct mlx5_core_dev *mdev,
					unsigned long *supported_modes,
					u32 eth_proto_cap)
{
	unsigned long proto_cap = eth_proto_cap;
	struct ptys2ethtool_config *table;
	u32 max_size;
	int proto;

	for_each_set_bit(proto, &proto_cap, MLX5E_LINK_MODES_NUMBER)
	mlx5e_ethtool_get_speed_arr(mdev, &table, &max_size);
	for_each_set_bit(proto, &proto_cap, max_size)
		bitmap_or(supported_modes, supported_modes,
			  ptys2ethtool_table[proto].supported,
			  table[proto].supported,
			  __ETHTOOL_LINK_MODE_MASK_NBITS);
}

static void ptys2ethtool_adver_link(unsigned long *advertising_modes,
static void ptys2ethtool_adver_link(struct mlx5_core_dev *mdev,
				    unsigned long *advertising_modes,
				    u32 eth_proto_cap)
{
	unsigned long proto_cap = eth_proto_cap;
	struct ptys2ethtool_config *table;
	u32 max_size;
	int proto;

	for_each_set_bit(proto, &proto_cap, MLX5E_LINK_MODES_NUMBER)
	mlx5e_ethtool_get_speed_arr(mdev, &table, &max_size);
	for_each_set_bit(proto, &proto_cap, max_size)
		bitmap_or(advertising_modes, advertising_modes,
			  ptys2ethtool_table[proto].advertised,
			  table[proto].advertised,
			  __ETHTOOL_LINK_MODE_MASK_NBITS);
}

@@ -716,22 +782,22 @@ static void get_speed_duplex(struct net_device *netdev,
	link_ksettings->base.duplex = duplex;
}

static void get_supported(u32 eth_proto_cap,
static void get_supported(struct mlx5_core_dev *mdev, u32 eth_proto_cap,
			  struct ethtool_link_ksettings *link_ksettings)
{
	unsigned long *supported = link_ksettings->link_modes.supported;
	ptys2ethtool_supported_link(mdev, supported, eth_proto_cap);

	ptys2ethtool_supported_link(supported, eth_proto_cap);
	ethtool_link_ksettings_add_link_mode(link_ksettings, supported, Pause);
}

static void get_advertising(u32 eth_proto_cap, u8 tx_pause,
			    u8 rx_pause,
static void get_advertising(struct mlx5_core_dev *mdev, u32 eth_proto_cap,
			    u8 tx_pause, u8 rx_pause,
			    struct ethtool_link_ksettings *link_ksettings)
{
	unsigned long *advertising = link_ksettings->link_modes.advertising;
	ptys2ethtool_adver_link(mdev, advertising, eth_proto_cap);

	ptys2ethtool_adver_link(advertising, eth_proto_cap);
	if (rx_pause)
		ethtool_link_ksettings_add_link_mode(link_ksettings, advertising, Pause);
	if (tx_pause ^ rx_pause)
@@ -781,12 +847,12 @@ static u8 get_connector_port(u32 eth_proto, u8 connector_type)
	return PORT_OTHER;
}

static void get_lp_advertising(u32 eth_proto_lp,
static void get_lp_advertising(struct mlx5_core_dev *mdev, u32 eth_proto_lp,
			       struct ethtool_link_ksettings *link_ksettings)
{
	unsigned long *lp_advertising = link_ksettings->link_modes.lp_advertising;

	ptys2ethtool_adver_link(lp_advertising, eth_proto_lp);
	ptys2ethtool_adver_link(mdev, lp_advertising, eth_proto_lp);
}

int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv,
@@ -803,6 +869,7 @@ int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv,
	u8 an_disable_admin;
	u8 an_status;
	u8 connector_type;
	bool ext;
	int err;

	err = mlx5_query_port_ptys(mdev, out, sizeof(out), MLX5_PTYS_EN, 1);
@@ -811,10 +878,13 @@ int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv,
			   __func__, err);
		goto err_query_regs;
	}

	eth_proto_cap    = MLX5_GET(ptys_reg, out, eth_proto_capability);
	eth_proto_admin  = MLX5_GET(ptys_reg, out, eth_proto_admin);
	eth_proto_oper   = MLX5_GET(ptys_reg, out, eth_proto_oper);
	ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet);
	eth_proto_cap    = MLX5_GET_ETH_PROTO(ptys_reg, out, ext,
					      eth_proto_capability);
	eth_proto_admin  = MLX5_GET_ETH_PROTO(ptys_reg, out, ext,
					      eth_proto_admin);
	eth_proto_oper   = MLX5_GET_ETH_PROTO(ptys_reg, out, ext,
					      eth_proto_oper);
	eth_proto_lp	    = MLX5_GET(ptys_reg, out, eth_proto_lp_advertise);
	an_disable_admin    = MLX5_GET(ptys_reg, out, an_disable_admin);
	an_status	    = MLX5_GET(ptys_reg, out, an_status);
@@ -825,8 +895,8 @@ int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv,
	ethtool_link_ksettings_zero_link_mode(link_ksettings, supported);
	ethtool_link_ksettings_zero_link_mode(link_ksettings, advertising);

	get_supported(eth_proto_cap, link_ksettings);
	get_advertising(eth_proto_admin, tx_pause, rx_pause, link_ksettings);
	get_supported(mdev, eth_proto_cap, link_ksettings);
	get_advertising(mdev, eth_proto_admin, tx_pause, rx_pause, link_ksettings);
	get_speed_duplex(priv->netdev, eth_proto_oper, link_ksettings);

	eth_proto_oper = eth_proto_oper ? eth_proto_oper : eth_proto_cap;
@@ -835,7 +905,7 @@ int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv,
						       connector_type);
	ptys2ethtool_supported_advertised_port(link_ksettings, eth_proto_admin,
					       connector_type);
	get_lp_advertising(eth_proto_lp, link_ksettings);
	get_lp_advertising(mdev, eth_proto_lp, link_ksettings);

	if (an_status == MLX5_AN_COMPLETE)
		ethtool_link_ksettings_add_link_mode(link_ksettings,
@@ -874,7 +944,9 @@ static u32 mlx5e_ethtool2ptys_adver_link(const unsigned long *link_modes)
	u32 i, ptys_modes = 0;

	for (i = 0; i < MLX5E_LINK_MODES_NUMBER; ++i) {
		if (bitmap_intersects(ptys2ethtool_table[i].advertised,
		if (*ptys2legacy_ethtool_table[i].advertised == 0)
			continue;
		if (bitmap_intersects(ptys2legacy_ethtool_table[i].advertised,
				      link_modes,
				      __ETHTOOL_LINK_MODE_MASK_NBITS))
			ptys_modes |= MLX5E_PROT_MASK(i);
@@ -883,6 +955,25 @@ static u32 mlx5e_ethtool2ptys_adver_link(const unsigned long *link_modes)
	return ptys_modes;
}

static u32 mlx5e_ethtool2ptys_ext_adver_link(const unsigned long *link_modes)
{
	u32 i, ptys_modes = 0;
	unsigned long modes[2];

	for (i = 0; i < MLX5E_EXT_LINK_MODES_NUMBER; ++i) {
		if (*ptys2ext_ethtool_table[i].advertised == 0)
			continue;
		memset(modes, 0, sizeof(modes));
		bitmap_and(modes, ptys2ext_ethtool_table[i].advertised,
			   link_modes, __ETHTOOL_LINK_MODE_MASK_NBITS);

		if (modes[0] == ptys2ext_ethtool_table[i].advertised[0] &&
		    modes[1] == ptys2ext_ethtool_table[i].advertised[1])
			ptys_modes |= MLX5E_PROT_MASK(i);
	}
	return ptys_modes;
}

int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv,
				     const struct ethtool_link_ksettings *link_ksettings)
{
@@ -890,6 +981,8 @@ int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv,
	struct mlx5e_port_eth_proto eproto;
	bool an_changes = false;
	u8 an_disable_admin;
	bool ext_supported;
	bool ext_requested;
	u8 an_disable_cap;
	bool an_disable;
	u32 link_modes;
@@ -897,18 +990,31 @@ int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv,
	u32 speed;
	int err;

	speed = link_ksettings->base.speed;
	u32 (*ethtool2ptys_adver_func)(const unsigned long *adver);

	link_modes = link_ksettings->base.autoneg == AUTONEG_ENABLE ?
		mlx5e_ethtool2ptys_adver_link(link_ksettings->link_modes.advertising) :
		mlx5e_port_speed2linkmodes(mdev, speed);
#define MLX5E_PTYS_EXT ((1ULL << ETHTOOL_LINK_MODE_50000baseKR_Full_BIT) - 1)

	ext_requested = (link_ksettings->link_modes.advertising[0] >
			MLX5E_PTYS_EXT);
	ext_supported = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet);

	/*when ptys_extended_ethernet is set legacy link modes are deprecated */
	if (ext_requested != ext_supported)
		return -EPROTONOSUPPORT;

	err = mlx5_port_query_eth_proto(mdev, 1, false, &eproto);
	speed = link_ksettings->base.speed;
	ethtool2ptys_adver_func = ext_requested ?
				  mlx5e_ethtool2ptys_ext_adver_link :
				  mlx5e_ethtool2ptys_adver_link;
	err = mlx5_port_query_eth_proto(mdev, 1, ext_supported, &eproto);
	if (err) {
		netdev_err(priv->netdev, "%s: query port eth proto failed: %d\n",
			   __func__, err);
		goto out;
	}
	link_modes = link_ksettings->base.autoneg == AUTONEG_ENABLE ?
		ethtool2ptys_adver_func(link_ksettings->link_modes.advertising) :
		mlx5e_port_speed2linkmodes(mdev, speed);

	link_modes = link_modes & eproto.cap;
	if (!link_modes) {
@@ -928,7 +1034,7 @@ int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv,
	if (!an_changes && link_modes == eproto.admin)
		goto out;

	mlx5_port_set_eth_ptys(mdev, an_disable, link_modes, false);
	mlx5_port_set_eth_ptys(mdev, an_disable, link_modes, ext_supported);
	mlx5_toggle_port_link(mdev);

out:
@@ -1516,7 +1622,6 @@ static int set_pflag_cqe_based_moder(struct net_device *netdev, bool enable,
	struct mlx5e_channels new_channels = {};
	bool mode_changed;
	u8 cq_period_mode, current_cq_period_mode;
	int err = 0;

	cq_period_mode = enable ?
		MLX5_CQ_PERIOD_MODE_START_FROM_CQE :
@@ -1544,12 +1649,7 @@ static int set_pflag_cqe_based_moder(struct net_device *netdev, bool enable,
		return 0;
	}

	err = mlx5e_open_channels(priv, &new_channels);
	if (err)
		return err;

	mlx5e_switch_priv_channels(priv, &new_channels, NULL);
	return 0;
	return mlx5e_safe_switch_channels(priv, &new_channels, NULL);
}

static int set_pflag_tx_cqe_based_moder(struct net_device *netdev, bool enable)
@@ -1582,11 +1682,10 @@ int mlx5e_modify_rx_cqe_compression_locked(struct mlx5e_priv *priv, bool new_val
		return 0;
	}

	err = mlx5e_open_channels(priv, &new_channels);
	err = mlx5e_safe_switch_channels(priv, &new_channels, NULL);
	if (err)
		return err;

	mlx5e_switch_priv_channels(priv, &new_channels, NULL);
	mlx5e_dbg(DRV, priv, "MLX5E: RxCqeCmprss was turned %s\n",
		  MLX5E_GET_PFLAG(&priv->channels.params,
				  MLX5E_PFLAG_RX_CQE_COMPRESS) ? "ON" : "OFF");
@@ -1619,7 +1718,6 @@ static int set_pflag_rx_striding_rq(struct net_device *netdev, bool enable)
	struct mlx5e_priv *priv = netdev_priv(netdev);
	struct mlx5_core_dev *mdev = priv->mdev;
	struct mlx5e_channels new_channels = {};
	int err;

	if (enable) {
		if (!mlx5e_check_fragmented_striding_rq_cap(mdev))
@@ -1641,12 +1739,7 @@ static int set_pflag_rx_striding_rq(struct net_device *netdev, bool enable)
		return 0;
	}

	err = mlx5e_open_channels(priv, &new_channels);
	if (err)
		return err;

	mlx5e_switch_priv_channels(priv, &new_channels, NULL);
	return 0;
	return mlx5e_safe_switch_channels(priv, &new_channels, NULL);
}

static int set_pflag_rx_no_csum_complete(struct net_device *netdev, bool enable)
@@ -1689,12 +1782,8 @@ static int set_pflag_xdp_tx_mpwqe(struct net_device *netdev, bool enable)
		return 0;
	}

	err = mlx5e_open_channels(priv, &new_channels);
	if (err)
	err = mlx5e_safe_switch_channels(priv, &new_channels, NULL);
	return err;

	mlx5e_switch_priv_channels(priv, &new_channels, NULL);
	return 0;
}

static const struct pflag_desc mlx5e_priv_flags[MLX5E_NUM_PFLAGS] = {
+21 −12
Original line number Diff line number Diff line
@@ -2885,13 +2885,14 @@ void mlx5e_deactivate_priv_channels(struct mlx5e_priv *priv)
	mlx5e_deactivate_channels(&priv->channels);
}

void mlx5e_switch_priv_channels(struct mlx5e_priv *priv,
static void mlx5e_switch_priv_channels(struct mlx5e_priv *priv,
				       struct mlx5e_channels *new_chs,
				       mlx5e_fp_hw_modify hw_modify)
{
	struct net_device *netdev = priv->netdev;
	int new_num_txqs;
	int carrier_ok;

	new_num_txqs = new_chs->num * new_chs->params.num_tc;

	carrier_ok = netif_carrier_ok(netdev);
@@ -2917,6 +2918,20 @@ void mlx5e_switch_priv_channels(struct mlx5e_priv *priv,
		netif_carrier_on(netdev);
}

int mlx5e_safe_switch_channels(struct mlx5e_priv *priv,
			       struct mlx5e_channels *new_chs,
			       mlx5e_fp_hw_modify hw_modify)
{
	int err;

	err = mlx5e_open_channels(priv, new_chs);
	if (err)
		return err;

	mlx5e_switch_priv_channels(priv, new_chs, hw_modify);
	return 0;
}

void mlx5e_timestamp_init(struct mlx5e_priv *priv)
{
	priv->tstamp.tx_type   = HWTSTAMP_TX_OFF;
@@ -3333,13 +3348,12 @@ static int mlx5e_setup_tc_mqprio(struct net_device *netdev,
		goto out;
	}

	err = mlx5e_open_channels(priv, &new_channels);
	err = mlx5e_safe_switch_channels(priv, &new_channels, NULL);
	if (err)
		goto out;

	priv->max_opened_tc = max_t(u8, priv->max_opened_tc,
				    new_channels.params.num_tc);
	mlx5e_switch_priv_channels(priv, &new_channels, NULL);
out:
	mutex_unlock(&priv->state_lock);
	return err;
@@ -3549,11 +3563,7 @@ static int set_feature_lro(struct net_device *netdev, bool enable)
		goto out;
	}

	err = mlx5e_open_channels(priv, &new_channels);
	if (err)
		goto out;

	mlx5e_switch_priv_channels(priv, &new_channels, mlx5e_modify_tirs_lro);
	err = mlx5e_safe_switch_channels(priv, &new_channels, mlx5e_modify_tirs_lro);
out:
	mutex_unlock(&priv->state_lock);
	return err;
@@ -3771,11 +3781,10 @@ int mlx5e_change_mtu(struct net_device *netdev, int new_mtu,
		goto out;
	}

	err = mlx5e_open_channels(priv, &new_channels);
	err = mlx5e_safe_switch_channels(priv, &new_channels, set_mtu_cb);
	if (err)
		goto out;

	mlx5e_switch_priv_channels(priv, &new_channels, set_mtu_cb);
	netdev->mtu = new_channels.params.sw_mtu;

out:
Loading