summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/ath/ath10k/wmi-tlv.c
diff options
context:
space:
mode:
authorSurabhi Vishnoi <svishnoi@codeaurora.org>2019-02-26 15:23:16 +0530
committerKalle Valo <kvalo@codeaurora.org>2019-02-28 10:48:19 +0200
commitf40a307eb92c45a4acf813efcda90b17d50d25c3 (patch)
treeb2ac4e505b5ae57a69e6e1ba53e7115cff83b975 /drivers/net/wireless/ath/ath10k/wmi-tlv.c
parentd23c2cdaa01360ddc8ca01cd34b964e4621e6381 (diff)
ath10k: Fill rx duration for each peer in fw_stats for WCN3990
Currently, rx_duration for each peer is not getting populated in fw_stats debugfs entry for WCN3990. WCN3990 firmware sends rx duration for each peer as part of peer_extd_stats in WMI_UPDATE_STATS_EVENT. To enable peer_extd_stats, firmware expects host to send fw_stats_req_mask with flag WMI_TLV_PEER_STATS_EXTD set in WMI_REQUEST_STATS_CMD. Send fw_stats_req_mask with flag WMI_TLV_PEER_STATS_EXTD set in WMI_REQUEST_STATS_CMD and parse the peer_extd_stats in WMI_UPDATE_STATS_EVENT to populate the rx_duration of each peer in fw_stats debugfs entry. Currently the driver handles 32-bit rx_duration, but the rx_duration for WCN3990 can be upto 63 bit. The firmware sends rx_duration split into two 32-bit fields, with the upper 32-bits being valid only if its MSB is set. This change handles the 63-bit rx_duration obtained from WCN3990 and maintain the backward compatibility. To get the rx_duration of each connected peer : cat /sys/kernel/debug/ieee80211/phyX/ath10k/fw_stats Tested HW: WCN3990 Tested FW: WLAN.HL.3.1-00784-QCAHLSWMTPLZ-1 Signed-off-by: Surabhi Vishnoi <svishnoi@codeaurora.org> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless/ath/ath10k/wmi-tlv.c')
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-tlv.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
index 890887eb886a..582fb11f648a 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -13,6 +13,7 @@
#include "wmi-tlv.h"
#include "p2p.h"
#include "testmode.h"
+#include <linux/bitfield.h>
/***************/
/* TLV helpers */
@@ -1296,6 +1297,7 @@ static int ath10k_wmi_tlv_op_pull_fw_stats(struct ath10k *ar,
{
const void **tb;
const struct wmi_tlv_stats_ev *ev;
+ u32 num_peer_stats_extd;
const void *data;
u32 num_pdev_stats;
u32 num_vdev_stats;
@@ -1303,6 +1305,7 @@ static int ath10k_wmi_tlv_op_pull_fw_stats(struct ath10k *ar,
u32 num_bcnflt_stats;
u32 num_chan_stats;
size_t data_len;
+ u32 stats_id;
int ret;
int i;
@@ -1327,11 +1330,13 @@ static int ath10k_wmi_tlv_op_pull_fw_stats(struct ath10k *ar,
num_peer_stats = __le32_to_cpu(ev->num_peer_stats);
num_bcnflt_stats = __le32_to_cpu(ev->num_bcnflt_stats);
num_chan_stats = __le32_to_cpu(ev->num_chan_stats);
+ stats_id = __le32_to_cpu(ev->stats_id);
+ num_peer_stats_extd = __le32_to_cpu(ev->num_peer_stats_extd);
ath10k_dbg(ar, ATH10K_DBG_WMI,
- "wmi tlv stats update pdev %i vdev %i peer %i bcnflt %i chan %i\n",
+ "wmi tlv stats update pdev %i vdev %i peer %i bcnflt %i chan %i peer_extd %i\n",
num_pdev_stats, num_vdev_stats, num_peer_stats,
- num_bcnflt_stats, num_chan_stats);
+ num_bcnflt_stats, num_chan_stats, num_peer_stats_extd);
for (i = 0; i < num_pdev_stats; i++) {
const struct wmi_pdev_stats *src;
@@ -1396,6 +1401,28 @@ static int ath10k_wmi_tlv_op_pull_fw_stats(struct ath10k *ar,
ath10k_wmi_pull_peer_stats(&src->old, dst);
dst->peer_rx_rate = __le32_to_cpu(src->peer_rx_rate);
+
+ if (stats_id & WMI_TLV_STAT_PEER_EXTD) {
+ const struct wmi_tlv_peer_stats_extd *extd;
+ unsigned long rx_duration_high;
+
+ extd = data + sizeof(*src) * (num_peer_stats - i - 1)
+ + sizeof(*extd) * i;
+
+ dst->rx_duration = __le32_to_cpu(extd->rx_duration);
+ rx_duration_high = __le32_to_cpu
+ (extd->rx_duration_high);
+
+ if (test_bit(WMI_TLV_PEER_RX_DURATION_HIGH_VALID_BIT,
+ &rx_duration_high)) {
+ rx_duration_high =
+ FIELD_GET(WMI_TLV_PEER_RX_DURATION_HIGH_MASK,
+ rx_duration_high);
+ dst->rx_duration |= (u64)rx_duration_high <<
+ WMI_TLV_PEER_RX_DURATION_SHIFT;
+ }
+ }
+
list_add_tail(&dst->list, &stats->peers);
}