OSDN Git Service

Use the kernel's atomic operations directly
[android-x86/external-modules-rtl8723au.git] / os_dep / osdep_service.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2012 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
22 #define _OSDEP_SERVICE_C_
23
24 #include <drv_conf.h>
25 #include <osdep_service.h>
26 #include <drv_types.h>
27 #include <recv_osdep.h>
28 #include <linux/vmalloc.h>
29
30 #define RT_TAG  '1178'
31
32
33 /*
34 * Translate the OS dependent @param error_code to OS independent RTW_STATUS_CODE
35 * @return: one of RTW_STATUS_CODE
36 */
37 inline int RTW_STATUS_CODE(int error_code){
38         if(error_code >=0)
39                 return _SUCCESS;
40
41         switch(error_code) {
42                 //case -ETIMEDOUT:
43                 //      return RTW_STATUS_TIMEDOUT;
44                 default:
45                         return _FAIL;
46         }
47 }
48
49 inline u8* _rtw_vmalloc(u32 sz)
50 {
51         u8      *pbuf;
52         pbuf = vmalloc(sz);
53
54         return pbuf;
55 }
56
57 inline u8* _rtw_zvmalloc(u32 sz)
58 {
59         u8      *pbuf;
60         pbuf = _rtw_vmalloc(sz);
61         if (pbuf != NULL)
62                 memset(pbuf, 0, sz);
63
64         return pbuf;
65 }
66
67 inline void _rtw_vmfree(u8 *pbuf, u32 sz)
68 {
69         vfree(pbuf);
70 }
71
72 u8* _rtw_malloc(u32 sz)
73 {
74
75         u8      *pbuf=NULL;
76
77         pbuf = kmalloc(sz,in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
78
79         return pbuf;
80 }
81
82
83 u8* _rtw_zmalloc(u32 sz)
84 {
85         u8      *pbuf = _rtw_malloc(sz);
86
87         if (pbuf != NULL) {
88                 memset(pbuf, 0, sz);
89         }
90
91         return pbuf;
92 }
93
94 void    _rtw_mfree(u8 *pbuf, u32 sz)
95 {
96         kfree(pbuf);
97 }
98
99
100 void    _rtw_mutex_init(_mutex *pmutex)
101 {
102 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
103         mutex_init(pmutex);
104 #else
105         init_MUTEX(pmutex);
106 #endif
107 }
108
109 void    _rtw_mutex_free(_mutex *pmutex);
110 void    _rtw_mutex_free(_mutex *pmutex)
111 {
112 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
113         mutex_destroy(pmutex);
114 #else
115 #endif
116 }
117
118
119 void    _rtw_init_queue(_queue  *pqueue)
120 {
121         INIT_LIST_HEAD(&(pqueue->queue));
122         spin_lock_init(&(pqueue->lock));
123 }
124
125 u32       _rtw_queue_empty(_queue *pqueue)
126 {
127         if (list_empty(&(pqueue->queue)))
128                 return _TRUE;
129         else
130                 return _FALSE;
131 }
132
133
134 u32 rtw_end_of_queue_search(struct list_head *head, struct list_head *plist)
135 {
136         if (head == plist)
137                 return _TRUE;
138         else
139                 return _FALSE;
140 }
141
142
143 u32     rtw_get_current_time(void)
144 {
145         return jiffies;
146 }
147
148 inline u32 rtw_systime_to_ms(u32 systime)
149 {
150         return systime * 1000 / HZ;
151 }
152
153 inline u32 rtw_ms_to_systime(u32 ms)
154 {
155         return ms * HZ / 1000;
156 }
157
158 // the input parameter start use the same unit as returned by rtw_get_current_time
159 inline s32 rtw_get_passing_time_ms(u32 start)
160 {
161         return rtw_systime_to_ms(jiffies-start);
162 }
163
164 inline s32 rtw_get_time_interval_ms(u32 start, u32 end)
165 {
166         return rtw_systime_to_ms(end-start);
167 }
168
169
170 void rtw_sleep_schedulable(int ms)
171 {
172     u32 delta;
173
174     delta = (ms * HZ)/1000;//(ms)
175     if (delta == 0) {
176         delta = 1;// 1 ms
177     }
178     set_current_state(TASK_INTERRUPTIBLE);
179     if (schedule_timeout(delta) != 0) {
180         return ;
181     }
182     return;
183 }
184
185
186 void rtw_msleep_os(int ms)
187 {
188         msleep((unsigned int)ms);
189 }
190
191 void rtw_usleep_os(int us)
192 {
193       // msleep((unsigned int)us);
194       if ( 1 < (us/1000) )
195                 msleep(1);
196       else
197                 msleep( (us/1000) + 1);
198 }
199
200
201 #ifdef DBG_DELAY_OS
202 void _rtw_mdelay_os(int ms, const char *func, const int line)
203 {
204         #if 0
205         if(ms>10)
206                 DBG_8723A("%s:%d %s(%d)\n", func, line, __FUNCTION__, ms);
207                 rtw_msleep_os(ms);
208         return;
209         #endif
210
211
212         DBG_8723A("%s:%d %s(%d)\n", func, line, __FUNCTION__, ms);
213
214         mdelay((unsigned long)ms);
215 }
216 void _rtw_udelay_os(int us, const char *func, const int line)
217 {
218
219         #if 0
220         if(us > 1000) {
221         DBG_8723A("%s:%d %s(%d)\n", func, line, __FUNCTION__, us);
222                 rtw_usleep_os(us);
223                 return;
224         }
225         #endif
226
227
228         DBG_8723A("%s:%d %s(%d)\n", func, line, __FUNCTION__, us);
229
230       udelay((unsigned long)us);
231 }
232 #else
233 void rtw_mdelay_os(int ms)
234 {
235         mdelay((unsigned long)ms);
236 }
237 void rtw_udelay_os(int us)
238 {
239       udelay((unsigned long)us);
240 }
241 #endif
242
243 void rtw_yield_os(void)
244 {
245         yield();
246 }
247
248 #define RTW_SUSPEND_LOCK_NAME "rtw_wifi"
249
250 #ifdef CONFIG_WAKELOCK
251 static struct wake_lock rtw_suspend_lock;
252 #elif defined(CONFIG_ANDROID_POWER)
253 static android_suspend_lock_t rtw_suspend_lock ={
254         .name = RTW_SUSPEND_LOCK_NAME
255 };
256 #endif
257
258 inline void rtw_suspend_lock_init(void)
259 {
260         #ifdef CONFIG_WAKELOCK
261         wake_lock_init(&rtw_suspend_lock, WAKE_LOCK_SUSPEND, RTW_SUSPEND_LOCK_NAME);
262         #elif defined(CONFIG_ANDROID_POWER)
263         android_init_suspend_lock(&rtw_suspend_lock);
264         #endif
265 }
266
267 inline void rtw_suspend_lock_uninit(void)
268 {
269         #ifdef CONFIG_WAKELOCK
270         wake_lock_destroy(&rtw_suspend_lock);
271         #elif defined(CONFIG_ANDROID_POWER)
272         android_uninit_suspend_lock(&rtw_suspend_lock);
273         #endif
274 }
275
276 inline void rtw_lock_suspend(void)
277 {
278         #ifdef CONFIG_WAKELOCK
279         wake_lock(&rtw_suspend_lock);
280         #elif defined(CONFIG_ANDROID_POWER)
281         android_lock_suspend(&rtw_suspend_lock);
282         #endif
283
284         #if  defined(CONFIG_WAKELOCK) || defined(CONFIG_ANDROID_POWER)
285         //DBG_8723A("####%s: suspend_lock_count:%d####\n", __FUNCTION__, rtw_suspend_lock.stat.count);
286         #endif
287 }
288
289 inline void rtw_unlock_suspend(void)
290 {
291         #ifdef CONFIG_WAKELOCK
292         wake_unlock(&rtw_suspend_lock);
293         #elif defined(CONFIG_ANDROID_POWER)
294         android_unlock_suspend(&rtw_suspend_lock);
295         #endif
296
297         #if  defined(CONFIG_WAKELOCK) || defined(CONFIG_ANDROID_POWER)
298         //DBG_8723A("####%s: suspend_lock_count:%d####\n", __FUNCTION__, rtw_suspend_lock.stat.count);
299         #endif
300 }
301
302 #ifdef CONFIG_WOWLAN
303 inline void rtw_lock_suspend_timeout(long timeout)
304 {
305         #ifdef CONFIG_WAKELOCK
306         wake_lock_timeout(&rtw_suspend_lock, timeout);
307         #elif defined(CONFIG_ANDROID_POWER)
308         android_lock_suspend_auto_expire(&rtw_suspend_lock, timeout);
309         #endif
310 }
311 #endif //CONFIG_WOWLAN
312
313 /*
314 * Open a file with the specific @param path, @param flag, @param mode
315 * @param fpp the pointer of struct file pointer to get struct file pointer while file opening is success
316 * @param path the path of the file to open
317 * @param flag file operation flags, please refer to linux document
318 * @param mode please refer to linux document
319 * @return Linux specific error code
320 */
321 static int openFile(struct file **fpp, char *path, int flag, int mode)
322 {
323         struct file *fp;
324
325         fp=filp_open(path, flag, mode);
326         if(IS_ERR(fp)) {
327                 *fpp=NULL;
328                 return PTR_ERR(fp);
329         }
330         else {
331                 *fpp=fp;
332                 return 0;
333         }
334 }
335
336 /*
337 * Close the file with the specific @param fp
338 * @param fp the pointer of struct file to close
339 * @return always 0
340 */
341 static int closeFile(struct file *fp)
342 {
343         filp_close(fp,NULL);
344         return 0;
345 }
346
347 static int readFile(struct file *fp,char *buf,int len)
348 {
349         int rlen=0, sum=0;
350
351         if (!fp->f_op || !fp->f_op->read)
352                 return -EPERM;
353
354         while(sum<len) {
355                 rlen=fp->f_op->read(fp,buf+sum,len-sum, &fp->f_pos);
356                 if(rlen>0)
357                         sum+=rlen;
358                 else if(0 != rlen)
359                         return rlen;
360                 else
361                         break;
362         }
363
364         return  sum;
365
366 }
367
368 static int writeFile(struct file *fp,char *buf,int len)
369 {
370         int wlen=0, sum=0;
371
372         if (!fp->f_op || !fp->f_op->write)
373                 return -EPERM;
374
375         while(sum<len) {
376                 wlen=fp->f_op->write(fp,buf+sum,len-sum, &fp->f_pos);
377                 if(wlen>0)
378                         sum+=wlen;
379                 else if(0 != wlen)
380                         return wlen;
381                 else
382                         break;
383         }
384
385         return sum;
386
387 }
388
389 /*
390 * Test if the specifi @param path is a file and readable
391 * @param path the path of the file to test
392 * @return Linux specific error code
393 */
394 static int isFileReadable(char *path)
395 {
396         struct file *fp;
397         int ret = 0;
398         mm_segment_t oldfs;
399         char buf;
400
401         fp=filp_open(path, O_RDONLY, 0);
402         if(IS_ERR(fp)) {
403                 ret = PTR_ERR(fp);
404         }
405         else {
406                 oldfs = get_fs(); set_fs(get_ds());
407
408                 if(1!=readFile(fp, &buf, 1))
409                         ret = PTR_ERR(fp);
410
411                 set_fs(oldfs);
412                 filp_close(fp,NULL);
413         }
414         return ret;
415 }
416
417 /*
418 * Open the file with @param path and retrive the file content into memory starting from @param buf for @param sz at most
419 * @param path the path of the file to open and read
420 * @param buf the starting address of the buffer to store file content
421 * @param sz how many bytes to read at most
422 * @return the byte we've read, or Linux specific error code
423 */
424 static int retriveFromFile(char *path, u8* buf, u32 sz)
425 {
426         int ret =-1;
427         mm_segment_t oldfs;
428         struct file *fp;
429
430         if(path && buf) {
431                 if( 0 == (ret=openFile(&fp,path, O_RDONLY, 0)) ){
432                         DBG_8723A("%s openFile path:%s fp=%p\n",__FUNCTION__, path ,fp);
433
434                         oldfs = get_fs(); set_fs(get_ds());
435                         ret=readFile(fp, buf, sz);
436                         set_fs(oldfs);
437                         closeFile(fp);
438
439                         DBG_8723A("%s readFile, ret:%d\n",__FUNCTION__, ret);
440
441                 } else {
442                         DBG_8723A("%s openFile path:%s Fail, ret:%d\n",__FUNCTION__, path, ret);
443                 }
444         } else {
445                 DBG_8723A("%s NULL pointer\n",__FUNCTION__);
446                 ret =  -EINVAL;
447         }
448         return ret;
449 }
450
451 /*
452 * Open the file with @param path and wirte @param sz byte of data starting from @param buf into the file
453 * @param path the path of the file to open and write
454 * @param buf the starting address of the data to write into file
455 * @param sz how many bytes to write at most
456 * @return the byte we've written, or Linux specific error code
457 */
458 static int storeToFile(char *path, u8* buf, u32 sz)
459 {
460         int ret =0;
461         mm_segment_t oldfs;
462         struct file *fp;
463
464         if(path && buf) {
465                 if( 0 == (ret=openFile(&fp, path, O_CREAT|O_WRONLY, 0666)) ) {
466                         DBG_8723A("%s openFile path:%s fp=%p\n",__FUNCTION__, path ,fp);
467
468                         oldfs = get_fs(); set_fs(get_ds());
469                         ret=writeFile(fp, buf, sz);
470                         set_fs(oldfs);
471                         closeFile(fp);
472
473                         DBG_8723A("%s writeFile, ret:%d\n",__FUNCTION__, ret);
474
475                 } else {
476                         DBG_8723A("%s openFile path:%s Fail, ret:%d\n",__FUNCTION__, path, ret);
477                 }
478         } else {
479                 DBG_8723A("%s NULL pointer\n",__FUNCTION__);
480                 ret =  -EINVAL;
481         }
482         return ret;
483 }
484
485 /*
486 * Test if the specifi @param path is a file and readable
487 * @param path the path of the file to test
488 * @return _TRUE or _FALSE
489 */
490 int rtw_is_file_readable(char *path)
491 {
492         if(isFileReadable(path) == 0)
493                 return _TRUE;
494         else
495                 return _FALSE;
496 }
497
498 /*
499 * Open the file with @param path and retrive the file content into memory starting from @param buf for @param sz at most
500 * @param path the path of the file to open and read
501 * @param buf the starting address of the buffer to store file content
502 * @param sz how many bytes to read at most
503 * @return the byte we've read
504 */
505 int rtw_retrive_from_file(char *path, u8* buf, u32 sz)
506 {
507         int ret =retriveFromFile(path, buf, sz);
508         return ret>=0?ret:0;
509 }
510
511 /*
512 * Open the file with @param path and wirte @param sz byte of data starting from @param buf into the file
513 * @param path the path of the file to open and write
514 * @param buf the starting address of the data to write into file
515 * @param sz how many bytes to write at most
516 * @return the byte we've written
517 */
518 int rtw_store_to_file(char *path, u8* buf, u32 sz)
519 {
520         int ret =storeToFile(path, buf, sz);
521         return ret>=0?ret:0;
522 }
523
524 struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv, void *old_priv)
525 {
526         struct net_device *pnetdev;
527         struct rtw_netdev_priv_indicator *pnpi;
528
529 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
530         pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
531 #else
532         pnetdev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator));
533 #endif
534         if (!pnetdev)
535                 goto RETURN;
536
537         pnpi = netdev_priv(pnetdev);
538         pnpi->priv=old_priv;
539         pnpi->sizeof_priv=sizeof_priv;
540
541 RETURN:
542         return pnetdev;
543 }
544
545 struct net_device *rtw_alloc_etherdev(int sizeof_priv)
546 {
547         struct net_device *pnetdev;
548         struct rtw_netdev_priv_indicator *pnpi;
549
550 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
551         pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
552 #else
553         pnetdev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator));
554 #endif
555         if (!pnetdev)
556                 goto RETURN;
557
558         pnpi = netdev_priv(pnetdev);
559
560         pnpi->priv = rtw_zvmalloc(sizeof_priv);
561         if (!pnpi->priv) {
562                 free_netdev(pnetdev);
563                 pnetdev = NULL;
564                 goto RETURN;
565         }
566
567         pnpi->sizeof_priv=sizeof_priv;
568 RETURN:
569         return pnetdev;
570 }
571
572 void rtw_free_netdev(struct net_device * netdev)
573 {
574         struct rtw_netdev_priv_indicator *pnpi;
575
576         if(!netdev)
577                 goto RETURN;
578
579         pnpi = netdev_priv(netdev);
580
581         if(!pnpi->priv)
582                 goto RETURN;
583
584         rtw_vmfree(pnpi->priv, pnpi->sizeof_priv);
585         free_netdev(netdev);
586
587 RETURN:
588         return;
589 }
590
591 /*
592 * Jeff: this function should be called under ioctl (rtnl_lock is accquired) while
593 * LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)
594 */
595 int rtw_change_ifname(_adapter *padapter, const char *ifname)
596 {
597         struct net_device *pnetdev;
598         struct net_device *cur_pnetdev;
599         struct rereg_nd_name_data *rereg_priv;
600         int ret;
601
602         if(!padapter)
603                 goto error;
604
605         cur_pnetdev = padapter->pnetdev;
606         rereg_priv = &padapter->rereg_nd_name_priv;
607
608         //free the old_pnetdev
609         if(rereg_priv->old_pnetdev) {
610                 free_netdev(rereg_priv->old_pnetdev);
611                 rereg_priv->old_pnetdev = NULL;
612         }
613
614         if(!rtnl_is_locked())
615                 unregister_netdev(cur_pnetdev);
616         else
617                 unregister_netdevice(cur_pnetdev);
618
619         rtw_proc_remove_one(cur_pnetdev);
620
621         rereg_priv->old_pnetdev=cur_pnetdev;
622
623         pnetdev = rtw_init_netdev(padapter);
624         if (!pnetdev)  {
625                 ret = -1;
626                 goto error;
627         }
628
629         SET_NETDEV_DEV(pnetdev, dvobj_to_dev(adapter_to_dvobj(padapter)));
630
631         rtw_init_netdev_name(pnetdev, ifname);
632
633         memcpy(pnetdev->dev_addr, padapter->eeprompriv.mac_addr, ETH_ALEN);
634
635         if(!rtnl_is_locked())
636                 ret = register_netdev(pnetdev);
637         else
638                 ret = register_netdevice(pnetdev);
639
640         if ( ret != 0) {
641                 RT_TRACE(_module_hci_intfs_c_,_drv_err_,("register_netdev() failed\n"));
642                 goto error;
643         }
644
645         rtw_proc_init_one(pnetdev);
646
647         return 0;
648
649 error:
650
651         return -1;
652
653 }
654
655 u64 rtw_modular64(u64 x, u64 y)
656 {
657         return do_div(x, y);
658 }
659
660 u64 rtw_division64(u64 x, u64 y)
661 {
662         do_div(x, y);
663         return x;
664 }
665
666 void rtw_buf_free(u8 **buf, u32 *buf_len)
667 {
668         u32 ori_len;
669
670         if (!buf || !buf_len)
671                 return;
672
673         ori_len = *buf_len;
674
675         if (*buf) {
676                 *buf_len = 0;
677                 _rtw_mfree(*buf, *buf_len);
678                 *buf = NULL;
679         }
680 }
681
682 void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len)
683 {
684         u32 ori_len = 0, dup_len = 0;
685         u8 *ori = NULL;
686         u8 *dup = NULL;
687
688         if (!buf || !buf_len)
689                 return;
690
691         if (!src || !src_len)
692                 goto keep_ori;
693
694         /* duplicate src */
695         dup = rtw_malloc(src_len);
696         if (dup) {
697                 dup_len = src_len;
698                 memcpy(dup, src, dup_len);
699         }
700
701 keep_ori:
702         ori = *buf;
703         ori_len = *buf_len;
704
705         /* replace buf with dup */
706         *buf_len = 0;
707         *buf = dup;
708         *buf_len = dup_len;
709
710         /* free ori */
711         if (ori && ori_len > 0)
712                 _rtw_mfree(ori, ori_len);
713 }
714
715
716 /**
717  * rtw_cbuf_full - test if cbuf is full
718  * @cbuf: pointer of struct rtw_cbuf
719  *
720  * Returns: _TRUE if cbuf is full
721  */
722 inline bool rtw_cbuf_full(struct rtw_cbuf *cbuf)
723 {
724         return (cbuf->write == cbuf->read-1)? _TRUE : _FALSE;
725 }
726
727 /**
728  * rtw_cbuf_empty - test if cbuf is empty
729  * @cbuf: pointer of struct rtw_cbuf
730  *
731  * Returns: _TRUE if cbuf is empty
732  */
733 inline bool rtw_cbuf_empty(struct rtw_cbuf *cbuf)
734 {
735         return (cbuf->write == cbuf->read)? _TRUE : _FALSE;
736 }
737
738 /**
739  * rtw_cbuf_push - push a pointer into cbuf
740  * @cbuf: pointer of struct rtw_cbuf
741  * @buf: pointer to push in
742  *
743  * Lock free operation, be careful of the use scheme
744  * Returns: _TRUE push success
745  */
746 bool rtw_cbuf_push(struct rtw_cbuf *cbuf, void *buf)
747 {
748         if (rtw_cbuf_full(cbuf))
749                 return _FAIL;
750
751         if (0)
752                 DBG_8723A("%s on %u\n", __func__, cbuf->write);
753         cbuf->bufs[cbuf->write] = buf;
754         cbuf->write = (cbuf->write+1)%cbuf->size;
755
756         return _SUCCESS;
757 }
758
759 /**
760  * rtw_cbuf_pop - pop a pointer from cbuf
761  * @cbuf: pointer of struct rtw_cbuf
762  *
763  * Lock free operation, be careful of the use scheme
764  * Returns: pointer popped out
765  */
766 void *rtw_cbuf_pop(struct rtw_cbuf *cbuf)
767 {
768         void *buf;
769         if (rtw_cbuf_empty(cbuf))
770                 return NULL;
771
772         if (0)
773                 DBG_8723A("%s on %u\n", __func__, cbuf->read);
774         buf = cbuf->bufs[cbuf->read];
775         cbuf->read = (cbuf->read+1)%cbuf->size;
776
777         return buf;
778 }
779
780 /**
781  * rtw_cbuf_alloc - allocte a rtw_cbuf with given size and do initialization
782  * @size: size of pointer
783  *
784  * Returns: pointer of srtuct rtw_cbuf, NULL for allocation failure
785  */
786 struct rtw_cbuf *rtw_cbuf_alloc(u32 size)
787 {
788         struct rtw_cbuf *cbuf;
789
790         cbuf = (struct rtw_cbuf *)rtw_malloc(sizeof(*cbuf) + sizeof(void*)*size);
791
792         if (cbuf) {
793                 cbuf->write = cbuf->read = 0;
794                 cbuf->size = size;
795         }
796
797         return cbuf;
798 }
799
800 /**
801  * rtw_cbuf_free - free the given rtw_cbuf
802  * @cbuf: pointer of struct rtw_cbuf to free
803  */
804 void rtw_cbuf_free(struct rtw_cbuf *cbuf)
805 {
806         rtw_mfree((u8*)cbuf, sizeof(*cbuf) + sizeof(void*)*cbuf->size);
807 }