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

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
...@@ -272,9 +272,10 @@ struct mlx5e_params { ...@@ -272,9 +272,10 @@ struct mlx5e_params {
u16 min_rx_wqes; u16 min_rx_wqes;
bool lro_en; bool lro_en;
u32 lro_wqe_sz; u32 lro_wqe_sz;
u8 rss_hfunc;
u16 tx_max_inline; u16 tx_max_inline;
u8 rss_hfunc;
u8 toeplitz_hash_key[40]; u8 toeplitz_hash_key[40];
u32 indirection_rqt[MLX5E_INDIR_RQT_SIZE];
}; };
enum { enum {
...@@ -571,6 +572,8 @@ int mlx5e_vlan_rx_kill_vid(struct net_device *dev, __always_unused __be16 proto, ...@@ -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_enable_vlan_filter(struct mlx5e_priv *priv);
void mlx5e_disable_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_open_locked(struct net_device *netdev);
int mlx5e_close_locked(struct net_device *netdev); int mlx5e_close_locked(struct net_device *netdev);
......
...@@ -684,11 +684,31 @@ static int mlx5e_set_settings(struct net_device *netdev, ...@@ -684,11 +684,31 @@ static int mlx5e_set_settings(struct net_device *netdev,
return err; 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, static int mlx5e_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
u8 *hfunc) u8 *hfunc)
{ {
struct mlx5e_priv *priv = netdev_priv(netdev); 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) if (hfunc)
*hfunc = priv->params.rss_hfunc; *hfunc = priv->params.rss_hfunc;
...@@ -699,28 +719,60 @@ static int mlx5e_set_rxfh(struct net_device *dev, const u32 *indir, ...@@ -699,28 +719,60 @@ static int mlx5e_set_rxfh(struct net_device *dev, const u32 *indir,
const u8 *key, const u8 hfunc) const u8 *key, const u8 hfunc)
{ {
struct mlx5e_priv *priv = netdev_priv(dev); struct mlx5e_priv *priv = netdev_priv(dev);
bool close_open;
int err = 0; int err = 0;
if (hfunc == ETH_RSS_HASH_NO_CHANGE) if ((hfunc != ETH_RSS_HASH_NO_CHANGE) &&
return 0; (hfunc != ETH_RSS_HASH_XOR) &&
if ((hfunc != ETH_RSS_HASH_XOR) &&
(hfunc != ETH_RSS_HASH_TOP)) (hfunc != ETH_RSS_HASH_TOP))
return -EINVAL; return -EINVAL;
mutex_lock(&priv->state_lock); mutex_lock(&priv->state_lock);
priv->params.rss_hfunc = hfunc; if (indir) {
if (test_bit(MLX5E_STATE_OPENED, &priv->state)) { memcpy(priv->params.indirection_rqt, indir,
mlx5e_close_locked(dev); sizeof(priv->params.indirection_rqt));
err = mlx5e_open_locked(dev); 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); mutex_unlock(&priv->state_lock);
return err; 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, static int mlx5e_get_tunable(struct net_device *dev,
const struct ethtool_tunable *tuna, const struct ethtool_tunable *tuna,
void *data) void *data)
...@@ -793,8 +845,11 @@ const struct ethtool_ops mlx5e_ethtool_ops = { ...@@ -793,8 +845,11 @@ const struct ethtool_ops mlx5e_ethtool_ops = {
.set_coalesce = mlx5e_set_coalesce, .set_coalesce = mlx5e_set_coalesce,
.get_settings = mlx5e_get_settings, .get_settings = mlx5e_get_settings,
.set_settings = mlx5e_set_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, .get_rxfh = mlx5e_get_rxfh,
.set_rxfh = mlx5e_set_rxfh, .set_rxfh = mlx5e_set_rxfh,
.get_rxnfc = mlx5e_get_rxnfc,
.get_tunable = mlx5e_get_tunable, .get_tunable = mlx5e_get_tunable,
.set_tunable = mlx5e_set_tunable, .set_tunable = mlx5e_set_tunable,
}; };
...@@ -1184,6 +1184,7 @@ static void mlx5e_fill_indir_rqt_rqns(struct mlx5e_priv *priv, void *rqtc) ...@@ -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) if (priv->params.rss_hfunc == ETH_RSS_HASH_XOR)
ix = mlx5e_bits_invert(i, MLX5E_LOG_INDIR_RQT_SIZE); ix = mlx5e_bits_invert(i, MLX5E_LOG_INDIR_RQT_SIZE);
ix = priv->params.indirection_rqt[ix];
ix = ix % priv->params.num_channels; ix = ix % priv->params.num_channels;
MLX5_SET(rqtc, rqtc, rq_num[i], MLX5_SET(rqtc, rqtc, rq_num[i],
test_bit(MLX5E_STATE_OPENED, &priv->state) ? 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) ...@@ -1242,7 +1243,7 @@ static int mlx5e_create_rqt(struct mlx5e_priv *priv, enum mlx5e_rqt_ix rqt_ix)
return err; 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; struct mlx5_core_dev *mdev = priv->mdev;
u32 *in; u32 *in;
...@@ -1912,6 +1913,7 @@ static void mlx5e_build_netdev_priv(struct mlx5_core_dev *mdev, ...@@ -1912,6 +1913,7 @@ static void mlx5e_build_netdev_priv(struct mlx5_core_dev *mdev,
int num_channels) int num_channels)
{ {
struct mlx5e_priv *priv = netdev_priv(netdev); struct mlx5e_priv *priv = netdev_priv(netdev);
int i;
priv->params.log_sq_size = priv->params.log_sq_size =
MLX5E_PARAMS_DEFAULT_LOG_SQ_SIZE; MLX5E_PARAMS_DEFAULT_LOG_SQ_SIZE;
...@@ -1935,6 +1937,9 @@ static void mlx5e_build_netdev_priv(struct mlx5_core_dev *mdev, ...@@ -1935,6 +1937,9 @@ static void mlx5e_build_netdev_priv(struct mlx5_core_dev *mdev,
netdev_rss_key_fill(priv->params.toeplitz_hash_key, netdev_rss_key_fill(priv->params.toeplitz_hash_key,
sizeof(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_en = false && !!MLX5_CAP_ETH(priv->mdev, lro_cap);
priv->params.lro_wqe_sz = priv->params.lro_wqe_sz =
MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ; MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment