ath10k: fix wmi service bitmap debug
[cascardo/linux.git] / drivers / net / wireless / ath / ath10k / debug.c
1 /*
2  * Copyright (c) 2005-2011 Atheros Communications Inc.
3  * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
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 <linux/module.h>
19 #include <linux/debugfs.h>
20
21 #include "core.h"
22 #include "debug.h"
23
24 /* ms */
25 #define ATH10K_DEBUG_HTT_STATS_INTERVAL 1000
26
27 static int ath10k_printk(const char *level, const char *fmt, ...)
28 {
29         struct va_format vaf;
30         va_list args;
31         int rtn;
32
33         va_start(args, fmt);
34
35         vaf.fmt = fmt;
36         vaf.va = &args;
37
38         rtn = printk("%sath10k: %pV", level, &vaf);
39
40         va_end(args);
41
42         return rtn;
43 }
44
45 int ath10k_info(const char *fmt, ...)
46 {
47         struct va_format vaf = {
48                 .fmt = fmt,
49         };
50         va_list args;
51         int ret;
52
53         va_start(args, fmt);
54         vaf.va = &args;
55         ret = ath10k_printk(KERN_INFO, "%pV", &vaf);
56         trace_ath10k_log_info(&vaf);
57         va_end(args);
58
59         return ret;
60 }
61 EXPORT_SYMBOL(ath10k_info);
62
63 int ath10k_err(const char *fmt, ...)
64 {
65         struct va_format vaf = {
66                 .fmt = fmt,
67         };
68         va_list args;
69         int ret;
70
71         va_start(args, fmt);
72         vaf.va = &args;
73         ret = ath10k_printk(KERN_ERR, "%pV", &vaf);
74         trace_ath10k_log_err(&vaf);
75         va_end(args);
76
77         return ret;
78 }
79 EXPORT_SYMBOL(ath10k_err);
80
81 int ath10k_warn(const char *fmt, ...)
82 {
83         struct va_format vaf = {
84                 .fmt = fmt,
85         };
86         va_list args;
87         int ret = 0;
88
89         va_start(args, fmt);
90         vaf.va = &args;
91
92         if (net_ratelimit())
93                 ret = ath10k_printk(KERN_WARNING, "%pV", &vaf);
94
95         trace_ath10k_log_warn(&vaf);
96
97         va_end(args);
98
99         return ret;
100 }
101 EXPORT_SYMBOL(ath10k_warn);
102
103 #ifdef CONFIG_ATH10K_DEBUGFS
104
105 void ath10k_debug_read_service_map(struct ath10k *ar,
106                                    void *service_map,
107                                    size_t map_size)
108 {
109         memcpy(ar->debug.wmi_service_bitmap, service_map, map_size);
110 }
111
112 static ssize_t ath10k_read_wmi_services(struct file *file,
113                                         char __user *user_buf,
114                                         size_t count, loff_t *ppos)
115 {
116         struct ath10k *ar = file->private_data;
117         char *buf;
118         unsigned int len = 0, buf_len = 4096;
119         const char *name;
120         ssize_t ret_cnt;
121         bool enabled;
122         int i;
123
124         buf = kzalloc(buf_len, GFP_KERNEL);
125         if (!buf)
126                 return -ENOMEM;
127
128         mutex_lock(&ar->conf_mutex);
129
130         if (len > buf_len)
131                 len = buf_len;
132
133         for (i = 0; i < WMI_MAX_SERVICE; i++) {
134                 enabled = test_bit(i, ar->debug.wmi_service_bitmap);
135                 name = wmi_service_name(i);
136
137                 if (!name) {
138                         if (enabled)
139                                 len += scnprintf(buf + len, buf_len - len,
140                                                  "%-40s %s (bit %d)\n",
141                                                  "unknown", "enabled", i);
142
143                         continue;
144                 }
145
146                 len += scnprintf(buf + len, buf_len - len,
147                                  "%-40s %s\n",
148                                  name, enabled ? "enabled" : "-");
149         }
150
151         ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
152
153         mutex_unlock(&ar->conf_mutex);
154
155         kfree(buf);
156         return ret_cnt;
157 }
158
159 static const struct file_operations fops_wmi_services = {
160         .read = ath10k_read_wmi_services,
161         .open = simple_open,
162         .owner = THIS_MODULE,
163         .llseek = default_llseek,
164 };
165
166 void ath10k_debug_read_target_stats(struct ath10k *ar,
167                                     struct wmi_stats_event *ev)
168 {
169         u8 *tmp = ev->data;
170         struct ath10k_target_stats *stats;
171         int num_pdev_stats, num_vdev_stats, num_peer_stats;
172         struct wmi_pdev_stats_10x *ps;
173         int i;
174
175         spin_lock_bh(&ar->data_lock);
176
177         stats = &ar->debug.target_stats;
178
179         num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats); /* 0 or 1 */
180         num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats); /* 0 or max vdevs */
181         num_peer_stats = __le32_to_cpu(ev->num_peer_stats); /* 0 or max peers */
182
183         if (num_pdev_stats) {
184                 ps = (struct wmi_pdev_stats_10x *)tmp;
185
186                 stats->ch_noise_floor = __le32_to_cpu(ps->chan_nf);
187                 stats->tx_frame_count = __le32_to_cpu(ps->tx_frame_count);
188                 stats->rx_frame_count = __le32_to_cpu(ps->rx_frame_count);
189                 stats->rx_clear_count = __le32_to_cpu(ps->rx_clear_count);
190                 stats->cycle_count = __le32_to_cpu(ps->cycle_count);
191                 stats->phy_err_count = __le32_to_cpu(ps->phy_err_count);
192                 stats->chan_tx_power = __le32_to_cpu(ps->chan_tx_pwr);
193
194                 stats->comp_queued = __le32_to_cpu(ps->wal.tx.comp_queued);
195                 stats->comp_delivered =
196                         __le32_to_cpu(ps->wal.tx.comp_delivered);
197                 stats->msdu_enqued = __le32_to_cpu(ps->wal.tx.msdu_enqued);
198                 stats->mpdu_enqued = __le32_to_cpu(ps->wal.tx.mpdu_enqued);
199                 stats->wmm_drop = __le32_to_cpu(ps->wal.tx.wmm_drop);
200                 stats->local_enqued = __le32_to_cpu(ps->wal.tx.local_enqued);
201                 stats->local_freed = __le32_to_cpu(ps->wal.tx.local_freed);
202                 stats->hw_queued = __le32_to_cpu(ps->wal.tx.hw_queued);
203                 stats->hw_reaped = __le32_to_cpu(ps->wal.tx.hw_reaped);
204                 stats->underrun = __le32_to_cpu(ps->wal.tx.underrun);
205                 stats->tx_abort = __le32_to_cpu(ps->wal.tx.tx_abort);
206                 stats->mpdus_requed = __le32_to_cpu(ps->wal.tx.mpdus_requed);
207                 stats->tx_ko = __le32_to_cpu(ps->wal.tx.tx_ko);
208                 stats->data_rc = __le32_to_cpu(ps->wal.tx.data_rc);
209                 stats->self_triggers = __le32_to_cpu(ps->wal.tx.self_triggers);
210                 stats->sw_retry_failure =
211                         __le32_to_cpu(ps->wal.tx.sw_retry_failure);
212                 stats->illgl_rate_phy_err =
213                         __le32_to_cpu(ps->wal.tx.illgl_rate_phy_err);
214                 stats->pdev_cont_xretry =
215                         __le32_to_cpu(ps->wal.tx.pdev_cont_xretry);
216                 stats->pdev_tx_timeout =
217                         __le32_to_cpu(ps->wal.tx.pdev_tx_timeout);
218                 stats->pdev_resets = __le32_to_cpu(ps->wal.tx.pdev_resets);
219                 stats->phy_underrun = __le32_to_cpu(ps->wal.tx.phy_underrun);
220                 stats->txop_ovf = __le32_to_cpu(ps->wal.tx.txop_ovf);
221
222                 stats->mid_ppdu_route_change =
223                         __le32_to_cpu(ps->wal.rx.mid_ppdu_route_change);
224                 stats->status_rcvd = __le32_to_cpu(ps->wal.rx.status_rcvd);
225                 stats->r0_frags = __le32_to_cpu(ps->wal.rx.r0_frags);
226                 stats->r1_frags = __le32_to_cpu(ps->wal.rx.r1_frags);
227                 stats->r2_frags = __le32_to_cpu(ps->wal.rx.r2_frags);
228                 stats->r3_frags = __le32_to_cpu(ps->wal.rx.r3_frags);
229                 stats->htt_msdus = __le32_to_cpu(ps->wal.rx.htt_msdus);
230                 stats->htt_mpdus = __le32_to_cpu(ps->wal.rx.htt_mpdus);
231                 stats->loc_msdus = __le32_to_cpu(ps->wal.rx.loc_msdus);
232                 stats->loc_mpdus = __le32_to_cpu(ps->wal.rx.loc_mpdus);
233                 stats->oversize_amsdu =
234                         __le32_to_cpu(ps->wal.rx.oversize_amsdu);
235                 stats->phy_errs = __le32_to_cpu(ps->wal.rx.phy_errs);
236                 stats->phy_err_drop = __le32_to_cpu(ps->wal.rx.phy_err_drop);
237                 stats->mpdu_errs = __le32_to_cpu(ps->wal.rx.mpdu_errs);
238
239                 if (test_bit(ATH10K_FW_FEATURE_WMI_10X,
240                              ar->fw_features)) {
241                         stats->ack_rx_bad = __le32_to_cpu(ps->ack_rx_bad);
242                         stats->rts_bad = __le32_to_cpu(ps->rts_bad);
243                         stats->rts_good = __le32_to_cpu(ps->rts_good);
244                         stats->fcs_bad = __le32_to_cpu(ps->fcs_bad);
245                         stats->no_beacons = __le32_to_cpu(ps->no_beacons);
246                         stats->mib_int_count = __le32_to_cpu(ps->mib_int_count);
247                         tmp += sizeof(struct wmi_pdev_stats_10x);
248                 } else {
249                         tmp += sizeof(struct wmi_pdev_stats_old);
250                 }
251         }
252
253         /* 0 or max vdevs */
254         /* Currently firmware does not support VDEV stats */
255         if (num_vdev_stats) {
256                 struct wmi_vdev_stats *vdev_stats;
257
258                 for (i = 0; i < num_vdev_stats; i++) {
259                         vdev_stats = (struct wmi_vdev_stats *)tmp;
260                         tmp += sizeof(struct wmi_vdev_stats);
261                 }
262         }
263
264         if (num_peer_stats) {
265                 struct wmi_peer_stats_10x *peer_stats;
266                 struct ath10k_peer_stat *s;
267
268                 stats->peers = num_peer_stats;
269
270                 for (i = 0; i < num_peer_stats; i++) {
271                         peer_stats = (struct wmi_peer_stats_10x *)tmp;
272                         s = &stats->peer_stat[i];
273
274                         memcpy(s->peer_macaddr, &peer_stats->peer_macaddr.addr,
275                                ETH_ALEN);
276                         s->peer_rssi = __le32_to_cpu(peer_stats->peer_rssi);
277                         s->peer_tx_rate =
278                                 __le32_to_cpu(peer_stats->peer_tx_rate);
279                         if (test_bit(ATH10K_FW_FEATURE_WMI_10X,
280                                      ar->fw_features)) {
281                                 s->peer_rx_rate =
282                                         __le32_to_cpu(peer_stats->peer_rx_rate);
283                                 tmp += sizeof(struct wmi_peer_stats_10x);
284
285                         } else {
286                                 tmp += sizeof(struct wmi_peer_stats_old);
287                         }
288                 }
289         }
290
291         spin_unlock_bh(&ar->data_lock);
292         complete(&ar->debug.event_stats_compl);
293 }
294
295 static ssize_t ath10k_read_fw_stats(struct file *file, char __user *user_buf,
296                                     size_t count, loff_t *ppos)
297 {
298         struct ath10k *ar = file->private_data;
299         struct ath10k_target_stats *fw_stats;
300         char *buf = NULL;
301         unsigned int len = 0, buf_len = 8000;
302         ssize_t ret_cnt = 0;
303         long left;
304         int i;
305         int ret;
306
307         fw_stats = &ar->debug.target_stats;
308
309         mutex_lock(&ar->conf_mutex);
310
311         if (ar->state != ATH10K_STATE_ON)
312                 goto exit;
313
314         buf = kzalloc(buf_len, GFP_KERNEL);
315         if (!buf)
316                 goto exit;
317
318         ret = ath10k_wmi_request_stats(ar, WMI_REQUEST_PEER_STAT);
319         if (ret) {
320                 ath10k_warn("could not request stats (%d)\n", ret);
321                 goto exit;
322         }
323
324         left = wait_for_completion_timeout(&ar->debug.event_stats_compl, 1*HZ);
325         if (left <= 0)
326                 goto exit;
327
328         spin_lock_bh(&ar->data_lock);
329         len += scnprintf(buf + len, buf_len - len, "\n");
330         len += scnprintf(buf + len, buf_len - len, "%30s\n",
331                          "ath10k PDEV stats");
332         len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
333                                  "=================");
334
335         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
336                          "Channel noise floor", fw_stats->ch_noise_floor);
337         len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
338                          "Channel TX power", fw_stats->chan_tx_power);
339         len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
340                          "TX frame count", fw_stats->tx_frame_count);
341         len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
342                          "RX frame count", fw_stats->rx_frame_count);
343         len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
344                          "RX clear count", fw_stats->rx_clear_count);
345         len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
346                          "Cycle count", fw_stats->cycle_count);
347         len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
348                          "PHY error count", fw_stats->phy_err_count);
349         len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
350                          "RTS bad count", fw_stats->rts_bad);
351         len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
352                          "RTS good count", fw_stats->rts_good);
353         len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
354                          "FCS bad count", fw_stats->fcs_bad);
355         len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
356                          "No beacon count", fw_stats->no_beacons);
357         len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
358                          "MIB int count", fw_stats->mib_int_count);
359
360         len += scnprintf(buf + len, buf_len - len, "\n");
361         len += scnprintf(buf + len, buf_len - len, "%30s\n",
362                          "ath10k PDEV TX stats");
363         len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
364                                  "=================");
365
366         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
367                          "HTT cookies queued", fw_stats->comp_queued);
368         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
369                          "HTT cookies disp.", fw_stats->comp_delivered);
370         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
371                          "MSDU queued", fw_stats->msdu_enqued);
372         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
373                          "MPDU queued", fw_stats->mpdu_enqued);
374         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
375                          "MSDUs dropped", fw_stats->wmm_drop);
376         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
377                          "Local enqued", fw_stats->local_enqued);
378         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
379                          "Local freed", fw_stats->local_freed);
380         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
381                          "HW queued", fw_stats->hw_queued);
382         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
383                          "PPDUs reaped", fw_stats->hw_reaped);
384         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
385                          "Num underruns", fw_stats->underrun);
386         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
387                          "PPDUs cleaned", fw_stats->tx_abort);
388         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
389                          "MPDUs requed", fw_stats->mpdus_requed);
390         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
391                          "Excessive retries", fw_stats->tx_ko);
392         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
393                          "HW rate", fw_stats->data_rc);
394         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
395                          "Sched self tiggers", fw_stats->self_triggers);
396         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
397                          "Dropped due to SW retries",
398                          fw_stats->sw_retry_failure);
399         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
400                          "Illegal rate phy errors",
401                          fw_stats->illgl_rate_phy_err);
402         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
403                          "Pdev continous xretry", fw_stats->pdev_cont_xretry);
404         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
405                          "TX timeout", fw_stats->pdev_tx_timeout);
406         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
407                          "PDEV resets", fw_stats->pdev_resets);
408         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
409                          "PHY underrun", fw_stats->phy_underrun);
410         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
411                          "MPDU is more than txop limit", fw_stats->txop_ovf);
412
413         len += scnprintf(buf + len, buf_len - len, "\n");
414         len += scnprintf(buf + len, buf_len - len, "%30s\n",
415                          "ath10k PDEV RX stats");
416         len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
417                                  "=================");
418
419         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
420                          "Mid PPDU route change",
421                          fw_stats->mid_ppdu_route_change);
422         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
423                          "Tot. number of statuses", fw_stats->status_rcvd);
424         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
425                          "Extra frags on rings 0", fw_stats->r0_frags);
426         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
427                          "Extra frags on rings 1", fw_stats->r1_frags);
428         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
429                          "Extra frags on rings 2", fw_stats->r2_frags);
430         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
431                          "Extra frags on rings 3", fw_stats->r3_frags);
432         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
433                          "MSDUs delivered to HTT", fw_stats->htt_msdus);
434         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
435                          "MPDUs delivered to HTT", fw_stats->htt_mpdus);
436         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
437                          "MSDUs delivered to stack", fw_stats->loc_msdus);
438         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
439                          "MPDUs delivered to stack", fw_stats->loc_mpdus);
440         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
441                          "Oversized AMSUs", fw_stats->oversize_amsdu);
442         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
443                          "PHY errors", fw_stats->phy_errs);
444         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
445                          "PHY errors drops", fw_stats->phy_err_drop);
446         len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
447                          "MPDU errors (FCS, MIC, ENC)", fw_stats->mpdu_errs);
448
449         len += scnprintf(buf + len, buf_len - len, "\n");
450         len += scnprintf(buf + len, buf_len - len, "%30s (%d)\n",
451                          "ath10k PEER stats", fw_stats->peers);
452         len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
453                                  "=================");
454
455         for (i = 0; i < fw_stats->peers; i++) {
456                 len += scnprintf(buf + len, buf_len - len, "%30s %pM\n",
457                                  "Peer MAC address",
458                                  fw_stats->peer_stat[i].peer_macaddr);
459                 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
460                                  "Peer RSSI", fw_stats->peer_stat[i].peer_rssi);
461                 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
462                                  "Peer TX rate",
463                                  fw_stats->peer_stat[i].peer_tx_rate);
464                 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
465                                  "Peer RX rate",
466                                  fw_stats->peer_stat[i].peer_rx_rate);
467                 len += scnprintf(buf + len, buf_len - len, "\n");
468         }
469         spin_unlock_bh(&ar->data_lock);
470
471         if (len > buf_len)
472                 len = buf_len;
473
474         ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
475
476 exit:
477         mutex_unlock(&ar->conf_mutex);
478         kfree(buf);
479         return ret_cnt;
480 }
481
482 static const struct file_operations fops_fw_stats = {
483         .read = ath10k_read_fw_stats,
484         .open = simple_open,
485         .owner = THIS_MODULE,
486         .llseek = default_llseek,
487 };
488
489 static ssize_t ath10k_read_simulate_fw_crash(struct file *file,
490                                              char __user *user_buf,
491                                              size_t count, loff_t *ppos)
492 {
493         const char buf[] = "To simulate firmware crash write one of the"
494                            " keywords to this file:\n `soft` - this will send"
495                            " WMI_FORCE_FW_HANG_ASSERT to firmware if FW"
496                            " supports that command.\n `hard` - this will send"
497                            " to firmware command with illegal parameters"
498                            " causing firmware crash.\n";
499
500         return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
501 }
502
503 /* Simulate firmware crash:
504  * 'soft': Call wmi command causing firmware hang. This firmware hang is
505  * recoverable by warm firmware reset.
506  * 'hard': Force firmware crash by setting any vdev parameter for not allowed
507  * vdev id. This is hard firmware crash because it is recoverable only by cold
508  * firmware reset.
509  */
510 static ssize_t ath10k_write_simulate_fw_crash(struct file *file,
511                                               const char __user *user_buf,
512                                               size_t count, loff_t *ppos)
513 {
514         struct ath10k *ar = file->private_data;
515         char buf[32];
516         int ret;
517
518         mutex_lock(&ar->conf_mutex);
519
520         simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
521
522         /* make sure that buf is null terminated */
523         buf[sizeof(buf) - 1] = 0;
524
525         if (ar->state != ATH10K_STATE_ON &&
526             ar->state != ATH10K_STATE_RESTARTED) {
527                 ret = -ENETDOWN;
528                 goto exit;
529         }
530
531         /* drop the possible '\n' from the end */
532         if (buf[count - 1] == '\n') {
533                 buf[count - 1] = 0;
534                 count--;
535         }
536
537         if (!strcmp(buf, "soft")) {
538                 ath10k_info("simulating soft firmware crash\n");
539                 ret = ath10k_wmi_force_fw_hang(ar, WMI_FORCE_FW_HANG_ASSERT, 0);
540         } else if (!strcmp(buf, "hard")) {
541                 ath10k_info("simulating hard firmware crash\n");
542                 /* 0x7fff is vdev id, and it is always out of range for all
543                  * firmware variants in order to force a firmware crash.
544                  */
545                 ret = ath10k_wmi_vdev_set_param(ar, 0x7fff,
546                                         ar->wmi.vdev_param->rts_threshold, 0);
547         } else {
548                 ret = -EINVAL;
549                 goto exit;
550         }
551
552         if (ret) {
553                 ath10k_warn("failed to simulate firmware crash: %d\n", ret);
554                 goto exit;
555         }
556
557         ret = count;
558
559 exit:
560         mutex_unlock(&ar->conf_mutex);
561         return ret;
562 }
563
564 static const struct file_operations fops_simulate_fw_crash = {
565         .read = ath10k_read_simulate_fw_crash,
566         .write = ath10k_write_simulate_fw_crash,
567         .open = simple_open,
568         .owner = THIS_MODULE,
569         .llseek = default_llseek,
570 };
571
572 static ssize_t ath10k_read_chip_id(struct file *file, char __user *user_buf,
573                                    size_t count, loff_t *ppos)
574 {
575         struct ath10k *ar = file->private_data;
576         unsigned int len;
577         char buf[50];
578
579         len = scnprintf(buf, sizeof(buf), "0x%08x\n", ar->chip_id);
580
581         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
582 }
583
584 static const struct file_operations fops_chip_id = {
585         .read = ath10k_read_chip_id,
586         .open = simple_open,
587         .owner = THIS_MODULE,
588         .llseek = default_llseek,
589 };
590
591 static int ath10k_debug_htt_stats_req(struct ath10k *ar)
592 {
593         u64 cookie;
594         int ret;
595
596         lockdep_assert_held(&ar->conf_mutex);
597
598         if (ar->debug.htt_stats_mask == 0)
599                 /* htt stats are disabled */
600                 return 0;
601
602         if (ar->state != ATH10K_STATE_ON)
603                 return 0;
604
605         cookie = get_jiffies_64();
606
607         ret = ath10k_htt_h2t_stats_req(&ar->htt, ar->debug.htt_stats_mask,
608                                        cookie);
609         if (ret) {
610                 ath10k_warn("failed to send htt stats request: %d\n", ret);
611                 return ret;
612         }
613
614         queue_delayed_work(ar->workqueue, &ar->debug.htt_stats_dwork,
615                            msecs_to_jiffies(ATH10K_DEBUG_HTT_STATS_INTERVAL));
616
617         return 0;
618 }
619
620 static void ath10k_debug_htt_stats_dwork(struct work_struct *work)
621 {
622         struct ath10k *ar = container_of(work, struct ath10k,
623                                          debug.htt_stats_dwork.work);
624
625         mutex_lock(&ar->conf_mutex);
626
627         ath10k_debug_htt_stats_req(ar);
628
629         mutex_unlock(&ar->conf_mutex);
630 }
631
632 static ssize_t ath10k_read_htt_stats_mask(struct file *file,
633                                             char __user *user_buf,
634                                             size_t count, loff_t *ppos)
635 {
636         struct ath10k *ar = file->private_data;
637         char buf[32];
638         unsigned int len;
639
640         len = scnprintf(buf, sizeof(buf), "%lu\n", ar->debug.htt_stats_mask);
641
642         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
643 }
644
645 static ssize_t ath10k_write_htt_stats_mask(struct file *file,
646                                              const char __user *user_buf,
647                                              size_t count, loff_t *ppos)
648 {
649         struct ath10k *ar = file->private_data;
650         unsigned long mask;
651         int ret;
652
653         ret = kstrtoul_from_user(user_buf, count, 0, &mask);
654         if (ret)
655                 return ret;
656
657         /* max 8 bit masks (for now) */
658         if (mask > 0xff)
659                 return -E2BIG;
660
661         mutex_lock(&ar->conf_mutex);
662
663         ar->debug.htt_stats_mask = mask;
664
665         ret = ath10k_debug_htt_stats_req(ar);
666         if (ret)
667                 goto out;
668
669         ret = count;
670
671 out:
672         mutex_unlock(&ar->conf_mutex);
673
674         return ret;
675 }
676
677 static const struct file_operations fops_htt_stats_mask = {
678         .read = ath10k_read_htt_stats_mask,
679         .write = ath10k_write_htt_stats_mask,
680         .open = simple_open,
681         .owner = THIS_MODULE,
682         .llseek = default_llseek,
683 };
684
685 static ssize_t ath10k_read_htt_max_amsdu_ampdu(struct file *file,
686                                                char __user *user_buf,
687                                                size_t count, loff_t *ppos)
688 {
689         struct ath10k *ar = file->private_data;
690         char buf[64];
691         u8 amsdu = 3, ampdu = 64;
692         unsigned int len;
693
694         mutex_lock(&ar->conf_mutex);
695
696         if (ar->debug.htt_max_amsdu)
697                 amsdu = ar->debug.htt_max_amsdu;
698
699         if (ar->debug.htt_max_ampdu)
700                 ampdu = ar->debug.htt_max_ampdu;
701
702         mutex_unlock(&ar->conf_mutex);
703
704         len = scnprintf(buf, sizeof(buf), "%u %u\n", amsdu, ampdu);
705
706         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
707 }
708
709 static ssize_t ath10k_write_htt_max_amsdu_ampdu(struct file *file,
710                                                 const char __user *user_buf,
711                                                 size_t count, loff_t *ppos)
712 {
713         struct ath10k *ar = file->private_data;
714         int res;
715         char buf[64];
716         unsigned int amsdu, ampdu;
717
718         simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
719
720         /* make sure that buf is null terminated */
721         buf[sizeof(buf) - 1] = 0;
722
723         res = sscanf(buf, "%u %u", &amsdu, &ampdu);
724
725         if (res != 2)
726                 return -EINVAL;
727
728         mutex_lock(&ar->conf_mutex);
729
730         res = ath10k_htt_h2t_aggr_cfg_msg(&ar->htt, ampdu, amsdu);
731         if (res)
732                 goto out;
733
734         res = count;
735         ar->debug.htt_max_amsdu = amsdu;
736         ar->debug.htt_max_ampdu = ampdu;
737
738 out:
739         mutex_unlock(&ar->conf_mutex);
740         return res;
741 }
742
743 static const struct file_operations fops_htt_max_amsdu_ampdu = {
744         .read = ath10k_read_htt_max_amsdu_ampdu,
745         .write = ath10k_write_htt_max_amsdu_ampdu,
746         .open = simple_open,
747         .owner = THIS_MODULE,
748         .llseek = default_llseek,
749 };
750
751 static ssize_t ath10k_read_fw_dbglog(struct file *file,
752                                             char __user *user_buf,
753                                             size_t count, loff_t *ppos)
754 {
755         struct ath10k *ar = file->private_data;
756         unsigned int len;
757         char buf[32];
758
759         len = scnprintf(buf, sizeof(buf), "0x%08x\n",
760                         ar->debug.fw_dbglog_mask);
761
762         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
763 }
764
765 static ssize_t ath10k_write_fw_dbglog(struct file *file,
766                                       const char __user *user_buf,
767                                       size_t count, loff_t *ppos)
768 {
769         struct ath10k *ar = file->private_data;
770         unsigned long mask;
771         int ret;
772
773         ret = kstrtoul_from_user(user_buf, count, 0, &mask);
774         if (ret)
775                 return ret;
776
777         mutex_lock(&ar->conf_mutex);
778
779         ar->debug.fw_dbglog_mask = mask;
780
781         if (ar->state == ATH10K_STATE_ON) {
782                 ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask);
783                 if (ret) {
784                         ath10k_warn("dbglog cfg failed from debugfs: %d\n",
785                                     ret);
786                         goto exit;
787                 }
788         }
789
790         ret = count;
791
792 exit:
793         mutex_unlock(&ar->conf_mutex);
794
795         return ret;
796 }
797
798 static const struct file_operations fops_fw_dbglog = {
799         .read = ath10k_read_fw_dbglog,
800         .write = ath10k_write_fw_dbglog,
801         .open = simple_open,
802         .owner = THIS_MODULE,
803         .llseek = default_llseek,
804 };
805
806 int ath10k_debug_start(struct ath10k *ar)
807 {
808         int ret;
809
810         lockdep_assert_held(&ar->conf_mutex);
811
812         ret = ath10k_debug_htt_stats_req(ar);
813         if (ret)
814                 /* continue normally anyway, this isn't serious */
815                 ath10k_warn("failed to start htt stats workqueue: %d\n", ret);
816
817         if (ar->debug.fw_dbglog_mask) {
818                 ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask);
819                 if (ret)
820                         /* not serious */
821                         ath10k_warn("failed to enable dbglog during start: %d",
822                                     ret);
823         }
824
825         return 0;
826 }
827
828 void ath10k_debug_stop(struct ath10k *ar)
829 {
830         lockdep_assert_held(&ar->conf_mutex);
831
832         /* Must not use _sync to avoid deadlock, we do that in
833          * ath10k_debug_destroy(). The check for htt_stats_mask is to avoid
834          * warning from del_timer(). */
835         if (ar->debug.htt_stats_mask != 0)
836                 cancel_delayed_work(&ar->debug.htt_stats_dwork);
837
838         ar->debug.htt_max_amsdu = 0;
839         ar->debug.htt_max_ampdu = 0;
840 }
841
842 static ssize_t ath10k_write_simulate_radar(struct file *file,
843                                            const char __user *user_buf,
844                                            size_t count, loff_t *ppos)
845 {
846         struct ath10k *ar = file->private_data;
847
848         ieee80211_radar_detected(ar->hw);
849
850         return count;
851 }
852
853 static const struct file_operations fops_simulate_radar = {
854         .write = ath10k_write_simulate_radar,
855         .open = simple_open,
856         .owner = THIS_MODULE,
857         .llseek = default_llseek,
858 };
859
860 #define ATH10K_DFS_STAT(s, p) (\
861         len += scnprintf(buf + len, size - len, "%-28s : %10u\n", s, \
862                          ar->debug.dfs_stats.p))
863
864 #define ATH10K_DFS_POOL_STAT(s, p) (\
865         len += scnprintf(buf + len, size - len, "%-28s : %10u\n", s, \
866                          ar->debug.dfs_pool_stats.p))
867
868 static ssize_t ath10k_read_dfs_stats(struct file *file, char __user *user_buf,
869                                      size_t count, loff_t *ppos)
870 {
871         int retval = 0, len = 0;
872         const int size = 8000;
873         struct ath10k *ar = file->private_data;
874         char *buf;
875
876         buf = kzalloc(size, GFP_KERNEL);
877         if (buf == NULL)
878                 return -ENOMEM;
879
880         if (!ar->dfs_detector) {
881                 len += scnprintf(buf + len, size - len, "DFS not enabled\n");
882                 goto exit;
883         }
884
885         ar->debug.dfs_pool_stats =
886                         ar->dfs_detector->get_stats(ar->dfs_detector);
887
888         len += scnprintf(buf + len, size - len, "Pulse detector statistics:\n");
889
890         ATH10K_DFS_STAT("reported phy errors", phy_errors);
891         ATH10K_DFS_STAT("pulse events reported", pulses_total);
892         ATH10K_DFS_STAT("DFS pulses detected", pulses_detected);
893         ATH10K_DFS_STAT("DFS pulses discarded", pulses_discarded);
894         ATH10K_DFS_STAT("Radars detected", radar_detected);
895
896         len += scnprintf(buf + len, size - len, "Global Pool statistics:\n");
897         ATH10K_DFS_POOL_STAT("Pool references", pool_reference);
898         ATH10K_DFS_POOL_STAT("Pulses allocated", pulse_allocated);
899         ATH10K_DFS_POOL_STAT("Pulses alloc error", pulse_alloc_error);
900         ATH10K_DFS_POOL_STAT("Pulses in use", pulse_used);
901         ATH10K_DFS_POOL_STAT("Seqs. allocated", pseq_allocated);
902         ATH10K_DFS_POOL_STAT("Seqs. alloc error", pseq_alloc_error);
903         ATH10K_DFS_POOL_STAT("Seqs. in use", pseq_used);
904
905 exit:
906         if (len > size)
907                 len = size;
908
909         retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
910         kfree(buf);
911
912         return retval;
913 }
914
915 static const struct file_operations fops_dfs_stats = {
916         .read = ath10k_read_dfs_stats,
917         .open = simple_open,
918         .owner = THIS_MODULE,
919         .llseek = default_llseek,
920 };
921
922 int ath10k_debug_create(struct ath10k *ar)
923 {
924         ar->debug.debugfs_phy = debugfs_create_dir("ath10k",
925                                                    ar->hw->wiphy->debugfsdir);
926
927         if (!ar->debug.debugfs_phy)
928                 return -ENOMEM;
929
930         INIT_DELAYED_WORK(&ar->debug.htt_stats_dwork,
931                           ath10k_debug_htt_stats_dwork);
932
933         init_completion(&ar->debug.event_stats_compl);
934
935         debugfs_create_file("fw_stats", S_IRUSR, ar->debug.debugfs_phy, ar,
936                             &fops_fw_stats);
937
938         debugfs_create_file("wmi_services", S_IRUSR, ar->debug.debugfs_phy, ar,
939                             &fops_wmi_services);
940
941         debugfs_create_file("simulate_fw_crash", S_IRUSR, ar->debug.debugfs_phy,
942                             ar, &fops_simulate_fw_crash);
943
944         debugfs_create_file("chip_id", S_IRUSR, ar->debug.debugfs_phy,
945                             ar, &fops_chip_id);
946
947         debugfs_create_file("htt_stats_mask", S_IRUSR, ar->debug.debugfs_phy,
948                             ar, &fops_htt_stats_mask);
949
950         debugfs_create_file("htt_max_amsdu_ampdu", S_IRUSR | S_IWUSR,
951                             ar->debug.debugfs_phy, ar,
952                             &fops_htt_max_amsdu_ampdu);
953
954         debugfs_create_file("fw_dbglog", S_IRUSR, ar->debug.debugfs_phy,
955                             ar, &fops_fw_dbglog);
956
957         if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED)) {
958                 debugfs_create_file("dfs_simulate_radar", S_IWUSR,
959                                     ar->debug.debugfs_phy, ar,
960                                     &fops_simulate_radar);
961
962                 debugfs_create_bool("dfs_block_radar_events", S_IWUSR,
963                                     ar->debug.debugfs_phy,
964                                     &ar->dfs_block_radar_events);
965
966                 debugfs_create_file("dfs_stats", S_IRUSR,
967                                     ar->debug.debugfs_phy, ar,
968                                     &fops_dfs_stats);
969         }
970
971         return 0;
972 }
973
974 void ath10k_debug_destroy(struct ath10k *ar)
975 {
976         cancel_delayed_work_sync(&ar->debug.htt_stats_dwork);
977 }
978
979 #endif /* CONFIG_ATH10K_DEBUGFS */
980
981 #ifdef CONFIG_ATH10K_DEBUG
982 void ath10k_dbg(enum ath10k_debug_mask mask, const char *fmt, ...)
983 {
984         struct va_format vaf;
985         va_list args;
986
987         va_start(args, fmt);
988
989         vaf.fmt = fmt;
990         vaf.va = &args;
991
992         if (ath10k_debug_mask & mask)
993                 ath10k_printk(KERN_DEBUG, "%pV", &vaf);
994
995         trace_ath10k_log_dbg(mask, &vaf);
996
997         va_end(args);
998 }
999 EXPORT_SYMBOL(ath10k_dbg);
1000
1001 void ath10k_dbg_dump(enum ath10k_debug_mask mask,
1002                      const char *msg, const char *prefix,
1003                      const void *buf, size_t len)
1004 {
1005         if (ath10k_debug_mask & mask) {
1006                 if (msg)
1007                         ath10k_dbg(mask, "%s\n", msg);
1008
1009                 print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, buf, len);
1010         }
1011
1012         /* tracing code doesn't like null strings :/ */
1013         trace_ath10k_log_dbg_dump(msg ? msg : "", prefix ? prefix : "",
1014                                   buf, len);
1015 }
1016 EXPORT_SYMBOL(ath10k_dbg_dump);
1017
1018 #endif /* CONFIG_ATH10K_DEBUG */