Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -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;
+19 −12
Original line number Original line Diff line number Diff line
@@ -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,
		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);
}
}


/**
/**
+47 −5
Original line number Original line Diff line number Diff line
@@ -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)
	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)
	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)
			(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)
		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);