Change igc_ethtool_set_rxfh() to accept and save a userspace-provided RSS key. When a key is provided, store it in the adapter and write the RSSRK registers accordingly. This can be tested using `ethtool -X hkey `. Signed-off-by: Kohei Enju --- drivers/net/ethernet/intel/igc/igc.h | 1 + drivers/net/ethernet/intel/igc/igc_ethtool.c | 31 ++++++++++++-------- drivers/net/ethernet/intel/igc/igc_main.c | 3 +- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h index dd159397d191..c894a5a99fc0 100644 --- a/drivers/net/ethernet/intel/igc/igc.h +++ b/drivers/net/ethernet/intel/igc/igc.h @@ -304,6 +304,7 @@ struct igc_adapter { u8 rss_indir_tbl[IGC_RETA_SIZE]; u8 rss_key[IGC_RSS_KEY_SIZE]; + bool has_user_rss_key; unsigned long link_check_timeout; struct igc_info ei; diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c index 0482e590bc5a..64eac1ccb3ff 100644 --- a/drivers/net/ethernet/intel/igc/igc_ethtool.c +++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c @@ -1527,24 +1527,29 @@ static int igc_ethtool_set_rxfh(struct net_device *netdev, int i; /* We do not allow change in unsupported parameters */ - if (rxfh->key || - (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE && - rxfh->hfunc != ETH_RSS_HASH_TOP)) + if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE && + rxfh->hfunc != ETH_RSS_HASH_TOP) return -EOPNOTSUPP; - if (!rxfh->indir) - return 0; - num_queues = adapter->rss_queues; + if (rxfh->indir) { + num_queues = adapter->rss_queues; - /* Verify user input. */ - for (i = 0; i < IGC_RETA_SIZE; i++) - if (rxfh->indir[i] >= num_queues) - return -EINVAL; + /* Verify user input. */ + for (i = 0; i < IGC_RETA_SIZE; i++) + if (rxfh->indir[i] >= num_queues) + return -EINVAL; - for (i = 0; i < IGC_RETA_SIZE; i++) - adapter->rss_indir_tbl[i] = rxfh->indir[i]; + for (i = 0; i < IGC_RETA_SIZE; i++) + adapter->rss_indir_tbl[i] = rxfh->indir[i]; - igc_write_rss_indir_tbl(adapter); + igc_write_rss_indir_tbl(adapter); + } + + if (rxfh->key) { + adapter->has_user_rss_key = true; + memcpy(adapter->rss_key, rxfh->key, sizeof(adapter->rss_key)); + igc_write_rss_key(adapter); + } return 0; } diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c index 1f0a601cbcef..e977661bed2f 100644 --- a/drivers/net/ethernet/intel/igc/igc_main.c +++ b/drivers/net/ethernet/intel/igc/igc_main.c @@ -779,7 +779,8 @@ static void igc_setup_mrqc(struct igc_adapter *adapter) u32 j, num_rx_queues; u32 mrqc, rxcsum; - netdev_rss_key_fill(adapter->rss_key, sizeof(adapter->rss_key)); + if (!adapter->has_user_rss_key) + netdev_rss_key_fill(adapter->rss_key, sizeof(adapter->rss_key)); igc_write_rss_key(adapter); num_rx_queues = adapter->rss_queues; -- 2.51.0