aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-06-03 02:07:02 -0400
committerDavid S. Miller <davem@davemloft.net>2014-06-03 02:07:02 -0400
commit014b20133bcd442db554c2d2d86181b34cd15b66 (patch)
tree3402034d4bba5628d21c98258634c58d5bb46bb7
parenta68ab98e6c7ab0955babcdc45ca446886f3bfb25 (diff)
parentf062a3844845d267e3716cbc188ad502a15898b7 (diff)
Merge branch 'ethtool-rssh-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/bwh/net-next
Ben Hutchings says: ==================== Pull request: Fixes for new ethtool RSS commands This addresses several problems I previously identified with the new ETHTOOL_{G,S}RSSH commands: 1. Missing validation of reserved parameters 2. Vague documentation 3. Use of unnamed magic number 4. No consolidation with existing driver operations I don't currently have access to suitable network hardware, but have tested these changes with a dummy driver that can support various combinations of operations and sizes, together with (a) Debian's ethtool 3.13 (b) ethtool 3.14 with the submitted patch to use ETHTOOL_{G,S}RSSH and minor adjustment for fixes 1 and 3. v2: Update RSS operations in vmxnet3 too ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c15
-rw-r--r--drivers/net/ethernet/broadcom/tg3.c8
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c8
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.c2
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.h2
-rw-r--r--drivers/net/ethernet/emulex/benet/be_ethtool.c3
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c15
-rw-r--r--drivers/net/ethernet/intel/igb/igb_ethtool.c9
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_ethtool.c10
-rw-r--r--drivers/net/ethernet/sfc/ethtool.c10
-rw-r--r--drivers/net/vmxnet3/vmxnet3_ethtool.c8
-rw-r--r--include/linux/ethtool.h24
-rw-r--r--include/uapi/linux/ethtool.h25
-rw-r--r--net/core/ethtool.c110
14 files changed, 120 insertions, 129 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
index 5203a8924edf..bd0600cf7266 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
@@ -3316,7 +3316,7 @@ static u32 bnx2x_get_rxfh_indir_size(struct net_device *dev)
3316 return T_ETH_INDIRECTION_TABLE_SIZE; 3316 return T_ETH_INDIRECTION_TABLE_SIZE;
3317} 3317}
3318 3318
3319static int bnx2x_get_rxfh_indir(struct net_device *dev, u32 *indir) 3319static int bnx2x_get_rxfh(struct net_device *dev, u32 *indir, u8 *key)
3320{ 3320{
3321 struct bnx2x *bp = netdev_priv(dev); 3321 struct bnx2x *bp = netdev_priv(dev);
3322 u8 ind_table[T_ETH_INDIRECTION_TABLE_SIZE] = {0}; 3322 u8 ind_table[T_ETH_INDIRECTION_TABLE_SIZE] = {0};
@@ -3340,14 +3340,15 @@ static int bnx2x_get_rxfh_indir(struct net_device *dev, u32 *indir)
3340 return 0; 3340 return 0;
3341} 3341}
3342 3342
3343static int bnx2x_set_rxfh_indir(struct net_device *dev, const u32 *indir) 3343static int bnx2x_set_rxfh(struct net_device *dev, const u32 *indir,
3344 const u8 *key)
3344{ 3345{
3345 struct bnx2x *bp = netdev_priv(dev); 3346 struct bnx2x *bp = netdev_priv(dev);
3346 size_t i; 3347 size_t i;
3347 3348
3348 for (i = 0; i < T_ETH_INDIRECTION_TABLE_SIZE; i++) { 3349 for (i = 0; i < T_ETH_INDIRECTION_TABLE_SIZE; i++) {
3349 /* 3350 /*
3350 * The same as in bnx2x_get_rxfh_indir: we can't use a memcpy() 3351 * The same as in bnx2x_get_rxfh: we can't use a memcpy()
3351 * as an internal storage of an indirection table is a u8 array 3352 * as an internal storage of an indirection table is a u8 array
3352 * while indir->ring_index points to an array of u32. 3353 * while indir->ring_index points to an array of u32.
3353 * 3354 *
@@ -3471,8 +3472,8 @@ static const struct ethtool_ops bnx2x_ethtool_ops = {
3471 .get_rxnfc = bnx2x_get_rxnfc, 3472 .get_rxnfc = bnx2x_get_rxnfc,
3472 .set_rxnfc = bnx2x_set_rxnfc, 3473 .set_rxnfc = bnx2x_set_rxnfc,
3473 .get_rxfh_indir_size = bnx2x_get_rxfh_indir_size, 3474 .get_rxfh_indir_size = bnx2x_get_rxfh_indir_size,
3474 .get_rxfh_indir = bnx2x_get_rxfh_indir, 3475 .get_rxfh = bnx2x_get_rxfh,
3475 .set_rxfh_indir = bnx2x_set_rxfh_indir, 3476 .set_rxfh = bnx2x_set_rxfh,
3476 .get_channels = bnx2x_get_channels, 3477 .get_channels = bnx2x_get_channels,
3477 .set_channels = bnx2x_set_channels, 3478 .set_channels = bnx2x_set_channels,
3478 .get_module_info = bnx2x_get_module_info, 3479 .get_module_info = bnx2x_get_module_info,
@@ -3498,8 +3499,8 @@ static const struct ethtool_ops bnx2x_vf_ethtool_ops = {
3498 .get_rxnfc = bnx2x_get_rxnfc, 3499 .get_rxnfc = bnx2x_get_rxnfc,
3499 .set_rxnfc = bnx2x_set_rxnfc, 3500 .set_rxnfc = bnx2x_set_rxnfc,
3500 .get_rxfh_indir_size = bnx2x_get_rxfh_indir_size, 3501 .get_rxfh_indir_size = bnx2x_get_rxfh_indir_size,
3501 .get_rxfh_indir = bnx2x_get_rxfh_indir, 3502 .get_rxfh = bnx2x_get_rxfh,
3502 .set_rxfh_indir = bnx2x_set_rxfh_indir, 3503 .set_rxfh = bnx2x_set_rxfh,
3503 .get_channels = bnx2x_get_channels, 3504 .get_channels = bnx2x_get_channels,
3504 .set_channels = bnx2x_set_channels, 3505 .set_channels = bnx2x_set_channels,
3505}; 3506};
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 3b74da5f48a1..df2792d8383d 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -12532,7 +12532,7 @@ static u32 tg3_get_rxfh_indir_size(struct net_device *dev)
12532 return size; 12532 return size;
12533} 12533}
12534 12534
12535static int tg3_get_rxfh_indir(struct net_device *dev, u32 *indir) 12535static int tg3_get_rxfh(struct net_device *dev, u32 *indir, u8 *key)
12536{ 12536{
12537 struct tg3 *tp = netdev_priv(dev); 12537 struct tg3 *tp = netdev_priv(dev);
12538 int i; 12538 int i;
@@ -12543,7 +12543,7 @@ static int tg3_get_rxfh_indir(struct net_device *dev, u32 *indir)
12543 return 0; 12543 return 0;
12544} 12544}
12545 12545
12546static int tg3_set_rxfh_indir(struct net_device *dev, const u32 *indir) 12546static int tg3_set_rxfh(struct net_device *dev, const u32 *indir, const u8 *key)
12547{ 12547{
12548 struct tg3 *tp = netdev_priv(dev); 12548 struct tg3 *tp = netdev_priv(dev);
12549 size_t i; 12549 size_t i;
@@ -14075,8 +14075,8 @@ static const struct ethtool_ops tg3_ethtool_ops = {
14075 .get_sset_count = tg3_get_sset_count, 14075 .get_sset_count = tg3_get_sset_count,
14076 .get_rxnfc = tg3_get_rxnfc, 14076 .get_rxnfc = tg3_get_rxnfc,
14077 .get_rxfh_indir_size = tg3_get_rxfh_indir_size, 14077 .get_rxfh_indir_size = tg3_get_rxfh_indir_size,
14078 .get_rxfh_indir = tg3_get_rxfh_indir, 14078 .get_rxfh = tg3_get_rxfh,
14079 .set_rxfh_indir = tg3_set_rxfh_indir, 14079 .set_rxfh = tg3_set_rxfh,
14080 .get_channels = tg3_get_channels, 14080 .get_channels = tg3_get_channels,
14081 .set_channels = tg3_set_channels, 14081 .set_channels = tg3_set_channels,
14082 .get_ts_info = tg3_get_ts_info, 14082 .get_ts_info = tg3_get_ts_info,
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 266a5bc6aedf..8cf6be93f491 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -2739,7 +2739,7 @@ static u32 get_rss_table_size(struct net_device *dev)
2739 return pi->rss_size; 2739 return pi->rss_size;
2740} 2740}
2741 2741
2742static int get_rss_table(struct net_device *dev, u32 *p) 2742static int get_rss_table(struct net_device *dev, u32 *p, u8 *key)
2743{ 2743{
2744 const struct port_info *pi = netdev_priv(dev); 2744 const struct port_info *pi = netdev_priv(dev);
2745 unsigned int n = pi->rss_size; 2745 unsigned int n = pi->rss_size;
@@ -2749,7 +2749,7 @@ static int get_rss_table(struct net_device *dev, u32 *p)
2749 return 0; 2749 return 0;
2750} 2750}
2751 2751
2752static int set_rss_table(struct net_device *dev, const u32 *p) 2752static int set_rss_table(struct net_device *dev, const u32 *p, const u8 *key)
2753{ 2753{
2754 unsigned int i; 2754 unsigned int i;
2755 struct port_info *pi = netdev_priv(dev); 2755 struct port_info *pi = netdev_priv(dev);
@@ -2851,8 +2851,8 @@ static const struct ethtool_ops cxgb_ethtool_ops = {
2851 .set_wol = set_wol, 2851 .set_wol = set_wol,
2852 .get_rxnfc = get_rxnfc, 2852 .get_rxnfc = get_rxnfc,
2853 .get_rxfh_indir_size = get_rss_table_size, 2853 .get_rxfh_indir_size = get_rss_table_size,
2854 .get_rxfh_indir = get_rss_table, 2854 .get_rxfh = get_rss_table,
2855 .set_rxfh_indir = set_rss_table, 2855 .set_rxfh = set_rss_table,
2856 .flash_device = set_flash, 2856 .flash_device = set_flash,
2857}; 2857};
2858 2858
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index a568f7d1a24c..f4ea3490f446 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -2065,7 +2065,7 @@ int be_cmd_reset_function(struct be_adapter *adapter)
2065} 2065}
2066 2066
2067int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, 2067int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable,
2068 u32 rss_hash_opts, u16 table_size, u8 *rss_hkey) 2068 u32 rss_hash_opts, u16 table_size, const u8 *rss_hkey)
2069{ 2069{
2070 struct be_mcc_wrb *wrb; 2070 struct be_mcc_wrb *wrb;
2071 struct be_cmd_req_rss_config *req; 2071 struct be_cmd_req_rss_config *req;
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
index d4616ffb7238..3e0a6b243806 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
@@ -2082,7 +2082,7 @@ int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num,
2082 u32 *function_mode, u32 *function_caps, u16 *asic_rev); 2082 u32 *function_mode, u32 *function_caps, u16 *asic_rev);
2083int be_cmd_reset_function(struct be_adapter *adapter); 2083int be_cmd_reset_function(struct be_adapter *adapter);
2084int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, 2084int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable,
2085 u32 rss_hash_opts, u16 table_size, u8 *rss_hkey); 2085 u32 rss_hash_opts, u16 table_size, const u8 *rss_hkey);
2086int be_process_mcc(struct be_adapter *adapter); 2086int be_process_mcc(struct be_adapter *adapter);
2087int be_cmd_set_beacon_state(struct be_adapter *adapter, u8 port_num, u8 beacon, 2087int be_cmd_set_beacon_state(struct be_adapter *adapter, u8 port_num, u8 beacon,
2088 u8 status, u8 state); 2088 u8 status, u8 state);
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
index 970ae337daac..e2da4d20dd3d 100644
--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
+++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
@@ -1117,7 +1117,8 @@ static int be_get_rxfh(struct net_device *netdev, u32 *indir, u8 *hkey)
1117 return 0; 1117 return 0;
1118} 1118}
1119 1119
1120static int be_set_rxfh(struct net_device *netdev, u32 *indir, u8 *hkey) 1120static int be_set_rxfh(struct net_device *netdev, const u32 *indir,
1121 const u8 *hkey)
1121{ 1122{
1122 int rc = 0, i, j; 1123 int rc = 0, i, j;
1123 struct be_adapter *adapter = netdev_priv(netdev); 1124 struct be_adapter *adapter = netdev_priv(netdev);
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
index df4dcfd364d8..9cd381a6c4be 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
@@ -624,13 +624,14 @@ static u32 i40evf_get_rxfh_indir_size(struct net_device *netdev)
624} 624}
625 625
626/** 626/**
627 * i40evf_get_rxfh_indir - get the rx flow hash indirection table 627 * i40evf_get_rxfh - get the rx flow hash indirection table
628 * @netdev: network interface device structure 628 * @netdev: network interface device structure
629 * @indir: indirection table 629 * @indir: indirection table
630 * @key: hash key (will be %NULL until get_rxfh_key_size is implemented)
630 * 631 *
631 * Reads the indirection table directly from the hardware. Always returns 0. 632 * Reads the indirection table directly from the hardware. Always returns 0.
632 **/ 633 **/
633static int i40evf_get_rxfh_indir(struct net_device *netdev, u32 *indir) 634static int i40evf_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key)
634{ 635{
635 struct i40evf_adapter *adapter = netdev_priv(netdev); 636 struct i40evf_adapter *adapter = netdev_priv(netdev);
636 struct i40e_hw *hw = &adapter->hw; 637 struct i40e_hw *hw = &adapter->hw;
@@ -648,14 +649,16 @@ static int i40evf_get_rxfh_indir(struct net_device *netdev, u32 *indir)
648} 649}
649 650
650/** 651/**
651 * i40evf_set_rxfh_indir - set the rx flow hash indirection table 652 * i40evf_set_rxfh - set the rx flow hash indirection table
652 * @netdev: network interface device structure 653 * @netdev: network interface device structure
653 * @indir: indirection table 654 * @indir: indirection table
655 * @key: hash key (will be %NULL until get_rxfh_key_size is implemented)
654 * 656 *
655 * Returns -EINVAL if the table specifies an inavlid queue id, otherwise 657 * Returns -EINVAL if the table specifies an inavlid queue id, otherwise
656 * returns 0 after programming the table. 658 * returns 0 after programming the table.
657 **/ 659 **/
658static int i40evf_set_rxfh_indir(struct net_device *netdev, const u32 *indir) 660static int i40evf_set_rxfh(struct net_device *netdev, const u32 *indir,
661 const u8 *key)
659{ 662{
660 struct i40evf_adapter *adapter = netdev_priv(netdev); 663 struct i40evf_adapter *adapter = netdev_priv(netdev);
661 struct i40e_hw *hw = &adapter->hw; 664 struct i40e_hw *hw = &adapter->hw;
@@ -689,8 +692,8 @@ static const struct ethtool_ops i40evf_ethtool_ops = {
689 .get_rxnfc = i40evf_get_rxnfc, 692 .get_rxnfc = i40evf_get_rxnfc,
690 .set_rxnfc = i40evf_set_rxnfc, 693 .set_rxnfc = i40evf_set_rxnfc,
691 .get_rxfh_indir_size = i40evf_get_rxfh_indir_size, 694 .get_rxfh_indir_size = i40evf_get_rxfh_indir_size,
692 .get_rxfh_indir = i40evf_get_rxfh_indir, 695 .get_rxfh = i40evf_get_rxfh,
693 .set_rxfh_indir = i40evf_set_rxfh_indir, 696 .set_rxfh = i40evf_set_rxfh,
694 .get_channels = i40evf_get_channels, 697 .get_channels = i40evf_get_channels,
695}; 698};
696 699
diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c
index a84297c85fb1..d8bbcf1873ca 100644
--- a/drivers/net/ethernet/intel/igb/igb_ethtool.c
+++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c
@@ -2830,7 +2830,7 @@ static u32 igb_get_rxfh_indir_size(struct net_device *netdev)
2830 return IGB_RETA_SIZE; 2830 return IGB_RETA_SIZE;
2831} 2831}
2832 2832
2833static int igb_get_rxfh_indir(struct net_device *netdev, u32 *indir) 2833static int igb_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key)
2834{ 2834{
2835 struct igb_adapter *adapter = netdev_priv(netdev); 2835 struct igb_adapter *adapter = netdev_priv(netdev);
2836 int i; 2836 int i;
@@ -2876,7 +2876,8 @@ void igb_write_rss_indir_tbl(struct igb_adapter *adapter)
2876 } 2876 }
2877} 2877}
2878 2878
2879static int igb_set_rxfh_indir(struct net_device *netdev, const u32 *indir) 2879static int igb_set_rxfh(struct net_device *netdev, const u32 *indir,
2880 const u8 *key)
2880{ 2881{
2881 struct igb_adapter *adapter = netdev_priv(netdev); 2882 struct igb_adapter *adapter = netdev_priv(netdev);
2882 struct e1000_hw *hw = &adapter->hw; 2883 struct e1000_hw *hw = &adapter->hw;
@@ -3025,8 +3026,8 @@ static const struct ethtool_ops igb_ethtool_ops = {
3025 .get_module_info = igb_get_module_info, 3026 .get_module_info = igb_get_module_info,
3026 .get_module_eeprom = igb_get_module_eeprom, 3027 .get_module_eeprom = igb_get_module_eeprom,
3027 .get_rxfh_indir_size = igb_get_rxfh_indir_size, 3028 .get_rxfh_indir_size = igb_get_rxfh_indir_size,
3028 .get_rxfh_indir = igb_get_rxfh_indir, 3029 .get_rxfh = igb_get_rxfh,
3029 .set_rxfh_indir = igb_set_rxfh_indir, 3030 .set_rxfh = igb_set_rxfh,
3030 .get_channels = igb_get_channels, 3031 .get_channels = igb_get_channels,
3031 .set_channels = igb_set_channels, 3032 .set_channels = igb_set_channels,
3032 .begin = igb_ethtool_begin, 3033 .begin = igb_ethtool_begin,
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
index 7ba3df3cb312..c021c96294fb 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
@@ -564,7 +564,7 @@ static u32 mlx4_en_get_rxfh_indir_size(struct net_device *dev)
564 return priv->rx_ring_num; 564 return priv->rx_ring_num;
565} 565}
566 566
567static int mlx4_en_get_rxfh_indir(struct net_device *dev, u32 *ring_index) 567static int mlx4_en_get_rxfh(struct net_device *dev, u32 *ring_index, u8 *key)
568{ 568{
569 struct mlx4_en_priv *priv = netdev_priv(dev); 569 struct mlx4_en_priv *priv = netdev_priv(dev);
570 struct mlx4_en_rss_map *rss_map = &priv->rss_map; 570 struct mlx4_en_rss_map *rss_map = &priv->rss_map;
@@ -582,8 +582,8 @@ static int mlx4_en_get_rxfh_indir(struct net_device *dev, u32 *ring_index)
582 return err; 582 return err;
583} 583}
584 584
585static int mlx4_en_set_rxfh_indir(struct net_device *dev, 585static int mlx4_en_set_rxfh(struct net_device *dev, const u32 *ring_index,
586 const u32 *ring_index) 586 const u8 *key)
587{ 587{
588 struct mlx4_en_priv *priv = netdev_priv(dev); 588 struct mlx4_en_priv *priv = netdev_priv(dev);
589 struct mlx4_en_dev *mdev = priv->mdev; 589 struct mlx4_en_dev *mdev = priv->mdev;
@@ -1224,8 +1224,8 @@ const struct ethtool_ops mlx4_en_ethtool_ops = {
1224 .get_rxnfc = mlx4_en_get_rxnfc, 1224 .get_rxnfc = mlx4_en_get_rxnfc,
1225 .set_rxnfc = mlx4_en_set_rxnfc, 1225 .set_rxnfc = mlx4_en_set_rxnfc,
1226 .get_rxfh_indir_size = mlx4_en_get_rxfh_indir_size, 1226 .get_rxfh_indir_size = mlx4_en_get_rxfh_indir_size,
1227 .get_rxfh_indir = mlx4_en_get_rxfh_indir, 1227 .get_rxfh = mlx4_en_get_rxfh,
1228 .set_rxfh_indir = mlx4_en_set_rxfh_indir, 1228 .set_rxfh = mlx4_en_set_rxfh,
1229 .get_channels = mlx4_en_get_channels, 1229 .get_channels = mlx4_en_get_channels,
1230 .set_channels = mlx4_en_set_channels, 1230 .set_channels = mlx4_en_set_channels,
1231 .get_ts_info = mlx4_en_get_ts_info, 1231 .get_ts_info = mlx4_en_get_ts_info,
diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c
index 0de8b07c24c2..74739c4b9997 100644
--- a/drivers/net/ethernet/sfc/ethtool.c
+++ b/drivers/net/ethernet/sfc/ethtool.c
@@ -1033,7 +1033,7 @@ static u32 efx_ethtool_get_rxfh_indir_size(struct net_device *net_dev)
1033 0 : ARRAY_SIZE(efx->rx_indir_table)); 1033 0 : ARRAY_SIZE(efx->rx_indir_table));
1034} 1034}
1035 1035
1036static int efx_ethtool_get_rxfh_indir(struct net_device *net_dev, u32 *indir) 1036static int efx_ethtool_get_rxfh(struct net_device *net_dev, u32 *indir, u8 *key)
1037{ 1037{
1038 struct efx_nic *efx = netdev_priv(net_dev); 1038 struct efx_nic *efx = netdev_priv(net_dev);
1039 1039
@@ -1041,8 +1041,8 @@ static int efx_ethtool_get_rxfh_indir(struct net_device *net_dev, u32 *indir)
1041 return 0; 1041 return 0;
1042} 1042}
1043 1043
1044static int efx_ethtool_set_rxfh_indir(struct net_device *net_dev, 1044static int efx_ethtool_set_rxfh(struct net_device *net_dev,
1045 const u32 *indir) 1045 const u32 *indir, const u8 *key)
1046{ 1046{
1047 struct efx_nic *efx = netdev_priv(net_dev); 1047 struct efx_nic *efx = netdev_priv(net_dev);
1048 1048
@@ -1125,8 +1125,8 @@ const struct ethtool_ops efx_ethtool_ops = {
1125 .get_rxnfc = efx_ethtool_get_rxnfc, 1125 .get_rxnfc = efx_ethtool_get_rxnfc,
1126 .set_rxnfc = efx_ethtool_set_rxnfc, 1126 .set_rxnfc = efx_ethtool_set_rxnfc,
1127 .get_rxfh_indir_size = efx_ethtool_get_rxfh_indir_size, 1127 .get_rxfh_indir_size = efx_ethtool_get_rxfh_indir_size,
1128 .get_rxfh_indir = efx_ethtool_get_rxfh_indir, 1128 .get_rxfh = efx_ethtool_get_rxfh,
1129 .set_rxfh_indir = efx_ethtool_set_rxfh_indir, 1129 .set_rxfh = efx_ethtool_set_rxfh,
1130 .get_ts_info = efx_ethtool_get_ts_info, 1130 .get_ts_info = efx_ethtool_get_ts_info,
1131 .get_module_info = efx_ethtool_get_module_info, 1131 .get_module_info = efx_ethtool_get_module_info,
1132 .get_module_eeprom = efx_ethtool_get_module_eeprom, 1132 .get_module_eeprom = efx_ethtool_get_module_eeprom,
diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c
index 00e120296e92..9396cca93b09 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethtool.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c
@@ -579,7 +579,7 @@ vmxnet3_get_rss_indir_size(struct net_device *netdev)
579} 579}
580 580
581static int 581static int
582vmxnet3_get_rss_indir(struct net_device *netdev, u32 *p) 582vmxnet3_get_rss(struct net_device *netdev, u32 *p, u8 *key)
583{ 583{
584 struct vmxnet3_adapter *adapter = netdev_priv(netdev); 584 struct vmxnet3_adapter *adapter = netdev_priv(netdev);
585 struct UPT1_RSSConf *rssConf = adapter->rss_conf; 585 struct UPT1_RSSConf *rssConf = adapter->rss_conf;
@@ -592,7 +592,7 @@ vmxnet3_get_rss_indir(struct net_device *netdev, u32 *p)
592} 592}
593 593
594static int 594static int
595vmxnet3_set_rss_indir(struct net_device *netdev, const u32 *p) 595vmxnet3_set_rss(struct net_device *netdev, const u32 *p, const u8 *key)
596{ 596{
597 unsigned int i; 597 unsigned int i;
598 unsigned long flags; 598 unsigned long flags;
@@ -628,8 +628,8 @@ static const struct ethtool_ops vmxnet3_ethtool_ops = {
628 .get_rxnfc = vmxnet3_get_rxnfc, 628 .get_rxnfc = vmxnet3_get_rxnfc,
629#ifdef VMXNET3_RSS 629#ifdef VMXNET3_RSS
630 .get_rxfh_indir_size = vmxnet3_get_rss_indir_size, 630 .get_rxfh_indir_size = vmxnet3_get_rss_indir_size,
631 .get_rxfh_indir = vmxnet3_get_rss_indir, 631 .get_rxfh = vmxnet3_get_rss,
632 .set_rxfh_indir = vmxnet3_set_rss_indir, 632 .set_rxfh = vmxnet3_set_rss,
633#endif 633#endif
634}; 634};
635 635
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 212f537fc686..e658229fee39 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -158,19 +158,16 @@ static inline u32 ethtool_rxfh_indir_default(u32 index, u32 n_rx_rings)
158 * Returns zero if not supported for this specific device. 158 * Returns zero if not supported for this specific device.
159 * @get_rxfh_indir_size: Get the size of the RX flow hash indirection table. 159 * @get_rxfh_indir_size: Get the size of the RX flow hash indirection table.
160 * Returns zero if not supported for this specific device. 160 * Returns zero if not supported for this specific device.
161 * @get_rxfh_indir: Get the contents of the RX flow hash indirection table.
162 * Will not be called if @get_rxfh_indir_size returns zero.
163 * @get_rxfh: Get the contents of the RX flow hash indirection table and hash 161 * @get_rxfh: Get the contents of the RX flow hash indirection table and hash
164 * key. 162 * key.
165 * Will not be called if @get_rxfh_indir_size and @get_rxfh_key_size 163 * Will only be called if one or both of @get_rxfh_indir_size and
166 * returns zero. 164 * @get_rxfh_key_size are implemented and return non-zero.
167 * Returns a negative error code or zero. 165 * Returns a negative error code or zero.
168 * @set_rxfh_indir: Set the contents of the RX flow hash indirection table. 166 * @set_rxfh: Set the contents of the RX flow hash indirection table and/or
169 * Will not be called if @get_rxfh_indir_size returns zero. 167 * hash key. In case only the indirection table or hash key is to be
170 * @set_rxfh: Set the contents of the RX flow hash indirection table and 168 * changed, the other argument will be %NULL.
171 * hash key. 169 * Will only be called if one or both of @get_rxfh_indir_size and
172 * Will not be called if @get_rxfh_indir_size and @get_rxfh_key_size 170 * @get_rxfh_key_size are implemented and return non-zero.
173 * returns zero.
174 * Returns a negative error code or zero. 171 * Returns a negative error code or zero.
175 * @get_channels: Get number of channels. 172 * @get_channels: Get number of channels.
176 * @set_channels: Set number of channels. Returns a negative error code or 173 * @set_channels: Set number of channels. Returns a negative error code or
@@ -244,10 +241,9 @@ struct ethtool_ops {
244 int (*reset)(struct net_device *, u32 *); 241 int (*reset)(struct net_device *, u32 *);
245 u32 (*get_rxfh_key_size)(struct net_device *); 242 u32 (*get_rxfh_key_size)(struct net_device *);
246 u32 (*get_rxfh_indir_size)(struct net_device *); 243 u32 (*get_rxfh_indir_size)(struct net_device *);
247 int (*get_rxfh)(struct net_device *, u32 *, u8 *); 244 int (*get_rxfh)(struct net_device *, u32 *indir, u8 *key);
248 int (*set_rxfh)(struct net_device *, u32 *, u8 *); 245 int (*set_rxfh)(struct net_device *, const u32 *indir,
249 int (*get_rxfh_indir)(struct net_device *, u32 *); 246 const u8 *key);
250 int (*set_rxfh_indir)(struct net_device *, const u32 *);
251 void (*get_channels)(struct net_device *, struct ethtool_channels *); 247 void (*get_channels)(struct net_device *, struct ethtool_channels *);
252 int (*set_channels)(struct net_device *, struct ethtool_channels *); 248 int (*set_channels)(struct net_device *, struct ethtool_channels *);
253 int (*get_dump_flag)(struct net_device *, struct ethtool_dump *); 249 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 d47d31d6fa0e..e3c7a719c76b 100644
--- a/include/uapi/linux/ethtool.h
+++ b/include/uapi/linux/ethtool.h
@@ -850,21 +850,23 @@ struct ethtool_rxfh_indir {
850 * struct ethtool_rxfh - command to get/set RX flow hash indir or/and hash key. 850 * struct ethtool_rxfh - command to get/set RX flow hash indir or/and hash key.
851 * @cmd: Specific command number - %ETHTOOL_GRSSH or %ETHTOOL_SRSSH 851 * @cmd: Specific command number - %ETHTOOL_GRSSH or %ETHTOOL_SRSSH
852 * @rss_context: RSS context identifier. 852 * @rss_context: RSS context identifier.
853 * @indir_size: On entry, the array size of the user buffer, which may be zero. 853 * @indir_size: On entry, the array size of the user buffer for the
854 * On return from %ETHTOOL_GRSSH, the array size of the hardware 854 * indirection table, which may be zero, or (for %ETHTOOL_SRSSH),
855 * indirection table. 855 * %ETH_RXFH_INDIR_NO_CHANGE. On return from %ETHTOOL_GRSSH,
856 * @key_size: On entry, the array size of the user buffer in bytes, 856 * the array size of the hardware indirection table.
857 * which may be zero. 857 * @key_size: On entry, the array size of the user buffer for the hash key,
858 * On return from %ETHTOOL_GRSSH, the size of the RSS hash key. 858 * which may be zero. On return from %ETHTOOL_GRSSH, the size of the
859 * hardware hash key.
859 * @rsvd: Reserved for future extensions. 860 * @rsvd: Reserved for future extensions.
860 * @rss_config: RX ring/queue index for each hash value i.e., indirection table 861 * @rss_config: RX ring/queue index for each hash value i.e., indirection table
861 * of size @indir_size followed by hash key of size @key_size. 862 * of @indir_size __u32 elements, followed by hash key of @key_size
863 * bytes.
862 * 864 *
863 * For %ETHTOOL_GRSSH, a @indir_size and key_size of zero means that only the 865 * For %ETHTOOL_GRSSH, a @indir_size and key_size of zero means that only the
864 * size should be returned. For %ETHTOOL_SRSSH, a @indir_size of 0xDEADBEEF 866 * size should be returned. For %ETHTOOL_SRSSH, an @indir_size of
865 * means that indir table setting is not requested and a @indir_size of zero 867 * %ETH_RXFH_INDIR_NO_CHANGE means that indir table setting is not requested
866 * means the indir table should be reset to default values. This last feature 868 * and a @indir_size of zero means the indir table should be reset to default
867 * is not supported by the original implementations. 869 * values.
868 */ 870 */
869struct ethtool_rxfh { 871struct ethtool_rxfh {
870 __u32 cmd; 872 __u32 cmd;
@@ -874,6 +876,7 @@ struct ethtool_rxfh {
874 __u32 rsvd[2]; 876 __u32 rsvd[2];
875 __u32 rss_config[0]; 877 __u32 rss_config[0];
876}; 878};
879#define ETH_RXFH_INDIR_NO_CHANGE 0xffffffff
877 880
878/** 881/**
879 * struct ethtool_rx_ntuple_flow_spec - specification for RX flow filter 882 * struct ethtool_rx_ntuple_flow_spec - specification for RX flow filter
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index aa8978ac47d2..17cb912793fa 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -561,19 +561,17 @@ static int ethtool_copy_validate_indir(u32 *indir, void __user *useraddr,
561 struct ethtool_rxnfc *rx_rings, 561 struct ethtool_rxnfc *rx_rings,
562 u32 size) 562 u32 size)
563{ 563{
564 int ret = 0, i; 564 int i;
565 565
566 if (copy_from_user(indir, useraddr, size * sizeof(indir[0]))) 566 if (copy_from_user(indir, useraddr, size * sizeof(indir[0])))
567 ret = -EFAULT; 567 return -EFAULT;
568 568
569 /* Validate ring indices */ 569 /* Validate ring indices */
570 for (i = 0; i < size; i++) { 570 for (i = 0; i < size; i++)
571 if (indir[i] >= rx_rings->data) { 571 if (indir[i] >= rx_rings->data)
572 ret = -EINVAL; 572 return -EINVAL;
573 break; 573
574 } 574 return 0;
575 }
576 return ret;
577} 575}
578 576
579static noinline_for_stack int ethtool_get_rxfh_indir(struct net_device *dev, 577static noinline_for_stack int ethtool_get_rxfh_indir(struct net_device *dev,
@@ -584,7 +582,7 @@ static noinline_for_stack int ethtool_get_rxfh_indir(struct net_device *dev,
584 int ret; 582 int ret;
585 583
586 if (!dev->ethtool_ops->get_rxfh_indir_size || 584 if (!dev->ethtool_ops->get_rxfh_indir_size ||
587 !dev->ethtool_ops->get_rxfh_indir) 585 !dev->ethtool_ops->get_rxfh)
588 return -EOPNOTSUPP; 586 return -EOPNOTSUPP;
589 dev_size = dev->ethtool_ops->get_rxfh_indir_size(dev); 587 dev_size = dev->ethtool_ops->get_rxfh_indir_size(dev);
590 if (dev_size == 0) 588 if (dev_size == 0)
@@ -610,7 +608,7 @@ static noinline_for_stack int ethtool_get_rxfh_indir(struct net_device *dev,
610 if (!indir) 608 if (!indir)
611 return -ENOMEM; 609 return -ENOMEM;
612 610
613 ret = dev->ethtool_ops->get_rxfh_indir(dev, indir); 611 ret = dev->ethtool_ops->get_rxfh(dev, indir, NULL);
614 if (ret) 612 if (ret)
615 goto out; 613 goto out;
616 614
@@ -634,7 +632,7 @@ static noinline_for_stack int ethtool_set_rxfh_indir(struct net_device *dev,
634 int ret; 632 int ret;
635 u32 ringidx_offset = offsetof(struct ethtool_rxfh_indir, ring_index[0]); 633 u32 ringidx_offset = offsetof(struct ethtool_rxfh_indir, ring_index[0]);
636 634
637 if (!ops->get_rxfh_indir_size || !ops->set_rxfh_indir || 635 if (!ops->get_rxfh_indir_size || !ops->set_rxfh ||
638 !ops->get_rxnfc) 636 !ops->get_rxnfc)
639 return -EOPNOTSUPP; 637 return -EOPNOTSUPP;
640 638
@@ -671,7 +669,7 @@ static noinline_for_stack int ethtool_set_rxfh_indir(struct net_device *dev,
671 goto out; 669 goto out;
672 } 670 }
673 671
674 ret = ops->set_rxfh_indir(dev, indir); 672 ret = ops->set_rxfh(dev, indir, NULL);
675 673
676out: 674out:
677 kfree(indir); 675 kfree(indir);
@@ -683,11 +681,11 @@ static noinline_for_stack int ethtool_get_rxfh(struct net_device *dev,
683{ 681{
684 int ret; 682 int ret;
685 const struct ethtool_ops *ops = dev->ethtool_ops; 683 const struct ethtool_ops *ops = dev->ethtool_ops;
686 u32 user_indir_size = 0, user_key_size = 0; 684 u32 user_indir_size, user_key_size;
687 u32 dev_indir_size = 0, dev_key_size = 0; 685 u32 dev_indir_size = 0, dev_key_size = 0;
686 struct ethtool_rxfh rxfh;
688 u32 total_size; 687 u32 total_size;
689 u32 indir_offset, indir_bytes; 688 u32 indir_bytes;
690 u32 key_offset;
691 u32 *indir = NULL; 689 u32 *indir = NULL;
692 u8 *hkey = NULL; 690 u8 *hkey = NULL;
693 u8 *rss_config; 691 u8 *rss_config;
@@ -699,33 +697,24 @@ static noinline_for_stack int ethtool_get_rxfh(struct net_device *dev,
699 697
700 if (ops->get_rxfh_indir_size) 698 if (ops->get_rxfh_indir_size)
701 dev_indir_size = ops->get_rxfh_indir_size(dev); 699 dev_indir_size = ops->get_rxfh_indir_size(dev);
702
703 indir_offset = offsetof(struct ethtool_rxfh, indir_size);
704
705 if (copy_from_user(&user_indir_size,
706 useraddr + indir_offset,
707 sizeof(user_indir_size)))
708 return -EFAULT;
709
710 if (copy_to_user(useraddr + indir_offset,
711 &dev_indir_size, sizeof(dev_indir_size)))
712 return -EFAULT;
713
714 if (ops->get_rxfh_key_size) 700 if (ops->get_rxfh_key_size)
715 dev_key_size = ops->get_rxfh_key_size(dev); 701 dev_key_size = ops->get_rxfh_key_size(dev);
716 702
717 if ((dev_key_size + dev_indir_size) == 0) 703 if ((dev_key_size + dev_indir_size) == 0)
718 return -EOPNOTSUPP; 704 return -EOPNOTSUPP;
719 705
720 key_offset = offsetof(struct ethtool_rxfh, key_size); 706 if (copy_from_user(&rxfh, useraddr, sizeof(rxfh)))
721
722 if (copy_from_user(&user_key_size,
723 useraddr + key_offset,
724 sizeof(user_key_size)))
725 return -EFAULT; 707 return -EFAULT;
708 user_indir_size = rxfh.indir_size;
709 user_key_size = rxfh.key_size;
726 710
727 if (copy_to_user(useraddr + key_offset, 711 /* Check that reserved fields are 0 for now */
728 &dev_key_size, sizeof(dev_key_size))) 712 if (rxfh.rss_context || rxfh.rsvd[0] || rxfh.rsvd[1])
713 return -EINVAL;
714
715 rxfh.indir_size = dev_indir_size;
716 rxfh.key_size = dev_key_size;
717 if (copy_to_user(useraddr, &rxfh, sizeof(rxfh)))
729 return -EFAULT; 718 return -EFAULT;
730 719
731 /* If the user buffer size is 0, this is just a query for the 720 /* If the user buffer size is 0, this is just a query for the
@@ -770,12 +759,11 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
770 int ret; 759 int ret;
771 const struct ethtool_ops *ops = dev->ethtool_ops; 760 const struct ethtool_ops *ops = dev->ethtool_ops;
772 struct ethtool_rxnfc rx_rings; 761 struct ethtool_rxnfc rx_rings;
773 u32 user_indir_size = 0, dev_indir_size = 0, i; 762 struct ethtool_rxfh rxfh;
774 u32 user_key_size = 0, dev_key_size = 0; 763 u32 dev_indir_size = 0, dev_key_size = 0, i;
775 u32 *indir = NULL, indir_bytes = 0; 764 u32 *indir = NULL, indir_bytes = 0;
776 u8 *hkey = NULL; 765 u8 *hkey = NULL;
777 u8 *rss_config; 766 u8 *rss_config;
778 u32 indir_offset, key_offset;
779 u32 rss_cfg_offset = offsetof(struct ethtool_rxfh, rss_config[0]); 767 u32 rss_cfg_offset = offsetof(struct ethtool_rxfh, rss_config[0]);
780 768
781 if (!(ops->get_rxfh_indir_size || ops->get_rxfh_key_size) || 769 if (!(ops->get_rxfh_indir_size || ops->get_rxfh_key_size) ||
@@ -784,36 +772,33 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
784 772
785 if (ops->get_rxfh_indir_size) 773 if (ops->get_rxfh_indir_size)
786 dev_indir_size = ops->get_rxfh_indir_size(dev); 774 dev_indir_size = ops->get_rxfh_indir_size(dev);
787
788 indir_offset = offsetof(struct ethtool_rxfh, indir_size);
789 if (copy_from_user(&user_indir_size,
790 useraddr + indir_offset,
791 sizeof(user_indir_size)))
792 return -EFAULT;
793
794 if (ops->get_rxfh_key_size) 775 if (ops->get_rxfh_key_size)
795 dev_key_size = dev->ethtool_ops->get_rxfh_key_size(dev); 776 dev_key_size = dev->ethtool_ops->get_rxfh_key_size(dev);
796
797 if ((dev_key_size + dev_indir_size) == 0) 777 if ((dev_key_size + dev_indir_size) == 0)
798 return -EOPNOTSUPP; 778 return -EOPNOTSUPP;
799 779
800 key_offset = offsetof(struct ethtool_rxfh, key_size); 780 if (copy_from_user(&rxfh, useraddr, sizeof(rxfh)))
801 if (copy_from_user(&user_key_size,
802 useraddr + key_offset,
803 sizeof(user_key_size)))
804 return -EFAULT; 781 return -EFAULT;
805 782
783 /* Check that reserved fields are 0 for now */
784 if (rxfh.rss_context || rxfh.rsvd[0] || rxfh.rsvd[1])
785 return -EINVAL;
786
806 /* If either indir or hash key is valid, proceed further. 787 /* If either indir or hash key is valid, proceed further.
788 * It is not valid to request that both be unchanged.
807 */ 789 */
808 if ((user_indir_size && ((user_indir_size != 0xDEADBEEF) && 790 if ((rxfh.indir_size &&
809 user_indir_size != dev_indir_size)) || 791 rxfh.indir_size != ETH_RXFH_INDIR_NO_CHANGE &&
810 (user_key_size && (user_key_size != dev_key_size))) 792 rxfh.indir_size != dev_indir_size) ||
793 (rxfh.key_size && (rxfh.key_size != dev_key_size)) ||
794 (rxfh.indir_size == ETH_RXFH_INDIR_NO_CHANGE &&
795 rxfh.key_size == 0))
811 return -EINVAL; 796 return -EINVAL;
812 797
813 if (user_indir_size != 0xDEADBEEF) 798 if (rxfh.indir_size != ETH_RXFH_INDIR_NO_CHANGE)
814 indir_bytes = dev_indir_size * sizeof(indir[0]); 799 indir_bytes = dev_indir_size * sizeof(indir[0]);
815 800
816 rss_config = kzalloc(indir_bytes + user_key_size, GFP_USER); 801 rss_config = kzalloc(indir_bytes + rxfh.key_size, GFP_USER);
817 if (!rss_config) 802 if (!rss_config)
818 return -ENOMEM; 803 return -ENOMEM;
819 804
@@ -822,28 +807,29 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
822 if (ret) 807 if (ret)
823 goto out; 808 goto out;
824 809
825 /* user_indir_size == 0 means reset the indir table to default. 810 /* rxfh.indir_size == 0 means reset the indir table to default.
826 * user_indir_size == 0xDEADBEEF means indir setting is not requested. 811 * rxfh.indir_size == ETH_RXFH_INDIR_NO_CHANGE means leave it unchanged.
827 */ 812 */
828 if (user_indir_size && user_indir_size != 0xDEADBEEF) { 813 if (rxfh.indir_size &&
814 rxfh.indir_size != ETH_RXFH_INDIR_NO_CHANGE) {
829 indir = (u32 *)rss_config; 815 indir = (u32 *)rss_config;
830 ret = ethtool_copy_validate_indir(indir, 816 ret = ethtool_copy_validate_indir(indir,
831 useraddr + rss_cfg_offset, 817 useraddr + rss_cfg_offset,
832 &rx_rings, 818 &rx_rings,
833 user_indir_size); 819 rxfh.indir_size);
834 if (ret) 820 if (ret)
835 goto out; 821 goto out;
836 } else if (user_indir_size == 0) { 822 } else if (rxfh.indir_size == 0) {
837 indir = (u32 *)rss_config; 823 indir = (u32 *)rss_config;
838 for (i = 0; i < dev_indir_size; i++) 824 for (i = 0; i < dev_indir_size; i++)
839 indir[i] = ethtool_rxfh_indir_default(i, rx_rings.data); 825 indir[i] = ethtool_rxfh_indir_default(i, rx_rings.data);
840 } 826 }
841 827
842 if (user_key_size) { 828 if (rxfh.key_size) {
843 hkey = rss_config + indir_bytes; 829 hkey = rss_config + indir_bytes;
844 if (copy_from_user(hkey, 830 if (copy_from_user(hkey,
845 useraddr + rss_cfg_offset + indir_bytes, 831 useraddr + rss_cfg_offset + indir_bytes,
846 user_key_size)) { 832 rxfh.key_size)) {
847 ret = -EFAULT; 833 ret = -EFAULT;
848 goto out; 834 goto out;
849 } 835 }