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

Commit 5bb387ed authored by Yue Ma's avatar Yue Ma Committed by Gerrit - the friendly Code Review server
Browse files

cnss2: Add support to retry with a list of PCIe RC ports



If PCIe enumeration fails with primary PCIe RC port, retry with
other PCIe RC ports if any in the list from device tree using
the same logic.

Change-Id: I4e803f74dfeda914a9944ab2d14a4055fc223301
Signed-off-by: default avatarYue Ma <yuem@codeaurora.org>
parent 37a11268
Loading
Loading
Loading
Loading
+41 −20
Original line number Diff line number Diff line
@@ -373,7 +373,7 @@ static struct cnss_misc_reg wlaon_reg_access_seq[] = {

#if IS_ENABLED(CONFIG_PCI_MSM)
/**
 * cnss_pci_enumerate() - Enumerate PCIe endpoints
 * _cnss_pci_enumerate() - Enumerate PCIe endpoints
 * @plat_priv: driver platform context pointer
 * @rc_num: root complex index that an endpoint connects to
 *
@@ -382,7 +382,7 @@ static struct cnss_misc_reg wlaon_reg_access_seq[] = {
 *
 * Return: 0 for success, negative value for error
 */
static int cnss_pci_enumerate(struct cnss_plat_data *plat_priv, int rc_num)
static int _cnss_pci_enumerate(struct cnss_plat_data *plat_priv, u32 rc_num)
{
	return msm_pcie_enumerate(rc_num);
}
@@ -569,7 +569,7 @@ static int _cnss_pci_get_reg_dump(struct cnss_pci_data *pci_priv,
	return msm_pcie_reg_dump(pci_priv->pci_dev, buf, len);
}
#else
static int cnss_pci_enumerate(struct cnss_plat_data *plat_priv, int rc_num)
static int _cnss_pci_enumerate(struct cnss_plat_data *plat_priv, u32 rc_num)
{
	return -EOPNOTSUPP;
}
@@ -5876,20 +5876,9 @@ struct pci_driver cnss_pci_driver = {
	},
};

int cnss_pci_init(struct cnss_plat_data *plat_priv)
static int cnss_pci_enumerate(struct cnss_plat_data *plat_priv, u32 rc_num)
{
	int ret = 0;
	struct device *dev = &plat_priv->plat_dev->dev;
	u32 rc_num;
	int retry = 0;

	ret = of_property_read_u32(dev->of_node, "qcom,wlan-rc-num", &rc_num);
	if (ret) {
		cnss_pr_err("Failed to find PCIe RC number, err = %d\n", ret);
		goto out;
	}

	plat_priv->rc_num = rc_num;
	int ret, retry = 0;

	/* Always set initial target PCIe link speed to Gen2 for QCA6490 device
	 * since there may be link issues if it boots up with Gen3 link speed.
@@ -5899,14 +5888,19 @@ int cnss_pci_init(struct cnss_plat_data *plat_priv)
	if (plat_priv->device_id == QCA6490_DEVICE_ID) {
		ret = cnss_pci_set_max_link_speed(plat_priv->bus_priv, rc_num,
						  PCI_EXP_LNKSTA_CLS_5_0GB);
		if (ret)
			cnss_pr_err("Failed to set target PCIe link speed to Gen2, err = %d\n",
				    ret);
		if (ret && ret != -EPROBE_DEFER)
			cnss_pr_err("Failed to set max PCIe RC%x link speed to Gen2, err = %d\n",
				    rc_num, ret);
	}

	cnss_pr_err("Trying to enumerate with PCIe RC%x\n", rc_num);
retry:
	ret = cnss_pci_enumerate(plat_priv, rc_num);
	ret = _cnss_pci_enumerate(plat_priv, rc_num);
	if (ret) {
		if (ret == -EPROBE_DEFER) {
			cnss_pr_dbg("PCIe RC driver is not ready, defer probe\n");
			goto out;
		}
		cnss_pr_err("Failed to enable PCIe RC%x, err = %d\n",
			    rc_num, ret);
		if (retry++ < LINK_TRAINING_RETRY_MAX_TIMES) {
@@ -5917,6 +5911,33 @@ int cnss_pci_init(struct cnss_plat_data *plat_priv)
		}
	}

	plat_priv->rc_num = rc_num;

out:
	return ret;
}

int cnss_pci_init(struct cnss_plat_data *plat_priv)
{
	struct device *dev = &plat_priv->plat_dev->dev;
	const __be32 *prop;
	int ret = 0, prop_len = 0, rc_count, i;

	prop = of_get_property(dev->of_node, "qcom,wlan-rc-num", &prop_len);
	if (!prop || !prop_len) {
		cnss_pr_err("Failed to get PCIe RC number from DT\n");
		goto out;
	}

	rc_count = prop_len / sizeof(__be32);
	for (i = 0; i < rc_count; i++) {
		ret = cnss_pci_enumerate(plat_priv, be32_to_cpup(&prop[i]));
		if (!ret)
			break;
		else if (ret == -EPROBE_DEFER || (ret && i == rc_count - 1))
			goto out;
	}

	ret = pci_register_driver(&cnss_pci_driver);
	if (ret) {
		cnss_pr_err("Failed to register to PCI framework, err = %d\n",