Merge branch 'linux-linaro-lsk-v4.4-android' of git://git.linaro.org/kernel/linux...
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8192du / os_dep / osdep_service.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2011 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 #ifdef PLATFORM_LINUX
29 #include <linux/vmalloc.h>
30 #endif
31 #ifdef PLATFORM_FREEBSD
32 #include <sys/malloc.h>
33 #include <sys/time.h>
34 #endif /* PLATFORM_FREEBSD */
35 #ifdef RTK_DMP_PLATFORM
36 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12))
37 #include <linux/pageremap.h>
38 #endif
39 #endif
40
41 #define RT_TAG  '1178'
42
43 #ifdef DBG_MEMORY_LEAK
44 #ifdef PLATFORM_LINUX
45 #include <asm/atomic.h>
46 atomic_t _malloc_cnt = ATOMIC_INIT(0);
47 atomic_t _malloc_size = ATOMIC_INIT(0);
48 #endif
49 #endif /* DBG_MEMORY_LEAK */
50
51
52 #if defined(PLATFORM_LINUX)
53 /*
54 * Translate the OS dependent @param error_code to OS independent RTW_STATUS_CODE
55 * @return: one of RTW_STATUS_CODE
56 */
57 inline int RTW_STATUS_CODE(int error_code){
58         if(error_code >=0)
59                 return _SUCCESS;
60
61         switch(error_code) {
62                 //case -ETIMEDOUT:
63                 //      return RTW_STATUS_TIMEDOUT;
64                 default:
65                         return _FAIL;
66         }
67 }
68 #else
69 inline int RTW_STATUS_CODE(int error_code){
70         return error_code;
71 }
72 #endif
73
74 u32 rtw_atoi(u8* s)
75 {
76
77         int num=0,flag=0;
78         int i;
79         for(i=0;i<=strlen(s);i++)
80         {
81           if(s[i] >= '0' && s[i] <= '9')
82                  num = num * 10 + s[i] -'0';
83           else if(s[0] == '-' && i==0) 
84                  flag =1;
85           else 
86                   break;
87          }
88
89         if(flag == 1)
90            num = num * -1;
91
92          return(num); 
93
94 }
95
96 inline u8* _rtw_vmalloc(u32 sz)
97 {
98         u8      *pbuf;
99 #ifdef PLATFORM_LINUX   
100         pbuf = vmalloc(sz);
101 #endif  
102 #ifdef PLATFORM_FREEBSD
103         pbuf = malloc(sz,M_DEVBUF,M_NOWAIT);    
104 #endif  
105         
106 #ifdef PLATFORM_WINDOWS
107         NdisAllocateMemoryWithTag(&pbuf,sz, RT_TAG);    
108 #endif
109
110 #ifdef DBG_MEMORY_LEAK
111 #ifdef PLATFORM_LINUX
112         if ( pbuf != NULL) {
113                 atomic_inc(&_malloc_cnt);
114                 atomic_add(sz, &_malloc_size);
115         }
116 #endif
117 #endif /* DBG_MEMORY_LEAK */
118
119         return pbuf;    
120 }
121
122 inline u8* _rtw_zvmalloc(u32 sz)
123 {
124         u8      *pbuf;
125 #ifdef PLATFORM_LINUX
126         pbuf = _rtw_vmalloc(sz);
127         if (pbuf != NULL)
128                 memset(pbuf, 0, sz);
129 #endif  
130 #ifdef PLATFORM_FREEBSD
131         pbuf = malloc(sz,M_DEVBUF,M_ZERO|M_NOWAIT);     
132 #endif  
133 #ifdef PLATFORM_WINDOWS
134         NdisAllocateMemoryWithTag(&pbuf,sz, RT_TAG);
135         if (pbuf != NULL)
136                 NdisFillMemory(pbuf, sz, 0);
137 #endif
138
139         return pbuf;    
140 }
141
142 inline void _rtw_vmfree(u8 *pbuf, u32 sz)
143 {
144 #ifdef  PLATFORM_LINUX
145         vfree(pbuf);
146 #endif  
147 #ifdef PLATFORM_FREEBSD
148         free(pbuf,M_DEVBUF);    
149 #endif  
150 #ifdef PLATFORM_WINDOWS
151         NdisFreeMemory(pbuf,sz, 0);
152 #endif
153
154 #ifdef DBG_MEMORY_LEAK
155 #ifdef PLATFORM_LINUX
156         atomic_dec(&_malloc_cnt);
157         atomic_sub(sz, &_malloc_size);
158 #endif
159 #endif /* DBG_MEMORY_LEAK */
160 }
161
162 u8* _rtw_malloc(u32 sz)
163 {
164
165         u8      *pbuf=NULL;
166
167 #ifdef PLATFORM_LINUX
168 #ifdef RTK_DMP_PLATFORM
169         if(sz > 0x4000)
170                 pbuf = (u8 *)dvr_malloc(sz);
171         else
172 #endif          
173                 pbuf = kmalloc(sz,in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);            
174
175 #endif  
176 #ifdef PLATFORM_FREEBSD
177         pbuf = malloc(sz,M_DEVBUF,M_NOWAIT);    
178 #endif          
179 #ifdef PLATFORM_WINDOWS
180
181         NdisAllocateMemoryWithTag(&pbuf,sz, RT_TAG);
182
183 #endif
184
185 #ifdef DBG_MEMORY_LEAK
186 #ifdef PLATFORM_LINUX
187         if ( pbuf != NULL) {
188                 atomic_inc(&_malloc_cnt);
189                 atomic_add(sz, &_malloc_size);
190         }
191 #endif
192 #endif /* DBG_MEMORY_LEAK */
193
194         return pbuf;    
195         
196 }
197
198
199 u8* _rtw_zmalloc(u32 sz)
200 {
201 #ifdef PLATFORM_FREEBSD
202         return malloc(sz,M_DEVBUF,M_ZERO|M_NOWAIT);
203 #else // PLATFORM_FREEBSD
204         u8      *pbuf = _rtw_malloc(sz);
205
206         if (pbuf != NULL) {
207
208 #ifdef PLATFORM_LINUX
209                 memset(pbuf, 0, sz);
210 #endif  
211         
212 #ifdef PLATFORM_WINDOWS
213                 NdisFillMemory(pbuf, sz, 0);
214 #endif
215
216         }
217
218         return pbuf;    
219 #endif // PLATFORM_FREEBSD
220 }
221
222 void    _rtw_mfree(u8 *pbuf, u32 sz)
223 {
224
225 #ifdef  PLATFORM_LINUX
226 #ifdef RTK_DMP_PLATFORM
227         if(sz > 0x4000)
228                 dvr_free(pbuf);
229         else
230 #endif
231                 kfree(pbuf);
232
233 #endif  
234 #ifdef PLATFORM_FREEBSD
235         free(pbuf,M_DEVBUF);    
236 #endif          
237 #ifdef PLATFORM_WINDOWS
238
239         NdisFreeMemory(pbuf,sz, 0);
240
241 #endif
242         
243 #ifdef DBG_MEMORY_LEAK
244 #ifdef PLATFORM_LINUX
245         atomic_dec(&_malloc_cnt);
246         atomic_sub(sz, &_malloc_size);
247 #endif
248 #endif /* DBG_MEMORY_LEAK */
249         
250 }
251
252 #ifdef PLATFORM_FREEBSD
253 //review again
254 struct sk_buff * dev_alloc_skb(unsigned int size)
255 {
256         struct sk_buff *skb=NULL;
257         u8 *data=NULL;
258         
259         //skb = (struct sk_buff *)_rtw_zmalloc(sizeof(struct sk_buff)); // for skb->len, etc.
260         skb = (struct sk_buff *)_rtw_malloc(sizeof(struct sk_buff));
261         if(!skb)
262                 goto out;
263         data = _rtw_malloc(size);
264         if(!data)
265                 goto nodata;
266
267         skb->head = (unsigned char*)data;
268         skb->data = (unsigned char*)data;
269         skb->tail = (unsigned char*)data;
270         skb->end = (unsigned char*)data + size;
271         skb->len = 0;
272         //printf("%s()-%d: skb=%p, skb->head = %p\n", __FUNCTION__, __LINE__, skb, skb->head);
273
274 out:
275         return skb;
276 nodata:
277         _rtw_mfree((u8 *)skb, sizeof(struct sk_buff));
278         skb = NULL;
279 goto out;
280         
281 }
282
283 void dev_kfree_skb_any(struct sk_buff *skb)
284 {
285         //printf("%s()-%d: skb->head = %p\n", __FUNCTION__, __LINE__, skb->head);
286         if(skb->head)
287                 _rtw_mfree(skb->head, 0);
288         //printf("%s()-%d: skb = %p\n", __FUNCTION__, __LINE__, skb);
289         if(skb)
290                 _rtw_mfree((u8 *)skb, 0);
291 }
292 struct sk_buff *skb_clone(const struct sk_buff *skb)
293 {
294         return NULL;
295 }
296
297 #endif /* PLATFORM_FREEBSD */
298
299 inline struct sk_buff *_rtw_skb_alloc(u32 sz)
300 {
301 #ifdef PLATFORM_LINUX
302         return __dev_alloc_skb(sz, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
303 #endif /* PLATFORM_LINUX */
304
305 #ifdef PLATFORM_FREEBSD
306         return dev_alloc_skb(sz);
307 #endif /* PLATFORM_FREEBSD */
308 }
309
310 inline void _rtw_skb_free(struct sk_buff *skb)
311 {
312         dev_kfree_skb_any(skb);
313 }
314
315 inline struct sk_buff *_rtw_skb_copy(const struct sk_buff *skb)
316 {
317 #ifdef PLATFORM_LINUX
318         return skb_copy(skb, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
319 #endif /* PLATFORM_LINUX */
320
321 #ifdef PLATFORM_FREEBSD
322         return NULL;
323 #endif /* PLATFORM_FREEBSD */
324 }
325
326 inline struct sk_buff *_rtw_skb_clone(struct sk_buff *skb)
327 {
328 #ifdef PLATFORM_LINUX
329         return skb_clone(skb, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
330 #endif /* PLATFORM_LINUX */
331
332 #ifdef PLATFORM_FREEBSD
333         return skb_clone(skb);
334 #endif /* PLATFORM_FREEBSD */
335 }
336
337 inline int _rtw_netif_rx(_nic_hdl ndev, struct sk_buff *skb)
338 {
339 #ifdef PLATFORM_LINUX
340         skb->dev = ndev;
341         return netif_rx(skb);
342 #endif /* PLATFORM_LINUX */
343
344 #ifdef PLATFORM_FREEBSD
345         return (*ndev->if_input)(ndev, skb);
346 #endif /* PLATFORM_FREEBSD */
347 }
348
349 void _rtw_skb_queue_purge(struct sk_buff_head *list)
350 {
351         struct sk_buff *skb;
352
353         while ((skb = skb_dequeue(list)) != NULL)
354                 _rtw_skb_free(skb);
355 }
356
357 #ifdef CONFIG_USB_HCI
358 inline void *_rtw_usb_buffer_alloc(struct usb_device *dev, size_t size, dma_addr_t *dma)
359 {
360 #ifdef PLATFORM_LINUX
361 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
362         return usb_alloc_coherent(dev, size, (in_interrupt() ? GFP_ATOMIC : GFP_KERNEL), dma);
363 #else
364         return usb_buffer_alloc(dev, size, (in_interrupt() ? GFP_ATOMIC : GFP_KERNEL), dma);
365 #endif
366 #endif /* PLATFORM_LINUX */
367         
368 #ifdef PLATFORM_FREEBSD
369         return (malloc(size, M_USBDEV, M_NOWAIT | M_ZERO));
370 #endif /* PLATFORM_FREEBSD */
371 }
372 inline void _rtw_usb_buffer_free(struct usb_device *dev, size_t size, void *addr, dma_addr_t dma)
373 {
374 #ifdef PLATFORM_LINUX
375 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
376         usb_free_coherent(dev, size, addr, dma); 
377 #else
378         usb_buffer_free(dev, size, addr, dma);
379 #endif
380 #endif /* PLATFORM_LINUX */
381
382 #ifdef PLATFORM_FREEBSD
383         free(addr, M_USBDEV);
384 #endif /* PLATFORM_FREEBSD */
385 }
386 #endif /* CONFIG_USB_HCI */
387
388 #ifdef DBG_MEM_ALLOC
389
390 struct rtw_mem_stat {
391         ATOMIC_T alloc; // the memory bytes we allocate currently
392         ATOMIC_T peak; // the peak memory bytes we allocate 
393         ATOMIC_T alloc_cnt; // the alloc count for alloc currently
394         ATOMIC_T alloc_err_cnt; // the error times we fail to allocate memory
395 };
396
397 struct rtw_mem_stat rtw_mem_type_stat[mstat_tf_idx(MSTAT_TYPE_MAX)];
398 #ifdef RTW_MEM_FUNC_STAT
399 struct rtw_mem_stat rtw_mem_func_stat[mstat_ff_idx(MSTAT_FUNC_MAX)];
400 #endif
401
402 char *MSTAT_TYPE_str[] = {
403         "VIR",
404         "PHY",
405         "SKB",
406         "USB",
407 };
408
409 #ifdef RTW_MEM_FUNC_STAT
410 char *MSTAT_FUNC_str[] = {
411         "UNSP",
412         "IO",
413         "TXIO",
414         "RXIO",
415         "TX",
416         "RX",
417 };
418 #endif
419
420 void rtw_mstat_dump(void *sel)
421 {
422         int i;
423         int value_t[4][mstat_tf_idx(MSTAT_TYPE_MAX)];
424 #ifdef RTW_MEM_FUNC_STAT
425         int value_f[4][mstat_ff_idx(MSTAT_FUNC_MAX)];
426 #endif
427         
428         int vir_alloc, vir_peak, vir_alloc_err, phy_alloc, phy_peak, phy_alloc_err;
429         int tx_alloc, tx_peak, tx_alloc_err, rx_alloc, rx_peak, rx_alloc_err;
430
431         for(i=0;i<mstat_tf_idx(MSTAT_TYPE_MAX);i++) {
432                 value_t[0][i] = ATOMIC_READ(&(rtw_mem_type_stat[i].alloc));
433                 value_t[1][i] = ATOMIC_READ(&(rtw_mem_type_stat[i].peak));
434                 value_t[2][i] = ATOMIC_READ(&(rtw_mem_type_stat[i].alloc_cnt));
435                 value_t[3][i] = ATOMIC_READ(&(rtw_mem_type_stat[i].alloc_err_cnt));
436         }
437
438         #ifdef RTW_MEM_FUNC_STAT
439         for(i=0;i<mstat_ff_idx(MSTAT_FUNC_MAX);i++) {
440                 value_f[0][i] = ATOMIC_READ(&(rtw_mem_func_stat[i].alloc));
441                 value_f[1][i] = ATOMIC_READ(&(rtw_mem_func_stat[i].peak));
442                 value_f[2][i] = ATOMIC_READ(&(rtw_mem_func_stat[i].alloc_cnt));
443                 value_f[3][i] = ATOMIC_READ(&(rtw_mem_func_stat[i].alloc_err_cnt));
444         }
445         #endif
446
447         DBG_871X_SEL_NL(sel, "===================== MSTAT =====================\n");
448         DBG_871X_SEL_NL(sel, "%4s %10s %10s %10s %10s\n", "TAG", "alloc", "peak", "aloc_cnt", "err_cnt");
449         DBG_871X_SEL_NL(sel, "-------------------------------------------------\n");
450         for(i=0;i<mstat_tf_idx(MSTAT_TYPE_MAX);i++) {
451                 DBG_871X_SEL_NL(sel, "%4s %10d %10d %10d %10d\n", MSTAT_TYPE_str[i], value_t[0][i], value_t[1][i], value_t[2][i], value_t[3][i]);
452         }
453         #ifdef RTW_MEM_FUNC_STAT
454         DBG_871X_SEL_NL(sel, "-------------------------------------------------\n");
455         for(i=0;i<mstat_ff_idx(MSTAT_FUNC_MAX);i++) {
456                 DBG_871X_SEL_NL(sel, "%4s %10d %10d %10d %10d\n", MSTAT_FUNC_str[i], value_f[0][i], value_f[1][i], value_f[2][i], value_f[3][i]);
457         }
458         #endif
459 }
460
461 void rtw_mstat_update(const enum mstat_f flags, const MSTAT_STATUS status, u32 sz)
462 {
463         static u32 update_time = 0;
464         int peak, alloc;
465         int i;
466
467         /* initialization */
468         if(!update_time) {
469                 for(i=0;i<mstat_tf_idx(MSTAT_TYPE_MAX);i++) {
470                         ATOMIC_SET(&(rtw_mem_type_stat[i].alloc), 0);
471                         ATOMIC_SET(&(rtw_mem_type_stat[i].peak), 0);
472                         ATOMIC_SET(&(rtw_mem_type_stat[i].alloc_cnt), 0);
473                         ATOMIC_SET(&(rtw_mem_type_stat[i].alloc_err_cnt), 0);
474                 }
475                 #ifdef RTW_MEM_FUNC_STAT
476                 for(i=0;i<mstat_ff_idx(MSTAT_FUNC_MAX);i++) {
477                         ATOMIC_SET(&(rtw_mem_func_stat[i].alloc), 0);
478                         ATOMIC_SET(&(rtw_mem_func_stat[i].peak), 0);
479                         ATOMIC_SET(&(rtw_mem_func_stat[i].alloc_cnt), 0);
480                         ATOMIC_SET(&(rtw_mem_func_stat[i].alloc_err_cnt), 0);
481                 }
482                 #endif
483         }
484
485         switch(status) {
486                 case MSTAT_ALLOC_SUCCESS:
487                         ATOMIC_INC(&(rtw_mem_type_stat[mstat_tf_idx(flags)].alloc_cnt));
488                         alloc = ATOMIC_ADD_RETURN(&(rtw_mem_type_stat[mstat_tf_idx(flags)].alloc), sz);
489                         peak=ATOMIC_READ(&(rtw_mem_type_stat[mstat_tf_idx(flags)].peak));
490                         if (peak<alloc)
491                                 ATOMIC_SET(&(rtw_mem_type_stat[mstat_tf_idx(flags)].peak), alloc);
492
493                         #ifdef RTW_MEM_FUNC_STAT
494                         ATOMIC_INC(&(rtw_mem_func_stat[mstat_ff_idx(flags)].alloc_cnt));
495                         alloc = ATOMIC_ADD_RETURN(&(rtw_mem_func_stat[mstat_ff_idx(flags)].alloc), sz);
496                         peak=ATOMIC_READ(&(rtw_mem_func_stat[mstat_ff_idx(flags)].peak));
497                         if (peak<alloc)
498                                 ATOMIC_SET(&(rtw_mem_func_stat[mstat_ff_idx(flags)].peak), alloc);
499                         #endif
500                         break;
501
502                 case MSTAT_ALLOC_FAIL:
503                         ATOMIC_INC(&(rtw_mem_type_stat[mstat_tf_idx(flags)].alloc_err_cnt));
504                         #ifdef RTW_MEM_FUNC_STAT
505                         ATOMIC_INC(&(rtw_mem_func_stat[mstat_ff_idx(flags)].alloc_err_cnt));
506                         #endif
507                         break;
508
509                 case MSTAT_FREE:
510                         ATOMIC_DEC(&(rtw_mem_type_stat[mstat_tf_idx(flags)].alloc_cnt));
511                         ATOMIC_SUB(&(rtw_mem_type_stat[mstat_tf_idx(flags)].alloc), sz);
512                         #ifdef RTW_MEM_FUNC_STAT
513                         ATOMIC_DEC(&(rtw_mem_func_stat[mstat_ff_idx(flags)].alloc_cnt));
514                         ATOMIC_SUB(&(rtw_mem_func_stat[mstat_ff_idx(flags)].alloc), sz);
515                         #endif
516                         break;
517         };
518
519         //if (rtw_get_passing_time_ms(update_time) > 5000) {
520         //      rtw_mstat_dump(RTW_DBGDUMP);
521                 update_time=rtw_get_current_time();
522         //}
523 }
524
525 #ifndef SIZE_MAX
526         #define SIZE_MAX (~(size_t)0)
527 #endif
528
529 struct mstat_sniff_rule {
530         enum mstat_f flags;
531         size_t lb;
532         size_t hb;
533 };
534
535 struct mstat_sniff_rule mstat_sniff_rules[] = {
536         {MSTAT_TYPE_PHY, 4097, SIZE_MAX},
537 };
538
539 int mstat_sniff_rule_num = sizeof(mstat_sniff_rules)/sizeof(struct mstat_sniff_rule);
540
541 bool match_mstat_sniff_rules(const enum mstat_f flags, const size_t size)
542 {
543         int i;
544         for (i = 0; i<mstat_sniff_rule_num; i++) {
545                 if (mstat_sniff_rules[i].flags == flags
546                                 && mstat_sniff_rules[i].lb <= size
547                                 && mstat_sniff_rules[i].hb >= size)
548                         return _TRUE;
549         }
550
551         return _FALSE;
552 }
553
554 inline u8* dbg_rtw_vmalloc(u32 sz, const enum mstat_f flags, const char *func, const int line)
555 {
556         u8  *p;
557
558         if (match_mstat_sniff_rules(flags, sz))
559                 DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, (sz));
560         
561         p=_rtw_vmalloc((sz));
562
563         rtw_mstat_update(
564                 flags
565                 , p ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL
566                 , sz
567         );
568         
569         return p;
570 }
571
572 inline u8* dbg_rtw_zvmalloc(u32 sz, const enum mstat_f flags, const char *func, const int line)
573 {
574         u8 *p;
575
576         if (match_mstat_sniff_rules(flags, sz))
577                 DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, (sz));
578
579         p=_rtw_zvmalloc((sz)); 
580
581         rtw_mstat_update(
582                 flags
583                 , p ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL
584                 , sz
585         );
586
587         return p;
588 }
589
590 inline void dbg_rtw_vmfree(u8 *pbuf, u32 sz, const enum mstat_f flags, const char *func, const int line)
591 {
592
593         if (match_mstat_sniff_rules(flags, sz))
594                 DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, (sz));
595
596         _rtw_vmfree((pbuf), (sz)); 
597
598         rtw_mstat_update(
599                 flags
600                 , MSTAT_FREE
601                 , sz
602         );
603 }
604
605 inline u8* dbg_rtw_malloc(u32 sz, const enum mstat_f flags, const char *func, const int line) 
606 {
607         u8 *p;
608
609         if (match_mstat_sniff_rules(flags, sz))
610                 DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, (sz));
611
612         p=_rtw_malloc((sz));
613
614         rtw_mstat_update(
615                 flags
616                 , p ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL
617                 , sz
618         );
619
620         return p;
621 }
622
623 inline u8* dbg_rtw_zmalloc(u32 sz, const enum mstat_f flags, const char *func, const int line)
624 {
625         u8 *p;
626
627         if (match_mstat_sniff_rules(flags, sz))
628                 DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, (sz));
629
630         p = _rtw_zmalloc((sz));
631
632         rtw_mstat_update(
633                 flags
634                 , p ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL
635                 , sz
636         );
637
638         return p;
639 }
640
641 inline void dbg_rtw_mfree(u8 *pbuf, u32 sz, const enum mstat_f flags, const char *func, const int line)
642 {
643         if (match_mstat_sniff_rules(flags, sz))
644                 DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, (sz));
645
646         _rtw_mfree((pbuf), (sz));
647
648         rtw_mstat_update(
649                 flags
650                 , MSTAT_FREE
651                 , sz
652         );
653 }
654
655 inline struct sk_buff * dbg_rtw_skb_alloc(unsigned int size, const enum mstat_f flags, const char *func, int line)
656 {
657         struct sk_buff *skb;
658         unsigned int truesize = 0;
659
660         skb = _rtw_skb_alloc(size);
661
662         if(skb)
663                 truesize = skb->truesize;
664
665         if(!skb || truesize < size || match_mstat_sniff_rules(flags, truesize))
666                 DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d), skb:%p, truesize=%u\n", func, line, __FUNCTION__, size, skb, truesize);
667
668         rtw_mstat_update(
669                 flags
670                 , skb ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL
671                 , truesize
672         );
673
674         return skb;
675 }
676
677 inline void dbg_rtw_skb_free(struct sk_buff *skb, const enum mstat_f flags, const char *func, int line)
678 {
679         unsigned int truesize = skb->truesize;
680
681         if(match_mstat_sniff_rules(flags, truesize))
682                 DBG_871X("DBG_MEM_ALLOC %s:%d %s, truesize=%u\n", func, line, __FUNCTION__, truesize);
683
684         _rtw_skb_free(skb);
685
686         rtw_mstat_update(
687                 flags
688                 , MSTAT_FREE
689                 , truesize
690         );
691 }
692
693 inline struct sk_buff *dbg_rtw_skb_copy(const struct sk_buff *skb, const enum mstat_f flags, const char *func, const int line)
694 {
695         struct sk_buff *skb_cp;
696         unsigned int truesize = skb->truesize;
697         unsigned int cp_truesize = 0;
698         
699         skb_cp = _rtw_skb_copy(skb);
700         if(skb_cp)
701                 cp_truesize = skb_cp->truesize;
702
703         if(!skb_cp || cp_truesize < truesize || match_mstat_sniff_rules(flags, cp_truesize))
704                 DBG_871X("DBG_MEM_ALLOC %s:%d %s(%u), skb_cp:%p, cp_truesize=%u\n", func, line, __FUNCTION__, truesize, skb_cp, cp_truesize);
705
706         rtw_mstat_update(
707                 flags
708                 , skb_cp ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL
709                 , truesize
710         );
711
712         return skb_cp;
713 }
714
715 inline struct sk_buff *dbg_rtw_skb_clone(struct sk_buff *skb, const enum mstat_f flags, const char *func, const int line)
716 {
717         struct sk_buff *skb_cl;
718         unsigned int truesize = skb->truesize;
719         unsigned int cl_truesize = 0;
720
721         skb_cl = _rtw_skb_clone(skb);
722         if(skb_cl)
723                 cl_truesize = skb_cl->truesize;
724
725         if(!skb_cl || cl_truesize < truesize || match_mstat_sniff_rules(flags, cl_truesize))
726                 DBG_871X("DBG_MEM_ALLOC %s:%d %s(%u), skb_cl:%p, cl_truesize=%u\n", func, line, __FUNCTION__, truesize, skb_cl, cl_truesize);
727
728         rtw_mstat_update(
729                 flags
730                 , skb_cl ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL
731                 , truesize
732         );
733
734         return skb_cl;
735 }
736
737 inline int dbg_rtw_netif_rx(_nic_hdl ndev, struct sk_buff *skb, const enum mstat_f flags, const char *func, int line)
738 {
739         int ret;
740         unsigned int truesize = skb->truesize;
741
742         if(match_mstat_sniff_rules(flags, truesize))
743                 DBG_871X("DBG_MEM_ALLOC %s:%d %s, truesize=%u\n", func, line, __FUNCTION__, truesize);
744
745         ret = _rtw_netif_rx(ndev, skb);
746         
747         rtw_mstat_update(
748                 flags
749                 , MSTAT_FREE
750                 , truesize
751         );
752
753         return ret;
754 }
755
756 inline void dbg_rtw_skb_queue_purge(struct sk_buff_head *list, enum mstat_f flags, const char *func, int line)
757 {
758         struct sk_buff *skb;
759
760         while ((skb = skb_dequeue(list)) != NULL)
761                 dbg_rtw_skb_free(skb, flags, func, line);
762 }
763
764 #ifdef CONFIG_USB_HCI
765 inline void *dbg_rtw_usb_buffer_alloc(struct usb_device *dev, size_t size, dma_addr_t *dma, const enum mstat_f flags, const char *func, int line)
766 {
767         void *p;
768
769         if(match_mstat_sniff_rules(flags, size))
770                 DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, size);
771
772         p = _rtw_usb_buffer_alloc(dev, size, dma);
773         
774         rtw_mstat_update(
775                 flags
776                 , p ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL
777                 , size
778         );
779
780         return p;
781 }
782
783 inline void dbg_rtw_usb_buffer_free(struct usb_device *dev, size_t size, void *addr, dma_addr_t dma, const enum mstat_f flags, const char *func, int line)
784 {
785         if(match_mstat_sniff_rules(flags, size))
786                 DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, size);
787
788         _rtw_usb_buffer_free(dev, size, addr, dma);
789
790         rtw_mstat_update(
791                 flags
792                 , MSTAT_FREE
793                 , size
794         );
795 }
796 #endif /* CONFIG_USB_HCI */
797 #endif /* DBG_MEM_ALLOC */
798
799 void* rtw_malloc2d(int h, int w, int size)
800 {
801         int j;
802
803         void **a = (void **) rtw_zmalloc( h*sizeof(void *) + h*w*size );
804         if(a == NULL)
805         {
806                 DBG_871X("%s: alloc memory fail!\n", __FUNCTION__);
807                 return NULL;
808         }
809
810         for( j=0; j<h; j++ )
811                 a[j] = ((char *)(a+h)) + j*w*size;
812
813         return a;
814 }
815
816 void rtw_mfree2d(void *pbuf, int h, int w, int size)
817 {
818         rtw_mfree((u8 *)pbuf, h*sizeof(void*) + w*h*size);
819 }
820
821 void _rtw_memcpy(void* dst, void* src, u32 sz)
822 {
823
824 #if defined (PLATFORM_LINUX)|| defined (PLATFORM_FREEBSD)
825
826         memcpy(dst, src, sz);
827
828 #endif  
829
830 #ifdef PLATFORM_WINDOWS
831
832         NdisMoveMemory(dst, src, sz);
833
834 #endif
835
836 }
837
838 int     _rtw_memcmp(void *dst, void *src, u32 sz)
839 {
840
841 #if defined (PLATFORM_LINUX)|| defined (PLATFORM_FREEBSD)
842 //under Linux/GNU/GLibc, the return value of memcmp for two same mem. chunk is 0
843
844         if (!(memcmp(dst, src, sz)))
845                 return _TRUE;
846         else
847                 return _FALSE;
848 #endif
849
850
851 #ifdef PLATFORM_WINDOWS
852 //under Windows, the return value of NdisEqualMemory for two same mem. chunk is 1
853         
854         if (NdisEqualMemory (dst, src, sz))
855                 return _TRUE;
856         else
857                 return _FALSE;
858
859 #endif  
860         
861         
862         
863 }
864
865 void _rtw_memset(void *pbuf, int c, u32 sz)
866 {
867
868 #if defined (PLATFORM_LINUX)|| defined (PLATFORM_FREEBSD)
869
870         memset(pbuf, c, sz);
871
872 #endif
873
874 #ifdef PLATFORM_WINDOWS
875 #if 0
876         NdisZeroMemory(pbuf, sz);
877         if (c != 0) memset(pbuf, c, sz);
878 #else
879         NdisFillMemory(pbuf, sz, c);
880 #endif
881 #endif
882
883 }
884
885 #ifdef PLATFORM_FREEBSD
886 static inline void __list_add(_list *pnew, _list *pprev, _list *pnext)
887  {
888          pnext->prev = pnew;
889          pnew->next = pnext;
890          pnew->prev = pprev;
891          pprev->next = pnew;
892 }
893 #endif /* PLATFORM_FREEBSD */
894
895 void _rtw_init_listhead(_list *list)
896 {
897
898 #ifdef PLATFORM_LINUX
899
900         INIT_LIST_HEAD(list);
901
902 #endif
903
904 #ifdef PLATFORM_FREEBSD
905          list->next = list;
906          list->prev = list;
907 #endif
908 #ifdef PLATFORM_WINDOWS
909
910         NdisInitializeListHead(list);
911
912 #endif
913
914 }
915
916
917 /*
918 For the following list_xxx operations, 
919 caller must guarantee the atomic context.
920 Otherwise, there will be racing condition.
921 */
922 u32     rtw_is_list_empty(_list *phead)
923 {
924
925 #ifdef PLATFORM_LINUX
926
927         if (list_empty(phead))
928                 return _TRUE;
929         else
930                 return _FALSE;
931
932 #endif
933 #ifdef PLATFORM_FREEBSD
934
935         if (phead->next == phead)
936                 return _TRUE;
937         else
938                 return _FALSE;
939
940 #endif
941
942
943 #ifdef PLATFORM_WINDOWS
944
945         if (IsListEmpty(phead))
946                 return _TRUE;
947         else
948                 return _FALSE;
949
950 #endif
951
952         
953 }
954
955 void rtw_list_insert_head(_list *plist, _list *phead)
956 {
957
958 #ifdef PLATFORM_LINUX
959         list_add(plist, phead);
960 #endif
961
962 #ifdef PLATFORM_FREEBSD
963         __list_add(plist, phead, phead->next);
964 #endif
965
966 #ifdef PLATFORM_WINDOWS
967         InsertHeadList(phead, plist);
968 #endif
969 }
970
971 void rtw_list_insert_tail(_list *plist, _list *phead)
972 {
973
974 #ifdef PLATFORM_LINUX   
975         
976         list_add_tail(plist, phead);
977         
978 #endif
979 #ifdef PLATFORM_FREEBSD
980         
981         __list_add(plist, phead->prev, phead);
982         
983 #endif  
984 #ifdef PLATFORM_WINDOWS
985
986   InsertTailList(phead, plist);
987
988 #endif          
989         
990 }
991
992
993 /*
994
995 Caller must check if the list is empty before calling rtw_list_delete
996
997 */
998
999
1000 void _rtw_init_sema(_sema       *sema, int init_val)
1001 {
1002
1003 #ifdef PLATFORM_LINUX
1004
1005         sema_init(sema, init_val);
1006
1007 #endif
1008 #ifdef PLATFORM_FREEBSD
1009         sema_init(sema, init_val, "rtw_drv");
1010 #endif
1011 #ifdef PLATFORM_OS_XP
1012
1013         KeInitializeSemaphore(sema, init_val,  SEMA_UPBND); // count=0;
1014
1015 #endif
1016         
1017 #ifdef PLATFORM_OS_CE
1018         if(*sema == NULL)
1019                 *sema = CreateSemaphore(NULL, init_val, SEMA_UPBND, NULL);
1020 #endif
1021
1022 }
1023
1024 void _rtw_free_sema(_sema       *sema)
1025 {
1026 #ifdef PLATFORM_FREEBSD
1027         sema_destroy(sema);
1028 #endif
1029 #ifdef PLATFORM_OS_CE
1030         CloseHandle(*sema);
1031 #endif
1032
1033 }
1034
1035 void _rtw_up_sema(_sema *sema)
1036 {
1037
1038 #ifdef PLATFORM_LINUX
1039
1040         up(sema);
1041
1042 #endif  
1043 #ifdef PLATFORM_FREEBSD
1044         sema_post(sema);
1045 #endif
1046 #ifdef PLATFORM_OS_XP
1047
1048         KeReleaseSemaphore(sema, IO_NETWORK_INCREMENT, 1,  FALSE );
1049
1050 #endif
1051
1052 #ifdef PLATFORM_OS_CE
1053         ReleaseSemaphore(*sema,  1,  NULL );
1054 #endif
1055 }
1056
1057 u32 _rtw_down_sema(_sema *sema)
1058 {
1059
1060 #ifdef PLATFORM_LINUX
1061         
1062         if (down_interruptible(sema))
1063                 return _FAIL;
1064         else
1065                 return _SUCCESS;
1066
1067 #endif          
1068 #ifdef PLATFORM_FREEBSD
1069         sema_wait(sema);
1070         return  _SUCCESS;
1071 #endif
1072 #ifdef PLATFORM_OS_XP
1073
1074         if(STATUS_SUCCESS == KeWaitForSingleObject(sema, Executive, KernelMode, TRUE, NULL))
1075                 return  _SUCCESS;
1076         else
1077                 return _FAIL;
1078 #endif
1079
1080 #ifdef PLATFORM_OS_CE
1081         if(WAIT_OBJECT_0 == WaitForSingleObject(*sema, INFINITE ))
1082                 return _SUCCESS; 
1083         else
1084                 return _FAIL;
1085 #endif
1086 }
1087
1088
1089
1090 void    _rtw_mutex_init(_mutex *pmutex)
1091 {
1092 #ifdef PLATFORM_LINUX
1093
1094 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1095         mutex_init(pmutex);
1096 #else
1097         init_MUTEX(pmutex);
1098 #endif
1099
1100 #endif
1101 #ifdef PLATFORM_FREEBSD
1102         mtx_init(pmutex, "", NULL, MTX_DEF|MTX_RECURSE);
1103 #endif
1104 #ifdef PLATFORM_OS_XP
1105
1106         KeInitializeMutex(pmutex, 0);
1107
1108 #endif
1109
1110 #ifdef PLATFORM_OS_CE
1111         *pmutex =  CreateMutex( NULL, _FALSE, NULL);
1112 #endif
1113 }
1114
1115 void    _rtw_mutex_free(_mutex *pmutex);
1116 void    _rtw_mutex_free(_mutex *pmutex)
1117 {
1118 #ifdef PLATFORM_LINUX
1119
1120 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1121         mutex_destroy(pmutex);
1122 #else   
1123 #endif
1124
1125 #ifdef PLATFORM_FREEBSD
1126         sema_destroy(pmutex);
1127 #endif
1128
1129 #endif
1130
1131 #ifdef PLATFORM_OS_XP
1132
1133 #endif
1134
1135 #ifdef PLATFORM_OS_CE
1136
1137 #endif
1138 }
1139
1140 void    _rtw_spinlock_init(_lock *plock)
1141 {
1142
1143 #ifdef PLATFORM_LINUX
1144
1145         spin_lock_init(plock);
1146
1147 #endif  
1148 #ifdef PLATFORM_FREEBSD
1149                 mtx_init(plock, "", NULL, MTX_DEF|MTX_RECURSE);
1150 #endif
1151 #ifdef PLATFORM_WINDOWS
1152
1153         NdisAllocateSpinLock(plock);
1154
1155 #endif
1156         
1157 }
1158
1159 void    _rtw_spinlock_free(_lock *plock)
1160 {
1161 #ifdef PLATFORM_FREEBSD
1162          mtx_destroy(plock);
1163 #endif
1164         
1165 #ifdef PLATFORM_WINDOWS
1166
1167         NdisFreeSpinLock(plock);
1168
1169 #endif
1170         
1171 }
1172 #ifdef PLATFORM_FREEBSD
1173 extern PADAPTER prtw_lock;
1174
1175 void rtw_mtx_lock(_lock *plock){
1176         if(prtw_lock){
1177                 mtx_lock(&prtw_lock->glock);
1178         }
1179         else{
1180                 printf("%s prtw_lock==NULL",__FUNCTION__);
1181         }
1182 }
1183 void rtw_mtx_unlock(_lock *plock){
1184         if(prtw_lock){
1185                 mtx_unlock(&prtw_lock->glock);
1186         }
1187         else{
1188                 printf("%s prtw_lock==NULL",__FUNCTION__);
1189         }
1190         
1191 }
1192 #endif //PLATFORM_FREEBSD
1193
1194
1195 void    _rtw_spinlock(_lock     *plock)
1196 {
1197
1198 #ifdef PLATFORM_LINUX
1199
1200         spin_lock(plock);
1201
1202 #endif
1203 #ifdef PLATFORM_FREEBSD
1204         mtx_lock(plock);
1205 #endif
1206 #ifdef PLATFORM_WINDOWS
1207
1208         NdisAcquireSpinLock(plock);
1209
1210 #endif
1211         
1212 }
1213
1214 void    _rtw_spinunlock(_lock *plock)
1215 {
1216
1217 #ifdef PLATFORM_LINUX
1218
1219         spin_unlock(plock);
1220
1221 #endif
1222 #ifdef PLATFORM_FREEBSD
1223         mtx_unlock(plock);
1224 #endif  
1225 #ifdef PLATFORM_WINDOWS
1226
1227         NdisReleaseSpinLock(plock);
1228
1229 #endif
1230 }
1231
1232
1233 void    _rtw_spinlock_ex(_lock  *plock)
1234 {
1235
1236 #ifdef PLATFORM_LINUX
1237
1238         spin_lock(plock);
1239
1240 #endif
1241 #ifdef PLATFORM_FREEBSD
1242         mtx_lock(plock);
1243 #endif  
1244 #ifdef PLATFORM_WINDOWS
1245
1246         NdisDprAcquireSpinLock(plock);
1247
1248 #endif
1249         
1250 }
1251
1252 void    _rtw_spinunlock_ex(_lock *plock)
1253 {
1254
1255 #ifdef PLATFORM_LINUX
1256
1257         spin_unlock(plock);
1258
1259 #endif
1260 #ifdef PLATFORM_FREEBSD
1261         mtx_unlock(plock);
1262 #endif  
1263 #ifdef PLATFORM_WINDOWS
1264
1265         NdisDprReleaseSpinLock(plock);
1266
1267 #endif
1268 }
1269
1270
1271
1272 void    _rtw_init_queue(_queue  *pqueue)
1273 {
1274
1275         _rtw_init_listhead(&(pqueue->queue));
1276
1277         _rtw_spinlock_init(&(pqueue->lock));
1278
1279 }
1280
1281 u32       _rtw_queue_empty(_queue       *pqueue)
1282 {
1283         return (rtw_is_list_empty(&(pqueue->queue)));
1284 }
1285
1286
1287 u32 rtw_end_of_queue_search(_list *head, _list *plist)
1288 {
1289         if (head == plist)
1290                 return _TRUE;
1291         else
1292                 return _FALSE;
1293 }
1294
1295
1296 u32     rtw_get_current_time(void)
1297 {
1298         
1299 #ifdef PLATFORM_LINUX
1300         return jiffies;
1301 #endif  
1302 #ifdef PLATFORM_FREEBSD
1303         struct timeval tvp;
1304         getmicrotime(&tvp);
1305         return tvp.tv_sec;
1306 #endif
1307 #ifdef PLATFORM_WINDOWS
1308         LARGE_INTEGER   SystemTime;
1309         NdisGetCurrentSystemTime(&SystemTime);
1310         return (u32)(SystemTime.LowPart);// count of 100-nanosecond intervals 
1311 #endif
1312 }
1313
1314 inline u32 rtw_systime_to_ms(u32 systime)
1315 {
1316 #ifdef PLATFORM_LINUX
1317         return systime * 1000 / HZ;
1318 #endif  
1319 #ifdef PLATFORM_FREEBSD
1320         return systime * 1000;
1321 #endif  
1322 #ifdef PLATFORM_WINDOWS
1323         return systime / 10000 ; 
1324 #endif
1325 }
1326
1327 inline u32 rtw_ms_to_systime(u32 ms)
1328 {
1329 #ifdef PLATFORM_LINUX
1330         return ms * HZ / 1000;
1331 #endif  
1332 #ifdef PLATFORM_FREEBSD
1333         return ms /1000;
1334 #endif  
1335 #ifdef PLATFORM_WINDOWS
1336         return ms * 10000 ; 
1337 #endif
1338 }
1339
1340 // the input parameter start use the same unit as returned by rtw_get_current_time
1341 inline s32 rtw_get_passing_time_ms(u32 start)
1342 {
1343 #ifdef PLATFORM_LINUX
1344         return rtw_systime_to_ms(jiffies-start);
1345 #endif
1346 #ifdef PLATFORM_FREEBSD
1347         return rtw_systime_to_ms(rtw_get_current_time());
1348 #endif  
1349 #ifdef PLATFORM_WINDOWS
1350         LARGE_INTEGER   SystemTime;
1351         NdisGetCurrentSystemTime(&SystemTime);
1352         return rtw_systime_to_ms((u32)(SystemTime.LowPart) - start) ;
1353 #endif
1354 }
1355
1356 inline s32 rtw_get_time_interval_ms(u32 start, u32 end)
1357 {
1358 #ifdef PLATFORM_LINUX
1359         return rtw_systime_to_ms(end-start);
1360 #endif
1361 #ifdef PLATFORM_FREEBSD
1362         return rtw_systime_to_ms(rtw_get_current_time());
1363 #endif  
1364 #ifdef PLATFORM_WINDOWS
1365         return rtw_systime_to_ms(end-start);
1366 #endif
1367 }
1368         
1369
1370 void rtw_sleep_schedulable(int ms)      
1371 {
1372
1373 #ifdef PLATFORM_LINUX
1374
1375     u32 delta;
1376     
1377     delta = (ms * HZ)/1000;//(ms)
1378     if (delta == 0) {
1379         delta = 1;// 1 ms
1380     }
1381     set_current_state(TASK_INTERRUPTIBLE);
1382     if (schedule_timeout(delta) != 0) {
1383         return ;
1384     }
1385     return;
1386
1387 #endif  
1388 #ifdef PLATFORM_FREEBSD
1389         DELAY(ms*1000);
1390         return ;
1391 #endif  
1392         
1393 #ifdef PLATFORM_WINDOWS
1394
1395         NdisMSleep(ms*1000); //(us)*1000=(ms)
1396
1397 #endif
1398
1399 }
1400
1401
1402 void rtw_msleep_os(int ms)
1403 {
1404
1405 #ifdef PLATFORM_LINUX
1406
1407         msleep((unsigned int)ms);
1408
1409 #endif  
1410 #ifdef PLATFORM_FREEBSD
1411        //Delay for delay microseconds 
1412         DELAY(ms*1000);
1413         return ;
1414 #endif  
1415 #ifdef PLATFORM_WINDOWS
1416
1417         NdisMSleep(ms*1000); //(us)*1000=(ms)
1418
1419 #endif
1420
1421
1422 }
1423 void rtw_usleep_os(int us)
1424 {
1425
1426 #ifdef PLATFORM_LINUX
1427         
1428       // msleep((unsigned int)us);
1429       if ( 1 < (us/1000) )
1430                 msleep(1);
1431       else
1432                 msleep( (us/1000) + 1);
1433
1434 #endif  
1435 #ifdef PLATFORM_FREEBSD
1436         //Delay for delay microseconds 
1437         DELAY(us);
1438
1439         return ;
1440 #endif  
1441 #ifdef PLATFORM_WINDOWS
1442
1443         NdisMSleep(us); //(us)
1444
1445 #endif
1446
1447
1448 }
1449
1450
1451 #ifdef DBG_DELAY_OS
1452 void _rtw_mdelay_os(int ms, const char *func, const int line)
1453 {
1454         #if 0
1455         if(ms>10)
1456                 DBG_871X("%s:%d %s(%d)\n", func, line, __FUNCTION__, ms);
1457                 rtw_msleep_os(ms);
1458         return;
1459         #endif
1460
1461
1462         DBG_871X("%s:%d %s(%d)\n", func, line, __FUNCTION__, ms);
1463
1464 #if defined(PLATFORM_LINUX)
1465
1466         mdelay((unsigned long)ms); 
1467
1468 #elif defined(PLATFORM_WINDOWS)
1469
1470         NdisStallExecution(ms*1000); //(us)*1000=(ms)
1471
1472 #endif
1473
1474
1475 }
1476 void _rtw_udelay_os(int us, const char *func, const int line)
1477 {
1478
1479         #if 0
1480         if(us > 1000) {
1481         DBG_871X("%s:%d %s(%d)\n", func, line, __FUNCTION__, us);
1482                 rtw_usleep_os(us);
1483                 return;
1484         }
1485         #endif 
1486
1487
1488         DBG_871X("%s:%d %s(%d)\n", func, line, __FUNCTION__, us);
1489         
1490         
1491 #if defined(PLATFORM_LINUX)
1492
1493       udelay((unsigned long)us); 
1494
1495 #elif defined(PLATFORM_WINDOWS)
1496
1497         NdisStallExecution(us); //(us)
1498
1499 #endif
1500
1501 }
1502 #else
1503 void rtw_mdelay_os(int ms)
1504 {
1505
1506 #ifdef PLATFORM_LINUX
1507
1508         mdelay((unsigned long)ms); 
1509
1510 #endif  
1511 #ifdef PLATFORM_FREEBSD
1512         DELAY(ms*1000);
1513         return ;
1514 #endif  
1515 #ifdef PLATFORM_WINDOWS
1516
1517         NdisStallExecution(ms*1000); //(us)*1000=(ms)
1518
1519 #endif
1520
1521
1522 }
1523 void rtw_udelay_os(int us)
1524 {
1525
1526 #ifdef PLATFORM_LINUX
1527
1528       udelay((unsigned long)us); 
1529
1530 #endif  
1531 #ifdef PLATFORM_FREEBSD
1532         //Delay for delay microseconds 
1533         DELAY(us);
1534         return ;
1535 #endif          
1536 #ifdef PLATFORM_WINDOWS
1537
1538         NdisStallExecution(us); //(us)
1539
1540 #endif
1541
1542 }
1543 #endif
1544
1545 void rtw_yield_os()
1546 {
1547 #ifdef PLATFORM_LINUX
1548         yield();
1549 #endif
1550 #ifdef PLATFORM_FREEBSD
1551         yield();
1552 #endif
1553 #ifdef PLATFORM_WINDOWS
1554         SwitchToThread();
1555 #endif
1556 }
1557
1558 #define RTW_SUSPEND_LOCK_NAME "rtw_wifi"
1559
1560 #ifdef CONFIG_WAKELOCK
1561 static struct wake_lock rtw_suspend_lock;
1562 #elif defined(CONFIG_ANDROID_POWER)
1563 static android_suspend_lock_t rtw_suspend_lock ={
1564         .name = RTW_SUSPEND_LOCK_NAME
1565 };
1566 #endif
1567
1568 inline void rtw_suspend_lock_init()
1569 {
1570         #ifdef CONFIG_WAKELOCK
1571         wake_lock_init(&rtw_suspend_lock, WAKE_LOCK_SUSPEND, RTW_SUSPEND_LOCK_NAME);
1572         #elif defined(CONFIG_ANDROID_POWER)
1573         android_init_suspend_lock(&rtw_suspend_lock);
1574         #endif
1575 }
1576
1577 inline void rtw_suspend_lock_uninit()
1578 {
1579         #ifdef CONFIG_WAKELOCK
1580         wake_lock_destroy(&rtw_suspend_lock);
1581         #elif defined(CONFIG_ANDROID_POWER)
1582         android_uninit_suspend_lock(&rtw_suspend_lock);
1583         #endif
1584 }
1585
1586 inline void rtw_lock_suspend()
1587 {
1588         #ifdef CONFIG_WAKELOCK
1589         wake_lock(&rtw_suspend_lock);
1590         #elif defined(CONFIG_ANDROID_POWER)
1591         android_lock_suspend(&rtw_suspend_lock);
1592         #endif
1593 }
1594
1595 inline void rtw_unlock_suspend()
1596 {
1597         #ifdef CONFIG_WAKELOCK
1598         wake_unlock(&rtw_suspend_lock);
1599         #elif defined(CONFIG_ANDROID_POWER)
1600         android_unlock_suspend(&rtw_suspend_lock);
1601         #endif
1602 }
1603
1604 inline void rtw_lock_suspend_timeout(u32 timeout_ms)
1605 {
1606         #ifdef CONFIG_WAKELOCK
1607         wake_lock_timeout(&rtw_suspend_lock, rtw_ms_to_systime(timeout_ms));
1608         #elif defined(CONFIG_ANDROID_POWER)
1609         android_lock_suspend_auto_expire(&rtw_suspend_lock, rtw_ms_to_systime(timeout_ms));
1610         #endif
1611 }
1612
1613 inline void ATOMIC_SET(ATOMIC_T *v, int i)
1614 {
1615         #ifdef PLATFORM_LINUX
1616         atomic_set(v,i);
1617         #elif defined(PLATFORM_WINDOWS)
1618         *v=i;// other choice????
1619         #elif defined(PLATFORM_FREEBSD)
1620         atomic_set_int(v,i);
1621         #endif
1622 }
1623
1624 inline int ATOMIC_READ(ATOMIC_T *v)
1625 {
1626         #ifdef PLATFORM_LINUX
1627         return atomic_read(v);
1628         #elif defined(PLATFORM_WINDOWS)
1629         return *v; // other choice????
1630         #elif defined(PLATFORM_FREEBSD)
1631         return atomic_load_acq_32(v);
1632         #endif
1633 }
1634
1635 inline void ATOMIC_ADD(ATOMIC_T *v, int i)
1636 {
1637         #ifdef PLATFORM_LINUX
1638         atomic_add(i,v);
1639         #elif defined(PLATFORM_WINDOWS)
1640         InterlockedAdd(v,i);
1641         #elif defined(PLATFORM_FREEBSD)
1642         atomic_add_int(v,i);
1643         #endif
1644 }
1645 inline void ATOMIC_SUB(ATOMIC_T *v, int i)
1646 {
1647         #ifdef PLATFORM_LINUX
1648         atomic_sub(i,v);
1649         #elif defined(PLATFORM_WINDOWS)
1650         InterlockedAdd(v,-i);
1651         #elif defined(PLATFORM_FREEBSD)
1652         atomic_subtract_int(v,i);
1653         #endif
1654 }
1655
1656 inline void ATOMIC_INC(ATOMIC_T *v)
1657 {
1658         #ifdef PLATFORM_LINUX
1659         atomic_inc(v);
1660         #elif defined(PLATFORM_WINDOWS)
1661         InterlockedIncrement(v);
1662         #elif defined(PLATFORM_FREEBSD)
1663         atomic_add_int(v,1);
1664         #endif
1665 }
1666
1667 inline void ATOMIC_DEC(ATOMIC_T *v)
1668 {
1669         #ifdef PLATFORM_LINUX
1670         atomic_dec(v);
1671         #elif defined(PLATFORM_WINDOWS)
1672         InterlockedDecrement(v);
1673         #elif defined(PLATFORM_FREEBSD)
1674         atomic_subtract_int(v,1);
1675         #endif
1676 }
1677
1678 inline int ATOMIC_ADD_RETURN(ATOMIC_T *v, int i)
1679 {
1680         #ifdef PLATFORM_LINUX
1681         return atomic_add_return(i,v);
1682         #elif defined(PLATFORM_WINDOWS)
1683         return InterlockedAdd(v,i);
1684         #elif defined(PLATFORM_FREEBSD)
1685         atomic_add_int(v,i);
1686         return atomic_load_acq_32(v);
1687         #endif
1688 }
1689
1690 inline int ATOMIC_SUB_RETURN(ATOMIC_T *v, int i)
1691 {
1692         #ifdef PLATFORM_LINUX
1693         return atomic_sub_return(i,v);
1694         #elif defined(PLATFORM_WINDOWS)
1695         return InterlockedAdd(v,-i);
1696         #elif defined(PLATFORM_FREEBSD)
1697         atomic_subtract_int(v,i);
1698         return atomic_load_acq_32(v);
1699         #endif
1700 }
1701
1702 inline int ATOMIC_INC_RETURN(ATOMIC_T *v)
1703 {
1704         #ifdef PLATFORM_LINUX
1705         return atomic_inc_return(v);
1706         #elif defined(PLATFORM_WINDOWS)
1707         return InterlockedIncrement(v);
1708         #elif defined(PLATFORM_FREEBSD)
1709         atomic_add_int(v,1);
1710         return atomic_load_acq_32(v);
1711         #endif
1712 }
1713
1714 inline int ATOMIC_DEC_RETURN(ATOMIC_T *v)
1715 {
1716         #ifdef PLATFORM_LINUX
1717         return atomic_dec_return(v);
1718         #elif defined(PLATFORM_WINDOWS)
1719         return InterlockedDecrement(v);
1720         #elif defined(PLATFORM_FREEBSD)
1721         atomic_subtract_int(v,1);
1722         return atomic_load_acq_32(v);
1723         #endif
1724 }
1725
1726
1727 #ifdef PLATFORM_LINUX
1728 /*
1729 * Open a file with the specific @param path, @param flag, @param mode
1730 * @param fpp the pointer of struct file pointer to get struct file pointer while file opening is success
1731 * @param path the path of the file to open
1732 * @param flag file operation flags, please refer to linux document
1733 * @param mode please refer to linux document
1734 * @return Linux specific error code
1735 */
1736 static int openFile(struct file **fpp, char *path, int flag, int mode) 
1737
1738         struct file *fp; 
1739  
1740         fp=filp_open(path, flag, mode); 
1741         if(IS_ERR(fp)) {
1742                 *fpp=NULL;
1743                 return PTR_ERR(fp);
1744         }
1745         else {
1746                 *fpp=fp; 
1747                 return 0;
1748         }       
1749 }
1750
1751 /*
1752 * Close the file with the specific @param fp
1753 * @param fp the pointer of struct file to close
1754 * @return always 0
1755 */
1756 static int closeFile(struct file *fp) 
1757
1758         filp_close(fp,NULL);
1759         return 0; 
1760 }
1761
1762 static int readFile(struct file *fp,char *buf,int len) 
1763
1764         int rlen=0, sum=0;
1765         
1766         if (!fp->f_op || !fp->f_op->read) 
1767                 return -EPERM;
1768
1769         while(sum<len) {
1770                 rlen=fp->f_op->read(fp,buf+sum,len-sum, &fp->f_pos);
1771                 if(rlen>0)
1772                         sum+=rlen;
1773                 else if(0 != rlen)
1774                         return rlen;
1775                 else
1776                         break;
1777         }
1778         
1779         return  sum;
1780
1781 }
1782
1783 static int writeFile(struct file *fp,char *buf,int len) 
1784
1785         int wlen=0, sum=0;
1786         
1787         if (!fp->f_op || !fp->f_op->write) 
1788                 return -EPERM; 
1789
1790         while(sum<len) {
1791                 wlen=fp->f_op->write(fp,buf+sum,len-sum, &fp->f_pos);
1792                 if(wlen>0)
1793                         sum+=wlen;
1794                 else if(0 != wlen)
1795                         return wlen;
1796                 else
1797                         break;
1798         }
1799
1800         return sum;
1801
1802 }
1803
1804 /*
1805 * Test if the specifi @param path is a file and readable
1806 * @param path the path of the file to test
1807 * @return Linux specific error code
1808 */
1809 static int isFileReadable(char *path)
1810
1811         struct file *fp;
1812         int ret = 0;
1813         mm_segment_t oldfs;
1814         char buf;
1815  
1816         fp=filp_open(path, O_RDONLY, 0); 
1817         if(IS_ERR(fp)) {
1818                 ret = PTR_ERR(fp);
1819         }
1820         else {
1821                 oldfs = get_fs(); set_fs(get_ds());
1822                 
1823                 if(1!=readFile(fp, &buf, 1))
1824                         ret = PTR_ERR(fp);
1825                 
1826                 set_fs(oldfs);
1827                 filp_close(fp,NULL);
1828         }       
1829         return ret;
1830 }
1831
1832 /*
1833 * Open the file with @param path and retrive the file content into memory starting from @param buf for @param sz at most
1834 * @param path the path of the file to open and read
1835 * @param buf the starting address of the buffer to store file content
1836 * @param sz how many bytes to read at most
1837 * @return the byte we've read, or Linux specific error code
1838 */
1839 static int retriveFromFile(char *path, u8* buf, u32 sz)
1840 {
1841         int ret =-1;
1842         mm_segment_t oldfs;
1843         struct file *fp;
1844
1845         if(path && buf) {
1846                 if( 0 == (ret=openFile(&fp,path, O_RDONLY, 0)) ){
1847                         DBG_871X("%s openFile path:%s fp=%p\n",__FUNCTION__, path ,fp);
1848
1849                         oldfs = get_fs(); set_fs(get_ds());
1850                         ret=readFile(fp, buf, sz);
1851                         set_fs(oldfs);
1852                         closeFile(fp);
1853                         
1854                         DBG_871X("%s readFile, ret:%d\n",__FUNCTION__, ret);
1855                         
1856                 } else {
1857                         DBG_871X("%s openFile path:%s Fail, ret:%d\n",__FUNCTION__, path, ret);
1858                 }
1859         } else {
1860                 DBG_871X("%s NULL pointer\n",__FUNCTION__);
1861                 ret =  -EINVAL;
1862         }
1863         return ret;
1864 }
1865
1866 /*
1867 * Open the file with @param path and wirte @param sz byte of data starting from @param buf into the file
1868 * @param path the path of the file to open and write
1869 * @param buf the starting address of the data to write into file
1870 * @param sz how many bytes to write at most
1871 * @return the byte we've written, or Linux specific error code
1872 */
1873 static int storeToFile(char *path, u8* buf, u32 sz)
1874 {
1875         int ret =0;
1876         mm_segment_t oldfs;
1877         struct file *fp;
1878         
1879         if(path && buf) {
1880                 if( 0 == (ret=openFile(&fp, path, O_CREAT|O_WRONLY, 0666)) ) {
1881                         DBG_871X("%s openFile path:%s fp=%p\n",__FUNCTION__, path ,fp);
1882
1883                         oldfs = get_fs(); set_fs(get_ds());
1884                         ret=writeFile(fp, buf, sz);
1885                         set_fs(oldfs);
1886                         closeFile(fp);
1887
1888                         DBG_871X("%s writeFile, ret:%d\n",__FUNCTION__, ret);
1889                         
1890                 } else {
1891                         DBG_871X("%s openFile path:%s Fail, ret:%d\n",__FUNCTION__, path, ret);
1892                 }       
1893         } else {
1894                 DBG_871X("%s NULL pointer\n",__FUNCTION__);
1895                 ret =  -EINVAL;
1896         }
1897         return ret;
1898 }
1899 #endif //PLATFORM_LINUX
1900
1901 /*
1902 * Test if the specifi @param path is a file and readable
1903 * @param path the path of the file to test
1904 * @return _TRUE or _FALSE
1905 */
1906 int rtw_is_file_readable(char *path)
1907 {
1908 #ifdef PLATFORM_LINUX
1909         if(isFileReadable(path) == 0)
1910                 return _TRUE;
1911         else
1912                 return _FALSE;
1913 #else
1914         //Todo...
1915         return _FALSE;
1916 #endif
1917 }
1918
1919 /*
1920 * Open the file with @param path and retrive the file content into memory starting from @param buf for @param sz at most
1921 * @param path the path of the file to open and read
1922 * @param buf the starting address of the buffer to store file content
1923 * @param sz how many bytes to read at most
1924 * @return the byte we've read
1925 */
1926 int rtw_retrive_from_file(char *path, u8* buf, u32 sz)
1927 {
1928 #ifdef PLATFORM_LINUX
1929         int ret =retriveFromFile(path, buf, sz);
1930         return ret>=0?ret:0;
1931 #else
1932         //Todo...
1933         return 0;
1934 #endif
1935 }
1936
1937 /*
1938 * Open the file with @param path and wirte @param sz byte of data starting from @param buf into the file
1939 * @param path the path of the file to open and write
1940 * @param buf the starting address of the data to write into file
1941 * @param sz how many bytes to write at most
1942 * @return the byte we've written
1943 */
1944 int rtw_store_to_file(char *path, u8* buf, u32 sz)
1945 {
1946 #ifdef PLATFORM_LINUX
1947         int ret =storeToFile(path, buf, sz);
1948         return ret>=0?ret:0;
1949 #else
1950         //Todo...
1951         return 0;
1952 #endif
1953 }
1954
1955 #if 1 //#ifdef MEM_ALLOC_REFINE_ADAPTOR
1956 #ifdef PLATFORM_LINUX
1957 struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv, void *old_priv)
1958 {
1959         struct net_device *pnetdev;
1960         struct rtw_netdev_priv_indicator *pnpi;
1961
1962 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
1963         pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
1964 #else
1965         pnetdev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator));
1966 #endif
1967         if (!pnetdev)
1968                 goto RETURN;
1969         
1970         pnpi = netdev_priv(pnetdev);
1971         pnpi->priv=old_priv;
1972         pnpi->sizeof_priv=sizeof_priv;
1973
1974 RETURN:
1975         return pnetdev;
1976 }
1977
1978 struct net_device *rtw_alloc_etherdev(int sizeof_priv)
1979 {
1980         struct net_device *pnetdev;
1981         struct rtw_netdev_priv_indicator *pnpi;
1982
1983 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
1984         pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
1985 #else
1986         pnetdev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator));
1987 #endif
1988         if (!pnetdev)
1989                 goto RETURN;
1990         
1991         pnpi = netdev_priv(pnetdev);
1992         
1993         pnpi->priv = rtw_zvmalloc(sizeof_priv);
1994         if (!pnpi->priv) {
1995                 free_netdev(pnetdev);
1996                 pnetdev = NULL;
1997                 goto RETURN;
1998         }
1999         
2000         pnpi->sizeof_priv=sizeof_priv;
2001 RETURN:
2002         return pnetdev;
2003 }
2004
2005 void rtw_free_netdev(struct net_device * netdev)
2006 {
2007         struct rtw_netdev_priv_indicator *pnpi;
2008         
2009         if(!netdev)
2010                 goto RETURN;
2011         
2012         pnpi = netdev_priv(netdev);
2013
2014         if(!pnpi->priv)
2015                 goto RETURN;
2016
2017         rtw_vmfree(pnpi->priv, pnpi->sizeof_priv);
2018         free_netdev(netdev);
2019
2020 RETURN:
2021         return;
2022 }
2023
2024 /*
2025 * Jeff: this function should be called under ioctl (rtnl_lock is accquired) while 
2026 * LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)
2027 */
2028 int rtw_change_ifname(_adapter *padapter, const char *ifname)
2029 {
2030         struct net_device *pnetdev;
2031         struct net_device *cur_pnetdev = padapter->pnetdev;
2032         struct rereg_nd_name_data *rereg_priv;
2033         int ret;
2034
2035         if(!padapter)
2036                 goto error;
2037
2038         rereg_priv = &padapter->rereg_nd_name_priv;
2039         
2040         //free the old_pnetdev
2041         if(rereg_priv->old_pnetdev) {
2042                 free_netdev(rereg_priv->old_pnetdev);
2043                 rereg_priv->old_pnetdev = NULL;
2044         }
2045
2046 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26))
2047         if(!rtnl_is_locked())
2048                 unregister_netdev(cur_pnetdev);
2049         else
2050 #endif
2051                 unregister_netdevice(cur_pnetdev);
2052
2053         rereg_priv->old_pnetdev=cur_pnetdev;
2054
2055         pnetdev = rtw_init_netdev(padapter);
2056         if (!pnetdev)  {
2057                 ret = -1;
2058                 goto error;
2059         }
2060
2061         SET_NETDEV_DEV(pnetdev, dvobj_to_dev(adapter_to_dvobj(padapter)));
2062
2063         rtw_init_netdev_name(pnetdev, ifname);
2064
2065         _rtw_memcpy(pnetdev->dev_addr, padapter->eeprompriv.mac_addr, ETH_ALEN);
2066
2067 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26))
2068         if(!rtnl_is_locked())
2069                 ret = register_netdev(pnetdev);
2070         else
2071 #endif
2072                 ret = register_netdevice(pnetdev);
2073
2074         if ( ret != 0) {
2075                 RT_TRACE(_module_hci_intfs_c_,_drv_err_,("register_netdev() failed\n"));
2076                 goto error;
2077         }
2078
2079         return 0;
2080
2081 error:
2082         
2083         return -1;
2084         
2085 }
2086 #endif
2087 #endif //MEM_ALLOC_REFINE_ADAPTOR
2088
2089 #ifdef PLATFORM_FREEBSD
2090 /*
2091  * Copy a buffer from userspace and write into kernel address 
2092  * space.
2093  *
2094  * This emulation just calls the FreeBSD copyin function (to 
2095  * copy data from user space buffer into a kernel space buffer)
2096  * and is designed to be used with the above io_write_wrapper.
2097  *
2098  * This function should return the number of bytes not copied.
2099  * I.e. success results in a zero value. 
2100  * Negative error values are not returned.
2101  */
2102 unsigned long
2103 copy_from_user(void *to, const void *from, unsigned long n)
2104 {      
2105         if ( copyin(from, to, n) != 0 ) {
2106                 /* Any errors will be treated as a failure
2107                    to copy any of the requested bytes */
2108                 return n;
2109         }
2110
2111         return 0;
2112 }
2113
2114 unsigned long
2115 copy_to_user(void *to, const void *from, unsigned long n)
2116 {
2117         if ( copyout(from, to, n) != 0 ) {
2118                 /* Any errors will be treated as a failure
2119                    to copy any of the requested bytes */
2120                 return n;
2121         }
2122
2123         return 0;
2124 }
2125
2126
2127 /*
2128  * The usb_register and usb_deregister functions are used to register
2129  * usb drivers with the usb subsystem. In this compatibility layer
2130  * emulation a list of drivers (struct usb_driver) is maintained
2131  * and is used for probing/attaching etc.
2132  *
2133  * usb_register and usb_deregister simply call these functions.
2134  */
2135 int 
2136 usb_register(struct usb_driver *driver)
2137 {
2138         rtw_usb_linux_register(driver);
2139         return 0;
2140 }
2141
2142
2143 int 
2144 usb_deregister(struct usb_driver *driver)
2145 {
2146         rtw_usb_linux_deregister(driver);
2147         return 0;
2148 }
2149
2150 void module_init_exit_wrapper(void *arg)
2151 {
2152         int (*func)(void) = arg;
2153         func();
2154         return;
2155 }
2156
2157 #endif //PLATFORM_FREEBSD
2158 u64 rtw_modular64(u64 x, u64 y)
2159 {
2160 #ifdef PLATFORM_LINUX
2161         return do_div(x, y);
2162 #elif defined(PLATFORM_WINDOWS)
2163         return (x % y);
2164 #elif defined(PLATFORM_FREEBSD)
2165         return (x %y);
2166 #endif
2167 }
2168
2169 u64 rtw_division64(u64 x, u64 y)
2170 {
2171 #ifdef PLATFORM_LINUX
2172         do_div(x, y);
2173         return x;
2174 #elif defined(PLATFORM_WINDOWS)
2175         return (x / y);
2176 #elif defined(PLATFORM_FREEBSD)
2177         return (x / y);
2178 #endif
2179 }
2180
2181 void rtw_buf_free(u8 **buf, u32 *buf_len)
2182 {
2183         u32 ori_len;
2184
2185         if (!buf || !buf_len)
2186                 return;
2187
2188         ori_len = *buf_len;
2189
2190         if (*buf) {
2191                 u32 tmp_buf_len = *buf_len;
2192                 *buf_len = 0;
2193                 rtw_mfree(*buf, tmp_buf_len);
2194                 *buf = NULL;
2195         }
2196 }
2197
2198 void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len)
2199 {
2200         u32 ori_len = 0, dup_len = 0;
2201         u8 *ori = NULL;
2202         u8 *dup = NULL;
2203
2204         if (!buf || !buf_len)
2205                 return;
2206
2207         if (!src || !src_len)
2208                 goto keep_ori;
2209
2210         /* duplicate src */
2211         dup = rtw_malloc(src_len);
2212         if (dup) {
2213                 dup_len = src_len;
2214                 _rtw_memcpy(dup, src, dup_len);
2215         }
2216
2217 keep_ori:
2218         ori = *buf;
2219         ori_len = *buf_len;
2220
2221         /* replace buf with dup */
2222         *buf_len = 0;
2223         *buf = dup;
2224         *buf_len = dup_len;
2225
2226         /* free ori */
2227         if (ori && ori_len > 0)
2228                 rtw_mfree(ori, ori_len);
2229 }
2230
2231
2232 /**
2233  * rtw_cbuf_full - test if cbuf is full
2234  * @cbuf: pointer of struct rtw_cbuf
2235  *
2236  * Returns: _TRUE if cbuf is full
2237  */
2238 inline bool rtw_cbuf_full(struct rtw_cbuf *cbuf)
2239 {
2240         return (cbuf->write == cbuf->read-1)? _TRUE : _FALSE;
2241 }
2242
2243 /**
2244  * rtw_cbuf_empty - test if cbuf is empty
2245  * @cbuf: pointer of struct rtw_cbuf
2246  *
2247  * Returns: _TRUE if cbuf is empty
2248  */
2249 inline bool rtw_cbuf_empty(struct rtw_cbuf *cbuf)
2250 {
2251         return (cbuf->write == cbuf->read)? _TRUE : _FALSE;
2252 }
2253
2254 /**
2255  * rtw_cbuf_push - push a pointer into cbuf
2256  * @cbuf: pointer of struct rtw_cbuf
2257  * @buf: pointer to push in
2258  *
2259  * Lock free operation, be careful of the use scheme
2260  * Returns: _TRUE push success
2261  */
2262 bool rtw_cbuf_push(struct rtw_cbuf *cbuf, void *buf)
2263 {
2264         if (rtw_cbuf_full(cbuf))
2265                 return _FAIL;
2266
2267         if (0)
2268                 DBG_871X("%s on %u\n", __func__, cbuf->write);
2269         cbuf->bufs[cbuf->write] = buf;
2270         cbuf->write = (cbuf->write+1)%cbuf->size;
2271
2272         return _SUCCESS;
2273 }
2274
2275 /**
2276  * rtw_cbuf_pop - pop a pointer from cbuf
2277  * @cbuf: pointer of struct rtw_cbuf
2278  *
2279  * Lock free operation, be careful of the use scheme
2280  * Returns: pointer popped out
2281  */
2282 void *rtw_cbuf_pop(struct rtw_cbuf *cbuf)
2283 {
2284         void *buf;
2285         if (rtw_cbuf_empty(cbuf))
2286                 return NULL;
2287
2288         if (0)
2289                 DBG_871X("%s on %u\n", __func__, cbuf->read);
2290         buf = cbuf->bufs[cbuf->read];
2291         cbuf->read = (cbuf->read+1)%cbuf->size;
2292
2293         return buf;
2294 }
2295
2296 /**
2297  * rtw_cbuf_alloc - allocte a rtw_cbuf with given size and do initialization
2298  * @size: size of pointer
2299  *
2300  * Returns: pointer of srtuct rtw_cbuf, NULL for allocation failure
2301  */
2302 struct rtw_cbuf *rtw_cbuf_alloc(u32 size)
2303 {
2304         struct rtw_cbuf *cbuf;
2305
2306         cbuf = (struct rtw_cbuf *)rtw_malloc(sizeof(*cbuf) + sizeof(void*)*size);
2307
2308         if (cbuf) {
2309                 cbuf->write = cbuf->read = 0;
2310                 cbuf->size = size;
2311         }
2312
2313         return cbuf;
2314 }
2315
2316 /**
2317  * rtw_cbuf_free - free the given rtw_cbuf
2318  * @cbuf: pointer of struct rtw_cbuf to free
2319  */
2320 void rtw_cbuf_free(struct rtw_cbuf *cbuf)
2321 {
2322         rtw_mfree((u8*)cbuf, sizeof(*cbuf) + sizeof(void*)*cbuf->size);
2323 }
2324