qcacld-3.0: Support firmware state check through cfg80211 vendor cmd

Add the support to allow user space applications through cfg80211
vendor command to check if wlan firmware is alive or not.

Change-Id: I96bb16e01974f7689493577741a36e3832963996
CRs-Fixed: 2399508
This commit is contained in:
Qun Zhang
2019-02-25 10:48:10 +08:00
committed by nshrivas
parent 635650c972
commit ef65562bcd
12 changed files with 504 additions and 1 deletions

10
Kbuild
View File

@@ -225,6 +225,10 @@ ifeq ($(CONFIG_WLAN_SYSFS), y)
HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs.o HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs.o
endif endif
ifeq ($(CONFIG_QCACLD_FEATURE_FW_STATE), y)
HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_fw_state.o
endif
###### OSIF_SYNC ######## ###### OSIF_SYNC ########
SYNC_DIR := os_if/sync SYNC_DIR := os_if/sync
SYNC_INC_DIR := $(SYNC_DIR)/inc SYNC_INC_DIR := $(SYNC_DIR)/inc
@@ -1650,6 +1654,9 @@ endif
ifeq ($(CONFIG_WLAN_FEATURE_TWT), y) ifeq ($(CONFIG_WLAN_FEATURE_TWT), y)
WMA_OBJS += $(WMA_SRC_DIR)/wma_twt.o WMA_OBJS += $(WMA_SRC_DIR)/wma_twt.o
endif endif
ifeq ($(CONFIG_QCACLD_FEATURE_FW_STATE), y)
WMA_OBJS += $(WMA_SRC_DIR)/wma_fw_state.o
endif
############## PLD ########## ############## PLD ##########
PLD_DIR := core/pld PLD_DIR := core/pld
PLD_INC_DIR := $(PLD_DIR)/inc 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) #Flag to enable Dynamic Voltage WDCVS (Config Voltage Mode)
cppflags-$(CONFIG_WLAN_DYNAMIC_CVM) += -DFEATURE_WLAN_DYNAMIC_CVM 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 ifdef CONFIG_MAX_LOGS_PER_SEC
ccflags-y += -DWLAN_MAX_LOGS_PER_SEC=$(CONFIG_MAX_LOGS_PER_SEC) ccflags-y += -DWLAN_MAX_LOGS_PER_SEC=$(CONFIG_MAX_LOGS_PER_SEC)
endif endif

View File

@@ -116,6 +116,9 @@ CONFIG_QCACLD_FEATURE_APF := y
#Flag to enable SARv1 -> SARv2 conversion #Flag to enable SARv1 -> SARv2 conversion
CONFIG_WLAN_FEATURE_SARV1_TO_SARV2 := n CONFIG_WLAN_FEATURE_SARV1_TO_SARV2 := n
#Flag to enable get firmware state
CONFIG_QCACLD_FEATURE_FW_STATE := y
ifeq ($(CONFIG_ARCH_MSM8998), y) ifeq ($(CONFIG_ARCH_MSM8998), y)
CONFIG_QCACLD_FEATURE_METERING := y CONFIG_QCACLD_FEATURE_METERING := y
endif endif

View File

@@ -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 <net/cfg80211.h>
/**
* 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 */

View File

@@ -94,6 +94,7 @@
#ifdef FEATURE_WLAN_APF #ifdef FEATURE_WLAN_APF
#include "wlan_hdd_apf.h" #include "wlan_hdd_apf.h"
#endif #endif
#include "wlan_hdd_fw_state.h"
#include <cdp_txrx_cmn.h> #include <cdp_txrx_cmn.h>
#include <cdp_txrx_misc.h> #include <cdp_txrx_misc.h>
@@ -12452,6 +12453,7 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = {
FEATURE_ACTIVE_TOS_VENDOR_COMMANDS FEATURE_ACTIVE_TOS_VENDOR_COMMANDS
FEATURE_NAN_VENDOR_COMMANDS FEATURE_NAN_VENDOR_COMMANDS
FEATURE_FW_STATE_COMMANDS
}; };
struct hdd_context *hdd_cfg80211_wiphy_alloc(void) struct hdd_context *hdd_cfg80211_wiphy_alloc(void)

View File

@@ -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(&params);
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;
}

View File

