aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel
diff options
context:
space:
mode:
authorMitch Williams <mitch.a.williams@intel.com>2014-11-10 22:15:04 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2014-11-18 04:08:33 -0500
commitc5c2f7c360af164448d87cb618af2ee5dad3a01a (patch)
treef4480eb400f19d12258c5a07bf88f7b4918c77e4 /drivers/net/ethernet/intel
parente684fa34c3a28b4893d43629a02a765a2a71e63e (diff)
i40e: re-enable VFLR interrupt sooner
VF interrupt processing takes a looooong time, and it's possible that we could lose a VFLR event if it happens while we're processing a VFLR on another VF. This would leave the VF in a semi-permanent reset state, which would not be cleared until yet another VF experiences a VFLR. To correct this situation, we enable the VFLR interrupt cause before we begin processing any pending resets. This means that any VFLR that occurs during reset processing will generate another interrupt and this routine will get called again. This change may cause a spurious interrupt when multiple VFLRs occur very close together in time. If this happens, then this routine will be called again and it will detect no outstanding VFLR events and do nothing. No harm, no foul. Change-ID: Id0451f3e6e73a2cf6db1668296c71e129b59dc19 Signed-off-by: Mitch Williams <mitch.a.williams@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel')
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
index fff3c276736b..668d860275d6 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
@@ -1869,6 +1869,12 @@ int i40e_vc_process_vflr_event(struct i40e_pf *pf)
1869 if (!test_bit(__I40E_VFLR_EVENT_PENDING, &pf->state)) 1869 if (!test_bit(__I40E_VFLR_EVENT_PENDING, &pf->state))
1870 return 0; 1870 return 0;
1871 1871
1872 /* re-enable vflr interrupt cause */
1873 reg = rd32(hw, I40E_PFINT_ICR0_ENA);
1874 reg |= I40E_PFINT_ICR0_ENA_VFLR_MASK;
1875 wr32(hw, I40E_PFINT_ICR0_ENA, reg);
1876 i40e_flush(hw);
1877
1872 clear_bit(__I40E_VFLR_EVENT_PENDING, &pf->state); 1878 clear_bit(__I40E_VFLR_EVENT_PENDING, &pf->state);
1873 for (vf_id = 0; vf_id < pf->num_alloc_vfs; vf_id++) { 1879 for (vf_id = 0; vf_id < pf->num_alloc_vfs; vf_id++) {
1874 reg_idx = (hw->func_caps.vf_base_id + vf_id) / 32; 1880 reg_idx = (hw->func_caps.vf_base_id + vf_id) / 32;
@@ -1885,12 +1891,6 @@ int i40e_vc_process_vflr_event(struct i40e_pf *pf)
1885 } 1891 }
1886 } 1892 }
1887 1893
1888 /* re-enable vflr interrupt cause */
1889 reg = rd32(hw, I40E_PFINT_ICR0_ENA);
1890 reg |= I40E_PFINT_ICR0_ENA_VFLR_MASK;
1891 wr32(hw, I40E_PFINT_ICR0_ENA, reg);
1892 i40e_flush(hw);
1893
1894 return 0; 1894 return 0;
1895} 1895}
1896 1896