2ab7b1f0297eb66ac791b4d952f9d5d244441d67
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rda5990 / rda_wlan / rda5890_debugfs.c
1 #include <linux/module.h>
2 #include <linux/dcache.h>
3 #include <linux/debugfs.h>
4 #include <linux/delay.h>
5 #include <linux/mm.h>
6 #include <linux/string.h>
7 #include <net/iw_handler.h>
8
9 #include "rda5890_defs.h"
10 #include "rda5890_dev.h"
11
12 static struct dentry *rda5890_dir = NULL;
13
14 void dump_buf(char *data, size_t len)
15 {
16     char temp_buf[64];
17     size_t i, off = 0;
18
19     memset(temp_buf, 0, 64);
20     for (i=0;i<len;i++) {
21         if(i%8 == 0) {
22             sprintf(&temp_buf[off], "  ");
23             off += 2;
24         }
25         sprintf(&temp_buf[off], "%02x ", data[i]);
26         off += 3;
27         if((i+1)%16 == 0) {
28             RDA5890_DBGLAP(RDA5890_DA_ALL, RDA5890_DL_TRACE,
29                 "%s\n", temp_buf);
30             memset(temp_buf, 0, 64);
31             off = 0;
32         }
33     }
34     RDA5890_DBGLAP(RDA5890_DA_ALL, RDA5890_DL_TRACE, "\n");
35 }
36
37 static int open_file_generic(struct inode *inode, struct file *file)
38 {
39         file->private_data = inode->i_private;
40         return 0;
41 }
42
43 #if 0
44 static ssize_t rda5890_write_file_dummy(struct file *file, const char __user *buf,
45                                 size_t count, loff_t *ppos)
46 {
47         return -EINVAL;
48 }
49 #endif
50
51 static ssize_t rda5890_debug_read(struct file *file, char __user *userbuf,
52                                   size_t count, loff_t *ppos)
53 {
54         //struct rda5890_private *priv = file->private_data;
55         size_t pos = 0;
56         unsigned long addr = get_zeroed_page(GFP_KERNEL);
57         char *buf = (char *)addr;
58         ssize_t res;
59
60         RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_TRACE,
61                 "%s\n", __func__);
62
63         pos += snprintf(buf+pos, PAGE_SIZE - pos, "state = %s\n",
64                                 "LWANG_TESTING");
65
66         res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
67
68         free_page(addr);
69         return res;
70 }
71
72 static ssize_t rda5890_debug_write(struct file *file,
73                                 const char __user *user_buf, size_t count,
74                                 loff_t *ppos)
75 {
76         //struct rda5890_private *priv = file->private_data;
77         ssize_t ret;
78         int p1, p2, p3, p4;
79         unsigned long addr = get_zeroed_page(GFP_KERNEL);
80         char *buf = (char *)addr;
81
82         RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_TRACE,
83                 "%s\n", __func__);
84
85         if (copy_from_user(buf, user_buf, count)) {
86                 ret = -EFAULT;
87                 goto out_unlock;
88         }
89         ret = sscanf(buf, "%d %d %d %d", &p1, &p2, &p3, &p4);
90         if (ret != 4) {
91                 ret = -EINVAL;
92                 goto out_unlock;
93         }
94
95         RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_TRACE,
96                 "input p1 = %d, p2 = %d, p3 = %d, p4 = %d\n",
97                 p1, p2, p3, p4);
98
99         ret = count;
100 out_unlock:
101         free_page(addr);
102         return ret;
103 }
104
105 static ssize_t rda5890_debugarea_read(struct file *file, char __user *userbuf,
106                                   size_t count, loff_t *ppos)
107 {
108         //struct rda5890_private *priv = file->private_data;
109         size_t pos = 0;
110         unsigned long addr = get_zeroed_page(GFP_KERNEL);
111         char *buf = (char *)addr;
112         ssize_t res;
113
114         RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_TRACE,
115                 "%s\n", __func__);
116
117         RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_TRACE,
118                 "get debug_area = 0x%x\n",rda5890_dbg_area);
119
120         pos += snprintf(buf+pos, PAGE_SIZE - pos, "%x\n",
121                                 rda5890_dbg_area);
122
123         res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
124
125         free_page(addr);
126         return res;
127 }
128
129 static ssize_t rda5890_debugarea_write(struct file *file,
130                                 const char __user *user_buf, size_t count,
131                                 loff_t *ppos)
132 {
133         //struct rda5890_private *priv = file->private_data;
134         ssize_t ret;
135         int debug_area;
136         unsigned long addr = get_zeroed_page(GFP_KERNEL);
137         char *buf = (char *)addr;
138
139         RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_TRACE,
140                 "%s\n", __func__);
141
142         if (copy_from_user(buf, user_buf, count)) {
143                 ret = -EFAULT;
144                 goto out_unlock;
145         }
146         ret = sscanf(buf, "%x", &debug_area);
147         if (ret != 1) {
148                 ret = -EINVAL;
149                 goto out_unlock;
150         }
151
152     rda5890_dbg_area = debug_area;
153         RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_TRACE,
154                 "set debug_area = 0x%x\n",rda5890_dbg_area);
155
156         ret = count;
157 out_unlock:
158         free_page(addr);
159         return ret;
160 }
161
162 static ssize_t rda5890_debuglevel_read(struct file *file, char __user *userbuf,
163                                   size_t count, loff_t *ppos)
164 {
165         //struct rda5890_private *priv = file->private_data;
166         size_t pos = 0;
167         unsigned long addr = get_zeroed_page(GFP_KERNEL);
168         char *buf = (char *)addr;
169         ssize_t res;
170
171         RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_TRACE,
172                 "%s\n", __func__);
173
174         RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_TRACE,
175                 "get debug_level = 0x%x\n",rda5890_dbg_level);
176
177         pos += snprintf(buf+pos, PAGE_SIZE - pos, "%x\n",
178                                 rda5890_dbg_level);
179
180         res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
181
182         free_page(addr);
183         return res;
184 }
185
186 static ssize_t rda5890_debuglevel_write(struct file *file,
187                                 const char __user *user_buf, size_t count,
188                                 loff_t *ppos)
189 {
190         //struct rda5890_private *priv = file->private_data;
191         ssize_t ret;
192         int debug_level;
193         unsigned long addr = get_zeroed_page(GFP_KERNEL);
194         char *buf = (char *)addr;
195
196         RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_TRACE,
197                 "%s\n", __func__);
198
199         if (copy_from_user(buf, user_buf, count)) {
200                 ret = -EFAULT;
201                 goto out_unlock;
202         }
203         ret = sscanf(buf, "%x", &debug_level);
204         if (ret != 1) {
205                 ret = -EINVAL;
206                 goto out_unlock;
207         }
208
209     rda5890_dbg_level = debug_level;
210         RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_TRACE,
211                 "set debug_level = 0x%x\n",rda5890_dbg_level);
212
213         ret = count;
214 out_unlock:
215         free_page(addr);
216         return ret;
217 }
218
219 static int debug_read_flag = 0;
220
221 static ssize_t rda5890_sdio_read(struct file *file, 
222                                 const char __user *user_buf, size_t count,
223                                 loff_t *ppos)
224 {
225         //struct rda5890_private *priv = file->private_data;
226         unsigned long addr = get_zeroed_page(GFP_KERNEL);
227         char *buf = (char *)addr;
228         int ret;
229
230         RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_TRACE,
231                 "%s\n", __func__);
232
233         if (copy_from_user(buf, user_buf, count)) {
234                 ret = -EFAULT;
235                 goto out_unlock;
236         }
237         ret = sscanf(buf, "%d", &debug_read_flag);
238         if (ret != 1) {
239                 ret = -EINVAL;
240                 goto out_unlock;
241         }
242
243 out_unlock:
244         free_page(addr);
245         return count;
246 }
247
248 static ssize_t rda5890_sdio_write(struct file *file,
249                                 const char __user *user_buf, size_t count,
250                                 loff_t *ppos)
251 {
252         struct rda5890_private *priv = file->private_data;
253         unsigned long addr = get_zeroed_page(GFP_KERNEL);
254         char *buf = (char *)addr;
255         int iter, len, i;
256         int ret;
257
258         RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_TRACE,
259                 "%s\n", __func__);
260
261         if (copy_from_user(buf, user_buf, count)) {
262                 ret = -EFAULT;
263                 goto out_unlock;
264         }
265         ret = sscanf(buf, "%d %d", &iter, &len);
266         if (ret != 2) {
267                 ret = -EINVAL;
268                 goto out_unlock;
269         }
270
271         if (len > 1660) {
272                 ret = -EINVAL;
273                 goto out_unlock;
274         }
275
276         for (i=0; i<len; i++) {
277                 buf[i] = len - i - 1;
278         }
279
280         for (i=0;i<iter;i++) {
281                 //RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_TRACE,
282                 //      "Host to Card, len = %d\n", len);
283
284                 ret = priv->hw_host_to_card(priv, buf, len, DATA_REQUEST_PACKET);
285
286                 //RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_TRACE,
287                 //      "Host to Card done, ret = %d\n", ret);
288         }
289
290 out_unlock:
291         free_page(addr);
292         return count;
293 }
294
295 #define SDIO_TEST_CMD_MAGIC        0x55664433
296 #define SDIO_TEST_CMD_LEN          16
297
298 #define SDIO_TEST_CMD_TYPE_H2C_START            1
299 #define SDIO_TEST_CMD_TYPE_H2C_STOP             2
300 #define SDIO_TEST_CMD_TYPE_H2C_STATUS           3
301 #define SDIO_TEST_CMD_TYPE_C2H_START            4
302 #define SDIO_TEST_CMD_TYPE_C2H_PILOT            5
303 #define SDIO_TEST_CMD_TYPE_C2H_END              6
304
305 static int recv_time_start, recv_time_end;
306 static int send_time_start, send_time_end;
307
308 void rda5890_sdio_test_card_to_host(char *buf, unsigned short len)
309 {
310         int i;
311         int cmd, cmd_iter, cmd_len;
312         int time_ms;
313         static int recv_pattern = 0;
314         static int recv_tput_flag = 0;
315         static int recv_pkts = 0;
316         static int recv_bytes = 0;
317
318         //RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_TRACE,
319         //      "SDIO TEST Card to Host, len = %d\n", len);
320
321         if (debug_read_flag) {
322                 RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_TRACE,
323                         "DEBUG RX, len = %d\n", len);
324                 dump_buf(buf, len);
325         }
326
327         if ((*(volatile unsigned long *)buf == SDIO_TEST_CMD_MAGIC)
328                         && len == SDIO_TEST_CMD_LEN) {
329                 cmd = (int)(*(volatile unsigned long *)(buf + 4));
330                 cmd_iter = (int)(*(volatile unsigned long *)(buf + 8));
331                 cmd_len = (int)(*(volatile unsigned long *)(buf + 12));
332                 //RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_TRACE,
333                 //              "SDIO TEST CMD: cmd = %d, iter = %d, len = %d\n", 
334                 //              cmd, cmd_iter, cmd_len);
335                 switch (cmd) {
336                 case SDIO_TEST_CMD_TYPE_H2C_STATUS:
337                         RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_TRACE,
338                                 "H2C STATUS CMD \n");
339                         time_ms = jiffies_to_msecs(send_time_end - send_time_start);
340                         RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_TRACE,
341                                 "SDIO H2C STATUS: pkts = %d, bytes = %d, time = %d ms\n",
342                                 cmd_iter, cmd_len, time_ms);
343                         break;
344                 case SDIO_TEST_CMD_TYPE_C2H_PILOT:
345                         //RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_TRACE,
346                         //      "C2H PILOT CMD \n");
347                         recv_pattern = 0;
348                         recv_tput_flag = 1;
349                         recv_pkts = 0;
350                         recv_bytes = 0;
351                         recv_time_start = jiffies;
352                         break;
353                 case SDIO_TEST_CMD_TYPE_C2H_END:
354                         //RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_TRACE,
355                         //      "C2H END CMD \n");
356                         recv_time_end = jiffies;
357                         recv_tput_flag = 0;
358                         time_ms = jiffies_to_msecs(recv_time_end - recv_time_start);
359                         RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_TRACE,
360                                 "SDIO C2H STATUS: pkts = %d, bytes = %d, time = %d ms\n",
361                                 recv_pkts, recv_bytes, time_ms);
362                         break;
363                 case SDIO_TEST_CMD_TYPE_H2C_START:
364                 case SDIO_TEST_CMD_TYPE_H2C_STOP:
365                 case SDIO_TEST_CMD_TYPE_C2H_START:
366                 default:
367                         RDA5890_ERRP("SDIO TEST CMD: Invalid cmd %d\n", cmd);
368                 break;
369                 }
370                 return;
371         }
372
373         for (i=0;i<len;i++) {
374                 if (recv_pattern == 0) {
375                         if (buf[i] != (char)(i)) {
376                                 RDA5890_ERRP("data[%d] error, 0x%02x, should be 0x%02x, len = %d\n", 
377                                         i, buf[i], (char)(i), len);
378                                 break;
379                         }
380                 }
381                 else {
382                         if (buf[i] != (char)(len - i - 1)) {
383                                 RDA5890_ERRP("data[%d] error, 0x%02x, should be 0x%02x, len = %d\n", 
384                                         i, buf[i], (char)(len - i - 1), len);
385                                 break;
386                         }
387                 }
388         }
389
390         if (recv_tput_flag)
391                 recv_pattern = !recv_pattern;
392
393         if (recv_tput_flag && i==len) {
394                 recv_pkts ++;
395                 recv_bytes += len;
396         }
397 }
398
399 static void sdio_tput_test_read(struct rda5890_private *priv, int iter, int len)
400 {
401         char cmd[SDIO_TEST_CMD_LEN];
402         int ret;
403
404         RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_TRACE,
405                 "%s, iter = %d, len = %d\n", __func__, iter, len);
406
407         (*(volatile unsigned long *)(cmd + 0)) = SDIO_TEST_CMD_MAGIC;
408         (*(volatile unsigned long *)(cmd + 4)) = SDIO_TEST_CMD_TYPE_C2H_START;
409         (*(volatile unsigned long *)(cmd + 8)) = iter;
410         (*(volatile unsigned long *)(cmd + 12)) = len;
411         ret = priv->hw_host_to_card(priv, cmd, len ,SDIO_TEST_CMD_LEN);
412         if (ret) {
413                 RDA5890_ERRP("START cmd send fail, ret = %d\n", ret);
414         }
415 }
416
417 static void sdio_tput_test_write(struct rda5890_private *priv, int iter, int len)
418 {
419         unsigned long addr = get_zeroed_page(GFP_KERNEL);
420         char *buf_1 = (char *)addr;
421         char *buf_2 = (char *)addr + PAGE_SIZE/2;
422         char cmd[SDIO_TEST_CMD_LEN];
423         int i;
424         int ret;
425
426         RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_TRACE,
427                 "%s, iter = %d, len = %d\n", __func__, iter, len);
428
429         for (i=0; i<len; i++) {
430                 buf_1[i] = len - i - 1;
431                 buf_2[i] = i;
432         }
433
434         (*(volatile unsigned long *)(cmd + 0)) = SDIO_TEST_CMD_MAGIC;
435         (*(volatile unsigned long *)(cmd + 4)) = SDIO_TEST_CMD_TYPE_H2C_START;
436         (*(volatile unsigned long *)(cmd + 8)) = iter;
437         (*(volatile unsigned long *)(cmd + 12)) = len;
438         ret = priv->hw_host_to_card(priv, cmd, len,SDIO_TEST_CMD_LEN);
439         if (ret) {
440                 RDA5890_ERRP("START cmd send fail, ret = %d\n", ret);
441                 goto out;
442         }
443
444         send_time_start = jiffies;
445         for (i=0;i<iter;i++) {
446                 if (!(i & 1))
447                         ret = priv->hw_host_to_card(priv, buf_1, len, DATA_REQUEST_PACKET);
448                 else
449                         ret = priv->hw_host_to_card(priv, buf_2, len, DATA_REQUEST_PACKET);
450                 if (ret) {
451                         RDA5890_ERRP("packet %d send fail, ret = %d\n", i, ret);
452                         goto out;
453                 }
454         }
455         send_time_end = jiffies;
456
457         (*(volatile unsigned long *)(cmd + 0)) = SDIO_TEST_CMD_MAGIC;
458         (*(volatile unsigned long *)(cmd + 4)) = SDIO_TEST_CMD_TYPE_H2C_STOP;
459         (*(volatile unsigned long *)(cmd + 8)) = iter;
460         (*(volatile unsigned long *)(cmd + 12)) = len;
461         ret = priv->hw_host_to_card(priv, cmd, len, SDIO_TEST_CMD_LEN);
462         if (ret) {
463                 RDA5890_ERRP("START cmd send fail, ret = %d\n", ret);
464                 goto out;
465         }
466
467 out:
468         free_page(addr);
469 }
470
471 static ssize_t rda5890_sdio_tput(struct file *file,
472                                 const char __user *user_buf, size_t count,
473                                 loff_t *ppos)
474 {
475         struct rda5890_private *priv = file->private_data;
476         int ret;
477         unsigned long addr = get_zeroed_page(GFP_KERNEL);
478         char *buf = (char *)addr;
479         int wr, iter, len;
480
481         RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_TRACE,
482                 "%s\n", __func__);
483
484         if (copy_from_user(buf, user_buf, count)) {
485                 ret = -EFAULT;
486                 goto out_unlock;
487         }
488         ret = sscanf(buf, "%d %d %d", &wr, &iter, &len);
489         if (ret != 3) {
490                 RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_TRACE,
491                         "Error Input, format shall be [wr iter len]\n");
492                 ret = -EINVAL;
493                 goto out_unlock;
494         }
495
496         RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_TRACE,
497                 "input wr = %d, iter = %d, len = %d\n",
498                 wr, iter, len);
499
500         if (wr)
501                 sdio_tput_test_write(priv, iter, len);
502         else
503                 sdio_tput_test_read(priv, iter, len);
504
505         ret = count;
506 out_unlock:
507         free_page(addr);
508         return ret;
509 }
510
511 #define FOPS(fread, fwrite) { \
512         .owner = THIS_MODULE, \
513         .open = open_file_generic, \
514         .read = (fread), \
515         .write = (fwrite), \
516 }
517
518 struct rda5890_debugfs_files {
519         char *name;
520         int perm;
521         struct file_operations fops;
522 };
523
524 static struct rda5890_debugfs_files debugfs_files[] = {
525         { "debug", 0444, FOPS(rda5890_debug_read, rda5890_debug_write), },
526         { "debugarea", 0444, FOPS(rda5890_debugarea_read, rda5890_debugarea_write), },
527         { "debuglevel", 0444, FOPS(rda5890_debuglevel_read, rda5890_debuglevel_write), },
528         { "sdioread", 0444, FOPS(NULL, rda5890_sdio_read), },
529         { "sdiowrite", 0444, FOPS(NULL, rda5890_sdio_write), },
530         { "sdiotput", 0444, FOPS(NULL, rda5890_sdio_tput), },
531 };
532
533 void rda5890_debugfs_init(void)
534 {
535         RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_DEBUG,
536                 "%s\n", __func__);
537
538         if (!rda5890_dir)
539                 rda5890_dir = debugfs_create_dir("rda5890", NULL);
540
541         return;
542 }
543
544 void rda5890_debugfs_remove(void)
545 {
546         RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_DEBUG,
547                 "%s\n", __func__);
548
549         if (rda5890_dir)
550                  debugfs_remove(rda5890_dir);
551
552         return;
553 }
554
555 void rda5890_debugfs_init_one(struct rda5890_private *priv)
556 {
557         int i;
558         struct rda5890_debugfs_files *files;
559         if (!rda5890_dir)
560                 goto exit;
561
562         RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_DEBUG,
563                 "%s\n", __func__);
564
565         priv->debugfs_dir = debugfs_create_dir("rda5890_dev", rda5890_dir);
566         if (!priv->debugfs_dir)
567                 goto exit;
568
569         for (i=0; i<ARRAY_SIZE(debugfs_files); i++) {
570                 files = &debugfs_files[i];
571                 priv->debugfs_files[i] = debugfs_create_file(files->name,
572                                                              files->perm,
573                                                              priv->debugfs_dir,
574                                                              priv,
575                                                              &files->fops);
576         }
577
578 exit:
579         return;
580 }
581
582 void rda5890_debugfs_remove_one(struct rda5890_private *priv)
583 {
584         int i;
585
586         RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_DEBUG,
587                 "%s\n", __func__);
588
589         for(i=0; i<ARRAY_SIZE(debugfs_files); i++)
590                 debugfs_remove(priv->debugfs_files[i]);
591         debugfs_remove(priv->debugfs_dir);
592 }
593