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

Commit d79a663f authored by Lazar Alexei's avatar Lazar Alexei Committed by Maya Erez
Browse files

wil6210: fix PCIe bus mastering in case of interface down



In case of interface down, radio is turned off but PCIe mastering is
not cleared.
This can cause unexpected PCIe access to the shutdown device.
Fix this by clearing PCIe mastering also in case interface is down

Change-Id: Iaf7ce20f99d25ab8a330b470c1b73956748f1d84
Signed-off-by: default avatarLazar Alexei <qca_ailizaro@qca.qualcomm.com>
Signed-off-by: default avatarMaya Erez <qca_merez@qca.qualcomm.com>
Signed-off-by: default avatarKalle Valo <kvalo@qca.qualcomm.com>
Git-commit: 680c242dc25e036265793edc7d755cfc15afd231
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git


Signed-off-by: default avatarMaya Erez <merez@codeaurora.org>
parent 3ca3856e
Loading
Loading
Loading
Loading
+15 −9
Original line number Diff line number Diff line
@@ -393,6 +393,9 @@ static int wil6210_suspend(struct device *dev, bool is_runtime)
	int rc = 0;
	struct pci_dev *pdev = to_pci_dev(dev);
	struct wil6210_priv *wil = pci_get_drvdata(pdev);
	struct net_device *ndev = wil_to_ndev(wil);
	bool keep_radio_on = ndev->flags & IFF_UP &&
			     wil->keep_radio_on_during_sleep;

	wil_dbg_pm(wil, "suspend: %s\n", is_runtime ? "runtime" : "system");

@@ -400,14 +403,14 @@ static int wil6210_suspend(struct device *dev, bool is_runtime)
	if (rc)
		goto out;

	rc = wil_suspend(wil, is_runtime);
	rc = wil_suspend(wil, is_runtime, keep_radio_on);
	if (!rc) {
		wil->suspend_stats.successful_suspends++;

		/* If platform device supports keep_radio_on_during_sleep
		 * it will control PCIe master
		/* In case radio stays on, platform device will control
		 * PCIe master
		 */
		if (!wil->keep_radio_on_during_sleep)
		if (!keep_radio_on)
			/* disable bus mastering */
			pci_clear_master(pdev);
	}
@@ -420,20 +423,23 @@ static int wil6210_resume(struct device *dev, bool is_runtime)
	int rc = 0;
	struct pci_dev *pdev = to_pci_dev(dev);
	struct wil6210_priv *wil = pci_get_drvdata(pdev);
	struct net_device *ndev = wil_to_ndev(wil);
	bool keep_radio_on = ndev->flags & IFF_UP &&
			     wil->keep_radio_on_during_sleep;

	wil_dbg_pm(wil, "resume: %s\n", is_runtime ? "runtime" : "system");

	/* If platform device supports keep_radio_on_during_sleep it will
	 * control PCIe master
	/* In case radio stays on, platform device will control
	 * PCIe master
	 */
	if (!wil->keep_radio_on_during_sleep)
	if (!keep_radio_on)
		/* allow master */
		pci_set_master(pdev);
	rc = wil_resume(wil, is_runtime);
	rc = wil_resume(wil, is_runtime, keep_radio_on);
	if (rc) {
		wil_err(wil, "device failed to resume (%d)\n", rc);
		wil->suspend_stats.failed_resumes++;
		if (!wil->keep_radio_on_during_sleep)
		if (!keep_radio_on)
			pci_clear_master(pdev);
	} else {
		wil->suspend_stats.successful_resumes++;
+2 −8
Original line number Diff line number Diff line
@@ -317,12 +317,9 @@ static int wil_resume_radio_off(struct wil6210_priv *wil)
	return rc;
}

int wil_suspend(struct wil6210_priv *wil, bool is_runtime)
int wil_suspend(struct wil6210_priv *wil, bool is_runtime, bool keep_radio_on)
{
	int rc = 0;
	struct net_device *ndev = wil_to_ndev(wil);
	bool keep_radio_on = ndev->flags & IFF_UP &&
			     wil->keep_radio_on_during_sleep;

	wil_dbg_pm(wil, "suspend: %s\n", is_runtime ? "runtime" : "system");

@@ -345,12 +342,9 @@ int wil_suspend(struct wil6210_priv *wil, bool is_runtime)
	return rc;
}

int wil_resume(struct wil6210_priv *wil, bool is_runtime)
int wil_resume(struct wil6210_priv *wil, bool is_runtime, bool keep_radio_on)
{
	int rc = 0;
	struct net_device *ndev = wil_to_ndev(wil);
	bool keep_radio_on = ndev->flags & IFF_UP &&
			     wil->keep_radio_on_during_sleep;
	unsigned long long suspend_time_usec = 0;

	wil_dbg_pm(wil, "resume: %s\n", is_runtime ? "runtime" : "system");
+2 −2
Original line number Diff line number Diff line
@@ -1041,8 +1041,8 @@ int wil_pm_runtime_get(struct wil6210_priv *wil);
void wil_pm_runtime_put(struct wil6210_priv *wil);

int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime);
int wil_suspend(struct wil6210_priv *wil, bool is_runtime);
int wil_resume(struct wil6210_priv *wil, bool is_runtime);
int wil_suspend(struct wil6210_priv *wil, bool is_runtime, bool keep_radio_on);
int wil_resume(struct wil6210_priv *wil, bool is_runtime, bool keep_radio_on);
bool wil_is_wmi_idle(struct wil6210_priv *wil);
int wmi_resume(struct wil6210_priv *wil);
int wmi_suspend(struct wil6210_priv *wil);