summaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/marvell/mwifiex/pcie.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
index 641fa539de1f..c3f5583ea70d 100644
--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
+++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
@@ -17,6 +17,7 @@
* this warranty disclaimer.
*/
+#include <linux/iopoll.h>
#include <linux/firmware.h>
#include "decl.h"
@@ -647,11 +648,15 @@ static void mwifiex_delay_for_sleep_cookie(struct mwifiex_adapter *adapter,
"max count reached while accessing sleep cookie\n");
}
+#define N_WAKEUP_TRIES_SHORT_INTERVAL 15
+#define N_WAKEUP_TRIES_LONG_INTERVAL 35
+
/* This function wakes up the card by reading fw_status register. */
static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
{
struct pcie_service_card *card = adapter->card;
const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
+ int retval;
mwifiex_dbg(adapter, EVENT,
"event: Wakeup device...\n");
@@ -659,11 +664,24 @@ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
if (reg->sleep_cookie)
mwifiex_pcie_dev_wakeup_delay(adapter);
- /* Accessing fw_status register will wakeup device */
- if (mwifiex_write_reg(adapter, reg->fw_status, FIRMWARE_READY_PCIE)) {
- mwifiex_dbg(adapter, ERROR,
- "Writing fw_status register failed\n");
- return -1;
+ /* The 88W8897 PCIe+USB firmware (latest version 15.68.19.p21) sometimes
+ * appears to ignore or miss our wakeup request, so we continue trying
+ * until we receive an interrupt from the card.
+ */
+ if (read_poll_timeout(mwifiex_write_reg, retval,
+ READ_ONCE(adapter->int_status) != 0,
+ 500, 500 * N_WAKEUP_TRIES_SHORT_INTERVAL,
+ false,
+ adapter, reg->fw_status, FIRMWARE_READY_PCIE)) {
+ if (read_poll_timeout(mwifiex_write_reg, retval,
+ READ_ONCE(adapter->int_status) != 0,
+ 10000, 10000 * N_WAKEUP_TRIES_LONG_INTERVAL,
+ false,
+ adapter, reg->fw_status, FIRMWARE_READY_PCIE)) {
+ mwifiex_dbg(adapter, ERROR,
+ "Firmware didn't wake up\n");
+ return -EIO;
+ }
}
if (reg->sleep_cookie) {