net: wireless: rockchip_wlan: add rtl8723bs support
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8723bs / os_dep / linux / rtw_proc.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2013 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *
19  ******************************************************************************/
20
21 #include <linux/ctype.h>        /* tolower() */
22 #include <drv_types.h>
23 #include <hal_data.h>
24 #include "rtw_proc.h"
25 #ifdef CONFIG_BT_COEXIST
26 #include <rtw_btcoex.h>
27 #endif
28
29 #ifdef CONFIG_PROC_DEBUG
30
31 static struct proc_dir_entry *rtw_proc = NULL;
32
33 inline struct proc_dir_entry *get_rtw_drv_proc(void)
34 {
35         return rtw_proc;
36 }
37
38 #define RTW_PROC_NAME DRV_NAME
39
40 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0))
41 #define file_inode(file) ((file)->f_dentry->d_inode)
42 #endif
43
44 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0))
45 #define PDE_DATA(inode) PDE((inode))->data
46 #define proc_get_parent_data(inode) PDE((inode))->parent->data
47 #endif
48
49 #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
50 #define get_proc_net proc_net
51 #else
52 #define get_proc_net init_net.proc_net
53 #endif
54
55 inline struct proc_dir_entry *rtw_proc_create_dir(const char *name, struct proc_dir_entry *parent, void *data)
56 {
57         struct proc_dir_entry *entry;
58
59 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
60         entry = proc_mkdir_data(name, S_IRUGO|S_IXUGO, parent, data);
61 #else
62         //entry = proc_mkdir_mode(name, S_IRUGO|S_IXUGO, parent);
63         entry = proc_mkdir(name, parent);
64         if (entry)
65                 entry->data = data;
66 #endif
67
68         return entry;
69 }
70
71 inline struct proc_dir_entry *rtw_proc_create_entry(const char *name, struct proc_dir_entry *parent, 
72         const struct file_operations *fops, void * data)
73 {
74         struct proc_dir_entry *entry;
75
76 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26))
77         entry = proc_create_data(name,  S_IFREG|S_IRUGO|S_IWUGO, parent, fops, data);
78 #else
79         entry = create_proc_entry(name, S_IFREG|S_IRUGO|S_IWUGO, parent);
80         if (entry) {
81                 entry->data = data;
82                 entry->proc_fops = fops;
83         }
84 #endif
85
86         return entry;
87 }
88
89 static int proc_get_dummy(struct seq_file *m, void *v)
90 {
91         return 0;
92 }
93
94 static int proc_get_drv_version(struct seq_file *m, void *v)
95 {
96         dump_drv_version(m);
97         return 0;
98 }
99
100 static int proc_get_log_level(struct seq_file *m, void *v)
101 {
102         dump_log_level(m);
103         return 0;
104 }
105
106 static int proc_get_drv_cfg(struct seq_file *m, void *v)
107 {
108         dump_drv_cfg(m);
109         return 0;
110 }
111
112 static ssize_t proc_set_log_level(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data)
113 {
114         char tmp[32];
115         int log_level;
116
117         if (count < 1)
118                 return -EINVAL;
119
120         if (count > sizeof(tmp)) {
121                 rtw_warn_on(1);
122                 return -EFAULT;
123         }
124
125         if (buffer && !copy_from_user(tmp, buffer, count)) {
126
127                 int num = sscanf(tmp, "%d ", &log_level);
128
129                 if( log_level >= _drv_always_ && log_level <= _drv_debug_ )
130                 {
131                         GlobalDebugLevel= log_level;
132                         printk("%d\n", GlobalDebugLevel);
133                 }
134         } else {
135                 return -EFAULT;
136         }
137         
138         return count;
139 }
140
141 #ifdef DBG_MEM_ALLOC
142 static int proc_get_mstat(struct seq_file *m, void *v)
143 {       
144         rtw_mstat_dump(m);
145         return 0;
146 }
147 #endif /* DBG_MEM_ALLOC */
148
149 static int proc_get_country_chplan_map(struct seq_file *m, void *v)
150 {
151         dump_country_chplan_map(m);
152         return 0;
153 }
154
155 static int proc_get_chplan_id_list(struct seq_file *m, void *v)
156 {
157         dump_chplan_id_list(m);
158         return 0;
159 }
160
161 static int proc_get_chplan_test(struct seq_file *m, void *v)
162 {
163         dump_chplan_test(m);
164         return 0;
165 }
166
167 /*
168 * rtw_drv_proc:
169 * init/deinit when register/unregister driver
170 */
171 const struct rtw_proc_hdl drv_proc_hdls [] = {
172         {"ver_info", proc_get_drv_version, NULL},
173         {"log_level", proc_get_log_level, proc_set_log_level},
174         {"drv_cfg", proc_get_drv_cfg, NULL},
175 #ifdef DBG_MEM_ALLOC
176         {"mstat", proc_get_mstat, NULL},
177 #endif /* DBG_MEM_ALLOC */
178         {"country_chplan_map", proc_get_country_chplan_map, NULL},
179         {"chplan_id_list", proc_get_chplan_id_list, NULL},
180         {"chplan_test", proc_get_chplan_test, NULL},
181 };
182
183 const int drv_proc_hdls_num = sizeof(drv_proc_hdls) / sizeof(struct rtw_proc_hdl);
184
185 static int rtw_drv_proc_open(struct inode *inode, struct file *file)
186 {
187         //struct net_device *dev = proc_get_parent_data(inode);
188         ssize_t index = (ssize_t)PDE_DATA(inode);
189         const struct rtw_proc_hdl *hdl = drv_proc_hdls+index;
190        return single_open(file, hdl->show, NULL);
191 }
192
193 static ssize_t rtw_drv_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos)
194 {
195         ssize_t index = (ssize_t)PDE_DATA(file_inode(file));
196         const struct rtw_proc_hdl *hdl = drv_proc_hdls+index;
197         ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *, void *) = hdl->write;
198         
199         if (write)
200                 return write(file, buffer, count, pos, NULL);
201
202         return -EROFS;
203 }
204
205 static const struct file_operations rtw_drv_proc_fops = {
206         .owner = THIS_MODULE,
207         .open = rtw_drv_proc_open,
208         .read = seq_read,
209         .llseek = seq_lseek,
210         .release = single_release,
211         .write = rtw_drv_proc_write,
212 };
213
214 int rtw_drv_proc_init(void)
215 {
216         int ret = _FAIL;
217         ssize_t i;
218         struct proc_dir_entry *entry = NULL;
219
220         if (rtw_proc != NULL) {
221                 rtw_warn_on(1);
222                 goto exit;
223         }
224
225         rtw_proc = rtw_proc_create_dir(RTW_PROC_NAME, get_proc_net, NULL);
226
227         if (rtw_proc == NULL) {
228                 rtw_warn_on(1);
229                 goto exit;
230         }
231
232         for (i=0;i<drv_proc_hdls_num;i++) {
233                 entry = rtw_proc_create_entry(drv_proc_hdls[i].name, rtw_proc, &rtw_drv_proc_fops, (void *)i);
234                 if (!entry) {
235                         rtw_warn_on(1);
236                         goto exit;
237                 }
238         }
239
240         ret = _SUCCESS;
241
242 exit:
243         return ret;
244 }
245
246 void rtw_drv_proc_deinit(void)
247 {
248         int i;
249
250         if (rtw_proc == NULL)
251                 return;
252
253         for (i=0;i<drv_proc_hdls_num;i++)
254                 remove_proc_entry(drv_proc_hdls[i].name, rtw_proc);
255
256         remove_proc_entry(RTW_PROC_NAME, get_proc_net);
257         rtw_proc = NULL;
258 }
259
260 #ifdef CONFIG_SDIO_HCI
261 static int proc_get_sd_f0_reg_dump(struct seq_file *m, void *v)
262 {
263         struct net_device *dev = m->private;
264         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
265
266         sd_f0_reg_dump(m, adapter);
267
268         return 0;
269 }
270
271 static int proc_get_sdio_local_reg_dump(struct seq_file *m, void *v)
272 {
273         struct net_device *dev = m->private;
274         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
275
276         sdio_local_reg_dump(m, adapter);
277
278         return 0;
279 }
280 #endif /* CONFIG_SDIO_HCI */
281
282 static int proc_get_mac_reg_dump(struct seq_file *m, void *v)
283 {
284         struct net_device *dev = m->private;
285         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
286
287         mac_reg_dump(m, adapter);
288
289         return 0;
290 }
291
292 static int proc_get_bb_reg_dump(struct seq_file *m, void *v)
293 {
294         struct net_device *dev = m->private;
295         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
296
297         bb_reg_dump(m, adapter);
298
299         return 0;
300 }
301
302 static int proc_get_rf_reg_dump(struct seq_file *m, void *v)
303 {
304         struct net_device *dev = m->private;
305         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
306
307         rf_reg_dump(m, adapter);
308
309         return 0;
310 }
311
312 static int proc_get_dump_adapters_status(struct seq_file *m, void *v)
313 {
314         struct net_device *dev = m->private;
315         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
316
317         dump_adapters_status(m, adapter_to_dvobj(adapter));
318
319         return 0;
320 }
321
322 //gpio setting
323 #ifdef CONFIG_GPIO_API
324 static ssize_t proc_set_config_gpio(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data)
325 {
326         struct net_device *dev = data;
327         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
328         char tmp[32]={0}; 
329         int num=0,gpio_pin=0,gpio_mode=0;//gpio_mode:0 input  1:output;
330         
331         if (count < 2)
332                 return -EFAULT;
333
334         if (count > sizeof(tmp)) {
335                 rtw_warn_on(1);
336                 return -EFAULT;
337         }
338
339         if (buffer && !copy_from_user(tmp, buffer, count)) {
340                 num     =sscanf(tmp, "%d %d",&gpio_pin,&gpio_mode);
341                 DBG_871X("num=%d gpio_pin=%d mode=%d\n",num,gpio_pin,gpio_mode);
342                 padapter->pre_gpio_pin=gpio_pin;
343
344                 if(gpio_mode==0 || gpio_mode==1  )
345                         rtw_hal_config_gpio(padapter, gpio_pin,gpio_mode);      
346         }
347         return count;
348
349 }
350 static ssize_t proc_set_gpio_output_value(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data)
351 {
352         struct net_device *dev = data;
353         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
354         char tmp[32]={0}; 
355         int num=0,gpio_pin=0,pin_mode=0;//pin_mode: 1 high         0:low
356         
357         if (count < 2)
358                 return -EFAULT;
359
360         if (count > sizeof(tmp)) {
361                 rtw_warn_on(1);
362                 return -EFAULT;
363         }
364
365         if (buffer && !copy_from_user(tmp, buffer, count)) {
366                 num     =sscanf(tmp, "%d %d",&gpio_pin,&pin_mode);
367                 DBG_871X("num=%d gpio_pin=%d pin_high=%d\n",num,gpio_pin,pin_mode);
368                 padapter->pre_gpio_pin=gpio_pin;
369                 
370                 if(pin_mode==0 || pin_mode==1  )
371                         rtw_hal_set_gpio_output_value(padapter, gpio_pin,pin_mode);     
372         }
373         return count;
374 }
375 static int proc_get_gpio(struct seq_file *m, void *v)
376 {
377         u8 gpioreturnvalue=0;
378         struct net_device *dev = m->private;
379         
380         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
381         if(!padapter)   
382                 return -EFAULT;
383         gpioreturnvalue = rtw_hal_get_gpio(padapter, padapter->pre_gpio_pin);
384         DBG_871X_SEL_NL(m, "get_gpio %d:%d \n",padapter->pre_gpio_pin ,gpioreturnvalue);
385         
386         return 0;
387
388 }
389 static ssize_t proc_set_gpio(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data)
390 {
391         struct net_device *dev = data;
392         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
393         char tmp[32]={0}; 
394         int num=0,gpio_pin=0;
395         
396         if (count < 1)
397                 return -EFAULT;
398
399         if (count > sizeof(tmp)) {
400                 rtw_warn_on(1);
401                 return -EFAULT;
402         }
403
404         if (buffer && !copy_from_user(tmp, buffer, count)) {
405                 num     =sscanf(tmp, "%d",&gpio_pin);
406                 DBG_871X("num=%d gpio_pin=%d\n",num,gpio_pin);
407                 padapter->pre_gpio_pin=gpio_pin;
408                 
409         }
410                 return count;
411 }
412 #endif
413 static int proc_get_current_tx_rate(struct seq_file *m, void *v)
414 {
415
416         struct net_device *dev = m->private;
417         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
418         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
419         struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
420         u8 i;
421         u8 null_addr[ETH_ALEN] = {0};
422         u8 *macaddr;
423         u8 current_rate_id = 0;
424
425         DBG_871X_SEL_NL(m, "%-5s %-4s %-17s %-7s\n"
426                 , "macid", "if_g", "macaddr", "tx_rate");
427
428         for (i = 0; i < macid_ctl->num; i++) {
429                 if (rtw_macid_is_used(macid_ctl, i) || macid_ctl->h2c_msr[i]) {
430                         if (macid_ctl->sta[i])
431                                 macaddr = macid_ctl->sta[i]->hwaddr;
432                         else
433                                 macaddr = null_addr;
434                         current_rate_id = rtw_get_current_tx_rate(adapter, i);
435                         if (!rtw_macid_is_bmc(macid_ctl, i)) {
436                                 DBG_871X_SEL_NL(m, "%5u %4u "MAC_FMT" %s\n"
437                                 , i
438                                 , rtw_macid_get_if_g(macid_ctl, i)
439                                 , MAC_ARG(macaddr)
440                                 , HDATA_RATE(current_rate_id)
441                                 );
442                         }
443
444
445                 }
446         }
447
448
449 return 0;
450
451 }
452
453
454 static int proc_get_linked_info_dump(struct seq_file *m, void *v)
455 {
456         struct net_device *dev = m->private;
457         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
458         if(padapter)    
459                 DBG_871X_SEL_NL(m, "linked_info_dump :%s \n", (padapter->bLinkInfoDump)?"enable":"disable");
460         
461         return 0;
462 }
463
464
465 static ssize_t proc_set_linked_info_dump(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data)
466 {
467         struct net_device *dev = data;
468         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
469
470         char tmp[32]={0}; 
471         int mode=0,pre_mode=0;
472         int num=0;      
473
474         if (count < 1)
475                 return -EFAULT;
476
477         if (count > sizeof(tmp)) {
478                 rtw_warn_on(1);
479                 return -EFAULT;
480         }
481
482         pre_mode=padapter->bLinkInfoDump;
483         DBG_871X("pre_mode=%d\n", pre_mode);
484
485         if (buffer && !copy_from_user(tmp, buffer, count)) {
486
487                 num     =sscanf(tmp, "%d ", &mode);
488                 DBG_871X("num=%d mode=%d\n",num,mode);
489
490                 if(num!=1)
491                 {
492                         DBG_871X("argument number is wrong\n");
493                                 return -EFAULT;
494                 }
495         
496                 if(mode==1 || (mode==0 && pre_mode==1) ) //not consider pwr_saving 0:
497                 {
498                         padapter->bLinkInfoDump = mode; 
499                 
500                 }
501                 else if( (mode==2 ) || (mode==0 && pre_mode==2))//consider power_saving
502                 {               
503                         //DBG_871X("linked_info_dump =%s \n", (padapter->bLinkInfoDump)?"enable":"disable")
504                         linked_info_dump(padapter,mode);        
505                 }
506         }
507         return count;
508 }
509
510 static int proc_get_mac_qinfo(struct seq_file *m, void *v)
511 {
512         struct net_device *dev = m->private;
513         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
514
515         rtw_hal_get_hwreg(adapter, HW_VAR_DUMP_MAC_QUEUE_INFO, (u8 *)m);
516
517         return 0;
518 }
519
520 int proc_get_wifi_spec(struct seq_file *m, void *v)
521 {
522         struct net_device *dev = m->private;
523         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
524         struct registry_priv    *pregpriv = &padapter->registrypriv;
525         
526         DBG_871X_SEL_NL(m,"wifi_spec=%d\n",pregpriv->wifi_spec);
527         return 0;
528 }
529
530 static int proc_get_chan_plan(struct seq_file *m, void *v)
531 {
532         struct net_device *dev = m->private;
533         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
534
535         dump_cur_chset(m, adapter);
536
537         return 0;
538 }
539
540 static ssize_t proc_set_chan_plan(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data)
541 {
542         struct net_device *dev = data;
543         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
544         char tmp[32];
545         u8 chan_plan = RTW_CHPLAN_MAX;
546
547         if (!padapter)
548                 return -EFAULT;
549
550         if (count < 1)
551         {
552                 DBG_871X("argument size is less than 1\n");
553                 return -EFAULT;
554         }       
555
556         if (count > sizeof(tmp)) {
557                 rtw_warn_on(1);
558                 return -EFAULT;
559         }
560
561         if (buffer && !copy_from_user(tmp, buffer, count)) {
562                 int num = sscanf(tmp, "%hhx", &chan_plan);
563                 if (num !=  1)
564                         return count;
565         }
566
567         rtw_set_channel_plan(padapter, chan_plan);
568
569         return count;
570 }
571
572 static int proc_get_country_code(struct seq_file *m, void *v)
573 {
574         struct net_device *dev = m->private;
575         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
576
577         if (adapter->mlmepriv.country_ent)
578                 dump_country_chplan(m, adapter->mlmepriv.country_ent);
579         else
580                 DBG_871X_SEL_NL(m, "unspecified\n");
581
582         return 0;
583 }
584
585 static ssize_t proc_set_country_code(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data)
586 {
587         struct net_device *dev = data;
588         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
589         char tmp[32];
590         char alpha2[2];
591         int num;
592
593         if (count < 1)
594                 return -EFAULT;
595
596         if (count > sizeof(tmp)) {
597                 rtw_warn_on(1);
598                 return -EFAULT;
599         }
600
601         if (!buffer || copy_from_user(tmp, buffer, count))
602                 goto exit;
603
604         num = sscanf(tmp, "%c%c", &alpha2[0], &alpha2[1]);
605         if (num !=      2)
606                 return count;
607
608         rtw_set_country(padapter, alpha2);
609
610 exit:
611         return count;
612 }
613
614 #ifdef CONFIG_DFS_MASTER
615 ssize_t proc_set_update_non_ocp(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data)
616 {
617         struct net_device *dev = data;
618         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
619         struct mlme_priv *mlme = &adapter->mlmepriv;
620         struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
621         char tmp[32];
622         u8 ch, bw = CHANNEL_WIDTH_20, offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
623         int ms = -1;
624
625         if (count < 1)
626                 return -EFAULT;
627
628         if (count > sizeof(tmp)) {
629                 rtw_warn_on(1);
630                 return -EFAULT;
631         }
632
633         if (buffer && !copy_from_user(tmp, buffer, count)) {
634
635                 int num = sscanf(tmp, "%hhu %hhu %hhu %d", &ch, &bw, &offset, &ms);
636
637                 if (num < 1 || (bw != CHANNEL_WIDTH_20 && num < 3))
638                         goto exit;
639
640                 if (bw == CHANNEL_WIDTH_20)
641                         rtw_chset_update_non_ocp_ms(mlmeext->channel_set
642                                 , ch, bw, HAL_PRIME_CHNL_OFFSET_DONT_CARE, ms);
643                 else
644                         rtw_chset_update_non_ocp_ms(mlmeext->channel_set
645                                 , ch, bw, offset, ms);
646         }
647
648 exit:
649         return count;
650 }
651
652 ssize_t proc_set_radar_detect(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data)
653 {
654         struct net_device *dev = data;
655         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
656         struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
657         char tmp[32];
658         u8 fake_radar_detect_cnt = 0;
659
660         if (count < 1)
661                 return -EFAULT;
662
663         if (count > sizeof(tmp)) {
664                 rtw_warn_on(1);
665                 return -EFAULT;
666         }
667
668         if (buffer && !copy_from_user(tmp, buffer, count)) {
669
670                 int num = sscanf(tmp, "%hhu", &fake_radar_detect_cnt);
671
672                 if (num < 1)
673                         goto exit;
674
675                 rfctl->dbg_dfs_master_fake_radar_detect_cnt = fake_radar_detect_cnt;
676         }
677
678 exit:
679         return count;
680 }
681 #endif /* CONFIG_DFS_MASTER */
682
683 static int proc_get_udpport(struct seq_file *m, void *v)
684 {
685         struct net_device *dev = m->private;
686         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
687         struct recv_priv *precvpriv = &(padapter->recvpriv);
688
689         DBG_871X_SEL_NL(m,"%d\n",precvpriv->sink_udpport);      
690         return 0;
691 }
692 static ssize_t proc_set_udpport(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data)
693 {
694         struct net_device *dev = data;
695         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
696         struct recv_priv *precvpriv = &(padapter->recvpriv);
697         int sink_udpport = 0;   
698         char tmp[32];
699         
700         
701         if (!padapter)
702                 return -EFAULT;
703
704         if (count < 1)
705         {
706                 DBG_871X("argument size is less than 1\n");
707                 return -EFAULT;
708         }       
709
710         if (count > sizeof(tmp)) {
711                 rtw_warn_on(1);
712                 return -EFAULT;
713         }
714
715         if (buffer && !copy_from_user(tmp, buffer, count)) {
716
717                 int num = sscanf(tmp, "%d", &sink_udpport);
718
719                 if (num !=  1) {
720                         DBG_871X("invalid input parameter number!\n");
721                         return count;
722                 }
723
724         }
725         precvpriv->sink_udpport = sink_udpport;
726         
727         return count;
728
729 }
730
731 static int proc_get_macid_info(struct seq_file *m, void *v)
732 {
733         struct net_device *dev = m->private;
734         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
735         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
736         struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
737         u8 i;
738         u8 null_addr[ETH_ALEN] = {0};
739         u8 *macaddr;
740
741         DBG_871X_SEL_NL(m, "max_num:%u\n", macid_ctl->num);
742         DBG_871X_SEL_NL(m, "\n");
743
744         DBG_871X_SEL_NL(m, "used:\n");
745         dump_macid_map(m, &macid_ctl->used, macid_ctl->num);
746         DBG_871X_SEL_NL(m, "\n");
747
748         DBG_871X_SEL_NL(m, "%-3s %-3s %-4s %-4s %-17s %s"
749                 "\n"
750                 , "id", "bmc", "if_g", "ch_g", "macaddr", "status"
751         );
752
753         for (i=0;i<macid_ctl->num;i++) {
754                 if (rtw_macid_is_used(macid_ctl, i)
755                         || macid_ctl->h2c_msr[i]
756                 ) {
757                         if (macid_ctl->sta[i])
758                                 macaddr = macid_ctl->sta[i]->hwaddr;
759                         else
760                                 macaddr = null_addr;
761
762                         DBG_871X_SEL_NL(m, "%3u %3u %4d %4d "MAC_FMT" "H2C_MSR_FMT" %s"
763                                 "\n"
764                                 , i
765                                 , rtw_macid_is_bmc(macid_ctl, i)
766                                 , rtw_macid_get_if_g(macid_ctl, i)
767                                 , rtw_macid_get_ch_g(macid_ctl, i)
768                                 , MAC_ARG(macaddr)
769                                 , H2C_MSR_ARG(&macid_ctl->h2c_msr[i])
770                                 , rtw_macid_is_used(macid_ctl, i) ? "" : "[unused]"
771                         );
772                 }
773         }
774
775         return 0;
776 }
777
778 static int proc_get_sec_cam(struct seq_file *m, void *v)
779 {
780         struct net_device *dev = m->private;
781         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
782         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
783         struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
784
785         DBG_871X_SEL_NL(m, "sec_cap:0x%02x\n", cam_ctl->sec_cap);
786         DBG_871X_SEL_NL(m, "flags:0x%08x\n", cam_ctl->flags);
787         DBG_871X_SEL_NL(m, "\n");
788
789         DBG_871X_SEL_NL(m, "max_num:%u\n", cam_ctl->num);
790         DBG_871X_SEL_NL(m, "used:\n");
791         dump_sec_cam_map(m, &cam_ctl->used, cam_ctl->num);
792         DBG_871X_SEL_NL(m, "\n");
793
794         DBG_871X_SEL_NL(m, "reg_scr:0x%04x\n", rtw_read16(adapter, 0x680));
795         DBG_871X_SEL_NL(m, "\n");
796
797         dump_sec_cam(m, adapter);
798
799         return 0;
800 }
801
802 static ssize_t proc_set_sec_cam(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data)
803 {
804         struct net_device *dev = data;
805         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
806         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
807         struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
808         char tmp[32] = {0};
809         char cmd[4];
810         u8 id;
811
812         if (count > sizeof(tmp)) {
813                 rtw_warn_on(1);
814                 return -EFAULT;
815         }
816
817         if (buffer && !copy_from_user(tmp, buffer, count)) {
818
819                 /* c <id>: clear specific cam entry */
820                 /* wfc <id>: write specific cam entry from cam cache */
821
822                 int num = sscanf(tmp, "%s %hhu", cmd, &id);
823
824                 if (num < 2)
825                         return count;
826
827                 if (id >= cam_ctl->num) {
828                         DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT" invalid id:%u\n", FUNC_ADPT_ARG(adapter), id);
829                         return count;
830                 }
831
832                 if (strcmp("c", cmd) == 0) {
833                         _clear_cam_entry(adapter, id);
834                         adapter->securitypriv.hw_decrypted = _FALSE; /* temporarily set this for TX path to use SW enc */
835                 } else if (strcmp("wfc", cmd) == 0) {
836                         write_cam_from_cache(adapter, id);
837                 }
838         }
839
840         return count;
841 }
842
843 static int proc_get_sec_cam_cache(struct seq_file *m, void *v)
844 {
845         struct net_device *dev = m->private;
846         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
847         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
848         struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
849         u8 i;
850
851         DBG_871X_SEL_NL(m, "SW sec cam cache:\n");
852         dump_sec_cam_ent_title(m, 1);
853         for (i = 0; i < cam_ctl->num; i++) {
854                 if (dvobj->cam_cache[i].ctrl != 0)
855                         dump_sec_cam_ent(m, &dvobj->cam_cache[i], i);
856         }
857
858         return 0;
859 }
860
861 static ssize_t proc_set_change_bss_chbw(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data)
862 {
863         struct net_device *dev = data;
864         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
865         struct mlme_priv *mlme = &(adapter->mlmepriv);
866         struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);
867         char tmp[32];
868         u8 ch, bw = CHANNEL_WIDTH_20, offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
869
870         if (count < 1)
871                 return -EFAULT;
872
873         if (count > sizeof(tmp)) {
874                 rtw_warn_on(1);
875                 return -EFAULT;
876         }
877
878         if (buffer && !copy_from_user(tmp, buffer, count)) {
879
880                 int num = sscanf(tmp, "%hhu %hhu %hhu", &ch, &bw, &offset);
881
882                 if (num < 1 || (bw != CHANNEL_WIDTH_20 && num < 3))
883                         goto exit;
884
885                 if (check_fwstate(mlme, WIFI_AP_STATE) && check_fwstate(mlme, WIFI_ASOC_STATE))
886                         rtw_change_bss_chbw_cmd(adapter, RTW_CMDF_WAIT_ACK, ch, bw, offset);
887         }
888
889 exit:
890         return count;
891 }
892
893 static int proc_get_target_tx_power(struct seq_file *m, void *v)
894 {
895         struct net_device *dev = m->private;
896         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
897
898         dump_target_tx_power(m, adapter);
899
900         return 0;
901 }
902
903 static int proc_get_tx_power_by_rate(struct seq_file *m, void *v)
904 {
905         struct net_device *dev = m->private;
906         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
907
908         dump_tx_power_by_rate(m, adapter);
909
910         return 0;
911 }
912
913 static int proc_get_tx_power_limit(struct seq_file *m, void *v)
914 {
915         struct net_device *dev = m->private;
916         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
917
918         dump_tx_power_limit(m, adapter);
919
920         return 0;
921 }
922
923 static int proc_get_tx_power_ext_info(struct seq_file *m, void *v)
924 {
925         struct net_device *dev = m->private;
926         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
927
928         dump_tx_power_ext_info(m, adapter);
929
930         return 0;
931 }
932
933 static ssize_t proc_set_tx_power_ext_info(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data)
934 {
935         struct net_device *dev = data;
936         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
937
938         char tmp[32] = {0};
939         char cmd[16] = {0};
940
941         if (count > sizeof(tmp)) {
942                 rtw_warn_on(1);
943                 return -EFAULT;
944         }
945
946         if (buffer && !copy_from_user(tmp, buffer, count)) {
947
948                 int num = sscanf(tmp, "%s", cmd);
949
950                 if (num < 1)
951                         return count;
952
953                 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
954                 phy_free_filebuf_mask(adapter, LOAD_BB_PG_PARA_FILE | LOAD_RF_TXPWR_LMT_PARA_FILE);
955                 #endif
956
957                 rtw_ps_deny(adapter, PS_DENY_IOCTL);
958                 LeaveAllPowerSaveModeDirect(adapter);
959
960                 if (strcmp("default", cmd) == 0)
961                         rtw_run_in_thread_cmd(adapter, ((void *)(phy_reload_default_tx_power_ext_info)), adapter);
962                 else
963                         rtw_run_in_thread_cmd(adapter, ((void *)(phy_reload_tx_power_ext_info)), adapter);
964
965                 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
966         }
967
968         return count;
969 }
970
971 #ifdef CONFIG_RF_GAIN_OFFSET
972 static int proc_get_kfree_flag(struct seq_file *m, void *v)
973 {
974         struct net_device *dev = m->private;
975         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
976         struct kfree_data_t *kfree_data = GET_KFREE_DATA(adapter);
977
978         DBG_871X_SEL_NL(m, "0x%02x\n", kfree_data->flag);
979
980         return 0;
981 }
982
983 static ssize_t proc_set_kfree_flag(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data)
984 {
985         struct net_device *dev = data;
986         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
987         struct kfree_data_t *kfree_data = GET_KFREE_DATA(adapter);
988         char tmp[32] = {0};
989         u8 flag;
990
991         if (count > sizeof(tmp)) {
992                 rtw_warn_on(1);
993                 return -EFAULT;
994         }
995
996         if (buffer && !copy_from_user(tmp, buffer, count)) {
997
998                 int num = sscanf(tmp, "%hhx", &flag);
999
1000                 if (num < 1)
1001                         return count;
1002
1003                 kfree_data->flag = flag;
1004         }
1005
1006         return count;
1007 }
1008
1009 static int proc_get_kfree_bb_gain(struct seq_file *m, void *v)
1010 {
1011         struct net_device *dev = m->private;
1012         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
1013         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1014         struct kfree_data_t *kfree_data = GET_KFREE_DATA(adapter);
1015         u8 i, j;
1016
1017          for (i = 0; i < BB_GAIN_NUM; i++) {
1018                 if (i == 0)
1019                         DBG_871X_SEL(m, "2G: ");
1020                 else if (i == 1)
1021                         DBG_871X_SEL(m, "5GLB1: ");
1022                 else if (i == 2)
1023                         DBG_871X_SEL(m, "5GLB2: ");
1024                 else if (i == 3)
1025                         DBG_871X_SEL(m, "5GMB1: ");
1026                 else if (i == 4)
1027                         DBG_871X_SEL(m, "5GMB2: ");
1028                 else if (i == 5)
1029                         DBG_871X_SEL(m, "5GHB: ");
1030
1031                 for (j = 0; j < hal_data->NumTotalRFPath; j++)
1032                         DBG_871X_SEL(m, "%d ", kfree_data->bb_gain[i][j]);
1033                 DBG_871X_SEL(m, "\n");
1034         }
1035
1036         return 0;
1037 }
1038
1039 static ssize_t proc_set_kfree_bb_gain(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data)
1040 {
1041         struct net_device *dev = data;
1042         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
1043         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1044         struct kfree_data_t *kfree_data = GET_KFREE_DATA(adapter);
1045         char tmp[BB_GAIN_NUM * RF_PATH_MAX] = {0};
1046         u8 path, chidx;
1047         s8 bb_gain[BB_GAIN_NUM];
1048         char ch_band_Group[6];
1049
1050         if (count > sizeof(tmp)) {
1051                 rtw_warn_on(1);
1052                 return -EFAULT;
1053         }
1054
1055         if (buffer && !copy_from_user(tmp, buffer, count)) {
1056                 char *c, *next;
1057                 int i = 0;
1058
1059                 next = tmp;
1060                 c = strsep(&next, " \t");
1061
1062                 if (sscanf(c, "%s", ch_band_Group) != 1) {
1063                         DBG_871X("Error Head Format, channel Group select\n,Please input:\t 2G , 5GLB1 , 5GLB2 , 5GMB1 , 5GMB2 , 5GHB\n");
1064                         return count;
1065                 }
1066                 if (strcmp("2G", ch_band_Group) == 0)
1067                         chidx = BB_GAIN_2G;
1068 #ifdef CONFIG_IEEE80211_BAND_5GHZ
1069                 else if (strcmp("5GLB1", ch_band_Group) == 0)
1070                         chidx = BB_GAIN_5GLB1;
1071                 else if (strcmp("5GLB2", ch_band_Group) == 0)
1072                         chidx = BB_GAIN_5GLB2;
1073                 else if (strcmp("5GMB1", ch_band_Group) == 0)
1074                         chidx = BB_GAIN_5GMB1;
1075                 else if (strcmp("5GMB2", ch_band_Group) == 0)
1076                         chidx = BB_GAIN_5GMB2;
1077                 else if (strcmp("5GHB", ch_band_Group) == 0)
1078                         chidx = BB_GAIN_5GHB;
1079 #endif /*CONFIG_IEEE80211_BAND_5GHZ*/
1080                 else {
1081                         DBG_871X("Error Head Format, channel Group select\n,Please input:\t 2G , 5GLB1 , 5GLB2 , 5GMB1 , 5GMB2 , 5GHB\n");
1082                         return count;
1083                 }
1084                 c = strsep(&next, " \t");
1085
1086                 while (c != NULL) {
1087                         if (sscanf(c, "%hhx", &bb_gain[i]) != 1)
1088                                 break;
1089
1090                         kfree_data->bb_gain[chidx][i] = bb_gain[i];
1091                         DBG_871X("%s,kfree_data->bb_gain[%d][%d]=%x\n", __func__, chidx, i, kfree_data->bb_gain[chidx][i]);
1092
1093                         c = strsep(&next, " \t");
1094                         i++;
1095                 }
1096
1097         }
1098
1099         return count;
1100
1101 }
1102
1103 static int proc_get_kfree_thermal(struct seq_file *m, void *v)
1104 {
1105         struct net_device *dev = m->private;
1106         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
1107         struct kfree_data_t *kfree_data = GET_KFREE_DATA(adapter);
1108
1109         DBG_871X_SEL(m, "%d\n", kfree_data->thermal);
1110
1111         return 0;
1112 }
1113
1114 static ssize_t proc_set_kfree_thermal(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data)
1115 {
1116         struct net_device *dev = data;
1117         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
1118         struct kfree_data_t *kfree_data = GET_KFREE_DATA(adapter);
1119         char tmp[32] = {0};
1120         s8 thermal;
1121
1122         if (count > sizeof(tmp)) {
1123                 rtw_warn_on(1);
1124                 return -EFAULT;
1125         }
1126
1127         if (buffer && !copy_from_user(tmp, buffer, count)) {
1128
1129                 int num = sscanf(tmp, "%hhd", &thermal);
1130
1131                 if (num < 1)
1132                         return count;
1133
1134                 kfree_data->thermal = thermal;
1135         }
1136
1137         return count;
1138 }
1139
1140 static ssize_t proc_set_tx_gain_offset(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data)
1141 {
1142         struct net_device *dev = data;
1143         _adapter *adapter;
1144         char tmp[32] = {0};
1145         u8 rf_path;
1146         s8 offset;
1147
1148         adapter = (_adapter *)rtw_netdev_priv(dev);
1149         if (!adapter)
1150                 return -EFAULT;
1151
1152         if (count > sizeof(tmp)) {
1153                 rtw_warn_on(1);
1154                 return -EFAULT;
1155         }
1156
1157         if (buffer && !copy_from_user(tmp, buffer, count)) {
1158                 u8 write_value;
1159                 int num = sscanf(tmp, "%hhu %hhd", &rf_path, &offset);
1160
1161                 if (num < 2)
1162                         return count;
1163
1164                 DBG_871X("write rf_path:%u tx gain offset:%d\n", rf_path, offset);
1165                 rtw_rf_set_tx_gain_offset(adapter, rf_path, offset);
1166         }
1167
1168         return count;
1169 }
1170 #endif /* CONFIG_RF_GAIN_OFFSET */
1171
1172 #ifdef CONFIG_BT_COEXIST
1173 ssize_t proc_set_btinfo_evt(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data)
1174 {
1175         struct net_device *dev = data;
1176         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1177         char tmp[32];
1178         u8 btinfo[8];
1179
1180         if (count < 6)
1181                 return -EFAULT;
1182
1183         if (count > sizeof(tmp)) {
1184                 rtw_warn_on(1);
1185                 return -EFAULT;
1186         }
1187
1188         if (buffer && !copy_from_user(tmp, buffer, count)) {
1189                 int num = 0;
1190
1191                 _rtw_memset(btinfo, 0, 8);
1192                 
1193                 num = sscanf(tmp, "%hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx"
1194                         , &btinfo[0], &btinfo[1], &btinfo[2], &btinfo[3]
1195                         , &btinfo[4], &btinfo[5], &btinfo[6], &btinfo[7]);
1196
1197                 if (num < 6)
1198                         return -EINVAL;
1199
1200                 btinfo[1] = num-2;
1201
1202                 rtw_btinfo_cmd(padapter, btinfo, btinfo[1]+2);
1203         }
1204         
1205         return count;
1206 }
1207
1208 static u8 btreg_read_type = 0;
1209 static u16 btreg_read_addr = 0;
1210 static int btreg_read_error = 0;
1211 static u8 btreg_write_type = 0;
1212 static u16 btreg_write_addr = 0;
1213 static int btreg_write_error = 0;
1214
1215 static u8 *btreg_type[] = {
1216         "rf",
1217         "modem",
1218         "bluewize",
1219         "vendor",
1220         "le"
1221 };
1222
1223 static int btreg_parse_str(char *input, u8 *type, u16 *addr, u16 *val)
1224 {
1225         u32 num;
1226         u8 str[80] = {0};
1227         u8 t = 0;
1228         u32 a, v;
1229         u8 i, n;
1230         u8 *p;
1231
1232
1233         num = sscanf(input, "%s %x %x", str, &a, &v);
1234         if (num < 2) {
1235                 DBG_871X("%s: INVALID input!(%s)\n", __FUNCTION__, input);
1236                 return -EINVAL;
1237         }
1238         if ((num < 3) && val) {
1239                 DBG_871X("%s: INVALID input!(%s)\n", __FUNCTION__, input);
1240                 return -EINVAL;
1241         }
1242
1243         /* convert to lower case for following type compare */
1244         p = str;
1245         for ( ; *p; ++p)
1246                 *p = tolower(*p);
1247         n = sizeof(btreg_type)/sizeof(btreg_type[0]);
1248         for (i = 0; i < n; i++) {
1249                 if (!strcmp(str, btreg_type[i])) {
1250                         t = i;
1251                         break;
1252                 }
1253         }
1254         if (i == n) {
1255                 DBG_871X("%s: unknown type(%s)!\n", __FUNCTION__, str);
1256                 return -EINVAL;
1257         }
1258
1259         switch (t) {
1260         case 0:
1261                 /* RF */
1262                 if (a & 0xFFFFFF80) {
1263                         DBG_871X("%s: INVALID address(0x%X) for type %s(%d)!\n",
1264                                 __FUNCTION__, a, btreg_type[t], t);
1265                         return -EINVAL;
1266                 }
1267                 break;
1268         case 1:
1269                 /* Modem */
1270                 if (a & 0xFFFFFE00) {
1271                         DBG_871X("%s: INVALID address(0x%X) for type %s(%d)!\n",
1272                                 __FUNCTION__, a, btreg_type[t], t);
1273                         return -EINVAL;
1274                 }
1275                 break;
1276         default:
1277                 /* Others(Bluewize, Vendor, LE) */
1278                 if (a & 0xFFFFF000) {
1279                         DBG_871X("%s: INVALID address(0x%X) for type %s(%d)!\n",
1280                                 __FUNCTION__, a, btreg_type[t], t);
1281                         return -EINVAL;
1282                 }
1283                 break;
1284         }
1285
1286         if (val) {
1287                 if (v & 0xFFFF0000) {
1288                         DBG_871X("%s: INVALID value(0x%x)!\n", __FUNCTION__, v);
1289                         return -EINVAL;
1290                 }
1291                 *val = (u16)v;
1292         }
1293
1294         *type = (u8)t;
1295         *addr = (u16)a;
1296
1297         return 0;
1298 }
1299
1300 int proc_get_btreg_read(struct seq_file *m, void *v)
1301 {
1302         struct net_device *dev;
1303         PADAPTER padapter;
1304         u16 ret;
1305         u32 data;
1306
1307
1308         if (btreg_read_error)
1309                 return btreg_read_error;
1310
1311         dev = m->private;
1312         padapter = (PADAPTER)rtw_netdev_priv(dev);
1313
1314         ret = rtw_btcoex_btreg_read(padapter, btreg_read_type, btreg_read_addr, &data);
1315         if (CHECK_STATUS_CODE_FROM_BT_MP_OPER_RET(ret, BT_STATUS_BT_OP_SUCCESS))
1316                 DBG_871X_SEL_NL(m, "BTREG read: (%s)0x%04X = 0x%08x\n", btreg_type[btreg_read_type], btreg_read_addr, data);
1317         else
1318                 DBG_871X_SEL_NL(m, "BTREG read: (%s)0x%04X read fail. error code = 0x%04x.\n", btreg_type[btreg_read_type], btreg_read_addr, ret);
1319
1320         return 0;
1321 }
1322
1323 ssize_t proc_set_btreg_read(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data)
1324 {
1325         struct net_device *dev = data;
1326         PADAPTER padapter;
1327         u8 tmp[80] = {0};
1328         u32 num;
1329         int err;
1330
1331
1332         padapter = (PADAPTER)rtw_netdev_priv(dev);
1333
1334         if (NULL == buffer) {
1335                 DBG_871X(FUNC_ADPT_FMT ": input buffer is NULL!\n",
1336                         FUNC_ADPT_ARG(padapter));
1337                 err = -EFAULT;
1338                 goto exit;
1339         }
1340
1341         if (count < 1) {
1342                 DBG_871X(FUNC_ADPT_FMT ": input length is 0!\n",
1343                         FUNC_ADPT_ARG(padapter));
1344                 err = -EFAULT;
1345                 goto exit;
1346         }
1347
1348         num = count;
1349         if (num > (sizeof(tmp) - 1))
1350                 num = (sizeof(tmp) - 1);
1351
1352         if (copy_from_user(tmp, buffer, num)) {
1353                 DBG_871X(FUNC_ADPT_FMT ": copy buffer from user space FAIL!\n",
1354                         FUNC_ADPT_ARG(padapter));
1355                 err = -EFAULT;
1356                 goto exit;
1357         }
1358
1359         err = btreg_parse_str(tmp, &btreg_read_type, &btreg_read_addr, NULL);
1360         if (err)
1361                 goto exit;
1362
1363         DBG_871X(FUNC_ADPT_FMT ": addr=(%s)0x%X\n",
1364                 FUNC_ADPT_ARG(padapter), btreg_type[btreg_read_type], btreg_read_addr);
1365
1366 exit:
1367         btreg_read_error = err;
1368
1369         return count;
1370 }
1371
1372 int proc_get_btreg_write(struct seq_file *m, void *v)
1373 {
1374         struct net_device *dev;
1375         PADAPTER padapter;
1376         u16 ret;
1377         u32 data;
1378
1379
1380         if (btreg_write_error < 0)
1381                 return btreg_write_error;
1382         else if (btreg_write_error > 0) {
1383                 DBG_871X_SEL_NL(m, "BTREG write: (%s)0x%04X write fail. error code = 0x%04x.\n", btreg_type[btreg_write_type], btreg_write_addr, btreg_write_error);
1384                 return 0;
1385         }
1386
1387         dev = m->private;
1388         padapter = (PADAPTER)rtw_netdev_priv(dev);
1389
1390         ret = rtw_btcoex_btreg_read(padapter, btreg_write_type, btreg_write_addr, &data);
1391         if (CHECK_STATUS_CODE_FROM_BT_MP_OPER_RET(ret, BT_STATUS_BT_OP_SUCCESS))
1392                 DBG_871X_SEL_NL(m, "BTREG read: (%s)0x%04X = 0x%08x\n", btreg_type[btreg_write_type], btreg_write_addr, data);
1393         else
1394                 DBG_871X_SEL_NL(m, "BTREG read: (%s)0x%04X read fail. error code = 0x%04x.\n", btreg_type[btreg_write_type], btreg_write_addr, ret);
1395
1396         return 0;
1397 }
1398
1399 ssize_t proc_set_btreg_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data)
1400 {
1401         struct net_device *dev = data;
1402         PADAPTER padapter;
1403         u8 tmp[80] = {0};
1404         u32 num;
1405         u16 val;
1406         u16 ret;
1407         int err;
1408
1409
1410         padapter = (PADAPTER)rtw_netdev_priv(dev);
1411
1412         if (NULL == buffer) {
1413                 DBG_871X(FUNC_ADPT_FMT ": input buffer is NULL!\n",
1414                         FUNC_ADPT_ARG(padapter));
1415                 err = -EFAULT;
1416                 goto exit;
1417         }
1418
1419         if (count < 1) {
1420                 DBG_871X(FUNC_ADPT_FMT ": input length is 0!\n",
1421                         FUNC_ADPT_ARG(padapter));
1422                 err = -EFAULT;
1423                 goto exit;
1424         }
1425
1426         num = count;
1427         if (num > (sizeof(tmp) - 1))
1428                 num = (sizeof(tmp) - 1);
1429
1430         if (copy_from_user(tmp, buffer, num)) {
1431                 DBG_871X(FUNC_ADPT_FMT ": copy buffer from user space FAIL!\n",
1432                         FUNC_ADPT_ARG(padapter));
1433                 err = -EFAULT;
1434                 goto exit;
1435         }
1436
1437         err = btreg_parse_str(tmp, &btreg_write_type, &btreg_write_addr, &val);
1438         if (err)
1439                 goto exit;
1440
1441         DBG_871X(FUNC_ADPT_FMT ": Set (%s)0x%X = 0x%x\n",
1442                 FUNC_ADPT_ARG(padapter), btreg_type[btreg_write_type], btreg_write_addr, val);
1443
1444         ret = rtw_btcoex_btreg_write(padapter, btreg_write_type, btreg_write_addr, val);
1445         if (!CHECK_STATUS_CODE_FROM_BT_MP_OPER_RET(ret, BT_STATUS_BT_OP_SUCCESS))
1446                 err = ret;
1447
1448 exit:
1449         btreg_write_error = err;
1450
1451         return count;
1452 }
1453 #endif /* CONFIG_BT_COEXIST */
1454
1455 #ifdef CONFIG_AUTO_CHNL_SEL_NHM
1456 static int proc_get_best_chan(struct seq_file *m, void *v)
1457 {
1458         struct net_device *dev = m->private;
1459         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
1460         u8 best_24g_ch = 0, best_5g_ch = 0;
1461
1462         rtw_hal_get_odm_var(adapter, HAL_ODM_AUTO_CHNL_SEL, &(best_24g_ch), &(best_5g_ch));
1463
1464         DBG_871X_SEL_NL(m, "Best 2.4G CH:%u\n", best_24g_ch);
1465         DBG_871X_SEL_NL(m, "Best 5G CH:%u\n", best_5g_ch);
1466         return 0;
1467 }
1468
1469 static ssize_t  proc_set_acs(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data)
1470 {
1471         struct net_device *dev = data;
1472         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1473         char tmp[32];
1474         u8 acs_satae = 0;
1475
1476         if (count < 1)
1477                 return -EFAULT;
1478
1479         if (count > sizeof(tmp)) {
1480                 rtw_warn_on(1);
1481                 return -EFAULT;
1482         }
1483         if (buffer && !copy_from_user(tmp, buffer, count)) {
1484
1485                 int num = sscanf(tmp, "%hhu", &acs_satae);
1486                 
1487                 if (num < 1)
1488                         return -EINVAL;
1489
1490                 if (1 == acs_satae)
1491                         rtw_acs_start(padapter, _TRUE);
1492                 else
1493                         rtw_acs_start(padapter, _FALSE);
1494
1495         }
1496         return count;
1497 }
1498 #endif
1499
1500 static int proc_get_hal_spec(struct seq_file *m, void *v)
1501 {
1502         struct net_device *dev = m->private;
1503         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
1504
1505         dump_hal_spec(m, adapter);
1506         return 0;
1507 }
1508
1509 /*
1510 * rtw_adapter_proc:
1511 * init/deinit when register/unregister net_device
1512 */
1513 const struct rtw_proc_hdl adapter_proc_hdls [] = {
1514         {"write_reg", proc_get_dummy, proc_set_write_reg},
1515         {"read_reg", proc_get_read_reg, proc_set_read_reg},
1516         {"adapters_status", proc_get_dump_adapters_status, NULL},
1517         {"fwstate", proc_get_fwstate, NULL},
1518         {"sec_info", proc_get_sec_info, NULL},
1519         {"mlmext_state", proc_get_mlmext_state, NULL},
1520         {"qos_option", proc_get_qos_option, NULL},
1521         {"ht_option", proc_get_ht_option, NULL},
1522         {"rf_info", proc_get_rf_info, NULL},
1523         {"scan_param", proc_get_scan_param, proc_set_scan_param},
1524         {"scan_abort", proc_get_scan_abort, NULL},      
1525 #ifdef CONFIG_SCAN_BACKOP
1526         {"backop_flags_sta", proc_get_backop_flags_sta, proc_set_backop_flags_sta},
1527         {"backop_flags_ap", proc_get_backop_flags_ap, proc_set_backop_flags_ap},
1528 #endif
1529         {"survey_info", proc_get_survey_info, proc_set_survey_info},
1530         {"ap_info", proc_get_ap_info, NULL},
1531         {"trx_info", proc_get_trx_info, proc_reset_trx_info},
1532         {"rate_ctl", proc_get_rate_ctl, proc_set_rate_ctl},
1533         {"dis_pwt_ctl", proc_get_dis_pwt, proc_set_dis_pwt},
1534         {"mac_qinfo", proc_get_mac_qinfo, NULL},
1535         {"macid_info", proc_get_macid_info, NULL},
1536         {"sec_cam", proc_get_sec_cam, proc_set_sec_cam},
1537         {"sec_cam_cache", proc_get_sec_cam_cache, NULL},
1538         {"suspend_info", proc_get_suspend_resume_info, NULL},
1539         {"wifi_spec",proc_get_wifi_spec,NULL},
1540 #ifdef CONFIG_LAYER2_ROAMING
1541         {"roam_flags", proc_get_roam_flags, proc_set_roam_flags},
1542         {"roam_param", proc_get_roam_param, proc_set_roam_param},
1543         {"roam_tgt_addr", proc_get_dummy, proc_set_roam_tgt_addr},
1544 #endif /* CONFIG_LAYER2_ROAMING */
1545
1546 #ifdef CONFIG_SDIO_HCI
1547         {"sd_f0_reg_dump", proc_get_sd_f0_reg_dump, NULL},
1548         {"sdio_local_reg_dump", proc_get_sdio_local_reg_dump, NULL},
1549 #endif /* CONFIG_SDIO_HCI */
1550
1551         {"fwdl_test_case", proc_get_dummy, proc_set_fwdl_test_case},
1552         {"del_rx_ampdu_test_case", proc_get_dummy, proc_set_del_rx_ampdu_test_case},
1553         {"wait_hiq_empty", proc_get_dummy, proc_set_wait_hiq_empty},
1554
1555         {"mac_reg_dump", proc_get_mac_reg_dump, NULL},
1556         {"bb_reg_dump", proc_get_bb_reg_dump, NULL},
1557         {"rf_reg_dump", proc_get_rf_reg_dump, NULL},
1558         
1559 #ifdef CONFIG_AP_MODE
1560         {"all_sta_info", proc_get_all_sta_info, NULL},
1561 #endif /* CONFIG_AP_MODE */
1562
1563 #ifdef DBG_MEMORY_LEAK
1564         {"_malloc_cnt", proc_get_malloc_cnt, NULL},
1565 #endif /* DBG_MEMORY_LEAK */
1566
1567 #ifdef CONFIG_FIND_BEST_CHANNEL
1568         {"best_channel", proc_get_best_channel, proc_set_best_channel},
1569 #endif
1570
1571         {"rx_signal", proc_get_rx_signal, proc_set_rx_signal},
1572         {"hw_info", proc_get_hw_status, NULL},
1573
1574 #ifdef CONFIG_80211N_HT
1575         {"ht_enable", proc_get_ht_enable, proc_set_ht_enable},
1576         {"bw_mode", proc_get_bw_mode, proc_set_bw_mode},
1577         {"ampdu_enable", proc_get_ampdu_enable, proc_set_ampdu_enable},
1578         {"rx_stbc", proc_get_rx_stbc, proc_set_rx_stbc},
1579         {"rx_ampdu", proc_get_rx_ampdu, proc_set_rx_ampdu},
1580         {"rx_ampdu_factor",proc_get_rx_ampdu_factor,proc_set_rx_ampdu_factor},
1581         {"rx_ampdu_density",proc_get_rx_ampdu_density,proc_set_rx_ampdu_density},
1582         {"tx_ampdu_density",proc_get_tx_ampdu_density,proc_set_tx_ampdu_density},        
1583 #endif /* CONFIG_80211N_HT */
1584
1585         {"en_fwps", proc_get_en_fwps, proc_set_en_fwps},
1586         {"mac_rptbuf", proc_get_mac_rptbuf, NULL},
1587
1588         //{"path_rssi", proc_get_two_path_rssi, NULL},
1589 //      {"rssi_disp",proc_get_rssi_disp, proc_set_rssi_disp},
1590
1591 #ifdef CONFIG_BT_COEXIST
1592         {"btcoex_dbg", proc_get_btcoex_dbg, proc_set_btcoex_dbg},
1593         {"btcoex", proc_get_btcoex_info, NULL},
1594         {"btinfo_evt", proc_get_dummy, proc_set_btinfo_evt},
1595         {"btreg_read", proc_get_btreg_read, proc_set_btreg_read},
1596         {"btreg_write", proc_get_btreg_write, proc_set_btreg_write},
1597 #endif /* CONFIG_BT_COEXIST */
1598
1599 #if defined(DBG_CONFIG_ERROR_DETECT)
1600         {"sreset", proc_get_sreset, proc_set_sreset},
1601 #endif /* DBG_CONFIG_ERROR_DETECT */
1602         {"trx_info_debug", proc_get_trx_info_debug, NULL},
1603         {"linked_info_dump",proc_get_linked_info_dump,proc_set_linked_info_dump},
1604         {"current_tx_rate", proc_get_current_tx_rate, NULL},
1605 #ifdef CONFIG_GPIO_API
1606         {"gpio_info",proc_get_gpio,proc_set_gpio},
1607         {"gpio_set_output_value",proc_get_dummy,proc_set_gpio_output_value},
1608         {"gpio_set_direction",proc_get_dummy,proc_set_config_gpio},
1609 #endif
1610
1611 #ifdef CONFIG_DBG_COUNTER
1612         {"rx_logs", proc_get_rx_logs, NULL},
1613         {"tx_logs", proc_get_tx_logs, NULL},
1614         {"int_logs", proc_get_int_logs, NULL},
1615 #endif
1616
1617 #ifdef CONFIG_PCI_HCI
1618         {"rx_ring", proc_get_rx_ring, NULL},
1619         {"tx_ring", proc_get_tx_ring, NULL},
1620 #endif
1621 #ifdef CONFIG_GPIO_WAKEUP
1622         {"wowlan_gpio_info", proc_get_wowlan_gpio_info,
1623                 proc_set_wowlan_gpio_info},
1624 #endif
1625 #ifdef CONFIG_P2P_WOWLAN
1626         {"p2p_wowlan_info", proc_get_p2p_wowlan_info, NULL},
1627 #endif
1628         {"country_code", proc_get_country_code, proc_set_country_code},
1629         {"chan_plan", proc_get_chan_plan, proc_set_chan_plan},
1630 #ifdef CONFIG_DFS_MASTER
1631         {"dfs_master_test_case", proc_get_dfs_master_test_case, proc_set_dfs_master_test_case},
1632         {"update_non_ocp", proc_get_dummy, proc_set_update_non_ocp},
1633         {"radar_detect", proc_get_dummy, proc_set_radar_detect},
1634 #endif
1635         {"new_bcn_max", proc_get_new_bcn_max, proc_set_new_bcn_max},
1636         {"sink_udpport",proc_get_udpport,proc_set_udpport},
1637 #ifdef DBG_RX_COUNTER_DUMP
1638         {"dump_rx_cnt_mode",proc_get_rx_cnt_dump,proc_set_rx_cnt_dump},
1639 #endif  
1640         {"change_bss_chbw", NULL, proc_set_change_bss_chbw},
1641         {"target_tx_power", proc_get_target_tx_power, NULL},
1642         {"tx_power_by_rate", proc_get_tx_power_by_rate, NULL},
1643         {"tx_power_limit", proc_get_tx_power_limit, NULL},
1644         {"tx_power_ext_info", proc_get_tx_power_ext_info, proc_set_tx_power_ext_info},
1645 #ifdef CONFIG_RF_GAIN_OFFSET
1646         {"tx_gain_offset", proc_get_dummy, proc_set_tx_gain_offset},
1647         {"kfree_flag", proc_get_kfree_flag, proc_set_kfree_flag},
1648         {"kfree_bb_gain", proc_get_kfree_bb_gain, proc_set_kfree_bb_gain},
1649         {"kfree_thermal", proc_get_kfree_thermal, proc_set_kfree_thermal},
1650 #endif
1651 #ifdef CONFIG_POWER_SAVING
1652         {"ps_info",proc_get_ps_info, NULL},
1653 #endif
1654 #ifdef CONFIG_TDLS
1655         {"tdls_info", proc_get_tdls_info, NULL},
1656 #endif
1657         {"monitor", proc_get_monitor, proc_set_monitor},
1658
1659 #ifdef CONFIG_AUTO_CHNL_SEL_NHM
1660         {"acs", proc_get_best_chan, proc_set_acs},
1661 #endif
1662 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
1663         {"rtkm_info", proc_get_rtkm_info, NULL}
1664 #endif
1665         {"efuse_map", proc_get_efuse_map, NULL},
1666 #ifdef CONFIG_IEEE80211W
1667         {"11w_tx_sa_query", proc_get_tx_sa_query, proc_set_tx_sa_query},
1668         {"11w_tx_deauth", proc_get_tx_deauth, proc_set_tx_deauth},
1669         {"11w_tx_auth", proc_get_tx_auth, proc_set_tx_auth},
1670 #endif /* CONFIG_IEEE80211W */
1671         {"hal_spec", proc_get_hal_spec, NULL},
1672 };
1673
1674 const int adapter_proc_hdls_num = sizeof(adapter_proc_hdls) / sizeof(struct rtw_proc_hdl);
1675
1676 static int rtw_adapter_proc_open(struct inode *inode, struct file *file)
1677 {
1678         ssize_t index = (ssize_t)PDE_DATA(inode);
1679         const struct rtw_proc_hdl *hdl = adapter_proc_hdls+index;
1680
1681         return single_open(file, hdl->show, proc_get_parent_data(inode));
1682 }
1683
1684 static ssize_t rtw_adapter_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos)
1685 {
1686         ssize_t index = (ssize_t)PDE_DATA(file_inode(file));
1687         const struct rtw_proc_hdl *hdl = adapter_proc_hdls+index;
1688         ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *, void *) = hdl->write;
1689
1690         if (write)
1691                 return write(file, buffer, count, pos, ((struct seq_file *)file->private_data)->private);
1692
1693         return -EROFS;
1694 }
1695
1696 static const struct file_operations rtw_adapter_proc_fops = {
1697         .owner = THIS_MODULE,
1698         .open = rtw_adapter_proc_open,
1699         .read = seq_read,
1700         .llseek = seq_lseek,
1701         .release = single_release,
1702         .write = rtw_adapter_proc_write,
1703 };
1704
1705 int proc_get_odm_dbg_comp(struct seq_file *m, void *v)
1706 {
1707         struct net_device *dev = m->private;
1708         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
1709
1710         rtw_odm_dbg_comp_msg(m, adapter);
1711
1712         return 0;
1713 }
1714
1715 ssize_t proc_set_odm_dbg_comp(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data)
1716 {
1717         struct net_device *dev = data;
1718         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
1719         char tmp[32];
1720
1721         u64 dbg_comp;
1722
1723         if (count < 1)
1724                 return -EFAULT;
1725
1726         if (count > sizeof(tmp)) {
1727                 rtw_warn_on(1);
1728                 return -EFAULT;
1729         }
1730
1731         if (buffer && !copy_from_user(tmp, buffer, count)) {
1732
1733                 int num = sscanf(tmp, "%llx", &dbg_comp);
1734
1735                 if (num != 1)
1736                         return count;
1737
1738                 rtw_odm_dbg_comp_set(adapter, dbg_comp);
1739         }
1740
1741         return count;
1742 }
1743
1744 int proc_get_odm_dbg_level(struct seq_file *m, void *v)
1745 {
1746         struct net_device *dev = m->private;
1747         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
1748
1749         rtw_odm_dbg_level_msg(m, adapter);
1750
1751         return 0;
1752 }
1753
1754 ssize_t proc_set_odm_dbg_level(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data)
1755 {
1756         struct net_device *dev = data;
1757         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
1758         char tmp[32];
1759
1760         u32 dbg_level;
1761
1762         if (count < 1)
1763                 return -EFAULT;
1764
1765         if (count > sizeof(tmp)) {
1766                 rtw_warn_on(1);
1767                 return -EFAULT;
1768         }
1769
1770         if (buffer && !copy_from_user(tmp, buffer, count)) {
1771
1772                 int num = sscanf(tmp, "%u", &dbg_level);
1773
1774                 if (num != 1)
1775                         return count;
1776
1777                 rtw_odm_dbg_level_set(adapter, dbg_level);
1778         }
1779
1780         return count;
1781 }
1782
1783 int proc_get_odm_ability(struct seq_file *m, void *v)
1784 {
1785         struct net_device *dev = m->private;
1786         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
1787
1788         rtw_odm_ability_msg(m, adapter);
1789
1790         return 0;
1791 }
1792
1793 ssize_t proc_set_odm_ability(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data)
1794 {
1795         struct net_device *dev = data;
1796         _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
1797         char tmp[32];
1798
1799         u32 ability;
1800
1801         if (count < 1)
1802                 return -EFAULT;
1803
1804         if (count > sizeof(tmp)) {
1805                 rtw_warn_on(1);
1806                 return -EFAULT;
1807         }
1808
1809         if (buffer && !copy_from_user(tmp, buffer, count)) {
1810
1811                 int num = sscanf(tmp, "%x", &ability);
1812
1813                 if (num != 1)
1814                         return count;
1815
1816                 rtw_odm_ability_set(adapter, ability);
1817         }
1818
1819         return count;
1820 }
1821
1822 int proc_get_odm_adaptivity(struct seq_file *m, void *v)
1823 {
1824         struct net_device *dev = m->private;
1825         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1826
1827         rtw_odm_adaptivity_parm_msg(m, padapter);
1828
1829         return 0;
1830 }
1831
1832 ssize_t proc_set_odm_adaptivity(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data)
1833 {
1834         struct net_device *dev = data;
1835         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1836         char tmp[32];
1837         u32 TH_L2H_ini;
1838         u32 TH_L2H_ini_mode2;
1839         s8 TH_EDCCA_HL_diff;
1840         s8 TH_EDCCA_HL_diff_mode2;
1841         u8 EDCCA_enable;
1842
1843         if (count < 1)
1844                 return -EFAULT;
1845
1846         if (count > sizeof(tmp)) {
1847                 rtw_warn_on(1);
1848                 return -EFAULT;
1849         }
1850
1851         if (buffer && !copy_from_user(tmp, buffer, count)) {
1852
1853                 int num = sscanf(tmp, "%x %hhd %x %hhd %hhu", &TH_L2H_ini, &TH_EDCCA_HL_diff, &TH_L2H_ini_mode2, &TH_EDCCA_HL_diff_mode2, &EDCCA_enable);
1854
1855                 if (num != 5)
1856                         return count;
1857
1858                 rtw_odm_adaptivity_parm_set(padapter, (s8)TH_L2H_ini, TH_EDCCA_HL_diff, (s8)TH_L2H_ini_mode2, TH_EDCCA_HL_diff_mode2, EDCCA_enable);
1859         }
1860         
1861         return count;
1862 }
1863
1864 static char *phydm_msg = NULL;
1865 #define PHYDM_MSG_LEN   80*24
1866
1867 int proc_get_phydm_cmd(struct seq_file *m, void *v)
1868 {
1869         struct net_device *netdev;
1870         PADAPTER padapter;
1871         PHAL_DATA_TYPE pHalData;
1872         PDM_ODM_T phydm;
1873
1874
1875         netdev = m->private;
1876         padapter = (PADAPTER)rtw_netdev_priv(netdev);
1877         pHalData = GET_HAL_DATA(padapter);
1878         phydm = &pHalData->odmpriv;
1879
1880         if (NULL == phydm_msg) {
1881                 phydm_msg = rtw_zmalloc(PHYDM_MSG_LEN);
1882                 if (NULL == phydm_msg)
1883                         return -ENOMEM;
1884
1885                 phydm_cmd(phydm, NULL, 0, 0, phydm_msg, PHYDM_MSG_LEN);
1886         }
1887
1888         DBG_871X_SEL(m, "%s\n", phydm_msg);
1889
1890         rtw_mfree(phydm_msg, PHYDM_MSG_LEN);
1891         phydm_msg = NULL;
1892
1893         return 0;
1894 }
1895
1896 ssize_t proc_set_phydm_cmd(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data)
1897 {
1898         struct net_device *netdev;
1899         PADAPTER padapter;
1900         PHAL_DATA_TYPE pHalData;
1901         PDM_ODM_T phydm;
1902         char tmp[64] = {0};
1903
1904
1905         netdev = (struct net_device*)data;
1906         padapter = (PADAPTER)rtw_netdev_priv(netdev);
1907         pHalData = GET_HAL_DATA(padapter);
1908         phydm = &pHalData->odmpriv;
1909
1910         if (count < 1)
1911                 return -EFAULT;
1912
1913         if (count > sizeof(tmp))
1914                 return -EFAULT;
1915
1916         if (buffer && !copy_from_user(tmp, buffer, count)) {
1917                 if (NULL == phydm_msg) {
1918                         phydm_msg = rtw_zmalloc(PHYDM_MSG_LEN);
1919                         if (NULL == phydm_msg)
1920                                 return -ENOMEM;
1921                 } else {
1922                         _rtw_memset(phydm_msg, 0, PHYDM_MSG_LEN);
1923                 }
1924
1925                 phydm_cmd(phydm, tmp, count, 1, phydm_msg, PHYDM_MSG_LEN);
1926
1927                 if (strlen(phydm_msg) == 0) {
1928                         rtw_mfree(phydm_msg, PHYDM_MSG_LEN);
1929                         phydm_msg = NULL;
1930                 }
1931         }
1932
1933         return count;
1934 }
1935
1936 /*
1937 * rtw_odm_proc:
1938 * init/deinit when register/unregister net_device, along with rtw_adapter_proc
1939 */
1940 const struct rtw_proc_hdl odm_proc_hdls [] = {
1941         {"dbg_comp", proc_get_odm_dbg_comp, proc_set_odm_dbg_comp},
1942         {"dbg_level", proc_get_odm_dbg_level, proc_set_odm_dbg_level},
1943         {"ability", proc_get_odm_ability, proc_set_odm_ability},
1944         {"adaptivity", proc_get_odm_adaptivity, proc_set_odm_adaptivity},
1945         {"cmd", proc_get_phydm_cmd, proc_set_phydm_cmd},
1946 };
1947
1948 const int odm_proc_hdls_num = sizeof(odm_proc_hdls) / sizeof(struct rtw_proc_hdl);
1949
1950 static int rtw_odm_proc_open(struct inode *inode, struct file *file)
1951 {
1952         ssize_t index = (ssize_t)PDE_DATA(inode);
1953         const struct rtw_proc_hdl *hdl = odm_proc_hdls+index;
1954
1955         return single_open(file, hdl->show, proc_get_parent_data(inode));
1956 }
1957
1958 static ssize_t rtw_odm_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos)
1959 {
1960         ssize_t index = (ssize_t)PDE_DATA(file_inode(file));
1961         const struct rtw_proc_hdl *hdl = odm_proc_hdls+index;
1962         ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *, void *) = hdl->write;
1963         
1964         if (write)
1965                 return write(file, buffer, count, pos, ((struct seq_file *)file->private_data)->private);
1966
1967         return -EROFS;
1968 }
1969
1970 static const struct file_operations rtw_odm_proc_fops = {
1971         .owner = THIS_MODULE,
1972         .open = rtw_odm_proc_open,
1973         .read = seq_read,
1974         .llseek = seq_lseek,
1975         .release = single_release,
1976         .write = rtw_odm_proc_write,
1977 };
1978
1979 struct proc_dir_entry *rtw_odm_proc_init(struct net_device *dev)
1980 {
1981         struct proc_dir_entry *dir_odm = NULL;
1982         struct proc_dir_entry *entry = NULL;
1983         _adapter        *adapter = rtw_netdev_priv(dev);
1984         ssize_t i;
1985
1986         if (adapter->dir_dev == NULL) {
1987                 rtw_warn_on(1);
1988                 goto exit;
1989         }
1990
1991         if (adapter->dir_odm != NULL) {
1992                 rtw_warn_on(1);
1993                 goto exit;
1994         }
1995
1996         dir_odm = rtw_proc_create_dir("odm", adapter->dir_dev, dev);
1997         if (dir_odm == NULL) {
1998                 rtw_warn_on(1);
1999                 goto exit;
2000         }
2001
2002         adapter->dir_odm = dir_odm;
2003
2004         for (i=0;i<odm_proc_hdls_num;i++) {
2005                 entry = rtw_proc_create_entry(odm_proc_hdls[i].name, dir_odm, &rtw_odm_proc_fops, (void *)i);
2006                 if (!entry) {
2007                         rtw_warn_on(1);
2008                         goto exit;
2009                 }
2010         }
2011
2012 exit:
2013         return dir_odm;
2014 }
2015
2016 void rtw_odm_proc_deinit(_adapter       *adapter)
2017 {
2018         struct proc_dir_entry *dir_odm = NULL;
2019         int i;
2020
2021         dir_odm = adapter->dir_odm;
2022
2023         if (dir_odm == NULL) {
2024                 rtw_warn_on(1);
2025                 return;
2026         }
2027
2028         for (i=0;i<odm_proc_hdls_num;i++)
2029                 remove_proc_entry(odm_proc_hdls[i].name, dir_odm);
2030
2031         remove_proc_entry("odm", adapter->dir_dev);
2032
2033         adapter->dir_odm = NULL;
2034
2035         if (phydm_msg) {
2036                 rtw_mfree(phydm_msg, PHYDM_MSG_LEN);
2037                 phydm_msg = NULL;
2038         }
2039 }
2040
2041 struct proc_dir_entry *rtw_adapter_proc_init(struct net_device *dev)
2042 {
2043         struct proc_dir_entry *drv_proc = get_rtw_drv_proc();
2044         struct proc_dir_entry *dir_dev = NULL;
2045         struct proc_dir_entry *entry = NULL;
2046         _adapter *adapter = rtw_netdev_priv(dev);
2047         u8 rf_type;
2048         ssize_t i;
2049
2050         if (drv_proc == NULL) {
2051                 rtw_warn_on(1);
2052                 goto exit;
2053         }
2054
2055         if (adapter->dir_dev != NULL) {
2056                 rtw_warn_on(1);
2057                 goto exit;
2058         }
2059
2060         dir_dev = rtw_proc_create_dir(dev->name, drv_proc, dev);
2061         if (dir_dev == NULL) {
2062                 rtw_warn_on(1);
2063                 goto exit;
2064         }
2065
2066         adapter->dir_dev = dir_dev;
2067
2068         for (i=0;i<adapter_proc_hdls_num;i++) {
2069                 entry = rtw_proc_create_entry(adapter_proc_hdls[i].name, dir_dev, &rtw_adapter_proc_fops, (void *)i);
2070                 if (!entry) {
2071                         rtw_warn_on(1);
2072                         goto exit;
2073                 }
2074         }
2075
2076         rtw_odm_proc_init(dev);
2077
2078 exit:
2079         return dir_dev;
2080 }
2081
2082 void rtw_adapter_proc_deinit(struct net_device *dev)
2083 {
2084         struct proc_dir_entry *drv_proc = get_rtw_drv_proc();
2085         struct proc_dir_entry *dir_dev = NULL;
2086         _adapter *adapter = rtw_netdev_priv(dev);
2087         int i;
2088
2089         dir_dev = adapter->dir_dev;
2090
2091         if (dir_dev == NULL) {
2092                 rtw_warn_on(1);
2093                 return;
2094         }
2095
2096         for (i=0;i<adapter_proc_hdls_num;i++)
2097                 remove_proc_entry(adapter_proc_hdls[i].name, dir_dev);
2098
2099         rtw_odm_proc_deinit(adapter);
2100
2101         remove_proc_entry(dev->name, drv_proc);
2102
2103         adapter->dir_dev = NULL;
2104 }
2105
2106 void rtw_adapter_proc_replace(struct net_device *dev)
2107 {
2108         struct proc_dir_entry *drv_proc = get_rtw_drv_proc();
2109         struct proc_dir_entry *dir_dev = NULL;
2110         _adapter *adapter = rtw_netdev_priv(dev);
2111         int i;
2112
2113         dir_dev = adapter->dir_dev;
2114
2115         if (dir_dev == NULL) {
2116                 rtw_warn_on(1);
2117                 return;
2118         }
2119
2120         for (i=0;i<adapter_proc_hdls_num;i++)
2121                 remove_proc_entry(adapter_proc_hdls[i].name, dir_dev);
2122
2123         rtw_odm_proc_deinit(adapter);
2124
2125         remove_proc_entry(adapter->old_ifname, drv_proc);
2126
2127         adapter->dir_dev = NULL;
2128
2129         rtw_adapter_proc_init(dev);
2130
2131 }
2132
2133 #endif /* CONFIG_PROC_DEBUG */
2134