i40evf: add new fields to store user configuration of RSS
authorHelin Zhang <helin.zhang@intel.com>
Mon, 26 Oct 2015 23:44:34 +0000 (19:44 -0400)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Wed, 2 Dec 2015 06:50:36 +0000 (22:50 -0800)
This patch adds new fields to i40e_vsi to store user configured
RSS config data and code to use it.

Change-ID: Ic5d3db8d9df52182b560248f8cdca9c5c7546879
Signed-off-by: Helin Zhang <helin.zhang@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/i40evf/i40evf.h
drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
drivers/net/ethernet/intel/i40evf/i40evf_main.c

index 5f2e61dc20ec5c9cad07f1d2380e0667949bded0..090c6048f0df095453ba349ec12603731736f202 100644 (file)
@@ -67,6 +67,8 @@ struct i40e_vsi {
        u16 rx_itr_setting;
        u16 tx_itr_setting;
        u16 qs_handle;
+       u8 *rss_hkey_user; /* User configured hash keys */
+       u8 *rss_lut_user;  /* User configured lookup table entries */
 };
 
 /* How many Rx Buffers do we bundle into one write to the hardware ? */
index a5209707bcf3df0bb80fe5c44f705dda1a84b934..966863c93dc445c1f0863fc045a405c3c81fe82b 100644 (file)
@@ -678,9 +678,7 @@ static int i40evf_set_rxfh(struct net_device *netdev, const u32 *indir,
 {
        struct i40evf_adapter *adapter = netdev_priv(netdev);
        struct i40e_vsi *vsi = &adapter->vsi;
-       u8 seed_def[I40EVF_HKEY_ARRAY_SIZE];
-       u8 *seed = NULL, *lut;
-       int ret;
+       u8 *seed = NULL;
        u16 i;
 
        /* We do not allow change in unsupported parameters */
@@ -691,21 +689,28 @@ static int i40evf_set_rxfh(struct net_device *netdev, const u32 *indir,
                return 0;
 
        if (key) {
-               memcpy(seed_def, key, I40EVF_HKEY_ARRAY_SIZE);
-               seed = seed_def;
+               if (!vsi->rss_hkey_user) {
+                       vsi->rss_hkey_user = kzalloc(I40EVF_HKEY_ARRAY_SIZE,
+                                                    GFP_KERNEL);
+                       if (!vsi->rss_hkey_user)
+                               return -ENOMEM;
+               }
+               memcpy(vsi->rss_hkey_user, key, I40EVF_HKEY_ARRAY_SIZE);
+               seed = vsi->rss_hkey_user;
+       }
+       if (!vsi->rss_lut_user) {
+               vsi->rss_lut_user = kzalloc(I40EVF_HLUT_ARRAY_SIZE,
+                                           GFP_KERNEL);
+               if (!vsi->rss_lut_user)
+                       return -ENOMEM;
        }
-       lut = kzalloc(I40EVF_HLUT_ARRAY_SIZE, GFP_KERNEL);
-       if (!lut)
-               return -ENOMEM;
 
        /* Each 32 bits pointed by 'indir' is stored with a lut entry */
        for (i = 0; i < I40EVF_HLUT_ARRAY_SIZE; i++)
-               lut[i] = (u8)(indir[i]);
+               vsi->rss_lut_user[i] = (u8)(indir[i]);
 
-       ret = i40evf_config_rss(vsi, seed, lut, I40EVF_HLUT_ARRAY_SIZE);
-       kfree(lut);
-
-       return ret;
+       return i40evf_config_rss(vsi, seed, vsi->rss_lut_user,
+                                I40EVF_HLUT_ARRAY_SIZE);
 }
 
 static const struct ethtool_ops i40evf_ethtool_ops = {
index 68251fa081ec907a0a174ebb4ff7b58a8c475fd1..1cd5d5d1b6603efeab20af633524e13bf868ae4a 100644 (file)
@@ -1453,9 +1453,21 @@ static int i40evf_init_rss(struct i40evf_adapter *adapter)
        lut = kzalloc(I40EVF_HLUT_ARRAY_SIZE, GFP_KERNEL);
        if (!lut)
                return -ENOMEM;
-       i40evf_fill_rss_lut(lut, I40EVF_HLUT_ARRAY_SIZE,
-                           adapter->num_active_queues);
-       netdev_rss_key_fill((void *)seed, I40EVF_HKEY_ARRAY_SIZE);
+
+       /* Use user configured lut if there is one, otherwise use default */
+       if (vsi->rss_lut_user)
+               memcpy(lut, vsi->rss_lut_user, I40EVF_HLUT_ARRAY_SIZE);
+       else
+               i40evf_fill_rss_lut(lut, I40EVF_HLUT_ARRAY_SIZE,
+                                   adapter->num_active_queues);
+
+       /* Use user configured hash key if there is one, otherwise
+        * user default.
+        */
+       if (vsi->rss_hkey_user)
+               memcpy(seed, vsi->rss_hkey_user, I40EVF_HKEY_ARRAY_SIZE);
+       else
+               netdev_rss_key_fill((void *)seed, I40EVF_HKEY_ARRAY_SIZE);
        ret = i40evf_config_rss(vsi, seed, lut, I40EVF_HLUT_ARRAY_SIZE);
        kfree(lut);
 
@@ -1582,6 +1594,22 @@ err_set_interrupt:
        return err;
 }
 
+/**
+ * i40evf_clear_rss_config_user - Clear user configurations of RSS
+ * @vsi: Pointer to VSI structure
+ **/
+static void i40evf_clear_rss_config_user(struct i40e_vsi *vsi)
+{
+       if (!vsi)
+               return;
+
+       kfree(vsi->rss_hkey_user);
+       vsi->rss_hkey_user = NULL;
+
+       kfree(vsi->rss_lut_user);
+       vsi->rss_lut_user = NULL;
+}
+
 /**
  * i40evf_watchdog_timer - Periodic call-back timer
  * @data: pointer to adapter disguised as unsigned long
@@ -2770,6 +2798,9 @@ static void i40evf_remove(struct pci_dev *pdev)
 
        flush_scheduled_work();
 
+       /* Clear user configurations for RSS */
+       i40evf_clear_rss_config_user(&adapter->vsi);
+
        if (hw->aq.asq.count)
                i40evf_shutdown_adminq(hw);