GNU Linux-libre 6.8.7-gnu
[releases.git] / drivers / net / wireless / ath / ath10k / debugfs_sta.c
1 // SPDX-License-Identifier: ISC
2 /*
3  * Copyright (c) 2014-2017 Qualcomm Atheros, Inc.
4  * Copyright (c) 2018, The Linux Foundation. All rights reserved.
5  * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
6  */
7
8 #include "core.h"
9 #include "wmi-ops.h"
10 #include "txrx.h"
11 #include "debug.h"
12
13 static void ath10k_rx_stats_update_amsdu_subfrm(struct ath10k *ar,
14                                                 struct ath10k_sta_tid_stats *stats,
15                                                 u32 msdu_count)
16 {
17         if (msdu_count == 1)
18                 stats->rx_pkt_amsdu[ATH10K_AMSDU_SUBFRM_NUM_1]++;
19         else if (msdu_count == 2)
20                 stats->rx_pkt_amsdu[ATH10K_AMSDU_SUBFRM_NUM_2]++;
21         else if (msdu_count == 3)
22                 stats->rx_pkt_amsdu[ATH10K_AMSDU_SUBFRM_NUM_3]++;
23         else if (msdu_count == 4)
24                 stats->rx_pkt_amsdu[ATH10K_AMSDU_SUBFRM_NUM_4]++;
25         else if (msdu_count > 4)
26                 stats->rx_pkt_amsdu[ATH10K_AMSDU_SUBFRM_NUM_MORE]++;
27 }
28
29 static void ath10k_rx_stats_update_ampdu_subfrm(struct ath10k *ar,
30                                                 struct ath10k_sta_tid_stats *stats,
31                                                 u32 mpdu_count)
32 {
33         if (mpdu_count <= 10)
34                 stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_10]++;
35         else if (mpdu_count <= 20)
36                 stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_20]++;
37         else if (mpdu_count <= 30)
38                 stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_30]++;
39         else if (mpdu_count <= 40)
40                 stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_40]++;
41         else if (mpdu_count <= 50)
42                 stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_50]++;
43         else if (mpdu_count <= 60)
44                 stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_60]++;
45         else if (mpdu_count > 60)
46                 stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_MORE]++;
47 }
48
49 void ath10k_sta_update_rx_tid_stats_ampdu(struct ath10k *ar, u16 peer_id, u8 tid,
50                                           struct htt_rx_indication_mpdu_range *ranges,
51                                           int num_ranges)
52 {
53         struct ath10k_sta *arsta;
54         struct ath10k_peer *peer;
55         int i;
56
57         if (tid > IEEE80211_NUM_TIDS || !(ar->sta_tid_stats_mask & BIT(tid)))
58                 return;
59
60         rcu_read_lock();
61         spin_lock_bh(&ar->data_lock);
62
63         peer = ath10k_peer_find_by_id(ar, peer_id);
64         if (!peer || !peer->sta)
65                 goto out;
66
67         arsta = (struct ath10k_sta *)peer->sta->drv_priv;
68
69         for (i = 0; i < num_ranges; i++)
70                 ath10k_rx_stats_update_ampdu_subfrm(ar,
71                                                     &arsta->tid_stats[tid],
72                                                     ranges[i].mpdu_count);
73
74 out:
75         spin_unlock_bh(&ar->data_lock);
76         rcu_read_unlock();
77 }
78
79 void ath10k_sta_update_rx_tid_stats(struct ath10k *ar, u8 *first_hdr,
80                                     unsigned long num_msdus,
81                                     enum ath10k_pkt_rx_err err,
82                                     unsigned long unchain_cnt,
83                                     unsigned long drop_cnt,
84                                     unsigned long drop_cnt_filter,
85                                     unsigned long queued_msdus)
86 {
87         struct ieee80211_sta *sta;
88         struct ath10k_sta *arsta;
89         struct ieee80211_hdr *hdr;
90         struct ath10k_sta_tid_stats *stats;
91         u8 tid = IEEE80211_NUM_TIDS;
92         bool non_data_frm = false;
93
94         hdr = (struct ieee80211_hdr *)first_hdr;
95         if (!ieee80211_is_data(hdr->frame_control))
96                 non_data_frm = true;
97
98         if (ieee80211_is_data_qos(hdr->frame_control))
99                 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
100
101         if (!(ar->sta_tid_stats_mask & BIT(tid)) || non_data_frm)
102                 return;
103
104         rcu_read_lock();
105
106         sta = ieee80211_find_sta_by_ifaddr(ar->hw, hdr->addr2, NULL);
107         if (!sta)
108                 goto exit;
109
110         arsta = (struct ath10k_sta *)sta->drv_priv;
111
112         spin_lock_bh(&ar->data_lock);
113         stats = &arsta->tid_stats[tid];
114         stats->rx_pkt_from_fw += num_msdus;
115         stats->rx_pkt_unchained += unchain_cnt;
116         stats->rx_pkt_drop_chained += drop_cnt;
117         stats->rx_pkt_drop_filter += drop_cnt_filter;
118         if (err != ATH10K_PKT_RX_ERR_MAX)
119                 stats->rx_pkt_err[err] += queued_msdus;
120         stats->rx_pkt_queued_for_mac += queued_msdus;
121         ath10k_rx_stats_update_amsdu_subfrm(ar, &arsta->tid_stats[tid],
122                                             num_msdus);
123         spin_unlock_bh(&ar->data_lock);
124
125 exit:
126         rcu_read_unlock();
127 }
128
129 static void ath10k_sta_update_extd_stats_rx_duration(struct ath10k *ar,
130                                                      struct ath10k_fw_stats *stats)
131 {
132         struct ath10k_fw_extd_stats_peer *peer;
133         struct ieee80211_sta *sta;
134         struct ath10k_sta *arsta;
135
136         rcu_read_lock();
137         list_for_each_entry(peer, &stats->peers_extd, list) {
138                 sta = ieee80211_find_sta_by_ifaddr(ar->hw, peer->peer_macaddr,
139                                                    NULL);
140                 if (!sta)
141                         continue;
142                 arsta = (struct ath10k_sta *)sta->drv_priv;
143                 arsta->rx_duration += (u64)peer->rx_duration;
144         }
145         rcu_read_unlock();
146 }
147
148 static void ath10k_sta_update_stats_rx_duration(struct ath10k *ar,
149                                                 struct ath10k_fw_stats *stats)
150 {
151         struct ath10k_fw_stats_peer *peer;
152         struct ieee80211_sta *sta;
153         struct ath10k_sta *arsta;
154
155         rcu_read_lock();
156         list_for_each_entry(peer, &stats->peers, list) {
157                 sta = ieee80211_find_sta_by_ifaddr(ar->hw, peer->peer_macaddr,
158                                                    NULL);
159                 if (!sta)
160                         continue;
161                 arsta = (struct ath10k_sta *)sta->drv_priv;
162                 arsta->rx_duration += (u64)peer->rx_duration;
163         }
164         rcu_read_unlock();
165 }
166
167 void ath10k_sta_update_rx_duration(struct ath10k *ar,
168                                    struct ath10k_fw_stats *stats)
169 {
170         if (stats->extended)
171                 ath10k_sta_update_extd_stats_rx_duration(ar, stats);
172         else
173                 ath10k_sta_update_stats_rx_duration(ar, stats);
174 }
175
176 static ssize_t ath10k_dbg_sta_read_aggr_mode(struct file *file,
177                                              char __user *user_buf,
178                                              size_t count, loff_t *ppos)
179 {
180         struct ieee80211_sta *sta = file->private_data;
181         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
182         struct ath10k *ar = arsta->arvif->ar;
183         char buf[32];
184         int len = 0;
185
186         mutex_lock(&ar->conf_mutex);
187         len = scnprintf(buf, sizeof(buf) - len, "aggregation mode: %s\n",
188                         (arsta->aggr_mode == ATH10K_DBG_AGGR_MODE_AUTO) ?
189                         "auto" : "manual");
190         mutex_unlock(&ar->conf_mutex);
191
192         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
193 }
194
195 static ssize_t ath10k_dbg_sta_write_aggr_mode(struct file *file,
196                                               const char __user *user_buf,
197                                               size_t count, loff_t *ppos)
198 {
199         struct ieee80211_sta *sta = file->private_data;
200         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
201         struct ath10k *ar = arsta->arvif->ar;
202         u32 aggr_mode;
203         int ret;
204
205         if (kstrtouint_from_user(user_buf, count, 0, &aggr_mode))
206                 return -EINVAL;
207
208         if (aggr_mode >= ATH10K_DBG_AGGR_MODE_MAX)
209                 return -EINVAL;
210
211         mutex_lock(&ar->conf_mutex);
212         if ((ar->state != ATH10K_STATE_ON) ||
213             (aggr_mode == arsta->aggr_mode)) {
214                 ret = count;
215                 goto out;
216         }
217
218         ret = ath10k_wmi_addba_clear_resp(ar, arsta->arvif->vdev_id, sta->addr);
219         if (ret) {
220                 ath10k_warn(ar, "failed to clear addba session ret: %d\n", ret);
221                 goto out;
222         }
223
224         arsta->aggr_mode = aggr_mode;
225 out:
226         mutex_unlock(&ar->conf_mutex);
227         return ret;
228 }
229
230 static const struct file_operations fops_aggr_mode = {
231         .read = ath10k_dbg_sta_read_aggr_mode,
232         .write = ath10k_dbg_sta_write_aggr_mode,
233         .open = simple_open,
234         .owner = THIS_MODULE,
235         .llseek = default_llseek,
236 };
237
238 static ssize_t ath10k_dbg_sta_write_addba(struct file *file,
239                                           const char __user *user_buf,
240                                           size_t count, loff_t *ppos)
241 {
242         struct ieee80211_sta *sta = file->private_data;
243         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
244         struct ath10k *ar = arsta->arvif->ar;
245         u32 tid, buf_size;
246         int ret;
247         char buf[64] = {0};
248
249         ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
250                                      user_buf, count);
251         if (ret <= 0)
252                 return ret;
253
254         ret = sscanf(buf, "%u %u", &tid, &buf_size);
255         if (ret != 2)
256                 return -EINVAL;
257
258         /* Valid TID values are 0 through 15 */
259         if (tid > HTT_DATA_TX_EXT_TID_MGMT - 2)
260                 return -EINVAL;
261
262         mutex_lock(&ar->conf_mutex);
263         if ((ar->state != ATH10K_STATE_ON) ||
264             (arsta->aggr_mode != ATH10K_DBG_AGGR_MODE_MANUAL)) {
265                 ret = count;
266                 goto out;
267         }
268
269         ret = ath10k_wmi_addba_send(ar, arsta->arvif->vdev_id, sta->addr,
270                                     tid, buf_size);
271         if (ret) {
272                 ath10k_warn(ar, "failed to send addba request: vdev_id %u peer %pM tid %u buf_size %u\n",
273                             arsta->arvif->vdev_id, sta->addr, tid, buf_size);
274         }
275
276         ret = count;
277 out:
278         mutex_unlock(&ar->conf_mutex);
279         return ret;
280 }
281
282 static const struct file_operations fops_addba = {
283         .write = ath10k_dbg_sta_write_addba,
284         .open = simple_open,
285         .owner = THIS_MODULE,
286         .llseek = default_llseek,
287 };
288
289 static ssize_t ath10k_dbg_sta_write_addba_resp(struct file *file,
290                                                const char __user *user_buf,
291                                                size_t count, loff_t *ppos)
292 {
293         struct ieee80211_sta *sta = file->private_data;
294         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
295         struct ath10k *ar = arsta->arvif->ar;
296         u32 tid, status;
297         int ret;
298         char buf[64] = {0};
299
300         ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
301                                      user_buf, count);
302         if (ret <= 0)
303                 return ret;
304
305         ret = sscanf(buf, "%u %u", &tid, &status);
306         if (ret != 2)
307                 return -EINVAL;
308
309         /* Valid TID values are 0 through 15 */
310         if (tid > HTT_DATA_TX_EXT_TID_MGMT - 2)
311                 return -EINVAL;
312
313         mutex_lock(&ar->conf_mutex);
314         if ((ar->state != ATH10K_STATE_ON) ||
315             (arsta->aggr_mode != ATH10K_DBG_AGGR_MODE_MANUAL)) {
316                 ret = count;
317                 goto out;
318         }
319
320         ret = ath10k_wmi_addba_set_resp(ar, arsta->arvif->vdev_id, sta->addr,
321                                         tid, status);
322         if (ret) {
323                 ath10k_warn(ar, "failed to send addba response: vdev_id %u peer %pM tid %u status%u\n",
324                             arsta->arvif->vdev_id, sta->addr, tid, status);
325         }
326         ret = count;
327 out:
328         mutex_unlock(&ar->conf_mutex);
329         return ret;
330 }
331
332 static const struct file_operations fops_addba_resp = {
333         .write = ath10k_dbg_sta_write_addba_resp,
334         .open = simple_open,
335         .owner = THIS_MODULE,
336         .llseek = default_llseek,
337 };
338
339 static ssize_t ath10k_dbg_sta_write_delba(struct file *file,
340                                           const char __user *user_buf,
341                                           size_t count, loff_t *ppos)
342 {
343         struct ieee80211_sta *sta = file->private_data;
344         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
345         struct ath10k *ar = arsta->arvif->ar;
346         u32 tid, initiator, reason;
347         int ret;
348         char buf[64] = {0};
349
350         ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
351                                      user_buf, count);
352         if (ret <= 0)
353                 return ret;
354
355         ret = sscanf(buf, "%u %u %u", &tid, &initiator, &reason);
356         if (ret != 3)
357                 return -EINVAL;
358
359         /* Valid TID values are 0 through 15 */
360         if (tid > HTT_DATA_TX_EXT_TID_MGMT - 2)
361                 return -EINVAL;
362
363         mutex_lock(&ar->conf_mutex);
364         if ((ar->state != ATH10K_STATE_ON) ||
365             (arsta->aggr_mode != ATH10K_DBG_AGGR_MODE_MANUAL)) {
366                 ret = count;
367                 goto out;
368         }
369
370         ret = ath10k_wmi_delba_send(ar, arsta->arvif->vdev_id, sta->addr,
371                                     tid, initiator, reason);
372         if (ret) {
373                 ath10k_warn(ar, "failed to send delba: vdev_id %u peer %pM tid %u initiator %u reason %u\n",
374                             arsta->arvif->vdev_id, sta->addr, tid, initiator,
375                             reason);
376         }
377         ret = count;
378 out:
379         mutex_unlock(&ar->conf_mutex);
380         return ret;
381 }
382
383 static const struct file_operations fops_delba = {
384         .write = ath10k_dbg_sta_write_delba,
385         .open = simple_open,
386         .owner = THIS_MODULE,
387         .llseek = default_llseek,
388 };
389
390 static ssize_t ath10k_dbg_sta_read_peer_debug_trigger(struct file *file,
391                                                       char __user *user_buf,
392                                                       size_t count,
393                                                       loff_t *ppos)
394 {
395         struct ieee80211_sta *sta = file->private_data;
396         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
397         struct ath10k *ar = arsta->arvif->ar;
398         char buf[8];
399         int len = 0;
400
401         mutex_lock(&ar->conf_mutex);
402         len = scnprintf(buf, sizeof(buf) - len,
403                         "Write 1 to once trigger the debug logs\n");
404         mutex_unlock(&ar->conf_mutex);
405
406         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
407 }
408
409 static ssize_t
410 ath10k_dbg_sta_write_peer_debug_trigger(struct file *file,
411                                         const char __user *user_buf,
412                                         size_t count, loff_t *ppos)
413 {
414         struct ieee80211_sta *sta = file->private_data;
415         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
416         struct ath10k *ar = arsta->arvif->ar;
417         u8 peer_debug_trigger;
418         int ret;
419
420         if (kstrtou8_from_user(user_buf, count, 0, &peer_debug_trigger))
421                 return -EINVAL;
422
423         if (peer_debug_trigger != 1)
424                 return -EINVAL;
425
426         mutex_lock(&ar->conf_mutex);
427
428         if (ar->state != ATH10K_STATE_ON) {
429                 ret = -ENETDOWN;
430                 goto out;
431         }
432
433         ret = ath10k_wmi_peer_set_param(ar, arsta->arvif->vdev_id, sta->addr,
434                                         ar->wmi.peer_param->debug, peer_debug_trigger);
435         if (ret) {
436                 ath10k_warn(ar, "failed to set param to trigger peer tid logs for station ret: %d\n",
437                             ret);
438                 goto out;
439         }
440 out:
441         mutex_unlock(&ar->conf_mutex);
442         return count;
443 }
444
445 static const struct file_operations fops_peer_debug_trigger = {
446         .open = simple_open,
447         .read = ath10k_dbg_sta_read_peer_debug_trigger,
448         .write = ath10k_dbg_sta_write_peer_debug_trigger,
449         .owner = THIS_MODULE,
450         .llseek = default_llseek,
451 };
452
453 static ssize_t ath10k_dbg_sta_read_peer_ps_state(struct file *file,
454                                                  char __user *user_buf,
455                                                  size_t count, loff_t *ppos)
456 {
457         struct ieee80211_sta *sta = file->private_data;
458         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
459         struct ath10k *ar = arsta->arvif->ar;
460         char buf[20];
461         int len = 0;
462
463         spin_lock_bh(&ar->data_lock);
464
465         len = scnprintf(buf, sizeof(buf) - len, "%d\n",
466                         arsta->peer_ps_state);
467
468         spin_unlock_bh(&ar->data_lock);
469
470         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
471 }
472
473 static const struct file_operations fops_peer_ps_state = {
474         .open = simple_open,
475         .read = ath10k_dbg_sta_read_peer_ps_state,
476         .owner = THIS_MODULE,
477         .llseek = default_llseek,
478 };
479
480 static char *get_err_str(enum ath10k_pkt_rx_err i)
481 {
482         switch (i) {
483         case ATH10K_PKT_RX_ERR_FCS:
484                 return "fcs_err";
485         case ATH10K_PKT_RX_ERR_TKIP:
486                 return "tkip_err";
487         case ATH10K_PKT_RX_ERR_CRYPT:
488                 return "crypt_err";
489         case ATH10K_PKT_RX_ERR_PEER_IDX_INVAL:
490                 return "peer_idx_inval";
491         case ATH10K_PKT_RX_ERR_MAX:
492                 return "unknown";
493         }
494
495         return "unknown";
496 }
497
498 static char *get_num_ampdu_subfrm_str(enum ath10k_ampdu_subfrm_num i)
499 {
500         switch (i) {
501         case ATH10K_AMPDU_SUBFRM_NUM_10:
502                 return "up to 10";
503         case ATH10K_AMPDU_SUBFRM_NUM_20:
504                 return "11-20";
505         case ATH10K_AMPDU_SUBFRM_NUM_30:
506                 return "21-30";
507         case ATH10K_AMPDU_SUBFRM_NUM_40:
508                 return "31-40";
509         case ATH10K_AMPDU_SUBFRM_NUM_50:
510                 return "41-50";
511         case ATH10K_AMPDU_SUBFRM_NUM_60:
512                 return "51-60";
513         case ATH10K_AMPDU_SUBFRM_NUM_MORE:
514                 return ">60";
515         case ATH10K_AMPDU_SUBFRM_NUM_MAX:
516                 return "0";
517         }
518
519         return "0";
520 }
521
522 static char *get_num_amsdu_subfrm_str(enum ath10k_amsdu_subfrm_num i)
523 {
524         switch (i) {
525         case ATH10K_AMSDU_SUBFRM_NUM_1:
526                 return "1";
527         case ATH10K_AMSDU_SUBFRM_NUM_2:
528                 return "2";
529         case ATH10K_AMSDU_SUBFRM_NUM_3:
530                 return "3";
531         case ATH10K_AMSDU_SUBFRM_NUM_4:
532                 return "4";
533         case ATH10K_AMSDU_SUBFRM_NUM_MORE:
534                 return ">4";
535         case ATH10K_AMSDU_SUBFRM_NUM_MAX:
536                 return "0";
537         }
538
539         return "0";
540 }
541
542 #define PRINT_TID_STATS(_field, _tabs) \
543         do { \
544                 int k = 0; \
545                 for (j = 0; j <= IEEE80211_NUM_TIDS; j++) { \
546                         if (ar->sta_tid_stats_mask & BIT(j))  { \
547                                 len += scnprintf(buf + len, buf_len - len, \
548                                                  "[%02d] %-10lu  ", \
549                                                  j, stats[j]._field); \
550                                 k++; \
551                                 if (k % 8 == 0)  { \
552                                         len += scnprintf(buf + len, \
553                                                          buf_len - len, "\n"); \
554                                         len += scnprintf(buf + len, \
555                                                          buf_len - len, \
556                                                          _tabs); \
557                                 } \
558                         } \
559                 } \
560                 len += scnprintf(buf + len, buf_len - len, "\n"); \
561         } while (0)
562
563 static ssize_t ath10k_dbg_sta_read_tid_stats(struct file *file,
564                                              char __user *user_buf,
565                                              size_t count, loff_t *ppos)
566 {
567         struct ieee80211_sta *sta = file->private_data;
568         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
569         struct ath10k *ar = arsta->arvif->ar;
570         struct ath10k_sta_tid_stats *stats = arsta->tid_stats;
571         size_t len = 0, buf_len = 1048 * IEEE80211_NUM_TIDS;
572         char *buf;
573         int i, j;
574         ssize_t ret;
575
576         buf = kzalloc(buf_len, GFP_KERNEL);
577         if (!buf)
578                 return -ENOMEM;
579
580         mutex_lock(&ar->conf_mutex);
581
582         spin_lock_bh(&ar->data_lock);
583
584         len += scnprintf(buf + len, buf_len - len,
585                          "\n\t\tDriver Rx pkt stats per tid, ([tid] count)\n");
586         len += scnprintf(buf + len, buf_len - len,
587                          "\t\t------------------------------------------\n");
588         len += scnprintf(buf + len, buf_len - len, "MSDUs from FW\t\t\t");
589         PRINT_TID_STATS(rx_pkt_from_fw, "\t\t\t\t");
590
591         len += scnprintf(buf + len, buf_len - len, "MSDUs unchained\t\t\t");
592         PRINT_TID_STATS(rx_pkt_unchained, "\t\t\t\t");
593
594         len += scnprintf(buf + len, buf_len - len,
595                          "MSDUs locally dropped:chained\t");
596         PRINT_TID_STATS(rx_pkt_drop_chained, "\t\t\t\t");
597
598         len += scnprintf(buf + len, buf_len - len,
599                          "MSDUs locally dropped:filtered\t");
600         PRINT_TID_STATS(rx_pkt_drop_filter, "\t\t\t\t");
601
602         len += scnprintf(buf + len, buf_len - len,
603                          "MSDUs queued for mac80211\t");
604         PRINT_TID_STATS(rx_pkt_queued_for_mac, "\t\t\t\t");
605
606         for (i = 0; i < ATH10K_PKT_RX_ERR_MAX; i++) {
607                 len += scnprintf(buf + len, buf_len - len,
608                                  "MSDUs with error:%s\t", get_err_str(i));
609                 PRINT_TID_STATS(rx_pkt_err[i], "\t\t\t\t");
610         }
611
612         len += scnprintf(buf + len, buf_len - len, "\n");
613         for (i = 0; i < ATH10K_AMPDU_SUBFRM_NUM_MAX; i++) {
614                 len += scnprintf(buf + len, buf_len - len,
615                                  "A-MPDU num subframes %s\t",
616                                  get_num_ampdu_subfrm_str(i));
617                 PRINT_TID_STATS(rx_pkt_ampdu[i], "\t\t\t\t");
618         }
619
620         len += scnprintf(buf + len, buf_len - len, "\n");
621         for (i = 0; i < ATH10K_AMSDU_SUBFRM_NUM_MAX; i++) {
622                 len += scnprintf(buf + len, buf_len - len,
623                                  "A-MSDU num subframes %s\t\t",
624                                  get_num_amsdu_subfrm_str(i));
625                 PRINT_TID_STATS(rx_pkt_amsdu[i], "\t\t\t\t");
626         }
627
628         spin_unlock_bh(&ar->data_lock);
629
630         ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
631
632         kfree(buf);
633
634         mutex_unlock(&ar->conf_mutex);
635
636         return ret;
637 }
638
639 static const struct file_operations fops_tid_stats_dump = {
640         .open = simple_open,
641         .read = ath10k_dbg_sta_read_tid_stats,
642         .owner = THIS_MODULE,
643         .llseek = default_llseek,
644 };
645
646 static ssize_t ath10k_dbg_sta_dump_tx_stats(struct file *file,
647                                             char __user *user_buf,
648                                             size_t count, loff_t *ppos)
649 {
650         struct ieee80211_sta *sta = file->private_data;
651         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
652         struct ath10k *ar = arsta->arvif->ar;
653         struct ath10k_htt_data_stats *stats;
654         const char *str_name[ATH10K_STATS_TYPE_MAX] = {"succ", "fail",
655                                                        "retry", "ampdu"};
656         const char *str[ATH10K_COUNTER_TYPE_MAX] = {"bytes", "packets"};
657         int len = 0, i, j, k, retval = 0;
658         const int size = 16 * 4096;
659         char *buf;
660
661         buf = kzalloc(size, GFP_KERNEL);
662         if (!buf)
663                 return -ENOMEM;
664
665         mutex_lock(&ar->conf_mutex);
666
667         if (!arsta->tx_stats) {
668                 ath10k_warn(ar, "failed to get tx stats");
669                 mutex_unlock(&ar->conf_mutex);
670                 kfree(buf);
671                 return 0;
672         }
673
674         spin_lock_bh(&ar->data_lock);
675         for (k = 0; k < ATH10K_STATS_TYPE_MAX; k++) {
676                 for (j = 0; j < ATH10K_COUNTER_TYPE_MAX; j++) {
677                         stats = &arsta->tx_stats->stats[k];
678                         len += scnprintf(buf + len, size - len, "%s_%s\n",
679                                          str_name[k],
680                                          str[j]);
681                         len += scnprintf(buf + len, size - len,
682                                          " VHT MCS %s\n",
683                                          str[j]);
684                         for (i = 0; i < ATH10K_VHT_MCS_NUM; i++)
685                                 len += scnprintf(buf + len, size - len,
686                                                  "  %llu ",
687                                                  stats->vht[j][i]);
688                         len += scnprintf(buf + len, size - len, "\n");
689                         len += scnprintf(buf + len, size - len, " HT MCS %s\n",
690                                          str[j]);
691                         for (i = 0; i < ATH10K_HT_MCS_NUM; i++)
692                                 len += scnprintf(buf + len, size - len,
693                                                  "  %llu ", stats->ht[j][i]);
694                         len += scnprintf(buf + len, size - len, "\n");
695                         len += scnprintf(buf + len, size - len,
696                                         " BW %s (20,5,10,40,80,160 MHz)\n", str[j]);
697                         len += scnprintf(buf + len, size - len,
698                                          "  %llu %llu %llu %llu %llu %llu\n",
699                                          stats->bw[j][0], stats->bw[j][1],
700                                          stats->bw[j][2], stats->bw[j][3],
701                                          stats->bw[j][4], stats->bw[j][5]);
702                         len += scnprintf(buf + len, size - len,
703                                          " NSS %s (1x1,2x2,3x3,4x4)\n", str[j]);
704                         len += scnprintf(buf + len, size - len,
705                                          "  %llu %llu %llu %llu\n",
706                                          stats->nss[j][0], stats->nss[j][1],
707                                          stats->nss[j][2], stats->nss[j][3]);
708                         len += scnprintf(buf + len, size - len,
709                                          " GI %s (LGI,SGI)\n",
710                                          str[j]);
711                         len += scnprintf(buf + len, size - len, "  %llu %llu\n",
712                                          stats->gi[j][0], stats->gi[j][1]);
713                         len += scnprintf(buf + len, size - len,
714                                          " legacy rate %s (1,2 ... Mbps)\n  ",
715                                          str[j]);
716                         for (i = 0; i < ATH10K_LEGACY_NUM; i++)
717                                 len += scnprintf(buf + len, size - len, "%llu ",
718                                                  stats->legacy[j][i]);
719                         len += scnprintf(buf + len, size - len, "\n");
720                         len += scnprintf(buf + len, size - len,
721                                          " Rate table %s (1,2 ... Mbps)\n  ",
722                                          str[j]);
723                         for (i = 0; i < ATH10K_RATE_TABLE_NUM; i++) {
724                                 len += scnprintf(buf + len, size - len, "%llu ",
725                                                  stats->rate_table[j][i]);
726                                 if (!((i + 1) % 8))
727                                         len +=
728                                         scnprintf(buf + len, size - len, "\n  ");
729                         }
730                 }
731         }
732
733         len += scnprintf(buf + len, size - len,
734                          "\nTX duration\n %llu usecs\n",
735                          arsta->tx_stats->tx_duration);
736         len += scnprintf(buf + len, size - len,
737                         "BA fails\n %llu\n", arsta->tx_stats->ba_fails);
738         len += scnprintf(buf + len, size - len,
739                         "ack fails\n %llu\n", arsta->tx_stats->ack_fails);
740         spin_unlock_bh(&ar->data_lock);
741
742         if (len > size)
743                 len = size;
744         retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
745         kfree(buf);
746
747         mutex_unlock(&ar->conf_mutex);
748         return retval;
749 }
750
751 static const struct file_operations fops_tx_stats = {
752         .read = ath10k_dbg_sta_dump_tx_stats,
753         .open = simple_open,
754         .owner = THIS_MODULE,
755         .llseek = default_llseek,
756 };
757
758 void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
759                             struct ieee80211_sta *sta, struct dentry *dir)
760 {
761         struct ath10k *ar = hw->priv;
762
763         debugfs_create_file("aggr_mode", 0644, dir, sta, &fops_aggr_mode);
764         debugfs_create_file("addba", 0200, dir, sta, &fops_addba);
765         debugfs_create_file("addba_resp", 0200, dir, sta, &fops_addba_resp);
766         debugfs_create_file("delba", 0200, dir, sta, &fops_delba);
767         debugfs_create_file("peer_debug_trigger", 0600, dir, sta,
768                             &fops_peer_debug_trigger);
769         debugfs_create_file("dump_tid_stats", 0400, dir, sta,
770                             &fops_tid_stats_dump);
771
772         if (ath10k_peer_stats_enabled(ar) &&
773             ath10k_debug_is_extd_tx_stats_enabled(ar))
774                 debugfs_create_file("tx_stats", 0400, dir, sta,
775                                     &fops_tx_stats);
776         debugfs_create_file("peer_ps_state", 0400, dir, sta,
777                             &fops_peer_ps_state);
778 }