diff --git a/Kbuild b/Kbuild index d239ab8f7ae6..5ad44b52f03e 100644 --- a/Kbuild +++ b/Kbuild @@ -225,6 +225,10 @@ ifeq ($(CONFIG_WLAN_SYSFS), y) HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs.o endif +ifeq ($(CONFIG_QCACLD_FEATURE_FW_STATE), y) +HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_fw_state.o +endif + ###### OSIF_SYNC ######## SYNC_DIR := os_if/sync SYNC_INC_DIR := $(SYNC_DIR)/inc @@ -1650,6 +1654,9 @@ endif ifeq ($(CONFIG_WLAN_FEATURE_TWT), y) WMA_OBJS += $(WMA_SRC_DIR)/wma_twt.o endif +ifeq ($(CONFIG_QCACLD_FEATURE_FW_STATE), y) +WMA_OBJS += $(WMA_SRC_DIR)/wma_fw_state.o +endif ############## PLD ########## PLD_DIR := core/pld PLD_INC_DIR := $(PLD_DIR)/inc @@ -2497,6 +2504,9 @@ cppflags-$(CONFIG_TARGET_11D_SCAN) += -DTARGET_11D_SCAN #Flag to enable Dynamic Voltage WDCVS (Config Voltage Mode) cppflags-$(CONFIG_WLAN_DYNAMIC_CVM) += -DFEATURE_WLAN_DYNAMIC_CVM +#Flag to enable get firmware state feature +cppflags-$(CONFIG_QCACLD_FEATURE_FW_STATE) += -DFEATURE_FW_STATE + ifdef CONFIG_MAX_LOGS_PER_SEC ccflags-y += -DWLAN_MAX_LOGS_PER_SEC=$(CONFIG_MAX_LOGS_PER_SEC) endif diff --git a/configs/default_defconfig b/configs/default_defconfig index 1e856f72cb8d..fea21503ad68 100644 --- a/configs/default_defconfig +++ b/configs/default_defconfig @@ -116,6 +116,9 @@ CONFIG_QCACLD_FEATURE_APF := y #Flag to enable SARv1 -> SARv2 conversion CONFIG_WLAN_FEATURE_SARV1_TO_SARV2 := n +#Flag to enable get firmware state +CONFIG_QCACLD_FEATURE_FW_STATE := y + ifeq ($(CONFIG_ARCH_MSM8998), y) CONFIG_QCACLD_FEATURE_METERING := y endif diff --git a/core/hdd/inc/wlan_hdd_fw_state.h b/core/hdd/inc/wlan_hdd_fw_state.h new file mode 100644 index 000000000000..b28de4b2d8f4 --- /dev/null +++ b/core/hdd/inc/wlan_hdd_fw_state.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 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 + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: wlan_hdd_fw_state.h + * + * Get firmware state related API's and definitions + */ + +#ifndef __WLAN_HDD_FW_STATE_H +#define __WLAN_HDD_FW_STATE_H + +#ifdef FEATURE_FW_STATE +#include +/** + * wlan_hdd_cfg80211_get_fw_status() - get fw state + * @wiphy: wiphy pointer + * @wdev: pointer to struct wireless_dev + * @data: pointer to incoming NL vendor data + * @data_len: length of @data + * + * Return: 0 on success; error number otherwise. + */ +int wlan_hdd_cfg80211_get_fw_state(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len); + +#define FEATURE_FW_STATE_COMMANDS \ +{ \ + .info.vendor_id = QCA_NL80211_VENDOR_ID, \ + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_FW_STATE, \ + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | \ + WIPHY_VENDOR_CMD_NEED_NETDEV, \ + .doit = wlan_hdd_cfg80211_get_fw_state \ +}, +#else /* FEATURE_FW_STATE */ +#define FEATURE_FW_STATE_COMMANDS +#endif /* FEATURE_FW_STATE */ +#endif /* __WLAN_HDD_FW_STATE_H */ diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 5989ccf8579a..98b53928be51 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -94,6 +94,7 @@ #ifdef FEATURE_WLAN_APF #include "wlan_hdd_apf.h" #endif +#include "wlan_hdd_fw_state.h" #include #include @@ -12452,6 +12453,7 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = { FEATURE_ACTIVE_TOS_VENDOR_COMMANDS FEATURE_NAN_VENDOR_COMMANDS + FEATURE_FW_STATE_COMMANDS }; struct hdd_context *hdd_cfg80211_wiphy_alloc(void) diff --git a/core/hdd/src/wlan_hdd_fw_state.c b/core/hdd/src/wlan_hdd_fw_state.c new file mode 100644 index 000000000000..1759ea70559b --- /dev/null +++ b/core/hdd/src/wlan_hdd_fw_state.c @@ -0,0 +1,204 @@ +/* + * Copyright (c) 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 + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: wlan_hdd_fw_state.c + * + * The implementation for getting firmware state + */ + +#include "wlan_hdd_main.h" +#include "wmi_unified_param.h" +#include "wlan_hdd_fw_state.h" +#include "qca_vendor.h" +#include "wlan_osif_request_manager.h" + +struct fw_state { + bool fw_active; +}; + +/** + * hdd_get_fw_state_cb() - Callback function to get fw state + * @context: opaque context originally passed to SME. HDD always passes + * a cookie for the request context + * + * This function receives the response/data from the lower layer and + * checks to see if the thread is still waiting then post the results to + * upper layer, if the request has timed out then ignore. + * + * Return: None + */ +static void hdd_get_fw_state_cb(void *context) +{ + struct osif_request *request; + struct fw_state *priv; + + hdd_enter(); + + request = osif_request_get(context); + if (!request) { + hdd_err("Obsolete request"); + return; + } + + priv = osif_request_priv(request); + priv->fw_active = true; + osif_request_complete(request); + osif_request_put(request); +} + +/** + * hdd_post_get_fw_state_rsp - send rsp to user space + * @hdd_ctx: pointer to hdd context + * @state: true for fw active, false for fw error state + * + * Return: 0 for success, non-zero for failure + */ +static int hdd_post_get_fw_state_rsp(struct hdd_context *hdd_ctx, + bool state) +{ + struct sk_buff *skb; + enum qca_wlan_vendor_attr_fw_state fw_state; + + skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, + sizeof(uint8_t) + + NLA_HDRLEN + + NLMSG_HDRLEN); + + if (!skb) { + hdd_err("cfg80211_vendor_event_alloc failed"); + return -ENOMEM; + } + + if (state) + fw_state = QCA_WLAN_VENDOR_ATTR_FW_STATE_ACTIVE; + else + fw_state = QCA_WLAN_VENDOR_ATTR_FW_STATE_ERROR; + + if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_FW_STATE, + (uint8_t)fw_state)) { + hdd_err("put fail"); + goto nla_put_failure; + } + + cfg80211_vendor_cmd_reply(skb); + return 0; + +nla_put_failure: + kfree_skb(skb); + return -EINVAL; +} + +/** + * __wlan_hdd_cfg80211_get_fw_state() - get fw state + * @wiphy: pointer to wireless wiphy structure. + * @wdev: pointer to wireless_dev structure. + * @data: Pointer to the data to be passed via vendor interface + * @data_len:Length of the data to be passed + * + * This function sends a request to fw and waits on a timer to + * invoke the callback. if the callback is invoked then true + * will be returned or otherwise fail status will be returned. + * + * Return: 0 on success; error number otherwise. + **/ +static int __wlan_hdd_cfg80211_get_fw_state(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + struct hdd_context *hdd_ctx = wiphy_priv(wiphy); + mac_handle_t mac_handle; + QDF_STATUS status; + int retval; + void *cookie; + struct osif_request *request; + struct fw_state *priv; + static const struct osif_request_params params = { + .priv_size = sizeof(*priv), + .timeout_ms = WLAN_WAIT_TIME_STATS, + }; + bool state = false; + + hdd_enter_dev(wdev->netdev); + + retval = wlan_hdd_validate_context(hdd_ctx); + if (retval) + return retval; + + if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { + hdd_err("Command not allowed in FTM mode"); + return -EPERM; + } + + request = osif_request_alloc(¶ms); + if (!request) { + hdd_err("Request allocation failure"); + return -ENOMEM; + } + cookie = osif_request_cookie(request); + + mac_handle = hdd_ctx->mac_handle; + status = sme_get_fw_state(mac_handle, + hdd_get_fw_state_cb, + cookie); + if (QDF_STATUS_SUCCESS != status) { + hdd_err("Unable to get fw state"); + retval = qdf_status_to_os_return(status); + } else { + retval = osif_request_wait_for_response(request); + if (retval) { + hdd_err("Target response timed out"); + state = false; + } else { + priv = osif_request_priv(request); + state = priv->fw_active; + } + } + retval = hdd_post_get_fw_state_rsp(hdd_ctx, state); + if (retval) + hdd_err("Failed to post fw state"); + + osif_request_put(request); + + hdd_exit(); + return retval; +} + +/** + * wlan_hdd_cfg80211_get_fw_status() - get fw state + * @wiphy: wiphy pointer + * @wdev: pointer to struct wireless_dev + * @data: pointer to incoming NL vendor data + * @data_len: length of @data + * + * Return: 0 on success; error number otherwise. + */ +int wlan_hdd_cfg80211_get_fw_state(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + int ret; + + cds_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_get_fw_state(wiphy, wdev, data, data_len); + cds_ssr_unprotect(__func__); + + return ret; +} diff --git a/core/mac/inc/wni_api.h b/core/mac/inc/wni_api.h index c37968250f8f..ae02e96f846e 100644 --- a/core/mac/inc/wni_api.h +++ b/core/mac/inc/wni_api.h @@ -236,7 +236,8 @@ enum eWniMsgTypes { WNI_SME_CFG_ACTION_FRM_HE_TB_PPDU = SIR_SME_MSG_TYPES_BEGIN + 150, /* To indicate Hidden ssid start complition to upper layer */ eWNI_SME_HIDDEN_SSID_RESTART_RSP = SIR_SME_MSG_TYPES_BEGIN + 151, - eWNI_SME_MSG_TYPES_END = SIR_SME_MSG_TYPES_BEGIN + 152 + eWNI_SME_FW_STATUS_IND = SIR_SME_MSG_TYPES_BEGIN + 152, + eWNI_SME_MSG_TYPES_END = SIR_SME_MSG_TYPES_BEGIN + 153 }; typedef struct sAniCfgTxRateCtrs { diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index d2371311eb48..4ca06a9f3c08 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -2184,6 +2184,24 @@ QDF_STATUS sme_get_chain_rssi(mac_handle_t mac_handle, get_chain_rssi_callback callback, void *context); +#ifdef FEATURE_FW_STATE +/** + * sme_get_fw_state() - Get fw state + * @mac_handle: Opaque handle to the global MAC context + * @callback: Callback function to be called with the result + * @context: Opaque context to be used by the caller to associate the + * request with the response + * + * This function constructs the cds message and fill in message type, + * post the same to WDA. + * + * Return: QDF_STATUS enumeration + */ +QDF_STATUS sme_get_fw_state(mac_handle_t mac_handle, + fw_state_callback callback, + void *context); +#endif /* FEATURE_FW_STATE */ + /** * sme_get_valid_channels() - sme api to get valid channels for * current regulatory domain diff --git a/core/sme/inc/sme_internal.h b/core/sme/inc/sme_internal.h index 66ea60f7e49a..ea99c72ab4d9 100644 --- a/core/sme/inc/sme_internal.h +++ b/core/sme/inc/sme_internal.h @@ -194,6 +194,15 @@ struct chain_rssi_result; typedef void (*get_chain_rssi_callback)(void *context, struct chain_rssi_result *data); +#ifdef FEATURE_FW_STATE +/** + * typedef fw_state_callback - get firmware state callback + * @context: Opaque context that the client can use to associate the + * callback with the request + */ +typedef void (*fw_state_callback)(void *context); +#endif /* FEATURE_FW_STATE */ + typedef void (*tx_queue_cb)(hdd_handle_t hdd_handle, uint32_t vdev_id, enum netif_action_type action, enum netif_reason_type reason); @@ -330,6 +339,10 @@ struct sme_context { void (*get_arp_stats_cb)(void *, struct rsp_stats *, void *); get_chain_rssi_callback get_chain_rssi_cb; void *get_chain_rssi_context; +#ifdef FEATURE_FW_STATE + fw_state_callback fw_state_cb; + void *fw_state_context; +#endif /* FEATURE_FW_STATE */ tx_queue_cb tx_queue_cb; twt_enable_cb twt_enable_cb; twt_disable_cb twt_disable_cb; diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 73b918f67ae3..09c1895b83c3 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -33,6 +33,7 @@ #include "wma_if.h" #include "wma.h" #include "wma_fips_api.h" +#include "wma_fw_state.h" #include "qdf_trace.h" #include "sme_trace.h" #include "qdf_types.h" @@ -76,6 +77,8 @@ static QDF_STATUS sme_process_channel_change_resp(struct mac_context *mac, static QDF_STATUS sme_stats_ext_event(struct mac_context *mac, struct stats_ext_event *msg); +static QDF_STATUS sme_fw_state_resp(struct mac_context *mac); + /* Internal SME APIs */ QDF_STATUS sme_acquire_global_lock(struct sme_context *sme) { @@ -2107,6 +2110,9 @@ QDF_STATUS sme_process_msg(struct mac_context *mac, struct scheduler_msg *pMsg) mac->sme.pget_peer_info_ext_cb_context); qdf_mem_free(pMsg->bodyptr); break; + case eWNI_SME_FW_STATUS_IND: + status = sme_fw_state_resp(mac); + break; case eWNI_SME_CSA_OFFLOAD_EVENT: if (pMsg->bodyptr) { csr_scan_flush_bss_entry(mac, pMsg->bodyptr); @@ -9167,6 +9173,53 @@ static QDF_STATUS sme_stats_ext_event(struct mac_context *mac, #endif +#ifdef FEATURE_FW_STATE +QDF_STATUS sme_get_fw_state(mac_handle_t mac_handle, + fw_state_callback callback, + void *context) +{ + QDF_STATUS status; + struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); + tp_wma_handle wma_handle; + + SME_ENTER(); + + mac_ctx->sme.fw_state_cb = callback; + mac_ctx->sme.fw_state_context = context; + wma_handle = cds_get_context(QDF_MODULE_ID_WMA); + status = wma_get_fw_state(wma_handle); + + SME_EXIT(); + return status; +} + +/** + * sme_fw_state_resp() - eWNI_SME_FW_STATUS_IND processor + * @mac: Global MAC context + + * This callback function called when SME received eWNI_SME_FW_STATUS_IND + * response from WMA + * + * Return: QDF_STATUS + */ +static QDF_STATUS sme_fw_state_resp(struct mac_context *mac) +{ + if (mac->sme.fw_state_cb) + mac->sme.fw_state_cb(mac->sme.fw_state_context); + mac->sme.fw_state_cb = NULL; + mac->sme.fw_state_context = NULL; + + return QDF_STATUS_SUCCESS; +} + +#else /* FEATURE_FW_STATE */ +static QDF_STATUS sme_fw_state_resp(struct mac_context *mac) +{ + return QDF_STATUS_SUCCESS; +} + +#endif /* FEATURE_FW_STATE */ + /* * sme_update_dfs_scan_mode() - * Update DFS roam scan mode diff --git a/core/wma/inc/wma_fw_state.h b/core/wma/inc/wma_fw_state.h new file mode 100644 index 000000000000..d508cb0fb09f --- /dev/null +++ b/core/wma/inc/wma_fw_state.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 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 + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: wma_fw_state.h + * + * Get firmware state related API's and definitions + */ + +#ifndef __WMA_FW_STATE_H +#define __WMA_FW_STATE_H + +#include "wma.h" + +#ifdef FEATURE_FW_STATE +/** + * wma_get_fw_state() - send wmi cmd to get fw state + * @wma_handle: wma handler + * + * Return: Return QDF_STATUS + */ +QDF_STATUS wma_get_fw_state(tp_wma_handle wma_handle); +void wma_register_fw_state_events(wmi_unified_t wmi_handle); +#else /* FEATURE_FW_STATE */ +static inline +void wma_register_fw_state_events(WMA_HANDLE wma_handle) +{ +} +#endif /* FEATURE_FW_STATE */ +#endif /* __WMA_FW_STATE_H */ diff --git a/core/wma/src/wma_fw_state.c b/core/wma/src/wma_fw_state.c new file mode 100644 index 000000000000..68e8145465fd --- /dev/null +++ b/core/wma/src/wma_fw_state.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 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 + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: wma_fw_state.c + * + * The implementation for getting firmware state + */ + +#include "wma_fw_state.h" +#include "wmi_unified_api.h" + +QDF_STATUS wma_get_fw_state(tp_wma_handle wma_handle) +{ + wmi_echo_cmd_fixed_param *cmd; + wmi_buf_t wmi_buf; + uint32_t len = sizeof(*cmd); + + if (!wma_handle) { + WMA_LOGE(FL("WMA is closed, can not issue cmd")); + return QDF_STATUS_E_INVAL; + } + + wmi_buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!wmi_buf) + return QDF_STATUS_E_NOMEM; + + cmd = (wmi_echo_cmd_fixed_param *)wmi_buf_data(wmi_buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_echo_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_echo_cmd_fixed_param)); + cmd->value = true; + + if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmi_buf, len, + WMI_ECHO_CMDID)) { + wmi_buf_free(wmi_buf); + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; +} + +/** + * wma_echo_event_handler() - process fw state rsp + * @handle: wma interface + * @buf: wmi event buf pointer + * @len: length of event buffer + * + * This function will send eWNI_SME_FW_STATUS_IND to SME + * + * Return: 0 for success or error code + */ +static int wma_echo_event_handler(void *handle, uint8_t *buf, uint32_t len) +{ + struct scheduler_msg sme_msg = { + .type = eWNI_SME_FW_STATUS_IND, + }; + QDF_STATUS qdf_status; + + WMA_LOGD("Received Echo reply from firmware!"); + + qdf_status = scheduler_post_message(QDF_MODULE_ID_WMA, + QDF_MODULE_ID_SME, + QDF_MODULE_ID_SME, &sme_msg); + if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { + WMA_LOGE("%s: Fail to post fw state reply msg", __func__); + return -EINVAL; + } + + return 0; +} + +void wma_register_fw_state_events(wmi_unified_t wmi_handle) +{ + wmi_unified_register_event_handler(wmi_handle, + wmi_echo_event_id, + wma_echo_event_handler, + WMA_RX_SERIALIZER_CTX); +} diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 0d338d3a8856..02f9ed735ed6 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -67,6 +67,7 @@ #include "cdp_txrx_misc.h" #include "wma_fips_api.h" #include "wma_nan_datapath.h" +#include "wma_fw_state.h" #include "wlan_lmac_if_def.h" #include "wlan_lmac_if_api.h" #include "target_if.h" @@ -3460,6 +3461,9 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc, wma_get_arp_stats_handler, WMA_RX_SERIALIZER_CTX); + /* register for fw state response event */ + wma_register_fw_state_events(wma_handle->wmi_handle); + /* register for peer info response event */ wmi_unified_register_event_handler(wma_handle->wmi_handle, wmi_peer_stats_info_event_id,