Commit b7e9392d authored by Robert Richter's avatar Robert Richter Committed by Dan Williams

PCI/AER: Unmask RCEC internal errors to enable RCH downstream port error handling

AER corrected and uncorrectable internal errors (CIE/UIE) are masked
in their corresponding mask registers per default once in power-up
state. [1][2] Enable internal errors for RCECs to receive CXL
downstream port errors of Restricted CXL Hosts (RCHs).

[1] CXL 3.0 Spec, 12.2.1.1 - RCH Downstream Port Detected Errors
[2] PCIe Base Spec r6.0, 7.8.4.3 Uncorrectable Error Mask Register,
    7.8.4.6 Correctable Error Mask Register
Co-developed-by: default avatarTerry Bowman <terry.bowman@amd.com>
Signed-off-by: default avatarTerry Bowman <terry.bowman@amd.com>
Signed-off-by: default avatarRobert Richter <rrichter@amd.com>
Acked-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Reviewed-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: default avatarDave Jiang <dave.jiang@intel.com>
Link: https://lore.kernel.org/r/20231018171713.1883517-19-rrichter@amd.comSigned-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent 0a867568
......@@ -936,6 +936,30 @@ static bool find_source_device(struct pci_dev *parent,
#ifdef CONFIG_PCIEAER_CXL
/**
* pci_aer_unmask_internal_errors - unmask internal errors
* @dev: pointer to the pcie_dev data structure
*
* Unmasks internal errors in the Uncorrectable and Correctable Error
* Mask registers.
*
* Note: AER must be enabled and supported by the device which must be
* checked in advance, e.g. with pcie_aer_is_native().
*/
static void pci_aer_unmask_internal_errors(struct pci_dev *dev)
{
int aer = dev->aer_cap;
u32 mask;
pci_read_config_dword(dev, aer + PCI_ERR_UNCOR_MASK, &mask);
mask &= ~PCI_ERR_UNC_INTN;
pci_write_config_dword(dev, aer + PCI_ERR_UNCOR_MASK, mask);
pci_read_config_dword(dev, aer + PCI_ERR_COR_MASK, &mask);
mask &= ~PCI_ERR_COR_INTERNAL;
pci_write_config_dword(dev, aer + PCI_ERR_COR_MASK, mask);
}
static bool is_cxl_mem_dev(struct pci_dev *dev)
{
/*
......@@ -1012,7 +1036,39 @@ static void cxl_rch_handle_error(struct pci_dev *dev, struct aer_err_info *info)
pcie_walk_rcec(dev, cxl_rch_handle_error_iter, info);
}
static int handles_cxl_error_iter(struct pci_dev *dev, void *data)
{
bool *handles_cxl = data;
if (!*handles_cxl)
*handles_cxl = is_cxl_mem_dev(dev) && cxl_error_is_native(dev);
/* Non-zero terminates iteration */
return *handles_cxl;
}
static bool handles_cxl_errors(struct pci_dev *rcec)
{
bool handles_cxl = false;
if (pci_pcie_type(rcec) == PCI_EXP_TYPE_RC_EC &&
pcie_aer_is_native(rcec))
pcie_walk_rcec(rcec, handles_cxl_error_iter, &handles_cxl);
return handles_cxl;
}
static void cxl_rch_enable_rcec(struct pci_dev *rcec)
{
if (!handles_cxl_errors(rcec))
return;
pci_aer_unmask_internal_errors(rcec);
pci_info(rcec, "CXL: Internal errors unmasked");
}
#else
static inline void cxl_rch_enable_rcec(struct pci_dev *dev) { }
static inline void cxl_rch_handle_error(struct pci_dev *dev,
struct aer_err_info *info) { }
#endif
......@@ -1412,6 +1468,7 @@ static int aer_probe(struct pcie_device *dev)
return status;
}
cxl_rch_enable_rcec(port);
aer_enable_rootport(rpc);
pci_info(port, "enabled with IRQ %d\n", dev->irq);
return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment