qcacld-3.0: Move get_peer_info into cp_stats component

Move WMI_REQUEST_PEER_STATS_INFO_CMDID related statistics into
cp_stats component.

Change-Id: I636221b0bc0e28180c97cd269440a7c733716a1d
CRs-Fixed: 2680618
This commit is contained in:
Min Liu 2020-05-06 20:45:45 +08:00 • committed by snandini
commit f7d6bc2675
22 changed files with 1109 additions and 612 deletions

14
Kbuild
View file

@ -722,7 +722,13 @@ CLD_WMI_ROAM_OBJS += $(WMI_DIR)/src/wmi_unified_roam_tlv.o \
$(WMI_DIR)/src/wmi_unified_roam_api.o
endif
CLD_WMI_OBJS := $(CLD_WMI_ROAM_OBJS)
ifeq ($(CONFIG_CP_STATS), y)
CLD_WMI_MC_CP_STATS_OBJS := $(WMI_DIR)/src/wmi_unified_mc_cp_stats_tlv.o \
$(WMI_DIR)/src/wmi_unified_mc_cp_stats_api.o
endif
CLD_WMI_OBJS := $(CLD_WMI_ROAM_OBJS) \
$(CLD_WMI_MC_CP_STATS_OBJS)
############ Qca-wifi-host-cmn ############
QDF_OS_DIR := qdf
@ -1562,6 +1568,11 @@ WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_cfr_tlv.o
WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_cfr_api.o
endif
ifeq ($(CONFIG_CP_STATS), y)
WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_cp_stats_api.o
WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_cp_stats_tlv.o
endif
########### FWLOG ###########
FWLOG_DIR := $(WLAN_COMMON_ROOT)/utils/fwlog
@ -2553,6 +2564,7 @@ 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) += -DQCA_SUPPORT_CP_STATS
cppflags-$(CONFIG_CP_STATS) += -DQCA_SUPPORT_MC_CP_STATS
cppflags-$(CONFIG_DCS) += -DDCS_INTERFERENCE_DETECTION
cppflags-$(CONFIG_FEATURE_INTEROP_ISSUES_AP) += -DWLAN_FEATURE_INTEROP_ISSUES_AP
cppflags-$(CONFIG_FEATURE_MEMDUMP_ENABLE) += -DWLAN_FEATURE_MEMDUMP_ENABLE

View file

