qcacld-3.0: Add support for ctrl path stats infrastructure
Implement support for sending new control path stats infrastructure via WMI_REQUEST_CTRL_PATH_STATS_CMDID and WMI_CTRL_PATH_STATS_EVENTID in cp stats component. Also add support for TWT Get statistics through this new method. Change-Id: I62b3a525cde797cd5b809ca9e8e6c91d5651c6b4 CRs-Fixed: 2851016
This commit is contained in:
parent
3208dfe908
commit
ebcefb3044
5
Kbuild
5
Kbuild
@ -2036,7 +2036,9 @@ CP_STATS_OBJS := $(CP_MC_STATS_COMPONENT_SRC)/wlan_cp_stats_mc_tgt_api.o \
|
||||
$(CP_STATS_CORE_SRC)/wlan_cp_stats_obj_mgr_handler.o \
|
||||
$(CP_STATS_CORE_SRC)/wlan_cp_stats_ol_api.o \
|
||||
$(CP_MC_STATS_OS_IF_SRC)/wlan_cfg80211_mc_cp_stats.o \
|
||||
$(CP_STATS_DISPATCHER_SRC)/wlan_cp_stats_utils_api.o
|
||||
$(CP_STATS_DISPATCHER_SRC)/wlan_cp_stats_utils_api.o \
|
||||
$(WLAN_COMMON_ROOT)/target_if/cp_stats/src/target_if_cp_stats.o \
|
||||
$(CP_STATS_DISPATCHER_SRC)/wlan_cp_stats_ucfg_api.o
|
||||
endif
|
||||
|
||||
$(call add-wlan-objs,cp_stats,$(CP_STATS_OBJS))
|
||||
@ -2652,6 +2654,7 @@ cppflags-$(CONFIG_WLAN_WEXT_SUPPORT_ENABLE) += -DWLAN_WEXT_SUPPORT_ENABLE
|
||||
cppflags-$(CONFIG_WLAN_LOGGING_SOCK_SVC) += -DWLAN_LOGGING_SOCK_SVC_ENABLE
|
||||
cppflags-$(CONFIG_WLAN_LOGGING_BUFFERS_DYNAMICALLY) += -DWLAN_LOGGING_BUFFERS_DYNAMICALLY
|
||||
cppflags-$(CONFIG_WLAN_FEATURE_FILS) += -DWLAN_FEATURE_FILS_SK
|
||||
cppflags-$(CONFIG_CP_STATS) += -DWLAN_SUPPORT_INFRA_CTRL_PATH_STATS
|
||||
cppflags-$(CONFIG_CP_STATS) += -DQCA_SUPPORT_CP_STATS
|
||||
cppflags-$(CONFIG_CP_STATS) += -DQCA_SUPPORT_MC_CP_STATS
|
||||
cppflags-$(CONFIG_DCS) += -DDCS_INTERFERENCE_DETECTION
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2012-2021 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
|
||||
@ -31,6 +31,10 @@
|
||||
/* For WMI_MAX_CHAINS */
|
||||
#include "wmi_unified.h"
|
||||
|
||||
#ifdef QCA_SUPPORT_MC_CP_STATS
|
||||
#include "wlan_cp_stats_public_structs.h"
|
||||
#endif
|
||||
|
||||
#ifdef WLAN_SUPPORT_TWT
|
||||
|
||||
#include <wmi_unified_twt_param.h>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2018, 2021 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
|
||||
@ -48,14 +48,31 @@ uint8_t target_if_mc_cp_get_mac_id(struct vdev_mlme_obj *vdev_mlme);
|
||||
* @psoc: pointer to psoc object
|
||||
* @event: event parameters
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS on Success, other QDF_STATUS error codes on
|
||||
* failure
|
||||
*/
|
||||
QDF_STATUS
|
||||
tgt_mc_cp_stats_process_stats_event(struct wlan_objmgr_psoc *psoc,
|
||||
struct stats_event *ev);
|
||||
|
||||
#ifdef WLAN_SUPPORT_INFRA_CTRL_PATH_STATS
|
||||
/**
|
||||
* tgt_mc_cp_stats_process_infra_stats_event(): API to process event from
|
||||
* cp stats infrastrucure
|
||||
* @psoc: pointer to psoc object
|
||||
* @infra_event: infra cp stats event parameters
|
||||
*
|
||||
* Return: status of operation
|
||||
*/
|
||||
QDF_STATUS tgt_mc_cp_stats_process_stats_event(struct wlan_objmgr_psoc *psoc,
|
||||
struct stats_event *event);
|
||||
QDF_STATUS tgt_mc_cp_stats_process_infra_stats_event(
|
||||
struct wlan_objmgr_psoc *psoc,
|
||||
struct infra_cp_stats_event *infra_event);
|
||||
|
||||
#endif
|
||||
/**
|
||||
* tgt_send_mc_cp_stats_req(): API to send stats request to lmac
|
||||
* @psoc: pointer to psoc object
|
||||
* @req: pointer to stats request
|
||||
*
|
||||
* Return: status of operation
|
||||
*/
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2018-2021 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
|
||||
@ -153,6 +153,20 @@ QDF_STATUS ucfg_mc_cp_stats_send_stats_request(struct wlan_objmgr_vdev *vdev,
|
||||
enum stats_req_type type,
|
||||
struct request_info *info);
|
||||
|
||||
/**
|
||||
* wlan_cfg80211_mc_twt_get_infra_cp_stats() - send twt get statistic request
|
||||
* @vdev: pointer to vdev object
|
||||
* @dialog_id: TWT session dialog id
|
||||
* @twt_peer_mac: mac address of the peer
|
||||
* @errno: error code
|
||||
*
|
||||
* Return: pointer to infra cp stats event for success or NULL for failure
|
||||
*/
|
||||
struct infra_cp_stats_event *
|
||||
wlan_cfg80211_mc_twt_get_infra_cp_stats(struct wlan_objmgr_vdev *vdev,
|
||||
uint32_t dialog_id,
|
||||
uint8_t twt_peer_mac[QDF_MAC_ADDR_SIZE],
|
||||
int *errno);
|
||||
/**
|
||||
* ucfg_mc_cp_stats_get_tx_power() - API to fetch tx_power
|
||||
* @vdev: pointer to vdev object
|
||||
@ -184,7 +198,6 @@ bool ucfg_mc_cp_stats_is_req_pending(struct wlan_objmgr_psoc *psoc,
|
||||
QDF_STATUS ucfg_mc_cp_stats_set_pending_req(struct wlan_objmgr_psoc *psoc,
|
||||
enum stats_req_type type,
|
||||
struct request_info *req);
|
||||
|
||||
/**
|
||||
* ucfg_mc_cp_stats_reset_pending_req() - API to reset pending request
|
||||
* @psoc: pointer to psoc object
|
||||
@ -213,10 +226,20 @@ QDF_STATUS ucfg_mc_cp_stats_get_pending_req(struct wlan_objmgr_psoc *psoc,
|
||||
enum stats_req_type type,
|
||||
struct request_info *info);
|
||||
|
||||
/**
|
||||
* ucfg_mc_infra_cp_stats_free_stats_resources() - API to free buffers within
|
||||
* infra cp stats_event structure
|
||||
* @ev: structure whose buffer are to freed
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void
|
||||
ucfg_mc_infra_cp_stats_free_stats_resources(struct infra_cp_stats_event *ev);
|
||||
|
||||
/**
|
||||
* ucfg_mc_cp_stats_free_stats_resources() - API to free buffers within stats_event
|
||||
* structure
|
||||
* @ev: strcture whose buffer are to freed
|
||||
* @ev: structure whose buffer are to freed
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
|
@ -26,10 +26,12 @@
|
||||
#include "wlan_cp_stats_mc_defs.h"
|
||||
#include "target_if_cp_stats.h"
|
||||
#include "wlan_cp_stats_tgt_api.h"
|
||||
#include "wlan_cp_stats_ucfg_api.h"
|
||||
#include "wlan_cp_stats_mc_tgt_api.h"
|
||||
#include <wlan_cp_stats_mc_ucfg_api.h>
|
||||
#include <wlan_cp_stats_utils_api.h>
|
||||
#include "../../core/src/wlan_cp_stats_defs.h"
|
||||
#include "../../core/src/wlan_cp_stats_obj_mgr_handler.h"
|
||||
|
||||
static bool tgt_mc_cp_stats_is_last_event(struct stats_event *ev,
|
||||
enum stats_req_type stats_type)
|
||||
@ -51,10 +53,25 @@ static bool tgt_mc_cp_stats_is_last_event(struct stats_event *ev,
|
||||
return is_last_event;
|
||||
}
|
||||
|
||||
#ifdef WLAN_SUPPORT_INFRA_CTRL_PATH_STATS
|
||||
static void
|
||||
tgt_cp_stats_register_infra_cp_stats_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
|
||||
{
|
||||
rx_ops->cp_stats_rx_ops.process_infra_stats_event =
|
||||
tgt_mc_cp_stats_process_infra_stats_event;
|
||||
}
|
||||
#else
|
||||
static void
|
||||
tgt_cp_stats_register_infra_cp_stats_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
void tgt_cp_stats_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
|
||||
{
|
||||
rx_ops->cp_stats_rx_ops.process_stats_event =
|
||||
tgt_mc_cp_stats_process_stats_event;
|
||||
tgt_cp_stats_register_infra_cp_stats_rx_ops(rx_ops);
|
||||
}
|
||||
|
||||
static void tgt_mc_cp_stats_extract_tx_power(struct wlan_objmgr_psoc *psoc,
|
||||
@ -614,6 +631,37 @@ tgt_mc_cp_stats_extract_peer_stats_info_ext(struct wlan_objmgr_psoc *psoc,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WLAN_SUPPORT_INFRA_CTRL_PATH_STATS
|
||||
#ifdef WLAN_SUPPORT_TWT
|
||||
static void
|
||||
tgt_mc_infra_cp_stats_extract_twt_stats(struct wlan_objmgr_psoc *psoc,
|
||||
struct infra_cp_stats_event *ev)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
get_infra_cp_stats_cb resp_cb;
|
||||
void *context;
|
||||
|
||||
status = wlan_cp_stats_infra_cp_get_context(psoc, &resp_cb, &context);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
cp_stats_err("ucfg_get_infra_cp_stats_context failed");
|
||||
return;
|
||||
}
|
||||
|
||||
cp_stats_debug("num_twt_infra_cp_stats = %d action %d",
|
||||
ev->num_twt_infra_cp_stats, ev->action);
|
||||
|
||||
if (resp_cb)
|
||||
resp_cb(ev, context);
|
||||
}
|
||||
#else
|
||||
static void
|
||||
tgt_mc_infra_cp_stats_extract_twt_stats(struct wlan_objmgr_psoc *psoc,
|
||||
struct infra_cp_stats_event *ev)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
#endif /* WLAN_SUPPORT_INFRA_CTRL_PATH_STATS */
|
||||
|
||||
static void tgt_mc_cp_stats_extract_cca_stats(struct wlan_objmgr_psoc *psoc,
|
||||
struct stats_event *ev)
|
||||
{
|
||||
@ -977,6 +1025,20 @@ static void tgt_mc_cp_send_lost_link_stats(struct wlan_objmgr_psoc *psoc,
|
||||
psoc_cp_stats_priv->legacy_stats_cb(ev);
|
||||
}
|
||||
|
||||
#ifdef WLAN_SUPPORT_INFRA_CTRL_PATH_STATS
|
||||
QDF_STATUS tgt_mc_cp_stats_process_infra_stats_event(
|
||||
struct wlan_objmgr_psoc *psoc,
|
||||
struct infra_cp_stats_event *infra_event)
|
||||
{
|
||||
if (!infra_event)
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
|
||||
tgt_mc_infra_cp_stats_extract_twt_stats(psoc, infra_event);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
QDF_STATUS tgt_mc_cp_stats_process_stats_event(struct wlan_objmgr_psoc *psoc,
|
||||
struct stats_event *ev)
|
||||
{
|
||||
|
@ -87,6 +87,11 @@ qca_wlan_vendor_twt_resume_dialog_policy[QCA_WLAN_VENDOR_ATTR_TWT_RESUME_MAX + 1
|
||||
[QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT2_TWT] = {.type = NLA_U32 },
|
||||
};
|
||||
|
||||
static const struct nla_policy
|
||||
qca_wlan_vendor_twt_stats_dialog_policy[QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAX + 1] = {
|
||||
[QCA_WLAN_VENDOR_ATTR_TWT_STATS_FLOW_ID] = {.type = NLA_U8 },
|
||||
};
|
||||
|
||||
const struct nla_policy
|
||||
wlan_hdd_wifi_twt_config_policy[
|
||||
QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX + 1] = {
|
||||
@ -1289,6 +1294,25 @@ static int hdd_twt_setup_session(struct hdd_adapter *adapter,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_get_twt_get_stats_event_len() - calculate length of skb
|
||||
* required for sending twt get statistics command responses.
|
||||
*
|
||||
* Return: length of skb
|
||||
*/
|
||||
static uint32_t hdd_get_twt_get_stats_event_len(void)
|
||||
{
|
||||
uint32_t len = 0;
|
||||
|
||||
len += NLMSG_HDRLEN;
|
||||
/* QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID */
|
||||
len += nla_total_size(sizeof(u8));
|
||||
/* QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATUS */
|
||||
len += nla_total_size(sizeof(u8));
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_get_twt_event_len() - calculate length of skb
|
||||
* required for sending twt terminate, pause and resume
|
||||
@ -2257,7 +2281,6 @@ static int hdd_twt_resume_session(struct hdd_adapter *adapter,
|
||||
hdd_sta_ctx->conn_info.conn_state);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
qdf_mem_copy(params.peer_macaddr, hdd_sta_ctx->conn_info.bssid.bytes,
|
||||
QDF_MAC_ADDR_SIZE);
|
||||
params.vdev_id = adapter->vdev_id;
|
||||
@ -2313,6 +2336,221 @@ static int hdd_twt_resume_session(struct hdd_adapter *adapter,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint32_t get_session_wake_duration(uint32_t dialog_id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_twt_pack_get_stats_resp_nlmsg()- Packs and sends twt get stats response
|
||||
* @reply_skb: pointer to response skb buffer
|
||||
* @params: Ponter to twt session parameter buffer
|
||||
* @num_session_stats: number of twt statistics
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS on success, else other qdf error values
|
||||
*/
|
||||
static QDF_STATUS
|
||||
hdd_twt_pack_get_stats_resp_nlmsg(struct sk_buff *reply_skb,
|
||||
struct twt_infra_cp_stats_event *params,
|
||||
uint32_t num_session_stats)
|
||||
{
|
||||
struct nlattr *config_attr, *nla_params;
|
||||
int i, attr;
|
||||
uint32_t wake_duration;
|
||||
|
||||
config_attr = nla_nest_start(reply_skb,
|
||||
QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS);
|
||||
if (!config_attr) {
|
||||
hdd_err("get_params nla_nest_start error");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_session_stats; i++) {
|
||||
|
||||
nla_params = nla_nest_start(reply_skb, i);
|
||||
if (!nla_params) {
|
||||
hdd_err("get_stats nla_nest_start error");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
attr = QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAC_ADDR;
|
||||
if (nla_put(reply_skb, attr, QDF_MAC_ADDR_SIZE,
|
||||
params[i].peer_macaddr.bytes)) {
|
||||
hdd_err("get_stats failed to put mac_addr");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
hdd_debug("get_stats peer mac_addr " QDF_MAC_ADDR_FMT,
|
||||
QDF_MAC_ADDR_REF(params[i].peer_macaddr.bytes));
|
||||
|
||||
attr = QCA_WLAN_VENDOR_ATTR_TWT_STATS_FLOW_ID;
|
||||
if (nla_put_u8(reply_skb, attr, params[i].dialog_id)) {
|
||||
hdd_err("get_stats failed to put dialog_id");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
hdd_debug("%d wake duration %d num sp cycles %d",
|
||||
params[i].dialog_id, wake_duration,
|
||||
params[i].num_sp_cycles);
|
||||
wake_duration = get_session_wake_duration(params[i].dialog_id);
|
||||
attr = QCA_WLAN_VENDOR_ATTR_TWT_STATS_SESSION_WAKE_DURATION;
|
||||
if (nla_put_u32(reply_skb, attr, wake_duration)) {
|
||||
hdd_err("get_params failed to put Wake duration");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
attr = QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS;
|
||||
if (nla_put_u32(reply_skb, attr, params[i].num_sp_cycles)) {
|
||||
hdd_err("get_params failed to put num_sp_cycles");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
attr = QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVG_WAKE_DURATION;
|
||||
if (nla_put_u32(reply_skb, attr, params[i].avg_sp_dur_us)) {
|
||||
hdd_err("get_params failed to put avg_sp_dur_us");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
attr = QCA_WLAN_VENDOR_ATTR_TWT_STATS_MIN_WAKE_DURATION;
|
||||
if (nla_put_u32(reply_skb, attr, params[i].min_sp_dur_us)) {
|
||||
hdd_err("get_params failed to put min_sp_dur_us");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
attr = QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAX_WAKE_DURATION;
|
||||
if (nla_put_u32(reply_skb, attr, params[i].max_sp_dur_us)) {
|
||||
hdd_err("get_params failed to put max_sp_dur_us");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
attr = QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_MPDU;
|
||||
if (nla_put_u32(reply_skb, attr, params[i].tx_mpdu_per_sp)) {
|
||||
hdd_err("get_params failed to put tx_mpdu_per_sp");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
attr = QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_MPDU;
|
||||
if (nla_put_u32(reply_skb, attr, params[i].rx_mpdu_per_sp)) {
|
||||
hdd_err("get_params failed to put rx_mpdu_per_sp");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
attr = QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_PACKET_SIZE;
|
||||
if (nla_put_u32(reply_skb, attr, params[i].tx_bytes_per_sp)) {
|
||||
hdd_err("get_params failed to put tx_bytes_per_sp");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
attr = QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_PACKET_SIZE;
|
||||
if (nla_put_u32(reply_skb, attr, params[i].rx_bytes_per_sp)) {
|
||||
hdd_err("get_params failed to put rx_bytes_per_sp");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
nla_nest_end(reply_skb, nla_params);
|
||||
}
|
||||
nla_nest_end(reply_skb, config_attr);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_twt_get_session_traffic_stats() - Obtains twt session traffic statistics
|
||||
* and sends response to the user space
|
||||
* @adapter: hdd_adapter
|
||||
* @dialog_id: dialog id of the twt session
|
||||
* @peer_mac: Mac address of the peer
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS on success, else other qdf error values
|
||||
*/
|
||||
static QDF_STATUS
|
||||
hdd_twt_request_session_traffic_stats(struct hdd_adapter *adapter,
|
||||
uint32_t dialog_id, uint8_t *peer_mac)
|
||||
{
|
||||
int errno;
|
||||
int skb_len;
|
||||
struct sk_buff *reply_skb;
|
||||
QDF_STATUS status = QDF_STATUS_E_INVAL;
|
||||
struct infra_cp_stats_event *event;
|
||||
|
||||
if (!adapter || !peer_mac)
|
||||
return status;
|
||||
|
||||
event = wlan_cfg80211_mc_twt_get_infra_cp_stats(adapter->vdev,
|
||||
dialog_id,
|
||||
peer_mac,
|
||||
&errno);
|
||||
if (!event)
|
||||
return errno;
|
||||
|
||||
skb_len = hdd_get_twt_get_stats_event_len();
|
||||
reply_skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(
|
||||
adapter->hdd_ctx->wiphy,
|
||||
skb_len);
|
||||
if (!reply_skb) {
|
||||
hdd_err("Get stats - alloc reply_skb failed");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
status = hdd_twt_pack_get_stats_resp_nlmsg(
|
||||
reply_skb,
|
||||
event->twt_infra_cp_stats,
|
||||
event->num_twt_infra_cp_stats);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
hdd_err("Get stats - Failed to pack nl response");
|
||||
wlan_cfg80211_vendor_free_skb(reply_skb);
|
||||
return qdf_status_to_os_return(status);
|
||||
}
|
||||
|
||||
return wlan_cfg80211_vendor_cmd_reply(reply_skb);
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_twt_get_session_stats() - Parses twt nl attrributes, obtains twt
|
||||
* session parameters based on dialog_id and returns to user via nl layer
|
||||
* @adapter: hdd_adapter
|
||||
* @twt_param_attr: twt nl attributes
|
||||
*
|
||||
* Return: 0 on success, negative value on failure
|
||||
*/
|
||||
static int hdd_twt_get_session_traffic_stats(struct hdd_adapter *adapter,
|
||||
struct nlattr *twt_param_attr)
|
||||
{
|
||||
struct hdd_station_ctx *hdd_sta_ctx =
|
||||
WLAN_HDD_GET_STATION_CTX_PTR(adapter);
|
||||
struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAX + 1];
|
||||
int ret, id;
|
||||
QDF_STATUS qdf_status;
|
||||
uint32_t dialog_id;
|
||||
uint8_t peer_mac[QDF_MAC_ADDR_SIZE];
|
||||
|
||||
ret = wlan_cfg80211_nla_parse_nested(
|
||||
tb,
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAX,
|
||||
twt_param_attr,
|
||||
qca_wlan_vendor_twt_stats_dialog_policy);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
id = QCA_WLAN_VENDOR_ATTR_TWT_STATS_FLOW_ID;
|
||||
if (tb[id])
|
||||
dialog_id = (uint32_t)nla_get_u8(tb[id]);
|
||||
else
|
||||
dialog_id = 0;
|
||||
|
||||
hdd_debug("get_stats dialog_id %d", dialog_id);
|
||||
|
||||
qdf_mem_copy(peer_mac,
|
||||
hdd_sta_ctx->conn_info.bssid.bytes,
|
||||
QDF_MAC_ADDR_SIZE);
|
||||
hdd_debug("get_stats peer mac_addr " QDF_MAC_ADDR_FMT,
|
||||
QDF_MAC_ADDR_REF(peer_mac));
|
||||
|
||||
qdf_status = hdd_twt_request_session_traffic_stats(adapter,
|
||||
dialog_id, peer_mac);
|
||||
|
||||
return qdf_status_to_os_return(qdf_status);
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_twt_notify_pack_nlmsg() - pack the skb with
|
||||
* twt notify event from firmware
|
||||
@ -2447,6 +2685,10 @@ static int hdd_twt_configure(struct hdd_adapter *adapter,
|
||||
case QCA_WLAN_TWT_GET_CAPABILITIES:
|
||||
ret = hdd_twt_get_capabilities(adapter, twt_param_attr);
|
||||
break;
|
||||
case QCA_WLAN_TWT_GET_STATS:
|
||||
ret = hdd_twt_get_session_traffic_stats(adapter,
|
||||
twt_param_attr);
|
||||
break;
|
||||
default:
|
||||
hdd_err("Invalid TWT Operation");
|
||||
ret = -EINVAL;
|
||||
|
@ -23,6 +23,7 @@
|
||||
*/
|
||||
|
||||
#include <wlan_cfg80211.h>
|
||||
#include <wlan_cp_stats_ucfg_api.h>
|
||||
#include <wlan_cp_stats_mc_defs.h>
|
||||
#include <wlan_cp_stats_mc_ucfg_api.h>
|
||||
#include <wlan_cfg80211_mc_cp_stats.h>
|
||||
@ -50,6 +51,41 @@ static void wlan_free_mib_stats(struct stats_event *stats)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WLAN_SUPPORT_INFRA_CTRL_PATH_STATS
|
||||
#ifdef WLAN_SUPPORT_TWT
|
||||
static void wlan_cfg80211_infra_cp_stats_twt_dealloc(void *priv)
|
||||
{
|
||||
struct infra_cp_stats_event *stats = priv;
|
||||
|
||||
qdf_mem_free(stats->twt_infra_cp_stats);
|
||||
stats->twt_infra_cp_stats = NULL;
|
||||
}
|
||||
#else
|
||||
static void wlan_cfg80211_infra_cp_stats_twt_dealloc(void *priv)
|
||||
{
|
||||
}
|
||||
#endif /* WLAN_SUPPORT_TWT */
|
||||
|
||||
/**
|
||||
* wlan_cfg80211_mc_infra_cp_stats_dealloc() - callback to free priv
|
||||
* allocations for infra cp stats
|
||||
* @priv: Pointer to priv data statucture
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static inline
|
||||
void wlan_cfg80211_mc_infra_cp_stats_dealloc(void *priv)
|
||||
{
|
||||
struct infra_cp_stats_event *stats = priv;
|
||||
|
||||
if (!stats) {
|
||||
osif_err("infar_cp_stats is NULL");
|
||||
return;
|
||||
}
|
||||
wlan_cfg80211_infra_cp_stats_twt_dealloc(priv);
|
||||
}
|
||||
#endif /* WLAN_SUPPORT_INFRA_CTRL_PATH_STATS */
|
||||
|
||||
/**
|
||||
* wlan_cfg80211_mc_cp_stats_dealloc() - callback to free priv
|
||||
* allocations for stats
|
||||
@ -522,6 +558,220 @@ station_stats_cb_fail:
|
||||
osif_request_put(request);
|
||||
}
|
||||
|
||||
#ifdef WLAN_SUPPORT_INFRA_CTRL_PATH_STATS
|
||||
|
||||
#ifdef WLAN_SUPPORT_TWT
|
||||
static void get_twt_infra_cp_stats(struct infra_cp_stats_event *ev,
|
||||
struct infra_cp_stats_event *priv)
|
||||
|
||||
{
|
||||
priv->num_twt_infra_cp_stats = ev->num_twt_infra_cp_stats;
|
||||
priv->twt_infra_cp_stats->dialog_id = ev->twt_infra_cp_stats->dialog_id;
|
||||
priv->twt_infra_cp_stats->status = ev->twt_infra_cp_stats->status;
|
||||
priv->twt_infra_cp_stats->num_sp_cycles =
|
||||
ev->twt_infra_cp_stats->num_sp_cycles;
|
||||
priv->twt_infra_cp_stats->avg_sp_dur_us =
|
||||
ev->twt_infra_cp_stats->avg_sp_dur_us;
|
||||
priv->twt_infra_cp_stats->min_sp_dur_us =
|
||||
ev->twt_infra_cp_stats->min_sp_dur_us;
|
||||
priv->twt_infra_cp_stats->max_sp_dur_us =
|
||||
ev->twt_infra_cp_stats->max_sp_dur_us;
|
||||
priv->twt_infra_cp_stats->tx_mpdu_per_sp =
|
||||
ev->twt_infra_cp_stats->tx_mpdu_per_sp;
|
||||
priv->twt_infra_cp_stats->rx_mpdu_per_sp =
|
||||
ev->twt_infra_cp_stats->rx_mpdu_per_sp;
|
||||
priv->twt_infra_cp_stats->tx_bytes_per_sp =
|
||||
ev->twt_infra_cp_stats->tx_bytes_per_sp;
|
||||
priv->twt_infra_cp_stats->rx_bytes_per_sp =
|
||||
ev->twt_infra_cp_stats->rx_bytes_per_sp;
|
||||
}
|
||||
|
||||
static void
|
||||
wlan_cfg80211_mc_infra_cp_free_twt_stats(struct infra_cp_stats_event *stats)
|
||||
{
|
||||
qdf_mem_free(stats->twt_infra_cp_stats);
|
||||
}
|
||||
#else
|
||||
static void get_twt_infra_cp_stats(struct infra_cp_stats_event *ev,
|
||||
struct infra_cp_stats_event *priv)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
wlan_cfg80211_mc_infra_cp_free_twt_stats(struct infra_cp_stats_event *stats)
|
||||
{
|
||||
}
|
||||
#endif /* WLAN_SUPPORT_TWT */
|
||||
|
||||
static inline void
|
||||
wlan_cfg80211_mc_infra_cp_stats_free_stats_event(
|
||||
struct infra_cp_stats_event *stats)
|
||||
{
|
||||
if (!stats)
|
||||
return;
|
||||
wlan_cfg80211_mc_infra_cp_free_twt_stats(stats);
|
||||
qdf_mem_free(stats);
|
||||
}
|
||||
|
||||
/**
|
||||
* infra_cp_stats_response_cb() - callback function to handle stats event
|
||||
* @ev: stats event buffer
|
||||
* @cookie: a cookie for the request context
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static inline
|
||||
void infra_cp_stats_response_cb(struct infra_cp_stats_event *ev,
|
||||
void *cookie)
|
||||
{
|
||||
struct infra_cp_stats_event *priv;
|
||||
struct osif_request *request;
|
||||
|
||||
request = osif_request_get(cookie);
|
||||
if (!request) {
|
||||
osif_err("Obsolete request");
|
||||
return;
|
||||
}
|
||||
|
||||
priv = osif_request_priv(request);
|
||||
|
||||
priv->action = ev->action;
|
||||
priv->request_id = ev->request_id;
|
||||
priv->status = ev->status;
|
||||
get_twt_infra_cp_stats(ev, priv);
|
||||
|
||||
osif_request_complete(request);
|
||||
osif_request_put(request);
|
||||
}
|
||||
|
||||
#ifdef WLAN_SUPPORT_TWT
|
||||
/*Infra limits Add comment here*/
|
||||
#define MAX_TWT_STAT_VDEV_ENTRIES 1
|
||||
#define MAX_TWT_STAT_MAC_ADDR_ENTRIES 1
|
||||
struct infra_cp_stats_event *
|
||||
wlan_cfg80211_mc_twt_get_infra_cp_stats(struct wlan_objmgr_vdev *vdev,
|
||||
uint32_t dialog_id,
|
||||
uint8_t twt_peer_mac[QDF_MAC_ADDR_SIZE],
|
||||
int *errno)
|
||||
{
|
||||
void *cookie;
|
||||
QDF_STATUS status;
|
||||
struct infra_cp_stats_event *priv, *out;
|
||||
struct twt_infra_cp_stats_event *twt_event;
|
||||
struct wlan_objmgr_peer *peer;
|
||||
struct osif_request *request;
|
||||
struct infra_cp_stats_cmd_info info = {0};
|
||||
static const struct osif_request_params params = {
|
||||
.priv_size = sizeof(*priv),
|
||||
.timeout_ms = 2 * CP_STATS_WAIT_TIME_STAT,
|
||||
.dealloc = wlan_cfg80211_mc_infra_cp_stats_dealloc,
|
||||
};
|
||||
|
||||
osif_debug("Enter");
|
||||
|
||||
out = qdf_mem_malloc(sizeof(*out));
|
||||
if (!out) {
|
||||
*errno = -ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
out->twt_infra_cp_stats =
|
||||
qdf_mem_malloc(sizeof(*out->twt_infra_cp_stats));
|
||||
if (!out->twt_infra_cp_stats) {
|
||||
*errno = -ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
request = osif_request_alloc(¶ms);
|
||||
if (!request) {
|
||||
qdf_mem_free(out);
|
||||
*errno = -ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cookie = osif_request_cookie(request);
|
||||
priv = osif_request_priv(request);
|
||||
|
||||
priv->twt_infra_cp_stats =
|
||||
qdf_mem_malloc(sizeof(*priv->twt_infra_cp_stats));
|
||||
if (!priv->twt_infra_cp_stats) {
|
||||
*errno = -ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
twt_event = priv->twt_infra_cp_stats;
|
||||
|
||||
info.request_cookie = cookie;
|
||||
info.stats_id = TYPE_REQ_CTRL_PATH_TWT_STAT;
|
||||
info.action = ACTION_REQ_CTRL_PATH_STAT_GET;
|
||||
info.infra_cp_stats_resp_cb = infra_cp_stats_response_cb;
|
||||
info.num_pdev_ids = 0;
|
||||
info.num_vdev_ids = MAX_TWT_STAT_VDEV_ENTRIES;
|
||||
info.vdev_id[0] = wlan_vdev_get_id(vdev);
|
||||
info.num_mac_addr_list = MAX_TWT_STAT_MAC_ADDR_ENTRIES;
|
||||
qdf_mem_copy(&info.peer_mac_addr[0], twt_peer_mac, QDF_MAC_ADDR_SIZE);
|
||||
|
||||
info.dialog_id = dialog_id;
|
||||
info.num_pdev_ids = 0;
|
||||
|
||||
peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_CP_STATS_ID);
|
||||
if (!peer) {
|
||||
osif_err("peer is null");
|
||||
*errno = -EINVAL;
|
||||
goto get_twt_stats_fail;
|
||||
}
|
||||
wlan_objmgr_peer_release_ref(peer, WLAN_CP_STATS_ID);
|
||||
|
||||
status = ucfg_infra_cp_stats_register_resp_cb(wlan_vdev_get_psoc(vdev),
|
||||
&info);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
osif_err("Failed to register resp callback: %d", status);
|
||||
*errno = qdf_status_to_os_return(status);
|
||||
goto get_twt_stats_fail;
|
||||
}
|
||||
|
||||
status = ucfg_send_infra_cp_stats_request(vdev, &info);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
osif_err("Failed to send twt stats request status: %d",
|
||||
status);
|
||||
*errno = qdf_status_to_os_return(status);
|
||||
goto get_twt_stats_fail;
|
||||
}
|
||||
|
||||
*errno = osif_request_wait_for_response(request);
|
||||
if (*errno) {
|
||||
osif_err("wait failed or timed out ret: %d", *errno);
|
||||
goto get_twt_stats_fail;
|
||||
}
|
||||
|
||||
out->num_twt_infra_cp_stats = priv->num_twt_infra_cp_stats;
|
||||
out->request_id = priv->request_id;
|
||||
out->twt_infra_cp_stats->dialog_id = twt_event->dialog_id;
|
||||
out->twt_infra_cp_stats->status = twt_event->status;
|
||||
out->twt_infra_cp_stats->num_sp_cycles = twt_event->num_sp_cycles;
|
||||
out->twt_infra_cp_stats->avg_sp_dur_us = twt_event->avg_sp_dur_us;
|
||||
out->twt_infra_cp_stats->min_sp_dur_us = twt_event->min_sp_dur_us;
|
||||
out->twt_infra_cp_stats->max_sp_dur_us = twt_event->max_sp_dur_us;
|
||||
out->twt_infra_cp_stats->tx_mpdu_per_sp = twt_event->tx_mpdu_per_sp;
|
||||
out->twt_infra_cp_stats->rx_mpdu_per_sp = twt_event->rx_mpdu_per_sp;
|
||||
out->twt_infra_cp_stats->tx_bytes_per_sp = twt_event->tx_bytes_per_sp;
|
||||
out->twt_infra_cp_stats->rx_bytes_per_sp = twt_event->rx_bytes_per_sp;
|
||||
osif_request_put(request);
|
||||
|
||||
osif_debug("Exit");
|
||||
|
||||
return out;
|
||||
|
||||
get_twt_stats_fail:
|
||||
osif_request_put(request);
|
||||
wlan_cfg80211_mc_infra_cp_stats_free_stats_event(out);
|
||||
|
||||
osif_debug("Exit");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
#endif /* WLAN_SUPPORT_INFRA_CTRL_PATH_STATS */
|
||||
|
||||
struct stats_event *
|
||||
wlan_cfg80211_mc_cp_stats_get_station_stats(struct wlan_objmgr_vdev *vdev,
|
||||
int *errno)
|
||||
|
Loading…
Reference in New Issue
Block a user