qcacld-3.0: Add support to handle updated link layer stats
Add support to parse and store additional link layer stats
included as part of radio stats and interface stats.
Change-Id: Idbefa508f5e79221c3d7598e6b120454b56e2423
CRs-Fixed: 2018087
diff --git a/core/hdd/src/wlan_hdd_stats.c b/core/hdd/src/wlan_hdd_stats.c
index 99b2661..9e81a52 100644
--- a/core/hdd/src/wlan_hdd_stats.c
+++ b/core/hdd/src/wlan_hdd_stats.c
@@ -1016,7 +1016,8 @@
" onTimeScan: %u onTimeNbd: %u"
" onTimeGscan: %u onTimeRoamScan: %u"
" onTimePnoScan: %u onTimeHs20: %u"
- " numChannels: %u total_num_tx_pwr_levels: %u",
+ " numChannels: %u total_num_tx_pwr_levels: %u"
+ " on_time_host_scan: %u, on_time_lpi_scan: %u",
pWifiRadioStat->radio, pWifiRadioStat->onTime,
pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
@@ -1024,7 +1025,9 @@
pWifiRadioStat->onTimeRoamScan,
pWifiRadioStat->onTimePnoScan,
pWifiRadioStat->onTimeHs20, pWifiRadioStat->numChannels,
- pWifiRadioStat->total_num_tx_power_levels);
+ pWifiRadioStat->total_num_tx_power_levels,
+ pWifiRadioStat->on_time_host_scan,
+ pWifiRadioStat->on_time_lpi_scan);
pWifiRadioStat++;
}
diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h
index 2f7c0d6..94b4892 100644
--- a/core/mac/inc/sir_api.h
+++ b/core/mac/inc/sir_api.h
@@ -4823,6 +4823,9 @@
/* tx time (in milliseconds) per TPC level (0.5 dBm) */
uint32_t tx_time_per_tpc[MAX_TPC_LEVELS];
+ uint32_t on_time_host_scan;
+ uint32_t on_time_lpi_scan;
+
/* channel statistics tSirWifiChannelStats */
tSirWifiChannelStats *channels;
} tSirWifiRadioStat, *tpSirWifiRadioStat;
@@ -4883,6 +4886,22 @@
tSirWifiRateStat rateStats[0];
} tSirWifiPeerInfo, *tpSirWifiPeerInfo;
+/**
+ * struct wifi_iface_offload_stat - Wifi Iface offload statistics
+ * @type: type of offload stats (enum wmi_offload_stats_type)
+ * @rx_count: Number of (MSDUs) frames Received
+ * @drp_count: Number of frames Dropped
+ * @fwd_count:
+ * Number of frames for which FW Responded (Valid for ARP and NS only).(or)
+ * Number of frames forwarded to Host (Valid for stats type except ARP and NS).
+ */
+struct wifi_iface_offload_stat {
+ wmi_offload_stats_type type;
+ uint32_t rx_count;
+ uint32_t drp_count;
+ uint32_t fwd_count;
+};
+
/* per access category statistics */
typedef struct {
/* tSirWifiTrafficAc */
@@ -4981,8 +5000,23 @@
uint32_t rts_fail_cnt;
uint32_t ppdu_succ_cnt;
uint32_t ppdu_fail_cnt;
+
+ uint32_t tx_rts_succ_cnt;
+ uint32_t tx_rts_fail_cnt;
+ uint32_t tx_ppdu_succ_cnt;
+ uint32_t tx_ppdu_fail_cnt;
+ uint32_t connected_duration;
+ uint32_t disconnected_duration;
+ uint32_t rtt_ranging_duration;
+ uint32_t rtt_responder_duration;
+ uint32_t num_probes_tx;
+ uint32_t num_beacon_miss;
+
/* per ac data packet statistics */
tSirWifiWmmAcStat AccessclassStats[WIFI_AC_MAX];
+
+ uint32_t num_offload_stats;
+ struct wifi_iface_offload_stat offload_stat[WMI_OFFLOAD_STATS_TYPE_MAX];
} tSirWifiIfaceStat, *tpSirWifiIfaceStat;
/* Peer statistics - corresponding to 3rd most LSB in
diff --git a/core/wma/src/wma_utils.c b/core/wma/src/wma_utils.c
index 6aa09f0..4bf6922 100644
--- a/core/wma/src/wma_utils.c
+++ b/core/wma/src/wma_utils.c
@@ -1484,6 +1484,8 @@
WMA_LOGD("on_time_pno_scan: %u on_time_hs20: %u num_channels: %u",
radio_stats->on_time_pno_scan, radio_stats->on_time_hs20,
radio_stats->num_channels);
+ WMA_LOGD("on_time_host_scan: %u, on_time_lpi_scan: %u",
+ radio_stats->on_time_host_scan, radio_stats->on_time_lpi_scan);
link_stats_results->paramId = WMI_LINK_STATS_RADIO;
link_stats_results->rspId = fixed_param->request_id;
@@ -1519,6 +1521,8 @@
rs_results->total_num_tx_power_levels = 0;
rs_results->tx_time_per_power_level = NULL;
rs_results->numChannels = radio_stats->num_channels;
+ rs_results->on_time_host_scan = radio_stats->on_time_host_scan;
+ rs_results->on_time_lpi_scan = radio_stats->on_time_lpi_scan;
rs_results->channels = NULL;
if (rs_results->numChannels) {
@@ -1891,12 +1895,14 @@
wmi_iface_link_stats_event_fixed_param *fixed_param;
wmi_iface_link_stats *link_stats;
wmi_wmm_ac_stats *ac_stats;
+ wmi_iface_offload_stats *offload_stats;
tSirLLStatsResults *link_stats_results;
- uint8_t *results, *t_link_stats, *t_ac_stats;
- uint32_t next_res_offset, next_ac_offset, count;
- uint32_t roaming_offset, roaming_size;
+ uint8_t *results, *t_link_stats, *t_ac_stats, *t_offload_stats;
+ uint32_t next_res_offset, next_ac_offset, next_offload_offset, count;
+ uint32_t roaming_offset, size;
size_t link_stats_size, ac_stats_size, iface_info_size;
- size_t link_stats_results_size;
+ size_t link_stats_results_size, offload_stats_size;
+ size_t total_ac_size, total_offload_size;
tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE);
@@ -1921,20 +1927,30 @@
* wmi_iface_link_stats_event_fixed_param fixed_param;
* wmi_iface_link_stats iface_link_stats;
* iface_link_stats->num_ac * size of(struct wmi_wmm_ac_stats)
+ * fixed_param->num_offload_stats * size of(wmi_iface_offload_stats);
*/
fixed_param = param_tlvs->fixed_param;
link_stats = param_tlvs->iface_link_stats;
ac_stats = param_tlvs->ac;
+ offload_stats = param_tlvs->iface_offload_stats;
- if (!fixed_param || !link_stats || (link_stats->num_ac && !ac_stats)) {
+ if (!fixed_param || !link_stats || (link_stats->num_ac && !ac_stats) ||
+ (fixed_param->num_offload_stats && !offload_stats)) {
WMA_LOGA("%s: Invalid param_tlvs for Iface Stats", __func__);
return -EINVAL;
}
link_stats_size = sizeof(tSirWifiIfaceStat);
iface_info_size = sizeof(tSirWifiInterfaceInfo);
+
ac_stats_size = sizeof(tSirWifiWmmAcStat);
- link_stats_results_size = sizeof(*link_stats_results) + link_stats_size;
+ offload_stats_size = sizeof(struct wifi_iface_offload_stat);
+
+ total_ac_size = ac_stats_size * WIFI_AC_MAX;
+ total_offload_size = offload_stats_size * WMI_OFFLOAD_STATS_TYPE_MAX +
+ member_size(tSirWifiIfaceStat, num_offload_stats);
+
+ link_stats_results_size = sizeof(*link_stats_results) + link_stats_size;
link_stats_results = qdf_mem_malloc(link_stats_results_size);
if (!link_stats_results) {
@@ -1952,23 +1968,34 @@
link_stats_results->peer_event_number = 0;
link_stats_results->moreResultToFollow = 0;
+ /* results is copied to tSirWifiIfaceStat in upper layer
+ * tSirWifiIfaceStat
+ * - tSirWifiInterfaceInfo (all fields except roaming is
+ * filled by host in the upper layer)
+ * - various members of tSirWifiIfaceStat (from wmi_iface_link_stats)
+ * - ACs information (from wmi_wmm_ac_stats)
+ * - num_offload_stats (from fixed param)
+ * - offload stats (from wmi_iface_offload_stats)
+ */
+
results = (uint8_t *) link_stats_results->results;
t_link_stats = (uint8_t *) link_stats;
t_ac_stats = (uint8_t *) ac_stats;
+ t_offload_stats = (uint8_t *) offload_stats;
/* Copy roaming state */
roaming_offset = offsetof(tSirWifiInterfaceInfo, roaming);
- roaming_size = member_size(tSirWifiInterfaceInfo, roaming);
+ size = member_size(tSirWifiInterfaceInfo, roaming);
- qdf_mem_copy(results + roaming_offset, &link_stats->roam_state,
- roaming_size);
+ qdf_mem_copy(results + roaming_offset, &link_stats->roam_state, size);
- qdf_mem_copy(results + iface_info_size,
+ next_res_offset = iface_info_size;
+ qdf_mem_copy(results + next_res_offset,
t_link_stats + WMI_TLV_HDR_SIZE,
link_stats_size - iface_info_size -
- WIFI_AC_MAX * ac_stats_size);
+ total_ac_size - total_offload_size);
- next_res_offset = link_stats_size - WIFI_AC_MAX * ac_stats_size;
+ next_res_offset = link_stats_size - total_ac_size - total_offload_size;
next_ac_offset = WMI_TLV_HDR_SIZE;
for (count = 0; count < link_stats->num_ac; count++) {
@@ -1980,6 +2007,23 @@
next_ac_offset += sizeof(*ac_stats);
}
+ next_res_offset = link_stats_size - total_offload_size;
+ /* copy num_offload_stats into result */
+ size = member_size(tSirWifiIfaceStat, num_offload_stats);
+ qdf_mem_copy(results + next_res_offset, &fixed_param->num_offload_stats,
+ size);
+
+ next_res_offset += size;
+ next_offload_offset = WMI_TLV_HDR_SIZE;
+
+ for (count = 0; count < fixed_param->num_offload_stats; count++) {
+ qdf_mem_copy(results + next_res_offset,
+ t_offload_stats + next_offload_offset,
+ offload_stats_size);
+ next_res_offset += offload_stats_size;
+ next_offload_offset += sizeof(*offload_stats);
+ }
+
/* call hdd callback with Link Layer Statistics
* vdev_id/ifacId in link_stats_results will be
* used to retrieve the correct HDD context