Commit 28c5869f authored by Helin Zhang's avatar Helin Zhang Committed by Jeff Kirsher

i40e: add new fields to store user configuration

This patch adds new fields to i40e_vsi to store user configured
RSS config data and code to use it.
Signed-off-by: default avatarHelin Zhang <helin.zhang@intel.com>
Change-ID: I73886469dca9e9f6b16d842182a87f3f4009f95d
Tested-by: default avatarAndrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 6cc56834
...@@ -508,6 +508,8 @@ struct i40e_vsi { ...@@ -508,6 +508,8 @@ struct i40e_vsi {
u16 rss_table_size; u16 rss_table_size;
u16 rss_size; u16 rss_size;
u8 *rss_hkey_user; /* User configured hash keys */
u8 *rss_lut_user; /* User configured lookup table entries */
u16 max_frame; u16 max_frame;
u16 rx_hdr_len; u16 rx_hdr_len;
......
...@@ -2651,10 +2651,8 @@ static int i40e_set_rxfh(struct net_device *netdev, const u32 *indir, ...@@ -2651,10 +2651,8 @@ static int i40e_set_rxfh(struct net_device *netdev, const u32 *indir,
{ {
struct i40e_netdev_priv *np = netdev_priv(netdev); struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_vsi *vsi = np->vsi; struct i40e_vsi *vsi = np->vsi;
u8 seed_def[I40E_HKEY_ARRAY_SIZE]; u8 *seed = NULL;
u8 *lut, *seed = NULL;
u16 i; u16 i;
int ret;
if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP) if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -2663,18 +2661,27 @@ static int i40e_set_rxfh(struct net_device *netdev, const u32 *indir, ...@@ -2663,18 +2661,27 @@ static int i40e_set_rxfh(struct net_device *netdev, const u32 *indir,
return 0; return 0;
if (key) { if (key) {
memcpy(seed_def, key, I40E_HKEY_ARRAY_SIZE); if (!vsi->rss_hkey_user) {
seed = seed_def; vsi->rss_hkey_user = kzalloc(I40E_HKEY_ARRAY_SIZE,
GFP_KERNEL);
if (!vsi->rss_hkey_user)
return -ENOMEM;
} }
lut = kzalloc(I40E_HLUT_ARRAY_SIZE, GFP_KERNEL); memcpy(vsi->rss_hkey_user, key, I40E_HKEY_ARRAY_SIZE);
if (!lut) seed = vsi->rss_hkey_user;
}
if (!vsi->rss_lut_user) {
vsi->rss_lut_user = kzalloc(I40E_HLUT_ARRAY_SIZE, GFP_KERNEL);
if (!vsi->rss_lut_user)
return -ENOMEM; return -ENOMEM;
}
/* Each 32 bits pointed by 'indir' is stored with a lut entry */
for (i = 0; i < I40E_HLUT_ARRAY_SIZE; i++) for (i = 0; i < I40E_HLUT_ARRAY_SIZE; i++)
lut[i] = (u8)(indir[i]); vsi->rss_lut_user[i] = (u8)(indir[i]);
ret = i40e_config_rss(vsi, seed, lut, I40E_HLUT_ARRAY_SIZE);
kfree(lut);
return ret; return i40e_config_rss(vsi, seed, vsi->rss_lut_user,
I40E_HLUT_ARRAY_SIZE);
} }
/** /**
......
...@@ -7300,6 +7300,23 @@ static void i40e_vsi_free_arrays(struct i40e_vsi *vsi, bool free_qvectors) ...@@ -7300,6 +7300,23 @@ static void i40e_vsi_free_arrays(struct i40e_vsi *vsi, bool free_qvectors)
vsi->rx_rings = NULL; vsi->rx_rings = NULL;
} }
/**
* i40e_clear_rss_config_user - clear the user configured RSS hash keys
* and lookup table
* @vsi: Pointer to VSI structure
*/
static void i40e_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;
}
/** /**
* i40e_vsi_clear - Deallocate the VSI provided * i40e_vsi_clear - Deallocate the VSI provided
* @vsi: the VSI being un-configured * @vsi: the VSI being un-configured
...@@ -7337,6 +7354,7 @@ static int i40e_vsi_clear(struct i40e_vsi *vsi) ...@@ -7337,6 +7354,7 @@ static int i40e_vsi_clear(struct i40e_vsi *vsi)
i40e_put_lump(pf->irq_pile, vsi->base_vector, vsi->idx); i40e_put_lump(pf->irq_pile, vsi->base_vector, vsi->idx);
i40e_vsi_free_arrays(vsi, true); i40e_vsi_free_arrays(vsi, true);
i40e_clear_rss_config_user(vsi);
pf->vsi[vsi->idx] = NULL; pf->vsi[vsi->idx] = NULL;
if (vsi->idx < pf->next_vsi) if (vsi->idx < pf->next_vsi)
...@@ -8015,8 +8033,6 @@ static int i40e_pf_config_rss(struct i40e_pf *pf) ...@@ -8015,8 +8033,6 @@ static int i40e_pf_config_rss(struct i40e_pf *pf)
wr32(hw, I40E_PFQF_HENA(0), (u32)hena); wr32(hw, I40E_PFQF_HENA(0), (u32)hena);
wr32(hw, I40E_PFQF_HENA(1), (u32)(hena >> 32)); wr32(hw, I40E_PFQF_HENA(1), (u32)(hena >> 32));
vsi->rss_size = min_t(int, pf->rss_size, vsi->num_queue_pairs);
/* Determine the RSS table size based on the hardware capabilities */ /* Determine the RSS table size based on the hardware capabilities */
reg_val = rd32(hw, I40E_PFQF_CTL_0); reg_val = rd32(hw, I40E_PFQF_CTL_0);
reg_val = (pf->rss_table_size == 512) ? reg_val = (pf->rss_table_size == 512) ?
...@@ -8024,15 +8040,28 @@ static int i40e_pf_config_rss(struct i40e_pf *pf) ...@@ -8024,15 +8040,28 @@ static int i40e_pf_config_rss(struct i40e_pf *pf)
(reg_val & ~I40E_PFQF_CTL_0_HASHLUTSIZE_512); (reg_val & ~I40E_PFQF_CTL_0_HASHLUTSIZE_512);
wr32(hw, I40E_PFQF_CTL_0, reg_val); wr32(hw, I40E_PFQF_CTL_0, reg_val);
/* Determine the RSS size of the VSI */
if (!vsi->rss_size)
vsi->rss_size = min_t(int, pf->rss_size, vsi->num_queue_pairs);
lut = kzalloc(vsi->rss_table_size, GFP_KERNEL); lut = kzalloc(vsi->rss_table_size, GFP_KERNEL);
if (!lut) if (!lut)
return -ENOMEM; return -ENOMEM;
/* Use user configured lut if there is one, otherwise use default */
if (vsi->rss_lut_user)
memcpy(lut, vsi->rss_lut_user, vsi->rss_table_size);
else
i40e_fill_rss_lut(pf, lut, vsi->rss_table_size, vsi->rss_size); i40e_fill_rss_lut(pf, lut, vsi->rss_table_size, vsi->rss_size);
/* Use user configured hash key if there is one, otherwise
* use default.
*/
if (vsi->rss_hkey_user)
memcpy(seed, vsi->rss_hkey_user, I40E_HKEY_ARRAY_SIZE);
else
netdev_rss_key_fill((void *)seed, I40E_HKEY_ARRAY_SIZE); netdev_rss_key_fill((void *)seed, I40E_HKEY_ARRAY_SIZE);
ret = i40e_config_rss(vsi, seed, lut, vsi->rss_table_size); ret = i40e_config_rss(vsi, seed, lut, vsi->rss_table_size);
kfree(lut); kfree(lut);
return ret; return ret;
...@@ -8063,6 +8092,19 @@ int i40e_reconfig_rss_queues(struct i40e_pf *pf, int queue_count) ...@@ -8063,6 +8092,19 @@ int i40e_reconfig_rss_queues(struct i40e_pf *pf, int queue_count)
pf->rss_size = new_rss_size; pf->rss_size = new_rss_size;
i40e_reset_and_rebuild(pf, true); i40e_reset_and_rebuild(pf, true);
/* Discard the user configured hash keys and lut, if less
* queues are enabled.
*/
if (queue_count < vsi->rss_size) {
i40e_clear_rss_config_user(vsi);
dev_dbg(&pf->pdev->dev,
"discard user configured hash keys and lut\n");
}
/* Reset vsi->rss_size, as number of enabled queues changed */
vsi->rss_size = min_t(int, pf->rss_size, vsi->num_queue_pairs);
i40e_pf_config_rss(pf); i40e_pf_config_rss(pf);
} }
dev_info(&pf->pdev->dev, "RSS count: %d\n", pf->rss_size); dev_info(&pf->pdev->dev, "RSS count: %d\n", pf->rss_size);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment