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

Commit 2d75b2bc authored by Achiad Shochat's avatar Achiad Shochat Committed by David S. Miller
Browse files

net/mlx5e: Add ethtool RSS configuration options



- get_rxfh_key_size
- get_rxfh_indir_size
- get/set_rxfh indirection table and RSS Toeplitz hash key
- get_rxnfc

Signed-off-by: default avatarAchiad Shochat <achiad@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 936896e9
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -272,9 +272,10 @@ struct mlx5e_params {
	u16 min_rx_wqes;
	bool lro_en;
	u32 lro_wqe_sz;
	u8  rss_hfunc;
	u16 tx_max_inline;
	u8  rss_hfunc;
	u8  toeplitz_hash_key[40];
	u32 indirection_rqt[MLX5E_INDIR_RQT_SIZE];
};

enum {
@@ -571,6 +572,8 @@ int mlx5e_vlan_rx_kill_vid(struct net_device *dev, __always_unused __be16 proto,
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);

int mlx5e_open_locked(struct net_device *netdev);
int mlx5e_close_locked(struct net_device *netdev);

+63 −8
Original line number Diff line number Diff line
@@ -684,11 +684,31 @@ out:
	return err;
}

static u32 mlx5e_get_rxfh_key_size(struct net_device *netdev)
{
	struct mlx5e_priv *priv = netdev_priv(netdev);

	return sizeof(priv->params.toeplitz_hash_key);
}

static u32 mlx5e_get_rxfh_indir_size(struct net_device *netdev)
{
	return MLX5E_INDIR_RQT_SIZE;
}

static int mlx5e_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
			  u8 *hfunc)
{
	struct mlx5e_priv *priv = netdev_priv(netdev);

	if (indir)
		memcpy(indir, priv->params.indirection_rqt,
		       sizeof(priv->params.indirection_rqt));

	if (key)
		memcpy(key, priv->params.toeplitz_hash_key,
		       sizeof(priv->params.toeplitz_hash_key));

	if (hfunc)
		*hfunc = priv->params.rss_hfunc;

@@ -699,28 +719,60 @@ 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;

	if (hfunc == ETH_RSS_HASH_NO_CHANGE)
		return 0;

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

	mutex_lock(&priv->state_lock);

	priv->params.rss_hfunc = hfunc;
	if (test_bit(MLX5E_STATE_OPENED, &priv->state)) {
		mlx5e_close_locked(dev);
		err = mlx5e_open_locked(dev);
	if (indir) {
		memcpy(priv->params.indirection_rqt, indir,
		       sizeof(priv->params.indirection_rqt));
		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));

	if (hfunc != ETH_RSS_HASH_NO_CHANGE)
		priv->params.rss_hfunc = hfunc;

	if (close_open)
		err = mlx5e_open_locked(priv->netdev);

	mutex_unlock(&priv->state_lock);

	return err;
}

static int mlx5e_get_rxnfc(struct net_device *netdev,
			   struct ethtool_rxnfc *info, u32 *rule_locs)
{
	struct mlx5e_priv *priv = netdev_priv(netdev);
	int err = 0;

	switch (info->cmd) {
	case ETHTOOL_GRXRINGS:
		info->data = priv->params.num_channels;
		break;
	default:
		err = -EOPNOTSUPP;
		break;
	}

	return err;
}

static int mlx5e_get_tunable(struct net_device *dev,
			     const struct ethtool_tunable *tuna,
			     void *data)
@@ -793,8 +845,11 @@ const struct ethtool_ops mlx5e_ethtool_ops = {
	.set_coalesce      = mlx5e_set_coalesce,
	.get_settings      = mlx5e_get_settings,
	.set_settings      = mlx5e_set_settings,
	.get_rxfh_key_size   = mlx5e_get_rxfh_key_size,
	.get_rxfh_indir_size = mlx5e_get_rxfh_indir_size,
	.get_rxfh          = mlx5e_get_rxfh,
	.set_rxfh          = mlx5e_set_rxfh,
	.get_rxnfc         = mlx5e_get_rxnfc,
	.get_tunable       = mlx5e_get_tunable,
	.set_tunable       = mlx5e_set_tunable,
};
+6 −1
Original line number Diff line number Diff line
@@ -1184,6 +1184,7 @@ static void mlx5e_fill_indir_rqt_rqns(struct mlx5e_priv *priv, void *rqtc)
		if (priv->params.rss_hfunc == ETH_RSS_HASH_XOR)
			ix = mlx5e_bits_invert(i, MLX5E_LOG_INDIR_RQT_SIZE);

		ix = priv->params.indirection_rqt[ix];
		ix = ix % priv->params.num_channels;
		MLX5_SET(rqtc, rqtc, rq_num[i],
			 test_bit(MLX5E_STATE_OPENED, &priv->state) ?
@@ -1242,7 +1243,7 @@ static int mlx5e_create_rqt(struct mlx5e_priv *priv, enum mlx5e_rqt_ix rqt_ix)
	return err;
}

static int mlx5e_redirect_rqt(struct mlx5e_priv *priv, enum mlx5e_rqt_ix rqt_ix)
int mlx5e_redirect_rqt(struct mlx5e_priv *priv, enum mlx5e_rqt_ix rqt_ix)
{
	struct mlx5_core_dev *mdev = priv->mdev;
	u32 *in;
@@ -1912,6 +1913,7 @@ static void mlx5e_build_netdev_priv(struct mlx5_core_dev *mdev,
				    int num_channels)
{
	struct mlx5e_priv *priv = netdev_priv(netdev);
	int i;

	priv->params.log_sq_size           =
		MLX5E_PARAMS_DEFAULT_LOG_SQ_SIZE;
@@ -1935,6 +1937,9 @@ static void mlx5e_build_netdev_priv(struct mlx5_core_dev *mdev,
	netdev_rss_key_fill(priv->params.toeplitz_hash_key,
			    sizeof(priv->params.toeplitz_hash_key));

	for (i = 0; i < MLX5E_INDIR_RQT_SIZE; i++)
		priv->params.indirection_rqt[i] = i % num_channels;

	priv->params.lro_en = false && !!MLX5_CAP_ETH(priv->mdev, lro_cap);
	priv->params.lro_wqe_sz            =
		MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ;