qcacld-3.0: Add support to read link layer stats via debugfs
Add support to read link layer stats via debugfs. This change set will issue get_req and store the received stats response is debugfs entry. Change-Id: If3af9f0a37283583ff011e35c7275a329a6e175d CRs-Fixed: 2018087
This commit is contained in:

committed by
snandini

parent
7bff29b84a
commit
c7e2bb7c83
1
Kbuild
1
Kbuild
@@ -415,6 +415,7 @@ HDD_OBJS := $(HDD_SRC_DIR)/wlan_hdd_assoc.o \
|
||||
|
||||
ifeq ($(CONFIG_WLAN_DEBUGFS), y)
|
||||
HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs.o
|
||||
HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs_llstat.o
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_WLAN_FEATURE_DSRC), y)
|
||||
|
116
core/hdd/inc/wlan_hdd_debugfs_llstat.h
Normal file
116
core/hdd/inc/wlan_hdd_debugfs_llstat.h
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file was originally distributed by Qualcomm Atheros, Inc.
|
||||
* under proprietary terms before Copyright ownership was assigned
|
||||
* to the Linux Foundation.
|
||||
*/
|
||||
|
||||
/**
|
||||
* DOC: wlan_hdd_debugfs_llstat.h
|
||||
*
|
||||
* WLAN Host Device Driver implementation to update
|
||||
* debugfs with Link Layer statistics
|
||||
*/
|
||||
|
||||
#ifndef _WLAN_HDD_DEBUGFS_LLSTAT_H
|
||||
#define _WLAN_HDD_DEBUGFS_LLSTAT_H
|
||||
|
||||
#define DEBUGFS_LLSTATS_BUF_SIZE 10240
|
||||
#define DEBUGFS_LLSTATS_REQID 4294967295
|
||||
#define DEBUGFS_LLSTATS_REQMASK 0x7
|
||||
|
||||
#include <wlan_hdd_main.h>
|
||||
|
||||
#if defined(WLAN_FEATURE_LINK_LAYER_STATS) && defined(WLAN_DEBUGFS)
|
||||
/**
|
||||
* hdd_debugfs_process_peer_stats() - Parse Peer stats and add it to buffer
|
||||
* @adapter: Pointer to device adapter
|
||||
* @data: Pointer to stats data
|
||||
*
|
||||
* Receiving Link Layer peer statistics from FW. This function stores the
|
||||
* firmware data in a buffer to be written into debugfs.
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void hdd_debugfs_process_peer_stats(struct hdd_adapter_s *adapter, void *data);
|
||||
|
||||
/**
|
||||
* hdd_debugfs_process_radio_stats() - Parse Radio stats and add it to buffer
|
||||
* @adapter: Pointer to device adapter
|
||||
* @more_data: More data
|
||||
* @data: Pointer to stats data
|
||||
* @num_radio: Number of radios
|
||||
*
|
||||
* Receiving Link Layer Radio statistics from FW. This function stores the
|
||||
* firmware data in a buffer to be written into debugfs.
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void hdd_debugfs_process_radio_stats(struct hdd_adapter_s *adapter,
|
||||
uint32_t more_data, void *data, uint32_t num_radio);
|
||||
|
||||
/**
|
||||
* hdd_link_layer_process_iface_stats() - This function is called after
|
||||
* @adapter: Pointer to device adapter
|
||||
* @data: Pointer to stats data
|
||||
* @num_peers: Number of peers
|
||||
*
|
||||
* Receiving Link Layer Interface statistics from FW.This function converts
|
||||
* the firmware data to the NL data and sends the same to the kernel/upper
|
||||
* layers.
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void hdd_debugfs_process_iface_stats(struct hdd_adapter_s *adapter,
|
||||
void *data, uint32_t num_peers);
|
||||
|
||||
/**
|
||||
* wlan_hdd_create_ll_stats_file() - API to create Link Layer stats file
|
||||
* @adapter: interface adapter pointer
|
||||
*
|
||||
* Return: 0 on success and errno on failure
|
||||
*/
|
||||
int wlan_hdd_create_ll_stats_file(struct hdd_adapter_s *adapter);
|
||||
#else
|
||||
static inline void hdd_debugfs_process_peer_stats(struct hdd_adapter_s *adapter,
|
||||
void *data)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void hdd_debugfs_process_radio_stats(
|
||||
struct hdd_adapter_s *adapter,
|
||||
uint32_t more_data, void *data, uint32_t num_radio)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void hdd_debugfs_process_iface_stats(
|
||||
struct hdd_adapter_s *adapter,
|
||||
void *data, uint32_t num_peers)
|
||||
{
|
||||
}
|
||||
static inline int wlan_hdd_create_ll_stats_file(struct hdd_adapter_s *adapter)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif /* #ifndef _WLAN_HDD_DEBUGFS_LLSTAT_H */
|
@@ -40,6 +40,7 @@
|
||||
#include <wlan_hdd_request_manager.h>
|
||||
#include <wlan_hdd_wowl.h>
|
||||
#include <cds_sched.h>
|
||||
#include <wlan_hdd_debugfs_llstat.h>
|
||||
|
||||
#define MAX_USER_COMMAND_SIZE_WOWL_ENABLE 8
|
||||
#define MAX_USER_COMMAND_SIZE_WOWL_PATTERN 512
|
||||
@@ -867,6 +868,9 @@ QDF_STATUS hdd_debugfs_init(hdd_adapter_t *adapter)
|
||||
if (QDF_STATUS_SUCCESS != wlan_hdd_create_power_stats_file(adapter))
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
if (0 != wlan_hdd_create_ll_stats_file(adapter))
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
526
core/hdd/src/wlan_hdd_debugfs_llstat.c
Normal file
526
core/hdd/src/wlan_hdd_debugfs_llstat.c
Normal file
@@ -0,0 +1,526 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
|
||||
*
|
||||
*
|
||||
* 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_debugfs_llstat.c
|
||||
*
|
||||
* WLAN Host Device Driver implementation to update
|
||||
* debugfs with Link Layer statistics
|
||||
*/
|
||||
|
||||
#include <wlan_hdd_debugfs_llstat.h>
|
||||
#include <cds_sched.h>
|
||||
#include <wlan_hdd_stats.h>
|
||||
#include <wma_api.h>
|
||||
|
||||
struct ll_stats_buf {
|
||||
ssize_t len;
|
||||
uint8_t *result;
|
||||
};
|
||||
|
||||
static struct ll_stats_buf ll_stats;
|
||||
|
||||
void hdd_debugfs_process_iface_stats(hdd_adapter_t *adapter,
|
||||
void *data, uint32_t num_peers)
|
||||
{
|
||||
tpSirWifiIfaceStat iface_stat;
|
||||
tpSirWifiInterfaceInfo iface_info;
|
||||
tpSirWifiWmmAcStat ac_stat;
|
||||
struct wifi_iface_offload_stat *offload_stat;
|
||||
uint64_t average_tsf_offset;
|
||||
int i;
|
||||
ssize_t len = 0;
|
||||
uint8_t *buffer;
|
||||
|
||||
ENTER();
|
||||
iface_stat = data;
|
||||
|
||||
buffer = ll_stats.result;
|
||||
buffer += ll_stats.len;
|
||||
len = scnprintf(buffer, DEBUGFS_LLSTATS_BUF_SIZE - ll_stats.len,
|
||||
"\n\n===LL_STATS_IFACE: num_peers: %d===", num_peers);
|
||||
|
||||
if (false == hdd_get_interface_info(adapter, &iface_stat->info)) {
|
||||
hdd_err("hdd_get_interface_info get fail");
|
||||
return;
|
||||
}
|
||||
|
||||
iface_info = &iface_stat->info;
|
||||
buffer += len;
|
||||
ll_stats.len += len;
|
||||
len = scnprintf(buffer, DEBUGFS_LLSTATS_BUF_SIZE - ll_stats.len,
|
||||
"\nmode: %u, MAC_ADDR: %pM, state: %u, roaming: %u, capabilities: %u, SSID: %s, BSSID_MAC: %pM, ap_country_str: %s, country_str: %s",
|
||||
iface_info->mode, &iface_info->macAddr.bytes[0],
|
||||
iface_info->state, iface_info->roaming,
|
||||
iface_info->capabilities, iface_info->ssid,
|
||||
&iface_info->bssid.bytes[0], iface_info->apCountryStr,
|
||||
iface_info->countryStr);
|
||||
|
||||
average_tsf_offset = iface_stat->avg_bcn_spread_offset_high;
|
||||
average_tsf_offset = (average_tsf_offset << 32) |
|
||||
iface_stat->avg_bcn_spread_offset_low;
|
||||
|
||||
buffer += len;
|
||||
ll_stats.len += len;
|
||||
len = scnprintf(buffer, DEBUGFS_LLSTATS_BUF_SIZE - ll_stats.len,
|
||||
"\nbeacon_rx: %u, mgmt_rx: %u, mgmt_action_rx: %u, mgmt_action_tx: %u, rssi_mgmt: %u, rssi_data: %u, rssi_ack: %u, is_leaky_ap: %u, avg_rx_frms_leaked: %u, rx_leak_window: %u, average_tsf_offset: %llu, Tx RTS success count: %u, Tx RTS fail count: %u, Tx ppdu success count: %u, Tx ppdu fail count: %u, Connected duration: %u, Disconnected duration: %u, RTT ranging duration: %u, RTT responder duration: %u, Num tx probes: %u, Num beacon miss: %u,\n\nNumber of AC: %d",
|
||||
iface_stat->beaconRx, iface_stat->mgmtRx,
|
||||
iface_stat->mgmtActionRx, iface_stat->mgmtActionTx,
|
||||
iface_stat->rssiMgmt, iface_stat->rssiData,
|
||||
iface_stat->rssiAck, iface_stat->is_leaky_ap,
|
||||
iface_stat->avg_rx_frms_leaked,
|
||||
iface_stat->rx_leak_window, average_tsf_offset,
|
||||
iface_stat->tx_rts_succ_cnt,
|
||||
iface_stat->tx_rts_fail_cnt,
|
||||
iface_stat->tx_ppdu_succ_cnt,
|
||||
iface_stat->tx_ppdu_fail_cnt,
|
||||
iface_stat->connected_duration,
|
||||
iface_stat->disconnected_duration,
|
||||
iface_stat->rtt_ranging_duration,
|
||||
iface_stat->rtt_responder_duration,
|
||||
iface_stat->num_probes_tx, iface_stat->num_beacon_miss,
|
||||
iface_stat->num_ac);
|
||||
|
||||
for (i = 0; i < iface_stat->num_ac; i++) {
|
||||
ac_stat = &iface_stat->AccessclassStats[i];
|
||||
buffer += len;
|
||||
ll_stats.len += len;
|
||||
len = scnprintf(buffer,
|
||||
DEBUGFS_LLSTATS_BUF_SIZE - ll_stats.len,
|
||||
"\nAC: %d, tx_mpdu: %u, rx_mpdu: %u, tx_mcast: %u, rx_mcast: %u, rx_ampdu: %u tx_ampdu: %u, mpdu_lost: %u, retries: %u, retries_short: %u, retries_long: %u, contention_time: min-%u max-%u avg-%u, contention num samples: %u",
|
||||
ac_stat->ac, ac_stat->txMpdu, ac_stat->rxMpdu,
|
||||
ac_stat->txMcast, ac_stat->rxMcast,
|
||||
ac_stat->rxAmpdu, ac_stat->txAmpdu,
|
||||
ac_stat->mpduLost, ac_stat->retries,
|
||||
ac_stat->retriesShort, ac_stat->retriesLong,
|
||||
ac_stat->contentionTimeMin,
|
||||
ac_stat->contentionTimeMax,
|
||||
ac_stat->contentionTimeAvg,
|
||||
ac_stat->contentionNumSamples);
|
||||
}
|
||||
|
||||
buffer += len;
|
||||
ll_stats.len += len;
|
||||
len = scnprintf(buffer, DEBUGFS_LLSTATS_BUF_SIZE - ll_stats.len,
|
||||
"\n\nNumber of offload stats: %d",
|
||||
iface_stat->num_offload_stats);
|
||||
|
||||
for (i = 0; i < iface_stat->num_offload_stats; i++) {
|
||||
offload_stat = &iface_stat->offload_stat[i];
|
||||
buffer += len;
|
||||
ll_stats.len += len;
|
||||
len = scnprintf(buffer,
|
||||
DEBUGFS_LLSTATS_BUF_SIZE - ll_stats.len,
|
||||
"\ntype: %d, rx_count: %u, drp_count: %u, fwd_count: %u",
|
||||
offload_stat->type, offload_stat->rx_count,
|
||||
offload_stat->drp_count,
|
||||
offload_stat->fwd_count);
|
||||
}
|
||||
|
||||
ll_stats.len += len;
|
||||
EXIT();
|
||||
}
|
||||
|
||||
void hdd_debugfs_process_peer_stats(hdd_adapter_t *adapter, void *data)
|
||||
{
|
||||
tpSirWifiPeerStat peer_stat;
|
||||
tpSirWifiPeerInfo peer_info;
|
||||
tpSirWifiRateStat rate_stat;
|
||||
int i, j, num_rate;
|
||||
ssize_t len = 0;
|
||||
uint8_t *buffer;
|
||||
|
||||
ENTER();
|
||||
|
||||
if (!ll_stats.result) {
|
||||
hdd_err("LL statistics buffer is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
peer_stat = (tpSirWifiPeerStat) data;
|
||||
|
||||
buffer = ll_stats.result;
|
||||
buffer += ll_stats.len;
|
||||
len = scnprintf(buffer, DEBUGFS_LLSTATS_BUF_SIZE - ll_stats.len,
|
||||
"\n\n===LL_STATS_PEER_ALL : num_peers %u===",
|
||||
peer_stat->numPeers);
|
||||
|
||||
peer_info = (tpSirWifiPeerInfo) ((uint8_t *) peer_stat->peerInfo);
|
||||
for (i = 1; i <= peer_stat->numPeers; i++) {
|
||||
buffer += len;
|
||||
ll_stats.len += len;
|
||||
len = scnprintf(buffer,
|
||||
DEBUGFS_LLSTATS_BUF_SIZE - ll_stats.len,
|
||||
"\nType: %d, peer_mac: %pM, capabilities: %u\nnum_rates: %d",
|
||||
wmi_to_sir_peer_type(peer_info->type),
|
||||
&peer_info->peerMacAddress.bytes[0],
|
||||
peer_info->capabilities, peer_info->numRate);
|
||||
|
||||
num_rate = peer_info->numRate;
|
||||
for (j = 0; j < num_rate; j++) {
|
||||
rate_stat = (tpSirWifiRateStat) ((uint8_t *)
|
||||
peer_info->rateStats + (j *
|
||||
sizeof(tSirWifiRateStat)));
|
||||
buffer += len;
|
||||
ll_stats.len += len;
|
||||
len = scnprintf(buffer,
|
||||
DEBUGFS_LLSTATS_BUF_SIZE - ll_stats.len,
|
||||
"\npreamble: %0x, nss: %0x, bw: %0x, mcs: %0x, bitrate: %0x, txmpdu: %u, rxmpdu: %u, mpdu_lost: %u, retries: %u, retries_short: %u, retries_long: %u",
|
||||
rate_stat->rate.preamble, rate_stat->rate.nss,
|
||||
rate_stat->rate.bw, rate_stat->rate.rateMcsIdx,
|
||||
rate_stat->rate.bitrate, rate_stat->txMpdu,
|
||||
rate_stat->rxMpdu, rate_stat->mpduLost,
|
||||
rate_stat->retries, rate_stat->retriesShort,
|
||||
rate_stat->retriesLong);
|
||||
}
|
||||
peer_info = (tpSirWifiPeerInfo) ((uint8_t *)
|
||||
peer_stat->peerInfo + (i *
|
||||
sizeof(tSirWifiPeerInfo)) +
|
||||
(num_rate * sizeof(tSirWifiRateStat)));
|
||||
}
|
||||
ll_stats.len += len;
|
||||
EXIT();
|
||||
|
||||
}
|
||||
|
||||
void hdd_debugfs_process_radio_stats(hdd_adapter_t *adapter,
|
||||
uint32_t more_data, void *data, uint32_t num_radio)
|
||||
{
|
||||
int i, j;
|
||||
ssize_t len = 0;
|
||||
uint8_t *buffer;
|
||||
tSirWifiRadioStat *radio_stat = (tpSirWifiRadioStat) data;
|
||||
tSirWifiChannelStats *chan_stat;
|
||||
|
||||
ENTER();
|
||||
|
||||
if (!ll_stats.result) {
|
||||
hdd_err("LL statistics buffer is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
buffer = ll_stats.result;
|
||||
buffer += ll_stats.len;
|
||||
len = scnprintf(buffer, DEBUGFS_LLSTATS_BUF_SIZE,
|
||||
"\n\n===LL_STATS_RADIO: number of radios: %u===",
|
||||
num_radio);
|
||||
|
||||
for (i = 0; i < num_radio; i++) {
|
||||
buffer += len;
|
||||
ll_stats.len += len;
|
||||
len = scnprintf(buffer,
|
||||
DEBUGFS_LLSTATS_BUF_SIZE - ll_stats.len,
|
||||
"\nRadio: %u on_time: %u, tx_time: %u, rx_time: %u, on_time_scan: %u, on_time_nbd: %u, on_time_gscan: %u, on_time_roam_scan: %u, on_time_pno_scan: %u on_time_hs20: %u, on_time_host_scan: %u, on_time_lpi_scan: %u\ntotal_num_tx_pwr_levels: %u\n",
|
||||
radio_stat->radio, radio_stat->onTime,
|
||||
radio_stat->txTime, radio_stat->rxTime,
|
||||
radio_stat->onTimeScan, radio_stat->onTimeNbd,
|
||||
radio_stat->onTimeGscan,
|
||||
radio_stat->onTimeRoamScan,
|
||||
radio_stat->onTimePnoScan,
|
||||
radio_stat->onTimeHs20,
|
||||
radio_stat->on_time_host_scan,
|
||||
radio_stat->on_time_lpi_scan,
|
||||
radio_stat->total_num_tx_power_levels);
|
||||
|
||||
for (j = 0; j < radio_stat->total_num_tx_power_levels; j++) {
|
||||
buffer += len;
|
||||
ll_stats.len += len;
|
||||
len = scnprintf(buffer,
|
||||
DEBUGFS_LLSTATS_BUF_SIZE - ll_stats.len,
|
||||
"%d ", radio_stat->tx_time_per_power_level[j]);
|
||||
}
|
||||
|
||||
buffer += len;
|
||||
ll_stats.len += len;
|
||||
len = scnprintf(buffer,
|
||||
DEBUGFS_LLSTATS_BUF_SIZE - ll_stats.len,
|
||||
"\nNum channels: %d", radio_stat->numChannels);
|
||||
|
||||
for (j = 0; j < radio_stat->numChannels; j++) {
|
||||
chan_stat = (tSirWifiChannelStats *)
|
||||
((uint8_t *)radio_stat->channels +
|
||||
(j * sizeof(tSirWifiChannelStats)));
|
||||
|
||||
buffer += len;
|
||||
ll_stats.len += len;
|
||||
len = scnprintf(buffer,
|
||||
DEBUGFS_LLSTATS_BUF_SIZE - ll_stats.len,
|
||||
"\nChan width: %d, center_freq: %d, center_freq0: %d, center_freq1: %d, on_time: %d, cca_busy_time: %d",
|
||||
chan_stat->channel.width,
|
||||
chan_stat->channel.centerFreq,
|
||||
chan_stat->channel.centerFreq0,
|
||||
chan_stat->channel.centerFreq1,
|
||||
chan_stat->onTime, chan_stat->ccaBusyTime);
|
||||
}
|
||||
|
||||
radio_stat++;
|
||||
}
|
||||
ll_stats.len += len;
|
||||
EXIT();
|
||||
}
|
||||
|
||||
static inline void wlan_hdd_llstats_free_buf(void)
|
||||
{
|
||||
qdf_mem_free(ll_stats.result);
|
||||
ll_stats.result = NULL;
|
||||
ll_stats.len = 0;
|
||||
}
|
||||
|
||||
static int wlan_hdd_llstats_alloc_buf(void)
|
||||
{
|
||||
ll_stats.len = 0;
|
||||
|
||||
ll_stats.result = qdf_mem_malloc(DEBUGFS_LLSTATS_BUF_SIZE);
|
||||
if (!ll_stats.result) {
|
||||
hdd_err("LL Stats buffer allocation failed");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_debugfs_stats_update() - Update userspace with local statistics buffer
|
||||
* @buf: userspace buffer (to which data is being copied into)
|
||||
* @count: max data that can be copied into buf
|
||||
* @pos: offset (where data should be copied into)
|
||||
*
|
||||
* This function should copies link layer statistics buffer into debugfs
|
||||
* entry.
|
||||
*
|
||||
* Return: number of characters copied; 0 on no-copy
|
||||
*/
|
||||
static ssize_t hdd_debugfs_stats_update(char __user *buf, size_t count,
|
||||
loff_t *pos)
|
||||
{
|
||||
ssize_t ret_cnt;
|
||||
|
||||
ENTER();
|
||||
|
||||
if (!ll_stats.result) {
|
||||
hdd_err("Trying to read from NULL buffer");
|
||||
return 0;
|
||||
}
|
||||
|
||||
hdd_info("LL stats read req: count: %zu, pos: %lld", count, *pos);
|
||||
ret_cnt = simple_read_from_buffer(buf, count, pos,
|
||||
ll_stats.result, ll_stats.len);
|
||||
|
||||
EXIT();
|
||||
return ret_cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
* __wlan_hdd_read_ll_stats_debugfs() - API to collect LL stats from FW
|
||||
* @file: file pointer
|
||||
* @buf: buffer
|
||||
* @count: count
|
||||
* @pos: position pointer
|
||||
*
|
||||
* Return: Number of bytes read on success, error number otherwise
|
||||
*/
|
||||
static ssize_t __wlan_hdd_read_ll_stats_debugfs(struct file *file,
|
||||
char __user *buf, size_t count, loff_t *pos)
|
||||
{
|
||||
hdd_adapter_t *adapter;
|
||||
hdd_context_t *hdd_ctx;
|
||||
ssize_t ret = 0;
|
||||
|
||||
ENTER();
|
||||
|
||||
adapter = (hdd_adapter_t *)file->private_data;
|
||||
if ((!adapter) || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
|
||||
hdd_err("Invalid adapter or adapter has invalid magic");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
|
||||
ret = wlan_hdd_validate_context(hdd_ctx);
|
||||
if (0 != ret)
|
||||
return ret;
|
||||
|
||||
/* All the events are received and buffer is populated */
|
||||
ret = hdd_debugfs_stats_update(buf, count, pos);
|
||||
hdd_info("%zu characters written into debugfs", ret);
|
||||
|
||||
EXIT();
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_hdd_read_ll_stats_debugfs() - SSR wrapper function to read LL debugfs
|
||||
* @file: file pointer
|
||||
* @buf: buffer
|
||||
* @count: count
|
||||
* @pos: position pointer
|
||||
*
|
||||
* Return: Number of bytes read on success, error number otherwise
|
||||
*/
|
||||
static ssize_t wlan_hdd_read_ll_stats_debugfs(struct file *file,
|
||||
char __user *buf,
|
||||
size_t count, loff_t *pos)
|
||||
{
|
||||
int ret;
|
||||
|
||||
cds_ssr_protect(__func__);
|
||||
ret = __wlan_hdd_read_ll_stats_debugfs(file, buf, count, pos);
|
||||
cds_ssr_unprotect(__func__);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* __wlan_hdd_open_ll_stats_debugfs() - Function to save private on open
|
||||
* @inode: Pointer to inode structure
|
||||
* @file: file pointer
|
||||
*
|
||||
* Return: zero
|
||||
*/
|
||||
static int __wlan_hdd_open_ll_stats_debugfs(struct inode *inode,
|
||||
struct file *file)
|
||||
{
|
||||
hdd_adapter_t *adapter;
|
||||
hdd_context_t *hdd_ctx;
|
||||
int ret;
|
||||
|
||||
ENTER();
|
||||
|
||||
if (inode->i_private)
|
||||
file->private_data = inode->i_private;
|
||||
|
||||
adapter = (hdd_adapter_t *)file->private_data;
|
||||
if ((NULL == adapter) || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
|
||||
hdd_err("Invalid adapter or adapter has invalid magic");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
|
||||
ret = wlan_hdd_validate_context(hdd_ctx);
|
||||
if (0 != ret)
|
||||
return ret;
|
||||
|
||||
ret = wlan_hdd_llstats_alloc_buf();
|
||||
if (0 != ret)
|
||||
return ret;
|
||||
|
||||
ret = wlan_hdd_ll_stats_get(adapter, DEBUGFS_LLSTATS_REQID,
|
||||
DEBUGFS_LLSTATS_REQMASK);
|
||||
if (0 != ret)
|
||||
return ret;
|
||||
|
||||
EXIT();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* wlan_hdd_open_ll_stats_debugfs() - SSR wrapper function to save private
|
||||
* on open
|
||||
* @inode: Pointer to inode structure
|
||||
* @file: file pointer
|
||||
*
|
||||
* Return: zero
|
||||
*/
|
||||
static int wlan_hdd_open_ll_stats_debugfs(struct inode *inode,
|
||||
struct file *file)
|
||||
{
|
||||
int ret;
|
||||
|
||||
cds_ssr_protect(__func__);
|
||||
ret = __wlan_hdd_open_ll_stats_debugfs(inode, file);
|
||||
cds_ssr_unprotect(__func__);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* __wlan_hdd_release_ll_stats_debugfs() - Function to save private on release
|
||||
* @inode: Pointer to inode structure
|
||||
* @file: file pointer
|
||||
*
|
||||
* Return: zero
|
||||
*/
|
||||
static int __wlan_hdd_release_ll_stats_debugfs(struct inode *inode,
|
||||
struct file *file)
|
||||
{
|
||||
hdd_adapter_t *adapter;
|
||||
hdd_context_t *hdd_ctx;
|
||||
int ret;
|
||||
|
||||
ENTER();
|
||||
|
||||
if (inode->i_private)
|
||||
file->private_data = inode->i_private;
|
||||
|
||||
adapter = (hdd_adapter_t *)file->private_data;
|
||||
if ((NULL == adapter) || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
|
||||
hdd_err("Invalid adapter or adapter has invalid magic");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
|
||||
ret = wlan_hdd_validate_context(hdd_ctx);
|
||||
if (0 != ret)
|
||||
return ret;
|
||||
|
||||
wlan_hdd_llstats_free_buf();
|
||||
|
||||
EXIT();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_hdd_release_ll_stats_debugfs() - SSR wrapper function to save private
|
||||
* on release
|
||||
* @inode: Pointer to inode structure
|
||||
* @file: file pointer
|
||||
*
|
||||
* Return: zero
|
||||
*/
|
||||
static int wlan_hdd_release_ll_stats_debugfs(struct inode *inode,
|
||||
struct file *file)
|
||||
{
|
||||
int ret;
|
||||
|
||||
cds_ssr_protect(__func__);
|
||||
ret = __wlan_hdd_release_ll_stats_debugfs(inode, file);
|
||||
cds_ssr_unprotect(__func__);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct file_operations fops_ll_stats_debugfs = {
|
||||
.read = wlan_hdd_read_ll_stats_debugfs,
|
||||
.open = wlan_hdd_open_ll_stats_debugfs,
|
||||
.release = wlan_hdd_release_ll_stats_debugfs,
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
int wlan_hdd_create_ll_stats_file(hdd_adapter_t *adapter)
|
||||
{
|
||||
if (!debugfs_create_file("ll_stats", 0444, adapter->debugfs_phy,
|
||||
adapter, &fops_ll_stats_debugfs))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
@@ -34,26 +34,7 @@
|
||||
#include "hif.h"
|
||||
#include <qca_vendor.h>
|
||||
#include "wma_api.h"
|
||||
|
||||
#ifdef WLAN_FEATURE_LINK_LAYER_STATS
|
||||
|
||||
/**
|
||||
* struct hdd_ll_stats_context - hdd link layer stats context
|
||||
*
|
||||
* @request_id: userspace-assigned link layer stats request id
|
||||
* @request_bitmap: userspace-assigned link layer stats request bitmap
|
||||
* @response_event: LL stats request wait event
|
||||
*/
|
||||
struct hdd_ll_stats_context {
|
||||
uint32_t request_id;
|
||||
uint32_t request_bitmap;
|
||||
struct completion response_event;
|
||||
spinlock_t context_lock;
|
||||
};
|
||||
|
||||
static struct hdd_ll_stats_context ll_stats_context;
|
||||
|
||||
#endif /* End of WLAN_FEATURE_LINK_LAYER_STATS */
|
||||
#include "wlan_hdd_debugfs_llstat.h"
|
||||
|
||||
/* 11B, 11G Rate table include Basic rate and Extended rate
|
||||
* The IDX field is the rate index
|
||||
@@ -193,6 +174,7 @@ static int rssi_mcs_tbl[][10] = {
|
||||
|
||||
|
||||
#ifdef WLAN_FEATURE_LINK_LAYER_STATS
|
||||
static struct hdd_ll_stats_context ll_stats_context;
|
||||
|
||||
/**
|
||||
* put_wifi_rate_stat() - put wifi rate stats
|
||||
@@ -244,23 +226,6 @@ static bool put_wifi_rate_stat(tpSirWifiRateStat stats,
|
||||
return true;
|
||||
}
|
||||
|
||||
static tSirWifiPeerType wmi_to_sir_peer_type(enum wmi_peer_type type)
|
||||
{
|
||||
switch (type) {
|
||||
case WMI_PEER_TYPE_DEFAULT:
|
||||
return WIFI_PEER_STA;
|
||||
case WMI_PEER_TYPE_BSS:
|
||||
return WIFI_PEER_AP;
|
||||
case WMI_PEER_TYPE_TDLS:
|
||||
return WIFI_PEER_TDLS;
|
||||
case WMI_PEER_TYPE_NAN_DATA:
|
||||
return WIFI_PEER_NAN;
|
||||
default:
|
||||
hdd_err("Cannot map wmi_peer_type %d to HAL peer type", type);
|
||||
return WIFI_PEER_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* put_wifi_peer_info() - put wifi peer info
|
||||
* @stats: Pointer to stats context
|
||||
@@ -559,15 +524,8 @@ static tSirWifiInterfaceMode hdd_map_device_to_ll_iface_mode(int deviceMode)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_get_interface_info() - get interface info
|
||||
* @pAdapter: Pointer to device adapter
|
||||
* @pInfo: Pointer to interface info
|
||||
*
|
||||
* Return: bool
|
||||
*/
|
||||
static bool hdd_get_interface_info(hdd_adapter_t *pAdapter,
|
||||
tpSirWifiInterfaceInfo pInfo)
|
||||
bool hdd_get_interface_info(hdd_adapter_t *pAdapter,
|
||||
tpSirWifiInterfaceInfo pInfo)
|
||||
{
|
||||
uint8_t *staMac = NULL;
|
||||
hdd_station_ctx_t *pHddStaCtx;
|
||||
@@ -1044,6 +1002,76 @@ static void hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
|
||||
EXIT();
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_ll_process_radio_stats() - Wrapper function for cfg80211/debugfs
|
||||
* @adapter: Pointer to device adapter
|
||||
* @more_data: More data
|
||||
* @data: Pointer to stats data
|
||||
* @num_radios: Number of radios
|
||||
* @resp_id: Response ID from FW
|
||||
*
|
||||
* Receiving Link Layer Radio statistics from FW. This function is a wrapper
|
||||
* function which calls cfg80211/debugfs functions based on the response ID.
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static void hdd_ll_process_radio_stats(hdd_adapter_t *adapter,
|
||||
uint32_t more_data, void *data, uint32_t num_radio,
|
||||
uint32_t resp_id)
|
||||
{
|
||||
if (DEBUGFS_LLSTATS_REQID == resp_id)
|
||||
hdd_debugfs_process_radio_stats(adapter, more_data,
|
||||
(tpSirWifiRadioStat)data, num_radio);
|
||||
else
|
||||
hdd_link_layer_process_radio_stats(adapter, more_data,
|
||||
(tpSirWifiRadioStat)data, num_radio);
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_ll_process_iface_stats() - Wrapper function for cfg80211/debugfs
|
||||
* @adapter: Pointer to device adapter
|
||||
* @data: Pointer to stats data
|
||||
* @num_peers: Number of peers
|
||||
* @resp_id: Response ID from FW
|
||||
*
|
||||
* Receiving Link Layer Radio statistics from FW. This function is a wrapper
|
||||
* function which calls cfg80211/debugfs functions based on the response ID.
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static void hdd_ll_process_iface_stats(hdd_adapter_t *adapter,
|
||||
void *data, uint32_t num_peers, uint32_t resp_id)
|
||||
{
|
||||
if (DEBUGFS_LLSTATS_REQID == resp_id)
|
||||
hdd_debugfs_process_iface_stats(adapter,
|
||||
(tpSirWifiIfaceStat) data, num_peers);
|
||||
else
|
||||
hdd_link_layer_process_iface_stats(adapter,
|
||||
(tpSirWifiIfaceStat) data, num_peers);
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_ll_process_peer_stats() - Wrapper function for cfg80211/debugfs
|
||||
* @adapter: Pointer to device adapter
|
||||
* @more_data: More data
|
||||
* @data: Pointer to stats data
|
||||
* @resp_id: Response ID from FW
|
||||
*
|
||||
* Receiving Link Layer Radio statistics from FW. This function is a wrapper
|
||||
* function which calls cfg80211/debugfs functions based on the response ID.
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static void hdd_ll_process_peer_stats(hdd_adapter_t *adapter,
|
||||
uint32_t more_data, void *data, uint32_t resp_id)
|
||||
{
|
||||
if (DEBUGFS_LLSTATS_REQID == resp_id)
|
||||
hdd_debugfs_process_peer_stats(adapter, data);
|
||||
else
|
||||
hdd_link_layer_process_peer_stats(adapter, more_data,
|
||||
(tpSirWifiPeerStat) data);
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_hdd_cfg80211_link_layer_stats_callback() - This function is called
|
||||
* @ctx: Pointer to hdd context
|
||||
@@ -1103,23 +1131,24 @@ void wlan_hdd_cfg80211_link_layer_stats_callback(void *ctx,
|
||||
}
|
||||
spin_unlock(&context->context_lock);
|
||||
|
||||
if (linkLayerStatsResults->
|
||||
paramId & WMI_LINK_STATS_RADIO) {
|
||||
hdd_link_layer_process_radio_stats(pAdapter,
|
||||
if (linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO) {
|
||||
hdd_ll_process_radio_stats(pAdapter,
|
||||
linkLayerStatsResults->moreResultToFollow,
|
||||
(tpSirWifiRadioStat)linkLayerStatsResults->results,
|
||||
linkLayerStatsResults->num_radio);
|
||||
linkLayerStatsResults->results,
|
||||
linkLayerStatsResults->num_radio,
|
||||
linkLayerStatsResults->rspId);
|
||||
|
||||
spin_lock(&context->context_lock);
|
||||
if (!linkLayerStatsResults->moreResultToFollow)
|
||||
context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
|
||||
spin_unlock(&context->context_lock);
|
||||
|
||||
} else if (linkLayerStatsResults->
|
||||
paramId & WMI_LINK_STATS_IFACE) {
|
||||
hdd_link_layer_process_iface_stats(pAdapter,
|
||||
(tpSirWifiIfaceStat)linkLayerStatsResults->results,
|
||||
linkLayerStatsResults->num_peers);
|
||||
} else if (linkLayerStatsResults->paramId &
|
||||
WMI_LINK_STATS_IFACE) {
|
||||
hdd_ll_process_iface_stats(pAdapter,
|
||||
linkLayerStatsResults->results,
|
||||
linkLayerStatsResults->num_peers,
|
||||
linkLayerStatsResults->rspId);
|
||||
|
||||
spin_lock(&context->context_lock);
|
||||
/* Firmware doesn't send peerstats event if no peers are
|
||||
@@ -1135,9 +1164,10 @@ void wlan_hdd_cfg80211_link_layer_stats_callback(void *ctx,
|
||||
|
||||
} else if (linkLayerStatsResults->
|
||||
paramId & WMI_LINK_STATS_ALL_PEER) {
|
||||
hdd_link_layer_process_peer_stats(pAdapter,
|
||||
hdd_ll_process_peer_stats(pAdapter,
|
||||
linkLayerStatsResults->moreResultToFollow,
|
||||
(tpSirWifiPeerStat)linkLayerStatsResults->results);
|
||||
linkLayerStatsResults->results,
|
||||
linkLayerStatsResults->rspId);
|
||||
|
||||
spin_lock(&context->context_lock);
|
||||
if (!linkLayerStatsResults->moreResultToFollow)
|
||||
@@ -1318,6 +1348,86 @@ nla_policy
|
||||
[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = {.type = NLA_U32}
|
||||
};
|
||||
|
||||
static int wlan_hdd_send_ll_stats_req(hdd_context_t *hdd_ctx,
|
||||
tSirLLStatsGetReq *req)
|
||||
{
|
||||
unsigned long rc;
|
||||
struct hdd_ll_stats_context *context;
|
||||
|
||||
context = &ll_stats_context;
|
||||
spin_lock(&context->context_lock);
|
||||
context->request_id = req->reqId;
|
||||
context->request_bitmap = req->paramIdMask;
|
||||
INIT_COMPLETION(context->response_event);
|
||||
spin_unlock(&context->context_lock);
|
||||
|
||||
if (QDF_STATUS_SUCCESS !=
|
||||
sme_ll_stats_get_req(hdd_ctx->hHal, req)) {
|
||||
hdd_err("sme_ll_stats_get_req Failed");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = wait_for_completion_timeout(&context->response_event,
|
||||
msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
|
||||
if (!rc) {
|
||||
hdd_err("Target response timed out request id %d request bitmap 0x%x",
|
||||
context->request_id, context->request_bitmap);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wlan_hdd_ll_stats_get(hdd_adapter_t *adapter, uint32_t req_id,
|
||||
uint32_t req_mask)
|
||||
{
|
||||
unsigned long rc;
|
||||
tSirLLStatsGetReq get_req;
|
||||
hdd_station_ctx_t *hddstactx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
|
||||
hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
|
||||
int status;
|
||||
|
||||
ENTER();
|
||||
|
||||
if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
|
||||
hdd_warn("Command not allowed in FTM mode");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
status = wlan_hdd_validate_context(hdd_ctx);
|
||||
if (0 != status)
|
||||
return -EINVAL;
|
||||
|
||||
if (hddstactx->hdd_ReassocScenario) {
|
||||
hdd_err("Roaming in progress, so unable to proceed this request");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (!adapter->isLinkLayerStatsSet)
|
||||
hdd_info("isLinkLayerStatsSet: %d; STATs will be all zero",
|
||||
adapter->isLinkLayerStatsSet);
|
||||
|
||||
get_req.reqId = req_id;
|
||||
get_req.paramIdMask = req_mask;
|
||||
get_req.staId = adapter->sessionId;
|
||||
|
||||
rtnl_lock();
|
||||
rc = wlan_hdd_send_ll_stats_req(hdd_ctx, &get_req);
|
||||
if (0 != rc) {
|
||||
hdd_err("Failed to send LL stats request (id:%u)", req_id);
|
||||
goto err_rtnl_unlock;
|
||||
}
|
||||
|
||||
rtnl_unlock();
|
||||
|
||||
EXIT();
|
||||
return rc;
|
||||
|
||||
err_rtnl_unlock:
|
||||
rtnl_unlock();
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* __wlan_hdd_cfg80211_ll_stats_get() - get link layer stats
|
||||
* @wiphy: Pointer to wiphy
|
||||
@@ -1334,7 +1444,6 @@ __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
|
||||
int data_len)
|
||||
{
|
||||
unsigned long rc;
|
||||
struct hdd_ll_stats_context *context;
|
||||
hdd_context_t *pHddCtx = wiphy_priv(wiphy);
|
||||
struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
|
||||
tSirLLStatsGetReq LinkLayerStatsGetReq;
|
||||
@@ -1396,26 +1505,13 @@ __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
context = &ll_stats_context;
|
||||
spin_lock(&context->context_lock);
|
||||
context->request_id = LinkLayerStatsGetReq.reqId;
|
||||
context->request_bitmap = LinkLayerStatsGetReq.paramIdMask;
|
||||
INIT_COMPLETION(context->response_event);
|
||||
spin_unlock(&context->context_lock);
|
||||
|
||||
if (QDF_STATUS_SUCCESS != sme_ll_stats_get_req(pHddCtx->hHal,
|
||||
&LinkLayerStatsGetReq)) {
|
||||
hdd_err("sme_ll_stats_get_req Failed");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = wait_for_completion_timeout(&context->response_event,
|
||||
msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
|
||||
rc = wlan_hdd_send_ll_stats_req(pHddCtx, &LinkLayerStatsGetReq);
|
||||
if (!rc) {
|
||||
hdd_err("Target response timed out request id %d request bitmap 0x%x",
|
||||
context->request_id, context->request_bitmap);
|
||||
return -ETIMEDOUT;
|
||||
hdd_err("Failed to send LL stats request (id:%u)",
|
||||
LinkLayerStatsGetReq.reqId);
|
||||
return rc;
|
||||
}
|
||||
|
||||
EXIT();
|
||||
return 0;
|
||||
}
|
||||
|
@@ -81,6 +81,21 @@ struct index_data_rate_type {
|
||||
};
|
||||
|
||||
#ifdef WLAN_FEATURE_LINK_LAYER_STATS
|
||||
|
||||
/**
|
||||
* struct hdd_ll_stats_context - hdd link layer stats context
|
||||
*
|
||||
* @request_id: userspace-assigned link layer stats request id
|
||||
* @request_bitmap: userspace-assigned link layer stats request bitmap
|
||||
* @response_event: LL stats request wait event
|
||||
*/
|
||||
struct hdd_ll_stats_context {
|
||||
uint32_t request_id;
|
||||
uint32_t request_bitmap;
|
||||
struct completion response_event;
|
||||
spinlock_t context_lock;
|
||||
};
|
||||
|
||||
/*
|
||||
* Used to allocate the size of 4096 for the link layer stats.
|
||||
* The size of 4096 is considered assuming that all data per
|
||||
@@ -153,6 +168,27 @@ int wlan_hdd_cfg80211_ll_stats_ext_set_param(struct wiphy *wiphy,
|
||||
struct wireless_dev *wdev,
|
||||
const void *data,
|
||||
int data_len);
|
||||
/**
|
||||
* hdd_get_interface_info() - get interface info
|
||||
* @adapter: Pointer to device adapter
|
||||
* @info: Pointer to interface info
|
||||
*
|
||||
* Return: bool
|
||||
*/
|
||||
bool hdd_get_interface_info(hdd_adapter_t *adapter,
|
||||
tpSirWifiInterfaceInfo info);
|
||||
|
||||
/**
|
||||
* wlan_hdd_ll_stats_get() - Get Link Layer statistics from FW
|
||||
* @adapter: Pointer to device adapter
|
||||
* @req_id: request id
|
||||
* @req_mask: bitmask used by FW for the request
|
||||
*
|
||||
* Return: 0 on success and error code otherwise
|
||||
*/
|
||||
int wlan_hdd_ll_stats_get(hdd_adapter_t *adapter, uint32_t req_id,
|
||||
uint32_t req_mask);
|
||||
|
||||
#else
|
||||
|
||||
static inline void hdd_init_ll_stats_ctx(void)
|
||||
|
@@ -306,4 +306,11 @@ static inline void wma_tx_failure_cb(void *ctx, uint32_t num_msdu,
|
||||
*/
|
||||
void wma_store_pdev(void *wma_ctx, struct wlan_objmgr_pdev *pdev);
|
||||
|
||||
/**
|
||||
* wmi_to_sir_peer_type() - convert peer type from WMI to SIR enum
|
||||
* @type: enum wmi_peer_type
|
||||
*
|
||||
* Return: tSirWifiPeerType
|
||||
*/
|
||||
tSirWifiPeerType wmi_to_sir_peer_type(enum wmi_peer_type type);
|
||||
#endif
|
||||
|
@@ -4014,3 +4014,20 @@ bool wma_is_service_enabled(WMI_SERVICE service_type)
|
||||
|
||||
return WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap, service_type);
|
||||
}
|
||||
|
||||
tSirWifiPeerType wmi_to_sir_peer_type(enum wmi_peer_type type)
|
||||
{
|
||||
switch (type) {
|
||||
case WMI_PEER_TYPE_DEFAULT:
|
||||
return WIFI_PEER_STA;
|
||||
case WMI_PEER_TYPE_BSS:
|
||||
return WIFI_PEER_AP;
|
||||
case WMI_PEER_TYPE_TDLS:
|
||||
return WIFI_PEER_TDLS;
|
||||
case WMI_PEER_TYPE_NAN_DATA:
|
||||
return WIFI_PEER_NAN;
|
||||
default:
|
||||
WMA_LOGE("Cannot map wmi_peer_type %d to HAL peer type", type);
|
||||
return WIFI_PEER_INVALID;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user