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