i40e: create a generic configure rss function
authorHelin Zhang <helin.zhang@intel.com>
Wed, 21 Oct 2015 23:56:23 +0000 (19:56 -0400)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Wed, 25 Nov 2015 18:05:58 +0000 (10:05 -0800)
This patch renames the old pf-specific function in order to clarify
its scope. This patch also creates a more generic configure RSS
function with the old name.

This patch also creates a new more generic function to get RSS
configuration, using the appropriate method.

Change-ID: Ieddca2707b708ef19f1ebccdfd03a0a0cd63d3af
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/i40e/i40e.h
drivers/net/ethernet/intel/i40e/i40e_ethtool.c
drivers/net/ethernet/intel/i40e/i40e_main.c

index f6b747cf94d6ee07b744a94551f3918b46c2a2dd..89f5323362ed9b85050db8454f26a640085617a4 100644 (file)
@@ -670,6 +670,8 @@ extern const char i40e_driver_name[];
 extern const char i40e_driver_version_str[];
 void i40e_do_reset_safe(struct i40e_pf *pf, u32 reset_flags);
 void i40e_do_reset(struct i40e_pf *pf, u32 reset_flags);
+int i40e_config_rss(struct i40e_vsi *vsi, u8 *seed, u8 *lut, u16 lut_size);
+int i40e_get_rss(struct i40e_vsi *vsi, u8 *seed, u8 *lut, u16 lut_size);
 struct i40e_vsi *i40e_find_vsi_from_id(struct i40e_pf *pf, u16 id);
 void i40e_update_stats(struct i40e_vsi *vsi);
 void i40e_update_eth_stats(struct i40e_vsi *vsi);
