qcacld-3.0: Extract vdev extended summary stats event
In case of MLO connection, firmware sends each vdev's status information via vdev extended stats event. Add support in driver, to extract that information. Change-Id: Ia7a0a92baf008e6549830672b68e58be5a8202df CRs-Fixed: 3483731
This commit is contained in:
parent
032ace6233
commit
4924b2aaf5
@ -441,6 +441,16 @@ struct pmf_bcn_protect_stats {
|
||||
uint32_t bcn_replay_cnt;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct vdev_summary_extd_stats - vdev summary extended stats
|
||||
* @vdev_id: vdev_id of the event
|
||||
* @is_mlo_vdev_active: is the mlo vdev currently active
|
||||
*/
|
||||
struct vdev_summary_extd_stats {
|
||||
uint8_t vdev_id;
|
||||
bool is_mlo_vdev_active;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct vdev_mc_cp_stats - vdev specific stats
|
||||
* @cca: cca stats
|
||||
@ -448,6 +458,7 @@ struct pmf_bcn_protect_stats {
|
||||
* @chain_rssi: chain rssi
|
||||
* @vdev_summary_stats: vdev's summary stats
|
||||
* @pmf_bcn_stats: pmf beacon protect stats
|
||||
* @vdev_extd_stats: vdev summary extended stats
|
||||
*/
|
||||
struct vdev_mc_cp_stats {
|
||||
struct cca_stats cca;
|
||||
@ -455,6 +466,7 @@ struct vdev_mc_cp_stats {
|
||||
int8_t chain_rssi[MAX_NUM_CHAINS];
|
||||
struct summary_stats vdev_summary_stats;
|
||||
struct pmf_bcn_protect_stats pmf_bcn_stats;
|
||||
struct vdev_summary_extd_stats vdev_extd_stats;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -746,6 +758,8 @@ struct peer_stats_info_ext_event {
|
||||
* @num_peer_stats_info_ext: number of peer extended stats info
|
||||
* @peer_stats_info_ext: peer extended stats info
|
||||
* @bcn_protect_stats: pmf bcn protect stats
|
||||
* @num_vdev_extd_stats: number of vdev extended stats
|
||||
* @vdev_extd_stats: if populated indicates array of ext summary stats per vdev
|
||||
*/
|
||||
struct stats_event {
|
||||
uint32_t num_pdev_stats;
|
||||
@ -774,6 +788,8 @@ struct stats_event {
|
||||
uint32_t num_peer_stats_info_ext;
|
||||
struct peer_stats_info_ext_event *peer_stats_info_ext;
|
||||
struct pmf_bcn_protect_stats bcn_protect_stats;
|
||||
uint32_t num_vdev_extd_stats;
|
||||
struct vdev_summary_extd_stats *vdev_extd_stats;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1009,6 +1009,55 @@ static void tgt_mc_cp_stats_extract_vdev_chain_rssi_stats(
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tgt_mc_cp_stats_extract_vdev_extd_stats(struct wlan_objmgr_psoc *psoc,
|
||||
struct stats_event *ev)
|
||||
{
|
||||
uint8_t i, vdev_id;
|
||||
QDF_STATUS status;
|
||||
struct request_info last_req = {0};
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
struct vdev_mc_cp_stats *vdev_mc_stats;
|
||||
struct vdev_cp_stats *vdev_cp_stats_priv;
|
||||
|
||||
if (!ev->vdev_extd_stats)
|
||||
return;
|
||||
|
||||
status = ucfg_mc_cp_stats_get_pending_req(psoc, TYPE_STATION_STATS,
|
||||
&last_req);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
cp_stats_err("ucfg_mc_cp_stats_get_pending_req failed");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < ev->num_vdev_extd_stats; i++) {
|
||||
vdev_id = ev->vdev_extd_stats[i].vdev_id;
|
||||
|
||||
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
|
||||
WLAN_CP_STATS_ID);
|
||||
if (!vdev) {
|
||||
cp_stats_err("vdev is null");
|
||||
return;
|
||||
}
|
||||
|
||||
vdev_cp_stats_priv = wlan_cp_stats_get_vdev_stats_obj(vdev);
|
||||
if (!vdev_cp_stats_priv) {
|
||||
cp_stats_err("vdev cp stats object is null");
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
|
||||
return;
|
||||
}
|
||||
|
||||
wlan_cp_stats_vdev_obj_lock(vdev_cp_stats_priv);
|
||||
vdev_mc_stats = vdev_cp_stats_priv->vdev_stats;
|
||||
qdf_mem_copy(&vdev_mc_stats->vdev_extd_stats,
|
||||
&ev->vdev_extd_stats[i],
|
||||
sizeof(vdev_mc_stats->vdev_extd_stats));
|
||||
|
||||
wlan_cp_stats_vdev_obj_unlock(vdev_cp_stats_priv);
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
|
||||
}
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
tgt_send_vdev_mc_cp_stats(struct wlan_objmgr_psoc *psoc,
|
||||
struct stats_event *ev,
|
||||
@ -1046,6 +1095,11 @@ tgt_send_vdev_mc_cp_stats(struct wlan_objmgr_psoc *psoc,
|
||||
ev->tx_rate_flags = vdev_mc_stats->tx_rate_flags;
|
||||
|
||||
ev->bcn_protect_stats = vdev_mc_stats->pmf_bcn_stats;
|
||||
|
||||
qdf_mem_copy(&ev->vdev_extd_stats[0],
|
||||
&vdev_mc_stats->vdev_extd_stats,
|
||||
sizeof(vdev_mc_stats->vdev_extd_stats));
|
||||
|
||||
wlan_cp_stats_vdev_obj_unlock(vdev_cp_stats_priv);
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
|
||||
|
||||
@ -1171,10 +1225,15 @@ tgt_mc_cp_stats_send_raw_station_stats(struct wlan_objmgr_psoc *psoc,
|
||||
|
||||
info.num_summary_stats = 1;
|
||||
info.num_chain_rssi_stats = 1;
|
||||
info.num_vdev_extd_stats = 1;
|
||||
info.vdev_summary_stats = qdf_mem_malloc(
|
||||
sizeof(*info.vdev_summary_stats));
|
||||
info.vdev_chain_rssi = qdf_mem_malloc(sizeof(*info.vdev_chain_rssi));
|
||||
if (!info.vdev_summary_stats || !info.vdev_chain_rssi)
|
||||
|
||||
info.vdev_extd_stats = qdf_mem_malloc(sizeof(*info.vdev_extd_stats));
|
||||
|
||||
if (!info.vdev_summary_stats || !info.vdev_chain_rssi ||
|
||||
!info.vdev_extd_stats)
|
||||
goto end;
|
||||
|
||||
status = tgt_send_vdev_mc_cp_stats(psoc, &info, last_req);
|
||||
@ -1263,6 +1322,7 @@ static void tgt_mc_cp_stats_extract_station_stats(
|
||||
tgt_mc_cp_stats_extract_vdev_summary_stats(psoc, ev);
|
||||
tgt_mc_cp_stats_extract_vdev_chain_rssi_stats(psoc, ev);
|
||||
tgt_mc_cp_stats_extract_pmf_bcn_stats(psoc, ev);
|
||||
tgt_mc_cp_stats_extract_vdev_extd_stats(psoc, ev);
|
||||
|
||||
/*
|
||||
* PEER stats are the last stats sent for get_station statistics.
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. 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
|
||||
@ -975,6 +975,7 @@ void ucfg_mc_cp_stats_free_stats_resources(struct stats_event *ev)
|
||||
qdf_mem_free(ev->vdev_chain_rssi);
|
||||
qdf_mem_free(ev->peer_extended_stats);
|
||||
ucfg_mc_cp_stats_free_peer_stats_info_ext(ev);
|
||||
qdf_mem_free(ev->vdev_extd_stats);
|
||||
qdf_mem_zero(ev, sizeof(*ev));
|
||||
}
|
||||
|
||||
|
@ -383,6 +383,8 @@ static void target_if_cp_stats_free_stats_event(struct stats_event *ev)
|
||||
ev->vdev_chain_rssi = NULL;
|
||||
target_if_cp_stats_free_mib_stats(ev);
|
||||
target_if_cp_stats_free_peer_stats_info_ext(ev);
|
||||
qdf_mem_free(ev->vdev_extd_stats);
|
||||
ev->vdev_extd_stats = NULL;
|
||||
}
|
||||
|
||||
static QDF_STATUS target_if_cp_stats_extract_pdev_stats(
|
||||
@ -858,6 +860,61 @@ static QDF_STATUS target_if_cp_stats_extract_vdev_chain_rssi_stats(
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
target_if_cp_stats_extract_vdev_extd_stats(struct wmi_unified *wmi_hdl,
|
||||
wmi_host_stats_event *stats_param,
|
||||
struct stats_event *ev,
|
||||
uint8_t *data)
|
||||
{
|
||||
uint8_t i;
|
||||
QDF_STATUS status;
|
||||
struct wmi_host_vdev_prb_fils_stats *stats;
|
||||
|
||||
ev->num_vdev_extd_stats = stats_param->num_vdev_extd_stats;
|
||||
if (!ev->num_vdev_extd_stats)
|
||||
return QDF_STATUS_SUCCESS;
|
||||
|
||||
if (ev->num_vdev_extd_stats > WLAN_MAX_MLD) {
|
||||
cp_stats_err("num_vdev_extd_stats is invalid: %u",
|
||||
ev->num_vdev_extd_stats);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
ev->vdev_extd_stats = qdf_mem_malloc(sizeof(*ev->vdev_extd_stats) *
|
||||
ev->num_vdev_extd_stats);
|
||||
if (!ev->vdev_extd_stats)
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
|
||||
stats = qdf_mem_malloc(sizeof(*stats) * ev->num_vdev_extd_stats);
|
||||
|
||||
if (!stats) {
|
||||
cp_stats_err("malloc failed for vdev extended stats");
|
||||
status = QDF_STATUS_E_NOMEM;
|
||||
goto end;
|
||||
}
|
||||
|
||||
for (i = 0 ; i < ev->num_vdev_extd_stats; i++) {
|
||||
status = wmi_extract_vdev_prb_fils_stats(wmi_hdl, data,
|
||||
i, stats);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
cp_stats_err("wmi_extract_vdev_extd_stats failed");
|
||||
qdf_mem_free(stats);
|
||||
goto end;
|
||||
}
|
||||
ev->vdev_extd_stats[i].vdev_id = stats[i].vdev_id;
|
||||
ev->vdev_extd_stats[i].is_mlo_vdev_active =
|
||||
stats[i].is_mlo_vdev_active;
|
||||
}
|
||||
|
||||
qdf_mem_free(stats);
|
||||
return status;
|
||||
|
||||
end:
|
||||
qdf_mem_free(ev->vdev_extd_stats);
|
||||
ev->vdev_extd_stats = NULL;
|
||||
return status;
|
||||
}
|
||||
|
||||
static QDF_STATUS target_if_cp_stats_extract_event(struct wmi_unified *wmi_hdl,
|
||||
struct stats_event *ev,
|
||||
uint8_t *data)
|
||||
@ -870,13 +927,14 @@ static QDF_STATUS target_if_cp_stats_extract_event(struct wmi_unified *wmi_hdl,
|
||||
cp_stats_err("stats param extract failed: %d", status);
|
||||
return status;
|
||||
}
|
||||
cp_stats_nofl_debug("num: pdev: %d, pdev_extd: %d, vdev: %d, peer: %d,"
|
||||
"peer_extd: %d rssi: %d, mib %d, mib_extd %d, "
|
||||
"bcnflt: %d, channel: %d, bcn: %d, peer_extd2: %d,"
|
||||
cp_stats_nofl_debug("num: pdev: %d, pdev_extd: %d, vdev: %d, vdev_extd: %d, "
|
||||
"peer: %d, peer_extd: %d rssi: %d, mib %d, mib_extd %d, "
|
||||
"bcnflt: %d, channel: %d, bcn: %d, peer_extd2: %d, "
|
||||
"last_event: %x, stats id: %d",
|
||||
stats_param.num_pdev_stats,
|
||||
stats_param.num_pdev_ext_stats,
|
||||
stats_param.num_vdev_stats,
|
||||
stats_param.num_vdev_extd_stats,
|
||||
stats_param.num_peer_stats,
|
||||
stats_param.num_peer_extd_stats,
|
||||
stats_param.num_rssi_stats,
|
||||
@ -932,7 +990,12 @@ static QDF_STATUS target_if_cp_stats_extract_event(struct wmi_unified *wmi_hdl,
|
||||
status = target_if_cp_stats_extract_pdev_extd_stats(wmi_hdl,
|
||||
&stats_param,
|
||||
ev, data);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
return status;
|
||||
|
||||
status = target_if_cp_stats_extract_vdev_extd_stats(wmi_hdl,
|
||||
&stats_param,
|
||||
ev, data);
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -1550,6 +1613,7 @@ static uint32_t get_stats_id(enum stats_req_type type)
|
||||
return (WMI_REQUEST_AP_STAT |
|
||||
WMI_REQUEST_PEER_STAT |
|
||||
WMI_REQUEST_VDEV_STAT |
|
||||
WMI_REQUEST_VDEV_EXTD_STAT |
|
||||
WMI_REQUEST_PDEV_STAT |
|
||||
WMI_REQUEST_PEER_EXTD2_STAT |
|
||||
WMI_REQUEST_RSSI_PER_CHAIN_STAT |
|
||||
|
@ -1017,6 +1017,7 @@ enum udp_qos_upgrade {
|
||||
* @snr: SNR measured from @rssi
|
||||
* @rssi_on_disconnect: Rssi at disconnection time in STA mode
|
||||
* @rssi_send: Notify RSSI over lpass
|
||||
* @is_mlo_vdev_active: is the mlo vdev currently active
|
||||
*/
|
||||
struct wlan_hdd_link_info {
|
||||
uint8_t vdev_id;
|
||||
@ -1035,6 +1036,7 @@ struct wlan_hdd_link_info {
|
||||
#ifdef WLAN_FEATURE_LPSS
|
||||
bool rssi_send;
|
||||
#endif
|
||||
bool is_mlo_vdev_active;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -273,6 +273,10 @@ static int copy_station_stats_to_adapter(struct hdd_adapter *adapter,
|
||||
adapter->tx_power.tx_pwr = stats->pdev_stats->max_pwr;
|
||||
adapter->tx_power.tx_pwr_cached_timestamp =
|
||||
qdf_system_ticks_to_msecs(qdf_system_ticks());
|
||||
/* Copy vdev status info sent by FW */
|
||||
if (stats->vdev_extd_stats)
|
||||
adapter->deflink->is_mlo_vdev_active =
|
||||
stats->vdev_extd_stats[0].is_mlo_vdev_active;
|
||||
|
||||
dynamic_cfg = mlme_get_dynamic_vdev_config(vdev);
|
||||
if (!dynamic_cfg) {
|
||||
|
@ -162,6 +162,7 @@ static void wlan_cfg80211_mc_cp_stats_dealloc(void *priv)
|
||||
qdf_mem_free(stats->peer_adv_stats);
|
||||
wlan_cfg80211_mc_cp_stats_free_peer_stats_info_ext(stats);
|
||||
wlan_free_mib_stats(stats);
|
||||
qdf_mem_free(stats->vdev_extd_stats);
|
||||
}
|
||||
|
||||
#define QCA_WLAN_VENDOR_ATTR_TOTAL_DRIVER_FW_LOCAL_WAKE \
|
||||
@ -586,6 +587,7 @@ static void get_station_stats_cb(struct stats_event *ev, void *cookie)
|
||||
struct stats_event *priv;
|
||||
struct osif_request *request;
|
||||
uint32_t summary_size, rssi_size, peer_adv_size = 0, pdev_size;
|
||||
uint32_t vdev_extd_size;
|
||||
|
||||
request = osif_request_get(cookie);
|
||||
if (!request) {
|
||||
@ -644,6 +646,17 @@ static void get_station_stats_cb(struct stats_event *ev, void *cookie)
|
||||
qdf_mem_copy(priv->pdev_stats, ev->pdev_stats, pdev_size);
|
||||
}
|
||||
|
||||
if (ev->num_vdev_extd_stats && ev->vdev_extd_stats) {
|
||||
vdev_extd_size =
|
||||
sizeof(*ev->vdev_extd_stats) * ev->num_vdev_extd_stats;
|
||||
priv->vdev_extd_stats = qdf_mem_malloc(vdev_extd_size);
|
||||
if (!priv->vdev_extd_stats)
|
||||
goto station_stats_cb_fail;
|
||||
|
||||
qdf_mem_copy(priv->vdev_extd_stats, ev->vdev_extd_stats,
|
||||
vdev_extd_size);
|
||||
}
|
||||
|
||||
priv->num_summary_stats = ev->num_summary_stats;
|
||||
priv->num_chain_rssi_stats = ev->num_chain_rssi_stats;
|
||||
priv->tx_rate = ev->tx_rate;
|
||||
@ -1117,6 +1130,9 @@ wlan_cfg80211_mc_cp_stats_get_station_stats(struct wlan_objmgr_vdev *vdev,
|
||||
if (priv->pdev_stats)
|
||||
out->pdev_stats = priv->pdev_stats;
|
||||
priv->pdev_stats = NULL;
|
||||
if (priv->vdev_extd_stats)
|
||||
out->vdev_extd_stats = priv->vdev_extd_stats;
|
||||
priv->vdev_extd_stats = NULL;
|
||||
|
||||
out->bcn_protect_stats = priv->bcn_protect_stats;
|
||||
osif_request_put(request);
|
||||
@ -1713,6 +1729,7 @@ void wlan_cfg80211_mc_cp_stats_free_stats_event(struct stats_event *stats)
|
||||
qdf_mem_free(stats->peer_adv_stats);
|
||||
wlan_free_mib_stats(stats);
|
||||
wlan_cfg80211_mc_cp_stats_free_peer_stats_info_ext(stats);
|
||||
qdf_mem_free(stats->vdev_extd_stats);
|
||||
qdf_mem_free(stats);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user