@ -28,6 +28,8 @@
#include "wlan_cmn.h"
#include "qdf_event.h"
/* For WMI_MAX_CHAINS */
#include "wmi_unified.h"
#ifdef WLAN_SUPPORT_TWT
@ -53,12 +55,14 @@
* @TYPE_STATION_STATS: station stats was requested
* @TYPE_PEER_STATS: peer stats was requested
* @TYPE_MIB_STATS: MIB stats was requested
* @TYPE_PEER_STATS_INFO_EXT: peer stats info ext was requested
*/
enum stats_req_type {
TYPE_CONNECTION_TX_POWER = 0,
TYPE_STATION_STATS,
TYPE_PEER_STATS,
TYPE_MIB_STATS,
TYPE_PEER_STATS_INFO_EXT,
TYPE_MAX,
};
@ -184,6 +188,8 @@ struct request_info {
void *cookie);
void (*get_mib_stats_cb)(struct stats_event *ev,
void *cookie);
void (*get_peer_stats_cb)(struct stats_event *ev,
void *cookie);
} u;
uint32_t vdev_id;
uint32_t pdev_id;
@ -497,6 +503,40 @@ struct chain_rssi_event {
int8_t chain_rssi[MAX_NUM_CHAINS];
};
/**
* struct peer_stats_info_ext_event - peer extended stats info
* @peer_macaddr: MAC address
* @tx_packets: packets transmitted to this station
* @tx_bytes: bytes transmitted to this station
* @rx_packets: packets received from this station
* @rx_bytes: bytes received from this station
* @tx_retries: cumulative retry counts
* @tx_failed: the number of failed frames
* @tx_succeed: the number of succeed frames
* @rssi: the signal strength
* @tx_rate: last used tx bitrate (kbps)
* @tx_rate_code: last tx rate code (last_tx_rate_code of wmi_peer_stats_info)
* @rx_rate: last used rx bitrate (kbps)
* @rx_rate_code: last rx rate code (last_rx_rate_code of wmi_peer_stats_info)
* @peer_rssi_per_chain: the average value of RSSI (dbm) per chain
*/
struct peer_stats_info_ext_event {
struct qdf_mac_addr peer_macaddr;
uint32_t tx_packets;
uint64_t tx_bytes;
uint32_t rx_packets;
uint64_t rx_bytes;
uint32_t tx_retries;
uint32_t tx_failed;
uint32_t tx_succeed;
int32_t rssi;
uint32_t tx_rate;
uint32_t tx_rate_code;
uint32_t rx_rate;
uint32_t rx_rate_code;
int32_t peer_rssi_per_chain[WMI_MAX_CHAINS];
};
/**
* struct stats_event - parameters populated by stats event
* @num_pdev_stats: num pdev stats
@ -518,6 +558,8 @@ struct chain_rssi_event {
* @tx_rate_flags: tx rate flags, (enum tx_rate_info)
* @last_event: The LSB indicates if the event is the last event or not and the
* MSB indicates if this feature is supported by FW or not.
* @num_peer_stats_info_ext: number of peer extended stats info
* @peer_stats_info_ext: peer extended stats info
*/
struct stats_event {
uint32_t num_pdev_stats;
@ -541,6 +583,56 @@ struct stats_event {
uint32_t rx_rate;
enum tx_rate_info tx_rate_flags;
uint32_t last_event;
uint32_t num_peer_stats_info_ext;
struct peer_stats_info_ext_event *peer_stats_info_ext;
};
/**
* struct peer_stats_request_params - peer stats request parameter
* @request_type: request type, one peer or all peers of the vdev
* @vdev_id: vdev id
* @peer_mac_addr: peer mac address, omitted if request type is all peers
* @reset_after_request: whether reset stats after request
*/
struct peer_stats_request_params {
uint32_t request_type;
uint32_t vdev_id;
uint8_t peer_mac_addr[QDF_MAC_ADDR_SIZE];
uint32_t reset_after_request;
};
/**
* struct wmi_host_peer_stats_info - WMI peer stats info
* @peer_macaddr: peer mac address
* @tx_bytes: tx_bytes
* @tx_packets: tx packets
* @rx_bytes: rx_bytes
* @rx_packets: rx packets
* @tx_retries: tx retries of MPDU
* @tx_failed: tx failed MPDU
* @last_tx_rate_code: rate code of the last tx
* @last_rx_rate_code: rate code of the last rx
* @last_tx_bitrate_kbps: bitrate in bps of the last tx
* @last_rx_bitrate_kbps: bitrate in bps of the last rx
* @peer_rssi: peer rssi
* @tx_succeed: tx succeed MPDU
* @peer_rssi_per_chain: peer rssi per chain
*/
typedef struct {
struct qdf_mac_addr peer_macaddr;
uint64_t tx_bytes;
uint32_t tx_packets;
uint64_t rx_bytes;
uint32_t rx_packets;
uint32_t tx_retries;
uint32_t tx_failed;
uint32_t last_tx_rate_code;
uint32_t last_rx_rate_code;
uint32_t last_tx_bitrate_kbps;
uint32_t last_rx_bitrate_kbps;
int32_t peer_rssi;
uint32_t tx_succeed;
int32_t peer_rssi_per_chain[WMI_MAX_CHAINS];
} wmi_host_peer_stats_info;
#endif /* __WLAN_CP_STATS_MC_DEFS_H__ */

View file

@ -584,6 +584,35 @@ static void tgt_mc_cp_stats_extract_mib_stats(struct wlan_objmgr_psoc *psoc,
}
#endif
static void
tgt_mc_cp_stats_extract_peer_stats_info_ext(struct wlan_objmgr_psoc *psoc,
struct stats_event *ev)
{
QDF_STATUS status;
struct request_info last_req = {0};
bool pending = false;
if (!ev->peer_stats_info_ext || ev->num_peer_stats_info_ext == 0) {
cp_stats_debug("no peer_stats_info_ext");
return;
}
status = ucfg_mc_cp_stats_get_pending_req(psoc,
TYPE_PEER_STATS_INFO_EXT,
&last_req);
if (QDF_IS_STATUS_ERROR(status)) {
cp_stats_err("ucfg_mc_cp_stats_get_pending_req failed");
return;
}
ucfg_mc_cp_stats_reset_pending_req(psoc, TYPE_PEER_STATS_INFO_EXT,
&last_req, &pending);
if (last_req.u.get_peer_stats_cb && pending) {
last_req.u.get_peer_stats_cb(ev, last_req.cookie);
last_req.u.get_peer_stats_cb = NULL;
}
}
static void tgt_mc_cp_stats_extract_cca_stats(struct wlan_objmgr_psoc *psoc,
struct stats_event *ev)
{
@ -915,6 +944,9 @@ QDF_STATUS tgt_mc_cp_stats_process_stats_event(struct wlan_objmgr_psoc *psoc,
if (ucfg_mc_cp_stats_is_req_pending(psoc, TYPE_MIB_STATS))
tgt_mc_cp_stats_extract_mib_stats(psoc, ev);
if (ucfg_mc_cp_stats_is_req_pending(psoc, TYPE_PEER_STATS_INFO_EXT))
tgt_mc_cp_stats_extract_peer_stats_info_ext(psoc, ev);
tgt_mc_cp_stats_extract_cca_stats(psoc, ev);
tgt_mc_cp_send_lost_link_stats(psoc, ev);
@ -942,12 +974,29 @@ QDF_STATUS tgt_send_mc_cp_stats_req(struct wlan_objmgr_psoc *psoc,
struct request_info *req)
{
struct wlan_lmac_if_cp_stats_tx_ops *tx_ops;
QDF_STATUS status;
tx_ops = target_if_cp_stats_get_tx_ops(psoc);
if (!tx_ops || !tx_ops->send_req_stats) {
if (!tx_ops) {
cp_stats_err("could not get tx_ops");
return QDF_STATUS_E_NULL_VALUE;
}
return tx_ops->send_req_stats(psoc, type, req);
switch (type) {
case TYPE_PEER_STATS_INFO_EXT:
if (!tx_ops->send_req_peer_stats) {
cp_stats_err("could not get send_req_peer_stats");
return QDF_STATUS_E_NULL_VALUE;
}
status = tx_ops->send_req_peer_stats(psoc, req);
break;
default:
if (!tx_ops->send_req_stats) {
cp_stats_err("could not get send_req_stats");
return QDF_STATUS_E_NULL_VALUE;
}
status = tx_ops->send_req_stats(psoc, type, req);
}
return status;
}

View file

@ -850,6 +850,7 @@ void ucfg_mc_cp_stats_free_stats_resources(struct stats_event *ev)
qdf_mem_free(ev->vdev_summary_stats);
qdf_mem_free(ev->vdev_chain_rssi);
qdf_mem_free(ev->peer_extended_stats);
qdf_mem_free(ev->peer_stats_info_ext);
qdf_mem_zero(ev, sizeof(*ev));
}

View file

@ -336,6 +336,8 @@ static void target_if_cp_stats_free_stats_event(struct stats_event *ev)
qdf_mem_free(ev->vdev_chain_rssi);
ev->vdev_chain_rssi = NULL;
target_if_cp_stats_free_mib_stats(ev);
qdf_mem_free(ev->peer_stats_info_ext);
ev->peer_stats_info_ext = NULL;
}
static QDF_STATUS target_if_cp_stats_extract_pdev_stats(
@ -813,6 +815,130 @@ end:
return qdf_status_to_os_return(status);
}
static QDF_STATUS
target_if_cp_stats_extract_peer_stats_event(struct wmi_unified *wmi_hdl,
struct stats_event *ev,
uint8_t *data)
{
QDF_STATUS status;
wmi_host_stats_event stats_param = {0};
struct peer_stats_info_ext_event *peer_stats_info;
wmi_host_peer_stats_info stats_info;
uint32_t peer_stats_info_size;
int i, j;
status = wmi_extract_peer_stats_param(wmi_hdl, data, &stats_param);
if (QDF_IS_STATUS_ERROR(status)) {
cp_stats_err("peer stats param extract failed: %d", status);
return status;
}
if (stats_param.num_peer_stats_info_ext == 0) {
cp_stats_err("num_peer_stats_info_ext is 0");
return status;
}
ev->num_peer_stats_info_ext = stats_param.num_peer_stats_info_ext;
peer_stats_info_size = sizeof(*ev->peer_stats_info_ext) *
ev->num_peer_stats_info_ext;
ev->peer_stats_info_ext = qdf_mem_malloc(peer_stats_info_size);
if (!ev->peer_stats_info_ext) {
ev->num_peer_stats_info_ext = 0;
return QDF_STATUS_E_NOMEM;
}
peer_stats_info = ev->peer_stats_info_ext;
for (i = 0; i < ev->num_peer_stats_info_ext; i++) {
status = wmi_extract_peer_stats_info(wmi_hdl, data,
i, &stats_info);
if (QDF_IS_STATUS_ERROR(status)) {
cp_stats_err("peer stats info extract failed: %d",
status);
qdf_mem_free(ev->peer_stats_info_ext);
ev->peer_stats_info_ext = NULL;
ev->num_peer_stats_info_ext = 0;
return status;
}
qdf_mem_copy(&peer_stats_info->peer_macaddr,
&stats_info.peer_macaddr,
sizeof(peer_stats_info->peer_macaddr));
peer_stats_info->tx_packets = stats_info.tx_packets;
peer_stats_info->tx_bytes = stats_info.tx_bytes;
peer_stats_info->rx_packets = stats_info.rx_packets;
peer_stats_info->rx_bytes = stats_info.rx_bytes;
peer_stats_info->tx_retries = stats_info.tx_retries;
peer_stats_info->tx_failed = stats_info.tx_failed;
peer_stats_info->tx_succeed = stats_info.tx_succeed;
peer_stats_info->rssi = stats_info.peer_rssi;
peer_stats_info->tx_rate = stats_info.last_tx_bitrate_kbps;
peer_stats_info->tx_rate_code = stats_info.last_tx_rate_code;
peer_stats_info->rx_rate = stats_info.last_rx_bitrate_kbps;
peer_stats_info->rx_rate_code = stats_info.last_rx_rate_code;
for (j = 0; j < WMI_MAX_CHAINS; j++)
peer_stats_info->peer_rssi_per_chain[j] =
stats_info.peer_rssi_per_chain[j];
peer_stats_info++;
}
return QDF_STATUS_SUCCESS;
}
/**
* target_if_mc_cp_stats_peer_stats_info_event_handler() - function to handle
* peer stats info event from firmware.
* @scn: scn handle
* @data: data buffer for event
* @datalen: data length
*
* Return: status of operation.
*/
static int target_if_mc_cp_stats_peer_stats_info_event_handler(ol_scn_t scn,
uint8_t *data,
uint32_t datalen)
{
QDF_STATUS status;
struct stats_event ev = {0};
struct wlan_objmgr_psoc *psoc;
struct wmi_unified *wmi_handle;
struct wlan_lmac_if_cp_stats_rx_ops *rx_ops;
if (!scn || !data) {
cp_stats_err("scn: 0x%pK, data: 0x%pK", scn, data);
return -EINVAL;
}
psoc = target_if_get_psoc_from_scn_hdl(scn);
if (!psoc) {
cp_stats_err("null psoc");
return -EINVAL;
}
rx_ops = target_if_cp_stats_get_rx_ops(psoc);
if (!rx_ops || !rx_ops->process_stats_event) {
cp_stats_err("callback not registered");
return -EINVAL;
}
wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
if (!wmi_handle) {
cp_stats_err("wmi_handle is null");
return -EINVAL;
}
status = target_if_cp_stats_extract_peer_stats_event(wmi_handle,
&ev, data);
if (QDF_IS_STATUS_ERROR(status)) {
cp_stats_err("extract event failed");
goto end;
}
status = rx_ops->process_stats_event(psoc, &ev);
end:
target_if_cp_stats_free_stats_event(&ev);
return qdf_status_to_os_return(status);
}
static void target_if_cp_stats_inc_wake_lock_stats(uint32_t reason,
struct wake_lock_stats *stats,
uint32_t *unspecified_wake_count)
@ -916,6 +1042,13 @@ target_if_cp_stats_register_event_handler(struct wlan_objmgr_psoc *psoc)
if (ret_val)
cp_stats_err("Failed to register stats event cb");
ret_val = wmi_unified_register_event_handler(wmi_handle,
wmi_peer_stats_info_event_id,
target_if_mc_cp_stats_peer_stats_info_event_handler,
WMI_RX_WORK_CTX);
if (ret_val)
cp_stats_err("Failed to register peer stats info event cb");
return qdf_status_from_os_return(ret_val);
}
@ -934,6 +1067,8 @@ target_if_cp_stats_unregister_event_handler(struct wlan_objmgr_psoc *psoc)
cp_stats_err("wmi_handle is null");
return QDF_STATUS_E_INVAL;
}
wmi_unified_unregister_event_handler(wmi_handle,
wmi_peer_stats_info_event_id);
wmi_unified_unregister_event_handler(wmi_handle,
wmi_update_stats_event_id);
@ -1035,6 +1170,36 @@ target_if_cp_stats_register_handlers(struct wlan_objmgr_psoc *psoc)
return qdf_status;
}
/**
* target_if_cp_stats_send_peer_stats_req() - API to send peer stats request
* to wmi
* @psoc: pointer to psoc object
* @req: pointer to object containing peer stats request parameters
*
* Return: status of operation.
*/
static QDF_STATUS
target_if_cp_stats_send_peer_stats_req(struct wlan_objmgr_psoc *psoc,
struct request_info *req)
{
struct wmi_unified *wmi_handle;
struct peer_stats_request_params param = {0};
wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
if (!wmi_handle) {
cp_stats_err("wmi_handle is null.");
return QDF_STATUS_E_NULL_VALUE;
}
param.request_type = WMI_REQUEST_ONE_PEER_STATS_INFO;
param.vdev_id = req->vdev_id;
qdf_mem_copy(param.peer_mac_addr, req->peer_mac_addr,
QDF_MAC_ADDR_SIZE);
param.reset_after_request = 0;
return wmi_unified_peer_stats_request_send(wmi_handle, &param);
}
QDF_STATUS
target_if_cp_stats_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
{
@ -1058,6 +1223,8 @@ target_if_cp_stats_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
cp_stats_tx_ops->inc_wake_lock_stats =
target_if_cp_stats_inc_wake_lock_stats;
cp_stats_tx_ops->send_req_stats = target_if_cp_stats_send_stats_req;
cp_stats_tx_ops->send_req_peer_stats =
target_if_cp_stats_send_peer_stats_req;
return QDF_STATUS_SUCCESS;
}

View file

