diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c b/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c
index 6040293db9c1..4eecd225db7c 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c
@@ -509,11 +509,14 @@ static u32 xgbe_get_rxfh_indir_size(struct net_device *netdev)
}
static int xgbe_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
- u8 *hfunc)
+ u8 *hfunc, u8 *dynamic)
{
struct xgbe_prv_data *pdata = netdev_priv(netdev);
unsigned int i;
+ if (dynamic)
+ *dynamic = false;
+
if (indir) {
for (i = 0; i < ARRAY_SIZE(pdata->rss_table); i++)
indir[i] = XGMAC_GET_BITS(pdata->rss_table[i],@@ -530,7 +533,7 @@ static int xgbe_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
}
static int xgbe_set_rxfh(struct net_device *netdev, const u32 *indir,
- const u8 *key, const u8 hfunc)
+ const u8 *key, const u8 hfunc, const u8 dynamic)
{
struct xgbe_prv_data *pdata = netdev_priv(netdev);
struct xgbe_hw_if *hw_if = &pdata->hw_if;diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
index 820b7e04bb5f..b346ac8d2b49 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
@@ -3417,12 +3417,15 @@ static u32 bnx2x_get_rxfh_indir_size(struct net_device *dev)
}
static int bnx2x_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
- u8 *hfunc)
+ u8 *hfunc, u8 *dynamic)
{
struct bnx2x *bp = netdev_priv(dev);
u8 ind_table[T_ETH_INDIRECTION_TABLE_SIZE] = {0};
size_t i;
+ if (dynamic)
+ *dynamic = false;
+
if (hfunc)
*hfunc = ETH_RSS_HASH_TOP;
if (!indir)@@ -3447,7 +3450,7 @@ static int bnx2x_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
}
static int bnx2x_set_rxfh(struct net_device *dev, const u32 *indir,
- const u8 *key, const u8 hfunc)
+ const u8 *key, const u8 hfunc, const u8 dynamic)
{
struct bnx2x *bp = netdev_priv(dev);
size_t i;diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
index 922b898e7a32..7a1d97319e0a 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
@@ -437,12 +437,15 @@ static u32 bnxt_get_rxfh_key_size(struct net_device *dev)
}
static int bnxt_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
- u8 *hfunc)
+ u8 *hfunc, u8 *dynamic)
{
struct bnxt *bp = netdev_priv(dev);
struct bnxt_vnic_info *vnic = &bp->vnic_info[0];
int i = 0;
+ if (dynamic)
+ *dynamic = false;
+
if (hfunc)
*hfunc = ETH_RSS_HASH_TOP;
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 9293675df7ba..460fbadc009d 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -12561,11 +12561,15 @@ static u32 tg3_get_rxfh_indir_size(struct net_device *dev)
return size;
}
-static int tg3_get_rxfh(struct net_device *dev, u32 *indir, u8 *key, u8 *hfunc)
+static int tg3_get_rxfh(struct net_device *dev, u32 *indir, u8 *key, u8 *hfunc,
+ u8 *dynamic)
{
struct tg3 *tp = netdev_priv(dev);
int i;
+ if (dynamic)
+ *dynamic = false;
+
if (hfunc)
*hfunc = ETH_RSS_HASH_TOP;
if (!indir)@@ -12578,7 +12582,7 @@ static int tg3_get_rxfh(struct net_device *dev, u32 *indir, u8 *key, u8 *hfunc)
}
static int tg3_set_rxfh(struct net_device *dev, const u32 *indir, const u8 *key,
- const u8 hfunc)
+ const u8 hfunc, const u8 dynamic)
{
struct tg3 *tp = netdev_priv(dev);
size_t i;diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c b/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
index a12b2e38cf61..781e456ae5ba 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
@@ -560,12 +560,15 @@ static u32 nicvf_get_rxfh_indir_size(struct net_device *dev)
}
static int nicvf_get_rxfh(struct net_device *dev, u32 *indir, u8 *hkey,
- u8 *hfunc)
+ u8 *hfunc, u8 *dynamic)
{
struct nicvf *nic = netdev_priv(dev);
struct nicvf_rss_info *rss = &nic->rss_info;
int idx;
+ if (dynamic)
+ *dynamic = false;
+
if (indir) {
for (idx = 0; idx < rss->rss_size; idx++)
indir[idx] = rss->ind_tbl[idx];@@ -581,7 +584,7 @@ static int nicvf_get_rxfh(struct net_device *dev, u32 *indir, u8 *hkey,
}
static int nicvf_set_rxfh(struct net_device *dev, const u32 *indir,
- const u8 *hkey, u8 hfunc)
+ const u8 *hkey, u8 hfunc, const u8 dynamic)
{
struct nicvf *nic = netdev_priv(dev);
struct nicvf_rss_info *rss = &nic->rss_info;diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
index 7a0b92b2f73c..b46dbbd6d914 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
@@ -989,11 +989,14 @@ static u32 get_rss_table_size(struct net_device *dev)
return pi->rss_size;
}
-static int get_rss_table(struct net_device *dev, u32 *p, u8 *key, u8 *hfunc)
+static int get_rss_table(struct net_device *dev, u32 *p, u8 *key, u8 *hfunc,
+ u8 *dynamic)
{
const struct port_info *pi = netdev_priv(dev);
unsigned int n = pi->rss_size;
+ if (dynamic)
+ *dynamic = false;
if (hfunc)
*hfunc = ETH_RSS_HASH_TOP;
if (!p)@@ -1004,7 +1007,7 @@ static int get_rss_table(struct net_device *dev, u32 *p, u8 *key, u8 *hfunc)
}
static int set_rss_table(struct net_device *dev, const u32 *p, const u8 *key,
- const u8 hfunc)
+ const u8 hfunc, const u8 dynamic)
{
unsigned int i;
struct port_info *pi = netdev_priv(dev);diff --git a/drivers/net/ethernet/cisco/enic/enic_ethtool.c b/drivers/net/ethernet/cisco/enic/enic_ethtool.c
index f44a39c40642..aba7555d703d 100644
--- a/drivers/net/ethernet/cisco/enic/enic_ethtool.c
+++ b/drivers/net/ethernet/cisco/enic/enic_ethtool.c
@@ -471,10 +471,13 @@ static u32 enic_get_rxfh_key_size(struct net_device *netdev)
}
static int enic_get_rxfh(struct net_device *netdev, u32 *indir, u8 *hkey,
- u8 *hfunc)
+ u8 *hfunc, u8 *dynamic)
{
struct enic *enic = netdev_priv(netdev);
+ if (dynamic)
+ *dynamic = false;
+
if (hkey)
memcpy(hkey, enic->rss_key, ENIC_RSS_LEN);
@@ -485,7 +488,7 @@ static int enic_get_rxfh(struct net_device *netdev, u32 *indir, u8 *hkey,
}
static int enic_set_rxfh(struct net_device *netdev, const u32 *indir,
- const u8 *hkey, const u8 hfunc)
+ const u8 *hkey, const u8 hfunc, const u8 dynamic)
{
struct enic *enic = netdev_priv(netdev);
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
index a19ac441336f..49c089ec2a77 100644
--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
+++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
@@ -1200,12 +1200,15 @@ static u32 be_get_rxfh_key_size(struct net_device *netdev)
}
static int be_get_rxfh(struct net_device *netdev, u32 *indir, u8 *hkey,
- u8 *hfunc)
+ u8 *hfunc, u8 *dynamic)
{
struct be_adapter *adapter = netdev_priv(netdev);
int i;
struct rss_info *rss = &adapter->rss_info;
+ if (dynamic)
+ *dynamic = false;
+
if (indir) {
for (i = 0; i < RSS_INDIR_TABLE_LEN; i++)
indir[i] = rss->rss_queue[i];@@ -1221,7 +1224,7 @@ static int be_get_rxfh(struct net_device *netdev, u32 *indir, u8 *hkey,
}
static int be_set_rxfh(struct net_device *netdev, const u32 *indir,
- const u8 *hkey, const u8 hfunc)
+ const u8 *hkey, const u8 hfunc, const u8 dynamic)
{
int rc = 0, i, j;
struct be_adapter *adapter = netdev_priv(netdev);diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
index 3df22840fcd1..6b99cdedd90a 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
@@ -1194,12 +1194,16 @@ hns_get_rss_indir_size(struct net_device *netdev)
}
static int
-hns_get_rss(struct net_device *netdev, u32 *indir, u8 *key, u8 *hfunc)
+hns_get_rss(struct net_device *netdev, u32 *indir, u8 *key, u8 *hfunc,
+ u8 *dynamic)
{
struct hns_nic_priv *priv = netdev_priv(netdev);
struct hnae_ae_ops *ops;
int ret;
+ if (dynamic)
+ *dynamic = false;
+
if (AE_IS_VER1(priv->enet_ver)) {
netdev_err(netdev,
"RSS feature is not supported on this hardware\n");@@ -1218,7 +1222,7 @@ hns_get_rss(struct net_device *netdev, u32 *indir, u8 *key, u8 *hfunc)
static int
hns_set_rss(struct net_device *netdev, const u32 *indir, const u8 *key,
- const u8 hfunc)
+ const u8 hfunc, const u8 dynamic)
{
struct hns_nic_priv *priv = netdev_priv(netdev);
struct hnae_ae_ops *ops;diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c b/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c
index 6a9f9886cb98..af11c4c1b256 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c
@@ -1091,7 +1091,7 @@ static u32 fm10k_get_rssrk_size(struct net_device __always_unused *netdev)
}
static int fm10k_get_rssh(struct net_device *netdev, u32 *indir, u8 *key,
- u8 *hfunc)
+ u8 *hfunc, u8 *dynamic)
{
struct fm10k_intfc *interface = netdev_priv(netdev);
int i, err;@@ -1099,6 +1099,9 @@ static int fm10k_get_rssh(struct net_device *netdev, u32 *indir, u8 *key,
if (hfunc)
*hfunc = ETH_RSS_HASH_TOP;
+ if (dynamic)
+ *dynamic = false;
+
err = fm10k_get_reta(netdev, indir);
if (err || !key)
return err;
@@ -1110,7 +1113,7 @@ static int fm10k_get_rssh(struct net_device *netdev, u32 *indir, u8 *key,
}
static int fm10k_set_rssh(struct net_device *netdev, const u32 *indir,
- const u8 *key, const u8 hfunc)
+ const u8 *key, const u8 hfunc, const u8 dynamic)
{
struct fm10k_intfc *interface = netdev_priv(netdev);
struct fm10k_hw *hw = &interface->hw;diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
index 54d63a61923e..ca00f98c73d1 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -2630,7 +2630,7 @@ static u32 i40e_get_rxfh_indir_size(struct net_device *netdev)
}
static int i40e_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
- u8 *hfunc)
+ u8 *hfunc, u8 *dynamic)
{
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_vsi *vsi = np->vsi;@@ -2638,6 +2638,9 @@ static int i40e_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
int ret;
u16 i;
+ if (dynamic)
+ *dynamic = false;
+
if (hfunc)
*hfunc = ETH_RSS_HASH_TOP;
@@ -2670,7 +2673,7 @@ static int i40e_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
* returns 0 after programming the table.
**/
static int i40e_set_rxfh(struct net_device *netdev, const u32 *indir,
- const u8 *key, const u8 hfunc)
+ const u8 *key, const u8 hfunc, const u8 dynamic)
{
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_vsi *vsi = np->vsi;diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
index dd4430aae7fa..2cae1dea7e91 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
@@ -643,7 +643,7 @@ static u32 i40evf_get_rxfh_indir_size(struct net_device *netdev)
* Reads the indirection table directly from the hardware. Always returns 0.
**/
static int i40evf_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
- u8 *hfunc)
+ u8 *hfunc, u8 *dynamic)
{
struct i40evf_adapter *adapter = netdev_priv(netdev);
struct i40e_vsi *vsi = &adapter->vsi;@@ -651,6 +651,8 @@ static int i40evf_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
int ret;
u16 i;
+ if (dynamic)
+ *dynamic = false;
if (hfunc)
*hfunc = ETH_RSS_HASH_TOP;
if (!indir)
@@ -686,7 +688,7 @@ static int i40evf_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
* returns 0 after programming the table.
**/
static int i40evf_set_rxfh(struct net_device *netdev, const u32 *indir,
- const u8 *key, const u8 hfunc)
+ const u8 *key, const u8 hfunc, const u8 dynamic)
{
struct i40evf_adapter *adapter = netdev_priv(netdev);
struct i40e_vsi *vsi = &adapter->vsi;diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c
index e4420abb413f..6330860d1488 100644
--- a/drivers/net/ethernet/intel/igb/igb_ethtool.c
+++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c
@@ -3211,11 +3211,13 @@ static u32 igb_get_rxfh_indir_size(struct net_device *netdev)
}
static int igb_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
- u8 *hfunc)
+ u8 *hfunc, u8 *dynamic)
{
struct igb_adapter *adapter = netdev_priv(netdev);
int i;
+ if (dynamic)
+ *dynamic = false;
if (hfunc)
*hfunc = ETH_RSS_HASH_TOP;
if (!indir)@@ -3262,7 +3264,7 @@ void igb_write_rss_indir_tbl(struct igb_adapter *adapter)
}
static int igb_set_rxfh(struct net_device *netdev, const u32 *indir,
- const u8 *key, const u8 hfunc)
+ const u8 *key, const u8 hfunc, const u8 dynamic)
{
struct igb_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
index 5fae53031462..05409e057c04 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
@@ -2931,10 +2931,13 @@ static void ixgbe_get_reta(struct ixgbe_adapter *adapter, u32 *indir)
}
static int ixgbe_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
- u8 *hfunc)
+ u8 *hfunc, u8 *dynamic)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ if (dynamic)
+ *dynamic = false;
+
if (hfunc)
*hfunc = ETH_RSS_HASH_TOP;
@@ -2948,7 +2951,7 @@ static int ixgbe_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
}
static int ixgbe_set_rxfh(struct net_device *netdev, const u32 *indir,
- const u8 *key, const u8 hfunc)
+ const u8 *key, const u8 hfunc, const u8 dynamic)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
int i;diff --git a/drivers/net/ethernet/intel/ixgbevf/ethtool.c b/drivers/net/ethernet/intel/ixgbevf/ethtool.c
index c48aef613b0a..fd225c284895 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ethtool.c
@@ -825,11 +825,14 @@ static u32 ixgbevf_get_rxfh_key_size(struct net_device *netdev)
}
static int ixgbevf_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
- u8 *hfunc)
+ u8 *hfunc, u8 *dynamic)
{
struct ixgbevf_adapter *adapter = netdev_priv(netdev);
int err = 0;
+ if (dynamic)
+ *dynamic = false;
+
if (hfunc)
*hfunc = ETH_RSS_HASH_TOP;
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index fabc8df40392..8950997b9d2c 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -3350,7 +3350,8 @@ static int mvneta_config_rss(struct mvneta_port *pp)
}
static int mvneta_ethtool_set_rxfh(struct net_device *dev, const u32 *indir,
- const u8 *key, const u8 hfunc)
+ const u8 *key, const u8 hfunc,
+ const u8 dynamic)
{
struct mvneta_port *pp = netdev_priv(dev);
/* We require at least one supported parameter to be changed@@ -3369,10 +3370,13 @@ static int mvneta_ethtool_set_rxfh(struct net_device *dev, const u32 *indir,
}
static int mvneta_ethtool_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
- u8 *hfunc)
+ u8 *hfunc, u8 *dynamic)
{
struct mvneta_port *pp = netdev_priv(dev);
+ if (dynamic)
+ *dynamic = false;
+
if (hfunc)
*hfunc = ETH_RSS_HASH_TOP;
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
index dd84cabb2a51..d99926b17b96 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
@@ -1118,7 +1118,7 @@ static int mlx4_en_check_rxfh_func(struct net_device *dev, u8 hfunc)
}
static int mlx4_en_get_rxfh(struct net_device *dev, u32 *ring_index, u8 *key,
- u8 *hfunc)
+ u8 *hfunc, u8 *dynamic)
{
struct mlx4_en_priv *priv = netdev_priv(dev);
struct mlx4_en_rss_map *rss_map = &priv->rss_map;@@ -1126,6 +1126,9 @@ static int mlx4_en_get_rxfh(struct net_device *dev, u32 *ring_index, u8 *key,
size_t n = priv->rx_ring_num;
int err = 0;
+ if (dynamic)
+ *dynamic = false;
+
rss_rings = priv->prof->rss_rings ?: priv->rx_ring_num;
rss_rings = 1 << ilog2(rss_rings);
@@ -1143,7 +1146,7 @@ static int mlx4_en_get_rxfh(struct net_device *dev, u32 *ring_index, u8 *key,
}
static int mlx4_en_set_rxfh(struct net_device *dev, const u32 *ring_index,
- const u8 *key, const u8 hfunc)
+ const u8 *key, const u8 hfunc, const u8 dynamic)
{
struct mlx4_en_priv *priv = netdev_priv(dev);
struct mlx4_en_dev *mdev = priv->mdev;diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
index 65624ac65b4c..86d14c6be8e7 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
@@ -685,10 +685,13 @@ static u32 mlx5e_get_rxfh_indir_size(struct net_device *netdev)
}
static int mlx5e_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
- u8 *hfunc)
+ u8 *hfunc, u8 *dynamic)
{
struct mlx5e_priv *priv = netdev_priv(netdev);
+ if (dynamic)
+ *dynamic = false;
+
if (indir)
memcpy(indir, priv->params.indirection_rqt,
sizeof(priv->params.indirection_rqt));@@ -704,7 +707,7 @@ static int mlx5e_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
}
static int mlx5e_set_rxfh(struct net_device *dev, const u32 *indir,
- const u8 *key, const u8 hfunc)
+ const u8 *key, const u8 hfunc, const u8 dynamic)
{
struct mlx5e_priv *priv = netdev_priv(dev);
bool close_open;diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
index 9a4084a68db5..448e49fb5db6 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
@@ -454,7 +454,7 @@ static u32 nfp_net_get_rxfh_key_size(struct net_device *netdev)
}
static int nfp_net_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
- u8 *hfunc)
+ u8 *hfunc, u8 *dynamic)
{
struct nfp_net *nn = netdev_priv(netdev);
int i;@@ -462,6 +462,9 @@ static int nfp_net_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
if (!(nn->cap & NFP_NET_CFG_CTRL_RSS))
return -EOPNOTSUPP;
+ if (dynamic)
+ *dynamic = false;
+
if (indir)
for (i = 0; i < ARRAY_SIZE(nn->rss_itbl); i++)
indir[i] = nn->rss_itbl[i];
@@ -475,7 +478,7 @@ static int nfp_net_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
static int nfp_net_set_rxfh(struct net_device *netdev,
const u32 *indir, const u8 *key,
- const u8 hfunc)
+ const u8 hfunc, const u8 dynamic)
{
struct nfp_net *nn = netdev_priv(netdev);
int i;diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c
index 034797661f96..5b483591f02f 100644
--- a/drivers/net/ethernet/sfc/ethtool.c
+++ b/drivers/net/ethernet/sfc/ethtool.c
@@ -1087,10 +1087,12 @@ static u32 efx_ethtool_get_rxfh_indir_size(struct net_device *net_dev)
}
static int efx_ethtool_get_rxfh(struct net_device *net_dev, u32 *indir, u8 *key,
- u8 *hfunc)
+ u8 *hfunc, u8 *dynamic)
{
struct efx_nic *efx = netdev_priv(net_dev);
+ if (dynamic)
+ *dynamic = false;
if (hfunc)
*hfunc = ETH_RSS_HASH_TOP;
if (indir)@@ -1099,7 +1101,8 @@ static int efx_ethtool_get_rxfh(struct net_device *net_dev, u32 *indir, u8 *key,
}
static int efx_ethtool_set_rxfh(struct net_device *net_dev, const u32 *indir,
- const u8 *key, const u8 hfunc)
+ const u8 *key, const u8 hfunc,
+ const u8 dynamic)
{
struct efx_nic *efx = netdev_priv(net_dev);
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 653dc9c4ebac..b109d98291d1 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -259,9 +259,9 @@ struct ethtool_ops {
u32 (*get_rxfh_key_size)(struct net_device *);
u32 (*get_rxfh_indir_size)(struct net_device *);
int (*get_rxfh)(struct net_device *, u32 *indir, u8 *key,
- u8 *hfunc);
+ u8 *hfunc, u8 *dynamic);
int (*set_rxfh)(struct net_device *, const u32 *indir,
- const u8 *key, const u8 hfunc);
+ const u8 *key, const u8 hfunc, const u8 dynamic);
void (*get_channels)(struct net_device *, struct ethtool_channels *);
int (*set_channels)(struct net_device *, struct ethtool_channels *);
int (*get_dump_flag)(struct net_device *, struct ethtool_dump *);diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
index 57fa39005e79..e2c4a6a94f47 100644
--- a/include/uapi/linux/ethtool.h
+++ b/include/uapi/linux/ethtool.h
@@ -923,6 +923,10 @@ struct ethtool_rxfh_indir {
* hardware hash key.
* @hfunc: Defines the current RSS hash function used by HW (or to be set to).
* Valid values are one of the %ETH_RSS_HASH_*.
+ * @dynamic: Indicate whether the device driver may use dynamic RSS settings
+ * which change due to various run time factors, such as number of
+ * queues. When false driver must attempt to preserve RSS settings when
+ * possible. When true driver may override any requested RSS settings.
* @rsvd: Reserved for future extensions.
* @rss_config: RX ring/queue index for each hash value i.e., indirection table
* of @indir_size __u32 elements, followed by hash key of @key_size@@ -933,6 +937,7 @@ struct ethtool_rxfh_indir {
* %ETH_RXFH_INDIR_NO_CHANGE means that indir table setting is not requested
* and a @indir_size of zero means the indir table should be reset to default
* values. An hfunc of zero means that hash function setting is not requested.
+ * If dynamic is true, driver may ignore any other settings requested.
*/
struct ethtool_rxfh {
__u32 cmd;@@ -940,7 +945,8 @@ struct ethtool_rxfh {
__u32 indir_size;
__u32 key_size;
__u8 hfunc;
- __u8 rsvd8[3];
+ __u8 dynamic;
+ __u8 rsvd8[2];
__u32 rsvd32;
__u32 rss_config[0];
};diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index daf04709dd3c..54676b258eef 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -676,7 +676,7 @@ static noinline_for_stack int ethtool_get_rxfh_indir(struct net_device *dev,
if (!indir)
return -ENOMEM;
- ret = dev->ethtool_ops->get_rxfh(dev, indir, NULL, NULL);
+ ret = dev->ethtool_ops->get_rxfh(dev, indir, NULL, NULL, NULL);
if (ret)
goto out;
@@ -737,7 +737,7 @@ static noinline_for_stack int ethtool_set_rxfh_indir(struct net_device *dev,
goto out;
}
- ret = ops->set_rxfh(dev, indir, NULL, ETH_RSS_HASH_NO_CHANGE);
+ ret = ops->set_rxfh(dev, indir, NULL, ETH_RSS_HASH_NO_CHANGE, false);
out:
kfree(indir);
@@ -755,7 +755,7 @@ static noinline_for_stack int ethtool_get_rxfh(struct net_device *dev,
u32 total_size;
u32 indir_bytes;
u32 *indir = NULL;
- u8 dev_hfunc = 0;
+ u8 dev_hfunc = 0, dynamic = 0;
u8 *hkey = NULL;
u8 *rss_config;
@@ -773,8 +773,7 @@ static noinline_for_stack int ethtool_get_rxfh(struct net_device *dev,
user_key_size = rxfh.key_size;
/* Check that reserved fields are 0 for now */
- if (rxfh.rss_context || rxfh.rsvd8[0] || rxfh.rsvd8[1] ||
- rxfh.rsvd8[2] || rxfh.rsvd32)
+ if (rxfh.rss_context || rxfh.rsvd8[0] || rxfh.rsvd8[1] || rxfh.rsvd32)
return -EINVAL;
rxfh.indir_size = dev_indir_size;
@@ -798,7 +797,8 @@ static noinline_for_stack int ethtool_get_rxfh(struct net_device *dev,
if (user_key_size)
hkey = rss_config + indir_bytes;
- ret = dev->ethtool_ops->get_rxfh(dev, indir, hkey, &dev_hfunc);
+ ret = dev->ethtool_ops->get_rxfh(dev, indir, hkey, &dev_hfunc,
+ &dynamic);
if (ret)
goto out;
@@ -809,6 +809,10 @@ static noinline_for_stack int ethtool_get_rxfh(struct net_device *dev,
offsetof(struct ethtool_rxfh, rss_config[0]),
rss_config, total_size)) {
ret = -EFAULT;
+ } else if (copy_to_user(useraddr +
+ offsetof(struct ethtool_rxfh, dynamic),
+ &dynamic, sizeof(rxfh.dynamic))) {
+ ret = -EFAULT;
}
out:
kfree(rss_config);@@ -841,19 +845,20 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
return -EFAULT;
/* Check that reserved fields are 0 for now */
- if (rxfh.rss_context || rxfh.rsvd8[0] || rxfh.rsvd8[1] ||
- rxfh.rsvd8[2] || rxfh.rsvd32)
+ if (rxfh.rss_context || rxfh.rsvd8[0] || rxfh.rsvd8[1] || rxfh.rsvd32)
return -EINVAL;
/* If either indir, hash key or function is valid, proceed further.
- * Must request at least one change: indir size, hash key or function.
+ * Must request at least one change: indir size, hash key, function or
+ * dynamic mode.
*/
if ((rxfh.indir_size &&
rxfh.indir_size != ETH_RXFH_INDIR_NO_CHANGE &&
rxfh.indir_size != dev_indir_size) ||
(rxfh.key_size && (rxfh.key_size != dev_key_size)) ||
(rxfh.indir_size == ETH_RXFH_INDIR_NO_CHANGE &&
- rxfh.key_size == 0 && rxfh.hfunc == ETH_RSS_HASH_NO_CHANGE))
+ rxfh.key_size == 0 && rxfh.hfunc == ETH_RSS_HASH_NO_CHANGE &&
+ rxfh.dynamic == 0))
return -EINVAL;
if (rxfh.indir_size != ETH_RXFH_INDIR_NO_CHANGE)
@@ -896,7 +901,7 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
}
}
- ret = ops->set_rxfh(dev, indir, hkey, rxfh.hfunc);
+ ret = ops->set_rxfh(dev, indir, hkey, rxfh.hfunc, rxfh.dynamic);
out:
kfree(rss_config);
--
2.6.3.505.g5cc1fd1