diff --git a/core/hdd/src/wlan_hdd_stats.c b/core/hdd/src/wlan_hdd_stats.c index b956a9ace728..9844189eafbb 100644 --- a/core/hdd/src/wlan_hdd_stats.c +++ b/core/hdd/src/wlan_hdd_stats.c @@ -3020,6 +3020,69 @@ static inline void wlan_hdd_fill_station_info_signal(struct station_info #define linkspeed_dbg(format, args...) #endif /* LINKSPEED_DEBUG_ENABLED */ +/** + * wlan_hdd_fill_summary_stats() - populate station_info summary stats + * @stats: summary stats to use as a source + * @info: kernel station_info struct to use as a destination + * + * Return: None + */ +static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats, + struct station_info *info) +{ + int i; + + info->rx_packets = stats->rx_frm_cnt; + info->tx_packets = 0; + info->tx_retries = 0; + info->tx_failed = 0; + + for (i = 0; i < WIFI_MAX_AC; ++i) { + info->tx_packets += stats->tx_frm_cnt[i]; + info->tx_retries += stats->multiple_retry_cnt[i]; + info->tx_failed += stats->fail_cnt[i]; + } + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && !defined(WITH_BACKPORTS) + info->filled |= STATION_INFO_TX_PACKETS | + STATION_INFO_TX_RETRIES | + STATION_INFO_TX_FAILED | + STATION_INFO_RX_PACKETS; +#else + info->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) | + BIT(NL80211_STA_INFO_TX_PACKETS) | + BIT(NL80211_STA_INFO_TX_RETRIES) | + BIT(NL80211_STA_INFO_TX_FAILED); +#endif +} + +/** + * wlan_hdd_get_sap_stats() - get aggregate SAP stats + * @adapter: sap adapter to get stats for + * @info: kernel station_info struct to populate + * + * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to + * support "station dump" and "station get" for SAP vdevs, even though they + * aren't technically stations. + * + * Return: errno + */ +static int +wlan_hdd_get_sap_stats(hdd_adapter_t *adapter, struct station_info *info) +{ + QDF_STATUS status; + + status = wlan_hdd_get_station_stats(adapter); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("Failed to get SAP stats; status:%d", status); + return qdf_status_to_os_return(status); + } + + wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info); + + return 0; +} + /** * __wlan_hdd_cfg80211_get_station() - get station statistics * @wiphy: Pointer to wiphy @@ -3075,11 +3138,18 @@ static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, return -EINVAL; } + status = wlan_hdd_validate_context(pHddCtx); + if (status) + return status; + if (wlan_hdd_validate_session_id(pAdapter->sessionId)) { hdd_err("invalid session id: %d", pAdapter->sessionId); return -EINVAL; } + if (pAdapter->device_mode == QDF_SAP_MODE) + return wlan_hdd_get_sap_stats(pAdapter, sinfo); + if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) || (0 == ssidlen)) { hdd_debug("Not associated or Invalid ssidlen, %d", @@ -3100,11 +3170,6 @@ static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, return 0; } - status = wlan_hdd_validate_context(pHddCtx); - - if (0 != status) - return status; - wlan_hdd_get_station_stats(pAdapter); if (pAdapter->hdd_stats.summary_stat.rssi) @@ -3472,26 +3537,8 @@ static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, } } + wlan_hdd_fill_summary_stats(&pAdapter->hdd_stats.summary_stat, sinfo); sinfo->tx_bytes = pAdapter->stats.tx_bytes; - - sinfo->tx_packets = - pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] + - pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] + - pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] + - pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3]; - - sinfo->tx_retries = - pAdapter->hdd_stats.summary_stat.multiple_retry_cnt[0] + - pAdapter->hdd_stats.summary_stat.multiple_retry_cnt[1] + - pAdapter->hdd_stats.summary_stat.multiple_retry_cnt[2] + - pAdapter->hdd_stats.summary_stat.multiple_retry_cnt[3]; - - sinfo->tx_failed = - pAdapter->hdd_stats.summary_stat.fail_cnt[0] + - pAdapter->hdd_stats.summary_stat.fail_cnt[1] + - pAdapter->hdd_stats.summary_stat.fail_cnt[2] + - pAdapter->hdd_stats.summary_stat.fail_cnt[3]; - sinfo->rx_bytes = pAdapter->stats.rx_bytes; sinfo->rx_packets = pAdapter->stats.rx_packets; @@ -3501,17 +3548,11 @@ static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && !defined(WITH_BACKPORTS) sinfo->filled |= STATION_INFO_TX_BITRATE | STATION_INFO_TX_BYTES | - STATION_INFO_TX_PACKETS | - STATION_INFO_TX_RETRIES | - STATION_INFO_TX_FAILED | STATION_INFO_RX_BYTES | STATION_INFO_RX_PACKETS; #else - sinfo->filled |= BIT(NL80211_STA_INFO_TX_BYTES) | - BIT(NL80211_STA_INFO_TX_BITRATE) | - BIT(NL80211_STA_INFO_TX_PACKETS) | - BIT(NL80211_STA_INFO_TX_RETRIES) | - BIT(NL80211_STA_INFO_TX_FAILED) | + sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE) | + BIT(NL80211_STA_INFO_TX_BYTES) | BIT(NL80211_STA_INFO_RX_BYTES) | BIT(NL80211_STA_INFO_RX_PACKETS); #endif diff --git a/core/sme/src/csr/csr_cmd_process.c b/core/sme/src/csr/csr_cmd_process.c index ebaa52180851..5a9dd8d6da25 100644 --- a/core/sme/src/csr/csr_cmd_process.c +++ b/core/sme/src/csr/csr_cmd_process.c @@ -76,6 +76,13 @@ QDF_STATUS csr_msg_processor(tpAniSirGlobal mac_ctx, void *msg_buf) break; default: + if (sme_rsp->messageType == + eWNI_SME_GET_STATISTICS_RSP) { + csr_roam_joined_state_msg_processor(mac_ctx, + msg_buf); + break; + } + /* * For all other messages, we ignore it * To work-around an issue where checking for set/remove