@ -0,0 +1,100 @@
/*
* Copyright (c) 2013-2020, 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: Implement API's specific to control path stats component.
*/
#ifndef _WMI_UNIFIED_MC_CP_STATS_API_H_
#define _WMI_UNIFIED_MC_CP_STATS_API_H_
#include <wlan_cp_stats_mc_defs.h>
/**
* wmi_extract_per_chain_rssi_stats() - extract rssi stats from event
* @wmi_handle: wmi handle
* @evt_buf: pointer to event buffer
* @index: Index into rssi stats
* @rssi_stats: Pointer to hold rssi stats
*
* Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
*/
QDF_STATUS
wmi_extract_per_chain_rssi_stats(wmi_unified_t wmi_handle, void *evt_buf,
uint32_t index,
struct wmi_host_per_chain_rssi_stats *rssi_stats);
/**
* wmi_extract_peer_adv_stats() - extract advance (extd2) peer stats from event
* @wmi_handle: wmi handle
* @evt_buf: pointer to event buffer
* @peer_adv_stats: Pointer to hold extended peer stats
*
* Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
*/
QDF_STATUS
wmi_extract_peer_adv_stats(wmi_unified_t wmi_handle, void *evt_buf,
struct wmi_host_peer_adv_stats *peer_adv_stats);
#ifdef WLAN_FEATURE_MIB_STATS
/**
* wmi_extract_mib_stats() - extract mib stats from event
* @wmi_handle: wmi handle
* @evt_buf: pointer to event buffer
* @mib_stats: pointer to hold mib stats
*
* Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
*/
QDF_STATUS wmi_extract_mib_stats(wmi_unified_t wmi_handle, void *evt_buf,
struct mib_stats_metrics *mib_stats);
#endif
/**
* wmi_unified_peer_stats_request_send() - send peer stats request to fw
* @wmi_handle: wmi handle
* @param: pointer to peer stats request parameters
*
* Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
*/
QDF_STATUS
wmi_unified_peer_stats_request_send(wmi_unified_t wmi_handle,
struct peer_stats_request_params *param);
/**
* wmi_extract_peer_stats_param() - extract all stats count from event
* @wmi_handle: wmi handle
* @evt_buf: pointer to event buffer
* @stats_param: Pointer to hold stats count
*
* Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
*/
QDF_STATUS
wmi_extract_peer_stats_param(wmi_unified_t wmi_handle, void *evt_buf,
wmi_host_stats_event *stats_param);
/**
* wmi_extract_peer_stats_info() - extract peer stats info from event
* @wmi_handle: wmi handle
* @evt_buf: pointer to event buffer
* @index: Index into beacon stats
* @peer_stats_info: Pointer to hold peer stats info
*
* Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
*/
QDF_STATUS
wmi_extract_peer_stats_info(wmi_unified_t wmi_handle, void *evt_buf,
uint32_t index,
wmi_host_peer_stats_info *peer_stats_info);
#endif /* _WMI_UNIFIED_MC_CP_STATS_API_H_ */

View file

@ -0,0 +1,92 @@
/*
* Copyright (c) 2016-2020, 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: Implement API's specific to cp stats component.
*/
#include "wmi_unified_priv.h"
#include "wmi_unified_param.h"
#include "wmi_unified_mc_cp_stats_api.h"
QDF_STATUS
wmi_extract_per_chain_rssi_stats(wmi_unified_t wmi_handle, void *evt_buf,
uint32_t index,
struct wmi_host_per_chain_rssi_stats *rssi_stats)
{
if (wmi_handle->ops->extract_per_chain_rssi_stats)
return wmi_handle->ops->extract_per_chain_rssi_stats(wmi_handle,
evt_buf, index, rssi_stats);
return QDF_STATUS_E_FAILURE;
}
QDF_STATUS
wmi_extract_peer_adv_stats(wmi_unified_t wmi_handle, void *evt_buf,
struct wmi_host_peer_adv_stats *peer_adv_stats)
{
if (wmi_handle->ops->extract_peer_adv_stats)
return wmi_handle->ops->extract_peer_adv_stats(wmi_handle,
evt_buf, peer_adv_stats);
return QDF_STATUS_E_FAILURE;
}
#ifdef WLAN_FEATURE_MIB_STATS
QDF_STATUS wmi_extract_mib_stats(wmi_unified_t wmi_handle, void *evt_buf,
struct mib_stats_metrics *mib_stats)
{
if (wmi_handle->ops->extract_mib_stats)
return wmi_handle->ops->extract_mib_stats(wmi_handle,
evt_buf,
mib_stats);
return QDF_STATUS_E_FAILURE;
}
#endif
QDF_STATUS
wmi_unified_peer_stats_request_send(wmi_unified_t wmi_handle,
struct peer_stats_request_params *param)
{
if (wmi_handle->ops->send_request_peer_stats_info_cmd)
return wmi_handle->ops->send_request_peer_stats_info_cmd(
wmi_handle, param);
return QDF_STATUS_E_FAILURE;
}
QDF_STATUS
wmi_extract_peer_stats_param(wmi_unified_t wmi_handle, void *evt_buf,
wmi_host_stats_event *stats_param)
{
if (wmi_handle->ops->extract_peer_stats_count)
return wmi_handle->ops->extract_peer_stats_count(wmi_handle,
evt_buf, stats_param);
return QDF_STATUS_E_FAILURE;
}
QDF_STATUS
wmi_extract_peer_stats_info(wmi_unified_t wmi_handle, void *evt_buf,
uint32_t index,
wmi_host_peer_stats_info *peer_stats_info)
{
if (wmi_handle->ops->extract_peer_stats_info)
return wmi_handle->ops->extract_peer_stats_info(wmi_handle,
evt_buf, index, peer_stats_info);
return QDF_STATUS_E_FAILURE;
}

View file

