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

Commit bdfc028d authored by Tariq Toukan's avatar Tariq Toukan Committed by David S. Miller
Browse files

net/mlx5e: Fix ethtool RX hash func configuration change



We should modify TIRs explicitly to apply the new RSS configuration.
The light ndo close/open calls do not "refresh" them.

Fixes: 2d75b2bc ('net/mlx5e: Add ethtool RSS configuration options')
Signed-off-by: default avatarTariq Toukan <tariqt@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0ad9b204
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -447,6 +447,8 @@ enum mlx5e_traffic_types {
	MLX5E_NUM_TT,
};

#define IS_HASHING_TT(tt) (tt != MLX5E_TT_ANY)

enum mlx5e_rqt_ix {
	MLX5E_INDIRECTION_RQT,
	MLX5E_SINGLE_RQ_RQT,
@@ -613,6 +615,7 @@ void mlx5e_enable_vlan_filter(struct mlx5e_priv *priv);
void mlx5e_disable_vlan_filter(struct mlx5e_priv *priv);

int mlx5e_redirect_rqt(struct mlx5e_priv *priv, enum mlx5e_rqt_ix rqt_ix);
void mlx5e_build_tir_ctx_hash(void *tirc, struct mlx5e_priv *priv);

int mlx5e_open_locked(struct net_device *netdev);
int mlx5e_close_locked(struct net_device *netdev);
+24 −10
Original line number Diff line number Diff line
@@ -703,18 +703,36 @@ static int mlx5e_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
	return 0;
}

static void mlx5e_modify_tirs_hash(struct mlx5e_priv *priv, void *in, int inlen)
{
	struct mlx5_core_dev *mdev = priv->mdev;
	void *tirc = MLX5_ADDR_OF(modify_tir_in, in, ctx);
	int i;

	MLX5_SET(modify_tir_in, in, bitmask.hash, 1);
	mlx5e_build_tir_ctx_hash(tirc, priv);

	for (i = 0; i < MLX5E_NUM_TT; i++)
		if (IS_HASHING_TT(i))
			mlx5_core_modify_tir(mdev, priv->tirn[i], in, inlen);
}

static int mlx5e_set_rxfh(struct net_device *dev, const u32 *indir,
			  const u8 *key, const u8 hfunc)
{
	struct mlx5e_priv *priv = netdev_priv(dev);
	bool close_open;
	int err = 0;
	int inlen = MLX5_ST_SZ_BYTES(modify_tir_in);
	void *in;

	if ((hfunc != ETH_RSS_HASH_NO_CHANGE) &&
	    (hfunc != ETH_RSS_HASH_XOR) &&
	    (hfunc != ETH_RSS_HASH_TOP))
		return -EINVAL;

	in = mlx5_vzalloc(inlen);
	if (!in)
		return -ENOMEM;

	mutex_lock(&priv->state_lock);

	if (indir) {
@@ -723,11 +741,6 @@ static int mlx5e_set_rxfh(struct net_device *dev, const u32 *indir,
		mlx5e_redirect_rqt(priv, MLX5E_INDIRECTION_RQT);
	}

	close_open = (key || (hfunc != ETH_RSS_HASH_NO_CHANGE)) &&
		     test_bit(MLX5E_STATE_OPENED, &priv->state);
	if (close_open)
		mlx5e_close_locked(dev);

	if (key)
		memcpy(priv->params.toeplitz_hash_key, key,
		       sizeof(priv->params.toeplitz_hash_key));
@@ -735,12 +748,13 @@ static int mlx5e_set_rxfh(struct net_device *dev, const u32 *indir,
	if (hfunc != ETH_RSS_HASH_NO_CHANGE)
		priv->params.rss_hfunc = hfunc;

	if (close_open)
		err = mlx5e_open_locked(priv->netdev);
	mlx5e_modify_tirs_hash(priv, in, inlen);

	mutex_unlock(&priv->state_lock);

	return err;
	kvfree(in);

	return 0;
}

static int mlx5e_get_rxnfc(struct net_device *netdev,
+16 −11
Original line number Diff line number Diff line
@@ -1317,6 +1317,21 @@ static void mlx5e_build_tir_ctx_lro(void *tirc, struct mlx5e_priv *priv)
			      lro_timer_supported_periods[2]));
}

void mlx5e_build_tir_ctx_hash(void *tirc, struct mlx5e_priv *priv)
{
	MLX5_SET(tirc, tirc, rx_hash_fn,
		 mlx5e_rx_hash_fn(priv->params.rss_hfunc));
	if (priv->params.rss_hfunc == ETH_RSS_HASH_TOP) {
		void *rss_key = MLX5_ADDR_OF(tirc, tirc,
					     rx_hash_toeplitz_key);
		size_t len = MLX5_FLD_SZ_BYTES(tirc,
					       rx_hash_toeplitz_key);

		MLX5_SET(tirc, tirc, rx_hash_symmetric, 1);
		memcpy(rss_key, priv->params.toeplitz_hash_key, len);
	}
}

static int mlx5e_modify_tirs_lro(struct mlx5e_priv *priv)
{
	struct mlx5_core_dev *mdev = priv->mdev;
@@ -1677,17 +1692,7 @@ static void mlx5e_build_tir_ctx(struct mlx5e_priv *priv, u32 *tirc, int tt)
	default:
		MLX5_SET(tirc, tirc, indirect_table,
			 priv->rqtn[MLX5E_INDIRECTION_RQT]);
		MLX5_SET(tirc, tirc, rx_hash_fn,
			 mlx5e_rx_hash_fn(priv->params.rss_hfunc));
		if (priv->params.rss_hfunc == ETH_RSS_HASH_TOP) {
			void *rss_key = MLX5_ADDR_OF(tirc, tirc,
						     rx_hash_toeplitz_key);
			size_t len = MLX5_FLD_SZ_BYTES(tirc,
						       rx_hash_toeplitz_key);

			MLX5_SET(tirc, tirc, rx_hash_symmetric, 1);
			memcpy(rss_key, priv->params.toeplitz_hash_key, len);
		}
		mlx5e_build_tir_ctx_hash(tirc, priv);
		break;
	}

+3 −1
Original line number Diff line number Diff line
@@ -4245,7 +4245,9 @@ struct mlx5_ifc_modify_tir_bitmask_bits {

	u8         reserved_at_20[0x1b];
	u8         self_lb_en[0x1];
	u8         reserved_at_3c[0x3];
	u8         reserved_at_3c[0x1];
	u8         hash[0x1];
	u8         reserved_at_3e[0x1];
	u8         lro[0x1];
};