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