@ -0,0 +1,433 @@
/*
* Copyright (c) 2013-2020, 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.
*/
#include "osdep.h"
#include "wmi.h"
#include "wmi_unified_priv.h"
#include "wmi_unified_param.h"
/**
* extract_per_chain_rssi_stats_tlv() - api to extract rssi stats from event
* buffer
* @wmi_handle: wmi handle
* @evt_buf: pointer to event buffer
* @index: Index into vdev stats
* @rssi_stats: Pointer to hold rssi stats
*
* Return: QDF_STATUS_SUCCESS for success or error code
*/
static QDF_STATUS
extract_per_chain_rssi_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf,
uint32_t index,
struct wmi_host_per_chain_rssi_stats *rssi_stats)
{
uint8_t *data;
wmi_rssi_stats *fw_rssi_stats;
wmi_per_chain_rssi_stats *rssi_event;
WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
if (!evt_buf) {
WMI_LOGE("evt_buf is null");
return QDF_STATUS_E_NULL_VALUE;
}
param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
rssi_event = param_buf->chain_stats;
if (index >= rssi_event->num_per_chain_rssi_stats) {
WMI_LOGE("invalid index");
return QDF_STATUS_E_INVAL;
}
data = ((uint8_t *)(&rssi_event[1])) + WMI_TLV_HDR_SIZE;
fw_rssi_stats = &((wmi_rssi_stats *)data)[index];
if (fw_rssi_stats->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS)
return QDF_STATUS_E_INVAL;
rssi_stats->vdev_id = fw_rssi_stats->vdev_id;
qdf_mem_copy(rssi_stats->rssi_avg_beacon,
fw_rssi_stats->rssi_avg_beacon,
sizeof(fw_rssi_stats->rssi_avg_beacon));
qdf_mem_copy(rssi_stats->rssi_avg_data,
fw_rssi_stats->rssi_avg_data,
sizeof(fw_rssi_stats->rssi_avg_data));
qdf_mem_copy(&rssi_stats->peer_macaddr,
&fw_rssi_stats->peer_macaddr,
sizeof(fw_rssi_stats->peer_macaddr));
return QDF_STATUS_SUCCESS;
}
/**
* extract_peer_adv_stats_tlv() - extract adv peer stats from event
* @param wmi_handle: wmi handle
* @param evt_buf: pointer to event buffer
* @param index: Index into extended peer stats
* @param peer_adv_stats: Pointer to hold adv peer stats
*
* Return: QDF_STATUS_SUCCESS for success or error code
*/
static QDF_STATUS extract_peer_adv_stats_tlv(wmi_unified_t wmi_handle,
void *evt_buf,
struct wmi_host_peer_adv_stats
*peer_adv_stats)
{
WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
wmi_peer_extd2_stats *adv_stats;
int i;
param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf;
adv_stats = param_buf->peer_extd2_stats;
if (!adv_stats) {
WMI_LOGD("%s: no peer_adv stats in event buffer", __func__);
return QDF_STATUS_E_INVAL;
}
for (i = 0; i < param_buf->num_peer_extd2_stats; i++) {
WMI_MAC_ADDR_TO_CHAR_ARRAY(&adv_stats[i].peer_macaddr,
peer_adv_stats[i].peer_macaddr);
peer_adv_stats[i].fcs_count = adv_stats[i].rx_fcs_err;
peer_adv_stats[i].rx_bytes =
(uint64_t)adv_stats[i].rx_bytes_u32 <<
WMI_LOWER_BITS_SHIFT_32 |
adv_stats[i].rx_bytes_l32;
peer_adv_stats[i].rx_count = adv_stats[i].rx_mpdus;
}
return QDF_STATUS_SUCCESS;
}
#ifdef WLAN_FEATURE_MIB_STATS
/**
* extract_mib_stats_tlv() - extract mib stats from event
* @wmi_handle: wmi handle
* @param evt_buf: pointer to event buffer
* @param mib_stats: pointer to hold mib stats
*
* Return: QDF_STATUS_SUCCESS for success or error code
*/
static QDF_STATUS extract_mib_stats_tlv(wmi_unified_t wmi_handle,
void *evt_buf,
struct mib_stats_metrics
*mib_stats)
{
WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
wmi_stats_event_fixed_param *ev_param;
uint8_t *data;
wmi_mib_stats *ev;
wmi_mib_extd_stats *ev_extd;
param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf;
ev_param = (wmi_stats_event_fixed_param *)param_buf->fixed_param;
data = (uint8_t *)param_buf->data;
ev = (wmi_mib_stats *)(data +
ev_param->num_pdev_stats * sizeof(wmi_pdev_stats) +
ev_param->num_vdev_stats * sizeof(wmi_vdev_stats) +
ev_param->num_peer_stats * sizeof(wmi_peer_stats) +
ev_param->num_bcnflt_stats *
sizeof(wmi_bcnfilter_stats_t) +
ev_param->num_chan_stats * sizeof(wmi_chan_stats));
qdf_mem_zero(mib_stats, sizeof(*mib_stats));
mib_stats->mib_counters.tx_frags =
ev->tx_mpdu_grp_frag_cnt;
mib_stats->mib_counters.group_tx_frames =
ev->tx_msdu_grp_frm_cnt;
mib_stats->mib_counters.failed_cnt = ev->tx_msdu_fail_cnt;
mib_stats->mib_counters.rx_frags = ev->rx_mpdu_frag_cnt;
mib_stats->mib_counters.group_rx_frames =
ev->rx_msdu_grp_frm_cnt;
mib_stats->mib_counters.fcs_error_cnt =
ev->rx_mpdu_fcs_err;
mib_stats->mib_counters.tx_frames =
ev->tx_msdu_frm_cnt;
mib_stats->mib_mac_statistics.retry_cnt =
ev->tx_msdu_retry_cnt;
mib_stats->mib_mac_statistics.frame_dup_cnt =
ev->rx_frm_dup_cnt;
mib_stats->mib_mac_statistics.rts_success_cnt =
ev->tx_rts_success_cnt;
mib_stats->mib_mac_statistics.rts_fail_cnt =
ev->tx_rts_fail_cnt;
mib_stats->mib_qos_counters.qos_tx_frag_cnt =
ev->tx_Qos_mpdu_grp_frag_cnt;
mib_stats->mib_qos_counters.qos_retry_cnt =
ev->tx_Qos_msdu_retry_UP;
mib_stats->mib_qos_counters.qos_failed_cnt =
ev->tx_Qos_msdu_fail_UP;
mib_stats->mib_qos_counters.qos_frame_dup_cnt =
ev->rx_Qos_frm_dup_cnt_UP;
mib_stats->mib_qos_counters.qos_rts_success_cnt =
ev->tx_Qos_rts_success_cnt_UP;
mib_stats->mib_qos_counters.qos_rts_fail_cnt =
ev->tx_Qos_rts_fail_cnt_UP;
mib_stats->mib_qos_counters.qos_rx_frag_cnt =
ev->rx_Qos_mpdu_frag_cnt_UP;
mib_stats->mib_qos_counters.qos_tx_frame_cnt =
ev->tx_Qos_msdu_frm_cnt_UP;
mib_stats->mib_qos_counters.qos_discarded_frame_cnt =
ev->rx_Qos_msdu_discard_cnt_UP;
mib_stats->mib_qos_counters.qos_mpdu_rx_cnt =
ev->rx_Qos_mpdu_cnt;
mib_stats->mib_qos_counters.qos_retries_rx_cnt =
ev->rx_Qos_mpdu_retryBit_cnt;
mib_stats->mib_rsna_stats.tkip_icv_err =
ev->rsna_TKIP_icv_err_cnt;
mib_stats->mib_rsna_stats.tkip_replays =
ev->rsna_TKIP_replay_err_cnt;
mib_stats->mib_rsna_stats.ccmp_decrypt_err =
ev->rsna_CCMP_decrypt_err_cnt;
mib_stats->mib_rsna_stats.ccmp_replays =
ev->rsna_CCMP_replay_err_cnt;
mib_stats->mib_counters_group3.tx_ampdu_cnt =
ev->tx_ampdu_cnt;
mib_stats->mib_counters_group3.tx_mpdus_in_ampdu_cnt =
ev->tx_mpdu_cnt_in_ampdu;
mib_stats->mib_counters_group3.tx_octets_in_ampdu_cnt =
ev->tx_octets_in_ampdu.upload.high;
mib_stats->mib_counters_group3.tx_octets_in_ampdu_cnt =
mib_stats->mib_counters_group3.tx_octets_in_ampdu_cnt << 32;
mib_stats->mib_counters_group3.tx_octets_in_ampdu_cnt +=
ev->tx_octets_in_ampdu.upload.low;
mib_stats->mib_counters_group3.ampdu_rx_cnt =
ev->rx_ampdu_cnt;
mib_stats->mib_counters_group3.mpdu_in_rx_ampdu_cnt =
ev->rx_mpdu_cnt_in_ampdu;
mib_stats->mib_counters_group3.rx_octets_in_ampdu_cnt =
ev->rx_octets_in_ampdu.upload.rx_octets_in_ampdu_high;
mib_stats->mib_counters_group3.rx_octets_in_ampdu_cnt =
mib_stats->mib_counters_group3.rx_octets_in_ampdu_cnt << 32;
mib_stats->mib_counters_group3.rx_octets_in_ampdu_cnt +=
ev->rx_octets_in_ampdu.upload.rx_octets_in_ampdu_low;
if (ev_param->num_mib_extd_stats) {
ev_extd = (wmi_mib_extd_stats *)((uint8_t *)ev +
ev_param->num_mib_stats * sizeof(wmi_mib_stats) +
ev_param->num_bcn_stats * sizeof(wmi_bcn_stats) +
ev_param->num_peer_extd_stats *
sizeof(wmi_peer_extd_stats));
mib_stats->mib_mac_statistics.multi_retry_cnt =
ev_extd->tx_msdu_multi_retry_cnt;
mib_stats->mib_mac_statistics.tx_ack_fail_cnt =
ev_extd->tx_ack_fail_cnt;
mib_stats->mib_qos_counters.qos_multi_retry_cnt =
ev_extd->tx_qos_msdu_multi_retry_up;
mib_stats->mib_qos_counters.tx_qos_ack_fail_cnt_up =
ev_extd->tx_qos_ack_fail_cnt_up;
mib_stats->mib_rsna_stats.cmac_icv_err =
ev_extd->rsna_cmac_icv_err_cnt;
mib_stats->mib_rsna_stats.cmac_replays =
ev_extd->rsna_cmac_replay_err_cnt;
mib_stats->mib_counters_group3.rx_ampdu_deli_crc_err_cnt =
ev_extd->rx_ampdu_deli_crc_err_cnt;
}
return QDF_STATUS_SUCCESS;
}
static void wmi_cp_stats_attach_mib_stats_tlv(struct wmi_ops *ops)
{
ops->extract_mib_stats = extract_mib_stats_tlv;
}
#else
static void wmi_cp_stats_attach_mib_stats_tlv(struct wmi_ops *ops)
{
}
#endif /* WLAN_FEATURE_MIB_STATS */
/**
* send_request_peer_stats_info_cmd_tlv() - WMI request peer stats function
* @wmi_handle: handle to WMI.
* @param: pointer to hold peer stats request parameter
*
* Return: QDF_STATUS
*/
static QDF_STATUS
send_request_peer_stats_info_cmd_tlv(wmi_unified_t wmi_handle,
struct peer_stats_request_params *param)
{
int32_t ret;
wmi_request_peer_stats_info_cmd_fixed_param *cmd;
wmi_buf_t buf;
uint16_t len = sizeof(wmi_request_peer_stats_info_cmd_fixed_param);
buf = wmi_buf_alloc(wmi_handle, len);
if (!buf)
return QDF_STATUS_E_NOMEM;
cmd = (wmi_request_peer_stats_info_cmd_fixed_param *)wmi_buf_data(buf);
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_request_peer_stats_info_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN(
wmi_request_peer_stats_info_cmd_fixed_param));
cmd->request_type = param->request_type;
cmd->vdev_id = param->vdev_id;
WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac_addr, &cmd->peer_macaddr);
cmd->reset_after_request = param->reset_after_request;
WMI_LOGD("PEER STATS REQ VDEV_ID:%d PEER:%pM TYPE:%d RESET:%d",
cmd->vdev_id, param->peer_mac_addr, cmd->request_type,
cmd->reset_after_request);
wmi_mtrace(WMI_REQUEST_PEER_STATS_INFO_CMDID, cmd->vdev_id, 0);
ret = wmi_unified_cmd_send(wmi_handle, buf, len,
WMI_REQUEST_PEER_STATS_INFO_CMDID);
if (ret) {
WMI_LOGE("Failed to send peer stats request to fw =%d", ret);
wmi_buf_free(buf);
}
return qdf_status_from_os_return(ret);
}
/**
* extract_peer_stats_count_tlv() - extract peer stats count from event
* @wmi_handle: wmi handle
* @evt_buf: pointer to event buffer
* @stats_param: Pointer to hold stats count
*
* Return: QDF_STATUS_SUCCESS for success or error code
*/
static QDF_STATUS
extract_peer_stats_count_tlv(wmi_unified_t wmi_handle, void *evt_buf,
wmi_host_stats_event *stats_param)
{
WMI_PEER_STATS_INFO_EVENTID_param_tlvs *param_buf;
wmi_peer_stats_info_event_fixed_param *ev_param;
param_buf = (WMI_PEER_STATS_INFO_EVENTID_param_tlvs *)evt_buf;
if (!param_buf)
return QDF_STATUS_E_FAILURE;
ev_param = param_buf->fixed_param;
if (!ev_param)
return QDF_STATUS_E_FAILURE;
if (!stats_param)
return QDF_STATUS_E_FAILURE;
stats_param->num_peer_stats_info_ext = ev_param->num_peers;
return QDF_STATUS_SUCCESS;
}
static void dump_peer_stats_info(wmi_peer_stats_info *stats)
{
u_int8_t mac[6];
int i;
WMI_MAC_ADDR_TO_CHAR_ARRAY(&stats->peer_macaddr, mac);
WMI_LOGD("mac %pM", mac);
WMI_LOGD("tx_bytes %d %d tx_packets %d %d",
stats->tx_bytes.low_32,
stats->tx_bytes.high_32,
stats->tx_packets.low_32,
stats->tx_packets.high_32);
WMI_LOGD("rx_bytes %d %d rx_packets %d %d",
stats->rx_bytes.low_32,
stats->rx_bytes.high_32,
stats->rx_packets.low_32,
stats->rx_packets.high_32);
WMI_LOGD("tx_retries %d tx_failed %d",
stats->tx_retries, stats->tx_failed);
WMI_LOGD("tx_rate_code %x rx_rate_code %x",
stats->last_tx_rate_code,
stats->last_rx_rate_code);
WMI_LOGD("tx_rate %x rx_rate %x",
stats->last_tx_bitrate_kbps,
stats->last_rx_bitrate_kbps);
WMI_LOGD("peer_rssi %d", stats->peer_rssi);
WMI_LOGD("tx_succeed %d", stats->tx_succeed);
for (i = 0; i < WMI_MAX_CHAINS; i++)
WMI_LOGD("chain%d_rssi %d", i, stats->peer_rssi_per_chain[i]);
}
/**
* extract_peer_stats_info_tlv() - extract peer stats info from event
* @wmi_handle: wmi handle
* @evt_buf: pointer to event buffer
* @index: Index into vdev stats
* @peer_stats_info: Pointer to hold peer stats info
*
* Return: QDF_STATUS_SUCCESS for success or error code
*/
static QDF_STATUS
extract_peer_stats_info_tlv(wmi_unified_t wmi_handle, void *evt_buf,
uint32_t index,
wmi_host_peer_stats_info *peer_stats_info)
{
WMI_PEER_STATS_INFO_EVENTID_param_tlvs *param_buf;
wmi_peer_stats_info_event_fixed_param *ev_param;
param_buf = (WMI_PEER_STATS_INFO_EVENTID_param_tlvs *)evt_buf;
ev_param = param_buf->fixed_param;
if (index < ev_param->num_peers) {
wmi_peer_stats_info *ev = &param_buf->peer_stats_info[index];
int i;
dump_peer_stats_info(ev);
WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr,
peer_stats_info->peer_macaddr.bytes);
peer_stats_info->tx_packets = ev->tx_packets.low_32;
peer_stats_info->tx_bytes = ev->tx_bytes.high_32;
peer_stats_info->tx_bytes <<= 32;
peer_stats_info->tx_bytes += ev->tx_bytes.low_32;
peer_stats_info->rx_packets = ev->rx_packets.low_32;
peer_stats_info->rx_bytes = ev->rx_bytes.high_32;
peer_stats_info->rx_bytes <<= 32;
peer_stats_info->rx_bytes += ev->rx_bytes.low_32;
peer_stats_info->tx_retries = ev->tx_retries;
peer_stats_info->tx_failed = ev->tx_failed;
peer_stats_info->tx_succeed = ev->tx_succeed;
peer_stats_info->peer_rssi = ev->peer_rssi;
peer_stats_info->last_tx_bitrate_kbps =
ev->last_tx_bitrate_kbps;
peer_stats_info->last_tx_rate_code = ev->last_tx_rate_code;
peer_stats_info->last_rx_bitrate_kbps =
ev->last_rx_bitrate_kbps;
peer_stats_info->last_rx_rate_code = ev->last_rx_rate_code;
for (i = 0; i < WMI_MAX_CHAINS; i++)
peer_stats_info->peer_rssi_per_chain[i] =
ev->peer_rssi_per_chain[i];
}
return QDF_STATUS_SUCCESS;
}
void wmi_mc_cp_stats_attach_tlv(wmi_unified_t wmi_handle)
{
struct wmi_ops *ops = wmi_handle->ops;
ops->extract_per_chain_rssi_stats = extract_per_chain_rssi_stats_tlv;
ops->extract_peer_adv_stats = extract_peer_adv_stats_tlv;
wmi_cp_stats_attach_mib_stats_tlv(ops);
ops->send_request_peer_stats_info_cmd =
send_request_peer_stats_info_cmd_tlv;
ops->extract_peer_stats_count = extract_peer_stats_count_tlv;
ops->extract_peer_stats_info = extract_peer_stats_info_tlv;
}

