Skip to content

Commit

Permalink
net/mlx4_en: Support for configurable RSS hash function
Browse files Browse the repository at this point in the history
The ConnectX HW is capable of using one of the following hash functions:
Toeplitz and an XOR hash function. This patch extends the implementation
of the mlx4_en driver set/get_rxfh callbacks to support getting and
setting the RSS hash function used by the device.

Signed-off-by: Eyal Perry <eyalpe@mellanox.com>
Signed-off-by: Amir Vadai <amirv@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Eyal Perry authored and David S. Miller committed Dec 9, 2014
1 parent 892311f commit 947cbb0
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 7 deletions.
34 changes: 29 additions & 5 deletions drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -978,6 +978,27 @@ static u32 mlx4_en_get_rxfh_key_size(struct net_device *netdev)
return MLX4_EN_RSS_KEY_SIZE;
}

static int mlx4_en_check_rxfh_func(struct net_device *dev, u8 hfunc)
{
struct mlx4_en_priv *priv = netdev_priv(dev);

/* check if requested function is supported by the device */
if ((hfunc == ETH_RSS_HASH_TOP &&
!(priv->mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_RSS_TOP)) ||
(hfunc == ETH_RSS_HASH_XOR &&
!(priv->mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_RSS_XOR)))
return -EINVAL;

priv->rss_hash_fn = hfunc;
if (hfunc == ETH_RSS_HASH_TOP && !(dev->features & NETIF_F_RXHASH))
en_warn(priv,
"Toeplitz hash function should be used in conjunction with RX hashing for optimal performance\n");
if (hfunc == ETH_RSS_HASH_XOR && (dev->features & NETIF_F_RXHASH))
en_warn(priv,
"Enabling both XOR Hash function and RX Hashing can limit RPS functionality\n");
return 0;
}

static int mlx4_en_get_rxfh(struct net_device *dev, u32 *ring_index, u8 *key,
u8 *hfunc)
{
Expand All @@ -999,7 +1020,7 @@ static int mlx4_en_get_rxfh(struct net_device *dev, u32 *ring_index, u8 *key,
if (key)
memcpy(key, priv->rss_key, MLX4_EN_RSS_KEY_SIZE);
if (hfunc)
*hfunc = ETH_RSS_HASH_TOP;
*hfunc = priv->rss_hash_fn;
return err;
}

Expand All @@ -1013,10 +1034,6 @@ static int mlx4_en_set_rxfh(struct net_device *dev, const u32 *ring_index,
int i;
int rss_rings = 0;

/* We do not allow change in unsupported parameters */
if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
return -EOPNOTSUPP;

/* Calculate RSS table size and make sure flows are spread evenly
* between rings
*/
Expand All @@ -1037,6 +1054,12 @@ static int mlx4_en_set_rxfh(struct net_device *dev, const u32 *ring_index,
if (!is_power_of_2(rss_rings))
return -EINVAL;

if (hfunc != ETH_RSS_HASH_NO_CHANGE) {
err = mlx4_en_check_rxfh_func(dev, hfunc);
if (err)
return err;
}

mutex_lock(&mdev->state_lock);
if (priv->port_up) {
port_up = 1;
Expand All @@ -1047,6 +1070,7 @@ static int mlx4_en_set_rxfh(struct net_device *dev, const u32 *ring_index,
priv->prof->rss_rings = rss_rings;
if (key)
memcpy(priv->rss_key, key, MLX4_EN_RSS_KEY_SIZE);

if (port_up) {
err = mlx4_en_start_port(dev);
if (err)
Expand Down
11 changes: 11 additions & 0 deletions drivers/net/ethernet/mellanox/mlx4/en_netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -2608,6 +2608,17 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
if (mdev->dev->caps.steering_mode != MLX4_STEERING_MODE_A0)
dev->priv_flags |= IFF_UNICAST_FLT;

/* Setting a default hash function value */
if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_RSS_TOP) {
priv->rss_hash_fn = ETH_RSS_HASH_TOP;
} else if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_RSS_XOR) {
priv->rss_hash_fn = ETH_RSS_HASH_XOR;
} else {
en_warn(priv,
"No RSS hash capabilities exposed, using Toeplitz\n");
priv->rss_hash_fn = ETH_RSS_HASH_TOP;
}

mdev->pndev[port] = dev;

netif_carrier_off(dev);
Expand Down
14 changes: 13 additions & 1 deletion drivers/net/ethernet/mellanox/mlx4/en_rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1223,7 +1223,19 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)

rss_context->flags = rss_mask;
rss_context->hash_fn = MLX4_RSS_HASH_TOP;
memcpy(rss_context->rss_key, priv->rss_key, MLX4_EN_RSS_KEY_SIZE);
if (priv->rss_hash_fn == ETH_RSS_HASH_XOR) {
rss_context->hash_fn = MLX4_RSS_HASH_XOR;
} else if (priv->rss_hash_fn == ETH_RSS_HASH_TOP) {
rss_context->hash_fn = MLX4_RSS_HASH_TOP;
memcpy(rss_context->rss_key, priv->rss_key,
MLX4_EN_RSS_KEY_SIZE);
netdev_rss_key_fill(rss_context->rss_key,
MLX4_EN_RSS_KEY_SIZE);
} else {
en_err(priv, "Unknown RSS hash function requested\n");
err = -EINVAL;
goto indir_err;
}
err = mlx4_qp_to_ready(mdev->dev, &priv->res.mtt, &context,
&rss_map->indir_qp, &rss_map->indir_state);
if (err)
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,6 @@ struct mlx4_en_port_profile {
};

struct mlx4_en_profile {
int rss_xor;
int udp_rss;
u8 rss_mask;
u32 active_ports;
Expand Down Expand Up @@ -619,6 +618,7 @@ struct mlx4_en_priv {

u32 pflags;
u8 rss_key[MLX4_EN_RSS_KEY_SIZE];
u8 rss_hash_fn;
};

enum mlx4_en_wol {
Expand Down

0 comments on commit 947cbb0

Please sign in to comment.