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
This commit is contained in:
Krishna Kumaar Natarajan 2017-03-08 16:05:05 -08:00 • committed by snandini
commit 7bff29b84a
3 changed files with 95 additions and 14 deletions

View file

@ -1016,7 +1016,8 @@ static void hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
" 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 @@ static void hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
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++;
}

View file

@ -4823,6 +4823,9 @@ typedef struct {
/* 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 @@ typedef struct {
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 @@ typedef struct {
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

View file

@ -1484,6 +1484,8 @@ static int wma_unified_link_radio_stats_event_handler(void *handle,
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 @@ static int wma_unified_link_radio_stats_event_handler(void *handle,
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 @@ int wma_unified_link_iface_stats_event_handler(void *handle,
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 @@ int wma_unified_link_iface_stats_event_handler(void *handle,
* 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 @@ int wma_unified_link_iface_stats_event_handler(void *handle,
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 @@ int wma_unified_link_iface_stats_event_handler(void *handle,
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