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:

committed by
Gerrit - the friendly Code Review server

parent
9a16bc08e5
commit
27e1c19f38
@@ -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;
|
||||||
|
@@ -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)
|
||||||
|
@@ -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) {
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user