aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/cxl/pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/cxl/pci.c')
-rw-r--r--drivers/misc/cxl/pci.c30
1 files changed, 28 insertions, 2 deletions
diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
index 02c85160bfe9..85761d7eb333 100644
--- a/drivers/misc/cxl/pci.c
+++ b/drivers/misc/cxl/pci.c
@@ -1035,6 +1035,32 @@ static int cxl_read_vsec(struct cxl *adapter, struct pci_dev *dev)
1035 return 0; 1035 return 0;
1036} 1036}
1037 1037
1038/*
1039 * Workaround a PCIe Host Bridge defect on some cards, that can cause
1040 * malformed Transaction Layer Packet (TLP) errors to be erroneously
1041 * reported. Mask this error in the Uncorrectable Error Mask Register.
1042 *
1043 * The upper nibble of the PSL revision is used to distinguish between
1044 * different cards. The affected ones have it set to 0.
1045 */
1046static void cxl_fixup_malformed_tlp(struct cxl *adapter, struct pci_dev *dev)
1047{
1048 int aer;
1049 u32 data;
1050
1051 if (adapter->psl_rev & 0xf000)
1052 return;
1053 if (!(aer = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR)))
1054 return;
1055 pci_read_config_dword(dev, aer + PCI_ERR_UNCOR_MASK, &data);
1056 if (data & PCI_ERR_UNC_MALF_TLP)
1057 if (data & PCI_ERR_UNC_INTN)
1058 return;
1059 data |= PCI_ERR_UNC_MALF_TLP;
1060 data |= PCI_ERR_UNC_INTN;
1061 pci_write_config_dword(dev, aer + PCI_ERR_UNCOR_MASK, data);
1062}
1063
1038static int cxl_vsec_looks_ok(struct cxl *adapter, struct pci_dev *dev) 1064static int cxl_vsec_looks_ok(struct cxl *adapter, struct pci_dev *dev)
1039{ 1065{
1040 if (adapter->vsec_status & CXL_STATUS_SECOND_PORT) 1066 if (adapter->vsec_status & CXL_STATUS_SECOND_PORT)
@@ -1134,6 +1160,8 @@ static int cxl_configure_adapter(struct cxl *adapter, struct pci_dev *dev)
1134 if ((rc = cxl_vsec_looks_ok(adapter, dev))) 1160 if ((rc = cxl_vsec_looks_ok(adapter, dev)))
1135 return rc; 1161 return rc;
1136 1162
1163 cxl_fixup_malformed_tlp(adapter, dev);
1164
1137 if ((rc = setup_cxl_bars(dev))) 1165 if ((rc = setup_cxl_bars(dev)))
1138 return rc; 1166 return rc;
1139 1167
@@ -1249,8 +1277,6 @@ static int cxl_probe(struct pci_dev *dev, const struct pci_device_id *id)
1249 int slice; 1277 int slice;
1250 int rc; 1278 int rc;
1251 1279
1252 pci_dev_get(dev);
1253
1254 if (cxl_verbose) 1280 if (cxl_verbose)
1255 dump_cxl_config_space(dev); 1281 dump_cxl_config_space(dev);
1256 1282