diff options
| author | CNSS_WLAN Service <cnssbldsw@qualcomm.com> | 2017-09-25 07:44:20 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-09-25 07:44:20 -0700 |
| commit | 528e4d91f8dbbbc8dadce117bf9df3cea93937e6 (patch) | |
| tree | 3ac4a069dc6dfd7a88f9d6bb9872c55f0411d3dc | |
| parent | 289334aaede82684dd22c26706d368393309f533 (diff) | |
| parent | d793dadff1c4a9e3010ff306d6aa4271c6604098 (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.h | 36 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_driver_ops.c | 15 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_main.c | 71 |
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); |
