aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_iov.c48
1 files changed, 28 insertions, 20 deletions
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_iov.c b/drivers/net/ethernet/intel/fm10k/fm10k_iov.c
index 74160c2095ee..5d4f1761dc0c 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_iov.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_iov.c
@@ -303,6 +303,28 @@ void fm10k_iov_suspend(struct pci_dev *pdev)
303 } 303 }
304} 304}
305 305
306static void fm10k_mask_aer_comp_abort(struct pci_dev *pdev)
307{
308 u32 err_mask;
309 int pos;
310
311 pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR);
312 if (!pos)
313 return;
314
315 /* Mask the completion abort bit in the ERR_UNCOR_MASK register,
316 * preventing the device from reporting these errors to the upstream
317 * PCIe root device. This avoids bringing down platforms which upgrade
318 * non-fatal completer aborts into machine check exceptions. Completer
319 * aborts can occur whenever a VF reads a queue it doesn't own.
320 */
321 pci_read_config_dword(pdev, pos + PCI_ERR_UNCOR_MASK, &err_mask);
322 err_mask |= PCI_ERR_UNC_COMP_ABORT;
323 pci_write_config_dword(pdev, pos + PCI_ERR_UNCOR_MASK, err_mask);
324
325 mmiowb();
326}
327
306int fm10k_iov_resume(struct pci_dev *pdev) 328int fm10k_iov_resume(struct pci_dev *pdev)
307{ 329{
308 struct fm10k_intfc *interface = pci_get_drvdata(pdev); 330 struct fm10k_intfc *interface = pci_get_drvdata(pdev);
@@ -318,6 +340,12 @@ int fm10k_iov_resume(struct pci_dev *pdev)
318 if (!iov_data) 340 if (!iov_data)
319 return -ENOMEM; 341 return -ENOMEM;
320 342
343 /* Lower severity of completer abort error reporting as
344 * the VFs can trigger this any time they read a queue
345 * that they don't own.
346 */
347 fm10k_mask_aer_comp_abort(pdev);
348
321 /* allocate hardware resources for the VFs */ 349 /* allocate hardware resources for the VFs */
322 hw->iov.ops.assign_resources(hw, num_vfs, num_vfs); 350 hw->iov.ops.assign_resources(hw, num_vfs, num_vfs);
323 351
@@ -461,20 +489,6 @@ void fm10k_iov_disable(struct pci_dev *pdev)
461 fm10k_iov_free_data(pdev); 489 fm10k_iov_free_data(pdev);
462} 490}
463 491
464static void fm10k_disable_aer_comp_abort(struct pci_dev *pdev)
465{
466 u32 err_sev;
467 int pos;
468
469 pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR);
470 if (!pos)
471 return;
472
473 pci_read_config_dword(pdev, pos + PCI_ERR_UNCOR_SEVER, &err_sev);
474 err_sev &= ~PCI_ERR_UNC_COMP_ABORT;
475 pci_write_config_dword(pdev, pos + PCI_ERR_UNCOR_SEVER, err_sev);
476}
477
478int fm10k_iov_configure(struct pci_dev *pdev, int num_vfs) 492int fm10k_iov_configure(struct pci_dev *pdev, int num_vfs)
479{ 493{
480 int current_vfs = pci_num_vf(pdev); 494 int current_vfs = pci_num_vf(pdev);
@@ -496,12 +510,6 @@ int fm10k_iov_configure(struct pci_dev *pdev, int num_vfs)
496 510
497 /* allocate VFs if not already allocated */ 511 /* allocate VFs if not already allocated */
498 if (num_vfs && num_vfs != current_vfs) { 512 if (num_vfs && num_vfs != current_vfs) {
499 /* Disable completer abort error reporting as
500 * the VFs can trigger this any time they read a queue
501 * that they don't own.
502 */
503 fm10k_disable_aer_comp_abort(pdev);
504
505 err = pci_enable_sriov(pdev, num_vfs); 513 err = pci_enable_sriov(pdev, num_vfs);
506 if (err) { 514 if (err) {
507 dev_err(&pdev->dev, 515 dev_err(&pdev->dev,