summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCNSS_WLAN Service <cnssbldsw@qualcomm.com>2017-09-25 07:44:20 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2017-09-25 07:44:20 -0700
commit528e4d91f8dbbbc8dadce117bf9df3cea93937e6 (patch)
tree3ac4a069dc6dfd7a88f9d6bb9872c55f0411d3dc
parent289334aaede82684dd22c26706d368393309f533 (diff)
parentd793dadff1c4a9e3010ff306d6aa4271c6604098 (diff)
Merge "qcacld-3.0: Set up watchdog timers for pld driver ops" into wlan-cld3.driver.lnx.1.1
-rw-r--r--core/hdd/inc/wlan_hdd_main.h36
-rw-r--r--core/hdd/src/wlan_hdd_driver_ops.c15
-rw-r--r--core/hdd/src/wlan_hdd_main.c71
3 files changed, 122 insertions, 0 deletions
diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h
index 753093d88f57..fd60b2ff11f0 100644
--- a/core/hdd/inc/wlan_hdd_main.h
+++ b/core/hdd/inc/wlan_hdd_main.h
@@ -323,6 +323,19 @@
#define WLAN_NUD_STATS_ARP_PKT_TYPE 1
/*
+ * @eHDD_DRV_OP_PROBE: Refers to .probe operation
+ * @eHDD_DRV_OP_REMOVE: Refers to .remove operation
+ * @eHDD_DRV_OP_SHUTDOWN: Refers to .shutdown operation
+ * @eHDD_DRV_OP_REINIT: Refers to .reinit operation
+ */
+enum {
+ eHDD_DRV_OP_PROBE = 0,
+ eHDD_DRV_OP_REMOVE,
+ eHDD_DRV_OP_SHUTDOWN,
+ eHDD_DRV_OP_REINIT
+};
+
+/*
* @eHDD_SCAN_REJECT_DEFAULT: default value
* @eHDD_CONNECTION_IN_PROGRESS: connection is in progress
* @eHDD_REASSOC_IN_PROGRESS: reassociation is in progress
@@ -2796,4 +2809,27 @@ hdd_nla_parse_nested(struct nlattr *tb[], int maxtype, const struct nlattr *nla,
*/
void hdd_pld_ipa_uc_shutdown_pipes(void);
+/**
+ * hdd_drv_ops_inactivity_handler() - Timeout handler for driver ops
+ * inactivity timer
+ *
+ * Return: None
+ */
+void hdd_drv_ops_inactivity_handler(void);
+
+/**
+ * hdd_start_driver_ops_timer() - Starts driver ops inactivity timer
+ * @drv_op: Enum indicating driver op
+ *
+ * Return: none
+ */
+void hdd_start_driver_ops_timer(int drv_op);
+
+/**
+ * hdd_stop_driver_ops_timer() - Stops driver ops inactivity timer
+ *
+ * Return: none
+ */
+void hdd_stop_driver_ops_timer(void);
+
#endif /* end #if !defined(WLAN_HDD_MAIN_H) */
diff --git a/core/hdd/src/wlan_hdd_driver_ops.c b/core/hdd/src/wlan_hdd_driver_ops.c
index e1335e475401..45ced4b8c1eb 100644
--- a/core/hdd/src/wlan_hdd_driver_ops.c
+++ b/core/hdd/src/wlan_hdd_driver_ops.c
@@ -338,6 +338,11 @@ static int wlan_hdd_probe(struct device *dev, void *bdev, const struct hif_bus_i
int ret = 0;
mutex_lock(&hdd_init_deinit_lock);
+ if (!reinit)
+ hdd_start_driver_ops_timer(eHDD_DRV_OP_PROBE);
+ else
+ hdd_start_driver_ops_timer(eHDD_DRV_OP_REINIT);
+
pr_info("%s: %sprobing driver v%s\n", WLAN_MODULE_NAME,
reinit ? "re-" : "", QWLAN_VERSIONSTR);
@@ -387,6 +392,7 @@ static int wlan_hdd_probe(struct device *dev, void *bdev, const struct hif_bus_i
cds_set_driver_in_bad_state(false);
probe_fail_cnt = 0;
re_init_fail_cnt = 0;
+ hdd_stop_driver_ops_timer();
mutex_unlock(&hdd_init_deinit_lock);
return 0;
@@ -408,6 +414,7 @@ err_hdd_deinit:
hdd_remove_pm_qos(dev);
cds_clear_fw_state(CDS_FW_STATE_DOWN);
+ hdd_stop_driver_ops_timer();
mutex_unlock(&hdd_init_deinit_lock);
return ret;
}
@@ -1107,7 +1114,11 @@ static void wlan_hdd_pld_remove(struct device *dev,
{
ENTER();
mutex_lock(&hdd_init_deinit_lock);
+ hdd_start_driver_ops_timer(eHDD_DRV_OP_REMOVE);
+
wlan_hdd_remove(dev);
+
+ hdd_stop_driver_ops_timer();
mutex_unlock(&hdd_init_deinit_lock);
EXIT();
}
@@ -1124,7 +1135,11 @@ static void wlan_hdd_pld_shutdown(struct device *dev,
{
ENTER();
mutex_lock(&hdd_init_deinit_lock);
+ hdd_start_driver_ops_timer(eHDD_DRV_OP_SHUTDOWN);
+
wlan_hdd_shutdown();
+
+ hdd_stop_driver_ops_timer();
mutex_unlock(&hdd_init_deinit_lock);
EXIT();
}
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
index 39f5944a25d2..87858cf66631 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -162,6 +162,12 @@ static struct attribute *attrs[] = {
#define MODULE_INITIALIZED 1
#endif
+#define HDD_OPS_INACTIVITY_TIMEOUT (120000)
+#define MAX_OPS_NAME_STRING_SIZE 20
+
+static qdf_timer_t hdd_drv_ops_inactivity_timer;
+static char drv_ops_string[MAX_OPS_NAME_STRING_SIZE];
+
/* the Android framework expects this param even though we don't use it */
#define BUF_LEN 20
static char fwpath_buffer[BUF_LEN];
@@ -11049,6 +11055,10 @@ int hdd_init(void)
goto err_out;
}
+ qdf_timer_init(NULL, &hdd_drv_ops_inactivity_timer,
+ (void *)hdd_drv_ops_inactivity_handler, NULL,
+ QDF_TIMER_TYPE_SW);
+
hdd_trace_init();
hdd_register_debug_callback();
@@ -11071,6 +11081,7 @@ void hdd_deinit(void)
wlan_logging_sock_deinit_svc();
#endif
+ qdf_timer_free(&hdd_drv_ops_inactivity_timer);
wlan_destroy_bug_report_lock();
cds_deinit();
}
@@ -12146,6 +12157,66 @@ void hdd_pld_ipa_uc_shutdown_pipes(void)
hdd_ipa_uc_force_pipe_shutdown(hdd_ctx);
}
+/**
+ * hdd_start_driver_ops_timer() - Starts driver ops inactivity timer
+ * @drv_op: Enum indicating driver op
+ *
+ * Return: none
+ */
+void hdd_start_driver_ops_timer(int drv_op)
+{
+ memset(drv_ops_string, 0, MAX_OPS_NAME_STRING_SIZE);
+ switch (drv_op) {
+ case eHDD_DRV_OP_PROBE:
+ memcpy(drv_ops_string, "probe", sizeof("probe"));
+ break;
+ case eHDD_DRV_OP_REMOVE:
+ memcpy(drv_ops_string, "remove", sizeof("remove"));
+ break;
+ case eHDD_DRV_OP_SHUTDOWN:
+ memcpy(drv_ops_string, "shutdown", sizeof("shutdown"));
+ break;
+ case eHDD_DRV_OP_REINIT:
+ memcpy(drv_ops_string, "reinit", sizeof("reinit"));
+ break;
+ }
+
+ qdf_timer_start(&hdd_drv_ops_inactivity_timer,
+ HDD_OPS_INACTIVITY_TIMEOUT);
+}
+
+/**
+ * hdd_stop_driver_ops_timer() - Stops driver ops inactivity timer
+ *
+ * Return: none
+ */
+void hdd_stop_driver_ops_timer(void)
+{
+ qdf_timer_sync_cancel(&hdd_drv_ops_inactivity_timer);
+}
+
+/**
+ * hdd_drv_ops_inactivity_handler() - Timeout handler for driver ops
+ * inactivity timer
+ *
+ * Return: None
+ */
+void hdd_drv_ops_inactivity_handler(void)
+{
+ hdd_err("%s: %d Sec timer expired while in .%s",
+ __func__, HDD_OPS_INACTIVITY_TIMEOUT/1000, drv_ops_string);
+
+ /* Driver shutdown is stuck, no recovery possible at this point */
+ if (0 == qdf_mem_cmp(&drv_ops_string[0], "shutdown",
+ sizeof("shutdown")))
+ QDF_BUG(0);
+
+ if (cds_is_self_recovery_enabled())
+ cds_trigger_recovery(false);
+ else
+ QDF_BUG(0);
+}
+
/* Register the module init/exit functions */
module_init(hdd_module_init);
module_exit(hdd_module_exit);