@@ -236,7 +236,8 @@ enum eWniMsgTypes {
WNI_SME_CFG_ACTION_FRM_HE_TB_PPDU = SIR_SME_MSG_TYPES_BEGIN + 150, WNI_SME_CFG_ACTION_FRM_HE_TB_PPDU = SIR_SME_MSG_TYPES_BEGIN + 150,
/* To indicate Hidden ssid start complition to upper layer */ /* To indicate Hidden ssid start complition to upper layer */
eWNI_SME_HIDDEN_SSID_RESTART_RSP = SIR_SME_MSG_TYPES_BEGIN + 151, 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 { typedef struct sAniCfgTxRateCtrs {

View File

@@ -2184,6 +2184,24 @@ QDF_STATUS sme_get_chain_rssi(mac_handle_t mac_handle,
get_chain_rssi_callback callback, get_chain_rssi_callback callback,
void *context); 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 * sme_get_valid_channels() - sme api to get valid channels for
* current regulatory domain * current regulatory domain

View File

@@ -194,6 +194,15 @@ struct chain_rssi_result;
typedef void (*get_chain_rssi_callback)(void *context, typedef void (*get_chain_rssi_callback)(void *context,
struct chain_rssi_result *data); 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, typedef void (*tx_queue_cb)(hdd_handle_t hdd_handle, uint32_t vdev_id,
enum netif_action_type action, enum netif_action_type action,
enum netif_reason_type reason); enum netif_reason_type reason);
@@ -330,6 +339,10 @@ struct sme_context {
void (*get_arp_stats_cb)(void *, struct rsp_stats *, void *); void (*get_arp_stats_cb)(void *, struct rsp_stats *, void *);
get_chain_rssi_callback get_chain_rssi_cb; get_chain_rssi_callback get_chain_rssi_cb;
void *get_chain_rssi_context; 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; tx_queue_cb tx_queue_cb;
twt_enable_cb twt_enable_cb; twt_enable_cb twt_enable_cb;
twt_disable_cb twt_disable_cb; twt_disable_cb twt_disable_cb;

View File

@@ -33,6 +33,7 @@
#include "wma_if.h" #include "wma_if.h"
#include "wma.h" #include "wma.h"
#include "wma_fips_api.h" #include "wma_fips_api.h"
#include "wma_fw_state.h"
#include "qdf_trace.h" #include "qdf_trace.h"
#include "sme_trace.h" #include "sme_trace.h"
#include "qdf_types.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, static QDF_STATUS sme_stats_ext_event(struct mac_context *mac,
struct stats_ext_event *msg); struct stats_ext_event *msg);
static QDF_STATUS sme_fw_state_resp(struct mac_context *mac);
/* Internal SME APIs */ /* Internal SME APIs */
QDF_STATUS sme_acquire_global_lock(struct sme_context *sme) 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); mac->sme.pget_peer_info_ext_cb_context);
qdf_mem_free(pMsg->bodyptr); qdf_mem_free(pMsg->bodyptr);
break; break;
case eWNI_SME_FW_STATUS_IND:
status = sme_fw_state_resp(mac);
break;
case eWNI_SME_CSA_OFFLOAD_EVENT: case eWNI_SME_CSA_OFFLOAD_EVENT:
if (pMsg->bodyptr) { if (pMsg->bodyptr) {
csr_scan_flush_bss_entry(mac, 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 #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() - * sme_update_dfs_scan_mode() -
* Update DFS roam scan mode * Update DFS roam scan mode

View File

@@ -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 */

View File

@@ -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);
}

View File

@@ -67,6 +67,7 @@
#include "cdp_txrx_misc.h" #include "cdp_txrx_misc.h"
#include "wma_fips_api.h" #include "wma_fips_api.h"
#include "wma_nan_datapath.h" #include "wma_nan_datapath.h"
#include "wma_fw_state.h"
#include "wlan_lmac_if_def.h" #include "wlan_lmac_if_def.h"
#include "wlan_lmac_if_api.h" #include "wlan_lmac_if_api.h"
#include "target_if.h" #include "target_if.h"
@@ -3460,6 +3461,9 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc,
wma_get_arp_stats_handler, wma_get_arp_stats_handler,
WMA_RX_SERIALIZER_CTX); 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 */ /* register for peer info response event */
wmi_unified_register_event_handler(wma_handle->wmi_handle, wmi_unified_register_event_handler(wma_handle->wmi_handle,
wmi_peer_stats_info_event_id, wmi_peer_stats_info_event_id,