Message ID | 1475066908-11771-1-git-send-email-akarwar@marvell.com (mailing list archive) |
---|---|
State | Accepted |
Commit | ec815dd2a5f110f627d7955e0027a3a008f68166 |
Delegated to: | Kalle Valo |
Headers | show |
Hi, On Wed, Sep 28, 2016 at 06:18:21PM +0530, Amitkumar Karwar wrote: > Following is mwifiex driver-firmware host sleep handshake. > It involves three threads. suspend handler, interrupt handler, interrupt > processing in main work queue. > > 1) Enter suspend handler > 2) Download HS_CFG command > 3) Response from firmware for HS_CFG > 4) Suspend thread waits until handshake completes(i.e hs_activate becomes > true) > 5) SLEEP from firmware > 6) SLEEP confirm downloaded to firmware. > 7) SLEEP confirm response from firmware > 8) Driver processes SLEEP confirm response and set hs_activate to wake up > suspend thread > 9) Exit suspend handler > 10) Read sleep cookie in loop and wait until it indicates firmware is > sleep. > 11) After processing SLEEP confirm response, we are at the end of interrupt > processing routine. Recheck if there are interrupts received while we were > processing them. > > During suspend-resume stress test, it's been observed that we may end up > acessing PCIe hardware(in 10 and 11) when PCIe bus is closed which leads > to a kernel crash. > > This patch solves the problem with below changes. > a) action 10 above can be done before 8 > b) Skip 11 if hs_activated is true. SLEEP confirm response > is the last interrupt from firmware. No need to recheck for > pending interrupts. > c) Add flush_workqueue() in suspend handler. > > Signed-off-by: Amitkumar Karwar <akarwar@marvell.com> Reviewed-by: Brian Norris <briannorris@chromium.org> Tested-by: Brian Norris <briannorris@chromium.org> > --- > drivers/net/wireless/marvell/mwifiex/pcie.c | 9 ++++++--- > 1 file changed, 6 insertions(+), 3 deletions(-) > > diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c > index 3c3c4f1..2833d47 100644 > --- a/drivers/net/wireless/marvell/mwifiex/pcie.c > +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c > @@ -118,6 +118,7 @@ static int mwifiex_pcie_suspend(struct device *dev) > adapter = card->adapter; > > hs_actived = mwifiex_enable_hs(adapter); > + flush_workqueue(adapter->workqueue); > > /* Indicate device suspended */ > adapter->is_suspended = true; > @@ -1669,9 +1670,6 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) > > if (!adapter->curr_cmd) { > if (adapter->ps_state == PS_STATE_SLEEP_CFM) { > - mwifiex_process_sleep_confirm_resp(adapter, skb->data, > - skb->len); > - mwifiex_pcie_enable_host_int(adapter); > if (mwifiex_write_reg(adapter, > PCIE_CPU_INT_EVENT, > CPU_INTR_SLEEP_CFM_DONE)) { > @@ -1684,6 +1682,9 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) > while (reg->sleep_cookie && (count++ < 10) && > mwifiex_pcie_ok_to_access_hw(adapter)) > usleep_range(50, 60); > + mwifiex_pcie_enable_host_int(adapter); > + mwifiex_process_sleep_confirm_resp(adapter, skb->data, > + skb->len); > } else { > mwifiex_dbg(adapter, ERROR, > "There is no command but got cmdrsp\n"); > @@ -2322,6 +2323,8 @@ static int mwifiex_process_pcie_int(struct mwifiex_adapter *adapter) > ret = mwifiex_pcie_process_cmd_complete(adapter); > if (ret) > return ret; > + if (adapter->hs_activated) > + return ret; > } > > if (card->msi_enable) { >
Amitkumar Karwar <akarwar@marvell.com> wrote: > Following is mwifiex driver-firmware host sleep handshake. > It involves three threads. suspend handler, interrupt handler, interrupt > processing in main work queue. > > 1) Enter suspend handler > 2) Download HS_CFG command > 3) Response from firmware for HS_CFG > 4) Suspend thread waits until handshake completes(i.e hs_activate becomes > true) > 5) SLEEP from firmware > 6) SLEEP confirm downloaded to firmware. > 7) SLEEP confirm response from firmware > 8) Driver processes SLEEP confirm response and set hs_activate to wake up > suspend thread > 9) Exit suspend handler > 10) Read sleep cookie in loop and wait until it indicates firmware is > sleep. > 11) After processing SLEEP confirm response, we are at the end of interrupt > processing routine. Recheck if there are interrupts received while we were > processing them. > > During suspend-resume stress test, it's been observed that we may end up > acessing PCIe hardware(in 10 and 11) when PCIe bus is closed which leads > to a kernel crash. > > This patch solves the problem with below changes. > a) action 10 above can be done before 8 > b) Skip 11 if hs_activated is true. SLEEP confirm response > is the last interrupt from firmware. No need to recheck for > pending interrupts. > c) Add flush_workqueue() in suspend handler. > > Signed-off-by: Amitkumar Karwar <akarwar@marvell.com> > Reviewed-by: Brian Norris <briannorris@chromium.org> > Tested-by: Brian Norris <briannorris@chromium.org> 8 patches applied to wireless-drivers-next.git, thanks. ec815dd2a5f1 mwifiex: prevent register accesses after host is sleeping 5190f2e40591 mwifiex: report error to PCIe for suspend failure c44c040300d7 mwifiex: Fix NULL pointer dereference in skb_dequeue() 113630b581d6 mwifiex: vendor_ie length check for parse WMM IEs a936ea543657 mwifiex: add memrw command information in README 77f486c8bb39 mwifiex: update tx_pkts_queued for requeued packets 49abe5c83cd0 mwifiex: fix command timeout problem seen in stress tests 3d8bd85c2c9e mwifiex: fix p2p device doesn't find in scan problem
diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c index 3c3c4f1..2833d47 100644 --- a/drivers/net/wireless/marvell/mwifiex/pcie.c +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c @@ -118,6 +118,7 @@ static int mwifiex_pcie_suspend(struct device *dev) adapter = card->adapter; hs_actived = mwifiex_enable_hs(adapter); + flush_workqueue(adapter->workqueue); /* Indicate device suspended */ adapter->is_suspended = true; @@ -1669,9 +1670,6 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) if (!adapter->curr_cmd) { if (adapter->ps_state == PS_STATE_SLEEP_CFM) { - mwifiex_process_sleep_confirm_resp(adapter, skb->data, - skb->len); - mwifiex_pcie_enable_host_int(adapter); if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, CPU_INTR_SLEEP_CFM_DONE)) { @@ -1684,6 +1682,9 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) while (reg->sleep_cookie && (count++ < 10) && mwifiex_pcie_ok_to_access_hw(adapter)) usleep_range(50, 60); + mwifiex_pcie_enable_host_int(adapter); + mwifiex_process_sleep_confirm_resp(adapter, skb->data, + skb->len); } else { mwifiex_dbg(adapter, ERROR, "There is no command but got cmdrsp\n"); @@ -2322,6 +2323,8 @@ static int mwifiex_process_pcie_int(struct mwifiex_adapter *adapter) ret = mwifiex_pcie_process_cmd_complete(adapter); if (ret) return ret; + if (adapter->hs_activated) + return ret; } if (card->msi_enable) {
Following is mwifiex driver-firmware host sleep handshake. It involves three threads. suspend handler, interrupt handler, interrupt processing in main work queue. 1) Enter suspend handler 2) Download HS_CFG command 3) Response from firmware for HS_CFG 4) Suspend thread waits until handshake completes(i.e hs_activate becomes true) 5) SLEEP from firmware 6) SLEEP confirm downloaded to firmware. 7) SLEEP confirm response from firmware 8) Driver processes SLEEP confirm response and set hs_activate to wake up suspend thread 9) Exit suspend handler 10) Read sleep cookie in loop and wait until it indicates firmware is sleep. 11) After processing SLEEP confirm response, we are at the end of interrupt processing routine. Recheck if there are interrupts received while we were processing them. During suspend-resume stress test, it's been observed that we may end up acessing PCIe hardware(in 10 and 11) when PCIe bus is closed which leads to a kernel crash. This patch solves the problem with below changes. a) action 10 above can be done before 8 b) Skip 11 if hs_activated is true. SLEEP confirm response is the last interrupt from firmware. No need to recheck for pending interrupts. c) Add flush_workqueue() in suspend handler. Signed-off-by: Amitkumar Karwar <akarwar@marvell.com> --- drivers/net/wireless/marvell/mwifiex/pcie.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)