index f26c0d16e43e4bb6054ae11275115a9901c4d1ec..6cb2b340cdc2a7827d4d10bd44fbf421d0b48b9e 100644 (file)
@@ -2611,10 +2611,9 @@ static int i40e_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
 {
        struct i40e_netdev_priv *np = netdev_priv(netdev);
        struct i40e_vsi *vsi = np->vsi;
-       struct i40e_pf *pf = vsi->back;
-       struct i40e_hw *hw = &pf->hw;
-       u32 reg_val;
-       int i, j;
+       u8 *lut, *seed = NULL;
+       int ret;
+       u16 i;
 
        if (hfunc)
                *hfunc = ETH_RSS_HASH_TOP;
@@ -2622,24 +2621,20 @@ static int i40e_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
        if (!indir)
                return 0;
 
-       for (i = 0, j = 0; i <= I40E_PFQF_HLUT_MAX_INDEX; i++) {
-               reg_val = rd32(hw, I40E_PFQF_HLUT(i));
-               indir[j++] = reg_val & 0xff;
-               indir[j++] = (reg_val >> 8) & 0xff;
-               indir[j++] = (reg_val >> 16) & 0xff;
-               indir[j++] = (reg_val >> 24) & 0xff;
-       }
+       seed = key;
+       lut = kzalloc(I40E_HLUT_ARRAY_SIZE, GFP_KERNEL);
+       if (!lut)
+               return -ENOMEM;
+       ret = i40e_get_rss(vsi, seed, lut, I40E_HLUT_ARRAY_SIZE);
+       if (ret)
+               goto out;
+       for (i = 0; i < I40E_HLUT_ARRAY_SIZE; i++)
+               indir[i] = (u32)(lut[i]);
 
-       if (key) {
-               for (i = 0, j = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++) {
-                       reg_val = rd32(hw, I40E_PFQF_HKEY(i));
-                       key[j++] = (u8)(reg_val & 0xff);
-                       key[j++] = (u8)((reg_val >> 8) & 0xff);
-                       key[j++] = (u8)((reg_val >> 16) & 0xff);
-                       key[j++] = (u8)((reg_val >> 24) & 0xff);
-               }
-       }
-       return 0;
+out:
+       kfree(lut);
+
+       return ret;
 }
 
 /**
@@ -2656,10 +2651,10 @@ static int i40e_set_rxfh(struct net_device *netdev, const u32 *indir,
 {
        struct i40e_netdev_priv *np = netdev_priv(netdev);
        struct i40e_vsi *vsi = np->vsi;
-       struct i40e_pf *pf = vsi->back;
-       struct i40e_hw *hw = &pf->hw;
-       u32 reg_val;
-       int i, j;
+       u8 seed_def[I40E_HKEY_ARRAY_SIZE];
+       u8 *lut, *seed = NULL;
+       u16 i;
+       int ret;
 
        if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
                return -EOPNOTSUPP;
@@ -2667,24 +2662,19 @@ static int i40e_set_rxfh(struct net_device *netdev, const u32 *indir,
        if (!indir)
                return 0;
 
-       for (i = 0, j = 0; i <= I40E_PFQF_HLUT_MAX_INDEX; i++) {
-               reg_val = indir[j++];
-               reg_val |= indir[j++] << 8;
-               reg_val |= indir[j++] << 16;
-               reg_val |= indir[j++] << 24;
-               wr32(hw, I40E_PFQF_HLUT(i), reg_val);
-       }
-
        if (key) {
-               for (i = 0, j = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++) {
-                       reg_val = key[j++];
-                       reg_val |= key[j++] << 8;
-                       reg_val |= key[j++] << 16;
-                       reg_val |= key[j++] << 24;
-                       wr32(hw, I40E_PFQF_HKEY(i), reg_val);
-               }
+               memcpy(seed_def, key, I40E_HKEY_ARRAY_SIZE);
+               seed = seed_def;
        }
-       return 0;
+       lut = kzalloc(I40E_HLUT_ARRAY_SIZE, GFP_KERNEL);
+       if (!lut)
+               return -ENOMEM;
+       for (i = 0; i < I40E_HLUT_ARRAY_SIZE; i++)
+               lut[i] = (u8)(indir[i]);
+       ret = i40e_config_rss(vsi, seed, lut, I40E_HLUT_ARRAY_SIZE);
+       kfree(lut);
+
+       return ret;
 }
 
 /**
index 9fe68024d9711f5780b7d77faefd62f956e90303..84b196238b92e8fcab53150fd76db6ba4f5557b2 100644 (file)
@@ -7873,7 +7873,7 @@ static int i40e_vsi_config_rss(struct i40e_vsi *vsi)
 }
 
 /**
- * i40e_config_rss_reg - Prepare for RSS if used
+ * i40e_config_rss_reg - Configure RSS keys and lut by writing registers
  * @vsi: Pointer to vsi structure
  * @seed: RSS hash seed
  * @lut: Lookup table
@@ -7910,6 +7910,73 @@ static int i40e_config_rss_reg(struct i40e_vsi *vsi, const u8 *seed,
        return 0;
 }
 
+/**
+ * i40e_get_rss_reg - Get the RSS keys and lut by reading registers
+ * @vsi: Pointer to VSI structure
+ * @seed: Buffer to store the keys
+ * @lut: Buffer to store the lookup table entries
+ * @lut_size: Size of buffer to store the lookup table entries
+ *
+ * Returns 0 on success, negative on failure
+ */
+static int i40e_get_rss_reg(struct i40e_vsi *vsi, u8 *seed,
+                           u8 *lut, u16 lut_size)
+{
+       struct i40e_pf *pf = vsi->back;
+       struct i40e_hw *hw = &pf->hw;
+       u16 i;
+
+       if (seed) {
+               u32 *seed_dw = (u32 *)seed;
+
+               for (i = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++)
+                       seed_dw[i] = rd32(hw, I40E_PFQF_HKEY(i));
+       }
+       if (lut) {
+               u32 *lut_dw = (u32 *)lut;
+
+               if (lut_size != I40E_HLUT_ARRAY_SIZE)
+                       return -EINVAL;
+               for (i = 0; i <= I40E_PFQF_HLUT_MAX_INDEX; i++)
+                       lut_dw[i] = rd32(hw, I40E_PFQF_HLUT(i));
+       }
+
+       return 0;
+}
+
+/**
+ * i40e_config_rss - Configure RSS keys and lut
+ * @vsi: Pointer to VSI structure
+ * @seed: RSS hash seed
+ * @lut: Lookup table
+ * @lut_size: Lookup table size
+ *
+ * Returns 0 on success, negative on failure
+ */
+int i40e_config_rss(struct i40e_vsi *vsi, u8 *seed, u8 *lut, u16 lut_size)
+{
+       struct i40e_pf *pf = vsi->back;
+
+       if (pf->flags & I40E_FLAG_RSS_AQ_CAPABLE)
+               return i40e_config_rss_aq(vsi, seed, lut, lut_size);
+       else
+               return i40e_config_rss_reg(vsi, seed, lut, lut_size);
+}
+
+/**
+ * i40e_get_rss - Get RSS keys and lut
+ * @vsi: Pointer to VSI structure
+ * @seed: Buffer to store the keys
+ * @lut: Buffer to store the lookup table entries
+ * lut_size: Size of buffer to store the lookup table entries
+ *
+ * Returns 0 on success, negative on failure
+ */
+int i40e_get_rss(struct i40e_vsi *vsi, u8 *seed, u8 *lut, u16 lut_size)
+{
+       return i40e_get_rss_reg(vsi, seed, lut, lut_size);
+}
+
 /**
  * i40e_fill_rss_lut - Fill the RSS lookup table with default values
  * @pf: Pointer to board private structure
@@ -7927,10 +7994,10 @@ static void i40e_fill_rss_lut(struct i40e_pf *pf, u8 *lut,
 }
 
 /**
- * i40e_config_rss - Prepare for RSS if used
+ * i40e_pf_config_rss - Prepare for RSS if used
  * @pf: board private structure
  **/
