Commit 5a6fe61f authored by Dan Williams's avatar Dan Williams
Browse files

Merge branch 'for-6.3/cxl' into cxl/next

Pick up the AER unmasking patches for v6.3.
parents ee817aca 248529ed
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -130,6 +130,7 @@ static inline int ways_to_eiw(unsigned int ways, u8 *eiw)
#define   CXL_RAS_UNCORRECTABLE_STATUS_MASK (GENMASK(16, 14) | GENMASK(11, 0))
#define CXL_RAS_UNCORRECTABLE_MASK_OFFSET 0x4
#define   CXL_RAS_UNCORRECTABLE_MASK_MASK (GENMASK(16, 14) | GENMASK(11, 0))
#define   CXL_RAS_UNCORRECTABLE_MASK_F256B_MASK BIT(8)
#define CXL_RAS_UNCORRECTABLE_SEVERITY_OFFSET 0x8
#define   CXL_RAS_UNCORRECTABLE_SEVERITY_MASK (GENMASK(16, 14) | GENMASK(11, 0))
#define CXL_RAS_CORRECTABLE_STATUS_OFFSET 0xC
+62 −8
Original line number Diff line number Diff line
@@ -412,9 +412,65 @@ static bool is_cxl_restricted(struct pci_dev *pdev)
	return pci_pcie_type(pdev) == PCI_EXP_TYPE_RC_END;
}

static void disable_aer(void *pdev)
/*
 * CXL v3.0 6.2.3 Table 6-4
 * The table indicates that if PCIe Flit Mode is set, then CXL is in 256B flits
 * mode, otherwise it's 68B flits mode.
 */
static bool cxl_pci_flit_256(struct pci_dev *pdev)
{
	pci_disable_pcie_error_reporting(pdev);
	u16 lnksta2;

	pcie_capability_read_word(pdev, PCI_EXP_LNKSTA2, &lnksta2);
	return lnksta2 & PCI_EXP_LNKSTA2_FLIT;
}

static int cxl_pci_ras_unmask(struct pci_dev *pdev)
{
	struct pci_host_bridge *host_bridge = pci_find_host_bridge(pdev->bus);
	struct cxl_dev_state *cxlds = pci_get_drvdata(pdev);
	void __iomem *addr;
	u32 orig_val, val, mask;
	u16 cap;
	int rc;

	if (!cxlds->regs.ras) {
		dev_dbg(&pdev->dev, "No RAS registers.\n");
		return 0;
	}

	/* BIOS has CXL error control */
	if (!host_bridge->native_cxl_error)
		return -ENXIO;

	rc = pcie_capability_read_word(pdev, PCI_EXP_DEVCTL, &cap);
	if (rc)
		return rc;

	if (cap & PCI_EXP_DEVCTL_URRE) {
		addr = cxlds->regs.ras + CXL_RAS_UNCORRECTABLE_MASK_OFFSET;
		orig_val = readl(addr);

		mask = CXL_RAS_UNCORRECTABLE_MASK_MASK;
		if (!cxl_pci_flit_256(pdev))
			mask &= ~CXL_RAS_UNCORRECTABLE_MASK_F256B_MASK;
		val = orig_val & ~mask;
		writel(val, addr);
		dev_dbg(&pdev->dev,
			"Uncorrectable RAS Errors Mask: %#x -> %#x\n",
			orig_val, val);
	}

	if (cap & PCI_EXP_DEVCTL_CERE) {
		addr = cxlds->regs.ras + CXL_RAS_CORRECTABLE_MASK_OFFSET;
		orig_val = readl(addr);
		val = orig_val & ~CXL_RAS_CORRECTABLE_MASK_MASK;
		writel(val, addr);
		dev_dbg(&pdev->dev, "Correctable RAS Errors Mask: %#x -> %#x\n",
			orig_val, val);
	}

	return 0;
}

static void free_event_buf(void *buf)
@@ -733,12 +789,10 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
	if (rc)
		return rc;

	if (cxlds->regs.ras) {
		pci_enable_pcie_error_reporting(pdev);
		rc = devm_add_action_or_reset(&pdev->dev, disable_aer, pdev);
	rc = cxl_pci_ras_unmask(pdev);
	if (rc)
			return rc;
	}
		dev_dbg(&pdev->dev, "No RAS reporting unmasked\n");

	pci_save_state(pdev);

	return rc;
+1 −0
Original line number Diff line number Diff line
@@ -693,6 +693,7 @@
#define  PCI_EXP_LNKCTL2_TX_MARGIN	0x0380 /* Transmit Margin */
#define  PCI_EXP_LNKCTL2_HASD		0x0020 /* HW Autonomous Speed Disable */
#define PCI_EXP_LNKSTA2		0x32	/* Link Status 2 */
#define  PCI_EXP_LNKSTA2_FLIT		0x0400 /* Flit Mode Status */
#define PCI_CAP_EXP_ENDPOINT_SIZEOF_V2	0x32	/* end of v2 EPs w/ link */
#define PCI_EXP_SLTCAP2		0x34	/* Slot Capabilities 2 */
#define  PCI_EXP_SLTCAP2_IBPD	0x00000001 /* In-band PD Disable Supported */