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

Commit d9bd520f authored by Hemant Kumar's avatar Hemant Kumar
Browse files

pci: msm: Add support for BDF filtering



Do not allow configuration access request to certain BDFs.
This is required for PCIe switches, unable to respond to
configuration access request to certain supported BDFs.
Without filtering, such BDFs are causing system bus hang
or enumeration failure of downstream ports of switch.

Change-Id: I4c4fa5cc4921dfe0217e05aaad4600abebcacd2b
Signed-off-by: default avatarHemant Kumar <hemantk@codeaurora.org>
parent fe7314a5
Loading
Loading
Loading
Loading
+35 −2
Original line number Diff line number Diff line
@@ -851,6 +851,9 @@ struct msm_pcie_dev_t {
	bool drv_supported;

	void (*rumi_init)(struct msm_pcie_dev_t *pcie_dev);

	u32 *filtered_bdfs;
	u32 bdf_count;
};

struct msm_root_dev_t {
@@ -3004,7 +3007,7 @@ static int msm_pcie_oper_conf(struct pci_bus *bus, u32 devfn, int oper,
	struct msm_pcie_dev_t *dev;
	void __iomem *config_base;
	bool rc = false;
	u32 rc_idx;
	u32 rc_idx, *filtered_bdf;
	int rv = 0;
	u32 bdf = BDF_OFFSET(bus->number, devfn);
	int i;
@@ -3060,6 +3063,19 @@ static int msm_pcie_oper_conf(struct pci_bus *bus, u32 devfn, int oper,
			goto unlock;
	}

	/* 32-bit BDF filtering */
	if (dev->bdf_count) {
		i = dev->bdf_count;
		filtered_bdf = dev->filtered_bdfs;
		while (i--) {
			if (*filtered_bdf == bdf) {
				*val = ~0;
				goto unlock;
			}
			filtered_bdf++;
		}
	}

	if (!rc && !dev->enumerated)
		msm_pcie_cfg_bdf(dev, bus->number, devfn);

@@ -5932,7 +5948,7 @@ static int msm_pcie_probe(struct platform_device *pdev)
{
	int ret = 0;
	int rc_idx = -1;
	int i, j;
	int i, j, size;
	struct msm_pcie_dev_t *pcie_dev;
	struct device_node *of_node;

@@ -6244,6 +6260,23 @@ static int msm_pcie_probe(struct platform_device *pdev)

	pcie_dev->drv_ready = true;

	of_get_property(pdev->dev.of_node, "qcom,filtered-bdfs", &size);
	if (size) {
		pcie_dev->filtered_bdfs = devm_kzalloc(&pdev->dev, size,
						       GFP_KERNEL);
		if (!pcie_dev->filtered_bdfs)
			return -ENOMEM;

		pcie_dev->bdf_count = size / sizeof(*pcie_dev->filtered_bdfs);

		ret = of_property_read_u32_array(pdev->dev.of_node,
						 "qcom,filtered-bdfs",
						 pcie_dev->filtered_bdfs,
						 pcie_dev->bdf_count);
		if (ret)
			pcie_dev->bdf_count = 0;
	}

	if (pcie_dev->boot_option & MSM_PCIE_NO_PROBE_ENUMERATION) {
		PCIE_DBG(pcie_dev,
			"PCIe: RC%d will be enumerated by client or endpoint.\n",