qcacmn: Extract and populate peer_extd2 stats from fw
Presently, the driver doesnot extract the peer extended2 stats (rx_bytes, rx_count, fcs_err) that are received from firmware. Provide the support to extract and populate the peer extended stats2 at the driver level. Change-Id: If1f1bb1ef2d1202581744dd509d0da1da718d8c1 CRs-Fixed: 2397638
Este commit está contenido en:

cometido por
nshrivas

padre
9a6ee7d0ce
commit
d768fd9e1e
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2018-2019 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
|
||||
@@ -87,12 +87,14 @@ struct vdev_cp_stats {
|
||||
* struct peer_cp_stats - defines cp stats at peer object
|
||||
* @peer_obj: pointer to peer
|
||||
* @peer_stats: pointer to ic/mc specific stats
|
||||
* @peer_adv_stats: pointer to peer adv stats
|
||||
* @peer_comp_priv_obj[]: component's private object pointers
|
||||
* @peer_cp_stats_lock: lock to protect object
|
||||
*/
|
||||
struct peer_cp_stats {
|
||||
struct wlan_objmgr_peer *peer_obj;
|
||||
void *peer_stats;
|
||||
void *peer_adv_stats;
|
||||
void *peer_comp_priv_obj[WLAN_CP_STATS_MAX_COMPONENTS];
|
||||
qdf_spinlock_t peer_cp_stats_lock;
|
||||
};
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2012-2019 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
|
||||
@@ -33,6 +33,9 @@
|
||||
|
||||
#define MAX_NUM_CHAINS 2
|
||||
|
||||
#define IS_MSB_SET(__num) ((__num) & BIT(31))
|
||||
#define IS_LSB_SET(__num) ((__num) & BIT(0))
|
||||
|
||||
/**
|
||||
* enum stats_req_type - enum indicating bit position of various stats type in
|
||||
* request map
|
||||
@@ -248,6 +251,20 @@ struct peer_mc_cp_stats {
|
||||
uint8_t peer_macaddr[WLAN_MACADDR_LEN];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct peer_adv_mc_cp_stats - peer specific adv stats
|
||||
* @peer_macaddr: mac address
|
||||
* @fcs_count: fcs count
|
||||
* @rx_bytes: rx bytes
|
||||
* @rx_count: rx count
|
||||
*/
|
||||
struct peer_adv_mc_cp_stats {
|
||||
uint8_t peer_macaddr[WLAN_MACADDR_LEN];
|
||||
uint32_t fcs_count;
|
||||
uint32_t rx_count;
|
||||
uint64_t rx_bytes;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct congestion_stats_event: congestion stats event param
|
||||
* @vdev_id: vdev_id of the event
|
||||
@@ -284,6 +301,8 @@ struct chain_rssi_event {
|
||||
* @pdev_stats: if populated array indicating pdev stats (index = pdev_id)
|
||||
* @num_peer_stats: num peer stats
|
||||
* @peer_stats: if populated array indicating peer stats
|
||||
* @peer_adv_stats: if populated, indicates peer adv (extd2) stats
|
||||
* @num_peer_adv_stats: number of peer adv (extd2) stats
|
||||
* @cca_stats: if populated indicates congestion stats
|
||||
* @num_summary_stats: number of summary stats
|
||||
* @vdev_summary_stats: if populated indicates array of summary stats per vdev
|
||||
@@ -291,12 +310,16 @@ struct chain_rssi_event {
|
||||
* @vdev_chain_rssi: if populated indicates array of chain rssi per vdev
|
||||
* @tx_rate: tx rate (kbps)
|
||||
* @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.
|
||||
*/
|
||||
struct stats_event {
|
||||
uint32_t num_pdev_stats;
|
||||
struct pdev_mc_cp_stats *pdev_stats;
|
||||
uint32_t num_peer_stats;
|
||||
struct peer_mc_cp_stats *peer_stats;
|
||||
uint32_t num_peer_adv_stats;
|
||||
struct peer_adv_mc_cp_stats *peer_adv_stats;
|
||||
struct congestion_stats_event *cca_stats;
|
||||
uint32_t num_summary_stats;
|
||||
struct summary_stats_event *vdev_summary_stats;
|
||||
@@ -305,6 +328,7 @@ struct stats_event {
|
||||
uint32_t tx_rate;
|
||||
uint32_t rx_rate;
|
||||
enum tx_rate_info tx_rate_flags;
|
||||
uint32_t last_event;
|
||||
};
|
||||
|
||||
#endif /* CONFIG_MCL */
|
||||
|
@@ -212,6 +212,54 @@ end:
|
||||
wlan_objmgr_peer_release_ref(peer, WLAN_CP_STATS_ID);
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
tgt_mc_cp_stats_update_peer_adv_stats(struct wlan_objmgr_psoc *psoc,
|
||||
struct peer_adv_mc_cp_stats
|
||||
*peer_adv_stats, uint32_t size)
|
||||
{
|
||||
uint8_t *peer_mac_addr;
|
||||
struct wlan_objmgr_peer *peer;
|
||||
struct peer_adv_mc_cp_stats *peer_adv_mc_stats;
|
||||
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||
struct peer_cp_stats *peer_cp_stats_priv;
|
||||
|
||||
if (!peer_adv_stats)
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
peer_mac_addr = peer_adv_stats->peer_macaddr;
|
||||
peer = wlan_objmgr_get_peer_by_mac(psoc, peer_mac_addr,
|
||||
WLAN_CP_STATS_ID);
|
||||
if (!peer) {
|
||||
cp_stats_err("peer is null");
|
||||
return QDF_STATUS_E_EXISTS;
|
||||
}
|
||||
peer_cp_stats_priv = wlan_cp_stats_get_peer_stats_obj(peer);
|
||||
if (!peer_cp_stats_priv) {
|
||||
cp_stats_err("peer_cp_stats_priv is null");
|
||||
status = QDF_STATUS_E_EXISTS;
|
||||
goto end;
|
||||
}
|
||||
wlan_cp_stats_peer_obj_lock(peer_cp_stats_priv);
|
||||
peer_adv_mc_stats = peer_cp_stats_priv->peer_adv_stats;
|
||||
|
||||
qdf_mem_copy(peer_adv_mc_stats->peer_macaddr,
|
||||
peer_adv_stats->peer_macaddr,
|
||||
WLAN_MACADDR_LEN);
|
||||
if (peer_adv_stats->fcs_count)
|
||||
peer_adv_mc_stats->fcs_count = peer_adv_stats->fcs_count;
|
||||
if (peer_adv_stats->rx_bytes)
|
||||
peer_adv_mc_stats->rx_bytes = peer_adv_stats->rx_bytes;
|
||||
if (peer_adv_stats->rx_count)
|
||||
peer_adv_mc_stats->rx_count = peer_adv_stats->rx_count;
|
||||
wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv);
|
||||
|
||||
end:
|
||||
if (peer)
|
||||
wlan_objmgr_peer_release_ref(peer, WLAN_CP_STATS_ID);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
tgt_mc_cp_stats_update_peer_stats(struct wlan_objmgr_psoc *psoc,
|
||||
struct peer_mc_cp_stats *peer_stats)
|
||||
@@ -273,10 +321,6 @@ static void tgt_mc_cp_stats_extract_peer_stats(struct wlan_objmgr_psoc *psoc,
|
||||
struct request_info last_req = {0};
|
||||
uint32_t selected;
|
||||
|
||||
if (!ev->peer_stats) {
|
||||
cp_stats_err("no peer stats");
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_station_stats)
|
||||
status = ucfg_mc_cp_stats_get_pending_req(psoc,
|
||||
@@ -292,6 +336,11 @@ static void tgt_mc_cp_stats_extract_peer_stats(struct wlan_objmgr_psoc *psoc,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ev->peer_stats) {
|
||||
cp_stats_debug("no peer stats");
|
||||
goto extd2_stats;
|
||||
}
|
||||
|
||||
selected = ev->num_peer_stats;
|
||||
for (i = 0; i < ev->num_peer_stats; i++) {
|
||||
status = tgt_mc_cp_stats_update_peer_stats(psoc,
|
||||
@@ -311,10 +360,40 @@ static void tgt_mc_cp_stats_extract_peer_stats(struct wlan_objmgr_psoc *psoc,
|
||||
/* no matched peer */
|
||||
if (!QDF_IS_ADDR_BROADCAST(last_req.peer_mac_addr) &&
|
||||
selected == ev->num_peer_stats) {
|
||||
cp_stats_err("peer not found stats");
|
||||
cp_stats_err("peer not found for stats");
|
||||
}
|
||||
|
||||
extd2_stats:
|
||||
|
||||
if (!ev->peer_adv_stats) {
|
||||
cp_stats_err("no peer_extd2 stats");
|
||||
goto complete;
|
||||
}
|
||||
selected = ev->num_peer_adv_stats;
|
||||
for (i = 0; i < ev->num_peer_adv_stats; i++) {
|
||||
status = tgt_mc_cp_stats_update_peer_adv_stats(
|
||||
psoc, &ev->peer_adv_stats[i],
|
||||
ev->num_peer_adv_stats);
|
||||
if (!QDF_IS_ADDR_BROADCAST(last_req.peer_mac_addr) &&
|
||||
!qdf_mem_cmp(ev->peer_adv_stats[i].peer_macaddr,
|
||||
last_req.peer_mac_addr,
|
||||
WLAN_MACADDR_LEN)) {
|
||||
/* mac is specified, but failed to update the peer */
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
return;
|
||||
|
||||
selected = i;
|
||||
}
|
||||
}
|
||||
|
||||
/* no matched peer */
|
||||
if (!QDF_IS_ADDR_BROADCAST(last_req.peer_mac_addr) &&
|
||||
selected == ev->num_peer_adv_stats) {
|
||||
cp_stats_err("peer not found for extd stats");
|
||||
return;
|
||||
}
|
||||
|
||||
complete:
|
||||
if (is_station_stats)
|
||||
return;
|
||||
|
||||
@@ -563,6 +642,10 @@ tgt_mc_cp_stats_prepare_n_send_raw_station_stats(struct wlan_objmgr_psoc *psoc,
|
||||
info.tx_rate_flags = vdev_mc_stats->tx_rate_flags;
|
||||
wlan_cp_stats_vdev_obj_unlock(vdev_cp_stats_priv);
|
||||
|
||||
info.peer_adv_stats = qdf_mem_malloc(sizeof(*info.peer_adv_stats));
|
||||
if (!info.peer_adv_stats)
|
||||
goto end;
|
||||
|
||||
wlan_cp_stats_peer_obj_lock(peer_cp_stats_priv);
|
||||
peer_mc_stats = peer_cp_stats_priv->peer_stats;
|
||||
/*
|
||||
@@ -571,6 +654,14 @@ tgt_mc_cp_stats_prepare_n_send_raw_station_stats(struct wlan_objmgr_psoc *psoc,
|
||||
*/
|
||||
info.tx_rate = peer_mc_stats->tx_rate / 100;
|
||||
info.rx_rate = peer_mc_stats->rx_rate / 100;
|
||||
|
||||
if (peer_cp_stats_priv->peer_adv_stats) {
|
||||
info.num_peer_adv_stats = 1;
|
||||
qdf_mem_copy(info.peer_adv_stats,
|
||||
peer_cp_stats_priv->peer_adv_stats,
|
||||
sizeof(peer_cp_stats_priv->peer_adv_stats));
|
||||
}
|
||||
|
||||
wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv);
|
||||
|
||||
end:
|
||||
@@ -590,10 +681,14 @@ static void tgt_mc_cp_stats_extract_station_stats(
|
||||
struct stats_event *ev)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
bool is_peer_stats;
|
||||
bool is_last_event;
|
||||
struct request_info last_req = {0};
|
||||
|
||||
is_peer_stats = (ev->peer_stats != NULL);
|
||||
if (IS_MSB_SET(ev->last_event))
|
||||
is_last_event = IS_LSB_SET(ev->last_event);
|
||||
else
|
||||
is_last_event = !!ev->peer_stats;
|
||||
|
||||
status = ucfg_mc_cp_stats_get_pending_req(psoc,
|
||||
TYPE_STATION_STATS,
|
||||
&last_req);
|
||||
@@ -611,7 +706,7 @@ static void tgt_mc_cp_stats_extract_station_stats(
|
||||
* PEER stats are the last stats sent for get_station statistics.
|
||||
* reset type_map bit for station stats .
|
||||
*/
|
||||
if (is_peer_stats) {
|
||||
if (is_last_event) {
|
||||
tgt_mc_cp_stats_prepare_n_send_raw_station_stats(psoc,
|
||||
&last_req);
|
||||
ucfg_mc_cp_stats_reset_pending_req(psoc, TYPE_STATION_STATS);
|
||||
|
@@ -85,11 +85,20 @@ QDF_STATUS wlan_cp_stats_peer_cs_init(struct peer_cp_stats *peer_cs)
|
||||
if (!peer_cs->peer_stats)
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
|
||||
peer_cs->peer_adv_stats = qdf_mem_malloc(sizeof
|
||||
(struct peer_adv_mc_cp_stats));
|
||||
if (!peer_cs->peer_adv_stats) {
|
||||
cp_stats_err("malloc failed");
|
||||
qdf_mem_free(peer_cs->peer_stats);
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
QDF_STATUS wlan_cp_stats_peer_cs_deinit(struct peer_cp_stats *peer_cs)
|
||||
{
|
||||
qdf_mem_free(peer_cs->peer_adv_stats);
|
||||
peer_cs->peer_adv_stats = NULL;
|
||||
qdf_mem_free(peer_cs->peer_stats);
|
||||
peer_cs->peer_stats = NULL;
|
||||
return QDF_STATUS_SUCCESS;
|
||||
@@ -554,6 +563,7 @@ void ucfg_mc_cp_stats_free_stats_resources(struct stats_event *ev)
|
||||
return;
|
||||
|
||||
qdf_mem_free(ev->pdev_stats);
|
||||
qdf_mem_free(ev->peer_adv_stats);
|
||||
qdf_mem_free(ev->peer_stats);
|
||||
qdf_mem_free(ev->cca_stats);
|
||||
qdf_mem_free(ev->vdev_summary_stats);
|
||||
|
Referencia en una nueva incidencia
Block a user