From 0f7cb26830a6e740455a7064e46ff1e926197ecb Mon Sep 17 00:00:00 2001 From: Wen Gong Date: Mon, 27 Apr 2020 16:04:14 +0800 Subject: ath10k: add rx bitrate report for SDIO For SDIO chip, its rx indication is struct htt_rx_indication_hl, which does not include the bitrate info as well as PCIe, for PCIe, it use function ath10k_htt_rx_h_rates to parse the bitrate info in struct rx_ppdu_start and then report it to mac80211 via ieee80211_rx_status. SDIO does not have the same info as PCIe, then iw command can not get the rx bitrate by "iw wlan0 station dump". for example, it always show 6.0 MBit/s localhost ~ # iw wlan0 link Connected to 3c:28:6d:96:fd:69 (on wlan0) SSID: kukui_test freq: 5180 RX: 111800 bytes (595 packets) TX: 35419 bytes (202 packets) signal: -41 dBm rx bitrate: 6.0 MBit/s This patch is to send WMI_TLV_REQUEST_PEER_STATS_INFO_CMDID to firmware for ath10k_sta_statistics and save the rx bitrate for WMI event WMI_TLV_PEER_STATS_INFO_EVENTID. This patch only effect SDIO chip, ath10k_mac_sta_get_peer_stats_info has check for bitrate_statistics of hw_params, this patch only enable it for "qca6174 hw3.2 sdio". Tested with QCA6174 SDIO firmware WLAN.RMH.4.4.1-00042. Signed-off-by: Wen Gong Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200427080416.8265-3-wgong@codeaurora.org --- drivers/net/wireless/ath/ath10k/mac.c | 40 +++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'drivers/net/wireless/ath/ath10k/mac.c') diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 0fb082c9d04b..d0401d3adde4 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -8305,6 +8305,44 @@ static void ath10k_mac_op_sta_pre_rcu_remove(struct ieee80211_hw *hw, peer->removed = true; } +static void ath10k_mac_sta_get_peer_stats_info(struct ath10k *ar, + struct ieee80211_sta *sta, + struct station_info *sinfo) +{ + struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv; + struct ath10k_peer *peer; + unsigned long time_left; + int ret; + + if (!(ar->hw_params.supports_peer_stats_info && + arsta->arvif->vdev_type == WMI_VDEV_TYPE_STA)) + return; + + spin_lock_bh(&ar->data_lock); + peer = ath10k_peer_find(ar, arsta->arvif->vdev_id, sta->addr); + spin_unlock_bh(&ar->data_lock); + if (!peer) + return; + + reinit_completion(&ar->peer_stats_info_complete); + + ret = ath10k_wmi_request_peer_stats_info(ar, + arsta->arvif->vdev_id, + WMI_REQUEST_ONE_PEER_STATS_INFO, + arsta->arvif->bssid, + 0); + if (ret && ret != -EOPNOTSUPP) { + ath10k_warn(ar, "could not request peer stats info: %d\n", ret); + return; + } + + time_left = wait_for_completion_timeout(&ar->peer_stats_info_complete, 3 * HZ); + if (time_left == 0) { + ath10k_warn(ar, "timed out waiting peer stats info\n"); + return; + } +} + static void ath10k_sta_statistics(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta, @@ -8340,6 +8378,8 @@ static void ath10k_sta_statistics(struct ieee80211_hw *hw, sinfo->tx_failed = arsta->tx_failed; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); } + + ath10k_mac_sta_get_peer_stats_info(ar, sta, sinfo); } static const struct ieee80211_ops ath10k_ops = { -- cgit