View file

@ -29,6 +29,7 @@
#include <linux/skbuff.h>
#include <linux/etherdevice.h>
#include <linux/if_ether.h>
#include <wlan_cfg80211_mc_cp_stats.h>
#include <wlan_cp_stats_mc_ucfg_api.h>
#include <wlan_hdd_stats.h>
#include <wlan_hdd_hostapd.h>
@ -1219,10 +1220,11 @@ static int hdd_get_connected_station_info(struct hdd_context *hdd_ctx,
{
struct sk_buff *skb = NULL;
uint32_t nl_buf_len;
struct sir_peer_info_ext peer_info;
bool txrx_rate = true;
struct stats_event *stats;
bool txrx_rate = false;
bool value;
QDF_STATUS status;
int ret;
nl_buf_len = NLMSG_HDRLEN;
nl_buf_len += (sizeof(stainfo->max_phy_rate) + NLA_HDRLEN) +
@ -1236,15 +1238,24 @@ static int hdd_get_connected_station_info(struct hdd_context *hdd_ctx,
status = ucfg_mlme_get_sap_get_peer_info(hdd_ctx->psoc, &value);
if (status != QDF_STATUS_SUCCESS)
hdd_err("Unable to fetch sap ger peer info");
if (!value ||
wlan_hdd_get_peer_info(adapter, mac_addr, &peer_info)) {
hdd_err("fail to get tx/rx rate");
txrx_rate = false;
} else {
stainfo->tx_rate = peer_info.tx_rate;
stainfo->rx_rate = peer_info.rx_rate;
if (value) {
stats = wlan_cfg80211_mc_cp_stats_get_peer_stats(adapter->vdev,
mac_addr.bytes,
&ret);
if (ret || !stats) {
hdd_err("fail to get tx/rx rate");
wlan_cfg80211_mc_cp_stats_free_stats_event(stats);
} else {
txrx_rate = true;
}
}
if (txrx_rate) {
stainfo->tx_rate = stats->peer_stats_info_ext->tx_rate;
stainfo->rx_rate = stats->peer_stats_info_ext->rx_rate;
nl_buf_len += (sizeof(stainfo->tx_rate) + NLA_HDRLEN) +
(sizeof(stainfo->rx_rate) + NLA_HDRLEN);
wlan_cfg80211_mc_cp_stats_free_stats_event(stats);
}
/* below info is only valid for HT/VHT mode */

View file

@ -4195,7 +4195,7 @@ static uint8_t hdd_get_rate_flags(uint32_t rate,
* Return: None
*/
static void wlan_hdd_fill_rate_info(struct hdd_fw_txrx_stats *txrx_stats,
struct sir_peer_info_ext *peer_info)
struct peer_stats_info_ext_event *peer_info)
{
uint8_t flags;
uint32_t rate_code;
@ -4280,8 +4280,7 @@ static int wlan_hdd_get_station_remote(struct wiphy *wiphy,
struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
struct hdd_context *hddctx = wiphy_priv(wiphy);
struct hdd_station_info *stainfo = NULL;
struct qdf_mac_addr macaddr;
struct sir_peer_info_ext peer_info;
struct stats_event *stats;
struct hdd_fw_txrx_stats txrx_stats;
int status;
@ -4298,9 +4297,10 @@ static int wlan_hdd_get_station_remote(struct wiphy *wiphy,
return -EINVAL;
}
qdf_mem_copy(macaddr.bytes, mac, QDF_MAC_ADDR_SIZE);
status = wlan_hdd_get_peer_info(adapter, macaddr, &peer_info);
if (status) {
stats = wlan_cfg80211_mc_cp_stats_get_peer_stats(adapter->vdev,
mac, &status);
if (status || !stats) {
wlan_cfg80211_mc_cp_stats_free_stats_event(stats);
hdd_put_sta_info_ref(&adapter->sta_info_list, &stainfo, true,
STA_INFO_WLAN_HDD_GET_STATION_REMOTE);
hdd_err("fail to get peer info from fw");
@ -4308,15 +4308,17 @@ static int wlan_hdd_get_station_remote(struct wiphy *wiphy,
}
qdf_mem_zero(&txrx_stats, sizeof(txrx_stats));
txrx_stats.tx_packets = peer_info.tx_packets;
txrx_stats.tx_bytes = peer_info.tx_bytes;
txrx_stats.rx_packets = peer_info.rx_packets;
txrx_stats.rx_bytes = peer_info.rx_bytes;
txrx_stats.tx_retries = peer_info.tx_retries;
txrx_stats.tx_failed = peer_info.tx_failed;
txrx_stats.rssi = peer_info.rssi + WLAN_HDD_TGT_NOISE_FLOOR_DBM;
wlan_hdd_fill_rate_info(&txrx_stats, &peer_info);
txrx_stats.tx_packets = stats->peer_stats_info_ext->tx_packets;
txrx_stats.tx_bytes = stats->peer_stats_info_ext->tx_bytes;
txrx_stats.rx_packets = stats->peer_stats_info_ext->rx_packets;
txrx_stats.rx_bytes = stats->peer_stats_info_ext->rx_bytes;
txrx_stats.tx_retries = stats->peer_stats_info_ext->tx_retries;
txrx_stats.tx_failed = stats->peer_stats_info_ext->tx_failed;
txrx_stats.rssi = stats->peer_stats_info_ext->rssi
+ WLAN_HDD_TGT_NOISE_FLOOR_DBM;
wlan_hdd_fill_rate_info(&txrx_stats, stats->peer_stats_info_ext);
wlan_hdd_fill_station_info(hddctx->psoc, sinfo, stainfo, &txrx_stats);
wlan_cfg80211_mc_cp_stats_free_stats_event(stats);
hdd_put_sta_info_ref(&adapter->sta_info_list, &stainfo, true,
STA_INFO_WLAN_HDD_GET_STATION_REMOTE);
@ -6006,117 +6008,6 @@ int wlan_hdd_get_link_speed(struct hdd_adapter *adapter, uint32_t *link_speed)
return 0;
}
struct peer_info_priv {
struct sir_peer_sta_ext_info peer_sta_ext_info;
};
/**
* wlan_hdd_get_peer_info_cb() - get peer info callback
* @sta_info: pointer of peer information
* @context: get peer info callback context
*
* This function will fill stats info to peer info priv
*
*/
static void wlan_hdd_get_peer_info_cb(struct sir_peer_info_ext_resp *sta_info,
void *context)
{
struct osif_request *request;
struct peer_info_priv *priv;
uint8_t sta_num;
if ((!sta_info) || (!context)) {
hdd_err("Bad param, sta_info [%pK] context [%pK]",
sta_info, context);
return;
}
if (!sta_info->count) {
hdd_err("Fail to get remote peer info");
return;
}
if (sta_info->count > MAX_PEER_STA) {
hdd_warn("Exceed max peer number %d", sta_info->count);
sta_num = MAX_PEER_STA;
} else {
sta_num = sta_info->count;
}
request = osif_request_get(context);
if (!request) {
hdd_err("Obsolete request");
return;
}
priv = osif_request_priv(request);
priv->peer_sta_ext_info.sta_num = sta_num;
qdf_mem_copy(&priv->peer_sta_ext_info.info,
sta_info->info,
sta_num * sizeof(sta_info->info[0]));
osif_request_complete(request);
osif_request_put(request);
}
int wlan_hdd_get_peer_info(struct hdd_adapter *adapter,
struct qdf_mac_addr macaddress,
struct sir_peer_info_ext *peer_info_ext)
{
QDF_STATUS status;
void *cookie;
int ret;
struct sir_peer_info_ext_req peer_info_req;
struct osif_request *request;
struct peer_info_priv *priv;
static const struct osif_request_params params = {
.priv_size = sizeof(*priv),
.timeout_ms = WLAN_WAIT_TIME_STATS,
};
if (!adapter) {
hdd_err("adapter is NULL");
return -EFAULT;
}
request = osif_request_alloc(&params);
if (!request) {
hdd_err("Request allocation failure");
return -ENOMEM;
}
cookie = osif_request_cookie(request);
priv = osif_request_priv(request);
qdf_mem_copy(&peer_info_req.peer_macaddr, &macaddress,
QDF_MAC_ADDR_SIZE);
peer_info_req.sessionid = adapter->vdev_id;
peer_info_req.reset_after_request = 0;
status = sme_get_peer_info_ext(adapter->hdd_ctx->mac_handle,
&peer_info_req,
cookie,
wlan_hdd_get_peer_info_cb);
if (status != QDF_STATUS_SUCCESS) {
hdd_err("Unable to retrieve statistics for peer info");
ret = -EFAULT;
} else {
ret = osif_request_wait_for_response(request);
if (ret) {
hdd_err("SME timed out while retrieving peer info");
ret = -EFAULT;
} else {
/* only support one peer by now */
*peer_info_ext = priv->peer_sta_ext_info.info[0];
ret = 0;
}
}
osif_request_put(request);
return ret;
}
int wlan_hdd_get_station_stats(struct hdd_adapter *adapter)
{
int ret = 0;

View file

@ -461,19 +461,6 @@ int wlan_hdd_get_linkspeed_for_peermac(struct hdd_adapter *adapter,
*/
int wlan_hdd_get_link_speed(struct hdd_adapter *adapter, uint32_t *link_speed);
/**
* wlan_hdd_get_peer_info() - get peer info
* @adapter: hostapd interface
* @macaddress: request peer mac address
* @peer_info_ext: one peer extended info retrieved
*
* This function will call sme_get_peer_info_ext to get peer info
*
* Return: 0 on success, otherwise error value
*/
int wlan_hdd_get_peer_info(struct hdd_adapter *adapter,
struct qdf_mac_addr macaddress,
struct sir_peer_info_ext *peer_info_ext);
/**
* wlan_hdd_get_station_stats() - Get station statistics
* @adapter: adapter for which statistics are desired

View file

@ -2536,80 +2536,6 @@ struct link_speed_info {
uint32_t estLinkSpeed; /* Linkspeed from firmware */
};
/**
* struct sir_peer_info_ext_req - peer info request struct
* @peer_macaddr: MAC address
* @sessionid: vdev id
* @reset_after_request: fw reset statistics after query
*
* peer info request message's struct
*/
struct sir_peer_info_ext_req {
struct qdf_mac_addr peer_macaddr;
uint8_t sessionid;
uint8_t reset_after_request;
};
/**
* struct sir_peer_info_ext - peer info information struct
* (refer to station_info struct in Kernel)
* @peer_macaddr: MAC address
* @tx_packets: packets transmitted to this station
* @tx_bytes: bytes transmitted to this station
* @rx_packets: packets received from this station
* @rx_bytes: bytes received from this station
* @tx_retries: cumulative retry counts
* @tx_failed: the number of failed frames
* @tx_succeed: the number of succeed frames
* @rssi: the signal strength
* @tx_rate: last used tx bitrate (kbps)
* @tx_rate_code: last tx rate code (last_tx_rate_code of wmi_peer_stats_info)
* @rx_rate: last used rx bitrate (kbps)
* @rx_rate_code: last rx rate code (last_rx_rate_code of wmi_peer_stats_info)
* @peer_rssi_per_chain: the average value of RSSI (dbm) per chain
*
* a station's information
*/
struct sir_peer_info_ext {
struct qdf_mac_addr peer_macaddr;
uint32_t tx_packets;
uint64_t tx_bytes;
uint32_t rx_packets;
uint64_t rx_bytes;
uint32_t tx_retries;
uint32_t tx_failed;
uint32_t tx_succeed;
int32_t rssi;
uint32_t tx_rate;
uint32_t tx_rate_code;
uint32_t rx_rate;
uint32_t rx_rate_code;
int32_t peer_rssi_per_chain[WMI_MAX_CHAINS];
};
/**
* struct sir_peer_info_ext_resp - all peers' information struct
* @count: peer's number
* @info: peer information
*
* all station's information
*/
struct sir_peer_info_ext_resp {
uint8_t count;
struct sir_peer_info_ext info[0];
};
/**
* @sta_num: number of peer station which has valid info
* @info: peer extended information
*
* all SAP peer station's extended information retrieved
*/
struct sir_peer_sta_ext_info {
uint8_t sta_num;
struct sir_peer_info_ext info[MAX_PEER_STA];
};
/**
* struct sir_isolation_resp - isolation info related structure
* @isolation_chain0: isolation value for chain 0

View file

@ -598,9 +598,8 @@ struct sir_cfg_action_frm_tb_ppdu {
/*
* Unused SIR_HAL_ITC_MSG_TYPES_BEGIN + 382 to
* SIR_HAL_ITC_MSG_TYPES_BEGIN + 386
* SIR_HAL_ITC_MSG_TYPES_BEGIN + 387
*/
#define SIR_HAL_GET_PEER_INFO_EXT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 387)
/* ARP Debug stats */
#define SIR_HAL_SET_ARP_STATS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 388)

View file

@ -2662,23 +2662,6 @@ int sme_set_cck_tx_fir_override(mac_handle_t mac_handle, int vdev_id);
QDF_STATUS sme_set_smps_cfg(uint32_t vdev_id, uint32_t param_id,
uint32_t param_val);
/**
* sme_get_peer_info_ext() - sme api to get peer ext info
* @mac_handle: Opaque handle to the global MAC context
* @req: peer ext info request struct send to wma
* @context: context of callback function
* @callbackfn: hdd callback function when receive response
*
* This function will send WMA_GET_PEER_INFO_EXT to WMA
*
* Return: QDF_STATUS_SUCCESS or non-zero on failure
*/
QDF_STATUS sme_get_peer_info_ext(mac_handle_t mac_handle,
struct sir_peer_info_ext_req *req,
void *context,
void (*callbackfn)(struct sir_peer_info_ext_resp *param,
void *pcontext));
/**
* sme_get_chain_rssi() - Get chain rssi
* @mac_handle: Opaque handle to the global MAC context

View file

@ -309,10 +309,6 @@ struct sme_context {
sme_link_speed_cb link_speed_cb;
void *link_speed_context;
/* get extended peer info callback */
void (*pget_peer_info_ext_ind_cb)(struct sir_peer_info_ext_resp *param,
void *pcontext);
void *pget_peer_info_ext_cb_context;
sme_get_isolation_cb get_isolation_cb;
void *get_isolation_cb_context;
#ifdef FEATURE_WLAN_EXTSCAN

View file

@ -2177,12 +2177,6 @@ QDF_STATUS sme_process_msg(struct mac_context *mac, struct scheduler_msg *pMsg)
status = sme_stats_ext_event(mac, pMsg->bodyptr);
qdf_mem_free(pMsg->bodyptr);
break;
case eWNI_SME_GET_PEER_INFO_EXT_IND:
if (mac->sme.pget_peer_info_ext_ind_cb)
mac->sme.pget_peer_info_ext_ind_cb(pMsg->bodyptr,
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;
@ -7842,56 +7836,6 @@ QDF_STATUS sme_get_link_speed(mac_handle_t mac_handle,
return status;
}
QDF_STATUS sme_get_peer_info_ext(mac_handle_t mac_handle,
struct sir_peer_info_ext_req *req,
void *context,
void (*callbackfn)(struct sir_peer_info_ext_resp *param,
void *pcontext))
{
QDF_STATUS status;
QDF_STATUS qdf_status;
struct mac_context *mac = MAC_CONTEXT(mac_handle);
struct scheduler_msg message = {0};
status = sme_acquire_global_lock(&mac->sme);
if (QDF_STATUS_SUCCESS == status) {
if (!callbackfn) {
QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
"%s: Indication Call back is NULL",
__func__);
sme_release_global_lock(&mac->sme);
return QDF_STATUS_E_FAILURE;
}
mac->sme.pget_peer_info_ext_ind_cb = callbackfn;
mac->sme.pget_peer_info_ext_cb_context = context;
/* serialize the req through MC thread */
message.bodyptr =
qdf_mem_malloc(sizeof(struct sir_peer_info_ext_req));
if (!message.bodyptr) {
sme_release_global_lock(&mac->sme);
return QDF_STATUS_E_NOMEM;
}
qdf_mem_copy(message.bodyptr,
req,
sizeof(struct sir_peer_info_ext_req));
message.type = WMA_GET_PEER_INFO_EXT;
qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
QDF_MODULE_ID_WMA,
QDF_MODULE_ID_WMA,
&message);
if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
"%s: Post get rssi msg fail", __func__);
qdf_mem_free(message.bodyptr);
status = QDF_STATUS_E_FAILURE;
}
sme_release_global_lock(&mac->sme);
}
return status;
}
QDF_STATUS sme_get_isolation(mac_handle_t mac_handle, void *context,
sme_get_isolation_cb callbackfn)
{

View file

@ -1246,18 +1246,6 @@ QDF_STATUS wma_sar_register_event_handlers(WMA_HANDLE handle);
void wma_process_link_status_req(tp_wma_handle wma,
tAniGetLinkStatus *pGetLinkStatus);
/**
* wma_get_peer_info_ext() - get peer info
* @handle: wma interface
* @peer_info_req: get peer info request information
*
* This function will send WMI_REQUEST_PEER_STATS_INFO_CMDID to FW
*
* Return: 0 on success, otherwise error value
*/
QDF_STATUS wma_get_peer_info_ext(WMA_HANDLE handle,
struct sir_peer_info_ext_req *peer_info_req);
/**
* wma_get_isolation() - get antenna isolation
* @handle: wma interface
@ -1268,19 +1256,6 @@ QDF_STATUS wma_get_peer_info_ext(WMA_HANDLE handle,
*/
QDF_STATUS wma_get_isolation(tp_wma_handle wma);
/**
* wma_peer_info_event_handler() - Handler for WMI_PEER_STATS_INFO_EVENTID
* @handle: WMA global handle
* @cmd_param_info: Command event data
* @len: Length of cmd_param_info
*
* This function will handle WMI_PEER_STATS_INFO_EVENTID
*
* Return: 0 on success, error code otherwise
*/
int wma_peer_info_event_handler(void *handle, u_int8_t *cmd_param_info,
u_int32_t len);
int wma_profile_data_report_event_handler(void *handle, uint8_t *event_buf,
uint32_t len);

View file

@ -308,8 +308,6 @@
#define WMA_DISASSOC_TX_COMP SIR_HAL_DISASSOC_TX_COMP
#define WMA_DEAUTH_TX_COMP SIR_HAL_DEAUTH_TX_COMP
#define WMA_GET_PEER_INFO_EXT SIR_HAL_GET_PEER_INFO_EXT
#define WMA_GET_ISOLATION SIR_HAL_GET_ISOLATION
#define WMA_MODEM_POWER_STATE_IND SIR_HAL_MODEM_POWER_STATE_IND

View file

@ -723,60 +723,6 @@ QDF_STATUS wma_get_link_speed(WMA_HANDLE handle,
return QDF_STATUS_SUCCESS;
}
QDF_STATUS wma_get_peer_info_ext(WMA_HANDLE handle,
struct sir_peer_info_ext_req *peer_info_req)
{
tp_wma_handle wma_handle = (tp_wma_handle)handle;
wmi_request_peer_stats_info_cmd_fixed_param *cmd;
wmi_buf_t wmi_buf;
uint32_t len;
uint8_t *buf_ptr;
if (!wma_handle || !wma_handle->wmi_handle) {
wma_err("WMA is closed, can not issue get rssi");
return QDF_STATUS_E_INVAL;
}
wma_debug("send WMI_REQUEST_PEER_STATS_INFO_CMDID");
len = sizeof(wmi_request_peer_stats_info_cmd_fixed_param);
wmi_buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
if (!wmi_buf)
return QDF_STATUS_E_NOMEM;
buf_ptr = (uint8_t *)wmi_buf_data(wmi_buf);
cmd = (wmi_request_peer_stats_info_cmd_fixed_param *)buf_ptr;
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_request_peer_stats_info_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN(
wmi_request_peer_stats_info_cmd_fixed_param));
cmd->vdev_id = peer_info_req->sessionid;
cmd->request_type = WMI_REQUEST_ONE_PEER_STATS_INFO;
wma_handle->get_one_peer_info = true;
WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_info_req->peer_macaddr.bytes,
&cmd->peer_macaddr);
cmd->reset_after_request = peer_info_req->reset_after_request;
if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmi_buf, len,
WMI_REQUEST_PEER_STATS_INFO_CMDID)) {
wmi_buf_free(wmi_buf);
return QDF_STATUS_E_FAILURE;
}
wma_info("vdev_id %d, mac %pM, req_type %x, reset %x",
cmd->vdev_id,
peer_info_req->peer_macaddr.bytes,
cmd->request_type,
cmd->reset_after_request);
qdf_mem_copy(&(wma_handle->peer_macaddr),
&(peer_info_req->peer_macaddr),
QDF_MAC_ADDR_SIZE);
return QDF_STATUS_SUCCESS;
}
QDF_STATUS wma_get_isolation(tp_wma_handle wma)
{
wmi_coex_get_antenna_isolation_cmd_fixed_param *cmd;

View file

@ -3098,12 +3098,6 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc,
/* 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,
wma_peer_info_event_handler,
WMA_RX_SERIALIZER_CTX);
#ifdef WLAN_POWER_DEBUG
/* register for Chip Power stats event */
wmi_unified_register_event_handler(wma_handle->wmi_handle,
@ -8569,10 +8563,6 @@ static QDF_STATUS wma_mc_process_msg(struct scheduler_msg *msg)
(tDisableIntraBssFwd *) msg->bodyptr);
qdf_mem_free(msg->bodyptr);
break;
case WMA_GET_PEER_INFO_EXT:
wma_get_peer_info_ext(wma_handle, msg->bodyptr);
qdf_mem_free(msg->bodyptr);
break;
case WMA_GET_ISOLATION:
wma_get_isolation(wma_handle);
break;

View file

@ -2937,224 +2937,6 @@ int wma_rso_cmd_status_event_handler(wmi_roam_event_fixed_param *wmi_event)
return 0;
}
/**
* wma_fill_peer_info() - fill SIR peer info from WMI peer info struct
* @wma: wma interface
* @stats_info: WMI peer info pointer
* @peer_info: SIR peer info pointer
*
* This function will fill SIR peer info from WMI peer info struct
*
* Return: None
*/
static void wma_fill_peer_info(tp_wma_handle wma,
wmi_peer_stats_info *stats_info,
struct sir_peer_info_ext *peer_info)
{
int i;
peer_info->tx_packets = stats_info->tx_packets.low_32;
peer_info->tx_bytes = stats_info->tx_bytes.high_32;
peer_info->tx_bytes <<= 32;
peer_info->tx_bytes += stats_info->tx_bytes.low_32;
peer_info->rx_packets = stats_info->rx_packets.low_32;
peer_info->rx_bytes = stats_info->rx_bytes.high_32;
peer_info->rx_bytes <<= 32;
peer_info->rx_bytes += stats_info->rx_bytes.low_32;
peer_info->tx_retries = stats_info->tx_retries;
peer_info->tx_failed = stats_info->tx_failed;
peer_info->tx_succeed = stats_info->tx_succeed;
peer_info->rssi = stats_info->peer_rssi;
peer_info->tx_rate = stats_info->last_tx_bitrate_kbps;
peer_info->tx_rate_code = stats_info->last_tx_rate_code;
peer_info->rx_rate = stats_info->last_rx_bitrate_kbps;
peer_info->rx_rate_code = stats_info->last_rx_rate_code;
for (i = 0; i < WMI_MAX_CHAINS; i++)
peer_info->peer_rssi_per_chain[i] =
stats_info->peer_rssi_per_chain[i];
}
/**
* wma_peer_info_ext_rsp() - process peer ext info ext
* @handle: wma interface
* @buf: wmi event buf pointer
*
* This function will send eWNI_SME_GET_PEER_INFO_EXT_IND to SME
*
* Return: 0 on success, error code otherwise
*/
static QDF_STATUS wma_peer_info_ext_rsp(tp_wma_handle wma, u_int8_t *buf)
{
wmi_peer_stats_info_event_fixed_param *event;
wmi_peer_stats_info *stats_info;
struct sir_peer_info_ext_resp *resp;
struct sir_peer_info_ext *peer_info;
struct scheduler_msg sme_msg = {0};
int i, j = 0;
QDF_STATUS qdf_status;
event = (wmi_peer_stats_info_event_fixed_param *)buf;
stats_info = (wmi_peer_stats_info *)(buf +
sizeof(wmi_peer_stats_info_event_fixed_param));
if (wma->get_one_peer_info) {
resp = qdf_mem_malloc(sizeof(struct sir_peer_info_ext_resp) +
sizeof(resp->info[0]));
if (!resp)
return QDF_STATUS_E_NOMEM;
resp->count = 0;
peer_info = &resp->info[0];
for (i = 0; i < event->num_peers; i++) {
WMI_MAC_ADDR_TO_CHAR_ARRAY(&stats_info->peer_macaddr,
peer_info->peer_macaddr.bytes);
if (!qdf_mem_cmp(peer_info->peer_macaddr.bytes,
wma->peer_macaddr.bytes,
QDF_MAC_ADDR_SIZE)) {
wma_fill_peer_info(wma, stats_info, peer_info);
resp->count++;
break;
}
stats_info = stats_info + 1;
}
} else {
resp = qdf_mem_malloc(sizeof(struct sir_peer_info_ext_resp) +
event->num_peers * sizeof(resp->info[0]));
if (!resp)
return QDF_STATUS_E_NOMEM;
resp->count = event->num_peers;
for (i = 0; i < event->num_peers; i++) {
peer_info = &resp->info[j];
WMI_MAC_ADDR_TO_CHAR_ARRAY(&stats_info->peer_macaddr,
peer_info->peer_macaddr.bytes);
if (!qdf_mem_cmp(peer_info->peer_macaddr.bytes,
wma->myaddr, QDF_MAC_ADDR_SIZE)) {
resp->count = resp->count - 1;
} else {
wma_fill_peer_info(wma, stats_info, peer_info);
j++;
}
stats_info = stats_info + 1;
}
}
sme_msg.type = eWNI_SME_GET_PEER_INFO_EXT_IND;
sme_msg.bodyptr = resp;
sme_msg.bodyval = 0;
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_err("Fail to post get peer info msg");
qdf_mem_free(resp);
}
return qdf_status;
}
/**
* dump_peer_stats_info() - dump wmi peer info struct
* @event: wmi peer info fixed param pointer
* @peer_stats: wmi peer stats info pointer
*
* This function will dump wmi peer info struct
*
* Return: None
*/
static void dump_peer_stats_info(wmi_peer_stats_info_event_fixed_param *event,
wmi_peer_stats_info *peer_stats)
{
int i, j;
wmi_peer_stats_info *stats = peer_stats;
u_int8_t mac[6];
wma_debug("vdev_id %d, num_peers %d more_data %d",
event->vdev_id,
event->num_peers, event->more_data);
for (i = 0; i < event->num_peers; i++) {
WMI_MAC_ADDR_TO_CHAR_ARRAY(&stats->peer_macaddr, mac);
wma_nofl_debug("mac %pM", mac);
wma_nofl_debug("tx_bytes %d %d tx_packets %d %d",
stats->tx_bytes.low_32,
stats->tx_bytes.high_32,
stats->tx_packets.low_32,
stats->tx_packets.high_32);
wma_nofl_debug("rx_bytes %d %d rx_packets %d %d",
stats->rx_bytes.low_32,
stats->rx_bytes.high_32,
stats->rx_packets.low_32,
stats->rx_packets.high_32);
wma_nofl_debug("tx_retries %d tx_failed %d",
stats->tx_retries, stats->tx_failed);
wma_nofl_debug("tx_rate_code %x rx_rate_code %x",
stats->last_tx_rate_code,
stats->last_rx_rate_code);
wma_nofl_debug("tx_rate %x rx_rate %x",
stats->last_tx_bitrate_kbps,
stats->last_rx_bitrate_kbps);
wma_nofl_debug("peer_rssi %d", stats->peer_rssi);
wma_nofl_debug("tx_succeed %d", stats->tx_succeed);
for (j = 0; j < WMI_MAX_CHAINS; j++)
wma_nofl_debug("chain%d_rssi %d", j,
stats->peer_rssi_per_chain[j]);
stats++;
}
}
int wma_peer_info_event_handler(void *handle, u_int8_t *cmd_param_info,
u_int32_t len)
{
tp_wma_handle wma = (tp_wma_handle) handle;
WMI_PEER_STATS_INFO_EVENTID_param_tlvs *param_buf;
wmi_peer_stats_info_event_fixed_param *event;
u_int32_t buf_size;
u_int8_t *buf;
param_buf =
(WMI_PEER_STATS_INFO_EVENTID_param_tlvs *)cmd_param_info;
if (!param_buf) {
wma_err("Invalid stats event");
return -EINVAL;
}
wma_debug("Recv WMI_PEER_STATS_INFO_EVENTID");
event = param_buf->fixed_param;
if (event->num_peers >
((WMI_SVC_MSG_MAX_SIZE -
sizeof(wmi_peer_stats_info_event_fixed_param))/
sizeof(wmi_peer_stats_info)) || event->num_peers >
param_buf->num_peer_stats_info) {
wma_err("Excess num of peers from fw: %d, num_peer_stats_info:%d",
event->num_peers, param_buf->num_peer_stats_info);
return -EINVAL;
}
buf_size = sizeof(wmi_peer_stats_info_event_fixed_param) +
sizeof(wmi_peer_stats_info) * event->num_peers;
buf = qdf_mem_malloc(buf_size);
if (!buf)
return -ENOMEM;
qdf_mem_copy(buf, param_buf->fixed_param,
sizeof(wmi_peer_stats_info_event_fixed_param));
qdf_mem_copy((buf + sizeof(wmi_peer_stats_info_event_fixed_param)),
param_buf->peer_stats_info,
sizeof(wmi_peer_stats_info) * event->num_peers);
wma_debug("dump peer stats info");
dump_peer_stats_info(event, param_buf->peer_stats_info);
wma_peer_info_ext_rsp(wma, buf);
qdf_mem_free(buf);
return 0;
}
/**
* wma_send_link_speed() - send link speed to SME
* @link_speed: link speed

View file

@ -72,6 +72,7 @@ static void wlan_cfg80211_mc_cp_stats_dealloc(void *priv)
qdf_mem_free(stats->vdev_summary_stats);
qdf_mem_free(stats->vdev_chain_rssi);
qdf_mem_free(stats->peer_adv_stats);
qdf_mem_free(stats->peer_stats_info_ext);
wlan_free_mib_stats(stats);
}
@ -718,6 +719,127 @@ get_mib_stats_fail:
}
#endif
/**
* get_peer_stats_cb() - get_peer_stats_cb callback function
* @ev: peer stats buffer
* @cookie: a cookie for the request context
*
* Return: None
*/
static void get_peer_stats_cb(struct stats_event *ev, void *cookie)
{
struct stats_event *priv;
struct osif_request *request;
uint32_t peer_stats_info_size;
request = osif_request_get(cookie);
if (!request) {
osif_err("Obsolete request");
return;
}
priv = osif_request_priv(request);
peer_stats_info_size = sizeof(*ev->peer_stats_info_ext) *
ev->num_peer_stats_info_ext;
if (priv->peer_stats_info_ext) {
osif_err("invalid context cookie %pK request %pK",
cookie, request);
goto peer_stats_cb_fail;
}
priv->peer_stats_info_ext = qdf_mem_malloc(peer_stats_info_size);
if (!priv->peer_stats_info_ext)
goto peer_stats_cb_fail;
qdf_mem_copy(priv->peer_stats_info_ext, ev->peer_stats_info_ext,
peer_stats_info_size);
peer_stats_cb_fail:
osif_request_complete(request);
osif_request_put(request);
}
struct stats_event *
wlan_cfg80211_mc_cp_stats_get_peer_stats(struct wlan_objmgr_vdev *vdev,
const uint8_t *mac_addr,
int *errno)
{
void *cookie;
QDF_STATUS status;
struct stats_event *priv, *out;
struct osif_request *request;
struct request_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_cp_stats_dealloc,
};
osif_debug("Enter");
out = qdf_mem_malloc(sizeof(*out));
if (!out) {
*errno = -ENOMEM;
return NULL;
}
request = osif_request_alloc(&params);
if (!request) {
qdf_mem_free(out);
*errno = -ENOMEM;
return NULL;
}
cookie = osif_request_cookie(request);
priv = osif_request_priv(request);
info.cookie = cookie;
info.u.get_peer_stats_cb = get_peer_stats_cb;
info.vdev_id = wlan_vdev_get_id(vdev);
info.pdev_id = wlan_objmgr_pdev_get_pdev_id(wlan_vdev_get_pdev(vdev));
qdf_mem_copy(info.peer_mac_addr, mac_addr, QDF_MAC_ADDR_SIZE);
status = ucfg_mc_cp_stats_send_stats_request(vdev,
TYPE_PEER_STATS_INFO_EXT,
&info);
if (QDF_IS_STATUS_ERROR(status)) {
osif_err("Failed to send stats request status: %d", status);
*errno = qdf_status_to_os_return(status);
goto get_peer_stats_fail;
}
*errno = osif_request_wait_for_response(request);
if (*errno) {
osif_err("wait failed or timed out ret: %d", *errno);
goto get_peer_stats_fail;
}
if (!priv->peer_stats_info_ext || priv->num_peer_stats_info_ext == 0) {
osif_err("Invalid stats");
osif_err("Peer stats info ext %d:%pK",
priv->num_peer_stats_info_ext,
priv->peer_stats_info_ext);
*errno = -EINVAL;
goto get_peer_stats_fail;
}
out->num_peer_stats_info_ext = priv->num_peer_stats_info_ext;
out->peer_stats_info_ext = priv->peer_stats_info_ext;
priv->peer_stats_info_ext = NULL;
osif_request_put(request);
osif_debug("Exit");
return out;
get_peer_stats_fail:
osif_request_put(request);
wlan_cfg80211_mc_cp_stats_free_stats_event(out);
osif_debug("Exit");
return NULL;
}
void wlan_cfg80211_mc_cp_stats_free_stats_event(struct stats_event *stats)
{
if (!stats)
@ -730,5 +852,6 @@ void wlan_cfg80211_mc_cp_stats_free_stats_event(struct stats_event *stats)
qdf_mem_free(stats->vdev_chain_rssi);
qdf_mem_free(stats->peer_adv_stats);
wlan_free_mib_stats(stats);
qdf_mem_free(stats->peer_stats_info_ext);
qdf_mem_free(stats);
}