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

Commit 679074d2 authored by Dedy Lansky's avatar Dedy Lansky Committed by Ian Maund
Browse files

wil6210: fix for memory corruption upon rmmod



Driver disabled PCI master before making sure HW is idle.
This caused memory corruption in case HW access system memory after
PCI master got disabled.
The fix is to change uninit sequence. Make sure FW/HW is idle before
disabling PCI

Change-Id: Ib74b3abd8034e61617f1b05daa171fa8fe7862b6
Signed-off-by: default avatarDedy Lansky <qca_dlansky@qca.qualcomm.com>
Signed-off-by: default avatarVladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
Git-commit: f172b56309fbc4835b3f258df6865309dc02e80c
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git


Signed-off-by: default avatarHamad Kadmany <hkadmany@codeaurora.org>
parent 71a5cf59
Loading
Loading
Loading
Loading
+25 −1
Original line number Diff line number Diff line
@@ -20,6 +20,10 @@

#include "wil6210.h"
#include "txrx.h"
#include "wmi.h"

#define WAIT_FOR_DISCONNECT_TIMEOUT_MS 2000
#define WAIT_FOR_DISCONNECT_INTERVAL_MS 10

static bool no_fw_recovery;
module_param(no_fw_recovery, bool, S_IRUGO | S_IWUSR);
@@ -631,6 +635,9 @@ int wil_up(struct wil6210_priv *wil)

static int __wil_down(struct wil6210_priv *wil)
{
	int iter = WAIT_FOR_DISCONNECT_TIMEOUT_MS /
			WAIT_FOR_DISCONNECT_INTERVAL_MS;

	WARN_ON(!mutex_is_locked(&wil->mutex));

	if (wil->platform_ops.bus_request)
@@ -648,7 +655,24 @@ static int __wil_down(struct wil6210_priv *wil)
		wil->scan_request = NULL;
	}

	wil6210_disconnect(wil, NULL);
	if (test_bit(wil_status_fwconnected, &wil->status) ||
	    test_bit(wil_status_fwconnecting, &wil->status))
		wmi_send(wil, WMI_DISCONNECT_CMDID, NULL, 0);

	/* make sure wil is idle (not connected) */
	mutex_unlock(&wil->mutex);
	while (iter--) {
		int idle = !test_bit(wil_status_fwconnected, &wil->status) &&
			   !test_bit(wil_status_fwconnecting, &wil->status);
		if (idle)
			break;
		msleep(WAIT_FOR_DISCONNECT_INTERVAL_MS);
	}
	mutex_lock(&wil->mutex);

	if (!iter)
		wil_err(wil, "timeout waiting for idle FW/HW\n");

	wil_rx_fini(wil);

	return 0;
+1 −1
Original line number Diff line number Diff line
@@ -235,8 +235,8 @@ static void wil_pcie_remove(struct pci_dev *pdev)
	wil_dbg_misc(wil, "%s()\n", __func__);

	wil6210_debugfs_remove(wil);
	wil_if_pcie_disable(wil);
	wil_if_remove(wil);
	wil_if_pcie_disable(wil);
	if (wil->platform_ops.uninit)
		wil->platform_ops.uninit(wil->platform_handle);
	wil_if_free(wil);