Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / drivers / net / wireless / realtek / rtw88 / debug.c
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /* Copyright(c) 2018-2019  Realtek Corporation
3  */
4
5 #include <linux/debugfs.h>
6 #include <linux/seq_file.h>
7 #include "main.h"
8 #include "sec.h"
9 #include "fw.h"
10 #include "debug.h"
11
12 #ifdef CONFIG_RTW88_DEBUGFS
13
14 struct rtw_debugfs_priv {
15         struct rtw_dev *rtwdev;
16         int (*cb_read)(struct seq_file *m, void *v);
17         ssize_t (*cb_write)(struct file *filp, const char __user *buffer,
18                             size_t count, loff_t *loff);
19         union {
20                 u32 cb_data;
21                 u8 *buf;
22                 struct {
23                         u32 page_offset;
24                         u32 page_num;
25                 } rsvd_page;
26                 struct {
27                         u8 rf_path;
28                         u32 rf_addr;
29                         u32 rf_mask;
30                 };
31                 struct {
32                         u32 addr;
33                         u32 len;
34                 } read_reg;
35         };
36 };
37
38 static int rtw_debugfs_single_show(struct seq_file *m, void *v)
39 {
40         struct rtw_debugfs_priv *debugfs_priv = m->private;
41
42         return debugfs_priv->cb_read(m, v);
43 }
44
45 static ssize_t rtw_debugfs_common_write(struct file *filp,
46                                         const char __user *buffer,
47                                         size_t count, loff_t *loff)
48 {
49         struct rtw_debugfs_priv *debugfs_priv = filp->private_data;
50
51         return debugfs_priv->cb_write(filp, buffer, count, loff);
52 }
53
54 static ssize_t rtw_debugfs_single_write(struct file *filp,
55                                         const char __user *buffer,
56                                         size_t count, loff_t *loff)
57 {
58         struct seq_file *seqpriv = (struct seq_file *)filp->private_data;
59         struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;
60
61         return debugfs_priv->cb_write(filp, buffer, count, loff);
62 }
63
64 static int rtw_debugfs_single_open_rw(struct inode *inode, struct file *filp)
65 {
66         return single_open(filp, rtw_debugfs_single_show, inode->i_private);
67 }
68
69 static int rtw_debugfs_close(struct inode *inode, struct file *filp)
70 {
71         return 0;
72 }
73
74 static const struct file_operations file_ops_single_r = {
75         .owner = THIS_MODULE,
76         .open = rtw_debugfs_single_open_rw,
77         .read = seq_read,
78         .llseek = seq_lseek,
79         .release = seq_release,
80 };
81
82 static const struct file_operations file_ops_single_rw = {
83         .owner = THIS_MODULE,
84         .open = rtw_debugfs_single_open_rw,
85         .release = single_release,
86         .read = seq_read,
87         .llseek = seq_lseek,
88         .write = rtw_debugfs_single_write,
89 };
90
91 static const struct file_operations file_ops_common_write = {
92         .owner = THIS_MODULE,
93         .write = rtw_debugfs_common_write,
94         .open = simple_open,
95         .release = rtw_debugfs_close,
96 };
97
98 static int rtw_debugfs_get_read_reg(struct seq_file *m, void *v)
99 {
100         struct rtw_debugfs_priv *debugfs_priv = m->private;
101         struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
102         u32 val, len, addr;
103
104         len = debugfs_priv->read_reg.len;
105         addr = debugfs_priv->read_reg.addr;
106         switch (len) {
107         case 1:
108                 val = rtw_read8(rtwdev, addr);
109                 seq_printf(m, "reg 0x%03x: 0x%02x\n", addr, val);
110                 break;
111         case 2:
112                 val = rtw_read16(rtwdev, addr);
113                 seq_printf(m, "reg 0x%03x: 0x%04x\n", addr, val);
114                 break;
115         case 4:
116                 val = rtw_read32(rtwdev, addr);
117                 seq_printf(m, "reg 0x%03x: 0x%08x\n", addr, val);
118                 break;
119         }
120         return 0;
121 }
122
123 static int rtw_debugfs_get_rf_read(struct seq_file *m, void *v)
124 {
125         struct rtw_debugfs_priv *debugfs_priv = m->private;
126         struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
127         u32 val, addr, mask;
128         u8 path;
129
130         path = debugfs_priv->rf_path;
131         addr = debugfs_priv->rf_addr;
132         mask = debugfs_priv->rf_mask;
133
134         val = rtw_read_rf(rtwdev, path, addr, mask);
135
136         seq_printf(m, "rf_read path:%d addr:0x%08x mask:0x%08x val=0x%08x\n",
137                    path, addr, mask, val);
138
139         return 0;
140 }
141
142 static int rtw_debugfs_copy_from_user(char tmp[], int size,
143                                       const char __user *buffer, size_t count,
144                                       int num)
145 {
146         int tmp_len;
147
148         if (count < num)
149                 return -EFAULT;
150
151         tmp_len = (count > size - 1 ? size - 1 : count);
152
153         if (!buffer || copy_from_user(tmp, buffer, tmp_len))
154                 return count;
155
156         tmp[tmp_len] = '\0';
157
158         return 0;
159 }
160
161 static ssize_t rtw_debugfs_set_read_reg(struct file *filp,
162                                         const char __user *buffer,
163                                         size_t count, loff_t *loff)
164 {
165         struct seq_file *seqpriv = (struct seq_file *)filp->private_data;
166         struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;
167         struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
168         char tmp[32 + 1];
169         u32 addr, len;
170         int num;
171
172         rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2);
173
174         num = sscanf(tmp, "%x %x", &addr, &len);
175
176         if (num !=  2)
177                 return count;
178
179         if (len != 1 && len != 2 && len != 4) {
180                 rtw_warn(rtwdev, "read reg setting wrong len\n");
181                 return -EINVAL;
182         }
183         debugfs_priv->read_reg.addr = addr;
184         debugfs_priv->read_reg.len = len;
185
186         return count;
187 }
188
189 static int rtw_debugfs_get_dump_cam(struct seq_file *m, void *v)
190 {
191         struct rtw_debugfs_priv *debugfs_priv = m->private;
192         struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
193         u32 val, command;
194         u32 hw_key_idx = debugfs_priv->cb_data << RTW_SEC_CAM_ENTRY_SHIFT;
195         u32 read_cmd = RTW_SEC_CMD_POLLING;
196         int i;
197
198         seq_printf(m, "cam entry%d\n", debugfs_priv->cb_data);
199         seq_puts(m, "0x0      0x1      0x2     0x3     ");
200         seq_puts(m, "0x4     0x5\n");
201         mutex_lock(&rtwdev->mutex);
202         for (i = 0; i <= 5; i++) {
203                 command = read_cmd | (hw_key_idx + i);
204                 rtw_write32(rtwdev, RTW_SEC_CMD_REG, command);
205                 val = rtw_read32(rtwdev, RTW_SEC_READ_REG);
206                 seq_printf(m, "%8.8x", val);
207                 if (i < 2)
208                         seq_puts(m, " ");
209         }
210         seq_puts(m, "\n");
211         mutex_unlock(&rtwdev->mutex);
212         return 0;
213 }
214
215 static int rtw_debugfs_get_rsvd_page(struct seq_file *m, void *v)
216 {
217         struct rtw_debugfs_priv *debugfs_priv = m->private;
218         struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
219         u8 page_size = rtwdev->chip->page_size;
220         u32 buf_size = debugfs_priv->rsvd_page.page_num * page_size;
221         u32 offset = debugfs_priv->rsvd_page.page_offset * page_size;
222         u8 *buf;
223         int i;
224         int ret;
225
226         buf = vzalloc(buf_size);
227         if (!buf)
228                 return -ENOMEM;
229
230         ret = rtw_dump_drv_rsvd_page(rtwdev, offset, buf_size, (u32 *)buf);
231         if (ret) {
232                 rtw_err(rtwdev, "failed to dump rsvd page\n");
233                 vfree(buf);
234                 return ret;
235         }
236
237         for (i = 0 ; i < buf_size ; i += 8) {
238                 if (i % page_size == 0)
239                         seq_printf(m, "PAGE %d\n", (i + offset) / page_size);
240                 seq_printf(m, "%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
241                            *(buf + i), *(buf + i + 1),
242                            *(buf + i + 2), *(buf + i + 3),
243                            *(buf + i + 4), *(buf + i + 5),
244                            *(buf + i + 6), *(buf + i + 7));
245         }
246         vfree(buf);
247
248         return 0;
249 }
250
251 static ssize_t rtw_debugfs_set_rsvd_page(struct file *filp,
252                                          const char __user *buffer,
253                                          size_t count, loff_t *loff)
254 {
255         struct seq_file *seqpriv = (struct seq_file *)filp->private_data;
256         struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;
257         struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
258         char tmp[32 + 1];
259         u32 offset, page_num;
260         int num;
261
262         rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2);
263
264         num = sscanf(tmp, "%d %d", &offset, &page_num);
265
266         if (num != 2) {
267                 rtw_warn(rtwdev, "invalid arguments\n");
268                 return num;
269         }
270
271         debugfs_priv->rsvd_page.page_offset = offset;
272         debugfs_priv->rsvd_page.page_num = page_num;
273
274         return count;
275 }
276
277 static ssize_t rtw_debugfs_set_single_input(struct file *filp,
278                                             const char __user *buffer,
279                                             size_t count, loff_t *loff)
280 {
281         struct seq_file *seqpriv = (struct seq_file *)filp->private_data;
282         struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;
283         struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
284         char tmp[32 + 1];
285         u32 input;
286         int num;
287
288         rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1);
289
290         num = kstrtoint(tmp, 0, &input);
291
292         if (num) {
293                 rtw_warn(rtwdev, "kstrtoint failed\n");
294                 return num;
295         }
296
297         debugfs_priv->cb_data = input;
298
299         return count;
300 }
301
302 static ssize_t rtw_debugfs_set_write_reg(struct file *filp,
303                                          const char __user *buffer,
304                                          size_t count, loff_t *loff)
305 {
306         struct rtw_debugfs_priv *debugfs_priv = filp->private_data;
307         struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
308         char tmp[32 + 1];
309         u32 addr, val, len;
310         int num;
311
312         rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3);
313
314         /* write BB/MAC register */
315         num = sscanf(tmp, "%x %x %x", &addr, &val, &len);
316
317         if (num !=  3)
318                 return count;
319
320         switch (len) {
321         case 1:
322                 rtw_dbg(rtwdev, RTW_DBG_DEBUGFS,
323                         "reg write8 0x%03x: 0x%08x\n", addr, val);
324                 rtw_write8(rtwdev, addr, (u8)val);
325                 break;
326         case 2:
327                 rtw_dbg(rtwdev, RTW_DBG_DEBUGFS,
328                         "reg write16 0x%03x: 0x%08x\n", addr, val);
329                 rtw_write16(rtwdev, addr, (u16)val);
330                 break;
331         case 4:
332                 rtw_dbg(rtwdev, RTW_DBG_DEBUGFS,
333                         "reg write32 0x%03x: 0x%08x\n", addr, val);
334                 rtw_write32(rtwdev, addr, (u32)val);
335                 break;
336         default:
337                 rtw_dbg(rtwdev, RTW_DBG_DEBUGFS,
338                         "error write length = %d\n", len);
339                 break;
340         }
341
342         return count;
343 }
344
345 static ssize_t rtw_debugfs_set_rf_write(struct file *filp,
346                                         const char __user *buffer,
347                                         size_t count, loff_t *loff)
348 {
349         struct rtw_debugfs_priv *debugfs_priv = filp->private_data;
350         struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
351         char tmp[32 + 1];
352         u32 path, addr, mask, val;
353         int num;
354
355         rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 4);
356
357         num = sscanf(tmp, "%x %x %x %x", &path, &addr, &mask, &val);
358
359         if (num !=  4) {
360                 rtw_warn(rtwdev, "invalid args, [path] [addr] [mask] [val]\n");
361                 return count;
362         }
363
364         rtw_write_rf(rtwdev, path, addr, mask, val);
365         rtw_dbg(rtwdev, RTW_DBG_DEBUGFS,
366                 "write_rf path:%d addr:0x%08x mask:0x%08x, val:0x%08x\n",
367                 path, addr, mask, val);
368
369         return count;
370 }
371
372 static ssize_t rtw_debugfs_set_rf_read(struct file *filp,
373                                        const char __user *buffer,
374                                        size_t count, loff_t *loff)
375 {
376         struct seq_file *seqpriv = (struct seq_file *)filp->private_data;
377         struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;
378         struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
379         char tmp[32 + 1];
380         u32 path, addr, mask;
381         int num;
382
383         rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3);
384
385         num = sscanf(tmp, "%x %x %x", &path, &addr, &mask);
386
387         if (num !=  3) {
388                 rtw_warn(rtwdev, "invalid args, [path] [addr] [mask] [val]\n");
389                 return count;
390         }
391
392         debugfs_priv->rf_path = path;
393         debugfs_priv->rf_addr = addr;
394         debugfs_priv->rf_mask = mask;
395
396         return count;
397 }
398
399 static int rtw_debug_get_mac_page(struct seq_file *m, void *v)
400 {
401         struct rtw_debugfs_priv *debugfs_priv = m->private;
402         struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
403         u32 val;
404         u32 page = debugfs_priv->cb_data;
405         int i, n;
406         int max = 0xff;
407
408         val = rtw_read32(rtwdev, debugfs_priv->cb_data);
409         for (n = 0; n <= max; ) {
410                 seq_printf(m, "\n%8.8x  ", n + page);
411                 for (i = 0; i < 4 && n <= max; i++, n += 4)
412                         seq_printf(m, "%8.8x    ",
413                                    rtw_read32(rtwdev, (page | n)));
414         }
415         seq_puts(m, "\n");
416         return 0;
417 }
418
419 static int rtw_debug_get_bb_page(struct seq_file *m, void *v)
420 {
421         struct rtw_debugfs_priv *debugfs_priv = m->private;
422         struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
423         u32 val;
424         u32 page = debugfs_priv->cb_data;
425         int i, n;
426         int max = 0xff;
427
428         val = rtw_read32(rtwdev, debugfs_priv->cb_data);
429         for (n = 0; n <= max; ) {
430                 seq_printf(m, "\n%8.8x  ", n + page);
431                 for (i = 0; i < 4 && n <= max; i++, n += 4)
432                         seq_printf(m, "%8.8x    ",
433                                    rtw_read32(rtwdev, (page | n)));
434         }
435         seq_puts(m, "\n");
436         return 0;
437 }
438
439 static int rtw_debug_get_rf_dump(struct seq_file *m, void *v)
440 {
441         struct rtw_debugfs_priv *debugfs_priv = m->private;
442         struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
443         u32 addr, offset, data;
444         u8 path;
445
446         for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
447                 seq_printf(m, "RF path:%d\n", path);
448                 for (addr = 0; addr < 0x100; addr += 4) {
449                         seq_printf(m, "%8.8x  ", addr);
450                         for (offset = 0; offset < 4; offset++) {
451                                 data = rtw_read_rf(rtwdev, path, addr + offset,
452                                                    0xffffffff);
453                                 seq_printf(m, "%8.8x    ", data);
454                         }
455                         seq_puts(m, "\n");
456                 }
457                 seq_puts(m, "\n");
458         }
459
460         return 0;
461 }
462
463 #define rtw_debug_impl_mac(page, addr)                          \
464 static struct rtw_debugfs_priv rtw_debug_priv_mac_ ##page = {   \
465         .cb_read = rtw_debug_get_mac_page,                      \
466         .cb_data = addr,                                        \
467 }
468
469 rtw_debug_impl_mac(0, 0x0000);
470 rtw_debug_impl_mac(1, 0x0100);
471 rtw_debug_impl_mac(2, 0x0200);
472 rtw_debug_impl_mac(3, 0x0300);
473 rtw_debug_impl_mac(4, 0x0400);
474 rtw_debug_impl_mac(5, 0x0500);
475 rtw_debug_impl_mac(6, 0x0600);
476 rtw_debug_impl_mac(7, 0x0700);
477 rtw_debug_impl_mac(10, 0x1000);
478 rtw_debug_impl_mac(11, 0x1100);
479 rtw_debug_impl_mac(12, 0x1200);
480 rtw_debug_impl_mac(13, 0x1300);
481 rtw_debug_impl_mac(14, 0x1400);
482 rtw_debug_impl_mac(15, 0x1500);
483 rtw_debug_impl_mac(16, 0x1600);
484 rtw_debug_impl_mac(17, 0x1700);
485
486 #define rtw_debug_impl_bb(page, addr)                   \
487 static struct rtw_debugfs_priv rtw_debug_priv_bb_ ##page = {    \
488         .cb_read = rtw_debug_get_bb_page,                       \
489         .cb_data = addr,                                        \
490 }
491
492 rtw_debug_impl_bb(8, 0x0800);
493 rtw_debug_impl_bb(9, 0x0900);
494 rtw_debug_impl_bb(a, 0x0a00);
495 rtw_debug_impl_bb(b, 0x0b00);
496 rtw_debug_impl_bb(c, 0x0c00);
497 rtw_debug_impl_bb(d, 0x0d00);
498 rtw_debug_impl_bb(e, 0x0e00);
499 rtw_debug_impl_bb(f, 0x0f00);
500 rtw_debug_impl_bb(18, 0x1800);
501 rtw_debug_impl_bb(19, 0x1900);
502 rtw_debug_impl_bb(1a, 0x1a00);
503 rtw_debug_impl_bb(1b, 0x1b00);
504 rtw_debug_impl_bb(1c, 0x1c00);
505 rtw_debug_impl_bb(1d, 0x1d00);
506 rtw_debug_impl_bb(1e, 0x1e00);
507 rtw_debug_impl_bb(1f, 0x1f00);
508 rtw_debug_impl_bb(2c, 0x2c00);
509 rtw_debug_impl_bb(2d, 0x2d00);
510 rtw_debug_impl_bb(40, 0x4000);
511 rtw_debug_impl_bb(41, 0x4100);
512
513 static struct rtw_debugfs_priv rtw_debug_priv_rf_dump = {
514         .cb_read = rtw_debug_get_rf_dump,
515 };
516
517 static struct rtw_debugfs_priv rtw_debug_priv_write_reg = {
518         .cb_write = rtw_debugfs_set_write_reg,
519 };
520
521 static struct rtw_debugfs_priv rtw_debug_priv_rf_write = {
522         .cb_write = rtw_debugfs_set_rf_write,
523 };
524
525 static struct rtw_debugfs_priv rtw_debug_priv_rf_read = {
526         .cb_write = rtw_debugfs_set_rf_read,
527         .cb_read = rtw_debugfs_get_rf_read,
528 };
529
530 static struct rtw_debugfs_priv rtw_debug_priv_read_reg = {
531         .cb_write = rtw_debugfs_set_read_reg,
532         .cb_read = rtw_debugfs_get_read_reg,
533 };
534
535 static struct rtw_debugfs_priv rtw_debug_priv_dump_cam = {
536         .cb_write = rtw_debugfs_set_single_input,
537         .cb_read = rtw_debugfs_get_dump_cam,
538 };
539
540 static struct rtw_debugfs_priv rtw_debug_priv_rsvd_page = {
541         .cb_write = rtw_debugfs_set_rsvd_page,
542         .cb_read = rtw_debugfs_get_rsvd_page,
543 };
544
545 #define rtw_debugfs_add_core(name, mode, fopname, parent)               \
546         do {                                                            \
547                 rtw_debug_priv_ ##name.rtwdev = rtwdev;                 \
548                 if (!debugfs_create_file(#name, mode,                   \
549                                          parent, &rtw_debug_priv_ ##name,\
550                                          &file_ops_ ##fopname))         \
551                         pr_debug("Unable to initialize debugfs:%s\n",   \
552                                #name);                                  \
553         } while (0)
554
555 #define rtw_debugfs_add_w(name)                                         \
556         rtw_debugfs_add_core(name, S_IFREG | 0222, common_write, debugfs_topdir)
557 #define rtw_debugfs_add_rw(name)                                        \
558         rtw_debugfs_add_core(name, S_IFREG | 0666, single_rw, debugfs_topdir)
559 #define rtw_debugfs_add_r(name)                                         \
560         rtw_debugfs_add_core(name, S_IFREG | 0444, single_r, debugfs_topdir)
561
562 void rtw_debugfs_init(struct rtw_dev *rtwdev)
563 {
564         struct dentry *debugfs_topdir = rtwdev->debugfs;
565
566         debugfs_topdir = debugfs_create_dir("rtw88",
567                                             rtwdev->hw->wiphy->debugfsdir);
568         rtw_debugfs_add_w(write_reg);
569         rtw_debugfs_add_rw(read_reg);
570         rtw_debugfs_add_w(rf_write);
571         rtw_debugfs_add_rw(rf_read);
572         rtw_debugfs_add_rw(dump_cam);
573         rtw_debugfs_add_rw(rsvd_page);
574         rtw_debugfs_add_r(mac_0);
575         rtw_debugfs_add_r(mac_1);
576         rtw_debugfs_add_r(mac_2);
577         rtw_debugfs_add_r(mac_3);
578         rtw_debugfs_add_r(mac_4);
579         rtw_debugfs_add_r(mac_5);
580         rtw_debugfs_add_r(mac_6);
581         rtw_debugfs_add_r(mac_7);
582         rtw_debugfs_add_r(bb_8);
583         rtw_debugfs_add_r(bb_9);
584         rtw_debugfs_add_r(bb_a);
585         rtw_debugfs_add_r(bb_b);
586         rtw_debugfs_add_r(bb_c);
587         rtw_debugfs_add_r(bb_d);
588         rtw_debugfs_add_r(bb_e);
589         rtw_debugfs_add_r(bb_f);
590         rtw_debugfs_add_r(mac_10);
591         rtw_debugfs_add_r(mac_11);
592         rtw_debugfs_add_r(mac_12);
593         rtw_debugfs_add_r(mac_13);
594         rtw_debugfs_add_r(mac_14);
595         rtw_debugfs_add_r(mac_15);
596         rtw_debugfs_add_r(mac_16);
597         rtw_debugfs_add_r(mac_17);
598         rtw_debugfs_add_r(bb_18);
599         rtw_debugfs_add_r(bb_19);
600         rtw_debugfs_add_r(bb_1a);
601         rtw_debugfs_add_r(bb_1b);
602         rtw_debugfs_add_r(bb_1c);
603         rtw_debugfs_add_r(bb_1d);
604         rtw_debugfs_add_r(bb_1e);
605         rtw_debugfs_add_r(bb_1f);
606         if (rtwdev->chip->id == RTW_CHIP_TYPE_8822C) {
607                 rtw_debugfs_add_r(bb_2c);
608                 rtw_debugfs_add_r(bb_2d);
609                 rtw_debugfs_add_r(bb_40);
610                 rtw_debugfs_add_r(bb_41);
611         }
612         rtw_debugfs_add_r(rf_dump);
613 }
614
615 #endif /* CONFIG_RTW88_DEBUGFS */
616
617 #ifdef CONFIG_RTW88_DEBUG
618
619 void __rtw_dbg(struct rtw_dev *rtwdev, enum rtw_debug_mask mask,
620                const char *fmt, ...)
621 {
622         struct va_format vaf = {
623                 .fmt = fmt,
624         };
625         va_list args;
626
627         va_start(args, fmt);
628         vaf.va = &args;
629
630         if (rtw_debug_mask & mask)
631                 dev_printk(KERN_DEBUG, rtwdev->dev, "%pV", &vaf);
632
633         va_end(args);
634 }
635 EXPORT_SYMBOL(__rtw_dbg);
636
637 #endif /* CONFIG_RTW88_DEBUG */