|
@@ -323,7 +323,7 @@ static void ath10k_debug_fw_stats_reset(struct ath10k *ar)
|
|
|
void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb)
|
|
|
{
|
|
|
struct ath10k_fw_stats stats = {};
|
|
|
- bool is_start, is_started, is_end, peer_stats_svc;
|
|
|
+ bool is_start, is_started, is_end;
|
|
|
size_t num_peers;
|
|
|
size_t num_vdevs;
|
|
|
int ret;
|
|
@@ -350,13 +350,11 @@ void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb)
|
|
|
* b) consume stat update events until another one with pdev stats is
|
|
|
* delivered which is treated as end-of-data and is itself discarded
|
|
|
*/
|
|
|
-
|
|
|
- peer_stats_svc = test_bit(WMI_SERVICE_PEER_STATS, ar->wmi.svc_map);
|
|
|
- if (peer_stats_svc)
|
|
|
+ if (ath10k_peer_stats_enabled(ar))
|
|
|
ath10k_sta_update_rx_duration(ar, &stats.peers);
|
|
|
|
|
|
if (ar->debug.fw_stats_done) {
|
|
|
- if (!peer_stats_svc)
|
|
|
+ if (!ath10k_peer_stats_enabled(ar))
|
|
|
ath10k_warn(ar, "received unsolicited stats update event\n");
|
|
|
|
|
|
goto free;
|
|
@@ -2184,6 +2182,73 @@ static const struct file_operations fops_btcoex = {
|
|
|
.open = simple_open
|
|
|
};
|
|
|
|
|
|
+static ssize_t ath10k_write_peer_stats(struct file *file,
|
|
|
+ const char __user *ubuf,
|
|
|
+ size_t count, loff_t *ppos)
|
|
|
+{
|
|
|
+ struct ath10k *ar = file->private_data;
|
|
|
+ char buf[32];
|
|
|
+ size_t buf_size;
|
|
|
+ int ret = 0;
|
|
|
+ bool val;
|
|
|
+
|
|
|
+ buf_size = min(count, (sizeof(buf) - 1));
|
|
|
+ if (copy_from_user(buf, ubuf, buf_size))
|
|
|
+ return -EFAULT;
|
|
|
+
|
|
|
+ buf[buf_size] = '\0';
|
|
|
+
|
|
|
+ if (strtobool(buf, &val) != 0)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ mutex_lock(&ar->conf_mutex);
|
|
|
+
|
|
|
+ if (ar->state != ATH10K_STATE_ON &&
|
|
|
+ ar->state != ATH10K_STATE_RESTARTED) {
|
|
|
+ ret = -ENETDOWN;
|
|
|
+ goto exit;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!(test_bit(ATH10K_FLAG_PEER_STATS, &ar->dev_flags) ^ val))
|
|
|
+ goto exit;
|
|
|
+
|
|
|
+ if (val)
|
|
|
+ set_bit(ATH10K_FLAG_PEER_STATS, &ar->dev_flags);
|
|
|
+ else
|
|
|
+ clear_bit(ATH10K_FLAG_PEER_STATS, &ar->dev_flags);
|
|
|
+
|
|
|
+ ath10k_info(ar, "restarting firmware due to Peer stats change");
|
|
|
+
|
|
|
+ queue_work(ar->workqueue, &ar->restart_work);
|
|
|
+ ret = count;
|
|
|
+
|
|
|
+exit:
|
|
|
+ mutex_unlock(&ar->conf_mutex);
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+static ssize_t ath10k_read_peer_stats(struct file *file, char __user *ubuf,
|
|
|
+ size_t count, loff_t *ppos)
|
|
|
+
|
|
|
+{
|
|
|
+ char buf[32];
|
|
|
+ struct ath10k *ar = file->private_data;
|
|
|
+ int len = 0;
|
|
|
+
|
|
|
+ mutex_lock(&ar->conf_mutex);
|
|
|
+ len = scnprintf(buf, sizeof(buf) - len, "%d\n",
|
|
|
+ test_bit(ATH10K_FLAG_PEER_STATS, &ar->dev_flags));
|
|
|
+ mutex_unlock(&ar->conf_mutex);
|
|
|
+
|
|
|
+ return simple_read_from_buffer(ubuf, count, ppos, buf, len);
|
|
|
+}
|
|
|
+
|
|
|
+static const struct file_operations fops_peer_stats = {
|
|
|
+ .read = ath10k_read_peer_stats,
|
|
|
+ .write = ath10k_write_peer_stats,
|
|
|
+ .open = simple_open
|
|
|
+};
|
|
|
+
|
|
|
static ssize_t ath10k_debug_fw_checksums_read(struct file *file,
|
|
|
char __user *user_buf,
|
|
|
size_t count, loff_t *ppos)
|
|
@@ -2347,6 +2412,11 @@ int ath10k_debug_register(struct ath10k *ar)
|
|
|
debugfs_create_file("btcoex", S_IRUGO | S_IWUSR,
|
|
|
ar->debug.debugfs_phy, ar, &fops_btcoex);
|
|
|
|
|
|
+ if (test_bit(WMI_SERVICE_PEER_STATS, ar->wmi.svc_map))
|
|
|
+ debugfs_create_file("peer_stats", S_IRUGO | S_IWUSR,
|
|
|
+ ar->debug.debugfs_phy, ar,
|
|
|
+ &fops_peer_stats);
|
|
|
+
|
|
|
debugfs_create_file("fw_checksums", S_IRUSR,
|
|
|
ar->debug.debugfs_phy, ar, &fops_fw_checksums);
|
|
|
|