summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMitch Williams <mitch.a.williams@intel.com>2013-11-28 06:39:40 +0000
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2014-01-06 02:39:10 -0800
commitf7414531a0cf1c0ff4031b8ff3627983969fb00e (patch)
tree5605fd5a1a2f293e0a80697a537ef13722baf527
parent3197ce220c821b869731872251f2e225c37cbbb0 (diff)
downloadlinux-f7414531a0cf1c0ff4031b8ff3627983969fb00e.tar.bz2
i40e: acknowledge VFLR when disabling SR-IOV
When SR-IOV is disabled, the (now nonexistent) virtual function devices undergo a VFLR event. We don't need to handle this event because the VFs are gone, but we do need to tell the HW that they are complete. This fixes an issue with a phantom VFLR and broken VFs when SR-IOV is re-enabled. Change-Id: I7580b49ded0158172a85b14661ec212af77000c8 Signed-off-by: Mitch Williams <mitch.a.williams@intel.com> Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com> Tested-by: Sibai Li <sibai.li@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
index f92404c8646e..e91f9d73dc48 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
@@ -726,7 +726,9 @@ static bool i40e_vfs_are_assigned(struct i40e_pf *pf)
**/
void i40e_free_vfs(struct i40e_pf *pf)
{
- int i, tmp;
+ struct i40e_hw *hw = &pf->hw;
+ u32 reg_idx, bit_idx;
+ int i, tmp, vf_id;
if (!pf->vf)
return;
@@ -748,8 +750,17 @@ void i40e_free_vfs(struct i40e_pf *pf)
kfree(pf->vf);
pf->vf = NULL;
- if (!i40e_vfs_are_assigned(pf))
+ if (!i40e_vfs_are_assigned(pf)) {
pci_disable_sriov(pf->pdev);
+ /* Acknowledge VFLR for all VFS. Without this, VFs will fail to
+ * work correctly when SR-IOV gets re-enabled.
+ */
+ for (vf_id = 0; vf_id < tmp; vf_id++) {
+ reg_idx = (hw->func_caps.vf_base_id + vf_id) / 32;
+ bit_idx = (hw->func_caps.vf_base_id + vf_id) % 32;
+ wr32(hw, I40E_GLGEN_VFLRSTAT(reg_idx), (1 << bit_idx));
+ }
+ }
else
dev_warn(&pf->pdev->dev,
"unable to disable SR-IOV because VFs are assigned.\n");