@ -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 )