summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/mwifiex
diff options
context:
space:
mode:
authorAmitkumar Karwar <akarwar@marvell.com>2014-12-31 13:36:41 +0300
committerKalle Valo <kvalo@codeaurora.org>2015-01-06 22:19:44 +0300
commit4636187da60b6e33526050235c610409d9cc00e8 (patch)
treee1bd810c8f421db9e787b2399f0288412bd92f6b /drivers/net/wireless/mwifiex
parentb4f1b177be27103cd84a3692ae71bf857700e27f (diff)
downloadlinux-4636187da60b6e33526050235c610409d9cc00e8.tar.xz
mwifiex: add wakeup timer based recovery mechanism
If host fails to wakeup the firmware, we will trigger card reset after 3 second timeout. Signed-off-by: Cathy Luo <cluo@marvell.com> Signed-off-by: Amitkumar Karwar <akarwar@marvell.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless/mwifiex')
-rw-r--r--drivers/net/wireless/mwifiex/init.c16
-rw-r--r--drivers/net/wireless/mwifiex/main.c2
-rw-r--r--drivers/net/wireless/mwifiex/main.h1
-rw-r--r--drivers/net/wireless/mwifiex/pcie.c1
-rw-r--r--drivers/net/wireless/mwifiex/sta_event.c3
-rw-r--r--drivers/net/wireless/mwifiex/usb.c1
6 files changed, 24 insertions, 0 deletions
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index a3dd601a495a..524692a59d4a 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -52,6 +52,18 @@ static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv)
return 0;
}
+static void wakeup_timer_fn(unsigned long data)
+{
+ struct mwifiex_adapter *adapter = (struct mwifiex_adapter *)data;
+
+ dev_err(adapter->dev, "Firmware wakeup failed\n");
+ adapter->hw_status = MWIFIEX_HW_STATUS_RESET;
+ mwifiex_cancel_all_pending_cmd(adapter);
+
+ if (adapter->if_ops.card_reset)
+ adapter->if_ops.card_reset(adapter);
+}
+
/*
* This function initializes the private structure and sets default
* values to the members.
@@ -285,6 +297,9 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
adapter->ext_scan = true;
adapter->key_api_major_ver = 0;
adapter->key_api_minor_ver = 0;
+
+ setup_timer(&adapter->wakeup_timer, wakeup_timer_fn,
+ (unsigned long)adapter);
}
/*
@@ -391,6 +406,7 @@ mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
return;
}
+ del_timer(&adapter->wakeup_timer);
mwifiex_cancel_all_pending_cmd(adapter);
/* Free lock variables */
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 2d4047f4be17..119e87574e83 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -237,6 +237,7 @@ process_start:
(is_command_pending(adapter) ||
!mwifiex_wmm_lists_empty(adapter))) {
adapter->pm_wakeup_fw_try = true;
+ mod_timer(&adapter->wakeup_timer, jiffies + (HZ*3));
adapter->if_ops.wakeup(adapter);
continue;
}
@@ -244,6 +245,7 @@ process_start:
if (IS_CARD_RX_RCVD(adapter)) {
adapter->data_received = false;
adapter->pm_wakeup_fw_try = false;
+ del_timer_sync(&adapter->wakeup_timer);
if (adapter->ps_state == PS_STATE_SLEEP)
adapter->ps_state = PS_STATE_AWAKE;
} else {
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index f9279399226a..55273eefb785 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -830,6 +830,7 @@ struct mwifiex_adapter {
u16 gen_null_pkt;
u16 pps_uapsd_mode;
u32 pm_wakeup_fw_try;
+ struct timer_list wakeup_timer;
u8 is_hs_configured;
struct mwifiex_hs_config_param hs_cfg;
u8 hs_activated;
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index c3a20f94f3c9..10e4a93d3d56 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -2064,6 +2064,7 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
* state until cookie is set */
adapter->ps_state = PS_STATE_AWAKE;
adapter->pm_wakeup_fw_try = false;
+ del_timer(&adapter->wakeup_timer);
}
}
}
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index fbec95bbc10f..419e35f1dbf3 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -312,6 +312,8 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
adapter->ps_state = PS_STATE_AWAKE;
adapter->pm_wakeup_card_req = false;
adapter->pm_wakeup_fw_try = false;
+ mod_timer(&adapter->wakeup_timer,
+ jiffies + (HZ*3));
break;
}
if (!mwifiex_send_null_packet
@@ -326,6 +328,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
adapter->ps_state = PS_STATE_AWAKE;
adapter->pm_wakeup_card_req = false;
adapter->pm_wakeup_fw_try = false;
+ del_timer_sync(&adapter->wakeup_timer);
break;
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c
index 8ae7a8586811..199b43f89e01 100644
--- a/drivers/net/wireless/mwifiex/usb.c
+++ b/drivers/net/wireless/mwifiex/usb.c
@@ -990,6 +990,7 @@ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
{
/* Simulation of HS_AWAKE event */
adapter->pm_wakeup_fw_try = false;
+ del_timer_sync(&adapter->wakeup_timer);
adapter->pm_wakeup_card_req = false;
adapter->ps_state = PS_STATE_AWAKE;