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:
10
Kbuild
10
Kbuild
@@ -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
|
||||||
|
@@ -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
|
||||||
|
55
core/hdd/inc/wlan_hdd_fw_state.h
Normal file
55
core/hdd/inc/wlan_hdd_fw_state.h
Normal 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 */
|
@@ -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)
|
||||||
|
204
core/hdd/src/wlan_hdd_fw_state.c
Normal file
204
core/hdd/src/wlan_hdd_fw_state.c
Normal 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(¶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;
|
||||||
|
}
|
@@ -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 {
|
||||||
|
@@ -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
|
||||||
|
@@ -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;
|
||||||
|
@@ -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
|
||||||
|
45
core/wma/inc/wma_fw_state.h
Normal file
45
core/wma/inc/wma_fw_state.h
Normal 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 */
|
95
core/wma/src/wma_fw_state.c
Normal file
95
core/wma/src/wma_fw_state.c
Normal 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);
|
||||||
|
}
|
@@ -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,
|
||||||
|
Reference in New Issue
Block a user