OSDN Git Service

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