qca-wifi: Provide support for avg. phyrate stats

Provide support for average tx and Rx phyrate statistics

Change-Id: I0fbb4aa7aaf215f49b066fc64a1f77b5c23db4d9
This commit is contained in:
Neha Bisht
2020-09-14 12:50:01 +05:30
committed by Gerrit - the friendly Code Review server
parent 9a16bc08e5
commit 27e1c19f38
4 changed files with 440 additions and 16 deletions

View File

@@ -90,6 +90,16 @@ struct wlan_peer_rx_rate_stats {
qdf_spinlock_t lock; qdf_spinlock_t lock;
}; };
/**
* struct wlan_peer_avg_rate_stats - Peer avg rate statistics
* @stats: array containing avg rate stats
* @lock: lock protecting list
*/
struct wlan_peer_avg_rate_stats {
struct wlan_avg_rate_stats stats;
qdf_spinlock_t lock;
};
/** /**
* struct wlan_peer_rx_link_stats - Peer Rx Link statistics * struct wlan_peer_rx_link_stats - Peer Rx Link statistics
* @stats: array containing rx rate stats * @stats: array containing rx rate stats
@@ -134,6 +144,7 @@ struct wlan_peer_link_metrics {
* struct wlan_peer_rate_stats_ctx - Peer statistics context * struct wlan_peer_rate_stats_ctx - Peer statistics context
* @rate_stats: Rate statistics (version 1 stats) * @rate_stats: Rate statistics (version 1 stats)
* @link_metrics: Link Metrics (version 2 stats) * @link_metrics: Link Metrics (version 2 stats)
* @avg: Avg rate statistics
* @mac_addr: peer MAC address * @mac_addr: peer MAC address
* @peer_cookie: cookie for unique session of peer * @peer_cookie: cookie for unique session of peer
* @pdev_id: id of dp pdev * @pdev_id: id of dp pdev
@@ -141,6 +152,7 @@ struct wlan_peer_link_metrics {
struct wlan_peer_rate_stats_ctx { struct wlan_peer_rate_stats_ctx {
struct wlan_peer_rate_stats *rate_stats; struct wlan_peer_rate_stats *rate_stats;
struct wlan_peer_link_metrics *link_metrics; struct wlan_peer_link_metrics *link_metrics;
struct wlan_peer_avg_rate_stats avg;
uint8_t mac_addr[WLAN_MAC_ADDR_LEN]; uint8_t mac_addr[WLAN_MAC_ADDR_LEN];
uint64_t peer_cookie; uint64_t peer_cookie;
uint8_t pdev_id; uint8_t pdev_id;

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 The Linux Foundation. All rights reserved. * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
* *
* Permission to use, copy, modify, and/or distribute this software for * Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the * any purpose with or without fee is hereby granted, provided that the
@@ -77,7 +77,7 @@ QDF_DECLARE_EWMA(rx_rssi, 1024, 8)
(((_val) >> DP_PEER_STATS_BW_OFFSET) & DP_PEER_STATS_BW_MASK) (((_val) >> DP_PEER_STATS_BW_OFFSET) & DP_PEER_STATS_BW_MASK)
/** /**
* enum cdp_peer_rate_stats_cmd - * enum wlan_peer_rate_stats_cmd -
* used by app to get specific stats * used by app to get specific stats
*/ */
enum wlan_peer_rate_stats_cmd { enum wlan_peer_rate_stats_cmd {
@@ -86,6 +86,7 @@ enum wlan_peer_rate_stats_cmd {
DP_PEER_SOJOURN_STATS, DP_PEER_SOJOURN_STATS,
DP_PEER_RX_LINK_STATS, DP_PEER_RX_LINK_STATS,
DP_PEER_TX_LINK_STATS, DP_PEER_TX_LINK_STATS,
DP_PEER_AVG_RATE_STATS,
}; };
/** struct wlan_tx_rate_stats - Tx packet rate info /** struct wlan_tx_rate_stats - Tx packet rate info
@@ -150,6 +151,46 @@ struct wlan_tx_sojourn_stats {
#define BW_USAGE_MAX_SIZE 4 #define BW_USAGE_MAX_SIZE 4
/**
* enum wlan_rate_ppdu_type -
* types of communication
*/
enum wlan_rate_ppdu_type {
WLAN_RATE_SU,
WLAN_RATE_MU_MIMO,
WLAN_RATE_MU_OFDMA,
WLAN_RATE_MU_OFDMA_MIMO,
WLAN_RATE_MAX,
};
/**
* struct wlan_rate_avg - avg rate stats
* @num_ppdu: number of ppdu
* @sum_mbps: cumulative rate in mbps
* @num_snr: number of times snr added
* @sum_snr: sum of snr
* @num_mpdu: number of mpdu
* @num_retry: num of retries
*/
struct wlan_rate_avg {
uint32_t num_ppdu;
uint32_t sum_mbps;
uint32_t num_snr;
uint32_t sum_snr;
uint64_t num_mpdu;
uint32_t num_retry;
};
/**
* struct wlan_avg_rate_stats - avg rate stats for tx and rx
* @tx: avg tx rate stats
* @rx: avg rx rate stats
*/
struct wlan_avg_rate_stats {
struct wlan_rate_avg tx[WLAN_RATE_MAX];
struct wlan_rate_avg rx[WLAN_RATE_MAX];
};
/** /**
* struct wlan_peer_bw_stats - per link bw related stats * struct wlan_peer_bw_stats - per link bw related stats
* @usage_total - sum of total BW (20, 40, 80, 160) * @usage_total - sum of total BW (20, 40, 80, 160)

View File

@@ -33,6 +33,257 @@
* x = 3 for 160MHz * x = 3 for 160MHz
*/ */
#define GET_BW_FROM_BW_ENUM(x) ((20) * (1 << x)) #define GET_BW_FROM_BW_ENUM(x) ((20) * (1 << x))
#define FLUSH_OVERFLOW_CHECK (1 << 31)
static void
wlan_peer_flush_avg_rate_stats(struct wlan_soc_rate_stats_ctx *soc_stats_ctx,
struct wlan_peer_rate_stats_ctx *stats_ctx)
{
struct wlan_peer_rate_stats_intf buf;
struct wlan_peer_avg_rate_stats *avg_stats;
if (!soc_stats_ctx)
return;
avg_stats = &stats_ctx->avg;
buf.stats = (struct wlan_avg_rate_stats *)&avg_stats->stats;
buf.buf_len = sizeof(struct wlan_avg_rate_stats);
buf.stats_type = DP_PEER_AVG_RATE_STATS;
buf.cookie = stats_ctx->peer_cookie;
qdf_mem_copy(buf.peer_mac, stats_ctx->mac_addr, WLAN_MAC_ADDR_LEN);
cdp_peer_flush_rate_stats(soc_stats_ctx->soc, stats_ctx->pdev_id, &buf);
soc_stats_ctx->txs_cache_flush++;
dp_info("txs_cache_flush: %d", soc_stats_ctx->txs_cache_flush);
qdf_mem_zero(&avg_stats->stats, sizeof(avg_stats->stats));
}
static int
wlan_peer_update_avg_tx_rate_stats_user(
struct wlan_avg_rate_stats *avg,
struct cdp_tx_completion_ppdu *ppdu,
struct cdp_tx_completion_ppdu_user *user)
{
enum wlan_rate_ppdu_type type;
uint32_t flush;
uint32_t kbps;
uint16_t fc = qdf_cpu_to_le16(ppdu->frame_ctrl);
bool is_pm = fc & (QDF_IEEE80211_FC1_PM << 8); // shift by 8 to get FC1 field
bool is_data = (fc & QDF_IEEE80211_FC0_TYPE_MASK) ==
QDF_IEEE80211_FC0_TYPE_DATA &&
((fc & QDF_IEEE80211_FC0_SUBTYPE_MASK) ==
QDF_IEEE80211_FC0_SUBTYPE_DATA ||
(fc & QDF_IEEE80211_FC0_SUBTYPE_MASK) ==
QDF_IEEE80211_FC0_SUBTYPE_QOS);
switch (user->ppdu_type) {
case WLAN_RATE_SU:
type = WLAN_RATE_SU;
break;
case WLAN_RATE_MU_MIMO:
type = WLAN_RATE_MU_MIMO;
break;
case WLAN_RATE_MU_OFDMA:
type = WLAN_RATE_MU_OFDMA;
break;
case WLAN_RATE_MU_OFDMA_MIMO:
type = WLAN_RATE_MU_OFDMA_MIMO;
break;
default:
dp_info("Invalid ppdu type");
return 0;
}
kbps = user->tx_ratekbps;
if (kbps == 0) {
dp_err("rate is invalid");
return 0;
}
if (!is_pm && is_data && !user->is_bss_peer) {
avg->tx[type].num_ppdu++;
avg->tx[type].sum_mbps += kbps / CDP_NUM_KB_IN_MB;
}
avg->tx[type].num_mpdu += user->mpdu_success;
avg->tx[type].num_retry += user->mpdu_failed;
if (user->ack_rssi_valid) {
avg->tx[type].num_snr++;
avg->tx[type].sum_snr += user->usr_ack_rssi;
}
flush = 0;
flush |= avg->tx[type].num_ppdu & FLUSH_OVERFLOW_CHECK;
flush |= avg->tx[type].sum_mbps & FLUSH_OVERFLOW_CHECK;
flush |= avg->tx[type].num_snr & FLUSH_OVERFLOW_CHECK;
flush |= avg->tx[type].sum_snr & FLUSH_OVERFLOW_CHECK;
return flush ? 1 : 0;
}
static void
wlan_peer_update_avg_tx_rate_stats(
struct wlan_soc_rate_stats_ctx *soc_stats_ctx,
struct cdp_tx_completion_ppdu *ppdu)
{
struct wlan_peer_rate_stats_ctx *stats_ctx;
struct wlan_avg_rate_stats *avg;
struct cdp_tx_completion_ppdu_user *user;
int i;
for (i = 0; i < ppdu->num_users; i++) {
user = &ppdu->user[i];
STATS_CTX_LOCK_ACQUIRE(&soc_stats_ctx->tx_ctx_lock);
if (user->peer_id == CDP_INVALID_PEER) {
dp_warn("no valid peer \n");
STATS_CTX_LOCK_RELEASE(&soc_stats_ctx->tx_ctx_lock);
continue;
}
stats_ctx = cdp_peer_get_rdkstats_ctx(soc_stats_ctx->soc,
ppdu->vdev_id,
user->mac_addr);
if (qdf_unlikely(!stats_ctx)) {
dp_warn("peer rate stats ctx is NULL, return");
dp_warn("peer_mac: " QDF_MAC_ADDR_FMT,
QDF_MAC_ADDR_REF(user->mac_addr));
STATS_CTX_LOCK_RELEASE(&soc_stats_ctx->tx_ctx_lock);
continue;
}
avg = &stats_ctx->avg.stats;
RATE_STATS_LOCK_ACQUIRE(&stats_ctx->avg.lock);
if (wlan_peer_update_avg_tx_rate_stats_user(avg, ppdu, user))
wlan_peer_flush_avg_rate_stats(soc_stats_ctx,
stats_ctx);
RATE_STATS_LOCK_RELEASE(&stats_ctx->avg.lock);
STATS_CTX_LOCK_RELEASE(&soc_stats_ctx->tx_ctx_lock);
}
}
static int
wlan_peer_update_avg_rx_rate_stats_user(struct wlan_avg_rate_stats *avg,
struct cdp_rx_indication_ppdu *ppdu,
struct cdp_rx_stats_ppdu_user *user)
{
enum wlan_rate_ppdu_type type;
uint32_t flush;
uint32_t kbps;
uint32_t nss;
uint32_t mcs;
uint16_t fc = qdf_cpu_to_le16(ppdu->frame_ctrl);
bool is_pm = fc & (QDF_IEEE80211_FC1_PM << 8); // shift by 8 to get FC1 field
bool is_data = (fc & QDF_IEEE80211_FC0_TYPE_MASK) ==
QDF_IEEE80211_FC0_TYPE_DATA &&
((fc & QDF_IEEE80211_FC0_SUBTYPE_MASK) ==
QDF_IEEE80211_FC0_SUBTYPE_DATA ||
(fc & QDF_IEEE80211_FC0_SUBTYPE_MASK) ==
QDF_IEEE80211_FC0_SUBTYPE_QOS);
switch (ppdu->u.ppdu_type) {
case WLAN_RATE_SU:
type = WLAN_RATE_SU;
break;
case WLAN_RATE_MU_MIMO:
type = WLAN_RATE_MU_MIMO;
break;
case WLAN_RATE_MU_OFDMA:
type = WLAN_RATE_MU_OFDMA;
break;
case WLAN_RATE_MU_OFDMA_MIMO:
type = WLAN_RATE_MU_OFDMA_MIMO;
break;
default:
dp_info("Invalid ppdu type");
return 0;
}
mcs = ppdu->u.mcs;
nss = ppdu->u.nss; /* apparently ppdu->nss counts from 1 */
if (user->mu_ul_info_valid) {
/* apparently ppdu_type won't reflect ul ofdma properly
* moreover, its possible to get 1 user ul ofdma
* this is ambiguous, but it makes most sense to consider these
* as SU because it can be used to avoid interference too.
*/
if (ppdu->num_users > 1)
type = WLAN_RATE_MU_OFDMA;
mcs = user->mcs;
nss = user->nss + 1; /* apparently user->nss counts from 0 */
}
kbps = user->rx_ratekbps;
if (kbps == 0) {
dp_err("rate is invalid");
return 0;
}
if (!is_pm && is_data && !user->is_bss_peer) {
avg->rx[type].num_ppdu++;
avg->rx[type].sum_mbps += kbps / CDP_NUM_KB_IN_MB;
}
avg->rx[type].num_snr++;
avg->rx[type].sum_snr += ppdu->rssi; /* Info not available per user */
avg->rx[type].num_mpdu += user->mpdu_cnt_fcs_ok;
avg->rx[type].num_retry += user->mpdu_cnt_fcs_err;
flush = 0;
flush |= avg->rx[type].num_ppdu & FLUSH_OVERFLOW_CHECK;
flush |= avg->rx[type].sum_mbps & FLUSH_OVERFLOW_CHECK;
flush |= avg->rx[type].num_snr & FLUSH_OVERFLOW_CHECK;
flush |= avg->rx[type].sum_snr & FLUSH_OVERFLOW_CHECK;
return flush ? 1 : 0;
}
static void
wlan_peer_update_avg_rx_rate_stats(
struct wlan_soc_rate_stats_ctx *soc_stats_ctx,
struct cdp_rx_indication_ppdu *ppdu)
{
struct wlan_peer_rate_stats_ctx *stats_ctx;
struct wlan_avg_rate_stats *avg;
struct cdp_rx_stats_ppdu_user *user;
int i;
for (i = 0; i < ppdu->num_users; i++) {
user = &ppdu->user[i];
STATS_CTX_LOCK_ACQUIRE(&soc_stats_ctx->rx_ctx_lock);
if (user->peer_id == CDP_INVALID_PEER) {
dp_warn("no valid peer \n");
STATS_CTX_LOCK_RELEASE(&soc_stats_ctx->rx_ctx_lock);
continue;
}
stats_ctx = cdp_peer_get_rdkstats_ctx(soc_stats_ctx->soc,
ppdu->vdev_id,
user->mac_addr);
if (qdf_unlikely(!stats_ctx)) {
dp_warn("peer rate stats ctx is NULL, return");
dp_warn("peer_mac: " QDF_MAC_ADDR_FMT,
QDF_MAC_ADDR_REF(user->mac_addr));
STATS_CTX_LOCK_RELEASE(&soc_stats_ctx->rx_ctx_lock);
continue;
}
avg = &stats_ctx->avg.stats;
RATE_STATS_LOCK_ACQUIRE(&stats_ctx->avg.lock);
if (wlan_peer_update_avg_rx_rate_stats_user(avg, ppdu, user))
wlan_peer_flush_avg_rate_stats(soc_stats_ctx,
stats_ctx);
RATE_STATS_LOCK_RELEASE(&stats_ctx->avg.lock);
STATS_CTX_LOCK_RELEASE(&soc_stats_ctx->rx_ctx_lock);
}
}
static void static void
wlan_peer_read_ewma_avg_rssi(struct wlan_rx_rate_stats *rx_stats) wlan_peer_read_ewma_avg_rssi(struct wlan_rx_rate_stats *rx_stats)
@@ -291,6 +542,10 @@ wlan_peer_flush_rate_stats(struct wlan_soc_rate_stats_ctx *soc_stats_ctx,
RATE_STATS_LOCK_ACQUIRE(&rx_stats->lock); RATE_STATS_LOCK_ACQUIRE(&rx_stats->lock);
wlan_peer_flush_rx_rate_stats(soc_stats_ctx, stats_ctx); wlan_peer_flush_rx_rate_stats(soc_stats_ctx, stats_ctx);
RATE_STATS_LOCK_RELEASE(&rx_stats->lock); RATE_STATS_LOCK_RELEASE(&rx_stats->lock);
RATE_STATS_LOCK_ACQUIRE(&stats_ctx->avg.lock);
wlan_peer_flush_avg_rate_stats(soc_stats_ctx, stats_ctx);
RATE_STATS_LOCK_RELEASE(&stats_ctx->avg.lock);
} }
if (soc_stats_ctx->stats_ver == RDK_LINK_STATS || if (soc_stats_ctx->stats_ver == RDK_LINK_STATS ||
@@ -373,8 +628,8 @@ wlan_peer_update_tx_link_stats(struct wlan_soc_rate_stats_ctx *soc_stats_ctx,
ppdu_user->mac_addr); ppdu_user->mac_addr);
if (qdf_unlikely(!stats_ctx)) { if (qdf_unlikely(!stats_ctx)) {
qdf_warn("peer rate stats ctx is NULL, return"); dp_warn("peer rate stats ctx is NULL, return");
qdf_warn("peer_mac: " QDF_MAC_ADDR_FMT, dp_warn("peer_mac: " QDF_MAC_ADDR_FMT,
QDF_MAC_ADDR_REF(ppdu_user->mac_addr)); QDF_MAC_ADDR_REF(ppdu_user->mac_addr));
STATS_CTX_LOCK_RELEASE(&soc_stats_ctx->tx_ctx_lock); STATS_CTX_LOCK_RELEASE(&soc_stats_ctx->tx_ctx_lock);
continue; continue;
@@ -447,8 +702,8 @@ wlan_peer_update_rx_link_stats(struct wlan_soc_rate_stats_ctx *soc_stats_ctx,
ppdu_user->mac_addr); ppdu_user->mac_addr);
if (qdf_unlikely(!stats_ctx)) { if (qdf_unlikely(!stats_ctx)) {
qdf_warn("peer rate stats ctx is NULL, return"); dp_warn("peer rate stats ctx is NULL, return");
qdf_warn("peer_mac: " QDF_MAC_ADDR_FMT, dp_warn("peer_mac: " QDF_MAC_ADDR_FMT,
QDF_MAC_ADDR_REF(ppdu_user->mac_addr)); QDF_MAC_ADDR_REF(ppdu_user->mac_addr));
STATS_CTX_LOCK_RELEASE(&soc_stats_ctx->rx_ctx_lock); STATS_CTX_LOCK_RELEASE(&soc_stats_ctx->rx_ctx_lock);
continue; continue;
@@ -521,11 +776,21 @@ wlan_peer_update_rx_rate_stats(struct wlan_soc_rate_stats_ctx *soc_stats_ctx,
if (cdp_rx_ppdu->u.ppdu_type != DP_PPDU_TYPE_SU) { if (cdp_rx_ppdu->u.ppdu_type != DP_PPDU_TYPE_SU) {
ppdu_user = &cdp_rx_ppdu->user[user_idx]; ppdu_user = &cdp_rx_ppdu->user[user_idx];
if (ppdu_user->peer_id == CDP_INVALID_PEER) {
dp_warn("no valid peer \n");
STATS_CTX_LOCK_RELEASE(&soc_stats_ctx->rx_ctx_lock);
continue;
}
stats_ctx = stats_ctx =
cdp_peer_get_rdkstats_ctx(soc_stats_ctx->soc, cdp_peer_get_rdkstats_ctx(soc_stats_ctx->soc,
ppdu_user->vdev_id, ppdu_user->vdev_id,
ppdu_user->mac_addr); ppdu_user->mac_addr);
} else { } else {
if (cdp_rx_ppdu->peer_id == CDP_INVALID_PEER) {
dp_warn("No valid peer \n");
STATS_CTX_LOCK_RELEASE(&soc_stats_ctx->rx_ctx_lock);
continue;
}
stats_ctx = stats_ctx =
cdp_peer_get_rdkstats_ctx(soc_stats_ctx->soc, cdp_peer_get_rdkstats_ctx(soc_stats_ctx->soc,
cdp_rx_ppdu->vdev_id, cdp_rx_ppdu->vdev_id,
@@ -533,8 +798,8 @@ wlan_peer_update_rx_rate_stats(struct wlan_soc_rate_stats_ctx *soc_stats_ctx,
} }
if (qdf_unlikely(!stats_ctx)) { if (qdf_unlikely(!stats_ctx)) {
qdf_warn("peer rate stats ctx is NULL, return"); dp_warn("peer rate stats ctx is NULL, return");
qdf_warn("peer_mac: " QDF_MAC_ADDR_FMT, dp_warn("peer_mac: " QDF_MAC_ADDR_FMT,
QDF_MAC_ADDR_REF(cdp_rx_ppdu->mac_addr)); QDF_MAC_ADDR_REF(cdp_rx_ppdu->mac_addr));
STATS_CTX_LOCK_RELEASE(&soc_stats_ctx->rx_ctx_lock); STATS_CTX_LOCK_RELEASE(&soc_stats_ctx->rx_ctx_lock);
continue; continue;
@@ -655,8 +920,8 @@ wlan_peer_update_tx_rate_stats(struct wlan_soc_rate_stats_ctx *soc_stats_ctx,
} }
if (qdf_unlikely(!stats_ctx)) { if (qdf_unlikely(!stats_ctx)) {
qdf_debug("peer rate stats ctx is NULL, investigate"); dp_warn("peer rate stats ctx is NULL, investigate");
qdf_debug("peer_mac: " QDF_MAC_ADDR_FMT, dp_warn("peer_mac: " QDF_MAC_ADDR_FMT,
QDF_MAC_ADDR_REF(ppdu_user->mac_addr)); QDF_MAC_ADDR_REF(ppdu_user->mac_addr));
STATS_CTX_LOCK_RELEASE(&soc_stats_ctx->tx_ctx_lock); STATS_CTX_LOCK_RELEASE(&soc_stats_ctx->tx_ctx_lock);
continue; continue;
@@ -726,7 +991,7 @@ wlan_peer_update_sojourn_stats(struct wlan_soc_rate_stats_ctx *soc_stats_ctx,
stats_ctx = (struct wlan_peer_rate_stats_ctx *)sojourn_stats->cookie; stats_ctx = (struct wlan_peer_rate_stats_ctx *)sojourn_stats->cookie;
if (qdf_unlikely(!stats_ctx)) { if (qdf_unlikely(!stats_ctx)) {
qdf_warn("peer rate stats ctx is NULL, return"); dp_warn("peer rate stats ctx is NULL, return");
return; return;
} }
@@ -772,6 +1037,7 @@ void wlan_peer_update_rate_stats(void *ctx,
qdf_nbuf_data(nbuf); qdf_nbuf_data(nbuf);
wlan_peer_update_tx_rate_stats(soc_stats_ctx, cdp_tx_ppdu); wlan_peer_update_tx_rate_stats(soc_stats_ctx, cdp_tx_ppdu);
wlan_peer_update_tx_link_stats(soc_stats_ctx, cdp_tx_ppdu); wlan_peer_update_tx_link_stats(soc_stats_ctx, cdp_tx_ppdu);
wlan_peer_update_avg_tx_rate_stats(soc_stats_ctx, cdp_tx_ppdu);
qdf_nbuf_free(nbuf); qdf_nbuf_free(nbuf);
break; break;
case WDI_EVENT_RX_PPDU_DESC: case WDI_EVENT_RX_PPDU_DESC:
@@ -779,6 +1045,7 @@ void wlan_peer_update_rate_stats(void *ctx,
qdf_nbuf_data(nbuf); qdf_nbuf_data(nbuf);
wlan_peer_update_rx_rate_stats(soc_stats_ctx, cdp_rx_ppdu); wlan_peer_update_rx_rate_stats(soc_stats_ctx, cdp_rx_ppdu);
wlan_peer_update_rx_link_stats(soc_stats_ctx, cdp_rx_ppdu); wlan_peer_update_rx_link_stats(soc_stats_ctx, cdp_rx_ppdu);
wlan_peer_update_avg_rx_rate_stats(soc_stats_ctx, cdp_rx_ppdu);
qdf_nbuf_free(nbuf); qdf_nbuf_free(nbuf);
break; break;
case WDI_EVENT_TX_SOJOURN_STAT: case WDI_EVENT_TX_SOJOURN_STAT:
@@ -790,7 +1057,7 @@ void wlan_peer_update_rate_stats(void *ctx,
wlan_peer_update_sojourn_stats(soc_stats_ctx, sojourn_stats); wlan_peer_update_sojourn_stats(soc_stats_ctx, sojourn_stats);
break; break;
default: default:
qdf_err("Err, Invalid type"); dp_err("Err, Invalid type");
} }
} }
@@ -822,6 +1089,7 @@ void wlan_peer_create_event_handler(void *ctx, enum WDI_EVENT event,
} }
RATE_STATS_LOCK_CREATE(&stats->rate_stats->tx.lock); RATE_STATS_LOCK_CREATE(&stats->rate_stats->tx.lock);
RATE_STATS_LOCK_CREATE(&stats->rate_stats->rx.lock); RATE_STATS_LOCK_CREATE(&stats->rate_stats->rx.lock);
RATE_STATS_LOCK_CREATE(&stats->avg.lock);
for (idx = 0; idx < WLANSTATS_CACHE_SIZE; idx++) { for (idx = 0; idx < WLANSTATS_CACHE_SIZE; idx++) {
stats->rate_stats->tx.stats[idx].rix = stats->rate_stats->tx.stats[idx].rix =
INVALID_CACHE_IDX; INVALID_CACHE_IDX;
@@ -854,6 +1122,7 @@ peer_create_fail2:
soc_stats_ctx->stats_ver == RDK_ALL_STATS) { soc_stats_ctx->stats_ver == RDK_ALL_STATS) {
RATE_STATS_LOCK_DESTROY(&stats->rate_stats->tx.lock); RATE_STATS_LOCK_DESTROY(&stats->rate_stats->tx.lock);
RATE_STATS_LOCK_DESTROY(&stats->rate_stats->rx.lock); RATE_STATS_LOCK_DESTROY(&stats->rate_stats->rx.lock);
RATE_STATS_LOCK_DESTROY(&stats->avg.lock);
qdf_mem_free(stats->rate_stats); qdf_mem_free(stats->rate_stats);
stats->rate_stats = NULL; stats->rate_stats = NULL;
} }
@@ -881,6 +1150,7 @@ void wlan_peer_destroy_event_handler(void *ctx, enum WDI_EVENT event,
if (stats->rate_stats) { if (stats->rate_stats) {
RATE_STATS_LOCK_DESTROY(&stats->rate_stats->tx.lock); RATE_STATS_LOCK_DESTROY(&stats->rate_stats->tx.lock);
RATE_STATS_LOCK_DESTROY(&stats->rate_stats->rx.lock); RATE_STATS_LOCK_DESTROY(&stats->rate_stats->rx.lock);
RATE_STATS_LOCK_DESTROY(&stats->avg.lock);
qdf_mem_free(stats->rate_stats); qdf_mem_free(stats->rate_stats);
} }
if (stats->link_metrics) { if (stats->link_metrics) {

View File

@@ -340,6 +340,97 @@ static void dp_peer_tx_rate_stats_print(uint8_t *peer_mac,
return; return;
} }
static void dp_peer_avg_rate_stats_print(uint8_t *peer_mac,
uint64_t peer_cookie,
void *buffer,
uint32_t buffer_len)
{
struct wlan_avg_rate_stats *stats = buffer;
enum wlan_rate_ppdu_type type;
static const char *type2str[] = {
"SU",
"MU-MIMO",
"MU-OFDMA",
"MU-MIMO-OFDMA",
};
uint32_t mpdu;
uint32_t psr;
uint32_t avg_mbps;
uint32_t avg_snr;
PRINT("peer %02hhx:%02hhx:%02hhx:%02hhx%02hhx:%02hhx",
peer_mac[0],
peer_mac[1],
peer_mac[2],
peer_mac[3],
peer_mac[4],
peer_mac[5]);
PRINT(" %20s %15s %15s %15s %15s %15s",
"mode",
"rate(mbps)",
"total ppdu",
"snr value",
"snr count",
"psr value");
PRINT("Avg tx stats: ");
for (type = 0; type < WLAN_RATE_MAX; type++) {
psr = 0;
avg_mbps = 0;
avg_snr = 0;
if (stats->tx[type].num_ppdu > 0)
avg_mbps = stats->tx[type].sum_mbps /
stats->tx[type].num_ppdu;
if (stats->tx[type].num_snr > 0)
avg_snr = stats->tx[type].sum_snr /
stats->tx[type].num_snr;
mpdu = stats->tx[type].num_mpdu +
stats->tx[type].num_retry;
if (mpdu > 0)
psr = (100 * stats->tx[type].num_mpdu) / mpdu;
PRINT(" %20s %15u %15u %15u %15u %15u",
type2str[type],
avg_mbps, stats->tx[type].num_ppdu,
avg_snr, stats->tx[type].num_snr,
psr);
}
PRINT("");
PRINT("Avg rx stats: ");
for (type = 0; type < WLAN_RATE_MAX; type++) {
psr = 0;
avg_mbps = 0;
avg_snr = 0;
if (stats->rx[type].num_ppdu > 0)
avg_mbps = stats->rx[type].sum_mbps /
stats->rx[type].num_ppdu;
if (stats->rx[type].num_snr > 0)
avg_snr = stats->rx[type].sum_snr /
stats->rx[type].num_snr;
mpdu = stats->rx[type].num_mpdu +
stats->rx[type].num_retry;
if (mpdu > 0)
psr = (100 * stats->rx[type].num_mpdu) / mpdu;
PRINT(" %20s %15u %15u %15u %15u %15u",
type2str[type],
avg_mbps, stats->rx[type].num_ppdu,
avg_snr, stats->rx[type].num_snr,
psr);
}
PRINT("");
PRINT("");
}
static void dp_peer_tx_link_stats_print(uint8_t *peer_mac, static void dp_peer_tx_link_stats_print(uint8_t *peer_mac,
uint64_t peer_cookie, uint64_t peer_cookie,
void *buffer, void *buffer,
@@ -442,10 +533,14 @@ static void dp_peer_stats_handler(uint32_t cache_type,
{ {
switch (cache_type) { switch (cache_type) {
case DP_PEER_RX_RATE_STATS: case DP_PEER_RX_RATE_STATS:
if (getenv("SKIP_RX_RATE_STATS"))
break;
dp_peer_rx_rate_stats_print(peer_mac, peer_cookie, dp_peer_rx_rate_stats_print(peer_mac, peer_cookie,
buffer, buffer_len); buffer, buffer_len);
break; break;
case DP_PEER_TX_RATE_STATS: case DP_PEER_TX_RATE_STATS:
if (getenv("SKIP_TX_RATE_STATS"))
break;
dp_peer_tx_rate_stats_print(peer_mac, peer_cookie, dp_peer_tx_rate_stats_print(peer_mac, peer_cookie,
buffer, buffer_len); buffer, buffer_len);
break; break;
@@ -457,6 +552,12 @@ static void dp_peer_stats_handler(uint32_t cache_type,
dp_peer_rx_link_stats_print(peer_mac, peer_cookie, dp_peer_rx_link_stats_print(peer_mac, peer_cookie,
buffer, buffer_len); buffer, buffer_len);
break; break;
case DP_PEER_AVG_RATE_STATS:
if (getenv("SKIP_AVG_RATE_STATS"))
break;
dp_peer_avg_rate_stats_print(peer_mac, peer_cookie,
buffer, buffer_len);
break;
} }
} }