diff --git a/core/bmi/inc/bmi.h b/core/bmi/inc/bmi.h index 583a1b117a..586d6355eb 100644 --- a/core/bmi/inc/bmi.h +++ b/core/bmi/inc/bmi.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -54,6 +54,15 @@ QDF_STATUS ol_cds_init(qdf_device_t qdf_dev, void *hif_ctx); void ol_cds_free(void); void ol_init_ini_config(struct ol_context *ol_ctx, struct ol_config_info *cfg); +/** + * ol_set_fw_crashed_cb() - set firmware crashed callback + * @ol_ctx: ol context + * @callback_fn: fw crashed callback function + * + * Return: None + */ +void ol_set_fw_crashed_cb(struct ol_context *ol_ctx, + void (*callback_fn)(void)); void bmi_cleanup(struct ol_context *scn); QDF_STATUS bmi_done(struct ol_context *ol_ctx); void bmi_target_ready(struct hif_opaque_softc *scn, void *cfg_ctx); @@ -76,6 +85,11 @@ ol_init_ini_config(struct ol_context *ol_ctx, struct ol_config_info *cfg) { } +static inline void +ol_set_fw_crashed_cb(struct ol_context *ol_ctx, void (*callback_fn)(void)) +{ +} + static inline void bmi_cleanup(struct ol_context *scn) { } diff --git a/core/bmi/src/i_bmi.h b/core/bmi/src/i_bmi.h index ae9857b328..bde7417987 100644 --- a/core/bmi/src/i_bmi.h +++ b/core/bmi/src/i_bmi.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -154,6 +154,7 @@ struct bmi_info { * @ramdump_work: Work for Ramdump collection * @fw_indication_work: Work for Fw inciation * @tgt_def: Target Defnition pointer + * @fw_crashed_cb: Callback for firmware crashed ind * * Structure to hold all ol BMI/Ramdump info */ @@ -168,6 +169,7 @@ struct ol_context { struct targetdef_t { struct targetdef_s *targetdef; } tgt_def; + void (*fw_crashed_cb)(void); }; #define GET_BMI_CONTEXT(ol_ctx) ((struct bmi_info *)ol_ctx) diff --git a/core/bmi/src/ol_fw.c b/core/bmi/src/ol_fw.c index 9052b1e4c0..8cdb305da7 100644 --- a/core/bmi/src/ol_fw.c +++ b/core/bmi/src/ol_fw.c @@ -546,13 +546,19 @@ struct ramdump_info { /** * if have platform driver support, reinit will be called by CNSS. - * recovery flag will be cleaned by reinit function. If not support, - * clean recovery flag in CLD driver. + * recovery flag will be cleaned and CRASHED indication will be sent + * to user space by reinit function. If not support, clean recovery + * flag and send CRASHED indication in CLD driver. */ -static inline void ol_check_clean_recovery_flag(struct device *dev) +static inline void ol_check_clean_recovery_flag(struct ol_context *ol_ctx) { - if (!pld_have_platform_driver_support(dev)) + qdf_device_t qdf_dev = ol_ctx->qdf_dev; + + if (!pld_have_platform_driver_support(qdf_dev->dev)) { cds_set_recovery_in_progress(false); + if (ol_ctx->fw_crashed_cb) + ol_ctx->fw_crashed_cb(); + } } #if !defined(QCA_WIFI_3_0) @@ -646,7 +652,7 @@ void ramdump_work_handler(void *data) BMI_ERR("HifDiagReadiMem FW Dump Area Pointer failed!"); ol_copy_ramdump(ramdump_scn); pld_device_crashed(qdf_dev->dev); - ol_check_clean_recovery_flag(qdf_dev->dev); + ol_check_clean_recovery_flag(ol_ctx); return; } @@ -673,10 +679,10 @@ void ramdump_work_handler(void *data) */ if (cds_is_load_or_unload_in_progress()) cds_set_recovery_in_progress(false); - else + else { pld_device_crashed(qdf_dev->dev); - - ol_check_clean_recovery_flag(qdf_dev->dev); + ol_check_clean_recovery_flag(ol_ctx); + } return; out_fail: @@ -687,7 +693,7 @@ out_fail: else pld_device_crashed(qdf_dev->dev); - ol_check_clean_recovery_flag(qdf_dev->dev); + ol_check_clean_recovery_flag(ol_ctx); } void fw_indication_work_handler(void *data) @@ -697,6 +703,8 @@ void fw_indication_work_handler(void *data) pld_device_self_recovery(qdf_dev->dev, PLD_REASON_DEFAULT); + + ol_check_clean_recovery_flag(ol_ctx); } void ol_target_failure(void *instance, QDF_STATUS status) @@ -1921,3 +1929,9 @@ void ol_init_ini_config(struct ol_context *ol_ctx, { qdf_mem_copy(&ol_ctx->cfg_info, cfg, sizeof(struct ol_config_info)); } + +void ol_set_fw_crashed_cb(struct ol_context *ol_ctx, + void (*callback_fn)(void)) +{ + ol_ctx->fw_crashed_cb = callback_fn; +} diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 0d2153d3a7..097e5d347d 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -14293,6 +14293,22 @@ void hdd_clean_up_pre_cac_interface(struct hdd_context *hdd_ctx) } +/** + * hdd_svc_fw_crashed_ind() - API to send FW CRASHED IND to Userspace + * + * Return: void + */ +static void hdd_svc_fw_crashed_ind(void) +{ + struct hdd_context *hdd_ctx; + + hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + + hdd_ctx ? wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index, + WLAN_SVC_FW_CRASHED_IND, + NULL, 0) : 0; +} + /** * hdd_update_ol_config - API to update ol configuration parameters * @hdd_ctx: HDD context @@ -14320,6 +14336,7 @@ static void hdd_update_ol_config(struct hdd_context *hdd_ctx) cfg.enable_lpass_support = hdd_lpass_is_supported(hdd_ctx); ol_init_ini_config(ol_ctx, &cfg); + ol_set_fw_crashed_cb(ol_ctx, hdd_svc_fw_crashed_ind); } #ifdef FEATURE_RUNTIME_PM