-static int i40e_config_rss(struct i40e_pf *pf)
+static int i40e_pf_config_rss(struct i40e_pf *pf)
 {
        struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
        u8 seed[I40E_HKEY_ARRAY_SIZE];
@@ -7940,8 +8007,6 @@ static int i40e_config_rss(struct i40e_pf *pf)
        u64 hena;
        int ret;
 
-       netdev_rss_key_fill((void *)seed, I40E_HKEY_ARRAY_SIZE);
-
        /* By default we enable TCP/UDP with IPv4/IPv6 ptypes */
        hena = (u64)rd32(hw, I40E_PFQF_HENA(0)) |
                ((u64)rd32(hw, I40E_PFQF_HENA(1)) << 32);
@@ -7965,10 +8030,8 @@ static int i40e_config_rss(struct i40e_pf *pf)
 
        i40e_fill_rss_lut(pf, lut, vsi->rss_table_size, vsi->rss_size);
 
-       if (pf->flags & I40E_FLAG_RSS_AQ_CAPABLE)
-               ret = i40e_config_rss_aq(vsi, seed, lut, vsi->rss_table_size);
-       else
-               ret = i40e_config_rss_reg(vsi, seed, lut, vsi->rss_table_size);
+       netdev_rss_key_fill((void *)seed, I40E_HKEY_ARRAY_SIZE);
+       ret = i40e_config_rss(vsi, seed, lut, vsi->rss_table_size);
 
        kfree(lut);
 
@@ -8000,7 +8063,7 @@ int i40e_reconfig_rss_queues(struct i40e_pf *pf, int queue_count)
                pf->rss_size = new_rss_size;
 
                i40e_reset_and_rebuild(pf, true);
-               i40e_config_rss(pf);
+               i40e_pf_config_rss(pf);
        }
        dev_info(&pf->pdev->dev, "RSS count:  %d\n", pf->rss_size);
        return pf->rss_size;
@@ -10009,7 +10072,7 @@ static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit)
         * the hash
         */
        if ((pf->flags & I40E_FLAG_RSS_ENABLED))
-               i40e_config_rss(pf);
+               i40e_pf_config_rss(pf);
 
        /* fill in link information and enable LSE reporting */
        i40e_update_link_info(&pf->hw);