diff options
author | Eyal Perry <eyalpe@mellanox.com> | 2014-12-02 18:12:11 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-12-08 21:07:10 -0500 |
commit | 947cbb0ac242096d60380952ec1a1761372cba66 (patch) | |
tree | d22d19869b349a9abfc8f52dbbb9ae4c531ff7c6 /drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | |
parent | 892311f66f2411b813ca631009356891a0c2b0a1 (diff) |
net/mlx4_en: Support for configurable RSS hash function
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>
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlx4/en_ethtool.c')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 34 |
1 files changed, 29 insertions, 5 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index 28c3fc5a0791..90e0f045a6bc 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c @@ -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) { @@ -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; } @@ -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 */ @@ -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; @@ -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) |