Skip to content

Commit

Permalink
cxl: Workaround malformed pcie packets on some cards
Browse files Browse the repository at this point in the history
This works around a pcie host bridge defect on some cards, that can cause
malformed Transaction Layer Packet (TLP) errors to be erroneously reported.

The upper nibble of the vendor section PSL revision is used to distinguish
between different cards. The affected ones have it set to 0.

Signed-off-by: Philippe Bergheaud <felix@linux.vnet.ibm.com>
Acked-by: Ian Munsie <imunsie@au1.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
  • Loading branch information
Philippe Bergheaud authored and Michael Ellerman committed Oct 6, 2015
1 parent 5f81b95 commit d79e680
Showing 1 changed file with 28 additions and 0 deletions.
28 changes: 28 additions & 0 deletions drivers/misc/cxl/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -1035,6 +1035,32 @@ static int cxl_read_vsec(struct cxl *adapter, struct pci_dev *dev)
return 0;
}

/*
* Workaround a PCIe Host Bridge defect on some cards, that can cause
* malformed Transaction Layer Packet (TLP) errors to be erroneously
* reported. Mask this error in the Uncorrectable Error Mask Register.
*
* The upper nibble of the PSL revision is used to distinguish between
* different cards. The affected ones have it set to 0.
*/
static void cxl_fixup_malformed_tlp(struct cxl *adapter, struct pci_dev *dev)
{
int aer;
u32 data;

if (adapter->psl_rev & 0xf000)
return;
if (!(aer = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR)))
return;
pci_read_config_dword(dev, aer + PCI_ERR_UNCOR_MASK, &data);
if (data & PCI_ERR_UNC_MALF_TLP)
if (data & PCI_ERR_UNC_INTN)
return;
data |= PCI_ERR_UNC_MALF_TLP;
data |= PCI_ERR_UNC_INTN;
pci_write_config_dword(dev, aer + PCI_ERR_UNCOR_MASK, data);
}

static int cxl_vsec_looks_ok(struct cxl *adapter, struct pci_dev *dev)
{
if (adapter->vsec_status & CXL_STATUS_SECOND_PORT)
Expand Down Expand Up @@ -1134,6 +1160,8 @@ static int cxl_configure_adapter(struct cxl *adapter, struct pci_dev *dev)
if ((rc = cxl_vsec_looks_ok(adapter, dev)))
return rc;

cxl_fixup_malformed_tlp(adapter, dev);

if ((rc = setup_cxl_bars(dev)))
return rc;

Expand Down

0 comments on commit d79e680

Please sign in to comment.