Skip to content

Commit

Permalink
mwifiex: fix cmd and Tx data timeout issue for PCIe cards
Browse files Browse the repository at this point in the history
We are sending sleep confirm done interrupt in the middle of
sleep handshake. There is a corner case when Tx done interrupt
is received from firmware during sleep handshake due to which
host and firmware power states go out of sync causing cmd and
Tx data timeout problem.

Hence sleep confirm done interrupt is sent at the end of sleep
handshake to fix the problem.

Cc: <stable@vger.kernel.org> # 3.10+
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Amitkumar Karwar authored and John W. Linville committed Feb 20, 2014
1 parent bb8e6a1 commit 1c97560
Showing 1 changed file with 11 additions and 17 deletions.
28 changes: 11 additions & 17 deletions drivers/net/wireless/mwifiex/pcie.c
Original file line number Diff line number Diff line change
Expand Up @@ -1531,6 +1531,14 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
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)) {
dev_warn(adapter->dev,
"Write register failed\n");
return -1;
}
while (reg->sleep_cookie && (count++ < 10) &&
mwifiex_pcie_ok_to_access_hw(adapter))
usleep_range(50, 60);
Expand Down Expand Up @@ -1999,23 +2007,9 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
adapter->int_status |= pcie_ireg;
spin_unlock_irqrestore(&adapter->int_lock, flags);

if (pcie_ireg & HOST_INTR_CMD_DONE) {
if ((adapter->ps_state == PS_STATE_SLEEP_CFM) ||
(adapter->ps_state == PS_STATE_SLEEP)) {
mwifiex_pcie_enable_host_int(adapter);
if (mwifiex_write_reg(adapter,
PCIE_CPU_INT_EVENT,
CPU_INTR_SLEEP_CFM_DONE)
) {
dev_warn(adapter->dev,
"Write register failed\n");
return;

}
}
} else if (!adapter->pps_uapsd_mode &&
adapter->ps_state == PS_STATE_SLEEP &&
mwifiex_pcie_ok_to_access_hw(adapter)) {
if (!adapter->pps_uapsd_mode &&
adapter->ps_state == PS_STATE_SLEEP &&
mwifiex_pcie_ok_to_access_hw(adapter)) {
/* Potentially for PCIe we could get other
* interrupts like shared. Don't change power
* state until cookie is set */
Expand Down

0 comments on commit 1c97560

Please sign in to comment.