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

Commit 76b57c67 authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

PCI: Wait for pending transactions to complete before 82599 FLR



Before initiating an FLR, we should wait for completion of any outstanding
non-posted requests.  See PCIe spec r3.0, sec 6.6.2.

This makes reset_intel_82599_sfp_virtfn() very similar to the generic
pcie_flr().  The only difference is that the 82599 doesn't report FLR
support in the VF Device Capability register.

Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
parent 59875ae4
Loading
Loading
Loading
Loading
+27 −1
Original line number Diff line number Diff line
@@ -3081,10 +3081,36 @@ static int reset_intel_generic_dev(struct pci_dev *dev, int probe)

static int reset_intel_82599_sfp_virtfn(struct pci_dev *dev, int probe)
{
	int i;
	u16 status;

	/*
	 * http://www.intel.com/content/dam/doc/datasheet/82599-10-gbe-controller-datasheet.pdf
	 *
	 * The 82599 supports FLR on VFs, but FLR support is reported only
	 * in the PF DEVCAP (sec 9.3.10.4), not in the VF DEVCAP (sec 9.5).
	 * Therefore, we can't use pcie_flr(), which checks the VF DEVCAP.
	 */

	if (probe)
		return 0;

	pcie_capability_write_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR);
	/* Wait for Transaction Pending bit clean */
	for (i = 0; i < 4; i++) {
		if (i)
			msleep((1 << (i - 1)) * 100);

		pcie_capability_read_word(dev, PCI_EXP_DEVSTA, &status);
		if (!(status & PCI_EXP_DEVSTA_TRPND))
			goto clear;
	}

	dev_err(&dev->dev, "transaction is not cleared; "
			"proceeding with reset anyway\n");

clear:
	pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR);

	msleep(100);

	return 0;