Commit f172b563 authored by Dedy Lansky's avatar Dedy Lansky Committed by John W. Linville

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
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>
parent 69778059
...@@ -20,6 +20,10 @@ ...@@ -20,6 +20,10 @@
#include "wil6210.h" #include "wil6210.h"
#include "txrx.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; static bool no_fw_recovery;
module_param(no_fw_recovery, bool, S_IRUGO | S_IWUSR); module_param(no_fw_recovery, bool, S_IRUGO | S_IWUSR);
...@@ -631,6 +635,9 @@ int wil_up(struct wil6210_priv *wil) ...@@ -631,6 +635,9 @@ int wil_up(struct wil6210_priv *wil)
static int __wil_down(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)); WARN_ON(!mutex_is_locked(&wil->mutex));
if (wil->platform_ops.bus_request) if (wil->platform_ops.bus_request)
...@@ -648,7 +655,24 @@ static int __wil_down(struct wil6210_priv *wil) ...@@ -648,7 +655,24 @@ static int __wil_down(struct wil6210_priv *wil)
wil->scan_request = NULL; 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); wil_rx_fini(wil);
return 0; return 0;
......
...@@ -233,8 +233,8 @@ static void wil_pcie_remove(struct pci_dev *pdev) ...@@ -233,8 +233,8 @@ static void wil_pcie_remove(struct pci_dev *pdev)
wil_dbg_misc(wil, "%s()\n", __func__); wil_dbg_misc(wil, "%s()\n", __func__);
wil6210_debugfs_remove(wil); wil6210_debugfs_remove(wil);
wil_if_pcie_disable(wil);
wil_if_remove(wil); wil_if_remove(wil);
wil_if_pcie_disable(wil);
if (wil->platform_ops.uninit) if (wil->platform_ops.uninit)
wil->platform_ops.uninit(wil->platform_handle); wil->platform_ops.uninit(wil->platform_handle);
wil_if_free(wil); wil_if_free(wil);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment